From: "Erich E. Hoover" Subject: [PATCH 1/1] ws2_32: Revise AcceptEx behavior to send completions for canceled sockets (resend, deferred). Message-Id: Date: Wed, 7 Mar 2012 15:31:08 -0700 Real Name: Erich Hoover Description: This patch changes how AcceptEx and the wine server use completions so that canceled sockets still send completion notifications. The patch fixes a significant issue with the WoW launcher and the Diablo 3 installer (fixes Bug #27657 and partially fixes Bug #28898). Changelog: ws2_32: Revise AcceptEx behavior to send completions for canceled sockets. From 9914dc08caf0a31746be533a82de302f398948d2 Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Wed, 7 Mar 2012 15:28:39 -0700 Subject: ws2_32: Revise AcceptEx behavior to send completions for canceled sockets. --- dlls/ws2_32/socket.c | 8 ++++---- server/async.c | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index d3a4590..dd818f2 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1700,7 +1700,7 @@ static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS sta if (status != STATUS_PENDING) goto finish; - return STATUS_SUCCESS; + return STATUS_ALERTED; finish: iosb->u.Status = status; @@ -1708,8 +1708,6 @@ finish: if (wsa->user_overlapped->hEvent) SetEvent(wsa->user_overlapped->hEvent); - if (wsa->cvalue) - WS_AddCompletion( HANDLE2SOCKET(wsa->listen_socket), wsa->cvalue, iosb->u.Status, iosb->Information ); *apc = ws2_async_accept_apc; return status; @@ -2040,7 +2038,9 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW req->async.callback = wine_server_client_ptr( WS2_async_accept ); req->async.iosb = wine_server_client_ptr( overlapped ); req->async.arg = wine_server_client_ptr( wsa ); - /* We don't set event or completion since we may also have to read */ + req->async.cvalue = cvalue; + /* We don't set event since we may also have to read, completion returns STATUS_ALERTED + * to indicate that no completion should be queued. */ status = wine_server_call( req ); } SERVER_END_REQ; diff --git a/server/async.c b/server/async.c index dd28dff..b8be5cd 100644 --- a/server/async.c +++ b/server/async.c @@ -256,10 +256,12 @@ void async_set_result( struct object *obj, unsigned int status, unsigned int tot else { if (async->timeout) remove_timeout_user( async->timeout ); + if (async->completion && async->data.cvalue && status != STATUS_ALERTED) + add_completion( async->completion, async->comp_key, async->data.cvalue, status, total ); + else if (async->completion && async->data.cvalue && status == STATUS_ALERTED) + status = STATUS_SUCCESS; async->timeout = NULL; async->status = status; - if (async->completion && async->data.cvalue) - add_completion( async->completion, async->comp_key, async->data.cvalue, status, total ); if (apc) { apc_call_t data; -- 1.7.5.4