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.

1971 lines
77 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. mminfo.c
  5. Abstract:
  6. This module monitor the system hard page fault.
  7. Author:
  8. Stephen Hsiao (shsiao) 4-8-96
  9. Environment:
  10. User Mode
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <assert.h>
  20. #define NTMMPERF 1
  21. #if NTMMPERF
  22. typedef enum _KTHREAD_STATE {
  23. Initialized,
  24. Ready,
  25. Running,
  26. Standby,
  27. Terminated,
  28. Waiting,
  29. Transition
  30. } KTHREAD_STATE;
  31. char *ThreadState[] = {
  32. "Initialized",
  33. "Ready",
  34. "Running",
  35. "Standby",
  36. "Terminated",
  37. "Waiting",
  38. "Transition",
  39. };
  40. char *WaitReason[] = {
  41. "Executive",
  42. "FreePage",
  43. "PageIn",
  44. "PoolAllocation",
  45. "DelayExecution",
  46. "Suspended",
  47. "UserRequest",
  48. "WrExecutive",
  49. "WrFreePage",
  50. "WrPageIn",
  51. "WrPoolAllocation",
  52. "WrDelayExecution",
  53. "WrSuspended",
  54. "WrUserRequest",
  55. "WrEventPair",
  56. "WrQueue",
  57. "WrLpcReceive",
  58. "WrLpcReply",
  59. "WrVirtualMemory",
  60. "WrPageOut",
  61. "WrRendezvous",
  62. "Spare2",
  63. "Spare3",
  64. "Spare4",
  65. "Spare5",
  66. "Spare6",
  67. "WrKernel",
  68. "MaximumWaitReason"
  69. };
  70. PSZ PoolTypeNames[7] = {
  71. "NonPagedPool",
  72. "PagedPool ",
  73. "NonPagedMS ",
  74. "NotUsed ",
  75. "NonPagedCaAl",
  76. "PagedCaAl ",
  77. "NonPCaAlMS "
  78. };
  79. #define CM_KEY_NODE_SIGNATURE 0x6b6e // "kn"
  80. #define CM_LINK_NODE_SIGNATURE 0x6b6c // "kl"
  81. #define CM_KEY_VALUE_SIGNATURE 0x6b76 // "kv"
  82. #define CM_KEY_SECURITY_SIGNATURE 0x6b73 // "ks"
  83. #define CM_KEY_FAST_LEAF 0x666c // "fl"
  84. #define MAX_TASKS 256
  85. #define TableSize 4096
  86. #define PAGE_SIZE 4096
  87. #define PROTECTED_POOL 0x80000000
  88. CHAR Mark[MAX_MMINFO_MARK_SIZE];
  89. DWORD pid;
  90. CHAR pname[MAX_PATH];
  91. CHAR *MmInfoBuffer;
  92. SYSTEM_MMINFO_FILENAME_INFORMATION ImageHash[TableSize];
  93. SYSTEM_MMINFO_PROCESS_INFORMATION ProcessHash[TableSize];
  94. LONG ThreadHash[TableSize] = {-1};
  95. LONG BufferLength;
  96. BOOLEAN Debug=FALSE;
  97. ULONG MmInfoOnFlag=0;
  98. ULONG DefaultOnFlag=(MMINFO_LOG_MEMORY |
  99. MMINFO_LOG_WORKINGSET |
  100. MMINFO_LOG_HARDFAULT |
  101. MMINFO_LOG_PROCESS |
  102. MMINFO_LOG_THREAD);
  103. ULONG DefaultDetailedOnFlag=(MMINFO_LOG_MEMORY |
  104. MMINFO_LOG_WORKINGSET |
  105. MMINFO_LOG_HARDFAULT |
  106. MMINFO_LOG_SOFTFAULT |
  107. MMINFO_LOG_PROCESS |
  108. MMINFO_LOG_THREAD |
  109. MMINFO_LOG_CSWITCH |
  110. MMINFO_LOG_POOL |
  111. MMINFO_LOG_CHANGELIST);
  112. #ifdef WS_INSTRUMENTATION
  113. char * WsInfoHeaderFormat =
  114. " WsInfo, Process, WorkSet, Claim, Access, Age0, Age1, Age2, Age3, Shared, Mod, Faults, RecentF, Repl, URepl, Boosts, Prio\n";
  115. char * WsInfoDataFormat =
  116. " WsInfo, %24s, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d\n";
  117. char * TrimHeaderFormat =
  118. " Trim, Process, WorkSet, Claim, Try, Got, Faults, RecentF, Repl, URepl, Boosts, Prio\n";
  119. char * TrimDataFormat =
  120. " Trim, %24s, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d\n";
  121. char * WsManagerHeaderFormat =
  122. " WsManager, Time, Avail, Claim, Faults, LastPF, Counter, DesReduc, DesFree, Action\n";
  123. char * WsManagerDataFormat =
  124. " WsManager, %10I64d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %s\n";
  125. #else
  126. char * WsInfoHeaderFormat =
  127. " WsInfo, Process, WorkSet, Faults, Prio\n";
  128. char * WsInfoDataFormat =
  129. " WsInfo, %24s, %8d, %8d, %8d\n";
  130. char * TrimHeaderFormat =
  131. " Trim, Process, WorkSet, Faults, Prio\n";
  132. char * TrimDataFormat =
  133. " Trim, %24s, %8d, %8d, %8d\n";
  134. char * WsManagerHeaderFormat =
  135. " WsManager, Time, Avail, Faults, LastPF, Counter, DesReduc, DesFree, Action\n";
  136. char * WsManagerDataFormat =
  137. " WsManager, %10I64d, %8d, %8d, %8d, %8d, %8d, %8d, %s\n";
  138. #endif // WS_INSTRUMENTATION
  139. char * ImageLoadHeaderFormat =
  140. " ImageLoad, BaseAddr, EndAddr, SectNum, Process, Name\n";
  141. char * ImageLoadDataFormat =
  142. " ImageLoad, %08x, %08x, %-8x, %s, %S\n";
  143. char * SampleProfileHeaderFormat =
  144. " SampledProfile, EIP, Count\n";
  145. char * SampledProfileDataFormat =
  146. " SampledProfile, %08x, %-8d\n";
  147. char * GeneralHeaderFormat = "%12s,%10s,%22s,%12s,%12s,%8s,%30s,%12s,%10s,%10s,%10s\n";
  148. ULONG ToTurnOn=0;
  149. ULONG ToTurnOff=0;
  150. CHAR System[] = "System";
  151. #define MODE_NONE 0
  152. #define MODE_SLASH 1
  153. #define MODE_PLUS 2
  154. #define MODE_MINUS 3
  155. typedef struct Api_Address_St {
  156. ULONG Address;
  157. CHAR *ApiName;
  158. } Api_Address_t, *PApi_Address_t;
  159. typedef struct Dll_Address_St {
  160. ULONG StartingAddress;
  161. ULONG EndingAddress;
  162. CHAR *DllName;
  163. } Dll_Address_t, *PDll_Address_t;
  164. PApi_Address_t GlobalApiInfo;
  165. PDll_Address_t GlobalDllInfo;
  166. int NumGlobalApis=0;
  167. int NumGlobalDlls=0;
  168. int NumAllocatedGlobalApis=0;
  169. int NumAllocatedGlobalDlls=0;
  170. #define AllocationIncrement 1000
  171. VOID InsertDll(ULONG StartingAddress, ULONG EndingAddress, CHAR *DllName){
  172. if (NumGlobalDlls == NumAllocatedGlobalDlls ){
  173. if (NumGlobalDlls == 0 ){
  174. NumAllocatedGlobalDlls = AllocationIncrement;
  175. GlobalDllInfo = (PDll_Address_t)
  176. malloc( sizeof(Dll_Address_t) * NumAllocatedGlobalDlls);
  177. } else {
  178. NumAllocatedGlobalDlls += AllocationIncrement;
  179. GlobalDllInfo = (PDll_Address_t)
  180. realloc( GlobalDllInfo, sizeof(Dll_Address_t) * NumAllocatedGlobalDlls);
  181. }
  182. }
  183. if (GlobalDllInfo == NULL ){
  184. return;
  185. }
  186. GlobalDllInfo[ NumGlobalDlls ].StartingAddress = StartingAddress;
  187. GlobalDllInfo[ NumGlobalDlls ].EndingAddress = EndingAddress;
  188. GlobalDllInfo[ NumGlobalDlls ].DllName = DllName;
  189. NumGlobalDlls ++;
  190. }
  191. VOID InsertApi(ULONG Address, CHAR *ApiName){
  192. if (NumGlobalApis == NumAllocatedGlobalApis ){
  193. if (NumGlobalApis == 0 ){
  194. NumAllocatedGlobalApis = AllocationIncrement;
  195. GlobalApiInfo = (PApi_Address_t)
  196. malloc( sizeof(Api_Address_t) * NumAllocatedGlobalApis);
  197. } else {
  198. NumAllocatedGlobalApis += AllocationIncrement;
  199. GlobalApiInfo = (PApi_Address_t)
  200. realloc( GlobalApiInfo, sizeof(Api_Address_t) * NumAllocatedGlobalApis);
  201. }
  202. }
  203. if (GlobalApiInfo == NULL ){
  204. return;
  205. }
  206. GlobalApiInfo[ NumGlobalApis ].Address = Address;
  207. GlobalApiInfo[ NumGlobalApis ].ApiName = ApiName;
  208. NumGlobalApis ++;
  209. }
  210. CHAR *DllContainingAddress(ULONG Address){
  211. int i;
  212. for(i=0; i < NumGlobalDlls; i++){
  213. if ( GlobalDllInfo[ i ].StartingAddress <= Address &&
  214. Address <= GlobalDllInfo[ i ].EndingAddress){
  215. return GlobalDllInfo[ i ].DllName;
  216. }
  217. }
  218. return "DllNotFound";
  219. }
  220. CHAR *ApiAtAddress(ULONG Address){
  221. int i;
  222. for(i=0; i < NumGlobalApis; i++){
  223. if ( GlobalApiInfo[ i ].Address == Address ){
  224. return GlobalApiInfo[ i ].ApiName;
  225. }
  226. }
  227. return "ApiNotFound";
  228. }
  229. VOID
  230. ParseArgs (
  231. int argc,
  232. char *argv[]
  233. )
  234. {
  235. ULONG Mode=MODE_NONE;
  236. char *p;
  237. char *Usage="\
  238. Usage: mminfo -Option \n\
  239. /c Turn OFF hard fault clustering\n\
  240. /i Initialize MmInfo (Allocate buffer)\n\
  241. /u Uninitialize MmInfo (Free buffer) \n\
  242. /d Turn on debugging\n\
  243. /f Turn off monitoring (Keep log for later processing) \n\
  244. /F Set a Mark with workingsetflush now \n\
  245. /M Set a Mark now \n\
  246. /o Turn on default monitoring (h,m,t, and w)\n\
  247. /O Turn on detailed monitoring (plus a, l, p, and S)\n\
  248. +/- a Turn on/off context switch monitor\n\
  249. +/- e Turn on/off EmptyQ on every Mark\n\
  250. +/- E Turn on/off EmptyQDetail (Per Process footprint) on every Mark\n\
  251. +/- h Turn on/off hard fault monitor\n\
  252. +/- l Turn on/off memory list monitor\n\
  253. +/- m Turn on/off memory monitor\n\
  254. +/- p Turn on/off pool monitor\n\
  255. +/- P Turn on/off sampled profiling\n\
  256. +/- r Turn on/off registry monitor\n\
  257. +/- R Turn on/off registry Relocation\n\
  258. +/- s Turn on/off initial snap shot of memory\n\
  259. +/- S Turn on/off Soft (Demand zero and Trainsition) fault monitor\n\
  260. +/- t Turn on/off thread & process monitor\n\
  261. +/- T Turn on/off detailed trimming monitor\n\
  262. +/- w Turn on/off working set monitor\n\
  263. +/- z Turn on/off detailed working set info\n\
  264. +/- Z Turn on/off dumping working set entries\n\
  265. Default Dump bata (Also turn off monitoring)\n\
  266. ";
  267. NTSTATUS status;
  268. int i;
  269. argc--;
  270. *argv++;
  271. while ( argc-- > 0 ) {
  272. p = *argv++;
  273. switch (*p) {
  274. case '/':
  275. Mode = MODE_SLASH;
  276. break;
  277. case '+':
  278. Mode = MODE_PLUS;
  279. break;
  280. case '-':
  281. Mode = MODE_MINUS;
  282. break;
  283. default:
  284. fprintf(stderr,"%s\n", Usage);
  285. ExitProcess(1);
  286. }
  287. p++;
  288. while(*p != '\0') {
  289. if (Mode == MODE_SLASH) {
  290. switch (*p) {
  291. case 'c':
  292. ToTurnOn = ToTurnOn | MMINFO_LOG_NO_CLUSTERING;
  293. break;
  294. case 'd':
  295. Debug=TRUE;
  296. break;
  297. case 'f':
  298. status = NtSetSystemInformation (
  299. SystemMmInfoLogOffInformation,
  300. NULL,
  301. 0);
  302. if (!NT_SUCCESS (status)) {
  303. fprintf(stderr,"Set system information failed %lx\n",status);
  304. }else{
  305. fprintf(stderr,"Monitor Off\n");
  306. }
  307. ExitProcess(0);
  308. case 'i':
  309. status = NtSetSystemInformation (
  310. SystemMmInfoInitializeInformation,
  311. NULL,
  312. 0);
  313. if (!NT_SUCCESS (status)) {
  314. fprintf(stderr, "Set system information failed %lx\n",status);
  315. }else{
  316. fprintf(stderr,"buffer allocated\n");
  317. }
  318. ExitProcess(0);
  319. case 'F':
  320. case 'M':
  321. {
  322. BOOLEAN Flush = (*p == 'F') ? TRUE : FALSE;
  323. p++;
  324. while(*p == '\0') {
  325. p++;
  326. }
  327. i=-1;
  328. if (*p == '/' || *p == '+' || *p == '-') {
  329. // Nothing in the Mark
  330. fprintf(stderr, "Mark not set!\n");
  331. fprintf(stderr,"%s\n", Usage);
  332. ExitProcess(0);
  333. } else if (*p == '"') {
  334. p++;
  335. while(*p != '"') {
  336. if (i < MAX_MMINFO_MARK_SIZE) {
  337. i++;
  338. Mark[i] = *p;
  339. }
  340. p++;
  341. }
  342. } else {
  343. while (*p != '\0') {
  344. if (i < MAX_MMINFO_MARK_SIZE) {
  345. i++;
  346. Mark[i] = *p;
  347. }
  348. p++;
  349. }
  350. }
  351. status = NtSetSystemInformation (
  352. Flush ? SystemMmInfoMarkWithFlush
  353. : SystemMmInfoMark,
  354. Mark,
  355. MAX_MMINFO_MARK_SIZE);
  356. if (!NT_SUCCESS (status)) {
  357. fprintf(stderr, "Set system information failed %lx\n",status);
  358. }else{
  359. fprintf(stderr, "Mark set: %s\n", Mark);
  360. }
  361. ExitProcess(0);
  362. }
  363. case 'o':
  364. MmInfoOnFlag = DefaultOnFlag;
  365. break;
  366. case 'O':
  367. MmInfoOnFlag = DefaultDetailedOnFlag;
  368. break;
  369. case 'u':
  370. status = NtSetSystemInformation (
  371. SystemMmInfoUnInitializeInformation,
  372. NULL,
  373. 0);
  374. if (!NT_SUCCESS (status)) {
  375. fprintf(stderr,"Set system information failed %lx\n",status);
  376. }else{
  377. fprintf(stderr,"Unitialized\n");
  378. }
  379. ExitProcess(0);
  380. default:
  381. fprintf(stderr,"%s\n", Usage);
  382. ExitProcess(1);
  383. }
  384. } else if (Mode == MODE_PLUS) {
  385. switch (*p) {
  386. case 'a':
  387. ToTurnOn = ToTurnOn | MMINFO_LOG_PROCESS |
  388. MMINFO_LOG_THREAD | MMINFO_LOG_CSWITCH;
  389. break;
  390. case 'e':
  391. ToTurnOn = ToTurnOn | MMINFO_LOG_MEMORY | MMINFO_LOG_EMPTYQ | MMINFO_LOG_PROCESS;
  392. break;
  393. case 'E':
  394. ToTurnOn = ToTurnOn | MMINFO_LOG_MEMORY | MMINFO_LOG_EMPTYQ
  395. | MMINFO_LOG_EMPTYQDETAIL | MMINFO_LOG_PROCESS;
  396. break;
  397. case 'm':
  398. ToTurnOn = ToTurnOn | MMINFO_LOG_MEMORY | MMINFO_LOG_PROCESS;
  399. break;
  400. case 'p':
  401. ToTurnOn = ToTurnOn | MMINFO_LOG_POOL;
  402. break;
  403. case 'w':
  404. ToTurnOn = ToTurnOn | MMINFO_LOG_WORKINGSET | MMINFO_LOG_PROCESS;
  405. break;
  406. case 't':
  407. ToTurnOn = ToTurnOn | MMINFO_LOG_PROCESS | MMINFO_LOG_THREAD;
  408. break;
  409. case 'T':
  410. ToTurnOn = ToTurnOn | MMINFO_LOG_WSCHANGE |
  411. MMINFO_LOG_MEMORY | MMINFO_LOG_PROCESS;
  412. break;
  413. case 'h':
  414. ToTurnOn = ToTurnOn | MMINFO_LOG_HARDFAULT | MMINFO_LOG_PROCESS;
  415. break;
  416. case 'l':
  417. ToTurnOn = ToTurnOn | MMINFO_LOG_CHANGELIST | MMINFO_LOG_MEMORY;
  418. break;
  419. case 'r':
  420. ToTurnOn = ToTurnOn | MMINFO_LOG_REGISTRY;
  421. break;
  422. case 'R':
  423. status = NtSetSystemInformation (
  424. SystemRelocateCMCellOn,
  425. NULL,
  426. 0);
  427. if (!NT_SUCCESS (status)) {
  428. fprintf(stderr,"Set system information failed %lx\n",status);
  429. }else{
  430. fprintf(stderr,"Registry Relocation on\n");
  431. }
  432. ExitProcess(0);
  433. case 's':
  434. ToTurnOn = ToTurnOn | MMINFO_LOG_INIT_MEMSNAP;
  435. break;
  436. case 'S':
  437. ToTurnOn = ToTurnOn | MMINFO_LOG_SOFTFAULT |
  438. MMINFO_LOG_PROCESS | MMINFO_LOG_MEMORY;
  439. break;
  440. case 'z':
  441. ToTurnOn = ToTurnOn | MMINFO_LOG_WSDETAILS;
  442. break;
  443. case 'Z':
  444. ToTurnOn = ToTurnOn | MMINFO_LOG_WSENTRIES;
  445. break;
  446. case 'P':
  447. ToTurnOn = ToTurnOn | MMINFO_LOG_PROFILE;
  448. break;
  449. default:
  450. fprintf(stderr,"%s\n", Usage);
  451. ExitProcess(1);
  452. }
  453. } else if (Mode == MODE_MINUS) {
  454. switch (*p) {
  455. case 'a':
  456. ToTurnOff = ToTurnOff | MMINFO_LOG_CSWITCH ;
  457. break;
  458. case 'e':
  459. ToTurnOff = ToTurnOff | MMINFO_LOG_EMPTYQ;
  460. break;
  461. case 'E':
  462. ToTurnOff = ToTurnOff | MMINFO_LOG_EMPTYQDETAIL;
  463. break;
  464. case 'm':
  465. ToTurnOff = ToTurnOff | MMINFO_LOG_MEMORY ;
  466. break;
  467. case 'p':
  468. ToTurnOff = ToTurnOff | MMINFO_LOG_POOL;
  469. break;
  470. case 'w':
  471. ToTurnOff = ToTurnOff | MMINFO_LOG_WORKINGSET;
  472. break;
  473. case 't':
  474. ToTurnOff = ToTurnOff | MMINFO_LOG_PROCESS |
  475. MMINFO_LOG_THREAD | MMINFO_LOG_CSWITCH;
  476. break;
  477. case 'T':
  478. ToTurnOff = ToTurnOff | MMINFO_LOG_WSCHANGE;
  479. break;
  480. case 'h':
  481. ToTurnOff = ToTurnOff | MMINFO_LOG_HARDFAULT;
  482. break;
  483. case 'l':
  484. ToTurnOff = ToTurnOff | MMINFO_LOG_CHANGELIST;
  485. break;
  486. case 'r':
  487. ToTurnOff = ToTurnOff | MMINFO_LOG_REGISTRY;
  488. break;
  489. case 'R':
  490. status = NtSetSystemInformation (
  491. SystemRelocateCMCellOff,
  492. NULL,
  493. 0);
  494. if (!NT_SUCCESS (status)) {
  495. fprintf(stderr,"Set system information failed %lx\n",status);
  496. }else{
  497. fprintf(stderr,"Registry Relocation off\n");
  498. }
  499. ExitProcess(0);
  500. case 's':
  501. ToTurnOff = ToTurnOff | MMINFO_LOG_INIT_MEMSNAP;
  502. break;
  503. case 'S':
  504. ToTurnOff = ToTurnOff | MMINFO_LOG_SOFTFAULT;
  505. break;
  506. case 'z':
  507. ToTurnOff = ToTurnOff | MMINFO_LOG_WSDETAILS;
  508. break;
  509. case 'Z':
  510. ToTurnOff = ToTurnOff | MMINFO_LOG_WSENTRIES;
  511. break;
  512. case 'P':
  513. ToTurnOff = ToTurnOff | MMINFO_LOG_PROFILE;
  514. break;
  515. default:
  516. fprintf(stderr,"%s\n", Usage);
  517. ExitProcess(1);
  518. }
  519. }
  520. p++;
  521. }
  522. }
  523. }
  524. #endif //NTMMPERF
  525. int _cdecl
  526. main(
  527. int argc,
  528. char *argv[]
  529. )
  530. {
  531. #if NTMMPERF
  532. LPSTR p;
  533. NTSTATUS status;
  534. ULONG ImageStart, ImageEnd;
  535. ULONG ProcessStart, ProcessEnd;
  536. SYSTEM_BASIC_INFORMATION BasicInfo;
  537. ULONG TotalPageTable;
  538. ULONG TotalModified;
  539. ULONG TotalTransition;
  540. SYSTEMTIME Time;
  541. ULONG PageKb;
  542. ULONG LogSize;
  543. ULONG LogType;
  544. _int64 *TmpPint64;
  545. _int64 PerfCounter, PerfCounterStart;
  546. _int64 PerfFrequency;
  547. PerfHook_t *Hook, *NextHook;
  548. TimeStamp_t TS;
  549. PerfSize_t Size;
  550. PerfTag_t Tag;
  551. PerfData_t *Info;
  552. ULONG i;
  553. //
  554. // First parse the arguments and see what to do.
  555. //
  556. ParseArgs( argc, argv );
  557. if (ToTurnOn & ToTurnOff) {
  558. fprintf(stderr,"Cannot turn on and off the same flag, make up your mind !!!\n");
  559. }else{
  560. MmInfoOnFlag=((MmInfoOnFlag | ToTurnOn) & ~ToTurnOff);
  561. }
  562. //
  563. // If there is a flag to turn on. Do it.
  564. //
  565. if (MmInfoOnFlag) {
  566. status = NtSetSystemInformation (
  567. SystemMmInfoLogOnInformation,
  568. &MmInfoOnFlag,
  569. sizeof(ULONG));
  570. if (!NT_SUCCESS (status)) {
  571. fprintf(stderr,"Set system information failed ON %lx\n",status);
  572. return 1;
  573. }else{
  574. fprintf(stderr,"Monitor On\n");
  575. return 0;
  576. }
  577. }
  578. //
  579. // If we reach this point, we are do dump the log.
  580. // First turn off monitor.
  581. //
  582. status = NtSetSystemInformation (SystemMmInfoLogOffInformation,
  583. NULL,
  584. 0);
  585. if (!NT_SUCCESS (status)) {
  586. fprintf(stderr,"Set system information failed %lx\n",status);
  587. return 1;
  588. }
  589. //
  590. // HACK FIXFIX when doing MP stuff
  591. //
  592. ThreadHash[0] = 0;
  593. ProcessHash[0].ProcessID = 0;
  594. RtlCopyMemory(ProcessHash[0].ImageFileName, "Idle", 16);
  595. status = NtQuerySystemInformation(
  596. SystemBasicInformation,
  597. &BasicInfo,
  598. sizeof(BasicInfo),
  599. NULL
  600. );
  601. if (!NT_SUCCESS (status)) {
  602. fprintf(stderr,"query system basic information failed %lx\n",status);
  603. return 1;
  604. }
  605. PageKb = BasicInfo.PageSize / 1024;
  606. //
  607. // print the Headers
  608. //
  609. printf(WsManagerHeaderFormat);
  610. printf(WsInfoHeaderFormat);
  611. printf(TrimHeaderFormat );
  612. printf(ImageLoadHeaderFormat);
  613. printf(SampleProfileHeaderFormat);
  614. //
  615. // Mow dump the buffer.
  616. //
  617. NextHook = PerfNextHook();
  618. Hook = PerfFirstHook();
  619. LogSize = (ULONG) NextHook - (ULONG) Hook;
  620. // fprintf(stderr, "Size in Pages %8d\n", PerfQueryBufferSize4KPages());
  621. // fprintf(stderr, "Size in Bytes %8d\n", PerfQueryBufferSizeBytes());
  622. // fprintf(stderr, "Size in KBs %8d\n", PerfQueryBufferSizeKB());
  623. // fprintf(stderr, "Size in Bytes %8d (%8x - %8x) \n", NextHook - Hook, Hook, NextHook);
  624. while( Hook < NextHook ){
  625. ULONG LogType;
  626. Hook = (PerfHook_t *)PerfGetHook(Hook, &Tag, &TS, &Size, &Info );
  627. LogType = Tag.u.Bits.HookId;
  628. // LogType = Tag.u.Value;
  629. // PerfCounter = 0xffffffffffffffff;
  630. PerfCounter = TS;
  631. if (Debug) {
  632. // fprintf(stdout, "%8x: LogType %4d, Size:%4d, Time: %I64u\n",Hook, LogType, Size, PerfCounter);
  633. }
  634. switch(LogType) {
  635. printf ("LogType=%08x\n", LogType);
  636. case PERF_APIMON_DLL_ADDRESS:
  637. {
  638. PPerf_Apimon_Dll_Address_t DllInfo;
  639. DllInfo = (PPerf_Apimon_Dll_Address_t) Info;
  640. InsertDll(DllInfo->StartingAddress,
  641. DllInfo->EndingAddress,
  642. DllInfo->DllName);
  643. printf ("DllAddressName %08x %08x %s\n",
  644. DllInfo->StartingAddress,
  645. DllInfo->EndingAddress,
  646. DllInfo->DllName);
  647. }
  648. break;
  649. case PERF_APIMON_API_ADDRESS:
  650. {
  651. PPerf_Apimon_Api_Address_t ApiInfo;
  652. ApiInfo = (PPerf_Apimon_Api_Address_t) Info;
  653. InsertApi(ApiInfo->Address,
  654. ApiInfo->ApiName);
  655. printf ("ApiAddressName %08x %s\n",
  656. ApiInfo->Address,
  657. ApiInfo->ApiName);
  658. }
  659. break;
  660. case PERF_APIMON_ENTER:
  661. {
  662. PPerf_Apimon_Enter_t PEnter;
  663. PEnter = (PPerf_Apimon_Api_Address_t) Info;
  664. printf ("ApiEnter %08x %s %s\n",
  665. PEnter->Address,
  666. DllContainingAddress(PEnter->Address),
  667. ApiAtAddress(PEnter->Address));
  668. }
  669. break;
  670. case PERF_APIMON_EXIT:
  671. {
  672. PPerf_Apimon_Enter_t PExit;
  673. PExit = (PPerf_Apimon_Api_Address_t) Info;
  674. printf ("ApiExit %08x %s %s\n",
  675. PExit->Address,
  676. DllContainingAddress(PExit->Address),
  677. ApiAtAddress(PExit->Address));
  678. }
  679. break;
  680. case MMINFO_LOG_TYPE_VERSION:
  681. {
  682. PSYSTEM_MMINFO_VERSION_INFORMATION TmpPMmInfoVersion;
  683. TmpPMmInfoVersion = (PSYSTEM_MMINFO_VERSION_INFORMATION) Info;
  684. if (TmpPMmInfoVersion->Version != MMINFO_VERSION) {
  685. fprintf(stderr, "Kernel Version:%4d mismatch with User Version:%d\n",
  686. TmpPMmInfoVersion->Version,
  687. MMINFO_VERSION
  688. );
  689. ExitProcess(1);
  690. } else {
  691. fprintf(stderr, "Version: %4d, BufferSize = %6d KB\n",
  692. MMINFO_VERSION,
  693. LogSize/1024);
  694. fprintf(stdout, "Version, %4d, BufferSize, %6d KB\n",
  695. MMINFO_VERSION,
  696. LogSize/1024);
  697. }
  698. }
  699. break;
  700. case MMINFO_LOG_TYPE_PERFFREQUENCY:
  701. {
  702. PMMINFO_TIME_FREQUENCY TimeFreq;
  703. TimeFreq = (PMMINFO_TIME_FREQUENCY) Info;
  704. PerfFrequency = TimeFreq->Frequency;
  705. PerfCounterStart = TimeFreq->Time;
  706. printf("Log start at (Performance Counter), %I64d\n",
  707. PerfCounterStart*1000000/PerfFrequency);
  708. }
  709. break;
  710. case MMINFO_LOG_TYPE_FILENAMEBUFFER:
  711. {
  712. PSYSTEM_MMINFO_FILENAME_INFORMATION TmpPImage;
  713. TmpPImage = (PSYSTEM_MMINFO_FILENAME_INFORMATION) Info;
  714. while (TmpPImage->ImageKey) {
  715. i=TmpPImage->ImageKey%TableSize;
  716. while(ImageHash[i].ImageKey != 0) {
  717. if (ImageHash[i].ImageKey == TmpPImage->ImageKey) {
  718. break;
  719. }else{
  720. i = (i+1)%TableSize;
  721. }
  722. }
  723. ImageHash[i].ImageKey =TmpPImage->ImageKey;
  724. ImageHash[i].ImageName.Length =TmpPImage->ImageName.Length;
  725. ImageHash[i].ImageName.Buffer =TmpPImage->ImageBuffer;
  726. if (Debug) {
  727. printf("%12s,", "S-Created");
  728. }
  729. if (Debug) {
  730. printf("%10s,%22s,%12s,%12x,%8s,%30S,%12s,%10s,%10s\n",
  731. "",
  732. "",
  733. "",
  734. ImageHash[i].ImageKey,
  735. "",
  736. ImageHash[i].ImageName.Buffer,
  737. "",
  738. "",
  739. "");
  740. }
  741. TmpPImage++;
  742. }
  743. }
  744. break;
  745. case MMINFO_LOG_TYPE_PAGEFAULT:
  746. {
  747. PSYSTEM_HARDPAGEFAULT_INFORMATION TmpPMmInfoLog;
  748. TmpPMmInfoLog=(PSYSTEM_HARDPAGEFAULT_INFORMATION) Info;
  749. printf("%12s,","HardFault");
  750. printf("%10I64d,",
  751. (PerfCounter - PerfCounterStart)*1000000/PerfFrequency);
  752. if (TmpPMmInfoLog->ProcessID == 0) {
  753. printf("%22s,","System ( 0)");
  754. } else{
  755. ULONG i;
  756. i = TmpPMmInfoLog->ProcessID;
  757. if (ProcessHash[i].ProcessID == TmpPMmInfoLog->ProcessID) {
  758. printf("%16s ",ProcessHash[i].ImageFileName);
  759. printf("(%3d),",ProcessHash[i].ProcessID);
  760. }else{
  761. printf("Process %13u,",TmpPMmInfoLog->ProcessID);
  762. }
  763. }
  764. printf("%12u,",TmpPMmInfoLog->ThreadID);
  765. printf("%12x,",TmpPMmInfoLog->Va);
  766. printf("%8u,",TmpPMmInfoLog->Pfn);
  767. {
  768. ULONG i;
  769. i=TmpPMmInfoLog->ImageKey%TableSize;
  770. while(ImageHash[i].ImageKey != 0) {
  771. if (ImageHash[i].ImageKey == TmpPMmInfoLog->ImageKey) {
  772. printf("%30S,",ImageHash[i].ImageName.Buffer);
  773. break;
  774. }else{
  775. i = (i+1)%TableSize;
  776. }
  777. }
  778. if (ImageHash[i].ImageKey == 0) {
  779. if (TmpPMmInfoLog->Va >= 0x8000000) {
  780. printf("%30s,","pagefile.sys");
  781. } else {
  782. printf("%19s (%8x),","Image", TmpPMmInfoLog->ImageKey);
  783. }
  784. }
  785. }
  786. printf("%12I64d,",TmpPMmInfoLog->ReadOffset);
  787. printf("%10u,",TmpPMmInfoLog->ByteCount);
  788. if (TmpPMmInfoLog->FaultType == 3) {
  789. printf("%10s,","Read");
  790. } else if (TmpPMmInfoLog->FaultType == 2) {
  791. printf("%10s,","Code");
  792. } else if (TmpPMmInfoLog->FaultType == 1) {
  793. printf("%10s,","Data");
  794. } else {
  795. printf("%10s,","NA");
  796. }
  797. printf("%10I64d",
  798. (TmpPMmInfoLog->IoCompleteTime-PerfCounter)
  799. *1000000/PerfFrequency);
  800. printf("\n");
  801. // printf("Got Page Fault Log\n");
  802. break;
  803. }
  804. case MMINFO_LOG_TYPE_TRANSITIONFAULT:
  805. case MMINFO_LOG_TYPE_DEMANDZEROFAULT:
  806. case MMINFO_LOG_TYPE_ADDVALIDPAGETOWS:
  807. case MMINFO_LOG_TYPE_PROTOPTEFAULT:
  808. case MMINFO_LOG_TYPE_ADDTOWS:
  809. {
  810. PSYSTEM_MMINFO_SOFTFAULT_INFORMATION TmpPMmInfoLog;
  811. TmpPMmInfoLog=(PSYSTEM_MMINFO_SOFTFAULT_INFORMATION) Info;
  812. if (LogType == MMINFO_LOG_TYPE_TRANSITIONFAULT) {
  813. printf("%12s,","TransFault");
  814. } else if (LogType == MMINFO_LOG_TYPE_DEMANDZEROFAULT) {
  815. printf("%12s,","DeZeroFault");
  816. } else if (LogType == MMINFO_LOG_TYPE_ADDVALIDPAGETOWS) {
  817. printf("%12s,","AddValidToWS");
  818. } else if (LogType == MMINFO_LOG_TYPE_PROTOPTEFAULT) {
  819. printf("%12s,","ProtoFault");
  820. } else if (LogType == MMINFO_LOG_TYPE_ADDTOWS) {
  821. printf("%12s,","AddToWS");
  822. } else {
  823. printf("%12s,","Unknown");
  824. }
  825. printf("%10s,", "");
  826. if (TmpPMmInfoLog->ProcessID == -1) {
  827. printf("%22s,","SystemCache");
  828. } else{
  829. ULONG i;
  830. i = TmpPMmInfoLog->ProcessID;
  831. if (ProcessHash[i].ProcessID == TmpPMmInfoLog->ProcessID) {
  832. printf("%16s ",ProcessHash[i].ImageFileName);
  833. printf("(%3d),",ProcessHash[i].ProcessID);
  834. }else{
  835. printf("Process %13u,",TmpPMmInfoLog->ProcessID);
  836. }
  837. }
  838. printf("%12u,",TmpPMmInfoLog->ThreadID);
  839. printf("%12x,",TmpPMmInfoLog->Va);
  840. printf("%8u",TmpPMmInfoLog->Pfn);
  841. printf("\n");
  842. break;
  843. }
  844. case MMINFO_LOG_TYPE_WORKINGSETSNAP:
  845. {
  846. PSYSTEM_MMINFO_WSENTRY_INFORMATION TmpPWs;
  847. PMMINFO_WSENTRY TmpPWsEntry;
  848. ULONG Size;
  849. ULONG ii;
  850. UCHAR Process[22];
  851. TmpPWs = (PSYSTEM_MMINFO_WSENTRY_INFORMATION) Info;
  852. Size = TmpPWs->WsSize;
  853. TmpPWsEntry = TmpPWs->Ws;
  854. if (TmpPWs->ProcessID == -1) {
  855. sprintf(Process,"%22s","SystemCache");
  856. } else {
  857. ULONG i;
  858. i = TmpPWs->ProcessID;
  859. if (ProcessHash[i].ProcessID == TmpPWs->ProcessID) {
  860. sprintf(Process, "%16s (%3d)",
  861. ProcessHash[i].ImageFileName,
  862. ProcessHash[i].ProcessID);
  863. }else{
  864. sprintf(Process,"Process %13u",TmpPWs->ProcessID);
  865. }
  866. }
  867. for (ii = 1; ii <= Size; ii++) {
  868. printf("%12s,%10s,%22s,%12u,%12x,%8u,%s,%s",
  869. "WsSnap",
  870. "",
  871. Process,
  872. ii,
  873. TmpPWsEntry->Va.Page << 12,
  874. TmpPWsEntry->Pa.Page,
  875. TmpPWsEntry->Pa.Accessed ?
  876. "Accessed" : "NotAccessed",
  877. TmpPWsEntry->Pa.Modified ?
  878. "Modified" : "NotModified",
  879. TmpPWsEntry->Pa.Shared ?
  880. "Shared" : "NotShared"
  881. );
  882. #ifdef WS_INSTRUMENTATION_ACCESS_BIT
  883. printf(",%s",
  884. TmpPWsEntry->Pa.RecentlyUsed ?
  885. "RecentlyUsed" : "NotRecentlyUsed"
  886. );
  887. #endif // WS_INSTRUMENTATION_ACCESS_BIT
  888. printf("\n");
  889. TmpPWsEntry++;
  890. }
  891. // printf("Size = %d\n", Size);
  892. break;
  893. }
  894. case MMINFO_LOG_TYPE_OUTWS_REPLACEUSED:
  895. case MMINFO_LOG_TYPE_OUTWS_REPLACEUNUSED:
  896. case MMINFO_LOG_TYPE_OUTWS_VOLUNTRIM:
  897. case MMINFO_LOG_TYPE_OUTWS_FORCETRIM:
  898. case MMINFO_LOG_TYPE_OUTWS_ADJUSTWS:
  899. case MMINFO_LOG_TYPE_OUTWS_EMPTYQ:
  900. {
  901. PSYSTEM_MMINFO_WSCHANGE_INFORMATION TmpPMmInfoLog;
  902. TmpPMmInfoLog=(PSYSTEM_MMINFO_WSCHANGE_INFORMATION) Info;
  903. printf("%12s,","Out_Of_WS");
  904. if (LogType == MMINFO_LOG_TYPE_OUTWS_REPLACEUSED) {
  905. printf("%10s,","RepUsed");
  906. } else if (LogType == MMINFO_LOG_TYPE_OUTWS_REPLACEUNUSED) {
  907. printf("%10s,","RepUnUsed");
  908. } else if (LogType == MMINFO_LOG_TYPE_OUTWS_VOLUNTRIM) {
  909. printf("%10s,","VolunTrim");
  910. } else if (LogType == MMINFO_LOG_TYPE_OUTWS_FORCETRIM) {
  911. printf("%10s,","ForceTrim");
  912. } else if (LogType == MMINFO_LOG_TYPE_OUTWS_ADJUSTWS) {
  913. printf("%10s,","AdjustWs");
  914. } else if (LogType == MMINFO_LOG_TYPE_OUTWS_EMPTYQ) {
  915. printf("%10s,","EmptyQ");
  916. } else {
  917. printf("%10s,","Unknown");
  918. }
  919. if (TmpPMmInfoLog->ProcessID == 0) {
  920. printf("%22s,","SystemCache");
  921. } else{
  922. ULONG i;
  923. i = TmpPMmInfoLog->ProcessID;
  924. if (ProcessHash[i].ProcessID == TmpPMmInfoLog->ProcessID) {
  925. printf("%16s ",ProcessHash[i].ImageFileName);
  926. printf("(%3d),",ProcessHash[i].ProcessID);
  927. }else{
  928. printf("Process %13u,",TmpPMmInfoLog->ProcessID);
  929. }
  930. }
  931. printf("%12s,","");
  932. printf("%12x,",TmpPMmInfoLog->Entry.Va.Page << 12);
  933. printf("%8u",TmpPMmInfoLog->Entry.Pa.Page);
  934. printf("\n");
  935. break;
  936. }
  937. case MMINFO_LOG_TYPE_WSINFOCACHE:
  938. case MMINFO_LOG_TYPE_TRIMCACHE:
  939. case MMINFO_LOG_TYPE_WSINFOPROCESS:
  940. case MMINFO_LOG_TYPE_TRIMPROCESS:
  941. {
  942. PSYSTEM_MMINFO_TRIMPROCESS_INFORMATION TmpPMmInfoTrimProcess;
  943. TmpPMmInfoTrimProcess = (PSYSTEM_MMINFO_TRIMPROCESS_INFORMATION) Info;
  944. if ((LogType == MMINFO_LOG_TYPE_WSINFOPROCESS) ||
  945. (LogType == MMINFO_LOG_TYPE_WSINFOCACHE)) {
  946. printf("%12s,","WsInfo");
  947. } else {
  948. printf("%12s,","Triming");
  949. }
  950. printf("WS:%7d,", TmpPMmInfoTrimProcess->ProcessWorkingSet);
  951. if ((LogType == MMINFO_LOG_TYPE_TRIMCACHE) ||
  952. (LogType == MMINFO_LOG_TYPE_WSINFOCACHE)) {
  953. printf("%22s,","SystemCache");
  954. } else{
  955. if (TmpPMmInfoTrimProcess->ProcessID == 0) {
  956. printf("%30s,","System ( 0)");
  957. } else {
  958. ULONG i;
  959. i = TmpPMmInfoTrimProcess->ProcessID;
  960. if (ProcessHash[i].ProcessID == TmpPMmInfoTrimProcess->ProcessID) {
  961. printf("%16s ",ProcessHash[i].ImageFileName);
  962. printf("(%3d),",ProcessHash[i].ProcessID);
  963. }else{
  964. printf("Process %13u,",TmpPMmInfoTrimProcess->ProcessID);
  965. }
  966. }
  967. }
  968. printf("Need:%7d,", TmpPMmInfoTrimProcess->ToTrim);
  969. printf("Got:%8d,", TmpPMmInfoTrimProcess->ActualTrim);
  970. printf("Pri:%4d,", TmpPMmInfoTrimProcess->ProcessMemoryPriority);
  971. printf("PageFaults:%8d,",
  972. TmpPMmInfoTrimProcess->ProcessPageFaultCount-
  973. TmpPMmInfoTrimProcess->ProcessLastPageFaultCount);
  974. if ((LogType == MMINFO_LOG_TYPE_WSINFOPROCESS) ||
  975. (LogType == MMINFO_LOG_TYPE_WSINFOCACHE)) {
  976. printf("Acc:%4d,",
  977. TmpPMmInfoTrimProcess->ProcessAccessedCount);
  978. printf("Mod:%4d,",
  979. TmpPMmInfoTrimProcess->ProcessModifiedCount);
  980. printf("Shd:%4d,",
  981. TmpPMmInfoTrimProcess->ProcessSharedCount);
  982. #ifdef WS_INSTRUMENTATION_ACCESS_BIT
  983. printf("RUsed:%4d,",
  984. TmpPMmInfoTrimProcess->ProcessRecentlyUsedCount);
  985. #endif // WS_INSTRUMENTATION_ACCESS_BIT
  986. }
  987. #ifdef WS_INSTRUMENTATION
  988. printf("Replacments:%5d,",
  989. TmpPMmInfoTrimProcess->ProcessReplacementCount);
  990. printf("QuotaBoosts:%5d,",
  991. TmpPMmInfoTrimProcess->ProcessQuotaBoostCount);
  992. printf("UsedRepls:%5d,",
  993. TmpPMmInfoTrimProcess->ProcessSparecount3);
  994. printf("FaultsSinceQInc:%5d,",
  995. TmpPMmInfoTrimProcess->ProcessPageFaultCount-
  996. TmpPMmInfoTrimProcess->ProcessLastGrowthFaultCount);
  997. printf("FaultSinceFGTrim:%5d,",
  998. TmpPMmInfoTrimProcess->ProcessPageFaultCount -
  999. TmpPMmInfoTrimProcess->
  1000. ProcessLastForegroundTrimFaultCount);
  1001. printf("Spare4:%5d,",
  1002. TmpPMmInfoTrimProcess->ProcessSparecount4);
  1003. printf("Spare5:%2d,",
  1004. TmpPMmInfoTrimProcess->ProcessSparecount5);
  1005. #endif // WS_INSTRUMENTATION
  1006. printf("\n");
  1007. break;
  1008. }
  1009. case MMINFO_LOG_TYPE_POOLSTAT:
  1010. case MMINFO_LOG_TYPE_ADDPOOLPAGE:
  1011. case MMINFO_LOG_TYPE_FREEPOOLPAGE:
  1012. {
  1013. PSYSTEM_MMINFO_POOL_INFORMATION TmpPMmInfoPool;
  1014. TmpPMmInfoPool = (PSYSTEM_MMINFO_POOL_INFORMATION) Info;
  1015. if (LogType == MMINFO_LOG_TYPE_ADDPOOLPAGE) {
  1016. printf("%12s,","AddPoolPage");
  1017. } else if (LogType == MMINFO_LOG_TYPE_FREEPOOLPAGE) {
  1018. printf("%12s,","FreePoolPage");
  1019. } else{
  1020. printf("%12s,","PoolSummary");
  1021. }
  1022. printf("%10s,%22d,%12s,%12x,%8d,%8d,%8d,%12d,%12d\n",
  1023. "",
  1024. (int) TmpPMmInfoPool->Pool /100,
  1025. PoolTypeNames[(TmpPMmInfoPool->Pool%100) & 7],
  1026. TmpPMmInfoPool->Entry,
  1027. TmpPMmInfoPool->Alloc,
  1028. TmpPMmInfoPool->DeAlloc,
  1029. TmpPMmInfoPool->TotalPages,
  1030. TmpPMmInfoPool->TotalBytes,
  1031. // TmpPMmInfoPool->TotalBytes*100/4096/TmpPMmInfoPool->TotalPages,
  1032. // TmpPMmInfoPool->TotalBigBytes,
  1033. TmpPMmInfoPool->TotalBigPages
  1034. // TmpPMmInfoPool->TotalBigBytes*100/4096/TmpPMmInfoPool->TotalBigPages
  1035. );
  1036. break;
  1037. }
  1038. case MMINFO_LOG_TYPE_WORKINGSETMANAGER:
  1039. {
  1040. PSYSTEM_WORKINGSETMANAGER_INFORMATION TmpPWorkingSetManager;
  1041. char *ActionString;
  1042. TmpPWorkingSetManager = (PSYSTEM_WORKINGSETMANAGER_INFORMATION) Info;
  1043. switch(TmpPWorkingSetManager->Action) {
  1044. case WS_ACTION_RESET_COUNTER:
  1045. ActionString = "Reset Counter";
  1046. break;
  1047. case WS_ACTION_NOTHING:
  1048. ActionString = "Nothing";
  1049. break;
  1050. case WS_ACTION_INCREMENT_COUNTER:
  1051. ActionString = "Increment Counter";
  1052. break;
  1053. case WS_ACTION_WILL_TRIM:
  1054. ActionString = "Start Trimming";
  1055. break;
  1056. case WS_ACTION_FORCE_TRIMMING_PROCESS:
  1057. ActionString = "Force Trim";
  1058. break;
  1059. case WS_ACTION_WAIT_FOR_WRITER:
  1060. ActionString = "Wait writter";
  1061. break;
  1062. case WS_ACTION_EXAMINED_ALL_PROCESS:
  1063. ActionString = "All Process Examed";
  1064. break;
  1065. case WS_ACTION_AMPLE_PAGES_EXIST:
  1066. ActionString = "Ample Pages Exist";
  1067. break;
  1068. case WS_ACTION_END_WALK_ENTRIES:
  1069. ActionString = "Finished Walking WsEntries";
  1070. break;
  1071. default:
  1072. ActionString = "Unknown Action";
  1073. break;
  1074. }
  1075. printf(WsManagerDataFormat,
  1076. (PerfCounter - PerfCounterStart) *1000000/PerfFrequency,
  1077. TmpPWorkingSetManager->Available,
  1078. TmpPWorkingSetManager->PageFaultCount,
  1079. TmpPWorkingSetManager->LastPageFaultCount,
  1080. TmpPWorkingSetManager->MiCheckCounter,
  1081. TmpPWorkingSetManager->DesiredReductionGoal,
  1082. TmpPWorkingSetManager->DesiredFreeGoal,
  1083. ActionString
  1084. );
  1085. break;
  1086. }
  1087. case MMINFO_LOG_TYPE_REMOVEPAGEFROMLIST:
  1088. case MMINFO_LOG_TYPE_REMOVEPAGEBYCOLOR:
  1089. case MMINFO_LOG_TYPE_PAGEINMEMORY:
  1090. case MMINFO_LOG_TYPE_MEMORYSNAP:
  1091. case MMINFO_LOG_TYPE_SETPFNDELETED:
  1092. case MMINFO_LOG_TYPE_DELETEKERNELSTACK:
  1093. {
  1094. PSYSTEM_REMOVEDPAGE_INFORMATION TmpPRemovedPage;
  1095. TmpPRemovedPage=(PSYSTEM_REMOVEDPAGE_INFORMATION) Info;
  1096. if (LogType == MMINFO_LOG_TYPE_PAGEINMEMORY) {
  1097. printf("%12s,","InMemory");
  1098. }else if (LogType == MMINFO_LOG_TYPE_MEMORYSNAP) {
  1099. printf("%12s,","MemSnap");
  1100. }else if (LogType == MMINFO_LOG_TYPE_SETPFNDELETED) {
  1101. printf("%12s,","PfnDeleted");
  1102. }else if (LogType == MMINFO_LOG_TYPE_DELETEKERNELSTACK) {
  1103. printf("%12s,","DeleteStack");
  1104. }else {
  1105. printf("%12s,","PageRemoved");
  1106. }
  1107. printf("%10I64d,",
  1108. (PerfCounter - PerfCounterStart)
  1109. *1000000/PerfFrequency);
  1110. printf("%22s,","");
  1111. printf("%12x,",TmpPRemovedPage->Pte);
  1112. // printf("%30S,",.ImageName.Buffer);
  1113. switch(TmpPRemovedPage->UsedFor) {
  1114. case MMINFO_PAGE_USED_FOR_PAGEDPOOL:
  1115. printf("%12x,",TmpPRemovedPage->Pte<<10);
  1116. printf("%8u,",TmpPRemovedPage->Pfn);
  1117. printf("%30s,","Paged Pool");
  1118. printf("%12s,%10s,%10s,","","","PagedPool");
  1119. break;
  1120. case MMINFO_PAGE_USED_FOR_NONPAGEDPOOL:
  1121. printf("%12x,",TmpPRemovedPage->Pte<<10);
  1122. printf("%8u,",TmpPRemovedPage->Pfn);
  1123. printf("%30s,","NonPaged Pool");
  1124. printf("%12s,%10s,%10s,","","","NonPagedP");
  1125. break;
  1126. case MMINFO_PAGE_USED_FOR_KERNELSTACK:
  1127. printf("%12x,",TmpPRemovedPage->Pte<<10);
  1128. printf("%8u,",TmpPRemovedPage->Pfn);
  1129. printf("%30s,","Kernel Stack");
  1130. printf("%12s,%10s,%10s,","","","K-Stack");
  1131. break;
  1132. case MMINFO_PAGE_USED_FOR_FREEPAGE:
  1133. printf("%12s,","");
  1134. printf("%8u,",TmpPRemovedPage->Pfn);
  1135. printf("%30s,","Free Page");
  1136. printf("%12s,%10s,%10s,","","","Free");
  1137. break;
  1138. case MMINFO_PAGE_USED_FOR_ZEROPAGE:
  1139. printf("%12s,","");
  1140. printf("%8u,",TmpPRemovedPage->Pfn);
  1141. printf("%30s,","Zero Page");
  1142. printf("%12s,%10s,%10s,","","","Zero");
  1143. break;
  1144. case MMINFO_PAGE_USED_FOR_BADPAGE:
  1145. printf("%12s,","");
  1146. printf("%8u,",TmpPRemovedPage->Pfn);
  1147. printf("%30s,","Bad Page");
  1148. printf("%12s,%10s,%10s,","","","Bad");
  1149. break;
  1150. case MMINFO_PAGE_USED_FOR_UNKNOWN:
  1151. printf("%12s,","");
  1152. printf("%8u,",TmpPRemovedPage->Pfn);
  1153. printf("%30s,","Unknown");
  1154. printf("%12s,%10s,%10s,","","","Unknown");
  1155. break;
  1156. case MMINFO_PAGE_USED_FOR_METAFILE:
  1157. printf("%12s,","");
  1158. printf("%8u,",TmpPRemovedPage->Pfn);
  1159. printf("%30s,","Meta File");
  1160. printf("%12s,%10s,%10s,","","","Meta");
  1161. break;
  1162. case MMINFO_PAGE_USED_FOR_NONAME:
  1163. printf("%12s,","");
  1164. printf("%8u,",TmpPRemovedPage->Pfn);
  1165. printf("%30s,","No Name");
  1166. printf("%12s,%10s,%10s,","","","Image");
  1167. break;
  1168. case MMINFO_PAGE_USED_FOR_PAGEFILEMAPPED:
  1169. printf("%12x,",TmpPRemovedPage->Pte<<10);
  1170. printf("%8u,",TmpPRemovedPage->Pfn);
  1171. printf("%30s,","Page File Mapped");
  1172. printf("%12s,%10s,%10s,","","","PFMapped");
  1173. break;
  1174. case MMINFO_PAGE_USED_FOR_FILE:
  1175. case MMINFO_PAGE_USED_FOR_KERNMAP:
  1176. {
  1177. ULONG i,j;
  1178. if (TmpPRemovedPage->UsedFor != MMINFO_PAGE_USED_FOR_KERNMAP) {
  1179. printf("%12s,","");
  1180. } else {
  1181. printf("%12x,",TmpPRemovedPage->Pte << 10);
  1182. }
  1183. printf("%8u,",TmpPRemovedPage->Pfn);
  1184. i=TmpPRemovedPage->ImageKey%TableSize;
  1185. while(ImageHash[i].ImageKey != 0) {
  1186. if (ImageHash[i].ImageKey == TmpPRemovedPage->ImageKey) {
  1187. printf("%30S,",ImageHash[i].ImageName.Buffer);
  1188. break;
  1189. }else{
  1190. i = (i+1)%TableSize;
  1191. }
  1192. }
  1193. if (Debug) {
  1194. // printf("(%4d %22x)",i,TmpPRemovedPage->ImageKey);
  1195. }
  1196. if (ImageHash[i].ImageKey == 0) {
  1197. if (TmpPRemovedPage->UsedFor != MMINFO_PAGE_USED_FOR_KERNMAP) {
  1198. printf("%19s (%8x),","Image", TmpPRemovedPage->ImageKey);
  1199. printf("%12I64d,",TmpPRemovedPage->Offset);
  1200. printf("%10s,","");
  1201. printf("%10s,","FILE");
  1202. }else{
  1203. printf("%19s (%8x),","KernMap", TmpPRemovedPage->ImageKey);
  1204. printf("%12s,%10s,","","");
  1205. printf("%10s,","Driver");
  1206. }
  1207. }else{
  1208. if (TmpPRemovedPage->UsedFor == MMINFO_PAGE_USED_FOR_KERNMAP) {
  1209. printf("%12I64d,",TmpPRemovedPage->Offset);
  1210. printf("%10s,","");
  1211. printf("%10s,","Driver");
  1212. }else if (TmpPRemovedPage->UsedFor == MMINFO_PAGE_USED_FOR_FILE) {
  1213. printf("%12I64d,",TmpPRemovedPage->Offset);
  1214. printf("%10s,","");
  1215. printf("%10s,","FILE");
  1216. }else{
  1217. printf("%12s,%10s,","","");
  1218. printf("%10s,","Unknown");
  1219. }
  1220. }
  1221. }
  1222. break;
  1223. case MMINFO_PAGE_USED_FOR_PROCESS:
  1224. case MMINFO_PAGE_USED_FOR_PAGETABLE:
  1225. {
  1226. ULONG i;
  1227. // Bug! Bug! The way to get VA can be wrong in the future.
  1228. if (TmpPRemovedPage->UsedFor == MMINFO_PAGE_USED_FOR_PAGETABLE) {
  1229. printf("%12x,",TmpPRemovedPage->Pte<<10);
  1230. printf("%8u,",TmpPRemovedPage->Pfn);
  1231. printf("(PT)");
  1232. }else{
  1233. printf("%12x,",TmpPRemovedPage->Pte<<10);
  1234. printf("%8u,",TmpPRemovedPage->Pfn);
  1235. printf(" ");
  1236. }
  1237. if (TmpPRemovedPage->ImageKey == 0) {
  1238. printf("%26s,","System ( 0)");
  1239. }else{
  1240. i = TmpPRemovedPage->ImageKey;
  1241. if (ProcessHash[i].ProcessID == TmpPRemovedPage->ImageKey) {
  1242. printf("%20s ",ProcessHash[i].ImageFileName);
  1243. printf("(%3d),",ProcessHash[i].ProcessID);
  1244. }else{
  1245. printf("Process %18u,",TmpPRemovedPage->ImageKey);
  1246. }
  1247. }
  1248. if (TmpPRemovedPage->UsedFor == MMINFO_PAGE_USED_FOR_PAGETABLE) {
  1249. // printf("%12I64d,",TmpPRemovedPage->Offset);
  1250. printf("%12s,%10s,%10s,","","","PageTable");
  1251. }else{
  1252. printf("%12s,%10s,%10s,","","","Process");
  1253. // printf("%30s,","Page Table");
  1254. }
  1255. }
  1256. break;
  1257. default:
  1258. printf("Error2 %22u,",TmpPRemovedPage->ImageKey);
  1259. break;
  1260. }
  1261. switch(TmpPRemovedPage->List) {
  1262. case MMINFO_PAGE_IN_LIST_FREEPAGE:
  1263. printf("%10s","Free List");
  1264. break;
  1265. case MMINFO_PAGE_IN_LIST_ZEROPAGE:
  1266. printf("%10s","Zero List");
  1267. break;
  1268. case MMINFO_PAGE_IN_LIST_BADPAGE:
  1269. printf("%10s","Bad List");
  1270. break;
  1271. case MMINFO_PAGE_IN_LIST_STANDBY:
  1272. printf("%10s","Standby");
  1273. break;
  1274. case MMINFO_PAGE_IN_LIST_TRANSITION:
  1275. printf("%10s","Transition");
  1276. break;
  1277. case MMINFO_PAGE_IN_LIST_MODIFIED:
  1278. printf("%10s","Modified");
  1279. break;
  1280. case MMINFO_PAGE_IN_LIST_MODIFIEDNOWRITE:
  1281. printf("%10s","ModNoWrite");
  1282. break;
  1283. case MMINFO_PAGE_IN_LIST_ACTIVEANDVALID:
  1284. printf("%10s","Valid");
  1285. break;
  1286. case MMINFO_PAGE_IN_LIST_VALIDANDPINNED:
  1287. printf("%10s","Valid_Pin");
  1288. break;
  1289. case MMINFO_PAGE_IN_LIST_UNKNOWN:
  1290. printf("%10s","Unknown");
  1291. break;
  1292. default:
  1293. // must be page table
  1294. printf("%10s","");
  1295. break;
  1296. }
  1297. printf("\n");
  1298. // printf("Got Removed Page Log\n");
  1299. break;
  1300. }
  1301. case MMINFO_LOG_TYPE_ZEROSHARECOUNT:
  1302. case MMINFO_LOG_TYPE_ZEROREFCOUNT:
  1303. case MMINFO_LOG_TYPE_DECREFCNT:
  1304. case MMINFO_LOG_TYPE_DECSHARCNT:
  1305. {
  1306. PSYSTEM_MMINFO_PFN_INFORMATION TmpPPfn;
  1307. TmpPPfn = (PSYSTEM_MMINFO_PFN_INFORMATION) Info;
  1308. if (LogType == MMINFO_LOG_TYPE_DECSHARCNT) {
  1309. printf("%12s,", "DecShareCnt");
  1310. } else if (LogType == MMINFO_LOG_TYPE_ZEROSHARECOUNT) {
  1311. printf("%12s,", "ZeroShareCnt");
  1312. } else if (LogType == MMINFO_LOG_TYPE_DECREFCNT) {
  1313. printf("%12s,", "DecRefCnt");
  1314. } else if (LogType == MMINFO_LOG_TYPE_ZEROREFCOUNT) {
  1315. printf("%12s,", "ZeroRefCnt");
  1316. } else {
  1317. printf("%12s,", "UNKNOWN");
  1318. }
  1319. printf("%10s,","");
  1320. printf("%22s,","");
  1321. printf("%12s,","");
  1322. printf("%12s,","");
  1323. printf("%8u\n",TmpPPfn->Pfn);
  1324. break;
  1325. }
  1326. case MMINFO_LOG_TYPE_INSERTINLIST:
  1327. case MMINFO_LOG_TYPE_INSERTATFRONT:
  1328. case MMINFO_LOG_TYPE_UNLINKFROMSTANDBY:
  1329. case MMINFO_LOG_TYPE_UNLINKFFREEORZERO:
  1330. {
  1331. PSYSTEM_MMINFO_STATE_INFORMATION TmpPMmInfoState;
  1332. TmpPMmInfoState=(PSYSTEM_MMINFO_STATE_INFORMATION) Info;
  1333. if (LogType == MMINFO_LOG_TYPE_INSERTINLIST) {
  1334. printf("%12s,%10s,","Insert-List", "");
  1335. }else if (LogType == MMINFO_LOG_TYPE_INSERTATFRONT) {
  1336. printf("%12s,%10s,","Insert-Front", "");
  1337. }else if (LogType == MMINFO_LOG_TYPE_UNLINKFROMSTANDBY) {
  1338. printf("%12s,%10s,","Unlink-From", "");
  1339. }else if (LogType == MMINFO_LOG_TYPE_UNLINKFFREEORZERO) {
  1340. printf("%12s,%10s,","Unlink-From", "");
  1341. }
  1342. printf("%22s,","");
  1343. printf("%12s,","");
  1344. printf("%12s,","");
  1345. printf("%8u,",TmpPMmInfoState->Pfn);
  1346. printf("%30s,","");
  1347. printf("%12s,%10s,%10s,","","","");
  1348. switch(TmpPMmInfoState->List) {
  1349. case MMINFO_PAGE_IN_LIST_FREEPAGE:
  1350. printf("%10s","Free List");
  1351. break;
  1352. case MMINFO_PAGE_IN_LIST_ZEROPAGE:
  1353. printf("%10s","Zero List");
  1354. break;
  1355. case MMINFO_PAGE_IN_LIST_BADPAGE:
  1356. printf("%10s","Bad List");
  1357. break;
  1358. case MMINFO_PAGE_IN_LIST_STANDBY:
  1359. printf("%10s","Standby");
  1360. break;
  1361. case MMINFO_PAGE_IN_LIST_TRANSITION:
  1362. printf("%10s","Transition");
  1363. break;
  1364. case MMINFO_PAGE_IN_LIST_MODIFIED:
  1365. printf("%10s","Modified");
  1366. break;
  1367. case MMINFO_PAGE_IN_LIST_MODIFIEDNOWRITE:
  1368. printf("%10s","ModNoWrite");
  1369. break;
  1370. case MMINFO_PAGE_IN_LIST_ACTIVEANDVALID:
  1371. printf("%10s","Valid");
  1372. break;
  1373. case MMINFO_PAGE_IN_LIST_VALIDANDPINNED:
  1374. printf("%10s","Valid_Pin");
  1375. break;
  1376. case MMINFO_PAGE_IN_LIST_UNKNOWN:
  1377. printf("%10s","Unknown");
  1378. break;
  1379. default:
  1380. // must be page table
  1381. printf("%10s","");
  1382. break;
  1383. }
  1384. printf("\n");
  1385. // printf("Got Removed Page Log\n");
  1386. break;
  1387. }
  1388. case MMINFO_LOG_TYPE_IMAGENAME:
  1389. case MMINFO_LOG_TYPE_SECTIONREMOVED:
  1390. {
  1391. PSYSTEM_MMINFO_FILENAME_INFORMATION TmpPImage;
  1392. ULONG i;
  1393. TmpPImage=(PSYSTEM_MMINFO_FILENAME_INFORMATION) Info;
  1394. // printf("Got Image Log\n");
  1395. i=TmpPImage->ImageKey%TableSize;
  1396. while(ImageHash[i].ImageKey != 0) {
  1397. if (ImageHash[i].ImageKey == TmpPImage->ImageKey) {
  1398. break;
  1399. }else{
  1400. i = (i+1)%TableSize;
  1401. }
  1402. }
  1403. if (LogType == MMINFO_LOG_TYPE_IMAGENAME) {
  1404. ImageHash[i].ImageKey
  1405. =TmpPImage->ImageKey;
  1406. ImageHash[i].ImageName.Length
  1407. =TmpPImage->ImageName.Length;
  1408. ImageHash[i].ImageName.Buffer
  1409. =TmpPImage->ImageBuffer;
  1410. if (Debug) {
  1411. printf("%12s,", "S-Created");
  1412. }
  1413. }else{
  1414. if (Debug) {
  1415. printf("%12s,", "S-Deleted");
  1416. }
  1417. }
  1418. if (Debug) {
  1419. printf("%10s,%22s,%12s,%12x,%8s,%30S,%12s,%10s,%10s\n",
  1420. "",
  1421. "",
  1422. "",
  1423. ImageHash[i].ImageKey,
  1424. "",
  1425. ImageHash[i].ImageName.Buffer,
  1426. "",
  1427. "",
  1428. "");
  1429. }
  1430. break;
  1431. }
  1432. case MMINFO_LOG_TYPE_PROCESSNAME:
  1433. case MMINFO_LOG_TYPE_DIEDPROCESS:
  1434. {
  1435. PSYSTEM_MMINFO_PROCESS_INFORMATION TmpPProcess;
  1436. ULONG i;
  1437. TmpPProcess=(PSYSTEM_MMINFO_PROCESS_INFORMATION) Info;
  1438. if (LogType == MMINFO_LOG_TYPE_PROCESSNAME) {
  1439. i = TmpPProcess->ProcessID;
  1440. ProcessHash[i].ProcessID
  1441. =TmpPProcess->ProcessID;
  1442. RtlCopyMemory(ProcessHash[i].ImageFileName,
  1443. TmpPProcess->ImageFileName, 16);
  1444. printf("%12s,", "P-Created");
  1445. }else{
  1446. printf("%12s,", "P-Deleted");
  1447. }
  1448. printf("%10s,%16s (%3d)\n",
  1449. "",
  1450. ProcessHash[TmpPProcess->ProcessID].ImageFileName,
  1451. ProcessHash[TmpPProcess->ProcessID].ProcessID);
  1452. // printf("Got Process Log\n");
  1453. break;
  1454. }
  1455. case MMINFO_LOG_TYPE_OUTSWAPPROCESS:
  1456. case MMINFO_LOG_TYPE_INSWAPPROCESS:
  1457. {
  1458. PSYSTEM_MMINFO_SWAPPROCESS_INFORMATION TmpPProc;
  1459. ULONG i;
  1460. TmpPProc=(PSYSTEM_MMINFO_SWAPPROCESS_INFORMATION) Info;
  1461. if (LogType == MMINFO_LOG_TYPE_OUTSWAPPROCESS) {
  1462. printf("%12s,", "P-OutSwap");
  1463. }else{
  1464. printf("%12s,", "P-InSwap");
  1465. }
  1466. if (PerfCounter) {
  1467. printf("%10I64d,", ((PerfCounter - PerfCounterStart) * 1000000) / PerfFrequency);
  1468. } else {
  1469. printf("%10s,", "");
  1470. }
  1471. printf("%16s (%3d)",
  1472. ProcessHash[TmpPProc->ProcessID].ImageFileName,
  1473. ProcessHash[TmpPProc->ProcessID].ProcessID);
  1474. printf("\n");
  1475. break;
  1476. }
  1477. case MMINFO_LOG_TYPE_OUTSWAPSTACK:
  1478. case MMINFO_LOG_TYPE_INSWAPSTACK:
  1479. {
  1480. PSYSTEM_MMINFO_SWAPTHREAD_INFORMATION TmpPThread;
  1481. ULONG i;
  1482. TmpPThread=(PSYSTEM_MMINFO_SWAPTHREAD_INFORMATION) Info;
  1483. if (LogType == MMINFO_LOG_TYPE_OUTSWAPSTACK) {
  1484. printf("%12s,", "KS-OutSwap");
  1485. }else{
  1486. printf("%12s,", "KS-InSwap");
  1487. }
  1488. printf("%10d,%16s (%3d)",
  1489. TmpPThread->ThreadID,
  1490. ProcessHash[TmpPThread->ProcessID].ImageFileName,
  1491. ProcessHash[TmpPThread->ProcessID].ProcessID);
  1492. if (PerfCounter) {
  1493. printf(",%12I64d", ((PerfCounter - PerfCounterStart) * 1000000) / PerfFrequency);
  1494. }
  1495. printf("\n");
  1496. break;
  1497. }
  1498. case MMINFO_LOG_TYPE_CREATETHREAD:
  1499. case MMINFO_LOG_TYPE_GROWKERNELSTACK:
  1500. case MMINFO_LOG_TYPE_TERMINATETHREAD:
  1501. case MMINFO_LOG_TYPE_CONVERTTOGUITHREAD:
  1502. {
  1503. PSYSTEM_MMINFO_THREAD_INFORMATION TmpPThread;
  1504. ULONG i;
  1505. TmpPThread=(PSYSTEM_MMINFO_THREAD_INFORMATION) Info;
  1506. if (LogType == MMINFO_LOG_TYPE_CREATETHREAD) {
  1507. printf("%12s,", "T-Created");
  1508. ThreadHash[TmpPThread->ThreadID] = TmpPThread->ProcessID;
  1509. }else if (LogType == MMINFO_LOG_TYPE_GROWKERNELSTACK) {
  1510. printf("%12s,", "GrowStack");
  1511. }else if (LogType == MMINFO_LOG_TYPE_CONVERTTOGUITHREAD) {
  1512. printf("%12s,", "T-GUI");
  1513. }else{
  1514. printf("%12s,", "T-Deleted");
  1515. //
  1516. // Threads are sometimes set as deleted while still
  1517. // running. If we mark them as dead here we have
  1518. // a problem when they are cswitched out.
  1519. //
  1520. //ThreadHash[TmpPThread->ThreadID] = -1;
  1521. }
  1522. printf("%10d,%16s (%3d)",
  1523. TmpPThread->ThreadID,
  1524. ProcessHash[TmpPThread->ProcessID].ImageFileName,
  1525. ProcessHash[TmpPThread->ProcessID].ProcessID);
  1526. // printf("Got Process Log\n");
  1527. if (LogType != MMINFO_LOG_TYPE_TERMINATETHREAD) {
  1528. printf(",%12x",TmpPThread->StackBase);
  1529. printf(",%12x",TmpPThread->StackLimit);
  1530. if (TmpPThread->UserStackBase) {
  1531. printf(",%12x",TmpPThread->UserStackBase);
  1532. printf(",%12x",TmpPThread->UserStackLimit);
  1533. } else {
  1534. printf(",%12s","");
  1535. printf(",%12s","");
  1536. }
  1537. if (TmpPThread->WaitMode >= 0) {
  1538. if (TmpPThread->WaitMode) {
  1539. printf(",%8s", "Swapable");
  1540. } else {
  1541. printf(",%8s", "NonSwap");
  1542. }
  1543. }
  1544. }
  1545. printf("\n");
  1546. break;
  1547. }
  1548. case MMINFO_LOG_TYPE_CSWITCH:
  1549. {
  1550. PSYSTEM_MMINFO_CSWITCH_INFORMATION TmpPMmInfo;
  1551. ULONG OldProcessId;
  1552. ULONG NewProcessId;
  1553. TmpPMmInfo = (PSYSTEM_MMINFO_CSWITCH_INFORMATION) Info;
  1554. OldProcessId = ThreadHash[TmpPMmInfo->OldThreadId];
  1555. NewProcessId = ThreadHash[TmpPMmInfo->NewThreadId];
  1556. if ((OldProcessId == -1) || (NewProcessId == -1)) {
  1557. printf("Error: Bad thread value %d or %d\n",
  1558. TmpPMmInfo->OldThreadId,
  1559. TmpPMmInfo->NewThreadId
  1560. );
  1561. break;
  1562. }
  1563. printf("%12s,%10I64d,%11s,%16s,%10d,%16s (%3d), %10d,%16s (%3d),%4d,%4d,%8s\n",
  1564. "CSwitch",
  1565. ((PerfCounter - PerfCounterStart) *
  1566. 1000000) / PerfFrequency,
  1567. ThreadState[TmpPMmInfo->OldState],
  1568. (TmpPMmInfo->OldState == Waiting) ?
  1569. WaitReason[TmpPMmInfo->WaitReason] :
  1570. "",
  1571. TmpPMmInfo->OldThreadId,
  1572. ProcessHash[OldProcessId].ImageFileName,
  1573. OldProcessId,
  1574. TmpPMmInfo->NewThreadId,
  1575. ProcessHash[NewProcessId].ImageFileName,
  1576. NewProcessId,
  1577. TmpPMmInfo->OldThreadPri,
  1578. TmpPMmInfo->NewThreadPri,
  1579. (TmpPMmInfo->OldWaitMode) ? "Swapable" : "NonSwap"
  1580. );
  1581. break;
  1582. }
  1583. case MMINFO_LOG_TYPE_POOLSNAP:
  1584. {
  1585. #define PROTECTED_POOL 0x80000000
  1586. ULONG PoolTag[2]={0,0};
  1587. PMMINFO_POOL_TRACKER_TABLE TmpPMmInfopoolTrackTable;
  1588. TmpPMmInfopoolTrackTable=(PMMINFO_POOL_TRACKER_TABLE) Info;
  1589. PoolTag[0]=TmpPMmInfopoolTrackTable->Tag & ~PROTECTED_POOL;
  1590. // Data for Paged Pool
  1591. if (TmpPMmInfopoolTrackTable->PagedAllocs) {
  1592. printf("%12s,","PoolSnap");
  1593. printf("%10s,", PoolTag);
  1594. printf("%22s,","");
  1595. printf("%12s,%12s,","PagedPool","");
  1596. printf("%8u,%8u,%8u\n",
  1597. TmpPMmInfopoolTrackTable->PagedBytes,
  1598. TmpPMmInfopoolTrackTable->PagedAllocs,
  1599. TmpPMmInfopoolTrackTable->PagedFrees);
  1600. }
  1601. // Data for NonPaged Pool
  1602. if (TmpPMmInfopoolTrackTable->NonPagedAllocs) {
  1603. printf("%12s,","PoolSnap");
  1604. printf("%10s,", PoolTag);
  1605. printf("%22s,","");
  1606. printf("%12s,%12s,","NonPagedPool","");
  1607. printf("%8u,%8u,%8u\n",
  1608. TmpPMmInfopoolTrackTable->NonPagedBytes,
  1609. TmpPMmInfopoolTrackTable->NonPagedAllocs,
  1610. TmpPMmInfopoolTrackTable->NonPagedFrees);
  1611. }
  1612. break;
  1613. }
  1614. case MMINFO_LOG_TYPE_ALLOCATEPOOL:
  1615. case MMINFO_LOG_TYPE_BIGPOOLPAGE:
  1616. {
  1617. #define PROTECTED_POOL 0x80000000
  1618. ULONG PoolTag[2]={0,0};
  1619. PSYSTEM_MMINFO_ALLOCATEPOOL_INFORMATION TmpPMmInfoAllocatePool;
  1620. TmpPMmInfoAllocatePool=(PSYSTEM_MMINFO_ALLOCATEPOOL_INFORMATION) Info;
  1621. PoolTag[0]=TmpPMmInfoAllocatePool->PoolTag & ~PROTECTED_POOL;
  1622. if (LogType == MMINFO_LOG_TYPE_ALLOCATEPOOL) {
  1623. printf("%12s,", "Pool_Alloc");
  1624. printf("%10s,", PoolTag);
  1625. if (TmpPMmInfoAllocatePool->ProcessID == 0) {
  1626. printf("%22s,","System ( 0)");
  1627. } else{
  1628. ULONG i;
  1629. i = TmpPMmInfoAllocatePool->ProcessID;
  1630. if (ProcessHash[i].ProcessID == TmpPMmInfoAllocatePool->ProcessID) {
  1631. printf("%16s ",ProcessHash[i].ImageFileName);
  1632. printf("(%3d),",ProcessHash[i].ProcessID);
  1633. }else{
  1634. printf("Process %13u,",TmpPMmInfoAllocatePool->ProcessID);
  1635. }
  1636. }
  1637. }else{
  1638. printf("%12s,","BigPoolPage");
  1639. printf("%10s,", PoolTag);
  1640. printf("%22s,","");
  1641. }
  1642. printf("%12s,%12x,%8u\n",
  1643. PoolTypeNames[TmpPMmInfoAllocatePool->PoolType & 7],
  1644. TmpPMmInfoAllocatePool->Entry,
  1645. TmpPMmInfoAllocatePool->Size);
  1646. break;
  1647. }
  1648. case MMINFO_LOG_TYPE_FREEPOOL:
  1649. {
  1650. PSYSTEM_MMINFO_FREEPOOL_INFORMATION TmpPMmInfoFreePool;
  1651. TmpPMmInfoFreePool=(PSYSTEM_MMINFO_FREEPOOL_INFORMATION) Info;
  1652. printf("%12s,%10s,%22s,%12s,%12x\n",
  1653. "Pool_Free",
  1654. "",
  1655. "",
  1656. "",
  1657. TmpPMmInfoFreePool->Entry);
  1658. break;
  1659. }
  1660. case MMINFO_LOG_TYPE_ASYNCMARK:
  1661. case MMINFO_LOG_TYPE_MARK:
  1662. {
  1663. PSYSTEM_MMINFO_MARK_INFORMATION TmpPMmInfo;
  1664. TmpPMmInfo = (PSYSTEM_MMINFO_MARK_INFORMATION) Info;
  1665. printf("%12s,%10I64d, %-s\n",
  1666. (LogType == MMINFO_LOG_TYPE_ASYNCMARK) ?
  1667. "AsyncMark" : "Mark",
  1668. ((PerfCounter - PerfCounterStart) *
  1669. 1000000) / PerfFrequency,
  1670. TmpPMmInfo->Name);
  1671. break;
  1672. }
  1673. case MMINFO_LOG_TYPE_CMCELLREFERRED:
  1674. {
  1675. PSYSTEM_MMINFO_CMCELL_INFORMATION TmpPMmInfoCmCell;
  1676. TmpPMmInfoCmCell=(PSYSTEM_MMINFO_CMCELL_INFORMATION) Info;
  1677. printf("%12s,%10s,","Cell_Used","");
  1678. switch(TmpPMmInfoCmCell->Signature) {
  1679. case CM_KEY_NODE_SIGNATURE:
  1680. printf("%22s,%12s","Key_Node","");
  1681. break;
  1682. case CM_LINK_NODE_SIGNATURE:
  1683. printf("%22s,%12s","Link_Node","");
  1684. break;
  1685. case CM_KEY_VALUE_SIGNATURE:
  1686. printf("%22s,%12s","Key_Value","");
  1687. break;
  1688. case CM_KEY_FAST_LEAF:
  1689. printf("%22s,%12s","Index_Leaf","");
  1690. break;
  1691. case CM_KEY_SECURITY_SIGNATURE:
  1692. printf("%22s,%12s","Key_Security","");
  1693. break;
  1694. default:
  1695. printf("%22s,%12s","Unknown","");
  1696. break;
  1697. }
  1698. printf(",%12x,%8d\n", TmpPMmInfoCmCell->Va, TmpPMmInfoCmCell->Size*-1);
  1699. break;
  1700. }
  1701. case MMINFO_LOG_TYPE_IMAGELOAD:
  1702. {
  1703. PMMINFO_IMAGELOAD_INFORMATION TmpPMmInfo;
  1704. char WsNameBuf[30];
  1705. char * WsName = &WsNameBuf[0];
  1706. TmpPMmInfo = (PMMINFO_IMAGELOAD_INFORMATION) Info;
  1707. Info = TmpPMmInfo + 1;
  1708. if (TmpPMmInfo->ProcessId == 0) {
  1709. WsName = "System ( 0)";
  1710. } else {
  1711. ULONG i;
  1712. i = TmpPMmInfo->ProcessId;
  1713. if (ProcessHash[i].ProcessID == TmpPMmInfo->ProcessId) {
  1714. sprintf(WsName, "%16s (%3d)",
  1715. ProcessHash[i].ImageFileName,
  1716. ProcessHash[i].ProcessID);
  1717. }else{
  1718. sprintf(WsName, "Process %13u", TmpPMmInfo->ProcessId);
  1719. }
  1720. }
  1721. printf(ImageLoadDataFormat,
  1722. TmpPMmInfo->ImageBase,
  1723. (ULONG)TmpPMmInfo->ImageBase + TmpPMmInfo->ImageSize,
  1724. TmpPMmInfo->ImageSectionNumber,
  1725. WsName,
  1726. TmpPMmInfo->ImageName
  1727. );
  1728. break;
  1729. }
  1730. case MMINFO_LOG_TYPE_SAMPLED_PROFILE:
  1731. {
  1732. PMMINFO_SAMPLED_PROFILE_INFORMATION TmpPMmInfo;
  1733. TmpPMmInfo = (PMMINFO_SAMPLED_PROFILE_INFORMATION) Info;
  1734. Info = TmpPMmInfo + 1;
  1735. printf(SampledProfileDataFormat,
  1736. TmpPMmInfo->InstructionPointer,
  1737. TmpPMmInfo->Count
  1738. );
  1739. break;
  1740. }
  1741. default:
  1742. // fprintf(stderr, "Tag Value %8d\n", Tag.u.Value);
  1743. // fprintf(stderr, "TimeStamp %8x %8x\n", TS.upper, TS.lower);
  1744. break;
  1745. }
  1746. }
  1747. #else //NTMMPERF
  1748. printf("Sorry but this is an internal tool!!!\n");
  1749. #endif //NTMMPERF
  1750. return 0;
  1751. }