wine-staging/patches/kernel32-SetFileCompletionNotificationModes/0002-ntdll-Allow-to-query-file-IO-completion-notification.patch
2017-02-17 22:15:05 +01:00

133 lines
5.4 KiB
Diff

From 723fa05be459725140a88f614b315b19f90cc235 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 5 Feb 2017 11:27:49 +0100
Subject: ntdll: Allow to query file IO completion notification mode.
---
dlls/ntdll/file.c | 18 +++++++++++++++++-
dlls/ntdll/tests/file.c | 15 +++++++++++++++
server/fd.c | 11 +++++++++++
server/protocol.def | 8 ++++++++
4 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 00131f11cf7..fc72833e1a4 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -2357,7 +2357,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
0, /* FileIdFullDirectoryInformation */
0, /* FileValidDataLengthInformation */
0, /* FileShortNameInformation */
- 0, /* FileIoCompletionNotificationInformation, */
+ sizeof(FILE_IO_COMPLETION_NOTIFICATION_INFORMATION), /* FileIoCompletionNotificationInformation, */
0, /* FileIoStatusBlockRangeInformation */
0, /* FileIoPriorityHintInformation */
0, /* FileSfioReserveInformation */
@@ -2617,6 +2617,22 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
}
}
break;
+ case FileIoCompletionNotificationInformation:
+ {
+ FILE_IO_COMPLETION_NOTIFICATION_INFORMATION *info = ptr;
+
+ SERVER_START_REQ( get_fd_compl_info )
+ {
+ req->handle = wine_server_obj_handle( hFile );
+ if (!(io->u.Status = wine_server_call( req )))
+ {
+ info->Flags = (reply->flags & COMPLETION_SKIP_ON_SUCCESS) ?
+ FILE_SKIP_COMPLETION_PORT_ON_SUCCESS : 0;
+ }
+ }
+ SERVER_END_REQ;
+ }
+ break;
case FileIdInformation:
if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
else
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 0a114e7cc73..214c51a726a 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -3303,6 +3303,11 @@ static void test_file_completion_information(void)
CloseHandle(h);
if (!(h = create_temp_file(FILE_FLAG_OVERLAPPED))) return;
+ info.Flags = ~0U;
+ status = pNtQueryInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+ ok(!(info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS), "got %08x\n", info.Flags);
+
memset(&ov, 0, sizeof(ov));
ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
port = CreateIoCompletionPort(h, NULL, 0xdeadbeef, 0);
@@ -3337,6 +3342,11 @@ static void test_file_completion_information(void)
status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+ info.Flags = 0;
+ status = pNtQueryInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+ ok((info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) != 0, "got %08x\n", info.Flags);
+
for (i = 0; i < 10; i++)
{
SetLastError(0xdeadbeef);
@@ -3362,6 +3372,11 @@ static void test_file_completion_information(void)
status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+ info.Flags = 0;
+ status = pNtQueryInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+ ok((info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) != 0, "got %08x\n", info.Flags);
+
for (i = 0; i < 10; i++)
{
SetLastError(0xdeadbeef);
diff --git a/server/fd.c b/server/fd.c
index 8ff5f9801ad..3d1a1d8befe 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2566,6 +2566,17 @@ DECL_HANDLER(set_fd_compl_info)
}
}
+/* get fd completion information */
+DECL_HANDLER(get_fd_compl_info)
+{
+ struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
+ if (fd)
+ {
+ reply->flags = fd->comp_flags;
+ release_object( fd );
+ }
+}
+
/* set fd disposition information */
DECL_HANDLER(set_fd_disp_info)
{
diff --git a/server/protocol.def b/server/protocol.def
index 73fef6fade6..935665b2005 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3665,6 +3665,14 @@ struct handle_info
#define COMPLETION_SKIP_ON_SUCCESS 0x01
+/* get fd completion information */
+@REQ(get_fd_compl_info)
+ obj_handle_t handle; /* handle to a file or directory */
+@REPLY
+ int flags; /* completion flags (see below) */
+@END
+
+
/* set fd disposition information */
@REQ(set_fd_disp_info)
obj_handle_t handle; /* handle to a file or directory */
--
2.11.0