kernel32-SetFileCompletionNotificationModes: Update patchset for server-side named pipes.

This commit is contained in:
Sebastian Lackner 2017-04-09 03:21:23 +02:00
parent 8568fe0a24
commit c372796653
5 changed files with 301 additions and 16 deletions

View File

@ -0,0 +1,105 @@
From 6a640e583277b35e4dd1ba2edffb45c379e4fd7e Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 9 Apr 2017 01:58:49 +0200
Subject: ntdll/tests: Add more tests for
FileIoCompletionNotificationInformation.
---
dlls/ntdll/tests/pipe.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index e242cb4c0f..fa0ca2da00 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -331,6 +331,77 @@ static void test_overlapped(void)
CloseHandle(hEvent);
}
+static void test_completion(void)
+{
+ static const char buf[] = "testdata";
+ FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info;
+ HANDLE port, pipe, client;
+ IO_STATUS_BLOCK iosb;
+ OVERLAPPED ov, *pov;
+ IO_STATUS_BLOCK io;
+ NTSTATUS status;
+ DWORD num_bytes;
+ ULONG_PTR key;
+ DWORD dwret;
+ BOOL ret;
+
+ memset(&ov, 0, sizeof(ov));
+ ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
+ ok(ov.hEvent != INVALID_HANDLE_VALUE, "CreateEvent failed, error %u\n", GetLastError());
+
+ status = create_pipe(&pipe, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */);
+ ok(!status, "NtCreateNamedPipeFile returned %x\n", status);
+ status = listen_pipe(pipe, ov.hEvent, &iosb, FALSE);
+ ok(status == STATUS_PENDING, "NtFsControlFile returned %x\n", status);
+
+ client = CreateFileW(testpipe, GENERIC_READ | GENERIC_WRITE, 0, 0,
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+ ok(client != INVALID_HANDLE_VALUE, "CreateFile failed, error %u\n", GetLastError());
+ dwret = WaitForSingleObject(ov.hEvent, 0);
+ ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", dwret);
+
+ port = CreateIoCompletionPort(client, NULL, 0xdeadbeef, 0);
+ ok(port != NULL, "CreateIoCompletionPort failed, error %u\n", GetLastError());
+
+ ret = WriteFile(client, buf, sizeof(buf), &num_bytes, &ov);
+ ok(ret, "WriteFile failed, error %u\n", GetLastError());
+ ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %u\n", num_bytes);
+
+ key = 0;
+ pov = NULL;
+ ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
+ ok(ret, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
+ ok(key == 0xdeadbeef, "expected 0xdeadbeef, got %lx\n", key);
+ ok(pov == &ov, "expected %p, got %p\n", &ov, pov);
+
+ info.Flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS;
+ status = pNtSetInformationFile(client, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+
+ info.Flags = 0;
+ status = pNtQueryInformationFile(client, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+ todo_wine
+ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+ todo_wine
+ ok((info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) != 0, "got %08x\n", info.Flags);
+
+ ret = WriteFile(client, buf, sizeof(buf), &num_bytes, &ov);
+ ok(ret, "WriteFile failed, error %u\n", GetLastError());
+ ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %u\n", num_bytes);
+
+ pov = (void *)0xdeadbeef;
+ ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
+ todo_wine
+ ok(!ret, "GetQueuedCompletionStatus succeeded\n");
+ todo_wine
+ ok(pov == NULL, "expected NULL, got %p\n", pov);
+
+ CloseHandle(ov.hEvent);
+ CloseHandle(client);
+ CloseHandle(pipe);
+ CloseHandle(port);
+}
+
static BOOL userapc_called;
static void CALLBACK userapc(ULONG_PTR dwParam)
{
@@ -1086,6 +1157,9 @@ START_TEST(pipe)
trace("starting overlapped tests\n");
test_overlapped();
+ trace("starting completion tests\n");
+ test_completion();
+
trace("starting FILE_PIPE_INFORMATION tests\n");
test_filepipeinfo();
--
2.11.0

View File

@ -0,0 +1,42 @@
From 652431398236beda32c5d3239451dbc46fbf1937 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 9 Apr 2017 02:01:25 +0200
Subject: ntdll: Do not require unix fd for
FileIoCompletionNotificationInformation.
---
dlls/ntdll/file.c | 3 ++-
dlls/ntdll/tests/pipe.c | 2 --
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 4e6051a42d..5e21ecc662 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -2440,7 +2440,8 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
if (len < info_sizes[class])
return io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
- if (class != FilePipeInformation && class != FilePipeLocalInformation)
+ if (class != FilePipeInformation && class != FilePipeLocalInformation &&
+ class != FileIoCompletionNotificationInformation)
{
if ((io->u.Status = server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL, NULL )))
{
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index fa0ca2da00..013eb2b39f 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -380,9 +380,7 @@ static void test_completion(void)
info.Flags = 0;
status = pNtQueryInformationFile(client, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
- todo_wine
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
- todo_wine
ok((info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) != 0, "got %08x\n", info.Flags);
ret = WriteFile(client, buf, sizeof(buf), &num_bytes, &ov);
--
2.11.0

View File

@ -0,0 +1,121 @@
From 714b2b8a22566f7c6c0d92ed74bd9886062fb16e Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 9 Apr 2017 03:13:25 +0200
Subject: server: Skip async completion when possible.
---
dlls/ntdll/tests/pipe.c | 2 --
server/async.c | 12 +++++++++++-
server/fd.c | 4 ++++
server/file.h | 1 +
4 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index 013eb2b39f..631013c755 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -389,9 +389,7 @@ static void test_completion(void)
pov = (void *)0xdeadbeef;
ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
- todo_wine
ok(!ret, "GetQueuedCompletionStatus succeeded\n");
- todo_wine
ok(pov == NULL, "expected NULL, got %p\n", pov);
CloseHandle(ov.hEvent);
diff --git a/server/async.c b/server/async.c
index e113681bb0..5a64565d5f 100644
--- a/server/async.c
+++ b/server/async.c
@@ -45,6 +45,7 @@ struct async
struct timeout_user *timeout;
unsigned int timeout_status; /* status to report upon timeout */
int signaled;
+ int skip_completion; /* skip completion */
struct event *event;
async_data_t data; /* data for async I/O call */
struct iosb *iosb; /* I/O status block */
@@ -165,6 +166,14 @@ static void async_queue_destroy( struct object *obj )
if (async_queue->completion) release_object( async_queue->completion );
}
+void async_skip_completion( struct async *async, int comp_flags )
+{
+ if (!async->data.callback) return;
+ if (!(comp_flags & COMPLETION_SKIP_ON_SUCCESS)) return;
+ async->skip_completion = (async->status == STATUS_SUCCESS ||
+ async->status == STATUS_ALERTED);
+}
+
/* notifies client thread of new status of its async request */
void async_terminate( struct async *async, unsigned int status )
{
@@ -263,6 +272,7 @@ struct async *create_async( struct thread *thread, const async_data_t *data, str
async->timeout = NULL;
async->queue = NULL;
async->signaled = 0;
+ async->skip_completion = 0;
if (iosb) async->iosb = (struct iosb *)grab_object( iosb );
else async->iosb = NULL;
@@ -328,7 +338,7 @@ void async_set_result( struct object *obj, unsigned int status, apc_param_t tota
async->status = status;
if (status == STATUS_MORE_PROCESSING_REQUIRED) return; /* don't report the completion */
- if (async->queue && async->data.cvalue)
+ if (async->queue && async->data.cvalue && !async->skip_completion)
add_async_completion( async->queue, async->data.cvalue, status, total );
if (apc)
{
diff --git a/server/fd.c b/server/fd.c
index 9617fa1279..e0c2ee4f26 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2381,6 +2381,7 @@ DECL_HANDLER(flush)
if (async)
{
reply->event = fd->fd_ops->flush( fd, async, req->blocking );
+ async_skip_completion( async, fd->comp_flags );
release_object( async );
}
release_object( fd );
@@ -2461,6 +2462,7 @@ DECL_HANDLER(read)
{
reply->wait = fd->fd_ops->read( fd, async, req->blocking, req->pos );
reply->options = fd->options;
+ async_skip_completion( async, fd->comp_flags );
release_object( async );
}
release_object( iosb );
@@ -2484,6 +2486,7 @@ DECL_HANDLER(write)
{
reply->wait = fd->fd_ops->write( fd, async, req->blocking, req->pos );
reply->options = fd->options;
+ async_skip_completion( async, fd->comp_flags );
release_object( async );
}
release_object( iosb );
@@ -2507,6 +2510,7 @@ DECL_HANDLER(ioctl)
{
reply->wait = fd->fd_ops->ioctl( fd, req->code, async, req->blocking );
reply->options = fd->options;
+ async_skip_completion( async, fd->comp_flags );
release_object( async );
}
release_object( iosb );
diff --git a/server/file.h b/server/file.h
index 398733c460..19bc3cbfe4 100644
--- a/server/file.h
+++ b/server/file.h
@@ -182,6 +182,7 @@ extern void async_set_result( struct object *obj, unsigned int status,
apc_param_t total, client_ptr_t apc, client_ptr_t apc_arg );
extern int async_queued( struct async_queue *queue );
extern int async_waiting( struct async_queue *queue );
+extern void async_skip_completion( struct async *async, int comp_flags );
extern void async_terminate( struct async *async, unsigned int status );
extern void async_wake_up( struct async_queue *queue, unsigned int status );
extern struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key );
--
2.11.0

View File

@ -1 +1,2 @@
Fixes: [38960] Add support for kernel32.SetFileCompletionNotificationModes
Depends: ntdll-FileNameInformation

View File

@ -2407,6 +2407,13 @@ if test "$enable_ntdll_CLI_Images" -eq 1; then
enable_mscoree_CorValidateImage=1
fi
if test "$enable_kernel32_SetFileCompletionNotificationModes" -eq 1; then
if test "$enable_ntdll_FileNameInformation" -gt 1; then
abort "Patchset ntdll-FileNameInformation disabled, but kernel32-SetFileCompletionNotificationModes depends on that."
fi
enable_ntdll_FileNameInformation=1
fi
if test "$enable_kernel32_Processor_Group" -eq 1; then
if test "$enable_api_ms_win_Stub_DLLs" -gt 1; then
abort "Patchset api-ms-win-Stub_DLLs disabled, but kernel32-Processor_Group depends on that."
@ -4769,23 +4776,44 @@ if test "$enable_kernel32_SCSI_Sysfs" -eq 1; then
) >> "$patchlist"
fi
# Patchset ntdll-FileNameInformation
# |
# | Modified files:
# | * dlls/ntdll/file.c, dlls/ntdll/tests/file.c
# |
if test "$enable_ntdll_FileNameInformation" -eq 1; then
patch_apply ntdll-FileNameInformation/0001-ntdll-Implement-querying-for-FileNameInformation-of-.patch
(
printf '%s\n' '+ { "Michael Müller", "ntdll: Implement querying for FileNameInformation of named pipes in NtQueryInformationFile.", 1 },';
) >> "$patchlist"
fi
# Patchset kernel32-SetFileCompletionNotificationModes
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * ntdll-FileNameInformation
# |
# | This patchset fixes the following Wine bugs:
# | * [#38960] Add support for kernel32.SetFileCompletionNotificationModes
# |
# | Modified files:
# | * dlls/kernel32/file.c, dlls/ntdll/file.c, dlls/ntdll/tests/file.c, dlls/ws2_32/tests/sock.c, server/fd.c,
# | server/protocol.def
# | * 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
# |
if test "$enable_kernel32_SetFileCompletionNotificationModes" -eq 1; then
patch_apply kernel32-SetFileCompletionNotificationModes/0001-ntdll-Implement-FileIoCompletionNotificationInformat.patch
patch_apply kernel32-SetFileCompletionNotificationModes/0002-ntdll-Allow-to-query-file-IO-completion-notification.patch
patch_apply kernel32-SetFileCompletionNotificationModes/0003-ws2_32-tests-Add-test-for-completion-notification-fl.patch
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
(
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 },';
printf '%s\n' '+ { "Sebastian Lackner", "ws2_32/tests: Add test for completion notification flags.", 1 },';
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 },';
) >> "$patchlist"
fi
@ -5366,18 +5394,6 @@ if test "$enable_ntdll_FileFsVolumeInformation" -eq 1; then
) >> "$patchlist"
fi
# Patchset ntdll-FileNameInformation
# |
# | Modified files:
# | * dlls/ntdll/file.c, dlls/ntdll/tests/file.c
# |
if test "$enable_ntdll_FileNameInformation" -eq 1; then
patch_apply ntdll-FileNameInformation/0001-ntdll-Implement-querying-for-FileNameInformation-of-.patch
(
printf '%s\n' '+ { "Michael Müller", "ntdll: Implement querying for FileNameInformation of named pipes in NtQueryInformationFile.", 1 },';
) >> "$patchlist"
fi
# Patchset ntdll-Fix_Alignment
# |
# | This patchset fixes the following Wine bugs:
@ -5513,7 +5529,7 @@ fi
# Patchset ntdll-NtQueryEaFile
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * kernel32-SetFileCompletionNotificationModes
# | * ntdll-FileNameInformation, kernel32-SetFileCompletionNotificationModes
# |
# | Modified files:
# | * dlls/ntdll/file.c, dlls/ntdll/tests/file.c
@ -5528,7 +5544,7 @@ fi
# Patchset ntdll-Junction_Points
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * kernel32-SetFileCompletionNotificationModes, ntdll-NtQueryEaFile
# | * ntdll-FileNameInformation, kernel32-SetFileCompletionNotificationModes, ntdll-NtQueryEaFile
# |
# | This patchset fixes the following Wine bugs:
# | * [#12401] Support for Junction Points