Author: tthompson
Date: Thu Jul 27 18:22:24 2017
New Revision: 75424
URL:
http://svn.reactos.org/svn/reactos?rev=75424&view=rev
Log:
[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.
Modified:
branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/btree.c
branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/finfo.c
branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c
branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h
Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/btree.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
==============================================================================
--- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/btree.c [iso-8859-1] (original)
+++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/btree.c [iso-8859-1] Thu Jul 27
18:22:24 2017
@@ -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 @@
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 @@
// 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 @@
// 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;
}
Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/finfo.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
==============================================================================
--- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/finfo.c [iso-8859-1] (original)
+++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/finfo.c [iso-8859-1] Thu Jul 27
18:22:24 2017
@@ -289,6 +289,128 @@
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 @@
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 @@
// 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;
}
Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
==============================================================================
--- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c [iso-8859-1] (original)
+++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c [iso-8859-1] Thu Jul 27
18:22:24 2017
@@ -2018,25 +2018,29 @@
// 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);
- DestinationAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)ParentFileRecord +
IndexRootOffset);
-
- // Find the attribute (or attribute-end marker) after the index root
- NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)DestinationAttribute +
DestinationAttribute->Length);
- if (NextAttribute->Type != AttributeEnd)
- {
- DPRINT1("FIXME: For now, only resizing index root at the end of a file
record is supported!\n");
- ExFreePoolWithTag(NewIndexRoot, TAG_NTFS);
- ReleaseAttributeContext(IndexRootContext);
- ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
- ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
- return STATUS_NOT_IMPLEMENTED;
- }
-
- // Update the length of the attribute in the file record of the parent directory
- InternalSetResidentAttributeLength(IndexRootContext,
- ParentFileRecord,
- IndexRootOffset,
- AttributeLength);
+
+ 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
+ NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)DestinationAttribute +
DestinationAttribute->Length);
+ if (NextAttribute->Type != AttributeEnd)
+ {
+ DPRINT1("FIXME: For now, only resizing index root at the end of a file
record is supported!\n");
+ ExFreePoolWithTag(NewIndexRoot, TAG_NTFS);
+ ReleaseAttributeContext(IndexRootContext);
+ ExFreePoolWithTag(I30IndexRoot, TAG_NTFS);
+ ExFreePoolWithTag(ParentFileRecord, TAG_NTFS);
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ // Update the length of the attribute in the file record of the parent directory
+ InternalSetResidentAttributeLength(IndexRootContext,
+ ParentFileRecord,
+ IndexRootOffset,
+ AttributeLength);
+ }
NT_ASSERT(ParentFileRecord->BytesInUse <=
DeviceExt->NtfsInfo.BytesPerFileRecord);
Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
==============================================================================
--- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] (original)
+++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h [iso-8859-1] Thu Jul 27
18:22:24 2017
@@ -207,6 +207,9 @@
#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
@@ -701,7 +704,20 @@
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,