SEH library
[reactos.git] / reactos / lib / pseh / framebased.c
1 #define STRICT
2 #define WIN32_LEAN_AND_MEAN
3 #include <windows.h>
4
5 #include <pseh/framebased/internal.h>
6 #include <excpt.h>
7
8 /* Assembly helpers, see i386/framebased.asm */
9 extern void __cdecl _SEHCleanHandlerEnvironment(void);
10 extern void __cdecl _SEHRegisterFrame(_SEHRegistration_t *);
11 extern void __cdecl _SEHUnregisterFrame(const _SEHRegistration_t *);
12 extern void __cdecl _SEHUnwind(_SEHPortableFrame_t *);
13
14 __declspec(noreturn) void __cdecl _SEHCallHandler(_SEHPortableFrame_t * frame)
15 {
16 frame->SPF_Handling = 1;
17 _SEHUnwind(frame);
18 frame->SPF_Handlers->SH_Handler(frame);
19 }
20
21 int __cdecl _SEHFrameHandler
22 (
23 struct _EXCEPTION_RECORD * ExceptionRecord,
24 void * EstablisherFrame,
25 struct _CONTEXT * ContextRecord,
26 void * DispatcherContext
27 )
28 {
29 _SEHPortableFrame_t * frame;
30
31 _SEHCleanHandlerEnvironment();
32
33 frame = EstablisherFrame;
34
35 /* Unwinding */
36 if(ExceptionRecord->ExceptionFlags & (4 | 2))
37 {
38 if(frame->SPF_Handlers->SH_Finally && !frame->SPF_Handling)
39 frame->SPF_Handlers->SH_Finally(frame);
40 }
41 /* Handling */
42 else
43 {
44 if(ExceptionRecord->ExceptionCode)
45 frame->SPF_Code = ExceptionRecord->ExceptionCode;
46 else
47 frame->SPF_Code = 0xC0000001;
48
49 if(frame->SPF_Handlers->SH_Filter)
50 {
51 int ret;
52
53 switch((UINT_PTR)frame->SPF_Handlers->SH_Filter)
54 {
55 case EXCEPTION_EXECUTE_HANDLER + 1:
56 case EXCEPTION_CONTINUE_SEARCH + 1:
57 case EXCEPTION_CONTINUE_EXECUTION + 1:
58 {
59 ret = (int)((UINT_PTR)frame->SPF_Handlers->SH_Filter) - 1;
60 break;
61 }
62
63 default:
64 {
65 EXCEPTION_POINTERS ep;
66
67 ep.ExceptionRecord = ExceptionRecord;
68 ep.ContextRecord = ContextRecord;
69
70 ret = frame->SPF_Handlers->SH_Filter(&ep, frame);
71 break;
72 }
73 }
74
75 /* EXCEPTION_CONTINUE_EXECUTION */
76 if(ret < 0)
77 return ExceptionContinueExecution;
78 /* EXCEPTION_EXECUTE_HANDLER */
79 else if(ret > 0)
80 _SEHCallHandler(frame);
81 /* EXCEPTION_CONTINUE_SEARCH */
82 else
83 /* fall through */;
84 }
85 }
86
87 return ExceptionContinueSearch;
88 }
89
90 void __stdcall _SEHEnter(_SEHPortableFrame_t * frame)
91 {
92 frame->SPF_Registration.SER_Handler = _SEHFrameHandler;
93 frame->SPF_Code = 0;
94 frame->SPF_Handling = 0;
95 _SEHRegisterFrame(&frame->SPF_Registration);
96 }
97
98 void __stdcall _SEHLeave(_SEHPortableFrame_t * frame)
99 {
100 _SEHUnregisterFrame(&frame->SPF_Registration);
101 }
102
103 /* EOF */