MiAgePte
INT64 __fastcall MiAgePte(INT64 a1, INT64 a2, UINT8 *a3){
INT64 v3;
INT64 v4;
INT64 v5;
INT64 v6;
__int64 v7;
unsigned __int64 v8;
unsigned __int64 v9;
int v10;
unsigned __int64 v11;
unsigned __int64 v12;
__int64 v13;
unsigned __int64 *v14;
char v15;
KSPIN_LOCK_QUEUE *v16;
__int64 v17;
unsigned __int64 v18;
_KSPIN_LOCK_QUEUE *volatile Next;
unsigned __int64 v20;
_MMPTE *PteBase;
__int64 v22;
unsigned __int64 v23;
UINT64 v24;
UINT64 v25;
_QWORD *v26;
__int64 v27;
_MMPTE *v28;
unsigned __int64 v29;
_MMPTE *PteLimit;
__int64 v31;
UINT64 *v32;
CHAR v34;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v36;
int v39;
UINT64 v40;
v39 = (int)a3;
v3 = *(_QWORD *)(a1 + 168);
v4 = a2;
v5 = *(_QWORD *)(a1 + 24);
v6 = a1;
v7 = *(_QWORD *)(v5 + 16);
if( *(_BYTE *)(v3 + 6) != 1 )
goto LABEL_22;
*(_BYTE *)(v3 + 6) = 0;
v7 = *(_QWORD *)(v5 + 16);
v8 = *(_QWORD *)(v5 + 136);
v9 = *(_QWORD *)(v7 + 32);
if( v8 <= v9 )
return 3i64;
v10 = *(_DWORD *)v3;
v11 = v8 - v9;
v12 = *(unsigned int *)(v3 + 12);
v13 = 0i64;
if( (*(_DWORD *)v3 & 4) == 0 )
{
v14 = &qword_140C4F500;
v15 = *(_BYTE *)(v5 + 184) & 7;
v36 = 0i64;
if( v15 != 2 )
v14 = (unsigned __int64 *)(v5 + 256);
LockQueue.Lock = v14;
LockQueue.Next = 0i64;
v16 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64((volatile __int64 *)v14, (__int64)&LockQueue);
if( v16 )
KxWaitForLockOwnerShip(&LockQueue, v16);
if( (v10 & 2) != 0 )
{
v17 = *(unsigned int *)(v7 + 24);
v18 = v17 + v11;
*(_DWORD *)(v7 + 24) = (v17 + v11) % v12;
}
else
{
v17 = *(unsigned int *)(v7 + 28);
v18 = v17 + v11;
*(_DWORD *)(v7 + 28) = (v17 + v11) % v12;
}
_m_prefetchw(&LockQueue);
Next = LockQueue.Next;
if( !LockQueue.Next )
{
if( (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockQueue.Lock,
0i64,
(signed __int64)&LockQueue) == &LockQueue )
{
LABEL_15:
if( v18 < v11 )
v17 = 0i64;
v13 = v17;
goto LABEL_18;
}
Next = KxWaitForLockChainValid(&LockQueue);
}
LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_15;
}
LABEL_18:
v20 = v12 * (v13 + v11) / 0x3E8;
if( v20 > v11 )
v20 = v11 * v12 / 0x3E8;
*(_QWORD *)(v3 + 48) = v20;
if( *(_QWORD *)(v3 + 40) >= v20 )
return 3i64;
v4 = a2;
v6 = a1;
LABEL_22:
PteBase = MmGetPteBase();
v22 = (_QWORD)PteBase << 25;
v23 = ((v4 << 25) - ((_QWORD)PteBase << 25)) >> 16;
v24 = (UINT64)PteBase + ((v23 >> 9) & 0x7FFFFFFFF8i64);
v40 = *(_QWORD *)v24;
v25 = v40;
MiPteInShadowRange((UINT64)&v40);
v26 = (_QWORD *)((char *)MmGetPfnDb() + 48 * ((v25 >> 12) & 0xFFFFFFFFFi64));
if( v39 )
{
v28 = MmGetPteBase();
v27 = (__int64)((v24 << 25) - v22 + 0x10000000) >> 16;
v29 = ((v27 << 25) - v22) >> 16;
if( v29 >= (unsigned __int64)v28 )
{
PteLimit = MmGetPteLimit();
do
{
if( v29 > (unsigned __int64)PteLimit )
break;
v27 = v29;
v29 = (__int64)((v29 << 25) - v22) >> 16;
}
while( v29 >= (unsigned __int64)v28 );
}
}
else
{
v27 = v24 + 8;
}
if( (*(_DWORD *)v3 & 2) != 0 )
{
*(_QWORD *)(v7 + 16) = v27;
}
else if( (*(_DWORD *)v3 & 4) == 0 )
{
*(_QWORD *)(v7 + 8) = v27;
}
if( !v39 || (v26[3] & 0x3FFFFFFFFFFFFFFFi64) == 1 && !(unsigned int)MiIsPageTableLocked(v5, v24) )
{
if( (v26[5] & 0x1000000000i64) == 0 )
{
v31 = v26[1];
if( v31 > 0
&& (unsigned int)MiDemoteCombinedPte(
(_MMSUPPORT_INSTANCE *)v5,
(_MMPTE *)v24,
(_MMPTE *)(v31 | 0x8000000000000000ui64)) == 1 )
{
v40 = MI_READ_PTE_LOCK_FREE(v24);
}
}
if( ((v40 >> 5) & 1) != 0 && (v32 = *(UINT64 **)(v3 + 248)) != 0i64 && v23 <= 0x7FFFFFFEFFFFi64 )
{
if( (unsigned int)MiInsertVmAccessedEntry(v32, v23) )
return MiAgeWorkingSetTail(v6);
}
else
{
v34 = ((v40 & 0x20) != 0) | 2;
if( (*(_DWORD *)v3 & 3) == 0 )
v34 = (v40 & 0x20) != 0;
MiAgePteWorker(v5, v24, v23, (INT64)v26, v3, v34);
}
if( ++*(_QWORD *)(v3 + 40) >= *(_QWORD *)(v3 + 48) )
return 3i64;
}
return 0i64;
}Referenced by:
No references.