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

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name :
  4. trc.cpp
  5. Abstract:
  6. Kernel-Mode Tracing Facility.
  7. This module utilizes DCL's tracing macros, defined in atrcapi.h, in a
  8. way that is intended to be independent of anything but NT DDK API's.
  9. Currently, rdpwd.sys and rdpdd.sys also use these shared macros, but not
  10. in a way that is independent of their respective components.
  11. Author:
  12. Revision History:
  13. --*/
  14. #include "precomp.hxx"
  15. #include <stdio.h>
  16. #define TRC_FILE "trc"
  17. #include "trc.h"
  18. //
  19. // This module shouldn't do much if we are not in a checked build.
  20. //
  21. #if DBG
  22. ////////////////////////////////////////////////////////////////////////
  23. //
  24. // Globals to this Module
  25. //
  26. //
  27. // Current Tracing Parameters
  28. //
  29. TRC_CONFIG TRC_Config = TRC_CONFIG_DEFAULT;
  30. //
  31. // InterlockedIncrement is a preincrement, first thing will roll over
  32. // and fill in entry 0
  33. //
  34. ULONG TRC_CurrentMsg = 0xFFFFFFFF;
  35. //
  36. // Recent Traces
  37. //
  38. CHAR TRC_RecentTraces[TRC_RamMsgMax][TRC_BUFFER_SIZE];
  39. BOOL TRC_ProfileTraceEnabled()
  40. {
  41. return TRC_Config.TraceProfile;
  42. }
  43. VOID TRC_TraceLine(
  44. ULONG traceLevel,
  45. PCHAR traceString,
  46. CHAR separator,
  47. ULONG lineNumber,
  48. PCHAR funcName,
  49. PCHAR fileName
  50. )
  51. /*++
  52. Routine Description:
  53. "C" Tracing Entry Point. From the perspective of the tracing macros, this
  54. function actaully does the tracing.
  55. Arguments:
  56. traceClass - Component doing the tracing
  57. traceType - ERR, ALT, NRM, DBG
  58. traceString - Unadorned message
  59. separator - separator character
  60. lineNumber - lineNumber where the TRC_XXX call was made
  61. funcName - function containing the TRC_XXX call
  62. fileName - file containing the TRC_XXX call
  63. Return Value:
  64. NA
  65. --*/
  66. {
  67. CHAR *msgBufEntry;
  68. ULONG ofs;
  69. CHAR tempString[TRC_BUFFER_SIZE]="";
  70. CHAR formatString[TRC_BUFFER_SIZE]="";
  71. ULONG_PTR processId;
  72. ULONG_PTR threadId;
  73. LARGE_INTEGER time;
  74. TIME_FIELDS TimeFields;
  75. ULONG idxBuffer;
  76. //
  77. // CODE_IMPROVMENT: Currently creates a big tracing string. Might be cool
  78. // save tracing records with all the fields so that the debugger ext.
  79. // could choose the output formatting on the fly. i.e. print just the
  80. // level you want, no grep required
  81. //
  82. //
  83. // Grab the next element in the RAM message buffer. We use the
  84. // mask to define which bits we are using for the counter. This
  85. // allows us to wrap the counter in one call to InterlockedIncrement.
  86. //
  87. idxBuffer = InterlockedIncrement((PLONG)&TRC_CurrentMsg) & TRC_RamMsgMask;
  88. msgBufEntry = (char *)&TRC_RecentTraces[idxBuffer];
  89. msgBufEntry[0] = 0;
  90. processId = (ULONG_PTR)PsGetCurrentProcess();
  91. //threadId = (ULONG_PTR)PsGetCurrentThread();
  92. threadId = 0;
  93. KeQuerySystemTime(&time);
  94. RtlTimeToTimeFields(&time, &TimeFields);
  95. //
  96. // Add the timestamp.
  97. //
  98. _snprintf(tempString, sizeof(tempString), TRC_TIME_FMT "%c", TimeFields.Hour, TimeFields.Minute,
  99. TimeFields.Second, TimeFields.Milliseconds, separator);
  100. strncat(msgBufEntry, tempString, TRC_BUFFER_SIZE - strlen(msgBufEntry));
  101. msgBufEntry[TRC_BUFFER_SIZE - 1] = 0;
  102. //
  103. // Add the process ID and thread ID
  104. //
  105. _snprintf(tempString, sizeof(tempString), TRC_PROC_FMT ":" TRC_PROC_FMT "%c", processId,
  106. threadId, separator);
  107. strncat(msgBufEntry, tempString, TRC_BUFFER_SIZE - strlen(msgBufEntry));
  108. msgBufEntry[TRC_BUFFER_SIZE - 1] = 0;
  109. //
  110. // Add the rest.
  111. //
  112. _snprintf(tempString, sizeof(tempString),
  113. TRC_FUNC_FMT "%c" TRC_LINE_FMT "%c%s\n",
  114. TRC_FUNCNAME_LEN,
  115. TRC_FUNCNAME_LEN,
  116. funcName,
  117. separator,
  118. lineNumber,
  119. separator,
  120. traceString);
  121. strncat(msgBufEntry, tempString, TRC_BUFFER_SIZE - strlen(msgBufEntry));
  122. msgBufEntry[TRC_BUFFER_SIZE - 1] = 0;
  123. msgBufEntry[TRC_BUFFER_SIZE - 2] = '\n';
  124. //
  125. // Now that we have got the trace string, we need to write it out to
  126. // the debugger, if so configured.
  127. //
  128. if (TRC_WillTrace(traceLevel, fileName, lineNumber)) {
  129. DbgPrint(msgBufEntry);
  130. }
  131. }
  132. BOOL TRCPrefixMatch(PCHAR cpnt, PCHAR prefix)
  133. /*++
  134. Routine Description:
  135. Internal function to compare a component name to a prefix.
  136. - assumes both are the same case
  137. - returns
  138. - TRUE if characters up to end of prefix match
  139. - FALSE otherwise
  140. Arguments:
  141. cpnt - filename
  142. prefix - characters to match
  143. Return Value:
  144. TRUE if matching, or FALSE
  145. --*/
  146. {
  147. while ((*cpnt == *prefix) && (*prefix != 0))
  148. {
  149. cpnt++;
  150. prefix++;
  151. }
  152. if (*prefix == 0)
  153. {
  154. return(TRUE);
  155. }
  156. return(FALSE);
  157. }
  158. BOOL TRC_WillTrace(
  159. IN ULONG traceLevel,
  160. IN PCHAR fileName,
  161. IN ULONG line
  162. )
  163. /*++
  164. Routine Description:
  165. Return whether tracing is turned on for a particular component.
  166. Arguments:
  167. traceComponent - Component producing this trace.
  168. traceLevel - Trace level (TRC_LEVEL_DBG, TRC_LEVEL_NRM, etc).
  169. fileName - Name of file being traced.
  170. line - Line of tracing call.
  171. Return Value:
  172. NA
  173. --*/
  174. {
  175. BOOL rc = FALSE;
  176. int i;
  177. //
  178. // First of all check the trace level. If the trace level is error or
  179. // above then we trace regardless.
  180. //
  181. if ((traceLevel >= TRC_LEVEL_ERR) && (traceLevel != TRC_PROFILE_TRACE)) {
  182. rc = TRUE;
  183. goto ExitFunc;
  184. }
  185. if (traceLevel < TRC_Config.TraceLevel) {
  186. rc = FALSE;
  187. goto ExitFunc;
  188. }
  189. /************************************************************************/
  190. /* Trace all lines if no prefixes are defined. */
  191. /************************************************************************/
  192. if (TRC_Config.Prefix[0].name[0] == 0)
  193. {
  194. rc = TRUE;
  195. goto ExitFunc;
  196. }
  197. /************************************************************************/
  198. /* Some prefixes are defined - check whether this line matches any of */
  199. /* them. */
  200. /************************************************************************/
  201. for (i = 0; i < TRC_MAX_PREFIX; i++)
  202. {
  203. if (TRC_Config.Prefix[i].name[0] == 0)
  204. {
  205. /****************************************************************/
  206. /* End of list - break */
  207. /****************************************************************/
  208. break;
  209. }
  210. if (TRCPrefixMatch(fileName, TRC_Config.Prefix[i].name))
  211. {
  212. /****************************************************************/
  213. /* Found matching filename - is there a line number range */
  214. /* specified? */
  215. /****************************************************************/
  216. if ((TRC_Config.Prefix[i].start == 0) &&
  217. (TRC_Config.Prefix[i].end == 0))
  218. {
  219. /************************************************************/
  220. /* No line number range - trace this line */
  221. /************************************************************/
  222. rc = TRUE;
  223. goto ExitFunc;
  224. }
  225. /****************************************************************/
  226. /* There's a line number range - see if this line falls within */
  227. /* it. */
  228. /****************************************************************/
  229. if ((line >= TRC_Config.Prefix[i].start) &&
  230. (line <= TRC_Config.Prefix[i].end))
  231. {
  232. /************************************************************/
  233. /* Line within prefix range - trace it. */
  234. /************************************************************/
  235. rc = TRUE;
  236. goto ExitFunc;
  237. }
  238. }
  239. } /* for */
  240. /************************************************************************/
  241. /* If we get here, we've searched the list of prefixes and failed to */
  242. /* find a match - don't trace the line */
  243. /************************************************************************/
  244. rc = FALSE;
  245. ExitFunc:
  246. return rc;
  247. }
  248. #endif /* DBG */