Author: fireball
Date: Thu Nov 20 14:02:36 2008
New Revision: 37488
URL:
http://svn.reactos.org/svn/reactos?rev=37488&view=rev
Log:
- Merge misaligned reads support (35998, 36834 by Art) from arty-newcc branch.
Modified:
trunk/reactos/drivers/filesystems/cdfs/rw.c
Modified: trunk/reactos/drivers/filesystems/cdfs/rw.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/cdfs/r…
==============================================================================
--- trunk/reactos/drivers/filesystems/cdfs/rw.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/cdfs/rw.c [iso-8859-1] Thu Nov 20 14:02:36 2008
@@ -76,14 +76,23 @@
{
LARGE_INTEGER FileOffset;
IO_STATUS_BLOCK IoStatus;
+ CC_FILE_SIZES FileSizes;
if (ReadOffset + Length > Fcb->Entry.DataLengthL)
Length = Fcb->Entry.DataLengthL - ReadOffset;
if (FileObject->PrivateCacheMap == NULL)
{
+ FileSizes.AllocationSize = Fcb->RFCB.AllocationSize;
+ FileSizes.FileSize = Fcb->RFCB.FileSize;
+ FileSizes.ValidDataLength = Fcb->RFCB.ValidDataLength;
+
+ DPRINT("Attach FCB to File: Size %08x%08x\n",
+ Fcb->RFCB.ValidDataLength.HighPart,
+ Fcb->RFCB.ValidDataLength.LowPart);
+
CcInitializeCacheMap(FileObject,
- (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
+ &FileSizes,
FALSE,
&(CdfsGlobalData->CacheMgrCallbacks),
Fcb);
@@ -103,25 +112,65 @@
if ((ReadOffset % BLOCKSIZE) != 0 || (Length % BLOCKSIZE) != 0)
{
- return STATUS_INVALID_PARAMETER;
- }
-
- 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))
- {
- *LengthRead = Length;
- if (Length + ReadOffset > Fcb->Entry.DataLengthL)
- {
- memset(Buffer + Fcb->Entry.DataLengthL - ReadOffset,
- 0,
- Length + ReadOffset - Fcb->Entry.DataLengthL);
+ /* Then we need to do a partial or misaligned read ... */
+ PVOID PageBuf = ExAllocatePool(NonPagedPool, BLOCKSIZE);
+ PCHAR ReadInPage = (PCHAR)PageBuf + (ReadOffset & (BLOCKSIZE - 1));
+ PCHAR TargetRead = (PCHAR)Buffer;
+ ULONG ActualReadOffset, EndOfExtent, ReadLen;
+
+ if (!PageBuf)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ ActualReadOffset = ReadOffset & ~(BLOCKSIZE - 1);
+ EndOfExtent = ReadOffset + Length;
+
+ while (ActualReadOffset < EndOfExtent)
+ {
+ Status = CdfsReadSectors
+ (DeviceExt->StorageDevice,
+ Fcb->Entry.ExtentLocationL + (ActualReadOffset / BLOCKSIZE),
+ 1,
+ PageBuf,
+ FALSE);
+
+ if (!NT_SUCCESS(Status))
+ break;
+
+ ReadLen = BLOCKSIZE - (ActualReadOffset & (BLOCKSIZE - 1));
+ if (ReadLen > EndOfExtent - ActualReadOffset)
+ {
+ ReadLen = EndOfExtent - ActualReadOffset;
+ }
+
+ RtlCopyMemory(TargetRead, ReadInPage, ReadLen);
+
+ ActualReadOffset += ReadLen;
+ TargetRead += ReadLen;
+ }
+
+ ExFreePool(PageBuf);
+ }
+ 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))
+ {
+ *LengthRead = Length;
+ if (Length + ReadOffset > Fcb->Entry.DataLengthL)
+ {
+ memset(Buffer + Fcb->Entry.DataLengthL - ReadOffset,
+ 0,
+ Length + ReadOffset - Fcb->Entry.DataLengthL);
+ }
}
}