Source code of Windows XP (NT5)
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.

855 lines
40 KiB

  1. /**MOD+**********************************************************************/
  2. /* Module: wtrcint.c */
  3. /* */
  4. /* Purpose: Internal tracing functions - Windows specific. */
  5. /* */
  6. /* Copyright(C) Microsoft Corporation 1997 */
  7. /* */
  8. /****************************************************************************/
  9. /** Changes:
  10. * $Log: Y:/logs/trc/wtrcint.c_v $
  11. *
  12. * Rev 1.10 22 Aug 1997 15:11:48 SJ
  13. * SFR1291: Win16 Trace DLL doesn't write integers to ini file properly
  14. *
  15. * Rev 1.9 09 Jul 1997 18:03:42 AK
  16. * SFR1016: Initial changes to support Unicode
  17. *
  18. * Rev 1.8 03 Jul 1997 13:29:04 AK
  19. * SFR0000: Initial development completed
  20. **/
  21. /**MOD-**********************************************************************/
  22. /****************************************************************************/
  23. /* */
  24. /* INCLUDES */
  25. /* */
  26. /****************************************************************************/
  27. #include <adcg.h>
  28. /****************************************************************************/
  29. /* Define TRC_FILE and TRC_GROUP. */
  30. /****************************************************************************/
  31. #define TRC_FILE "wtrcint"
  32. #define TRC_GROUP TRC_GROUP_TRACE
  33. /****************************************************************************/
  34. /* Trace specific includes. */
  35. /* */
  36. /* Note that including atrcapi.h automatically includes wtrcapi.h for us. */
  37. /****************************************************************************/
  38. #include <atrcapi.h>
  39. #include <atrcint.h>
  40. #include <wtrcrc.h>
  41. #include <ndcgver.h>
  42. /****************************************************************************/
  43. /* */
  44. /* DATA */
  45. /* */
  46. /****************************************************************************/
  47. #define DC_INCLUDE_DATA
  48. #include <atrcdata.c>
  49. #undef DC_INCLUDE_DATA
  50. /****************************************************************************/
  51. /* */
  52. /* FUNCTIONS */
  53. /* */
  54. /****************************************************************************/
  55. /****************************************************************************/
  56. /* FUNCTION: TRCGetModuleFileName(...) */
  57. /* */
  58. /* DESCRIPTION: */
  59. /* ============ */
  60. /* This function gets the DLL module file name, without path or extension. */
  61. /* Global trchModule must contain the library module handle (WIN32) or */
  62. /* instance handle (WIN16). */
  63. /* */
  64. /* PARAMETERS: */
  65. /* =========== */
  66. /* pModuleName : address of buffer into which the module name is written. */
  67. /* */
  68. /* RETURNS: */
  69. /* ======== */
  70. /* DC_RC_OK is successful, error code otherwise. */
  71. /* */
  72. /****************************************************************************/
  73. DCUINT DCINTERNAL TRCGetModuleFileName(PDCTCHAR pModuleName,
  74. UINT cchModuleName)
  75. {
  76. DCINT rc = DC_RC_OK;
  77. PDCTCHAR pTemp;
  78. PDCTCHAR pName;
  79. DCTCHAR pModuleFileName[TRC_FILE_NAME_SIZE];
  80. HRESULT hr;
  81. /************************************************************************/
  82. /* Get the trace DLL module file name. We use this later when we get a */
  83. /* stack trace. */
  84. /************************************************************************/
  85. if ( GetModuleFileName(trchModule,
  86. pModuleFileName,
  87. TRC_FILE_NAME_SIZE) != 0 )
  88. {
  89. /********************************************************************/
  90. /* The module file name is currently in the form of a complete */
  91. /* path - however we only want the actual module name. */
  92. /********************************************************************/
  93. pName = pModuleFileName;
  94. pTemp = DC_TSTRCHR(pName, _T('\\'));
  95. while (NULL != pTemp)
  96. {
  97. pName = pTemp + 1;
  98. pTemp = DC_TSTRCHR(pName, _T('\\'));
  99. }
  100. /********************************************************************/
  101. /* Now remove the file name extension - we do this by replacing */
  102. /* the decimal point with a null. */
  103. /********************************************************************/
  104. pTemp = DC_TSTRCHR(pName, _T('.'));
  105. if (NULL != pTemp)
  106. {
  107. *pTemp = _T('\0');
  108. }
  109. /********************************************************************/
  110. /* Finally copy what remains into the caller's buffer */
  111. /********************************************************************/
  112. hr = StringCchCopy(pModuleName, cchModuleName, pName);
  113. if (FAILED(hr)) {
  114. rc = TRC_RC_IO_ERROR;
  115. }
  116. }
  117. else
  118. {
  119. rc = TRC_RC_IO_ERROR;
  120. }
  121. return(rc);
  122. }
  123. /**PROC+*********************************************************************/
  124. /* Name: TRCAssertDlgProc */
  125. /* */
  126. /* Purpose: Dialog Proc for assert box */
  127. /* */
  128. /* Returns: TRUE / FALSE */
  129. /* */
  130. /* Params: IN usual Windows parameters */
  131. /* */
  132. /**PROC-*********************************************************************/
  133. INT_PTR CALLBACK TRCAssertDlgProc(HWND hwndDlg,
  134. UINT msg,
  135. WPARAM wParam,
  136. LPARAM lParam)
  137. {
  138. INT_PTR rc = FALSE;
  139. RECT rect;
  140. DCINT xPos;
  141. DCINT yPos;
  142. PDCTCHAR pText;
  143. switch (msg)
  144. {
  145. case WM_INITDIALOG:
  146. {
  147. /****************************************************************/
  148. /* Set the text */
  149. /****************************************************************/
  150. pText = (PDCTCHAR)lParam;
  151. SetDlgItemText(hwndDlg, TRC_ID_TEXT, pText);
  152. SetWindowText(hwndDlg, TRC_ASSERT_TITLE);
  153. /****************************************************************/
  154. /* Center on the screen, and set to topmost. */
  155. /****************************************************************/
  156. GetWindowRect(hwndDlg, &rect);
  157. xPos = ( GetSystemMetrics(SM_CXSCREEN) -
  158. (rect.right - rect.left)) / 2;
  159. yPos = ( GetSystemMetrics(SM_CYSCREEN) -
  160. (rect.bottom - rect.top)) / 2;
  161. SetWindowPos(hwndDlg,
  162. HWND_TOPMOST,
  163. xPos, yPos,
  164. rect.right - rect.left,
  165. rect.bottom - rect.top,
  166. SWP_NOACTIVATE);
  167. rc = TRUE;
  168. }
  169. break;
  170. case WM_COMMAND:
  171. {
  172. switch(DC_GET_WM_COMMAND_ID(wParam))
  173. {
  174. case IDABORT:
  175. case IDRETRY:
  176. case IDIGNORE:
  177. {
  178. PostMessage(hwndDlg,
  179. WM_USER + DC_GET_WM_COMMAND_ID(wParam),
  180. 0, 0);
  181. rc = TRUE;
  182. }
  183. break;
  184. default:
  185. {
  186. /********************************************************/
  187. /* Ignore other messages */
  188. /********************************************************/
  189. }
  190. break;
  191. }
  192. }
  193. case WM_CLOSE:
  194. {
  195. /****************************************************************/
  196. /* If 'x' selected, treat as 'Ignore' */
  197. /****************************************************************/
  198. PostMessage(hwndDlg, WM_USER + IDIGNORE, 0, 0);
  199. }
  200. break;
  201. default:
  202. {
  203. /****************************************************************/
  204. /* Ignore */
  205. /****************************************************************/
  206. }
  207. break;
  208. }
  209. return(rc);
  210. } /* TRCAssertDlgProc */
  211. /****************************************************************************/
  212. /* FUNCTION: TRCDisplayAssertBox(...) */
  213. /* */
  214. /* DESCRIPTION: */
  215. /* ============ */
  216. /* This function displays an assert box and then decides (based on the user */
  217. /* action) whether to kill the thread, jump into a debugger or just ignore */
  218. /* the assert. */
  219. /* */
  220. /* PARAMETERS: */
  221. /* =========== */
  222. /* pText : a pointer to the null-terminated assert text string. */
  223. /* */
  224. /* RETURNS: */
  225. /* ======== */
  226. /* Nothing. */
  227. /* */
  228. /****************************************************************************/
  229. DCVOID DCINTERNAL TRCDisplayAssertBox(PDCTCHAR pText)
  230. {
  231. HWND hwndDlg;
  232. MSG msg;
  233. DCINT rc;
  234. HRESULT hr;
  235. TCHAR szFormattedText[TRC_FRMT_BUFFER_SIZE];
  236. /************************************************************************/
  237. /* If we are not currently displaying an assert dialog box then display */
  238. /* one. This function will display an assert box and then handle the */
  239. /* user action (i.e. whether we kill the thread, jump into the */
  240. /* debugger or just ignore (!) the assert). */
  241. /* */
  242. /* Note that the testing and setting of the flag is not done under a */
  243. /* mutex and therefore can potentially be preempted. There is */
  244. /* therefore the possibility that multiple threads can assert */
  245. /* simulataneously (a rare occurance) and thus we end up with multiple */
  246. /* assert dialogs on the screen. However we avoid the cascading assert */
  247. /* problem. */
  248. /************************************************************************/
  249. if (TEST_FLAG(trcpFilter->trcStatus, TRC_STATUS_ASSERT_DISPLAYED))
  250. {
  251. DC_QUIT;
  252. }
  253. /************************************************************************/
  254. /* Set the flag to indicate that an assert is currently displayed, */
  255. /* display the assert and then clear the flag. */
  256. /************************************************************************/
  257. SET_FLAG(trcpFilter->trcStatus, TRC_STATUS_ASSERT_DISPLAYED);
  258. /************************************************************************/
  259. /* To prevent re-entrancy, do not use MessageBox. Create a dialog and */
  260. /* use a message loop to handle this until it has been dismissed. Note */
  261. /* that this will block the thread which issued the assert. */
  262. /* Pass the assert text to the dialog's WM_INITDDIALOG callback. */
  263. /************************************************************************/
  264. hwndDlg = CreateDialogParam(trchModule,
  265. MAKEINTRESOURCE(TRC_IDD_ASSERT),
  266. NULL,
  267. TRCAssertDlgProc,
  268. (LPARAM)(pText));
  269. if (hwndDlg == NULL)
  270. {
  271. /********************************************************************/
  272. /* Use Message Box - but note that this will give reentrancy */
  273. /* problems. Since the choice on this dialog is */
  274. /* Abort/Retry/Ignore, we add an explanatory message to the effect */
  275. /* that 'Retry' is really 'Debug'. */
  276. /********************************************************************/
  277. hr = StringCchPrintf(szFormattedText,
  278. SIZE_TCHARS(szFormattedText),
  279. _T("%s %s"),
  280. pText,
  281. TRC_ASSERT_TEXT2);
  282. if (SUCCEEDED(hr)) {
  283. rc = MessageBox(NULL,
  284. pText,
  285. TRC_ASSERT_TITLE,
  286. MB_ABORTRETRYIGNORE | MB_ICONSTOP |
  287. MB_SETFOREGROUND);
  288. }
  289. else {
  290. DC_QUIT;
  291. }
  292. }
  293. else
  294. {
  295. /********************************************************************/
  296. /* Show the dialog. */
  297. /********************************************************************/
  298. ShowWindow(hwndDlg, SW_SHOW);
  299. /********************************************************************/
  300. /* Only pull off messages for this dialog. */
  301. /********************************************************************/
  302. while (GetMessage (&msg, hwndDlg, 0, 0))
  303. {
  304. TranslateMessage(&msg);
  305. DispatchMessage(&msg);
  306. /****************************************************************/
  307. /* WM_USER + ID??? is used to terminate processing. */
  308. /****************************************************************/
  309. if (msg.message >= WM_USER)
  310. {
  311. /************************************************************/
  312. /* finished */
  313. /************************************************************/
  314. EndDialog(hwndDlg, IDOK);
  315. break;
  316. }
  317. }
  318. /********************************************************************/
  319. /* Get the return code from the message ID */
  320. /********************************************************************/
  321. if (msg.message >= WM_USER)
  322. {
  323. rc = msg.message - WM_USER;
  324. }
  325. else
  326. {
  327. /****************************************************************/
  328. /* WM_QUIT - treat as an Abort. */
  329. /****************************************************************/
  330. rc = IDABORT;
  331. }
  332. }
  333. /************************************************************************/
  334. /* Now that the assert box is no more, clear the flag. */
  335. /************************************************************************/
  336. CLEAR_FLAG(trcpFilter->trcStatus, TRC_STATUS_ASSERT_DISPLAYED);
  337. /************************************************************************/
  338. /* Switch on the return code from MessageBox. */
  339. /************************************************************************/
  340. switch (rc)
  341. {
  342. case IDABORT:
  343. {
  344. /****************************************************************/
  345. /* Abort selected - so exit the current thread. */
  346. /****************************************************************/
  347. TRCExitProcess(TRC_THREAD_EXIT);
  348. }
  349. break;
  350. case IDRETRY:
  351. {
  352. /****************************************************************/
  353. /* Retry selected - jump into the debugger if JIT (Just In */
  354. /* Time) debugging is enabled. */
  355. /****************************************************************/
  356. DebugBreak();
  357. }
  358. break;
  359. case IDIGNORE:
  360. {
  361. /****************************************************************/
  362. /* Ignore selected - just blindly carry on... */
  363. /****************************************************************/
  364. }
  365. break;
  366. }
  367. DC_EXIT_POINT:
  368. return;
  369. } /* TRCDisplayAssertBox */
  370. /****************************************************************************/
  371. /* FUNCTION: TRCInternalTrace(...) */
  372. /* */
  373. /* DESCRIPTION: */
  374. /* ============ */
  375. /* This function writes a string to the debugger on every process attach */
  376. /* detach. Note that in general the mutex will not have been obtained */
  377. /* when this function is called. */
  378. /* */
  379. /* The problem with this function is that DllMain will call this function */
  380. /* every time a thread attaches / detaches at which point it has the */
  381. /* process critical section. However we may be in the middle of a stack */
  382. /* trace on another thread and holding the trace mutex. Stack tracing */
  383. /* requires the process critical section while holding the trace mutex */
  384. /* which deadlocks if DllMain is waiting on the trace mutex. */
  385. /* */
  386. /* PARAMETERS: */
  387. /* =========== */
  388. /* type : is this an process/thread attach/detach or a symbols */
  389. /* loading/loaded/unloaded. */
  390. /* */
  391. /* RETURNS: */
  392. /* ======== */
  393. /* Nothing. */
  394. /* */
  395. /****************************************************************************/
  396. DCVOID DCINTERNAL TRCInternalTrace(DCUINT32 type)
  397. {
  398. PDCTCHAR pStatus;
  399. DC_DATE theDate;
  400. DC_TIME theTime;
  401. DCUINT32 processId;
  402. DCUINT32 threadId;
  403. DCUINT32 length;
  404. DCTCHAR szOutputBuffer[TRC_FRMT_BUFFER_SIZE];
  405. HRESULT hr;
  406. /************************************************************************/
  407. /* Determine whether this is an attach or a detach. */
  408. /************************************************************************/
  409. switch (type)
  410. {
  411. case TRC_TRACE_DLL_INITIALIZE:
  412. {
  413. pStatus = _T("Trace initialized");
  414. }
  415. break;
  416. case TRC_TRACE_DLL_TERMINATE:
  417. {
  418. pStatus = _T("Trace terminated ");
  419. }
  420. break;
  421. case TRC_PROCESS_ATTACH_NOTIFY:
  422. {
  423. pStatus = _T("Process attached ");
  424. }
  425. break;
  426. case TRC_PROCESS_DETACH_NOTIFY:
  427. {
  428. pStatus = _T("Process detached ");
  429. }
  430. break;
  431. case TRC_THREAD_ATTACH_NOTIFY:
  432. {
  433. pStatus = _T("Thread attached ");
  434. }
  435. break;
  436. case TRC_THREAD_DETACH_NOTIFY:
  437. {
  438. pStatus = _T("Thread detached ");
  439. }
  440. break;
  441. case TRC_SYMBOLS_LOADING_NOTIFY:
  442. {
  443. pStatus = _T("Loading symbols ");
  444. }
  445. break;
  446. case TRC_SYMBOLS_LOADED_NOTIFY:
  447. {
  448. pStatus = _T("Symbols loaded ");
  449. }
  450. break;
  451. case TRC_SYMBOLS_UNLOAD_NOTIFY:
  452. {
  453. pStatus = _T("Symbols freed ");
  454. }
  455. break;
  456. case TRC_FILES_RESET:
  457. {
  458. pStatus = _T("Trace files reset");
  459. }
  460. break;
  461. default:
  462. {
  463. pStatus = _T("Undefined ");
  464. }
  465. break;
  466. }
  467. /************************************************************************/
  468. /* Get the current date and time. */
  469. /************************************************************************/
  470. TRCGetCurrentDate(&theDate);
  471. TRCGetCurrentTime(&theTime);
  472. /************************************************************************/
  473. /* Get our process and thread IDs. */
  474. /************************************************************************/
  475. processId = TRCGetCurrentProcessId();
  476. threadId = TRCGetCurrentThreadId();
  477. /************************************************************************/
  478. /* Format the attach/detach string. */
  479. /************************************************************************/
  480. hr = StringCchPrintf(
  481. szOutputBuffer,
  482. SIZE_TCHARS(szOutputBuffer),
  483. _T("### %s (") TRC_PROC_FMT _T(":") TRC_THRD_FMT _T(") at ")
  484. _T("") TRC_TIME_FMT _T(" ") TRC_DATE_FMT _T(" ###\r\n"),
  485. pStatus,
  486. processId,
  487. threadId,
  488. theTime.hour,
  489. theTime.min,
  490. theTime.sec,
  491. theTime.hundredths,
  492. theDate.day,
  493. theDate.month,
  494. theDate.year
  495. );
  496. if (SUCCEEDED(hr)) {
  497. /************************************************************************/
  498. /* Now output this string to the debugger. We can't output this to */
  499. /* file as we need to have the trace mutex to do that and we may not */
  500. /* have the mutex. To avoid confusion we only write to the debugger. */
  501. /************************************************************************/
  502. length = DC_TSTRLEN(szOutputBuffer);
  503. OutputDebugString(szOutputBuffer);
  504. }
  505. return;
  506. } /* TRCInternalTrace */
  507. /****************************************************************************/
  508. /* FUNCTION: TRCMaybeSwapFile(...) */
  509. /* */
  510. /* DESCRIPTION: */
  511. /* ============ */
  512. /* This function checks if the current trace file has enough space to */
  513. /* accomodate a string of the supplied length and, if not, makes the other */
  514. /* trace file current. */
  515. /* */
  516. /* PARAMETERS: */
  517. /* =========== */
  518. /* length : length of the string. */
  519. /* */
  520. /* RETURNS: */
  521. /* ======== */
  522. /* Nothing. */
  523. /* */
  524. /****************************************************************************/
  525. DCVOID DCINTERNAL TRCMaybeSwapFile(DCUINT length)
  526. {
  527. /************************************************************************/
  528. /* If the length of the string plus the offset is greater than the */
  529. /* length of the trace file then we need to swap trace files. */
  530. /************************************************************************/
  531. if ((trcpSharedData->trcOffset + length) > trcpConfig->maxFileSize)
  532. {
  533. /********************************************************************/
  534. /* We need to swap trace files so set the offset to 0 and then */
  535. /* flip the trace file. */
  536. /********************************************************************/
  537. trcpSharedData->trcOffset = 0;
  538. trcpSharedData->trcIndicator++;
  539. trcpSharedData->trcIndicator %= TRC_NUM_FILES;
  540. /********************************************************************/
  541. /* Now we need to reset the new trace file by blanking it out. */
  542. /********************************************************************/
  543. TRCBlankFile(trcpSharedData->trcIndicator);
  544. }
  545. DC_EXIT_POINT:
  546. return;
  547. } /* TRCOutputToFile */
  548. /****************************************************************************/
  549. /* FUNCTION: TRCReadProfInt(...) */
  550. /* */
  551. /* DESCRIPTION: */
  552. /* ============ */
  553. /* This reads a private profile integer from the registry. */
  554. /* */
  555. /* PARAMETERS: */
  556. /* =========== */
  557. /* pSection : section containing the entry to read */
  558. /* pEntry : entry name of integer to retrieve */
  559. /* pValue : buffer to return the entry in */
  560. /* */
  561. /* RETURNS: */
  562. /* ======== */
  563. /* 0 : success */
  564. /* TRC_RC_IO_ERROR : I/O error. */
  565. /* */
  566. /****************************************************************************/
  567. DCUINT DCINTERNAL TRCReadProfInt(PDCTCHAR pEntry,
  568. PDCUINT32 pValue)
  569. {
  570. DCUINT rc = 0;
  571. /************************************************************************/
  572. /* First try to read the value from the current user section */
  573. /************************************************************************/
  574. rc = TRCReadEntry(HKEY_CURRENT_USER,
  575. pEntry,
  576. (PDCTCHAR)pValue,
  577. sizeof(*pValue),
  578. REG_DWORD);
  579. if (0 != rc)
  580. {
  581. /********************************************************************/
  582. /* Couldn't read the value from the current user section. Try to */
  583. /* pick up a default value from the local machine section. */
  584. /********************************************************************/
  585. rc = TRCReadEntry(HKEY_LOCAL_MACHINE,
  586. pEntry,
  587. (PDCTCHAR)pValue,
  588. sizeof(*pValue),
  589. REG_DWORD);
  590. if (0 != rc)
  591. {
  592. /****************************************************************/
  593. /* There is nothing we can do so just fall through. */
  594. /****************************************************************/
  595. }
  596. }
  597. return(rc);
  598. } /* TRCReadProfInt */
  599. /****************************************************************************/
  600. /* FUNCTION: TRCReadProfString(...) */
  601. /* */
  602. /* DESCRIPTION: */
  603. /* ============ */
  604. /* This reads a private profile string from registry. */
  605. /* */
  606. /* PARAMETERS: */
  607. /* =========== */
  608. /* pSection : section containing the entry to read. */
  609. /* pEntry : entry name of string to retrieve (if NULL all entries */
  610. /* in the section are returned). */
  611. /* pBuffer : buffer to return the entry in. */
  612. /* bufferSize : size of the buffer in bytes. */
  613. /* */
  614. /* RETURNS: */
  615. /* ======== */
  616. /* 0 : success. */
  617. /* TRC_RC_IO_ERROR : I/O error. */
  618. /* */
  619. /****************************************************************************/
  620. DCUINT DCINTERNAL TRCReadProfString(PDCTCHAR pEntry,
  621. PDCTCHAR pBuffer,
  622. DCINT16 bufferSize)
  623. {
  624. DCUINT rc = 0;
  625. /************************************************************************/
  626. /* First try to read the value from the current user section. */
  627. /************************************************************************/
  628. rc = TRCReadEntry(HKEY_CURRENT_USER,
  629. pEntry,
  630. pBuffer,
  631. bufferSize,
  632. REG_SZ);
  633. if (0 != rc)
  634. {
  635. /********************************************************************/
  636. /* Couldn't read the value from the current user section. Try to */
  637. /* pick up a default value from the local machine section. */
  638. /********************************************************************/
  639. rc = TRCReadEntry(HKEY_LOCAL_MACHINE,
  640. pEntry,
  641. pBuffer,
  642. bufferSize,
  643. REG_SZ);
  644. if (0 != rc)
  645. {
  646. /****************************************************************/
  647. /* There is nothing we can do so just fall through. */
  648. /****************************************************************/
  649. }
  650. }
  651. return(rc);
  652. } /* TRCReadProfString */
  653. /****************************************************************************/
  654. /* FUNCTION: TRCResetTraceFiles(...) */
  655. /* */
  656. /* DESCRIPTION: */
  657. /* ============ */
  658. /* This function resets the trace files. It nulls out both trace files */
  659. /* and then resets the file offset to 0 and the file indicator to file 0. */
  660. /* */
  661. /* PARAMETERS: */
  662. /* =========== */
  663. /* None. */
  664. /* */
  665. /* RETURNS: */
  666. /* ======== */
  667. /* Nothing. */
  668. /* */
  669. /****************************************************************************/
  670. DCVOID DCINTERNAL TRCResetTraceFiles(DCVOID)
  671. {
  672. DCUINT i;
  673. /************************************************************************/
  674. /* Blank out the trace files. Note that we must have the mutex at this */
  675. /* point. */
  676. /************************************************************************/
  677. for (i = 0; i < TRC_NUM_FILES; i++)
  678. {
  679. TRCBlankFile(i);
  680. }
  681. /************************************************************************/
  682. /* Set the trace file indicator to file 0 and set the file offset to 0. */
  683. /************************************************************************/
  684. trcpSharedData->trcIndicator = 0;
  685. trcpSharedData->trcOffset = 0;
  686. /************************************************************************/
  687. /* Output a debug string. */
  688. /************************************************************************/
  689. TRCInternalTrace(TRC_FILES_RESET);
  690. } /* TRCResetTraceFiles */
  691. /****************************************************************************/
  692. /* FUNCTION: TRCWriteProfInt(...) */
  693. /* */
  694. /* DESCRIPTION: */
  695. /* ============ */
  696. /* This writes a private profile integer to the registry. */
  697. /* */
  698. /* PARAMETERS: */
  699. /* =========== */
  700. /* pSection : section containing the entry written */
  701. /* pEntry : entry name of integer to write. If the entry does not */
  702. /* exist it is created and if it is NULL the entire */
  703. /* section is deleted. */
  704. /* pValue : pointer to the integer to be written. If the pointer */
  705. /* is NULL the entry is deleted. */
  706. /* */
  707. /* RETURNS: */
  708. /* ======== */
  709. /* 0 : success */
  710. /* TRC_RC_IO_ERROR : I/O error. */
  711. /* */
  712. /****************************************************************************/
  713. DCUINT DCINTERNAL TRCWriteProfInt(PDCTCHAR pEntry,
  714. PDCUINT32 pValue)
  715. {
  716. DCUINT rc = 0;
  717. /************************************************************************/
  718. /* Write the entry to the current user section. */
  719. /************************************************************************/
  720. rc = TRCWriteEntry(HKEY_CURRENT_USER,
  721. pEntry,
  722. (PDCTCHAR)pValue,
  723. sizeof(DCINT),
  724. REG_DWORD);
  725. if (0 != rc)
  726. {
  727. TRCDebugOutput(_T("Failed to write int"));
  728. }
  729. return(rc);
  730. } /* TRCWriteProfInt */
  731. /****************************************************************************/
  732. /* FUNCTION: TRCWriteProfString(...) */
  733. /* */
  734. /* DESCRIPTION: */
  735. /* ============ */
  736. /* This writes a private profile string to the registry. */
  737. /* */
  738. /* PARAMETERS: */
  739. /* =========== */
  740. /* pSection : section containing the entry written */
  741. /* pEntry : entry name of string to write. If the entry does not */
  742. /* exist it is created and if it is NULL the entire */
  743. /* section is deleted. */
  744. /* pBuffer : buffer containing the entry. If the buffer is NULL */
  745. /* the entry is deleted. */
  746. /* */
  747. /* RETURNS: */
  748. /* ======== */
  749. /* 0 : success */
  750. /* TRC_RC_IO_ERROR : I/O error. */
  751. /* */
  752. /****************************************************************************/
  753. DCUINT DCINTERNAL TRCWriteProfString(PDCTCHAR pEntry,
  754. PDCTCHAR pBuffer)
  755. {
  756. DCUINT rc = 0;
  757. /************************************************************************/
  758. /* Write the entry to the current user section */
  759. /************************************************************************/
  760. rc = TRCWriteEntry(HKEY_CURRENT_USER,
  761. pEntry,
  762. pBuffer,
  763. DC_TSTRBYTELEN(pBuffer),
  764. REG_SZ);
  765. if (0 != rc)
  766. {
  767. TRCDebugOutput(_T("Failed to write string"));
  768. }
  769. return(rc);
  770. } /* TRCWriteProfString */
  771. #include <ntrcint.c>