/*++ 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 #include #include #include #include #include #include #include #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; }