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.

143 lines
2.9 KiB

  1. // dexception
  2. //
  3. // Exception class
  4. #pragma once
  5. #include "shtl.h"
  6. #include "tstring.h"
  7. using namespace std;
  8. class dexception
  9. {
  10. protected:
  11. enum
  12. {
  13. hresult, text, unknown
  14. } m_type;
  15. tstring m_text;
  16. HRESULT m_hr;
  17. public:
  18. virtual ~dexception()
  19. {}
  20. dexception() :
  21. m_type(unknown)
  22. {}
  23. dexception(const char * psz) :
  24. m_type(text),
  25. m_text(psz)
  26. {}
  27. dexception(const tstring& xs) :
  28. m_type(text),
  29. m_text(xs)
  30. {}
  31. dexception(const DWORD& dwError) :
  32. m_type(hresult),
  33. m_hr(HRESULT_FROM_WIN32(dwError))
  34. {}
  35. dexception(const HRESULT& hr) :
  36. m_type(hresult),
  37. m_hr(hr)
  38. {}
  39. operator const HRESULT() const
  40. {
  41. return (m_type == hresult) ? m_hr : E_UNEXPECTED;
  42. }
  43. tstring GetErrorText()
  44. {
  45. if (m_type == text)
  46. return m_text;
  47. if (m_text.length())
  48. return m_text;
  49. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  50. NULL,
  51. m_hr,
  52. LANG_USER_DEFAULT,
  53. m_text.GetBuffer(255),
  54. 255,
  55. NULL);
  56. m_text.ReleaseBuffer(-1);
  57. return m_text;
  58. }
  59. };
  60. // errorinfo_exception
  61. //
  62. // Exception class that knows how to set the last error for this
  63. // thread using the IErrorInfo object
  64. class errorinfo_exception : public dexception
  65. {
  66. private:
  67. CLSID m_clsid;
  68. IID m_iid;
  69. tstring m_str;
  70. public:
  71. errorinfo_exception(const tstring & str,
  72. const HRESULT & hr,
  73. const CLSID & clsid,
  74. const IID & iid)
  75. : dexception(hr),
  76. m_clsid(clsid),
  77. m_iid(iid),
  78. m_str(str)
  79. {
  80. ASSERT(FAILED(hr));
  81. }
  82. HRESULT ReportError() const
  83. {
  84. return AtlReportError(m_clsid, m_str, m_iid, m_hr);
  85. }
  86. };
  87. // win32error
  88. //
  89. // Exception class that looks at GetLastError. By default, will
  90. // use E_UNEXPECTED if GetLastError was not actually set by failing API.
  91. class win32error : public dexception
  92. {
  93. public:
  94. win32error(bool bEnsureFailure = true)
  95. {
  96. DWORD dwError = GetLastError();
  97. m_type = hresult;
  98. m_hr = (dwError || !bEnsureFailure) ? HRESULT_FROM_WIN32(dwError) : E_UNEXPECTED;
  99. }
  100. };
  101. // CATCH_AND_RETURN_AS_HRESULT
  102. //
  103. // Protects a block of code (such as an interface implementation) that can throw
  104. // our exceptions, and if it catches any, converts to an HRESULT and returns it
  105. // to the caller
  106. #define CATCH_AND_RETURN_AS_HRESULT \
  107. catch(const errorinfo_exception & e)\
  108. { \
  109. return e.ReportError(); \
  110. } \
  111. catch(const dexception & d) \
  112. { \
  113. return (HRESULT) d; \
  114. }