remove whitespace from end of lines
[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(SystemCacheInformation, &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.NumberProcessors);
100 status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberProcessors, &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 == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
117 HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
118 }
119
120 } while (status == 0xC0000004 /*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 == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
135 HeapFree(GetProcessHeap(), 0, pBuffer);
136 }
137
138 } while (status == 0xC0000004 /*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<SystemBasicInfo.NumberProcessors; 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.IdleTime) - 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.NumberProcessors; /* + 0.5; */
185 dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberProcessors; /* + 0.5; */
186 }
187
188 /* Store new CPU's idle and system time */
189 liOldIdleTime = SysPerfInfo.IdleTime;
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.NumberProcessors; /* + 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->QuotaPagedPoolUsage;
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 ULONG PerfDataGetProcessId(ULONG Index)
349 {
350 ULONG ProcessId;
351
352 EnterCriticalSection(&PerfDataCriticalSection);
353
354 if (Index < ProcessCount)
355 ProcessId = (ULONG)pPerfData[Index].ProcessId;
356 else
357 ProcessId = 0;
358
359 LeaveCriticalSection(&PerfDataCriticalSection);
360
361 return ProcessId;
362 }
363
364 BOOL PerfDataGetUserName(ULONG Index, LPTSTR lpUserName, int nMaxCount)
365 {
366 BOOL bSuccessful;
367
368 EnterCriticalSection(&PerfDataCriticalSection);
369
370 if (Index < ProcessCount) {
371 #ifdef _UNICODE
372 wcsncpy(lpUserName, pPerfData[Index].UserName, nMaxCount);
373 #else
374 WideCharToMultiByte(CP_ACP, 0, pPerfData[Index].UserName, -1, lpUserName, nMaxCount, NULL, NULL);
375 #endif
376
377 bSuccessful = TRUE;
378 } else {
379 bSuccessful = FALSE;
380 }
381
382 LeaveCriticalSection(&PerfDataCriticalSection);
383
384 return bSuccessful;
385 }
386
387 ULONG PerfDataGetSessionId(ULONG Index)
388 {
389 ULONG SessionId;
390
391 EnterCriticalSection(&PerfDataCriticalSection);
392
393 if (Index < ProcessCount)
394 SessionId = pPerfData[Index].SessionId;
395 else
396 SessionId = 0;
397
398 LeaveCriticalSection(&PerfDataCriticalSection);
399
400 return SessionId;
401 }
402
403 ULONG PerfDataGetCPUUsage(ULONG Index)
404 {
405 ULONG CpuUsage;
406
407 EnterCriticalSection(&PerfDataCriticalSection);
408
409 if (Index < ProcessCount)
410 CpuUsage = pPerfData[Index].CPUUsage;
411 else
412 CpuUsage = 0;
413
414 LeaveCriticalSection(&PerfDataCriticalSection);
415
416 return CpuUsage;
417 }
418
419 TIME PerfDataGetCPUTime(ULONG Index)
420 {
421 TIME CpuTime = {{0,0}};
422
423 EnterCriticalSection(&PerfDataCriticalSection);
424
425 if (Index < ProcessCount)
426 CpuTime = pPerfData[Index].CPUTime;
427
428 LeaveCriticalSection(&PerfDataCriticalSection);
429
430 return CpuTime;
431 }
432
433 ULONG PerfDataGetWorkingSetSizeBytes(ULONG Index)
434 {
435 ULONG WorkingSetSizeBytes;
436
437 EnterCriticalSection(&PerfDataCriticalSection);
438
439 if (Index < ProcessCount)
440 WorkingSetSizeBytes = pPerfData[Index].WorkingSetSizeBytes;
441 else
442 WorkingSetSizeBytes = 0;
443
444 LeaveCriticalSection(&PerfDataCriticalSection);
445
446 return WorkingSetSizeBytes;
447 }
448
449 ULONG PerfDataGetPeakWorkingSetSizeBytes(ULONG Index)
450 {
451 ULONG PeakWorkingSetSizeBytes;
452
453 EnterCriticalSection(&PerfDataCriticalSection);
454
455 if (Index < ProcessCount)
456 PeakWorkingSetSizeBytes = pPerfData[Index].PeakWorkingSetSizeBytes;
457 else
458 PeakWorkingSetSizeBytes = 0;
459
460 LeaveCriticalSection(&PerfDataCriticalSection);
461
462 return PeakWorkingSetSizeBytes;
463 }
464
465 ULONG PerfDataGetWorkingSetSizeDelta(ULONG Index)
466 {
467 ULONG WorkingSetSizeDelta;
468
469 EnterCriticalSection(&PerfDataCriticalSection);
470
471 if (Index < ProcessCount)
472 WorkingSetSizeDelta = pPerfData[Index].WorkingSetSizeDelta;
473 else
474 WorkingSetSizeDelta = 0;
475
476 LeaveCriticalSection(&PerfDataCriticalSection);
477
478 return WorkingSetSizeDelta;
479 }
480
481 ULONG PerfDataGetPageFaultCount(ULONG Index)
482 {
483 ULONG PageFaultCount;
484
485 EnterCriticalSection(&PerfDataCriticalSection);
486
487 if (Index < ProcessCount)
488 PageFaultCount = pPerfData[Index].PageFaultCount;
489 else
490 PageFaultCount = 0;
491
492 LeaveCriticalSection(&PerfDataCriticalSection);
493
494 return PageFaultCount;
495 }
496
497 ULONG PerfDataGetPageFaultCountDelta(ULONG Index)
498 {
499 ULONG PageFaultCountDelta;
500
501 EnterCriticalSection(&PerfDataCriticalSection);
502
503 if (Index < ProcessCount)
504 PageFaultCountDelta = pPerfData[Index].PageFaultCountDelta;
505 else
506 PageFaultCountDelta = 0;
507
508 LeaveCriticalSection(&PerfDataCriticalSection);
509
510 return PageFaultCountDelta;
511 }
512
513 ULONG PerfDataGetVirtualMemorySizeBytes(ULONG Index)
514 {
515 ULONG VirtualMemorySizeBytes;
516
517 EnterCriticalSection(&PerfDataCriticalSection);
518
519 if (Index < ProcessCount)
520 VirtualMemorySizeBytes = pPerfData[Index].VirtualMemorySizeBytes;
521 else
522 VirtualMemorySizeBytes = 0;
523
524 LeaveCriticalSection(&PerfDataCriticalSection);
525
526 return VirtualMemorySizeBytes;
527 }
528
529 ULONG PerfDataGetPagedPoolUsagePages(ULONG Index)
530 {
531 ULONG PagedPoolUsagePages;
532
533 EnterCriticalSection(&PerfDataCriticalSection);
534
535 if (Index < ProcessCount)
536 PagedPoolUsagePages = pPerfData[Index].PagedPoolUsagePages;
537 else
538 PagedPoolUsagePages = 0;
539
540 LeaveCriticalSection(&PerfDataCriticalSection);
541
542 return PagedPoolUsagePages;
543 }
544
545 ULONG PerfDataGetNonPagedPoolUsagePages(ULONG Index)
546 {
547 ULONG NonPagedPoolUsagePages;
548
549 EnterCriticalSection(&PerfDataCriticalSection);
550
551 if (Index < ProcessCount)
552 NonPagedPoolUsagePages = pPerfData[Index].NonPagedPoolUsagePages;
553 else
554 NonPagedPoolUsagePages = 0;
555
556 LeaveCriticalSection(&PerfDataCriticalSection);
557
558 return NonPagedPoolUsagePages;
559 }
560
561 ULONG PerfDataGetBasePriority(ULONG Index)
562 {
563 ULONG BasePriority;
564
565 EnterCriticalSection(&PerfDataCriticalSection);
566
567 if (Index < ProcessCount)
568 BasePriority = pPerfData[Index].BasePriority;
569 else
570 BasePriority = 0;
571
572 LeaveCriticalSection(&PerfDataCriticalSection);
573
574 return BasePriority;
575 }
576
577 ULONG PerfDataGetHandleCount(ULONG Index)
578 {
579 ULONG HandleCount;
580
581 EnterCriticalSection(&PerfDataCriticalSection);
582
583 if (Index < ProcessCount)
584 HandleCount = pPerfData[Index].HandleCount;
585 else
586 HandleCount = 0;
587
588 LeaveCriticalSection(&PerfDataCriticalSection);
589
590 return HandleCount;
591 }
592
593 ULONG PerfDataGetThreadCount(ULONG Index)
594 {
595 ULONG ThreadCount;
596
597 EnterCriticalSection(&PerfDataCriticalSection);
598
599 if (Index < ProcessCount)
600 ThreadCount = pPerfData[Index].ThreadCount;
601 else
602 ThreadCount = 0;
603
604 LeaveCriticalSection(&PerfDataCriticalSection);
605
606 return ThreadCount;
607 }
608
609 ULONG PerfDataGetUSERObjectCount(ULONG Index)
610 {
611 ULONG USERObjectCount;
612
613 EnterCriticalSection(&PerfDataCriticalSection);
614
615 if (Index < ProcessCount)
616 USERObjectCount = pPerfData[Index].USERObjectCount;
617 else
618 USERObjectCount = 0;
619
620 LeaveCriticalSection(&PerfDataCriticalSection);
621
622 return USERObjectCount;
623 }
624
625 ULONG PerfDataGetGDIObjectCount(ULONG Index)
626 {
627 ULONG GDIObjectCount;
628
629 EnterCriticalSection(&PerfDataCriticalSection);
630
631 if (Index < ProcessCount)
632 GDIObjectCount = pPerfData[Index].GDIObjectCount;
633 else
634 GDIObjectCount = 0;
635
636 LeaveCriticalSection(&PerfDataCriticalSection);
637
638 return GDIObjectCount;
639 }
640
641 BOOL PerfDataGetIOCounters(ULONG Index, PIO_COUNTERS pIoCounters)
642 {
643 BOOL bSuccessful;
644
645 EnterCriticalSection(&PerfDataCriticalSection);
646
647 if (Index < ProcessCount)
648 {
649 memcpy(pIoCounters, &pPerfData[Index].IOCounters, sizeof(IO_COUNTERS));
650 bSuccessful = TRUE;
651 }
652 else
653 bSuccessful = FALSE;
654
655 LeaveCriticalSection(&PerfDataCriticalSection);
656
657 return bSuccessful;
658 }
659
660 ULONG PerfDataGetCommitChargeTotalK(void)
661 {
662 ULONG Total;
663 ULONG PageSize;
664
665 EnterCriticalSection(&PerfDataCriticalSection);
666
667 Total = SystemPerfInfo.TotalCommittedPages;
668 PageSize = SystemBasicInfo.PhysicalPageSize;
669
670 LeaveCriticalSection(&PerfDataCriticalSection);
671
672 Total = Total * (PageSize / 1024);
673
674 return Total;
675 }
676
677 ULONG PerfDataGetCommitChargeLimitK(void)
678 {
679 ULONG Limit;
680 ULONG PageSize;
681
682 EnterCriticalSection(&PerfDataCriticalSection);
683
684 Limit = SystemPerfInfo.TotalCommitLimit;
685 PageSize = SystemBasicInfo.PhysicalPageSize;
686
687 LeaveCriticalSection(&PerfDataCriticalSection);
688
689 Limit = Limit * (PageSize / 1024);
690
691 return Limit;
692 }
693
694 ULONG PerfDataGetCommitChargePeakK(void)
695 {
696 ULONG Peak;
697 ULONG PageSize;
698
699 EnterCriticalSection(&PerfDataCriticalSection);
700
701 Peak = SystemPerfInfo.PeakCommitment;
702 PageSize = SystemBasicInfo.PhysicalPageSize;
703
704 LeaveCriticalSection(&PerfDataCriticalSection);
705
706 Peak = Peak * (PageSize / 1024);
707
708 return Peak;
709 }
710
711 ULONG PerfDataGetKernelMemoryTotalK(void)
712 {
713 ULONG Total;
714 ULONG Paged;
715 ULONG NonPaged;
716 ULONG PageSize;
717
718 EnterCriticalSection(&PerfDataCriticalSection);
719
720 Paged = SystemPerfInfo.PagedPoolUsage;
721 NonPaged = SystemPerfInfo.NonPagedPoolUsage;
722 PageSize = SystemBasicInfo.PhysicalPageSize;
723
724 LeaveCriticalSection(&PerfDataCriticalSection);
725
726 Paged = Paged * (PageSize / 1024);
727 NonPaged = NonPaged * (PageSize / 1024);
728
729 Total = Paged + NonPaged;
730
731 return Total;
732 }
733
734 ULONG PerfDataGetKernelMemoryPagedK(void)
735 {
736 ULONG Paged;
737 ULONG PageSize;
738
739 EnterCriticalSection(&PerfDataCriticalSection);
740
741 Paged = SystemPerfInfo.PagedPoolUsage;
742 PageSize = SystemBasicInfo.PhysicalPageSize;
743
744 LeaveCriticalSection(&PerfDataCriticalSection);
745
746 Paged = Paged * (PageSize / 1024);
747
748 return Paged;
749 }
750
751 ULONG PerfDataGetKernelMemoryNonPagedK(void)
752 {
753 ULONG NonPaged;
754 ULONG PageSize;
755
756 EnterCriticalSection(&PerfDataCriticalSection);
757
758 NonPaged = SystemPerfInfo.NonPagedPoolUsage;
759 PageSize = SystemBasicInfo.PhysicalPageSize;
760
761 LeaveCriticalSection(&PerfDataCriticalSection);
762
763 NonPaged = NonPaged * (PageSize / 1024);
764
765 return NonPaged;
766 }
767
768 ULONG PerfDataGetPhysicalMemoryTotalK(void)
769 {
770 ULONG Total;
771 ULONG PageSize;
772
773 EnterCriticalSection(&PerfDataCriticalSection);
774
775 Total = SystemBasicInfo.NumberOfPhysicalPages;
776 PageSize = SystemBasicInfo.PhysicalPageSize;
777
778 LeaveCriticalSection(&PerfDataCriticalSection);
779
780 Total = Total * (PageSize / 1024);
781
782 return Total;
783 }
784
785 ULONG PerfDataGetPhysicalMemoryAvailableK(void)
786 {
787 ULONG Available;
788 ULONG PageSize;
789
790 EnterCriticalSection(&PerfDataCriticalSection);
791
792 Available = SystemPerfInfo.AvailablePages;
793 PageSize = SystemBasicInfo.PhysicalPageSize;
794
795 LeaveCriticalSection(&PerfDataCriticalSection);
796
797 Available = Available * (PageSize / 1024);
798
799 return Available;
800 }
801
802 ULONG PerfDataGetPhysicalMemorySystemCacheK(void)
803 {
804 ULONG SystemCache;
805 ULONG PageSize;
806
807 EnterCriticalSection(&PerfDataCriticalSection);
808
809 SystemCache = SystemCacheInfo.CurrentSize;
810 PageSize = SystemBasicInfo.PhysicalPageSize;
811
812 LeaveCriticalSection(&PerfDataCriticalSection);
813
814 /* SystemCache = SystemCache * (PageSize / 1024); */
815 SystemCache = SystemCache / 1024;
816
817 return SystemCache;
818 }
819
820 ULONG PerfDataGetSystemHandleCount(void)
821 {
822 ULONG HandleCount;
823
824 EnterCriticalSection(&PerfDataCriticalSection);
825
826 HandleCount = SystemHandleInfo.NumberOfHandles;
827
828 LeaveCriticalSection(&PerfDataCriticalSection);
829
830 return HandleCount;
831 }
832
833 ULONG PerfDataGetTotalThreadCount(void)
834 {
835 ULONG ThreadCount = 0;
836 ULONG i;
837
838 EnterCriticalSection(&PerfDataCriticalSection);
839
840 for (i=0; i<ProcessCount; i++)
841 {
842 ThreadCount += pPerfData[i].ThreadCount;
843 }
844
845 LeaveCriticalSection(&PerfDataCriticalSection);
846
847 return ThreadCount;
848 }