mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- 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. svn path=/trunk/; revision=22721
This commit is contained in:
parent
cabeb71d14
commit
b42accc93a
1 changed files with 225 additions and 198 deletions
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* PROJECT: ReactOS Kernel
|
||||||
* PROJECT: ReactOS kernel
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: ntoskrnl/io/iocomp.c
|
* FILE: ntoskrnl/io/event.c
|
||||||
* PURPOSE: No purpose listed.
|
* PURPOSE: I/O Wrappers for the Executive Event Functions
|
||||||
*
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
* Thomas Weidenmueller (w3seek@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -17,7 +17,7 @@ POBJECT_TYPE IoCompletionType;
|
||||||
|
|
||||||
NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
|
NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
|
||||||
|
|
||||||
static GENERIC_MAPPING IopCompletionMapping =
|
GENERIC_MAPPING IopCompletionMapping =
|
||||||
{
|
{
|
||||||
STANDARD_RIGHTS_READ | IO_COMPLETION_QUERY_STATE,
|
STANDARD_RIGHTS_READ | IO_COMPLETION_QUERY_STATE,
|
||||||
STANDARD_RIGHTS_WRITE | IO_COMPLETION_MODIFY_STATE,
|
STANDARD_RIGHTS_WRITE | IO_COMPLETION_MODIFY_STATE,
|
||||||
|
@ -25,23 +25,24 @@ static GENERIC_MAPPING IopCompletionMapping =
|
||||||
IO_COMPLETION_ALL_ACCESS
|
IO_COMPLETION_ALL_ACCESS
|
||||||
};
|
};
|
||||||
|
|
||||||
static const INFORMATION_CLASS_INFO IoCompletionInfoClass[] = {
|
static const INFORMATION_CLASS_INFO IoCompletionInfoClass[] =
|
||||||
|
{
|
||||||
/* IoCompletionBasicInformation */
|
/* 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
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
|
IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
|
||||||
{
|
{
|
||||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||||
PNPAGED_LOOKASIDE_LIST List;
|
PNPAGED_LOOKASIDE_LIST List;
|
||||||
|
|
||||||
/* Use the P List */
|
/* Use the P List */
|
||||||
List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].P;
|
List = (PNPAGED_LOOKASIDE_LIST)Prcb->
|
||||||
|
PPLookasideList[LookasideCompletionList].P;
|
||||||
List->L.TotalFrees++;
|
List->L.TotalFrees++;
|
||||||
|
|
||||||
/* Check if the Free was within the Depth or not */
|
/* Check if the Free was within the Depth or not */
|
||||||
|
@ -51,7 +52,8 @@ IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
|
||||||
List->L.FreeMisses++;
|
List->L.FreeMisses++;
|
||||||
|
|
||||||
/* Use the L List */
|
/* Use the L List */
|
||||||
List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].L;
|
List = (PNPAGED_LOOKASIDE_LIST)Prcb->
|
||||||
|
PPLookasideList[LookasideCompletionList].L;
|
||||||
List->L.TotalFrees++;
|
List->L.TotalFrees++;
|
||||||
|
|
||||||
/* Check if the Free was within the Depth or not */
|
/* Check if the Free was within the Depth or not */
|
||||||
|
@ -68,7 +70,7 @@ IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
IopDeleteIoCompletion(PVOID ObjectBody)
|
IopDeleteIoCompletion(PVOID ObjectBody)
|
||||||
{
|
{
|
||||||
PKQUEUE Queue = ObjectBody;
|
PKQUEUE Queue = ObjectBody;
|
||||||
|
@ -77,19 +79,18 @@ IopDeleteIoCompletion(PVOID ObjectBody)
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
PIO_COMPLETION_PACKET Packet;
|
PIO_COMPLETION_PACKET Packet;
|
||||||
|
|
||||||
DPRINT("IopDeleteIoCompletion()\n");
|
|
||||||
|
|
||||||
/* Rundown the Queue */
|
/* Rundown the Queue */
|
||||||
FirstEntry = KeRundownQueue(Queue);
|
FirstEntry = KeRundownQueue(Queue);
|
||||||
|
if (FirstEntry)
|
||||||
/* Clean up the IRPs */
|
{
|
||||||
if (FirstEntry) {
|
/* Loop the packets */
|
||||||
|
|
||||||
CurrentEntry = FirstEntry;
|
CurrentEntry = FirstEntry;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
/* Get the Packet */
|
/* Get the Packet */
|
||||||
Packet = CONTAINING_RECORD(CurrentEntry, IO_COMPLETION_PACKET, ListEntry);
|
Packet = CONTAINING_RECORD(CurrentEntry,
|
||||||
|
IO_COMPLETION_PACKET,
|
||||||
|
ListEntry);
|
||||||
|
|
||||||
/* Go to next Entry */
|
/* Go to next Entry */
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
@ -110,11 +111,33 @@ IopDeleteIoCompletion(PVOID ObjectBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
IopInitIoCompletionImplementation(VOID)
|
||||||
|
{
|
||||||
|
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
|
||||||
|
/* Initialize the Driver object type */
|
||||||
|
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
||||||
|
RtlInitUnicodeString(&Name, L"IoCompletion");
|
||||||
|
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
||||||
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KQUEUE);
|
||||||
|
ObjectTypeInitializer.PoolType = NonPagedPool;
|
||||||
|
ObjectTypeInitializer.ValidAccessMask = IO_COMPLETION_ALL_ACCESS;
|
||||||
|
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
||||||
|
ObjectTypeInitializer.GenericMapping = IopCompletionMapping;
|
||||||
|
ObjectTypeInitializer.DeleteProcedure = IopDeleteIoCompletion;
|
||||||
|
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoCompletionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
IoSetIoCompletion(IN PVOID IoCompletion,
|
IoSetIoCompletion(IN PVOID IoCompletion,
|
||||||
IN PVOID KeyContext,
|
IN PVOID KeyContext,
|
||||||
IN PVOID ApcContext,
|
IN PVOID ApcContext,
|
||||||
|
@ -128,7 +151,8 @@ IoSetIoCompletion(IN PVOID IoCompletion,
|
||||||
PIO_COMPLETION_PACKET Packet;
|
PIO_COMPLETION_PACKET Packet;
|
||||||
|
|
||||||
/* Get the P List */
|
/* Get the P List */
|
||||||
List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].P;
|
List = (PNPAGED_LOOKASIDE_LIST)Prcb->
|
||||||
|
PPLookasideList[LookasideCompletionList].P;
|
||||||
|
|
||||||
/* Try to allocate the Packet */
|
/* Try to allocate the Packet */
|
||||||
List->L.TotalAllocates++;
|
List->L.TotalAllocates++;
|
||||||
|
@ -141,7 +165,8 @@ IoSetIoCompletion(IN PVOID IoCompletion,
|
||||||
List->L.AllocateMisses++;
|
List->L.AllocateMisses++;
|
||||||
|
|
||||||
/* Get L List */
|
/* Get L List */
|
||||||
List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[LookasideCompletionList].L;
|
List = (PNPAGED_LOOKASIDE_LIST)Prcb->
|
||||||
|
PPLookasideList[LookasideCompletionList].L;
|
||||||
|
|
||||||
/* Try to allocate the Packet */
|
/* Try to allocate the Packet */
|
||||||
List->L.TotalAllocates++;
|
List->L.TotalAllocates++;
|
||||||
|
@ -173,6 +198,7 @@ IoSetIoCompletion(IN PVOID IoCompletion,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Out of memory, fail */
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +210,7 @@ IoSetIoCompletion(IN PVOID IoCompletion,
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject,
|
IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp,
|
IN PIRP Irp,
|
||||||
IN PIO_COMPLETION_ROUTINE CompletionRoutine,
|
IN PIO_COMPLETION_ROUTINE CompletionRoutine,
|
||||||
|
@ -197,30 +223,8 @@ IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject,
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
FASTCALL
|
|
||||||
IopInitIoCompletionImplementation(VOID)
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
|
||||||
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KQUEUE);
|
|
||||||
ObjectTypeInitializer.PoolType = NonPagedPool;
|
|
||||||
ObjectTypeInitializer.ValidAccessMask = IO_COMPLETION_ALL_ACCESS;
|
|
||||||
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
|
||||||
ObjectTypeInitializer.GenericMapping = IopCompletionMapping;
|
|
||||||
ObjectTypeInitializer.DeleteProcedure = IopDeleteIoCompletion;
|
|
||||||
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoCompletionType);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle,
|
NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
@ -230,23 +234,26 @@ NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle,
|
||||||
HANDLE hIoCompletionHandle;
|
HANDLE hIoCompletionHandle;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if (PreviousMode != KernelMode) {
|
/* Check if this was a user-mode call */
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
_SEH_TRY {
|
{
|
||||||
|
/* Wrap probing in SEH */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Probe the handle */
|
||||||
ProbeForWriteHandle(IoCompletionHandle);
|
ProbeForWriteHandle(IoCompletionHandle);
|
||||||
} _SEH_HANDLE {
|
|
||||||
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
} _SEH_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status)) {
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Fail on exception */
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the Object */
|
/* Create the Object */
|
||||||
|
@ -259,10 +266,8 @@ NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&Queue);
|
(PVOID*)&Queue);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
/* Check for success */
|
{
|
||||||
if (NT_SUCCESS(Status)) {
|
|
||||||
|
|
||||||
/* Initialize the Queue */
|
/* Initialize the Queue */
|
||||||
KeInitializeQueue(Queue, NumberOfConcurrentThreads);
|
KeInitializeQueue(Queue, NumberOfConcurrentThreads);
|
||||||
|
|
||||||
|
@ -273,16 +278,20 @@ NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
&hIoCompletionHandle);
|
&hIoCompletionHandle);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
if (NT_SUCCESS(Status)) {
|
{
|
||||||
|
/* Protect writing the handle in SEH */
|
||||||
_SEH_TRY {
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Write the handle back */
|
||||||
*IoCompletionHandle = hIoCompletionHandle;
|
*IoCompletionHandle = hIoCompletionHandle;
|
||||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
} _SEH_END;
|
}
|
||||||
|
_SEH_END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +300,7 @@ NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
NtOpenIoCompletion(OUT PHANDLE IoCompletionHandle,
|
NtOpenIoCompletion(OUT PHANDLE IoCompletionHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
||||||
|
@ -299,23 +308,26 @@ NtOpenIoCompletion(OUT PHANDLE IoCompletionHandle,
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
HANDLE hIoCompletionHandle;
|
HANDLE hIoCompletionHandle;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if(PreviousMode != KernelMode) {
|
/* Check if this was a user-mode call */
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
_SEH_TRY {
|
{
|
||||||
|
/* Wrap probing in SEH */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Probe the handle */
|
||||||
ProbeForWriteHandle(IoCompletionHandle);
|
ProbeForWriteHandle(IoCompletionHandle);
|
||||||
} _SEH_HANDLE {
|
|
||||||
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
} _SEH_END;
|
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status)) {
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Fail on exception */
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the Object */
|
/* Open the Object */
|
||||||
|
@ -326,25 +338,28 @@ NtOpenIoCompletion(OUT PHANDLE IoCompletionHandle,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
NULL,
|
NULL,
|
||||||
&hIoCompletionHandle);
|
&hIoCompletionHandle);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
if (NT_SUCCESS(Status)) {
|
{
|
||||||
|
/* Protect writing the handle in SEH */
|
||||||
_SEH_TRY {
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Write the handle back */
|
||||||
*IoCompletionHandle = hIoCompletionHandle;
|
*IoCompletionHandle = hIoCompletionHandle;
|
||||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
} _SEH_END;
|
}
|
||||||
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return Status */
|
/* Return Status */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
NtQueryIoCompletion(IN HANDLE IoCompletionHandle,
|
NtQueryIoCompletion(IN HANDLE IoCompletionHandle,
|
||||||
IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
|
IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
|
||||||
OUT PVOID IoCompletionInformation,
|
OUT PVOID IoCompletionInformation,
|
||||||
|
@ -354,22 +369,18 @@ NtQueryIoCompletion(IN HANDLE IoCompletionHandle,
|
||||||
PKQUEUE Queue;
|
PKQUEUE Queue;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Check buffers and parameters */
|
/* Check buffers and parameters */
|
||||||
Status = DefaultQueryInfoBufferCheck(IoCompletionInformationClass,
|
Status = DefaultQueryInfoBufferCheck(IoCompletionInformationClass,
|
||||||
IoCompletionInfoClass,
|
IoCompletionInfoClass,
|
||||||
sizeof(IoCompletionInfoClass) / sizeof(IoCompletionInfoClass[0]),
|
sizeof(IoCompletionInfoClass) /
|
||||||
|
sizeof(IoCompletionInfoClass[0]),
|
||||||
IoCompletionInformation,
|
IoCompletionInformation,
|
||||||
IoCompletionInformationLength,
|
IoCompletionInformationLength,
|
||||||
ResultLength,
|
ResultLength,
|
||||||
PreviousMode);
|
PreviousMode);
|
||||||
if(!NT_SUCCESS(Status)) {
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
DPRINT1("NtQueryMutant() failed, Status: 0x%x\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the Object */
|
/* Get the Object */
|
||||||
Status = ObReferenceObjectByHandle(IoCompletionHandle,
|
Status = ObReferenceObjectByHandle(IoCompletionHandle,
|
||||||
|
@ -378,39 +389,41 @@ NtQueryIoCompletion(IN HANDLE IoCompletionHandle,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&Queue,
|
(PVOID*)&Queue,
|
||||||
NULL);
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
/* Check for Success */
|
{
|
||||||
if (NT_SUCCESS(Status)) {
|
/* Protect write in SEH */
|
||||||
|
_SEH_TRY
|
||||||
_SEH_TRY {
|
{
|
||||||
|
|
||||||
/* Return Info */
|
/* Return Info */
|
||||||
((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->Depth = KeReadStateQueue(Queue);
|
((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->
|
||||||
|
Depth = KeReadStateQueue(Queue);
|
||||||
|
|
||||||
|
/* Dereference the queue */
|
||||||
ObDereferenceObject(Queue);
|
ObDereferenceObject(Queue);
|
||||||
|
|
||||||
/* Return Result Length if needed */
|
/* Return Result Length if needed */
|
||||||
if (ResultLength) {
|
if (ResultLength)
|
||||||
|
{
|
||||||
*ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
|
*ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
|
||||||
}
|
}
|
||||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
} _SEH_END;
|
}
|
||||||
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return Status */
|
/* Return Status */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Dequeues an I/O completion message from an I/O completion object
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
|
NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
|
||||||
OUT PVOID *CompletionKey,
|
OUT PVOID *KeyContext,
|
||||||
OUT PVOID *CompletionContext,
|
OUT PVOID *ApcContext,
|
||||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
IN PLARGE_INTEGER Timeout OPTIONAL)
|
IN PLARGE_INTEGER Timeout OPTIONAL)
|
||||||
{
|
{
|
||||||
|
@ -420,32 +433,41 @@ NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PIRP Irp;
|
||||||
|
PVOID Apc, Key;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if (PreviousMode != KernelMode) {
|
/* Check if the call was from user mode */
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
/* Protect probes in SEH */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Probe the pointers */
|
||||||
|
ProbeForWritePointer(KeyContext);
|
||||||
|
ProbeForWritePointer(ApcContext);
|
||||||
|
|
||||||
_SEH_TRY {
|
/* Probe the I/O Status Block */
|
||||||
|
|
||||||
ProbeForWritePointer(CompletionKey);
|
|
||||||
ProbeForWritePointer(CompletionContext);
|
|
||||||
ProbeForWrite(IoStatusBlock,
|
ProbeForWrite(IoStatusBlock,
|
||||||
sizeof(IO_STATUS_BLOCK),
|
sizeof(IO_STATUS_BLOCK),
|
||||||
sizeof(ULONG));
|
sizeof(ULONG));
|
||||||
if (Timeout != NULL) {
|
if (Timeout)
|
||||||
|
{
|
||||||
|
/* Probe and capture the timeout */
|
||||||
SafeTimeout = ProbeForReadLargeInteger(Timeout);
|
SafeTimeout = ProbeForReadLargeInteger(Timeout);
|
||||||
Timeout = &SafeTimeout;
|
Timeout = &SafeTimeout;
|
||||||
}
|
}
|
||||||
} _SEH_HANDLE {
|
|
||||||
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
} _SEH_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status)) {
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Fail on exception */
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open the Object */
|
/* Open the Object */
|
||||||
|
@ -455,57 +477,66 @@ NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&Queue,
|
(PVOID*)&Queue,
|
||||||
NULL);
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
/* Check for success */
|
{
|
||||||
if (NT_SUCCESS(Status)) {
|
|
||||||
|
|
||||||
/* Remove queue */
|
/* Remove queue */
|
||||||
ListEntry = KeRemoveQueue(Queue, PreviousMode, Timeout);
|
ListEntry = KeRemoveQueue(Queue, PreviousMode, Timeout);
|
||||||
|
|
||||||
/* If we got a timeout or user_apc back, return the status */
|
/* 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;
|
Status = (NTSTATUS)ListEntry;
|
||||||
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
/* Get the Packet Data */
|
/* 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 */
|
/* Check if this is piggybacked on an IRP */
|
||||||
if (Packet->PacketType == IrpCompletionPacket)
|
if (Packet->PacketType == IrpCompletionPacket)
|
||||||
{
|
{
|
||||||
/* Get the IRP */
|
/* Get the IRP */
|
||||||
PIRP Irp = NULL;
|
Irp = CONTAINING_RECORD(ListEntry,
|
||||||
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
|
IRP,
|
||||||
|
Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
/* Return values to user */
|
/* Save values */
|
||||||
_SEH_TRY {
|
Key = Irp->Tail.CompletionKey;
|
||||||
|
Apc = Irp->Overlay.AsynchronousParameters.UserApcContext;
|
||||||
*CompletionKey = Irp->Tail.CompletionKey;
|
IoStatus = Irp->IoStatus;
|
||||||
*CompletionContext = Irp->Overlay.AsynchronousParameters.UserApcContext;
|
|
||||||
*IoStatusBlock = Packet->IoStatus;
|
|
||||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
|
||||||
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
} _SEH_END;
|
|
||||||
|
|
||||||
|
/* Free the IRP */
|
||||||
IoFreeIrp(Irp);
|
IoFreeIrp(Irp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* This is a user-mode generated or API generated mini-packet */
|
/* Save values */
|
||||||
_SEH_TRY {
|
Key = Packet->Key;
|
||||||
|
Apc = Packet->Context;
|
||||||
*CompletionKey = Packet->Key;
|
IoStatus = Packet->IoStatus;
|
||||||
*CompletionContext = Packet->Context;
|
|
||||||
*IoStatusBlock = Packet->IoStatus;
|
|
||||||
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
} _SEH_END;
|
|
||||||
|
|
||||||
|
/* Free the packet */
|
||||||
IopFreeIoCompletionPacket(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 */
|
/* Dereference the Object */
|
||||||
|
@ -516,11 +547,8 @@ NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Queues an I/O completion message to an I/O completion object
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
|
NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
|
||||||
IN PVOID CompletionKey,
|
IN PVOID CompletionKey,
|
||||||
IN PVOID CompletionContext,
|
IN PVOID CompletionContext,
|
||||||
|
@ -529,7 +557,6 @@ NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PKQUEUE Queue;
|
PKQUEUE Queue;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Get the Object */
|
/* Get the Object */
|
||||||
|
@ -539,10 +566,8 @@ NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
|
||||||
ExGetPreviousMode(),
|
ExGetPreviousMode(),
|
||||||
(PVOID*)&Queue,
|
(PVOID*)&Queue,
|
||||||
NULL);
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
/* Check for Success */
|
{
|
||||||
if (NT_SUCCESS(Status)) {
|
|
||||||
|
|
||||||
/* Set the Completion */
|
/* Set the Completion */
|
||||||
Status = IoSetIoCompletion(Queue,
|
Status = IoSetIoCompletion(Queue,
|
||||||
CompletionKey,
|
CompletionKey,
|
||||||
|
@ -550,6 +575,8 @@ NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
|
||||||
CompletionStatus,
|
CompletionStatus,
|
||||||
CompletionInformation,
|
CompletionInformation,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
|
/* Dereference the object */
|
||||||
ObDereferenceObject(Queue);
|
ObDereferenceObject(Queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue