00100                    :
00101 
00102     This function walks up 
the list of SEB's associated with 
the specified
00103     
procedure and calls except filters and finally handlers as necessary.
00104 
00105     It 
is called in two different contexts:
00106         (i)  by 
the exception dispatcher after an exception 
is raised
00107         (ii) by 
the unwinder during an unwind operation
00108 
00109     In 
the first 
case, 
is searches 
the SEB list 
for except filters to evaluate.
00110     In 
the second 
case, 
it searches 
for finally handlers to execute.
00111 
00112 Arguments:
00113 
00114     ExceptionRecord - Supplies a pointer to an exception record.
00115 
00116     EstablisherFrame - Supplies a (
virtual frame) pointer to 
the frame of 
the
00117         establisher function.
00118 
00119     ContextRecord - Supplies a pointer to a context record.
00120 
00121     DispatcherContext - Supplies a pointer to 
the exception dispatcher or
00122         unwind dispatcher context.
00123 
00124 Return Value:
00125 
00126     If 
the exception 
is handled by one of 
the exception filter 
routines, then
00127     there 
is no 
return from 
this routine and 
RtlUnwind is called. Otherwise,
00128     an exception disposition value of 
continue execution or 
continue search 
is
00129     returned.
00130 
00131 Notes:
00132     In context (i) there are 3 possibilities:
00133 
00134         (a) If an exception filter returns a value greater that 0 (meaning
00135             that the associated handler should be invoked) there is no
00136             return from this function. RtlUnwind is called to unwind the
00137             stack to the exception handler corresponding to that filter.
00138 
00139         (b) If an exception filter returns a value less than 0 (meaning
00140             that the exception should be dismissed), this routine returns
00141             value ExceptionContinueExecution.
00142 
00143         (c) If every filter returns value 0 (meaning that the search for a
00144             handler should continue elsewhere), this function returns
00145             ExceptionContinueSearch.
00146 
00147     In context (ii) there are 2 possibilities:
00148 
00149         (d) If no branches are detected out of finally handlers, this
00150             function returns ExceptionContinueSearch.
00151 
00152         (e) If a branch is detected out of a finally handler, there is no
00153             return from this routine. RtlUnwind is called to unwind to the
00154             branch target (and cancel the current unwind).
00155 
00156     There may be 
long jumps out of both except filters and finally handlers
00157     in which case this routine will be peeled off the stack without returning.
00158 
00159 --*/
00160 
00161 {
00162 
00163     ULONG_PTR ContinuationAddress;
00164     EXCEPTION_FILTER ExceptionFilter;
00165     PVOID ExceptionHandler;
00166     EXCEPTION_POINTERS ExceptionPointers;
00167     LONG FilterValue;
00168     ULONG_PTR RealFramePointer;
00169     PSEH_BLOCK Seb;
00170     PSEH_CONTEXT SehContext;
00171     PSEH_BLOCK TargetSeb;
00172     TERMINATION_HANDLER TerminationHandler;
00173 
00174     
00175     
00176     
00177     
00178     
00179     
00180 
00181     SehContext = (PSEH_CONTEXT)((ULONG_PTR)EstablisherFrame +
00182         (LONG_PTR)DispatcherContext->FunctionEntry->HandlerData);
00183     RealFramePointer = SehContext->RealFramePointer;
00184 
00185     
00186     
00187     
00188     
00189 
00190     
if (IS_DISPATCHING(ExceptionRecord->ExceptionFlags)) {
00191 
00192         
00193         
00194         
00195         
00196         
00197         
00198 
00199         ExceptionPointers.ExceptionRecord = ExceptionRecord;
00200         ExceptionPointers.ContextRecord = ContextRecord;
00201 
00202         
for (Seb = SehContext->CurrentSeb; Seb != 
NULL; Seb = Seb->ParentSeb) {
00203             
if (
IS_EXCEPT(Seb)) {
00204 
00205                 
00206                 
00207                 
00208                 
00209                 
00210 
00211                 ExceptionFilter = (EXCEPTION_FILTER)Seb->HandlerAddress;
00212                 ExceptionHandler = (PVOID)Seb->JumpTarget;
00213 
00214                 FilterValue = 
__C_ExecuteExceptionFilter(&ExceptionPointers,
00215                                                          ExceptionFilter,
00216                                                          RealFramePointer);
00217 
00218                 
00219                 
00220                 
00221                 
00222                 
00223                 
00224                 
00225                 
00226 
00227                 
if (FilterValue < 0) {
00228                     
return ExceptionContinueExecution;
00229 
00230                 } 
else if (FilterValue > 0) {
00231                     SehContext->ExceptionCode = ExceptionRecord->ExceptionCode;
00232                     
MODIFY_UNWIND_EXCEPTION_RECORD(ExceptionRecord,
00233                                                    Seb->ParentSeb);
00234                     
RtlUnwind2(EstablisherFrame,
00235                                ExceptionHandler,
00236                                ExceptionRecord,
00237                                0,
00238                                ContextRecord);
00239                 }
00240             }
00241         }
00242 
00243     } 
else if (!IS_TARGET_UNWIND(ExceptionRecord->ExceptionFlags)) {
00244 
00245         
00246         
00247         
00248         
00249         
00250         
00251         
00252 
00253         
while (SehContext->CurrentSeb != 
NULL) {
00254 
00255             
00256             
00257             
00258 
00259             Seb = SehContext->CurrentSeb;
00260             SehContext->CurrentSeb = Seb->ParentSeb;
00261 
00262             
if (
IS_FINALLY(Seb)) {
00263 
00264                 
00265                 
00266                 
00267                 
00268 
00269                 TerminationHandler = (TERMINATION_HANDLER)Seb->HandlerAddress;
00270                 ContinuationAddress =
00271                     
__C_ExecuteTerminationHandler(TRUE,
00272                                                   TerminationHandler,
00273                                                   RealFramePointer);
00274 
00275                 
00276                 
00277                 
00278                 
00279                 
00280 
00281                 
if (ContinuationAddress != 0) {
00282                     
MODIFY_UNWIND_EXCEPTION_RECORD(ExceptionRecord,
00283                                                    SehContext->CurrentSeb);
00284                     
RtlUnwind(EstablisherFrame,
00285                               (PVOID)ContinuationAddress,
00286                               ExceptionRecord,
00287                               0);
00288                 }
00289             }
00290         }
00291 
00292     } 
else {
00293 
00294         
00295         
00296         
00297         
00298         
00299         
00300         
00301 
00302         TargetSeb = (PSEH_BLOCK)ExceptionRecord->ExceptionInformation[0];
00303         ContinuationAddress = 
_OtsLocalFinallyUnwind(SehContext,
00304                                                      TargetSeb,
00305                                                      (PVOID)RealFramePointer);
00306         
if (ContinuationAddress != 0) {
00307 
00308             
00309             
00310             
00311             
00312             
00313 
00314             
MODIFY_UNWIND_EXCEPTION_RECORD(ExceptionRecord,
00315                                            SehContext->CurrentSeb);
00316             
RtlUnwind(EstablisherFrame,
00317                       (PVOID)ContinuationAddress,
00318                       ExceptionRecord,
00319                       0);
00320         }
00321     }
00322 
00323     
00324     
00325     
00326 
00327     
return ExceptionContinueSearch;
00328 }