[FASTFAT] Fix size checking in VfatGetFileNameInformation()
[reactos.git] / drivers / filesystems / ntfs / blockdev.c
index 8558693..6c90131 100644 (file)
 /* FUNCTIONS ****************************************************************/
 
 NTSTATUS
-NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
-                IN ULONG DiskSector,
-                IN ULONG SectorCount,
-                IN ULONG SectorSize,
-                IN OUT PUCHAR Buffer,
-                IN BOOLEAN Override)
+NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
+             IN LONGLONG StartingOffset,
+             IN ULONG Length,
+             IN ULONG SectorSize,
+             IN OUT PUCHAR Buffer,
+             IN BOOLEAN Override)
 {
     PIO_STACK_LOCATION Stack;
     IO_STATUS_BLOCK IoStatus;
     LARGE_INTEGER Offset;
-    ULONG BlockSize;
     KEVENT Event;
     PIRP Irp;
     NTSTATUS Status;
+    ULONGLONG RealReadOffset;
+    ULONG RealLength;
+    BOOLEAN AllocatedBuffer = FALSE;
+    PUCHAR ReadBuffer = Buffer;
+
+    DPRINT("NtfsReadDisk(%p, %I64x, %u, %u, %p, %d)\n", DeviceObject, StartingOffset, Length, SectorSize, Buffer, Override);
 
     KeInitializeEvent(&Event,
                       NotificationEvent,
                       FALSE);
 
-    Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
-    BlockSize = SectorCount * SectorSize;
+    RealReadOffset = (ULONGLONG)StartingOffset;
+    RealLength = Length;
+
+    if ((RealReadOffset % SectorSize) != 0 || (RealLength % SectorSize) != 0)
+    {
+        RealReadOffset = ROUND_DOWN(StartingOffset, SectorSize);
+        RealLength = ROUND_UP(Length, SectorSize);
+
+        ReadBuffer = ExAllocatePoolWithTag(NonPagedPool, RealLength + SectorSize, TAG_NTFS);
+        if (ReadBuffer == NULL)
+        {
+            DPRINT1("Not enough memory!\n");
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+        AllocatedBuffer = TRUE;
+    }
 
-    DPRINT("NtfsReadSectors(DeviceObject %p, DiskSector %d, Buffer %p)\n",
-           DeviceObject, DiskSector, Buffer);
-    DPRINT("Offset %I64x BlockSize %ld\n",
-           Offset.QuadPart,
-           BlockSize);
+    Offset.QuadPart = RealReadOffset;
 
     DPRINT("Building synchronous FSD Request...\n");
     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
                                        DeviceObject,
-                                       Buffer,
-                                       BlockSize,
+                                       ReadBuffer,
+                                       RealLength,
                                        &Offset,
                                        &Event,
                                        &IoStatus);
     if (Irp == NULL)
     {
         DPRINT("IoBuildSynchronousFsdRequest failed\n");
+
+        if (AllocatedBuffer)
+        {
+            ExFreePoolWithTag(ReadBuffer, TAG_NTFS);
+        }
+
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -93,11 +114,38 @@ NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
         Status = IoStatus.Status;
     }
 
-    DPRINT("NtfsReadSectors() done (Status %x)\n", Status);
+    if (AllocatedBuffer)
+    {
+        if (NT_SUCCESS(Status))
+        {
+            RtlCopyMemory(Buffer, ReadBuffer + (StartingOffset - RealReadOffset), Length);
+        }
+
+        ExFreePoolWithTag(ReadBuffer, TAG_NTFS);
+    }
+
+    DPRINT("NtfsReadDisk() done (Status %x)\n", Status);
 
     return Status;
 }
 
+NTSTATUS
+NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
+                IN ULONG DiskSector,
+                IN ULONG SectorCount,
+                IN ULONG SectorSize,
+                IN OUT PUCHAR Buffer,
+                IN BOOLEAN Override)
+{
+    LONGLONG Offset;
+    ULONG BlockSize;
+
+    Offset = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
+    BlockSize = SectorCount * SectorSize;
+
+    return NtfsReadDisk(DeviceObject, Offset, BlockSize, SectorSize, Buffer, Override);
+}
+
 
 NTSTATUS
 NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,