ntdll/tests: Add tests for FileIoCompletionNotificationInformation info class.
Sebastian Lackner
sebastian at fds-team.de
Thu Feb 16 22:14:59 CST 2017
Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---
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 1a02ce5eaa5..5053eb123d1 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 2f2ea866ae7..08af643b334 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,
--
2.11.0
More information about the wine-patches
mailing list