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