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.

226 lines
5.6 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. if (!PteSize) {
  80. dprintf("unable to get nt!_MMPTE\n");
  81. EXIT_API();
  82. return E_INVALIDARG;
  83. }
  84. NumberOfPteToRead = PageSize / PteSize - 16;
  85. if (GetFieldValue(SystemCacheWsLoc,
  86. "nt!_MMSUPPORT",
  87. "WorkingSetSize",
  88. WorkingSetSize)) {
  89. dprintf("unable to get system cache list\n");
  90. EXIT_API();
  91. return E_INVALIDARG;
  92. }
  93. GetFieldValue(SystemCacheWsLoc,"nt!_MMSUPPORT","PeakWorkingSetSize",PeakWorkingSetSize);
  94. dprintf("File Cache Information\n");
  95. dprintf(" Current size %ld kb\n",WorkingSetSize*
  96. (PageSize / 1024));
  97. dprintf(" Peak size %ld kb\n",PeakWorkingSetSize*
  98. (PageSize / 1024));
  99. if (!ReadPointer(PfnDb,&PfnStart)) {
  100. dprintf("unable to get PFN database address\n");
  101. EXIT_API();
  102. return E_INVALIDARG;
  103. }
  104. SystemCacheStartPte = DbgGetPteAddress (SystemCacheStart);
  105. SystemCacheEndPte = DbgGetPteAddress (SystemCacheEnd);
  106. NumberOfPtes = (ULONG) ( 1 + (SystemCacheEndPte - SystemCacheStartPte) / PteSize);
  107. //
  108. // Read in all the PTEs mapping the system cache.
  109. //
  110. dprintf(" Loading file cache database (%u PTEs)\r", NumberOfPtes);
  111. GetBitFieldOffset("nt!_MMPTE", "u.Hard.Valid", &ValidShift, &ValidSize);
  112. // dprintf("Valid off %d, num %d ", ValidShift, ValidSize);
  113. Valid = 0;
  114. ZeroMemory(Buffer, sizeof(Buffer));
  115. for (PteCount = 0;
  116. PteCount < NumberOfPtes;
  117. PteCount += 1) {
  118. if (CheckControlC()) {
  119. EXIT_API();
  120. return E_INVALIDARG;
  121. }
  122. //
  123. // Read a chunk at a time
  124. //
  125. if ((SystemCacheStartPte + (PteCount+1)* PteSize) > BufferedAddress + sizeof(Buffer) ) {
  126. BufferedAddress = (SystemCacheStartPte + PteCount * PteSize);
  127. if (!ReadMemory(BufferedAddress,
  128. Buffer,
  129. sizeof(Buffer),
  130. &result)) {
  131. dprintf("Unable to read memory at %p\n", BufferedAddress);
  132. PteCount += sizeof(Buffer) / PteSize;
  133. continue;
  134. }
  135. }
  136. Pte = (SystemCacheStartPte + PteCount * PteSize) - BufferedAddress;
  137. //
  138. // Too many ptes, so do the Valid checking directly instead of calling DbgGetValid
  139. //
  140. if ((*((PULONG) &Buffer[(ULONG) Pte]) >> ValidShift) & 1) {
  141. Valid += 1;
  142. }
  143. if (!(PteCount % (NumberOfPtes/100))) {
  144. dprintf(" Loading file cache database (%02d%% of %u PTEs)\r", PteCount*100/NumberOfPtes, NumberOfPtes);
  145. }
  146. }
  147. dprintf("\n");
  148. dprintf(" File cache PTEs loaded, loading PFNs...\n");
  149. // Removing below stmt since this causes lot of invald PTEs to be scanned.
  150. if (BuildNo < 3590)
  151. {
  152. HighPage = Valid;
  153. } else
  154. {
  155. HighPage = (ULONG) GetNtDebuggerDataPtrValue(MmHighestPhysicalPage);
  156. }
  157. LowPage = 0;
  158. //
  159. // Allocate a local PFN array (only) large enough to hold data about
  160. // each valid PTE we've found.
  161. //
  162. dprintf(" File cache has %ld valid pages\n",Valid);
  163. PfnSize = GetTypeSize("nt!_MMPFN");
  164. Pte = SystemCacheStartPte;
  165. dprintf(" File cache PFN data extracted\n");
  166. MemoryUsage (PfnStart,LowPage,HighPage, 1);
  167. EXIT_API();
  168. return S_OK;
  169. }