MmAdjustWorkingSetSizeEx
VOID __fastcall MmAdjustWorkingSetSizeEx(
UINT64 WorkingSetMinimumInBytes,
UINT64 WorkingSetMaximumInBytes,
_WORKING_SET_TYPE WorkingSetType,
UINT8 IncreaseOkay,
UINT64 Flags,
UINT8 *IncreaseOccurred){
_EPROCESS *Process;
_ETHREAD *CurrentThread;
_MMSUPPORT_INSTANCE *p_Instance;
_MMSUPPORT_SHARED *SharedVm;
UINT64 v13;
UINT64 v14;
unsigned __int64 MinimumWorkingSetSize;
UINT64 v16;
UINT64 VmWorkingSetList;
UINT64 v18;
int v19;
_MMSUPPORT_FLAGS v20;
UINT64 v21;
__int32 v22;
_MMSUPPORT_INSTANCE *v23;
ULONG_PTR *v24;
struct _KPRCB *CurrentPrcb;
__int64 CachedResidentAvailable;
bool v27;
signed __int32 v28;
ULONG_PTR *v29;
struct _KPRCB *v30;
__int64 v31;
signed __int32 v32;
UINT64 VerifyFlags;
UINT64 WorkingSetMinimumInOut;
ULONG_PTR *Partition;
UINT64 WorkingSetMaximumInOut;
UINT64 v37;
_KLOCK_QUEUE_HANDLE v38;
_KLOCK_QUEUE_HANDLE LockQueue;
UINT8 WsIrql;
unsigned __int16 IncreaseOccurreda;
*(_QWORD *)&LockQueue.OldIrql = 0i64;
Process = 0i64;
memset(&v38, 0, sizeof(v38));
*IncreaseOccurred = 0;
LockQueue.LockQueue = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( WorkingSetType == WorkingSetTypeUser )
{
Process = CurrentThread->Tcb.ApcState.Process;
p_Instance = &Process->Vm.Instance;
goto LABEL_3;
}
if( WorkingSetType == WorkingSetTypeSystemTypes )
{
MiGetCurrentMultiplexedVm();
p_Instance = v23;
if( v23 )
{
LABEL_3:
if( WorkingSetMinimumInBytes == -1i64 && WorkingSetMaximumInBytes == -1i64 )
{
MiEmptyWorkingSetInitiate((INT64)p_Instance, 0, 0i64, -1i64);
return;
}
Partition = *(ULONG_PTR **)(*(&stru_140C4DB30 + 267) + 8i64 * p_Instance->PartitionId);
SharedVm = MiGetSharedVm(p_Instance);
WsIrql = ExAcquireSpinLockExclusive((INT64 *)&SharedVm->WorkingSetLock);
SharedVm->GoodCitizenWaiting = 0;
LockQueue.LockQueue.Next = 0i64;
LockQueue.LockQueue.Lock = &MiGetSharedVm(p_Instance)->WorkingSetCoreLock;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, LockQueue.LockQueue.Lock);
if( WorkingSetType == WorkingSetTypeUser && (Process->Flags & 0x20) != 0 )
goto LABEL_29;
v13 = WorkingSetMinimumInBytes ? WorkingSetMinimumInBytes >> 12 : p_Instance->MinimumWorkingSetSize;
WorkingSetMinimumInOut = v13;
v14 = WorkingSetMaximumInBytes ? WorkingSetMaximumInBytes >> 12 : p_Instance->MaximumWorkingSetSize;
LODWORD(VerifyFlags) = 0;
WorkingSetMaximumInOut = v14;
if( (MiCheckWsLimits(
p_Instance,
&WorkingSetMinimumInOut,
&WorkingSetMaximumInOut,
(unsigned int)Flags,
VerifyFlags) & 0xC0000000) == -1073741824 )
goto LABEL_29;
MinimumWorkingSetSize = p_Instance->MinimumWorkingSetSize;
v16 = WorkingSetMinimumInOut;
VmWorkingSetList = (UINT64)p_Instance->VmWorkingSetList;
v37 = VmWorkingSetList;
if( WorkingSetMinimumInOut > MinimumWorkingSetSize )
{
v18 = WorkingSetMinimumInOut - MinimumWorkingSetSize;
*IncreaseOccurred = 1;
if( !IncreaseOkay
|| WorkingSetType == WorkingSetTypeUser && PsChargeProcessQuota(Process, VmWorkingSetList) < 0 )
{
goto LABEL_29;
}
if( MiChargeResident(Partition, v18, 0x200ui64) == MiChargeFailed )
{
if( WorkingSetType == WorkingSetTypeUser )
PsReturnProcessQuota(Process, v21);
goto LABEL_29;
}
VmWorkingSetList = v37;
}
else
{
v18 = MinimumWorkingSetSize - WorkingSetMinimumInOut;
if( WorkingSetMinimumInOut < *(_QWORD *)(VmWorkingSetList + 32) )
goto LABEL_29;
}
if( WorkingSetMaximumInOut < p_Instance->WorkingSetLeafSize )
{
if( *(_QWORD *)(VmWorkingSetList + 32) + 6i64 >= WorkingSetMaximumInOut )
{
if( *IncreaseOccurred == 1 )
{
if( WorkingSetType == WorkingSetTypeUser )
PsReturnProcessQuota(Process, VmWorkingSetList);
v24 = Partition;
if( Partition == (ULONG_PTR *)&Irp )
{
CurrentPrcb = KeGetCurrentPrcb();
CachedResidentAvailable = (int)CurrentPrcb->CachedResidentAvailable;
if( (_DWORD)CachedResidentAvailable != -1 )
{
if( v18 + CachedResidentAvailable <= 0x100 )
{
do
{
if( v18 >= 0x80000 )
break;
v28 = _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
v18 + CachedResidentAvailable,
CachedResidentAvailable);
v27 = (_DWORD)CachedResidentAvailable == v28;
LODWORD(CachedResidentAvailable) = v28;
if( v27 )
goto LABEL_29;
}
while( v28 != -1 && v18 + v28 <= 0x100 );
}
if( (int)CachedResidentAvailable > 192
&& (_DWORD)CachedResidentAvailable != -1
&& (_DWORD)CachedResidentAvailable == _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
192,
CachedResidentAvailable) )
{
v18 += (int)CachedResidentAvailable - 192;
}
v24 = Partition;
}
}
if( v18 )
_InterlockedExchangeAdd64((volatile signed __int64 *)v24 + 896, v18);
}
goto LABEL_29;
}
p_Instance->Flags._bf_0 |= 0x10u;
}
if( !*IncreaseOccurred && v18 )
{
if( WorkingSetType == WorkingSetTypeUser )
PsReturnProcessQuota(Process, VmWorkingSetList);
v29 = Partition;
if( Partition == (ULONG_PTR *)&Irp )
{
v30 = KeGetCurrentPrcb();
v31 = (int)v30->CachedResidentAvailable;
if( (_DWORD)v31 != -1 )
{
if( v18 + v31 <= 0x100 )
{
do
{
if( v18 >= 0x80000 )
break;
v32 = _InterlockedCompareExchange(
(volatile signed __int32 *)&v30->CachedResidentAvailable,
v18 + v31,
v31);
v27 = (_DWORD)v31 == v32;
LODWORD(v31) = v32;
if( v27 )
goto LABEL_88;
}
while( v32 != -1 && v18 + v32 <= 0x100 );
}
if( (int)v31 > 192
&& (_DWORD)v31 != -1
&& (_DWORD)v31 == _InterlockedCompareExchange(
(volatile signed __int32 *)&v30->CachedResidentAvailable,
192,
v31) )
{
v18 += (int)v31 - 192;
}
v29 = Partition;
}
v16 = WorkingSetMinimumInOut;
}
if( v18 )
{
_InterlockedExchangeAdd64((volatile signed __int64 *)v29 + 896, v18);
LABEL_88:
v16 = WorkingSetMinimumInOut;
}
}
p_Instance->MaximumWorkingSetSize = WorkingSetMaximumInOut;
p_Instance->MinimumWorkingSetSize = v16;
if( !(_DWORD)Flags )
{
LABEL_29:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
MiUnlockWorkingSetExclusive(p_Instance, WsIrql);
return;
}
v19 = 0;
v38.LockQueue.Next = 0i64;
v38.LockQueue.Lock = (unsigned __int64 *volatile)((char *)&stru_140C4DB30 + 4176);
KxAcquireQueuedSpinLock(&v38.LockQueue, (UINT64 *)&stru_140C4DB30 + 522);
v20 = p_Instance->Flags;
IncreaseOccurreda = v20.u1;
if( (Flags & 4) != 0 )
{
v20.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 |= 0x80u;
}
else
{
if( (Flags & 8) == 0 )
goto LABEL_23;
v20.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 &= ~0x80u;
}
v19 = 1;
LOBYTE(IncreaseOccurreda) = v20.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0;
LABEL_23:
if( (Flags & 1) != 0 )
{
LOBYTE(IncreaseOccurreda) = v20.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 | 0x40;
}
else
{
if( (Flags & 2) != 0 )
{
v19 = 1;
LOBYTE(IncreaseOccurreda) = v20.$9F51E323906620A7CE080F79FB124AD0::$3F85127412E45D453B47E0230FB8DC78::_bf_0 & 0xBF;
}
if( !v19 )
goto LABEL_28;
}
p_Instance->Flags.u1 = IncreaseOccurreda;
LABEL_28:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&v38);
goto LABEL_29;
}
}
else
{
v22 = WorkingSetType - 3;
if( WorkingSetType == WorkingSetTypePagedPool )
{
v22 = 2;
LABEL_43:
p_Instance = MiGetAnyMultiplexedVm((_MI_WORKING_SET_TYPE)v22, CurrentThread);
goto LABEL_3;
}
if( WorkingSetType == WorkingSetTypeSystemViews )
goto LABEL_43;
}
}Referenced by:
MmAdjustWorkingSetSize
NtSetSystemInformation
PspSetQuotaLimits
SmKmVirtualLockContextIncreaseWsMin
SmKmVirtualLockCtxMemoryUnlocked