Sebastian Lackner : ntdll/tests: Add tests for FileIoCompletionNotificationInformation info class.

Alexandre Julliard julliard at winehq.org
Fri Feb 17 14:37:10 CST 2017


Module: wine
Branch: master
Commit: f9ede5c4c11f999f940945616e5c69f860d93397
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f9ede5c4c11f999f940945616e5c69f860d93397

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Fri Feb 17 05:14:59 2017 +0100

ntdll/tests: Add tests for FileIoCompletionNotificationInformation info class.

Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/tests/file.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/winternl.h      |   8 +++
 2 files changed, 140 insertions(+)

diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 1a02ce5..5053eb1 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -3261,6 +3261,137 @@ static void test_file_all_name_information(void)
     HeapFree( GetProcessHeap(), 0, file_name );
 }
 
+static void test_file_completion_information(void)
+{
+    static const char buf[] = "testdata";
+    FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info;
+    OVERLAPPED ov, *pov;
+    IO_STATUS_BLOCK io;
+    NTSTATUS status;
+    DWORD num_bytes;
+    HANDLE port, h;
+    ULONG_PTR key;
+    BOOL ret;
+    int i;
+
+    if (!(h = create_temp_file(0))) return;
+
+    status = pNtSetInformationFile(h, &io, &info, sizeof(info) - 1, FileIoCompletionNotificationInformation);
+    todo_wine
+    ok(status == STATUS_INFO_LENGTH_MISMATCH || status == STATUS_INVALID_INFO_CLASS /* XP */,
+       "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+    if (status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED)
+    {
+        skip("FileIoCompletionNotificationInformation class not supported\n");
+        CloseHandle(h);
+        return;
+    }
+
+    info.Flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS;
+    status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+    ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %08x\n", status);
+
+    CloseHandle(h);
+    if (!(h = create_temp_file(FILE_FLAG_OVERLAPPED))) return;
+
+    info.Flags = FILE_SKIP_SET_EVENT_ON_HANDLE;
+    status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+    ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+
+    info.Flags = FILE_SKIP_SET_USER_EVENT_ON_FAST_IO;
+    status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+    ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+
+    CloseHandle(h);
+    if (!(h = create_temp_file(FILE_FLAG_OVERLAPPED))) return;
+
+    memset(&ov, 0, sizeof(ov));
+    ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
+    port = CreateIoCompletionPort(h, NULL, 0xdeadbeef, 0);
+    ok(port != NULL, "CreateIoCompletionPort failed, error %u\n", GetLastError());
+
+    for (i = 0; i < 10; i++)
+    {
+        SetLastError(0xdeadbeef);
+        ret = WriteFile(h, buf, sizeof(buf), &num_bytes, &ov);
+        if (ret || GetLastError() != ERROR_IO_PENDING) break;
+        ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE);
+        ok(ret, "GetOverlappedResult failed, error %u\n", GetLastError());
+        ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
+        ok(ret, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
+        ret = FALSE;
+    }
+    if (ret)
+    {
+        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);
+    }
+    else
+        win_skip("WriteFile never returned TRUE\n");
+
+    info.Flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS;
+    status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+    ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+
+    for (i = 0; i < 10; i++)
+    {
+        SetLastError(0xdeadbeef);
+        ret = WriteFile(h, buf, sizeof(buf), &num_bytes, &ov);
+        if (ret || GetLastError() != ERROR_IO_PENDING) break;
+        ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE);
+        ok(ret, "GetOverlappedResult failed, error %u\n", GetLastError());
+        ret = FALSE;
+    }
+    if (ret)
+    {
+        ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %u\n", num_bytes);
+
+        pov = (void *)0xdeadbeef;
+        ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 500);
+        ok(!ret, "GetQueuedCompletionStatus succeeded\n");
+        ok(pov == NULL, "expected NULL, got %p\n", pov);
+    }
+    else
+        win_skip("WriteFile never returned TRUE\n");
+
+    info.Flags = 0;
+    status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
+    ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+
+    for (i = 0; i < 10; i++)
+    {
+        SetLastError(0xdeadbeef);
+        ret = WriteFile(h, buf, sizeof(buf), &num_bytes, &ov);
+        if (ret || GetLastError() != ERROR_IO_PENDING) break;
+        ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE);
+        ok(ret, "GetOverlappedResult failed, error %u\n", GetLastError());
+        ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
+        ok(ret, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
+        ret = FALSE;
+    }
+    if (ret)
+    {
+        ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %u\n", num_bytes);
+
+        pov = (void *)0xdeadbeef;
+        ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
+        ok(!ret, "GetQueuedCompletionStatus succeeded\n");
+        ok(pov == NULL, "expected NULL, got %p\n", pov);
+    }
+    else
+        win_skip("WriteFile never returned TRUE\n");
+
+    CloseHandle(ov.hEvent);
+    CloseHandle(port);
+    CloseHandle(h);
+}
+
 static void test_file_id_information(void)
 {
     BY_HANDLE_FILE_INFORMATION info;
@@ -4299,6 +4430,7 @@ START_TEST(file)
     test_file_rename_information();
     test_file_link_information();
     test_file_disposition_information();
+    test_file_completion_information();
     test_file_id_information();
     test_query_volume_information_file();
     test_query_attribute_information_file();
diff --git a/include/winternl.h b/include/winternl.h
index f6308f5..5cd1664 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -741,6 +741,14 @@ typedef struct _FILE_ALL_INFORMATION {
     FILE_NAME_INFORMATION      NameInformation;
 } FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;
 
+typedef struct _FILE_IO_COMPLETION_NOTIFICATION_INFORMATION {
+    ULONG Flags;
+} FILE_IO_COMPLETION_NOTIFICATION_INFORMATION, *PFILE_IO_COMPLETION_NOTIFICATION_INFORMATION;
+
+#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1
+#define FILE_SKIP_SET_EVENT_ON_HANDLE        0x2
+#define FILE_SKIP_SET_USER_EVENT_ON_FAST_IO  0x4
+
 typedef enum _FSINFOCLASS {
     FileFsVolumeInformation = 1,
     FileFsLabelInformation,




More information about the wine-cvs mailing list