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.

821 lines
23 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. pstat.c
  5. Abstract:
  6. This module contains the Windows NT process/thread status display.
  7. Author:
  8. Lou Perazzoli (LouP) 25-Oct-1991
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <assert.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19. #include <time.h>
  20. #include <stdlib.h>
  21. #define BUFFER_SIZE 64*1024
  22. #define MAX_BUFFER_SIZE 10*1024*1024
  23. VOID
  24. PrintLoadedDrivers(
  25. VOID
  26. );
  27. ULONG CurrentBufferSize;
  28. UCHAR *StateTable[] = {
  29. "Initialized",
  30. "Ready",
  31. "Running",
  32. "Standby",
  33. "Terminated",
  34. "Wait:",
  35. "Transition",
  36. "Unknown",
  37. "Unknown",
  38. "Unknown",
  39. "Unknown",
  40. "Unknown"
  41. };
  42. UCHAR *WaitTable[] = {
  43. "Executive",
  44. "FreePage",
  45. "PageIn",
  46. "PoolAllocation",
  47. "DelayExecution",
  48. "Suspended",
  49. "UserRequest",
  50. "Executive",
  51. "FreePage",
  52. "PageIn",
  53. "PoolAllocation",
  54. "DelayExecution",
  55. "Suspended",
  56. "UserRequest",
  57. "EventPairHigh",
  58. "EventPairLow",
  59. "LpcReceive",
  60. "LpcReply",
  61. "VirtualMemory",
  62. "PageOut",
  63. "Spare1",
  64. "Spare2",
  65. "Spare3",
  66. "Spare4",
  67. "Spare5",
  68. "Spare6",
  69. "Spare7",
  70. "Unknown",
  71. "Unknown",
  72. "Unknown"
  73. };
  74. UCHAR *Empty = " ";
  75. BOOLEAN fUserOnly = TRUE;
  76. BOOLEAN fSystemOnly = TRUE;
  77. BOOLEAN fVerbose = FALSE;
  78. BOOLEAN fPrintIt;
  79. int
  80. __cdecl
  81. main(
  82. int argc,
  83. char *argv[]
  84. )
  85. {
  86. PSYSTEM_PROCESS_INFORMATION ProcessInfo;
  87. PSYSTEM_THREAD_INFORMATION ThreadInfo;
  88. PUCHAR LargeBuffer1;
  89. NTSTATUS status;
  90. NTSTATUS Status;
  91. ULONG i;
  92. ULONG TotalOffset = 0;
  93. TIME_FIELDS UserTime;
  94. TIME_FIELDS KernelTime;
  95. TIME_FIELDS UpTime;
  96. SYSTEM_BASIC_INFORMATION BasicInfo;
  97. SYSTEM_TIMEOFDAY_INFORMATION TimeOfDayInfo;
  98. PSYSTEM_PAGEFILE_INFORMATION PageFileInfo;
  99. LARGE_INTEGER Time;
  100. LPSTR lpstrCmd;
  101. CHAR ch;
  102. ANSI_STRING pname;
  103. SYSTEM_PERFORMANCE_INFORMATION PerfInfo;
  104. SYSTEM_FILECACHE_INFORMATION FileCache;
  105. SIZE_T SumCommit;
  106. SIZE_T SumWorkingSet;
  107. SetFileApisToOEM();
  108. lpstrCmd = GetCommandLine();
  109. if( lpstrCmd != NULL ) {
  110. CharToOem( lpstrCmd, lpstrCmd );
  111. }
  112. LargeBuffer1 = VirtualAlloc (NULL,
  113. MAX_BUFFER_SIZE,
  114. MEM_RESERVE,
  115. PAGE_READWRITE);
  116. if (LargeBuffer1 == NULL) {
  117. printf("Memory allocation failed\n");
  118. return 0;
  119. }
  120. if (VirtualAlloc (LargeBuffer1,
  121. BUFFER_SIZE,
  122. MEM_COMMIT,
  123. PAGE_READWRITE) == NULL) {
  124. printf("Memory commit failed\n");
  125. return 0;
  126. }
  127. CurrentBufferSize = BUFFER_SIZE;
  128. do
  129. ch = *lpstrCmd++;
  130. while (ch != ' ' && ch != '\t' && ch != '\0');
  131. while (ch == ' ' || ch == '\t')
  132. ch = *lpstrCmd++;
  133. while (ch == '-') {
  134. ch = *lpstrCmd++;
  135. // process multiple switch characters as needed
  136. do {
  137. switch (ch) {
  138. case 'U':
  139. case 'u':
  140. fUserOnly = TRUE;
  141. fSystemOnly = FALSE;
  142. ch = *lpstrCmd++;
  143. break;
  144. case 'S':
  145. case 's':
  146. fUserOnly = FALSE;
  147. fSystemOnly = TRUE;
  148. ch = *lpstrCmd++;
  149. break;
  150. case 'V':
  151. case 'v':
  152. fVerbose = TRUE;
  153. ch = *lpstrCmd++;
  154. break;
  155. default:
  156. printf("bad switch '%c'\n", ch);
  157. ExitProcess(1);
  158. }
  159. }
  160. while (ch != ' ' && ch != '\t' && ch != '\0');
  161. // skip over any following white space
  162. while (ch == ' ' || ch == '\t')
  163. ch = *lpstrCmd++;
  164. }
  165. status = NtQuerySystemInformation(
  166. SystemBasicInformation,
  167. &BasicInfo,
  168. sizeof(SYSTEM_BASIC_INFORMATION),
  169. NULL
  170. );
  171. if (!NT_SUCCESS(status)) {
  172. printf("Query info failed %lx\n",status);
  173. return(status);
  174. }
  175. status = NtQuerySystemInformation(
  176. SystemTimeOfDayInformation,
  177. &TimeOfDayInfo,
  178. sizeof(SYSTEM_TIMEOFDAY_INFORMATION),
  179. NULL
  180. );
  181. if (!NT_SUCCESS(status)) {
  182. printf("Query info failed %lx\n",status);
  183. return(status);
  184. }
  185. Time.QuadPart = TimeOfDayInfo.CurrentTime.QuadPart -
  186. TimeOfDayInfo.BootTime.QuadPart;
  187. RtlTimeToElapsedTimeFields ( &Time, &UpTime);
  188. printf("Pstat version 0.3: memory: %4ld kb uptime:%3ld %2ld:%02ld:%02ld.%03ld \n\n",
  189. BasicInfo.NumberOfPhysicalPages * (BasicInfo.PageSize/1024),
  190. UpTime.Day,
  191. UpTime.Hour,
  192. UpTime.Minute,
  193. UpTime.Second,
  194. UpTime.Milliseconds);
  195. PageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION)LargeBuffer1;
  196. status = NtQuerySystemInformation(
  197. SystemPageFileInformation,
  198. PageFileInfo,
  199. CurrentBufferSize,
  200. NULL
  201. );
  202. if (NT_SUCCESS(status)) {
  203. //
  204. // Print out the page file information.
  205. //
  206. if (PageFileInfo->TotalSize == 0) {
  207. printf("no page files in use\n");
  208. } else {
  209. for (; ; ) {
  210. printf("PageFile: %wZ\n", &PageFileInfo->PageFileName);
  211. printf("\tCurrent Size: %6ld kb Total Used: %6ld kb Peak Used %6ld kb\n",
  212. PageFileInfo->TotalSize*(BasicInfo.PageSize/1024),
  213. PageFileInfo->TotalInUse*(BasicInfo.PageSize/1024),
  214. PageFileInfo->PeakUsage*(BasicInfo.PageSize/1024));
  215. if (PageFileInfo->NextEntryOffset == 0) {
  216. break;
  217. }
  218. PageFileInfo = (PSYSTEM_PAGEFILE_INFORMATION)(
  219. (PCHAR)PageFileInfo + PageFileInfo->NextEntryOffset);
  220. }
  221. }
  222. }
  223. retry:
  224. status = NtQuerySystemInformation(
  225. SystemProcessInformation,
  226. LargeBuffer1,
  227. CurrentBufferSize,
  228. NULL
  229. );
  230. if (status == STATUS_INFO_LENGTH_MISMATCH) {
  231. //
  232. // Increase buffer size.
  233. //
  234. CurrentBufferSize += 8192;
  235. if (VirtualAlloc (LargeBuffer1,
  236. CurrentBufferSize,
  237. MEM_COMMIT,
  238. PAGE_READWRITE) == NULL) {
  239. printf("Memory commit failed\n");
  240. return 0;
  241. }
  242. goto retry;
  243. }
  244. if (!NT_SUCCESS(status)) {
  245. printf("Query info failed %lx\n",status);
  246. return(status);
  247. }
  248. //
  249. // display pmon style process output, then detailed output that includes
  250. // per thread stuff
  251. //
  252. TotalOffset = 0;
  253. SumCommit = 0;
  254. SumWorkingSet = 0;
  255. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)LargeBuffer1;
  256. while (TRUE) {
  257. SumCommit += ProcessInfo->PrivatePageCount / 1024;
  258. SumWorkingSet += ProcessInfo->WorkingSetSize / 1024;
  259. if (ProcessInfo->NextEntryOffset == 0) {
  260. break;
  261. }
  262. TotalOffset += ProcessInfo->NextEntryOffset;
  263. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&LargeBuffer1[TotalOffset];
  264. }
  265. Status = NtQuerySystemInformation(
  266. SystemPerformanceInformation,
  267. &PerfInfo,
  268. sizeof(PerfInfo),
  269. NULL
  270. );
  271. if ( !NT_SUCCESS(Status) ) {
  272. printf("Query perf Failed %lx\n",Status);
  273. return 0;
  274. }
  275. Status = NtQuerySystemInformation(
  276. SystemFileCacheInformation,
  277. &FileCache,
  278. sizeof(FileCache),
  279. NULL
  280. );
  281. if ( !NT_SUCCESS(Status) ) {
  282. printf("Query file cache Failed %lx\n",Status);
  283. return 0;
  284. }
  285. NtQuerySystemInformation(
  286. SystemBasicInformation,
  287. &BasicInfo,
  288. sizeof(BasicInfo),
  289. NULL
  290. );
  291. SumWorkingSet += FileCache.CurrentSize/1024;
  292. printf (
  293. "\n Memory:%7ldK Avail:%7ldK TotalWs:%7ldK InRam Kernel:%5ldK P:%5ldK\n",
  294. BasicInfo.NumberOfPhysicalPages*(BasicInfo.PageSize/1024),
  295. PerfInfo.AvailablePages*(BasicInfo.PageSize/1024),
  296. SumWorkingSet,
  297. (PerfInfo.ResidentSystemCodePage + PerfInfo.ResidentSystemDriverPage)*(BasicInfo.PageSize/1024),
  298. (PerfInfo.ResidentPagedPoolPage)*(BasicInfo.PageSize/1024)
  299. );
  300. printf(
  301. " Commit:%7ldK/%7ldK Limit:%7ldK Peak:%7ldK Pool N:%5ldK P:%5ldK\n",
  302. PerfInfo.CommittedPages*(BasicInfo.PageSize/1024),
  303. SumCommit,
  304. PerfInfo.CommitLimit*(BasicInfo.PageSize/1024),
  305. PerfInfo.PeakCommitment*(BasicInfo.PageSize/1024),
  306. PerfInfo.NonPagedPoolPages*(BasicInfo.PageSize/1024),
  307. PerfInfo.PagedPoolPages*(BasicInfo.PageSize/1024)
  308. );
  309. TotalOffset = 0;
  310. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)LargeBuffer1;
  311. printf("\n");
  312. printf(" User Time Kernel Time Ws Faults Commit Pri Hnd Thd Pid Name\n");
  313. printf(" %6ld %8ld %s\n",
  314. FileCache.CurrentSize/1024,
  315. FileCache.PageFaultCount,
  316. "File Cache"
  317. );
  318. while (TRUE) {
  319. pname.Buffer = NULL;
  320. if ( ProcessInfo->ImageName.Buffer ) {
  321. RtlUnicodeStringToAnsiString(&pname,(PUNICODE_STRING)&ProcessInfo->ImageName,TRUE);
  322. }
  323. RtlTimeToElapsedTimeFields ( &ProcessInfo->UserTime, &UserTime);
  324. RtlTimeToElapsedTimeFields ( &ProcessInfo->KernelTime, &KernelTime);
  325. printf("%3ld:%02ld:%02ld.%03ld %3ld:%02ld:%02ld.%03ld",
  326. UserTime.Hour,
  327. UserTime.Minute,
  328. UserTime.Second,
  329. UserTime.Milliseconds,
  330. KernelTime.Hour,
  331. KernelTime.Minute,
  332. KernelTime.Second,
  333. KernelTime.Milliseconds
  334. );
  335. printf("%6ld %8ld %7ld",
  336. ProcessInfo->WorkingSetSize / 1024,
  337. ProcessInfo->PageFaultCount,
  338. ProcessInfo->PrivatePageCount / 1024
  339. );
  340. printf(" %2ld %4ld %3ld %3ld %s\n",
  341. ProcessInfo->BasePriority,
  342. ProcessInfo->HandleCount,
  343. ProcessInfo->NumberOfThreads,
  344. HandleToUlong(ProcessInfo->UniqueProcessId),
  345. ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : (
  346. ProcessInfo->ImageName.Buffer ? pname.Buffer : "System")
  347. );
  348. if ( pname.Buffer ) {
  349. RtlFreeAnsiString(&pname);
  350. }
  351. if (ProcessInfo->NextEntryOffset == 0) {
  352. break;
  353. }
  354. TotalOffset += ProcessInfo->NextEntryOffset;
  355. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&LargeBuffer1[TotalOffset];
  356. }
  357. //
  358. // Beginning of normal old style pstat output
  359. //
  360. TotalOffset = 0;
  361. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)LargeBuffer1;
  362. printf("\n");
  363. while (TRUE) {
  364. fPrintIt = FALSE;
  365. if ( (ProcessInfo->ImageName.Buffer && fUserOnly) ||
  366. (ProcessInfo->ImageName.Buffer==NULL && fSystemOnly) ) {
  367. fPrintIt = TRUE;
  368. pname.Buffer = NULL;
  369. if ( ProcessInfo->ImageName.Buffer ) {
  370. RtlUnicodeStringToAnsiString(&pname,(PUNICODE_STRING)&ProcessInfo->ImageName,TRUE);
  371. }
  372. printf("pid:%3lx pri:%2ld Hnd:%5ld Pf:%7ld Ws:%7ldK %s\n",
  373. HandleToUlong(ProcessInfo->UniqueProcessId),
  374. ProcessInfo->BasePriority,
  375. ProcessInfo->HandleCount,
  376. ProcessInfo->PageFaultCount,
  377. ProcessInfo->WorkingSetSize / 1024,
  378. ProcessInfo->UniqueProcessId == 0 ? "Idle Process" : (
  379. ProcessInfo->ImageName.Buffer ? pname.Buffer : "System")
  380. );
  381. if ( pname.Buffer ) {
  382. RtlFreeAnsiString(&pname);
  383. }
  384. }
  385. i = 0;
  386. ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1);
  387. if (ProcessInfo->NumberOfThreads) {
  388. printf(" tid pri Ctx Swtch StrtAddr User Time Kernel Time State\n");
  389. }
  390. while (i < ProcessInfo->NumberOfThreads) {
  391. RtlTimeToElapsedTimeFields ( &ThreadInfo->UserTime, &UserTime);
  392. RtlTimeToElapsedTimeFields ( &ThreadInfo->KernelTime, &KernelTime);
  393. if ( fPrintIt ) {
  394. printf(" %3lx %2ld %9ld %p",
  395. ProcessInfo->UniqueProcessId == 0 ? 0 : HandleToUlong(ThreadInfo->ClientId.UniqueThread),
  396. ProcessInfo->UniqueProcessId == 0 ? 0 : ThreadInfo->Priority,
  397. ThreadInfo->ContextSwitches,
  398. ProcessInfo->UniqueProcessId == 0 ? 0 : ThreadInfo->StartAddress
  399. );
  400. printf(" %2ld:%02ld:%02ld.%03ld %2ld:%02ld:%02ld.%03ld",
  401. UserTime.Hour,
  402. UserTime.Minute,
  403. UserTime.Second,
  404. UserTime.Milliseconds,
  405. KernelTime.Hour,
  406. KernelTime.Minute,
  407. KernelTime.Second,
  408. KernelTime.Milliseconds
  409. );
  410. printf(" %s%s\n",
  411. StateTable[ThreadInfo->ThreadState],
  412. (ThreadInfo->ThreadState == 5) ?
  413. WaitTable[ThreadInfo->WaitReason] : Empty
  414. );
  415. }
  416. ThreadInfo += 1;
  417. i += 1;
  418. }
  419. if (ProcessInfo->NextEntryOffset == 0) {
  420. break;
  421. }
  422. TotalOffset += ProcessInfo->NextEntryOffset;
  423. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&LargeBuffer1[TotalOffset];
  424. if ( fPrintIt ) {
  425. printf("\n");
  426. }
  427. }
  428. PrintLoadedDrivers();
  429. return 0;
  430. }
  431. typedef struct _MODULE_DATA {
  432. ULONG CodeSize;
  433. ULONG DataSize;
  434. ULONG BssSize;
  435. ULONG RoDataSize;
  436. ULONG ImportDataSize;
  437. ULONG ExportDataSize;
  438. ULONG ResourceDataSize;
  439. ULONG PagedSize;
  440. ULONG InitSize;
  441. ULONG CheckSum;
  442. ULONG TimeDateStamp;
  443. } MODULE_DATA, *PMODULE_DATA;
  444. typedef struct _LOADED_IMAGE {
  445. PUCHAR MappedAddress;
  446. PIMAGE_NT_HEADERS FileHeader;
  447. PIMAGE_SECTION_HEADER LastRvaSection;
  448. int NumberOfSections;
  449. PIMAGE_SECTION_HEADER Sections;
  450. } LOADED_IMAGE, *PLOADED_IMAGE;
  451. VOID
  452. SumModuleData(
  453. PMODULE_DATA Sum,
  454. PMODULE_DATA Current
  455. )
  456. {
  457. Sum->CodeSize += Current->CodeSize;
  458. Sum->DataSize += Current->DataSize;
  459. Sum->BssSize += Current->BssSize;
  460. Sum->RoDataSize += Current->RoDataSize;
  461. Sum->ImportDataSize += Current->ImportDataSize;
  462. Sum->ExportDataSize += Current->ExportDataSize;
  463. Sum->ResourceDataSize += Current->ResourceDataSize;
  464. Sum->PagedSize += Current->PagedSize;
  465. Sum->InitSize += Current->InitSize;
  466. }
  467. VOID
  468. PrintModuleSeperator(
  469. VOID
  470. )
  471. {
  472. printf("------------------------------------------------------------------------------\n");
  473. }
  474. VOID
  475. PrintModuleHeader(
  476. VOID
  477. )
  478. {
  479. printf(" ModuleName Load Addr Code Data Paged LinkDate\n");
  480. PrintModuleSeperator();
  481. }
  482. VOID
  483. PrintModuleLine(
  484. LPSTR ModuleName,
  485. PMODULE_DATA Current,
  486. PRTL_PROCESS_MODULE_INFORMATION Module
  487. )
  488. {
  489. if ( Module ) {
  490. printf("%12s %p %7d %7d %7d %s",
  491. ModuleName,
  492. Module->ImageBase,
  493. Current->CodeSize,
  494. Current->DataSize,
  495. Current->PagedSize,
  496. Current->TimeDateStamp ? ctime((time_t *)&Current->TimeDateStamp) : "\n"
  497. );
  498. }
  499. else {
  500. printf("%12s %7d %7d %7d\n",
  501. ModuleName,
  502. Current->CodeSize,
  503. Current->DataSize,
  504. Current->PagedSize
  505. );
  506. }
  507. }
  508. VOID
  509. GetModuleData(
  510. HANDLE hFile,
  511. PMODULE_DATA Mod
  512. )
  513. {
  514. HANDLE hMappedFile;
  515. PIMAGE_DOS_HEADER DosHeader;
  516. LOADED_IMAGE LoadedImage;
  517. ULONG SectionAlignment;
  518. PIMAGE_SECTION_HEADER Section;
  519. int i;
  520. ULONG Size;
  521. hMappedFile = CreateFileMapping(
  522. hFile,
  523. NULL,
  524. PAGE_READONLY,
  525. 0,
  526. 0,
  527. NULL
  528. );
  529. if ( !hMappedFile ) {
  530. return;
  531. }
  532. LoadedImage.MappedAddress = MapViewOfFile(
  533. hMappedFile,
  534. FILE_MAP_READ,
  535. 0,
  536. 0,
  537. 0
  538. );
  539. CloseHandle(hMappedFile);
  540. if ( !LoadedImage.MappedAddress ) {
  541. return;
  542. }
  543. //
  544. // Everything is mapped. Now check the image and find nt image headers
  545. //
  546. DosHeader = (PIMAGE_DOS_HEADER)LoadedImage.MappedAddress;
  547. if ( DosHeader->e_magic != IMAGE_DOS_SIGNATURE ) {
  548. UnmapViewOfFile(LoadedImage.MappedAddress);
  549. return;
  550. }
  551. LoadedImage.FileHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);
  552. if ( LoadedImage.FileHeader->Signature != IMAGE_NT_SIGNATURE ) {
  553. UnmapViewOfFile(LoadedImage.MappedAddress);
  554. return;
  555. }
  556. LoadedImage.NumberOfSections = LoadedImage.FileHeader->FileHeader.NumberOfSections;
  557. LoadedImage.Sections = (PIMAGE_SECTION_HEADER)((ULONG_PTR)LoadedImage.FileHeader + sizeof(IMAGE_NT_HEADERS));
  558. LoadedImage.LastRvaSection = LoadedImage.Sections;
  559. //
  560. // Walk through the sections and tally the dater
  561. //
  562. SectionAlignment = LoadedImage.FileHeader->OptionalHeader.SectionAlignment;
  563. for(Section = LoadedImage.Sections,i=0; i<LoadedImage.NumberOfSections; i++,Section++) {
  564. Size = Section->Misc.VirtualSize;
  565. if (Size == 0) {
  566. Size = Section->SizeOfRawData;
  567. }
  568. Size = (Size + SectionAlignment - 1) & ~(SectionAlignment - 1);
  569. if (!_strnicmp(Section->Name,"PAGE", 4 )) {
  570. Mod->PagedSize += Size;
  571. }
  572. else if (!_stricmp(Section->Name,"INIT" )) {
  573. Mod->InitSize += Size;
  574. }
  575. else if (!_stricmp(Section->Name,".bss" )) {
  576. Mod->BssSize = Size;
  577. }
  578. else if (!_stricmp(Section->Name,".edata" )) {
  579. Mod->ExportDataSize = Size;
  580. }
  581. else if (!_stricmp(Section->Name,".idata" )) {
  582. Mod->ImportDataSize = Size;
  583. }
  584. else if (!_stricmp(Section->Name,".rsrc" )) {
  585. Mod->ResourceDataSize = Size;
  586. }
  587. else if (Section->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
  588. Mod->CodeSize += Size;
  589. }
  590. else if (Section->Characteristics & IMAGE_SCN_MEM_WRITE) {
  591. Mod->DataSize += Size;
  592. }
  593. else if (Section->Characteristics & IMAGE_SCN_MEM_READ) {
  594. Mod->RoDataSize += Size;
  595. }
  596. else {
  597. Mod->DataSize += Size;
  598. }
  599. }
  600. Mod->CheckSum = LoadedImage.FileHeader->OptionalHeader.CheckSum;
  601. Mod->TimeDateStamp = LoadedImage.FileHeader->FileHeader.TimeDateStamp;
  602. UnmapViewOfFile(LoadedImage.MappedAddress);
  603. return;
  604. }
  605. VOID
  606. PrintLoadedDrivers(
  607. VOID
  608. )
  609. {
  610. ULONG i;
  611. PCHAR s;
  612. HANDLE FileHandle;
  613. CHAR KernelPath[MAX_PATH];
  614. CHAR DriversPath[MAX_PATH];
  615. PCHAR ModuleInfo;
  616. ULONG ModuleInfoLength;
  617. ULONG ReturnedLength;
  618. PRTL_PROCESS_MODULES Modules;
  619. PRTL_PROCESS_MODULE_INFORMATION Module;
  620. NTSTATUS Status;
  621. MODULE_DATA Sum;
  622. MODULE_DATA Current;
  623. printf("\n");
  624. //
  625. // Locate system drivers.
  626. //
  627. ModuleInfoLength = 64000;
  628. while (1) {
  629. ModuleInfo = malloc (ModuleInfoLength);
  630. if (ModuleInfo == NULL) {
  631. printf ("Failed to allocate memory for module information buffer of size %d\n",
  632. ModuleInfoLength);
  633. return;
  634. }
  635. Status = NtQuerySystemInformation (
  636. SystemModuleInformation,
  637. ModuleInfo,
  638. ModuleInfoLength,
  639. &ReturnedLength);
  640. if (!NT_SUCCESS(Status)) {
  641. free (ModuleInfo);
  642. if (Status == STATUS_INFO_LENGTH_MISMATCH &&
  643. ReturnedLength > ModuleInfoLength) {
  644. ModuleInfoLength = ReturnedLength;
  645. continue;
  646. }
  647. printf("query system info failed status - %lx\n",Status);
  648. return;
  649. }
  650. break;
  651. }
  652. GetSystemDirectory(KernelPath,sizeof(KernelPath));
  653. strcpy(DriversPath,KernelPath);
  654. strcat(DriversPath,"\\Drivers");
  655. ZeroMemory(&Sum,sizeof(Sum));
  656. PrintModuleHeader();
  657. Modules = (PRTL_PROCESS_MODULES)ModuleInfo;
  658. Module = &Modules->Modules[ 0 ];
  659. for (i=0; i<Modules->NumberOfModules; i++) {
  660. ZeroMemory(&Current,sizeof(Current));
  661. s = &Module->FullPathName[ Module->OffsetToFileName ];
  662. //
  663. // try to open the file
  664. //
  665. SetCurrentDirectory(KernelPath);
  666. FileHandle = CreateFile(
  667. s,
  668. GENERIC_READ,
  669. FILE_SHARE_READ,
  670. NULL,
  671. OPEN_EXISTING,
  672. 0,
  673. NULL
  674. );
  675. if ( FileHandle == INVALID_HANDLE_VALUE ) {
  676. SetCurrentDirectory(DriversPath);
  677. FileHandle = CreateFile(
  678. s,
  679. GENERIC_READ,
  680. FILE_SHARE_READ,
  681. NULL,
  682. OPEN_EXISTING,
  683. 0,
  684. NULL
  685. );
  686. }
  687. if ( FileHandle != INVALID_HANDLE_VALUE ) {
  688. GetModuleData(FileHandle,&Current);
  689. CloseHandle(FileHandle);
  690. }
  691. SumModuleData(&Sum,&Current);
  692. PrintModuleLine(s,&Current,Module);
  693. Module++;
  694. }
  695. PrintModuleSeperator();
  696. PrintModuleLine("Total",&Sum,NULL);
  697. free (ModuleInfo);
  698. }