790 lines
22 KiB
C
790 lines
22 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1995 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
reducer.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Trace Reducer Tool
|
||
|
|
||
|
Author:
|
||
|
|
||
|
08-Apr-1998 mraghu
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C"{
|
||
|
#endif
|
||
|
|
||
|
#define _UNICODE
|
||
|
#define UNICODE
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <windows.h>
|
||
|
#include <shellapi.h>
|
||
|
#include <tchar.h>
|
||
|
|
||
|
#include "pdhp.h"
|
||
|
|
||
|
#define MAXSTR 1024
|
||
|
#define MAXLOGFILES 16
|
||
|
#define MAX_BUFFER_SIZE 1048576
|
||
|
|
||
|
#if DBG
|
||
|
ULONG ETAAPITestFlag = 1;
|
||
|
|
||
|
VOID
|
||
|
TestETAApis(
|
||
|
PTRACE_BASIC_INFO TraceBasicInfo
|
||
|
);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
void ReducerUsage()
|
||
|
{
|
||
|
printf("Usage: reducer [Options] <EtlFile1 EtlFile2 ...> | [-h | -help | -?]\n");
|
||
|
printf("\t-out <filename> Output file name. Default is Workload.txt\n");
|
||
|
printf("\t-h \n");
|
||
|
printf("\t-help \n");
|
||
|
printf("\t-? Display usage information\n");
|
||
|
|
||
|
// printf("\t-start <time-stamp> Start Time\n");
|
||
|
// printf("\t-end <time-stamp> End Time\n");
|
||
|
// printf("\t <time-stamp> can be found in tracedmp result\n");
|
||
|
// printf("\n");
|
||
|
// printf("\t-base Original reducer report (default report)\n");
|
||
|
// printf("\t-file Hot File Report\n");
|
||
|
// printf("\t-pf page fault report\n");
|
||
|
// printf("\t -summary processes summary of faults per process (default PF report).\n");
|
||
|
// printf("\t modules summary of faults per module.\n");
|
||
|
// printf("\t -process <image name> rundown for specific process.\n");
|
||
|
// printf("\t all\n");
|
||
|
// printf("\t -module <module name> rundown for specific modules.\n");
|
||
|
// printf("\t all\n");
|
||
|
// printf("\t -sort ALL sort by all fault total.\n");
|
||
|
// printf("\t HPF sort by HPF fault total.\n");
|
||
|
// printf("\t TF sort by TF fault total.\n");
|
||
|
// printf("\t DZF sort by DZF fault total.\n");
|
||
|
// printf("\t COW sort by COW fault total.\n");
|
||
|
// printf("\n");
|
||
|
// printf("\tNote: (1) Cannot generate HotFile Report and PageFault Report\n");
|
||
|
// printf("\t at the same time\n");
|
||
|
// printf("\t0x%08X,%d,\n", STATUS_SEVERITY_WARNING, RtlNtStatusToDosError(STATUS_SEVERITY_WARNING));
|
||
|
}
|
||
|
|
||
|
ULONGLONG
|
||
|
ParseTimeString(TCHAR * strTime)
|
||
|
{
|
||
|
#if 0
|
||
|
CHAR lstrTime[25];
|
||
|
PCHAR strYear, strMonth, strDate,
|
||
|
strHour, strMinute, strSecond, strMilliSecond;
|
||
|
LARGE_INTEGER largeTime;
|
||
|
FILETIME localTime, stdTime;
|
||
|
SYSTEMTIME sysTime;
|
||
|
|
||
|
if (strTime == NULL)
|
||
|
return (ULONGLONG) 0;
|
||
|
|
||
|
strcpy(lstrTime, strTime);
|
||
|
|
||
|
strMonth = lstrTime;
|
||
|
for (strDate = strMonth;
|
||
|
*strDate && *strDate >= '0' && *strDate <= '9';
|
||
|
strDate ++);
|
||
|
*strDate = '\0';
|
||
|
strDate ++;
|
||
|
|
||
|
for (strYear = strDate;
|
||
|
*strYear && *strYear >= '0' && *strYear <= '9';
|
||
|
strYear ++);
|
||
|
*strYear = '\0';
|
||
|
strYear ++;
|
||
|
|
||
|
for (strHour = strYear;
|
||
|
*strHour && *strHour >= '0' && *strHour <= '9';
|
||
|
strHour ++);
|
||
|
*strHour = '\0';
|
||
|
strHour ++;
|
||
|
|
||
|
for (strMinute = strHour;
|
||
|
*strMinute && *strMinute >= '0' && *strMinute <= '9';
|
||
|
strMinute ++);
|
||
|
*strMinute = '\0';
|
||
|
strMinute ++;
|
||
|
|
||
|
for (strSecond = strMinute;
|
||
|
*strSecond && *strSecond >= '0' && *strSecond <= '9';
|
||
|
strSecond ++);
|
||
|
*strSecond = '\0';
|
||
|
strSecond ++;
|
||
|
|
||
|
for (strMilliSecond = strSecond;
|
||
|
*strMilliSecond && *strMilliSecond >= '0' && *strMilliSecond <= '9';
|
||
|
strMilliSecond ++);
|
||
|
*strMilliSecond = '\0';
|
||
|
strMilliSecond ++;
|
||
|
|
||
|
sysTime.wYear = atoi(strYear);
|
||
|
sysTime.wMonth = atoi(strMonth);
|
||
|
sysTime.wDay = atoi(strDate);
|
||
|
sysTime.wHour = atoi(strHour);
|
||
|
sysTime.wMinute = atoi(strMinute);
|
||
|
sysTime.wSecond = atoi(strSecond);
|
||
|
sysTime.wMilliseconds = atoi(strMilliSecond);
|
||
|
|
||
|
SystemTimeToFileTime(&sysTime, &localTime);
|
||
|
LocalFileTimeToFileTime(&localTime, &stdTime);
|
||
|
largeTime.HighPart = stdTime.dwHighDateTime;
|
||
|
largeTime.LowPart = stdTime.dwLowDateTime;
|
||
|
return (ULONGLONG) largeTime.QuadPart;
|
||
|
#else
|
||
|
ULONGLONG TimeStamp = 0;
|
||
|
ULONG i = 0;
|
||
|
|
||
|
for (i = 0; strTime[i] != '\0'; i ++)
|
||
|
{
|
||
|
TimeStamp = TimeStamp * 10 + (strTime[i] - '0');
|
||
|
}
|
||
|
|
||
|
return TimeStamp;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
ProcessTrace(
|
||
|
IN ULONG LogFileCount,
|
||
|
IN LPCTSTR * LogFileName,
|
||
|
IN ULONGLONG StartTime,
|
||
|
IN ULONGLONG EndTime,
|
||
|
IN ULONGLONG DSStartTime,
|
||
|
IN ULONGLONG DSEndTime,
|
||
|
IN ULONG MoreFlags,
|
||
|
IN PVOID pUserContext,
|
||
|
IN LPCTSTR pOutFileName
|
||
|
)
|
||
|
{
|
||
|
// Call TraceLib and process it.
|
||
|
//
|
||
|
TRACE_BASIC_INFO TraceBasicInfo;
|
||
|
|
||
|
memset(&TraceBasicInfo, 0, sizeof(TRACE_BASIC_INFO));
|
||
|
TraceBasicInfo.Flags = TRACE_REDUCE | MoreFlags;
|
||
|
TraceBasicInfo.LogFileName = LogFileName;
|
||
|
TraceBasicInfo.LogFileCount = LogFileCount;
|
||
|
TraceBasicInfo.pUserContext = pUserContext;
|
||
|
TraceBasicInfo.StartTime = StartTime;
|
||
|
TraceBasicInfo.EndTime = EndTime;
|
||
|
TraceBasicInfo.DSStartTime = DSStartTime;
|
||
|
TraceBasicInfo.DSEndTime = DSEndTime;
|
||
|
|
||
|
TraceBasicInfo.ProcFileName = pOutFileName;
|
||
|
InitTraceContext(&TraceBasicInfo);
|
||
|
|
||
|
#if DBG
|
||
|
if (ETAAPITestFlag) {
|
||
|
TestETAApis( & TraceBasicInfo );
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
DeinitTraceContext(&TraceBasicInfo);
|
||
|
}
|
||
|
|
||
|
int __cdecl main(int argc ,char * argv[])
|
||
|
{
|
||
|
WCHAR TraceLogFile[MAXSTR];
|
||
|
WCHAR PerfLogFile[MAXSTR];
|
||
|
BOOLEAN bTrace = FALSE;
|
||
|
LPTSTR EvmFile[MAXLOGFILES];
|
||
|
ULONGLONG StartTime = 0, EndTime = 0;
|
||
|
ULONG i;
|
||
|
ULONG LogFileCount = 0;
|
||
|
LPTSTR *targv;
|
||
|
#ifdef UNICODE
|
||
|
LPTSTR *cmdargv;
|
||
|
#endif
|
||
|
|
||
|
ULONG flagsMore = 0;
|
||
|
PVOID pUserContext = NULL;
|
||
|
CPD_USER_CONTEXT_MM UserContextMM;
|
||
|
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
if ((cmdargv = CommandLineToArgvW(
|
||
|
GetCommandLineW(), // pointer to a command-line string
|
||
|
&argc // receives the argument count
|
||
|
)) == NULL)
|
||
|
{
|
||
|
return(GetLastError());
|
||
|
};
|
||
|
targv = cmdargv ;
|
||
|
#else
|
||
|
targv = argv;
|
||
|
#endif
|
||
|
|
||
|
UserContextMM.reportNow = REPORT_SUMMARY_PROCESS;
|
||
|
UserContextMM.sortNow = REPORT_SORT_ALL;
|
||
|
UserContextMM.strImgName = NULL;
|
||
|
memset(&TraceLogFile, 0, sizeof(WCHAR) * MAXSTR);
|
||
|
|
||
|
while (--argc > 0)
|
||
|
{
|
||
|
++targv;
|
||
|
if (**targv == '-' || **targv == '/')
|
||
|
{
|
||
|
** targv = '-';
|
||
|
if (!_tcsicmp(targv[0], _T("-out")))
|
||
|
{
|
||
|
if (argc > 1)
|
||
|
{
|
||
|
TCHAR TempStr[MAXSTR];
|
||
|
|
||
|
_tcscpy(TempStr, targv[1]);
|
||
|
++targv; --argc;
|
||
|
_tfullpath(TraceLogFile, TempStr, MAXSTR);
|
||
|
printf("Setting output file to: '%ws'\n", TraceLogFile);
|
||
|
bTrace = TRUE;
|
||
|
}
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-start")))
|
||
|
{
|
||
|
if (argc > 1)
|
||
|
{
|
||
|
flagsMore |= TRACE_DS_ONLY | TRACE_LOG_REPORT_BASIC;
|
||
|
StartTime = ParseTimeString(targv[1]);
|
||
|
argc --; targv ++;
|
||
|
}
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-end")))
|
||
|
{
|
||
|
if (argc > 1)
|
||
|
{
|
||
|
flagsMore |= TRACE_DS_ONLY | TRACE_LOG_REPORT_BASIC;
|
||
|
EndTime = ParseTimeString(targv[1]);
|
||
|
argc --; targv ++;
|
||
|
}
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-base")))
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_BASIC;
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-spooler")))
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_BASIC;
|
||
|
flagsMore |= TRACE_SPOOLER;
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-total")))
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_TOTALS;
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-file")))
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_FILE;
|
||
|
/* if (argc > 1 && targv[1][0] >= '0' && targv[1][0] <= '9')
|
||
|
{
|
||
|
pUserContext = UlongToPtr(atoi(targv[1]));
|
||
|
argc --; targv ++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pUserContext = UlongToPtr(DEFAULT_FILE_REPORT_SIZE);
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-hpf")))
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_HARDFAULT;
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-pf")))
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_MEMORY;
|
||
|
pUserContext = (PVOID) & UserContextMM;
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-summary")))
|
||
|
{
|
||
|
if (argc > 1)
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_MEMORY;
|
||
|
pUserContext = (PVOID) & UserContextMM;
|
||
|
|
||
|
if (!_tcsicmp(targv[1], _T("processes")))
|
||
|
{
|
||
|
argc --; targv ++;
|
||
|
UserContextMM.reportNow = REPORT_SUMMARY_PROCESS;
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[1], _T("modules")))
|
||
|
{
|
||
|
argc --; targv ++;
|
||
|
UserContextMM.reportNow = REPORT_SUMMARY_MODULE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else if (!_tcsicmp(targv[0], _T("-process")))
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_MEMORY;
|
||
|
pUserContext = (PVOID) & UserContextMM;
|
||
|
UserContextMM.reportNow = REPORT_LIST_PROCESS;
|
||
|
|
||
|
if ((argc > 1) && (targv[1][0] != '-' || targv[1][0] != '/'))
|
||
|
{
|
||
|
if (_tcsicmp(targv[1], _T("all")))
|
||
|
{
|
||
|
UserContextMM.strImgName =
|
||
|
malloc(sizeof(TCHAR) * (_tcslen(targv[1]) + 1));
|
||
|
if (UserContextMM.strImgName)
|
||
|
{
|
||
|
_tcscpy(UserContextMM.strImgName, targv[1]);
|
||
|
}
|
||
|
}
|
||
|
argc --; targv ++;
|
||
|
}
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[0], _T("-module")))
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_MEMORY;
|
||
|
pUserContext = (PVOID) & UserContextMM;
|
||
|
UserContextMM.reportNow = REPORT_LIST_MODULE;
|
||
|
|
||
|
if ((argc > 1) && (targv[1][0] != '-' || targv[1][0] != '/'))
|
||
|
{
|
||
|
if (_tcsicmp(targv[1], _T("all")))
|
||
|
{
|
||
|
UserContextMM.strImgName =
|
||
|
malloc(sizeof(TCHAR) * (_tcslen(targv[1]) + 1));
|
||
|
if (UserContextMM.strImgName)
|
||
|
{
|
||
|
_tcscpy(UserContextMM.strImgName, targv[1]);
|
||
|
}
|
||
|
}
|
||
|
argc --; targv ++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else if (!_tcsicmp(targv[0], _T("-sort")))
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_MEMORY;
|
||
|
pUserContext = (PVOID) & UserContextMM;
|
||
|
|
||
|
if ((argc > 1) && (targv[1][0] != '-' || targv[1][0] != '/'))
|
||
|
{
|
||
|
if (!_tcsicmp(targv[1], _T("hpf")))
|
||
|
{
|
||
|
UserContextMM.sortNow = REPORT_SORT_HPF;
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[1], _T("tf")))
|
||
|
{
|
||
|
UserContextMM.sortNow = REPORT_SORT_TF;
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[1], _T("dzf")))
|
||
|
{
|
||
|
UserContextMM.sortNow = REPORT_SORT_DZF;
|
||
|
}
|
||
|
else if (!_tcsicmp(targv[1], _T("cow")))
|
||
|
{
|
||
|
UserContextMM.sortNow = REPORT_SORT_COW;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UserContextMM.sortNow = REPORT_SORT_ALL;
|
||
|
}
|
||
|
argc --; targv ++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
goto Usage;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LPTSTR pLogFile;
|
||
|
|
||
|
pLogFile = malloc(sizeof(TCHAR) * MAXSTR);
|
||
|
RtlZeroMemory((char *) pLogFile, sizeof(TCHAR) * MAXSTR);
|
||
|
EvmFile[LogFileCount] = pLogFile;
|
||
|
_tcscpy(EvmFile[LogFileCount ++], targv[0]);
|
||
|
bTrace = TRUE;
|
||
|
|
||
|
printf("LogFile %ws\n", (char *) EvmFile[LogFileCount - 1]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (LogFileCount == 0)
|
||
|
{
|
||
|
goto Usage;
|
||
|
}
|
||
|
|
||
|
if (flagsMore == 0)
|
||
|
{
|
||
|
flagsMore |= TRACE_LOG_REPORT_BASIC;
|
||
|
}
|
||
|
|
||
|
if ( (flagsMore & TRACE_LOG_REPORT_MEMORY)
|
||
|
&& (flagsMore & TRACE_LOG_REPORT_FILE))
|
||
|
{
|
||
|
printf("Error: cannot generate HotFile report and PageFault report at the same time.\n");
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
if (bTrace)
|
||
|
{
|
||
|
ProcessTrace(LogFileCount, EvmFile, (ULONGLONG) 0, (ULONGLONG) 0,
|
||
|
StartTime, EndTime, flagsMore, pUserContext, TraceLogFile);
|
||
|
}
|
||
|
|
||
|
for (i=0; i < LogFileCount; i++)
|
||
|
{
|
||
|
free((char*)EvmFile[i]);
|
||
|
}
|
||
|
|
||
|
if (UserContextMM.strImgName)
|
||
|
{
|
||
|
free(UserContextMM.strImgName);
|
||
|
}
|
||
|
|
||
|
Cleanup:
|
||
|
#ifdef UNICODE
|
||
|
GlobalFree(cmdargv);
|
||
|
#endif
|
||
|
return 0;
|
||
|
|
||
|
Usage:
|
||
|
ReducerUsage();
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
|
||
|
#if DBG
|
||
|
|
||
|
VOID
|
||
|
PrintHeader(
|
||
|
FILE* f,
|
||
|
TRACEINFOCLASS CurrentClass,
|
||
|
TRACEINFOCLASS RootClass,
|
||
|
BOOLEAN bDrillDown,
|
||
|
LPCWSTR InstanceName
|
||
|
)
|
||
|
{
|
||
|
|
||
|
|
||
|
if (bDrillDown) {
|
||
|
fprintf(f, "-------------------------------------------\n");
|
||
|
fprintf(f, "RootClass: %d Instance %ws\n", RootClass, InstanceName);
|
||
|
fprintf(f, "-------------------------------------------\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
switch(CurrentClass) {
|
||
|
|
||
|
case TraceProcessInformation:
|
||
|
|
||
|
fprintf(f, "Trace Process Information\n");
|
||
|
fprintf(f, "------------------------\n");
|
||
|
fprintf(f, "\nPID Name Image UCpu KCpu ReadIO WriteIO\n\n");
|
||
|
break;
|
||
|
|
||
|
case TraceDiskInformation:
|
||
|
fprintf(f, "Trace Disk Information\n");
|
||
|
fprintf(f, "----------------------\n");
|
||
|
fprintf(f, "\nDiskId Name ReadIO WriteIO\n\n");
|
||
|
break;
|
||
|
|
||
|
case TraceThreadInformation:
|
||
|
fprintf(f, "Trace Thread Information\n");
|
||
|
fprintf(f, "------------------------\n");
|
||
|
fprintf(f, "\nTID PID UCpu KCpu ReadIO WriteIO \n\n");
|
||
|
break;
|
||
|
case TraceFileInformation:
|
||
|
fprintf(f, "Trace File Information\n");
|
||
|
fprintf(f, "------------------------\n");
|
||
|
fprintf(f, "\nFileName ReadIO WriteIO \n\n");
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
PrintProcessInfo(
|
||
|
FILE* f,
|
||
|
PTRACE_PROCESS_INFO pProcessInfo
|
||
|
)
|
||
|
{
|
||
|
fprintf(f, "%4d %-10ws %-10ws %5d %5d %5d %5d\n",
|
||
|
pProcessInfo->PID,
|
||
|
pProcessInfo->UserName,
|
||
|
pProcessInfo->ImageName,
|
||
|
pProcessInfo->UserCPU,
|
||
|
pProcessInfo->KernelCPU,
|
||
|
pProcessInfo->ReadCount,
|
||
|
pProcessInfo->WriteCount);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
PrintThreadInfo(
|
||
|
FILE* f,
|
||
|
PTRACE_THREAD_INFO pThreadInfo
|
||
|
)
|
||
|
{
|
||
|
fprintf(f, "%4x \n", pThreadInfo->ThreadId);
|
||
|
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
PrintDiskInfo(
|
||
|
FILE* f,
|
||
|
PTRACE_DISK_INFO pDiskInfo
|
||
|
)
|
||
|
{
|
||
|
fprintf(f, "%d %-10ws %5d %5d \n",
|
||
|
pDiskInfo->DiskNumber,
|
||
|
pDiskInfo->DiskName,
|
||
|
pDiskInfo->ReadCount,
|
||
|
pDiskInfo->WriteCount);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
PrintFileInfo(
|
||
|
FILE* f,
|
||
|
PTRACE_FILE_INFO pFileInfo
|
||
|
)
|
||
|
{
|
||
|
fprintf(f, "%ws %5d %5d\n",
|
||
|
pFileInfo->FileName,
|
||
|
pFileInfo->ReadCount,
|
||
|
pFileInfo->WriteCount
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
TestETAApis(
|
||
|
PTRACE_BASIC_INFO TraceBasicInfo
|
||
|
)
|
||
|
{
|
||
|
ULONG Status;
|
||
|
ULONG OutLength;
|
||
|
PTRACE_PROCESS_INFO pProcessInfo;
|
||
|
PTRACE_DISK_INFO pDiskInfo;
|
||
|
PTRACE_FILE_INFO pFileInfo;
|
||
|
PTRACE_THREAD_INFO pThreadInfo;
|
||
|
char* LargeBuffer1;
|
||
|
ULONG CurrentBufferSize;
|
||
|
BOOLEAN Done, FinshPrinting, bDrillDown;
|
||
|
TRACEINFOCLASS CurrentClass, RootClass;
|
||
|
ULONG TotalOffset;
|
||
|
FILE* f;
|
||
|
int i = 0;
|
||
|
LPWSTR InstanceName;
|
||
|
WCHAR Name[MAXSTR+1];
|
||
|
|
||
|
InstanceName = (LPWSTR)&Name;
|
||
|
|
||
|
LargeBuffer1 = VirtualAlloc(NULL,
|
||
|
MAX_BUFFER_SIZE,
|
||
|
MEM_RESERVE,
|
||
|
PAGE_READWRITE);
|
||
|
|
||
|
if (LargeBuffer1 == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
CurrentBufferSize = 10*8192;
|
||
|
|
||
|
if (VirtualAlloc(LargeBuffer1,
|
||
|
81920,
|
||
|
MEM_COMMIT,
|
||
|
PAGE_READWRITE) == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
f = _wfopen(L"TraceAPI.rpt", L"w");
|
||
|
|
||
|
if (f == NULL) {
|
||
|
VirtualFree(LargeBuffer1, 0, MEM_RELEASE);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CurrentClass = TraceProcessInformation;
|
||
|
RootClass = TraceProcessInformation;
|
||
|
Done = FALSE;
|
||
|
bDrillDown = FALSE;
|
||
|
|
||
|
while (!Done) {
|
||
|
|
||
|
Retry1:
|
||
|
if (!bDrillDown) {
|
||
|
|
||
|
Status = TraceQueryAllInstances(
|
||
|
CurrentClass,
|
||
|
LargeBuffer1,
|
||
|
CurrentBufferSize,
|
||
|
&OutLength);
|
||
|
}
|
||
|
else {
|
||
|
Status = TraceDrillDown(
|
||
|
RootClass,
|
||
|
InstanceName,
|
||
|
CurrentClass,
|
||
|
LargeBuffer1,
|
||
|
CurrentBufferSize,
|
||
|
&OutLength
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (Status == ERROR_MORE_DATA) {
|
||
|
CurrentBufferSize += OutLength;
|
||
|
if (VirtualAlloc(LargeBuffer1,
|
||
|
CurrentBufferSize,
|
||
|
MEM_COMMIT,
|
||
|
PAGE_READWRITE) == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
goto Retry1;
|
||
|
}
|
||
|
|
||
|
if (Status != ERROR_SUCCESS) {
|
||
|
Done = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Print Header
|
||
|
//
|
||
|
PrintHeader(f, CurrentClass, RootClass, bDrillDown, InstanceName);
|
||
|
|
||
|
//
|
||
|
// Walk the Process List and Print report.
|
||
|
//
|
||
|
|
||
|
TotalOffset = 0;
|
||
|
pProcessInfo = (TRACE_PROCESS_INFO *) LargeBuffer1;
|
||
|
pThreadInfo = (TRACE_THREAD_INFO *) LargeBuffer1;
|
||
|
pFileInfo = (TRACE_FILE_INFO *) LargeBuffer1;
|
||
|
pDiskInfo = (TRACE_DISK_INFO *) LargeBuffer1;
|
||
|
|
||
|
FinshPrinting = FALSE;
|
||
|
while (!FinshPrinting) {
|
||
|
|
||
|
switch(CurrentClass) {
|
||
|
case TraceProcessInformation:
|
||
|
|
||
|
PrintProcessInfo(f, pProcessInfo);
|
||
|
if (pProcessInfo->NextEntryOffset == 0) {
|
||
|
FinshPrinting = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
TotalOffset += pProcessInfo->NextEntryOffset;
|
||
|
pProcessInfo = (TRACE_PROCESS_INFO *)
|
||
|
&LargeBuffer1[TotalOffset];
|
||
|
break;
|
||
|
case TraceDiskInformation:
|
||
|
PrintDiskInfo(f, pDiskInfo);
|
||
|
if (pDiskInfo->NextEntryOffset == 0) {
|
||
|
FinshPrinting = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
TotalOffset += pDiskInfo->NextEntryOffset;
|
||
|
pDiskInfo = (TRACE_DISK_INFO *)
|
||
|
&LargeBuffer1[TotalOffset];
|
||
|
default:
|
||
|
FinshPrinting = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (TotalOffset == 0)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (!bDrillDown) {
|
||
|
switch(CurrentClass) {
|
||
|
|
||
|
case TraceProcessInformation:
|
||
|
CurrentClass = TraceDiskInformation;
|
||
|
break;
|
||
|
case TraceThreadInformation:
|
||
|
CurrentClass = TraceDiskInformation;
|
||
|
break;
|
||
|
case TraceDiskInformation:
|
||
|
RootClass = TraceProcessInformation;
|
||
|
CurrentClass = TraceProcessInformation;
|
||
|
bDrillDown = TRUE;
|
||
|
break;
|
||
|
|
||
|
case TraceFileInformation:
|
||
|
Done = TRUE;
|
||
|
break;
|
||
|
default:
|
||
|
Done = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if (bDrillDown) {
|
||
|
switch(RootClass) {
|
||
|
case TraceProcessInformation:
|
||
|
wcscpy(InstanceName, L"\\\\NTDEV\\mraghu");
|
||
|
if (CurrentClass == TraceProcessInformation) {
|
||
|
CurrentClass = TraceFileInformation;
|
||
|
}
|
||
|
else if (CurrentClass == TraceFileInformation) {
|
||
|
CurrentClass = TraceDiskInformation;
|
||
|
}
|
||
|
else {
|
||
|
RootClass = TraceDiskInformation;
|
||
|
CurrentClass = TraceProcessInformation;
|
||
|
wcscpy (InstanceName, L"Disk1");
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case TraceDiskInformation:
|
||
|
if (CurrentClass == TraceProcessInformation) {
|
||
|
CurrentClass = TraceFileInformation;
|
||
|
wcscpy (InstanceName, L"Disk1");
|
||
|
}
|
||
|
else {
|
||
|
Done = TRUE;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
case TraceFileInformation:
|
||
|
|
||
|
|
||
|
default:
|
||
|
Done = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fclose (f);
|
||
|
|
||
|
VirtualFree(LargeBuffer1, 0, MEM_RELEASE);
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|