diff --git a/reactos/drivers/filesystems/fastfat/cleanup.c b/reactos/drivers/filesystems/fastfat/cleanup.c index 97c2515116e..f9bde77d206 100644 --- a/reactos/drivers/filesystems/fastfat/cleanup.c +++ b/reactos/drivers/filesystems/fastfat/cleanup.c @@ -24,6 +24,7 @@ VfatCleanupFile( PVFAT_IRP_CONTEXT IrpContext) { PVFATFCB pFcb; + PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt; PFILE_OBJECT FileObject = IrpContext->FileObject; DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n", @@ -37,6 +38,7 @@ VfatCleanupFile( if (pFcb->Flags & FCB_IS_VOLUME) { pFcb->OpenHandleCount--; + DeviceExt->OpenHandleCount--; if (pFcb->OpenHandleCount != 0) { @@ -63,6 +65,7 @@ VfatCleanupFile( FileObject->FsContext2); pFcb->OpenHandleCount--; + DeviceExt->OpenHandleCount--; if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) && FsRtlAreThereCurrentFileLocks(&pFcb->FileLock)) diff --git a/reactos/drivers/filesystems/fastfat/create.c b/reactos/drivers/filesystems/fastfat/create.c index bccbdb77183..6314c52ae3c 100644 --- a/reactos/drivers/filesystems/fastfat/create.c +++ b/reactos/drivers/filesystems/fastfat/create.c @@ -473,10 +473,18 @@ VfatCreateFile( return STATUS_INVALID_PARAMETER; } + /* Deny create if the volume is locked */ + if (DeviceExt->Flags & VCB_VOLUME_LOCKED) + { + return STATUS_ACCESS_DENIED; + } + /* This a open operation for the volume itself */ if (FileObject->FileName.Length == 0 && (FileObject->RelatedFileObject == NULL || FileObject->RelatedFileObject->FsContext2 != NULL)) { + DPRINT1("Volume opening\n"); + if (RequestedDisposition != FILE_OPEN && RequestedDisposition != FILE_OPEN_IF) { @@ -497,6 +505,7 @@ VfatCreateFile( pFcb = DeviceExt->VolumeFcb; vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject); + DeviceExt->OpenHandleCount++; Irp->IoStatus.Information = FILE_OPENED; return STATUS_SUCCESS; @@ -639,6 +648,7 @@ VfatCreateFile( } pFcb->OpenHandleCount++; + DeviceExt->OpenHandleCount++; } else if (ParentFcb != NULL) { @@ -884,6 +894,7 @@ VfatCreateFile( } pFcb->OpenHandleCount++; + DeviceExt->OpenHandleCount++; /* FIXME : test write access if requested */ diff --git a/reactos/drivers/filesystems/fastfat/fsctl.c b/reactos/drivers/filesystems/fastfat/fsctl.c index e0a1608600c..19f97854ea8 100644 --- a/reactos/drivers/filesystems/fastfat/fsctl.c +++ b/reactos/drivers/filesystems/fastfat/fsctl.c @@ -612,6 +612,8 @@ VfatMount( FsRtlNotifyInitializeSync(&DeviceExt->NotifySync); InitializeListHead(&DeviceExt->NotifyList); + DPRINT1("Mount success\n"); + Status = STATUS_SUCCESS; ByeBye: @@ -855,6 +857,72 @@ VfatMarkVolumeDirty( return Status; } +static +NTSTATUS +VfatLockOrUnlockVolume( + PVFAT_IRP_CONTEXT IrpContext, + BOOLEAN Lock) +{ + PFILE_OBJECT FileObject; + PDEVICE_EXTENSION DeviceExt; + + DPRINT1("VfatLockOrUnlockVolume(%p, %d)\n", IrpContext, Lock); + + DeviceExt = IrpContext->DeviceExt; + FileObject = IrpContext->FileObject; + + /* Only allow locking with the volume open */ + if (FileObject->FsContext != DeviceExt->VolumeFcb) + { + return STATUS_ACCESS_DENIED; + } + + /* Bail out if it's already in the demanded state */ + if (((DeviceExt->Flags & VCB_VOLUME_LOCKED) && Lock) || + (!(DeviceExt->Flags & VCB_VOLUME_LOCKED) && !Lock)) + { + return STATUS_ACCESS_DENIED; + } + + /* Deny locking if we're not alone */ + if (Lock && DeviceExt->OpenHandleCount != 1) + { + return STATUS_ACCESS_DENIED; + } + + /* Finally, proceed */ + if (Lock) + { + DeviceExt->Flags |= VCB_VOLUME_LOCKED; + } + else + { + DeviceExt->Flags &= ~VCB_VOLUME_LOCKED; + } + + return STATUS_SUCCESS; +} + +static +NTSTATUS +VfatDismountVolume( + PVFAT_IRP_CONTEXT IrpContext) +{ + PDEVICE_EXTENSION DeviceExt; + + DPRINT1("VfatDismountVolume(%p)\n", IrpContext); + + DeviceExt = IrpContext->DeviceExt; + + if (!(DeviceExt->Flags & VCB_VOLUME_LOCKED)) + { + return STATUS_ACCESS_DENIED; + } + + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + /* * FUNCTION: File system control */ @@ -898,6 +966,18 @@ VfatFileSystemControl( Status = VfatMarkVolumeDirty(IrpContext); break; + case FSCTL_LOCK_VOLUME: + Status = VfatLockOrUnlockVolume(IrpContext, TRUE); + break; + + case FSCTL_UNLOCK_VOLUME: + Status = VfatLockOrUnlockVolume(IrpContext, FALSE); + break; + + case FSCTL_DISMOUNT_VOLUME: + Status = VfatDismountVolume(IrpContext); + break; + default: Status = STATUS_INVALID_DEVICE_REQUEST; } diff --git a/reactos/drivers/filesystems/fastfat/vfat.h b/reactos/drivers/filesystems/fastfat/vfat.h index 416fa74c9fa..c35b73540b6 100644 --- a/reactos/drivers/filesystems/fastfat/vfat.h +++ b/reactos/drivers/filesystems/fastfat/vfat.h @@ -296,6 +296,9 @@ typedef struct DEVICE_EXTENSION /* Notifications */ LIST_ENTRY NotifyList; PNOTIFY_SYNC NotifySync; + + /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP */ + ULONG OpenHandleCount; } DEVICE_EXTENSION, VCB, *PVCB; typedef struct