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.

365 lines
8.8 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Copyright (c) Microsoft Corporation 1993-1994
  4. //
  5. // File: err.c
  6. //
  7. // This files contains all error handling routines.
  8. //
  9. // History:
  10. // 08-06-93 ScottH Transferred from twin code
  11. //
  12. //---------------------------------------------------------------------------
  13. ///////////////////////////////////////////////////// INCLUDES
  14. #include "brfprv.h" // common headers
  15. ///////////////////////////////////////////////////// TYPEDEFS
  16. ///////////////////////////////////////////////////// CONTROLLING DEFINES
  17. ///////////////////////////////////////////////////// DEFINES
  18. ///////////////////////////////////////////////////// MODULE DATA
  19. #ifdef DEBUG
  20. TCHAR const c_szNewline[] = TEXT("\r\n");
  21. TCHAR const c_szTrace[] = TEXT("t BRIEFCASE ");
  22. TCHAR const c_szDbg[] = TEXT("BRIEFCASE ");
  23. TCHAR const c_szAssertFailed[] = TEXT("BRIEFCASE Assertion failed in %s on line %d\r\n");
  24. struct _RIIDMAP
  25. {
  26. REFIID riid;
  27. LPCTSTR psz;
  28. } const c_rgriidmap[] = {
  29. { &IID_IUnknown, TEXT("IID_IUnknown") },
  30. { &IID_IBriefcaseStg, TEXT("IID_IBriefcaseStg") },
  31. { &IID_IEnumUnknown, TEXT("IID_IEnumUnknown") },
  32. { &IID_IShellBrowser, TEXT("IID_IShellBrowser") },
  33. { &IID_IShellView, TEXT("IID_IShellView") },
  34. { &IID_IContextMenu, TEXT("IID_IContextMenu") },
  35. { &IID_IShellFolder, TEXT("IID_IShellFolder") },
  36. { &IID_IShellExtInit, TEXT("IID_IShellExtInit") },
  37. { &IID_IShellPropSheetExt, TEXT("IID_IShellPropSheetExt") },
  38. { &IID_IPersistFolder, TEXT("IID_IPersistFolder") },
  39. { &IID_IExtractIcon, TEXT("IID_IExtractIcon") },
  40. { &IID_IShellDetails, TEXT("IID_IShellDetails") },
  41. { &IID_IDelayedRelease, TEXT("IID_IDelayedRelease") },
  42. { &IID_IShellLink, TEXT("IID_IShellLink") },
  43. };
  44. struct _SCODEMAP
  45. {
  46. SCODE sc;
  47. LPCTSTR psz;
  48. } const c_rgscodemap[] = {
  49. { S_OK, TEXT("S_OK") },
  50. { S_FALSE, TEXT("S_FALSE") },
  51. { E_UNEXPECTED, TEXT("E_UNEXPECTED") },
  52. { E_NOTIMPL, TEXT("E_NOTIMPL") },
  53. { E_OUTOFMEMORY, TEXT("E_OUTOFMEMORY") },
  54. { E_INVALIDARG, TEXT("E_INVALIDARG") },
  55. { E_NOINTERFACE, TEXT("E_NOINTERFACE") },
  56. { E_POINTER, TEXT("E_POINTER") },
  57. { E_HANDLE, TEXT("E_HANDLE") },
  58. { E_ABORT, TEXT("E_ABORT") },
  59. { E_FAIL, TEXT("E_FAIL") },
  60. { E_ACCESSDENIED, TEXT("E_ACCESSDENIED") },
  61. };
  62. #endif
  63. ///////////////////////////////////////////////////// PUBLIC FUNCTIONS
  64. #ifdef DEBUG
  65. /*----------------------------------------------------------
  66. Purpose: Return English reason for the debug break
  67. Returns: String
  68. Cond: --
  69. */
  70. LPCTSTR PRIVATE GetReasonString(
  71. UINT flag) // One of BF_ flags
  72. {
  73. LPCTSTR psz;
  74. if (IsFlagSet(flag, BF_ONOPEN))
  75. psz = TEXT("BREAK ON OPEN BRIEFCASE\r\n");
  76. else if (IsFlagSet(flag, BF_ONCLOSE))
  77. psz = TEXT("BREAK ON CLOSE BRIEFCASE\r\n");
  78. else if (IsFlagSet(flag, BF_ONRUNONCE))
  79. psz = TEXT("BREAK ON RunDLL_RunOnlyOnce\r\n");
  80. else if (IsFlagSet(flag, BF_ONVALIDATE))
  81. psz = TEXT("BREAK ON VALIDATION FAILURE\r\n");
  82. else if (IsFlagSet(flag, BF_ONTHREADATT))
  83. psz = TEXT("BREAK ON THREAD ATTACH\r\n");
  84. else if (IsFlagSet(flag, BF_ONTHREADDET))
  85. psz = TEXT("BREAK ON THREAD DETACH\r\n");
  86. else if (IsFlagSet(flag, BF_ONPROCESSATT))
  87. psz = TEXT("BREAK ON PROCESS ATTACH\r\n");
  88. else if (IsFlagSet(flag, BF_ONPROCESSDET))
  89. psz = TEXT("BREAK ON PROCESS DETACH\r\n");
  90. else
  91. psz = c_szNewline;
  92. return psz;
  93. }
  94. /*----------------------------------------------------------
  95. Purpose: Perform a debug break based on the flag
  96. Returns: --
  97. Cond: --
  98. */
  99. void PUBLIC DEBUG_BREAK(
  100. UINT flag) // One of BF_ flags
  101. {
  102. BOOL bBreak;
  103. LPCTSTR psz;
  104. ENTEREXCLUSIVE();
  105. {
  106. bBreak = IsFlagSet(g_uBreakFlags, flag);
  107. psz = GetReasonString(flag);
  108. }
  109. LEAVEEXCLUSIVE();
  110. if (bBreak)
  111. {
  112. TRACE_MSG(TF_ALWAYS, psz);
  113. DebugBreak();
  114. }
  115. }
  116. void PUBLIC BrfAssertFailed(
  117. LPCTSTR pszFile,
  118. int line)
  119. {
  120. LPCTSTR psz;
  121. TCHAR ach[256];
  122. UINT uBreakFlags;
  123. ENTEREXCLUSIVE();
  124. {
  125. uBreakFlags = g_uBreakFlags;
  126. }
  127. LEAVEEXCLUSIVE();
  128. // Strip off path info from filename string, if present.
  129. //
  130. for (psz = pszFile + lstrlen(pszFile); psz != pszFile; psz=CharPrev(pszFile, psz))
  131. {
  132. if ((CharPrev(pszFile, psz) != (psz-2)) && *(psz - 1) == TEXT('\\'))
  133. break;
  134. }
  135. wsprintf(ach, c_szAssertFailed, psz, line);
  136. OutputDebugString(ach);
  137. if (IsFlagSet(uBreakFlags, BF_ONVALIDATE))
  138. DebugBreak();
  139. }
  140. void CPUBLIC BrfAssertMsg(
  141. BOOL f,
  142. LPCTSTR pszMsg, ...)
  143. {
  144. TCHAR ach[MAXPATHLEN+40]; // Largest path plus extra
  145. if (!f)
  146. {
  147. lstrcpy(ach, c_szTrace);
  148. wvsprintf(&ach[ARRAYSIZE(c_szTrace)-1], pszMsg, (va_list)(&pszMsg + 1));
  149. OutputDebugString(ach);
  150. OutputDebugString(c_szNewline);
  151. }
  152. }
  153. void CPUBLIC BrfDebugMsg(
  154. UINT uFlag,
  155. LPCTSTR pszMsg, ...)
  156. {
  157. TCHAR ach[MAXPATHLEN+40]; // Largest path plus extra
  158. UINT uTraceFlags;
  159. ENTEREXCLUSIVE();
  160. {
  161. uTraceFlags = g_uTraceFlags;
  162. }
  163. LEAVEEXCLUSIVE();
  164. if (uFlag == TF_ALWAYS || IsFlagSet(uTraceFlags, uFlag))
  165. {
  166. lstrcpy(ach, c_szTrace);
  167. wvsprintf(&ach[ARRAYSIZE(c_szTrace)-1], pszMsg, (va_list)(&pszMsg + 1));
  168. OutputDebugString(ach);
  169. OutputDebugString(c_szNewline);
  170. }
  171. }
  172. /*----------------------------------------------------------
  173. Purpose: Returns the string form of an known interface ID.
  174. Returns: String ptr
  175. Cond: --
  176. */
  177. LPCTSTR PUBLIC Dbg_GetRiidName(
  178. REFIID riid)
  179. {
  180. int i;
  181. for (i = 0; i < ARRAYSIZE(c_rgriidmap); i++)
  182. {
  183. if (IsEqualIID(riid, c_rgriidmap[i].riid))
  184. return c_rgriidmap[i].psz;
  185. }
  186. return TEXT("Unknown riid");
  187. }
  188. /*----------------------------------------------------------
  189. Purpose: Returns the string form of an scode given an hresult.
  190. Returns: String ptr
  191. Cond: --
  192. */
  193. LPCTSTR PUBLIC Dbg_GetScode(
  194. HRESULT hres)
  195. {
  196. int i;
  197. SCODE sc;
  198. sc = GetScode(hres);
  199. for (i = 0; i < ARRAYSIZE(c_rgscodemap); i++)
  200. {
  201. if (sc == c_rgscodemap[i].sc)
  202. return c_rgscodemap[i].psz;
  203. }
  204. return TEXT("Unknown scode");
  205. }
  206. /*----------------------------------------------------------
  207. Purpose: Returns a string safe enough to print...and I don't
  208. mean swear words.
  209. Returns: String ptr
  210. Cond: --
  211. */
  212. LPCTSTR PUBLIC Dbg_SafeStr(
  213. LPCTSTR psz)
  214. {
  215. if (psz)
  216. return psz;
  217. else
  218. return TEXT("NULL");
  219. }
  220. /*----------------------------------------------------------
  221. Purpose: Returns a string safe enough to print given an IDataObject.
  222. Returns: String ptr
  223. Cond: --
  224. */
  225. LPCTSTR PUBLIC Dbg_DataObjStr(
  226. LPDATAOBJECT pdtobj,
  227. LPTSTR pszBuf)
  228. {
  229. if (pdtobj)
  230. {
  231. DataObj_QueryPath(pdtobj, pszBuf);
  232. }
  233. else
  234. {
  235. lstrcpy(pszBuf, TEXT("NULL"));
  236. }
  237. return pszBuf;
  238. }
  239. #endif // DEBUG
  240. /*----------------------------------------------------------
  241. Purpose: This function maps the hresult to an hresult in the
  242. error table, and displays the corresponding string
  243. in a messagebox.
  244. Returns: return value of MessageBox
  245. Cond: --
  246. */
  247. int PUBLIC SEMsgBox(
  248. HWND hwnd,
  249. UINT idsCaption,
  250. HRESULT hres,
  251. PCSETBL pTable,
  252. UINT cArraySize) // Number of elements in table
  253. {
  254. PCSETBL p;
  255. PCSETBL pEnd;
  256. p = pTable;
  257. pEnd = &pTable[cArraySize-1];
  258. while (p != pEnd)
  259. {
  260. if (p->hres == hres)
  261. {
  262. return MsgBox(hwnd, MAKEINTRESOURCE(p->ids), MAKEINTRESOURCE(idsCaption),
  263. NULL, p->uStyle);
  264. }
  265. p++;
  266. }
  267. // Cover last entry
  268. if (p->hres == hres)
  269. {
  270. return MsgBox(hwnd, MAKEINTRESOURCE(p->ids), MAKEINTRESOURCE(idsCaption),
  271. NULL, p->uStyle);
  272. }
  273. return -1;
  274. }
  275. /*----------------------------------------------------------
  276. Purpose: Maps an hresult to a valid "official" hresult. This
  277. is necessary because the SYNCUI uses a FACILITY_TR
  278. which is only good for us, but unknown to the outside
  279. world.
  280. Returns: hresult
  281. Cond: --
  282. */
  283. HRESULT PUBLIC MapToOfficialHresult(
  284. HRESULT hres)
  285. {
  286. if (IS_ENGINE_ERROR(hres))
  287. {
  288. SCODE sc = GetScode(hres);
  289. if (E_TR_OUT_OF_MEMORY == sc)
  290. hres = ResultFromScode(E_OUTOFMEMORY);
  291. else
  292. hres = ResultFromScode(E_FAIL);
  293. }
  294. return hres;
  295. }