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.

542 lines
18 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Filename : Excption.h
  4. // Purpose : To define the generic exception.
  5. //
  6. // Project : pqs
  7. // Component: Common
  8. //
  9. // Author : urib
  10. //
  11. // Log:
  12. // Jan 19 1997 urib Creation
  13. // Mar 2 1997 urib Add win32 error exception.
  14. // Jun 25 1997 urib Move definition of translator class to header.
  15. // Change name to CExceptionTranslatorSetter.
  16. // This is done because every thread needs to use
  17. // it as it enters our scope.
  18. // Sep 16 1997 urib Supply default parameter to CWin32ErrorException.
  19. // Oct 21 1997 urib Added macros to throw exceptions that know their
  20. // location.
  21. // Feb 12 1998 urib Print error information from within Hresult
  22. // Exception.
  23. // Feb 17 1998 urib Move translator code from cpp to header.
  24. // Jun 22 1998 yairh add GetFile & GetLine methods
  25. // Jul 19 1998 urib Specify calling convention on exception translator
  26. // function.
  27. // Aug 17 1998 urib Remove the ... catch clause.
  28. // Jan 10 1999 urib Support a throwing new.
  29. // Jan 21 1999 urib Fix THROW macros to force arguments to be WCHAR
  30. // string even in non UNICODE environment.
  31. // Feb 1 1999 urib Add null pointer exception. Add throwing new to
  32. // COM macros.
  33. // Mar 15 2000 urib Add missing "leaving function" trace.
  34. // Apr 12 2000 urib Move new manipulation to memory management module.
  35. // Sep 6 2000 urib Fix EnterLeave macros.
  36. // Oct 25 2000 urib Check allocation failure on Generic exception.
  37. //
  38. ////////////////////////////////////////////////////////////////////////////////
  39. #ifndef EXCPTION_H
  40. #define EXCPTION_H
  41. #include <eh.h>
  42. #include <stdexcpt.h>
  43. #include "Tracer.h"
  44. #include "AutoPtr.h"
  45. #include "FtfError.h"
  46. ////////////////////////////////////////////////////////////////////////////////
  47. //
  48. // CException class definition
  49. //
  50. ////////////////////////////////////////////////////////////////////////////////
  51. class CException
  52. {
  53. public:
  54. CException(PWSTR pwszFile = NULL, ULONG ulLine = 0)
  55. {
  56. m_pwszFile = pwszFile;
  57. m_ulLine = ulLine;
  58. Trace(
  59. elError,
  60. tagError,(
  61. "CException:"
  62. "on file %S, line %d",
  63. (pwszFile ? pwszFile :
  64. L"Fix this exception to return "
  65. L"a file and line"),
  66. ulLine));
  67. }
  68. // Get an error string.
  69. virtual
  70. BOOL GetErrorMessage(
  71. PWSTR pwszError,
  72. UINT nMaxError,
  73. PUINT pnHelpContext = NULL ) = NULL;
  74. #if 0
  75. // Notify via message box.
  76. virtual
  77. int ReportError(
  78. UINT nType = MB_OK,
  79. UINT nMessageID = 0 )
  80. {
  81. UNREFERENCED_PARAMETER(nMessageID);
  82. WCHAR rwchErrorString[1000];
  83. GetErrorMessage(rwchErrorString, 1000);
  84. return MessageBoxW(
  85. NULL,
  86. rwchErrorString,
  87. L"Exception occured",
  88. nType);
  89. }
  90. #endif
  91. virtual
  92. ~CException(){};
  93. PWSTR GetFile() { return m_pwszFile; }
  94. ULONG GetLine() { return m_ulLine; }
  95. virtual void PrintErrorMsg(
  96. char* pszFunction,
  97. ULONG_PTR dwThis,
  98. char* pszFile,
  99. int iLine,
  100. TAG tag = 0)
  101. {
  102. WCHAR rwchError[1000];
  103. GetErrorMessage(rwchError, sizeof(rwchError)/sizeof(WCHAR));
  104. Trace(
  105. elError,
  106. tag,(
  107. "COM Exception Catcher:"
  108. "%s (this = %#x) threw an exception. "
  109. "Error is message\"%S\". "
  110. "Caught in file %s line %d.",
  111. pszFunction,
  112. dwThis,
  113. rwchError,
  114. pszFile,
  115. iLine));
  116. }
  117. protected:
  118. PWSTR m_pwszFile;
  119. ULONG m_ulLine;
  120. };
  121. ////////////////////////////////////////////////////////////////////////////////
  122. //
  123. // CStructuredException class definition
  124. //
  125. ////////////////////////////////////////////////////////////////////////////////
  126. class CStructuredException : public CException
  127. {
  128. public:
  129. CStructuredException(UINT uiSeCode)
  130. :m_uiSeCode(uiSeCode){};
  131. // Get an error string.
  132. virtual
  133. BOOL GetErrorMessage(
  134. PWSTR pwszError,
  135. UINT nMaxError,
  136. PUINT pnHelpContext = NULL )
  137. {
  138. UNREFERENCED_PARAMETER(pnHelpContext);
  139. int iRet;
  140. iRet = _snwprintf(
  141. pwszError,
  142. nMaxError,
  143. L"Structured exception %#X",
  144. GetExceptionCode());
  145. pwszError[nMaxError - 1] = '\0';
  146. return iRet;
  147. }
  148. // Return the exception code.
  149. UINT
  150. GetExceptionCode()
  151. {
  152. return m_uiSeCode;
  153. }
  154. // The translator.
  155. static
  156. void _cdecl Translator(UINT ui, EXCEPTION_POINTERS*)
  157. {
  158. throw CStructuredException(ui);
  159. }
  160. private:
  161. UINT m_uiSeCode;
  162. };
  163. ////////////////////////////////////////////////////////////////////////////////
  164. //
  165. // CGenericException class definition
  166. //
  167. ////////////////////////////////////////////////////////////////////////////////
  168. class CGenericException : public CException
  169. {
  170. public:
  171. CGenericException(LPWSTR pwszTheError)
  172. {
  173. m_apwszTheError = _wcsdup(pwszTheError);
  174. if (!m_apwszTheError.IsValid())
  175. {
  176. m_apwszTheError =
  177. L"Memory allocation failed in the exception object creation";
  178. m_apwszTheError.Detach();
  179. }
  180. }
  181. // Get an error string.
  182. virtual
  183. BOOL GetErrorMessage(
  184. PWSTR pwszError,
  185. UINT nMaxError,
  186. PUINT pnHelpContext = NULL )
  187. {
  188. UNREFERENCED_PARAMETER(pnHelpContext);
  189. int iRet;
  190. iRet = _snwprintf(
  191. pwszError,
  192. nMaxError,
  193. L"%s",
  194. m_apwszTheError);
  195. pwszError[nMaxError - 1] = '\0';
  196. return iRet;
  197. }
  198. private:
  199. CAutoMallocPointer<WCHAR> m_apwszTheError;
  200. };
  201. ////////////////////////////////////////////////////////////////////////////////
  202. //
  203. // CHresultException class definition
  204. //
  205. ////////////////////////////////////////////////////////////////////////////////
  206. class CHresultException : public CException
  207. {
  208. public:
  209. CHresultException(HRESULT hrResult = E_FAIL,
  210. PWSTR pwszFile = NULL,
  211. ULONG ulLine = 0)
  212. :m_hrResult(hrResult), CException(pwszFile, ulLine)
  213. {
  214. WCHAR rwchError[1000];
  215. GetErrorMessage(rwchError, sizeof(rwchError)/sizeof(WCHAR));
  216. Trace(
  217. elError,
  218. tagError,(
  219. "Exception:"
  220. "%S",
  221. rwchError));
  222. }
  223. // Get an error string.
  224. virtual
  225. BOOL GetErrorMessage(
  226. PWSTR pwszError,
  227. UINT nMaxError,
  228. PUINT pnHelpContext = NULL )
  229. {
  230. UNREFERENCED_PARAMETER(pnHelpContext);
  231. int iRet;
  232. iRet = _snwprintf(
  233. pwszError,
  234. nMaxError,
  235. L"HResult exception %#X",
  236. m_hrResult);
  237. pwszError[nMaxError - 1] = '\0';
  238. return iRet;
  239. }
  240. operator HRESULT()
  241. {
  242. return m_hrResult;
  243. }
  244. virtual void PrintErrorMsg(
  245. char* pszFunction,
  246. ULONG_PTR dwThis,
  247. char* pszFile,
  248. int iLine,
  249. DWORD dwError,
  250. TAG tag = 0)
  251. {
  252. WCHAR rwchError[1000];
  253. GetErrorMessage(rwchError, sizeof(rwchError)/sizeof(WCHAR));
  254. Trace(
  255. elError,
  256. tag,(
  257. "COM Exception Catcher:"
  258. "%s (this = %#x) threw an hresult(%#x) exception. "
  259. "Error message is \"%S\". "
  260. "Caught in file %s line %d.",
  261. pszFunction,
  262. dwThis,
  263. dwError,
  264. rwchError,
  265. pszFile,
  266. iLine));
  267. }
  268. protected:
  269. HRESULT m_hrResult;
  270. };
  271. ////////////////////////////////////////////////////////////////////////////////
  272. //
  273. // CWin32ErrorException class definition
  274. //
  275. ////////////////////////////////////////////////////////////////////////////////
  276. class CWin32ErrorException : public CHresultException
  277. {
  278. public:
  279. CWin32ErrorException(LONG lResult = GetLastError(),
  280. PWSTR pwszFile = NULL,
  281. ULONG ulLine = 0)
  282. :CHresultException(MAKE_FTF_E(lResult), pwszFile, ulLine){}
  283. };
  284. ////////////////////////////////////////////////////////////////////////////////
  285. //
  286. // CMemoryException class definition
  287. //
  288. ////////////////////////////////////////////////////////////////////////////////
  289. class CMemoryException : public CWin32ErrorException
  290. {
  291. public:
  292. CMemoryException(PWSTR pwszFile = NULL, ULONG ulLine = 0)
  293. :CWin32ErrorException(E_OUTOFMEMORY, pwszFile, ulLine){};
  294. // Get an error string.
  295. virtual
  296. BOOL GetErrorMessage(
  297. PWSTR pwszError,
  298. UINT nMaxError,
  299. PUINT pnHelpContext = NULL )
  300. {
  301. UNREFERENCED_PARAMETER(pnHelpContext);
  302. int iRet;
  303. iRet = _snwprintf(pwszError, nMaxError, L"Memory exception !!!");
  304. pwszError[nMaxError - 1] = '\0';
  305. return iRet;
  306. }
  307. };
  308. ////////////////////////////////////////////////////////////////////////////////
  309. //
  310. // Macros for exception throwing and catching
  311. //
  312. ////////////////////////////////////////////////////////////////////////////////
  313. #define __PQWIDE(str) L##str
  314. #define PQWIDE(str) __PQWIDE(str)
  315. #define THROW_MEMORY_EXCEPTION() \
  316. throw CMemoryException(PQWIDE(__FILE__), __LINE__)
  317. #define THROW_HRESULT_EXCEPTION(hr) \
  318. throw CHresultException(hr, PQWIDE(__FILE__), __LINE__)
  319. #define THROW_WIN32ERROR_EXCEPTION(hr) \
  320. throw CWin32ErrorException(hr, PQWIDE(__FILE__), __LINE__)
  321. #if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
  322. class CEnterLeavePrinting
  323. {
  324. public:
  325. CEnterLeavePrinting(TAG tag, char* pszFuncName, void* pThisPointer)
  326. :m_tag(tag)
  327. ,m_pszFuncName(pszFuncName)
  328. ,m_pThisPointer(pThisPointer)
  329. {
  330. Trace(
  331. elVerbose,
  332. m_tag,(
  333. "Entering %s (this = %#x):",
  334. m_pszFuncName,
  335. pThisPointer));
  336. }
  337. ~CEnterLeavePrinting()
  338. {
  339. Trace(
  340. elVerbose,
  341. m_tag,(
  342. "Leaving %s (this = %#x):",
  343. m_pszFuncName,
  344. m_pThisPointer));
  345. }
  346. protected:
  347. TAG m_tag;
  348. char* m_pszFuncName;
  349. void* m_pThisPointer;
  350. };
  351. //
  352. // Use this macro at the beginning of an HRESULT COM method
  353. //
  354. #define BEGIN_STDMETHOD(function, tag) \
  355. CEnterLeavePrinting print(tag, #function, this); \
  356. try \
  357. {
  358. //
  359. // Use this macro at the end of an HRESULT COM method
  360. //
  361. #define END_STDMETHOD(function, tag) \
  362. } \
  363. catch(CHresultException& hre) \
  364. { \
  365. hre.PrintErrorMsg( \
  366. #function, \
  367. (ULONG_PTR)this, \
  368. __FILE__, \
  369. __LINE__, \
  370. (HRESULT)hre), \
  371. tag; \
  372. return hre; \
  373. } \
  374. catch(CException& e) \
  375. { \
  376. e.PrintErrorMsg( \
  377. #function, \
  378. (ULONG_PTR)this, \
  379. __FILE__, \
  380. __LINE__, \
  381. tag); \
  382. return E_FAIL; \
  383. }
  384. //
  385. // Use this macro at the end of a void COM method
  386. //
  387. #define END_VOIDMETHOD(function, tag) \
  388. } \
  389. catch(CHresultException& hre) \
  390. { \
  391. hre.PrintErrorMsg( \
  392. #function, \
  393. (ULONG_PTR)this, \
  394. __FILE__, \
  395. __LINE__, \
  396. tag, \
  397. (HRESULT)hre); \
  398. } \
  399. catch(CException& e) \
  400. { \
  401. e.PrintErrorMsg( \
  402. #function, \
  403. (ULONG_PTR)this, \
  404. __FILE__, \
  405. __LINE__, \
  406. tag \
  407. ); \
  408. }
  409. #else
  410. //
  411. // Use this macro at the beginning of an HRESULT COM method
  412. //
  413. #define BEGIN_STDMETHOD(function, tag) \
  414. try \
  415. {
  416. //
  417. // Use this macro at the end of an HRESULT COM method
  418. //
  419. #define END_STDMETHOD(function, tag) \
  420. } \
  421. catch(CHresultException& hre) \
  422. { \
  423. hre.PrintErrorMsg( \
  424. #function, \
  425. (ULONG_PTR)this, \
  426. __FILE__, \
  427. __LINE__, \
  428. (HRESULT)hre); \
  429. return hre; \
  430. } \
  431. catch(CException& e) \
  432. { \
  433. e.PrintErrorMsg( \
  434. #function, \
  435. (ULONG_PTR)this, \
  436. __FILE__, \
  437. __LINE__); \
  438. return E_FAIL; \
  439. }
  440. //
  441. // Use this macro at the end of a void COM method
  442. //
  443. #define END_VOIDMETHOD(function, tag) \
  444. } \
  445. catch(CHresultException& hre) \
  446. { \
  447. hre.PrintErrorMsg( \
  448. #function, \
  449. (ULONG_PTR)this, \
  450. __FILE__, \
  451. __LINE__, \
  452. (HRESULT)hre); \
  453. } \
  454. catch(CException& e) \
  455. { \
  456. e.PrintErrorMsg( \
  457. #function, \
  458. (ULONG_PTR)this, \
  459. __FILE__, \
  460. __LINE__); \
  461. }
  462. #endif // DEBUG
  463. #endif /* EXCPTION_H */