MiComputePageCommitment
NTSTATUS __stdcall MiComputePageCommitment(
VOID *StartingAddress,
VOID *EndingAddress,
_MMVAD_SHORT *Vad,
UINT8 WsIrql,
UINT64 *ReducedCommitClonePages){
int v5;
unsigned __int64 v6;
_MMWSL_INSTANCE *VmWorkingSetList;
_MMPTE *PteBase;
_MMPTE *v9;
_MMPTE *v10;
__int64 v11;
_QWORD *v12;
int v13;
_MMPTE *NextPageTable;
_MMPTE *v15;
__int64 v16;
__int64 v17;
_MMPTE *v18;
NTSTATUS IsPteDecommittedPage;
UINT64 v20;
int v21;
unsigned int v22;
__int64 v23;
_MMPTE *NextPteToTrim;
_MMCLONE_DESCRIPTOR *CloneAddress;
unsigned __int64 v26;
_UNICODE_STRING *v27;
UINT8 v28;
PWCHAR v29;
int v30;
__int64 v31;
unsigned __int64 v33;
int v34;
_MMPTE v35;
__int64 v36;
bool v37;
UINT64 PageTableFlags;
_MMPTE PointerPte;
_EPROCESS *CurrentProcess;
UINT64 v41;
INT64 p_Vm;
UINT64 LargePage;
_MMPTE *v44;
_MMWSL_INSTANCE *v45;
UINT8 v46;
_QWORD *v47;
v46 = WsIrql;
LODWORD(LargePage) = 0;
v5 = 0;
v6 = ((unsigned __int64)StartingAddress >> 9) & 0x7FFFFFFFF8i64;
CurrentProcess = KeGetCurrentThread()->ApcState.Process;
VmWorkingSetList = CurrentProcess->Vm.Instance.VmWorkingSetList;
p_Vm = (INT64)&CurrentProcess->Vm;
PteBase = MmGetPteBase();
v45 = VmWorkingSetList;
v9 = (_MMPTE *)((char *)PteBase + v6);
v10 = (_MMPTE *)((char *)PteBase + (((unsigned __int64)EndingAddress >> 9) & 0x7FFFFFFFF8i64));
v44 = v10;
if( (Vad->u1.LongFlags1 & 0x80000000) == 0 )
{
v11 = 0i64;
}
else
{
v5 = 2;
v11 = v10 - v9 + 1;
}
v12 = v47;
if( v47 )
*v47 = 0i64;
if( v9 <= v10 )
{
v13 = (int)ReducedCommitClonePages;
do
{
LODWORD(PageTableFlags) = v13;
NextPageTable = MiGetNextPageTable(v9, v10, 0i64, WsIrql, PageTableFlags, &LargePage, PointerPte.u.Long);
v9 = NextPageTable;
if( !NextPageTable )
return v11;
v15 = NextPageTable;
v16 = 1i64;
if( (_DWORD)LargePage )
{
v17 = (unsigned int)LargePage;
v18 = MmGetPteBase();
do
{
v15 = (_MMPTE *)((char *)v18 + (((unsigned __int64)v15 >> 9) & 0x7FFFFFFFF8i64));
v16 <<= 9;
--v17;
}
while( v17 );
}
v41 = (UINT64)MmGetPteBase() + (((unsigned __int64)v15 >> 9) & 0x7FFFFFFFF8i64);
do
{
PointerPte.u.Long = v15->u.Long;
if( !PointerPte.u.Long )
goto LABEL_32;
IsPteDecommittedPage = MiIsPteDecommittedPage(&PointerPte);
v21 = v5;
v5 |= 1u;
v22 = v21 & 0xFFFFFFFE;
if( !IsPteDecommittedPage )
v5 = v22;
if( (v5 & 2) != 0 )
{
v23 = v11 - v16;
if( (v5 & 1) == 0 )
v23 = v11;
v11 = v23;
}
else if( (v5 & 1) == 0 )
{
v11 += v16;
}
if( !v12 )
goto LABEL_31;
NextPteToTrim = VmWorkingSetList[9].NextPteToTrim;
if( !NextPteToTrim || (v5 & 1) != 0 )
goto LABEL_30;
CloneAddress = 0i64;
if( (v20 & 1) != 0 )
{
LODWORD(v26) = MI_READ_PTE_LOCK_FREE((INT64)&PointerPte);
LOBYTE(v30) = MI_PFN_IS_PROTO((_UNICODE_STRING *)&MmGetPfnDb()[(v26 >> 12) & 0xFFFFFFFFFi64], v27, v28, v29);
if( !v30 )
goto LABEL_47;
if( (*(_QWORD *)(v31 + 40) & 0x1000000000i64) == 0 && *(__int64 *)(v31 + 8) > 0 )
{
v12 = v47;
LABEL_30:
VmWorkingSetList = v45;
LABEL_31:
v10 = v44;
goto LABEL_32;
}
v33 = *(_QWORD *)(v31 + 8) | 0x8000000000000000ui64;
goto LABEL_46;
}
if( (v20 & 0x400) != 0 )
{
LOBYTE(v34) = MiIsPrototypePteVadLookup(v20);
if( !v34 && !MI_PROTO_FORMAT_COMBINED(v35) )
{
if( *(&stru_140C4DB30 + 42) && (v36 & 0x10) == 0 )
v36 &= ~*(&stru_140C4DB30 + 42);
v33 = v36 >> 16;
LABEL_46:
CloneAddress = MiLocateCloneAddress(CurrentProcess, (VOID *)v33);
}
}
LABEL_47:
v10 = v44;
if( CloneAddress )
{
v37 = (unsigned __int64)NextPteToTrim <= CloneAddress->NestingLevel;
v12 = v47;
VmWorkingSetList = v45;
if( !v37 )
++*v47;
}
else
{
v12 = v47;
VmWorkingSetList = v45;
}
LABEL_32:
++v15;
v9 += v16;
}
while( ((unsigned __int16)v15 & 0xFFF) != 0 && v9 <= v10 );
v13 = (int)ReducedCommitClonePages;
if( ((unsigned __int8)ReducedCommitClonePages & 4) == 0 )
{
MiUnlockPageTableInternal(p_Vm, v41);
v13 = (int)ReducedCommitClonePages;
}
WsIrql = v46;
}
while( v9 <= v10 );
}
return v11;
}Referenced by:
MiCommitExistingVad
MiCountCommittedPages
MiDeletePartialVad
MiProtectPrivateMemory
MiSetProtectionOnSection