IopCompleteRequest
void __fastcall IopCompleteRequest(__int64 a1, __int64 a2, _QWORD *a3, ULONG_PTR *a4, _QWORD *a5){
__int64 v5;
_ETHREAD *CurrentThread;
_FILE_OBJECT *v7;
_DWORD *v8;
int v9;
int v10;
struct _MDL *v11;
struct _MDL *Next;
__int16 MdlFlags;
__int64 AllocationProcessorNumber;
struct _KPRCB *CurrentPrcb;
__int64 v16;
struct _KEVENT *p_Event;
struct _DMA_ADAPTER *v18;
_IO_COMPLETION_CONTEXT *CompletionContext;
__int64 v20;
INT64 v21;
struct _KEVENT *v22;
int v23;
int v24;
unsigned __int64 v25;
unsigned __int64 v26;
_ETHREAD *v27;
__int64 v28;
unsigned __int64 v29;
_ETHREAD *v30;
unsigned __int8 CurrentIrql;
_QWORD *v32;
__int64 v33;
_QWORD *v34;
INT64 v35;
INT64 v36;
_QWORD *v37;
INT64 *v38;
int v39;
INT64 v40;
INT64 v41;
int v42;
unsigned __int64 v43;
unsigned __int64 v44;
__int64 v45;
IRP *v46;
char v47;
__int64 v48;
struct _KPRCB *v49;
char v50;
__int16 v51;
__int64 v52;
__int64 v53;
__int64 v54;
__int64 v55;
char v56;
_TRANSFER_TYPE BugCheckParameter4;
__int64 v58;
KQUEUE *Object;
void *Key;
char v61;
v5 = a1 - 120;
v58 = a1 - 120;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v7 = (_FILE_OBJECT *)*a4;
if( !a3 || (v61 = 1, *a3 != 1i64) )
v61 = 0;
v8 = (_DWORD *)(v5 + 16);
v9 = *(_DWORD *)(v5 + 16);
if( (v9 & 0x80u) != 0 )
{
v7->FinalStatus = *(_DWORD *)(v5 + 48);
*(_QWORD *)(v5 + 160) = *a5;
KeSetEvent(&v7->Event, 0);
return;
}
if( (v9 & 0x10) != 0 )
{
if( (v9 & 0x40) != 0 )
{
v10 = *(_DWORD *)(v5 + 48);
if( v10 != -2147483626 && (v10 & 0xC0000000) != -1073741824 )
memmove(*(UINT8 **)(v5 + 112), *(UINT8 **)(v5 + 24), *(_QWORD *)(v5 + 56));
}
if( (*v8 & 0x20) != 0 )
ExFreePoolWithTag(*(PVOID *)(v5 + 24), 0);
}
*v8 &= 0xFFFFFFCF;
v11 = *(struct _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();
v16 = *((_QWORD *)CurrentPrcb + 262);
++*(_DWORD *)(v16 + 28);
if( *(_WORD *)v16 < *(_WORD *)(v16 + 16)
|| (++*(_DWORD *)(v16 + 32),
v16 = *((_QWORD *)CurrentPrcb + 263),
++*(_DWORD *)(v16 + 28),
*(_WORD *)v16 < *(_WORD *)(v16 + 16)) )
{
RtlpInterlockedPushEntrySList((PSLIST_HEADER)v16, (PSLIST_ENTRY)v11);
}
else
{
++*(_DWORD *)(v16 + 32);
(*(void(__fastcall **)(struct _MDL *))(v16 + 56))(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 || (v7->Flags & 2) == 0) )
{
LABEL_53:
Object = 0i64;
Key = 0i64;
if( v7 )
{
CompletionContext = v7->CompletionContext;
if( CompletionContext )
{
if( (*v8 & 0x2000) != 0 )
{
Object = (KQUEUE *)CompletionContext->Port;
Key = CompletionContext->Key;
}
else
{
IopIncrementCompletionContextUsageCountAndReadData(v7);
}
if( Object )
ObfReferenceObject(Object);
}
}
v20 = *(_QWORD *)(v5 + 72);
v21 = v58;
if( (*(_BYTE *)(v5 + 71) & 0x10) != 0 )
*(_DWORD *)(v20 + 4) = *(_DWORD *)(v58 + 56);
else
*(_QWORD *)(v20 + 8) = *(_QWORD *)(v58 + 56);
*(_DWORD *)v20 = *(_DWORD *)(v5 + 48);
v22 = *(struct _KEVENT **)(v5 + 80);
if( v22 )
{
KeSetEvent(v22, 0);
if( !v7 )
goto LABEL_74;
v23 = *(_DWORD *)(v5 + 16);
if( (v23 & 4) == 0 )
{
HalPutDmaAdapter(*(PADAPTER_OBJECT *)(v5 + 80));
v23 = *(_DWORD *)(v5 + 16);
}
if( (v7->Flags & 2) == 0 || (v23 & 0x1000) != 0 )
{
LABEL_74:
v24 = *(_DWORD *)(v5 + 16);
if( (v24 & 0x2000) != 0 )
v25 = *(_QWORD *)(v5 + 88) & 0xFFFFFFFFFFFFFFF9ui64;
else
v25 = 0i64;
if( (v24 & 0x100) != 0 )
{
v26 = *(unsigned int *)(v58 + 56);
if( v25 )
{
_InterlockedExchangeAdd64((volatile signed __int64 *)(v25 + 1576), v26);
}
else
{
v27 = (_ETHREAD *)KeGetCurrentThread();
*((_QWORD *)v27 + 115) += v26;
}
__addgsqword(0x2EE8u, v26);
}
else if( (v24 & 0x200) != 0 )
{
IopUpdateWriteTransferCount(
(_DEVICE_OBJECT *)*(unsigned int *)(v58 + 56),
(_IRP *)v25,
v21,
(_FILE_OBJECT *)a4,
BugCheckParameter4);
}
else
{
v28 = *(_QWORD *)(v58 + 56);
if( v28 >= 0 )
{
v29 = (unsigned int)v28;
if( v25 )
{
_InterlockedExchangeAdd64((volatile signed __int64 *)(v25 + 1592), (unsigned int)v28);
}
else
{
v30 = (_ETHREAD *)KeGetCurrentThread();
*((_QWORD *)v30 + 117) += v29;
}
__addgsqword(0x2EF8u, v29);
}
}
if( (*(_DWORD *)(v5 + 16) & 0x2000) != 0 )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
if( _interlockedbittestandset64((volatile signed __int32 *)&v7->IrpListLock, 0i64) )
KxWaitForSpinLockAndAcquire(&v7->IrpListLock);
v32 = (_QWORD *)(v5 + 32);
v33 = *(_QWORD *)(v5 + 32);
v34 = *(_QWORD **)(v5 + 40);
if( *(_QWORD *)(v33 + 8) == v5 + 32 && (_QWORD *)*v34 == v32 )
{
*v34 = v33;
*(_QWORD *)(v33 + 8) = v34;
*(_QWORD *)(v5 + 40) = v5 + 32;
*v32 = v32;
ObfDereferenceObjectWithTag((PVOID)(*(_QWORD *)(v5 + 88) & 0xFFFFFFFFFFFFFFF9ui64), 0x70436F49ui64);
*(_DWORD *)(v5 + 16) = *(_DWORD *)(v5 + 16) & 0xFFFF5FFF | 0x8000;
_InterlockedAnd64((volatile signed __int64 *)&v7->IrpListLock, 0i64);
v35 = *((_QWORD *)KeGetCurrentPrcb() + 4247);
goto LABEL_103;
}
}
else
{
v36 = (INT64)CurrentThread;
*(_QWORD *)(v5 + 152) = CurrentThread;
CurrentIrql = 0;
if( CurrentThread )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
if( _interlockedbittestandset64((volatile signed __int32 *)CurrentThread + 354, 0i64) )
KxWaitForSpinLockAndAcquire((UINT64 *)CurrentThread + 177);
v36 = (INT64)CurrentThread;
}
v37 = (_QWORD *)(v5 + 32);
v35 = *(_QWORD *)(v5 + 32);
v38 = *(INT64 **)(v5 + 40);
if( *(_QWORD *)(v35 + 8) == v5 + 32 && (_QWORD *)*v38 == v37 )
{
*v38 = v35;
*(_QWORD *)(v35 + 8) = v38;
*(_QWORD *)(v5 + 40) = v5 + 32;
*v37 = v37;
if( !v36 )
goto LABEL_104;
_InterlockedAnd64((volatile signed __int64 *)(v36 + 1416), 0i64);
v35 = *((_QWORD *)KeGetCurrentPrcb() + 4247);
LABEL_103:
v36 = (INT64)CurrentThread;
__writecr8(CurrentIrql);
LABEL_104:
v39 = *(_DWORD *)(v5 + 16) & 0x8000;
if( !v39 )
*(_QWORD *)(v5 + 88) &= ~1ui64;
if( !v39 )
{
v35 = *(_QWORD *)(v5 + 88);
if( v35 )
{
if( v61 )
v40 = (unsigned int)*(char *)(v5 + 70);
else
v40 = 2i64;
KeInitializeApc(
v5 + 120,
v36,
v40,
(INT64)IopUserRundown,
(INT64)IopUserRundown,
v35,
*(_BYTE *)(v5 + 64),
*(_QWORD *)(v5 + 96));
KeInsertQueueApc((_KAPC *)(v5 + 120), *(PVOID *)(v5 + 72), 0i64, 2i64);
goto LABEL_157;
}
}
if( Object
&& *(_QWORD *)(v5 + 96)
&& ((v7->Flags & 0x2000000) == 0
|| *(_BYTE *)(v5 + 65)
|| (*(_DWORD *)(v5 + 48) & 0xC0000000) == 0x80000000) )
{
v41 = 0i64;
v42 = *((_DWORD *)v7->DeviceObject + 18);
if( v42 == 8 || v42 == 20 )
v41 = 1i64;
*(_QWORD *)(v5 + 120) = Key;
*(_DWORD *)(v5 + 184) = 0;
KeInsertQueueEx(Object, (LIST_ENTRY *)(v5 + 168), v41, 0);
goto LABEL_157;
}
if( v39 )
{
v43 = *(_QWORD *)(v5 + 88);
do
{
v44 = v43;
v45 = ((v43 >> 1) & 3) - 1;
v43 = _InterlockedCompareExchange64(
(volatile signed __int64 *)(v5 + 88),
v43 & 0xFFFFFFFFFFFFFFF9ui64 | (2 * v45),
v43);
}
while( v44 != v43 );
if( (_DWORD)v45 )
goto LABEL_157;
v46 = (IRP *)v5;
if( !IopDispatchFreeIrp )
{
IopFreeIrp((IRP *)v5);
goto LABEL_157;
}
}
else
{
if( !IopDispatchFreeIrp )
{
if( *(_WORD *)v5 != 6 )
KeBugCheckEx(IopDispatchFreeIrp + 68, v5, 0x257Cui64, 0i64, 0i64);
*(_WORD *)v5 = 0;
v47 = *(_BYTE *)(v5 + 71);
if( (v47 & 0x40) != 0 )
{
IopFreeIrpExtension(v5, -1, 1);
v47 = *(_BYTE *)(v5 + 71);
}
if( (v47 & 0x21) == 33 )
{
IopFreeReserveIrp((_IRP *)v5, v35);
}
else
{
v48 = *(unsigned __int16 *)(v5 + 4);
if( (unsigned int)v48 >= (unsigned int)KeNumberProcessors_0 )
{
v49 = KeGetCurrentPrcb();
}
else
{
_mm_lfence();
v49 = *(&KiProcessorBlock + v48);
}
v50 = *(_BYTE *)(v5 + 71);
if( (v50 & 8) != 0 )
{
*(_BYTE *)(v5 + 71) = v50 ^ 8;
_InterlockedIncrement((volatile signed __int32 *)v49 + 2919);
v50 = *(_BYTE *)(v5 + 71);
}
if( (v50 & 4) != 0 )
{
if( (IopIrpStackProfilerFlags & 3) == 0
|| (v51 = *(_WORD *)(v5 + 2), v51 == 72 * (char)IopLargeIrpStackLocations + 208)
|| v51 == 72 * (char)IopMediumIrpStackLocations + 208
|| v51 == 280 )
{
v52 = *(unsigned __int16 *)(v5 + 2);
if( (unsigned __int16)v52 < (unsigned __int16)(72 * (char)IopLargeIrpStackLocations + 208) )
{
if( (unsigned __int16)v52 < (unsigned __int16)(72 * (char)IopMediumIrpStackLocations + 208) )
{
v53 = 2048i64;
v54 = 2056i64;
}
else
{
v53 = 2064i64;
v54 = 2072i64;
}
}
else
{
v53 = 2080i64;
v54 = 2088i64;
}
*(_QWORD *)(v58 + 56) = v52;
v55 = *(_QWORD *)((char *)v49 + v53);
++*(_DWORD *)(v55 + 28);
if( *(_WORD *)v55 < *(_WORD *)(v55 + 16)
|| (++*(_DWORD *)(v55 + 32),
v55 = *(_QWORD *)((char *)v49 + v54),
++*(_DWORD *)(v55 + 28),
*(_WORD *)v55 < *(_WORD *)(v55 + 16)) )
{
v56 = *(_BYTE *)(v5 + 71);
if( (v56 & 1) != 0 )
{
*(_BYTE *)(v5 + 71) = v56 ^ 1;
ExReturnPoolQuota((PVOID)v5);
}
RtlpInterlockedPushEntrySList((PSLIST_HEADER)v55, (PSLIST_ENTRY)v5);
goto LABEL_157;
}
++*(_DWORD *)(v55 + 32);
}
}
ExFreePoolWithTag((PVOID)v5, 0);
}
LABEL_157:
if( Object )
HalPutDmaAdapter((PADAPTER_OBJECT)Object);
if( v7 )
ObDereferenceObjectDeferDelete(v7);
return;
}
v46 = (IRP *)v5;
}
IovFreeIrpPrivate(v46);
goto LABEL_157;
}
}
__fastfail(3u);
}
}
else
{
if( !v7 )
goto LABEL_74;
if( (v7->Flags & 0x4000000) != 0 )
goto LABEL_73;
}
KeSetEvent(&v7->Event, 0);
LABEL_73:
v7->FinalStatus = *(_DWORD *)(v5 + 48);
goto LABEL_74;
}
if( v7 )
{
if( (*v8 & 4) != 0 )
{
*(_OWORD *)*(_QWORD *)(v5 + 72) = *(_OWORD *)(v5 + 48);
p_Event = *(struct _KEVENT **)(v5 + 80);
if( p_Event )
{
LABEL_39:
KeSetEvent(p_Event, 0);
goto LABEL_40;
}
}
else
{
v7->FinalStatus = *(_DWORD *)(v5 + 48);
}
p_Event = &v7->Event;
goto LABEL_39;
}
LABEL_40:
if( (*v8 & 0x2000) != 0 )
IopDequeueIrpFromFileObject((_IRP *)v5, v7);
if( v7 )
ObDereferenceObjectDeferDelete(v7);
v18 = *(struct _DMA_ADAPTER **)(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((IRP *)v5);
}Referenced by:
IoRemoveIoCompletion
IopAbortRequest
IopSynchronousServiceTail
IopfCompleteRequest
NtQueryInformationFile
NtSetInformationFile