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