[NTFS]
authorPierre Schweitzer <pierre@reactos.org>
Tue, 4 Nov 2014 07:56:20 +0000 (07:56 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Tue, 4 Nov 2014 07:56:20 +0000 (07:56 +0000)
- Move the ROUND_UP & ROUND_DOWN macro definition to header
- Make NtfsReadDisk() sector size aware so that it can properly align read on the disk (and thus prevent them from failing)
- If $ATTRIBUTE_LIST is non resident, then display a message and continue, don't assert on it. This is to be implemented later on.

This fixes directory enumeration on a Windows 7 NTFS volume.

svn path=/trunk/; revision=65240

reactos/drivers/filesystems/ntfs/blockdev.c
reactos/drivers/filesystems/ntfs/mft.c
reactos/drivers/filesystems/ntfs/ntfs.h
reactos/drivers/filesystems/ntfs/rw.c

index 3628bb3..ed1d642 100644 (file)
@@ -36,6 +36,7 @@ NTSTATUS
 NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
              IN LONGLONG StartingOffset,
              IN ULONG Length,
+             IN ULONG SectorSize,
              IN OUT PUCHAR Buffer,
              IN BOOLEAN Override)
 {
@@ -45,20 +46,41 @@ NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
     KEVENT Event;
     PIRP Irp;
     NTSTATUS Status;
+    ULONGLONG RealReadOffset;
+    ULONG RealLength;
+    BOOLEAN AllocatedBuffer = FALSE;
+    PUCHAR ReadBuffer = Buffer;
 
-    DPRINT("NtfsReadDisk(%p, %I64x, %u, %p, %d)\n", DeviceObject, StartingOffset, Length, Buffer, Override);
+    DPRINT("NtfsReadDisk(%p, %I64x, %u, %u, %p, %d)\n", DeviceObject, StartingOffset, Length, SectorSize, Buffer, Override);
 
     KeInitializeEvent(&Event,
                       NotificationEvent,
                       FALSE);
 
-    Offset.QuadPart = StartingOffset;
+    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,
-                                       Buffer,
-                                       Length,
+                                       ReadBuffer,
+                                       RealLength,
                                        &Offset,
                                        &Event,
                                        &IoStatus);
@@ -86,6 +108,12 @@ NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
         Status = IoStatus.Status;
     }
 
+    if (NT_SUCCESS(Status) && AllocatedBuffer)
+    {
+        RtlCopyMemory(Buffer, ReadBuffer + (StartingOffset - RealReadOffset), Length);
+        ExFreePoolWithTag(ReadBuffer, TAG_NTFS);
+    }
+
     DPRINT("NtfsReadDisk() done (Status %x)\n", Status);
 
     return Status;
@@ -105,7 +133,7 @@ NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
     Offset = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
     BlockSize = SectorCount * SectorSize;
 
-    return NtfsReadDisk(DeviceObject, Offset, BlockSize, Buffer, Override);
+    return NtfsReadDisk(DeviceObject, Offset, BlockSize, SectorSize, Buffer, Override);
 }
 
 
index 2b94e22..820cfa4 100644 (file)
@@ -106,37 +106,43 @@ FindAttributeHelper(PDEVICE_EXTENSION Vcb,
             PNTFS_ATTR_RECORD ListAttrRecordEnd;
 
             // Do not handle non-resident yet
-            ASSERT(!(AttrRecord->IsNonResident & 1));
-
-            ListContext = PrepareAttributeContext(AttrRecord);
-
-            ListSize = AttributeDataLength(&ListContext->Record);
-            if(ListSize <= 0xFFFFFFFF)
-                ListBuffer = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS);
-            else
-                ListBuffer = NULL;
-
-            if(!ListBuffer)
+            if (AttrRecord->IsNonResident)
             {
-                DPRINT("Failed to allocate memory: %x\n", (ULONG)ListSize);
+                UNIMPLEMENTED;
                 continue;
             }
+            else
+            {
+                ListContext = PrepareAttributeContext(AttrRecord);
 
-            ListAttrRecord = (PNTFS_ATTR_RECORD)ListBuffer;
-            ListAttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)ListBuffer + ListSize);
+                ListSize = AttributeDataLength(&ListContext->Record);
+                if(ListSize <= 0xFFFFFFFF)
+                    ListBuffer = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS);
+                else
+                    ListBuffer = NULL;
 
-            if (ReadAttribute(Vcb, ListContext, 0, ListBuffer, (ULONG)ListSize) == ListSize)
-            {
-                Context = FindAttributeHelper(Vcb, ListAttrRecord, ListAttrRecordEnd,
-                                              Type, Name, NameLength);
+                if(!ListBuffer)
+                {
+                    DPRINT("Failed to allocate memory: %x\n", (ULONG)ListSize);
+                    continue;
+                }
 
-                ReleaseAttributeContext(ListContext);
-                ExFreePoolWithTag(ListBuffer, TAG_NTFS);
+                ListAttrRecord = (PNTFS_ATTR_RECORD)ListBuffer;
+                ListAttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)ListBuffer + ListSize);
 
-                if (Context != NULL)
+                if (ReadAttribute(Vcb, ListContext, 0, ListBuffer, (ULONG)ListSize) == ListSize)
                 {
-                    DPRINT("Found context = %p\n", Context);
-                    return Context;
+                    Context = FindAttributeHelper(Vcb, ListAttrRecord, ListAttrRecordEnd,
+                                                  Type, Name, NameLength);
+
+                    ReleaseAttributeContext(ListContext);
+                    ExFreePoolWithTag(ListBuffer, TAG_NTFS);
+
+                    if (Context != NULL)
+                    {
+                        DPRINT("Found context = %p\n", Context);
+                        return Context;
+                    }
                 }
             }
         }
@@ -310,6 +316,7 @@ ReadAttribute(PDEVICE_EXTENSION Vcb,
     Status = NtfsReadDisk(Vcb->StorageDevice,
                           DataRunStartLCN * Vcb->NtfsInfo.BytesPerCluster + Offset - CurrentOffset,
                           ReadLength,
+                          Vcb->NtfsInfo.BytesPerSector,
                           (PVOID)Buffer,
                           FALSE);
     if (NT_SUCCESS(Status))
@@ -344,6 +351,7 @@ ReadAttribute(PDEVICE_EXTENSION Vcb,
                 Status = NtfsReadDisk(Vcb->StorageDevice,
                                       DataRunStartLCN * Vcb->NtfsInfo.BytesPerCluster,
                                       ReadLength,
+                                      Vcb->NtfsInfo.BytesPerSector,
                                       (PVOID)Buffer,
                                       FALSE);
                 if (!NT_SUCCESS(Status))
index 22187d6..573b6ca 100644 (file)
@@ -10,6 +10,7 @@
 #define TAG_NTFS 'SFTN'
 
 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
+#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
 
 #define DEVICE_NAME L"\\Ntfs"
 
@@ -456,6 +457,7 @@ NTSTATUS
 NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
              IN LONGLONG StartingOffset,
              IN ULONG Length,
+             IN ULONG SectorSize,
              IN OUT PUCHAR Buffer,
              IN BOOLEAN Override);
 
index fb485df..0ae0a28 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-/* GLOBALS *******************************************************************/
-
-#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
-#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
-
 /* FUNCTIONS ****************************************************************/
 
 /*