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.
42 LPTOP_LEVEL_EXCEPTION_FILTER pTopExcHandler
= NULL
;
46 pTopExcHandler
= (LPTOP_LEVEL_EXCEPTION_FILTER
)GetProcAddress32(
47 GetModuleHandle("KERNEL32"),
48 "UnhandledExceptionFilter" );
54 * This function is undocumented. This is the general idea of
55 * RtlUnwind, though. Note that error handling is not yet implemented
59 void EXC_RtlUnwind(PEXCEPTION_FRAME pEndFrame
,LPVOID unusedEip
,
60 PEXCEPTION_RECORD pRecord
, DWORD returnEax
,
63 EXCEPTION_RECORD record
;
67 pcontext
->Eax
=returnEax
;
69 /* build an exception record, if we do not have one */
72 record
.ExceptionCode
= 0xC0000026; /* invalid disposition */
73 record
.ExceptionFlags
= 0;
74 record
.ExceptionRecord
= NULL
;
75 record
.ExceptionAddress
=(LPVOID
) pcontext
->Eip
;
76 record
.NumberParameters
= 0;
81 pRecord
->ExceptionFlags
|=EH_UNWINDING
;
83 pRecord
->ExceptionFlags
|=EH_UNWINDING
| EH_EXIT_UNWIND
;
85 /* get chain of exception frames */
86 while((TebExceptionFrame
!=NULL
)&&
87 (TebExceptionFrame
!=((void *)-1)) &&
88 (TebExceptionFrame
!=pEndFrame
))
90 dprintf_win32(stddeb
,"calling exception handler at 0x%x\n",
91 (int) TebExceptionFrame
->Handler
);
94 retval
=TebExceptionFrame
->Handler(pRecord
, TebExceptionFrame
,
97 dprintf_win32(stddeb
,"exception handler returns 0x%x, dispatch=0x%x\n",
98 retval
, (int) dispatch
);
100 if(retval
==ExceptionCollidedUnwind
)
101 TebExceptionFrame
=(LPVOID
) dispatch
;
102 else if(TebExceptionFrame
!=pEndFrame
)
103 TebExceptionFrame
=TebExceptionFrame
->Prev
;
114 VOID
EXC_RaiseException(DWORD dwExceptionCode
,
115 DWORD dwExceptionFlags
,
117 const LPDWORD lpArguments
,
120 PEXCEPTION_FRAME pframe
;
121 EXCEPTION_RECORD record
;
122 DWORD dispatch
; /* is this used in raising exceptions ?? */
126 /* compose an exception record */
128 record
.ExceptionCode
= dwExceptionCode
;
129 record
.ExceptionFlags
= dwExceptionFlags
;
130 record
.ExceptionRecord
= NULL
;
131 record
.NumberParameters
= cArguments
;
132 record
.ExceptionAddress
= (LPVOID
) pcontext
->Eip
;
134 for(i
=0;i
<cArguments
;i
++)
135 record
.ExceptionInformation
[i
]=lpArguments
[i
];
137 /* get chain of exception frames */
139 retval
=ExceptionContinueSearch
;
140 pframe
=TebExceptionFrame
;
142 while((pframe
!=NULL
)&&(pframe
!=((void *)0xFFFFFFFF)))
144 dprintf_win32(stddeb
,"calling exception handler at 0x%x\n",
145 (int) pframe
->Handler
);
147 retval
=pframe
->Handler(&record
,pframe
,pcontext
,&dispatch
);
149 dprintf_win32(stddeb
,"exception handler returns 0x%x, dispatch=0x%x\n",
150 retval
, (int) dispatch
);
152 if(retval
==ExceptionContinueExecution
)
157 if(retval
!=ExceptionContinueExecution
)
159 retval
=EXC_CallUnhandledExceptionFilter(&record
,pcontext
);
160 if(retval
!=EXCEPTION_CONTINUE_EXECUTION
)
162 dprintf_win32(stddeb
,"no handler wanted to handle "
163 "the exception, exiting\n" );
164 ExitProcess(dwExceptionCode
); /* what status should be used here ? */
169 /*******************************************************************
170 * UnhandledExceptionFilter (KERNEL32.537)
172 * This is the unhandled exception code.
173 * Actually, this should show up a dialog box, with all kinds of
174 * fancy debugging information. It does nothing now!
177 DWORD
UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers
)
179 PEXCEPTION_RECORD pRecord
;
182 pRecord
=epointers
->ExceptionRecord
;
183 pContext
=epointers
->ContextRecord
;
185 if(pRecord
->ExceptionFlags
& (EH_UNWINDING
| EH_EXIT_UNWIND
) )
187 dprintf_win32(stddeb
,"UnhandledExceptionFilter: exiting\n");
188 ExitProcess(pRecord
->ExceptionCode
);
192 RtlUnwind(0,pRecord
,0,-1 );
196 * This is just to avoid a warning, code should not get here
197 * if it does, EXC_RaiseException will terminate it.
199 return EXCEPTION_CONTINUE_SEARCH
;
202 /*************************************************************
203 * SetUnhandledExceptionFilter (KERNEL32.516)
208 LPTOP_LEVEL_EXCEPTION_FILTER
209 SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER efilter
)
211 pTopExcHandler
=efilter
;