MiCheckCommitReleaseFromVad
NTSTATUS __stdcall MiCheckCommitReleaseFromVad(
_MI_PARTITION *Partition,
_EPROCESS *Process,
_MMSUPPORT_INSTANCE *Vm,
_MMVAD_SHORT *Vad,
UINT64 AcceptStorePages,
UINT64 *ResetPagesNotReleasedCount){
unsigned __int64 v6;
_MMSUPPORT_INSTANCE *v7;
_MMPTE *PteBase;
__int64 v11;
unsigned __int64 v12;
_MMPTE *v13;
UINT64 v14;
UINT8 v15;
UINT8 v16;
_MMPTE *NextPageTable;
unsigned __int64 v18;
UINT64 v19;
__int64 v20;
char *v21;
unsigned __int64 v22;
_MMPTE v23;
__int64 v24;
unsigned __int64 v25;
_MMPFN *v26;
int v27;
_MMPTE v28;
__int64 v29;
__int64 v30;
_MMPFN *v31;
bool v32;
UINT64 v33;
UINT64 PageTableFlags;
UINT64 LargePage;
INT64 bf_0;
UINT64 PagesProcessedOut;
UINT64 v39;
_MMPTE *v40;
UINT8 i;
v6 = (unsigned __int64)Vad->StartingVpnHigh << 32;
v7 = Vm;
LODWORD(LargePage) = 0;
PagesProcessedOut = 0i64;
PteBase = MmGetPteBase();
v11 = 0i64;
v12 = (unsigned __int64)&PteBase[(Vad->StartingVpn | v6) & 0xFFFFFFFFFi64];
v13 = &PteBase[(Vad->EndingVpn | ((unsigned __int64)Vad->EndingVpnHigh << 32)) & 0xFFFFFFFFFi64];
v40 = v13;
MiLockWorkingSetShared();
v16 = v15;
for( i = v15; v12 <= (unsigned __int64)v13; v16 = i )
{
LODWORD(PageTableFlags) = 0;
NextPageTable = MiGetNextPageTable((_MMPTE *)v12, v13, 0i64, v16, PageTableFlags, &LargePage, LargePage);
v18 = (unsigned __int64)NextPageTable;
if( NextPageTable != (_MMPTE *)v12 )
{
v19 = NextPageTable ? (__int64)((__int64)NextPageTable - v12) >> 3 : ((__int64)((__int64)v13 - v12) >> 3) + 1;
LODWORD(v20) = MiComputeCommitChargeForZeroPteRange(Vad, (_MMPTE *)v12, v19);
v11 += v20;
if( !v18 )
break;
}
v12 = v18;
v21 = (char *)MmGetPteBase() + ((v18 >> 9) & 0x7FFFFFFFF8i64);
v22 = (unsigned __int64)v13;
v39 = (UINT64)v21;
if( (v18 & 0xFFFFFFFFFFFFF000ui64) + 4088 <= (unsigned __int64)v13 )
v22 = (v18 & 0xFFFFFFFFFFFFF000ui64) + 4088;
if( v18 <= v22 )
{
while( 1 )
{
LODWORD(v23.u.Long) = MI_READ_PTE_LOCK_FREE(v12);
bf_0 = v23.u.Hard._bf_0;
if( !v23.u.Long )
break;
if( (v23.u.Long & 1) != 0 )
{
if( (v23.u.Long & 0x200) == 0 || (Vad->u.LongFlags & 0x70) == 64 && MiRotatedToFrameBuffer((_MMPTE *)v12) )
goto LABEL_48;
LODWORD(v25) = MI_READ_PTE_LOCK_FREE((INT64)&bf_0);
v26 = &MmGetPfnDb()[(v25 >> 12) & 0xFFFFFFFFFi64];
if( (v26->u4._bf_0 & 0x1000000000i64) == 0 && (__int64)v26->ListEntry.Blink > 0 )
goto LABEL_48;
if( Process->CloneRoot.Root && MiLocateCloneAddress(Process, (VOID *)(v26->PteLong | 0x8000000000000000ui64)) )
goto LABEL_48;
LABEL_47:
++v11;
goto LABEL_48;
}
if( (v23.u.Long & 0x400) != 0 )
{
LOBYTE(v27) = MiIsPrototypePteVadLookup(v23.u.Long);
if( v27 )
{
v29 = v11 + 1;
if( ((v28.u.Long >> 5) & 5) != 5 )
v29 = v11;
v11 = v29;
goto LABEL_48;
}
if( MI_PROTO_FORMAT_COMBINED(v28) )
goto LABEL_48;
if( Process->CloneRoot.Root )
{
if( *(&stru_140C4DB30 + 42) && (v30 & 0x10) == 0 )
v30 &= ~*(&stru_140C4DB30 + 42);
if( MiLocateCloneAddress(Process, (VOID *)(v30 >> 16)) )
goto LABEL_48;
}
MiComputeImageVadCommitCharge(
(_MMVAD *)Vad,
(unsigned __int64)((__int64)((v12 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16) >> 12,
1ui64,
&PagesProcessedOut);
goto LABEL_33;
}
if( (v23.u.Long & 0x800) != 0 )
{
v31 = MiLockTransitionLeafPage(v12, 0i64);
if( v31 )
{
if( (*(_BYTE *)(&v31->u3 + 1) & 0x10) == 0
&& (*(_DWORD *)(&v31->3 + 1) & 4) == 0
&& !v31->u3.ReferenceCount )
{
++*ResetPagesNotReleasedCount;
}
_InterlockedAnd64(&v31->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
}
else
{
v12 -= 8i64;
}
goto LABEL_48;
}
if( (v23.u.Long & 4) != 0 )
{
if( !(_DWORD)AcceptStorePages )
goto LABEL_48;
v32 = MiIsPteInStore(Partition, v23) == 0;
}
else
{
v32 = ((v23.u.Long >> 5) & 0x1F) == 16;
}
if( !v32 )
goto LABEL_47;
LABEL_48:
v12 += 8i64;
if( v12 > v22 )
{
v21 = (char *)v39;
v13 = v40;
goto LABEL_50;
}
}
LODWORD(v24) = MiComputeCommitChargeForZeroPteRange(Vad, (_MMPTE *)v12, 1ui64);
LABEL_33:
v11 += v24;
goto LABEL_48;
}
LABEL_50:
v33 = (UINT64)v21;
v7 = Vm;
MiUnlockPageTableInternal((INT64)Vm, v33);
}
LOBYTE(v14) = v16;
MiUnlockWorkingSetShared(v7, v14);
return v11;
}Referenced by:
MiReleaseOutSwappedProcessCommit