From df3a6889ba9dcf245e10a7e2499e42c27f236708 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 8 Oct 2014 19:12:48 +0000 Subject: [PATCH] [NTFS] - Remove magic value usage in NtfsDumpFileAttributes() - Implement GetFileNameFromRecord() which returns the $FILE_NAME attribute from a FILE record - On record lookup, also return the MFT index of the found record - Finally implement NtfsMakeFCBFromDirEntry() which allows creating a FCB from a dir entry. It is still incomplete though, it doesn't copy any data yet from the entry svn path=/trunk/; revision=64610 --- reactos/drivers/filesystems/ntfs/attrib.c | 20 ++++++- reactos/drivers/filesystems/ntfs/fcb.c | 71 +++++++++++------------ reactos/drivers/filesystems/ntfs/mft.c | 8 ++- reactos/drivers/filesystems/ntfs/ntfs.h | 6 +- 4 files changed, 65 insertions(+), 40 deletions(-) diff --git a/reactos/drivers/filesystems/ntfs/attrib.c b/reactos/drivers/filesystems/ntfs/attrib.c index 572f6aadffa..aa525475015 100644 --- a/reactos/drivers/filesystems/ntfs/attrib.c +++ b/reactos/drivers/filesystems/ntfs/attrib.c @@ -278,7 +278,7 @@ NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord) Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset); while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) && - Attribute->Type != (ATTRIBUTE_TYPE)-1) + Attribute->Type != AttributeEnd) { NtfsDumpAttribute(Attribute); @@ -286,4 +286,22 @@ NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord) } } +PFILENAME_ATTRIBUTE +GetFileNameFromRecord(PFILE_RECORD_HEADER FileRecord) +{ + PNTFS_ATTR_RECORD Attribute; + + Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset); + while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) && + Attribute->Type != AttributeEnd) + { + if (Attribute->Type == AttributeFileName) + return (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset); + + Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length); + } + + return NULL; +} + /* EOF */ diff --git a/reactos/drivers/filesystems/ntfs/fcb.c b/reactos/drivers/filesystems/ntfs/fcb.c index 0c3a6ae807d..f0235354bf4 100644 --- a/reactos/drivers/filesystems/ntfs/fcb.c +++ b/reactos/drivers/filesystems/ntfs/fcb.c @@ -354,57 +354,53 @@ NtfsGetDirEntryName(PDEVICE_EXTENSION DeviceExt, NTSTATUS NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb, PNTFS_FCB DirectoryFCB, - PWSTR Name, + PUNICODE_STRING Name, PFILE_RECORD_HEADER Record, + ULONGLONG MFTIndex, PNTFS_FCB * fileFCB) { -#if 0 - WCHAR pathName[MAX_PATH]; - PFCB rcFCB; - ULONG Size; + WCHAR pathName[MAX_PATH]; + PFILENAME_ATTRIBUTE FileName; + PNTFS_FCB rcFCB; - if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) + - sizeof(WCHAR) + wcslen (Name) > MAX_PATH) + DPRINT1("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p)\n", Vcb, DirectoryFCB, Name, Record, fileFCB); + + FileName = GetFileNameFromRecord(Record); + if (!FileName) { - return(STATUS_OBJECT_NAME_INVALID); + return STATUS_OBJECT_NAME_NOT_FOUND; // Not sure that's the best here } - wcscpy(pathName, DirectoryFCB->PathName); - if (!NtfsFCBIsRoot(DirectoryFCB)) + if (Name->Buffer[0] != 0 && wcslen(DirectoryFCB->PathName) + + sizeof(WCHAR) + Name->Length / sizeof(WCHAR) > MAX_PATH) { - wcscat(pathName, L"\\"); + return STATUS_OBJECT_NAME_INVALID; } - if (Name[0] != 0) + wcscpy(pathName, DirectoryFCB->PathName); + if (!NtfsFCBIsRoot(DirectoryFCB)) { - wcscat(pathName, Name); + wcscat(pathName, L"\\"); } - else - { - WCHAR entryName[MAX_PATH]; + wcscat(pathName, Name->Buffer); - NtfsGetDirEntryName(Vcb, Record, entryName); - wcscat(pathName, entryName); + rcFCB = NtfsCreateFCB(pathName, Vcb); + if (!rcFCB) + { + return STATUS_INSUFFICIENT_RESOURCES; } - rcFCB = NtfsCreateFCB(pathName, Vcb); - memcpy(&rcFCB->Entry, Record, sizeof(DIR_RECORD)); + rcFCB->RFCB.FileSize.QuadPart = FileName->DataSize; + rcFCB->RFCB.ValidDataLength.QuadPart = FileName->DataSize; + rcFCB->RFCB.AllocationSize.QuadPart = FileName->AllocatedSize; - Size = rcFCB->Entry.DataLengthL; + NtfsFCBInitializeCache(Vcb, rcFCB); + rcFCB->RefCount = 1; + rcFCB->MFTIndex = MFTIndex; + NtfsAddFCBToTable(Vcb, rcFCB); + *fileFCB = rcFCB; - rcFCB->RFCB.FileSize.QuadPart = Size; - rcFCB->RFCB.ValidDataLength.QuadPart = Size; - rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, BLOCKSIZE); -// DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart); - NtfsFCBInitializeCache(Vcb, rcFCB); - rcFCB->RefCount++; - NtfsAddFCBToTable(Vcb, rcFCB); - *fileFCB = rcFCB; - - return(STATUS_SUCCESS); -#else - return STATUS_NOT_IMPLEMENTED; -#endif + return STATUS_SUCCESS; } @@ -460,18 +456,21 @@ NtfsDirFindFile(PNTFS_VCB Vcb, UNICODE_STRING File; PFILE_RECORD_HEADER FileRecord; PNTFS_ATTR_CONTEXT DataContext; + ULONGLONG MFTIndex; + + DPRINT1("NtfsDirFindFile(%p, %p, %S, %p)\n", Vcb, DirectoryFcb, FileToFind, FoundFCB); *FoundFCB = NULL; RtlInitUnicodeString(&File, FileToFind); CurrentDir = DirectoryFcb->MFTIndex; - Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &DataContext, CurrentDir); + Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &DataContext, &MFTIndex, CurrentDir); if (!NT_SUCCESS(Status)) { return Status; } - Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, FileToFind, FileRecord, FoundFCB); + Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, &File, FileRecord, MFTIndex, FoundFCB); ExFreePoolWithTag(FileRecord, TAG_NTFS); return Status; diff --git a/reactos/drivers/filesystems/ntfs/mft.c b/reactos/drivers/filesystems/ntfs/mft.c index 3ab7f372169..b27cfd697ee 100644 --- a/reactos/drivers/filesystems/ntfs/mft.c +++ b/reactos/drivers/filesystems/ntfs/mft.c @@ -649,6 +649,7 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, PFILE_RECORD_HEADER *FileRecord, PNTFS_ATTR_CONTEXT *DataContext, + PULONGLONG MFTIndex, ULONGLONG CurrentMFTIndex) { UNICODE_STRING Current, Remaining; @@ -694,6 +695,8 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb, return Status; } + *MFTIndex = CurrentMFTIndex; + return STATUS_SUCCESS; } @@ -701,8 +704,9 @@ NTSTATUS NtfsLookupFile(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, PFILE_RECORD_HEADER *FileRecord, - PNTFS_ATTR_CONTEXT *DataContext) + PNTFS_ATTR_CONTEXT *DataContext, + PULONGLONG MFTIndex) { - return NtfsLookupFileAt(Vcb, PathName, FileRecord, DataContext, NTFS_FILE_ROOT); + return NtfsLookupFileAt(Vcb, PathName, FileRecord, DataContext, MFTIndex, NTFS_FILE_ROOT); } /* EOF */ diff --git a/reactos/drivers/filesystems/ntfs/ntfs.h b/reactos/drivers/filesystems/ntfs/ntfs.h index 22cadd4e771..fd174a375c8 100644 --- a/reactos/drivers/filesystems/ntfs/ntfs.h +++ b/reactos/drivers/filesystems/ntfs/ntfs.h @@ -433,6 +433,8 @@ DecodeRun(PUCHAR DataRun, VOID NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord); +PFILENAME_ATTRIBUTE +GetFileNameFromRecord(PFILE_RECORD_HEADER FileRecord); /* blockdev.c */ @@ -632,13 +634,15 @@ NTSTATUS NtfsLookupFile(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, PFILE_RECORD_HEADER *FileRecord, - PNTFS_ATTR_CONTEXT *DataContext); + PNTFS_ATTR_CONTEXT *DataContext, + PULONGLONG MFTIndex); NTSTATUS NtfsLookupFileAt(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, PFILE_RECORD_HEADER *FileRecord, PNTFS_ATTR_CONTEXT *DataContext, + PULONGLONG MFTIndex, ULONGLONG CurrentMFTIndex); /* misc.c */