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.

2430 lines
73 KiB

  1. //
  2. // Copyright 2001 - Microsoft Corporation
  3. //
  4. // Created By:
  5. // Geoff Pease (GPease) 23-JAN-2001
  6. //
  7. // Maintained By:
  8. // Geoff Pease (GPease) 23-JAN-2001
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11. #pragma once
  12. //
  13. // KB: USES_SYSALLOCSTRING gpease 8-NOV-1999
  14. // Turn this on if you are going to use the OLE automation
  15. // functions: SysAllocString, SysFreeString, etc..
  16. //
  17. // #define USES_SYSALLOCSTRING
  18. //
  19. // Trace Flags
  20. //
  21. typedef enum _TRACEFLAGS
  22. {
  23. mtfALWAYS = 0xFFFFFFFF,
  24. mtfNEVER = 0x00000000,
  25. // function entry/exits, call, scoping
  26. mtfASSERT_HR = 0x00000001, // Halt if HRESULT is an error
  27. mtfQUERYINTERFACE = 0x00000002, // Query Interface details and halt on error
  28. // other
  29. mtfCALLS = 0x00000010, // Function calls that use the TraceMsgDo macro
  30. mtfFUNC = 0x00000020, // Functions entrances w/parameters
  31. mtfSTACKSCOPE = 0x00000040, // if set, debug spew will generate bar/space for level each of the call stack
  32. mtfPERTHREADTRACE = 0x00000080, // Enables per thread tracing
  33. // specific
  34. mtfDLL = 0x00000100, // DLL specific
  35. mtfWM = 0x00000200, // Window Messages
  36. // memory
  37. mtfMEMORYLEAKS = 0x01000000, // Halts when a memory leak is detected on thread exit
  38. mtfMEMORYINIT = 0x02000000, // Initializes new memory allocations to non-zero value
  39. mtfMEMORYALLOCS = 0x04000000, // Turns on spew to display each de/allocation.
  40. // citracker spew
  41. mtfCITRACKERS = 0x08000000, // CITrackers will spew entrances and exits
  42. // output prefixes
  43. mtfADDTIMEDATE = 0x10000000, // Replaces Filepath(Line) with Date/Time
  44. mtfBYMODULENAME = 0x20000000, // Puts the module name at the beginning of the line
  45. mtfOUTPUTTODISK = 0x80000000, // Writes output to disk
  46. } TRACEFLAGS;
  47. typedef DWORD TRACEFLAG;
  48. #define ASZ_NEWLINE "\r\n"
  49. #define SZ_NEWLINE TEXT(ASZ_NEWLINE)
  50. #define SIZEOF_ASZ_NEWLINE ( sizeof( ASZ_NEWLINE ) - sizeof( CHAR ) )
  51. #define SIZEOF_SZ_NEWLINE ( sizeof( SZ_NEWLINE ) - sizeof( TCHAR ) )
  52. #ifdef DEBUG
  53. #pragma message( "BUILD: DEBUG macros being built" )
  54. //
  55. // Globals
  56. //
  57. extern DWORD g_TraceMemoryIndex; // TLS index for the memory tracking link list
  58. extern DWORD g_dwCounter; // Stack depth counter
  59. extern TRACEFLAG g_tfModule; // Global tracing flags
  60. extern const LPCTSTR g_pszModuleIn; // Local module name - use DEFINE_MODULE
  61. extern const TCHAR g_szTrue[]; // Array "TRUE"
  62. extern const TCHAR g_szFalse[]; // Array "FALSE"
  63. //
  64. // Definition Macros
  65. //
  66. #define DEFINE_MODULE( _module ) const LPCTSTR g_pszModuleIn = TEXT(_module);
  67. #define __MODULE__ g_pszModuleIn
  68. #define DEFINE_THISCLASS( _class ) static const TCHAR g_szClass[] = TEXT(_class);
  69. #define __THISCLASS__ g_szClass
  70. //
  71. // ImageHlp Stuff - not ready for prime time yet.
  72. //
  73. #if defined( IMAGEHLP_ENABLED )
  74. #include <imagehlp.h>
  75. typedef BOOL ( * PFNSYMGETSYMFROMADDR )( HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL );
  76. typedef BOOL ( * PFNSYMGETLINEFROMADDR )( HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE );
  77. typedef BOOL ( * PFNSYMGETMODULEINFO )( HANDLE, DWORD, PIMAGEHLP_MODULE );
  78. extern HINSTANCE g_hImageHlp; // IMAGEHLP.DLL instance handle
  79. extern PFNSYMGETSYMFROMADDR g_pfnSymGetSymFromAddr;
  80. extern PFNSYMGETLINEFROMADDR g_pfnSymGetLineFromAddr;
  81. extern PFNSYMGETMODULEINFO g_pfnSymGetModuleInfo;
  82. #endif // IMAGEHLP_ENABLED
  83. void
  84. DebugIncrementStackDepthCounter( void );
  85. void
  86. DebugDecrementStackDepthCounter( void );
  87. //////////////////////////////////////////////////////////////////////////////
  88. //++
  89. //
  90. // MACRO
  91. // TraceInitializeProcess(
  92. // _rgControl,
  93. // _sizeofControl
  94. // )
  95. //
  96. // Description:
  97. // Should be called in the DLL main on process attach or in the entry
  98. // routine of an EXE. Initializes debugging globals and TLS. Registers
  99. // the WMI tracing facilities (if WMI support is enabled).
  100. //
  101. // Arguments:
  102. // _rgControl WMI control block (see DEBUG_WMI_CONTROL_GUIDS)
  103. // _sizeofControl The sizeof( _rgControl )
  104. //
  105. // Return Values:
  106. // None.
  107. //
  108. //--
  109. //////////////////////////////////////////////////////////////////////////////
  110. #define TraceInitializeProcess() \
  111. do \
  112. { \
  113. DebugInitializeTraceFlags(); \
  114. } while ( 0 )
  115. //////////////////////////////////////////////////////////////////////////////
  116. //++
  117. //
  118. // MACRO
  119. // TraceInitializeThread(
  120. // _name
  121. // )
  122. //
  123. // Description:
  124. // Should be called in the DLL thread attach or when a new thread is
  125. // created. Sets up the memory tracing for that thread as well as
  126. // establishing the tfThread for each thread (if mtfPERTHREADTRACE
  127. // is set in g_tfModule).
  128. //
  129. // Arguments:
  130. // _name NULL or the name of the thread.
  131. //
  132. // Return Values:
  133. // None.
  134. //
  135. //--
  136. //////////////////////////////////////////////////////////////////////////////
  137. #define TraceInitializeThread( _name ) \
  138. do \
  139. { \
  140. TlsSetValue( g_TraceMemoryIndex, NULL ); \
  141. DebugInitializeThreadTraceFlags( _name ); \
  142. } while ( 0 )
  143. //////////////////////////////////////////////////////////////////////////////
  144. //++
  145. //
  146. // MACRO
  147. // TraceTerminateThread( void )
  148. //
  149. // Description:
  150. // Should be called before a thread terminates. It will check to make
  151. // sure all memory allocated by the thread was released properly. It
  152. // will also cleanup any per thread structures.
  153. //
  154. // Arguments:
  155. // None.
  156. //
  157. // Return Values:
  158. // None.
  159. //
  160. //--
  161. //////////////////////////////////////////////////////////////////////////////
  162. #define TraceTerminateThread() \
  163. do \
  164. { \
  165. DebugMemoryCheck( NULL, NULL ); \
  166. DebugTerminiateThreadTraceFlags(); \
  167. } while ( 0 )
  168. //////////////////////////////////////////////////////////////////////////////
  169. //++
  170. //
  171. // MACRO
  172. // TraceCreateMemoryList(
  173. // _pmbIn
  174. // )
  175. //
  176. // Description:
  177. // Creates a thread independent list to track objects.
  178. //
  179. // _pmbIn should be an LPVOID.
  180. //
  181. // Arguments:
  182. // _pmbIn - Pointer to store the head of the list.
  183. //
  184. // Return Values:
  185. // None.
  186. //
  187. //--
  188. //////////////////////////////////////////////////////////////////////////////
  189. #define TraceCreateMemoryList( _pmbIn ) \
  190. DebugCreateMemoryList( TEXT(__FILE__), __LINE__, __MODULE__, &_pmbIn, TEXT(#_pmbIn) );
  191. //////////////////////////////////////////////////////////////////////////////
  192. //++
  193. //
  194. // MACRO
  195. // TraceTerminateMemoryList(
  196. // _pmbIn
  197. // )
  198. //
  199. // Description:
  200. // Checks to make sure the list is empty before destroying the list.
  201. //
  202. // _pmbIn should be an LPVOID.
  203. //
  204. // Arguments:
  205. // _pmbIn - Pointer to store the head of the list.
  206. //
  207. // Return Values:
  208. // None.
  209. //
  210. //--
  211. //////////////////////////////////////////////////////////////////////////////
  212. #define TraceTerminateMemoryList( _pmbIn ) \
  213. do \
  214. { \
  215. DebugMemoryCheck( _pmbIn, TEXT(#_pmbIn) ); \
  216. DebugFree( _pmbIn, TEXT(__FILE__), __LINE__, __MODULE__ ); \
  217. } while ( 0 )
  218. //////////////////////////////////////////////////////////////////////////////
  219. //++
  220. //
  221. // MACRO
  222. // TraceMoveToMemoryList(
  223. // _addr
  224. // _pmbIn
  225. // )
  226. //
  227. // Description:
  228. // Moves an object from the thread tracking list to a thread independent
  229. // memory list (_pmbIn).
  230. //
  231. // _pmbIn should be castable to an LPVOID.
  232. //
  233. // Arguments:
  234. // _addr - Address of object to move.
  235. // _pmbIn - Pointer to store the head of the list.
  236. //
  237. // Return Values:
  238. // None.
  239. //
  240. //--
  241. //////////////////////////////////////////////////////////////////////////////
  242. #define TraceMoveToMemoryList( _addr, _pmbIn ) \
  243. DebugMoveToMemoryList( TEXT(__FILE__), __LINE__, __MODULE__, _addr, _pmbIn, TEXT(#_pmbIn) );
  244. //////////////////////////////////////////////////////////////////////////////
  245. //++
  246. //
  247. // MACRO
  248. // TraceMoveFromMemoryList(
  249. // _addr
  250. // _pmbIn
  251. // )
  252. //
  253. // Description:
  254. // Moves an object from a thread independent memory list (_pmbIn) to the
  255. // per thread tracking list.
  256. //
  257. // _pmbIn should be castable to an LPVOID.
  258. //
  259. // Arguments:
  260. // _addr - Address of object to move.
  261. // _pmbIn - Pointer to store the head of the list.
  262. //
  263. // Return Values:
  264. // None.
  265. //
  266. //--
  267. //////////////////////////////////////////////////////////////////////////////
  268. #define TraceMoveFromMemoryList( _addr, _pmbIn ) \
  269. DebugMoveFromMemoryList( TEXT(__FILE__), __LINE__, __MODULE__, _addr, _pmbIn, TEXT(#_pmbIn) );
  270. //////////////////////////////////////////////////////////////////////////////
  271. //++
  272. //
  273. // MACRO
  274. // TraceMemoryListDelete(
  275. // _addr
  276. // _pmbIn
  277. // )
  278. //
  279. // Description:
  280. // Moves and object from the thread tracking list to a thread independent
  281. // memory list (_pmbIn).
  282. //
  283. // _pmbIn should be an LPVOID.
  284. //
  285. // Arguments:
  286. // _addr - Address of object to delete.
  287. // _pmbIn - Pointer to store the head of the list.
  288. //
  289. // Return Values:
  290. // None.
  291. //
  292. //--
  293. //////////////////////////////////////////////////////////////////////////////
  294. #define TraceMemoryListDelete( _addr, _pmbIn, _fClobberIn ) \
  295. DebugMemoryListDelete( TEXT(__FILE__), __LINE__, __MODULE__, _addr, _pmbIn, TEXT(#_pmbIn), _fClobberIn );
  296. //////////////////////////////////////////////////////////////////////////////
  297. //++
  298. //
  299. // MACRO
  300. // TraceTerminateProcess
  301. //
  302. // Description:
  303. // Should be called before a process terminates. It cleans up anything
  304. // that the Debug APIs created. It will check to make sure all memory
  305. // allocated by the main thread was released properly. It will also
  306. // terminate WMI tracing (if WMI support is enabled). It also closes
  307. // the logging handle.
  308. //
  309. // Arguments:
  310. // _rgControl - WMI control block (see DEBUG_WMI_CONTROL_GUIDS)
  311. // _sizeofControl - the sizeof( _rgControl )
  312. //
  313. // Return Values:
  314. // None.
  315. //
  316. //--
  317. //////////////////////////////////////////////////////////////////////////////
  318. #define TraceTerminateProcess() \
  319. do \
  320. { \
  321. DebugMemoryCheck( NULL, NULL ); \
  322. DebugTerminateProcess(); \
  323. } while ( 0 )
  324. //****************************************************************************
  325. //
  326. // Debug initialization routines
  327. //
  328. // Uses should use the TraceInitializeXXX and TraceTerminateXXX macros, not
  329. // these routines.
  330. //
  331. //****************************************************************************
  332. void
  333. DebugInitializeTraceFlags( void );
  334. void
  335. DebugInitializeThreadTraceFlags(
  336. LPCTSTR pszThreadNameIn
  337. );
  338. void
  339. DebugTerminateProcess( void );
  340. void
  341. DebugTerminiateThreadTraceFlags( void );
  342. void
  343. DebugCreateMemoryList(
  344. LPCTSTR pszFileIn,
  345. const int nLineIn,
  346. LPCTSTR pszModuleIn,
  347. LPVOID * ppvListOut,
  348. LPCTSTR pszListNameIn
  349. );
  350. void
  351. DebugMemoryListDelete(
  352. LPCTSTR pszFileIn,
  353. const int nLineIn,
  354. LPCTSTR pszModuleIn,
  355. void * pvMemIn,
  356. LPVOID pvListIn,
  357. LPCTSTR pszListNameIn,
  358. BOOL fClobberIn
  359. );
  360. void
  361. DebugMoveToMemoryList(
  362. LPCTSTR pszFileIn,
  363. const int nLineIn,
  364. LPCTSTR pszModuleIn,
  365. void * pvMemIn,
  366. LPVOID pmbListIn,
  367. LPCTSTR pszListNameIn
  368. );
  369. void
  370. DebugMoveFromMemoryList(
  371. LPCTSTR pszFileIn,
  372. const int nLineIn,
  373. LPCTSTR pszModuleIn,
  374. HGLOBAL hGlobal,
  375. LPVOID pmbListIn,
  376. LPCTSTR pszListNameIn
  377. );
  378. //****************************************************************************
  379. //
  380. // Memmory Allocation Subsitution Macros
  381. //
  382. // Replaces LocalAlloc/LocalFree, GlobalAlloc/GlobalFree, and malloc/free
  383. //
  384. //****************************************************************************
  385. #define TraceAlloc( _flags, _size ) DebugAlloc( TEXT(__FILE__), __LINE__, __MODULE__, _flags, _size, TEXT(#_size) )
  386. #define TraceReAlloc( _pvmem, _size, _flags ) DebugReAlloc( TEXT(__FILE__), __LINE__, __MODULE__, _pvmem, _flags, _size, TEXT(#_size) )
  387. #define TraceFree( _hmem ) DebugFree( _hmem, TEXT(__FILE__), __LINE__, __MODULE__ )
  388. //////////////////////////////////////////////////////////////////////////////
  389. //++
  390. //
  391. // MACRO
  392. // TraceAllocString(
  393. // _flags,
  394. // _size
  395. // )
  396. //
  397. // Description:
  398. // Quick way to allocation a string that is the proper size and that will
  399. // be tracked by memory tracking.
  400. //
  401. // Arguments:
  402. // _flags - Allocation attributes.
  403. // _size - Number of characters in the string to be allocated.
  404. //
  405. // Return Values:
  406. // Handle/pointer to memory to be used as a string.
  407. //
  408. //////////////////////////////////////////////////////////////////////////////
  409. #define TraceAllocString( _flags, _size ) \
  410. (LPTSTR) DebugAlloc( TEXT(__FILE__), \
  411. __LINE__, \
  412. __MODULE__, \
  413. _flags, \
  414. (_size) * sizeof( TCHAR ), \
  415. TEXT(#_size) \
  416. )
  417. //****************************************************************************
  418. //
  419. // Code Tracing Macros
  420. //
  421. //****************************************************************************
  422. //////////////////////////////////////////////////////////////////////////////
  423. //++
  424. //
  425. // MACRO
  426. // TraceFunc(
  427. // _szArgs
  428. // )
  429. //
  430. // Description:
  431. // Displays file, line number, module and "_szArgs" only if the mtfFUNC is
  432. // set in g_tfModule. "_szArgs" is the name of the function just
  433. // entered. It also increments the stack counter.
  434. //
  435. // Arguments:
  436. // _szArgs - Arguments for the function just entered.
  437. //
  438. // Return Values:
  439. // None.
  440. //
  441. //--
  442. //////////////////////////////////////////////////////////////////////////////
  443. #define TraceFunc( _szArgs ) \
  444. HRESULT __MissingTraceFunc; \
  445. if ( g_tfModule != 0 ) \
  446. { \
  447. DebugIncrementStackDepthCounter(); \
  448. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )") ); \
  449. }
  450. //
  451. // These next macros are just like TraceFunc except they take additional
  452. // arguments to display the values passed into the function call. "_szArgs"
  453. // should contain a printf string on how to display the arguments.
  454. //
  455. #define TraceFunc1( _szArgs, _arg1 ) \
  456. HRESULT __MissingTraceFunc; \
  457. if ( g_tfModule != 0 ) \
  458. { \
  459. DebugIncrementStackDepthCounter(); \
  460. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1 ); \
  461. }
  462. #define TraceFunc2( _szArgs, _arg1, _arg2 ) \
  463. HRESULT __MissingTraceFunc; \
  464. if ( g_tfModule != 0 ) \
  465. { \
  466. DebugIncrementStackDepthCounter(); \
  467. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2 ); \
  468. }
  469. #define TraceFunc3( _szArgs, _arg1, _arg2, _arg3 ) \
  470. HRESULT __MissingTraceFunc; \
  471. if ( g_tfModule != 0 ) \
  472. { \
  473. DebugIncrementStackDepthCounter(); \
  474. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2, _arg3 ); \
  475. }
  476. #define TraceFunc4( _szArgs, _arg1, _arg2, _arg3, _arg4 ) \
  477. HRESULT __MissingTraceFunc; \
  478. if ( g_tfModule != 0 ) \
  479. { \
  480. DebugIncrementStackDepthCounter(); \
  481. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2, _arg3, _arg4 ); \
  482. }
  483. #define TraceFunc5( _szArgs, _arg1, _arg2, _arg3, _arg4, _arg5 ) \
  484. HRESULT __MissingTraceFunc; \
  485. if ( g_tfModule != 0 ) \
  486. { \
  487. DebugIncrementStackDepthCounter(); \
  488. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2, _arg3, _arg4, arg5 ); \
  489. }
  490. #define TraceFunc6( _szArgs, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) \
  491. HRESULT __MissingTraceFunc; \
  492. if ( g_tfModule != 0 ) \
  493. { \
  494. DebugIncrementStackDepthCounter(); \
  495. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("+ ") TEXT(__FUNCTION__) TEXT("( ") TEXT(_szArgs) TEXT(" )"), _arg1, _arg2, _arg3, _arg4, arg5, arg6 ); \
  496. }
  497. //////////////////////////////////////////////////////////////////////////////
  498. //++
  499. //
  500. // MACRO
  501. // TraceQIFunc(
  502. // _szArgs,
  503. // riid,
  504. // ppv
  505. // )
  506. //
  507. // Description:
  508. // Just like TraceFunc but customized for QueryInterface. Specifically,
  509. // displays the name of the interface and the value of the return pointer.
  510. //
  511. // Arguments:
  512. // _riid - Interface ID.
  513. // _ppv - Return pointer.
  514. //
  515. // Return Values:
  516. // None.
  517. //
  518. //--
  519. //////////////////////////////////////////////////////////////////////////////
  520. #define TraceQIFunc( _riid, _ppv ) \
  521. HRESULT __MissingTraceFunc; \
  522. if ( g_tfModule != 0 ) \
  523. { \
  524. TCHAR szGuid[ cchGUID_STRING_SIZE ]; \
  525. DebugIncrementStackDepthCounter(); \
  526. TraceMessage( TEXT(__FILE__), \
  527. __LINE__, \
  528. __MODULE__, \
  529. mtfFUNC, \
  530. TEXT("+ ") TEXT(__FUNCTION__) TEXT("( [IUnknown] %s, ppv = %#x )"), \
  531. PszTraceFindInterface( _riid, szGuid ), \
  532. _ppv \
  533. ); \
  534. }
  535. //////////////////////////////////////////////////////////////////////////////
  536. //++
  537. //
  538. // MACRO
  539. // TraceFlow(
  540. // _pszFormat
  541. // )
  542. //
  543. // Description:
  544. // This macro outputs a string that is indented to the current depth.
  545. //
  546. //--
  547. //////////////////////////////////////////////////////////////////////////////
  548. #define TraceFlow( _pszFormat ) \
  549. do \
  550. { \
  551. if ( g_tfModule != 0 ) \
  552. { \
  553. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat) ); \
  554. } \
  555. } while ( 0 )
  556. //
  557. // These next macros are just like TraceFunc except they take additional
  558. // arguments to display the values passed into the function call. "_pszFormat"
  559. // should contain a printf string on how to display the arguments.
  560. //
  561. #define TraceFlow1( _pszFormat, _arg1 ) \
  562. do \
  563. { \
  564. if ( g_tfModule != 0 ) \
  565. { \
  566. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1 ); \
  567. } \
  568. } while ( 0 )
  569. #define TraceFlow2( _pszFormat, _arg1, _arg2 ) \
  570. do \
  571. { \
  572. if ( g_tfModule != 0 ) \
  573. { \
  574. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2 ); \
  575. } \
  576. } while ( 0 )
  577. #define TraceFlow3( _pszFormat, _arg1, _arg2, _arg3 ) \
  578. do \
  579. { \
  580. if ( g_tfModule != 0 ) \
  581. { \
  582. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2, _arg3 ); \
  583. } \
  584. } while ( 0 )
  585. #define TraceFlow4( _pszFormat, _arg1, _arg2, _arg3, _arg4 ) \
  586. do \
  587. { \
  588. if ( g_tfModule != 0 ) \
  589. { \
  590. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2, _arg3, _arg4 ); \
  591. } \
  592. } while ( 0 )
  593. #define TraceFlow5( _pszFormat, _arg1, _arg2, _arg3, _arg4, _arg5 ) \
  594. do \
  595. { \
  596. if ( g_tfModule != 0 ) \
  597. { \
  598. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2, _arg3, _arg4, _arg5 ); \
  599. } \
  600. } while ( 0 )
  601. #define TraceFlow6( _pszFormat, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) \
  602. do \
  603. { \
  604. if ( g_tfModule != 0 ) \
  605. { \
  606. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFLOW, TEXT("| ") TEXT(_pszFormat), _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ); \
  607. } \
  608. } while ( 0 )
  609. //////////////////////////////////////////////////////////////////////////////
  610. //++
  611. //
  612. // MACRO
  613. // TraceFuncExit( void )
  614. //
  615. // Description:
  616. // Return macro for TraceFunc() if the return type is void. It also
  617. // decrements the stack counter.
  618. //
  619. // Arguments:
  620. // None.
  621. //
  622. // Return Values:
  623. // None.
  624. //
  625. //--
  626. //////////////////////////////////////////////////////////////////////////////
  627. #define TraceFuncExit() \
  628. do \
  629. { \
  630. if ( g_tfModule != 0 ) \
  631. { \
  632. __MissingTraceFunc = 0; \
  633. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \
  634. DebugDecrementStackDepthCounter(); \
  635. } \
  636. return; \
  637. } while ( 0 )
  638. //////////////////////////////////////////////////////////////////////////////
  639. //++
  640. //
  641. // MACRO
  642. // RETURN(
  643. // _rval
  644. // )
  645. //
  646. // Description:
  647. // Return macro for TraceFunc(). The _rval will be returned as the
  648. // result of the function. It also decrements the stack counter.
  649. //
  650. // Arguments:
  651. // _rval - Result of the function.
  652. //
  653. // Return Values:
  654. // None.
  655. //
  656. //--
  657. //////////////////////////////////////////////////////////////////////////////
  658. #define RETURN( _rval ) \
  659. do \
  660. { \
  661. if ( g_tfModule != 0 ) \
  662. { \
  663. __MissingTraceFunc = 0; \
  664. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \
  665. DebugDecrementStackDepthCounter(); \
  666. } \
  667. return _rval; \
  668. } while ( 0 )
  669. /*
  670. return ( ( g_tfModule != 0 ) \
  671. ? ( TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ) \
  672. , DebugDecrementStackDepthCounter() \
  673. , _rval ) \
  674. : _rval )
  675. */
  676. //////////////////////////////////////////////////////////////////////////////
  677. //++
  678. //
  679. // MACRO
  680. // FRETURN(
  681. // _rval
  682. // )
  683. //
  684. // Description:
  685. // This is a fake version of the return macro for TraceFunc().
  686. // *** This doesn't return. *** It also decrements the stack counter.
  687. //
  688. // Arguments:
  689. // _rval - Result of the function.
  690. //
  691. // Return Values:
  692. // None.
  693. //
  694. //--
  695. //////////////////////////////////////////////////////////////////////////////
  696. #define FRETURN( _rval ) \
  697. do \
  698. { \
  699. if ( g_tfModule != 0 ) \
  700. { \
  701. __MissingTraceFunc = 0; \
  702. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \
  703. DebugDecrementStackDepthCounter(); \
  704. } \
  705. } while ( 0 )
  706. //////////////////////////////////////////////////////////////////////////////
  707. //++
  708. //
  709. // MACRO
  710. // HRETURN(
  711. // _hr
  712. // )
  713. //
  714. // Description:
  715. // Return macro for TraceFunc(). The _hr will be returned as the result
  716. // of the function. If the value is not S_OK, it will be displayed in
  717. // the debugger. It also decrements the stack counter.
  718. //
  719. // Arguments:
  720. // _hr - Result of the function.
  721. //
  722. // Return Values:
  723. // None.
  724. //
  725. //--
  726. //////////////////////////////////////////////////////////////////////////////
  727. #define HRETURN( _hr ) \
  728. do \
  729. { \
  730. if ( g_tfModule != 0 ) \
  731. { \
  732. __MissingTraceFunc = 0; \
  733. if ( _hr != S_OK ) \
  734. { \
  735. DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V hr = 0x%08x (%s)"), _hr ); \
  736. } \
  737. else \
  738. { \
  739. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \
  740. } \
  741. DebugDecrementStackDepthCounter(); \
  742. } \
  743. return _hr; \
  744. } while ( 0 )
  745. //
  746. // These next macros are just like HRETURN except they allow other
  747. // exceptable values to be passed.back without causing extra spew.
  748. //
  749. #define HRETURN1( _hr, _arg1 ) \
  750. do \
  751. { \
  752. if ( g_tfModule != 0 ) \
  753. { \
  754. __MissingTraceFunc = 0; \
  755. if ( ( _hr != S_OK ) && ( _hr != _arg1 ) ) \
  756. { \
  757. DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V hr = 0x%08x (%s)"), _hr ); \
  758. } \
  759. else \
  760. { \
  761. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \
  762. } \
  763. DebugDecrementStackDepthCounter(); \
  764. } \
  765. return _hr; \
  766. } while ( 0 )
  767. #define HRETURN2( _hr, _arg1, _arg2 ) \
  768. do \
  769. { \
  770. if ( g_tfModule != 0 ) \
  771. { \
  772. __MissingTraceFunc = 0; \
  773. if ( ( _hr != S_OK ) && ( _hr != _arg1 ) && ( _hr != _arg2 ) ) \
  774. { \
  775. DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V hr = 0x%08x (%s)"), _hr ); \
  776. } \
  777. else \
  778. { \
  779. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \
  780. } \
  781. DebugDecrementStackDepthCounter(); \
  782. } \
  783. return _hr; \
  784. } while ( 0 )
  785. #define HRETURN3( _hr, _arg1, _arg2, _arg3 ) \
  786. do \
  787. { \
  788. if ( g_tfModule != 0 ) \
  789. { \
  790. __MissingTraceFunc = 0; \
  791. if ( ( _hr != S_OK ) && ( _hr != _arg1 ) && ( _hr != _arg2 ) && ( _hr != _arg3 ) ) \
  792. { \
  793. DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V hr = 0x%08x (%s)"), _hr ); \
  794. } \
  795. else \
  796. { \
  797. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \
  798. } \
  799. DebugDecrementStackDepthCounter(); \
  800. } \
  801. return _hr; \
  802. } while ( 0 )
  803. //////////////////////////////////////////////////////////////////////////////
  804. //++
  805. //
  806. // MACRO
  807. // TraceDo(
  808. // _szExp
  809. // )
  810. //
  811. // Description:
  812. // Displays the file, line number, module and function call and return
  813. // from the function call (no return value displayed) for "_szExp" only
  814. // if the mtfCALLS is set in g_tfModule. Note return value is not
  815. // displayed. _szExp will be in RETAIL version of the product.
  816. //
  817. // Arguments:
  818. // _szExp
  819. // The expression to be traced including assigment to the return
  820. // variable.
  821. //
  822. // Return Values:
  823. // None. The return value should be defined within _szExp.
  824. //
  825. //--
  826. //////////////////////////////////////////////////////////////////////////////
  827. #define TraceDo( _szExp ) \
  828. do \
  829. { \
  830. if ( g_tfModule != 0 ) \
  831. { \
  832. DebugIncrementStackDepthCounter(); \
  833. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_szExp ) ); \
  834. _szExp; \
  835. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("V") ); \
  836. DebugDecrementStackDepthCounter(); \
  837. } \
  838. else \
  839. { \
  840. _szExp; \
  841. } \
  842. } while ( 0 )
  843. //////////////////////////////////////////////////////////////////////////////
  844. //++
  845. //
  846. // MACRO
  847. // TraceMsgDo(
  848. // _pszExp,
  849. // _pszReturnMsg
  850. // )
  851. //
  852. // Description:
  853. // Displays the file, line number, module and function call and return
  854. // value which is formatted in "_pszReturnMsg" for "_pszExp" only if the
  855. // mtfCALLS is set in g_tfModule. _pszExp will be in the RETAIL version
  856. // of the product.
  857. //
  858. // Arguments:
  859. // _pszExp
  860. // The expression to be traced including assigment to the return
  861. // variable.
  862. // _pszReturnMsg
  863. // A format string for displaying the return value.
  864. //
  865. // Return Values:
  866. // None. The return value should be defined within _szExp.
  867. //
  868. // Example:
  869. // TraceMsgDo( hr = HrDoSomething(), "0x%08.8x" );
  870. //
  871. //--
  872. //////////////////////////////////////////////////////////////////////////////
  873. #define TraceMsgDo( _pszExp, _pszReturnMsg ) \
  874. do \
  875. { \
  876. if ( g_tfModule != 0 ) \
  877. { \
  878. DebugIncrementStackDepthCounter(); \
  879. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  880. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp ); \
  881. DebugDecrementStackDepthCounter(); \
  882. } \
  883. else \
  884. { \
  885. _pszExp; \
  886. } \
  887. } while ( 0 )
  888. //
  889. // These next macros are just like TraceMsgDo except they take additional
  890. // arguments to display the values passed into the function call. "_pszMsg"
  891. // should contain a printf format string describing how to display the
  892. // arguments.
  893. //
  894. #define TraceMsgDo1( _pszExp, _pszMsg, _arg1 ) \
  895. do \
  896. { \
  897. if ( g_tfModule != 0 ) \
  898. { \
  899. DebugIncrementStackDepthCounter(); \
  900. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  901. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1 ); \
  902. DebugDecrementStackDepthCounter(); \
  903. } \
  904. else \
  905. { \
  906. _pszExp; \
  907. } \
  908. } while ( 0 )
  909. #define TraceMsgDo2( _pszExp, _pszMsg, _arg1, _arg2 ) \
  910. do \
  911. { \
  912. if ( g_tfModule != 0 ) \
  913. { \
  914. DebugIncrementStackDepthCounter(); \
  915. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  916. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2 ); \
  917. DebugDecrementStackDepthCounter(); \
  918. } \
  919. else \
  920. { \
  921. _pszExp; \
  922. } \
  923. } while ( 0 )
  924. #define TraceMsgDo3( _pszExp, _pszMsg, _arg1, _arg2, _arg3 ) \
  925. do \
  926. { \
  927. if ( g_tfModule != 0 ) \
  928. { \
  929. DebugIncrementStackDepthCounter(); \
  930. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  931. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3 ); \
  932. DebugDecrementStackDepthCounter(); \
  933. } \
  934. else \
  935. { \
  936. _pszExp; \
  937. } \
  938. } while ( 0 )
  939. #define TraceMsgDo4( _pszExp, _pszMsg, _arg1, _arg2, _arg3, _arg4 ) \
  940. do \
  941. { \
  942. if ( g_tfModule != 0 ) \
  943. { \
  944. DebugIncrementStackDepthCounter(); \
  945. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  946. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4 ); \
  947. DebugDecrementStackDepthCounter(); \
  948. } \
  949. else \
  950. { \
  951. _pszExp; \
  952. } \
  953. } while ( 0 )
  954. #define TraceMsgDo5( _pszExp, _pszMsg, _arg1, _arg2, _arg3, _arg4, _arg5 ) \
  955. do \
  956. { \
  957. if ( g_tfModule != 0 ) \
  958. { \
  959. DebugIncrementStackDepthCounter(); \
  960. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  961. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4, _arg5 ); \
  962. DebugDecrementStackDepthCounter(); \
  963. } \
  964. else \
  965. { \
  966. _pszExp; \
  967. } \
  968. } while ( 0 )
  969. #define TraceMsgDo6( _pszExp, _pszMsg, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) \
  970. do \
  971. { \
  972. if ( g_tfModule != 0 ) \
  973. { \
  974. DebugIncrementStackDepthCounter(); \
  975. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  976. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ); \
  977. DebugDecrementStackDepthCounter(); \
  978. } \
  979. else \
  980. { \
  981. _pszExp; \
  982. } \
  983. } while ( 0 )
  984. //////////////////////////////////////////////////////////////////////////////
  985. //++
  986. //
  987. // MACRO
  988. // TraceMsgPreDo(
  989. // _pszExp,
  990. // _pszPreMsg
  991. // _pszReturnMsg,
  992. // )
  993. //
  994. // Description:
  995. // Displays the file, line number, module and function call and return
  996. // value which is formatted in "_pszReturnMsg" for "_pszExp" only if the
  997. // mtfCALLS is set in g_tfModule. _pszExp will be in the RETAIL version
  998. // of the product.
  999. //
  1000. // Same as TraceMsgDo except it displays the formatted message before
  1001. // executing the expression. Arguments for TraceMsgPreDo1, etc. are
  1002. // applied to both _pszPreMsg and _pszReturnMsg. The first substitution
  1003. // string in _pszReturnMsg is for the return value from the function.
  1004. //
  1005. // Arguments:
  1006. // _pszExp
  1007. // The expression to be traced including assigment to the return
  1008. // variable.
  1009. // _pszPreMsg
  1010. // A format string for displaying a message before the expression
  1011. // is evaluated.
  1012. // _pszReturnMsg
  1013. // A format string for displaying the return value.
  1014. //
  1015. // Return Values:
  1016. // None. The return value should be defined within _szExp.
  1017. //
  1018. // Example:
  1019. // TraceMsgPreDo1( hr = HrDoSomething( bstrName ),
  1020. // "Name = '%ls'",
  1021. // "0x%08.8x, Name = '%ls'",
  1022. // bstrName
  1023. // );
  1024. //
  1025. //--
  1026. //////////////////////////////////////////////////////////////////////////////
  1027. #define TraceMsgPreDo( _pszExp, _pszPreMsg, _pszReturnMsg ) \
  1028. do \
  1029. { \
  1030. if ( g_tfModule != 0 ) \
  1031. { \
  1032. DebugIncrementStackDepthCounter(); \
  1033. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  1034. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg) ); \
  1035. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp ); \
  1036. DebugDecrementStackDepthCounter(); \
  1037. } \
  1038. else \
  1039. { \
  1040. _pszExp; \
  1041. } \
  1042. } while ( 0 )
  1043. //
  1044. // These next macros are just like TraceMsgPreDo except they take additional
  1045. // arguments to display the values passed into the function call. "_pszPreMsg"
  1046. // should contain a printf format string describing how to display the
  1047. // arguments.
  1048. //
  1049. #define TraceMsgPreDo1( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1 ) \
  1050. do \
  1051. { \
  1052. if ( g_tfModule != 0 ) \
  1053. { \
  1054. DebugIncrementStackDepthCounter(); \
  1055. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  1056. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1 ); \
  1057. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1 ); \
  1058. DebugDecrementStackDepthCounter(); \
  1059. } \
  1060. else \
  1061. { \
  1062. _pszExp; \
  1063. } \
  1064. } while ( 0 )
  1065. #define TraceMsgPreDo2( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2 ) \
  1066. do \
  1067. { \
  1068. if ( g_tfModule != 0 ) \
  1069. { \
  1070. DebugIncrementStackDepthCounter(); \
  1071. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  1072. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2 ); \
  1073. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2 ); \
  1074. DebugDecrementStackDepthCounter(); \
  1075. } \
  1076. else \
  1077. { \
  1078. _pszExp; \
  1079. } \
  1080. } while ( 0 )
  1081. #define TraceMsgPreDo3( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2, _arg3 ) \
  1082. do \
  1083. { \
  1084. if ( g_tfModule != 0 ) \
  1085. { \
  1086. DebugIncrementStackDepthCounter(); \
  1087. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  1088. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2, _arg3 ); \
  1089. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3 ); \
  1090. DebugDecrementStackDepthCounter(); \
  1091. } \
  1092. else \
  1093. { \
  1094. _pszExp; \
  1095. } \
  1096. } while ( 0 )
  1097. #define TraceMsgPreDo4( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2, _arg3, _arg4 ) \
  1098. do \
  1099. { \
  1100. if ( g_tfModule != 0 ) \
  1101. { \
  1102. DebugIncrementStackDepthCounter(); \
  1103. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  1104. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2, _arg3, _arg4 ); \
  1105. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4 ); \
  1106. DebugDecrementStackDepthCounter(); \
  1107. } \
  1108. else \
  1109. { \
  1110. _pszExp; \
  1111. } \
  1112. } while ( 0 )
  1113. #define TraceMsgPreDo5( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2, _arg3, _arg4, _arg5 ) \
  1114. do \
  1115. { \
  1116. if ( g_tfModule != 0 ) \
  1117. { \
  1118. DebugIncrementStackDepthCounter(); \
  1119. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  1120. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2, _arg3, _arg4, _arg5 ); \
  1121. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4, _arg5 ); \
  1122. DebugDecrementStackDepthCounter(); \
  1123. } \
  1124. else \
  1125. { \
  1126. _pszExp; \
  1127. } \
  1128. } while ( 0 )
  1129. #define TraceMsgPreDo6( _pszExp, _pszPreMsg, _pszReturnMsg, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) \
  1130. do \
  1131. { \
  1132. if ( g_tfModule != 0 ) \
  1133. { \
  1134. DebugIncrementStackDepthCounter(); \
  1135. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("+ ") TEXT(#_pszExp) ); \
  1136. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT("| ") TEXT(_pszPreMsg), _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ); \
  1137. TraceMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, mtfCALLS, TEXT(_pszReturnMsg), TEXT(#_pszExp), _pszExp, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ); \
  1138. DebugDecrementStackDepthCounter(); \
  1139. } \
  1140. else \
  1141. { \
  1142. _pszExp; \
  1143. } \
  1144. } while ( 0 )
  1145. //////////////////////////////////////////////////////////////////////////////
  1146. //++
  1147. //
  1148. // MACRO
  1149. // TraceMsgGUID(
  1150. // _flags,
  1151. // _msg
  1152. // _guid
  1153. // )
  1154. //
  1155. // Description:
  1156. // Dumps a GUID to the debugger only if one of the flags in _flags is
  1157. // set in g_tfModule.
  1158. //
  1159. // Arguments:
  1160. // _flags - Flags to check
  1161. // _msg - msg to print before GUID
  1162. // _guid - GUID to dump
  1163. //
  1164. // Return Values:
  1165. // None.
  1166. //
  1167. //--
  1168. //////////////////////////////////////////////////////////////////////////////
  1169. #define TraceMsgGUID( _flags, _msg, _guid ) \
  1170. do \
  1171. { \
  1172. if ( g_tfModule != 0 ) \
  1173. { \
  1174. TraceMessage( TEXT(__FILE__), \
  1175. __LINE__, \
  1176. __MODULE__, \
  1177. _flags, \
  1178. TEXT("%s {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"), \
  1179. TEXT(_msg), \
  1180. _guid.Data1, _guid.Data2, _guid.Data3, \
  1181. _guid.Data4[ 0 ], _guid.Data4[ 1 ], _guid.Data4[ 2 ], _guid.Data4[ 3 ], \
  1182. _guid.Data4[ 4 ], _guid.Data4[ 5 ], _guid.Data4[ 6 ], _guid.Data4[ 7 ] ); \
  1183. } \
  1184. } while ( 0 )
  1185. //////////////////////////////////////////////////////////////////////////////
  1186. //++
  1187. //
  1188. // MACRO
  1189. // ErrorMsg(
  1190. // _szMsg,
  1191. // _err
  1192. // )
  1193. //
  1194. // Description:
  1195. // Print an error out. Can be used to write errors to a file. Note that
  1196. // it will also print the source filename, line number and module name.
  1197. //
  1198. // Arguments:
  1199. // _szMsg - Format string to be displayed.
  1200. // _err - Error code of the error.
  1201. //
  1202. // Return Values:
  1203. // None.
  1204. //
  1205. //--
  1206. //////////////////////////////////////////////////////////////////////////////
  1207. #define ErrorMsg( _szMsg, _err ) \
  1208. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfALWAYS, TEXT(__FUNCTION__) TEXT(": ") TEXT(_szMsg), _err );
  1209. //////////////////////////////////////////////////////////////////////////////
  1210. //++
  1211. //
  1212. // MACRO
  1213. // WndMsg(
  1214. // _hwnd,
  1215. // _umsg,
  1216. // _wparam,
  1217. // _lparam
  1218. // )
  1219. //
  1220. // Description:
  1221. // Prints out a message to trace windows messages.
  1222. //
  1223. // Arguments:
  1224. // _hwnd - The HWND
  1225. // _umsg - The uMsg
  1226. // _wparam - The WPARAM
  1227. // _lparam _ The LPARAM
  1228. //
  1229. // Return Values:
  1230. // None.
  1231. //
  1232. //--
  1233. //////////////////////////////////////////////////////////////////////////////
  1234. #define WndMsg( _hwnd, _umsg, _wparam, _lparam ) \
  1235. do \
  1236. { \
  1237. if ( g_tfModule & mtfWM ) \
  1238. { \
  1239. DebugMsg( TEXT("%s: WM : hWnd = 0x%08x, uMsg = %u, wParam = 0x%08x (%u), lParam = 0x%08x (%u)"), __MODULE__, _hwnd, _umsg, _wparam, _wparam, _lparam, _lparam ); \
  1240. } \
  1241. } while ( 0 )
  1242. //****************************************************************************
  1243. //
  1244. // Debug Macros
  1245. //
  1246. // These calls are only compiled in DEBUG. They are a NOP in RETAIL
  1247. // (not even compiled in).
  1248. //
  1249. //****************************************************************************
  1250. //
  1251. // Same as TraceDo() but only compiled in DEBUG.
  1252. //
  1253. #define DebugDo( _fn ) \
  1254. do \
  1255. { \
  1256. DebugIncrementStackDepthCounter(); \
  1257. DebugMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT("+ ") TEXT(#_fn ) ); \
  1258. _fn; \
  1259. DebugMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT("V") ); \
  1260. DebugDecrementStackDepthCounter(); \
  1261. } while ( 0 )
  1262. //
  1263. // Same as TraceMsgDo() but only compiled in DEBUG.
  1264. //
  1265. #define DebugMsgDo( _fn, _msg ) \
  1266. do \
  1267. { \
  1268. DebugIncrementStackDepthCounter(); \
  1269. DebugMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT("+ ") TEXT(#_fn) ); \
  1270. DebugMessageDo( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), TEXT(#_fn), _fn ); \
  1271. DebugDecrementStackDepthCounter(); \
  1272. } while ( 0 )
  1273. //****************************************************************************
  1274. //
  1275. // HRESULT testing macros
  1276. //
  1277. // These functions check HRESULT return values and display UI if conditions
  1278. // warrant only in DEBUG.
  1279. //
  1280. //****************************************************************************
  1281. //////////////////////////////////////////////////////////////////////////////
  1282. //++
  1283. //
  1284. // MACRO
  1285. // IsTraceFlagSet(
  1286. // _flag
  1287. // )
  1288. //
  1289. // Description:
  1290. // Checks to see of the flag is set in the global flags or in the per
  1291. // thread flags. If you specify more than one flag and if any of them are
  1292. // set, it will return TRUE.
  1293. //
  1294. // In RETAIL this always return FALSE thereby effectively deleting the
  1295. // block of the if statement. Example:
  1296. //
  1297. // if ( IsTraceFlagSet( mtfPERTHREADTRACE ) )
  1298. // {
  1299. // //
  1300. // // This code only exists in DEBUG.
  1301. // .
  1302. // .
  1303. // .
  1304. // }
  1305. //
  1306. // Arguments:
  1307. // _flags - Flag to check for.
  1308. //
  1309. // Return Values:
  1310. // TRUE - If DEBUG and flag set.
  1311. // FLASE - If RETAIL or flag not set.
  1312. //
  1313. //--
  1314. //////////////////////////////////////////////////////////////////////////////
  1315. #define IsTraceFlagSet( _flag ) ( g_tfModule && IsDebugFlagSet( _flag ) )
  1316. //////////////////////////////////////////////////////////////////////////////
  1317. //++
  1318. //
  1319. // MACRO
  1320. // TBOOL(
  1321. // _bexp
  1322. // )
  1323. //
  1324. // Description:
  1325. // Warning is display if BOOL is anything but TRUE (non-zero). This can be
  1326. // use in an expression. Example:
  1327. //
  1328. // hr = TBOOL( pSomething->IsSomething( arg ) );
  1329. //
  1330. // Arguments:
  1331. // _bexp - Function expression to check.
  1332. //
  1333. // Return Values:
  1334. // Result of the "_bexp" expression.
  1335. //
  1336. //--
  1337. //////////////////////////////////////////////////////////////////////////////
  1338. #define TBOOL( _bexp ) \
  1339. TraceBOOL( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_bexp), _bexp )
  1340. //////////////////////////////////////////////////////////////////////////////
  1341. //++
  1342. //
  1343. // MACRO
  1344. // THR(
  1345. // _hr
  1346. // )
  1347. //
  1348. // Description:
  1349. // Warning is display if HRESULT is anything but S_OK (0). This can be
  1350. // use in an expression. Example:
  1351. //
  1352. // hr = THR( pSomething->DoSomething( arg ) );
  1353. //
  1354. // Arguments:
  1355. // _hr - Function expression to check.
  1356. //
  1357. // Return Values:
  1358. // Result of the "_hr" expression.
  1359. //
  1360. //--
  1361. //////////////////////////////////////////////////////////////////////////////
  1362. #define THR( _hr ) \
  1363. TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, FALSE )
  1364. #define THRE( _hr, _hrIgnore ) \
  1365. TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, FALSE, _hrIgnore )
  1366. //////////////////////////////////////////////////////////////////////////////
  1367. //++
  1368. //
  1369. // MACRO
  1370. // STHR(
  1371. // _hr
  1372. // )
  1373. //
  1374. // Description:
  1375. // Warning is display if FAILED( _hr ) is TRUE. This can be use in an
  1376. // expression. Example:
  1377. //
  1378. // hr = STHR( pSomething->DoSomething( arg ) );
  1379. //
  1380. // Arguments:
  1381. // _hr - Function expression to check.
  1382. //
  1383. // Return Values:
  1384. // Result of the "_hr" expression.
  1385. //
  1386. //--
  1387. //////////////////////////////////////////////////////////////////////////////
  1388. #define STHR( _hr ) \
  1389. TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, TRUE )
  1390. #define STHRE( _hr, _hrIgnore ) \
  1391. TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, TRUE, _hrIgnore )
  1392. //////////////////////////////////////////////////////////////////////////////
  1393. //++
  1394. //
  1395. // MACRO
  1396. // TW32(
  1397. // _fn
  1398. // )
  1399. //
  1400. // Description:
  1401. // Warning is display if result is anything but ERROR_SUCCESS (0). This
  1402. // can be use in an expression. Example:
  1403. //
  1404. // dwErr = TW32( RegOpenKey( HKLM, "foobar", &hkey ) );
  1405. //
  1406. // Arguments:
  1407. // _fn - Function expression to check.
  1408. //
  1409. // Return Values:
  1410. // Result of the "_fn" expression.
  1411. //
  1412. //--
  1413. //////////////////////////////////////////////////////////////////////////////
  1414. #define TW32( _fn ) \
  1415. TraceWin32( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_fn), _fn )
  1416. #define TW32E( _fn, _errIgnore ) \
  1417. TraceWin32( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_fn), _fn, _errIgnore )
  1418. //////////////////////////////////////////////////////////////////////////////
  1419. //++
  1420. //
  1421. // MACRO
  1422. // RRETURN(
  1423. // _fn
  1424. // )
  1425. //
  1426. // Description:
  1427. // Warning is display if return value is anything but ERROR_SUCCESS (0).
  1428. //
  1429. // Argument:
  1430. // _fn - Value to return.
  1431. //
  1432. // Return Values:
  1433. // _fn always.
  1434. //
  1435. //--
  1436. //////////////////////////////////////////////////////////////////////////////
  1437. #define RRETURN( _fn ) \
  1438. do \
  1439. { \
  1440. if ( g_tfModule != 0 ) \
  1441. { \
  1442. __MissingTraceFunc = 0; \
  1443. if ( _fn != ERROR_SUCCESS ) \
  1444. { \
  1445. DebugReturnMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT( "V ") TEXT(#_fn) TEXT(" = 0x%08x (%s)"), _fn ); \
  1446. } \
  1447. else \
  1448. { \
  1449. TraceMessage( TEXT(__FILE__), __LINE__, __MODULE__, mtfFUNC, TEXT("V") ); \
  1450. } \
  1451. DebugDecrementStackDepthCounter(); \
  1452. } \
  1453. return _fn; \
  1454. } while ( 0 )
  1455. //////////////////////////////////////////////////////////////////////////////
  1456. //++
  1457. //
  1458. // MACRO
  1459. // QIRETURN(
  1460. // _hr,
  1461. // _riid
  1462. // )
  1463. //
  1464. // Description:
  1465. // Warning is display if HRESULT is anything but S_OK (0) only if
  1466. // mtfQUERYINTERFACE is set in g_tfModule, otherwise only a debug
  1467. // message will be printed. Note that TraceFunc() must have been called
  1468. // on the call stack counter must be incremented prior to using.
  1469. //
  1470. // QIRETURNx will ignore E_NOINTERFACE errors for the interfaces
  1471. // specified.
  1472. //
  1473. // Arguments:
  1474. // _hr - Result of the query interface call.
  1475. // _riid - The reference ID of the interfaced queried for.
  1476. //
  1477. // Return Values:
  1478. // None - calls RETURN macro.
  1479. //
  1480. //--
  1481. //////////////////////////////////////////////////////////////////////////////
  1482. #define QIRETURN( _hr, _riid ) \
  1483. do \
  1484. { \
  1485. if ( _hr ) \
  1486. { \
  1487. TCHAR szGuid[ 40 ]; \
  1488. TCHAR szSymbolicName[ 64 ]; \
  1489. DWORD cchSymbolicName = 64; \
  1490. DebugFindWinerrorSymbolicName( _hr, szSymbolicName, &cchSymbolicName ); \
  1491. Assert( cchSymbolicName != 64 ); \
  1492. DebugMessage( TEXT(__FILE__), \
  1493. __LINE__, \
  1494. __MODULE__, \
  1495. TEXT("*HRESULT* QueryInterface( %s, ppv ) failed(), hr = 0x%08x (%s)"), \
  1496. PszDebugFindInterface( _riid, szGuid ), \
  1497. _hr, \
  1498. szSymbolicName \
  1499. ); \
  1500. } \
  1501. if ( g_tfModule & mtfQUERYINTERFACE ) \
  1502. { \
  1503. __MissingTraceFunc = 0; \
  1504. TraceHR( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_hr), _hr, FALSE ); \
  1505. } \
  1506. HRETURN( _hr ); \
  1507. } while ( 0 )
  1508. #define QIRETURN1( _hr, _riid, _riidIgnored1 ) \
  1509. do \
  1510. { \
  1511. if ( _hr == E_NOINTERFACE \
  1512. && IsEqualIID( _riid, _riidIgnored1 ) \
  1513. ) \
  1514. { \
  1515. FRETURN( S_OK ); \
  1516. return( _hr ); \
  1517. } \
  1518. QIRETURN( _hr, _riid ); \
  1519. } while ( 0 )
  1520. #define QIRETURN2( _hr, _riid, _riidIgnored1, _riidIgnored2 ) \
  1521. do \
  1522. { \
  1523. if ( _hr == E_NOINTERFACE \
  1524. && ( IsEqualIID( _riid, _riidIgnored1 ) \
  1525. || IsEqualIID( _riid, _riidIgnored2 ) \
  1526. ) \
  1527. ) \
  1528. { \
  1529. FRETURN( S_OK ); \
  1530. return( _hr ); \
  1531. } \
  1532. QIRETURN( _hr, _riid ); \
  1533. } while ( 0 )
  1534. #define QIRETURN3( _hr, _riid, _riidIgnored1, _riidIgnored2, _riidIgnored3 ) \
  1535. do \
  1536. { \
  1537. if ( _hr == E_NOINTERFACE \
  1538. && ( IsEqualIID( _riid, _riidIgnored1 ) \
  1539. || IsEqualIID( _riid, _riidIgnored2 ) \
  1540. || IsEqualIID( _riid, _riidIgnored3 ) \
  1541. ) \
  1542. ) \
  1543. { \
  1544. FRETURN( S_OK ); \
  1545. return( _hr ); \
  1546. } \
  1547. QIRETURN( _hr, _riid ); \
  1548. } while ( 0 )
  1549. #define QIRETURN4( _hr, _riid, _riidIgnored1, _riidIgnored2, _riidIgnored3, _riidIgnored4 ) \
  1550. do \
  1551. { \
  1552. if ( _hr == E_NOINTERFACE \
  1553. && ( IsEqualIID( _riid, _riidIgnored1 ) \
  1554. || IsEqualIID( _riid, _riidIgnored2 ) \
  1555. || IsEqualIID( _riid, _riidIgnored3 ) \
  1556. || IsEqualIID( _riid, _riidIgnored4 ) \
  1557. ) \
  1558. ) \
  1559. { \
  1560. FRETURN( S_OK ); \
  1561. return( _hr ); \
  1562. } \
  1563. QIRETURN( _hr, _riid ); \
  1564. } while ( 0 )
  1565. #define QIRETURN5( _hr, _riid, _riidIgnored1, _riidIgnored2, _riidIgnored3, _riidIgnored4, _riidIgnored5 ) \
  1566. do \
  1567. { \
  1568. if ( _hr == E_NOINTERFACE \
  1569. && ( IsEqualIID( _riid, _riidIgnored1 ) \
  1570. || IsEqualIID( _riid, _riidIgnored2 ) \
  1571. || IsEqualIID( _riid, _riidIgnored3 ) \
  1572. || IsEqualIID( _riid, _riidIgnored4 ) \
  1573. || IsEqualIID( _riid, _riidIgnored5 ) \
  1574. ) \
  1575. ) \
  1576. { \
  1577. FRETURN( S_OK ); \
  1578. return( _hr ); \
  1579. } \
  1580. QIRETURN( _hr, _riid ); \
  1581. } while ( 0 )
  1582. #define QIRETURN6( _hr, _riid, _riidIgnored1, _riidIgnored2, _riidIgnored3, _riidIgnored4, _riidIgnored5, _riidIgnored6 ) \
  1583. do \
  1584. { \
  1585. if ( _hr == E_NOINTERFACE \
  1586. && ( IsEqualIID( _riid, _riidIgnored1 ) \
  1587. || IsEqualIID( _riid, _riidIgnored2 ) \
  1588. || IsEqualIID( _riid, _riidIgnored3 ) \
  1589. || IsEqualIID( _riid, _riidIgnored4 ) \
  1590. || IsEqualIID( _riid, _riidIgnored5 ) \
  1591. || IsEqualIID( _riid, _riidIgnored6 ) \
  1592. ) \
  1593. ) \
  1594. { \
  1595. FRETURN( S_OK ); \
  1596. return( _hr ); \
  1597. } \
  1598. QIRETURN( _hr, _riid ); \
  1599. } while ( 0 )
  1600. //////////////////////////////////////////////////////////////////////////////
  1601. //++
  1602. //
  1603. // MACRO
  1604. // QIRETURN_IGNORESTDMARSHALLING(
  1605. // _hr,
  1606. // _riid
  1607. // )
  1608. //
  1609. // Description:
  1610. // Works like QIRETURN (see QIRETURN above), but ignores E_NOINTERFACE for
  1611. // the standard marshalling interfaces.
  1612. //
  1613. // Arguments:
  1614. // _hr - Result of the query interface call.
  1615. // _riid - The reference ID of the interfaced queried for.
  1616. //
  1617. // Return Values:
  1618. // None - calls QIRETURN5 macro.
  1619. //
  1620. //--
  1621. //////////////////////////////////////////////////////////////////////////////
  1622. #define QIRETURN_IGNORESTDMARSHALLING( _hr, _riid ) \
  1623. do \
  1624. { \
  1625. const GUID _COCLASS_IdentityUnmarshall = { 0x0000001b, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }; \
  1626. QIRETURN5( _hr, _riid, IID_IMarshal, _COCLASS_IdentityUnmarshall, IID_IStdMarshalInfo, IID_IExternalConnection, IID_ICallFactory ); \
  1627. } while ( 0 )
  1628. #define QIRETURN_IGNORESTDMARSHALLING1( _hr, _riid, _riid1 ) \
  1629. do \
  1630. { \
  1631. const GUID _COCLASS_IdentityUnmarshall = { 0x0000001b, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }; \
  1632. QIRETURN6( _hr, _riid, IID_IMarshal, _COCLASS_IdentityUnmarshall, IID_IStdMarshalInfo, IID_IExternalConnection, IID_ICallFactory, _riid1 ); \
  1633. } while ( 0 )
  1634. //////////////////////////////////////////////////////////////////////////////
  1635. //++
  1636. //
  1637. // MACRO
  1638. // BOOLTOSTRING(
  1639. // _fBool
  1640. // )
  1641. //
  1642. // Desfription:
  1643. // If _fBool is true, returns address of "TRUE" else returns address of
  1644. // "FALSE".
  1645. //
  1646. // Argument:
  1647. // _fBool - Expression to evaluate.
  1648. //
  1649. // Return Values:
  1650. // address of "TRUE" if _fBool is true.
  1651. // address of "FALSE" if _fBool is false.
  1652. //
  1653. //--
  1654. //////////////////////////////////////////////////////////////////////////////
  1655. #define BOOLTOSTRING( _fBool ) ( (_fBool) ? g_szTrue : g_szFalse )
  1656. //****************************************************************************
  1657. //
  1658. // Trace/Debug Functions - these do not exist in RETAIL.
  1659. //
  1660. //****************************************************************************
  1661. BOOL
  1662. IsDebugFlagSet(
  1663. TRACEFLAG tfIn
  1664. );
  1665. void
  1666. __cdecl
  1667. TraceMsg(
  1668. TRACEFLAG tfIn,
  1669. LPCSTR pszFormatIn,
  1670. ...
  1671. );
  1672. void
  1673. __cdecl
  1674. TraceMsg(
  1675. TRACEFLAG tfIn,
  1676. LPCWSTR pszFormatIn,
  1677. ...
  1678. );
  1679. void
  1680. __cdecl
  1681. DebugMsg(
  1682. LPCSTR pszFormatIn,
  1683. ...
  1684. );
  1685. void
  1686. __cdecl
  1687. DebugMsg(
  1688. LPCWSTR pszFormatIn,
  1689. ...
  1690. );
  1691. void
  1692. __cdecl
  1693. DebugMsgNoNewline(
  1694. LPCSTR pszFormatIn,
  1695. ...
  1696. );
  1697. void
  1698. __cdecl
  1699. DebugMsgNoNewline(
  1700. LPCWSTR pszFormatIn,
  1701. ...
  1702. );
  1703. void
  1704. __cdecl
  1705. TraceMessage(
  1706. LPCTSTR pszFileIn,
  1707. const int nLineIn,
  1708. LPCTSTR pszModuleIn,
  1709. TRACEFLAG tfIn,
  1710. LPCTSTR pszFormatIn,
  1711. ...
  1712. );
  1713. void
  1714. __cdecl
  1715. TraceMessageDo(
  1716. LPCTSTR pszFileIn,
  1717. const int nLineIn,
  1718. LPCTSTR pszModuleIn,
  1719. TRACEFLAG tfIn,
  1720. LPCTSTR pszFormatIn,
  1721. LPCTSTR pszFuncIn,
  1722. ...
  1723. );
  1724. void
  1725. __cdecl
  1726. DebugMessage(
  1727. LPCTSTR pszFileIn,
  1728. const int nLineIn,
  1729. LPCTSTR pszModuleIn,
  1730. LPCTSTR pszFormatIn,
  1731. ...
  1732. );
  1733. void
  1734. __cdecl
  1735. DebugMessageDo(
  1736. LPCTSTR pszFileIn,
  1737. const int nLineIn,
  1738. LPCTSTR pszModuleIn,
  1739. LPCTSTR pszFormatIn,
  1740. LPCTSTR pszFuncIn,
  1741. ...
  1742. );
  1743. BOOL
  1744. AssertMessage(
  1745. LPCTSTR pszFileIn,
  1746. const int nLineIn,
  1747. LPCTSTR pszModuleIn,
  1748. LPCTSTR pszfnIn,
  1749. BOOL fTrueIn
  1750. );
  1751. BOOL
  1752. TraceBOOL(
  1753. LPCTSTR pszFileIn,
  1754. const int nLineIn,
  1755. LPCTSTR pszModuleIn,
  1756. LPCTSTR pszfnIn,
  1757. BOOL bIn
  1758. );
  1759. HRESULT
  1760. TraceHR(
  1761. LPCTSTR pszFileIn,
  1762. const int nLineIn,
  1763. LPCTSTR pszModuleIn,
  1764. LPCTSTR pszfnIn,
  1765. HRESULT hrIn,
  1766. BOOL fSuccessIn,
  1767. HRESULT hrIgnoreIn = S_OK
  1768. );
  1769. ULONG
  1770. TraceWin32(
  1771. LPCTSTR pszFileIn,
  1772. const int nLineIn,
  1773. LPCTSTR pszModuleIn,
  1774. LPCTSTR pszfnIn,
  1775. ULONG ulErrIn,
  1776. ULONG ulErrIgnoreIn = ERROR_SUCCESS
  1777. );
  1778. void
  1779. __cdecl
  1780. TraceLogMsgNoNewline(
  1781. LPCSTR pszFormatIn,
  1782. ...
  1783. );
  1784. void
  1785. __cdecl
  1786. TraceLogMsgNoNewline(
  1787. LPCWSTR pszFormatIn,
  1788. ...
  1789. );
  1790. #if 0
  1791. //
  1792. // Trying to get the NTSTATUS stuff to play in "user world"
  1793. // is just about impossible. This is here in case it is needed
  1794. // and one could find the right combination of headers to
  1795. // make it work. Inflicting such pain on others is the reason
  1796. // why this function is #ifdef'fed.
  1797. //
  1798. void
  1799. DebugFindNTStatusSymbolicName(
  1800. NTSTATUS dwStatusIn,
  1801. LPTSTR pszNameOut,
  1802. LPDWORD pcchNameInout
  1803. );
  1804. #endif
  1805. void
  1806. DebugFindWinerrorSymbolicName(
  1807. DWORD dwErrIn,
  1808. LPTSTR pszNameOut,
  1809. LPDWORD pcchNameInout
  1810. );
  1811. void
  1812. DebugReturnMessage(
  1813. LPCTSTR pszFileIn,
  1814. const int nLineIn,
  1815. LPCTSTR pszModuleIn,
  1816. LPCTSTR pszMessageIn,
  1817. DWORD dwErrIn
  1818. );
  1819. //****************************************************************************
  1820. //
  1821. // Use the TraceMemoryXXX wrappers, not the DebugMemoryXXX functions.
  1822. // The memory tracking functions do not exist in RETAIL (converted to NOP).
  1823. //
  1824. //****************************************************************************
  1825. typedef enum EMEMORYBLOCKTYPE
  1826. {
  1827. mmbtUNKNOWN = 0, // Never used
  1828. mmbtMEMORYALLOCATION, // GlobalAlloc/LocalAlloc/malloc
  1829. mmbtOBJECT, // Object pointer
  1830. mmbtHANDLE, // Object handle
  1831. mmbtPUNK, // IUnknown pointer
  1832. mmbtSYSALLOCSTRING // SysAllocString
  1833. } EMEMORYBLOCKTYPE;
  1834. #define TraceMemoryAdd( _mbtType, _hGlobalIn, _pszFileIn, _nLineIn, _pszModuleIn, _dwBytesIn, _pszCommentIn ) \
  1835. DebugMemoryAdd( _mbtType, _hGlobalIn, _pszFileIn, _nLineIn, _pszModuleIn, _dwBytesIn, _pszCommentIn )
  1836. #define TraceMemoryAddAddress( _pv ) \
  1837. DebugMemoryAdd( mmbtMEMORYALLOCATION, _pv, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_pv) )
  1838. #define TraceMemoryAddHandle( _handle ) \
  1839. DebugMemoryAdd( mmbtHANDLE, _handle, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_handle) )
  1840. #define TraceMemoryAddObject( _pv ) \
  1841. DebugMemoryAdd( mmbtOBJECT, _pv, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_pv) )
  1842. #define TraceMemoryAddPunk( _punk ) \
  1843. DebugMemoryAdd( mmbtPUNK, _punk, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_punk) )
  1844. #define TraceMemoryAddBSTR( _pv ) \
  1845. DebugMemoryAdd( mmbtSYSALLOCSTRING, _pv, TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT(#_pv) )
  1846. #define TraceMemoryDelete( _hGlobalIn, _fClobberIn ) \
  1847. DebugMemoryDelete( mmbtUNKNOWN, _hGlobalIn, TEXT(__FILE__), __LINE__, __MODULE__, _fClobberIn )
  1848. #define TraceStrDup( _sz ) \
  1849. (LPTSTR) DebugMemoryAdd( mmbtMEMORYALLOCATION, StrDup( _sz ), TEXT(__FILE__), __LINE__, __MODULE__, 0, TEXT("StrDup( ") TEXT(#_sz) TEXT(" )") )
  1850. #if defined( USES_SYSALLOCSTRING )
  1851. #define TraceSysAllocString( _sz ) \
  1852. (BSTR) DebugMemoryAdd( mmbtSYSALLOCSTRING, SysAllocString( _sz ), TEXT(__FILE__), __LINE__, __MODULE__, ( *(&_sz) == NULL ? 0 : wcslen( _sz ) + 1 ), TEXT("SysAllocString( ") TEXT(#_sz) TEXT(")") )
  1853. #define TraceSysAllocStringByteLen( _sz, _len ) \
  1854. (BSTR) DebugMemoryAdd( mmbtSYSALLOCSTRING, SysAllocStringByteLen( _sz, _len ), TEXT(__FILE__), __LINE__, __MODULE__, _len, TEXT("SysAllocStringByteLen( ") TEXT(#_sz) TEXT(")") )
  1855. #define TraceSysAllocStringLen( _sz, _len ) \
  1856. (BSTR) DebugMemoryAdd( mmbtSYSALLOCSTRING, SysAllocStringLen( _sz, _len ), TEXT(__FILE__), __LINE__, __MODULE__, _len + 1, TEXT("SysAllocStringLen( ") TEXT(#_sz) TEXT(")") )
  1857. #define TraceSysReAllocString( _bstrOrg, _bstrNew ) \
  1858. DebugSysReAllocString( TEXT(__FILE__), __LINE__, __MODULE__, _bstrOrg, _bstrNew, TEXT("TraceSysReAllocString(") TEXT(#_bstrOrg) TEXT(", ") TEXT(#_bstrNew) TEXT(" )") )
  1859. #define TraceSysReAllocStringLen( _bstrOrg, _bstrNew, _cch ) \
  1860. DebugSysReAllocStringLen( TEXT(__FILE__), __LINE__, __MODULE__, _bstrOrg, _bstrNew, _cch, TEXT("TraceSysReAllocString(") TEXT(#_bstrOrg) TEXT(", ") TEXT(#_bstrNew) TEXT(", ") TEXT(#_cch) TEXT(" )") )
  1861. #define TraceSysFreeString( _bstr ) \
  1862. DebugMemoryDelete( mmbtSYSALLOCSTRING, _bstr, TEXT(__FILE__), __LINE__, __MODULE__, TRUE ); \
  1863. SysFreeString( _bstr )
  1864. #endif // USES_SYSALLOCSTRING
  1865. //****************************************************************************
  1866. //
  1867. // Memory tracing functions - these are remapped to the GlobalAlloc/GlobalFree
  1868. // heap functions when in RETAIL. Use the TraceMemoryXXX wrappers, not the
  1869. // DebugMemoryXXX functions.
  1870. //
  1871. //****************************************************************************
  1872. void *
  1873. DebugAlloc(
  1874. LPCTSTR pszFileIn,
  1875. const int nLineIn,
  1876. LPCTSTR pszModuleIn,
  1877. UINT uFlagsIn,
  1878. DWORD dwBytesIn,
  1879. LPCTSTR pszCommentIn
  1880. );
  1881. void *
  1882. DebugReAlloc(
  1883. LPCTSTR pszFileIn,
  1884. const int nLineIn,
  1885. LPCTSTR pszModuleIn,
  1886. void * pvMemIn,
  1887. UINT uFlagsIn,
  1888. DWORD dwBytesIn,
  1889. LPCTSTR pszCommentIn
  1890. );
  1891. BOOL
  1892. DebugFree(
  1893. void * pvMemIn,
  1894. LPCTSTR pszFileIn,
  1895. const int nLineIn,
  1896. LPCTSTR pszModuleIn
  1897. );
  1898. void *
  1899. DebugMemoryAdd(
  1900. EMEMORYBLOCKTYPE mbtType,
  1901. void * pvMemIn,
  1902. LPCTSTR pszFileIn,
  1903. const int nLineIn,
  1904. LPCTSTR pszModuleIn,
  1905. DWORD dwBytesIn,
  1906. LPCTSTR pszCommentIn
  1907. );
  1908. void
  1909. DebugMemoryDelete(
  1910. EMEMORYBLOCKTYPE mbtTypeIn,
  1911. void * pvMemIn,
  1912. LPCTSTR pszFileIn,
  1913. const int nLineIn,
  1914. LPCTSTR pszModuleIn,
  1915. BOOL fClobberIn
  1916. );
  1917. #if defined( USES_SYSALLOCSTRING )
  1918. INT
  1919. DebugSysReAllocString(
  1920. LPCTSTR pszFileIn,
  1921. const int nLineIn,
  1922. LPCTSTR pszModuleIn,
  1923. BSTR * pbstrIn,
  1924. const OLECHAR * pszIn,
  1925. LPCTSTR pszCommentIn
  1926. );
  1927. INT
  1928. DebugSysReAllocStringLen(
  1929. LPCTSTR pszFileIn,
  1930. const int nLineIn,
  1931. LPCTSTR pszModuleIn,
  1932. BSTR * pbstrIn,
  1933. const OLECHAR * pszIn,
  1934. unsigned int ucchIn,
  1935. LPCTSTR pszCommentIn
  1936. );
  1937. #endif // USES_SYSALLOCSTRING
  1938. void
  1939. DebugMemoryCheck(
  1940. LPVOID pvListIn,
  1941. LPCTSTR pszListNameIn
  1942. );
  1943. //****************************************************************************
  1944. //
  1945. // operator new() for C++
  1946. //
  1947. //****************************************************************************
  1948. #ifdef __cplusplus
  1949. extern
  1950. void *
  1951. __cdecl
  1952. operator new(
  1953. size_t nSizeIn,
  1954. LPCTSTR pszFileIn,
  1955. const int nLineIn,
  1956. LPCTSTR pszModuleIn
  1957. );
  1958. /*
  1959. //****************************************************************************
  1960. //
  1961. // operator new []() for C++
  1962. //
  1963. //****************************************************************************
  1964. extern
  1965. void *
  1966. __cdecl
  1967. operator new [](
  1968. size_t nSizeIn,
  1969. LPCTSTR pszFileIn,
  1970. const int nLineIn,
  1971. LPCTSTR pszModuleIn
  1972. );
  1973. */
  1974. //****************************************************************************
  1975. //
  1976. // operator delete() for C++
  1977. //
  1978. //****************************************************************************
  1979. extern
  1980. void
  1981. __cdecl
  1982. operator delete(
  1983. void * pMem,
  1984. LPCTSTR pszFileIn,
  1985. const int nLineIn,
  1986. LPCTSTR pszModuleIn
  1987. );
  1988. /*
  1989. //****************************************************************************
  1990. //
  1991. // operator delete []() for C++
  1992. //
  1993. //****************************************************************************
  1994. extern
  1995. void
  1996. __cdecl
  1997. operator delete [](
  1998. void * pMemIn,
  1999. size_t stSizeIn,
  2000. LPCTSTR pszFileIn,
  2001. const int nLineIn,
  2002. LPCTSTR pszModuleIn
  2003. );
  2004. */
  2005. //
  2006. // Remap "new" to our macro so "we" don't have to type anything extra and
  2007. // so it magically dissappears in RETAIL.
  2008. //
  2009. #define new new( TEXT(__FILE__), __LINE__, __MODULE__ )
  2010. #endif
  2011. //****************************************************************************
  2012. //
  2013. //
  2014. #else // it's RETAIL ******************************************************
  2015. //
  2016. //
  2017. //****************************************************************************
  2018. #pragma message("BUILD: RETAIL macros being built")
  2019. //
  2020. // Debugging -> NOPs
  2021. //
  2022. #define DEFINE_MODULE( _module )
  2023. #define __MODULE__ NULL
  2024. #define DEFINE_THISCLASS( _class )
  2025. #define __THISCLASS__ NULL
  2026. //#define DEFINE_SUPER( _super )
  2027. //#define __SUPERCLASS__ NULL
  2028. #define BOOLTOSTRING( _fBool ) NULL
  2029. #define DebugDo( _fn )
  2030. #define DebugMsgDo( _fn, _msg )
  2031. #define TraceMsgGUID( _f, _m, _g )
  2032. #define AssertMessage( _f, _l, _m, _e, _msg ) TRUE
  2033. //
  2034. // TODO: gpease 08-NOV-1999
  2035. // We probably want to do something special for ErrorMsg()
  2036. //
  2037. #define ErrorMsg 1 ? (void)0 : (void)__noop
  2038. #define TraceMsg 1 ? (void)0 : (void)__noop
  2039. #define WndMsg 1 ? (void)0 : (void)__noop
  2040. #define DebugMsg 1 ? (void)0 : (void)__noop
  2041. #define DebugMsgNoNewline 1 ? (void)0 : (void)__noop
  2042. #define TraceMessage 1 ? (void)0 : (void)__noop
  2043. #define DebugMessage 1 ? (void)0 : (void)__noop
  2044. #define TraceHR 1 ? (void)0 : (void)__noop
  2045. #define TraceFunc 1 ? (void)0 : (void)__noop
  2046. #define TraceFunc1 1 ? (void)0 : (void)__noop
  2047. #define TraceFunc2 1 ? (void)0 : (void)__noop
  2048. #define TraceFunc3 1 ? (void)0 : (void)__noop
  2049. #define TraceFunc4 1 ? (void)0 : (void)__noop
  2050. #define TraceFunc5 1 ? (void)0 : (void)__noop
  2051. #define TraceFunc6 1 ? (void)0 : (void)__noop
  2052. #define TraceQIFunc 1 ? (void)0 : (void)__noop
  2053. #define TraceFlow 1 ? (void)0 : (void)__noop
  2054. #define TraceFlow1 1 ? (void)0 : (void)__noop
  2055. #define TraceFlow2 1 ? (void)0 : (void)__noop
  2056. #define TraceFlow3 1 ? (void)0 : (void)__noop
  2057. #define TraceFlow4 1 ? (void)0 : (void)__noop
  2058. #define TraceFlow5 1 ? (void)0 : (void)__noop
  2059. #define TraceFlow6 1 ? (void)0 : (void)__noop
  2060. #define TraceFuncExit() return
  2061. #define TraceInitializeThread( _name )
  2062. #define TraceTerminateThread()
  2063. #define TraceMemoryAdd( _mbtType, _hGlobalIn, _pszFileIn, _nLineIn, _pszModuleIn, _uFlagsIn, _dwBytesIn, _pszCommentIn ) _hGlobalIn
  2064. #define TraceMemoryAddHandle( _handle ) _handle
  2065. #define TraceMemoryAddBSTR( _bstr ) _bstr
  2066. #define TraceMemoryAddAddress( _pv ) _pv
  2067. #define TraceMemoryAddHandle( _obj ) _obj
  2068. #define TraceMemoryAddPunk( _punk ) _punk
  2069. #define TraceMemoryDelete( _h, _b ) _h
  2070. #define TraceMemoryAddObject( _pv ) _pv
  2071. #define IsTraceFlagSet( _flag ) FALSE
  2072. //
  2073. // Tracing -> just do operation
  2074. //
  2075. #define TraceDo( _fn ) _fn
  2076. #define TraceMsgDo( _fn, _msg ) _fn
  2077. #define TraceMsgDo1( _fn, _msg, _arg1 ) _fn
  2078. #define TraceMsgDo2( _fn, _msg, _arg1, _arg2 ) _fn
  2079. #define TraceMsgDo3( _fn, _msg, _arg1, _arg2, _arg3 ) _fn
  2080. #define TraceMsgDo4( _fn, _msg, _arg1, _arg2, _arg3, _arg4 ) _fn
  2081. #define TraceMsgDo5( _fn, _msg, _arg1, _arg2, _arg3, _arg4, _arg5 ) _fn
  2082. #define TraceMsgDo6( _fn, _msg, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) _fn
  2083. #define TraceMsgPreDo( _fn, _msg1, _msg2 ) _fn
  2084. #define TraceMsgPreDo1( _fn, _msg1, _msg2, _arg1 ) _fn
  2085. #define TraceMsgPreDo2( _fn, _msg1, _msg2, _arg1, _arg2 ) _fn
  2086. #define TraceMsgPreDo3( _fn, _msg1, _msg2, _arg1, _arg2, _arg3 ) _fn
  2087. #define TraceMsgPreDo4( _fn, _msg1, _msg2, _arg1, _arg2, _arg3, _arg4 ) _fn
  2088. #define TraceMsgPreDo5( _fn, _msg1, _msg2, _arg1, _arg2, _arg3, _arg4, _arg5 ) _fn
  2089. #define TraceMsgPreDo6( _fn, _msg1, _msg2, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) _fn
  2090. #define TraceAssertIfZero( _fn ) _fn
  2091. //
  2092. // RETURN testing -> do retail
  2093. //
  2094. #define TBOOL
  2095. #define THR
  2096. #define THRE( _hr, _hrIgnore ) _hr
  2097. #define STHR
  2098. #define STHRE( _hr, _hrIgnore ) _hr
  2099. #define TW32
  2100. #define TW32E( _fn, _errIgnore ) _fn
  2101. #define RETURN( _fn ) return _fn
  2102. #define FRETURN( _fn )
  2103. #define RRETURN( _fn ) return _fn
  2104. #define HRETURN( _hr ) return _hr
  2105. #define QIRETURN( _qi, _riid ) return _qi
  2106. #define QIRETURN1( _qi, _riid, _riid1 ) return _qi
  2107. #define QIRETURN2( _qi, _riid, _riid1, _riid2 ) return _qi
  2108. #define QIRETURN3( _qi, _riid, _riid1, _riid2, _riid3 ) return _qi
  2109. #define QIRETURN4( _qi, _riid, _riid1, _riid2, _riid3, _riid4 ) return _qi
  2110. #define QIRETURN5( _qi, _riid, _riid1, _riid2, _riid3, _riid4, _riid5 ) return _qi
  2111. #define QIRETURN6( _qi, _riid, _riid1, _riid2, _riid3, _riid4, _riid5, _riid6 ) return _qi
  2112. #define QIRETURN_IGNORESTDMARSHALLING( _qi, _riid ) return _qi
  2113. #define QIRETURN_IGNORESTDMARSHALLING1( _qi, _riid, _riid1 ) return _qi
  2114. //
  2115. // Memory Functions -> do retail
  2116. //
  2117. #define TraceAlloc( _flags, _size ) HeapAlloc( GetProcessHeap(), _flags, _size )
  2118. #define TraceAllocString( _flags, _size ) (LPTSTR) HeapAlloc( GetProcessHeap(), flags, (_size) * sizeof( TCHAR ) )
  2119. #define TraceReAlloc( _pvMem, _uBytes, _uFlags ) ( ( _pvMem == NULL ) \
  2120. ? HeapAlloc( GetProcessHeap(), _uFlags, _uBytes ) \
  2121. : HeapReAlloc( GetProcessHeap(), _uFlags, _pvMem, _uBytes ) )
  2122. #define TraceFree( _pv ) HeapFree( GetProcessHeap(), 0, _pv )
  2123. #define TraceStrDup( _sz ) StrDup( _sz )
  2124. #define TraceSysAllocString( _sz ) SysAllocString( _sz )
  2125. #define TraceSysAllocStringByteLen( _sz, _len ) SysAllocStringByteLen( _sz, _len )
  2126. #define TraceSysAllocStringLen( _sz, _len ) SysAllocStringLen( _sz, _len )
  2127. #define TraceSysReAllocString( _bstrOrg, _bstrNew ) SysReAllocString( _bstrOrg, _bstrNew )
  2128. #define TraceSysReAllocStringLen( _bstrOrg, _bstrNew, _cch ) SysReAllocStringLen( _bstrOrg, _bstrNew, _cch )
  2129. #define TraceSysFreeString( _bstr ) SysFreeString( _bstr )
  2130. #define TraceCreateMemoryList( _pvIn )
  2131. #define TraceMoveToMemoryList( _addr, _pvIn )
  2132. #define TraceMemoryListDelete( _addr, _pvIn, _fClobber )
  2133. #define TraceTerminateMemoryList( _pvIn )
  2134. #define TraceMoveFromMemoryList( _addr, _pmbIn )
  2135. #endif // DEBUG
  2136. #if DBG==1 || defined( _DEBUG )
  2137. //////////////////////////////////////////////////////////////////////////////
  2138. //
  2139. // MACRO
  2140. // DEBUG_BREAK
  2141. //
  2142. // Description:
  2143. // Because the system expection handler can hick-up over INT 3s and
  2144. // DebugBreak()s, This x86 only macro causes the program to break in the
  2145. // right spot.
  2146. //
  2147. //////////////////////////////////////////////////////////////////////////////
  2148. #if defined( _X86_ )
  2149. #define DEBUG_BREAK do { _try { _asm int 3 } _except (EXCEPTION_EXECUTE_HANDLER) {;} } while (0)
  2150. #else
  2151. #define DEBUG_BREAK DebugBreak()
  2152. #endif
  2153. //////////////////////////////////////////////////////////////////////////////
  2154. //++
  2155. //
  2156. // MACRO
  2157. // Assert(
  2158. // _fn
  2159. // )
  2160. //
  2161. // Description:
  2162. // Checks to see if the Expression is TRUE. If not, a message will be
  2163. // displayed to the user on wether the program should break or continue.
  2164. //
  2165. // Arguments:
  2166. // _fn - Expression being asserted.
  2167. //
  2168. // Return Values:
  2169. // None.
  2170. //
  2171. //--
  2172. //////////////////////////////////////////////////////////////////////////////
  2173. #ifdef Assert
  2174. #undef Assert
  2175. #endif
  2176. #define Assert( _fn ) \
  2177. do \
  2178. { \
  2179. if ( !(_fn) && AssertMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(#_fn), !!(_fn) ) ) \
  2180. DEBUG_BREAK; \
  2181. } while ( 0 )
  2182. //////////////////////////////////////////////////////////////////////////////
  2183. //++
  2184. //
  2185. // MACRO
  2186. // AssertMsg(
  2187. // _fn,
  2188. // _msg
  2189. // )
  2190. //
  2191. // Descrption:
  2192. // Just like an Assert but has an (hopefully) informative message
  2193. // associated with it.
  2194. //
  2195. // Arguments:
  2196. // _fn - Expression to be evaluated.
  2197. // _msg - Message to be display if assertion fails.
  2198. //
  2199. // Return Values:
  2200. // None.
  2201. //
  2202. //--
  2203. //////////////////////////////////////////////////////////////////////////////
  2204. #ifdef AssertMsg
  2205. #undef AssertMsg
  2206. #endif
  2207. #define AssertMsg( _fn, _msg ) \
  2208. do \
  2209. { \
  2210. if ( !(_fn) && AssertMessage( TEXT(__FILE__), __LINE__, __MODULE__, TEXT(_msg), !!(_fn) ) ) \
  2211. DEBUG_BREAK; \
  2212. } while ( 0 )
  2213. //////////////////////////////////////////////////////////////////////////////
  2214. //++
  2215. //
  2216. // MACRO
  2217. // AssertString(
  2218. // _fn,
  2219. // _msg
  2220. // )
  2221. //
  2222. // Descrption:
  2223. // Just like an Assert but has an (hopefully) informative string
  2224. // associated with it.
  2225. //
  2226. // Arguments:
  2227. // _fn - Expression to be evaluated.
  2228. // _msg - String to be display if assertion fails.
  2229. //
  2230. // Return Values:
  2231. // None.
  2232. //
  2233. //--
  2234. //////////////////////////////////////////////////////////////////////////////
  2235. #ifdef AssertString
  2236. #undef AssertString
  2237. #endif
  2238. #define AssertString( _fn, _str ) \
  2239. do \
  2240. { \
  2241. if ( !(_fn) && AssertMessage( TEXT(__FILE__), __LINE__, __MODULE__, _str, !!(_fn) ) ) \
  2242. DEBUG_BREAK; \
  2243. } while ( 0 )
  2244. #else // DBG!=1 && !_DEBUG
  2245. #define DEBUG_BREAK DebugBreak();
  2246. #ifndef Assert
  2247. #define Assert( _e )
  2248. #endif
  2249. #ifndef AssertMsg
  2250. #define AssertMsg( _e, _m )
  2251. #endif
  2252. #ifndef AssertString
  2253. #define AssertString( _e, _m )
  2254. #endif
  2255. #endif // DBG==1 || _DEBUG