Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

raisests.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 raisests.c 00008 00009 Abstract: 00010 00011 This module implements routines to raise a general exception from kernel 00012 mode or a noncontinuable exception from kernel mode. 00013 00014 Author: 00015 00016 David N. Cutler (davec) 18-Oct-1990 00017 00018 Environment: 00019 00020 Any mode. 00021 00022 Revision History: 00023 00024 Thomas Van Baak (tvb) 5-May-1992 00025 00026 Adapted for Alpha AXP. 00027 00028 --*/ 00029 00030 #include "exp.h" 00031 00032 // 00033 // Define private function prototypes. 00034 // 00035 00036 VOID 00037 ExpRaiseException ( 00038 IN PEXCEPTION_RECORD ExceptionRecord 00039 ); 00040 00041 VOID 00042 ExpRaiseStatus ( 00043 IN NTSTATUS ExceptionCode 00044 ); 00045 00046 VOID 00047 ExRaiseException ( 00048 IN PEXCEPTION_RECORD ExceptionRecord 00049 ) 00050 00051 /*++ 00052 00053 Routine Description: 00054 00055 This function raises a software exception by building a context record 00056 and calling the exception dispatcher directly. 00057 00058 N.B. This routine is a shell routine that simply calls another routine 00059 to do the real work. The reason this is done is to avoid a problem 00060 in try/finally scopes where the last statement in the scope is a 00061 call to raise an exception. 00062 00063 Arguments: 00064 00065 ExceptionRecord - Supplies a pointer to an exception record. 00066 00067 Return Value: 00068 00069 None. 00070 00071 --*/ 00072 00073 { 00074 00075 #ifdef DBGtvb 00076 DbgPrint("ExRaiseException(ExceptionRecord = %lx) Status = %lx\n", 00077 ExceptionRecord, ExceptionRecord->ExceptionCode); 00078 ); 00079 #endif 00080 ExpRaiseException(ExceptionRecord); 00081 return; 00082 } 00083 00084 VOID 00085 ExpRaiseException ( 00086 IN PEXCEPTION_RECORD ExceptionRecord 00087 ) 00088 00089 /*++ 00090 00091 Routine Description: 00092 00093 This function raises a software exception by building a context record 00094 and calling the exception dispatcher directly. 00095 00096 Arguments: 00097 00098 ExceptionRecord - Supplies a pointer to an exception record. 00099 00100 Return Value: 00101 00102 None. 00103 00104 --*/ 00105 00106 { 00107 00108 ULONG_PTR ControlPc; 00109 CONTEXT ContextRecord; 00110 FRAME_POINTERS EstablisherFrame; 00111 PRUNTIME_FUNCTION FunctionEntry; 00112 BOOLEAN InFunction; 00113 ULONG_PTR NextPc; 00114 NTSTATUS Status; 00115 00116 // 00117 // Capture the current context, virtually unwind to the caller of this 00118 // routine, set the fault instruction address to that of the caller, and 00119 // call the exception dispatcher. 00120 // 00121 00122 RtlCaptureContext(&ContextRecord); 00123 ControlPc = (ULONG_PTR)ContextRecord.IntRa - 4; 00124 FunctionEntry = RtlLookupFunctionEntry(ControlPc); 00125 NextPc = RtlVirtualUnwind(ControlPc, 00126 FunctionEntry, 00127 &ContextRecord, 00128 &InFunction, 00129 &EstablisherFrame, 00130 NULL); 00131 00132 ContextRecord.Fir = (ULONGLONG)(LONG_PTR)NextPc + 4; 00133 ExceptionRecord->ExceptionAddress = (PVOID)ContextRecord.Fir; 00134 00135 // 00136 // If the exception is successfully dispatched, then continue execution. 00137 // Otherwise, give the kernel debugger a chance to handle the exception. 00138 // 00139 00140 if (RtlDispatchException(ExceptionRecord, &ContextRecord)) { 00141 Status = ZwContinue(&ContextRecord, FALSE); 00142 00143 } else { 00144 Status = ZwRaiseException(ExceptionRecord, &ContextRecord, FALSE); 00145 } 00146 00147 // 00148 // Either the attempt to continue execution or the attempt to give 00149 // the kernel debugger a chance to handle the exception failed. Raise 00150 // a noncontinuable exception. 00151 // 00152 00153 ExRaiseStatus(Status); 00154 } 00155 00156 VOID 00157 ExRaiseStatus ( 00158 IN NTSTATUS ExceptionCode 00159 ) 00160 00161 /*++ 00162 00163 Routine Description: 00164 00165 This function raises an exception with the specified status value by 00166 building an exception record, building a context record, and calling the 00167 exception dispatcher directly. The exception is marked as noncontinuable 00168 with no parameters. There is no return from this function. 00169 00170 N.B. This routine is a shell routine that simply calls another routine 00171 to do the real work. The reason this is done is to avoid a problem 00172 in try/finally scopes where the last statement in the scope is a 00173 call to raise an exception. 00174 00175 Arguments: 00176 00177 ExceptionCode - Supplies the status value to be used as the exception 00178 code for the exception that is to be raised. 00179 00180 Return Value: 00181 00182 None. 00183 00184 --*/ 00185 00186 { 00187 00188 #ifdef DBGxx 00189 DbgPrint("ExRaiseStatus(ExceptionCode = %lx)\n", ExceptionCode); 00190 #endif 00191 ExpRaiseStatus(ExceptionCode); 00192 return; 00193 } 00194 00195 VOID 00196 ExpRaiseStatus ( 00197 IN NTSTATUS ExceptionCode 00198 ) 00199 00200 /*++ 00201 00202 Routine Description: 00203 00204 This function raises an exception with the specified status value by 00205 building an exception record, building a context record, and calling the 00206 exception dispatcher directly. The exception is marked as noncontinuable 00207 with no parameters. There is no return from this function. 00208 00209 Arguments: 00210 00211 ExceptionCode - Supplies the status value to be used as the exception 00212 code for the exception that is to be raised. 00213 00214 Return Value: 00215 00216 None. 00217 00218 --*/ 00219 00220 { 00221 00222 ULONG_PTR ControlPc; 00223 CONTEXT ContextRecord; 00224 FRAME_POINTERS EstablisherFrame; 00225 EXCEPTION_RECORD ExceptionRecord; 00226 PRUNTIME_FUNCTION FunctionEntry; 00227 BOOLEAN InFunction; 00228 ULONG_PTR NextPc; 00229 NTSTATUS Status; 00230 00231 // 00232 // Construct an exception record. 00233 // 00234 00235 ExceptionRecord.ExceptionCode = ExceptionCode; 00236 ExceptionRecord.ExceptionRecord = (PEXCEPTION_RECORD)NULL; 00237 ExceptionRecord.NumberParameters = 0; 00238 ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; 00239 00240 // 00241 // Capture the current context, virtually unwind to the caller of this 00242 // routine, set the fault instruction address to that of the caller, and 00243 // call the exception dispatcher. 00244 // 00245 00246 RtlCaptureContext(&ContextRecord); 00247 ControlPc = (ULONG_PTR)ContextRecord.IntRa - 4; 00248 FunctionEntry = RtlLookupFunctionEntry(ControlPc); 00249 NextPc = RtlVirtualUnwind(ControlPc, 00250 FunctionEntry, 00251 &ContextRecord, 00252 &InFunction, 00253 &EstablisherFrame, 00254 NULL); 00255 00256 ContextRecord.Fir = (ULONGLONG)(LONG_PTR)NextPc + 4; 00257 ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Fir; 00258 RtlDispatchException(&ExceptionRecord, &ContextRecord); 00259 00260 // 00261 // An unwind was not initiated during the dispatching of a noncontinuable 00262 // exception. Give the kernel debugger a chance to handle the exception. 00263 // 00264 00265 Status = ZwRaiseException(&ExceptionRecord, &ContextRecord, FALSE); 00266 00267 // 00268 // The attempt to give the kernel debugger a chance to handle the exception 00269 // failed. Raise another noncontinuable exception. 00270 // 00271 00272 ExRaiseStatus(Status); 00273 }

Generated on Sat May 15 19:41:35 2004 for test by doxygen 1.3.7