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

📄 fsctl.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
                ExFreePool(Ext2Sb);
            }

            if (VolumeDeviceObject)
            {
                IoDeleteDevice(VolumeDeviceObject);
            }
        }
        
        if (!IrpContext->ExceptionInProgress)
        {
            if (NT_SUCCESS(Status))
            {
                ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
            }
            
            IrpContext->Irp->IoStatus.Status = Status;
            
            Ext2CompleteRequest(
                IrpContext->Irp,
                (CCHAR)
                (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
            
            Ext2FreeIrpContext(IrpContext);
        }
    }
    
    return Status;
}


NTSTATUS
Ext2VerifyVolume (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT          DeviceObject;
    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
    PEXT2_SUPER_BLOCK       ext2_sb = NULL;
    PEXT2_VCB               Vcb;
    BOOLEAN                 VcbResourceAcquired = FALSE;
    PIRP                    Irp;
    PIO_STACK_LOCATION      IoStackLocation;
    
    __try
    {
        ASSERT(IrpContext != NULL);
        
        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
            (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
        
        DeviceObject = IrpContext->DeviceObject;
        //
        // This request is not allowed on the main device object
        //
        if (DeviceObject == gExt2Global->DeviceObject)
        {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }
        
        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
        
        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
            (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
        
        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource,
            TRUE );
        
        VcbResourceAcquired = TRUE;
        
        if (!FlagOn(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME))
        {
            Status = STATUS_SUCCESS;
            __leave;
        }
        
        Irp = IrpContext->Irp;

        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
        
        ext2_sb = Ext2LoadSuper(Vcb->TargetDeviceObject);

        if (ext2_sb && ext2_sb->s_magic == EXT2_SUPER_MAGIC)
        {
            ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
                
            Ext2DbgPrint(D_FSCTL, "Ext2VerifyVolume: Volume verify succeeded.\n");

            Status = STATUS_SUCCESS;

            __leave;
        }
        else
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
                );
            
            VcbResourceAcquired = FALSE;
            
            Ext2PurgeVolume(Vcb, FALSE);
            
            ExAcquireResourceExclusiveLite(
                &Vcb->MainResource,
                TRUE
                );
            
            VcbResourceAcquired = TRUE;
            
            SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
            
            ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
            
            Ext2DbgPrint(D_FSCTL, "Ext2VerifyVolume: Volume verify failed\n");
            
            __leave;
        }

        __leave;
    }

    __finally
    {
        if (ext2_sb)
            ExFreePool(ext2_sb);

        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }
        
        if (!IrpContext->ExceptionInProgress)
        {
            IrpContext->Irp->IoStatus.Status = Status;
            
            Ext2CompleteRequest(
                IrpContext->Irp,
                (CCHAR)
                (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
            
            Ext2FreeIrpContext(IrpContext);
        }
    }
    
    return Status;
}


NTSTATUS
Ext2IsVolumeMounted (IN PEXT2_IRP_CONTEXT IrpContext)
{
    ASSERT(IrpContext);

    ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
           (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

    return Ext2VerifyVolume(IrpContext);
}


NTSTATUS
Ext2DismountVolume (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    PEXT2_VCB       Vcb;
    BOOLEAN         VcbResourceAcquired = FALSE;
    
    __try
    {
        ASSERT(IrpContext != NULL);
        
        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
            (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
        
        DeviceObject = IrpContext->DeviceObject;

        //
        // This request is not allowed on the main device object
        //
        if (DeviceObject == gExt2Global->DeviceObject)
        {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }
        
        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
        
        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
            (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
        
        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource,
            TRUE );
        
        VcbResourceAcquired = TRUE;
        
        if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED))
        {
            Ext2DbgPrint(D_FSCTL, "Ext2Dismount: Volume is not locked.\n");
            
            Status = STATUS_ACCESS_DENIED;
            
            __leave;
        }
        
        SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
        
        Ext2DbgPrint(D_FSCTL, "Ext2Dismount: Volume dismount pending.\n");
        
        Status = STATUS_SUCCESS;
    }
    __finally
    {
        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }
        
        if (!IrpContext->ExceptionInProgress)
        {
            IrpContext->Irp->IoStatus.Status = Status;
            
            Ext2CompleteRequest(
                IrpContext->Irp,
                (CCHAR)
                (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
                );
            
            Ext2FreeIrpContext(IrpContext);
        }
    }
    
    return Status;
}


NTSTATUS
Ext2PurgeVolume (IN PEXT2_VCB Vcb,
         IN BOOLEAN  FlushBeforePurge )
{
    BOOLEAN         VcbResourceAcquired = FALSE;
    PEXT2_FCB       Fcb;
    LIST_ENTRY      FcbList;
    PLIST_ENTRY     ListEntry;
    PFCB_LIST_ENTRY FcbListEntry;

    BOOLEAN         Flush = FlushBeforePurge;
    
    __try
    {
        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
            (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
        
        if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
        {
            Flush = FALSE;
        }

        ExAcquireResourceSharedLite(
            &Vcb->MainResource,
            TRUE );
        
        VcbResourceAcquired = TRUE;
        
        InitializeListHead(&FcbList);
        
        for (ListEntry = Vcb->FcbList.Flink;
             ListEntry != &Vcb->FcbList;
             ListEntry = ListEntry->Flink  )
        {
            Fcb = CONTAINING_RECORD(ListEntry, EXT2_FCB, Next);
            
            ExAcquireResourceExclusiveLite(
                &Fcb->CountResource,
                TRUE );
            
            Fcb->ReferenceCount++;

            ExReleaseResourceForThreadLite(
                &Fcb->CountResource,
                ExGetCurrentResourceThread());

#if DBG
            Ext2DbgPrint(D_FSCTL, "Ext2PurgeVolume: %s refercount=%xh\n", Fcb->AnsiFileName.Buffer, Fcb->ReferenceCount);
#endif  
            
            FcbListEntry = ExAllocatePool(PagedPool, sizeof(FCB_LIST_ENTRY));

            if (!FcbListEntry)
            {
                Ext2DbgPrint(D_FSCTL, "Ext2PurgeVolume: Error allocating FcbListEntry ...\n");
            }
            
            FcbListEntry->Fcb = Fcb;
            
            InsertTailList(&FcbList, &FcbListEntry->Next);
        }
        
        ExReleaseResourceForThreadLite(
            &Vcb->MainResource,
            ExGetCurrentResourceThread() );
        
        VcbResourceAcquired = FALSE;
        
        while (!IsListEmpty(&FcbList))
        {
            ListEntry = RemoveHeadList(&FcbList);
            
            FcbListEntry = CONTAINING_RECORD(ListEntry, FCB_LIST_ENTRY, Next);
            
            Fcb = FcbListEntry->Fcb;
            
            Ext2PurgeFile(Fcb, FlushBeforePurge);
            
            if (!Fcb->OpenHandleCount && Fcb->ReferenceCount == 1)
            {
#if DBG
                Ext2DbgPrint(D_FSCTL, "Ext2FreeFcb %s.\n", Fcb->AnsiFileName.Buffer);
#endif
                Ext2FreeFcb(Fcb);
            }
            
            ExFreePool(FcbListEntry);
        }
        
        Ext2DbgPrint(D_FSCTL, "Ext2PurgeVolume: Volume flushed and purged.\n");
    }
    __finally
    {
        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread() );
        }
    }

    return STATUS_SUCCESS;
}

NTSTATUS
Ext2PurgeFile (IN PEXT2_FCB Fcb,
           IN BOOLEAN  FlushBeforePurge )
{
    IO_STATUS_BLOCK    IoStatus;

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

    
    if(!IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) && FlushBeforePurge)
    {
#if DBG
        Ext2DbgPrint(D_FSCTL, "Ext2PurgeFile: CcFlushCache on %s.\n", Fcb->AnsiFileName.Buffer);
#endif        
        CcFlushCache(&Fcb->SectionObject, NULL, 0, &IoStatus);
        ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
    }
    
    if (Fcb->SectionObject.ImageSectionObject)
    {

#if DBG
        Ext2DbgPrint(D_FSCTL, "Ext2PurgeFile: MmFlushImageSection on %s.\n", Fcb->AnsiFileName.Buffer);
#endif
    
        MmFlushImageSection(&Fcb->SectionObject, MmFlushForWrite);
    }
    
    if (Fcb->SectionObject.DataSectionObject)
    {
#if DBG
        Ext2DbgPrint(D_FSCTL, "Ext2PurgeFile: CcPurgeCacheSection on %s.\n", Fcb->AnsiFileName.Buffer);
#endif
        CcPurgeCacheSection(&Fcb->SectionObject, NULL, 0, FALSE);
    }

    return STATUS_SUCCESS;
}


NTSTATUS
Ext2FileSystemControl (IN PEXT2_IRP_CONTEXT IrpContext)
{
    NTSTATUS    Status;
    
    ASSERT(IrpContext);
    
    ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
        (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
    
    switch (IrpContext->MinorFunction)
    {
    case IRP_MN_USER_FS_REQUEST:
        Status = Ext2UserFsRequest(IrpContext);
        break;
        
    case IRP_MN_MOUNT_VOLUME:
        Status = Ext2MountVolume(IrpContext);
        break;
        
    case IRP_MN_VERIFY_VOLUME:
        Status = Ext2VerifyVolume(IrpContext);
        break;
        
    default:
        Status = STATUS_INVALID_DEVICE_REQUEST;
        IrpContext->Irp->IoStatus.Status = Status;
        Ext2CompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
        Ext2FreeIrpContext(IrpContext);
    }
    
    return Status;
}

⌨️ 快捷键说明

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