IoSetIoCompletionEx2
VOID __fastcall IoSetIoCompletionEx2(
VOID *IoCompletion,
VOID *KeyContext,
VOID *ApcContext,
INT64 IoStatus,
UINT64 IoStatusInformation,
UINT8 Quota,
_IO_MINI_COMPLETION_PACKET_USER *MiniPacket,
UINT8 Wait){
_IOP_MINI_COMPLETION_PACKET v9;
_QWORD *v13;
UINT8 OldIrql;
struct _KPRCB *CurrentPrcb;
_ETHREAD *CurrentThread;
_QWORD *WorkOnBehalfThread;
char v18;
_IOP_MINI_COMPLETION_PACKET *MiniCompletionPacket;
int v20;
_LIST_ENTRY *v21;
bool MiniPacketa;
v9 = IoStatus;
if( MiniPacket )
{
v13 = (char *)IoCompletion + 8;
MiniPacket->IoStatusInformation = IoStatusInformation;
MiniPacket->KeyContext = KeyContext;
MiniPacket->ApcContext = ApcContext;
MiniPacket->IoStatus = IoStatus;
OldIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
CurrentThread = CurrentPrcb->CurrentThread;
WorkOnBehalfThread = CurrentThread->Tcb.gap0;
if( CurrentThread->WorkOnBehalfThread )
WorkOnBehalfThread = CurrentThread->WorkOnBehalfThread;
MiniPacketa = Wait && *(_BYTE *)(WorkOnBehalfThread[68] + 1850i64) == 2;
KiAcquireKobjectLockSafe(IoCompletion);
if( (_QWORD *)*v13 == v13
|| *((_DWORD *)IoCompletion + 10) >= *((_DWORD *)IoCompletion + 11) && !MiniPacketa
|| CurrentThread->Tcb.Queue == IoCompletion && CurrentThread->Tcb.WaitReason == 15
|| (KiWakeQueueWaiter(CurrentPrcb, (_KQUEUE *)IoCompletion, (INT64)MiniPacket), !v18) )
{
v20 = *((_DWORD *)IoCompletion + 1);
*((_DWORD *)IoCompletion + 1) = v20 + 1;
v21 = (_LIST_ENTRY *)*((_QWORD *)IoCompletion + 4);
if( (char *)v21->Flink != (char *)IoCompletion + 24 )
__fastfail(3u);
MiniPacket->ListEntry.Flink = (_LIST_ENTRY *)((char *)IoCompletion + 24);
MiniPacket->ListEntry.Blink = v21;
v21->Flink = &MiniPacket->ListEntry;
*((_QWORD *)IoCompletion + 4) = MiniPacket;
if( !v20 && (_QWORD *)*v13 != v13 )
KiWakeOtherQueueWaiters(CurrentPrcb, (_KQUEUE *)IoCompletion);
}
_InterlockedAnd((volatile signed __int32 *)IoCompletion, 0xFFFFFF7F);
KiExitDispatcher(CurrentPrcb, Wait != 0 ? 3 : 0, AdjustUnwait, 0i64, OldIrql);
}
else
{
MiniCompletionPacket = IopAllocateMiniCompletionPacket(1u, Quota);
if( MiniCompletionPacket )
{
*((_QWORD *)MiniCompletionPacket + 3) = KeyContext;
*((_QWORD *)MiniCompletionPacket + 4) = ApcContext;
MiniCompletionPacket[10] = v9;
*((_QWORD *)MiniCompletionPacket + 6) = IoStatusInformation;
KeInsertQueueEx((_KQUEUE *)IoCompletion, (_LIST_ENTRY *)MiniCompletionPacket, 0i64, Wait);
}
}
}Referenced by:
AlpcpLookasidePacketCallbackRoutine
AlpcpQueueIoCompletionPort
AlpcpSignalAndWait
ExpShutdownWorkerFactory
ExpWorkerFactoryCompletionPacketRoutine
IoSetIoCompletion
NtSetIoCompletion