IopCompleteRequest
void __fastcall IopCompleteRequest(__int64 a1, __int64 a2, _QWORD *a3, _KAPC **a4, _QWORD *a5){
__int64 v5;
_ETHREAD *CurrentThread;
_KAPC *v7;
_DWORD *v8;
int v9;
int v10;
_MDL *v11;
_MDL *Next;
__int16 MdlFlags;
__int64 AllocationProcessorNumber;
struct _KPRCB *CurrentPrcb;
_GENERAL_LOOKASIDE *P;
_KEVENT *p_SystemArgument1;
_ADAPTER_OBJECT *v18;
__int64 v19;
__int64 v20;
_KEVENT *v21;
int v22;
int v23;
_EPROCESS *v24;
unsigned __int64 v25;
_ETHREAD *v26;
__int64 v27;
unsigned __int64 v28;
_ETHREAD *v29;
unsigned __int8 CurrentIrql;
_QWORD *v31;
__int64 v32;
_QWORD *v33;
_QWORD *SchedulerAssist;
INT64 v35;
_QWORD *v36;
_QWORD *v37;
int v38;
INT64 v39;
INT64 v40;
int CycleTime;
unsigned __int64 v42;
unsigned __int64 v43;
__int64 v44;
_IRP *v45;
char v46;
__int64 v47;
struct _KPRCB *v48;
char v49;
__int16 v50;
__int64 v51;
__int64 v52;
__int64 v53;
__int64 v54;
char v55;
__int64 v56;
_KQUEUE *Object;
__int64 v58;
char v59;
v5 = a1 - 120;
v56 = a1 - 120;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v7 = *a4;
if( !a3 || (v59 = 1, *a3 != 1i64) )
v59 = 0;
v8 = (_DWORD *)(v5 + 16);
v9 = *(_DWORD *)(v5 + 16);
if( (v9 & 0x80u) != 0 )
{
LODWORD(v7->NormalContext) = *(_DWORD *)(v5 + 48);
*(_QWORD *)(v5 + 160) = *a5;
KeSetEvent((PRKEVENT)&v7[1].SystemArgument1, 0, 0);
return;
}
if( (v9 & 0x10) != 0 )
{
if( (v9 & 0x40) != 0 )
{
v10 = *(_DWORD *)(v5 + 48);
if( v10 != -2147483626 && (v10 & 0xC0000000) != -1073741824 )
memmove(*(VOID **)(v5 + 112), *(const VOID **)(v5 + 24), *(_QWORD *)(v5 + 56));
}
if( (*v8 & 0x20) != 0 )
ExFreePoolWithTag(*(PVOID *)(v5 + 24), 0);
}
*v8 &= 0xFFFFFFCF;
v11 = *(_MDL **)(v5 + 8);
if( v11 )
{
do
{
Next = v11->Next;
MdlFlags = v11->MdlFlags;
if( (MdlFlags & 0x20) != 0 )
{
MmUnmapLockedPages(v11->MappedSystemVa, v11);
MdlFlags = v11->MdlFlags;
}
if( (MdlFlags & 8) != 0 )
{
AllocationProcessorNumber = v11->AllocationProcessorNumber;
if( (unsigned int)AllocationProcessorNumber >= (unsigned int)KeNumberProcessors_0 )
{
CurrentPrcb = 0i64;
}
else
{
_mm_lfence();
CurrentPrcb = *(&KiProcessorBlock + AllocationProcessorNumber);
}
if( !CurrentPrcb )
CurrentPrcb = KeGetCurrentPrcb();
P = CurrentPrcb->PPLookasideList[3].P;
++P->TotalFrees;
if( LOWORD(P->ListHead.Alignment) < P->Depth
|| (++P->FreeMisses,
P = CurrentPrcb->PPLookasideList[3].L,
++P->TotalFrees,
LOWORD(P->ListHead.Alignment) < P->Depth) )
{
RtlpInterlockedPushEntrySList(&P->ListHead, (PSLIST_ENTRY)v11);
}
else
{
++P->FreeMisses;
((void(__fastcall *)(_MDL *))P->FreeEx)(v11);
}
}
else
{
ExFreePoolWithTag(v11, 0);
}
v11 = Next;
}
while( Next );
}
*(_QWORD *)(v5 + 8) = 0i64;
if( (*(_DWORD *)(v5 + 48) & 0xC0000000) != -1073741824 )
goto LABEL_53;
if( !*(_BYTE *)(v5 + 65) )
goto LABEL_40;
if( (*v8 & 4) == 0 && (!v7 || (*(_DWORD *)&v7->ApcStateIndex & 2) == 0) )
{
LABEL_53:
Object = 0i64;
v58 = 0i64;
if( v7 )
{
v19 = *(_QWORD *)&v7[2].Type;
if( v19 )
{
if( (*v8 & 0x2000) != 0 )
{
Object = *(_KQUEUE **)v19;
v58 = *(_QWORD *)(v19 + 8);
}
else
{
IopIncrementCompletionContextUsageCountAndReadData(v7);
}
if( Object )
ObfReferenceObject(Object);
}
}
v20 = *(_QWORD *)(v5 + 72);
if( (*(_BYTE *)(v5 + 71) & 0x10) != 0 )
*(_DWORD *)(v20 + 4) = *(_DWORD *)(v56 + 56);
else
*(_QWORD *)(v20 + 8) = *(_QWORD *)(v56 + 56);
*(_DWORD *)v20 = *(_DWORD *)(v5 + 48);
v21 = *(_KEVENT **)(v5 + 80);
if( v21 )
{
KeSetEvent(v21, 0, 0);
if( !v7 )
goto LABEL_74;
v22 = *(_DWORD *)(v5 + 16);
if( (v22 & 4) == 0 )
{
HalPutDmaAdapter(*(PADAPTER_OBJECT *)(v5 + 80));
v22 = *(_DWORD *)(v5 + 16);
}
if( (*(_DWORD *)&v7->ApcStateIndex & 2) == 0 || (v22 & 0x1000) != 0 )
{
LABEL_74:
v23 = *(_DWORD *)(v5 + 16);
if( (v23 & 0x2000) != 0 )
v24 = (_EPROCESS *)(*(_QWORD *)(v5 + 88) & 0xFFFFFFFFFFFFFFF9ui64);
else
v24 = 0i64;
if( (v23 & 0x100) != 0 )
{
v25 = *(unsigned int *)(v56 + 56);
if( v24 )
{
_InterlockedExchangeAdd64((volatile signed __int64 *)&v24->ReadTransferCount, v25);
}
else
{
v26 = (_ETHREAD *)KeGetCurrentThread();
v26->Tcb.ReadTransferCount += v25;
}
__addgsqword(0x2EE8u, v25);
}
else if( (v23 & 0x200) != 0 )
{
IopUpdateWriteTransferCount(*(unsigned int *)(v56 + 56), v24);
}
else
{
v27 = *(_QWORD *)(v56 + 56);
if( v27 >= 0 )
{
v28 = (unsigned int)v27;
if( v24 )
{
_InterlockedExchangeAdd64((volatile signed __int64 *)&v24->OtherTransferCount, (unsigned int)v27);
}
else
{
v29 = (_ETHREAD *)KeGetCurrentThread();
v29->Tcb.OtherTransferCount += v28;
}
__addgsqword(0x2EF8u, v28);
}
}
if( (*(_DWORD *)(v5 + 16) & 0x2000) != 0 )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
if( _interlockedbittestandset64((volatile signed __int32 *)&v7[2].Thread, 0i64) )
KxWaitForSpinLockAndAcquire((UINT64 *)&v7[2].Thread);
v31 = (_QWORD *)(v5 + 32);
v32 = *(_QWORD *)(v5 + 32);
v33 = *(_QWORD **)(v5 + 40);
if( *(_QWORD *)(v32 + 8) == v5 + 32 && (_QWORD *)*v33 == v31 )
{
*v33 = v32;
*(_QWORD *)(v32 + 8) = v33;
*(_QWORD *)(v5 + 40) = v5 + 32;
*v31 = v31;
ObfDereferenceObjectWithTag((VOID *)(*(_QWORD *)(v5 + 88) & 0xFFFFFFFFFFFFFFF9ui64), 0x70436F49ui64);
*(_DWORD *)(v5 + 16) = *(_DWORD *)(v5 + 16) & 0xFFFF5FFF | 0x8000;
_InterlockedAnd64((volatile signed __int64 *)&v7[2].Thread, 0i64);
SchedulerAssist = KeGetCurrentPrcb()->SchedulerAssist;
goto LABEL_103;
}
}
else
{
v35 = (INT64)CurrentThread;
*(_QWORD *)(v5 + 152) = CurrentThread;
CurrentIrql = 0;
if( CurrentThread )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
if( _interlockedbittestandset64((volatile signed __int32 *)&CurrentThread->IrpListLock, 0i64) )
KxWaitForSpinLockAndAcquire(&CurrentThread->IrpListLock);
v35 = (INT64)CurrentThread;
}
v36 = (_QWORD *)(v5 + 32);
SchedulerAssist = *(_QWORD **)(v5 + 32);
v37 = *(_QWORD **)(v5 + 40);
if( SchedulerAssist[1] == v5 + 32 && (_QWORD *)*v37 == v36 )
{
*v37 = SchedulerAssist;
SchedulerAssist[1] = v37;
*(_QWORD *)(v5 + 40) = v5 + 32;
*v36 = v36;
if( !v35 )
goto LABEL_104;
_InterlockedAnd64((volatile signed __int64 *)(v35 + 1416), 0i64);
SchedulerAssist = KeGetCurrentPrcb()->SchedulerAssist;
LABEL_103:
v35 = (INT64)CurrentThread;
__writecr8(CurrentIrql);
LABEL_104:
v38 = *(_DWORD *)(v5 + 16) & 0x8000;
if( !v38 )
*(_QWORD *)(v5 + 88) &= ~1ui64;
if( !v38 )
{
SchedulerAssist = *(_QWORD **)(v5 + 88);
if( SchedulerAssist )
{
if( v59 )
v39 = (unsigned int)*(char *)(v5 + 70);
else
v39 = 2i64;
KeInitializeApc(
v5 + 120,
v35,
v39,
(INT64)IopUserRundown,
(INT64)IopUserRundown,
(INT64)SchedulerAssist,
*(_BYTE *)(v5 + 64),
*(_QWORD *)(v5 + 96));
KeInsertQueueApc(v5 + 120, *(_QWORD *)(v5 + 72), 0i64, 2i64);
goto LABEL_157;
}
}
if( Object
&& *(_QWORD *)(v5 + 96)
&& ((*(_DWORD *)&v7->ApcStateIndex & 0x2000000) == 0
|| *(_BYTE *)(v5 + 65)
|| (*(_DWORD *)(v5 + 48) & 0xC0000000) == 0x80000000) )
{
v40 = 0i64;
CycleTime = v7->Thread->Tcb.CycleTime;
if( CycleTime == 8 || CycleTime == 20 )
v40 = 1i64;
*(_QWORD *)(v5 + 120) = v58;
*(_DWORD *)(v5 + 184) = 0;
KeInsertQueueEx(Object, (_LIST_ENTRY *)(v5 + 168), v40, 0);
goto LABEL_157;
}
if( v38 )
{
v42 = *(_QWORD *)(v5 + 88);
do
{
v43 = v42;
v44 = ((v42 >> 1) & 3) - 1;
v42 = _InterlockedCompareExchange64(
(volatile signed __int64 *)(v5 + 88),
v42 & 0xFFFFFFFFFFFFFFF9ui64 | (2 * v44),
v42);
}
while( v43 != v42 );
if( (_DWORD)v44 )
goto LABEL_157;
v45 = (_IRP *)v5;
if( !IopDispatchFreeIrp )
{
IopFreeIrp((_IRP *)v5);
goto LABEL_157;
}
}
else
{
if( !IopDispatchFreeIrp )
{
if( *(_WORD *)v5 != 6 )
KeBugCheckEx(IopDispatchFreeIrp + 68, (PVOID)v5, (PVOID)0x257C, 0i64, 0i64);
*(_WORD *)v5 = 0;
v46 = *(_BYTE *)(v5 + 71);
if( (v46 & 0x40) != 0 )
{
IopFreeIrpExtension((_IRP *)v5, IopAllExtensions, 1u);
v46 = *(_BYTE *)(v5 + 71);
}
if( (v46 & 0x21) == 33 )
{
IopFreeReserveIrp((_IRP *)v5, (CHAR)SchedulerAssist);
}
else
{
v47 = *(unsigned __int16 *)(v5 + 4);
if( (unsigned int)v47 >= (unsigned int)KeNumberProcessors_0 )
{
v48 = KeGetCurrentPrcb();
}
else
{
_mm_lfence();
v48 = *(&KiProcessorBlock + v47);
}
v49 = *(_BYTE *)(v5 + 71);
if( (v49 & 8) != 0 )
{
*(_BYTE *)(v5 + 71) = v49 ^ 8;
_InterlockedIncrement(&v48->LookasideIrpFloat);
v49 = *(_BYTE *)(v5 + 71);
}
if( (v49 & 4) != 0 )
{
if( (*(&stru_140C452E0 + 1144) & 3) == 0
|| (v50 = *(_WORD *)(v5 + 2), v50 == 72 * *(&stru_140C452E0 + 2844) + 208)
|| v50 == 72 * *(&stru_140C452E0 + 2840) + 208
|| v50 == 280 )
{
v51 = *(unsigned __int16 *)(v5 + 2);
if( (unsigned __int16)v51 < (unsigned __int16)(72 * *(&stru_140C452E0 + 2844) + 208) )
{
if( (unsigned __int16)v51 < (unsigned __int16)(72 * *(&stru_140C452E0 + 2840) + 208) )
{
v52 = 2048i64;
v53 = 2056i64;
}
else
{
v52 = 2064i64;
v53 = 2072i64;
}
}
else
{
v52 = 2080i64;
v53 = 2088i64;
}
*(_QWORD *)(v56 + 56) = v51;
v54 = *(_QWORD *)((char *)&v48->_MxCsr + v52);
++*(_DWORD *)(v54 + 28);
if( *(_WORD *)v54 < *(_WORD *)(v54 + 16)
|| (++*(_DWORD *)(v54 + 32),
v54 = *(_QWORD *)((char *)&v48->_MxCsr + v53),
++*(_DWORD *)(v54 + 28),
*(_WORD *)v54 < *(_WORD *)(v54 + 16)) )
{
v55 = *(_BYTE *)(v5 + 71);
if( (v55 & 1) != 0 )
{
*(_BYTE *)(v5 + 71) = v55 ^ 1;
ExReturnPoolQuota((VOID *)v5);
}
RtlpInterlockedPushEntrySList((PSLIST_HEADER)v54, (PSLIST_ENTRY)v5);
goto LABEL_157;
}
++*(_DWORD *)(v54 + 32);
}
}
ExFreePoolWithTag((PVOID)v5, 0);
}
LABEL_157:
if( Object )
HalPutDmaAdapter((PADAPTER_OBJECT)Object);
if( v7 )
ObDereferenceObjectDeferDelete((UINT64)v7);
return;
}
v45 = (_IRP *)v5;
}
IovFreeIrpPrivate(v45);
goto LABEL_157;
}
}
__fastfail(3u);
}
}
else
{
if( !v7 )
goto LABEL_74;
if( (*(_DWORD *)&v7->ApcStateIndex & 0x4000000) != 0 )
goto LABEL_73;
}
KeSetEvent((PRKEVENT)&v7[1].SystemArgument1, 0, 0);
LABEL_73:
LODWORD(v7->NormalContext) = *(_DWORD *)(v5 + 48);
goto LABEL_74;
}
if( v7 )
{
if( (*v8 & 4) != 0 )
{
*(_OWORD *)*(_QWORD *)(v5 + 72) = *(_OWORD *)(v5 + 48);
p_SystemArgument1 = *(_KEVENT **)(v5 + 80);
if( p_SystemArgument1 )
{
LABEL_39:
KeSetEvent(p_SystemArgument1, 0, 0);
goto LABEL_40;
}
}
else
{
LODWORD(v7->NormalContext) = *(_DWORD *)(v5 + 48);
}
p_SystemArgument1 = (_KEVENT *)&v7[1].SystemArgument1;
goto LABEL_39;
}
LABEL_40:
if( (*v8 & 0x2000) != 0 )
IopDequeueIrpFromFileObject((_IRP *)v5, (_FILE_OBJECT *)v7);
if( v7 )
ObDereferenceObjectDeferDelete((UINT64)v7);
v18 = *(_ADAPTER_OBJECT **)(v5 + 80);
if( v18 && v7 && (*v8 & 4) == 0 )
HalPutDmaAdapter(v18);
if( (*v8 & 0x8000) != 0 )
{
if( (unsigned int)IopInterlockedAdd((UINT64 *)(v5 + 88), 0xFFFFFFFFi64) )
return;
}
else
{
*(_QWORD *)(v5 + 152) = CurrentThread;
IopDequeueIrpFromThread((_IRP *)v5);
}
IoFreeIrp((PIRP)v5);
}Referenced by:
IoRemoveIoCompletion
IopAbortRequest
IopSynchronousServiceTail
IopfCompleteRequest
NtQueryInformationFile
NtSetInformationFile