872 lines
19 KiB
C++
872 lines
19 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 1998-1999 Microsoft Corporation
|
||
|
All rights reserved.
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
dbgmsgp.cxx
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Debug Library
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Steve Kiraly (SteveKi) 10-Dec-1995
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
#include "precomp.hxx"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
TDebugMsg::
|
||
|
TDebugMsg(
|
||
|
VOID
|
||
|
) : m_eLevel(static_cast<EDebugLevel>(0)),
|
||
|
m_eBreak(static_cast<EDebugLevel>(0)),
|
||
|
m_pDeviceRoot(NULL),
|
||
|
m_pstrPrefix(NULL),
|
||
|
m_pBuiltinDeviceRoot(NULL)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
TDebugMsg::
|
||
|
~TDebugMsg(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
TDebugMsg::
|
||
|
Valid(
|
||
|
VOID
|
||
|
) const
|
||
|
{
|
||
|
return !!m_pBuiltinDeviceRoot;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
TDebugMsg::
|
||
|
Disable(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
m_eLevel = static_cast<EDebugLevel>( m_eLevel | kDbgNone );
|
||
|
m_eBreak = static_cast<EDebugLevel>( m_eBreak | kDbgNone );
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
TDebugMsg::
|
||
|
Enable(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
m_eLevel = static_cast<EDebugLevel>( m_eLevel & ~kDbgNone );
|
||
|
m_eBreak = static_cast<EDebugLevel>( m_eBreak & ~kDbgNone );
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
TDebugMsg::
|
||
|
Type(
|
||
|
IN EDebugLevel eLevel
|
||
|
) const
|
||
|
{
|
||
|
return !(m_eLevel & kDbgNone) && ((m_eLevel & eLevel) || (eLevel & kDbgAlways));
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
TDebugMsg::
|
||
|
Break(
|
||
|
IN EDebugLevel eLevel
|
||
|
) const
|
||
|
{
|
||
|
return m_eBreak & eLevel;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
Initialize
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
VOID
|
||
|
TDebugMsg::
|
||
|
Initialize(
|
||
|
IN LPCTSTR pszPrefix,
|
||
|
IN UINT uDevice,
|
||
|
IN INT eLevel,
|
||
|
IN INT eBreak
|
||
|
)
|
||
|
{
|
||
|
if (!m_pBuiltinDeviceRoot)
|
||
|
{
|
||
|
BOOL bRetval = FALSE;
|
||
|
|
||
|
//
|
||
|
// Set the debug message and break level.
|
||
|
//
|
||
|
m_eLevel = static_cast<EDebugLevel>(eLevel & ~kDbgPrivateMask);
|
||
|
m_eBreak = static_cast<EDebugLevel>(eBreak & ~kDbgPrivateMask);
|
||
|
|
||
|
//
|
||
|
// Set the global device flags.
|
||
|
//
|
||
|
if (!Globals.DebugDevices)
|
||
|
{
|
||
|
Globals.DebugDevices = uDevice & (kDbgNull | kDbgDebugger | kDbgFile);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set the character type to current compiled type.
|
||
|
//
|
||
|
m_eLevel = static_cast<EDebugLevel>(m_eLevel | Globals.CompiledCharType);
|
||
|
|
||
|
//
|
||
|
// Set the prefix string.
|
||
|
//
|
||
|
m_pstrPrefix = INTERNAL_NEW TDebugString(pszPrefix ? pszPrefix : kstrPrefix);
|
||
|
|
||
|
//
|
||
|
// Set the prefix string.
|
||
|
//
|
||
|
if (m_pstrPrefix && m_pstrPrefix->bValid() && m_pstrPrefix->bCat( _T(":")))
|
||
|
{
|
||
|
//
|
||
|
// Set the additional format strings.
|
||
|
//
|
||
|
m_pstrFileInfoFormat = INTERNAL_NEW TDebugString(kstrFileInfoFormat);
|
||
|
m_pstrTimeStampFormatShort = INTERNAL_NEW TDebugString(kstrTimeStampFormatShort);
|
||
|
m_pstrTimeStampFormatLong = INTERNAL_NEW TDebugString(kstrTimeStampFormatLong);
|
||
|
m_pstrThreadIdFormat = INTERNAL_NEW TDebugString(kstrThreadIdFormat);
|
||
|
|
||
|
if( m_pstrFileInfoFormat && m_pstrFileInfoFormat->bValid() &&
|
||
|
m_pstrTimeStampFormatShort && m_pstrTimeStampFormatShort->bValid() &&
|
||
|
m_pstrTimeStampFormatLong && m_pstrTimeStampFormatLong->bValid() &&
|
||
|
m_pstrThreadIdFormat && m_pstrThreadIdFormat->bValid() )
|
||
|
{
|
||
|
//
|
||
|
// Attach the default debug devices.
|
||
|
//
|
||
|
if(Attach(NULL, kDbgDebugger, NULL, &m_pBuiltinDeviceRoot) &&
|
||
|
Attach(NULL, kDbgFile, kstrDefaultLogFileName, &m_pBuiltinDeviceRoot) &&
|
||
|
Attach(NULL, kDbgNull, NULL, &m_pBuiltinDeviceRoot))
|
||
|
{
|
||
|
bRetval = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ErrorText( _T("Error: TDebugMsg::Initialize - A default debug device failed to attach!\n") );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ErrorText( _T("Error: TDebugMsg::Initialize - format string failed construction!\n") );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ErrorText( _T("Error: TDebugMsg::Initialize - Debug prefix string failed allocation!\n") );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If we failed then unregister, cleanup.
|
||
|
//
|
||
|
if (!bRetval)
|
||
|
{
|
||
|
Destroy();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ErrorText( _T("Error: TDebugMsg::Initialize already initalized!\n") );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
Destroy
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Destroys the internal state of this class, this function
|
||
|
does the same work the destructor would.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
VOID
|
||
|
TDebugMsg::
|
||
|
Destroy(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// Release the debug device.
|
||
|
//
|
||
|
while( m_pDeviceRoot )
|
||
|
{
|
||
|
TDebugNodeDouble *pNode = m_pDeviceRoot;
|
||
|
pNode->Remove( &m_pDeviceRoot );
|
||
|
TDebugFactory::Dispose( static_cast<TDebugDevice *>( pNode ) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Release the builtin debug device.
|
||
|
//
|
||
|
while( m_pBuiltinDeviceRoot )
|
||
|
{
|
||
|
TDebugNodeDouble *pNode = m_pBuiltinDeviceRoot;
|
||
|
pNode->Remove( &m_pBuiltinDeviceRoot );
|
||
|
TDebugFactory::Dispose( static_cast<TDebugDevice *>( pNode ) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Release the string objects.
|
||
|
//
|
||
|
INTERNAL_DELETE m_pstrPrefix;
|
||
|
INTERNAL_DELETE m_pstrFileInfoFormat;
|
||
|
INTERNAL_DELETE m_pstrTimeStampFormatShort;
|
||
|
INTERNAL_DELETE m_pstrTimeStampFormatLong;
|
||
|
INTERNAL_DELETE m_pstrThreadIdFormat;
|
||
|
|
||
|
//
|
||
|
// Indicate we are not registered.
|
||
|
//
|
||
|
m_eLevel = static_cast<EDebugLevel>(0);
|
||
|
m_eBreak = static_cast<EDebugLevel>(0);
|
||
|
m_pDeviceRoot = NULL;
|
||
|
m_pBuiltinDeviceRoot = NULL;
|
||
|
m_pstrPrefix = NULL;
|
||
|
m_pstrFileInfoFormat = NULL;
|
||
|
m_pstrTimeStampFormatShort = NULL;
|
||
|
m_pstrTimeStampFormatLong = NULL;
|
||
|
m_pstrThreadIdFormat = NULL;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
Attach
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Attach debug device to list of output devices.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
uDevice - Type of debug device to use.
|
||
|
pszConfiguration - Pointer to configuration string.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE debug device attached, FALSE if error occurred.
|
||
|
|
||
|
--*/
|
||
|
BOOL
|
||
|
TDebugMsg::
|
||
|
Attach(
|
||
|
IN HANDLE *phDevice,
|
||
|
IN UINT uDevice,
|
||
|
IN LPCTSTR pszConfiguration,
|
||
|
IN TDebugNodeDouble **ppDeviceRoot
|
||
|
)
|
||
|
{
|
||
|
BOOL bRetval = FALSE;
|
||
|
|
||
|
//
|
||
|
// Get access to the debug factory.
|
||
|
//
|
||
|
TDebugFactory DebugFactory;
|
||
|
|
||
|
//
|
||
|
// If we failed to create the debug factory then exit.
|
||
|
//
|
||
|
if (DebugFactory.bValid())
|
||
|
{
|
||
|
//
|
||
|
// Create the specified debug device using the factory.
|
||
|
//
|
||
|
TDebugDevice *pDebugDevice = DebugFactory.Produce(uDevice,
|
||
|
pszConfiguration,
|
||
|
m_eLevel & kDbgUnicode);
|
||
|
|
||
|
//
|
||
|
// Check if the debug device was created ok.
|
||
|
//
|
||
|
if (pDebugDevice)
|
||
|
{
|
||
|
//
|
||
|
// Place this device on the debug device list.
|
||
|
//
|
||
|
if (ppDeviceRoot)
|
||
|
{
|
||
|
pDebugDevice->Insert(ppDeviceRoot);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pDebugDevice->Insert(&m_pDeviceRoot);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Copy back the pointer to the debug device.
|
||
|
//
|
||
|
if (phDevice)
|
||
|
{
|
||
|
*phDevice = (HANDLE)pDebugDevice;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Successfully attached debug device.
|
||
|
//
|
||
|
bRetval = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ErrorText( _T("Error: TDebugMsg::bAttach - Debug device creation failed!\n") );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ErrorText( _T("Error: TDebugMsg::bAttach - Debug factory creation failed!\n") );
|
||
|
}
|
||
|
|
||
|
return bRetval;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
Detach
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Detach the debug device from the device stream.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
phDevice - Pointer to debug device handle.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
VOID
|
||
|
TDebugMsg::
|
||
|
Detach(
|
||
|
IN HANDLE *phDevice
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// We silently ignore non initialized devices, or null pointers.
|
||
|
//
|
||
|
if (phDevice && *phDevice)
|
||
|
{
|
||
|
//
|
||
|
// Get a usable pointer.
|
||
|
//
|
||
|
TDebugDevice *pDebugDevice = (TDebugDevice *)*phDevice;
|
||
|
|
||
|
//
|
||
|
// Remove this device from the debug device list.
|
||
|
//
|
||
|
pDebugDevice->Remove( &m_pDeviceRoot );
|
||
|
|
||
|
//
|
||
|
// Dispose of the device.
|
||
|
//
|
||
|
TDebugFactory::Dispose( pDebugDevice );
|
||
|
|
||
|
//
|
||
|
|
||
|
// Mark this device as released.
|
||
|
//
|
||
|
*phDevice = NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ErrorText( _T("Error: TDebugMsg::vDetach - non initialized or null pointer!\n") );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
Msg
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is public overloaded function for
|
||
|
sending the message to the output devices.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
eLevel - requested message level
|
||
|
pszFile - pointer to file name where message was called
|
||
|
uLine - line number where message was called
|
||
|
pszModulePrefix - message defined module prefix, used as an override
|
||
|
pszMessage - pointer to post formated message string
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
VOID
|
||
|
TDebugMsg::
|
||
|
Msg(
|
||
|
IN UINT eLevel,
|
||
|
IN LPCTSTR pszFile,
|
||
|
IN UINT uLine,
|
||
|
IN LPCTSTR pszModulePrefix,
|
||
|
IN LPSTR pszMessage
|
||
|
) const
|
||
|
{
|
||
|
if (pszMessage)
|
||
|
{
|
||
|
if (Type(static_cast<EDebugLevel>(eLevel)))
|
||
|
{
|
||
|
StringTrait StrMessage;
|
||
|
|
||
|
StrMessage.pszNarrow = pszMessage;
|
||
|
|
||
|
eLevel = eLevel & ~kDbgUnicode;
|
||
|
|
||
|
Output(static_cast<EDebugLevel>(eLevel), pszFile, uLine, pszModulePrefix, StrMessage);
|
||
|
|
||
|
if (Break(static_cast<EDebugLevel>(eLevel)))
|
||
|
{
|
||
|
DebugBreak();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INTERNAL_DELETE [] pszMessage;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
Msg
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function is public overloaded function for
|
||
|
sending the message to the output devices.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
eLevel - requested message level
|
||
|
pszFile - pointer to file name where message was called
|
||
|
uLine - line number where message was called
|
||
|
pszModulePrefix - message defined module prefix, used as an override
|
||
|
pszMessage - pointer to post formated message string
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
VOID
|
||
|
TDebugMsg::
|
||
|
Msg(
|
||
|
IN UINT eLevel,
|
||
|
IN LPCTSTR pszFile,
|
||
|
IN UINT uLine,
|
||
|
IN LPCTSTR pszModulePrefix,
|
||
|
IN LPWSTR pszMessage
|
||
|
) const
|
||
|
{
|
||
|
if (pszMessage)
|
||
|
{
|
||
|
if (Type(static_cast<EDebugLevel>(eLevel)))
|
||
|
{
|
||
|
StringTrait StrMessage;
|
||
|
|
||
|
StrMessage.pszWide = pszMessage;
|
||
|
|
||
|
eLevel = eLevel | kDbgUnicode;
|
||
|
|
||
|
Output(static_cast<EDebugLevel>(eLevel), pszFile, uLine, pszModulePrefix, StrMessage);
|
||
|
|
||
|
if (Break(static_cast<EDebugLevel>(eLevel)))
|
||
|
{
|
||
|
DebugBreak();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INTERNAL_DELETE [] pszMessage;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/********************************************************************
|
||
|
|
||
|
Private member functions.
|
||
|
|
||
|
********************************************************************/
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
Output
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Outputs the messages to the list of registred
|
||
|
debug devices.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
eLevel - requested message level
|
||
|
pszFile - pointer to file name where message was called
|
||
|
uLine - line number where message was called
|
||
|
pszModulePrefix - message defined module prefix, used as an override
|
||
|
pszMessage - pointer to post formated message string
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
VOID
|
||
|
TDebugMsg::
|
||
|
Output(
|
||
|
IN EDebugLevel eLevel,
|
||
|
IN LPCTSTR pszFileName,
|
||
|
IN UINT uLine,
|
||
|
IN LPCTSTR pszModulePrefix,
|
||
|
IN StringTrait &strMsg
|
||
|
) const
|
||
|
{
|
||
|
TDebugString strFinal;
|
||
|
|
||
|
//
|
||
|
// Build the final output string.
|
||
|
//
|
||
|
if (BuildFinalString(strFinal,
|
||
|
eLevel,
|
||
|
pszModulePrefix,
|
||
|
pszFileName,
|
||
|
uLine,
|
||
|
strMsg))
|
||
|
{
|
||
|
//
|
||
|
// Calculate the byte count (less the null terminator) of the final string.
|
||
|
//
|
||
|
UINT uByteCount = (m_eLevel & kDbgUnicode)
|
||
|
? strFinal.uLen() * sizeof(WCHAR)
|
||
|
: strFinal.uLen() * sizeof(CHAR);
|
||
|
|
||
|
LPBYTE pByte = reinterpret_cast<LPBYTE>(const_cast<LPTSTR>(static_cast<LPCTSTR>(strFinal)));
|
||
|
|
||
|
{
|
||
|
//
|
||
|
// Create interator on built in device list.
|
||
|
//
|
||
|
TDebugNodeDouble::Iterator Iter(m_pBuiltinDeviceRoot);
|
||
|
|
||
|
//
|
||
|
// Output this string to all the built in debug devices.
|
||
|
//
|
||
|
for( Iter.First(); !Iter.IsDone(); Iter.Next() )
|
||
|
{
|
||
|
if (static_cast<TDebugDevice *>(Iter.Current())->eGetDebugType() & Globals.DebugDevices)
|
||
|
{
|
||
|
static_cast<TDebugDevice *>(Iter.Current())->bOutput(uByteCount, pByte);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
{
|
||
|
//
|
||
|
// Create interator on device list.
|
||
|
//
|
||
|
TDebugNodeDouble::Iterator Iter(m_pDeviceRoot);
|
||
|
|
||
|
//
|
||
|
// Output this string to all the registered debug devices.
|
||
|
//
|
||
|
for( Iter.First(); !Iter.IsDone(); Iter.Next() )
|
||
|
{
|
||
|
static_cast<TDebugDevice *>(Iter.Current())->bOutput( uByteCount, pByte);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ErrorText(_T("Error: TDebugMsg::vOutput - failed to build format string.\n"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
BuildFinalString
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routing build the actual string that will be sent to the
|
||
|
debug output devices.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
strFinal - string refrence where to return the finale output string.
|
||
|
eLevel - debug message level.
|
||
|
pszModulePrefix - per message prefix string, can be null.
|
||
|
pszFileName - file name were the message was requested.
|
||
|
uLine - line number were message was requested.
|
||
|
StrMsg - post formated message string.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE final string was build successfully, FALSE error occurred.
|
||
|
|
||
|
--*/
|
||
|
BOOL
|
||
|
TDebugMsg::
|
||
|
BuildFinalString(
|
||
|
IN TDebugString &strFinal,
|
||
|
IN EDebugLevel eLevel,
|
||
|
IN LPCTSTR pszModulePrefix,
|
||
|
IN LPCTSTR pszFileName,
|
||
|
IN UINT uLine,
|
||
|
IN StringTrait &StrMsg
|
||
|
) const
|
||
|
{
|
||
|
LPCTSTR pszFormat;
|
||
|
TDebugString strArg0;
|
||
|
TDebugString strArg1;
|
||
|
TDebugString strArg2;
|
||
|
TDebugString strArg3;
|
||
|
|
||
|
UINT eFlags = m_eLevel | eLevel;
|
||
|
|
||
|
if (!(eFlags & kDbgNoPrefix))
|
||
|
{
|
||
|
(VOID)strArg0.bUpdate(pszModulePrefix ? pszModulePrefix : *m_pstrPrefix);
|
||
|
}
|
||
|
|
||
|
if (!(eFlags & kDbgNoFileInfo))
|
||
|
{
|
||
|
(VOID)GetParameter(eFlags & (kDbgFileInfo | kDbgFileInfoLong), strArg1, pszFileName, uLine);
|
||
|
}
|
||
|
|
||
|
(VOID)GetParameter(eFlags & (kDbgFileInfo | kDbgFileInfoLong), strArg1, pszFileName, uLine);
|
||
|
|
||
|
(VOID)GetParameter(eFlags & (kDbgTimeStamp | kDbgTimeStampLong), strArg2, NULL, 0);
|
||
|
|
||
|
(VOID)GetParameter(eFlags & kDbgThreadId, strArg3, NULL, 0);
|
||
|
|
||
|
if ((eLevel & kDbgUnicode) == (m_eLevel & kDbgUnicode))
|
||
|
{
|
||
|
pszFormat = _T("%s%s%s%s %s");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pszFormat = _T("%s%s%s%s %S");
|
||
|
}
|
||
|
|
||
|
(VOID)strFinal.bFormat( pszFormat,
|
||
|
static_cast<LPCTSTR>(strArg0),
|
||
|
static_cast<LPCTSTR>(strArg1),
|
||
|
static_cast<LPCTSTR>(strArg2),
|
||
|
static_cast<LPCTSTR>(strArg3),
|
||
|
StrMsg.pszByte);
|
||
|
|
||
|
return strFinal.bValid();
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
GetParameter
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function get the parameter for the additinal information
|
||
|
displayed in a format string. The flags passed to the message
|
||
|
class and to the message function are used a guide.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
eFlags - Flags indicating what parameter to get.
|
||
|
strString - place were to return resultant string.
|
||
|
pszFileName - pointer to file name to format if requested.
|
||
|
uLine - line number for file name format.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE parmeter was returned in strString, FALSE error.
|
||
|
|
||
|
--*/
|
||
|
BOOL
|
||
|
TDebugMsg::
|
||
|
GetParameter(
|
||
|
IN UINT eFlags,
|
||
|
IN OUT TDebugString &strString,
|
||
|
IN LPCTSTR pszFileName,
|
||
|
IN UINT uLine
|
||
|
) const
|
||
|
{
|
||
|
BOOL bRetval = TRUE;
|
||
|
|
||
|
if (eFlags & kDbgFileInfo)
|
||
|
{
|
||
|
bRetval = strString.bFormat(*m_pstrFileInfoFormat, StripPathFromFileName(pszFileName), uLine);
|
||
|
}
|
||
|
|
||
|
if (eFlags & kDbgFileInfoLong)
|
||
|
{
|
||
|
bRetval = strString.bFormat(*m_pstrFileInfoFormat, pszFileName, uLine);
|
||
|
}
|
||
|
|
||
|
if (eFlags & kDbgTimeStamp)
|
||
|
{
|
||
|
bRetval = strString.bFormat(*m_pstrTimeStampFormatShort, GetTickCount());
|
||
|
}
|
||
|
|
||
|
if (eFlags & kDbgTimeStampLong)
|
||
|
{
|
||
|
TCHAR szBuffer[MAX_PATH];
|
||
|
SYSTEMTIME Time;
|
||
|
|
||
|
GetSystemTime(&Time);
|
||
|
|
||
|
bRetval = SystemTimeToTzSpecificLocalTime(NULL, &Time, &Time) &&
|
||
|
GetTimeFormat(LOCALE_USER_DEFAULT, 0, &Time, NULL, szBuffer, COUNTOF(szBuffer)) &&
|
||
|
strString.bFormat(*m_pstrTimeStampFormatLong, szBuffer);
|
||
|
}
|
||
|
|
||
|
if (eFlags & kDbgThreadId)
|
||
|
{
|
||
|
bRetval = strString.bFormat(*m_pstrThreadIdFormat, GetCurrentThreadId());
|
||
|
}
|
||
|
|
||
|
return bRetval;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
SetMessageFieldFormat
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routing allows individual parts of the format string
|
||
|
to have a custom format string specifier.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Field - specified which format field to change.
|
||
|
pszFormat - new format string, the caller must know the correct type.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
VOID
|
||
|
TDebugMsg::
|
||
|
SetMessageFieldFormat(
|
||
|
IN UINT eField,
|
||
|
IN LPTSTR pszFormat
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// Set the new format string.
|
||
|
//
|
||
|
if (eField & kDbgFileInfo)
|
||
|
{
|
||
|
m_pstrFileInfoFormat->bUpdate(pszFormat);
|
||
|
}
|
||
|
|
||
|
if (eField & kDbgFileInfoLong)
|
||
|
{
|
||
|
m_pstrFileInfoFormat->bUpdate(pszFormat);
|
||
|
}
|
||
|
|
||
|
if (eField & kDbgTimeStamp)
|
||
|
{
|
||
|
m_pstrTimeStampFormatShort->bUpdate(pszFormat);
|
||
|
}
|
||
|
|
||
|
if (eField & kDbgTimeStampLong)
|
||
|
{
|
||
|
m_pstrTimeStampFormatLong->bUpdate(pszFormat);
|
||
|
}
|
||
|
|
||
|
if (eField & kDbgThreadId)
|
||
|
{
|
||
|
m_pstrThreadIdFormat->bUpdate(pszFormat);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If any of the format strings were cleared then
|
||
|
// reset them back to the default value.
|
||
|
//
|
||
|
if (m_pstrFileInfoFormat->bEmpty())
|
||
|
{
|
||
|
m_pstrFileInfoFormat->bUpdate(kstrFileInfoFormat);
|
||
|
}
|
||
|
|
||
|
if (m_pstrTimeStampFormatShort->bEmpty())
|
||
|
{
|
||
|
m_pstrTimeStampFormatShort->bUpdate(kstrTimeStampFormatShort);
|
||
|
}
|
||
|
|
||
|
if (m_pstrTimeStampFormatLong->bEmpty())
|
||
|
{
|
||
|
m_pstrTimeStampFormatLong->bUpdate(kstrTimeStampFormatLong);
|
||
|
}
|
||
|
|
||
|
if (m_pstrThreadIdFormat->bEmpty())
|
||
|
{
|
||
|
m_pstrThreadIdFormat->bUpdate(kstrThreadIdFormat);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|