IoRemoveIoCompletion
NTSTATUS __fastcall IoRemoveIoCompletion(
UINT64 a1,
INT64 a2,
INT64 *a3,
UINT64 a4,
UINT64 *NumEntriesRemoved,
INT8 PreviousMode,
INT64 CapturedTimeout,
INT8 Alertable){
INT64 *v8;
INT64 v9;
unsigned int v10;
__int64 i;
INT64 v12;
char v13;
__int64 v14;
__int64 v15;
__int64 v16;
NTSTATUS result;
unsigned __int8 CurrentIrql;
NTSTATUS v19;
struct _KPRCB *v20;
INT64 v21;
int v22;
_EPROCESS *v23;
UINT64 Count;
unsigned __int8 v25;
__int64 v27;
__int128 v28;
unsigned int v29;
INT64 *v30;
struct _KPRCB *CurrentPrcb;
__int64 v32;
PVOID v33;
PVOID Object;
UINT64 v35;
INT64 v36;
INT64 *v37;
UINT64 *v38;
_KAPC_STATE ApcState;
v8 = a3;
v30 = a3;
v9 = a2;
v33 = (PVOID)a1;
v35 = a1;
v36 = a2;
v37 = a3;
v38 = NumEntriesRemoved;
v28 = 0i64;
LODWORD(Count) = a4;
v10 = KeRemoveQueueEx(a1, PreviousMode, Alertable, CapturedTimeout, a3, Count);
v29 = v10;
for( i = 0i64; ; i = (unsigned int)(i + 1) )
{
if( (unsigned int)i >= v10 )
{
result = 0;
goto LABEL_11;
}
v12 = v8[i];
if( (unsigned __int64)(v12 - 257) <= 1 || v12 == 192 || v12 == 128 )
break;
v13 = *(_BYTE *)(v12 + 16);
if( v13 )
{
if( v13 == 2 )
{
v14 = *(_QWORD *)(v12 + 56);
v15 = *(_QWORD *)(v12 + 48);
LODWORD(v28) = *(_DWORD *)(v12 + 72);
*((_QWORD *)&v28 + 1) = *(_QWORD *)(v12 + 64);
Object = *(PVOID *)(v12 + 80);
CurrentIrql = KeGetCurrentIrql();
v25 = CurrentIrql;
__writecr8(2ui64);
v19 = KiIrqlFlags;
CurrentPrcb = KeGetCurrentPrcb();
if( _interlockedbittestandset64((volatile signed __int32 *)(v12 + 96), 0i64) )
{
v19 = KxWaitForSpinLockAndAcquire((UINT64 *)(v12 + 96));
CurrentIrql = v25;
}
*(_BYTE *)(v12 + 104) = 0;
*(_QWORD *)(v12 + 88) = 0i64;
_InterlockedAnd64((volatile signed __int64 *)(v12 + 96), 0i64);
v20 = KeGetCurrentPrcb();
if( v20->SchedulerAssist && v20->NestingLevel <= 1u && !v19 )
CurrentIrql = v25;
__writecr8(CurrentIrql);
ObfDereferenceObjectWithTag(Object, 0x746C6644ui64);
ObfDereferenceObjectWithTag(v33, 0x746C6644ui64);
ObfDereferenceObjectWithTag((VOID *)v12, 0x746C6644ui64);
v9 = a2;
}
else
{
v14 = *(_QWORD *)(v12 + 32);
v15 = *(_QWORD *)(v12 + 24);
LODWORD(v28) = *(_DWORD *)(v12 + 40);
*((_QWORD *)&v28 + 1) = *(_QWORD *)(v12 + 48);
IopFreeMiniCompletionPacket((_IOP_MINI_COMPLETION_PACKET *)v12);
}
}
else
{
v21 = v12 - 168;
v14 = *(_QWORD *)(v21 + 96);
CurrentPrcb = (struct _KPRCB *)(v21 + 120);
v15 = *(_QWORD *)(v21 + 120);
v28 = *(_OWORD *)(v21 + 48);
v22 = *(_DWORD *)(v21 + 16);
if( (v22 & 0x2000) != 0 )
{
v32 = 0i64;
v27 = 0i64;
v23 = (_EPROCESS *)(*(_QWORD *)(v21 + 88) & 0xFFFFFFFFFFFFFFF9ui64);
memset(&ApcState, 0, sizeof(ApcState));
*(_QWORD *)(v21 + 96) = 0i64;
if( v23 == KeGetCurrentThread()->ApcState.Process )
{
IopCompleteRequest(v21 + 120, (__int64)&v32, &v27, (_KAPC **)(v21 + 192), &v27);
v9 = a2;
}
else
{
if( ExAcquireRundownProtection(&v23->RundownProtect) )
{
KiStackAttachProcess(v23, 0i64, &ApcState);
IopCompleteRequest((__int64)CurrentPrcb, (__int64)&v32, &v27, (_KAPC **)(v21 + 192), &v27);
KiUnstackDetachProcess(&ApcState, 0i64);
ExReleaseRundownProtection(&v23->RundownProtect);
}
else
{
IopDropIrp((PIRP)v21, *(_QWORD *)(v21 + 192));
LODWORD(v28) = -1073741536;
*((_QWORD *)&v28 + 1) = 0i64;
}
v9 = a2;
}
}
else if( (v22 & 0x8000) == 0 || !(unsigned int)IopInterlockedAdd((UINT64 *)(v21 + 88), 0xFFFFFFFFi64) )
{
IoFreeIrp((PIRP)v21);
}
}
v16 = 32i64 * (unsigned int)i;
*(_QWORD *)(v16 + v9) = v15;
*(_QWORD *)(v16 + v9 + 8) = v14;
*(_OWORD *)(v16 + v9 + 16) = v28;
v8 = v30;
}
result = v12;
LABEL_11:
*(_DWORD *)v38 = v10;
return result;
}Referenced by:
NtRemoveIoCompletion
NtRemoveIoCompletionEx
NtWaitForWorkViaWorkerFactory