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.

533 lines
12 KiB

  1. /*++
  2. Copyright (c) 1994-2000 Microsoft Corporation
  3. Module Name :
  4. error.h
  5. Abstract:
  6. Message Functions Definitions
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Sergei Antonov (sergeia)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. 2/17/2000 sergeia removed dependency on MFC
  14. --*/
  15. #ifndef _ERROR_H
  16. #define _ERROR_H
  17. #pragma warning(disable:4786) // Disable warning for names > 256
  18. //
  19. // Slightly easier syntax to register a facility
  20. //
  21. #define REGISTER_FACILITY(dwCode, lpSource)\
  22. CError::RegisterFacility(dwCode, lpSource)
  23. //
  24. // Helper Function
  25. //
  26. HRESULT GetLastHRESULT();
  27. BOOL InitErrorFunctionality();
  28. void TerminateErrorFunctionality();
  29. typedef struct tagFACILITY
  30. {
  31. LPCTSTR lpszDll;
  32. UINT nTextID;
  33. } FACILITY;
  34. #pragma warning(disable : 4231)
  35. #pragma warning(disable : 4251)
  36. //typedef std::map<DWORD, CString> CMapDWORDtoCString;
  37. //typedef std::map<HRESULT, UINT> CMapHRESULTtoUINT;
  38. class CFacilityMap : public std::map<DWORD, CString>
  39. {
  40. };
  41. class COverridesMap : public std::map<HRESULT, UINT>
  42. {
  43. public:
  44. COverridesMap()
  45. {
  46. }
  47. ~COverridesMap()
  48. {
  49. }
  50. };
  51. class _EXPORT CError
  52. /*++
  53. Class Description:
  54. Error handling class, works for both HRESULT and old-style DWORD
  55. error codes. Construct with or assign a DWORD or HRESULT error
  56. return code, and the object can then be used to determine success
  57. or failure, and the object provides text for the error code either
  58. directly, in a message, or formatted with additional text. Also,
  59. the CError object understands the range of winsock errors and
  60. lanman errors, and looks for them in the appropriate places.
  61. The object can be referenced as a BOOL, a DWORD, an HRESULT, or
  62. a LPCTSTR as a success/failure, a WIN32 error, and HRESULT or
  63. the text equivalent respectively.
  64. Example of typical programme flow:
  65. CError err(FunctionWhichReturnsHresult());
  66. //
  67. // Use IDS_MY_ERROR for access denied errors for the
  68. // duration of this scope.
  69. //
  70. err.AddOverride(ERROR_ACCESS_DENIED, IDS_MY_ERROR);
  71. if (!err.MessageBoxOnFailure())
  72. {
  73. //
  74. // If we failed, this already displayed the error
  75. // message in a messagebox. Only when we succeed
  76. // we get here.
  77. //
  78. ... stuff ...
  79. }
  80. SomeWinApiWhichSetsLastError();
  81. err.GetLastWinError();
  82. if (err.Failed())
  83. {
  84. printf("WIN32 Error code %ld\nHRESULT %ld\nText: %s\n",
  85. (DWORD)err,
  86. (HRESULT)err,
  87. (LPCTSTR)err
  88. );
  89. }
  90. Public Interface:
  91. TextFromHRESULT : Convert HRESULT to text
  92. TextFromHRESULTExpand : Expand %h string to error text, %H to error code
  93. MessageBox : Display error in a messagebox
  94. MessageBoxFormat : Use %h string as format in messagebox
  95. MessageBoxOnFailure : Display message if error is a failure
  96. AddOverride : Add message override with string ID
  97. RemoveOverride : Remove message override
  98. RegisterFacility : Register facility
  99. UnregisterFacility : Unregister facility
  100. Succeeded : Determine if the error code indicates a success
  101. Failed : Determine if the error code indicates a failure
  102. CError : Constructors
  103. Reset : Reset error code
  104. GetLastWinError : Assign internal code to GetLastError
  105. SetLastWinError : Set last error from internal code
  106. operator = : Assignment operators
  107. operator == : Comparison operators
  108. operator != : Comparison operators
  109. operator LPOLESTR : Conversion operator
  110. operator LPCTSTR : Conversion operator
  111. operator HRESULT : Conversion operator
  112. operator DWORD : Conversion operator
  113. operator BOOL : Conversion operator
  114. --*/
  115. {
  116. #define IS_HRESULT(hr) (hr & 0xffff0000)
  117. #define REMOVE_OVERRIDE ((UINT)-1)
  118. #define NO_HELP_CONTEXT ((UINT)-1)
  119. #define USE_LAST_ERROR (TRUE)
  120. //
  121. // Private Internal FACILITY codes
  122. //
  123. #define FACILITY_WINSOCK (0xffe)
  124. #define FACILITY_LANMAN (0xfff)
  125. //
  126. // Static Helpers
  127. //
  128. public:
  129. //
  130. // Success/Failure determinants, works regardless
  131. // of whether hrCode is a DWORD or HRESULT
  132. //
  133. static BOOL Succeeded(HRESULT hrCode);
  134. static BOOL Failed(HRESULT hrCode);
  135. //
  136. // Guarantee return is WIN32 error code
  137. //
  138. static DWORD Win32Error(HRESULT hrCode) { return HRESULT_CODE(hrCode); }
  139. //
  140. // Guarantee return is a true HRESULT
  141. //
  142. static HRESULT HResult(HRESULT hrCode) { return HRESULT_FROM_WIN32(hrCode); }
  143. //
  144. // Register a DLL for a given facility code.
  145. // Use NULL to unregister the facility
  146. //
  147. static void RegisterFacility(
  148. IN DWORD dwFacility,
  149. IN LPCSTR lpDLL = NULL
  150. );
  151. static void UnregisterFacility(
  152. IN DWORD dwFacility
  153. );
  154. //
  155. // Constructor/Destructor
  156. //
  157. public:
  158. //
  159. // If constructed with TRUE, the object is initialized to
  160. // last error. It's set to ERROR_SUCCESS otherwise (default case)
  161. //
  162. CError();
  163. CError(HRESULT hrCode);
  164. CError(DWORD dwCode);
  165. ~CError();
  166. //
  167. // Helpers
  168. //
  169. public:
  170. BOOL Succeeded() const { return SUCCEEDED(m_hrCode); }
  171. BOOL Failed() const { return FAILED(m_hrCode); }
  172. HRESULT TextFromHRESULT(
  173. OUT LPTSTR szBuffer,
  174. OUT DWORD cchBuffer
  175. ) const;
  176. HRESULT TextFromHRESULT(
  177. OUT CString & strMsg
  178. ) const;
  179. LPCTSTR TextFromHRESULTExpand(
  180. OUT LPTSTR szBuffer,
  181. OUT DWORD cchBuffer,
  182. OUT HRESULT * phResult = NULL
  183. ) const;
  184. LPCTSTR TextFromHRESULTExpand(
  185. OUT CString & strBuffer
  186. ) const;
  187. int MessageBox(
  188. IN UINT nType = MB_OK | MB_ICONWARNING,
  189. IN UINT nHelpContext = NO_HELP_CONTEXT
  190. ) const;
  191. BOOL MessageBoxOnFailure(
  192. IN UINT nType = MB_OK | MB_ICONWARNING,
  193. IN UINT nHelpContext = NO_HELP_CONTEXT
  194. ) const;
  195. int MessageBoxFormat(
  196. IN HINSTANCE hInst,
  197. IN UINT nFmt,
  198. IN UINT nType,
  199. IN UINT nHelpContext,
  200. ...
  201. ) const;
  202. void Reset();
  203. void GetLastWinError();
  204. void SetLastWinError() const;
  205. DWORD Win32Error() const;
  206. HRESULT HResult() const { return m_hrCode; }
  207. //
  208. // Add override for specific error code.
  209. // Use -1 to remove the override. This function
  210. // will return the previous override (or -1)
  211. //
  212. UINT AddOverride(
  213. IN HRESULT hrCode,
  214. IN UINT nMessage = REMOVE_OVERRIDE
  215. );
  216. void RemoveOverride(
  217. IN HRESULT hrCode
  218. );
  219. void RemoveAllOverrides();
  220. protected:
  221. //
  222. // Expand escape code
  223. //
  224. BOOL ExpandEscapeCode(
  225. IN LPTSTR szBuffer,
  226. IN DWORD cchBuffer,
  227. OUT IN LPTSTR & lp,
  228. IN CString & strReplacement,
  229. OUT HRESULT & hr
  230. ) const;
  231. //
  232. // Check for override message
  233. //
  234. BOOL HasOverride(
  235. OUT UINT * pnMessage = NULL
  236. ) const;
  237. //
  238. // Assignment Operators
  239. //
  240. public:
  241. const CError & operator =(HRESULT hr);
  242. const CError & operator =(const CError & err);
  243. //
  244. // Comparison Operators
  245. //
  246. public:
  247. const BOOL operator ==(HRESULT hr);
  248. const BOOL operator ==(CError & err);
  249. const BOOL operator !=(HRESULT hr);
  250. const BOOL operator !=(CError & err);
  251. //
  252. // Conversion Operators
  253. //
  254. public:
  255. operator const HRESULT() const { return m_hrCode; }
  256. operator const DWORD() const;
  257. operator const BOOL() const;
  258. operator LPOLESTR();
  259. operator LPCTSTR();
  260. protected:
  261. static HRESULT CvtToInternalFormat(HRESULT hrCode);
  262. //
  263. // Check for FACILITY dll
  264. //
  265. static LPCTSTR FindFacility(
  266. IN DWORD dwFacility
  267. );
  268. protected:
  269. friend BOOL InitErrorFunctionality();
  270. friend void TerminateErrorFunctionality();
  271. static BOOL AllocateStatics();
  272. static void DeAllocateStatics();
  273. static BOOL AreStaticsAllocated();
  274. protected:
  275. static const TCHAR s_chEscape; // Escape character
  276. static const TCHAR s_chEscText; // Escape code for text
  277. static const TCHAR s_chEscNumber; // Escape code for error code
  278. static LPCTSTR s_cszLMDLL; // Lanman Message DLL
  279. static LPCTSTR s_cszWSDLL; // Winsock Message DLL
  280. static LPCTSTR s_cszFacility[]; // Facility Table
  281. static HRESULT s_cdwMinLMErr; // Lanman Error Range
  282. static HRESULT s_cdwMaxLMErr; // Lanman Error Range
  283. static HRESULT s_cdwMinWSErr; // Winsock Error Range
  284. static HRESULT s_cdwMaxWSErr; // Winsock Error Range
  285. static DWORD s_cdwFacilities; // Number of facility items
  286. //
  287. // Allocated objects
  288. //
  289. static CString * s_pstrDefError; // Default Error String
  290. static CString * s_pstrDefSuccs; // Default Success String
  291. static CFacilityMap * s_pmapFacilities;
  292. static BOOL s_fAllocated;
  293. protected:
  294. const CError & Construct(HRESULT hr);
  295. const CError & Construct(const CError & err);
  296. COverridesMap mapOverrides;
  297. private:
  298. HRESULT m_hrCode;
  299. CString m_str;
  300. };
  301. //
  302. // Inline Expansions
  303. //
  304. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  305. inline HRESULT GetLastHRESULT()
  306. {
  307. return CError::HResult(::GetLastError());
  308. }
  309. inline /* static */ BOOL CError::Succeeded(HRESULT hrCode)
  310. {
  311. //
  312. // Works with either HRESULT or WIN32 error code
  313. //
  314. return IS_HRESULT(hrCode)
  315. ? SUCCEEDED(hrCode)
  316. : hrCode == ERROR_SUCCESS;
  317. }
  318. inline /* static */ BOOL CError::Failed(HRESULT hrCode)
  319. {
  320. //
  321. // Works with either HRESULT or WIN32 error code
  322. //
  323. return IS_HRESULT(hrCode)
  324. ? FAILED(hrCode)
  325. : hrCode != ERROR_SUCCESS;
  326. }
  327. inline /* static */ void CError::UnregisterFacility(
  328. IN DWORD dwFacility
  329. )
  330. {
  331. RegisterFacility(dwFacility, NULL);
  332. }
  333. inline CError::CError()
  334. {
  335. Construct(S_OK);
  336. }
  337. inline CError::CError(HRESULT hrCode)
  338. {
  339. Construct(hrCode);
  340. }
  341. inline CError::CError(DWORD dwCode)
  342. {
  343. Construct((HRESULT)dwCode);
  344. }
  345. inline DWORD CError::Win32Error() const
  346. {
  347. return CError::Win32Error(m_hrCode);
  348. }
  349. inline void CError::Reset()
  350. {
  351. m_hrCode = S_OK;
  352. }
  353. inline void CError::GetLastWinError()
  354. {
  355. Construct(::GetLastError());
  356. }
  357. inline void CError::SetLastWinError() const
  358. {
  359. ::SetLastError(Win32Error(m_hrCode));
  360. }
  361. inline void CError::RemoveOverride(
  362. IN HRESULT hrCode
  363. )
  364. {
  365. (void)CError::AddOverride(hrCode, REMOVE_OVERRIDE);
  366. }
  367. inline const CError & CError::operator =(HRESULT hr)
  368. {
  369. return Construct(hr);
  370. }
  371. inline const CError & CError::operator =(const CError & err)
  372. {
  373. return Construct(err);
  374. }
  375. inline const BOOL CError::operator ==(HRESULT hr)
  376. {
  377. return m_hrCode == hr;
  378. }
  379. inline const BOOL CError::operator ==(CError & err)
  380. {
  381. return m_hrCode == err.m_hrCode;
  382. }
  383. inline const BOOL CError::operator !=(HRESULT hr)
  384. {
  385. return m_hrCode != hr;
  386. }
  387. inline const BOOL CError::operator !=(CError & err)
  388. {
  389. return m_hrCode != err.m_hrCode;
  390. }
  391. inline CError::operator const DWORD() const
  392. {
  393. return Win32Error();
  394. }
  395. inline CError::operator const BOOL() const
  396. {
  397. return Succeeded();
  398. }
  399. //inline CError::operator LPOLESTR()
  400. //{
  401. // TextFromHRESULT(m_str);
  402. // return m_str.c_str();
  403. //}
  404. inline CError::operator LPCTSTR()
  405. {
  406. TextFromHRESULT(m_str);
  407. return m_str;
  408. }
  409. //
  410. // AfxMessageBox helpers
  411. //
  412. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  413. inline BOOL NoYesMessageBox(CString& str)
  414. {
  415. CString strCaption;
  416. strCaption.LoadString(_Module.GetResourceInstance(), IDS_APP_TITLE);
  417. return ::MessageBox(::GetFocus(), str, strCaption, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2) == IDYES;
  418. }
  419. inline BOOL NoYesMessageBox(UINT nID)
  420. {
  421. CString strText;
  422. strText.LoadString(_Module.GetResourceInstance(), nID);
  423. return NoYesMessageBox(strText);
  424. }
  425. inline BOOL YesNoMessageBox(CString& str)
  426. {
  427. CString strCaption;
  428. strCaption.LoadString(_Module.GetResourceInstance(), IDS_APP_TITLE);
  429. return ::MessageBox(::GetFocus(), str, strCaption, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1) == IDYES;
  430. }
  431. inline BOOL YesNoMessageBox(UINT nID)
  432. {
  433. CString strText;
  434. strText.LoadString(_Module.GetResourceInstance(), nID);
  435. return YesNoMessageBox(strText);
  436. }
  437. #endif // _ERROR_H