From: "Erich E. Hoover" Subject: [PATCH 1/3] ws2_32: Ask the server to process unsupported WSAIoctl operations (resend 2). Message-Id: Date: Wed, 20 Nov 2013 15:07:44 -0700 As some of you know I've been working on fixing SIO_ADDRESS_LIST_CHANGE in order to fix some problems with Silverlight on a variety of streaming sites. Due to some feedback I've received I've gone to the effort to completely revise these patches to work inside of the server instead of using iphlpapi. Since I haven't heard back from my RFC I'm hoping that everyone is happy with what I've done here. Also, special thanks go to Sebastian Lackner and André Hentschel for scrutinizing these patches. This particular patch allows unsupported WSAIoctl() calls to be processed by the server, permitting SIO_ADDRESS_LIST_CHANGE calls to be handled there (part 2). The patch was modeled after similar behavior for unimplemented ioctl() calls in ntdll. From 4efefa82fb7b767e503028b7dc73da786446ae9a Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Mon, 18 Nov 2013 17:21:49 -0700 Subject: ws2_32: Ask the server to process unsupported WSAIoctl operations. --- dlls/ws2_32/socket.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 679258b..44a9093 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3608,6 +3608,36 @@ 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); + + if (status != STATUS_PENDING) RtlFreeHeap( GetProcessHeap(), 0, wsa ); + + return NtStatusToWSAError( status ); +} + /********************************************************************** * WSAIoctl (WS2_32.50) * @@ -3800,9 +3830,8 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID } 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 */ + TRACE("-> SIO_ADDRESS_LIST_CHANGE request\n"); + status = WSAEOPNOTSUPP; /* this operation needs to be handled by the server */ break; case WS_SIO_ADDRESS_LIST_QUERY: @@ -4045,6 +4074,18 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID break; } + if (status == WSAEOPNOTSUPP) + { + status = server_ioctl_sock(s, code, in_buff, in_size, out_buff, out_size, ret_size, + overlapped, completion); + if (status != WSAEOPNOTSUPP) + { + /* overlapped and completion operations will be handled by the server */ + completion = NULL; + overlapped = NULL; + } + } + if (completion) { FIXME( "completion routine %p not supported\n", completion ); -- 1.7.9.5