You've already forked wine-staging
							
							
				mirror of
				https://gitlab.winehq.org/wine/wine-staging.git
				synced 2025-09-12 18:50:20 -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