diff --git a/patches/kernel32-SetFileCompletionNotificationModes/0001-ntdll-Implement-FileIoCompletionNotificationInformat.patch b/patches/kernel32-SetFileCompletionNotificationModes/0001-ntdll-Implement-FileIoCompletionNotificationInformat.patch index 33b6d8d7..81027c73 100644 --- a/patches/kernel32-SetFileCompletionNotificationModes/0001-ntdll-Implement-FileIoCompletionNotificationInformat.patch +++ b/patches/kernel32-SetFileCompletionNotificationModes/0001-ntdll-Implement-FileIoCompletionNotificationInformat.patch @@ -1,7 +1,8 @@ -From 542040171f936b56bc90f663cf6118a5998179af Mon Sep 17 00:00:00 2001 +From 624410b16ab0e56d0f87ce4cb2382df29710ba73 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 15 Oct 2016 19:50:46 +0200 Subject: ntdll: Implement FileIoCompletionNotificationInformation info class. + (v2) FIXME: The tests do not seem to work on all testbots yet. FIXME: Could we use the existing wineserver call instead? @@ -10,12 +11,12 @@ FIXME: Could we use the existing wineserver call instead? dlls/ntdll/file.c | 17 +++++++ dlls/ntdll/tests/file.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ include/winternl.h | 8 +++ - server/fd.c | 21 +++++++- + server/fd.c | 23 ++++++++- server/protocol.def | 8 +++ - 6 files changed, 193 insertions(+), 4 deletions(-) + 6 files changed, 195 insertions(+), 4 deletions(-) diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c -index cc7ead1..5fe2268 100644 +index cc7ead1cdd6..5fe22686bb1 100644 --- a/dlls/kernel32/file.c +++ b/dlls/kernel32/file.c @@ -1061,13 +1061,20 @@ BOOL WINAPI SetEndOfFile( HANDLE hFile ) @@ -43,10 +44,10 @@ index cc7ead1..5fe2268 100644 } diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 7fbde50..14715b1 100644 +index c7669ee02fe..5560762b3cd 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c -@@ -2788,6 +2788,23 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, +@@ -2787,6 +2787,23 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, io->u.Status = STATUS_INVALID_PARAMETER_3; break; @@ -71,7 +72,7 @@ index 7fbde50..14715b1 100644 io->u.Status = STATUS_INVALID_INFO_CLASS; break; diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 586b2c9..dfaf4a5 100644 +index 57d7df9c00a..f9c61e2f25b 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) @@ -210,7 +211,7 @@ index 586b2c9..dfaf4a5 100644 static void test_query_volume_information_file(void) { NTSTATUS status; -@@ -4214,6 +4343,7 @@ START_TEST(file) +@@ -4260,6 +4389,7 @@ START_TEST(file) test_file_rename_information(); test_file_link_information(); test_file_disposition_information(); @@ -219,7 +220,7 @@ index 586b2c9..dfaf4a5 100644 test_query_attribute_information_file(); } diff --git a/include/winternl.h b/include/winternl.h -index f35091c..7613d8b 100644 +index f35091cba1a..7613d8b9264 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -725,6 +725,14 @@ typedef struct _FILE_ALL_INFORMATION { @@ -238,7 +239,7 @@ index f35091c..7613d8b 100644 FileFsVolumeInformation = 1, FileFsLabelInformation, diff --git a/server/fd.c b/server/fd.c -index 17b1b66..0d5c7a2 100644 +index 732a5b798f3..8ff5f9801ad 100644 --- a/server/fd.c +++ b/server/fd.c @@ -194,6 +194,7 @@ struct fd @@ -257,7 +258,23 @@ index 17b1b66..0d5c7a2 100644 list_init( &fd->inode_entry ); list_init( &fd->locks ); -@@ -2556,12 +2558,29 @@ DECL_HANDLER(add_fd_completion) +@@ -1642,6 +1644,7 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use + fd->write_q = NULL; + fd->wait_q = NULL; + fd->completion = NULL; ++ fd->comp_flags = 0; + fd->no_fd_status = STATUS_BAD_DEVICE_TYPE; + list_init( &fd->inode_entry ); + list_init( &fd->locks ); +@@ -2369,6 +2372,7 @@ void fd_copy_completion( struct fd *src, struct fd *dst ) + { + assert( !dst->completion ); + dst->completion = fd_get_completion( src, &dst->comp_key ); ++ dst->comp_flags = src->comp_flags; + } + + /* flush a file buffers */ +@@ -2539,12 +2543,29 @@ DECL_HANDLER(add_fd_completion) struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 ); if (fd) { @@ -289,10 +306,10 @@ index 17b1b66..0d5c7a2 100644 DECL_HANDLER(set_fd_disp_info) { diff --git a/server/protocol.def b/server/protocol.def -index 8d86737..229596a 100644 +index 60865a6ffc2..73fef6fade6 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -3678,6 +3678,14 @@ struct handle_info +@@ -3657,6 +3657,14 @@ struct handle_info @END @@ -308,5 +325,5 @@ index 8d86737..229596a 100644 @REQ(set_fd_disp_info) obj_handle_t handle; /* handle to a file or directory */ -- -2.9.0 +2.11.0 diff --git a/patches/kernel32-SetFileCompletionNotificationModes/0002-ntdll-Allow-to-query-file-IO-completion-notification.patch b/patches/kernel32-SetFileCompletionNotificationModes/0002-ntdll-Allow-to-query-file-IO-completion-notification.patch new file mode 100644 index 00000000..f792b390 --- /dev/null +++ b/patches/kernel32-SetFileCompletionNotificationModes/0002-ntdll-Allow-to-query-file-IO-completion-notification.patch @@ -0,0 +1,132 @@ +From 50ce3a32218828dafd18daea3649ca36a203f2a7 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 5 Feb 2017 11:27:49 +0100 +Subject: ntdll: Allow to query file IO completion notification mode. + +--- + dlls/ntdll/file.c | 18 +++++++++++++++++- + dlls/ntdll/tests/file.c | 15 +++++++++++++++ + server/fd.c | 11 +++++++++++ + server/protocol.def | 8 ++++++++ + 4 files changed, 51 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c +index 5560762b3cd..db65c2b40cd 100644 +--- a/dlls/ntdll/file.c ++++ b/dlls/ntdll/file.c +@@ -2359,7 +2359,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, + 0, /* FileIdFullDirectoryInformation */ + 0, /* FileValidDataLengthInformation */ + 0, /* FileShortNameInformation */ +- 0, /* FileIoCompletionNotificationInformation, */ ++ sizeof(FILE_IO_COMPLETION_NOTIFICATION_INFORMATION), /* FileIoCompletionNotificationInformation, */ + 0, /* FileIoStatusBlockRangeInformation */ + 0, /* FileIoPriorityHintInformation */ + 0, /* FileSfioReserveInformation */ +@@ -2612,6 +2612,22 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, + } + } + break; ++ case FileIoCompletionNotificationInformation: ++ { ++ FILE_IO_COMPLETION_NOTIFICATION_INFORMATION *info = ptr; ++ ++ SERVER_START_REQ( get_fd_compl_info ) ++ { ++ req->handle = wine_server_obj_handle( hFile ); ++ if (!(io->u.Status = wine_server_call( req ))) ++ { ++ info->Flags = (reply->flags & COMPLETION_SKIP_ON_SUCCESS) ? ++ FILE_SKIP_COMPLETION_PORT_ON_SUCCESS : 0; ++ } ++ } ++ SERVER_END_REQ; ++ } ++ break; + default: + FIXME("Unsupported class (%d)\n", class); + io->u.Status = STATUS_NOT_IMPLEMENTED; +diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c +index f9c61e2f25b..ee14f85d6b6 100644 +--- a/dlls/ntdll/tests/file.c ++++ b/dlls/ntdll/tests/file.c +@@ -3303,6 +3303,11 @@ static void test_file_completion_information(void) + CloseHandle(h); + if (!(h = create_temp_file(FILE_FLAG_OVERLAPPED))) return; + ++ info.Flags = ~0U; ++ status = pNtQueryInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); ++ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); ++ ok(!(info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS), "got %08x\n", info.Flags); ++ + memset(&ov, 0, sizeof(ov)); + ov.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL); + port = CreateIoCompletionPort(h, NULL, 0xdeadbeef, 0); +@@ -3337,6 +3342,11 @@ static void test_file_completion_information(void) + status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); + ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); + ++ info.Flags = 0; ++ status = pNtQueryInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); ++ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); ++ ok((info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) != 0, "got %08x\n", info.Flags); ++ + for (i = 0; i < 10; i++) + { + SetLastError(0xdeadbeef); +@@ -3362,6 +3372,11 @@ static void test_file_completion_information(void) + status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); + ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); + ++ info.Flags = 0; ++ status = pNtQueryInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation); ++ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); ++ ok((info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) != 0, "got %08x\n", info.Flags); ++ + for (i = 0; i < 10; i++) + { + SetLastError(0xdeadbeef); +diff --git a/server/fd.c b/server/fd.c +index 8ff5f9801ad..3d1a1d8befe 100644 +--- a/server/fd.c ++++ b/server/fd.c +@@ -2566,6 +2566,17 @@ DECL_HANDLER(set_fd_compl_info) + } + } + ++/* get fd completion information */ ++DECL_HANDLER(get_fd_compl_info) ++{ ++ struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 ); ++ if (fd) ++ { ++ reply->flags = fd->comp_flags; ++ release_object( fd ); ++ } ++} ++ + /* set fd disposition information */ + DECL_HANDLER(set_fd_disp_info) + { +diff --git a/server/protocol.def b/server/protocol.def +index 73fef6fade6..935665b2005 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -3665,6 +3665,14 @@ struct handle_info + #define COMPLETION_SKIP_ON_SUCCESS 0x01 + + ++/* get fd completion information */ ++@REQ(get_fd_compl_info) ++ obj_handle_t handle; /* handle to a file or directory */ ++@REPLY ++ int flags; /* completion flags (see below) */ ++@END ++ ++ + /* set fd disposition information */ + @REQ(set_fd_disp_info) + obj_handle_t handle; /* handle to a file or directory */ +-- +2.11.0 + diff --git a/patches/kernel32-SetFileCompletionNotificationModes/0003-ws2_32-tests-Add-test-for-completion-notification-fl.patch b/patches/kernel32-SetFileCompletionNotificationModes/0003-ws2_32-tests-Add-test-for-completion-notification-fl.patch new file mode 100644 index 00000000..5e5345de --- /dev/null +++ b/patches/kernel32-SetFileCompletionNotificationModes/0003-ws2_32-tests-Add-test-for-completion-notification-fl.patch @@ -0,0 +1,85 @@ +From e7126b3b16c10175052730398d4f1e578b024747 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sun, 5 Feb 2017 11:54:21 +0100 +Subject: ws2_32/tests: Add test for completion notification flags. + +--- + dlls/ws2_32/tests/sock.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c +index 720808887cf..0b8682e2edc 100644 +--- a/dlls/ws2_32/tests/sock.c ++++ b/dlls/ws2_32/tests/sock.c +@@ -78,6 +78,10 @@ static int (WINAPI *pWSAEnumNameSpaceProvidersA)(LPDWORD,LPWSANAMESPACE_INFOA) + static int (WINAPI *pWSAEnumNameSpaceProvidersW)(LPDWORD,LPWSANAMESPACE_INFOW); + static int (WINAPI *pWSAPoll)(WSAPOLLFD *,ULONG,INT); + ++/* Function pointers from ntdll */ ++static NTSTATUS (WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); ++static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS); ++ + /* Function pointers from iphlpapi */ + static DWORD (WINAPI *pGetAdaptersInfo)(PIP_ADAPTER_INFO,PULONG); + static DWORD (WINAPI *pGetIpForwardTable)(PMIB_IPFORWARDTABLE,PULONG,BOOL); +@@ -1222,6 +1226,7 @@ static void Init (void) + WORD ver = MAKEWORD (2, 2); + WSADATA data; + HMODULE hws2_32 = GetModuleHandleA("ws2_32.dll"), hiphlpapi; ++ HMODULE hntdll = GetModuleHandleA("ntdll.dll"); + + pfreeaddrinfo = (void *)GetProcAddress(hws2_32, "freeaddrinfo"); + pgetaddrinfo = (void *)GetProcAddress(hws2_32, "getaddrinfo"); +@@ -1238,6 +1243,9 @@ static void Init (void) + pWSAEnumNameSpaceProvidersW = (void *)GetProcAddress(hws2_32, "WSAEnumNameSpaceProvidersW"); + pWSAPoll = (void *)GetProcAddress(hws2_32, "WSAPoll"); + ++ pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile"); ++ pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile"); ++ + hiphlpapi = LoadLibraryA("iphlpapi.dll"); + if (hiphlpapi) + { +@@ -9006,10 +9014,13 @@ end: + + static void test_completion_port(void) + { ++ FILE_IO_COMPLETION_NOTIFICATION_INFORMATION io_info; + HANDLE previous_port, io_port; + WSAOVERLAPPED ov, *olp; + SOCKET src, dest, dup, connector = INVALID_SOCKET; + WSAPROTOCOL_INFOA info; ++ IO_STATUS_BLOCK io; ++ NTSTATUS status; + char buf[1024]; + WSABUF bufs; + DWORD num_bytes, flags; +@@ -9459,6 +9470,11 @@ static void test_completion_port(void) + io_port = CreateIoCompletionPort((HANDLE)dest, previous_port, 236, 0); + ok(io_port != NULL, "failed to create completion port %u\n", GetLastError()); + ++ io_info.Flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS; ++ status = pNtSetInformationFile((HANDLE)dest, &io, &io_info, sizeof(io_info), FileIoCompletionNotificationInformation); ++ ok(status == STATUS_SUCCESS || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */, ++ "expected STATUS_SUCCESS, got %08x\n", status); ++ + bret = pAcceptEx(src, dest, buf, sizeof(buf) - 2*(sizeof(struct sockaddr_in) + 16), + sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16, + &num_bytes, &ov); +@@ -9484,6 +9500,13 @@ static void test_completion_port(void) + ok(olp == &ov, "Overlapped structure is at %p\n", olp); + ok(olp && (olp->Internal == (ULONG)STATUS_SUCCESS), "Internal status is %lx\n", olp ? olp->Internal : 0); + ++ io_info.Flags = 0; ++ status = pNtQueryInformationFile((HANDLE)dest, &io, &io_info, sizeof(io_info), FileIoCompletionNotificationInformation); ++ ok(status == STATUS_SUCCESS || broken(status == STATUS_INVALID_INFO_CLASS) /* XP */, ++ "expected STATUS_SUCCESS, got %08x\n", status); ++ if (status == STATUS_SUCCESS) ++ ok((io_info.Flags & FILE_SKIP_COMPLETION_PORT_ON_SUCCESS) != 0, "got %08x\n", io_info.Flags); ++ + SetLastError(0xdeadbeef); + key = 0xdeadbeef; + num_bytes = 0xdeadbeef; +-- +2.11.0 + diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index d08f1a51..ab5ec1bf 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -4758,12 +4758,17 @@ fi # | * [#38960] Add support for kernel32.SetFileCompletionNotificationModes # | # | Modified files: -# | * dlls/kernel32/file.c, dlls/ntdll/file.c, dlls/ntdll/tests/file.c, include/winternl.h, server/fd.c, server/protocol.def +# | * dlls/kernel32/file.c, dlls/ntdll/file.c, dlls/ntdll/tests/file.c, dlls/ws2_32/tests/sock.c, include/winternl.h, +# | server/fd.c, server/protocol.def # | if test "$enable_kernel32_SetFileCompletionNotificationModes" -eq 1; then patch_apply kernel32-SetFileCompletionNotificationModes/0001-ntdll-Implement-FileIoCompletionNotificationInformat.patch + patch_apply kernel32-SetFileCompletionNotificationModes/0002-ntdll-Allow-to-query-file-IO-completion-notification.patch + patch_apply kernel32-SetFileCompletionNotificationModes/0003-ws2_32-tests-Add-test-for-completion-notification-fl.patch ( - printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Implement FileIoCompletionNotificationInformation info class.", 1 },'; + printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Implement FileIoCompletionNotificationInformation info class.", 2 },'; + printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Allow to query file IO completion notification mode.", 1 },'; + printf '%s\n' '+ { "Sebastian Lackner", "ws2_32/tests: Add test for completion notification flags.", 1 },'; ) >> "$patchlist" fi