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.

1282 lines
67 KiB

  1. /****************************************************************************/
  2. /* atrcint.c */
  3. /* */
  4. /* Internal trace functions */
  5. /* */
  6. /* Copyright(C) Microsoft Corporation 1997-1998 */
  7. /****************************************************************************/
  8. #include <adcg.h>
  9. /****************************************************************************/
  10. /* Define TRC_FILE and TRC_GROUP. */
  11. /****************************************************************************/
  12. #define TRC_FILE "atrcint"
  13. #define TRC_GROUP TRC_GROUP_TRACE
  14. /****************************************************************************/
  15. /* Common and trace specific includes. */
  16. /****************************************************************************/
  17. #include <atrcapi.h>
  18. #include <atrcint.h>
  19. /****************************************************************************/
  20. /* */
  21. /* DATA */
  22. /* */
  23. /****************************************************************************/
  24. #define DC_INCLUDE_DATA
  25. #include <atrcdata.c>
  26. #undef DC_INCLUDE_DATA
  27. /****************************************************************************/
  28. /* */
  29. /* FUNCTIONS */
  30. /* */
  31. /****************************************************************************/
  32. /****************************************************************************/
  33. /* FUNCTION: TRCCheckState(...) */
  34. /* */
  35. /* DESCRIPTION: */
  36. /* ============ */
  37. /* This function checks the current internal trace state. It does the */
  38. /* following depending on the trace state: */
  39. /* */
  40. /* TRC_STATE_UNINITIALIZED : calls TRC_Initialize to initialize trace. If */
  41. /* this succeeds it returns TRUE. */
  42. /* TRC_STATE_INITIALIZED : returns TRUE. */
  43. /* TRC_STATE_TERMINATED : returns FALSE. */
  44. /* */
  45. /* PARAMETERS: */
  46. /* =========== */
  47. /* None. */
  48. /* */
  49. /* RETURNS: */
  50. /* ======== */
  51. /* See above. */
  52. /* */
  53. /****************************************************************************/
  54. DCBOOL32 DCINTERNAL TRCCheckState(DCVOID)
  55. {
  56. DCBOOL32 rc = FALSE;
  57. /************************************************************************/
  58. /* Now switch on the current trace state. */
  59. /************************************************************************/
  60. switch (trcState)
  61. {
  62. case TRC_STATE_UNINITIALIZED:
  63. {
  64. /****************************************************************/
  65. /* Trace is uninitialized so attempt to initialize it. */
  66. /****************************************************************/
  67. rc = (0 == TRC_Initialize(FALSE));
  68. }
  69. break;
  70. case TRC_STATE_INITIALIZED:
  71. {
  72. /****************************************************************/
  73. /* Trace is initialized and tracing is permitted in this state */
  74. /* so return TRUE. */
  75. /****************************************************************/
  76. rc = TRUE;
  77. }
  78. break;
  79. case TRC_STATE_TERMINATED:
  80. {
  81. /****************************************************************/
  82. /* Trace has been terminated. Tracing is no longer permitted */
  83. /* so return FALSE. */
  84. /****************************************************************/
  85. rc = FALSE;
  86. }
  87. break;
  88. default:
  89. {
  90. TRCDebugOutput(_T("Unknown trace state!\n"));
  91. }
  92. break;
  93. }
  94. return(rc);
  95. } /* TRCCheckState */
  96. /****************************************************************************/
  97. /* FUNCTION: TRCDumpLine(...) */
  98. /* */
  99. /* DESCRIPTION: */
  100. /* ============ */
  101. /* This function takes a block of data and formats it into a string */
  102. /* containing raw hex plus ASCII equivalent data. */
  103. /* */
  104. /* PARAMETERS: */
  105. /* =========== */
  106. /* buffer : the buffer to trace. */
  107. /* length : the length. */
  108. /* offset : the offset of the buffer. */
  109. /* */
  110. /* RETURNS: */
  111. /* ======== */
  112. /* Nothing. */
  113. /* */
  114. /****************************************************************************/
  115. DCVOID DCINTERNAL TRCDumpLine(PDCUINT8 buffer,
  116. DCUINT length,
  117. DCUINT32 offset,
  118. DCUINT traceLevel)
  119. {
  120. DCUINT i, limDataSize;
  121. DCUINT pos;
  122. TRC_LINE traceLine;
  123. HRESULT hr;
  124. /************************************************************************/
  125. /* Write the offset into the start of the TRC_LINE structure. */
  126. /************************************************************************/
  127. hr = StringCchPrintf(traceLine.address,
  128. SIZE_TCHARS(traceLine.address),
  129. _T(" %05X "), offset);
  130. if (FAILED(hr)) {
  131. DC_QUIT;
  132. }
  133. /************************************************************************/
  134. /* Format the binary portion of the data. First of all blank out the */
  135. /* hexData portion of the TRC_LINE structure. */
  136. /************************************************************************/
  137. limDataSize = sizeof(traceLine.hexData) / sizeof(traceLine.hexData[0]);
  138. for (i = 0; i < limDataSize; i++)
  139. {
  140. traceLine.hexData[i] = _T(' ');
  141. }
  142. /************************************************************************/
  143. /* Now write the data into the hexData block. <pos> stores the current */
  144. /* position in the output buffer (which is an array of 36 characters). */
  145. /* On each loop through we write two characters into the array (which */
  146. /* represent one byte) and so we increment <pos> by 2 each time. */
  147. /* However at the end of a block of eight characters we add an extra */
  148. /* blank - thus we need to increment <pos> again. */
  149. /************************************************************************/
  150. pos = 0;
  151. for (i = 0; i < length; i++)
  152. {
  153. hr = StringCchPrintf(&(traceLine.hexData[pos]),
  154. 3, //we write 2 characters at most (+1 for null)
  155. _T("%02X"),
  156. (DCUINT8)*(buffer+i));
  157. if (FAILED(hr)) {
  158. DC_QUIT;
  159. }
  160. /********************************************************************/
  161. /* Increment character position by 2. */
  162. /********************************************************************/
  163. pos += 2;
  164. /********************************************************************/
  165. /* If this is the end of a group of four characters then add a */
  166. /* spacing character. We need to overwrite the terminating NULL */
  167. /* written by DC_TSPRINTF. */
  168. /********************************************************************/
  169. traceLine.hexData[pos] = _T(' ');
  170. if (0 == ((i + 1) % 4))
  171. {
  172. pos++;
  173. }
  174. }
  175. /************************************************************************/
  176. /* Copy in the binary data for display in ascii form. First of all */
  177. /* blank out the asciiData portion of the TRC_LINE structure. */
  178. /************************************************************************/
  179. limDataSize = sizeof(traceLine.asciiData) / sizeof(traceLine.asciiData[0]);
  180. for (i = 0; i < limDataSize; i++)
  181. {
  182. traceLine.asciiData[i] = _T(' ');
  183. }
  184. #ifdef UNICODE
  185. for (i = 0; i < length; i++)
  186. {
  187. traceLine.asciiData[i] = buffer[i];
  188. }
  189. #else
  190. DC_MEMCPY(traceLine.asciiData, buffer, length);
  191. #endif
  192. /************************************************************************/
  193. /* Now translate non-printable characters to '.'. */
  194. /************************************************************************/
  195. for (i = 0; i < length; i++)
  196. {
  197. if ((traceLine.asciiData[i] < 0x20) ||
  198. (traceLine.asciiData[i] > 0x7E))
  199. {
  200. traceLine.asciiData[i] = _T('.');
  201. }
  202. }
  203. /************************************************************************/
  204. /* Add the terminating newline. */
  205. /************************************************************************/
  206. DC_MEMSET(traceLine.end, '\0', sizeof(traceLine.end));
  207. StringCchCopy(traceLine.end, SIZE_TCHARS(traceLine.end), TRC_CRLF);
  208. /************************************************************************/
  209. /* Finally trace this buffer out. */
  210. /************************************************************************/
  211. TRCOutput((PDCTCHAR)&traceLine,
  212. DC_TSTRLEN((PDCTCHAR)&traceLine) * sizeof(DCTCHAR),
  213. traceLevel);
  214. DC_EXIT_POINT:
  215. return;
  216. } /* TRCDumpLine */
  217. /****************************************************************************/
  218. /* FUNCTION: TRCReadFlag(...) */
  219. /* */
  220. /* DESCRIPTION: */
  221. /* ============ */
  222. /* This function reads a flag setting from the configuration data. */
  223. /* */
  224. /* PARAMETERS: */
  225. /* =========== */
  226. /* entryName : the profile entry name. */
  227. /* flag : the flag to set or clear. */
  228. /* pSetting : a pointer to the variable containing the flag. */
  229. /* */
  230. /* RETURNS: */
  231. /* ======== */
  232. /* Nothing. */
  233. /* */
  234. /****************************************************************************/
  235. DCVOID DCINTERNAL TRCReadFlag(PDCTCHAR entryName,
  236. DCUINT32 flag,
  237. PDCUINT32 pSetting)
  238. {
  239. DCUINT rc = 0;
  240. DCUINT32 entryValue;
  241. /************************************************************************/
  242. /* Test the flag and set entryValue to a boolean, rather than the */
  243. /* entire flag array. */
  244. /************************************************************************/
  245. entryValue = (TEST_FLAG(*pSetting, flag) ? 1UL : 0UL);
  246. /************************************************************************/
  247. /* Call <TRCReadProfInt> to get the setting of an integer. */
  248. /************************************************************************/
  249. rc = TRCReadProfInt(entryName, &entryValue);
  250. /************************************************************************/
  251. /* Check the return code - if it is non-zero then just leave this */
  252. /* flag at its default setting. */
  253. /************************************************************************/
  254. if (0 != rc)
  255. {
  256. DC_QUIT;
  257. }
  258. /************************************************************************/
  259. /* Now set or clear the flag depending on <value>. */
  260. /************************************************************************/
  261. if (0UL == entryValue)
  262. {
  263. CLEAR_FLAG(*pSetting, flag);
  264. }
  265. else
  266. {
  267. SET_FLAG(*pSetting, flag);
  268. }
  269. DC_EXIT_POINT:
  270. return;
  271. } /* TRCReadFlag */
  272. /****************************************************************************/
  273. /* FUNCTION: TRCSetDefaults(...) */
  274. /* */
  275. /* DESCRIPTION: */
  276. /* ============ */
  277. /* This function sets the trace defaults. */
  278. /* */
  279. /* PARAMETERS: */
  280. /* =========== */
  281. /* None. */
  282. /* */
  283. /* RETURNS: */
  284. /* ======== */
  285. /* Nothing. */
  286. /* */
  287. /****************************************************************************/
  288. DCVOID DCINTERNAL TRCSetDefaults(DCVOID)
  289. {
  290. /************************************************************************/
  291. /* Set the default values for the trace configuration. The subsequent */
  292. /* calls to TRCReadProfInt will only modify the default value if the */
  293. /* appropriate entry exists in the configuration data. */
  294. /* */
  295. /* We set the following things: */
  296. /* */
  297. /* - trace level to Alert. */
  298. /* - enable all component groups. */
  299. /* - remove all prefixes. */
  300. /* - set the maximum trace file size to the default value. */
  301. /* - set the data truncation size to the default value. */
  302. /* - set the function name size to the default value. */
  303. /* - enable the beep and file flags. */
  304. /* - set the first trace file name to TRC1.TXT */
  305. /* - set the second trace file name to TRC2.TXT */
  306. /* In Win32, additionally */
  307. /* - set time stamp */
  308. /* - set process ID */
  309. /* - set thread ID */
  310. /* */
  311. /************************************************************************/
  312. trcpConfig->traceLevel = TRC_DEFAULT_TRACE_LEVEL;
  313. trcpConfig->components = TRC_DEFAULT_COMPONENTS;
  314. trcpConfig->prefixList[0] = TRC_DEFAULT_PREFIX_LIST;
  315. trcpConfig->maxFileSize = TRC_DEFAULT_MAX_FILE_SIZE;
  316. trcpConfig->dataTruncSize = TRC_DEFAULT_DATA_TRUNC_SIZE;
  317. trcpConfig->funcNameLength = TRC_DEFAULT_FUNC_NAME_LENGTH;
  318. trcpConfig->flags = 0UL;
  319. SET_FLAG(trcpConfig->flags, TRC_DEFAULT_FLAGS);
  320. StringCchCopy(trcpConfig->fileNames[0],
  321. SIZE_TCHARS(trcpConfig->fileNames[0]),
  322. TRC_DEFAULT_FILE_NAME0);
  323. StringCchCopy(trcpConfig->fileNames[1],
  324. SIZE_TCHARS(trcpConfig->fileNames[1]),
  325. TRC_DEFAULT_FILE_NAME1);
  326. return;
  327. } /* TRCSetDefaults */
  328. /****************************************************************************/
  329. /* FUNCTION: TRCReadSharedDataConfig(...) */
  330. /* */
  331. /* DESCRIPTION: */
  332. /* ============ */
  333. /* This function reads configuration data into the shared data area. */
  334. /* */
  335. /* PARAMETERS: */
  336. /* =========== */
  337. /* None. */
  338. /* */
  339. /* RETURNS: */
  340. /* ======== */
  341. /* Nothing. */
  342. /* */
  343. /****************************************************************************/
  344. DCVOID DCINTERNAL TRCReadSharedDataConfig(DCVOID)
  345. {
  346. /************************************************************************/
  347. /* Call routine to set up trace defaults. */
  348. /************************************************************************/
  349. TRCSetDefaults();
  350. /************************************************************************/
  351. /* Determine the trace level. */
  352. /************************************************************************/
  353. TRCReadProfInt(_T("TraceLevel"), &(trcpConfig->traceLevel));
  354. if (trcpConfig->traceLevel > TRC_LEVEL_DIS )
  355. {
  356. /********************************************************************/
  357. /* Bad trace level. Set to default. */
  358. /********************************************************************/
  359. trcpConfig->traceLevel = TRC_DEFAULT_TRACE_LEVEL;
  360. }
  361. /************************************************************************/
  362. /* Determine the maximum size of each trace file. */
  363. /************************************************************************/
  364. TRCReadProfInt(_T("TraceFileSize"), &(trcpConfig->maxFileSize));
  365. if ((trcpConfig->maxFileSize < TRC_MIN_TRC_FILE_SIZE) ||
  366. (trcpConfig->maxFileSize > TRC_MAX_TRC_FILE_SIZE))
  367. {
  368. /********************************************************************/
  369. /* Trace file setting in registry/ini file is out of bounds. */
  370. /********************************************************************/
  371. (trcpConfig->maxFileSize) = TRC_DEFAULT_MAX_FILE_SIZE;
  372. }
  373. /************************************************************************/
  374. /* Determine the data truncation size. */
  375. /************************************************************************/
  376. TRCReadProfInt(_T("DataTruncSize"), &(trcpConfig->dataTruncSize));
  377. if ( trcpConfig->dataTruncSize > TRC_MAX_TRC_FILE_SIZE )
  378. {
  379. /********************************************************************/
  380. /* Data trunc size is out of bounds. */
  381. /********************************************************************/
  382. trcpConfig->dataTruncSize = TRC_DEFAULT_DATA_TRUNC_SIZE;
  383. }
  384. /************************************************************************/
  385. /* Determine the function name size. */
  386. /************************************************************************/
  387. TRCReadProfInt(_T("FuncNameLength"), &(trcpConfig->funcNameLength));
  388. if ( trcpConfig->funcNameLength >
  389. (TRC_FRMT_BUFFER_SIZE - TRC_LINE_BUFFER_SIZE) )
  390. {
  391. /********************************************************************/
  392. /* Func name length is out of bounds. */
  393. /********************************************************************/
  394. trcpConfig->funcNameLength = TRC_DEFAULT_FUNC_NAME_LENGTH;
  395. }
  396. /************************************************************************/
  397. /* Read the prefix list in. This is in the form <COMP>=L where <COMP> */
  398. /* is the component name and L is the desired trace level. For example */
  399. /* TRCAPI=2,TRCINT=0 enables alert level tracing for module TRCAPI and */
  400. /* debug level tracing for module TRCINT. */
  401. /************************************************************************/
  402. TRCReadProfString(_T("Prefixes"),
  403. trcpConfig->prefixList,
  404. TRC_PREFIX_LIST_SIZE);
  405. /************************************************************************/
  406. /* Read in the trace file names. */
  407. /************************************************************************/
  408. TRCReadProfString(_T("FileName1"),
  409. trcpConfig->fileNames[0],
  410. TRC_FILE_NAME_SIZE);
  411. TRCReadProfString(_T("FileName2"),
  412. trcpConfig->fileNames[1],
  413. TRC_FILE_NAME_SIZE);
  414. /************************************************************************/
  415. /* Component groups. */
  416. /************************************************************************/
  417. TRCReadFlag(_T("NETWORK"), TRC_GROUP_NETWORK, &trcpConfig->components);
  418. TRCReadFlag(_T("SECURITY"), TRC_GROUP_SECURITY, &trcpConfig->components);
  419. TRCReadFlag(_T("CORE"), TRC_GROUP_CORE, &trcpConfig->components);
  420. TRCReadFlag(_T("UI"), TRC_GROUP_UI, &trcpConfig->components);
  421. TRCReadFlag(_T("UTILITIES"),TRC_GROUP_UTILITIES, &trcpConfig->components);
  422. /************************************************************************/
  423. /* The following groups should be permanently off, as they're disused. */
  424. /************************************************************************/
  425. #ifdef DC_OMIT
  426. TRCReadFlag(_T("UNUSED1"), TRC_GROUP_UNUSED1, &trcpConfig->components);
  427. TRCReadFlag(_T("UNUSED2"), TRC_GROUP_UNUSED2, &trcpConfig->components);
  428. TRCReadFlag(_T("UNUSED3"), TRC_GROUP_UNUSED3, &trcpConfig->components);
  429. TRCReadFlag(_T("UNUSED4"), TRC_GROUP_UNUSED4, &trcpConfig->components);
  430. TRCReadFlag(_T("UNUSED5"), TRC_GROUP_UNUSED5, &trcpConfig->components);
  431. #endif
  432. /************************************************************************/
  433. /* @@@ SJ Aug 97 */
  434. /* Remove this as the components become used. */
  435. /************************************************************************/
  436. CLEAR_FLAG(trcpConfig->components, TRC_GROUP_UNUSED1);
  437. CLEAR_FLAG(trcpConfig->components, TRC_GROUP_UNUSED2);
  438. CLEAR_FLAG(trcpConfig->components, TRC_GROUP_UNUSED3);
  439. CLEAR_FLAG(trcpConfig->components, TRC_GROUP_UNUSED4);
  440. CLEAR_FLAG(trcpConfig->components, TRC_GROUP_UNUSED5);
  441. /************************************************************************/
  442. /* Trace flags. */
  443. /************************************************************************/
  444. TRCReadFlag(_T("BreakOnError"), TRC_OPT_BREAK_ON_ERROR, &trcpConfig->flags);
  445. TRCReadFlag(_T("BeepOnError"), TRC_OPT_BEEP_ON_ERROR, &trcpConfig->flags);
  446. TRCReadFlag(_T("FileOutput"), TRC_OPT_FILE_OUTPUT, &trcpConfig->flags);
  447. TRCReadFlag(_T("DebugOutput"), TRC_OPT_DEBUGGER_OUTPUT, &trcpConfig->flags);
  448. TRCReadFlag(_T("FlushOnTrace"), TRC_OPT_FLUSH_ON_TRACE, &trcpConfig->flags);
  449. TRCReadFlag(_T("ProfileTrace"), TRC_OPT_PROFILE_TRACING, &trcpConfig->flags);
  450. TRCReadFlag(_T("StackTracing"), TRC_OPT_STACK_TRACING, &trcpConfig->flags);
  451. TRCReadFlag(_T("ProcessID"), TRC_OPT_PROCESS_ID, &trcpConfig->flags);
  452. TRCReadFlag(_T("ThreadID"), TRC_OPT_THREAD_ID, &trcpConfig->flags);
  453. TRCReadFlag(_T("TimeStamp"), TRC_OPT_TIME_STAMP, &trcpConfig->flags);
  454. TRCReadFlag(_T("BreakOnAssert"),TRC_OPT_BREAK_ON_ASSERT, &trcpConfig->flags);
  455. #ifdef DC_OMIT
  456. /****************************************************************************/
  457. /* Not implemented yet. */
  458. /****************************************************************************/
  459. TRCReadFlag(_T("RelativeTimeStamp"), TRC_OPT_RELATIVE_TIME_STAMP,
  460. &trcpConfig->flags);
  461. #endif
  462. return;
  463. } /* TRCReadSharedDataConfig */
  464. /****************************************************************************/
  465. /* FUNCTION: TRCShouldTraceThis(...) */
  466. /* */
  467. /* DESCRIPTION: */
  468. /* ============ */
  469. /* This function decides whether this trace line should be traced based */
  470. /* on the currently selected components and prefixes. Note that this */
  471. /* function is not called if the trace level of the line is lower than */
  472. /* the currently selected trace level. */
  473. /* */
  474. /* PARAMETERS: */
  475. /* =========== */
  476. /* traceComponent : the component group producing this trace. */
  477. /* pFileName : the name of the file producing this trace. */
  478. /* */
  479. /* RETURNS: */
  480. /* ======== */
  481. /* TRUE if the line should be traced and FALSE otherwise. */
  482. /* */
  483. /****************************************************************************/
  484. DCBOOL DCINTERNAL TRCShouldTraceThis(DCUINT32 traceComponent,
  485. DCUINT32 traceLevel,
  486. PDCTCHAR pFileName,
  487. DCUINT32 lineNumber)
  488. {
  489. DCBOOL rc = FALSE;
  490. PDCTCHAR pName;
  491. PDCTCHAR pTemp;
  492. DCUINT32 pfxLength;
  493. DCUINT pfxArrayNum;
  494. DCUINT32 pfxTraceLevel;
  495. DCBOOL32 pfxFnTrcLevel;
  496. /************************************************************************/
  497. /* First of all check the trace level. If the trace level is error or */
  498. /* above then we trace regardless. */
  499. /************************************************************************/
  500. if ((traceLevel >= TRC_LEVEL_ERR) && (traceLevel != TRC_PROFILE_TRACE))
  501. {
  502. rc = TRUE;
  503. DC_QUIT;
  504. }
  505. /************************************************************************/
  506. /* If this component is suppressed then just quit. */
  507. /************************************************************************/
  508. if (0 == (traceComponent & trcpConfig->components))
  509. {
  510. DC_QUIT;
  511. }
  512. /************************************************************************/
  513. /* If prefix checking requested then do it now. */
  514. /************************************************************************/
  515. if (_T('\0') == trcpConfig->prefixList[0])
  516. {
  517. /********************************************************************/
  518. /* The prefix list is empty so just quit. */
  519. /********************************************************************/
  520. rc = TRUE;
  521. DC_QUIT;
  522. }
  523. /************************************************************************/
  524. /* First we have to move past any explicit directory names in the file */
  525. /* name. */
  526. /************************************************************************/
  527. pName = pFileName;
  528. pTemp = DC_TSTRCHR(pName, _T('\\'));
  529. while (NULL != pTemp)
  530. {
  531. pName = &(pTemp[1]);
  532. pTemp = DC_TSTRCHR(pName, _T('\\'));
  533. }
  534. /************************************************************************/
  535. /* We now have a pointer to the actual file prefix. We need to compare */
  536. /* this with the list of prefixes that have been set (These have the */
  537. /* format: */
  538. /* */
  539. /* MODNAM=n,MODAPI=m,MODINT=o */
  540. /* */
  541. /* where MODNAM is the module name and m is the trace level). */
  542. /* */
  543. /* Set the prefix array number indicator <prefixArrayNumber> to 0 and */
  544. /* null the temporary pointer. */
  545. /************************************************************************/
  546. /************************************************************************/
  547. /* Try to find the current module name in the prefix list. */
  548. /************************************************************************/
  549. for (pfxArrayNum = 0; pfxArrayNum < TRC_NUM_PREFIXES; pfxArrayNum++)
  550. {
  551. /********************************************************************/
  552. /* If the first character of the prefix name is a zero then ignore */
  553. /* and break as we have reached the end of the prefix list. */
  554. /********************************************************************/
  555. if (_T('\0') == trcpFilter->trcPfxNameArray[pfxArrayNum][0])
  556. {
  557. rc = FALSE;
  558. DC_QUIT;
  559. }
  560. /********************************************************************/
  561. /* Determine the length of the current prefix string. */
  562. /********************************************************************/
  563. pfxLength = DC_TSTRLEN(trcpFilter->trcPfxNameArray[pfxArrayNum]);
  564. /********************************************************************/
  565. /* Now perform a case insensitive comparison between the prefix */
  566. /* array and the file name. */
  567. /********************************************************************/
  568. if (0 == TRCStrnicmp(pName,
  569. trcpFilter->trcPfxNameArray[pfxArrayNum],
  570. pfxLength))
  571. {
  572. /****************************************************************/
  573. /* If no line number range is specified or the line number of */
  574. /* this piece of trace is within the range then consider it as */
  575. /* a candidate for tracing out. */
  576. /****************************************************************/
  577. if ((0 == trcpFilter->trcPfxStartArray[pfxArrayNum]) ||
  578. ((lineNumber < trcpFilter->trcPfxEndArray[pfxArrayNum]) &&
  579. (lineNumber > trcpFilter->trcPfxStartArray[pfxArrayNum])))
  580. {
  581. /************************************************************/
  582. /* Now determine the prefix trace level. */
  583. /************************************************************/
  584. pfxTraceLevel = trcpFilter->trcPfxLevelArray[pfxArrayNum];
  585. pfxFnTrcLevel = trcpFilter->trcPfxFnLvlArray[pfxArrayNum];
  586. /************************************************************/
  587. /* Finally compare the trace level to the level specified */
  588. /* in the prefix string. If the statement trace level is */
  589. /* lower than prefix level then we don't trace. */
  590. /************************************************************/
  591. if (((traceLevel == TRC_PROFILE_TRACE) && pfxFnTrcLevel) ||
  592. (traceLevel >= pfxTraceLevel))
  593. {
  594. rc = TRUE;
  595. DC_QUIT;
  596. }
  597. }
  598. }
  599. }
  600. DC_EXIT_POINT:
  601. return(rc);
  602. } /* TRCShouldTraceThis */
  603. /****************************************************************************/
  604. /* FUNCTION: TRCSplitPrefixes(...) */
  605. /* */
  606. /* DESCRIPTION: */
  607. /* ============ */
  608. /* This function takes a comma seperated array of prefixes and converts */
  609. /* them into an array. Each member of this array is a seperate prefix. */
  610. /* */
  611. /* PARAMETERS: */
  612. /* =========== */
  613. /* None. */
  614. /* */
  615. /* RETURNS: */
  616. /* ======== */
  617. /* Nothing. */
  618. /* */
  619. /****************************************************************************/
  620. DCVOID DCINTERNAL TRCSplitPrefixes(DCVOID)
  621. {
  622. PDCTCHAR pStart;
  623. PDCTCHAR pEnd;
  624. DCUINT numChars;
  625. DCUINT currentArrayNumber;
  626. DCUINT i;
  627. DCUINT32 startLine;
  628. DCUINT32 endLine;
  629. /************************************************************************/
  630. /* First of all we blank out the old prefix name array. */
  631. /************************************************************************/
  632. DC_MEMSET(trcpFilter->trcPfxNameArray,
  633. '\0',
  634. sizeof(trcpFilter->trcPfxNameArray));
  635. /************************************************************************/
  636. /* Now blank out the old prefix level array. */
  637. /************************************************************************/
  638. for (i = 0; i < TRC_NUM_PREFIXES; i++)
  639. {
  640. trcpFilter->trcPfxLevelArray[i] = 0;
  641. trcpFilter->trcPfxFnLvlArray[i] = FALSE;
  642. trcpFilter->trcPfxStartArray[i] = 0;
  643. trcpFilter->trcPfxEndArray[i] = 0;
  644. }
  645. /************************************************************************/
  646. /* Set the current prefix array number to zero (i.e. ready to index the */
  647. /* first element of the prefix array). */
  648. /************************************************************************/
  649. currentArrayNumber = 0;
  650. /************************************************************************/
  651. /* Split the prefix string into an array of seperate elements. */
  652. /************************************************************************/
  653. pStart = trcpConfig->prefixList;
  654. /************************************************************************/
  655. /* Ignore any spaces at the start of the string. */
  656. /************************************************************************/
  657. while (_T(' ') == *pStart)
  658. {
  659. pStart++;
  660. }
  661. /************************************************************************/
  662. /* Now set <pEnd> to point to the same point as <pStart>. */
  663. /************************************************************************/
  664. pEnd = pStart;
  665. while (_T('\0') != *pEnd)
  666. {
  667. /********************************************************************/
  668. /* Now run along the string looking for a comma, an equals sign, */
  669. /* the end, a space or a bracket. */
  670. /********************************************************************/
  671. while ((_T('\0') != *pEnd) &&
  672. (_T('=') != *pEnd) &&
  673. (_T(' ') != *pEnd) &&
  674. (_T('(') != *pEnd) &&
  675. (_T(',') != *pEnd))
  676. {
  677. pEnd = CharNext(pEnd);
  678. }
  679. /********************************************************************/
  680. /* We now have a valid string to write to the trace buffer so get */
  681. /* its length. */
  682. /********************************************************************/
  683. numChars = (DCUINT)(pEnd - pStart);
  684. /********************************************************************/
  685. /* The maximum allowable length of the string is 7 characters (a 7 */
  686. /* character prefix). If the length is greater than 7 characters */
  687. /* then we truncate it. */
  688. /********************************************************************/
  689. if (numChars > 7)
  690. {
  691. numChars = 7;
  692. }
  693. /********************************************************************/
  694. /* Now use <DC_MEMCPY> to copy the characters from the prefix */
  695. /* string into the prefix array. Note that as we zeroed the array */
  696. /* out at the start we don't need to add a terminating NULL to the */
  697. /* prefix array string. */
  698. /********************************************************************/
  699. DC_MEMCPY(trcpFilter->trcPfxNameArray[currentArrayNumber],
  700. pStart,
  701. numChars * sizeof(TCHAR));
  702. /********************************************************************/
  703. /* Skip any spaces after this word, which may precede an '='. */
  704. /********************************************************************/
  705. while (_T(' ') == *pEnd)
  706. {
  707. pEnd++;
  708. }
  709. /********************************************************************/
  710. /* Now split the trace level out and store it in the level array. */
  711. /* If <pEnd> is currently pointing to an equals sign then we need */
  712. /* to copy the trace level which follows to the level array. */
  713. /* Otherwise we do nothing as the default level is set to */
  714. /* TRC_LEVEL_DBG. */
  715. /********************************************************************/
  716. if (_T('=') == *pEnd)
  717. {
  718. /****************************************************************/
  719. /* Increment past the equals sign. */
  720. /****************************************************************/
  721. pEnd++;
  722. /****************************************************************/
  723. /* Skip any spaces after the '='. */
  724. /****************************************************************/
  725. while (_T(' ') == *pEnd)
  726. {
  727. pEnd++;
  728. }
  729. /****************************************************************/
  730. /* Check that we have not reached the end of the string or a */
  731. /* comma. This will happen if we have a prefix list such as */
  732. /* 'trcint='. In this case we just ignore the equals sign. */
  733. /* Also check that the level specified is valid - otherwise */
  734. /* ignore it. */
  735. /****************************************************************/
  736. if ((_T('\0') != *pEnd) &&
  737. (_T(',') != *pEnd) &&
  738. (*pEnd >= TRC_LEVEL_MIN_CHAR) &&
  739. (*pEnd <= TRC_LEVEL_MAX_CHAR))
  740. {
  741. trcpFilter->trcPfxLevelArray[currentArrayNumber] =
  742. (DCUINT32) (*pEnd - _T('0'));
  743. /************************************************************/
  744. /* Skip past the number. */
  745. /************************************************************/
  746. pEnd++;
  747. }
  748. /****************************************************************/
  749. /* Check for a the function entry/exit trace flag. */
  750. /****************************************************************/
  751. if (DC_TOUPPER(*pEnd) == TRC_LEVEL_PRF_CHAR)
  752. {
  753. trcpFilter->trcPfxFnLvlArray[currentArrayNumber] = TRUE;
  754. pEnd++;
  755. }
  756. }
  757. /********************************************************************/
  758. /* Skip any spaces after this word, which may precede an '('. */
  759. /********************************************************************/
  760. while (_T(' ') == *pEnd)
  761. {
  762. pEnd++;
  763. }
  764. /********************************************************************/
  765. /* Now split out the (optional) line number range. */
  766. /* */
  767. /* Syntax is (aaa-bbb), where aaa is the start line number and bbb */
  768. /* is the end line number. */
  769. /* */
  770. /* Spaces are allowed - e.g. ( aaa - bbb ) */
  771. /********************************************************************/
  772. if (_T('(') == *pEnd)
  773. {
  774. pEnd++; /* skip past the open bracket */
  775. startLine = 0;
  776. endLine = 0;
  777. /****************************************************************/
  778. /* Skip past blanks */
  779. /****************************************************************/
  780. while (_T(' ') == *pEnd)
  781. {
  782. pEnd++;
  783. }
  784. /****************************************************************/
  785. /* Extract the start line number */
  786. /****************************************************************/
  787. while ((_T('0') <= *pEnd) &&
  788. (_T('9') >= *pEnd))
  789. {
  790. startLine = (startLine * 10) + (*pEnd - _T('0'));
  791. pEnd++;
  792. }
  793. /****************************************************************/
  794. /* Look for the next delimiter: '-' or ')' */
  795. /****************************************************************/
  796. while ((_T('-') != *pEnd) &&
  797. (_T(')') != *pEnd) &&
  798. (_T('\0') != *pEnd))
  799. {
  800. pEnd = CharNext(pEnd);
  801. }
  802. /****************************************************************/
  803. /* Stop now if we've reached the end of the line */
  804. /****************************************************************/
  805. if (_T('\0') == *pEnd)
  806. {
  807. TRCDebugOutput(_T("Unexpected end of line in prefixes"));
  808. DC_QUIT;
  809. }
  810. /****************************************************************/
  811. /* Extract the end line number (if any) */
  812. /****************************************************************/
  813. if (_T('-') == *pEnd)
  814. {
  815. pEnd++; /* skip past '-' */
  816. while (_T(' ') == *pEnd)
  817. {
  818. pEnd++;
  819. }
  820. while ((_T('0') <= *pEnd) &&
  821. (_T('9') >= *pEnd))
  822. {
  823. endLine = (endLine * 10) + (*pEnd - _T('0'));
  824. pEnd++;
  825. }
  826. }
  827. /****************************************************************/
  828. /* Look for the closing delimiter: ')' */
  829. /****************************************************************/
  830. while ((_T('\0') != *pEnd) &&
  831. (_T(')') != *pEnd))
  832. {
  833. pEnd = CharNext(pEnd);
  834. }
  835. /****************************************************************/
  836. /* Stop now if we've reached the end of the line */
  837. /****************************************************************/
  838. if (_T('\0') == *pEnd)
  839. {
  840. TRCDebugOutput(_T("Unexpected end of line in prefixes"));
  841. DC_QUIT;
  842. }
  843. pEnd++; /* Jump past close bracket */
  844. /****************************************************************/
  845. /* Store the start and end line numbers if they make sense */
  846. /****************************************************************/
  847. if (endLine > startLine)
  848. {
  849. trcpFilter->trcPfxStartArray[currentArrayNumber] = startLine;
  850. trcpFilter->trcPfxEndArray[currentArrayNumber] = endLine;
  851. }
  852. }
  853. /********************************************************************/
  854. /* Now increment the currentArrayNumber. */
  855. /********************************************************************/
  856. currentArrayNumber++;
  857. /********************************************************************/
  858. /* Check that we have not overrun the array. */
  859. /********************************************************************/
  860. if (currentArrayNumber >= TRC_NUM_PREFIXES)
  861. {
  862. /****************************************************************/
  863. /* We've overrun the prefix list - so send some trace to the */
  864. /* debug console and then quit. */
  865. /****************************************************************/
  866. TRCDebugOutput(_T("The prefix arrays are full!"));
  867. DC_QUIT;
  868. }
  869. /********************************************************************/
  870. /* If the character at the end of the string is a comma or a space */
  871. /* then skip past it. */
  872. /********************************************************************/
  873. while ((_T(',') == *pEnd) ||
  874. (_T(' ') == *pEnd))
  875. {
  876. pEnd++;
  877. }
  878. /********************************************************************/
  879. /* Set pStart to the same position as pEnd. */
  880. /********************************************************************/
  881. pStart = pEnd;
  882. }
  883. /************************************************************************/
  884. /* We're through so just return. */
  885. /************************************************************************/
  886. DC_EXIT_POINT:
  887. return;
  888. } /* TRCSplitPrefixes */
  889. /****************************************************************************/
  890. /* FUNCTION: TRCStrnicmp(...) */
  891. /* */
  892. /* DESCRIPTION: */
  893. /* ============ */
  894. /* Code to implement a strnicmp (length-limited, case-insensitive string */
  895. /* comparison) because it is otherwise unavailable (see SFR0636). */
  896. /* */
  897. /* PARAMETERS: */
  898. /* =========== */
  899. /* source - source string */
  900. /* target - target string */
  901. /* count - maximum length to compare */
  902. /* */
  903. /* RETURNS: */
  904. /* ======== */
  905. /* 0 - strings match up to specified point */
  906. /* other - strings do not match up to specified point */
  907. /* */
  908. /****************************************************************************/
  909. DCINT32 DCINTERNAL TRCStrnicmp(PDCTCHAR pSource,
  910. PDCTCHAR pTarget,
  911. DCUINT32 count)
  912. {
  913. DCUINT sourcechar;
  914. DCUINT targetchar;
  915. DCINT32 rc=0;
  916. if (count == 0)
  917. {
  918. DC_QUIT;
  919. }
  920. do
  921. {
  922. /********************************************************************/
  923. /* Make sure that we extend characters in an unsigned fashion. */
  924. /********************************************************************/
  925. sourcechar = (DCUINT)(DCUINT8)*pSource++;
  926. targetchar = (DCUINT)(DCUINT8)*pTarget++;
  927. /********************************************************************/
  928. /* Convert to lower case if char is an upper case letter. */
  929. /********************************************************************/
  930. if ( (sourcechar >= _T('A')) && (sourcechar <= _T('Z')) )
  931. {
  932. sourcechar += _T('a') - _T('A');
  933. }
  934. if ( (targetchar >= _T('A')) && (targetchar <= _T('Z')) )
  935. {
  936. targetchar += _T('a') - _T('A');
  937. }
  938. } while ( (0 != (--count)) && sourcechar && (sourcechar == targetchar) );
  939. rc = (DCINT32)(sourcechar - targetchar);
  940. DC_EXIT_POINT:
  941. return(rc);
  942. } /* TRCStrnicmp */
  943. /****************************************************************************/
  944. /* FUNCTION: TRCWriteFlag(...) */
  945. /* */
  946. /* DESCRIPTION: */
  947. /* ============ */
  948. /* This function writes a configuration flag setting. */
  949. /* */
  950. /* PARAMETERS: */
  951. /* =========== */
  952. /* entryName - the profile entry name. */
  953. /* flag - the flag to set or clear. */
  954. /* pSetting - a pointer to the variable containing the flag. */
  955. /* */
  956. /* RETURNS: */
  957. /* ======== */
  958. /* Nothing. */
  959. /* */
  960. /****************************************************************************/
  961. DCVOID DCINTERNAL TRCWriteFlag(PDCTCHAR entryName,
  962. DCUINT32 flag,
  963. DCUINT32 setting)
  964. {
  965. DCUINT32 entryValue = 0;
  966. /************************************************************************/
  967. /* If the flag is set then change the entryValue to 1. */
  968. /************************************************************************/
  969. if (TEST_FLAG(setting, flag))
  970. {
  971. entryValue = 1;
  972. }
  973. /************************************************************************/
  974. /* Call <TRCWriteProfInt> to write the flag settin. */
  975. /************************************************************************/
  976. TRCWriteProfInt(entryName, &entryValue);
  977. return;
  978. } /* TRCWriteFlag */
  979. /****************************************************************************/
  980. /* FUNCTION: TRCWriteSharedDataConfig(...) */
  981. /* */
  982. /* DESCRIPTION: */
  983. /* ============ */
  984. /* This function saves configuration data from the shared data area. */
  985. /* */
  986. /* PARAMETERS: */
  987. /* =========== */
  988. /* None. */
  989. /* */
  990. /* RETURNS: */
  991. /* ======== */
  992. /* Nothing. */
  993. /* */
  994. /****************************************************************************/
  995. DCVOID DCINTERNAL TRCWriteSharedDataConfig(DCVOID)
  996. {
  997. /************************************************************************/
  998. /* Save the trace level. */
  999. /************************************************************************/
  1000. TRCWriteProfInt(_T("TraceLevel"), &(trcpConfig->traceLevel));
  1001. /************************************************************************/
  1002. /* Save the maximum size of each trace file. */
  1003. /************************************************************************/
  1004. TRCWriteProfInt(_T("TraceFileSize"), &(trcpConfig->maxFileSize));
  1005. /************************************************************************/
  1006. /* Save the data truncation size. */
  1007. /************************************************************************/
  1008. TRCWriteProfInt(_T("DataTruncSize"), &(trcpConfig->dataTruncSize));
  1009. /************************************************************************/
  1010. /* Save the function name size. */
  1011. /************************************************************************/
  1012. TRCWriteProfInt(_T("FuncNameLength"), &(trcpConfig->funcNameLength));
  1013. /************************************************************************/
  1014. /* Write the prefix list out. This is in the form <COMP>=L where */
  1015. /* <COMP> is the component name and L is the desired trace level. For */
  1016. /* example CMDATA=2,CMINT=0 enables alert level tracing for module */
  1017. /* CMDATA and debug level tracing for module CMINT. */
  1018. /************************************************************************/
  1019. TRCWriteProfString(_T("Prefixes"), trcpConfig->prefixList);
  1020. /************************************************************************/
  1021. /* Save the trace file names. */
  1022. /************************************************************************/
  1023. TRCWriteProfString(_T("FileName1"), trcpConfig->fileNames[0]);
  1024. TRCWriteProfString(_T("FileName2"), trcpConfig->fileNames[1]);
  1025. /************************************************************************/
  1026. /* Component groups. */
  1027. /************************************************************************/
  1028. TRCWriteFlag(_T("NETWORK"), TRC_GROUP_NETWORK, trcpConfig->components);
  1029. TRCWriteFlag(_T("SECURITY"), TRC_GROUP_SECURITY, trcpConfig->components);
  1030. TRCWriteFlag(_T("CORE"), TRC_GROUP_CORE, trcpConfig->components);
  1031. TRCWriteFlag(_T("UI"), TRC_GROUP_UI, trcpConfig->components);
  1032. TRCWriteFlag(_T("UTILITIES"),TRC_GROUP_UTILITIES, trcpConfig->components);
  1033. #ifdef DC_OMIT
  1034. /****************************************************************************/
  1035. /* These groups are reserved. */
  1036. /****************************************************************************/
  1037. TRCWriteFlag(_T("UNUSED1"), TRC_GROUP_UNUSED1, trcpConfig->components);
  1038. TRCWriteFlag(_T("UNUSED2"), TRC_GROUP_UNUSED2, trcpConfig->components);
  1039. TRCWriteFlag(_T("UNUSED3"), TRC_GROUP_UNUSED3, trcpConfig->components);
  1040. TRCWriteFlag(_T("UNUSED4"), TRC_GROUP_UNUSED4, trcpConfig->components);
  1041. TRCWriteFlag(_T("UNUSED5"), TRC_GROUP_UNUSED5, trcpConfig->components);
  1042. #endif
  1043. /************************************************************************/
  1044. /* Trace flags. */
  1045. /************************************************************************/
  1046. TRCWriteFlag(_T("BreakOnError"), TRC_OPT_BREAK_ON_ERROR, trcpConfig->flags);
  1047. TRCWriteFlag(_T("BeepOnError"), TRC_OPT_BEEP_ON_ERROR, trcpConfig->flags);
  1048. TRCWriteFlag(_T("FileOutput"), TRC_OPT_FILE_OUTPUT, trcpConfig->flags);
  1049. TRCWriteFlag(_T("DebugOutput"), TRC_OPT_DEBUGGER_OUTPUT, trcpConfig->flags);
  1050. TRCWriteFlag(_T("FlushOnTrace"), TRC_OPT_FLUSH_ON_TRACE, trcpConfig->flags);
  1051. TRCWriteFlag(_T("ProfileTrace"), TRC_OPT_PROFILE_TRACING, trcpConfig->flags);
  1052. TRCWriteFlag(_T("StackTracing"), TRC_OPT_STACK_TRACING, trcpConfig->flags);
  1053. TRCWriteFlag(_T("ProcessID"), TRC_OPT_PROCESS_ID, trcpConfig->flags);
  1054. TRCWriteFlag(_T("ThreadID"), TRC_OPT_THREAD_ID, trcpConfig->flags);
  1055. TRCWriteFlag(_T("TimeStamp"), TRC_OPT_TIME_STAMP, trcpConfig->flags);
  1056. TRCWriteFlag(_T("BreakOnAssert"),TRC_OPT_BREAK_ON_ASSERT, trcpConfig->flags);
  1057. #ifdef DC_OMIT
  1058. /****************************************************************************/
  1059. /* Not implemented yet. */
  1060. /****************************************************************************/
  1061. TRCWriteFlag(_T("RelativeTimeStamp"), TRC_OPT_RELATIVE_TIME_STAMP,
  1062. &trcpConfig->flags);
  1063. #endif
  1064. return;
  1065. } /* TRCWriteSharedDataConfig */
  1066. /****************************************************************************/
  1067. /* FUNCTION: TRCCloseAllFiles(...) */
  1068. /* */
  1069. /* DESCRIPTION: */
  1070. /* ============ */
  1071. /* Closes all the trace memory mapped files. */
  1072. /* */
  1073. /* PARAMETERS: */
  1074. /* =========== */
  1075. /* None. */
  1076. /* */
  1077. /* RETURNS: */
  1078. /* ======== */
  1079. /* Nothing. */
  1080. /* */
  1081. /****************************************************************************/
  1082. DCVOID DCINTERNAL TRCCloseAllFiles(DCVOID)
  1083. {
  1084. /************************************************************************/
  1085. /* Close all the trace output files. We close the one that the trace */
  1086. /* indicator is pointing at last - this is because we use the time */
  1087. /* stamp of the trace file to set the trace indicator at the start of */
  1088. /* day (we choose the most recent file). */
  1089. /************************************************************************/
  1090. TRCCloseSingleFile((trcpSharedData->trcIndicator + 1) % TRC_NUM_FILES, 0);
  1091. /************************************************************************/
  1092. /* Now close the other trace file. */
  1093. /************************************************************************/
  1094. TRCCloseSingleFile(trcpSharedData->trcIndicator, 30);
  1095. return;
  1096. } /* TRCCloseAllFiles */
  1097. /****************************************************************************/
  1098. /* FUNCTION: TRCOutput(...) */
  1099. /* */
  1100. /* DESCRIPTION: */
  1101. /* ============ */
  1102. /* This function outputs the passed string to the trace file and/or the */
  1103. /* debugger depending on the options selected. */
  1104. /* */
  1105. /* PARAMETERS: */
  1106. /* =========== */
  1107. /* pText : a pointer to the string. */
  1108. /* length : the length of the string. */
  1109. /* traceLevel : the trace level. */
  1110. /* */
  1111. /* RETURNS: */
  1112. /* ======== */
  1113. /* Nothing. */
  1114. /* */
  1115. /****************************************************************************/
  1116. DCVOID DCINTERNAL TRCOutput(PDCTCHAR pText,
  1117. DCINT length,
  1118. DCINT traceLevel)
  1119. {
  1120. /************************************************************************/
  1121. /* Decide if we should output to file. */
  1122. /************************************************************************/
  1123. if (TEST_FLAG(trcpConfig->flags, TRC_OPT_FILE_OUTPUT))
  1124. {
  1125. TRCOutputToFile(pText, length, traceLevel);
  1126. }
  1127. /************************************************************************/
  1128. /* Decide if we should output to the debugger. */
  1129. /************************************************************************/
  1130. if (TEST_FLAG(trcpConfig->flags, TRC_OPT_DEBUGGER_OUTPUT))
  1131. {
  1132. TRCDebugOutput(pText);
  1133. }
  1134. return;
  1135. } /* TRCOutput */