Source code of Windows XP (NT5)
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.

356 lines
8.1 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include "psapi.h"
  6. #include <stddef.h>
  7. BOOL
  8. WINAPI
  9. EnumProcesses(
  10. DWORD * lpidProcess,
  11. DWORD cb,
  12. LPDWORD lpcbNeeded
  13. )
  14. {
  15. DWORD cbProcessInformation;
  16. LPVOID pvProcessInformation;
  17. NTSTATUS Status;
  18. DWORD ibCur, i;
  19. DWORD cdwMax;
  20. DWORD TotalOffset;
  21. cbProcessInformation = 32768;
  22. Retry:
  23. pvProcessInformation = LocalAlloc(LMEM_FIXED, cbProcessInformation);
  24. if (pvProcessInformation == NULL) {
  25. return(FALSE);
  26. }
  27. Status = NtQuerySystemInformation(
  28. SystemProcessInformation,
  29. pvProcessInformation,
  30. cbProcessInformation,
  31. NULL
  32. );
  33. if ( Status == STATUS_INFO_LENGTH_MISMATCH ) {
  34. LocalFree((HLOCAL) pvProcessInformation);
  35. cbProcessInformation += 32768;
  36. goto Retry;
  37. }
  38. if ( !NT_SUCCESS(Status) ) {
  39. SetLastError( RtlNtStatusToDosError( Status ) );
  40. return(FALSE);
  41. }
  42. TotalOffset = 0;
  43. ibCur = 0;
  44. cdwMax = cb / sizeof(DWORD);
  45. i = 0;
  46. for (;;) {
  47. PSYSTEM_PROCESS_INFORMATION pProcessInformation;
  48. pProcessInformation = (PSYSTEM_PROCESS_INFORMATION)
  49. ((BYTE *) pvProcessInformation + TotalOffset);
  50. if (i < cdwMax) {
  51. try {
  52. lpidProcess[i] = HandleToUlong(pProcessInformation->UniqueProcessId);
  53. }
  54. except (EXCEPTION_EXECUTE_HANDLER) {
  55. LocalFree((HLOCAL) pvProcessInformation);
  56. SetLastError( RtlNtStatusToDosError( GetExceptionCode() ) );
  57. return(FALSE);
  58. }
  59. i++;
  60. }
  61. ibCur = pProcessInformation->NextEntryOffset;
  62. TotalOffset += ibCur;
  63. if (ibCur == 0) {
  64. break;
  65. }
  66. };
  67. try {
  68. *lpcbNeeded = i * sizeof(DWORD);
  69. }
  70. except (EXCEPTION_EXECUTE_HANDLER) {
  71. LocalFree((HLOCAL) pvProcessInformation);
  72. SetLastError( RtlNtStatusToDosError( GetExceptionCode() ) );
  73. return(FALSE);
  74. }
  75. LocalFree((HLOCAL) pvProcessInformation);
  76. return(TRUE);
  77. }
  78. BOOL
  79. WINAPI
  80. GetProcessMemoryInfo (
  81. HANDLE hProcess,
  82. PPROCESS_MEMORY_COUNTERS ppsmemCounters,
  83. DWORD cb
  84. )
  85. /*++
  86. Routine Description:
  87. This function returns all the PSVM_COUNTERS for a process.
  88. Arguments:
  89. hProcess - Handle for the process being queried.
  90. ppsmemCounters - Points to buffer that will receive the PROCESS_MEMORY_COUNTERS.
  91. cb - size of ppsmemCounters
  92. Return Value:
  93. The return value is TRUE or FALSE.
  94. --*/
  95. {
  96. NTSTATUS Status;
  97. VM_COUNTERS_EX VmCounters;
  98. BOOL fEx;
  99. // Try to feel if the ptr passed is NULL and if not,
  100. // is it long enough for us.
  101. try {
  102. ppsmemCounters->PeakPagefileUsage = 0;
  103. }
  104. except (EXCEPTION_EXECUTE_HANDLER) {
  105. SetLastError( RtlNtStatusToDosError( GetExceptionCode() ) );
  106. return(FALSE);
  107. }
  108. if (cb < sizeof(PROCESS_MEMORY_COUNTERS)) {
  109. SetLastError( ERROR_INSUFFICIENT_BUFFER );
  110. return(FALSE);
  111. } else if (cb < sizeof(PROCESS_MEMORY_COUNTERS_EX)) {
  112. fEx = FALSE;
  113. } else {
  114. fEx = TRUE;
  115. }
  116. Status = NtQueryInformationProcess(
  117. hProcess,
  118. ProcessVmCounters,
  119. &VmCounters,
  120. sizeof(VmCounters),
  121. NULL
  122. );
  123. if ( !NT_SUCCESS(Status) )
  124. {
  125. SetLastError( RtlNtStatusToDosError( Status ) );
  126. return( FALSE );
  127. }
  128. if (fEx) {
  129. ppsmemCounters->cb = sizeof(PROCESS_MEMORY_COUNTERS_EX);
  130. } else {
  131. ppsmemCounters->cb = sizeof(PROCESS_MEMORY_COUNTERS);
  132. }
  133. ppsmemCounters->PageFaultCount = VmCounters.PageFaultCount;
  134. ppsmemCounters->PeakWorkingSetSize = VmCounters.PeakWorkingSetSize;
  135. ppsmemCounters->WorkingSetSize = VmCounters.WorkingSetSize;
  136. ppsmemCounters->QuotaPeakPagedPoolUsage = VmCounters.QuotaPeakPagedPoolUsage;
  137. ppsmemCounters->QuotaPagedPoolUsage = VmCounters.QuotaPagedPoolUsage;
  138. ppsmemCounters->QuotaPeakNonPagedPoolUsage = VmCounters.QuotaPeakNonPagedPoolUsage;
  139. ppsmemCounters->QuotaNonPagedPoolUsage = VmCounters.QuotaNonPagedPoolUsage;
  140. ppsmemCounters->PagefileUsage = VmCounters.PagefileUsage;
  141. ppsmemCounters->PeakPagefileUsage = VmCounters.PeakPagefileUsage;
  142. if (fEx) {
  143. ((PPROCESS_MEMORY_COUNTERS_EX)ppsmemCounters)->PrivateUsage = VmCounters.PrivateUsage;
  144. }
  145. return(TRUE);
  146. }
  147. BOOL
  148. WINAPI
  149. InitializeProcessForWsWatch(
  150. HANDLE hProcess
  151. )
  152. {
  153. NTSTATUS Status;
  154. Status = NtSetInformationProcess(
  155. hProcess,
  156. ProcessWorkingSetWatch,
  157. NULL,
  158. 0
  159. );
  160. if ( NT_SUCCESS(Status) || Status == STATUS_PORT_ALREADY_SET || Status == STATUS_ACCESS_DENIED ) {
  161. return TRUE;
  162. }
  163. else {
  164. SetLastError( RtlNtStatusToDosError( Status ) );
  165. return FALSE;
  166. }
  167. }
  168. BOOL
  169. WINAPI
  170. GetWsChanges(
  171. HANDLE hProcess,
  172. PPSAPI_WS_WATCH_INFORMATION lpWatchInfo,
  173. DWORD cb
  174. )
  175. {
  176. NTSTATUS Status;
  177. Status = NtQueryInformationProcess(
  178. hProcess,
  179. ProcessWorkingSetWatch,
  180. (PVOID *)lpWatchInfo,
  181. cb,
  182. NULL
  183. );
  184. if ( NT_SUCCESS(Status) ) {
  185. return TRUE;
  186. }
  187. else {
  188. SetLastError( RtlNtStatusToDosError( Status ) );
  189. return FALSE;
  190. }
  191. }
  192. DWORD
  193. WINAPI
  194. GetProcessImageFileNameW(
  195. HANDLE hProcess,
  196. LPWSTR lpImageFileName,
  197. DWORD nSize
  198. )
  199. {
  200. PUNICODE_STRING Buffer;
  201. ULONG BufferSize,
  202. ReturnLength;
  203. NTSTATUS Status;
  204. BufferSize = sizeof(UNICODE_STRING) + nSize * 2;
  205. Buffer = LocalAlloc(LMEM_FIXED, BufferSize);
  206. if (! Buffer) {
  207. ReturnLength = 0;
  208. goto cleanup;
  209. }
  210. Status = NtQueryInformationProcess(hProcess,
  211. ProcessImageFileName,
  212. Buffer,
  213. BufferSize,
  214. NULL);
  215. if (Status == STATUS_INFO_LENGTH_MISMATCH) {
  216. Status = STATUS_BUFFER_TOO_SMALL;
  217. }
  218. if (! NT_SUCCESS(Status)) {
  219. SetLastError( RtlNtStatusToDosError( Status ) );
  220. ReturnLength = 0;
  221. goto cleanup_buffer;
  222. }
  223. RtlCopyMemory(lpImageFileName,
  224. Buffer->Buffer,
  225. Buffer->Length);
  226. ReturnLength = Buffer->Length >> 1;
  227. if (ReturnLength < nSize) {
  228. lpImageFileName[ReturnLength] = UNICODE_NULL;
  229. }
  230. cleanup_buffer:
  231. LocalFree((HLOCAL) Buffer);
  232. cleanup:
  233. return ReturnLength;
  234. }
  235. DWORD
  236. WINAPI
  237. GetProcessImageFileNameA(
  238. HANDLE hProcess,
  239. LPSTR lpImageFileName,
  240. DWORD nSize
  241. )
  242. {
  243. PUNICODE_STRING Buffer;
  244. ULONG BufferSize,
  245. ReturnLength;
  246. NTSTATUS Status;
  247. BufferSize = sizeof(UNICODE_STRING) + nSize * 2;
  248. Buffer = LocalAlloc(LMEM_FIXED, BufferSize);
  249. if (! Buffer) {
  250. ReturnLength = 0;
  251. goto cleanup;
  252. }
  253. Status = NtQueryInformationProcess(hProcess,
  254. ProcessImageFileName,
  255. Buffer,
  256. BufferSize,
  257. NULL);
  258. if (Status == STATUS_INFO_LENGTH_MISMATCH) {
  259. Status = STATUS_BUFFER_TOO_SMALL;
  260. }
  261. if (! NT_SUCCESS(Status)) {
  262. SetLastError( RtlNtStatusToDosError( Status ) );
  263. ReturnLength = 0;
  264. goto cleanup_buffer;
  265. }
  266. ReturnLength = WideCharToMultiByte(CP_ACP,
  267. 0,
  268. Buffer->Buffer,
  269. Buffer->Length,
  270. lpImageFileName,
  271. nSize,
  272. NULL,
  273. NULL);
  274. if (ReturnLength) {
  275. //
  276. // WideCharToMultiByte includes the trailing NULL in its
  277. // count; we do not.
  278. //
  279. --ReturnLength;
  280. }
  281. cleanup_buffer:
  282. LocalFree((HLOCAL) Buffer);
  283. cleanup:
  284. return ReturnLength;
  285. }