/binding/win32/ws2tcpip.d

http://github.com/wilkie/djehuty · D · 850 lines · 452 code · 101 blank · 297 comment · 16 complexity · 973ce3bf41afb2ddb8fc043b5aa2c8d6 MD5 · raw file

  1. /*
  2. * ws2tcpip.d
  3. *
  4. * This module binds WS2tcpip.h to D. The original copyright notice
  5. * is preserved below.
  6. *
  7. * Author: Dave Wilkinson
  8. * Originated: November 25th, 2009
  9. *
  10. */
  11. module binding.win32.ws2tcpip;
  12. import binding.win32.winsock;
  13. import binding.win32.windef;
  14. import binding.win32.winbase;
  15. import binding.win32.winnt;
  16. /*
  17. ** WS2TCPIP.H - WinSock2 Extension for TCP/IP protocols
  18. **
  19. ** This file contains TCP/IP specific information for use
  20. ** by WinSock2 compatible applications.
  21. **
  22. ** Copyright (c) Microsoft Corporation. All rights reserved.
  23. **
  24. ** To provide the backward compatibility, all the TCP/IP
  25. ** specific definitions that were included in the WINSOCK.H
  26. ** file are now included in WINSOCK2.H file. WS2TCPIP.H
  27. ** file includes only the definitions introduced in the
  28. ** "WinSock 2 Protocol-Specific Annex" document.
  29. **
  30. ** Rev 0.3 Nov 13, 1995
  31. ** Rev 0.4 Dec 15, 1996
  32. */
  33. /* Error codes from getaddrinfo() */
  34. const auto EAI_AGAIN = WSATRY_AGAIN;
  35. const auto EAI_BADFLAGS = WSAEINVAL;
  36. const auto EAI_FAIL = WSANO_RECOVERY;
  37. const auto EAI_FAMILY = WSAEAFNOSUPPORT;
  38. const auto EAI_MEMORY = WSA_NOT_ENOUGH_MEMORY;
  39. //#define EAI_NODATA WSANO_DATA
  40. const auto EAI_NONAME = WSAHOST_NOT_FOUND;
  41. const auto EAI_SERVICE = WSATYPE_NOT_FOUND;
  42. const auto EAI_SOCKTYPE = WSAESOCKTNOSUPPORT;
  43. //
  44. // DCR_FIX: EAI_NODATA remove or fix
  45. //
  46. // EAI_NODATA was removed from rfc2553bis
  47. // need to find out from the authors why and
  48. // determine the error for "no records of this type"
  49. // temporarily, we'll keep #define to avoid changing
  50. // code that could change back; use NONAME
  51. //
  52. const auto EAI_NODATA = EAI_NONAME;
  53. /* Structure used in getaddrinfo() call */
  54. struct ADDRINFOA {
  55. int ai_flags; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
  56. int ai_family; // PF_xxx
  57. int ai_socktype; // SOCK_xxx
  58. int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6
  59. size_t ai_addrlen; // Length of ai_addr
  60. char * ai_canonname; // Canonical name for nodename
  61. sockaddr * ai_addr; // Binary address
  62. addrinfo * ai_next; // Next structure in linked list
  63. }
  64. alias ADDRINFOA* PADDRINFOA;
  65. struct ADDRINFOW {
  66. int ai_flags; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
  67. int ai_family; // PF_xxx
  68. int ai_socktype; // SOCK_xxx
  69. int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6
  70. size_t ai_addrlen; // Length of ai_addr
  71. PWSTR ai_canonname; // Canonical name for nodename
  72. sockaddr * ai_addr; // Binary address
  73. addrinfoW * ai_next; // Next structure in linked list
  74. }
  75. alias ADDRINFOW* PADDRINFOW;
  76. // Switchable definition for GetAddrInfo()
  77. version(UNICODE) {
  78. alias ADDRINFOW ADDRINFOT;
  79. alias ADDRINFOW* PADDRINFOT;
  80. }
  81. else {
  82. alias ADDRINFOA ADDRINFOT;
  83. alias ADDRINFOA *PADDRINFOT;
  84. }
  85. // RFC standard definition for getaddrinfo()
  86. alias ADDRINFOA ADDRINFO;
  87. alias ADDRINFOA* LPADDRINFO;
  88. struct ADDRINFOEXA {
  89. int ai_flags; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
  90. int ai_family; // PF_xxx
  91. int ai_socktype; // SOCK_xxx
  92. int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6
  93. size_t ai_addrlen; // Length of ai_addr
  94. char *ai_canonname; // Canonical name for nodename
  95. sockaddr *ai_addr; // Binary address
  96. void *ai_blob;
  97. size_t ai_bloblen;
  98. LPGUID ai_provider;
  99. addrinfoexA *ai_next; // Next structure in linked list
  100. }
  101. alias ADDRINFOEXA* PADDRINFOEXA;
  102. alias ADDRINFOEXA* LPADDRINFOEXA;
  103. struct ADDRINFOEXW {
  104. int ai_flags; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
  105. int ai_family; // PF_xxx
  106. int ai_socktype; // SOCK_xxx
  107. int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6
  108. size_t ai_addrlen; // Length of ai_addr
  109. PWSTR ai_canonname; // Canonical name for nodename
  110. sockaddr *ai_addr; // Binary address
  111. void *ai_blob;
  112. size_t ai_bloblen;
  113. LPGUID ai_provider;
  114. addrinfoexW *ai_next; // Next structure in linked list
  115. }
  116. alias ADDRINFOEXW* PADDRINFOEXW;
  117. alias ADDRINFOEXW* LPADDRINFOEXW;
  118. version(UNICODE) {
  119. alias ADDRINFOEXW ADDRINFOEX;
  120. alias ADDRINFOEXW *PADDRINFOEX;
  121. }
  122. else {
  123. alias ADDRINFOEXA ADDRINFOEX;
  124. alias ADDRINFOEXA *PADDRINFOEX;
  125. }
  126. //
  127. // Flags used in "hints" argument to getaddrinfo()
  128. // - AI_ADDRCONFIG is supported starting with Vista
  129. // - default is AI_ADDRCONFIG ON whether the flag is set or not
  130. // because the performance penalty in not having ADDRCONFIG in
  131. // the multi-protocol stack environment is severe;
  132. // this defaulting may be disabled by specifying the AI_ALL flag,
  133. // in that case AI_ADDRCONFIG must be EXPLICITLY specified to
  134. // enable ADDRCONFIG behavior
  135. //
  136. const auto AI_PASSIVE = 0x00000001 ; // Socket address will be used in bind() call
  137. const auto AI_CANONNAME = 0x00000002 ; // Return canonical name in first ai_canonname
  138. const auto AI_NUMERICHOST = 0x00000004 ; // Nodename must be a numeric address string
  139. const auto AI_NUMERICSERV = 0x00000008 ; // Servicename must be a numeric port number
  140. const auto AI_ALL = 0x00000100 ; // Query both IP6 and IP4 with AI_V4MAPPED
  141. const auto AI_ADDRCONFIG = 0x00000400 ; // Resolution only if global address configured
  142. const auto AI_V4MAPPED = 0x00000800 ; // On v6 failure, query v4 and convert to V4MAPPED format
  143. const auto AI_NON_AUTHORITATIVE = LUP_NON_AUTHORITATIVE ; // 0x4000
  144. const auto AI_SECURE = LUP_SECURE ; // 0x8000
  145. const auto AI_RETURN_PREFERRED_NAMES = LUP_RETURN_PREFERRED_NAMES ; // 0x10000
  146. INT getaddrinfo(
  147. PCSTR pNodeName,
  148. PCSTR pServiceName,
  149. ADDRINFOA * pHints,
  150. PADDRINFOA * ppResult
  151. );
  152. INT GetAddrInfoW(
  153. PCWSTR pNodeName,
  154. PCWSTR pServiceName,
  155. ADDRINFOW * pHints,
  156. PADDRINFOW * ppResult
  157. );
  158. const auto GetAddrInfoA = getaddrinfo;
  159. version(UNICODE) {
  160. alias GetAddrInfoW GetAddrInfo;
  161. }
  162. else {
  163. alias GetAddrInfoA GetAddrInfo;
  164. }
  165. alias INT function(PCSTR pNodeName, PCSTR pServiceName, ADDRINFOA* pHints, PADDRINFOA* ppResult) LPFN_GETADDRINFO;
  166. alias INT function(PCWSTR pNodeName, PCWSTR pServiceName, ADDRINFOA* pHints, PADDRINFOA* ppResult) LPFN_GETADDRINFOW;
  167. alias LPFN_GETADDRINFO LPFN_GETADDRINFOA;
  168. version(UNICODE) {
  169. alias LPFN_GETADDRINFOW LPFN_GETADDRINFOT;
  170. }
  171. else {
  172. alias LPFN_GETADDRINFOA LPFN_GETADDRINFOT;
  173. }
  174. alias void function(DWORD, dwError, DWORD dwBytes, LPWSAOVERLAPPED lpOverlapped) LPLOOKUPSERVICE_COMPLETION_ROUTINE;
  175. INT GetAddrInfoExA(
  176. PCSTR pName,
  177. PCSTR pServiceName,
  178. DWORD dwNameSpace,
  179. LPGUID lpNspId,
  180. ADDRINFOEXA* hints,
  181. PADDRINFOEXA* ppResult,
  182. timeval* timeout,
  183. LPOVERLAPPED lpOverlapped,
  184. LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine,
  185. LPHANDLE lpNameHandle
  186. );
  187. INT GetAddrInfoExW(
  188. PCWSTR pName,
  189. PCWSTR pServiceName,
  190. DWORD dwNameSpace,
  191. LPGUID lpNspId,
  192. ADDRINFOEXW* hints,
  193. PADDRINFOEXW* ppResult,
  194. timeval* timeout,
  195. LPOVERLAPPED lpOverlapped,
  196. LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine,
  197. LPHANDLE lpHandle
  198. );
  199. version(UNICODE) {
  200. alias GetAddrInfoExW GetAddrInfoEx;
  201. }
  202. else {
  203. alias GetAddrInfoExA GetAddrInfoEx;
  204. }
  205. alias INT function(PCSTR pName, PCSTR pServiceName, DWORD dwNameSpace, LPGUID lpNspId,
  206. ADDRINFOEXA* hints, PADDRINFOEXA ppResult, timeval* timeout, LPOVERLAPPED lpOverlapped,
  207. LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine, LPHANDLE lpNameHandle) LPFN_GETADDRINFOEXA;
  208. alias INT function(
  209. PCWSTR pName,
  210. PCWSTR pServiceName,
  211. DWORD dwNameSpace,
  212. LPGUID lpNspId,
  213. ADDRINFOEXW* hints,
  214. PADDRINFOEXW* ppResult,
  215. timeval* timeout,
  216. LPOVERLAPPED lpOverlapped,
  217. LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine,
  218. LPHANDLE lpHandle
  219. ) LPFN_GETADDRINFOEXW ;
  220. version(UNICODE) {
  221. alias LPFN_GETADDRINFOEXW LPFN_GETADDRINFOEX;
  222. }
  223. else {
  224. alias LPFN_GETADDRINFOEXA LPFN_GETADDRINFOEX;
  225. }
  226. INT SetAddrInfoExA(
  227. PCSTR pName,
  228. PCSTR pServiceName,
  229. SOCKET_ADDRESS *pAddresses,
  230. DWORD dwAddressCount,
  231. LPBLOB lpBlob,
  232. DWORD dwFlags,
  233. DWORD dwNameSpace,
  234. LPGUID lpNspId,
  235. timeval *timeout,
  236. LPOVERLAPPED lpOverlapped,
  237. LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine,
  238. LPHANDLE lpNameHandle
  239. );
  240. INT SetAddrInfoExW(
  241. PCWSTR pName,
  242. PCWSTR pServiceName,
  243. SOCKET_ADDRESS *pAddresses,
  244. DWORD dwAddressCount,
  245. LPBLOB lpBlob,
  246. DWORD dwFlags,
  247. DWORD dwNameSpace,
  248. LPGUID lpNspId,
  249. timeval *timeout,
  250. LPOVERLAPPED lpOverlapped,
  251. LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine,
  252. LPHANDLE lpNameHandle
  253. );
  254. version(UNICODE) {
  255. alias SetAddrInfoExW SetAddrInfoEx;
  256. }
  257. else {
  258. alias SetAddrInfoExA SetAddrInfoEx;
  259. }
  260. alias INT function (
  261. PCSTR pName,
  262. PCSTR pServiceName,
  263. SOCKET_ADDRESS *pAddresses,
  264. DWORD dwAddressCount,
  265. LPBLOB lpBlob,
  266. DWORD dwFlags,
  267. DWORD dwNameSpace,
  268. LPGUID lpNspId,
  269. timeval *timeout,
  270. LPOVERLAPPED lpOverlapped,
  271. LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine,
  272. LPHANDLE lpNameHandle
  273. ) LPFN_SETADDRINFOEXA;
  274. alias INT function (
  275. PCWSTR pName,
  276. PCWSTR pServiceName,
  277. SOCKET_ADDRESS *pAddresses,
  278. DWORD dwAddressCount,
  279. LPBLOB lpBlob,
  280. DWORD dwFlags,
  281. DWORD dwNameSpace,
  282. LPGUID lpNspId,
  283. timeval *timeout,
  284. LPOVERLAPPED lpOverlapped,
  285. LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine,
  286. LPHANDLE lpNameHandle
  287. ) LPFN_SETADDRINFOEXW;
  288. version(UNICODE) {
  289. alias LPFN_SETADDRINFOEXW LPFN_SETADDRINFOEX;
  290. }
  291. else {
  292. alias LPFN_SETADDRINFOEXA LPFN_SETADDRINFOEX;
  293. }
  294. VOID freeaddrinfo(
  295. PADDRINFOA pAddrInfo
  296. );
  297. VOID FreeAddrInfoW(
  298. PADDRINFOW pAddrInfo
  299. );
  300. alias freeaddrinfo FreeAddrInfoA;
  301. version(UNICODE) {
  302. alias FreeAddrInfoW FreeAddrInfo;
  303. }
  304. else {
  305. alias FreeAddrInfoA FreeAddrInfo;
  306. }
  307. alias VOID function (
  308. PADDRINFOA pAddrInfo
  309. ) LPFN_FREEADDRINFO;
  310. alias VOID function (
  311. PADDRINFOW pAddrInfo
  312. ) LPFN_FREEADDRINFOW;
  313. alias LPFN_FREEADDRINFO LPFN_FREEADDRINFOA;
  314. version(UNICODE) {
  315. alias LPFN_FREEADDRINFOW LPFN_FREEADDRINFOT;
  316. }
  317. else {
  318. alias LPFN_FREEADDRINFOA LPFN_FREEADDRINFOT;
  319. }
  320. void FreeAddrInfoEx(
  321. PADDRINFOEXA pAddrInfoEx
  322. );
  323. void FreeAddrInfoExW(
  324. PADDRINFOEXW pAddrInfoEx
  325. );
  326. alias FreeAddrInfoEx FreeAddrInfoExA;
  327. version(UNICODE) {
  328. alias FreeAddrInfoExW FreeAddrInfoEx;
  329. }
  330. alias void function (
  331. PADDRINFOEXA pAddrInfoEx
  332. ) LPFN_FREEADDRINFOEXA;
  333. alias void function (
  334. PADDRINFOEXW pAddrInfoEx
  335. ) LPFN_FREEADDRINFOEXW;
  336. version(UNICODE) {
  337. alias LPFN_FREEADDRINFOEXW LPFN_FREEADDRINFOEX;
  338. }
  339. else {
  340. alias LPFN_FREEADDRINFOEXA LPFN_FREEADDRINFOEX;
  341. }
  342. alias int socklen_t;
  343. INT getnameinfo(
  344. SOCKADDR* pSockaddr,
  345. socklen_t SockaddrLength,
  346. PCHAR pNodeBuffer,
  347. DWORD NodeBufferSize,
  348. PCHAR pServiceBuffer,
  349. DWORD ServiceBufferSize,
  350. INT Flags
  351. );
  352. INT GetNameInfoW(
  353. SOCKADDR* pSockaddr,
  354. socklen_t SockaddrLength,
  355. PWCHAR pNodeBuffer,
  356. DWORD NodeBufferSize,
  357. PWCHAR pServiceBuffer,
  358. DWORD ServiceBufferSize,
  359. INT Flags
  360. );
  361. alias getnameinfo GetNameInfoA;
  362. version(UNICODE) {
  363. alias GetNameInfoW GetNameInfo;
  364. }
  365. else {
  366. alias GetNameInfoA GetNameInfo;
  367. }
  368. alias int function (
  369. SOCKADDR* pSockaddr,
  370. socklen_t SockaddrLength,
  371. PCHAR pNodeBuffer,
  372. DWORD NodeBufferSize,
  373. PCHAR pServiceBuffer,
  374. DWORD ServiceBufferSize,
  375. INT Flags
  376. ) LPFN_GETNAMEINFO;
  377. alias INT function (
  378. SOCKADDR* pSockaddr,
  379. socklen_t SockaddrLength,
  380. PWCHAR pNodeBuffer,
  381. DWORD NodeBufferSize,
  382. PWCHAR pServiceBuffer,
  383. DWORD ServiceBufferSize,
  384. INT Flags
  385. ) LPFN_GETNAMEINFOW;
  386. alias LPFN_GETNAMEINFO LPFN_GETNAMEINFOA;
  387. version(UNICODE) {
  388. alias LPFN_GETNAMEINFOW LPFN_GETNAMEINFOT;
  389. }
  390. else {
  391. alias LPFN_GETNAMEINFOA LPFN_GETNAMEINFOT;
  392. }
  393. INT inet_pton(
  394. INT Family,
  395. PCSTR pszAddrString,
  396. PVOID pAddrBuf
  397. );
  398. INT InetPtonW(
  399. INT Family,
  400. PCWSTR pszAddrString,
  401. PVOID pAddrBuf
  402. );
  403. PCSTR inet_ntop(
  404. INT Family,
  405. PVOID pAddr,
  406. PSTR pStringBuf,
  407. size_t StringBufSize
  408. );
  409. PCWSTR InetNtopW(
  410. INT Family,
  411. PVOID pAddr,
  412. PWSTR pStringBuf,
  413. size_t StringBufSize
  414. );
  415. alias inet_pton InetPtonA;
  416. alias inet_ntop InetNtopA;
  417. version(UNICODE) {
  418. alias InetPtonW InetPton;
  419. alias InetNtopW InetNtop;
  420. }
  421. else {
  422. alias InetPtonA InetPton;
  423. alias InetNtopA InetNtop;
  424. }
  425. alias INT function (
  426. INT Family,
  427. PCSTR pszAddrString,
  428. PVOID pAddrBuf
  429. ) LPFN_INET_PTONA;
  430. alias INT function (
  431. INT Family,
  432. PCWSTR pszAddrString,
  433. PVOID pAddrBuf
  434. ) LPFN_INET_PTONW;
  435. alias PCSTR function (
  436. INT Family,
  437. PVOID pAddr,
  438. PSTR pStringBuf,
  439. size_t StringBufSize
  440. ) LPFN_INET_NTOPA;
  441. alias PCWSTR function (
  442. INT Family,
  443. PVOID pAddr,
  444. PWSTR pStringBuf,
  445. size_t StringBufSize
  446. ) LPFN_INET_NTOPW;
  447. version(UNICODE) {
  448. alias LPFN_INET_PTONW LPFN_INET_PTON;
  449. alias LPFN_INET_NTOPW LPFN_INET_NTOP;
  450. }
  451. else {
  452. alias LPFN_INET_PTONA LPFN_INET_PTON;
  453. alias LPFN_INET_NTOPA LPFN_INET_NTOP;
  454. }
  455. version(UNICODE) {
  456. alias gai_strerrorW gai_strerror;
  457. }
  458. else {
  459. alias gai_strerrorA gai_strerror;
  460. }
  461. // WARNING: The gai_strerror inline functions below use static buffers,
  462. // and hence are not thread-safe. We'll use buffers long enough to hold
  463. // 1k characters. Any system error messages longer than this will be
  464. // returned as empty strings. However 1k should work for the error codes
  465. // used by getaddrinfo().
  466. /*const auto GAI_STRERROR_BUFFER_SIZE = 1024;
  467. char * gai_strerrorA(
  468. int ecode) {
  469. DWORD dwMsgLen;
  470. static char buff[GAI_STRERROR_BUFFER_SIZE + 1];
  471. dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
  472. |FORMAT_MESSAGE_IGNORE_INSERTS
  473. |FORMAT_MESSAGE_MAX_WIDTH_MASK,
  474. NULL,
  475. ecode,
  476. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  477. (LPSTR)buff,
  478. GAI_STRERROR_BUFFER_SIZE,
  479. NULL);
  480. return buff;
  481. }
  482. WS2TCPIP_INLINE
  483. WCHAR *
  484. gai_strerrorW(
  485. IN int ecode
  486. )
  487. {
  488. DWORD dwMsgLen;
  489. static WCHAR buff[GAI_STRERROR_BUFFER_SIZE + 1];
  490. dwMsgLen = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
  491. |FORMAT_MESSAGE_IGNORE_INSERTS
  492. |FORMAT_MESSAGE_MAX_WIDTH_MASK,
  493. NULL,
  494. ecode,
  495. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  496. (LPWSTR)buff,
  497. GAI_STRERROR_BUFFER_SIZE,
  498. NULL);
  499. return buff;
  500. }*/
  501. const auto NI_MAXHOST = 1025 ; /* Max size of a fully-qualified domain name */
  502. const auto NI_MAXSERV = 32 ; /* Max size of a service name */
  503. /* Flags for getnameinfo() */
  504. const auto NI_NOFQDN = 0x01 ; /* Only return nodename portion for local hosts */
  505. const auto NI_NUMERICHOST = 0x02 ; /* Return numeric form of the host's address */
  506. const auto NI_NAMEREQD = 0x04 ; /* Error if the host's name not in DNS */
  507. const auto NI_NUMERICSERV = 0x08 ; /* Return numeric form of the service (port #) */
  508. const auto NI_DGRAM = 0x10 ; /* Service is a datagram service */
  509. /* Multicast source filter APIs from RFC 3678. */
  510. /*
  511. int setipv4sourcefilter(
  512. IN SOCKET Socket,
  513. IN IN_ADDR Interface,
  514. IN IN_ADDR Group,
  515. IN MULTICAST_MODE_TYPE FilterMode,
  516. IN ULONG SourceCount,
  517. IN CONST IN_ADDR *SourceList
  518. )
  519. {
  520. int Error;
  521. DWORD Size, Returned;
  522. PIP_MSFILTER Filter;
  523. if (SourceCount >
  524. (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
  525. WSASetLastError(WSAENOBUFS);
  526. return SOCKET_ERROR;
  527. }
  528. Size = IP_MSFILTER_SIZE(SourceCount);
  529. Filter = (PIP_MSFILTER) HeapAlloc(GetProcessHeap(), 0, Size);
  530. if (Filter == NULL) {
  531. WSASetLastError(WSAENOBUFS);
  532. return SOCKET_ERROR;
  533. }
  534. Filter->imsf_multiaddr = Group;
  535. Filter->imsf_interface = Interface;
  536. Filter->imsf_fmode = FilterMode;
  537. Filter->imsf_numsrc = SourceCount;
  538. if (SourceCount > 0) {
  539. CopyMemory(Filter->imsf_slist, SourceList,
  540. SourceCount * sizeof(*SourceList));
  541. }
  542. Error = WSAIoctl(Socket, SIOCSIPMSFILTER, Filter, Size, NULL, 0,
  543. &Returned, NULL, NULL);
  544. HeapFree(GetProcessHeap(), 0, Filter);
  545. return Error;
  546. }
  547. */
  548. /*
  549. WS2TCPIP_INLINE
  550. int
  551. getipv4sourcefilter(
  552. IN SOCKET Socket,
  553. IN IN_ADDR Interface,
  554. IN IN_ADDR Group,
  555. OUT MULTICAST_MODE_TYPE *FilterMode,
  556. IN OUT ULONG *SourceCount,
  557. OUT IN_ADDR *SourceList
  558. )
  559. {
  560. int Error;
  561. DWORD Size, Returned;
  562. PIP_MSFILTER Filter;
  563. if (*SourceCount >
  564. (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
  565. WSASetLastError(WSAENOBUFS);
  566. return SOCKET_ERROR;
  567. }
  568. Size = IP_MSFILTER_SIZE(*SourceCount);
  569. Filter = (PIP_MSFILTER) HeapAlloc(GetProcessHeap(), 0, Size);
  570. if (Filter == NULL) {
  571. WSASetLastError(WSAENOBUFS);
  572. return SOCKET_ERROR;
  573. }
  574. Filter->imsf_multiaddr = Group;
  575. Filter->imsf_interface = Interface;
  576. Filter->imsf_numsrc = *SourceCount;
  577. Error = WSAIoctl(Socket, SIOCGIPMSFILTER, Filter, Size, Filter, Size,
  578. &Returned, NULL, NULL);
  579. if (Error == 0) {
  580. if (*SourceCount > 0) {
  581. CopyMemory(SourceList, Filter->imsf_slist,
  582. *SourceCount * sizeof(*SourceList));
  583. *SourceCount = Filter->imsf_numsrc;
  584. }
  585. *FilterMode = Filter->imsf_fmode;
  586. }
  587. HeapFree(GetProcessHeap(), 0, Filter);
  588. return Error;
  589. }
  590. */
  591. /*
  592. WS2TCPIP_INLINE
  593. int
  594. setsourcefilter(
  595. IN SOCKET Socket,
  596. IN ULONG Interface,
  597. IN CONST SOCKADDR *Group,
  598. IN int GroupLength,
  599. IN MULTICAST_MODE_TYPE FilterMode,
  600. IN ULONG SourceCount,
  601. IN CONST SOCKADDR_STORAGE *SourceList
  602. )
  603. {
  604. int Error;
  605. DWORD Size, Returned;
  606. PGROUP_FILTER Filter;
  607. if (SourceCount >=
  608. (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
  609. WSASetLastError(WSAENOBUFS);
  610. return SOCKET_ERROR;
  611. }
  612. Size = GROUP_FILTER_SIZE(SourceCount);
  613. Filter = (PGROUP_FILTER) HeapAlloc(GetProcessHeap(), 0, Size);
  614. if (Filter == NULL) {
  615. WSASetLastError(WSAENOBUFS);
  616. return SOCKET_ERROR;
  617. }
  618. Filter->gf_interface = Interface;
  619. ZeroMemory(&Filter->gf_group, sizeof(Filter->gf_group));
  620. CopyMemory(&Filter->gf_group, Group, GroupLength);
  621. Filter->gf_fmode = FilterMode;
  622. Filter->gf_numsrc = SourceCount;
  623. if (SourceCount > 0) {
  624. CopyMemory(Filter->gf_slist, SourceList,
  625. SourceCount * sizeof(*SourceList));
  626. }
  627. Error = WSAIoctl(Socket, SIOCSMSFILTER, Filter, Size, NULL, 0,
  628. &Returned, NULL, NULL);
  629. HeapFree(GetProcessHeap(), 0, Filter);
  630. return Error;
  631. }
  632. */
  633. /*
  634. WS2TCPIP_INLINE
  635. int
  636. getsourcefilter(
  637. IN SOCKET Socket,
  638. IN ULONG Interface,
  639. IN CONST SOCKADDR *Group,
  640. IN int GroupLength,
  641. OUT MULTICAST_MODE_TYPE *FilterMode,
  642. IN OUT ULONG *SourceCount,
  643. OUT SOCKADDR_STORAGE *SourceList
  644. )
  645. {
  646. int Error;
  647. DWORD Size, Returned;
  648. PGROUP_FILTER Filter;
  649. if (*SourceCount >
  650. (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
  651. WSASetLastError(WSAENOBUFS);
  652. return SOCKET_ERROR;
  653. }
  654. Size = GROUP_FILTER_SIZE(*SourceCount);
  655. Filter = (PGROUP_FILTER) HeapAlloc(GetProcessHeap(), 0, Size);
  656. if (Filter == NULL) {
  657. WSASetLastError(WSAENOBUFS);
  658. return SOCKET_ERROR;
  659. }
  660. Filter->gf_interface = Interface;
  661. ZeroMemory(&Filter->gf_group, sizeof(Filter->gf_group));
  662. CopyMemory(&Filter->gf_group, Group, GroupLength);
  663. Filter->gf_numsrc = *SourceCount;
  664. Error = WSAIoctl(Socket, SIOCGMSFILTER, Filter, Size, Filter, Size,
  665. &Returned, NULL, NULL);
  666. if (Error == 0) {
  667. if (*SourceCount > 0) {
  668. CopyMemory(SourceList, Filter->gf_slist,
  669. *SourceCount * sizeof(*SourceList));
  670. *SourceCount = Filter->gf_numsrc;
  671. }
  672. *FilterMode = Filter->gf_fmode;
  673. }
  674. HeapFree(GetProcessHeap(), 0, Filter);
  675. return Error;
  676. }
  677. */
  678. //
  679. // Secure socket API definitions
  680. //
  681. INT WSASetSocketSecurity (
  682. SOCKET Socket,
  683. SOCKET_SECURITY_SETTINGS* SecuritySettings,
  684. ULONG SecuritySettingsLen,
  685. LPWSAOVERLAPPED Overlapped,
  686. LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
  687. );
  688. INT WSAQuerySocketSecurity (
  689. SOCKET Socket,
  690. SOCKET_SECURITY_QUERY_TEMPLATE* SecurityQueryTemplate,
  691. ULONG SecurityQueryTemplateLen,
  692. SOCKET_SECURITY_QUERY_INFO* SecurityQueryInfo,
  693. ULONG* SecurityQueryInfoLen,
  694. LPWSAOVERLAPPED Overlapped,
  695. LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
  696. );
  697. INT WSASetSocketPeerTargetName (
  698. SOCKET Socket,
  699. SOCKET_PEER_TARGET_NAME* PeerTargetName,
  700. ULONG PeerTargetNameLen,
  701. LPWSAOVERLAPPED Overlapped,
  702. LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
  703. );
  704. INT WSADeleteSocketPeerTargetName (
  705. SOCKET Socket,
  706. sockaddr* PeerAddr,
  707. ULONG PeerAddrLen,
  708. LPWSAOVERLAPPED Overlapped,
  709. LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
  710. );
  711. INT WSAImpersonateSocketPeer (
  712. SOCKET Socket,
  713. sockaddr* PeerAddr,
  714. ULONG PeerAddrLen
  715. );
  716. INT WSARevertImpersonation ();