[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