diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 5e7c463d08b..b7cbff39d2a 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -308,6 +308,7 @@ @ stub NtReleaseProcessMutant @ stdcall NtReleaseSemaphore(long long ptr) @ stdcall NtRemoveIoCompletion(ptr ptr ptr ptr ptr) +@ stdcall NtRemoveIoCompletionEx(ptr ptr long ptr ptr long) # @ stub NtRemoveProcessDebug @ stdcall NtRenameKey(long ptr) @ stdcall NtReplaceKey(ptr long ptr) @@ -1243,6 +1244,7 @@ @ stub ZwReleaseProcessMutant @ stdcall -private ZwReleaseSemaphore(long long ptr) NtReleaseSemaphore @ stdcall -private ZwRemoveIoCompletion(ptr ptr ptr ptr ptr) NtRemoveIoCompletion +@ stdcall -private ZwRemoveIoCompletionEx(ptr ptr long ptr ptr long) NtRemoveIoCompletionEx # @ stub ZwRemoveProcessDebug @ stdcall -private ZwRenameKey(long ptr) NtRenameKey @ stdcall -private ZwReplaceKey(ptr long ptr) NtReplaceKey diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index bb462f211e7..4ae8e36ce04 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -1333,6 +1333,54 @@ NTSTATUS WINAPI NtRemoveIoCompletion( HANDLE CompletionPort, PULONG_PTR Completi return status; } +/****************************************************************** + * NtRemoveIoCompletionEx (NTDLL.@) + * ZwRemoveIoCompletionEx (NTDLL.@) + */ +NTSTATUS WINAPI NtRemoveIoCompletionEx( HANDLE port, FILE_IO_COMPLETION_INFORMATION *info, ULONG count, + ULONG *written, LARGE_INTEGER *timeout, BOOLEAN alertable ) +{ + NTSTATUS ret; + ULONG i = 0; + + TRACE("%p %p %u %p %p %u\n", port, info, count, written, timeout, alertable); + + for (;;) + { + for (;;) + { + SERVER_START_REQ( remove_completion ) + { + req->handle = wine_server_obj_handle( port ); + if (!(ret = wine_server_call( req ))) + { + info[i].CompletionKey = reply->ckey; + info[i].CompletionValue = reply->cvalue; + info[i].IoStatusBlock.Information = reply->information; + info[i].IoStatusBlock.u.Status = reply->status; + } + } + SERVER_END_REQ; + + if (ret != STATUS_SUCCESS) break; + + if (i++ >= count) break; + } + + if (i && ret == STATUS_PENDING) + { + ret = STATUS_SUCCESS; + break; + } + + ret = NtWaitForSingleObject( port, alertable, timeout ); + if (ret != WAIT_OBJECT_0) break; + } + + *written = i ? i : 1; + return ret; +} + /****************************************************************** * NtOpenIoCompletion (NTDLL.@) * ZwOpenIoCompletion (NTDLL.@)