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.

437 lines
13 KiB

  1. #pragma once
  2. // this is incompatible with stidebug.h, so don't include stidebug.h
  3. #define _STIDEBUG_H_
  4. #undef ASSERT
  5. #undef REQUIRE
  6. #undef DPRINTF
  7. #undef DPRINTF2
  8. #undef DPRINTF_NOINFO
  9. //
  10. // predefined bits in debug flags
  11. //
  12. // something is really wrong, should not go unnoticed
  13. #define COREDBG_ERRORS 0x00000001
  14. // something that may be of interest to debugging person
  15. #define COREDBG_WARNINGS 0x00000002
  16. // trace random low-priority things with DBG_TRC
  17. #define COREDBG_TRACES 0x00000004
  18. // trace function entries, exits (if so equipped)
  19. // with DBG_FN
  20. #define COREDBG_FNS 0x00000008
  21. // break on errors
  22. #define COREDBG_BREAK_ON_ERRORS 0x80000000
  23. // log to file (default)
  24. #define COREDBG_DONT_LOG_TO_FILE 0x40000000
  25. // log to debugger (default)
  26. #define COREDBG_DONT_LOG_TO_DEBUGGER 0x20000000
  27. // debug log is saved to this file
  28. #define COREDBG_FILE_NAME "%systemroot%\\wiatest.log"
  29. // registry key location
  30. #define COREDBG_FLAGS_REGKEY "System\\CurrentControlSet\\Control\\StillImage\\Debug"
  31. // registry DWORD value name
  32. #define COREDBG_FLAGS_REGVAL "DebugFlags"
  33. // registry DWORD for max log file size
  34. #define COREDBG_REGVAL_FILE_SIZE_LIMIT "DebugFileSizeLimit"
  35. #define COREDBG_FILE_SIZE_LIMIT (512 * 1024) // bytes
  36. #ifdef DEBUG
  37. // by default, log errors only in debug builds
  38. #define COREDBG_DEFAULT_FLAGS COREDBG_ERRORS
  39. #else
  40. // by default log nothing in free builds
  41. #define COREDBG_DEFAULT_FLAGS 0
  42. #endif
  43. /****************************************************************************
  44. HOW TO USE WIA CORE DEBUG (main macros)
  45. ======================================
  46. - DBG_INIT(hInstance)
  47. Call from WinMain or DllMain to enable debug flags on a per module
  48. basis. If you don't call it, all DLLs will inherit the debug flags
  49. of the process that creates them.
  50. - DBG_ERR(("Something happened, hr = 0x%x", hr));
  51. Use when an error condition occurred.
  52. - DBG_WRN(("Warning, something happening, Value=%d", iValue));
  53. Use in a situation warranting a warning.
  54. - DBG_TRC(("Random trace statement, Value=%s", szValue));
  55. Use sparingly to trace certain parts of your code. Minimize spew!!!
  56. - DBG_PRT(("Output without standard File,Line,ThreadID info, Value=%d", iValue));
  57. Same as DBG_TRC, but doesn't output the File,Line,ThreadID line.
  58. ***Use this only if you are doing some special formatting (use sparingly)***
  59. - DBG_FN(FnName)
  60. Tracks entry and exits from a given scope.
  61. - CHECK_NOERR (VarName)
  62. CHECK_NOERR2 (VarName, (YourMsg,...))
  63. Does GetLastError and if not 0, outputs error.
  64. - CHECK_S_OK (hr)
  65. CHECK_S_OK2 (hr, (YourMsg,...))
  66. Checks if hr == S_OK, if not, outputs error.
  67. - CHECK_SUCCESS (lResult)
  68. CHECK_SUCCESS2(lResult, (YourMsg,...))
  69. Checks if lResult == ERROR_SUCCESS, if not, outputs error.
  70. - REQUIRE_NOERR (VarName)
  71. REQUIRE_NOERR2 (VarName, (YourMsg,...))
  72. Same as equivalent CHECK_* macros above, but calls "goto Cleanup" as well
  73. - REQUIRE_S_OK (hr)
  74. REQUIRE_S_OK2 (hr, (YourMsg,...))
  75. Same as equivalent CHECK_* macros above, but calls "goto Cleanup" as well
  76. - REQUIRE_SUCCESS (lResult)
  77. REQUIRE_SUCCESS2(lResult, (YourMsg,...))
  78. Same as equivalent CHECK_* macros above, but calls "goto Cleanup" as well
  79. HOW TO TURN ON WIA CORE DEBUG (3 ways)
  80. ======================================
  81. 1) Set registry HKLM\System\CurrentControlSet\Control\StillImage\Debug\<ModuleName>,
  82. DWORD value "DebugFlags" to an OR'd value of above COREDBG_* flags.
  83. Need to restart app to pick up new settings. Key is auto created the first time
  84. the app is run. (Note: <ModuleName> above is the name
  85. of your DLL or EXE. e.g. wiavusd.dll has a registry key of
  86. "HKLM\System\CurrentControlSet\Control\StillImage\Debug\wiavusd.dll")
  87. OR
  88. 2) In the debugger, set g_dwDebugFlags to OR'd value of COREDBG_* flags above.
  89. You can do this anytime during the debug session.
  90. OR
  91. 3) Call in your code WIA_SET_FLAGS(COREDBG_ERRORS | COREDBG_WARNINGS | COREDBG_TRACES);
  92. or any combo of the COREDBG_* flags.
  93. *****************************************************************************/
  94. #define DBG_INIT(x) DINIT(x)
  95. #define DBG_ERR(x) DPRINTF(COREDBG_ERRORS, x)
  96. #define DBG_WRN(x) DPRINTF(COREDBG_WARNINGS, x)
  97. #define DBG_TRC(x) DPRINTF(COREDBG_TRACES, x)
  98. #define DBG_PRT(x) DPRINTF_NOINFO(COREDBG_TRACES, x)
  99. #define DBG_SET_FLAGS(x) g_dwDebugFlags = (x)
  100. #ifdef __cplusplus
  101. extern "C" {
  102. #endif
  103. //
  104. // accessible to your startup code and at runtime in debugger
  105. // defined in wia\common\stirt\coredbg.cpp
  106. //
  107. extern DWORD g_dwDebugFlags;
  108. extern HANDLE g_hDebugFile;
  109. extern DWORD g_dwDebugFileSizeLimit;
  110. extern BOOL g_bDebugInited;
  111. void CoreDbgTrace(LPCSTR fmt, ...);
  112. void CoreDbgTraceWithTab(LPCSTR fmt, ...);
  113. void CoreDbgInit(HINSTANCE hInstance);
  114. #ifdef DEBUG
  115. #define DINIT(x) CoreDbgInit(x)
  116. #define ASSERT(x) \
  117. if(!(x)) { \
  118. DWORD threadId = GetCurrentThreadId(); \
  119. CoreDbgTrace("WIA: [%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId, #x); \
  120. CoreDbgTraceWithTab("ASSERT FAILED. '%s'", #x); \
  121. DebugBreak(); \
  122. }
  123. #undef VERIFY
  124. #define VERIFY(x) ASSERT(x)
  125. #define REQUIRE(x) ASSERT(x)
  126. #define DPRINTF(flags, x) \
  127. if(!g_bDebugInited) \
  128. { \
  129. CoreDbgInit(NULL); \
  130. } \
  131. if(flags & g_dwDebugFlags) { \
  132. DWORD threadId = GetCurrentThreadId(); \
  133. CoreDbgTrace("WIA: [%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId); \
  134. CoreDbgTraceWithTab x; \
  135. if((flags & COREDBG_ERRORS) && (g_dwDebugFlags & COREDBG_BREAK_ON_ERRORS)) { \
  136. DebugBreak(); \
  137. } \
  138. }
  139. #define DPRINTF2(flags, x, y) \
  140. if(!g_bDebugInited) \
  141. { \
  142. CoreDbgInit(NULL); \
  143. } \
  144. if (flags & g_dwDebugFlags) { \
  145. DWORD threadId = GetCurrentThreadId(); \
  146. CoreDbgTrace("WIA: [%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId); \
  147. CoreDbgTraceWithTab x; \
  148. CoreDbgTraceWithTab y; \
  149. if((flags & COREDBG_ERRORS) && (g_dwDebugFlags & COREDBG_BREAK_ON_ERRORS)) { \
  150. DebugBreak(); \
  151. } \
  152. }
  153. #define DPRINTF_NOINFO(flags, x) \
  154. if(!g_bDebugInited) \
  155. { \
  156. CoreDbgInit(NULL); \
  157. } \
  158. if (flags & g_dwDebugFlags) { \
  159. CoreDbgTraceWithTab x; \
  160. if((flags & COREDBG_ERRORS) && (g_dwDebugFlags & COREDBG_BREAK_ON_ERRORS)) { \
  161. DebugBreak(); \
  162. } \
  163. }
  164. #ifdef __cplusplus
  165. #define DBG_FN(x) CoreDbgFn __CoreDbgFnObject(#x)
  166. #else
  167. #define DBG_FN(x)
  168. #endif
  169. #else // begin NODEBUG
  170. #define DINIT(x)
  171. #define ASSERT(x)
  172. #undef VERIFY
  173. #define VERIFY(x) x
  174. #define REQUIRE(x) x
  175. #define DPRINTF(flags, x) \
  176. if(flags & g_dwDebugFlags) { \
  177. CoreDbgTraceWithTab x; \
  178. }
  179. #define DPRINTF2(flags, x, y) \
  180. if(flags & g_dwDebugFlags) { \
  181. CoreDbgTraceWithTab x; \
  182. CoreDbgTraceWithTab y; \
  183. }
  184. #define DPRINTF_NOINFO(flags, x) \
  185. if(flags & g_dwDebugFlags) { \
  186. CoreDbgTraceWithTab x; \
  187. }
  188. #ifdef __cplusplus
  189. #define DBG_FN(x) CoreDbgFn __CoreDbgFnObject(#x)
  190. #else
  191. #define DBG_FN(x)
  192. #endif
  193. #endif // end NODEBUG
  194. #define COREDBG_MFMT_FLAGS (FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | \
  195. FORMAT_MESSAGE_MAX_WIDTH_MASK)
  196. #define REQUIRE_NOERR(x) \
  197. if(!(x)) { \
  198. DWORD __dwCoreDbgLastError = GetLastError(); \
  199. CHAR szError[80]; \
  200. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __dwCoreDbgLastError, 0, szError, 80, NULL)) \
  201. { \
  202. wsprintfA(szError, "Unknown error"); \
  203. } \
  204. DBG_ERR(("ERROR: %s = %d (0x%08X), '%s'", #x, __dwCoreDbgLastError, __dwCoreDbgLastError, szError)); \
  205. goto Cleanup; \
  206. }
  207. #define REQUIRE_NOERR2(x, y) \
  208. if(!(x)) { \
  209. DWORD __dwCoreDbgLastError = GetLastError(); \
  210. CHAR szError[80]; \
  211. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __dwCoreDbgLastError, 0, szError, 80, NULL)) \
  212. { \
  213. wsprintfA(szError, "Unknown error"); \
  214. } \
  215. DPRINTF2(COREDBG_ERRORS, ("ERROR: %s = %d (0x%08X), '%s'", #x, __dwCoreDbgLastError, __dwCoreDbgLastError, szError), y); \
  216. goto Cleanup; \
  217. }
  218. #define REQUIRE_S_OK(x) { \
  219. HRESULT __hrCoreDbg = S_OK; \
  220. __hrCoreDbg = (x); \
  221. if(__hrCoreDbg != S_OK) { \
  222. CHAR szError[80]; \
  223. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __hrCoreDbg, 0, szError, 80, NULL)) \
  224. { \
  225. wsprintfA(szError, "Unknown hr"); \
  226. } \
  227. DBG_ERR(("ERROR: %s = 0x%08X, '%s'", #x, __hrCoreDbg, szError)); \
  228. goto Cleanup; \
  229. } \
  230. }
  231. #define REQUIRE_S_OK2(x,y) { \
  232. HRESULT __hrCoreDbg = S_OK; \
  233. __hrCoreDbg = (x); \
  234. if(__hrCoreDbg != S_OK) { \
  235. CHAR szError[80]; \
  236. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __hrCoreDbg, 0, szError, 80, NULL)) \
  237. { \
  238. wsprintfA(szError, "Unknown hr"); \
  239. } \
  240. DPRINTF2(COREDBG_ERRORS, ("ERROR: %s = 0x%08X, '%s'", #x, __hrCoreDbg, szError), y); \
  241. goto Cleanup; \
  242. } \
  243. }
  244. #define REQUIRE_SUCCESS(x) { \
  245. UINT __resultCoreDbg = (x); \
  246. if(__resultCoreDbg != ERROR_SUCCESS) { \
  247. CHAR szError[80]; \
  248. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __resultCoreDbg, 0, szError, 80, NULL)) \
  249. { \
  250. wsprintfA(szError, "Unknown error"); \
  251. } \
  252. DBG_ERR(("ERROR: %s = 0x%08X, '%s'", #x, __resultCoreDbg, szError)); \
  253. goto Cleanup; \
  254. } \
  255. }
  256. #define REQUIRE_SUCCESS2(x, y) { \
  257. UINT __resultCoreDbg = (x); \
  258. if(__resultCoreDbg != ERROR_SUCCESS) { \
  259. CHAR szError[80]; \
  260. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __resultCoreDbg, 0, szError, 80, NULL)) \
  261. { \
  262. wsprintfA(szError, "Unknown error"); \
  263. } \
  264. DPRINTF2(COREDBG_ERRORS, ("ERROR: %s = 0x%08X, '%s'", #x, __resultCoreDbg, szError), y); \
  265. goto Cleanup; \
  266. } \
  267. }
  268. #define CHECK_NOERR(x) \
  269. if(!(x)) { \
  270. DWORD __dwCoreDbgLastError = GetLastError(); \
  271. CHAR szError[80]; \
  272. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __dwCoreDbgLastError, 0, szError, 80, NULL)) \
  273. { \
  274. wsprintfA(szError, "Unknown error"); \
  275. } \
  276. DBG_ERR(("ERROR: %s = %d (0x%08X), '%s'", #x, __dwCoreDbgLastError, __dwCoreDbgLastError, szError)); \
  277. }
  278. #define CHECK_NOERR2(x, y) \
  279. if(!(x)) { \
  280. DWORD dwCoreDbgLastError = GetLastError(); \
  281. CHAR szError[80]; \
  282. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __dwCoreDbgLastError, 0, szError, 80, NULL)) \
  283. { \
  284. wsprintfA(szError, "Unknown error", __dwCoreDbgLastError, __dwCoreDbgLastError); \
  285. } \
  286. DPRINTF2(COREDBG_ERRORS, ("ERROR: %s = %d (0x%08X), '%s'", #x, __dwCoreDbgLastError, szError), y); \
  287. }
  288. #define CHECK_S_OK(x) { \
  289. HRESULT __hrCoreDbg = S_OK; \
  290. __hrCoreDbg = (x); \
  291. if(__hrCoreDbg != S_OK) { \
  292. CHAR szError[80]; \
  293. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __hrCoreDbg, 0, szError, 80, NULL)) \
  294. { \
  295. wsprintfA(szError, "Unknown hr"); \
  296. } \
  297. DBG_ERR(("ERROR: %s = 0x%08X, '%s'", #x, __hrCoreDbg, szError)); \
  298. } \
  299. }
  300. #define CHECK_S_OK2(x,y) { \
  301. HRESULT __hrCoreDbg = S_OK; \
  302. __hrCoreDbg = (x); \
  303. if(__hrCoreDbg != S_OK) { \
  304. CHAR szError[80]; \
  305. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __hrCoreDbg, 0, szError, 80, NULL)) \
  306. { \
  307. wsprintfA(szError, "Unknown hr"); \
  308. } \
  309. DPRINTF2(COREDBG_ERRORS, ("ERROR: %s = 0x%08X, '%s'", #x, __hrCoreDbg, szError), y); \
  310. } \
  311. }
  312. #define CHECK_SUCCESS(x) { \
  313. UINT __resultCoreDbg = (x); \
  314. if(__resultCoreDbg != ERROR_SUCCESS) { \
  315. CHAR szError[80]; \
  316. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __resultCoreDbg, 0, szError, 80, NULL)) \
  317. { \
  318. wsprintfA(szError, "Unknown error"); \
  319. } \
  320. DBG_ERR(("ERROR: %s = 0x%08X, '%s'", #x, __resultCoreDbg, szError)); \
  321. } \
  322. }
  323. #define CHECK_SUCCESS2(x, y) { \
  324. UINT __resultCoreDbg = (x); \
  325. if(__resultCoreDbg != ERROR_SUCCESS) { \
  326. CHAR szError[80]; \
  327. if(!FormatMessageA(COREDBG_MFMT_FLAGS, NULL, __resultCoreDbg, 0, szError, 80, NULL)) \
  328. { \
  329. wsprintfA(szError, "Unknown error"); \
  330. } \
  331. DPRINTF2(COREDBG_ERRORS, ("ERROR: %s = 0x%08X, '%s'", #x, __resultCoreDbg, szError), y); \
  332. } \
  333. }
  334. #ifdef __cplusplus
  335. class CoreDbgFn {
  336. private:
  337. LPCSTR m_fn;
  338. DWORD m_threadId;
  339. public:
  340. CoreDbgFn(LPCSTR fn)
  341. {
  342. m_fn = fn;
  343. m_threadId = GetCurrentThreadId();
  344. if(!g_bDebugInited)
  345. {
  346. CoreDbgInit(NULL);
  347. }
  348. if(g_dwDebugFlags & COREDBG_FNS)
  349. {
  350. CoreDbgTraceWithTab("WIA: Thread 0x%X (%d) Entering %s", m_threadId, m_threadId, m_fn);
  351. }
  352. }
  353. ~CoreDbgFn()
  354. {
  355. if(g_dwDebugFlags & COREDBG_FNS)
  356. {
  357. CoreDbgTraceWithTab("WIA: Thread 0x%X (%d) Leaving %s", m_threadId, m_threadId, m_fn);
  358. }
  359. }
  360. };
  361. #endif
  362. #ifdef __cplusplus
  363. }
  364. #endif