Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

581 lines
15 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 2002
  6. //
  7. // File: debug.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. /*----------------------------------------------------------------------------
  11. / Title;
  12. / debug.cpp
  13. /
  14. / Authors;
  15. / David De Vorchik (daviddv)
  16. /
  17. / Notes;
  18. / Provides printf style debug output
  19. /----------------------------------------------------------------------------*/
  20. #include "precomp.hxx"
  21. #include "stdio.h"
  22. #include "simstr.h"
  23. #pragma hdrstop
  24. #ifdef DEBUG
  25. /*-----------------------------------------------------------------------------
  26. / Locals & helper functions
  27. /----------------------------------------------------------------------------*/
  28. #define GETDEPTH(x) (x)=reinterpret_cast<UINT_PTR>(TlsGetValue (g_dwMargin));
  29. #define SETDEPTH(x) TlsSetValue (g_dwMargin, reinterpret_cast<LPVOID>((x)));
  30. DWORD g_dwMargin=0;
  31. DWORD g_dwTraceMask = 0;
  32. #define MAX_CALL_DEPTH 64
  33. #define BUFFER_SIZE 4096
  34. /*-----------------------------------------------------------------------------
  35. / _indent
  36. / -------
  37. / Output to the debug stream indented by n columns.
  38. /
  39. / In:
  40. / i = column to indent to.
  41. / pString -> string to be indented
  42. /
  43. / Out:
  44. / -
  45. /----------------------------------------------------------------------------*/
  46. void _indent(UINT_PTR i, const CSimpleString& String)
  47. {
  48. CSimpleString strIndentBuffer;
  49. strIndentBuffer.Format(TEXT("%08x "), GetCurrentThreadId());
  50. for ( ; i > 0 ; i-- )
  51. {
  52. strIndentBuffer.Concat(TEXT(" "));
  53. }
  54. strIndentBuffer.Concat(String);
  55. strIndentBuffer.Concat(TEXT("\n"));
  56. OutputDebugString(strIndentBuffer.String());
  57. }
  58. /*-----------------------------------------------------------------------------
  59. / DoTraceSetMask
  60. / --------------
  61. / Adjust the trace mask to reflect the state given.
  62. /
  63. / In:
  64. / dwMask = mask for enabling / disable trace output
  65. /
  66. / Out:
  67. / -
  68. /----------------------------------------------------------------------------*/
  69. void DoTraceSetMask(DWORD dwMask)
  70. {
  71. g_dwTraceMask = dwMask;
  72. }
  73. /*-----------------------------------------------------------------------------
  74. / DoTraceEnter
  75. / ------------
  76. / Display the name of the function we are in.
  77. /
  78. / In:
  79. / pName -> function name to be displayed in subsequent trace output.
  80. /
  81. / Out:
  82. / -
  83. /----------------------------------------------------------------------------*/
  84. void DoTraceEnter(DWORD dwMask, LPCTSTR pName)
  85. {
  86. UINT_PTR uDepth=0;
  87. CSimpleString str;
  88. GETDEPTH(uDepth);
  89. uDepth++;
  90. SETDEPTH(uDepth);
  91. if ( !pName )
  92. pName = TEXT("<no name>"); // no function name given
  93. str.Format(TEXT("ENTER: %s"), pName);
  94. _indent (uDepth, str);
  95. }
  96. /*-----------------------------------------------------------------------------
  97. / DoTraceLeave
  98. / ------------
  99. / On exit from a function, decrement the margin
  100. /
  101. / In:
  102. / -
  103. / Out:
  104. / -
  105. /----------------------------------------------------------------------------*/
  106. void DoTraceLeave(void)
  107. {
  108. UINT_PTR uDepth;
  109. GETDEPTH (uDepth);
  110. uDepth--;
  111. SETDEPTH(uDepth);
  112. }
  113. /*-----------------------------------------------------------------------------
  114. / DoTrace
  115. / -------
  116. / Perform printf formatting to the debugging stream. We indent the output
  117. / and stream the function name as required to give some indication of
  118. / call stack depth.
  119. /
  120. / In:
  121. / pFormat -> printf style formatting string
  122. / ... = arguments as required for the formatting
  123. /
  124. / Out:
  125. / -
  126. /----------------------------------------------------------------------------*/
  127. void DoTrace(LPCTSTR pFormat, ...)
  128. {
  129. va_list va;
  130. TCHAR szTraceBuffer[BUFFER_SIZE] = {0};
  131. UINT_PTR uDepth;
  132. GETDEPTH(uDepth);
  133. if ( uDepth < MAX_CALL_DEPTH )
  134. {
  135. va_start(va, pFormat);
  136. wvnsprintf(szTraceBuffer, ARRAYSIZE(szTraceBuffer)-1, pFormat, va);
  137. va_end(va);
  138. _indent(uDepth+1, CSimpleString(szTraceBuffer));
  139. }
  140. }
  141. /*-----------------------------------------------------------------------------
  142. / DoTraceGuid
  143. / -----------
  144. / Given a GUID output it into the debug string, first we try and map it
  145. / to a name (ie. IShellFolder), if that didn't work then we convert it
  146. / to its human readable form.
  147. /
  148. / In:
  149. / pszPrefix -> prefix string
  150. / lpGuid -> guid to be streamed
  151. /
  152. / Out:
  153. / -
  154. /----------------------------------------------------------------------------*/
  155. #ifdef UNICODE
  156. #define MAP_GUID(x) &x, TEXT(""L#x)
  157. #else
  158. #define MAP_GUID(x) &x, TEXT(""#x)
  159. #endif
  160. #define MAP_GUID2(x,y) MAP_GUID(x), MAP_GUID(y)
  161. const struct
  162. {
  163. const GUID* m_pGUID;
  164. LPCTSTR m_pName;
  165. }
  166. _guid_map[] =
  167. {
  168. MAP_GUID(IID_IUnknown),
  169. MAP_GUID(IID_IClassFactory),
  170. MAP_GUID(IID_IDropTarget),
  171. MAP_GUID(IID_IDataObject),
  172. MAP_GUID(IID_IPersist),
  173. MAP_GUID(IID_IPersistStream),
  174. MAP_GUID(IID_IPersistFolder),
  175. MAP_GUID(IID_IPersistFolder2),
  176. MAP_GUID(IID_IPersistFile),
  177. MAP_GUID(IID_IOleWindow),
  178. MAP_GUID2(IID_INewShortcutHookA, IID_INewShortcutHookW),
  179. MAP_GUID(IID_IShellBrowser),
  180. MAP_GUID(IID_IShellView),
  181. MAP_GUID(IID_IContextMenu),
  182. MAP_GUID(IID_IShellIcon),
  183. MAP_GUID(IID_IShellFolder),
  184. MAP_GUID(IID_IShellExtInit),
  185. MAP_GUID(IID_IShellPropSheetExt),
  186. MAP_GUID2(IID_IExtractIconA, IID_IExtractIconW),
  187. MAP_GUID2(IID_IShellLinkA, IID_IShellLinkW),
  188. MAP_GUID2(IID_IShellCopyHookA, IID_IShellCopyHookW),
  189. MAP_GUID2(IID_IFileViewerA, IID_IFileViewerW),
  190. MAP_GUID(IID_ICommDlgBrowser),
  191. MAP_GUID(IID_IEnumIDList),
  192. MAP_GUID(IID_IFileViewerSite),
  193. MAP_GUID(IID_IContextMenu2),
  194. MAP_GUID2(IID_IShellExecuteHookA, IID_IShellExecuteHookW),
  195. MAP_GUID(IID_IPropSheetPage),
  196. MAP_GUID(IID_IShellView2),
  197. MAP_GUID(IID_IUniformResourceLocator),
  198. MAP_GUID(IID_IShellDetails),
  199. MAP_GUID(IID_IShellExtInit),
  200. MAP_GUID(IID_IShellPropSheetExt),
  201. MAP_GUID(IID_IShellIconOverlay),
  202. MAP_GUID(IID_IExtractImage),
  203. MAP_GUID(IID_IExtractImage2),
  204. MAP_GUID(IID_IQueryInfo),
  205. MAP_GUID(IID_IShellDetails3),
  206. MAP_GUID(IID_IShellView2),
  207. MAP_GUID(IID_IShellFolder2),
  208. MAP_GUID(IID_IShellIconOverlay),
  209. MAP_GUID(IID_IMoniker),
  210. MAP_GUID(IID_IStream),
  211. MAP_GUID(IID_ISequentialStream),
  212. MAP_GUID(IID_IPersistFreeThreadedObject),
  213. };
  214. void DoTraceGUID(LPCTSTR pPrefix, REFGUID rGUID)
  215. {
  216. TCHAR szGUID[GUIDSTR_MAX];
  217. CSimpleString strBuffer;
  218. LPCTSTR pName = NULL;
  219. size_t i;
  220. UINT_PTR uDepth;
  221. GETDEPTH(uDepth);
  222. if ( uDepth < MAX_CALL_DEPTH )
  223. {
  224. for ( i = 0 ; i < ARRAYSIZE(_guid_map); i++ )
  225. {
  226. if ( IsEqualGUID(rGUID, *_guid_map[i].m_pGUID) )
  227. {
  228. pName = _guid_map[i].m_pName;
  229. break;
  230. }
  231. }
  232. if ( !pName )
  233. {
  234. SHStringFromGUID(rGUID, szGUID, ARRAYSIZE(szGUID));
  235. pName = szGUID;
  236. }
  237. strBuffer.Format(TEXT("%s %s"), pPrefix, pName);
  238. _indent(uDepth+1, strBuffer);
  239. }
  240. }
  241. /*-----------------------------------------------------------------------------
  242. / DoTraceViewMsg
  243. / --------------
  244. / Given a view msg (SFVM_ && DVM_), print out the corresponding text...
  245. /
  246. / In:
  247. / uMsg -> msg to be streamed
  248. / wParam -> wParam value for message
  249. / lParam -> lParam value for message
  250. /
  251. / Out:
  252. / -
  253. /----------------------------------------------------------------------------*/
  254. #ifdef UNICODE
  255. #define MAP_MSG(x) x, TEXT(""L#x)
  256. #else
  257. #define MAP_MSG(x) x, TEXT(""#x)
  258. #endif
  259. const struct
  260. {
  261. UINT m_uMsg;
  262. LPCTSTR m_pName;
  263. }
  264. _view_msg_map[] =
  265. {
  266. MAP_MSG(SFVM_MERGEMENU),
  267. MAP_MSG(SFVM_INVOKECOMMAND),
  268. MAP_MSG(SFVM_GETHELPTEXT),
  269. MAP_MSG(SFVM_GETTOOLTIPTEXT),
  270. MAP_MSG(SFVM_GETBUTTONINFO),
  271. MAP_MSG(SFVM_GETBUTTONS),
  272. MAP_MSG(SFVM_INITMENUPOPUP),
  273. MAP_MSG(SFVM_SELCHANGE),
  274. MAP_MSG(SFVM_DRAWITEM),
  275. MAP_MSG(SFVM_MEASUREITEM),
  276. MAP_MSG(SFVM_EXITMENULOOP),
  277. MAP_MSG(SFVM_PRERELEASE),
  278. MAP_MSG(SFVM_GETCCHMAX),
  279. MAP_MSG(SFVM_FSNOTIFY),
  280. MAP_MSG(SFVM_WINDOWCREATED),
  281. MAP_MSG(SFVM_WINDOWDESTROY),
  282. MAP_MSG(SFVM_REFRESH),
  283. MAP_MSG(SFVM_SETFOCUS),
  284. MAP_MSG(SFVM_QUERYCOPYHOOK),
  285. MAP_MSG(SFVM_NOTIFYCOPYHOOK),
  286. MAP_MSG(SFVM_GETDETAILSOF),
  287. MAP_MSG(SFVM_COLUMNCLICK),
  288. MAP_MSG(SFVM_QUERYFSNOTIFY),
  289. MAP_MSG(SFVM_DEFITEMCOUNT),
  290. MAP_MSG(SFVM_DEFVIEWMODE),
  291. MAP_MSG(SFVM_UNMERGEMENU),
  292. MAP_MSG(SFVM_INSERTITEM),
  293. MAP_MSG(SFVM_DELETEITEM),
  294. MAP_MSG(SFVM_UPDATESTATUSBAR),
  295. MAP_MSG(SFVM_BACKGROUNDENUM),
  296. MAP_MSG(SFVM_GETWORKINGDIR),
  297. MAP_MSG(SFVM_GETCOLSAVESTREAM),
  298. MAP_MSG(SFVM_SELECTALL),
  299. MAP_MSG(SFVM_DIDDRAGDROP),
  300. MAP_MSG(SFVM_SUPPORTSIDENTITY),
  301. MAP_MSG(SFVM_FOLDERISPARENT),
  302. MAP_MSG(SFVM_SETISFV),
  303. MAP_MSG(SFVM_GETVIEWS),
  304. MAP_MSG(SFVM_THISIDLIST),
  305. MAP_MSG(SFVM_GETITEMIDLIST),
  306. MAP_MSG(SFVM_SETITEMIDLIST),
  307. MAP_MSG(SFVM_INDEXOFITEMIDLIST),
  308. MAP_MSG(SFVM_ODFINDITEM),
  309. MAP_MSG(SFVM_HWNDMAIN),
  310. MAP_MSG(SFVM_ADDPROPERTYPAGES),
  311. MAP_MSG(SFVM_BACKGROUNDENUMDONE),
  312. MAP_MSG(SFVM_GETNOTIFY),
  313. MAP_MSG(SFVM_ARRANGE),
  314. MAP_MSG(SFVM_QUERYSTANDARDVIEWS),
  315. MAP_MSG(SFVM_QUERYREUSEEXTVIEW),
  316. MAP_MSG(SFVM_GETSORTDEFAULTS),
  317. MAP_MSG(SFVM_GETEMPTYTEXT),
  318. MAP_MSG(SFVM_GETITEMICONINDEX),
  319. MAP_MSG(SFVM_DONTCUSTOMIZE),
  320. MAP_MSG(SFVM_SIZE),
  321. MAP_MSG(SFVM_GETZONE),
  322. MAP_MSG(SFVM_GETPANE),
  323. MAP_MSG(SFVM_ISOWNERDATA),
  324. MAP_MSG(SFVM_GETODRANGEOBJECT),
  325. MAP_MSG(SFVM_ODCACHEHINT),
  326. MAP_MSG(SFVM_GETHELPTOPIC),
  327. MAP_MSG(SFVM_OVERRIDEITEMCOUNT),
  328. MAP_MSG(SFVM_GETHELPTEXTW),
  329. MAP_MSG(SFVM_GETTOOLTIPTEXTW),
  330. MAP_MSG(SFVM_GETIPERSISTHISTORY),
  331. MAP_MSG(SFVM_GETANIMATION),
  332. };
  333. const struct
  334. {
  335. UINT m_uMsg;
  336. LPCTSTR m_pName;
  337. }
  338. _shcn_msg_map[] =
  339. {
  340. MAP_MSG(SHCNE_RENAMEITEM),
  341. MAP_MSG(SHCNE_CREATE),
  342. MAP_MSG(SHCNE_DELETE),
  343. MAP_MSG(SHCNE_MKDIR),
  344. MAP_MSG(SHCNE_RMDIR),
  345. MAP_MSG(SHCNE_MEDIAINSERTED),
  346. MAP_MSG(SHCNE_MEDIAREMOVED),
  347. MAP_MSG(SHCNE_DRIVEREMOVED),
  348. MAP_MSG(SHCNE_DRIVEADD),
  349. MAP_MSG(SHCNE_NETSHARE),
  350. MAP_MSG(SHCNE_NETUNSHARE),
  351. MAP_MSG(SHCNE_ATTRIBUTES),
  352. MAP_MSG(SHCNE_UPDATEDIR),
  353. MAP_MSG(SHCNE_UPDATEITEM),
  354. MAP_MSG(SHCNE_SERVERDISCONNECT),
  355. MAP_MSG(SHCNE_UPDATEIMAGE),
  356. MAP_MSG(SHCNE_DRIVEADDGUI),
  357. MAP_MSG(SHCNE_RENAMEFOLDER),
  358. MAP_MSG(SHCNE_FREESPACE),
  359. };
  360. void DoTraceViewMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
  361. {
  362. LPCTSTR pName = NULL;
  363. CSimpleString strBuffer;
  364. CSimpleString strTmp;
  365. size_t i;
  366. UINT_PTR uDepth;
  367. GETDEPTH(uDepth);
  368. if ( uDepth < MAX_CALL_DEPTH )
  369. {
  370. for ( i = 0 ; i < ARRAYSIZE(_view_msg_map); i++ )
  371. {
  372. if ( _view_msg_map[i].m_uMsg == uMsg )
  373. {
  374. pName = _view_msg_map[i].m_pName;
  375. break;
  376. }
  377. }
  378. if (!pName)
  379. {
  380. strTmp.Format(TEXT("SFVM_(%d)"), uMsg );
  381. pName = strTmp.String();
  382. }
  383. if (uMsg == SFVM_FSNOTIFY)
  384. {
  385. LPCTSTR pEvent = NULL;
  386. for (i= 0; i < ARRAYSIZE(_shcn_msg_map); i++)
  387. {
  388. if ( _shcn_msg_map[i].m_uMsg == uMsg )
  389. {
  390. pEvent = _shcn_msg_map[i].m_pName;
  391. break;
  392. }
  393. }
  394. if (!pEvent)
  395. {
  396. pEvent = TEXT("Unknown");
  397. }
  398. strBuffer.Format(TEXT("%s w(%08X) l(%08X == %s)"), pName, wParam, lParam, pEvent);
  399. _indent(uDepth+1, strBuffer);
  400. }
  401. else
  402. {
  403. strBuffer.Format(TEXT("%s w(%08X) l(%08X)"), pName, wParam, lParam);
  404. _indent(uDepth+1, strBuffer);
  405. }
  406. }
  407. }
  408. const struct
  409. {
  410. UINT m_uMsg;
  411. LPCTSTR m_pName;
  412. }
  413. _menu_msg_map[] =
  414. {
  415. MAP_MSG(DFM_MERGECONTEXTMENU),
  416. MAP_MSG(DFM_INVOKECOMMAND),
  417. MAP_MSG(DFM_ADDREF),
  418. MAP_MSG(DFM_RELEASE),
  419. MAP_MSG(DFM_GETHELPTEXT),
  420. MAP_MSG(DFM_WM_MEASUREITEM),
  421. MAP_MSG(DFM_WM_DRAWITEM),
  422. MAP_MSG(DFM_WM_INITMENUPOPUP),
  423. MAP_MSG(DFM_VALIDATECMD),
  424. MAP_MSG(DFM_MERGECONTEXTMENU_TOP),
  425. MAP_MSG(DFM_GETHELPTEXTW),
  426. MAP_MSG(DFM_INVOKECOMMANDEX),
  427. MAP_MSG(DFM_MAPCOMMANDNAME),
  428. MAP_MSG(DFM_GETDEFSTATICID),
  429. MAP_MSG(DFM_GETVERBW),
  430. };
  431. const struct
  432. {
  433. WPARAM m_uMsg;
  434. LPCTSTR m_pName;
  435. }
  436. _menu_invk_cmd_msg_map[] =
  437. {
  438. MAP_MSG(DFM_CMD_RENAME),
  439. MAP_MSG(DFM_CMD_MODALPROP),
  440. MAP_MSG(DFM_CMD_PASTESPECIAL),
  441. MAP_MSG(DFM_CMD_PASTELINK),
  442. MAP_MSG(DFM_CMD_VIEWDETAILS),
  443. MAP_MSG(DFM_CMD_VIEWLIST),
  444. MAP_MSG(DFM_CMD_PASTE),
  445. MAP_MSG(DFM_CMD_NEWFOLDER),
  446. MAP_MSG(DFM_CMD_PROPERTIES),
  447. MAP_MSG(DFM_CMD_LINK),
  448. MAP_MSG(DFM_CMD_COPY),
  449. MAP_MSG(DFM_CMD_MOVE),
  450. MAP_MSG(DFM_CMD_DELETE),
  451. };
  452. void DoTraceMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
  453. {
  454. LPCTSTR pName = NULL;
  455. CSimpleString strBuffer;
  456. CSimpleString strTmp;
  457. size_t i;
  458. UINT_PTR uDepth;
  459. GETDEPTH (uDepth);
  460. if ( uDepth < MAX_CALL_DEPTH )
  461. {
  462. for ( i = 0 ; i < ARRAYSIZE(_menu_msg_map); i++ )
  463. {
  464. if ( _menu_msg_map[i].m_uMsg == uMsg )
  465. {
  466. pName = _menu_msg_map[i].m_pName;
  467. break;
  468. }
  469. }
  470. if (!pName)
  471. {
  472. strTmp.Format(TEXT("DFM_(%d)"), uMsg );
  473. pName = strTmp.String();
  474. }
  475. if ((uMsg == DFM_INVOKECOMMAND) && (wParam >= DFM_CMD_RENAME))
  476. {
  477. strBuffer.Format(TEXT("%s w(%s) l(%08X)"), pName, _menu_invk_cmd_msg_map[wParam-DFM_CMD_RENAME].m_pName, lParam);
  478. }
  479. else
  480. {
  481. strBuffer.Format(TEXT("%s w(%08X) l(%08X)"), pName, wParam, lParam);
  482. }
  483. _indent(uDepth+1, strBuffer);
  484. }
  485. }
  486. /*-----------------------------------------------------------------------------
  487. / DoTraceAssert
  488. / -------------
  489. / Our assert handler, out faults it the trace mask as enabled assert
  490. / faulting.
  491. /
  492. / In:
  493. / iLine = line
  494. / pFilename -> filename of the file we asserted in
  495. /
  496. / Out:
  497. / -
  498. /----------------------------------------------------------------------------*/
  499. void DoTraceAssert(int iLine, LPCTSTR pFilename)
  500. {
  501. CSimpleString strBuffer;
  502. UINT_PTR uDepth;
  503. GETDEPTH(uDepth);
  504. strBuffer.Format(TEXT("Assert failed in %s, line %d"), pFilename, iLine);
  505. _indent(uDepth+1, strBuffer);
  506. if ( g_dwTraceMask & TRACE_COMMON_ASSERT )
  507. DebugBreak();
  508. }
  509. #endif