[NTFS] - Add some utility functions and improve some comments. Improve NtfsAddFilenam...
authorTrevor Thompson <tmt256@email.vccs.edu>
Thu, 27 Jul 2017 18:22:24 +0000 (18:22 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sun, 10 Dec 2017 10:15:04 +0000 (11:15 +0100)
+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

drivers/filesystems/ntfs/btree.c
drivers/filesystems/ntfs/finfo.c
drivers/filesystems/ntfs/mft.c
drivers/filesystems/ntfs/ntfs.h

index a7eacb3..38fa9ae 100644 (file)
 
 /* 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;
     }
index 323b85c..aee8aa5 100644 (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;
     }
 
index 72953c0..928839e 100644 (file)
@@ -2018,25 +2018,29 @@ 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);
-    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)
+    
+    if (AttributeLength != IndexRootContext->Record.Resident.ValueLength)
     {
-        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;
-    }
+        DestinationAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)ParentFileRecord + IndexRootOffset);
 
-    // Update the length of the attribute in the file record of the parent directory
-    InternalSetResidentAttributeLength(IndexRootContext,
-                                       ParentFileRecord,
-                                       IndexRootOffset,
-                                       AttributeLength);
+        // 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);
 
index 9cbc4d5..39c3321 100644 (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,