From a8644f7a2d21af509d3f05b14f70f2e19f5d96ff Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Mon, 22 Feb 2016 22:20:54 +0000 Subject: [PATCH] [NTFS] - 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 --- .../drivers/filesystems/ntfs/CMakeLists.txt | 1 + reactos/drivers/filesystems/ntfs/close.c | 1 + reactos/drivers/filesystems/ntfs/create.c | 12 ++++ reactos/drivers/filesystems/ntfs/dispatch.c | 4 ++ reactos/drivers/filesystems/ntfs/fsctl.c | 59 ++++++++++++++++++- reactos/drivers/filesystems/ntfs/ntfs.c | 1 + reactos/drivers/filesystems/ntfs/ntfs.h | 12 ++++ 7 files changed, 88 insertions(+), 2 deletions(-) diff --git a/reactos/drivers/filesystems/ntfs/CMakeLists.txt b/reactos/drivers/filesystems/ntfs/CMakeLists.txt index a5b247d48b9..ff3b35f647f 100644 --- a/reactos/drivers/filesystems/ntfs/CMakeLists.txt +++ b/reactos/drivers/filesystems/ntfs/CMakeLists.txt @@ -2,6 +2,7 @@ list(APPEND SOURCE attrib.c blockdev.c + cleanup.c close.c create.c devctl.c diff --git a/reactos/drivers/filesystems/ntfs/close.c b/reactos/drivers/filesystems/ntfs/close.c index 4502149f68e..79ef82c9326 100644 --- a/reactos/drivers/filesystems/ntfs/close.c +++ b/reactos/drivers/filesystems/ntfs/close.c @@ -59,6 +59,7 @@ NtfsCloseFile(PDEVICE_EXTENSION DeviceExt, FileObject->FsContext2 = NULL; FileObject->FsContext = NULL; FileObject->SectionObjectPointer = NULL; + DeviceExt->OpenHandleCount--; if (FileObject->FileName.Buffer) { diff --git a/reactos/drivers/filesystems/ntfs/create.c b/reactos/drivers/filesystems/ntfs/create.c index d8ad7082a5f..43859741e16 100644 --- a/reactos/drivers/filesystems/ntfs/create.c +++ b/reactos/drivers/filesystems/ntfs/create.c @@ -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 diff --git a/reactos/drivers/filesystems/ntfs/dispatch.c b/reactos/drivers/filesystems/ntfs/dispatch.c index 613e5cf1f7e..09140f2f320 100644 --- a/reactos/drivers/filesystems/ntfs/dispatch.c +++ b/reactos/drivers/filesystems/ntfs/dispatch.c @@ -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; diff --git a/reactos/drivers/filesystems/ntfs/fsctl.c b/reactos/drivers/filesystems/ntfs/fsctl.c index 5550df23b1d..0ce93a58eaa 100644 --- a/reactos/drivers/filesystems/ntfs/fsctl.c +++ b/reactos/drivers/filesystems/ntfs/fsctl.c @@ -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; diff --git a/reactos/drivers/filesystems/ntfs/ntfs.c b/reactos/drivers/filesystems/ntfs/ntfs.c index d4bbb84ddcd..94ba4f8f6a9 100644 --- a/reactos/drivers/filesystems/ntfs/ntfs.c +++ b/reactos/drivers/filesystems/ntfs/ntfs.c @@ -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; diff --git a/reactos/drivers/filesystems/ntfs/ntfs.h b/reactos/drivers/filesystems/ntfs/ntfs.h index 0ecd3159636..2e1567cd3c0 100644 --- a/reactos/drivers/filesystems/ntfs/ntfs.h +++ b/reactos/drivers/filesystems/ntfs/ntfs.h @@ -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