[ros-diffs] [fireball] 33476: - 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.

fireball at svn.reactos.org fireball at svn.reactos.org
Mon May 12 18:30:20 CEST 2008


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?rev=33476&r1=33475&r2=33476&view=diff
==============================================================================
--- 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 */



More information about the Ros-diffs mailing list