PpmInstallNewIdleStates
NTSTATUS __stdcall PpmInstallNewIdleStates(_KPRCB *Prcb, UINT64 Param1, UINT64 Param2){
int v3;
NTSTATUS v6;
_PPM_IDLE_STATES *IdleStates;
__int64 v9;
int v10;
_DWORD *v11;
__int64 v12;
bool v13;
int v14;
unsigned int v15;
size_t v16;
VOID **PoolWithTag;
VOID **v18;
char *v19;
char *v20;
unsigned int v21;
unsigned int *v22;
UINT64 v23;
VOID **v24;
char *v25;
int v26;
unsigned int *v27;
unsigned __int8 *v28;
_PPM_IDLE_STATES *v29;
unsigned int TargetState;
_PROC_IDLE_ACCOUNTING *IdleAccounting;
_KPRCB *v32;
__int64 v33;
unsigned __int64 PriorIdleTime;
unsigned int v35;
__int64 v36;
_PPM_VETO_ACCOUNTING **v37;
__int64 v38;
_PPM_VETO_ACCOUNTING *p_VetoAccounting;
unsigned __int8 IdleOverride;
unsigned int v41;
unsigned int v42;
size_t Size;
_PPM_IDLE_STATES *v45;
_PROCESSOR_POWER_STATE *p_PowerState;
_KAFFINITY_EX Affinity;
v3 = Param2;
memset(Affinity.Bitmap, 0i64, sizeof(Affinity.Bitmap));
v6 = 0;
IdleStates = Prcb->PowerState.IdleStates;
p_PowerState = &Prcb->PowerState;
if( IdleStates )
{
if( v3 == 1 )
return v6;
IdleOverride = IdleStates->IdleOverride;
PpmUpdateProcessorIdleAccounting(&Prcb->PowerState);
}
else
{
IdleOverride = 0;
}
v9 = *(unsigned int *)(Param1 + 116);
if( !(_DWORD)v9 )
return -1073741811;
v10 = 0;
if( *(_BYTE *)(Param1 + 19) == 1 )
{
v11 = (_DWORD *)(Param1 + 120);
v12 = (unsigned int)v9;
do
{
v13 = (*v11 & 0x100) == 0;
v14 = v10 + 1;
v11 += 8;
if( !v13 )
v14 = v10;
v10 = v14;
--v12;
}
while( v12 );
}
v15 = (248 * v9 + 819) & 0xFFFFFFFC;
v41 = v15 + 8 * *(_DWORD *)(Param1 + 112);
v42 = v41 + 24 * v10;
v16 = (((v42 + 1000 * v9 + 47) & 0xFFFFFFF8) + 4 * v9 + 15) & 0xFFFFFFF8;
if( *(&stru_140CF2E80 + 972) )
v16 += (**(&stru_140CF2E80 + 972) * (_DWORD)v9) << 6;
Size = v16;
PoolWithTag = ExAllocatePoolWithTag(0x200ui64, v16, 1766674512i64);
v45 = (_PPM_IDLE_STATES *)PoolWithTag;
v18 = PoolWithTag;
if( !PoolWithTag )
return -1073741670;
memset(PoolWithTag, 0i64, Size);
*((_DWORD *)v18 + 9) = v3;
v18[5] = *(VOID **)(Param1 + 72);
*(_BYTE *)v18 = *(_BYTE *)(Param1 + 19);
*((_BYTE *)v18 + 2) = *(_BYTE *)(Param1 + 16);
*((_BYTE *)v18 + 8) = *(_BYTE *)(Param1 + 18);
*((_DWORD *)v18 + 16) = 0;
*((_DWORD *)v18 + 8) = v9;
v18[51] = *(VOID **)(Param1 + 24);
v18[54] = *(VOID **)(Param1 + 40);
v18[55] = *(VOID **)(Param1 + 48);
v18[56] = *(VOID **)(Param1 + 56);
v18[53] = *(VOID **)(Param1 + 80);
v18[52] = *(VOID **)(Param1 + 64);
v18[57] = *(VOID **)(Param1 + 88);
v18[58] = *(VOID **)(Param1 + 32);
v18[59] = *(VOID **)(Param1 + 96);
v18[60] = *(VOID **)(Param1 + 104);
v18[61] = *(VOID **)(Param1 + 8);
*((_DWORD *)v18 + 136) = *(_DWORD *)(Param1 + 112);
*((_DWORD *)v18 + 198) = 1;
v18[69] = (char *)v18 + v15;
v18[101] = v18 + 100;
if( v10 )
{
v19 = (char *)v18 + v41;
*((_DWORD *)v18 + 190) = v10;
v18[96] = v19;
v20 = &v19[24 * v10];
}
else
{
v20 = 0i64;
}
v18[9] = (VOID *)1310740;
memset(v18 + 10, 0i64, 0xA0u);
v21 = 0;
v22 = (unsigned int *)(v20 + 4);
v23 = Param1 + 120;
v24 = v18 + 123;
v25 = (char *)v18 + ((((v42 + 1000 * (_DWORD)v9 + 47) & 0xFFFFFFF8) + 4 * (_DWORD)v9 + 15) & 0xFFFFFFF8);
do
{
*(_OWORD *)v24 = *(_OWORD *)(v23 + 16);
*(v24 - 21) = (VOID *)1310721;
memset(v24 - 20, 0i64, 0xA0u);
*((_BYTE *)v24 + 72) = (*(_DWORD *)v23 >> 3) & 0xF;
*((_BYTE *)v24 + 74) = *(_BYTE *)v23 & 1;
*((_BYTE *)v24 + 75) = (*(_DWORD *)v23 & 4) != 0;
*((_BYTE *)v24 + 76) = (*(_DWORD *)v23 & 2) != 0;
v26 = *(_DWORD *)v23;
if( *(int *)v23 < 0 )
{
*((_DWORD *)v24 + 7) = 1;
*((_BYTE *)v24 + 73) = 1;
v26 = *(_DWORD *)v23;
}
*((_BYTE *)v24 + 77) = (v26 & 0x80) != 0;
*((_BYTE *)v24 + 78) = BYTE1(*(_DWORD *)v23) & 1;
*((_BYTE *)v24 + 79) = (*(_DWORD *)v23 & 0x40000000) != 0;
*((_DWORD *)v24 + 4) = *(_DWORD *)(v23 + 4);
*((_DWORD *)v24 + 6) = *(_DWORD *)(v23 + 12);
*((_DWORD *)v24 + 5) = *(_DWORD *)(v23 + 8);
v24[6] = v24 + 5;
v24[5] = v24 + 5;
if( v21 && PpmIdleDisableStatesAtBoot == 2 )
*((_DWORD *)v24 + 8) = 0x80000000;
v27 = (unsigned int *)*(&stru_140CF2E80 + 972);
if( *(&stru_140CF2E80 + 972) )
{
*((_DWORD *)v24 + 15) = **(&stru_140CF2E80 + 972);
v24[8] = v25;
v25 += 64 * (unsigned __int64)*v27;
}
if( v22 != (unsigned int *)4 && (*(_DWORD *)v23 & 0x100) == 0 )
{
v22 -= 6;
*((_BYTE *)v22 - 3) = 1;
*v22 = v21;
}
++v21;
v24 += 31;
v23 += 32i64;
}
while( v21 < (unsigned int)v9 );
v28 = &v45->InterfaceVersion + v42;
v13 = *(&stru_140CF2E80 + 972) == 0i64;
v45->Tracing = (_PERFINFO_PPM_STATE_SELECTION *)(&v45->InterfaceVersion + ((v42 + 1000 * (_DWORD)v9 + 47) & 0xFFFFFFF8));
*(_DWORD *)v28 = v9;
if( !v13 )
{
v37 = (_PPM_VETO_ACCOUNTING **)(v28 + 200);
v38 = v9;
p_VetoAccounting = &v45->State[0].VetoAccounting;
do
{
*v37 = p_VetoAccounting;
p_VetoAccounting = (_PPM_VETO_ACCOUNTING *)((char *)p_VetoAccounting + 248);
v37 += 125;
--v38;
}
while( v38 );
}
KxAcquireSpinLock((UINT64 *)&stru_140C23628 + 122);
v29 = p_PowerState->IdleStates;
p_PowerState->IdleStates = v45;
KxReleaseSpinLock((UINT64 *)&stru_140C23628 + 122);
if( IdleOverride )
v45->OverrideIndex = v29->OverrideIndex;
if( !v29 || (TargetState = v29->TargetState, TargetState >= (unsigned int)v9) )
TargetState = 0;
v45->TargetState = TargetState;
v45->IdleOverride = IdleOverride;
IdleAccounting = p_PowerState->IdleAccounting;
p_PowerState->IdleAccounting = (_PROC_IDLE_ACCOUNTING *)v28;
if( IdleAccounting )
{
PriorIdleTime = IdleAccounting->PriorIdleTime;
v35 = 0;
for( *((_QWORD *)v28 + 3) = PriorIdleTime; v35 < IdleAccounting->StateCount; *((_QWORD *)v28 + 3) = PriorIdleTime )
{
v36 = v35++;
PriorIdleTime += IdleAccounting->State[v36].TotalTime;
}
v32 = Prcb;
}
else
{
v32 = Prcb;
*((_QWORD *)v28 + 3) = (unsigned int)KeMaximumIncrement
* (unsigned __int64)Prcb->IdleThread->Tcb.SchedulerApc.SpareLong0;
}
PpmResetIdlePolicy(p_PowerState);
if( IdleAccounting )
*((_DWORD *)v28 + 2) = IdleAccounting->ResetCount + 1;
*(_DWORD *)&Affinity.Count = 1310721;
memset(&Affinity.Reserved, 0i64, 0xA4u);
KeAddProcessorAffinityEx(&Affinity.Count, v32->Number);
LOBYTE(v33) = PpmDeepestHardwareIdleState(v45);
((void(__fastcall *)(__int64, _KAFFINITY_EX *))off_140C006A8[0])(v33, &Affinity);
if( v45->Type != 1 && v45->InterfaceVersion == 1 )
PpmIdleDurationExpirationTimeout = (unsigned int)(10000 * PpmIdleDurationExpirationTimeoutMs);
if( v29 )
ExFreePoolWithTag(v29, 0x694D5050u);
return v6;
}Referenced by:
PpmIdleInstallDefaultStates