PsQueryProcessEnergyValues

VOID __stdcall PsQueryProcessEnergyValues(_EPROCESS *Process, _PROCESS_ENERGY_VALUES *EnergyValues){
  struct _PO_PROCESS_ENERGY_CONTEXT *EnergyContext; 
  unsigned __int64 v5; 
  NTSTATUS TimelineBitmapTime; 
  _PROCESS_ENERGY_VALUES *v7; 
  signed __int64 v8; 
  unsigned int v9; 
  __int64 v10; 
  $23B4C273857820E54D514962632FC7C8 *v11; 
  __int64 v12; 
  _ENERGY_STATE_DURATION v13; 
  unsigned int v14; 
  unsigned __int64 Value_high; 
  __int64 v16; 
  __int64 v17; 
  _ENERGY_STATE_DURATION *v18; 
  unsigned __int64 v19; 
  unsigned int v20; 
  unsigned __int64 v21; 
  __int64 v22; 
  _ETHREAD *CurrentThread; 
  _EX_PUSH_LOCK *p_ThreadListLock; 
  _LIST_ENTRY *p_ThreadListHead; 
  _LIST_ENTRY *i; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *v28; 
  unsigned int v29; 
  unsigned int v30; 
  signed __int64 v31; 
  _PROCESS_ENERGY_VALUES *v32; 
  __int64 v33; 
  __int64 v34; 
  int v35; 
  unsigned int v36; 
  unsigned int v37; 
  int v38; 
  unsigned int v39; 
  unsigned int v40; 
  int v41; 

  memset(EnergyValues, 0i64, 0x1B0u);
  if( !PoEnergyEstimationEnabled() || Process == *(_EPROCESS **)&PsIdleProcess )
    return;
  EnergyContext = Process->EnergyContext;
  EnergyValues->DiskEnergy = *((_QWORD *)EnergyContext + 8);
  EnergyValues->NetworkTailEnergy = *((_QWORD *)EnergyContext + 9);
  EnergyValues->MBBTailEnergy = *((_QWORD *)EnergyContext + 10);
  EnergyValues->NetworkTxRxBytes = *((_QWORD *)EnergyContext + 11);
  EnergyValues->MBBTxRxBytes = *((_QWORD *)EnergyContext + 12);
  v5 = (KUSER_SHARED_DATA.TickCountQuad * KUSER_SHARED_DATA.TickCountMultiplier) >> 24;
  TimelineBitmapTime = KeQueryTimelineBitmapTime();
  v7 = EnergyValues + 1;
  v8 = EnergyContext - (struct _PO_PROCESS_ENERGY_CONTEXT *)EnergyValues;
  v9 = TimelineBitmapTime;
  v10 = 14i64;
  do
  {
    v7->Cycles[0][0] = *(unsigned __int64 *)((char *)v7->Cycles[0] + v8);
    v7 = (_PROCESS_ENERGY_VALUES *)((char *)v7 + 8);
    --v10;
  }
  while( v10 );
  v11 = &EnergyValues->104;
  v12 = 3i64;
  do
  {
    v13.Value = *(unsigned __int64 *)((char *)v11->Durations + v8);
    v14 = 0;
    v11->Durations[0] = v13;
    Value_high = HIDWORD(v13.Value);
    if( (Value_high & 0x80000000) != 0i64 )
    {
      v36 = Value_high & 0x7FFFFFFF;
      v11->Durations[0]._bf_4 = v36;
      v37 = *(unsigned int *)((char *)&v11->Durations[0].LastChangeTime + v8);
      if( (unsigned int)v5 > v37 )
      {
        v11->Durations[0].LastChangeTime = v5;
        v14 = v5 - v37;
        if( (_DWORD)v5 - v37 == -1 || ~v14 < v36 )
          v38 = -1;
        else
          v38 = v14 + v36;
        v11->Durations[0]._bf_4 = v38 & 0x7FFFFFFF;
      }
    }
    if( v11 == &EnergyValues->104 )
    {
      v16 = 304i64;
    }
    else
    {
      if( v11 != ($23B4C273857820E54D514962632FC7C8 *)&EnergyValues->DesktopVisibleDuration )
        goto LABEL_14;
      v16 = 312i64;
    }
    if( (_PROCESS_ENERGY_VALUES *)((char *)EnergyValues + v16) && v14 )
      RtlTimelineBitmapUpdateRange((INT64 *)((char *)EnergyValues + v16), v9 - (v14 >> 12), v9);
LABEL_14:
    v11 = ($23B4C273857820E54D514962632FC7C8 *)((char *)v11 + 8);
    --v12;
  }
  while( v12 );
  v17 = 5i64;
  v18 = &EnergyValues[1].Durations[1];
  while( 2 )
  {
    v19 = *(unsigned __int64 *)((char *)&v18->Value + v8);
    v20 = 0;
    v18->Value = v19;
    v21 = HIDWORD(v19);
    if( (v21 & 0x80000000) != 0i64 )
    {
      v39 = v21 & 0x7FFFFFFF;
      v18->_bf_4 = v39;
      v40 = *(unsigned int *)((char *)&v18->LastChangeTime + v8);
      if( (unsigned int)v5 > v40 )
      {
        v18->LastChangeTime = v5;
        v20 = v5 - v40;
        if( (_DWORD)v5 - v40 == -1 || ~v20 < v39 )
          v41 = -1;
        else
          v41 = v20 + v39;
        v18->_bf_4 = v41 & 0x7FFFFFFF;
      }
    }
    if( v18 == &EnergyValues[1].PSMForegroundDuration )
    {
      v22 = 352i64;
      goto LABEL_22;
    }
    if( v18 == (_ENERGY_STATE_DURATION *)&EnergyValues[1].CompositionRendered )
    {
      v22 = 360i64;
LABEL_22:
      if( (_PROCESS_ENERGY_VALUES *)((char *)EnergyValues + v22) && v20 )
        RtlTimelineBitmapUpdateRange((INT64 *)((char *)EnergyValues + v22), v9 - (v20 >> 12), v9);
      goto LABEL_25;
    }
    if( v18 == (_ENERGY_STATE_DURATION *)&EnergyValues[1].CompositionDirtyPropagated )
    {
      v22 = 368i64;
      goto LABEL_22;
    }
LABEL_25:
    ++v18;
    if( --v17 )
      continue;
    break;
  }
  EnergyValues->CompositionRendered = *((_DWORD *)EnergyContext + 32);
  EnergyValues->CompositionDirtyGenerated = *((_DWORD *)EnergyContext + 33);
  EnergyValues->CompositionDirtyPropagated = *((_DWORD *)EnergyContext + 34);
  LODWORD(EnergyValues[1].AttributedCycles[0][1]) = *((_DWORD *)EnergyContext + 106);
  HIDWORD(EnergyValues[1].AttributedCycles[0][1]) = *((_DWORD *)EnergyContext + 107);
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --CurrentThread->Tcb.KernelApcDisable;
  p_ThreadListLock = &Process->ThreadListLock;
  ExAcquirePushLockSharedEx(&Process->ThreadListLock, 0i64);
  p_ThreadListHead = &Process->ThreadListHead;
  *(_OWORD *)&EnergyValues->Cycles[0][0] = *(_OWORD *)EnergyContext;
  *(_OWORD *)&EnergyValues->Cycles[1][0] = *((_OWORD *)EnergyContext + 1);
  *(_OWORD *)&EnergyValues->Cycles[2][0] = *((_OWORD *)EnergyContext + 2);
  *(_OWORD *)&EnergyValues->Cycles[3][0] = *((_OWORD *)EnergyContext + 3);
  *(_OWORD *)&EnergyValues->AttributedCycles[0][0] = *((_OWORD *)EnergyContext + 9);
  *(_OWORD *)&EnergyValues->AttributedCycles[1][0] = *((_OWORD *)EnergyContext + 10);
  *(_OWORD *)&EnergyValues->AttributedCycles[2][0] = *((_OWORD *)EnergyContext + 11);
  *(_OWORD *)&EnergyValues->AttributedCycles[3][0] = *((_OWORD *)EnergyContext + 12);
  *(_OWORD *)&EnergyValues->WorkOnBehalfCycles[0][0] = *((_OWORD *)EnergyContext + 13);
  *(_OWORD *)&EnergyValues->WorkOnBehalfCycles[1][0] = *((_OWORD *)EnergyContext + 14);
  *(_OWORD *)&EnergyValues->WorkOnBehalfCycles[2][0] = *((_OWORD *)EnergyContext + 15);
  *(_OWORD *)&EnergyValues->WorkOnBehalfCycles[3][0] = *((_OWORD *)EnergyContext + 16);
  for( i = p_ThreadListHead->Flink; i != p_ThreadListHead; i = i->Flink )
  {
    Flink = i[17].Flink;
    v28 = Flink[12].Flink;
    v29 = EnergyValues[1].Cycles[0][0];
    if( (unsigned int)v28 > v29 )
    {
      LODWORD(EnergyValues[1].Cycles[0][0]) = (_DWORD)v28;
      if( (unsigned int)v28 - v29 >= 0x20 )
        v35 = 0;
      else
        v35 = HIDWORD(EnergyValues[1].Cycles[0][0]) << ((_BYTE)v28 - v29);
      HIDWORD(EnergyValues[1].Cycles[0][0]) = v35 | HIDWORD(v28);
    }
    else
    {
      v30 = v29 - (_DWORD)v28;
      if( v30 < 0x20 )
        HIDWORD(EnergyValues[1].Cycles[0][0]) |= HIDWORD(v28) << v30;
    }
    v31 = (char *)Flink - (char *)EnergyValues;
    v32 = EnergyValues;
    v33 = 4i64;
    do
    {
      v34 = 2i64;
      do
      {
        v32->Cycles[0][0] += *(unsigned __int64 *)((char *)v32->Cycles[0] + v31);
        v32->AttributedCycles[0][0] += *(unsigned __int64 *)((char *)v32->Cycles[4] + v31);
        v32->WorkOnBehalfCycles[0][0] += *(_QWORD *)((char *)&v32->CompositionRendered + v31);
        v32 = (_PROCESS_ENERGY_VALUES *)((char *)v32 + 8);
        --v34;
      }
      while( v34 );
      --v33;
    }
    while( v33 );
  }
  if( _InterlockedCompareExchange64(&p_ThreadListLock->_bf_0, 0i64, 17i64) != 17 )
    ExfReleasePushLockShared(p_ThreadListLock);
  KeAbPostRelease(p_ThreadListLock);
  KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
}

Referenced by:

ExpGetProcessInformation
NtQueryInformationProcess
PopEtEnergyContextProcessStateUpdate
PopEtProcessEnumSnapshotCallback
PspFoldProcessAccountingIntoJob
PspQueryProcessAccountingInformationCallback