[PATCH 3/5] server: Fail with WSAEINVAL or WSAEALREADY when trying to connect a socket that is already connecting via nonblocking connect().
Zebediah Figura
z.figura12 at gmail.com
Thu Jun 10 12:36:37 CDT 2021
Fixes connection in Mortal Kombat 11; reported by Thomas Crider.
Fixes: a891713f48fbcdae05f27f7e73b1cec78cf42644
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
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)
{
--
2.30.2
More information about the wine-devel
mailing list