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.

213 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. filecach.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Wesley Witt (wesw) 15-Aug-1993
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. DECLARE_API( filecache )
  16. /*++
  17. Routine Description:
  18. Displays physical memory usage by drivers.
  19. Arguments:
  20. None.
  21. Return Value:
  22. None.
  23. --*/
  24. {
  25. ULONG result;
  26. ULONG NumberOfPtes;
  27. ULONG PteCount;
  28. ULONG ReadCount;
  29. ULONG64 SystemCacheWsLoc;
  30. ULONG64 SystemCacheStart;
  31. ULONG64 SystemCacheEnd;
  32. ULONG64 SystemCacheStartPte;
  33. ULONG64 SystemCacheEndPte;
  34. ULONG Transition = 0;
  35. ULONG Valid;
  36. ULONG ValidShift, ValidSize;
  37. ULONG64 PfnIndex;
  38. ULONG PteSize;
  39. ULONG PfnSize;
  40. ULONG HighPage;
  41. ULONG LowPage;
  42. ULONG64 Pte;
  43. ULONG64 PfnDb;
  44. ULONG64 Pfn;
  45. ULONG64 PfnStart;
  46. ULONG64 PfnArray;
  47. ULONG64 PfnArrayOffset;
  48. ULONG NumberOfPteToRead;
  49. ULONG WorkingSetSize, PeakWorkingSetSize;
  50. ULONG64 BufferedAddress=0;
  51. CHAR Buffer[2048];
  52. INIT_API();
  53. dprintf("***** Dump file cache******\n");
  54. SystemCacheStart = GetNtDebuggerDataPtrValue( MmSystemCacheStart );
  55. if (!SystemCacheStart) {
  56. dprintf("unable to get SystemCacheStart\n");
  57. EXIT_API();
  58. return E_INVALIDARG;
  59. }
  60. SystemCacheEnd = GetNtDebuggerDataPtrValue( MmSystemCacheEnd );
  61. if (!SystemCacheEnd) {
  62. dprintf("unable to get SystemCacheEnd\n");
  63. EXIT_API();
  64. return E_INVALIDARG;
  65. }
  66. SystemCacheWsLoc = GetNtDebuggerData( MmSystemCacheWs );
  67. if (!SystemCacheWsLoc) {
  68. dprintf("unable to get MmSystemCacheWs\n");
  69. EXIT_API();
  70. return E_INVALIDARG;
  71. }
  72. PfnDb = GetNtDebuggerData( MmPfnDatabase );
  73. if (!PfnDb) {
  74. dprintf("unable to get MmPfnDatabase\n");
  75. EXIT_API();
  76. return E_INVALIDARG;
  77. }
  78. PteSize = GetTypeSize("nt!_MMPTE");
  79. NumberOfPteToRead = PageSize / PteSize - 16;
  80. if (GetFieldValue(SystemCacheWsLoc,
  81. "nt!_MMSUPPORT",
  82. "WorkingSetSize",
  83. WorkingSetSize)) {
  84. dprintf("unable to get system cache list\n");
  85. EXIT_API();
  86. return E_INVALIDARG;
  87. }
  88. GetFieldValue(SystemCacheWsLoc,"nt!_MMSUPPORT","PeakWorkingSetSize",PeakWorkingSetSize);
  89. dprintf("File Cache Information\n");
  90. dprintf(" Current size %ld kb\n",WorkingSetSize*
  91. (PageSize / 1024));
  92. dprintf(" Peak size %ld kb\n",PeakWorkingSetSize*
  93. (PageSize / 1024));
  94. if (!ReadPointer(PfnDb,&PfnStart)) {
  95. dprintf("unable to get PFN database address\n");
  96. EXIT_API();
  97. return E_INVALIDARG;
  98. }
  99. SystemCacheStartPte = DbgGetPteAddress (SystemCacheStart);
  100. SystemCacheEndPte = DbgGetPteAddress (SystemCacheEnd);
  101. NumberOfPtes = (ULONG) ( 1 + (SystemCacheEndPte - SystemCacheStartPte) / PteSize);
  102. //
  103. // Read in all the PTEs mapping the system cache.
  104. //
  105. dprintf(" Loading file cache database (%u PTEs)\r", NumberOfPtes);
  106. GetBitFieldOffset("nt!_MMPTE", "u.Hard.Valid", &ValidShift, &ValidSize);
  107. // dprintf("Valid off %d, num %d ", ValidShift, ValidSize);
  108. Valid = 0;
  109. ZeroMemory(Buffer, sizeof(Buffer));
  110. for (PteCount = 0;
  111. PteCount < NumberOfPtes;
  112. PteCount += 1) {
  113. if (CheckControlC()) {
  114. EXIT_API();
  115. return E_INVALIDARG;
  116. }
  117. //
  118. // Read a chunk at a time
  119. //
  120. if ((SystemCacheStartPte + (PteCount+1)* PteSize) > BufferedAddress + sizeof(Buffer) ) {
  121. BufferedAddress = (SystemCacheStartPte + PteCount * PteSize);
  122. if (!ReadMemory(BufferedAddress,
  123. Buffer,
  124. sizeof(Buffer),
  125. &result)) {
  126. dprintf("Unable to read memory at %p\n", BufferedAddress);
  127. PteCount += sizeof(Buffer) / PteSize;
  128. continue;
  129. }
  130. }
  131. Pte = (SystemCacheStartPte + PteCount * PteSize) - BufferedAddress;
  132. //
  133. // Too many ptes, so do the Valid checking directly instead of calling DbgGetValid
  134. //
  135. if ((*((PULONG) &Buffer[(ULONG) Pte]) >> ValidShift) & 1) {
  136. Valid += 1;
  137. }
  138. if (!(PteCount % (NumberOfPtes/100))) {
  139. dprintf(" Loading file cache database (%02d%% of %u PTEs)\r", PteCount*100/NumberOfPtes, NumberOfPtes);
  140. }
  141. }
  142. dprintf("\n");
  143. dprintf(" File cache PTEs loaded, loading PFNs...\n");
  144. HighPage = Valid;
  145. LowPage = 0;
  146. //
  147. // Allocate a local PFN array (only) large enough to hold data about
  148. // each valid PTE we've found.
  149. //
  150. dprintf(" File cache has %ld valid pages\n",Valid);
  151. PfnSize = GetTypeSize("nt!_MMPFN");
  152. Pte = SystemCacheStartPte;
  153. dprintf(" File cache PFN data extracted\n");
  154. MemoryUsage (PfnStart,LowPage,HighPage, 1);
  155. EXIT_API();
  156. return S_OK;
  157. }