#ifndef _SOCKET_H_
#define _SOCKET_H_

#define WSABASEERR              10000
#define WSAEINTR                (WSABASEERR+4)
#define WSAEBADF                (WSABASEERR+9)
#define WSAEACCES               (WSABASEERR+13)
#define WSAEFAULT               (WSABASEERR+14)
#define WSAEINVAL               (WSABASEERR+22)
#define WSAEMFILE               (WSABASEERR+24)
#define WSAEWOULDBLOCK          (WSABASEERR+35)
#define WSAEINPROGRESS          (WSABASEERR+36)
#define WSAEALREADY             (WSABASEERR+37)
#define WSAENOTSOCK             (WSABASEERR+38)
#define WSAEDESTADDRREQ         (WSABASEERR+39)
#define WSAEMSGSIZE             (WSABASEERR+40)
#define WSAEPROTOTYPE           (WSABASEERR+41)
#define WSAENOPROTOOPT          (WSABASEERR+42)
#define WSAEPROTONOSUPPORT      (WSABASEERR+43)
#define WSAESOCKTNOSUPPORT      (WSABASEERR+44)
#define WSAEOPNOTSUPP           (WSABASEERR+45)
#define WSAEPFNOSUPPORT         (WSABASEERR+46)
#define WSAEAFNOSUPPORT         (WSABASEERR+47)
#define WSAEADDRINUSE           (WSABASEERR+48)
#define WSAEADDRNOTAVAIL        (WSABASEERR+49)
#define WSAENETDOWN             (WSABASEERR+50)
#define WSAENETUNREACH          (WSABASEERR+51)
#define WSAENETRESET            (WSABASEERR+52)
#define WSAECONNABORTED         (WSABASEERR+53)
#define WSAECONNRESET           (WSABASEERR+54)
#define WSAENOBUFS              (WSABASEERR+55)
#define WSAEISCONN              (WSABASEERR+56)
#define WSAENOTCONN             (WSABASEERR+57)
#define WSAESHUTDOWN            (WSABASEERR+58)
#define WSAETOOMANYREFS         (WSABASEERR+59)
#define WSAETIMEDOUT            (WSABASEERR+60)
#define WSAECONNREFUSED         (WSABASEERR+61)
#define WSAELOOP                (WSABASEERR+62)
#define WSAENAMETOOLONG         (WSABASEERR+63)
#define WSAEHOSTDOWN            (WSABASEERR+64)
#define WSAEHOSTUNREACH         (WSABASEERR+65)
#define WSAENOTEMPTY            (WSABASEERR+66)
#define WSAEPROCLIM             (WSABASEERR+67)
#define WSAEUSERS               (WSABASEERR+68)
#define WSAEDQUOT               (WSABASEERR+69)
#define WSAESTALE               (WSABASEERR+70)
#define WSAEREMOTE              (WSABASEERR+71)

#define INVALID_SOCKET  (SOCKET)(~0)
#define SOCKET_ERROR            (-1)

typedef struct
{
    WORD            wVersion;
    WORD            wHighVersion;
    char            szDescription[256+1];
    char            szSystemStatus[128+1];
    unsigned short  iMaxSockets;
    unsigned short  iMaxUdpDg;
    char *          lpVendorInfo;
} WSADATA, * LPWSADATA;

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

typedef struct _PROTOCOL_INFOA {
    DWORD dwServiceFlags ;
    INT iAddressFamily ;
    INT iMaxSockAddr ;
    INT iMinSockAddr ;
    INT iSocketType ;
    INT iProtocol ;
    DWORD dwMessageSize ;
    LPSTR   lpProtocol ;
} PROTOCOL_INFOA, *PPROTOCOL_INFOA, * LPPROTOCOL_INFOA ;
/* use ansi mode */
#define PROTOCOL_INFO PROTOCOL_INFOA

typedef struct _WSAPROTOCOLCHAIN {
    int ChainLen;
    DWORD ChainEntries[7];
} WSAPROTOCOLCHAIN;

#ifndef GUID_DEFINED
#define GUID_DEFINED
typedef struct _GUID
{
    unsigned long  Data1;
    unsigned short Data2;
    unsigned short Data3;
    unsigned char  Data4[8];
} GUID;
#endif /* GUID_DEFINED */

typedef struct _WSAPROTOCOL_INFOA {
    DWORD   dwServiceFlags1;
    DWORD   dwServiceFlags2;
    DWORD   dwServiceFlags3;
    DWORD   dwServiceFlags4;
    DWORD   dwProviderFlags;
    GUID    ProviderId;
    DWORD   dwCatalogEntryId;
    WSAPROTOCOLCHAIN ProtocolChain;
    int     iVersion;
    int     iAddressFamily;
    int     iMaxSockAddr;
    int     iMinSockAddr;
    int     iSocketType;
    int     iProtocol;
    int     iProtocolMaxOffset;
    int     iNetworkByteOrder;
    int     iSecurityScheme;
    DWORD   dwMessageSize;
    DWORD   dwProviderReserved;
    CHAR    szProtocol[255+1];
} WSAPROTOCOL_INFOA, * LPWSAPROTOCOL_INFOA;

/* use ansi mode */
#define WSAPROTOCOL_INFO WSAPROTOCOL_INFOA

typedef int SOCKET;

typedef struct _win_fd_set {
        u_int   fd_count;
        SOCKET  fd_array[64];
} win_fd_set;

typedef int    WINAPI (*LPFN_WSASTARTUP) (WORD, LPWSADATA);
typedef int    WINAPI (*LPFN_WSACLEANUP) (void);
typedef int    WINAPI (*LPFN_WSAGETLASTERROR) (void);
typedef int    WINAPI (*LPFN_CLOSESOCKET) (SOCKET);
typedef int    WINAPI (*LPFN_RECV) (SOCKET, char *, int, int);
typedef int    WINAPI (*LPFN_SEND) (SOCKET, const char  * buf, int len, int flags);
typedef int    WINAPI (*LPFN_IOCTLSOCKET) (SOCKET, long, u_long *);
typedef int    WINAPI (*LPFN_BIND)  (SOCKET, const struct sockaddr *, int);
typedef int    WINAPI (*LPFN_LISTEN) (SOCKET, int);
typedef int    WINAPI (*LPFN_CONNECT) (SOCKET, const struct sockaddr *, int);
typedef int    WINAPI (*LPFN_SETSOCKOPT) (SOCKET, int, int, const char *, int);
typedef int    WINAPI (*LPFN_GETSOCKOPT) (SOCKET, int, int,  char *, int *);
typedef int    WINAPI (*LPFN_GETPEERNAME) (SOCKET, struct sockaddr *, int *);
typedef int    WINAPI (*LPFN_GETHOSTNAME) (char *, int);
typedef int    WINAPI (*LPFN_SHUTDOWN)   (SOCKET, int);
typedef int    WINAPI (*LPFN_GETSOCKNAME) (SOCKET, struct sockaddr *, int *);
typedef INT    WINAPI (*LPFN_WSAENUMPROTOCOLS) (LPDWORD, LPVOID, LPDWORD);
typedef SOCKET WINAPI (*LPFN_SOCKET) (int, int, int);
typedef SOCKET WINAPI (*LPFN_ACCEPT) (SOCKET, struct sockaddr *, int *);
typedef int    WINAPI (*LPFN_SELECT) (int, win_fd_set *, win_fd_set *, win_fd_set *, const struct timeval *);
typedef struct hostent *  WINAPI (*LPFN_GETHOSTBYADDR) (const char *, int, int);
typedef struct hostent *  WINAPI (*LPFN_GETHOSTBYNAME) (const char *);
typedef struct servent *  WINAPI (*LPFN_GETSERVBYPORT) (int port, const char *);
typedef struct servent *  WINAPI (*LPFN_GETSERVBYNAME) (const char *, const char *);
typedef struct protoent * WINAPI (*LPFN_GETPROTOBYNUMBER) (int);
typedef struct protoent * WINAPI (*LPFN_GETPROTOBYNAME) (const char *);

int _rsxnt_socket_errno();

extern LPFN_WSASTARTUP          wsa_WSAStartup       ;
extern LPFN_WSACLEANUP          wsa_WSACleanup       ;
extern LPFN_WSAGETLASTERROR     wsa_WSAGetLastError  ;
extern LPFN_GETSOCKOPT          wsa_getsockopt       ;
extern LPFN_CLOSESOCKET         wsa_closesocket      ;
extern LPFN_RECV                wsa_recv             ;
extern LPFN_SEND                wsa_send             ;
extern LPFN_IOCTLSOCKET         wsa_ioctlsocket      ;
extern LPFN_SOCKET              wsa_socket           ;
extern LPFN_BIND                wsa_bind             ;
extern LPFN_LISTEN              wsa_listen           ;
extern LPFN_ACCEPT              wsa_accept           ;
extern LPFN_CONNECT             wsa_connect          ;
extern LPFN_SETSOCKOPT          wsa_setsockopt       ;
extern LPFN_GETSOCKNAME         wsa_getsockname      ;
extern LPFN_GETPEERNAME         wsa_getpeername      ;
extern LPFN_GETHOSTBYNAME       wsa_gethostbyname    ;
extern LPFN_GETHOSTBYADDR       wsa_gethostbyaddr    ;
extern LPFN_GETSERVBYNAME       wsa_getservbyname    ;
extern LPFN_GETSERVBYPORT       wsa_getservbyport    ;
extern LPFN_GETPROTOBYNAME      wsa_getprotobyname   ;
extern LPFN_GETPROTOBYNUMBER    wsa_getprotobynumber ;
extern LPFN_GETHOSTNAME         wsa_gethostname      ;
extern LPFN_SHUTDOWN            wsa_shutdown         ;
extern LPFN_WSAENUMPROTOCOLS    wsa_WSAEnumProtocols ;

extern int _rsxnt_socket_inited;
// #define USE_WINSOCK2

#endif /* _SOCKET_H_ */
