Author: fireball
Date: Mon May 12 11:30:20 2008
New Revision: 33476
URL:
http://svn.reactos.org/svn/reactos?rev=33476&view=rev
Log:
- Factor out device reading code into a separate function.
- Fix a bug which led to reading a wrong sector in case of DeltaEnd != 0 operation.
Modified:
branches/nocc/ntoskrnl/cache/copysup.c
Modified: branches/nocc/ntoskrnl/cache/copysup.c
URL:
http://svn.reactos.org/svn/reactos/branches/nocc/ntoskrnl/cache/copysup.c?r…
==============================================================================
--- branches/nocc/ntoskrnl/cache/copysup.c [iso-8859-1] (original)
+++ branches/nocc/ntoskrnl/cache/copysup.c [iso-8859-1] Mon May 12 11:30:20 2008
@@ -26,6 +26,45 @@
/* FUNCTIONS ******************************************************************/
+NTSTATUS
+NTAPI
+DoDeviceRead(PFILE_OBJECT FileObject,
+ LARGE_INTEGER SectorBase,
+ PCHAR SystemBuffer,
+ ULONG AlignSize,
+ ULONG *LengthRead)
+{
+ IO_STATUS_BLOCK IoStatusBlock = {{0}};
+ NTSTATUS Status;
+ KEVENT Event;
+ PMDL Mdl;
+
+ /* Create an MDL for the transfer */
+ Mdl = IoAllocateMdl(SystemBuffer, AlignSize, TRUE, FALSE, NULL);
+ MmBuildMdlForNonPagedPool(Mdl),
+ Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
+
+ /* Setup the event */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ /* Read the page */
+ Status = IoPageRead(FileObject, Mdl, &SectorBase, &Event,
&IoStatusBlock);
+ if (Status == STATUS_PENDING)
+ {
+ /* Do the wait */
+ KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ /* Free the MDL */
+ IoFreeMdl(Mdl);
+
+ /* Save how much we read, if needed */
+ if (LengthRead) *LengthRead = IoStatusBlock.Information;
+
+ return Status;
+}
+
BOOLEAN
NTAPI
CcCopyRead(IN PFILE_OBJECT FileObject,
@@ -38,10 +77,8 @@
NTSTATUS Status;
ULONG AlignBase, AlignSize, DeltaBase;
LARGE_INTEGER SectorBase;
- IO_STATUS_BLOCK IoStatusBlock = {{0}};
- KEVENT Event;
PCHAR SystemBuffer;
- PMDL Mdl;
+ ULONG LengthRead;
BOOLEAN DirectRead = FALSE;
DPRINT("CcCopyRead(FileObject 0x%p, FileOffset %I64x, "
"Length %lx, Wait %d, Buffer 0x%p, IoStatus 0x%p)\n",
@@ -81,22 +118,9 @@
DeltaBase = 0;
}
- /* Create an MDL for the transfer */
- Mdl = IoAllocateMdl(SystemBuffer, AlignSize, TRUE, FALSE, NULL);
- MmBuildMdlForNonPagedPool(Mdl),
- Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
-
- /* Setup the event */
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
- /* Read the page */
- Status = IoPageRead(FileObject, Mdl, &SectorBase, &Event,
&IoStatusBlock);
- if (Status == STATUS_PENDING)
- {
- /* Do the wait */
- KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
- Status = IoStatusBlock.Status;
- }
+ /* Do actual read from the device */
+ Status = DoDeviceRead(FileObject, SectorBase, SystemBuffer, AlignSize,
&LengthRead);
+
if (!NT_SUCCESS(Status)) DPRINT1("Status: %lx\n", Status);
ASSERT(NT_SUCCESS(Status));
@@ -110,14 +134,11 @@
ExFreePool(SystemBuffer);
}
- /* Free the MDL */
- IoFreeMdl(Mdl);
-
/* Check if we read less than the caller wanted */
- if (IoStatusBlock.Information < Length)
+ if (LengthRead < Length)
{
/* Only then do we write the real size */
- IoStatus->Information = IoStatusBlock.Information;
+ IoStatus->Information = LengthRead;
}
else
{
@@ -142,7 +163,7 @@
UNIMPLEMENTED;
while (TRUE);
}
-
+
BOOLEAN
NTAPI
CcCopyWrite(IN PFILE_OBJECT FileObject,
@@ -157,7 +178,7 @@
IO_STATUS_BLOCK IoStatusBlock;
KEVENT Event;
PCHAR SystemBuffer;
- PMDL Mdl, ReadMdl;
+ PMDL Mdl;
BOOLEAN DirectWrite = FALSE;
DPRINT("CcCopyWrite(FileObject 0x%p, FileOffset %I64x, "
"Length %lx, Wait %d, Buffer 0x%p)\n",
@@ -242,63 +263,28 @@
//
if (DeltaBase)
{
- /* Create an MDL for the read transfer */
- ReadMdl = IoAllocateMdl(SystemBuffer, PAGE_SIZE, TRUE, FALSE, NULL);
- MmBuildMdlForNonPagedPool(ReadMdl),
- ReadMdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
-
/* We have an offset from a page boundary, so we need to do a read */
- ReadSector = SectorBase;
- Status = IoPageRead(FileObject,
- ReadMdl,
- &ReadSector,
- &Event,
- &IoStatusBlock);
- if (Status == STATUS_PENDING)
- {
- /* Do the wait */
- KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
- Status = IoStatusBlock.Status;
- }
+ Status = DoDeviceRead(FileObject, SectorBase, SystemBuffer,
+ PAGE_SIZE, NULL);
/* This shouldn't fail */
ASSERT(NT_SUCCESS(Status));
-
- /* Free the MDL */
- IoFreeMdl(ReadMdl);
}
/* Now check if we read up to a page boundary, or have an offset */
if ((DeltaEnd))// && (Length > PAGE_SIZE))
{
- /* Create an MDL for the read transfer */
- ReadMdl = IoAllocateMdl(SystemBuffer + ROUND_DOWN(Length, PAGE_SIZE),
- PAGE_SIZE,
- TRUE,
- FALSE,
- NULL);
- MmBuildMdlForNonPagedPool(ReadMdl),
- ReadMdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
-
/* We have an offset from a page boundary, so we need to do a read */
+ ReadSector = SectorBase;
ReadSector.QuadPart += ROUND_DOWN(Length, PAGE_SIZE);
- Status = IoPageRead(FileObject,
- ReadMdl,
- &SectorBase,
- &Event,
- &IoStatusBlock);
- if (Status == STATUS_PENDING)
- {
- /* Do the wait */
- KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
- Status = IoStatusBlock.Status;
- }
+ Status = DoDeviceRead(FileObject,
+ ReadSector,
+ SystemBuffer + ROUND_DOWN(Length, PAGE_SIZE),
+ PAGE_SIZE,
+ NULL);
/* This shouldn't fail */
ASSERT(NT_SUCCESS(Status));
-
- /* Free the MDL */
- IoFreeMdl(ReadMdl);
}
/* Okay, now we have the original data, write our modified data on top */