From 60d3d2c399b7b4637d92afea70bf856f5e5f2f6a Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Fri, 17 Oct 2014 22:17:59 +0000 Subject: [PATCH] [NTFS] 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 | 19 +++++++++++++------ reactos/drivers/filesystems/ntfs/ntfs.h | 2 ++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/reactos/drivers/filesystems/ntfs/mft.c b/reactos/drivers/filesystems/ntfs/mft.c index 5ee4bd370e2..1ad70f17ac2 100644 --- a/reactos/drivers/filesystems/ntfs/mft.c +++ b/reactos/drivers/filesystems/ntfs/mft.c @@ -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); diff --git a/reactos/drivers/filesystems/ntfs/ntfs.h b/reactos/drivers/filesystems/ntfs/ntfs.h index 212ec79088c..eb75a8ca324 100644 --- a/reactos/drivers/filesystems/ntfs/ntfs.h +++ b/reactos/drivers/filesystems/ntfs/ntfs.h @@ -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 -- 2.17.1