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