reactos/drivers/filesystems/ffs/src/except.c

210 lines
3.6 KiB
C

/*
* FFS File System Driver for Windows
*
* except.c
*
* 2004.5.6 ~
*
* Lee Jae-Hong, http://www.pyrasis.com
*
* See License.txt
*
*/
#include "ntifs.h"
#include "ffsdrv.h"
/* Globals */
extern PFFS_GLOBAL FFSGlobal;
/* Definitions */
#ifdef ALLOC_PRAGMA
//#pragma alloc_text(PAGE, FFSExceptionFilter)
//#pragma alloc_text(PAGE, FFSExceptionHandler)
#endif
NTSTATUS
FFSExceptionFilter(
IN PFFS_IRP_CONTEXT IrpContext,
IN PEXCEPTION_POINTERS ExceptionPointer)
{
NTSTATUS Status, ExceptionCode;
PEXCEPTION_RECORD ExceptRecord;
ExceptRecord = ExceptionPointer->ExceptionRecord;
ExceptionCode = ExceptRecord->ExceptionCode;
FFSBreakPoint();
//
// Check IrpContext is valid or not
//
if (IrpContext)
{
if ((IrpContext->Identifier.Type != FFSICX) ||
(IrpContext->Identifier.Size != sizeof(FFS_IRP_CONTEXT)))
{
IrpContext = NULL;
}
}
else
{
if (FsRtlIsNtstatusExpected(ExceptionCode))
{
return EXCEPTION_EXECUTE_HANDLER;
}
else
{
FFSBugCheck(FFS_BUGCHK_EXCEPT, (ULONG_PTR)ExceptRecord,
(ULONG_PTR)ExceptionPointer->ContextRecord,
(ULONG_PTR)ExceptRecord->ExceptionAddress);
}
}
//
// For the purposes of processing this exception, let's mark this
// request as being able to wait, and neither write through nor on
// removable media if we aren't posting it.
//
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
if (FsRtlIsNtstatusExpected(ExceptionCode))
{
//
// If the exception is expected execute our handler
//
FFSPrint((DBG_ERROR, "FFSExceptionFilter: 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
//
FFSPrint((DBG_ERROR, "FFSExceptionFilter: Passing on exception %#x\n",
ExceptionCode));
Status = EXCEPTION_CONTINUE_SEARCH;
if (IrpContext)
{
FFSFreeIrpContext(IrpContext);
}
}
return Status;
}
NTSTATUS
FFSExceptionHandler(
IN PFFS_IRP_CONTEXT IrpContext)
{
NTSTATUS Status;
FFSBreakPoint();
if (IrpContext)
{
if ((IrpContext->Identifier.Type != FFSICX) ||
(IrpContext->Identifier.Size != sizeof(FFS_IRP_CONTEXT)))
{
FFSBreakPoint();
return STATUS_UNSUCCESSFUL;
}
Status = IrpContext->ExceptionCode;
if (IrpContext->Irp)
{
//
// Check if this error is a result of user actions
//
PIRP Irp = IrpContext->Irp;
if (IoIsErrorUserInduced(Status))
{
//
// Now we will generate a pop-up to user
//
PDEVICE_OBJECT RealDevice;
PVPB Vpb = NULL;
PETHREAD Thread;
if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
{
Vpb = IoGetCurrentIrpStackLocation(Irp)->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);
}
if (RealDevice != NULL)
{
//
// Now we pop-up the error dialog ...
//
IoMarkIrpPending(Irp);
IoRaiseHardError(Irp, Vpb, RealDevice);
IoSetDeviceToVerify(Thread, NULL);
Status = STATUS_PENDING;
goto errorout;
}
}
IrpContext->Irp->IoStatus.Status = Status;
FFSCompleteRequest(IrpContext->Irp, FALSE, IO_NO_INCREMENT);
}
errorout:
FFSFreeIrpContext(IrpContext);
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
return Status;
}