[ros-diffs] [ion] 22721: - Fix formatting/function order - Use only one SEH block in NtRemoveIoCompletion - Get the completion status from the IRP, not from the Mini-Packet, if the completion came from an IRP and not a Mini-Packet.

ion at svn.reactos.org ion at svn.reactos.org
Fri Jun 30 19:53:01 CEST 2006


Author: ion
Date: Fri Jun 30 21:53:00 2006
New Revision: 22721

URL: http://svn.reactos.org/svn/reactos?rev=22721&view=rev
Log:
- Fix formatting/function order
- Use only one SEH block in NtRemoveIoCompletion
- Get the completion status from the IRP, not from the Mini-Packet, if the completion came from an IRP and not a Mini-Packet.

Modified:
    trunk/reactos/ntoskrnl/io/iocomp.c

Modified: trunk/reactos/ntoskrnl/io/iocomp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iocomp.c?rev=22721&r1=22720&r2=22721&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/iocomp.c (original)
+++ trunk/reactos/ntoskrnl/io/iocomp.c Fri Jun 30 21:53:00 2006
@@ -1,10 +1,10 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/iocomp.c
- * PURPOSE:         No purpose listed.
- *
- * PROGRAMMERS:     David Welch (welch at mcmail.com)
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/event.c
+ * PURPOSE:         I/O Wrappers for the Executive Event Functions
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
+ *                  Thomas Weidenmueller (w3seek at reactos.org)
  */
 
 /* INCLUDES *****************************************************************/
@@ -17,7 +17,7 @@
 
 NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
 
-static GENERIC_MAPPING IopCompletionMapping =
+GENERIC_MAPPING IopCompletionMapping =
 {
     STANDARD_RIGHTS_READ    | IO_COMPLETION_QUERY_STATE,
     STANDARD_RIGHTS_WRITE   | IO_COMPLETION_MODIFY_STATE,
@@ -25,50 +25,52 @@
     IO_COMPLETION_ALL_ACCESS
 };
 
-static const INFORMATION_CLASS_INFO IoCompletionInfoClass[] = {
-
+static const INFORMATION_CLASS_INFO IoCompletionInfoClass[] =
+{
      /* IoCompletionBasicInformation */
-    ICI_SQ_SAME( sizeof(IO_COMPLETION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
+    ICI_SQ_SAME(sizeof(IO_COMPLETION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
 };
 
-/* FUNCTIONS *****************************************************************/
+/* PRIVATE FUNCTIONS *********************************************************/
 
 VOID
-STDCALL
+NTAPI
 IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
 {
     PKPRCB Prcb = KeGetCurrentPrcb();
     PNPAGED_LOOKASIDE_LIST List;
-    
+
     /* Use the P List */
-    List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].P;
+    List = (PNPAGED_LOOKASIDE_LIST)Prcb->
+            PPLookasideList[LookasideCompletionList].P;
     List->L.TotalFrees++;
-        
+
     /* Check if the Free was within the Depth or not */
     if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
     {
         /* Let the balancer know */
         List->L.FreeMisses++;
-            
+
         /* Use the L List */
-        List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].L;
+        List = (PNPAGED_LOOKASIDE_LIST)Prcb->
+                PPLookasideList[LookasideCompletionList].L;
         List->L.TotalFrees++;
 
         /* Check if the Free was within the Depth or not */
         if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
-        {            
+        {
             /* All lists failed, use the pool */
             List->L.FreeMisses++;
             ExFreePool(Packet);
         }
     }
-        
+
     /* The free was within dhe Depth */
     InterlockedPushEntrySList(&List->L.ListHead, (PSINGLE_LIST_ENTRY)Packet);
 }
 
 VOID
-STDCALL
+NTAPI
 IopDeleteIoCompletion(PVOID ObjectBody)
 {
     PKQUEUE Queue = ObjectBody;
@@ -77,19 +79,18 @@
     PIRP Irp;
     PIO_COMPLETION_PACKET Packet;
 
-    DPRINT("IopDeleteIoCompletion()\n");
-
     /* Rundown the Queue */
     FirstEntry = KeRundownQueue(Queue);
-
-    /* Clean up the IRPs */
-    if (FirstEntry) {
-
+    if (FirstEntry)
+    {
+        /* Loop the packets */
         CurrentEntry = FirstEntry;
-        do {
-
+        do
+        {
             /* Get the Packet */
-            Packet = CONTAINING_RECORD(CurrentEntry, IO_COMPLETION_PACKET, ListEntry);
+            Packet = CONTAINING_RECORD(CurrentEntry,
+                                       IO_COMPLETION_PACKET,
+                                       ListEntry);
 
             /* Go to next Entry */
             CurrentEntry = CurrentEntry->Flink;
@@ -110,93 +111,6 @@
     }
 }
 
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-IoSetIoCompletion(IN PVOID IoCompletion,
-                  IN PVOID KeyContext,
-                  IN PVOID ApcContext,
-                  IN NTSTATUS IoStatus,
-                  IN ULONG_PTR IoStatusInformation,
-                  IN BOOLEAN Quota)
-{
-    PKQUEUE Queue = (PKQUEUE)IoCompletion;
-    PNPAGED_LOOKASIDE_LIST List;
-    PKPRCB Prcb = KeGetCurrentPrcb();
-    PIO_COMPLETION_PACKET Packet;
-
-    /* Get the P List */
-    List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].P;
-    
-    /* Try to allocate the Packet */
-    List->L.TotalAllocates++;
-    Packet = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
-    
-    /* Check if that failed, use the L list if it did */
-    if (!Packet)
-    {
-        /* Let the balancer know */
-        List->L.AllocateMisses++;
-        
-        /* Get L List */
-        List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].L;
-    
-        /* Try to allocate the Packet */
-        List->L.TotalAllocates++;
-        Packet = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
-    }
-    
-    /* Still failed, use pool */
-    if (!Packet)
-    {
-        /* Let the balancer know */
-        List->L.AllocateMisses++;
-        
-        /* Allocate from Nonpaged Pool */
-        Packet = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Packet), IOC_TAG);
-    }
-    
-    /* Make sure we have one by now... */
-    if (Packet)
-    {
-        /* Set up the Packet */
-        Packet->PacketType = IrpMiniCompletionPacket;
-        Packet->Key = KeyContext;
-        Packet->Context = ApcContext;
-        Packet->IoStatus.Status = IoStatus;
-        Packet->IoStatus.Information = IoStatusInformation;
-
-        /* Insert the Queue */
-        KeInsertQueue(Queue, &Packet->ListEntry);
-    }
-    else
-    {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* Return Success */
-    return STATUS_SUCCESS;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject,
-                         IN PIRP Irp,
-                         IN PIO_COMPLETION_ROUTINE CompletionRoutine,
-                         IN PVOID Context,
-                         IN BOOLEAN InvokeOnSuccess,
-                         IN BOOLEAN InvokeOnError,
-                         IN BOOLEAN InvokeOnCancel)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
 VOID
 FASTCALL
 IopInitIoCompletionImplementation(VOID)
@@ -204,8 +118,6 @@
     OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
     UNICODE_STRING Name;
 
-    DPRINT("Creating IoCompletion Object Type\n");
-  
     /* Initialize the Driver object type  */
     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
     RtlInitUnicodeString(&Name, L"IoCompletion");
@@ -219,34 +131,129 @@
     ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoCompletionType);
 }
 
-NTSTATUS
-STDCALL
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IoSetIoCompletion(IN PVOID IoCompletion,
+                  IN PVOID KeyContext,
+                  IN PVOID ApcContext,
+                  IN NTSTATUS IoStatus,
+                  IN ULONG_PTR IoStatusInformation,
+                  IN BOOLEAN Quota)
+{
+    PKQUEUE Queue = (PKQUEUE)IoCompletion;
+    PNPAGED_LOOKASIDE_LIST List;
+    PKPRCB Prcb = KeGetCurrentPrcb();
+    PIO_COMPLETION_PACKET Packet;
+
+    /* Get the P List */
+    List = (PNPAGED_LOOKASIDE_LIST)Prcb->
+            PPLookasideList[LookasideCompletionList].P;
+
+    /* Try to allocate the Packet */
+    List->L.TotalAllocates++;
+    Packet = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
+
+    /* Check if that failed, use the L list if it did */
+    if (!Packet)
+    {
+        /* Let the balancer know */
+        List->L.AllocateMisses++;
+
+        /* Get L List */
+        List = (PNPAGED_LOOKASIDE_LIST)Prcb->
+                PPLookasideList[LookasideCompletionList].L;
+
+        /* Try to allocate the Packet */
+        List->L.TotalAllocates++;
+        Packet = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
+    }
+
+    /* Still failed, use pool */
+    if (!Packet)
+    {
+        /* Let the balancer know */
+        List->L.AllocateMisses++;
+
+        /* Allocate from Nonpaged Pool */
+        Packet = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Packet), IOC_TAG);
+    }
+
+    /* Make sure we have one by now... */
+    if (Packet)
+    {
+        /* Set up the Packet */
+        Packet->PacketType = IrpMiniCompletionPacket;
+        Packet->Key = KeyContext;
+        Packet->Context = ApcContext;
+        Packet->IoStatus.Status = IoStatus;
+        Packet->IoStatus.Information = IoStatusInformation;
+
+        /* Insert the Queue */
+        KeInsertQueue(Queue, &Packet->ListEntry);
+    }
+    else
+    {
+        /* Out of memory, fail */
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Return Success */
+    return STATUS_SUCCESS;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject,
+                         IN PIRP Irp,
+                         IN PIO_COMPLETION_ROUTINE CompletionRoutine,
+                         IN PVOID Context,
+                         IN BOOLEAN InvokeOnSuccess,
+                         IN BOOLEAN InvokeOnError,
+                         IN BOOLEAN InvokeOnCancel)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
 NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle,
-                     IN  ACCESS_MASK DesiredAccess,
-                     IN  POBJECT_ATTRIBUTES ObjectAttributes,
-                     IN  ULONG NumberOfConcurrentThreads)
+                     IN ACCESS_MASK DesiredAccess,
+                     IN POBJECT_ATTRIBUTES ObjectAttributes,
+                     IN ULONG NumberOfConcurrentThreads)
 {
     PKQUEUE Queue;
     HANDLE hIoCompletionHandle;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-
     PAGED_CODE();
 
-    if (PreviousMode != KernelMode) {
-
-        _SEH_TRY {
-
+    /* Check if this was a user-mode call */
+    if (PreviousMode != KernelMode)
+    {
+        /* Wrap probing in SEH */
+        _SEH_TRY
+        {
+            /* Probe the handle */
             ProbeForWriteHandle(IoCompletionHandle);
-        } _SEH_HANDLE {
-
+        }
+        _SEH_HANDLE
+        {
+            /* Get the exception code */
             Status = _SEH_GetExceptionCode();
-        } _SEH_END;
-
-        if (!NT_SUCCESS(Status)) {
-
-            return Status;
-        }
+        }
+        _SEH_END;
+
+        /* Fail on exception */
+        if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Create the Object */
@@ -259,10 +266,8 @@
                             0,
                             0,
                             (PVOID*)&Queue);
-
-    /* Check for success */
-    if (NT_SUCCESS(Status)) {
-
+    if (NT_SUCCESS(Status))
+    {
         /* Initialize the Queue */
         KeInitializeQueue(Queue, NumberOfConcurrentThreads);
 
@@ -273,16 +278,20 @@
                                 0,
                                 NULL,
                                 &hIoCompletionHandle);
-
-        if (NT_SUCCESS(Status)) {
-
-            _SEH_TRY {
-
+        if (NT_SUCCESS(Status))
+        {
+            /* Protect writing the handle in SEH */
+            _SEH_TRY
+            {
+                /* Write the handle back */
                 *IoCompletionHandle = hIoCompletionHandle;
-            } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+            }
+            _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+            {
+                /* Get the exception code */
                 Status = _SEH_GetExceptionCode();
-            } _SEH_END;
+            }
+            _SEH_END;
         }
    }
 
@@ -291,7 +300,7 @@
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 NtOpenIoCompletion(OUT PHANDLE IoCompletionHandle,
                    IN ACCESS_MASK DesiredAccess,
                    IN POBJECT_ATTRIBUTES ObjectAttributes)
@@ -299,23 +308,26 @@
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     HANDLE hIoCompletionHandle;
     NTSTATUS Status = STATUS_SUCCESS;
-
     PAGED_CODE();
 
-    if(PreviousMode != KernelMode) {
-
-        _SEH_TRY {
-
+    /* Check if this was a user-mode call */
+    if (PreviousMode != KernelMode)
+    {
+        /* Wrap probing in SEH */
+        _SEH_TRY
+        {
+            /* Probe the handle */
             ProbeForWriteHandle(IoCompletionHandle);
-        } _SEH_HANDLE {
-
+        }
+        _SEH_HANDLE
+        {
+            /* Get the exception code */
             Status = _SEH_GetExceptionCode();
-        } _SEH_END;
-
-        if(!NT_SUCCESS(Status)) {
-
-            return Status;
-        }
+        }
+        _SEH_END;
+
+        /* Fail on exception */
+        if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Open the Object */
@@ -326,25 +338,28 @@
                                 DesiredAccess,
                                 NULL,
                                 &hIoCompletionHandle);
-
-    if (NT_SUCCESS(Status)) {
-
-        _SEH_TRY {
-
+    if (NT_SUCCESS(Status))
+    {
+        /* Protect writing the handle in SEH */
+        _SEH_TRY
+        {
+            /* Write the handle back */
             *IoCompletionHandle = hIoCompletionHandle;
-        } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
+            /* Get the exception code */
             Status = _SEH_GetExceptionCode();
-        } _SEH_END;
+        }
+        _SEH_END;
     }
 
     /* Return Status */
     return Status;
 }
 
-
-NTSTATUS
-STDCALL
+NTSTATUS
+NTAPI
 NtQueryIoCompletion(IN  HANDLE IoCompletionHandle,
                     IN  IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
                     OUT PVOID IoCompletionInformation,
@@ -354,22 +369,18 @@
     PKQUEUE Queue;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-
     PAGED_CODE();
 
     /* Check buffers and parameters */
     Status = DefaultQueryInfoBufferCheck(IoCompletionInformationClass,
                                          IoCompletionInfoClass,
-                                         sizeof(IoCompletionInfoClass) / sizeof(IoCompletionInfoClass[0]),
+                                         sizeof(IoCompletionInfoClass) /
+                                         sizeof(IoCompletionInfoClass[0]),
                                          IoCompletionInformation,
                                          IoCompletionInformationLength,
                                          ResultLength,
                                          PreviousMode);
-    if(!NT_SUCCESS(Status)) {
-
-        DPRINT1("NtQueryMutant() failed, Status: 0x%x\n", Status);
-        return Status;
-    }
+    if (!NT_SUCCESS(Status)) return Status;
 
     /* Get the Object */
     Status = ObReferenceObjectByHandle(IoCompletionHandle,
@@ -378,41 +389,43 @@
                                        PreviousMode,
                                        (PVOID*)&Queue,
                                        NULL);
-
-    /* Check for Success */
-   if (NT_SUCCESS(Status)) {
-
-        _SEH_TRY {
-
+    if (NT_SUCCESS(Status))
+    {
+        /* Protect write in SEH */
+        _SEH_TRY
+        {
             /* Return Info */
-            ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->Depth = KeReadStateQueue(Queue);
+            ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->
+                Depth = KeReadStateQueue(Queue);
+
+            /* Dereference the queue */
             ObDereferenceObject(Queue);
 
             /* Return Result Length if needed */
-            if (ResultLength) {
-
+            if (ResultLength)
+            {
                 *ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
             }
-        } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
+            /* Get exception code */
             Status = _SEH_GetExceptionCode();
-        } _SEH_END;
+        }
+        _SEH_END;
     }
 
     /* Return Status */
     return Status;
 }
 
-/*
- * Dequeues an I/O completion message from an I/O completion object
- */
-NTSTATUS
-STDCALL
-NtRemoveIoCompletion(IN  HANDLE IoCompletionHandle,
-                     OUT PVOID *CompletionKey,
-                     OUT PVOID *CompletionContext,
+NTSTATUS
+NTAPI
+NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
+                     OUT PVOID *KeyContext,
+                     OUT PVOID *ApcContext,
                      OUT PIO_STATUS_BLOCK IoStatusBlock,
-                     IN  PLARGE_INTEGER Timeout OPTIONAL)
+                     IN PLARGE_INTEGER Timeout OPTIONAL)
 {
     LARGE_INTEGER SafeTimeout;
     PKQUEUE Queue;
@@ -420,32 +433,41 @@
     PLIST_ENTRY ListEntry;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
-
+    PIRP Irp;
+    PVOID Apc, Key;
+    IO_STATUS_BLOCK IoStatus;
     PAGED_CODE();
 
-    if (PreviousMode != KernelMode) {
-
-        _SEH_TRY {
-
-            ProbeForWritePointer(CompletionKey);
-            ProbeForWritePointer(CompletionContext);
+    /* Check if the call was from user mode */
+    if (PreviousMode != KernelMode)
+    {
+        /* Protect probes in SEH */
+        _SEH_TRY
+        {
+            /* Probe the pointers */
+            ProbeForWritePointer(KeyContext);
+            ProbeForWritePointer(ApcContext);
+
+            /* Probe the I/O Status Block */
             ProbeForWrite(IoStatusBlock,
                           sizeof(IO_STATUS_BLOCK),
                           sizeof(ULONG));
-            if (Timeout != NULL) {
-
+            if (Timeout)
+            {
+                /* Probe and capture the timeout */
                 SafeTimeout = ProbeForReadLargeInteger(Timeout);
                 Timeout = &SafeTimeout;
             }
-        } _SEH_HANDLE {
-
+        }
+        _SEH_HANDLE
+        {
+            /* Get the exception code */
             Status = _SEH_GetExceptionCode();
-        } _SEH_END;
-
-        if (!NT_SUCCESS(Status)) {
-
-            return Status;
-        }
+        }
+        _SEH_END;
+
+        /* Fail on exception */
+        if (!NT_SUCCESS(Status)) return Status;
     }
 
     /* Open the Object */
@@ -455,57 +477,66 @@
                                        PreviousMode,
                                        (PVOID*)&Queue,
                                        NULL);
-
-    /* Check for success */
-    if (NT_SUCCESS(Status)) {
-
+    if (NT_SUCCESS(Status))
+    {
         /* Remove queue */
         ListEntry = KeRemoveQueue(Queue, PreviousMode, Timeout);
 
         /* If we got a timeout or user_apc back, return the status */
-        if ((NTSTATUS)ListEntry == STATUS_TIMEOUT || (NTSTATUS)ListEntry == STATUS_USER_APC) {
-
+        if (((NTSTATUS)ListEntry == STATUS_TIMEOUT) ||
+            ((NTSTATUS)ListEntry == STATUS_USER_APC))
+        {
+            /* Set this as the status */
             Status = (NTSTATUS)ListEntry;
-
-        } else {
-
+        }
+        else
+        {
             /* Get the Packet Data */
-            Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
+            Packet = CONTAINING_RECORD(ListEntry,
+                                       IO_COMPLETION_PACKET,
+                                       ListEntry);
 
             /* Check if this is piggybacked on an IRP */
             if (Packet->PacketType == IrpCompletionPacket)
             {
                 /* Get the IRP */
-                PIRP Irp = NULL;
-                Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
-                
-                /* Return values to user */
-                _SEH_TRY {
-
-                    *CompletionKey = Irp->Tail.CompletionKey;
-                    *CompletionContext = Irp->Overlay.AsynchronousParameters.UserApcContext;
-                    *IoStatusBlock = Packet->IoStatus;
-                } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
-                    Status = _SEH_GetExceptionCode();
-                } _SEH_END;
-
+                Irp = CONTAINING_RECORD(ListEntry,
+                                        IRP,
+                                        Tail.Overlay.ListEntry);
+
+                /* Save values */
+                Key = Irp->Tail.CompletionKey;
+                Apc = Irp->Overlay.AsynchronousParameters.UserApcContext;
+                IoStatus = Irp->IoStatus;
+
+                /* Free the IRP */
                 IoFreeIrp(Irp);
             }
             else
             {
-                /* This is a user-mode generated or API generated mini-packet */
-                _SEH_TRY {
-
-                    *CompletionKey = Packet->Key;
-                    *CompletionContext = Packet->Context;
-                    *IoStatusBlock = Packet->IoStatus;
-                } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-                    Status = _SEH_GetExceptionCode();
-                } _SEH_END;
-
+                /* Save values */
+                Key = Packet->Key;
+                Apc = Packet->Context;
+                IoStatus = Packet->IoStatus;
+
+                /* Free the packet */
                 IopFreeIoCompletionPacket(Packet);
             }
+
+            /* Enter SEH to write back the values */
+            _SEH_TRY
+            {
+                /* Write the values to caller */
+                *ApcContext = Apc;
+                *KeyContext = Key;
+                *IoStatusBlock = IoStatus;
+            }
+            _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+            {
+                /* Get the exception code */
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
         }
 
         /* Dereference the Object */
@@ -516,11 +547,8 @@
     return Status;
 }
 
-/*
- * Queues an I/O completion message to an I/O completion object
- */
-NTSTATUS
-STDCALL
+NTSTATUS
+NTAPI
 NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
                   IN PVOID CompletionKey,
                   IN PVOID CompletionContext,
@@ -529,7 +557,6 @@
 {
     NTSTATUS Status;
     PKQUEUE Queue;
-
     PAGED_CODE();
 
     /* Get the Object */
@@ -539,10 +566,8 @@
                                        ExGetPreviousMode(),
                                        (PVOID*)&Queue,
                                        NULL);
-
-    /* Check for Success */
-    if (NT_SUCCESS(Status)) {
-
+    if (NT_SUCCESS(Status))
+    {
         /* Set the Completion */
         Status = IoSetIoCompletion(Queue,
                                    CompletionKey,
@@ -550,6 +575,8 @@
                                    CompletionStatus,
                                    CompletionInformation,
                                    TRUE);
+
+        /* Dereference the object */
         ObDereferenceObject(Queue);
     }
 




More information about the Ros-diffs mailing list