PageRenderTime 92ms CodeModel.GetById 18ms app.highlight 69ms RepoModel.GetById 1ms app.codeStats 0ms

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