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

📄 fsctl.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 3 页
字号:

        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
        
        rfsd_sb = RfsdLoadSuper(Vcb, TRUE);

		// FUTURE: use the volume name and uuid from the extended superblock to make this happen.
		// NOTE: The magic check will have to use the same thing as mount did!
        if ((rfsd_sb != NULL) /*&& (rfsd_sb->s_magic == RFSD_SUPER_MAGIC) &&
            (memcmp(rfsd_sb->s_uuid, SUPER_BLOCK->s_uuid, 16) == 0) &&
            (memcmp(rfsd_sb->s_volume_name, SUPER_BLOCK->s_volume_name, 16) ==0)*/) {
            ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);

            if (RfsdIsMediaWriteProtected(IrpContext, Vcb->TargetDeviceObject)) {
                SetFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
            } else {
                ClearFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
            }
                
            RfsdPrint((DBG_INFO, "RfsdVerifyVolume: Volume verify succeeded.\n"));

            Status = STATUS_SUCCESS;
        } else {
            Status = STATUS_WRONG_VOLUME;

            RfsdPurgeVolume(Vcb, FALSE);
             
            SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
            
            ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
            
            RfsdPrint((DBG_INFO, "RfsdVerifyVolume: Volume verify failed.\n"));
        }

    } __finally {

        if (rfsd_sb)
            ExFreePool(rfsd_sb);

        if (VcbResourceAcquired) {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }

        if (GlobalResourceAcquired) {
            ExReleaseResourceForThreadLite(
                &RfsdGlobal->Resource,
                ExGetCurrentResourceThread() );
        }
        
        if (!IrpContext->ExceptionInProgress) {
            RfsdCompleteIrpContext(IrpContext,  Status);
        }
    }
    
    return Status;
}


NTSTATUS
RfsdIsVolumeMounted (IN PRFSD_IRP_CONTEXT IrpContext)
{
    ASSERT(IrpContext);

    ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
           (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));

    return RfsdVerifyVolume(IrpContext);
}


NTSTATUS
RfsdDismountVolume (IN PRFSD_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    PRFSD_VCB       Vcb;
    BOOLEAN         VcbResourceAcquired = FALSE;
    
    __try {

        ASSERT(IrpContext != NULL);
        
        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
            (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
        
        DeviceObject = IrpContext->DeviceObject;

        //
        // This request is not allowed on the main device object
        //
        if (DeviceObject == RfsdGlobal->DeviceObject) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }
        
        Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
        
        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
            (Vcb->Identifier.Size == sizeof(RFSD_VCB)));

        ASSERT(IsMounted(Vcb));

        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource,
            TRUE );
        
        VcbResourceAcquired = TRUE;

        if ( IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
            Status = STATUS_VOLUME_DISMOUNTED;
            __leave;
        }

/*        
        if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
            RfsdPrint((DBG_ERROR, "RfsdDismount: Volume is not locked.\n"));
            
            Status = STATUS_ACCESS_DENIED;
           
            __leave;
        }
*/
#if DISABLED
        RfsdFlushFiles(Vcb, FALSE);

        RfsdFlushVolume(Vcb, FALSE);

        RfsdPurgeVolume(Vcb, TRUE);
#endif
        ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread() );

        VcbResourceAcquired = FALSE;

        RfsdCheckDismount(IrpContext, Vcb, TRUE);

        RfsdPrint((DBG_INFO, "RfsdDismount: Volume dismount pending.\n"));

        Status = STATUS_SUCCESS;

    } __finally {

        if (VcbResourceAcquired) {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }
        
        if (!IrpContext->ExceptionInProgress) {
            RfsdCompleteIrpContext(IrpContext,  Status);
        }
    }
    
    return Status;
}

BOOLEAN
RfsdCheckDismount (
    IN PRFSD_IRP_CONTEXT IrpContext,
    IN PRFSD_VCB         Vcb,
    IN BOOLEAN           bForce   )
{
    KIRQL   Irql;
    PVPB    Vpb = Vcb->Vpb;
    BOOLEAN bDeleted = FALSE;
    ULONG   UnCleanCount = 0;

    ExAcquireResourceExclusiveLite(
        &RfsdGlobal->Resource, TRUE );

    ExAcquireResourceExclusiveLite(
        &Vcb->MainResource, TRUE );

    if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
        (IrpContext->RealDevice == Vcb->RealDevice)) {
        UnCleanCount = 3;
    } else {
        UnCleanCount = 2;
    }

    IoAcquireVpbSpinLock (&Irql);

    if ((Vpb->ReferenceCount == UnCleanCount) || bForce) {

        if ((Vpb->ReferenceCount != UnCleanCount) && bForce) {
            KdPrint(("RfsdCheckDismount: force dismount ...\n"));
        }

        ClearFlag( Vpb->Flags, VPB_MOUNTED );
        ClearFlag( Vpb->Flags, VPB_LOCKED );

        if ((Vcb->RealDevice != Vpb->RealDevice) &&
            (Vcb->RealDevice->Vpb == Vpb)) {
            SetFlag( Vcb->RealDevice->Flags, DO_DEVICE_INITIALIZING );
            SetFlag( Vpb->Flags, VPB_PERSISTENT );
        }

        RfsdRemoveVcb(Vcb);

        ClearFlag(Vpb->Flags, VPB_MOUNTED);
        SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);

        Vpb->DeviceObject = NULL;

        bDeleted = TRUE;
    }

    IoReleaseVpbSpinLock(Irql);

    ExReleaseResourceForThreadLite(
        &Vcb->MainResource,
        ExGetCurrentResourceThread() );

    ExReleaseResourceForThreadLite(
        &RfsdGlobal->Resource,
        ExGetCurrentResourceThread() );

    if (bDeleted) {
        KdPrint(("RfsdCheckDismount: now free the vcb ...\n"));
        RfsdFreeVcb(Vcb);
    }

    return bDeleted;
}


NTSTATUS
RfsdPurgeVolume (IN PRFSD_VCB Vcb,
                 IN BOOLEAN  FlushBeforePurge )
{
    PRFSD_FCB       Fcb;
    LIST_ENTRY      FcbList;
    PLIST_ENTRY     ListEntry;
    PFCB_LIST_ENTRY FcbListEntry;
   
    __try {

        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
            (Vcb->Identifier.Size == sizeof(RFSD_VCB)));
        
        if ( IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
             IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
            FlushBeforePurge = FALSE;
        }

        FcbListEntry= NULL;
        InitializeListHead(&FcbList);
        
        for (ListEntry = Vcb->FcbList.Flink;
             ListEntry != &Vcb->FcbList;
             ListEntry = ListEntry->Flink  ) {

            Fcb = CONTAINING_RECORD(ListEntry, RFSD_FCB, Next);

            Fcb->ReferenceCount++;

            RfsdPrint((DBG_INFO, "RfsdPurgeVolume: %s refercount=%xh\n", Fcb->AnsiFileName.Buffer, Fcb->ReferenceCount));
            
            FcbListEntry = ExAllocatePool(PagedPool, sizeof(FCB_LIST_ENTRY));

            if (FcbListEntry) {

                FcbListEntry->Fcb = Fcb;
            
                InsertTailList(&FcbList, &FcbListEntry->Next);
            } else {
                RfsdPrint((DBG_ERROR, "RfsdPurgeVolume: Error allocating FcbListEntry ...\n"));
            }
        }
        
        while (!IsListEmpty(&FcbList)) {

            ListEntry = RemoveHeadList(&FcbList);
            
            FcbListEntry = CONTAINING_RECORD(ListEntry, FCB_LIST_ENTRY, Next);
            
            Fcb = FcbListEntry->Fcb;

            if (ExAcquireResourceExclusiveLite(
                &Fcb->MainResource,
                TRUE )) {

                RfsdPurgeFile(Fcb, FlushBeforePurge);

                if (!Fcb->OpenHandleCount && Fcb->ReferenceCount == 1) {
                    RemoveEntryList(&Fcb->Next);
                    RfsdFreeFcb(Fcb);
                } else {
                    ExReleaseResourceForThreadLite(
                        &Fcb->MainResource,
                        ExGetCurrentResourceThread());
                }
            }
           
            ExFreePool(FcbListEntry);
        }

        if (FlushBeforePurge) {
            ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
            ExReleaseResource(&Vcb->PagingIoResource);

            CcFlushCache(&Vcb->SectionObject, NULL, 0, NULL);
        }

        if (Vcb->SectionObject.ImageSectionObject) {
            MmFlushImageSection(&Vcb->SectionObject, MmFlushForWrite);
        }
    
        if (Vcb->SectionObject.DataSectionObject) {
            CcPurgeCacheSection(&Vcb->SectionObject, NULL, 0, FALSE);
        }
        
        RfsdPrint((DBG_INFO, "RfsdPurgeVolume: Volume flushed and purged.\n"));

    } __finally {
        // Nothing
    }

    return STATUS_SUCCESS;
}

NTSTATUS
RfsdPurgeFile ( IN PRFSD_FCB Fcb,
                IN BOOLEAN  FlushBeforePurge )
{
    IO_STATUS_BLOCK    IoStatus;

    ASSERT(Fcb != NULL);
        
    ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
        (Fcb->Identifier.Size == sizeof(RFSD_FCB)));

    
    if( !IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) && FlushBeforePurge &&
        !IsFlagOn(Fcb->Vcb->Flags, VCB_WRITE_PROTECTED)) {

        RfsdPrint((DBG_INFO, "RfsdPurgeFile: CcFlushCache on %s.\n", 
                             Fcb->AnsiFileName.Buffer));

        ExAcquireSharedStarveExclusive(&Fcb->PagingIoResource, TRUE);
        ExReleaseResource(&Fcb->PagingIoResource);

        CcFlushCache(&Fcb->SectionObject, NULL, 0, &IoStatus);

        ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
    }
    
    if (Fcb->SectionObject.ImageSectionObject) {

        RfsdPrint((DBG_INFO, "RfsdPurgeFile: MmFlushImageSection on %s.\n", 
                             Fcb->AnsiFileName.Buffer));
    
        MmFlushImageSection(&Fcb->SectionObject, MmFlushForWrite);
    }
    
    if (Fcb->SectionObject.DataSectionObject) {

        RfsdPrint((DBG_INFO, "RfsdPurgeFile: CcPurgeCacheSection on %s.\n",
                             Fcb->AnsiFileName.Buffer));

        CcPurgeCacheSection(&Fcb->SectionObject, NULL, 0, FALSE);
    }

    return STATUS_SUCCESS;
}


NTSTATUS
RfsdFileSystemControl (IN PRFSD_IRP_CONTEXT IrpContext)
{
    NTSTATUS    Status;
    
    ASSERT(IrpContext);
    
    ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
        (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
    
    switch (IrpContext->MinorFunction) {

        case IRP_MN_USER_FS_REQUEST:
            Status = RfsdUserFsRequest(IrpContext);
            break;
        
        case IRP_MN_MOUNT_VOLUME:
            Status = RfsdMountVolume(IrpContext);
            break;
        
        case IRP_MN_VERIFY_VOLUME:
            Status = RfsdVerifyVolume(IrpContext);
            break;
        
        default:

            RfsdPrint((DBG_ERROR, "RfsdFilsSystemControl: Invalid Device Request.\n"));
            Status = STATUS_INVALID_DEVICE_REQUEST;
            RfsdCompleteIrpContext(IrpContext,  Status);
    }
    
    return Status;
}

⌨️ 快捷键说明

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