📄 iocomp.c
字号:
if (NT_SUCCESS(Status))
{
/* Protect writing the handle in SEH */
_SEH_TRY
{
/* Write the handle back */
*IoCompletionHandle = hIoCompletionHandle;
}
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
}
/* Return Status */
return Status;
}
NTSTATUS
NTAPI
NtOpenIoCompletion(OUT PHANDLE IoCompletionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
HANDLE hIoCompletionHandle;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
/* Check if this was a user-mode call */
if (PreviousMode != KernelMode)
{
/* Wrap probing in SEH */
_SEH_TRY
{
/* Probe the handle */
ProbeForWriteHandle(IoCompletionHandle);
}
_SEH_HANDLE
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* Fail on exception */
if (!NT_SUCCESS(Status)) return Status;
}
/* Open the Object */
Status = ObOpenObjectByName(ObjectAttributes,
IoCompletionType,
PreviousMode,
NULL,
DesiredAccess,
NULL,
&hIoCompletionHandle);
if (NT_SUCCESS(Status))
{
/* Protect writing the handle in SEH */
_SEH_TRY
{
/* Write the handle back */
*IoCompletionHandle = hIoCompletionHandle;
}
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
/* Return Status */
return Status;
}
NTSTATUS
NTAPI
NtQueryIoCompletion(IN HANDLE IoCompletionHandle,
IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
OUT PVOID IoCompletionInformation,
IN ULONG IoCompletionInformationLength,
OUT PULONG ResultLength OPTIONAL)
{
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]),
IoCompletionInformation,
IoCompletionInformationLength,
ResultLength,
PreviousMode);
if (!NT_SUCCESS(Status)) return Status;
/* Get the Object */
Status = ObReferenceObjectByHandle(IoCompletionHandle,
IO_COMPLETION_QUERY_STATE,
IoCompletionType,
PreviousMode,
(PVOID*)&Queue,
NULL);
if (NT_SUCCESS(Status))
{
/* Protect write in SEH */
_SEH_TRY
{
/* Return Info */
((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->
Depth = KeReadStateQueue(Queue);
/* Dereference the queue */
ObDereferenceObject(Queue);
/* Return Result Length if needed */
if (ResultLength)
{
*ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
}
}
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
/* Get exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
/* Return Status */
return Status;
}
NTSTATUS
NTAPI
NtRemoveIoCompletion(IN HANDLE IoCompletionHandle,
OUT PVOID *KeyContext,
OUT PVOID *ApcContext,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER Timeout OPTIONAL)
{
LARGE_INTEGER SafeTimeout;
PKQUEUE Queue;
PIO_COMPLETION_PACKET Packet;
PLIST_ENTRY ListEntry;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
PIRP Irp;
PVOID Apc, Key;
IO_STATUS_BLOCK IoStatus;
PAGED_CODE();
/* 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 */
ProbeForWriteIoStatusBlock(IoStatusBlock);
if (Timeout)
{
/* Probe and capture the timeout */
SafeTimeout = ProbeForReadLargeInteger(Timeout);
Timeout = &SafeTimeout;
}
}
_SEH_HANDLE
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* Fail on exception */
if (!NT_SUCCESS(Status)) return Status;
}
/* Open the Object */
Status = ObReferenceObjectByHandle(IoCompletionHandle,
IO_COMPLETION_MODIFY_STATE,
IoCompletionType,
PreviousMode,
(PVOID*)&Queue,
NULL);
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))
{
/* Set this as the status */
Status = (NTSTATUS)ListEntry;
}
else
{
/* Get the Packet Data */
Packet = CONTAINING_RECORD(ListEntry,
IO_COMPLETION_PACKET,
ListEntry);
/* Check if this is piggybacked on an IRP */
if (Packet->PacketType == IrpCompletionPacket)
{
/* Get the IRP */
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
{
/* 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 */
ObDereferenceObject(Queue);
}
/* Return status */
return Status;
}
NTSTATUS
NTAPI
NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
IN PVOID CompletionKey,
IN PVOID CompletionContext,
IN NTSTATUS CompletionStatus,
IN ULONG CompletionInformation)
{
NTSTATUS Status;
PKQUEUE Queue;
PAGED_CODE();
/* Get the Object */
Status = ObReferenceObjectByHandle(IoCompletionPortHandle,
IO_COMPLETION_MODIFY_STATE,
IoCompletionType,
ExGetPreviousMode(),
(PVOID*)&Queue,
NULL);
if (NT_SUCCESS(Status))
{
/* Set the Completion */
Status = IoSetIoCompletion(Queue,
CompletionKey,
CompletionContext,
CompletionStatus,
CompletionInformation,
TRUE);
/* Dereference the object */
ObDereferenceObject(Queue);
}
/* Return status */
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -