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