diff --git a/reactos/drivers/filesystems/cdfs/rw.c b/reactos/drivers/filesystems/cdfs/rw.c index c5a216f053e..ef94d22e3ff 100644 --- a/reactos/drivers/filesystems/cdfs/rw.c +++ b/reactos/drivers/filesystems/cdfs/rw.c @@ -55,6 +55,7 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt, { NTSTATUS Status = STATUS_SUCCESS; PFCB Fcb; + ULONG ToRead = Length; DPRINT("CdfsReadFile(ReadOffset %lu Length %lu)\n", ReadOffset, Length); @@ -67,6 +68,9 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt, if (ReadOffset >= Fcb->Entry.DataLengthL) return(STATUS_END_OF_FILE); + + if (ReadOffset + Length > Fcb->Entry.DataLengthL) + ToRead = Fcb->Entry.DataLengthL - ReadOffset; DPRINT("Reading %d bytes at %d\n", Length, ReadOffset); @@ -78,9 +82,6 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt, DPRINT("Using cache\n"); - if (ReadOffset + Length > Fcb->Entry.DataLengthL) - Length = Fcb->Entry.DataLengthL - ReadOffset; - if (FileObject->PrivateCacheMap == NULL) { FileSizes.AllocationSize = Fcb->RFCB.AllocationSize; @@ -101,79 +102,56 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt, FileOffset.QuadPart = (LONGLONG)ReadOffset; CcCopyRead(FileObject, &FileOffset, - Length, + ToRead, TRUE, Buffer, &IoStatus); *LengthRead = IoStatus.Information; - return(IoStatus.Status); - } - - if ((ReadOffset % BLOCKSIZE) != 0 || (Length % BLOCKSIZE) != 0) - { - /* Then we need to do a partial or misaligned read ... */ - PCHAR PageBuf = ExAllocatePool(NonPagedPool, BLOCKSIZE); - PCHAR TargetRead = (PCHAR)Buffer; - ULONG ActualReadOffset, EndOfExtent, ReadLen; - - if (!PageBuf) - { - return STATUS_NO_MEMORY; - } - - ActualReadOffset = ROUND_DOWN(ReadOffset, BLOCKSIZE); - EndOfExtent = ReadOffset + Length; - - while (ActualReadOffset < EndOfExtent) - { - Status = CdfsReadSectors - (DeviceExt->StorageDevice, - Fcb->Entry.ExtentLocationL + (ActualReadOffset / BLOCKSIZE), - 1, - (PVOID)PageBuf, - FALSE); - - if (!NT_SUCCESS(Status)) - break; - - ReadLen = BLOCKSIZE - (ReadOffset - ActualReadOffset); - if (ReadLen > EndOfExtent - ReadOffset) - { - ReadLen = EndOfExtent - ReadOffset; - } - DPRINT("Copying %d bytes.\n", ReadLen); - RtlCopyMemory(TargetRead, PageBuf + (ReadOffset - ActualReadOffset), ReadLen); - - ActualReadOffset += BLOCKSIZE; - TargetRead += ReadLen; - ReadOffset += ReadLen; - } - - ExFreePool(PageBuf); + Status = IoStatus.Status; } else { - if (ReadOffset + Length > ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE)) - Length = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE) - ReadOffset; - - Status = CdfsReadSectors(DeviceExt->StorageDevice, - Fcb->Entry.ExtentLocationL + (ReadOffset / BLOCKSIZE), - Length / BLOCKSIZE, - Buffer, - FALSE); - if (NT_SUCCESS(Status)) + ULONG ActualReadOffset = ROUND_DOWN(ReadOffset, BLOCKSIZE); + ULONG nBlocks = (ROUND_UP(ReadOffset + ToRead, BLOCKSIZE) - ActualReadOffset) / BLOCKSIZE; + PUCHAR PageBuf; + BOOLEAN bFreeBuffer = FALSE; + if ((ReadOffset % BLOCKSIZE) != 0 || (ToRead % BLOCKSIZE) != 0) { - *LengthRead = Length; - if (Length + ReadOffset > Fcb->Entry.DataLengthL) + PageBuf = ExAllocatePool(NonPagedPool, nBlocks * BLOCKSIZE); + if (!PageBuf) { - memset(Buffer + Fcb->Entry.DataLengthL - ReadOffset, - 0, - Length + ReadOffset - Fcb->Entry.DataLengthL); + return STATUS_NO_MEMORY; } + bFreeBuffer = TRUE; } + else + { + PageBuf = Buffer; + } + Status = CdfsReadSectors(DeviceExt->StorageDevice, + Fcb->Entry.ExtentLocationL + (ActualReadOffset / BLOCKSIZE), + nBlocks, + (PVOID)PageBuf, + FALSE); + + if(NT_SUCCESS(Status)) + { + *LengthRead = ToRead; + if(bFreeBuffer) + { + /* Copy what we've got */ + RtlCopyMemory(Buffer, PageBuf + (ReadOffset - ActualReadOffset), ToRead); + } + /* Zero out the rest */ + if(ToRead != Length) + RtlZeroMemory(Buffer + ToRead, Length - ToRead); + } + + if(bFreeBuffer) + ExFreePool(PageBuf); } - + return Status; }