GetAcceptExSockaddrs returns garbage! Does anyone know why?

Posted by David on Stack Overflow See other posts from Stack Overflow or by David
Published on 2010-05-22T06:40:27Z Indexed on 2010/05/22 6:40 UTC
Read the original article Hit count: 252

Filed under:
|

Hello, I'm trying to write a quick/dirty echoserver in Delphi, but I notice that GetAcceptExSockaddrs seems to be writing to only the first 4 bytes of the structure I pass it.

    USES SysUtils; 


    TYPE 
    BOOL = LongBool; 
    DWORD = Cardinal; 
    LPDWORD = ^DWORD; 
    short = SmallInt; 
    ushort = Word; 
    uint16 = Word; 
    uint = Cardinal; 
    ulong = Cardinal; 
    SOCKET = uint; 
    PVOID = Pointer; 
    _HANDLE = DWORD; 


    _in_addr = packed record 
            s_addr : ulong; 
    end; 

    _sockaddr_in = packed record 
            sin_family : short; 
            sin_port : uint16; 
            sin_addr : _in_addr; 
            sin_zero : array[0..7] of Char; 
    end; 
    P_sockaddr_in = ^_sockaddr_in; 

    _Overlapped = packed record 
            Internal : Int64; 
            Offset : Int64; 
            hEvent : _HANDLE; 
    end; 
    LP_Overlapped = ^_Overlapped; 


    IMPORTS 
    function _AcceptEx (sListenSocket, sAcceptSocket : SOCKET; lpOutputBuffer : PVOID; dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength : DWORD; lpdwBytesReceived : LPDWORD; lpOverlapped : LP_OVERLAPPED) : BOOL; stdcall; external MSWinsock name 'AcceptEx'; 

    procedure _GetAcceptExSockaddrs (lpOutputBuffer : PVOID; dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength : DWORD; LocalSockaddr : P_Sockaddr_in; LocalSockaddrLength : LPINT; RemoteSockaddr : P_Sockaddr_in; RemoteSockaddrLength : LPINT); stdcall; external MSWinsock name 'GetAcceptExSockaddrs'; 


    CONST 
    BufDataSize = 8192; 
    BufAddrSize = SizeOf (_sockaddr_in) + 16; 


    VAR 
    ListenSock, AcceptSock : SOCKET; 
    Addr, LocalAddr, RemoteAddr : _sockaddr_in; 
    LocalAddrSize, RemoteAddrSize : INT; 
    Buf : array[1..BufDataSize + BufAddrSize * 2] of Byte; 
    BytesReceived : DWORD; 
    Ov : _Overlapped; 

    BEGIN 
    //WSAStartup, create listen socket, bind to port 1066 on any interface, listen 
    //Create event for overlapped (autoreset, initally not signalled) 
    //Create accept socket 
    if _AcceptEx (ListenSock, AcceptSock, @Buf, BufDataSize, BufAddrSize, BufAddrSize, @BytesReceived, @Ov) then 
            WinCheck ('SetEvent', _SetEvent (Ov.hEvent)) 
    else 
            if GetLastError <> ERROR_IO_PENDING then 
                    WinCheck ('AcceptEx', GetLastError); 

    {do WaitForMultipleObjects} 

    _GetAcceptExSockaddrs (@Buf, BufDataSize, BufAddrSize, BufAddrSize, @LocalAddr, @LocalAddrSize, @RemoteAddr, @RemoteAddrSize); 

So if I run this, connect to it with Telnet (on same computer, connecting to localhost) and then type a key, WaitForMultipleObjects will unblock and GetAcceptExSockaddrs will run. But the result is garbage!

RemoteAddr.sin_family = -13894 
RemoteAddr.sin_port = 64 

and the rest is zeroes.

What gives? Thanks in advance!

© Stack Overflow or respective owner

Related posts about winsock

Related posts about delphi