home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 January / PCWorld_2000-01_cd.bin / Software / Servis / Devc / _SETUP.5 / Group18 / eh3.c next >
Encoding:
Text File  |  1997-10-28  |  3.2 KB  |  113 lines

  1. int
  2. __except_handler3(
  3.     struct _EXCEPTION_RECORD*    pExceptionRecord,
  4.     struct EXCEPTION_REGISTRATION*    pRegistrationFrame,
  5.     struct _CONTEXT*        pContextRecord,
  6.     void*                pDispatcherContext
  7.     )
  8. {
  9.     LONG    filterFuncRet;
  10.     LONG trylevel;
  11.     EXCEPTION_POINTERS exceptPtrs;
  12.     PSCOPETABLE pScopeTable;
  13.  
  14.  
  15.     CLD // Clear the direction flag (make no assumptions!)
  16.  
  17.     // if neither the EXCEPTION_UNWINDING nor EXCEPTION_EXIT_UNWIND bit
  18.     // is set... This is true the first time through the handler (the
  19.     // non-unwinding case)
  20.  
  21.     if ( ! (pExceptionRecord->ExceptionFlags
  22.          & (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
  23.                ) )
  24.     {
  25.         // Build the EXCEPTION_POINTERS structure on the stack
  26.         exceptPtrs.ExceptionRecord = pExceptionRecord;
  27.         exceptPtrs.ContextRecord = pContextRecord;
  28.  
  29.         // Put the pointer to the EXCEPTION_POINTERS 4 bytes below the
  30.         // establisher frame. See ASM code for GetExceptionInformation
  31.         *(PDWORD)((PBYTE)pRegistrationFrame - 4) = &exceptPtrs;
  32.  
  33.         // Get initial "trylevel" value
  34.         trylevel = pRegistrationFrame->trylevel 
  35.  
  36.         // Get a pointer to the scopetable array
  37.         scopeTable = pRegistrationFrame->scopetable;
  38.  
  39. search_for_handler: 
  40.         if ( pRegistrationFrame->trylevel != TRYLEVEL_NONE )
  41.         {
  42.             if ( pRegistrationFrame->scopetable[trylevel].lpfnFilter )
  43.             {
  44.  
  45.                 PUSH EBP // Save this frame EBP
  46.  
  47.             // !!!Very Important!!! Switch to original EBP. This is
  48.             // what allows all locals in the frame to have the same
  49.             // value as before the exception occurred.
  50.  
  51.                 EBP = &pRegistrationFrame->_ebp
  52.  
  53.                 // Call the filter function
  54.                 filterFuncRet = scopetable[trylevel].lpfnFilter();
  55.  
  56.                 POP EBP // Restore handler frame EBP
  57.  
  58.                 if ( filterFuncRet != EXCEPTION_CONTINUE_SEARCH )
  59.                 {
  60.                     if ( filterFuncRet < 0 ) // EXCEPTION_CONTINUE_EXECUTION
  61.                         return ExceptionContinueExecution;
  62.  
  63.                     // If we get here, EXCEPTION_EXECUTE_HANDLER was specified
  64.                     scopetable == pRegistrationFrame->scopetable
  65.  
  66.             // Does the actual OS cleanup of registration frames
  67.                     // Causes this function to recurse
  68.                     __global_unwind2( pRegistrationFrame );
  69.  
  70.  
  71.         // Once we get here, everything is all cleaned up, except
  72.         // for the last frame, where we'll continue execution
  73.                     EBP = &pRegistrationFrame->_ebp
  74.  
  75.                     __local_unwind2( pRegistrationFrame, trylevel );
  76.  
  77.         // NLG == "non-local-goto" (setjmp/longjmp stuff)
  78.                     __NLG_Notify( 1 ); // EAX == scopetable->lpfnHandler
  79.  
  80.         // Set the current trylevel to whatever SCOPETABLE entry
  81.         // was being used when a handler was found
  82.                     pRegistrationFrame->trylevel = scopetable->previousTryLevel;
  83.  
  84.         // Call the _except {} block. Never returns.
  85.                     pRegistrationFrame->scopetable[trylevel].lpfnHandler();
  86.                 }
  87.             }
  88.  
  89.             scopeTable = pRegistrationFrame->scopetable;
  90.             trylevel = scopeTable->previousTryLevel
  91.  
  92.             goto search_for_handler;
  93.         }
  94.         else // trylevel == TRYLEVEL_NONE
  95.         {
  96.             retvalue == DISPOSITION_CONTINUE_SEARCH;
  97.         }
  98.     }
  99.     else // EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND flags are set
  100.     {
  101.         PUSH EBP // Save EBP
  102.  
  103.         EBP = pRegistrationFrame->_ebp // Set EBP for __local_unwind2
  104.  
  105.         __local_unwind2( pRegistrationFrame, TRYLEVEL_NONE )
  106.  
  107.         POP EBP // Restore EBP
  108.  
  109.         retvalue == DISPOSITION_CONTINUE_SEARCH;
  110.     }
  111. }
  112.  
  113.