From: "Erich E. Hoover" Subject: [PATCH 1/3] ws2_32: Ask the server to process unsupported WSAIoctl operations (resend). Message-Id: Date: Tue, 12 Nov 2013 10:50:03 -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 for scrutinizing these patches and my apologies to everyone for taking so long to submit this again. 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 177b753cb5e4f0c29d94e1ac969f052cbfb8b209 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 4 Oct 2013 08:10:20 -0600 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