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.

214 lines
4.7 KiB

  1. #if !defined(_FUSION_INC_SXSEXCEPTIONHANDLING_H_INCLUDED_)
  2. #define _FUSION_INC_SXSEXCEPTIONHANDLING_H_INCLUDED_
  3. /*++
  4. Copyright (c) 2000 Microsoft Corporation
  5. Module Name:
  6. SxsExceptionHandling.h
  7. Abstract:
  8. Author:
  9. Jay Krell (a-JayK) October 2000
  10. Revision History:
  11. --*/
  12. #pragma once
  13. #include "nt.h"
  14. #include "ntrtl.h"
  15. #include "nturtl.h"
  16. #include "windows.h"
  17. #include "fusionlastwin32error.h"
  18. #include "fusionntdll.h"
  19. #include "fusiontrace.h"
  20. #include "csxspreservelasterror.h" // Most destructors should use this.
  21. #include "fusionheap.h"
  22. /*-----------------------------------------------------------------------------
  23. Instead of:
  24. __except(EXECEPTION_EXECUTE_HANDLER)
  25. say:
  26. __except(SXSP_EXCEPTION_FILTER())
  27. This way all exceptions will be logged with DbgPrint,
  28. and probably hit a breakpoint if under a debugger, and any other behavior we
  29. want.
  30. If your exception filter is other than (EXECEPTION_EXECUTE_HANDLER), then
  31. you are on your own.
  32. -----------------------------------------------------------------------------*/
  33. INT
  34. SxspExceptionFilter(
  35. PEXCEPTION_POINTERS ExceptionPointers,
  36. PCSTR Function
  37. );
  38. #define SXSP_EXCEPTION_FILTER() (::SxspExceptionFilter(GetExceptionInformation(), __FUNCTION__))
  39. #define SXS_REPORT_SEH_EXCEPTION(string) \
  40. __try \
  41. { \
  42. if (::FusionpReportConditionAndBreak(NULL, "SXS.DLL: " __FUNCTION__ " - Unhandled exception caught: 0x%08lx", GetExceptionCode())) \
  43. FUSION_DEBUG_BREAK(); \
  44. } \
  45. __except(EXCEPTION_EXECUTE_HANDLER) { }
  46. class CCriticalSectionNoConstructor : public CRITICAL_SECTION
  47. {
  48. void operator=(const CCriticalSectionNoConstructor&); // deliberately not implemented
  49. //CCriticalSectionNoConstructor(const CCriticalSectionNoConstructor&); // deliberately not implemented
  50. public:
  51. BOOL Construct();
  52. BOOL ConstructWithSEH(PCSTR Function = "");
  53. BOOL Destruct();
  54. };
  55. inline BOOL
  56. CCriticalSectionNoConstructor::Construct()
  57. {
  58. ::InitializeCriticalSection(this);
  59. return TRUE;
  60. }
  61. inline BOOL
  62. CCriticalSectionNoConstructor::Destruct()
  63. {
  64. ::DeleteCriticalSection(this);
  65. return TRUE;
  66. }
  67. inline BOOL
  68. CCriticalSectionNoConstructor::ConstructWithSEH(
  69. PCSTR /* Function */)
  70. {
  71. BOOL Result = FALSE;
  72. DWORD dwWin32Error;
  73. __try
  74. {
  75. if (!this->Construct())
  76. goto Exit;
  77. }
  78. __except(SXSP_EXCEPTION_FILTER())
  79. {
  80. SXS_REPORT_SEH_EXCEPTION("");
  81. #if FUSION_STATIC_NTDLL
  82. dwWin32Error = ::RtlNtStatusToDosErrorNoTeb(GetExceptionCode());
  83. #else
  84. dwWin32Error = ERROR_OUTOFMEMORY;
  85. #endif
  86. ::FusionpSetLastWin32Error(dwWin32Error);
  87. goto Exit;
  88. }
  89. Result = TRUE;
  90. Exit:
  91. return Result;
  92. }
  93. class CSxsLockCriticalSection
  94. {
  95. public:
  96. CSxsLockCriticalSection(CRITICAL_SECTION &rcs) : m_rcs(rcs), m_fIsLocked(false) { }
  97. BOOL Lock();
  98. BOOL TryLock();
  99. BOOL LockWithSEH();
  100. ~CSxsLockCriticalSection() { if (m_fIsLocked) { CSxsPreserveLastError ple; ::LeaveCriticalSection(&m_rcs); ple.Restore(); } }
  101. BOOL Unlock();
  102. protected:
  103. CRITICAL_SECTION &m_rcs;
  104. bool m_fIsLocked;
  105. private:
  106. void operator=(const CSxsLockCriticalSection&);
  107. CSxsLockCriticalSection(const CSxsLockCriticalSection&);
  108. };
  109. inline
  110. BOOL
  111. CSxsLockCriticalSection::Lock()
  112. {
  113. BOOL fSuccess = FALSE;
  114. FN_TRACE_WIN32(fSuccess);
  115. INTERNAL_ERROR_CHECK(!m_fIsLocked);
  116. ::EnterCriticalSection(&m_rcs);
  117. m_fIsLocked = true;
  118. fSuccess = TRUE;
  119. Exit:
  120. return fSuccess;
  121. }
  122. inline
  123. BOOL
  124. CSxsLockCriticalSection::LockWithSEH()
  125. {
  126. BOOL fSuccess = FALSE;
  127. DWORD dwWin32Error;
  128. // We can't use the spiffy macros in the same frame as a __try block.
  129. ASSERT_NTC(!m_fIsLocked);
  130. if (m_fIsLocked)
  131. {
  132. ::FusionpSetLastWin32Error(ERROR_INTERNAL_ERROR);
  133. goto Exit;
  134. }
  135. __try
  136. {
  137. if (!this->Lock())
  138. goto Exit;
  139. m_fIsLocked = true;
  140. }
  141. __except(SXSP_EXCEPTION_FILTER())
  142. {
  143. SXS_REPORT_SEH_EXCEPTION("");
  144. #if FUSION_STATIC_NTDLL
  145. dwWin32Error = ::RtlNtStatusToDosErrorNoTeb(GetExceptionCode());
  146. #else
  147. dwWin32Error = ERROR_OUTOFMEMORY;
  148. #endif
  149. ::FusionpSetLastWin32Error(dwWin32Error);
  150. goto Exit;
  151. }
  152. fSuccess = TRUE;
  153. Exit:
  154. return fSuccess;
  155. }
  156. inline
  157. BOOL
  158. CSxsLockCriticalSection::TryLock()
  159. {
  160. BOOL fSuccess = FALSE;
  161. FN_TRACE_WIN32(fSuccess);
  162. IFW32FALSE_ORIGINATE_AND_EXIT(::TryEnterCriticalSection(&m_rcs));
  163. m_fIsLocked = true;
  164. fSuccess = TRUE;
  165. Exit:
  166. return fSuccess;
  167. }
  168. inline
  169. BOOL
  170. CSxsLockCriticalSection::Unlock()
  171. {
  172. BOOL fSuccess = FALSE;
  173. FN_TRACE_WIN32(fSuccess);
  174. INTERNAL_ERROR_CHECK(m_fIsLocked);
  175. ::LeaveCriticalSection(&m_rcs);
  176. m_fIsLocked = false;
  177. fSuccess = TRUE;
  178. Exit:
  179. return fSuccess;
  180. }
  181. #endif // !defined(_FUSION_INC_SXSEXCEPTIONHANDLING_H_INCLUDED_)