From 723fa05be459725140a88f614b315b19f90cc235 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner 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