mirror of
https://github.com/reactos/reactos.git
synced 2025-05-21 18:16:07 +00:00
210 lines
3.6 KiB
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;
|
|
}
|
|
|