|
|
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999-2001 Microsoft Corporation
//
// Module Name:
// Debug.h
//
// Description:
// Debugging utilities header.
//
// Maintained By:
// Galen Barbee (GalenB) 22-NOV-1999
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
//
// KB: USES_SYSALLOCSTRING gpease 8-NOV-1999
// Turn this on if you are going to use the OLE automation
// functions: SysAllocString, SysFreeString, etc..
//
// #define USES_SYSALLOCSTRING
//
// Trace Flags
//
typedef enum _TRACEFLAGS { mtfALWAYS = 0xFFFFFFFF, mtfNEVER = 0x00000000, // function entry/exits, call, scoping
mtfASSERT_HR = 0x00000001, // Halt if HRESULT is an error
mtfQUERYINTERFACE = 0x00000002, // Query Interface details and halt on error
// Asserts
mtfSHOWASSERTS = 0x00000004, // Show assert message box
// = 0x00000008,
// other
mtfCALLS = 0x00000010, // Function calls that use the TraceMsgDo macro
mtfFUNC = 0x00000020, // Functions entrances w/parameters
mtfSTACKSCOPE = 0x00000040, // if set, debug spew will generate bar/space for level each of the call stack
mtfPERTHREADTRACE = 0x00000080, // Enables per thread tracing, excludes memory tracking.
// specific
mtfDLL = 0x00000100, // DLL specific
mtfWM = 0x00000200, // Window Messages
mtfFLOW = 0x00000400, // Control flow
// = 0x00000800
// citracker spew
mtfCITRACKERS = 0x00001000, // CITrackers will spew entrances and exits
// = 0x00002000,
// = 0x00004000,
// = 0x00008000,
// = 0x00010000,
// = 0x00020000,
// = 0x00040000,
// = 0x00080000,
// = 0x00100000,
// = 0x00200000,
// = 0x00400000,
// = 0x00800000,
// memory
mtfMEMORYLEAKS = 0x01000000, // Halts when a memory leak is detected on thread exit
mtfMEMORYINIT = 0x02000000, // Initializes new memory allocations to non-zero value
mtfMEMORYALLOCS = 0x04000000, // Turns on spew to display each de/allocation.
// = 0x08000000,
// output prefixes
mtfADDTIMEDATE = 0x10000000, // Replaces Filepath(Line) with Date/Time
mtfBYMODULENAME = 0x20000000, // Puts the module name at the beginning of the line
// = 0x40000000,
mtfOUTPUTTODISK = 0x80000000, // Writes output to disk
} TRACEFLAGS;
typedef DWORD TRACEFLAG;
#define ASZ_NEWLINE "\r\n"
#define SZ_NEWLINE TEXT( ASZ_NEWLINE )
#define SIZEOF_ASZ_NEWLINE ( sizeof( ASZ_NEWLINE ) - sizeof( CHAR ) )
#define SIZEOF_SZ_NEWLINE ( sizeof( SZ_NEWLINE ) - sizeof( TCHAR ) )
#define FREE_ADDRESS 0xFA
#define FREE_BLOCK 0xFB
#define AVAILABLE_ADDRESS 0xAA
#ifdef DEBUG
#pragma message( "BUILD: DEBUG macros being built" )
//
// Globals
//
extern DWORD g_TraceMemoryIndex; // TLS index for the memory tracking link list
extern DWORD g_dwCounter; // Stack depth counter
extern TRACEFLAG g_tfModule; // Global tracing flags
extern const LPCTSTR g_pszModuleIn; // Local module name - use DEFINE_MODULE
extern const TCHAR g_szTrue[]; // Array "TRUE"
extern const TCHAR g_szFalse[]; // Array "FALSE"
//
// Definition Macros
//
#define DEFINE_MODULE( _module ) const LPCTSTR g_pszModuleIn = TEXT(_module);
#define __MODULE__ g_pszModuleIn
#define DEFINE_THISCLASS( _class ) static const TCHAR g_szClass[] = TEXT(_class);
#define __THISCLASS__ g_szClass
//
// ImageHlp Stuff - not ready for prime time yet.
//
#if defined( IMAGEHLP_ENABLED )
#include <imagehlp.h>
typedef BOOL ( * PFNSYMGETSYMFROMADDR )( HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL ); typedef BOOL ( * PFNSYMGETLINEFROMADDR )( HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE ); typedef BOOL ( * PFNSYMGETMODULEINFO )( HANDLE, DWORD, PIMAGEHLP_MODULE );
extern HINSTANCE g_hImageHlp; // IMAGEHLP.DLL instance handle
extern PFNSYMGETSYMFROMADDR g_pfnSymGetSymFromAddr; extern PFNSYMGETLINEFROMADDR g_pfnSymGetLineFromAddr; extern PFNSYMGETMODULEINFO g_pfnSymGetModuleInfo; #endif // IMAGEHLP_ENABLED
void DebugIncrementStackDepthCounter( void );
void DebugDecrementStackDepthCounter( void );
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceInitializeProcess(
// _rgControl
// _sizeofControl
// _fGlobalMemoryTackingIn
// )
//
// Description:
// Should be called in the DLL main on process attach or in the entry
// routine of an EXE. Initializes debugging globals and TLS. Registers
// the WMI tracing facilities (if WMI support is enabled).
//
// Arguments:
// _rgControl WMI control block (see DEBUG_WMI_CONTROL_GUIDS)
// _sizeofControl The sizeof( _rgControl )
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#if defined( DEBUG_SW_TRACING_ENABLED )
#define TraceInitializeProcess( _rgControl, _sizeofControl, _fGlobalMemoryTackingIn ) \
do \ { \ DebugInitializeTraceFlags( _fGlobalMemoryTackingIn ); \ WMIInitializeTracing( _rgControl, _sizeofControl ); \ } while ( 0 ) #else // ! DEBUG_SW_TRACING_ENABLED
#define TraceInitializeProcess( _fGlobalMemoryTackingIn ) \
do \ { \ DebugInitializeTraceFlags( _fGlobalMemoryTackingIn ); \ } while ( 0 ) #endif // DEBUG_SW_TRACING_ENABLED
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceInitializeThread(
// _name
// )
//
// Description:
// Should be called in the DLL thread attach or when a new thread is
// created. Sets up the memory tracing for that thread as well as
// establishing the tfThread for each thread (if mtfPERTHREADTRACE
// is set in g_tfModule).
//
// Arguments:
// _name NULL or the name of the thread.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceInitializeThread( _name ) \
do \ { \ TlsSetValue( g_TraceMemoryIndex, NULL ); \ DebugInitializeThreadTraceFlags( _name ); \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceThreadRundown( void )
//
// Description:
// Should be called before a thread terminates. It will check to make
// sure all memory allocated by the thread was released properly. It
// will also cleanup any per thread structures.
//
// Arguments:
// None.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceThreadRundown() \
do \ { \ DebugMemoryCheck( NULL, NULL ); \ DebugThreadRundownTraceFlags(); \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceCreateMemoryList(
// _pmbIn
// )
//
// Description:
// Creates a thread-independent list to track objects.
//
// _pmbIn should be an LPVOID.
//
// Arguments:
// _pmbIn - Pointer to store the head of the list.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceCreateMemoryList( _pmbIn ) \
DebugCreateMemoryList( TEXT(__FILE__), __LINE__, __MODULE__, &_pmbIn, TEXT(#_pmbIn) );
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceTerminateMemoryList(
// _pmbIn
// )
//
// Description:
// Checks to make sure the list is empty before destroying the list.
//
// _pmbIn should be an LPVOID.
//
// Arguments:
// _pmbIn - Pointer to store the head of the list.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
// BUGBUG: DavidP 09-DEC-1999
// _pmbIn is evaluated multiple times but the name of the
// macro is mixed case.
#define TraceTerminateMemoryList( _pmbIn ) \
do \ { \ DebugMemoryCheck( _pmbIn, TEXT(#_pmbIn) ); \ HeapFree( GetProcessHeap(), 0, _pmbIn ); \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceMoveToMemoryList(
// _addr
// _pmbIn
// )
//
// Description:
// Moves an object from the thread tracking list to a thread independent
// memory list (_pmbIn).
//
// _pmbIn should be castable to an LPVOID.
//
// Arguments:
// _addr - Address of object to move.
// _pmbIn - Pointer to store the head of the list.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
//#define TraceMoveToMemoryList( _addr, _pmbIn ) \ // DebugMoveToMemoryList( TEXT(__FILE__), __LINE__, __MODULE__, _addr, _pmbIn, TEXT(#_pmbIn) );
#define TraceMoveToMemoryList( _addr, _pmbIn )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceMoveFromMemoryList(
// _addr
// _pmbIn
// )
//
// Description:
// Moves an object from a thread independent memory list (_pmbIn) to the
// per thread tracking list.
//
// _pmbIn should be castable to an LPVOID.
//
// Arguments:
// _addr - Address of object to move.
// _pmbIn - Pointer to store the head of the list.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
//#define TraceMoveFromMemoryList( _addr, _pmbIn ) \ // DebugMoveFromMemoryList( TEXT(__FILE__), __LINE__, __MODULE__, _addr, _pmbIn, TEXT(#_pmbIn) );
#define TraceMoveFromMemoryList( _addr, _pmbIn )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceMemoryListDelete(
// _addr
// _pmbIn
// )
//
// Description:
// Moves and object from the thread tracking list to a thread independent
// memory list (_pmbIn).
//
// _pmbIn should be an LPVOID.
//
// Arguments:
// _addr - Address of object to delete.
// _pmbIn - Pointer to store the head of the list.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
//#define TraceMemoryListDelete( _addr, _pmbIn, _fClobberIn ) \ // DebugMemoryListDelete( TEXT(__FILE__), __LINE__, __MODULE__, _addr, _pmbIn, TEXT(#_pmbIn), _fClobberIn );
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceTerminateProcess
//
// Description:
// Should be called before a process terminates. It cleans up anything
// that the Debug APIs created. It will check to make sure all memory
// allocated by the main thread was released properly. It will also
// terminate WMI tracing (if WMI support is enabled). It also closes
// the logging handle.
//
// Arguments:
// _rgControl - WMI control block (see DEBUG_WMI_CONTROL_GUIDS)
// _sizeofControl - the sizeof( _rgControl )
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#if defined( DEBUG_SW_TRACING_ENABLED )
#define TraceTerminateProcess( _rgControl, _sizeofControl ) \
do \ { \ LogTerminateProcess(); \ WMITerminateTracing( _rgControl, _sizeofControl ); \ DebugMemoryCheck( NULL, NULL ); \ DebugTerminateProcess(); \ } while ( 0 ) #else // ! DEBUG_SW_TRACING_ENABLED
//
// TODO: 11 DEC 2000 GalenB
//
// LogTerminateProcess() needs to be available for retail builds.
// Since it doesn't yet do anything this isn't a problem, but that
// of course can change...
//
#define TraceTerminateProcess() \
do \ { \ LogTerminateProcess(); \ DebugMemoryCheck( NULL, NULL ); \ DebugTerminateProcess(); \ } while ( 0 ) #endif // DEBUG_SW_TRACING_ENABLED
//****************************************************************************
//
// Debug initialization routines
//
// Uses should use the TraceInitializeXXX and TraceTerminateXXX macros, not
// these routines.
//
//****************************************************************************
void DebugInitializeTraceFlags( BOOL fGlobalMemoryTackingIn = TRUE );
void DebugInitializeThreadTraceFlags( LPCTSTR pszThreadNameIn );
void DebugTerminateProcess( void );
void DebugThreadRundownTraceFlags( void );
void DebugCreateMemoryList( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, LPVOID * ppvListOut, LPCTSTR pszListNameIn );
void DebugMemoryListDelete( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, void * pvMemIn, LPVOID pvListIn, LPCTSTR pszListNameIn, BOOL fClobberIn );
void DebugMoveToMemoryList( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, void * pvMemIn, LPVOID pmbListIn, LPCTSTR pszListNameIn );
void DebugMoveFromMemoryList( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, HGLOBAL hGlobal, LPVOID pmbListIn, LPCTSTR pszListNameIn );
//****************************************************************************
//
// Memmory Allocation Subsitution Macros
//
// Replaces LocalAlloc/LocalFree, GlobalAlloc/GlobalFree, and malloc/free
//
//****************************************************************************
#define TraceAlloc( _flags, _size ) DebugAlloc( TEXT(__FILE__), __LINE__, __MODULE__, _flags, _size, TEXT(#_size) )
#define TraceReAlloc( _pvmem, _size, _flags ) DebugReAlloc( TEXT(__FILE__), __LINE__, __MODULE__, _pvmem, _flags, _size, TEXT(#_size) )
#define TraceFree( _hmem ) DebugFree( _hmem, TEXT(__FILE__), __LINE__, __MODULE__ )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceAllocString(
// _flags,
// _size
// )
//
// Description:
// Quick way to allocation a string that is the proper size and that will
// be tracked by memory tracking.
//
// Arguments:
// _flags - Allocation attributes.
// _size - Number of characters in the string to be allocated.
//
// Return Values:
// Handle/pointer to memory to be used as a string.
//
//////////////////////////////////////////////////////////////////////////////
#define TraceAllocString( _flags, _size ) \
(LPTSTR) DebugAlloc( TEXT(__FILE__), \ __LINE__, \ __MODULE__, \ _flags, \ (_size) * sizeof( TCHAR ), \ TEXT(#_size) \ )
//****************************************************************************
//
// Code Tracing Macros
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceFunc(
// _szArgs
// )
//
// Description:
// Displays file, line number, module and "_szArgs" only if the mtfFUNC is
// set in g_tfModule. "_szArgs" is the name of the function just
// entered. It also increments the stack counter.
//
// Arguments:
// _szArgs - Arguments for the function just entered.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceFunc( _szArgs ) \
HRESULT __MissingTraceFunc; \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )") ); \ }
//
// These next macros are just like TraceFunc except they take additional
// arguments to display the values passed into the function call. "_szArgs"
// should contain a printf string on how to display the arguments.
//
#define TraceFunc1( _szArgs, _arg1 ) \
HRESULT __MissingTraceFunc; \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1 ); \ }
#define TraceFunc2( _szArgs, _arg1, _arg2 ) \
HRESULT __MissingTraceFunc; \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2 ); \ }
#define TraceFunc3( _szArgs, _arg1, _arg2, _arg3 ) \
HRESULT __MissingTraceFunc; \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2, _arg3 ); \ }
#define TraceFunc4( _szArgs, _arg1, _arg2, _arg3, _arg4 ) \
HRESULT __MissingTraceFunc; \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2, _arg3, _arg4 ); \ }
#define TraceFunc5( _szArgs, _arg1, _arg2, _arg3, _arg4, _arg5 ) \
HRESULT __MissingTraceFunc; \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2, _arg3, _arg4, arg5 ); \ }
#define TraceFunc6( _szArgs, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) \
HRESULT __MissingTraceFunc; \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2, _arg3, _arg4, arg5, arg6 ); \ }
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceQIFunc(
// _szArgs,
// riid,
// ppv
// )
//
// Description:
// Just like TraceFunc but customized for QueryInterface. Specifically,
// displays the name of the interface and the value of the return pointer.
//
// Arguments:
// _riid - Interface ID.
// _ppv - Return pointer.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceQIFunc( _riid, _ppv ) \
HRESULT __MissingTraceFunc; \ if ( g_tfModule != 0 ) \ { \ TCHAR szGuid[ cchGUID_STRING_SIZE ]; \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), \ __LINE__, \ __MODULE__, \ mtfFUNC, \ TEXT("+ ") TEXT(__FUNCTION__) TEXT("( [IUnknown] %s, ppv = %#x )"), \ PszTraceFindInterface( _riid, szGuid ), \ _ppv \ ); \ }
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceFlow(
// _pszFormat
// )
//
// Description:
// This macro outputs a string that is indented to the current depth.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceFlow( _pszFormat ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat) ); \ } \ } while ( 0 )
//
// These next macros are just like TraceFunc except they take additional
// arguments to display the values passed into the function call. "_pszFormat"
// should contain a printf string on how to display the arguments.
//
#define TraceFlow1( _pszFormat, _arg1 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1 ); \ } \ } while ( 0 )
#define TraceFlow2( _pszFormat, _arg1, _arg2 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2 ); \ } \ } while ( 0 ) #define TraceFlow3( _pszFormat, _arg1, _arg2, _arg3 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2, _arg3 ); \ } \ } while ( 0 ) #define TraceFlow4( _pszFormat, _arg1, _arg2, _arg3, _arg4 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2, _arg3, _arg4 ); \ } \ } while ( 0 ) #define TraceFlow5( _pszFormat, _arg1, _arg2, _arg3, _arg4, _arg5 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2, _arg3, _arg4, _arg5 ); \ } \ } while ( 0 )
#define TraceFlow6( _pszFormat, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ); \ } \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceFuncExit( void )
//
// Description:
// Return macro for TraceFunc() if the return type is void. It also
// decrements the stack counter.
//
// Arguments:
// None.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceFuncExit() \
do \ { \ if ( g_tfModule != 0 ) \ { \ __MissingTraceFunc = 0; \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \ DebugDecrementStackDepthCounter(); \ } \ return; \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// RETURN(
// _rval
// )
//
// Description:
// Return macro for TraceFunc(). The _rval will be returned as the
// result of the function. It also decrements the stack counter.
//
// Arguments:
// _rval - Result of the function.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define RETURN( _rval ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ __MissingTraceFunc = 0; \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \ DebugDecrementStackDepthCounter(); \ } \ return _rval; \ } while ( 0 )
/*
return ( ( g_tfModule != 0 ) \ ? ( TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ) \ , DebugDecrementStackDepthCounter() \ , _rval ) \ : _rval ) */
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// FRETURN(
// _rval
// )
//
// Description:
// This is a fake version of the return macro for TraceFunc().
// *** This doesn't return. *** It also decrements the stack counter.
//
// Arguments:
// _rval - Result of the function.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define FRETURN( _rval ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ __MissingTraceFunc = 0; \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \ DebugDecrementStackDepthCounter(); \ } \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// HRETURN(
// _hr
// )
//
// Description:
// Return macro for TraceFunc(). The _hr will be returned as the result
// of the function. If the value is not S_OK, it will be displayed in
// the debugger. It also decrements the stack counter.
//
// Arguments:
// _hr - Result of the function.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define HRETURN( _hr ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ __MissingTraceFunc = 0; \ if ( _hr != S_OK ) \ { \ DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V hr = 0x%08x (%s)"), _hr ); \ } \ else \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \ } \ DebugDecrementStackDepthCounter(); \ } \ return _hr; \ } while ( 0 )
//
// These next macros are just like HRETURN except they allow other
// exceptable values to be passed.back without causing extra spew.
//
#define HRETURN1( _hr, _arg1 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ __MissingTraceFunc = 0; \ if ( ( _hr != S_OK ) && ( _hr != _arg1 ) ) \ { \ DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V hr = 0x%08x (%s)"), _hr ); \ } \ else \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \ } \ DebugDecrementStackDepthCounter(); \ } \ return _hr; \ } while ( 0 )
#define HRETURN2( _hr, _arg1, _arg2 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ __MissingTraceFunc = 0; \ if ( ( _hr != S_OK ) && ( _hr != _arg1 ) && ( _hr != _arg2 ) ) \ { \ DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V hr = 0x%08x (%s)"), _hr ); \ } \ else \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \ } \ DebugDecrementStackDepthCounter(); \ } \ return _hr; \ } while ( 0 )
#define HRETURN3( _hr, _arg1, _arg2, _arg3 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ __MissingTraceFunc = 0; \ if ( ( _hr != S_OK ) && ( _hr != _arg1 ) && ( _hr != _arg2 ) && ( _hr != _arg3 ) ) \ { \ DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V hr = 0x%08x (%s)"), _hr ); \ } \ else \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \ } \ DebugDecrementStackDepthCounter(); \ } \ return _hr; \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceDo(
// _szExp
// )
//
// Description:
// Displays the file, line number, module and function call and return
// from the function call (no return value displayed) for "_szExp" only
// if the mtfCALLS is set in g_tfModule. Note return value is not
// displayed. _szExp will be in RETAIL version of the product.
//
// Arguments:
// _szExp
// The expression to be traced including assigment to the return
// variable.
//
// Return Values:
// None. The return value should be defined within _szExp.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceDo( _szExp ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_szExp ) ); \ _szExp; \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("V") ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _szExp; \ } \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceMsgDo(
// _pszExp,
// _pszReturnMsg
// )
//
// Description:
// Displays the file, line number, module and function call and return
// value which is formatted in "_pszReturnMsg" for "_pszExp" only if the
// mtfCALLS is set in g_tfModule. _pszExp will be in the RETAIL version
// of the product.
//
// Arguments:
// _pszExp
// The expression to be traced including assigment to the return
// variable.
// _pszReturnMsg
// A format string for displaying the return value.
//
// Return Values:
// None. The return value should be defined within _szExp.
//
// Example:
// TraceMsgDo( hr = HrDoSomething(), "0x%08.8x" );
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceMsgDo( _pszExp, _pszReturnMsg ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
//
// These next macros are just like TraceMsgDo except they take additional
// arguments to display the values passed into the function call. "_pszReturnMsg"
// should contain a printf format string describing how to display the
// arguments.
//
#define TraceMsgDo1( _pszExp, _pszReturnMsg, _arg1 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgDo2( _pszExp, _pszReturnMsg, _arg1, _arg2 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgDo3( _pszExp, _pszReturnMsg, _arg1, _arg2, _arg3 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgDo4( _pszExp, _pszReturnMsg, _arg1, _arg2, _arg3, _arg4 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgDo5( _pszExp, _pszReturnMsg, _arg1, _arg2, _arg3, _arg4, _arg5 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4, _arg5 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgDo6( _pszExp, _pszReturnMsg, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceMsgPreDo(
// _pszExp,
// _pszPreMsg
// _pszReturnMsg,
// )
//
// Description:
// Displays the file, line number, module and function call and return
// value which is formatted in "_pszReturnMsg" for "_pszExp" only if the
// mtfCALLS is set in g_tfModule. _pszExp will be in the RETAIL version
// of the product.
//
// Same as TraceMsgDo except it displays the formatted message before
// executing the expression. Arguments for TraceMsgPreDo1, etc. are
// applied to both _pszPreMsg and _pszReturnMsg. The first substitution
// string in _pszReturnMsg is for the return value from the function.
//
// Arguments:
// _pszExp
// The expression to be traced including assigment to the return
// variable.
// _pszPreMsg
// A format string for displaying a message before the expression
// is evaluated.
// _pszReturnMsg
// A format string for displaying the return value.
//
// Return Values:
// None. The return value should be defined within _szExp.
//
// Example:
// TraceMsgPreDo1( hr = HrDoSomething( bstrName ),
// "Name = '%ls'",
// "0x%08.8x, Name = '%ls'",
// bstrName
// );
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TraceMsgPreDo( _pszExp, _pszPreMsg, _pszReturnMsg ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg) ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
//
// These next macros are just like TraceMsgPreDo except they take additional
// arguments to display the values passed into the function call. "_pszPreMsg"
// should contain a printf format string describing how to display the
// arguments.
//
#define TraceMsgPreDo1( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1 ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgPreDo2( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2 ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgPreDo3( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2, _arg3 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2, _arg3 ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgPreDo4( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2, _arg3, _arg4 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2, _arg3, _arg4 ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgPreDo5( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2, _arg3, _arg4, _arg5 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2, _arg3, _arg4, _arg5 ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4, _arg5 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
#define TraceMsgPreDo6( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ DebugIncrementStackDepthCounter(); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ); \ TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ); \ DebugDecrementStackDepthCounter(); \ } \ else \ { \ _pszExp; \ } \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TraceMsgGUID(
// _flags,
// _msg
// _guid
// )
//
// Description:
// Dumps a GUID to the debugger only if one of the flags in _flags is
// set in g_tfModule.
//
// Arguments:
// _flags - Flags to check
// _msg - msg to print before GUID
// _guid - GUID to dump
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
// BUGBUG: DavidP 09-DEC-1999
// _guid is evaluated multiple times but the name of the
// macro is mixed case.
#define TraceMsgGUID( _flags, _msg, _guid ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ TraceMessage( TEXT(__FILE__), \ __LINE__, \ __MODULE__, \ _flags, \ TEXT("%s {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"), \ TEXT(_msg), \ _guid.Data1, _guid.Data2, _guid.Data3, \ _guid.Data4[ 0 ], _guid.Data4[ 1 ], _guid.Data4[ 2 ], _guid.Data4[ 3 ], \ _guid.Data4[ 4 ], _guid.Data4[ 5 ], _guid.Data4[ 6 ], _guid.Data4[ 7 ] ); \ } \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// ErrorMsg(
// _szMsg,
// _err
// )
//
// Description:
// Print an error out. Can be used to write errors to a file. Note that
// it will also print the source filename, line number and module name.
//
// Arguments:
// _szMsg - Format string to be displayed.
// _err - Error code of the error.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define ErrorMsg( _szMsg, _err ) \
TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfALWAYS, TEXT(__FUNCTION__) TEXT(": ") TEXT(_szMsg), _err );
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// WndMsg(
// _hwnd,
// _umsg,
// _wparam,
// _lparam
// )
//
// Description:
// Prints out a message to trace windows messages.
//
// Arguments:
// _hwnd - The HWND
// _umsg - The uMsg
// _wparam - The WPARAM
// _lparam _ The LPARAM
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
// BUGBUG: DavidP 09-DEC-1999
// _wparam and _lparam are evaluated multiple times but the name
// of the macro is mixed case.
#define WndMsg( _hwnd, _umsg, _wparam, _lparam ) \
do \ { \ if ( g_tfModule & mtfWM ) \ { \ DebugMsg( TEXT("%s: WM : hWnd = 0x%08x, uMsg = %u, wParam = 0x%08x (%u), lParam = 0x%08x (%u)"), __MODULE__, _hwnd, _umsg, _wparam, _wparam, _lparam, _lparam ); \ } \ } while ( 0 )
//****************************************************************************
//
// Debug Macros
//
// These calls are only compiled in DEBUG. They are a NOP in RETAIL
// (not even compiled in).
//
//****************************************************************************
//
// Same as TraceDo() but only compiled in DEBUG.
//
#define DebugDo( _fn ) \
do \ { \ DebugIncrementStackDepthCounter(); \ DebugMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT("+ ") TEXT(#_fn ) ); \ _fn; \ DebugMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT("V") ); \ DebugDecrementStackDepthCounter(); \ } while ( 0 )
//
// Same as TraceMsgDo() but only compiled in DEBUG.
//
#define DebugMsgDo( _fn, _msg ) \
do \ { \ DebugIncrementStackDepthCounter(); \ DebugMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT("+ ") TEXT(#_fn) ); \ DebugMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), TEXT(#_fn), _fn ); \ DebugDecrementStackDepthCounter(); \ } while ( 0 )
//****************************************************************************
//
// HRESULT testing macros
//
// These functions check HRESULT return values and display UI if conditions
// warrant only in DEBUG.
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// IsTraceFlagSet(
// _flag
// )
//
// Description:
// Checks to see of the flag is set in the global flags or in the per
// thread flags. If you specify more than one flag and if any of them are
// set, it will return TRUE.
//
// In RETAIL this always return FALSE thereby effectively deleting the
// block of the if statement. Example:
//
// if ( IsTraceFlagSet( mtfPERTHREADTRACE ) )
// {
// //
// // This code only exists in DEBUG.
// .
// .
// .
// }
//
// Arguments:
// _flags - Flag to check for.
//
// Return Values:
// TRUE - If DEBUG and flag set.
// FLASE - If RETAIL or flag not set.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define IsTraceFlagSet( _flag ) ( g_tfModule && IsDebugFlagSet( _flag ) )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// THR(
// _hr
// )
//
// Description:
// Warning is display if HRESULT is anything but S_OK (0). This can be
// use in an expression. Example:
//
// hr = THR( pSomething->DoSomething( arg ) );
//
// Arguments:
// _hr - Function expression to check.
//
// Return Values:
// Result of the "_hr" expression.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define THR( _hr ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, FALSE, S_OK )
#define THRMSG( _hr, _msg ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _hr, FALSE, S_OK ) #define THRMSG1( _hr, _msg, _arg1 ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _hr, FALSE, S_OK, _arg1 )
#define THRE( _hr, _hrIgnore ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, FALSE, _hrIgnore )
#define THREMSG( _hr, _hrIgnore, _msg ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _hr, FALSE, _hrIgnore ) #define THREMSG1( _hr, _hrIgnore, _msg, _arg1 ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _hr, FALSE, _hrIgnore, _arg1 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// STHR(
// _hr
// )
//
// Description:
// Warning is display if FAILED( _hr ) is TRUE. This can be use in an
// expression. Example:
//
// hr = STHR( pSomething->DoSomething( arg ) );
//
// Arguments:
// _hr - Function expression to check.
//
// Return Values:
// Result of the "_hr" expression.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define STHR( _hr ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, TRUE, S_OK )
#define STHRMSG( _hr, _msg ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _hr, TRUE, S_OK ) #define STHRMSG1( _hr, _msg, _arg1 ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _hr, TRUE, S_OK, _arg1 )
#define STHRE( _hr, _hrIgnore ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, TRUE, _hrIgnore )
#define STHREMSG( _hr, _hrIgnore, _msg ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _hr, TRUE, _hrIgnore ) #define STHREMSG1( _hr, _hrIgnore, _msg, _arg1 ) \
TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _hr, TRUE, _hrIgnore, _arg1 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// TW32(
// _fn
// )
//
// Description:
// Warning is display if result is anything but ERROR_SUCCESS (0). This
// can be use in an expression. Example:
//
// dwErr = TW32( RegOpenKey( HKLM, "foobar", &hkey ) );
//
// Arguments:
// _fn - Function expression to check.
//
// Return Values:
// Result of the "_fn" expression.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define TW32( _fn ) \
TraceWin32( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_fn), _fn, ERROR_SUCCESS )
#define TW32MSG( _fn, _msg ) \
TraceWin32( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _fn, ERROR_SUCCESS ) #define TW32MSG1( _fn, _msg, _arg1 ) \
TraceWin32( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _fn, ERROR_SUCCESS, _arg1 )
#define TW32E( _fn, _errIgnore ) \
TraceWin32( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_fn), _fn, _errIgnore )
#define TW32EMSG( _fn, _errIgnore, _msg ) \
TraceWin32( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _fn, _errIgnore ) #define TW32EMSG1( _fn, _errIgnore, _msg, _arg1 ) \
TraceWin32( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), _fn, _errIgnore, _arg1 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// RRETURN(
// _fn
// )
//
// Description:
// Warning is display if return value is anything but ERROR_SUCCESS (0).
//
// Argument:
// _fn - Value to return.
//
// Return Values:
// _fn always.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define RRETURN( _fn ) \
do \ { \ if ( g_tfModule != 0 ) \ { \ __MissingTraceFunc = 0; \ if ( _fn != ERROR_SUCCESS ) \ { \ DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V ") TEXT(#_fn) TEXT(" = 0x%08x (%s)"), _fn ); \ } \ else \ { \ TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \ } \ DebugDecrementStackDepthCounter(); \ } \ return _fn; \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// QIRETURN(
// _hr,
// _riid
// )
//
// Description:
// Warning is display if HRESULT is anything but S_OK (0) only if
// mtfQUERYINTERFACE is set in g_tfModule, otherwise only a debug
// message will be printed. Note that TraceFunc() must have been called
// on the call stack counter must be incremented prior to using.
//
// QIRETURNx will ignore E_NOINTERFACE errors for the interfaces
// specified.
//
// Arguments:
// _hr - Result of the query interface call.
// _riid - The reference ID of the interfaced queried for.
//
// Return Values:
// None - calls RETURN macro.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define QIRETURN( _hr, _riid ) \
do \ { \ if ( _hr ) \ { \ TCHAR szGuid[ 40 ]; \ TCHAR szSymbolicName[ 64 ]; \ DWORD cchSymbolicName = 64; \ DebugFindWinerrorSymbolicName( _hr, szSymbolicName, &cchSymbolicName ); \ Assert( cchSymbolicName != 64 ); \ DebugMessage( TEXT(__FILE__), \ __LINE__, \ __MODULE__, \ TEXT("*HRESULT* QueryInterface( %s, ppv ) failed(), hr = 0x%08x (%s)"), \ PszDebugFindInterface( _riid, szGuid ), \ _hr, \ szSymbolicName \ ); \ } \ if ( g_tfModule & mtfQUERYINTERFACE ) \ { \ __MissingTraceFunc = 0; \ TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, FALSE, S_OK ); \ } \ HRETURN( _hr ); \ } while ( 0 )
#define QIRETURN1( _hr, _riid, _riidIgnored1 ) \
do \ { \ if ( _hr == E_NOINTERFACE \ && IsEqualIID( _riid, _riidIgnored1 ) \ ) \ { \ FRETURN( S_OK ); \ return( _hr ); \ } \ QIRETURN( _hr, _riid ); \ } while ( 0 )
#define QIRETURN2( _hr, _riid, _riidIgnored1, _riidIgnored2 ) \
do \ { \ if ( _hr == E_NOINTERFACE \ && ( IsEqualIID( _riid, _riidIgnored1 ) \ || IsEqualIID( _riid, _riidIgnored2 ) \ ) \ ) \ { \ FRETURN( S_OK ); \ return( _hr ); \ } \ QIRETURN( _hr, _riid ); \ } while ( 0 )
#define QIRETURN3( _hr, _riid, _riidIgnored1, _riidIgnored2, _riidIgnored3 ) \
do \ { \ if ( _hr == E_NOINTERFACE \ && ( IsEqualIID( _riid, _riidIgnored1 ) \ || IsEqualIID( _riid, _riidIgnored2 ) \ || IsEqualIID( _riid, _riidIgnored3 ) \ ) \ ) \ { \ FRETURN( S_OK ); \ return( _hr ); \ } \ QIRETURN( _hr, _riid ); \ } while ( 0 )
#define QIRETURN4( _hr, _riid, _riidIgnored1, _riidIgnored2, _riidIgnored3, _riidIgnored4 ) \
do \ { \ if ( _hr == E_NOINTERFACE \ && ( IsEqualIID( _riid, _riidIgnored1 ) \ || IsEqualIID( _riid, _riidIgnored2 ) \ || IsEqualIID( _riid, _riidIgnored3 ) \ || IsEqualIID( _riid, _riidIgnored4 ) \ ) \ ) \ { \ FRETURN( S_OK ); \ return( _hr ); \ } \ QIRETURN( _hr, _riid ); \ } while ( 0 )
#define QIRETURN5( _hr, _riid, _riidIgnored1, _riidIgnored2, _riidIgnored3, _riidIgnored4, _riidIgnored5 ) \
do \ { \ if ( _hr == E_NOINTERFACE \ && ( IsEqualIID( _riid, _riidIgnored1 ) \ || IsEqualIID( _riid, _riidIgnored2 ) \ || IsEqualIID( _riid, _riidIgnored3 ) \ || IsEqualIID( _riid, _riidIgnored4 ) \ || IsEqualIID( _riid, _riidIgnored5 ) \ ) \ ) \ { \ FRETURN( S_OK ); \ return( _hr ); \ } \ QIRETURN( _hr, _riid ); \ } while ( 0 )
#define QIRETURN6( _hr, _riid, _riidIgnored1, _riidIgnored2, _riidIgnored3, _riidIgnored4, _riidIgnored5, _riidIgnored6 ) \
do \ { \ if ( _hr == E_NOINTERFACE \ && ( IsEqualIID( _riid, _riidIgnored1 ) \ || IsEqualIID( _riid, _riidIgnored2 ) \ || IsEqualIID( _riid, _riidIgnored3 ) \ || IsEqualIID( _riid, _riidIgnored4 ) \ || IsEqualIID( _riid, _riidIgnored5 ) \ || IsEqualIID( _riid, _riidIgnored6 ) \ ) \ ) \ { \ FRETURN( S_OK ); \ return( _hr ); \ } \ QIRETURN( _hr, _riid ); \ } while ( 0 )
#define QIRETURN7( _hr, _riid, _riidIgnored1, _riidIgnored2, _riidIgnored3, _riidIgnored4, _riidIgnored5, _riidIgnored6, _riidIgnored7 ) \
do \ { \ if ( _hr == E_NOINTERFACE \ && ( IsEqualIID( _riid, _riidIgnored1 ) \ || IsEqualIID( _riid, _riidIgnored2 ) \ || IsEqualIID( _riid, _riidIgnored3 ) \ || IsEqualIID( _riid, _riidIgnored4 ) \ || IsEqualIID( _riid, _riidIgnored5 ) \ || IsEqualIID( _riid, _riidIgnored6 ) \ || IsEqualIID( _riid, _riidIgnored7 ) \ ) \ ) \ { \ FRETURN( S_OK ); \ return( _hr ); \ } \ QIRETURN( _hr, _riid ); \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// QIRETURN_IGNORESTDMARSHALLING(
// _hr,
// _riid
// )
//
// Description:
// Works like QIRETURN (see QIRETURN above), but ignores E_NOINTERFACE for
// the standard marshalling interfaces.
//
// Arguments:
// _hr - Result of the query interface call.
// _riid - The reference ID of the interfaced queried for.
//
// Return Values:
// None - calls QIRETURN5 macro.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define QIRETURN_IGNORESTDMARSHALLING( _hr, _riid ) \
do \ { \ const GUID _COCLASS_IdentityUnmarshall = { 0x0000001b, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }; \ const GUID _IID_IMarshalOptions_ = { 0x4c1e39e1, 0xe3e3, 0x4296, 0xaa, 0x86, 0xec, 0x93, 0x8d, 0x89, 0x6e, 0x92 }; \ QIRETURN6( _hr, _riid, IID_IMarshal, _COCLASS_IdentityUnmarshall, IID_IStdMarshalInfo, IID_IExternalConnection, IID_ICallFactory, _IID_IMarshalOptions_ ); \ } while ( 0 )
#define QIRETURN_IGNORESTDMARSHALLING1( _hr, _riid, _riid1 ) \
do \ { \ const GUID _COCLASS_IdentityUnmarshall = { 0x0000001b, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }; \ const GUID _IID_IMarshalOptions_ = { 0x4c1e39e1, 0xe3e3, 0x4296, 0xaa, 0x86, 0xec, 0x93, 0x8d, 0x89, 0x6e, 0x92 }; \ QIRETURN7( _hr, _riid, IID_IMarshal, _COCLASS_IdentityUnmarshall, IID_IStdMarshalInfo, IID_IExternalConnection, IID_ICallFactory, _riid1, _IID_IMarshalOptions_ ); \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// BOOLTOSTRING(
// _fBool
// )
//
// Desfription:
// If _fBool is true, returns address of "TRUE" else returns address of
// "FALSE".
//
// Argument:
// _fBool - Expression to evaluate.
//
// Return Values:
// address of "TRUE" if _fBool is true.
// address of "FALSE" if _fBool is false.
//
//--
//////////////////////////////////////////////////////////////////////////////
#define BOOLTOSTRING( _fBool ) ( (_fBool) ? g_szTrue : g_szFalse )
//****************************************************************************
//
// Trace/Debug Functions - these do not exist in RETAIL.
//
//****************************************************************************
BOOL IsDebugFlagSet( TRACEFLAG tfIn );
void __cdecl TraceMsg( TRACEFLAG tfIn, LPCSTR pszFormatIn, ... );
void __cdecl TraceMsg( TRACEFLAG tfIn, LPCWSTR pszFormatIn, ... );
void __cdecl DebugMsg( LPCSTR pszFormatIn, ... );
void __cdecl DebugMsg( LPCWSTR pszFormatIn, ... );
void __cdecl DebugMsgNoNewline( LPCSTR pszFormatIn, ... );
void __cdecl DebugMsgNoNewline( LPCWSTR pszFormatIn, ... );
void __cdecl TraceMessage( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, TRACEFLAG tfIn, LPCTSTR pszFormatIn, ... );
void __cdecl TraceMessageDo( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, TRACEFLAG tfIn, LPCTSTR pszFormatIn, LPCTSTR pszFuncIn, ... );
void __cdecl DebugMessage( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, LPCTSTR pszFormatIn, ... );
void __cdecl DebugMessageDo( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, LPCTSTR pszFormatIn, LPCTSTR pszFuncIn, ... );
BOOL AssertMessage( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, LPCTSTR pszfnIn, BOOL fTrueIn, ... );
HRESULT TraceHR( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, LPCTSTR pszfnIn, HRESULT hrIn, BOOL fSuccessIn, HRESULT hrIgnoreIn, ... );
ULONG TraceWin32( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, LPCTSTR pszfnIn, ULONG ulErrIn, ULONG ulErrIgnoreIn, ... );
void __cdecl TraceLogMsgNoNewline( LPCSTR pszFormatIn, ... );
void __cdecl TraceLogMsgNoNewline( LPCWSTR pszFormatIn, ... );
#if 0
//
// Trying to get the NTSTATUS stuff to play in "user world"
// is just about impossible. This is here in case it is needed
// and one could find the right combination of headers to
// make it work. Inflicting such pain on others is the reason
// why this function is #ifdef'fed.
//
void DebugFindNTStatusSymbolicName( NTSTATUS dwStatusIn, LPTSTR pszNameOut, LPDWORD pcchNameInout ); #endif
void DebugFindWinerrorSymbolicName( DWORD dwErrIn, LPTSTR pszNameOut, LPDWORD pcchNameInout );
void DebugReturnMessage( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, LPCTSTR pszMessageIn, DWORD dwErrIn );
//****************************************************************************
//
// Use the TraceMemoryXXX wrappers, not the DebugMemoryXXX functions.
// The memory tracking functions do not exist in RETAIL (converted to NOP).
//
//****************************************************************************
typedef enum EMEMORYBLOCKTYPE { mmbtUNKNOWN = 0, // Never used
mmbtMEMORYALLOCATION, // GlobalAlloc/LocalAlloc/malloc
mmbtOBJECT, // Object pointer
mmbtHANDLE, // Object handle
mmbtPUNK, // IUnknown pointer
mmbtSYSALLOCSTRING // SysAllocString
} EMEMORYBLOCKTYPE;
#define TraceMemoryAdd( _mbtType, _hGlobalIn, _pszFileIn, _nLineIn, _pszModuleIn, _dwBytesIn, _pszCommentIn ) \
DebugMemoryAdd( _mbtType, _hGlobalIn, _pszFileIn, _nLineIn, _pszModuleIn, _dwBytesIn, _pszCommentIn )
#define TraceMemoryAddAddress( _pv ) \
DebugMemoryAdd( mmbtMEMORYALLOCATION, _pv, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_pv) )
#define TraceMemoryAddHandle( _handle ) \
DebugMemoryAdd( mmbtHANDLE, _handle, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_handle) )
#define TraceMemoryAddObject( _pv ) \
DebugMemoryAdd( mmbtOBJECT, _pv, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_pv) )
#define TraceMemoryAddPunk( _punk ) \
DebugMemoryAdd( mmbtPUNK, _punk, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_punk) )
#define TraceMemoryAddBSTR( _pv ) \
DebugMemoryAdd( mmbtSYSALLOCSTRING, _pv, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_pv) )
#define TraceMemoryDelete( _hGlobalIn, _fClobberIn ) \
DebugMemoryDelete( mmbtUNKNOWN, _hGlobalIn, TEXT(__FILE__), __LINE__, __MODULE__, _fClobberIn )
#define TraceStrDup( _sz ) \
(LPTSTR) DebugMemoryAdd( mmbtMEMORYALLOCATION, StrDup( _sz ), TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT("StrDup( ") TEXT(#_sz) TEXT(" )") )
#if defined( USES_SYSALLOCSTRING )
// BUGBUG: DavidP 09-DEC-1999
// _sz is evaluated multiple times but the name of the
// macro is mixed case.
#define TraceSysAllocString( _sz ) \
(BSTR) DebugMemoryAdd( mmbtSYSALLOCSTRING, SysAllocString( _sz ), TEXT(__FILE__), __LINE__, __MODULE__, ((DWORD)( *(&_sz) == NULL ? 0 : wcslen( _sz ) + 1 )), TEXT("SysAllocString( ") TEXT(#_sz) TEXT(")") )
// BUGBUG: DavidP 09-DEC-1999
// _sz and _len are evaluated multiple times but the name of the
// macro is mixed case.
#define TraceSysAllocStringByteLen( _sz, _len ) \
(BSTR) DebugMemoryAdd( mmbtSYSALLOCSTRING, SysAllocStringByteLen( _sz, _len ), TEXT(__FILE__), __LINE__, __MODULE__, _len, TEXT("SysAllocStringByteLen( ") TEXT(#_sz) TEXT(")") )
// BUGBUG: DavidP 09-DEC-1999
// _sz and _len are evaluated multiple times but the name of the
// macro is mixed case.
#define TraceSysAllocStringLen( _sz, _len ) \
(BSTR) DebugMemoryAdd( mmbtSYSALLOCSTRING, SysAllocStringLen( _sz, _len ), TEXT(__FILE__), __LINE__, __MODULE__, _len + 1, TEXT("SysAllocStringLen( ") TEXT(#_sz) TEXT(")") )
#define TraceSysReAllocString( _bstrOrg, _bstrNew ) \
DebugSysReAllocString( TEXT(__FILE__), __LINE__, __MODULE__, _bstrOrg, _bstrNew, TEXT("TraceSysReAllocString(") TEXT(#_bstrOrg) TEXT(", ") TEXT(#_bstrNew) TEXT(" )") )
#define TraceSysReAllocStringLen( _bstrOrg, _bstrNew, _cch ) \
DebugSysReAllocStringLen( TEXT(__FILE__), __LINE__, __MODULE__, _bstrOrg, _bstrNew, _cch, TEXT("TraceSysReAllocString(") TEXT(#_bstrOrg) TEXT(", ") TEXT(#_bstrNew) TEXT(", ") TEXT(#_cch) TEXT(" )") )
#define TraceSysFreeString( _bstr ) \
DebugMemoryDelete( mmbtSYSALLOCSTRING, _bstr, TEXT(__FILE__), __LINE__, __MODULE__, TRUE ); \ SysFreeString( _bstr ) #endif // USES_SYSALLOCSTRING
//****************************************************************************
//
// Memory tracing functions - these are remapped to the GlobalAlloc/GlobalFree
// heap functions when in RETAIL. Use the TraceMemoryXXX wrappers, not the
// DebugMemoryXXX functions.
//
//****************************************************************************
void * DebugAlloc( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, UINT uFlagsIn, DWORD dwBytesIn, LPCTSTR pszCommentIn );
void * DebugReAlloc( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, void * pvMemIn, UINT uFlagsIn, DWORD dwBytesIn, LPCTSTR pszCommentIn );
BOOL DebugFree( void * pvMemIn, LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn );
void * DebugMemoryAdd( EMEMORYBLOCKTYPE mbtType , void * pvMemIn , LPCTSTR pszFileIn , const int nLineIn , LPCTSTR pszModuleIn , DWORD dwBytesIn , LPCTSTR pszCommentIn );
void DebugMemoryDelete( EMEMORYBLOCKTYPE mbtTypeIn , void * pvMemIn , LPCTSTR pszFileIn , const int nLineIn , LPCTSTR pszModuleIn , BOOL fClobberIn );
#if defined( USES_SYSALLOCSTRING )
INT DebugSysReAllocString( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, BSTR * pbstrIn, const OLECHAR * pszIn, LPCTSTR pszCommentIn );
INT DebugSysReAllocStringLen( LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn, BSTR * pbstrIn, const OLECHAR * pszIn, unsigned int ucchIn, LPCTSTR pszCommentIn );
#endif // USES_SYSALLOCSTRING
void DebugMemoryCheck( LPVOID pvListIn, LPCTSTR pszListNameIn );
//****************************************************************************
//
// operator new() for C++
//
//****************************************************************************
#ifdef __cplusplus
extern void * __cdecl operator new( size_t nSizeIn, LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn ); /*
//****************************************************************************
//
// operator new []() for C++
//
//****************************************************************************
extern void * __cdecl operator new []( size_t nSizeIn, LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn ); */ //****************************************************************************
//
// operator delete() for C++
//
//****************************************************************************
extern void __cdecl operator delete( void * pMem, LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn ); /*
//****************************************************************************
//
// operator delete []() for C++
//
//****************************************************************************
extern void __cdecl operator delete []( void * pMemIn, size_t stSizeIn, LPCTSTR pszFileIn, const int nLineIn, LPCTSTR pszModuleIn ); */ //
// Remap "new" to our macro so "we" don't have to type anything extra and
// so it magically dissappears in RETAIL.
//
#define new new( TEXT(__FILE__), __LINE__, __MODULE__ )
#endif
//****************************************************************************
//
//
#else // it's RETAIL ******************************************************
//
//
//****************************************************************************
#pragma message("BUILD: RETAIL macros being built")
//
// Debugging -> NOPs
//
#define DEFINE_MODULE( _module )
#define __MODULE__ NULL
#define DEFINE_THISCLASS( _class )
#define __THISCLASS__ NULL
//#define DEFINE_SUPER( _super )
//#define __SUPERCLASS__ NULL
#define BOOLTOSTRING( _fBool ) NULL
#define DebugDo( _fn )
#define DebugMsgDo( _fn, _msg )
#define TraceMsgGUID( _f, _m, _g )
#define AssertMessage TRUE
//
// TODO: gpease 08-NOV-1999
// We probably want to do something special for ErrorMsg()
//
#define ErrorMsg 1 ? (void)0 : (void)__noop
#define TraceMsg 1 ? (void)0 : (void)__noop
#define WndMsg 1 ? (void)0 : (void)__noop
#define DebugMsg 1 ? (void)0 : (void)__noop
#define DebugMsgNoNewline 1 ? (void)0 : (void)__noop
#define TraceMessage 1 ? (void)0 : (void)__noop
#define DebugMessage 1 ? (void)0 : (void)__noop
#define TraceHR 1 ? (void)0 : (void)__noop
#define TraceFunc 1 ? (void)0 : (void)__noop
#define TraceFunc1 1 ? (void)0 : (void)__noop
#define TraceFunc2 1 ? (void)0 : (void)__noop
#define TraceFunc3 1 ? (void)0 : (void)__noop
#define TraceFunc4 1 ? (void)0 : (void)__noop
#define TraceFunc5 1 ? (void)0 : (void)__noop
#define TraceFunc6 1 ? (void)0 : (void)__noop
#define TraceQIFunc 1 ? (void)0 : (void)__noop
#define TraceFlow 1 ? (void)0 : (void)__noop
#define TraceFlow1 1 ? (void)0 : (void)__noop
#define TraceFlow2 1 ? (void)0 : (void)__noop
#define TraceFlow3 1 ? (void)0 : (void)__noop
#define TraceFlow4 1 ? (void)0 : (void)__noop
#define TraceFlow5 1 ? (void)0 : (void)__noop
#define TraceFlow6 1 ? (void)0 : (void)__noop
#define TraceFuncExit() return
#if defined( DEBUG_SW_TRACING_ENABLED )
#define TraceInitializeProcess( _rgControl, _sizeofControl, _fGlobalMemoryTackingIn )
#define TraceTerminateProcess( _rgControl, _sizeofControl )
#else // ! DEBUG_SW_TRACING_ENABLED
#define TraceInitializeProcess( _fGlobalMemoryTackingIn )
#define TraceTerminateProcess()
#endif // DEBUG_SW_TRACING_ENABLED
#define TraceInitializeThread( _name )
#define TraceThreadRundown()
#define TraceMemoryAdd( _mbtType, _hGlobalIn, _pszFileIn, _nLineIn, _pszModuleIn, _uFlagsIn, _dwBytesIn, _pszCommentIn ) _hGlobalIn
#define TraceMemoryAddHandle( _handle ) _handle
#define TraceMemoryAddBSTR( _bstr ) _bstr
#define TraceMemoryAddAddress( _pv ) _pv
#define TraceMemoryAddHandle( _obj ) _obj
#define TraceMemoryAddPunk( _punk ) _punk
#define TraceMemoryDelete( _h, _b ) _h
#define TraceMemoryAddObject( _pv ) _pv
#define IsTraceFlagSet( _flag ) FALSE
//
// Tracing -> just do operation
//
#define TraceDo( _fn ) _fn
#define TraceMsgDo( _fn, _msg ) _fn
#define TraceMsgDo1( _fn, _msg, _arg1 ) _fn
#define TraceMsgDo2( _fn, _msg, _arg1, _arg2 ) _fn
#define TraceMsgDo3( _fn, _msg, _arg1, _arg2, _arg3 ) _fn
#define TraceMsgDo4( _fn, _msg, _arg1, _arg2, _arg3, _arg4 ) _fn
#define TraceMsgDo5( _fn, _msg, _arg1, _arg2, _arg3, _arg4, _arg5 ) _fn
#define TraceMsgDo6( _fn, _msg, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) _fn
#define TraceMsgPreDo( _fn, _msg1, _msg2 ) _fn
#define TraceMsgPreDo1( _fn, _msg1, _msg2, _arg1 ) _fn
#define TraceMsgPreDo2( _fn, _msg1, _msg2, _arg1, _arg2 ) _fn
#define TraceMsgPreDo3( _fn, _msg1, _msg2, _arg1, _arg2, _arg3 ) _fn
#define TraceMsgPreDo4( _fn, _msg1, _msg2, _arg1, _arg2, _arg3, _arg4 ) _fn
#define TraceMsgPreDo5( _fn, _msg1, _msg2, _arg1, _arg2, _arg3, _arg4, _arg5 ) _fn
#define TraceMsgPreDo6( _fn, _msg1, _msg2, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) _fn
#define TraceAssertIfZero( _fn ) _fn
//
// RETURN testing -> do retail
//
#define THR( _hr ) _hr
#define THRMSG( _hr, _msg ) _hr
#define THRMSG1( _hr, _msg, _arg1 ) _hr
#define THRE( _hr, _hrIgnore ) _hr
#define THREMSG( _hr, _hrIgnore, _msg ) _hr
#define THREMSG1( _hr, _hrIgnore, _msg, _arg1 ) _hr
#define STHR( _hr ) _hr
#define STHRMSG( _hr, _msg ) _hr
#define STHRMSG1( _hr, _msg, _arg1 ) _hr
#define STHRE( _hr, _hrIgnore ) _hr
#define STHREMSG( _hr, _hrIgnore, _msg ) _hr
#define STHREMSG1( _hr, _hrIgnore, _msg, _arg1 ) _hr
#define TW32( _fn ) _fn
#define TW32MSG( _fn, _msg ) _fn
#define TW32MSG1( _fn, _msg, _arg1 ) _fn
#define TW32E( _fn, _errIgnore ) _fn
#define TW32EMSG( _fn, _errIgnore, _msg ) _fn
#define TW32EMSG1( _fn, _errIgnore, _msg, _arg1 ) _fn
#define RETURN( _fn ) return _fn
#define FRETURN( _fn )
#define RRETURN( _fn ) return _fn
#define HRETURN( _hr ) return _hr
#define QIRETURN( _qi, _riid ) return _qi
#define QIRETURN1( _qi, _riid, _riid1 ) return _qi
#define QIRETURN2( _qi, _riid, _riid1, _riid2 ) return _qi
#define QIRETURN3( _qi, _riid, _riid1, _riid2, _riid3 ) return _qi
#define QIRETURN4( _qi, _riid, _riid1, _riid2, _riid3, _riid4 ) return _qi
#define QIRETURN5( _qi, _riid, _riid1, _riid2, _riid3, _riid4, _riid5 ) return _qi
#define QIRETURN6( _qi, _riid, _riid1, _riid2, _riid3, _riid4, _riid5, _riid6 ) return _qi
#define QIRETURN7( _qi, _riid, _riid1, _riid2, _riid3, _riid4, _riid5, _riid6, _riid7 ) return _qi
#define QIRETURN_IGNORESTDMARSHALLING( _qi, _riid ) return _qi
#define QIRETURN_IGNORESTDMARSHALLING1( _qi, _riid, _riid1 ) return _qi
//
// Memory Functions -> do retail
//
#define TraceAlloc( _flags, _size ) HeapAlloc( GetProcessHeap(), _flags, _size )
#define TraceAllocString( _flags, _size ) (LPTSTR) HeapAlloc( GetProcessHeap(), flags, (_size) * sizeof( TCHAR ) )
#define TraceReAlloc( _pvMem, _uBytes, _uFlags ) ( ( _pvMem == NULL ) \
? HeapAlloc( GetProcessHeap(), _uFlags, _uBytes ) \ : HeapReAlloc( GetProcessHeap(), _uFlags, _pvMem, _uBytes ) ) #define TraceFree( _pv ) HeapFree( GetProcessHeap(), 0, _pv )
#define TraceStrDup( _sz ) StrDup( _sz )
#define TraceSysAllocString( _sz ) SysAllocString( _sz )
#define TraceSysAllocStringByteLen( _sz, _len ) SysAllocStringByteLen( _sz, _len )
#define TraceSysAllocStringLen( _sz, _len ) SysAllocStringLen( _sz, _len )
#define TraceSysReAllocString( _bstrOrg, _bstrNew ) SysReAllocString( _bstrOrg, _bstrNew )
#define TraceSysReAllocStringLen( _bstrOrg, _bstrNew, _cch ) SysReAllocStringLen( _bstrOrg, _bstrNew, _cch )
#define TraceSysFreeString( _bstr ) SysFreeString( _bstr )
#define TraceCreateMemoryList( _pvIn )
#define TraceMoveToMemoryList( _addr, _pvIn )
//#define TraceMemoryListDelete( _addr, _pvIn, _fClobber )
#define TraceTerminateMemoryList( _pvIn )
#define TraceMoveFromMemoryList( _addr, _pmbIn )
#endif // DEBUG
#if DBG==1 || defined( _DEBUG )
//////////////////////////////////////////////////////////////////////////////
//
// MACRO
// DEBUG_BREAK
//
// Description:
// Because the system expection handler can hick-up over INT 3s and
// DebugBreak()s, This x86 only macro causes the program to break in the
// right spot.
//
//////////////////////////////////////////////////////////////////////////////
#if defined( _X86_ )
#define DEBUG_BREAK do { _try { _asm int 3 } _except (EXCEPTION_EXECUTE_HANDLER) {;} } while ( 0 )
#else
#define DEBUG_BREAK DebugBreak()
#endif
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// Assert(
// _fn
// )
//
// Description:
// Checks to see if the Expression is TRUE. If not, a message will be
// displayed to the user on wether the program should break or continue.
//
// Arguments:
// _fn - Expression being asserted.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#ifdef Assert
#undef Assert
#endif
// BUGBUG: DavidP 09-DEC-1999
// __fn is evaluated multiple times but the name of the
// macro is mixed case.
#define Assert( _fn ) \
do \ { \ if ( ! (_fn) && AssertMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_fn), !!(_fn) ) ) \ { \ DEBUG_BREAK; \ } \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// AssertMsg(
// _fn,
// _msg
// )
//
// Descrption:
// Just like an Assert but has an (hopefully) informative message
// associated with it.
//
// Arguments:
// _fn - Expression to be evaluated.
// _msg - Message to be display if assertion fails.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#ifdef AssertMsg
#undef AssertMsg
#undef AssertMsg1
#endif
// BUGBUG: DavidP 09-DEC-1999
// _fn is evaluated multiple times but the name of the
// macro is mixed case.
#define AssertMsg( _fn, _msg ) \
do \ { \ if ( ! (_fn) && AssertMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), !!(_fn) ) ) \ { \ DEBUG_BREAK; \ } \ } while ( 0 ) #define AssertMsg1( _fn, _msg, _arg1 ) \
do \ { \ if ( ! (_fn) && AssertMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), !!(_fn), _arg1 ) ) \ { \ DEBUG_BREAK; \ } \ } while ( 0 )
//////////////////////////////////////////////////////////////////////////////
//++
//
// MACRO
// AssertString(
// _fn,
// _msg
// )
//
// Descrption:
// Just like an Assert but has a (hopefully) informative string
// associated with it.
//
// Arguments:
// _fn - Expression to be evaluated.
// _msg - String to be display if assertion fails.
//
// Return Values:
// None.
//
//--
//////////////////////////////////////////////////////////////////////////////
#ifdef AssertString
#undef AssertString
#endif
// BUGBUG: DavidP 09-DEC-1999
// _fn is evaluated multiple times but the name of the
// macro is mixed case.
#define AssertString( _fn, _str ) \
do \ { \ if ( ! (_fn) && AssertMessage( TEXT(__FILE__), __LINE__, __MODULE__, _str, !!(_fn) ) ) \ { \ DEBUG_BREAK; \ } \ } while ( 0 )
#undef VERIFY
#undef VERIFYMSG
#undef VERIFYMSG1
#undef VERIFYSTRING
#define VERIFY( _fn ) Assert( _fn )
#define VERIFYMSG( _fn, _msg ) AssertMsg( _fn, _msg )
#define VERIFYMSG1( _fn, _msg, _arg1 ) AssertMsg1( _fn, _msg, _arg1 )
#define VERIFYSTRING( _fn, _str ) AssertString( _fn, _str )
#else // DBG!=1 && !_DEBUG
#define DEBUG_BREAK DebugBreak()
#ifndef Assert
#define Assert( _fn )
#endif
#ifndef AssertMsg
#define AssertMsg( _fn, _msg )
#endif
#ifndef AssertMsg1
#define AssertMsg1( _fn, _msg, _arg1 )
#endif
#ifndef AssertString
#define AssertString( _fn, _msg )
#endif
#ifndef VERIFY
#define VERIFY( _fn ) _fn
#endif
#ifndef VERIFYMSG
#define VERIFYMSG( _fn, _msg ) _fn
#endif
#ifndef VERIFYMSG1
#define VERIFYMSG1( _fn, _msg, _arg1 ) _fn
#endif
#ifndef VERIFYSTRING
#define VERIFYSTRING( _fn, _str ) _fn
#endif
#endif // DBG==1 || _DEBUG
|