From: Zhiyi Zhang zzhang@codeweavers.com
Test that setting completion information for an overlapped file could make it become signaled if FILE_SKIP_SET_EVENT_ON_HANDLE is not set. --- dlls/ntdll/tests/file.c | 53 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 9f8d29f9810..e5001c4e856 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -4117,13 +4117,16 @@ static void _test_completion_flags(unsigned line, HANDLE handle, DWORD expected_ static void test_file_completion_information(void) { DECLSPEC_ALIGN(TEST_OVERLAPPED_READ_SIZE) static unsigned char aligned_buf[TEST_OVERLAPPED_READ_SIZE]; + static const char pipe_name[] = "\\.\pipe\test_file_completion_information"; static const char buf[] = "testdata"; FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info; + HANDLE port, h, completion, server, client; + FILE_COMPLETION_INFORMATION fci; + BYTE recv_buf[TEST_BUF_LEN]; + DWORD num_bytes, flag; OVERLAPPED ov, *pov; IO_STATUS_BLOCK io; NTSTATUS status; - DWORD num_bytes; - HANDLE port, h; ULONG_PTR key; BOOL ret; int i; @@ -4297,6 +4300,52 @@ static void test_file_completion_information(void) CloseHandle(ov.hEvent); CloseHandle(port); CloseHandle(h); + + /* Test that setting FileCompletionInformation makes an overlapped file signaled unless FILE_SKIP_SET_EVENT_ON_HANDLE is set */ + for (flag = 0; flag <= FILE_SKIP_SET_USER_EVENT_ON_FAST_IO; flag = flag ? flag << 1 : 1) + { + winetest_push_context("%#lx", flag); + + status = pNtCreateIoCompletion(&completion, IO_COMPLETION_ALL_ACCESS, NULL, 0); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + + server = CreateNamedPipeA(pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, + 1000, NULL); + ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed, error %lu.\n", GetLastError()); + client = CreateFileA(pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL); + ok(client != INVALID_HANDLE_VALUE, "CreateFile failed, error %lu.\n", GetLastError()); + + memset(&ov, 0, sizeof(ov)); + ReadFile(server, recv_buf, TEST_BUF_LEN, &num_bytes, &ov); + ok(!is_signaled(server), "Expected not signaled.\n"); + + info.Flags = flag; + status = pNtSetInformationFile(server, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + test_completion_flags(server, flag); + + fci.CompletionPort = completion; + fci.CompletionKey = CKEY_FIRST; + io.Status = 0xdeadbeef; + status = pNtSetInformationFile(server, &io, &fci, sizeof(fci), FileCompletionInformation); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + ok(io.Status == STATUS_SUCCESS, "Got unexpected iosb.Status %#lx.\n", io.Status); + if (flag == FILE_SKIP_SET_EVENT_ON_HANDLE) + ok(!is_signaled(server), "Expected not signaled.\n"); + else + todo_wine + ok(is_signaled(server), "Expected signaled.\n"); + + status = pNtClose(client); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + status = pNtClose(server); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + status = pNtClose(completion); + ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); + winetest_pop_context(); + } }
static void test_file_id_information(void)