UINT CCompInfo::GetCPUInfo() { SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIME_INFORMATION SysTimeInfo; SYSTEM_BASIC_INFORMATION SysBaseInfo; double dbIdleTime; double dbSystemTime; LONG status; LARGE_INTEGER liOldIdleTime = {0,0}; LARGE_INTEGER liOldSystemTime = {0,0}; NtQuerySystemInformation = (PROCNTQSI)GetProcAddress( GetModuleHandle("ntdll"), "NtQuerySystemInformation" ); if (!NtQuerySystemInformation) return 0; // get number of processors in the system status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL); if (status != NO_ERROR) return 0; while(1) { // get new system time status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0); if (status!=NO_ERROR) return 0; // get new CPU's idle time status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL); if (status != NO_ERROR) return 0; // if it's a first call - skip it if (liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); // CurrentCpuIdle = IdleTime / SystemTime dbIdleTime = dbIdleTime / dbSystemTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5; return (UINT)dbIdleTime; } // store new CPU's idle and system time liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; // wait one second Sleep(m_Sleep); } }
UINT USystem::getCPUUsage() { SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIME_INFORMATION SysTimeInfo; SYSTEM_BASIC_INFORMATION SysBaseInfo; double dbIdleTime; double dbSystemTime; LONG status; LARGE_INTEGER liOldIdleTime; LARGE_INTEGER liOldSystemTime; UINT x=0; NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation" ); if (!NtQuerySystemInformation) return (0); // get number of processors in the system status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL ); if (status != NO_ERROR) return (0); //printf("\nCPU Usage (press any key to exit): "); while( x != 2 ) { // get new system time status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0 ); if (status!=NO_ERROR) return (0); // get new CPU's idle time status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL ); if (status != NO_ERROR) return (0); // if it's a first call - skip it if (liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); // CurrentCpuIdle = IdleTime / SystemTime dbIdleTime = dbIdleTime / dbSystemTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) /NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5; //printf("\b\b\b\b%3d%",(UINT)dbIdleTime); //printf ("Usage : ",(UINT)dbIdleTime); } // store new CPU's idle and system time liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; x++; //Sleep(1000); } return (UINT)dbIdleTime; }
//********************************************************************* // // SetProcessListText // // Format the process list text. // void SetProcessListText (PPERF_INSTANCE pInst, PPERF_COUNTER pCPU, PPERF_COUNTER pPRIV, PPERF_COUNTER pProcID, double fTime, LPTSTR str) { DWORD *pdwProcID; LARGE_INTEGER *liCPU; LARGE_INTEGER *liPRIV; double fCPU = 0; double fPRIV = 0; INT PcntPRIV = 0; INT PcntUSER = 0; TIME_FIELD TimeFld; TCHAR szTemp[100]; if (pCPU) { liCPU = (LARGE_INTEGER *) CounterData (pInst, pCPU); fCPU = Li2Double (*liCPU); } if (pPRIV) { liPRIV = (LARGE_INTEGER *) CounterData (pInst, pPRIV); fPRIV = Li2Double (*liPRIV); } if (fCPU > 0) { PcntPRIV = (INT)(fPRIV / fCPU * 100 + 0.5); PcntUSER = 100 - PcntPRIV; } if (pProcID) { pdwProcID = (DWORD *) CounterData (pInst, pProcID); wsprintf (szTemp, TEXT("%ls (%#x)"), InstanceName(pInst), *pdwProcID); } else wsprintf (szTemp, TEXT("%ls"), InstanceName(pInst)); FormatTimeFields (fCPU/1.0e7, &TimeFld); wsprintf (str, TEXT("%s\t%3ld:%02ld:%02ld.%03ld\t%3ld%%\t%3ld%%"), szTemp, TimeFld.Hours, TimeFld.Mins, TimeFld.Secs, TimeFld.mSecs, PcntPRIV, PcntUSER); }
//********************************************************************* // // RefreshThreadList // // Find all threads for a given process and update the thread list. // void RefreshThreadList (HWND hThreadList, PPERF_OBJECT pObject, DWORD ParentIndex) { PPERF_INSTANCE pInstance; TCHAR szListText[256]; INT ListIndex; PPERF_COUNTER pCounterCPU; PPERF_COUNTER pCounterPRIV; double fObjectFreq; double fObjectTime; double fTime; INT InstanceIndex = 0; INT err; if (pObject) { if ((pCounterCPU = FindCounter (pObject, PX_THREAD_CPU)) && (pCounterPRIV = FindCounter (pObject, PX_THREAD_PRIV))) { fObjectFreq = Li2Double (pObject->PerfFreq); fObjectTime = Li2Double (pObject->PerfTime); fTime = fObjectTime / fObjectFreq; pInstance = FirstInstance (pObject); while (pInstance && InstanceIndex < pObject->NumInstances) { if (ParentIndex == pInstance->ParentObjectInstance) { SetThreadListText (pInstance, pCounterCPU, pCounterPRIV, fTime, szListText); ListIndex = SendMessage (hThreadList, LB_INSERTSTRING, (WPARAM)-1, (DWORD)szListText); err = SendMessage (hThreadList, LB_SETITEMDATA, ListIndex, InstanceIndex); } pInstance = NextInstance (pInstance); InstanceIndex++; } } } }
//********************************************************************* // // RefreshProcessList // // Find all process and update the process list. // void RefreshProcessList (HWND hProcessList, PPERF_OBJECT pObject) { PPERF_INSTANCE pInstance; TCHAR szListText[256]; INT ListIndex; PPERF_COUNTER pCounterCPU; PPERF_COUNTER pCounterPRIV; PPERF_COUNTER pCounterProcID; double fObjectFreq; double fObjectTime; double fTime; INT InstanceIndex = 0; INT err; if (pObject) { if ((pCounterCPU = FindCounter (pObject, PX_PROCESS_CPU)) && (pCounterPRIV = FindCounter (pObject, PX_PROCESS_PRIV)) && (pCounterProcID = FindCounter (pObject, PX_PROCESS_ID))) { fObjectFreq = Li2Double (pObject->PerfFreq); fObjectTime = Li2Double (pObject->PerfTime); fTime = fObjectTime / fObjectFreq; pInstance = FirstInstance (pObject); while (pInstance && InstanceIndex < pObject->NumInstances) { SetProcessListText (pInstance, pCounterCPU, pCounterPRIV, pCounterProcID, fTime, szListText); ListIndex = SendMessage (hProcessList, LB_ADDSTRING, 0, (DWORD)szListText); err = SendMessage (hProcessList, LB_SETITEMDATA, ListIndex, InstanceIndex); pInstance = NextInstance (pInstance); InstanceIndex++; } } } }
void WINAPI CpuLimitThread(LPVOID) { LARGE_INTEGER liOldIdleTime={0},liOldSystemTime={0}; SYSTEM_PERFORMANCE_INFORMATION spi; SYSTEM_TIME_INFORMATION sti; if ((!NtQuerySystemInformation(SystemPerformanceInformation,&spi,sizeof(spi),NULL)) && (!NtQuerySystemInformation(SystemTimeOfDayInformation,&sti,sizeof(sti),NULL))) { if (liOldIdleTime.QuadPart) { double dbIdleTime=Li2Double(spi.IdleTime)-Li2Double(liOldIdleTime), dbSystemTime=Li2Double(sti.nKeSystemTime)-Li2Double(liOldSystemTime); dbIdleTime=dbIdleTime/dbSystemTime; dbIdleTime=100.0-dbIdleTime*100.0*(double)dwProcessorsCount+0.5; dwIdleTime=(DWORD)dbIdleTime; if ((dwIdleTime >= MAX_CPU_TIME_LIMIT) && (GetUserIdleTime() < MAX_IDLE_TIME)) { if (bCpuSleep) { bCpuSleep=false; dwPeriodBegin=0; } else { DWORD dwPeriodEnd=GetTickCount(); if (dwPeriodEnd-dwPeriodBegin >= MAX_CPU_LOAD_DURATION) bCpuSleep=true; dwPeriodBegin=dwPeriodEnd; } } else { bCpuSleep=false; dwPeriodBegin=0; } } liOldIdleTime.QuadPart=spi.IdleTime.QuadPart; liOldSystemTime.QuadPart=sti.nKeSystemTime.QuadPart; } dwMemUsage=GetMemUsage(); Sleep(1000); return; }
//返回当时cpu的占用率(0-100) int Wutils :: getCPUusage() { int retv=0; OSVERSIONINFO vi; vi.dwOSVersionInfoSize=sizeof(vi); ::GetVersionEx(&vi); if(vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {//NT/win2000 SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIME_INFORMATION SysTimeInfo; SYSTEM_BASIC_INFORMATION SysBaseInfo; double dbIdleTime; double dbSystemTime; static LARGE_INTEGER liOldIdleTime = {0,0}; static LARGE_INTEGER liOldSystemTime = {0,0}; NtQuerySystemInformation = (PROCNTQSI)GetProcAddress( GetModuleHandle("ntdll"), "NtQuerySystemInformation" ); if (!NtQuerySystemInformation) return 0; // get number of processors in the system if(NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL)!=NO_ERROR) return 0; // get new system time if(NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0)!=NO_ERROR) return 0; // get new CPU's idle time if(NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL)!=NO_ERROR) return 0; // if it's a first call - skip it if (liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); // CurrentCpuIdle = IdleTime / SystemTime dbIdleTime = dbIdleTime / dbSystemTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5; retv=(int)dbIdleTime; } // store new CPU's idle and system time liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; } else {//win9x HKEY hkey; DWORD dwDataSize; DWORD dwType; DWORD dwCpuUsage; // geting current counter's value if ( RegOpenKeyEx( HKEY_DYN_DATA, "PerfStats\\StatData", 0,KEY_READ, &hkey ) != ERROR_SUCCESS) return 0; dwDataSize=sizeof(DWORD); RegQueryValueEx( hkey,"KERNEL\\CPUUsage",NULL,&dwType,(LPBYTE)&dwCpuUsage,&dwDataSize ); retv=(int)(dwCpuUsage>100?100:dwCpuUsage); RegCloseKey(hkey); } return retv; }
void PerfDataRefresh(void) { try { ULONG ulSize = 0; LONG status = 0; LPBYTE pBuffer = 0; ULONG BufferSize = 0; PSYSTEM_PROCESS_INFORMATION pSPI = 0; PPERFDATA pPDOld = 0; ULONG Idx = 0; ULONG Idx2 = 0; HANDLE hProcess = 0; HANDLE hProcessToken = 0; TCHAR szTemp[MAX_PATH + 100] = {0}; DWORD dwSize = 0; SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo = {0}; SYSTEM_TIME_INFORMATION SysTimeInfo = {0}; SYSTEM_CACHE_INFORMATION SysCacheInfo = {0}; LPBYTE SysHandleInfoData = 0; PSYSTEM_PROCESSORTIME_INFO SysProcessorTimeInfo = 0; double CurrentKernelTime = 0; int iControlLoop1 = 0; int iControlLoop2 = 0; int iRequiredMem = (64 * 1024); if (!g_NtQuerySystemInformation) return; /* Get new system time */ status = g_NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0); if (status != NO_ERROR) return; /* Get new CPU's idle time */ status = g_NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL); if (status != NO_ERROR) return; /* Get system cache information */ status = g_NtQuerySystemInformation(SystemCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL); if (status != NO_ERROR) return; /* Get processor time information */ SysProcessorTimeInfo = (PSYSTEM_PROCESSORTIME_INFO)malloc(sizeof(SYSTEM_PROCESSORTIME_INFO) * g_SystemBasicInfo.bKeNumberProcessors); status = g_NtQuerySystemInformation(SystemProcessorTimeInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSORTIME_INFO) * g_SystemBasicInfo.bKeNumberProcessors, &ulSize); if (status != NO_ERROR) return; /* Get handle information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; iControlLoop1 = 0; iRequiredMem = (64 * 1024); do { ++iControlLoop1; if(iControlLoop1 > 10) { return; } BufferSize += iRequiredMem; SysHandleInfoData = (LPBYTE)malloc(BufferSize); if(NULL == SysHandleInfoData) { return; } ulSize = 0; status = g_NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize); if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { if(ulSize > BufferSize) { BufferSize = ulSize; iRequiredMem = (iRequiredMem / 2); } free(SysHandleInfoData); SysHandleInfoData = NULL; } } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/); /* Get process information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; iControlLoop1 = 0; iRequiredMem = (64 * 1024); do { ++iControlLoop1; if(iControlLoop1 > 10) { return; } BufferSize += iRequiredMem; pBuffer = (LPBYTE)malloc(BufferSize); status = g_NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize); if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { free(pBuffer); pBuffer = NULL; if(ulSize > BufferSize) { BufferSize = ulSize; iRequiredMem = (iRequiredMem / 2); } } } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/); /* * Save system performance info */ memcpy(&g_SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION)); /* * Save system cache info */ memcpy(&g_SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION)); /* * Save system processor time info */ if (g_SystemProcessorTimeInfo) { free(g_SystemProcessorTimeInfo); g_SystemProcessorTimeInfo = NULL; } g_SystemProcessorTimeInfo = SysProcessorTimeInfo; SysProcessorTimeInfo = NULL; /* * Save system handle info */ memcpy(&g_SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION)); free(SysHandleInfoData); SysHandleInfoData = NULL; for (CurrentKernelTime=0, Idx=0; Idx<g_SystemBasicInfo.bKeNumberProcessors; Idx++) { CurrentKernelTime += Li2Double(g_SystemProcessorTimeInfo[Idx].KernelTime); CurrentKernelTime += Li2Double(g_SystemProcessorTimeInfo[Idx].DpcTime); CurrentKernelTime += Li2Double(g_SystemProcessorTimeInfo[Idx].InterruptTime); } // If it's a first call - skip idle time calcs if (g_liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue g_dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(g_liOldIdleTime); g_dbKernelTime = CurrentKernelTime - g_OldKernelTime; g_dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(g_liOldSystemTime); // CurrentCpuIdle = IdleTime / SystemTime g_dbIdleTime = g_dbIdleTime / g_dbSystemTime; g_dbKernelTime = g_dbKernelTime / g_dbSystemTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors g_dbIdleTime = 100.0 - g_dbIdleTime * 100.0 / (double)g_SystemBasicInfo.bKeNumberProcessors; g_dbKernelTime = 100.0 - g_dbKernelTime * 100.0 / (double)g_SystemBasicInfo.bKeNumberProcessors; } // Store new CPU's idle and system time g_liOldIdleTime = SysPerfInfo.liIdleTime; g_liOldSystemTime = SysTimeInfo.liKeSystemTime; g_OldKernelTime = CurrentKernelTime; // Determine the process count //We loop through the data we got from g_NtQuerySystemInformation //and count how many structures there are (until RelativeOffset is 0) g_ProcessCountOld = g_ProcessCount; g_ProcessCount = 0; pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; while (pSPI) { g_ProcessCount++; if (pSPI->RelativeOffset == 0) break; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset); } // Now alloc a new PERFDATA array and fill in the data if (g_pPerfDataOld) { free(g_pPerfDataOld); g_pPerfDataOld = NULL; } g_pPerfDataOld = g_pPerfData; g_pPerfData = (PPERFDATA)malloc(sizeof(PERFDATA) * g_ProcessCount); pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; for (Idx=0; Idx<g_ProcessCount; Idx++) { // Get the old perf data for this process (if any) // so that we can establish delta values pPDOld = NULL; for (Idx2=0; Idx2<g_ProcessCountOld; Idx2++) { if (g_pPerfDataOld[Idx2].ProcessId == pSPI->ProcessId) { pPDOld = &g_pPerfDataOld[Idx2]; break; } } // Clear out process perf data structure memset(&g_pPerfData[Idx], 0, sizeof(PERFDATA)); if (pSPI->Name.Buffer) { lstrcpyW(g_pPerfData[Idx].ImageName, pSPI->Name.Buffer); } else { static const WCHAR idleW[] = {'S','y','s','t','e','m',' ','I','d','l','e',' ','P','r','o','c','e','s','s',0}; lstrcpyW(g_pPerfData[Idx].ImageName, idleW ); } g_pPerfData[Idx].ProcessId = pSPI->ProcessId; if (pPDOld) { double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime); double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime); double CpuTime = (CurTime - OldTime) / g_dbSystemTime; CpuTime = CpuTime * 100.0 / (double)g_SystemBasicInfo.bKeNumberProcessors; if(CpuTime > 100) { CpuTime = 100; } g_pPerfData[Idx].CPUUsage = (ULONG)CpuTime; } g_pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart; g_pPerfData[Idx].WorkingSetSizeBytes = pSPI->TotalWorkingSetSizeBytes; g_pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSizeBytes; if (pPDOld) { g_pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->TotalWorkingSetSizeBytes - (LONG)pPDOld->WorkingSetSizeBytes); } else { g_pPerfData[Idx].WorkingSetSizeDelta = 0; } g_pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount; if (pPDOld) { g_pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount); } else { g_pPerfData[Idx].PageFaultCountDelta = 0; } g_pPerfData[Idx].VirtualMemorySizeBytes = pSPI->TotalVirtualSizeBytes; g_pPerfData[Idx].PagedPoolUsagePages = pSPI->TotalPagedPoolUsagePages; g_pPerfData[Idx].NonPagedPoolUsagePages = pSPI->TotalNonPagedPoolUsagePages; g_pPerfData[Idx].BasePriority = pSPI->BasePriority; g_pPerfData[Idx].HandleCount = pSPI->HandleCount; g_pPerfData[Idx].ThreadCount = pSPI->ThreadCount; g_pPerfData[Idx].SessionId = pSPI->SessionId; g_pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart; g_pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset); } free(pBuffer); pBuffer = NULL; if (g_SystemProcessorTimeInfo) { free(g_SystemProcessorTimeInfo); g_SystemProcessorTimeInfo = NULL; } } catch(...) { } }
void PerfDataRefresh() { LONG status; ULONG ulSize; LPBYTE pBuffer; ULONG Idx, Idx2; PSYSTEM_PROCESS_INFORMATION pSPI; PPERFDATA pPDOld; #ifdef EXTRA_INFO HANDLE hProcess; HANDLE hProcessToken; TCHAR szTemp[MAX_PATH]; DWORD dwSize; #endif #ifdef TIMES LARGE_INTEGER liCurrentKernelTime; LARGE_INTEGER liCurrentIdleTime; LARGE_INTEGER liCurrentTime; #endif PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcessorTimeInfo; SYSTEM_TIMEOFDAY_INFORMATION SysTimeInfo; #ifdef TIMES // Get new system time status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0); if (status != NO_ERROR) return; #endif // Get processor information SysProcessorTimeInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)malloc(sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors); status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors, &ulSize); // Get process information PsaCaptureProcessesAndThreads((PSYSTEM_PROCESS_INFORMATION *)&pBuffer); #ifdef TIMES liCurrentKernelTime.QuadPart = 0; liCurrentIdleTime.QuadPart = 0; for (Idx=0; Idx<SystemBasicInfo.NumberOfProcessors; Idx++) { liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].KernelTime.QuadPart; liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].DpcTime.QuadPart; liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].InterruptTime.QuadPart; liCurrentIdleTime.QuadPart += SysProcessorTimeInfo[Idx].IdleTime.QuadPart; } // If it's a first call - skip idle time calcs if (liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue liCurrentTime.QuadPart = liCurrentIdleTime.QuadPart - liOldIdleTime.QuadPart; dbIdleTime = Li2Double(liCurrentTime); liCurrentTime.QuadPart = liCurrentKernelTime.QuadPart - liOldKernelTime.QuadPart; dbKernelTime = Li2Double(liCurrentTime); liCurrentTime.QuadPart = SysTimeInfo.CurrentTime.QuadPart - liOldSystemTime.QuadPart; dbSystemTime = Li2Double(liCurrentTime); // CurrentCpuIdle = IdleTime / SystemTime dbIdleTime = dbIdleTime / dbSystemTime; dbKernelTime = dbKernelTime / dbSystemTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors;// + 0.5; dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors;// + 0.5; } // Store new CPU's idle and system time liOldIdleTime = liCurrentIdleTime; liOldSystemTime = SysTimeInfo.CurrentTime; liOldKernelTime = liCurrentKernelTime; #endif // Determine the process count // We loop through the data we got from PsaCaptureProcessesAndThreads // and count how many structures there are (until PsaWalkNextProcess // returns NULL) ProcessCountOld = ProcessCount; ProcessCount = 0; pSPI = PsaWalkFirstProcess((PSYSTEM_PROCESS_INFORMATION)pBuffer); while (pSPI) { ProcessCount++; pSPI = PsaWalkNextProcess(pSPI); } // Now alloc a new PERFDATA array and fill in the data if (pPerfDataOld) { free(pPerfDataOld); } pPerfDataOld = pPerfData; pPerfData = (PPERFDATA)malloc(sizeof(PERFDATA) * ProcessCount); pSPI = PsaWalkFirstProcess((PSYSTEM_PROCESS_INFORMATION)pBuffer); for (Idx=0; Idx<ProcessCount; Idx++) { // Get the old perf data for this process (if any) // so that we can establish delta values pPDOld = NULL; for (Idx2=0; Idx2<ProcessCountOld; Idx2++) { if (pPerfDataOld[Idx2].ProcessId == (ULONG)(pSPI->UniqueProcessId) && /* check also for the creation time, a new process may have an id of an old one */ pPerfDataOld[Idx2].CreateTime.QuadPart == pSPI->CreateTime.QuadPart) { pPDOld = &pPerfDataOld[Idx2]; break; } } // Clear out process perf data structure memset(&pPerfData[Idx], 0, sizeof(PERFDATA)); if (pSPI->ImageName.Buffer) { wcsncpy(pPerfData[Idx].ImageName, pSPI->ImageName.Buffer, pSPI->ImageName.Length / sizeof(WCHAR)); pPerfData[Idx].ImageName[pSPI->ImageName.Length / sizeof(WCHAR)] = 0; } else { #ifdef _UNICODE wcscpy(pPerfData[Idx].ImageName, lpIdleProcess); #else MultiByteToWideChar(CP_ACP, 0, lpIdleProcess, strlen(lpIdleProcess), pPerfData[Idx].ImageName, MAX_PATH); #endif } pPerfData[Idx].ProcessId = (ULONG)(pSPI->UniqueProcessId); pPerfData[Idx].CreateTime = pSPI->CreateTime; if (pPDOld) { #ifdef TIMES double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime); double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime); double CpuTime = (CurTime - OldTime) / dbSystemTime; CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; // + 0.5; pPerfData[Idx].CPUUsage = (ULONG)CpuTime; #else pPerfData[Idx].CPUUsage = 0; #endif } pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart; pPerfData[Idx].WorkingSetSizeBytes = pSPI->WorkingSetSize; pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSize; if (pPDOld) pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->WorkingSetSize - (LONG)pPDOld->WorkingSetSizeBytes); else pPerfData[Idx].WorkingSetSizeDelta = 0; pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount; if (pPDOld) pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount); else pPerfData[Idx].PageFaultCountDelta = 0; pPerfData[Idx].VirtualMemorySizeBytes = pSPI->VirtualSize; pPerfData[Idx].PagedPoolUsagePages = pSPI->QuotaPagedPoolUsage; pPerfData[Idx].NonPagedPoolUsagePages = pSPI->QuotaNonPagedPoolUsage; pPerfData[Idx].BasePriority = pSPI->BasePriority; pPerfData[Idx].HandleCount = pSPI->HandleCount; pPerfData[Idx].ThreadCount = pSPI->NumberOfThreads; //pPerfData[Idx].SessionId = pSPI->SessionId; #ifdef EXTRA_INFO hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)pSPI->UniqueProcessId); if (hProcess) { if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) { ImpersonateLoggedOnUser(hProcessToken); memset(szTemp, 0, sizeof(TCHAR[MAX_PATH])); dwSize = MAX_PATH; GetUserName(szTemp, &dwSize); #ifndef UNICODE MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH); #endif RevertToSelf(); CloseHandle(hProcessToken); } CloseHandle(hProcess); } #endif #ifdef TIMES pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart; pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart; #endif pSPI = PsaWalkNextProcess(pSPI); } PsaFreeCapture(pBuffer); free(SysProcessorTimeInfo); }
void PerfDataRefresh(void) { ULONG ulSize; LONG status; LPBYTE pBuffer; ULONG BufferSize; PSYSTEM_PROCESS_INFORMATION pSPI; PPERFDATA pPDOld; ULONG Idx, Idx2; HANDLE hProcess; HANDLE hProcessToken; TCHAR szTemp[MAX_PATH]; DWORD dwSize; SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIME_INFORMATION SysTimeInfo; SYSTEM_CACHE_INFORMATION SysCacheInfo; LPBYTE SysHandleInfoData; PSYSTEM_PROCESSORTIME_INFO SysProcessorTimeInfo; double CurrentKernelTime; if (!NtQuerySystemInformation) return; /* Get new system time */ status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0); if (status != NO_ERROR) return; /* Get new CPU's idle time */ status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL); if (status != NO_ERROR) return; /* Get system cache information */ status = NtQuerySystemInformation(SystemCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL); if (status != NO_ERROR) return; /* Get processor time information */ SysProcessorTimeInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors); status = NtQuerySystemInformation(SystemProcessorTimeInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors, &ulSize); if (status != NO_ERROR) { HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo); return; } /* Get handle information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; do { BufferSize += 0x10000; SysHandleInfoData = HeapAlloc(GetProcessHeap(), 0, BufferSize); status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize); if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { HeapFree(GetProcessHeap(), 0, SysHandleInfoData); } } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/); /* Get process information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; do { BufferSize += 0x10000; pBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize); if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { HeapFree(GetProcessHeap(), 0, pBuffer); } } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/); EnterCriticalSection(&PerfDataCriticalSection); /* * Save system performance info */ memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION)); /* * Save system cache info */ memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION)); /* * Save system processor time info */ HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo); SystemProcessorTimeInfo = SysProcessorTimeInfo; /* * Save system handle info */ memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION)); HeapFree(GetProcessHeap(), 0, SysHandleInfoData); for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.bKeNumberProcessors; Idx++) { CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime); CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime); CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime); } /* If it's a first call - skip idle time calcs */ if (liOldIdleTime.QuadPart != 0) { /* CurrentValue = NewValue - OldValue */ dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbKernelTime = CurrentKernelTime - OldKernelTime; dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); /* CurrentCpuIdle = IdleTime / SystemTime */ dbIdleTime = dbIdleTime / dbSystemTime; dbKernelTime = dbKernelTime / dbSystemTime; /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */ dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */ dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */ } /* Store new CPU's idle and system time */ liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; OldKernelTime = CurrentKernelTime; /* Determine the process count * We loop through the data we got from NtQuerySystemInformation * and count how many structures there are (until RelativeOffset is 0) */ ProcessCountOld = ProcessCount; ProcessCount = 0; pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; while (pSPI) { ProcessCount++; if (pSPI->RelativeOffset == 0) break; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset); } /* Now alloc a new PERFDATA array and fill in the data */ HeapFree(GetProcessHeap(), 0, pPerfDataOld); pPerfDataOld = pPerfData; pPerfData = HeapAlloc(GetProcessHeap(), 0, sizeof(PERFDATA) * ProcessCount); pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; for (Idx=0; Idx<ProcessCount; Idx++) { /* Get the old perf data for this process (if any) */ /* so that we can establish delta values */ pPDOld = NULL; for (Idx2=0; Idx2<ProcessCountOld; Idx2++) { if (pPerfDataOld[Idx2].ProcessId == pSPI->ProcessId) { pPDOld = &pPerfDataOld[Idx2]; break; } } /* Clear out process perf data structure */ memset(&pPerfData[Idx], 0, sizeof(PERFDATA)); if (pSPI->Name.Buffer) lstrcpyW(pPerfData[Idx].ImageName, pSPI->Name.Buffer); else { static const WCHAR idleW[] = {'S','y','s','t','e','m',' ','I','d','l','e',' ','P','r','o','c','e','s','s',0}; lstrcpyW(pPerfData[Idx].ImageName, idleW ); } pPerfData[Idx].ProcessId = pSPI->ProcessId; if (pPDOld) { double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime); double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime); double CpuTime = (CurTime - OldTime) / dbSystemTime; CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */ pPerfData[Idx].CPUUsage = (ULONG)CpuTime; } pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart; pPerfData[Idx].WorkingSetSizeBytes = pSPI->TotalWorkingSetSizeBytes; pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSizeBytes; if (pPDOld) pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->TotalWorkingSetSizeBytes - (LONG)pPDOld->WorkingSetSizeBytes); else pPerfData[Idx].WorkingSetSizeDelta = 0; pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount; if (pPDOld) pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount); else pPerfData[Idx].PageFaultCountDelta = 0; pPerfData[Idx].VirtualMemorySizeBytes = pSPI->TotalVirtualSizeBytes; pPerfData[Idx].PagedPoolUsagePages = pSPI->TotalPagedPoolUsagePages; pPerfData[Idx].NonPagedPoolUsagePages = pSPI->TotalNonPagedPoolUsagePages; pPerfData[Idx].BasePriority = pSPI->BasePriority; pPerfData[Idx].HandleCount = pSPI->HandleCount; pPerfData[Idx].ThreadCount = pSPI->ThreadCount; pPerfData[Idx].SessionId = pSPI->SessionId; hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pSPI->ProcessId); if (hProcess) { if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) { ImpersonateLoggedOnUser(hProcessToken); memset(szTemp, 0, sizeof(TCHAR[MAX_PATH])); dwSize = MAX_PATH; GetUserName(szTemp, &dwSize); #ifndef UNICODE MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH); /* int MultiByteToWideChar( UINT CodePage, // code page DWORD dwFlags, // character-type options LPCSTR lpMultiByteStr, // string to map int cbMultiByte, // number of bytes in string LPWSTR lpWideCharStr, // wide-character buffer int cchWideChar // size of buffer ); */ #endif RevertToSelf(); CloseHandle(hProcessToken); } if (pGetGuiResources) { pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS); pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS); } if (pGetProcessIoCounters) pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters); CloseHandle(hProcess); } pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart; pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset); } HeapFree(GetProcessHeap(), 0, pBuffer); LeaveCriticalSection(&PerfDataCriticalSection); }
void PerfDataRefresh(void) { ULONG ulSize; LONG status; LPBYTE pBuffer; ULONG BufferSize; PSYSTEM_PROCESS_INFORMATION pSPI; PPERFDATA pPDOld; ULONG Idx, Idx2; HANDLE hProcess; HANDLE hProcessToken; WCHAR wszTemp[MAX_PATH]; DWORD dwSize; SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIMEOFDAY_INFORMATION SysTimeInfo; SYSTEM_CACHE_INFORMATION SysCacheInfo; LPBYTE SysHandleInfoData; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *SysProcessorTimeInfo; double CurrentKernelTime; /* Get new system time */ status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0); if (status != NO_ERROR) return; /* Get new CPU's idle time */ status = pNtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL); if (status != NO_ERROR) return; /* Get system cache information */ status = pNtQuerySystemInformation(SystemCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL); if (status != NO_ERROR) return; /* Get processor time information */ SysProcessorTimeInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*SysProcessorTimeInfo) * SystemBasicInfo.NumberOfProcessors); status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(*SysProcessorTimeInfo) * SystemBasicInfo.NumberOfProcessors, &ulSize); if (status != NO_ERROR) { HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo); return; } /* Get handle information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; do { BufferSize += 0x10000; SysHandleInfoData = HeapAlloc(GetProcessHeap(), 0, BufferSize); status = pNtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize); if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { HeapFree(GetProcessHeap(), 0, SysHandleInfoData); } } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/); /* Get process information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; do { BufferSize += 0x10000; pBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); status = pNtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize); if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { HeapFree(GetProcessHeap(), 0, pBuffer); } } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/); EnterCriticalSection(&PerfDataCriticalSection); /* * Save system performance info */ memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION)); /* * Save system cache info */ memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION)); /* * Save system processor time info */ HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo); SystemProcessorTimeInfo = SysProcessorTimeInfo; /* * Save system handle info */ memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION)); HeapFree(GetProcessHeap(), 0, SysHandleInfoData); for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.NumberOfProcessors; Idx++) { CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime); CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].Reserved1[0]); CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].Reserved1[1]); } /* If it's a first call - skip idle time calcs */ if (liOldIdleTime.QuadPart != 0) { /* CurrentValue = NewValue - OldValue */ dbIdleTime = Li2Double(SysPerfInfo.IdleTime) - Li2Double(liOldIdleTime); dbKernelTime = CurrentKernelTime - OldKernelTime; dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); /* CurrentCpuIdle = IdleTime / SystemTime */ dbIdleTime = dbIdleTime / dbSystemTime; dbKernelTime = dbKernelTime / dbSystemTime; /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */ dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */ dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */ } /* Store new CPU's idle and system time */ liOldIdleTime = SysPerfInfo.IdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; OldKernelTime = CurrentKernelTime; /* Determine the process count * We loop through the data we got from NtQuerySystemInformation * and count how many structures there are (until RelativeOffset is 0) */ ProcessCountOld = ProcessCount; ProcessCount = 0; pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; while (pSPI) { ProcessCount++; if (pSPI->NextEntryOffset == 0) break; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset); } /* Now alloc a new PERFDATA array and fill in the data */ HeapFree(GetProcessHeap(), 0, pPerfDataOld); pPerfDataOld = pPerfData; pPerfData = HeapAlloc(GetProcessHeap(), 0, sizeof(PERFDATA) * ProcessCount); pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; for (Idx=0; Idx<ProcessCount; Idx++) { /* Get the old perf data for this process (if any) */ /* so that we can establish delta values */ pPDOld = NULL; for (Idx2=0; Idx2<ProcessCountOld; Idx2++) { if (pPerfDataOld[Idx2].ProcessId == (DWORD_PTR)pSPI->UniqueProcessId) { pPDOld = &pPerfDataOld[Idx2]; break; } } /* Clear out process perf data structure */ memset(&pPerfData[Idx], 0, sizeof(PERFDATA)); if (pSPI->ProcessName.Buffer) lstrcpyW(pPerfData[Idx].ImageName, pSPI->ProcessName.Buffer); else { WCHAR idleW[255]; LoadStringW(hInst, IDS_SYSTEM_IDLE_PROCESS, idleW, sizeof(idleW)/sizeof(WCHAR)); lstrcpyW(pPerfData[Idx].ImageName, idleW ); } pPerfData[Idx].ProcessId = (DWORD_PTR)pSPI->UniqueProcessId; if (pPDOld) { double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime); double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime); double CpuTime = (CurTime - OldTime) / dbSystemTime; CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */ pPerfData[Idx].CPUUsage = (ULONG)CpuTime; } pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart; pPerfData[Idx].vmCounters.WorkingSetSize = pSPI->vmCounters.WorkingSetSize; pPerfData[Idx].vmCounters.PeakWorkingSetSize = pSPI->vmCounters.PeakWorkingSetSize; if (pPDOld) pPerfData[Idx].WorkingSetSizeDelta = labs(pSPI->vmCounters.WorkingSetSize - pPDOld->vmCounters.WorkingSetSize); else pPerfData[Idx].WorkingSetSizeDelta = 0; pPerfData[Idx].vmCounters.PageFaultCount = pSPI->vmCounters.PageFaultCount; if (pPDOld) pPerfData[Idx].PageFaultCountDelta = labs(pSPI->vmCounters.PageFaultCount - pPDOld->vmCounters.PageFaultCount); else pPerfData[Idx].PageFaultCountDelta = 0; pPerfData[Idx].vmCounters.VirtualSize = pSPI->vmCounters.VirtualSize; pPerfData[Idx].vmCounters.QuotaPagedPoolUsage = pSPI->vmCounters.QuotaPagedPoolUsage; pPerfData[Idx].vmCounters.QuotaNonPagedPoolUsage = pSPI->vmCounters.QuotaNonPagedPoolUsage; pPerfData[Idx].BasePriority = pSPI->dwBasePriority; pPerfData[Idx].HandleCount = pSPI->HandleCount; pPerfData[Idx].ThreadCount = pSPI->dwThreadCount; pPerfData[Idx].SessionId = pSPI->SessionId; hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD_PTR)pSPI->UniqueProcessId); if (hProcess) { if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) { ImpersonateLoggedOnUser(hProcessToken); memset(wszTemp, 0, sizeof(wszTemp)); dwSize = MAX_PATH; GetUserNameW(wszTemp, &dwSize); RevertToSelf(); CloseHandle(hProcessToken); } if (pGetGuiResources) { pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS); pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS); } if (pGetProcessIoCounters) pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters); if (pIsWow64Process) pIsWow64Process(hProcess, &pPerfData[Idx].Wow64Process); CloseHandle(hProcess); } pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart; pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset); } HeapFree(GetProcessHeap(), 0, pBuffer); LeaveCriticalSection(&PerfDataCriticalSection); }
double getCpuUsage() { SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIME_INFORMATION SysTimeInfo; SYSTEM_BASIC_INFORMATION SysBaseInfo; LONG status; //change char** to lpcwstr char a[] = "ntdll"; WCHAR wsz[64]; swprintf(wsz, L"%S", a); LPCWSTR ntdll = wsz; NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle(ntdll),"NtQuerySystemInformation"); // get number of processors in the system status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL); if (status != NO_ERROR) return -1; if (!NtQuerySystemInformation) return -1; // get number of processors in the system status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL); if (status != NO_ERROR) return -1; // get new system time status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0); if (status!=NO_ERROR) return -1; // get new CPU's idle time status =NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL); if (status != NO_ERROR) return -1; if ( m_iNumberProcessors != SysBaseInfo.bKeNumberProcessors) { //save m_iNumberProcessors = SysBaseInfo.bKeNumberProcessors; //if sppi not null clear if (m_pSPPI != NULL) delete []m_pSPPI; if (m_PUT != NULL) delete []m_PUT; //malloc and point m_pSPPI = new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[m_iNumberProcessors]; m_PUT = new m_PROCESSORS_USE_TIME[m_iNumberProcessors]; } // get ProcessorPer time status =NtQuerySystemInformation(SystemProcessorPerformanceInformation, m_pSPPI, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * m_iNumberProcessors, NULL); if (status != NO_ERROR) return -1; // if it's a first call - skip it if (liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); // CurrentCpuIdle = IdleTime / SystemTime dbIdleTime = dbIdleTime / dbSystemTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors; //calc Processors for (int i = 0; i < m_iNumberProcessors; i++) { m_PUT[i].dbCurrentTime = Li2Double(m_pSPPI[i].KernelTime) + Li2Double(m_pSPPI[i].UserTime) + Li2Double(m_pSPPI[i].DpcTime) + Li2Double(m_pSPPI[i].InterruptTime) - m_PUT[i].dbOldCurrentTime; m_PUT[i].dbIdleTime = Li2Double(m_pSPPI[i].IdleTime) - m_PUT[i].dbOldIdleTime; // CurrentCpuIdle = IdleTime / SystemTime m_PUT[i].dbIdleTime = m_PUT[i].dbIdleTime / m_PUT[i].dbCurrentTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors m_PUT[i].dbIdleTime = 100.0 - m_PUT[i].dbIdleTime * 100.0; } } // store new CPU's idle and system time liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; for (int i = 0; i < m_iNumberProcessors; i++) { m_PUT[i].dbOldCurrentTime = Li2Double(m_pSPPI[i].KernelTime) + Li2Double(m_pSPPI[i].UserTime) + Li2Double(m_pSPPI[i].DpcTime) + Li2Double(m_pSPPI[i].InterruptTime); m_PUT[i].dbOldIdleTime = Li2Double(m_pSPPI[i].IdleTime); } return dbIdleTime; }
/* ** Updates the current CPU utilization value. ** */ bool CMeasureCPU::Update() { if (!CMeasure::PreUpdate()) return false; if (m_Processor == 0) { BOOL status; FILETIME ftIdleTime, ftKernelTime, ftUserTime; // get new CPU's idle/kernel/user time status = GetSystemTimes(&ftIdleTime, &ftKernelTime, &ftUserTime); if (status == 0) return false; CalcUsage(Ft2Double(ftIdleTime), Ft2Double(ftKernelTime) + Ft2Double(ftUserTime)); } else if (c_NtQuerySystemInformation) { LONG status; ULONG bufSize = c_BufferSize; BYTE* buf = (bufSize > 0) ? new BYTE[bufSize] : NULL; int loop = 0; do { ULONG size = 0; status = c_NtQuerySystemInformation(SystemProcessorPerformanceInformation, buf, bufSize, &size); if (status == STATUS_SUCCESS || status != STATUS_INFO_LENGTH_MISMATCH) break; else // status == STATUS_INFO_LENGTH_MISMATCH { if (size == 0) // Returned required buffer size is always 0 on Windows 2000/XP. { if (bufSize == 0) { bufSize = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * c_NumOfProcessors; } else { bufSize += sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); } } else { if (size != bufSize) { bufSize = size; } else // ?? { bufSize += sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); } } delete [] buf; buf = new BYTE[bufSize]; } ++loop; } while (loop < 5); if (status != STATUS_SUCCESS) // failed { delete [] buf; return false; } if (bufSize != c_BufferSize) { // Store the new buffer size c_BufferSize = bufSize; } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* systemPerfInfo = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)buf; int processor = m_Processor - 1; CalcUsage(Li2Double(systemPerfInfo[processor].IdleTime), Li2Double(systemPerfInfo[processor].KernelTime) + Li2Double(systemPerfInfo[processor].UserTime)); delete [] buf; } else { return false; } return PostUpdate(); }
void PerfDataRefresh(void) { ULONG ulSize; NTSTATUS status; LPBYTE pBuffer; ULONG BufferSize; PSYSTEM_PROCESS_INFORMATION pSPI; PPERFDATA pPDOld; ULONG Idx, Idx2; HANDLE hProcess; HANDLE hProcessToken; SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIMEOFDAY_INFORMATION SysTimeInfo; SYSTEM_FILECACHE_INFORMATION SysCacheInfo; LPBYTE SysHandleInfoData; PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcessorTimeInfo; double CurrentKernelTime; PSECURITY_DESCRIPTOR ProcessSD; PSID ProcessUser; ULONG Buffer[64]; /* must be 4 bytes aligned! */ ULONG cwcUserName; /* Get new system time */ status = NtQuerySystemInformation(SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), NULL); if (!NT_SUCCESS(status)) return; /* Get new CPU's idle time */ status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL); if (!NT_SUCCESS(status)) return; /* Get system cache information */ status = NtQuerySystemInformation(SystemFileCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL); if (!NT_SUCCESS(status)) return; /* Get processor time information */ SysProcessorTimeInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)HeapAlloc(GetProcessHeap(), 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors); status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors, &ulSize); if (!NT_SUCCESS(status)) { if (SysProcessorTimeInfo != NULL) HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo); return; } /* Get handle information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; do { BufferSize += 0x10000; SysHandleInfoData = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, BufferSize); status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize); if (status == STATUS_INFO_LENGTH_MISMATCH) { HeapFree(GetProcessHeap(), 0, SysHandleInfoData); } } while (status == STATUS_INFO_LENGTH_MISMATCH); /* Get process information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; do { BufferSize += 0x10000; pBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, BufferSize); status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize); if (status == STATUS_INFO_LENGTH_MISMATCH) { HeapFree(GetProcessHeap(), 0, pBuffer); } } while (status == STATUS_INFO_LENGTH_MISMATCH); EnterCriticalSection(&PerfDataCriticalSection); /* * Save system performance info */ memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION)); /* * Save system cache info */ memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_FILECACHE_INFORMATION)); /* * Save system processor time info */ if (SystemProcessorTimeInfo) { HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo); } SystemProcessorTimeInfo = SysProcessorTimeInfo; /* * Save system handle info */ memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION)); HeapFree(GetProcessHeap(), 0, SysHandleInfoData); for (CurrentKernelTime=0, Idx=0; Idx<(ULONG)SystemBasicInfo.NumberOfProcessors; Idx++) { CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime); CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime); CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime); } /* If it's a first call - skip idle time calcs */ if (liOldIdleTime.QuadPart != 0) { /* CurrentValue = NewValue - OldValue */ dbIdleTime = Li2Double(SysPerfInfo.IdleProcessTime) - Li2Double(liOldIdleTime); dbKernelTime = CurrentKernelTime - OldKernelTime; dbSystemTime = Li2Double(SysTimeInfo.CurrentTime) - Li2Double(liOldSystemTime); /* CurrentCpuIdle = IdleTime / SystemTime */ dbIdleTime = dbIdleTime / dbSystemTime; dbKernelTime = dbKernelTime / dbSystemTime; /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */ dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */ dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */ } /* Store new CPU's idle and system time */ liOldIdleTime = SysPerfInfo.IdleProcessTime; liOldSystemTime = SysTimeInfo.CurrentTime; OldKernelTime = CurrentKernelTime; /* Determine the process count * We loop through the data we got from NtQuerySystemInformation * and count how many structures there are (until RelativeOffset is 0) */ ProcessCountOld = ProcessCount; ProcessCount = 0; pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; while (pSPI) { ProcessCount++; if (pSPI->NextEntryOffset == 0) break; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset); } /* Now alloc a new PERFDATA array and fill in the data */ pPerfData = (PPERFDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PERFDATA) * ProcessCount); pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; for (Idx=0; Idx<ProcessCount; Idx++) { /* Get the old perf data for this process (if any) */ /* so that we can establish delta values */ pPDOld = NULL; if (pPerfDataOld) { for (Idx2=0; Idx2<ProcessCountOld; Idx2++) { if (pPerfDataOld[Idx2].ProcessId == pSPI->UniqueProcessId) { pPDOld = &pPerfDataOld[Idx2]; break; } } } if (pSPI->ImageName.Buffer) { /* Don't assume a UNICODE_STRING Buffer is zero terminated: */ int len = pSPI->ImageName.Length / 2; /* Check against max size and allow for terminating zero (already zeroed): */ if(len >= MAX_PATH)len=MAX_PATH - 1; wcsncpy(pPerfData[Idx].ImageName, pSPI->ImageName.Buffer, len); } else { LoadStringW(hInst, IDS_IDLE_PROCESS, pPerfData[Idx].ImageName, sizeof(pPerfData[Idx].ImageName) / sizeof(pPerfData[Idx].ImageName[0])); } pPerfData[Idx].ProcessId = pSPI->UniqueProcessId; if (pPDOld) { double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime); double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime); double CpuTime = (CurTime - OldTime) / dbSystemTime; CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */ pPerfData[Idx].CPUUsage = (ULONG)CpuTime; } pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart; pPerfData[Idx].WorkingSetSizeBytes = pSPI->WorkingSetSize; pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSize; if (pPDOld) pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->WorkingSetSize - (LONG)pPDOld->WorkingSetSizeBytes); else pPerfData[Idx].WorkingSetSizeDelta = 0; pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount; if (pPDOld) pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount); else pPerfData[Idx].PageFaultCountDelta = 0; pPerfData[Idx].VirtualMemorySizeBytes = pSPI->VirtualSize; pPerfData[Idx].PagedPoolUsagePages = pSPI->QuotaPeakPagedPoolUsage; pPerfData[Idx].NonPagedPoolUsagePages = pSPI->QuotaPeakNonPagedPoolUsage; pPerfData[Idx].BasePriority = pSPI->BasePriority; pPerfData[Idx].HandleCount = pSPI->HandleCount; pPerfData[Idx].ThreadCount = pSPI->NumberOfThreads; pPerfData[Idx].SessionId = pSPI->SessionId; pPerfData[Idx].UserName[0] = UNICODE_NULL; pPerfData[Idx].USERObjectCount = 0; pPerfData[Idx].GDIObjectCount = 0; ProcessUser = SystemUserSid; ProcessSD = NULL; if (pSPI->UniqueProcessId != NULL) { hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | READ_CONTROL, FALSE, PtrToUlong(pSPI->UniqueProcessId)); if (hProcess) { /* don't query the information of the system process. It's possible but returns Administrators as the owner of the process instead of SYSTEM */ if (pSPI->UniqueProcessId != (HANDLE)0x4) { if (OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) { DWORD RetLen = 0; BOOL Ret; Ret = GetTokenInformation(hProcessToken, TokenUser, (LPVOID)Buffer, sizeof(Buffer), &RetLen); CloseHandle(hProcessToken); if (Ret) ProcessUser = ((PTOKEN_USER)Buffer)->User.Sid; else goto ReadProcOwner; } else { ReadProcOwner: GetSecurityInfo(hProcess, SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION, &ProcessUser, NULL, NULL, NULL, &ProcessSD); } pPerfData[Idx].USERObjectCount = GetGuiResources(hProcess, GR_USEROBJECTS); pPerfData[Idx].GDIObjectCount = GetGuiResources(hProcess, GR_GDIOBJECTS); } GetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters); CloseHandle(hProcess); } else { goto ClearInfo; } } else { ClearInfo: /* clear information we were unable to fetch */ ZeroMemory(&pPerfData[Idx].IOCounters, sizeof(IO_COUNTERS)); } cwcUserName = sizeof(pPerfData[0].UserName) / sizeof(pPerfData[0].UserName[0]); CachedGetUserFromSid(ProcessUser, pPerfData[Idx].UserName, &cwcUserName); if (ProcessSD != NULL) { LocalFree((HLOCAL)ProcessSD); } pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart; pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset); } HeapFree(GetProcessHeap(), 0, pBuffer); if (pPerfDataOld) { HeapFree(GetProcessHeap(), 0, pPerfDataOld); } pPerfDataOld = pPerfData; LeaveCriticalSection(&PerfDataCriticalSection); }
//------------------------------------------------------------------ // get CPU usage on NT-style operating systems //------------------------------------------------------------------ DWORD cpuUsageNT() { static SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; static SYSTEM_TIME_INFORMATION SysTimeInfo; static SYSTEM_BASIC_INFORMATION SysBaseInfo; static double dbIdleTime; static double dbSystemTime; static LONG status; static LARGE_INTEGER liOldIdleTime = {0,0}; static LARGE_INTEGER liOldSystemTime = {0,0}; static BOOL init = FALSE; static PROCNTQSI NtQuerySystemInformation = NULL; DWORD retVal = 0xffffffff; if( !init ) { NtQuerySystemInformation = (PROCNTQSI)GetProcAddress( GetModuleHandle(_T("ntdll")), "NtQuerySystemInformation" ); if( !NtQuerySystemInformation ) return 0xffffffff; // get number of processors in the system status = NtQuerySystemInformation( SystemBasicInformation, &SysBaseInfo, sizeof(SysBaseInfo), NULL ); if( status != NO_ERROR ) return 0xffffffff; init = TRUE; } // get new system time status = NtQuerySystemInformation( SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0 ); if( status != NO_ERROR ) return 0xffffffff; // get new CPU's idle time status = NtQuerySystemInformation( SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL ); if( status != NO_ERROR ) return 0xffffffff; // if it's a first call - skip it if( liOldIdleTime.QuadPart != 0 ) { // CurrentValue = NewValue - OldValue dbIdleTime = Li2Double( SysPerfInfo.liIdleTime ) - Li2Double( liOldIdleTime ); dbSystemTime = Li2Double( SysTimeInfo.liKeSystemTime ) - Li2Double( liOldSystemTime ); // CurrentCpuIdle = IdleTime / SystemTime dbIdleTime = dbIdleTime / dbSystemTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5; retVal = (DWORD)dbIdleTime; } // store new CPU's idle and system time liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; return retVal; }
static void WinNT_PollThread(void *vparam) { CpuUsageThreadParams *param = (CpuUsageThreadParams*)vparam; DWORD dwBufferSize=0,dwCount; BYTE *pBuffer=NULL; PERF_DATA_BLOCK *pPerfData=NULL; LONG res,lCount; PERF_OBJECT_TYPE *pPerfObj; PERF_COUNTER_DEFINITION *pPerfCounter; PERF_INSTANCE_DEFINITION *pPerfInstance; PERF_COUNTER_BLOCK *pPerfCounterBlock; DWORD dwObjectId,dwCounterId; WCHAR wszValueName[11],*pwszInstanceName; BYTE nCpuUsage; BOOL fSwitched,fFound,fIsFirst=FALSE; LARGE_INTEGER liPrevCounterValue={0},liCurrentCounterValue={0},liPrevPerfTime100nSec={0}; /* init */ dwObjectId=238; /*'Processor' object */ dwCounterId=6; /* '% processor time' counter */ pwszInstanceName=L"_Total"; /* '_Total' instance */ _itot_s(dwObjectId, wszValueName, 10); fSwitched = WinNT_PerfStatsSwitch(_T("PerfOS"), FALSE); /* poll */ for(;;) { /* retrieve data for given object */ res=RegQueryValueExW(HKEY_PERFORMANCE_DATA,wszValueName,NULL,NULL,(BYTE*)pPerfData,&dwBufferSize); while(!pBuffer || res==ERROR_MORE_DATA) { pBuffer=(BYTE*)mir_realloc(pPerfData,dwBufferSize+=256); if (!pBuffer) break; pPerfData=(PERF_DATA_BLOCK*)pBuffer; res=RegQueryValueExW(HKEY_PERFORMANCE_DATA,wszValueName,NULL,NULL,pBuffer,&dwBufferSize); } if (res != ERROR_SUCCESS) break; /* find object in data */ fFound=FALSE; /* first object */ pPerfObj=(PERF_OBJECT_TYPE*)((BYTE*)pPerfData+pPerfData->HeaderLength); for(dwCount=0;dwCount<pPerfData->NumObjectTypes;++dwCount) { if (pPerfObj->ObjectNameTitleIndex==dwObjectId) { /* find counter in object data */ /* first counter */ pPerfCounter=(PERF_COUNTER_DEFINITION*)((BYTE*)pPerfObj+pPerfObj->HeaderLength); for(dwCount=0;dwCount<(pPerfObj->NumCounters);++dwCount) { if (pPerfCounter->CounterNameTitleIndex==dwCounterId) { /* find instance in counter data */ if (pPerfObj->NumInstances==PERF_NO_INSTANCES) { pPerfCounterBlock=(PERF_COUNTER_BLOCK*)((BYTE*)pPerfObj+pPerfObj->DefinitionLength); liCurrentCounterValue=*(LARGE_INTEGER*)((BYTE*)pPerfCounterBlock+pPerfCounter->CounterOffset); fFound=TRUE; } else { /* first instance */ pPerfInstance=(PERF_INSTANCE_DEFINITION*)((BYTE*)pPerfObj+pPerfObj->DefinitionLength); for(lCount=0;lCount<(pPerfObj->NumInstances);++lCount) { pPerfCounterBlock=(PERF_COUNTER_BLOCK*)((BYTE*)pPerfInstance+pPerfInstance->ByteLength); if (!mir_wstrcmpi(pwszInstanceName,(WCHAR*)((BYTE*)pPerfInstance+pPerfInstance->NameOffset))) { liCurrentCounterValue=*(LARGE_INTEGER*)((BYTE*)pPerfCounterBlock+pPerfCounter->CounterOffset); fFound=TRUE; break; } /* next instance */ pPerfInstance=(PPERF_INSTANCE_DEFINITION)((BYTE*)pPerfCounterBlock+pPerfCounterBlock->ByteLength); } } break; } /* next counter */ pPerfCounter=(PERF_COUNTER_DEFINITION*)((BYTE*)pPerfCounter+pPerfCounter->ByteLength); } break; } /* next object */ pPerfObj=(PERF_OBJECT_TYPE*)((BYTE*)pPerfObj+pPerfObj->TotalByteLength); } if (!fFound) break; /* calc val from data, we need two samplings * counter type: PERF_100NSEC_TIMER_INV * calc: time base=100Ns, value=100*(1-(data_diff)/(100NsTime_diff)) */ if (!fIsFirst) { nCpuUsage=(BYTE)((1.0-(Li2Double(liCurrentCounterValue)-Li2Double(liPrevCounterValue))/(Li2Double(pPerfData->PerfTime100nSec)-Li2Double(liPrevPerfTime100nSec)))*100.0+0.5); if (!CallBackAndWait(param,nCpuUsage)) break; } else fIsFirst=FALSE; /* store current sampling for next */ memcpy(&liPrevCounterValue,&liCurrentCounterValue,sizeof(LARGE_INTEGER)); memcpy(&liPrevPerfTime100nSec,&pPerfData->PerfTime100nSec,sizeof(LARGE_INTEGER)); } /* uninit */ if (pPerfData) mir_free(pPerfData); if (fSwitched) WinNT_PerfStatsSwitch(_T("PerfOS"),TRUE); /* return error for PollCpuUsage() if never succeeded */ if (param->hFirstEvent != NULL) SetEvent(param->hFirstEvent); mir_free(param); }
int sysmon_cpupercent(void) { int r; // get new system time status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0); if (status != NO_ERROR) return -1; // get new CPU's idle time status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL); if (status != NO_ERROR) return -1; #ifdef WITH_EXCLUSION // get excluded process' time if (pxH) { GetProcessTimes(pxH, (FILETIME *)(&pxCreat), (FILETIME *)(&pxExit), (FILETIME *)(&pxKern), (FILETIME *)(&pxUser)); } #endif // if it's a first call - skip it if (liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); #ifdef WITH_EXCLUSION if (pxH) { dbPxTime = Li2Double(pxKern) - Li2Double(pxOKern) + Li2Double(pxUser) - Li2Double(pxOUser); dbIdleTime = (dbIdleTime + dbPxTime) / dbSystemTime; } else #endif { dbIdleTime = dbIdleTime / dbSystemTime; } // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors; } // store new CPU's idle and system time liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; #ifdef WITH_EXCLUSION if (pxH) { pxOKern = pxKern; pxOUser = pxUser; } #endif r = lrint(dbIdleTime); if (r < 0) r = 0; else if (r > 100) r = 100; return r; }