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.
1520 lines
44 KiB
1520 lines
44 KiB
//+-------------------------------------------------------------------
|
|
// Microsoft OLE
|
|
// Copyright (C) Microsoft Corporation, 1994-1995.
|
|
//
|
|
// File: cdbghelp.cxx
|
|
//
|
|
// Contents: OLE Debug Helper Object
|
|
//
|
|
// Classes: CDebugHelper
|
|
//
|
|
// History: 19-Nov-94 DeanE Created
|
|
//---------------------------------------------------------------------
|
|
#include <dfheader.hxx>
|
|
#pragma hdrstop
|
|
|
|
|
|
// Global library character constants - note alphabetical order for
|
|
// easy reference
|
|
//
|
|
CONST TCHAR chBackSlash = TEXT('\\');
|
|
CONST TCHAR chEqual = TEXT('=');
|
|
CONST TCHAR chNewLine = TEXT('\n');
|
|
CONST TCHAR chNull = TEXT('\0');
|
|
CONST TCHAR chPeriod = TEXT('.');
|
|
CONST TCHAR chSpace = TEXT(' ');
|
|
CONST TCHAR chTrace = TEXT(' ');
|
|
CONST TCHAR chTraceErr = TEXT('e');
|
|
|
|
// Global library string contants - note alphabetical order for
|
|
// easy reference
|
|
//
|
|
CONST TCHAR szCRLF[] = TEXT("\r\n");
|
|
CONST TCHAR szError[] = TEXT("ERROR "); // Used TraceMsg for ERRORs
|
|
CONST TCHAR szNewLine[] = TEXT("\n");
|
|
CONST TCHAR szNull[] = TEXT("");
|
|
CONST TCHAR szPeriod[] = TEXT(".");
|
|
|
|
|
|
// Test Result Description strings
|
|
//
|
|
LPCTSTR szPass = TEXT("VAR_PASS");
|
|
LPCTSTR szFail = TEXT("VAR_FAIL");
|
|
LPCTSTR szAbort = TEXT("VAR_ABORT");
|
|
LPCTSTR szWarn = TEXT("WARNING");
|
|
LPCTSTR szInfo = TEXT("INFO");
|
|
LPCTSTR szInvalid = TEXT("INVALID!!");
|
|
|
|
// Debug Helper Usage String
|
|
//
|
|
LPTSTR gptszDebugHelperUsageString = {
|
|
TEXT("Debug Object Command line options:\r\n")
|
|
TEXT(" /logloc - where log output goes (bitfield)\r\n")
|
|
TEXT(" /traceloc - where trace output goes (bitfield)\r\n")
|
|
TEXT(" /tracelvl - trace levels (bitfield)\r\n")
|
|
TEXT(" /spyclass - spy window\r\n")
|
|
TEXT(" /labmode - do not use PopUp for errors\r\n")
|
|
TEXT(" /breakmode - break on error\r\n")
|
|
TEXT(" /verbose - trace hrchecks that are ok\r\n")
|
|
};
|
|
|
|
int giAlwaysNegativeOne = -1;
|
|
|
|
// Global variable, the THREAD_VALIDATE_FLAG_ON bit of which at present is
|
|
// used to do or skip thread validation DH_VDATETHREAD macro. Other bits
|
|
// might be used in future. Initialize the variable to set its bit
|
|
// THREAD_VALIDATE_FLAG_ON.
|
|
|
|
ULONG g_fThreadValidate = THREAD_VALIDATE_FLAG_ON ;
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::CDebugHelp
|
|
//
|
|
// Synopsis: Initializes CDebugHelp object. Makes object usable
|
|
// in it's default state.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: Nothing. Constructor cannot fail.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
CDebugHelp::CDebugHelp() :
|
|
_fLogLoc(DH_LOC_TERM),
|
|
_fTraceLoc(DH_LOC_TERM),
|
|
_fTraceLvl(DH_LVL_ALWAYS|DH_LVL_ERROR),
|
|
_fMode(DH_LABMODE),
|
|
_hrExpectedError(S_OK),
|
|
_fCreatedLog(FALSE),
|
|
_plog(NULL),
|
|
_hwndAssert(NULL),
|
|
_cPass(0),
|
|
_cAbort(0),
|
|
_cFail(0),
|
|
_cIndentLevel(0),
|
|
_fSpyWarning(0),
|
|
_pszSpyWindowClass((LPTSTR) SZ_DEFAULT_SPY_WINDOW_CLASS)
|
|
{
|
|
DWORD cchModule;
|
|
TCHAR szModule[CCH_MAX_MODULE];
|
|
TCHAR szModule1[CCH_MAX_MODULE];
|
|
short ret=0;
|
|
|
|
lstrcpy(_szDbgPrefix, TEXT("NoName"));
|
|
|
|
// Initialize the debug prefix string - it is the first
|
|
// CCH_MAX_DBGPREFIX characters in the name of this
|
|
// .exe, without the extension
|
|
//
|
|
|
|
cchModule = GetModuleFileName(NULL, szModule1, CCH_MAX_MODULE);
|
|
|
|
if ((0 != cchModule) && (cchModule < CCH_MAX_MODULE))
|
|
{
|
|
ret = GetFileTitle(szModule1, szModule, sizeof(szModule));
|
|
|
|
if (0 == ret)
|
|
{
|
|
//
|
|
// Strip the .exe extension if it exists
|
|
//
|
|
|
|
cchModule = _tcslen(szModule);
|
|
|
|
if (cchModule >= 4) // if the name has at least 4 chars
|
|
{
|
|
if (0 == _tcsicmp(szModule + cchModule - 4, TEXT(".exe")))
|
|
{
|
|
szModule[cchModule - 4] = TEXT('\0');
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save the module name as the debug prefix
|
|
//
|
|
|
|
_tcscpy(_szDbgPrefix, szModule);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::~CDebugHelp
|
|
//
|
|
// Synopsis: Releases resources associated with the CDebugHelp class.
|
|
// Sets member variables so the basic functions can work.
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
CDebugHelp::~CDebugHelp()
|
|
{
|
|
// Set all member variables to valid default values
|
|
_fLogLoc = DH_LOC_TERM;
|
|
_fTraceLoc = DH_LOC_TERM;
|
|
_fTraceLvl = DH_LVL_ALWAYS|DH_LVL_ERROR;
|
|
_fMode = DH_LABMODE;
|
|
|
|
// Close the log by deleting the log object, if we created it
|
|
if (_fCreatedLog)
|
|
{
|
|
delete _plog;
|
|
}
|
|
|
|
_plog = NULL;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::GetRegDbgInfo
|
|
//
|
|
// Synopsis: Initializes CDebugHelp object from the registry. Even
|
|
// if errors occur, the object is left in the usable
|
|
// default state.
|
|
//
|
|
// Arguments: [pszRegKey] - Registy key holding necessary values.
|
|
//
|
|
// Returns: S_OK if values read and settings are valid, an error
|
|
// code if not.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
HRESULT CDebugHelp::GetRegDbgInfo(LPTSTR pszRegKey)
|
|
{
|
|
CRegistryHelp *prhRegKey = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
DWORD fLabMode = TRUE;
|
|
DWORD fBreakMode= FALSE;
|
|
DWORD fVerbose = FALSE;
|
|
|
|
// Open the registry key
|
|
prhRegKey = new(NullOnFail) CRegistryHelp(
|
|
#ifndef _MAC
|
|
HKEY_CURRENT_USER,
|
|
#else // _MAC
|
|
HKEY_CLASSES_ROOT,
|
|
#endif // _MAC
|
|
pszRegKey,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ,
|
|
&hr);
|
|
if (prhRegKey == NULL)
|
|
{
|
|
hr = MAKE_TH_ERROR_CODE(E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
delete prhRegKey;
|
|
return(hr);
|
|
}
|
|
|
|
|
|
// Note: From this point, error returns don't mean return an
|
|
// error, but set the default and return
|
|
//
|
|
|
|
// Get Trace Location value
|
|
hr = prhRegKey->GetValueDword(
|
|
NULL,
|
|
SZ_REG_TRACE_LOC,
|
|
&_fTraceLoc,
|
|
REG_DWORD);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
_fTraceLoc = ValidateLoc(_fTraceLoc);
|
|
}
|
|
|
|
// Get Log Location value
|
|
hr = prhRegKey->GetValueDword(
|
|
NULL,
|
|
SZ_REG_LOG_LOC,
|
|
&_fLogLoc,
|
|
REG_DWORD);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
_fLogLoc = ValidateLoc(_fLogLoc);
|
|
}
|
|
|
|
// Get Trace Level
|
|
hr = prhRegKey->GetValueDword(
|
|
NULL,
|
|
SZ_REG_TRACE_LVL,
|
|
&_fTraceLvl,
|
|
REG_DWORD);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
_fTraceLvl = ValidateLvl(_fTraceLvl) | DH_LVL_ALWAYS | DH_LVL_ERROR;
|
|
}
|
|
|
|
// Get Mode
|
|
hr = prhRegKey->GetValueDword(
|
|
NULL,
|
|
SZ_REG_LABMODE,
|
|
&fLabMode,
|
|
REG_DWORD);
|
|
if (SUCCEEDED(hr) && fLabMode)
|
|
{
|
|
_fMode = DH_LABMODE;
|
|
}
|
|
|
|
hr = prhRegKey->GetValueDword(
|
|
NULL,
|
|
SZ_REG_BREAKMODE,
|
|
&fBreakMode,
|
|
REG_DWORD);
|
|
if (SUCCEEDED(hr) && fBreakMode)
|
|
{
|
|
_fMode |= DH_BREAKMODE;
|
|
}
|
|
|
|
hr = prhRegKey->GetValueDword(
|
|
NULL,
|
|
SZ_REG_VERBOSE,
|
|
&fVerbose,
|
|
REG_DWORD);
|
|
if (SUCCEEDED(hr) && fVerbose)
|
|
{
|
|
_fMode |= DH_VERBOSE;
|
|
}
|
|
|
|
_fMode = ValidateMode(_fMode);
|
|
|
|
// Clean up and exit
|
|
delete prhRegKey;
|
|
|
|
hr = S_OK;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::WriteRegDbgInfo
|
|
//
|
|
// Synopsis: Write the current state of the CDebugHelp object to
|
|
// the registry.
|
|
//
|
|
// Arguments: [pszRegKey] - Registy key to write to.
|
|
//
|
|
// Returns: S_OK if values written, an error code if not.
|
|
//
|
|
// History: 21-Apr-96 Kennethm Created
|
|
//--------------------------------------------------------------------
|
|
HRESULT CDebugHelp::WriteRegDbgInfo(LPTSTR pszRegKey)
|
|
{
|
|
CRegistryHelp *prhRegKey = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// Open the registry key
|
|
prhRegKey = new(NullOnFail) CRegistryHelp(
|
|
#ifndef _MAC
|
|
HKEY_CURRENT_USER,
|
|
#else // _MAC
|
|
HKEY_CLASSES_ROOT,
|
|
#endif // _MAC
|
|
pszRegKey,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_WRITE,
|
|
&hr);
|
|
if (prhRegKey == NULL)
|
|
{
|
|
hr = MAKE_TH_ERROR_CODE(E_OUTOFMEMORY);
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
delete prhRegKey;
|
|
return(hr);
|
|
}
|
|
|
|
|
|
// Write Trace Location value
|
|
hr = prhRegKey->SetValueDword(
|
|
NULL,
|
|
SZ_REG_TRACE_LOC,
|
|
_fTraceLoc,
|
|
REG_DWORD);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
// Write Log Location value
|
|
hr = prhRegKey->SetValueDword(
|
|
NULL,
|
|
SZ_REG_LOG_LOC,
|
|
_fLogLoc,
|
|
REG_DWORD);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Write Trace Level
|
|
hr = prhRegKey->SetValueDword(
|
|
NULL,
|
|
SZ_REG_TRACE_LVL,
|
|
_fTraceLvl,
|
|
REG_DWORD);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Write Lab Mode
|
|
hr = prhRegKey->SetValueDword(
|
|
NULL,
|
|
SZ_REG_LABMODE,
|
|
_fMode&DH_LABMODE ? TRUE : FALSE,
|
|
REG_DWORD);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Write Break Mode
|
|
hr = prhRegKey->SetValueDword(
|
|
NULL,
|
|
SZ_REG_BREAKMODE,
|
|
_fMode&DH_BREAKMODE ? TRUE : FALSE,
|
|
REG_DWORD);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Write Verbose
|
|
hr = prhRegKey->SetValueDword(
|
|
NULL,
|
|
SZ_REG_VERBOSE,
|
|
_fMode&DH_VERBOSE ? TRUE : FALSE,
|
|
REG_DWORD);
|
|
}
|
|
|
|
// Clean up and exit
|
|
delete prhRegKey;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::CreateLog, public
|
|
//
|
|
// Synopsis: Creates a new log based on the parameters passed.
|
|
//
|
|
// Arguments: [argc] - Number of command line args
|
|
// [argv] - Command line args
|
|
//
|
|
// Returns: S_OK if log created successfully or none is specified,
|
|
// E_FAIL if not.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
HRESULT CDebugHelp::CreateLog(int argc, char **argv)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Check for existing log
|
|
if ((_plog != NULL) && (_fCreatedLog == TRUE))
|
|
{
|
|
delete _plog;
|
|
}
|
|
|
|
// Create the new log
|
|
_plog = new(NullOnFail) Log(argc, argv, LOG_ANSI);
|
|
if (NULL == _plog)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
if (NO_ERROR != _plog->ConfirmCreation())
|
|
{
|
|
delete _plog;
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
// Set _fCreatedLog flag to true so the log will get deleted during
|
|
// cleanup (otherwise the calling process must delete it).
|
|
//
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
_fCreatedLog = TRUE;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::CreateLog, public
|
|
//
|
|
// Synopsis: Creates a new log based on the parameters passed.
|
|
//
|
|
// Arguments: [paszCmdline] - Windows-style ANSI command line.
|
|
//
|
|
// Returns: S_OK if log created successfully or none is specified,
|
|
// E_FAIL if not.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
HRESULT CDebugHelp::CreateLog(LPSTR paszCmdline)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
int argc = 0;
|
|
CHAR **argv = NULL;
|
|
|
|
// Convert pszCmdline to argc/argv parameters
|
|
hr = CmdlineToArgs(paszCmdline, &argc, &argv);
|
|
if (FAILED(hr))
|
|
{
|
|
return(hr);
|
|
}
|
|
|
|
// Check for existing log
|
|
if ((_plog != NULL) && (_fCreatedLog == TRUE))
|
|
{
|
|
delete _plog;
|
|
}
|
|
|
|
// Create the new log
|
|
_plog = new(NullOnFail) Log(argc, argv, LOG_ANSI);
|
|
if (NULL == _plog)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
if (NO_ERROR != _plog->ConfirmCreation())
|
|
{
|
|
delete _plog;
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
// Set _fCreatedLog flag to true so the log will get deleted during
|
|
// cleanup (otherwise the calling process must delete it).
|
|
//
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
_fCreatedLog = TRUE;
|
|
}
|
|
|
|
//
|
|
// Delete the argc/argv command line created by CmdlineToArgs
|
|
//
|
|
|
|
|
|
while (argc > 0)
|
|
{
|
|
--argc;
|
|
delete argv[argc];
|
|
}
|
|
|
|
delete argv;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::SetLog, public
|
|
//
|
|
// Synopsis: Sets the log pointer to the one passed. This one should
|
|
// not be deleted. Deletes existing log is appropriate. If
|
|
// NULL is passed, the old log is deleted and the new log
|
|
// is set to NULL (none).
|
|
//
|
|
// Arguments: [plog] - Pointer to new log.
|
|
//
|
|
// Returns: S_OK if log set successfully, E_FAIL if not.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
HRESULT CDebugHelp::SetLog(Log *plog)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// Make sure new log pointer is valid
|
|
if ((NULL == plog) || (FALSE == IsBadReadPtr(plog, sizeof(Log *))))
|
|
{
|
|
// Free old log if we have one
|
|
if ((_plog != NULL) && (_fCreatedLog == TRUE))
|
|
{
|
|
delete _plog;
|
|
}
|
|
|
|
// Set new log; we should not delete the pointer
|
|
_plog = plog;
|
|
_fCreatedLog = FALSE;
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
OutputDebugString(TEXT("Invalid log pointer"));
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::SetDebugInfo, public
|
|
//
|
|
// Synopsis: Sets debug information.
|
|
//
|
|
// Arguments: [fLogLoc] - New Log Location setting.
|
|
// [fTraceLoc] - New Trace Location setting.
|
|
// [fTraceLvl] - New Trace Level setting.
|
|
// [fMode] - New Mode setting.
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
// 10-Apr-97 SCousens revamp fMode
|
|
//--------------------------------------------------------------------
|
|
HRESULT CDebugHelp::SetDebugInfo(
|
|
DWORD fLogLoc,
|
|
DWORD fTraceLoc,
|
|
DWORD fTraceLvl,
|
|
DWORD fMode)
|
|
{
|
|
// Validate New settings
|
|
fLogLoc = ValidateLoc(fLogLoc);
|
|
fTraceLoc = ValidateLoc(fTraceLoc);
|
|
fTraceLvl = ValidateLvl(fTraceLvl);
|
|
fMode = ValidateMode(fMode);
|
|
|
|
// Assign new values
|
|
if (fLogLoc != DH_LOC_SAME)
|
|
{
|
|
_fLogLoc = fLogLoc;
|
|
}
|
|
|
|
if (fTraceLoc != DH_LOC_SAME)
|
|
{
|
|
_fTraceLoc = fTraceLoc;
|
|
}
|
|
|
|
if (fTraceLvl != DH_LVL_SAME)
|
|
{
|
|
_fTraceLvl = DH_LVL_ALWAYS|DH_LVL_ERROR|fTraceLvl;
|
|
}
|
|
|
|
// Set mode bits, one by one
|
|
if ((fMode & DH_LABMODE_SET) ||
|
|
(fMode & DH_BREAKMODE_SET) ||
|
|
(fMode & DH_VERBOSE_SET))
|
|
{
|
|
DWORD fNewMode;
|
|
fNewMode = fMode & DH_LABMODE_SET ?
|
|
fMode & DH_LABMODE :
|
|
_fMode & DH_LABMODE;
|
|
|
|
fNewMode |= fMode & DH_BREAKMODE_SET ?
|
|
fMode & DH_BREAKMODE :
|
|
_fMode & DH_BREAKMODE;
|
|
|
|
fNewMode |= fMode & DH_VERBOSE_SET ?
|
|
fMode & DH_VERBOSE :
|
|
_fMode & DH_VERBOSE;
|
|
|
|
// mask off the SET bits
|
|
_fMode = fNewMode &
|
|
~(DH_LABMODE_SET |
|
|
DH_BREAKMODE_SET |
|
|
DH_VERBOSE_SET) ;
|
|
}
|
|
|
|
// Reset the warning flag (in OutputMsg)
|
|
_fSpyWarning = FALSE;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::SetPopupWindow, public
|
|
//
|
|
// Synopsis: Associates the window handle passed with the Assert
|
|
// popups that can occur if Lab Mode is set FALSE. Simply
|
|
// replaces any existing window handle - does not close
|
|
// it, etc.
|
|
//
|
|
// Arguments: [hwnd] - New window handle
|
|
//
|
|
// Returns: S_OK if set successfully, E_FAIL if not.
|
|
//
|
|
// History: 1-Dec-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
HRESULT CDebugHelp::SetPopupWindow(HWND hwnd)
|
|
{
|
|
_hwndAssert = hwnd;
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebughelp::SetSpyWindowClass, public
|
|
//
|
|
//
|
|
// Synopsis: Set the window class that all spy window output will
|
|
// go to.
|
|
//
|
|
// Arguments: [pszSpyWindowClass] -- pointer to class name
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// Algorithm: If the old spy class is not equal to the default one,
|
|
// free up the buffer we allocated. Then create a new
|
|
// buffer and copy the new class string into it.
|
|
//
|
|
// History: 09-Aug-95 MikeW Created
|
|
//
|
|
// Notes: If an error is returned the old class is preserved.
|
|
//--------------------------------------------------------------------
|
|
HRESULT CDebugHelp::SetSpyWindowClass(const LPTSTR pszSpyWindowClass)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
LPTSTR pszTemp;
|
|
|
|
if (_pszSpyWindowClass != SZ_DEFAULT_SPY_WINDOW_CLASS)
|
|
{
|
|
delete [] _pszSpyWindowClass;
|
|
}
|
|
|
|
pszTemp = new TCHAR[_tcslen(pszSpyWindowClass) + 1];
|
|
|
|
if (NULL == pszTemp)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
_pszSpyWindowClass = pszTemp;
|
|
_tcscpy(_pszSpyWindowClass, pszSpyWindowClass);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::TraceMsg, public
|
|
//
|
|
// Synopsis: Outputs the debug string to the current location setting
|
|
// if any set bit in the level passed match set bits in the
|
|
// global level.
|
|
//
|
|
// Arguments: [fLvl] - Trace level.
|
|
// [pszFmt] - Trace message format string.
|
|
// [...] - Arguments for format string.
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// History: 20-Oct-93 DeanE Created
|
|
// 10-Apr-97 SCousens Spiff up output string on error
|
|
//--------------------------------------------------------------------
|
|
void CDebugHelp::TraceMsg(DWORD fLvl, LPTSTR pszFmt, ...)
|
|
{
|
|
TCHAR szBuffer[CCH_MAX_DBG_CHARS];
|
|
TCHAR szDebug[CCH_MAX_DBG_CHARS +
|
|
CCH_MAX_DBGPREFIX +
|
|
CCH_MAX_INDENTPRINT + 6 ];
|
|
TCHAR szSpaces[CCH_MAX_INDENTPRINT];
|
|
va_list varArgs;
|
|
|
|
// If the level has DH_LVL_ENTRY in it indent by one
|
|
//
|
|
if (fLvl & DH_LVL_ENTRY)
|
|
{
|
|
_cIndentLevel++;
|
|
}
|
|
|
|
// If all of the bits match, then we will output the string to the
|
|
// current location(s)
|
|
//
|
|
if ((fLvl & _fTraceLvl) == fLvl)
|
|
{
|
|
// Print the caller's string to a buffer
|
|
va_start(varArgs, pszFmt);
|
|
_vsntprintf(szBuffer, CCH_MAX_DBG_CHARS, pszFmt, varArgs);
|
|
szBuffer[CCH_MAX_DBG_CHARS-1] = chNull;
|
|
va_end(varArgs);
|
|
|
|
// Add correct number of space for indentation
|
|
lstrcpy(szSpaces, TEXT(" "));
|
|
if (_cIndentLevel < CCH_MAX_INDENTPRINT)
|
|
{
|
|
szSpaces[_cIndentLevel]=TEXT('\0');
|
|
}
|
|
|
|
// Now prepend it with the debug prefix
|
|
_sntprintf(szDebug,
|
|
CCH_MAX_DBG_CHARS,
|
|
TEXT("%s: %c %s%s%s"),
|
|
_szDbgPrefix,
|
|
DH_LVL_ERROR & fLvl ? chTraceErr : chTrace,
|
|
szSpaces,
|
|
DH_LVL_ERROR & fLvl ? szError : szNull,
|
|
szBuffer);
|
|
szDebug[CCH_MAX_DBG_CHARS-1] = chNull;
|
|
|
|
// Now, spit the thing out to the proper places
|
|
OutputMsg(_fTraceLoc, szDebug);
|
|
}
|
|
|
|
// If the level has DH_LVL_EXIT in it unindent by one
|
|
//
|
|
if (fLvl & DH_LVL_EXIT)
|
|
{
|
|
_cIndentLevel--;
|
|
}
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::ReportResult, public
|
|
//
|
|
// Synopsis: Outputs the test variation and result to the location(s)
|
|
// currently specified.
|
|
//
|
|
// Arguments: [usResult] - Result of the test
|
|
// [pszFmt] - Format of the log message
|
|
// [...] - Parameters for message
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
void CDebugHelp::ReportResult(USHORT usResult, LPTSTR pszFmt, ...)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
TCHAR szFmtBuffer[CCH_MAX_LOG_CHARS];
|
|
TCHAR szLogBuffer[CCH_MAX_LOG_CHARS];
|
|
va_list varArgs;
|
|
|
|
// format variable arg list into a buffer.
|
|
va_start(varArgs, pszFmt);
|
|
_vsntprintf(szFmtBuffer, CCH_MAX_LOG_CHARS, pszFmt, varArgs);
|
|
szFmtBuffer[CCH_MAX_LOG_CHARS-1] = chNull;
|
|
va_end(varArgs);
|
|
|
|
|
|
// Set up log buffer. Truncate any extra chars.
|
|
_sntprintf(szLogBuffer,
|
|
CCH_MAX_LOG_CHARS,
|
|
TEXT("%s: %s"),
|
|
GetResultText(usResult),
|
|
szFmtBuffer);
|
|
szLogBuffer[CCH_MAX_LOG_CHARS-1] = chNull;
|
|
|
|
SetStats(usResult);
|
|
|
|
// Send it out
|
|
OutputMsg(_fLogLoc, szLogBuffer);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::ReportStats, public
|
|
//
|
|
// Synopsis: Outputs statistics about test variations run so far,
|
|
// such as #tests run, #passed, #failed, etc to the Log
|
|
// Location (_fLogLoc).
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
void CDebugHelp::ReportStats()
|
|
{
|
|
TCHAR szBuffer[CCH_MAX_LOG_CHARS];
|
|
|
|
_sntprintf(szBuffer, CCH_MAX_LOG_CHARS,
|
|
TEXT("Summary--> Passed: %lu ; Failed: %lu ; Aborted: %lu"),
|
|
_cPass,
|
|
_cFail,
|
|
_cAbort);
|
|
szBuffer[CCH_MAX_LOG_CHARS-1] = chNull;
|
|
|
|
OutputMsg(_fLogLoc, szBuffer);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::LabAssertEx, public
|
|
//
|
|
// Synopsis: Produces an assert message to the current debug
|
|
// location(s) or to a dialog box, if running in non-Lab
|
|
// mode.
|
|
//
|
|
// Arguments: [szFile] - File assert occurred in.
|
|
// [nLine] - Line assert occurred.
|
|
// [nszMsg] - Assert message.
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// History: 20-Oct-93 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
void CDebugHelp::LabAssertEx(LPCTSTR szFile, int nLine, LPCTSTR szMsg)
|
|
{
|
|
TCHAR szBuffer[CCH_MAX_ASSERT_CHARS];
|
|
int nAnswer;
|
|
|
|
_sntprintf(szBuffer,
|
|
CCH_MAX_ASSERT_CHARS,
|
|
TEXT("Assert!!! File: %s, Line: %d, %s\n"),
|
|
szFile,
|
|
nLine,
|
|
szMsg);
|
|
szBuffer[CCH_MAX_ASSERT_CHARS-1] = chNull;
|
|
|
|
// always spew
|
|
OutputMsg(_fTraceLoc, szBuffer);
|
|
|
|
// if labmode, popup
|
|
if (FALSE == (_fMode & DH_LABMODE))
|
|
{
|
|
nAnswer = MessageBox(
|
|
_hwndAssert,
|
|
szBuffer,
|
|
TEXT("CT OLE Assert"),
|
|
MB_ICONEXCLAMATION | MB_OKCANCEL);
|
|
if (IDCANCEL==nAnswer)
|
|
{
|
|
DebugBreak();
|
|
}
|
|
}
|
|
// if break, break
|
|
else if (FALSE != (_fMode & DH_BREAKMODE))
|
|
{
|
|
DebugBreak();
|
|
}
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::CheckResult, public
|
|
//
|
|
// Synopsis: Compares the hr passed in with expected hr passed in
|
|
//
|
|
// Arguments: [hrCheck] - Result to check.
|
|
// [hrExpected] - Result expected.
|
|
// [pszFuncName] - Name of the current function
|
|
// [pszMsg] - Debug message if result not in list passed.
|
|
// [nLine] - __LINE__ macro
|
|
// [pszFile] - __FILE__ macro
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// History: 12-Aug-94 KennethM Created
|
|
// 1-Dec-94 DeanE Incorporated into CDebugHelp class
|
|
// 12-Apr-95 KennethM Only checks against S_OK
|
|
// 10-Apr-97 SCousens Check against errors also
|
|
//--------------------------------------------------------------------
|
|
HRESULT CDebugHelp::CheckResult (HRESULT hrCheck,
|
|
HRESULT hrExpected,
|
|
LPTSTR pszFuncName,
|
|
LPTSTR pszMsg,
|
|
int nLine,
|
|
LPTSTR pszFile)
|
|
{
|
|
TCHAR szAssertBuf[CCH_MAX_ASSERT_CHARS];
|
|
TCHAR szAssertTitle[CCH_MAX_ASSERT_CHARS];
|
|
TCHAR szMsgBuffer[CCH_MAX_ASSERT_CHARS];
|
|
DWORD cchMsgBuffer = 0;
|
|
int nAnswer;
|
|
HRESULT hr = S_OK;
|
|
|
|
// If _dwExpectedError is set, then someone up the call chain
|
|
// wants us to ignore that error code, even if our direct caller
|
|
// does not. If the incoming error code matches _dwExpectedError,
|
|
// then ignore it and return.
|
|
if ( ( _hrExpectedError != S_OK ) && ( hrCheck == _hrExpectedError ) )
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
// figure out if we have a problem
|
|
if (hrCheck != hrExpected)
|
|
{
|
|
if (FAILED(hrCheck))
|
|
{
|
|
hr = hrCheck;
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
// No problem, prepare to bail
|
|
if (S_OK == hr)
|
|
{
|
|
// if we are verbose, call tracemsg
|
|
if (FALSE != (DH_VERBOSE & _fMode))
|
|
{
|
|
TraceMsg(DH_LVL_ALWAYS,
|
|
S_OK == hrExpected ? // different output if HRCHECK
|
|
TEXT("%s; %s; ok") :
|
|
TEXT("%s; %s; hr=%#lx; ok"),
|
|
pszFuncName,
|
|
pszMsg,
|
|
hrCheck);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// Get the text for the HRESULT from the system
|
|
cchMsgBuffer = FormatMessage(
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
hrCheck,
|
|
GetSystemDefaultLangID(),
|
|
szMsgBuffer,
|
|
CCH_MAX_ASSERT_CHARS,
|
|
NULL);
|
|
szMsgBuffer[CCH_MAX_ASSERT_CHARS-1] = chNull;
|
|
|
|
if (0 == cchMsgBuffer)
|
|
{
|
|
_sntprintf(
|
|
szMsgBuffer,
|
|
CCH_MAX_ASSERT_CHARS,
|
|
TEXT("Error 0x%08x"),
|
|
hrCheck);
|
|
}
|
|
else // zap any \r\n from the FormatMessage
|
|
{
|
|
while ('\r' == szMsgBuffer[cchMsgBuffer-1] ||
|
|
'\n' == szMsgBuffer[cchMsgBuffer-1])
|
|
{
|
|
szMsgBuffer[--cchMsgBuffer] = chNull;
|
|
}
|
|
}
|
|
|
|
// Output to Trace Location
|
|
TraceMsg(DH_LVL_ERROR,
|
|
S_OK == hrExpected ? // different output if HRCHECK
|
|
TEXT("%s; %s; hr=%lx; %s") :
|
|
TEXT("%s; %s; hr=%lx;"),
|
|
pszFuncName,
|
|
pszMsg,
|
|
hr,
|
|
szMsgBuffer);
|
|
// If we are comparing against failure, show what we expected and got.
|
|
if (S_OK != hrExpected)
|
|
{
|
|
TraceMsg(DH_LVL_ALWAYS,
|
|
TEXT("+ hr Expected:%#lx; Got:%#lx; %s"),
|
|
hrExpected,
|
|
hrCheck,
|
|
szMsgBuffer);
|
|
}
|
|
TraceMsg(DH_LVL_ALWAYS,
|
|
TEXT("+ File:%s; Line:%d"),
|
|
pszFile,
|
|
nLine);
|
|
|
|
// labmode - display an error popup
|
|
if (FALSE == (_fMode & DH_LABMODE))
|
|
{
|
|
_sntprintf(szAssertBuf,
|
|
CCH_MAX_ASSERT_CHARS,
|
|
TEXT("%s : hr=%#lx : Expected %#lx\n%s\n"),
|
|
pszMsg,
|
|
hrCheck,
|
|
hrExpected,
|
|
szMsgBuffer);
|
|
szAssertBuf[CCH_MAX_ASSERT_CHARS-1] = chNull;
|
|
|
|
_sntprintf(szAssertTitle,
|
|
CCH_MAX_ASSERT_CHARS,
|
|
TEXT("CT OLE - %s Error"),
|
|
_szDbgPrefix);
|
|
szAssertTitle[CCH_MAX_ASSERT_CHARS-1] = chNull;
|
|
|
|
// Do we want to debug this?
|
|
nAnswer = MessageBox(
|
|
_hwndAssert,
|
|
szAssertBuf,
|
|
szAssertTitle,
|
|
MB_ICONSTOP | MB_OKCANCEL);
|
|
// yes we do?
|
|
if (IDCANCEL==nAnswer)
|
|
{
|
|
DebugBreak();
|
|
}
|
|
}
|
|
// break mode, break into the debugger
|
|
else if (FALSE != (_fMode & DH_BREAKMODE))
|
|
{
|
|
DebugBreak();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::SetExpectedError, public
|
|
//
|
|
// Synopsis: Disables error logging for the specified error code.
|
|
//
|
|
// Arguments: [hrExpectedError] - Error code to disable. Pass S_OK
|
|
// for no expected errors.
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// History: 16-Sep-97 BWill Created
|
|
//
|
|
// Notes: -- Use this call to temporarily disable error logging
|
|
// in client code.
|
|
// -- Call this function with S_OK to enable all checks.
|
|
// -- See also DH_EXPECTEDERROR/DH_NOEXPECTEDERROR in
|
|
// cdbghelp.hxx.
|
|
//--------------------------------------------------------------------
|
|
void CDebugHelp::SetExpectedError( HRESULT hrExpectedError )
|
|
{
|
|
_hrExpectedError = hrExpectedError;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::ValidateLoc, private
|
|
//
|
|
// Synopsis: Checks the location flag passed to insure it is a legal
|
|
// value.
|
|
//
|
|
// Arguments: [fLoc] - Location flag to check.
|
|
//
|
|
// Returns: Legal version of what we were to check.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
// 10-Apr-97 SCousens Return legal value
|
|
//--------------------------------------------------------------------
|
|
DWORD CDebugHelp::ValidateLoc(DWORD fLoc)
|
|
{
|
|
// Get what we can out of supplied location
|
|
return (DH_LOC_VALID & fLoc);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::ValidateLvl, private
|
|
//
|
|
// Synopsis: Checks the Trace Level flag passed to insure it is a
|
|
// legal value.
|
|
//
|
|
// Arguments: [fLvl] - Trace Level to check.
|
|
//
|
|
// Returns: Legal version of what we were to check.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
// 10-Apr-97 SCousens Return legal value
|
|
//--------------------------------------------------------------------
|
|
DWORD CDebugHelp::ValidateLvl(DWORD fLvl)
|
|
{
|
|
// Make sure a valid setting is passed
|
|
return (~DH_LVL_INVMASK & fLvl);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::ValidateMode, private
|
|
//
|
|
// Synopsis: Checks the Lab Mode flag passed to insure it is a
|
|
// legal value.
|
|
//
|
|
// Arguments: [fMode] - Flag to check.
|
|
//
|
|
// Returns: Legal version of what we were to check.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
// 10-Apr-97 SCousens Return legal value
|
|
//--------------------------------------------------------------------
|
|
DWORD CDebugHelp::ValidateMode(DWORD fMode)
|
|
{
|
|
return (fMode & (~DH_INVMODE));
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::SetStats, private
|
|
//
|
|
// Synopsis: Sets stats based on result
|
|
//
|
|
// Arguments: [usResult] - Result to add.
|
|
//
|
|
// Returns: nothing.
|
|
//
|
|
// History: 20-Oct-93 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
VOID CDebugHelp::SetStats(USHORT usResult)
|
|
{
|
|
|
|
switch (usResult)
|
|
{
|
|
case LOG_PASS:
|
|
_cPass++;
|
|
break;
|
|
|
|
case LOG_FAIL:
|
|
_cFail++;
|
|
break;
|
|
|
|
case LOG_ABORT:
|
|
_cAbort++;
|
|
break;
|
|
|
|
default:
|
|
// do nothing.
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::GetResultText, private
|
|
//
|
|
// Synopsis: Determines the correct text to printf for the result code
|
|
// passed. Result code corresponds to LogServer result codes.
|
|
//
|
|
// Arguments: [usResult] - Result to look up.
|
|
//
|
|
// Returns: Pointer to output string corresponding to the result
|
|
// code passed (ie "PASSED" for LOG_PASS).
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
//--------------------------------------------------------------------
|
|
LPCTSTR CDebugHelp::GetResultText(USHORT usResult)
|
|
{
|
|
LPCTSTR szResult = NULL;
|
|
TCHAR szAssert[CCH_MAX_DBG_CHARS];
|
|
|
|
switch (usResult)
|
|
{
|
|
case LOG_PASS:
|
|
szResult = szPass;
|
|
break;
|
|
|
|
case LOG_FAIL:
|
|
szResult = szFail;
|
|
break;
|
|
|
|
case LOG_ABORT:
|
|
szResult = szAbort;
|
|
break;
|
|
|
|
case LOG_WARN:
|
|
szResult = szWarn;
|
|
break;
|
|
|
|
case LOG_INFO:
|
|
szResult = szInfo;
|
|
break;
|
|
|
|
default:
|
|
szResult = szInvalid;
|
|
_sntprintf(szAssert,
|
|
CCH_MAX_DBG_CHARS,
|
|
TEXT("Invalid Test Result=%ld"),
|
|
usResult);
|
|
szAssert[CCH_MAX_DBG_CHARS-1] = chNull;
|
|
LabAssertEx(TEXT(__FILE__), __LINE__, szAssert);
|
|
break;
|
|
}
|
|
|
|
return(szResult);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------
|
|
// Member: CDebugHelp::OutputMsg, private
|
|
//
|
|
// Synopsis: Outputs the buffer to the locations specified.
|
|
// Location, log, and buffer are all assumed to be valid,
|
|
// so no error checking is done.
|
|
//
|
|
// Arguments: [fLoc] - Location(s) to output buffer to.
|
|
// [pszBuffer] - Buffer to output.
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// History: 21-Nov-94 DeanE Created
|
|
// 08-Mar-95 MikeW Added DH_LOC_SPYWIN stuff
|
|
//--------------------------------------------------------------------
|
|
void CDebugHelp::OutputMsg(DWORD fLoc, LPTSTR pszBuffer)
|
|
{
|
|
CHAR szLogBuf[CCH_MAX_LOG_CHARS];
|
|
|
|
if (fLoc & DH_LOC_TERM)
|
|
{
|
|
OutputDebugString(pszBuffer);
|
|
OutputDebugString(szNewLine);
|
|
}
|
|
|
|
if (fLoc & DH_LOC_STDOUT)
|
|
{
|
|
_tprintf(TEXT("%s\n"), pszBuffer);
|
|
}
|
|
|
|
if (fLoc & DH_LOC_LOG)
|
|
{
|
|
if (FALSE == IsBadReadPtr(_plog, sizeof(Log *)))
|
|
{
|
|
// Buffer must be ANSI regardless of platform
|
|
#ifdef UNICODE
|
|
_snprintf(szLogBuf, CCH_MAX_LOG_CHARS, "%ls", pszBuffer);
|
|
#else
|
|
_snprintf(szLogBuf, CCH_MAX_LOG_CHARS, "%s", pszBuffer);
|
|
#endif
|
|
szLogBuf[CCH_MAX_LOG_CHARS-1] = chNull;
|
|
_plog->WriteData(szLogBuf);
|
|
}
|
|
else
|
|
{
|
|
// Trying to write to log that doesn't exist!
|
|
OutputDebugString(TEXT("CDebugHelp: Unable to write to Log File!\n"));
|
|
}
|
|
}
|
|
|
|
if (fLoc & DH_LOC_SPYWIN)
|
|
{
|
|
HWND hWndSpy;
|
|
|
|
hWndSpy = FindWindow(_pszSpyWindowClass, NULL);
|
|
|
|
if (NULL != hWndSpy)
|
|
{
|
|
SendMessage(hWndSpy, LB_ADDSTRING, 0, (LPARAM) pszBuffer);
|
|
SendMessage(hWndSpy, LB_ADDSTRING, 0, (LPARAM) szCRLF);
|
|
}
|
|
else if (FALSE == _fSpyWarning)
|
|
{
|
|
//only spew this once, till someone changes the settings.
|
|
_fSpyWarning = TRUE;
|
|
// Unable to find SpyWindow
|
|
OutputDebugString(TEXT("CDebugHelp: Spy Window not found!\n"));
|
|
}
|
|
}
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: InitializeDebugObject
|
|
//
|
|
// Synopsis: Initialize the debug helper (trace levels, etc.)
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: S_OK if all went well
|
|
// S_FALSE if we encountered /? and spewed and bailed.
|
|
//
|
|
// History: 29-Apr-05 kennethm Created
|
|
// 09-Aug-95 MikeW Override defaults w/ command line
|
|
// 10-Apr-97 SCousens move into CDebugHelp
|
|
//--------------------------------------------------------------------------
|
|
|
|
HRESULT CDebugHelp::Initialize()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
int nRet;
|
|
|
|
LPTSTR pszSpyClass = NULL;
|
|
|
|
CUlongCmdlineObj cmdTraceLvl (OLESTR("tracelvl"), OLESTR("Trace levels"));
|
|
CUlongCmdlineObj cmdTraceLoc (OLESTR("traceloc"), OLESTR("Trace output"));
|
|
CUlongCmdlineObj cmdLogLoc (OLESTR("logloc"), OLESTR("Log output"));
|
|
CBoolCmdlineObj cmdDebugUI (OLESTR("DebugUI"), OLESTR("Popup debug dialog"), OLESTR("FALSE"));
|
|
CBoolCmdlineObj cmdLabMode (OLESTR("labmode"), OLESTR("Popup on error"), OLESTR("FALSE"));
|
|
CBoolCmdlineObj cmdBreak (OLESTR("breakmode"), OLESTR("Break on error"), OLESTR("FALSE"));
|
|
CBoolCmdlineObj cmdVerbose (OLESTR("verbose"), OLESTR("Trace HRCHECK for a noisy log"), OLESTR("FALSE"));
|
|
CBaseCmdlineObj cmdSpyClass (OLESTR("spyclass"), OLESTR("Classname for Spy Window"));
|
|
CCmdline cmdlineArgs;
|
|
|
|
CBaseCmdlineObj *aPossCmdline[] = {
|
|
&cmdTraceLvl,
|
|
&cmdTraceLoc,
|
|
&cmdLogLoc,
|
|
&cmdDebugUI,
|
|
&cmdLabMode,
|
|
&cmdVerbose,
|
|
&cmdBreak,
|
|
&cmdSpyClass };
|
|
|
|
//
|
|
// Read the debug options from the registry
|
|
//
|
|
hr = GetRegDbgInfo (DEFAULT_REG_LOC);
|
|
|
|
//
|
|
// Now that we have the defaults from the registry read the command
|
|
// line to over-ride them.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
//
|
|
// Make sure there were no errors starting up the cmd line objects
|
|
//
|
|
nRet = cmdlineArgs.QueryError();
|
|
if (nRet != CMDLINE_NO_ERROR)
|
|
{
|
|
hr = E_FAIL;
|
|
TraceMsg (DH_LVL_ERROR, TEXT("cmdlineArgs.QueryError"));
|
|
}
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
//
|
|
// Now parse the command line
|
|
//
|
|
|
|
nRet = cmdlineArgs.Parse(aPossCmdline,
|
|
sizeof(aPossCmdline)/sizeof(CBaseCmdlineObj *),
|
|
FALSE);
|
|
if (nRet != CMDLINE_NO_ERROR)
|
|
{
|
|
hr = E_FAIL;
|
|
TraceMsg (DH_LVL_ERROR, TEXT("cmdlineArgs.Parse"));
|
|
}
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
DWORD dwLogLoc = DH_LOC_SAME;
|
|
DWORD dwTraceLoc = DH_LOC_SAME;
|
|
DWORD dwTraceLvl = DH_LVL_SAME;
|
|
DWORD dwMode = 0;
|
|
|
|
if (cmdLabMode.IsFound())
|
|
{
|
|
dwMode = *cmdLabMode.GetValue () ? DH_LABMODE_ON : DH_LABMODE_OFF;
|
|
}
|
|
if (cmdVerbose.IsFound())
|
|
{
|
|
dwMode |= *cmdVerbose.GetValue () ? DH_VERBOSE_ON : DH_VERBOSE_OFF;
|
|
}
|
|
if (cmdBreak.IsFound())
|
|
{
|
|
dwMode |= *cmdBreak.GetValue () ? DH_BREAKMODE_ON : DH_BREAKMODE_OFF;
|
|
}
|
|
if (cmdTraceLvl.IsFound())
|
|
{
|
|
dwTraceLvl = *cmdTraceLvl.GetValue();
|
|
}
|
|
if (cmdTraceLoc.IsFound())
|
|
{
|
|
dwTraceLoc = *cmdTraceLoc.GetValue();
|
|
}
|
|
if (cmdLogLoc.IsFound())
|
|
{
|
|
dwLogLoc = *cmdLogLoc.GetValue();
|
|
}
|
|
SetDebugInfo( \
|
|
dwLogLoc, \
|
|
dwTraceLoc, \
|
|
dwTraceLvl, \
|
|
dwMode);
|
|
|
|
if (cmdSpyClass.IsFound())
|
|
{
|
|
OleStringToTString(cmdSpyClass.GetValue(), &pszSpyClass);
|
|
|
|
if (NULL != pszSpyClass)
|
|
{
|
|
SetSpyWindowClass (pszSpyClass);
|
|
delete [] pszSpyClass;
|
|
}
|
|
}
|
|
if (cmdDebugUI.IsFound())
|
|
{
|
|
HRESULT hr2 = OptionsDialog (GetModuleHandle (NULL), GetActiveWindow ());
|
|
if (FAILED(hr2))
|
|
{
|
|
TraceMsg (DH_LVL_ERROR,
|
|
TEXT("DialogBoxParam failed; hr=%#x. (Is dlg in res?)"),
|
|
hr2);
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CEntryExitTrace::CEntryExitTrace
|
|
//
|
|
// Synopsis: Displays a debug line saying the current function is being
|
|
// entered. Saves the information so it can be displayed
|
|
// when the destructor is called.
|
|
//
|
|
// Arguments: [pDebugObject] -- The parent debug log object
|
|
// [plExitOutput] -- The 32 value to display on exit (can be
|
|
// NULL)
|
|
// [fLvl] -- The trace level of this function
|
|
// [pszFuncName] -- The name of this function
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 4-10-95 kennethm Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
CEntryExitTrace::CEntryExitTrace(
|
|
CDebugHelp *pDebugObject,
|
|
PLONG plExitOutput,
|
|
DWORD fLvl,
|
|
LPTSTR pszFuncName)
|
|
{
|
|
// Save the paramters
|
|
|
|
_pDebugObject = pDebugObject;
|
|
_plExitOutput = plExitOutput;
|
|
_pszFuncName = pszFuncName;
|
|
_fLvl = fLvl;
|
|
|
|
// Display the trace information
|
|
|
|
_pDebugObject->TraceMsg(
|
|
(_fLvl | DH_LVL_ENTRY),
|
|
TEXT("%s _IN"),
|
|
_pszFuncName);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CEntryExitTrace::~CEntryExitTrace
|
|
//
|
|
// Synopsis: Destructor. Display a trace output line
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 4-17-95 kennethm Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
CEntryExitTrace::~CEntryExitTrace(void)
|
|
{
|
|
// Display the trace information
|
|
|
|
if (_plExitOutput != NULL)
|
|
{
|
|
_pDebugObject->TraceMsg(
|
|
(_fLvl | DH_LVL_EXIT),
|
|
TEXT("%s _OUT:%#08lx"),
|
|
_pszFuncName,
|
|
*_plExitOutput);
|
|
}
|
|
else
|
|
{
|
|
_pDebugObject->TraceMsg(
|
|
(_fLvl | DH_LVL_EXIT),
|
|
TEXT("%s _OUT"),
|
|
_pszFuncName);
|
|
}
|
|
}
|