#pragma once /** * @Description: a class for convert SEH exception to c++ exception * @Author: shang_cm * @Date: 2020-06-01 16:09:00 * @LastEditTime: 2010-06-01 16:09:00 * @LastEditors: shang_cm */ #pragma once #include #include class seh_exception : std::exception { typedef ULONG(WINAPI* fpRtlNtStatusToDosError)(DWORD Status); public: seh_exception(unsigned int nExceptionCode, _EXCEPTION_POINTERS* pstExcptionInfor) : m_nExceptionCode(0), m_pExcptionInfor(NULL), m_szMsgBuff(NULL), m_hNtModule(NULL), RtlNtStatusToDosError(NULL) { m_nExceptionCode = nExceptionCode; m_pExcptionInfor = pstExcptionInfor; m_hNtModule = GetModuleHandle(L"NTDLL.DLL"); if (NULL != m_hNtModule) { RtlNtStatusToDosError = (fpRtlNtStatusToDosError)GetProcAddress(m_hNtModule, "RtlNtStatusToDosError"); } } virtual ~seh_exception() { m_nExceptionCode = 0; m_pExcptionInfor = NULL; RtlNtStatusToDosError = NULL; if (NULL != m_szMsgBuff) { LocalFree(m_szMsgBuff); m_szMsgBuff = NULL; } }; const char* what() const noexcept { if (RtlNtStatusToDosError != NULL) { DWORD nConvertLen = FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, m_hNtModule, RtlNtStatusToDosError(m_nExceptionCode), 0, (char*)&m_szMsgBuff, 0, NULL); if (0 != nConvertLen) { return m_szMsgBuff; } } return "SEH_UNKNOW_ERROR"; } const PEXCEPTION_POINTERS info() const { return m_pExcptionInfor; } const unsigned int code() const { return m_nExceptionCode; } private: HMODULE m_hNtModule; unsigned int m_nExceptionCode; char* m_szMsgBuff; PEXCEPTION_POINTERS m_pExcptionInfor; fpRtlNtStatusToDosError RtlNtStatusToDosError; public: static void(__cdecl TranslateSEHtoCE)(unsigned int nExceptionCode, struct _EXCEPTION_POINTERS* pstExcptionInfor) { throw seh_exception(nExceptionCode, pstExcptionInfor); } };