Sync with trunk head (part 1 of x)
[reactos.git] / base / applications / 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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_FILECACHE_INFORMATION SystemCacheInfo;
39 SYSTEM_HANDLE_INFORMATION SystemHandleInfo;
40 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemProcessorTimeInfo = NULL;
41 PSID SystemUserSid = NULL;
42
43 BOOL PerfDataInitialize(void)
44 {
45 SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
46 NTSTATUS status;
47
48 InitializeCriticalSection(&PerfDataCriticalSection);
49
50 /*
51 * Get number of processors in the system
52 */
53 status = NtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL);
54 if (status != NO_ERROR)
55 return FALSE;
56
57 /*
58 * Create the SYSTEM Sid
59 */
60 AllocateAndInitializeSid(&NtSidAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &SystemUserSid);
61 return TRUE;
62 }
63
64 void PerfDataUninitialize(void)
65 {
66
67 if (pPerfData != NULL)
68 HeapFree(GetProcessHeap(), 0, pPerfData);
69
70 DeleteCriticalSection(&PerfDataCriticalSection);
71
72 if (SystemUserSid != NULL)
73 {
74 FreeSid(SystemUserSid);
75 SystemUserSid = NULL;
76 }
77 }
78
79 static void SidToUserName(PSID Sid, LPWSTR szBuffer, DWORD BufferSize)
80 {
81 static WCHAR szDomainNameUnused[255];
82 DWORD DomainNameLen = sizeof(szDomainNameUnused) / sizeof(szDomainNameUnused[0]);
83 SID_NAME_USE Use;
84
85 if (Sid != NULL)
86 LookupAccountSidW(NULL, Sid, szBuffer, &BufferSize, szDomainNameUnused, &DomainNameLen, &Use);
87 }
88
89 void PerfDataRefresh(void)
90 {
91 ULONG ulSize;
92 NTSTATUS status;
93 LPBYTE pBuffer;
94 ULONG BufferSize;
95 PSYSTEM_PROCESS_INFORMATION pSPI;
96 PPERFDATA pPDOld;
97 ULONG Idx, Idx2;
98 HANDLE hProcess;
99 HANDLE hProcessToken;
100 SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
101 SYSTEM_TIMEOFDAY_INFORMATION SysTimeInfo;
102 SYSTEM_FILECACHE_INFORMATION SysCacheInfo;
103 LPBYTE SysHandleInfoData;
104 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcessorTimeInfo;
105 double CurrentKernelTime;
106 PSECURITY_DESCRIPTOR ProcessSD;
107 PSID ProcessUser;
108 ULONG Buffer[64]; /* must be 4 bytes aligned! */
109
110 /* Get new system time */
111 status = NtQuerySystemInformation(SystemTimeOfDayInformation, &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(SystemFileCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL);
122 if (status != NO_ERROR)
123 return;
124
125 /* Get processor time information */
126 SysProcessorTimeInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)HeapAlloc(GetProcessHeap(), 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors);
127 status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors, &ulSize);
128
129 if (status != NO_ERROR)
130 {
131 if (SysProcessorTimeInfo != NULL)
132 HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo);
133 return;
134 }
135
136 /* Get handle information
137 * We don't know how much data there is so just keep
138 * increasing the buffer size until the call succeeds
139 */
140 BufferSize = 0;
141 do
142 {
143 BufferSize += 0x10000;
144 SysHandleInfoData = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, BufferSize);
145
146 status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize);
147
148 if (status == STATUS_INFO_LENGTH_MISMATCH) {
149 HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
150 }
151
152 } while (status == STATUS_INFO_LENGTH_MISMATCH);
153
154 /* Get process information
155 * We don't know how much data there is so just keep
156 * increasing the buffer size until the call succeeds
157 */
158 BufferSize = 0;
159 do
160 {
161 BufferSize += 0x10000;
162 pBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, BufferSize);
163
164 status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);
165
166 if (status == STATUS_INFO_LENGTH_MISMATCH) {
167 HeapFree(GetProcessHeap(), 0, pBuffer);
168 }
169
170 } while (status == STATUS_INFO_LENGTH_MISMATCH);
171
172 EnterCriticalSection(&PerfDataCriticalSection);
173
174 /*
175 * Save system performance info
176 */
177 memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION));
178
179 /*
180 * Save system cache info
181 */
182 memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_FILECACHE_INFORMATION));
183
184 /*
185 * Save system processor time info
186 */
187 if (SystemProcessorTimeInfo) {
188 HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo);
189 }
190 SystemProcessorTimeInfo = SysProcessorTimeInfo;
191
192 /*
193 * Save system handle info
194 */
195 memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION));
196 HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
197
198 for (CurrentKernelTime=0, Idx=0; Idx<(ULONG)SystemBasicInfo.NumberOfProcessors; 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.IdleProcessTime) - Li2Double(liOldIdleTime);
208 dbKernelTime = CurrentKernelTime - OldKernelTime;
209 dbSystemTime = Li2Double(SysTimeInfo.CurrentTime) - 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.NumberOfProcessors; /* + 0.5; */
217 dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */
218 }
219
220 /* Store new CPU's idle and system time */
221 liOldIdleTime = SysPerfInfo.IdleProcessTime;
222 liOldSystemTime = SysTimeInfo.CurrentTime;
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 */
229 ProcessCountOld = ProcessCount;
230 ProcessCount = 0;
231 pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
232 while (pSPI) {
233 ProcessCount++;
234 if (pSPI->NextEntryOffset == 0)
235 break;
236 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset);
237 }
238
239 /* Now alloc a new PERFDATA array and fill in the data */
240 if (pPerfDataOld) {
241 HeapFree(GetProcessHeap(), 0, pPerfDataOld);
242 }
243 pPerfDataOld = pPerfData;
244 /* Clear out process perf data structures with HEAP_ZERO_MEMORY flag: */
245 pPerfData = (PPERFDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 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->UniqueProcessId) {
253 pPDOld = &pPerfDataOld[Idx2];
254 break;
255 }
256 }
257
258 if (pSPI->ImageName.Buffer) {
259 /* Don't assume a UNICODE_STRING Buffer is zero terminated: */
260 int len = pSPI->ImageName.Length / 2;
261 /* Check against max size and allow for terminating zero (already zeroed): */
262 if(len >= MAX_PATH)len=MAX_PATH - 1;
263 wcsncpy(pPerfData[Idx].ImageName, pSPI->ImageName.Buffer, len);
264 } else {
265 LoadStringW(hInst, IDS_IDLE_PROCESS, pPerfData[Idx].ImageName,
266 sizeof(pPerfData[Idx].ImageName) / sizeof(pPerfData[Idx].ImageName[0]));
267 }
268
269 pPerfData[Idx].ProcessId = pSPI->UniqueProcessId;
270
271 if (pPDOld) {
272 double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
273 double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
274 double CpuTime = (CurTime - OldTime) / dbSystemTime;
275 CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; /* + 0.5; */
276 pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
277 }
278 pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
279 pPerfData[Idx].WorkingSetSizeBytes = pSPI->WorkingSetSize;
280 pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSize;
281 if (pPDOld)
282 pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->WorkingSetSize - (LONG)pPDOld->WorkingSetSizeBytes);
283 else
284 pPerfData[Idx].WorkingSetSizeDelta = 0;
285 pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount;
286 if (pPDOld)
287 pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount);
288 else
289 pPerfData[Idx].PageFaultCountDelta = 0;
290 pPerfData[Idx].VirtualMemorySizeBytes = pSPI->VirtualSize;
291 pPerfData[Idx].PagedPoolUsagePages = pSPI->QuotaPeakPagedPoolUsage;
292 pPerfData[Idx].NonPagedPoolUsagePages = pSPI->QuotaPeakNonPagedPoolUsage;
293 pPerfData[Idx].BasePriority = pSPI->BasePriority;
294 pPerfData[Idx].HandleCount = pSPI->HandleCount;
295 pPerfData[Idx].ThreadCount = pSPI->NumberOfThreads;
296 pPerfData[Idx].SessionId = pSPI->SessionId;
297 pPerfData[Idx].UserName[0] = L'\0';
298 pPerfData[Idx].USERObjectCount = 0;
299 pPerfData[Idx].GDIObjectCount = 0;
300 ProcessUser = SystemUserSid;
301 ProcessSD = NULL;
302
303 if (pSPI->UniqueProcessId != NULL) {
304 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | READ_CONTROL, FALSE, PtrToUlong(pSPI->UniqueProcessId));
305 if (hProcess) {
306 /* don't query the information of the system process. It's possible but
307 returns Administrators as the owner of the process instead of SYSTEM */
308 if (pSPI->UniqueProcessId != (HANDLE)0x4)
309 {
310 if (OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
311 {
312 DWORD RetLen = 0;
313 BOOL Ret;
314
315 Ret = GetTokenInformation(hProcessToken, TokenUser, (LPVOID)Buffer, sizeof(Buffer), &RetLen);
316 CloseHandle(hProcessToken);
317
318 if (Ret)
319 ProcessUser = ((PTOKEN_USER)Buffer)->User.Sid;
320 else
321 goto ReadProcOwner;
322 }
323 else
324 {
325 ReadProcOwner:
326 GetSecurityInfo(hProcess, SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION, &ProcessUser, NULL, NULL, NULL, &ProcessSD);
327 }
328
329 pPerfData[Idx].USERObjectCount = GetGuiResources(hProcess, GR_USEROBJECTS);
330 pPerfData[Idx].GDIObjectCount = GetGuiResources(hProcess, GR_GDIOBJECTS);
331 }
332
333 GetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
334 CloseHandle(hProcess);
335 } else {
336 goto ClearInfo;
337 }
338 } else {
339 ClearInfo:
340 /* clear information we were unable to fetch */
341 ZeroMemory(&pPerfData[Idx].IOCounters, sizeof(IO_COUNTERS));
342 }
343
344 SidToUserName(ProcessUser, pPerfData[Idx].UserName, sizeof(pPerfData[0].UserName) / sizeof(pPerfData[0].UserName[0]));
345
346 if (ProcessSD != NULL)
347 {
348 LocalFree((HLOCAL)ProcessSD);
349 }
350
351 pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
352 pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
353 pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset);
354 }
355 HeapFree(GetProcessHeap(), 0, pBuffer);
356 LeaveCriticalSection(&PerfDataCriticalSection);
357 }
358
359 ULONG PerfDataGetProcessCount(void)
360 {
361 return ProcessCount;
362 }
363
364 ULONG PerfDataGetProcessorUsage(void)
365 {
366 return (ULONG)dbIdleTime;
367 }
368
369 ULONG PerfDataGetProcessorSystemUsage(void)
370 {
371 return (ULONG)dbKernelTime;
372 }
373
374 BOOL PerfDataGetImageName(ULONG Index, LPWSTR lpImageName, int nMaxCount)
375 {
376 BOOL bSuccessful;
377
378 EnterCriticalSection(&PerfDataCriticalSection);
379
380 if (Index < ProcessCount) {
381 wcsncpy(lpImageName, pPerfData[Index].ImageName, nMaxCount);
382 bSuccessful = TRUE;
383 } else {
384 bSuccessful = FALSE;
385 }
386 LeaveCriticalSection(&PerfDataCriticalSection);
387 return bSuccessful;
388 }
389
390 int PerfGetIndexByProcessId(DWORD dwProcessId)
391 {
392 int FoundIndex = -1;
393 ULONG Index;
394
395 EnterCriticalSection(&PerfDataCriticalSection);
396
397 for (Index = 0; Index < ProcessCount; Index++)
398 {
399 if (PtrToUlong(pPerfData[Index].ProcessId) == dwProcessId)
400 {
401 FoundIndex = Index;
402 break;
403 }
404 }
405
406 LeaveCriticalSection(&PerfDataCriticalSection);
407
408 return FoundIndex;
409 }
410
411 ULONG PerfDataGetProcessId(ULONG Index)
412 {
413 ULONG ProcessId;
414
415 EnterCriticalSection(&PerfDataCriticalSection);
416
417 if (Index < ProcessCount)
418 ProcessId = PtrToUlong(pPerfData[Index].ProcessId);
419 else
420 ProcessId = 0;
421
422 LeaveCriticalSection(&PerfDataCriticalSection);
423
424 return ProcessId;
425 }
426
427 BOOL PerfDataGetUserName(ULONG Index, LPWSTR lpUserName, int nMaxCount)
428 {
429 BOOL bSuccessful;
430
431 EnterCriticalSection(&PerfDataCriticalSection);
432
433 if (Index < ProcessCount) {
434 wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount);
435 bSuccessful = TRUE;
436 } else {
437 bSuccessful = FALSE;
438 }
439
440 LeaveCriticalSection(&PerfDataCriticalSection);
441
442 return bSuccessful;
443 }
444
445 ULONG PerfDataGetSessionId(ULONG Index)
446 {
447 ULONG SessionId;
448
449 EnterCriticalSection(&PerfDataCriticalSection);
450
451 if (Index < ProcessCount)
452 SessionId = pPerfData[Index].SessionId;
453 else
454 SessionId = 0;
455
456 LeaveCriticalSection(&PerfDataCriticalSection);
457
458 return SessionId;
459 }
460
461 ULONG PerfDataGetCPUUsage(ULONG Index)
462 {
463 ULONG CpuUsage;
464
465 EnterCriticalSection(&PerfDataCriticalSection);
466
467 if (Index < ProcessCount)
468 CpuUsage = pPerfData[Index].CPUUsage;
469 else
470 CpuUsage = 0;
471
472 LeaveCriticalSection(&PerfDataCriticalSection);
473
474 return CpuUsage;
475 }
476
477 LARGE_INTEGER PerfDataGetCPUTime(ULONG Index)
478 {
479 LARGE_INTEGER CpuTime = {{0,0}};
480
481 EnterCriticalSection(&PerfDataCriticalSection);
482
483 if (Index < ProcessCount)
484 CpuTime = pPerfData[Index].CPUTime;
485
486 LeaveCriticalSection(&PerfDataCriticalSection);
487
488 return CpuTime;
489 }
490
491 ULONG PerfDataGetWorkingSetSizeBytes(ULONG Index)
492 {
493 ULONG WorkingSetSizeBytes;
494
495 EnterCriticalSection(&PerfDataCriticalSection);
496
497 if (Index < ProcessCount)
498 WorkingSetSizeBytes = pPerfData[Index].WorkingSetSizeBytes;
499 else
500 WorkingSetSizeBytes = 0;
501
502 LeaveCriticalSection(&PerfDataCriticalSection);
503
504 return WorkingSetSizeBytes;
505 }
506
507 ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index)
508 {
509 ULONG PeakWorkingSetSizeBytes;
510
511 EnterCriticalSection(&PerfDataCriticalSection);
512
513 if (Index < ProcessCount)
514 PeakWorkingSetSizeBytes = pPerfData[Index].PeakWorkingSetSizeBytes;
515 else
516 PeakWorkingSetSizeBytes = 0;
517
518 LeaveCriticalSection(&PerfDataCriticalSection);
519
520 return PeakWorkingSetSizeBytes;
521 }
522
523 ULONG PerfDataGetWorkingSetSizeDelta(ULONG Index)
524 {
525 ULONG WorkingSetSizeDelta;
526
527 EnterCriticalSection(&PerfDataCriticalSection);
528
529 if (Index < ProcessCount)
530 WorkingSetSizeDelta = pPerfData[Index].WorkingSetSizeDelta;
531 else
532 WorkingSetSizeDelta = 0;
533
534 LeaveCriticalSection(&PerfDataCriticalSection);
535
536 return WorkingSetSizeDelta;
537 }
538
539 ULONG PerfDataGetPageFaultCount(ULONG Index)
540 {
541 ULONG PageFaultCount;
542
543 EnterCriticalSection(&PerfDataCriticalSection);
544
545 if (Index < ProcessCount)
546 PageFaultCount = pPerfData[Index].PageFaultCount;
547 else
548 PageFaultCount = 0;
549
550 LeaveCriticalSection(&PerfDataCriticalSection);
551
552 return PageFaultCount;
553 }
554
555 ULONG PerfDataGetPageFaultCountDelta(ULONG Index)
556 {
557 ULONG PageFaultCountDelta;
558
559 EnterCriticalSection(&PerfDataCriticalSection);
560
561 if (Index < ProcessCount)
562 PageFaultCountDelta = pPerfData[Index].PageFaultCountDelta;
563 else
564 PageFaultCountDelta = 0;
565
566 LeaveCriticalSection(&PerfDataCriticalSection);
567
568 return PageFaultCountDelta;
569 }
570
571 ULONG PerfDataGetVirtualMemorySizeBytes(ULONG Index)
572 {
573 ULONG VirtualMemorySizeBytes;
574
575 EnterCriticalSection(&PerfDataCriticalSection);
576
577 if (Index < ProcessCount)
578 VirtualMemorySizeBytes = pPerfData[Index].VirtualMemorySizeBytes;
579 else
580 VirtualMemorySizeBytes = 0;
581
582 LeaveCriticalSection(&PerfDataCriticalSection);
583
584 return VirtualMemorySizeBytes;
585 }
586
587 ULONG PerfDataGetPagedPoolUsagePages(ULONG Index)
588 {
589 ULONG PagedPoolUsage;
590
591 EnterCriticalSection(&PerfDataCriticalSection);
592
593 if (Index < ProcessCount)
594 PagedPoolUsage = pPerfData[Index].PagedPoolUsagePages;
595 else
596 PagedPoolUsage = 0;
597
598 LeaveCriticalSection(&PerfDataCriticalSection);
599
600 return PagedPoolUsage;
601 }
602
603 ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index)
604 {
605 ULONG NonPagedPoolUsage;
606
607 EnterCriticalSection(&PerfDataCriticalSection);
608
609 if (Index < ProcessCount)
610 NonPagedPoolUsage = pPerfData[Index].NonPagedPoolUsagePages;
611 else
612 NonPagedPoolUsage = 0;
613
614 LeaveCriticalSection(&PerfDataCriticalSection);
615
616 return NonPagedPoolUsage;
617 }
618
619 ULONG PerfDataGetBasePriority(ULONG Index)
620 {
621 ULONG BasePriority;
622
623 EnterCriticalSection(&PerfDataCriticalSection);
624
625 if (Index < ProcessCount)
626 BasePriority = pPerfData[Index].BasePriority;
627 else
628 BasePriority = 0;
629
630 LeaveCriticalSection(&PerfDataCriticalSection);
631
632 return BasePriority;
633 }
634
635 ULONG PerfDataGetHandleCount(ULONG Index)
636 {
637 ULONG HandleCount;
638
639 EnterCriticalSection(&PerfDataCriticalSection);
640
641 if (Index < ProcessCount)
642 HandleCount = pPerfData[Index].HandleCount;
643 else
644 HandleCount = 0;
645
646 LeaveCriticalSection(&PerfDataCriticalSection);
647
648 return HandleCount;
649 }
650
651 ULONG PerfDataGetThreadCount(ULONG Index)
652 {
653 ULONG ThreadCount;
654
655 EnterCriticalSection(&PerfDataCriticalSection);
656
657 if (Index < ProcessCount)
658 ThreadCount = pPerfData[Index].ThreadCount;
659 else
660 ThreadCount = 0;
661
662 LeaveCriticalSection(&PerfDataCriticalSection);
663
664 return ThreadCount;
665 }
666
667 ULONG PerfDataGetUSERObjectCount(ULONG Index)
668 {
669 ULONG USERObjectCount;
670
671 EnterCriticalSection(&PerfDataCriticalSection);
672
673 if (Index < ProcessCount)
674 USERObjectCount = pPerfData[Index].USERObjectCount;
675 else
676 USERObjectCount = 0;
677
678 LeaveCriticalSection(&PerfDataCriticalSection);
679
680 return USERObjectCount;
681 }
682
683 ULONG PerfDataGetGDIObjectCount(ULONG Index)
684 {
685 ULONG GDIObjectCount;
686
687 EnterCriticalSection(&PerfDataCriticalSection);
688
689 if (Index < ProcessCount)
690 GDIObjectCount = pPerfData[Index].GDIObjectCount;
691 else
692 GDIObjectCount = 0;
693
694 LeaveCriticalSection(&PerfDataCriticalSection);
695
696 return GDIObjectCount;
697 }
698
699 BOOL PerfDataGetIOCounters(ULONG Index, PIO_COUNTERS pIoCounters)
700 {
701 BOOL bSuccessful;
702
703 EnterCriticalSection(&PerfDataCriticalSection);
704
705 if (Index < ProcessCount)
706 {
707 memcpy(pIoCounters, &pPerfData[Index].IOCounters, sizeof(IO_COUNTERS));
708 bSuccessful = TRUE;
709 }
710 else
711 bSuccessful = FALSE;
712
713 LeaveCriticalSection(&PerfDataCriticalSection);
714
715 return bSuccessful;
716 }
717
718 ULONG PerfDataGetCommitChargeTotalK(void)
719 {
720 ULONG Total;
721 ULONG PageSize;
722
723 EnterCriticalSection(&PerfDataCriticalSection);
724
725 Total = SystemPerfInfo.CommittedPages;
726 PageSize = SystemBasicInfo.PageSize;
727
728 LeaveCriticalSection(&PerfDataCriticalSection);
729
730 Total = Total * (PageSize / 1024);
731
732 return Total;
733 }
734
735 ULONG PerfDataGetCommitChargeLimitK(void)
736 {
737 ULONG Limit;
738 ULONG PageSize;
739
740 EnterCriticalSection(&PerfDataCriticalSection);
741
742 Limit = SystemPerfInfo.CommitLimit;
743 PageSize = SystemBasicInfo.PageSize;
744
745 LeaveCriticalSection(&PerfDataCriticalSection);
746
747 Limit = Limit * (PageSize / 1024);
748
749 return Limit;
750 }
751
752 ULONG PerfDataGetCommitChargePeakK(void)
753 {
754 ULONG Peak;
755 ULONG PageSize;
756
757 EnterCriticalSection(&PerfDataCriticalSection);
758
759 Peak = SystemPerfInfo.PeakCommitment;
760 PageSize = SystemBasicInfo.PageSize;
761
762 LeaveCriticalSection(&PerfDataCriticalSection);
763
764 Peak = Peak * (PageSize / 1024);
765
766 return Peak;
767 }
768
769 ULONG PerfDataGetKernelMemoryTotalK(void)
770 {
771 ULONG Total;
772 ULONG Paged;
773 ULONG NonPaged;
774 ULONG PageSize;
775
776 EnterCriticalSection(&PerfDataCriticalSection);
777
778 Paged = SystemPerfInfo.PagedPoolPages;
779 NonPaged = SystemPerfInfo.NonPagedPoolPages;
780 PageSize = SystemBasicInfo.PageSize;
781
782 LeaveCriticalSection(&PerfDataCriticalSection);
783
784 Paged = Paged * (PageSize / 1024);
785 NonPaged = NonPaged * (PageSize / 1024);
786
787 Total = Paged + NonPaged;
788
789 return Total;
790 }
791
792 ULONG PerfDataGetKernelMemoryPagedK(void)
793 {
794 ULONG Paged;
795 ULONG PageSize;
796
797 EnterCriticalSection(&PerfDataCriticalSection);
798
799 Paged = SystemPerfInfo.PagedPoolPages;
800 PageSize = SystemBasicInfo.PageSize;
801
802 LeaveCriticalSection(&PerfDataCriticalSection);
803
804 Paged = Paged * (PageSize / 1024);
805
806 return Paged;
807 }
808
809 ULONG PerfDataGetKernelMemoryNonPagedK(void)
810 {
811 ULONG NonPaged;
812 ULONG PageSize;
813
814 EnterCriticalSection(&PerfDataCriticalSection);
815
816 NonPaged = SystemPerfInfo.NonPagedPoolPages;
817 PageSize = SystemBasicInfo.PageSize;
818
819 LeaveCriticalSection(&PerfDataCriticalSection);
820
821 NonPaged = NonPaged * (PageSize / 1024);
822
823 return NonPaged;
824 }
825
826 ULONG PerfDataGetPhysicalMemoryTotalK(void)
827 {
828 ULONG Total;
829 ULONG PageSize;
830
831 EnterCriticalSection(&PerfDataCriticalSection);
832
833 Total = SystemBasicInfo.NumberOfPhysicalPages;
834 PageSize = SystemBasicInfo.PageSize;
835
836 LeaveCriticalSection(&PerfDataCriticalSection);
837
838 Total = Total * (PageSize / 1024);
839
840 return Total;
841 }
842
843 ULONG PerfDataGetPhysicalMemoryAvailableK(void)
844 {
845 ULONG Available;
846 ULONG PageSize;
847
848 EnterCriticalSection(&PerfDataCriticalSection);
849
850 Available = SystemPerfInfo.AvailablePages;
851 PageSize = SystemBasicInfo.PageSize;
852
853 LeaveCriticalSection(&PerfDataCriticalSection);
854
855 Available = Available * (PageSize / 1024);
856
857 return Available;
858 }
859
860 ULONG PerfDataGetPhysicalMemorySystemCacheK(void)
861 {
862 ULONG SystemCache;
863 ULONG PageSize;
864
865 EnterCriticalSection(&PerfDataCriticalSection);
866
867 PageSize = SystemBasicInfo.PageSize;
868 SystemCache = SystemCacheInfo.CurrentSizeIncludingTransitionInPages * PageSize;
869
870 LeaveCriticalSection(&PerfDataCriticalSection);
871
872 return SystemCache / 1024;
873 }
874
875 ULONG PerfDataGetSystemHandleCount(void)
876 {
877 ULONG HandleCount;
878
879 EnterCriticalSection(&PerfDataCriticalSection);
880
881 HandleCount = SystemHandleInfo.NumberOfHandles;
882
883 LeaveCriticalSection(&PerfDataCriticalSection);
884
885 return HandleCount;
886 }
887
888 ULONG PerfDataGetTotalThreadCount(void)
889 {
890 ULONG ThreadCount = 0;
891 ULONG i;
892
893 EnterCriticalSection(&PerfDataCriticalSection);
894
895 for (i=0; i<ProcessCount; i++)
896 {
897 ThreadCount += pPerfData[i].ThreadCount;
898 }
899
900 LeaveCriticalSection(&PerfDataCriticalSection);
901
902 return ThreadCount;
903 }
904
905 BOOL PerfDataGet(ULONG Index, PPERFDATA *lppData)
906 {
907 BOOL bSuccessful = FALSE;
908
909 EnterCriticalSection(&PerfDataCriticalSection);
910 if (Index < ProcessCount)
911 {
912 *lppData = pPerfData + Index;
913 bSuccessful = TRUE;
914 }
915 LeaveCriticalSection(&PerfDataCriticalSection);
916 return bSuccessful;
917 }
918