From 93af2278c0d9a29d005107b97ffb82f46d022cae Mon Sep 17 00:00:00 2001 From: Gunnar Dalsnes Date: Tue, 21 Dec 2004 02:34:32 +0000 Subject: [PATCH] NtRemoveIoCompletion: didn't check for possible NTSTATUS codes returned from KeRemoveQueue Spotted by GvG svn path=/trunk/; revision=12268 --- reactos/ntoskrnl/io/iocomp.c | 58 +++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/reactos/ntoskrnl/io/iocomp.c b/reactos/ntoskrnl/io/iocomp.c index 4bf5adeb1fc..cd8b591930b 100644 --- a/reactos/ntoskrnl/io/iocomp.c +++ b/reactos/ntoskrnl/io/iocomp.c @@ -279,6 +279,8 @@ NtRemoveIoCompletion( { PKQUEUE Queue; NTSTATUS Status; + PIO_COMPLETION_PACKET Packet; + PLIST_ENTRY ListEntry; Status = ObReferenceObjectByHandle( IoCompletionHandle, IO_COMPLETION_MODIFY_STATE, @@ -286,29 +288,45 @@ NtRemoveIoCompletion( UserMode, (PVOID*)&Queue, NULL); - if (NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { - PIO_COMPLETION_PACKET Packet; - PLIST_ENTRY ListEntry; - - /* - Try 2 remove packet from queue. Wait (optionaly) if - no packet in queue or max num of threads allready running. - */ - ListEntry = KeRemoveQueue(Queue, UserMode, Timeout ); - - ObDereferenceObject(Queue); - - Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry); - - if (CompletionKey) *CompletionKey = Packet->Key; - if (CompletionContext) *CompletionContext = Packet->Context; - if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus; - - ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet); + return Status; } - return Status; + /* + Try 2 remove packet from queue. Wait (optionaly) if + no packet in queue or max num of threads allready running. + */ + + do { + + ListEntry = KeRemoveQueue(Queue, UserMode, Timeout ); + + /* Nebbets book says nothing about NtRemoveIoCompletion returning STATUS_USER_APC, + and the umode equivalent GetQueuedCompletionStatus says nothing about this either, + so my guess it we should restart the operation. Need further investigation. -Gunnar + */ + + } while((NTSTATUS)ListEntry == STATUS_USER_APC); + + ObDereferenceObject(Queue); + + if ((NTSTATUS)ListEntry == STATUS_TIMEOUT) + { + return STATUS_TIMEOUT; + } + + ASSERT(ListEntry); + + Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry); + + if (CompletionKey) *CompletionKey = Packet->Key; + if (CompletionContext) *CompletionContext = Packet->Context; + if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus; + + ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet); + + return STATUS_SUCCESS; }