📄 fsctl.c
字号:
/*
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 + -