Sync'ing remaining changes after recent CVS problems. Seem to now have my route back!
[reactos.git] / rosapps / taskmgr / perfdata.c
1 /*
2 * ReactOS Task Manager
3 *
4 * perfdata.cpp
5 *
6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program 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
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
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 <malloc.h>
28 #include <memory.h>
29 #include <tchar.h>
30 #include <process.h>
31 #include <stdio.h>
32
33 #include "taskmgr.h"
34 #include "perfdata.h"
35
36 PROCNTQSI NtQuerySystemInformation = NULL;
37 PROCGGR pGetGuiResources = NULL;
38 PROCGPIC pGetProcessIoCounters = NULL;
39 CRITICAL_SECTION PerfDataCriticalSection;
40 PPERFDATA pPerfDataOld = NULL; // Older perf data (saved to establish delta values)
41 PPERFDATA pPerfData = NULL; // Most recent copy of perf data
42 ULONG ProcessCountOld = 0;
43 ULONG ProcessCount = 0;
44 double dbIdleTime;
45 double dbKernelTime;
46 double dbSystemTime;
47 LARGE_INTEGER liOldIdleTime = {{0,0}};
48 double OldKernelTime = 0;
49 LARGE_INTEGER liOldSystemTime = {{0,0}};
50 SYSTEM_PERFORMANCE_INFORMATION SystemPerfInfo;
51 SYSTEM_BASIC_INFORMATION SystemBasicInfo;
52 SYSTEM_CACHE_INFORMATION SystemCacheInfo;
53 SYSTEM_HANDLE_INFORMATION SystemHandleInfo;
54 PSYSTEM_PROCESSORTIME_INFO SystemProcessorTimeInfo = NULL;
55
56 BOOL PerfDataInitialize(void)
57 {
58 LONG status;
59
60 NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQuerySystemInformation");
61 pGetGuiResources = (PROCGGR)GetProcAddress(GetModuleHandle(_T("user32.dll")), "GetGuiResources");
62 pGetProcessIoCounters = (PROCGPIC)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "GetProcessIoCounters");
63
64 InitializeCriticalSection(&PerfDataCriticalSection);
65
66 if (!NtQuerySystemInformation)
67 return FALSE;
68
69 //
70 // Get number of processors in the system
71 //
72 status = NtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL);
73 if (status != NO_ERROR)
74 return FALSE;
75
76 return TRUE;
77 }
78
79 void PerfDataUninitialize(void)
80 {
81 NtQuerySystemInformation = NULL;
82
83 DeleteCriticalSection(&PerfDataCriticalSection);
84 }
85
86 void PerfDataRefresh(void)
87 {
88 ULONG ulSize;
89 LONG status;
90 LPBYTE pBuffer;
91 ULONG BufferSize;
92 PSYSTEM_PROCESS_INFORMATION pSPI;
93 PPERFDATA pPDOld;
94 ULONG Idx, Idx2;
95 HANDLE hProcess;
96 HANDLE hProcessToken;
97 TCHAR szTemp[MAX_PATH];
98 DWORD dwSize;
99 SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
100 SYSTEM_TIME_INFORMATION SysTimeInfo;
101 SYSTEM_CACHE_INFORMATION SysCacheInfo;
102 LPBYTE SysHandleInfoData;
103 PSYSTEM_PROCESSORTIME_INFO SysProcessorTimeInfo;
104 double CurrentKernelTime;
105
106
107 if (!NtQuerySystemInformation)
108 return;
109
110 // Get new system time
111 status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
112 if (status != NO_ERROR)
113 return;
114
115 // Get new CPU's idle time
116 status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL);
117 if (status != NO_ERROR)
118 return;
119
120 // Get system cache information
121 status = NtQuerySystemInformation(SystemCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL);
122 if (status != NO_ERROR)
123 return;
124
125 // Get processor time information
126 //SysProcessorTimeInfo = new SYSTEM_PROCESSORTIME_INFO[SystemBasicInfo.bKeNumberProcessors];
127 SysProcessorTimeInfo = (PSYSTEM_PROCESSORTIME_INFO)malloc(sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors);
128 status = NtQuerySystemInformation(SystemProcessorTimeInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors, &ulSize);
129 if (status != NO_ERROR)
130 return;
131
132 // Get handle information
133 // We don't know how much data there is so just keep
134 // increasing the buffer size until the call succeeds
135 BufferSize = 0;
136 do
137 {
138 BufferSize += 0x10000;
139 //SysHandleInfoData = new BYTE[BufferSize];
140 SysHandleInfoData = (LPBYTE)malloc(BufferSize);
141
142 status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize);
143
144 if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
145 //delete[] SysHandleInfoData;
146 free(SysHandleInfoData);
147 }
148
149 } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
150
151 // Get process information
152 // We don't know how much data there is so just keep
153 // increasing the buffer size until the call succeeds
154 BufferSize = 0;
155 do
156 {
157 BufferSize += 0x10000;
158 //pBuffer = new BYTE[BufferSize];
159 pBuffer = (LPBYTE)malloc(BufferSize);
160
161 status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);
162
163 if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
164 //delete[] pBuffer;
165 free(pBuffer);
166 }
167
168 } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
169
170 EnterCriticalSection(&PerfDataCriticalSection);
171
172 //
173 // Save system performance info
174 //
175 memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION));
176
177 //
178 // Save system cache info
179 //
180 memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION));
181
182 //
183 // Save system processor time info
184 //
185 if (SystemProcessorTimeInfo) {
186 //delete[] SystemProcessorTimeInfo;
187 free(SystemProcessorTimeInfo);
188 }
189 SystemProcessorTimeInfo = SysProcessorTimeInfo;
190
191 //
192 // Save system handle info
193 //
194 memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION));
195 //delete[] SysHandleInfoData;
196 free(SysHandleInfoData);
197
198 for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.bKeNumberProcessors; Idx++) {
199 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
200 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime);
201 CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime);
202 }
203
204 // If it's a first call - skip idle time calcs
205 if (liOldIdleTime.QuadPart != 0) {
206 // CurrentValue = NewValue - OldValue
207 dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
208 dbKernelTime = CurrentKernelTime - OldKernelTime;
209 dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
210
211 // CurrentCpuIdle = IdleTime / SystemTime
212 dbIdleTime = dbIdleTime / dbSystemTime;
213 dbKernelTime = dbKernelTime / dbSystemTime;
214
215 // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
216 dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors;// + 0.5;
217 dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors;// + 0.5;
218 }
219
220 // Store new CPU's idle and system time
221 liOldIdleTime = SysPerfInfo.liIdleTime;
222 liOldSystemTime = SysTimeInfo.liKeSystemTime;
223 OldKernelTime = CurrentKernelTime;
224
225 // Determine the process count
226 // We loop through the data we got from NtQuerySystemInformation
227 // and count how many structures there are (until RelativeOffset is 0)
228 ProcessCountOld = ProcessCount;
229 ProcessCount = 0;
230 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
231 while (pSPI) {
232 ProcessCount++;
233 if (pSPI->RelativeOffset == 0)
234 break;
235 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
236 }
237
238 // Now alloc a new PERFDATA array and fill in the data
239 if (pPerfDataOld) {
240 //delete[] pPerfDataOld;
241 free(pPerfDataOld);
242 }
243 pPerfDataOld = pPerfData;
244 //pPerfData = new PERFDATA[ProcessCount];
245 pPerfData = (PPERFDATA)malloc(sizeof(PERFDATA) * ProcessCount);
246 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
247 for (Idx=0; Idx<ProcessCount; Idx++) {
248 // Get the old perf data for this process (if any)
249 // so that we can establish delta values
250 pPDOld = NULL;
251 for (Idx2=0; Idx2<ProcessCountOld; Idx2++) {
252 if (pPerfDataOld[Idx2].ProcessId == pSPI->ProcessId) {
253 pPDOld = &pPerfDataOld[Idx2];
254 break;
255 }
256 }
257
258 // Clear out process perf data structure
259 memset(&pPerfData[Idx], 0, sizeof(PERFDATA));
260
261 if (pSPI->Name.Buffer)
262 wcscpy(pPerfData[Idx].ImageName, pSPI->Name.Buffer);
263 else
264 wcscpy(pPerfData[Idx].ImageName, L"System Idle Process");
265
266 pPerfData[Idx].ProcessId = pSPI->ProcessId;
267
268 if (pPDOld) {
269 double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
270 double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
271 double CpuTime = (CurTime - OldTime) / dbSystemTime;
272 CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors;// + 0.5;
273 pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
274 }
275 pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
276 pPerfData[Idx].WorkingSetSizeBytes = pSPI->TotalWorkingSetSizeBytes;
277 pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSizeBytes;
278 if (pPDOld)
279 pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->TotalWorkingSetSizeBytes - (LONG)pPDOld->WorkingSetSizeBytes);
280 else
281 pPerfData[Idx].WorkingSetSizeDelta = 0;
282 pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount;
283 if (pPDOld)
284 pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount);
285 else
286 pPerfData[Idx].PageFaultCountDelta = 0;
287 pPerfData[Idx].VirtualMemorySizeBytes = pSPI->TotalVirtualSizeBytes;
288 pPerfData[Idx].PagedPoolUsagePages = pSPI->TotalPagedPoolUsagePages;
289 pPerfData[Idx].NonPagedPoolUsagePages = pSPI->TotalNonPagedPoolUsagePages;
290 pPerfData[Idx].BasePriority = pSPI->BasePriority;
291 pPerfData[Idx].HandleCount = pSPI->HandleCount;
292 pPerfData[Idx].ThreadCount = pSPI->ThreadCount;
293 pPerfData[Idx].SessionId = pSPI->SessionId;
294
295 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pSPI->ProcessId);
296 if (hProcess) {
297 if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
298 ImpersonateLoggedOnUser(hProcessToken);
299 memset(szTemp, 0, sizeof(TCHAR[MAX_PATH]));
300 dwSize = MAX_PATH;
301 GetUserName(szTemp, &dwSize);
302 #ifndef UNICODE
303 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH);
304 /*
305 int MultiByteToWideChar(
306 UINT CodePage, // code page
307 DWORD dwFlags, // character-type options
308 LPCSTR lpMultiByteStr, // string to map
309 int cbMultiByte, // number of bytes in string
310 LPWSTR lpWideCharStr, // wide-character buffer
311 int cchWideChar // size of buffer
312 );
313 */
314 #endif
315 RevertToSelf();
316 CloseHandle(hProcessToken);
317 }
318 if (pGetGuiResources) {
319 pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS);
320 pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS);
321 }
322 if (pGetProcessIoCounters)
323 pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
324 CloseHandle(hProcess);
325 }
326 pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
327 pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
328 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
329 }
330 //delete[] pBuffer;
331 free(pBuffer);
332 LeaveCriticalSection(&PerfDataCriticalSection);
333 }
334
335 ULONG PerfDataGetProcessCount(void)
336 {
337 return ProcessCount;
338 }
339
340 ULONG PerfDataGetProcessorUsage(void)
341 {
342 return (ULONG)dbIdleTime;
343 }
344
345 ULONG PerfDataGetProcessorSystemUsage(void)
346 {
347 return (ULONG)dbKernelTime;
348 }
349
350 BOOL PerfDataGetImageName(ULONG Index, LPTSTR lpImageName, int nMaxCount)
351 {
352 BOOL bSuccessful;
353
354 EnterCriticalSection(&PerfDataCriticalSection);
355
356 if (Index < ProcessCount) {
357 #ifdef _UNICODE
358 wcsncpy(lpImageName, pPerfData[Index].ImageName, nMaxCount);
359 #else
360 WideCharToMultiByte(CP_ACP, 0, pPerfData[Index].ImageName, -1, lpImageName, nMaxCount, NULL, NULL);
361 #endif
362
363 bSuccessful = TRUE;
364 } else {
365 bSuccessful = FALSE;
366 }
367 LeaveCriticalSection(&PerfDataCriticalSection);
368 return bSuccessful;
369 }
370
371 ULONG PerfDataGetProcessId(ULONG Index)
372 {
373 ULONG ProcessId;
374
375 EnterCriticalSection(&PerfDataCriticalSection);
376
377 if (Index < ProcessCount)
378 ProcessId = pPerfData[Index].ProcessId;
379 else
380 ProcessId = 0;
381
382 LeaveCriticalSection(&PerfDataCriticalSection);
383
384 return ProcessId;
385 }
386
387 BOOL PerfDataGetUserName(ULONG Index, LPTSTR lpUserName, int nMaxCount)
388 {
389 BOOL bSuccessful;
390
391 EnterCriticalSection(&PerfDataCriticalSection);
392
393 if (Index < ProcessCount) {
394 #ifdef _UNICODE
395 wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount);
396 #else
397 WideCharToMultiByte(CP_ACP, 0, pPerfData[Index].UserName, -1, lpUserName, nMaxCount, NULL, NULL);
398 #endif
399
400 bSuccessful = TRUE;
401 } else {
402 bSuccessful = FALSE;
403 }
404
405 LeaveCriticalSection(&PerfDataCriticalSection);
406
407 return bSuccessful;
408 }
409
410 ULONG PerfDataGetSessionId(ULONG Index)
411 {
412 ULONG SessionId;
413
414 EnterCriticalSection(&PerfDataCriticalSection);
415
416 if (Index < ProcessCount)
417 SessionId = pPerfData[Index].SessionId;
418 else
419 SessionId = 0;
420
421 LeaveCriticalSection(&PerfDataCriticalSection);
422
423 return SessionId;
424 }
425
426 ULONG PerfDataGetCPUUsage(ULONG Index)
427 {
428 ULONG CpuUsage;
429
430 EnterCriticalSection(&PerfDataCriticalSection);
431
432 if (Index < ProcessCount)
433 CpuUsage = pPerfData[Index].CPUUsage;
434 else
435 CpuUsage = 0;
436
437 LeaveCriticalSection(&PerfDataCriticalSection);
438
439 return CpuUsage;
440 }
441
442 TIME PerfDataGetCPUTime(ULONG Index)
443 {
444 TIME CpuTime = {{0,0}};
445
446 EnterCriticalSection(&PerfDataCriticalSection);
447
448 if (Index < ProcessCount)
449 CpuTime = pPerfData[Index].CPUTime;
450
451 LeaveCriticalSection(&PerfDataCriticalSection);
452
453 return CpuTime;
454 }
455
456 ULONG PerfDataGetWorkingSetSizeBytes(ULONG Index)
457 {
458 ULONG WorkingSetSizeBytes;
459
460 EnterCriticalSection(&PerfDataCriticalSection);
461
462 if (Index < ProcessCount)
463 WorkingSetSizeBytes = pPerfData[Index].WorkingSetSizeBytes;
464 else
465 WorkingSetSizeBytes = 0;
466
467 LeaveCriticalSection(&PerfDataCriticalSection);
468
469 return WorkingSetSizeBytes;
470 }
471
472 ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index)
473 {
474 ULONG PeakWorkingSetSizeBytes;
475
476 EnterCriticalSection(&PerfDataCriticalSection);
477
478 if (Index < ProcessCount)
479 PeakWorkingSetSizeBytes = pPerfData[Index].PeakWorkingSetSizeBytes;
480 else
481 PeakWorkingSetSizeBytes = 0;
482
483 LeaveCriticalSection(&PerfDataCriticalSection);
484
485 return PeakWorkingSetSizeBytes;
486 }
487
488 ULONG PerfDataGetWorkingSetSizeDelta(ULONG Index)
489 {
490 ULONG WorkingSetSizeDelta;
491
492 EnterCriticalSection(&PerfDataCriticalSection);
493
494 if (Index < ProcessCount)
495 WorkingSetSizeDelta = pPerfData[Index].WorkingSetSizeDelta;
496 else
497 WorkingSetSizeDelta = 0;
498
499 LeaveCriticalSection(&PerfDataCriticalSection);
500
501 return WorkingSetSizeDelta;
502 }
503
504 ULONG PerfDataGetPageFaultCount(ULONG Index)
505 {
506 ULONG PageFaultCount;
507
508 EnterCriticalSection(&PerfDataCriticalSection);
509
510 if (Index < ProcessCount)
511 PageFaultCount = pPerfData[Index].PageFaultCount;
512 else
513 PageFaultCount = 0;
514
515 LeaveCriticalSection(&PerfDataCriticalSection);
516
517 return PageFaultCount;
518 }
519
520 ULONG PerfDataGetPageFaultCountDelta(ULONG Index)
521 {
522 ULONG PageFaultCountDelta;
523
524 EnterCriticalSection(&PerfDataCriticalSection);
525
526 if (Index < ProcessCount)
527 PageFaultCountDelta = pPerfData[Index].PageFaultCountDelta;
528 else
529 PageFaultCountDelta = 0;
530
531 LeaveCriticalSection(&PerfDataCriticalSection);
532
533 return PageFaultCountDelta;
534 }
535
536 ULONG PerfDataGetVirtualMemorySizeBytes(ULONG Index)
537 {
538 ULONG VirtualMemorySizeBytes;
539
540 EnterCriticalSection(&PerfDataCriticalSection);
541
542 if (Index < ProcessCount)
543 VirtualMemorySizeBytes = pPerfData[Index].VirtualMemorySizeBytes;
544 else
545 VirtualMemorySizeBytes = 0;
546
547 LeaveCriticalSection(&PerfDataCriticalSection);
548
549 return VirtualMemorySizeBytes;
550 }
551
552 ULONG PerfDataGetPagedPoolUsagePages(ULONG Index)
553 {
554 ULONG PagedPoolUsagePages;
555
556 EnterCriticalSection(&PerfDataCriticalSection);
557
558 if (Index < ProcessCount)
559 PagedPoolUsagePages = pPerfData[Index].PagedPoolUsagePages;
560 else
561 PagedPoolUsagePages = 0;
562
563 LeaveCriticalSection(&PerfDataCriticalSection);
564
565 return PagedPoolUsagePages;
566 }
567
568 ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index)
569 {
570 ULONG NonPagedPoolUsagePages;
571
572 EnterCriticalSection(&PerfDataCriticalSection);
573
574 if (Index < ProcessCount)
575 NonPagedPoolUsagePages = pPerfData[Index].NonPagedPoolUsagePages;
576 else
577 NonPagedPoolUsagePages = 0;
578
579 LeaveCriticalSection(&PerfDataCriticalSection);
580
581 return NonPagedPoolUsagePages;
582 }
583
584 ULONG PerfDataGetBasePriority(ULONG Index)
585 {
586 ULONG BasePriority;
587
588 EnterCriticalSection(&PerfDataCriticalSection);
589
590 if (Index < ProcessCount)
591 BasePriority = pPerfData[Index].BasePriority;
592 else
593 BasePriority = 0;
594
595 LeaveCriticalSection(&PerfDataCriticalSection);
596
597 return BasePriority;
598 }
599
600 ULONG PerfDataGetHandleCount(ULONG Index)
601 {
602 ULONG HandleCount;
603
604 EnterCriticalSection(&PerfDataCriticalSection);
605
606 if (Index < ProcessCount)
607 HandleCount = pPerfData[Index].HandleCount;
608 else
609 HandleCount = 0;
610
611 LeaveCriticalSection(&PerfDataCriticalSection);
612
613 return HandleCount;
614 }
615
616 ULONG PerfDataGetThreadCount(ULONG Index)
617 {
618 ULONG ThreadCount;
619
620 EnterCriticalSection(&PerfDataCriticalSection);
621
622 if (Index < ProcessCount)
623 ThreadCount = pPerfData[Index].ThreadCount;
624 else
625 ThreadCount = 0;
626
627 LeaveCriticalSection(&PerfDataCriticalSection);
628
629 return ThreadCount;
630 }
631
632 ULONG PerfDataGetUSERObjectCount(ULONG Index)
633 {
634 ULONG USERObjectCount;
635
636 EnterCriticalSection(&PerfDataCriticalSection);
637
638 if (Index < ProcessCount)
639 USERObjectCount = pPerfData[Index].USERObjectCount;
640 else
641 USERObjectCount = 0;
642
643 LeaveCriticalSection(&PerfDataCriticalSection);
644
645 return USERObjectCount;
646 }
647
648 ULONG PerfDataGetGDIObjectCount(ULONG Index)
649 {
650 ULONG GDIObjectCount;
651
652 EnterCriticalSection(&PerfDataCriticalSection);
653
654 if (Index < ProcessCount)
655 GDIObjectCount = pPerfData[Index].GDIObjectCount;
656 else
657 GDIObjectCount = 0;
658
659 LeaveCriticalSection(&PerfDataCriticalSection);
660
661 return GDIObjectCount;
662 }
663
664 BOOL PerfDataGetIOCounters(ULONG Index, PIO_COUNTERS pIoCounters)
665 {
666 BOOL bSuccessful;
667
668 EnterCriticalSection(&PerfDataCriticalSection);
669
670 if (Index < ProcessCount)
671 {
672 memcpy(pIoCounters, &pPerfData[Index].IOCounters, sizeof(IO_COUNTERS));
673 bSuccessful = TRUE;
674 }
675 else
676 bSuccessful = FALSE;
677
678 LeaveCriticalSection(&PerfDataCriticalSection);
679
680 return bSuccessful;
681 }
682
683 ULONG PerfDataGetCommitChargeTotalK(void)
684 {
685 ULONG Total;
686 ULONG PageSize;
687
688 EnterCriticalSection(&PerfDataCriticalSection);
689
690 Total = SystemPerfInfo.MmTotalCommitedPages;
691 PageSize = SystemBasicInfo.uPageSize;
692
693 LeaveCriticalSection(&PerfDataCriticalSection);
694
695 Total = Total * (PageSize / 1024);
696
697 return Total;
698 }
699
700 ULONG PerfDataGetCommitChargeLimitK(void)
701 {
702 ULONG Limit;
703 ULONG PageSize;
704
705 EnterCriticalSection(&PerfDataCriticalSection);
706
707 Limit = SystemPerfInfo.MmTotalCommitLimit;
708 PageSize = SystemBasicInfo.uPageSize;
709
710 LeaveCriticalSection(&PerfDataCriticalSection);
711
712 Limit = Limit * (PageSize / 1024);
713
714 return Limit;
715 }
716
717 ULONG PerfDataGetCommitChargePeakK(void)
718 {
719 ULONG Peak;
720 ULONG PageSize;
721
722 EnterCriticalSection(&PerfDataCriticalSection);
723
724 Peak = SystemPerfInfo.MmPeakLimit;
725 PageSize = SystemBasicInfo.uPageSize;
726
727 LeaveCriticalSection(&PerfDataCriticalSection);
728
729 Peak = Peak * (PageSize / 1024);
730
731 return Peak;
732 }
733
734 ULONG PerfDataGetKernelMemoryTotalK(void)
735 {
736 ULONG Total;
737 ULONG Paged;
738 ULONG NonPaged;
739 ULONG PageSize;
740
741 EnterCriticalSection(&PerfDataCriticalSection);
742
743 Paged = SystemPerfInfo.PoolPagedBytes;
744 NonPaged = SystemPerfInfo.PoolNonPagedBytes;
745 PageSize = SystemBasicInfo.uPageSize;
746
747 LeaveCriticalSection(&PerfDataCriticalSection);
748
749 Paged = Paged * (PageSize / 1024);
750 NonPaged = NonPaged * (PageSize / 1024);
751
752 Total = Paged + NonPaged;
753
754 return Total;
755 }
756
757 ULONG PerfDataGetKernelMemoryPagedK(void)
758 {
759 ULONG Paged;
760 ULONG PageSize;
761
762 EnterCriticalSection(&PerfDataCriticalSection);
763
764 Paged = SystemPerfInfo.PoolPagedBytes;
765 PageSize = SystemBasicInfo.uPageSize;
766
767 LeaveCriticalSection(&PerfDataCriticalSection);
768
769 Paged = Paged * (PageSize / 1024);
770
771 return Paged;
772 }
773
774 ULONG PerfDataGetKernelMemoryNonPagedK(void)
775 {
776 ULONG NonPaged;
777 ULONG PageSize;
778
779 EnterCriticalSection(&PerfDataCriticalSection);
780
781 NonPaged = SystemPerfInfo.PoolNonPagedBytes;
782 PageSize = SystemBasicInfo.uPageSize;
783
784 LeaveCriticalSection(&PerfDataCriticalSection);
785
786 NonPaged = NonPaged * (PageSize / 1024);
787
788 return NonPaged;
789 }
790
791 ULONG PerfDataGetPhysicalMemoryTotalK(void)
792 {
793 ULONG Total;
794 ULONG PageSize;
795
796 EnterCriticalSection(&PerfDataCriticalSection);
797
798 Total = SystemBasicInfo.uMmNumberOfPhysicalPages;
799 PageSize = SystemBasicInfo.uPageSize;
800
801 LeaveCriticalSection(&PerfDataCriticalSection);
802
803 Total = Total * (PageSize / 1024);
804
805 return Total;
806 }
807
808 ULONG PerfDataGetPhysicalMemoryAvailableK(void)
809 {
810 ULONG Available;
811 ULONG PageSize;
812
813 EnterCriticalSection(&PerfDataCriticalSection);
814
815 Available = SystemPerfInfo.MmAvailablePages;
816 PageSize = SystemBasicInfo.uPageSize;
817
818 LeaveCriticalSection(&PerfDataCriticalSection);
819
820 Available = Available * (PageSize / 1024);
821
822 return Available;
823 }
824
825 ULONG PerfDataGetPhysicalMemorySystemCacheK(void)
826 {
827 ULONG SystemCache;
828 ULONG PageSize;
829
830 EnterCriticalSection(&PerfDataCriticalSection);
831
832 SystemCache = SystemCacheInfo.CurrentSize;
833 PageSize = SystemBasicInfo.uPageSize;
834
835 LeaveCriticalSection(&PerfDataCriticalSection);
836
837 //SystemCache = SystemCache * (PageSize / 1024);
838 SystemCache = SystemCache / 1024;
839
840 return SystemCache;
841 }
842
843 ULONG PerfDataGetSystemHandleCount(void)
844 {
845 ULONG HandleCount;
846
847 EnterCriticalSection(&PerfDataCriticalSection);
848
849 HandleCount = SystemHandleInfo.Count;
850
851 LeaveCriticalSection(&PerfDataCriticalSection);
852
853 return HandleCount;
854 }
855
856 ULONG PerfDataGetTotalThreadCount(void)
857 {
858 ULONG ThreadCount = 0;
859 ULONG i;
860
861 EnterCriticalSection(&PerfDataCriticalSection);
862
863 for (i=0; i<ProcessCount; i++)
864 {
865 ThreadCount += pPerfData[i].ThreadCount;
866 }
867
868 LeaveCriticalSection(&PerfDataCriticalSection);
869
870 return ThreadCount;
871 }