/*++ Copyright (c) 1997-2000 Microsoft Corporation Module Name: untfs2.h Abstract: This module contains partial basic declarations and definitions for the NTFS utilities. Note that more extensive description of the file system structures may be found in ntos\inc\ntfs.h. Author: Daniel Chan [danielch] 29-Mar-1997 Revision History: IMPORTANT NOTE: The NTFS on-disk structure must guarantee natural alignment of all arithmetic quantities on disk up to and including quad-word (64-bit) numbers. Therefore, all attribute records are quad-word aligned, etc. --*/ #if !defined( _UNTFS2_DEFN_ ) #define _UNTFS2_DEFN_ #include "bigint.hxx" #include "bpb.hxx" #include "wstring.hxx" #include DEFINE_TYPE( BIG_INT, LCN ); DEFINE_TYPE( BIG_INT, VCN ); DEFINE_TYPE( LARGE_INTEGER, LSN ); // This definition is for VCNs that appear in Unions, since an object // with a constructor (like a BIG_INT) can't appear in a union. DEFINE_TYPE( LARGE_INTEGER, VCN2 ); // An MFT_SEGMENT_REFERENCE identifies a cluster in the Master // File Table by its file number (VCN in Master File Table) and // sequence number. If the sequence number is zero, sequence // number checking is not performed. typedef struct _MFT_SEGMENT_REFERENCE { ULONG LowPart; USHORT HighPart; USHORT SequenceNumber; } MFT_SEGMENT_REFERENCE, *PMFT_SEGMENT_REFERENCE; DEFINE_TYPE( struct _MFT_SEGMENT_REFERENCE, MFT_SEGMENT_REFERENCE ); DEFINE_TYPE( MFT_SEGMENT_REFERENCE, FILE_REFERENCE ); // System file numbers: // // The first sixteen entries in the Master File Table are reserved for // system use. The following reserved slots have been defined: #define MASTER_FILE_TABLE_NUMBER (0) #define MASTER_FILE_TABLE2_NUMBER (1) #define LOG_FILE_NUMBER (2) #define VOLUME_DASD_NUMBER (3) #define ATTRIBUTE_DEF_TABLE_NUMBER (4) #define ROOT_FILE_NAME_INDEX_NUMBER (5) #define BIT_MAP_FILE_NUMBER (6) #define BOOT_FILE_NUMBER (7) #define BAD_CLUSTER_FILE_NUMBER (8) #define QUOTA_TABLE_NUMBER (9) // for version < 2.0 #define SECURITY_TABLE_NUMBER (9) // for version >= 2.0 #define UPCASE_TABLE_NUMBER (10) #define EXTEND_TABLE_NUMBER (11) // for version >= 2.0 #define MFT_OVERFLOW_FRS_NUMBER (15) #define FIRST_USER_FILE_NUMBER (16) DEFINE_TYPE( ULONG, ATTRIBUTE_TYPE_CODE ); // // System-defined Attribute Type Codes. For the System-defined attributes, // the Unicode Name is exactly equal to the name of the following symbols. // For this reason, all of the system-defined attribute names start with "$", // to always distinguish them when attribute names are listed, and to reserve // a namespace for attributes defined in the future. I.e., a User-Defined // attribute name will never collide with a current or future system-defined // attribute name if it does not start with "$". User attribute numbers // should not start until $FIRST_USER_DEFINED_ATTRIBUTE, too allow the // potential for upgrading existing volumes with new user-defined attributes // in future versions of NTFS. The tagged attribute list is terminated with // a lone-standing $END - the rest of the attribute record does not exist. // #define $UNUSED (0x0) #define $STANDARD_INFORMATION (0x10) #define $ATTRIBUTE_LIST (0x20) #define $FILE_NAME (0x30) #define $VOLUME_VERSION (0x40) #define $OBJECT_ID (0x40) // starting in NT 5.0 #define $SECURITY_DESCRIPTOR (0x50) #define $VOLUME_NAME (0x60) #define $VOLUME_INFORMATION (0x70) #define $DATA (0x80) #define $INDEX_ROOT (0x90) #define $INDEX_ALLOCATION (0xA0) #define $BITMAP (0xB0) #define $SYMBOLIC_LINK (0xC0) #define $REPARSE_POINT (0xC0) // starting in NT 5.0 #define $EA_INFORMATION (0xD0) #define $EA_DATA (0xE0) #define $FIRST_USER_DEFINED_ATTRIBUTE_1 (0x100) // true up to NT 4.0 #define $PROPERTY_SET (0xF0) // starting in NT 5.0 #define $LOGGED_UTILITY_STREAM (0x100) // starting in NT 5.0 #define $FIRST_USER_DEFINED_ATTRIBUTE_2 (0x1000) // starting in NT 5.0 #define $END (0xFFFFFFFF) // // The boot sector is duplicated on the partition. The first copy is on // the first physical sector (LBN == 0) of the partition, and the second // copy is at / 2. If the first copy can // not be read when trying to mount the disk, the second copy may be read // and has the identical contents. Format must figure out which cluster // the second boot record belongs in, and it must zero all of the other // sectors that happen to be in the same cluster. The boot file minimally // contains with two clusters, which are the two clusters which contain the // copies of the boot record. If format knows that some system likes to // put code somewhere, then it should also align this requirement to // even clusters, and add that to the boot file as well. // // // Define the boot sector. Note that MFT2 is exactly three file record // segments long, and it mirrors the first three file record segments from // the MFT, which are MFT, MFT2 and the Log File. // // The Oem field contains the ASCII characters "NTFS ". // // The Checksum field is a simple additive checksum of all of the ULONGs // which precede the Checksum ULONG. The rest of the sector is not included // in this Checksum. // typedef struct _PACKED_BOOT_SECTOR { UCHAR Jump[3]; // offset = 0x000 UCHAR Oem[8]; // offset = 0x003 OLD_PACKED_BIOS_PARAMETER_BLOCK PackedBpb; // offset = 0x00B UCHAR PhysicalDrive; // offset = 0x024 UCHAR ReservedForBootCode; // offset = 0x025 UCHAR Unused[2]; // offset = 0x026 LARGE_INTEGER NumberSectors; // offset = 0x028 LCN MftStartLcn; // offset = 0x030 LCN Mft2StartLcn; // offset = 0x038 CHAR ClustersPerFileRecordSegment; // offset = 0x040 UCHAR Unused1[3]; // offset = 0x041 CHAR DefaultClustersPerIndexAllocationBuffer; // offset = 0x044 UCHAR Unused2[3]; // offset = 0x047 LARGE_INTEGER SerialNumber; // offset = 0x048 ULONG Checksum; // offset = 0x050 UCHAR BootStrap[0x200-0x054]; // offset = 0x054 } PACKED_BOOT_SECTOR; // sizeof = 0x200 typedef PACKED_BOOT_SECTOR *PPACKED_BOOT_SECTOR; // Update sequence array structures--see ntos\inc\cache.h for // description. #define SEQUENCE_NUMBER_STRIDE (512) DEFINE_TYPE( USHORT, UPDATE_SEQUENCE_NUMBER ); typedef struct _UNTFS_MULTI_SECTOR_HEADER { UCHAR Signature[4]; USHORT UpdateSequenceArrayOffset; // byte offset USHORT UpdateSequenceArraySize; // number of Update Sequence Numbers }; DEFINE_TYPE( _UNTFS_MULTI_SECTOR_HEADER, UNTFS_MULTI_SECTOR_HEADER ); typedef UPDATE_SEQUENCE_NUMBER UPDATE_SEQUENCE_ARRAY[1]; typedef UPDATE_SEQUENCE_ARRAY *PUPDATE_SEQUENCE_ARRAY; // // File Record Segment. This is the header that begins every File Record // Segment in the Master File Table. // typedef struct _FILE_RECORD_SEGMENT_HEADER { UNTFS_MULTI_SECTOR_HEADER MultiSectorHeader; LSN Lsn; USHORT SequenceNumber; USHORT ReferenceCount; USHORT FirstAttributeOffset; USHORT Flags; // FILE_xxx flags ULONG FirstFreeByte; // byte-offset ULONG BytesAvailable; // Size of FRS FILE_REFERENCE BaseFileRecordSegment; USHORT NextAttributeInstance; // Attribute instance tag for next insert. USHORT SegmentNumberHighPart; // used in mft recovery ULONG SegmentNumberLowPart; // used in mft recovery UPDATE_SEQUENCE_ARRAY UpdateArrayForCreateOnly; }; typedef struct _FILE_RECORD_SEGMENT_HEADER_V0 { UNTFS_MULTI_SECTOR_HEADER MultiSectorHeader; LSN Lsn; USHORT SequenceNumber; USHORT ReferenceCount; USHORT FirstAttributeOffset; USHORT Flags; // FILE_xxx flags ULONG FirstFreeByte; // byte-offset ULONG BytesAvailable; // Size of FRS FILE_REFERENCE BaseFileRecordSegment; USHORT NextAttributeInstance; // Attribute instance tag for next insert. UPDATE_SEQUENCE_ARRAY UpdateArrayForCreateOnly; }; DEFINE_TYPE( _FILE_RECORD_SEGMENT_HEADER, FILE_RECORD_SEGMENT_HEADER ); DEFINE_TYPE( _FILE_RECORD_SEGMENT_HEADER_V0, FILE_RECORD_SEGMENT_HEADER_V0 ); // // FILE_xxx flags. // #define FILE_RECORD_SEGMENT_IN_USE (0x0001) #define FILE_FILE_NAME_INDEX_PRESENT (0x0002) #define FILE_SYSTEM_FILE (0x0004) #define FILE_VIEW_INDEX_PRESENT (0x0008) // // Attribute Record. Logically an attribute has a type, an optional name, // and a value, however the storage details make it a little more complicated. // For starters, an attribute's value may either be resident in the file // record segment itself, on nonresident in a separate data stream. If it // is nonresident, it may actually exist multiple times in multiple file // record segments to describe different ranges of VCNs. // // Attribute Records are always aligned on a quad word (64-bit) boundary. // // Note that SIZE_OF_RESIDENT_HEADER and SIZE_OF_NONRESIDENT_HEADER // must correspond to the ATTRIBUTE_RECORD_HEADER structure. #define SIZE_OF_RESIDENT_HEADER 24 #define SIZE_OF_NONRESIDENT_HEADER 64 typedef struct _ATTRIBUTE_RECORD_HEADER { ATTRIBUTE_TYPE_CODE TypeCode; ULONG RecordLength; UCHAR FormCode; UCHAR NameLength; // length in characters USHORT NameOffset; // byte offset from start of record USHORT Flags; // ATTRIBUTE_xxx flags. USHORT Instance; // FRS-unique attribute instance tag union { // // Resident Form. Attribute resides in file record segment. // struct { ULONG ValueLength; // in bytes USHORT ValueOffset; // byte offset from start of record UCHAR ResidentFlags; // RESIDENT_FORM_xxx Flags. UCHAR Reserved; } Resident; // // Nonresident Form. Attribute resides in separate stream. // struct { VCN2 LowestVcn; VCN2 HighestVcn; USHORT MappingPairsOffset; // byte offset from start of record UCHAR CompressionUnit; UCHAR Reserved[5]; LARGE_INTEGER AllocatedLength; LARGE_INTEGER FileSize; LARGE_INTEGER ValidDataLength; LARGE_INTEGER TotalAllocated; // // Mapping Pairs Array follows, starting at the offset given // above. See the extended comment in ntfs.h. // } Nonresident; } Form; }; DEFINE_TYPE( _ATTRIBUTE_RECORD_HEADER, ATTRIBUTE_RECORD_HEADER ); // // Attribute Form Codes // #define RESIDENT_FORM (0x00) #define NONRESIDENT_FORM (0x01) // // Define Attribute Flags // #define ATTRIBUTE_FLAG_COMPRESSION_MASK (0x00FF) #define ATTRIBUTE_FLAG_SPARSE (0x8000) #define ATTRIBUTE_FLAG_ENCRYPTED (0x4000) // // RESIDENT_FORM_xxx flags // // // This attribute is indexed. // #define RESIDENT_FORM_INDEXED (0x01) // // The maximum attribute name length is 255 (in chars) // #define NTFS_MAX_ATTR_NAME_LEN (255) // // Volume Information attribute. This attribute is only intended to be // used on the Volume DASD file. // typedef struct _VOLUME_INFORMATION { LARGE_INTEGER Reserved; // // Major and minor version number of NTFS on this volume, starting // with 1.0. The major and minor version numbers are set from the // major and minor version of the Format and NTFS implementation for // which they are initialized. The policy for incementing major and // minor versions will always be decided on a case by case basis, however, // the following two paragraphs attempt to suggest an approximate strategy. // // The major version number is incremented if/when a volume format // change is made which requires major structure changes (hopefully // never?). If an implementation of NTFS sees a volume with a higher // major version number, it should refuse to mount the volume. If a // newer implementation of NTFS sees an older major version number, // it knows the volume cannot be accessed without performing a one-time // conversion. // // The minor version number is incremented if/when minor enhancements // are made to a major version, which potentially support enhanced // functionality through additional file or attribute record fields, // or new system-defined files or attributes. If an older implementation // of NTFS sees a newer minor version number on a volume, it may issue // some kind of warning, but it will proceed to access the volume - with // presumably some degradation in functionality compared to the version // of NTFS which initialized the volume. If a newer implementation of // NTFS sees a volume with an older minor version number, it may issue // a warning and proceed. In this case, it may choose to increment the // minor version number on the volume and begin full or incremental // upgrade of the volume on an as-needed basis. It may also leave the // minor version number unchanged, until some sort of explicit directive // from the user specifies that the minor version should be updated. // UCHAR MajorVersion; UCHAR MinorVersion; // // VOLUME_xxx flags. // USHORT VolumeFlags; } VOLUME_INFORMATION; typedef VOLUME_INFORMATION *PVOLUME_INFORMATION; // Current version number: // #define NTFS_CURRENT_MAJOR_VERSION 1 #define NTFS_CURRENT_MINOR_VERSION 2 // // Volume is dirty // #define VOLUME_DIRTY (0x0001) #define VOLUME_RESIZE_LOG_FILE (0x0002) #define VOLUME_UPGRADE_ON_MOUNT (0x0004) #define VOLUME_MOUNTED_ON_40 (0x0008) #define VOLUME_DELETE_USN_UNDERWAY (0x0010) #define VOLUME_REPAIR_OBJECT_ID (0x0020) #define VOLUME_CHKDSK_RAN_ONCE (0x4000) #define VOLUME_CHKDSK_RAN (0x8000) #include // Macros: #define QuadAlign( n ) \ (((n) + 7) & ~7 ) #define DwordAlign( n ) \ (((n) + 3) & ~3 ) #define IsQuadAligned( n ) \ (((n) & 7) == 0) #define IsDwordAligned( n ) \ (((n) & 3) == 0) #endif // _UNTFS2_DEFN_