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.

334 lines
7.7 KiB

  1. #include "pwalker.h"
  2. #pragma hdrstop
  3. #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
  4. //
  5. // Unicode strings are counted 16-bit character strings. If they are
  6. // NULL terminated, Length does not include trailing NULL.
  7. //
  8. typedef struct _UNICODE_STRING {
  9. USHORT Length;
  10. USHORT MaximumLength;
  11. PWSTR Buffer;
  12. } UNICODE_STRING;
  13. typedef LONG KPRIORITY;
  14. typedef struct _SYSTEM_PROCESS_INFORMATION {
  15. ULONG NextEntryOffset;
  16. ULONG NumberOfThreads;
  17. LARGE_INTEGER SpareLi1;
  18. LARGE_INTEGER SpareLi2;
  19. LARGE_INTEGER SpareLi3;
  20. LARGE_INTEGER CreateTime;
  21. LARGE_INTEGER UserTime;
  22. LARGE_INTEGER KernelTime;
  23. UNICODE_STRING ImageName;
  24. KPRIORITY BasePriority;
  25. HANDLE UniqueProcessId;
  26. HANDLE InheritedFromUniqueProcessId;
  27. ULONG HandleCount;
  28. ULONG SpareUl2;
  29. ULONG SpareUl3;
  30. ULONG PeakVirtualSize;
  31. ULONG VirtualSize;
  32. ULONG PageFaultCount;
  33. ULONG PeakWorkingSetSize;
  34. ULONG WorkingSetSize;
  35. ULONG QuotaPeakPagedPoolUsage;
  36. ULONG QuotaPagedPoolUsage;
  37. ULONG QuotaPeakNonPagedPoolUsage;
  38. ULONG QuotaNonPagedPoolUsage;
  39. ULONG PagefileUsage;
  40. ULONG PeakPagefileUsage;
  41. ULONG PrivatePageCount;
  42. } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
  43. typedef LONG NTSTATUS;
  44. typedef enum _SYSTEM_INFORMATION_CLASS {
  45. SystemBasicInformation,
  46. SystemProcessorInformation, // obsolete...delete
  47. SystemPerformanceInformation,
  48. SystemTimeOfDayInformation,
  49. SystemPathInformation,
  50. SystemProcessInformation,
  51. SystemCallCountInformation,
  52. SystemDeviceInformation,
  53. SystemProcessorPerformanceInformation,
  54. SystemFlagsInformation,
  55. SystemCallTimeInformation,
  56. SystemModuleInformation,
  57. SystemLocksInformation,
  58. SystemStackTraceInformation,
  59. SystemPagedPoolInformation,
  60. SystemNonPagedPoolInformation,
  61. SystemHandleInformation,
  62. SystemObjectInformation,
  63. SystemPageFileInformation,
  64. SystemVdmInstemulInformation,
  65. SystemVdmBopInformation,
  66. SystemFileCacheInformation,
  67. SystemPoolTagInformation,
  68. SystemInterruptInformation,
  69. SystemDpcBehaviorInformation,
  70. SystemFullMemoryInformation,
  71. SystemLoadGdiDriverInformation,
  72. SystemUnloadGdiDriverInformation,
  73. SystemTimeAdjustmentInformation,
  74. SystemSummaryMemoryInformation,
  75. SystemUnused1,
  76. SystemUnused2,
  77. SystemCrashDumpInformation,
  78. SystemExceptionInformation,
  79. SystemCrashDumpStateInformation,
  80. SystemKernelDebuggerInformation,
  81. SystemContextSwitchInformation,
  82. SystemRegistryQuotaInformation,
  83. SystemExtendServiceTableInformation,
  84. SystemPrioritySeperation,
  85. SystemUnused3,
  86. SystemUnused4,
  87. SystemUnused5,
  88. SystemUnused6,
  89. SystemCurrentTimeZoneInformation,
  90. SystemLookasideInformation,
  91. SystemTimeSlipNotification
  92. } SYSTEM_INFORMATION_CLASS;
  93. #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
  94. typedef NTSTATUS (NTAPI * FN_NTQUERYSYSTEMINFORMATION)(
  95. IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
  96. OUT PVOID SystemInformation,
  97. IN ULONG SystemInformationLength,
  98. OUT PULONG ReturnLength OPTIONAL
  99. );
  100. //
  101. // Task list structure as returned by GetTaskList().
  102. //
  103. typedef struct _TASK_LISTA
  104. {
  105. DWORD dwProcessId;
  106. DWORD dwParentProcessId;
  107. DWORD dwPriority;
  108. DWORD dwThreadCount;
  109. CHAR ProcessName[MAX_PATH];
  110. } TASK_LISTA, *PTASK_LISTA, FAR *LPTASK_LISTA;
  111. typedef struct _TASK_LISTW
  112. {
  113. DWORD dwProcessId;
  114. DWORD dwParentProcessId;
  115. DWORD dwPriority;
  116. DWORD dwThreadCount;
  117. WCHAR ProcessName[MAX_PATH];
  118. } TASK_LISTW, *PTASK_LISTW, FAR *LPTASK_LISTW;
  119. #ifdef UNICODE
  120. #define TASK_LIST TASK_LISTW
  121. #define LPTASK_LIST LPTASK_LISTW
  122. #else
  123. #define TASK_LIST TASK_LISTA
  124. #define LPTASK_LIST LPTASK_LISTA
  125. #endif
  126. #define CKMP_ALLOC(cb) (VOID *)LocalAlloc( LPTR, (cb) )
  127. #define CKMP_REALLOC(p,cb) (VOID *)LocalReAlloc( (HLOCAL)p, (cb), LPTR )
  128. #define CKMP_FREE(p) LocalFree( (HLOCAL)(p) )
  129. #define INITIAL_SIZE 65536
  130. #define EXTEND_SIZE 32768
  131. HLOCAL
  132. GetLocalTaskListNt(
  133. LPDWORD pdwNumTasks
  134. )
  135. {
  136. LPTASK_LISTW pTaskListW;
  137. PSYSTEM_PROCESS_INFORMATION processInfo;
  138. PSYSTEM_PROCESS_INFORMATION processScan;
  139. NTSTATUS status;
  140. ULONG bufferSize;
  141. ULONG totalOffset;
  142. ULONG processCount;
  143. ULONG i;
  144. FN_NTQUERYSYSTEMINFORMATION _pfnNtQuerySystemInformation = NULL;
  145. HMODULE hNtdll;
  146. hNtdll = GetModuleHandleA( "NTDLL.DLL" );
  147. if( hNtdll != NULL )
  148. {
  149. _pfnNtQuerySystemInformation = (FN_NTQUERYSYSTEMINFORMATION)
  150. GetProcAddress( hNtdll, "NtQuerySystemInformation" );
  151. }
  152. //
  153. // Bail if we couldn't find the entrypoint.
  154. //
  155. if( _pfnNtQuerySystemInformation == NULL ) {
  156. return NULL;
  157. }
  158. //
  159. // Read the process info.
  160. //
  161. bufferSize = INITIAL_SIZE;
  162. retry:
  163. processInfo = CKMP_ALLOC( bufferSize );
  164. if( processInfo == NULL ) {
  165. return NULL;
  166. }
  167. status = _pfnNtQuerySystemInformation(
  168. SystemProcessInformation,
  169. processInfo,
  170. bufferSize,
  171. NULL
  172. );
  173. if( status == STATUS_INFO_LENGTH_MISMATCH ) {
  174. CKMP_FREE( processInfo );
  175. bufferSize += EXTEND_SIZE;
  176. goto retry;
  177. }
  178. if( !NT_SUCCESS(status) ) {
  179. return NULL;
  180. }
  181. //
  182. // Count the number of active processes.
  183. //
  184. processCount = 0;
  185. totalOffset = 0;
  186. processScan = processInfo;
  187. for( ; ; ) {
  188. processCount++;
  189. if( processScan->NextEntryOffset == 0 ) {
  190. break;
  191. }
  192. totalOffset += processScan->NextEntryOffset;
  193. processScan = (PVOID)( (PCHAR)processInfo + totalOffset );
  194. }
  195. //
  196. // Now allocate the user's buffer.
  197. //
  198. pTaskListW = CKMP_ALLOC( processCount * sizeof(*pTaskListW) );
  199. if( pTaskListW == NULL ) {
  200. CKMP_FREE( processInfo );
  201. return NULL;
  202. }
  203. //
  204. // And map 'em over.
  205. //
  206. totalOffset = 0;
  207. processScan = processInfo;
  208. for( i = 0 ; i < processCount ; i++ ) {
  209. PWCHAR name;
  210. ULONG len;
  211. pTaskListW[i].dwProcessId = (DWORD)processScan->UniqueProcessId;
  212. pTaskListW[i].dwParentProcessId = (DWORD)processScan->InheritedFromUniqueProcessId;
  213. pTaskListW[i].dwPriority = (DWORD)processScan->BasePriority;
  214. pTaskListW[i].dwThreadCount = (DWORD)processScan->NumberOfThreads;
  215. if( processScan->ImageName.Buffer == NULL ) {
  216. name = L"Idle";
  217. len = sizeof( L"Idle" ) - sizeof(WCHAR);
  218. } else {
  219. name = processScan->ImageName.Buffer;
  220. len = processScan->ImageName.Length;
  221. }
  222. RtlCopyMemory(
  223. pTaskListW[i].ProcessName,
  224. name,
  225. len
  226. );
  227. pTaskListW[i].ProcessName[len / sizeof(WCHAR)] = L'\0';
  228. totalOffset += processScan->NextEntryOffset;
  229. processScan = (PVOID)( (PCHAR)processInfo + totalOffset );
  230. }
  231. //
  232. // Cleanup & we're outta here.
  233. //
  234. *pdwNumTasks = (DWORD)processCount;
  235. CKMP_FREE( processInfo );
  236. return (HLOCAL) pTaskListW;
  237. } // GetLocalTaskListNt
  238. BOOL
  239. GetLocalTaskNameNt(
  240. HLOCAL hTaskList,
  241. DWORD dwItem,
  242. LPSTR lpszTaskName,
  243. DWORD cbMaxTaskName
  244. )
  245. {
  246. LPTASK_LISTW pTaskListW = (LPTASK_LISTW) hTaskList;
  247. BOOL success;
  248. success = WideCharToMultiByte( CP_ACP, 0,
  249. pTaskListW[dwItem].ProcessName, -1,
  250. lpszTaskName, cbMaxTaskName, NULL, NULL );
  251. return success;
  252. }
  253. DWORD
  254. GetLocalTaskProcessIdNt(
  255. HLOCAL hTaskList,
  256. DWORD dwItem
  257. )
  258. {
  259. LPTASK_LISTW pTaskListW = (LPTASK_LISTW) hTaskList;
  260. return pTaskListW[dwItem]. dwProcessId;
  261. }
  262. void
  263. FreeLocalTaskListNt(
  264. HLOCAL hTaskList
  265. )
  266. {
  267. CKMP_FREE( hTaskList );
  268. }