/*++ Copyright (c) 1991-2001 Microsoft Corporation Module Name: untfs.h Abstract: This module contains 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: Bill McJohn [BillMc] 23-July-1991 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( _UNTFS_DEFN_ ) #define _UNTFS_DEFN_ #define FRIEND friend #define MIN( a, b ) ( ((a) < (b)) ? (a) : (b) ) // Set up the UNTFS_EXPORT macro for exporting from UNTFS (if the // source file is a member of UNTFS) or importing from UNTFS (if // the source file is a client of UNTFS). // #if defined ( _AUTOCHECK_ ) #define UNTFS_EXPORT #elif defined ( _UNTFS_MEMBER_ ) #define UNTFS_EXPORT __declspec(dllexport) #else #define UNTFS_EXPORT __declspec(dllimport) #endif #include "bigint.hxx" #include "bpb.hxx" #include "wstring.hxx" #include "untfs2.hxx" #include // Miscellaneous constants: // This value represents the number of clusters from the Master // File Table which are copied to the Master File Table Reflection. #define REFLECTED_MFT_SEGMENTS (4) #define BYTES_IN_BOOT_AREA (0x2000) // This value is used in a mapping-pair to indicate that the run // described by the mapping pair doesn't really exist. This allows // NTFS to support sparse files. Note that the actual values // are LARGE_INTEGERS; the BIG_INT class manages the conversion. #define LCN_NOT_PRESENT -1 #define INVALID_VCN -1 // // Temporary definitions **** // typedef ULONG COLLATION_RULE; typedef ULONG DISPLAY_RULE; // This defines the number of bytes to read at one time // when processing the MFT. #define MFT_PRIME_SIZE (16*1024) // This defines the number of frs'es to read at one time // when processing the MFT. #define MFT_READ_CHUNK_SIZE (128) // The compression chunk size is constant for now, at 4KB. // #define NTFS_CHUNK_SIZE (0x1000) // // This number is actually the log of the number of clusters per compression // unit to be stored in a nonresident attribute record header. // #define NTFS_CLUSTERS_PER_COMPRESSION (4) // // Collation Rules // // // For binary collation, values are collated by a binary compare of their // bytes, with the first byte being most significant. // #define COLLATION_BINARY (0) // // For collation of Ntfs file names, file names are collated as Unicode // strings. See below. // #define COLLATION_FILE_NAME (1) // // For collation of Unicode strings, the strings are collated by their // binary Unicode value, with the exception that for characters which may // be upcased, the lower case value for that character collates immediately // after the upcased value. // #define COLLATION_UNICODE_STRING (2) #define COLLATION_ULONG (16) #define COLLATION_SID (17) #define COLLATION_SECURITY_HASH (18) #define COLLATION_ULONGS (19) // // Total number of collation rules // #define COLLATION_NUMBER_RULES (7) INLINE BOOLEAN operator == ( IN RCMFT_SEGMENT_REFERENCE Left, IN RCMFT_SEGMENT_REFERENCE Right ) /*++ Routine Description: This function tests two segment references for equality. Arguments: Left -- supplies the left-hand operand Right -- supplies the right-hand operand Return Value: TRUE if they are equal; FALSE if not. --*/ { return( Left.HighPart == Right.HighPart && Left.LowPart == Right.LowPart && Left.SequenceNumber == Right.SequenceNumber ); } // // If the ClustersPerFileRecordSegment entry is zero, we use the // following as the size of our frs's regardless of the cluster // size. // #define SMALL_FRS_SIZE (1024) // // If the DefaultClustersPerIndexAllocationBuffer entry is zero, // we use the following as the size of our buffers regardless of // the cluster size. // #define SMALL_INDEX_BUFFER_SIZE (4096) // // If the above NextAttributeInstance field exceeds the following // value, chkdsk will take steps to prevent it from rolling over. // #define ATTRIBUTE_INSTANCE_TAG_THRESHOLD 0xf000 // // Define a macro to determine the maximum space available for a // single attribute. For example, this is required when a // nonresident attribute has to split into multiple file records - // we need to know how much we can squeeze into a single file // record. If this macro has any inaccurracy, it must be in the // direction of returning a slightly smaller number than actually // required. // // ULONG // NtfsMaximumAttributeSize ( // IN ULONG FileRecordSegmentSize // ); // #define NtfsMaximumAttributeSize(FRSS) ( \ (FRSS) - QuadAlign(sizeof(FILE_RECORD_SEGMENT_HEADER)) - \ QuadAlign((((FRSS) / SEQUENCE_NUMBER_STRIDE) * sizeof(UPDATE_SEQUENCE_NUMBER))) - \ QuadAlign(sizeof(ATTRIBUTE_TYPE_CODE)) \ ) // // Macros for manipulating mapping pair count byte. // INLINE UCHAR ComputeMappingPairCountByte( IN UCHAR VcnLength, IN UCHAR LcnLength ) { return VcnLength + 16*LcnLength; } INLINE UCHAR VcnBytesFromCountByte( IN UCHAR CountByte ) { return CountByte%16; } INLINE UCHAR LcnBytesFromCountByte( IN UCHAR CountByte ) { return CountByte/16; } // // Standard Information Attribute. This attribute is present in every // base file record, and must be resident. // typedef struct _STANDARD_INFORMATION { LARGE_INTEGER CreationTime; LARGE_INTEGER LastModificationTime; // refers to $DATA attribute LARGE_INTEGER LastChangeTime; // any attribute LARGE_INTEGER LastAccessTime; ULONG FileAttributes; ULONG MaximumVersions; ULONG VersionNumber; ULONG Reserved; }; DEFINE_TYPE( _STANDARD_INFORMATION, STANDARD_INFORMATION ); typedef struct _STANDARD_INFORMATION2 { LARGE_INTEGER CreationTime; LARGE_INTEGER LastModificationTime; // refers to $DATA attribute LARGE_INTEGER LastChangeTime; // any attribute LARGE_INTEGER LastAccessTime; ULONG FileAttributes; ULONG MaximumVersions; ULONG VersionNumber; ULONG ClassId; ULONG OwnerId; ULONG SecurityId; LARGE_INTEGER QuotaCharged; LARGE_INTEGER Usn; }; DEFINE_TYPE( _STANDARD_INFORMATION2, STANDARD_INFORMATION2 ); #define SIZEOF_NEW_STANDARD_INFORMATION (0x48) // // Define the file attributes, starting with the Fat attributes. // #define FAT_DIRENT_ATTR_READ_ONLY (0x01) #define FAT_DIRENT_ATTR_HIDDEN (0x02) #define FAT_DIRENT_ATTR_SYSTEM (0x04) #define FAT_DIRENT_ATTR_VOLUME_ID (0x08) #define FAT_DIRENT_ATTR_ARCHIVE (0x20) #define FAT_DIRENT_ATTR_DEVICE (0x40) // // The FILE_ATTRIBUTE_ENCRYPTED bit coincides with the FILE_ATTRIBUTE_DEVICE on Win9x. // So we are changing it to a different value. In the meantime, chkdsk should clear // this bit whenever it sees it on ntfs volume. // #define FILE_ATTRIBUTE_ENCRYPTED_OLD (0x40) // // This bit is duplicated from the file record, to indicate that // this file has a file name index present (is a "directory"). // #define DUP_FILE_NAME_INDEX_PRESENT (0x10000000) #define DUP_VIEW_INDEX_PRESENT (0x20000000) // // Attribute List. Because there is not a special header that goes // before the list of attribute list entries we do not need to declare // an attribute list header // // // The Attributes List attribute is an ordered-list of quad-word // aligned ATTRIBUTE_LIST_ENTRY records. It is ordered first by // Attribute Type Code, and then by Attribute Name (if present). No two // attributes may exist with the same type code, name and LowestVcn. This // also means that at most one occurrence of a given Attribute Type Code // without a name may exist. // // To binary search this attribute, it is first necessary to make a quick // pass through it and form a list of pointers, since the optional name // makes it variable-length. // typedef struct _ATTRIBUTE_LIST_ENTRY { ATTRIBUTE_TYPE_CODE AttributeTypeCode; USHORT RecordLength; // length in bytes UCHAR AttributeNameLength; // length in characters UCHAR AttributeNameOffset; // offset from beginning of struct VCN LowestVcn; MFT_SEGMENT_REFERENCE SegmentReference; USHORT Instance; // FRS-unique instance tag WCHAR AttributeName[1]; }; DEFINE_TYPE( _ATTRIBUTE_LIST_ENTRY, ATTRIBUTE_LIST_ENTRY ); BOOLEAN operator <= ( IN RCATTRIBUTE_LIST_ENTRY Left, IN RCATTRIBUTE_LIST_ENTRY Right ); typedef struct _DUPLICATED_INFORMATION { BIG_INT CreationTime; // File creation BIG_INT LastModificationTime; // Last change of $DATA attribute BIG_INT LastChangeTime; // Last change of any attribute BIG_INT LastAccessTime; // see ntfs.h for notes BIG_INT AllocatedLength; // File allocated size BIG_INT FileSize; // File actual size ULONG FileAttributes; union { struct { USHORT PackedEaSize; USHORT Reserved; }; ULONG ReparsePointTag; }; }; DEFINE_TYPE( _DUPLICATED_INFORMATION, DUPLICATED_INFORMATION ); // // File Name attribute. A file has one File Name attribute for every // directory it is entered into (hard links). // typedef struct _FILE_NAME { FILE_REFERENCE ParentDirectory; DUPLICATED_INFORMATION Info; UCHAR FileNameLength; // length in characters UCHAR Flags; // FILE_NAME_xxx flags WCHAR FileName[1]; // First character of file name }; DEFINE_TYPE( _FILE_NAME, FILE_NAME ); // NtfsFileNameGetLength evaluates to the length of a FILE_NAME attribute // value, which is the FILE_NAME structure plus the length of the name. // Note that this is the actual length, not the quad-aligned length. #define NtfsFileNameGetLength(p) ( FIELD_OFFSET( FILE_NAME, FileName ) \ + ((p)->FileNameLength * sizeof( WCHAR )) ) // NtfsFileNameGetName gets the pointer to the name in a FILE_NAME // structure, which in turn is the value of an NTFS $FILE_NAME attribute. #define NtfsFileNameGetName(p) ( &((p)->FileName[0]) ) // // File Name flags // #define FILE_NAME_NTFS (0x01) #define FILE_NAME_DOS (0x02) // // The maximum file name length is 255 (in chars) // #define NTFS_MAX_FILE_NAME_LENGTH (255) // // The maximum number of links on a file is 1024 // #define NTFS_MAX_LINK_COUNT (1024) // This is the name of all attributes associated with an index // over $FILE_NAME: #define FileNameIndexNameData "$I30" // // Object ID attribute. // typedef struct _OBJECT_ID { char x[16]; }; DEFINE_TYPE( _OBJECT_ID, OBJECT_ID ); typedef struct _OBJID_INDEX_ENTRY_VALUE { OBJECT_ID key; MFT_SEGMENT_REFERENCE SegmentReference; char extraInfo[48]; }; DEFINE_TYPE( _OBJID_INDEX_ENTRY_VALUE, OBJID_INDEX_ENTRY_VALUE ); // // Object Id File Name to appear in the \$Extend directory // #define ObjectIdFileName "$ObjId" #define LObjectIdFileName L"$ObjId" #define ObjectIdIndexNameData "$O" // // Reparse Point Index Entry // typedef struct _REPARSE_INDEX_ENTRY_VALUE { ULONG Tag; // ULONG Reserved; MFT_SEGMENT_REFERENCE SegmentReference; }; DEFINE_TYPE( _REPARSE_INDEX_ENTRY_VALUE, REPARSE_INDEX_ENTRY_VALUE ); // // Reparse File Name to appear in the \$Extend directory // #define ReparseFileName "$Reparse" #define LReparseFileName L"$Reparse" #define ReparseIndexNameData "$R" // // Volume Version attribute. // typedef struct _VOLUME_VERSION { ULONG CurrentVersion; ULONG MaximumVersions; }; DEFINE_TYPE( _VOLUME_VERSION, VOLUME_VERSION ); // // Security Descriptor attribute. This is just a normal attribute stream // containing a security descriptor as defined by NT security and is // really treated pretty opaque by NTFS. // #define SecurityIdIndexNameData "$SII" #define SecurityDescriptorHashIndexNameData "$SDH" #define SecurityDescriptorStreamNameData "$SDS" // Security Descriptor Stream data is organized into chunks of 256K bytes // and it contains a mirror copy of each security descriptor. When writing // to a security descriptor at location X, another copy will be written at // location (X+256K). When writing a security descriptor that will // cross the 256K boundary, the pointer will be advanced by 256K to skip // over the mirror portion. #define SecurityDescriptorsBlockSize (0x40000) // 256K #define SecurityDescriptorMaxSize (0x20000) // 128K // Volume Name attribute. This attribute is just a normal attribute stream // containing the unicode characters that make up the volume label. It // is an attribute of the Volume Dasd File. // // // Common Index Header for Index Root and Index Allocation Buffers. // This structure is used to locate the Index Entries and describe the free // space in either of the two structures above. // typedef struct _INDEX_HEADER { // // Offset from the start of this structure to the first Index Entry. // ULONG FirstIndexEntry; // // Offset from the start of this structure to the first (quad-word aligned) // free byte. // ULONG FirstFreeByte; // // Total number of bytes available, from the start of this structure. // In the Index Root, this number must always be equal to FirstFreeByte, // as the total attribute record will be grown and shrunk as required. // ULONG BytesAvailable; // // INDEX_xxx flags. // UCHAR Flags; // // Reserved to round up to quad word boundary. // UCHAR Reserved[3]; } INDEX_HEADER; typedef INDEX_HEADER *PINDEX_HEADER; // // INDEX_xxx flags // // // This Index or Index Allocation buffer is an intermediate node, as opposed to // a leaf in the Btree. All Index Entries will have a Vcn down pointer. // #define INDEX_NODE (0x01) // // Index Root attribute. The index attribute consists of an index // header record followed by one or more index entries. // typedef struct _INDEX_ROOT { ATTRIBUTE_TYPE_CODE IndexedAttributeType; COLLATION_RULE CollationRule; ULONG BytesPerIndexBuffer; UCHAR ClustersPerIndexBuffer; UCHAR Reserved[3]; // // Index Header to describe the Index Entries which follow // INDEX_HEADER IndexHeader; } INDEX_ROOT; typedef INDEX_ROOT *PINDEX_ROOT; // // Index Allocation record is used for non-root clusters of the b-tree // Each non root cluster is contained in the data part of the index // allocation attribute. Each cluster starts with an index allocation list // header and is followed by one or more index entries. // typedef struct _INDEX_ALLOCATION_BUFFER { // // Multi-Sector Header as defined by the Cache Manager. This structure // will always contain the signature "INDX" and a description of the // location and size of the Update Sequence Array. // UNTFS_MULTI_SECTOR_HEADER MultiSectorHeader; // // Log File Sequence Number of last logged update to this Index Allocation // Buffer. // LSN Lsn; VCN ThisVcn; // // Index Header to describe the Index Entries which follow // INDEX_HEADER IndexHeader; // // Update Sequence Array to protect multi-sector transfers of the // Index Allocation Bucket. // UPDATE_SEQUENCE_ARRAY UpdateSequenceArray; } INDEX_ALLOCATION_BUFFER; typedef INDEX_ALLOCATION_BUFFER *PINDEX_ALLOCATION_BUFFER; // // Index Entry. This structure is common to both the resident index list // attribute and the Index Allocation records // typedef struct _INDEX_ENTRY { // // Define a union to distinguish directory indices from view indices // union { // // Reference to file containing the attribute with this // attribute value. // FILE_REFERENCE FileReference; // offset = 0x000 // // For views, describe the Data Offset and Length in bytes // struct { USHORT DataOffset; // offset = 0x000 USHORT DataLength; // offset = 0x001 ULONG ReservedForZero; // offset = 0x002 }; }; // // Length of this index entry, in bytes. // USHORT Length; // // Length of attribute value, in bytes. The attribute value immediately // follows this record. // USHORT AttributeLength; // // INDEX_ENTRY_xxx Flags. // USHORT Flags; // // Reserved to round to quad-word boundary. // USHORT Reserved; // // If this Index Entry is an intermediate node in the tree, as determined // by the INDEX_xxx flags, then a VCN is stored at the end of this // entry at Length - sizeof(VCN). // }; DEFINE_TYPE( _INDEX_ENTRY, INDEX_ENTRY ); #define GetDownpointer( x ) \ (*((PVCN)((PBYTE)(x) + (x)->Length - sizeof(VCN)))) #define GetIndexEntryValue( x ) \ ((PBYTE)(x)+sizeof(INDEX_ENTRY)) #define GetNextEntry( x ) \ ((PINDEX_ENTRY)( (PBYTE)(x)+(x)->Length )) CONST UCHAR NtfsIndexLeafEndEntrySize = QuadAlign( sizeof(INDEX_ENTRY) ); // // INDEX_ENTRY_xxx flags // // // This entry is currently in the intermediate node form, i.e., it has a // Vcn at the end. // #define INDEX_ENTRY_NODE (0x0001) // // This entry is the special END record for the Index or Index Allocation buffer. // #define INDEX_ENTRY_END (0x0002) // // Define the struture of the quota data in the quota index. The key for // the quota index is the 32 bit owner id. // typedef struct _QUOTA_USER_DATA { ULONG QuotaVersion; ULONG QuotaFlags; ULONGLONG QuotaUsed; ULONGLONG QuotaChangeTime; ULONGLONG QuotaThreshold; ULONGLONG QuotaLimit; ULONGLONG QuotaExceededTime; SID QuotaSid; } QUOTA_USER_DATA, *PQUOTA_USER_DATA; // // Define the size of the quota user data structure without the quota SID. // #define SIZEOF_QUOTA_USER_DATA FIELD_OFFSET(QUOTA_USER_DATA, QuotaSid) // // Define the current version of the quote user data. // #define QUOTA_USER_VERSION 1 // // Define the quota flags. // #define QUOTA_FLAG_DEFAULT_LIMITS (0x00000001) #define QUOTA_FLAG_LIMIT_REACHED (0x00000002) #define QUOTA_FLAG_ID_DELETED (0x00000004) #define QUOTA_FLAG_USER_MASK (0x00000007) // // The following flags are only stored in the quota defaults index entry. // #define QUOTA_FLAG_TRACKING_ENABLED (0x00000010) #define QUOTA_FLAG_ENFORCEMENT_ENABLED (0x00000020) #define QUOTA_FLAG_TRACKING_REQUESTED (0x00000040) #define QUOTA_FLAG_LOG_THRESHOLD (0x00000080) #define QUOTA_FLAG_LOG_LIMIT (0x00000100) #define QUOTA_FLAG_OUT_OF_DATE (0x00000200) #define QUOTA_FLAG_CORRUPT (0x00000400) #define QUOTA_FLAG_PENDING_DELETES (0x00000800) // // Define the quota charge for resident streams. // #define QUOTA_RESIDENT_STREAM (1024) // // Define special quota owner ids. // #define QUOTA_INVALID_ID 0x00000000 #define QUOTA_DEFAULTS_ID 0x00000001 #define QUOTA_FISRT_USER_ID 0x00000100 // // Quota File Name to appear in the \$Extend directory // #define QuotaFileName "$Quota" #define LQuotaFileName L"$Quota" // // Quota Index Names // #define Sid2UseridQuotaNameData "$O" #define Userid2SidQuotaNameData "$Q" // // Usn Journal // typedef struct { ULONG RecordLength; USHORT MajorVersion; USHORT MinorVersion; union { // // Version 1.0 // struct { ULONGLONG FileReferenceNumber; ULONGLONG ParentFileReferenceNumber; USN Usn; LARGE_INTEGER TimeStamp; ULONG Reason; ULONG SecurityId; ULONG FileAttributes; USHORT FileNameLength; WCHAR FileName[1]; } u1; // // Version 2.0 // struct { ULONGLONG FileReferenceNumber; ULONGLONG ParentFileReferenceNumber; USN Usn; LARGE_INTEGER TimeStamp; ULONG Reason; ULONG SourceInfo; // Additional info about source of change ULONG SecurityId; ULONG FileAttributes; USHORT FileNameLength; USHORT FileNameOffset; // Offset to file name WCHAR FileName[1]; } u2; } version; } USN_REC, *PUSN_REC; #define SIZE_OF_USN_REC_V1 0x38 #define SIZE_OF_USN_REC_V2 0x3E #define USN_PAGE_SIZE (0x1000) // 4 K #define USN_MAX_SIZE (1024*1024*8) // 8 MBytes #define USN_ALLOC_DELTA_MAX_SIZE (1024*1024) // 1 MBytes #define USN_JRNL_MAX_FILE_SIZE (0x20000000000) // 512 * 2^32 // // Usn Journal Name to appear in the \$Extend directory // #define UsnJournalFileName "$UsnJrnl" #define LUsnJournalFileName L"$UsnJrnl" // // Usn Journal named $DATA attribute Names // #define UsnJournalNameData "$J" #define UsnJournalMaxNameData "$Max" #define MAXULONGLONG (0xffffffffffffffff) // // Key structure for Security Hash index // typedef struct _SECURITY_HASH_KEY { ULONG Hash; // Hash value for descriptor ULONG SecurityId; // Security Id (guaranteed unique) } SECURITY_HASH_KEY, *PSECURITY_HASH_KEY; // // Key structure for Security Id index is simply the SECURITY_ID itself // // // Header for security descriptors in the security descriptor stream. This // is the data format for all indexes and is part of SharedSecurity // typedef struct _SECURITY_DESCRIPTOR_HEADER { SECURITY_HASH_KEY HashKey; // Hash value for the descriptor ULONGLONG Offset; // offset to beginning of header ULONG Length; // Length in bytes } SECURITY_DESCRIPTOR_HEADER, *PSECURITY_DESCRIPTOR_HEADER; typedef struct _SECURITY_ENTRY { SECURITY_DESCRIPTOR_HEADER security_descriptor_header; SECURITY_DESCRIPTOR security; } SECURITY_ENTRY, *PSECURITY_ENTRY; #define GETSECURITYDESCRIPTORLENGTH(HEADER) \ ((HEADER)->Length - sizeof( SECURITY_DESCRIPTOR_HEADER )) #define SetSecurityDescriptorLength(HEADER,LENGTH) \ ((HEADER)->Length = (LENGTH) + sizeof( SECURITY_DESCRIPTOR_HEADER )) // // Define standard values for well-known security IDs // #define SECURITY_ID_INVALID (0x00000000) #define SECURITY_ID_FIRST (0x00000100) // // MFT Bitmap attribute // // The MFT Bitmap is simply a normal attribute stream in which there is // one bit to represent the allocation state of each File Record Segment // in the MFT. Bit clear means free, and bit set means allocated. // // Whenever the MFT Data attribute is extended, the MFT Bitmap attribute // must also be extended. If the bitmap is still in a file record segment // for the MFT, then it must be extended and the new bits cleared. When // the MFT Bitmap is in the Nonresident form, then the allocation should // always be sufficient to store enough bits to describe the MFT, however // ValidDataLength insures that newly allocated space to the MFT Bitmap // has an initial value of all 0's. This means that if the MFT Bitmap is // extended, the newly represented file record segments are automatically in // the free state. // // No structure definition is required; the positional offset of the file // record segment is exactly equal to the bit offset of its corresponding // bit in the Bitmap. // // // The utilities attempt to allocate a more disk space than necessary for // the initial MFT Bitmap to allow for future growth. // #define MFT_BITMAP_INITIAL_SIZE 0x2000 /* bytes of bitmap */ // // Symbolic Link attribute ****TBS // typedef struct _SYMBOLIC_LINK { LARGE_INTEGER Tbs; } SYMBOLIC_LINK; typedef SYMBOLIC_LINK *PSYMBOLIC_LINK; // // Ea Information attribute // typedef struct _EA_INFORMATION { USHORT PackedEaSize; // Size of buffer to hold in unpacked form USHORT NeedEaCount; // Count of EA's with NEED_EA bit set ULONG UnpackedEaSize; // Size of buffer to hold in packed form } EA_INFORMATION; typedef EA_INFORMATION *PEA_INFORMATION; struct PACKED_EA { UCHAR Flag; UCHAR NameSize; UCHAR ValueSize[2]; // Was USHORT. CHAR Name[1]; }; DEFINE_POINTER_TYPES( PACKED_EA ); #define EA_FLAG_NEED 0x80 // // SLEAZY_LARGE_INTEGER is used because x86 C8 won't allow us to // do static init on a union (like LARGE_INTEGER) and we can't use // BIG_INT for cases where we need to static-init an array with a non- // default constructor. The bit pattern must be the same as // LARGE_INTEGER. // typedef struct _SLEAZY_LARGE_INTEGER { ULONG LowPart; LONG HighPart; } SLEAZY_LARGE_INTEGER, *PSLEAZY_LARGE_INTEGER; // // Attribute Definition Table // // The following struct defines the columns of this table. Initially they // will be stored as simple records, and ordered by Attribute Type Code. // typedef struct _ATTRIBUTE_DEFINITION_COLUMNS { // // Unicode attribute name. // WCHAR AttributeName[64]; // // Attribute Type Code. // ATTRIBUTE_TYPE_CODE AttributeTypeCode; // // Default Display Rule for this attribute // DISPLAY_RULE DisplayRule; // // Default Collation rule // COLLATION_RULE CollationRule; // // ATTRIBUTE_DEF_xxx flags // ULONG Flags; // // Minimum Length for attribute, if present. // SLEAZY_LARGE_INTEGER MinimumLength; // // Maximum Length for attribute. // SLEAZY_LARGE_INTEGER MaximumLength; } ATTRIBUTE_DEFINITION_COLUMNS; DEFINE_POINTER_TYPES( ATTRIBUTE_DEFINITION_COLUMNS ); // // ATTRIBUTE_DEF_xxx flags // // // This flag is set if the attribute may be indexed. // #define ATTRIBUTE_DEF_INDEXABLE (0x00000002) // // This flag is set if the attribute may occur more than once, such as is // allowed for the File Name attribute. // #define ATTRIBUTE_DEF_DUPLICATES_ALLOWED (0x00000004) // // This flag is set if the value of the attribute may not be entirely // null, i.e., all binary 0's. // #define ATTRIBUTE_DEF_MAY_NOT_BE_NULL (0x00000008) // // This attribute must be indexed, and no two attributes may exist with // the same value in the same file record segment. // #define ATTRIBUTE_DEF_MUST_BE_INDEXED (0x00000010) // // This attribute must be named, and no two attributes may exist with // the same name in the same file record segment. // #define ATTRIBUTE_DEF_MUST_BE_NAMED (0x00000020) // // This attribute must be in the Resident Form. // #define ATTRIBUTE_DEF_MUST_BE_RESIDENT (0x00000040) // // Modifications to this attribute should be logged even if the // attribute is nonresident. // #define ATTRIBUTE_DEF_LOG_NONRESIDENT (0X00000080) // // The remaining stuff in this file describes some of the lfs data // structures; some of these are used by chkdsk, and some are used // only by diskedit. // typedef struct _MULTI_SECTOR_HEADER { // // Space for a four-character signature // UCHAR Signature[4]; // // Offset to Update Sequence Array, from start of structure. The Update // Sequence Array must end before the last USHORT in the first "sector" // of size SEQUENCE_NUMBER_STRIDE. (I.e., with the current constants, // the sum of the next two fields must be <= 510.) // USHORT UpdateSequenceArrayOffset; // // Size of Update Sequence Array (from above formula) // USHORT UpdateSequenceArraySize; } MULTI_SECTOR_HEADER, *PMULTI_SECTOR_HEADER; typedef struct _LFS_RESTART_PAGE_HEADER { // // Cache multisector protection header. // MULTI_SECTOR_HEADER MultiSectorHeader; // // This is the last Lsn found by checkdisk for this volume. // LSN ChkDskLsn; // // ULONG SystemPageSize; ULONG LogPageSize; // // Lfs restart area offset. This is the offset from the start of this // structure to the Lfs restart area. // USHORT RestartOffset; USHORT MinorVersion; USHORT MajorVersion; // // Update Sequence Array. Used to protect the page blcok. // UPDATE_SEQUENCE_ARRAY UpdateSequenceArray; } LFS_RESTART_PAGE_HEADER, *PLFS_RESTART_PAGE_HEADER; // // Log Client Record. A log client record exists for each client user of // the log file. One of these is in each Lfs restart area. // #define LFS_NO_CLIENT 0xffff #define LFS_CLIENT_NAME_MAX 64 typedef struct _LFS_CLIENT_RECORD { // // Oldest Lsn. This is the oldest Lsn that this client requires to // be in the log file. // LSN OldestLsn; // // Client Restart Lsn. This is the Lsn of the latest client restart // area written to the disk. A reserved Lsn will indicate that no // restart area exists for this client. // LSN ClientRestartLsn; // // // Previous/Next client area. These are the indexes into an array of // Log Client Records for the previous and next client records. // USHORT PrevClient; USHORT NextClient; // // Sequence Number. Incremented whenever this record is reused. This // will happen whenever a client opens (reopens) the log file and has // no current restart area. USHORT SeqNumber; // // Alignment field. // USHORT AlignWord; // // Align the entire record. // ULONG AlignDWord; // // The following fields are used to describe the client name. A client // name consists of at most 32 Unicode character (64 bytes). The Log // file service will treat client names as case sensitive. // ULONG ClientNameLength; WCHAR ClientName[LFS_CLIENT_NAME_MAX]; } LFS_CLIENT_RECORD, *PLFS_CLIENT_RECORD; typedef struct _LFS_RESTART_AREA { // // Current Lsn. This is periodic snapshot of the current logical end of // log file to facilitate restart. // LSN CurrentLsn; // // Number of Clients. This is the maximum number of clients supported // for this log file. // USHORT LogClients; // // The following are indexes into the client record arrays. The client // records are linked into two lists. A free list of client records and // an in-use list of records. // USHORT ClientFreeList; USHORT ClientInUseList; // // Flag field. // // RESTART_SINGLE_PAGE_IO All log pages written 1 by 1 // LFS_CLEAN_SHUTDOWN // USHORT Flags; // // The following is the number of bits to use for the sequence number. // ULONG SeqNumberBits; // // Length of this restart area. // USHORT RestartAreaLength; // // Offset from the start of this structure to the client array. // Ignored in versions prior to 1.1 // USHORT ClientArrayOffset; // // Usable log file size. We will stop sharing the value in the page header. // LONGLONG FileSize; // // DataLength of last Lsn. This doesn't include the length of // the Lfs header. // ULONG LastLsnDataLength; // // The following apply to log pages. This is the log page data offset and // the length of the log record header. Ignored in versions prior to 1.1 // USHORT RecordHeaderLength; USHORT LogPageDataOffset; // // Log file open count. Used to determine if there has been a change to the disk. // ULONG RestartOpenLogCount; // // Track log flush failures // ULONG LastFailedFlushStatus; LONGLONG LastFailedFlushOffset; LSN LastFailedFlushLsn; // // Keep this structure quadword aligned. // // // Client data. // LFS_CLIENT_RECORD LogClientArray[1]; } LFS_RESTART_AREA, *PLFS_RESTART_AREA; // // Flags definition in LFS_RESTART_AREA // #define LFS_CLEAN_SHUTDOWN (0x0002) #include BOOLEAN GetSystemFileName( IN UCHAR Major, IN VCN FileNumber, OUT PWSTRING FileName, OUT PBOOLEAN NoName ); #endif // _UNTFS_DEFN_