Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenframebased.c
Go to the documentation of this file.
00001 /* 00002 Copyright (c) 2004/2005 KJK::Hyperion 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a 00005 copy of this software and associated documentation files (the "Software"), 00006 to deal in the Software without restriction, including without limitation 00007 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 and/or sell copies of the Software, and to permit persons to whom the 00009 Software is furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00019 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00020 DEALINGS IN THE SOFTWARE. 00021 */ 00022 00023 #define _NTSYSTEM_ 00024 #define STRICT 00025 #define WIN32_LEAN_AND_MEAN 00026 #include <windows.h> 00027 00028 #include <pseh/pseh.h> 00029 #include <pseh/framebased/internal.h> 00030 #include <pseh/excpt.h> 00031 #include <pseh/framebased.h> 00032 00033 #include <excpt.h> 00034 00035 /* Tracing */ 00036 #ifdef _SEH_ENABLE_TRACE 00037 extern unsigned long __cdecl DbgPrint(const char * format, ...); 00038 00039 #define _SEH_TRACE_HEADER_(FRAME_) \ 00040 DbgPrint("[PSEH:%p]%s:%d:", FRAME_, __FILE__, __LINE__); 00041 00042 #define _SEH_TRACE_TRAILER_ \ 00043 DbgPrint("\n"); 00044 00045 #define _SEH_FILTER_RET_STRING_(RET_) \ 00046 (((int)(RET_) < 0) ? "_SEH_CONTINUE_EXECUTION" : (((int)(RET_) > 0) ? "_SEH_EXECUTE_HANDLER" : "_SEH_CONTINUE_SEARCH")) 00047 00048 #define _SEH_TRACE_LINE_(FRAME_, ARGS_) \ 00049 { \ 00050 _SEH_TRACE_HEADER_(FRAME_); \ 00051 DbgPrint ARGS_; \ 00052 _SEH_TRACE_TRAILER_; \ 00053 } 00054 00055 #define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_) \ 00056 { \ 00057 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \ 00058 { \ 00059 _SEH_TRACE_HEADER_(FRAME_); \ 00060 DbgPrint(">>> %s(", (FUNCNAME_)); \ 00061 DbgPrint ARGS_; \ 00062 DbgPrint(")"); \ 00063 _SEH_TRACE_TRAILER_; \ 00064 } \ 00065 } 00066 00067 #define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_) \ 00068 { \ 00069 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \ 00070 { \ 00071 _SEH_TRACE_HEADER_(FRAME_); \ 00072 DbgPrint("<<< %s => ", (FUNCNAME_)); \ 00073 DbgPrint ARGS_; \ 00074 _SEH_TRACE_TRAILER_; \ 00075 } \ 00076 } 00077 00078 #define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_) \ 00079 { \ 00080 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_EXCEPTION_RECORD) \ 00081 { \ 00082 _SEH_TRACE_LINE_ \ 00083 ( \ 00084 (FRAME_), \ 00085 ( \ 00086 "ExceptionRecord %p = { ExceptionCode : %08X, ExceptionFlags : %08X, ExceptionRecord : %p, ExceptionAddress : %p }", \ 00087 (ER_), \ 00088 (ER_)->ExceptionCode, \ 00089 (ER_)->ExceptionFlags, \ 00090 (ER_)->ExceptionRecord, \ 00091 (ER_)->ExceptionAddress \ 00092 ) \ 00093 ); \ 00094 } \ 00095 } 00096 00097 #ifdef _X86_ 00098 #define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) \ 00099 { \ 00100 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CONTEXT) \ 00101 { \ 00102 if(((CONTEXT_)->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) \ 00103 { \ 00104 _SEH_TRACE_LINE_ \ 00105 ( \ 00106 (FRAME_), \ 00107 ( \ 00108 "eax=%08X ebx=%08X ecx=%08X edx=%08X esi=%08X edi=%08X", \ 00109 (CONTEXT_)->Eax, \ 00110 (CONTEXT_)->Ebx, \ 00111 (CONTEXT_)->Ecx, \ 00112 (CONTEXT_)->Edx, \ 00113 (CONTEXT_)->Esi, \ 00114 (CONTEXT_)->Edi \ 00115 ) \ 00116 ); \ 00117 } \ 00118 \ 00119 if(((CONTEXT_)->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) \ 00120 { \ 00121 _SEH_TRACE_LINE_ \ 00122 ( \ 00123 (FRAME_), \ 00124 ( \ 00125 "eip=%08X esp=%08X ebp=%08X efl=%08X cs=%08X ss=%08X", \ 00126 (CONTEXT_)->Eip, \ 00127 (CONTEXT_)->Esp, \ 00128 (CONTEXT_)->Ebp, \ 00129 (CONTEXT_)->EFlags, \ 00130 (CONTEXT_)->SegCs, \ 00131 (CONTEXT_)->SegSs \ 00132 ) \ 00133 ); \ 00134 } \ 00135 \ 00136 if(((CONTEXT_)->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) \ 00137 { \ 00138 _SEH_TRACE_LINE_ \ 00139 ( \ 00140 (FRAME_), \ 00141 ( \ 00142 "ds=%08X es=%08X fs=%08X gs=%08X", \ 00143 (CONTEXT_)->SegDs, \ 00144 (CONTEXT_)->SegEs, \ 00145 (CONTEXT_)->SegFs, \ 00146 (CONTEXT_)->SegGs \ 00147 ) \ 00148 ); \ 00149 } \ 00150 } \ 00151 } 00152 #else 00153 #define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) 00154 #endif 00155 00156 #define _SEH_TRACE_UNWIND(FRAME_, ARGS_) \ 00157 { \ 00158 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_UNWIND) \ 00159 { \ 00160 _SEH_TRACE_LINE_((FRAME_), ARGS_); \ 00161 } \ 00162 } 00163 00164 #define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_) \ 00165 { \ 00166 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_TRYLEVEL) \ 00167 { \ 00168 _SEH_TRACE_LINE_((FRAME_), ("trylevel %p, filter %p", (TRYLEVEL_), (TRYLEVEL_)->SPT_Handlers.SH_Filter)); \ 00169 } \ 00170 } 00171 00172 #define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_) \ 00173 { \ 00174 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \ 00175 { \ 00176 _SEH_TRACE_LINE_ \ 00177 ( \ 00178 (FRAME_), \ 00179 ( \ 00180 "trylevel %p, calling filter %p, ExceptionCode %08X", \ 00181 (TRYLEVEL_), \ 00182 (TRYLEVEL_)->SPT_Handlers.SH_Filter, \ 00183 (ER_)->ExceptionCode \ 00184 ) \ 00185 ); \ 00186 } \ 00187 } 00188 00189 #define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_) \ 00190 { \ 00191 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \ 00192 { \ 00193 _SEH_TRACE_LINE_ \ 00194 ( \ 00195 (FRAME_), \ 00196 ( \ 00197 "trylevel %p, filter %p => %s", \ 00198 (TRYLEVEL_), \ 00199 (TRYLEVEL_)->SPT_Handlers.SH_Filter, \ 00200 _SEH_FILTER_RET_STRING_(RET_) \ 00201 ) \ 00202 ); \ 00203 } \ 00204 } 00205 00206 #define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_) \ 00207 { \ 00208 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_FILTER) \ 00209 { \ 00210 _SEH_TRACE_LINE_ \ 00211 ( \ 00212 (FRAME_), \ 00213 ( \ 00214 "trylevel %p => %s", \ 00215 (TRYLEVEL_), \ 00216 _SEH_FILTER_RET_STRING_(RET_) \ 00217 ) \ 00218 ); \ 00219 } \ 00220 } 00221 00222 #define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_) \ 00223 { \ 00224 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_HANDLER) \ 00225 { \ 00226 _SEH_TRACE_LINE_((FRAME_), ("trylevel %p, handling", (TRYLEVEL_))); \ 00227 } \ 00228 } 00229 00230 #define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_) \ 00231 { \ 00232 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \ 00233 { \ 00234 _SEH_TRACE_LINE_ \ 00235 ( \ 00236 (FRAME_), \ 00237 ( \ 00238 "trylevel %p, calling exit routine %p", \ 00239 (TRYLEVEL_), \ 00240 (TRYLEVEL_)->SPT_Handlers.SH_Finally \ 00241 ) \ 00242 ); \ 00243 } \ 00244 } 00245 00246 #define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_) \ 00247 { \ 00248 if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \ 00249 { \ 00250 _SEH_TRACE_LINE_ \ 00251 ( \ 00252 (FRAME_), \ 00253 ( \ 00254 "trylevel %p, exit routine %p returned", \ 00255 (TRYLEVEL_), \ 00256 (TRYLEVEL_)->SPT_Handlers.SH_Finally \ 00257 ) \ 00258 ); \ 00259 } \ 00260 } 00261 00262 #else 00263 #define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_) 00264 #define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_) 00265 #define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_) 00266 #define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) 00267 #define _SEH_TRACE_UNWIND(FRAME_, ARGS_) 00268 #define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_) 00269 #define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_) 00270 #define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_) 00271 #define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_) 00272 #define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_) 00273 #define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_) 00274 #define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_) 00275 #endif 00276 00277 /* Assembly helpers, see i386/framebased.asm */ 00278 extern void __cdecl _SEHCleanHandlerEnvironment(void); 00279 extern struct __SEHRegistration * __cdecl _SEHRegisterFrame(_SEHRegistration_t *); 00280 extern void __cdecl _SEHUnregisterFrame(void); 00281 extern void __cdecl _SEHGlobalUnwind(_SEHPortableFrame_t *); 00282 extern _SEHRegistration_t * __cdecl _SEHCurrentRegistration(void); 00283 00284 /* Borland C++ uses a different decoration (i.e. none) for stdcall functions */ 00285 extern void __stdcall RtlUnwind(void *, void *, PEXCEPTION_RECORD, void *); 00286 void const * _SEHRtlUnwind = RtlUnwind; 00287 00288 static void __stdcall _SEHLocalUnwind 00289 ( 00290 _SEHPortableFrame_t * frame, 00291 _SEHPortableTryLevel_t * dsttrylevel 00292 ) 00293 { 00294 _SEHPortableTryLevel_t * trylevel; 00295 00296 _SEH_TRACE_UNWIND(frame, ("enter local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel)); 00297 00298 for 00299 ( 00300 trylevel = frame->SPF_TopTryLevel; 00301 trylevel != dsttrylevel; 00302 trylevel = trylevel->SPT_Next 00303 ) 00304 { 00305 _SEHFinally_t pfnFinally; 00306 00307 /* ASSERT(trylevel); */ 00308 00309 pfnFinally = trylevel->SPT_Handlers.SH_Finally; 00310 00311 if(pfnFinally) 00312 { 00313 _SEH_TRACE_ENTER_CALL_FINALLY(frame, trylevel); 00314 pfnFinally(frame); 00315 _SEH_TRACE_LEAVE_CALL_FINALLY(frame, trylevel); 00316 } 00317 } 00318 00319 _SEH_TRACE_UNWIND(frame, ("leave local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel)); 00320 } 00321 00322 static void __cdecl _SEHCallHandler 00323 ( 00324 _SEHPortableFrame_t * frame, 00325 _SEHPortableTryLevel_t * trylevel 00326 ) 00327 { 00328 _SEHGlobalUnwind(frame); 00329 _SEHLocalUnwind(frame, trylevel); 00330 _SEH_TRACE_ENTER_CALL_HANDLER(frame, trylevel); 00331 frame->SPF_Handler(trylevel); 00332 /* ASSERT(0); */ 00333 } 00334 00335 static int __cdecl _SEHFrameHandler 00336 ( 00337 struct _EXCEPTION_RECORD * ExceptionRecord, 00338 void * EstablisherFrame, 00339 struct _CONTEXT * ContextRecord, 00340 void * DispatcherContext 00341 ) 00342 { 00343 _SEHPortableFrame_t * frame; 00344 00345 _SEHCleanHandlerEnvironment(); 00346 00347 frame = EstablisherFrame; 00348 00349 _SEH_TRACE_ENTER 00350 ( 00351 frame, 00352 "_SEHFrameHandler", 00353 ( 00354 "%p, %p, %p, %p", 00355 ExceptionRecord, 00356 EstablisherFrame, 00357 ContextRecord, 00358 DispatcherContext 00359 ) 00360 ); 00361 00362 _SEH_TRACE_EXCEPTION_RECORD(frame, ExceptionRecord); 00363 _SEH_TRACE_CONTEXT(frame, ContextRecord); 00364 00365 /* Unwinding */ 00366 if(ExceptionRecord->ExceptionFlags & (4 | 2)) 00367 { 00368 _SEH_TRACE_UNWIND(frame, ("enter forced unwind")); 00369 _SEHLocalUnwind(frame, NULL); 00370 _SEH_TRACE_UNWIND(frame, ("leave forced unwind")); 00371 } 00372 /* Handling */ 00373 else 00374 { 00375 int ret; 00376 _SEHPortableTryLevel_t * trylevel; 00377 00378 if(ExceptionRecord->ExceptionCode) 00379 frame->SPF_Code = ExceptionRecord->ExceptionCode; 00380 else 00381 frame->SPF_Code = 0xC0000001; 00382 00383 for 00384 ( 00385 trylevel = frame->SPF_TopTryLevel; 00386 trylevel != NULL; 00387 trylevel = trylevel->SPT_Next 00388 ) 00389 { 00390 _SEHFilter_t pfnFilter = trylevel->SPT_Handlers.SH_Filter; 00391 00392 _SEH_TRACE_TRYLEVEL(frame, trylevel); 00393 00394 switch((UINT_PTR)pfnFilter) 00395 { 00396 case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER): 00397 case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH): 00398 case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_CONTINUE_EXECUTION): 00399 { 00400 ret = (int)((UINT_PTR)pfnFilter) - 2; 00401 break; 00402 } 00403 00404 default: 00405 { 00406 if(trylevel->SPT_Handlers.SH_Filter) 00407 { 00408 EXCEPTION_POINTERS ep; 00409 00410 ep.ExceptionRecord = ExceptionRecord; 00411 ep.ContextRecord = ContextRecord; 00412 00413 _SEH_TRACE_ENTER_CALL_FILTER(frame, trylevel, ExceptionRecord); 00414 ret = pfnFilter(&ep, frame); 00415 _SEH_TRACE_LEAVE_CALL_FILTER(frame, trylevel, ret); 00416 } 00417 else 00418 ret = _SEH_CONTINUE_SEARCH; 00419 00420 break; 00421 } 00422 } 00423 00424 _SEH_TRACE_FILTER(frame, trylevel, ret); 00425 00426 /* _SEH_CONTINUE_EXECUTION */ 00427 if(ret < 0) 00428 { 00429 _SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueExecution")); 00430 return ExceptionContinueExecution; 00431 } 00432 /* _SEH_EXECUTE_HANDLER */ 00433 else if(ret > 0) 00434 _SEHCallHandler(frame, trylevel); 00435 /* _SEH_CONTINUE_SEARCH */ 00436 else 00437 continue; 00438 } 00439 00440 /* FALLTHROUGH */ 00441 } 00442 00443 _SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueSearch")); 00444 return ExceptionContinueSearch; 00445 } 00446 00447 void __stdcall _SEHEnterFrame_s(_SEHPortableFrame_t * frame) 00448 { 00449 _SEHEnterFrame_f(frame); 00450 } 00451 00452 void __stdcall _SEHLeaveFrame_s(void) 00453 { 00454 _SEHLeaveFrame_f(); 00455 } 00456 00457 void __stdcall _SEHReturn_s(void) 00458 { 00459 _SEHReturn_f(); 00460 } 00461 00462 void _SEH_FASTCALL _SEHEnterFrame_f(_SEHPortableFrame_t * frame) 00463 { 00464 /* ASSERT(frame); */ 00465 /* ASSERT(trylevel); */ 00466 frame->SPF_Registration.SER_Handler = _SEHFrameHandler; 00467 frame->SPF_Code = 0; 00468 _SEHRegisterFrame(&frame->SPF_Registration); 00469 } 00470 00471 void _SEH_FASTCALL _SEHLeaveFrame_f(void) 00472 { 00473 /* _SEHPortableFrame_t * frame; 00474 00475 frame = _SEH_CONTAINING_RECORD 00476 ( 00477 _SEHCurrentRegistration(), 00478 _SEHPortableFrame_t, 00479 SPF_Registration 00480 ); */ 00481 00482 /* ASSERT(frame); */ 00483 /* ASSERT(frame->SPF_TopTryLevel == NULL) */ 00484 00485 _SEHUnregisterFrame(); 00486 } 00487 00488 void _SEH_FASTCALL _SEHReturn_f(void) 00489 { 00490 _SEHPortableFrame_t * frame; 00491 00492 frame = _SEH_CONTAINING_RECORD 00493 ( 00494 _SEHCurrentRegistration(), 00495 _SEHPortableFrame_t, 00496 SPF_Registration 00497 ); 00498 00499 _SEHLocalUnwind(frame, NULL); 00500 _SEHUnregisterFrame(); 00501 } 00502 00503 /* EOF */ Generated on Fri May 25 2012 04:34:45 for ReactOS by
1.7.6.1
|