MiFlushDirtyBitsToPfn
NTSTATUS __stdcall MiFlushDirtyBitsToPfn(
VOID *StartingAddress,
VOID *EndingAddress,
_ETHREAD *CurrentThread,
UINT64 AsyncOk){
NTSTATUS result;
_MMPTE *PteBase;
_MMPTE *v9;
_MMPTE *v10;
_MMSUPPORT_INSTANCE *p_Instance;
UINT64 v12;
UINT8 v13;
UINT8 v14;
_MMPTE *NextPageTable;
UINT64 v16;
_MMPFN *v17;
__int64 v18;
UINT64 v19;
UINT64 v20;
_MMPFN *v21;
unsigned __int64 v22;
__int64 v23;
unsigned __int64 v24;
__int64 v25;
UINT64 v26;
UINT64 v27;
_MMPFN *PfnDb;
__int64 v29;
unsigned int v30;
volatile signed __int32 *v31;
unsigned __int64 v32;
UINT64 PageTableFlags;
UINT64 v34;
UINT64 v35;
UINT64 SpinCount;
UINT64 v37;
INT64 v38;
UINT64 v39;
_MI_TB_FLUSH_LIST TbFlushList[48];
LODWORD(SpinCount) = 0;
result = (unsigned int)memset(TbFlushList, 0i64, 0xB8u);
if( !*(&stru_140C4DB30 + 248) )
{
TbFlushList[0] = 1;
LOWORD(TbFlushList[1]) = 0;
*(_QWORD *)&TbFlushList[4] = 0i64;
TbFlushList[2] = 20;
*(_QWORD *)&TbFlushList[6] = 0i64;
PteBase = MmGetPteBase();
v9 = (_MMPTE *)((char *)PteBase + (((unsigned __int64)StartingAddress >> 9) & 0x7FFFFFFFF8i64));
v10 = (_MMPTE *)((char *)PteBase + (((unsigned __int64)EndingAddress >> 9) & 0x7FFFFFFFF8i64));
p_Instance = &CurrentThread->Tcb.ApcState.Process->Vm.Instance;
v38 = (INT64)p_Instance;
MiLockWorkingSetShared();
v14 = v13;
LOBYTE(v34) = v13;
while( v9 <= v10 )
{
LODWORD(PageTableFlags) = 0;
NextPageTable = MiGetNextPageTable(v9, v10, TbFlushList, v14, PageTableFlags, &SpinCount, v34);
v9 = NextPageTable;
if( !NextPageTable )
break;
v16 = (UINT64)PteBase + (((unsigned __int64)NextPageTable >> 9) & 0x7FFFFFFFF8i64);
v39 = v16;
if( (_DWORD)SpinCount )
{
v22 = (unsigned __int64)PteBase + (((unsigned __int64)NextPageTable >> 9) & 0x7FFFFFFFF8i64);
v23 = (unsigned int)SpinCount;
do
{
v16 = (UINT64)PteBase + ((v16 >> 9) & 0x7FFFFFFFF8i64);
--v23;
}
while( v23 );
v24 = 0x200000i64;
if( (unsigned int)SpinCount > 1 )
{
v25 = (unsigned int)(SpinCount - 1);
do
{
v22 = (unsigned __int64)PteBase + ((v22 >> 9) & 0x7FFFFFFFF8i64);
v24 <<= 9;
--v25;
}
while( v25 );
}
LODWORD(v26) = MI_READ_PTE_LOCK_FREE(v22);
v35 = v26;
v27 = v26;
if( (v26 & 1) != 0 && (v26 & 0x42) != 0 )
{
MiPteInShadowRange((UINT64)&v35);
PfnDb = MmGetPfnDb();
v29 = 48 * ((v27 >> 12) & 0xFFFFFFFFFi64) + 24;
v30 = 0;
if( v24 )
{
v31 = (volatile signed __int32 *)((char *)PfnDb + v29);
do
{
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64(v31, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *(__int64 *)v31 < 0 );
}
*((_BYTE *)v31 + 10) |= 0x10u;
_InterlockedAnd64((volatile signed __int64 *)v31, 0x7FFFFFFFFFFFFFFFui64);
v30 += 4096;
v31 += 12;
}
while( v30 < v24 );
p_Instance = (_MMSUPPORT_INSTANCE *)v38;
}
PteBase = MmGetPteBase();
}
LODWORD(v32) = MiGetLeafVa(v22 + 8);
v9 = (_MMPTE *)((char *)PteBase + ((v32 >> 9) & 0x7FFFFFFFF8i64));
}
else
{
v17 = MmGetPfnDb();
v18 = (__int64)(((_QWORD)NextPageTable << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
do
{
LODWORD(v19) = MI_READ_PTE_LOCK_FREE((INT64)v9);
v35 = v19;
v20 = v19;
if( (v19 & 1) != 0 && (v19 & 0x42) != 0 )
{
MiPteInShadowRange((UINT64)&v35);
v21 = &v17[(v20 >> 12) & 0xFFFFFFFFFi64];
LODWORD(v37) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v21->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v37);
while( v21->u2._bf_0 < 0 );
}
*((_BYTE *)&v21->u3 + 2) |= 0x10u;
_InterlockedAnd64(&v21->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
MiWriteValidPteNewProtection((INT64 *)v9, v35 & 0xFFFFFFFFFFFFFFBDui64);
MiInsertTbFlushEntry(TbFlushList, (VOID *)v18, 1ui64, 0i64);
}
v18 += 4096i64;
++v9;
}
while( (v18 & 0x1FFFFF) != 0 && v9 <= v10 );
MiFlushTbList(TbFlushList);
v16 = v39;
p_Instance = (_MMSUPPORT_INSTANCE *)v38;
PteBase = MmGetPteBase();
}
MiUnlockPageTableInternal((INT64)p_Instance, v16);
v14 = v34;
}
LOBYTE(v12) = v14;
MiUnlockWorkingSetShared(p_Instance, v12);
}
return result;
}Referenced by:
MmFlushVirtualMemory