From: Bruno Jesus <00cpxxx@gmail.com> Subject: ws2_32: Fix function GetAcceptExSockaddrs Message-Id: Date: Sat, 26 Nov 2011 19:35:01 -0200 From 74dd5243e49b9789e37d191d0f0294134a6b0eae Mon Sep 17 00:00:00 2001 From: Bruno Jesus <00cpxxx@gmail.com> Date: Sat, 26 Nov 2011 19:26:06 -0200 Subject: ws2_32: Fix function GetAcceptExSockaddrs In function GetAcceptExSockaddrs the buffer is decoded incorrectly, the local and remote parameters are reversed. Fixes bug http://bugs.winehq.org/show_bug.cgi?id=29164 --- dlls/ws2_32/socket.c | 4 ++-- dlls/ws2_32/tests/sock.c | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index cf33400..81b6b0f 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1675,13 +1675,13 @@ static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS sta /* WS2 Spec says size param is extra 16 bytes long...what do we put in it? */ addr = ((char *)wsa->buf) + wsa->data_len; len = wsa->local_len - sizeof(int); - WS_getpeername(HANDLE2SOCKET(wsa->accept_socket), + WS_getsockname(HANDLE2SOCKET(wsa->accept_socket), (struct WS_sockaddr *)(addr + sizeof(int)), &len); *(int *)addr = len; addr += wsa->local_len; len = wsa->remote_len - sizeof(int); - WS_getsockname(HANDLE2SOCKET(wsa->accept_socket), + WS_getpeername(HANDLE2SOCKET(wsa->accept_socket), (struct WS_sockaddr *)(addr + sizeof(int)), &len); *(int *)addr = len; diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 11e7b3c..4e5bb52 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4495,17 +4495,18 @@ static void test_AcceptEx(void) SOCKET acceptor = INVALID_SOCKET; SOCKET connector = INVALID_SOCKET; SOCKET connector2 = INVALID_SOCKET; - struct sockaddr_in bindAddress; + struct sockaddr_in bindAddress, peerAddress, *readBindAddress, *readRemoteAddress; int socklen; - GUID acceptExGuid = WSAID_ACCEPTEX; + GUID acceptExGuid = WSAID_ACCEPTEX, getAcceptExGuid = WSAID_GETACCEPTEXSOCKADDRS; LPFN_ACCEPTEX pAcceptEx = NULL; + LPFN_GETACCEPTEXSOCKADDRS pGetAcceptExSockaddrs = NULL; fd_set fds_accept, fds_send; struct timeval timeout = {0,10}; /* wait for 10 milliseconds */ int got, conn1, i; DWORD bytesReturned; char buffer[1024]; OVERLAPPED overlapped; - int iret; + int iret, localSize = sizeof(struct sockaddr_in), remoteSize = localSize; BOOL bret; DWORD dwret; @@ -4557,6 +4558,13 @@ static void test_AcceptEx(void) goto end; } + iret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &getAcceptExGuid, sizeof(getAcceptExGuid), + &pGetAcceptExSockaddrs, sizeof(pGetAcceptExSockaddrs), &bytesReturned, NULL, NULL); + if (iret) { + skip("WSAIoctl failed to get GetAcceptExSockaddrs with ret %d + errno %d\n", iret, WSAGetLastError()); + goto end; + } + bret = pAcceptEx(INVALID_SOCKET, acceptor, buffer, sizeof(buffer) - 2*(sizeof(struct sockaddr_in) + 16), sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16, &bytesReturned, &overlapped); @@ -4693,6 +4701,26 @@ static void test_AcceptEx(void) dwret = WaitForSingleObject(overlapped.hEvent, 0); ok(dwret == WAIT_TIMEOUT, "Waiting for accept event timeout failed with %d + errno %d\n", dwret, GetLastError()); + iret = getsockname( connector, (struct sockaddr *)&peerAddress, &remoteSize); + ok( !iret, "getsockname failed.\n"); + + /* Check if the buffer from AcceptEx is decoded correclty */ + pGetAcceptExSockaddrs(buffer, 2, sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16, + (struct sockaddr **)&readBindAddress, &localSize, + (struct sockaddr **)&readRemoteAddress, &remoteSize); + ok( readBindAddress->sin_addr.s_addr == bindAddress.sin_addr.s_addr, + "Local socket address is different %s != %s\n", + inet_ntoa(readBindAddress->sin_addr), inet_ntoa(bindAddress.sin_addr)); + ok( readBindAddress->sin_port == bindAddress.sin_port, + "Local socket port is different: %d != %d\n", + readBindAddress->sin_port, bindAddress.sin_port); + ok( readRemoteAddress->sin_addr.s_addr == peerAddress.sin_addr.s_addr, + "Remote socket address is different %s != %s\n", + inet_ntoa(readRemoteAddress->sin_addr), inet_ntoa(peerAddress.sin_addr)); + ok( readRemoteAddress->sin_port == peerAddress.sin_port, + "Remote socket port is different: %d != %d\n", + readRemoteAddress->sin_port, peerAddress.sin_port); + iret = send(connector, buffer, 1, 0); ok(iret == 1, "could not send 1 byte: send %d errno %d\n", iret, WSAGetLastError()); -- 1.7.2.5