1 /*
2 Written by Christopher E. Miller
3 $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 */
5
6
7 module core.sys.windows.winsock2;
8 version (Windows):
9 @system:
10
11 pragma(lib, "ws2_32");
12
13 extern(Windows):
14 nothrow:
15
16 alias SOCKET = size_t;
17 alias socklen_t = int;
18
19 enum SOCKET INVALID_SOCKET = cast(SOCKET)~0;
20 enum int SOCKET_ERROR = -1;
21
22 enum WSADESCRIPTION_LEN = 256;
23 enum WSASYS_STATUS_LEN = 128;
24
25 struct WSADATA
26 {
27 ushort wVersion;
28 ushort wHighVersion;
29 char[WSADESCRIPTION_LEN + 1] szDescription = 0;
30 char[WSASYS_STATUS_LEN + 1] szSystemStatus = 0;
31 ushort iMaxSockets;
32 ushort iMaxUdpDg;
33 char* lpVendorInfo;
34 }
35 alias LPWSADATA = WSADATA*;
36
37
38 enum int IOCPARM_MASK = 0x7F;
39 enum int IOC_IN = cast(int)0x80000000;
40 enum int FIONBIO = cast(int)(IOC_IN | ((uint.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126);
41
42 enum NI_MAXHOST = 1025;
43 enum NI_MAXSERV = 32;
44
45 @nogc
46 {
47 int WSAStartup(ushort wVersionRequested, LPWSADATA lpWSAData);
48 int WSACleanup();
49 SOCKET socket(int af, int type, int protocol);
50 int ioctlsocket(SOCKET s, int cmd, uint* argp);
51 int bind(SOCKET s, const(sockaddr)* name, socklen_t namelen);
52 int connect(SOCKET s, const(sockaddr)* name, socklen_t namelen);
53 int listen(SOCKET s, int backlog);
54 SOCKET accept(SOCKET s, sockaddr* addr, socklen_t* addrlen);
55 int closesocket(SOCKET s);
56 int shutdown(SOCKET s, int how);
57 int getpeername(SOCKET s, sockaddr* name, socklen_t* namelen);
58 int getsockname(SOCKET s, sockaddr* name, socklen_t* namelen);
59 int send(SOCKET s, const(void)* buf, int len, int flags);
60 int sendto(SOCKET s, const(void)* buf, int len, int flags, const(sockaddr)* to, socklen_t tolen);
61 int recv(SOCKET s, void* buf, int len, int flags);
62 int recvfrom(SOCKET s, void* buf, int len, int flags, sockaddr* from, socklen_t* fromlen);
63 int getsockopt(SOCKET s, int level, int optname, void* optval, socklen_t* optlen);
64 int setsockopt(SOCKET s, int level, int optname, const(void)* optval, socklen_t optlen);
65 uint inet_addr(const char* cp);
66 int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, const(timeval)* timeout);
67 char* inet_ntoa(in_addr ina);
68 hostent* gethostbyname(const char* name);
69 hostent* gethostbyaddr(const(void)* addr, int len, int type);
70 protoent* getprotobyname(const char* name);
71 protoent* getprotobynumber(int number);
72 servent* getservbyname(const char* name, const char* proto);
73 servent* getservbyport(int port, const char* proto);
74 }
75
76 enum: int
77 {
78 NI_NOFQDN = 0x01,
79 NI_NUMERICHOST = 0x02,
80 NI_NAMEREQD = 0x04,
81 NI_NUMERICSERV = 0x08,
82 NI_DGRAM = 0x10,
83 }
84
85 @nogc
86 {
87 int gethostname(const char* name, int namelen);
88 int getaddrinfo(const(char)* nodename, const(char)* servname, const(addrinfo)* hints, addrinfo** res);
89 void freeaddrinfo(addrinfo* ai);
90 int getnameinfo(const(sockaddr)* sa, socklen_t salen, char* host, uint hostlen, char* serv, uint servlen, int flags);
91 }
92
93 enum WSABASEERR = 10000;
94
95 enum: int
96 {
97 /*
98 * Windows Sockets definitions of regular Microsoft C error constants
99 */
100 WSAEINTR = (WSABASEERR+4),
101 WSAEBADF = (WSABASEERR+9),
102 WSAEACCES = (WSABASEERR+13),
103 WSAEFAULT = (WSABASEERR+14),
104 WSAEINVAL = (WSABASEERR+22),
105 WSAEMFILE = (WSABASEERR+24),
106
107 /*
108 * Windows Sockets definitions of regular Berkeley error constants
109 */
110 WSAEWOULDBLOCK = (WSABASEERR+35),
111 WSAEINPROGRESS = (WSABASEERR+36),
112 WSAEALREADY = (WSABASEERR+37),
113 WSAENOTSOCK = (WSABASEERR+38),
114 WSAEDESTADDRREQ = (WSABASEERR+39),
115 WSAEMSGSIZE = (WSABASEERR+40),
116 WSAEPROTOTYPE = (WSABASEERR+41),
117 WSAENOPROTOOPT = (WSABASEERR+42),
118 WSAEPROTONOSUPPORT = (WSABASEERR+43),
119 WSAESOCKTNOSUPPORT = (WSABASEERR+44),
120 WSAEOPNOTSUPP = (WSABASEERR+45),
121 WSAEPFNOSUPPORT = (WSABASEERR+46),
122 WSAEAFNOSUPPORT = (WSABASEERR+47),
123 WSAEADDRINUSE = (WSABASEERR+48),
124 WSAEADDRNOTAVAIL = (WSABASEERR+49),
125 WSAENETDOWN = (WSABASEERR+50),
126 WSAENETUNREACH = (WSABASEERR+51),
127 WSAENETRESET = (WSABASEERR+52),
128 WSAECONNABORTED = (WSABASEERR+53),
129 WSAECONNRESET = (WSABASEERR+54),
130 WSAENOBUFS = (WSABASEERR+55),
131 WSAEISCONN = (WSABASEERR+56),
132 WSAENOTCONN = (WSABASEERR+57),
133 WSAESHUTDOWN = (WSABASEERR+58),
134 WSAETOOMANYREFS = (WSABASEERR+59),
135 WSAETIMEDOUT = (WSABASEERR+60),
136 WSAECONNREFUSED = (WSABASEERR+61),
137 WSAELOOP = (WSABASEERR+62),
138 WSAENAMETOOLONG = (WSABASEERR+63),
139 WSAEHOSTDOWN = (WSABASEERR+64),
140 WSAEHOSTUNREACH = (WSABASEERR+65),
141 WSAENOTEMPTY = (WSABASEERR+66),
142 WSAEPROCLIM = (WSABASEERR+67),
143 WSAEUSERS = (WSABASEERR+68),
144 WSAEDQUOT = (WSABASEERR+69),
145 WSAESTALE = (WSABASEERR+70),
146 WSAEREMOTE = (WSABASEERR+71),
147
148 /*
149 * Extended Windows Sockets error constant definitions
150 */
151 WSASYSNOTREADY = (WSABASEERR+91),
152 WSAVERNOTSUPPORTED = (WSABASEERR+92),
153 WSANOTINITIALISED = (WSABASEERR+93),
154
155 /* Authoritative Answer: Host not found */
156 WSAHOST_NOT_FOUND = (WSABASEERR+1001),
157 HOST_NOT_FOUND = WSAHOST_NOT_FOUND,
158
159 /* Non-Authoritative: Host not found, or SERVERFAIL */
160 WSATRY_AGAIN = (WSABASEERR+1002),
161 TRY_AGAIN = WSATRY_AGAIN,
162
163 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
164 WSANO_RECOVERY = (WSABASEERR+1003),
165 NO_RECOVERY = WSANO_RECOVERY,
166
167 /* Valid name, no data record of requested type */
168 WSANO_DATA = (WSABASEERR+1004),
169 NO_DATA = WSANO_DATA,
170
171 /* no address, look for MX record */
172 WSANO_ADDRESS = WSANO_DATA,
173 NO_ADDRESS = WSANO_ADDRESS
174 }
175
176 /*
177 * Windows Sockets errors redefined as regular Berkeley error constants
178 */
179 enum: int
180 {
181 EWOULDBLOCK = WSAEWOULDBLOCK,
182 EINPROGRESS = WSAEINPROGRESS,
183 EALREADY = WSAEALREADY,
184 ENOTSOCK = WSAENOTSOCK,
185 EDESTADDRREQ = WSAEDESTADDRREQ,
186 EMSGSIZE = WSAEMSGSIZE,
187 EPROTOTYPE = WSAEPROTOTYPE,
188 ENOPROTOOPT = WSAENOPROTOOPT,
189 EPROTONOSUPPORT = WSAEPROTONOSUPPORT,
190 ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT,
191 EOPNOTSUPP = WSAEOPNOTSUPP,
192 EPFNOSUPPORT = WSAEPFNOSUPPORT,
193 EAFNOSUPPORT = WSAEAFNOSUPPORT,
194 EADDRINUSE = WSAEADDRINUSE,
195 EADDRNOTAVAIL = WSAEADDRNOTAVAIL,
196 ENETDOWN = WSAENETDOWN,
197 ENETUNREACH = WSAENETUNREACH,
198 ENETRESET = WSAENETRESET,
199 ECONNABORTED = WSAECONNABORTED,
200 ECONNRESET = WSAECONNRESET,
201 ENOBUFS = WSAENOBUFS,
202 EISCONN = WSAEISCONN,
203 ENOTCONN = WSAENOTCONN,
204 ESHUTDOWN = WSAESHUTDOWN,
205 ETOOMANYREFS = WSAETOOMANYREFS,
206 ETIMEDOUT = WSAETIMEDOUT,
207 ECONNREFUSED = WSAECONNREFUSED,
208 ELOOP = WSAELOOP,
209 ENAMETOOLONG = WSAENAMETOOLONG,
210 EHOSTDOWN = WSAEHOSTDOWN,
211 EHOSTUNREACH = WSAEHOSTUNREACH,
212 ENOTEMPTY = WSAENOTEMPTY,
213 EPROCLIM = WSAEPROCLIM,
214 EUSERS = WSAEUSERS,
215 EDQUOT = WSAEDQUOT,
216 ESTALE = WSAESTALE,
217 EREMOTE = WSAEREMOTE
218 }
219
220 enum: int
221 {
222 EAI_NONAME = WSAHOST_NOT_FOUND,
223 }
224
225 int WSAGetLastError() @trusted @nogc;
226
227
228 enum: int
229 {
230 AF_UNSPEC = 0,
231
232 AF_UNIX = 1,
233 AF_INET = 2,
234 AF_IMPLINK = 3,
235 AF_PUP = 4,
236 AF_CHAOS = 5,
237 AF_NS = 6,
238 AF_IPX = AF_NS,
239 AF_ISO = 7,
240 AF_OSI = AF_ISO,
241 AF_ECMA = 8,
242 AF_DATAKIT = 9,
243 AF_CCITT = 10,
244 AF_SNA = 11,
245 AF_DECnet = 12,
246 AF_DLI = 13,
247 AF_LAT = 14,
248 AF_HYLINK = 15,
249 AF_APPLETALK = 16,
250 AF_NETBIOS = 17,
251 AF_VOICEVIEW = 18,
252 AF_FIREFOX = 19,
253 AF_UNKNOWN1 = 20,
254 AF_BAN = 21,
255 AF_ATM = 22,
256 AF_INET6 = 23,
257 AF_CLUSTER = 24,
258 AF_12844 = 25,
259 AF_IRDA = 26,
260 AF_NETDES = 28,
261
262 AF_MAX = 29,
263
264
265 PF_UNSPEC = AF_UNSPEC,
266
267 PF_UNIX = AF_UNIX,
268 PF_INET = AF_INET,
269 PF_IMPLINK = AF_IMPLINK,
270 PF_PUP = AF_PUP,
271 PF_CHAOS = AF_CHAOS,
272 PF_NS = AF_NS,
273 PF_IPX = AF_IPX,
274 PF_ISO = AF_ISO,
275 PF_OSI = AF_OSI,
276 PF_ECMA = AF_ECMA,
277 PF_DATAKIT = AF_DATAKIT,
278 PF_CCITT = AF_CCITT,
279 PF_SNA = AF_SNA,
280 PF_DECnet = AF_DECnet,
281 PF_DLI = AF_DLI,
282 PF_LAT = AF_LAT,
283 PF_HYLINK = AF_HYLINK,
284 PF_APPLETALK = AF_APPLETALK,
285 PF_VOICEVIEW = AF_VOICEVIEW,
286 PF_FIREFOX = AF_FIREFOX,
287 PF_UNKNOWN1 = AF_UNKNOWN1,
288 PF_BAN = AF_BAN,
289 PF_INET6 = AF_INET6,
290
291 PF_MAX = AF_MAX,
292 }
293
294
295 enum: int
296 {
297 SOL_SOCKET = 0xFFFF,
298 }
299
300
301 enum: int
302 {
303 SO_DEBUG = 0x0001,
304 SO_ACCEPTCONN = 0x0002,
305 SO_REUSEADDR = 0x0004,
306 SO_KEEPALIVE = 0x0008,
307 SO_DONTROUTE = 0x0010,
308 SO_BROADCAST = 0x0020,
309 SO_USELOOPBACK = 0x0040,
310 SO_LINGER = 0x0080,
311 SO_DONTLINGER = ~SO_LINGER,
312 SO_OOBINLINE = 0x0100,
313 SO_SNDBUF = 0x1001,
314 SO_RCVBUF = 0x1002,
315 SO_SNDLOWAT = 0x1003,
316 SO_RCVLOWAT = 0x1004,
317 SO_SNDTIMEO = 0x1005,
318 SO_RCVTIMEO = 0x1006,
319 SO_ERROR = 0x1007,
320 SO_TYPE = 0x1008,
321 SO_EXCLUSIVEADDRUSE = ~SO_REUSEADDR,
322
323 TCP_NODELAY = 1,
324
325 IP_OPTIONS = 1,
326
327 IP_HDRINCL = 2,
328 IP_TOS = 3,
329 IP_TTL = 4,
330 IP_MULTICAST_IF = 9,
331 IP_MULTICAST_TTL = 10,
332 IP_MULTICAST_LOOP = 11,
333 IP_ADD_MEMBERSHIP = 12,
334 IP_DROP_MEMBERSHIP = 13,
335 IP_DONTFRAGMENT = 14,
336 IP_ADD_SOURCE_MEMBERSHIP = 15,
337 IP_DROP_SOURCE_MEMBERSHIP = 16,
338 IP_BLOCK_SOURCE = 17,
339 IP_UNBLOCK_SOURCE = 18,
340 IP_PKTINFO = 19,
341
342 IPV6_UNICAST_HOPS = 4,
343 IPV6_MULTICAST_IF = 9,
344 IPV6_MULTICAST_HOPS = 10,
345 IPV6_MULTICAST_LOOP = 11,
346 IPV6_ADD_MEMBERSHIP = 12,
347 IPV6_DROP_MEMBERSHIP = 13,
348 IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP,
349 IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP,
350 IPV6_V6ONLY = 27,
351 }
352
353
354 /// Default FD_SETSIZE value.
355 /// In C/C++, it is redefinable by #define-ing the macro before #include-ing
356 /// winsock.h. In D, use the $(D FD_CREATE) function to allocate a $(D fd_set)
357 /// of an arbitrary size.
358 enum int FD_SETSIZE = 64;
359
360
fd_set_custom(uint SETSIZE)361 struct fd_set_custom(uint SETSIZE)
362 {
363 uint fd_count;
364 SOCKET[SETSIZE] fd_array;
365 }
366
367 alias fd_set = fd_set_custom!FD_SETSIZE;
368
369 // Removes.
FD_CLR(SOCKET fd,fd_set * set)370 void FD_CLR(SOCKET fd, fd_set* set) pure @nogc
371 {
372 uint c = set.fd_count;
373 SOCKET* start = set.fd_array.ptr;
374 SOCKET* stop = start + c;
375
376 for (; start != stop; start++)
377 {
378 if (*start == fd)
379 goto found;
380 }
381 return; //not found
382
383 found:
384 for (++start; start != stop; start++)
385 {
386 *(start - 1) = *start;
387 }
388
389 set.fd_count = c - 1;
390 }
391
392
393 // Tests.
FD_ISSET(SOCKET fd,const (fd_set)* set)394 int FD_ISSET(SOCKET fd, const(fd_set)* set) pure @nogc
395 {
396 const(SOCKET)* start = set.fd_array.ptr;
397 const(SOCKET)* stop = start + set.fd_count;
398
399 for (; start != stop; start++)
400 {
401 if (*start == fd)
402 return true;
403 }
404 return false;
405 }
406
407
408 // Adds.
FD_SET(SOCKET fd,fd_set * set)409 void FD_SET(SOCKET fd, fd_set* set) pure @nogc
410 {
411 uint c = set.fd_count;
412 set.fd_array.ptr[c] = fd;
413 set.fd_count = c + 1;
414 }
415
416
417 // Resets to zero.
FD_ZERO(fd_set * set)418 void FD_ZERO(fd_set* set) pure @nogc
419 {
420 set.fd_count = 0;
421 }
422
423
424 /// Creates a new $(D fd_set) with the specified capacity.
FD_CREATE(uint capacity)425 fd_set* FD_CREATE(uint capacity) pure
426 {
427 // Take into account alignment (SOCKET may be 64-bit and require 64-bit alignment on 64-bit systems)
428 size_t size = (fd_set_custom!1).sizeof - SOCKET.sizeof + (SOCKET.sizeof * capacity);
429 auto data = new ubyte[size];
430 auto set = cast(fd_set*)data.ptr;
431 FD_ZERO(set);
432 return set;
433 }
434
435 struct linger
436 {
437 ushort l_onoff;
438 ushort l_linger;
439 }
440
441
442 struct protoent
443 {
444 char* p_name;
445 char** p_aliases;
446 short p_proto;
447 }
448
449
450 struct servent
451 {
452 char* s_name;
453 char** s_aliases;
454
versionservent455 version (Win64)
456 {
457 char* s_proto;
458 short s_port;
459 }
versionservent460 else version (Win32)
461 {
462 short s_port;
463 char* s_proto;
464 }
465 }
466
467
468 /+
469 union in6_addr
470 {
471 private union _u_t
472 {
473 ubyte[16] Byte;
474 ushort[8] Word;
475 }
476 _u_t u;
477 }
478
479
480 struct in_addr6
481 {
482 ubyte[16] s6_addr;
483 }
484 +/
485
486 @safe pure @nogc
487 {
488 ushort htons(ushort x);
489 uint htonl(uint x);
490 ushort ntohs(ushort x);
491 uint ntohl(uint x);
492 }
493
494
495 enum: int
496 {
497 SOCK_STREAM = 1,
498 SOCK_DGRAM = 2,
499 SOCK_RAW = 3,
500 SOCK_RDM = 4,
501 SOCK_SEQPACKET = 5,
502 }
503
504
505 enum: int
506 {
507 IPPROTO_IP = 0,
508 IPPROTO_ICMP = 1,
509 IPPROTO_IGMP = 2,
510 IPPROTO_GGP = 3,
511 IPPROTO_TCP = 6,
512 IPPROTO_PUP = 12,
513 IPPROTO_UDP = 17,
514 IPPROTO_IDP = 22,
515 IPPROTO_IPV6 = 41,
516 IPPROTO_ND = 77,
517 IPPROTO_RAW = 255,
518
519 IPPROTO_MAX = 256,
520 }
521
522
523 enum: int
524 {
525 MSG_OOB = 0x1,
526 MSG_PEEK = 0x2,
527 MSG_DONTROUTE = 0x4
528 }
529
530
531 enum: int
532 {
533 SD_RECEIVE = 0,
534 SD_SEND = 1,
535 SD_BOTH = 2,
536 }
537
538
539 enum: uint
540 {
541 INADDR_ANY = 0,
542 INADDR_LOOPBACK = 0x7F000001,
543 INADDR_BROADCAST = 0xFFFFFFFF,
544 INADDR_NONE = 0xFFFFFFFF,
545 ADDR_ANY = INADDR_ANY,
546 }
547
548
549 enum: int
550 {
551 AI_PASSIVE = 0x1,
552 AI_CANONNAME = 0x2,
553 AI_NUMERICHOST = 0x4,
554 AI_ADDRCONFIG = 0x0400,
555 AI_NON_AUTHORITATIVE = 0x04000,
556 AI_SECURE = 0x08000,
557 AI_RETURN_PREFERRED_NAMES = 0x010000,
558 }
559
560
561 struct timeval
562 {
563 int tv_sec;
564 int tv_usec;
565 }
566
567
568 union in_addr
569 {
570 private union _S_un_t
571 {
572 private struct _S_un_b_t
573 {
574 ubyte s_b1, s_b2, s_b3, s_b4;
575 }
576 _S_un_b_t S_un_b;
577
578 private struct _S_un_w_t
579 {
580 ushort s_w1, s_w2;
581 }
582 _S_un_w_t S_un_w;
583
584 uint S_addr;
585 }
586 _S_un_t S_un;
587
588 uint s_addr;
589
590 struct
591 {
592 ubyte s_net, s_host;
593
594 union
595 {
596 ushort s_imp;
597
598 struct
599 {
600 ubyte s_lh, s_impno;
601 }
602 }
603 }
604 }
605
606
607 union in6_addr
608 {
609 private union _in6_u_t
610 {
611 ubyte[16] u6_addr8;
612 ushort[8] u6_addr16;
613 uint[4] u6_addr32;
614 }
615 _in6_u_t in6_u;
616
617 ubyte[16] s6_addr8;
618 ushort[8] s6_addr16;
619 uint[4] s6_addr32;
620
621 alias s6_addr = s6_addr8;
622 }
623
624
625 enum in6_addr IN6ADDR_ANY = { s6_addr8: [0] };
626 enum in6_addr IN6ADDR_LOOPBACK = { s6_addr8: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] };
627 //alias IN6ADDR_ANY_INIT = IN6ADDR_ANY;
628 //alias IN6ADDR_LOOPBACK_INIT = IN6ADDR_LOOPBACK;
629
630 enum int INET_ADDRSTRLEN = 16;
631 enum int INET6_ADDRSTRLEN = 46;
632
633
634
635
636 struct sockaddr
637 {
638 short sa_family;
639 ubyte[14] sa_data;
640 }
641 alias sockaddr SOCKADDR;
642 alias SOCKADDR* PSOCKADDR, LPSOCKADDR;
643
644 struct sockaddr_storage
645 {
646 short ss_family;
647 char[6] __ss_pad1 = void;
648 long __ss_align;
649 char[112] __ss_pad2 = void;
650 }
651 alias sockaddr_storage SOCKADDR_STORAGE;
652 alias SOCKADDR_STORAGE* PSOCKADDR_STORAGE;
653
654 struct sockaddr_in
655 {
656 short sin_family = AF_INET;
657 ushort sin_port;
658 in_addr sin_addr;
659 ubyte[8] sin_zero;
660 }
661 alias sockaddr_in SOCKADDR_IN;
662 alias SOCKADDR_IN* PSOCKADDR_IN, LPSOCKADDR_IN;
663
664
665 struct sockaddr_in6
666 {
667 short sin6_family = AF_INET6;
668 ushort sin6_port;
669 uint sin6_flowinfo;
670 in6_addr sin6_addr;
671 uint sin6_scope_id;
672 }
673
674
675 struct addrinfo
676 {
677 int ai_flags;
678 int ai_family;
679 int ai_socktype;
680 int ai_protocol;
681 size_t ai_addrlen;
682 char* ai_canonname;
683 sockaddr* ai_addr;
684 addrinfo* ai_next;
685 }
686
687
688 struct hostent
689 {
690 char* h_name;
691 char** h_aliases;
692 short h_addrtype;
693 short h_length;
694 char** h_addr_list;
695
696
697 char* h_addr() @safe pure nothrow @nogc
698 {
699 return h_addr_list[0];
700 }
701 }
702
703 // Note: These are Winsock2!!
704 struct WSAOVERLAPPED;
705 alias LPWSAOVERLAPPED = WSAOVERLAPPED*;
706 alias LPWSAOVERLAPPED_COMPLETION_ROUTINE = void function(uint, uint, LPWSAOVERLAPPED, uint);
707 int WSAIoctl(SOCKET s, uint dwIoControlCode,
708 void* lpvInBuffer, uint cbInBuffer,
709 void* lpvOutBuffer, uint cbOutBuffer,
710 uint* lpcbBytesReturned,
711 LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
712
713
714 enum IOC_VENDOR = 0x18000000;
715 enum SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4;
716
717 /* Argument structure for SIO_KEEPALIVE_VALS */
718 struct tcp_keepalive
719 {
720 uint onoff;
721 uint keepalivetime;
722 uint keepaliveinterval;
723 }
724