[NTFS]
authorPierre Schweitzer <pierre@reactos.org>
Mon, 22 Feb 2016 22:20:54 +0000 (22:20 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 22 Feb 2016 22:20:54 +0000 (22:20 +0000)
- Implement IRP_MJ_CLEANUP (minus the cases we can't deal with yet)
- Implement open handles count for FCB & VCB
- Implement volume locking (so useful)

svn path=/trunk/; revision=70772

reactos/drivers/filesystems/ntfs/CMakeLists.txt
reactos/drivers/filesystems/ntfs/close.c
reactos/drivers/filesystems/ntfs/create.c
reactos/drivers/filesystems/ntfs/dispatch.c
reactos/drivers/filesystems/ntfs/fsctl.c
reactos/drivers/filesystems/ntfs/ntfs.c
reactos/drivers/filesystems/ntfs/ntfs.h

index a5b247d..ff3b35f 100644 (file)
@@ -2,6 +2,7 @@
 list(APPEND SOURCE
     attrib.c
     blockdev.c
+    cleanup.c
     close.c
     create.c
     devctl.c
index 4502149..79ef82c 100644 (file)
@@ -59,6 +59,7 @@ NtfsCloseFile(PDEVICE_EXTENSION DeviceExt,
     FileObject->FsContext2 = NULL;
     FileObject->FsContext = NULL;
     FileObject->SectionObjectPointer = NULL;
+    DeviceExt->OpenHandleCount--;
 
     if (FileObject->FileName.Buffer)
     {
index d8ad708..4385974 100644 (file)
@@ -351,6 +351,12 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject,
         return STATUS_INVALID_PARAMETER;
     }
 
+    /* Deny create if the volume is locked */
+    if (DeviceExt->Flags & VCB_VOLUME_LOCKED)
+    {
+        return STATUS_ACCESS_DENIED;
+    }
+
     FileObject = Stack->FileObject;
 
     if (RequestedDisposition == FILE_CREATE ||
@@ -500,6 +506,12 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject,
         }
     }
 
+    if (NT_SUCCESS(Status))
+    {
+        Fcb->OpenHandleCount++;
+        DeviceExt->OpenHandleCount++;
+    }
+
     /*
      * If the directory containing the file to open doesn't exist then
      * fail immediately
index 613e5cf..09140f2 100644 (file)
@@ -101,6 +101,10 @@ NtfsDispatch(PNTFS_IRP_CONTEXT IrpContext)
             Status = NtfsClose(IrpContext);
             break;
 
+        case IRP_MJ_CLEANUP:
+            Status = NtfsCleanup(IrpContext);
+            break;
+
         case IRP_MJ_CREATE:
             Status = NtfsCreate(IrpContext);
             break;
index 5550df2..0ce93a5 100644 (file)
@@ -833,6 +833,55 @@ GetVolumeBitmap(PDEVICE_EXTENSION DeviceExt,
 }
 
 
+static
+NTSTATUS
+LockOrUnlockVolume(PDEVICE_EXTENSION DeviceExt,
+                   PIRP Irp,
+                   BOOLEAN Lock)
+{
+    PFILE_OBJECT FileObject;
+    PNTFS_FCB Fcb;
+    PIO_STACK_LOCATION Stack;
+
+    DPRINT("LockOrUnlockVolume(%p, %p, %d)\n", DeviceExt, Irp, Lock);
+
+    Stack = IoGetCurrentIrpStackLocation(Irp);
+    FileObject = Stack->FileObject;
+    Fcb = FileObject->FsContext;
+
+    /* Only allow locking with the volume open */
+    if (!(Fcb->Flags & FCB_IS_VOLUME))
+    {
+        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
 NtfsUserFsRequest(PDEVICE_OBJECT DeviceObject,
@@ -854,7 +903,6 @@ NtfsUserFsRequest(PDEVICE_OBJECT DeviceObject,
         case FSCTL_EXTEND_VOLUME:
         //case FSCTL_GET_RETRIEVAL_POINTER_BASE:
         case FSCTL_GET_RETRIEVAL_POINTERS:
-        case FSCTL_LOCK_VOLUME:
         //case FSCTL_LOOKUP_STREAM_FROM_CLUSTER:
         case FSCTL_MARK_HANDLE:
         case FSCTL_MOVE_FILE:
@@ -862,13 +910,20 @@ NtfsUserFsRequest(PDEVICE_OBJECT DeviceObject,
         case FSCTL_READ_FILE_USN_DATA:
         case FSCTL_READ_USN_JOURNAL:
         //case FSCTL_SHRINK_VOLUME:
-        case FSCTL_UNLOCK_VOLUME:
         case FSCTL_WRITE_USN_CLOSE_RECORD:
             UNIMPLEMENTED;
             DPRINT1("Unimplemented user request: %x\n", Stack->Parameters.FileSystemControl.FsControlCode);
             Status = STATUS_NOT_IMPLEMENTED;
             break;
 
+        case FSCTL_LOCK_VOLUME:
+            Status = LockOrUnlockVolume(DeviceExt, Irp, TRUE);
+            break;
+
+        case FSCTL_UNLOCK_VOLUME:
+            Status = LockOrUnlockVolume(DeviceExt, Irp, FALSE);
+            break;
+
         case FSCTL_GET_NTFS_VOLUME_DATA:
             Status = GetNfsVolumeData(DeviceExt, Irp);
             break;
index d4bbb84..94ba4f8 100644 (file)
@@ -135,6 +135,7 @@ NtfsInitializeFunctionPointers(PDRIVER_OBJECT DriverObject)
 {
     DriverObject->MajorFunction[IRP_MJ_CREATE]                   = NtfsFsdDispatch;
     DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = NtfsFsdDispatch;
+    DriverObject->MajorFunction[IRP_MJ_CLEANUP]                  = NtfsFsdDispatch;
     DriverObject->MajorFunction[IRP_MJ_READ]                     = NtfsFsdDispatch;
     DriverObject->MajorFunction[IRP_MJ_WRITE]                    = NtfsFsdDispatch;
     DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = NtfsFsdDispatch;
index 0ecd315..2e1567c 100644 (file)
@@ -116,8 +116,13 @@ typedef struct
 
     NTFS_INFO NtfsInfo;
 
+    ULONG Flags;
+    ULONG OpenHandleCount;
+
 } DEVICE_EXTENSION, *PDEVICE_EXTENSION, NTFS_VCB, *PNTFS_VCB;
 
+#define VCB_VOLUME_LOCKED       0x0001
+
 typedef struct
 {
     NTFSIDENTIFIER Identifier;
@@ -460,6 +465,7 @@ typedef struct _FCB
 
     LONG RefCount;
     ULONG Flags;
+    ULONG OpenHandleCount;
 
     ULONGLONG MFTIndex;
     USHORT LinkCount;
@@ -562,6 +568,12 @@ NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
                     IN BOOLEAN Override);
 
 
+/* close.c */
+
+NTSTATUS
+NtfsCleanup(PNTFS_IRP_CONTEXT IrpContext);
+
+
 /* close.c */
 
 NTSTATUS