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.

528 lines
12 KiB

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