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.

849 lines
16 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. dbgmsg.cxx
  6. Abstract:
  7. Debug Library
  8. Author:
  9. Steve Kiraly (SteveKi) 10-Dec-1995
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. #pragma hdrstop
  14. //
  15. // Singleton instance.
  16. //
  17. namespace
  18. {
  19. TDebugMsg DebugMsg;
  20. }
  21. /*++
  22. Title:
  23. TDebugMsg_Register
  24. Routine Description:
  25. Registers the prefix, device, trace and break level with the
  26. global debug messaging library.
  27. Arguments:
  28. pszPrefix - pointer to prefix string.
  29. uDevice - debug device type.
  30. eLevel - message trace level.
  31. eBreak - debug break level.
  32. Return Value:
  33. TRUE device registered, FALSE error occurred.
  34. --*/
  35. extern "C"
  36. BOOL
  37. TDebugMsg_Register(
  38. IN LPCTSTR pszPrefix,
  39. IN UINT uDevice,
  40. IN INT eLevel,
  41. IN INT eBreak
  42. )
  43. {
  44. //
  45. // Initialize the debug library, it not already initialized.
  46. //
  47. DebugLibraryInitialize();
  48. //
  49. // Hold the critical section while we access the heap.
  50. //
  51. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  52. //
  53. // Don't re-initialize the message class.
  54. //
  55. if (!DebugMsg.Valid())
  56. {
  57. //
  58. // Initialize the debug heap.
  59. //
  60. DebugMsg.Initialize(pszPrefix, uDevice, eLevel, eBreak);
  61. //
  62. // Expose the debug message class for the debug extension.
  63. //
  64. Globals.DebugMsgSingleton = &DebugMsg;
  65. }
  66. //
  67. // Return the message class status.
  68. //
  69. return DebugMsg.Valid();
  70. }
  71. /*++
  72. Title:
  73. TDebugMsg_Release
  74. Routine Description:
  75. Arguments:
  76. Return Value:
  77. --*/
  78. extern "C"
  79. VOID
  80. TDebugMsg_Release(
  81. VOID
  82. )
  83. {
  84. //
  85. // Initialize the debug library, it not already initialized.
  86. //
  87. DebugLibraryInitialize();
  88. //
  89. // Hold the critical section while we access the heap.
  90. //
  91. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  92. //
  93. // Destroy the message class.
  94. //
  95. DebugMsg.Destroy();
  96. //
  97. // Remote the debug message class from the debug extension.
  98. //
  99. Globals.DebugMsgSingleton = NULL;
  100. }
  101. /*++
  102. Title:
  103. TDebugMsg_vEnable
  104. Routine Description:
  105. Enabled the debug messaging class, debug device will be called
  106. when a message is asked to be sent.
  107. Arguments:
  108. None
  109. Return Value:
  110. None
  111. --*/
  112. extern "C"
  113. VOID
  114. TDebugMsg_Enable(
  115. VOID
  116. )
  117. {
  118. //
  119. // Initialize the debug library, it not already initialized.
  120. //
  121. DebugLibraryInitialize();
  122. //
  123. // Hold the critical section while we access message class.
  124. //
  125. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  126. //
  127. // Only do the command if the message class is enabled.
  128. //
  129. if (DebugMsg.Valid())
  130. {
  131. DebugMsg.Enable();
  132. }
  133. }
  134. /*++
  135. Title:
  136. TDebugMsg_Disable
  137. Routine Description:
  138. Disable the debug messaging class, debug device will not be called
  139. when a message is asked to be sent.
  140. Arguments:
  141. None
  142. Return Value:
  143. None
  144. --*/
  145. extern "C"
  146. VOID
  147. TDebugMsg_Disable(
  148. VOID
  149. )
  150. {
  151. //
  152. // Initialize the debug library, it not already initialized.
  153. //
  154. DebugLibraryInitialize();
  155. //
  156. // Hold the critical section while we access message class.
  157. //
  158. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  159. //
  160. // Only do the command if the message class is enabled.
  161. //
  162. if (DebugMsg.Valid())
  163. {
  164. DebugMsg.Disable();
  165. }
  166. }
  167. /*++
  168. Title:
  169. TDebugMsg_Attach
  170. Routine Description:
  171. Attaches the output device specified by uDevice and pszConfiguration.
  172. if this routing is successfull, the handle to the attached device
  173. is returned in phDevice.
  174. Arguments:
  175. phDevice - pointer to device handle were to return newly created
  176. add attached output device.
  177. uDevice, - output device type to attached, see header file for
  178. an enumeration of valid output device types.
  179. pszConfiguration - pointer to output device specific configuration
  180. string.
  181. Return Value:
  182. TRUE device was attached, FALSE error occurred.
  183. --*/
  184. extern "C"
  185. BOOL
  186. TDebugMsg_Attach(
  187. IN HANDLE *phDevice,
  188. IN UINT uDevice,
  189. IN LPCTSTR pszConfiguration
  190. )
  191. {
  192. //
  193. // Initialize the debug library, it not already initialized.
  194. //
  195. DebugLibraryInitialize();
  196. //
  197. // Hold the critical section while we access message class.
  198. //
  199. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  200. //
  201. // Is the message class valid.
  202. //
  203. BOOL bRetval = DebugMsg.Valid();
  204. //
  205. // Only do the command if the message class is enabled.
  206. //
  207. if (bRetval)
  208. {
  209. bRetval = DebugMsg.Attach(phDevice, uDevice, pszConfiguration);
  210. }
  211. return bRetval;
  212. }
  213. /*++
  214. Title:
  215. TDebugMsg_Detach
  216. Routine Description:
  217. Removes the device specified by the handle from the
  218. list of output devices.
  219. Arguments:
  220. phDevice - Pointer to debug device handle
  221. Return Value:
  222. None
  223. --*/
  224. extern "C"
  225. VOID
  226. TDebugMsg_Detach(
  227. IN HANDLE *phDevice
  228. )
  229. {
  230. //
  231. // Initialize the debug library, it not already initialized.
  232. //
  233. DebugLibraryInitialize();
  234. //
  235. // Hold the critical section while we access message class.
  236. //
  237. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  238. //
  239. // Only do the command if the message class is enabled.
  240. //
  241. if (DebugMsg.Valid())
  242. {
  243. DebugMsg.Detach(phDevice);
  244. }
  245. }
  246. /*++
  247. Title:
  248. TDebugMsg_MsgA
  249. Routine Description:
  250. This function outputs the specified message to the list
  251. of output debug devices. Not this routine is not a general
  252. purpose output routine, the pszMessage parameter must be
  253. have been allocated from the internal debug heap.
  254. Arguments:
  255. uLevel - debug trace and break level
  256. pszFile - pointer to file name
  257. uLine - file line number
  258. pszModulePrefix - pointe to module prefix, OPTIONAL
  259. pszMessage - pointer to post formatted message string, that
  260. was returned from a call to TDebugMsg_pszFmt,
  261. if this pointer is non null then it relased
  262. back to the internal debug heap before this
  263. routine returns.
  264. Return Value:
  265. None
  266. --*/
  267. extern "C"
  268. VOID
  269. TDebugMsg_MsgA(
  270. IN UINT uLevel,
  271. IN LPCTSTR pszFile,
  272. IN UINT uLine,
  273. IN LPCTSTR pszModulePrefix,
  274. IN LPSTR pszMessage
  275. )
  276. {
  277. //
  278. // Initialize the debug library, it not already initialized.
  279. //
  280. DebugLibraryInitialize();
  281. //
  282. // Hold the critical section while we access message class.
  283. //
  284. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  285. //
  286. // Only do the command if the message class is enabled.
  287. //
  288. if (DebugMsg.Valid())
  289. {
  290. DebugMsg.Msg(uLevel, pszFile, uLine, pszModulePrefix, pszMessage);
  291. }
  292. else
  293. {
  294. //
  295. // Message class is not initialized, well lets do it now.
  296. //
  297. DebugMsg.Initialize(NULL, kDbgDebugger, kDbgTrace, kDbgNone);
  298. //
  299. // Only do the command if the message class is enabled.
  300. //
  301. if (DebugMsg.Valid())
  302. {
  303. DebugMsg.Msg(uLevel, pszFile, uLine, pszModulePrefix, pszMessage);
  304. }
  305. else
  306. {
  307. INTERNAL_DELETE [] pszMessage;
  308. }
  309. }
  310. }
  311. /*++
  312. Title:
  313. TDebugMsg_Msg
  314. Routine Description:
  315. This function outputs the specified message to the list
  316. of output debug devices. Not this routine is not a general
  317. purpose output routine, the pszMessage parameter must be
  318. have been allocated from the internal debug heap.
  319. Arguments:
  320. uLevel - debug trace and break level
  321. pszFile - pointer to file name
  322. uLine - file line number
  323. pszModulePrefix - pointe to module prefix, OPTIONAL
  324. pszMessage - pointer to post formatted message string, that
  325. was returned from a call to TDebugMsg_pszFmt,
  326. if this pointer is non null then it relased
  327. back to the internal debug heap before this
  328. routine returns.
  329. Return Value:
  330. Pointer to allocated string, NULL if failure.
  331. --*/
  332. extern "C"
  333. VOID
  334. TDebugMsg_MsgW(
  335. IN UINT uLevel,
  336. IN LPCTSTR pszFile,
  337. IN UINT uLine,
  338. IN LPCTSTR pszModulePrefix,
  339. IN LPWSTR pszMessage
  340. )
  341. {
  342. //
  343. // Initialize the debug library, it not already initialized.
  344. //
  345. DebugLibraryInitialize();
  346. //
  347. // Hold the critical section while we access message class.
  348. //
  349. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  350. //
  351. // Only do the command if the message class is enabled.
  352. //
  353. if (DebugMsg.Valid())
  354. {
  355. DebugMsg.Msg(uLevel, pszFile, uLine, pszModulePrefix, pszMessage);
  356. }
  357. else
  358. {
  359. //
  360. // Message class is not initialized, well lets do it now.
  361. //
  362. DebugMsg.Initialize(NULL, kDbgDebugger, kDbgTrace, kDbgNone);
  363. //
  364. // Only do the command if the message class is enabled.
  365. //
  366. if (DebugMsg.Valid())
  367. {
  368. DebugMsg.Msg(uLevel, pszFile, uLine, pszModulePrefix, pszMessage);
  369. }
  370. else
  371. {
  372. INTERNAL_DELETE [] pszMessage;
  373. }
  374. }
  375. }
  376. /*++
  377. Title:
  378. TDebugMsg_Msg
  379. Routine Description:
  380. This function outputs the specified message to the list
  381. of output debug devices. Not this routine is not a general
  382. purpose output routine, the pszMessage parameter must be
  383. have been allocated from the internal debug heap.
  384. Arguments:
  385. uLevel - debug trace and break level
  386. pszFile - pointer to file name
  387. uLine - file line number
  388. pszModulePrefix - pointe to module prefix, OPTIONAL
  389. pszMessage - pointer to post formatted message string, that
  390. was returned from a call to TDebugMsg_pszFmt,
  391. if this pointer is non null then it relased
  392. back to the internal debug heap before this
  393. routine returns.
  394. Return Value:
  395. None
  396. --*/
  397. VOID
  398. TDebugMsg_Msg(
  399. IN UINT uLevel,
  400. IN LPCTSTR pszFile,
  401. IN UINT uLine,
  402. IN LPCTSTR pszModulePrefix,
  403. IN LPSTR pszMessage
  404. )
  405. {
  406. //
  407. // Initialize the debug library, it not already initialized.
  408. //
  409. DebugLibraryInitialize();
  410. //
  411. // Hold the critical section while we access message class.
  412. //
  413. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  414. //
  415. // Only do the command if the message class is enabled.
  416. //
  417. if (DebugMsg.Valid())
  418. {
  419. DebugMsg.Msg(uLevel, pszFile, uLine, pszModulePrefix, pszMessage);
  420. }
  421. else
  422. {
  423. //
  424. // Message class is not initialized, well lets do it now.
  425. //
  426. DebugMsg.Initialize(NULL, kDbgDebugger, kDbgTrace, kDbgNone);
  427. //
  428. // Only do the command if the message class is enabled.
  429. //
  430. if (DebugMsg.Valid())
  431. {
  432. DebugMsg.Msg(uLevel, pszFile, uLine, pszModulePrefix, pszMessage);
  433. }
  434. else
  435. {
  436. INTERNAL_DELETE [] pszMessage;
  437. }
  438. }
  439. }
  440. /*++
  441. Title:
  442. TDebugMsg_Msg
  443. Routine Description:
  444. This function outputs the specified message to the list
  445. of output debug devices. Not this routine is not a general
  446. purpose output routine, the pszMessage parameter must be
  447. have been allocated from the internal debug heap.
  448. Arguments:
  449. uLevel - debug trace and break level
  450. pszFile - pointer to file name
  451. uLine - file line number
  452. pszModulePrefix - pointe to module prefix, OPTIONAL
  453. pszMessage - pointer to post formatted message string, that
  454. was returned from a call to TDebugMsg_pszFmt,
  455. if this pointer is non null then it relased
  456. back to the internal debug heap before this
  457. routine returns.
  458. Return Value:
  459. None
  460. --*/
  461. VOID
  462. TDebugMsg_Msg(
  463. IN UINT uLevel,
  464. IN LPCTSTR pszFile,
  465. IN UINT uLine,
  466. IN LPCTSTR pszModulePrefix,
  467. IN LPWSTR pszMessage
  468. )
  469. {
  470. //
  471. // Initialize the debug library, it not already initialized.
  472. //
  473. DebugLibraryInitialize();
  474. //
  475. // Hold the critical section while we access message class.
  476. //
  477. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  478. //
  479. // Only do the command if the message class is enabled.
  480. //
  481. if (DebugMsg.Valid())
  482. {
  483. DebugMsg.Msg(uLevel, pszFile, uLine, pszModulePrefix, pszMessage);
  484. }
  485. else
  486. {
  487. //
  488. // Message class is not initialized, well lets do it now.
  489. //
  490. DebugMsg.Initialize(NULL, kDbgDebugger, kDbgTrace, kDbgNone);
  491. //
  492. // Only do the command if the message class is enabled.
  493. //
  494. if (DebugMsg.Valid())
  495. {
  496. DebugMsg.Msg(uLevel, pszFile, uLine, pszModulePrefix, pszMessage);
  497. }
  498. else
  499. {
  500. INTERNAL_DELETE [] pszMessage;
  501. }
  502. }
  503. }
  504. /*++
  505. Title:
  506. TDebugMsg_FmtA
  507. Routine Description:
  508. This function takes a format string and a list of arguments
  509. and returns a allocated string that is formated, specified
  510. by the format string.
  511. Arguments:
  512. pszFmt - pointer to format string.
  513. ... - varable number of arguments.
  514. Return Value:
  515. Pointer to allocated string, NULL if failure.
  516. --*/
  517. extern "C"
  518. LPSTR
  519. WINAPIV
  520. TDebugMsg_FmtA(
  521. IN LPCSTR pszFmt,
  522. IN ...
  523. )
  524. {
  525. va_list pArgs;
  526. va_start(pArgs, pszFmt);
  527. LPSTR pszResult = vFormatA(pszFmt, pArgs);
  528. va_end(pArgs);
  529. return pszResult;
  530. }
  531. /*++
  532. Title:
  533. TDebugMsg_FmtW
  534. Routine Description:
  535. This function takes a format string and a list of arguments
  536. and returns a allocated string that is formated, specified
  537. by the format string.
  538. Arguments:
  539. pszFmt - pointer to format string.
  540. ... - varable number of arguments.
  541. Return Value:
  542. Pointer to allocated string, NULL if failure.
  543. --*/
  544. extern "C"
  545. LPWSTR
  546. WINAPIV
  547. TDebugMsg_FmtW(
  548. IN LPCWSTR pszFmt,
  549. IN ...
  550. )
  551. {
  552. va_list pArgs;
  553. va_start(pArgs, pszFmt);
  554. LPWSTR pszResult = vFormatW(pszFmt, pArgs);
  555. va_end(pArgs);
  556. return pszResult;
  557. }
  558. /*++
  559. Title:
  560. TDebugMsg_Fmt
  561. Routine Description:
  562. This function takes a format string and a list of arguments
  563. and returns a allocated string that is formated, specified
  564. by the format string.
  565. Arguments:
  566. pszFmt - pointer to format string.
  567. ... - varable number of arguments.
  568. Return Value:
  569. Pointer to allocated string, NULL if failure.
  570. --*/
  571. LPSTR
  572. WINAPIV
  573. TDebugMsg_Fmt(
  574. IN LPCSTR pszFmt,
  575. IN ...
  576. )
  577. {
  578. va_list pArgs;
  579. va_start(pArgs, pszFmt);
  580. LPSTR pszResult = vFormatA(pszFmt, pArgs);
  581. va_end(pArgs);
  582. return pszResult;
  583. }
  584. /*++
  585. Title:
  586. TDebugMsg_Fmt
  587. Routine Description:
  588. This function takes a format string and a list of arguments
  589. and returns a allocated string that is formated, specified
  590. by the format string.
  591. Arguments:
  592. pszFmt - pointer to format string.
  593. ... - varable number of arguments.
  594. Return Value:
  595. Pointer to allocated format string, NULL if failure.
  596. --*/
  597. LPWSTR
  598. WINAPIV
  599. TDebugMsg_Fmt(
  600. IN LPCWSTR pszFmt,
  601. IN ...
  602. )
  603. {
  604. va_list pArgs;
  605. va_start(pArgs, pszFmt);
  606. LPWSTR pszResult = vFormatW(pszFmt, pArgs);
  607. va_end(pArgs);
  608. return pszResult;
  609. }
  610. /*++
  611. Title:
  612. TDebugMsg_SetMessageFieldFormat
  613. Routine Description:
  614. Arguments:
  615. Return Value:
  616. None.
  617. --*/
  618. VOID
  619. TDebugMsg_SetMessageFieldFormat(
  620. IN UINT eField,
  621. IN LPTSTR pszFormat
  622. )
  623. {
  624. //
  625. // Initialize the debug library, it not already initialized.
  626. //
  627. DebugLibraryInitialize();
  628. //
  629. // Hold the critical section while we access message class.
  630. //
  631. TDebugCriticalSection::TLock CS(GlobalCriticalSection);
  632. //
  633. // Only do the command if the message class is enabled.
  634. //
  635. if (DebugMsg.Valid())
  636. {
  637. DebugMsg.SetMessageFieldFormat(eField, pszFormat);
  638. }
  639. }