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.

502 lines
14 KiB

  1. // ----------------------------------------------------------------------------
  2. // debug.c
  3. //
  4. // Microsoft At Work Fax Debugging Utilities
  5. //
  6. // Copyright (C) 1993 Microsoft Corporation
  7. // ----------------------------------------------------------------------------
  8. /* Revision History:
  9. *
  10. * When Who What
  11. * -------- ------------------ ---------------------------------------
  12. * 3.17.94 MAPI Original source from MAPI mapidbg.c
  13. * 3.17.94 Yoram Yaacovi Modifications to overcome compobj.h problems
  14. * 3.7.94 Yoram Yaacovi Update to MAPI build 154
  15. * 12.1.94 Yoram Yaacovi Added DebugLog()
  16. *
  17. ***********************************************************************/
  18. #include <windows.h>
  19. #include <stdio.h>
  20. #include <time.h>
  21. //#include "faxcfg.h"
  22. #include "mapi.h"
  23. #include "mapidbg.h"
  24. #include "mapidefs.h"
  25. #include "mapicode.h"
  26. #ifdef DEBUG
  27. /*
  28. *
  29. * From current\src\mapi\inc\_memcpy.h
  30. *
  31. * MemCopy()
  32. *
  33. * A much safer version of memcpy that checks the value of the byte
  34. * count before calling the memcpy() function. This macro is only built
  35. * into the 16 bit non-debug builds.
  36. */
  37. #ifndef __MEMCPY_H_
  38. #define __MEMCPY_H_
  39. #define MemCopy(_dst,_src,_cb) memcpy(_dst,_src,(size_t)(_cb))
  40. #endif
  41. #if defined(WIN16) || defined(WIN32)
  42. static BOOL fTraceEnabled = -1;
  43. static BOOL fLogTraceEnabled = -1;
  44. static BOOL fAssertLeaks = -1;
  45. static TCHAR szKeyTraceEnabled[] = TEXT("DebugTrace");
  46. static TCHAR szKeyLogTraceEnabled[] = TEXT("DebugTraceLog");
  47. static TCHAR szKeyDebugTrap[] = TEXT("DebugTrap");
  48. static TCHAR szKeyExtendedDebug[] = TEXT("ExtendedDebug");
  49. static TCHAR szKeyUseVirtual[] = TEXT("VirtualMemory");
  50. static TCHAR szKeyAssertLeaks[] = TEXT("AssertLeaks");
  51. static TCHAR szKeyCheckOften[] = TEXT("CheckHeapOften");
  52. static TCHAR szSectionDebug[] = TEXT("General");
  53. static TCHAR szDebugIni[] = TEXT("MAWFDBG.INI");
  54. #endif
  55. // ExtendedDebug --------------------------------------------------------------
  56. BOOL ExtendedDebug(void)
  57. {
  58. return (GetPrivateProfileInt(szSectionDebug, szKeyExtendedDebug,
  59. 0, szDebugIni));
  60. }
  61. // DebugTrap --------------------------------------------------------------
  62. void DebugTrap(void)
  63. {
  64. if (GetPrivateProfileInt(szSectionDebug, szKeyDebugTrap,
  65. 0, szDebugIni))
  66. DebugBreak();
  67. }
  68. // DebugLog --------------------------------------------------------------
  69. void DebugLog(LPSTR szString)
  70. {
  71. FILE *logfile;
  72. // open a log file for appending. create if does not exist
  73. if ((logfile = fopen ("c:\\uilog.txt", "a+")) != NULL)
  74. {
  75. fwrite (szString, 1, strlen(szString), logfile);
  76. fclose(logfile);
  77. }
  78. }
  79. // DebugOutputFn --------------------------------------------------------------
  80. void DebugOutputFn(char *psz)
  81. {
  82. #if defined(_MAC)
  83. OutputDebugString(psz);
  84. #else
  85. char * pszBeg;
  86. char * pszEnd;
  87. char szBuf[3];
  88. #if defined(WIN16) || defined(WIN32)
  89. if (fTraceEnabled == -1)
  90. {
  91. fTraceEnabled = GetPrivateProfileInt(szSectionDebug, szKeyTraceEnabled,
  92. 0, szDebugIni);
  93. }
  94. if (!fTraceEnabled)
  95. return;
  96. if (fLogTraceEnabled == -1)
  97. {
  98. fLogTraceEnabled =
  99. GetPrivateProfileInt(szSectionDebug, szKeyLogTraceEnabled, 0, szDebugIni);
  100. }
  101. #endif
  102. for (pszBeg = psz; pszBeg && *pszBeg; pszBeg = pszEnd) {
  103. pszEnd = strchr(pszBeg, '\n');
  104. if (pszEnd) {
  105. MemCopy(szBuf, pszEnd, 3);
  106. if (pszEnd > pszBeg && *(pszEnd - 1) != '\r')
  107. strcpy(pszEnd, "\r\n");
  108. else
  109. *(pszEnd + 1) = 0;
  110. }
  111. if (fLogTraceEnabled)
  112. DebugLog(pszBeg);
  113. else
  114. OutputDebugStringA(pszBeg);
  115. if (pszEnd) {
  116. MemCopy(pszEnd, szBuf, 3);
  117. pszEnd += 1;
  118. }
  119. }
  120. #endif
  121. }
  122. // DebugTrapFn ----------------------------------------------------------------
  123. #if defined(WIN32) && defined(THREAD_MSG_BOX)
  124. typedef struct {
  125. char * sz1;
  126. char * sz2;
  127. UINT rgf;
  128. int iResult;
  129. } MBContext;
  130. DWORD WINAPI MessageBoxFnThreadMain(MBContext *pmbc)
  131. {
  132. pmbc->iResult = MessageBoxA(NULL, pmbc->sz1, pmbc->sz2,
  133. pmbc->rgf | MB_SETFOREGROUND);
  134. return(0);
  135. }
  136. int MessageBoxFn(char *sz1, char *sz2, UINT rgf)
  137. {
  138. HANDLE hThread;
  139. DWORD dwThreadId;
  140. MBContext mbc;
  141. mbc.sz1 = sz1;
  142. mbc.sz2 = sz2;
  143. mbc.rgf = rgf;
  144. mbc.iResult = IDRETRY;
  145. hThread = CreateThread(NULL, 0,
  146. (PTHREAD_START_ROUTINE)MessageBoxFnThreadMain, &mbc, 0, &dwThreadId);
  147. if (hThread != NULL) {
  148. WaitForSingleObject(hThread, INFINITE);
  149. CloseHandle(hThread);
  150. }
  151. return(mbc.iResult);
  152. }
  153. #else
  154. #define MessageBoxFn(sz1, sz2, rgf) MessageBoxA(NULL, sz1, sz2, rgf)
  155. #endif
  156. int __cdecl DebugTrapFn(int fFatal, char *pszFile, int iLine, char *pszFormat, ...)
  157. {
  158. char sz[512];
  159. va_list vl;
  160. #if defined(WIN16) || defined(WIN32)
  161. int id;
  162. #endif
  163. strcpy(sz, "++++ MAWF Debug Trap (");
  164. _strdate(sz + strlen(sz));
  165. strcat(sz, " ");
  166. _strtime(sz + strlen(sz));
  167. strcat(sz, ")\n");
  168. DebugOutputFn(sz);
  169. va_start(vl, pszFormat);
  170. wvsprintfA(sz, pszFormat, vl);
  171. va_end(vl);
  172. wsprintfA(sz + strlen(sz), "\n[File %s, Line %d]\n\n", pszFile, iLine);
  173. DebugOutputFn(sz);
  174. #if defined(DOS)
  175. _asm { int 3 }
  176. #endif
  177. #if defined(WIN16) || defined(WIN32)
  178. // Hold down control key to prevent MessageBox
  179. if ( GetAsyncKeyState(VK_CONTROL) >= 0 )
  180. {
  181. id = MessageBoxFn(sz, "Microsoft At Work Fax Debug Trap",
  182. MB_ABORTRETRYIGNORE | MB_ICONHAND | MB_TASKMODAL |
  183. (fFatal ? MB_DEFBUTTON1 : MB_DEFBUTTON3));
  184. if (id == IDABORT)
  185. *((LPBYTE)NULL) = 0;
  186. else if (id == IDRETRY)
  187. DebugBreak();
  188. }
  189. #endif
  190. return(0);
  191. }
  192. // ExtendedDebugTraceFn ---------------------------------------------------------------
  193. int __cdecl ExtendedDebugTraceFn(char *pszFormat, ...)
  194. {
  195. char sz[512];
  196. int fAutoLF = 0;
  197. va_list vl;
  198. if (ExtendedDebug())
  199. {
  200. if (*pszFormat == '~') {
  201. pszFormat += 1;
  202. fAutoLF = 1;
  203. }
  204. va_start(vl, pszFormat);
  205. wvsprintfA(sz, pszFormat, vl);
  206. va_end(vl);
  207. if (fAutoLF)
  208. strcat(sz, "\n");
  209. DebugOutputFn(sz);
  210. }
  211. return(0);
  212. }
  213. // DebugTraceFn ---------------------------------------------------------------
  214. int __cdecl DebugTraceFn(char *pszFormat, ...)
  215. {
  216. char sz[512];
  217. char sz1[512];
  218. int fAutoLF = 0;
  219. va_list vl;
  220. HINSTANCE hInst=NULL; // this really needs to be a parameter
  221. if (*pszFormat == '~') {
  222. pszFormat += 1;
  223. fAutoLF = 1;
  224. }
  225. va_start(vl, pszFormat);
  226. wvsprintfA(sz, pszFormat, vl);
  227. va_end(vl);
  228. if (fAutoLF)
  229. strcat(sz, "\n");
  230. strcpy(sz1, sz);
  231. DebugOutputFn(sz1);
  232. return(0);
  233. }
  234. // SCODE & PropTag decoding ---------------------------------------------------
  235. typedef struct
  236. {
  237. char * psz;
  238. unsigned long ulPropTag;
  239. } PT;
  240. typedef struct
  241. {
  242. char * psz;
  243. SCODE sc;
  244. } SC;
  245. #define Pt(_ptag) {#_ptag, _ptag}
  246. #define Sc(_sc) {#_sc, _sc}
  247. #if !defined(DOS)
  248. static PT rgpt[] = {
  249. /*
  250. * Property types
  251. */
  252. Pt(PT_UNSPECIFIED),
  253. Pt(PT_NULL),
  254. Pt(PT_I2),
  255. Pt(PT_LONG),
  256. Pt(PT_R4),
  257. Pt(PT_DOUBLE),
  258. Pt(PT_CURRENCY),
  259. Pt(PT_APPTIME),
  260. Pt(PT_ERROR),
  261. Pt(PT_BOOLEAN),
  262. Pt(PT_OBJECT),
  263. Pt(PT_I8),
  264. Pt(PT_STRING8),
  265. Pt(PT_UNICODE),
  266. Pt(PT_SYSTIME),
  267. Pt(PT_CLSID),
  268. Pt(PT_BINARY),
  269. Pt(PT_TSTRING),
  270. Pt(PT_MV_I2),
  271. Pt(PT_MV_LONG),
  272. Pt(PT_MV_R4),
  273. Pt(PT_MV_DOUBLE),
  274. Pt(PT_MV_CURRENCY),
  275. Pt(PT_MV_APPTIME),
  276. Pt(PT_MV_SYSTIME),
  277. Pt(PT_MV_STRING8),
  278. Pt(PT_MV_BINARY),
  279. Pt(PT_MV_UNICODE),
  280. Pt(PT_MV_CLSID),
  281. Pt(PT_MV_I8)
  282. };
  283. #define cpt (sizeof(rgpt) / sizeof(PT))
  284. static SC rgsc[] = {
  285. /* FACILITY_NULL error codes from OLE */
  286. Sc(S_OK),
  287. Sc(S_FALSE),
  288. Sc(E_UNEXPECTED),
  289. Sc(E_NOTIMPL),
  290. Sc(E_OUTOFMEMORY),
  291. Sc(E_INVALIDARG),
  292. Sc(E_NOINTERFACE),
  293. Sc(E_POINTER),
  294. Sc(E_HANDLE),
  295. Sc(E_ABORT),
  296. Sc(E_FAIL),
  297. Sc(E_ACCESSDENIED),
  298. /* General errors (used by more than one MAPI object) */
  299. Sc(MAPI_E_NO_SUPPORT),
  300. Sc(MAPI_E_BAD_CHARWIDTH),
  301. Sc(MAPI_E_STRING_TOO_LONG),
  302. Sc(MAPI_E_UNKNOWN_FLAGS),
  303. Sc(MAPI_E_INVALID_ENTRYID),
  304. Sc(MAPI_E_INVALID_OBJECT),
  305. Sc(MAPI_E_OBJECT_CHANGED),
  306. Sc(MAPI_E_OBJECT_DELETED),
  307. Sc(MAPI_E_BUSY),
  308. Sc(MAPI_E_NOT_ENOUGH_DISK),
  309. Sc(MAPI_E_NOT_ENOUGH_RESOURCES),
  310. Sc(MAPI_E_NOT_FOUND),
  311. Sc(MAPI_E_VERSION),
  312. Sc(MAPI_E_LOGON_FAILED),
  313. Sc(MAPI_E_SESSION_LIMIT),
  314. Sc(MAPI_E_USER_CANCEL),
  315. Sc(MAPI_E_UNABLE_TO_ABORT),
  316. Sc(MAPI_E_NETWORK_ERROR),
  317. Sc(MAPI_E_DISK_ERROR),
  318. Sc(MAPI_E_TOO_COMPLEX),
  319. Sc(MAPI_E_BAD_COLUMN),
  320. Sc(MAPI_E_EXTENDED_ERROR),
  321. Sc(MAPI_E_COMPUTED),
  322. /* MAPI base function and status object specific errors and warnings */
  323. Sc(MAPI_E_END_OF_SESSION),
  324. Sc(MAPI_E_UNKNOWN_ENTRYID),
  325. Sc(MAPI_E_MISSING_REQUIRED_COLUMN),
  326. /* Property specific errors and warnings */
  327. Sc(MAPI_E_BAD_VALUE),
  328. Sc(MAPI_E_INVALID_TYPE),
  329. Sc(MAPI_E_TYPE_NO_SUPPORT),
  330. Sc(MAPI_E_UNEXPECTED_TYPE),
  331. Sc(MAPI_E_TOO_BIG),
  332. Sc(MAPI_W_ERRORS_RETURNED),
  333. /* Table specific errors and warnings */
  334. Sc(MAPI_E_UNABLE_TO_COMPLETE),
  335. Sc(MAPI_E_TABLE_EMPTY),
  336. Sc(MAPI_E_TABLE_TOO_BIG),
  337. Sc(MAPI_E_INVALID_BOOKMARK),
  338. Sc(MAPI_W_POSITION_CHANGED),
  339. Sc(MAPI_W_APPROX_COUNT),
  340. /* Transport specific errors and warnings */
  341. Sc(MAPI_E_WAIT),
  342. Sc(MAPI_E_CANCEL),
  343. Sc(MAPI_E_NOT_ME),
  344. Sc(MAPI_W_CANCEL_MESSAGE),
  345. /* Message Store, Folder, and Message specific errors and warnings */
  346. Sc(MAPI_E_CORRUPT_STORE),
  347. Sc(MAPI_E_NOT_IN_QUEUE),
  348. Sc(MAPI_E_NO_SUPPRESS),
  349. Sc(MAPI_E_COLLISION),
  350. Sc(MAPI_E_NOT_INITIALIZED),
  351. Sc(MAPI_E_NON_STANDARD),
  352. Sc(MAPI_E_NO_RECIPIENTS),
  353. Sc(MAPI_E_SUBMITTED),
  354. Sc(MAPI_E_HAS_FOLDERS),
  355. Sc(MAPI_E_HAS_MESSAGES),
  356. Sc(MAPI_E_FOLDER_CYCLE),
  357. /* Address Book specific errors and warnings */
  358. Sc(MAPI_E_AMBIGUOUS_RECIP)
  359. };
  360. #define csc (sizeof(rgsc) / sizeof(SC))
  361. #endif
  362. char * __cdecl
  363. SzDecodeScodeFn(SCODE sc)
  364. {
  365. static char rgch[64];
  366. #if !defined(DOS)
  367. int isc;
  368. for (isc = 0; isc < csc; ++isc)
  369. if (sc == rgsc[isc].sc)
  370. return rgsc[isc].psz;
  371. #endif
  372. wsprintfA (rgch, "%08lX", sc);
  373. return rgch;
  374. }
  375. #else // no DEBUG
  376. typedef long SCODE;
  377. // need to define empty functions for DEF file resolution
  378. BOOL ExtendedDebug(void)
  379. {
  380. return FALSE;
  381. }
  382. void DebugTrap(void)
  383. {
  384. }
  385. int __cdecl DebugTrapFn(int fFatal, char *pszFile, int iLine, char *pszFormat, ...)
  386. {
  387. return 0;
  388. }
  389. int __cdecl DebugTraceFn(char *pszFormat, ...)
  390. {
  391. return 0;
  392. }
  393. int __cdecl ExtendedDebugTraceFn(char *pszFormat, ...)
  394. {
  395. return 0;
  396. }
  397. char * __cdecl SzDecodeScodeFn(SCODE sc)
  398. {
  399. return NULL;
  400. }
  401. #endif