{ +-------------------------------------------------------------+ }
{ |                                                             | }
{ |   GM-Software                                               | }
{ |   ===========                                               | }
{ |                                                             | }
{ |   Project: All Projects                                     | }
{ |                                                             | }
{ |   Description: Platform independent Socket API modified     | }
{ |                and enhanced.                                | }
{ |                                                             | }
{ |   Copyright (C) - 2012 - Gerrit Moeller.                    | }
{ |                                                             | }
{ |   Source code dstributed under MIT license.                 | }
{ |                                                             | }
{ |   See: https://www.gm-software.de                           | }
{ |                                                             | }
{ +-------------------------------------------------------------+ }

{$INCLUDE GMCompilerSettings.inc}

unit GMSocketAPI;

{$WEAKPACKAGEUNIT}

interface

uses {$IFDEF JEDIAPI}jwaWinType,{$ELSE}Windows,{$ENDIF} GMStrDef;

const
  {$IFDEF WINSOCK1}
  cStrWinsockDLLName = 'wsock32.dll';
  {$ELSE}
  cStrWinsockDLLName = 'ws2_32.dll';
  {$ENDIF}

  cWinsockVersion101 = $0101;
  cWinsockVersion202 = $0202;


type

  {$EXTERNALSYM u_short}
  u_short = Word;
  {$EXTERNALSYM u_int}
  u_int = LongWord; // LongInt;
  {$EXTERNALSYM u_long}
  u_long = LongWord; //LongInt;

  {$EXTERNALSYM TSocket}
  TSocket = PtrUInt;

const
  {$EXTERNALSYM FD_SETSIZE}
  FD_SETSIZE     =   64;

// WinSock 2 extension -- manifest constants for shutdown()
  {$EXTERNALSYM SD_RECEIVE}
  SD_RECEIVE     = 0;
  {$EXTERNALSYM SD_SEND}
  SD_SEND        = 1;
  {$EXTERNALSYM SD_BOTH}
  SD_BOTH        = 2;

type

  {$NODEFINE PFDSet}
  PFDSet = ^TFDSet;
  {$NODEFINE TFDSet}
  TFDSet = record
    fd_count: u_int;
    fd_array: array[0..FD_SETSIZE-1] of TSocket;
  end;

  PTimeVal = ^TTimeVal;
  {$EXTERNALSYM timeval}
  timeval = record
    tv_sec: LongInt;
    tv_usec: LongInt;
  end;
  TTimeVal = timeval;

const
  {$EXTERNALSYM IOCPARM_MASK}
  IOCPARM_MASK = $7f;
  {$EXTERNALSYM IOC_VOID}
  IOC_VOID     = $20000000;
  {$EXTERNALSYM IOC_OUT}
  IOC_OUT      = $40000000;
  {$EXTERNALSYM IOC_IN}
  IOC_IN       = $80000000;
  {$EXTERNALSYM IOC_INOUT}
  IOC_INOUT    = (IOC_IN or IOC_OUT);

  {$EXTERNALSYM FIONREAD}
  FIONREAD     = IOC_OUT or { get # bytes to read }
    ((LongInt(SizeOf(LongInt)) and IOCPARM_MASK) shl 16) or
    (LongInt(Byte('f')) shl 8) or 127;
  {$EXTERNALSYM FIONBIO}
  FIONBIO      = IOC_IN or { set/clear non-blocking i/o }
    ((LongInt(SizeOf(LongInt)) and IOCPARM_MASK) shl 16) or
    (LongInt(Byte('f')) shl 8) or 126;
  {$EXTERNALSYM FIOASYNC}
  FIOASYNC     = IOC_IN or { set/clear async i/o }
    ((LongInt(SizeOf(LongInt)) and IOCPARM_MASK) shl 16) or
    (LongInt(Byte('f')) shl 8) or 125;

type
  PHostEnt = ^THostEnt;
  {$EXTERNALSYM hostent}
  hostent = record
    h_name: PAnsiChar;
    h_aliases: ^PAnsiChar;
    h_addrtype: Smallint;
    h_length: Smallint;
    case Byte of
      0: (h_addr_list: ^PAnsiChar);
      1: (h_addr: ^PAnsiChar)
  end;
  THostEnt = hostent;

  PNetEnt = ^TNetEnt;
  {$EXTERNALSYM netent}
  netent = record
    n_name: PAnsiChar;
    n_aliases: ^PAnsiChar;
    n_addrtype: Smallint;
    n_net: u_long;
  end;
  TNetEnt = netent;

  PServEnt = ^TServEnt;
  {$EXTERNALSYM servent}
  servent = record
    s_name: PAnsiChar;
    s_aliases: ^PAnsiChar;
    s_port: Word;
    s_proto: PAnsiChar;
  end;
  TServEnt = servent;

  PProtoEnt = ^TProtoEnt;
  {$EXTERNALSYM protoent}
  protoent = record
    p_name: PAnsiChar;
    p_aliases: ^PAnsiChar;
    p_proto: Smallint;
  end;
  TProtoEnt = protoent;

const

  // Protocols

  {$EXTERNALSYM IPPROTO_IP}
  IPPROTO_IP     =   0;             // dummy for IP 
  {$EXTERNALSYM IPPROTO_ICMP}
  IPPROTO_ICMP   =   1;             // control message protocol 
  {$EXTERNALSYM IPPROTO_IGMP}
  IPPROTO_IGMP   =   2;             // group management protocol 
  {$EXTERNALSYM BTHPROTO_RFCOMM}
  BTHPROTO_RFCOMM =   3;            // gateway^2 (deprecated) 
  {$EXTERNALSYM IPPROTO_TCP}
  IPPROTO_TCP    =   6;             // tcp 
  {$EXTERNALSYM IPPROTO_PUP}
  IPPROTO_PUP    =  12;             // pup 
  {$EXTERNALSYM IPPROTO_UDP}
  IPPROTO_UDP    =  17;             // user datagram protocol 
  {$EXTERNALSYM IPPROTO_IDP}
  IPPROTO_IDP    =  22;             // xns idp 
  {$EXTERNALSYM IPPROTO_ICMPV6}
  IPPROTO_ICMPV6 = 58;
  {$EXTERNALSYM IPPROTO_ND}
  IPPROTO_ND     =  77;             // UNOFFICIAL net disk proto 
  {$EXTERNALSYM IPPROTO_RM}
  IPPROTO_RM     = 113;

  {$EXTERNALSYM IPPROTO_RAW}
  IPPROTO_RAW    =  255;            // raw IP packet 
  {$EXTERNALSYM IPPROTO_MAX}
  IPPROTO_MAX    =  256;

  // Port/socket numbers: network standard functions

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

  // Port/socket numbers: host specific functions 

  {$EXTERNALSYM IPPORT_TFTP}
  IPPORT_TFTP        =  69;
  {$EXTERNALSYM IPPORT_RJE}
  IPPORT_RJE         =  77;
  {$EXTERNALSYM IPPORT_FINGER}
  IPPORT_FINGER      =  79;
  {$EXTERNALSYM IPPORT_TTYLINK}
  IPPORT_TTYLINK     =  87;
  {$EXTERNALSYM IPPORT_SUPDUP}
  IPPORT_SUPDUP      =  95;

  // UNIX TCP sockets 

  {$EXTERNALSYM IPPORT_EXECSERVER}
  IPPORT_EXECSERVER  =  512;
  {$EXTERNALSYM IPPORT_LOGINSERVER}
  IPPORT_LOGINSERVER =  513;
  {$EXTERNALSYM IPPORT_CMDSERVER}
  IPPORT_CMDSERVER   =  514;
  {$EXTERNALSYM IPPORT_EFSSERVER}
  IPPORT_EFSSERVER   =  520;

  // UNIX UDP sockets 

  {$EXTERNALSYM IPPORT_BIFFUDP}
  IPPORT_BIFFUDP     =  512;
  {$EXTERNALSYM IPPORT_WHOSERVER}
  IPPORT_WHOSERVER   =  513;
  {$EXTERNALSYM IPPORT_ROUTESERVER}
  IPPORT_ROUTESERVER =  520;

  // Ports < IPPORT_RESERVED are reserved for privileged processes (e.g. root). 

  {$EXTERNALSYM IPPORT_RESERVED}
  IPPORT_RESERVED    =  1024;

  // Link numbers 

  {$EXTERNALSYM IMPLINK_IP}
  IMPLINK_IP         =  155;
  {$EXTERNALSYM IMPLINK_LOWEXPER}
  IMPLINK_LOWEXPER   =  156;
  {$EXTERNALSYM IMPLINK_HIGHEXPER}
  IMPLINK_HIGHEXPER  =  158;

type
  SunBArr = packed record
    s_bArr: array [0..3] of Byte; //u_char;
  end;

  {$EXTERNALSYM SunB}
  SunB = packed record
    s_b1, s_b2, s_b3, s_b4: Byte; //u_char;
  end;

  {$EXTERNALSYM SunW}
  SunW = packed record
    s_w1, s_w2: u_short;
  end;

  PInAddr = ^TInAddr;
  {$EXTERNALSYM in_addr}
  in_addr = record
    case LongInt of
      0: (S_un_b: SunB);
      1: (S_un_w: SunW);
      2: (S_addr: u_long);
      3: (s_b_Arr: SunBArr);
  end;
  TInAddr = in_addr;

  PSockAddrIn = ^TSockAddrIn;
  {$EXTERNALSYM sockaddr_in}
  sockaddr_in = record
    case LongInt of
      0: (sin_family: u_short;
          sin_port: u_short;
          sin_addr: TInAddr;
          sin_zero: array[0..7] of AnsiChar);
      1: (sa_family: u_short;
          sa_data: array[0..13] of AnsiChar)
  end;
  TSockAddrIn = sockaddr_in;

  PInAddr6 = ^TInAddr6;
  TInAddr6 = record
    case LongInt of
      0: (S6_addr: packed array [0..15] of byte);
      1: (u6_addr8: packed array [0..15] of byte);
      2: (u6_addr16: packed array [0..7] of word);
      3: (u6_addr32: packed array [0..3] of LongInt);
  end;

  PSockAddrIn6 = ^TSockAddrIn6;
  TSockAddrIn6 = record
		sin6_family:   u_short;     // AF_INET6
		sin6_port:     u_short;     // Transport level port number
		sin6_flowinfo: u_long;	    // IPv6 flow information
		sin6_addr:     TInAddr6;    // IPv6 address
		sin6_scope_id: u_long;      // Scope Id: IF number for link-local
                                    //           SITE id for site-local
  end;

  TIPv6_mreq = record
    ipv6mr_multiaddr: TInAddr6; // IPv6 multicast address.
    ipv6mr_interface: LongInt;   // Interface index.
    padding: LongInt;
  end;


const
  {$EXTERNALSYM INADDR_ANY}
  INADDR_ANY       = $00000000;
  {$EXTERNALSYM INADDR_LOOPBACK}
  INADDR_LOOPBACK  = $7F000001;
  {$EXTERNALSYM INADDR_BROADCAST}
  INADDR_BROADCAST = $FFFFFFFF; // -1;
  {$EXTERNALSYM INADDR_NONE}
  INADDR_NONE      = $FFFFFFFF; // -1;

  {$EXTERNALSYM WSADESCRIPTION_LEN}
  WSADESCRIPTION_LEN     =   256;
  {$EXTERNALSYM WSASYS_STATUS_LEN}
  WSASYS_STATUS_LEN      =   128;

type
  PWSAData = ^TWSAData;
  {$EXTERNALSYM WSAData}
  WSAData = record // !!! also WSDATA
    wVersion: Word;
    wHighVersion: Word;
    szDescription: array[0..WSADESCRIPTION_LEN] of AnsiChar;
    szSystemStatus: array[0..WSASYS_STATUS_LEN] of AnsiChar;
    iMaxSockets: Word;
    iMaxUdpDg: Word;
    lpVendorInfo: PAnsiChar;
  end;
  TWSAData = WSAData;

  {$EXTERNALSYM PTransmitFileBuffers}
  PTransmitFileBuffers = ^TTransmitFileBuffers;
  {$EXTERNALSYM _TRANSMIT_FILE_BUFFERS}
  _TRANSMIT_FILE_BUFFERS = record
      Head: Pointer;
      HeadLength: DWORD;
      Tail: Pointer;
      TailLength: DWORD;
  end;
  {$EXTERNALSYM TTransmitFileBuffers}
  TTransmitFileBuffers = _TRANSMIT_FILE_BUFFERS;
  {$EXTERNALSYM TRANSMIT_FILE_BUFFERS}
  TRANSMIT_FILE_BUFFERS = _TRANSMIT_FILE_BUFFERS;


const
  {$EXTERNALSYM TF_DISCONNECT}
  TF_DISCONNECT           = $01;
  {$EXTERNALSYM TF_REUSE_SOCKET}
  TF_REUSE_SOCKET         = $02;
  {$EXTERNALSYM TF_WRITE_BEHIND}
  TF_WRITE_BEHIND         = $04;

{ Options for use with [gs]etsockopt at the IP level. }

  {$EXTERNALSYM IP_OPTIONS}
  IP_OPTIONS          = 1;
  {$EXTERNALSYM IP_MULTICAST_IF}
  IP_MULTICAST_IF     = 2;           { set/get IP multicast interface   }
  {$EXTERNALSYM IP_MULTICAST_TTL}
  IP_MULTICAST_TTL    = 3;           { set/get IP multicast timetolive  }
  {$EXTERNALSYM IP_MULTICAST_LOOP}
  IP_MULTICAST_LOOP   = 4;           { set/get IP multicast loopback    }
  {$EXTERNALSYM IP_ADD_MEMBERSHIP}
  IP_ADD_MEMBERSHIP   = 5;           { add  an IP group membership      }
  {$EXTERNALSYM IP_DROP_MEMBERSHIP}
  IP_DROP_MEMBERSHIP  = 6;           { drop an IP group membership      }
  {$EXTERNALSYM IP_TTL}
  IP_TTL              = 7;           { set/get IP Time To Live          }
  {$EXTERNALSYM IP_TOS}
  IP_TOS              = 8;           { set/get IP Type Of Service       }
  {$EXTERNALSYM IP_DONTFRAGMENT}
  IP_DONTFRAGMENT     = 9;           { set/get IP Don't Fragment flag   }


  {$EXTERNALSYM IP_DEFAULT_MULTICAST_TTL}
  IP_DEFAULT_MULTICAST_TTL   = 1;    { normally limit m'casts to 1 hop  }
  {$EXTERNALSYM IP_DEFAULT_MULTICAST_LOOP}
  IP_DEFAULT_MULTICAST_LOOP  = 1;    { normally hear sends if a member  }
  {$EXTERNALSYM IP_MAX_MEMBERSHIPS}
  IP_MAX_MEMBERSHIPS         = 20;   { per socket; must fit in one mbuf }

{ This is used instead of -1, since the
  TSocket type is unsigned.}

  {$EXTERNALSYM INVALID_SOCKET    =}
  INVALID_SOCKET    = TSocket(not(0));
  {$EXTERNALSYM SOCKET_ERROR      =}
  SOCKET_ERROR      = -1;

{ Types }

  {$EXTERNALSYM SOCK_STREAM}
  SOCK_STREAM     = 1;               { stream socket }
  {$EXTERNALSYM SOCK_DGRAM}
  SOCK_DGRAM      = 2;               { datagram socket }
  {$EXTERNALSYM SOCK_RAW}
  SOCK_RAW        = 3;               { raw-protocol interface }
  {$EXTERNALSYM SOCK_RDM}
  SOCK_RDM        = 4;               { reliably-delivered message }
  {$EXTERNALSYM SOCK_SEQPACKET}
  SOCK_SEQPACKET  = 5;               { sequenced packet stream }

{ Option flags per-socket. }

  {$EXTERNALSYM SO_DEBUG}
  SO_DEBUG        = $0001;          { turn on debugging info recording }
  {$EXTERNALSYM SO_ACCEPTCONN}
  SO_ACCEPTCONN   = $0002;          { socket has had listen() }
  {$EXTERNALSYM SO_REUSEADDR}
  SO_REUSEADDR    = $0004;          { allow local address reuse }
  {$EXTERNALSYM SO_KEEPALIVE}
  SO_KEEPALIVE    = $0008;          { keep connections alive }
  {$EXTERNALSYM SO_DONTROUTE}
  SO_DONTROUTE    = $0010;          { just use interface addresses }
  {$EXTERNALSYM SO_BROADCAST}
  SO_BROADCAST    = $0020;          { permit sending of broadcast msgs }
  {$EXTERNALSYM SO_USELOOPBACK}
  SO_USELOOPBACK  = $0040;          { bypass hardware when possible }
  {$EXTERNALSYM SO_LINGER}
  SO_LINGER       = $0080;          { linger on close if data present }
  {$EXTERNALSYM SO_OOBINLINE}
  SO_OOBINLINE    = $0100;          { leave received OOB data in line }

  {$EXTERNALSYM SO_DONTLINGER}
  SO_DONTLINGER  =   $ff7f;

{ Additional options. }

  {$EXTERNALSYM SO_SNDBUF}
  SO_SNDBUF       = $1001;          { send buffer size }
  {$EXTERNALSYM SO_RCVBUF}
  SO_RCVBUF       = $1002;          { receive buffer size }
  {$EXTERNALSYM SO_SNDLOWAT}
  SO_SNDLOWAT     = $1003;          { send low-water mark }
  {$EXTERNALSYM SO_RCVLOWAT}
  SO_RCVLOWAT     = $1004;          { receive low-water mark }
  {$EXTERNALSYM SO_SNDTIMEO}
  SO_SNDTIMEO     = $1005;          { send timeout }
  {$EXTERNALSYM SO_RCVTIMEO}
  SO_RCVTIMEO     = $1006;          { receive timeout }
  {$EXTERNALSYM SO_ERROR}
  SO_ERROR        = $1007;          { get error status and clear }
  {$EXTERNALSYM SO_TYPE}
  SO_TYPE         = $1008;          { get socket type }

{ Options for connect and disconnect data and options.  Used only by
  non-TCP/IP transports such as DECNet, OSI TP4, etc. }

  {$EXTERNALSYM SO_CONNDATA}
  SO_CONNDATA     = $7000;
  {$EXTERNALSYM SO_CONNOPT}
  SO_CONNOPT      = $7001;
  {$EXTERNALSYM SO_DISCDATA}
  SO_DISCDATA     = $7002;
  {$EXTERNALSYM SO_DISCOPT}
  SO_DISCOPT      = $7003;
  {$EXTERNALSYM SO_CONNDATALEN}
  SO_CONNDATALEN  = $7004;
  {$EXTERNALSYM SO_CONNOPTLEN}
  SO_CONNOPTLEN   = $7005;
  {$EXTERNALSYM SO_DISCDATALEN}
  SO_DISCDATALEN  = $7006;
  {$EXTERNALSYM SO_DISCOPTLEN}
  SO_DISCOPTLEN   = $7007;

{ Option for opening sockets for synchronous access. }

  {$EXTERNALSYM SO_OPENTYPE}
  SO_OPENTYPE     = $7008;

  {$EXTERNALSYM SO_SYNCHRONOUS_ALERT}
  SO_SYNCHRONOUS_ALERT    = $10;
  {$EXTERNALSYM SO_SYNCHRONOUS_NONALERT}
  SO_SYNCHRONOUS_NONALERT = $20;

{ Other NT-specific options. }

  {$EXTERNALSYM SO_MAXDG}
  SO_MAXDG        = $7009;
  {$EXTERNALSYM SO_MAXPATHDG}
  SO_MAXPATHDG    = $700A;
  {$EXTERNALSYM SO_UPDATE_ACCEPT_CONTEXT}
  SO_UPDATE_ACCEPT_CONTEXT     = $700B;
  {$EXTERNALSYM SO_CONNECT_TIME}
  SO_CONNECT_TIME = $700C;

{ TCP options. }

  {$EXTERNALSYM TCP_NODELAY}
  TCP_NODELAY     = $0001;
  {$EXTERNALSYM TCP_BSDURGENT}
  TCP_BSDURGENT   = $7000;

{ Address families. }

  {$EXTERNALSYM AF_UNSPEC}
  AF_UNSPEC       = 0;               { unspecified }
  {$EXTERNALSYM AF_UNIX}
  AF_UNIX         = 1;               { local to host (pipes, portals) }
  {$EXTERNALSYM AF_INET}
  AF_INET         = 2;               { internetwork: UDP, TCP, etc. }
  {$EXTERNALSYM AF_IMPLINK}
  AF_IMPLINK      = 3;               { arpanet imp addresses }
  {$EXTERNALSYM AF_PUP}
  AF_PUP          = 4;               { pup protocols: e.g. BSP }
  {$EXTERNALSYM AF_CHAOS}
  AF_CHAOS        = 5;               { mit CHAOS protocols }
  {$EXTERNALSYM AF_IPX}
  AF_IPX          = 6;               { IPX and SPX }
  {$EXTERNALSYM AF_NS}
  AF_NS           = 6;               { XEROX NS protocols }
  {$EXTERNALSYM AF_ISO}
  AF_ISO          = 7;               { ISO protocols }
  {$EXTERNALSYM AF_OSI}
  AF_OSI          = AF_ISO;          { OSI is ISO }
  {$EXTERNALSYM AF_ECMA}
  AF_ECMA         = 8;               { european computer manufacturers }
  {$EXTERNALSYM AF_DATAKIT}
  AF_DATAKIT      = 9;               { datakit protocols }
  {$EXTERNALSYM AF_CCITT}
  AF_CCITT        = 10;              { CCITT protocols, X.25 etc }
  {$EXTERNALSYM AF_SNA}
  AF_SNA          = 11;              { IBM SNA }
  {$EXTERNALSYM AF_DECnet}
  AF_DECnet       = 12;              { DECnet }
  {$EXTERNALSYM AF_DLI}
  AF_DLI          = 13;              { Direct data link interface }
  {$EXTERNALSYM AF_LAT}
  AF_LAT          = 14;              { LAT }
  {$EXTERNALSYM AF_HYLINK}
  AF_HYLINK       = 15;              { NSC Hyperchannel }
  {$EXTERNALSYM AF_APPLETALK}
  AF_APPLETALK    = 16;              { AppleTalk }
  {$EXTERNALSYM AF_NETBIOS}
  AF_NETBIOS      = 17;              { NetBios-style addresses }
  {$EXTERNALSYM AF_VOICEVIEW}
  AF_VOICEVIEW    = 18;              { VoiceView }
  {$EXTERNALSYM AF_FIREFOX}
  AF_FIREFOX      = 19;              { FireFox }
  {$EXTERNALSYM AF_UNKNOWN1}
  AF_UNKNOWN1     = 20;              { Somebody is using this! }
  {$EXTERNALSYM AF_BAN}
  AF_BAN          = 21;              { Banyan }
  {$EXTERNALSYM AF_INET6}
  AF_INET6        = 23;
  {$EXTERNALSYM AF_IRDA}
  AF_IRDA         = 26;
  {$EXTERNALSYM AF_BTH}
  AF_BTH          = 32;

  {$EXTERNALSYM AF_MAX}
  AF_MAX          = 32;



type
  { Structure used by kernel to store most addresses. }

  {$EXTERNALSYM PSOCKADDR}
  PSOCKADDR = ^TSockAddr;
  {$EXTERNALSYM TSockAddr}
  TSockAddr = sockaddr_in;


  { Structure used by kernel to pass protocol information in raw sockets. }
  PSockProto = ^TSockProto;
  {$EXTERNALSYM sockproto}
  sockproto = record
    sp_family: u_short;
    sp_protocol: u_short;
  end;
  TSockProto = sockproto;

const
{ Protocol families, same as address families for now. }

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

  {$EXTERNALSYM PF_MAX}
  PF_MAX          = AF_MAX;

type
{ Structure used for manipulating linger option. }
  PLinger = ^TLinger;
  {$EXTERNALSYM linger}
  linger = record
    l_onoff: u_short;
    l_linger: u_short;
  end;
  TLinger = linger;

const
{ Level number for (get/set)sockopt() to apply to socket itself. }

  {$EXTERNALSYM SOL_SOCKET}
  SOL_SOCKET      = $ffff;          {options for socket level }

{ Maximum queue length specifiable by listen. }

  {$EXTERNALSYM SOMAXCONN}
  SOMAXCONN       = 5;

  {$EXTERNALSYM MSG_OOB}
  MSG_OOB         = $1;             {process out-of-band data }
  {$EXTERNALSYM MSG_PEEK}
  MSG_PEEK        = $2;             {peek at incoming message }
  {$EXTERNALSYM MSG_DONTROUTE}
  MSG_DONTROUTE   = $4;             {send without using routing tables }

  {$EXTERNALSYM MSG_MAXIOVLEN}
  MSG_MAXIOVLEN   = 16;

  {$EXTERNALSYM MSG_PARTIAL}
  MSG_PARTIAL     = $8000;          {partial send or recv for message xport }

{ Define constant based on rfc883, used by gethostbyxxxx() calls. }

  {$EXTERNALSYM MAXGETHOSTSTRUCT}
  MAXGETHOSTSTRUCT        = 1024;

{ Define flags to be used with the WSAAsyncSelect() call. }

  {$EXTERNALSYM FD_READ}
  FD_READ         = $01;
  {$EXTERNALSYM FD_WRITE}
  FD_WRITE        = $02;
  {$EXTERNALSYM FD_OOB}
  FD_OOB          = $04;
  {$EXTERNALSYM FD_ACCEPT}
  FD_ACCEPT       = $08;
  {$EXTERNALSYM FD_CONNECT}
  FD_CONNECT      = $10;
  {$EXTERNALSYM FD_CLOSE}
  FD_CLOSE        = $20;

{ All Windows Sockets error constants are biased by WSABASEERR from the "normal" }

  WSANOERROR = 0;

  WSA_INVALID_HANDLE = 6;
  WSA_NOT_ENOUGH_MEMORY = 8;
  WSA_INVALID_PARAMETER = 87;
  WSA_OPERATION_ABORTED = 995;
//WSA_IO_INCOMPLETE = 996;
//WSA_IO_PENDING = 997;

  {$EXTERNALSYM WSABASEERR}
  WSABASEERR              = 10000;

{ Windows Sockets definitions of regular Microsoft C error constants }

  {$EXTERNALSYM WSAEINTR}
  WSAEINTR                = WSABASEERR+4;
  {$EXTERNALSYM WSAEBADF}
  WSAEBADF                = WSABASEERR+9;
  {$EXTERNALSYM WSAEACCES}
  WSAEACCES               = WSABASEERR+13;
  {$EXTERNALSYM WSAEFAULT}
  WSAEFAULT               = WSABASEERR+14;
  {$EXTERNALSYM WSAEINVAL}
  WSAEINVAL               = WSABASEERR+22;
  {$EXTERNALSYM WSAEMFILE}
  WSAEMFILE               = WSABASEERR+24;

{ Windows Sockets definitions of regular Berkeley error constants }

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

  {$EXTERNALSYM WSAEDISCON}
  WSAEDISCON              = WSABASEERR+101;

  WSAENOMORE              = WSABASEERR+102;
  WSAECANCELLED           = WSABASEERR+103;
  WSAEINVALIDPROCTABLE    = WSABASEERR+104;
  WSAEINVALIDPROVIDER     = WSABASEERR+105;
  WSAEPROVIDERFAILEDINIT  = WSABASEERR+106;
  WSASYSCALLFAILURE       = WSABASEERR+107;
  WSASERVICE_NOT_FOUND    = WSABASEERR+108;
  WSATYPE_NOT_FOUND       = WSABASEERR+109;
  WSA_E_NO_MORE           = WSABASEERR+110;
  WSA_E_CANCELLED         = WSABASEERR+111;
  WSAEREFUSED             = WSABASEERR+112;

{ Extended Windows Sockets error constant definitions }

  {$EXTERNALSYM WSASYSNOTREADY}
  WSASYSNOTREADY          = WSABASEERR+91;
  {$EXTERNALSYM WSAVERNOTSUPPORTED}
  WSAVERNOTSUPPORTED      = WSABASEERR+92;
  {$EXTERNALSYM WSANOTINITIALISED}
  WSANOTINITIALISED       = WSABASEERR+93;


{ Error return codes from gethostbyname() and gethostbyaddr()
  (when using the resolver). Note that these errors are
  retrieved via WSAGetLastError() and must therefore follow
  the rules for avoiding clashes with error numbers from
  specific implementations or language run-time systems.
  For this reason the codes are based at WSABASEERR+1001.
  Note also that [WSA]NO_ADDRESS is defined only for
  compatibility purposes. }

{ Authoritative Answer: Host not found }

  {$EXTERNALSYM WSAHOST_NOT_FOUND}
  WSAHOST_NOT_FOUND       = WSABASEERR+1001;
  {$EXTERNALSYM HOST_NOT_FOUND}
  HOST_NOT_FOUND          = WSAHOST_NOT_FOUND;

{ Non-Authoritative: Host not found, or SERVERFAIL }

  {$EXTERNALSYM WSATRY_AGAIN}
  WSATRY_AGAIN            = WSABASEERR+1002;
  {$EXTERNALSYM TRY_AGAIN}
  TRY_AGAIN               = WSATRY_AGAIN;

{ Non recoverable errors, FORMERR, REFUSED, NOTIMP }

  {$EXTERNALSYM WSANO_RECOVERY}
  WSANO_RECOVERY          = WSABASEERR+1003;
  {$EXTERNALSYM NO_RECOVERY}
  NO_RECOVERY             = WSANO_RECOVERY;

{ Valid name, no data record of requested type }

  {$EXTERNALSYM WSANO_DATA}
  WSANO_DATA              = WSABASEERR+1004;
  {$EXTERNALSYM NO_DATA}
  NO_DATA                 = WSANO_DATA;

{ no address, look for MX record }

  {$EXTERNALSYM WSANO_ADDRESS}
  WSANO_ADDRESS           = WSANO_DATA;
  {$EXTERNALSYM NO_ADDRESS}
  NO_ADDRESS              = WSANO_ADDRESS;

{ Windows Sockets errors redefined as regular Berkeley error constants.
  These are commented out in Windows NT to avoid conflicts with errno.h.
  Use the WSA constants instead. }

  {$EXTERNALSYM EWOULDBLOCK}
  EWOULDBLOCK        =  WSAEWOULDBLOCK;
  {$EXTERNALSYM EINPROGRESS}
  EINPROGRESS        =  WSAEINPROGRESS;
  {$EXTERNALSYM EALREADY}
  EALREADY           =  WSAEALREADY;
  {$EXTERNALSYM ENOTSOCK}
  ENOTSOCK           =  WSAENOTSOCK;
  {$EXTERNALSYM EDESTADDRREQ}
  EDESTADDRREQ       =  WSAEDESTADDRREQ;
  {$EXTERNALSYM EMSGSIZE}
  EMSGSIZE           =  WSAEMSGSIZE;
  {$EXTERNALSYM EPROTOTYPE}
  EPROTOTYPE         =  WSAEPROTOTYPE;
  {$EXTERNALSYM ENOPROTOOPT}
  ENOPROTOOPT        =  WSAENOPROTOOPT;
  {$EXTERNALSYM EPROTONOSUPPORT}
  EPROTONOSUPPORT    =  WSAEPROTONOSUPPORT;
  {$EXTERNALSYM ESOCKTNOSUPPORT}
  ESOCKTNOSUPPORT    =  WSAESOCKTNOSUPPORT;
  {$EXTERNALSYM EOPNOTSUPP}
  EOPNOTSUPP         =  WSAEOPNOTSUPP;
  {$EXTERNALSYM EPFNOSUPPORT}
  EPFNOSUPPORT       =  WSAEPFNOSUPPORT;
  {$EXTERNALSYM EAFNOSUPPORT}
  EAFNOSUPPORT       =  WSAEAFNOSUPPORT;
  {$EXTERNALSYM EADDRINUSE}
  EADDRINUSE         =  WSAEADDRINUSE;
  {$EXTERNALSYM EADDRNOTAVAIL}
  EADDRNOTAVAIL      =  WSAEADDRNOTAVAIL;
  {$EXTERNALSYM ENETDOWN}
  ENETDOWN           =  WSAENETDOWN;
  {$EXTERNALSYM ENETUNREACH}
  ENETUNREACH        =  WSAENETUNREACH;
  {$EXTERNALSYM ENETRESET}
  ENETRESET          =  WSAENETRESET;
  {$EXTERNALSYM ECONNABORTED}
  ECONNABORTED       =  WSAECONNABORTED;
  {$EXTERNALSYM ECONNRESET}
  ECONNRESET         =  WSAECONNRESET;
  {$EXTERNALSYM ENOBUFS}
  ENOBUFS            =  WSAENOBUFS;
  {$EXTERNALSYM EISCONN}
  EISCONN            =  WSAEISCONN;
  {$EXTERNALSYM ENOTCONN}
  ENOTCONN           =  WSAENOTCONN;
  {$EXTERNALSYM ESHUTDOWN}
  ESHUTDOWN          =  WSAESHUTDOWN;
  {$EXTERNALSYM ETOOMANYREFS}
  ETOOMANYREFS       =  WSAETOOMANYREFS;
  {$EXTERNALSYM ETIMEDOUT}
  ETIMEDOUT          =  WSAETIMEDOUT;
  {$EXTERNALSYM ECONNREFUSED}
  ECONNREFUSED       =  WSAECONNREFUSED;
  {$EXTERNALSYM ELOOP}
  ELOOP              =  WSAELOOP;
  {$EXTERNALSYM ENAMETOOLONG}
  ENAMETOOLONG       =  WSAENAMETOOLONG;
  {$EXTERNALSYM EHOSTDOWN}
  EHOSTDOWN          =  WSAEHOSTDOWN;
  {$EXTERNALSYM EHOSTUNREACH}
  EHOSTUNREACH       =  WSAEHOSTUNREACH;
  {$EXTERNALSYM ENOTEMPTY}
  ENOTEMPTY          =  WSAENOTEMPTY;
  {$EXTERNALSYM EPROCLIM}
  EPROCLIM           =  WSAEPROCLIM;
  {$EXTERNALSYM EUSERS}
  EUSERS             =  WSAEUSERS;
  {$EXTERNALSYM EDQUOT}
  EDQUOT             =  WSAEDQUOT;
  {$EXTERNALSYM ESTALE}
  ESTALE             =  WSAESTALE;
  {$EXTERNALSYM EREMOTE}
  EREMOTE            =  WSAEREMOTE;


//
// Socket API DLL routines
// To keep code portable better only use routines that are part of berkley socket implementation
//

{$EXTERNALSYM accept}
function accept(s: TSocket; addr: PSockAddr; addrlen: PInteger): TSocket; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM bind}
//function bind(s: TSocket; var addr: TSockAddr; namelen: LongInt): LongInt; stdcall;
function bind(s: TSocket; var addr; addrSize: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM closesocket}
function closesocket(s: TSocket): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM connect}
//function connect(s: TSocket; var name: TSockAddr; namelen: LongInt): LongInt; stdcall;
function connect(s: TSocket; var addr; addrSize: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM ioctlsocket}
function ioctlsocket(s: TSocket; cmd: DWORD; var arg: u_long): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM getpeername}
function getpeername(s: TSocket; var name; var namelen: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM getsockname}
function getsockname(s: TSocket; var name; var namelen: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM getsockopt}
function getsockopt(s: TSocket; level, optname: LongInt; optval: PAnsiChar; var optlen: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM htonl}
function htonl(hostlong: u_long): u_long; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM htons}
function htons(hostshort: u_short): u_short; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM inet_addr}
function inet_addr(cp: PAnsiChar): u_long; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM inet_ntoa}
function inet_ntoa(inaddr: TInAddr): PAnsiChar; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM listen}
function listen(s: TSocket; backlog: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM ntohl}
function ntohl(netlong: u_long): u_long; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM ntohs}
function ntohs(netshort: u_short): u_short; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM recv}
function recv(s: TSocket; var Buf; len, flags: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM recvfrom}
function recvfrom(s: TSocket; var Buf; len, flags: LongInt; var from: TSockAddr; var fromlen: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM select}
function select(nfds: LongInt; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM send}
function send(s: TSocket; var Buf; len, flags: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM sendto}
function sendto(s: TSocket; var Buf; len, flags: LongInt; var addrto: TSockAddr; tolen: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM setsockopt}
function setsockopt(s: TSocket; level, optname: LongInt; optval: PAnsiChar; optlen: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM shutdown}
function shutdown(s: TSocket; how: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM socket}
function socket(af, Struct, protocol: LongInt): TSocket; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM gethostbyaddr}
function gethostbyaddr(addr: Pointer; len, Struct: LongInt): PHostEnt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM gethostbyname}
function gethostbyname(name: PAnsiChar): PHostEnt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM gethostname}
function gethostname(name: PAnsiChar; len: LongInt): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM getservbyport}
function getservbyport(port: LongInt; proto: PAnsiChar): PServEnt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM getservbyname}
function getservbyname(name, proto: PAnsiChar): PServEnt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM getprotobynumber}
function getprotobynumber(proto: LongInt): PProtoEnt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM getprotobyname}
function getprotobyname(name: PAnsiChar): PProtoEnt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM WSAStartup}
function WSAStartup(wVersionRequired: word; var WSData: TWSAData): LongInt; stdcall; external cStrWinsockDLLName;
{$EXTERNALSYM WSACleanup}
function WSACleanup: LongInt; stdcall; external cStrWinsockDLLName;
//{$EXTERNALSYM WSASetLastError}
//procedure WSASetLastError(iError: LongInt); stdcall;
{$EXTERNALSYM WSAGetLastError}
function WSAGetLastError: LongInt; stdcall; external cStrWinsockDLLName;
//{$EXTERNALSYM WSAIsBlocking}
//function WSAIsBlocking: BOOL; stdcall;
//{$EXTERNALSYM WSAUnhookBlockingHook}
//function WSAUnhookBlockingHook: LongInt; stdcall;
//{$EXTERNALSYM WSASetBlockingHook}
//function WSASetBlockingHook(lpBlockFunc: TFarProc): TFarProc; stdcall;
//{$EXTERNALSYM WSACancelBlockingCall}
//function WSACancelBlockingCall: LongInt; stdcall;
//{$EXTERNALSYM WSAAsyncGetServByName}
//function WSAAsyncGetServByName(HWindow: HWND; wMsg: u_int;
//name, proto, buf: PAnsiChar; buflen: LongInt): THandle; stdcall;
//{$EXTERNALSYM WSAAsyncGetServByPort}
//function WSAAsyncGetServByPort( HWindow: HWND; wMsg, port: u_int;
//proto, buf: PAnsiChar; buflen: LongInt): THandle; stdcall;
//{$EXTERNALSYM WSAAsyncGetProtoByName}
//function WSAAsyncGetProtoByName(HWindow: HWND; wMsg: u_int;
//name, buf: PAnsiChar; buflen: LongInt): THandle; stdcall;
//{$EXTERNALSYM WSAAsyncGetProtoByNumber}
//function WSAAsyncGetProtoByNumber(HWindow: HWND; wMsg: u_int; number: LongInt;
//buf: PAnsiChar; buflen: LongInt): THandle; stdcall;
//{$EXTERNALSYM WSAAsyncGetHostByName}
//function WSAAsyncGetHostByName(HWindow: HWND; wMsg: u_int;
//name, buf: PAnsiChar; buflen: LongInt): THandle; stdcall;
//{$EXTERNALSYM WSAAsyncGetHostByAddr}
//function WSAAsyncGetHostByAddr(HWindow: HWND; wMsg: u_int; addr: PAnsiChar;
//len, Struct: LongInt; buf: PAnsiChar; buflen: LongInt): THandle; stdcall;
//{$EXTERNALSYM WSACancelAsyncRequest}
//function WSACancelAsyncRequest(hAsyncTaskHandle: THandle): LongInt; stdcall;
//{$EXTERNALSYM WSAAsyncSelect}
//function WSAAsyncSelect(s: TSocket; HWindow: HWND; wMsg: u_int; lEvent: LongInt): LongInt; stdcall;
//{$EXTERNALSYM WSARecvEx}
//function WSARecvEx(s: TSocket; var buf; len: LongInt; var flags: LongInt): LongInt; stdcall;
{$EXTERNALSYM __WSAFDIsSet}
function __WSAFDIsSet(s: TSocket; var FDSet: TFDSet): Bool; stdcall; external cStrWinsockDLLName;

//{$EXTERNALSYM TransmitFile}
//function TransmitFile(hSocket: TSocket; hFile: THandle; nNumberOfBytesToWrite: DWORD;
//nNumberOfBytesPerSend: DWORD; lpOverlapped: POverlapped;
//lpTransmitBuffers: PTransmitFileBuffers; dwReserved: DWORD): BOOL; stdcall;

//{$EXTERNALSYM AcceptEx}
//function AcceptEx(sListenSocket, sAcceptSocket: TSocket;
//lpOutputBuffer: Pointer; dwReceiveDataLength, dwLocalAddressLength,
//dwRemoteAddressLength: DWORD; var lpdwBytesReceived: DWORD;
//lpOverlapped: POverlapped): BOOL; stdcall;

//{$EXTERNALSYM GetAcceptExSockaddrs}
//procedure GetAcceptExSockaddrs(lpOutputBuffer: Pointer;
//dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: DWORD;
//var LocalSockaddr: TSockAddr; var LocalSockaddrLength: LongInt;
//var RemoteSockaddr: TSockAddr; var RemoteSockaddrLength: LongInt); stdcall;

{$EXTERNALSYM WSAMakeSyncReply}
function WSAMakeSyncReply(Buflen, Error: Word): LongInt;
{$EXTERNALSYM WSAMakeSelectReply}
function WSAMakeSelectReply(Event, Error: Word): LongInt;
{$EXTERNALSYM WSAGetAsyncBuflen}
function WSAGetAsyncBuflen(Param: LongInt): Word;
{$EXTERNALSYM WSAGetAsyncError}
function WSAGetAsyncError(Param: LongInt): Word;
{$EXTERNALSYM WSAGetSelectEvent}
function WSAGetSelectEvent(Param: LongInt): Word;
{$EXTERNALSYM WSAGetSelectError}
function WSAGetSelectError(Param: LongInt): Word;

{$EXTERNALSYM FD_CLR}
procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);
{$EXTERNALSYM FD_ISSET}
function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;
{$EXTERNALSYM FD_SET}
procedure FD_SET(Socket: TSocket; var FDSet: TFDSet); // renamed due to conflict with fd_set (above)
{$EXTERNALSYM FD_ZERO}
procedure FD_ZERO(var FDSet: TFDSet);


function SocketErrorMsgFromCode(const ASocketErrorCode: LongInt): TGMString;


implementation


resourcestring

  RStrWSANOERR = 'Socket function secceeded';
  RStrUnknownSocketErr = 'Unknown socket error';

  RStrWSA_INVALID_HANDLE = 'Specified event object handle is invalid';
  RStrWSA_NOT_ENOUGH_MEMORY = 'Insufficient memory available';
  RStrWSA_INVALID_PARAMETER = 'One or more parameters are invalid';
  RStrWSA_OPERATION_ABORTED = 'Overlapped operation aborted';
//RStrWSA_IO_INCOMPLETE = 'Overlapped I/O event object not in signaled state';
//RStrWSA_IO_PENDING = 'Overlapped operations will complete later';

  RStrWSAEINTR = 'Interrupted function call';
  RStrWSAEBADF = 'File handle is not valid';
  RStrWSAEACCES = 'Permission denied';
  RStrWSAEFAULT = 'Bad address';
  RStrWSAEINVAL = 'Invalid argument(s)';
  RStrWSAEMFILE = 'Too many open files';
  RStrWSAEWOULDBLOCK = 'Resource temporarily unavailable';
  RStrWSAEINPROGRESS = 'Operation now in progress';
  RStrWSAEALREADY = 'Operation already in progress';
  RStrWSAENOTSOCK = 'Socket operation on nonsocket';
  RStrWSAEDESTADDRREQ = 'Destination address required';
  RStrWSAEMSGSIZE = 'Message too long';
  RStrWSAEPROTOTYPE = 'Protocol wrong type for socket';
  RStrWSAENOPROTOOPT = 'Bad protocol option';
  RStrWSAEPROTONOSUPPORT = 'Protocol not supported';
  RStrWSAESOCKTNOSUPPORT = 'Socket type not supported';
  RStrWSAEOPNOTSUPP = 'Operation not supported';
  RStrWSAEPFNOSUPPORT = 'Protocol family not supported';
  RStrWSAEAFNOSUPPORT = 'Address family not supported by protocol family';
  RStrWSAEADDRINUSE = 'Address already in use';
  RStrWSAEADDRNOTAVAIL = 'Cannot assign requested address';
  RStrWSAENETDOWN = 'Network is down';
  RStrWSAENETUNREACH = 'Network is unreachable';
  RStrWSAENETRESET = 'Network dropped connection on reset';
  RStrWSAECONNABORTED = 'Software caused connection abort';
  RStrWSAECONNRESET = 'Connection reset by peer';
  RStrWSAENOBUFS = 'No buffer space available';
  RStrWSAEISCONN = 'Socket is already connected';
  RStrWSAENOTCONN = 'Socket is not connected';
  RStrWSAESHUTDOWN = 'Cannot send after socket shutdown';
  RStrWSAETOOMANYREFS = 'Too many references';
  RStrWSAETIMEDOUT = 'Connection timed out';
  RStrWSAECONNREFUSED = 'Connection refused';
  RStrWSAELOOP = 'Cannot translate name';
  RStrWSAENAMETOOLONG = 'Name too long';
  RStrWSAEHOSTDOWN = 'Host is down';
  RStrWSAEHOSTUNREACH = 'No route to host';
  RStrWSAENOTEMPTY = 'Directory not empty';
  RStrWSAEPROCLIM = 'Too many processes';
  RStrWSAEUSERS = 'User quota exceeded';
  RStrWSAEDQUOT = 'Disk quota exceeded';
  RStrWSAESTALE = 'Stale file handle reference';
  RStrWSAEREMOTE = 'Item is remote';
  RStrWSASYSNOTREADY = 'Network subsystem is unavailable';
  RStrWSAVERNOTSUPPORTED = 'Winsock.dll version out of range';
  RStrWSANOTINITIALISED = 'Successful WSAStartup not yet performed';
  RStrWSAEDISCON = 'Graceful shutdown in progress';
  RStrWSAENOMORE = 'No more results';
  RStrWSAECANCELLED = 'Call has been canceled';
  RStrWSAEINVALIDPROCTABLE = 'Procedure call table is invalid';
  RStrWSAEINVALIDPROVIDER = 'Service provider is invalid';
  RStrWSAEPROVIDERFAILEDINIT = 'Service provider failed to initialize';
  RStrWSASYSCALLFAILURE = 'System call failure';
  RStrWSASERVICE_NOT_FOUND = 'Service not found';
  RStrWSATYPE_NOT_FOUND = 'Class type not found';
  RStrWSA_E_NO_MORE = 'No more results';
  RStrWSAEREFUSED = 'Database query was refused';

  RStrWSAHOST_NOT_FOUND = 'Host not found';
  RStrWSATRY_AGAIN = 'Nonauthoritative host not found';
  RStrWSANO_RECOVERY = 'This is a nonrecoverable error';
//RStrWSANO_DATA = 'Valid name, no data record of requested type';
  RStrWSANO_DATA = 'Cannot resolve host name';


  
function WSAMakeSyncReply;
begin
  WSAMakeSyncReply:= MakeLong(Buflen, Error);
end;

function WSAMakeSelectReply;
begin
  WSAMakeSelectReply:= MakeLong(Event, Error);
end;

function WSAGetAsyncBuflen;
begin
  WSAGetAsyncBuflen:= LOWORD(Param);
end;

function WSAGetAsyncError;
begin
  WSAGetAsyncError:= HIWORD(Param);
end;

function WSAGetSelectEvent;
begin
  WSAGetSelectEvent:= LOWORD(Param);
end;

function WSAGetSelectError;
begin
  WSAGetSelectError:= HIWORD(Param);
end;

procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);
var
  I: u_int;
begin
  I := 0;
  while I < FDSet.fd_count do
  begin
    if FDSet.fd_array[I] = Socket then
    begin
      while I < FDSet.fd_count - 1 do
      begin
        FDSet.fd_array[I] := FDSet.fd_array[I + 1];
        Inc(I);
      end;
      Dec(FDSet.fd_count);
      Break;
    end;
    Inc(I);
  end;
end;

function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;
begin
  Result := __WSAFDIsSet(Socket, FDSet);
end;

procedure FD_SET(Socket: TSocket; var FDSet: TFDSet);
begin
  if FDSet.fd_count < FD_SETSIZE then
  begin
    FDSet.fd_array[FDSet.fd_count] := Socket;
    Inc(FDSet.fd_count);
  end;
end;

procedure FD_ZERO(var FDSet: TFDSet);
begin
  FDSet.fd_count := 0;
end;

function SocketErrorMsgFromCode(const ASocketErrorCode: LongInt): TGMString;
begin
  case ASocketErrorCode of
    WSANOERROR: Result := RStrWSANOERR;

    WSA_INVALID_HANDLE: Result := RStrWSA_INVALID_HANDLE;
    WSA_NOT_ENOUGH_MEMORY: Result := RStrWSA_NOT_ENOUGH_MEMORY;
    WSA_INVALID_PARAMETER: Result := RStrWSA_INVALID_PARAMETER;
    WSA_OPERATION_ABORTED: Result := RStrWSA_OPERATION_ABORTED;
//  WSA_IO_INCOMPLETE: Result := RStrWSA_IO_INCOMPLETE;
//  WSA_IO_PENDING: Result := RStrWSA_IO_PENDING;

    WSAEINTR: Result := RStrWSAEINTR;
    WSAEBADF: Result := RStrWSAEBADF;
    WSAEACCES: Result := RStrWSAEACCES;
    WSAEFAULT: Result := RStrWSAEFAULT;
    WSAEINVAL: Result := RStrWSAEINVAL;
    WSAEMFILE: Result := RStrWSAEMFILE;
    WSAEWOULDBLOCK: Result := RStrWSAEWOULDBLOCK;
    WSAEINPROGRESS: Result := RStrWSAEINPROGRESS;
    WSAEALREADY: Result := RStrWSAEALREADY;
    WSAENOTSOCK: Result := RStrWSAENOTSOCK;
    WSAEDESTADDRREQ: Result := RStrWSAEDESTADDRREQ;
    WSAEMSGSIZE: Result := RStrWSAEMSGSIZE;
    WSAEPROTOTYPE: Result := RStrWSAEPROTOTYPE;
    WSAENOPROTOOPT: Result := RStrWSAENOPROTOOPT;
    WSAEPROTONOSUPPORT: Result := RStrWSAEPROTONOSUPPORT;
    WSAESOCKTNOSUPPORT: Result := RStrWSAESOCKTNOSUPPORT;
    WSAEOPNOTSUPP: Result := RStrWSAEOPNOTSUPP;
    WSAEPFNOSUPPORT: Result := RStrWSAEPFNOSUPPORT;
    WSAEAFNOSUPPORT: Result := RStrWSAEAFNOSUPPORT;
    WSAEADDRINUSE: Result := RStrWSAEADDRINUSE;
    WSAEADDRNOTAVAIL: Result := RStrWSAEADDRNOTAVAIL;
    WSAENETDOWN: Result := RStrWSAENETDOWN;
    WSAENETUNREACH: Result := RStrWSAENETUNREACH;
    WSAENETRESET: Result := RStrWSAENETRESET;
    WSAECONNABORTED: Result := RStrWSAECONNABORTED;
    WSAECONNRESET: Result := RStrWSAECONNRESET;
    WSAENOBUFS: Result := RStrWSAENOBUFS;
    WSAEISCONN: Result := RStrWSAEISCONN;
    WSAENOTCONN: Result := RStrWSAENOTCONN;
    WSAESHUTDOWN: Result := RStrWSAESHUTDOWN;
    WSAETOOMANYREFS: Result := RStrWSAETOOMANYREFS;
    WSAETIMEDOUT: Result := RStrWSAETIMEDOUT;
    WSAECONNREFUSED: Result := RStrWSAECONNREFUSED;
    WSAELOOP: Result := RStrWSAELOOP;
    WSAENAMETOOLONG: Result := RStrWSAENAMETOOLONG;
    WSAEHOSTDOWN: Result := RStrWSAEHOSTDOWN;
    WSAEHOSTUNREACH: Result := RStrWSAEHOSTUNREACH;
    WSAENOTEMPTY: Result := RStrWSAENOTEMPTY;
    WSAEPROCLIM: Result := RStrWSAEPROCLIM;
    WSAEUSERS: Result := RStrWSAEUSERS;
    WSAEDQUOT: Result := RStrWSAEDQUOT;
    WSAESTALE: Result := RStrWSAESTALE;
    WSAEREMOTE: Result := RStrWSAEREMOTE;
    WSASYSNOTREADY: Result := RStrWSASYSNOTREADY;
    WSAVERNOTSUPPORTED: Result := RStrWSAVERNOTSUPPORTED;
    WSANOTINITIALISED: Result := RStrWSANOTINITIALISED;
    WSAEDISCON: Result := RStrWSAEDISCON;
    WSAENOMORE: Result := RStrWSAENOMORE;
    WSAECANCELLED: Result := RStrWSAECANCELLED;
    WSAEINVALIDPROCTABLE: Result := RStrWSAEINVALIDPROCTABLE;
    WSAEINVALIDPROVIDER: Result := RStrWSAEINVALIDPROVIDER;
    WSAEPROVIDERFAILEDINIT: Result := RStrWSAEPROVIDERFAILEDINIT;
    WSASYSCALLFAILURE: Result := RStrWSASYSCALLFAILURE;

    WSASERVICE_NOT_FOUND: Result := RStrWSASERVICE_NOT_FOUND;
    WSATYPE_NOT_FOUND: Result := RStrWSATYPE_NOT_FOUND;
    WSA_E_NO_MORE: Result := RStrWSA_E_NO_MORE;
    WSA_E_CANCELLED: Result := RStrWSAECANCELLED;
    WSAEREFUSED: Result := RStrWSAEREFUSED;

    WSAHOST_NOT_FOUND: Result := RStrWSAHOST_NOT_FOUND;
    WSATRY_AGAIN: Result := RStrWSATRY_AGAIN;
    WSANO_RECOVERY: Result := RStrWSANO_RECOVERY;
    WSANO_DATA: Result := RStrWSANO_DATA;

    else Result := RStrUnknownSocketErr;
  end;
end;


end.