Zebediah Figura : server: Fail with WSAEINVAL or WSAEALREADY when trying to connect a socket that is already connecting via nonblocking connect().

Alexandre Julliard julliard at winehq.org
Thu Jun 10 16:04:51 CDT 2021


Module: wine
Branch: master
Commit: 9344a490a4924d48baa0dcf2b63cac11c795cdca
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=9344a490a4924d48baa0dcf2b63cac11c795cdca

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Thu Jun 10 12:36:37 2021 -0500

server: Fail with WSAEINVAL or WSAEALREADY when trying to connect a socket that is already connecting via nonblocking connect().

Fixes connection in Mortal Kombat 11; reported by Thomas Crider.

Fixes: a891713f48fbcdae05f27f7e73b1cec78cf42644
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ws2_32/socket.c     | 3 ++-
 dlls/ws2_32/tests/sock.c | 4 ++--
 server/sock.c            | 8 ++++++++
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index a4d0e932eae..5f0d712f5b7 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -2222,7 +2222,8 @@ int WINAPI WS_connect( SOCKET s, const struct WS_sockaddr *addr, int len )
     }
     if (status)
     {
-        SetLastError( NtStatusToWSAError( status ) );
+        /* NtStatusToWSAError() has no mapping for WSAEALREADY */
+        SetLastError( status == STATUS_ADDRESS_ALREADY_ASSOCIATED ? WSAEALREADY : NtStatusToWSAError( status ) );
         return -1;
     }
     return 0;
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 95bf7a12830..d581b1df6c1 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -10251,7 +10251,7 @@ static void test_connecting_socket(void)
      * second to return WSAEALREADY. */
     ret = connect(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
     ok(ret == -1, "got %d\n", ret);
-    todo_wine ok(WSAGetLastError() == WSAEALREADY, "got %u\n", WSAGetLastError());
+    ok(WSAGetLastError() == WSAEALREADY, "got %u\n", WSAGetLastError());
 
     ret = WSAIoctl(client, SIO_GET_EXTENSION_FUNCTION_POINTER, &connectex_guid, sizeof(connectex_guid),
             &pConnectEx, sizeof(pConnectEx), &size, NULL, NULL);
@@ -10260,7 +10260,7 @@ static void test_connecting_socket(void)
     overlapped.InternalHigh = 0xdeadbeef;
     ret = pConnectEx(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr), NULL, 0, &size, &overlapped);
     ok(!ret, "got %d\n", ret);
-    todo_wine ok(WSAGetLastError() == WSAEINVAL, "got %u\n", WSAGetLastError());
+    ok(WSAGetLastError() == WSAEINVAL, "got %u\n", WSAGetLastError());
     ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "got status %#x\n", (NTSTATUS)overlapped.Internal);
     todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
 
diff --git a/server/sock.c b/server/sock.c
index cae0c2ff32b..b4649abbf08 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -1784,6 +1784,14 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
             return 0;
         }
 
+        if (sock->state & FD_CONNECT)
+        {
+            /* FIXME: STATUS_ADDRESS_ALREADY_ASSOCIATED probably isn't right,
+             * but there's no status code that maps to WSAEALREADY... */
+            set_error( params->synchronous ? STATUS_ADDRESS_ALREADY_ASSOCIATED : STATUS_INVALID_PARAMETER );
+            return 0;
+        }
+
         ret = connect( unix_fd, addr, params->addr_len );
         if (ret < 0 && errno != EINPROGRESS)
         {




More information about the wine-cvs mailing list