Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/tests/sock.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index cf3878eba40..e76d9ac27a6 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -200,6 +200,23 @@ static void tcp_socketpair(SOCKET *src, SOCKET *dst) tcp_socketpair_flags(src, dst, WSA_FLAG_OVERLAPPED); }
+#define check_poll(a, b) check_poll_(__LINE__, a, POLLRDNORM | POLLRDBAND | POLLWRNORM, b, FALSE) +#define check_poll_todo(a, b) check_poll_(__LINE__, a, POLLRDNORM | POLLRDBAND | POLLWRNORM, b, TRUE) +#define check_poll_mask(a, b, c) check_poll_(__LINE__, a, b, c, FALSE) +#define check_poll_mask_todo(a, b, c) check_poll_(__LINE__, a, b, c, TRUE) +static void check_poll_(int line, SOCKET s, short mask, short expect, BOOL todo) +{ + WSAPOLLFD pollfd; + int ret; + + pollfd.fd = s; + pollfd.events = mask; + pollfd.revents = 0xdead; + ret = pWSAPoll(&pollfd, 1, 1000); + ok_(__FILE__, line)(ret == (pollfd.revents ? 1 : 0), "WSAPoll() returned %d\n", ret); + todo_wine_if (todo) ok_(__FILE__, line)(pollfd.revents == expect, "got wrong events %#x\n", pollfd.revents); +} + static void set_so_opentype ( BOOL overlapped ) { int optval = !overlapped, newval, len = sizeof (int); @@ -3763,11 +3780,17 @@ static void test_fionread_siocatmark(void) ret = send(server, "data", 5, 0); ok(ret == 5, "got %d\n", ret);
+ /* wait for the data to be available */ + check_poll_mask(client, POLLRDNORM, POLLRDNORM); + check_fionread_siocatmark(client, 5, TRUE);
ret = send(server, "a", 1, MSG_OOB); ok(ret == 1, "got %d\n", ret);
+ /* wait for the data to be available */ + check_poll_mask(client, POLLRDBAND, POLLRDBAND); + check_fionread_siocatmark_todo_oob(client, 5, FALSE);
ret = send(server, "a", 1, MSG_OOB); @@ -5871,23 +5894,6 @@ static void test_write_watch(void) VirtualFree( base, 0, MEM_FREE ); }
-#define check_poll(a, b) check_poll_(__LINE__, a, POLLRDNORM | POLLRDBAND | POLLWRNORM, b, FALSE) -#define check_poll_todo(a, b) check_poll_(__LINE__, a, POLLRDNORM | POLLRDBAND | POLLWRNORM, b, TRUE) -#define check_poll_mask(a, b, c) check_poll_(__LINE__, a, b, c, FALSE) -#define check_poll_mask_todo(a, b, c) check_poll_(__LINE__, a, b, c, TRUE) -static void check_poll_(int line, SOCKET s, short mask, short expect, BOOL todo) -{ - WSAPOLLFD pollfd; - int ret; - - pollfd.fd = s; - pollfd.events = mask; - pollfd.revents = 0xdead; - ret = pWSAPoll(&pollfd, 1, 1000); - ok_(__FILE__, line)(ret == (pollfd.revents ? 1 : 0), "WSAPoll() returned %d\n", ret); - todo_wine_if (todo) ok_(__FILE__, line)(pollfd.revents == expect, "got wrong events %#x\n", pollfd.revents); -} - static void test_WSAPoll(void) { const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/tests/sock.c | 142 ++++++++++++++++++++++++++++++++------- 1 file changed, 117 insertions(+), 25 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index e76d9ac27a6..3829a7914cb 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -9231,58 +9231,150 @@ static void test_shutdown_completion_port(void)
static void test_address_list_query(void) { - SOCKET_ADDRESS_LIST *address_list; - DWORD bytes_returned, size; + char buffer[1024]; + SOCKET_ADDRESS_LIST *address_list = (SOCKET_ADDRESS_LIST *)buffer; + OVERLAPPED overlapped = {0}, *overlapped_ptr; + DWORD size, expect_size; unsigned int i; + ULONG_PTR key; + HANDLE port; SOCKET s; int ret;
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); ok(s != INVALID_SOCKET, "Failed to create socket, error %d.\n", WSAGetLastError()); + port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
- bytes_returned = 0; - ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0, &bytes_returned, NULL, NULL); + size = 0; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0, &size, NULL, NULL); ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret); ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError()); - ok(bytes_returned >= FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), - "Got unexpected bytes_returned %u.\n", bytes_returned); + ok(size >= FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), "Got unexpected size %u.\n", size); + expect_size = size;
- size = bytes_returned; - bytes_returned = 0; - address_list = HeapAlloc(GetProcessHeap(), 0, size * 2); - ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, address_list, size * 2, &bytes_returned, NULL, NULL); - ok(!ret, "Got unexpected ret %d, error %d.\n", ret, WSAGetLastError()); - ok(bytes_returned == size, "Got unexpected bytes_returned %u, expected %u.\n", bytes_returned, size); + size = 0; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &size, NULL, NULL); + ok(!ret, "Got unexpected ret %d.\n", ret); + todo_wine ok(!WSAGetLastError(), "Got unexpected error %d.\n", WSAGetLastError()); + ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
- bytes_returned = FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[address_list->iAddressCount]); + expect_size = FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[address_list->iAddressCount]); for (i = 0; i < address_list->iAddressCount; ++i) { - bytes_returned += address_list->Address[i].iSockaddrLength; + expect_size += address_list->Address[i].iSockaddrLength; } - ok(size == bytes_returned, "Got unexpected size %u, expected %u.\n", size, bytes_returned); + ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
- ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, address_list, size, NULL, NULL, NULL); + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), NULL, NULL, NULL); ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret); ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
- bytes_returned = 0xdeadbeef; - ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, size, &bytes_returned, NULL, NULL); + size = 0xdeadbeef; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, sizeof(buffer), &size, NULL, NULL); ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret); ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError()); - ok(bytes_returned == size, "Got unexpected bytes_returned %u, expected %u.\n", bytes_returned, size); + ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size);
- ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, address_list, 1, &bytes_returned, NULL, NULL); + size = 0xdeadbeef; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 0, &size, NULL, NULL); + ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret); + ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError()); + ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size); + + size = 0xdeadbeef; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 1, &size, NULL, NULL); ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret); ok(WSAGetLastError() == WSAEINVAL, "Got unexpected error %d.\n", WSAGetLastError()); - ok(bytes_returned == 0, "Got unexpected bytes_returned %u.\n", bytes_returned); + ok(!size, "Got size %u.\n", size);
- ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, address_list, - FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), &bytes_returned, NULL, NULL); + size = 0xdeadbeef; + memset(buffer, 0xcc, sizeof(buffer)); + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, + FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), &size, NULL, NULL); ok(ret == SOCKET_ERROR, "Got unexpected ret %d.\n", ret); ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError()); - ok(bytes_returned == size, "Got unexpected bytes_returned %u, expected %u.\n", bytes_returned, size); + ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size); + ok(address_list->iAddressCount == 0xcccccccc, "Got %u addresses.\n", address_list->iAddressCount); + + WSASetLastError(0xdeadbeef); + overlapped.Internal = 0xdeadbeef; + overlapped.InternalHigh = 0xdeadbeef; + size = 0xdeadbeef; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 0, &size, &overlapped, NULL); + ok(ret == -1, "Got unexpected ret %d.\n", ret); + ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError()); + ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size); + todo_wine ok(overlapped.Internal == 0xdeadbeef, "Got status %#x.\n", (NTSTATUS)overlapped.Internal); + todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "Got size %Iu.\n", overlapped.InternalHigh); + + overlapped.Internal = 0xdeadbeef; + overlapped.InternalHigh = 0xdeadbeef; + size = 0xdeadbeef; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 1, &size, &overlapped, NULL); + ok(ret == -1, "Got unexpected ret %d.\n", ret); + ok(WSAGetLastError() == WSAEINVAL, "Got unexpected error %d.\n", WSAGetLastError()); + ok(!size, "Expected size %u, got %u.\n", expect_size, size); + ok(overlapped.Internal == 0xdeadbeef, "Got status %#x.\n", (NTSTATUS)overlapped.Internal); + ok(overlapped.InternalHigh == 0xdeadbeef, "Got size %Iu.\n", overlapped.InternalHigh); + + overlapped.Internal = 0xdeadbeef; + overlapped.InternalHigh = 0xdeadbeef; + size = 0xdeadbeef; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, + FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0]), &size, &overlapped, NULL); + ok(ret == -1, "Got unexpected ret %d.\n", ret); + ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError()); + ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size); + todo_wine ok(overlapped.Internal == 0xdeadbeef, "Got status %#x.\n", (NTSTATUS)overlapped.Internal); + todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "Got size %Iu.\n", overlapped.InternalHigh); + ok(address_list->iAddressCount == 0xcccccccc, "Got %u addresses.\n", address_list->iAddressCount); + + overlapped.Internal = 0xdeadbeef; + overlapped.InternalHigh = 0xdeadbeef; + size = 0xdeadbeef; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &size, &overlapped, NULL); + ok(!ret, "Got unexpected ret %d.\n", ret); + todo_wine ok(!WSAGetLastError(), "Got unexpected error %d.\n", WSAGetLastError()); + ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size); + + ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0); + todo_wine ok(ret, "Got error %u.\n", GetLastError()); + todo_wine ok(!size, "Got size %u.\n", size); + ok(overlapped_ptr == &overlapped, "Got overlapped %p.\n", overlapped_ptr); + ok(!overlapped.Internal, "Got status %#x.\n", (NTSTATUS)overlapped.Internal); + todo_wine ok(!overlapped.InternalHigh, "Got size %Iu.\n", overlapped.InternalHigh); + + ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0); + ok(!ret, "Expected failure.\n"); + todo_wine ok(GetLastError() == WAIT_TIMEOUT, "Got error %u.\n", GetLastError()); + + closesocket(s); + CloseHandle(port); + + /* Test with an APC. */ + + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), NULL, &overlapped, socket_apc); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + + apc_count = 0; + size = 0xdeadbeef; + ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, sizeof(buffer), &size, &overlapped, socket_apc); + ok(!ret, "expected success\n"); + ok(size == expect_size, "got size %u\n", size); + + ret = SleepEx(0, TRUE); + todo_wine ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret); + if (ret == WAIT_IO_COMPLETION) + { + ok(apc_count == 1, "APC was called %u times\n", apc_count); + ok(!apc_error, "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); + }
- HeapFree(GetProcessHeap(), 0, address_list); closesocket(s); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/tests/sock.c | 72 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 3829a7914cb..b5be63d9995 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -10010,23 +10010,46 @@ static void test_iocp(void) closesocket(dst); }
-static void test_wsaioctl(void) +static void test_get_interface_list(void) { + OVERLAPPED overlapped = {0}, *overlapped_ptr; + DWORD size, expect_size; unsigned int i, count; INTERFACE_INFO *info; BOOL loopback_found; char buffer[4096]; - DWORD size; + ULONG_PTR key; + HANDLE port; SOCKET s; int ret;
s = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); ok(s != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError()); + port = CreateIoCompletionPort((HANDLE)s, NULL, 123, 0);
size = 0xdeadbeef; + WSASetLastError(0xdeadbeef); ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), &size, NULL, NULL); ok(!ret, "Got unexpected ret %d.\n", ret); + todo_wine ok(!WSAGetLastError(), "Got error %u.\n", WSAGetLastError()); ok(size && size != 0xdeadbeef && !(size % sizeof(INTERFACE_INFO)), "Got unexpected size %u.\n", size); + expect_size = size; + + size = 0xdeadbeef; + overlapped.Internal = 0xdeadbeef; + overlapped.InternalHigh = 0xdeadbeef; + ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), &size, &overlapped, NULL); + todo_wine ok(ret == -1, "Got unexpected ret %d.\n", ret); + todo_wine ok(WSAGetLastError() == ERROR_IO_PENDING, "Got error %u.\n", WSAGetLastError()); + todo_wine ok(size == 0xdeadbeef, "Got size %u.\n", size); + + ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 100); + ok(ret, "Got error %u.\n", GetLastError()); + ok(size == expect_size, "Expected size %u, got %u.\n", expect_size, size); + ok(key == 123, "Got key %Iu.\n", key); + ok(overlapped_ptr == &overlapped, "Got overlapped %p.\n", overlapped_ptr); + ok(!overlapped.Internal, "Got status %#x.\n", (NTSTATUS)overlapped.Internal); + ok(overlapped.InternalHigh == expect_size, "Expected size %u, got %Iu.\n", expect_size, overlapped.InternalHigh);
info = (INTERFACE_INFO *)buffer; count = size / sizeof(INTERFACE_INFO); @@ -10058,10 +10081,53 @@ static void test_wsaioctl(void) ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError()); ok(!size, "Got unexpected size %u.\n", size);
+ size = 0xdeadbeef; + overlapped.Internal = 0xdeadbeef; + overlapped.InternalHigh = 0xdeadbeef; + ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(INTERFACE_INFO) - 1, &size, &overlapped, NULL); + ok(ret == -1, "Got unexpected ret %d.\n", ret); + todo_wine ok(WSAGetLastError() == ERROR_IO_PENDING, "Got error %u.\n", WSAGetLastError()); + todo_wine ok(size == 0xdeadbeef, "Got size %u.\n", size); + + ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 100); + ok(!ret, "Expected failure.\n"); + todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "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); + todo_wine ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_TOO_SMALL, "Got status %#x.\n", (NTSTATUS)overlapped.Internal); + ok(!overlapped.InternalHigh, "Got size %Iu.\n", overlapped.InternalHigh); + ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, sizeof(buffer), NULL, NULL, NULL); ok(ret == -1, "Got unexpected ret %d.\n", ret); ok(WSAGetLastError() == WSAEFAULT, "Got unexpected error %d.\n", WSAGetLastError());
+ CloseHandle(port); + closesocket(s); + + /* Test with an APC. */ + + s = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); + ok(s != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError()); + + size = 0xdeadbeef; + apc_count = 0; + ret = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, + sizeof(INTERFACE_INFO) - 1, &size, &overlapped, socket_apc); + ok(ret == -1, "Got unexpected ret %d.\n", ret); + todo_wine ok(WSAGetLastError() == ERROR_IO_PENDING, "Got error %u.\n", WSAGetLastError()); + todo_wine ok(size == 0xdeadbeef, "Got size %u.\n", size); + + ret = SleepEx(100, TRUE); + todo_wine ok(ret == WAIT_IO_COMPLETION, "got %d\n", ret); + if (ret == WAIT_IO_COMPLETION) + { + ok(apc_count == 1, "APC was called %u times\n", apc_count); + ok(apc_error == WSAEFAULT, "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); + } + closesocket(s); }
@@ -10674,6 +10740,7 @@ START_TEST( sock ) test_fionbio(); test_fionread_siocatmark(); test_get_extension_func(); + test_get_interface_list(); test_keepalive_vals(); test_sioRoutingInterfaceQuery(); test_sioAddressListChange(); @@ -10707,7 +10774,6 @@ START_TEST( sock )
/* this is an io heavy test, do it at the end so the kernel doesn't start dropping packets */ test_send(); - test_wsaioctl();
Exit(); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 18 +++++------ dlls/ws2_32/tests/sock.c | 66 +++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 43 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 24ac24dcdeb..b6a14c3e4f4 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3329,7 +3329,7 @@ static DWORD get_interface_list(SOCKET s, void *out_buff, DWORD out_size, DWORD DWORD status = 0; int fd;
- if (!out_buff || !ret_size) + if (!out_buff) return WSAEFAULT;
if ((fd = get_sock_fd(s, 0, NULL)) == -1) @@ -3451,6 +3451,12 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID TRACE("%04lx, %s, %p, %d, %p, %d, %p, %p, %p\n", s, debugstr_wsaioctl(code), in_buff, in_size, out_buff, out_size, ret_size, overlapped, completion);
+ if (!ret_size) + { + SetLastError( WSAEFAULT ); + return -1; + } + switch (code) { case WS_FIONBIO: @@ -3544,12 +3550,6 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
TRACE("-> SIO_ADDRESS_LIST_QUERY request\n");
- if (!ret_size) - { - SetLastError(WSAEFAULT); - return SOCKET_ERROR; - } - if (out_size && out_size < FIELD_OFFSET(SOCKET_ADDRESS_LIST, Address[0])) { *ret_size = 0; @@ -3718,7 +3718,7 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID TRACE("-> WS_SIO_ROUTING_INTERFACE_QUERY request\n");
if (!in_buff || in_size < sizeof(struct WS_sockaddr) || - !out_buff || out_size < sizeof(struct WS_sockaddr_in) || !ret_size) + !out_buff || out_size < sizeof(struct WS_sockaddr_in)) { SetLastError(WSAEFAULT); return SOCKET_ERROR; @@ -3816,7 +3816,7 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
if (!status) { - if (ret_size) *ret_size = total; + *ret_size = total; return 0; } SetLastError( status ); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index b5be63d9995..bf8d028611f 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -3705,8 +3705,8 @@ static void test_fionread_siocatmark(void)
WSASetLastError(0xdeadbeef); ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value), NULL, NULL, NULL); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef); size = 0xdeadbeef; @@ -3717,8 +3717,8 @@ static void test_fionread_siocatmark(void)
WSASetLastError(0xdeadbeef); ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value), NULL, NULL, NULL); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef); size = 0xdeadbeef; @@ -3732,12 +3732,12 @@ static void test_fionread_siocatmark(void) port = CreateIoCompletionPort((HANDLE)client, NULL, 123, 0);
ret = WSAIoctl(client, FIONREAD, NULL, 0, &value, sizeof(value), NULL, &overlapped, NULL); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
ret = WSAIoctl(client, SIOCATMARK, NULL, 0, &value, sizeof(value), NULL, &overlapped, NULL); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef); size = 0xdeadbeef; @@ -3857,12 +3857,12 @@ static void test_fionread_siocatmark(void) server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ret = WSAIoctl(server, FIONREAD, NULL, 0, &value, sizeof(value), NULL, &overlapped, socket_apc); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
ret = WSAIoctl(server, SIOCATMARK, NULL, 0, &value, sizeof(value), NULL, &overlapped, socket_apc); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
apc_count = 0; size = 0xdeadbeef; @@ -3920,8 +3920,8 @@ static void test_fionbio(void)
WSASetLastError(0xdeadbeef); ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, NULL, NULL, NULL); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
ret = WSAIoctl(s, FIONBIO, &one, sizeof(one) - 1, NULL, 0, &size, &overlapped, NULL); ok(ret == -1, "expected failure\n"); @@ -3952,7 +3952,7 @@ static void test_fionbio(void) ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, NULL, &overlapped, NULL); - todo_wine ok(ret == -1, "expected failure\n"); + ok(ret == -1, "expected failure\n"); ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
ret = WSAEventSelect(s, event, FD_READ); @@ -3974,8 +3974,8 @@ static void test_fionbio(void) s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ret = WSAIoctl(s, FIONBIO, &one, sizeof(one), NULL, 0, NULL, &overlapped, socket_apc); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
apc_count = 0; size = 0xdeadbeef; @@ -4033,12 +4033,12 @@ static void test_keepalive_vals(void) ok(!size, "got size %u\n", size);
ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, NULL, NULL, NULL); - todo_wine ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, NULL, &overlapped, NULL); - todo_wine ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef); size = 0xdeadbeef; @@ -4093,8 +4093,8 @@ static void test_keepalive_vals(void) sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &kalive, sizeof(kalive), NULL, 0, NULL, &overlapped, socket_apc); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
apc_count = 0; size = 0xdeadbeef; @@ -4135,9 +4135,8 @@ static void test_unsupported_ioctls(void)
WSASetLastError(0xdeadbeef); ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, NULL, &overlapped, NULL); - todo_wine_if (codes[i] == SIO_FLUSH) - ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef); size = 0xdeadbeef; @@ -4182,9 +4181,8 @@ static void test_unsupported_ioctls(void) s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ret = WSAIoctl(s, codes[i], NULL, 0, NULL, 0, NULL, &overlapped, socket_apc); - todo_wine_if (codes[i] == SIO_FLUSH) - ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
apc_count = 0; size = 0xdeadbeef; @@ -4228,8 +4226,8 @@ static void test_get_extension_func(void) WSASetLastError(0xdeadbeef); ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID), &func, sizeof(func), NULL, &overlapped, NULL); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
WSASetLastError(0xdeadbeef); size = 0xdeadbeef; @@ -4269,7 +4267,7 @@ static void test_get_extension_func(void) todo_wine ok(overlapped.InternalHigh == 0xdeadbeef, "got size %Iu\n", overlapped.InternalHigh);
ret = GetQueuedCompletionStatus(port, &size, &key, &overlapped_ptr, 0); - todo_wine ok(!ret, "expected failure\n"); + ok(!ret, "expected failure\n"); todo_wine ok(GetLastError() == WAIT_TIMEOUT, "got error %u\n", WSAGetLastError());
CloseHandle(port); @@ -4279,8 +4277,8 @@ static void test_get_extension_func(void)
ret = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(GUID), &func, sizeof(func), NULL, &overlapped, socket_apc); - todo_wine ok(ret == -1, "expected failure\n"); - todo_wine ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError()); + ok(ret == -1, "expected failure\n"); + ok(WSAGetLastError() == WSAEFAULT, "got error %u\n", WSAGetLastError());
apc_count = 0; size = 0xdeadbeef;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 119 ++++++------------------------------------- 1 file changed, 15 insertions(+), 104 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index b6a14c3e4f4..c1f415444df 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -457,78 +457,6 @@ static void socket_list_remove(SOCKET socket) LeaveCriticalSection(&cs_socket_list); }
-/**************************************************************** - * Async IO declarations - ****************************************************************/ - -typedef NTSTATUS async_callback_t( void *user, IO_STATUS_BLOCK *io, NTSTATUS status ); - -struct ws2_async_io -{ - async_callback_t *callback; /* must be the first field */ - struct ws2_async_io *next; -}; - -struct ws2_async_shutdown -{ - struct ws2_async_io io; - HANDLE hSocket; - IO_STATUS_BLOCK iosb; - int type; -}; - -struct ws2_async -{ - struct ws2_async_io io; - HANDLE hSocket; - LPWSAOVERLAPPED user_overlapped; - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_func; - IO_STATUS_BLOCK local_iosb; - struct WS_sockaddr *addr; - union - { - int val; /* for send operations */ - int *ptr; /* for recv operations */ - } addrlen; - DWORD flags; - DWORD *lpFlags; - WSABUF *control; - unsigned int n_iovecs; - unsigned int first_iovec; - struct iovec iovec[1]; -}; - -static struct ws2_async_io *async_io_freelist; - -static void release_async_io( struct ws2_async_io *io ) -{ - for (;;) - { - struct ws2_async_io *next = async_io_freelist; - io->next = next; - if (InterlockedCompareExchangePointer( (void **)&async_io_freelist, io, next ) == next) return; - } -} - -static struct ws2_async_io *alloc_async_io( DWORD size, async_callback_t callback ) -{ - /* first free remaining previous fileinfos */ - - struct ws2_async_io *io = InterlockedExchangePointer( (void **)&async_io_freelist, NULL ); - - while (io) - { - struct ws2_async_io *next = io->next; - HeapFree( GetProcessHeap(), 0, io ); - io = next; - } - - io = HeapAlloc( GetProcessHeap(), 0, size ); - if (io) io->callback = callback; - return io; -} - - typedef struct /* WSAAsyncSelect() control struct */ { HANDLE service, event, sock; @@ -1727,20 +1655,6 @@ static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, i return TRUE; }
-/************************************************************************** - * Functions for handling overlapped I/O - **************************************************************************/ - -/* user APC called upon async completion */ -static void WINAPI ws2_async_apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved ) -{ - struct ws2_async *wsa = arg; - - if (wsa->completion_func) wsa->completion_func( NtStatusToWSAError(iosb->u.Status), - iosb->Information, wsa->user_overlapped, - wsa->flags ); - release_async_io( &wsa->io ); -}
/*********************************************************************** @@ -3283,29 +3197,28 @@ static DWORD server_ioctl_sock( SOCKET s, DWORD code, LPVOID in_buff, DWORD in_s LPWSAOVERLAPPED overlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE completion ) { - HANDLE event = overlapped ? overlapped->hEvent : 0; + IO_STATUS_BLOCK iosb, *piosb = &iosb; HANDLE handle = SOCKET2HANDLE( s ); - struct ws2_async *wsa = NULL; - IO_STATUS_BLOCK *io = (PIO_STATUS_BLOCK)overlapped, iosb; + PIO_APC_ROUTINE apc = NULL; + HANDLE event = NULL; void *cvalue = NULL; NTSTATUS status;
+ if (overlapped) + { + piosb = (IO_STATUS_BLOCK *)overlapped; + if (!((ULONG_PTR)overlapped->hEvent & 1)) cvalue = overlapped; + event = overlapped->hEvent; + } + if (completion) { - if (!(wsa = (struct ws2_async *)alloc_async_io( sizeof(*wsa), NULL ))) - return WSA_NOT_ENOUGH_MEMORY; - wsa->hSocket = handle; - wsa->user_overlapped = overlapped; - wsa->completion_func = completion; - if (!io) io = &wsa->local_iosb; - cvalue = wsa; + event = NULL; + cvalue = completion; + apc = socket_apc; } - else if (!io) - io = &iosb; - else if (!((ULONG_PTR)overlapped->hEvent & 1)) - cvalue = overlapped;
- status = NtDeviceIoControlFile( handle, event, wsa ? ws2_async_apc : NULL, cvalue, io, code, + status = NtDeviceIoControlFile( handle, event, apc, cvalue, piosb, code, in_buff, in_size, out_buff, out_size ); if (status == STATUS_NOT_SUPPORTED) { @@ -3313,9 +3226,7 @@ static DWORD server_ioctl_sock( SOCKET s, DWORD code, LPVOID in_buff, DWORD in_s code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3); } else if (status == STATUS_SUCCESS) - *ret_size = io->Information; /* "Information" is the size written to the output buffer */ - - if (status != STATUS_PENDING) RtlFreeHeap( GetProcessHeap(), 0, wsa ); + *ret_size = piosb->Information;
return NtStatusToWSAError( status ); }
This reverts commit 8b8ddffa2152832908ced42191fa19dcb64d900e.
ws2_32 no longer uses system APCs.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/unix/server.c | 15 --------------- dlls/ntdll/unix/signal_arm.c | 9 --------- dlls/ntdll/unix/signal_arm64.c | 10 ---------- dlls/ntdll/unix/signal_i386.c | 12 +----------- dlls/ntdll/unix/signal_x86_64.c | 11 +---------- dlls/ntdll/unix/unix_private.h | 3 --- 6 files changed, 2 insertions(+), 58 deletions(-)
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index c0cf13b3cb4..cec2ef250a3 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -379,24 +379,9 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO { IO_STATUS_BLOCK *iosb = wine_server_get_ptr( call->async_io.sb ); struct async_fileio *user = wine_server_get_ptr( call->async_io.user ); - void *saved_frame = get_syscall_frame(); - void *frame;
result->type = call->type; result->async_io.status = user->callback( user, iosb, call->async_io.status ); - - if ((frame = get_syscall_frame()) != saved_frame) - { - /* The frame can be altered by syscalls from ws2_32 async callbacks - * which are currently in the user part. */ - static unsigned int once; - - if (!once++) - FIXME( "syscall frame changed in APC function, frame %p, saved_frame %p.\n", frame, saved_frame ); - - set_syscall_frame( saved_frame ); - } - if (result->async_io.status != STATUS_PENDING) result->async_io.total = iosb->Information; break; diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 11b6aa8d0ad..8ecdaa3995b 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -201,15 +201,6 @@ static inline struct arm_thread_data *arm_thread_data(void) return (struct arm_thread_data *)ntdll_get_thread_data()->cpu_data; }
-void *get_syscall_frame(void) -{ - return arm_thread_data()->syscall_frame; -} - -void set_syscall_frame(void *frame) -{ - arm_thread_data()->syscall_frame = frame; -}
/*********************************************************************** * unwind_builtin_dll diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index 2359b1838d6..e696ba41a66 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -157,16 +157,6 @@ static inline struct arm64_thread_data *arm64_thread_data(void) return (struct arm64_thread_data *)ntdll_get_thread_data()->cpu_data; }
-void *get_syscall_frame(void) -{ - return arm64_thread_data()->syscall_frame; -} - -void set_syscall_frame(void *frame) -{ - arm64_thread_data()->syscall_frame = frame; -} - extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, void *dispatcher );
/*********************************************************************** diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 87024e1bfce..707e965d8b3 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -527,16 +527,6 @@ static inline struct x86_thread_data *x86_thread_data(void) return (struct x86_thread_data *)ntdll_get_thread_data()->cpu_data; }
-void *get_syscall_frame(void) -{ - return x86_thread_data()->syscall_frame; -} - -void set_syscall_frame(void *frame) -{ - x86_thread_data()->syscall_frame = frame; -} - static struct syscall_xsave *get_syscall_xsave( struct syscall_frame *frame ) { return (struct syscall_xsave *)((ULONG_PTR)((struct syscall_xsave *)frame - 1) & ~63); @@ -973,7 +963,7 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context, */ void signal_restore_full_cpu_context(void) { - struct syscall_xsave *xsave = get_syscall_xsave( get_syscall_frame() ); + struct syscall_xsave *xsave = get_syscall_xsave( x86_thread_data()->syscall_frame );
if (cpu_info.ProcessorFeatureBits & CPU_FEATURE_XSAVE) { diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index dcb0e588c66..1ab991d3cb5 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -327,15 +327,6 @@ static inline struct amd64_thread_data *amd64_thread_data(void) return (struct amd64_thread_data *)ntdll_get_thread_data()->cpu_data; }
-void *get_syscall_frame(void) -{ - return amd64_thread_data()->syscall_frame; -} - -void set_syscall_frame(void *frame) -{ - amd64_thread_data()->syscall_frame = frame; -}
static struct syscall_xsave *get_syscall_xsave( struct syscall_frame *frame ) { @@ -1598,7 +1589,7 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context, */ void signal_restore_full_cpu_context(void) { - struct syscall_xsave *xsave = get_syscall_xsave( get_syscall_frame() ); + struct syscall_xsave *xsave = get_syscall_xsave( amd64_thread_data()->syscall_frame );
if (cpu_info.ProcessorFeatureBits & CPU_FEATURE_XSAVE) { diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index f28d5cf4e99..5b9af322a68 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -290,9 +290,6 @@ extern void WINAPI DECLSPEC_NORETURN call_user_exception_dispatcher( EXCEPTION_R NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) DECLSPEC_HIDDEN; extern void WINAPI call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) DECLSPEC_HIDDEN;
-extern void *get_syscall_frame(void) DECLSPEC_HIDDEN; -extern void set_syscall_frame(void *frame) DECLSPEC_HIDDEN; - #define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */
#define TICKSPERSEC 10000000