⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatdata.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

Copyright (c) 1989-2000 Microsoft Corporation

Module Name:

    FatData.c

Abstract:

    This module declares the global data used by the Fat file system.


--*/

#include "FatProcs.h"

//
//  The Bug check file id for this module
//

#define BugCheckFileId                   (FAT_BUG_CHECK_FATDATA)

//
//  The debug trace level
//

#define Dbg                              (DEBUG_TRACE_CATCH_EXCEPTIONS)

#ifdef ALLOC_PRAGMA

#if DBG
#pragma alloc_text(PAGE, FatBugCheckExceptionFilter)
#endif

#pragma alloc_text(PAGE, FatCompleteRequest_Real)
#pragma alloc_text(PAGE, FatFastIoCheckIfPossible)
#pragma alloc_text(PAGE, FatFastQueryBasicInfo)
#pragma alloc_text(PAGE, FatFastQueryNetworkOpenInfo)
#pragma alloc_text(PAGE, FatFastQueryStdInfo)
#pragma alloc_text(PAGE, FatIsIrpTopLevel)
#pragma alloc_text(PAGE, FatPopUpFileCorrupt)
#pragma alloc_text(PAGE, FatProcessException)
#endif


//
//  The global fsd data record, and zero large integer
//

FAT_DATA FatData;

PDEVICE_OBJECT FatDiskFileSystemDeviceObject;
PDEVICE_OBJECT FatCdromFileSystemDeviceObject;

LARGE_INTEGER FatLargeZero = {0,0};
LARGE_INTEGER FatMaxLarge = {MAXULONG,MAXLONG};

LARGE_INTEGER Fat30Milliseconds = {(ULONG)(-30 * 1000 * 10), -1};
LARGE_INTEGER Fat100Milliseconds = {(ULONG)(-30 * 1000 * 10), -1};
LARGE_INTEGER FatOneDay = {0x2a69c000, 0xc9};
LARGE_INTEGER FatJanOne1980 = {0xe1d58000,0x01a8e79f};
LARGE_INTEGER FatDecThirtyOne1979 = {0xb76bc000,0x01a8e6d6};

FAT_TIME_STAMP FatTimeJanOne1980 = {{0,0,0},{1,1,0}};

LARGE_INTEGER FatMagic10000    = {0xe219652c, 0xd1b71758};
LARGE_INTEGER FatMagic86400000 = {0xfa67b90e, 0xc6d750eb};

FAST_IO_DISPATCH FatFastIoDispatch;

//
//  Our lookaside lists.
//

NPAGED_LOOKASIDE_LIST FatIrpContextLookasideList;
NPAGED_LOOKASIDE_LIST FatNonPagedFcbLookasideList;
NPAGED_LOOKASIDE_LIST FatEResourceLookasideList;

SLIST_HEADER FatCloseContextSList;

//
//  Synchronization for the close queue
//

FAST_MUTEX FatCloseQueueMutex;

//
//  Reserve MDL for paging file operations.
//

PMDL FatReserveMdl = NULL;
KEVENT FatReserveEvent;

#ifdef FASTFATDBG

LONG FatDebugTraceLevel = 0x00000009;
LONG FatDebugTraceIndent = 0;

ULONG FatFsdEntryCount = 0;
ULONG FatFspEntryCount = 0;
ULONG FatIoCallDriverCount = 0;

LONG FatPerformanceTimerLevel = 0x00000000;

ULONG FatTotalTicks[32] = { 0 };

//
//  I need this because C can't support conditional compilation within
//  a macro.
//

PVOID FatNull = NULL;

#endif // FASTFATDBG

#if DBG

NTSTATUS FatAssertNotStatus = STATUS_SUCCESS;
BOOLEAN FatTestRaisedStatus = FALSE;

#endif


#if DBG
ULONG
FatBugCheckExceptionFilter (
    IN PEXCEPTION_POINTERS ExceptionPointer
    )

/*++

Routine Description:

    An exception filter which acts as an assert that the exception should
    never occur.
    
    This is only valid on debug builds, we don't want the overhead on retail.

Arguments:

    ExceptionPointers - The result of GetExceptionInformation() in the context
        of the exception.

Return Value:

    Bugchecks.

--*/

{
    FatBugCheck( (ULONG_PTR)ExceptionPointer->ExceptionRecord,
                 (ULONG_PTR)ExceptionPointer->ContextRecord,
                 (ULONG_PTR)ExceptionPointer->ExceptionRecord->ExceptionAddress );

    return EXCEPTION_EXECUTE_HANDLER;
}
#endif


ULONG
FatExceptionFilter (
    IN PIRP_CONTEXT IrpContext,
    IN PEXCEPTION_POINTERS ExceptionPointer
    )

/*++

Routine Description:

    This routine is used to decide if we should or should not handle
    an exception status that is being raised.  It inserts the status
    into the IrpContext and either indicates that we should handle
    the exception or bug check the system.

Arguments:

    ExceptionPointers - The result of GetExceptionInformation() in the context
        of the exception.

Return Value:

    ULONG - returns EXCEPTION_EXECUTE_HANDLER or bugchecks

--*/

{
    NTSTATUS ExceptionCode;

    ExceptionCode = ExceptionPointer->ExceptionRecord->ExceptionCode;
    DebugTrace(0, DEBUG_TRACE_UNWIND, "FatExceptionFilter %X\n", ExceptionCode);
    DebugDump("FatExceptionFilter\n", Dbg, NULL );

    //
    // If the exception is STATUS_IN_PAGE_ERROR, get the I/O error code
    // from the exception record.
    //

    if (ExceptionCode == STATUS_IN_PAGE_ERROR) {
        if (ExceptionPointer->ExceptionRecord->NumberParameters >= 3) {
            ExceptionCode = (NTSTATUS)ExceptionPointer->ExceptionRecord->ExceptionInformation[2];
        }
    }

    //
    //  If there is not an irp context, we must have had insufficient resources.
    //

    if ( !ARGUMENT_PRESENT( IrpContext ) ) {

        if (!FsRtlIsNtstatusExpected( ExceptionCode )) {

            FatBugCheck( (ULONG_PTR)ExceptionPointer->ExceptionRecord,
                         (ULONG_PTR)ExceptionPointer->ContextRecord,
                         (ULONG_PTR)ExceptionPointer->ExceptionRecord->ExceptionAddress );
        }

        return EXCEPTION_EXECUTE_HANDLER;
    }

    //
    //  For the purposes of processing this exception, let's mark this
    //  request as being able to wait and disable  write through if we
    //  aren't posting it.
    //

    SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);

    if ( (ExceptionCode != STATUS_CANT_WAIT) &&
         (ExceptionCode != STATUS_VERIFY_REQUIRED) ) {

        SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH);
    }

    if ( IrpContext->ExceptionStatus == 0 ) {

        if (FsRtlIsNtstatusExpected( ExceptionCode )) {

            IrpContext->ExceptionStatus = ExceptionCode;

            return EXCEPTION_EXECUTE_HANDLER;

        } else {

            FatBugCheck( (ULONG_PTR)ExceptionPointer->ExceptionRecord,
                         (ULONG_PTR)ExceptionPointer->ContextRecord,
                         (ULONG_PTR)ExceptionPointer->ExceptionRecord->ExceptionAddress );
        }

    } else {

        //
        //  We raised this code explicitly ourselves, so it had better be
        //  expected.
        //

        ASSERT( IrpContext->ExceptionStatus == ExceptionCode );
        ASSERT( FsRtlIsNtstatusExpected( ExceptionCode ) );
    }

    return EXCEPTION_EXECUTE_HANDLER;
}

NTSTATUS
FatProcessException (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp,
    IN NTSTATUS ExceptionCode
    )

/*++

Routine Description:

    This routine process an exception.  It either completes the request
    with the saved exception status or it sends it off to IoRaiseHardError()

Arguments:

    Irp - Supplies the Irp being processed

    ExceptionCode - Supplies the normalized exception status being handled

Return Value:

    NTSTATUS - Returns the results of either posting the Irp or the
        saved completion status.

--*/

{
    PVCB Vcb;
    PIO_STACK_LOCATION IrpSp;
    FAT_VOLUME_STATE TransitionState = VolumeDirty;
    ULONG SavedFlags;

    DebugTrace(0, Dbg, "FatProcessException\n", 0);

    //
    //  If there is not an irp context, we must have had insufficient resources.
    //

    if ( !ARGUMENT_PRESENT( IrpContext ) ) {

        FatCompleteRequest( FatNull, Irp, ExceptionCode );

        return ExceptionCode;
    }

    //
    //  Get the real exception status from IrpContext->ExceptionStatus, and
    //  reset it.
    //

    ExceptionCode = IrpContext->ExceptionStatus;
    FatResetExceptionState( IrpContext );

    //
    //  If this is an Mdl write request, then take care of the Mdl
    //  here so that things get cleaned up properly.  Cc now leaves
    //  the MDL in place so a filesystem can retry after clearing an
    //  internal condition (FAT does not).
    //

    if ((IrpContext->MajorFunction == IRP_MJ_WRITE) &&
        (FlagOn( IrpContext->MinorFunction, IRP_MN_COMPLETE_MDL ) == IRP_MN_COMPLETE_MDL) &&
        (Irp->MdlAddress != NULL)) {

        PIO_STACK_LOCATION LocalIrpSp = IoGetCurrentIrpStackLocation(Irp);

        CcMdlWriteAbort( LocalIrpSp->FileObject, Irp->MdlAddress );
        Irp->MdlAddress = NULL;
    }

    //
    //  If we are going to post the request, we may have to lock down the
    //  user's buffer, so do it here in a try except so that we failed the
    //  request if the LockPages fails.
    //
    //  Also unpin any repinned Bcbs, protected by the try {} except {} filter.
    //

    try {

        SavedFlags = IrpContext->Flags;

        //
        //  Make sure we don't try to write through Bcbs
        //

        SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH);

        FatUnpinRepinnedBcbs( IrpContext );

        IrpContext->Flags = SavedFlags;

        //
        //  If we will have to post the request, do it here.  Note
        //  that the last thing FatPrePostIrp() does is mark the Irp pending,
        //  so it is critical that we actually return PENDING.  Nothing
        //  from this point to return can fail, so we are OK.
        //
        //  We cannot do a verify operations at APC level because we
        //  have to wait for Io operations to complete.
        //

        if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) &&
            (((ExceptionCode == STATUS_VERIFY_REQUIRED) && KeAreAllApcsDisabled()) ||
             (ExceptionCode == STATUS_CANT_WAIT))) {

            ExceptionCode = FatFsdPostRequest( IrpContext, Irp );
        }

    } except( FatExceptionFilter( IrpContext, GetExceptionInformation() ) ) {

        ExceptionCode = IrpContext->ExceptionStatus;
        IrpContext->ExceptionStatus = 0;

        IrpContext->Flags = SavedFlags;
    }

    //
    //  If we posted the request, just return here.
    //

    if (ExceptionCode == STATUS_PENDING) {

        return ExceptionCode;
    }

    Irp->IoStatus.Status = ExceptionCode;

    //
    //  If this request is not a "top-level" irp, just complete it.
    //

    if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL)) {

        //
        //  If there is a cache operation above us, commute verify
        //  to a lock conflict.  This will cause retries so that
        //  we have a chance of getting through without needing
        //  to return an unaesthetic error for the operation.
        //

        if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP &&
            ExceptionCode == STATUS_VERIFY_REQUIRED) {

            ExceptionCode = STATUS_FILE_LOCK_CONFLICT;
        }
        
        FatCompleteRequest( IrpContext, Irp, ExceptionCode );

        return ExceptionCode;
    }

    if (IoIsErrorUserInduced(ExceptionCode)) {

        //
        //  Check for the various error conditions that can be caused by,
        //  and possibly resolved by the user.
        //

        if (ExceptionCode == STATUS_VERIFY_REQUIRED) {

            PDEVICE_OBJECT Device;

            DebugTrace(0, Dbg, "Perform Verify Operation\n", 0);

            //
            //  Now we are at the top level file system entry point.
            //
            //  Grab the device to verify from the thread local storage
            //  and stick it in the information field for transportation
            //  to the fsp.  We also clear the field at this time.
            //

            Device = IoGetDeviceToVerify( Irp->Tail.Overlay.Thread );
            IoSetDeviceToVerify( Irp->Tail.Overlay.Thread, NULL );

            if ( Device == NULL ) {

                Device = IoGetDeviceToVerify( PsGetCurrentThread() );
                IoSetDeviceToVerify( PsGetCurrentThread(), NULL );

                ASSERT( Device != NULL );
            }

            //
            //  Let's not BugCheck just because the driver messed up.
            //

            if (Device == NULL) {

                ExceptionCode = STATUS_DRIVER_INTERNAL_ERROR;

                FatCompleteRequest( IrpContext, Irp, ExceptionCode );

                return ExceptionCode;
            }

            //
            //  FatPerformVerify() will do the right thing with the Irp.

            return FatPerformVerify( IrpContext, Irp, Device );
        }

        //
        //  The other user induced conditions generate an error unless
        //  they have been disabled for this request.
        //

        if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS)) {

            FatCompleteRequest( IrpContext, Irp, ExceptionCode );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -