perfdata.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. /*
  2. * ReactOS Task Manager
  3. *
  4. * perfdata.c
  5. *
  6. * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  21. */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <windows.h>
  25. #include <commctrl.h>
  26. #include <winnt.h>
  27. #include "taskmgr.h"
  28. #include "perfdata.h"
  29. static PROCNTQSI pNtQuerySystemInformation = NULL;
  30. static PROCGGR pGetGuiResources = NULL;
  31. static PROCGPIC pGetProcessIoCounters = NULL;
  32. static PROCISW64 pIsWow64Process = NULL;
  33. static CRITICAL_SECTION PerfDataCriticalSection;
  34. static PPERFDATA pPerfDataOld = NULL; /* Older perf data (saved to establish delta values) */
  35. static PPERFDATA pPerfData = NULL; /* Most recent copy of perf data */
  36. static ULONG ProcessCountOld = 0;
  37. static ULONG ProcessCount = 0;
  38. static double dbIdleTime;
  39. static double dbKernelTime;
  40. static double dbSystemTime;
  41. static LARGE_INTEGER liOldIdleTime = {{0,0}};
  42. static double OldKernelTime = 0;
  43. static LARGE_INTEGER liOldSystemTime = {{0,0}};
  44. static SYSTEM_PERFORMANCE_INFORMATION SystemPerfInfo;
  45. static SYSTEM_BASIC_INFORMATION SystemBasicInfo;
  46. static SYSTEM_CACHE_INFORMATION SystemCacheInfo;
  47. static SYSTEM_HANDLE_INFORMATION SystemHandleInfo;
  48. static PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemProcessorTimeInfo = NULL;
  49. BOOL PerfDataInitialize(void)
  50. {
  51. LONG status;
  52. static const WCHAR wszNtdll[] = {'n','t','d','l','l','.','d','l','l',0};
  53. static const WCHAR wszUser32[] = {'u','s','e','r','3','2','.','d','l','l',0};
  54. static const WCHAR wszKernel32[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
  55. pNtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandleW(wszNtdll), "NtQuerySystemInformation");
  56. pGetGuiResources = (PROCGGR)GetProcAddress(GetModuleHandleW(wszUser32), "GetGuiResources");
  57. pGetProcessIoCounters = (PROCGPIC)GetProcAddress(GetModuleHandleW(wszKernel32), "GetProcessIoCounters");
  58. pIsWow64Process = (PROCISW64)GetProcAddress(GetModuleHandleW(wszKernel32), "IsWow64Process");
  59. InitializeCriticalSection(&PerfDataCriticalSection);
  60. if (!pNtQuerySystemInformation)
  61. return FALSE;
  62. /*
  63. * Get number of processors in the system
  64. */
  65. status = pNtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL);
  66. if (status != NO_ERROR)
  67. return FALSE;
  68. return TRUE;
  69. }
  70. void PerfDataRefresh(void)
  71. {
  72. ULONG ulSize;
  73. LONG status;
  74. LPBYTE pBuffer;
  75. ULONG BufferSize;
  76. PSYSTEM_PROCESS_INFORMATION pSPI;
  77. PPERFDATA pPDOld;
  78. ULONG Idx, Idx2;
  79. HANDLE hProcess;
  80. HANDLE hProcessToken;
  81. WCHAR wszTemp[MAX_PATH];
  82. DWORD dwSize;
  83. SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
  84. SYSTEM_TIMEOFDAY_INFORMATION SysTimeInfo;
  85. SYSTEM_CACHE_INFORMATION SysCacheInfo;
  86. LPBYTE SysHandleInfoData;
  87. SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *SysProcessorTimeInfo;
  88. double CurrentKernelTime;
  89. /* Get new system time */
  90. status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
  91. if (status != NO_ERROR)
  92. return;
  93. /* Get new CPU's idle time */
  94. status = pNtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL);
  95. if (status != NO_ERROR)
  96. return;
  97. /* Get system cache information */
  98. status = pNtQuerySystemInformation(SystemCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL);
  99. if (status != NO_ERROR)
  100. return;
  101. /* Get processor time information */
  102. SysProcessorTimeInfo = HeapAlloc(GetProcessHeap(), 0,
  103. sizeof(*SysProcessorTimeInfo) * SystemBasicInfo.NumberOfProcessors);
  104. status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(*SysProcessorTimeInfo) * SystemBasicInfo.NumberOfProcessors, &ulSize);
  105. if (status != NO_ERROR) {
  106. HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo);
  107. return;
  108. }
  109. /* Get handle information
  110. * We don't know how much data there is so just keep
  111. * increasing the buffer size until the call succeeds
  112. */
  113. BufferSize = 0;
  114. do
  115. {
  116. BufferSize += 0x10000;
  117. SysHandleInfoData = HeapAlloc(GetProcessHeap(), 0, BufferSize);
  118. status = pNtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize);
  119. if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
  120. HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
  121. }
  122. } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
  123. /* Get process information
  124. * We don't know how much data there is so just keep
  125. * increasing the buffer size until the call succeeds
  126. */
  127. BufferSize = 0;
  128. do
  129. {
  130. BufferSize += 0x10000;
  131. pBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize);
  132. status = pNtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);
  133. if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
  134. HeapFree(GetProcessHeap(), 0, pBuffer);
  135. }
  136. } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
  137. EnterCriticalSection(&PerfDataCriticalSection);
  138. /*
  139. * Save system performance info
  140. */
  141. memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION));
  142. /*
  143. * Save system cache info
  144. */
  145. memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION));
  146. /*
  147. * Save system processor time info
  148. */
  149. HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo);
  150. SystemProcessorTimeInfo = SysProcessorTimeInfo;
  151. /*
  152. * Save system handle info
  153. */
  154. memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION));
  155. HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
  156. for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.NumberOfProcessors; Idx++) {
  157. CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
  158. CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].Reserved1[0]);
  159. CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].Reserved1[1]);
  160. }
  161. /* If it's a first call - skip idle time calcs */
  162. if (liOldIdleTime.QuadPart != 0) {
  163. /* CurrentValue = NewValue - OldValue */
  164. dbIdleTime = Li2Double(SysPerfInfo.IdleTime) - Li2Double(liOldIdleTime);
  165. dbKernelTime = CurrentKernelTime - OldKernelTime;
  166. dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
  167. /* CurrentCpuIdle = IdleTime / SystemTime */
  168. dbIdleTime = dbIdleTime / dbSystemTime;
  169. dbKernelTime = dbKernelTime / dbSystemTime;
  170. /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
  171. dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */
  172. dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */
  173. }
  174. /* Store new CPU's idle and system time */
  175. liOldIdleTime = SysPerfInfo.IdleTime;
  176. liOldSystemTime = SysTimeInfo.liKeSystemTime;
  177. OldKernelTime = CurrentKernelTime;
  178. /* Determine the process count
  179. * We loop through the data we got from NtQuerySystemInformation
  180. * and count how many structures there are (until RelativeOffset is 0)
  181. */
  182. ProcessCountOld = ProcessCount;
  183. ProcessCount = 0;
  184. pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
  185. while (pSPI) {
  186. ProcessCount++;
  187. if (pSPI->NextEntryOffset == 0)
  188. break;
  189. pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset);
  190. }
  191. /* Now alloc a new PERFDATA array and fill in the data */
  192. HeapFree(GetProcessHeap(), 0, pPerfDataOld);
  193. pPerfDataOld = pPerfData;
  194. pPerfData = HeapAlloc(GetProcessHeap(), 0, sizeof(PERFDATA) * ProcessCount);
  195. pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
  196. for (Idx=0; Idx<ProcessCount; Idx++) {
  197. /* Get the old perf data for this process (if any) */
  198. /* so that we can establish delta values */
  199. pPDOld = NULL;
  200. for (Idx2=0; Idx2<ProcessCountOld; Idx2++) {
  201. if (pPerfDataOld[Idx2].ProcessId == (DWORD_PTR)pSPI->UniqueProcessId) {
  202. pPDOld = &pPerfDataOld[Idx2];
  203. break;
  204. }
  205. }
  206. /* Clear out process perf data structure */
  207. memset(&pPerfData[Idx], 0, sizeof(PERFDATA));
  208. if (pSPI->ProcessName.Buffer)
  209. lstrcpyW(pPerfData[Idx].ImageName, pSPI->ProcessName.Buffer);
  210. else
  211. {
  212. WCHAR idleW[255];
  213. LoadStringW(hInst, IDS_SYSTEM_IDLE_PROCESS, idleW, ARRAY_SIZE(idleW));
  214. lstrcpyW(pPerfData[Idx].ImageName, idleW );
  215. }
  216. pPerfData[Idx].ProcessId = (DWORD_PTR)pSPI->UniqueProcessId;
  217. if (pPDOld) {
  218. double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
  219. double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
  220. double CpuTime = (CurTime - OldTime) / dbSystemTime;
  221. CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */
  222. pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
  223. }
  224. pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
  225. pPerfData[Idx].vmCounters.WorkingSetSize = pSPI->vmCounters.WorkingSetSize;
  226. pPerfData[Idx].vmCounters.PeakWorkingSetSize = pSPI->vmCounters.PeakWorkingSetSize;
  227. if (pPDOld)
  228. pPerfData[Idx].WorkingSetSizeDelta = labs(pSPI->vmCounters.WorkingSetSize - pPDOld->vmCounters.WorkingSetSize);
  229. else
  230. pPerfData[Idx].WorkingSetSizeDelta = 0;
  231. pPerfData[Idx].vmCounters.PageFaultCount = pSPI->vmCounters.PageFaultCount;
  232. if (pPDOld)
  233. pPerfData[Idx].PageFaultCountDelta = labs(pSPI->vmCounters.PageFaultCount - pPDOld->vmCounters.PageFaultCount);
  234. else
  235. pPerfData[Idx].PageFaultCountDelta = 0;
  236. pPerfData[Idx].vmCounters.VirtualSize = pSPI->vmCounters.VirtualSize;
  237. pPerfData[Idx].vmCounters.QuotaPagedPoolUsage = pSPI->vmCounters.QuotaPagedPoolUsage;
  238. pPerfData[Idx].vmCounters.QuotaNonPagedPoolUsage = pSPI->vmCounters.QuotaNonPagedPoolUsage;
  239. pPerfData[Idx].BasePriority = pSPI->dwBasePriority;
  240. pPerfData[Idx].HandleCount = pSPI->HandleCount;
  241. pPerfData[Idx].ThreadCount = pSPI->dwThreadCount;
  242. pPerfData[Idx].SessionId = pSPI->SessionId;
  243. hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD_PTR)pSPI->UniqueProcessId);
  244. if (hProcess) {
  245. if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
  246. ImpersonateLoggedOnUser(hProcessToken);
  247. memset(wszTemp, 0, sizeof(wszTemp));
  248. dwSize = MAX_PATH;
  249. GetUserNameW(wszTemp, &dwSize);
  250. RevertToSelf();
  251. CloseHandle(hProcessToken);
  252. }
  253. if (pGetGuiResources) {
  254. pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS);
  255. pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS);
  256. }
  257. if (pGetProcessIoCounters)
  258. pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
  259. if (pIsWow64Process)
  260. pIsWow64Process(hProcess, &pPerfData[Idx].Wow64Process);
  261. CloseHandle(hProcess);
  262. }
  263. pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
  264. pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
  265. pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset);
  266. }
  267. HeapFree(GetProcessHeap(), 0, pBuffer);
  268. LeaveCriticalSection(&PerfDataCriticalSection);
  269. }
  270. ULONG PerfDataGetProcessCount(void)
  271. {
  272. return ProcessCount;
  273. }
  274. ULONG PerfDataGetProcessorUsage(void)
  275. {
  276. if( dbIdleTime < 0.0 )
  277. return 0;
  278. if( dbIdleTime > 100.0 )
  279. return 100;
  280. return (ULONG)dbIdleTime;
  281. }
  282. ULONG PerfDataGetProcessorSystemUsage(void)
  283. {
  284. if( dbKernelTime < 0.0 )
  285. return 0;
  286. if( dbKernelTime > 100.0 )
  287. return 100;
  288. return (ULONG)dbKernelTime;
  289. }
  290. BOOL PerfDataGetImageName(ULONG Index, LPWSTR lpImageName, int nMaxCount)
  291. {
  292. static const WCHAR proc32W[] = {' ','*','3','2',0};
  293. BOOL bSuccessful;
  294. EnterCriticalSection(&PerfDataCriticalSection);
  295. if (Index < ProcessCount) {
  296. wcsncpy(lpImageName, pPerfData[Index].ImageName, nMaxCount);
  297. if (pPerfData[Index].Wow64Process &&
  298. nMaxCount - lstrlenW(lpImageName) > 4 /* =lstrlenW(proc32W) */)
  299. lstrcatW(lpImageName, proc32W);
  300. bSuccessful = TRUE;
  301. } else {
  302. bSuccessful = FALSE;
  303. }
  304. LeaveCriticalSection(&PerfDataCriticalSection);
  305. return bSuccessful;
  306. }
  307. ULONG PerfDataGetProcessId(ULONG Index)
  308. {
  309. ULONG ProcessId;
  310. EnterCriticalSection(&PerfDataCriticalSection);
  311. if (Index < ProcessCount)
  312. ProcessId = pPerfData[Index].ProcessId;
  313. else
  314. ProcessId = 0;
  315. LeaveCriticalSection(&PerfDataCriticalSection);
  316. return ProcessId;
  317. }
  318. BOOL PerfDataGetUserName(ULONG Index, LPWSTR lpUserName, int nMaxCount)
  319. {
  320. BOOL bSuccessful;
  321. EnterCriticalSection(&PerfDataCriticalSection);
  322. if (Index < ProcessCount) {
  323. wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount);
  324. bSuccessful = TRUE;
  325. } else {
  326. bSuccessful = FALSE;
  327. }
  328. LeaveCriticalSection(&PerfDataCriticalSection);
  329. return bSuccessful;
  330. }
  331. ULONG PerfDataGetSessionId(ULONG Index)
  332. {
  333. ULONG SessionId;
  334. EnterCriticalSection(&PerfDataCriticalSection);
  335. if (Index < ProcessCount)
  336. SessionId = pPerfData[Index].SessionId;
  337. else
  338. SessionId = 0;
  339. LeaveCriticalSection(&PerfDataCriticalSection);
  340. return SessionId;
  341. }
  342. ULONG PerfDataGetCPUUsage(ULONG Index)
  343. {
  344. ULONG CpuUsage;
  345. EnterCriticalSection(&PerfDataCriticalSection);
  346. if (Index < ProcessCount)
  347. CpuUsage = pPerfData[Index].CPUUsage;
  348. else
  349. CpuUsage = 0;
  350. LeaveCriticalSection(&PerfDataCriticalSection);
  351. return CpuUsage;
  352. }
  353. TIME PerfDataGetCPUTime(ULONG Index)
  354. {
  355. TIME CpuTime = {{0,0}};
  356. EnterCriticalSection(&PerfDataCriticalSection);
  357. if (Index < ProcessCount)
  358. CpuTime = pPerfData[Index].CPUTime;
  359. LeaveCriticalSection(&PerfDataCriticalSection);
  360. return CpuTime;
  361. }
  362. ULONG PerfDataGetWorkingSetSizeBytes(ULONG Index)
  363. {
  364. ULONG WorkingSetSizeBytes;
  365. EnterCriticalSection(&PerfDataCriticalSection);
  366. if (Index < ProcessCount)
  367. WorkingSetSizeBytes = pPerfData[Index].vmCounters.WorkingSetSize;
  368. else
  369. WorkingSetSizeBytes = 0;
  370. LeaveCriticalSection(&PerfDataCriticalSection);
  371. return WorkingSetSizeBytes;
  372. }
  373. ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index)
  374. {
  375. ULONG PeakWorkingSetSizeBytes;
  376. EnterCriticalSection(&PerfDataCriticalSection);
  377. if (Index < ProcessCount)
  378. PeakWorkingSetSizeBytes = pPerfData[Index].vmCounters.PeakWorkingSetSize;
  379. else
  380. PeakWorkingSetSizeBytes = 0;
  381. LeaveCriticalSection(&PerfDataCriticalSection);
  382. return PeakWorkingSetSizeBytes;
  383. }
  384. ULONG PerfDataGetWorkingSetSizeDelta(ULONG Index)
  385. {
  386. ULONG WorkingSetSizeDelta;
  387. EnterCriticalSection(&PerfDataCriticalSection);
  388. if (Index < ProcessCount)
  389. WorkingSetSizeDelta = pPerfData[Index].WorkingSetSizeDelta;
  390. else
  391. WorkingSetSizeDelta = 0;
  392. LeaveCriticalSection(&PerfDataCriticalSection);
  393. return WorkingSetSizeDelta;
  394. }
  395. ULONG PerfDataGetPageFaultCount(ULONG Index)
  396. {
  397. ULONG PageFaultCount;
  398. EnterCriticalSection(&PerfDataCriticalSection);
  399. if (Index < ProcessCount)
  400. PageFaultCount = pPerfData[Index].vmCounters.PageFaultCount;
  401. else
  402. PageFaultCount = 0;
  403. LeaveCriticalSection(&PerfDataCriticalSection);
  404. return PageFaultCount;
  405. }
  406. ULONG PerfDataGetPageFaultCountDelta(ULONG Index)
  407. {
  408. ULONG PageFaultCountDelta;
  409. EnterCriticalSection(&PerfDataCriticalSection);
  410. if (Index < ProcessCount)
  411. PageFaultCountDelta = pPerfData[Index].PageFaultCountDelta;
  412. else
  413. PageFaultCountDelta = 0;
  414. LeaveCriticalSection(&PerfDataCriticalSection);
  415. return PageFaultCountDelta;
  416. }
  417. ULONG PerfDataGetVirtualMemorySizeBytes(ULONG Index)
  418. {
  419. ULONG VirtualMemorySizeBytes;
  420. EnterCriticalSection(&PerfDataCriticalSection);
  421. if (Index < ProcessCount)
  422. VirtualMemorySizeBytes = pPerfData[Index].vmCounters.VirtualSize;
  423. else
  424. VirtualMemorySizeBytes = 0;
  425. LeaveCriticalSection(&PerfDataCriticalSection);
  426. return VirtualMemorySizeBytes;
  427. }
  428. ULONG PerfDataGetPagedPoolUsagePages(ULONG Index)
  429. {
  430. ULONG PagedPoolUsagePages;
  431. EnterCriticalSection(&PerfDataCriticalSection);
  432. if (Index < ProcessCount)
  433. PagedPoolUsagePages = pPerfData[Index].vmCounters.QuotaPagedPoolUsage;
  434. else
  435. PagedPoolUsagePages = 0;
  436. LeaveCriticalSection(&PerfDataCriticalSection);
  437. return PagedPoolUsagePages;
  438. }
  439. ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index)
  440. {
  441. ULONG NonPagedPoolUsagePages;
  442. EnterCriticalSection(&PerfDataCriticalSection);
  443. if (Index < ProcessCount)
  444. NonPagedPoolUsagePages = pPerfData[Index].vmCounters.QuotaNonPagedPoolUsage;
  445. else
  446. NonPagedPoolUsagePages = 0;
  447. LeaveCriticalSection(&PerfDataCriticalSection);
  448. return NonPagedPoolUsagePages;
  449. }
  450. ULONG PerfDataGetBasePriority(ULONG Index)
  451. {
  452. ULONG BasePriority;
  453. EnterCriticalSection(&PerfDataCriticalSection);
  454. if (Index < ProcessCount)
  455. BasePriority = pPerfData[Index].BasePriority;
  456. else
  457. BasePriority = 0;
  458. LeaveCriticalSection(&PerfDataCriticalSection);
  459. return BasePriority;
  460. }
  461. ULONG PerfDataGetHandleCount(ULONG Index)
  462. {
  463. ULONG HandleCount;
  464. EnterCriticalSection(&PerfDataCriticalSection);
  465. if (Index < ProcessCount)
  466. HandleCount = pPerfData[Index].HandleCount;
  467. else
  468. HandleCount = 0;
  469. LeaveCriticalSection(&PerfDataCriticalSection);
  470. return HandleCount;
  471. }
  472. ULONG PerfDataGetThreadCount(ULONG Index)
  473. {
  474. ULONG ThreadCount;
  475. EnterCriticalSection(&PerfDataCriticalSection);
  476. if (Index < ProcessCount)
  477. ThreadCount = pPerfData[Index].ThreadCount;
  478. else
  479. ThreadCount = 0;
  480. LeaveCriticalSection(&PerfDataCriticalSection);
  481. return ThreadCount;
  482. }
  483. ULONG PerfDataGetUSERObjectCount(ULONG Index)
  484. {
  485. ULONG USERObjectCount;
  486. EnterCriticalSection(&PerfDataCriticalSection);
  487. if (Index < ProcessCount)
  488. USERObjectCount = pPerfData[Index].USERObjectCount;
  489. else
  490. USERObjectCount = 0;
  491. LeaveCriticalSection(&PerfDataCriticalSection);
  492. return USERObjectCount;
  493. }
  494. ULONG PerfDataGetGDIObjectCount(ULONG Index)
  495. {
  496. ULONG GDIObjectCount;
  497. EnterCriticalSection(&PerfDataCriticalSection);
  498. if (Index < ProcessCount)
  499. GDIObjectCount = pPerfData[Index].GDIObjectCount;
  500. else
  501. GDIObjectCount = 0;
  502. LeaveCriticalSection(&PerfDataCriticalSection);
  503. return GDIObjectCount;
  504. }
  505. BOOL PerfDataGetIOCounters(ULONG Index, PIO_COUNTERS pIoCounters)
  506. {
  507. BOOL bSuccessful;
  508. EnterCriticalSection(&PerfDataCriticalSection);
  509. if (Index < ProcessCount)
  510. {
  511. memcpy(pIoCounters, &pPerfData[Index].IOCounters, sizeof(IO_COUNTERS));
  512. bSuccessful = TRUE;
  513. }
  514. else
  515. bSuccessful = FALSE;
  516. LeaveCriticalSection(&PerfDataCriticalSection);
  517. return bSuccessful;
  518. }
  519. ULONG PerfDataGetCommitChargeTotalK(void)
  520. {
  521. ULONG Total;
  522. ULONG PageSize;
  523. EnterCriticalSection(&PerfDataCriticalSection);
  524. Total = SystemPerfInfo.TotalCommittedPages;
  525. PageSize = SystemBasicInfo.PageSize;
  526. LeaveCriticalSection(&PerfDataCriticalSection);
  527. Total = Total * (PageSize / 1024);
  528. return Total;
  529. }
  530. ULONG PerfDataGetCommitChargeLimitK(void)
  531. {
  532. ULONG Limit;
  533. ULONG PageSize;
  534. EnterCriticalSection(&PerfDataCriticalSection);
  535. Limit = SystemPerfInfo.TotalCommitLimit;
  536. PageSize = SystemBasicInfo.PageSize;
  537. LeaveCriticalSection(&PerfDataCriticalSection);
  538. Limit = Limit * (PageSize / 1024);
  539. return Limit;
  540. }
  541. ULONG PerfDataGetCommitChargePeakK(void)
  542. {
  543. ULONG Peak;
  544. ULONG PageSize;
  545. EnterCriticalSection(&PerfDataCriticalSection);
  546. Peak = SystemPerfInfo.PeakCommitment;
  547. PageSize = SystemBasicInfo.PageSize;
  548. LeaveCriticalSection(&PerfDataCriticalSection);
  549. Peak = Peak * (PageSize / 1024);
  550. return Peak;
  551. }
  552. ULONG PerfDataGetKernelMemoryTotalK(void)
  553. {
  554. ULONG Total;
  555. ULONG Paged;
  556. ULONG NonPaged;
  557. ULONG PageSize;
  558. EnterCriticalSection(&PerfDataCriticalSection);
  559. Paged = SystemPerfInfo.PagedPoolUsage;
  560. NonPaged = SystemPerfInfo.NonPagedPoolUsage;
  561. PageSize = SystemBasicInfo.PageSize;
  562. LeaveCriticalSection(&PerfDataCriticalSection);
  563. Paged = Paged * (PageSize / 1024);
  564. NonPaged = NonPaged * (PageSize / 1024);
  565. Total = Paged + NonPaged;
  566. return Total;
  567. }
  568. ULONG PerfDataGetKernelMemoryPagedK(void)
  569. {
  570. ULONG Paged;
  571. ULONG PageSize;
  572. EnterCriticalSection(&PerfDataCriticalSection);
  573. Paged = SystemPerfInfo.PagedPoolUsage;
  574. PageSize = SystemBasicInfo.PageSize;
  575. LeaveCriticalSection(&PerfDataCriticalSection);
  576. Paged = Paged * (PageSize / 1024);
  577. return Paged;
  578. }
  579. ULONG PerfDataGetKernelMemoryNonPagedK(void)
  580. {
  581. ULONG NonPaged;
  582. ULONG PageSize;
  583. EnterCriticalSection(&PerfDataCriticalSection);
  584. NonPaged = SystemPerfInfo.NonPagedPoolUsage;
  585. PageSize = SystemBasicInfo.PageSize;
  586. LeaveCriticalSection(&PerfDataCriticalSection);
  587. NonPaged = NonPaged * (PageSize / 1024);
  588. return NonPaged;
  589. }
  590. ULONG PerfDataGetPhysicalMemoryTotalK(void)
  591. {
  592. ULONG Total;
  593. ULONG PageSize;
  594. EnterCriticalSection(&PerfDataCriticalSection);
  595. Total = SystemBasicInfo.MmNumberOfPhysicalPages;
  596. PageSize = SystemBasicInfo.PageSize;
  597. LeaveCriticalSection(&PerfDataCriticalSection);
  598. Total = Total * (PageSize / 1024);
  599. return Total;
  600. }
  601. ULONG PerfDataGetPhysicalMemoryAvailableK(void)
  602. {
  603. ULONG Available;
  604. ULONG PageSize;
  605. EnterCriticalSection(&PerfDataCriticalSection);
  606. Available = SystemPerfInfo.AvailablePages;
  607. PageSize = SystemBasicInfo.PageSize;
  608. LeaveCriticalSection(&PerfDataCriticalSection);
  609. Available = Available * (PageSize / 1024);
  610. return Available;
  611. }
  612. ULONG PerfDataGetPhysicalMemorySystemCacheK(void)
  613. {
  614. ULONG SystemCache;
  615. EnterCriticalSection(&PerfDataCriticalSection);
  616. SystemCache = SystemCacheInfo.CurrentSize;
  617. LeaveCriticalSection(&PerfDataCriticalSection);
  618. SystemCache = SystemCache / 1024;
  619. return SystemCache;
  620. }
  621. ULONG PerfDataGetSystemHandleCount(void)
  622. {
  623. ULONG HandleCount;
  624. EnterCriticalSection(&PerfDataCriticalSection);
  625. HandleCount = SystemHandleInfo.Count;
  626. LeaveCriticalSection(&PerfDataCriticalSection);
  627. return HandleCount;
  628. }
  629. ULONG PerfDataGetTotalThreadCount(void)
  630. {
  631. ULONG ThreadCount = 0;
  632. ULONG i;
  633. EnterCriticalSection(&PerfDataCriticalSection);
  634. for (i=0; i<ProcessCount; i++)
  635. {
  636. ThreadCount += pPerfData[i].ThreadCount;
  637. }
  638. LeaveCriticalSection(&PerfDataCriticalSection);
  639. return ThreadCount;
  640. }