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