https://git.reactos.org/?p=reactos.git;a=commitdiff;h=03a9d8c7ca880006b4aa3…
commit 03a9d8c7ca880006b4aa37098e885206ddc106cc
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Sat Nov 4 21:29:51 2017 +0100
[CDFS] Implement volume un/locking.
CORE-13957
---
drivers/filesystems/cdfs/cdfs.h | 4 +++
drivers/filesystems/cdfs/fsctl.c | 69 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 73 insertions(+)
diff --git a/drivers/filesystems/cdfs/cdfs.h b/drivers/filesystems/cdfs/cdfs.h
index f5a8185834..b23846f647 100644
--- a/drivers/filesystems/cdfs/cdfs.h
+++ b/drivers/filesystems/cdfs/cdfs.h
@@ -153,6 +153,8 @@ typedef struct _CDINFO
} CDINFO, *PCDINFO;
+#define VCB_VOLUME_LOCKED 0x0001
+
typedef struct
{
ERESOURCE VcbResource;
@@ -165,6 +167,8 @@ typedef struct
PDEVICE_OBJECT StorageDevice;
PFILE_OBJECT StreamFileObject;
+ ULONG Flags;
+
CDINFO CdInfo;
/* Notifications */
diff --git a/drivers/filesystems/cdfs/fsctl.c b/drivers/filesystems/cdfs/fsctl.c
index 44ad59cf22..925819fb8e 100644
--- a/drivers/filesystems/cdfs/fsctl.c
+++ b/drivers/filesystems/cdfs/fsctl.c
@@ -23,6 +23,7 @@
* PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes
* Eric Kohl
+* Pierre Schweitzer
*/
/* INCLUDES *****************************************************************/
@@ -549,6 +550,64 @@ CdfsVerifyVolume(
}
+static
+NTSTATUS
+CdfsLockOrUnlockVolume(
+ IN PCDFS_IRP_CONTEXT IrpContext,
+ IN BOOLEAN LockVolume)
+{
+ PFCB Fcb;
+ PVPB Vpb;
+ PFILE_OBJECT FileObject;
+ PDEVICE_EXTENSION DeviceExt;
+
+ FileObject = IrpContext->FileObject;
+ Fcb = FileObject->FsContext;
+ DeviceExt = IrpContext->DeviceObject->DeviceExtension;
+ Vpb = DeviceExt->StreamFileObject->Vpb;
+
+ /* Only allow locking with the volume open */
+ if (!BooleanFlagOn(Fcb->Flags, FCB_IS_VOLUME_STREAM))
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Bail out if it's already in the demanded state */
+ if ((BooleanFlagOn(DeviceExt->Flags, VCB_VOLUME_LOCKED) && LockVolume) ||
+ (!BooleanFlagOn(DeviceExt->Flags, VCB_VOLUME_LOCKED) && !LockVolume))
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Bail out if it's already in the demanded state */
+ if ((BooleanFlagOn(Vpb->Flags, VPB_LOCKED) && LockVolume) ||
+ (!BooleanFlagOn(Vpb->Flags, VPB_LOCKED) && !LockVolume))
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Deny locking if we're not alone */
+ if (LockVolume && DeviceExt->OpenHandleCount != 1)
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Finally, proceed */
+ if (LockVolume)
+ {
+ DeviceExt->Flags |= VCB_VOLUME_LOCKED;
+ Vpb->Flags |= VPB_LOCKED;
+ }
+ else
+ {
+ DeviceExt->Flags &= ~VCB_VOLUME_LOCKED;
+ Vpb->Flags &= ~VPB_LOCKED;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
NTSTATUS
NTAPI
CdfsSetCompression(
@@ -604,6 +663,16 @@ CdfsFileSystemControl(
Status = CdfsSetCompression(DeviceObject, Irp);
break;
+ case FSCTL_LOCK_VOLUME:
+ DPRINT("CDFS: IRP_MN_USER_FS_REQUEST /
FSCTL_LOCK_VOLUME\n");
+ Status = CdfsLockOrUnlockVolume(IrpContext, TRUE);
+ break;
+
+ case FSCTL_UNLOCK_VOLUME:
+ DPRINT("CDFS: IRP_MN_USER_FS_REQUEST /
FSCTL_UNLOCK_VOLUME\n");
+ Status = CdfsLockOrUnlockVolume(IrpContext, FALSE);
+ break;
+
default:
DPRINT1("CDFS: IRP_MN_USER_FS_REQUEST / Unknown IoControlCode
0x%x\n",
Stack->Parameters.DeviceIoControl.IoControlCode);