- 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);
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 */

View file

@ -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;

View file

@ -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 */

View file

@ -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 */