[NTFS] - Add some fixes and improvements to attribute.c from CR-123:

-AddFileName() - Don't use dedicated buffer for FileNameNoPath, just point into FileObject->FileName's buffer. Don't use RtlCopyUnicodeString(), just update pointers.
-AddRun() - Fix an SEH2_YIELD with missing return statement.
-FreeClusters() - Use ULONG_MAX in place of 0xffffffff.
-NtfsDumpIndexRootAttribute() - Use consistent UpperCase naming convention. Use BooleanFlagOn() macro where appropriate. Replace magic 8 with sizeof(ULONGLONG).
-GetFileNameAttributeLength() - Add documentation.

svn path=/branches/GSoC_2016/NTFS/; revision=75279
This commit is contained in:
Trevor Thompson 2017-07-04 21:40:02 +00:00 committed by Thomas Faber
parent f5b7f90f23
commit e5cc846555

View file

@ -29,6 +29,7 @@
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include "ntfs.h" #include "ntfs.h"
#include <ntintsafe.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
@ -147,7 +148,6 @@ AddFileName(PFILE_RECORD_HEADER FileRecord,
UNICODE_STRING Current, Remaining, FilenameNoPath; UNICODE_STRING Current, Remaining, FilenameNoPath;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
ULONG FirstEntry; ULONG FirstEntry;
WCHAR Buffer[MAX_PATH];
if (AttributeAddress->Type != AttributeEnd) if (AttributeAddress->Type != AttributeEnd)
{ {
@ -172,7 +172,8 @@ AddFileName(PFILE_RECORD_HEADER FileRecord,
// we need to extract the filename from the path // we need to extract the filename from the path
DPRINT1("Pathname: %wZ\n", &FileObject->FileName); DPRINT1("Pathname: %wZ\n", &FileObject->FileName);
RtlInitEmptyUnicodeString(&FilenameNoPath, Buffer, MAX_PATH); FilenameNoPath.Buffer = FileObject->FileName.Buffer;
FilenameNoPath.MaximumLength = FilenameNoPath.Length = FileObject->FileName.Length;
FsRtlDissectName(FileObject->FileName, &Current, &Remaining); FsRtlDissectName(FileObject->FileName, &Current, &Remaining);
@ -180,8 +181,11 @@ AddFileName(PFILE_RECORD_HEADER FileRecord,
{ {
DPRINT1("Current: %wZ\n", &Current); DPRINT1("Current: %wZ\n", &Current);
if(Remaining.Length != 0) if (Remaining.Length != 0)
RtlCopyUnicodeString(&FilenameNoPath, &Remaining); {
FilenameNoPath.Buffer = Remaining.Buffer;
FilenameNoPath.Length = FilenameNoPath.MaximumLength = Remaining.Length;
}
FirstEntry = 0; FirstEntry = 0;
Status = NtfsFindMftRecord(DeviceExt, Status = NtfsFindMftRecord(DeviceExt,
@ -196,8 +200,11 @@ AddFileName(PFILE_RECORD_HEADER FileRecord,
if (Remaining.Length == 0 ) if (Remaining.Length == 0 )
{ {
if(Current.Length != 0) if (Current.Length != 0)
RtlCopyUnicodeString(&FilenameNoPath, &Current); {
FilenameNoPath.Buffer = Current.Buffer;
FilenameNoPath.Length = FilenameNoPath.MaximumLength = Current.Length;
}
break; break;
} }
@ -317,9 +324,13 @@ AddRun(PNTFS_VCB Vcb,
{ {
ExRaiseStatus(STATUS_UNSUCCESSFUL); ExRaiseStatus(STATUS_UNSUCCESSFUL);
} }
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { }
_SEH2_YIELD(_SEH2_GetExceptionCode()); _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
} _SEH2_END; {
DPRINT1("Failed to add LargeMcb Entry!\n");
_SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
RunBuffer = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerFileRecord, TAG_NTFS); RunBuffer = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerFileRecord, TAG_NTFS);
if (!RunBuffer) if (!RunBuffer)
@ -756,7 +767,7 @@ FreeClusters(PNTFS_VCB Vcb,
} }
BitmapDataSize = AttributeDataLength(&DataContext->Record); BitmapDataSize = AttributeDataLength(&DataContext->Record);
BitmapDataSize = min(BitmapDataSize, 0xffffffff); BitmapDataSize = min(BitmapDataSize, ULONG_MAX);
ASSERT((BitmapDataSize * 8) >= Vcb->NtfsInfo.ClusterCount); ASSERT((BitmapDataSize * 8) >= Vcb->NtfsInfo.ClusterCount);
BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, Vcb->NtfsInfo.BytesPerSector), TAG_NTFS); BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, Vcb->NtfsInfo.BytesPerSector), TAG_NTFS);
if (BitmapData == NULL) if (BitmapData == NULL)
@ -1144,8 +1155,8 @@ VOID
NtfsDumpIndexRootAttribute(PNTFS_ATTR_RECORD Attribute) NtfsDumpIndexRootAttribute(PNTFS_ATTR_RECORD Attribute)
{ {
PINDEX_ROOT_ATTRIBUTE IndexRootAttr; PINDEX_ROOT_ATTRIBUTE IndexRootAttr;
ULONG currentOffset; ULONG CurrentOffset;
ULONG currentNode; ULONG CurrentNode;
IndexRootAttr = (PINDEX_ROOT_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset); IndexRootAttr = (PINDEX_ROOT_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
@ -1168,18 +1179,18 @@ NtfsDumpIndexRootAttribute(PNTFS_ATTR_RECORD Attribute)
IndexRootAttr->Header.FirstEntryOffset, IndexRootAttr->Header.FirstEntryOffset,
IndexRootAttr->Header.TotalSizeOfEntries, IndexRootAttr->Header.TotalSizeOfEntries,
IndexRootAttr->Header.AllocatedSize); IndexRootAttr->Header.AllocatedSize);
currentOffset = IndexRootAttr->Header.FirstEntryOffset; CurrentOffset = IndexRootAttr->Header.FirstEntryOffset;
currentNode = 0; CurrentNode = 0;
// print details of every node in the index // print details of every node in the index
while (currentOffset < IndexRootAttr->Header.TotalSizeOfEntries) while (CurrentOffset < IndexRootAttr->Header.TotalSizeOfEntries)
{ {
PINDEX_ENTRY_ATTRIBUTE currentIndexExtry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexRootAttr + 0x10 + currentOffset); PINDEX_ENTRY_ATTRIBUTE currentIndexExtry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexRootAttr + 0x10 + CurrentOffset);
DbgPrint(" Index Node Entry %lu", currentNode++); DbgPrint(" Index Node Entry %lu", CurrentNode++);
if (currentIndexExtry->Flags & NTFS_INDEX_ENTRY_NODE) if (BooleanFlagOn(currentIndexExtry->Flags, NTFS_INDEX_ENTRY_NODE))
DbgPrint(" (Branch)"); DbgPrint(" (Branch)");
else else
DbgPrint(" (Leaf)"); DbgPrint(" (Leaf)");
if((currentIndexExtry->Flags & NTFS_INDEX_ENTRY_END)) if (BooleanFlagOn(currentIndexExtry->Flags, NTFS_INDEX_ENTRY_END))
{ {
DbgPrint(" (Dummy Key)"); DbgPrint(" (Dummy Key)");
} }
@ -1203,11 +1214,11 @@ NtfsDumpIndexRootAttribute(PNTFS_ATTR_RECORD Attribute)
if (currentIndexExtry->Flags & NTFS_INDEX_ENTRY_NODE) if (currentIndexExtry->Flags & NTFS_INDEX_ENTRY_NODE)
{ {
// Print the VCN of the sub-node // Print the VCN of the sub-node
PULONGLONG SubNodeVCN = (PULONGLONG)((ULONG_PTR)currentIndexExtry + currentIndexExtry->Length - 8); PULONGLONG SubNodeVCN = (PULONGLONG)((ULONG_PTR)currentIndexExtry + currentIndexExtry->Length - sizeof(ULONGLONG));
DbgPrint(" VCN of sub-node: 0x%llx\n", *SubNodeVCN); DbgPrint(" VCN of sub-node: 0x%llx\n", *SubNodeVCN);
} }
currentOffset += currentIndexExtry->Length; CurrentOffset += currentIndexExtry->Length;
ASSERT(currentIndexExtry->Length); ASSERT(currentIndexExtry->Length);
} }
@ -1567,6 +1578,19 @@ GetStandardInformationFromRecord(PDEVICE_EXTENSION Vcb,
return NULL; return NULL;
} }
/**
* @name GetFileNameAttributeLength
* @implemented
*
* Returns the size of a given FILENAME_ATTRIBUTE, in bytes.
*
* @param FileNameAttribute
* Pointer to a FILENAME_ATTRIBUTE to determine the size of.
*
* @remarks
* The length of a FILENAME_ATTRIBUTE is variable and is dependent on the length of the file name stored at the end.
* This function operates on the FILENAME_ATTRIBUTE proper, so don't try to pass it a PNTFS_ATTR_RECORD.
*/
ULONG GetFileNameAttributeLength(PFILENAME_ATTRIBUTE FileNameAttribute) ULONG GetFileNameAttributeLength(PFILENAME_ATTRIBUTE FileNameAttribute)
{ {
ULONG Length = FIELD_OFFSET(FILENAME_ATTRIBUTE, Name) + (FileNameAttribute->NameLength * sizeof(WCHAR)); ULONG Length = FIELD_OFFSET(FILENAME_ATTRIBUTE, Name) + (FileNameAttribute->NameLength * sizeof(WCHAR));