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.
 
 
 
 
 
 

316 lines
8.9 KiB

/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name :
trc.cpp
Abstract:
Kernel-Mode Tracing Facility.
This module utilizes DCL's tracing macros, defined in atrcapi.h, in a
way that is intended to be independent of anything but NT DDK API's.
Currently, rdpwd.sys and rdpdd.sys also use these shared macros, but not
in a way that is independent of their respective components.
Author:
Revision History:
--*/
#include "precomp.hxx"
#include <stdio.h>
#define TRC_FILE "trc"
#include "trc.h"
//
// This module shouldn't do much if we are not in a checked build.
//
#if DBG
////////////////////////////////////////////////////////////////////////
//
// Globals to this Module
//
//
// Current Tracing Parameters
//
TRC_CONFIG TRC_Config = TRC_CONFIG_DEFAULT;
//
// InterlockedIncrement is a preincrement, first thing will roll over
// and fill in entry 0
//
ULONG TRC_CurrentMsg = 0xFFFFFFFF;
//
// Recent Traces
//
CHAR TRC_RecentTraces[TRC_RamMsgMax][TRC_BUFFER_SIZE];
BOOL TRC_ProfileTraceEnabled()
{
return TRC_Config.TraceProfile;
}
VOID TRC_TraceLine(
ULONG traceLevel,
PCHAR traceString,
CHAR separator,
ULONG lineNumber,
PCHAR funcName,
PCHAR fileName
)
/*++
Routine Description:
"C" Tracing Entry Point. From the perspective of the tracing macros, this
function actaully does the tracing.
Arguments:
traceClass - Component doing the tracing
traceType - ERR, ALT, NRM, DBG
traceString - Unadorned message
separator - separator character
lineNumber - lineNumber where the TRC_XXX call was made
funcName - function containing the TRC_XXX call
fileName - file containing the TRC_XXX call
Return Value:
NA
--*/
{
CHAR *msgBufEntry;
ULONG ofs;
CHAR tempString[TRC_BUFFER_SIZE]="";
CHAR formatString[TRC_BUFFER_SIZE]="";
ULONG_PTR processId;
ULONG_PTR threadId;
LARGE_INTEGER time;
TIME_FIELDS TimeFields;
ULONG idxBuffer;
//
// CODE_IMPROVMENT: Currently creates a big tracing string. Might be cool
// save tracing records with all the fields so that the debugger ext.
// could choose the output formatting on the fly. i.e. print just the
// level you want, no grep required
//
//
// Grab the next element in the RAM message buffer. We use the
// mask to define which bits we are using for the counter. This
// allows us to wrap the counter in one call to InterlockedIncrement.
//
idxBuffer = InterlockedIncrement((PLONG)&TRC_CurrentMsg) & TRC_RamMsgMask;
msgBufEntry = (char *)&TRC_RecentTraces[idxBuffer];
msgBufEntry[0] = 0;
processId = (ULONG_PTR)PsGetCurrentProcess();
//threadId = (ULONG_PTR)PsGetCurrentThread();
threadId = 0;
KeQuerySystemTime(&time);
RtlTimeToTimeFields(&time, &TimeFields);
//
// Add the timestamp.
//
_snprintf(tempString, sizeof(tempString), TRC_TIME_FMT "%c", TimeFields.Hour, TimeFields.Minute,
TimeFields.Second, TimeFields.Milliseconds, separator);
strncat(msgBufEntry, tempString, TRC_BUFFER_SIZE - strlen(msgBufEntry));
msgBufEntry[TRC_BUFFER_SIZE - 1] = 0;
//
// Add the process ID and thread ID
//
_snprintf(tempString, sizeof(tempString), TRC_PROC_FMT ":" TRC_PROC_FMT "%c", processId,
threadId, separator);
strncat(msgBufEntry, tempString, TRC_BUFFER_SIZE - strlen(msgBufEntry));
msgBufEntry[TRC_BUFFER_SIZE - 1] = 0;
//
// Add the rest.
//
_snprintf(tempString, sizeof(tempString),
TRC_FUNC_FMT "%c" TRC_LINE_FMT "%c%s\n",
TRC_FUNCNAME_LEN,
TRC_FUNCNAME_LEN,
funcName,
separator,
lineNumber,
separator,
traceString);
strncat(msgBufEntry, tempString, TRC_BUFFER_SIZE - strlen(msgBufEntry));
msgBufEntry[TRC_BUFFER_SIZE - 1] = 0;
msgBufEntry[TRC_BUFFER_SIZE - 2] = '\n';
//
// Now that we have got the trace string, we need to write it out to
// the debugger, if so configured.
//
if (TRC_WillTrace(traceLevel, fileName, lineNumber)) {
DbgPrint(msgBufEntry);
}
}
BOOL TRCPrefixMatch(PCHAR cpnt, PCHAR prefix)
/*++
Routine Description:
Internal function to compare a component name to a prefix.
- assumes both are the same case
- returns
- TRUE if characters up to end of prefix match
- FALSE otherwise
Arguments:
cpnt - filename
prefix - characters to match
Return Value:
TRUE if matching, or FALSE
--*/
{
while ((*cpnt == *prefix) && (*prefix != 0))
{
cpnt++;
prefix++;
}
if (*prefix == 0)
{
return(TRUE);
}
return(FALSE);
}
BOOL TRC_WillTrace(
IN ULONG traceLevel,
IN PCHAR fileName,
IN ULONG line
)
/*++
Routine Description:
Return whether tracing is turned on for a particular component.
Arguments:
traceComponent - Component producing this trace.
traceLevel - Trace level (TRC_LEVEL_DBG, TRC_LEVEL_NRM, etc).
fileName - Name of file being traced.
line - Line of tracing call.
Return Value:
NA
--*/
{
BOOL rc = FALSE;
int i;
//
// First of all check the trace level. If the trace level is error or
// above then we trace regardless.
//
if ((traceLevel >= TRC_LEVEL_ERR) && (traceLevel != TRC_PROFILE_TRACE)) {
rc = TRUE;
goto ExitFunc;
}
if (traceLevel < TRC_Config.TraceLevel) {
rc = FALSE;
goto ExitFunc;
}
/************************************************************************/
/* Trace all lines if no prefixes are defined. */
/************************************************************************/
if (TRC_Config.Prefix[0].name[0] == 0)
{
rc = TRUE;
goto ExitFunc;
}
/************************************************************************/
/* Some prefixes are defined - check whether this line matches any of */
/* them. */
/************************************************************************/
for (i = 0; i < TRC_MAX_PREFIX; i++)
{
if (TRC_Config.Prefix[i].name[0] == 0)
{
/****************************************************************/
/* End of list - break */
/****************************************************************/
break;
}
if (TRCPrefixMatch(fileName, TRC_Config.Prefix[i].name))
{
/****************************************************************/
/* Found matching filename - is there a line number range */
/* specified? */
/****************************************************************/
if ((TRC_Config.Prefix[i].start == 0) &&
(TRC_Config.Prefix[i].end == 0))
{
/************************************************************/
/* No line number range - trace this line */
/************************************************************/
rc = TRUE;
goto ExitFunc;
}
/****************************************************************/
/* There's a line number range - see if this line falls within */
/* it. */
/****************************************************************/
if ((line >= TRC_Config.Prefix[i].start) &&
(line <= TRC_Config.Prefix[i].end))
{
/************************************************************/
/* Line within prefix range - trace it. */
/************************************************************/
rc = TRUE;
goto ExitFunc;
}
}
} /* for */
/************************************************************************/
/* If we get here, we've searched the list of prefixes and failed to */
/* find a match - don't trace the line */
/************************************************************************/
rc = FALSE;
ExitFunc:
return rc;
}
#endif /* DBG */