Author: fireball Date: Wed Oct 14 17:59:14 2009 New Revision: 43453
URL: http://svn.reactos.org/svn/reactos?rev=43453&view=rev Log: [fastfat_new] - Implement shared VCB locking. - Implement QueryVolumeInfo common handler, and a handler of QueryFsVolumeInfo class. Doesn't currently work due to missing VPB.
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h trunk/reactos/drivers/filesystems/fastfat_new/volume.c
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat... ============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.c [iso-8859-1] Wed Oct 14 17:59:14 2009 @@ -385,6 +385,23 @@ } }
+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,
Modified: trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat... ============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/fastfat.h [iso-8859-1] Wed Oct 14 17:59:14 2009 @@ -142,6 +142,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,
Modified: trunk/reactos/drivers/filesystems/fastfat_new/volume.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat... ============================================================================== --- trunk/reactos/drivers/filesystems/fastfat_new/volume.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat_new/volume.c [iso-8859-1] Wed Oct 14 17:59:14 2009 @@ -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