[NTFS]
authorPierre Schweitzer <pierre@reactos.org>
Fri, 17 Oct 2014 22:17:59 +0000 (22:17 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Fri, 17 Oct 2014 22:17:59 +0000 (22:17 +0000)
Bugfixing... Part 4/X:
- Fix a nasty bug in NtfsLookupFileAt() (how did it work before?). The name parsing was wrong (no progress was being made) and thus was leading to an infinite loop in directory browsing.
- Fix a lovely bug coming from a non-documented feature in NTFS. To properly read the MFT index, you've to apply a mask. Do this to properly handles MFT record. This fixes returned MFT index which allows resuse.
- Do not allow returning MFT records < 0x10 for now. Not sure whether it should be allowed, but so far, these are MFT special records, so let's forget about it. IIRC, they are available on Windows. But trying to chase another bug for the moment.

This does not fix yet directory enumeration.

svn path=/trunk/; revision=64793

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

index 5ee4bd3..1ad70f1 100644 (file)
@@ -548,9 +548,11 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
         while (IndexEntry < IndexEntryEnd &&
                !(IndexEntry->Flags & NTFS_INDEX_ENTRY_END))
         {
-            if (CurrentEntry >= *FirstEntry && CompareFileName(FileName, IndexEntry, DirSearch))
+            if ((IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK) > 0x10 &&
+                CurrentEntry >= *FirstEntry &&
+                CompareFileName(FileName, IndexEntry, DirSearch))
             {
-                *OutMFTIndex = IndexEntry->Data.Directory.IndexedFile;
+                *OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK);
                 *FirstEntry = CurrentEntry;
                 RtlCopyMemory(OutName, IndexEntry->FileName.Name, IndexEntry->FileName.NameLength);
                 OutName[IndexEntry->FileName.NameLength / sizeof(WCHAR)] = UNICODE_NULL;
@@ -639,10 +641,12 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
                 while (IndexEntry < IndexEntryEnd &&
                        !(IndexEntry->Flags & NTFS_INDEX_ENTRY_END))
                 {
-                    if (CurrentEntry >= *FirstEntry && CompareFileName(FileName, IndexEntry, DirSearch))
+                    if ((IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK) > 0x10 &&
+                        CurrentEntry >= *FirstEntry &&
+                        CompareFileName(FileName, IndexEntry, DirSearch))
                     {
                         DPRINT("File found\n");
-                        *OutMFTIndex = IndexEntry->Data.Directory.IndexedFile;
+                        *OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK);
                         *FirstEntry = CurrentEntry;
                         RtlCopyMemory(OutName, IndexEntry->FileName.Name, IndexEntry->FileName.NameLength);
                         OutName[IndexEntry->FileName.NameLength / sizeof(WCHAR)] = UNICODE_NULL;
@@ -694,7 +698,7 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
 
     while (Current.Length != 0)
     {
-        DPRINT1("Lookup: %wZ\n", &Current);
+        DPRINT1("Current: %wZ\n", &Current);
 
         Status = NtfsFindMftRecord(Vcb, CurrentMFTIndex, &Current, &FirstEntry, FALSE, &CurrentMFTIndex, FoundName);
         if (!NT_SUCCESS(Status))
@@ -702,7 +706,10 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
             return Status;
         }
 
-        FsRtlDissectName(*PathName, &Current, &Remaining);
+        if (Remaining.Length == 0)
+            return STATUS_OBJECT_PATH_NOT_FOUND;
+
+        FsRtlDissectName(Current, &Current, &Remaining);
     }
 
     *FileRecord = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerFileRecord, TAG_NTFS);
index 212ec79..eb75a8c 100644 (file)
@@ -169,6 +169,8 @@ typedef enum
 #define NTFS_FILE_UPCASE            10
 #define NTFS_FILE_EXTEND            11
 
+#define NTFS_MFT_MASK 0x0000FFFFFFFFFFFFULL
+
 #define COLLATION_BINARY              0x00
 #define COLLATION_FILE_NAME           0x01
 #define COLLATION_UNICODE_STRING      0x02