1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
/********************************************************/
/* ntapi: Native API core library */
/* Copyright (C) 2013--2016 Z. Gilboa */
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
/********************************************************/
#include <psxtypes/psxtypes.h>
#include <ntapi/nt_object.h>
#include <ntapi/nt_file.h>
#include <ntapi/nt_socket.h>
#include <ntapi/ntapi.h>
#include "ntapi_impl.h"
typedef struct _nt_afd_bind_request {
uint32_t unknown;
nt_sockaddr addr;
} nt_afd_bind_request;
typedef struct _nt_afd_bind_reply {
nt_sockaddr addr;
} nt_afd_bind_reply;
typedef struct __addr_memcpy {
uint64_t d0;
uint64_t d1;
uint64_t d2;
uint32_t d3;
} _addr_memcpy;
int32_t __cdecl __ntapi_sc_bind_v2(
__in nt_socket * hssocket,
__in const nt_sockaddr * addr,
__in uintptr_t addrlen,
__in uintptr_t service_flags __optional,
__out nt_sockaddr * sockaddr __optional,
__out nt_io_status_block * iosb __optional)
{
nt_io_status_block siosb;
nt_afd_bind_request afd_bind_req;
nt_afd_bind_reply afd_bind_rep;
_addr_memcpy * src;
_addr_memcpy * dst;
(void)service_flags;
if ((addrlen != sizeof(nt_sockaddr_in4))
&& (addrlen != sizeof(nt_sockaddr_in6)))
return NT_STATUS_INVALID_PARAMETER_3;
iosb = iosb ? iosb : &siosb;
/* request */
afd_bind_req.unknown = hssocket->domain;
src = (_addr_memcpy *)addr;
dst = (_addr_memcpy *)&(afd_bind_req.addr);
dst->d0 = src->d0;
dst->d1 = src->d1;
if (addrlen == sizeof(nt_sockaddr_in6)) {
dst->d2 = src->d2;
dst->d3 = src->d3;
} else {
dst->d2 = 0;
dst->d3 = 0;
}
hssocket->iostatus = __ntapi->zw_device_io_control_file(
hssocket->hsocket,
hssocket->hevent,
0,
0,
iosb,
NT_AFD_IOCTL_BIND,
&afd_bind_req,
sizeof(afd_bind_req),
&afd_bind_rep,
sizeof(afd_bind_rep));
__ntapi->sc_wait(hssocket,iosb,0);
if (!hssocket->iostatus && sockaddr) {
/* return updated address information */
src = (_addr_memcpy *)&(afd_bind_rep);
dst = (_addr_memcpy *)sockaddr;
dst->d0 = src->d0;
dst->d1 = src->d1;
if (addrlen == sizeof(nt_sockaddr_in6)) {
dst->d2 = src->d2;
dst->d3 = src->d3;
}
}
return hssocket->iostatus;
}
|