| /* |
| * 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 |
| */ |
| |
| #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */ |
| #include <windows.h> |
| #include <commctrl.h> |
| #include <stdlib.h> |
| #include <malloc.h> |
| #include <memory.h> |
| #include <tchar.h> |
| #include <stdio.h> |
| #include <winnt.h> |
| #include "taskmgr.h" |
| #include "perfdata.h" |
| |
| PROCNTQSI NtQuerySystemInformation = NULL; |
| PROCGGR pGetGuiResources = NULL; |
| PROCGPIC pGetProcessIoCounters = NULL; |
| CRITICAL_SECTION PerfDataCriticalSection; |
| PPERFDATA pPerfDataOld = NULL; /* Older perf data (saved to establish delta values) */ |
| PPERFDATA pPerfData = NULL; /* Most recent copy of perf data */ |
| ULONG ProcessCountOld = 0; |
| ULONG ProcessCount = 0; |
| double dbIdleTime; |
| double dbKernelTime; |
| double dbSystemTime; |
| LARGE_INTEGER liOldIdleTime = {{0,0}}; |
| double OldKernelTime = 0; |
| LARGE_INTEGER liOldSystemTime = {{0,0}}; |
| SYSTEM_PERFORMANCE_INFORMATION SystemPerfInfo; |
| SYSTEM_BASIC_INFORMATION SystemBasicInfo; |
| SYSTEM_CACHE_INFORMATION SystemCacheInfo; |
| SYSTEM_HANDLE_INFORMATION SystemHandleInfo; |
| PSYSTEM_PROCESSORTIME_INFO SystemProcessorTimeInfo = NULL; |
| |
| BOOL PerfDataInitialize(void) |
| { |
| LONG status; |
| |
| NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQuerySystemInformation"); |
| pGetGuiResources = (PROCGGR)GetProcAddress(GetModuleHandle(_T("user32.dll")), "GetGuiResources"); |
| pGetProcessIoCounters = (PROCGPIC)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "GetProcessIoCounters"); |
| |
| InitializeCriticalSection(&PerfDataCriticalSection); |
| |
| if (!NtQuerySystemInformation) |
| return FALSE; |
| |
| /* |
| * Get number of processors in the system |
| */ |
| status = NtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL); |
| if (status != NO_ERROR) |
| return FALSE; |
| |
| return TRUE; |
| } |
| |
| void PerfDataUninitialize(void) |
| { |
| NtQuerySystemInformation = NULL; |
| |
| DeleteCriticalSection(&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; |
| 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 = (PSYSTEM_PROCESSORTIME_INFO)malloc(sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors); |
| status = NtQuerySystemInformation(SystemProcessorTimeInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSORTIME_INFO) * 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; |
| do |
| { |
| BufferSize += 0x10000; |
| SysHandleInfoData = (LPBYTE)malloc(BufferSize); |
| |
| status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize); |
| |
| if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { |
| free(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 = (LPBYTE)malloc(BufferSize); |
| |
| status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize); |
| |
| if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { |
| free(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 |
| */ |
| free(SystemProcessorTimeInfo); |
| SystemProcessorTimeInfo = SysProcessorTimeInfo; |
| |
| /* |
| * Save system handle info |
| */ |
| memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION)); |
| free(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 */ |
| free(pPerfDataOld); |
| pPerfDataOld = pPerfData; |
| pPerfData = (PPERFDATA)malloc(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); |
| } |
| free(pBuffer); |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| } |
| |
| ULONG PerfDataGetProcessCount(void) |
| { |
| return ProcessCount; |
| } |
| |
| ULONG PerfDataGetProcessorUsage(void) |
| { |
| return (ULONG)dbIdleTime; |
| } |
| |
| ULONG PerfDataGetProcessorSystemUsage(void) |
| { |
| return (ULONG)dbKernelTime; |
| } |
| |
| BOOL PerfDataGetImageName(ULONG Index, LPTSTR lpImageName, int nMaxCount) |
| { |
| BOOL bSuccessful; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| if (Index < ProcessCount) { |
| #ifdef _UNICODE |
| wcsncpy(lpImageName, pPerfData[Index].ImageName, nMaxCount); |
| #else |
| WideCharToMultiByte(CP_ACP, 0, pPerfData[Index].ImageName, -1, lpImageName, nMaxCount, NULL, NULL); |
| #endif |
| |
| 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, LPTSTR lpUserName, int nMaxCount) |
| { |
| BOOL bSuccessful; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| if (Index < ProcessCount) { |
| #ifdef _UNICODE |
| wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount); |
| #else |
| WideCharToMultiByte(CP_ACP, 0, pPerfData[Index].UserName, -1, lpUserName, nMaxCount, NULL, NULL); |
| #endif |
| |
| 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].WorkingSetSizeBytes; |
| else |
| WorkingSetSizeBytes = 0; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| return WorkingSetSizeBytes; |
| } |
| |
| ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index) |
| { |
| ULONG PeakWorkingSetSizeBytes; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| if (Index < ProcessCount) |
| PeakWorkingSetSizeBytes = pPerfData[Index].PeakWorkingSetSizeBytes; |
| 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].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].VirtualMemorySizeBytes; |
| else |
| VirtualMemorySizeBytes = 0; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| return VirtualMemorySizeBytes; |
| } |
| |
| ULONG PerfDataGetPagedPoolUsagePages(ULONG Index) |
| { |
| ULONG PagedPoolUsagePages; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| if (Index < ProcessCount) |
| PagedPoolUsagePages = pPerfData[Index].PagedPoolUsagePages; |
| else |
| PagedPoolUsagePages = 0; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| return PagedPoolUsagePages; |
| } |
| |
| ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index) |
| { |
| ULONG NonPagedPoolUsagePages; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| if (Index < ProcessCount) |
| NonPagedPoolUsagePages = pPerfData[Index].NonPagedPoolUsagePages; |
| 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.MmTotalCommitedPages; |
| PageSize = SystemBasicInfo.uPageSize; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| Total = Total * (PageSize / 1024); |
| |
| return Total; |
| } |
| |
| ULONG PerfDataGetCommitChargeLimitK(void) |
| { |
| ULONG Limit; |
| ULONG PageSize; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| Limit = SystemPerfInfo.MmTotalCommitLimit; |
| PageSize = SystemBasicInfo.uPageSize; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| Limit = Limit * (PageSize / 1024); |
| |
| return Limit; |
| } |
| |
| ULONG PerfDataGetCommitChargePeakK(void) |
| { |
| ULONG Peak; |
| ULONG PageSize; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| Peak = SystemPerfInfo.MmPeakLimit; |
| PageSize = SystemBasicInfo.uPageSize; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| Peak = Peak * (PageSize / 1024); |
| |
| return Peak; |
| } |
| |
| ULONG PerfDataGetKernelMemoryTotalK(void) |
| { |
| ULONG Total; |
| ULONG Paged; |
| ULONG NonPaged; |
| ULONG PageSize; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| Paged = SystemPerfInfo.PoolPagedBytes; |
| NonPaged = SystemPerfInfo.PoolNonPagedBytes; |
| PageSize = SystemBasicInfo.uPageSize; |
| |
| 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.PoolPagedBytes; |
| PageSize = SystemBasicInfo.uPageSize; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| Paged = Paged * (PageSize / 1024); |
| |
| return Paged; |
| } |
| |
| ULONG PerfDataGetKernelMemoryNonPagedK(void) |
| { |
| ULONG NonPaged; |
| ULONG PageSize; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| NonPaged = SystemPerfInfo.PoolNonPagedBytes; |
| PageSize = SystemBasicInfo.uPageSize; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| NonPaged = NonPaged * (PageSize / 1024); |
| |
| return NonPaged; |
| } |
| |
| ULONG PerfDataGetPhysicalMemoryTotalK(void) |
| { |
| ULONG Total; |
| ULONG PageSize; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| Total = SystemBasicInfo.uMmNumberOfPhysicalPages; |
| PageSize = SystemBasicInfo.uPageSize; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| Total = Total * (PageSize / 1024); |
| |
| return Total; |
| } |
| |
| ULONG PerfDataGetPhysicalMemoryAvailableK(void) |
| { |
| ULONG Available; |
| ULONG PageSize; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| Available = SystemPerfInfo.MmAvailablePages; |
| PageSize = SystemBasicInfo.uPageSize; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| Available = Available * (PageSize / 1024); |
| |
| return Available; |
| } |
| |
| ULONG PerfDataGetPhysicalMemorySystemCacheK(void) |
| { |
| ULONG SystemCache; |
| ULONG PageSize; |
| |
| EnterCriticalSection(&PerfDataCriticalSection); |
| |
| SystemCache = SystemCacheInfo.CurrentSize; |
| PageSize = SystemBasicInfo.uPageSize; |
| |
| LeaveCriticalSection(&PerfDataCriticalSection); |
| |
| /* SystemCache = SystemCache * (PageSize / 1024); */ |
| 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; |
| } |