1 // Licensed under the Apache License, Version 2.0
2 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
4 // All files in the project carrying such notice may not be copied, modified, or distributed
5 // except according to those terms
6 //! WinSock2 Extension for TCP/IP protocols
7 use ctypes::c_int;
8 use shared::guiddef::LPGUID;
9 use shared::minwindef::{DWORD, INT, LPHANDLE, ULONG};
10 use shared::mstcpip::{
11     SOCKET_PEER_TARGET_NAME, SOCKET_SECURITY_QUERY_INFO, SOCKET_SECURITY_QUERY_TEMPLATE,
12     SOCKET_SECURITY_SETTINGS,
13 };
14 use shared::winerror::{
15     WSAEAFNOSUPPORT, WSAEINVAL, WSAESOCKTNOSUPPORT, WSAHOST_NOT_FOUND, WSANO_RECOVERY,
16     WSATRY_AGAIN, WSATYPE_NOT_FOUND, WSA_IPSEC_NAME_POLICY_ERROR, WSA_SECURE_HOST_NOT_FOUND,
17 };
18 use shared::ws2def::{
19     ADDRINFOA, ADDRINFOEXA, ADDRINFOEXW, ADDRINFOW, PADDRINFOA, PADDRINFOEXA, PADDRINFOEXW,
20     PADDRINFOW, SOCKADDR, SOCKET_ADDRESS,
21 };
22 use shared::wtypesbase::LPBLOB;
23 use um::minwinbase::LPOVERLAPPED;
24 use um::winnt::{PCHAR, PCSTR, PCWSTR, PSTR, PVOID, PWCHAR, PWSTR, VOID};
25 use um::winsock2::{
26     LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE, SOCKET, WSA_NOT_ENOUGH_MEMORY, timeval,
27 };
28 use vc::vcruntime::size_t;
29 pub const UDP_NOCHECKSUM: c_int = 1;
30 pub const UDP_CHECKSUM_COVERAGE: c_int = 20;
31 pub const EAI_AGAIN: DWORD = WSATRY_AGAIN;
32 pub const EAI_BADFLAGS: DWORD = WSAEINVAL;
33 pub const EAI_FAIL: DWORD = WSANO_RECOVERY;
34 pub const EAI_FAMILY: DWORD = WSAEAFNOSUPPORT;
35 pub const EAI_MEMORY: DWORD = WSA_NOT_ENOUGH_MEMORY as u32;
36 pub const EAI_NOSECURENAME: DWORD = WSA_SECURE_HOST_NOT_FOUND;
37 pub const EAI_NONAME: DWORD = WSAHOST_NOT_FOUND;
38 pub const EAI_SERVICE: DWORD = WSATYPE_NOT_FOUND;
39 pub const EAI_SOCKTYPE: DWORD = WSAESOCKTNOSUPPORT;
40 pub const EAI_IPSECPOLICY: DWORD = WSA_IPSEC_NAME_POLICY_ERROR;
41 pub const EAI_NODATA: DWORD = EAI_NONAME;
42 pub type ADDRINFO = ADDRINFOA;
43 pub type LPADDRINFO = *mut ADDRINFOA;
44 extern "system" {
getaddrinfo( pNodeName: PCSTR, pServiceName: PCSTR, pHints: *const ADDRINFOA, ppResult: *mut PADDRINFOA, ) -> INT45     pub fn getaddrinfo(
46         pNodeName: PCSTR,
47         pServiceName: PCSTR,
48         pHints: *const ADDRINFOA,
49         ppResult: *mut PADDRINFOA,
50     ) -> INT;
GetAddrInfoW( pNodeName: PCWSTR, pServiceName: PCWSTR, pHints: *const ADDRINFOW, ppResult: *mut PADDRINFOW, ) -> INT51     pub fn GetAddrInfoW(
52         pNodeName: PCWSTR,
53         pServiceName: PCWSTR,
54         pHints: *const ADDRINFOW,
55         ppResult: *mut PADDRINFOW,
56     ) -> INT;
57 }
58 FN!{stdcall LPFN_GETADDRINFO(
59     pNodeName: PCSTR,
60     pServiceName: PCSTR,
61     pHints: *const ADDRINFOA,
62     ppResult: *mut PADDRINFOA,
63 ) -> INT}
64 FN!{stdcall LPFN_GETADDRINFOW(
65     pNodeName: PCWSTR,
66     pServiceName: PCWSTR,
67     pHints: *const ADDRINFOW,
68     ppResult: *mut PADDRINFOW,
69 ) -> INT}
70 FN!{stdcall LPLOOKUPSERVICE_COMPLETION_ROUTINE(
71     dwError: DWORD,
72     dwBytes: DWORD,
73     lpOverlapped: LPWSAOVERLAPPED,
74 ) -> ()}
75 extern "system" {
GetAddrInfoExA( pName: PCSTR, pServiceName: PCSTR, dwNameSpace: DWORD, lpNspId: LPGUID, hints: *const ADDRINFOEXA, ppResult: *mut PADDRINFOEXA, timeout: *mut timeval, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE, lpNameHandle: LPHANDLE, ) -> INT76     pub fn GetAddrInfoExA(
77         pName: PCSTR,
78         pServiceName: PCSTR,
79         dwNameSpace: DWORD,
80         lpNspId: LPGUID,
81         hints: *const ADDRINFOEXA,
82         ppResult: *mut PADDRINFOEXA,
83         timeout: *mut timeval,
84         lpOverlapped: LPOVERLAPPED,
85         lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
86         lpNameHandle: LPHANDLE,
87     ) -> INT;
GetAddrInfoExW( pName: PCWSTR, pServiceName: PCWSTR, dwNameSpace: DWORD, lpNspId: LPGUID, hints: *const ADDRINFOEXW, ppResult: *mut PADDRINFOEXW, timeout: *mut timeval, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE, lpNameHandle: LPHANDLE, ) -> INT88     pub fn GetAddrInfoExW(
89         pName: PCWSTR,
90         pServiceName: PCWSTR,
91         dwNameSpace: DWORD,
92         lpNspId: LPGUID,
93         hints: *const ADDRINFOEXW,
94         ppResult: *mut PADDRINFOEXW,
95         timeout: *mut timeval,
96         lpOverlapped: LPOVERLAPPED,
97         lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
98         lpNameHandle: LPHANDLE,
99     ) -> INT;
GetAddrInfoExCancel( lpHandle: LPHANDLE, ) -> INT100     pub fn GetAddrInfoExCancel(
101         lpHandle: LPHANDLE,
102     ) -> INT;
GetAddrInfoExOverlappedResult( lpOverlapped: LPOVERLAPPED, ) -> INT103     pub fn GetAddrInfoExOverlappedResult(
104         lpOverlapped: LPOVERLAPPED,
105     ) -> INT;
106 }
107 FN!{stdcall LPFN_GETADDRINFOEXA(
108     pName: PCSTR,
109     pServiceName: PCSTR,
110     dwNameSpace: DWORD,
111     lpNspId: LPGUID,
112     hints: *const ADDRINFOEXA,
113     ppResult: *mut PADDRINFOEXA,
114     timeout: *mut timeval,
115     lpOverlapped: LPOVERLAPPED,
116     lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
117     lpNameHandle: LPHANDLE,
118 ) -> INT}
119 FN!{stdcall LPFN_GETADDRINFOEXW(
120     pName: PCWSTR,
121     pServiceName: PCWSTR,
122     dwNameSpace: DWORD,
123     lpNspId: LPGUID,
124     hints: *const ADDRINFOEXW,
125     ppResult: *mut PADDRINFOEXW,
126     timeout: *mut timeval,
127     lpOverlapped: LPOVERLAPPED,
128     lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
129     lpNameHandle: LPHANDLE,
130 ) -> INT}
131 FN!{stdcall LPFN_GETADDRINFOEXCANCEL(
132     lpHandle: LPHANDLE,
133 ) -> INT}
134 FN!{stdcall LPFN_GETADDRINFOEXOVERLAPPEDRESULT(
135     lpOverlapped: LPOVERLAPPED,
136 ) -> INT}
137 extern "system" {
SetAddrInfoExA( pName: PCSTR, pServiceName: PCSTR, pAddresses: *mut SOCKET_ADDRESS, dwAddressCount: DWORD, lpBlob: LPBLOB, dwFlags: DWORD, dwNameSpace: DWORD, lpNspId: LPGUID, timeout: *mut timeval, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE, lpNameHandle: LPHANDLE, ) -> INT138     pub fn SetAddrInfoExA(
139         pName: PCSTR,
140         pServiceName: PCSTR,
141         pAddresses: *mut SOCKET_ADDRESS,
142         dwAddressCount: DWORD,
143         lpBlob: LPBLOB,
144         dwFlags: DWORD,
145         dwNameSpace: DWORD,
146         lpNspId: LPGUID,
147         timeout: *mut timeval,
148         lpOverlapped: LPOVERLAPPED,
149         lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
150         lpNameHandle: LPHANDLE,
151     ) -> INT;
SetAddrInfoExW( pName: PCWSTR, pServiceName: PCWSTR, pAddresses: *mut SOCKET_ADDRESS, dwAddressCount: DWORD, lpBlob: LPBLOB, dwFlags: DWORD, dwNameSpace: DWORD, lpNspId: LPGUID, timeout: *mut timeval, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE, lpNameHandle: LPHANDLE, ) -> INT152     pub fn SetAddrInfoExW(
153         pName: PCWSTR,
154         pServiceName: PCWSTR,
155         pAddresses: *mut SOCKET_ADDRESS,
156         dwAddressCount: DWORD,
157         lpBlob: LPBLOB,
158         dwFlags: DWORD,
159         dwNameSpace: DWORD,
160         lpNspId: LPGUID,
161         timeout: *mut timeval,
162         lpOverlapped: LPOVERLAPPED,
163         lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
164         lpNameHandle: LPHANDLE,
165     ) -> INT;
166 }
167 FN!{stdcall LPFN_SETADDRINFOEXA(
168     pName: PCSTR,
169     pServiceName: PCSTR,
170     pAddresses: *mut SOCKET_ADDRESS,
171     dwAddressCount: DWORD,
172     lpBlob: LPBLOB,
173     dwFlags: DWORD,
174     dwNameSpace: DWORD,
175     lpNspId: LPGUID,
176     timeout: *mut timeval,
177     lpOverlapped: LPOVERLAPPED,
178     lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
179     lpNameHandle: LPHANDLE,
180 ) -> INT}
181 FN!{stdcall LPFN_SETADDRINFOEXW(
182     pName: PCWSTR,
183     pServiceName: PCWSTR,
184     pAddresses: *mut SOCKET_ADDRESS,
185     dwAddressCount: DWORD,
186     lpBlob: LPBLOB,
187     dwFlags: DWORD,
188     dwNameSpace: DWORD,
189     lpNspId: LPGUID,
190     timeout: *mut timeval,
191     lpOverlapped: LPOVERLAPPED,
192     lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
193     lpNameHandle: LPHANDLE,
194 ) -> INT}
195 extern "system" {
freeaddrinfo( pAddrInfo: PADDRINFOA, )196     pub fn freeaddrinfo(
197         pAddrInfo: PADDRINFOA,
198     );
FreeAddrInfoW( pAddrInfo: PADDRINFOW, )199     pub fn FreeAddrInfoW(
200         pAddrInfo: PADDRINFOW,
201     );
202 }
203 FN!{stdcall LPFN_FREEADDRINFO(
204     pAddrInfo: PADDRINFOA,
205 ) -> ()}
206 FN!{stdcall LPFN_FREEADDRINFOW(
207     pAddrInfo: PADDRINFOW,
208 ) -> ()}
209 extern "system" {
FreeAddrInfoEx( pAddrInfoEx: PADDRINFOEXA, )210     pub fn FreeAddrInfoEx(
211         pAddrInfoEx: PADDRINFOEXA,
212     );
FreeAddrInfoExW( pAddrInfoEx: PADDRINFOEXW, )213     pub fn FreeAddrInfoExW(
214         pAddrInfoEx: PADDRINFOEXW,
215     );
216 }
217 FN!{stdcall LPFN_FREEADDRINFOEXA(
218     pAddrInfoEx: PADDRINFOEXA,
219 ) -> ()}
220 FN!{stdcall LPFN_FREEADDRINFOEXW(
221     pAddrInfoEx: PADDRINFOEXW,
222 ) -> ()}
223 pub type socklen_t = c_int;
224 extern "system" {
getnameinfo( pSockaddr: *const SOCKADDR, SockaddrLength: socklen_t, pNodeBuffer: PCHAR, NodeBufferSize: DWORD, pServiceBuffer: PCHAR, ServiceBufferSize: DWORD, Flags: INT, ) -> INT225     pub fn getnameinfo(
226         pSockaddr: *const SOCKADDR,
227         SockaddrLength: socklen_t,
228         pNodeBuffer: PCHAR,
229         NodeBufferSize: DWORD,
230         pServiceBuffer: PCHAR,
231         ServiceBufferSize: DWORD,
232         Flags: INT,
233     ) -> INT;
GetNameInfoW( pSockaddr: *const SOCKADDR, SockaddrLength: socklen_t, pNodeBuffer: PWCHAR, NodeBufferSize: DWORD, pServiceBuffer: PWCHAR, ServiceBufferSize: DWORD, Flags: INT, ) -> INT234     pub fn GetNameInfoW(
235         pSockaddr: *const SOCKADDR,
236         SockaddrLength: socklen_t,
237         pNodeBuffer: PWCHAR,
238         NodeBufferSize: DWORD,
239         pServiceBuffer: PWCHAR,
240         ServiceBufferSize: DWORD,
241         Flags: INT,
242     ) -> INT;
243 }
244 FN!{stdcall LPFN_GETNAMEINFO(
245     pSockaddr: *const SOCKADDR,
246     SockaddrLength: socklen_t,
247     pNodeBuffer: PCHAR,
248     NodeBufferSize: DWORD,
249     pServiceBuffer: PCHAR,
250     ServiceBufferSize: DWORD,
251     Flags: INT,
252 ) -> c_int}
253 FN!{stdcall LPFN_GETNAMEINFOW(
254     pSockaddr: *const SOCKADDR,
255     SockaddrLength: socklen_t,
256     pNodeBuffer: PWCHAR,
257     NodeBufferSize: DWORD,
258     pServiceBuffer: PWCHAR,
259     ServiceBufferSize: DWORD,
260     Flags: INT,
261 ) -> INT}
262 extern "system" {
inet_pton( Family: INT, pszAddrString: PCSTR, pAddrBuf: PVOID, ) -> INT263     pub fn inet_pton(
264         Family: INT,
265         pszAddrString: PCSTR,
266         pAddrBuf: PVOID,
267     ) -> INT;
InetPtonW( Family: INT, pszAddrString: PCWSTR, pAddrBuf: PVOID, ) -> INT268     pub fn InetPtonW(
269         Family: INT,
270         pszAddrString: PCWSTR,
271         pAddrBuf: PVOID,
272     ) -> INT;
inet_ntop( Family: INT, pAddr: *const VOID, pStringBuf: PSTR, StringBufSize: size_t, ) -> PCSTR273     pub fn inet_ntop(
274         Family: INT,
275         pAddr: *const VOID,
276         pStringBuf: PSTR,
277         StringBufSize: size_t,
278     ) -> PCSTR;
InetNtopW( Family: INT, pAddr: *const VOID, pStringBuf: PWSTR, StringBufSize: size_t, ) -> PCWSTR279     pub fn InetNtopW(
280         Family: INT,
281         pAddr: *const VOID,
282         pStringBuf: PWSTR,
283         StringBufSize: size_t,
284     ) -> PCWSTR;
285 }
286 FN!{stdcall LPFN_INET_PTONA(
287     Family: INT,
288     pszAddrString: PCSTR,
289     pAddrBuf: PVOID,
290 ) -> INT}
291 FN!{stdcall LPFN_INET_PTONW(
292     Family: INT,
293     pszAddrString: PCWSTR,
294     pAddrBuf: PVOID,
295 ) -> INT}
296 FN!{stdcall LPFN_INET_NTOPA(
297     Family: INT,
298     pAddr: *const VOID,
299     pStringBuf: PSTR,
300     StringBufSize: size_t,
301 ) -> PCSTR}
302 FN!{stdcall LPFN_INET_NTOPW(
303     Family: INT,
304     pAddr: *const VOID,
305     pStringBuf: PWSTR,
306     StringBufSize: size_t,
307 ) -> PCWSTR}
308 pub const GAI_STRERROR_BUFFER_SIZE: usize = 1024;
309 extern "system" {
WSASetSocketSecurity( Socket: SOCKET, SecuritySettings: *const SOCKET_SECURITY_SETTINGS, SecuritySettingsLen: ULONG, Overlapped: LPWSAOVERLAPPED, CompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, ) -> INT310     pub fn WSASetSocketSecurity(
311         Socket: SOCKET,
312         SecuritySettings: *const SOCKET_SECURITY_SETTINGS,
313         SecuritySettingsLen: ULONG,
314         Overlapped: LPWSAOVERLAPPED,
315         CompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
316     ) -> INT;
WSAQuerySocketSecurity( Socket: SOCKET, SecurityQueryTemplate: *const SOCKET_SECURITY_QUERY_TEMPLATE, SecurityQueryTemplateLen: ULONG, SecurityQueryInfo: *mut SOCKET_SECURITY_QUERY_INFO, SecurityQueryInfoLen: *mut ULONG, Overlapped: LPWSAOVERLAPPED, CompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, ) -> INT317     pub fn WSAQuerySocketSecurity(
318         Socket: SOCKET,
319         SecurityQueryTemplate: *const SOCKET_SECURITY_QUERY_TEMPLATE,
320         SecurityQueryTemplateLen: ULONG,
321         SecurityQueryInfo: *mut SOCKET_SECURITY_QUERY_INFO,
322         SecurityQueryInfoLen: *mut ULONG,
323         Overlapped: LPWSAOVERLAPPED,
324         CompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
325     ) -> INT;
WSASetSocketPeerTargetName( Socket: SOCKET, PeerTargetName: *const SOCKET_PEER_TARGET_NAME, PeerTargetNameLen: ULONG, Overlapped: LPWSAOVERLAPPED, CompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, ) -> INT326     pub fn WSASetSocketPeerTargetName(
327         Socket: SOCKET,
328         PeerTargetName: *const SOCKET_PEER_TARGET_NAME,
329         PeerTargetNameLen: ULONG,
330         Overlapped: LPWSAOVERLAPPED,
331         CompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
332     ) -> INT;
WSADeleteSocketPeerTargetName( Socket: SOCKET, PeerAddr: *const SOCKADDR, PeerAddrLen: ULONG, Overlapped: LPWSAOVERLAPPED, CompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, ) -> INT333     pub fn WSADeleteSocketPeerTargetName(
334         Socket: SOCKET,
335         PeerAddr: *const SOCKADDR,
336         PeerAddrLen: ULONG,
337         Overlapped: LPWSAOVERLAPPED,
338         CompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
339     ) -> INT;
WSAImpersonateSocketPeer( Socket: SOCKET, PeerAddr: *const SOCKADDR, PeerAddrLen: ULONG, ) -> INT340     pub fn WSAImpersonateSocketPeer(
341         Socket: SOCKET,
342         PeerAddr: *const SOCKADDR,
343         PeerAddrLen: ULONG,
344     ) -> INT;
WSARevertImpersonation()345     pub fn WSARevertImpersonation();
346 }
347