[FASTFAT] Fix size checking in VfatGetFileNameInformation()
[reactos.git] / drivers / filesystems / ntfs / blockdev.c
index fd18c41..6c90131 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-/* GLOBALS *****************************************************************/
-
-
 /* 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;
-
-  KeInitializeEvent(&Event,
-                   NotificationEvent,
-                   FALSE);
-
-  Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
-  BlockSize = SectorCount * SectorSize;
-
-  DPRINT("NtfsReadSectors(DeviceObject %p, DiskSector %d, Buffer %p)\n",
-        DeviceObject, DiskSector, Buffer);
-  DPRINT("Offset %I64x BlockSize %ld\n",
-        Offset.QuadPart,
-        BlockSize);
-
-  DPRINT("Building synchronous FSD Request...\n");
-  Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
-                                    DeviceObject,
-                                    Buffer,
-                                    BlockSize,
-                                    &Offset,
-                                    &Event,
-                                    &IoStatus);
-  if (Irp == NULL)
+    PIO_STACK_LOCATION Stack;
+    IO_STATUS_BLOCK IoStatus;
+    LARGE_INTEGER Offset;
+    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);
+
+    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;
+    }
+
+    Offset.QuadPart = RealReadOffset;
+
+    DPRINT("Building synchronous FSD Request...\n");
+    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+                                       DeviceObject,
+                                       ReadBuffer,
+                                       RealLength,
+                                       &Offset,
+                                       &Event,
+                                       &IoStatus);
+    if (Irp == NULL)
     {
-      DPRINT("IoBuildSynchronousFsdRequest failed\n");
-      return STATUS_INSUFFICIENT_RESOURCES;
+        DPRINT("IoBuildSynchronousFsdRequest failed\n");
+
+        if (AllocatedBuffer)
+        {
+            ExFreePoolWithTag(ReadBuffer, TAG_NTFS);
+        }
+
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-  if (Override)
+    if (Override)
     {
-      Stack = IoGetNextIrpStackLocation(Irp);
-      Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
+        Stack = IoGetNextIrpStackLocation(Irp);
+        Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
     }
 
-  DPRINT("Calling IO Driver... with irp %p\n", Irp);
-  Status = IoCallDriver(DeviceObject, Irp);
+    DPRINT("Calling IO Driver... with irp %p\n", Irp);
+    Status = IoCallDriver(DeviceObject, Irp);
 
-  DPRINT("Waiting for IO Operation for %p\n", Irp);
-  if (Status == STATUS_PENDING)
+    DPRINT("Waiting for IO Operation for %p\n", Irp);
+    if (Status == STATUS_PENDING)
     {
-      DPRINT("Operation pending\n");
-      KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
-      DPRINT("Getting IO Status... for %p\n", Irp);
-      Status = IoStatus.Status;
+        DPRINT("Operation pending\n");
+        KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+        DPRINT("Getting IO Status... for %p\n", Irp);
+        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 Status;
+    return NtfsReadDisk(DeviceObject, Offset, BlockSize, SectorSize, Buffer, Override);
 }
 
 
 NTSTATUS
 NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
-                   IN ULONG ControlCode,
-                   IN PVOID InputBuffer,
-                   IN ULONG InputBufferSize,
-                   IN OUT PVOID OutputBuffer,
-                   IN OUT PULONG OutputBufferSize,
-                   IN BOOLEAN Override)
+                    IN ULONG ControlCode,
+                    IN PVOID InputBuffer,
+                    IN ULONG InputBufferSize,
+                    IN OUT PVOID OutputBuffer,
+                    IN OUT PULONG OutputBufferSize,
+                    IN BOOLEAN Override)
 {
-  PIO_STACK_LOCATION Stack;
-  IO_STATUS_BLOCK IoStatus;
-  KEVENT Event;
-  PIRP Irp;
-  NTSTATUS Status;
-
-  KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-  DPRINT("Building device I/O control request ...\n");
-  Irp = IoBuildDeviceIoControlRequest(ControlCode,
-                                     DeviceObject,
-                                     InputBuffer,
-                                     InputBufferSize,
-                                     OutputBuffer,
-                                     (OutputBufferSize) ? *OutputBufferSize : 0,
-                                     FALSE,
-                                     &Event,
-                                     &IoStatus);
-  if (Irp == NULL)
+    PIO_STACK_LOCATION Stack;
+    IO_STATUS_BLOCK IoStatus;
+    KEVENT Event;
+    PIRP Irp;
+    NTSTATUS Status;
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    DPRINT("Building device I/O control request ...\n");
+    Irp = IoBuildDeviceIoControlRequest(ControlCode,
+                                        DeviceObject,
+                                        InputBuffer,
+                                        InputBufferSize,
+                                        OutputBuffer,
+                                        (OutputBufferSize) ? *OutputBufferSize : 0,
+                                        FALSE,
+                                        &Event,
+                                        &IoStatus);
+    if (Irp == NULL)
     {
-      DPRINT("IoBuildDeviceIoControlRequest() failed\n");
-      return STATUS_INSUFFICIENT_RESOURCES;
+        DPRINT("IoBuildDeviceIoControlRequest() failed\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-  if (Override)
+    if (Override)
     {
-      Stack = IoGetNextIrpStackLocation(Irp);
-      Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
+        Stack = IoGetNextIrpStackLocation(Irp);
+        Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
     }
 
-  DPRINT("Calling IO Driver... with irp %p\n", Irp);
-  Status = IoCallDriver(DeviceObject, Irp);
-  if (Status == STATUS_PENDING)
+    DPRINT("Calling IO Driver... with irp %p\n", Irp);
+    Status = IoCallDriver(DeviceObject, Irp);
+    if (Status == STATUS_PENDING)
     {
-      KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
-      Status = IoStatus.Status;
+        KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+        Status = IoStatus.Status;
     }
 
-  if (OutputBufferSize)
+    if (OutputBufferSize)
     {
-      *OutputBufferSize = IoStatus.Information;
+        *OutputBufferSize = IoStatus.Information;
     }
 
-  return Status;
+    return Status;
 }
 
 /* EOF */