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

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