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.

650 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: oleprint.cxx
  7. //
  8. // Contents: printf for API/Method trace
  9. //
  10. // Functions: oleprintf
  11. //
  12. // History: 11-Jul-95 t-stevan Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <windows.h>
  16. #include <stdarg.h>
  17. #include <ole2sp.h>
  18. #include <ole2com.h>
  19. #if DBG==1
  20. #include "outfuncs.h"
  21. #include "oleprint.hxx"
  22. // *** Constants ***
  23. const char *pscTabString = " "; // 3 space tabs
  24. // *** Types and Enums ***
  25. // Enumeration of basic types
  26. enum
  27. {
  28. TYP_INT = 0,
  29. TYP_UNSIGNED,
  30. TYP_HEX,
  31. TYP_HEXCAPS,
  32. TYP_LARGE,
  33. TYP_BOOL,
  34. TYP_BOOLCAPS,
  35. TYP_POINTER,
  36. TYP_POINTERCAPS,
  37. TYP_HANDLE,
  38. TYP_HANDLECAPS,
  39. TYP_STR,
  40. TYP_WIDESTR,
  41. TYP_GUID,
  42. TYP_STRUCT,
  43. NO_TYPE
  44. };
  45. // Type of parameter printing functions
  46. typedef void (*ParamFunc) (CTextBufferA &buf, va_list &param, char *&ppstr);
  47. // Enumeration of Structure types
  48. enum
  49. {
  50. STRUCT_BIND_OPTS=0,
  51. STRUCT_DVTARGETDEVICE,
  52. STRUCT_FORMATETC,
  53. STRUCT_FILETIME,
  54. STRUCT_INTERFACEINFO,
  55. STRUCT_LOGPALETTE,
  56. STRUCT_MSG,
  57. STRUCT_OLEINPLACEFRAMEINFO,
  58. STRUCT_OLEMENUGROUPWIDTHS,
  59. STRUCT_POINT,
  60. STRUCT_RECT,
  61. STRUCT_STGMEDIUM,
  62. STRUCT_STATSTG,
  63. STRUCT_SIZE,
  64. NO_STRUCT
  65. };
  66. // Type of structure printing functions
  67. typedef void (*WriteFunc) (CTextBufferA &buf, void *pParam);
  68. // *** Prototypes ***
  69. // Functions to handle writing out parameters
  70. static void WriteInt(CTextBufferA &buf, va_list &, char *&);
  71. static void WriteUnsigned(CTextBufferA &buf, va_list &, char *&);
  72. static void WriteHex(CTextBufferA &buf, va_list &, char *&);
  73. static void WriteHexCaps(CTextBufferA &buf, va_list &, char *&);
  74. static void WriteLarge(CTextBufferA &buf, va_list &, char *&);
  75. static void WriteBool(CTextBufferA &buf, va_list &, char *&);
  76. static void WriteBoolCaps(CTextBufferA &buf, va_list &, char *&);
  77. static void WritePointer(CTextBufferA &buf, va_list &, char *&);
  78. static void WritePointerCaps(CTextBufferA &buf, va_list &, char *&);
  79. static void WriteString(CTextBufferA &buf, va_list &, char *&);
  80. static void WriteWideString(CTextBufferA &buf, va_list &, char *&);
  81. static void WriteGUID(CTextBufferA &buf, va_list &, char *&);
  82. static void WriteStruct(CTextBufferA &buf, va_list &, char *&);
  83. // *** Global Data ***
  84. char gPidString[20];
  85. // this table holds the functions for writing base types
  86. static ParamFunc g_pFuncs[] = {WriteInt, WriteUnsigned, WriteHex,
  87. WriteHexCaps, WriteLarge, WriteBool,
  88. WriteBoolCaps,WritePointer,WritePointerCaps,
  89. WriteHex,WriteHexCaps,WriteString,
  90. WriteWideString, WriteGUID, WriteStruct,
  91. NULL};
  92. // this table starts at 'A' == 65
  93. // This is the base type lookup table -> tells what kind of base type to print out
  94. static const BYTE g_tcLookup[] = {NO_TYPE, TYP_BOOLCAPS, NO_TYPE, TYP_INT, NO_TYPE, // 'A' - 'E'
  95. NO_TYPE, NO_TYPE, NO_TYPE, TYP_GUID, NO_TYPE, // 'F' - 'J'
  96. NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, // 'K' - 'O'
  97. TYP_POINTERCAPS, NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, // 'P' - 'T'
  98. TYP_UNSIGNED, NO_TYPE, NO_TYPE, TYP_HEXCAPS, NO_TYPE, // 'U' - 'Y'
  99. NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, NO_TYPE, // 'Z' - '^'
  100. NO_TYPE, NO_TYPE, NO_TYPE, TYP_BOOL, NO_TYPE, // '_' - 'c'
  101. TYP_INT, NO_TYPE, NO_TYPE, NO_TYPE, TYP_HANDLE, // 'd' - 'h'
  102. NO_TYPE, NO_TYPE, NO_TYPE, TYP_LARGE, NO_TYPE, // 'i' - 'm'
  103. NO_TYPE, NO_TYPE, TYP_POINTER, NO_TYPE, NO_TYPE, // 'n' - 'r'
  104. TYP_STR, TYP_STRUCT, TYP_UNSIGNED, NO_TYPE, TYP_WIDESTR, // 's' - 'w'
  105. TYP_HEX, NO_TYPE, NO_TYPE}; // 'x' - 'z'
  106. // This holds the functions for writing out structures
  107. static WriteFunc g_pStructFuncs[] = {(WriteFunc) WriteBIND_OPTS, (WriteFunc) WriteDVTARGETDEVICE,
  108. (WriteFunc) WriteFORMATETC, (WriteFunc) WriteFILETIME,
  109. (WriteFunc) WriteINTERFACEINFO, (WriteFunc) WriteLOGPALETTE,
  110. (WriteFunc) WriteMSG, (WriteFunc) WriteOLEINPLACEFRAMEINFO,
  111. (WriteFunc) WriteOLEMENUGROUPWIDTHS, (WriteFunc) WritePOINT,
  112. (WriteFunc) WriteRECT, (WriteFunc) WriteSTGMEDIUM, (WriteFunc) WriteSTATSTG,
  113. (WriteFunc) WriteSIZE, NULL };
  114. // this table starts at 'a' == 97
  115. // this table holds what type of structure to print out
  116. static const BYTE g_structLookup[] = {NO_STRUCT, STRUCT_BIND_OPTS, NO_STRUCT, STRUCT_DVTARGETDEVICE, // 'a' - 'd'
  117. STRUCT_FORMATETC, STRUCT_FILETIME, NO_STRUCT, NO_STRUCT, // 'e' - 'h'
  118. STRUCT_INTERFACEINFO, NO_STRUCT, NO_STRUCT, STRUCT_LOGPALETTE, // 'i' - 'l'
  119. STRUCT_MSG, NO_STRUCT, STRUCT_OLEINPLACEFRAMEINFO, STRUCT_POINT,// 'm' - 'p'
  120. NO_STRUCT, STRUCT_RECT, STRUCT_STGMEDIUM, STRUCT_STATSTG , // 'q' - 't'
  121. NO_STRUCT, NO_STRUCT, STRUCT_OLEMENUGROUPWIDTHS, NO_STRUCT, // 'u' - 'x'
  122. NO_STRUCT, STRUCT_SIZE }; // 'y' - 'z'
  123. //+---------------------------------------------------------------------------
  124. //
  125. // Function: oleprintf
  126. //
  127. // Synopsis: Prints out trace information using a given function, given a
  128. // nesting depth (for indenting), an API/Method name, a format string,
  129. // and a variable number of arguments
  130. //
  131. // Arguments: [depth] - nesting/indentation level
  132. // [pscApiName] - name of API/Method traced
  133. // [pscFormat] - format string
  134. // [argptr] - variable argument list
  135. //
  136. // Returns: nothing
  137. //
  138. // History: 11-Jul-95 t-stevan Created
  139. //
  140. //----------------------------------------------------------------------------
  141. void __cdecl oleprintf(int depth, const char *pscApiName, const char *pscFormat, va_list argptr)
  142. {
  143. // buffer all output so that multithreaded traces look right
  144. CTextBufferA buf;
  145. char temp[20];
  146. char *pscPos;
  147. // first print out the process id
  148. buf << gPidString;
  149. buf << '.';
  150. // now print out the thread id
  151. _itoa(GetCurrentThreadId(), temp, 10);
  152. buf << temp;
  153. buf << "> ";
  154. // tab to nesting/indent depth
  155. while(depth-- > 0)
  156. {
  157. buf << pscTabString;
  158. }
  159. // now print out API name
  160. buf << pscApiName;
  161. // now we are ready to print out what was passed
  162. pscPos = strchr(pscFormat, '%');
  163. while(pscPos != NULL)
  164. {
  165. // insert the text up to the found '%' character into the buffer
  166. buf.Insert(pscFormat, (int)(pscPos-pscFormat));
  167. if(*(pscPos+1) == '%') // this is '%%', we only print one '%' and don't print an argument
  168. {
  169. buf << *pscPos;
  170. pscFormat = pscPos+2;
  171. }
  172. else
  173. {
  174. BYTE argType = NO_TYPE;
  175. // advance pscPos to type specifier
  176. pscPos++;
  177. // we need to take an argument and handle it
  178. if(*pscPos >= 'A' && *pscPos <= 'z')
  179. {
  180. argType = g_tcLookup[*pscPos- 'A'];
  181. }
  182. if(argType != NO_TYPE)
  183. {
  184. // handle argument
  185. // function will advance pscPos past format specifier
  186. g_pFuncs[argType](buf, argptr, pscPos);
  187. }
  188. else
  189. {
  190. // assume we've got a one character format specifier
  191. pscPos++;
  192. // unknown type, assume size of int
  193. va_arg(argptr, int);
  194. }
  195. // advance search pointer past type specifier
  196. pscFormat = pscPos;
  197. }
  198. pscPos = strchr(pscFormat, '%');
  199. }
  200. // print out remainder of string
  201. buf << pscFormat;
  202. // destructor will flush buffer for us
  203. }
  204. //+---------------------------------------------------------------------------
  205. //
  206. // Function: WriteHex
  207. //
  208. // Synopsis: Prints out a lower case hex value
  209. //
  210. // Arguments: [buf] - reference to text buffer to write text to
  211. // [param] - reference to variable argument list
  212. // [pFormat] - reference to a char * to the format string,
  213. // used to advance string past specifier string
  214. //
  215. // Returns: nothing
  216. //
  217. // History: 11-Jul-95 t-stevan Created
  218. //
  219. //----------------------------------------------------------------------------
  220. void WriteHex(CTextBufferA &buf, va_list &param, char *&pFormat)
  221. {
  222. WriteHexCommon(buf, va_arg(param, unsigned long), FALSE);
  223. //advance format pointer
  224. pFormat++;
  225. }
  226. //+---------------------------------------------------------------------------
  227. //
  228. // Function: WriteHexCaps
  229. //
  230. // Synopsis: Prints out an upper case hex value
  231. //
  232. // Arguments: [buf] - reference to text buffer to write text to
  233. // [param] - reference to variable argument list
  234. // [pFormat] - reference to a char * to the format string,
  235. // used to advance string past specifier string
  236. //
  237. // Returns: nothing
  238. //
  239. // History: 11-Jul-95 t-stevan Created
  240. //
  241. //----------------------------------------------------------------------------
  242. void WriteHexCaps(CTextBufferA &buf, va_list &param, char *&pFormat)
  243. {
  244. WriteHexCommon(buf, va_arg(param, unsigned long), TRUE);
  245. //advance format pointer
  246. pFormat++;
  247. }
  248. //+---------------------------------------------------------------------------
  249. //
  250. // Function: WriteInt
  251. //
  252. // Synopsis: Prints out a signed integer value
  253. //
  254. // Arguments: [buf] - reference to text buffer to write text to
  255. // [param] - reference to variable argument list
  256. // [pFormat] - reference to a char * to the format string,
  257. // used to advance string past specifier string
  258. //
  259. // Returns: nothing
  260. //
  261. // History: 11-Jul-95 t-stevan Created
  262. //
  263. //----------------------------------------------------------------------------
  264. void WriteInt(CTextBufferA &buf, va_list &param, char *&pFormat)
  265. {
  266. WriteIntCommon(buf, va_arg(param, unsigned int), FALSE);
  267. // advance pointer
  268. pFormat++;
  269. }
  270. //+---------------------------------------------------------------------------
  271. //
  272. // Function: WriteUnsigned
  273. //
  274. // Synopsis: Prints out a unsigned value, may be 64 bit or 32 bit
  275. // depending on next character in format specifier
  276. //
  277. // Arguments: [buf] - reference to text buffer to write text to
  278. // [param] - reference to variable argument list
  279. // [pFormat] - reference to a char * to the format string,
  280. // used to advance string past specifier string
  281. //
  282. // Returns: nothing
  283. //
  284. // History: 11-Jul-95 t-stevan Created
  285. //
  286. //----------------------------------------------------------------------------
  287. void WriteUnsigned(CTextBufferA &buf, va_list &param, char *&pFormat)
  288. {
  289. switch(*(pFormat+1)) // next character determines type
  290. {
  291. case 'd': // 32-bit
  292. case 'D':
  293. WriteIntCommon(buf, va_arg(param, unsigned long), TRUE);
  294. // Advance format pointer
  295. pFormat+=2;
  296. break;
  297. case 'l': // 64-bit
  298. case 'L':
  299. WriteLargeCommon(buf, va_arg(param, __int64 *), TRUE);
  300. // advance format pointer
  301. if(*(pFormat+2) == 'd' || *(pFormat+2) == 'D')
  302. {
  303. pFormat+=3;
  304. }
  305. else
  306. {
  307. pFormat+=2;
  308. }
  309. break;
  310. default:
  311. pFormat++; // assume it's just one char-type specifier
  312. break;
  313. }
  314. }
  315. //+---------------------------------------------------------------------------
  316. //
  317. // Function: WritePointer
  318. //
  319. // Synopsis: Prints out a lower case pointer value,
  320. // checks to make sure pointer is good value
  321. // prints out symbol if a symbol maps to pointer
  322. //
  323. // Arguments: [buf] - reference to text buffer to write text to
  324. // [param] - reference to variable argument list
  325. // [pFormat] - reference to a char * to the format string,
  326. // used to advance string past specifier string
  327. //
  328. // Returns: nothing
  329. //
  330. // History: 11-Jul-95 t-stevan Created
  331. //
  332. //----------------------------------------------------------------------------
  333. void WritePointer(CTextBufferA &buf, va_list &param, char *&pFormat)
  334. {
  335. if(*(pFormat+1) != 'p')
  336. {
  337. WritePointerCommon(buf, va_arg(param, void *), FALSE, FALSE, FALSE);
  338. pFormat++;
  339. }
  340. else
  341. {
  342. void **pPointer;
  343. BufferContext bc;
  344. // take snapshot of buffer
  345. buf.SnapShot(bc);
  346. // write pointer to pointer
  347. // first validate this pointer
  348. __try
  349. {
  350. pPointer = va_arg(param, void **);
  351. WritePointerCommon(buf, *pPointer, FALSE, FALSE, FALSE);
  352. }
  353. __except(ExceptionFilter(_exception_code()))
  354. {
  355. // try to revert buffer
  356. buf.Revert(bc);
  357. WritePointerCommon(buf, pPointer, FALSE, TRUE, FALSE);
  358. }
  359. pFormat +=2;
  360. }
  361. }
  362. //+---------------------------------------------------------------------------
  363. //
  364. // Function: WritePointerCaps
  365. //
  366. // Synopsis: Prints out an upper case pointer value,
  367. // checks to make sure pointer is good value
  368. // prints out symbol if a symbol maps to pointer
  369. //
  370. // Arguments: [buf] - reference to text buffer to write text to
  371. // [param] - reference to variable argument list
  372. // [pFormat] - reference to a char * to the format string,
  373. // used to advance string past specifier string
  374. //
  375. // Returns: nothing
  376. //
  377. // History: 11-Jul-95 t-stevan Created
  378. //
  379. //----------------------------------------------------------------------------
  380. void WritePointerCaps(CTextBufferA &buf, va_list &param, char *&pFormat)
  381. {
  382. WritePointerCommon(buf, va_arg(param, void *), TRUE, FALSE, FALSE);
  383. pFormat++;
  384. }
  385. //+---------------------------------------------------------------------------
  386. //
  387. // Function: WriteLarge
  388. //
  389. // Synopsis: Prints out a 64-bit integer
  390. //
  391. // Arguments: [buf] - reference to text buffer to write text to
  392. // [param] - reference to variable argument list
  393. // [pFormat] - reference to a char * to the format string,
  394. // used to advance string past specifier string
  395. //
  396. // Returns: nothing
  397. //
  398. // History: 11-Jul-95 t-stevan Created
  399. //
  400. //----------------------------------------------------------------------------
  401. void WriteLarge(CTextBufferA &buf, va_list &param, char *&pFormat)
  402. {
  403. WriteLargeCommon(buf, va_arg(param, __int64 *), FALSE);
  404. if(*(pFormat+1) == 'd' || *(pFormat+1) == 'D')
  405. {
  406. pFormat+=2;
  407. }
  408. else
  409. {
  410. pFormat++;
  411. }
  412. }
  413. //+---------------------------------------------------------------------------
  414. //
  415. // Function: WriteBool
  416. //
  417. // Synopsis: Prints out a lower case boolean value
  418. //
  419. // Arguments: [buf] - reference to text buffer to write text to
  420. // [param] - reference to variable argument list
  421. // [pFormat] - reference to a char * to the format string,
  422. // used to advance string past specifier string
  423. //
  424. // Returns: nothing
  425. //
  426. // History: 11-Jul-95 t-stevan Created
  427. //
  428. //----------------------------------------------------------------------------
  429. void WriteBool(CTextBufferA &buf, va_list &param, char *&pFormat)
  430. {
  431. WriteBoolCommon(buf, va_arg(param, BOOL), FALSE);
  432. pFormat++;
  433. }
  434. //+---------------------------------------------------------------------------
  435. //
  436. // Function: WriteBoolCaps
  437. //
  438. // Synopsis: Prints out an upper case boolean value
  439. //
  440. // Arguments: [buf] - reference to text buffer to write text to
  441. // [param] - reference to variable argument list
  442. // [pFormat] - reference to a char * to the format string,
  443. // used to advance string past specifier string
  444. //
  445. // Returns: nothing
  446. //
  447. // History: 11-Jul-95 t-stevan Created
  448. //
  449. //----------------------------------------------------------------------------
  450. void WriteBoolCaps(CTextBufferA &buf, va_list &param, char *&pFormat)
  451. {
  452. WriteBoolCommon(buf, va_arg(param, BOOL), TRUE);
  453. pFormat++;
  454. }
  455. //+---------------------------------------------------------------------------
  456. //
  457. // Function: WriteString
  458. //
  459. // Synopsis: Prints out an ASCII string
  460. //
  461. // Arguments: [buf] - reference to text buffer to write text to
  462. // [param] - reference to variable argument list
  463. // [pFormat] - reference to a char * to the format string,
  464. // used to advance string past specifier string
  465. //
  466. // Returns: nothing
  467. //
  468. // History: 11-Jul-95 t-stevan Created
  469. //
  470. //----------------------------------------------------------------------------
  471. void WriteString(CTextBufferA &buf, va_list &param, char *&pFormat)
  472. {
  473. WriteStringCommon(buf, va_arg(param, const char *));
  474. // Advance format pointer
  475. pFormat++;
  476. }
  477. //+---------------------------------------------------------------------------
  478. //
  479. // Function: WriteWideString
  480. //
  481. // Synopsis: Prints out a UNICODE string, but only supports ASCII characters
  482. // if character > 256 is encountered, an "unprintable character" char
  483. // is printed
  484. //
  485. // Arguments: [buf] - reference to text buffer to write text to
  486. // [param] - reference to variable argument list
  487. // [pFormat] - reference to a char * to the format string,
  488. // used to advance string past specifier string
  489. //
  490. // Returns: nothing
  491. //
  492. // History: 11-Jul-95 t-stevan Created
  493. //
  494. //----------------------------------------------------------------------------
  495. void WriteWideString(CTextBufferA &buf, va_list &param, char *&pFormat)
  496. {
  497. WriteWideStringCommon(buf, va_arg(param, const WCHAR *));
  498. // Advance format pointer
  499. if(*(pFormat+1) == 's')
  500. {
  501. pFormat+=2;
  502. }
  503. else
  504. {
  505. pFormat++;
  506. }
  507. }
  508. //+---------------------------------------------------------------------------
  509. //
  510. // Function: WriteGUID
  511. //
  512. // Synopsis: Prints out a GUID
  513. //
  514. // Arguments: [buf] - reference to text buffer to write text to
  515. // [param] - reference to variable argument list
  516. // [pFormat] - reference to a char * to the format string,
  517. // used to advance string past specifier string
  518. //
  519. // Returns: nothing
  520. //
  521. // History: 11-Jul-95 t-stevan Created
  522. //
  523. //----------------------------------------------------------------------------
  524. void WriteGUID(CTextBufferA &buf, va_list &param, char *&pFormat)
  525. {
  526. WriteGUIDCommon(buf, va_arg(param, GUID *));
  527. // Advance format pointer
  528. pFormat++;
  529. }
  530. //+---------------------------------------------------------------------------
  531. //
  532. // Function: WriteStuct
  533. //
  534. // Synopsis: Prints out a structure. If structure expansion is enabled
  535. // expands the structure depending on it's type
  536. //
  537. // Arguments: [buf] - reference to text buffer to write text to
  538. // [param] - reference to variable argument list
  539. // [pFormat] - reference to a char * to the format string,
  540. // used to advance string past specifier string
  541. //
  542. // Returns: nothing
  543. //
  544. // History: 11-Jul-95 t-stevan Created
  545. //
  546. //----------------------------------------------------------------------------
  547. void WriteStruct(CTextBufferA &buf, va_list &param, char *&pFormat)
  548. {
  549. void *pArg;
  550. BYTE bType = NO_STRUCT;
  551. pArg = va_arg(param, void *);
  552. if(*(pFormat+1) >= 'a' && *(pFormat+1) <= 'z')
  553. {
  554. bType = g_structLookup[*(pFormat+1) - 'a'];
  555. }
  556. if(bType != NO_STRUCT) // only print out known structures
  557. {
  558. BufferContext bc;
  559. buf.SnapShot(bc); // take a snapshot of the buffer
  560. __try
  561. {
  562. g_pStructFuncs[bType](buf, pArg);
  563. }
  564. __except (ExceptionFilter(_exception_code()))
  565. {
  566. buf.Revert(bc); // try to revert to the old buffer
  567. // bad pointer
  568. WritePointerCommon(buf, pArg, FALSE, TRUE, FALSE);
  569. }
  570. }
  571. else
  572. {
  573. // write out the pointer
  574. WritePointerCommon(buf, pArg, FALSE, FALSE, FALSE);
  575. }
  576. // increment format pointer
  577. pFormat += 2;
  578. }
  579. #endif // DBG==1