INIT.C

/*++ 

Copyright 1995 - 1998 Microsoft Corporation

Module Name:

init.c

Abstract:

This is the initialization module for the pfmon program.

Author:

Mark Lucovsky (markl) 26-Jan-1995

Revision History:

--*/

#include "pfmonp.h"

BOOL
InitializePfmon( VOID )
{
LPTSTR CommandLine;
BOOL fShowUsage;
DWORD Pid = 0;

fShowUsage = FALSE;
CommandLine = GetCommandLine();
while (*CommandLine > ' ') {
CommandLine += 1;
}
while (TRUE) {
while (*CommandLine <= ' ') {
if (*CommandLine == '\0') {
break;
} else {
CommandLine += 1;
}
}

if (!strnicmp( CommandLine, "/v", 2 ) || !strnicmp( CommandLine, "-v", 2 )) {
CommandLine += 2;
fVerbose = TRUE;
} else if (!strnicmp( CommandLine, "/?", 2 ) || !strnicmp( CommandLine, "-?", 2 )) {
CommandLine += 2;
fShowUsage = TRUE;
goto showusage;
} else if (!strnicmp( CommandLine, "/c", 2 ) || !strnicmp( CommandLine, "-c", 2 )) {
CommandLine += 2;
fCodeOnly = TRUE;
} else if (!strnicmp( CommandLine, "/h", 2 ) || !strnicmp( CommandLine, "-h", 2 )) {
CommandLine += 2;
fHardOnly = TRUE;
} else if (!strnicmp( CommandLine, "/n", 2 ) || !strnicmp( CommandLine, "-n", 2 )) {
CommandLine += 2;
LogFile = fopen("pfmon.log","wt");
fLogOnly = TRUE;
} else if (!strnicmp( CommandLine, "/l", 2 ) || !strnicmp( CommandLine, "-l", 2 )) {
CommandLine += 2;
LogFile = fopen("pfmon.log","wt");
} else if (!strnicmp( CommandLine, "/p", 2 ) || !strnicmp( CommandLine, "-p", 2 )) {
CommandLine += 2;
while (*CommandLine <= ' ') {
if (*CommandLine == '\0') {
break;
} else {
++CommandLine;
}
}
Pid = atoi(CommandLine);
CommandLine = strchr(CommandLine,' ');
if (CommandLine==NULL) {
break;
}
} else if (!strnicmp( CommandLine, "/d", 2 ) || !strnicmp( CommandLine, "-d", 2 )) {
CommandLine += 2;
fDatabase = TRUE;
} else {
break;
}
}
showusage:
if ( fShowUsage ) {
fprintf(stdout,"Usage: PFMON [switches] application-command-line\n");
fprintf(stdout," [-?] display this message\n");
fprintf(stdout," [-n] don't display running faults, just log to pfmon.log\n");
fprintf(stdout," [-l] log faults to pfmon.log\n");
fprintf(stdout," [-c] only show code faults\n");
fprintf(stdout," [-h] only show hard faults\n");
fprintf(stdout," [-p pid] attach to existing process\n");
fprintf(stdout," [-d] Database format (tab delimited)\n");
fprintf(stdout," format: pagefault number, Page Fault type (Hard or Soft),\n");
fprintf(stdout," Program Counter's Module, Symbol for PC, Decimal value of PC,\n");
fprintf(stdout," Decimal value of PC, Module of the virtual address accessed,\n");
fprintf(stdout," Symbol for VA, value of VA\n");
return FALSE;
};

InitializeListHead( &ProcessListHead );
InitializeListHead( &ModuleListHead );
SetSymbolSearchPath();

PfmonModuleHandle = GetModuleHandle( NULL );

if (Pid != 0) {
return(AttachApplicationForDebug(Pid));
} else {
return (LoadApplicationForDebug( CommandLine ));
}

return TRUE;
}

BOOL
LoadApplicationForDebug(
LPSTR CommandLine
)
{
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;

ZeroMemory( &StartupInfo, sizeof( StartupInfo ) );
StartupInfo.cb = sizeof(StartupInfo);

if (!CreateProcess( NULL,
CommandLine,
NULL,
NULL,
FALSE, // No handles to inherit
DEBUG_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInformation)) {
DeclareError( PFMON_CANT_DEBUG_PROGRAM,
GetLastError(),
CommandLine
);
return FALSE;
} else {
hProcess = ProcessInformation.hProcess;
SymInitialize(hProcess,NULL,FALSE);

return InitializeProcessForWsWatch(hProcess);
}
}

BOOL
AttachApplicationForDebug(
DWORD Pid
)
{

if (!DebugActiveProcess(Pid)) {
DeclareError( PFMON_CANT_DEBUG_ACTIVE_PROGRAM,
GetLastError(),
Pid );
return FALSE;
} else {
hProcess = OpenProcess(PROCESS_VM_READ
| PROCESS_QUERY_INFORMATION
| PROCESS_SET_INFORMATION,
FALSE,
Pid);
SymInitialize(hProcess,NULL,FALSE);

return InitializeProcessForWsWatch(hProcess);
}
}