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