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.

670 lines
22 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. wintrace.c
  5. Abstract:
  6. This module contains the code for the wintrace APIs.
  7. Author:
  8. Michael Tsang (MikeTs) 01-May-2000
  9. Environment:
  10. User mode
  11. Revision History:
  12. --*/
  13. #include "pch.h"
  14. int giIndentLevel = 0;
  15. DWORD gdwfTraceTxt = 0;
  16. NAMETABLE WMMsgNames[] =
  17. {
  18. WM_NULL, "Null",
  19. WM_CREATE, "Create",
  20. WM_DESTROY, "Destroy",
  21. WM_MOVE, "Move",
  22. WM_SIZE, "Size",
  23. WM_ACTIVATE, "Activate",
  24. WM_SETFOCUS, "SetFocus",
  25. WM_KILLFOCUS, "KillFocus",
  26. WM_ENABLE, "Enable",
  27. WM_SETREDRAW, "SetRedraw",
  28. WM_SETTEXT, "SetText",
  29. WM_GETTEXT, "GetText",
  30. WM_GETTEXTLENGTH, "GetTextLen",
  31. WM_PAINT, "Paint",
  32. WM_CLOSE, "Close",
  33. WM_QUERYENDSESSION, "QueryEndSession",
  34. WM_QUERYOPEN, "QueryOpen",
  35. WM_ENDSESSION, "EndSession",
  36. WM_QUIT, "Quit",
  37. WM_ERASEBKGND, "EraseBackground",
  38. WM_SYSCOLORCHANGE, "SysColorChange",
  39. WM_SHOWWINDOW, "ShowWindow",
  40. WM_WININICHANGE, "WinIniChange",
  41. WM_SETTINGCHANGE, "SettingChange",
  42. WM_DEVMODECHANGE, "DevModeChange",
  43. WM_ACTIVATEAPP, "ActivateApp",
  44. WM_FONTCHANGE, "FontChange",
  45. WM_TIMECHANGE, "TimeChange",
  46. WM_CANCELMODE, "CancelMode",
  47. WM_SETCURSOR, "SetCursor",
  48. WM_MOUSEACTIVATE, "MouseActivate",
  49. WM_CHILDACTIVATE, "ChildActivate",
  50. WM_QUEUESYNC, "QueueSync",
  51. WM_GETMINMAXINFO, "GetMinMaxInfo",
  52. WM_PAINTICON, "PaintIcon",
  53. WM_ICONERASEBKGND, "IconEraseBackground",
  54. WM_NEXTDLGCTL, "NextDialogControl",
  55. WM_SPOOLERSTATUS, "SpoolerStatus",
  56. WM_DRAWITEM, "DrawItem",
  57. WM_MEASUREITEM, "MeasureItem",
  58. WM_DELETEITEM, "DeleteItem",
  59. WM_VKEYTOITEM, "VKeyToItem",
  60. WM_CHARTOITEM, "CharToItem",
  61. WM_SETFONT, "SetFont",
  62. WM_GETFONT, "GetFont",
  63. WM_SETHOTKEY, "SetHotKey",
  64. WM_GETHOTKEY, "GetHotKey",
  65. WM_QUERYDRAGICON, "QueryDragIcon",
  66. WM_COMPAREITEM, "CompareItem",
  67. WM_GETOBJECT, "GetObject",
  68. WM_COMPACTING, "Compacting",
  69. WM_COMMNOTIFY, "CommNotify",
  70. WM_WINDOWPOSCHANGING, "WindowPosChanging",
  71. WM_WINDOWPOSCHANGED, "WindowPosChanged",
  72. WM_POWER, "Power",
  73. WM_COPYDATA, "CopyData",
  74. WM_CANCELJOURNAL, "CancelJournal",
  75. WM_NOTIFY, "Notify",
  76. WM_INPUTLANGCHANGEREQUEST, "InputLangChangeRequest",
  77. WM_INPUTLANGCHANGE, "InputLangChange",
  78. WM_TCARD, "TCard",
  79. WM_HELP, "Help",
  80. WM_USERCHANGED, "UserChanged",
  81. WM_NOTIFYFORMAT, "NotifyFormat",
  82. WM_CONTEXTMENU, "ContextMenu",
  83. WM_STYLECHANGING, "StyleChanging",
  84. WM_STYLECHANGED, "StyleChanged",
  85. WM_DISPLAYCHANGE, "DisplayChange",
  86. WM_GETICON, "GetIcon",
  87. WM_SETICON, "SetIcon",
  88. WM_NCCREATE, "NCCreate",
  89. WM_NCDESTROY, "NCDestroy",
  90. WM_NCCALCSIZE, "NCCalcSize",
  91. WM_NCHITTEST, "NCHitTest",
  92. WM_NCPAINT, "NCPaint",
  93. WM_NCACTIVATE, "NCActivate",
  94. WM_GETDLGCODE, "GetDialogCode",
  95. WM_SYNCPAINT, "SyncPaint",
  96. WM_NCMOUSEMOVE, "NCMouseMove",
  97. WM_NCLBUTTONDOWN, "NCLeftButtonDown",
  98. WM_NCLBUTTONUP, "NCLeftButtonUp",
  99. WM_NCLBUTTONDBLCLK, "NCLeftButtonDoubleClick",
  100. WM_NCRBUTTONDOWN, "NCRightButtonDown",
  101. WM_NCRBUTTONUP, "NCRightButtonUp",
  102. WM_NCRBUTTONDBLCLK, "NCRightButtonDoubleClick",
  103. WM_NCMBUTTONDOWN, "NCMiddleButtonDown",
  104. WM_NCMBUTTONUP, "NCMiddleButtonUp",
  105. WM_NCMBUTTONDBLCLK, "NCMiddleButtonDoubleClick",
  106. WM_NCXBUTTONDOWN, "NCXButtonDown",
  107. WM_NCXBUTTONUP, "NCXButtonUp",
  108. WM_NCXBUTTONDBLCLK, "NCXButtonDoubleClick",
  109. WM_KEYFIRST, "KeyFirst",
  110. WM_KEYDOWN, "KeyDown",
  111. WM_KEYUP, "KeyUp",
  112. WM_CHAR, "Char",
  113. WM_DEADCHAR, "DeadChar",
  114. WM_SYSKEYDOWN, "SysKeyDown",
  115. WM_SYSKEYUP, "SysKeyUp",
  116. WM_SYSCHAR, "SysChar",
  117. WM_SYSDEADCHAR, "SysDeadChar",
  118. WM_KEYLAST, "KeyLast",
  119. WM_IME_STARTCOMPOSITION, "IMEStartComposition",
  120. WM_IME_ENDCOMPOSITION, "IMEEndComposition",
  121. WM_IME_COMPOSITION, "IMEComposition",
  122. WM_IME_KEYLAST, "IMEKeyLast",
  123. WM_INITDIALOG, "InitDialog",
  124. WM_COMMAND, "Command",
  125. WM_SYSCOMMAND, "SysCommand",
  126. WM_TIMER, "Timer",
  127. WM_HSCROLL, "HScroll",
  128. WM_VSCROLL, "VScroll",
  129. WM_INITMENU, "InitMenu",
  130. WM_INITMENUPOPUP, "InitMenuPopup",
  131. WM_MENUSELECT, "MenuSelect",
  132. WM_MENUCHAR, "MenuChar",
  133. WM_ENTERIDLE, "EnterIdle",
  134. WM_MENURBUTTONUP, "MenuRightButtonUp",
  135. WM_MENUDRAG, "MenuDrag",
  136. WM_MENUGETOBJECT, "MenuGetObject",
  137. WM_UNINITMENUPOPUP, "UninitMenuPopup",
  138. WM_MENUCOMMAND, "MenuCommand",
  139. WM_CHANGEUISTATE, "ChangeUIState",
  140. WM_UPDATEUISTATE, "UpdateUIState",
  141. WM_QUERYUISTATE, "QueryUIState",
  142. WM_CTLCOLORMSGBOX, "CtlColorMsgBox",
  143. WM_CTLCOLOREDIT, "CtlColorEdit",
  144. WM_CTLCOLORLISTBOX, "CtlColorListBox",
  145. WM_CTLCOLORBTN, "CtlColorButton",
  146. WM_CTLCOLORDLG, "CtlColorDialog",
  147. WM_CTLCOLORSCROLLBAR, "CtlColorScrollBar",
  148. WM_CTLCOLORSTATIC, "CtlColorStatic",
  149. WM_MOUSEFIRST, "MouseFirst",
  150. WM_MOUSEMOVE, "MouseMove",
  151. WM_LBUTTONDOWN, "LeftButtonDown",
  152. WM_LBUTTONUP, "LeftButtonUp",
  153. WM_LBUTTONDBLCLK, "LeftButtonDoubleClick",
  154. WM_RBUTTONDOWN, "RightButtonDown",
  155. WM_RBUTTONUP, "RightButtonUp",
  156. WM_RBUTTONDBLCLK, "RightButtonDoubleClick",
  157. WM_MBUTTONDOWN, "MiddleButtonDown",
  158. WM_MBUTTONUP, "MiddleButtonUp",
  159. WM_MBUTTONDBLCLK, "MiddleButtonDoubleClick",
  160. WM_MOUSEWHEEL, "MouseWheel",
  161. WM_XBUTTONDOWN, "XButtonDown",
  162. WM_XBUTTONUP, "XButtonUp",
  163. WM_XBUTTONDBLCLK, "XButtonDoubleClick",
  164. WM_MOUSELAST, "MouseLast",
  165. WM_PARENTNOTIFY, "ParentNotify",
  166. WM_ENTERMENULOOP, "EnterMenuLoop",
  167. WM_EXITMENULOOP, "ExitMenuLoop",
  168. WM_NEXTMENU, "NextMenu",
  169. WM_SIZING, "Sizing",
  170. WM_CAPTURECHANGED, "CaptureChanged",
  171. WM_MOVING, "Moving",
  172. WM_POWERBROADCAST, "PowerBroadcast",
  173. WM_DEVICECHANGE, "DeviceChange",
  174. WM_MDICREATE, "MDICreate",
  175. WM_MDIDESTROY, "MDIDestroy",
  176. WM_MDIACTIVATE, "MDIActivate",
  177. WM_MDIRESTORE, "MDIRestore",
  178. WM_MDINEXT, "MDINext",
  179. WM_MDIMAXIMIZE, "MDIMaximize",
  180. WM_MDITILE, "MDITitle",
  181. WM_MDICASCADE, "MDICascade",
  182. WM_MDIICONARRANGE, "MDIIconArrange",
  183. WM_MDIGETACTIVE, "MDIGetActive",
  184. WM_MDISETMENU, "MDISetMenu",
  185. WM_ENTERSIZEMOVE, "EnterSizeMove",
  186. WM_EXITSIZEMOVE, "ExitSizeMove",
  187. WM_DROPFILES, "DropFiles",
  188. WM_MDIREFRESHMENU, "MDIRefreshMenu",
  189. WM_IME_SETCONTEXT, "IMESetContext",
  190. WM_IME_NOTIFY, "IMENotify",
  191. WM_IME_CONTROL, "IMEControl",
  192. WM_IME_COMPOSITIONFULL, "IMECompositionFull",
  193. WM_IME_SELECT, "IMESelect",
  194. WM_IME_CHAR, "IMEChar",
  195. WM_IME_REQUEST, "IMERequest",
  196. WM_IME_KEYDOWN, "IMEKeyDown",
  197. WM_IME_KEYUP, "IMEKeyUp",
  198. WM_MOUSEHOVER, "MouseHover",
  199. WM_MOUSELEAVE, "MouseLeave",
  200. WM_NCMOUSEHOVER, "NCMouseHover",
  201. WM_NCMOUSELEAVE, "NCMouseLeave",
  202. WM_CUT, "Cut",
  203. WM_COPY, "Copy",
  204. WM_PASTE, "Paste",
  205. WM_CLEAR, "Clear",
  206. WM_UNDO, "Undo",
  207. WM_RENDERFORMAT, "RenderFormat",
  208. WM_RENDERALLFORMATS, "RenderAllFormats",
  209. WM_DESTROYCLIPBOARD, "DestroyClipboard",
  210. WM_DRAWCLIPBOARD, "DrawClipboard",
  211. WM_PAINTCLIPBOARD, "PaintClipboard",
  212. WM_VSCROLLCLIPBOARD, "VScrollClipboard",
  213. WM_SIZECLIPBOARD, "SizeClipboard",
  214. WM_ASKCBFORMATNAME, "AskCBFormatName",
  215. WM_CHANGECBCHAIN, "ChangeCBChain",
  216. WM_HSCROLLCLIPBOARD, "HScrollClipboard",
  217. WM_QUERYNEWPALETTE, "QueryNewPalette",
  218. WM_PALETTEISCHANGING, "PaletteIsChanging",
  219. WM_PALETTECHANGED, "PaletteChanged",
  220. WM_HOTKEY, "HotKey",
  221. WM_PRINT, "Print",
  222. WM_PRINTCLIENT, "PrintClient",
  223. WM_APPCOMMAND, "AppCommand",
  224. WM_HANDHELDFIRST, "HandHeldFirst",
  225. WM_HANDHELDLAST, "HandHeldLast",
  226. WM_AFXFIRST, "AFXFirst",
  227. WM_AFXLAST, "AFXLast",
  228. WM_PENWINFIRST, "PenWinFirst",
  229. WM_PENWINLAST, "PenWinLast",
  230. WM_USER, "User",
  231. WM_APP, "App",
  232. 0x00, NULL
  233. };
  234. /*++
  235. @doc EXTERNAL
  236. @func VOID | TraceInit | Initialize the tracing component.
  237. @parm IN PSZ | pszClientName | Points to the client name string.
  238. @parm IN int | iDefTraceLevel | Specifies default trace level.
  239. @parm IN int | iDefVerboseLevel | Specifies default verbose level.
  240. @rvalue SUCCESS | Returns TRUE.
  241. @rvalue FAILURE | Returns FALSE.
  242. --*/
  243. BOOL EXPORT
  244. TraceInit(
  245. IN PSZ pszClientName,
  246. IN int iDefTraceLevel,
  247. IN int iDefVerboseLevel
  248. )
  249. {
  250. WTTRACEPROC("TraceInit", 1)
  251. BOOL rc = FALSE;
  252. char szMsg[128];
  253. WTENTER(("(ClientName=%s,DefTraceLevel=%d,DefVerboseLevel=%d)\n",
  254. pszClientName, iDefTraceLevel, iDefVerboseLevel));
  255. if (ghClientThread == (HANDLE)-1)
  256. {
  257. gdwfWinTrace = 0;
  258. gdwfTraceTxt = 0;
  259. giIndentLevel = 0;
  260. memset(&gClientInfo, 0, sizeof(gClientInfo));
  261. memset(gszClientName, 0, sizeof(gszClientName));
  262. lstrcpynA(gszClientName, pszClientName, sizeof(gszClientName));
  263. gClientInfo.Settings.iTraceLevel = iDefTraceLevel;
  264. gClientInfo.Settings.iVerboseLevel = iDefVerboseLevel;
  265. ghTraceMutex = CreateMutex(NULL, FALSE, NULL);
  266. if (ghTraceMutex == NULL)
  267. {
  268. WTERRPRINT(("Failed to create trace mutex (err=%d).\n",
  269. GetLastError()));
  270. }
  271. else
  272. {
  273. ghClientThread = (HANDLE)_beginthread(ClientThread,
  274. 0,
  275. pszClientName);
  276. if (ghClientThread != (HANDLE)-1)
  277. {
  278. rc = TRUE;
  279. }
  280. else
  281. {
  282. CloseHandle(ghTraceMutex);
  283. ghTraceMutex = 0;
  284. WTERRPRINT(("Failed to create client thread.\n"));
  285. }
  286. }
  287. }
  288. else
  289. {
  290. WTERRPRINT(("Client is already initialized\n"));
  291. }
  292. WTEXIT(("=%x\n", rc));
  293. return rc;
  294. } //TraceInit
  295. /*++
  296. @doc EXTERNAL
  297. @func VOID | TraceTerminate | Terminating trace, clean up.
  298. @parm VOID | None.
  299. @rvalue None
  300. --*/
  301. VOID EXPORT
  302. TraceTerminate(
  303. VOID
  304. )
  305. {
  306. WTTRACEPROC("TraceTerminate", 1)
  307. WTENTER(("()\n"));
  308. if (ghClientThread != (HANDLE)-1)
  309. {
  310. DWORD rc;
  311. gdwfWinTrace |= WTF_TERMINATING;
  312. if (ghClient != 0)
  313. {
  314. RPC_TRY("WTDeregisterClient",
  315. WTDeregisterClient(ghTracerBinding, ghClient));
  316. ghClient = 0;
  317. }
  318. rc = WaitForSingleObject(ghClientThread, INFINITE);
  319. WTASSERT(rc == WAIT_OBJECT_0);
  320. gdwfWinTrace = 0;
  321. gdwfTraceTxt = 0;
  322. giIndentLevel = 0;
  323. }
  324. if (ghTraceMutex != NULL)
  325. {
  326. CloseHandle(ghTraceMutex);
  327. ghTraceMutex = 0;
  328. }
  329. WTEXIT(("!\n"));
  330. return;
  331. } //TraceTerminate
  332. /*++
  333. @doc EXTERNAL
  334. @func BOOL | IsTraceProcOn |
  335. Determine if the given procedure should be traced.
  336. @parm IN PSZ | pszProcName | Points to procedure name string.
  337. @parm IN int | iProcLevel | Specifies the procedure trace level.
  338. @parm IN BOOL | fEnter | TRUE if called from ENTERPROC.
  339. @rvalue SUCCESS | Returns TRUE.
  340. @rvalue FAILURE | Returns FALSE.
  341. --*/
  342. BOOL EXPORT
  343. IsTraceProcOn(
  344. IN PSZ pszProcName,
  345. IN int iProcLevel,
  346. IN BOOL fEnter
  347. )
  348. {
  349. WTTRACEPROC("IsTraceProcOn", 2)
  350. BOOL rc = FALSE;
  351. DWORD rcWait;
  352. static int icTriggers = 0;
  353. WTENTER(("(ProcName=%s,ProcLevel=%d,fEnter=%x)\n",
  354. pszProcName, iProcLevel, fEnter));
  355. if (giIndentLevel < 0)
  356. {
  357. giIndentLevel = 0;
  358. }
  359. gdwfTraceTxt &= ~TRACETXT_BREAK;
  360. if (ghTraceMutex != 0)
  361. {
  362. rcWait = WaitForSingleObject(ghTraceMutex, TIMEOUT_TRACEMUTEX);
  363. if (rcWait == WAIT_OBJECT_0)
  364. {
  365. if (!(gdwfWinTrace & WTF_TRACE_INPROGRESS))
  366. {
  367. PTRIGPT TrigPt;
  368. if ((gClientInfo.Settings.dwfSettings &
  369. SETTINGS_TRIGMODE_ENABLED) &&
  370. ((TrigPt = FindTrigPt(pszProcName)) != NULL))
  371. {
  372. if (TrigPt->dwfTrigPt & TRIGPT_TRACE_ENABLED)
  373. {
  374. if (fEnter)
  375. {
  376. icTriggers++;
  377. }
  378. else
  379. {
  380. icTriggers--;
  381. }
  382. rc = TRUE;
  383. }
  384. if (TrigPt->dwfTrigPt & TRIGPT_BREAK_ENABLED)
  385. {
  386. gdwfTraceTxt |= TRACETXT_BREAK;
  387. }
  388. }
  389. else if ((iProcLevel <= gClientInfo.Settings.iTraceLevel) &&
  390. (!(gClientInfo.Settings.dwfSettings &
  391. SETTINGS_TRIGMODE_ENABLED) || (icTriggers > 0)))
  392. {
  393. rc = TRUE;
  394. }
  395. if (rc == TRUE)
  396. {
  397. gpszProcName = pszProcName;
  398. gdwfWinTrace |= WTF_TRACE_INPROGRESS;
  399. }
  400. }
  401. if (rc == FALSE)
  402. {
  403. ReleaseMutex(ghTraceMutex);
  404. }
  405. }
  406. else
  407. {
  408. WTERRPRINT(("Failed to wait for trace mutex (rc=%x).\n", rcWait));
  409. }
  410. }
  411. WTEXIT(("=%x\n", rc));
  412. return rc;
  413. } //IsTraceProcOn
  414. /*++
  415. @doc EXTERNAL
  416. @func VOID | TraceProc | Trace procedure.
  417. @parm IN PSZ | pszFormat | Points to format string.
  418. @parm ... | Substituting arguments for the format string.
  419. @rvalue None.
  420. --*/
  421. VOID EXPORT
  422. TraceProc(
  423. IN PSZ pszFormat,
  424. ...
  425. )
  426. {
  427. WTTRACEPROC("TraceProc", 2)
  428. BOOL fToDebugger;
  429. char szTraceTxt[MAX_TRACETXT_LEN];
  430. va_list arglist;
  431. WTENTER(("(Format=%s,...)\n", pszFormat));
  432. if (!(gdwfWinTrace & WTF_CLIENT_READY) ||
  433. (gClientInfo.Settings.dwfSettings & SETTINGS_TRACE_TO_DEBUGGER))
  434. {
  435. int i;
  436. fToDebugger = TRUE;
  437. wsprintfA(szTraceTxt, "[%08x]%s: ",
  438. GetCurrentThreadId(), gszClientName);
  439. for (i = 0; i < giIndentLevel; ++i)
  440. {
  441. lstrcatA(szTraceTxt, "| ");
  442. }
  443. }
  444. else
  445. {
  446. fToDebugger = FALSE;
  447. szTraceTxt[0] = '\0';
  448. }
  449. lstrcatA(szTraceTxt, gpszProcName);
  450. va_start(arglist, pszFormat);
  451. wvsprintfA(&szTraceTxt[lstrlenA(szTraceTxt)], pszFormat, arglist);
  452. va_end(arglist);
  453. if (fToDebugger)
  454. {
  455. OutputDebugStringA(szTraceTxt);
  456. }
  457. else
  458. {
  459. RPC_TRY("WTTraceProc",
  460. WTTraceProc(ghTracerBinding,
  461. ghClient,
  462. GetCurrentThreadId(),
  463. giIndentLevel,
  464. szTraceTxt));
  465. }
  466. gdwfWinTrace &= ~WTF_TRACE_INPROGRESS;
  467. ReleaseMutex(ghTraceMutex);
  468. WTEXIT(("!\n"));
  469. return;
  470. } //TraceProc
  471. /*++
  472. @doc EXTERNAL
  473. @func BOOL | IsTraceMsgOn | Determine if the message should be printed.
  474. @parm IN PSZ | pszProcName | Points to procedure name string.
  475. @parm IN int | iVerboseLevel | Specifies the verbose level of the message.
  476. @rvalue SUCCESS | Returns TRUE.
  477. @rvalue FAILURE | Returns FALSE.
  478. --*/
  479. BOOL EXPORT
  480. IsTraceMsgOn(
  481. IN PSZ pszProcName,
  482. IN int iVerboseLevel
  483. )
  484. {
  485. WTTRACEPROC("IsTraceMsgOn", 2)
  486. BOOL rc = FALSE;
  487. DWORD rcWait;
  488. WTENTER(("(ProcName=%s,VerboseLevel=%d)\n", pszProcName, iVerboseLevel));
  489. gdwfTraceTxt &= ~TRACETXT_MSGTYPE_MASK;
  490. if (ghTraceMutex != 0)
  491. {
  492. rcWait = WaitForSingleObject(ghTraceMutex, TIMEOUT_TRACEMUTEX);
  493. if (rcWait == WAIT_OBJECT_0)
  494. {
  495. if (iVerboseLevel <= gClientInfo.Settings.iVerboseLevel)
  496. {
  497. gpszProcName = pszProcName;
  498. rc = TRUE;
  499. }
  500. if (rc == FALSE)
  501. {
  502. ReleaseMutex(ghTraceMutex);
  503. }
  504. }
  505. else
  506. {
  507. WTERRPRINT(("Failed to wait for trace mutex (rc=%x).\n", rcWait));
  508. }
  509. }
  510. WTEXIT(("=%x\n", rc));
  511. return rc;
  512. } //IsTraceMsgOn
  513. /*++
  514. @doc EXTERNAL
  515. @func VOID | TraceMsg | Print a message.
  516. @parm IN PSZ | pszFormat | Points to format string.
  517. @parm ... | Substituting arguments for the format string.
  518. @rvalue None.
  519. --*/
  520. VOID EXPORT
  521. TraceMsg(
  522. IN PSZ pszFormat,
  523. ...
  524. )
  525. {
  526. WTTRACEPROC("TraceMsg", 2)
  527. DWORD MsgType = gdwfTraceTxt & TRACETXT_MSGTYPE_MASK;
  528. char szTraceTxt[MAX_TRACETXT_LEN];
  529. va_list arglist;
  530. WTENTER(("(Format=%s,...)\n", pszFormat));
  531. wsprintfA(szTraceTxt, "[%08x]%s.%s%s: ",
  532. GetCurrentThreadId(),
  533. gszClientName, gpszProcName,
  534. (MsgType == TRACETXT_MSGTYPE_ERROR)? "_ERR":
  535. (MsgType == TRACETXT_MSGTYPE_WARN)? "_WARN":
  536. (MsgType == TRACETXT_MSGTYPE_INFO)? "_INFO": "");
  537. va_start(arglist, pszFormat);
  538. wvsprintfA(&szTraceTxt[lstrlenA(szTraceTxt)], pszFormat, arglist);
  539. va_end(arglist);
  540. if (!(gdwfWinTrace & WTF_CLIENT_READY) ||
  541. (gClientInfo.Settings.dwfSettings & SETTINGS_TRACE_TO_DEBUGGER))
  542. {
  543. OutputDebugStringA(szTraceTxt);
  544. }
  545. else
  546. {
  547. RPC_TRY("WTTraceMsg",
  548. WTTraceMsg(ghTracerBinding, ghClient, szTraceTxt));
  549. }
  550. ReleaseMutex(ghTraceMutex);
  551. WTEXIT(("!\n"));
  552. return;
  553. } //TraceMsg
  554. /*++
  555. @doc EXTERNAL
  556. @func PSZ | LookupName |
  557. Look up name string of a code in the given name table.
  558. @parm IN ULONG | Code | The given code to lookup.
  559. @parm IN PNAMETABLE | NameTable | The name table to look into.
  560. @rvalue SUCCESS - Returns pointer to the minor function name string.
  561. @rvalue FAILURE - Returns "unknown".
  562. --*/
  563. PSZ EXPORT
  564. LookupName(
  565. IN ULONG Code,
  566. IN PNAMETABLE NameTable
  567. )
  568. {
  569. PSZ pszName = NULL;
  570. static char szUnknown[64];
  571. while (NameTable->pszName != NULL)
  572. {
  573. if (Code == NameTable->Code)
  574. {
  575. pszName = NameTable->pszName;
  576. break;
  577. }
  578. NameTable++;
  579. }
  580. if (pszName == NULL)
  581. {
  582. wsprintfA(szUnknown, "unknown [0x%x (%d)]", Code, Code);
  583. pszName = szUnknown;
  584. }
  585. return pszName;
  586. } //LookupName