From: Matt Durgavich mattdurgavich@gmail.com
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/ws2_32/socket.c | 22 ++++++++++++++++------ dlls/ws2_32/tests/sock.c | 15 +++++++-------- server/protocol.def | 3 +++ server/sock.c | 9 +++++++++ 4 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index a302612..a2b9aea 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1697,13 +1697,23 @@ int WINAPI WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) */ INT WINAPI WSACleanup(void) { - if (num_startup) { - num_startup--; - TRACE("pending cleanups: %d\n", num_startup); - return 0; + if (!num_startup) + { + SetLastError(WSANOTINITIALISED); + return SOCKET_ERROR; } - SetLastError(WSANOTINITIALISED); - return SOCKET_ERROR; + + if (!--num_startup) + { + SERVER_START_REQ(socket_cleanup) + { + wine_server_call( req ); + } + SERVER_END_REQ; + } + + TRACE("pending cleanups: %d\n", num_startup); + return 0; }
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 0c7f736..f0fa8f0 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -1218,18 +1218,17 @@ static void test_WithWSAStartup(void) ok(res == 0, "WSAStartup() failed unexpectedly: %d\n", res);
/* show that sockets are destroyed automatically after WSACleanup */ - todo_wine { SetLastError(0xdeadbeef); res = send(pairs[0].src, "TEST", 4, 0); error = WSAGetLastError(); ok(res == SOCKET_ERROR, "send should have failed\n"); - ok(error == WSAENOTSOCK, "expected 10038, got %d\n", error); + todo_wine ok(error == WSAENOTSOCK, "expected 10038, got %d\n", error);
SetLastError(0xdeadbeef); res = send(pairs[0].dst, "TEST", 4, 0); error = WSAGetLastError(); ok(res == SOCKET_ERROR, "send should have failed\n"); - ok(error == WSAENOTSOCK, "expected 10038, got %d\n", error); + todo_wine ok(error == WSAENOTSOCK, "expected 10038, got %d\n", error);
/* Check that all sockets were destroyed */ for (i = 0; i < socks; i++) @@ -1249,14 +1248,14 @@ static void test_WithWSAStartup(void) SetLastError(0xdeadbeef); res = getsockname(sock, (struct sockaddr *)&saddr, &size); error = WSAGetLastError(); - ok(res == SOCKET_ERROR, "Test[%d]: getsockname should have failed\n", i); - if (res == SOCKET_ERROR) - ok(error == WSAENOTSOCK, "Test[%d]: expected 10038, got %d\n", i, error); + if (j == 2 || (j == 0 && i == 0)) + todo_wine ok(res == SOCKET_ERROR, "Test[%d]: getsockname should have failed\n", i); + else + ok(res == SOCKET_ERROR, "Test[%d]: getsockname should have failed\n", i); + todo_wine ok(error == WSAENOTSOCK, "Test[%d]: expected 10038, got %d\n", i, error); } }
- } - /* While wine is not fixed, close all sockets manually */ for (i = 0; i < socks; i++) { diff --git a/server/protocol.def b/server/protocol.def index b6ad514..af0bc20 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1006,6 +1006,9 @@ struct rawinput_device obj_handle_t handle; /* handle to close */ @END
+/* Close all sockets for the current process */ +@REQ(socket_cleanup) +@END
/* Set a handle information */ @REQ(set_handle_info) diff --git a/server/sock.c b/server/sock.c index 1a53ce4..5095a6e 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1334,3 +1334,12 @@ DECL_HANDLER(get_socket_info)
release_object( &sock->obj ); } + +DECL_HANDLER(socket_cleanup) +{ + unsigned int index = 0; + obj_handle_t sock; + + while ((sock = enumerate_handles(current->process, &sock_ops, &index))) + close_handle(current->process, sock); +}