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

raisexcp.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

VOID KiContinuePreviousModeUser (IN PCONTEXT ContextRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode)
NTSTATUS KiContinue (IN PCONTEXT ContextRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
NTSTATUS KiRaiseException (IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN BOOLEAN FirstChance)


Function Documentation

NTSTATUS KiContinue IN PCONTEXT  ContextRecord,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame
 

Definition at line 99 of file raisexcp.c.

References APC_LEVEL, EXCEPTION_EXECUTE_HANDLER, FALSE, KeContextToKframes(), KeLowerIrql(), KeRaiseIrql(), KernelMode, KiContinuePreviousModeUser(), KPROCESSOR_MODE, NTSTATUS(), Status, and TRUE.

00107 : 00108 00109 This function is called to copy the specified context frame to the 00110 specified exception and trap frames for the continue system service. 00111 00112 Arguments: 00113 00114 ContextRecord - Supplies a pointer to a context record. 00115 00116 ExceptionFrame - Supplies a pointer to an exception frame. 00117 00118 TrapFrame - Supplies a pointer to a trap frame. 00119 00120 Return Value: 00121 00122 STATUS_ACCESS_VIOLATION is returned if the context record is not readable 00123 from user mode. 00124 00125 STATUS_DATATYPE_MISALIGNMENT is returned if the context record is not 00126 properly aligned. 00127 00128 STATUS_SUCCESS is returned if the context frame is copied successfully 00129 to the specified exception and trap frames. 00130 00131 --*/ 00132 00133 { 00134 KPROCESSOR_MODE PreviousMode; 00135 NTSTATUS Status; 00136 KIRQL OldIrql; 00137 BOOLEAN IrqlChanged = FALSE; 00138 00139 // 00140 // Synchronize with other context operations. 00141 // 00142 00143 Status = STATUS_SUCCESS; 00144 if (KeGetCurrentIrql() < APC_LEVEL) { 00145 00146 // 00147 // To support try-except and ExRaiseStatus in device driver code we 00148 // need to check if we are already at raised level. 00149 // 00150 00151 IrqlChanged = TRUE; 00152 KeRaiseIrql(APC_LEVEL, &OldIrql); 00153 } 00154 00155 // 00156 // Establish an exception handler and probe and capture the specified 00157 // context record if the previous mode is user. If the probe or copy 00158 // fails, then return the exception code as the function value. Else 00159 // copy the context record to the specified exception and trap frames, 00160 // and return success as the function value. 00161 // 00162 00163 try { 00164 00165 // 00166 // Get the previous processor mode. If the previous processor mode is 00167 // user, then probe and copy the specified context record. 00168 // 00169 00170 PreviousMode = KeGetPreviousMode(); 00171 if (PreviousMode != KernelMode) { 00172 KiContinuePreviousModeUser(ContextRecord, 00173 ExceptionFrame, 00174 TrapFrame, 00175 PreviousMode); 00176 } else { 00177 00178 // 00179 // Move information from the context record to the exception 00180 // and trap frames. 00181 // 00182 00183 KeContextToKframes(TrapFrame, 00184 ExceptionFrame, 00185 ContextRecord, 00186 ContextRecord->ContextFlags, 00187 PreviousMode); 00188 } 00189 00190 // 00191 // If an exception occurs during the probe or copy of the context 00192 // record, then always handle the exception and return the exception 00193 // code as the status value. 00194 // 00195 00196 } except(EXCEPTION_EXECUTE_HANDLER) { 00197 Status = GetExceptionCode(); 00198 } 00199 00200 if (IrqlChanged) { 00201 KeLowerIrql (OldIrql); 00202 } 00203 00204 return Status; 00205 }

VOID KiContinuePreviousModeUser IN PCONTEXT  ContextRecord,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN KPROCESSOR_MODE  PreviousMode
 

Definition at line 37 of file raisexcp.c.

References KeContextToKframes(), and ProbeForRead.

Referenced by KiContinue().

00046 : 00047 00048 This function is called from KiContinue if PreviousMode is 00049 not KernelMode. In this case a kernel mode copy of the 00050 ContextRecord is made before calling KeContextToKframes. 00051 This is done in a seperate routine to save stack space for 00052 the common case which is PreviousMode == Kernel. 00053 00054 N.B. This routine is called from within a try/except block 00055 that will be used to handle errors like invalid context. 00056 00057 Arguments: 00058 00059 00060 ContextRecord - Supplies a pointer to a context record. 00061 00062 ExceptionFrame - Supplies a pointer to an exception frame. 00063 00064 TrapFrame - Supplies a pointer to a trap frame. 00065 00066 PreviousMode - Not KernelMode. 00067 00068 Return Value: 00069 00070 None. 00071 00072 --*/ 00073 00074 { 00075 CONTEXT ContextRecord2; 00076 00077 // 00078 // Copy the context record to kernel mode space. 00079 // 00080 00081 ProbeForRead(ContextRecord, sizeof(CONTEXT), CONTEXT_ALIGN); 00082 RtlMoveMemory(&ContextRecord2, ContextRecord, sizeof(CONTEXT)); 00083 ContextRecord = &ContextRecord2; 00084 00085 // 00086 // Move information from the context record to the exception 00087 // and trap frames. 00088 // 00089 00090 KeContextToKframes(TrapFrame, 00091 ExceptionFrame, 00092 &ContextRecord2, 00093 ContextRecord2.ContextFlags, 00094 PreviousMode); 00095 }

NTSTATUS KiRaiseException IN PEXCEPTION_RECORD  ExceptionRecord,
IN PCONTEXT  ContextRecord,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN BOOLEAN  FirstChance
 

Definition at line 208 of file raisexcp.c.

References EXCEPTION_EXECUTE_HANDLER, KeContextToKframes(), KernelMode, KiDispatchException(), KPROCESSOR_MODE, and ProbeForRead.

00218 : 00219 00220 This function is called to raise an exception. The exception can be 00221 raised as a first or second chance exception. 00222 00223 Arguments: 00224 00225 ExceptionRecord - Supplies a pointer to an exception record. 00226 00227 ContextRecord - Supplies a pointer to a context record. 00228 00229 ExceptionFrame - Supplies a pointer to an exception frame. 00230 00231 TrapFrame - Supplies a pointer to a trap frame. 00232 00233 FirstChance - Supplies a boolean value that specifies whether this is 00234 the first (TRUE) or second (FALSE) chance for the exception. 00235 00236 Return Value: 00237 00238 STATUS_ACCESS_VIOLATION is returned if either the exception or the context 00239 record is not readable from user mode. 00240 00241 STATUS_DATATYPE_MISALIGNMENT is returned if the exception record or the 00242 context record are not properly aligned. 00243 00244 STATUS_INVALID_PARAMETER is returned if the number of exception parameters 00245 is greater than the maximum allowable number of exception parameters. 00246 00247 STATUS_SUCCESS is returned if the exception is dispatched and handled. 00248 00249 --*/ 00250 00251 { 00252 00253 CONTEXT ContextRecord2; 00254 EXCEPTION_RECORD ExceptionRecord2; 00255 ULONG Length; 00256 ULONG Params; 00257 KPROCESSOR_MODE PreviousMode; 00258 00259 // 00260 // Establish an exception handler and probe the specified exception and 00261 // context records for read accessibility. If the probe fails, then 00262 // return the exception code as the service status. Else call the exception 00263 // dispatcher to dispatch the exception. 00264 // 00265 00266 try { 00267 00268 // 00269 // Get the previous processor mode. If the previous processor mode 00270 // is user, then probe and copy the specified exception and context 00271 // records. 00272 // 00273 00274 PreviousMode = KeGetPreviousMode(); 00275 if (PreviousMode != KernelMode) { 00276 ProbeForRead(ContextRecord, sizeof(CONTEXT), CONTEXT_ALIGN); 00277 ProbeForRead(ExceptionRecord, 00278 FIELD_OFFSET (EXCEPTION_RECORD, NumberParameters) + 00279 sizeof (ExceptionRecord->NumberParameters), sizeof(ULONG)); 00280 Params = ExceptionRecord->NumberParameters; 00281 if (Params > EXCEPTION_MAXIMUM_PARAMETERS) { 00282 return STATUS_INVALID_PARAMETER; 00283 } 00284 00285 // 00286 // The exception record structure is defined unlike others with trailing 00287 // information as being its maximum size rather than just a single trailing 00288 // element. 00289 // 00290 Length = (sizeof(EXCEPTION_RECORD) - 00291 ((EXCEPTION_MAXIMUM_PARAMETERS - Params) * 00292 sizeof(ExceptionRecord->ExceptionInformation[0]))); 00293 00294 // 00295 // The structure is currently less that 64k so we don't really need this probe. 00296 // 00297 ProbeForRead(ExceptionRecord, Length, sizeof(ULONG)); 00298 00299 // 00300 // Copy the exception and context record to local storage so an 00301 // access violation cannot occur during exception dispatching. 00302 // 00303 00304 RtlMoveMemory(&ContextRecord2, ContextRecord, sizeof(CONTEXT)); 00305 RtlMoveMemory(&ExceptionRecord2, ExceptionRecord, Length); 00306 ContextRecord = &ContextRecord2; 00307 ExceptionRecord = &ExceptionRecord2; 00308 // 00309 // The number of parameters might have changed after we validated but before we 00310 // copied the structure. Fix this up as lower levels might not like this. 00311 // 00312 ExceptionRecord->NumberParameters = Params; 00313 } 00314 00315 // 00316 // If an exception occurs during the probe of the exception or context 00317 // record, then always handle the exception and return the exception code 00318 // as the status value. 00319 // 00320 00321 } except(EXCEPTION_EXECUTE_HANDLER) { 00322 return GetExceptionCode(); 00323 } 00324 00325 // 00326 // Move information from the context record to the exception and 00327 // trap frames. 00328 // 00329 00330 KeContextToKframes(TrapFrame, 00331 ExceptionFrame, 00332 ContextRecord, 00333 ContextRecord->ContextFlags, 00334 PreviousMode); 00335 00336 // 00337 // Make sure the reserved bit is clear in the exception code and 00338 // perform exception dispatching. 00339 // 00340 // N.B. The reserved bit is used to differentiate internally gerarated 00341 // codes from codes generated by application programs. 00342 // 00343 00344 ExceptionRecord->ExceptionCode &= 0xefffffff; 00345 KiDispatchException(ExceptionRecord, 00346 ExceptionFrame, 00347 TrapFrame, 00348 PreviousMode, 00349 FirstChance); 00350 00351 return STATUS_SUCCESS; 00352 } }


Generated on Sat May 15 19:45:26 2004 for test by doxygen 1.3.7