PspQueryJobHierarchyAccountingInformation

VOID __stdcall PspQueryJobHierarchyAccountingInformation(
        _EJOB *Job,
        _JOBOBJECT_EXTENDED_ACCOUNTING_INFORMATION *Information){
  _ETHREAD *CurrentThread; 
  int v5; 
  _EJOB **v6; 
  INT64 v7; 
  INT64 v8; 
  __int64 v9; 
  INT64 v10; 
  _OWORD *EnergyValues; 
  __int64 v12; 
  INT64 *v13; 
  __int128 v14; 
  __int128 v15; 
  __int128 v16; 
  __int128 v17; 
  __int128 v18; 
  __int128 v19; 
  __int128 v20; 
  _EJOB *v21; 
  _EJOB *RootJob[2]; 
  INT64 JobPostCallback[86]; 

  RootJob[0] = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  memset(JobPostCallback, 0i64, sizeof(JobPostCallback));
  PspLockRootJobShared(Job, CurrentThread, RootJob);
  v5 = 0;
  v6 = RootJob;
  while( Job != *v6 )
  {
    ++v5;
    ++v6;
    if( v5 )
    {
      ExAcquireResourceSharedLite((UINT64)Job + 56, 1);
      break;
    }
  }
  LODWORD(v21) = 1;
  PspEnumJobsAndProcessesInJobHierarchy(
    Job,
    0i64,
    0i64,
    PspQueryProcessAccountingInformationCallback,
    JobPostCallback,
    v21,
    RootJob[0],
    (INT64 *)RootJob[1],
    (_EPROCESS *)JobPostCallback[0],
    (VOID *)JobPostCallback[1],
    (VOID *)JobPostCallback[2],
    JobPostCallback[3]);
  v7 = JobPostCallback[14];
  Information->BasicInfo.TotalUserTime.QuadPart = JobPostCallback[14] + *((_QWORD *)Job + 20);
  Information->BasicInfo.ThisPeriodTotalUserTime.QuadPart = *((_QWORD *)Job + 23) + v7;
  v8 = JobPostCallback[13];
  Information->BasicInfo.TotalKernelTime.QuadPart = JobPostCallback[13] + *((_QWORD *)Job + 21);
  Information->BasicInfo.ThisPeriodTotalKernelTime.QuadPart = *((_QWORD *)Job + 24) + v8;
  Information->BasicInfo.TotalPageFaultCount = LODWORD(JobPostCallback[31]) + *((_DWORD *)Job + 52);
  Information->BasicInfo.TotalProcesses = *((_DWORD *)Job + 53);
  Information->BasicInfo.ActiveProcesses = *((_DWORD *)Job + 54);
  Information->BasicInfo.TotalTerminatedProcesses = *((_DWORD *)Job + 55);
  Information->IoInfo.ReadOperationCount = JobPostCallback[18] + *((_QWORD *)Job + 61);
  Information->IoInfo.WriteOperationCount = JobPostCallback[19] + *((_QWORD *)Job + 62);
  Information->IoInfo.OtherOperationCount = JobPostCallback[20] + *((_QWORD *)Job + 63);
  Information->IoInfo.ReadTransferCount = JobPostCallback[21] + *((_QWORD *)Job + 64);
  Information->IoInfo.WriteTransferCount = JobPostCallback[22] + *((_QWORD *)Job + 65);
  Information->IoInfo.OtherTransferCount = JobPostCallback[23] + *((_QWORD *)Job + 66);
  Information->DiskIoInfo.BytesRead = JobPostCallback[26] + *((_QWORD *)Job + 67);
  Information->DiskIoInfo.BytesWritten = JobPostCallback[27] + *((_QWORD *)Job + 68);
  Information->DiskIoInfo.ReadOperationCount = JobPostCallback[28] + *((_QWORD *)Job + 69);
  Information->DiskIoInfo.WriteOperationCount = JobPostCallback[29] + *((_QWORD *)Job + 70);
  Information->DiskIoInfo.FlushOperationCount = JobPostCallback[30] + *((_QWORD *)Job + 71);
  Information->ContextSwitches = JobPostCallback[17] + *((_QWORD *)Job + 25);
  Information->TotalCycleTime.QuadPart = JobPostCallback[16] + *((_QWORD *)Job + 22);
  Information->ReadyTime = JobPostCallback[15] + *((_QWORD *)Job + 128);
  Information[1].DiskIoInfo.FlushOperationCount = JobPostCallback[24] + *((_QWORD *)Job + 198);
  Information[1].ContextSwitches = JobPostCallback[25] + *((_QWORD *)Job + 199);
  v9 = *((_QWORD *)Job + 126);
  if( v9 )
    Information->ReadyTime += KeQuerySchedulingGroupReadyTime((_KSCHEDULING_GROUP *)(v9 + 128));
  v10 = *((_QWORD *)Job + 166);
  EnergyValues = Information->EnergyValues;
  if( v10 )
  {
    PsAddProcessEnergyValues((INT64)&JobPostCallback[32], v10);
    v12 = 2i64;
    v13 = &JobPostCallback[32];
    do
    {
      v14 = *((_OWORD *)v13 + 1);
      *EnergyValues = *(_OWORD *)v13;
      v15 = *((_OWORD *)v13 + 2);
      EnergyValues[1] = v14;
      v16 = *((_OWORD *)v13 + 3);
      EnergyValues[2] = v15;
      v17 = *((_OWORD *)v13 + 4);
      EnergyValues[3] = v16;
      v18 = *((_OWORD *)v13 + 5);
      EnergyValues[4] = v17;
      v19 = *((_OWORD *)v13 + 6);
      EnergyValues[5] = v18;
      v20 = *((_OWORD *)v13 + 7);
      v13 += 16;
      EnergyValues[6] = v19;
      EnergyValues += 8;
      *(EnergyValues - 1) = v20;
      --v12;
    }
    while( v12 );
    *EnergyValues = *(_OWORD *)v13;
  }
  else
  {
    memset(EnergyValues, 0i64, 0x110u);
  }
  PspUnlockJobConditionally(Job, RootJob);
  PspUnlockJob(RootJob[0], CurrentThread);
}

Referenced by:

NtQueryInformationJobObject