https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5579428b4f1361481dae3ea0b901c0a915401148

commit 5579428b4f1361481dae3ea0b901c0a915401148
Author: Trevor Thompson <[email protected]>
AuthorDate: Thu Jul 27 18:22:24 2017 +0000

    [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
---
 drivers/filesystems/ntfs/btree.c |  46 +++++++++++++-
 drivers/filesystems/ntfs/finfo.c | 128 ++++++++++++++++++++++++++++++++++++++-
 drivers/filesystems/ntfs/mft.c   |  38 ++++++------
 drivers/filesystems/ntfs/ntfs.h  |  16 +++++
 4 files changed, 206 insertions(+), 22 deletions(-)

diff --git a/drivers/filesystems/ntfs/btree.c b/drivers/filesystems/ntfs/btree.c
index a7eacb3173..38fa9aefee 100644
--- a/drivers/filesystems/ntfs/btree.c
+++ b/drivers/filesystems/ntfs/btree.c
@@ -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;
     }
diff --git a/drivers/filesystems/ntfs/finfo.c b/drivers/filesystems/ntfs/finfo.c
index 323b85cf45..aee8aa51e2 100644
--- a/drivers/filesystems/ntfs/finfo.c
+++ b/drivers/filesystems/ntfs/finfo.c
@@ -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;
     }
 
diff --git a/drivers/filesystems/ntfs/mft.c b/drivers/filesystems/ntfs/mft.c
index 72953c0086..928839edd7 100644
--- a/drivers/filesystems/ntfs/mft.c
+++ b/drivers/filesystems/ntfs/mft.c
@@ -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);
 
diff --git a/drivers/filesystems/ntfs/ntfs.h b/drivers/filesystems/ntfs/ntfs.h
index 9cbc4d5485..39c33210fc 100644
--- a/drivers/filesystems/ntfs/ntfs.h
+++ b/drivers/filesystems/ntfs/ntfs.h
@@ -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,

Reply via email to