From fd5c07553123522c1fb9bb3371f94dc16dd16b7b Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 14 Oct 2009 15:59:14 +0000 Subject: [PATCH] [fastfat_new] - Implement shared VCB locking. - Implement QueryVolumeInfo common handler, and a handler of QueryFsVolumeInfo class. Doesn't currently work due to missing VPB. svn path=/trunk/; revision=43453 --- .../drivers/filesystems/fastfat_new/fastfat.c | 17 ++ .../drivers/filesystems/fastfat_new/fastfat.h | 4 + .../drivers/filesystems/fastfat_new/volume.c | 148 +++++++++++++++++- 3 files changed, 166 insertions(+), 3 deletions(-) diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.c b/reactos/drivers/filesystems/fastfat_new/fastfat.c index 52db0af1064..533e7520807 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.c +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.c @@ -385,6 +385,23 @@ FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext, } } +BOOLEAN +NTAPI +FatAcquireSharedVcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PVCB Vcb) +{ + /* Acquire VCB's resource if possible */ + if (ExAcquireResourceSharedLite(&Vcb->Resource, + BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) + { + return TRUE; + } + else + { + return FALSE; + } +} + VOID NTAPI FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext, diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.h b/reactos/drivers/filesystems/fastfat_new/fastfat.h index ccfb7a2feb4..1ecdb6cbaf8 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.h +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.h @@ -143,6 +143,10 @@ BOOLEAN NTAPI FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb); +BOOLEAN NTAPI +FatAcquireSharedVcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PVCB Vcb); + VOID NTAPI FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb); diff --git a/reactos/drivers/filesystems/fastfat_new/volume.c b/reactos/drivers/filesystems/fastfat_new/volume.c index 3bcb558327c..f32f4efbb3a 100644 --- a/reactos/drivers/filesystems/fastfat_new/volume.c +++ b/reactos/drivers/filesystems/fastfat_new/volume.c @@ -8,17 +8,159 @@ /* INCLUDES *****************************************************************/ -#define NDEBUG +//#define NDEBUG #include "fastfat.h" /* FUNCTIONS ****************************************************************/ +NTSTATUS +NTAPI +FatiQueryFsVolumeInfo(PVCB Vcb, + PFILE_FS_VOLUME_INFORMATION Buffer, + PLONG Length) +{ + ULONG ByteSize; + NTSTATUS Status = STATUS_SUCCESS; + + /* Deduct the minimum written length */ + *Length -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]); + + /* Zero it */ + RtlZeroMemory(Buffer, sizeof(FILE_FS_VOLUME_INFORMATION)); + + DPRINT("Serial number 0x%x, label length %d\n", + Vcb->Vpb->SerialNumber, Vcb->Vpb->VolumeLabelLength); + + /* Save serial number */ + Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber; + + /* Set max byte size */ + ByteSize = Vcb->Vpb->VolumeLabelLength; + + /* Check buffer length and reduce byte size if needed */ + if (*Length < Vcb->Vpb->VolumeLabelLength) + { + /* Copy only up to what buffer size was provided */ + ByteSize = *Length; + Status = STATUS_BUFFER_OVERFLOW; + } + + /* Copy volume label */ + Buffer->VolumeLabelLength = Vcb->Vpb->VolumeLabelLength; + RtlCopyMemory(Buffer->VolumeLabel, Vcb->Vpb->VolumeLabel, ByteSize); + *Length -= ByteSize; + + return Status; +} + +NTSTATUS +NTAPI +FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) +{ + PFILE_OBJECT FileObject; + PIO_STACK_LOCATION IrpSp; + FILE_INFORMATION_CLASS InfoClass; + TYPE_OF_OPEN FileType; + PVCB Vcb; + PFCB Fcb; + PCCB Ccb; + LONG Length; + PVOID Buffer; + BOOLEAN VcbLocked = FALSE; + NTSTATUS Status = STATUS_SUCCESS; + + /* Get IRP stack location */ + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + /* Get the file object */ + FileObject = IrpSp->FileObject; + + /* Copy variables to something with shorter names */ + InfoClass = IrpSp->Parameters.QueryVolume.FsInformationClass; + Length = IrpSp->Parameters.QueryVolume.Length; + Buffer = Irp->AssociatedIrp.SystemBuffer; + + DPRINT("FatiQueryVolumeInfo\n", 0); + DPRINT("\tIrp = %08lx\n", Irp); + DPRINT("\tLength = %08lx\n", Length); + DPRINT("\tFsInformationClass = %08lx\n", InfoClass); + DPRINT("\tBuffer = %08lx\n", Buffer); + + FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); + + DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType); + + switch (InfoClass) + { + case FileFsVolumeInformation: + /* Acquired the shared VCB lock */ + if (!FatAcquireSharedVcb(IrpContext, Vcb)) + { + ASSERT(FALSE); + } + + /* Remember we locked it */ + VcbLocked = TRUE; + + /* Call FsVolumeInfo handler */ + Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length); + break; + default: + DPRINT1("Volume information class %d is not supported!\n", InfoClass); + UNIMPLEMENTED; + } + + /* Set IoStatus.Information to amount of filled bytes */ + Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length; + + /* Release VCB lock */ + if (VcbLocked) FatReleaseVcb(IrpContext, Vcb); + + /* Complete request and return status */ + FatCompleteRequest(IrpContext, Irp, Status); + return Status; +} + NTSTATUS NTAPI FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp) { - DPRINT1("FatQueryVolumeInfo()\n"); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + BOOLEAN TopLevel, CanWait; + PFAT_IRP_CONTEXT IrpContext; + + CanWait = TRUE; + TopLevel = FALSE; + Status = STATUS_INVALID_DEVICE_REQUEST; + + /* Get CanWait flag */ + if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL) + CanWait = IoIsOperationSynchronous(Irp); + + /* Enter FsRtl critical region */ + FsRtlEnterFileSystem(); + + /* Set Top Level IRP if not set */ + if (IoGetTopLevelIrp() == NULL) + { + IoSetTopLevelIrp(Irp); + TopLevel = TRUE; + } + + /* Build an irp context */ + IrpContext = FatBuildIrpContext(Irp, CanWait); + + /* Call the request handler */ + Status = FatiQueryVolumeInfo(IrpContext, Irp); + + /* Restore top level Irp */ + if (TopLevel) + IoSetTopLevelIrp(NULL); + + /* Leave FsRtl critical region */ + FsRtlExitFileSystem(); + + return Status; } NTSTATUS