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

📄 fsctl.c

📁 I want to provide an example file system driver for Windows NT/2000/XP. For some time I have worked
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
    This is a romfs file system driver for Windows NT/2000/XP.
    Copyright (C) 1999, 2000, 2001, 2002 Bo Brant閚.
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "ntifs.h"
#include "fsd.h"
#include "rom_fs.h"
#include "border.h"

NTSTATUS
FsdFileSystemControl (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    NTSTATUS Status;

    ASSERT(IrpContext);

    ASSERT((IrpContext->Identifier.Type == ICX) &&
           (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

    switch (IrpContext->MinorFunction)
    {
    case IRP_MN_USER_FS_REQUEST:
        Status = FsdUserFsRequest(IrpContext);
        break;

    case IRP_MN_MOUNT_VOLUME:
        Status = FsdMountVolume(IrpContext);
        break;

    case IRP_MN_VERIFY_VOLUME:
        Status = FsdVerifyVolume(IrpContext);
        break;

    default:
        Status = STATUS_INVALID_DEVICE_REQUEST;
        IrpContext->Irp->IoStatus.Status = Status;
        FsdCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
        FsdFreeIrpContext(IrpContext);
    }

    return Status;
}

NTSTATUS
FsdUserFsRequest (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    PIRP                Irp;
    PIO_STACK_LOCATION  IrpSp;
    ULONG               FsControlCode;
    NTSTATUS            Status;

    ASSERT(IrpContext);

    ASSERT((IrpContext->Identifier.Type == ICX) &&
           (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

    Irp = IrpContext->Irp;

    IrpSp = IoGetCurrentIrpStackLocation(Irp);

#ifndef _GNU_NTIFS_
    FsControlCode =
        IrpSp->Parameters.FileSystemControl.FsControlCode;
#else
    FsControlCode = ((PEXTENDED_IO_STACK_LOCATION)
        IrpSp)->Parameters.FileSystemControl.FsControlCode;
#endif

    switch (FsControlCode)
    {
    case FSCTL_LOCK_VOLUME:
        Status = FsdLockVolume(IrpContext);
        break;

    case FSCTL_UNLOCK_VOLUME:
        Status = FsdUnlockVolume(IrpContext);
        break;

    case FSCTL_DISMOUNT_VOLUME:
        Status = FsdDismountVolume(IrpContext);
        break;

    case FSCTL_IS_VOLUME_MOUNTED:
        Status = FsdIsVolumeMounted(IrpContext);
        break;

    default:
        Status = STATUS_INVALID_DEVICE_REQUEST;
        IrpContext->Irp->IoStatus.Status = Status;
        FsdCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
        FsdFreeIrpContext(IrpContext);
    }

    return Status;
}

#pragma code_seg(FSD_PAGED_CODE)

NTSTATUS
FsdLockVolume (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    PFSD_VCB        Vcb;
#if (VER_PRODUCTBUILD >= 2195)
    BOOLEAN         VolumeLockNotifyed = FALSE;
#endif
    BOOLEAN         VcbResourceAcquired = FALSE;

    __try
    {
        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == ICX) &&
               (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        if (DeviceObject == FsdGlobalData.DeviceObject)
        {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Vcb = (PFSD_VCB) DeviceObject->DeviceExtension;

        ASSERT(Vcb != NULL);

        ASSERT((Vcb->Identifier.Type == VCB) &&
               (Vcb->Identifier.Size == sizeof(FSD_VCB)));

#if (VER_PRODUCTBUILD >= 2195)

        FsRtlNotifyVolumeEvent(IrpContext->FileObject, FSRTL_VOLUME_LOCK);

        VolumeLockNotifyed = TRUE;

#endif

        ExAcquireResourceSharedLite(
             &Vcb->MainResource,
             TRUE
             );

        VcbResourceAcquired = TRUE;

        if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED))
        {
            KdPrint((DRIVER_NAME ": *** Volume is already locked ***\n"));

            Status = STATUS_ACCESS_DENIED;

            __leave;
        }

        if (Vcb->OpenFileHandleCount)
        {
            KdPrint((DRIVER_NAME ": *** Open files exists ***\n"));

            Status = STATUS_ACCESS_DENIED;

            __leave;
        }

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

        VcbResourceAcquired = FALSE;

        FsdPurgeVolume(Vcb, TRUE);

        ExAcquireResourceExclusiveLite(
             &Vcb->MainResource,
             TRUE
             );

        VcbResourceAcquired = TRUE;

        if (Vcb->ReferenceCount > 1)
        {
            KdPrint((DRIVER_NAME ": *** Could not purge cached files ***\n"));

            Status = STATUS_ACCESS_DENIED;

            __leave;
        }

        SetFlag(Vcb->Flags, VCB_VOLUME_LOCKED);

        FsdSetVpbFlag(Vcb->Vpb, VPB_LOCKED);

        KdPrint((DRIVER_NAME ": Volume locked\n"));

        Status = STATUS_SUCCESS;
    }
    __finally
    {
        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }

#if (VER_PRODUCTBUILD >= 2195)

        if (!NT_SUCCESS(Status) && VolumeLockNotifyed)
        {
            FsRtlNotifyVolumeEvent(IrpContext->FileObject, FSRTL_VOLUME_LOCK_FAILED);
        }

#endif

        if (!AbnormalTermination())
        {
            IrpContext->Irp->IoStatus.Status = Status;

            FsdCompleteRequest(
                IrpContext->Irp,
                (CCHAR)
                (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
                );

            FsdFreeIrpContext(IrpContext);
        }
    }

    return Status;
}

NTSTATUS
FsdUnlockVolume (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    PFSD_VCB        Vcb;
    BOOLEAN         VcbResourceAcquired = FALSE;

    __try
    {
        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == ICX) &&
               (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        if (DeviceObject == FsdGlobalData.DeviceObject)
        {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Vcb = (PFSD_VCB) DeviceObject->DeviceExtension;

        ASSERT(Vcb != NULL);

        ASSERT((Vcb->Identifier.Type == VCB) &&
               (Vcb->Identifier.Size == sizeof(FSD_VCB)));

        ExAcquireResourceExclusiveLite(
             &Vcb->MainResource,
             TRUE
             );

        VcbResourceAcquired = TRUE;

        if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED))
        {
            KdPrint((DRIVER_NAME ": *** Volume is not locked ***\n"));

            Status = STATUS_ACCESS_DENIED;

            __leave;
        }

        ClearFlag(Vcb->Flags, VCB_VOLUME_LOCKED);

        FsdClearVpbFlag(Vcb->Vpb, VPB_LOCKED);

        KdPrint((DRIVER_NAME ": Volume unlocked\n"));

        Status = STATUS_SUCCESS;
    }
    __finally
    {
        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }

#if (VER_PRODUCTBUILD >= 2195)

        if (NT_SUCCESS(Status))
        {
            FsRtlNotifyVolumeEvent(IrpContext->FileObject, FSRTL_VOLUME_UNLOCK);
        }

#endif

        if (!AbnormalTermination())
        {
            IrpContext->Irp->IoStatus.Status = Status;

            FsdCompleteRequest(
                IrpContext->Irp,
                (CCHAR)
                (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
                );

            FsdFreeIrpContext(IrpContext);
        }
    }

    return Status;
}

NTSTATUS
FsdDismountVolume (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    PDEVICE_OBJECT  DeviceObject;
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    PFSD_VCB        Vcb;
#if (VER_PRODUCTBUILD >= 2195)
    BOOLEAN         VolumeDismountNotifyed = FALSE;
#endif
    BOOLEAN         VcbResourceAcquired = FALSE;

    __try
    {
        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == ICX) &&
               (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;

        if (DeviceObject == FsdGlobalData.DeviceObject)
        {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Vcb = (PFSD_VCB) DeviceObject->DeviceExtension;

        ASSERT(Vcb != NULL);

        ASSERT((Vcb->Identifier.Type == VCB) &&
               (Vcb->Identifier.Size == sizeof(FSD_VCB)));

#if (VER_PRODUCTBUILD >= 2195)

        FsRtlNotifyVolumeEvent(IrpContext->FileObject, FSRTL_VOLUME_DISMOUNT);

        VolumeDismountNotifyed = TRUE;

#endif

        ExAcquireResourceExclusiveLite(
             &Vcb->MainResource,
             TRUE
             );

        VcbResourceAcquired = TRUE;

        if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED))
        {
            KdPrint((DRIVER_NAME ": *** Volume is not locked ***\n"));

            Status = STATUS_ACCESS_DENIED;

            __leave;
        }

        SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);

        KdPrint((DRIVER_NAME ": Volume dismount pending\n"));

        Status = STATUS_SUCCESS;
    }
    __finally
    {
        if (VcbResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread()
                );
        }

#if (VER_PRODUCTBUILD >= 2195)

        if (!NT_SUCCESS(Status) && VolumeDismountNotifyed)
        {
            FsRtlNotifyVolumeEvent(IrpContext->FileObject, FSRTL_VOLUME_DISMOUNT_FAILED);
        }

#endif

        if (!AbnormalTermination())
        {
            IrpContext->Irp->IoStatus.Status = Status;

            FsdCompleteRequest(
                IrpContext->Irp,
                (CCHAR)
                (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
                );

            FsdFreeIrpContext(IrpContext);
        }
    }

    return Status;
}

#pragma code_seg() // end FSD_PAGED_CODE

NTSTATUS
FsdIsVolumeMounted (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    ASSERT(IrpContext);

    ASSERT((IrpContext->Identifier.Type == ICX) &&
           (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

    return FsdVerifyVolume(IrpContext);
}

#pragma code_seg(FSD_PAGED_CODE)

NTSTATUS
FsdMountVolume (
    IN PFSD_IRP_CONTEXT IrpContext
    )
{
    PDEVICE_OBJECT              MainDeviceObject;
    BOOLEAN                     GlobalDataResourceAcquired = FALSE;
    PIRP                        Irp;
    PIO_STACK_LOCATION          IrpSp;
    PDEVICE_OBJECT              TargetDeviceObject;
    NTSTATUS                    Status = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT              VolumeDeviceObject = NULL;
    PFSD_VCB                    Vcb;
    BOOLEAN                     VcbResourceInitialized = FALSE;
    BOOLEAN                     NotifySyncInitialized = FALSE;
    struct romfs_super_block*   romfs_super_block = NULL;
    USHORT                      VolumeLabelLength;
    struct romfs_inode*         Inode = NULL;
    LARGE_INTEGER               Offset;
    ULONG                       IoctlSize;

    __try
    {
        ASSERT(IrpContext != NULL);

        ASSERT((IrpContext->Identifier.Type == ICX) &&
               (IrpContext->Identifier.Size == sizeof(FSD_IRP_CONTEXT)));

        MainDeviceObject = IrpContext->DeviceObject;

        if (MainDeviceObject != FsdGlobalData.DeviceObject)
        {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        ExAcquireResourceExclusiveLite(
            &FsdGlobalData.Resource,
            TRUE
            );

        GlobalDataResourceAcquired = TRUE;

        if (FlagOn(FsdGlobalData.Flags, FSD_UNLOAD_PENDING))
        {
            Status = STATUS_UNRECOGNIZED_VOLUME;
            __leave;
        }

        Irp = IrpContext->Irp;

        IrpSp = IoGetCurrentIrpStackLocation(Irp);

        TargetDeviceObject = IrpSp->Parameters.MountVolume.DeviceObject;

        Status = FsdIsDeviceRomfs(TargetDeviceObject);

        if (!NT_SUCCESS(Status))
        {
            __leave;
        }

        Status = IoCreateDevice(
            MainDeviceObject->DriverObject,
            sizeof(FSD_VCB),
            NULL,
            FILE_DEVICE_DISK_FILE_SYSTEM,

⌨️ 快捷键说明

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