[ntfs] Added missing on-disk structures.

This commit is contained in:
2026-03-01 13:43:48 +00:00
parent ec7f25e745
commit 4b6c563e85
2 changed files with 1339 additions and 1 deletions

View File

@@ -0,0 +1,627 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Enums.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2026 Natalia Portillo
// ****************************************************************************/
using System;
namespace Aaru.Filesystems;
/// <inheritdoc />
public sealed partial class NTFS
{
#region Nested type: NtfsRecordMagic
/// <summary>Magic identifiers present at the beginning of all multi-sector protected NTFS records</summary>
enum NtfsRecordMagic : uint
{
/// <summary>MFT entry ("FILE")</summary>
File = 0x454c4946,
/// <summary>Index buffer ("INDX")</summary>
Indx = 0x58444e49,
/// <summary>Hole marker ("HOLE")</summary>
Hole = 0x454c4f48,
/// <summary>Restart page ("RSTR")</summary>
Rstr = 0x52545352,
/// <summary>Log record page ("RCRD")</summary>
Rcrd = 0x44524352,
/// <summary>Chkdsk modified ("CHKD")</summary>
Chkd = 0x444b4843,
/// <summary>Bad record ("BAAD")</summary>
Baad = 0x44414142,
/// <summary>Empty/uninitialized</summary>
Empty = 0xffffffff
}
#endregion
#region Nested type: SystemFileNumber
/// <summary>System files MFT record numbers</summary>
enum SystemFileNumber : uint
{
/// <summary>Master File Table ($MFT)</summary>
Mft = 0,
/// <summary>MFT mirror ($MFTMirr)</summary>
MftMirr = 1,
/// <summary>Journaling log ($LogFile)</summary>
LogFile = 2,
/// <summary>Volume information ($Volume)</summary>
Volume = 3,
/// <summary>Attribute definitions ($AttrDef)</summary>
AttrDef = 4,
/// <summary>Root directory</summary>
Root = 5,
/// <summary>Cluster allocation bitmap ($Bitmap)</summary>
Bitmap = 6,
/// <summary>Boot sector ($Boot)</summary>
Boot = 7,
/// <summary>Bad cluster list ($BadClus)</summary>
BadClus = 8,
/// <summary>Security descriptors ($Secure)</summary>
Secure = 9,
/// <summary>Uppercase table ($UpCase)</summary>
UpCase = 10,
/// <summary>Extended system directory ($Extend)</summary>
Extend = 11,
/// <summary>First user file record</summary>
FirstUser = 16
}
#endregion
#region Nested type: MftRecordFlags
/// <summary>MFT record flags (16-bit)</summary>
[Flags]
enum MftRecordFlags : ushort
{
/// <summary>Record is allocated and in use</summary>
InUse = 0x0001,
/// <summary>Record represents a directory</summary>
IsDirectory = 0x0002,
/// <summary>Special record 4 type</summary>
Is4 = 0x0004,
/// <summary>Used as view index</summary>
IsViewIndex = 0x0008
}
#endregion
#region Nested type: AttributeType
/// <summary>System-defined attribute types (32-bit)</summary>
enum AttributeType : uint
{
/// <summary>Unused</summary>
Unused = 0x00,
/// <summary>$STANDARD_INFORMATION</summary>
StandardInformation = 0x10,
/// <summary>$ATTRIBUTE_LIST</summary>
AttributeList = 0x20,
/// <summary>$FILE_NAME</summary>
FileName = 0x30,
/// <summary>$OBJECT_ID (NTFS 3.0+) / $VOLUME_VERSION (NTFS 1.2)</summary>
ObjectId = 0x40,
/// <summary>$SECURITY_DESCRIPTOR</summary>
SecurityDescriptor = 0x50,
/// <summary>$VOLUME_NAME</summary>
VolumeName = 0x60,
/// <summary>$VOLUME_INFORMATION</summary>
VolumeInformation = 0x70,
/// <summary>$DATA</summary>
Data = 0x80,
/// <summary>$INDEX_ROOT</summary>
IndexRoot = 0x90,
/// <summary>$INDEX_ALLOCATION</summary>
IndexAllocation = 0xa0,
/// <summary>$BITMAP</summary>
Bitmap = 0xb0,
/// <summary>$REPARSE_POINT (NTFS 3.0+) / $SYMBOLIC_LINK (NTFS 1.2)</summary>
ReparsePoint = 0xc0,
/// <summary>$EA_INFORMATION</summary>
EaInformation = 0xd0,
/// <summary>$EA</summary>
Ea = 0xe0,
/// <summary>$PROPERTY_SET</summary>
PropertySet = 0xf0,
/// <summary>$LOGGED_UTILITY_STREAM (NTFS 3.0+)</summary>
LoggedUtilityStream = 0x100,
/// <summary>First user-defined attribute</summary>
FirstUserDefined = 0x1000,
/// <summary>End marker</summary>
End = 0xffffffff
}
#endregion
#region Nested type: CollationRule
/// <summary>Collation rules for sorting views and indexes (32-bit)</summary>
enum CollationRule : uint
{
/// <summary>Binary compare (first byte most significant)</summary>
Binary = 0x00,
/// <summary>File name collation</summary>
FileName = 0x01,
/// <summary>Unicode string collation</summary>
UnicodeString = 0x02,
/// <summary>Ascending unsigned 32-bit values</summary>
NtofsUlong = 0x10,
/// <summary>Ascending SID values</summary>
NtofsSid = 0x11,
/// <summary>First by hash then by security_id</summary>
NtofsSecurityHash = 0x12,
/// <summary>Sequence of ascending unsigned 32-bit values</summary>
NtofsUlongs = 0x13
}
#endregion
#region Nested type: AttrDefFlags
/// <summary>Attribute definition flags (32-bit)</summary>
[Flags]
enum AttrDefFlags : uint
{
/// <summary>Attribute can be indexed</summary>
Indexable = 0x02,
/// <summary>Attribute can be present multiple times</summary>
Multiple = 0x04,
/// <summary>Attribute value must contain at least one non-zero byte</summary>
NotZero = 0x08,
/// <summary>Attribute must be indexed and the value must be unique</summary>
IndexedUnique = 0x10,
/// <summary>Attribute must be named and the name must be unique</summary>
NamedUnique = 0x20,
/// <summary>Attribute must be resident</summary>
Resident = 0x40,
/// <summary>Always log modifications to this attribute</summary>
AlwaysLog = 0x80
}
#endregion
#region Nested type: AttributeFlags
/// <summary>Attribute flags (16-bit)</summary>
[Flags]
enum AttributeFlags : ushort
{
/// <summary>Attribute is compressed</summary>
Compressed = 0x0001,
/// <summary>Compression method mask</summary>
CompressionMask = 0x00ff,
/// <summary>Attribute is encrypted</summary>
Encrypted = 0x4000,
/// <summary>Attribute is sparse</summary>
Sparse = 0x8000
}
#endregion
#region Nested type: ResidentAttributeFlags
/// <summary>Resident attribute flags (8-bit)</summary>
[Flags]
enum ResidentAttributeFlags : byte
{
/// <summary>Attribute is referenced in an index</summary>
Indexed = 0x01
}
#endregion
#region Nested type: FileAttributeFlags
/// <summary>File attribute flags (32-bit)</summary>
[Flags]
enum FileAttributeFlags : uint
{
/// <summary>File is read-only</summary>
ReadOnly = 0x00000001,
/// <summary>File is hidden</summary>
Hidden = 0x00000002,
/// <summary>System file</summary>
System = 0x00000004,
/// <summary>Directory</summary>
Directory = 0x00000010,
/// <summary>File needs archiving</summary>
Archive = 0x00000020,
/// <summary>Device file</summary>
Device = 0x00000040,
/// <summary>Normal file (no special attributes)</summary>
Normal = 0x00000080,
/// <summary>Temporary file</summary>
Temporary = 0x00000100,
/// <summary>Sparse file</summary>
SparseFile = 0x00000200,
/// <summary>Reparse point</summary>
ReparsePoint = 0x00000400,
/// <summary>File is compressed</summary>
Compressed = 0x00000800,
/// <summary>File data is offline</summary>
Offline = 0x00001000,
/// <summary>File is excluded from content indexing</summary>
NotContentIndexed = 0x00002000,
/// <summary>File is encrypted</summary>
Encrypted = 0x00004000,
/// <summary>Recall data on open (cloud/HSM)</summary>
RecallOnOpen = 0x00040000,
/// <summary>Duplicate file name index present</summary>
DupFileNameIndexPresent = 0x10000000,
/// <summary>Duplicate view index present</summary>
DupViewIndexPresent = 0x20000000
}
#endregion
#region Nested type: FileNameNamespace
/// <summary>Possible namespaces for file names in NTFS (8-bit)</summary>
enum FileNameNamespace : byte
{
/// <summary>POSIX namespace (case sensitive, most permissive)</summary>
Posix = 0x00,
/// <summary>Win32 namespace (case insensitive)</summary>
Win32 = 0x01,
/// <summary>DOS 8.3 namespace</summary>
Dos = 0x02,
/// <summary>Win32 and DOS names are identical</summary>
Win32AndDos = 0x03
}
#endregion
#region Nested type: VolumeFlags
/// <summary>NTFS volume flags (16-bit)</summary>
[Flags]
enum VolumeFlags : ushort
{
/// <summary>Volume is dirty (needs chkdsk)</summary>
IsDirty = 0x0001,
/// <summary>Resize LogFile on next mount</summary>
ResizeLogFile = 0x0002,
/// <summary>Upgrade volume on mount</summary>
UpgradeOnMount = 0x0004,
/// <summary>Mounted on NT4</summary>
MountedOnNt4 = 0x0008,
/// <summary>USN journal deletion in progress</summary>
DeleteUsnUnderway = 0x0010,
/// <summary>Repair $ObjId on next mount</summary>
RepairObjectId = 0x0020,
/// <summary>Chkdsk is running</summary>
ChkdskUnderway = 0x4000,
/// <summary>Volume modified by chkdsk</summary>
ModifiedByChkdsk = 0x8000
}
#endregion
#region Nested type: IndexHeaderFlags
/// <summary>Index header flags (8-bit)</summary>
[Flags]
enum IndexHeaderFlags : byte
{
/// <summary>Small index / leaf node</summary>
SmallIndex = 0,
/// <summary>Large index / internal node with sub-nodes</summary>
LargeIndex = 1
}
#endregion
#region Nested type: IndexEntryFlags
/// <summary>Index entry flags (16-bit)</summary>
[Flags]
enum IndexEntryFlags : ushort
{
/// <summary>Entry points to a sub-node (index block VCN)</summary>
Node = 0x0001,
/// <summary>Last entry in index block/root</summary>
End = 0x0002
}
#endregion
#region Nested type: SecurityDescriptorControl
/// <summary>Security descriptor control flags (16-bit)</summary>
[Flags]
enum SecurityDescriptorControl : ushort
{
/// <summary>Owner was defaulted</summary>
OwnerDefaulted = 0x0001,
/// <summary>Group was defaulted</summary>
GroupDefaulted = 0x0002,
/// <summary>DACL present</summary>
DaclPresent = 0x0004,
/// <summary>DACL was defaulted</summary>
DaclDefaulted = 0x0008,
/// <summary>SACL present</summary>
SaclPresent = 0x0010,
/// <summary>SACL was defaulted</summary>
SaclDefaulted = 0x0020,
/// <summary>DACL auto-inherit requested</summary>
DaclAutoInheritReq = 0x0100,
/// <summary>SACL auto-inherit requested</summary>
SaclAutoInheritReq = 0x0200,
/// <summary>DACL was auto-inherited</summary>
DaclAutoInherited = 0x0400,
/// <summary>SACL was auto-inherited</summary>
SaclAutoInherited = 0x0800,
/// <summary>DACL is protected from inheritance</summary>
DaclProtected = 0x1000,
/// <summary>SACL is protected from inheritance</summary>
SaclProtected = 0x2000,
/// <summary>RM control valid</summary>
RmControlValid = 0x4000,
/// <summary>Self-relative format</summary>
SelfRelative = 0x8000
}
#endregion
#region Nested type: AceType
/// <summary>ACE types (8-bit)</summary>
enum AceType : byte
{
/// <summary>Allow access</summary>
AccessAllowed = 0,
/// <summary>Deny access</summary>
AccessDenied = 1,
/// <summary>Audit access</summary>
SystemAudit = 2,
/// <summary>Alarm on access</summary>
SystemAlarm = 3,
/// <summary>Compound ACE (legacy)</summary>
AccessAllowedCompound = 4,
/// <summary>Allow with object-specific rights</summary>
AccessAllowedObject = 5,
/// <summary>Deny with object-specific rights</summary>
AccessDeniedObject = 6,
/// <summary>Audit with object-specific rights</summary>
SystemAuditObject = 7,
/// <summary>Alarm with object-specific rights</summary>
SystemAlarmObject = 8
}
#endregion
#region Nested type: AceFlags
/// <summary>ACE inheritance and audit flags (8-bit)</summary>
[Flags]
enum AceFlags : byte
{
/// <summary>Files inherit this ACE</summary>
ObjectInherit = 0x01,
/// <summary>Subdirectories inherit this ACE</summary>
ContainerInherit = 0x02,
/// <summary>Stop inheritance after this level</summary>
NoPropagateInherit = 0x04,
/// <summary>Inherit only (not applied to current object)</summary>
InheritOnly = 0x08,
/// <summary>ACE was inherited</summary>
Inherited = 0x10,
/// <summary>Audit successful access</summary>
SuccessfulAccess = 0x40,
/// <summary>Audit failed access</summary>
FailedAccess = 0x80
}
#endregion
#region Nested type: AccessRights
/// <summary>NTFS access rights masks (32-bit)</summary>
[Flags]
enum AccessRights : uint
{
/// <summary>Read file data / list directory contents</summary>
ReadData = 0x00000001,
/// <summary>Write file data / create file in directory</summary>
WriteData = 0x00000002,
/// <summary>Append data / create subdirectory</summary>
AppendData = 0x00000004,
/// <summary>Read extended attributes</summary>
ReadEa = 0x00000008,
/// <summary>Write extended attributes</summary>
WriteEa = 0x00000010,
/// <summary>Execute file / traverse directory</summary>
Execute = 0x00000020,
/// <summary>Delete children in directory</summary>
DeleteChild = 0x00000040,
/// <summary>Read attributes</summary>
ReadAttributes = 0x00000080,
/// <summary>Write attributes</summary>
WriteAttributes = 0x00000100,
/// <summary>Delete object</summary>
Delete = 0x00010000,
/// <summary>Read security descriptor / owner</summary>
ReadControl = 0x00020000,
/// <summary>Modify DACL</summary>
WriteDac = 0x00040000,
/// <summary>Change owner</summary>
WriteOwner = 0x00080000,
/// <summary>Synchronize</summary>
Synchronize = 0x00100000,
/// <summary>Access system ACL</summary>
AccessSystemSecurity = 0x01000000,
/// <summary>Maximum allowed access</summary>
MaximumAllowed = 0x02000000,
/// <summary>Full access</summary>
GenericAll = 0x10000000,
/// <summary>Generic execute</summary>
GenericExecute = 0x20000000,
/// <summary>Generic write</summary>
GenericWrite = 0x40000000,
/// <summary>Generic read</summary>
GenericRead = 0x80000000
}
#endregion
#region Nested type: ObjectAceFlags
/// <summary>Object ACE flags (32-bit)</summary>
[Flags]
enum ObjectAceFlags : uint
{
/// <summary>Object type GUID present</summary>
ObjectTypePresent = 1,
/// <summary>Inherited object type GUID present</summary>
InheritedObjectTypePresent = 2
}
#endregion
#region Nested type: ReparseTag
/// <summary>Reparse point tag values (32-bit)</summary>
[Flags]
enum ReparseTag : uint
{
/// <summary>Directory bit</summary>
Directory = 0x10000000,
/// <summary>Name surrogate bit (alias)</summary>
IsAlias = 0x20000000,
/// <summary>High-latency bit</summary>
IsHighLatency = 0x40000000,
/// <summary>Microsoft-owned tag</summary>
IsMicrosoft = 0x80000000,
/// <summary>CSV</summary>
Csv = 0x80000009,
/// <summary>Dedup</summary>
Dedup = 0x80000013,
/// <summary>DFS</summary>
Dfs = 0x8000000A,
/// <summary>DFSR</summary>
Dfsr = 0x80000012,
/// <summary>HSM</summary>
Hsm = 0xC0000004,
/// <summary>HSM2</summary>
Hsm2 = 0x80000006,
/// <summary>Junction / mount point</summary>
MountPoint = 0xA0000003,
/// <summary>NFS</summary>
Nfs = 0x80000014,
/// <summary>SIS</summary>
Sis = 0x80000007,
/// <summary>Symbolic link</summary>
Symlink = 0xA000000C,
/// <summary>WIM</summary>
Wim = 0x80000008,
/// <summary>DFM</summary>
Dfm = 0x80000016,
/// <summary>Windows Overlay Filter</summary>
Wof = 0x80000017,
/// <summary>WCI</summary>
Wci = 0x80000018,
/// <summary>Cloud</summary>
Cloud = 0x9000001A,
/// <summary>App execution link</summary>
AppExecLink = 0x8000001B,
/// <summary>GVFS</summary>
Gvfs = 0x9000001C,
/// <summary>WSL symlink</summary>
LxSymlink = 0xA000001D,
/// <summary>WSL AF_UNIX socket</summary>
AfUnix = 0x80000023,
/// <summary>WSL FIFO</summary>
LxFifo = 0x80000024,
/// <summary>WSL character device</summary>
LxChr = 0x80000025,
/// <summary>WSL block device</summary>
LxBlk = 0x80000026
}
#endregion
#region Nested type: QuotaFlags
/// <summary>Quota entry flags (32-bit)</summary>
[Flags]
enum QuotaFlags : uint
{
/// <summary>Use default limits</summary>
DefaultLimits = 0x00000001,
/// <summary>Quota limit reached</summary>
LimitReached = 0x00000002,
/// <summary>Quota ID deleted</summary>
IdDeleted = 0x00000004,
/// <summary>Quota tracking enabled</summary>
TrackingEnabled = 0x00000010,
/// <summary>Quota enforcement enabled</summary>
EnforcementEnabled = 0x00000020,
/// <summary>Tracking requested</summary>
TrackingRequested = 0x00000040,
/// <summary>Log when threshold reached</summary>
LogThreshold = 0x00000080,
/// <summary>Log when limit reached</summary>
LogLimit = 0x00000100,
/// <summary>Quota data out of date</summary>
OutOfDate = 0x00000200,
/// <summary>Quota entry corrupt</summary>
Corrupt = 0x00000400,
/// <summary>Pending quota deletes</summary>
PendingDeletes = 0x00000800
}
#endregion
#region Nested type: EaFlags
/// <summary>Extended attribute flags (8-bit)</summary>
[Flags]
enum EaFlags : byte
{
/// <summary>Critical EA — file cannot be properly interpreted without understanding this EA</summary>
NeedEa = 0x80
}
#endregion
#region Nested type: RestartFlags
/// <summary>LogFile restart area flags (16-bit)</summary>
[Flags]
enum RestartFlags : ushort
{
/// <summary>Volume is clean</summary>
VolumeIsClean = 0x0002
}
#endregion
}

View File

@@ -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)
/// <inheritdoc />
/// <summary>Implements detection of the New Technology File System (NTFS)</summary>
public sealed partial class NTFS
@@ -111,5 +112,715 @@ public sealed partial class NTFS
public readonly ushort signature2;
}
#endregion
#region Nested type: NtfsRecordHeader
/// <summary>Common header for all multi-sector protected NTFS records</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct NtfsRecordHeader
{
/// <summary>0x000, Magic identifier (FILE, INDX, RSTR, RCRD, etc.)</summary>
public readonly NtfsRecordMagic magic;
/// <summary>0x004, Offset to Update Sequence Array</summary>
public readonly ushort usa_ofs;
/// <summary>0x006, Number of USA entries (including USN)</summary>
public readonly ushort usa_count;
}
#endregion
#region Nested type: MftRecord
/// <summary>MFT record header (NTFS 3.1+, 48 bytes)</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct MftRecord
{
/// <summary>0x000, "FILE" magic</summary>
public readonly NtfsRecordMagic magic;
/// <summary>0x004, Offset to Update Sequence Array</summary>
public readonly ushort usa_ofs;
/// <summary>0x006, Number of USA entries</summary>
public readonly ushort usa_count;
/// <summary>0x008, LogFile sequence number</summary>
public readonly ulong lsn;
/// <summary>0x010, Reuse count for this MFT record slot</summary>
public readonly ushort sequence_number;
/// <summary>0x012, Number of hard links</summary>
public readonly ushort link_count;
/// <summary>0x014, Byte offset to first attribute</summary>
public readonly ushort attrs_offset;
/// <summary>0x016, MFT record flags</summary>
public readonly MftRecordFlags flags;
/// <summary>0x018, Bytes used in this MFT record</summary>
public readonly uint bytes_in_use;
/// <summary>0x01C, Total allocated size of this MFT record</summary>
public readonly uint bytes_allocated;
/// <summary>0x020, MFT reference to base record (0 for base records)</summary>
public readonly ulong base_mft_record;
/// <summary>0x028, Next attribute instance number</summary>
public readonly ushort next_attr_instance;
/// <summary>0x02A, Reserved (NTFS 3.1+)</summary>
public readonly ushort reserved;
/// <summary>0x02C, This record's index in $MFT (NTFS 3.1+)</summary>
public readonly uint mft_record_number;
}
#endregion
#region Nested type: MftRecordOld
/// <summary>MFT record header (pre-NTFS 3.1, 42 bytes)</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct MftRecordOld
{
/// <summary>0x000, "FILE" magic</summary>
public readonly NtfsRecordMagic magic;
/// <summary>0x004, Offset to Update Sequence Array</summary>
public readonly ushort usa_ofs;
/// <summary>0x006, Number of USA entries</summary>
public readonly ushort usa_count;
/// <summary>0x008, LogFile sequence number</summary>
public readonly ulong lsn;
/// <summary>0x010, Reuse count for this MFT record slot</summary>
public readonly ushort sequence_number;
/// <summary>0x012, Number of hard links</summary>
public readonly ushort link_count;
/// <summary>0x014, Byte offset to first attribute</summary>
public readonly ushort attrs_offset;
/// <summary>0x016, MFT record flags</summary>
public readonly MftRecordFlags flags;
/// <summary>0x018, Bytes used in this MFT record</summary>
public readonly uint bytes_in_use;
/// <summary>0x01C, Total allocated size of this MFT record</summary>
public readonly uint bytes_allocated;
/// <summary>0x020, MFT reference to base record (0 for base records)</summary>
public readonly ulong base_mft_record;
/// <summary>0x028, Next attribute instance number</summary>
public readonly ushort next_attr_instance;
}
#endregion
#region Nested type: AttrDef
/// <summary>Attribute definition entry ($AttrDef), 160 bytes</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct AttrDef
{
/// <summary>0x000, Unicode attribute name (UTF-16LE, zero-terminated)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x40)]
public readonly ushort[] name;
/// <summary>0x080, Attribute type code</summary>
public readonly AttributeType type;
/// <summary>0x084, Default display rule</summary>
public readonly uint display_rule;
/// <summary>0x088, Default collation rule</summary>
public readonly CollationRule collation_rule;
/// <summary>0x08C, ATTR_DEF_* flags</summary>
public readonly AttrDefFlags flags;
/// <summary>0x090, Minimum attribute value size</summary>
public readonly ulong min_size;
/// <summary>0x098, Maximum attribute value size</summary>
public readonly ulong max_size;
}
#endregion
#region Nested type: ResidentAttributeRecord
/// <summary>Resident attribute record header</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct ResidentAttributeRecord
{
/// <summary>0x000, Attribute type</summary>
public readonly AttributeType type;
/// <summary>0x004, Total record length</summary>
public readonly uint length;
/// <summary>0x008, Always 0 for resident</summary>
public readonly byte non_resident;
/// <summary>0x009, Name length in Unicode characters</summary>
public readonly byte name_length;
/// <summary>0x00A, Offset to attribute name</summary>
public readonly ushort name_offset;
/// <summary>0x00C, Attribute flags</summary>
public readonly AttributeFlags flags;
/// <summary>0x00E, Unique instance number</summary>
public readonly ushort instance;
/// <summary>0x010, Attribute value size in bytes</summary>
public readonly uint value_length;
/// <summary>0x014, Offset to value data</summary>
public readonly ushort value_offset;
/// <summary>0x016, Resident attribute flags</summary>
public readonly ResidentAttributeFlags resident_flags;
/// <summary>0x017, Reserved</summary>
public readonly sbyte reserved;
}
#endregion
#region Nested type: NonResidentAttributeRecord
/// <summary>Non-resident attribute record header</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct NonResidentAttributeRecord
{
/// <summary>0x000, Attribute type</summary>
public readonly AttributeType type;
/// <summary>0x004, Total record length</summary>
public readonly uint length;
/// <summary>0x008, Always 1 for non-resident</summary>
public readonly byte non_resident;
/// <summary>0x009, Name length in Unicode characters</summary>
public readonly byte name_length;
/// <summary>0x00A, Offset to attribute name</summary>
public readonly ushort name_offset;
/// <summary>0x00C, Attribute flags</summary>
public readonly AttributeFlags flags;
/// <summary>0x00E, Unique instance number</summary>
public readonly ushort instance;
/// <summary>0x010, Lowest VCN</summary>
public readonly ulong lowest_vcn;
/// <summary>0x018, Highest VCN</summary>
public readonly ulong highest_vcn;
/// <summary>0x020, Offset to mapping pairs array</summary>
public readonly ushort mapping_pairs_offset;
/// <summary>0x022, Log2(clusters per compression unit), 0 if uncompressed</summary>
public readonly byte compression_unit;
/// <summary>0x023, Reserved</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public readonly byte[] reserved;
/// <summary>0x028, Allocated disk space in bytes</summary>
public readonly ulong allocated_size;
/// <summary>0x030, Logical attribute value size in bytes</summary>
public readonly ulong data_size;
/// <summary>0x038, Initialized portion size in bytes</summary>
public readonly ulong initialized_size;
/// <summary>0x040, Compressed on-disk size (only if compressed/sparse)</summary>
public readonly ulong compressed_size;
}
#endregion
#region Nested type: StandardInformationV1
/// <summary>$STANDARD_INFORMATION attribute (NTFS 1.2)</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct StandardInformationV1
{
/// <summary>0x000, File creation time</summary>
public readonly long creation_time;
/// <summary>0x008, Last data modification time</summary>
public readonly long last_data_change_time;
/// <summary>0x010, Last MFT record change time</summary>
public readonly long last_mft_change_time;
/// <summary>0x018, Last access time</summary>
public readonly long last_access_time;
/// <summary>0x020, File attribute flags</summary>
public readonly FileAttributeFlags file_attributes;
/// <summary>0x024, Reserved (12 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public readonly byte[] reserved;
}
#endregion
#region Nested type: StandardInformationV3
/// <summary>$STANDARD_INFORMATION attribute (NTFS 3.0+)</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct StandardInformationV3
{
/// <summary>0x000, File creation time</summary>
public readonly long creation_time;
/// <summary>0x008, Last data modification time</summary>
public readonly long last_data_change_time;
/// <summary>0x010, Last MFT record change time</summary>
public readonly long last_mft_change_time;
/// <summary>0x018, Last access time</summary>
public readonly long last_access_time;
/// <summary>0x020, File attribute flags</summary>
public readonly FileAttributeFlags file_attributes;
/// <summary>0x024, Maximum allowed file versions (0 = versioning disabled)</summary>
public readonly uint maximum_versions;
/// <summary>0x028, Current version number</summary>
public readonly uint version_number;
/// <summary>0x02C, Class ID</summary>
public readonly uint class_id;
/// <summary>0x030, Owner ID (maps to $Quota via $Q index)</summary>
public readonly uint owner_id;
/// <summary>0x034, Security ID (maps to $Secure $SII/$SDS)</summary>
public readonly uint security_id;
/// <summary>0x038, Quota charge in bytes</summary>
public readonly ulong quota_charged;
/// <summary>0x040, Last USN from $UsnJrnl</summary>
public readonly ulong usn;
}
#endregion
#region Nested type: AttributeListEntry
/// <summary>$ATTRIBUTE_LIST entry</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct AttributeListEntry
{
/// <summary>0x000, Attribute type code</summary>
public readonly AttributeType type;
/// <summary>0x004, Entry length (8-byte aligned)</summary>
public readonly ushort length;
/// <summary>0x006, Attribute name length in Unicode characters</summary>
public readonly byte name_length;
/// <summary>0x007, Offset to attribute name</summary>
public readonly byte name_offset;
/// <summary>0x008, Lowest VCN of this attribute extent</summary>
public readonly ulong lowest_vcn;
/// <summary>0x010, MFT reference to record holding this attribute</summary>
public readonly ulong mft_reference;
/// <summary>0x018, Attribute instance number</summary>
public readonly ushort instance;
}
#endregion
#region Nested type: FileNameAttribute
/// <summary>$FILE_NAME attribute (type 0x30), always resident</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct FileNameAttribute
{
/// <summary>0x000, MFT reference to parent directory</summary>
public readonly ulong parent_directory;
/// <summary>0x008, File creation time</summary>
public readonly long creation_time;
/// <summary>0x010, Last data modification time</summary>
public readonly long last_data_change_time;
/// <summary>0x018, Last MFT record change time</summary>
public readonly long last_mft_change_time;
/// <summary>0x020, Last access time</summary>
public readonly long last_access_time;
/// <summary>0x028, Allocated size of unnamed $DATA</summary>
public readonly ulong allocated_size;
/// <summary>0x030, Logical size of unnamed $DATA</summary>
public readonly ulong data_size;
/// <summary>0x038, File attribute flags</summary>
public readonly FileAttributeFlags file_attributes;
/// <summary>0x03C, EA packed size or reparse point tag</summary>
public readonly uint ea_reparse;
/// <summary>0x040, File name length in Unicode characters</summary>
public readonly byte file_name_length;
/// <summary>0x041, File name namespace</summary>
public readonly FileNameNamespace file_name_type;
}
#endregion
#region Nested type: ObjectIdAttribute
/// <summary>$OBJECT_ID attribute (NTFS 3.0+), always resident, 1664 bytes</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct ObjectIdAttribute
{
/// <summary>0x000, Unique object GUID</summary>
public readonly Guid object_id;
/// <summary>0x010, Birth volume GUID (optional)</summary>
public readonly Guid birth_volume_id;
/// <summary>0x020, Birth object GUID (optional)</summary>
public readonly Guid birth_object_id;
/// <summary>0x030, Domain GUID (optional, usually zero)</summary>
public readonly Guid domain_id;
}
#endregion
#region Nested type: NtfsSid
/// <summary>Security Identifier (SID) fixed header</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct NtfsSid
{
/// <summary>0x000, SID revision level (usually 1)</summary>
public readonly byte revision;
/// <summary>0x001, Number of sub-authorities</summary>
public readonly byte sub_authority_count;
/// <summary>0x002, 6-byte identifier authority</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public readonly byte[] identifier_authority;
}
#endregion
#region Nested type: NtfsAce
/// <summary>Access Control Entry (ACE) fixed header</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct NtfsAce
{
/// <summary>0x000, ACE type</summary>
public readonly AceType type;
/// <summary>0x001, Inheritance and audit flags</summary>
public readonly AceFlags flags;
/// <summary>0x002, Total ACE size in bytes</summary>
public readonly ushort size;
/// <summary>0x004, Access rights mask</summary>
public readonly AccessRights mask;
}
#endregion
#region Nested type: NtfsAcl
/// <summary>Access Control List (ACL) header, 8 bytes</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct NtfsAcl
{
/// <summary>0x000, ACL revision (2 or 4)</summary>
public readonly byte revision;
/// <summary>0x001, Padding</summary>
public readonly byte alignment1;
/// <summary>0x002, Total ACL size in bytes (header + ACEs)</summary>
public readonly ushort size;
/// <summary>0x004, Number of ACEs</summary>
public readonly ushort ace_count;
/// <summary>0x006, Padding</summary>
public readonly ushort alignment2;
}
#endregion
#region Nested type: SecurityDescriptorRelative
/// <summary>Self-relative security descriptor, 20 bytes</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct SecurityDescriptorRelative
{
/// <summary>0x000, Revision (usually 1)</summary>
public readonly byte revision;
/// <summary>0x001, Padding</summary>
public readonly byte alignment;
/// <summary>0x002, Control flags</summary>
public readonly SecurityDescriptorControl control;
/// <summary>0x004, Offset to owner SID</summary>
public readonly uint owner;
/// <summary>0x008, Offset to group SID</summary>
public readonly uint group;
/// <summary>0x00C, Offset to SACL</summary>
public readonly uint sacl;
/// <summary>0x010, Offset to DACL</summary>
public readonly uint dacl;
}
#endregion
#region Nested type: SiiIndexKey
/// <summary>Key for $SII index in $Secure</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct SiiIndexKey
{
/// <summary>0x000, Security identifier</summary>
public readonly uint security_id;
}
#endregion
#region Nested type: SdhIndexKey
/// <summary>Key for $SDH index in $Secure</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct SdhIndexKey
{
/// <summary>0x000, Hash of security descriptor</summary>
public readonly uint hash;
/// <summary>0x004, Security identifier</summary>
public readonly uint security_id;
}
#endregion
#region Nested type: VolumeInformation
/// <summary>$VOLUME_INFORMATION attribute (type 0x70), always resident</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct VolumeInformation
{
/// <summary>0x000, Reserved</summary>
public readonly ulong reserved;
/// <summary>0x008, NTFS major version number</summary>
public readonly byte major_ver;
/// <summary>0x009, NTFS minor version number</summary>
public readonly byte minor_ver;
/// <summary>0x00A, Volume flags</summary>
public readonly VolumeFlags flags;
}
#endregion
#region Nested type: IndexHeader
/// <summary>Common header for index entries in index root and index blocks</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct IndexHeader
{
/// <summary>0x000, Byte offset to first INDEX_ENTRY (relative to this header)</summary>
public readonly uint entries_offset;
/// <summary>0x004, Bytes used by index entries</summary>
public readonly uint index_length;
/// <summary>0x008, Total allocated bytes for this index</summary>
public readonly uint allocated_size;
/// <summary>0x00C, Index flags (SMALL_INDEX / LARGE_INDEX)</summary>
public readonly IndexHeaderFlags flags;
/// <summary>0x00D, Reserved (3 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public readonly byte[] reserved;
}
#endregion
#region Nested type: IndexRoot
/// <summary>$INDEX_ROOT attribute (type 0x90), always resident</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct IndexRoot
{
/// <summary>0x000, Attribute type being indexed ($FILE_NAME for directories, 0 for view indexes)</summary>
public readonly AttributeType type;
/// <summary>0x004, Collation rule for sorting entries</summary>
public readonly CollationRule collation_rule;
/// <summary>0x008, Size of each index block in bytes</summary>
public readonly uint index_block_size;
/// <summary>0x00C, Clusters per index block</summary>
public readonly byte clusters_per_index_block;
/// <summary>0x00D, Reserved (3 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public readonly byte[] reserved;
/// <summary>0x010, Index header</summary>
public readonly IndexHeader index;
}
#endregion
#region Nested type: IndexBlock
/// <summary>Index allocation block ($INDEX_ALLOCATION, type 0xa0), 40-byte header</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct IndexBlock
{
/// <summary>0x000, "INDX" magic</summary>
public readonly NtfsRecordMagic magic;
/// <summary>0x004, Offset to Update Sequence Array</summary>
public readonly ushort usa_ofs;
/// <summary>0x006, Number of USA entries</summary>
public readonly ushort usa_count;
/// <summary>0x008, Log sequence number of last modification</summary>
public readonly ulong lsn;
/// <summary>0x010, VCN of this index block</summary>
public readonly ulong index_block_vcn;
/// <summary>0x018, Index header</summary>
public readonly IndexHeader index;
}
#endregion
#region Nested type: IndexEntryHeader
/// <summary>Index entry header (fixed 16-byte part of every index entry)</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct IndexEntryHeader
{
/// <summary>0x000, MFT reference of indexed file (directory index) or data offset/length (view index)</summary>
public readonly ulong indexed_file_or_data;
/// <summary>0x008, Total entry size in bytes</summary>
public readonly ushort length;
/// <summary>0x00A, Key size in bytes</summary>
public readonly ushort key_length;
/// <summary>0x00C, Index entry flags</summary>
public readonly IndexEntryFlags flags;
/// <summary>0x00E, Reserved</summary>
public readonly ushort reserved;
}
#endregion
#region Nested type: ReparseIndexKey
/// <summary>Key for $R index in $Extend/$Reparse</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct ReparseIndexKey
{
/// <summary>0x000, Reparse point tag</summary>
public readonly ReparseTag reparse_tag;
/// <summary>0x004, MFT record number of the file</summary>
public readonly ulong file_id;
}
#endregion
#region Nested type: ReparsePointAttribute
/// <summary>$REPARSE_POINT attribute (type 0xc0)</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct ReparsePointAttribute
{
/// <summary>0x000, Reparse point type and flags</summary>
public readonly ReparseTag reparse_tag;
/// <summary>0x004, Size of reparse data in bytes</summary>
public readonly ushort reparse_data_length;
/// <summary>0x006, Reserved</summary>
public readonly ushort reserved;
}
#endregion
#region Nested type: EaInformation
/// <summary>$EA_INFORMATION attribute (type 0xd0), always resident</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct EaInformation
{
/// <summary>0x000, Packed EA size in bytes</summary>
public readonly ushort ea_length;
/// <summary>0x002, Number of EAs with NEED_EA flag set</summary>
public readonly ushort need_ea_count;
/// <summary>0x004, Unpacked EA query size in bytes</summary>
public readonly uint ea_query_length;
}
#endregion
#region Nested type: EaAttribute
/// <summary>Extended attribute entry ($EA, type 0xe0) fixed header</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct EaAttribute
{
/// <summary>0x000, Offset to next EA entry</summary>
public readonly uint next_entry_offset;
/// <summary>0x004, EA flags (NEED_EA = 0x80)</summary>
public readonly EaFlags flags;
/// <summary>0x005, EA name length in bytes (excluding NUL terminator)</summary>
public readonly byte ea_name_length;
/// <summary>0x006, EA value length in bytes</summary>
public readonly ushort ea_value_length;
}
#endregion
#region Nested type: QuotaControlEntry
/// <summary>Quota control entry in $Quota/$Q (fixed part)</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct QuotaControlEntry
{
/// <summary>0x000, Version (currently 2)</summary>
public readonly uint version;
/// <summary>0x004, Quota flags</summary>
public readonly QuotaFlags flags;
/// <summary>0x008, Current quota usage in bytes</summary>
public readonly ulong bytes_used;
/// <summary>0x010, Last modification time</summary>
public readonly long change_time;
/// <summary>0x018, Soft quota limit (-1 = unlimited)</summary>
public readonly long threshold;
/// <summary>0x020, Hard quota limit (-1 = unlimited)</summary>
public readonly long limit;
/// <summary>0x028, Time when soft quota was exceeded</summary>
public readonly long exceeded_time;
}
#endregion
#region Nested type: RestartPageHeader
/// <summary>LogFile restart page header ($LogFile, magic "RSTR")</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct RestartPageHeader
{
/// <summary>0x000, "RSTR" magic</summary>
public readonly NtfsRecordMagic magic;
/// <summary>0x004, Offset to Update Sequence Array</summary>
public readonly ushort usa_ofs;
/// <summary>0x006, Number of USA entries</summary>
public readonly ushort usa_count;
/// <summary>0x008, Last LSN found by chkdsk</summary>
public readonly ulong chkdsk_lsn;
/// <summary>0x010, System page size in bytes</summary>
public readonly uint system_page_size;
/// <summary>0x014, Log page size in bytes</summary>
public readonly uint log_page_size;
/// <summary>0x018, Byte offset to restart area</summary>
public readonly ushort restart_area_offset;
/// <summary>0x01A, Log file minor version</summary>
public readonly ushort minor_ver;
/// <summary>0x01C, Log file major version</summary>
public readonly ushort major_ver;
}
#endregion
#region Nested type: RestartArea
/// <summary>LogFile restart area record</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct RestartArea
{
/// <summary>0x000, Current/last LSN</summary>
public readonly ulong current_lsn;
/// <summary>0x008, Number of log client records</summary>
public readonly ushort log_clients;
/// <summary>0x00A, Index of first free client record</summary>
public readonly ushort client_free_list;
/// <summary>0x00C, Index of first in-use client record</summary>
public readonly ushort client_in_use_list;
/// <summary>0x00E, Restart area flags</summary>
public readonly RestartFlags flags;
/// <summary>0x010, Bits used for sequence number</summary>
public readonly uint seq_number_bits;
/// <summary>0x014, Length of restart area including client array</summary>
public readonly ushort restart_area_length;
/// <summary>0x016, Offset to first log client record</summary>
public readonly ushort client_array_offset;
/// <summary>0x018, Usable log file size in bytes</summary>
public readonly ulong file_size;
/// <summary>0x020, Last LSN data length</summary>
public readonly uint last_lsn_data_length;
/// <summary>0x024, Log record header size</summary>
public readonly ushort log_record_header_length;
/// <summary>0x026, Offset to data in log page</summary>
public readonly ushort log_page_data_offset;
/// <summary>0x028, Log open count (incremented each mount)</summary>
public readonly uint restart_log_open_count;
/// <summary>0x02C, Reserved</summary>
public readonly uint reserved;
}
#endregion
#region Nested type: LogClientRecord
/// <summary>LogFile client record</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct LogClientRecord
{
/// <summary>0x000, Oldest LSN needed by this client</summary>
public readonly ulong oldest_lsn;
/// <summary>0x008, Client restart position LSN</summary>
public readonly ulong client_restart_lsn;
/// <summary>0x010, Previous client record index</summary>
public readonly ushort prev_client;
/// <summary>0x012, Next client record index</summary>
public readonly ushort next_client;
/// <summary>0x014, Sequence number</summary>
public readonly ushort seq_number;
/// <summary>0x016, Reserved (6 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public readonly byte[] reserved;
/// <summary>0x01C, Client name length in bytes</summary>
public readonly uint client_name_length;
/// <summary>0x020, Client name in Unicode (usually "NTFS")</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public readonly ushort[] client_name;
}
#endregion
}