2017-02-17 13:15:05 -08:00
|
|
|
From 723fa05be459725140a88f614b315b19f90cc235 Mon Sep 17 00:00:00 2001
|
2017-02-05 02:57:04 -08:00
|
|
|
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
|
2017-02-17 13:15:05 -08:00
|
|
|
index 00131f11cf7..fc72833e1a4 100644
|
2017-02-05 02:57:04 -08:00
|
|
|
--- a/dlls/ntdll/file.c
|
|
|
|
+++ b/dlls/ntdll/file.c
|
2017-02-17 13:15:05 -08:00
|
|
|
@@ -2357,7 +2357,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
2017-02-05 02:57:04 -08:00
|
|
|
0, /* FileIdFullDirectoryInformation */
|
|
|
|
0, /* FileValidDataLengthInformation */
|
|
|
|
0, /* FileShortNameInformation */
|
|
|
|
- 0, /* FileIoCompletionNotificationInformation, */
|
|
|
|
+ sizeof(FILE_IO_COMPLETION_NOTIFICATION_INFORMATION), /* FileIoCompletionNotificationInformation, */
|
|
|
|
0, /* FileIoStatusBlockRangeInformation */
|
|
|
|
0, /* FileIoPriorityHintInformation */
|
|
|
|
0, /* FileSfioReserveInformation */
|
2017-02-17 13:15:05 -08:00
|
|
|
@@ -2617,6 +2617,22 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
2017-02-05 02:57:04 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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;
|
2017-02-17 13:15:05 -08:00
|
|
|
case FileIdInformation:
|
|
|
|
if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
|
|
|
|
else
|
2017-02-05 02:57:04 -08:00
|
|
|
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
2017-02-17 13:15:05 -08:00
|
|
|
index 0a114e7cc73..214c51a726a 100644
|
2017-02-05 02:57:04 -08:00
|
|
|
--- 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
|
|
|
|
|