windows-nt/Source/XPSP1/NT/shell/ext/shtl/dexception.h
2020-09-26 16:20:57 +08:00

144 lines
2.9 KiB
C++

// dexception
//
// Exception class
#pragma once
#include "shtl.h"
#include "tstring.h"
using namespace std;
class dexception
{
protected:
enum
{
hresult, text, unknown
} m_type;
tstring m_text;
HRESULT m_hr;
public:
virtual ~dexception()
{}
dexception() :
m_type(unknown)
{}
dexception(const char * psz) :
m_type(text),
m_text(psz)
{}
dexception(const tstring& xs) :
m_type(text),
m_text(xs)
{}
dexception(const DWORD& dwError) :
m_type(hresult),
m_hr(HRESULT_FROM_WIN32(dwError))
{}
dexception(const HRESULT& hr) :
m_type(hresult),
m_hr(hr)
{}
operator const HRESULT() const
{
return (m_type == hresult) ? m_hr : E_UNEXPECTED;
}
tstring GetErrorText()
{
if (m_type == text)
return m_text;
if (m_text.length())
return m_text;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
m_hr,
LANG_USER_DEFAULT,
m_text.GetBuffer(255),
255,
NULL);
m_text.ReleaseBuffer(-1);
return m_text;
}
};
// errorinfo_exception
//
// Exception class that knows how to set the last error for this
// thread using the IErrorInfo object
class errorinfo_exception : public dexception
{
private:
CLSID m_clsid;
IID m_iid;
tstring m_str;
public:
errorinfo_exception(const tstring & str,
const HRESULT & hr,
const CLSID & clsid,
const IID & iid)
: dexception(hr),
m_clsid(clsid),
m_iid(iid),
m_str(str)
{
ASSERT(FAILED(hr));
}
HRESULT ReportError() const
{
return AtlReportError(m_clsid, m_str, m_iid, m_hr);
}
};
// win32error
//
// Exception class that looks at GetLastError. By default, will
// use E_UNEXPECTED if GetLastError was not actually set by failing API.
class win32error : public dexception
{
public:
win32error(bool bEnsureFailure = true)
{
DWORD dwError = GetLastError();
m_type = hresult;
m_hr = (dwError || !bEnsureFailure) ? HRESULT_FROM_WIN32(dwError) : E_UNEXPECTED;
}
};
// CATCH_AND_RETURN_AS_HRESULT
//
// Protects a block of code (such as an interface implementation) that can throw
// our exceptions, and if it catches any, converts to an HRESULT and returns it
// to the caller
#define CATCH_AND_RETURN_AS_HRESULT \
catch(const errorinfo_exception & e)\
{ \
return e.ReportError(); \
} \
catch(const dexception & d) \
{ \
return (HRESULT) d; \
}