Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. psenum.c
  5. Abstract:
  6. This module returns various performance values
  7. Author:
  8. Neill clift (NeillC) 23-Jul-2000
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include "psapi.h"
  16. BOOL
  17. WINAPI
  18. GetPerformanceInfo (
  19. PPERFORMANCE_INFORMATION pPerformanceInformation,
  20. DWORD cb
  21. )
  22. /*++
  23. Routine Description:
  24. The routine gets some performance values.
  25. Arguments:
  26. pPerformanceInformation - A block out performance values that are returned.
  27. Return Value:
  28. BOOL - Returns TRUE is the function was successfull FALSE otherwise
  29. --*/
  30. {
  31. NTSTATUS Status;
  32. SYSTEM_BASIC_INFORMATION BasicInfo;
  33. SYSTEM_PERFORMANCE_INFORMATION PerfInfo;
  34. SYSTEM_FILECACHE_INFORMATION FileCache;
  35. PSYSTEM_PROCESS_INFORMATION ProcInfo, tProcInfo;
  36. ULONG BufferLength, RetLen;
  37. ULONG Processes;
  38. ULONG Threads;
  39. ULONG Handles;
  40. if (cb < sizeof (PERFORMANCE_INFORMATION)) {
  41. SetLastError (RtlNtStatusToDosError (STATUS_INFO_LENGTH_MISMATCH));
  42. return FALSE;
  43. }
  44. Status = NtQuerySystemInformation (SystemBasicInformation,
  45. &BasicInfo,
  46. sizeof(BasicInfo),
  47. NULL);
  48. if (!NT_SUCCESS (Status)) {
  49. SetLastError (RtlNtStatusToDosError (Status));
  50. return FALSE;
  51. }
  52. Status = NtQuerySystemInformation (SystemPerformanceInformation,
  53. &PerfInfo,
  54. sizeof(PerfInfo),
  55. NULL);
  56. if (!NT_SUCCESS (Status)) {
  57. SetLastError (RtlNtStatusToDosError (Status));
  58. return FALSE;
  59. }
  60. Status = NtQuerySystemInformation (SystemFileCacheInformation,
  61. &FileCache,
  62. sizeof(FileCache),
  63. NULL);
  64. if (!NT_SUCCESS (Status)) {
  65. SetLastError (RtlNtStatusToDosError (Status));
  66. return FALSE;
  67. }
  68. BufferLength = 4096;
  69. while (1) {
  70. ProcInfo = LocalAlloc (LMEM_FIXED, BufferLength);
  71. if (ProcInfo == NULL) {
  72. SetLastError (RtlNtStatusToDosError (STATUS_INSUFFICIENT_RESOURCES));
  73. return FALSE;
  74. }
  75. Status = NtQuerySystemInformation (SystemProcessInformation,
  76. ProcInfo,
  77. BufferLength,
  78. &RetLen);
  79. if (NT_SUCCESS (Status)) {
  80. break;
  81. }
  82. LocalFree (ProcInfo);
  83. if (Status == STATUS_INFO_LENGTH_MISMATCH) {
  84. if (RetLen > BufferLength) {
  85. BufferLength = RetLen;
  86. } else {
  87. BufferLength += 4096;
  88. }
  89. } else {
  90. SetLastError (RtlNtStatusToDosError (Status));
  91. return FALSE;
  92. }
  93. }
  94. Processes = 0;
  95. Threads = 0;
  96. Handles = 0;
  97. tProcInfo = ProcInfo;
  98. while (RetLen > sizeof (SYSTEM_PROCESS_INFORMATION)) {
  99. Processes += 1;
  100. Threads += tProcInfo->NumberOfThreads;
  101. Handles += tProcInfo->HandleCount;
  102. if (tProcInfo->NextEntryOffset == 0 || tProcInfo->NextEntryOffset > RetLen) {
  103. break;
  104. }
  105. RetLen -= tProcInfo->NextEntryOffset;
  106. tProcInfo = (PSYSTEM_PROCESS_INFORMATION) ((PUCHAR) tProcInfo + tProcInfo->NextEntryOffset);
  107. }
  108. LocalFree (ProcInfo);
  109. pPerformanceInformation->cb = sizeof (PERFORMANCE_INFORMATION);
  110. pPerformanceInformation->CommitTotal = PerfInfo.CommittedPages;
  111. pPerformanceInformation->CommitLimit = PerfInfo.CommitLimit;
  112. pPerformanceInformation->CommitPeak = PerfInfo.PeakCommitment;
  113. pPerformanceInformation->PhysicalTotal = BasicInfo.NumberOfPhysicalPages;
  114. pPerformanceInformation->PhysicalAvailable = PerfInfo.AvailablePages;
  115. pPerformanceInformation->SystemCache = FileCache.CurrentSizeIncludingTransitionInPages;
  116. pPerformanceInformation->KernelTotal = PerfInfo.PagedPoolPages + PerfInfo.NonPagedPoolPages;
  117. pPerformanceInformation->KernelPaged = PerfInfo.PagedPoolPages;
  118. pPerformanceInformation->KernelNonpaged = PerfInfo.NonPagedPoolPages;
  119. pPerformanceInformation->PageSize = BasicInfo.PageSize;
  120. pPerformanceInformation->HandleCount = Handles;
  121. pPerformanceInformation->ProcessCount = Processes;
  122. pPerformanceInformation->ThreadCount = Threads;
  123. return TRUE;
  124. }
  125. BOOL
  126. WINAPI
  127. EnumPageFilesW (
  128. PENUM_PAGE_FILE_CALLBACKW pCallBackRoutine,
  129. LPVOID pContext
  130. )
  131. /*++
  132. Routine Description:
  133. The routine calls the callback routine for each installed page file in the system
  134. Arguments:
  135. pCallBackRoutine - Routine called for each pagefile
  136. pContext - Context value provided by the user and passed to the call back routine.
  137. Return Value:
  138. BOOL - Returns TRUE is the function was successfull FALSE otherwise
  139. --*/
  140. {
  141. NTSTATUS Status;
  142. ULONG BufferLength, RetLen;
  143. PSYSTEM_PAGEFILE_INFORMATION PageFileInfo, tPageFileInfo;
  144. BufferLength = 4096;
  145. while (1) {
  146. PageFileInfo = LocalAlloc (LMEM_FIXED, BufferLength);
  147. if (PageFileInfo == NULL) {
  148. SetLastError (RtlNtStatusToDosError (STATUS_INSUFFICIENT_RESOURCES));
  149. return FALSE;
  150. }
  151. Status = NtQuerySystemInformation (SystemPageFileInformation,
  152. PageFileInfo,
  153. BufferLength,
  154. &RetLen);
  155. if (NT_SUCCESS (Status)) {
  156. break;
  157. }
  158. LocalFree (PageFileInfo);
  159. if (Status == STATUS_INFO_LENGTH_MISMATCH) {
  160. if (RetLen > BufferLength) {
  161. BufferLength = RetLen;
  162. } else {
  163. BufferLength += 4096;
  164. }
  165. } else {
  166. SetLastError (RtlNtStatusToDosError (Status));
  167. return FALSE;
  168. }
  169. }
  170. tPageFileInfo = PageFileInfo;
  171. while (RetLen > sizeof (SYSTEM_PAGEFILE_INFORMATION)) {
  172. ENUM_PAGE_FILE_INFORMATION pfi;
  173. PWCHAR pWc;
  174. pfi.cb = sizeof (ENUM_PAGE_FILE_INFORMATION);
  175. pfi.Reserved = 0;
  176. pfi.TotalSize = tPageFileInfo->TotalSize;
  177. pfi.TotalInUse = tPageFileInfo->TotalInUse;
  178. pfi.PeakUsage = tPageFileInfo->PeakUsage;
  179. pWc = wcschr (tPageFileInfo->PageFileName.Buffer, L':');
  180. if (pWc != NULL && pWc > tPageFileInfo->PageFileName.Buffer) {
  181. pWc--;
  182. pCallBackRoutine (pContext, &pfi, pWc);
  183. }
  184. if (tPageFileInfo->NextEntryOffset == 0 || tPageFileInfo->NextEntryOffset > RetLen) {
  185. break;
  186. }
  187. RetLen -= tPageFileInfo->NextEntryOffset;
  188. tPageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION) ((PUCHAR) tPageFileInfo +
  189. tPageFileInfo->NextEntryOffset);
  190. }
  191. LocalFree (PageFileInfo);
  192. return TRUE;
  193. }
  194. typedef struct _ENUM_PAGE_FILE_CONV_CTX {
  195. LPVOID Ctx;
  196. PENUM_PAGE_FILE_CALLBACKA CallBack;
  197. DWORD LastError;
  198. } ENUM_PAGE_FILE_CONV_CTX, *PENUM_PAGE_FILE_CONV_CTX;
  199. BOOL
  200. CallBackConvertToAscii (
  201. LPVOID pContext,
  202. PENUM_PAGE_FILE_INFORMATION pPageFileInfo,
  203. LPCWSTR lpFilename
  204. )
  205. {
  206. DWORD Len;
  207. LPSTR AsciiStr;
  208. PENUM_PAGE_FILE_CONV_CTX Ctx = pContext;
  209. BOOL RetVal;
  210. Len = wcslen (lpFilename) + 1;
  211. AsciiStr = LocalAlloc (LMEM_FIXED, Len);
  212. if (AsciiStr == NULL) {
  213. Ctx->LastError = RtlNtStatusToDosError (STATUS_INSUFFICIENT_RESOURCES);
  214. return FALSE;
  215. }
  216. if (WideCharToMultiByte (CP_ACP, 0, lpFilename, -1, AsciiStr, Len, NULL, NULL)) {
  217. RetVal = Ctx->CallBack (Ctx->Ctx, pPageFileInfo, AsciiStr);
  218. } else {
  219. Ctx->LastError = GetLastError ();
  220. RetVal = FALSE;
  221. }
  222. LocalFree (AsciiStr);
  223. return RetVal;
  224. }
  225. BOOL
  226. WINAPI
  227. EnumPageFilesA (
  228. PENUM_PAGE_FILE_CALLBACKA pCallBackRoutine,
  229. LPVOID pContext
  230. )
  231. /*++
  232. Routine Description:
  233. The routine calls the callback routine for each installed page file in the system
  234. Arguments:
  235. pCallBackRoutine - Routine called for each pagefile
  236. pContext - Context value provided by the user and passed to the call back routine.
  237. Return Value:
  238. BOOL - Returns TRUE is the function was successfull FALSE otherwise
  239. --*/
  240. {
  241. ENUM_PAGE_FILE_CONV_CTX Ctx;
  242. BOOL RetVal;
  243. Ctx.Ctx = pContext;
  244. Ctx.CallBack = pCallBackRoutine;
  245. Ctx.LastError = 0;
  246. RetVal = EnumPageFilesW (CallBackConvertToAscii,
  247. &Ctx);
  248. if (RetVal) {
  249. //
  250. // See if our conversion routine encountered an error. If it doid then return this to the caller
  251. //
  252. if (Ctx.LastError != 0) {
  253. RetVal = FALSE;
  254. SetLastError (Ctx.LastError);
  255. }
  256. }
  257. return RetVal;
  258. }