diff --git a/Aaru.Filesystems/NTFS/Enums.cs b/Aaru.Filesystems/NTFS/Enums.cs new file mode 100644 index 000000000..8bb8b0fca --- /dev/null +++ b/Aaru.Filesystems/NTFS/Enums.cs @@ -0,0 +1,627 @@ +// /*************************************************************************** +// Aaru Data Preservation Suite +// ---------------------------------------------------------------------------- +// +// Filename : Enums.cs +// Author(s) : Natalia Portillo +// +// Component : Microsoft NT File System plugin. +// +// --[ Description ] ---------------------------------------------------------- +// +// Enumerations for the Microsoft NT File System. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2026 Natalia Portillo +// ****************************************************************************/ + +using System; + +namespace Aaru.Filesystems; + +/// +public sealed partial class NTFS +{ +#region Nested type: NtfsRecordMagic + + /// Magic identifiers present at the beginning of all multi-sector protected NTFS records + enum NtfsRecordMagic : uint + { + /// MFT entry ("FILE") + File = 0x454c4946, + /// Index buffer ("INDX") + Indx = 0x58444e49, + /// Hole marker ("HOLE") + Hole = 0x454c4f48, + /// Restart page ("RSTR") + Rstr = 0x52545352, + /// Log record page ("RCRD") + Rcrd = 0x44524352, + /// Chkdsk modified ("CHKD") + Chkd = 0x444b4843, + /// Bad record ("BAAD") + Baad = 0x44414142, + /// Empty/uninitialized + Empty = 0xffffffff + } + +#endregion + +#region Nested type: SystemFileNumber + + /// System files MFT record numbers + enum SystemFileNumber : uint + { + /// Master File Table ($MFT) + Mft = 0, + /// MFT mirror ($MFTMirr) + MftMirr = 1, + /// Journaling log ($LogFile) + LogFile = 2, + /// Volume information ($Volume) + Volume = 3, + /// Attribute definitions ($AttrDef) + AttrDef = 4, + /// Root directory + Root = 5, + /// Cluster allocation bitmap ($Bitmap) + Bitmap = 6, + /// Boot sector ($Boot) + Boot = 7, + /// Bad cluster list ($BadClus) + BadClus = 8, + /// Security descriptors ($Secure) + Secure = 9, + /// Uppercase table ($UpCase) + UpCase = 10, + /// Extended system directory ($Extend) + Extend = 11, + /// First user file record + FirstUser = 16 + } + +#endregion + +#region Nested type: MftRecordFlags + + /// MFT record flags (16-bit) + [Flags] + enum MftRecordFlags : ushort + { + /// Record is allocated and in use + InUse = 0x0001, + /// Record represents a directory + IsDirectory = 0x0002, + /// Special record 4 type + Is4 = 0x0004, + /// Used as view index + IsViewIndex = 0x0008 + } + +#endregion + +#region Nested type: AttributeType + + /// System-defined attribute types (32-bit) + enum AttributeType : uint + { + /// Unused + Unused = 0x00, + /// $STANDARD_INFORMATION + StandardInformation = 0x10, + /// $ATTRIBUTE_LIST + AttributeList = 0x20, + /// $FILE_NAME + FileName = 0x30, + /// $OBJECT_ID (NTFS 3.0+) / $VOLUME_VERSION (NTFS 1.2) + ObjectId = 0x40, + /// $SECURITY_DESCRIPTOR + SecurityDescriptor = 0x50, + /// $VOLUME_NAME + VolumeName = 0x60, + /// $VOLUME_INFORMATION + VolumeInformation = 0x70, + /// $DATA + Data = 0x80, + /// $INDEX_ROOT + IndexRoot = 0x90, + /// $INDEX_ALLOCATION + IndexAllocation = 0xa0, + /// $BITMAP + Bitmap = 0xb0, + /// $REPARSE_POINT (NTFS 3.0+) / $SYMBOLIC_LINK (NTFS 1.2) + ReparsePoint = 0xc0, + /// $EA_INFORMATION + EaInformation = 0xd0, + /// $EA + Ea = 0xe0, + /// $PROPERTY_SET + PropertySet = 0xf0, + /// $LOGGED_UTILITY_STREAM (NTFS 3.0+) + LoggedUtilityStream = 0x100, + /// First user-defined attribute + FirstUserDefined = 0x1000, + /// End marker + End = 0xffffffff + } + +#endregion + +#region Nested type: CollationRule + + /// Collation rules for sorting views and indexes (32-bit) + enum CollationRule : uint + { + /// Binary compare (first byte most significant) + Binary = 0x00, + /// File name collation + FileName = 0x01, + /// Unicode string collation + UnicodeString = 0x02, + /// Ascending unsigned 32-bit values + NtofsUlong = 0x10, + /// Ascending SID values + NtofsSid = 0x11, + /// First by hash then by security_id + NtofsSecurityHash = 0x12, + /// Sequence of ascending unsigned 32-bit values + NtofsUlongs = 0x13 + } + +#endregion + +#region Nested type: AttrDefFlags + + /// Attribute definition flags (32-bit) + [Flags] + enum AttrDefFlags : uint + { + /// Attribute can be indexed + Indexable = 0x02, + /// Attribute can be present multiple times + Multiple = 0x04, + /// Attribute value must contain at least one non-zero byte + NotZero = 0x08, + /// Attribute must be indexed and the value must be unique + IndexedUnique = 0x10, + /// Attribute must be named and the name must be unique + NamedUnique = 0x20, + /// Attribute must be resident + Resident = 0x40, + /// Always log modifications to this attribute + AlwaysLog = 0x80 + } + +#endregion + +#region Nested type: AttributeFlags + + /// Attribute flags (16-bit) + [Flags] + enum AttributeFlags : ushort + { + /// Attribute is compressed + Compressed = 0x0001, + /// Compression method mask + CompressionMask = 0x00ff, + /// Attribute is encrypted + Encrypted = 0x4000, + /// Attribute is sparse + Sparse = 0x8000 + } + +#endregion + +#region Nested type: ResidentAttributeFlags + + /// Resident attribute flags (8-bit) + [Flags] + enum ResidentAttributeFlags : byte + { + /// Attribute is referenced in an index + Indexed = 0x01 + } + +#endregion + +#region Nested type: FileAttributeFlags + + /// File attribute flags (32-bit) + [Flags] + enum FileAttributeFlags : uint + { + /// File is read-only + ReadOnly = 0x00000001, + /// File is hidden + Hidden = 0x00000002, + /// System file + System = 0x00000004, + /// Directory + Directory = 0x00000010, + /// File needs archiving + Archive = 0x00000020, + /// Device file + Device = 0x00000040, + /// Normal file (no special attributes) + Normal = 0x00000080, + /// Temporary file + Temporary = 0x00000100, + /// Sparse file + SparseFile = 0x00000200, + /// Reparse point + ReparsePoint = 0x00000400, + /// File is compressed + Compressed = 0x00000800, + /// File data is offline + Offline = 0x00001000, + /// File is excluded from content indexing + NotContentIndexed = 0x00002000, + /// File is encrypted + Encrypted = 0x00004000, + /// Recall data on open (cloud/HSM) + RecallOnOpen = 0x00040000, + /// Duplicate file name index present + DupFileNameIndexPresent = 0x10000000, + /// Duplicate view index present + DupViewIndexPresent = 0x20000000 + } + +#endregion + +#region Nested type: FileNameNamespace + + /// Possible namespaces for file names in NTFS (8-bit) + enum FileNameNamespace : byte + { + /// POSIX namespace (case sensitive, most permissive) + Posix = 0x00, + /// Win32 namespace (case insensitive) + Win32 = 0x01, + /// DOS 8.3 namespace + Dos = 0x02, + /// Win32 and DOS names are identical + Win32AndDos = 0x03 + } + +#endregion + +#region Nested type: VolumeFlags + + /// NTFS volume flags (16-bit) + [Flags] + enum VolumeFlags : ushort + { + /// Volume is dirty (needs chkdsk) + IsDirty = 0x0001, + /// Resize LogFile on next mount + ResizeLogFile = 0x0002, + /// Upgrade volume on mount + UpgradeOnMount = 0x0004, + /// Mounted on NT4 + MountedOnNt4 = 0x0008, + /// USN journal deletion in progress + DeleteUsnUnderway = 0x0010, + /// Repair $ObjId on next mount + RepairObjectId = 0x0020, + /// Chkdsk is running + ChkdskUnderway = 0x4000, + /// Volume modified by chkdsk + ModifiedByChkdsk = 0x8000 + } + +#endregion + +#region Nested type: IndexHeaderFlags + + /// Index header flags (8-bit) + [Flags] + enum IndexHeaderFlags : byte + { + /// Small index / leaf node + SmallIndex = 0, + /// Large index / internal node with sub-nodes + LargeIndex = 1 + } + +#endregion + +#region Nested type: IndexEntryFlags + + /// Index entry flags (16-bit) + [Flags] + enum IndexEntryFlags : ushort + { + /// Entry points to a sub-node (index block VCN) + Node = 0x0001, + /// Last entry in index block/root + End = 0x0002 + } + +#endregion + +#region Nested type: SecurityDescriptorControl + + /// Security descriptor control flags (16-bit) + [Flags] + enum SecurityDescriptorControl : ushort + { + /// Owner was defaulted + OwnerDefaulted = 0x0001, + /// Group was defaulted + GroupDefaulted = 0x0002, + /// DACL present + DaclPresent = 0x0004, + /// DACL was defaulted + DaclDefaulted = 0x0008, + /// SACL present + SaclPresent = 0x0010, + /// SACL was defaulted + SaclDefaulted = 0x0020, + /// DACL auto-inherit requested + DaclAutoInheritReq = 0x0100, + /// SACL auto-inherit requested + SaclAutoInheritReq = 0x0200, + /// DACL was auto-inherited + DaclAutoInherited = 0x0400, + /// SACL was auto-inherited + SaclAutoInherited = 0x0800, + /// DACL is protected from inheritance + DaclProtected = 0x1000, + /// SACL is protected from inheritance + SaclProtected = 0x2000, + /// RM control valid + RmControlValid = 0x4000, + /// Self-relative format + SelfRelative = 0x8000 + } + +#endregion + +#region Nested type: AceType + + /// ACE types (8-bit) + enum AceType : byte + { + /// Allow access + AccessAllowed = 0, + /// Deny access + AccessDenied = 1, + /// Audit access + SystemAudit = 2, + /// Alarm on access + SystemAlarm = 3, + /// Compound ACE (legacy) + AccessAllowedCompound = 4, + /// Allow with object-specific rights + AccessAllowedObject = 5, + /// Deny with object-specific rights + AccessDeniedObject = 6, + /// Audit with object-specific rights + SystemAuditObject = 7, + /// Alarm with object-specific rights + SystemAlarmObject = 8 + } + +#endregion + +#region Nested type: AceFlags + + /// ACE inheritance and audit flags (8-bit) + [Flags] + enum AceFlags : byte + { + /// Files inherit this ACE + ObjectInherit = 0x01, + /// Subdirectories inherit this ACE + ContainerInherit = 0x02, + /// Stop inheritance after this level + NoPropagateInherit = 0x04, + /// Inherit only (not applied to current object) + InheritOnly = 0x08, + /// ACE was inherited + Inherited = 0x10, + /// Audit successful access + SuccessfulAccess = 0x40, + /// Audit failed access + FailedAccess = 0x80 + } + +#endregion + +#region Nested type: AccessRights + + /// NTFS access rights masks (32-bit) + [Flags] + enum AccessRights : uint + { + /// Read file data / list directory contents + ReadData = 0x00000001, + /// Write file data / create file in directory + WriteData = 0x00000002, + /// Append data / create subdirectory + AppendData = 0x00000004, + /// Read extended attributes + ReadEa = 0x00000008, + /// Write extended attributes + WriteEa = 0x00000010, + /// Execute file / traverse directory + Execute = 0x00000020, + /// Delete children in directory + DeleteChild = 0x00000040, + /// Read attributes + ReadAttributes = 0x00000080, + /// Write attributes + WriteAttributes = 0x00000100, + /// Delete object + Delete = 0x00010000, + /// Read security descriptor / owner + ReadControl = 0x00020000, + /// Modify DACL + WriteDac = 0x00040000, + /// Change owner + WriteOwner = 0x00080000, + /// Synchronize + Synchronize = 0x00100000, + /// Access system ACL + AccessSystemSecurity = 0x01000000, + /// Maximum allowed access + MaximumAllowed = 0x02000000, + /// Full access + GenericAll = 0x10000000, + /// Generic execute + GenericExecute = 0x20000000, + /// Generic write + GenericWrite = 0x40000000, + /// Generic read + GenericRead = 0x80000000 + } + +#endregion + +#region Nested type: ObjectAceFlags + + /// Object ACE flags (32-bit) + [Flags] + enum ObjectAceFlags : uint + { + /// Object type GUID present + ObjectTypePresent = 1, + /// Inherited object type GUID present + InheritedObjectTypePresent = 2 + } + +#endregion + +#region Nested type: ReparseTag + + /// Reparse point tag values (32-bit) + [Flags] + enum ReparseTag : uint + { + /// Directory bit + Directory = 0x10000000, + /// Name surrogate bit (alias) + IsAlias = 0x20000000, + /// High-latency bit + IsHighLatency = 0x40000000, + /// Microsoft-owned tag + IsMicrosoft = 0x80000000, + /// CSV + Csv = 0x80000009, + /// Dedup + Dedup = 0x80000013, + /// DFS + Dfs = 0x8000000A, + /// DFSR + Dfsr = 0x80000012, + /// HSM + Hsm = 0xC0000004, + /// HSM2 + Hsm2 = 0x80000006, + /// Junction / mount point + MountPoint = 0xA0000003, + /// NFS + Nfs = 0x80000014, + /// SIS + Sis = 0x80000007, + /// Symbolic link + Symlink = 0xA000000C, + /// WIM + Wim = 0x80000008, + /// DFM + Dfm = 0x80000016, + /// Windows Overlay Filter + Wof = 0x80000017, + /// WCI + Wci = 0x80000018, + /// Cloud + Cloud = 0x9000001A, + /// App execution link + AppExecLink = 0x8000001B, + /// GVFS + Gvfs = 0x9000001C, + /// WSL symlink + LxSymlink = 0xA000001D, + /// WSL AF_UNIX socket + AfUnix = 0x80000023, + /// WSL FIFO + LxFifo = 0x80000024, + /// WSL character device + LxChr = 0x80000025, + /// WSL block device + LxBlk = 0x80000026 + } + +#endregion + +#region Nested type: QuotaFlags + + /// Quota entry flags (32-bit) + [Flags] + enum QuotaFlags : uint + { + /// Use default limits + DefaultLimits = 0x00000001, + /// Quota limit reached + LimitReached = 0x00000002, + /// Quota ID deleted + IdDeleted = 0x00000004, + /// Quota tracking enabled + TrackingEnabled = 0x00000010, + /// Quota enforcement enabled + EnforcementEnabled = 0x00000020, + /// Tracking requested + TrackingRequested = 0x00000040, + /// Log when threshold reached + LogThreshold = 0x00000080, + /// Log when limit reached + LogLimit = 0x00000100, + /// Quota data out of date + OutOfDate = 0x00000200, + /// Quota entry corrupt + Corrupt = 0x00000400, + /// Pending quota deletes + PendingDeletes = 0x00000800 + } + +#endregion + +#region Nested type: EaFlags + + /// Extended attribute flags (8-bit) + [Flags] + enum EaFlags : byte + { + /// Critical EA — file cannot be properly interpreted without understanding this EA + NeedEa = 0x80 + } + +#endregion + +#region Nested type: RestartFlags + + /// LogFile restart area flags (16-bit) + [Flags] + enum RestartFlags : ushort + { + /// Volume is clean + VolumeIsClean = 0x0002 + } + +#endregion +} \ No newline at end of file diff --git a/Aaru.Filesystems/NTFS/Structs.cs b/Aaru.Filesystems/NTFS/Structs.cs index 381ec6c30..eabae296f 100644 --- a/Aaru.Filesystems/NTFS/Structs.cs +++ b/Aaru.Filesystems/NTFS/Structs.cs @@ -26,11 +26,12 @@ // Copyright © 2011-2026 Natalia Portillo // ****************************************************************************/ +using System; using System.Runtime.InteropServices; namespace Aaru.Filesystems; -// Information from Inside Windows NT +// Information from Inside Windows NT and the Linux kernel NTFS driver (fs/ntfs) /// /// Implements detection of the New Technology File System (NTFS) public sealed partial class NTFS @@ -111,5 +112,715 @@ public sealed partial class NTFS public readonly ushort signature2; } +#endregion + +#region Nested type: NtfsRecordHeader + + /// Common header for all multi-sector protected NTFS records + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct NtfsRecordHeader + { + /// 0x000, Magic identifier (FILE, INDX, RSTR, RCRD, etc.) + public readonly NtfsRecordMagic magic; + /// 0x004, Offset to Update Sequence Array + public readonly ushort usa_ofs; + /// 0x006, Number of USA entries (including USN) + public readonly ushort usa_count; + } + +#endregion + +#region Nested type: MftRecord + + /// MFT record header (NTFS 3.1+, 48 bytes) + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct MftRecord + { + /// 0x000, "FILE" magic + public readonly NtfsRecordMagic magic; + /// 0x004, Offset to Update Sequence Array + public readonly ushort usa_ofs; + /// 0x006, Number of USA entries + public readonly ushort usa_count; + /// 0x008, LogFile sequence number + public readonly ulong lsn; + /// 0x010, Reuse count for this MFT record slot + public readonly ushort sequence_number; + /// 0x012, Number of hard links + public readonly ushort link_count; + /// 0x014, Byte offset to first attribute + public readonly ushort attrs_offset; + /// 0x016, MFT record flags + public readonly MftRecordFlags flags; + /// 0x018, Bytes used in this MFT record + public readonly uint bytes_in_use; + /// 0x01C, Total allocated size of this MFT record + public readonly uint bytes_allocated; + /// 0x020, MFT reference to base record (0 for base records) + public readonly ulong base_mft_record; + /// 0x028, Next attribute instance number + public readonly ushort next_attr_instance; + /// 0x02A, Reserved (NTFS 3.1+) + public readonly ushort reserved; + /// 0x02C, This record's index in $MFT (NTFS 3.1+) + public readonly uint mft_record_number; + } + +#endregion + +#region Nested type: MftRecordOld + + /// MFT record header (pre-NTFS 3.1, 42 bytes) + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct MftRecordOld + { + /// 0x000, "FILE" magic + public readonly NtfsRecordMagic magic; + /// 0x004, Offset to Update Sequence Array + public readonly ushort usa_ofs; + /// 0x006, Number of USA entries + public readonly ushort usa_count; + /// 0x008, LogFile sequence number + public readonly ulong lsn; + /// 0x010, Reuse count for this MFT record slot + public readonly ushort sequence_number; + /// 0x012, Number of hard links + public readonly ushort link_count; + /// 0x014, Byte offset to first attribute + public readonly ushort attrs_offset; + /// 0x016, MFT record flags + public readonly MftRecordFlags flags; + /// 0x018, Bytes used in this MFT record + public readonly uint bytes_in_use; + /// 0x01C, Total allocated size of this MFT record + public readonly uint bytes_allocated; + /// 0x020, MFT reference to base record (0 for base records) + public readonly ulong base_mft_record; + /// 0x028, Next attribute instance number + public readonly ushort next_attr_instance; + } + +#endregion + +#region Nested type: AttrDef + + /// Attribute definition entry ($AttrDef), 160 bytes + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct AttrDef + { + /// 0x000, Unicode attribute name (UTF-16LE, zero-terminated) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x40)] + public readonly ushort[] name; + /// 0x080, Attribute type code + public readonly AttributeType type; + /// 0x084, Default display rule + public readonly uint display_rule; + /// 0x088, Default collation rule + public readonly CollationRule collation_rule; + /// 0x08C, ATTR_DEF_* flags + public readonly AttrDefFlags flags; + /// 0x090, Minimum attribute value size + public readonly ulong min_size; + /// 0x098, Maximum attribute value size + public readonly ulong max_size; + } + +#endregion + +#region Nested type: ResidentAttributeRecord + + /// Resident attribute record header + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct ResidentAttributeRecord + { + /// 0x000, Attribute type + public readonly AttributeType type; + /// 0x004, Total record length + public readonly uint length; + /// 0x008, Always 0 for resident + public readonly byte non_resident; + /// 0x009, Name length in Unicode characters + public readonly byte name_length; + /// 0x00A, Offset to attribute name + public readonly ushort name_offset; + /// 0x00C, Attribute flags + public readonly AttributeFlags flags; + /// 0x00E, Unique instance number + public readonly ushort instance; + /// 0x010, Attribute value size in bytes + public readonly uint value_length; + /// 0x014, Offset to value data + public readonly ushort value_offset; + /// 0x016, Resident attribute flags + public readonly ResidentAttributeFlags resident_flags; + /// 0x017, Reserved + public readonly sbyte reserved; + } + +#endregion + +#region Nested type: NonResidentAttributeRecord + + /// Non-resident attribute record header + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct NonResidentAttributeRecord + { + /// 0x000, Attribute type + public readonly AttributeType type; + /// 0x004, Total record length + public readonly uint length; + /// 0x008, Always 1 for non-resident + public readonly byte non_resident; + /// 0x009, Name length in Unicode characters + public readonly byte name_length; + /// 0x00A, Offset to attribute name + public readonly ushort name_offset; + /// 0x00C, Attribute flags + public readonly AttributeFlags flags; + /// 0x00E, Unique instance number + public readonly ushort instance; + /// 0x010, Lowest VCN + public readonly ulong lowest_vcn; + /// 0x018, Highest VCN + public readonly ulong highest_vcn; + /// 0x020, Offset to mapping pairs array + public readonly ushort mapping_pairs_offset; + /// 0x022, Log2(clusters per compression unit), 0 if uncompressed + public readonly byte compression_unit; + /// 0x023, Reserved + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] + public readonly byte[] reserved; + /// 0x028, Allocated disk space in bytes + public readonly ulong allocated_size; + /// 0x030, Logical attribute value size in bytes + public readonly ulong data_size; + /// 0x038, Initialized portion size in bytes + public readonly ulong initialized_size; + /// 0x040, Compressed on-disk size (only if compressed/sparse) + public readonly ulong compressed_size; + } + +#endregion + +#region Nested type: StandardInformationV1 + + /// $STANDARD_INFORMATION attribute (NTFS 1.2) + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct StandardInformationV1 + { + /// 0x000, File creation time + public readonly long creation_time; + /// 0x008, Last data modification time + public readonly long last_data_change_time; + /// 0x010, Last MFT record change time + public readonly long last_mft_change_time; + /// 0x018, Last access time + public readonly long last_access_time; + /// 0x020, File attribute flags + public readonly FileAttributeFlags file_attributes; + /// 0x024, Reserved (12 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] + public readonly byte[] reserved; + } + +#endregion + +#region Nested type: StandardInformationV3 + + /// $STANDARD_INFORMATION attribute (NTFS 3.0+) + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct StandardInformationV3 + { + /// 0x000, File creation time + public readonly long creation_time; + /// 0x008, Last data modification time + public readonly long last_data_change_time; + /// 0x010, Last MFT record change time + public readonly long last_mft_change_time; + /// 0x018, Last access time + public readonly long last_access_time; + /// 0x020, File attribute flags + public readonly FileAttributeFlags file_attributes; + /// 0x024, Maximum allowed file versions (0 = versioning disabled) + public readonly uint maximum_versions; + /// 0x028, Current version number + public readonly uint version_number; + /// 0x02C, Class ID + public readonly uint class_id; + /// 0x030, Owner ID (maps to $Quota via $Q index) + public readonly uint owner_id; + /// 0x034, Security ID (maps to $Secure $SII/$SDS) + public readonly uint security_id; + /// 0x038, Quota charge in bytes + public readonly ulong quota_charged; + /// 0x040, Last USN from $UsnJrnl + public readonly ulong usn; + } + +#endregion + +#region Nested type: AttributeListEntry + + /// $ATTRIBUTE_LIST entry + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct AttributeListEntry + { + /// 0x000, Attribute type code + public readonly AttributeType type; + /// 0x004, Entry length (8-byte aligned) + public readonly ushort length; + /// 0x006, Attribute name length in Unicode characters + public readonly byte name_length; + /// 0x007, Offset to attribute name + public readonly byte name_offset; + /// 0x008, Lowest VCN of this attribute extent + public readonly ulong lowest_vcn; + /// 0x010, MFT reference to record holding this attribute + public readonly ulong mft_reference; + /// 0x018, Attribute instance number + public readonly ushort instance; + } + +#endregion + +#region Nested type: FileNameAttribute + + /// $FILE_NAME attribute (type 0x30), always resident + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct FileNameAttribute + { + /// 0x000, MFT reference to parent directory + public readonly ulong parent_directory; + /// 0x008, File creation time + public readonly long creation_time; + /// 0x010, Last data modification time + public readonly long last_data_change_time; + /// 0x018, Last MFT record change time + public readonly long last_mft_change_time; + /// 0x020, Last access time + public readonly long last_access_time; + /// 0x028, Allocated size of unnamed $DATA + public readonly ulong allocated_size; + /// 0x030, Logical size of unnamed $DATA + public readonly ulong data_size; + /// 0x038, File attribute flags + public readonly FileAttributeFlags file_attributes; + /// 0x03C, EA packed size or reparse point tag + public readonly uint ea_reparse; + /// 0x040, File name length in Unicode characters + public readonly byte file_name_length; + /// 0x041, File name namespace + public readonly FileNameNamespace file_name_type; + } + +#endregion + +#region Nested type: ObjectIdAttribute + + /// $OBJECT_ID attribute (NTFS 3.0+), always resident, 16–64 bytes + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct ObjectIdAttribute + { + /// 0x000, Unique object GUID + public readonly Guid object_id; + /// 0x010, Birth volume GUID (optional) + public readonly Guid birth_volume_id; + /// 0x020, Birth object GUID (optional) + public readonly Guid birth_object_id; + /// 0x030, Domain GUID (optional, usually zero) + public readonly Guid domain_id; + } + +#endregion + +#region Nested type: NtfsSid + + /// Security Identifier (SID) fixed header + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct NtfsSid + { + /// 0x000, SID revision level (usually 1) + public readonly byte revision; + /// 0x001, Number of sub-authorities + public readonly byte sub_authority_count; + /// 0x002, 6-byte identifier authority + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public readonly byte[] identifier_authority; + } + +#endregion + +#region Nested type: NtfsAce + + /// Access Control Entry (ACE) fixed header + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct NtfsAce + { + /// 0x000, ACE type + public readonly AceType type; + /// 0x001, Inheritance and audit flags + public readonly AceFlags flags; + /// 0x002, Total ACE size in bytes + public readonly ushort size; + /// 0x004, Access rights mask + public readonly AccessRights mask; + } + +#endregion + +#region Nested type: NtfsAcl + + /// Access Control List (ACL) header, 8 bytes + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct NtfsAcl + { + /// 0x000, ACL revision (2 or 4) + public readonly byte revision; + /// 0x001, Padding + public readonly byte alignment1; + /// 0x002, Total ACL size in bytes (header + ACEs) + public readonly ushort size; + /// 0x004, Number of ACEs + public readonly ushort ace_count; + /// 0x006, Padding + public readonly ushort alignment2; + } + +#endregion + +#region Nested type: SecurityDescriptorRelative + + /// Self-relative security descriptor, 20 bytes + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct SecurityDescriptorRelative + { + /// 0x000, Revision (usually 1) + public readonly byte revision; + /// 0x001, Padding + public readonly byte alignment; + /// 0x002, Control flags + public readonly SecurityDescriptorControl control; + /// 0x004, Offset to owner SID + public readonly uint owner; + /// 0x008, Offset to group SID + public readonly uint group; + /// 0x00C, Offset to SACL + public readonly uint sacl; + /// 0x010, Offset to DACL + public readonly uint dacl; + } + +#endregion + +#region Nested type: SiiIndexKey + + /// Key for $SII index in $Secure + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct SiiIndexKey + { + /// 0x000, Security identifier + public readonly uint security_id; + } + +#endregion + +#region Nested type: SdhIndexKey + + /// Key for $SDH index in $Secure + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct SdhIndexKey + { + /// 0x000, Hash of security descriptor + public readonly uint hash; + /// 0x004, Security identifier + public readonly uint security_id; + } + +#endregion + +#region Nested type: VolumeInformation + + /// $VOLUME_INFORMATION attribute (type 0x70), always resident + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct VolumeInformation + { + /// 0x000, Reserved + public readonly ulong reserved; + /// 0x008, NTFS major version number + public readonly byte major_ver; + /// 0x009, NTFS minor version number + public readonly byte minor_ver; + /// 0x00A, Volume flags + public readonly VolumeFlags flags; + } + +#endregion + +#region Nested type: IndexHeader + + /// Common header for index entries in index root and index blocks + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct IndexHeader + { + /// 0x000, Byte offset to first INDEX_ENTRY (relative to this header) + public readonly uint entries_offset; + /// 0x004, Bytes used by index entries + public readonly uint index_length; + /// 0x008, Total allocated bytes for this index + public readonly uint allocated_size; + /// 0x00C, Index flags (SMALL_INDEX / LARGE_INDEX) + public readonly IndexHeaderFlags flags; + /// 0x00D, Reserved (3 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public readonly byte[] reserved; + } + +#endregion + +#region Nested type: IndexRoot + + /// $INDEX_ROOT attribute (type 0x90), always resident + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct IndexRoot + { + /// 0x000, Attribute type being indexed ($FILE_NAME for directories, 0 for view indexes) + public readonly AttributeType type; + /// 0x004, Collation rule for sorting entries + public readonly CollationRule collation_rule; + /// 0x008, Size of each index block in bytes + public readonly uint index_block_size; + /// 0x00C, Clusters per index block + public readonly byte clusters_per_index_block; + /// 0x00D, Reserved (3 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public readonly byte[] reserved; + /// 0x010, Index header + public readonly IndexHeader index; + } + +#endregion + +#region Nested type: IndexBlock + + /// Index allocation block ($INDEX_ALLOCATION, type 0xa0), 40-byte header + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct IndexBlock + { + /// 0x000, "INDX" magic + public readonly NtfsRecordMagic magic; + /// 0x004, Offset to Update Sequence Array + public readonly ushort usa_ofs; + /// 0x006, Number of USA entries + public readonly ushort usa_count; + /// 0x008, Log sequence number of last modification + public readonly ulong lsn; + /// 0x010, VCN of this index block + public readonly ulong index_block_vcn; + /// 0x018, Index header + public readonly IndexHeader index; + } + +#endregion + +#region Nested type: IndexEntryHeader + + /// Index entry header (fixed 16-byte part of every index entry) + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct IndexEntryHeader + { + /// 0x000, MFT reference of indexed file (directory index) or data offset/length (view index) + public readonly ulong indexed_file_or_data; + /// 0x008, Total entry size in bytes + public readonly ushort length; + /// 0x00A, Key size in bytes + public readonly ushort key_length; + /// 0x00C, Index entry flags + public readonly IndexEntryFlags flags; + /// 0x00E, Reserved + public readonly ushort reserved; + } + +#endregion + +#region Nested type: ReparseIndexKey + + /// Key for $R index in $Extend/$Reparse + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct ReparseIndexKey + { + /// 0x000, Reparse point tag + public readonly ReparseTag reparse_tag; + /// 0x004, MFT record number of the file + public readonly ulong file_id; + } + +#endregion + +#region Nested type: ReparsePointAttribute + + /// $REPARSE_POINT attribute (type 0xc0) + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct ReparsePointAttribute + { + /// 0x000, Reparse point type and flags + public readonly ReparseTag reparse_tag; + /// 0x004, Size of reparse data in bytes + public readonly ushort reparse_data_length; + /// 0x006, Reserved + public readonly ushort reserved; + } + +#endregion + +#region Nested type: EaInformation + + /// $EA_INFORMATION attribute (type 0xd0), always resident + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct EaInformation + { + /// 0x000, Packed EA size in bytes + public readonly ushort ea_length; + /// 0x002, Number of EAs with NEED_EA flag set + public readonly ushort need_ea_count; + /// 0x004, Unpacked EA query size in bytes + public readonly uint ea_query_length; + } + +#endregion + +#region Nested type: EaAttribute + + /// Extended attribute entry ($EA, type 0xe0) fixed header + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct EaAttribute + { + /// 0x000, Offset to next EA entry + public readonly uint next_entry_offset; + /// 0x004, EA flags (NEED_EA = 0x80) + public readonly EaFlags flags; + /// 0x005, EA name length in bytes (excluding NUL terminator) + public readonly byte ea_name_length; + /// 0x006, EA value length in bytes + public readonly ushort ea_value_length; + } + +#endregion + +#region Nested type: QuotaControlEntry + + /// Quota control entry in $Quota/$Q (fixed part) + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct QuotaControlEntry + { + /// 0x000, Version (currently 2) + public readonly uint version; + /// 0x004, Quota flags + public readonly QuotaFlags flags; + /// 0x008, Current quota usage in bytes + public readonly ulong bytes_used; + /// 0x010, Last modification time + public readonly long change_time; + /// 0x018, Soft quota limit (-1 = unlimited) + public readonly long threshold; + /// 0x020, Hard quota limit (-1 = unlimited) + public readonly long limit; + /// 0x028, Time when soft quota was exceeded + public readonly long exceeded_time; + } + +#endregion + +#region Nested type: RestartPageHeader + + /// LogFile restart page header ($LogFile, magic "RSTR") + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct RestartPageHeader + { + /// 0x000, "RSTR" magic + public readonly NtfsRecordMagic magic; + /// 0x004, Offset to Update Sequence Array + public readonly ushort usa_ofs; + /// 0x006, Number of USA entries + public readonly ushort usa_count; + /// 0x008, Last LSN found by chkdsk + public readonly ulong chkdsk_lsn; + /// 0x010, System page size in bytes + public readonly uint system_page_size; + /// 0x014, Log page size in bytes + public readonly uint log_page_size; + /// 0x018, Byte offset to restart area + public readonly ushort restart_area_offset; + /// 0x01A, Log file minor version + public readonly ushort minor_ver; + /// 0x01C, Log file major version + public readonly ushort major_ver; + } + +#endregion + +#region Nested type: RestartArea + + /// LogFile restart area record + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct RestartArea + { + /// 0x000, Current/last LSN + public readonly ulong current_lsn; + /// 0x008, Number of log client records + public readonly ushort log_clients; + /// 0x00A, Index of first free client record + public readonly ushort client_free_list; + /// 0x00C, Index of first in-use client record + public readonly ushort client_in_use_list; + /// 0x00E, Restart area flags + public readonly RestartFlags flags; + /// 0x010, Bits used for sequence number + public readonly uint seq_number_bits; + /// 0x014, Length of restart area including client array + public readonly ushort restart_area_length; + /// 0x016, Offset to first log client record + public readonly ushort client_array_offset; + /// 0x018, Usable log file size in bytes + public readonly ulong file_size; + /// 0x020, Last LSN data length + public readonly uint last_lsn_data_length; + /// 0x024, Log record header size + public readonly ushort log_record_header_length; + /// 0x026, Offset to data in log page + public readonly ushort log_page_data_offset; + /// 0x028, Log open count (incremented each mount) + public readonly uint restart_log_open_count; + /// 0x02C, Reserved + public readonly uint reserved; + } + +#endregion + +#region Nested type: LogClientRecord + + /// LogFile client record + [StructLayout(LayoutKind.Sequential, Pack = 1)] + readonly struct LogClientRecord + { + /// 0x000, Oldest LSN needed by this client + public readonly ulong oldest_lsn; + /// 0x008, Client restart position LSN + public readonly ulong client_restart_lsn; + /// 0x010, Previous client record index + public readonly ushort prev_client; + /// 0x012, Next client record index + public readonly ushort next_client; + /// 0x014, Sequence number + public readonly ushort seq_number; + /// 0x016, Reserved (6 bytes) + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public readonly byte[] reserved; + /// 0x01C, Client name length in bytes + public readonly uint client_name_length; + /// 0x020, Client name in Unicode (usually "NTFS") + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public readonly ushort[] client_name; + } + #endregion } \ No newline at end of file