- 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
This commit is contained in:
Pierre Schweitzer 2014-10-08 19:12:48 +00:00
parent 189e1394bd
commit df3a6889ba
4 changed files with 65 additions and 40 deletions

View file

@ -278,7 +278,7 @@ NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord)
Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset); Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) && while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
Attribute->Type != (ATTRIBUTE_TYPE)-1) Attribute->Type != AttributeEnd)
{ {
NtfsDumpAttribute(Attribute); 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 */ /* EOF */

View file

@ -354,57 +354,53 @@ NtfsGetDirEntryName(PDEVICE_EXTENSION DeviceExt,
NTSTATUS NTSTATUS
NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb, NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb,
PNTFS_FCB DirectoryFCB, PNTFS_FCB DirectoryFCB,
PWSTR Name, PUNICODE_STRING Name,
PFILE_RECORD_HEADER Record, PFILE_RECORD_HEADER Record,
ULONGLONG MFTIndex,
PNTFS_FCB * fileFCB) PNTFS_FCB * fileFCB)
{ {
#if 0 WCHAR pathName[MAX_PATH];
WCHAR pathName[MAX_PATH]; PFILENAME_ATTRIBUTE FileName;
PFCB rcFCB; PNTFS_FCB rcFCB;
ULONG Size;
if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) + DPRINT1("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p)\n", Vcb, DirectoryFCB, Name, Record, fileFCB);
sizeof(WCHAR) + wcslen (Name) > MAX_PATH)
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 (Name->Buffer[0] != 0 && wcslen(DirectoryFCB->PathName) +
if (!NtfsFCBIsRoot(DirectoryFCB)) 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 wcscat(pathName, Name->Buffer);
{
WCHAR entryName[MAX_PATH];
NtfsGetDirEntryName(Vcb, Record, entryName); rcFCB = NtfsCreateFCB(pathName, Vcb);
wcscat(pathName, entryName); if (!rcFCB)
{
return STATUS_INSUFFICIENT_RESOURCES;
} }
rcFCB = NtfsCreateFCB(pathName, Vcb); rcFCB->RFCB.FileSize.QuadPart = FileName->DataSize;
memcpy(&rcFCB->Entry, Record, sizeof(DIR_RECORD)); 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; return STATUS_SUCCESS;
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
} }
@ -460,18 +456,21 @@ NtfsDirFindFile(PNTFS_VCB Vcb,
UNICODE_STRING File; UNICODE_STRING File;
PFILE_RECORD_HEADER FileRecord; PFILE_RECORD_HEADER FileRecord;
PNTFS_ATTR_CONTEXT DataContext; PNTFS_ATTR_CONTEXT DataContext;
ULONGLONG MFTIndex;
DPRINT1("NtfsDirFindFile(%p, %p, %S, %p)\n", Vcb, DirectoryFcb, FileToFind, FoundFCB);
*FoundFCB = NULL; *FoundFCB = NULL;
RtlInitUnicodeString(&File, FileToFind); RtlInitUnicodeString(&File, FileToFind);
CurrentDir = DirectoryFcb->MFTIndex; CurrentDir = DirectoryFcb->MFTIndex;
Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &DataContext, CurrentDir); Status = NtfsLookupFileAt(Vcb, &File, &FileRecord, &DataContext, &MFTIndex, CurrentDir);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return Status;
} }
Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, FileToFind, FileRecord, FoundFCB); Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, &File, FileRecord, MFTIndex, FoundFCB);
ExFreePoolWithTag(FileRecord, TAG_NTFS); ExFreePoolWithTag(FileRecord, TAG_NTFS);
return Status; return Status;

View file

@ -649,6 +649,7 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
PUNICODE_STRING PathName, PUNICODE_STRING PathName,
PFILE_RECORD_HEADER *FileRecord, PFILE_RECORD_HEADER *FileRecord,
PNTFS_ATTR_CONTEXT *DataContext, PNTFS_ATTR_CONTEXT *DataContext,
PULONGLONG MFTIndex,
ULONGLONG CurrentMFTIndex) ULONGLONG CurrentMFTIndex)
{ {
UNICODE_STRING Current, Remaining; UNICODE_STRING Current, Remaining;
@ -694,6 +695,8 @@ NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
return Status; return Status;
} }
*MFTIndex = CurrentMFTIndex;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -701,8 +704,9 @@ NTSTATUS
NtfsLookupFile(PDEVICE_EXTENSION Vcb, NtfsLookupFile(PDEVICE_EXTENSION Vcb,
PUNICODE_STRING PathName, PUNICODE_STRING PathName,
PFILE_RECORD_HEADER *FileRecord, 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 */ /* EOF */

View file

@ -433,6 +433,8 @@ DecodeRun(PUCHAR DataRun,
VOID VOID
NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord); NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord);
PFILENAME_ATTRIBUTE
GetFileNameFromRecord(PFILE_RECORD_HEADER FileRecord);
/* blockdev.c */ /* blockdev.c */
@ -632,13 +634,15 @@ NTSTATUS
NtfsLookupFile(PDEVICE_EXTENSION Vcb, NtfsLookupFile(PDEVICE_EXTENSION Vcb,
PUNICODE_STRING PathName, PUNICODE_STRING PathName,
PFILE_RECORD_HEADER *FileRecord, PFILE_RECORD_HEADER *FileRecord,
PNTFS_ATTR_CONTEXT *DataContext); PNTFS_ATTR_CONTEXT *DataContext,
PULONGLONG MFTIndex);
NTSTATUS NTSTATUS
NtfsLookupFileAt(PDEVICE_EXTENSION Vcb, NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
PUNICODE_STRING PathName, PUNICODE_STRING PathName,
PFILE_RECORD_HEADER *FileRecord, PFILE_RECORD_HEADER *FileRecord,
PNTFS_ATTR_CONTEXT *DataContext, PNTFS_ATTR_CONTEXT *DataContext,
PULONGLONG MFTIndex,
ULONGLONG CurrentMFTIndex); ULONGLONG CurrentMFTIndex);
/* misc.c */ /* misc.c */