/* * ReactOS Task Manager * * perfdata.c * * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <commctrl.h> #include <winnt.h> #include "taskmgr.h" #include "perfdata.h" static PROCNTQSI pNtQuerySystemInformation = NULL; static PROCGGR pGetGuiResources = NULL; static PROCGPIC pGetProcessIoCounters = NULL; static PROCISW64 pIsWow64Process = NULL; static CRITICAL_SECTION PerfDataCriticalSection; static PPERFDATA pPerfDataOld = NULL; /* Older perf data (saved to establish delta values) */ static PPERFDATA pPerfData = NULL; /* Most recent copy of perf data */ static ULONG ProcessCountOld = 0; static ULONG ProcessCount = 0; static double dbIdleTime; static double dbKernelTime; static double dbSystemTime; static LARGE_INTEGER liOldIdleTime = {{0,0}}; static double OldKernelTime = 0; static LARGE_INTEGER liOldSystemTime = {{0,0}}; static SYSTEM_PERFORMANCE_INFORMATION SystemPerfInfo; static SYSTEM_BASIC_INFORMATION SystemBasicInfo; static SYSTEM_CACHE_INFORMATION SystemCacheInfo; static SYSTEM_HANDLE_INFORMATION SystemHandleInfo; static PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemProcessorTimeInfo = NULL; BOOL PerfDataInitialize(void) { LONG status; static const WCHAR wszNtdll[] = {'n','t','d','l','l','.','d','l','l',0}; static const WCHAR wszUser32[] = {'u','s','e','r','3','2','.','d','l','l',0}; static const WCHAR wszKernel32[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0}; pNtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandleW(wszNtdll), "NtQuerySystemInformation"); pGetGuiResources = (PROCGGR)GetProcAddress(GetModuleHandleW(wszUser32), "GetGuiResources"); pGetProcessIoCounters = (PROCGPIC)GetProcAddress(GetModuleHandleW(wszKernel32), "GetProcessIoCounters"); pIsWow64Process = (PROCISW64)GetProcAddress(GetModuleHandleW(wszKernel32), "IsWow64Process"); InitializeCriticalSection(&PerfDataCriticalSection); if (!pNtQuerySystemInformation) return FALSE; /* * Get number of processors in the system */ status = pNtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL); if (status != NO_ERROR) return FALSE; return TRUE; } 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, ARRAY_SIZE(idleW)); 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); } ULONG PerfDataGetProcessCount(void) { return ProcessCount; } ULONG PerfDataGetProcessorUsage(void) { if( dbIdleTime < 0.0 ) return 0; if( dbIdleTime > 100.0 ) return 100; return (ULONG)dbIdleTime; } ULONG PerfDataGetProcessorSystemUsage(void) { if( dbKernelTime < 0.0 ) return 0; if( dbKernelTime > 100.0 ) return 100; return (ULONG)dbKernelTime; } BOOL PerfDataGetImageName(ULONG Index, LPWSTR lpImageName, int nMaxCount) { static const WCHAR proc32W[] = {' ','*','3','2',0}; BOOL bSuccessful; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) { wcsncpy(lpImageName, pPerfData[Index].ImageName, nMaxCount); if (pPerfData[Index].Wow64Process && nMaxCount - lstrlenW(lpImageName) > 4 /* =lstrlenW(proc32W) */) lstrcatW(lpImageName, proc32W); bSuccessful = TRUE; } else { bSuccessful = FALSE; } LeaveCriticalSection(&PerfDataCriticalSection); return bSuccessful; } ULONG PerfDataGetProcessId(ULONG Index) { ULONG ProcessId; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) ProcessId = pPerfData[Index].ProcessId; else ProcessId = 0; LeaveCriticalSection(&PerfDataCriticalSection); return ProcessId; } BOOL PerfDataGetUserName(ULONG Index, LPWSTR lpUserName, int nMaxCount) { BOOL bSuccessful; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) { wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount); bSuccessful = TRUE; } else { bSuccessful = FALSE; } LeaveCriticalSection(&PerfDataCriticalSection); return bSuccessful; } ULONG PerfDataGetSessionId(ULONG Index) { ULONG SessionId; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) SessionId = pPerfData[Index].SessionId; else SessionId = 0; LeaveCriticalSection(&PerfDataCriticalSection); return SessionId; } ULONG PerfDataGetCPUUsage(ULONG Index) { ULONG CpuUsage; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) CpuUsage = pPerfData[Index].CPUUsage; else CpuUsage = 0; LeaveCriticalSection(&PerfDataCriticalSection); return CpuUsage; } TIME PerfDataGetCPUTime(ULONG Index) { TIME CpuTime = {{0,0}}; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) CpuTime = pPerfData[Index].CPUTime; LeaveCriticalSection(&PerfDataCriticalSection); return CpuTime; } ULONG PerfDataGetWorkingSetSizeBytes(ULONG Index) { ULONG WorkingSetSizeBytes; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) WorkingSetSizeBytes = pPerfData[Index].vmCounters.WorkingSetSize; else WorkingSetSizeBytes = 0; LeaveCriticalSection(&PerfDataCriticalSection); return WorkingSetSizeBytes; } ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index) { ULONG PeakWorkingSetSizeBytes; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) PeakWorkingSetSizeBytes = pPerfData[Index].vmCounters.PeakWorkingSetSize; else PeakWorkingSetSizeBytes = 0; LeaveCriticalSection(&PerfDataCriticalSection); return PeakWorkingSetSizeBytes; } ULONG PerfDataGetWorkingSetSizeDelta(ULONG Index) { ULONG WorkingSetSizeDelta; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) WorkingSetSizeDelta = pPerfData[Index].WorkingSetSizeDelta; else WorkingSetSizeDelta = 0; LeaveCriticalSection(&PerfDataCriticalSection); return WorkingSetSizeDelta; } ULONG PerfDataGetPageFaultCount(ULONG Index) { ULONG PageFaultCount; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) PageFaultCount = pPerfData[Index].vmCounters.PageFaultCount; else PageFaultCount = 0; LeaveCriticalSection(&PerfDataCriticalSection); return PageFaultCount; } ULONG PerfDataGetPageFaultCountDelta(ULONG Index) { ULONG PageFaultCountDelta; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) PageFaultCountDelta = pPerfData[Index].PageFaultCountDelta; else PageFaultCountDelta = 0; LeaveCriticalSection(&PerfDataCriticalSection); return PageFaultCountDelta; } ULONG PerfDataGetVirtualMemorySizeBytes(ULONG Index) { ULONG VirtualMemorySizeBytes; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) VirtualMemorySizeBytes = pPerfData[Index].vmCounters.VirtualSize; else VirtualMemorySizeBytes = 0; LeaveCriticalSection(&PerfDataCriticalSection); return VirtualMemorySizeBytes; } ULONG PerfDataGetPagedPoolUsagePages(ULONG Index) { ULONG PagedPoolUsagePages; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) PagedPoolUsagePages = pPerfData[Index].vmCounters.QuotaPagedPoolUsage; else PagedPoolUsagePages = 0; LeaveCriticalSection(&PerfDataCriticalSection); return PagedPoolUsagePages; } ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index) { ULONG NonPagedPoolUsagePages; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) NonPagedPoolUsagePages = pPerfData[Index].vmCounters.QuotaNonPagedPoolUsage; else NonPagedPoolUsagePages = 0; LeaveCriticalSection(&PerfDataCriticalSection); return NonPagedPoolUsagePages; } ULONG PerfDataGetBasePriority(ULONG Index) { ULONG BasePriority; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) BasePriority = pPerfData[Index].BasePriority; else BasePriority = 0; LeaveCriticalSection(&PerfDataCriticalSection); return BasePriority; } ULONG PerfDataGetHandleCount(ULONG Index) { ULONG HandleCount; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) HandleCount = pPerfData[Index].HandleCount; else HandleCount = 0; LeaveCriticalSection(&PerfDataCriticalSection); return HandleCount; } ULONG PerfDataGetThreadCount(ULONG Index) { ULONG ThreadCount; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) ThreadCount = pPerfData[Index].ThreadCount; else ThreadCount = 0; LeaveCriticalSection(&PerfDataCriticalSection); return ThreadCount; } ULONG PerfDataGetUSERObjectCount(ULONG Index) { ULONG USERObjectCount; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) USERObjectCount = pPerfData[Index].USERObjectCount; else USERObjectCount = 0; LeaveCriticalSection(&PerfDataCriticalSection); return USERObjectCount; } ULONG PerfDataGetGDIObjectCount(ULONG Index) { ULONG GDIObjectCount; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) GDIObjectCount = pPerfData[Index].GDIObjectCount; else GDIObjectCount = 0; LeaveCriticalSection(&PerfDataCriticalSection); return GDIObjectCount; } BOOL PerfDataGetIOCounters(ULONG Index, PIO_COUNTERS pIoCounters) { BOOL bSuccessful; EnterCriticalSection(&PerfDataCriticalSection); if (Index < ProcessCount) { memcpy(pIoCounters, &pPerfData[Index].IOCounters, sizeof(IO_COUNTERS)); bSuccessful = TRUE; } else bSuccessful = FALSE; LeaveCriticalSection(&PerfDataCriticalSection); return bSuccessful; } ULONG PerfDataGetCommitChargeTotalK(void) { ULONG Total; ULONG PageSize; EnterCriticalSection(&PerfDataCriticalSection); Total = SystemPerfInfo.TotalCommittedPages; PageSize = SystemBasicInfo.PageSize; LeaveCriticalSection(&PerfDataCriticalSection); Total = Total * (PageSize / 1024); return Total; } ULONG PerfDataGetCommitChargeLimitK(void) { ULONG Limit; ULONG PageSize; EnterCriticalSection(&PerfDataCriticalSection); Limit = SystemPerfInfo.TotalCommitLimit; PageSize = SystemBasicInfo.PageSize; LeaveCriticalSection(&PerfDataCriticalSection); Limit = Limit * (PageSize / 1024); return Limit; } ULONG PerfDataGetCommitChargePeakK(void) { ULONG Peak; ULONG PageSize; EnterCriticalSection(&PerfDataCriticalSection); Peak = SystemPerfInfo.PeakCommitment; PageSize = SystemBasicInfo.PageSize; LeaveCriticalSection(&PerfDataCriticalSection); Peak = Peak * (PageSize / 1024); return Peak; } ULONG PerfDataGetKernelMemoryTotalK(void) { ULONG Total; ULONG Paged; ULONG NonPaged; ULONG PageSize; EnterCriticalSection(&PerfDataCriticalSection); Paged = SystemPerfInfo.PagedPoolUsage; NonPaged = SystemPerfInfo.NonPagedPoolUsage; PageSize = SystemBasicInfo.PageSize; LeaveCriticalSection(&PerfDataCriticalSection); Paged = Paged * (PageSize / 1024); NonPaged = NonPaged * (PageSize / 1024); Total = Paged + NonPaged; return Total; } ULONG PerfDataGetKernelMemoryPagedK(void) { ULONG Paged; ULONG PageSize; EnterCriticalSection(&PerfDataCriticalSection); Paged = SystemPerfInfo.PagedPoolUsage; PageSize = SystemBasicInfo.PageSize; LeaveCriticalSection(&PerfDataCriticalSection); Paged = Paged * (PageSize / 1024); return Paged; } ULONG PerfDataGetKernelMemoryNonPagedK(void) { ULONG NonPaged; ULONG PageSize; EnterCriticalSection(&PerfDataCriticalSection); NonPaged = SystemPerfInfo.NonPagedPoolUsage; PageSize = SystemBasicInfo.PageSize; LeaveCriticalSection(&PerfDataCriticalSection); NonPaged = NonPaged * (PageSize / 1024); return NonPaged; } ULONG PerfDataGetPhysicalMemoryTotalK(void) { ULONG Total; ULONG PageSize; EnterCriticalSection(&PerfDataCriticalSection); Total = SystemBasicInfo.MmNumberOfPhysicalPages; PageSize = SystemBasicInfo.PageSize; LeaveCriticalSection(&PerfDataCriticalSection); Total = Total * (PageSize / 1024); return Total; } ULONG PerfDataGetPhysicalMemoryAvailableK(void) { ULONG Available; ULONG PageSize; EnterCriticalSection(&PerfDataCriticalSection); Available = SystemPerfInfo.AvailablePages; PageSize = SystemBasicInfo.PageSize; LeaveCriticalSection(&PerfDataCriticalSection); Available = Available * (PageSize / 1024); return Available; } ULONG PerfDataGetPhysicalMemorySystemCacheK(void) { ULONG SystemCache; EnterCriticalSection(&PerfDataCriticalSection); SystemCache = SystemCacheInfo.CurrentSize; LeaveCriticalSection(&PerfDataCriticalSection); SystemCache = SystemCache / 1024; return SystemCache; } ULONG PerfDataGetSystemHandleCount(void) { ULONG HandleCount; EnterCriticalSection(&PerfDataCriticalSection); HandleCount = SystemHandleInfo.Count; LeaveCriticalSection(&PerfDataCriticalSection); return HandleCount; } ULONG PerfDataGetTotalThreadCount(void) { ULONG ThreadCount = 0; ULONG i; EnterCriticalSection(&PerfDataCriticalSection); for (i=0; i<ProcessCount; i++) { ThreadCount += pPerfData[i].ThreadCount; } LeaveCriticalSection(&PerfDataCriticalSection); return ThreadCount; }