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

📄 verfysup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 4 页
字号:
                                                 (PVOID)Sector,
                                                 WriteLength,
                                                 &Offset,
                                                 NULL );

            if ( Irp == NULL ) {

                try_return(NOTHING);
            }

            //
            //  Make this operation write-through.  It never hurts to try to be
            //  safer about this, even though we aren't logged.
            //

            SetFlag( IoGetNextIrpStackLocation( Irp )->Flags, SL_WRITE_THROUGH );

            //
            //  Set up the completion routine
            //

            IoSetCompletionRoutine( Irp,
                                    FatMarkVolumeCompletionRoutine,
                                    &Event,
                                    TRUE,
                                    TRUE,
                                    TRUE );

            //
            //  Call the device to do the write and wait for it to finish.
            //  Igmore any return status.
            //

            Status = IoCallDriver( Vcb->TargetDeviceObject, Irp );

            if (Status == STATUS_PENDING) {

                (VOID)KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, (PLARGE_INTEGER)NULL );
            }

        try_exit: NOTHING;
        } finally {

            //
            //  Clean up the Irp and Mdl
            //


            if (Irp) {

                //
                //  If there is an MDL (or MDLs) associated with this I/O
                //  request, Free it (them) here.  This is accomplished by
                //  walking the MDL list hanging off of the IRP and deallocating
                //  each MDL encountered.
                //

                while (Irp->MdlAddress != NULL) {

                    PMDL NextMdl;

                    NextMdl = Irp->MdlAddress->Next;

                    MmUnlockPages( Irp->MdlAddress );

                    IoFreeMdl( Irp->MdlAddress );

                    Irp->MdlAddress = NextMdl;
                }

                IoFreeIrp( Irp );
            }

            if (Bcb != NULL) {

                FatUnpinBcb( IrpContext, Bcb );
            }
        }
    }

    if (!abort) {

        //
        //  Flip the dirty bit in the FAT
        //

        if (VolumeState == VolumeDirty) {

           FatSetFatEntry( IrpContext, Vcb, FAT_DIRTY_BIT_INDEX, FAT_DIRTY_VOLUME);

        } else {
    
           FatSetFatEntry( IrpContext, Vcb, FAT_DIRTY_BIT_INDEX, FAT_CLEAN_VOLUME);
        }
    }

    DebugTrace(-1, Dbg, "FatMarkVolume -> VOID\n", 0);

    return;
}


VOID
FatFspMarkVolumeDirtyWithRecover(
    PVOID Parameter
    )

/*++

Routine Description:

    This is the routine that performs the actual FatMarkVolume Dirty call
    on a paging file Io that encounters a media error.  It is responsible
    for completing the PagingIo Irp as soon as this is done.

    Note:  this routine (and thus FatMarkVolume()) must be resident as
           the paging file might be damaged at this point.

Arguments:

    Parameter - Points to a dirty volume packet that was allocated from pool

Return Value:

    None.

--*/

{
    PCLEAN_AND_DIRTY_VOLUME_PACKET Packet;
    PVCB Vcb;
    IRP_CONTEXT IrpContext;
    PIRP Irp;
    BOOLEAN VcbExists = FALSE;

    DebugTrace(+1, Dbg, "FatDeferredCleanVolume\n", 0);

    Packet = (PCLEAN_AND_DIRTY_VOLUME_PACKET)Parameter;

    Vcb = Packet->Vcb;
    Irp = Packet->Irp;

    //
    //  Dummy up the IrpContext so we can call our worker routines
    //

    RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT));

    SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
    IrpContext.OriginatingIrp = Irp;

    //
    //  Make us appear as a top level FSP request so that we will
    //  receive any errors from the operation.
    //

    IoSetTopLevelIrp( (PIRP)FSRTL_FSP_TOP_LEVEL_IRP );

    //
    //  Try to write out the dirty bit.  If something goes wrong, we
    //  tried.
    //

    try {

        SetFlag( Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY );

        FatMarkVolume( &IrpContext, Vcb, VolumeDirtyWithSurfaceTest );

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

        NOTHING;
    }

    IoSetTopLevelIrp( NULL );

    //
    //  Now complete the originating Irp or set the synchronous event.
    //

    if (Packet->Event) {
        KeSetEvent( Packet->Event, 0, FALSE );
    } else {
        IoCompleteRequest( Irp, IO_DISK_INCREMENT );
    }
}


VOID
FatCheckDirtyBit (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb
    )

/*++

Routine Description:

    This routine looks at the volume dirty bit, and depending on the state of
    VCB_STATE_FLAG_MOUNTED_DIRTY, the appropriate action is taken.

Arguments:

    Vcb - Supplies the Vcb being queried.

Return Value:

    None.

--*/

{
    BOOLEAN Dirty;

    PPACKED_BOOT_SECTOR BootSector;
    PBCB BootSectorBcb;

    UNICODE_STRING VolumeLabel;

    //
    //  Look in the boot sector
    //

    FatReadVolumeFile( IrpContext,
                       Vcb,
                       0,
                       sizeof(PACKED_BOOT_SECTOR),
                       &BootSectorBcb,
                       (PVOID *)&BootSector );

    try {

        //
        //  Check if the magic bit is set
        //

        if (IsBpbFat32(&BootSector->PackedBpb)) {
            Dirty = BooleanFlagOn( ((PPACKED_BOOT_SECTOR_EX)BootSector)->CurrentHead,
                                   FAT_BOOT_SECTOR_DIRTY );
        } else {
            Dirty = BooleanFlagOn( BootSector->CurrentHead, FAT_BOOT_SECTOR_DIRTY );
        }

        //
        //  Setup the VolumeLabel string
        //

        VolumeLabel.Length = Vcb->Vpb->VolumeLabelLength;
        VolumeLabel.MaximumLength = MAXIMUM_VOLUME_LABEL_LENGTH;
        VolumeLabel.Buffer = &Vcb->Vpb->VolumeLabel[0];

        if ( Dirty ) {

            //
            //  Do not trigger the mounted dirty bit if this is a verify
            //  and the volume is a boot or paging device.  We know that
            //  a boot or paging device cannot leave the system, and thus
            //  that on its mount we will have figured this out correctly.
            //
            //  This logic is a reasonable hack-o-rama to make BillG happy
            //  since his machine ran chkdsk after he installed Beta 3.  Why?
            //  'cause setup cracked a non-exclusive DASD handle near the
            //  end of setup, wrote some data, closed the handle and we
            //  set the verify bit ... came back around and saw that other
            //  arbitrary activity had left the volume in a temporarily dirty
            //  state.
            //
            //  Of course, the real problem is that we don't have a journal.
            //

            if (!(IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
                  IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME &&
                  FlagOn( Vcb->VcbState, VCB_STATE_FLAG_BOOT_OR_PAGING_FILE))) {

                KdPrintEx((DPFLTR_FASTFAT_ID,
                           DPFLTR_INFO_LEVEL,
                           "FASTFAT: WARNING! Mounting Dirty Volume %Z\n",
                           &VolumeLabel));

                SetFlag( Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY );
            }

        } else {

            if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {

                KdPrintEx((DPFLTR_FASTFAT_ID,
                           DPFLTR_INFO_LEVEL,
                           "FASTFAT: Volume %Z has been cleaned.\n",
                           &VolumeLabel));

                ClearFlag( Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY );

            } else {

                (VOID)FsRtlBalanceReads( Vcb->TargetDeviceObject );
            }
        }

    } finally {

        FatUnpinBcb( IrpContext, BootSectorBcb );
    }
}


VOID
FatVerifyOperationIsLegal (
    IN PIRP_CONTEXT IrpContext
    )

/*++

Routine Description:

    This routine determines is the requested operation should be allowed to
    continue.  It either returns to the user if the request is Okay, or
    raises an appropriate status.

Arguments:

    Irp - Supplies the Irp to check

Return Value:

    None.

--*/

{
    PIRP Irp;
    PFILE_OBJECT FileObject;

    Irp = IrpContext->OriginatingIrp;

    //
    //  If the Irp is not present, then we got here via close.
    //
    //

    if ( Irp == NULL ) {

        return;
    }

    FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;

    //
    //  If there is not a file object, we cannot continue.
    //

    if ( FileObject == NULL ) {

        return;
    }

    //
    //  If the file object has already been cleaned up, and
    //
    //  A) This request is a paging io read or write, or
    //  B) This request is a close operation, or
    //  C) This request is a set or query info call (for Lou)
    //  D) This is an MDL complete
    //
    //  let it pass, otherwise return STATUS_FILE_CLOSED.
    //

    if ( FlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE) ) {

        PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

        if ( (FlagOn(Irp->Flags, IRP_PAGING_IO)) ||
             (IrpSp->MajorFunction == IRP_MJ_CLOSE ) ||
             (IrpSp->MajorFunction == IRP_MJ_SET_INFORMATION) ||
             (IrpSp->MajorFunction == IRP_MJ_QUERY_INFORMATION) ||
             ( ( (IrpSp->MajorFunction == IRP_MJ_READ) ||
                 (IrpSp->MajorFunction == IRP_MJ_WRITE) ) &&
               FlagOn(IrpSp->MinorFunction, IRP_MN_COMPLETE) ) ) {

            NOTHING;

        } else {

            FatRaiseStatus( IrpContext, STATUS_FILE_CLOSED );
        }
    }

    return;
}



//
//  Internal support routine
//

VOID
FatResetFcb (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb
    )

/*++

Routine Description:

    This routine is called when an Fcb has been marked as needs to be verified.

    It does the following tasks:

        - Reset Mcb mapping information
        - For directories, reset dirent hints
        - Set allocation size to unknown

Arguments:

    Fcb - Supplies the Fcb to reset

Return Value:

    None.

--*/

{
    //
    //  Don't do the two following operations for the Root Dcb
    //  or paging files.  Paging files!? Yes, if someone diddles
    //  a volume we try to reverify all of the Fcbs just in case;
    //  however, there is no safe way to chuck and retrieve the
    //  mapping pair information for the paging file. Lose it and
    //  die.
    //

    if ( NodeType(Fcb) != FAT_NTC_ROOT_DCB &&
         !FlagOn( Fcb->FcbState, FCB_STATE_PAGING_FILE )) {

        //
        //  Reset the mcb mapping.
        //

        FsRtlRemoveLargeMcbEntry( &Fcb->Mcb, 0, 0xFFFFFFFF );

        //
        //  Reset the allocation size to 0 or unknown
        //

        if ( Fcb->FirstClusterOfFile == 0 ) {

            Fcb->Header.AllocationSize.QuadPart = 0;

        } else {

            Fcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;
        }
    }

    //
    //  If this is a directory, reset the hints.
    //

    if ( (NodeType(Fcb) == FAT_NTC_DCB) ||
         (NodeType(Fcb) == FAT_NTC_ROOT_DCB) ) {

        //
        //  Force a rescan of the directory
        //

        Fcb->Specific.Dcb.UnusedDirentVbo = 0xffffffff;
        Fcb->Specific.Dcb.DeletedDirentHint = 0xffffffff;
    }
}



//
//  Internal support routine
//

VOID
FatDetermineAndMarkFcbCondition (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb
    )

/*++

Routine Description:

⌨️ 快捷键说明

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