From 03a9d8c7ca880006b4aa37098e885206ddc106cc Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sat, 4 Nov 2017 21:29:51 +0100 Subject: [PATCH] [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 f5a81858344..b23846f6478 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 44ad59cf228..925819fb8e1 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); -- 2.17.1