module win32.winsock;

// Translated from Microsoft Platform SDK August 2001 Edition
// by Y.Tomino (demoonlit@inter7.jp)


// #ifndef _WINSOCKAPI_
// #define _WINSOCKAPI_

// #if _MSC_VER > 1000
// #pragma once
// #endif

// #ifndef _INC_WINDOWS
import win32.windows;
// #endif /* _INC_WINDOWS */

alias ubyte u_char;
alias ushort u_short;
alias uint u_int;
alias uint u_long;

alias UINT_PTR SOCKET;

// #ifndef FD_SETSIZE
enum : uint { FD_SETSIZE = 64 }
// #endif /* FD_SETSIZE */

struct fd_set {
  u_int fd_count;
  SOCKET fd_array[FD_SETSIZE];
}

// #ifdef __cplusplus
// extern "C" {
// #endif

extern(Windows) export int __WSAFDIsSet(SOCKET, fd_set *);

// #ifdef __cplusplus
// }
// #endif

// #define FD_CLR(fd, set) do { u_int __i; for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count ; __i++) { if (((fd_set FAR *)(set))->fd_array[__i] == fd) { while (__i < ((fd_set FAR *)(set))->fd_count-1) { ((fd_set FAR *)(set))->fd_array[__i] = ((fd_set FAR *)(set))->fd_array[__i+1]; __i++; } ((fd_set FAR *)(set))->fd_count--; break; } } } while(0)

void FD_SET(int fd, fd_set* set){ if(set.fd_count < FD_SETSIZE){ set.fd_array[set.fd_count++] = fd; }}

void FD_ZERO(fd_set* set){ set.fd_count = 0; }

// #define FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)(fd), (fd_set FAR *)(set))

struct timeval {
  int tv_sec;
  int tv_usec;
}

// #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
// #define timercmp(tvp, uvp, cmp) ((tvp)->tv_sec cmp (uvp)->tv_sec || (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
// #define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0

enum : uint { IOCPARM_MASK = 0x7f }
enum : uint { IOC_VOID = 0x20000000 }
enum : uint { IOC_OUT = 0x40000000 }
enum : uint { IOC_IN = 0x80000000 }
enum : uint { IOC_INOUT = IOC_IN|IOC_OUT }

// #define _IO(x,y) (IOC_VOID|((x)<<8)|(y))

// #define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))

// #define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))

// #define FIONREAD _IOR('f', 127, u_long)
// #define FIONBIO _IOW('f', 126, u_long)
// #define FIOASYNC _IOW('f', 125, u_long)

// #define SIOCSHIWAT _IOW('s', 0, u_long)
// #define SIOCGHIWAT _IOR('s', 1, u_long)
// #define SIOCSLOWAT _IOW('s', 2, u_long)
// #define SIOCGLOWAT _IOR('s', 3, u_long)
// #define SIOCATMARK _IOR('s', 7, u_long)

struct hostent {
  char * h_name;
  char** h_aliases;
  short h_addrtype;
  short h_length;
  char** h_addr_list;
// #define h_addr h_addr_list[0]
}

struct netent {
  char * n_name;
  char** n_aliases;
  short n_addrtype;
  u_long n_net;
}

struct servent {
  char * s_name;
  char** s_aliases;
// #ifdef _WIN64
// ...
// #else
  short s_port;
  char * s_proto;
// #endif
}

struct protoent {
  char * p_name;
  char** p_aliases;
  short p_proto;
}

enum : uint { IPPROTO_IP = 0 }
enum : uint { IPPROTO_ICMP = 1 }
enum : uint { IPPROTO_IGMP = 2 }
enum : uint { IPPROTO_GGP = 3 }
enum : uint { IPPROTO_TCP = 6 }
enum : uint { IPPROTO_PUP = 12 }
enum : uint { IPPROTO_UDP = 17 }
enum : uint { IPPROTO_IDP = 22 }
enum : uint { IPPROTO_ND = 77 }

enum : uint { IPPROTO_RAW = 255 }
enum : uint { IPPROTO_MAX = 256 }

enum : uint { IPPORT_ECHO = 7 }
enum : uint { IPPORT_DISCARD = 9 }
enum : uint { IPPORT_SYSTAT = 11 }
enum : uint { IPPORT_DAYTIME = 13 }
enum : uint { IPPORT_NETSTAT = 15 }
enum : uint { IPPORT_FTP = 21 }
enum : uint { IPPORT_TELNET = 23 }
enum : uint { IPPORT_SMTP = 25 }
enum : uint { IPPORT_TIMESERVER = 37 }
enum : uint { IPPORT_NAMESERVER = 42 }
enum : uint { IPPORT_WHOIS = 43 }
enum : uint { IPPORT_MTP = 57 }

enum : uint { IPPORT_TFTP = 69 }
enum : uint { IPPORT_RJE = 77 }
enum : uint { IPPORT_FINGER = 79 }
enum : uint { IPPORT_TTYLINK = 87 }
enum : uint { IPPORT_SUPDUP = 95 }

enum : uint { IPPORT_EXECSERVER = 512 }
enum : uint { IPPORT_LOGINSERVER = 513 }
enum : uint { IPPORT_CMDSERVER = 514 }
enum : uint { IPPORT_EFSSERVER = 520 }

enum : uint { IPPORT_BIFFUDP = 512 }
enum : uint { IPPORT_WHOSERVER = 513 }
enum : uint { IPPORT_ROUTESERVER = 520 }

enum : uint { IPPORT_RESERVED = 1024 }

enum : uint { IMPLINK_IP = 155 }
enum : uint { IMPLINK_LOWEXPER = 156 }
enum : uint { IMPLINK_HIGHEXPER = 158 }

struct in_addr {
union {
  struct { u_char s_b1,s_b2,s_b3,s_b4; }
  struct { u_short s_w1,s_w2; }
  u_long S_addr;
}

// #define s_addr S_un.S_addr

// #define s_host S_un.S_un_b.s_b2

// #define s_net S_un.S_un_b.s_b1

// #define s_imp S_un.S_un_w.s_w2

// #define s_impno S_un.S_un_b.s_b4

// #define s_lh S_un.S_un_b.s_b3

}

// #define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0)
enum : uint { IN_CLASSA_NET = 0xff000000 }
enum : uint { IN_CLASSA_NSHIFT = 24 }
enum : uint { IN_CLASSA_HOST = 0x00ffffff }
enum : uint { IN_CLASSA_MAX = 128 }

// #define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000)
// #define IN_CLASSB_NET 0xffff0000
// #define IN_CLASSB_NSHIFT 16
enum : uint { IN_CLASSB_HOST = 0x0000ffff }
enum : uint { IN_CLASSB_MAX = 65536 }

// #define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000)
// #define IN_CLASSC_NET 0xffffff00
// #define IN_CLASSC_NSHIFT 8
enum : uint { IN_CLASSC_HOST = 0x000000ff }

enum : uint { INADDR_ANY = 0 }
enum : uint { INADDR_LOOPBACK = 0x7f000001 }
// #define INADDR_BROADCAST (u_long)0xffffffff
enum : uint { INADDR_NONE = uint.max }

struct sockaddr_in {
  short sin_family;
  u_short sin_port;
  in_addr sin_addr;
  char sin_zero[8];
}

enum : uint { WSADESCRIPTION_LEN = 256 }
enum : uint { WSASYS_STATUS_LEN = 128 }

struct WSAData {
  WORD wVersion;
  WORD wHighVersion;
// #ifdef _WIN64
// ...
// #else
  char szDescription[WSADESCRIPTION_LEN+1];
  char szSystemStatus[WSASYS_STATUS_LEN+1];
  ushort iMaxSockets;
  ushort iMaxUdpDg;
  char *              lpVendorInfo;
// #endif
}
alias WSAData WSADATA;

alias WSADATA* LPWSADATA;

enum : uint { IP_OPTIONS = 1 }
enum : uint { IP_MULTICAST_IF = 2 }
enum : uint { IP_MULTICAST_TTL = 3 }
enum : uint { IP_MULTICAST_LOOP = 4 }
enum : uint { IP_ADD_MEMBERSHIP = 5 }
enum : uint { IP_DROP_MEMBERSHIP = 6 }
enum : uint { IP_TTL = 7 }
enum : uint { IP_TOS = 8 }
enum : uint { IP_DONTFRAGMENT = 9 }

enum : uint { IP_DEFAULT_MULTICAST_TTL = 1 }
enum : uint { IP_DEFAULT_MULTICAST_LOOP = 1 }
enum : uint { IP_MAX_MEMBERSHIPS = 20 }

struct ip_mreq {
  in_addr imr_multiaddr;
  in_addr imr_interface;
}

enum : uint { INVALID_SOCKET = uint.max }
enum { SOCKET_ERROR = -1 }

enum : uint { SOCK_STREAM = 1 }
enum : uint { SOCK_DGRAM = 2 }
enum : uint { SOCK_RAW = 3 }
enum : uint { SOCK_RDM = 4 }
enum : uint { SOCK_SEQPACKET = 5 }

enum : uint { SO_DEBUG = 0x0001 }
enum : uint { SO_ACCEPTCONN = 0x0002 }
enum : uint { SO_REUSEADDR = 0x0004 }
enum : uint { SO_KEEPALIVE = 0x0008 }
enum : uint { SO_DONTROUTE = 0x0010 }
enum : uint { SO_BROADCAST = 0x0020 }
enum : uint { SO_USELOOPBACK = 0x0040 }
enum : uint { SO_LINGER = 0x0080 }
enum : uint { SO_OOBINLINE = 0x0100 }

enum : uint { SO_DONTLINGER = ~SO_LINGER }

enum : uint { SO_SNDBUF = 0x1001 }
enum : uint { SO_RCVBUF = 0x1002 }
enum : uint { SO_SNDLOWAT = 0x1003 }
enum : uint { SO_RCVLOWAT = 0x1004 }
enum : uint { SO_SNDTIMEO = 0x1005 }
enum : uint { SO_RCVTIMEO = 0x1006 }
enum : uint { SO_ERROR = 0x1007 }
enum : uint { SO_TYPE = 0x1008 }

enum : uint { SO_CONNDATA = 0x7000 }
enum : uint { SO_CONNOPT = 0x7001 }
enum : uint { SO_DISCDATA = 0x7002 }
enum : uint { SO_DISCOPT = 0x7003 }
enum : uint { SO_CONNDATALEN = 0x7004 }
enum : uint { SO_CONNOPTLEN = 0x7005 }
enum : uint { SO_DISCDATALEN = 0x7006 }
enum : uint { SO_DISCOPTLEN = 0x7007 }

enum : uint { SO_OPENTYPE = 0x7008 }

enum : uint { SO_SYNCHRONOUS_ALERT = 0x10 }
enum : uint { SO_SYNCHRONOUS_NONALERT = 0x20 }

enum : uint { SO_MAXDG = 0x7009 }
enum : uint { SO_MAXPATHDG = 0x700A }
enum : uint { SO_UPDATE_ACCEPT_CONTEXT = 0x700B }
enum : uint { SO_CONNECT_TIME = 0x700C }

enum : uint { TCP_NODELAY = 0x0001 }
enum : uint { TCP_BSDURGENT = 0x7000 }

enum : uint { AF_UNSPEC = 0 }
enum : uint { AF_UNIX = 1 }
enum : uint { AF_INET = 2 }
enum : uint { AF_IMPLINK = 3 }
enum : uint { AF_PUP = 4 }
enum : uint { AF_CHAOS = 5 }
enum : uint { AF_IPX = 6 }
enum : uint { AF_NS = 6 }
enum : uint { AF_ISO = 7 }
alias AF_ISO AF_OSI;
enum : uint { AF_ECMA = 8 }
enum : uint { AF_DATAKIT = 9 }
enum : uint { AF_CCITT = 10 }
enum : uint { AF_SNA = 11 }
enum : uint { AF_DECnet = 12 }
enum : uint { AF_DLI = 13 }
enum : uint { AF_LAT = 14 }
enum : uint { AF_HYLINK = 15 }
enum : uint { AF_APPLETALK = 16 }
enum : uint { AF_NETBIOS = 17 }
enum : uint { AF_VOICEVIEW = 18 }
enum : uint { AF_FIREFOX = 19 }
enum : uint { AF_UNKNOWN1 = 20 }
enum : uint { AF_BAN = 21 }

enum : uint { AF_MAX = 22 }

struct sockaddr {
  u_short sa_family;
  char sa_data[14];
}

struct sockproto {
  u_short sp_family;
  u_short sp_protocol;
}

alias AF_UNSPEC PF_UNSPEC;
alias AF_UNIX PF_UNIX;
alias AF_INET PF_INET;
alias AF_IMPLINK PF_IMPLINK;
alias AF_PUP PF_PUP;
alias AF_CHAOS PF_CHAOS;
alias AF_NS PF_NS;
alias AF_IPX PF_IPX;
alias AF_ISO PF_ISO;
alias AF_OSI PF_OSI;
alias AF_ECMA PF_ECMA;
alias AF_DATAKIT PF_DATAKIT;
alias AF_CCITT PF_CCITT;
alias AF_SNA PF_SNA;
alias AF_DECnet PF_DECnet;
alias AF_DLI PF_DLI;
alias AF_LAT PF_LAT;
alias AF_HYLINK PF_HYLINK;
alias AF_APPLETALK PF_APPLETALK;
alias AF_VOICEVIEW PF_VOICEVIEW;
alias AF_FIREFOX PF_FIREFOX;
alias AF_UNKNOWN1 PF_UNKNOWN1;
alias AF_BAN PF_BAN;

alias AF_MAX PF_MAX;

struct linger {
  u_short l_onoff;
  u_short l_linger;
}

enum : uint { SOL_SOCKET = 0xffff }

enum : uint { SOMAXCONN = 5 }

enum : uint { MSG_OOB = 0x1 }
enum : uint { MSG_PEEK = 0x2 }
enum : uint { MSG_DONTROUTE = 0x4 }

enum : uint { MSG_MAXIOVLEN = 16 }

enum : uint { MSG_PARTIAL = 0x8000 }

enum : uint { MAXGETHOSTSTRUCT = 1024 }

enum : uint { FD_READ = 0x01 }
enum : uint { FD_WRITE = 0x02 }
enum : uint { FD_OOB = 0x04 }
enum : uint { FD_ACCEPT = 0x08 }
enum : uint { FD_CONNECT = 0x10 }
enum : uint { FD_CLOSE = 0x20 }

// #ifndef WSABASEERR

enum : uint { WSABASEERR = 10000 }

enum : uint { WSAEINTR = WSABASEERR+4 }
enum : uint { WSAEBADF = WSABASEERR+9 }
enum : uint { WSAEACCES = WSABASEERR+13 }
enum : uint { WSAEFAULT = WSABASEERR+14 }
enum : uint { WSAEINVAL = WSABASEERR+22 }
enum : uint { WSAEMFILE = WSABASEERR+24 }

enum : uint { WSAEWOULDBLOCK = WSABASEERR+35 }
enum : uint { WSAEINPROGRESS = WSABASEERR+36 }
enum : uint { WSAEALREADY = WSABASEERR+37 }
enum : uint { WSAENOTSOCK = WSABASEERR+38 }
enum : uint { WSAEDESTADDRREQ = WSABASEERR+39 }
enum : uint { WSAEMSGSIZE = WSABASEERR+40 }
enum : uint { WSAEPROTOTYPE = WSABASEERR+41 }
enum : uint { WSAENOPROTOOPT = WSABASEERR+42 }
enum : uint { WSAEPROTONOSUPPORT = WSABASEERR+43 }
enum : uint { WSAESOCKTNOSUPPORT = WSABASEERR+44 }
enum : uint { WSAEOPNOTSUPP = WSABASEERR+45 }
enum : uint { WSAEPFNOSUPPORT = WSABASEERR+46 }
enum : uint { WSAEAFNOSUPPORT = WSABASEERR+47 }
enum : uint { WSAEADDRINUSE = WSABASEERR+48 }
enum : uint { WSAEADDRNOTAVAIL = WSABASEERR+49 }
enum : uint { WSAENETDOWN = WSABASEERR+50 }
enum : uint { WSAENETUNREACH = WSABASEERR+51 }
enum : uint { WSAENETRESET = WSABASEERR+52 }
enum : uint { WSAECONNABORTED = WSABASEERR+53 }
enum : uint { WSAECONNRESET = WSABASEERR+54 }
enum : uint { WSAENOBUFS = WSABASEERR+55 }
enum : uint { WSAEISCONN = WSABASEERR+56 }
enum : uint { WSAENOTCONN = WSABASEERR+57 }
enum : uint { WSAESHUTDOWN = WSABASEERR+58 }
enum : uint { WSAETOOMANYREFS = WSABASEERR+59 }
enum : uint { WSAETIMEDOUT = WSABASEERR+60 }
enum : uint { WSAECONNREFUSED = WSABASEERR+61 }
enum : uint { WSAELOOP = WSABASEERR+62 }
enum : uint { WSAENAMETOOLONG = WSABASEERR+63 }
enum : uint { WSAEHOSTDOWN = WSABASEERR+64 }
enum : uint { WSAEHOSTUNREACH = WSABASEERR+65 }
enum : uint { WSAENOTEMPTY = WSABASEERR+66 }
enum : uint { WSAEPROCLIM = WSABASEERR+67 }
enum : uint { WSAEUSERS = WSABASEERR+68 }
enum : uint { WSAEDQUOT = WSABASEERR+69 }
enum : uint { WSAESTALE = WSABASEERR+70 }
enum : uint { WSAEREMOTE = WSABASEERR+71 }

enum : uint { WSAEDISCON = WSABASEERR+101 }

enum : uint { WSASYSNOTREADY = WSABASEERR+91 }
enum : uint { WSAVERNOTSUPPORTED = WSABASEERR+92 }
enum : uint { WSANOTINITIALISED = WSABASEERR+93 }

enum : uint { WSAHOST_NOT_FOUND = WSABASEERR+1001 }

enum : uint { WSATRY_AGAIN = WSABASEERR+1002 }

enum : uint { WSANO_RECOVERY = WSABASEERR+1003 }

enum : uint { WSANO_DATA = WSABASEERR+1004 }

// #endif /* ifdef WSABASEERR */

// #define h_errno WSAGetLastError()
alias WSAHOST_NOT_FOUND HOST_NOT_FOUND;
alias WSATRY_AGAIN TRY_AGAIN;
alias WSANO_RECOVERY NO_RECOVERY;
alias WSANO_DATA NO_DATA;

alias WSANO_DATA WSANO_ADDRESS;
alias WSANO_ADDRESS NO_ADDRESS;

// #if 0
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #...
// #endif

// #ifdef __cplusplus
// extern "C" {
// #endif

extern(Windows) export SOCKET accept(
  SOCKET s,
  sockaddr *addr,
  int *addrlen);

extern(Windows) export int bind(
  SOCKET s,
  sockaddr *addr,
  int namelen);

extern(Windows) export int closesocket(SOCKET s);

extern(Windows) export int connect(
  SOCKET s,
  sockaddr *name,
  int namelen);

extern(Windows) export int ioctlsocket(
  SOCKET s,
  int cmd,
  u_long *argp);

extern(Windows) export int getpeername(
  SOCKET s,
  sockaddr *name,
  int * namelen);

extern(Windows) export int getsockname(
  SOCKET s,
  sockaddr *name,
  int * namelen);

extern(Windows) export int getsockopt(
  SOCKET s,
  int level,
  int optname,
  char * optval,
  int *optlen);

extern(Windows) export u_long htonl(u_long hostlong);

extern(Windows) export u_short htons(u_short hostshort);

extern(Windows) export uint inet_addr(  char  * cp);

extern(Windows) export char* inet_ntoa(uint in_);
extern(Windows) export int listen(
  SOCKET s,
  int backlog);

extern(Windows) export u_long ntohl(u_long netlong);

extern(Windows) export u_short ntohs(u_short netshort);

extern(Windows) export int recv(
  SOCKET s,
  char * buf,
  int len,
  int flags);

extern(Windows) export int recvfrom(
  SOCKET s,
  char * buf,
  int len,
  int flags,
  sockaddr *from,
  int * fromlen);

extern(Windows) export int select(
  int nfds,
  fd_set *readfds,
  fd_set *writefds,
  fd_set *exceptfds,
  timeval *timeout);

extern(Windows) export int send(
  SOCKET s,
  char * buf,
  int len,
  int flags);

extern(Windows) export int sendto(
  SOCKET s,
  char * buf,
  int len,
  int flags,
  sockaddr *to,
  int tolen);

extern(Windows) export int setsockopt(
  SOCKET s,
  int level,
  int optname,
  char * optval,
  int optlen);

extern(Windows) export int shutdown(
  SOCKET s,
  int how);

extern(Windows) export SOCKET socket(
  int af,
  int type,
  int protocol);

extern(Windows) export hostent* gethostbyaddr(
  char  * addr,
  int len,
  int type);
extern(Windows) export hostent* gethostbyname(  char  * name);
extern(Windows) export int gethostname(
  char * name,
  int namelen);

extern(Windows) export servent* getservbyport(
  int port,
  char  * proto);
extern(Windows) export servent* getservbyname(
  char  * name,
  char  * proto);
extern(Windows) export protoent* getprotobynumber( int proto);
extern(Windows) export protoent* getprotobyname(  char  * name);

extern(Windows) export int WSAStartup(
  WORD wVersionRequired,
  LPWSADATA lpWSAData);

extern(Windows) export int WSACleanup();

extern(Windows) export void WSASetLastError(int iError);

extern(Windows) export int WSAGetLastError();

extern(Windows) export BOOL WSAIsBlocking();

extern(Windows) export int WSAUnhookBlockingHook();

extern(Windows) export FARPROC WSASetBlockingHook(FARPROC lpBlockFunc);

extern(Windows) export int WSACancelBlockingCall();

extern(Windows) export HANDLE WSAAsyncGetServByName(
  HWND hWnd,
  u_int wMsg,
  char * name,
  char * proto,
  char * buf,
  int buflen);

extern(Windows) export HANDLE WSAAsyncGetServByPort(
  HWND hWnd,
  u_int wMsg,
  int port,
  char * proto,
  char * buf,
  int buflen);

extern(Windows) export HANDLE WSAAsyncGetProtoByName(
  HWND hWnd,
  u_int wMsg,
  char * name,
  char * buf,
  int buflen);

extern(Windows) export HANDLE WSAAsyncGetProtoByNumber(
  HWND hWnd,
  u_int wMsg,
  int number,
  char * buf,
  int buflen);

extern(Windows) export HANDLE WSAAsyncGetHostByName(
  HWND hWnd,
  u_int wMsg,
  char * name,
  char * buf,
  int buflen);

extern(Windows) export HANDLE WSAAsyncGetHostByAddr(
  HWND hWnd,
  u_int wMsg,
  char * addr,
  int len,
  int type,
  char * buf,
  int buflen);

extern(Windows) export int WSACancelAsyncRequest(HANDLE hAsyncTaskHandle);

extern(Windows) export int WSAAsyncSelect(
  SOCKET s,
  HWND hWnd,
  u_int wMsg,
  int lEvent);

extern(Windows) export int WSARecvEx(
  SOCKET s,
  char * buf,
  int len,
  int *flags);

struct _TRANSMIT_FILE_BUFFERS {
  PVOID Head;
  DWORD HeadLength;
  PVOID Tail;
  DWORD TailLength;
}
alias _TRANSMIT_FILE_BUFFERS TRANSMIT_FILE_BUFFERS;
alias _TRANSMIT_FILE_BUFFERS* PTRANSMIT_FILE_BUFFERS;
alias _TRANSMIT_FILE_BUFFERS* LPTRANSMIT_FILE_BUFFERS;

enum : uint { TF_DISCONNECT = 0x01 }
enum : uint { TF_REUSE_SOCKET = 0x02 }
enum : uint { TF_WRITE_BEHIND = 0x04 }

extern(Windows) export BOOL TransmitFile(
  SOCKET hSocket,
  HANDLE hFile,
  DWORD nNumberOfBytesToWrite,
  DWORD nNumberOfBytesPerSend,
  LPOVERLAPPED lpOverlapped,
  LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
  DWORD dwReserved);

extern(Windows) export BOOL AcceptEx(
  SOCKET sListenSocket,
  SOCKET sAcceptSocket,
  PVOID lpOutputBuffer,
  DWORD dwReceiveDataLength,
  DWORD dwLocalAddressLength,
  DWORD dwRemoteAddressLength,
  LPDWORD lpdwBytesReceived,
  LPOVERLAPPED lpOverlapped);

extern(Windows) export VOID GetAcceptExSockaddrs(
  PVOID lpOutputBuffer,
  DWORD dwReceiveDataLength,
  DWORD dwLocalAddressLength,
  DWORD dwRemoteAddressLength,
  sockaddr **LocalSockaddr,
  LPINT LocalSockaddrLength,
  sockaddr **RemoteSockaddr,
  LPINT RemoteSockaddrLength);

// #ifdef __cplusplus
// }
// #endif

alias sockaddr SOCKADDR;
alias sockaddr* PSOCKADDR;
alias sockaddr* LPSOCKADDR;

alias sockaddr_in SOCKADDR_IN;
alias sockaddr_in* PSOCKADDR_IN;
alias sockaddr_in* LPSOCKADDR_IN;

alias linger LINGER;
alias linger* PLINGER;
alias linger* LPLINGER;

alias in_addr IN_ADDR;
alias in_addr* PIN_ADDR;
alias in_addr* LPIN_ADDR;

alias fd_set FD_SET;
alias fd_set* PFD_SET;
alias fd_set* LPFD_SET;

alias hostent HOSTENT;
alias hostent* PHOSTENT;
alias hostent* LPHOSTENT;

alias servent SERVENT;
alias servent* PSERVENT;
alias servent* LPSERVENT;

alias protoent PROTOENT;
alias protoent* PPROTOENT;
alias protoent* LPPROTOENT;

alias timeval TIMEVAL;
alias timeval* PTIMEVAL;
alias timeval* LPTIMEVAL;

// #define WSAMAKEASYNCREPLY(buflen,error) MAKELONG(buflen,error)

// #define WSAMAKESELECTREPLY(event,error) MAKELONG(event,error)

// #define WSAGETASYNCBUFLEN(lParam) LOWORD(lParam)

// #define WSAGETASYNCERROR(lParam) HIWORD(lParam)

// #define WSAGETSELECTEVENT(lParam) LOWORD(lParam)

// #define WSAGETSELECTERROR(lParam) HIWORD(lParam)

// #ifdef IPV6STRICT
// #...
// #endif // IPV6STRICT

// #endif  /* _WINSOCKAPI_ */
