Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274/* * COPYRIGHT: See COPYRIGHT.TXT * PROJECT: Ext2 File System Driver for WinNT/2K/XP * FILE: except.c * PROGRAMMER: Matt Wu <mattwu@163.com> * HOMEPAGE: http://www.ext2fsd.com * UPDATE HISTORY: */
/* INCLUDES *****************************************************************/
#include "ext2fs.h"
/* GLOBALS ***************************************************************/
extern PEXT2_GLOBAL Ext2Global;
/* DEFINITIONS *************************************************************/
NTSTATUSExt2ExceptionFilter ( IN PEXT2_IRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer){ NTSTATUS Status = EXCEPTION_EXECUTE_HANDLER; NTSTATUS ExceptionCode; PEXCEPTION_RECORD ExceptRecord;
ExceptRecord = ExceptionPointer->ExceptionRecord; ExceptionCode = ExceptRecord->ExceptionCode;
DbgPrint("-------------------------------------------------------------\n"); DbgPrint("Exception happends in Ext2Fsd (code %xh):\n", ExceptionCode); DbgPrint(".exr %p;.cxr %p;\n", ExceptionPointer->ExceptionRecord, ExceptionPointer->ContextRecord); DbgPrint("-------------------------------------------------------------\n");
DbgBreak();
// // Check IrpContext is valid or not //
if (IrpContext) { if ((IrpContext->Identifier.Type != EXT2ICX) || (IrpContext->Identifier.Size != sizeof(EXT2_IRP_CONTEXT))) { DbgBreak(); IrpContext = NULL; } else if (IrpContext->DeviceObject) { PEXT2_VCB Vcb = NULL; Vcb = (PEXT2_VCB) IrpContext->DeviceObject->DeviceExtension; if (NULL == Vcb) { Status = EXCEPTION_EXECUTE_HANDLER; } else { if (Vcb->Identifier.Type == EXT2VCB && !IsMounted(Vcb)) { Status = EXCEPTION_EXECUTE_HANDLER; } } } } else { if (FsRtlIsNtstatusExpected(ExceptionCode)) { return EXCEPTION_EXECUTE_HANDLER; } else { Ext2BugCheck( EXT2_BUGCHK_EXCEPT, (ULONG_PTR)ExceptRecord, (ULONG_PTR)ExceptionPointer->ContextRecord, (ULONG_PTR)ExceptRecord->ExceptionAddress ); } }
if (IrpContext) { SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); }
if ( Status == EXCEPTION_EXECUTE_HANDLER || FsRtlIsNtstatusExpected(ExceptionCode)) { // // If the exception is expected execute our handler //
DEBUG(DL_ERR, ( "Ext2ExceptionFilter: Catching exception %xh\n", ExceptionCode));
Status = EXCEPTION_EXECUTE_HANDLER;
if (IrpContext) { IrpContext->ExceptionInProgress = TRUE; IrpContext->ExceptionCode = ExceptionCode; }
} else {
// // Continue search for an higher level exception handler //
DEBUG(DL_ERR, ( "Ext2ExceptionFilter: Passing on exception %#x\n", ExceptionCode));
Status = EXCEPTION_CONTINUE_SEARCH;
if (IrpContext) { Ext2FreeIrpContext(IrpContext); } }
return Status;}
NTSTATUSExt2ExceptionHandler (IN PEXT2_IRP_CONTEXT IrpContext){ NTSTATUS Status;
if (IrpContext) {
if ( (IrpContext->Identifier.Type != EXT2ICX) || (IrpContext->Identifier.Size != sizeof(EXT2_IRP_CONTEXT))) { DbgBreak(); return STATUS_UNSUCCESSFUL; }
Status = IrpContext->ExceptionCode;
if (IrpContext->Irp) {
// // Check if this error is a result of user actions //
PEXT2_VCB Vcb = NULL; PIRP Irp = IrpContext->Irp; PIO_STACK_LOCATION IrpSp;
IrpSp = IoGetCurrentIrpStackLocation(Irp); Vcb = (PEXT2_VCB) IrpContext->DeviceObject->DeviceExtension;
if (NULL == Vcb) { Status = STATUS_INVALID_PARAMETER; } else if (Vcb->Identifier.Type != EXT2VCB) { Status = STATUS_INVALID_PARAMETER; } else if (!IsMounted(Vcb)) { if (IsFlagOn(Vcb->Flags, VCB_DEVICE_REMOVED)) { Status = STATUS_NO_SUCH_DEVICE; } else { Status = STATUS_VOLUME_DISMOUNTED; } } else {
/* queue it again if our request is at top level */ if (IrpContext->IsTopLevel && ((Status == STATUS_CANT_WAIT) || ((Status == STATUS_VERIFY_REQUIRED) && (KeGetCurrentIrql() >= APC_LEVEL)))) {
Status = Ext2QueueRequest(IrpContext); } }
if (Status == STATUS_PENDING) { goto errorout; }
Irp->IoStatus.Status = Status;
if (IoIsErrorUserInduced(Status)) {
// // Now we will generate a pop-up to user //
PDEVICE_OBJECT RealDevice; PVPB Vpb = NULL; PETHREAD Thread;
if (IrpSp->FileObject != NULL) { Vpb = IrpSp->FileObject->Vpb; }
// // Get the initial thread //
Thread = Irp->Tail.Overlay.Thread; RealDevice = IoGetDeviceToVerify( Thread );
if (RealDevice == NULL) { // // Get current thread //
Thread = PsGetCurrentThread(); RealDevice = IoGetDeviceToVerify( Thread );
ASSERT( RealDevice != NULL ); }
Status = IrpContext->ExceptionCode;
if (RealDevice != NULL) {
if (IrpContext->ExceptionCode == STATUS_VERIFY_REQUIRED) {
Status = IoVerifyVolume (RealDevice, FALSE);
ExAcquireResourceSharedLite(&Vcb->MainResource, TRUE); if (NT_SUCCESS(Status) && (!IsMounted(Vcb) || IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))) { Status = STATUS_WRONG_VOLUME; } ExReleaseResourceLite(&Vcb->MainResource);
if (Ext2CheckDismount(IrpContext, Vcb, FALSE)) { Ext2CompleteIrpContext( IrpContext, STATUS_VOLUME_DISMOUNTED); Status = STATUS_VOLUME_DISMOUNTED; Irp = NULL; goto errorout; }
if ( (IrpContext->MajorFunction == IRP_MJ_CREATE) && (IrpContext->FileObject->RelatedFileObject == NULL) && ((Status == STATUS_SUCCESS) || (Status == STATUS_WRONG_VOLUME))) {
Irp->IoStatus.Information = IO_REMOUNT;
Ext2CompleteIrpContext( IrpContext, STATUS_REPARSE); Status = STATUS_REPARSE; Irp = NULL; }
if (Irp) {
if (!NT_SUCCESS(Status)) { IoSetHardErrorOrVerifyDevice(Irp, RealDevice); ASSERT (STATUS_VERIFY_REQUIRED != Status); Ext2NormalizeAndRaiseStatus(IrpContext, Status); }
Status = Ext2QueueRequest(IrpContext); }
goto errorout;
} else {
Status = STATUS_PENDING;
IoMarkIrpPending( Irp ); IoRaiseHardError( Irp, Vpb, RealDevice ); IoSetDeviceToVerify( Thread, NULL ); goto release_context; } } }
Ext2CompleteRequest(Irp, FALSE, IO_NO_INCREMENT); }
release_context:
Ext2FreeIrpContext(IrpContext);
} else {
Status = STATUS_INVALID_PARAMETER; }
errorout:
return Status;}