Jacek Caban : ws2_32: Pass completion routing to NtDeviceIoControlFile in server_ioctl_sock only if caller provided completion routine.
Alexandre Julliard
julliard at winehq.org
Thu Oct 13 14:34:02 CDT 2016
Module: wine
Branch: master
Commit: 93863d25fc32a6229590e3b97a9d12e1a94676d5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=93863d25fc32a6229590e3b97a9d12e1a94676d5
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Oct 12 17:11:34 2016 +0200
ws2_32: Pass completion routing to NtDeviceIoControlFile in server_ioctl_sock only if caller provided completion routine.
Otherwise we're always doing non-blocking calls, preventing server from
doing the right thing (and in actually doing the opposite in
WS_SIO_ADDRESS_LIST_CHANGE case).
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ws2_32/socket.c | 27 ++++++++++++++++++---------
dlls/ws2_32/tests/sock.c | 2 --
server/sock.c | 2 +-
3 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index e3c7507..e8c5130 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -4520,18 +4520,27 @@ static DWORD server_ioctl_sock( SOCKET s, DWORD code, LPVOID in_buff, DWORD in_s
{
HANDLE event = overlapped ? overlapped->hEvent : 0;
HANDLE handle = SOCKET2HANDLE( s );
- struct ws2_async *wsa;
+ struct ws2_async *wsa = NULL;
+ IO_STATUS_BLOCK *io = (PIO_STATUS_BLOCK)overlapped, iosb;
+ void *cvalue = NULL;
NTSTATUS status;
- PIO_STATUS_BLOCK io;
- if (!(wsa = (struct ws2_async *)alloc_async_io( sizeof(*wsa) )))
- return WSA_NOT_ENOUGH_MEMORY;
- wsa->hSocket = handle;
- wsa->user_overlapped = overlapped;
- wsa->completion_func = completion;
- io = (overlapped ? (PIO_STATUS_BLOCK)overlapped : &wsa->local_iosb);
+ if (completion)
+ {
+ if (!(wsa = (struct ws2_async *)alloc_async_io( sizeof(*wsa) )))
+ return WSA_NOT_ENOUGH_MEMORY;
+ wsa->hSocket = handle;
+ wsa->user_overlapped = overlapped;
+ wsa->completion_func = completion;
+ if (!io) io = &wsa->local_iosb;
+ cvalue = wsa;
+ }
+ else if (!io)
+ io = &iosb;
+ else if (!((ULONG_PTR)overlapped->hEvent & 1))
+ cvalue = overlapped;
- status = NtDeviceIoControlFile( handle, event, ws2_async_apc, wsa, io, code,
+ status = NtDeviceIoControlFile( handle, event, wsa ? ws2_async_apc : NULL, cvalue, io, code,
in_buff, in_size, out_buff, out_size );
if (status == STATUS_NOT_SUPPORTED)
{
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 320f820..b7aaea3 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -8387,7 +8387,6 @@ static void test_sioAddressListChange(void)
ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
error = GetLastError();
ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %d\n", error);
-todo_wine
ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%x\n", error);
CloseHandle(overlapped.hEvent);
@@ -8426,7 +8425,6 @@ todo_wine
ret = WSAIoctl(sock, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &num_bytes, &overlapped, NULL);
error = GetLastError();
ok (ret == SOCKET_ERROR, "WSAIoctl(SIO_ADDRESS_LIST_CHANGE) failed with error %d\n", error);
-todo_wine
ok (error == ERROR_IO_PENDING, "expected 0x3e5, got 0x%x\n", error);
CloseHandle(overlapped.hEvent);
diff --git a/server/sock.c b/server/sock.c
index 89049e0..d7349fc 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -548,7 +548,7 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
switch(code)
{
case WS_SIO_ADDRESS_LIST_CHANGE:
- if ((sock->state & FD_WINE_NONBLOCKING) && !blocking)
+ if ((sock->state & FD_WINE_NONBLOCKING) && blocking)
{
set_error( STATUS_CANT_WAIT );
return 0;
More information about the wine-cvs
mailing list