PsQueryProcessEnergyValues
VOID __fastcall PsQueryProcessEnergyValues(_EPROCESS *Process, _PROCESS_ENERGY_VALUES *EnergyValues){
__int64 v4;
unsigned __int64 v5;
unsigned int TimelineBitmapTime;
_PROCESS_ENERGY_VALUES *v7;
__int64 v8;
unsigned int v9;
__int64 v10;
$A40FAFA829411A05444CCCF5AD3E992E *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;
INT64 *v24;
_QWORD *v25;
_QWORD *i;
__int64 v27;
__int64 v28;
unsigned int v29;
unsigned int v30;
__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((INT64)EnergyValues, 0i64);
if( !PoEnergyEstimationEnabled() || Process == PsIdleProcess )
return;
v4 = *((_QWORD *)Process + 285);
EnergyValues->DiskEnergy = *(_QWORD *)(v4 + 64);
EnergyValues->NetworkTailEnergy = *(_QWORD *)(v4 + 72);
EnergyValues->MBBTailEnergy = *(_QWORD *)(v4 + 80);
EnergyValues->NetworkTxRxBytes = *(_QWORD *)(v4 + 88);
EnergyValues->MBBTxRxBytes = *(_QWORD *)(v4 + 96);
v5 = (KUSER_SHARED_DATA.TickCountQuad * KUSER_SHARED_DATA.TickCountMultiplier) >> 24;
TimelineBitmapTime = KeQueryTimelineBitmapTime();
v7 = EnergyValues + 1;
v8 = v4 - (_QWORD)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;
*((_DWORD *)&v11->Durations[0].1 + 1) = 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;
*((_DWORD *)&v11->Durations[0].1 + 1) = v38 & 0x7FFFFFFF;
}
}
if( v11 == &EnergyValues->104 )
{
v16 = 304i64;
}
else
{
if( v11 != ($A40FAFA829411A05444CCCF5AD3E992E *)&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 = ($A40FAFA829411A05444CCCF5AD3E992E *)((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;
*((_DWORD *)&v18->1 + 1) = 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;
*((_DWORD *)&v18->1 + 1) = 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 *)(v4 + 128);
EnergyValues->CompositionDirtyGenerated = *(_DWORD *)(v4 + 132);
EnergyValues->CompositionDirtyPropagated = *(_DWORD *)(v4 + 136);
LODWORD(EnergyValues[1].AttributedCycles[0][1]) = *(_DWORD *)(v4 + 424);
HIDWORD(EnergyValues[1].AttributedCycles[0][1]) = *(_DWORD *)(v4 + 428);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)CurrentThread + 242);
v24 = (INT64 *)((char *)Process + 2144);
ExAcquirePushLockSharedEx((UINT64)Process + 2144, 0i64);
v25 = (_QWORD *)((char *)Process + 1504);
*(_OWORD *)&EnergyValues->Cycles[0][0] = *(_OWORD *)v4;
*(_OWORD *)&EnergyValues->Cycles[1][0] = *(_OWORD *)(v4 + 16);
*(_OWORD *)&EnergyValues->Cycles[2][0] = *(_OWORD *)(v4 + 32);
*(_OWORD *)&EnergyValues->Cycles[3][0] = *(_OWORD *)(v4 + 48);
*(_OWORD *)&EnergyValues->AttributedCycles[0][0] = *(_OWORD *)(v4 + 144);
*(_OWORD *)&EnergyValues->AttributedCycles[1][0] = *(_OWORD *)(v4 + 160);
*(_OWORD *)&EnergyValues->AttributedCycles[2][0] = *(_OWORD *)(v4 + 176);
*(_OWORD *)&EnergyValues->AttributedCycles[3][0] = *(_OWORD *)(v4 + 192);
*(_OWORD *)&EnergyValues->WorkOnBehalfCycles[0][0] = *(_OWORD *)(v4 + 208);
*(_OWORD *)&EnergyValues->WorkOnBehalfCycles[1][0] = *(_OWORD *)(v4 + 224);
*(_OWORD *)&EnergyValues->WorkOnBehalfCycles[2][0] = *(_OWORD *)(v4 + 240);
*(_OWORD *)&EnergyValues->WorkOnBehalfCycles[3][0] = *(_OWORD *)(v4 + 256);
for( i = (_QWORD *)*v25; i != v25; i = (_QWORD *)*i )
{
v27 = i[34];
v28 = *(_QWORD *)(v27 + 192);
v29 = EnergyValues[1].Cycles[0][0];
if( (unsigned int)v28 > v29 )
{
LODWORD(EnergyValues[1].Cycles[0][0]) = v28;
if( (unsigned int)v28 - v29 >= 0x20 )
v35 = 0;
else
v35 = HIDWORD(EnergyValues[1].Cycles[0][0]) << (v28 - v29);
HIDWORD(EnergyValues[1].Cycles[0][0]) = v35 | HIDWORD(v28);
}
else
{
v30 = v29 - v28;
if( v30 < 0x20 )
HIDWORD(EnergyValues[1].Cycles[0][0]) |= HIDWORD(v28) << v30;
}
v31 = v27 - (_QWORD)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(v24, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(v24);
KeAbPostRelease(v24);
KeLeaveCriticalRegionThread((__int64)CurrentThread);
}Referenced by:
ExpGetProcessInformation
NtQueryInformationProcess
PopEtEnergyContextProcessStateUpdate
PopEtProcessEnumSnapshotCallback
PspFoldProcessAccountingIntoJob
PspQueryProcessAccountingInformationCallback