From 9ef3f7c1a2c7371db74d3e5c4efaf991e7b0e00b Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 2 Oct 2009 10:49:57 +0000 Subject: [PATCH 1/1] [fastfat_new] - Implement querying standard information (important for getting correct file size). - Substitute CcMap/copy/Unpin by CcCopyRead in FatReadBlocks. - Take offset into account (seek) in file read operation. Fixes always reading files from the beginning. svn path=/trunk/; revision=43252 --- .../drivers/filesystems/fastfat_new/finfo.c | 86 ++++++++++++++++++- .../drivers/filesystems/fastfat_new/fullfat.c | 10 ++- reactos/drivers/filesystems/fastfat_new/rw.c | 4 + 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/reactos/drivers/filesystems/fastfat_new/finfo.c b/reactos/drivers/filesystems/fastfat_new/finfo.c index 54480e61052..1183d722d6d 100644 --- a/reactos/drivers/filesystems/fastfat_new/finfo.c +++ b/reactos/drivers/filesystems/fastfat_new/finfo.c @@ -13,6 +13,49 @@ /* FUNCTIONS ****************************************************************/ +VOID +NTAPI +FatiQueryStandardInformation(IN PFAT_IRP_CONTEXT IrpContext, + IN PFCB Fcb, + IN PFILE_OBJECT FileObject, + IN OUT PFILE_STANDARD_INFORMATION Buffer, + IN OUT PLONG Length) +{ + /* Zero the buffer */ + RtlZeroMemory(Buffer, sizeof(FILE_STANDARD_INFORMATION)); + + /* Deduct the written length */ + *Length -= sizeof(FILE_STANDARD_INFORMATION); + + Buffer->NumberOfLinks = 1; + Buffer->DeletePending = FALSE; // FIXME + + /* Check if it's a dir or a file */ + if (FatNodeType(Fcb) == FAT_NTC_FCB) + { + Buffer->Directory = FALSE; + + Buffer->EndOfFile.LowPart = Fcb->FatHandle->Filesize; + Buffer->AllocationSize = Buffer->EndOfFile; + DPRINT1("Filesize %d, chain length %d\n", Fcb->FatHandle->Filesize, Fcb->FatHandle->iChainLength); + } + else + { + Buffer->Directory = TRUE; + } +} + +VOID +NTAPI +FatiQueryInternalInformation(IN PFAT_IRP_CONTEXT IrpContext, + IN PFCB Fcb, + IN PFILE_OBJECT FileObject, + IN OUT PFILE_INTERNAL_INFORMATION Buffer, + IN OUT PLONG Length) +{ + UNIMPLEMENTED; +} + NTSTATUS NTAPI FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, @@ -25,6 +68,9 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, PVCB Vcb; PFCB Fcb; PCCB Ccb; + LONG Length; + PVOID Buffer; + NTSTATUS Status = STATUS_SUCCESS; /* Get IRP stack location */ IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -32,19 +78,51 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, /* Get the file object */ FileObject = IrpSp->FileObject; + /* Copy variables to something with shorter names */ InfoClass = IrpSp->Parameters.QueryFile.FileInformationClass; + Length = IrpSp->Parameters.QueryFile.Length; + Buffer = Irp->AssociatedIrp.SystemBuffer; - DPRINT1("FatCommonQueryInformation\n", 0); + DPRINT1("FatiQueryInformation\n", 0); DPRINT1("\tIrp = %08lx\n", Irp); - DPRINT1("\tLength = %08lx\n", IrpSp->Parameters.QueryFile.Length); + DPRINT1("\tLength = %08lx\n", Length); DPRINT1("\tFileInformationClass = %08lx\n", InfoClass); - DPRINT1("\tBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer); + DPRINT1("\tBuffer = %08lx\n", Buffer); FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb); DPRINT1("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType); - return STATUS_SUCCESS; + // TODO: Acquire FCB locks + + switch (InfoClass) + { + case FileStandardInformation: + FatiQueryStandardInformation(IrpContext, Fcb, FileObject, Buffer, &Length); + break; + case FileInternalInformation: + FatiQueryInternalInformation(IrpContext, Fcb, FileObject, Buffer, &Length); + break; + default: + DPRINT1("Unimplemented information class %d requested\n", InfoClass); + Status = STATUS_INVALID_PARAMETER; + } + + /* Check for buffer overflow */ + if (Length < 0) + { + Status = STATUS_BUFFER_OVERFLOW; + Length = 0; + } + + /* Set IoStatus.Information to amount of filled bytes */ + Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length; + + // TODO: Release FCB locks + + /* Complete request and return status */ + FatCompleteRequest(IrpContext, Irp, Status); + return Status; } NTSTATUS diff --git a/reactos/drivers/filesystems/fastfat_new/fullfat.c b/reactos/drivers/filesystems/fastfat_new/fullfat.c index fdbd2a6845c..bb0947aad66 100644 --- a/reactos/drivers/filesystems/fastfat_new/fullfat.c +++ b/reactos/drivers/filesystems/fastfat_new/fullfat.c @@ -41,16 +41,17 @@ FF_T_SINT32 FatReadBlocks(FF_T_UINT8 *DestBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Count, void *pParam) { LARGE_INTEGER Offset; - PVOID Buffer; + //PVOID Buffer; PVCB Vcb = (PVCB)pParam; - PBCB Bcb; + //PBCB Bcb; ULONG SectorSize = 512; // FIXME: hardcoding 512 is bad + IO_STATUS_BLOCK IoSb; DPRINT("FatReadBlocks %p %d %d %p\n", DestBuffer, SectorAddress, Count, pParam); /* Calculate the offset */ Offset.QuadPart = Int32x32To64(SectorAddress, SectorSize); - +#if 0 if (!CcMapData(Vcb->StreamFileObject, &Offset, Count * SectorSize, @@ -68,6 +69,9 @@ FatReadBlocks(FF_T_UINT8 *DestBuffer, FF_T_UINT32 SectorAddress, FF_T_UINT32 Cou /* Unpin unneeded data */ CcUnpinData(Bcb); +#else + CcCopyRead(Vcb->StreamFileObject, &Offset, Count * SectorSize, TRUE, DestBuffer, &IoSb); +#endif /* Return amount of read data in sectors */ return Count; diff --git a/reactos/drivers/filesystems/fastfat_new/rw.c b/reactos/drivers/filesystems/fastfat_new/rw.c index 3d54129eda8..10aa8f9b509 100644 --- a/reactos/drivers/filesystems/fastfat_new/rw.c +++ b/reactos/drivers/filesystems/fastfat_new/rw.c @@ -54,6 +54,10 @@ FatiRead(PFAT_IRP_CONTEXT IrpContext) Buffer = FatMapUserBuffer(IrpContext->Irp); DPRINT1("Normal cached read, buffer %p\n"); + /* Set offset */ + FF_Seek(Fcb->FatHandle, ByteOffset.LowPart, FF_SEEK_SET); + + /* Read */ BytesRead = FF_Read(Fcb->FatHandle, NumberOfBytes, 1, Buffer); DPRINT1("Read %d bytes\n", BytesRead); -- 2.17.1