00061 :
00062
00063 This function scans
the scope tables associated with
the specified
00064
procedure and calls exception and termination handlers as necessary.
00065
00066 This language specific exception handler function
is called on a
00067 per-frame basis and in two different cases:
00068
00069 First,
the IS_DISPATCHING
case,
it is called by
the exception
00070 dispatcher,
RtlDispatchException, via
the short assembler routine,
00071 __C_ExecuteHandlerForException, when trying to locate exception
00072 filters within
the given frame.
00073
00074 Second,
the IS_UNWINDING
case,
it is called by
the frame unwinder,
00075
RtlUnwind, via
the short assembler routine, __C_ExecuteHandlerForUnwind,
00076 when unwinding
the stack and trying to locate termination handlers
00077 within
the given frame.
00078
00079 Arguments:
00080
00081 ExceptionRecord - Supplies a pointer to an exception record.
00082
00083 EstablisherFrame - Supplies a pointer to frame of
the establisher function.
00084
00085 ContextRecord - Supplies a pointer to a context record.
00086
00087 DispatcherContext - Supplies a pointer to
the exception dispatcher or
00088 unwind dispatcher context.
00089
00090 Return Value:
00091
00092 If
the exception
is handled by one of
the exception filter
routines, then
00093 there
is no
return from
this routine and
RtlUnwind is called. Otherwise,
00094 an exception disposition value of
continue execution or
continue search
is
00095 returned.
00096
00097 --*/
00098
00099 {
00100
00101 ULONG_PTR ControlPc;
00102 EXCEPTION_FILTER ExceptionFilter;
00103 EXCEPTION_POINTERS ExceptionPointers;
00104 PRUNTIME_FUNCTION FunctionEntry;
00105 ULONG
Index;
00106 PSCOPE_TABLE ScopeTable;
00107 ULONG_PTR TargetPc;
00108 TERMINATION_HANDLER TerminationHandler;
00109 LONG Value;
00110
00111
00112
00113
00114
00115
00116
00117 ControlPc = DispatcherContext->ControlPc;
00118 FunctionEntry = DispatcherContext->FunctionEntry;
00119 ScopeTable = (PSCOPE_TABLE)(FunctionEntry->HandlerData);
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
if (IS_DISPATCHING(ExceptionRecord->ExceptionFlags)) {
00138
00139
00140
00141
00142
00143
00144
00145 ExceptionPointers.ExceptionRecord = ExceptionRecord;
00146 ExceptionPointers.ContextRecord = ContextRecord;
00147
00148
00149
00150
00151
00152
00153
00154
00155
for (
Index = 0;
Index < ScopeTable->Count;
Index += 1) {
00156
if ((ControlPc >= ScopeTable->ScopeRecord[
Index].BeginAddress) &&
00157 (ControlPc < ScopeTable->ScopeRecord[
Index].EndAddress) &&
00158 (ScopeTable->ScopeRecord[
Index].JumpTarget != 0)) {
00159
00160
00161
00162
00163
00164 ExceptionFilter =
00165 (EXCEPTION_FILTER)ScopeTable->ScopeRecord[
Index].HandlerAddress;
00166 Value =
__C_ExecuteExceptionFilter(&ExceptionPointers,
00167 ExceptionFilter,
00168 (ULONG_PTR)EstablisherFrame);
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
if (Value < 0) {
00188
return ExceptionContinueExecution;
00189
00190 }
else if (Value > 0) {
00191
00192
00193
00194
00195
00196
00197
00198
00199
RtlUnwind2(EstablisherFrame,
00200 (PVOID)ScopeTable->ScopeRecord[Index].JumpTarget,
00201 ExceptionRecord,
00202 ULongToPtr( ExceptionRecord->ExceptionCode ),
00203 ContextRecord);
00204 }
00205 }
00206 }
00207
00208 }
else {
00209
00210
00211
00212
00213
00214
00215 TargetPc = (ULONG_PTR)ContextRecord->Fir;
00216
for (
Index = 0;
Index < ScopeTable->Count;
Index += 1) {
00217
if ((ControlPc >= ScopeTable->ScopeRecord[
Index].BeginAddress) &&
00218 (ControlPc < ScopeTable->ScopeRecord[
Index].EndAddress)) {
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
if ((TargetPc >= ScopeTable->ScopeRecord[
Index].BeginAddress) &&
00232 (TargetPc <= ScopeTable->ScopeRecord[
Index].EndAddress)) {
00233
break;
00234
00235 }
else {
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
if (ScopeTable->ScopeRecord[
Index].JumpTarget != 0) {
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
if (TargetPc == ScopeTable->ScopeRecord[
Index].JumpTarget) {
00263
break;
00264 }
00265
00266 }
else {
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 DispatcherContext->ControlPc =
00280 ScopeTable->ScopeRecord[
Index].EndAddress + 4;
00281 TerminationHandler =
00282 (TERMINATION_HANDLER)ScopeTable->ScopeRecord[
Index].HandlerAddress;
00283
__C_ExecuteTerminationHandler(TRUE,
00284 TerminationHandler,
00285 (ULONG_PTR)EstablisherFrame);
00286 }
00287 }
00288 }
00289 }
00290 }
00291
00292
00293
00294
00295
00296
return ExceptionContinueSearch;
00297 }
}