winemenubuilder: Add a trailing '\n' to a FIXME() call.
[wine/testsucceed.git] / programs / taskmgr / perfdata.c
blob0f3bf145144e0e86d460f1c72570a5979b71912a
1 /*
2 * ReactOS Task Manager
4 * perfdata.c
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
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.
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.
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
23 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
24 #include <windows.h>
25 #include <commctrl.h>
26 #include <stdlib.h>
27 #include <memory.h>
28 #include <tchar.h>
29 #include <stdio.h>
30 #include <winnt.h>
31 #include "taskmgr.h"
32 #include "perfdata.h"
34 static PROCNTQSI NtQuerySystemInformation = NULL;
35 static PROCGGR pGetGuiResources = NULL;
36 static PROCGPIC pGetProcessIoCounters = NULL;
37 static CRITICAL_SECTION PerfDataCriticalSection;
38 static PPERFDATA pPerfDataOld = NULL; /* Older perf data (saved to establish delta values) */
39 static PPERFDATA pPerfData = NULL; /* Most recent copy of perf data */
40 static ULONG ProcessCountOld = 0;
41 static ULONG ProcessCount = 0;
42 static double dbIdleTime;
43 static double dbKernelTime;
44 static double dbSystemTime;
45 static LARGE_INTEGER liOldIdleTime = {{0,0}};
46 static double OldKernelTime = 0;
47 static LARGE_INTEGER liOldSystemTime = {{0,0}};
48 static SYSTEM_PERFORMANCE_INFORMATION SystemPerfInfo;
49 static SYSTEM_BASIC_INFORMATION SystemBasicInfo;
50 static SYSTEM_CACHE_INFORMATION SystemCacheInfo;
51 static SYSTEM_HANDLE_INFORMATION SystemHandleInfo;
52 static PSYSTEM_PROCESSORTIME_INFO SystemProcessorTimeInfo = NULL;
54 BOOL PerfDataInitialize(void)
56 LONG status;
57 static const WCHAR wszNtdll[] = {'n','t','d','l','l','.','d','l','l',0};
58 static const WCHAR wszUser32[] = {'u','s','e','r','3','2','.','d','l','l',0};
59 static const WCHAR wszKernel32[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
61 NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandleW(wszNtdll), "NtQuerySystemInformation");
62 pGetGuiResources = (PROCGGR)GetProcAddress(GetModuleHandleW(wszUser32), "GetGuiResources");
63 pGetProcessIoCounters = (PROCGPIC)GetProcAddress(GetModuleHandleW(wszKernel32), "GetProcessIoCounters");
65 InitializeCriticalSection(&PerfDataCriticalSection);
67 if (!NtQuerySystemInformation)
68 return FALSE;
71 * Get number of processors in the system
73 status = NtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL);
74 if (status != NO_ERROR)
75 return FALSE;
77 return TRUE;
80 void PerfDataUninitialize(void)
82 NtQuerySystemInformation = NULL;
84 DeleteCriticalSection(&PerfDataCriticalSection);
87 void PerfDataRefresh(void)
89 ULONG ulSize;
90 LONG status;
91 LPBYTE pBuffer;
92 ULONG BufferSize;
93 PSYSTEM_PROCESS_INFORMATION pSPI;
94 PPERFDATA pPDOld;
95 ULONG Idx, Idx2;
96 HANDLE hProcess;
97 HANDLE hProcessToken;
98 WCHAR wszTemp[MAX_PATH];
99 DWORD dwSize;
100 SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
101 SYSTEM_TIME_INFORMATION SysTimeInfo;
102 SYSTEM_CACHE_INFORMATION SysCacheInfo;
103 LPBYTE SysHandleInfoData;
104 PSYSTEM_PROCESSORTIME_INFO SysProcessorTimeInfo;
105 double CurrentKernelTime;
108 if (!NtQuerySystemInformation)
109 return;
111 /* Get new system time */
112 status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
113 if (status != NO_ERROR)
114 return;
116 /* Get new CPU's idle time */
117 status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL);
118 if (status != NO_ERROR)
119 return;
121 /* Get system cache information */
122 status = NtQuerySystemInformation(SystemCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL);
123 if (status != NO_ERROR)
124 return;
126 /* Get processor time information */
127 SysProcessorTimeInfo = HeapAlloc(GetProcessHeap(), 0,
128 sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors);
129 status = NtQuerySystemInformation(SystemProcessorTimeInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors, &ulSize);
130 if (status != NO_ERROR) {
131 HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo);
132 return;
135 /* Get handle information
136 * We don't know how much data there is so just keep
137 * increasing the buffer size until the call succeeds
139 BufferSize = 0;
142 BufferSize += 0x10000;
143 SysHandleInfoData = HeapAlloc(GetProcessHeap(), 0, BufferSize);
145 status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize);
147 if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
148 HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
151 } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
153 /* Get process information
154 * We don't know how much data there is so just keep
155 * increasing the buffer size until the call succeeds
157 BufferSize = 0;
160 BufferSize += 0x10000;
161 pBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize);
163 status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);
165 if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
166 HeapFree(GetProcessHeap(), 0, pBuffer);
169 } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
171 EnterCriticalSection(&PerfDataCriticalSection);
174 * Save system performance info
176 memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION));
179 * Save system cache info
181 memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION));
184 * Save system processor time info
186 HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo);
187 SystemProcessorTimeInfo = SysProcessorTimeInfo;
190 * Save system handle info
192 memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION));
193 HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
195 for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.bKeNumberProcessors; Idx++) {
196 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
197 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime);
198 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime);
201 /* If it's a first call - skip idle time calcs */
202 if (liOldIdleTime.QuadPart != 0) {
203 /* CurrentValue = NewValue - OldValue */
204 dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
205 dbKernelTime = CurrentKernelTime - OldKernelTime;
206 dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
208 /* CurrentCpuIdle = IdleTime / SystemTime */
209 dbIdleTime = dbIdleTime / dbSystemTime;
210 dbKernelTime = dbKernelTime / dbSystemTime;
212 /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
213 dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
214 dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
217 /* Store new CPU's idle and system time */
218 liOldIdleTime = SysPerfInfo.liIdleTime;
219 liOldSystemTime = SysTimeInfo.liKeSystemTime;
220 OldKernelTime = CurrentKernelTime;
222 /* Determine the process count
223 * We loop through the data we got from NtQuerySystemInformation
224 * and count how many structures there are (until RelativeOffset is 0)
226 ProcessCountOld = ProcessCount;
227 ProcessCount = 0;
228 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
229 while (pSPI) {
230 ProcessCount++;
231 if (pSPI->RelativeOffset == 0)
232 break;
233 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
236 /* Now alloc a new PERFDATA array and fill in the data */
237 HeapFree(GetProcessHeap(), 0, pPerfDataOld);
238 pPerfDataOld = pPerfData;
239 pPerfData = HeapAlloc(GetProcessHeap(), 0, sizeof(PERFDATA) * ProcessCount);
240 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
241 for (Idx=0; Idx<ProcessCount; Idx++) {
242 /* Get the old perf data for this process (if any) */
243 /* so that we can establish delta values */
244 pPDOld = NULL;
245 for (Idx2=0; Idx2<ProcessCountOld; Idx2++) {
246 if (pPerfDataOld[Idx2].ProcessId == pSPI->ProcessId) {
247 pPDOld = &pPerfDataOld[Idx2];
248 break;
252 /* Clear out process perf data structure */
253 memset(&pPerfData[Idx], 0, sizeof(PERFDATA));
255 if (pSPI->Name.Buffer)
256 lstrcpyW(pPerfData[Idx].ImageName, pSPI->Name.Buffer);
257 else
259 WCHAR idleW[255];
260 LoadStringW(hInst, IDS_SYSTEM_IDLE_PROCESS, idleW, sizeof(idleW)/sizeof(WCHAR));
261 lstrcpyW(pPerfData[Idx].ImageName, idleW );
264 pPerfData[Idx].ProcessId = pSPI->ProcessId;
266 if (pPDOld) {
267 double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
268 double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
269 double CpuTime = (CurTime - OldTime) / dbSystemTime;
270 CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
271 pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
273 pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
274 pPerfData[Idx].WorkingSetSizeBytes = pSPI->TotalWorkingSetSizeBytes;
275 pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSizeBytes;
276 if (pPDOld)
277 pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->TotalWorkingSetSizeBytes - (LONG)pPDOld->WorkingSetSizeBytes);
278 else
279 pPerfData[Idx].WorkingSetSizeDelta = 0;
280 pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount;
281 if (pPDOld)
282 pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount);
283 else
284 pPerfData[Idx].PageFaultCountDelta = 0;
285 pPerfData[Idx].VirtualMemorySizeBytes = pSPI->TotalVirtualSizeBytes;
286 pPerfData[Idx].PagedPoolUsagePages = pSPI->TotalPagedPoolUsagePages;
287 pPerfData[Idx].NonPagedPoolUsagePages = pSPI->TotalNonPagedPoolUsagePages;
288 pPerfData[Idx].BasePriority = pSPI->BasePriority;
289 pPerfData[Idx].HandleCount = pSPI->HandleCount;
290 pPerfData[Idx].ThreadCount = pSPI->ThreadCount;
291 pPerfData[Idx].SessionId = pSPI->SessionId;
293 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pSPI->ProcessId);
294 if (hProcess) {
295 if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
296 ImpersonateLoggedOnUser(hProcessToken);
297 memset(wszTemp, 0, sizeof(wszTemp));
298 dwSize = MAX_PATH;
299 GetUserNameW(wszTemp, &dwSize);
300 RevertToSelf();
301 CloseHandle(hProcessToken);
303 if (pGetGuiResources) {
304 pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS);
305 pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS);
307 if (pGetProcessIoCounters)
308 pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
309 CloseHandle(hProcess);
311 pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
312 pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
313 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
315 HeapFree(GetProcessHeap(), 0, pBuffer);
316 LeaveCriticalSection(&PerfDataCriticalSection);
319 ULONG PerfDataGetProcessCount(void)
321 return ProcessCount;
324 ULONG PerfDataGetProcessorUsage(void)
326 if( dbIdleTime < 0.0 )
327 return 0;
328 if( dbIdleTime > 100.0 )
329 return 100;
330 return (ULONG)dbIdleTime;
333 ULONG PerfDataGetProcessorSystemUsage(void)
335 if( dbKernelTime < 0.0 )
336 return 0;
337 if( dbKernelTime > 100.0 )
338 return 100;
339 return (ULONG)dbKernelTime;
342 BOOL PerfDataGetImageName(ULONG Index, LPWSTR lpImageName, int nMaxCount)
344 BOOL bSuccessful;
346 EnterCriticalSection(&PerfDataCriticalSection);
348 if (Index < ProcessCount) {
349 wcsncpy(lpImageName, pPerfData[Index].ImageName, nMaxCount);
350 bSuccessful = TRUE;
351 } else {
352 bSuccessful = FALSE;
354 LeaveCriticalSection(&PerfDataCriticalSection);
355 return bSuccessful;
358 ULONG PerfDataGetProcessId(ULONG Index)
360 ULONG ProcessId;
362 EnterCriticalSection(&PerfDataCriticalSection);
364 if (Index < ProcessCount)
365 ProcessId = pPerfData[Index].ProcessId;
366 else
367 ProcessId = 0;
369 LeaveCriticalSection(&PerfDataCriticalSection);
371 return ProcessId;
374 BOOL PerfDataGetUserName(ULONG Index, LPWSTR lpUserName, int nMaxCount)
376 BOOL bSuccessful;
378 EnterCriticalSection(&PerfDataCriticalSection);
380 if (Index < ProcessCount) {
381 wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount);
382 bSuccessful = TRUE;
383 } else {
384 bSuccessful = FALSE;
387 LeaveCriticalSection(&PerfDataCriticalSection);
389 return bSuccessful;
392 ULONG PerfDataGetSessionId(ULONG Index)
394 ULONG SessionId;
396 EnterCriticalSection(&PerfDataCriticalSection);
398 if (Index < ProcessCount)
399 SessionId = pPerfData[Index].SessionId;
400 else
401 SessionId = 0;
403 LeaveCriticalSection(&PerfDataCriticalSection);
405 return SessionId;
408 ULONG PerfDataGetCPUUsage(ULONG Index)
410 ULONG CpuUsage;
412 EnterCriticalSection(&PerfDataCriticalSection);
414 if (Index < ProcessCount)
415 CpuUsage = pPerfData[Index].CPUUsage;
416 else
417 CpuUsage = 0;
419 LeaveCriticalSection(&PerfDataCriticalSection);
421 return CpuUsage;
424 TIME PerfDataGetCPUTime(ULONG Index)
426 TIME CpuTime = {{0,0}};
428 EnterCriticalSection(&PerfDataCriticalSection);
430 if (Index < ProcessCount)
431 CpuTime = pPerfData[Index].CPUTime;
433 LeaveCriticalSection(&PerfDataCriticalSection);
435 return CpuTime;
438 ULONG PerfDataGetWorkingSetSizeBytes(ULONG Index)
440 ULONG WorkingSetSizeBytes;
442 EnterCriticalSection(&PerfDataCriticalSection);
444 if (Index < ProcessCount)
445 WorkingSetSizeBytes = pPerfData[Index].WorkingSetSizeBytes;
446 else
447 WorkingSetSizeBytes = 0;
449 LeaveCriticalSection(&PerfDataCriticalSection);
451 return WorkingSetSizeBytes;
454 ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index)
456 ULONG PeakWorkingSetSizeBytes;
458 EnterCriticalSection(&PerfDataCriticalSection);
460 if (Index < ProcessCount)
461 PeakWorkingSetSizeBytes = pPerfData[Index].PeakWorkingSetSizeBytes;
462 else
463 PeakWorkingSetSizeBytes = 0;
465 LeaveCriticalSection(&PerfDataCriticalSection);
467 return PeakWorkingSetSizeBytes;
470 ULONG PerfDataGetWorkingSetSizeDelta(ULONG Index)
472 ULONG WorkingSetSizeDelta;
474 EnterCriticalSection(&PerfDataCriticalSection);
476 if (Index < ProcessCount)
477 WorkingSetSizeDelta = pPerfData[Index].WorkingSetSizeDelta;
478 else
479 WorkingSetSizeDelta = 0;
481 LeaveCriticalSection(&PerfDataCriticalSection);
483 return WorkingSetSizeDelta;
486 ULONG PerfDataGetPageFaultCount(ULONG Index)
488 ULONG PageFaultCount;
490 EnterCriticalSection(&PerfDataCriticalSection);
492 if (Index < ProcessCount)
493 PageFaultCount = pPerfData[Index].PageFaultCount;
494 else
495 PageFaultCount = 0;
497 LeaveCriticalSection(&PerfDataCriticalSection);
499 return PageFaultCount;
502 ULONG PerfDataGetPageFaultCountDelta(ULONG Index)
504 ULONG PageFaultCountDelta;
506 EnterCriticalSection(&PerfDataCriticalSection);
508 if (Index < ProcessCount)
509 PageFaultCountDelta = pPerfData[Index].PageFaultCountDelta;
510 else
511 PageFaultCountDelta = 0;
513 LeaveCriticalSection(&PerfDataCriticalSection);
515 return PageFaultCountDelta;
518 ULONG PerfDataGetVirtualMemorySizeBytes(ULONG Index)
520 ULONG VirtualMemorySizeBytes;
522 EnterCriticalSection(&PerfDataCriticalSection);
524 if (Index < ProcessCount)
525 VirtualMemorySizeBytes = pPerfData[Index].VirtualMemorySizeBytes;
526 else
527 VirtualMemorySizeBytes = 0;
529 LeaveCriticalSection(&PerfDataCriticalSection);
531 return VirtualMemorySizeBytes;
534 ULONG PerfDataGetPagedPoolUsagePages(ULONG Index)
536 ULONG PagedPoolUsagePages;
538 EnterCriticalSection(&PerfDataCriticalSection);
540 if (Index < ProcessCount)
541 PagedPoolUsagePages = pPerfData[Index].PagedPoolUsagePages;
542 else
543 PagedPoolUsagePages = 0;
545 LeaveCriticalSection(&PerfDataCriticalSection);
547 return PagedPoolUsagePages;
550 ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index)
552 ULONG NonPagedPoolUsagePages;
554 EnterCriticalSection(&PerfDataCriticalSection);
556 if (Index < ProcessCount)
557 NonPagedPoolUsagePages = pPerfData[Index].NonPagedPoolUsagePages;
558 else
559 NonPagedPoolUsagePages = 0;
561 LeaveCriticalSection(&PerfDataCriticalSection);
563 return NonPagedPoolUsagePages;
566 ULONG PerfDataGetBasePriority(ULONG Index)
568 ULONG BasePriority;
570 EnterCriticalSection(&PerfDataCriticalSection);
572 if (Index < ProcessCount)
573 BasePriority = pPerfData[Index].BasePriority;
574 else
575 BasePriority = 0;
577 LeaveCriticalSection(&PerfDataCriticalSection);
579 return BasePriority;
582 ULONG PerfDataGetHandleCount(ULONG Index)
584 ULONG HandleCount;
586 EnterCriticalSection(&PerfDataCriticalSection);
588 if (Index < ProcessCount)
589 HandleCount = pPerfData[Index].HandleCount;
590 else
591 HandleCount = 0;
593 LeaveCriticalSection(&PerfDataCriticalSection);
595 return HandleCount;
598 ULONG PerfDataGetThreadCount(ULONG Index)
600 ULONG ThreadCount;
602 EnterCriticalSection(&PerfDataCriticalSection);
604 if (Index < ProcessCount)
605 ThreadCount = pPerfData[Index].ThreadCount;
606 else
607 ThreadCount = 0;
609 LeaveCriticalSection(&PerfDataCriticalSection);
611 return ThreadCount;
614 ULONG PerfDataGetUSERObjectCount(ULONG Index)
616 ULONG USERObjectCount;
618 EnterCriticalSection(&PerfDataCriticalSection);
620 if (Index < ProcessCount)
621 USERObjectCount = pPerfData[Index].USERObjectCount;
622 else
623 USERObjectCount = 0;
625 LeaveCriticalSection(&PerfDataCriticalSection);
627 return USERObjectCount;
630 ULONG PerfDataGetGDIObjectCount(ULONG Index)
632 ULONG GDIObjectCount;
634 EnterCriticalSection(&PerfDataCriticalSection);
636 if (Index < ProcessCount)
637 GDIObjectCount = pPerfData[Index].GDIObjectCount;
638 else
639 GDIObjectCount = 0;
641 LeaveCriticalSection(&PerfDataCriticalSection);
643 return GDIObjectCount;
646 BOOL PerfDataGetIOCounters(ULONG Index, PIO_COUNTERS pIoCounters)
648 BOOL bSuccessful;
650 EnterCriticalSection(&PerfDataCriticalSection);
652 if (Index < ProcessCount)
654 memcpy(pIoCounters, &pPerfData[Index].IOCounters, sizeof(IO_COUNTERS));
655 bSuccessful = TRUE;
657 else
658 bSuccessful = FALSE;
660 LeaveCriticalSection(&PerfDataCriticalSection);
662 return bSuccessful;
665 ULONG PerfDataGetCommitChargeTotalK(void)
667 ULONG Total;
668 ULONG PageSize;
670 EnterCriticalSection(&PerfDataCriticalSection);
672 Total = SystemPerfInfo.MmTotalCommittedPages;
673 PageSize = SystemBasicInfo.uPageSize;
675 LeaveCriticalSection(&PerfDataCriticalSection);
677 Total = Total * (PageSize / 1024);
679 return Total;
682 ULONG PerfDataGetCommitChargeLimitK(void)
684 ULONG Limit;
685 ULONG PageSize;
687 EnterCriticalSection(&PerfDataCriticalSection);
689 Limit = SystemPerfInfo.MmTotalCommitLimit;
690 PageSize = SystemBasicInfo.uPageSize;
692 LeaveCriticalSection(&PerfDataCriticalSection);
694 Limit = Limit * (PageSize / 1024);
696 return Limit;
699 ULONG PerfDataGetCommitChargePeakK(void)
701 ULONG Peak;
702 ULONG PageSize;
704 EnterCriticalSection(&PerfDataCriticalSection);
706 Peak = SystemPerfInfo.MmPeakLimit;
707 PageSize = SystemBasicInfo.uPageSize;
709 LeaveCriticalSection(&PerfDataCriticalSection);
711 Peak = Peak * (PageSize / 1024);
713 return Peak;
716 ULONG PerfDataGetKernelMemoryTotalK(void)
718 ULONG Total;
719 ULONG Paged;
720 ULONG NonPaged;
721 ULONG PageSize;
723 EnterCriticalSection(&PerfDataCriticalSection);
725 Paged = SystemPerfInfo.PoolPagedBytes;
726 NonPaged = SystemPerfInfo.PoolNonPagedBytes;
727 PageSize = SystemBasicInfo.uPageSize;
729 LeaveCriticalSection(&PerfDataCriticalSection);
731 Paged = Paged * (PageSize / 1024);
732 NonPaged = NonPaged * (PageSize / 1024);
734 Total = Paged + NonPaged;
736 return Total;
739 ULONG PerfDataGetKernelMemoryPagedK(void)
741 ULONG Paged;
742 ULONG PageSize;
744 EnterCriticalSection(&PerfDataCriticalSection);
746 Paged = SystemPerfInfo.PoolPagedBytes;
747 PageSize = SystemBasicInfo.uPageSize;
749 LeaveCriticalSection(&PerfDataCriticalSection);
751 Paged = Paged * (PageSize / 1024);
753 return Paged;
756 ULONG PerfDataGetKernelMemoryNonPagedK(void)
758 ULONG NonPaged;
759 ULONG PageSize;
761 EnterCriticalSection(&PerfDataCriticalSection);
763 NonPaged = SystemPerfInfo.PoolNonPagedBytes;
764 PageSize = SystemBasicInfo.uPageSize;
766 LeaveCriticalSection(&PerfDataCriticalSection);
768 NonPaged = NonPaged * (PageSize / 1024);
770 return NonPaged;
773 ULONG PerfDataGetPhysicalMemoryTotalK(void)
775 ULONG Total;
776 ULONG PageSize;
778 EnterCriticalSection(&PerfDataCriticalSection);
780 Total = SystemBasicInfo.uMmNumberOfPhysicalPages;
781 PageSize = SystemBasicInfo.uPageSize;
783 LeaveCriticalSection(&PerfDataCriticalSection);
785 Total = Total * (PageSize / 1024);
787 return Total;
790 ULONG PerfDataGetPhysicalMemoryAvailableK(void)
792 ULONG Available;
793 ULONG PageSize;
795 EnterCriticalSection(&PerfDataCriticalSection);
797 Available = SystemPerfInfo.MmAvailablePages;
798 PageSize = SystemBasicInfo.uPageSize;
800 LeaveCriticalSection(&PerfDataCriticalSection);
802 Available = Available * (PageSize / 1024);
804 return Available;
807 ULONG PerfDataGetPhysicalMemorySystemCacheK(void)
809 ULONG SystemCache;
811 EnterCriticalSection(&PerfDataCriticalSection);
813 SystemCache = SystemCacheInfo.CurrentSize;
815 LeaveCriticalSection(&PerfDataCriticalSection);
817 SystemCache = SystemCache / 1024;
819 return SystemCache;
822 ULONG PerfDataGetSystemHandleCount(void)
824 ULONG HandleCount;
826 EnterCriticalSection(&PerfDataCriticalSection);
828 HandleCount = SystemHandleInfo.Count;
830 LeaveCriticalSection(&PerfDataCriticalSection);
832 return HandleCount;
835 ULONG PerfDataGetTotalThreadCount(void)
837 ULONG ThreadCount = 0;
838 ULONG i;
840 EnterCriticalSection(&PerfDataCriticalSection);
842 for (i=0; i<ProcessCount; i++)
844 ThreadCount += pPerfData[i].ThreadCount;
847 LeaveCriticalSection(&PerfDataCriticalSection);
849 return ThreadCount;