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

📄 fatdata.c

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

            return ExceptionCode;

        } else {

            //
            //  Generate a pop-up
            //

            PDEVICE_OBJECT RealDevice;
            PVPB Vpb;
            PETHREAD Thread;

            if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL) {

                Vpb = IoGetCurrentIrpStackLocation(Irp)->FileObject->Vpb;

            } else {

                Vpb = NULL;
            }

            //
            //  The device to verify is either in my thread local storage
            //  or that of the thread that owns the Irp.
            //

            Thread = Irp->Tail.Overlay.Thread;
            RealDevice = IoGetDeviceToVerify( Thread );

            if ( RealDevice == NULL ) {

                Thread = PsGetCurrentThread();
                RealDevice = IoGetDeviceToVerify( Thread );

                ASSERT( RealDevice != NULL );
            }

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

            if (RealDevice == NULL) {

                FatCompleteRequest( IrpContext, Irp, ExceptionCode );

                return ExceptionCode;
            }

            //
            //  This routine actually causes the pop-up.  It usually
            //  does this by queuing an APC to the callers thread,
            //  but in some cases it will complete the request immediately,
            //  so it is very important to IoMarkIrpPending() first.
            //

            IoMarkIrpPending( Irp );
            IoRaiseHardError( Irp, Vpb, RealDevice );

            //
            //  We will be handing control back to the caller here, so
            //  reset the saved device object.
            //

            IoSetDeviceToVerify( Thread, NULL );

            //
            //  The Irp will be completed by Io or resubmitted.  In either
            //  case we must clean up the IrpContext here.
            //

            FatDeleteIrpContext( IrpContext );
            return STATUS_PENDING;
        }
    }

    //
    //  This is just a run of the mill error.  If is a STATUS that we
    //  raised ourselves, and the information would be use for the
    //  user, raise an informational pop-up.
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );
    Vcb = IrpContext->Vcb;

    //
    //  Now, if the Vcb is unknown to us this means that the error was raised
    //  in the process of a mount and before we even had a chance to build
    //  a full Vcb - and was really handled there.
    //

    if (Vcb != NULL) {

        if ( !FatDeviceIsFatFsdo( IrpSp->DeviceObject) &&
             !NT_SUCCESS(ExceptionCode) &&
             !FsRtlIsTotalDeviceFailure(ExceptionCode) ) {

            TransitionState = VolumeDirtyWithSurfaceTest;
        }

        //
        //  If this was a STATUS_FILE_CORRUPT or similar error indicating some
        //  nastiness out on the media, then mark the volume permanently dirty.
        //

        if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS) &&
            ( TransitionState == VolumeDirtyWithSurfaceTest ||
              (ExceptionCode == STATUS_FILE_CORRUPT_ERROR) ||
              (ExceptionCode == STATUS_DISK_CORRUPT_ERROR) ||
              (ExceptionCode == STATUS_EA_CORRUPT_ERROR) ||
              (ExceptionCode == STATUS_INVALID_EA_NAME) ||
              (ExceptionCode == STATUS_EA_LIST_INCONSISTENT) ||
              (ExceptionCode == STATUS_NO_EAS_ON_FILE) )) {

            ASSERT( NodeType(Vcb) == FAT_NTC_VCB );
            ASSERT( !FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL));

            SetFlag( Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY );
            SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);

            //
            //  Do the "dirty" work, ignoring any error.  We need to take the Vcb here
            //  to synchronize against the verify path tearing things down, since
            //  we dropped all synchronization when backing up due to the exception.
            //

            FatAcquireExclusiveVcbNoOpCheck( IrpContext, Vcb);
            
            try {

                if (VcbGood == Vcb->VcbCondition) {

                    FatMarkVolume( IrpContext, Vcb, TransitionState );
                }
            } 
            except( FatExceptionFilter( IrpContext, GetExceptionInformation() ) ) {

                NOTHING;
            }

            FatReleaseVcb( IrpContext, Vcb);
        }
    }

    FatCompleteRequest( IrpContext, Irp, ExceptionCode );

    return ExceptionCode;
}


VOID
FatCompleteRequest_Real (
    IN PIRP_CONTEXT IrpContext OPTIONAL,
    IN PIRP Irp OPTIONAL,
    IN NTSTATUS Status
    )

/*++

Routine Description:

    This routine completes a Irp

Arguments:

    Irp - Supplies the Irp being processed

    Status - Supplies the status to complete the Irp with

Return Value:

    None.

--*/

{
    //
    //  If we have an Irp Context then unpin all of the repinned bcbs
    //  we might have collected.
    //

    if (IrpContext != NULL) {

        ASSERT( IrpContext->Repinned.Bcb[0] == NULL );

        FatUnpinRepinnedBcbs( IrpContext );
    }

    //
    //  Delete the Irp context before completing the IRP so if
    //  we run into some of the asserts, we can still backtrack
    //  through the IRP.
    //

    if (IrpContext != NULL) {

        FatDeleteIrpContext( IrpContext );
    }

    //
    //  If we have an Irp then complete the irp.
    //

    if (Irp != NULL) {

        //
        //  We got an error, so zero out the information field before
        //  completing the request if this was an input operation.
        //  Otherwise IopCompleteRequest will try to copy to the user's buffer.
        //

        if ( NT_ERROR(Status) &&
             FlagOn(Irp->Flags, IRP_INPUT_OPERATION) ) {

            Irp->IoStatus.Information = 0;
        }

        Irp->IoStatus.Status = Status;

        IoCompleteRequest( Irp, IO_DISK_INCREMENT );
    }

    return;
}

BOOLEAN
FatIsIrpTopLevel (
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine detects if an Irp is the Top level requestor, ie. if it os OK
    to do a verify or pop-up now.  If TRUE is returned, then no file system
    resources are held above us.

Arguments:

    Irp - Supplies the Irp being processed

    Status - Supplies the status to complete the Irp with

Return Value:

    None.

--*/

{
    if ( IoGetTopLevelIrp() == NULL ) {

        IoSetTopLevelIrp( Irp );

        return TRUE;

    } else {

        return FALSE;
    }
}


BOOLEAN
FatFastIoCheckIfPossible (
    IN PFILE_OBJECT FileObject,
    IN PLARGE_INTEGER FileOffset,
    IN ULONG Length,
    IN BOOLEAN Wait,
    IN ULONG LockKey,
    IN BOOLEAN CheckForReadOperation,
    OUT PIO_STATUS_BLOCK IoStatus,
    IN PDEVICE_OBJECT DeviceObject
    )

/*++

Routine Description:

    This routine checks if fast i/o is possible for a read/write operation

Arguments:

    FileObject - Supplies the file object used in the query

    FileOffset - Supplies the starting byte offset for the read/write operation

    Length - Supplies the length, in bytes, of the read/write operation

    Wait - Indicates if we can wait

    LockKey - Supplies the lock key

    CheckForReadOperation - Indicates if this is a check for a read or write
        operation

    IoStatus - Receives the status of the operation if our return value is
        FastIoReturnError

Return Value:

    BOOLEAN - TRUE if fast I/O is possible and FALSE if the caller needs
        to take the long route.

--*/

{
    PVCB Vcb;
    PFCB Fcb;
    PCCB Ccb;

    LARGE_INTEGER LargeLength;

    //
    //  Decode the file object to get our fcb, the only one we want
    //  to deal with is a UserFileOpen
    //

    if (FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb ) != UserFileOpen) {

        return FALSE;
    }

    LargeLength.QuadPart = Length;

    //
    //  Based on whether this is a read or write operation we call
    //  fsrtl check for read/write
    //

    if (CheckForReadOperation) {

        if (FsRtlFastCheckLockForRead( &Fcb->Specific.Fcb.FileLock,
                                       FileOffset,
                                       &LargeLength,
                                       LockKey,
                                       FileObject,
                                       PsGetCurrentProcess() )) {

            return TRUE;
        }

    } else {

        //
        //  Also check for a write-protected volume here.
        //

        if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED) &&
            FsRtlFastCheckLockForWrite( &Fcb->Specific.Fcb.FileLock,
                                        FileOffset,
                                        &LargeLength,
                                        LockKey,
                                        FileObject,
                                        PsGetCurrentProcess() )) {

            return TRUE;
        }
    }

    return FALSE;
}


BOOLEAN
FatFastQueryBasicInfo (
    IN PFILE_OBJECT FileObject,
    IN BOOLEAN Wait,
    IN OUT PFILE_BASIC_INFORMATION Buffer,
    OUT PIO_STATUS_BLOCK IoStatus,
    IN PDEVICE_OBJECT DeviceObject
    )

/*++

Routine Description:

    This routine is for the fast query call for basic file information.

Arguments:

    FileObject - Supplies the file object used in this operation

    Wait - Indicates if we are allowed to wait for the information

    Buffer - Supplies the output buffer to receive the basic information

    IoStatus - Receives the final status of the operation

Return Value:

    BOOLEAN - TRUE if the operation succeeded and FALSE if the caller
        needs to take the long route.

--*/

{
    BOOLEAN Results = FALSE;
    IRP_CONTEXT IrpContext;

    TYPE_OF_OPEN TypeOfOpen;
    PVCB Vcb;
    PFCB Fcb;
    PCCB Ccb;

    BOOLEAN FcbAcquired = FALSE;

    //
    //  Prepare the dummy irp context
    //

    RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT) );
    IrpContext.NodeTypeCode = FAT_NTC_IRP_CONTEXT;
    IrpContext.NodeByteSize = sizeof(IRP_CONTEXT);

    if (Wait) {

        SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);

    } else {

        ClearFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
    }

    //
    //  Determine the type of open for the input file object and only accept
    //  the user file or directory open
    //

    TypeOfOpen = FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb );

    if ((TypeOfOpen != UserFileOpen) && (TypeOfOpen != UserDirectoryOpen)) {

        return Results;
    }

    FsRtlEnterFileSystem();

    //
    //  Get access to the Fcb but only if it is not the paging file
    //

    if (!FlagOn( Fcb->FcbState, FCB_STATE_PAGING_FILE )) {

        if (!ExAcquireResourceSharedLite( Fcb->Header.Resource, Wait )) {

            FsRtlExitFileSystem();
            return Results;
        }

        FcbAcquired = TRUE;
    }

    try {

        //
        //  If the Fcb is not in a good state, return FALSE.
        //

        if (Fcb->FcbCondition != FcbGood) {

            try_return( Results );
        }

        Buffer->FileAttributes = 0;

        //
        //  If the fcb is not the root dcb then we will fill in the
        //  buffer otherwise it is all setup for us.
        //

        if (NodeType(Fcb) != FAT_NTC_ROOT_DCB) {

            //

⌨️ 快捷键说明

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