Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

3649 lines
125 KiB

//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
// Copyright (c) 2002 OSR Open Systems Resources, Inc.
//
// TraceView.cpp : Defines the class behaviors for the application.
//////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <tchar.h>
#include <wmistr.h>
#include <initguid.h>
#include <objbase.h>
#include <io.h>
#include <new.h>
#include <fcntl.h>
extern "C" {
#include <evntrace.h>
}
#include <traceprt.h>
#include <guiddef.h>
#include <wmiguid.h>
#include <iostream.h>
#include <ios>
#include <conio.h>
#include "TraceView.h"
#include "DockDialogBar.h"
#include "LogSession.h"
#include "DisplayDlg.h"
#include "ListCtrlEx.h"
#include "LogSessionDlg.h"
#include "MainFrm.h"
#include "htmlhelp.h"
#include "utils.h"
extern "C" {
#ifdef UNICODE
typedef
ULONG
(*PFLUSH_TRACE_FUNC)(
IN TRACEHANDLE TraceHandle,
IN LPCWSTR InstanceName,
IN OUT PEVENT_TRACE_PROPERTIES Properties
);
#else
typedef
ULONG
(*PFLUSH_TRACE_FUNC)(
IN TRACEHANDLE TraceHandle,
IN LPCSTR InstanceName,
IN OUT PEVENT_TRACE_PROPERTIES Properties
);
#endif
typedef
ULONG
(*PENUMERATE_TRACE_GUIDS_FUNC)(
IN OUT PTRACE_GUID_PROPERTIES *GuidPropertiesArray,
IN ULONG PropertyArrayCount,
OUT PULONG GuidCount
);
PENUMERATE_TRACE_GUIDS_FUNC EnumerateTraceGuidsFunction = NULL;
PFLUSH_TRACE_FUNC FlushTraceFunction = NULL;
}
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//
// Global to this module
//
HINSTANCE advapidll=NULL;
// CTraceViewApp
BEGIN_MESSAGE_MAP(CTraceViewApp, CWinApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
ON_COMMAND(ID_HELP_HELPTOPICS, OnHelpHelpTopics)
ON_COMMAND(ID_HELP, OnHelpHelpTopics)
END_MESSAGE_MAP()
// CTraceViewApp construction
CTraceViewApp::CTraceViewApp()
{
m_globalLoggerStartValue = 0;
}
CTraceViewApp::~CTraceViewApp()
{
}
// The one and only CTraceViewApp object
CTraceViewApp theApp;
// CTraceViewApp initialization
BOOL CTraceViewApp::InitInstance()
{
ULONG length;
CString temp;
GUID directoryGuid;
CString str;
STARTUPINFO startupInfo;
//
// Get the temp directory and save it
//
length = GetTempPath(0, NULL);
m_traceDirectory.GetBuffer(MAX_PATH);
if(length < GetTempPath(length, (LPTSTR)(LPCTSTR)m_traceDirectory)) {
AfxMessageBox(_T("Failed To Create Temp Directory\nApplication Will Exit"));
return FALSE;
}
//
// make sure the directory exists
//
CreateDirectory(m_traceDirectory, NULL);
//
// I have to do this cast here
// to get the string to allocate a new buffer
// or the += operation below overwrites the
// existing buffer??
//
m_traceDirectory = (LPCTSTR)m_traceDirectory;
//
// create our own unique directory under the temp directory
//
if(S_OK != CoCreateGuid(&directoryGuid)) {
AfxMessageBox(_T("Failed To Create Temp Directory\nApplication Will Exit"));
return FALSE;
}
GuidToString(directoryGuid, temp);
m_traceDirectory += (LPCTSTR)temp;
m_traceDirectory += (LPCTSTR)_T("\\");
if(!CreateDirectory(m_traceDirectory, NULL) && (GetLastError() != ERROR_ALREADY_EXISTS)) {
AfxMessageBox(_T("Failed To Create Temp Directory\nApplication Will Exit"));
return FALSE;
}
//
// Initialize the trace block ready array mutex
//
m_hTraceBlockMutex = CreateMutex(NULL,TRUE,NULL);
if(m_hTraceBlockMutex == NULL) {
DWORD error = GetLastError();
str.Format(_T("CreateMutex Error %d %x"),error,error);
AfxMessageBox(str);
return FALSE;
}
ReleaseMutex(m_hTraceBlockMutex);
advapidll = LoadLibrary(_T("advapi32.dll"));
if (advapidll != NULL) {
#ifdef UNICODE
FlushTraceFunction = (PFLUSH_TRACE_FUNC)GetProcAddress(advapidll, "FlushTraceW");
#else
FlushTraceFunction = GetProcAddress(advapidll, "FlushTraceA");
#endif
EnumerateTraceGuidsFunction = (PENUMERATE_TRACE_GUIDS_FUNC)GetProcAddress(advapidll, "EnumerateTraceGuids");
}
//
// Determine if this is a command line instance or a GUI instance
//
if(__argc > 1) {
//
// Hook up stdout, stdin, and stderr
//
InitializeConsole();
CommandLine();
return FALSE;
}
//
// InitCommonControls() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
//
InitCommonControls();
CWinApp::InitInstance();
//
// Initialize OLE libraries
//
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
//
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
//
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
//
// To create the main window, this code creates a new frame window
// object and then sets it as the application's main window object
//
CMainFrame* pFrame = new CMainFrame;
m_pMainWnd = pFrame;
//
// create and load the frame with its resources
//
if (!pFrame->LoadFrame(IDR_MAINFRAME)) {
return FALSE;
}
//
// The one and only window has been initialized, so show and update it
//
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
//
// Set the icon
//
AfxGetMainWnd()->SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE);
//
// call DragAcceptFiles only if there's a suffix
// In an SDI app, this should occur after ProcessShellCommand
//
return TRUE;
}
int CTraceViewApp::ExitInstance()
{
CTraceMessage *pTraceMessage = NULL;
LONG itemCount;
//
// Free the library we loaded earlier
//
FreeLibrary(advapidll);
//
// Free the trace block array
//
//
// Get the free array protection
//
WaitForSingleObject(m_hTraceBlockMutex, INFINITE);
itemCount = m_traceBlockArray.GetSize();
ASSERT(itemCount == 0);
for(LONG ii = 0; ii < itemCount; ii++) {
//
// delete the next entry in the list
//
delete m_traceBlockArray.GetAt(ii);
}
m_traceBlockArray.RemoveAll();
//
// Release the free array protection
//
ReleaseMutex(m_hTraceBlockMutex);
//
// Remove our temporary directory
//
if(!m_traceDirectory.IsEmpty()) {
RemoveDirectory(m_traceDirectory);
}
return CWinApp::ExitInstance();
}
BOOL CTraceViewApp::InitializeConsole()
{
BOOL connected = FALSE;
TCHAR outputPipeName[256];
TCHAR inputPipeName[256];
TCHAR errorPipeName[256];
//
// Initialize our console creation flag
//
m_bCreatedConsole = FALSE;
//
// construct named pipe names
//
_stprintf(outputPipeName,
_T("\\\\.\\pipe\\%dcout"),
GetCurrentProcessId());
_stprintf(inputPipeName,
_T("\\\\.\\pipe\\%dcin"),
GetCurrentProcessId() );
_stprintf(errorPipeName,
_T("\\\\.\\pipe\\%dcerr"),
GetCurrentProcessId() );
//
// attach named pipes to stdin/stdout/stderr
//
connected = (_tfreopen( outputPipeName, _T("a"), stdout ) != NULL) &&
(_tfreopen( inputPipeName, _T("r"), stdin ) != NULL) &&
(_tfreopen( errorPipeName, _T("a"), stderr ) != NULL);
//
// if unsuccessful, i.e. no console was available
// we need to create a new console
//
if (!connected) {
connected = AllocConsole();
if (connected) {
connected = (_tfreopen( _T("CONOUT$"), _T("a"), stdout ) != NULL) &&
(_tfreopen( _T("CONIN$"), _T("r"), stdin ) != NULL) &&
(_tfreopen( _T("CONERR$"), _T("a"), stderr ) != NULL);
//
// Indicate that we created a new console
//
m_bCreatedConsole = TRUE;
}
}
//
// synchronize iostreams with standard io
//
if(connected) {
std::ios_base::sync_with_stdio();
}
return connected;
}
LONG CTraceViewApp::CommandLine()
{
CString str;
LONG argc = __argc;
LPTSTR loggerName;
LONG sizeNeeded;
LONG status = ERROR_INVALID_PARAMETER;
//
// dump all arguments
//
//for(LONG ii = 0; ii < argc; ii++) {
// str.Format(_T("%ls"), __wargv[ii]);
// AfxMessageBox(str);
//}
//AfxMessageBox(m_lpCmdLine);
//
// Initialize structure first
//
sizeNeeded = sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAX_STR_LENGTH * sizeof(TCHAR);
sizeNeeded += MAX_ENABLE_FLAGS * sizeof(ULONG); // for extension enable flags
m_pLoggerInfo = (PEVENT_TRACE_PROPERTIES) new char[sizeNeeded];
if (m_pLoggerInfo == NULL) {
return (ERROR_OUTOFMEMORY);
}
RtlZeroMemory(m_pLoggerInfo, sizeNeeded);
m_pLoggerInfo->Wnode.BufferSize = sizeNeeded;
m_pLoggerInfo->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
m_pLoggerInfo->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
m_pLoggerInfo->LogFileNameOffset = m_pLoggerInfo->LoggerNameOffset + (MAX_STR_LENGTH * sizeof(TCHAR));
loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
_tcscpy(loggerName, KERNEL_LOGGER_NAME);
if(!_tcscmp(__wargv[1], _T("-start") )) {
status = StartSession();
}
if(!_tcscmp(__wargv[1], _T("-stop") )) {
status = StopSession();
}
if(!_tcscmp(__wargv[1], _T("-update") )) {
status = UpdateActiveSession();
}
if(!_tcscmp(__wargv[1], _T("-enable") )) {
status = EnableProvider(TRUE);
}
if(!_tcscmp(__wargv[1], _T("-disable") )) {
status = EnableProvider(FALSE);
}
if(!_tcscmp(__wargv[1], _T("-flush") )) {
status = FlushActiveBuffers();
}
if(!_tcscmp(__wargv[1], _T("-enumguid") )) {
status = EnumerateRegisteredGuids();
}
if(!_tcscmp(__wargv[1], _T("-q") )) {
status = QueryActiveSession();
}
if(!_tcscmp(__wargv[1], _T("-l") )) {
status = ListActiveSessions(FALSE);
}
if(!_tcscmp(__wargv[1], _T("-x") )) {
status = ListActiveSessions(TRUE);
}
if(!_tcscmp(__wargv[1], _T("-process") )) {
status = ConsumeTraceEvents();
}
if(!_tcscmp(__wargv[1], _T("-parsepdb") )) {
status = ExtractPdbInfo();
}
if(status == ERROR_INVALID_PARAMETER) {
DisplayHelp();
}
if(m_bCreatedConsole) {
//
// Prompt user for input so that the console doesn't
// disappear before the user sees what it displays
//
_tprintf(_T("\n\nPress any key to exit\n"));
_getch();
}
return status;
}
LONG CTraceViewApp::StartSession()
{
CString str;
LPTSTR loggerName = NULL;
LPTSTR logFileName;
LONG start = 2;
LONG status;
TRACEHANDLE loggerHandle = 0;
CString guidFile;
CString pdbFile;
CString tmcPath;
GUID guid;
LONG guidCount = 0;
ULONG enableFlags = 0;
ULONG traceLevel = 0;
ULONG specialLogger = 0;
USHORT numberOfFlags = 0;
USHORT offset;
PTRACE_ENABLE_FLAG_EXTENSION flagExt;
PULONG pFlags = NULL;
LONG i;
CFileFind fileFind;
TCHAR drive[10];
TCHAR path[MAXSTR];
TCHAR file[MAXSTR];
TCHAR ext[MAXSTR];
pFlags = &m_pLoggerInfo->EnableFlags;
loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
logFileName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LogFileNameOffset);
if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
_tcscpy(loggerName, __wargv[2]);
start = 3;
}
for(LONG ii = start; ii < __argc; ii++) {
//
// Set the buffer size
//
if(!_tcscmp(__wargv[ii], _T("-b"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->BufferSize = _ttoi(__wargv[ii + 1]);
/*BUGBUG
if (kdOn && m_pLoggerInfo->BufferSize > 3) {
_tprintf(_T("Kernel Debugging has been enabled: Buffer size has been set to 3kBytes\n"));
m_pLoggerInfo->BufferSize = 3;
}
*/
ii++;
}
}
}
//
// Set the minimum number of buffers
//
if(!_tcscmp(__wargv[ii], _T("-min"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->MinimumBuffers = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the maximum number of buffers
//
if(!_tcscmp(__wargv[ii], _T("-max"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->MaximumBuffers = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the log file name
//
if(!_tcscmp(__wargv[ii], _T("-f"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
_tfullpath(logFileName, __wargv[ii + 1], MAX_STR_LENGTH);
ii++;
}
}
}
//
// Set the log file append setting
//
if(!_tcscmp(__wargv[ii], _T("-append"))) {
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_APPEND;
}
//
// Set the preallocate setting
//
if(!_tcscmp(__wargv[ii], _T("-prealloc"))) {
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_PREALLOCATE;
}
//
// Set the sequential log file setting
//
if(!_tcscmp(__wargv[ii], _T("-seq"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_SEQUENTIAL;
m_pLoggerInfo->MaximumFileSize = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the sequential log file setting
//
if(!_tcscmp(__wargv[ii], _T("-cir"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_CIRCULAR;
m_pLoggerInfo->MaximumFileSize = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the new log file size setting
//
if(!_tcscmp(__wargv[ii], _T("-newfile"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_FILE_MODE_NEWFILE;
m_pLoggerInfo->MaximumFileSize = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the flush time setting
//
if(!_tcscmp(__wargv[ii], _T("-ft"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->FlushTimer = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the paged setting
//
if(!_tcscmp(__wargv[ii], _T("-paged"))) {
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_USE_PAGED_MEMORY;
}
//
// Get the control guid(s)
//
if(!_tcscmp(__wargv[ii], _T("-guid"))) {
if((ii + 1) < __argc) {
if(__wargv[ii + 1][0] == _T('#')) {
m_guidArray.Add(__wargv[ii + 1][1]);
guidCount++;
} else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
_tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
// _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
guidCount += GetGuids(guidFile);
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
}
ii++;
}
}
//
// Get the control guid(s) from a PDB file
//
if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
if(((ii + 1) < __argc) &&
((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
_tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
pdbFile = (LPCTSTR)pdbFile;
ParsePdb(pdbFile, m_traceDirectory, TRUE);
_tprintf(_T("\n\n"));
tmcPath = (LPCTSTR)m_traceDirectory;
tmcPath +=_T("\\*.tmc");
if(!fileFind.FindFile(tmcPath)) {
_tprintf(_T("Failed To Get Control GUID From PDB"));
return ERROR_INVALID_PARAMETER;
}
while(fileFind.FindNextFile()) {
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
}
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
ii++;
}
}
//
// Check for real-time setting
//
if(!_tcscmp(__wargv[ii], _T("-rt"))) {
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
//
// Did the user specify buffering only?
//
if ((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
if (__wargv[ii + 1][0] == 'b')
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_BUFFERING_MODE;
ii++;
}
}
}
//
// Set the debug output setting
//
if(!_tcscmp(__wargv[ii], _T("-kd"))) {
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_KD_FILTER_MODE;
m_pLoggerInfo->BufferSize = 3;
}
//
// Set the age (decay time) setting
//
if(!_tcscmp(__wargv[ii], _T("-age"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->AgeLimit = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the level
//
if(!_tcscmp(__wargv[ii], _T("-level"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
traceLevel = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the flags
//
if((!_tcscmp(__wargv[ii], _T("-flag"))) || (!_tcscmp(__wargv[ii], _T("-flags")))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
//
// Get the flags specified, convert from hex if necessary
//
if(__wargv[ii + 1][1] == _T('x') || __wargv[ii + 1][1] == _T('X')) {
m_pLoggerInfo->EnableFlags |= ahextoi(__wargv[ii + 1]);
} else {
m_pLoggerInfo->EnableFlags |= _ttoi(__wargv[ii + 1]);
}
//
// Copy flags for EnableTrace
//
enableFlags = m_pLoggerInfo->EnableFlags;
//
// Do not accept flags with MSB = 1.
//
if (0x80000000 & m_pLoggerInfo->EnableFlags) {
_tprintf(_T("Invalid Flags: 0x%0X(%d.)\n"),
m_pLoggerInfo->EnableFlags, m_pLoggerInfo->EnableFlags);
status = ERROR_INVALID_PARAMETER;
return status;
}
ii++;
}
}
}
//
// Set the eflags
//
if(!_tcscmp(__wargv[ii], _T("-eflag"))) {
if((ii + 2) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
numberOfFlags = (USHORT)_ttoi(__wargv[ii + 1]);
ii++;
if((numberOfFlags > MAX_ENABLE_FLAGS) || (numberOfFlags < 1)) {
_tprintf(_T("Error: Invalid number of enable flags\n"));
status = ERROR_INVALID_PARAMETER;
return status;
}
offset = (USHORT) sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAX_STR_LENGTH * sizeof(TCHAR);
m_pLoggerInfo->EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
flagExt = (PTRACE_ENABLE_FLAG_EXTENSION)
&m_pLoggerInfo->EnableFlags;
flagExt->Offset = offset;
flagExt->Length = (UCHAR)numberOfFlags;
pFlags = (PULONG)(offset + (PCHAR) m_pLoggerInfo);
for (i = 0; ((i < numberOfFlags) && ((ii + 1) < __argc)); i++) {
if ((__wargv[ii + 1][0] == '-') || (__wargv[ii + 1][0] == '/')) {
//
// Correct the number of eflags when the user
// types an incorrect number.
// However, this does not work if the next
// argument is Logger Name.
//
break;
}
pFlags[i] = ahextoi(__wargv[ii + 1]);
ii++;
// _tprintf(_T("Setting logger flags to 0x%0X(%d.)\n"),
// pFlags[i], pFlags[i] );
}
numberOfFlags = (USHORT)i;
for ( ; i < MAX_ENABLE_FLAGS; i++) {
pFlags[i] = 0;
}
if (flagExt->Length != (UCHAR)numberOfFlags) {
// _tprintf(_T("Correcting the number of eflags to %d\n"), i),
flagExt->Length = (UCHAR)numberOfFlags;
}
}
}
}
}
/*
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
if (GuidCount != 1) {
_tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
return ERROR_INVALID_PARAMETER;
}
m_pLoggerInfo->Wnode.Guid = *GuidArray[0];
}
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_PREALLOCATE &&
m_pLoggerInfo->MaximumFileSize == 0) {
_tprintf(_T("Need file size for preallocated log file\n"));
return ERROR_INVALID_PARAMETER;
}
// end_sdk
if (specialLogger == 3) { // Global Logger
status = SetGlobalLoggerSettings(1L, m_pLoggerInfo, m_pLoggerInfo->Wnode.ClientContext);
if (status != ERROR_SUCCESS)
break;
status = GetGlobalLoggerSettings(m_pLoggerInfo, &m_pLoggerInfo->Wnode.ClientContext, &m_globalLoggerStartValue);
break;
}
// begin_sdk
if(m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_EXTENSION){
if(IsEqualGUID(&CritSecGuid,GuidArray[0]) ||
IsEqualGUID(&HeapGuid,GuidArray[0])){
m_pLoggerInfo->Wnode.HistoricalContext = traceLevel;
}
}
*/
if (!_tcscmp(loggerName, _T("NT Kernel Logger"))) {
if (pFlags == &m_pLoggerInfo->EnableFlags) {
*pFlags |= EVENT_TRACE_FLAG_PROCESS;
*pFlags |= EVENT_TRACE_FLAG_THREAD;
*pFlags |= EVENT_TRACE_FLAG_DISK_IO;
*pFlags |= EVENT_TRACE_FLAG_NETWORK_TCPIP;
}
m_pLoggerInfo->Wnode.Guid = SystemTraceControlGuid; // defaults to OS
}
//
// Set the default log file name if necessary
//
if(!(m_pLoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE)) {
_tcscpy(logFileName, _T("C:\\LogFile.Etl"));
}
status = StartTrace(&loggerHandle, loggerName, m_pLoggerInfo);
if (status != ERROR_SUCCESS) {
_tprintf(_T("Could not start logger: %s\n")
_T("Operation Status: %uL\n"),
loggerName,
status);
} else {
_tprintf(_T("Logger Started...\n"));
}
PrintLoggerStatus(status);
if((guidCount > 0) && (specialLogger == 0)) {
_tprintf(_T("Enabling trace to logger %d\n"), loggerHandle);
for(ULONG ii = 0; ii < (ULONG)guidCount; ii++) {
//
// Convert the guid string to a guid
//
StringToGuid(m_guidArray[ii].GetBuffer(0), &guid);
//
// Enable the provider
//
status = EnableTrace (
TRUE,
enableFlags,
traceLevel,
&guid,
loggerHandle);
//
// If the Guid can not be enabled, it is a benign
// failure. Print Warning message and continue.
//
if (status == 4317) {
_tprintf(_T("WARNING: Could not enable some guids.\n"));
_tprintf(_T("Check your Guids file\n"));
status = ERROR_SUCCESS;
}
if (status != ERROR_SUCCESS) {
_tprintf(_T("ERROR: Failed to enable Guid [%d]...\n"), ii);
_tprintf(_T("Operation Status: %uL\n"), status);
_tprintf(_T("%s\n"),DecodeStatus(status));
break;
}
}
} else if (guidCount > 0) {
_tprintf(_T("ERROR: System Logger does not accept application guids...\n"));
status = ERROR_INVALID_PARAMETER;
}
return status;
}
LONG CTraceViewApp::StopSession()
{
TRACEHANDLE loggerHandle = 0;
LPTSTR loggerName = NULL;
LONG start = 2;
LONG guidCount = 0;
CString guidFile;
GUID guid;
LONG status;
CString pdbFile;
CString tmcPath;
CFileFind fileFind;
TCHAR drive[10];
TCHAR path[MAXSTR];
TCHAR file[MAXSTR];
TCHAR ext[MAXSTR];
//
// Get the logger name string
//
loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
_tcscpy(loggerName, __wargv[2]);
start = 3;
}
for(LONG ii = start; ii < __argc; ii++) {
//
// Get the control guid(s)
//
if(!_tcscmp(__wargv[ii], _T("-guid"))) {
if((ii + 1) < __argc) {
if(__wargv[ii + 1][0] == _T('#')) {
m_guidArray.Add(__wargv[ii + 1][1]);
guidCount++;
} else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
_tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
// _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
guidCount += GetGuids(guidFile);
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
}
ii++;
}
}
//
// Get the control guid(s) from a PDB file
//
if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
if(((ii + 1) < __argc) &&
((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
_tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
pdbFile = (LPCTSTR)pdbFile;
ParsePdb(pdbFile, m_traceDirectory, TRUE);
_tprintf(_T("\n\n"));
tmcPath = (LPCTSTR)m_traceDirectory;
tmcPath +=_T("\\*.tmc");
if(!fileFind.FindFile(tmcPath)) {
_tprintf(_T("Failed To Get Control GUID From PDB"));
return ERROR_INVALID_PARAMETER;
}
while(fileFind.FindNextFile()) {
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
}
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
ii++;
}
}
}
/*
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
if (guidCount != 1) {
_tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
Status = ERROR_INVALID_PARAMETER;
break;
}
pLoggerInfo->Wnode.Guid = *m_guidArray[0];
}
if (specialLogger == 3)
Status = GetGlobalLoggerSettings(pLoggerInfo, &pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
*/
if(guidCount > 0) {
/*
if (pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
Status = ControlTrace(loggerHandle, LoggerName, pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
if (Status != ERROR_SUCCESS)
break;
loggerHandle = pLoggerInfo->Wnode.HistoricalContext;
Status = EnableTrace( FALSE,
EVENT_TRACE_PRIVATE_LOGGER_MODE,
0,
m_guidArray[0],
loggerHandle );
}
else {
*/
status = ControlTrace(loggerHandle,
loggerName,
m_pLoggerInfo,
EVENT_TRACE_CONTROL_QUERY);
if(status == ERROR_WMI_INSTANCE_NOT_FOUND) {
return status;
}
loggerHandle = m_pLoggerInfo->Wnode.HistoricalContext;
for(ULONG i = 0; i < (ULONG)guidCount; i++) {
//
// Convert the string to a GUID
//
StringToGuid(m_guidArray[i].GetBuffer(0), &guid);
EnableTrace(FALSE,
0,
0,
&guid,
loggerHandle);
}
// }
}
status = ControlTrace(loggerHandle,
loggerName,
m_pLoggerInfo,
EVENT_TRACE_CONTROL_STOP);
PrintLoggerStatus(status);
return status;
}
LONG CTraceViewApp::ListActiveSessions(BOOL bKill)
{
ULONG returnCount ;
ULONG listSizeNeeded;
PEVENT_TRACE_PROPERTIES pListLoggerInfo[MAX_LOG_SESSIONS];
PEVENT_TRACE_PROPERTIES pStorage;
PVOID storage;
LONG status;
TRACEHANDLE loggerHandle = 0;
listSizeNeeded = MAX_LOG_SESSIONS * (sizeof(EVENT_TRACE_PROPERTIES)
+ 2 * MAX_STR_LENGTH * sizeof(TCHAR));
storage = malloc(listSizeNeeded);
if (storage == NULL) {
status = ERROR_OUTOFMEMORY;
return status;
}
RtlZeroMemory(storage, listSizeNeeded);
pStorage = (PEVENT_TRACE_PROPERTIES)storage;
for (ULONG i = 0; i < MAX_LOG_SESSIONS; i++) {
pStorage->Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES)
+ 2 * MAX_STR_LENGTH * sizeof(TCHAR);
pStorage->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES)
+ MAX_STR_LENGTH * sizeof(TCHAR);
pStorage->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
pListLoggerInfo[i] = pStorage;
pStorage = (PEVENT_TRACE_PROPERTIES) (
(char*)pStorage +
pStorage->Wnode.BufferSize);
}
// if (XP) {
status = QueryAllTraces(pListLoggerInfo,
MAX_LOG_SESSIONS,
&returnCount);
/*
}
else {
status = QueryAllTraces(pListLoggerInfo,
32,
&returnCount);
}
*/
if (status == ERROR_SUCCESS)
{
for (ULONG j = 0; j < returnCount; j++)
{
LPTSTR ListLoggerName;
TCHAR asked = _T('?') ;
BOOL StatusPrint = FALSE ;
if (bKill)
{
ListLoggerName = (LPTSTR) ((char*)pListLoggerInfo[j] +
pListLoggerInfo[j]->LoggerNameOffset);
/*
if (!bForceKill) {
while (!(asked == _T('y')) && !(asked == _T('n'))) {
ULONG ReadChars = 0;
_tprintf(_T("Do you want to kill Logger \"%s\" (Y or N)?"), ListLoggerName);
ReadChars = _tscanf(_T(" %c"), &asked);
if (ReadChars == 0 || ReadChars == EOF) {
continue;
}
if (asked == _T('Y')) {
asked = _T('y') ;
} else if (asked == _T('N')) {
asked = _T('n') ;
}
}
} else {
*/
asked = _T('y');
// }
if (asked == _T('y')) {
if (!IsEqualGUID(pListLoggerInfo[j]->Wnode.Guid,
SystemTraceControlGuid))
{
loggerHandle = pListLoggerInfo[j]->Wnode.HistoricalContext;
status = EnableTrace(
FALSE,
(pListLoggerInfo[j]->LogFileMode &
EVENT_TRACE_PRIVATE_LOGGER_MODE)
? (EVENT_TRACE_PRIVATE_LOGGER_MODE)
: (0),
0,
& pListLoggerInfo[j]->Wnode.Guid,
loggerHandle);
}
status = ControlTrace((TRACEHANDLE) 0,
ListLoggerName,
pListLoggerInfo[j],
EVENT_TRACE_CONTROL_STOP);
_tprintf(_T("Logger \"%s\" has been killed\n"), ListLoggerName);
StatusPrint = TRUE ;
} else {
_tprintf(_T("Logger \"%s\" has not been killed, current Status is\n"), ListLoggerName);
StatusPrint = FALSE ;
}
}
m_pLoggerInfo = pListLoggerInfo[j];
PrintLoggerStatus(status);
_tprintf(_T("\n"));
}
}
free(storage);
return status;
}
LONG CTraceViewApp::QueryActiveSession()
{
TRACEHANDLE loggerHandle = 0;
LPTSTR loggerName = NULL;
LONG start = 2;
LONG guidCount = 0;
CString guidFile;
GUID guid;
LONG status;
CString pdbFile;
CString tmcPath;
CFileFind fileFind;
TCHAR drive[10];
TCHAR path[MAXSTR];
TCHAR file[MAXSTR];
TCHAR ext[MAXSTR];
//
// Get the logger name string
//
loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
_tcscpy(loggerName, __wargv[2]);
start = 3;
}
for(LONG ii = start; ii < __argc; ii++) {
//
// Get the control guid(s)
//
if(!_tcscmp(__wargv[ii], _T("-guid"))) {
if((ii + 1) < __argc) {
if(__wargv[ii + 1][0] == _T('#')) {
m_guidArray.Add(__wargv[ii + 1][1]);
guidCount++;
} else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
_tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
// _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
guidCount += GetGuids(guidFile);
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
}
ii++;
}
}
//
// Get the control guid(s) from a PDB file
//
if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
if(((ii + 1) < __argc) &&
((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
_tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
pdbFile = (LPCTSTR)pdbFile;
ParsePdb(pdbFile, m_traceDirectory, TRUE);
_tprintf(_T("\n\n"));
tmcPath = (LPCTSTR)m_traceDirectory;
tmcPath +=_T("\\*.tmc");
if(!fileFind.FindFile(tmcPath)) {
_tprintf(_T("Failed To Get Control GUID From PDB"));
return ERROR_INVALID_PARAMETER;
}
while(fileFind.FindNextFile()) {
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
}
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
ii++;
}
}
}
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
if (guidCount != 1) {
_tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
status = ERROR_INVALID_PARAMETER;
return status;
}
StringToGuid(m_guidArray[0].GetBuffer(0), &guid);
m_pLoggerInfo->Wnode.Guid = guid;
}
/*
if (specialLogger == 3) {
status = GetGlobalLoggerSettings(m_pLoggerInfo, &m_pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
}
*/
status = ControlTrace(loggerHandle, loggerName, m_pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
PrintLoggerStatus(status);
return status;
}
LONG CTraceViewApp::FlushActiveBuffers()
{
TRACEHANDLE loggerHandle = 0;
LPTSTR loggerName = NULL;
LONG start = 2;
LONG guidCount = 0;
CString guidFile;
GUID guid;
LONG status;
CString pdbFile;
CString tmcPath;
CFileFind fileFind;
TCHAR drive[10];
TCHAR path[MAXSTR];
TCHAR file[MAXSTR];
TCHAR ext[MAXSTR];
//
// Get the logger name string
//
loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
_tcscpy(loggerName, __wargv[2]);
start = 3;
}
for(LONG ii = start; ii < __argc; ii++) {
//
// Get the control guid(s)
//
if(!_tcscmp(__wargv[ii], _T("-guid"))) {
if((ii + 1) < __argc) {
if(__wargv[ii + 1][0] == _T('#')) {
m_guidArray.Add(__wargv[ii + 1][1]);
guidCount++;
} else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
_tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
// _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
guidCount += GetGuids(guidFile);
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
}
ii++;
}
}
//
// Get the control guid(s) from a PDB file
//
if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
if(((ii + 1) < __argc) &&
((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
_tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
pdbFile = (LPCTSTR)pdbFile;
ParsePdb(pdbFile, m_traceDirectory, TRUE);
_tprintf(_T("\n\n"));
tmcPath = (LPCTSTR)m_traceDirectory;
tmcPath +=_T("\\*.tmc");
if(!fileFind.FindFile(tmcPath)) {
_tprintf(_T("Failed To Get Control GUID From PDB"));
return ERROR_INVALID_PARAMETER;
}
while(fileFind.FindNextFile()) {
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
}
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
ii++;
}
}
}
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
if(guidCount != 1) {
_tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
status = ERROR_INVALID_PARAMETER;
return status;
}
StringToGuid(m_guidArray[0].GetBuffer(0), &guid);
m_pLoggerInfo->Wnode.Guid = guid;
}
// status = (ULONG)FlushTrace(loggerHandle, loggerName, m_pLoggerInfo);
status = 1;
if(FlushTraceFunction) {
status = (ULONG)(FlushTraceFunction)(loggerHandle, loggerName, m_pLoggerInfo);
PrintLoggerStatus(status);
}
return status;
}
LONG CTraceViewApp::UpdateActiveSession()
{
TRACEHANDLE loggerHandle = 0;
LPTSTR loggerName = NULL;
LPTSTR logFileName = NULL;
LONG start = 2;
LONG guidCount = 0;
CString guidFile;
GUID guid;
LONG status;
ULONG enableFlags = 0;
ULONG specialLogger = 0;
USHORT numberOfFlags = 0;
USHORT offset;
PTRACE_ENABLE_FLAG_EXTENSION flagExt;
PULONG pFlags = NULL;
LONG i;
CString pdbFile;
CString tmcPath;
CFileFind fileFind;
TCHAR drive[10];
TCHAR path[MAXSTR];
TCHAR file[MAXSTR];
TCHAR ext[MAXSTR];
//
// Get the logger name string
//
loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
logFileName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LogFileNameOffset);
//
// Get the logger name
//
if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
_tcscpy(loggerName, __wargv[2]);
start = 3;
}
for(LONG ii = start; ii < __argc; ii++) {
//
// Set the maximum number of buffers
//
if(!_tcscmp(__wargv[ii], _T("-max"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->MaximumBuffers = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the log file name
//
if(!_tcscmp(__wargv[ii], _T("-f"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
_tfullpath(logFileName, __wargv[ii + 1], MAX_STR_LENGTH);
ii++;
}
}
}
//
// Set the flush time setting
//
if(!_tcscmp(__wargv[ii], _T("-ft"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
m_pLoggerInfo->FlushTimer = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Get the control guid(s)
//
if(!_tcscmp(__wargv[ii], _T("-guid"))) {
if((ii + 1) < __argc) {
if(__wargv[ii + 1][0] == _T('#')) {
m_guidArray.Add(__wargv[ii + 1][1]);
guidCount++;
} else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
_tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
// _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
guidCount += GetGuids(guidFile);
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
}
ii++;
}
}
//
// Get the control guid(s) from a PDB file
//
if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
if(((ii + 1) < __argc) &&
((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
_tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
pdbFile = (LPCTSTR)pdbFile;
ParsePdb(pdbFile, m_traceDirectory, TRUE);
_tprintf(_T("\n\n"));
tmcPath = (LPCTSTR)m_traceDirectory;
tmcPath +=_T("\\*.tmc");
if(!fileFind.FindFile(tmcPath)) {
_tprintf(_T("Failed To Get Control GUID From PDB"));
return ERROR_INVALID_PARAMETER;
}
while(fileFind.FindNextFile()) {
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
}
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
ii++;
}
}
//
// Check for real-time setting
//
if(!_tcscmp(__wargv[ii], _T("-rt"))) {
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
//
// Did the user specify buffering only?
//
if ((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
if (__wargv[ii + 1][0] == 'b')
m_pLoggerInfo->LogFileMode |= EVENT_TRACE_BUFFERING_MODE;
ii++;
}
}
}
//
// Set the flags
//
if((!_tcscmp(__wargv[ii], _T("-flag"))) || (!_tcscmp(__wargv[ii], _T("-flags")))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
//
// Get the flags specified, convert from hex if necessary
//
if(__wargv[ii + 1][1] == _T('x') || __wargv[ii + 1][1] == _T('X')) {
m_pLoggerInfo->EnableFlags |= ahextoi(__wargv[ii + 1]);
} else {
m_pLoggerInfo->EnableFlags |= _ttoi(__wargv[ii + 1]);
}
//
// Copy flags for EnableTrace
//
enableFlags = m_pLoggerInfo->EnableFlags;
//
// Do not accept flags with MSB = 1.
//
if (0x80000000 & m_pLoggerInfo->EnableFlags) {
_tprintf(_T("Invalid Flags: 0x%0X(%d.)\n"),
m_pLoggerInfo->EnableFlags, m_pLoggerInfo->EnableFlags);
status = ERROR_INVALID_PARAMETER;
return status;
}
ii++;
}
}
}
//
// Set the eflags
//
if(!_tcscmp(__wargv[ii], _T("-eflag"))) {
if((ii + 2) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
numberOfFlags = (USHORT)_ttoi(__wargv[ii + 1]);
ii++;
if((numberOfFlags > MAX_ENABLE_FLAGS) || (numberOfFlags < 1)) {
_tprintf(_T("Error: Invalid number of enable flags\n"));
status = ERROR_INVALID_PARAMETER;
return status;
}
offset = (USHORT) sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAX_STR_LENGTH * sizeof(TCHAR);
m_pLoggerInfo->EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
flagExt = (PTRACE_ENABLE_FLAG_EXTENSION)
&m_pLoggerInfo->EnableFlags;
flagExt->Offset = offset;
flagExt->Length = (UCHAR)numberOfFlags;
pFlags = (PULONG)(offset + (PCHAR) m_pLoggerInfo);
for (i = 0; ((i < numberOfFlags) && ((ii + 1) < __argc)); i++) {
if ((__wargv[ii + 1][0] == '-') || (__wargv[ii + 1][0] == '/')) {
//
// Correct the number of eflags when the user
// types an incorrect number.
// However, this does not work if the next
// argument is Logger Name.
//
break;
}
pFlags[i] = ahextoi(__wargv[ii + 1]);
ii++;
// _tprintf(_T("Setting logger flags to 0x%0X(%d.)\n"),
// pFlags[i], pFlags[i] );
}
numberOfFlags = (USHORT)i;
for ( ; i < MAX_ENABLE_FLAGS; i++) {
pFlags[i] = 0;
}
if (flagExt->Length != (UCHAR)numberOfFlags) {
// _tprintf(_T("Correcting the number of eflags to %d\n"), i),
flagExt->Length = (UCHAR)numberOfFlags;
}
}
}
}
}
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
if (guidCount != 1) {
_tprintf(_T("Need exactly one GUID for PRIVATE loggers\n"));
status = ERROR_INVALID_PARAMETER;
return status;
}
StringToGuid(m_guidArray[0].GetBuffer(0), &guid);
m_pLoggerInfo->Wnode.Guid = guid;
}
/*
if (specialLogger == 3) {
status = GetGlobalLoggerSettings(m_pLoggerInfo, &m_pLoggerInfo->Wnode.ClientContext, &GlobalLoggerStartValue);
}
*/
status = ControlTrace(loggerHandle, loggerName, m_pLoggerInfo, EVENT_TRACE_CONTROL_UPDATE);
PrintLoggerStatus(status);
return status;
}
LONG CTraceViewApp::EnumerateRegisteredGuids()
{
ULONG propertyArrayCount = 10;
PTRACE_GUID_PROPERTIES *guidPropertiesArray;
ULONG enumGuidCount;
ULONG sizeStorage;
PVOID storageNeeded;
PTRACE_GUID_PROPERTIES cleanStorage;
CString str;
LONG status;
ULONG i;
Retry:
sizeStorage = propertyArrayCount * (sizeof(TRACE_GUID_PROPERTIES) + sizeof(PTRACE_GUID_PROPERTIES));
storageNeeded = malloc(sizeStorage);
if(storageNeeded == NULL) {
status = ERROR_OUTOFMEMORY;
return status;
}
RtlZeroMemory(storageNeeded, sizeStorage);
guidPropertiesArray = (PTRACE_GUID_PROPERTIES *)storageNeeded;
cleanStorage = (PTRACE_GUID_PROPERTIES)((char*)storageNeeded + propertyArrayCount * sizeof(PTRACE_GUID_PROPERTIES));
for(i = 0; i < propertyArrayCount; i++) {
guidPropertiesArray[i] = cleanStorage;
cleanStorage = (PTRACE_GUID_PROPERTIES) (
(char*)cleanStorage + sizeof(TRACE_GUID_PROPERTIES)
);
}
//
// V1.0 Note: We are deliberately "breaking" things here, so that
// TraceView will NOT be able to load in Windows 2000. This is because
// very last minute testing indicated that TraceView did not work
// properly on Win2K. This will take some investigating, so the
// work to support Win2K is deferred to a later release.
// (see companion "V1.0 NOTE" in the code below)
//
status = EnumerateTraceGuids(guidPropertiesArray,
propertyArrayCount,
&enumGuidCount);
//
// See V1.0 NOTE, above
//
// if(EnumerateTraceGuidsFunction) {
//
// status = (EnumerateTraceGuidsFunction)(guidPropertiesArray,
// propertyArrayCount,
// &enumGuidCount);
if(status == ERROR_MORE_DATA)
{
propertyArrayCount = enumGuidCount;
free(storageNeeded);
goto Retry;
}
//
// (see V1.0 NOTE above)
//
// } else {
//
// _tprintf(_T("not supported on Win2K\n"));
// status = 1;
//
// return status;
// }
//
// print the GUID_PROPERTIES and Free Strorage
//
_tprintf(_T(" Guid Enabled LoggerId Level Flags\n"));
_tprintf(_T("----------------------------------------------------------\n"));
for (i=0; i < enumGuidCount; i++) {
GuidToString(guidPropertiesArray[i]->Guid, str);
_tprintf(_T("%s %5s %d %d %d\n"),
(LPCTSTR)str,
(guidPropertiesArray[i]->IsEnable) ? _T("TRUE") : _T("FALSE"),
guidPropertiesArray[i]->LoggerId,
guidPropertiesArray[i]->EnableLevel,
guidPropertiesArray[i]->EnableFlags);
}
free(storageNeeded);
return status;
}
LONG CTraceViewApp::EnableProvider(BOOL bEnable)
{
TRACEHANDLE loggerHandle = 0;
LPTSTR loggerName = NULL;
LPTSTR logFileName = NULL;
LONG start = 2;
LONG guidCount = 0;
CString guidFile;
GUID guid;
LONG status;
ULONG enableFlags = 0;
ULONG traceLevel = 0;
ULONG specialLogger = 0;
USHORT numberOfFlags = 0;
USHORT offset;
PTRACE_ENABLE_FLAG_EXTENSION flagExt;
PULONG pFlags = NULL;
LONG i;
CString pdbFile;
CString tmcPath;
CFileFind fileFind;
TCHAR drive[10];
TCHAR path[MAXSTR];
TCHAR file[MAXSTR];
TCHAR ext[MAXSTR];
//
// Get the logger name string
//
loggerName = (LPTSTR)((char*)m_pLoggerInfo + m_pLoggerInfo->LoggerNameOffset);
//
// Get the logger name
//
if((__argc > 2) && ((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
_tcscpy(loggerName, __wargv[2]);
start = 3;
}
for(LONG ii = start; ii < __argc; ii++) {
//
// Get the control guid(s)
//
if(!_tcscmp(__wargv[ii], _T("-guid"))) {
if((ii + 1) < __argc) {
if(__wargv[ii + 1][0] == _T('#')) {
m_guidArray.Add(__wargv[ii + 1][1]);
guidCount++;
} else if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
_tfullpath(guidFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
// _tprintf(_T("Getting guids from %s\n"), (LPCTSTR)guidFile);
guidCount += GetGuids(guidFile);
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
}
ii++;
}
}
//
// Get the control guid(s) from a PDB file
//
if(!_tcscmp(__wargv[ii], _T("-pdb"))) {
if(((ii + 1) < __argc) &&
((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
_tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), __wargv[ii + 1], MAX_STR_LENGTH);
pdbFile = (LPCTSTR)pdbFile;
ParsePdb(pdbFile, m_traceDirectory, TRUE);
_tprintf(_T("\n\n"));
tmcPath = (LPCTSTR)m_traceDirectory;
tmcPath +=_T("\\*.tmc");
if(!fileFind.FindFile(tmcPath)) {
_tprintf(_T("Failed To Get Control GUID From PDB"));
return ERROR_INVALID_PARAMETER;
}
while(fileFind.FindNextFile()) {
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
}
tmcPath = fileFind.GetFileName();
_tsplitpath(tmcPath, drive, path, file, ext );
m_guidArray.Add(file);
guidCount++;
if (guidCount < 0) {
_tprintf( _T("Error: %ls does not exist\n"), (LPCTSTR)guidFile );
} else if (guidCount == 0){
_tprintf( _T("Error: %ls is invalid\n"), (LPCTSTR)guidFile );
status = ERROR_INVALID_PARAMETER;
return status;
}
ii++;
}
}
//
// Set the level
//
if(!_tcscmp(__wargv[ii], _T("-level"))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
traceLevel = _ttoi(__wargv[ii + 1]);
ii++;
}
}
}
//
// Set the flags
//
if((!_tcscmp(__wargv[ii], _T("-flag"))) || (!_tcscmp(__wargv[ii], _T("-flags")))) {
if((ii + 1) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
//
// Get the flags specified, convert from hex if necessary
//
if(__wargv[ii + 1][1] == _T('x') || __wargv[ii + 1][1] == _T('X')) {
m_pLoggerInfo->EnableFlags |= ahextoi(__wargv[ii + 1]);
} else {
m_pLoggerInfo->EnableFlags |= _ttoi(__wargv[ii + 1]);
}
//
// Copy flags for EnableTrace
//
enableFlags = m_pLoggerInfo->EnableFlags;
//
// Do not accept flags with MSB = 1.
//
if (0x80000000 & m_pLoggerInfo->EnableFlags) {
_tprintf(_T("Invalid Flags: 0x%0X(%d.)\n"),
m_pLoggerInfo->EnableFlags, m_pLoggerInfo->EnableFlags);
status = ERROR_INVALID_PARAMETER;
return status;
}
ii++;
}
}
}
//
// Set the eflags
//
if(!_tcscmp(__wargv[ii], _T("-eflag"))) {
if((ii + 2) < __argc) {
if((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/')) {
numberOfFlags = (USHORT)_ttoi(__wargv[ii + 1]);
ii++;
if((numberOfFlags > MAX_ENABLE_FLAGS) || (numberOfFlags < 1)) {
_tprintf(_T("Error: Invalid number of enable flags\n"));
status = ERROR_INVALID_PARAMETER;
return status;
}
offset = (USHORT) sizeof(EVENT_TRACE_PROPERTIES) + 2 * MAX_STR_LENGTH * sizeof(TCHAR);
m_pLoggerInfo->EnableFlags = EVENT_TRACE_FLAG_EXTENSION;
flagExt = (PTRACE_ENABLE_FLAG_EXTENSION)
&m_pLoggerInfo->EnableFlags;
flagExt->Offset = offset;
flagExt->Length = (UCHAR)numberOfFlags;
pFlags = (PULONG)(offset + (PCHAR) m_pLoggerInfo);
for (i = 0; ((i < numberOfFlags) && ((ii + 1) < __argc)); i++) {
if ((__wargv[ii + 1][0] == '-') || (__wargv[ii + 1][0] == '/')) {
//
// Correct the number of eflags when the user
// types an incorrect number.
// However, this does not work if the next
// argument is Logger Name.
//
break;
}
pFlags[i] = ahextoi(__wargv[ii + 1]);
ii++;
// _tprintf(_T("Setting logger flags to 0x%0X(%d.)\n"),
// pFlags[i], pFlags[i] );
}
numberOfFlags = (USHORT)i;
for ( ; i < MAX_ENABLE_FLAGS; i++) {
pFlags[i] = 0;
}
if (flagExt->Length != (UCHAR)numberOfFlags) {
// _tprintf(_T("Correcting the number of eflags to %d\n"), i),
flagExt->Length = (UCHAR)numberOfFlags;
}
}
}
}
}
if(m_pLoggerInfo->LogFileMode & EVENT_TRACE_PRIVATE_LOGGER_MODE) {
if(guidCount != 1) {
_tprintf(_T("Need one GUID for PRIVATE loggers\n"));
status = ERROR_INVALID_PARAMETER;
return status;
}
StringToGuid(m_guidArray[0].GetBuffer(0), &guid);
m_pLoggerInfo->Wnode.Guid = guid;
}
status = ControlTrace((TRACEHANDLE) 0, loggerName, m_pLoggerInfo, EVENT_TRACE_CONTROL_QUERY);
if(status != ERROR_SUCCESS) {
/*
if( IsEqualGUID(&HeapGuid,&m_pLoggerInfo->Wnode.Guid)
|| IsEqualGUID(&CritSecGuid,&m_pLoggerInfo->Wnode.Guid)
){
//do nothing
} else {
*/
_tprintf( _T("ERROR: Logger not started\n")
_T("Operation Status: %uL\n")
_T("%s\n"),
status,
DecodeStatus(status));
return status;
// }
}
loggerHandle = m_pLoggerInfo->Wnode.HistoricalContext;
if((guidCount > 0) && (specialLogger == 0)) {
_tprintf(_T("Enabling trace to logger %d\n"), loggerHandle);
for(i = 0; i < (ULONG)guidCount; i++) {
StringToGuid(m_guidArray[i].GetBuffer(0), &guid);
status = EnableTrace (
bEnable,
enableFlags,
traceLevel,
&guid,
loggerHandle);
//
// If the Guid can not be enabled, it is a benign
// failure. Print Warning message and continue.
//
if(status == 4317) {
_tprintf(_T("WARNING: Could not enable some guids.\n"));
_tprintf(_T("Check your Guids file\n"));
status = ERROR_SUCCESS;
}
if(status != ERROR_SUCCESS) {
_tprintf(_T("ERROR: Failed to enable Guid [%d]...\n"), i);
_tprintf(_T("Operation Status: %uL\n"), status);
_tprintf(_T("%s\n"),DecodeStatus(status));
return status;
}
}
} else if(guidCount > 0) {
_tprintf(_T("ERROR: System Logger does not accept application guids...\n"));
status = ERROR_INVALID_PARAMETER;
}
PrintLoggerStatus(status);
return status;
}
LONG CTraceViewApp::ConsumeTraceEvents()
{
TCHAR guidFileName[MAXSTR];
TCHAR dumpFileName[MAXSTR];
TCHAR summaryFileName[MAXSTR];
LPTSTR *commandLine;
LPTSTR *targv;
LPTSTR *cmdargv;
LONG argc;
PEVENT_TRACE_LOGFILE pLogFile;
ULONG status;
ULONG guidCount = 0;
ULONG i;
ULONG j;
TRACEHANDLE handleArray[MAXLOGFILES];
CString pdbFile;
CString formatOptions;
//
// initialize member variables
//
m_pDumpFile = NULL;
m_pSummaryFile = NULL;
m_bDebugDisplay = FALSE ;
m_bDisplayOnly = FALSE ;
m_bSummaryOnly = FALSE ;
m_bNoSummary = FALSE ;
m_bVerbose = FALSE ;
m_bFixUp = FALSE ;
m_bODSOutput = FALSE ;
m_bTMFSpecified = FALSE ;
m_bCSVMode = FALSE ;
m_bNoCSVHeader = TRUE ;
m_bCSVHeader = FALSE ;
m_totalBuffersRead = 0;
m_totalEventsLost = 0;
m_totalEventCount = 0;
m_timerResolution = 10;
m_bufferWrap = 0 ;
m_eventListHead = NULL;
m_logFileCount = 0;
m_userMode = FALSE; // TODO: Pick this up from the stream itself.
m_traceMask = NULL;
targv = __wargv;
argc = __argc;
_tcscpy(dumpFileName, _T("FmtFile.txt"));
_tcscpy(summaryFileName, _T("FmtSum.txt"));
// By default look for Define.guid in the image location
if ((status = GetModuleFileName(NULL, guidFileName, MAXSTR)) == MAXSTR) {
guidFileName[MAXSTR-1] = _T('\0');
}
if( status != 0 ){
TCHAR drive[10];
TCHAR path[MAXSTR];
TCHAR file[MAXSTR];
TCHAR ext[MAXSTR];
_tsplitpath( guidFileName, drive, path, file, ext );
_tcscpy(ext, GUID_EXT );
_tcscpy(file, GUID_FILE );
_tmakepath( guidFileName, drive, path, file, ext );
}else{
_tcscpy( guidFileName, GUID_FILE );
_tcscat( guidFileName, _T(".") );
_tcscat( guidFileName, GUID_EXT );
}
while (--argc > 0) {
++targv;
if (**targv == '-' || **targv == '/') { // argument found
if( **targv == '/' ){
**targv = '-';
}
else if (!_tcsicmp(targv[0], _T("-debug"))) {
m_bDebugDisplay = TRUE;
}
else if (!_tcsicmp(targv[0], _T("-display"))) {
m_bDebugDisplay = TRUE ;
}
else if (!_tcsicmp(targv[0], _T("-displayonly"))) {
m_bDisplayOnly = TRUE ;
}
else if (!_tcsicmp(targv[0], _T("-fixup"))) {
m_bFixUp = TRUE;
}
else if (!_tcsicmp(targv[0], _T("-summary"))) {
m_bSummaryOnly = TRUE;
}
else if (!_tcsicmp(targv[0], _T("-seq"))) {
SetTraceFormatParameter(ParameterSEQUENCE, ULongToPtr(1));
}
else if (!_tcsicmp(targv[0], _T("-gmt"))) {
SetTraceFormatParameter(ParameterGMT, ULongToPtr(1));
}
else if (!_tcsicmp(targv[0], _T("-utc"))) {
SetTraceFormatParameter(ParameterGMT, ULongToPtr(1));
} else if (!_tcsicmp(targv[0], _T("-nosummary"))) {
m_bNoSummary = TRUE;
} else if (!_tcsicmp(targv[0], _T("-csv"))) {
m_bCSVMode = TRUE ;
m_bCSVHeader = TRUE ;
SetTraceFormatParameter(ParameterStructuredFormat,UlongToPtr(1));
} else if (!_tcsicmp(targv[0], _T("-nocsvheader"))) {
m_bNoCSVHeader = FALSE ;
}
else if (!_tcsicmp(targv[0], _T("-noprefix"))) {
SetTraceFormatParameter(ParameterUsePrefix,UlongToPtr(0));
}
else if (!_tcsicmp(targv[0], _T("-rt"))) {
TCHAR LoggerName[MAXSTR];
_tcscpy(LoggerName, KERNEL_LOGGER_NAME);
if (argc > 1) {
if (targv[1][0] != '-' && targv[1][0] != '/') {
++targv;
--argc;
_tcscpy(LoggerName, targv[0]);
}
}
pLogFile = (PEVENT_TRACE_LOGFILE)malloc(sizeof(EVENT_TRACE_LOGFILE));
if (pLogFile == NULL){
_tprintf(_T("Allocation Failure\n"));
goto cleanup;
}
RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
m_evmFile[m_logFileCount] = pLogFile;
m_evmFile[m_logFileCount]->LogFileName = NULL;
m_evmFile[m_logFileCount]->LoggerName =
(LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
if ( m_evmFile[m_logFileCount]->LoggerName == NULL ) {
_tprintf(_T("Allocation Failure\n"));
goto cleanup;
}
_tcscpy(m_evmFile[m_logFileCount]->LoggerName, LoggerName);
_tprintf(_T("Setting RealTime mode for %s\n"),
m_evmFile[m_logFileCount]->LoggerName);
m_evmFile[m_logFileCount]->Context = NULL;
m_evmFile[m_logFileCount]->BufferCallback = (PEVENT_TRACE_BUFFER_CALLBACKW)BufferCallback;
m_evmFile[m_logFileCount]->BuffersRead = 0;
m_evmFile[m_logFileCount]->CurrentTime = 0;
m_evmFile[m_logFileCount]->EventCallback = (PEVENT_CALLBACK)&DumpEvent;
m_evmFile[m_logFileCount]->LogFileMode =
EVENT_TRACE_REAL_TIME_MODE;
m_logFileCount++;
}
else if ( !_tcsicmp(targv[0], _T("-guid")) ) { // maintain for compatabillity
if (argc > 1) {
if (targv[1][0] != '-' && targv[1][0] != '/') {
_tcscpy(guidFileName, targv[1]);
++targv; --argc;
m_bTMFSpecified = TRUE ;
}
}
}
else if ( !_tcsicmp(targv[0], _T("-tmf")) ) {
if (argc > 1) {
if (targv[1][0] != '-' && targv[1][0] != '/') {
_tcscpy(guidFileName, targv[1]);
++targv; --argc;
m_bTMFSpecified = TRUE ;
}
}
}
else if ( !_tcsicmp(targv[0], _T("-pdb")) ) {
if (argc > 1) {
if (targv[1][0] != '-' && targv[1][0] != '/') {
_tfullpath(pdbFile.GetBuffer(MAX_STR_LENGTH), targv[1], MAX_STR_LENGTH);
pdbFile = (LPCTSTR)pdbFile;
if(ParsePdb(pdbFile, m_traceDirectory, TRUE)) {
SetTraceFormatParameter(ParameterTraceFormatSearchPath,
m_traceDirectory.GetBuffer(0));
}
++targv;
--argc;
}
}
}
else if ( !_tcsicmp(targv[0], _T("-p")) ){
if (argc > 1) {
if (targv[1][0] != '-' && targv[1][0] != '/') {
SetTraceFormatParameter(ParameterTraceFormatSearchPath, targv[1]);
++targv; --argc;
}
}
}
else if ( !_tcsicmp(targv[0], _T("-format")) ) {
if (argc > 1) {
if (targv[1][0] != '-' && targv[1][0] != '/') {
for(LONG ii = 0; ii < _tcslen(targv[1]); ii++) {
switch(targv[1][ii]) {
case 'n':
formatOptions += _T("%1!s! ");
break;
case 'w':
formatOptions += _T("%2!s! ");
break;
case 't':
formatOptions += _T("%3!04X! ");
break;
case 's':
formatOptions += _T("%4!s! ");
break;
case 'k':
formatOptions += _T("%5!s! ");
break;
case 'u':
formatOptions += _T("%6!s! ");
break;
case 'q':
formatOptions += _T("%7!d! ");
break;
case 'p':
formatOptions += _T("%8!04X! ");
break;
case 'c':
formatOptions += _T("%9!d! ");
break;
case 'f':
formatOptions += _T("%!FUNC! ");
break;
default:
break;
}
}
SetEnvironmentVariable(_T("TRACE_FORMAT_PREFIX"),
formatOptions);
++targv; --argc;
}
}
}
else if ( !_tcsicmp(targv[0], _T("-v")) ) {
m_bVerbose = TRUE ;
}
else if ( !_tcsicmp(targv[0], _T("-ods")) ) {
m_bODSOutput = TRUE ;
}
else if ( !_tcsicmp(targv[0], _T("-onlyshow")) ) {
if (argc > 1) {
m_traceMask = (TCHAR *)malloc((_tcslen(targv[1])+1) * sizeof(TCHAR));
_tcscpy(m_traceMask, targv[1]);
++targv; --argc;
}
}
else if ( !_tcsicmp(targv[0], _T("-o")) ) {
if (argc > 1) {
if (targv[1][0] != '-' && targv[1][0] != '/') {
TCHAR drive[10];
TCHAR path[MAXSTR];
TCHAR file[MAXSTR];
TCHAR ext[MAXSTR];
++targv; --argc;
_tfullpath(dumpFileName, targv[0], MAXSTR);
_tsplitpath( dumpFileName, drive, path, file, ext );
_tcscat(ext,_T(".sum"));
_tmakepath( summaryFileName, drive, path, file, ext );
}
}
}
}
else {
pLogFile = (PEVENT_TRACE_LOGFILE)malloc(sizeof(EVENT_TRACE_LOGFILE));
if (pLogFile == NULL){
_tprintf(_T("Allocation Failure(EVENT_TRACE_LOGFILE)\n")); // Need to cleanup better.
goto cleanup;
}
RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
m_evmFile[m_logFileCount] = pLogFile;
m_evmFile[m_logFileCount]->LoggerName = NULL;
m_evmFile[m_logFileCount]->LogFileName =
(LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
if (m_evmFile[m_logFileCount]->LogFileName == NULL) {
_tprintf(_T("Allocation Failure (LogFileName)\n"));
goto cleanup;
}
_tfullpath(m_evmFile[m_logFileCount]->LogFileName, targv[0], MAXSTR);
_tprintf(_T("Setting log file to: %s\n"),
m_evmFile[m_logFileCount]->LogFileName);
if (!CheckFile(m_evmFile[m_logFileCount]->LogFileName)) {
_tprintf(_T("Cannot open logfile for reading\n"));
goto cleanup;
}
m_evmFile[m_logFileCount]->Context = NULL;
m_evmFile[m_logFileCount]->BufferCallback = (PEVENT_TRACE_BUFFER_CALLBACKW)BufferCallback;
m_evmFile[m_logFileCount]->BuffersRead = 0;
m_evmFile[m_logFileCount]->CurrentTime = 0;
m_evmFile[m_logFileCount]->EventCallback = (PEVENT_CALLBACK)&DumpEvent;
m_logFileCount++;
}
}
if( _tcslen( guidFileName ) ){
TCHAR str[MAXSTR];
_tfullpath( str, guidFileName, MAXSTR);
_tcscpy( guidFileName, str );
_tprintf(_T("Getting guids from %s\n"), guidFileName);
guidCount = GetTraceGuids(guidFileName, (PLIST_ENTRY *) &m_eventListHead);
if ((guidCount <= 0) && m_bTMFSpecified)
{
_tprintf(_T("GetTraceGuids returned %d, GetLastError=%d, for %s\n"),
guidCount,
GetLastError(),
guidFileName);
}
}
if (m_logFileCount <= 0) {
pLogFile = (PEVENT_TRACE_LOGFILE)malloc(sizeof(EVENT_TRACE_LOGFILE));
if (pLogFile == NULL){
_tprintf(_T("Allocation Failure\n")); // Need to cleanup better.
goto cleanup;
}
RtlZeroMemory(pLogFile, sizeof(EVENT_TRACE_LOGFILE));
m_evmFile[0] = pLogFile;
m_evmFile[0]->LoggerName = NULL;
m_logFileCount = 1;
m_evmFile[0]->LogFileName = (LPTSTR) malloc(MAXSTR*sizeof(TCHAR));
if (m_evmFile[0]->LogFileName == NULL) {
_tprintf(_T("Allocation Failure\n"));
goto cleanup;
}
_tcscpy(m_evmFile[0]->LogFileName, _T("C:\\Logfile.Etl"));
m_evmFile[0]->EventCallback = (PEVENT_CALLBACK)&DumpEvent;
}
for (i = 0; i < m_logFileCount; i++) {
TRACEHANDLE x;
x = OpenTrace(m_evmFile[i]);
handleArray[i] = x;
if (handleArray[i] == 0) {
_tprintf(_T("Error Opening Trace %d with status=%d\n"),
i, GetLastError());
for (j = 0; j < i; j++)
CloseTrace(handleArray[j]);
goto cleanup;
}
}
if (!m_bDisplayOnly) {
m_pDumpFile = _tfopen(dumpFileName, _T("w"));
if (m_pDumpFile == NULL) {
_tprintf(_T("Format File \"%s\" Could not be opened for writing 0X%X\n"),
dumpFileName,GetLastError());
goto cleanup;
}
m_pSummaryFile = NULL ;
if (!m_bNoSummary) {
m_pSummaryFile = _tfopen(summaryFileName, _T("w"));
if (m_pSummaryFile == NULL) {
_tprintf(_T("Summary File \"%s\" could not be opened for writing 0X%X\n"),
summaryFileName,GetLastError());
goto cleanup;
}
}
} else {
m_pDumpFile = stdout;
m_pSummaryFile = stdout;
}
status = ProcessTrace(handleArray,
m_logFileCount,
NULL, NULL);
if (status != ERROR_SUCCESS) {
_tprintf(_T("Error processing trace entry with status=0x%x (GetLastError=0x%x)\n"),
status, GetLastError());
}
for (j = 0; j < m_logFileCount; j++){
status = CloseTrace(handleArray[j]);
if (status != ERROR_SUCCESS) {
_tprintf(_T("Error Closing Trace %d with status=%d\n"), j, status);
}
}
if (!m_bNoSummary) {
_ftprintf(m_pSummaryFile,_T("Files Processed:\n"));
for (i=0; i<m_logFileCount; i++) {
_ftprintf(m_pSummaryFile,_T("\t%s\n"),m_evmFile[i]->LogFileName);
}
GetTraceElapseTime(&m_elapseTime);
_ftprintf(m_pSummaryFile,
_T("Total Buffers Processed %d\n")
_T("Total Events Processed %d\n")
_T("Total Events Lost %d\n")
_T("Elapsed Time %I64d sec\n"),
m_totalBuffersRead,
m_totalEventCount,
m_totalEventsLost,
(m_elapseTime / 10000000) );
_ftprintf(m_pSummaryFile,
_T("+-----------------------------------------------------------------------------------+\n")
_T("|%10s %-20s %-10s %-36s|\n")
_T("+-----------------------------------------------------------------------------------+\n"),
_T("EventCount"),
_T("EventName"),
_T("EventType"),
_T("Guid")
);
SummaryTraceEventList(m_summaryBlock, SIZESUMMARYBLOCK, m_eventListHead);
_ftprintf(m_pSummaryFile,
_T("%s+-----------------------------------------------------------------------------------+\n"),
m_summaryBlock);
}
cleanup:
CleanupTraceEventList(m_eventListHead);
if (m_bVerbose) {
_tprintf(_T("\n")); // need a newline after the block updates
}
if (m_pDumpFile != NULL) {
_tprintf(_T("Event traces dumped to %s\n"), dumpFileName);
fclose(m_pDumpFile);
}
if(m_pSummaryFile != NULL){
_tprintf(_T("Event Summary dumped to %s\n"), summaryFileName);
fclose(m_pSummaryFile);
}
for (i = 0; i < m_logFileCount; i ++)
{
if (m_evmFile[i]->LoggerName != NULL)
{
free(m_evmFile[i]->LoggerName);
m_evmFile[i]->LoggerName = NULL;
}
if (m_evmFile[i]->LogFileName != NULL)
{
free(m_evmFile[i]->LogFileName);
m_evmFile[i]->LogFileName = NULL;
}
free(m_evmFile[i]);
}
status = GetLastError();
if(status != ERROR_SUCCESS ){
_tprintf(_T("Exit Status: %d\n"), status );
}
return 0;
}
LONG CTraceViewApp::ExtractPdbInfo()
{
DWORD status;
CString path;
CString pdbName;
CHAR pdbNameStr[500];
CHAR pathStr[500];
INT len;
INT targv = 0;
BOOL bPDBName = FALSE ;
LPTSTR dllToLoad = NULL;
/*
TCHAR helptext[] = "Usage: TracePDB -f <pdbname> [-p <path>] [-v]\n"
" Options:\n"
// " -r recurse into subdirectories\n"
" -f specifies the PDBName from which to extract tmf's\n"
" -p specifies the path to create the tmf's,\n"
" by default the current directory.\n"
" -v verbose, displays actions taken \n" ;
*/
if (GetCurrentDirectory(MAX_PATH, path.GetBuffer(MAX_PATH)) == 0 ) {
_fputts(_T("TracePDB: no current directory\n"), stdout);
return ERROR_PATH_NOT_FOUND;
}
path = (LPCTSTR)path;
//
// Get the PDB file name
//
if((__argc > 2) &&
((__wargv[2][0] != '-') && (__wargv[2][0] != '/'))) {
if((_tcslen(__wargv[2]) + 1) > MAX_PATH) {
_fputts(_T("TracePDB: PDBname too large\n"), stdout);
return ERROR_INVALID_PARAMETER;
}
pdbName.GetBuffer(_tcslen(__wargv[2]) + 1);
pdbName = __wargv[2];
bPDBName = TRUE ;
}
for(LONG ii = 3; ii < __argc; ii++) {
if((__argc > 3) && ((__wargv[ii][0] == '-') || (__wargv[ii][0] == '/'))) {
if(__wargv[ii][1] == 'p') {
if(((ii + 1) < __argc) &&
((__wargv[ii + 1][0] != '-') && (__wargv[ii + 1][0] != '/'))) {
if((_tcslen(__wargv[ii + 1]) + 1) > MAX_PATH) {
fputs("TracePDB: Path larger than MAX_PATH\n", stdout);
return ERROR_INVALID_PARAMETER;
}
_tcsncpy(path.GetBuffer(_tcslen(__wargv[ii + 1]) + 1),
__wargv[ii + 1],
_tcslen(__wargv[ii + 1]) + 1);
ii++;
}
} else {
return ERROR_INVALID_PARAMETER;
}
}
}
if (!bPDBName) {
_tprintf(_T("TracePDB: No PDB specified?\n\n"));
return ERROR_INVALID_PARAMETER;
}
if((dllToLoad = (LPTSTR) malloc(MAX_PATH + 1)) == NULL) {
_fputts(_T("TracePDB: malloc failed\n"), stdout);
return ERROR_OUTOFMEMORY;
}
_tcscpy(dllToLoad, _T("mspdb70.dll"));
if(!ParsePdb(pdbName, path, TRUE)) {
status = ERROR_INVALID_PARAMETER;
_tprintf(_T("TracePDB: failed with error %d\n"), status);
}
return status;
}
void CTraceViewApp::DisplayHelp()
{
_fputts(
_T("\n")
_T("\n")
_T("\n")
_T("Control:\n")
_T("Usage: traceview [action] [options] | [-h | -help | -?]\n")
_T("\n")
_T("Control Actions:\n")
_T("\t-start [LoggerName] Starts up the [LoggerName] trace session\n")
_T("\t-stop [LoggerName] Stops the [LoggerName] trace session\n")
_T("\t-update [LoggerName] Updates the [LoggerName] trace session\n")
_T("\t-enable [LoggerName] Enables providers for the [LoggerName] session\n")
_T("\t-disable [LoggerName] Disables providers for the [LoggerName] session\n")
_T("\t-flush [LoggerName] Flushes the [LoggerName] active buffers\n")
_T("\t-enumguid Enumerate Registered Trace Guids\n")
_T("\t-q [LoggerName] Query status of [LoggerName] trace session\n")
_T("\t-l List all trace sessions\n")
_T("\t-x Stops all active trace sessions\n")
_T("\n")
_T("Control Options:\n")
_T("\t-b <n> Sets buffer size to <n> Kbytes\n")
_T("\t-min <n> Sets minimum buffers\n")
_T("\t-max <n> Sets maximum buffers\n")
_T("\t-f <name> Log to file <name>\n")
_T("\t-append Append to file\n")
_T("\t-prealloc Pre-allocate\n")
_T("\t-seq <n> Sequential logfile of up to n Mbytes\n")
_T("\t-cir <n> Circular logfile of n Mbytes\n")
_T("\t-newfile <n> Log to a new file after every n Mbytes\n")
_T("\t-ft <n> Set flush timer to n seconds\n")
_T("\t-paged Use pageable memory for buffers\n")
_T("\t-guid <file> Start tracing for providers in file\n")
_T("\t-pdb <file> Start tracing for provider related to PDB file\n")
_T("\t-rt Enable tracing in real time mode\n")
_T("\t-kd Enable tracing in kernel debugger\n")
_T("\t-age <n> Modify aging decay time to n minutes\n")
_T("\t-level <n> Enable Level passed to the providers\n")
_T("\t-flag <n> Enable Flags passed to the providers\n")
_T("\t-eflag <n> <flag...> Enable flags (several) to providers\n")
_T("\n")
_T("\n")
_T("Consumption:\n")
_T("Usage: traceview [action] [options] <evmfile> | [-h | -help | -?]\n")
_T("\n")
_T("Consumption Actions:\n")
_T("\t-process Setup trace event processing for consumer\n")
_T("\n")
_T("Consumption Options:\n")
_T("\t-o <file> Output file\n")
_T("\t-csv Format the output as a comma seperated file\n")
_T("\t-tmf <file> Format definition file\n")
_T("\t-pdb <file> Retrieve format information from PDB file\n")
_T("\t-p <path> TMF file search path\n")
_T("\t-rt [loggername] Realtime formatting\n")
_T("\t-h Display this information\n")
_T("\t-display Display output\n")
_T("\t-displayonly Display output. Don't write to the file\n")
_T("\t-nosummary Don't create the summary file\n")
_T("\t-noprefix Suppress any defined TRACE_FORMAT_PREFIX")
_T("\t-ods do Display output using OutputDebugString\n")
_T("\t-summaryonly Don't create the listing file.\n")
_T("\t-v Verbose Display\n")
_T("\n")
_T("\tDefault evmfile is ") _T("C:\\Logfile.Etl") _T("\n")
_T("\tDefault outputfile is ") _T("FmtFile.txt") _T("\n")
_T("\tDefault TMF file is ") GUID_FILE _T(".") GUID_EXT _T("\n")
_T("\n")
_T("\n")
_T("Parsing:\n")
_T("Usage: traceview [action] <pdbname> [-p <path>] | [-h | -help | -?]\n")
_T("\n")
_T("Parsing Actions:\n")
_T("\t-parsepdb <pdbname> Extract TMF(s) from <pdbname>\n")
_T("\n")
_T("Parsing Options:\n")
_T("\t-p specifies the path to create the tmf's,\n")
_T("\t by default the current directory.\n")
_T("\n")
_T("\n")
_T("\n")
_T("Examples:\n")
_T("\n")
_T("Start a log session named foo with the following properties:\n")
_T(" - real-time\n")
_T(" - flags set to 0x7\n")
_T(" - flush time equal to 1\n")
_T(" - control GUID information stored in foo.pdb\n")
_T("\n")
_T("traceview -start foo -rt - flag 0x7 -ft 1 -pdb foo.pdb\n")
_T("\n")
_T("\n")
_T("Consume trace events from a logger named bar with the\n")
_T(" following options:\n")
_T(" - process events in real-time from real-time logger bar\n")
_T(" - display to screen only, no listing file generated\n")
_T(" - display process ID, CPU number, and function name\n")
_T(" ahead of event message \n")
_T(" - extract event format information from bar.pdb\n")
_T("\n")
_T("traceview -process -pdb bar.pdb -displayonly -rt bar -format pcf\n")
_T("\n")
_T("\n")
_T("Extract the TMF files from a PDB file and place them in \n")
_T(" a directory named c:\\foobar\n")
_T("\n")
_T("traceview -parsepdb bar.pdb -p c:\\foobar\n"),
stdout
);
}
// CTraceViewApp message handlers
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
public:
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// App command to run the dialog
void CTraceViewApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
// CTraceViewApp message handlers
CTraceMessage * CTraceViewApp::AllocateTraceEventBlock()
{
CTraceMessage *pTraceMessage = NULL;
//
// Get the array protection
//
WaitForSingleObject(m_hTraceBlockMutex, INFINITE);
if(m_traceBlockArray.GetSize()) {
ASSERT(FALSE);
pTraceMessage = m_traceBlockArray.GetAt(0);
m_traceBlockArray.RemoveAt(0);
} else {
pTraceMessage = new CTraceMessage();
}
//
// Release the array protection
//
ReleaseMutex(m_hTraceBlockMutex);
return pTraceMessage;
}
void CTraceViewApp::FreeTraceEventBlocks(CArray<CTraceMessage*, CTraceMessage*> &TraceArray)
{
//
// Get the free array protection
//
WaitForSingleObject(m_hTraceBlockMutex, INFINITE);
m_traceBlockArray.Append(TraceArray);
TraceArray.RemoveAll();
//
// Release the free array protection
//
ReleaseMutex(m_hTraceBlockMutex);
}
BOOL CTraceViewApp::OnIdle(LONG lCount)
{
CTraceMessage *pTraceMessage = NULL;
//
// Get the free array protection
//
WaitForSingleObject(m_hTraceBlockMutex, INFINITE);
for(LONG ii = 0; ii < 1000; ii++) {
if(m_traceBlockArray.GetSize() < 100) {
break;
}
//
// Get the next entry from the list
//
pTraceMessage = m_traceBlockArray.GetAt(0);
m_traceBlockArray.RemoveAt(0);
delete pTraceMessage;
}
//
// Release the free array protection
//
ReleaseMutex(m_hTraceBlockMutex);
return CWinApp::OnIdle(lCount);
}
void CTraceViewApp::PrintLoggerStatus(ULONG Status)
{
LPTSTR loggerName;
LPTSTR LogFileName;
CString errorMsg;
if ((m_pLoggerInfo->LoggerNameOffset > 0) &&
(m_pLoggerInfo->LoggerNameOffset < m_pLoggerInfo->Wnode.BufferSize)) {
loggerName = (LPTSTR) ((char*)m_pLoggerInfo +
m_pLoggerInfo->LoggerNameOffset);
}
else loggerName = NULL;
if ((m_pLoggerInfo->LogFileNameOffset > 0) &&
(m_pLoggerInfo->LogFileNameOffset < m_pLoggerInfo->Wnode.BufferSize)) {
LogFileName = (LPTSTR) ((char*)m_pLoggerInfo +
m_pLoggerInfo->LogFileNameOffset);
}
else LogFileName = NULL;
_tprintf(_T("Operation Status: %uL\t"), Status);
_tprintf(_T("%s\n"), DecodeStatus(Status));
_tprintf(_T("Logger Name: %s\n"),
(loggerName == NULL) ?
_T(" ") : loggerName);
// end_sdk
if (loggerName == NULL || !_tcscmp(loggerName, _T("GlobalLogger"))) {
// Logger ID
_tprintf(_T("Status: %s\n"),
m_globalLoggerStartValue ?
_T("Registry set to start") : _T("Registry set to stop"));
_tprintf(_T("Logger Id: %I64x\n"), m_pLoggerInfo->Wnode.HistoricalContext);
_tprintf(_T("Logger Thread Id: %p\n"), m_pLoggerInfo->LoggerThreadId);
if (m_pLoggerInfo->BufferSize == 0)
_tprintf(_T("Buffer Size: default value\n"));
else
_tprintf(_T("Buffer Size: %d Kb\n"), m_pLoggerInfo->BufferSize);
if (m_pLoggerInfo->MaximumBuffers == 0)
_tprintf(_T("Maximum Buffers: default value\n"));
else
_tprintf(_T("Maximum Buffers: %d\n"), m_pLoggerInfo->MaximumBuffers);
if (m_pLoggerInfo->MinimumBuffers == 0)
_tprintf(_T("Minimum Buffers: default value\n"));
else
_tprintf(_T("Minimum Buffers: %d\n"), m_pLoggerInfo->MinimumBuffers);
_tprintf(_T("Number of Buffers: %d\n"), m_pLoggerInfo->NumberOfBuffers);
_tprintf(_T("Free Buffers: %d\n"), m_pLoggerInfo->FreeBuffers);
_tprintf(_T("Buffers Written: %d\n"), m_pLoggerInfo->BuffersWritten);
_tprintf(_T("Events Lost: %d\n"), m_pLoggerInfo->EventsLost);
_tprintf(_T("Log Buffers Lost: %d\n"), m_pLoggerInfo->LogBuffersLost);
_tprintf(_T("Real Time Buffers Lost: %d\n"), m_pLoggerInfo->RealTimeBuffersLost);
_tprintf(_T("AgeLimit: %d\n"), m_pLoggerInfo->AgeLimit);
if (LogFileName == NULL) {
_tprintf(_T("Buffering Mode: "));
}
else {
_tprintf(_T("Log File Mode: "));
}
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_APPEND) {
_tprintf(_T("Append "));
}
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
_tprintf(_T("Circular\n"));
}
else if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
_tprintf(_T("Sequential\n"));
}
else {
_tprintf(_T("Sequential\n"));
}
if (m_pLoggerInfo->MaximumFileSize > 0) {
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_KBYTES_FOR_SIZE)
_tprintf(_T("Maximum File Size: %d Kb\n"), m_pLoggerInfo->MaximumFileSize);
else
_tprintf(_T("Maximum File Size: %d Mb\n"), m_pLoggerInfo->MaximumFileSize);
}
if (m_pLoggerInfo->FlushTimer > 0)
_tprintf(_T("Buffer Flush Timer: %d secs\n"), m_pLoggerInfo->FlushTimer);
if (m_pLoggerInfo->EnableFlags != 0) {
_tprintf(_T("Enabled tracing: "));
if ((loggerName != NULL) && (!_tcscmp(loggerName, KERNEL_LOGGER_NAME))) {
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
_tprintf(_T("Process "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
_tprintf(_T("Thread "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
_tprintf(_T("Disk "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
_tprintf(_T("File "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
_tprintf(_T("PageFaults "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
_tprintf(_T("HardFaults "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
_tprintf(_T("ImageLoad "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
_tprintf(_T("TcpIp "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_REGISTRY)
_tprintf(_T("Registry "));
}
else {
_tprintf(_T("0x%08x"), m_pLoggerInfo->EnableFlags );
}
_tprintf(_T("\n"));
}
if (LogFileName == NULL || _tcslen(LogFileName) == 0) {
_tprintf(_T("Log Filename: default location\n"));
_tprintf(_T(" %%SystemRoot%%\\System32\\LogFiles\\WMI\\trace.log\n"));
}
else
_tprintf(_T("Log Filename: %s\n"), LogFileName);
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_LOCAL_SEQUENCE) {
_tprintf(_T("Local Sequence numbers in use\n"));
}
else if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_GLOBAL_SEQUENCE) {
_tprintf(_T("Global Sequence numbers in use\n"));
}
}
else {
// begin_sdk
_tprintf(_T("Logger Id: %I64x\n"), m_pLoggerInfo->Wnode.HistoricalContext);
_tprintf(_T("Logger Thread Id: %p\n"), m_pLoggerInfo->LoggerThreadId);
if (Status != 0)
return;
_tprintf(_T("Buffer Size: %d Kb"), m_pLoggerInfo->BufferSize);
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_PAGED_MEMORY) {
_tprintf(_T(" using paged memory\n"));
}
else {
_tprintf(_T("\n"));
}
_tprintf(_T("Maximum Buffers: %d\n"), m_pLoggerInfo->MaximumBuffers);
_tprintf(_T("Minimum Buffers: %d\n"), m_pLoggerInfo->MinimumBuffers);
_tprintf(_T("Number of Buffers: %d\n"), m_pLoggerInfo->NumberOfBuffers);
_tprintf(_T("Free Buffers: %d\n"), m_pLoggerInfo->FreeBuffers);
_tprintf(_T("Buffers Written: %d\n"), m_pLoggerInfo->BuffersWritten);
_tprintf(_T("Events Lost: %d\n"), m_pLoggerInfo->EventsLost);
_tprintf(_T("Log Buffers Lost: %d\n"), m_pLoggerInfo->LogBuffersLost);
_tprintf(_T("Real Time Buffers Lost: %d\n"), m_pLoggerInfo->RealTimeBuffersLost);
_tprintf(_T("AgeLimit: %d\n"), m_pLoggerInfo->AgeLimit);
if (LogFileName == NULL) {
_tprintf(_T("Buffering Mode: "));
}
else {
_tprintf(_T("Log File Mode: "));
}
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_APPEND) {
_tprintf(_T("Append "));
}
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_CIRCULAR) {
_tprintf(_T("Circular\n"));
}
else if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
_tprintf(_T("Sequential\n"));
}
else {
_tprintf(_T("Sequential\n"));
}
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_REAL_TIME_MODE) {
_tprintf(_T("Real Time mode enabled"));
// end_sdk
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_BUFFERING_MODE) {
_tprintf(_T(": buffering only"));
}
// begin_sdk
_tprintf(_T("\n"));
}
if (m_pLoggerInfo->MaximumFileSize > 0) {
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_KBYTES_FOR_SIZE)
_tprintf(_T("Maximum File Size: %d Kb\n"), m_pLoggerInfo->MaximumFileSize);
else
_tprintf(_T("Maximum File Size: %d Mb\n"), m_pLoggerInfo->MaximumFileSize);
}
if (m_pLoggerInfo->FlushTimer > 0)
_tprintf(_T("Buffer Flush Timer: %d secs\n"), m_pLoggerInfo->FlushTimer);
if (m_pLoggerInfo->EnableFlags != 0) {
_tprintf(_T("Enabled tracing: "));
if ((loggerName != NULL) && (!_tcscmp(loggerName, KERNEL_LOGGER_NAME))) {
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_PROCESS)
_tprintf(_T("Process "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_THREAD)
_tprintf(_T("Thread "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_IO)
_tprintf(_T("Disk "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_DISK_FILE_IO)
_tprintf(_T("File "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS)
_tprintf(_T("PageFaults "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS)
_tprintf(_T("HardFaults "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_IMAGE_LOAD)
_tprintf(_T("ImageLoad "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_NETWORK_TCPIP)
_tprintf(_T("TcpIp "));
if (m_pLoggerInfo->EnableFlags & EVENT_TRACE_FLAG_REGISTRY)
_tprintf(_T("Registry "));
}else{
_tprintf(_T("0x%08x"), m_pLoggerInfo->EnableFlags );
}
_tprintf(_T("\n"));
}
if (LogFileName != NULL) {
_tprintf(_T("Log Filename: %s\n"), LogFileName);
}
// end_sdk
if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_LOCAL_SEQUENCE) {
_tprintf(_T("Local Sequence numbers in use\n"));
}
else if (m_pLoggerInfo->LogFileMode & EVENT_TRACE_USE_GLOBAL_SEQUENCE) {
_tprintf(_T("Global Sequence numbers in use\n"));
}
}
// begin_sdk
}
LPCTSTR CTraceViewApp::DecodeStatus(ULONG Status)
{
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
Status,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
m_errorMsg.GetBuffer(MAX_STR_LENGTH),
MAX_STR_LENGTH,
NULL );
return m_errorMsg;
}
LONG CTraceViewApp::GetGuids(LPCTSTR GuidFile)
{
FILE *f;
TCHAR line[MAX_STR_LENGTH];
TCHAR arg[MAX_STR_LENGTH];
LPGUID guid;
int i;
int n;
f = _tfopen(GuidFile, _T("r"));
if(f == NULL) {
return -1;
}
n = 0;
while(_fgetts(line, MAX_STR_LENGTH, f) != NULL) {
if (_tcslen(line) < 36)
continue;
if (line[0] == ';' ||
line[0] == '\0' ||
line[0] == '#' ||
line[0] == '/')
continue;
n ++;
m_guidArray.Add(line);
}
fclose(f);
return (ULONG)n;
}
void CTraceViewApp::DisplayVersionInfo()
{
TCHAR buffer[512];
TCHAR strProgram[MAXSTR];
DWORD dw;
BYTE* pVersionInfo;
LPTSTR pVersion = NULL;
LPTSTR pProduct = NULL;
LPTSTR pCopyRight = NULL;
if ((dw = GetModuleFileName(NULL, strProgram, MAXSTR)) == MAXSTR) {
strProgram[MAXSTR-1] = _T('\0');
}
if( dw>0 ){
dw = GetFileVersionInfoSize( strProgram, &dw );
if( dw > 0 ){
pVersionInfo = (BYTE*)malloc(dw);
if( NULL != pVersionInfo ){
if(GetFileVersionInfo( strProgram, 0, dw, pVersionInfo )){
LPDWORD lptr = NULL;
VerQueryValue( pVersionInfo, _T("\\VarFileInfo\\Translation"), (void**)&lptr, (UINT*)&dw );
if( lptr != NULL ){
_stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("ProductVersion") );
VerQueryValue( pVersionInfo, buffer, (void**)&pVersion, (UINT*)&dw );
_stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("OriginalFilename") );
VerQueryValue( pVersionInfo, buffer, (void**)&pProduct, (UINT*)&dw );
_stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("LegalCopyright") );
VerQueryValue( pVersionInfo, buffer, (void**)&pCopyRight, (UINT*)&dw );
}
if( pProduct != NULL && pVersion != NULL && pCopyRight != NULL ){
_tprintf( _T("\nMicrosoft (R) %s (%s)\n%s\n\n"), pProduct, pVersion, pCopyRight );
}
}
free( pVersionInfo );
}
}
}
}
BOOL CTraceViewApp::CheckFile(LPTSTR fileName)
{
HANDLE hFile;
BYTE LogHeaderBuffer[DEFAULT_LOG_BUFFER_SIZE];
ULONG nBytesRead ;
ULONG hResult ;
PEVENT_TRACE pEvent;
PTRACE_LOGFILE_HEADER logfileHeader ;
LARGE_INTEGER lFileSize ;
LARGE_INTEGER lFileSizeMB ;
DWORD dwDesiredAccess , dwShareMode ;
FILETIME stdTime, localTime, endlocalTime, endTime;
SYSTEMTIME sysTime, endsysTime;
PEVENT_TRACE_LOGFILE pLogBuffer ;
if (m_bFixUp) {
dwShareMode = 0 ;
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE ;
} else {
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ;
dwDesiredAccess = GENERIC_READ ;
}
hFile = CreateFile(
fileName,
dwDesiredAccess,
dwShareMode,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
if (m_bFixUp) {
_tprintf(_T("ERROR: Fixup could not open file, Error = 0x%X\n"),GetLastError());
exit(GetLastError());
}
return(FALSE);
}
// While we are here we will look to see if the file is ok and fix up
// Circular buffer anomolies
if (((hResult = ReadFile(hFile,
(LPVOID)LogHeaderBuffer,
DEFAULT_LOG_BUFFER_SIZE,
&nBytesRead,
NULL)) == 0) || nBytesRead < DEFAULT_LOG_BUFFER_SIZE) {
_tprintf(_T("ERROR: Fixup could not read file, Error = 0x%X, bytes read = %d(of %d)\n"),
GetLastError(),nBytesRead,DEFAULT_LOG_BUFFER_SIZE);
exit(ERROR_BAD_ARGUMENTS);
}
pEvent = (PEVENT_TRACE)LogHeaderBuffer ;
logfileHeader = (PTRACE_LOGFILE_HEADER)&LogHeaderBuffer[sizeof(WMI_BUFFER_HEADER) +
sizeof(SYSTEM_TRACE_HEADER)];
if (m_bVerbose) {
_tprintf(_T("Dumping Logfile Header\n"));
RtlCopyMemory(&stdTime , &(logfileHeader->StartTime), sizeof(FILETIME));
FileTimeToLocalFileTime(&stdTime, &localTime);
FileTimeToSystemTime(&localTime, &sysTime);
RtlCopyMemory(&endTime , &(logfileHeader->EndTime), sizeof(FILETIME));
FileTimeToLocalFileTime(&endTime, &endlocalTime);
FileTimeToSystemTime(&endlocalTime, &endsysTime);
_tprintf(_T("\tStart Time %02d/%02d/%04d-%02d:%02d:%02d.%03d\n"),
sysTime.wMonth,
sysTime.wDay,
sysTime.wYear,
sysTime.wHour,
sysTime.wMinute,
sysTime.wSecond,
sysTime.wMilliseconds);
_tprintf(_T("\tBufferSize %d\n"),
logfileHeader->BufferSize);
_tprintf(_T("\tVersion %d\n"),
logfileHeader->Version);
_tprintf(_T("\tProviderVersion %d\n"),
logfileHeader->ProviderVersion);
_tprintf(_T("\tEnd Time %02d/%02d/%04d-%02d:%02d:%02d.%03d\n"),
endsysTime.wMonth,
endsysTime.wDay,
endsysTime.wYear,
endsysTime.wHour,
endsysTime.wMinute,
endsysTime.wSecond,
endsysTime.wMilliseconds);
_tprintf(_T("\tTimer Resolution %d\n"),
logfileHeader->TimerResolution);
_tprintf(_T("\tMaximum File Size %d\n"),
logfileHeader->MaximumFileSize);
_tprintf(_T("\tBuffers Written %d\n"),
logfileHeader->BuffersWritten);
/*
_tprintf(_T("\tLogger Name %ls\n"),
logfileHeader->LoggerName);
_tprintf(_T("\tLogfile Name %ls\n"),
logfileHeader->LogFileName);
*/
_tprintf(_T("\tTimezone is %s (Bias is %dmins)\n"),
logfileHeader->TimeZone.StandardName,logfileHeader->TimeZone.Bias);
_tprintf(_T("\tLogfile Mode %X "),
logfileHeader->LogFileMode);
if (logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_NONE) {
_tprintf(_T("Logfile is off(?)\n"));
} else if (logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_SEQUENTIAL) {
_tprintf(_T("Logfile is sequential\n"));
} else if (logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_CIRCULAR) {
_tprintf(_T("Logfile is circular\n"));
}
_tprintf(_T("\tProcessorCount %d\n"),
logfileHeader->NumberOfProcessors);
}
if (GetFileSizeEx(hFile, &lFileSize) == 0) {
_tprintf(_T("WARNING: Could not get file size, continuing\n"));
} else {
lFileSizeMB.QuadPart = lFileSize.QuadPart / (1024*1024) ;
if (lFileSizeMB.QuadPart > logfileHeader->MaximumFileSize) {
_tprintf(_T("WARNING: File size given as %dMB, should be %dMB\n"),
logfileHeader->MaximumFileSize,lFileSizeMB.QuadPart);
if (lFileSize.HighPart != 0) {
_tprintf(_T("WARNING: Log file is TOO big"));
}
if (m_bFixUp) {
logfileHeader->MaximumFileSize = lFileSizeMB.LowPart + 1 ;
}
}
}
if ((logfileHeader->LogFileMode == EVENT_TRACE_FILE_MODE_CIRCULAR) &&
(logfileHeader->BuffersWritten== 0 )) {
_tprintf(_T("WARNING: Circular Trace File did not have 'wrap' address\n"));
if (m_bFixUp) {
// Figure out the wrap address
INT LowBuff = 1, HighBuff, CurrentBuff, MaxBuff ;
FILETIME LowTime, HighTime, CurrentTime, MaxTime ;
if (lFileSize.HighPart != 0) {
_tprintf(_T("ERROR: File TOO big\n"));
exit(-1);
}
MaxBuff = (LONG)(lFileSize.QuadPart / logfileHeader->BufferSize) - 1 ;
_tprintf(_T("MaxBuff=%d\n"),MaxBuff);
pLogBuffer = (PEVENT_TRACE_LOGFILE)malloc(logfileHeader->BufferSize);
if (SetFilePointer(hFile,0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
_tprintf(_T("ERROR: Could not reset file to beginning for FixUp, Error = 0x%X"),
GetLastError());
exit(GetLastError());
}
for (CurrentBuff = 1 ; CurrentBuff <= MaxBuff; CurrentBuff++) {
if (SetFilePointer(hFile,logfileHeader->BufferSize, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) {
_tprintf(_T("ERROR: Could not set file to next buffer for FixUp, Error = 0x%X"),
GetLastError());
exit(GetLastError());
}
hResult = ReadFile(hFile,
(LPVOID)pLogBuffer,
logfileHeader->BufferSize,
&nBytesRead,
NULL);
BufferCallback((PEVENT_TRACE_LOGFILE)pLogBuffer);
}
}
}
if (m_bFixUp) {
if (SetFilePointer(hFile,0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
_tprintf(_T("ERROR: Could not reset file to beginning for FixUp, Error = 0x%X"),
GetLastError());
exit(GetLastError());
}
logfileHeader->BuffersWritten = m_bufferWrap;
if (!WriteFile(hFile,(LPVOID)LogHeaderBuffer,DEFAULT_LOG_BUFFER_SIZE,&nBytesRead, NULL)) {
_tprintf(_T("ERROR: Could not Write file for FixUp, Error = 0x%X"),
GetLastError());
exit(GetLastError());
}
_tprintf(_T("INFO: Buffer Wrap reset to %d\n"), m_bufferWrap);
}
CloseHandle(hFile);
return (TRUE);
}
ULONG CTraceViewApp::BufferCallback(PEVENT_TRACE_LOGFILE pLog)
{
ULONG i;
ULONG Status;
EVENT_TRACE_PROPERTIES LoggerProp;
CTraceViewApp *pApp = (CTraceViewApp *)AfxGetApp();
pApp->m_totalBuffersRead++;
pApp->m_totalEventsLost += pLog->EventsLost;
if (pApp->m_bVerbose) {
FILETIME stdTime, localTime;
SYSTEMTIME sysTime;
RtlCopyMemory(&stdTime , &pLog->CurrentTime, sizeof(FILETIME));
FileTimeToSystemTime(&stdTime, &sysTime);
_tprintf(_T("%02d/%02d/%04d-%02d:%02d:%02d.%03d :: %8d: Filled=%8d, Lost=%3d"),
sysTime.wMonth,
sysTime.wDay,
sysTime.wYear,
sysTime.wHour,
sysTime.wMinute,
sysTime.wSecond,
sysTime.wMilliseconds,
pApp->m_totalBuffersRead,
pLog->Filled,
pLog->EventsLost);
_tprintf(_T(" TotalLost= %d\r"), pApp->m_totalEventsLost);
if (CompareFileTime(&pApp->m_lastTime,&stdTime) == 1) {
_tprintf(_T("\nWARNING: time appears to have wrapped here (Block = %d)!\n"), pApp->m_totalBuffersRead);
pApp->m_bufferWrap = pApp->m_totalBuffersRead;
}
pApp->m_lastTime = stdTime ;
}
return (TRUE);
}
void CTraceViewApp::DumpEvent(PEVENT_TRACE pEvent)
{
CTraceViewApp *pApp = (CTraceViewApp *)AfxGetApp();
pApp->m_totalEventCount++;
if (pEvent == NULL) {
_tprintf(_T("pEvent is NULL\n"));
return;
}
// DumpEvent() is only a wrapper, it calls FormatTraceEvent() in TracePrt.
//
if (FormatTraceEvent(pApp->m_eventListHead, pEvent, pApp->m_eventBuf, SIZEEVENTBUF, NULL) > 0)
{
TCHAR * eventBufWork = &pApp->m_eventBuf[0] ;
#ifdef UNICODE
//sprintf(_T("Name,\"SubName(File+line#)\",ThreadID,ProcessId,SequenceNumber,CPUNumber,Indent,Function,Component,TraceLevel,TraceFlags,Text\n"));
if (pApp->m_bCSVMode) {
PSTRUCTUREDMESSAGE pStructuredMessage = (PSTRUCTUREDMESSAGE)&pApp->m_eventBuf[0];
/* if (fCSVHeader && fNoCSVHeader) {
fCSVHeader = FALSE ;
_stprintf((TCHAR *)pApp->m_eventBufCSV,_T("GUIDname,TypeName,ThreadId,ProcessId,SequenceNum,CpuNumber,Indent,CompnentName,SubComponentName,FunctionName,LevelName,FlagsName, String"));
} */
_stprintf((TCHAR *)pApp->m_eventBufCSV,_T("%s,%s,%08X,%08X,%d,%d,%d,%s,%s,%s,%s,%s,\"%s\""),
(pStructuredMessage->GuidName?&pApp->m_eventBuf[pStructuredMessage->GuidName/sizeof(TCHAR)]:_T("")),
(pStructuredMessage->GuidTypeName?&pApp->m_eventBuf[pStructuredMessage->GuidTypeName/sizeof(TCHAR)]:_T("")),
pStructuredMessage->ThreadId,
pStructuredMessage->ProcessId,
pStructuredMessage->SequenceNum,
pStructuredMessage->CpuNumber,
pStructuredMessage->Indent,
(pStructuredMessage->ComponentName?&pApp->m_eventBuf[pStructuredMessage->ComponentName/sizeof(TCHAR)]:_T("")),
(pStructuredMessage->SubComponentName?&pApp->m_eventBuf[pStructuredMessage->SubComponentName/sizeof(TCHAR)]:_T("")),
(pStructuredMessage->FunctionName?&pApp->m_eventBuf[pStructuredMessage->FunctionName/sizeof(TCHAR)]:_T("")),
(pStructuredMessage->LevelName?&pApp->m_eventBuf[pStructuredMessage->LevelName/sizeof(TCHAR)]:_T("")),
(pStructuredMessage->FlagsName?&pApp->m_eventBuf[pStructuredMessage->FlagsName/sizeof(TCHAR)]:_T("")),
(pStructuredMessage->FormattedString?&pApp->m_eventBuf[pStructuredMessage->FormattedString/sizeof(TCHAR)]:_T("")));
eventBufWork = (TCHAR *)&pApp->m_eventBufCSV[0] ;
}
//
// Convert Unicode to MultiByte
//
if (WideCharToMultiByte(GetConsoleOutputCP(),
0,
eventBufWork,
-1,
pApp->m_eventBufA,
SIZEEVENTBUF * sizeof(WCHAR),
NULL,
NULL ) == 0 )
{
//
// do nothing, let the _ftprintf handle it.
//
}
else
{
if (!pApp->m_bSummaryOnly && !pApp->m_bDisplayOnly) {
fprintf(pApp->m_pDumpFile, "%s\n", pApp->m_eventBufA);
}
if (pApp->m_bDebugDisplay || pApp->m_bDisplayOnly) {
if (pApp->m_bODSOutput) {
OutputDebugStringA(pApp->m_eventBufA);
OutputDebugStringA("\n");
} else {
printf("%s\n", pApp->m_eventBufA);
}
}
return ;
}
#endif
if (!pApp->m_bSummaryOnly && !pApp->m_bDisplayOnly) {
_ftprintf(pApp->m_pDumpFile, _T("%s\n"),pApp->m_eventBuf);
}
if (pApp->m_bDebugDisplay || pApp->m_bDisplayOnly) {
if (pApp->m_bODSOutput) {
OutputDebugString(pApp->m_eventBuf);
OutputDebugString(_T("\n"));
} else {
_tprintf(_T("%s\n"),pApp->m_eventBuf);
}
}
}
}
void CTraceViewApp::OnHelpHelpTopics()
{
::HtmlHelp(
0,
_T("traceview.chm"),
HH_DISPLAY_TOC,
NULL);
}