MiMoveDirtyBitsToPfns
VOID __fastcall MiMoveDirtyBitsToPfns(_MMPTE *PointerPte, _MMPTE *EndPte, INT64 WsIrql, _KTBFLUSH_TYPE a4){
char v7;
UINT64 v8;
_MMPTE *PteBase;
unsigned __int64 v10;
unsigned __int64 v11;
_EPROCESS *Process;
_MMSUPPORT_INSTANCE *p_Instance;
__int64 *i;
volatile signed __int32 *v15;
unsigned __int8 v16;
volatile __int32 *v17;
UINT64 CurrentIrql;
struct _KPRCB *CurrentPrcb;
int v20;
__int64 v21;
__int64 v22;
int v23;
_MMPTE *v24;
unsigned __int64 v25;
unsigned __int64 v26;
_MMSUPPORT_FULL *AnyMultiplexedVm;
NTSTATUS v28;
unsigned int v29;
_MMPTE *v30;
UINT64 v31;
UINT64 v32;
unsigned __int64 v33;
_MMPTE *v34;
unsigned __int64 v35;
unsigned __int64 v36;
__int64 v37;
__int64 v38;
__int64 v39;
unsigned __int64 v40;
_MMPTE *v41;
_MMPTE *v42;
unsigned __int64 v43;
unsigned __int64 v44;
signed __int32 v45;
__int64 v46;
signed __int32 v47;
unsigned __int64 v48;
unsigned __int64 v49;
_BYTE *v50;
char v51;
int v52;
int v53;
__int64 v54;
unsigned __int64 v55;
_MMPTE *v56;
_MMPTE *v57;
_MMSUPPORT_FLAGS Flags;
__int64 v59;
_MMPTE *v60;
unsigned int v61;
unsigned __int64 v62;
UINT64 v63;
int v64;
char v65;
__int64 v66;
unsigned int v67;
char v68;
__int64 v69;
unsigned __int64 v70;
UINT64 v71;
_MI_PARTITION *v72;
_MMPFN *v73;
unsigned __int8 v74;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v75;
__int64 v76;
__int64 v77;
unsigned __int64 v78;
unsigned __int64 v79;
int v80;
_MMPTE *PteLimit;
unsigned __int64 v82;
__int64 v83;
unsigned __int64 v84;
__int64 v85;
UINT64 v86;
INT64 v87;
_MMPTE *v88;
INT64 *v89;
UINT64 v90;
UINT64 v91;
UINT64 v92;
unsigned __int64 v93;
UINT64 SpinCount;
_MMSUPPORT_FULL *p_Vm;
__int64 v96;
INT64 v97;
UINT64 v98;
unsigned __int64 *v99;
__int64 v100;
__int128 v101;
_MMWSL_INSTANCE *VmWorkingSetList;
__int64 v103;
_QWORD v104[22];
_MI_TB_FLUSH_LIST TbFlushList;
__int16 v106;
__int16 v107;
__int64 v108;
__int64 v109;
__int64 Base[21];
v97 = WsIrql;
LOBYTE(v89) = a4;
v107 = 0;
v100 = 0i64;
v7 = a4;
memset(&Base[1], 0i64, 0x98u);
v90 = 0i64;
v8 = 0i64;
HIDWORD(v89) = 0;
PteBase = MmGetPteBase();
v10 = (unsigned __int64)PteBase + (((unsigned __int64)PointerPte >> 9) & 0x7FFFFFFFF8i64);
v11 = (unsigned __int64)PteBase + (((unsigned __int64)EndPte >> 9) & 0x7FFFFFFFF8i64);
v93 = v11;
Process = KeGetCurrentThread()->ApcState.Process;
p_Instance = &Process->Vm.Instance;
VmWorkingSetList = Process->Vm.Instance.VmWorkingSetList;
p_Vm = &Process->Vm;
HIDWORD(SpinCount) = v7 & 1;
if( (v7 & 1) != 0 )
{
for( i = *(__int64 **)(WsIrql + 56); i; i = (__int64 *)*i )
{
if( (i[8] & 4) != 0 )
break;
}
v99 = (unsigned __int64 *)(i + 1);
}
else
{
v99 = 0i64;
}
v106 = 0;
v109 = 0i64;
Base[0] = 0i64;
v15 = (volatile signed __int32 *)((char *)&stru_140C4DB30 + 6544);
v108 = 20i64;
TbFlushList = 1;
v16 = p_Instance->Flags._bf_0 & 7;
if( v16 >= 6u )
{
CurrentIrql = KeGetCurrentIrql();
v91 = CurrentIrql;
__writecr8(2ui64);
}
else
{
if( v16 == 2 )
v17 = (volatile __int32 *)((char *)&stru_140C4DB30 + 6544);
else
v17 = (volatile __int32 *)&p_Instance[1];
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
if( CurrentPrcb->SchedulerAssist && CurrentPrcb->NestingLevel <= 1u && CurrentPrcb->NestingLevel == 1 )
PteBase = MmGetPteBase();
_m_prefetchw((const void *)v17);
v20 = *v17 & 0x7FFFFFFF;
if( v20 != _InterlockedCompareExchange(v17, v20 + 1, v20) )
{
ExpWaitForSpinLockSharedAndAcquire((INT64 *)v17, CurrentIrql);
PteBase = MmGetPteBase();
}
v8 = 0i64;
if( *((_DWORD *)v17 + 1) )
_InterlockedExchange(v17 + 1, 0);
v91 = CurrentIrql;
}
if( v10 > v11 )
goto LABEL_68;
v21 = (_QWORD)PteBase << 25;
v96 = (_QWORD)PteBase << 25;
v22 = (__int64)((v11 << 25) - ((_QWORD)PteBase << 25)) >> 16;
v23 = (unsigned __int8)v89 & 2;
v103 = v22;
LODWORD(v89) = v23;
while( 2 )
{
if( v8 )
{
MiFlushTbList(&TbFlushList);
MiUnlockPageTableInternal((INT64)p_Instance, v8);
v90 = 0i64;
LOBYTE(v80) = MiWorkingSetIsContended((INT64)p_Instance);
if( v80 || (unsigned int)KeShouldYieldProcessor() )
{
MiUnlockWorkingSetShared(p_Instance, (unsigned __int8)CurrentIrql);
MiLockWorkingSetShared();
}
v23 = (int)v89;
}
if( v23 )
_InterlockedIncrement64((volatile signed __int64 *)&VmWorkingSetList[15].NextPteToAccessClear);
v101 = 0i64;
memset((char *)v104 + 2, 0i64, 0xAEu);
v24 = MmGetPteBase();
LOWORD(v104[0]) = 2273;
v25 = (__int64)((v10 << 25) - v21) >> 16;
v26 = v25;
if( v25 >= (unsigned __int64)v24 )
{
PteLimit = MmGetPteLimit();
do
{
if( v26 > (unsigned __int64)PteLimit )
break;
v26 = (__int64)((v26 << 25) - v21) >> 16;
}
while( v26 >= (unsigned __int64)v24 );
p_Instance = &p_Vm->Instance;
}
if( v26 < 0xFFFF800000000000ui64 || v26 >= *(&stru_140C4DB30 + 937) && v26 <= *(&stru_140C4DB30 + 175) )
AnyMultiplexedVm = &KeGetCurrentThread()->ApcState.Process->Vm;
else
AnyMultiplexedVm = (_MMSUPPORT_FULL *)MiGetAnyMultiplexedVm(MiWorkingSetTypeSystemViews, v24);
v28 = MiFastLockLeafPageTable((INT64)AnyMultiplexedVm, v25);
if( v28 )
{
v29 = v28 - 1;
LODWORD(v101) = v28 - 1;
v30 = MmGetPteBase();
v31 = (UINT64)v30 + ((v25 >> 9) & 0x7FFFFFFFF8i64);
*((_QWORD *)&v101 + 1) = v31;
}
else
{
LOWORD(v104[0]) |= 4u;
v104[21] = &v101;
v104[2] = 0i64;
v104[3] = AnyMultiplexedVm;
BYTE2(v104[0]) = BYTE2(v104[0]) & 0xE3 | 4;
v104[20] = MiGetNextPageTableTail;
BYTE6(v104[0]) = v91;
v104[4] = v25;
v104[5] = v22;
MiWalkPageTables((INT64)v104);
v29 = v101;
v31 = *((_QWORD *)&v101 + 1);
v30 = MmGetPteBase();
}
v32 = v31;
if( v31 )
{
v90 = (UINT64)v30 + ((v31 >> 9) & 0x7FFFFFFFF8i64);
if( v29 )
{
v32 = (UINT64)v30 + ((v31 >> 9) & 0x7FFFFFFFF8i64);
v82 = (unsigned __int64)v30 + ((v11 >> 9) & 0x7FFFFFFFF8i64);
if( v29 > 1 )
{
v83 = v29 - 1;
do
{
v32 = (UINT64)v30 + ((v32 >> 9) & 0x7FFFFFFFF8i64);
v82 = (unsigned __int64)v30 + ((v82 >> 9) & 0x7FFFFFFFF8i64);
--v83;
}
while( v83 );
}
v84 = v32 + 8;
v90 = (UINT64)v30 + ((v32 >> 9) & 0x7FFFFFFFF8i64);
if( ((v32 + 8) & 0xFFF) != 0 )
{
do
{
if( v84 > v82 )
break;
LODWORD(v85) = MI_READ_PTE_LOCK_FREE(v84);
v100 = v85;
if( (v85 & 1) == 0 )
break;
if( (v85 & 0x80u) == 0i64 )
break;
v84 += 8i64;
}
while( (v84 & 0xFFF) != 0 );
v30 = MmGetPteBase();
}
v33 = v84 - 8;
}
else
{
v33 = (v31 & 0xFFFFFFFFFFFFF000ui64) + 4088;
if( v33 > v11 )
v33 = v11;
}
}
else
{
v33 = v11;
}
if( !HIDWORD(SpinCount) )
goto LABEL_52;
HIDWORD(v89) = 1;
if( v10 >= (unsigned __int64)v30 )
{
v34 = MmGetPteLimit();
do
{
if( v10 > (unsigned __int64)v34 )
break;
v10 = (__int64)((v10 << 25) - v96) >> 16;
}
while( v10 >= (unsigned __int64)v30 );
p_Instance = &p_Vm->Instance;
}
v35 = (v10 >> 12) - (*(unsigned int *)(v97 + 24) | ((unsigned __int64)*(unsigned __int8 *)(v97 + 32) << 32));
LODWORD(v36) = MiGetVadMandatoryPageSize(v97);
if( v36 != 1 )
v35 /= v36;
v40 = v33 + 8;
v41 = MmGetPteBase();
if( v33 + 8 >= (unsigned __int64)v41 )
{
v42 = MmGetPteLimit();
do
{
if( v40 > (unsigned __int64)v42 )
break;
v40 = (__int64)((v40 << 25) - v38) >> 16;
}
while( v40 >= (unsigned __int64)v41 );
p_Instance = &p_Vm->Instance;
}
if( v40 > (((*(unsigned int *)(v39 + 28) | ((unsigned __int64)*(unsigned __int8 *)(v39 + 33) << 32)) << 12) | 0xFFF) )
{
v43 = *v99;
}
else
{
v43 = (v40 >> 12) - v37;
if( v36 != 1 )
v43 /= v36;
}
v44 = v43 - v35;
LODWORD(SpinCount) = 0;
KeGetCurrentIrql();
__writecr8(2ui64);
v45 = *(_DWORD *)(v39 + 48);
v46 = v39;
do
{
while( (v45 & 1) != 0 )
{
if( (v45 & 2) != 0 )
{
LODWORD(SpinCount) = 0;
do
{
KeYieldProcessorEx(&SpinCount);
v45 = *(_DWORD *)(v46 + 48);
}
while( (v45 & 1) != 0 );
}
else
{
v45 = _InterlockedCompareExchange((volatile signed __int32 *)(v46 + 48), v45 | 2, v45);
}
}
v47 = v45;
v45 = _InterlockedCompareExchange((volatile signed __int32 *)(v46 + 48), v45 & 0xFFFFFFFC | 1, v45);
}
while( v47 != v45 );
v11 = v93;
if( !v44 )
goto LABEL_52;
v48 = v35;
v49 = v35 & 7;
v50 = (_BYTE *)(v99[1] + (v48 >> 3));
if( v49 + v44 > 8 )
{
if( (_DWORD)v49 )
{
*v50++ &= byte_14001DA00[v49];
v44 -= (unsigned int)(8 - v49);
}
if( v44 > 8 )
{
memset(v50, 0i64, v44 >> 3);
v50 += v44 >> 3;
v44 &= 7u;
}
if( !v44 )
goto LABEL_51;
v51 = byte_14001A768[v44];
}
else
{
v51 = ~(byte_14001DA00[v44] << v49);
}
*v50 &= v51;
LABEL_51:
v11 = v93;
LABEL_52:
if( !v31 )
break;
if( v32 > v33 )
goto LABEL_59;
v52 = HIDWORD(SpinCount);
v53 = (int)v89;
do
{
v54 = *(_QWORD *)v32;
v100 = v54;
if( (v54 & 1) == 0 || (v54 & 0x42) == 0 )
goto LABEL_57;
if( !v52 )
{
if( v53 && v54 < 0 )
goto LABEL_57;
LODWORD(v86) = MiGetLeafVa(v32);
if( (MiGetWsleContents(v87, v86) & 0xF) == 9 )
goto LABEL_57;
}
v59 = *(_QWORD *)v32;
v60 = MmGetPteBase();
v92 = *(_QWORD *)v32 & 0xFFFFFFFFFFFFFFBDui64;
v61 = 0;
v62 = (__int64)((v32 << 25) - v96) >> 16;
if( v62 < (unsigned __int64)v60 )
goto LABEL_82;
v88 = MmGetPteLimit();
do
{
if( v62 > (unsigned __int64)v88 )
break;
++v61;
v62 = (__int64)((v62 << 25) - v96) >> 16;
}
while( v62 >= (unsigned __int64)v60 );
if( v61 )
{
MiRewritePteWithLockBit((INT64)&KeGetCurrentThread()->ApcState.Process->Vm, (INT64 *)v32, v92);
MiInsertLargeTbFlushEntry(&TbFlushList, v61, v32);
}
else
{
LABEL_82:
v63 = v92 ^ (v59 ^ v92) & 0xF00000000000000i64 ^ (v59 ^ v92 ^ (v59 ^ v92) & 0xF00000000000000i64) & 0x7000000000000000i64;
LOBYTE(v64) = MiPteInShadowRange(v32);
if( v64 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v63 & 1) != 0 )
v63 |= 0x8000000000000000ui64;
*(_QWORD *)v32 = v63;
v65 = v106;
v66 = 1i64;
if( TbFlushList != 1
&& (v106 & 8) == 0
&& v62 >= (unsigned __int64)v60
&& v62 <= (unsigned __int64)MmGetPteLimit() )
{
v65 = v106 | 8;
LOBYTE(v106) = v106 | 8;
}
v67 = HIDWORD(v108);
if( !HIDWORD(v108) )
{
LABEL_99:
if( HIDWORD(v108) >= (unsigned int)v108 )
{
HIBYTE(v106) = 1;
}
else
{
while( 1 )
{
v77 = (unsigned __int64)(v66 - 1) > 0x3FF ? 1024i64 : v66;
v78 = v62 & 0xFFFFFFFFFFFFF000ui64 | ((_WORD)v77 - 1) & 0x3FF;
v66 -= v77;
v62 += v77 << 12;
Base[v67] = v78;
v109 += v77;
v67 = HIDWORD(v108) + 1;
HIDWORD(v108) = v67;
if( v67 == (_DWORD)v108 && (v106 & 4) == 0 )
{
qsort((UINT64)Base, v67, 8ui64, (INT64)MiTbFlushSort, v89, v90, v91);
MiCompressTbFlushList(&TbFlushList);
v67 = HIDWORD(v108);
if( HIDWORD(v108) == (_DWORD)v108 )
break;
}
if( !v66 )
goto LABEL_91;
}
if( v66 )
{
HIBYTE(v106) = 1;
v109 = HIDWORD(v108);
}
}
goto LABEL_91;
}
v68 = v65 & 4;
if( v68
|| (v69 = Base[HIDWORD(v108) - 1], (v69 & 0xC00) != 0)
|| (v70 = Base[HIDWORD(v108) - 1] & 0x3FF, (v69 & 0xFFFFFFFFFFFFF000ui64) + ((v70 + 1) << 12) != v62)
|| v70 + 1 <= v70
|| v70 + 1 > 0x3FF )
{
if( v68 )
goto LABEL_99;
v76 = Base[HIDWORD(v108) - 1];
if( (v76 & 0xC00) != 0 )
goto LABEL_99;
if( (v76 & 0xFFFFFFFFFFFFF000ui64) != v62 + 4096 )
goto LABEL_99;
v79 = Base[HIDWORD(v108) - 1] & 0x3FF;
if( v79 + 1 > 0x3FF || v79 + 1 <= v79 )
goto LABEL_99;
++v109;
Base[HIDWORD(v108) - 1] = ((unsigned __int16)(v76 - 4096) ^ (unsigned __int16)(v76 - 4096 + 1)) & 0x3FF ^ (unsigned __int64)(v76 - 4096);
}
else
{
++v109;
Base[HIDWORD(v108) - 1] = ((unsigned __int16)v69 ^ (unsigned __int16)(v69 + 1)) & 0x3FF ^ (unsigned __int64)v69;
}
}
LABEL_91:
v71 = v92;
MiPteInShadowRange((UINT64)&v92);
v72 = 0i64;
v73 = &MmGetPfnDb()[(v71 >> 12) & 0xFFFFFFFFFi64];
LODWORD(v98) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v73->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v98);
while( v73->u2._bf_0 < 0 );
}
v74 = *((_BYTE *)&v73->u3 + 2);
v75.Long = 0i64;
if( (v74 & 0x10) == 0 )
{
if( (!_bittest64(
&v73->OriginalPte.u.Hard.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0,
0xAu) & (unsigned __int8)~(v74 >> 3)) != 0 )
{
v75.Long = MiCapturePageFileInfoInline(&v73->OriginalPte, 1ui64, 0i64).u.Long;
v74 = *((_BYTE *)&v73->u3 + 2);
}
*((_BYTE *)&v73->u3 + 2) = v74 | 0x10;
if( v75.Long )
v72 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v73->u4._bf_0 >> 39) & 0x3FF));
}
_InterlockedAnd64(&v73->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v75.Long )
MiReleasePageFileInfo(v72, (_MMPTE)v75.Long, 1ui64);
LABEL_57:
v32 += 8i64;
}
while( v32 <= v33 );
p_Instance = &p_Vm->Instance;
v11 = v93;
LABEL_59:
if( HIDWORD(v89) )
{
_InterlockedAnd((volatile signed __int32 *)(v97 + 48), 0xFFFFFFFC);
__writecr8(2ui64);
HIDWORD(v89) = 0;
}
v55 = v32;
v56 = MmGetPteBase();
if( v32 >= (unsigned __int64)v56 )
{
v57 = MmGetPteLimit();
do
{
if( v55 > (unsigned __int64)v57 )
break;
v55 = (__int64)((v55 << 25) - v96) >> 16;
}
while( v55 >= (unsigned __int64)v56 );
p_Instance = &p_Vm->Instance;
v11 = v93;
}
v21 = v96;
v10 = (unsigned __int64)v56 + ((v55 >> 9) & 0x7FFFFFFFF8i64);
v22 = v103;
v23 = (int)v89;
if( v10 <= v11 )
{
v8 = v90;
LOBYTE(CurrentIrql) = v91;
continue;
}
break;
}
v15 = (volatile signed __int32 *)((char *)&stru_140C4DB30 + 6544);
LABEL_68:
MiFlushTbList(&TbFlushList);
if( HIDWORD(v89) )
MiUnlockVadCore(v97, 2u);
if( v90 )
MiUnlockPageTableInternal((INT64)p_Instance, v90);
if( (p_Instance->Flags._bf_0 & 7u) < 6 )
{
Flags = p_Instance->Flags;
if( (Flags.$2436257948A9E417F8C1432C685A007E::$56A022E0416FA8F0D143F219D5D8FA21::_bf_0 & 8) != 0
|| (Flags.$2436257948A9E417F8C1432C685A007E::$56A022E0416FA8F0D143F219D5D8FA21::_bf_0 & 4) != 0
|| (Flags.$2436257948A9E417F8C1432C685A007E::$56A022E0416FA8F0D143F219D5D8FA21::_bf_0 & 0x10) != 0 )
{
MiPreUnlockWorkingSetShared(p_Instance, v91);
Flags.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 = p_Instance->Flags._bf_0;
}
if( (Flags.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 & 7) != 2 )
v15 = (volatile signed __int32 *)&p_Instance[1];
MiCheckProcessShadow();
_InterlockedAnd(v15, 0xBFFFFFFF);
_InterlockedDecrement(v15);
}
__writecr8((unsigned __int8)v91);
}Referenced by:
MiBeginHoldingDirtyFaults
MiProcessVaRangesInfoClass
NtResetWriteWatch