00058 :
00059
00060 This function scans
the scope tables associated with
the specified
00061
procedure and calls exception and termination handlers as necessary.
00062
00063 Arguments:
00064
00065 ExceptionRecord - Supplies a pointer to an exception record.
00066
00067 EstablisherFrame - Supplies a pointer to frame of
the establisher function.
00068
00069 ContextRecord - Supplies a pointer to a context record.
00070
00071 DispatcherContext - Supplies a pointer to
the exception dispatcher or
00072 unwind dispatcher context.
00073
00074 Return Value:
00075
00076 If
the exception
is handled by one of
the exception filter
routines, then
00077 there
is no
return from
this routine and
RtlUnwind is called. Otherwise,
00078 an exception disposition value of
continue execution or
continue search
is
00079 returned.
00080
00081 --*/
00082
00083 {
00084
00085 ULONG ControlPc;
00086 EXCEPTION_FILTER ExceptionFilter;
00087 EXCEPTION_POINTERS ExceptionPointers;
00088 PRUNTIME_FUNCTION FunctionEntry;
00089 ULONG
Index;
00090 PSCOPE_TABLE ScopeTable;
00091 ULONG TargetPc;
00092 TERMINATION_HANDLER TerminationHandler;
00093 LONG Value;
00094
00095
00096
00097
00098
00099
00100
00101 ControlPc = DispatcherContext->ControlPc;
00102 FunctionEntry = DispatcherContext->FunctionEntry;
00103 ScopeTable = (PSCOPE_TABLE)(FunctionEntry->HandlerData);
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
if (IS_DISPATCHING(ExceptionRecord->ExceptionFlags)) {
00114
00115
00116
00117
00118
00119
00120 ExceptionPointers.ExceptionRecord = ExceptionRecord;
00121 ExceptionPointers.ContextRecord = ContextRecord;
00122
for (
Index = 0;
Index < ScopeTable->Count;
Index += 1) {
00123
if ((ControlPc >= ScopeTable->ScopeRecord[
Index].BeginAddress) &&
00124 (ControlPc < ScopeTable->ScopeRecord[
Index].EndAddress) &&
00125 (ScopeTable->ScopeRecord[
Index].JumpTarget != 0)) {
00126
00127
00128
00129
00130
00131 ExceptionFilter =
00132 (EXCEPTION_FILTER)ScopeTable->ScopeRecord[
Index].HandlerAddress;
00133 Value =
__C_ExecuteExceptionFilter(&ExceptionPointers,
00134 ExceptionFilter,
00135 (ULONG)EstablisherFrame);
00136
00137
00138
00139
00140
00141
00142
00143
00144
if (Value < 0) {
00145
return ExceptionContinueExecution;
00146
00147 }
else if (Value > 0) {
00148
RtlUnwind2(EstablisherFrame,
00149 (PVOID)ScopeTable->ScopeRecord[Index].JumpTarget,
00150 ExceptionRecord,
00151 (PVOID)ExceptionRecord->ExceptionCode,
00152 ContextRecord);
00153 }
00154 }
00155 }
00156
00157 }
else {
00158
00159
00160
00161
00162
00163
00164 TargetPc = ContextRecord->Fir;
00165
for (
Index = 0;
Index < ScopeTable->Count;
Index += 1) {
00166
if ((ControlPc >= ScopeTable->ScopeRecord[
Index].BeginAddress) &&
00167 (ControlPc < ScopeTable->ScopeRecord[
Index].EndAddress)) {
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
if ((TargetPc >= ScopeTable->ScopeRecord[
Index].BeginAddress) &&
00181 (TargetPc <= ScopeTable->ScopeRecord[
Index].EndAddress)) {
00182
break;
00183
00184 }
else {
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
if (ScopeTable->ScopeRecord[
Index].JumpTarget != 0) {
00197
if (TargetPc == ScopeTable->ScopeRecord[
Index].JumpTarget) {
00198
break;
00199 }
00200
00201 }
else {
00202 DispatcherContext->ControlPc =
00203 ScopeTable->ScopeRecord[
Index].EndAddress + 4;
00204 TerminationHandler =
00205 (TERMINATION_HANDLER)ScopeTable->ScopeRecord[
Index].HandlerAddress;
00206
__C_ExecuteTerminationHandler(TRUE,
00207 TerminationHandler,
00208 (ULONG)EstablisherFrame);
00209 }
00210 }
00211 }
00212 }
00213 }
00214
00215
00216
00217
00218
00219
return ExceptionContinueSearch;
00220 }
}