; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: OS dependent part of the network library.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes: This library follows the rules of Berkley sockets library with some small
;         differences (for example in the return values)
;_________________________________________________________________________________________

uglobal
  __wsaData WSADATA
endg


initialize InitWindowsSockets
begin
        invoke  WSAStartup, $0101, __wsaData
        test    eax, eax
        jz      @f
        int3
@@:
        return
endp

finalize FinishWindowsSockets
begin
        invoke  WSACleanup
        return
endp


proc __SocketError
begin
        cmp     eax, SOCKET_ERROR
        jne     .no_error

        push    ecx edx
        invoke  WSAGetLastError
        pop     edx ecx
        stc
        return

.no_error:
        clc
        return
endp


proc SocketCreate, .protocol_family, .socket_type, .protocol
begin
        push    ecx edx
        invoke  socket, [.protocol_family], [.socket_type], [.protocol]
        call    __SocketError
        pop     edx ecx
        return
endp



proc SocketClose, .hSocket
begin
        push    ecx edx
        invoke  shutdown

        invoke  closesocket, [.hSocket]
        call    __SocketError
        pop     edx ecx
        return
endp



proc SocketConnect, .hSocket, .pAddress
begin
        push    ecx edx
        invoke  connect, [.hSocket], [.pAddress], sizeof.TSocketAddress
        call    __SocketError
        pop     edx ecx
        return
endp



proc SocketBind, .hSocket, .pAddressIn
begin
        push    ecx edx
        invoke  bind, [.hSocket], [.pAddressIn], sizeof.TSocketAddressIn
        call    __SocketError
        pop     edx ecx
        return
endp



proc SocketListen, .hSocket, .maxPending
begin
        push    ecx edx
        invoke  listen, [.hSocket], [.maxPending]
        call    __SocketError
        pop     edx ecx
        return
endp



proc SocketAccept, .hSocket, .pAddress
.addrlen dd ?
begin
        push    edx
        mov     [.addrlen], 0
        mov     [.addrlen], sizeof.TSocketAddress
        lea     ecx, [.addrlen]
        cmp     [.pAddress], 0
        jne     @f
        xor     ecx, ecx
@@:
        invoke  accept, [.hSocket], [.pAddress], ecx
        mov     ecx, [.addrlen]
        call    __SocketError
        pop     edx
        return
endp



proc SocketSend, .hSocket, .pBuffer, .DataLen, .flags
begin
        push    ecx edx
        invoke  send, [.hSocket], [.pBuffer], [.DataLen], [.flags]
        call    __SocketError
        pop     edx ecx
        return
endp


proc SocketReceive, .hSocket, .pBuffer, .BufferSize, .flags
begin
        push    ecx edx
        invoke  recv, [.hSocket], [.pBuffer], [.BufferSize], [.flags]
        call    __SocketError
        pop     edx ecx
        return
endp


proc SocketSendTo, .hSocket, .pBuffer, .DataLen, .flags, .pAddressTo
begin
        push    ecx edx
        invoke  sendto, [.hSocket], [.pBuffer], [.DataLen], [.flags], [.pAddressTo], sizeof.TSocketAddress
        call    __SocketError
        pop     edx ecx
        return
endp


proc SocketReceiveFrom, .hSocket, .pBuffer, .BufferSize, .flags, .pAddressFrom
.addrlen dd ?
begin
        push    edx
        mov     [.addrlen], sizeof.SocketAddress
        lea     ecx,  [.addrlen]
        invoke  recvfrom, [.hSocket], [.pBuffer], [.BufferSize], [.flags], [.pAddressFrom], ecx
        call    __SocketError
        mov     ecx, [.addrlen]
        pop     edx
        return
endp