[CDFS] Implement volume un/locking.
authorPierre Schweitzer <pierre@reactos.org>
Sat, 4 Nov 2017 20:29:51 +0000 (21:29 +0100)
committerPierre Schweitzer <pierre@reactos.org>
Sat, 4 Nov 2017 20:29:51 +0000 (21:29 +0100)
CORE-13957

drivers/filesystems/cdfs/cdfs.h
drivers/filesystems/cdfs/fsctl.c

index f5a8185..b23846f 100644 (file)
@@ -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 */
index 44ad59c..925819f 100644 (file)
@@ -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);