MiAgeWorkingSet
INT64 __fastcall MiAgeWorkingSet(_MMSUPPORT_INSTANCE *VmSupport, UINT8 WsIrql, UINT64 AgingFlags, UINT64 Percent){
unsigned int v4;
int v6;
_MMWSL_INSTANCE *VmWorkingSetList;
int v8;
unsigned __int64 WorkingSetSize;
__int64 v10;
unsigned __int64 LockedEntries;
signed __int32 v12;
unsigned __int64 v13;
unsigned int v14;
int v15;
unsigned __int64 *v16;
struct _KPRCB *CurrentPrcb;
KSPIN_LOCK_QUEUE *v18;
__int64 LastAccessClearingRemainder;
unsigned __int64 v20;
_KSPIN_LOCK_QUEUE *volatile Next;
struct _KPRCB *v22;
unsigned __int64 v23;
__int64 PartitionId;
char *v25;
_QWORD *v26;
__int64 v27;
_QWORD *v28;
unsigned __int64 v29;
__int64 v30;
_QWORD *v31;
int v32;
unsigned __int8 v33;
int v34;
char v35;
unsigned __int8 v36;
int v37;
CHAR *RandomPte;
char v39;
const CHAR *v40;
char *v43;
unsigned __int128 v44;
int v45;
__int64 v46;
char v48;
_MMWSL_INSTANCE *v49;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v51;
int v52;
int v53;
int v54;
__int64 v55;
__int64 v56;
__int64 v57;
__int64 v58;
int result;
__int16 result_4;
int v61;
unsigned int v62;
__int64 v63;
__int64 v64;
__int64 v65;
__int64 v66;
unsigned __int64 v67;
char *v68;
int v69;
__int16 v70;
__int64 v71;
__int64 v72;
__int64 v73;
INT64 *v74;
_WORD v75[3];
UINT8 v76;
_MMSUPPORT_INSTANCE *v77;
__int64 v78;
CHAR *v79;
INT64(__fastcall *v80)(INT64, INT64, UINT8 *);
INT64(__fastcall *v81)(INT64);
int *p_result;
char v83[192];
_DWORD v84[68];
__int64 v85[6];
char v86[16];
int *v87;
__int64 v88;
__int64 *v89;
__int64 v90;
__int64 *v91;
__int64 v92;
__int64 *v93;
__int64 v94;
__int64 *v95;
__int64 v96;
int *v97;
__int64 v98;
v4 = Percent;
v6 = AgingFlags;
memset((INT64)v83, 0i64);
memset((INT64)&result, 0i64);
memset((INT64)v75, 0i64);
memset((INT64)v84, 0i64);
VmWorkingSetList = VmSupport->VmWorkingSetList;
v8 = 3;
WorkingSetSize = VmSupport->WorkingSetSize;
v10 = 0i64;
v49 = VmWorkingSetList;
LockedEntries = VmWorkingSetList->LockedEntries;
v12 = 1;
if( WorkingSetSize <= LockedEntries )
goto LABEL_45;
v13 = WorkingSetSize - LockedEntries;
v14 = 10;
if( v4 )
v14 = v4;
v52 = v6 & 4;
if( (v6 & 4) == 0 )
{
v15 = *(_BYTE *)&VmSupport->Flags.0 & 7;
v51 = 0i64;
if( (_BYTE)v15 == 2 )
v16 = &qword_140C4F500;
else
v16 = &VmSupport[1].AgeDistribution[3];
LockQueue.Lock = v16;
LockQueue.Next = 0i64;
CurrentPrcb = KeGetCurrentPrcb();
if( *((_QWORD *)CurrentPrcb + 4247) && *((_BYTE *)CurrentPrcb + 32) <= 1u && *((_BYTE *)CurrentPrcb + 32) == 1 )
{
VmWorkingSetList = v49;
v10 = 0i64;
}
v18 = (KSPIN_LOCK_QUEUE *)_InterlockedExchange64((volatile __int64 *)v16, (__int64)&LockQueue);
if( v18 )
{
KxWaitForLockOwnerShip(&LockQueue, v18);
VmWorkingSetList = v49;
v10 = 0i64;
}
if( (v6 & 2) != 0 )
{
LastAccessClearingRemainder = VmWorkingSetList->LastAccessClearingRemainder;
v20 = v13 + LastAccessClearingRemainder;
VmWorkingSetList->LastAccessClearingRemainder = (v13 + LastAccessClearingRemainder) % v14;
}
else
{
LastAccessClearingRemainder = VmWorkingSetList->LastAgingRemainder;
v20 = v13 + LastAccessClearingRemainder;
VmWorkingSetList->LastAgingRemainder = (v13 + LastAccessClearingRemainder) % v14;
}
_m_prefetchw(&LockQueue);
Next = LockQueue.Next;
if( !LockQueue.Next )
{
Next = (_KSPIN_LOCK_QUEUE *volatile)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockQueue.Lock,
0i64,
(signed __int64)&LockQueue);
if( Next == &LockQueue )
{
LABEL_14:
v22 = KeGetCurrentPrcb();
if( *((_QWORD *)v22 + 4247) && *((_BYTE *)v22 + 32) <= 1u && !(_DWORD)Next )
v10 = 0i64;
v12 = 1;
if( v20 >= v13 )
goto LABEL_16;
goto LABEL_68;
}
Next = KxWaitForLockChainValid(&LockQueue);
v10 = 0i64;
}
LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_14;
}
LABEL_68:
LastAccessClearingRemainder = 0i64;
LABEL_16:
v23 = v14 * (v13 + LastAccessClearingRemainder) / 0x3E8;
if( v23 > v13 )
{
v44 = v13 * v14 * (unsigned __int128)0x624DD2F1A9FBE77ui64;
v23 = (*((_QWORD *)&v44 + 1) + ((v13 * v14 - *((_QWORD *)&v44 + 1)) >> 1)) >> 9;
}
PartitionId = VmSupport->PartitionId;
v62 = v14;
v25 = 0i64;
v26 = *(_QWORD **)(qword_140C4E388 + 8 * PartitionId);
v27 = v26[856];
if( (v6 & 3) != 0 )
{
v28 = v26 + 304;
v29 = v26[280] + v26[288];
v30 = 0i64;
v31 = v26 + 329;
if( v28 < v31 )
{
do
{
v30 += *v28;
v10 += v28[5];
v28 += 10;
}
while( v28 < v31 - 5 );
if( v28 < v31 )
v29 += *v28;
v29 += v30 + v10;
}
if( v29 + *v31 < *(_QWORD *)(v27 + 72) )
{
if( VmSupport->Flags.MemoryPriority != 2 )
{
if( v29 >= *(_QWORD *)(v27 + 64) )
v8 = 5;
v61 = v8;
}
if( (*(_BYTE *)&VmSupport->Flags.0 & 7) != 0
|| !(unsigned int)MiIsStoreProcess((__int64)&VmSupport[-9].AgeDistribution[3]) )
{
result_4 = *(_WORD *)(v27 + 2350);
}
}
if( v23 <= 0x100 )
goto LABEL_88;
v32 = 509;
if( v23 < 0x1FD )
v32 = v23;
LODWORD(v43) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
v25 = v43;
v12 = 1;
if( !v43 )
{
LABEL_88:
if( _InterlockedCompareExchange((volatile signed __int32 *)(v27 + 124), v12, 0) )
{
v25 = v83;
v32 = 20;
}
else
{
v25 = (char *)(v27 + 128);
v32 = 256;
}
}
v33 = *(_BYTE *)&VmSupport->Flags.0 & 7;
if( v33 )
v34 = v33 < 2u ? 2 : 0;
else
v34 = v12;
*(_DWORD *)v25 = v34;
*((_DWORD *)v25 + 3) = 0;
*((_WORD *)v25 + 2) = 0;
*((_QWORD *)v25 + 2) = 0i64;
*((_QWORD *)v25 + 3) = 0i64;
*((_DWORD *)v25 + 2) = v32;
if( (*(_BYTE *)&VmSupport->Flags.0 & 7) == 0 && VmSupport[3].AgeDistribution[1] )
{
v84[1] = 32;
v74 = (INT64 *)v84;
}
}
v76 = WsIrql;
v35 = (char)VmSupport->Flags.0;
v77 = VmSupport;
result = v6;
v67 = v23;
v68 = v25;
v36 = v35 & 7;
if( v36 )
v37 = v36 < 2u ? 2 : 0;
else
v37 = v12;
v69 = v37;
p_result = &result;
v75[0] = 14;
v80 = MiAgePte;
v81 = MiAgeWorkingSetTail;
v71 = 20i64;
v70 = 4;
v72 = 0i64;
v73 = 0i64;
if( v52 )
{
RandomPte = MiGenerateRandomPte((INT64)v75);
}
else if( (v6 & 2) != 0 )
{
RandomPte = (CHAR *)v49->NextPteToAccessClear;
}
else
{
RandomPte = (CHAR *)v49->NextPteToAge;
}
v79 = RandomPte;
if( !RandomPte )
v78 = -1i64;
v8 = MiWalkPageTables((INT64)v75);
if( v25 )
{
if( v25 == (char *)(v27 + 128) )
{
_InterlockedAnd((volatile signed __int32 *)(v27 + 124), 0);
}
else if( v25 != v83 )
{
ExFreePoolWithTag(v25, 0);
}
}
if( v8 == 4 )
++*(_DWORD *)(v27 + 2568);
LABEL_45:
if( *(_QWORD *)&qword_140C4EC20 )
{
v39 = *(_BYTE *)&VmSupport->Flags.0 & 7;
v40 = v39 ? 0i64 : (const CHAR *)&VmSupport[-2].HardFaultCount;
if( **(_DWORD **)&qword_140C4EC20 > 5u
&& (*(_BYTE *)(*(_QWORD *)&qword_140C4EC20 + 16i64) & 1) != 0
&& (*(_QWORD *)(*(_QWORD *)&qword_140C4EC20 + 24i64) & 1i64) == *(_QWORD *)(*(_QWORD *)&qword_140C4EC20 + 24i64) )
{
v48 = v39;
v85[4] = (__int64)&v48;
v85[5] = 1i64;
tlgCreate1Sz_char((__int64)v86, v40);
v53 = v45;
v87 = &v53;
v55 = v66;
v88 = 4i64;
v89 = &v55;
v56 = v63;
v91 = &v56;
v57 = v65;
v93 = &v57;
v58 = v64;
v95 = &v58;
v97 = &v54;
v90 = 8i64;
v92 = 8i64;
v94 = 8i64;
v96 = 8i64;
v54 = v6;
v98 = 4i64;
tlgWriteEx_EtwWriteEx(v46, (unsigned __int8 *)&byte_140024EBF, 0i64, 1u, 0, 0, 0xAu, (__int64)v85);
}
}
return v8 == 4;
}Referenced by:
MiForceAgeWorkingSet
MiTrimOrAgeWorkingSet