[PATCH 5/5] ws2_32: Implement SIO_BASE_HANDLE.

Zebediah Figura z.figura12 at gmail.com
Thu Jun 10 12:36:39 CDT 2021


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50520
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/ws2_32/socket.c     | 22 ++++++++++
 dlls/ws2_32/tests/sock.c | 92 ++++++++++++++++++++++++++++++++++++++++
 include/mswsock.h        | 10 +++--
 3 files changed, 120 insertions(+), 4 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 843ec5ba3ab..f4e3a6c9e43 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -3463,6 +3463,28 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
         return ret ? -1 : 0;
     }
 
+    case WS_SIO_BASE_HANDLE:
+    {
+        NTSTATUS status;
+        DWORD ret;
+
+        if (overlapped)
+        {
+            status = STATUS_NOT_SUPPORTED;
+        }
+        else
+        {
+            status = STATUS_SUCCESS;
+            *(SOCKET *)out_buff = s;
+        }
+        ret = server_ioctl_sock( s, IOCTL_AFD_WINE_COMPLETE_ASYNC, &status, sizeof(status),
+                                 NULL, 0, ret_size, overlapped, completion );
+        if (overlapped) ret = ERROR_IO_PENDING;
+        if (!ret) *ret_size = sizeof(SOCKET);
+        SetLastError( ret );
+        return ret ? -1 : 0;
+    }
+
     default:
         FIXME( "unimplemented ioctl %s\n", debugstr_wsaioctl( code ) );
         /* fall through */
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index d581b1df6c1..76d0a3f3b19 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -4275,6 +4275,97 @@ static void test_get_extension_func(void)
     closesocket(s);
 }
 
+static void test_base_handle(void)
+{
+    OVERLAPPED overlapped = {0}, *overlapped_ptr;
+    unsigned int i;
+    SOCKET s, base;
+    ULONG_PTR key;
+    HANDLE port;
+    DWORD size;
+    int ret;
+
+    static const struct
+    {
+        int family, type, protocol;
+    }
+    tests[] =
+    {
+        {AF_INET, SOCK_STREAM, IPPROTO_TCP},
+        {AF_INET, SOCK_DGRAM, IPPROTO_UDP},
+        {AF_INET6, SOCK_STREAM, IPPROTO_TCP},
+        {AF_INET6, SOCK_DGRAM, IPPROTO_UDP},
+    };
+
+    for (i = 0; i < ARRAY_SIZE(tests); ++i)
+    {
+        s = socket(tests[i].family, tests[i].type, tests[i].protocol);
+        if (s == INVALID_SOCKET) continue;
+        port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
+
+        WSASetLastError(0xdeadbeef);
+        ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), NULL, &overlapped, NULL);
+        ok(ret == -1, "expected failure\n");
+        ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
+
+        WSASetLastError(0xdeadbeef);
+        size = 0xdeadbeef;
+        base = 0xdeadbeef;
+        ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), &size, NULL, NULL);
+        ok(!ret, "expected success\n");
+        ok(!WSAGetLastError(), "got error %u\n", WSAGetLastError());
+        ok(size == sizeof(base), "got size %u\n", size);
+        ok(base == s, "expected %#Ix, got %#Ix\n", s, base);
+
+        WSASetLastError(0xdeadbeef);
+        size = 0xdeadbeef;
+        base = 0xdeadbeef;
+        overlapped.Internal = 0xdeadbeef;
+        overlapped.InternalHigh = 0xdeadbeef;
+        ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), &size, &overlapped, NULL);
+        ok(ret == -1, "expected failure\n");
+        ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
+        ok(size == 0xdeadbeef, "got size %u\n", size);
+
+        ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0);
+        ok(!ret, "expected failure\n");
+        ok(GetLastError() == ERROR_NOT_SUPPORTED, "got error %u\n", GetLastError());
+        ok(!size, "got size %u\n", size);
+        ok(key == 123, "got key %Iu\n", key);
+        ok(overlapped_ptr == &overlapped, "got overlapped %p\n", overlapped_ptr);
+        ok((NTSTATUS)overlapped.Internal == STATUS_NOT_SUPPORTED, "got status %#x\n", (NTSTATUS)overlapped.Internal);
+        ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
+        ok(base == 0xdeadbeef, "expected %#Ix, got %#Ix\n", s, base);
+
+        CloseHandle(port);
+        closesocket(s);
+
+        s = socket(tests[i].family, tests[i].type, tests[i].protocol);
+
+        ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), NULL, &overlapped, socket_apc);
+        ok(ret == -1, "expected failure\n");
+        ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
+
+        apc_count = 0;
+        size = 0xdeadbeef;
+        base = 0xdeadbeef;
+        ret = WSAIoctl(s, SIO_BASE_HANDLE, NULL, 0, &base, sizeof(base), &size, &overlapped, socket_apc);
+        ok(ret == -1, "expected failure\n");
+        ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
+        ok(size == 0xdeadbeef, "got size %u\n", size);
+
+        ret = SleepEx(0, TRUE);
+        ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret);
+        ok(apc_count == 1, "APC was called %u times\n", apc_count);
+        ok(apc_error == WSAEOPNOTSUPP, "got APC error %u\n", apc_error);
+        ok(!apc_size, "got APC size %u\n", apc_size);
+        ok(apc_overlapped == &overlapped, "got APC overlapped %p\n", apc_overlapped);
+        ok(base == 0xdeadbeef, "expected %#Ix, got %#Ix\n", s, base);
+
+        closesocket(s);
+    }
+}
+
 static BOOL drain_pause = FALSE;
 static DWORD WINAPI drain_socket_thread(LPVOID arg)
 {
@@ -10837,6 +10928,7 @@ START_TEST( sock )
     test_keepalive_vals();
     test_sioRoutingInterfaceQuery();
     test_sioAddressListChange();
+    test_base_handle();
     test_unsupported_ioctls();
 
     test_WSASendMsg();
diff --git a/include/mswsock.h b/include/mswsock.h
index e402f33ecf7..fa97d5bf04d 100644
--- a/include/mswsock.h
+++ b/include/mswsock.h
@@ -83,11 +83,13 @@ extern "C" {
 #endif
 
 #ifndef USE_WS_PREFIX
-#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
-#define SIO_SET_COMPATIBILITY_MODE _WSAIOW(IOC_VENDOR,300)
+#define SIO_UDP_CONNRESET               _WSAIOW(IOC_VENDOR, 12)
+#define SIO_SET_COMPATIBILITY_MODE      _WSAIOW(IOC_VENDOR, 300)
+#define SIO_BASE_HANDLE                 _WSAIOR(IOC_WS2, 34)
 #else
-#define WS_SIO_UDP_CONNRESET _WSAIOW(WS_IOC_VENDOR,12)
-#define WS_SIO_SET_COMPATIBILITY_MODE _WSAIOW(WS_IOC_VENDOR,300)
+#define WS_SIO_UDP_CONNRESET            _WSAIOW(WS_IOC_VENDOR, 12)
+#define WS_SIO_SET_COMPATIBILITY_MODE   _WSAIOW(WS_IOC_VENDOR, 300)
+#define WS_SIO_BASE_HANDLE              _WSAIOR(WS_IOC_WS2, 34)
 #endif
 
 #define DE_REUSE_SOCKET TF_REUSE_SOCKET
-- 
2.30.2




More information about the wine-devel mailing list