windows-nt/Source/XPSP1/NT/base/tools/kdexts2/filecach.c
2020-09-26 16:20:57 +08:00

214 lines
5 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
filecach.c
Abstract:
WinDbg Extension Api
Author:
Wesley Witt (wesw) 15-Aug-1993
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
DECLARE_API( filecache )
/*++
Routine Description:
Displays physical memory usage by drivers.
Arguments:
None.
Return Value:
None.
--*/
{
ULONG result;
ULONG NumberOfPtes;
ULONG PteCount;
ULONG ReadCount;
ULONG64 SystemCacheWsLoc;
ULONG64 SystemCacheStart;
ULONG64 SystemCacheEnd;
ULONG64 SystemCacheStartPte;
ULONG64 SystemCacheEndPte;
ULONG Transition = 0;
ULONG Valid;
ULONG ValidShift, ValidSize;
ULONG64 PfnIndex;
ULONG PteSize;
ULONG PfnSize;
ULONG HighPage;
ULONG LowPage;
ULONG64 Pte;
ULONG64 PfnDb;
ULONG64 Pfn;
ULONG64 PfnStart;
ULONG64 PfnArray;
ULONG64 PfnArrayOffset;
ULONG NumberOfPteToRead;
ULONG WorkingSetSize, PeakWorkingSetSize;
ULONG64 BufferedAddress=0;
CHAR Buffer[2048];
INIT_API();
dprintf("***** Dump file cache******\n");
SystemCacheStart = GetNtDebuggerDataPtrValue( MmSystemCacheStart );
if (!SystemCacheStart) {
dprintf("unable to get SystemCacheStart\n");
EXIT_API();
return E_INVALIDARG;
}
SystemCacheEnd = GetNtDebuggerDataPtrValue( MmSystemCacheEnd );
if (!SystemCacheEnd) {
dprintf("unable to get SystemCacheEnd\n");
EXIT_API();
return E_INVALIDARG;
}
SystemCacheWsLoc = GetNtDebuggerData( MmSystemCacheWs );
if (!SystemCacheWsLoc) {
dprintf("unable to get MmSystemCacheWs\n");
EXIT_API();
return E_INVALIDARG;
}
PfnDb = GetNtDebuggerData( MmPfnDatabase );
if (!PfnDb) {
dprintf("unable to get MmPfnDatabase\n");
EXIT_API();
return E_INVALIDARG;
}
PteSize = GetTypeSize("nt!_MMPTE");
NumberOfPteToRead = PageSize / PteSize - 16;
if (GetFieldValue(SystemCacheWsLoc,
"nt!_MMSUPPORT",
"WorkingSetSize",
WorkingSetSize)) {
dprintf("unable to get system cache list\n");
EXIT_API();
return E_INVALIDARG;
}
GetFieldValue(SystemCacheWsLoc,"nt!_MMSUPPORT","PeakWorkingSetSize",PeakWorkingSetSize);
dprintf("File Cache Information\n");
dprintf(" Current size %ld kb\n",WorkingSetSize*
(PageSize / 1024));
dprintf(" Peak size %ld kb\n",PeakWorkingSetSize*
(PageSize / 1024));
if (!ReadPointer(PfnDb,&PfnStart)) {
dprintf("unable to get PFN database address\n");
EXIT_API();
return E_INVALIDARG;
}
SystemCacheStartPte = DbgGetPteAddress (SystemCacheStart);
SystemCacheEndPte = DbgGetPteAddress (SystemCacheEnd);
NumberOfPtes = (ULONG) ( 1 + (SystemCacheEndPte - SystemCacheStartPte) / PteSize);
//
// Read in all the PTEs mapping the system cache.
//
dprintf(" Loading file cache database (%u PTEs)\r", NumberOfPtes);
GetBitFieldOffset("nt!_MMPTE", "u.Hard.Valid", &ValidShift, &ValidSize);
// dprintf("Valid off %d, num %d ", ValidShift, ValidSize);
Valid = 0;
ZeroMemory(Buffer, sizeof(Buffer));
for (PteCount = 0;
PteCount < NumberOfPtes;
PteCount += 1) {
if (CheckControlC()) {
EXIT_API();
return E_INVALIDARG;
}
//
// Read a chunk at a time
//
if ((SystemCacheStartPte + (PteCount+1)* PteSize) > BufferedAddress + sizeof(Buffer) ) {
BufferedAddress = (SystemCacheStartPte + PteCount * PteSize);
if (!ReadMemory(BufferedAddress,
Buffer,
sizeof(Buffer),
&result)) {
dprintf("Unable to read memory at %p\n", BufferedAddress);
PteCount += sizeof(Buffer) / PteSize;
continue;
}
}
Pte = (SystemCacheStartPte + PteCount * PteSize) - BufferedAddress;
//
// Too many ptes, so do the Valid checking directly instead of calling DbgGetValid
//
if ((*((PULONG) &Buffer[(ULONG) Pte]) >> ValidShift) & 1) {
Valid += 1;
}
if (!(PteCount % (NumberOfPtes/100))) {
dprintf(" Loading file cache database (%02d%% of %u PTEs)\r", PteCount*100/NumberOfPtes, NumberOfPtes);
}
}
dprintf("\n");
dprintf(" File cache PTEs loaded, loading PFNs...\n");
HighPage = Valid;
LowPage = 0;
//
// Allocate a local PFN array (only) large enough to hold data about
// each valid PTE we've found.
//
dprintf(" File cache has %ld valid pages\n",Valid);
PfnSize = GetTypeSize("nt!_MMPFN");
Pte = SystemCacheStartPte;
dprintf(" File cache PFN data extracted\n");
MemoryUsage (PfnStart,LowPage,HighPage, 1);
EXIT_API();
return S_OK;
}