test: raisests.c Source File

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 }