Erich E. Hoover : ws2_32: Ask the server to process unsupported WSAIoctl operations.

Alexandre Julliard julliard at winehq.org
Fri Mar 28 14:13:35 CDT 2014


Module: wine
Branch: master
Commit: 5963d7f09c0b83e01dec6787dd0aceb6ee610d81
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5963d7f09c0b83e01dec6787dd0aceb6ee610d81

Author: Erich E. Hoover <erich.e.hoover at gmail.com>
Date:   Tue Mar 18 19:45:17 2014 +0100

ws2_32: Ask the server to process unsupported WSAIoctl operations.

---

 dlls/ws2_32/socket.c |   60 ++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 53 insertions(+), 7 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index cdcbb11..fe85356 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -3673,6 +3673,40 @@ static const char *debugstr_wsaioctl(DWORD ioctl)
                             (USHORT)(ioctl & 0xffff));
 }
 
+/* do an ioctl call through the server */
+static DWORD server_ioctl_sock( SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size,
+                                LPVOID out_buff, DWORD out_size, LPDWORD ret_size,
+                                LPWSAOVERLAPPED overlapped,
+                                LPWSAOVERLAPPED_COMPLETION_ROUTINE completion )
+{
+    HANDLE event = overlapped ? overlapped->hEvent : 0;
+    HANDLE handle = SOCKET2HANDLE( s );
+    struct ws2_async *wsa;
+    NTSTATUS status;
+    PIO_STATUS_BLOCK io;
+
+    if (!(wsa = RtlAllocateHeap( GetProcessHeap(), 0, 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);
+
+    status = NtDeviceIoControlFile( handle, event, (PIO_APC_ROUTINE)ws2_async_apc, wsa, io, code,
+                                    in_buff, in_size, out_buff, out_size );
+    if (status == STATUS_NOT_SUPPORTED)
+    {
+        FIXME("Unsupported ioctl %x (device=%x access=%x func=%x method=%x)\n",
+              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 );
+
+    return NtStatusToWSAError( status );
+}
+
 /**********************************************************************
  *              WSAIoctl                (WS2_32.50)
  *
@@ -3865,12 +3899,6 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
            break;
        }
 
-   case WS_SIO_ADDRESS_LIST_CHANGE:
-       FIXME("-> SIO_ADDRESS_LIST_CHANGE request: stub\n");
-       /* FIXME: error and return code depend on whether socket was created
-        * with WSA_FLAG_OVERLAPPED, but there is no easy way to get this */
-       break;
-
    case WS_SIO_ADDRESS_LIST_QUERY:
    {
         DWORD size;
@@ -4106,11 +4134,29 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
         WSASetLastError(WSAEOPNOTSUPP);
         return SOCKET_ERROR;
     default:
-        FIXME("unsupported WS_IOCTL cmd (%s)\n", debugstr_wsaioctl(code));
         status = WSAEOPNOTSUPP;
         break;
     }
 
+    if (status == WSAEOPNOTSUPP)
+    {
+        status = server_ioctl_sock(s, code, in_buff, in_size, out_buff, out_size, &total,
+                                   overlapped, completion);
+        if (status != WSAEOPNOTSUPP)
+        {
+            if (status == 0 || status == WSA_IO_PENDING)
+                TRACE("-> %s request\n", debugstr_wsaioctl(code));
+            else
+                ERR("-> %s request failed with status 0x%x\n", debugstr_wsaioctl(code), status);
+
+            /* overlapped and completion operations will be handled by the server */
+            completion = NULL;
+            overlapped = NULL;
+        }
+        else
+            FIXME("unsupported WS_IOCTL cmd (%s)\n", debugstr_wsaioctl(code));
+    }
+
     if (completion)
     {
         FIXME( "completion routine %p not supported\n", completion );




More information about the wine-cvs mailing list