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.

352 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. proc.c
  5. Abstract:
  6. Code for dumping information about processes using the NT API rather than
  7. the win32 API.
  8. Environment:
  9. User mode only
  10. Revision History:
  11. 03-26-96 : Created
  12. --*/
  13. //
  14. // this module may be compiled at warning level 4 with the following
  15. // warnings disabled:
  16. //
  17. #pragma warning(disable:4200) // array[0]
  18. #pragma warning(disable:4201) // nameless struct/unions
  19. #pragma warning(disable:4214) // bit fields other than int
  20. #include <nt.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <windows.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <assert.h>
  28. #define PROCESS_BUFFER_INCREMENT (16 * 4096)
  29. PSYSTEM_PROCESS_INFORMATION ProcessInfo = NULL;
  30. DWORD ProcessInfoLength;
  31. VOID
  32. GetAllProcessInfo(
  33. VOID
  34. )
  35. {
  36. PSYSTEM_PROCESS_INFORMATION buffer;
  37. DWORD bufferSize = 1 * PROCESS_BUFFER_INCREMENT;
  38. NTSTATUS status;
  39. assert(ProcessInfo == NULL);
  40. do {
  41. buffer = LocalAlloc(LMEM_FIXED, bufferSize);
  42. if(buffer == NULL) {
  43. return;
  44. }
  45. status = NtQuerySystemInformation(SystemProcessInformation,
  46. buffer,
  47. bufferSize,
  48. &ProcessInfoLength);
  49. if(status == STATUS_INFO_LENGTH_MISMATCH) {
  50. LocalFree(buffer);
  51. bufferSize += PROCESS_BUFFER_INCREMENT;
  52. continue;
  53. }
  54. } while(status == STATUS_INFO_LENGTH_MISMATCH);
  55. if(NT_SUCCESS(status)) {
  56. ProcessInfo = buffer;
  57. }
  58. return;
  59. }
  60. VOID
  61. PrintProcessInfo(
  62. DWORD_PTR ProcessId
  63. )
  64. {
  65. PSYSTEM_PROCESS_INFORMATION info;
  66. if(ProcessInfo == NULL) {
  67. return;
  68. }
  69. info = ProcessInfo;
  70. do {
  71. if(ProcessId == (DWORD_PTR) info->UniqueProcessId) {
  72. printf(": %.*S",
  73. (info->ImageName.Length / 2),
  74. info->ImageName.Buffer);
  75. break;
  76. }
  77. info = (PSYSTEM_PROCESS_INFORMATION) (((ULONG_PTR) info) +
  78. info->NextEntryOffset);
  79. } while((ULONG_PTR) info <= (ULONG_PTR) ProcessInfo + ProcessInfoLength);
  80. return;
  81. }
  82. #if 0
  83. DWORD
  84. QueryDirectory(
  85. IN PSTRING DirectoryName
  86. )
  87. {
  88. NTSTATUS Status;
  89. HANDLE DirectoryHandle, LinkHandle;
  90. ULONG Context = 0;
  91. ULONG i, ReturnedLength;
  92. UNICODE_STRING LinkTarget;
  93. POBJECT_DIRECTORY_INFORMATION DirInfo;
  94. POBJECT_NAME_INFORMATION NameInfo;
  95. OBJECT_ATTRIBUTES Attributes;
  96. UNICODE_STRING UnicodeString;
  97. //
  98. // Perform initial setup
  99. //
  100. RtlZeroMemory( Buffer, BUFFERSIZE );
  101. //
  102. // Open the directory for list directory access
  103. //
  104. Status = RtlAnsiStringToUnicodeString(
  105. &UnicodeString,
  106. DirectoryName,
  107. TRUE
  108. );
  109. ASSERT(NT_SUCCESS(Status));
  110. InitializeObjectAttributes(&Attributes,
  111. &UnicodeString,
  112. OBJ_CASE_INSENSITIVE,
  113. NULL,
  114. NULL);
  115. Status = NtOpenDirectoryObject(&DirectoryHandle,
  116. DIRECTORY_QUERY,
  117. &Attributes);
  118. if(!NT_SUCCESS(Status)) {
  119. if (Status == STATUS_OBJECT_TYPE_MISMATCH) {
  120. printf("%Z is not a valid Object Directory Object name\n",
  121. DirectoryName );
  122. } else {
  123. printf("Error %#08lx opening %Z\n", Status, DirectoryName);
  124. }
  125. return;
  126. }
  127. //
  128. // Query the entire directory in one sweep
  129. //
  130. NumberOfDirEntries = 0;
  131. for (Status = NtQueryDirectoryObject( DirectoryHandle,
  132. &Buffer,
  133. BUFFERSIZE,
  134. FALSE,
  135. FALSE,
  136. &Context,
  137. &ReturnedLength );
  138. NT_SUCCESS( Status );
  139. Status = NtQueryDirectoryObject( DirectoryHandle,
  140. &Buffer,
  141. BUFFERSIZE,
  142. FALSE,
  143. FALSE,
  144. &Context,
  145. &ReturnedLength ) ) {
  146. //
  147. // Check the status of the operation.
  148. //
  149. if (!NT_SUCCESS( Status )) {
  150. if (Status != STATUS_NO_MORE_FILES) {
  151. Error( Status, Status );
  152. }
  153. break;
  154. }
  155. //
  156. // For every record in the buffer type out the directory information
  157. //
  158. //
  159. // Point to the first record in the buffer, we are guaranteed to have
  160. // one otherwise Status would have been No More Files
  161. //
  162. DirInfo = (POBJECT_DIRECTORY_INFORMATION) &Buffer[0];
  163. while (TRUE) {
  164. //
  165. // Check if there is another record. If there isn't, then get out
  166. // of the loop now
  167. //
  168. if (DirInfo->Name.Length == 0) {
  169. break;
  170. }
  171. //
  172. // Print out information about the file
  173. //
  174. if (NumberOfDirEntries >= MAX_DIR_ENTRIES) {
  175. printf( "OBJDIR: Too many directory entries.\n" );
  176. exit( 1 );
  177. }
  178. DirEntries[ NumberOfDirEntries ].Name = RtlAllocateHeap( RtlProcessHeap(),
  179. HEAP_ZERO_MEMORY,
  180. DirInfo->Name.Length +
  181. sizeof( UNICODE_NULL )
  182. );
  183. DirEntries[ NumberOfDirEntries ].Type = RtlAllocateHeap( RtlProcessHeap(),
  184. HEAP_ZERO_MEMORY,
  185. DirInfo->TypeName.Length +
  186. sizeof( UNICODE_NULL )
  187. );
  188. memmove( DirEntries[ NumberOfDirEntries ].Name,
  189. DirInfo->Name.Buffer,
  190. DirInfo->Name.Length
  191. );
  192. memmove( DirEntries[ NumberOfDirEntries ].Type,
  193. DirInfo->TypeName.Buffer,
  194. DirInfo->TypeName.Length
  195. );
  196. NumberOfDirEntries++;
  197. //
  198. // There is another record so advance DirInfo to the next entry
  199. //
  200. DirInfo = (POBJECT_DIRECTORY_INFORMATION) (((PUCHAR) DirInfo) +
  201. sizeof( OBJECT_DIRECTORY_INFORMATION ) );
  202. }
  203. RtlZeroMemory( Buffer, BUFFERSIZE );
  204. }
  205. qsort( DirEntries,
  206. NumberOfDirEntries,
  207. sizeof( DIR_ENTRY ),
  208. CompareDirEntry
  209. );
  210. for (i=0; i<NumberOfDirEntries; i++) {
  211. printf( "%-32ws ", DirEntries[ i ].Name);
  212. if (CompoundLineOutput) {
  213. printf("\n ");
  214. }
  215. printf( "%ws", DirEntries[ i ].Type );
  216. if (!wcscmp( DirEntries[ i ].Type, L"SymbolicLink" )) {
  217. RtlInitUnicodeString( &UnicodeString, DirEntries[ i ].Name );
  218. InitializeObjectAttributes( &Attributes,
  219. &UnicodeString,
  220. OBJ_CASE_INSENSITIVE,
  221. DirectoryHandle,
  222. NULL );
  223. Status = NtOpenSymbolicLinkObject( &LinkHandle,
  224. SYMBOLIC_LINK_QUERY,
  225. &Attributes
  226. );
  227. if (NT_SUCCESS( Status )) {
  228. LinkTarget.Buffer = LinkTargetBuffer;
  229. LinkTarget.Length = 0;
  230. LinkTarget.MaximumLength = sizeof( LinkTargetBuffer );
  231. Status = NtQuerySymbolicLinkObject( LinkHandle,
  232. &LinkTarget,
  233. NULL
  234. );
  235. NtClose( LinkHandle );
  236. }
  237. if (!NT_SUCCESS( Status )) {
  238. printf( " - unable to query link target (Status == %09X)\n", Status );
  239. }
  240. else {
  241. printf( " - %wZ\n", &LinkTarget );
  242. }
  243. }
  244. else {
  245. printf( "\n" );
  246. }
  247. }
  248. //
  249. // Output final messages
  250. //
  251. if (NumberOfDirEntries == 0) {
  252. printf( "no entries\n" );
  253. }
  254. else
  255. if (NumberOfDirEntries == 1) {
  256. printf( "\n1 entry\n" );
  257. }
  258. else {
  259. printf( "\n%ld entries\n", NumberOfDirEntries );
  260. }
  261. //
  262. // Now close the directory object
  263. //
  264. (VOID) NtClose( DirectoryHandle );
  265. //
  266. // And return to our caller
  267. //
  268. return;
  269. }
  270. #endif