NTSTATUS NTAPI PsaEnumerateProcessesAndThreads(IN PPROC_ENUM_ROUTINE ProcessCallback, IN OUT PVOID ProcessCallbackContext, IN PTHREAD_ENUM_ROUTINE ThreadCallback, IN OUT PVOID ThreadCallbackContext) { PSYSTEM_PROCESS_INFORMATION pInfoBuffer = NULL; NTSTATUS Status; if(ProcessCallback == NULL && ThreadCallback == NULL) { return STATUS_INVALID_PARAMETER; } /* get the processes and threads list */ Status = PsaCaptureProcessesAndThreads(&pInfoBuffer); if(!NT_SUCCESS(Status)) { goto Bail; } /* walk the processes and threads list */ Status = PsaWalkProcessesAndThreads(pInfoBuffer, ProcessCallback, ProcessCallbackContext, ThreadCallback, ThreadCallbackContext); Bail: PsaFreeCapture(pInfoBuffer); return Status; }
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); }