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.

730 lines
22 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. wsle.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Lou Perazzoli (LouP) 14-Mar-1994
  9. Environment:
  10. User Mode.
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #define PACKET_MAX_SIZE 4000
  15. #define NUMBER_OF_WSLE_TO_READ 1000 // ((PACKET_MAX_SIZE/sizeof(MMWSLE))-1)
  16. USHORT
  17. GetPfnRefCount(
  18. IN ULONG64 PageFrameNumber
  19. );
  20. DECLARE_API( wsle )
  21. /*++
  22. Routine Description:
  23. Dumps all wsles for process.
  24. Arguments:
  25. args - Address Flags
  26. Return Value:
  27. None
  28. --*/
  29. {
  30. ULONG Result;
  31. ULONG Flags;
  32. ULONG index;
  33. ULONG64 WorkingSet;
  34. ULONG64 WsleBase;
  35. ULONG64 Va;
  36. ULONG64 Wsle;
  37. ULONG next;
  38. ULONG j;
  39. ULONG k;
  40. PCHAR WsleArray;
  41. ULONG64 WsleStart;
  42. ULONG ReadCount;
  43. ULONG result;
  44. ULONG found;
  45. ULONG64 PteAddress;
  46. ULONG SizeofWsle;
  47. ULONG64 Quota, HashTable;
  48. ULONG FirstFree, FirstDynamic, LastEntry, NextSlot, LastInitializedWsle;
  49. ULONG NonDirectCount, HashTableSize;
  50. PCHAR pc;
  51. Flags = 0;
  52. WorkingSet = 0;
  53. Flags = (ULONG) GetExpression(args);
  54. pc = strchr(args, ' ');
  55. WorkingSet = pc ? GetExpression(pc) : 0;
  56. if (WorkingSet == 0) {
  57. if (TargetMachine == IMAGE_FILE_MACHINE_I386) {
  58. WorkingSet = GetPointerValue("nt!MmWorkingSetList");
  59. }
  60. else if (TargetMachine == IMAGE_FILE_MACHINE_IA64) {
  61. WorkingSet = (ULONG64)0x6FC00a02000;
  62. }
  63. else if (TargetMachine == IMAGE_FILE_MACHINE_AMD64) {
  64. WorkingSet = (ULONG64)0xFFFFF70000082000;
  65. }
  66. else {
  67. dprintf ("No default WSL for target machine %x\n", TargetMachine);
  68. return E_INVALIDARG;
  69. }
  70. }
  71. if (GetFieldValue(WorkingSet, "nt!_MMWSL", "Quota", Quota)) {
  72. dprintf("%08p: Unable to get contents of WSL\n",WorkingSet );
  73. return E_INVALIDARG;
  74. }
  75. if (GetTypeSize("nt!_MMWSL") == 0) {
  76. dprintf("Type MMWSL not found.\n");
  77. return E_INVALIDARG;
  78. }
  79. GetFieldValue(WorkingSet,"nt!_MMWSL","FirstDynamic", FirstDynamic);
  80. GetFieldValue(WorkingSet,"nt!_MMWSL","FirstFree", FirstFree);
  81. GetFieldValue(WorkingSet,"nt!_MMWSL","Wsle", Wsle);
  82. GetFieldValue(WorkingSet,"nt!_MMWSL","LastEntry", LastEntry);
  83. GetFieldValue(WorkingSet,"nt!_MMWSL","NextSlot", NextSlot);
  84. GetFieldValue(WorkingSet,"nt!_MMWSL","LastInitializedWsle", LastInitializedWsle);
  85. GetFieldValue(WorkingSet,"nt!_MMWSL","NonDirectCount", NonDirectCount);
  86. GetFieldValue(WorkingSet,"nt!_MMWSL","HashTableSize", HashTableSize);
  87. GetFieldValue(WorkingSet,"nt!_MMWSL","HashTable", HashTable);
  88. dprintf ("\nWorking Set @ %8p\n", WorkingSet);
  89. dprintf (" Quota: %8I64lx FirstFree: %8lx FirstDynamic: %8lx\n",
  90. Quota,
  91. FirstFree,
  92. FirstDynamic);
  93. dprintf (" LastEntry %8lx NextSlot: %8lx LastInitialized %8lx\n",
  94. LastEntry,
  95. NextSlot,
  96. LastInitializedWsle);
  97. dprintf (" NonDirect %8lx HashTable: %8p HashTableSize: %8lx\n",
  98. NonDirectCount,
  99. HashTable,
  100. HashTableSize);
  101. if (Flags == 0) {
  102. return E_INVALIDARG;
  103. }
  104. SizeofWsle = GetTypeSize("nt!_MMWSLE");
  105. if (SizeofWsle == 0) {
  106. dprintf("Type _MMWSLE not found.\n");
  107. return E_INVALIDARG;
  108. }
  109. if (Flags == 7) {
  110. BOOL FirstTime = TRUE;
  111. //
  112. // Check free entries in the working set list.
  113. //
  114. WsleArray = VirtualAlloc (NULL,
  115. (LastInitializedWsle + 1) * SizeofWsle,
  116. MEM_RESERVE | MEM_COMMIT,
  117. PAGE_READWRITE);
  118. //
  119. // Copy the working set list over to the debugger.
  120. //
  121. if (WsleArray == NULL) {
  122. dprintf("Unable to get allocate memory of %ld bytes\n",
  123. (LastInitializedWsle + 1) * SizeofWsle);
  124. return E_INVALIDARG;
  125. }
  126. dprintf("\nVirtual Address Age Locked ReferenceCount\n");
  127. WsleStart = Wsle;
  128. for (j = 0;
  129. j <= LastInitializedWsle;
  130. j += NUMBER_OF_WSLE_TO_READ) {
  131. if ( CheckControlC() ) {
  132. VirtualFree (WsleArray,0,MEM_RELEASE);
  133. return E_INVALIDARG;
  134. }
  135. ReadCount = (LastInitializedWsle + 1 - j ) > NUMBER_OF_WSLE_TO_READ ?
  136. NUMBER_OF_WSLE_TO_READ :
  137. LastInitializedWsle + 1 - j;
  138. ReadCount *= SizeofWsle;
  139. //
  140. // Enough to read and forget - KD will cache the data
  141. //
  142. if ( !ReadMemory( WsleStart + j*SizeofWsle,
  143. WsleArray + j*SizeofWsle,
  144. ReadCount,
  145. &result) ) {
  146. dprintf("Unable to get Wsle table block - "
  147. "address %lx - count %lu - page %lu\n",
  148. WsleStart + j*SizeofWsle, ReadCount, j);
  149. VirtualFree (WsleArray,0,MEM_RELEASE);
  150. return E_INVALIDARG;
  151. }
  152. for (k=0; k<ReadCount/SizeofWsle; k++) {
  153. GetFieldValue(WsleStart + (j+k)*SizeofWsle, "nt!_MMWSLE", "u1.e1.Valid", WsleArray[j+k]);
  154. }
  155. dprintf(".");
  156. }
  157. dprintf("\r");
  158. //
  159. // Walk the array looking for bad free entries.
  160. //
  161. for (j = 0;
  162. j <= LastInitializedWsle;
  163. j += 1) {
  164. ULONG Valid, Age, LockedInWs, LockedInMemory;
  165. ULONG64 WsleToread = WsleStart + j*SizeofWsle, Long;
  166. if ( CheckControlC() ) {
  167. dprintf("j= %x\n",j);
  168. VirtualFree (WsleArray,0,MEM_RELEASE);
  169. return E_INVALIDARG;
  170. }
  171. GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.e1.Valid", Valid);
  172. if (Valid == 0) {
  173. //
  174. // Locate j in the array.
  175. //
  176. found = FALSE;
  177. for (k = 0;
  178. k <= LastInitializedWsle;
  179. k += 1) {
  180. ULONG k_Valid;
  181. ULONG64 k_Long;
  182. k_Valid = WsleArray[k];
  183. if (k_Valid == 0) {
  184. GetFieldValue(WsleStart + k*SizeofWsle, "nt!_MMWSLE", "u1.Long", k_Long);
  185. if ((ULONG) (k_Long >> MM_FREE_WSLE_SHIFT) == j) {
  186. found = TRUE;
  187. #if 0
  188. dprintf(" free entry located @ index %ld. %lx %ld. %lx\n",
  189. j, WsleArray[j].u1.Long,k,WsleArray[k]);
  190. #endif
  191. break;
  192. }
  193. }
  194. }
  195. if (!found) {
  196. if (FirstFree == j) {
  197. // dprintf("first index found\n");
  198. } else {
  199. GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.VirtualAddress", Long);
  200. dprintf(" free entry not located @ index %ld. %p\n",
  201. j, Long);
  202. }
  203. }
  204. }
  205. else {
  206. ULONG PteValid;
  207. GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.VirtualAddress", Long);
  208. Va = Long;
  209. PteAddress = DbgGetPteAddress (Va);
  210. if (!GetFieldValue(PteAddress,
  211. "nt!_MMPTE",
  212. "u.Hard.Valid",
  213. PteValid) ) {
  214. if (PteValid == 0) {
  215. dprintf(" cannot find valid PTE for WS index %d, VA %p\n",
  216. j, Long);
  217. }
  218. else {
  219. ULONG64 PageFrameNumber;
  220. USHORT ReferenceCount;
  221. GetFieldValue( PteAddress,
  222. "nt!_MMPTE",
  223. "u.Hard.PageFrameNumber",
  224. PageFrameNumber);
  225. ReferenceCount = GetPfnRefCount (PageFrameNumber);
  226. GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.e1.Age", Age);
  227. GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.e1.LockedInWs", LockedInWs);
  228. GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.LockedInMemory", LockedInMemory);
  229. dprintf("%16p %2u %8ld %8ld\n",
  230. Long, Age,
  231. (LockedInWs |
  232. LockedInMemory) ? 1 : 0,
  233. ReferenceCount);
  234. }
  235. }
  236. else {
  237. dprintf(" cannot find valid PDE for WS index %d, VA %p\n",
  238. j, Long);
  239. }
  240. }
  241. }
  242. VirtualFree (WsleArray,0,MEM_RELEASE);
  243. } else {
  244. ULONG64 nextLong;
  245. next = FirstFree;
  246. WsleBase = Wsle;
  247. while (next != (ULONG) WSLE_NULL_INDEX) {
  248. if (CheckControlC()) {
  249. return E_INVALIDARG;
  250. }
  251. if ( GetFieldValue( WsleBase + SizeofWsle*next,
  252. "nt!_MMWSLE",
  253. "u1.VirtualAddress",
  254. nextLong) ) {
  255. dprintf("%08p: Unable to get contents of wsle\n",
  256. WsleBase+SizeofWsle*next );
  257. return E_INVALIDARG;
  258. }
  259. dprintf("index %8lx value %8p\n", next, nextLong);
  260. next = (ULONG) (nextLong >> MM_FREE_WSLE_SHIFT);
  261. }
  262. }
  263. return S_OK;
  264. }
  265. typedef struct _MMSECTION_FLAGS {
  266. unsigned BeingDeleted : 1;
  267. unsigned BeingCreated : 1;
  268. unsigned BeingPurged : 1;
  269. unsigned NoModifiedWriting : 1;
  270. unsigned FailAllIo : 1;
  271. unsigned Image : 1;
  272. unsigned Based : 1;
  273. unsigned File : 1;
  274. unsigned Networked : 1;
  275. unsigned NoCache : 1;
  276. unsigned PhysicalMemory : 1;
  277. unsigned CopyOnWrite : 1;
  278. unsigned Reserve : 1; // not a spare bit!
  279. unsigned Commit : 1;
  280. unsigned FloppyMedia : 1;
  281. unsigned WasPurged : 1;
  282. unsigned UserReference : 1;
  283. unsigned GlobalMemory : 1;
  284. unsigned DeleteOnClose : 1;
  285. unsigned FilePointerNull : 1;
  286. unsigned DebugSymbolsLoaded : 1;
  287. unsigned SetMappedFileIoComplete : 1;
  288. unsigned CollidedFlush : 1;
  289. unsigned NoChange : 1;
  290. unsigned HadUserReference : 1;
  291. unsigned ImageMappedInSystemSpace : 1;
  292. unsigned UserWritable : 1;
  293. unsigned Accessed : 1;
  294. unsigned GlobalOnlyPerSession : 1;
  295. unsigned Rom : 1;
  296. unsigned filler : 2;
  297. } MMSECTION_FLAGS;
  298. typedef struct _MMSUBSECTION_FLAGS {
  299. unsigned ReadOnly : 1;
  300. unsigned ReadWrite : 1;
  301. unsigned CopyOnWrite : 1;
  302. unsigned GlobalMemory: 1;
  303. unsigned Protection : 5;
  304. unsigned LargePages : 1;
  305. unsigned StartingSector4132 : 10; // 2 ** (42+12) == 4MB*4GB == 16K TB
  306. unsigned SectorEndOffset : 12;
  307. } MMSUBSECTION_FLAGS;
  308. DECLARE_API( ca )
  309. /*++
  310. Routine Description:
  311. Dumps a control area.
  312. Arguments:
  313. args - Address Flags
  314. Return Value:
  315. None
  316. --*/
  317. {
  318. LARGE_INTEGER StartingSector;
  319. ULONG64 ControlAreaVa;
  320. ULONG64 SubsectionVa;
  321. ULONG ControlAreaSize;
  322. ULONG LargeControlAreaSize;
  323. ULONG SubsectionSize;
  324. ULONG SubsectionCount;
  325. ULONG64 Segment;
  326. ULONG64 FileObject;
  327. ULONG NumberOfSubsections;
  328. MMSECTION_FLAGS ControlAreaFlags;
  329. MMSUBSECTION_FLAGS SubsectionFlags;
  330. LOGICAL MappedDataFile;
  331. LOGICAL PrintedSomething;
  332. ControlAreaVa = GetExpression(args);
  333. dprintf("\n");
  334. dprintf("ControlArea @%08p\n", ControlAreaVa);
  335. ControlAreaSize = GetTypeSize("nt!_CONTROL_AREA");
  336. if (ControlAreaSize == 0) {
  337. dprintf("Type CONTROL_AREA not found.\n");
  338. return E_INVALIDARG;
  339. }
  340. InitTypeRead(ControlAreaVa, nt!_CONTROL_AREA);
  341. Segment = ReadField(Segment);
  342. NumberOfSubsections = (ULONG)ReadField(NumberOfSubsections);
  343. FileObject = ReadField(FilePointer);
  344. dprintf (" Segment: %08p Flink %8p Blink %8p\n",
  345. Segment,
  346. ReadField(DereferenceList.Flink),
  347. ReadField(DereferenceList.Blink));
  348. dprintf (" Section Ref %8lx Pfn Ref %8lx Mapped Views %8lx\n",
  349. (ULONG) ReadField(NumberOfSectionReferences),
  350. (ULONG) ReadField(NumberOfPfnReferences),
  351. (ULONG) ReadField(NumberOfMappedViews));
  352. dprintf (" User Ref %8lx Subsections %8lx Flush Count %8lx\n",
  353. (ULONG) ReadField(NumberOfUserReferences),
  354. NumberOfSubsections,
  355. (USHORT) ReadField(FlushInProgressCount));
  356. dprintf (" File Object %08p ModWriteCount%7lx System Views %8lx\n",
  357. FileObject,
  358. (USHORT) ReadField(ModifiedWriteCount),
  359. (USHORT) ReadField(NumberOfSystemCacheViews));
  360. dprintf (" WaitForDel %8p\n",
  361. ReadField(WaitingForDeletion));
  362. GetFieldValue(ControlAreaVa, "nt!_CONTROL_AREA", "u.LongFlags", ControlAreaFlags);
  363. dprintf (" Flags (%lx) ", ControlAreaFlags);
  364. if (ControlAreaFlags.BeingDeleted) { dprintf("BeingDeleted "); }
  365. if (ControlAreaFlags.BeingCreated) { dprintf("BeingCreated "); }
  366. if (ControlAreaFlags.BeingPurged) { dprintf("BeingPurged "); }
  367. if (ControlAreaFlags.NoModifiedWriting) { dprintf("NoModifiedWriting "); }
  368. if (ControlAreaFlags.FailAllIo) { dprintf("FailAllIo "); }
  369. if (ControlAreaFlags.Image) { dprintf("Image "); }
  370. if (ControlAreaFlags.Based) { dprintf("Based "); }
  371. if (ControlAreaFlags.File) { dprintf("File "); }
  372. if (ControlAreaFlags.Networked) { dprintf("Networked "); }
  373. if (ControlAreaFlags.NoCache) { dprintf("NoCache "); }
  374. if (ControlAreaFlags.PhysicalMemory) { dprintf("PhysicalMemory "); }
  375. if (ControlAreaFlags.CopyOnWrite) { dprintf("CopyOnWrite "); }
  376. if (ControlAreaFlags.Reserve) { dprintf("Reserve "); }
  377. if (ControlAreaFlags.Commit) { dprintf("Commit "); }
  378. if (ControlAreaFlags.FloppyMedia) { dprintf("FloppyMedia "); }
  379. if (ControlAreaFlags.WasPurged) { dprintf("WasPurged "); }
  380. if (ControlAreaFlags.UserReference) { dprintf("UserReference "); }
  381. if (ControlAreaFlags.GlobalMemory) { dprintf("GlobalMemory "); }
  382. if (ControlAreaFlags.DeleteOnClose) { dprintf("DeleteOnClose "); }
  383. if (ControlAreaFlags.FilePointerNull) { dprintf("FilePointerNull "); }
  384. if (ControlAreaFlags.DebugSymbolsLoaded) { dprintf("DebugSymbolsLoaded "); }
  385. if (ControlAreaFlags.SetMappedFileIoComplete) { dprintf("SetMappedFileIoComplete "); }
  386. if (ControlAreaFlags.CollidedFlush) { dprintf("CollidedFlush "); }
  387. if (ControlAreaFlags.NoChange) { dprintf("NoChange "); }
  388. if (ControlAreaFlags.HadUserReference) { dprintf("HadUserReference "); }
  389. if (ControlAreaFlags.ImageMappedInSystemSpace) { dprintf("ImageMappedInSystemSpace "); }
  390. if (ControlAreaFlags.UserWritable) { dprintf("UserWritable "); }
  391. if (ControlAreaFlags.Accessed) { dprintf("Accessed "); }
  392. if (ControlAreaFlags.GlobalOnlyPerSession) { dprintf("GlobalOnlyPerSession "); }
  393. if (ControlAreaFlags.Rom) { dprintf("Rom "); }
  394. dprintf ("\n\n");
  395. MappedDataFile = FALSE;
  396. //
  397. // Dump the file object's name if there is one and it's resident.
  398. //
  399. if (FileObject != 0) {
  400. ULONG64 FileNameLength;
  401. ULONG64 FileNameBuffer;
  402. PUCHAR tempbuffer;
  403. ULONG result;
  404. UNICODE_STRING unicodeString;
  405. if (GetTypeSize("nt!_FILE_OBJECT") == 0) {
  406. dprintf("Type FILE_OBJECT not found.\n");
  407. return E_INVALIDARG;
  408. }
  409. InitTypeRead(FileObject, nt!_FILE_OBJECT);
  410. FileNameBuffer = ReadField(FileName.Buffer);
  411. unicodeString.Length = (USHORT) ReadField(FileName.Length);
  412. tempbuffer = LocalAlloc(LPTR, unicodeString.Length);
  413. unicodeString.Buffer = (PWSTR)tempbuffer;
  414. unicodeString.MaximumLength = unicodeString.Length;
  415. if (FileNameBuffer == 0) {
  416. dprintf("\tNo Name for File\n");
  417. }
  418. else if (!ReadMemory ( FileNameBuffer,
  419. tempbuffer,
  420. unicodeString.Length,
  421. &result)) {
  422. dprintf("\tFile Name paged out\n");
  423. } else {
  424. dprintf("\tFile: %wZ\n", &unicodeString);
  425. }
  426. LocalFree(tempbuffer);
  427. if (ControlAreaFlags.Image == 0) {
  428. MappedDataFile = TRUE;
  429. }
  430. }
  431. //
  432. // Dump the segment information.
  433. //
  434. dprintf("\nSegment @ %08p:\n", Segment);
  435. if (MappedDataFile == FALSE) {
  436. if (GetTypeSize("nt!_SEGMENT") == 0) {
  437. dprintf("Type SEGMENT not found.\n");
  438. return E_INVALIDARG;
  439. }
  440. InitTypeRead(Segment, nt!_SEGMENT);
  441. }
  442. else {
  443. if (GetTypeSize("nt!_MAPPED_FILE_SEGMENT") == 0) {
  444. dprintf("Type MAPPED_FILE_SEGMENT not found.\n");
  445. return E_INVALIDARG;
  446. }
  447. InitTypeRead(Segment, nt!_MAPPED_FILE_SEGMENT);
  448. }
  449. dprintf(" ControlArea %08p Total Ptes %8lx NonExtendPtes %8lx\n",
  450. ReadField(ControlArea),
  451. (ULONG) ReadField(TotalNumberOfPtes),
  452. (ULONG) ReadField(NonExtendedPtes));
  453. if (ControlAreaVa != ReadField(ControlArea)) {
  454. dprintf("SEGMENT is corrupt - bad control area backlink.\n");
  455. return E_INVALIDARG;
  456. }
  457. dprintf(" WriteUserRef %8lx SizeOfSegment %I64x PTE Template %I64X\n",
  458. (ULONG) ReadField(WritableUserReferences),
  459. ReadField(SizeOfSegment),
  460. ReadField(SegmentPteTemplate.u.Long));
  461. dprintf(" Committed %8p Extend Info %8p Image Base %8p\n",
  462. ReadField(NumberOfCommittedPages),
  463. ReadField(ExtendInfo),
  464. ReadField(SystemImageBase));
  465. dprintf(" Based Addr %8p\n",
  466. ReadField(BasedAddress));
  467. if (MappedDataFile == FALSE) {
  468. if (ControlAreaFlags.Image == 1) {
  469. dprintf(" Image commit %8p Image Info. %8p",
  470. ReadField(ImageCommitment),
  471. ReadField(ImageInformation));
  472. }
  473. else {
  474. dprintf(" CreatingProcess %8p FirstMappedVa %8p",
  475. ReadField(u1.CreatingProcess),
  476. ReadField(u2.FirstMappedVa));
  477. }
  478. dprintf(" ProtoPtes %08p\n",
  479. ReadField(PrototypePte));
  480. }
  481. //
  482. // Dump the subsection(s).
  483. //
  484. SubsectionSize = GetTypeSize("nt!_SUBSECTION");
  485. if (SubsectionSize == 0) {
  486. dprintf("Type SUBSECTION not found.\n");
  487. return E_INVALIDARG;
  488. }
  489. LargeControlAreaSize = GetTypeSize("nt!_LARGE_CONTROL_AREA");
  490. if (LargeControlAreaSize == 0) {
  491. dprintf("Type LARGE_CONTROL_AREA not found.\n");
  492. return E_INVALIDARG;
  493. }
  494. if (ControlAreaFlags.GlobalOnlyPerSession) {
  495. SubsectionVa = ControlAreaVa + LargeControlAreaSize;
  496. }
  497. else {
  498. SubsectionVa = ControlAreaVa + ControlAreaSize;
  499. }
  500. SubsectionCount = 0;
  501. do {
  502. if (CheckControlC()) {
  503. return E_INVALIDARG;
  504. }
  505. InitTypeRead(SubsectionVa, nt!_SUBSECTION);
  506. SubsectionCount += 1;
  507. dprintf("\nSubsection %ld. @ %8p\n", SubsectionCount, SubsectionVa);
  508. GetFieldValue(SubsectionVa, "nt!_SUBSECTION", "u.LongFlags", SubsectionFlags);
  509. StartingSector.LowPart = (ULONG)ReadField(StartingSector);
  510. StartingSector.HighPart = (LONG)SubsectionFlags.StartingSector4132;
  511. dprintf(" ControlArea: %08p Starting Sector %I64X Number Of Sectors %lx\n",
  512. ReadField(ControlArea),
  513. StartingSector,
  514. (ULONG) ReadField(NumberOfFullSectors));
  515. dprintf(" Base Pte %08p Ptes In subsect %8lx Unused Ptes %8lx\n",
  516. ReadField(SubsectionBase),
  517. (ULONG) ReadField(PtesInSubsection),
  518. (ULONG) ReadField(UnusedPtes));
  519. dprintf(" Flags %8lx Sector Offset %8lx Protection %8lx\n",
  520. SubsectionFlags,
  521. SubsectionFlags.SectorEndOffset,
  522. SubsectionFlags.Protection);
  523. PrintedSomething = FALSE;
  524. if (SubsectionFlags.ReadOnly) {
  525. if (PrintedSomething == FALSE) {
  526. dprintf(" ");
  527. }
  528. PrintedSomething = TRUE;
  529. dprintf("ReadOnly ");
  530. }
  531. if (SubsectionFlags.ReadWrite) {
  532. if (PrintedSomething == FALSE) {
  533. dprintf(" ");
  534. }
  535. PrintedSomething = TRUE;
  536. dprintf("ReadWrite");
  537. }
  538. if (SubsectionFlags.CopyOnWrite) {
  539. if (PrintedSomething == FALSE) {
  540. dprintf(" ");
  541. }
  542. PrintedSomething = TRUE;
  543. dprintf("CopyOnWrite ");
  544. }
  545. if (SubsectionFlags.GlobalMemory) {
  546. if (PrintedSomething == FALSE) {
  547. dprintf(" ");
  548. }
  549. PrintedSomething = TRUE;
  550. dprintf("GlobalMemory ");
  551. }
  552. if (SubsectionFlags.LargePages) {
  553. if (PrintedSomething == FALSE) {
  554. dprintf(" ");
  555. }
  556. PrintedSomething = TRUE;
  557. dprintf("Large Pages");
  558. }
  559. if (PrintedSomething == TRUE) {
  560. dprintf("\n");
  561. }
  562. if (MappedDataFile == TRUE) {
  563. InitTypeRead(SubsectionVa, nt!_MSUBSECTION);
  564. dprintf(" Flink %08p Blink %08p MappedViews %8x\n",
  565. ReadField(DereferenceList.Flink),
  566. ReadField(DereferenceList.Blink),
  567. (ULONG) ReadField(NumberOfMappedViews));
  568. dprintf(" SubsectionDataFlags %8x\n",
  569. (ULONG) ReadField(u2.LongFlags2));
  570. }
  571. SubsectionVa = ReadField(NextSubsection);
  572. } while (SubsectionVa != 0);
  573. return S_OK;
  574. }