windows-nt/Source/XPSP1/NT/sdktools/perfmtr/mminfo.c
2020-09-26 16:20:57 +08:00

1972 lines
77 KiB
C

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
mminfo.c
Abstract:
This module monitor the system hard page fault.
Author:
Stephen Hsiao (shsiao) 4-8-96
Environment:
User Mode
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define NTMMPERF 1
#if NTMMPERF
typedef enum _KTHREAD_STATE {
Initialized,
Ready,
Running,
Standby,
Terminated,
Waiting,
Transition
} KTHREAD_STATE;
char *ThreadState[] = {
"Initialized",
"Ready",
"Running",
"Standby",
"Terminated",
"Waiting",
"Transition",
};
char *WaitReason[] = {
"Executive",
"FreePage",
"PageIn",
"PoolAllocation",
"DelayExecution",
"Suspended",
"UserRequest",
"WrExecutive",
"WrFreePage",
"WrPageIn",
"WrPoolAllocation",
"WrDelayExecution",
"WrSuspended",
"WrUserRequest",
"WrEventPair",
"WrQueue",
"WrLpcReceive",
"WrLpcReply",
"WrVirtualMemory",
"WrPageOut",
"WrRendezvous",
"Spare2",
"Spare3",
"Spare4",
"Spare5",
"Spare6",
"WrKernel",
"MaximumWaitReason"
};
PSZ PoolTypeNames[7] = {
"NonPagedPool",
"PagedPool ",
"NonPagedMS ",
"NotUsed ",
"NonPagedCaAl",
"PagedCaAl ",
"NonPCaAlMS "
};
#define CM_KEY_NODE_SIGNATURE 0x6b6e // "kn"
#define CM_LINK_NODE_SIGNATURE 0x6b6c // "kl"
#define CM_KEY_VALUE_SIGNATURE 0x6b76 // "kv"
#define CM_KEY_SECURITY_SIGNATURE 0x6b73 // "ks"
#define CM_KEY_FAST_LEAF 0x666c // "fl"
#define MAX_TASKS 256
#define TableSize 4096
#define PAGE_SIZE 4096
#define PROTECTED_POOL 0x80000000
CHAR Mark[MAX_MMINFO_MARK_SIZE];
DWORD pid;
CHAR pname[MAX_PATH];
CHAR *MmInfoBuffer;
SYSTEM_MMINFO_FILENAME_INFORMATION ImageHash[TableSize];
SYSTEM_MMINFO_PROCESS_INFORMATION ProcessHash[TableSize];
LONG ThreadHash[TableSize] = {-1};
LONG BufferLength;
BOOLEAN Debug=FALSE;
ULONG MmInfoOnFlag=0;
ULONG DefaultOnFlag=(MMINFO_LOG_MEMORY |
MMINFO_LOG_WORKINGSET |
MMINFO_LOG_HARDFAULT |
MMINFO_LOG_PROCESS |
MMINFO_LOG_THREAD);
ULONG DefaultDetailedOnFlag=(MMINFO_LOG_MEMORY |
MMINFO_LOG_WORKINGSET |
MMINFO_LOG_HARDFAULT |
MMINFO_LOG_SOFTFAULT |
MMINFO_LOG_PROCESS |
MMINFO_LOG_THREAD |
MMINFO_LOG_CSWITCH |
MMINFO_LOG_POOL |
MMINFO_LOG_CHANGELIST);
#ifdef WS_INSTRUMENTATION
char * WsInfoHeaderFormat =
" WsInfo, Process, WorkSet, Claim, Access, Age0, Age1, Age2, Age3, Shared, Mod, Faults, RecentF, Repl, URepl, Boosts, Prio\n";
char * WsInfoDataFormat =
" WsInfo, %24s, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d\n";
char * TrimHeaderFormat =
" Trim, Process, WorkSet, Claim, Try, Got, Faults, RecentF, Repl, URepl, Boosts, Prio\n";
char * TrimDataFormat =
" Trim, %24s, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d\n";
char * WsManagerHeaderFormat =
" WsManager, Time, Avail, Claim, Faults, LastPF, Counter, DesReduc, DesFree, Action\n";
char * WsManagerDataFormat =
" WsManager, %10I64d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %s\n";
#else
char * WsInfoHeaderFormat =
" WsInfo, Process, WorkSet, Faults, Prio\n";
char * WsInfoDataFormat =
" WsInfo, %24s, %8d, %8d, %8d\n";
char * TrimHeaderFormat =
" Trim, Process, WorkSet, Faults, Prio\n";
char * TrimDataFormat =
" Trim, %24s, %8d, %8d, %8d\n";
char * WsManagerHeaderFormat =
" WsManager, Time, Avail, Faults, LastPF, Counter, DesReduc, DesFree, Action\n";
char * WsManagerDataFormat =
" WsManager, %10I64d, %8d, %8d, %8d, %8d, %8d, %8d, %s\n";
#endif // WS_INSTRUMENTATION
char * ImageLoadHeaderFormat =
" ImageLoad, BaseAddr, EndAddr, SectNum, Process, Name\n";
char * ImageLoadDataFormat =
" ImageLoad, %08x, %08x, %-8x, %s, %S\n";
char * SampleProfileHeaderFormat =
" SampledProfile, EIP, Count\n";
char * SampledProfileDataFormat =
" SampledProfile, %08x, %-8d\n";
char * GeneralHeaderFormat = "%12s,%10s,%22s,%12s,%12s,%8s,%30s,%12s,%10s,%10s,%10s\n";
ULONG ToTurnOn=0;
ULONG ToTurnOff=0;
CHAR System[] = "System";
#define MODE_NONE 0
#define MODE_SLASH 1
#define MODE_PLUS 2
#define MODE_MINUS 3
typedef struct Api_Address_St {
ULONG Address;
CHAR *ApiName;
} Api_Address_t, *PApi_Address_t;
typedef struct Dll_Address_St {
ULONG StartingAddress;
ULONG EndingAddress;
CHAR *DllName;
} Dll_Address_t, *PDll_Address_t;
PApi_Address_t GlobalApiInfo;
PDll_Address_t GlobalDllInfo;
int NumGlobalApis=0;
int NumGlobalDlls=0;
int NumAllocatedGlobalApis=0;
int NumAllocatedGlobalDlls=0;
#define AllocationIncrement 1000
VOID InsertDll(ULONG StartingAddress, ULONG EndingAddress, CHAR *DllName){
if (NumGlobalDlls == NumAllocatedGlobalDlls ){
if (NumGlobalDlls == 0 ){
NumAllocatedGlobalDlls = AllocationIncrement;
GlobalDllInfo = (PDll_Address_t)
malloc( sizeof(Dll_Address_t) * NumAllocatedGlobalDlls);
} else {
NumAllocatedGlobalDlls += AllocationIncrement;
GlobalDllInfo = (PDll_Address_t)
realloc( GlobalDllInfo, sizeof(Dll_Address_t) * NumAllocatedGlobalDlls);
}
}
if (GlobalDllInfo == NULL ){
return;
}
GlobalDllInfo[ NumGlobalDlls ].StartingAddress = StartingAddress;
GlobalDllInfo[ NumGlobalDlls ].EndingAddress = EndingAddress;
GlobalDllInfo[ NumGlobalDlls ].DllName = DllName;
NumGlobalDlls ++;
}
VOID InsertApi(ULONG Address, CHAR *ApiName){
if (NumGlobalApis == NumAllocatedGlobalApis ){
if (NumGlobalApis == 0 ){
NumAllocatedGlobalApis = AllocationIncrement;
GlobalApiInfo = (PApi_Address_t)
malloc( sizeof(Api_Address_t) * NumAllocatedGlobalApis);
} else {
NumAllocatedGlobalApis += AllocationIncrement;
GlobalApiInfo = (PApi_Address_t)
realloc( GlobalApiInfo, sizeof(Api_Address_t) * NumAllocatedGlobalApis);
}
}
if (GlobalApiInfo == NULL ){
return;
}
GlobalApiInfo[ NumGlobalApis ].Address = Address;
GlobalApiInfo[ NumGlobalApis ].ApiName = ApiName;
NumGlobalApis ++;
}
CHAR *DllContainingAddress(ULONG Address){
int i;
for(i=0; i < NumGlobalDlls; i++){
if ( GlobalDllInfo[ i ].StartingAddress <= Address &&
Address <= GlobalDllInfo[ i ].EndingAddress){
return GlobalDllInfo[ i ].DllName;
}
}
return "DllNotFound";
}
CHAR *ApiAtAddress(ULONG Address){
int i;
for(i=0; i < NumGlobalApis; i++){
if ( GlobalApiInfo[ i ].Address == Address ){
return GlobalApiInfo[ i ].ApiName;
}
}
return "ApiNotFound";
}
VOID
ParseArgs (
int argc,
char *argv[]
)
{
ULONG Mode=MODE_NONE;
char *p;
char *Usage="\
Usage: mminfo -Option \n\
/c Turn OFF hard fault clustering\n\
/i Initialize MmInfo (Allocate buffer)\n\
/u Uninitialize MmInfo (Free buffer) \n\
/d Turn on debugging\n\
/f Turn off monitoring (Keep log for later processing) \n\
/F Set a Mark with workingsetflush now \n\
/M Set a Mark now \n\
/o Turn on default monitoring (h,m,t, and w)\n\
/O Turn on detailed monitoring (plus a, l, p, and S)\n\
+/- a Turn on/off context switch monitor\n\
+/- e Turn on/off EmptyQ on every Mark\n\
+/- E Turn on/off EmptyQDetail (Per Process footprint) on every Mark\n\
+/- h Turn on/off hard fault monitor\n\
+/- l Turn on/off memory list monitor\n\
+/- m Turn on/off memory monitor\n\
+/- p Turn on/off pool monitor\n\
+/- P Turn on/off sampled profiling\n\
+/- r Turn on/off registry monitor\n\
+/- R Turn on/off registry Relocation\n\
+/- s Turn on/off initial snap shot of memory\n\
+/- S Turn on/off Soft (Demand zero and Trainsition) fault monitor\n\
+/- t Turn on/off thread & process monitor\n\
+/- T Turn on/off detailed trimming monitor\n\
+/- w Turn on/off working set monitor\n\
+/- z Turn on/off detailed working set info\n\
+/- Z Turn on/off dumping working set entries\n\
Default Dump bata (Also turn off monitoring)\n\
";
NTSTATUS status;
int i;
argc--;
*argv++;
while ( argc-- > 0 ) {
p = *argv++;
switch (*p) {
case '/':
Mode = MODE_SLASH;
break;
case '+':
Mode = MODE_PLUS;
break;
case '-':
Mode = MODE_MINUS;
break;
default:
fprintf(stderr,"%s\n", Usage);
ExitProcess(1);
}
p++;
while(*p != '\0') {
if (Mode == MODE_SLASH) {
switch (*p) {
case 'c':
ToTurnOn = ToTurnOn | MMINFO_LOG_NO_CLUSTERING;
break;
case 'd':
Debug=TRUE;
break;
case 'f':
status = NtSetSystemInformation (
SystemMmInfoLogOffInformation,
NULL,
0);
if (!NT_SUCCESS (status)) {
fprintf(stderr,"Set system information failed %lx\n",status);
}else{
fprintf(stderr,"Monitor Off\n");
}
ExitProcess(0);
case 'i':
status = NtSetSystemInformation (
SystemMmInfoInitializeInformation,
NULL,
0);
if (!NT_SUCCESS (status)) {
fprintf(stderr, "Set system information failed %lx\n",status);
}else{
fprintf(stderr,"buffer allocated\n");
}
ExitProcess(0);
case 'F':
case 'M':
{
BOOLEAN Flush = (*p == 'F') ? TRUE : FALSE;
p++;
while(*p == '\0') {
p++;
}
i=-1;
if (*p == '/' || *p == '+' || *p == '-') {
// Nothing in the Mark
fprintf(stderr, "Mark not set!\n");
fprintf(stderr,"%s\n", Usage);
ExitProcess(0);
} else if (*p == '"') {
p++;
while(*p != '"') {
if (i < MAX_MMINFO_MARK_SIZE) {
i++;
Mark[i] = *p;
}
p++;
}
} else {
while (*p != '\0') {
if (i < MAX_MMINFO_MARK_SIZE) {
i++;
Mark[i] = *p;
}
p++;
}
}
status = NtSetSystemInformation (
Flush ? SystemMmInfoMarkWithFlush
: SystemMmInfoMark,
Mark,
MAX_MMINFO_MARK_SIZE);
if (!NT_SUCCESS (status)) {
fprintf(stderr, "Set system information failed %lx\n",status);
}else{
fprintf(stderr, "Mark set: %s\n", Mark);
}
ExitProcess(0);
}
case 'o':
MmInfoOnFlag = DefaultOnFlag;
break;
case 'O':
MmInfoOnFlag = DefaultDetailedOnFlag;
break;
case 'u':
status = NtSetSystemInformation (
SystemMmInfoUnInitializeInformation,
NULL,
0);
if (!NT_SUCCESS (status)) {
fprintf(stderr,"Set system information failed %lx\n",status);
}else{
fprintf(stderr,"Unitialized\n");
}
ExitProcess(0);
default:
fprintf(stderr,"%s\n", Usage);
ExitProcess(1);
}
} else if (Mode == MODE_PLUS) {
switch (*p) {
case 'a':
ToTurnOn = ToTurnOn | MMINFO_LOG_PROCESS |
MMINFO_LOG_THREAD | MMINFO_LOG_CSWITCH;
break;
case 'e':
ToTurnOn = ToTurnOn | MMINFO_LOG_MEMORY | MMINFO_LOG_EMPTYQ | MMINFO_LOG_PROCESS;
break;
case 'E':
ToTurnOn = ToTurnOn | MMINFO_LOG_MEMORY | MMINFO_LOG_EMPTYQ
| MMINFO_LOG_EMPTYQDETAIL | MMINFO_LOG_PROCESS;
break;
case 'm':
ToTurnOn = ToTurnOn | MMINFO_LOG_MEMORY | MMINFO_LOG_PROCESS;
break;
case 'p':
ToTurnOn = ToTurnOn | MMINFO_LOG_POOL;
break;
case 'w':
ToTurnOn = ToTurnOn | MMINFO_LOG_WORKINGSET | MMINFO_LOG_PROCESS;
break;
case 't':
ToTurnOn = ToTurnOn | MMINFO_LOG_PROCESS | MMINFO_LOG_THREAD;
break;
case 'T':
ToTurnOn = ToTurnOn | MMINFO_LOG_WSCHANGE |
MMINFO_LOG_MEMORY | MMINFO_LOG_PROCESS;
break;
case 'h':
ToTurnOn = ToTurnOn | MMINFO_LOG_HARDFAULT | MMINFO_LOG_PROCESS;
break;
case 'l':
ToTurnOn = ToTurnOn | MMINFO_LOG_CHANGELIST | MMINFO_LOG_MEMORY;
break;
case 'r':
ToTurnOn = ToTurnOn | MMINFO_LOG_REGISTRY;
break;
case 'R':
status = NtSetSystemInformation (
SystemRelocateCMCellOn,
NULL,
0);
if (!NT_SUCCESS (status)) {
fprintf(stderr,"Set system information failed %lx\n",status);
}else{
fprintf(stderr,"Registry Relocation on\n");
}
ExitProcess(0);
case 's':
ToTurnOn = ToTurnOn | MMINFO_LOG_INIT_MEMSNAP;
break;
case 'S':
ToTurnOn = ToTurnOn | MMINFO_LOG_SOFTFAULT |
MMINFO_LOG_PROCESS | MMINFO_LOG_MEMORY;
break;
case 'z':
ToTurnOn = ToTurnOn | MMINFO_LOG_WSDETAILS;
break;
case 'Z':
ToTurnOn = ToTurnOn | MMINFO_LOG_WSENTRIES;
break;
case 'P':
ToTurnOn = ToTurnOn | MMINFO_LOG_PROFILE;
break;
default:
fprintf(stderr,"%s\n", Usage);
ExitProcess(1);
}
} else if (Mode == MODE_MINUS) {
switch (*p) {
case 'a':
ToTurnOff = ToTurnOff | MMINFO_LOG_CSWITCH ;
break;
case 'e':
ToTurnOff = ToTurnOff | MMINFO_LOG_EMPTYQ;
break;
case 'E':
ToTurnOff = ToTurnOff | MMINFO_LOG_EMPTYQDETAIL;
break;
case 'm':
ToTurnOff = ToTurnOff | MMINFO_LOG_MEMORY ;
break;
case 'p':
ToTurnOff = ToTurnOff | MMINFO_LOG_POOL;
break;
case 'w':
ToTurnOff = ToTurnOff | MMINFO_LOG_WORKINGSET;
break;
case 't':
ToTurnOff = ToTurnOff | MMINFO_LOG_PROCESS |
MMINFO_LOG_THREAD | MMINFO_LOG_CSWITCH;
break;
case 'T':
ToTurnOff = ToTurnOff | MMINFO_LOG_WSCHANGE;
break;
case 'h':
ToTurnOff = ToTurnOff | MMINFO_LOG_HARDFAULT;
break;
case 'l':
ToTurnOff = ToTurnOff | MMINFO_LOG_CHANGELIST;
break;
case 'r':
ToTurnOff = ToTurnOff | MMINFO_LOG_REGISTRY;
break;
case 'R':
status = NtSetSystemInformation (
SystemRelocateCMCellOff,
NULL,
0);
if (!NT_SUCCESS (status)) {
fprintf(stderr,"Set system information failed %lx\n",status);
}else{
fprintf(stderr,"Registry Relocation off\n");
}
ExitProcess(0);
case 's':
ToTurnOff = ToTurnOff | MMINFO_LOG_INIT_MEMSNAP;
break;
case 'S':
ToTurnOff = ToTurnOff | MMINFO_LOG_SOFTFAULT;
break;
case 'z':
ToTurnOff = ToTurnOff | MMINFO_LOG_WSDETAILS;
break;
case 'Z':
ToTurnOff = ToTurnOff | MMINFO_LOG_WSENTRIES;
break;
case 'P':
ToTurnOff = ToTurnOff | MMINFO_LOG_PROFILE;
break;
default:
fprintf(stderr,"%s\n", Usage);
ExitProcess(1);
}
}
p++;
}
}
}
#endif //NTMMPERF
int _cdecl
main(
int argc,
char *argv[]
)
{
#if NTMMPERF
LPSTR p;
NTSTATUS status;
ULONG ImageStart, ImageEnd;
ULONG ProcessStart, ProcessEnd;
SYSTEM_BASIC_INFORMATION BasicInfo;
ULONG TotalPageTable;
ULONG TotalModified;
ULONG TotalTransition;
SYSTEMTIME Time;
ULONG PageKb;
ULONG LogSize;
ULONG LogType;
_int64 *TmpPint64;
_int64 PerfCounter, PerfCounterStart;
_int64 PerfFrequency;
PerfHook_t *Hook, *NextHook;
TimeStamp_t TS;
PerfSize_t Size;
PerfTag_t Tag;
PerfData_t *Info;
ULONG i;
//
// First parse the arguments and see what to do.
//
ParseArgs( argc, argv );
if (ToTurnOn & ToTurnOff) {
fprintf(stderr,"Cannot turn on and off the same flag, make up your mind !!!\n");
}else{
MmInfoOnFlag=((MmInfoOnFlag | ToTurnOn) & ~ToTurnOff);
}
//
// If there is a flag to turn on. Do it.
//
if (MmInfoOnFlag) {
status = NtSetSystemInformation (
SystemMmInfoLogOnInformation,
&MmInfoOnFlag,
sizeof(ULONG));
if (!NT_SUCCESS (status)) {
fprintf(stderr,"Set system information failed ON %lx\n",status);
return 1;
}else{
fprintf(stderr,"Monitor On\n");
return 0;
}
}
//
// If we reach this point, we are do dump the log.
// First turn off monitor.
//
status = NtSetSystemInformation (SystemMmInfoLogOffInformation,
NULL,
0);
if (!NT_SUCCESS (status)) {
fprintf(stderr,"Set system information failed %lx\n",status);
return 1;
}
//
// HACK FIXFIX when doing MP stuff
//
ThreadHash[0] = 0;
ProcessHash[0].ProcessID = 0;
RtlCopyMemory(ProcessHash[0].ImageFileName, "Idle", 16);
status = NtQuerySystemInformation(
SystemBasicInformation,
&BasicInfo,
sizeof(BasicInfo),
NULL
);
if (!NT_SUCCESS (status)) {
fprintf(stderr,"query system basic information failed %lx\n",status);
return 1;
}
PageKb = BasicInfo.PageSize / 1024;
//
// print the Headers
//
printf(WsManagerHeaderFormat);
printf(WsInfoHeaderFormat);
printf(TrimHeaderFormat );
printf(ImageLoadHeaderFormat);
printf(SampleProfileHeaderFormat);
//
// Mow dump the buffer.
//
NextHook = PerfNextHook();
Hook = PerfFirstHook();
LogSize = (ULONG) NextHook - (ULONG) Hook;
// fprintf(stderr, "Size in Pages %8d\n", PerfQueryBufferSize4KPages());
// fprintf(stderr, "Size in Bytes %8d\n", PerfQueryBufferSizeBytes());
// fprintf(stderr, "Size in KBs %8d\n", PerfQueryBufferSizeKB());
// fprintf(stderr, "Size in Bytes %8d (%8x - %8x) \n", NextHook - Hook, Hook, NextHook);
while( Hook < NextHook ){
ULONG LogType;
Hook = (PerfHook_t *)PerfGetHook(Hook, &Tag, &TS, &Size, &Info );
LogType = Tag.u.Bits.HookId;
// LogType = Tag.u.Value;
// PerfCounter = 0xffffffffffffffff;
PerfCounter = TS;
if (Debug) {
// fprintf(stdout, "%8x: LogType %4d, Size:%4d, Time: %I64u\n",Hook, LogType, Size, PerfCounter);
}
switch(LogType) {
printf ("LogType=%08x\n", LogType);
case PERF_APIMON_DLL_ADDRESS:
{
PPerf_Apimon_Dll_Address_t DllInfo;
DllInfo = (PPerf_Apimon_Dll_Address_t) Info;
InsertDll(DllInfo->StartingAddress,
DllInfo->EndingAddress,
DllInfo->DllName);
printf ("DllAddressName %08x %08x %s\n",
DllInfo->StartingAddress,
DllInfo->EndingAddress,
DllInfo->DllName);
}
break;
case PERF_APIMON_API_ADDRESS:
{
PPerf_Apimon_Api_Address_t ApiInfo;
ApiInfo = (PPerf_Apimon_Api_Address_t) Info;
InsertApi(ApiInfo->Address,
ApiInfo->ApiName);
printf ("ApiAddressName %08x %s\n",
ApiInfo->Address,
ApiInfo->ApiName);
}
break;
case PERF_APIMON_ENTER:
{
PPerf_Apimon_Enter_t PEnter;
PEnter = (PPerf_Apimon_Api_Address_t) Info;
printf ("ApiEnter %08x %s %s\n",
PEnter->Address,
DllContainingAddress(PEnter->Address),
ApiAtAddress(PEnter->Address));
}
break;
case PERF_APIMON_EXIT:
{
PPerf_Apimon_Enter_t PExit;
PExit = (PPerf_Apimon_Api_Address_t) Info;
printf ("ApiExit %08x %s %s\n",
PExit->Address,
DllContainingAddress(PExit->Address),
ApiAtAddress(PExit->Address));
}
break;
case MMINFO_LOG_TYPE_VERSION:
{
PSYSTEM_MMINFO_VERSION_INFORMATION TmpPMmInfoVersion;
TmpPMmInfoVersion = (PSYSTEM_MMINFO_VERSION_INFORMATION) Info;
if (TmpPMmInfoVersion->Version != MMINFO_VERSION) {
fprintf(stderr, "Kernel Version:%4d mismatch with User Version:%d\n",
TmpPMmInfoVersion->Version,
MMINFO_VERSION
);
ExitProcess(1);
} else {
fprintf(stderr, "Version: %4d, BufferSize = %6d KB\n",
MMINFO_VERSION,
LogSize/1024);
fprintf(stdout, "Version, %4d, BufferSize, %6d KB\n",
MMINFO_VERSION,
LogSize/1024);
}
}
break;
case MMINFO_LOG_TYPE_PERFFREQUENCY:
{
PMMINFO_TIME_FREQUENCY TimeFreq;
TimeFreq = (PMMINFO_TIME_FREQUENCY) Info;
PerfFrequency = TimeFreq->Frequency;
PerfCounterStart = TimeFreq->Time;
printf("Log start at (Performance Counter), %I64d\n",
PerfCounterStart*1000000/PerfFrequency);
}
break;
case MMINFO_LOG_TYPE_FILENAMEBUFFER:
{
PSYSTEM_MMINFO_FILENAME_INFORMATION TmpPImage;
TmpPImage = (PSYSTEM_MMINFO_FILENAME_INFORMATION) Info;
while (TmpPImage->ImageKey) {
i=TmpPImage->ImageKey%TableSize;
while(ImageHash[i].ImageKey != 0) {
if (ImageHash[i].ImageKey == TmpPImage->ImageKey) {
break;
}else{
i = (i+1)%TableSize;
}
}
ImageHash[i].ImageKey =TmpPImage->ImageKey;
ImageHash[i].ImageName.Length =TmpPImage->ImageName.Length;
ImageHash[i].ImageName.Buffer =TmpPImage->ImageBuffer;
if (Debug) {
printf("%12s,", "S-Created");
}
if (Debug) {
printf("%10s,%22s,%12s,%12x,%8s,%30S,%12s,%10s,%10s\n",
"",
"",
"",
ImageHash[i].ImageKey,
"",
ImageHash[i].ImageName.Buffer,
"",
"",
"");
}
TmpPImage++;
}
}
break;
case MMINFO_LOG_TYPE_PAGEFAULT:
{
PSYSTEM_HARDPAGEFAULT_INFORMATION TmpPMmInfoLog;
TmpPMmInfoLog=(PSYSTEM_HARDPAGEFAULT_INFORMATION) Info;
printf("%12s,","HardFault");
printf("%10I64d,",
(PerfCounter - PerfCounterStart)*1000000/PerfFrequency);
if (TmpPMmInfoLog->ProcessID == 0) {
printf("%22s,","System ( 0)");
} else{
ULONG i;
i = TmpPMmInfoLog->ProcessID;
if (ProcessHash[i].ProcessID == TmpPMmInfoLog->ProcessID) {
printf("%16s ",ProcessHash[i].ImageFileName);
printf("(%3d),",ProcessHash[i].ProcessID);
}else{
printf("Process %13u,",TmpPMmInfoLog->ProcessID);
}
}
printf("%12u,",TmpPMmInfoLog->ThreadID);
printf("%12x,",TmpPMmInfoLog->Va);
printf("%8u,",TmpPMmInfoLog->Pfn);
{
ULONG i;
i=TmpPMmInfoLog->ImageKey%TableSize;
while(ImageHash[i].ImageKey != 0) {
if (ImageHash[i].ImageKey == TmpPMmInfoLog->ImageKey) {
printf("%30S,",ImageHash[i].ImageName.Buffer);
break;
}else{
i = (i+1)%TableSize;
}
}
if (ImageHash[i].ImageKey == 0) {
if (TmpPMmInfoLog->Va >= 0x8000000) {
printf("%30s,","pagefile.sys");
} else {
printf("%19s (%8x),","Image", TmpPMmInfoLog->ImageKey);
}
}
}
printf("%12I64d,",TmpPMmInfoLog->ReadOffset);
printf("%10u,",TmpPMmInfoLog->ByteCount);
if (TmpPMmInfoLog->FaultType == 3) {
printf("%10s,","Read");
} else if (TmpPMmInfoLog->FaultType == 2) {
printf("%10s,","Code");
} else if (TmpPMmInfoLog->FaultType == 1) {
printf("%10s,","Data");
} else {
printf("%10s,","NA");
}
printf("%10I64d",
(TmpPMmInfoLog->IoCompleteTime-PerfCounter)
*1000000/PerfFrequency);
printf("\n");
// printf("Got Page Fault Log\n");
break;
}
case MMINFO_LOG_TYPE_TRANSITIONFAULT:
case MMINFO_LOG_TYPE_DEMANDZEROFAULT:
case MMINFO_LOG_TYPE_ADDVALIDPAGETOWS:
case MMINFO_LOG_TYPE_PROTOPTEFAULT:
case MMINFO_LOG_TYPE_ADDTOWS:
{
PSYSTEM_MMINFO_SOFTFAULT_INFORMATION TmpPMmInfoLog;
TmpPMmInfoLog=(PSYSTEM_MMINFO_SOFTFAULT_INFORMATION) Info;
if (LogType == MMINFO_LOG_TYPE_TRANSITIONFAULT) {
printf("%12s,","TransFault");
} else if (LogType == MMINFO_LOG_TYPE_DEMANDZEROFAULT) {
printf("%12s,","DeZeroFault");
} else if (LogType == MMINFO_LOG_TYPE_ADDVALIDPAGETOWS) {
printf("%12s,","AddValidToWS");
} else if (LogType == MMINFO_LOG_TYPE_PROTOPTEFAULT) {
printf("%12s,","ProtoFault");
} else if (LogType == MMINFO_LOG_TYPE_ADDTOWS) {
printf("%12s,","AddToWS");
} else {
printf("%12s,","Unknown");
}
printf("%10s,", "");
if (TmpPMmInfoLog->ProcessID == -1) {
printf("%22s,","SystemCache");
} else{
ULONG i;
i = TmpPMmInfoLog->ProcessID;
if (ProcessHash[i].ProcessID == TmpPMmInfoLog->ProcessID) {
printf("%16s ",ProcessHash[i].ImageFileName);
printf("(%3d),",ProcessHash[i].ProcessID);
}else{
printf("Process %13u,",TmpPMmInfoLog->ProcessID);
}
}
printf("%12u,",TmpPMmInfoLog->ThreadID);
printf("%12x,",TmpPMmInfoLog->Va);
printf("%8u",TmpPMmInfoLog->Pfn);
printf("\n");
break;
}
case MMINFO_LOG_TYPE_WORKINGSETSNAP:
{
PSYSTEM_MMINFO_WSENTRY_INFORMATION TmpPWs;
PMMINFO_WSENTRY TmpPWsEntry;
ULONG Size;
ULONG ii;
UCHAR Process[22];
TmpPWs = (PSYSTEM_MMINFO_WSENTRY_INFORMATION) Info;
Size = TmpPWs->WsSize;
TmpPWsEntry = TmpPWs->Ws;
if (TmpPWs->ProcessID == -1) {
sprintf(Process,"%22s","SystemCache");
} else {
ULONG i;
i = TmpPWs->ProcessID;
if (ProcessHash[i].ProcessID == TmpPWs->ProcessID) {
sprintf(Process, "%16s (%3d)",
ProcessHash[i].ImageFileName,
ProcessHash[i].ProcessID);
}else{
sprintf(Process,"Process %13u",TmpPWs->ProcessID);
}
}
for (ii = 1; ii <= Size; ii++) {
printf("%12s,%10s,%22s,%12u,%12x,%8u,%s,%s",
"WsSnap",
"",
Process,
ii,
TmpPWsEntry->Va.Page << 12,
TmpPWsEntry->Pa.Page,
TmpPWsEntry->Pa.Accessed ?
"Accessed" : "NotAccessed",
TmpPWsEntry->Pa.Modified ?
"Modified" : "NotModified",
TmpPWsEntry->Pa.Shared ?
"Shared" : "NotShared"
);
#ifdef WS_INSTRUMENTATION_ACCESS_BIT
printf(",%s",
TmpPWsEntry->Pa.RecentlyUsed ?
"RecentlyUsed" : "NotRecentlyUsed"
);
#endif // WS_INSTRUMENTATION_ACCESS_BIT
printf("\n");
TmpPWsEntry++;
}
// printf("Size = %d\n", Size);
break;
}
case MMINFO_LOG_TYPE_OUTWS_REPLACEUSED:
case MMINFO_LOG_TYPE_OUTWS_REPLACEUNUSED:
case MMINFO_LOG_TYPE_OUTWS_VOLUNTRIM:
case MMINFO_LOG_TYPE_OUTWS_FORCETRIM:
case MMINFO_LOG_TYPE_OUTWS_ADJUSTWS:
case MMINFO_LOG_TYPE_OUTWS_EMPTYQ:
{
PSYSTEM_MMINFO_WSCHANGE_INFORMATION TmpPMmInfoLog;
TmpPMmInfoLog=(PSYSTEM_MMINFO_WSCHANGE_INFORMATION) Info;
printf("%12s,","Out_Of_WS");
if (LogType == MMINFO_LOG_TYPE_OUTWS_REPLACEUSED) {
printf("%10s,","RepUsed");
} else if (LogType == MMINFO_LOG_TYPE_OUTWS_REPLACEUNUSED) {
printf("%10s,","RepUnUsed");
} else if (LogType == MMINFO_LOG_TYPE_OUTWS_VOLUNTRIM) {
printf("%10s,","VolunTrim");
} else if (LogType == MMINFO_LOG_TYPE_OUTWS_FORCETRIM) {
printf("%10s,","ForceTrim");
} else if (LogType == MMINFO_LOG_TYPE_OUTWS_ADJUSTWS) {
printf("%10s,","AdjustWs");
} else if (LogType == MMINFO_LOG_TYPE_OUTWS_EMPTYQ) {
printf("%10s,","EmptyQ");
} else {
printf("%10s,","Unknown");
}
if (TmpPMmInfoLog->ProcessID == 0) {
printf("%22s,","SystemCache");
} else{
ULONG i;
i = TmpPMmInfoLog->ProcessID;
if (ProcessHash[i].ProcessID == TmpPMmInfoLog->ProcessID) {
printf("%16s ",ProcessHash[i].ImageFileName);
printf("(%3d),",ProcessHash[i].ProcessID);
}else{
printf("Process %13u,",TmpPMmInfoLog->ProcessID);
}
}
printf("%12s,","");
printf("%12x,",TmpPMmInfoLog->Entry.Va.Page << 12);
printf("%8u",TmpPMmInfoLog->Entry.Pa.Page);
printf("\n");
break;
}
case MMINFO_LOG_TYPE_WSINFOCACHE:
case MMINFO_LOG_TYPE_TRIMCACHE:
case MMINFO_LOG_TYPE_WSINFOPROCESS:
case MMINFO_LOG_TYPE_TRIMPROCESS:
{
PSYSTEM_MMINFO_TRIMPROCESS_INFORMATION TmpPMmInfoTrimProcess;
TmpPMmInfoTrimProcess = (PSYSTEM_MMINFO_TRIMPROCESS_INFORMATION) Info;
if ((LogType == MMINFO_LOG_TYPE_WSINFOPROCESS) ||
(LogType == MMINFO_LOG_TYPE_WSINFOCACHE)) {
printf("%12s,","WsInfo");
} else {
printf("%12s,","Triming");
}
printf("WS:%7d,", TmpPMmInfoTrimProcess->ProcessWorkingSet);
if ((LogType == MMINFO_LOG_TYPE_TRIMCACHE) ||
(LogType == MMINFO_LOG_TYPE_WSINFOCACHE)) {
printf("%22s,","SystemCache");
} else{
if (TmpPMmInfoTrimProcess->ProcessID == 0) {
printf("%30s,","System ( 0)");
} else {
ULONG i;
i = TmpPMmInfoTrimProcess->ProcessID;
if (ProcessHash[i].ProcessID == TmpPMmInfoTrimProcess->ProcessID) {
printf("%16s ",ProcessHash[i].ImageFileName);
printf("(%3d),",ProcessHash[i].ProcessID);
}else{
printf("Process %13u,",TmpPMmInfoTrimProcess->ProcessID);
}
}
}
printf("Need:%7d,", TmpPMmInfoTrimProcess->ToTrim);
printf("Got:%8d,", TmpPMmInfoTrimProcess->ActualTrim);
printf("Pri:%4d,", TmpPMmInfoTrimProcess->ProcessMemoryPriority);
printf("PageFaults:%8d,",
TmpPMmInfoTrimProcess->ProcessPageFaultCount-
TmpPMmInfoTrimProcess->ProcessLastPageFaultCount);
if ((LogType == MMINFO_LOG_TYPE_WSINFOPROCESS) ||
(LogType == MMINFO_LOG_TYPE_WSINFOCACHE)) {
printf("Acc:%4d,",
TmpPMmInfoTrimProcess->ProcessAccessedCount);
printf("Mod:%4d,",
TmpPMmInfoTrimProcess->ProcessModifiedCount);
printf("Shd:%4d,",
TmpPMmInfoTrimProcess->ProcessSharedCount);
#ifdef WS_INSTRUMENTATION_ACCESS_BIT
printf("RUsed:%4d,",
TmpPMmInfoTrimProcess->ProcessRecentlyUsedCount);
#endif // WS_INSTRUMENTATION_ACCESS_BIT
}
#ifdef WS_INSTRUMENTATION
printf("Replacments:%5d,",
TmpPMmInfoTrimProcess->ProcessReplacementCount);
printf("QuotaBoosts:%5d,",
TmpPMmInfoTrimProcess->ProcessQuotaBoostCount);
printf("UsedRepls:%5d,",
TmpPMmInfoTrimProcess->ProcessSparecount3);
printf("FaultsSinceQInc:%5d,",
TmpPMmInfoTrimProcess->ProcessPageFaultCount-
TmpPMmInfoTrimProcess->ProcessLastGrowthFaultCount);
printf("FaultSinceFGTrim:%5d,",
TmpPMmInfoTrimProcess->ProcessPageFaultCount -
TmpPMmInfoTrimProcess->
ProcessLastForegroundTrimFaultCount);
printf("Spare4:%5d,",
TmpPMmInfoTrimProcess->ProcessSparecount4);
printf("Spare5:%2d,",
TmpPMmInfoTrimProcess->ProcessSparecount5);
#endif // WS_INSTRUMENTATION
printf("\n");
break;
}
case MMINFO_LOG_TYPE_POOLSTAT:
case MMINFO_LOG_TYPE_ADDPOOLPAGE:
case MMINFO_LOG_TYPE_FREEPOOLPAGE:
{
PSYSTEM_MMINFO_POOL_INFORMATION TmpPMmInfoPool;
TmpPMmInfoPool = (PSYSTEM_MMINFO_POOL_INFORMATION) Info;
if (LogType == MMINFO_LOG_TYPE_ADDPOOLPAGE) {
printf("%12s,","AddPoolPage");
} else if (LogType == MMINFO_LOG_TYPE_FREEPOOLPAGE) {
printf("%12s,","FreePoolPage");
} else{
printf("%12s,","PoolSummary");
}
printf("%10s,%22d,%12s,%12x,%8d,%8d,%8d,%12d,%12d\n",
"",
(int) TmpPMmInfoPool->Pool /100,
PoolTypeNames[(TmpPMmInfoPool->Pool%100) & 7],
TmpPMmInfoPool->Entry,
TmpPMmInfoPool->Alloc,
TmpPMmInfoPool->DeAlloc,
TmpPMmInfoPool->TotalPages,
TmpPMmInfoPool->TotalBytes,
// TmpPMmInfoPool->TotalBytes*100/4096/TmpPMmInfoPool->TotalPages,
// TmpPMmInfoPool->TotalBigBytes,
TmpPMmInfoPool->TotalBigPages
// TmpPMmInfoPool->TotalBigBytes*100/4096/TmpPMmInfoPool->TotalBigPages
);
break;
}
case MMINFO_LOG_TYPE_WORKINGSETMANAGER:
{
PSYSTEM_WORKINGSETMANAGER_INFORMATION TmpPWorkingSetManager;
char *ActionString;
TmpPWorkingSetManager = (PSYSTEM_WORKINGSETMANAGER_INFORMATION) Info;
switch(TmpPWorkingSetManager->Action) {
case WS_ACTION_RESET_COUNTER:
ActionString = "Reset Counter";
break;
case WS_ACTION_NOTHING:
ActionString = "Nothing";
break;
case WS_ACTION_INCREMENT_COUNTER:
ActionString = "Increment Counter";
break;
case WS_ACTION_WILL_TRIM:
ActionString = "Start Trimming";
break;
case WS_ACTION_FORCE_TRIMMING_PROCESS:
ActionString = "Force Trim";
break;
case WS_ACTION_WAIT_FOR_WRITER:
ActionString = "Wait writter";
break;
case WS_ACTION_EXAMINED_ALL_PROCESS:
ActionString = "All Process Examed";
break;
case WS_ACTION_AMPLE_PAGES_EXIST:
ActionString = "Ample Pages Exist";
break;
case WS_ACTION_END_WALK_ENTRIES:
ActionString = "Finished Walking WsEntries";
break;
default:
ActionString = "Unknown Action";
break;
}
printf(WsManagerDataFormat,
(PerfCounter - PerfCounterStart) *1000000/PerfFrequency,
TmpPWorkingSetManager->Available,
TmpPWorkingSetManager->PageFaultCount,
TmpPWorkingSetManager->LastPageFaultCount,
TmpPWorkingSetManager->MiCheckCounter,
TmpPWorkingSetManager->DesiredReductionGoal,
TmpPWorkingSetManager->DesiredFreeGoal,
ActionString
);
break;
}
case MMINFO_LOG_TYPE_REMOVEPAGEFROMLIST:
case MMINFO_LOG_TYPE_REMOVEPAGEBYCOLOR:
case MMINFO_LOG_TYPE_PAGEINMEMORY:
case MMINFO_LOG_TYPE_MEMORYSNAP:
case MMINFO_LOG_TYPE_SETPFNDELETED:
case MMINFO_LOG_TYPE_DELETEKERNELSTACK:
{
PSYSTEM_REMOVEDPAGE_INFORMATION TmpPRemovedPage;
TmpPRemovedPage=(PSYSTEM_REMOVEDPAGE_INFORMATION) Info;
if (LogType == MMINFO_LOG_TYPE_PAGEINMEMORY) {
printf("%12s,","InMemory");
}else if (LogType == MMINFO_LOG_TYPE_MEMORYSNAP) {
printf("%12s,","MemSnap");
}else if (LogType == MMINFO_LOG_TYPE_SETPFNDELETED) {
printf("%12s,","PfnDeleted");
}else if (LogType == MMINFO_LOG_TYPE_DELETEKERNELSTACK) {
printf("%12s,","DeleteStack");
}else {
printf("%12s,","PageRemoved");
}
printf("%10I64d,",
(PerfCounter - PerfCounterStart)
*1000000/PerfFrequency);
printf("%22s,","");
printf("%12x,",TmpPRemovedPage->Pte);
// printf("%30S,",.ImageName.Buffer);
switch(TmpPRemovedPage->UsedFor) {
case MMINFO_PAGE_USED_FOR_PAGEDPOOL:
printf("%12x,",TmpPRemovedPage->Pte<<10);
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","Paged Pool");
printf("%12s,%10s,%10s,","","","PagedPool");
break;
case MMINFO_PAGE_USED_FOR_NONPAGEDPOOL:
printf("%12x,",TmpPRemovedPage->Pte<<10);
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","NonPaged Pool");
printf("%12s,%10s,%10s,","","","NonPagedP");
break;
case MMINFO_PAGE_USED_FOR_KERNELSTACK:
printf("%12x,",TmpPRemovedPage->Pte<<10);
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","Kernel Stack");
printf("%12s,%10s,%10s,","","","K-Stack");
break;
case MMINFO_PAGE_USED_FOR_FREEPAGE:
printf("%12s,","");
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","Free Page");
printf("%12s,%10s,%10s,","","","Free");
break;
case MMINFO_PAGE_USED_FOR_ZEROPAGE:
printf("%12s,","");
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","Zero Page");
printf("%12s,%10s,%10s,","","","Zero");
break;
case MMINFO_PAGE_USED_FOR_BADPAGE:
printf("%12s,","");
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","Bad Page");
printf("%12s,%10s,%10s,","","","Bad");
break;
case MMINFO_PAGE_USED_FOR_UNKNOWN:
printf("%12s,","");
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","Unknown");
printf("%12s,%10s,%10s,","","","Unknown");
break;
case MMINFO_PAGE_USED_FOR_METAFILE:
printf("%12s,","");
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","Meta File");
printf("%12s,%10s,%10s,","","","Meta");
break;
case MMINFO_PAGE_USED_FOR_NONAME:
printf("%12s,","");
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","No Name");
printf("%12s,%10s,%10s,","","","Image");
break;
case MMINFO_PAGE_USED_FOR_PAGEFILEMAPPED:
printf("%12x,",TmpPRemovedPage->Pte<<10);
printf("%8u,",TmpPRemovedPage->Pfn);
printf("%30s,","Page File Mapped");
printf("%12s,%10s,%10s,","","","PFMapped");
break;
case MMINFO_PAGE_USED_FOR_FILE:
case MMINFO_PAGE_USED_FOR_KERNMAP:
{
ULONG i,j;
if (TmpPRemovedPage->UsedFor != MMINFO_PAGE_USED_FOR_KERNMAP) {
printf("%12s,","");
} else {
printf("%12x,",TmpPRemovedPage->Pte << 10);
}
printf("%8u,",TmpPRemovedPage->Pfn);
i=TmpPRemovedPage->ImageKey%TableSize;
while(ImageHash[i].ImageKey != 0) {
if (ImageHash[i].ImageKey == TmpPRemovedPage->ImageKey) {
printf("%30S,",ImageHash[i].ImageName.Buffer);
break;
}else{
i = (i+1)%TableSize;
}
}
if (Debug) {
// printf("(%4d %22x)",i,TmpPRemovedPage->ImageKey);
}
if (ImageHash[i].ImageKey == 0) {
if (TmpPRemovedPage->UsedFor != MMINFO_PAGE_USED_FOR_KERNMAP) {
printf("%19s (%8x),","Image", TmpPRemovedPage->ImageKey);
printf("%12I64d,",TmpPRemovedPage->Offset);
printf("%10s,","");
printf("%10s,","FILE");
}else{
printf("%19s (%8x),","KernMap", TmpPRemovedPage->ImageKey);
printf("%12s,%10s,","","");
printf("%10s,","Driver");
}
}else{
if (TmpPRemovedPage->UsedFor == MMINFO_PAGE_USED_FOR_KERNMAP) {
printf("%12I64d,",TmpPRemovedPage->Offset);
printf("%10s,","");
printf("%10s,","Driver");
}else if (TmpPRemovedPage->UsedFor == MMINFO_PAGE_USED_FOR_FILE) {
printf("%12I64d,",TmpPRemovedPage->Offset);
printf("%10s,","");
printf("%10s,","FILE");
}else{
printf("%12s,%10s,","","");
printf("%10s,","Unknown");
}
}
}
break;
case MMINFO_PAGE_USED_FOR_PROCESS:
case MMINFO_PAGE_USED_FOR_PAGETABLE:
{
ULONG i;
// Bug! Bug! The way to get VA can be wrong in the future.
if (TmpPRemovedPage->UsedFor == MMINFO_PAGE_USED_FOR_PAGETABLE) {
printf("%12x,",TmpPRemovedPage->Pte<<10);
printf("%8u,",TmpPRemovedPage->Pfn);
printf("(PT)");
}else{
printf("%12x,",TmpPRemovedPage->Pte<<10);
printf("%8u,",TmpPRemovedPage->Pfn);
printf(" ");
}
if (TmpPRemovedPage->ImageKey == 0) {
printf("%26s,","System ( 0)");
}else{
i = TmpPRemovedPage->ImageKey;
if (ProcessHash[i].ProcessID == TmpPRemovedPage->ImageKey) {
printf("%20s ",ProcessHash[i].ImageFileName);
printf("(%3d),",ProcessHash[i].ProcessID);
}else{
printf("Process %18u,",TmpPRemovedPage->ImageKey);
}
}
if (TmpPRemovedPage->UsedFor == MMINFO_PAGE_USED_FOR_PAGETABLE) {
// printf("%12I64d,",TmpPRemovedPage->Offset);
printf("%12s,%10s,%10s,","","","PageTable");
}else{
printf("%12s,%10s,%10s,","","","Process");
// printf("%30s,","Page Table");
}
}
break;
default:
printf("Error2 %22u,",TmpPRemovedPage->ImageKey);
break;
}
switch(TmpPRemovedPage->List) {
case MMINFO_PAGE_IN_LIST_FREEPAGE:
printf("%10s","Free List");
break;
case MMINFO_PAGE_IN_LIST_ZEROPAGE:
printf("%10s","Zero List");
break;
case MMINFO_PAGE_IN_LIST_BADPAGE:
printf("%10s","Bad List");
break;
case MMINFO_PAGE_IN_LIST_STANDBY:
printf("%10s","Standby");
break;
case MMINFO_PAGE_IN_LIST_TRANSITION:
printf("%10s","Transition");
break;
case MMINFO_PAGE_IN_LIST_MODIFIED:
printf("%10s","Modified");
break;
case MMINFO_PAGE_IN_LIST_MODIFIEDNOWRITE:
printf("%10s","ModNoWrite");
break;
case MMINFO_PAGE_IN_LIST_ACTIVEANDVALID:
printf("%10s","Valid");
break;
case MMINFO_PAGE_IN_LIST_VALIDANDPINNED:
printf("%10s","Valid_Pin");
break;
case MMINFO_PAGE_IN_LIST_UNKNOWN:
printf("%10s","Unknown");
break;
default:
// must be page table
printf("%10s","");
break;
}
printf("\n");
// printf("Got Removed Page Log\n");
break;
}
case MMINFO_LOG_TYPE_ZEROSHARECOUNT:
case MMINFO_LOG_TYPE_ZEROREFCOUNT:
case MMINFO_LOG_TYPE_DECREFCNT:
case MMINFO_LOG_TYPE_DECSHARCNT:
{
PSYSTEM_MMINFO_PFN_INFORMATION TmpPPfn;
TmpPPfn = (PSYSTEM_MMINFO_PFN_INFORMATION) Info;
if (LogType == MMINFO_LOG_TYPE_DECSHARCNT) {
printf("%12s,", "DecShareCnt");
} else if (LogType == MMINFO_LOG_TYPE_ZEROSHARECOUNT) {
printf("%12s,", "ZeroShareCnt");
} else if (LogType == MMINFO_LOG_TYPE_DECREFCNT) {
printf("%12s,", "DecRefCnt");
} else if (LogType == MMINFO_LOG_TYPE_ZEROREFCOUNT) {
printf("%12s,", "ZeroRefCnt");
} else {
printf("%12s,", "UNKNOWN");
}
printf("%10s,","");
printf("%22s,","");
printf("%12s,","");
printf("%12s,","");
printf("%8u\n",TmpPPfn->Pfn);
break;
}
case MMINFO_LOG_TYPE_INSERTINLIST:
case MMINFO_LOG_TYPE_INSERTATFRONT:
case MMINFO_LOG_TYPE_UNLINKFROMSTANDBY:
case MMINFO_LOG_TYPE_UNLINKFFREEORZERO:
{
PSYSTEM_MMINFO_STATE_INFORMATION TmpPMmInfoState;
TmpPMmInfoState=(PSYSTEM_MMINFO_STATE_INFORMATION) Info;
if (LogType == MMINFO_LOG_TYPE_INSERTINLIST) {
printf("%12s,%10s,","Insert-List", "");
}else if (LogType == MMINFO_LOG_TYPE_INSERTATFRONT) {
printf("%12s,%10s,","Insert-Front", "");
}else if (LogType == MMINFO_LOG_TYPE_UNLINKFROMSTANDBY) {
printf("%12s,%10s,","Unlink-From", "");
}else if (LogType == MMINFO_LOG_TYPE_UNLINKFFREEORZERO) {
printf("%12s,%10s,","Unlink-From", "");
}
printf("%22s,","");
printf("%12s,","");
printf("%12s,","");
printf("%8u,",TmpPMmInfoState->Pfn);
printf("%30s,","");
printf("%12s,%10s,%10s,","","","");
switch(TmpPMmInfoState->List) {
case MMINFO_PAGE_IN_LIST_FREEPAGE:
printf("%10s","Free List");
break;
case MMINFO_PAGE_IN_LIST_ZEROPAGE:
printf("%10s","Zero List");
break;
case MMINFO_PAGE_IN_LIST_BADPAGE:
printf("%10s","Bad List");
break;
case MMINFO_PAGE_IN_LIST_STANDBY:
printf("%10s","Standby");
break;
case MMINFO_PAGE_IN_LIST_TRANSITION:
printf("%10s","Transition");
break;
case MMINFO_PAGE_IN_LIST_MODIFIED:
printf("%10s","Modified");
break;
case MMINFO_PAGE_IN_LIST_MODIFIEDNOWRITE:
printf("%10s","ModNoWrite");
break;
case MMINFO_PAGE_IN_LIST_ACTIVEANDVALID:
printf("%10s","Valid");
break;
case MMINFO_PAGE_IN_LIST_VALIDANDPINNED:
printf("%10s","Valid_Pin");
break;
case MMINFO_PAGE_IN_LIST_UNKNOWN:
printf("%10s","Unknown");
break;
default:
// must be page table
printf("%10s","");
break;
}
printf("\n");
// printf("Got Removed Page Log\n");
break;
}
case MMINFO_LOG_TYPE_IMAGENAME:
case MMINFO_LOG_TYPE_SECTIONREMOVED:
{
PSYSTEM_MMINFO_FILENAME_INFORMATION TmpPImage;
ULONG i;
TmpPImage=(PSYSTEM_MMINFO_FILENAME_INFORMATION) Info;
// printf("Got Image Log\n");
i=TmpPImage->ImageKey%TableSize;
while(ImageHash[i].ImageKey != 0) {
if (ImageHash[i].ImageKey == TmpPImage->ImageKey) {
break;
}else{
i = (i+1)%TableSize;
}
}
if (LogType == MMINFO_LOG_TYPE_IMAGENAME) {
ImageHash[i].ImageKey
=TmpPImage->ImageKey;
ImageHash[i].ImageName.Length
=TmpPImage->ImageName.Length;
ImageHash[i].ImageName.Buffer
=TmpPImage->ImageBuffer;
if (Debug) {
printf("%12s,", "S-Created");
}
}else{
if (Debug) {
printf("%12s,", "S-Deleted");
}
}
if (Debug) {
printf("%10s,%22s,%12s,%12x,%8s,%30S,%12s,%10s,%10s\n",
"",
"",
"",
ImageHash[i].ImageKey,
"",
ImageHash[i].ImageName.Buffer,
"",
"",
"");
}
break;
}
case MMINFO_LOG_TYPE_PROCESSNAME:
case MMINFO_LOG_TYPE_DIEDPROCESS:
{
PSYSTEM_MMINFO_PROCESS_INFORMATION TmpPProcess;
ULONG i;
TmpPProcess=(PSYSTEM_MMINFO_PROCESS_INFORMATION) Info;
if (LogType == MMINFO_LOG_TYPE_PROCESSNAME) {
i = TmpPProcess->ProcessID;
ProcessHash[i].ProcessID
=TmpPProcess->ProcessID;
RtlCopyMemory(ProcessHash[i].ImageFileName,
TmpPProcess->ImageFileName, 16);
printf("%12s,", "P-Created");
}else{
printf("%12s,", "P-Deleted");
}
printf("%10s,%16s (%3d)\n",
"",
ProcessHash[TmpPProcess->ProcessID].ImageFileName,
ProcessHash[TmpPProcess->ProcessID].ProcessID);
// printf("Got Process Log\n");
break;
}
case MMINFO_LOG_TYPE_OUTSWAPPROCESS:
case MMINFO_LOG_TYPE_INSWAPPROCESS:
{
PSYSTEM_MMINFO_SWAPPROCESS_INFORMATION TmpPProc;
ULONG i;
TmpPProc=(PSYSTEM_MMINFO_SWAPPROCESS_INFORMATION) Info;
if (LogType == MMINFO_LOG_TYPE_OUTSWAPPROCESS) {
printf("%12s,", "P-OutSwap");
}else{
printf("%12s,", "P-InSwap");
}
if (PerfCounter) {
printf("%10I64d,", ((PerfCounter - PerfCounterStart) * 1000000) / PerfFrequency);
} else {
printf("%10s,", "");
}
printf("%16s (%3d)",
ProcessHash[TmpPProc->ProcessID].ImageFileName,
ProcessHash[TmpPProc->ProcessID].ProcessID);
printf("\n");
break;
}
case MMINFO_LOG_TYPE_OUTSWAPSTACK:
case MMINFO_LOG_TYPE_INSWAPSTACK:
{
PSYSTEM_MMINFO_SWAPTHREAD_INFORMATION TmpPThread;
ULONG i;
TmpPThread=(PSYSTEM_MMINFO_SWAPTHREAD_INFORMATION) Info;
if (LogType == MMINFO_LOG_TYPE_OUTSWAPSTACK) {
printf("%12s,", "KS-OutSwap");
}else{
printf("%12s,", "KS-InSwap");
}
printf("%10d,%16s (%3d)",
TmpPThread->ThreadID,
ProcessHash[TmpPThread->ProcessID].ImageFileName,
ProcessHash[TmpPThread->ProcessID].ProcessID);
if (PerfCounter) {
printf(",%12I64d", ((PerfCounter - PerfCounterStart) * 1000000) / PerfFrequency);
}
printf("\n");
break;
}
case MMINFO_LOG_TYPE_CREATETHREAD:
case MMINFO_LOG_TYPE_GROWKERNELSTACK:
case MMINFO_LOG_TYPE_TERMINATETHREAD:
case MMINFO_LOG_TYPE_CONVERTTOGUITHREAD:
{
PSYSTEM_MMINFO_THREAD_INFORMATION TmpPThread;
ULONG i;
TmpPThread=(PSYSTEM_MMINFO_THREAD_INFORMATION) Info;
if (LogType == MMINFO_LOG_TYPE_CREATETHREAD) {
printf("%12s,", "T-Created");
ThreadHash[TmpPThread->ThreadID] = TmpPThread->ProcessID;
}else if (LogType == MMINFO_LOG_TYPE_GROWKERNELSTACK) {
printf("%12s,", "GrowStack");
}else if (LogType == MMINFO_LOG_TYPE_CONVERTTOGUITHREAD) {
printf("%12s,", "T-GUI");
}else{
printf("%12s,", "T-Deleted");
//
// Threads are sometimes set as deleted while still
// running. If we mark them as dead here we have
// a problem when they are cswitched out.
//
//ThreadHash[TmpPThread->ThreadID] = -1;
}
printf("%10d,%16s (%3d)",
TmpPThread->ThreadID,
ProcessHash[TmpPThread->ProcessID].ImageFileName,
ProcessHash[TmpPThread->ProcessID].ProcessID);
// printf("Got Process Log\n");
if (LogType != MMINFO_LOG_TYPE_TERMINATETHREAD) {
printf(",%12x",TmpPThread->StackBase);
printf(",%12x",TmpPThread->StackLimit);
if (TmpPThread->UserStackBase) {
printf(",%12x",TmpPThread->UserStackBase);
printf(",%12x",TmpPThread->UserStackLimit);
} else {
printf(",%12s","");
printf(",%12s","");
}
if (TmpPThread->WaitMode >= 0) {
if (TmpPThread->WaitMode) {
printf(",%8s", "Swapable");
} else {
printf(",%8s", "NonSwap");
}
}
}
printf("\n");
break;
}
case MMINFO_LOG_TYPE_CSWITCH:
{
PSYSTEM_MMINFO_CSWITCH_INFORMATION TmpPMmInfo;
ULONG OldProcessId;
ULONG NewProcessId;
TmpPMmInfo = (PSYSTEM_MMINFO_CSWITCH_INFORMATION) Info;
OldProcessId = ThreadHash[TmpPMmInfo->OldThreadId];
NewProcessId = ThreadHash[TmpPMmInfo->NewThreadId];
if ((OldProcessId == -1) || (NewProcessId == -1)) {
printf("Error: Bad thread value %d or %d\n",
TmpPMmInfo->OldThreadId,
TmpPMmInfo->NewThreadId
);
break;
}
printf("%12s,%10I64d,%11s,%16s,%10d,%16s (%3d), %10d,%16s (%3d),%4d,%4d,%8s\n",
"CSwitch",
((PerfCounter - PerfCounterStart) *
1000000) / PerfFrequency,
ThreadState[TmpPMmInfo->OldState],
(TmpPMmInfo->OldState == Waiting) ?
WaitReason[TmpPMmInfo->WaitReason] :
"",
TmpPMmInfo->OldThreadId,
ProcessHash[OldProcessId].ImageFileName,
OldProcessId,
TmpPMmInfo->NewThreadId,
ProcessHash[NewProcessId].ImageFileName,
NewProcessId,
TmpPMmInfo->OldThreadPri,
TmpPMmInfo->NewThreadPri,
(TmpPMmInfo->OldWaitMode) ? "Swapable" : "NonSwap"
);
break;
}
case MMINFO_LOG_TYPE_POOLSNAP:
{
#define PROTECTED_POOL 0x80000000
ULONG PoolTag[2]={0,0};
PMMINFO_POOL_TRACKER_TABLE TmpPMmInfopoolTrackTable;
TmpPMmInfopoolTrackTable=(PMMINFO_POOL_TRACKER_TABLE) Info;
PoolTag[0]=TmpPMmInfopoolTrackTable->Tag & ~PROTECTED_POOL;
// Data for Paged Pool
if (TmpPMmInfopoolTrackTable->PagedAllocs) {
printf("%12s,","PoolSnap");
printf("%10s,", PoolTag);
printf("%22s,","");
printf("%12s,%12s,","PagedPool","");
printf("%8u,%8u,%8u\n",
TmpPMmInfopoolTrackTable->PagedBytes,
TmpPMmInfopoolTrackTable->PagedAllocs,
TmpPMmInfopoolTrackTable->PagedFrees);
}
// Data for NonPaged Pool
if (TmpPMmInfopoolTrackTable->NonPagedAllocs) {
printf("%12s,","PoolSnap");
printf("%10s,", PoolTag);
printf("%22s,","");
printf("%12s,%12s,","NonPagedPool","");
printf("%8u,%8u,%8u\n",
TmpPMmInfopoolTrackTable->NonPagedBytes,
TmpPMmInfopoolTrackTable->NonPagedAllocs,
TmpPMmInfopoolTrackTable->NonPagedFrees);
}
break;
}
case MMINFO_LOG_TYPE_ALLOCATEPOOL:
case MMINFO_LOG_TYPE_BIGPOOLPAGE:
{
#define PROTECTED_POOL 0x80000000
ULONG PoolTag[2]={0,0};
PSYSTEM_MMINFO_ALLOCATEPOOL_INFORMATION TmpPMmInfoAllocatePool;
TmpPMmInfoAllocatePool=(PSYSTEM_MMINFO_ALLOCATEPOOL_INFORMATION) Info;
PoolTag[0]=TmpPMmInfoAllocatePool->PoolTag & ~PROTECTED_POOL;
if (LogType == MMINFO_LOG_TYPE_ALLOCATEPOOL) {
printf("%12s,", "Pool_Alloc");
printf("%10s,", PoolTag);
if (TmpPMmInfoAllocatePool->ProcessID == 0) {
printf("%22s,","System ( 0)");
} else{
ULONG i;
i = TmpPMmInfoAllocatePool->ProcessID;
if (ProcessHash[i].ProcessID == TmpPMmInfoAllocatePool->ProcessID) {
printf("%16s ",ProcessHash[i].ImageFileName);
printf("(%3d),",ProcessHash[i].ProcessID);
}else{
printf("Process %13u,",TmpPMmInfoAllocatePool->ProcessID);
}
}
}else{
printf("%12s,","BigPoolPage");
printf("%10s,", PoolTag);
printf("%22s,","");
}
printf("%12s,%12x,%8u\n",
PoolTypeNames[TmpPMmInfoAllocatePool->PoolType & 7],
TmpPMmInfoAllocatePool->Entry,
TmpPMmInfoAllocatePool->Size);
break;
}
case MMINFO_LOG_TYPE_FREEPOOL:
{
PSYSTEM_MMINFO_FREEPOOL_INFORMATION TmpPMmInfoFreePool;
TmpPMmInfoFreePool=(PSYSTEM_MMINFO_FREEPOOL_INFORMATION) Info;
printf("%12s,%10s,%22s,%12s,%12x\n",
"Pool_Free",
"",
"",
"",
TmpPMmInfoFreePool->Entry);
break;
}
case MMINFO_LOG_TYPE_ASYNCMARK:
case MMINFO_LOG_TYPE_MARK:
{
PSYSTEM_MMINFO_MARK_INFORMATION TmpPMmInfo;
TmpPMmInfo = (PSYSTEM_MMINFO_MARK_INFORMATION) Info;
printf("%12s,%10I64d, %-s\n",
(LogType == MMINFO_LOG_TYPE_ASYNCMARK) ?
"AsyncMark" : "Mark",
((PerfCounter - PerfCounterStart) *
1000000) / PerfFrequency,
TmpPMmInfo->Name);
break;
}
case MMINFO_LOG_TYPE_CMCELLREFERRED:
{
PSYSTEM_MMINFO_CMCELL_INFORMATION TmpPMmInfoCmCell;
TmpPMmInfoCmCell=(PSYSTEM_MMINFO_CMCELL_INFORMATION) Info;
printf("%12s,%10s,","Cell_Used","");
switch(TmpPMmInfoCmCell->Signature) {
case CM_KEY_NODE_SIGNATURE:
printf("%22s,%12s","Key_Node","");
break;
case CM_LINK_NODE_SIGNATURE:
printf("%22s,%12s","Link_Node","");
break;
case CM_KEY_VALUE_SIGNATURE:
printf("%22s,%12s","Key_Value","");
break;
case CM_KEY_FAST_LEAF:
printf("%22s,%12s","Index_Leaf","");
break;
case CM_KEY_SECURITY_SIGNATURE:
printf("%22s,%12s","Key_Security","");
break;
default:
printf("%22s,%12s","Unknown","");
break;
}
printf(",%12x,%8d\n", TmpPMmInfoCmCell->Va, TmpPMmInfoCmCell->Size*-1);
break;
}
case MMINFO_LOG_TYPE_IMAGELOAD:
{
PMMINFO_IMAGELOAD_INFORMATION TmpPMmInfo;
char WsNameBuf[30];
char * WsName = &WsNameBuf[0];
TmpPMmInfo = (PMMINFO_IMAGELOAD_INFORMATION) Info;
Info = TmpPMmInfo + 1;
if (TmpPMmInfo->ProcessId == 0) {
WsName = "System ( 0)";
} else {
ULONG i;
i = TmpPMmInfo->ProcessId;
if (ProcessHash[i].ProcessID == TmpPMmInfo->ProcessId) {
sprintf(WsName, "%16s (%3d)",
ProcessHash[i].ImageFileName,
ProcessHash[i].ProcessID);
}else{
sprintf(WsName, "Process %13u", TmpPMmInfo->ProcessId);
}
}
printf(ImageLoadDataFormat,
TmpPMmInfo->ImageBase,
(ULONG)TmpPMmInfo->ImageBase + TmpPMmInfo->ImageSize,
TmpPMmInfo->ImageSectionNumber,
WsName,
TmpPMmInfo->ImageName
);
break;
}
case MMINFO_LOG_TYPE_SAMPLED_PROFILE:
{
PMMINFO_SAMPLED_PROFILE_INFORMATION TmpPMmInfo;
TmpPMmInfo = (PMMINFO_SAMPLED_PROFILE_INFORMATION) Info;
Info = TmpPMmInfo + 1;
printf(SampledProfileDataFormat,
TmpPMmInfo->InstructionPointer,
TmpPMmInfo->Count
);
break;
}
default:
// fprintf(stderr, "Tag Value %8d\n", Tag.u.Value);
// fprintf(stderr, "TimeStamp %8x %8x\n", TS.upper, TS.lower);
break;
}
}
#else //NTMMPERF
printf("Sorry but this is an internal tool!!!\n");
#endif //NTMMPERF
return 0;
}