| /* | |
| * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 | |
| */ | |
| if (SystemProcessorTimeInfo) { | |
| 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 */ | |
| if (pPerfDataOld) { | |
| 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; | |
| } |