6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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;
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
;
43 typedef struct _SIDTOUSERNAME
48 } SIDTOUSERNAME
, *PSIDTOUSERNAME
;
50 static LIST_ENTRY SidToUserNameHead
= {&SidToUserNameHead
, &SidToUserNameHead
};
52 BOOL
PerfDataInitialize(void)
54 SID_IDENTIFIER_AUTHORITY NtSidAuthority
= {SECURITY_NT_AUTHORITY
};
57 InitializeCriticalSection(&PerfDataCriticalSection
);
60 * Get number of processors in the system
62 status
= NtQuerySystemInformation(SystemBasicInformation
, &SystemBasicInfo
, sizeof(SystemBasicInfo
), NULL
);
63 if (status
!= NO_ERROR
)
67 * Create the SYSTEM Sid
69 AllocateAndInitializeSid(&NtSidAuthority
, 1, SECURITY_LOCAL_SYSTEM_RID
, 0, 0, 0, 0, 0, 0, 0, &SystemUserSid
);
73 void PerfDataUninitialize(void)
76 PSIDTOUSERNAME pEntry
;
78 if (pPerfData
!= NULL
)
79 HeapFree(GetProcessHeap(), 0, pPerfData
);
81 DeleteCriticalSection(&PerfDataCriticalSection
);
83 if (SystemUserSid
!= NULL
)
85 FreeSid(SystemUserSid
);
89 /* Free user names cache list */
90 pCur
= SidToUserNameHead
.Flink
;
91 while (pCur
!= &SidToUserNameHead
)
93 pEntry
= CONTAINING_RECORD(pCur
, SIDTOUSERNAME
, List
);
95 HeapFree(GetProcessHeap(), 0, pEntry
);
99 static void SidToUserName(PSID Sid
, LPWSTR szBuffer
, DWORD BufferSize
)
101 static WCHAR szDomainNameUnused
[255];
102 DWORD DomainNameLen
= sizeof(szDomainNameUnused
) / sizeof(szDomainNameUnused
[0]);
106 LookupAccountSidW(NULL
, Sid
, szBuffer
, &BufferSize
, szDomainNameUnused
, &DomainNameLen
, &Use
);
111 CachedGetUserFromSid(
117 PSIDTOUSERNAME pEntry
;
118 ULONG cbSid
, cwcUserName
;
120 cwcUserName
= *pcwcUserName
;
122 /* Walk through the list */
123 for(pCur
= SidToUserNameHead
.Flink
;
124 pCur
!= &SidToUserNameHead
;
127 pEntry
= CONTAINING_RECORD(pCur
, SIDTOUSERNAME
, List
);
128 if (EqualSid((PSID
)&pEntry
->Data
, pSid
))
130 wcsncpy(pUserName
, pEntry
->pszName
, cwcUserName
);
131 *pcwcUserName
= cwcUserName
;
136 /* We didn't find the SID in the list, get the name conventional */
137 SidToUserName(pSid
, pUserName
, cwcUserName
);
139 /* Allocate a new entry */
140 *pcwcUserName
= wcslen(pUserName
);
141 cwcUserName
= *pcwcUserName
+ 1;
142 cbSid
= GetLengthSid(pSid
);
143 pEntry
= HeapAlloc(GetProcessHeap(), 0, sizeof(SIDTOUSERNAME
) + cbSid
+ cwcUserName
* sizeof(WCHAR
));
145 /* Copy the Sid and name to our entry */
146 CopySid(cbSid
, (PSID
)&pEntry
->Data
, pSid
);
147 pEntry
->pszName
= (LPWSTR
)(pEntry
->Data
+ cbSid
);
148 wcsncpy(pEntry
->pszName
, pUserName
, cwcUserName
);
150 /* Insert the new entry */
151 pEntry
->List
.Flink
= &SidToUserNameHead
;
152 pEntry
->List
.Blink
= SidToUserNameHead
.Blink
;
153 SidToUserNameHead
.Blink
->Flink
= &pEntry
->List
;
154 SidToUserNameHead
.Blink
= &pEntry
->List
;
159 void PerfDataRefresh(void)
165 PSYSTEM_PROCESS_INFORMATION pSPI
;
169 HANDLE hProcessToken
;
170 SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo
;
171 SYSTEM_TIMEOFDAY_INFORMATION SysTimeInfo
;
172 SYSTEM_FILECACHE_INFORMATION SysCacheInfo
;
173 LPBYTE SysHandleInfoData
;
174 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcessorTimeInfo
;
175 double CurrentKernelTime
;
176 PSECURITY_DESCRIPTOR ProcessSD
;
178 ULONG Buffer
[64]; /* must be 4 bytes aligned! */
181 /* Get new system time */
182 status
= NtQuerySystemInformation(SystemTimeOfDayInformation
, &SysTimeInfo
, sizeof(SysTimeInfo
), 0);
183 if (status
!= NO_ERROR
)
186 /* Get new CPU's idle time */
187 status
= NtQuerySystemInformation(SystemPerformanceInformation
, &SysPerfInfo
, sizeof(SysPerfInfo
), NULL
);
188 if (status
!= NO_ERROR
)
191 /* Get system cache information */
192 status
= NtQuerySystemInformation(SystemFileCacheInformation
, &SysCacheInfo
, sizeof(SysCacheInfo
), NULL
);
193 if (status
!= NO_ERROR
)
196 /* Get processor time information */
197 SysProcessorTimeInfo
= (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
)HeapAlloc(GetProcessHeap(), 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) * SystemBasicInfo
.NumberOfProcessors
);
198 status
= NtQuerySystemInformation(SystemProcessorPerformanceInformation
, SysProcessorTimeInfo
, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
) * SystemBasicInfo
.NumberOfProcessors
, &ulSize
);
200 if (status
!= NO_ERROR
)
202 if (SysProcessorTimeInfo
!= NULL
)
203 HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo
);
207 /* Get handle information
208 * We don't know how much data there is so just keep
209 * increasing the buffer size until the call succeeds
214 BufferSize
+= 0x10000;
215 SysHandleInfoData
= (LPBYTE
)HeapAlloc(GetProcessHeap(), 0, BufferSize
);
217 status
= NtQuerySystemInformation(SystemHandleInformation
, SysHandleInfoData
, BufferSize
, &ulSize
);
219 if (status
== STATUS_INFO_LENGTH_MISMATCH
) {
220 HeapFree(GetProcessHeap(), 0, SysHandleInfoData
);
223 } while (status
== STATUS_INFO_LENGTH_MISMATCH
);
225 /* Get process information
226 * We don't know how much data there is so just keep
227 * increasing the buffer size until the call succeeds
232 BufferSize
+= 0x10000;
233 pBuffer
= (LPBYTE
)HeapAlloc(GetProcessHeap(), 0, BufferSize
);
235 status
= NtQuerySystemInformation(SystemProcessInformation
, pBuffer
, BufferSize
, &ulSize
);
237 if (status
== STATUS_INFO_LENGTH_MISMATCH
) {
238 HeapFree(GetProcessHeap(), 0, pBuffer
);
241 } while (status
== STATUS_INFO_LENGTH_MISMATCH
);
243 EnterCriticalSection(&PerfDataCriticalSection
);
246 * Save system performance info
248 memcpy(&SystemPerfInfo
, &SysPerfInfo
, sizeof(SYSTEM_PERFORMANCE_INFORMATION
));
251 * Save system cache info
253 memcpy(&SystemCacheInfo
, &SysCacheInfo
, sizeof(SYSTEM_FILECACHE_INFORMATION
));
256 * Save system processor time info
258 if (SystemProcessorTimeInfo
) {
259 HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo
);
261 SystemProcessorTimeInfo
= SysProcessorTimeInfo
;
264 * Save system handle info
266 memcpy(&SystemHandleInfo
, SysHandleInfoData
, sizeof(SYSTEM_HANDLE_INFORMATION
));
267 HeapFree(GetProcessHeap(), 0, SysHandleInfoData
);
269 for (CurrentKernelTime
=0, Idx
=0; Idx
<(ULONG
)SystemBasicInfo
.NumberOfProcessors
; Idx
++) {
270 CurrentKernelTime
+= Li2Double(SystemProcessorTimeInfo
[Idx
].KernelTime
);
271 CurrentKernelTime
+= Li2Double(SystemProcessorTimeInfo
[Idx
].DpcTime
);
272 CurrentKernelTime
+= Li2Double(SystemProcessorTimeInfo
[Idx
].InterruptTime
);
275 /* If it's a first call - skip idle time calcs */
276 if (liOldIdleTime
.QuadPart
!= 0) {
277 /* CurrentValue = NewValue - OldValue */
278 dbIdleTime
= Li2Double(SysPerfInfo
.IdleProcessTime
) - Li2Double(liOldIdleTime
);
279 dbKernelTime
= CurrentKernelTime
- OldKernelTime
;
280 dbSystemTime
= Li2Double(SysTimeInfo
.CurrentTime
) - Li2Double(liOldSystemTime
);
282 /* CurrentCpuIdle = IdleTime / SystemTime */
283 dbIdleTime
= dbIdleTime
/ dbSystemTime
;
284 dbKernelTime
= dbKernelTime
/ dbSystemTime
;
286 /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
287 dbIdleTime
= 100.0 - dbIdleTime
* 100.0 / (double)SystemBasicInfo
.NumberOfProcessors
; /* + 0.5; */
288 dbKernelTime
= 100.0 - dbKernelTime
* 100.0 / (double)SystemBasicInfo
.NumberOfProcessors
; /* + 0.5; */
291 /* Store new CPU's idle and system time */
292 liOldIdleTime
= SysPerfInfo
.IdleProcessTime
;
293 liOldSystemTime
= SysTimeInfo
.CurrentTime
;
294 OldKernelTime
= CurrentKernelTime
;
296 /* Determine the process count
297 * We loop through the data we got from NtQuerySystemInformation
298 * and count how many structures there are (until RelativeOffset is 0)
300 ProcessCountOld
= ProcessCount
;
302 pSPI
= (PSYSTEM_PROCESS_INFORMATION
)pBuffer
;
305 if (pSPI
->NextEntryOffset
== 0)
307 pSPI
= (PSYSTEM_PROCESS_INFORMATION
)((LPBYTE
)pSPI
+ pSPI
->NextEntryOffset
);
310 /* Now alloc a new PERFDATA array and fill in the data */
312 HeapFree(GetProcessHeap(), 0, pPerfDataOld
);
314 pPerfDataOld
= pPerfData
;
315 /* Clear out process perf data structures with HEAP_ZERO_MEMORY flag: */
316 pPerfData
= (PPERFDATA
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(PERFDATA
) * ProcessCount
);
317 pSPI
= (PSYSTEM_PROCESS_INFORMATION
)pBuffer
;
318 for (Idx
=0; Idx
<ProcessCount
; Idx
++) {
319 /* Get the old perf data for this process (if any) */
320 /* so that we can establish delta values */
322 for (Idx2
=0; Idx2
<ProcessCountOld
; Idx2
++) {
323 if (pPerfDataOld
[Idx2
].ProcessId
== pSPI
->UniqueProcessId
) {
324 pPDOld
= &pPerfDataOld
[Idx2
];
329 if (pSPI
->ImageName
.Buffer
) {
330 /* Don't assume a UNICODE_STRING Buffer is zero terminated: */
331 int len
= pSPI
->ImageName
.Length
/ 2;
332 /* Check against max size and allow for terminating zero (already zeroed): */
333 if(len
>= MAX_PATH
)len
=MAX_PATH
- 1;
334 wcsncpy(pPerfData
[Idx
].ImageName
, pSPI
->ImageName
.Buffer
, len
);
336 LoadStringW(hInst
, IDS_IDLE_PROCESS
, pPerfData
[Idx
].ImageName
,
337 sizeof(pPerfData
[Idx
].ImageName
) / sizeof(pPerfData
[Idx
].ImageName
[0]));
340 pPerfData
[Idx
].ProcessId
= pSPI
->UniqueProcessId
;
343 double CurTime
= Li2Double(pSPI
->KernelTime
) + Li2Double(pSPI
->UserTime
);
344 double OldTime
= Li2Double(pPDOld
->KernelTime
) + Li2Double(pPDOld
->UserTime
);
345 double CpuTime
= (CurTime
- OldTime
) / dbSystemTime
;
346 CpuTime
= CpuTime
* 100.0 / (double)SystemBasicInfo
.NumberOfProcessors
; /* + 0.5; */
347 pPerfData
[Idx
].CPUUsage
= (ULONG
)CpuTime
;
349 pPerfData
[Idx
].CPUTime
.QuadPart
= pSPI
->UserTime
.QuadPart
+ pSPI
->KernelTime
.QuadPart
;
350 pPerfData
[Idx
].WorkingSetSizeBytes
= pSPI
->WorkingSetSize
;
351 pPerfData
[Idx
].PeakWorkingSetSizeBytes
= pSPI
->PeakWorkingSetSize
;
353 pPerfData
[Idx
].WorkingSetSizeDelta
= labs((LONG
)pSPI
->WorkingSetSize
- (LONG
)pPDOld
->WorkingSetSizeBytes
);
355 pPerfData
[Idx
].WorkingSetSizeDelta
= 0;
356 pPerfData
[Idx
].PageFaultCount
= pSPI
->PageFaultCount
;
358 pPerfData
[Idx
].PageFaultCountDelta
= labs((LONG
)pSPI
->PageFaultCount
- (LONG
)pPDOld
->PageFaultCount
);
360 pPerfData
[Idx
].PageFaultCountDelta
= 0;
361 pPerfData
[Idx
].VirtualMemorySizeBytes
= pSPI
->VirtualSize
;
362 pPerfData
[Idx
].PagedPoolUsagePages
= pSPI
->QuotaPeakPagedPoolUsage
;
363 pPerfData
[Idx
].NonPagedPoolUsagePages
= pSPI
->QuotaPeakNonPagedPoolUsage
;
364 pPerfData
[Idx
].BasePriority
= pSPI
->BasePriority
;
365 pPerfData
[Idx
].HandleCount
= pSPI
->HandleCount
;
366 pPerfData
[Idx
].ThreadCount
= pSPI
->NumberOfThreads
;
367 pPerfData
[Idx
].SessionId
= pSPI
->SessionId
;
368 pPerfData
[Idx
].UserName
[0] = L
'\0';
369 pPerfData
[Idx
].USERObjectCount
= 0;
370 pPerfData
[Idx
].GDIObjectCount
= 0;
371 ProcessUser
= SystemUserSid
;
374 if (pSPI
->UniqueProcessId
!= NULL
) {
375 hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
| READ_CONTROL
, FALSE
, PtrToUlong(pSPI
->UniqueProcessId
));
377 /* don't query the information of the system process. It's possible but
378 returns Administrators as the owner of the process instead of SYSTEM */
379 if (pSPI
->UniqueProcessId
!= (HANDLE
)0x4)
381 if (OpenProcessToken(hProcess
, TOKEN_QUERY
, &hProcessToken
))
386 Ret
= GetTokenInformation(hProcessToken
, TokenUser
, (LPVOID
)Buffer
, sizeof(Buffer
), &RetLen
);
387 CloseHandle(hProcessToken
);
390 ProcessUser
= ((PTOKEN_USER
)Buffer
)->User
.Sid
;
397 GetSecurityInfo(hProcess
, SE_KERNEL_OBJECT
, OWNER_SECURITY_INFORMATION
, &ProcessUser
, NULL
, NULL
, NULL
, &ProcessSD
);
400 pPerfData
[Idx
].USERObjectCount
= GetGuiResources(hProcess
, GR_USEROBJECTS
);
401 pPerfData
[Idx
].GDIObjectCount
= GetGuiResources(hProcess
, GR_GDIOBJECTS
);
404 GetProcessIoCounters(hProcess
, &pPerfData
[Idx
].IOCounters
);
405 CloseHandle(hProcess
);
411 /* clear information we were unable to fetch */
412 ZeroMemory(&pPerfData
[Idx
].IOCounters
, sizeof(IO_COUNTERS
));
415 cwcUserName
= sizeof(pPerfData
[0].UserName
) / sizeof(pPerfData
[0].UserName
[0]);
416 CachedGetUserFromSid(ProcessUser
, pPerfData
[Idx
].UserName
, &cwcUserName
);
418 if (ProcessSD
!= NULL
)
420 LocalFree((HLOCAL
)ProcessSD
);
423 pPerfData
[Idx
].UserTime
.QuadPart
= pSPI
->UserTime
.QuadPart
;
424 pPerfData
[Idx
].KernelTime
.QuadPart
= pSPI
->KernelTime
.QuadPart
;
425 pSPI
= (PSYSTEM_PROCESS_INFORMATION
)((LPBYTE
)pSPI
+ pSPI
->NextEntryOffset
);
427 HeapFree(GetProcessHeap(), 0, pBuffer
);
428 LeaveCriticalSection(&PerfDataCriticalSection
);
431 ULONG
PerfDataGetProcessIndex(ULONG pid
)
435 EnterCriticalSection(&PerfDataCriticalSection
);
437 for (idx
= 0; idx
< ProcessCount
; idx
++)
439 if (PtrToUlong(pPerfData
[idx
].ProcessId
) == pid
)
445 LeaveCriticalSection(&PerfDataCriticalSection
);
447 if (idx
== ProcessCount
)
454 ULONG
PerfDataGetProcessCount(void)
459 ULONG
PerfDataGetProcessorUsage(void)
461 return (ULONG
)dbIdleTime
;
464 ULONG
PerfDataGetProcessorSystemUsage(void)
466 return (ULONG
)dbKernelTime
;
469 BOOL
PerfDataGetImageName(ULONG Index
, LPWSTR lpImageName
, int nMaxCount
)
473 EnterCriticalSection(&PerfDataCriticalSection
);
475 if (Index
< ProcessCount
) {
476 wcsncpy(lpImageName
, pPerfData
[Index
].ImageName
, nMaxCount
);
481 LeaveCriticalSection(&PerfDataCriticalSection
);
485 ULONG
PerfDataGetProcessId(ULONG Index
)
489 EnterCriticalSection(&PerfDataCriticalSection
);
491 if (Index
< ProcessCount
)
492 ProcessId
= PtrToUlong(pPerfData
[Index
].ProcessId
);
496 LeaveCriticalSection(&PerfDataCriticalSection
);
501 BOOL
PerfDataGetUserName(ULONG Index
, LPWSTR lpUserName
, int nMaxCount
)
505 EnterCriticalSection(&PerfDataCriticalSection
);
507 if (Index
< ProcessCount
) {
508 wcsncpy(lpUserName
, pPerfData
[Index
].UserName
, nMaxCount
);
514 LeaveCriticalSection(&PerfDataCriticalSection
);
519 ULONG
PerfDataGetSessionId(ULONG Index
)
523 EnterCriticalSection(&PerfDataCriticalSection
);
525 if (Index
< ProcessCount
)
526 SessionId
= pPerfData
[Index
].SessionId
;
530 LeaveCriticalSection(&PerfDataCriticalSection
);
535 ULONG
PerfDataGetCPUUsage(ULONG Index
)
539 EnterCriticalSection(&PerfDataCriticalSection
);
541 if (Index
< ProcessCount
)
542 CpuUsage
= pPerfData
[Index
].CPUUsage
;
546 LeaveCriticalSection(&PerfDataCriticalSection
);
551 LARGE_INTEGER
PerfDataGetCPUTime(ULONG Index
)
553 LARGE_INTEGER CpuTime
= {{0,0}};
555 EnterCriticalSection(&PerfDataCriticalSection
);
557 if (Index
< ProcessCount
)
558 CpuTime
= pPerfData
[Index
].CPUTime
;
560 LeaveCriticalSection(&PerfDataCriticalSection
);
565 ULONG
PerfDataGetWorkingSetSizeBytes(ULONG Index
)
567 ULONG WorkingSetSizeBytes
;
569 EnterCriticalSection(&PerfDataCriticalSection
);
571 if (Index
< ProcessCount
)
572 WorkingSetSizeBytes
= pPerfData
[Index
].WorkingSetSizeBytes
;
574 WorkingSetSizeBytes
= 0;
576 LeaveCriticalSection(&PerfDataCriticalSection
);
578 return WorkingSetSizeBytes
;
581 ULONG
PerfDataGetPeakWorkingSetSizeBytes(ULONG Index
)
583 ULONG PeakWorkingSetSizeBytes
;
585 EnterCriticalSection(&PerfDataCriticalSection
);
587 if (Index
< ProcessCount
)
588 PeakWorkingSetSizeBytes
= pPerfData
[Index
].PeakWorkingSetSizeBytes
;
590 PeakWorkingSetSizeBytes
= 0;
592 LeaveCriticalSection(&PerfDataCriticalSection
);
594 return PeakWorkingSetSizeBytes
;
597 ULONG
PerfDataGetWorkingSetSizeDelta(ULONG Index
)
599 ULONG WorkingSetSizeDelta
;
601 EnterCriticalSection(&PerfDataCriticalSection
);
603 if (Index
< ProcessCount
)
604 WorkingSetSizeDelta
= pPerfData
[Index
].WorkingSetSizeDelta
;
606 WorkingSetSizeDelta
= 0;
608 LeaveCriticalSection(&PerfDataCriticalSection
);
610 return WorkingSetSizeDelta
;
613 ULONG
PerfDataGetPageFaultCount(ULONG Index
)
615 ULONG PageFaultCount
;
617 EnterCriticalSection(&PerfDataCriticalSection
);
619 if (Index
< ProcessCount
)
620 PageFaultCount
= pPerfData
[Index
].PageFaultCount
;
624 LeaveCriticalSection(&PerfDataCriticalSection
);
626 return PageFaultCount
;
629 ULONG
PerfDataGetPageFaultCountDelta(ULONG Index
)
631 ULONG PageFaultCountDelta
;
633 EnterCriticalSection(&PerfDataCriticalSection
);
635 if (Index
< ProcessCount
)
636 PageFaultCountDelta
= pPerfData
[Index
].PageFaultCountDelta
;
638 PageFaultCountDelta
= 0;
640 LeaveCriticalSection(&PerfDataCriticalSection
);
642 return PageFaultCountDelta
;
645 ULONG
PerfDataGetVirtualMemorySizeBytes(ULONG Index
)
647 ULONG VirtualMemorySizeBytes
;
649 EnterCriticalSection(&PerfDataCriticalSection
);
651 if (Index
< ProcessCount
)
652 VirtualMemorySizeBytes
= pPerfData
[Index
].VirtualMemorySizeBytes
;
654 VirtualMemorySizeBytes
= 0;
656 LeaveCriticalSection(&PerfDataCriticalSection
);
658 return VirtualMemorySizeBytes
;
661 ULONG
PerfDataGetPagedPoolUsagePages(ULONG Index
)
663 ULONG PagedPoolUsage
;
665 EnterCriticalSection(&PerfDataCriticalSection
);
667 if (Index
< ProcessCount
)
668 PagedPoolUsage
= pPerfData
[Index
].PagedPoolUsagePages
;
672 LeaveCriticalSection(&PerfDataCriticalSection
);
674 return PagedPoolUsage
;
677 ULONG
PerfDataGetNonPagedPoolUsagePages(ULONG Index
)
679 ULONG NonPagedPoolUsage
;
681 EnterCriticalSection(&PerfDataCriticalSection
);
683 if (Index
< ProcessCount
)
684 NonPagedPoolUsage
= pPerfData
[Index
].NonPagedPoolUsagePages
;
686 NonPagedPoolUsage
= 0;
688 LeaveCriticalSection(&PerfDataCriticalSection
);
690 return NonPagedPoolUsage
;
693 ULONG
PerfDataGetBasePriority(ULONG Index
)
697 EnterCriticalSection(&PerfDataCriticalSection
);
699 if (Index
< ProcessCount
)
700 BasePriority
= pPerfData
[Index
].BasePriority
;
704 LeaveCriticalSection(&PerfDataCriticalSection
);
709 ULONG
PerfDataGetHandleCount(ULONG Index
)
713 EnterCriticalSection(&PerfDataCriticalSection
);
715 if (Index
< ProcessCount
)
716 HandleCount
= pPerfData
[Index
].HandleCount
;
720 LeaveCriticalSection(&PerfDataCriticalSection
);
725 ULONG
PerfDataGetThreadCount(ULONG Index
)
729 EnterCriticalSection(&PerfDataCriticalSection
);
731 if (Index
< ProcessCount
)
732 ThreadCount
= pPerfData
[Index
].ThreadCount
;
736 LeaveCriticalSection(&PerfDataCriticalSection
);
741 ULONG
PerfDataGetUSERObjectCount(ULONG Index
)
743 ULONG USERObjectCount
;
745 EnterCriticalSection(&PerfDataCriticalSection
);
747 if (Index
< ProcessCount
)
748 USERObjectCount
= pPerfData
[Index
].USERObjectCount
;
752 LeaveCriticalSection(&PerfDataCriticalSection
);
754 return USERObjectCount
;
757 ULONG
PerfDataGetGDIObjectCount(ULONG Index
)
759 ULONG GDIObjectCount
;
761 EnterCriticalSection(&PerfDataCriticalSection
);
763 if (Index
< ProcessCount
)
764 GDIObjectCount
= pPerfData
[Index
].GDIObjectCount
;
768 LeaveCriticalSection(&PerfDataCriticalSection
);
770 return GDIObjectCount
;
773 BOOL
PerfDataGetIOCounters(ULONG Index
, PIO_COUNTERS pIoCounters
)
777 EnterCriticalSection(&PerfDataCriticalSection
);
779 if (Index
< ProcessCount
)
781 memcpy(pIoCounters
, &pPerfData
[Index
].IOCounters
, sizeof(IO_COUNTERS
));
787 LeaveCriticalSection(&PerfDataCriticalSection
);
792 ULONG
PerfDataGetCommitChargeTotalK(void)
797 EnterCriticalSection(&PerfDataCriticalSection
);
799 Total
= SystemPerfInfo
.CommittedPages
;
800 PageSize
= SystemBasicInfo
.PageSize
;
802 LeaveCriticalSection(&PerfDataCriticalSection
);
804 Total
= Total
* (PageSize
/ 1024);
809 ULONG
PerfDataGetCommitChargeLimitK(void)
814 EnterCriticalSection(&PerfDataCriticalSection
);
816 Limit
= SystemPerfInfo
.CommitLimit
;
817 PageSize
= SystemBasicInfo
.PageSize
;
819 LeaveCriticalSection(&PerfDataCriticalSection
);
821 Limit
= Limit
* (PageSize
/ 1024);
826 ULONG
PerfDataGetCommitChargePeakK(void)
831 EnterCriticalSection(&PerfDataCriticalSection
);
833 Peak
= SystemPerfInfo
.PeakCommitment
;
834 PageSize
= SystemBasicInfo
.PageSize
;
836 LeaveCriticalSection(&PerfDataCriticalSection
);
838 Peak
= Peak
* (PageSize
/ 1024);
843 ULONG
PerfDataGetKernelMemoryTotalK(void)
850 EnterCriticalSection(&PerfDataCriticalSection
);
852 Paged
= SystemPerfInfo
.PagedPoolPages
;
853 NonPaged
= SystemPerfInfo
.NonPagedPoolPages
;
854 PageSize
= SystemBasicInfo
.PageSize
;
856 LeaveCriticalSection(&PerfDataCriticalSection
);
858 Paged
= Paged
* (PageSize
/ 1024);
859 NonPaged
= NonPaged
* (PageSize
/ 1024);
861 Total
= Paged
+ NonPaged
;
866 ULONG
PerfDataGetKernelMemoryPagedK(void)
871 EnterCriticalSection(&PerfDataCriticalSection
);
873 Paged
= SystemPerfInfo
.PagedPoolPages
;
874 PageSize
= SystemBasicInfo
.PageSize
;
876 LeaveCriticalSection(&PerfDataCriticalSection
);
878 Paged
= Paged
* (PageSize
/ 1024);
883 ULONG
PerfDataGetKernelMemoryNonPagedK(void)
888 EnterCriticalSection(&PerfDataCriticalSection
);
890 NonPaged
= SystemPerfInfo
.NonPagedPoolPages
;
891 PageSize
= SystemBasicInfo
.PageSize
;
893 LeaveCriticalSection(&PerfDataCriticalSection
);
895 NonPaged
= NonPaged
* (PageSize
/ 1024);
900 ULONG
PerfDataGetPhysicalMemoryTotalK(void)
905 EnterCriticalSection(&PerfDataCriticalSection
);
907 Total
= SystemBasicInfo
.NumberOfPhysicalPages
;
908 PageSize
= SystemBasicInfo
.PageSize
;
910 LeaveCriticalSection(&PerfDataCriticalSection
);
912 Total
= Total
* (PageSize
/ 1024);
917 ULONG
PerfDataGetPhysicalMemoryAvailableK(void)
922 EnterCriticalSection(&PerfDataCriticalSection
);
924 Available
= SystemPerfInfo
.AvailablePages
;
925 PageSize
= SystemBasicInfo
.PageSize
;
927 LeaveCriticalSection(&PerfDataCriticalSection
);
929 Available
= Available
* (PageSize
/ 1024);
934 ULONG
PerfDataGetPhysicalMemorySystemCacheK(void)
939 EnterCriticalSection(&PerfDataCriticalSection
);
941 PageSize
= SystemBasicInfo
.PageSize
;
942 SystemCache
= SystemCacheInfo
.CurrentSizeIncludingTransitionInPages
* PageSize
;
944 LeaveCriticalSection(&PerfDataCriticalSection
);
946 return SystemCache
/ 1024;
949 ULONG
PerfDataGetSystemHandleCount(void)
953 EnterCriticalSection(&PerfDataCriticalSection
);
955 HandleCount
= SystemHandleInfo
.NumberOfHandles
;
957 LeaveCriticalSection(&PerfDataCriticalSection
);
962 ULONG
PerfDataGetTotalThreadCount(void)
964 ULONG ThreadCount
= 0;
967 EnterCriticalSection(&PerfDataCriticalSection
);
969 for (i
=0; i
<ProcessCount
; i
++)
971 ThreadCount
+= pPerfData
[i
].ThreadCount
;
974 LeaveCriticalSection(&PerfDataCriticalSection
);
979 BOOL
PerfDataGet(ULONG Index
, PPERFDATA
*lppData
)
981 BOOL bSuccessful
= FALSE
;
983 EnterCriticalSection(&PerfDataCriticalSection
);
984 if (Index
< ProcessCount
)
986 *lppData
= pPerfData
+ Index
;
989 LeaveCriticalSection(&PerfDataCriticalSection
);