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