MiFreePhysicalPageChain
VOID __stdcall MiFreePhysicalPageChain(INT64 a1, INT64 a2, INT64 a3){
__int64 v3;
_ETHREAD *CurrentThread;
UINT64 v6;
unsigned int v7;
INT64 v8;
INT64 v9;
INT64 v10;
__int64 v11;
UINT64 v12;
unsigned __int64 v13;
__int64 *v14;
INT64 v15;
UINT8 v16;
volatile signed __int64 v17;
UINT8 v18;
char v19;
__int64 v20;
unsigned __int64 v21;
int v22;
__int64 *v23;
__int64 v24;
INT64 v25;
UINT64 v26;
signed __int64 *v27;
unsigned __int64 v28;
_DWORD *v29;
_ETHREAD *v30;
__int64 MemoryDescriptorList[518];
v3 = *(_QWORD *)(a1 + 32);
v22 = a3;
memset(MemoryDescriptorList, 0i64, sizeof(MemoryDescriptorList));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v6 = *(_QWORD *)(v3 + 8);
v7 = 0;
v23 = &MemoryDescriptorList[6];
v8 = 0i64;
v29 = (_DWORD *)v3;
v30 = CurrentThread;
v26 = v6;
if( !v22 )
{
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquireAutoExpandPushLockExclusive((_EX_PUSH_LOCK_AUTO_EXPAND *)(v3 + 56), 0i64);
v6 = v26;
}
v27 = *(signed __int64 **)(v3 + 24);
if( a2 )
{
v9 = a2;
do
{
v10 = v9;
v25 = *(_QWORD *)(v9 + 16);
v11 = 0i64;
v12 = 0i64;
v13 = (v9 - (__int64)MmGetPfnDb()) / 48;
v28 = v13 / v6;
v14 = v23;
v15 = v10 + 24;
do
{
v24 = v11;
v16 = MiLockPageInline((_MMPFN *)(v15 - 24));
v17 = *(_QWORD *)v15;
v18 = v16;
if( (*(_QWORD *)v15 & 0x4000000000000000i64) == 0 )
{
v17 |= 0x4000000000000000ui64;
*(_QWORD *)v15 = v17;
}
v19 = *(_BYTE *)(v15 + 10);
if( (v19 & 8) != 0 )
{
v17 = *(_QWORD *)v15;
*(_BYTE *)(v15 + 10) = v19 & 0xF7;
}
v11 = v17 & 0x3FFFFFFFFFFFFFFFi64;
if( (v17 & 0x3FFFFFFFFFFFFFFFi64) == 0 )
{
*(_QWORD *)(v15 - 8) = 0i64;
*(_QWORD *)v15 = v17 ^ (v17 ^ 1) & 0x3FFFFFFFFFFFFFFFi64;
}
_InterlockedAnd64((volatile signed __int64 *)v15, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v18);
if( v12 )
v11 = v24;
if( !v11 )
{
if( !v12 )
_bittestandreset64(v27, v28);
if( v7 == 512 )
{
MemoryDescriptorList[0] = 0i64;
MemoryDescriptorList[4] = 0i64;
LODWORD(MemoryDescriptorList[1]) = 135216;
MemoryDescriptorList[5] = 0x200000i64;
MiFreePagesFromMdl(MemoryDescriptorList, 0i64, 0x3FFFFFFFFFFFFFFFui64);
v8 += 512i64;
v14 = &MemoryDescriptorList[6];
v7 = 0;
}
*v14++ = v13;
++v7;
}
v6 = v26;
++v12;
v15 += 48i64;
++v13;
}
while( v12 < v26 );
v23 = v14;
v9 = v25;
}
while( v25 );
LODWORD(v3) = (_DWORD)v29;
CurrentThread = v30;
if( v7 )
{
MemoryDescriptorList[0] = 0i64;
MemoryDescriptorList[4] = 0i64;
MemoryDescriptorList[5] = v7 << 12;
LOWORD(MemoryDescriptorList[1]) = 8 * (v7 + 6);
WORD1(MemoryDescriptorList[1]) = 2;
MiFreePagesFromMdl(MemoryDescriptorList, 0i64, v26);
v8 += v7;
}
if( v8 )
{
LODWORD(v20) = MiGetAweInfoPartition((INT64)v29);
_InterlockedExchangeAdd64((volatile signed __int64 *)(v20 + 7608), v21);
if( (*v29 & 1) != 0 )
MiReturnProcessPhysicalPages((INT64)v30->Tcb.ApcState.Process, v8);
}
}
if( !v22 )
{
ExReleaseAutoExpandPushLockExclusive(v3 + 56, 0);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
}
}Referenced by:
MiDeletePagablePteRange
NtMapUserPhysicalPages
NtMapUserPhysicalPagesScatter