[FASTFAT]
authorPierre Schweitzer <pierre@reactos.org>
Thu, 30 Oct 2014 20:56:40 +0000 (20:56 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Thu, 30 Oct 2014 20:56:40 +0000 (20:56 +0000)
On the road for getting rid of IopParseDevice() hack....

- Add support for FSCTL_LOCK_VOLUME, FSCTL_UNLOCK_VOLUME, FSCTL_DISMOUNT_VOLUME in VfatFileSystemControl()
- Implement VfatLockOrUnlockVolume(). This brings some kind of volume locking to FastFAT FSD. It's likely not fully accurate and welcome to race conditions. But, its main purpose is to be used in usetup. So, this is fine for now.
- Stubplement VfatDismountVolume(). This will be implemented later on, but should be relatively straightforward as it requires volume to be locked (so, we're the last ones on it :-)).

svn path=/trunk/; revision=65129

reactos/drivers/filesystems/fastfat/cleanup.c
reactos/drivers/filesystems/fastfat/create.c
reactos/drivers/filesystems/fastfat/fsctl.c
reactos/drivers/filesystems/fastfat/vfat.h

index 97c2515..f9bde77 100644 (file)
@@ -24,6 +24,7 @@ VfatCleanupFile(
     PVFAT_IRP_CONTEXT IrpContext)
 {
     PVFATFCB pFcb;
     PVFAT_IRP_CONTEXT IrpContext)
 {
     PVFATFCB pFcb;
+    PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt;
     PFILE_OBJECT FileObject = IrpContext->FileObject;
 
     DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
     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--;
     if (pFcb->Flags & FCB_IS_VOLUME)
     {
         pFcb->OpenHandleCount--;
+        DeviceExt->OpenHandleCount--;
 
         if (pFcb->OpenHandleCount != 0)
         {
 
         if (pFcb->OpenHandleCount != 0)
         {
@@ -63,6 +65,7 @@ VfatCleanupFile(
                            FileObject->FsContext2);
 
         pFcb->OpenHandleCount--;
                            FileObject->FsContext2);
 
         pFcb->OpenHandleCount--;
+        DeviceExt->OpenHandleCount--;
 
         if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
             FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
 
         if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
             FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
index bccbdb7..6314c52 100644 (file)
@@ -473,10 +473,18 @@ VfatCreateFile(
         return STATUS_INVALID_PARAMETER;
     }
 
         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))
     {
     /* 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)
         {
         if (RequestedDisposition != FILE_OPEN &&
             RequestedDisposition != FILE_OPEN_IF)
         {
@@ -497,6 +505,7 @@ VfatCreateFile(
 
         pFcb = DeviceExt->VolumeFcb;
         vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
 
         pFcb = DeviceExt->VolumeFcb;
         vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
+        DeviceExt->OpenHandleCount++;
 
         Irp->IoStatus.Information = FILE_OPENED;
         return STATUS_SUCCESS;
 
         Irp->IoStatus.Information = FILE_OPENED;
         return STATUS_SUCCESS;
@@ -639,6 +648,7 @@ VfatCreateFile(
             }
 
             pFcb->OpenHandleCount++;
             }
 
             pFcb->OpenHandleCount++;
+            DeviceExt->OpenHandleCount++;
         }
         else if (ParentFcb != NULL)
         {
         }
         else if (ParentFcb != NULL)
         {
@@ -884,6 +894,7 @@ VfatCreateFile(
     }
 
     pFcb->OpenHandleCount++;
     }
 
     pFcb->OpenHandleCount++;
+    DeviceExt->OpenHandleCount++;
 
     /* FIXME : test write access if requested */
 
 
     /* FIXME : test write access if requested */
 
index e0a1608..19f9785 100644 (file)
@@ -612,6 +612,8 @@ VfatMount(
     FsRtlNotifyInitializeSync(&DeviceExt->NotifySync);
     InitializeListHead(&DeviceExt->NotifyList);
 
     FsRtlNotifyInitializeSync(&DeviceExt->NotifySync);
     InitializeListHead(&DeviceExt->NotifyList);
 
+    DPRINT1("Mount success\n");
+
     Status = STATUS_SUCCESS;
 
 ByeBye:
     Status = STATUS_SUCCESS;
 
 ByeBye:
@@ -855,6 +857,72 @@ VfatMarkVolumeDirty(
     return Status;
 }
 
     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
  */
 /*
  * FUNCTION: File system control
  */
@@ -898,6 +966,18 @@ VfatFileSystemControl(
                     Status = VfatMarkVolumeDirty(IrpContext);
                     break;
 
                     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;
             }
                 default:
                     Status = STATUS_INVALID_DEVICE_REQUEST;
             }
index 416fa74..c35b735 100644 (file)
@@ -296,6 +296,9 @@ typedef struct DEVICE_EXTENSION
     /* Notifications */
     LIST_ENTRY NotifyList;
     PNOTIFY_SYNC NotifySync;
     /* 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
 } DEVICE_EXTENSION, VCB, *PVCB;
 
 typedef struct