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