752 lines
16 KiB
C++
752 lines
16 KiB
C++
/*++
|
|
|
|
Copyright (c) 1994-1998 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
msg.h
|
|
|
|
Abstract:
|
|
|
|
Message Functions Definitions
|
|
|
|
Author:
|
|
|
|
Ronald Meijer (ronaldm)
|
|
|
|
Project:
|
|
|
|
Internet Services Manager
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#ifndef _MSG_H
|
|
#define _MSG_H
|
|
|
|
|
|
//
|
|
// Helper macro to override an error message until the
|
|
// end of the current scope.
|
|
//
|
|
#define TEMP_ERROR_OVERRIDE(hr, nID)\
|
|
CErrorOverride err##hr##to##nID##__LINE__(hr, nID)
|
|
|
|
//
|
|
// Slightly easier syntax to register a facility
|
|
//
|
|
#define REGISTER_FACILITY(dwCode, lpSource)\
|
|
CError::RegisterFacility(dwCode, lpSource)
|
|
|
|
|
|
//
|
|
// Helper Function
|
|
//
|
|
COMDLL HRESULT GetLastHRESULT();
|
|
|
|
typedef struct tagFACILITY
|
|
{
|
|
LPCTSTR lpszDll;
|
|
UINT nTextID;
|
|
} FACILITY;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef CMap<DWORD, DWORD &, CString, CString &> CMapDWORDtoCString;
|
|
typedef CMap<HRESULT, HRESULT &, UINT, UINT &> CMapHRESULTtoUINT;
|
|
|
|
|
|
|
|
class COMDLL CError
|
|
/*++
|
|
|
|
Class Description:
|
|
|
|
Error handling class, works for both HRESULT and old-style DWORD
|
|
error codes. Construct with or assign a DWORD or HRESULT error
|
|
return code, and the object can then be used to determine success
|
|
or failure, and the object provides text for the error code either
|
|
directly, in a message, or formatted with additional text. Also,
|
|
the CError object understands the range of winsock errors and
|
|
lanman errors, and looks for them in the appropriate places.
|
|
The object can be referenced as a BOOL, a DWORD, an HRESULT, or
|
|
a LPCTSTR as a success/failure, a WIN32 error, and HRESULT or
|
|
the text equivalent respectively.
|
|
|
|
Example of typical programme flow:
|
|
|
|
//
|
|
// Use IDS_MY_ERROR for access denied errors for the
|
|
// duration of this scope.
|
|
//
|
|
TEMP_ERROR_OVERRIDE(ERROR_ACCESS_DENIED, IDS_MY_ERROR);
|
|
|
|
CError err(FunctionWhichReturnsHresult());
|
|
if (!err.MessageBoxOnFailure())
|
|
{
|
|
//
|
|
// If we failed, this already displayed the error
|
|
// message in a messagebox. Only when we succeed
|
|
// we get here.
|
|
//
|
|
... stuff ...
|
|
}
|
|
|
|
SomeWinApiWhichSetsLastError();
|
|
err.GetLastWinError();
|
|
if (err.Failed())
|
|
{
|
|
printf("WIN32 Error code %ld\nHRESULT %ld\nText: %s\n",
|
|
(DWORD)err,
|
|
(HRESULT)err,
|
|
(LPCTSTR)err
|
|
);
|
|
}
|
|
|
|
Public Interface:
|
|
|
|
TextFromHRESULT : Convert HRESULT to text
|
|
TextFromHRESULTExpand : Expand %h string to error text, %H to error code
|
|
MessageBox : Display error in a messagebox
|
|
MessageBoxFormat : Use %h string as format in messagebox
|
|
MessageBoxOnFailure : Display message if error is a failure
|
|
MessageBoxLastError : Display last error in a messagebox
|
|
AddOverride : Add message override with string ID
|
|
RemoveOverride : Remove message override
|
|
RegisterFacility : Register facility
|
|
UnregisterFacility : Unregister facility
|
|
Succeeded : Determine if the error code indicates a success
|
|
Failed : Determine if the error code indicates a failure
|
|
|
|
CError : Constructors
|
|
Reset : Reset error code
|
|
GetLastWinError : Assign internal code to GetLastError
|
|
SetLastWinError : Set last error from internal code
|
|
|
|
operator = : Assignment operators
|
|
operator == : Comparison operators
|
|
operator != : Comparison operators
|
|
operator HRESULT : Conversion operator
|
|
operator DWORD : Conversion operator
|
|
operator BOOL : Conversion operator
|
|
operator LPCTSTR : Conversion operator
|
|
|
|
--*/
|
|
{
|
|
#define IS_HRESULT(hr) (hr & 0xffff0000)
|
|
#define REMOVE_OVERRIDE ((UINT)-1)
|
|
#define NO_HELP_CONTEXT ((UINT)-1)
|
|
#define USE_LAST_ERROR (TRUE)
|
|
|
|
//
|
|
// Private Internal FACILITY codes
|
|
//
|
|
#define FACILITY_WINSOCK (0xffe)
|
|
#define FACILITY_LANMAN (0xfff)
|
|
|
|
//
|
|
// Static Helpers
|
|
//
|
|
public:
|
|
//
|
|
// Success/Failure determinants, works regardless
|
|
// of whether hrCode is a DWORD or HRESULT
|
|
//
|
|
static BOOL Succeeded(HRESULT hrCode);
|
|
static BOOL Failed(HRESULT hrCode);
|
|
|
|
//
|
|
// Convert to text
|
|
//
|
|
static HRESULT TextFromHRESULT(
|
|
IN HRESULT hrCode,
|
|
OUT LPTSTR szBuffer,
|
|
OUT DWORD cchBuffer
|
|
);
|
|
|
|
//
|
|
// As above, with a CString
|
|
//
|
|
static HRESULT TextFromHRESULT(
|
|
IN HRESULT hrCode,
|
|
OUT CString & strBuffer
|
|
);
|
|
|
|
//
|
|
// Expand %h to error message from hrcode
|
|
//
|
|
static LPCTSTR TextFromHRESULTExpand(
|
|
IN HRESULT hrCode,
|
|
OUT LPTSTR szBuffer,
|
|
OUT DWORD cchBuffer,
|
|
OUT HRESULT * phResult = NULL
|
|
);
|
|
|
|
//
|
|
// As above with CString
|
|
//
|
|
static LPCTSTR TextFromHRESULTExpand(
|
|
IN HRESULT hrCode,
|
|
OUT CString & strBuffer
|
|
);
|
|
|
|
//
|
|
// Display text in error messagebox
|
|
//
|
|
static int MessageBox(
|
|
IN HRESULT hrCode,
|
|
IN UINT nType = MB_OK,
|
|
IN UINT nHelpContext = NO_HELP_CONTEXT
|
|
);
|
|
|
|
//
|
|
// Display last error in messagebox
|
|
//
|
|
static int MessageBoxLastError(
|
|
IN UINT nType = MB_OK,
|
|
IN UINT nHelpContext = NO_HELP_CONTEXT
|
|
);
|
|
|
|
//
|
|
// Guarantee return is WIN32 error code
|
|
//
|
|
static DWORD Win32Error(HRESULT hrCode) { return HRESULT_CODE(hrCode); }
|
|
|
|
//
|
|
// Guarantee return is a true HRESULT
|
|
//
|
|
static HRESULT HResult(HRESULT hrCode) { return HRESULT_FROM_WIN32(hrCode); }
|
|
|
|
//
|
|
// Add override for specific error code.
|
|
// Use -1 to remove the override. This function
|
|
// will return the previous override (or -1)
|
|
//
|
|
static UINT AddOverride(
|
|
IN HRESULT hrCode,
|
|
IN UINT nMessage = REMOVE_OVERRIDE
|
|
);
|
|
|
|
static void RemoveOverride(
|
|
IN HRESULT hrCode
|
|
);
|
|
|
|
static void RemoveAllOverrides();
|
|
|
|
//
|
|
// Register a DLL for a given facility code.
|
|
// Use NULL to unregister the facility
|
|
//
|
|
static void RegisterFacility(
|
|
IN DWORD dwFacility,
|
|
IN LPCSTR lpDLL = NULL
|
|
);
|
|
|
|
static void UnregisterFacility(
|
|
IN DWORD dwFacility
|
|
);
|
|
|
|
//
|
|
// Constructor/Destructor
|
|
//
|
|
public:
|
|
//
|
|
// If constructed with TRUE, the object is initialized to
|
|
// last error. It's set to ERROR_SUCCESS otherwise (default case)
|
|
//
|
|
CError(BOOL fUseLastError = FALSE);
|
|
CError(HRESULT hrCode);
|
|
CError(DWORD dwCode);
|
|
~CError();
|
|
|
|
//
|
|
// Helpers
|
|
//
|
|
public:
|
|
BOOL Succeeded() const { return SUCCEEDED(m_hrCode); }
|
|
BOOL Failed() const { return FAILED(m_hrCode); }
|
|
|
|
HRESULT TextFromHRESULT(
|
|
OUT LPTSTR szBuffer,
|
|
OUT DWORD cchBuffer
|
|
) const;
|
|
|
|
HRESULT TextFromHRESULT(
|
|
OUT CString & strMsg
|
|
);
|
|
|
|
LPCTSTR TextFromHRESULTExpand(
|
|
OUT LPTSTR szBuffer,
|
|
OUT DWORD cchBuffer,
|
|
OUT HRESULT * phResult = NULL
|
|
);
|
|
|
|
LPCTSTR TextFromHRESULTExpand(
|
|
OUT CString & strBuffer
|
|
);
|
|
|
|
int MessageBox(
|
|
IN UINT nType = MB_OK,
|
|
IN UINT nHelpContext = NO_HELP_CONTEXT
|
|
) const;
|
|
|
|
BOOL MessageBoxOnFailure(
|
|
IN UINT nType = MB_OK,
|
|
IN UINT nHelpContext = NO_HELP_CONTEXT
|
|
) const;
|
|
|
|
int MessageBoxFormat(
|
|
IN UINT nFmt,
|
|
IN UINT nType,
|
|
IN UINT nHelpContext,
|
|
...
|
|
) const;
|
|
|
|
void Reset();
|
|
void GetLastWinError();
|
|
void SetLastWinError() const;
|
|
DWORD Win32Error() const;
|
|
HRESULT HResult() const { return m_hrCode; }
|
|
|
|
//
|
|
// Assignment Operators
|
|
//
|
|
public:
|
|
const CError & operator =(HRESULT hr);
|
|
const CError & operator =(const CError & err);
|
|
|
|
//
|
|
// Comparison Operators
|
|
//
|
|
public:
|
|
const BOOL operator ==(HRESULT hr);
|
|
const BOOL operator ==(CError & err);
|
|
const BOOL operator !=(HRESULT hr);
|
|
const BOOL operator !=(CError & err);
|
|
|
|
//
|
|
// Conversion Operators
|
|
//
|
|
public:
|
|
operator const HRESULT() const { return m_hrCode; }
|
|
operator const DWORD() const;
|
|
operator const BOOL() const;
|
|
operator LPCTSTR();
|
|
|
|
#ifdef _DEBUG
|
|
|
|
public:
|
|
//
|
|
// CDumpContext stream operator
|
|
//
|
|
inline friend CDumpContext & AFXAPI operator <<(
|
|
IN OUT CDumpContext & dc,
|
|
IN const CError & value
|
|
)
|
|
{
|
|
return dc << (DWORD)value.m_hrCode;
|
|
}
|
|
|
|
#endif // _DEBUG
|
|
|
|
protected:
|
|
static HRESULT CvtToInternalFormat(HRESULT hrCode);
|
|
|
|
//
|
|
// Expand escape code
|
|
//
|
|
static BOOL ExpandEscapeCode(
|
|
IN LPTSTR szBuffer,
|
|
IN DWORD cchBuffer,
|
|
OUT IN LPTSTR & lp,
|
|
IN CString & strReplacement,
|
|
OUT HRESULT & hr
|
|
);
|
|
|
|
//
|
|
// Check for override message
|
|
//
|
|
static BOOL HasOverride(
|
|
IN HRESULT hrCode,
|
|
OUT UINT * pnMessage = NULL
|
|
);
|
|
|
|
//
|
|
// Check for FACILITY dll
|
|
//
|
|
static LPCTSTR FindFacility(
|
|
IN DWORD dwFacility
|
|
);
|
|
|
|
protected:
|
|
friend BOOL InitErrorFunctionality();
|
|
friend void TerminateErrorFunctionality();
|
|
static BOOL AllocateStatics();
|
|
static void DeAllocateStatics();
|
|
static BOOL AreStaticsAllocated() { return s_fAllocated; }
|
|
|
|
protected:
|
|
static const TCHAR s_chEscape; // Escape character
|
|
static const TCHAR s_chEscText; // Escape code for text
|
|
static const TCHAR s_chEscNumber; // Escape code for error code
|
|
static LPCTSTR s_cszLMDLL; // Lanman Message DLL
|
|
static LPCTSTR s_cszWSDLL; // Winsock Message DLL
|
|
static LPCTSTR s_cszFacility[]; // Facility Table
|
|
static HRESULT s_cdwMinLMErr; // Lanman Error Range
|
|
static HRESULT s_cdwMaxLMErr; // Lanman Error Range
|
|
static HRESULT s_cdwMinWSErr; // Winsock Error Range
|
|
static HRESULT s_cdwMaxWSErr; // Winsock Error Range
|
|
static DWORD s_cdwFacilities; // Number of facility items
|
|
|
|
//
|
|
// Allocated objects
|
|
//
|
|
static CString * s_pstrDefError; // Default Error String
|
|
static CString * s_pstrDefSuccs; // Default Success String
|
|
static CMapDWORDtoCString * s_pmapFacilities;
|
|
static CMapHRESULTtoUINT * s_pmapOverrides;
|
|
static BOOL s_fAllocated;
|
|
|
|
protected:
|
|
const CError & Construct(HRESULT hr);
|
|
const CError & Construct(const CError & err);
|
|
|
|
private:
|
|
HRESULT m_hrCode;
|
|
CString * m_pstrBuff;
|
|
};
|
|
|
|
|
|
|
|
class COMDLL CErrorOverride
|
|
/*++
|
|
|
|
Class Description:
|
|
|
|
Error override class -- restores the override on destructor
|
|
see TEMP_ERROR_OVERRIDE macro below
|
|
|
|
Public Interface:
|
|
|
|
CErrorOverride : Constructor
|
|
|
|
--*/
|
|
{
|
|
public:
|
|
CErrorOverride(HRESULT hr, UINT nID);
|
|
~CErrorOverride();
|
|
|
|
private:
|
|
HRESULT m_hrCode;
|
|
UINT m_nPrev;
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// Inline Expansions
|
|
//
|
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
|
|
inline HRESULT GetLastHRESULT()
|
|
{
|
|
return CError::HResult(::GetLastError());
|
|
}
|
|
|
|
inline /* static */ BOOL CError::Succeeded(HRESULT hrCode)
|
|
{
|
|
//
|
|
// Works with either HRESULT or WIN32 error code
|
|
//
|
|
return IS_HRESULT(hrCode)
|
|
? SUCCEEDED(hrCode)
|
|
: hrCode == ERROR_SUCCESS;
|
|
}
|
|
|
|
inline /* static */ BOOL CError::Failed(HRESULT hrCode)
|
|
{
|
|
//
|
|
// Works with either HRESULT or WIN32 error code
|
|
//
|
|
return IS_HRESULT(hrCode)
|
|
? FAILED(hrCode)
|
|
: hrCode != ERROR_SUCCESS;
|
|
}
|
|
|
|
inline /* static */ int MessageBoxLastError(
|
|
IN UINT nType,
|
|
IN UINT nHelpContext
|
|
)
|
|
{
|
|
return CError::MessageBox(
|
|
::GetLastError(),
|
|
nType,
|
|
nHelpContext
|
|
);
|
|
}
|
|
|
|
#if 0
|
|
|
|
inline /* static */ DWORD CError::Win32Error(
|
|
IN HRESULT hrCode
|
|
)
|
|
{
|
|
return HRESULT_CODE(hrCode);
|
|
}
|
|
|
|
inline /* static */ HRESULT CError::HResult(
|
|
IN HRESULT hrCode
|
|
)
|
|
{
|
|
//
|
|
// This will leave true HRESULTs intact
|
|
//
|
|
return HRESULT_FROM_WIN32(hrCode);
|
|
}
|
|
#endif // 0
|
|
|
|
inline /* static */ void CError::RemoveOverride(
|
|
IN HRESULT hrCode
|
|
)
|
|
{
|
|
(void)CError::AddOverride(hrCode, REMOVE_OVERRIDE);
|
|
}
|
|
|
|
inline /* static */ void CError::UnregisterFacility(
|
|
IN DWORD dwFacility
|
|
)
|
|
{
|
|
RegisterFacility(dwFacility, NULL);
|
|
}
|
|
|
|
inline CError::CError(
|
|
IN BOOL fUseLastError
|
|
)
|
|
: m_pstrBuff(NULL)
|
|
{
|
|
Construct(fUseLastError ? ::GetLastError() : ERROR_SUCCESS);
|
|
}
|
|
|
|
inline CError::CError(HRESULT hrCode)
|
|
: m_pstrBuff(NULL)
|
|
{
|
|
Construct(hrCode);
|
|
}
|
|
|
|
inline CError::CError(DWORD dwCode)
|
|
: m_pstrBuff(NULL)
|
|
{
|
|
Construct((HRESULT)dwCode);
|
|
}
|
|
|
|
inline HRESULT CError::TextFromHRESULT(
|
|
OUT LPTSTR szBuffer,
|
|
OUT DWORD cchBuffer
|
|
) const
|
|
{
|
|
return CError::TextFromHRESULT(m_hrCode, szBuffer, cchBuffer);
|
|
}
|
|
|
|
inline HRESULT CError::TextFromHRESULT(
|
|
OUT CString & strBuffer
|
|
)
|
|
{
|
|
return CError::TextFromHRESULT(m_hrCode, strBuffer);
|
|
}
|
|
|
|
inline LPCTSTR CError::TextFromHRESULTExpand(
|
|
OUT LPTSTR szBuffer,
|
|
OUT DWORD cchBuffer,
|
|
OUT HRESULT * phResult
|
|
)
|
|
{
|
|
return CError::TextFromHRESULTExpand(
|
|
m_hrCode,
|
|
szBuffer,
|
|
cchBuffer,
|
|
phResult
|
|
);
|
|
}
|
|
|
|
inline LPCTSTR CError::TextFromHRESULTExpand(
|
|
OUT CString & strBuffer
|
|
)
|
|
{
|
|
return CError::TextFromHRESULTExpand(m_hrCode, strBuffer);
|
|
}
|
|
|
|
inline int CError::MessageBox(
|
|
IN UINT nType,
|
|
IN UINT nHelpContext
|
|
) const
|
|
{
|
|
return CError::MessageBox(m_hrCode, nType, nHelpContext);
|
|
}
|
|
|
|
inline DWORD CError::Win32Error() const
|
|
{
|
|
return CError::Win32Error(m_hrCode);
|
|
}
|
|
|
|
inline void CError::Reset()
|
|
{
|
|
m_hrCode = S_OK;
|
|
}
|
|
|
|
inline void CError::GetLastWinError()
|
|
{
|
|
Construct(::GetLastError());
|
|
}
|
|
|
|
inline void CError::SetLastWinError() const
|
|
{
|
|
::SetLastError(Win32Error(m_hrCode));
|
|
}
|
|
|
|
inline const CError & CError::operator =(HRESULT hr)
|
|
{
|
|
return Construct(hr);
|
|
}
|
|
|
|
inline const CError & CError::operator =(const CError & err)
|
|
{
|
|
return Construct(err);
|
|
}
|
|
|
|
inline const BOOL CError::operator ==(HRESULT hr)
|
|
{
|
|
return m_hrCode == hr;
|
|
}
|
|
|
|
inline const BOOL CError::operator ==(CError & err)
|
|
{
|
|
return m_hrCode == err.m_hrCode;
|
|
}
|
|
|
|
inline const BOOL CError::operator !=(HRESULT hr)
|
|
{
|
|
return m_hrCode != hr;
|
|
}
|
|
|
|
inline const BOOL CError::operator !=(CError & err)
|
|
{
|
|
return m_hrCode != err.m_hrCode;
|
|
}
|
|
|
|
inline CError::operator const DWORD() const
|
|
{
|
|
return Win32Error();
|
|
}
|
|
|
|
inline CError::operator const BOOL() const
|
|
{
|
|
return Succeeded();
|
|
}
|
|
|
|
inline CErrorOverride::CErrorOverride(
|
|
IN HRESULT hr,
|
|
IN UINT nID
|
|
)
|
|
: m_hrCode(hr),
|
|
m_nPrev(CError::AddOverride(hr, nID))
|
|
{
|
|
}
|
|
|
|
inline CErrorOverride::~CErrorOverride()
|
|
{
|
|
//
|
|
// Restore the old message
|
|
//
|
|
CError::AddOverride(m_hrCode, m_nPrev);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Clear text warning dialog
|
|
//
|
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
|
|
|
|
|
|
class COMDLL CClearTxtDlg : public CDialog
|
|
{
|
|
/*++
|
|
|
|
Class Description:
|
|
|
|
Dialog which displays the clear text warning
|
|
|
|
Public Interface:
|
|
|
|
CClearTxtDlg : Constructor
|
|
|
|
--*/
|
|
public:
|
|
//
|
|
// Constructor
|
|
//
|
|
CClearTxtDlg(CWnd * pParent = NULL);
|
|
|
|
//
|
|
// Dialog Data
|
|
//
|
|
protected:
|
|
//{{AFX_DATA(CClearTxtDlg)
|
|
enum { IDD = IDD_CLEARTEXTWARNING };
|
|
//}}AFX_DATA
|
|
|
|
//
|
|
// Overrides
|
|
//
|
|
protected:
|
|
// ClassWizard generated virtual function overrides
|
|
//{{AFX_VIRTUAL(CClearTxtDlg)
|
|
protected:
|
|
virtual void DoDataExchange(CDataExchange * pDX);
|
|
//}}AFX_VIRTUAL
|
|
|
|
//
|
|
// Implementation
|
|
//
|
|
protected:
|
|
// Generated message map functions
|
|
//{{AFX_MSG(CClearTxtDlg)
|
|
virtual BOOL OnInitDialog();
|
|
//}}AFX_MSG
|
|
DECLARE_MESSAGE_MAP()
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// AfxMessageBox helpers
|
|
//
|
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
|
|
inline BOOL NoYesMessageBox(UINT nID)
|
|
{
|
|
return AfxMessageBox(nID, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2) == IDYES;
|
|
}
|
|
|
|
inline BOOL NoYesMessageBox(CString & str)
|
|
{
|
|
return AfxMessageBox(str, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2) == IDYES;
|
|
}
|
|
|
|
inline BOOL YesNoMessageBox(UINT nID)
|
|
{
|
|
return AfxMessageBox(nID, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1) == IDYES;
|
|
}
|
|
|
|
inline BOOL YesNoMessageBox(CString & str)
|
|
{
|
|
return AfxMessageBox(str, MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1) == IDYES;
|
|
}
|
|
|
|
#endif // _MSG_H
|