From 89e1cf3d44ff5670e67e3f5e5caf50d7fa551e17 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 18 May 2021 22:35:50 -0500 Subject: [PATCH] ws2_32: Use IOCTL_AFD_WINE_SHUTDOWN in WS2_DisconnectEx(). Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/ws2_32/socket.c | 29 ++++++++++++------ dlls/ws2_32/tests/sock.c | 65 ++++++++++++++++++---------------------- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index aad92d5d4df..0110d53ab48 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3110,23 +3110,34 @@ static BOOL WINAPI WS2_ConnectEx( SOCKET s, const struct WS_sockaddr *name, int return !status; } -/*********************************************************************** - * DisconnectEx - */ -static BOOL WINAPI WS2_DisconnectEx( SOCKET s, LPOVERLAPPED ov, DWORD flags, DWORD reserved ) + +static BOOL WINAPI WS2_DisconnectEx( SOCKET s, OVERLAPPED *overlapped, DWORD flags, DWORD reserved ) { - TRACE( "socket %04lx, ov %p, flags 0x%x, reserved 0x%x\n", s, ov, flags, reserved ); + IO_STATUS_BLOCK iosb, *piosb = &iosb; + void *cvalue = NULL; + int how = SD_SEND; + HANDLE event = 0; + NTSTATUS status; + + TRACE( "socket %#lx, overlapped %p, flags %#x, reserved %#x\n", s, overlapped, flags, reserved ); if (flags & TF_REUSE_SOCKET) FIXME( "Reusing socket not supported yet\n" ); - if (ov) + if (overlapped) { - ov->Internal = STATUS_PENDING; - ov->InternalHigh = 0; + piosb = (IO_STATUS_BLOCK *)overlapped; + if (!((ULONG_PTR)overlapped->hEvent & 1)) cvalue = overlapped; + event = overlapped->hEvent; + overlapped->Internal = STATUS_PENDING; + overlapped->InternalHigh = 0; } - return !WS_shutdown( s, SD_BOTH ); + status = NtDeviceIoControlFile( (HANDLE)s, event, NULL, cvalue, piosb, + IOCTL_AFD_WINE_SHUTDOWN, &how, sizeof(how), NULL, 0 ); + if (!status && overlapped) status = STATUS_PENDING; + SetLastError( NtStatusToWSAError( status ) ); + return !status; } /*********************************************************************** diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 5028a4e749e..2c1f0e6142a 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -6732,7 +6732,7 @@ static void test_DisconnectEx(void) WSASetLastError(0xdeadbeef); ret = pDisconnectEx(client, &overlapped, 0, 0); ok(!ret, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError()); + ok(WSAGetLastError() == WSAENOTCONN, "got error %u\n", WSAGetLastError()); ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr)); ok(!ret, "failed to connect, error %u\n", WSAGetLastError()); @@ -6741,18 +6741,15 @@ static void test_DisconnectEx(void) WSASetLastError(0xdeadbeef); ret = pDisconnectEx(client, &overlapped, 0, 0); - todo_wine ok(!ret, "expected failure\n"); - todo_wine ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError()); + ok(!ret, "expected failure\n"); + ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError()); - if (WSAGetLastError() == ERROR_IO_PENDING) - { - ret = WaitForSingleObject(overlapped.hEvent, 1000); - ok(!ret, "wait timed out\n"); - size = 0xdeadbeef; - ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE); - ok(ret, "got error %u\n", GetLastError()); - ok(!size, "got size %u\n", size); - } + ret = WaitForSingleObject(overlapped.hEvent, 1000); + ok(!ret, "wait timed out\n"); + size = 0xdeadbeef; + ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, FALSE); + ok(ret, "got error %u\n", GetLastError()); + ok(!size, "got size %u\n", size); ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr)); ok(ret == -1, "expected failure\n"); @@ -6805,8 +6802,8 @@ static void test_DisconnectEx(void) WSASetLastError(0xdeadbeef); ret = pDisconnectEx(client, NULL, 0, 0); - todo_wine ok(ret, "expected success\n"); - todo_wine ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError()); + ok(ret, "expected success\n"); + ok(!WSAGetLastError() || WSAGetLastError() == 0xdeadbeef /* < 7 */, "got error %u\n", WSAGetLastError()); ret = connect(client, (struct sockaddr *)&server_addr, sizeof(server_addr)); ok(ret == -1, "expected failure\n"); @@ -8552,18 +8549,16 @@ static void test_shutdown_completion_port(void) SetLastError(0xdeadbeef); ret = pDisconnectEx(client, &overlapped, 0, 0); - todo_wine ok(!ret, "expected failure\n"); - todo_wine ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError()); - if (GetLastError() == ERROR_IO_PENDING) - { - ret = WaitForSingleObject(overlapped.hEvent, 1000); - ok(!ret, "wait failed\n"); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError()); - size = 0xdeadbeef; - ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, TRUE); - ok(ret, "got error %u\n", GetLastError()); - ok(!size, "got %u bytes\n", size); - } + ret = WaitForSingleObject(overlapped.hEvent, 1000); + ok(!ret, "wait failed\n"); + + size = 0xdeadbeef; + ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, TRUE); + ok(ret, "got error %u\n", GetLastError()); + ok(!size, "got %u bytes\n", size); size = 0xdeadbeef; key = 0xdeadbeef; @@ -8617,18 +8612,16 @@ static void test_shutdown_completion_port(void) SetLastError(0xdeadbeef); ret = pDisconnectEx(client, &overlapped, 0, 0); - todo_wine ok(!ret, "expected failure\n"); - todo_wine ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError()); - if (GetLastError() == ERROR_IO_PENDING) - { - ret = WaitForSingleObject(overlapped.hEvent, 1000); - ok(!ret, "wait failed\n"); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_IO_PENDING, "got error %u\n", GetLastError()); - size = 0xdeadbeef; - ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, TRUE); - ok(ret, "got error %u\n", GetLastError()); - ok(!size, "got %u bytes\n", size); - } + ret = WaitForSingleObject(overlapped.hEvent, 1000); + ok(!ret, "wait failed\n"); + + size = 0xdeadbeef; + ret = GetOverlappedResult((HANDLE)client, &overlapped, &size, TRUE); + ok(ret, "got error %u\n", GetLastError()); + ok(!size, "got %u bytes\n", size); ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0); ok(!ret, "expected failure\n");