MiFreePhysicalPages
NTSTATUS __stdcall MiFreePhysicalPages(INT64 a1, INT64 a2){
INT64 v3;
__int64 *v4;
NTSTATUS v5;
UINT64 v6;
_QWORD *v7;
unsigned __int64 v8;
_ETHREAD *CurrentThread;
_MMSUPPORT_INSTANCE *p_Instance;
unsigned __int64 v11;
const signed __int64 *v12;
_MMPTE *PteBase;
__int64 v14;
unsigned __int64 v15;
_MMPFN *v16;
VOID *v17;
UINT64 PteLong;
UINT64 v19;
char v20;
unsigned __int64 Long;
int v22;
VOID *v23;
__int64 v24;
char v25;
int v26;
UINT64 v27;
UINT64 v28;
NTSTATUS result;
char WsIrql;
int v31;
int v32;
UINT64 CommitSize;
unsigned __int64 v34;
signed __int64 *v35;
_ETHREAD *v36;
unsigned __int64 v37;
__int64 v39;
unsigned __int64 v40;
unsigned __int64 v41;
ULONG_PTR Lock;
_MI_TB_FLUSH_LIST TbFlushList[48];
v3 = a1;
memset(TbFlushList, 0i64, 0xB8u);
TbFlushList[0] = 1;
LOWORD(TbFlushList[1]) = 0;
v4 = (__int64 *)(a2 + 48);
*(_QWORD *)&TbFlushList[4] = 0i64;
v5 = 0;
*(_QWORD *)&TbFlushList[6] = 0i64;
v6 = 0i64;
v31 = 0;
v7 = (_QWORD *)(a2 + 48);
v8 = (unsigned __int64)*(unsigned int *)(a2 + 40) >> 12;
TbFlushList[2] = 20;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
WsIrql = 17;
v36 = CurrentThread;
v34 = a2 + 48 + 8 * v8;
v37 = *(_QWORD *)(v3 + 8);
p_Instance = &CurrentThread->Tcb.ApcState.Process->Vm.Instance;
v32 = *(_DWORD *)v3 & 1;
if( v32 )
MiLockAweVadsExclusive((INT64)CurrentThread);
--CurrentThread->Tcb.SpecialApcDisable;
Lock = v3 + 56;
ExAcquireAutoExpandPushLockExclusive((_EX_PUSH_LOCK_AUTO_EXPAND *)(v3 + 56), 0i64);
v11 = *(_QWORD *)(v3 + 16);
v12 = *(const signed __int64 **)(v3 + 24);
v41 = v11;
v35 = (signed __int64 *)v12;
if( (unsigned __int64)v4 < v34 )
{
PteBase = MmGetPteBase();
while( 1 )
{
v39 = *v4;
v14 = *v4;
v15 = *v4 / v37;
v40 = v15;
if( *v4 % v37 )
break;
if( v15 >= v11 )
break;
if( !_bittest64(v12, v15) )
break;
v16 = &MmGetPfnDb()[v39];
CommitSize = (UINT64)v16;
if( (v16->u2._bf_0 & 0x4000000000000000i64) != 0 )
break;
v17 = (VOID *)(v16->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64);
if( v17 != (VOID *)1 && (*(_DWORD *)v3 & 1) != 0 )
{
PteLong = v16->PteLong;
v19 = (UINT64)PteBase + ((PteLong >> 9) & 0x7FFFFFFFF8i64);
if( v6 != v19 )
{
if( v6 )
{
MiFlushTbList(TbFlushList);
MiUnlockPageTableInternal((INT64)p_Instance, v6);
}
v6 = v19;
if( WsIrql == 17 )
{
MiLockWorkingSetShared();
WsIrql = v20;
}
MiLockPageTableInternal((INT64)p_Instance, v19, 0i64);
}
Long = ZeroPte.u.Long;
LOBYTE(v22) = MiPteInShadowRange(PteLong);
if( v22 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
Long = ZeroPte.u.Long | 0x8000000000000000ui64;
*(_QWORD *)PteLong = Long;
MiUpdateAwePageTable(v6, -1i64, 0xFFFFFFFFi64);
MiInsertTbFlushEntry(
TbFlushList,
(VOID *)((__int64)((PteLong << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16),
1ui64,
0i64);
MiDecrementAweMapCount(v23, CommitSize, (UINT64)MmBadPointer);
v16 = (_MMPFN *)CommitSize;
v3 = a1;
v14 = v39;
}
LODWORD(v24) = MiDecrementAweMapCount(v17, (UINT64)v16, (UINT64)MmBadPointer);
if( !v24 )
{
*v7++ = v14;
_bittestandreset64(v35, v40);
}
v25 = ++v31;
if( WsIrql != 17 && (v25 & 0x3F) == 0 )
{
LOBYTE(v26) = MiWorkingSetIsContended((INT64)p_Instance);
if( v26
|| (unsigned int)MiPageTableLockIsContended((__int64)p_Instance, v6)
|| (unsigned int)KeShouldYieldProcessor() )
{
MiFlushTbList(TbFlushList);
MiUnlockPageTableInternal((INT64)p_Instance, v6);
LOBYTE(v27) = WsIrql;
MiUnlockWorkingSetShared(p_Instance, v27);
v6 = 0i64;
WsIrql = 17;
}
}
v12 = v35;
++v4;
v11 = v41;
PteBase = MmGetPteBase();
if( (unsigned __int64)v4 >= v34 )
goto LABEL_33;
}
v5 = -1073741800;
LABEL_33:
if( v6 )
{
MiFlushTbList(TbFlushList);
MiUnlockPageTableInternal((INT64)p_Instance, v6);
LOBYTE(v28) = WsIrql;
MiUnlockWorkingSetShared(p_Instance, v28);
}
CurrentThread = v36;
}
ExReleaseAutoExpandPushLockExclusive(Lock, 0);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
if( v32 )
MiUnlockAweVadsExclusive(&CurrentThread->Tcb);
result = v5;
*(_DWORD *)(a2 + 44) = ((__int64)v4 - a2 - 48) >> 3;
*(_DWORD *)(a2 + 40) = ((__int64)v7 - a2 - 48) >> 3;
return result;
}Referenced by:
NtFreeUserPhysicalPages