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

499 lines
12 KiB

/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
mspdebug.cpp
Abstract:
This module contains the debugging support for the MSPs.
--*/
#include "precomp.h"
#pragma hdrstop
#include <stdio.h>
#include <strsafe.h>
//
// no need to build this code if MSPLOG is not defined
//
#ifdef MSPLOG
#define MAXDEBUGSTRINGLENGTH 513
static DWORD sg_dwTraceID = INVALID_TRACEID;
static const ULONG MAX_KEY_LENGTH = 100;
static const DWORD DEFAULT_DEBUGGER_MASK = 0xffff0000;
static char sg_szTraceName[MAX_KEY_LENGTH]; // saves name of dll
static DWORD sg_dwTracingToDebugger = 0;
static DWORD sg_dwTracingToConsole = 0;
static DWORD sg_dwTracingToFile = 0;
static DWORD sg_dwDebuggerMask = 0;
//
// this flag indicates whether any tracing needs to be done at all
//
BOOL g_bMSPBaseTracingOn = FALSE;
BOOL NTAPI MSPLogRegister(LPCTSTR szName)
{
HKEY hTracingKey;
char szTracingKey[MAX_KEY_LENGTH];
const char szDebuggerTracingEnableValue[] = "EnableDebuggerTracing";
const char szConsoleTracingEnableValue[] = "EnableConsoleTracing";
const char szFileTracingEnableValue[] = "EnableFileTracing";
const char szTracingMaskValue[] = "ConsoleTracingMask";
sg_dwTracingToDebugger = 0;
sg_dwTracingToConsole = 0;
sg_dwTracingToFile = 0;
#ifdef UNICODE
HRESULT hr = StringCchPrintfA(szTracingKey,
MAX_KEY_LENGTH,
"Software\\Microsoft\\Tracing\\%ls",
szName);
#else
HRESULT hr = StringCchPrintfA(szTracingKey,
MAX_KEY_LENGTH,
"Software\\Microsoft\\Tracing\\%s",
szName);
#endif
if (FAILED(hr))
{
//
// if this assert fires, the chances are the name string passed to us
// by the MSP is too long. the msp developer needs to address that.
//
_ASSERTE(FALSE);
return FALSE;
}
_ASSERTE(sg_dwTraceID == INVALID_TRACEID);
if ( ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE,
szTracingKey,
0,
KEY_READ,
&hTracingKey) )
{
DWORD dwDataSize = sizeof (DWORD);
DWORD dwDataType;
LONG lRc = RegQueryValueExA(hTracingKey,
szDebuggerTracingEnableValue,
0,
&dwDataType,
(LPBYTE) &sg_dwTracingToDebugger,
&dwDataSize);
if (ERROR_SUCCESS != lRc)
{
sg_dwTracingToDebugger = 0;
}
lRc = RegQueryValueExA(hTracingKey,
szConsoleTracingEnableValue,
0,
&dwDataType,
(LPBYTE) &sg_dwTracingToConsole,
&dwDataSize);
if (ERROR_SUCCESS != lRc)
{
sg_dwTracingToConsole = 0;
}
lRc = RegQueryValueExA(hTracingKey,
szFileTracingEnableValue,
0,
&dwDataType,
(LPBYTE) &sg_dwTracingToFile,
&dwDataSize);
if (ERROR_SUCCESS != lRc)
{
sg_dwTracingToFile = 0;
}
lRc = RegQueryValueExA(hTracingKey,
szTracingMaskValue,
0,
&dwDataType,
(LPBYTE) &sg_dwDebuggerMask,
&dwDataSize);
if (ERROR_SUCCESS != lRc)
{
sg_dwDebuggerMask = DEFAULT_DEBUGGER_MASK;
}
RegCloseKey (hTracingKey);
}
else
{
//
// the key could not be opened. in case the key does not exist,
// register with rtutils so that the reg keys get created
//
#ifdef UNICODE
hr = StringCchPrintfA(sg_szTraceName, MAX_KEY_LENGTH, "%ls", szName);
#else
hr = StringCchPrintfA(sg_szTraceName, MAX_KEY_LENGTH, "%s", szName);
#endif
if (FAILED(hr))
{
//
// if this assert fires, the chances are the name string passed to us
// by the MSP is too long. the msp developer needs to address that.
//
_ASSERTE(FALSE);
return FALSE;
}
//
// tracing should not have been initialized
//
sg_dwTraceID = TraceRegister(szName);
if (sg_dwTraceID != INVALID_TRACEID)
{
g_bMSPBaseTracingOn = TRUE;
}
return TRUE;
}
//
// are we asked to do any tracing at all?
//
if ( (0 != sg_dwTracingToDebugger) ||
(0 != sg_dwTracingToConsole ) ||
(0 != sg_dwTracingToFile ) )
{
//
// see if we need to register with rtutils
//
if ( (0 != sg_dwTracingToConsole ) || (0 != sg_dwTracingToFile) )
{
//
// rtutils tracing is enabled. register with rtutils
//
#ifdef UNICODE
hr = StringCchPrintfA(sg_szTraceName, MAX_KEY_LENGTH, "%ls", szName);
#else
hr = StringCchPrintfA(sg_szTraceName, MAX_KEY_LENGTH, "%s", szName);
#endif
if (FAILED(hr))
{
//
// if this assert fires, the chances are the name string passed to us
// by the MSP is too long. the msp developer needs to address that.
//
_ASSERTE(FALSE);
return FALSE;
}
//
// tracing should not have been initialized
//
_ASSERTE(sg_dwTraceID == INVALID_TRACEID);
//
// register
//
sg_dwTraceID = TraceRegister(szName);
}
//
// if debugger tracing, or succeeded registering with rtutils, we are all set
//
if ( (0 != sg_dwTracingToDebugger) || (sg_dwTraceID != INVALID_TRACEID) )
{
//
// some tracing is enabled. set the global flag
//
g_bMSPBaseTracingOn = TRUE;
return TRUE;
}
else
{
//
// registration did not go through and debugger logging is off
//
return FALSE;
}
}
//
// logging is not enabled. nothing to do
//
return TRUE;
}
void NTAPI MSPLogDeRegister()
{
if (g_bMSPBaseTracingOn)
{
sg_dwTracingToDebugger = 0;
sg_dwTracingToConsole = 0;
sg_dwTracingToFile = 0;
//
// if we registered tracing, unregister now
//
if ( sg_dwTraceID != INVALID_TRACEID )
{
TraceDeregister(sg_dwTraceID);
sg_dwTraceID = INVALID_TRACEID;
}
}
}
void NTAPI LogPrint(IN DWORD dwDbgLevel, IN LPCSTR lpszFormat, IN ...)
/*++
Routine Description:
Formats the incoming debug message & calls TraceVprintfEx to print it.
Arguments:
dwDbgLevel - The type of the message.
lpszFormat - printf-style format string, followed by appropriate
list of arguments
Return Value:
--*/
{
static char * message[] =
{
"ERROR",
"WARNING",
"INFO",
"TRACE",
"EVENT",
"INVALID TRACE LEVEL"
};
char szTraceBuf[MAXDEBUGSTRINGLENGTH];
DWORD dwIndex;
if ( ( sg_dwTracingToDebugger > 0 ) &&
( 0 != ( dwDbgLevel & sg_dwDebuggerMask ) ) )
{
switch(dwDbgLevel)
{
case MSP_ERROR: dwIndex = 0; break;
case MSP_WARN: dwIndex = 1; break;
case MSP_INFO: dwIndex = 2; break;
case MSP_TRACE: dwIndex = 3; break;
case MSP_EVENT: dwIndex = 4; break;
default: dwIndex = 5; break;
}
// retrieve local time
SYSTEMTIME SystemTime;
GetLocalTime(&SystemTime);
HRESULT hr =
StringCchPrintfA(szTraceBuf,
MAXDEBUGSTRINGLENGTH,
"%s:[%02u:%02u:%02u.%03u,tid=%x:]%s: ",
sg_szTraceName,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond,
SystemTime.wMilliseconds,
GetCurrentThreadId(),
message[dwIndex]);
if (FAILED(hr))
{
//
// if this assert fires, there is a good chance a bug was
// introduced in this function
//
_ASSERTE(FALSE);
return;
}
va_list ap;
va_start(ap, lpszFormat);
size_t nStringLength = 0;
hr = StringCchLengthA(szTraceBuf,
MAXDEBUGSTRINGLENGTH,
&nStringLength);
if (FAILED(hr))
{
//
// if this assert fires, there is a good chance a bug was
// introduced in this function
//
_ASSERTE(FALSE);
return;
}
if (nStringLength >= MAXDEBUGSTRINGLENGTH)
{
//
// the string is too long, was a bug introduced in this function?
//
_ASSERTE(FALSE);
return;
}
hr = StringCchVPrintfA(&szTraceBuf[nStringLength],
MAXDEBUGSTRINGLENGTH - nStringLength,
lpszFormat,
ap
);
if (FAILED(hr))
{
//
// the string the msp code is trying to log is too long. assert to
// indicate this, but proceed to logging it (StringCchVPrintfA
// guarantees that in case of ERROR_INSUFFICIENT_BUFFER, the
// string is remain null-terminated).
//
_ASSERTE(FALSE);
if (ERROR_INSUFFICIENT_BUFFER != hr)
{
return;
}
}
hr = StringCchCatA(szTraceBuf, MAXDEBUGSTRINGLENGTH,"\n");
// in case of failure, the string is likely to be too long. debugbreak,
// and proceed to logging, in which case the string will not be ended
// with '\n'
_ASSERTE(SUCCEEDED(hr));
OutputDebugStringA (szTraceBuf);
va_end(ap);
}
if (sg_dwTraceID != INVALID_TRACEID)
{
if ( ( sg_dwTracingToConsole > 0 ) || ( sg_dwTracingToFile > 0 ) )
{
switch(dwDbgLevel)
{
case MSP_ERROR: dwIndex = 0; break;
case MSP_WARN: dwIndex = 1; break;
case MSP_INFO: dwIndex = 2; break;
case MSP_TRACE: dwIndex = 3; break;
case MSP_EVENT: dwIndex = 4; break;
default: dwIndex = 5; break;
}
HRESULT hr = StringCchPrintfA(szTraceBuf,
MAXDEBUGSTRINGLENGTH,
"[%s] %s",
message[dwIndex],
lpszFormat);
if (FAILED(hr))
{
// the string we are trying to log is too long (or there is an
// unexpected error). do not proceed to logging, since we
// cannot afford to loose the formatting information contained
// in the string -- that would confuse TraceVprintfExA()
_ASSERTE(FALSE);
return;
}
va_list arglist;
va_start(arglist, lpszFormat);
TraceVprintfExA(sg_dwTraceID, dwDbgLevel | TRACE_USE_MSEC, szTraceBuf, arglist);
va_end(arglist);
}
}
}
#endif // MSPLOG
// eof