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.

751 lines
16 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. // Helper macro to override an error message until the
  17. // end of the current scope.
  18. //
  19. #define TEMP_ERROR_OVERRIDE(hr, nID)\
  20. CErrorOverride err##hr##to##nID##__LINE__(hr, nID)
  21. //
  22. // Slightly easier syntax to register a facility
  23. //
  24. #define REGISTER_FACILITY(dwCode, lpSource)\
  25. CError::RegisterFacility(dwCode, lpSource)
  26. //
  27. // Helper Function
  28. //
  29. COMDLL HRESULT GetLastHRESULT();
  30. typedef struct tagFACILITY
  31. {
  32. LPCTSTR lpszDll;
  33. UINT nTextID;
  34. } FACILITY;
  35. typedef CMap<DWORD, DWORD &, CString, CString &> CMapDWORDtoCString;
  36. typedef CMap<HRESULT, HRESULT &, UINT, UINT &> CMapHRESULTtoUINT;
  37. class COMDLL CError
  38. /*++
  39. Class Description:
  40. Error handling class, works for both HRESULT and old-style DWORD
  41. error codes. Construct with or assign a DWORD or HRESULT error
  42. return code, and the object can then be used to determine success
  43. or failure, and the object provides text for the error code either
  44. directly, in a message, or formatted with additional text. Also,
  45. the CError object understands the range of winsock errors and
  46. lanman errors, and looks for them in the appropriate places.
  47. The object can be referenced as a BOOL, a DWORD, an HRESULT, or
  48. a LPCTSTR as a success/failure, a WIN32 error, and HRESULT or
  49. the text equivalent respectively.
  50. Example of typical programme flow:
  51. //
  52. // Use IDS_MY_ERROR for access denied errors for the
  53. // duration of this scope.
  54. //
  55. TEMP_ERROR_OVERRIDE(ERROR_ACCESS_DENIED, IDS_MY_ERROR);
  56. CError err(FunctionWhichReturnsHresult());
  57. if (!err.MessageBoxOnFailure())
  58. {
  59. //
  60. // If we failed, this already displayed the error
  61. // message in a messagebox. Only when we succeed
  62. // we get here.
  63. //
  64. ... stuff ...
  65. }
  66. SomeWinApiWhichSetsLastError();
  67. err.GetLastWinError();
  68. if (err.Failed())
  69. {
  70. printf("WIN32 Error code %ld\nHRESULT %ld\nText: %s\n",
  71. (DWORD)err,
  72. (HRESULT)err,
  73. (LPCTSTR)err
  74. );
  75. }
  76. Public Interface:
  77. TextFromHRESULT : Convert HRESULT to text
  78. TextFromHRESULTExpand : Expand %h string to error text, %H to error code
  79. MessageBox : Display error in a messagebox
  80. MessageBoxFormat : Use %h string as format in messagebox
  81. MessageBoxOnFailure : Display message if error is a failure
  82. MessageBoxLastError : Display last error in a messagebox
  83. AddOverride : Add message override with string ID
  84. RemoveOverride : Remove message override
  85. RegisterFacility : Register facility
  86. UnregisterFacility : Unregister facility
  87. Succeeded : Determine if the error code indicates a success
  88. Failed : Determine if the error code indicates a failure
  89. CError : Constructors
  90. Reset : Reset error code
  91. GetLastWinError : Assign internal code to GetLastError
  92. SetLastWinError : Set last error from internal code
  93. operator = : Assignment operators
  94. operator == : Comparison operators
  95. operator != : Comparison operators
  96. operator HRESULT : Conversion operator
  97. operator DWORD : Conversion operator
  98. operator BOOL : Conversion operator
  99. operator LPCTSTR : Conversion operator
  100. --*/
  101. {
  102. #define IS_HRESULT(hr) (hr & 0xffff0000)
  103. #define REMOVE_OVERRIDE ((UINT)-1)
  104. #define NO_HELP_CONTEXT ((UINT)-1)
  105. #define USE_LAST_ERROR (TRUE)
  106. //
  107. // Private Internal FACILITY codes
  108. //
  109. #define FACILITY_WINSOCK (0xffe)
  110. #define FACILITY_LANMAN (0xfff)
  111. //
  112. // Static Helpers
  113. //
  114. public:
  115. //
  116. // Success/Failure determinants, works regardless
  117. // of whether hrCode is a DWORD or HRESULT
  118. //
  119. static BOOL Succeeded(HRESULT hrCode);
  120. static BOOL Failed(HRESULT hrCode);
  121. //
  122. // Convert to text
  123. //
  124. static HRESULT TextFromHRESULT(
  125. IN HRESULT hrCode,
  126. OUT LPTSTR szBuffer,
  127. OUT DWORD cchBuffer
  128. );
  129. //
  130. // As above, with a CString
  131. //
  132. static HRESULT TextFromHRESULT(
  133. IN HRESULT hrCode,
  134. OUT CString & strBuffer
  135. );
  136. //
  137. // Expand %h to error message from hrcode
  138. //
  139. static LPCTSTR TextFromHRESULTExpand(
  140. IN HRESULT hrCode,
  141. OUT LPTSTR szBuffer,
  142. OUT DWORD cchBuffer,
  143. OUT HRESULT * phResult = NULL
  144. );
  145. //
  146. // As above with CString
  147. //
  148. static LPCTSTR TextFromHRESULTExpand(
  149. IN HRESULT hrCode,
  150. OUT CString & strBuffer
  151. );
  152. //
  153. // Display text in error messagebox
  154. //
  155. static int MessageBox(
  156. IN HRESULT hrCode,
  157. IN UINT nType = MB_OK,
  158. IN UINT nHelpContext = NO_HELP_CONTEXT
  159. );
  160. //
  161. // Display last error in messagebox
  162. //
  163. static int MessageBoxLastError(
  164. IN UINT nType = MB_OK,
  165. IN UINT nHelpContext = NO_HELP_CONTEXT
  166. );
  167. //
  168. // Guarantee return is WIN32 error code
  169. //
  170. static DWORD Win32Error(HRESULT hrCode) { return HRESULT_CODE(hrCode); }
  171. //
  172. // Guarantee return is a true HRESULT
  173. //
  174. static HRESULT HResult(HRESULT hrCode) { return HRESULT_FROM_WIN32(hrCode); }
  175. //
  176. // Add override for specific error code.
  177. // Use -1 to remove the override. This function
  178. // will return the previous override (or -1)
  179. //
  180. static UINT AddOverride(
  181. IN HRESULT hrCode,
  182. IN UINT nMessage = REMOVE_OVERRIDE
  183. );
  184. static void RemoveOverride(
  185. IN HRESULT hrCode
  186. );
  187. static void RemoveAllOverrides();
  188. //
  189. // Register a DLL for a given facility code.
  190. // Use NULL to unregister the facility
  191. //
  192. static void RegisterFacility(
  193. IN DWORD dwFacility,
  194. IN LPCSTR lpDLL = NULL
  195. );
  196. static void UnregisterFacility(
  197. IN DWORD dwFacility
  198. );
  199. //
  200. // Constructor/Destructor
  201. //
  202. public:
  203. //
  204. // If constructed with TRUE, the object is initialized to
  205. // last error. It's set to ERROR_SUCCESS otherwise (default case)
  206. //
  207. CError(BOOL fUseLastError = FALSE);
  208. CError(HRESULT hrCode);
  209. CError(DWORD dwCode);
  210. ~CError();
  211. //
  212. // Helpers
  213. //
  214. public:
  215. BOOL Succeeded() const { return SUCCEEDED(m_hrCode); }
  216. BOOL Failed() const { return FAILED(m_hrCode); }
  217. HRESULT TextFromHRESULT(
  218. OUT LPTSTR szBuffer,
  219. OUT DWORD cchBuffer
  220. ) const;
  221. HRESULT TextFromHRESULT(
  222. OUT CString & strMsg
  223. );
  224. LPCTSTR TextFromHRESULTExpand(
  225. OUT LPTSTR szBuffer,
  226. OUT DWORD cchBuffer,
  227. OUT HRESULT * phResult = NULL
  228. );
  229. LPCTSTR TextFromHRESULTExpand(
  230. OUT CString & strBuffer
  231. );
  232. int MessageBox(
  233. IN UINT nType = MB_OK,
  234. IN UINT nHelpContext = NO_HELP_CONTEXT
  235. ) const;
  236. BOOL MessageBoxOnFailure(
  237. IN UINT nType = MB_OK,
  238. IN UINT nHelpContext = NO_HELP_CONTEXT
  239. ) const;
  240. int MessageBoxFormat(
  241. IN UINT nFmt,
  242. IN UINT nType,
  243. IN UINT nHelpContext,
  244. ...
  245. ) const;
  246. void Reset();
  247. void GetLastWinError();
  248. void SetLastWinError() const;
  249. DWORD Win32Error() const;
  250. HRESULT HResult() const { return m_hrCode; }
  251. //
  252. // Assignment Operators
  253. //
  254. public:
  255. const CError & operator =(HRESULT hr);
  256. const CError & operator =(const CError & err);
  257. //
  258. // Comparison Operators
  259. //
  260. public:
  261. const BOOL operator ==(HRESULT hr);
  262. const BOOL operator ==(CError & err);
  263. const BOOL operator !=(HRESULT hr);
  264. const BOOL operator !=(CError & err);
  265. //
  266. // Conversion Operators
  267. //
  268. public:
  269. operator const HRESULT() const { return m_hrCode; }
  270. operator const DWORD() const;
  271. operator const BOOL() const;
  272. operator LPCTSTR();
  273. #ifdef _DEBUG
  274. public:
  275. //
  276. // CDumpContext stream operator
  277. //
  278. inline friend CDumpContext & AFXAPI operator <<(
  279. IN OUT CDumpContext & dc,
  280. IN const CError & value
  281. )
  282. {
  283. return dc << (DWORD)value.m_hrCode;
  284. }
  285. #endif // _DEBUG
  286. protected:
  287. static HRESULT CvtToInternalFormat(HRESULT hrCode);
  288. //
  289. // Expand escape code
  290. //
  291. static BOOL ExpandEscapeCode(
  292. IN LPTSTR szBuffer,
  293. IN DWORD cchBuffer,
  294. OUT IN LPTSTR & lp,
  295. IN CString & strReplacement,
  296. OUT HRESULT & hr
  297. );
  298. //
  299. // Check for override message
  300. //
  301. static BOOL HasOverride(
  302. IN HRESULT hrCode,
  303. OUT UINT * pnMessage = NULL
  304. );
  305. //
  306. // Check for FACILITY dll
  307. //
  308. static LPCTSTR FindFacility(
  309. IN DWORD dwFacility
  310. );
  311. protected:
  312. friend BOOL InitErrorFunctionality();
  313. friend void TerminateErrorFunctionality();
  314. static BOOL AllocateStatics();
  315. static void DeAllocateStatics();
  316. static BOOL AreStaticsAllocated() { return s_fAllocated; }
  317. protected:
  318. static const TCHAR s_chEscape; // Escape character
  319. static const TCHAR s_chEscText; // Escape code for text
  320. static const TCHAR s_chEscNumber; // Escape code for error code
  321. static LPCTSTR s_cszLMDLL; // Lanman Message DLL
  322. static LPCTSTR s_cszWSDLL; // Winsock Message DLL
  323. static LPCTSTR s_cszFacility[]; // Facility Table
  324. static HRESULT s_cdwMinLMErr; // Lanman Error Range
  325. static HRESULT s_cdwMaxLMErr; // Lanman Error Range
  326. static HRESULT s_cdwMinWSErr; // Winsock Error Range
  327. static HRESULT s_cdwMaxWSErr; // Winsock Error Range
  328. static DWORD s_cdwFacilities; // Number of facility items
  329. //
  330. // Allocated objects
  331. //
  332. static CString * s_pstrDefError; // Default Error String
  333. static CString * s_pstrDefSuccs; // Default Success String
  334. static CMapDWORDtoCString * s_pmapFacilities;
  335. static CMapHRESULTtoUINT * s_pmapOverrides;
  336. static BOOL s_fAllocated;
  337. protected:
  338. const CError & Construct(HRESULT hr);
  339. const CError & Construct(const CError & err);
  340. private:
  341. HRESULT m_hrCode;
  342. CString * m_pstrBuff;
  343. };
  344. class COMDLL CErrorOverride
  345. /*++
  346. Class Description:
  347. Error override class -- restores the override on destructor
  348. see TEMP_ERROR_OVERRIDE macro below
  349. Public Interface:
  350. CErrorOverride : Constructor
  351. --*/
  352. {
  353. public:
  354. CErrorOverride(HRESULT hr, UINT nID);
  355. ~CErrorOverride();
  356. private:
  357. HRESULT m_hrCode;
  358. UINT m_nPrev;
  359. };
  360. //
  361. // Inline Expansions
  362. //
  363. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  364. inline HRESULT GetLastHRESULT()
  365. {
  366. return CError::HResult(::GetLastError());
  367. }
  368. inline /* static */ BOOL CError::Succeeded(HRESULT hrCode)
  369. {
  370. //
  371. // Works with either HRESULT or WIN32 error code
  372. //
  373. return IS_HRESULT(hrCode)
  374. ? SUCCEEDED(hrCode)
  375. : hrCode == ERROR_SUCCESS;
  376. }
  377. inline /* static */ BOOL CError::Failed(HRESULT hrCode)
  378. {
  379. //
  380. // Works with either HRESULT or WIN32 error code
  381. //
  382. return IS_HRESULT(hrCode)
  383. ? FAILED(hrCode)
  384. : hrCode != ERROR_SUCCESS;
  385. }
  386. inline /* static */ int MessageBoxLastError(
  387. IN UINT nType,
  388. IN UINT nHelpContext
  389. )
  390. {
  391. return CError::MessageBox(
  392. ::GetLastError(),
  393. nType,
  394. nHelpContext
  395. );
  396. }
  397. #if 0
  398. inline /* static */ DWORD CError::Win32Error(
  399. IN HRESULT hrCode
  400. )
  401. {
  402. return HRESULT_CODE(hrCode);
  403. }
  404. inline /* static */ HRESULT CError::HResult(
  405. IN HRESULT hrCode
  406. )
  407. {
  408. //
  409. // This will leave true HRESULTs intact
  410. //
  411. return HRESULT_FROM_WIN32(hrCode);
  412. }
  413. #endif // 0
  414. inline /* static */ void CError::RemoveOverride(
  415. IN HRESULT hrCode
  416. )
  417. {
  418. (void)CError::AddOverride(hrCode, REMOVE_OVERRIDE);
  419. }
  420. inline /* static */ void CError::UnregisterFacility(
  421. IN DWORD dwFacility
  422. )
  423. {
  424. RegisterFacility(dwFacility, NULL);
  425. }
  426. inline CError::CError(
  427. IN BOOL fUseLastError
  428. )
  429. : m_pstrBuff(NULL)
  430. {
  431. Construct(fUseLastError ? ::GetLastError() : ERROR_SUCCESS);
  432. }
  433. inline CError::CError(HRESULT hrCode)
  434. : m_pstrBuff(NULL)
  435. {
  436. Construct(hrCode);
  437. }
  438. inline CError::CError(DWORD dwCode)
  439. : m_pstrBuff(NULL)
  440. {
  441. Construct((HRESULT)dwCode);
  442. }
  443. inline HRESULT CError::TextFromHRESULT(
  444. OUT LPTSTR szBuffer,
  445. OUT DWORD cchBuffer
  446. ) const
  447. {
  448. return CError::TextFromHRESULT(m_hrCode, szBuffer, cchBuffer);
  449. }
  450. inline HRESULT CError::TextFromHRESULT(
  451. OUT CString & strBuffer
  452. )
  453. {
  454. return CError::TextFromHRESULT(m_hrCode, strBuffer);
  455. }
  456. inline LPCTSTR CError::TextFromHRESULTExpand(
  457. OUT LPTSTR szBuffer,
  458. OUT DWORD cchBuffer,
  459. OUT HRESULT * phResult
  460. )
  461. {
  462. return CError::TextFromHRESULTExpand(
  463. m_hrCode,
  464. szBuffer,
  465. cchBuffer,
  466. phResult
  467. );
  468. }
  469. inline LPCTSTR CError::TextFromHRESULTExpand(
  470. OUT CString & strBuffer
  471. )
  472. {
  473. return CError::TextFromHRESULTExpand(m_hrCode, strBuffer);
  474. }
  475. inline int CError::MessageBox(
  476. IN UINT nType,
  477. IN UINT nHelpContext
  478. ) const
  479. {
  480. return CError::MessageBox(m_hrCode, nType, nHelpContext);
  481. }
  482. inline DWORD CError::Win32Error() const
  483. {
  484. return CError::Win32Error(m_hrCode);
  485. }
  486. inline void CError::Reset()
  487. {
  488. m_hrCode = S_OK;
  489. }
  490. inline void CError::GetLastWinError()
  491. {
  492. Construct(::GetLastError());
  493. }
  494. inline void CError::SetLastWinError() const
  495. {
  496. ::SetLastError(Win32Error(m_hrCode));
  497. }
  498. inline const CError & CError::operator =(HRESULT hr)
  499. {
  500. return Construct(hr);
  501. }
  502. inline const CError & CError::operator =(const CError & err)
  503. {
  504. return Construct(err);
  505. }
  506. inline const BOOL CError::operator ==(HRESULT hr)
  507. {
  508. return m_hrCode == hr;
  509. }
  510. inline const BOOL CError::operator ==(CError & err)
  511. {
  512. return m_hrCode == err.m_hrCode;
  513. }
  514. inline const BOOL CError::operator !=(HRESULT hr)
  515. {
  516. return m_hrCode != hr;
  517. }
  518. inline const BOOL CError::operator !=(CError & err)
  519. {
  520. return m_hrCode != err.m_hrCode;
  521. }
  522. inline CError::operator const DWORD() const
  523. {
  524. return Win32Error();
  525. }
  526. inline CError::operator const BOOL() const
  527. {
  528. return Succeeded();
  529. }
  530. inline CErrorOverride::CErrorOverride(
  531. IN HRESULT hr,
  532. IN UINT nID
  533. )
  534. : m_hrCode(hr),
  535. m_nPrev(CError::AddOverride(hr, nID))
  536. {
  537. }
  538. inline CErrorOverride::~CErrorOverride()
  539. {
  540. //
  541. // Restore the old message
  542. //
  543. CError::AddOverride(m_hrCode, m_nPrev);
  544. }
  545. //
  546. // Clear text warning dialog
  547. //
  548. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  549. class COMDLL CClearTxtDlg : public CDialog
  550. {
  551. /*++
  552. Class Description:
  553. Dialog which displays the clear text warning
  554. Public Interface:
  555. CClearTxtDlg : Constructor
  556. --*/
  557. public:
  558. //
  559. // Constructor
  560. //
  561. CClearTxtDlg(CWnd * pParent = NULL);
  562. //
  563. // Dialog Data
  564. //
  565. protected:
  566. //{{AFX_DATA(CClearTxtDlg)
  567. enum { IDD = IDD_CLEARTEXTWARNING };
  568. //}}AFX_DATA
  569. //
  570. // Overrides
  571. //
  572. protected:
  573. // ClassWizard generated virtual function overrides
  574. //{{AFX_VIRTUAL(CClearTxtDlg)
  575. protected:
  576. virtual void DoDataExchange(CDataExchange * pDX);
  577. //}}AFX_VIRTUAL
  578. //
  579. // Implementation
  580. //
  581. protected:
  582. // Generated message map functions
  583. //{{AFX_MSG(CClearTxtDlg)
  584. virtual BOOL OnInitDialog();
  585. //}}AFX_MSG
  586. DECLARE_MESSAGE_MAP()
  587. };
  588. //
  589. // AfxMessageBox helpers
  590. //
  591. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  592. inline BOOL NoYesMessageBox(UINT nID)
  593. {
  594. return AfxMessageBox(nID, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2) == IDYES;
  595. }
  596. inline BOOL NoYesMessageBox(CString & str)
  597. {
  598. return AfxMessageBox(str, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2) == IDYES;
  599. }
  600. inline BOOL YesNoMessageBox(UINT nID)
  601. {
  602. return AfxMessageBox(nID, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1) == IDYES;
  603. }
  604. inline BOOL YesNoMessageBox(CString & str)
  605. {
  606. return AfxMessageBox(str, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1) == IDYES;
  607. }
  608. #endif // _MSG_H