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=2…
==============================================================================
--- 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(a)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(a)reactos.org)
+ * Thomas Weidenmueller (w3seek(a)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);
}