143 lines
3.7 KiB
C
143 lines
3.7 KiB
C
/*++
|
||
|
||
Copyright (c) 1994 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
Except.h
|
||
|
||
Abstract:
|
||
|
||
This module prototypes the macros and routines used for exception handling.
|
||
|
||
Author:
|
||
|
||
Joe Linn [JoeLinn] 24-aug-1994
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#ifndef _EXCEPTION_STUFF_DEFINED_
|
||
#define _EXCEPTION_STUFF_DEFINED_
|
||
|
||
|
||
//
|
||
// The following two macro are used by the Fsd/Fsp exception handlers to
|
||
// process an exception. The first macro is the exception filter used in the
|
||
// Fsd/Fsp to decide if an exception should be handled at this level.
|
||
// The second macro decides if the exception is to be finished off by
|
||
// completing the IRP, and cleaning up the Irp Context, or if we should
|
||
// bugcheck. Exception values such as RxStatus(FILE_INVALID) (raised by
|
||
// VerfySup.c) cause us to complete the Irp and cleanup, while exceptions
|
||
// such as accvio cause us to bugcheck.
|
||
//
|
||
// The basic structure for fsd/fsp exception handling is as follows:
|
||
//
|
||
// RxFsdXxx(...)
|
||
// {
|
||
// try {
|
||
//
|
||
// ...
|
||
//
|
||
// } except(RxExceptionFilter( RxContext, GetExceptionCode() )) {
|
||
//
|
||
// Status = RxProcessException( RxContext, GetExceptionCode() );
|
||
// }
|
||
//
|
||
// Return Status;
|
||
// }
|
||
//
|
||
// To explicitly raise an exception that we expect, such as
|
||
// RxStatus(FILE_INVALID), use the below macro RxRaiseStatus(). To raise a
|
||
// status from an unknown origin (such as CcFlushCache()), use the macro
|
||
// RxNormalizeAndRaiseStatus. This will raise the status if it is expected,
|
||
// or raise RxStatus(UNEXPECTED_IO_ERROR) if it is not.
|
||
//
|
||
// Note that when using these two macros, the original status is placed in
|
||
// RxContext->ExceptionStatus, signaling RxExceptionFilter and
|
||
// RxProcessException that the status we actually raise is by definition
|
||
// expected.
|
||
//
|
||
|
||
LONG
|
||
RxExceptionFilter (
|
||
IN PRX_CONTEXT RxContext,
|
||
IN PEXCEPTION_POINTERS ExceptionPointer
|
||
);
|
||
|
||
NTSTATUS
|
||
RxProcessException (
|
||
IN PRX_CONTEXT RxContext,
|
||
IN NTSTATUS ExceptionCode
|
||
);
|
||
|
||
#define CATCH_EXPECTED_EXCEPTIONS (FsRtlIsNtstatusExpected(GetExceptionCode()) ? \
|
||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH )
|
||
|
||
|
||
//
|
||
// VOID
|
||
// RxRaiseStatus (
|
||
// IN PRIP_CONTEXT RxContext,
|
||
// IN NT_STATUS Status
|
||
// );
|
||
//
|
||
//
|
||
|
||
#define RxRaiseStatus(RXCONTEXT,STATUS) { \
|
||
ASSERT((RXCONTEXT)!=NULL); \
|
||
if (RxContext!=NULL) {(RXCONTEXT)->StoredStatus = (STATUS); } \
|
||
ExRaiseStatus( (STATUS) ); \
|
||
}
|
||
|
||
//
|
||
// VOID
|
||
// RxNormalAndRaiseStatus (
|
||
// IN PRIP_CONTEXT RxContext,
|
||
// IN NT_STATUS Status
|
||
// );
|
||
//
|
||
|
||
#define RxNormalizeAndRaiseStatus(RXCONTEXT,STATUS) { \
|
||
ASSERT((RXCONTEXT)!=NULL); \
|
||
if (RxContext!=NULL) {(RXCONTEXT)->StoredStatus = (STATUS); } \
|
||
if ((STATUS) == (STATUS_VERIFY_REQUIRED)) { ExRaiseStatus((STATUS)); } \
|
||
ExRaiseStatus(FsRtlNormalizeNtstatus((STATUS),(STATUS_UNEXPECTED_IO_ERROR))); \
|
||
}
|
||
|
||
|
||
//
|
||
// The following macros are used to establish the semantics needed
|
||
// to do a return from within a try-finally clause. As a rule every
|
||
// try clause must end with a label call try_exit. For example,
|
||
//
|
||
// try {
|
||
// :
|
||
// :
|
||
//
|
||
// try_exit: NOTHING;
|
||
// } finally {
|
||
//
|
||
// :
|
||
// :
|
||
// }
|
||
//
|
||
// Every return statement executed inside of a try clause should use the
|
||
// try_return macro. If the compiler fully supports the try-finally construct
|
||
// then the macro should be
|
||
//
|
||
// #define try_return(S) { return(S); }
|
||
//
|
||
// If the compiler does not support the try-finally construct then the macro
|
||
// should be
|
||
//
|
||
// #define try_return(S) { S; goto try_exit; }
|
||
//
|
||
|
||
#define try_return(S) { S; goto try_exit; }
|
||
|
||
|
||
|
||
#endif // _EXCEPTION_STUFF_DEFINED_
|
||
|