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