You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Rebase against 9eb56e25e37b4adec0d72875455ffb787238672f.
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
From 3743bfb6a418605e3d30f9b4dad57ec8e498ed71 Mon Sep 17 00:00:00 2001
|
||||
From 616d2000a5dd5f9e68fe873a368e72dda49d6953 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 15 Oct 2016 19:50:46 +0200
|
||||
Subject: ntdll: Implement FileIoCompletionNotificationInformation info class.
|
||||
@ -7,13 +7,12 @@ Subject: ntdll: Implement FileIoCompletionNotificationInformation info class.
|
||||
FIXME: The tests do not seem to work on all testbots yet.
|
||||
FIXME: Could we use the existing wineserver call instead?
|
||||
---
|
||||
dlls/kernel32/file.c | 13 +++--
|
||||
dlls/ntdll/file.c | 17 +++++++
|
||||
dlls/ntdll/tests/file.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
include/winternl.h | 8 +++
|
||||
server/fd.c | 23 ++++++++-
|
||||
server/protocol.def | 8 +++
|
||||
6 files changed, 195 insertions(+), 4 deletions(-)
|
||||
dlls/kernel32/file.c | 13 ++++++++++---
|
||||
dlls/ntdll/file.c | 17 +++++++++++++++++
|
||||
dlls/ntdll/tests/file.c | 3 +--
|
||||
server/fd.c | 23 ++++++++++++++++++++++-
|
||||
server/protocol.def | 8 ++++++++
|
||||
5 files changed, 58 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c
|
||||
index 3e93b0dfd78..f4e63bcaae6 100644
|
||||
@ -72,172 +71,23 @@ index fd7f3dd955a..00131f11cf7 100644
|
||||
io->u.Status = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 1a02ce5eaa5..0a114e7cc73 100644
|
||||
index 5053eb123d1..bf45cbfa522 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -3261,6 +3261,135 @@ static void test_file_all_name_information(void)
|
||||
HeapFree( GetProcessHeap(), 0, file_name );
|
||||
}
|
||||
@@ -3277,12 +3277,11 @@ static void test_file_completion_information(void)
|
||||
if (!(h = create_temp_file(0))) return;
|
||||
|
||||
+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);
|
||||
+ 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)
|
||||
+ {
|
||||
+ 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 +4428,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,
|
||||
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");
|
||||
+ win_skip("FileIoCompletionNotificationInformation class not supported\n");
|
||||
CloseHandle(h);
|
||||
return;
|
||||
}
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index 732a5b798f3..8ff5f9801ad 100644
|
||||
--- a/server/fd.c
|
||||
|
Reference in New Issue
Block a user