ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

framebased.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.