From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/signal_arm64ec.c | 1 + dlls/ntdll/tests/file.c | 1 - dlls/ntdll/unix/sync.c | 20 ++++++++++++++++++++ dlls/wow64/sync.c | 12 ++++++++++++ include/winternl.h | 1 + server/completion.c | 27 +++++++++++++++++++++++++++ server/protocol.def | 7 +++++++ 8 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 05f40a8bdf3..c0d552a0c4b 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -159,6 +159,7 @@ @ stdcall -syscall NtCancelIoFileEx(long ptr ptr) @ stdcall -syscall NtCancelSynchronousIoFile(long ptr ptr) @ stdcall -syscall=0x0061 NtCancelTimer(long ptr) +@ stdcall -syscall NtCancelWaitCompletionPacket(ptr long) @ stdcall -syscall=0x003e NtClearEvent(long) @ stdcall -syscall=0x000f NtClose(long) @ stdcall -syscall=0x003b NtCloseObjectAuditAlarm(ptr long long) diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c index f942a6c966c..441db7f0ead 100644 --- a/dlls/ntdll/signal_arm64ec.c +++ b/dlls/ntdll/signal_arm64ec.c @@ -364,6 +364,7 @@ DEFINE_SYSCALL(NtCancelIoFile, (HANDLE handle, IO_STATUS_BLOCK *io_status)) DEFINE_SYSCALL(NtCancelIoFileEx, (HANDLE handle, IO_STATUS_BLOCK *io, IO_STATUS_BLOCK *io_status)) DEFINE_SYSCALL(NtCancelSynchronousIoFile, (HANDLE handle, IO_STATUS_BLOCK *io, IO_STATUS_BLOCK *io_status)) DEFINE_SYSCALL(NtCancelTimer, (HANDLE handle, BOOLEAN *state)) +DEFINE_SYSCALL(NtCancelWaitCompletionPacket, (HANDLE packet, BOOLEAN remove_signaled)) DEFINE_SYSCALL(NtClearEvent, (HANDLE handle)) DEFINE_SYSCALL(NtClose, (HANDLE handle)) DEFINE_SYSCALL(NtCloseObjectAuditAlarm, (UNICODE_STRING *subsystem, HANDLE handle, BOOLEAN onclose)) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 3304bf1cc88..785667be9a0 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -7646,7 +7646,6 @@ static void test_cancel_wait_completion_packet(void)
if (!pNtCancelWaitCompletionPacket) { - todo_wine win_skip("NtCancelWaitCompletionPacket is unavailable.\n"); return; } diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index d19428e9cbf..3c7c9fe3c5a 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -2900,6 +2900,26 @@ NTSTATUS WINAPI NtAssociateWaitCompletionPacket( HANDLE packet, HANDLE completio return ret; }
+/*********************************************************************** + * NtCancelWaitCompletionPacket (NTDLL.@) + */ +NTSTATUS WINAPI NtCancelWaitCompletionPacket( HANDLE packet, BOOLEAN remove_signaled ) +{ + NTSTATUS status; + + TRACE( "%p, %d\n", packet, remove_signaled ); + + SERVER_START_REQ( cancel_completion_packet ) + { + req->packet = wine_server_obj_handle( packet ); + req->remove_signaled = remove_signaled; + status = wine_server_call( req ); + } + SERVER_END_REQ; + return status; +} + + /*********************************************************************** * NtCreateWaitCompletionPacket (NTDLL.@) */ diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c index 1920c956790..c57801c9348 100644 --- a/dlls/wow64/sync.c +++ b/dlls/wow64/sync.c @@ -1877,6 +1877,18 @@ NTSTATUS WINAPI wow64_NtAssociateWaitCompletionPacket( UINT *args ) }
+/********************************************************************** + * wow64_NtCancelWaitCompletionPacket + */ +NTSTATUS WINAPI wow64_NtCancelWaitCompletionPacket( UINT *args ) +{ + HANDLE packet = get_handle( &args ); + BOOLEAN remove_signaled = get_ulong( &args ); + + return NtCancelWaitCompletionPacket( packet, remove_signaled ); +} + + /********************************************************************** * wow64_NtCreateWaitCompletionPacket */ diff --git a/include/winternl.h b/include/winternl.h index 26a0598ee24..69364eb7ab4 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -4465,6 +4465,7 @@ NTSYSAPI NTSTATUS WINAPI NtCancelIoFile(HANDLE,PIO_STATUS_BLOCK); NTSYSAPI NTSTATUS WINAPI NtCancelIoFileEx(HANDLE,PIO_STATUS_BLOCK,PIO_STATUS_BLOCK); NTSYSAPI NTSTATUS WINAPI NtCancelSynchronousIoFile(HANDLE,PIO_STATUS_BLOCK,PIO_STATUS_BLOCK); NTSYSAPI NTSTATUS WINAPI NtCancelTimer(HANDLE, BOOLEAN*); +NTSYSAPI NTSTATUS WINAPI NtCancelWaitCompletionPacket(HANDLE, BOOLEAN); NTSYSAPI NTSTATUS WINAPI NtClearEvent(HANDLE); NTSYSAPI NTSTATUS WINAPI NtClose(HANDLE); NTSYSAPI NTSTATUS WINAPI NtCloseObjectAuditAlarm(PUNICODE_STRING,HANDLE,BOOLEAN); diff --git a/server/completion.c b/server/completion.c index 6baaaacdb33..c182f3fd7a0 100644 --- a/server/completion.c +++ b/server/completion.c @@ -743,3 +743,30 @@ DECL_HANDLER(associate_completion_packet) release_object( target ); release_object( packet ); } + +/* cancel a wait completion packet */ +DECL_HANDLER(cancel_completion_packet) +{ + struct completion_packet *packet; + + packet = get_completion_packet_obj( current->process, req->packet, WAIT_COMPLETION_PACKET_QUERY_STATE ); + if (!packet) + return; + + if (!packet->in_target_packet_queue && !packet->in_completion_queue) + { + set_error( STATUS_CANCELLED ); + release_object( packet ); + return; + } + + if (packet->in_completion_queue && !req->remove_signaled) + { + set_error( STATUS_PENDING ); + release_object( packet ); + return; + } + + cancel_completion_packet( packet ); + release_object( packet ); +} diff --git a/server/protocol.def b/server/protocol.def index 35ae85e619a..40538089151 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3907,6 +3907,13 @@ struct handle_info @END
+/* Cancel a wait completion packet */ +@REQ(cancel_completion_packet) + obj_handle_t packet; /* wait completion packet handle */ + int remove_signaled;/* whether to remove signaled packet */ +@END + + /* check for associated completion and push msg */ @REQ(add_fd_completion) obj_handle_t handle; /* async' object */