IoSetIoCompletionEx2
NTSTATUS __stdcall IoSetIoCompletionEx2(
PVOID IoCompletion,
PVOID KeyContext,
PVOID ApcContext,
INT64 IoStatus,
UINT64 IoStatusInformation,
UINT8 Quota,
_IO_MINI_COMPLETION_PACKET_USER *MiniPacket,
UINT8 Wait){
NTSTATUS v9;
int v10;
_QWORD *v14;
UINT8 OldIrql;
struct _KPRCB *CurrentPrcb;
__int64 v17;
__int64 v18;
BYTE *MiniCompletionPacket;
int v21;
_LIST_ENTRY *v22;
bool MiniPacketa;
v9 = 0;
v10 = IoStatus;
if( MiniPacket )
{
v14 = (char *)IoCompletion + 8;
MiniPacket->IoStatusInformation = IoStatusInformation;
MiniPacket->KeyContext = KeyContext;
MiniPacket->ApcContext = ApcContext;
MiniPacket->IoStatus = IoStatus;
OldIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
v17 = *((_QWORD *)CurrentPrcb + 1);
v18 = v17;
if( *(_QWORD *)(v17 + 1472) )
v18 = *(_QWORD *)(v17 + 1472);
MiniPacketa = Wait && *(_BYTE *)(*(_QWORD *)(v18 + 544) + 1850i64) == 2;
KiAcquireKobjectLockSafe(IoCompletion);
if( (_QWORD *)*v14 == v14
|| *((_DWORD *)IoCompletion + 10) >= *((_DWORD *)IoCompletion + 11) && !MiniPacketa
|| *(PVOID *)(v17 + 232) == IoCompletion && *(_BYTE *)(v17 + 643) == 15
|| !KiWakeQueueWaiter(CurrentPrcb, (_KQUEUE *)IoCompletion, (INT64)MiniPacket) )
{
v21 = *((_DWORD *)IoCompletion + 1);
*((_DWORD *)IoCompletion + 1) = v21 + 1;
v22 = (_LIST_ENTRY *)*((_QWORD *)IoCompletion + 4);
if( (char *)v22->Flink != (char *)IoCompletion + 24 )
__fastfail(3u);
MiniPacket->ListEntry.Flink = (_LIST_ENTRY *)((char *)IoCompletion + 24);
MiniPacket->ListEntry.Blink = v22;
v22->Flink = &MiniPacket->ListEntry;
*((_QWORD *)IoCompletion + 4) = MiniPacket;
if( !v21 && (_QWORD *)*v14 != v14 )
KiWakeOtherQueueWaiters(CurrentPrcb, (_KQUEUE *)IoCompletion);
}
_InterlockedAnd((volatile signed __int32 *)IoCompletion, 0xFFFFFF7F);
KiExitDispatcher(CurrentPrcb, Wait != 0 ? 3 : 0, AdjustUnwait, 0i64, OldIrql);
}
else
{
MiniCompletionPacket = IopAllocateMiniCompletionPacket(1, Quota);
if( MiniCompletionPacket )
{
*((_QWORD *)MiniCompletionPacket + 3) = KeyContext;
*((_QWORD *)MiniCompletionPacket + 4) = ApcContext;
*((_DWORD *)MiniCompletionPacket + 10) = v10;
*((_QWORD *)MiniCompletionPacket + 6) = IoStatusInformation;
KeInsertQueueEx((KQUEUE *)IoCompletion, (LIST_ENTRY *)MiniCompletionPacket, 0i64, Wait);
}
else
{
return -1073741670;
}
}
return v9;
}Referenced by:
AlpcpLookasidePacketCallbackRoutine
AlpcpQueueIoCompletionPort
AlpcpSignalAndWait
ExpShutdownWorkerFactory
ExpWorkerFactoryCompletionPacketRoutine
IoSetIoCompletion
NtSetIoCompletion