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     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 }