[NTFS] - Add some utility functions and improve some comments. Improve NtfsAddFilenameToDirectory().

+PrintAllVCNs() - Diagnostic function which prints VCN of every node in an index allocation.
+GetAllocationOffsetFromVCN() - Calculates location of an index buffer from the node's VCN.
+GetInfoClassName() - Gets a string representation of an info class enumeration, to speed up development of unimplemented classes.
-NtfsSetInformation() & NtfsQueryInformation() - Use GetInfoClassName to report unhandled information classes.
-CompareTreeKeys() - Add a comment and clarify some comments.
-NtfsAddFilenameToDirectory() - Don't try to update the size of Index Root on disk if the attribute length hasn't changed.

svn path=/branches/GSoC_2016/NTFS/; revision=75424
This commit is contained in:
Trevor Thompson 2017-07-27 18:22:24 +00:00 committed by Thomas Faber
parent 9cef425464
commit 5579428b4f
4 changed files with 206 additions and 22 deletions

View file

@ -32,6 +32,47 @@
/* FUNCTIONS ****************************************************************/
// TEMP FUNCTION for diagnostic purposes.
// Prints VCN of every node in an index allocation
VOID
PrintAllVCNs(PDEVICE_EXTENSION Vcb,
PNTFS_ATTR_CONTEXT IndexAllocationContext,
ULONG NodeSize)
{
ULONGLONG CurrentOffset = 0;
PINDEX_BUFFER CurrentNode, Buffer;
ULONGLONG BufferSize = AttributeDataLength(&IndexAllocationContext->Record);
ULONGLONG i;
int Count = 0;
Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, TAG_NTFS);
ULONG BytesRead = ReadAttribute(Vcb, IndexAllocationContext, 0, (PCHAR)Buffer, BufferSize);
ASSERT(BytesRead = BufferSize);
CurrentNode = Buffer;
// loop through all the nodes
for (i = 0; i < BufferSize; i += NodeSize)
{
NTSTATUS Status = FixupUpdateSequenceArray(Vcb, &CurrentNode->Ntfs);
if (!NT_SUCCESS(Status))
{
DPRINT1("ERROR: Fixing fixup failed!\n");
continue;
}
DPRINT1("Node #%d, VCN: %I64u\n", Count, CurrentNode->VCN);
CurrentNode = (PINDEX_BUFFER)((ULONG_PTR)CurrentNode + NodeSize);
CurrentOffset += NodeSize;
Count++;
}
ExFreePoolWithTag(Buffer, TAG_NTFS);
}
/**
* @name CompareTreeKeys
* @implemented
@ -62,6 +103,7 @@ CompareTreeKeys(PB_TREE_KEY Key1, PB_TREE_KEY Key2, BOOLEAN CaseSensitive)
UNICODE_STRING Key1Name, Key2Name;
LONG Comparison;
// Key1 must not be the final key (AKA the dummy key)
ASSERT(!(Key1->IndexEntry->Flags & NTFS_INDEX_ENTRY_END));
// If Key2 is the "dummy key", key 1 will always come first
@ -89,7 +131,7 @@ CompareTreeKeys(PB_TREE_KEY Key1, PB_TREE_KEY Key2, BOOLEAN CaseSensitive)
// Compare the names of the same length
Comparison = RtlCompareUnicodeString(&Key1Name, &Key2Name, !CaseSensitive);
// If the truncated files are the same length, the shorter one comes first
// If the truncated names are the same length, the shorter one comes first
if (Comparison == 0)
return -1;
}
@ -102,7 +144,7 @@ CompareTreeKeys(PB_TREE_KEY Key1, PB_TREE_KEY Key2, BOOLEAN CaseSensitive)
// Compare the names of the same length
Comparison = RtlCompareUnicodeString(&Key1Name, &Key2Name, !CaseSensitive);
// If the truncated files are the same length, the shorter one comes first
// If the truncated names are the same length, the shorter one comes first
if (Comparison == 0)
return 1;
}

View file

@ -289,6 +289,128 @@ NtfsGetSteamInformation(PNTFS_FCB Fcb,
return Status;
}
// Convert enum value to friendly name
const PCSTR
GetInfoClassName(FILE_INFORMATION_CLASS infoClass)
{
const PCSTR fileInfoClassNames[] = { "???????",
"FileDirectoryInformation",
"FileFullDirectoryInformation",
"FileBothDirectoryInformation",
"FileBasicInformation",
"FileStandardInformation",
"FileInternalInformation",
"FileEaInformation",
"FileAccessInformation",
"FileNameInformation",
"FileRenameInformation",
"FileLinkInformation",
"FileNamesInformation",
"FileDispositionInformation",
"FilePositionInformation",
"FileFullEaInformation",
"FileModeInformation",
"FileAlignmentInformation",
"FileAllInformation",
"FileAllocationInformation",
"FileEndOfFileInformation",
"FileAlternateNameInformation",
"FileStreamInformation",
"FilePipeInformation",
"FilePipeLocalInformation",
"FilePipeRemoteInformation",
"FileMailslotQueryInformation",
"FileMailslotSetInformation",
"FileCompressionInformation",
"FileObjectIdInformation",
"FileCompletionInformation",
"FileMoveClusterInformation",
"FileQuotaInformation",
"FileReparsePointInformation",
"FileNetworkOpenInformation",
"FileAttributeTagInformation",
"FileTrackingInformation",
"FileIdBothDirectoryInformation",
"FileIdFullDirectoryInformation",
"FileValidDataLengthInformation",
"FileShortNameInformation",
"FileIoCompletionNotificationInformation",
"FileIoStatusBlockRangeInformation",
"FileIoPriorityHintInformation",
"FileSfioReserveInformation",
"FileSfioVolumeInformation",
"FileHardLinkInformation",
"FileProcessIdsUsingFileInformation",
"FileNormalizedNameInformation",
"FileNetworkPhysicalNameInformation",
"FileIdGlobalTxDirectoryInformation",
"FileIsRemoteDeviceInformation",
"FileAttributeCacheInformation",
"FileNumaNodeInformation",
"FileStandardLinkInformation",
"FileRemoteProtocolInformation",
"FileReplaceCompletionInformation",
"FileMaximumInformation",
"FileDirectoryInformation",
"FileFullDirectoryInformation",
"FileBothDirectoryInformation",
"FileBasicInformation",
"FileStandardInformation",
"FileInternalInformation",
"FileEaInformation",
"FileAccessInformation",
"FileNameInformation",
"FileRenameInformation",
"FileLinkInformation",
"FileNamesInformation",
"FileDispositionInformation",
"FilePositionInformation",
"FileFullEaInformation",
"FileModeInformation",
"FileAlignmentInformation",
"FileAllInformation",
"FileAllocationInformation",
"FileEndOfFileInformation",
"FileAlternateNameInformation",
"FileStreamInformation",
"FilePipeInformation",
"FilePipeLocalInformation",
"FilePipeRemoteInformation",
"FileMailslotQueryInformation",
"FileMailslotSetInformation",
"FileCompressionInformation",
"FileObjectIdInformation",
"FileCompletionInformation",
"FileMoveClusterInformation",
"FileQuotaInformation",
"FileReparsePointInformation",
"FileNetworkOpenInformation",
"FileAttributeTagInformation",
"FileTrackingInformation",
"FileIdBothDirectoryInformation",
"FileIdFullDirectoryInformation",
"FileValidDataLengthInformation",
"FileShortNameInformation",
"FileIoCompletionNotificationInformation",
"FileIoStatusBlockRangeInformation",
"FileIoPriorityHintInformation",
"FileSfioReserveInformation",
"FileSfioVolumeInformation",
"FileHardLinkInformation",
"FileProcessIdsUsingFileInformation",
"FileNormalizedNameInformation",
"FileNetworkPhysicalNameInformation",
"FileIdGlobalTxDirectoryInformation",
"FileIsRemoteDeviceInformation",
"FileAttributeCacheInformation",
"FileNumaNodeInformation",
"FileStandardLinkInformation",
"FileRemoteProtocolInformation",
"FileReplaceCompletionInformation",
"FileMaximumInformation" };
return fileInfoClassNames[infoClass];
}
/*
* FUNCTION: Retrieve the specified file information
*/
@ -376,12 +498,12 @@ NtfsQueryInformation(PNTFS_IRP_CONTEXT IrpContext)
case FileAlternateNameInformation:
case FileAllInformation:
DPRINT1("Unimplemented information class %u\n", FileInformationClass);
DPRINT1("Unimplemented information class: %s\n", GetInfoClassName(FileInformationClass));
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
DPRINT1("Unimplemented information class %u\n", FileInformationClass);
DPRINT1("Unimplemented information class: %s\n", GetInfoClassName(FileInformationClass));
Status = STATUS_INVALID_PARAMETER;
}
@ -645,7 +767,7 @@ NtfsSetInformation(PNTFS_IRP_CONTEXT IrpContext)
// TODO: all other information classes
default:
DPRINT1("FIXME: Unimplemented information class %u\n", FileInformationClass);
DPRINT1("FIXME: Unimplemented information class: %s\n", GetInfoClassName(FileInformationClass));
Status = STATUS_NOT_IMPLEMENTED;
}

View file

@ -2018,6 +2018,9 @@ NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt,
// we must create an index allocation and index bitmap (TODO). Also TODO: support file records with
// $ATTRIBUTE_LIST's.
AttributeLength = NewIndexRoot->Header.AllocatedSize + FIELD_OFFSET(INDEX_ROOT_ATTRIBUTE, Header);
if (AttributeLength != IndexRootContext->Record.Resident.ValueLength)
{
DestinationAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)ParentFileRecord + IndexRootOffset);
// Find the attribute (or attribute-end marker) after the index root
@ -2037,6 +2040,7 @@ NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt,
ParentFileRecord,
IndexRootOffset,
AttributeLength);
}
NT_ASSERT(ParentFileRecord->BytesInUse <= DeviceExt->NtfsInfo.BytesPerFileRecord);

View file

@ -208,6 +208,9 @@ typedef enum
#define INDEX_ROOT_SMALL 0x0
#define INDEX_ROOT_LARGE 0x1
#define INDEX_NODE_SMALL 0x0
#define INDEX_NODE_LARGE 0x1
#define NTFS_INDEX_ENTRY_NODE 1
#define NTFS_INDEX_ENTRY_END 2
@ -700,9 +703,22 @@ CreateIndexRootFromBTree(PDEVICE_EXTENSION DeviceExt,
VOID
DestroyBTree(PB_TREE Tree);
VOID
DestroyBTreeNode(PB_TREE_FILENAME_NODE Node);
VOID
DumpBTree(PB_TREE Tree);
VOID
DumpBTreeNode(PB_TREE_FILENAME_NODE Node,
ULONG Number,
ULONG Depth);
ULONGLONG
GetAllocationOffsetFromVCN(PDEVICE_EXTENSION DeviceExt,
ULONG IndexBufferSize,
ULONGLONG Vcn);
NTSTATUS
NtfsInsertKey(ULONGLONG FileReference,
PFILENAME_ATTRIBUTE FileNameAttribute,