mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
kernel32-SetFileCompletionNotificationModes: Fix a corner-case related to AcceptEx (thanks Jacek).
This commit is contained in:
parent
2420bc89ed
commit
be0d43d2b1
@ -0,0 +1,125 @@
|
||||
From 2289d4a4f8a8085bd6fd4eebee829ee22df8abc5 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Wed, 14 Jun 2017 14:47:33 +0200
|
||||
Subject: ws2_32: Don't skip completion in AcceptEx.
|
||||
|
||||
Spotted by Jacek Caban.
|
||||
|
||||
FIXME: It would be better to get rid of the STATUS_MORE_PROCESSING_REQUIRED handling.
|
||||
---
|
||||
dlls/ws2_32/socket.c | 13 +++++++------
|
||||
dlls/ws2_32/tests/sock.c | 5 +++++
|
||||
server/fd.c | 2 +-
|
||||
server/protocol.def | 1 +
|
||||
4 files changed, 14 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
|
||||
index 886ff82dba9..0340547dce0 100644
|
||||
--- a/dlls/ws2_32/socket.c
|
||||
+++ b/dlls/ws2_32/socket.c
|
||||
@@ -654,7 +654,7 @@ static int ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, in
|
||||
int WSAIOCTL_GetInterfaceCount(void);
|
||||
int WSAIOCTL_GetInterfaceName(int intNumber, char *intName);
|
||||
|
||||
-static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus, ULONG Information );
|
||||
+static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus, ULONG Information, BOOL force );
|
||||
|
||||
#define MAP_OPTION(opt) { WS_##opt, opt }
|
||||
|
||||
@@ -2510,7 +2510,7 @@ static NTSTATUS WS2_async_accept_recv( void *user, IO_STATUS_BLOCK *iosb, NTSTAT
|
||||
return status;
|
||||
|
||||
if (wsa->cvalue)
|
||||
- WS_AddCompletion( HANDLE2SOCKET(wsa->listen_socket), wsa->cvalue, iosb->u.Status, iosb->Information );
|
||||
+ WS_AddCompletion( HANDLE2SOCKET(wsa->listen_socket), wsa->cvalue, iosb->u.Status, iosb->Information, TRUE );
|
||||
|
||||
release_async_io( &wsa->io );
|
||||
return status;
|
||||
@@ -5139,7 +5139,7 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
|
||||
overlapped->Internal = status;
|
||||
overlapped->InternalHigh = total;
|
||||
if (overlapped->hEvent) NtSetEvent( overlapped->hEvent, NULL );
|
||||
- if (cvalue) WS_AddCompletion( HANDLE2SOCKET(s), cvalue, status, total );
|
||||
+ if (cvalue) WS_AddCompletion( HANDLE2SOCKET(s), cvalue, status, total, FALSE );
|
||||
}
|
||||
|
||||
if (!status)
|
||||
@@ -5534,7 +5534,7 @@ int WINAPI WSAPoll(WSAPOLLFD *wfds, ULONG count, int timeout)
|
||||
|
||||
/* helper to send completion messages for client-only i/o operation case */
|
||||
static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus,
|
||||
- ULONG Information )
|
||||
+ ULONG Information, BOOL force )
|
||||
{
|
||||
SERVER_START_REQ( add_fd_completion )
|
||||
{
|
||||
@@ -5542,6 +5542,7 @@ static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS C
|
||||
req->cvalue = CompletionValue;
|
||||
req->status = CompletionStatus;
|
||||
req->information = Information;
|
||||
+ req->force = force;
|
||||
wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
@@ -5686,7 +5687,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||
if (lpNumberOfBytesSent) *lpNumberOfBytesSent = n;
|
||||
if (!wsa->completion_func)
|
||||
{
|
||||
- if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n );
|
||||
+ if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n, FALSE );
|
||||
if (lpOverlapped->hEvent) SetEvent( lpOverlapped->hEvent );
|
||||
HeapFree( GetProcessHeap(), 0, wsa );
|
||||
}
|
||||
@@ -7888,7 +7889,7 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
|
||||
iosb->Information = n;
|
||||
if (!wsa->completion_func)
|
||||
{
|
||||
- if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n );
|
||||
+ if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n, FALSE );
|
||||
if (lpOverlapped->hEvent) SetEvent( lpOverlapped->hEvent );
|
||||
HeapFree( GetProcessHeap(), 0, wsa );
|
||||
}
|
||||
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
|
||||
index acbec940954..c7f0c01112a 100644
|
||||
--- a/dlls/ws2_32/tests/sock.c
|
||||
+++ b/dlls/ws2_32/tests/sock.c
|
||||
@@ -9939,6 +9939,11 @@ static void test_completion_port(void)
|
||||
ok(io_port != NULL, "failed to create completion port %u\n", GetLastError());
|
||||
|
||||
io_info.Flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS;
|
||||
+ status = pNtSetInformationFile((HANDLE)src, &io, &io_info, sizeof(io_info), FileIoCompletionNotificationInformation);
|
||||
+ ok(status == STATUS_SUCCESS || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */,
|
||||
+ "expected STATUS_SUCCESS, got %08x\n", status);
|
||||
+
|
||||
+ io_info.Flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS;
|
||||
status = pNtSetInformationFile((HANDLE)dest, &io, &io_info, sizeof(io_info), FileIoCompletionNotificationInformation);
|
||||
ok(status == STATUS_SUCCESS || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */,
|
||||
"expected STATUS_SUCCESS, got %08x\n", status);
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index 1b82bd30860..94febea990b 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2704,7 +2704,7 @@ DECL_HANDLER(add_fd_completion)
|
||||
struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
|
||||
if (fd)
|
||||
{
|
||||
- if (fd->completion && (!(fd->comp_flags & COMPLETION_SKIP_ON_SUCCESS) || req->status))
|
||||
+ if (fd->completion && (!(fd->comp_flags & COMPLETION_SKIP_ON_SUCCESS) || req->status || req->force))
|
||||
add_completion( fd->completion, fd->comp_key, req->cvalue, req->status, req->information );
|
||||
release_object( fd );
|
||||
}
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 3912908e519..ba047d5581c 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -3725,6 +3725,7 @@ struct handle_info
|
||||
apc_param_t cvalue; /* completion value */
|
||||
apc_param_t information; /* IO_STATUS_BLOCK Information */
|
||||
unsigned int status; /* completion status */
|
||||
+ int force; /* don't check if skip-on-success is set */
|
||||
@END
|
||||
|
||||
|
||||
--
|
||||
2.13.1
|
||||
|
@ -5088,8 +5088,8 @@ fi
|
||||
# | * [#38960] Add support for kernel32.SetFileCompletionNotificationModes
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/file.c, dlls/ntdll/file.c, dlls/ntdll/tests/file.c, dlls/ntdll/tests/pipe.c, dlls/ws2_32/tests/sock.c,
|
||||
# | server/async.c, server/fd.c, server/file.h, server/protocol.def
|
||||
# | * dlls/kernel32/file.c, dlls/ntdll/file.c, dlls/ntdll/tests/file.c, dlls/ntdll/tests/pipe.c, dlls/ws2_32/socket.c,
|
||||
# | dlls/ws2_32/tests/sock.c, server/async.c, server/fd.c, server/file.h, server/protocol.def
|
||||
# |
|
||||
if test "$enable_kernel32_SetFileCompletionNotificationModes" -eq 1; then
|
||||
patch_apply kernel32-SetFileCompletionNotificationModes/0001-ntdll-Implement-FileIoCompletionNotificationInformat.patch
|
||||
@ -5098,6 +5098,7 @@ if test "$enable_kernel32_SetFileCompletionNotificationModes" -eq 1; then
|
||||
patch_apply kernel32-SetFileCompletionNotificationModes/0004-ntdll-tests-Add-more-tests-for-FileIoCompletionNotif.patch
|
||||
patch_apply kernel32-SetFileCompletionNotificationModes/0005-ntdll-Do-not-require-unix-fd-for-FileIoCompletionNot.patch
|
||||
patch_apply kernel32-SetFileCompletionNotificationModes/0006-server-Skip-async-completion-when-possible.patch
|
||||
patch_apply kernel32-SetFileCompletionNotificationModes/0007-ws2_32-Don-t-skip-completion-in-AcceptEx.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Implement FileIoCompletionNotificationInformation info class.", 2 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Allow to query file IO completion notification mode.", 1 },';
|
||||
@ -5105,6 +5106,7 @@ if test "$enable_kernel32_SetFileCompletionNotificationModes" -eq 1; then
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "ntdll/tests: Add more tests for FileIoCompletionNotificationInformation.", 1 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Do not require unix fd for FileIoCompletionNotificationInformation.", 1 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "server: Skip async completion when possible.", 1 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "ws2_32: Don'\''t skip completion in AcceptEx.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user