MODULE WSock32;
IMPORT SYSTEM, Kernel32, Modules, User32,KernelLog;
CONST
WSADescriptionLen* = 256; WSASysStatusLen* = 128;
AFINet* = 2; PFINet* = AFINet;
SockStream* = 1;
IPProtoTCP* = 6;
InvalidSocket* = -1;
SOMaxConn* = 07FFFFFFFH;
WSABaseErr = 10000;
WSAEInProgress* = WSABaseErr+36; WSAEConnAborted* = WSABaseErr+53;
WSAEConnReset* = WSABaseErr+54; WSAEShutdown* = WSABaseErr+58;
SocketError*= -1;
SockDGram* = 2; SockRaw* = 3;
IPProtoICMP* = 1; IPProtoUDP* = 17;
MAXGETHOSTSTRUCT* = 1024;
FDRead* = 01H; FDWrite* = 02H; FDAccept *= 08H; FDConnect* = 010H; FDClose* = 020H;
WSAEInval* = WSABaseErr+22; WSAEWouldBlock* = WSABaseErr+35;
WSAENoBufs* = WSABaseErr+55;
WSAEConnRefused*= WSABaseErr+61;
FIONRead* = 4004667FH;
SOLSocket* = 0FFFFH; SOSndTimeo* = 01005H; SORcvTimeo* = 01006H;
MsgPeek* = 2;
SDReceive*=0; SDSend*=1; SDboth* = 2;
TYPE
TimeVal* = POINTER TO TimeValDesc;
TimeValDesc* = RECORD
sec*,musec*: LONGINT;
END;
WSAData* = RECORD
wVersion*, wHighVersion*: INTEGER;
szDescription*: ARRAY WSADescriptionLen+1 OF CHAR;
szSystemStatus*: ARRAY WSASysStatusLen+1 OF CHAR;
iMaxSockets*, iMaxUdpDg*: INTEGER;
lpVendorInfo*: Kernel32.ADDRESS
END;
inAddr* = LONGINT;
PsockaddrIn* = POINTER TO sockaddrIn;
sockaddrIn* = RECORD
sinFamily*, sinPort*: INTEGER;
sinAddr*: inAddr;
inZero: ARRAY 8 OF CHAR
END;
Paddrinfo* = POINTER TO addrinfo;
addrinfo* = RECORD
aiFlags*: SET;
aiFamily*, aiSocktype*, aiProtocol*: LONGINT;
aiAddrlen*: LONGINT;
aiCanonname*: Kernel32.ADDRESS;
aiAddr*{UNTRACED}: PsockaddrIn;
aiNext*{UNTRACED}: Paddrinfo
END;
Socket* = Kernel32.HANDLE;
Group* = LONGINT;
FDSet*=RECORD
fdcount*: LONGINT;
socket*: ARRAY 64 OF LONGINT;
END;
WSAProtocolInfo* = RECORD
data: ARRAY 372 OF SYSTEM.BYTE
END;
LPHostent* = Kernel32.ADDRESS;
PHostent*= POINTER TO Hostent;
Hostent* = RECORD
hName*,
hAliases*:
Kernel32.ADDRESS;
hAddrtype*, hLength*: INTEGER;
hAddrList*:
Kernel32.ADDRESS
END;
Error = OBJECT
VAR
nr: LONGINT;
name: ARRAY 64 OF CHAR;
msg: ARRAY 256 OF CHAR;
left, right: Error;
END Error;
VAR
wsock32: Kernel32.HMODULE;
wship6: Kernel32.HMODULE;
wsaStarted: BOOLEAN;
errors: Error;
WSACleanup-: PROCEDURE {WINAPI} (): LONGINT;
WSAAsyncGetHostByAddr-: PROCEDURE {WINAPI} (hWnd: User32.HWND; wMsg: LONGINT; VAR addr: ARRAY OF SYSTEM.BYTE; len: LONGINT; type: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE; buflen: LONGINT): Kernel32.HANDLE;
WSAAsyncGetHostByName-: PROCEDURE {WINAPI} (hWnd: User32.HWND; wMsg: LONGINT; name: ARRAY OF CHAR; VAR buf: ARRAY OF SYSTEM.BYTE; buflen: LONGINT): Kernel32.HANDLE;
WSAAsyncSelect-: PROCEDURE {WINAPI} (s: Socket; hWnd: User32.HWND; wMsg: LONGINT; lEvent: LONGINT): LONGINT;
WSAGetLastError-: PROCEDURE {WINAPI} (): LONGINT;
WSASocket-: PROCEDURE {WINAPI} (af, type, protocol: LONGINT; VAR lpProtocolInfo: WSAProtocolInfo; g: Group; dwFlags: LONGINT): Socket;
WSAStartup-: PROCEDURE {WINAPI} (wVersionRequested: LONGINT; VAR lpWSAData: WSAData): LONGINT;
accept-: PROCEDURE {WINAPI} (s: Socket; VAR addr: ARRAY OF SYSTEM.BYTE; VAR addrlen: LONGINT): Socket;
bind-: PROCEDURE {WINAPI} (s: Socket; VAR name: ARRAY OF SYSTEM.BYTE; namelen: LONGINT): LONGINT;
closesocket-: PROCEDURE {WINAPI} (s: Socket): LONGINT;
connect-: PROCEDURE {WINAPI} (s: Socket; VAR name: ARRAY OF SYSTEM.BYTE; namelen: LONGINT): LONGINT;
freeaddrinfo-:PROCEDURE {WINAPI}(ai:Paddrinfo);
getaddrinfo-: PROCEDURE {WINAPI}(VAR nodename, servname: ARRAY OF CHAR; VAR hints: ARRAY OF SYSTEM.BYTE; VAR res: Paddrinfo): LONGINT;
gethostbyname-: PROCEDURE {WINAPI} (VAR name: ARRAY OF CHAR): PHostent;
gethostname-: PROCEDURE {WINAPI} (VAR name: ARRAY OF CHAR; namelen: LONGINT): LONGINT;
getpeername-: PROCEDURE {WINAPI} (s: Socket; VAR name: ARRAY OF SYSTEM.BYTE; VAR namelen: LONGINT): LONGINT;
getsockname-:PROCEDURE {WINAPI} (s: Socket; VAR name: ARRAY OF SYSTEM.BYTE; VAR namelen: LONGINT): LONGINT;
htonl-: PROCEDURE {WINAPI} (x: LONGINT): LONGINT;
htons-: PROCEDURE {WINAPI} (x: INTEGER): INTEGER;
ioctlsocket-: PROCEDURE {WINAPI} (s: Socket; cmd: LONGINT; VAR argp: LONGINT): LONGINT;
listen-: PROCEDURE {WINAPI} (s: Socket; backlog: LONGINT): LONGINT;
ntohl-: PROCEDURE {WINAPI} (x: LONGINT): LONGINT;
ntohs-: PROCEDURE {WINAPI} (x: INTEGER): INTEGER;
recv-: PROCEDURE {WINAPI} (s: Socket; VAR buf: ARRAY OF SYSTEM.BYTE; len: LONGINT; flags: SET): LONGINT;
recvfrom-: PROCEDURE {WINAPI} (s: Socket; VAR buf: ARRAY OF SYSTEM.BYTE; len: LONGINT; flags: LONGINT; VAR from: ARRAY OF SYSTEM.BYTE; VAR fromlen: LONGINT): LONGINT;
select-: PROCEDURE {WINAPI} (nfds:INTEGER; VAR readfds,writefds,exceptfds: FDSet; timeout: TimeVal): LONGINT;
send-: PROCEDURE {WINAPI} (s: Socket; CONST buf: ARRAY OF SYSTEM.BYTE; len: LONGINT; flags: SET): LONGINT;
sendto-: PROCEDURE {WINAPI} (s: Socket; VAR buf: ARRAY OF SYSTEM.BYTE; len: LONGINT; flags: LONGINT; VAR to: ARRAY OF SYSTEM.BYTE; tolen: LONGINT): LONGINT;
setsockopt-: PROCEDURE {WINAPI} (s: Socket; level, optname: LONGINT; VAR optval: ARRAY OF SYSTEM.BYTE; optlen: LONGINT): LONGINT;
socket-: PROCEDURE {WINAPI} (af, type, protocol: LONGINT): Socket;
shutdown-:PROCEDURE{WINAPI} (s: Socket; how: LONGINT): LONGINT;
PROCEDURE TermMod;
BEGIN
IF wsock32 # Kernel32.NULL THEN
Kernel32.FreeLibrary(wsock32); wsock32 := Kernel32.NULL
END;
IF wship6 # Kernel32.NULL THEN
Kernel32.FreeLibrary(wship6); wship6 := Kernel32.NULL
END
END TermMod;
PROCEDURE Init;
VAR str: ARRAY 32 OF CHAR;
BEGIN
str := "ws2_32.dll";
wsock32 := Kernel32.LoadLibrary(str);
IF wsock32 = Kernel32.NULL THEN
str := "WSOCK32.DLL";
wsock32 := Kernel32.LoadLibrary(str)
END;
str := "wship6.dll";
wship6 := Kernel32.LoadLibrary(str);
Kernel32.GetProcAddress(wsock32, "WSACleanup", SYSTEM.VAL(LONGINT, WSACleanup));
Kernel32.GetProcAddress(wsock32, "WSAAsyncGetHostByAddr", SYSTEM.VAL(LONGINT, WSAAsyncGetHostByAddr));
Kernel32.GetProcAddress(wsock32, "WSAAsyncGetHostByName", SYSTEM.VAL(LONGINT, WSAAsyncGetHostByName));
Kernel32.GetProcAddress(wsock32, "WSAAsyncSelect", SYSTEM.VAL(LONGINT, WSAAsyncSelect));
Kernel32.GetProcAddress(wsock32, "WSAGetLastError", SYSTEM.VAL(LONGINT, WSAGetLastError));
Kernel32.GetProcAddress(wsock32, "WSASocketA", SYSTEM.VAL(LONGINT, WSASocket));
Kernel32.GetProcAddress(wsock32, "WSAStartup", SYSTEM.VAL(LONGINT, WSAStartup));
Kernel32.GetProcAddress(wsock32, "accept", SYSTEM.VAL(LONGINT, accept));
Kernel32.GetProcAddress(wsock32, "bind", SYSTEM.VAL(LONGINT, bind));
Kernel32.GetProcAddress(wsock32, "closesocket", SYSTEM.VAL(LONGINT, closesocket));
Kernel32.GetProcAddress(wsock32, "connect", SYSTEM.VAL(LONGINT, connect));
Kernel32.GetProcAddress(wsock32, "freeaddrinfo", SYSTEM.VAL(LONGINT, freeaddrinfo));
Kernel32.GetProcAddress(wsock32, "getaddrinfo", SYSTEM.VAL(LONGINT, getaddrinfo));
Kernel32.GetProcAddress(wsock32, "gethostbyname", SYSTEM.VAL(LONGINT, gethostbyname));
Kernel32.GetProcAddress(wsock32, "gethostname", SYSTEM.VAL(LONGINT, gethostname));
Kernel32.GetProcAddress(wsock32, "getpeername", SYSTEM.VAL(LONGINT, getpeername));
Kernel32.GetProcAddress(wsock32, "getsockname", SYSTEM.VAL(LONGINT, getsockname));
Kernel32.GetProcAddress(wsock32, "htonl", SYSTEM.VAL(LONGINT, htonl));
Kernel32.GetProcAddress(wsock32, "htons", SYSTEM.VAL(LONGINT, htons));
Kernel32.GetProcAddress(wsock32, "ioctlsocket", SYSTEM.VAL(LONGINT, ioctlsocket));
Kernel32.GetProcAddress(wsock32, "listen", SYSTEM.VAL(LONGINT, listen));
Kernel32.GetProcAddress(wsock32, "ntohl", SYSTEM.VAL(LONGINT, ntohl));
Kernel32.GetProcAddress(wsock32, "ntohs", SYSTEM.VAL(LONGINT, ntohs));
Kernel32.GetProcAddress(wsock32, "recv", SYSTEM.VAL(LONGINT, recv));
Kernel32.GetProcAddress(wsock32, "recvfrom", SYSTEM.VAL(LONGINT, recvfrom));
Kernel32.GetProcAddress(wsock32, "select", SYSTEM.VAL(LONGINT, select));
Kernel32.GetProcAddress(wsock32, "send", SYSTEM.VAL(LONGINT, send));
Kernel32.GetProcAddress(wsock32, "sendto", SYSTEM.VAL(LONGINT, sendto));
Kernel32.GetProcAddress(wsock32, "setsockopt", SYSTEM.VAL(LONGINT, setsockopt));
Kernel32.GetProcAddress(wsock32, "socket", SYSTEM.VAL(LONGINT, socket));
Kernel32.GetProcAddress(wsock32, "shutdown", SYSTEM.VAL(LONGINT, shutdown));
IF freeaddrinfo = NIL THEN
KernelLog.String("Trying to locate getaddrinfo, freeaddrinfo"); KernelLog.Ln;
str := "wship6.dll";
wship6 := Kernel32.LoadLibrary(str);
IF wship6 # Kernel32.NULL THEN
Kernel32.GetProcAddress(wship6, "freeaddrinfo", SYSTEM.VAL(LONGINT, freeaddrinfo));
Kernel32.GetProcAddress(wship6, "getaddrinfo", SYSTEM.VAL(LONGINT, getaddrinfo))
ELSE
KernelLog.String("Failed locating getaddrinfo, freeaddrinfo! You must install IPv6!"); KernelLog.Ln;
END
END;
Modules.InstallTermHandler(TermMod)
END Init;
PROCEDURE Startup*;
VAR data: WSAData; res: LONGINT;
BEGIN
KernelLog.String("WSAStartup ");
res := WSAStartup(2, data);
wsaStarted := res = 0;
IF wsaStarted THEN
KernelLog.String("done: "); KernelLog.String(data.szDescription)
ELSE
KernelLog.String("failed: "); KernelLog.Int(res, 0)
END;
KernelLog.Ln()
END Startup;
PROCEDURE CleanUp*;
VAR res: LONGINT;
BEGIN
IF wsaStarted THEN
res := WSACleanup();
wsaStarted := FALSE
END
END CleanUp;
PROCEDURE DispError*;
VAR err: Error; nr: LONGINT;
BEGIN
nr := WSAGetLastError();
IF (nr=0) THEN RETURN END;
err := errors;
WHILE (err # NIL ) & (err.nr # nr) DO
IF nr < err.nr THEN err := err.left
ELSIF nr > err.nr THEN err := err.right
END;
END;
IF err # NIL THEN
KernelLog.Enter; KernelLog.String( "Winsock: (" ); KernelLog.String( err.name ); KernelLog.String( ") : " );
KernelLog.String( err.msg ); KernelLog.Exit;
ELSE
KernelLog.Enter; KernelLog.String( "AosWinsock, unknown Error !! This should never happen:" );
KernelLog.Int( nr, 5 ); KernelLog.Exit;
END;
END DispError;
PROCEDURE Enter( nr: LONGINT; short, desc: ARRAY OF CHAR );
VAR this: Error;
PROCEDURE InsertErr( VAR err: Error; this: Error );
BEGIN
IF err # NIL THEN
IF this.nr < err.nr THEN InsertErr( err.left, this ) ELSE InsertErr( err.right, this ) END;
ELSE err := this;
END;
END InsertErr;
BEGIN
NEW( this ); this.nr := nr; COPY( short, this.name ); COPY( desc, this.msg ); InsertErr( errors, this );
END Enter;
PROCEDURE InitErrs;
BEGIN
Enter( 10013, "WSAEACCES", "Permission denied." );
Enter( 10048, "WSAEADDRINUSE", "Address already in use." );
Enter( 10049, "WSAEADDRNOTAVAIL", "Cannot assign requested address." );
Enter( 10047, "WSAEAFNOSUPPORT", "Address family not supported by protocol family." );
Enter( 10037, "WSAEALREADY", "Operation already in progress." );
Enter( 10061, "WSAECONNREFUSED", "Connection refused." );
Enter( 10053, "WSAECONNABORTED", "Software caused connection abort." );
Enter( 10054, "WSAECONNRESET", "Connection reset by peer." );
Enter( 10039, "WSAEDESTADDRREQ", "Destination address required." );
Enter( 10014, "WSAEFAULT", "Bad address." ); Enter( 10064, "WSAEHOSTDOWN", "Host is down." );
Enter( 10065, "WSAEHOSTUNREACH", "No route to host." );
Enter( 10036, "WSAEINPROGRESS", "Operation now in progress. " );
Enter( 10004, "WSAEINTR", "Interrupted function call." ); Enter( 10022, "WSAEINVAL", "Invalid argument." );
Enter( 10056, "WSAEISCONN", "Socket is already connected." );
Enter( 10024, "WSAEMFILE", "Too many open files." ); Enter( 10040, "WSAEMSGSIZE", "Message too long." );
Enter( 10050, "WSAENETDOWN", "Network is down." );
Enter( 10052, "WSAENETRESET", "Network dropped connection on reset." );
Enter( 10051, "WSAENETUNREACH", "Network is unreachable." );
Enter( 10055, "WSAENOBUFS", "No buffer space available." );
Enter( 10042, "WSAENOPROTOOPT", "Bad protocol option." );
Enter( 10057, "WSAENOTCONN", "Socket is not connected." );
Enter( 10038, "WSAENOTSOCK", "Socket operation on non-socket." );
Enter( 10045, "WSAEOPNOTSUPP", "Operation not supported." );
Enter( 10046, "WSAEPFNOSUPPORT", "Protocol family not supported." );
Enter( 10067, "WSAEPROCLIM", "Too many processes." );
Enter( 10043, "WSAEPROTONOSUPPORT", "Protocol not supported." );
Enter( 10041, "WSAEPROTOTYPE", "Protocol wrong type for socket." );
Enter( 10058, "WSAESHUTDOWN", "Cannot send after socket shutdown." );
Enter( 10044, "WSAESOCKTNOSUPPORT", "Socket type not supported." );
Enter( 10060, "WSAETIMEDOUT", "Connection timed out." );
Enter( 10109, "WSATYPE_NOT_FOUND", "Class type not found" );
Enter( 10035, "WSAEWOULDBLOCK", "Resource temporarily unavailable." );
Enter( 11001, "WSAHOST_NOT_FOUND", "Host not found." );
Enter( 10093, "WSANOTINITIALISED", "Successful WSAStartup() not yet performed." );
Enter( 11004, "WSANO_DATA", "Valid name, no data record of requested type." );
Enter( 11003, "WSANO_RECOVERY", "This is a non-recoverable error." );
Enter( 10091, "WSASYSNOTREADY", "Network subsystem is unavailable." );
Enter( 11002, "WSATRY_AGAIN", "Non-authoritative host not found." );
Enter( 10092, "WSAVERNOTSUPPORTED", "WINSOCK.DLL version out of range." );
Enter( 10101, "WSAEDISCON", "Graceful shutdown in progress." );
END InitErrs;
BEGIN
InitErrs(); Init();
END WSock32.