2 * Win32 exception functions
4 * Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl)
7 * What really happens behind the scenes of those new
8 * __try{...}__except(..){....} and
9 * __try{...}__finally{...}
10 * statements is simply not documented by Microsoft. There could be different
12 * One reason could be that they try to hide the fact that exception
13 * handling in Win32 looks almost the same as in OS/2 2.x.
14 * Another reason could be that Microsoft does not want others to write
15 * binary compatible implementations of the Win32 API (like us).
17 * Whatever the reason, THIS SUCKS!! Ensuring portabilty or future
18 * compatability may be valid reasons to keep some things undocumented.
19 * But exception handling is so basic to Win32 that it should be
23 * -Most functions need better parameter checking.
24 * -I do not know how to handle exceptions within an exception handler.
25 * or what is done when ExceptionNestedException is returned from an
27 * -Real exceptions are not yet implemented. only the exception functions
28 * are implemented. A real implementation needs some new code in
29 * loader/signal.c. There would also be a need for showing debugging
30 * information in UnhandledExceptionFilter.
43 LPTOP_LEVEL_EXCEPTION_FILTER pTopExcHandler
= NULL
;
47 pTopExcHandler
= (LPTOP_LEVEL_EXCEPTION_FILTER
)PE_GetProcAddress(
48 GetModuleHandle("KERNEL32"),
49 "UnhandledExceptionFilter" );
55 * This function is undocumented. This is the general idea of
56 * RtlUnwind, though. Note that error handling is not yet implemented
60 void EXC_RtlUnwind(PEXCEPTION_FRAME pEndFrame
,PVOID unusedEip
,
61 PEXCEPTION_RECORD pRecord
, DWORD returnEax
,
64 EXCEPTION_RECORD record
;
68 pcontext
->Eax
=returnEax
;
70 /* build an exception record, if we do not have one */
73 record
.ExceptionCode
= 0xC0000026; /* invalid disposition */
74 record
.ExceptionFlags
= 0;
75 record
.ExceptionRecord
= NULL
;
76 record
.ExceptionAddress
=(PVOID
) pcontext
->Eip
;
77 record
.NumberParameters
= 0;
82 pRecord
->ExceptionFlags
|=EH_UNWINDING
;
84 pRecord
->ExceptionFlags
|=EH_UNWINDING
| EH_EXIT_UNWIND
;
86 /* get chain of exception frames */
87 while((TebExceptionFrame
!=NULL
)&&
88 (TebExceptionFrame
!=((void *)-1)) &&
89 (TebExceptionFrame
!=pEndFrame
))
91 dprintf_win32(stddeb
,"calling exception handler at 0x%x\n",
92 (int) TebExceptionFrame
->Handler
);
95 retval
=TebExceptionFrame
->Handler(pRecord
, TebExceptionFrame
,
98 dprintf_win32(stddeb
,"exception handler returns 0x%x, dispatch=0x%x\n",
99 retval
, (int) dispatch
);
101 if(retval
==ExceptionCollidedUnwind
)
102 TebExceptionFrame
=(PVOID
) dispatch
;
103 else if(TebExceptionFrame
!=pEndFrame
)
104 TebExceptionFrame
=TebExceptionFrame
->Prev
;
115 VOID
EXC_RaiseException(DWORD dwExceptionCode
,
116 DWORD dwExceptionFlags
,
118 const LPDWORD lpArguments
,
121 PEXCEPTION_FRAME pframe
;
122 EXCEPTION_RECORD record
;
123 DWORD dispatch
; /* is this used in raising exceptions ?? */
127 /* compose an exception record */
129 record
.ExceptionCode
= dwExceptionCode
;
130 record
.ExceptionFlags
= dwExceptionFlags
;
131 record
.ExceptionRecord
= NULL
;
132 record
.NumberParameters
= cArguments
;
133 record
.ExceptionAddress
= (PVOID
) pcontext
->Eip
;
135 for(i
=0;i
<cArguments
;i
++)
136 record
.ExceptionInformation
[i
]=lpArguments
[i
];
138 /* get chain of exception frames */
140 retval
=ExceptionContinueSearch
;
141 pframe
=TebExceptionFrame
;
143 while((pframe
!=NULL
)&&(pframe
!=((void *)0xFFFFFFFF)))
145 dprintf_win32(stddeb
,"calling exception handler at 0x%x\n",
146 (int) pframe
->Handler
);
148 retval
=pframe
->Handler(&record
,pframe
,pcontext
,&dispatch
);
150 dprintf_win32(stddeb
,"exception handler returns 0x%x, dispatch=0x%x\n",
151 retval
, (int) dispatch
);
153 if(retval
==ExceptionContinueExecution
)
158 if(retval
!=ExceptionContinueExecution
)
160 retval
=EXC_CallUnhandledExceptionFilter(&record
,pcontext
);
161 if(retval
!=EXCEPTION_CONTINUE_EXECUTION
)
163 dprintf_win32(stddeb
,"no handler wanted to handle "
164 "the exception, exiting\n" );
165 ExitProcess(dwExceptionCode
); /* what status should be used here ? */
170 /*******************************************************************
171 * UnhandledExceptionFilter (KERNEL32.537)
173 * This is the unhandled exception code.
174 * Actually, this should show up a dialog box, with all kinds of
175 * fancy debugging information. It does nothing now!
178 DWORD
UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers
)
180 PEXCEPTION_RECORD pRecord
;
183 pRecord
=epointers
->ExceptionRecord
;
184 pContext
=epointers
->ContextRecord
;
186 if(pRecord
->ExceptionFlags
& (EH_UNWINDING
| EH_EXIT_UNWIND
) )
188 dprintf_win32(stddeb
,"UnhandledExceptionFilter: exiting\n");
189 ExitProcess(pRecord
->ExceptionCode
);
193 RtlUnwind(0,pRecord
,0,-1 );
197 * This is just to avoid a warning, code should not get here
198 * if it does, EXC_RaiseException will terminate it.
200 return EXCEPTION_CONTINUE_SEARCH
;
203 /*************************************************************
204 * SetUnhandledExceptionFilter (KERNEL32.516)
209 LPTOP_LEVEL_EXCEPTION_FILTER
210 SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER efilter
)
212 pTopExcHandler
=efilter
;