#if !defined(_FUSION_INC_SXSEXCEPTIONHANDLING_H_INCLUDED_) #define _FUSION_INC_SXSEXCEPTIONHANDLING_H_INCLUDED_ /*++ Copyright (c) 2000 Microsoft Corporation Module Name: SxsExceptionHandling.h Abstract: Author: Jay Krell (a-JayK) October 2000 Revision History: --*/ #pragma once #include "nt.h" #include "ntrtl.h" #include "nturtl.h" #include "windows.h" #include "fusionlastwin32error.h" #include "fusionntdll.h" #include "fusiontrace.h" #include "csxspreservelasterror.h" // Most destructors should use this. #include "fusionheap.h" /*----------------------------------------------------------------------------- Instead of: __except(EXECEPTION_EXECUTE_HANDLER) say: __except(SXSP_EXCEPTION_FILTER()) This way all exceptions will be logged with DbgPrint, and probably hit a breakpoint if under a debugger, and any other behavior we want. If your exception filter is other than (EXECEPTION_EXECUTE_HANDLER), then you are on your own. -----------------------------------------------------------------------------*/ INT SxspExceptionFilter( PEXCEPTION_POINTERS ExceptionPointers, PCSTR Function ); #define SXSP_EXCEPTION_FILTER() (::SxspExceptionFilter(GetExceptionInformation(), __FUNCTION__)) #define SXS_REPORT_SEH_EXCEPTION(string) \ __try \ { \ if (::FusionpReportConditionAndBreak(NULL, "SXS.DLL: " __FUNCTION__ " - Unhandled exception caught: 0x%08lx", GetExceptionCode())) \ FUSION_DEBUG_BREAK(); \ } \ __except(EXCEPTION_EXECUTE_HANDLER) { } class CCriticalSectionNoConstructor : public CRITICAL_SECTION { void operator=(const CCriticalSectionNoConstructor&); // deliberately not implemented //CCriticalSectionNoConstructor(const CCriticalSectionNoConstructor&); // deliberately not implemented public: BOOL Construct(); BOOL ConstructWithSEH(PCSTR Function = ""); BOOL Destruct(); }; inline BOOL CCriticalSectionNoConstructor::Construct() { ::InitializeCriticalSection(this); return TRUE; } inline BOOL CCriticalSectionNoConstructor::Destruct() { ::DeleteCriticalSection(this); return TRUE; } inline BOOL CCriticalSectionNoConstructor::ConstructWithSEH( PCSTR /* Function */) { BOOL Result = FALSE; DWORD dwWin32Error; __try { if (!this->Construct()) goto Exit; } __except(SXSP_EXCEPTION_FILTER()) { SXS_REPORT_SEH_EXCEPTION(""); #if FUSION_STATIC_NTDLL dwWin32Error = ::RtlNtStatusToDosErrorNoTeb(GetExceptionCode()); #else dwWin32Error = ERROR_OUTOFMEMORY; #endif ::FusionpSetLastWin32Error(dwWin32Error); goto Exit; } Result = TRUE; Exit: return Result; } class CSxsLockCriticalSection { public: CSxsLockCriticalSection(CRITICAL_SECTION &rcs) : m_rcs(rcs), m_fIsLocked(false) { } BOOL Lock(); BOOL TryLock(); BOOL LockWithSEH(); ~CSxsLockCriticalSection() { if (m_fIsLocked) { CSxsPreserveLastError ple; ::LeaveCriticalSection(&m_rcs); ple.Restore(); } } BOOL Unlock(); protected: CRITICAL_SECTION &m_rcs; bool m_fIsLocked; private: void operator=(const CSxsLockCriticalSection&); CSxsLockCriticalSection(const CSxsLockCriticalSection&); }; inline BOOL CSxsLockCriticalSection::Lock() { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); INTERNAL_ERROR_CHECK(!m_fIsLocked); ::EnterCriticalSection(&m_rcs); m_fIsLocked = true; fSuccess = TRUE; Exit: return fSuccess; } inline BOOL CSxsLockCriticalSection::LockWithSEH() { BOOL fSuccess = FALSE; DWORD dwWin32Error; // We can't use the spiffy macros in the same frame as a __try block. ASSERT_NTC(!m_fIsLocked); if (m_fIsLocked) { ::FusionpSetLastWin32Error(ERROR_INTERNAL_ERROR); goto Exit; } __try { if (!this->Lock()) goto Exit; m_fIsLocked = true; } __except(SXSP_EXCEPTION_FILTER()) { SXS_REPORT_SEH_EXCEPTION(""); #if FUSION_STATIC_NTDLL dwWin32Error = ::RtlNtStatusToDosErrorNoTeb(GetExceptionCode()); #else dwWin32Error = ERROR_OUTOFMEMORY; #endif ::FusionpSetLastWin32Error(dwWin32Error); goto Exit; } fSuccess = TRUE; Exit: return fSuccess; } inline BOOL CSxsLockCriticalSection::TryLock() { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); IFW32FALSE_ORIGINATE_AND_EXIT(::TryEnterCriticalSection(&m_rcs)); m_fIsLocked = true; fSuccess = TRUE; Exit: return fSuccess; } inline BOOL CSxsLockCriticalSection::Unlock() { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); INTERNAL_ERROR_CHECK(m_fIsLocked); ::LeaveCriticalSection(&m_rcs); m_fIsLocked = false; fSuccess = TRUE; Exit: return fSuccess; } #endif // !defined(_FUSION_INC_SXSEXCEPTIONHANDLING_H_INCLUDED_)