Bugfixing... Part 5/X:
- Actually, we don't care about the name in the file index. We don't need it to read the data attribute, it's unnamed. And the returned name was buggy (this still needs work though)
- When we are getting a file record which is a directory, there is NO data attribute. Don't attempt to read it. This prevents failure on directory entry return.

These fixes enable NTFS directory listing in ReactOS!
Even though, more fixes are required. So far, the metadata of the files are kind of broken. Explorer seems to be unable to list files.
This keeps anyway being a major step forward, as this was totally impossible a month ago ;-).

For these willing to see NTFS in action in ReactOS: http://www.heisspiter.net/~Pierre/rostests/NTFS_listing.png

svn path=/trunk/; revision=64800
This commit is contained in:
Pierre Schweitzer 2014-10-18 12:18:37 +00:00
parent 4a58f77497
commit e2a846bea8

View file

@ -180,7 +180,7 @@ FindAttribute(PDEVICE_EXTENSION Vcb,
PNTFS_ATTR_RECORD AttrRecord; PNTFS_ATTR_RECORD AttrRecord;
PNTFS_ATTR_RECORD AttrRecordEnd; PNTFS_ATTR_RECORD AttrRecordEnd;
DPRINT1("NtfsFindAttribute(%p, %p, %u, %S, %u, %p)\n", Vcb, MftRecord, Type, Name, NameLength, AttrCtx); DPRINT1("FindAttribute(%p, %p, %u, %S, %u, %p)\n", Vcb, MftRecord, Type, Name, NameLength, AttrCtx);
AttrRecord = (PNTFS_ATTR_RECORD)((PCHAR)MftRecord + MftRecord->AttributeOffset); AttrRecord = (PNTFS_ATTR_RECORD)((PCHAR)MftRecord + MftRecord->AttributeOffset);
AttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)MftRecord + Vcb->NtfsInfo.BytesPerFileRecord); AttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)MftRecord + Vcb->NtfsInfo.BytesPerFileRecord);
@ -488,8 +488,7 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
PUNICODE_STRING FileName, PUNICODE_STRING FileName,
PULONG FirstEntry, PULONG FirstEntry,
BOOLEAN DirSearch, BOOLEAN DirSearch,
ULONGLONG *OutMFTIndex, ULONGLONG *OutMFTIndex)
PWSTR OutName)
{ {
PFILE_RECORD_HEADER MftRecord; PFILE_RECORD_HEADER MftRecord;
//ULONG Magic; //ULONG Magic;
@ -508,7 +507,7 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
NTSTATUS Status; NTSTATUS Status;
ULONG CurrentEntry = 0; ULONG CurrentEntry = 0;
DPRINT1("NtfsFindMftRecord(%p, %I64d, %wZ, %p, %u, %p, %p)\n", Vcb, MFTIndex, FileName, FirstEntry, DirSearch, OutMFTIndex, OutName); DPRINT1("NtfsFindMftRecord(%p, %I64d, %wZ, %p, %u, %p)\n", Vcb, MFTIndex, FileName, FirstEntry, DirSearch, OutMFTIndex);
MftRecord = ExAllocatePoolWithTag(NonPagedPool, MftRecord = ExAllocatePoolWithTag(NonPagedPool,
Vcb->NtfsInfo.BytesPerFileRecord, Vcb->NtfsInfo.BytesPerFileRecord,
@ -554,8 +553,6 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
{ {
*OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK); *OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK);
*FirstEntry = CurrentEntry; *FirstEntry = CurrentEntry;
RtlCopyMemory(OutName, IndexEntry->FileName.Name, IndexEntry->FileName.NameLength);
OutName[IndexEntry->FileName.NameLength / sizeof(WCHAR)] = UNICODE_NULL;
ExFreePoolWithTag(IndexRecord, TAG_NTFS); ExFreePoolWithTag(IndexRecord, TAG_NTFS);
ExFreePoolWithTag(MftRecord, TAG_NTFS); ExFreePoolWithTag(MftRecord, TAG_NTFS);
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -648,8 +645,6 @@ NtfsFindMftRecord(PDEVICE_EXTENSION Vcb,
DPRINT("File found\n"); DPRINT("File found\n");
*OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK); *OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK);
*FirstEntry = CurrentEntry; *FirstEntry = CurrentEntry;
RtlCopyMemory(OutName, IndexEntry->FileName.Name, IndexEntry->FileName.NameLength);
OutName[IndexEntry->FileName.NameLength / sizeof(WCHAR)] = UNICODE_NULL;
ExFreePoolWithTag(BitmapData, TAG_NTFS); ExFreePoolWithTag(BitmapData, TAG_NTFS);
ExFreePoolWithTag(IndexRecord, TAG_NTFS); ExFreePoolWithTag(IndexRecord, TAG_NTFS);
ExFreePoolWithTag(MftRecord, TAG_NTFS); ExFreePoolWithTag(MftRecord, TAG_NTFS);
@ -689,8 +684,7 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
{ {
UNICODE_STRING Current, Remaining; UNICODE_STRING Current, Remaining;
NTSTATUS Status; NTSTATUS Status;
WCHAR FoundName[MAX_PATH + 1]; ULONG FirstEntry = 0;
ULONG FirstEntry = 0, Length;
DPRINT1("NtfsLookupFileAt(%p, %wZ, %p, %p, %I64x)\n", Vcb, PathName, FileRecord, DataContext, CurrentMFTIndex); DPRINT1("NtfsLookupFileAt(%p, %wZ, %p, %p, %I64x)\n", Vcb, PathName, FileRecord, DataContext, CurrentMFTIndex);
@ -700,7 +694,7 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
{ {
DPRINT1("Current: %wZ\n", &Current); DPRINT1("Current: %wZ\n", &Current);
Status = NtfsFindMftRecord(Vcb, CurrentMFTIndex, &Current, &FirstEntry, FALSE, &CurrentMFTIndex, FoundName); Status = NtfsFindMftRecord(Vcb, CurrentMFTIndex, &Current, &FirstEntry, FALSE, &CurrentMFTIndex);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return Status;
@ -727,14 +721,19 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
return Status; return Status;
} }
Length = wcslen(FoundName) * sizeof(WCHAR); if (!((*FileRecord)->Flags & FRH_DIRECTORY))
Status = FindAttribute(Vcb, *FileRecord, AttributeData, FoundName, Length, DataContext);
if (!NT_SUCCESS(Status))
{ {
DPRINT("NtfsLookupFileAt: Can't find data attribute\n"); Status = FindAttribute(Vcb, *FileRecord, AttributeData, L"", 0, DataContext);
ExFreePoolWithTag(*FileRecord, TAG_NTFS); if (!NT_SUCCESS(Status))
return Status; {
DPRINT("NtfsLookupFileAt: Can't find data attribute\n");
ExFreePoolWithTag(*FileRecord, TAG_NTFS);
return Status;
}
}
else
{
*DataContext = NULL;
} }
*MFTIndex = CurrentMFTIndex; *MFTIndex = CurrentMFTIndex;
@ -762,12 +761,10 @@ NtfsFindFileAt(PDEVICE_EXTENSION Vcb,
ULONGLONG CurrentMFTIndex) ULONGLONG CurrentMFTIndex)
{ {
NTSTATUS Status; NTSTATUS Status;
WCHAR FoundName[MAX_PATH + 1];
ULONG Length;
DPRINT1("NtfsFindFileAt(%p, %wZ, %p, %p, %p, %p, %I64x)\n", Vcb, SearchPattern, FirstEntry, FileRecord, DataContext, MFTIndex, CurrentMFTIndex); DPRINT1("NtfsFindFileAt(%p, %wZ, %p, %p, %p, %p, %I64x)\n", Vcb, SearchPattern, FirstEntry, FileRecord, DataContext, MFTIndex, CurrentMFTIndex);
Status = NtfsFindMftRecord(Vcb, CurrentMFTIndex, SearchPattern, FirstEntry, TRUE, &CurrentMFTIndex, FoundName); Status = NtfsFindMftRecord(Vcb, CurrentMFTIndex, SearchPattern, FirstEntry, TRUE, &CurrentMFTIndex);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return Status;
@ -788,14 +785,19 @@ NtfsFindFileAt(PDEVICE_EXTENSION Vcb,
return Status; return Status;
} }
Length = wcslen(FoundName) * sizeof(WCHAR); if (!((*FileRecord)->Flags & FRH_DIRECTORY))
Status = FindAttribute(Vcb, *FileRecord, AttributeData, FoundName, Length, DataContext);
if (!NT_SUCCESS(Status))
{ {
DPRINT("NtfsFindFileAt: Can't find data attribute\n"); Status = FindAttribute(Vcb, *FileRecord, AttributeData, L"", 0, DataContext);
ExFreePoolWithTag(*FileRecord, TAG_NTFS); if (!NT_SUCCESS(Status))
return Status; {
DPRINT("NtfsFindFileAt: Can't find data attribute\n");
ExFreePoolWithTag(*FileRecord, TAG_NTFS);
return Status;
}
}
else
{
*DataContext = NULL;
} }
*MFTIndex = CurrentMFTIndex; *MFTIndex = CurrentMFTIndex;