Commit in reactos/ntoskrnl/io on MAIN
iocomp.c+33-151.16 -> 1.17
NtRemoveIoCompletion: didn't check for possible NTSTATUS codes returned from KeRemoveQueue
Spotted by GvG

reactos/ntoskrnl/io
iocomp.c 1.16 -> 1.17
diff -u -r1.16 -r1.17
--- iocomp.c	25 Nov 2004 22:18:16 -0000	1.16
+++ iocomp.c	21 Dec 2004 02:34:32 -0000	1.17
@@ -279,6 +279,8 @@
 {
    PKQUEUE  Queue;
    NTSTATUS Status;
+   PIO_COMPLETION_PACKET   Packet;
+   PLIST_ENTRY             ListEntry;
       
    Status = ObReferenceObjectByHandle( IoCompletionHandle,
                                        IO_COMPLETION_MODIFY_STATE,
@@ -286,29 +288,45 @@
                                        UserMode,
                                        (PVOID*)&Queue,
                                        NULL);
-   if (NT_SUCCESS(Status))
+   if (!NT_SUCCESS(Status))
    {
-      PIO_COMPLETION_PACKET   Packet;
-      PLIST_ENTRY             ListEntry;
+      return Status;
+   }
 
-      /*
-      Try 2 remove packet from queue. Wait (optionaly) if
-      no packet in queue or max num of threads allready running.
-      */
+   /*
+   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 );
 
-      ObDereferenceObject(Queue);
-
-      Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
+      /* 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
+      */
 
-      if (CompletionKey) *CompletionKey = Packet->Key;
-      if (CompletionContext) *CompletionContext = Packet->Context;
-      if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus;
+   } while((NTSTATUS)ListEntry == STATUS_USER_APC);
 
-      ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
+   ObDereferenceObject(Queue);
+   
+   if ((NTSTATUS)ListEntry == STATUS_TIMEOUT)
+   {
+      return STATUS_TIMEOUT;
    }
+   
+   ASSERT(ListEntry);
+   
+   Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
 
-   return Status;
+   if (CompletionKey) *CompletionKey = Packet->Key;
+   if (CompletionContext) *CompletionContext = Packet->Context;
+   if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus;
+
+   ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
+
+   return STATUS_SUCCESS;
 }
 
 
CVSspam 0.2.8