IoRemoveIoCompletion
VOID __fastcall IoRemoveIoCompletion(
VOID *IoCompletionPtr,
_FILE_IO_COMPLETION_INFORMATION *IoCompletionInformation,
_LIST_ENTRY **EntryArray,
UINT64 Count,
UINT64 *NumEntriesRemoved,
CHAR PreviousMode,
_LARGE_INTEGER *CapturedTimeout,
UINT8 Alertable){
_LIST_ENTRY **v8;
_FILE_IO_COMPLETION_INFORMATION *v9;
ULONG v10;
__int64 i;
_LIST_ENTRY *v12;
char Flink;
_LIST_ENTRY *Blink;
_LIST_ENTRY *v15;
__int64 v16;
unsigned __int8 CurrentIrql;
int v18;
struct _KPRCB *v19;
_LIST_ENTRY **p_Blink;
int v21;
unsigned __int64 v22;
unsigned __int8 v23;
__int64 v25;
IO_STATUS_BLOCK v26;
ULONG v27;
_LIST_ENTRY **v28;
struct _KPRCB *CurrentPrcb;
__int64 v30;
PVOID v31;
PVOID Object;
VOID *v33;
_FILE_IO_COMPLETION_INFORMATION *v34;
_LIST_ENTRY **v35;
UINT64 *v36;
_KAPC_STATE ApcState;
v8 = EntryArray;
v28 = EntryArray;
v9 = IoCompletionInformation;
v31 = IoCompletionPtr;
v33 = IoCompletionPtr;
v34 = IoCompletionInformation;
v35 = EntryArray;
v36 = NumEntriesRemoved;
v26 = 0i64;
v10 = KeRemoveQueueEx((PKQUEUE)IoCompletionPtr, PreviousMode, Alertable, CapturedTimeout, EntryArray, Count);
v27 = v10;
for( i = 0i64; (unsigned int)i < v10; i = (unsigned int)(i + 1) )
{
v12 = v8[i];
if( (unsigned __int64)&v12[-17].Blink + 7 <= 1 || v12 == (_LIST_ENTRY *)192 || v12 == (_LIST_ENTRY *)128 )
break;
Flink = (char)v12[1].Flink;
if( Flink )
{
if( Flink == 2 )
{
Blink = v12[3].Blink;
v15 = v12[3].Flink;
v26.Status = (int)v12[4].Blink;
v26.Information = (unsigned __int64)v12[4].Flink;
Object = v12[5].Flink;
CurrentIrql = KeGetCurrentIrql();
v23 = CurrentIrql;
__writecr8(2ui64);
v18 = KiIrqlFlags;
CurrentPrcb = KeGetCurrentPrcb();
if( _interlockedbittestandset64((volatile signed __int32 *)&v12[6], 0i64) )
{
v18 = KxWaitForSpinLockAndAcquire((UINT64 *)&v12[6]);
CurrentIrql = v23;
}
LOBYTE(v12[6].Blink) = 0;
v12[5].Blink = 0i64;
_InterlockedAnd64((volatile signed __int64 *)&v12[6], 0i64);
v19 = KeGetCurrentPrcb();
if( *((_QWORD *)v19 + 4247) && *((_BYTE *)v19 + 32) <= 1u && !v18 )
CurrentIrql = v23;
__writecr8(CurrentIrql);
ObfDereferenceObjectWithTag(Object, 0x746C6644ui64);
ObfDereferenceObjectWithTag(v31, 0x746C6644ui64);
ObfDereferenceObjectWithTag(v12, 0x746C6644ui64);
v9 = IoCompletionInformation;
}
else
{
Blink = v12[2].Flink;
v15 = v12[1].Blink;
v26.Status = (int)v12[2].Blink;
v26.Information = (unsigned __int64)v12[3].Flink;
IopFreeMiniCompletionPacket((struct SLIST_ENTRY *)v12);
}
}
else
{
p_Blink = &v12[-11].Blink;
Blink = p_Blink[12];
CurrentPrcb = (struct _KPRCB *)(p_Blink + 15);
v15 = p_Blink[15];
v26 = (IO_STATUS_BLOCK)*((_OWORD *)p_Blink + 3);
v21 = *((_DWORD *)p_Blink + 4);
if( (v21 & 0x2000) != 0 )
{
v30 = 0i64;
v25 = 0i64;
v22 = (unsigned __int64)p_Blink[11] & 0xFFFFFFFFFFFFFFF9ui64;
memset(&ApcState, 0, sizeof(ApcState));
p_Blink[12] = 0i64;
if( v22 == *((_QWORD *)KeGetCurrentThread() + 23) )
{
IopCompleteRequest((__int64)(p_Blink + 15), (__int64)&v30, &v25, (ULONG_PTR *)p_Blink + 24, &v25);
v9 = IoCompletionInformation;
}
else
{
if( ExAcquireRundownProtection((PEX_RUNDOWN_REF)(v22 + 1112)) )
{
KiStackAttachProcess((_KPROCESS *)v22, 0i64, &ApcState);
IopCompleteRequest((__int64)CurrentPrcb, (__int64)&v30, &v25, (ULONG_PTR *)p_Blink + 24, &v25);
KiUnstackDetachProcess(&ApcState, 0i64);
ExReleaseRundownProtection((PEX_RUNDOWN_REF)(v22 + 1112));
}
else
{
IopDropIrp((_IRP *)p_Blink, (_FILE_OBJECT *)p_Blink[24]);
v26.Status = -1073741536;
v26.Information = 0i64;
}
v9 = IoCompletionInformation;
}
}
else if( (v21 & 0x8000) == 0 || !(unsigned int)IopInterlockedAdd((UINT64 *)p_Blink + 11, 0xFFFFFFFFi64) )
{
IoFreeIrp((IRP *)p_Blink);
}
}
v16 = (unsigned int)i;
v9[v16].KeyContext = v15;
v9[v16].ApcContext = Blink;
v9[v16].IoStatusBlock = v26;
v8 = v28;
}
*(_DWORD *)v36 = v10;
}Referenced by:
NtRemoveIoCompletion
NtRemoveIoCompletionEx
NtWaitForWorkViaWorkerFactory