1a1d312deSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * layout.h - All NTFS associated on-disk structures. Part of the Linux-NTFS
41da177e4SLinus Torvalds * project.
51da177e4SLinus Torvalds *
6c002f425SAnton Altaparmakov * Copyright (c) 2001-2005 Anton Altaparmakov
71da177e4SLinus Torvalds * Copyright (c) 2002 Richard Russon
81da177e4SLinus Torvalds */
91da177e4SLinus Torvalds
101da177e4SLinus Torvalds #ifndef _LINUX_NTFS_LAYOUT_H
111da177e4SLinus Torvalds #define _LINUX_NTFS_LAYOUT_H
121da177e4SLinus Torvalds
131da177e4SLinus Torvalds #include <linux/types.h>
141da177e4SLinus Torvalds #include <linux/bitops.h>
151da177e4SLinus Torvalds #include <linux/list.h>
161da177e4SLinus Torvalds #include <asm/byteorder.h>
171da177e4SLinus Torvalds
181da177e4SLinus Torvalds #include "types.h"
191da177e4SLinus Torvalds
201da177e4SLinus Torvalds /* The NTFS oem_id "NTFS " */
2163cd8854SHarvey Harrison #define magicNTFS cpu_to_le64(0x202020205346544eULL)
221da177e4SLinus Torvalds
231da177e4SLinus Torvalds /*
241da177e4SLinus Torvalds * Location of bootsector on partition:
251da177e4SLinus Torvalds * The standard NTFS_BOOT_SECTOR is on sector 0 of the partition.
261da177e4SLinus Torvalds * On NT4 and above there is one backup copy of the boot sector to
271da177e4SLinus Torvalds * be found on the last sector of the partition (not normally accessible
281da177e4SLinus Torvalds * from within Windows as the bootsector contained number of sectors
291da177e4SLinus Torvalds * value is one less than the actual value!).
301da177e4SLinus Torvalds * On versions of NT 3.51 and earlier, the backup copy was located at
311da177e4SLinus Torvalds * number of sectors/2 (integer divide), i.e. in the middle of the volume.
321da177e4SLinus Torvalds */
331da177e4SLinus Torvalds
341da177e4SLinus Torvalds /*
351da177e4SLinus Torvalds * BIOS parameter block (bpb) structure.
361da177e4SLinus Torvalds */
371da177e4SLinus Torvalds typedef struct {
381da177e4SLinus Torvalds le16 bytes_per_sector; /* Size of a sector in bytes. */
391da177e4SLinus Torvalds u8 sectors_per_cluster; /* Size of a cluster in sectors. */
401da177e4SLinus Torvalds le16 reserved_sectors; /* zero */
411da177e4SLinus Torvalds u8 fats; /* zero */
421da177e4SLinus Torvalds le16 root_entries; /* zero */
431da177e4SLinus Torvalds le16 sectors; /* zero */
441da177e4SLinus Torvalds u8 media_type; /* 0xf8 = hard disk */
451da177e4SLinus Torvalds le16 sectors_per_fat; /* zero */
461da177e4SLinus Torvalds le16 sectors_per_track; /* irrelevant */
471da177e4SLinus Torvalds le16 heads; /* irrelevant */
481da177e4SLinus Torvalds le32 hidden_sectors; /* zero */
491da177e4SLinus Torvalds le32 large_sectors; /* zero */
501da177e4SLinus Torvalds } __attribute__ ((__packed__)) BIOS_PARAMETER_BLOCK;
511da177e4SLinus Torvalds
521da177e4SLinus Torvalds /*
531da177e4SLinus Torvalds * NTFS boot sector structure.
541da177e4SLinus Torvalds */
551da177e4SLinus Torvalds typedef struct {
561da177e4SLinus Torvalds u8 jump[3]; /* Irrelevant (jump to boot up code).*/
571da177e4SLinus Torvalds le64 oem_id; /* Magic "NTFS ". */
581da177e4SLinus Torvalds BIOS_PARAMETER_BLOCK bpb; /* See BIOS_PARAMETER_BLOCK. */
591da177e4SLinus Torvalds u8 unused[4]; /* zero, NTFS diskedit.exe states that
601da177e4SLinus Torvalds this is actually:
611da177e4SLinus Torvalds __u8 physical_drive; // 0x80
621da177e4SLinus Torvalds __u8 current_head; // zero
631da177e4SLinus Torvalds __u8 extended_boot_signature;
641da177e4SLinus Torvalds // 0x80
651da177e4SLinus Torvalds __u8 unused; // zero
661da177e4SLinus Torvalds */
671da177e4SLinus Torvalds /*0x28*/sle64 number_of_sectors; /* Number of sectors in volume. Gives
681da177e4SLinus Torvalds maximum volume size of 2^63 sectors.
691da177e4SLinus Torvalds Assuming standard sector size of 512
701da177e4SLinus Torvalds bytes, the maximum byte size is
711da177e4SLinus Torvalds approx. 4.7x10^21 bytes. (-; */
721da177e4SLinus Torvalds sle64 mft_lcn; /* Cluster location of mft data. */
731da177e4SLinus Torvalds sle64 mftmirr_lcn; /* Cluster location of copy of mft. */
741da177e4SLinus Torvalds s8 clusters_per_mft_record; /* Mft record size in clusters. */
751da177e4SLinus Torvalds u8 reserved0[3]; /* zero */
761da177e4SLinus Torvalds s8 clusters_per_index_record; /* Index block size in clusters. */
771da177e4SLinus Torvalds u8 reserved1[3]; /* zero */
781da177e4SLinus Torvalds le64 volume_serial_number; /* Irrelevant (serial number). */
791da177e4SLinus Torvalds le32 checksum; /* Boot sector checksum. */
801da177e4SLinus Torvalds /*0x54*/u8 bootstrap[426]; /* Irrelevant (boot up code). */
811da177e4SLinus Torvalds le16 end_of_sector_marker; /* End of bootsector magic. Always is
821da177e4SLinus Torvalds 0xaa55 in little endian. */
831da177e4SLinus Torvalds /* sizeof() = 512 (0x200) bytes */
841da177e4SLinus Torvalds } __attribute__ ((__packed__)) NTFS_BOOT_SECTOR;
851da177e4SLinus Torvalds
861da177e4SLinus Torvalds /*
871da177e4SLinus Torvalds * Magic identifiers present at the beginning of all ntfs record containing
881da177e4SLinus Torvalds * records (like mft records for example).
891da177e4SLinus Torvalds */
901da177e4SLinus Torvalds enum {
911da177e4SLinus Torvalds /* Found in $MFT/$DATA. */
9263cd8854SHarvey Harrison magic_FILE = cpu_to_le32(0x454c4946), /* Mft entry. */
9363cd8854SHarvey Harrison magic_INDX = cpu_to_le32(0x58444e49), /* Index buffer. */
9463cd8854SHarvey Harrison magic_HOLE = cpu_to_le32(0x454c4f48), /* ? (NTFS 3.0+?) */
951da177e4SLinus Torvalds
961da177e4SLinus Torvalds /* Found in $LogFile/$DATA. */
9763cd8854SHarvey Harrison magic_RSTR = cpu_to_le32(0x52545352), /* Restart page. */
9863cd8854SHarvey Harrison magic_RCRD = cpu_to_le32(0x44524352), /* Log record page. */
991da177e4SLinus Torvalds
1001da177e4SLinus Torvalds /* Found in $LogFile/$DATA. (May be found in $MFT/$DATA, also?) */
10163cd8854SHarvey Harrison magic_CHKD = cpu_to_le32(0x444b4843), /* Modified by chkdsk. */
1021da177e4SLinus Torvalds
1031da177e4SLinus Torvalds /* Found in all ntfs record containing records. */
10463cd8854SHarvey Harrison magic_BAAD = cpu_to_le32(0x44414142), /* Failed multi sector
1051da177e4SLinus Torvalds transfer was detected. */
1061da177e4SLinus Torvalds /*
1071da177e4SLinus Torvalds * Found in $LogFile/$DATA when a page is full of 0xff bytes and is
1081da177e4SLinus Torvalds * thus not initialized. Page must be initialized before using it.
1091da177e4SLinus Torvalds */
11063cd8854SHarvey Harrison magic_empty = cpu_to_le32(0xffffffff) /* Record is empty. */
1111da177e4SLinus Torvalds };
1121da177e4SLinus Torvalds
1131da177e4SLinus Torvalds typedef le32 NTFS_RECORD_TYPE;
1141da177e4SLinus Torvalds
1151da177e4SLinus Torvalds /*
1161da177e4SLinus Torvalds * Generic magic comparison macros. Finally found a use for the ## preprocessor
1171da177e4SLinus Torvalds * operator! (-8
1181da177e4SLinus Torvalds */
1191da177e4SLinus Torvalds
__ntfs_is_magic(le32 x,NTFS_RECORD_TYPE r)120c49c3111SRichard Knutsson static inline bool __ntfs_is_magic(le32 x, NTFS_RECORD_TYPE r)
1211da177e4SLinus Torvalds {
1221da177e4SLinus Torvalds return (x == r);
1231da177e4SLinus Torvalds }
1241da177e4SLinus Torvalds #define ntfs_is_magic(x, m) __ntfs_is_magic(x, magic_##m)
1251da177e4SLinus Torvalds
__ntfs_is_magicp(le32 * p,NTFS_RECORD_TYPE r)126c49c3111SRichard Knutsson static inline bool __ntfs_is_magicp(le32 *p, NTFS_RECORD_TYPE r)
1271da177e4SLinus Torvalds {
1281da177e4SLinus Torvalds return (*p == r);
1291da177e4SLinus Torvalds }
1301da177e4SLinus Torvalds #define ntfs_is_magicp(p, m) __ntfs_is_magicp(p, magic_##m)
1311da177e4SLinus Torvalds
1321da177e4SLinus Torvalds /*
1331da177e4SLinus Torvalds * Specialised magic comparison macros for the NTFS_RECORD_TYPEs defined above.
1341da177e4SLinus Torvalds */
1351da177e4SLinus Torvalds #define ntfs_is_file_record(x) ( ntfs_is_magic (x, FILE) )
1361da177e4SLinus Torvalds #define ntfs_is_file_recordp(p) ( ntfs_is_magicp(p, FILE) )
1371da177e4SLinus Torvalds #define ntfs_is_mft_record(x) ( ntfs_is_file_record (x) )
1381da177e4SLinus Torvalds #define ntfs_is_mft_recordp(p) ( ntfs_is_file_recordp(p) )
1391da177e4SLinus Torvalds #define ntfs_is_indx_record(x) ( ntfs_is_magic (x, INDX) )
1401da177e4SLinus Torvalds #define ntfs_is_indx_recordp(p) ( ntfs_is_magicp(p, INDX) )
1411da177e4SLinus Torvalds #define ntfs_is_hole_record(x) ( ntfs_is_magic (x, HOLE) )
1421da177e4SLinus Torvalds #define ntfs_is_hole_recordp(p) ( ntfs_is_magicp(p, HOLE) )
1431da177e4SLinus Torvalds
1441da177e4SLinus Torvalds #define ntfs_is_rstr_record(x) ( ntfs_is_magic (x, RSTR) )
1451da177e4SLinus Torvalds #define ntfs_is_rstr_recordp(p) ( ntfs_is_magicp(p, RSTR) )
1461da177e4SLinus Torvalds #define ntfs_is_rcrd_record(x) ( ntfs_is_magic (x, RCRD) )
1471da177e4SLinus Torvalds #define ntfs_is_rcrd_recordp(p) ( ntfs_is_magicp(p, RCRD) )
1481da177e4SLinus Torvalds
1491da177e4SLinus Torvalds #define ntfs_is_chkd_record(x) ( ntfs_is_magic (x, CHKD) )
1501da177e4SLinus Torvalds #define ntfs_is_chkd_recordp(p) ( ntfs_is_magicp(p, CHKD) )
1511da177e4SLinus Torvalds
1521da177e4SLinus Torvalds #define ntfs_is_baad_record(x) ( ntfs_is_magic (x, BAAD) )
1531da177e4SLinus Torvalds #define ntfs_is_baad_recordp(p) ( ntfs_is_magicp(p, BAAD) )
1541da177e4SLinus Torvalds
1551da177e4SLinus Torvalds #define ntfs_is_empty_record(x) ( ntfs_is_magic (x, empty) )
1561da177e4SLinus Torvalds #define ntfs_is_empty_recordp(p) ( ntfs_is_magicp(p, empty) )
1571da177e4SLinus Torvalds
1581da177e4SLinus Torvalds /*
1591da177e4SLinus Torvalds * The Update Sequence Array (usa) is an array of the le16 values which belong
1601da177e4SLinus Torvalds * to the end of each sector protected by the update sequence record in which
1611da177e4SLinus Torvalds * this array is contained. Note that the first entry is the Update Sequence
1621da177e4SLinus Torvalds * Number (usn), a cyclic counter of how many times the protected record has
1631da177e4SLinus Torvalds * been written to disk. The values 0 and -1 (ie. 0xffff) are not used. All
1641da177e4SLinus Torvalds * last le16's of each sector have to be equal to the usn (during reading) or
1651da177e4SLinus Torvalds * are set to it (during writing). If they are not, an incomplete multi sector
1661da177e4SLinus Torvalds * transfer has occurred when the data was written.
1671da177e4SLinus Torvalds * The maximum size for the update sequence array is fixed to:
1681da177e4SLinus Torvalds * maximum size = usa_ofs + (usa_count * 2) = 510 bytes
1691da177e4SLinus Torvalds * The 510 bytes comes from the fact that the last le16 in the array has to
1701da177e4SLinus Torvalds * (obviously) finish before the last le16 of the first 512-byte sector.
1711da177e4SLinus Torvalds * This formula can be used as a consistency check in that usa_ofs +
1721da177e4SLinus Torvalds * (usa_count * 2) has to be less than or equal to 510.
1731da177e4SLinus Torvalds */
1741da177e4SLinus Torvalds typedef struct {
1751da177e4SLinus Torvalds NTFS_RECORD_TYPE magic; /* A four-byte magic identifying the record
1761da177e4SLinus Torvalds type and/or status. */
1771da177e4SLinus Torvalds le16 usa_ofs; /* Offset to the Update Sequence Array (usa)
1781da177e4SLinus Torvalds from the start of the ntfs record. */
1791da177e4SLinus Torvalds le16 usa_count; /* Number of le16 sized entries in the usa
1801da177e4SLinus Torvalds including the Update Sequence Number (usn),
1811da177e4SLinus Torvalds thus the number of fixups is the usa_count
1821da177e4SLinus Torvalds minus 1. */
1831da177e4SLinus Torvalds } __attribute__ ((__packed__)) NTFS_RECORD;
1841da177e4SLinus Torvalds
1851da177e4SLinus Torvalds /*
1861da177e4SLinus Torvalds * System files mft record numbers. All these files are always marked as used
1871da177e4SLinus Torvalds * in the bitmap attribute of the mft; presumably in order to avoid accidental
1881da177e4SLinus Torvalds * allocation for random other mft records. Also, the sequence number for each
1891da177e4SLinus Torvalds * of the system files is always equal to their mft record number and it is
1901da177e4SLinus Torvalds * never modified.
1911da177e4SLinus Torvalds */
1921da177e4SLinus Torvalds typedef enum {
1931da177e4SLinus Torvalds FILE_MFT = 0, /* Master file table (mft). Data attribute
1941da177e4SLinus Torvalds contains the entries and bitmap attribute
1951da177e4SLinus Torvalds records which ones are in use (bit==1). */
1961da177e4SLinus Torvalds FILE_MFTMirr = 1, /* Mft mirror: copy of first four mft records
1971da177e4SLinus Torvalds in data attribute. If cluster size > 4kiB,
1981da177e4SLinus Torvalds copy of first N mft records, with
1991da177e4SLinus Torvalds N = cluster_size / mft_record_size. */
2001da177e4SLinus Torvalds FILE_LogFile = 2, /* Journalling log in data attribute. */
2011da177e4SLinus Torvalds FILE_Volume = 3, /* Volume name attribute and volume information
2021da177e4SLinus Torvalds attribute (flags and ntfs version). Windows
2031da177e4SLinus Torvalds refers to this file as volume DASD (Direct
2041da177e4SLinus Torvalds Access Storage Device). */
2051da177e4SLinus Torvalds FILE_AttrDef = 4, /* Array of attribute definitions in data
2061da177e4SLinus Torvalds attribute. */
2071da177e4SLinus Torvalds FILE_root = 5, /* Root directory. */
2081da177e4SLinus Torvalds FILE_Bitmap = 6, /* Allocation bitmap of all clusters (lcns) in
2091da177e4SLinus Torvalds data attribute. */
2101da177e4SLinus Torvalds FILE_Boot = 7, /* Boot sector (always at cluster 0) in data
2111da177e4SLinus Torvalds attribute. */
2121da177e4SLinus Torvalds FILE_BadClus = 8, /* Contains all bad clusters in the non-resident
2131da177e4SLinus Torvalds data attribute. */
2141da177e4SLinus Torvalds FILE_Secure = 9, /* Shared security descriptors in data attribute
2151da177e4SLinus Torvalds and two indexes into the descriptors.
2161da177e4SLinus Torvalds Appeared in Windows 2000. Before that, this
2171da177e4SLinus Torvalds file was named $Quota but was unused. */
2181da177e4SLinus Torvalds FILE_UpCase = 10, /* Uppercase equivalents of all 65536 Unicode
2191da177e4SLinus Torvalds characters in data attribute. */
2201da177e4SLinus Torvalds FILE_Extend = 11, /* Directory containing other system files (eg.
2211da177e4SLinus Torvalds $ObjId, $Quota, $Reparse and $UsnJrnl). This
2221da177e4SLinus Torvalds is new to NTFS3.0. */
2231da177e4SLinus Torvalds FILE_reserved12 = 12, /* Reserved for future use (records 12-15). */
2241da177e4SLinus Torvalds FILE_reserved13 = 13,
2251da177e4SLinus Torvalds FILE_reserved14 = 14,
2261da177e4SLinus Torvalds FILE_reserved15 = 15,
2271da177e4SLinus Torvalds FILE_first_user = 16, /* First user file, used as test limit for
2281da177e4SLinus Torvalds whether to allow opening a file or not. */
2291da177e4SLinus Torvalds } NTFS_SYSTEM_FILES;
2301da177e4SLinus Torvalds
2311da177e4SLinus Torvalds /*
2321da177e4SLinus Torvalds * These are the so far known MFT_RECORD_* flags (16-bit) which contain
2331da177e4SLinus Torvalds * information about the mft record in which they are present.
2341da177e4SLinus Torvalds */
2351da177e4SLinus Torvalds enum {
23663cd8854SHarvey Harrison MFT_RECORD_IN_USE = cpu_to_le16(0x0001),
23763cd8854SHarvey Harrison MFT_RECORD_IS_DIRECTORY = cpu_to_le16(0x0002),
2381da177e4SLinus Torvalds } __attribute__ ((__packed__));
2391da177e4SLinus Torvalds
2401da177e4SLinus Torvalds typedef le16 MFT_RECORD_FLAGS;
2411da177e4SLinus Torvalds
2421da177e4SLinus Torvalds /*
2431da177e4SLinus Torvalds * mft references (aka file references or file record segment references) are
2441da177e4SLinus Torvalds * used whenever a structure needs to refer to a record in the mft.
2451da177e4SLinus Torvalds *
2461da177e4SLinus Torvalds * A reference consists of a 48-bit index into the mft and a 16-bit sequence
2471da177e4SLinus Torvalds * number used to detect stale references.
2481da177e4SLinus Torvalds *
2491da177e4SLinus Torvalds * For error reporting purposes we treat the 48-bit index as a signed quantity.
2501da177e4SLinus Torvalds *
2511da177e4SLinus Torvalds * The sequence number is a circular counter (skipping 0) describing how many
2521da177e4SLinus Torvalds * times the referenced mft record has been (re)used. This has to match the
2531da177e4SLinus Torvalds * sequence number of the mft record being referenced, otherwise the reference
2541da177e4SLinus Torvalds * is considered stale and removed (FIXME: only ntfsck or the driver itself?).
2551da177e4SLinus Torvalds *
2561da177e4SLinus Torvalds * If the sequence number is zero it is assumed that no sequence number
2571da177e4SLinus Torvalds * consistency checking should be performed.
2581da177e4SLinus Torvalds *
2591da177e4SLinus Torvalds * FIXME: Since inodes are 32-bit as of now, the driver needs to always check
2601da177e4SLinus Torvalds * for high_part being 0 and if not either BUG(), cause a panic() or handle
2611da177e4SLinus Torvalds * the situation in some other way. This shouldn't be a problem as a volume has
2621da177e4SLinus Torvalds * to become HUGE in order to need more than 32-bits worth of mft records.
2631da177e4SLinus Torvalds * Assuming the standard mft record size of 1kb only the records (never mind
2641da177e4SLinus Torvalds * the non-resident attributes, etc.) would require 4Tb of space on their own
2651da177e4SLinus Torvalds * for the first 32 bits worth of records. This is only if some strange person
2661da177e4SLinus Torvalds * doesn't decide to foul play and make the mft sparse which would be a really
2671da177e4SLinus Torvalds * horrible thing to do as it would trash our current driver implementation. )-:
2681da177e4SLinus Torvalds * Do I hear screams "we want 64-bit inodes!" ?!? (-;
2691da177e4SLinus Torvalds *
2701da177e4SLinus Torvalds * FIXME: The mft zone is defined as the first 12% of the volume. This space is
2711da177e4SLinus Torvalds * reserved so that the mft can grow contiguously and hence doesn't become
2721da177e4SLinus Torvalds * fragmented. Volume free space includes the empty part of the mft zone and
2731da177e4SLinus Torvalds * when the volume's free 88% are used up, the mft zone is shrunk by a factor
2741da177e4SLinus Torvalds * of 2, thus making more space available for more files/data. This process is
2751da177e4SLinus Torvalds * repeated every time there is no more free space except for the mft zone until
2761da177e4SLinus Torvalds * there really is no more free space.
2771da177e4SLinus Torvalds */
2781da177e4SLinus Torvalds
2791da177e4SLinus Torvalds /*
2801da177e4SLinus Torvalds * Typedef the MFT_REF as a 64-bit value for easier handling.
2811da177e4SLinus Torvalds * Also define two unpacking macros to get to the reference (MREF) and
2821da177e4SLinus Torvalds * sequence number (MSEQNO) respectively.
2831da177e4SLinus Torvalds * The _LE versions are to be applied on little endian MFT_REFs.
2841da177e4SLinus Torvalds * Note: The _LE versions will return a CPU endian formatted value!
2851da177e4SLinus Torvalds */
286e2fcc61eSAnton Altaparmakov #define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
28763cd8854SHarvey Harrison #define MFT_REF_MASK_LE cpu_to_le64(MFT_REF_MASK_CPU)
2881da177e4SLinus Torvalds
2891da177e4SLinus Torvalds typedef u64 MFT_REF;
2901da177e4SLinus Torvalds typedef le64 leMFT_REF;
2911da177e4SLinus Torvalds
2921da177e4SLinus Torvalds #define MK_MREF(m, s) ((MFT_REF)(((MFT_REF)(s) << 48) | \
293e2fcc61eSAnton Altaparmakov ((MFT_REF)(m) & MFT_REF_MASK_CPU)))
2941da177e4SLinus Torvalds #define MK_LE_MREF(m, s) cpu_to_le64(MK_MREF(m, s))
2951da177e4SLinus Torvalds
296e2fcc61eSAnton Altaparmakov #define MREF(x) ((unsigned long)((x) & MFT_REF_MASK_CPU))
2971da177e4SLinus Torvalds #define MSEQNO(x) ((u16)(((x) >> 48) & 0xffff))
298e2fcc61eSAnton Altaparmakov #define MREF_LE(x) ((unsigned long)(le64_to_cpu(x) & MFT_REF_MASK_CPU))
2991da177e4SLinus Torvalds #define MSEQNO_LE(x) ((u16)((le64_to_cpu(x) >> 48) & 0xffff))
3001da177e4SLinus Torvalds
301c49c3111SRichard Knutsson #define IS_ERR_MREF(x) (((x) & 0x0000800000000000ULL) ? true : false)
3021da177e4SLinus Torvalds #define ERR_MREF(x) ((u64)((s64)(x)))
3031da177e4SLinus Torvalds #define MREF_ERR(x) ((int)((s64)(x)))
3041da177e4SLinus Torvalds
3051da177e4SLinus Torvalds /*
3061da177e4SLinus Torvalds * The mft record header present at the beginning of every record in the mft.
3071da177e4SLinus Torvalds * This is followed by a sequence of variable length attribute records which
3081da177e4SLinus Torvalds * is terminated by an attribute of type AT_END which is a truncated attribute
3091da177e4SLinus Torvalds * in that it only consists of the attribute type code AT_END and none of the
3101da177e4SLinus Torvalds * other members of the attribute structure are present.
3111da177e4SLinus Torvalds */
3121da177e4SLinus Torvalds typedef struct {
3131da177e4SLinus Torvalds /*Ofs*/
3141da177e4SLinus Torvalds /* 0 NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
3151da177e4SLinus Torvalds NTFS_RECORD_TYPE magic; /* Usually the magic is "FILE". */
3161da177e4SLinus Torvalds le16 usa_ofs; /* See NTFS_RECORD definition above. */
3171da177e4SLinus Torvalds le16 usa_count; /* See NTFS_RECORD definition above. */
3181da177e4SLinus Torvalds
3191da177e4SLinus Torvalds /* 8*/ le64 lsn; /* $LogFile sequence number for this record.
3201da177e4SLinus Torvalds Changed every time the record is modified. */
3211da177e4SLinus Torvalds /* 16*/ le16 sequence_number; /* Number of times this mft record has been
3221da177e4SLinus Torvalds reused. (See description for MFT_REF
3231da177e4SLinus Torvalds above.) NOTE: The increment (skipping zero)
3241da177e4SLinus Torvalds is done when the file is deleted. NOTE: If
3251da177e4SLinus Torvalds this is zero it is left zero. */
3261da177e4SLinus Torvalds /* 18*/ le16 link_count; /* Number of hard links, i.e. the number of
3271da177e4SLinus Torvalds directory entries referencing this record.
3281da177e4SLinus Torvalds NOTE: Only used in mft base records.
3291da177e4SLinus Torvalds NOTE: When deleting a directory entry we
3301da177e4SLinus Torvalds check the link_count and if it is 1 we
3311da177e4SLinus Torvalds delete the file. Otherwise we delete the
3321da177e4SLinus Torvalds FILE_NAME_ATTR being referenced by the
3331da177e4SLinus Torvalds directory entry from the mft record and
3341da177e4SLinus Torvalds decrement the link_count.
3351da177e4SLinus Torvalds FIXME: Careful with Win32 + DOS names! */
3361da177e4SLinus Torvalds /* 20*/ le16 attrs_offset; /* Byte offset to the first attribute in this
3371da177e4SLinus Torvalds mft record from the start of the mft record.
3381da177e4SLinus Torvalds NOTE: Must be aligned to 8-byte boundary. */
3391da177e4SLinus Torvalds /* 22*/ MFT_RECORD_FLAGS flags; /* Bit array of MFT_RECORD_FLAGS. When a file
3401da177e4SLinus Torvalds is deleted, the MFT_RECORD_IN_USE flag is
3411da177e4SLinus Torvalds set to zero. */
3421da177e4SLinus Torvalds /* 24*/ le32 bytes_in_use; /* Number of bytes used in this mft record.
3431da177e4SLinus Torvalds NOTE: Must be aligned to 8-byte boundary. */
3441da177e4SLinus Torvalds /* 28*/ le32 bytes_allocated; /* Number of bytes allocated for this mft
3451da177e4SLinus Torvalds record. This should be equal to the mft
3461da177e4SLinus Torvalds record size. */
3471da177e4SLinus Torvalds /* 32*/ leMFT_REF base_mft_record;/* This is zero for base mft records.
3481da177e4SLinus Torvalds When it is not zero it is a mft reference
3491da177e4SLinus Torvalds pointing to the base mft record to which
3501da177e4SLinus Torvalds this record belongs (this is then used to
3511da177e4SLinus Torvalds locate the attribute list attribute present
3521da177e4SLinus Torvalds in the base record which describes this
3531da177e4SLinus Torvalds extension record and hence might need
3541da177e4SLinus Torvalds modification when the extension record
3551da177e4SLinus Torvalds itself is modified, also locating the
3561da177e4SLinus Torvalds attribute list also means finding the other
3571da177e4SLinus Torvalds potential extents, belonging to the non-base
3581da177e4SLinus Torvalds mft record). */
3591da177e4SLinus Torvalds /* 40*/ le16 next_attr_instance;/* The instance number that will be assigned to
3601da177e4SLinus Torvalds the next attribute added to this mft record.
3611da177e4SLinus Torvalds NOTE: Incremented each time after it is used.
3621da177e4SLinus Torvalds NOTE: Every time the mft record is reused
3631da177e4SLinus Torvalds this number is set to zero. NOTE: The first
3641da177e4SLinus Torvalds instance number is always 0. */
3651da177e4SLinus Torvalds /* The below fields are specific to NTFS 3.1+ (Windows XP and above): */
3661da177e4SLinus Torvalds /* 42*/ le16 reserved; /* Reserved/alignment. */
3671da177e4SLinus Torvalds /* 44*/ le32 mft_record_number; /* Number of this mft record. */
3681da177e4SLinus Torvalds /* sizeof() = 48 bytes */
3691da177e4SLinus Torvalds /*
3701da177e4SLinus Torvalds * When (re)using the mft record, we place the update sequence array at this
3711da177e4SLinus Torvalds * offset, i.e. before we start with the attributes. This also makes sense,
3721da177e4SLinus Torvalds * otherwise we could run into problems with the update sequence array
3731da177e4SLinus Torvalds * containing in itself the last two bytes of a sector which would mean that
3741da177e4SLinus Torvalds * multi sector transfer protection wouldn't work. As you can't protect data
3751da177e4SLinus Torvalds * by overwriting it since you then can't get it back...
3761da177e4SLinus Torvalds * When reading we obviously use the data from the ntfs record header.
3771da177e4SLinus Torvalds */
3781da177e4SLinus Torvalds } __attribute__ ((__packed__)) MFT_RECORD;
3791da177e4SLinus Torvalds
3801da177e4SLinus Torvalds /* This is the version without the NTFS 3.1+ specific fields. */
3811da177e4SLinus Torvalds typedef struct {
3821da177e4SLinus Torvalds /*Ofs*/
3831da177e4SLinus Torvalds /* 0 NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
3841da177e4SLinus Torvalds NTFS_RECORD_TYPE magic; /* Usually the magic is "FILE". */
3851da177e4SLinus Torvalds le16 usa_ofs; /* See NTFS_RECORD definition above. */
3861da177e4SLinus Torvalds le16 usa_count; /* See NTFS_RECORD definition above. */
3871da177e4SLinus Torvalds
3881da177e4SLinus Torvalds /* 8*/ le64 lsn; /* $LogFile sequence number for this record.
3891da177e4SLinus Torvalds Changed every time the record is modified. */
3901da177e4SLinus Torvalds /* 16*/ le16 sequence_number; /* Number of times this mft record has been
3911da177e4SLinus Torvalds reused. (See description for MFT_REF
3921da177e4SLinus Torvalds above.) NOTE: The increment (skipping zero)
3931da177e4SLinus Torvalds is done when the file is deleted. NOTE: If
3941da177e4SLinus Torvalds this is zero it is left zero. */
3951da177e4SLinus Torvalds /* 18*/ le16 link_count; /* Number of hard links, i.e. the number of
3961da177e4SLinus Torvalds directory entries referencing this record.
3971da177e4SLinus Torvalds NOTE: Only used in mft base records.
3981da177e4SLinus Torvalds NOTE: When deleting a directory entry we
3991da177e4SLinus Torvalds check the link_count and if it is 1 we
4001da177e4SLinus Torvalds delete the file. Otherwise we delete the
4011da177e4SLinus Torvalds FILE_NAME_ATTR being referenced by the
4021da177e4SLinus Torvalds directory entry from the mft record and
4031da177e4SLinus Torvalds decrement the link_count.
4041da177e4SLinus Torvalds FIXME: Careful with Win32 + DOS names! */
4051da177e4SLinus Torvalds /* 20*/ le16 attrs_offset; /* Byte offset to the first attribute in this
4061da177e4SLinus Torvalds mft record from the start of the mft record.
4071da177e4SLinus Torvalds NOTE: Must be aligned to 8-byte boundary. */
4081da177e4SLinus Torvalds /* 22*/ MFT_RECORD_FLAGS flags; /* Bit array of MFT_RECORD_FLAGS. When a file
4091da177e4SLinus Torvalds is deleted, the MFT_RECORD_IN_USE flag is
4101da177e4SLinus Torvalds set to zero. */
4111da177e4SLinus Torvalds /* 24*/ le32 bytes_in_use; /* Number of bytes used in this mft record.
4121da177e4SLinus Torvalds NOTE: Must be aligned to 8-byte boundary. */
4131da177e4SLinus Torvalds /* 28*/ le32 bytes_allocated; /* Number of bytes allocated for this mft
4141da177e4SLinus Torvalds record. This should be equal to the mft
4151da177e4SLinus Torvalds record size. */
4161da177e4SLinus Torvalds /* 32*/ leMFT_REF base_mft_record;/* This is zero for base mft records.
4171da177e4SLinus Torvalds When it is not zero it is a mft reference
4181da177e4SLinus Torvalds pointing to the base mft record to which
4191da177e4SLinus Torvalds this record belongs (this is then used to
4201da177e4SLinus Torvalds locate the attribute list attribute present
4211da177e4SLinus Torvalds in the base record which describes this
4221da177e4SLinus Torvalds extension record and hence might need
4231da177e4SLinus Torvalds modification when the extension record
4241da177e4SLinus Torvalds itself is modified, also locating the
4251da177e4SLinus Torvalds attribute list also means finding the other
4261da177e4SLinus Torvalds potential extents, belonging to the non-base
4271da177e4SLinus Torvalds mft record). */
4281da177e4SLinus Torvalds /* 40*/ le16 next_attr_instance;/* The instance number that will be assigned to
4291da177e4SLinus Torvalds the next attribute added to this mft record.
4301da177e4SLinus Torvalds NOTE: Incremented each time after it is used.
4311da177e4SLinus Torvalds NOTE: Every time the mft record is reused
4321da177e4SLinus Torvalds this number is set to zero. NOTE: The first
4331da177e4SLinus Torvalds instance number is always 0. */
4341da177e4SLinus Torvalds /* sizeof() = 42 bytes */
4351da177e4SLinus Torvalds /*
4361da177e4SLinus Torvalds * When (re)using the mft record, we place the update sequence array at this
4371da177e4SLinus Torvalds * offset, i.e. before we start with the attributes. This also makes sense,
4381da177e4SLinus Torvalds * otherwise we could run into problems with the update sequence array
4391da177e4SLinus Torvalds * containing in itself the last two bytes of a sector which would mean that
4401da177e4SLinus Torvalds * multi sector transfer protection wouldn't work. As you can't protect data
4411da177e4SLinus Torvalds * by overwriting it since you then can't get it back...
4421da177e4SLinus Torvalds * When reading we obviously use the data from the ntfs record header.
4431da177e4SLinus Torvalds */
4441da177e4SLinus Torvalds } __attribute__ ((__packed__)) MFT_RECORD_OLD;
4451da177e4SLinus Torvalds
4461da177e4SLinus Torvalds /*
4471da177e4SLinus Torvalds * System defined attributes (32-bit). Each attribute type has a corresponding
4481da177e4SLinus Torvalds * attribute name (Unicode string of maximum 64 character length) as described
4491da177e4SLinus Torvalds * by the attribute definitions present in the data attribute of the $AttrDef
4501da177e4SLinus Torvalds * system file. On NTFS 3.0 volumes the names are just as the types are named
4511da177e4SLinus Torvalds * in the below defines exchanging AT_ for the dollar sign ($). If that is not
4521da177e4SLinus Torvalds * a revealing choice of symbol I do not know what is... (-;
4531da177e4SLinus Torvalds */
4541da177e4SLinus Torvalds enum {
45563cd8854SHarvey Harrison AT_UNUSED = cpu_to_le32( 0),
45663cd8854SHarvey Harrison AT_STANDARD_INFORMATION = cpu_to_le32( 0x10),
45763cd8854SHarvey Harrison AT_ATTRIBUTE_LIST = cpu_to_le32( 0x20),
45863cd8854SHarvey Harrison AT_FILE_NAME = cpu_to_le32( 0x30),
45963cd8854SHarvey Harrison AT_OBJECT_ID = cpu_to_le32( 0x40),
46063cd8854SHarvey Harrison AT_SECURITY_DESCRIPTOR = cpu_to_le32( 0x50),
46163cd8854SHarvey Harrison AT_VOLUME_NAME = cpu_to_le32( 0x60),
46263cd8854SHarvey Harrison AT_VOLUME_INFORMATION = cpu_to_le32( 0x70),
46363cd8854SHarvey Harrison AT_DATA = cpu_to_le32( 0x80),
46463cd8854SHarvey Harrison AT_INDEX_ROOT = cpu_to_le32( 0x90),
46563cd8854SHarvey Harrison AT_INDEX_ALLOCATION = cpu_to_le32( 0xa0),
46663cd8854SHarvey Harrison AT_BITMAP = cpu_to_le32( 0xb0),
46763cd8854SHarvey Harrison AT_REPARSE_POINT = cpu_to_le32( 0xc0),
46863cd8854SHarvey Harrison AT_EA_INFORMATION = cpu_to_le32( 0xd0),
46963cd8854SHarvey Harrison AT_EA = cpu_to_le32( 0xe0),
47063cd8854SHarvey Harrison AT_PROPERTY_SET = cpu_to_le32( 0xf0),
47163cd8854SHarvey Harrison AT_LOGGED_UTILITY_STREAM = cpu_to_le32( 0x100),
47263cd8854SHarvey Harrison AT_FIRST_USER_DEFINED_ATTRIBUTE = cpu_to_le32( 0x1000),
47363cd8854SHarvey Harrison AT_END = cpu_to_le32(0xffffffff)
4741da177e4SLinus Torvalds };
4751da177e4SLinus Torvalds
4761da177e4SLinus Torvalds typedef le32 ATTR_TYPE;
4771da177e4SLinus Torvalds
4781da177e4SLinus Torvalds /*
4791da177e4SLinus Torvalds * The collation rules for sorting views/indexes/etc (32-bit).
4801da177e4SLinus Torvalds *
4811da177e4SLinus Torvalds * COLLATION_BINARY - Collate by binary compare where the first byte is most
4821da177e4SLinus Torvalds * significant.
4831da177e4SLinus Torvalds * COLLATION_UNICODE_STRING - Collate Unicode strings by comparing their binary
4841da177e4SLinus Torvalds * Unicode values, except that when a character can be uppercased, the
4851da177e4SLinus Torvalds * upper case value collates before the lower case one.
4861da177e4SLinus Torvalds * COLLATION_FILE_NAME - Collate file names as Unicode strings. The collation
4871da177e4SLinus Torvalds * is done very much like COLLATION_UNICODE_STRING. In fact I have no idea
4881da177e4SLinus Torvalds * what the difference is. Perhaps the difference is that file names
4891da177e4SLinus Torvalds * would treat some special characters in an odd way (see
4901da177e4SLinus Torvalds * unistr.c::ntfs_collate_names() and unistr.c::legal_ansi_char_array[]
4911da177e4SLinus Torvalds * for what I mean but COLLATION_UNICODE_STRING would not give any special
4921da177e4SLinus Torvalds * treatment to any characters at all, but this is speculation.
4931da177e4SLinus Torvalds * COLLATION_NTOFS_ULONG - Sorting is done according to ascending le32 key
4941da177e4SLinus Torvalds * values. E.g. used for $SII index in FILE_Secure, which sorts by
4951da177e4SLinus Torvalds * security_id (le32).
4961da177e4SLinus Torvalds * COLLATION_NTOFS_SID - Sorting is done according to ascending SID values.
4971da177e4SLinus Torvalds * E.g. used for $O index in FILE_Extend/$Quota.
4981da177e4SLinus Torvalds * COLLATION_NTOFS_SECURITY_HASH - Sorting is done first by ascending hash
4991da177e4SLinus Torvalds * values and second by ascending security_id values. E.g. used for $SDH
5001da177e4SLinus Torvalds * index in FILE_Secure.
5011da177e4SLinus Torvalds * COLLATION_NTOFS_ULONGS - Sorting is done according to a sequence of ascending
5021da177e4SLinus Torvalds * le32 key values. E.g. used for $O index in FILE_Extend/$ObjId, which
5031da177e4SLinus Torvalds * sorts by object_id (16-byte), by splitting up the object_id in four
5041da177e4SLinus Torvalds * le32 values and using them as individual keys. E.g. take the following
5051da177e4SLinus Torvalds * two security_ids, stored as follows on disk:
5061da177e4SLinus Torvalds * 1st: a1 61 65 b7 65 7b d4 11 9e 3d 00 e0 81 10 42 59
5071da177e4SLinus Torvalds * 2nd: 38 14 37 d2 d2 f3 d4 11 a5 21 c8 6b 79 b1 97 45
5081da177e4SLinus Torvalds * To compare them, they are split into four le32 values each, like so:
5091da177e4SLinus Torvalds * 1st: 0xb76561a1 0x11d47b65 0xe0003d9e 0x59421081
5101da177e4SLinus Torvalds * 2nd: 0xd2371438 0x11d4f3d2 0x6bc821a5 0x4597b179
5111da177e4SLinus Torvalds * Now, it is apparent why the 2nd object_id collates after the 1st: the
5121da177e4SLinus Torvalds * first le32 value of the 1st object_id is less than the first le32 of
5131da177e4SLinus Torvalds * the 2nd object_id. If the first le32 values of both object_ids were
5141da177e4SLinus Torvalds * equal then the second le32 values would be compared, etc.
5151da177e4SLinus Torvalds */
5161da177e4SLinus Torvalds enum {
51763cd8854SHarvey Harrison COLLATION_BINARY = cpu_to_le32(0x00),
51863cd8854SHarvey Harrison COLLATION_FILE_NAME = cpu_to_le32(0x01),
51963cd8854SHarvey Harrison COLLATION_UNICODE_STRING = cpu_to_le32(0x02),
52063cd8854SHarvey Harrison COLLATION_NTOFS_ULONG = cpu_to_le32(0x10),
52163cd8854SHarvey Harrison COLLATION_NTOFS_SID = cpu_to_le32(0x11),
52263cd8854SHarvey Harrison COLLATION_NTOFS_SECURITY_HASH = cpu_to_le32(0x12),
52363cd8854SHarvey Harrison COLLATION_NTOFS_ULONGS = cpu_to_le32(0x13),
5241da177e4SLinus Torvalds };
5251da177e4SLinus Torvalds
5261da177e4SLinus Torvalds typedef le32 COLLATION_RULE;
5271da177e4SLinus Torvalds
5281da177e4SLinus Torvalds /*
5291da177e4SLinus Torvalds * The flags (32-bit) describing attribute properties in the attribute
530bb3cf335SAnton Altaparmakov * definition structure. FIXME: This information is based on Regis's
531bb3cf335SAnton Altaparmakov * information and, according to him, it is not certain and probably
532bb3cf335SAnton Altaparmakov * incomplete. The INDEXABLE flag is fairly certainly correct as only the file
533bb3cf335SAnton Altaparmakov * name attribute has this flag set and this is the only attribute indexed in
534bb3cf335SAnton Altaparmakov * NT4.
5351da177e4SLinus Torvalds */
5361da177e4SLinus Torvalds enum {
53763cd8854SHarvey Harrison ATTR_DEF_INDEXABLE = cpu_to_le32(0x02), /* Attribute can be
5381da177e4SLinus Torvalds indexed. */
53963cd8854SHarvey Harrison ATTR_DEF_MULTIPLE = cpu_to_le32(0x04), /* Attribute type
540bb3cf335SAnton Altaparmakov can be present multiple times in the
541bb3cf335SAnton Altaparmakov mft records of an inode. */
54263cd8854SHarvey Harrison ATTR_DEF_NOT_ZERO = cpu_to_le32(0x08), /* Attribute value
543bb3cf335SAnton Altaparmakov must contain at least one non-zero
544bb3cf335SAnton Altaparmakov byte. */
54563cd8854SHarvey Harrison ATTR_DEF_INDEXED_UNIQUE = cpu_to_le32(0x10), /* Attribute must be
546bb3cf335SAnton Altaparmakov indexed and the attribute value must be
547bb3cf335SAnton Altaparmakov unique for the attribute type in all of
548bb3cf335SAnton Altaparmakov the mft records of an inode. */
54963cd8854SHarvey Harrison ATTR_DEF_NAMED_UNIQUE = cpu_to_le32(0x20), /* Attribute must be
550bb3cf335SAnton Altaparmakov named and the name must be unique for
551bb3cf335SAnton Altaparmakov the attribute type in all of the mft
552bb3cf335SAnton Altaparmakov records of an inode. */
55363cd8854SHarvey Harrison ATTR_DEF_RESIDENT = cpu_to_le32(0x40), /* Attribute must be
554bb3cf335SAnton Altaparmakov resident. */
55563cd8854SHarvey Harrison ATTR_DEF_ALWAYS_LOG = cpu_to_le32(0x80), /* Always log
556bb3cf335SAnton Altaparmakov modifications to this attribute,
557bb3cf335SAnton Altaparmakov regardless of whether it is resident or
558bb3cf335SAnton Altaparmakov non-resident. Without this, only log
559bb3cf335SAnton Altaparmakov modifications if the attribute is
560bb3cf335SAnton Altaparmakov resident. */
5611da177e4SLinus Torvalds };
5621da177e4SLinus Torvalds
5631da177e4SLinus Torvalds typedef le32 ATTR_DEF_FLAGS;
5641da177e4SLinus Torvalds
5651da177e4SLinus Torvalds /*
5661da177e4SLinus Torvalds * The data attribute of FILE_AttrDef contains a sequence of attribute
5671da177e4SLinus Torvalds * definitions for the NTFS volume. With this, it is supposed to be safe for an
5681da177e4SLinus Torvalds * older NTFS driver to mount a volume containing a newer NTFS version without
5691da177e4SLinus Torvalds * damaging it (that's the theory. In practice it's: not damaging it too much).
5701da177e4SLinus Torvalds * Entries are sorted by attribute type. The flags describe whether the
5711da177e4SLinus Torvalds * attribute can be resident/non-resident and possibly other things, but the
5721da177e4SLinus Torvalds * actual bits are unknown.
5731da177e4SLinus Torvalds */
5741da177e4SLinus Torvalds typedef struct {
5751da177e4SLinus Torvalds /*hex ofs*/
5761da177e4SLinus Torvalds /* 0*/ ntfschar name[0x40]; /* Unicode name of the attribute. Zero
5771da177e4SLinus Torvalds terminated. */
5781da177e4SLinus Torvalds /* 80*/ ATTR_TYPE type; /* Type of the attribute. */
5791da177e4SLinus Torvalds /* 84*/ le32 display_rule; /* Default display rule.
5801da177e4SLinus Torvalds FIXME: What does it mean? (AIA) */
5811da177e4SLinus Torvalds /* 88*/ COLLATION_RULE collation_rule; /* Default collation rule. */
5821da177e4SLinus Torvalds /* 8c*/ ATTR_DEF_FLAGS flags; /* Flags describing the attribute. */
5831da177e4SLinus Torvalds /* 90*/ sle64 min_size; /* Optional minimum attribute size. */
5841da177e4SLinus Torvalds /* 98*/ sle64 max_size; /* Maximum size of attribute. */
5851da177e4SLinus Torvalds /* sizeof() = 0xa0 or 160 bytes */
5861da177e4SLinus Torvalds } __attribute__ ((__packed__)) ATTR_DEF;
5871da177e4SLinus Torvalds
5881da177e4SLinus Torvalds /*
5891da177e4SLinus Torvalds * Attribute flags (16-bit).
5901da177e4SLinus Torvalds */
5911da177e4SLinus Torvalds enum {
59263cd8854SHarvey Harrison ATTR_IS_COMPRESSED = cpu_to_le16(0x0001),
59363cd8854SHarvey Harrison ATTR_COMPRESSION_MASK = cpu_to_le16(0x00ff), /* Compression method
5941da177e4SLinus Torvalds mask. Also, first
5951da177e4SLinus Torvalds illegal value. */
59663cd8854SHarvey Harrison ATTR_IS_ENCRYPTED = cpu_to_le16(0x4000),
59763cd8854SHarvey Harrison ATTR_IS_SPARSE = cpu_to_le16(0x8000),
5981da177e4SLinus Torvalds } __attribute__ ((__packed__));
5991da177e4SLinus Torvalds
6001da177e4SLinus Torvalds typedef le16 ATTR_FLAGS;
6011da177e4SLinus Torvalds
6021da177e4SLinus Torvalds /*
6031da177e4SLinus Torvalds * Attribute compression.
6041da177e4SLinus Torvalds *
6051da177e4SLinus Torvalds * Only the data attribute is ever compressed in the current ntfs driver in
6061da177e4SLinus Torvalds * Windows. Further, compression is only applied when the data attribute is
6071da177e4SLinus Torvalds * non-resident. Finally, to use compression, the maximum allowed cluster size
6081da177e4SLinus Torvalds * on a volume is 4kib.
6091da177e4SLinus Torvalds *
6101da177e4SLinus Torvalds * The compression method is based on independently compressing blocks of X
6111da177e4SLinus Torvalds * clusters, where X is determined from the compression_unit value found in the
6121da177e4SLinus Torvalds * non-resident attribute record header (more precisely: X = 2^compression_unit
6131da177e4SLinus Torvalds * clusters). On Windows NT/2k, X always is 16 clusters (compression_unit = 4).
6141da177e4SLinus Torvalds *
6151da177e4SLinus Torvalds * There are three different cases of how a compression block of X clusters
6161da177e4SLinus Torvalds * can be stored:
6171da177e4SLinus Torvalds *
6181da177e4SLinus Torvalds * 1) The data in the block is all zero (a sparse block):
6191da177e4SLinus Torvalds * This is stored as a sparse block in the runlist, i.e. the runlist
6201da177e4SLinus Torvalds * entry has length = X and lcn = -1. The mapping pairs array actually
6211da177e4SLinus Torvalds * uses a delta_lcn value length of 0, i.e. delta_lcn is not present at
6221da177e4SLinus Torvalds * all, which is then interpreted by the driver as lcn = -1.
6231da177e4SLinus Torvalds * NOTE: Even uncompressed files can be sparse on NTFS 3.0 volumes, then
6241da177e4SLinus Torvalds * the same principles apply as above, except that the length is not
6251da177e4SLinus Torvalds * restricted to being any particular value.
6261da177e4SLinus Torvalds *
6271da177e4SLinus Torvalds * 2) The data in the block is not compressed:
6281da177e4SLinus Torvalds * This happens when compression doesn't reduce the size of the block
6291da177e4SLinus Torvalds * in clusters. I.e. if compression has a small effect so that the
6301da177e4SLinus Torvalds * compressed data still occupies X clusters, then the uncompressed data
6311da177e4SLinus Torvalds * is stored in the block.
6321da177e4SLinus Torvalds * This case is recognised by the fact that the runlist entry has
6331da177e4SLinus Torvalds * length = X and lcn >= 0. The mapping pairs array stores this as
6341da177e4SLinus Torvalds * normal with a run length of X and some specific delta_lcn, i.e.
6351da177e4SLinus Torvalds * delta_lcn has to be present.
6361da177e4SLinus Torvalds *
6371da177e4SLinus Torvalds * 3) The data in the block is compressed:
6381da177e4SLinus Torvalds * The common case. This case is recognised by the fact that the run
6391da177e4SLinus Torvalds * list entry has length L < X and lcn >= 0. The mapping pairs array
6401da177e4SLinus Torvalds * stores this as normal with a run length of X and some specific
6411da177e4SLinus Torvalds * delta_lcn, i.e. delta_lcn has to be present. This runlist entry is
6421da177e4SLinus Torvalds * immediately followed by a sparse entry with length = X - L and
6431da177e4SLinus Torvalds * lcn = -1. The latter entry is to make up the vcn counting to the
6441da177e4SLinus Torvalds * full compression block size X.
6451da177e4SLinus Torvalds *
6461da177e4SLinus Torvalds * In fact, life is more complicated because adjacent entries of the same type
6471da177e4SLinus Torvalds * can be coalesced. This means that one has to keep track of the number of
6481da177e4SLinus Torvalds * clusters handled and work on a basis of X clusters at a time being one
6491da177e4SLinus Torvalds * block. An example: if length L > X this means that this particular runlist
6501da177e4SLinus Torvalds * entry contains a block of length X and part of one or more blocks of length
6511da177e4SLinus Torvalds * L - X. Another example: if length L < X, this does not necessarily mean that
6521da177e4SLinus Torvalds * the block is compressed as it might be that the lcn changes inside the block
6531da177e4SLinus Torvalds * and hence the following runlist entry describes the continuation of the
6541da177e4SLinus Torvalds * potentially compressed block. The block would be compressed if the
6551da177e4SLinus Torvalds * following runlist entry describes at least X - L sparse clusters, thus
6561da177e4SLinus Torvalds * making up the compression block length as described in point 3 above. (Of
6571da177e4SLinus Torvalds * course, there can be several runlist entries with small lengths so that the
6581da177e4SLinus Torvalds * sparse entry does not follow the first data containing entry with
6591da177e4SLinus Torvalds * length < X.)
6601da177e4SLinus Torvalds *
6611da177e4SLinus Torvalds * NOTE: At the end of the compressed attribute value, there most likely is not
6621da177e4SLinus Torvalds * just the right amount of data to make up a compression block, thus this data
6631da177e4SLinus Torvalds * is not even attempted to be compressed. It is just stored as is, unless
6641da177e4SLinus Torvalds * the number of clusters it occupies is reduced when compressed in which case
6651da177e4SLinus Torvalds * it is stored as a compressed compression block, complete with sparse
6661da177e4SLinus Torvalds * clusters at the end.
6671da177e4SLinus Torvalds */
6681da177e4SLinus Torvalds
6691da177e4SLinus Torvalds /*
6701da177e4SLinus Torvalds * Flags of resident attributes (8-bit).
6711da177e4SLinus Torvalds */
6721da177e4SLinus Torvalds enum {
6731da177e4SLinus Torvalds RESIDENT_ATTR_IS_INDEXED = 0x01, /* Attribute is referenced in an index
6741da177e4SLinus Torvalds (has implications for deleting and
6751da177e4SLinus Torvalds modifying the attribute). */
6761da177e4SLinus Torvalds } __attribute__ ((__packed__));
6771da177e4SLinus Torvalds
6781da177e4SLinus Torvalds typedef u8 RESIDENT_ATTR_FLAGS;
6791da177e4SLinus Torvalds
6801da177e4SLinus Torvalds /*
6811da177e4SLinus Torvalds * Attribute record header. Always aligned to 8-byte boundary.
6821da177e4SLinus Torvalds */
6831da177e4SLinus Torvalds typedef struct {
6841da177e4SLinus Torvalds /*Ofs*/
6851da177e4SLinus Torvalds /* 0*/ ATTR_TYPE type; /* The (32-bit) type of the attribute. */
6861da177e4SLinus Torvalds /* 4*/ le32 length; /* Byte size of the resident part of the
6871da177e4SLinus Torvalds attribute (aligned to 8-byte boundary).
6881da177e4SLinus Torvalds Used to get to the next attribute. */
6891da177e4SLinus Torvalds /* 8*/ u8 non_resident; /* If 0, attribute is resident.
6901da177e4SLinus Torvalds If 1, attribute is non-resident. */
6911da177e4SLinus Torvalds /* 9*/ u8 name_length; /* Unicode character size of name of attribute.
6921da177e4SLinus Torvalds 0 if unnamed. */
6931da177e4SLinus Torvalds /* 10*/ le16 name_offset; /* If name_length != 0, the byte offset to the
6941da177e4SLinus Torvalds beginning of the name from the attribute
6951da177e4SLinus Torvalds record. Note that the name is stored as a
6961da177e4SLinus Torvalds Unicode string. When creating, place offset
6971da177e4SLinus Torvalds just at the end of the record header. Then,
6981da177e4SLinus Torvalds follow with attribute value or mapping pairs
6991da177e4SLinus Torvalds array, resident and non-resident attributes
7001da177e4SLinus Torvalds respectively, aligning to an 8-byte
7011da177e4SLinus Torvalds boundary. */
7021da177e4SLinus Torvalds /* 12*/ ATTR_FLAGS flags; /* Flags describing the attribute. */
7031da177e4SLinus Torvalds /* 14*/ le16 instance; /* The instance of this attribute record. This
7041da177e4SLinus Torvalds number is unique within this mft record (see
7051da177e4SLinus Torvalds MFT_RECORD/next_attribute_instance notes in
706*6bbf2901SRandy Dunlap mft.h for more details). */
7071da177e4SLinus Torvalds /* 16*/ union {
7081da177e4SLinus Torvalds /* Resident attributes. */
7091da177e4SLinus Torvalds struct {
7101da177e4SLinus Torvalds /* 16 */ le32 value_length;/* Byte size of attribute value. */
7111da177e4SLinus Torvalds /* 20 */ le16 value_offset;/* Byte offset of the attribute
7121da177e4SLinus Torvalds value from the start of the
7131da177e4SLinus Torvalds attribute record. When creating,
7141da177e4SLinus Torvalds align to 8-byte boundary if we
7151da177e4SLinus Torvalds have a name present as this might
7161da177e4SLinus Torvalds not have a length of a multiple
7171da177e4SLinus Torvalds of 8-bytes. */
7181da177e4SLinus Torvalds /* 22 */ RESIDENT_ATTR_FLAGS flags; /* See above. */
7191da177e4SLinus Torvalds /* 23 */ s8 reserved; /* Reserved/alignment to 8-byte
7201da177e4SLinus Torvalds boundary. */
7211da177e4SLinus Torvalds } __attribute__ ((__packed__)) resident;
7221da177e4SLinus Torvalds /* Non-resident attributes. */
7231da177e4SLinus Torvalds struct {
7241da177e4SLinus Torvalds /* 16*/ leVCN lowest_vcn;/* Lowest valid virtual cluster number
7251da177e4SLinus Torvalds for this portion of the attribute value or
7261da177e4SLinus Torvalds 0 if this is the only extent (usually the
7271da177e4SLinus Torvalds case). - Only when an attribute list is used
7281da177e4SLinus Torvalds does lowest_vcn != 0 ever occur. */
7291da177e4SLinus Torvalds /* 24*/ leVCN highest_vcn;/* Highest valid vcn of this extent of
7301da177e4SLinus Torvalds the attribute value. - Usually there is only one
7311da177e4SLinus Torvalds portion, so this usually equals the attribute
7321da177e4SLinus Torvalds value size in clusters minus 1. Can be -1 for
7331da177e4SLinus Torvalds zero length files. Can be 0 for "single extent"
7341da177e4SLinus Torvalds attributes. */
7351da177e4SLinus Torvalds /* 32*/ le16 mapping_pairs_offset; /* Byte offset from the
7361da177e4SLinus Torvalds beginning of the structure to the mapping pairs
7371da177e4SLinus Torvalds array which contains the mappings between the
7381da177e4SLinus Torvalds vcns and the logical cluster numbers (lcns).
7391da177e4SLinus Torvalds When creating, place this at the end of this
7401da177e4SLinus Torvalds record header aligned to 8-byte boundary. */
7411da177e4SLinus Torvalds /* 34*/ u8 compression_unit; /* The compression unit expressed
7421da177e4SLinus Torvalds as the log to the base 2 of the number of
7431da177e4SLinus Torvalds clusters in a compression unit. 0 means not
7441da177e4SLinus Torvalds compressed. (This effectively limits the
7451da177e4SLinus Torvalds compression unit size to be a power of two
7469451f851SAnton Altaparmakov clusters.) WinNT4 only uses a value of 4.
747a0646a1fSAnton Altaparmakov Sparse files have this set to 0 on XPSP2. */
7481da177e4SLinus Torvalds /* 35*/ u8 reserved[5]; /* Align to 8-byte boundary. */
7491da177e4SLinus Torvalds /* The sizes below are only used when lowest_vcn is zero, as otherwise it would
7501da177e4SLinus Torvalds be difficult to keep them up-to-date.*/
7511da177e4SLinus Torvalds /* 40*/ sle64 allocated_size; /* Byte size of disk space
7521da177e4SLinus Torvalds allocated to hold the attribute value. Always
7531da177e4SLinus Torvalds is a multiple of the cluster size. When a file
7541da177e4SLinus Torvalds is compressed, this field is a multiple of the
7551da177e4SLinus Torvalds compression block size (2^compression_unit) and
7561da177e4SLinus Torvalds it represents the logically allocated space
7571da177e4SLinus Torvalds rather than the actual on disk usage. For this
7581da177e4SLinus Torvalds use the compressed_size (see below). */
7591da177e4SLinus Torvalds /* 48*/ sle64 data_size; /* Byte size of the attribute
7601da177e4SLinus Torvalds value. Can be larger than allocated_size if
7611da177e4SLinus Torvalds attribute value is compressed or sparse. */
7621da177e4SLinus Torvalds /* 56*/ sle64 initialized_size; /* Byte size of initialized
7631da177e4SLinus Torvalds portion of the attribute value. Usually equals
7641da177e4SLinus Torvalds data_size. */
7651da177e4SLinus Torvalds /* sizeof(uncompressed attr) = 64*/
7661da177e4SLinus Torvalds /* 64*/ sle64 compressed_size; /* Byte size of the attribute
7671da177e4SLinus Torvalds value after compression. Only present when
7689451f851SAnton Altaparmakov compressed or sparse. Always is a multiple of
7699451f851SAnton Altaparmakov the cluster size. Represents the actual amount
7709451f851SAnton Altaparmakov of disk space being used on the disk. */
7711da177e4SLinus Torvalds /* sizeof(compressed attr) = 72*/
7721da177e4SLinus Torvalds } __attribute__ ((__packed__)) non_resident;
7731da177e4SLinus Torvalds } __attribute__ ((__packed__)) data;
7741da177e4SLinus Torvalds } __attribute__ ((__packed__)) ATTR_RECORD;
7751da177e4SLinus Torvalds
7761da177e4SLinus Torvalds typedef ATTR_RECORD ATTR_REC;
7771da177e4SLinus Torvalds
7781da177e4SLinus Torvalds /*
7792c2c8c1cSAnton Altaparmakov * File attribute flags (32-bit) appearing in the file_attributes fields of the
7802c2c8c1cSAnton Altaparmakov * STANDARD_INFORMATION attribute of MFT_RECORDs and the FILENAME_ATTR
7812c2c8c1cSAnton Altaparmakov * attributes of MFT_RECORDs and directory index entries.
7822c2c8c1cSAnton Altaparmakov *
7832c2c8c1cSAnton Altaparmakov * All of the below flags appear in the directory index entries but only some
7842c2c8c1cSAnton Altaparmakov * appear in the STANDARD_INFORMATION attribute whilst only some others appear
7852c2c8c1cSAnton Altaparmakov * in the FILENAME_ATTR attribute of MFT_RECORDs. Unless otherwise stated the
7862c2c8c1cSAnton Altaparmakov * flags appear in all of the above.
7871da177e4SLinus Torvalds */
7881da177e4SLinus Torvalds enum {
78963cd8854SHarvey Harrison FILE_ATTR_READONLY = cpu_to_le32(0x00000001),
79063cd8854SHarvey Harrison FILE_ATTR_HIDDEN = cpu_to_le32(0x00000002),
79163cd8854SHarvey Harrison FILE_ATTR_SYSTEM = cpu_to_le32(0x00000004),
79263cd8854SHarvey Harrison /* Old DOS volid. Unused in NT. = cpu_to_le32(0x00000008), */
7931da177e4SLinus Torvalds
79463cd8854SHarvey Harrison FILE_ATTR_DIRECTORY = cpu_to_le32(0x00000010),
7951da177e4SLinus Torvalds /* Note, FILE_ATTR_DIRECTORY is not considered valid in NT. It is
7961da177e4SLinus Torvalds reserved for the DOS SUBDIRECTORY flag. */
79763cd8854SHarvey Harrison FILE_ATTR_ARCHIVE = cpu_to_le32(0x00000020),
79863cd8854SHarvey Harrison FILE_ATTR_DEVICE = cpu_to_le32(0x00000040),
79963cd8854SHarvey Harrison FILE_ATTR_NORMAL = cpu_to_le32(0x00000080),
8001da177e4SLinus Torvalds
80163cd8854SHarvey Harrison FILE_ATTR_TEMPORARY = cpu_to_le32(0x00000100),
80263cd8854SHarvey Harrison FILE_ATTR_SPARSE_FILE = cpu_to_le32(0x00000200),
80363cd8854SHarvey Harrison FILE_ATTR_REPARSE_POINT = cpu_to_le32(0x00000400),
80463cd8854SHarvey Harrison FILE_ATTR_COMPRESSED = cpu_to_le32(0x00000800),
8051da177e4SLinus Torvalds
80663cd8854SHarvey Harrison FILE_ATTR_OFFLINE = cpu_to_le32(0x00001000),
80763cd8854SHarvey Harrison FILE_ATTR_NOT_CONTENT_INDEXED = cpu_to_le32(0x00002000),
80863cd8854SHarvey Harrison FILE_ATTR_ENCRYPTED = cpu_to_le32(0x00004000),
8091da177e4SLinus Torvalds
81063cd8854SHarvey Harrison FILE_ATTR_VALID_FLAGS = cpu_to_le32(0x00007fb7),
8111da177e4SLinus Torvalds /* Note, FILE_ATTR_VALID_FLAGS masks out the old DOS VolId and the
8121da177e4SLinus Torvalds FILE_ATTR_DEVICE and preserves everything else. This mask is used
8131da177e4SLinus Torvalds to obtain all flags that are valid for reading. */
81463cd8854SHarvey Harrison FILE_ATTR_VALID_SET_FLAGS = cpu_to_le32(0x000031a7),
8151da177e4SLinus Torvalds /* Note, FILE_ATTR_VALID_SET_FLAGS masks out the old DOS VolId, the
8161da177e4SLinus Torvalds F_A_DEVICE, F_A_DIRECTORY, F_A_SPARSE_FILE, F_A_REPARSE_POINT,
8171da177e4SLinus Torvalds F_A_COMPRESSED, and F_A_ENCRYPTED and preserves the rest. This mask
818fd589a8fSAnand Gadiyar is used to obtain all flags that are valid for setting. */
8191da177e4SLinus Torvalds /*
8202c2c8c1cSAnton Altaparmakov * The flag FILE_ATTR_DUP_FILENAME_INDEX_PRESENT is present in all
8212c2c8c1cSAnton Altaparmakov * FILENAME_ATTR attributes but not in the STANDARD_INFORMATION
8222c2c8c1cSAnton Altaparmakov * attribute of an mft record.
8231da177e4SLinus Torvalds */
82463cd8854SHarvey Harrison FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT = cpu_to_le32(0x10000000),
8251da177e4SLinus Torvalds /* Note, this is a copy of the corresponding bit from the mft record,
8261da177e4SLinus Torvalds telling us whether this is a directory or not, i.e. whether it has
8271da177e4SLinus Torvalds an index root attribute or not. */
82863cd8854SHarvey Harrison FILE_ATTR_DUP_VIEW_INDEX_PRESENT = cpu_to_le32(0x20000000),
8291da177e4SLinus Torvalds /* Note, this is a copy of the corresponding bit from the mft record,
8301da177e4SLinus Torvalds telling us whether this file has a view index present (eg. object id
8311da177e4SLinus Torvalds index, quota index, one of the security indexes or the encrypting
8321da177e4SLinus Torvalds filesystem related indexes). */
8331da177e4SLinus Torvalds };
8341da177e4SLinus Torvalds
8351da177e4SLinus Torvalds typedef le32 FILE_ATTR_FLAGS;
8361da177e4SLinus Torvalds
8371da177e4SLinus Torvalds /*
8381da177e4SLinus Torvalds * NOTE on times in NTFS: All times are in MS standard time format, i.e. they
8391da177e4SLinus Torvalds * are the number of 100-nanosecond intervals since 1st January 1601, 00:00:00
8401da177e4SLinus Torvalds * universal coordinated time (UTC). (In Linux time starts 1st January 1970,
8411da177e4SLinus Torvalds * 00:00:00 UTC and is stored as the number of 1-second intervals since then.)
8421da177e4SLinus Torvalds */
8431da177e4SLinus Torvalds
8441da177e4SLinus Torvalds /*
8451da177e4SLinus Torvalds * Attribute: Standard information (0x10).
8461da177e4SLinus Torvalds *
8471da177e4SLinus Torvalds * NOTE: Always resident.
8481da177e4SLinus Torvalds * NOTE: Present in all base file records on a volume.
8491da177e4SLinus Torvalds * NOTE: There is conflicting information about the meaning of each of the time
8501da177e4SLinus Torvalds * fields but the meaning as defined below has been verified to be
8511da177e4SLinus Torvalds * correct by practical experimentation on Windows NT4 SP6a and is hence
8521da177e4SLinus Torvalds * assumed to be the one and only correct interpretation.
8531da177e4SLinus Torvalds */
8541da177e4SLinus Torvalds typedef struct {
8551da177e4SLinus Torvalds /*Ofs*/
8561da177e4SLinus Torvalds /* 0*/ sle64 creation_time; /* Time file was created. Updated when
8571da177e4SLinus Torvalds a filename is changed(?). */
8581da177e4SLinus Torvalds /* 8*/ sle64 last_data_change_time; /* Time the data attribute was last
8591da177e4SLinus Torvalds modified. */
8601da177e4SLinus Torvalds /* 16*/ sle64 last_mft_change_time; /* Time this mft record was last
8611da177e4SLinus Torvalds modified. */
8621da177e4SLinus Torvalds /* 24*/ sle64 last_access_time; /* Approximate time when the file was
8631da177e4SLinus Torvalds last accessed (obviously this is not
8641da177e4SLinus Torvalds updated on read-only volumes). In
8651da177e4SLinus Torvalds Windows this is only updated when
8661da177e4SLinus Torvalds accessed if some time delta has
8671da177e4SLinus Torvalds passed since the last update. Also,
8682c2c8c1cSAnton Altaparmakov last access time updates can be
8691da177e4SLinus Torvalds disabled altogether for speed. */
8701da177e4SLinus Torvalds /* 32*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */
8711da177e4SLinus Torvalds /* 36*/ union {
8721da177e4SLinus Torvalds /* NTFS 1.2 */
8731da177e4SLinus Torvalds struct {
8741da177e4SLinus Torvalds /* 36*/ u8 reserved12[12]; /* Reserved/alignment to 8-byte
8751da177e4SLinus Torvalds boundary. */
8761da177e4SLinus Torvalds } __attribute__ ((__packed__)) v1;
8771da177e4SLinus Torvalds /* sizeof() = 48 bytes */
8781da177e4SLinus Torvalds /* NTFS 3.x */
8791da177e4SLinus Torvalds struct {
8801da177e4SLinus Torvalds /*
8811da177e4SLinus Torvalds * If a volume has been upgraded from a previous NTFS version, then these
8821da177e4SLinus Torvalds * fields are present only if the file has been accessed since the upgrade.
8831da177e4SLinus Torvalds * Recognize the difference by comparing the length of the resident attribute
8841da177e4SLinus Torvalds * value. If it is 48, then the following fields are missing. If it is 72 then
8851da177e4SLinus Torvalds * the fields are present. Maybe just check like this:
8861da177e4SLinus Torvalds * if (resident.ValueLength < sizeof(STANDARD_INFORMATION)) {
8871da177e4SLinus Torvalds * Assume NTFS 1.2- format.
8881da177e4SLinus Torvalds * If (volume version is 3.x)
8891da177e4SLinus Torvalds * Upgrade attribute to NTFS 3.x format.
8901da177e4SLinus Torvalds * else
8911da177e4SLinus Torvalds * Use NTFS 1.2- format for access.
8921da177e4SLinus Torvalds * } else
8931da177e4SLinus Torvalds * Use NTFS 3.x format for access.
8941da177e4SLinus Torvalds * Only problem is that it might be legal to set the length of the value to
8951da177e4SLinus Torvalds * arbitrarily large values thus spoiling this check. - But chkdsk probably
8961da177e4SLinus Torvalds * views that as a corruption, assuming that it behaves like this for all
8971da177e4SLinus Torvalds * attributes.
8981da177e4SLinus Torvalds */
8991da177e4SLinus Torvalds /* 36*/ le32 maximum_versions; /* Maximum allowed versions for
9001da177e4SLinus Torvalds file. Zero if version numbering is disabled. */
9011da177e4SLinus Torvalds /* 40*/ le32 version_number; /* This file's version (if any).
9021da177e4SLinus Torvalds Set to zero if maximum_versions is zero. */
9031da177e4SLinus Torvalds /* 44*/ le32 class_id; /* Class id from bidirectional
9041da177e4SLinus Torvalds class id index (?). */
9051da177e4SLinus Torvalds /* 48*/ le32 owner_id; /* Owner_id of the user owning
9061da177e4SLinus Torvalds the file. Translate via $Q index in FILE_Extend
9071da177e4SLinus Torvalds /$Quota to the quota control entry for the user
9081da177e4SLinus Torvalds owning the file. Zero if quotas are disabled. */
9091da177e4SLinus Torvalds /* 52*/ le32 security_id; /* Security_id for the file.
9101da177e4SLinus Torvalds Translate via $SII index and $SDS data stream
9111da177e4SLinus Torvalds in FILE_Secure to the security descriptor. */
9121da177e4SLinus Torvalds /* 56*/ le64 quota_charged; /* Byte size of the charge to
9131da177e4SLinus Torvalds the quota for all streams of the file. Note: Is
9141da177e4SLinus Torvalds zero if quotas are disabled. */
9159f993fe4SAnton Altaparmakov /* 64*/ leUSN usn; /* Last update sequence number
9161da177e4SLinus Torvalds of the file. This is a direct index into the
9173f2faef0SAnton Altaparmakov transaction log file ($UsnJrnl). It is zero if
9183f2faef0SAnton Altaparmakov the usn journal is disabled or this file has
9193f2faef0SAnton Altaparmakov not been subject to logging yet. See usnjrnl.h
9203f2faef0SAnton Altaparmakov for details. */
9211da177e4SLinus Torvalds } __attribute__ ((__packed__)) v3;
9221da177e4SLinus Torvalds /* sizeof() = 72 bytes (NTFS 3.x) */
9231da177e4SLinus Torvalds } __attribute__ ((__packed__)) ver;
9241da177e4SLinus Torvalds } __attribute__ ((__packed__)) STANDARD_INFORMATION;
9251da177e4SLinus Torvalds
9261da177e4SLinus Torvalds /*
9271da177e4SLinus Torvalds * Attribute: Attribute list (0x20).
9281da177e4SLinus Torvalds *
9291da177e4SLinus Torvalds * - Can be either resident or non-resident.
9301da177e4SLinus Torvalds * - Value consists of a sequence of variable length, 8-byte aligned,
9311da177e4SLinus Torvalds * ATTR_LIST_ENTRY records.
9321da177e4SLinus Torvalds * - The list is not terminated by anything at all! The only way to know when
9331da177e4SLinus Torvalds * the end is reached is to keep track of the current offset and compare it to
9341da177e4SLinus Torvalds * the attribute value size.
9351da177e4SLinus Torvalds * - The attribute list attribute contains one entry for each attribute of
9361da177e4SLinus Torvalds * the file in which the list is located, except for the list attribute
9371da177e4SLinus Torvalds * itself. The list is sorted: first by attribute type, second by attribute
9381da177e4SLinus Torvalds * name (if present), third by instance number. The extents of one
9391da177e4SLinus Torvalds * non-resident attribute (if present) immediately follow after the initial
9401da177e4SLinus Torvalds * extent. They are ordered by lowest_vcn and have their instace set to zero.
9411da177e4SLinus Torvalds * It is not allowed to have two attributes with all sorting keys equal.
9421da177e4SLinus Torvalds * - Further restrictions:
9431da177e4SLinus Torvalds * - If not resident, the vcn to lcn mapping array has to fit inside the
9441da177e4SLinus Torvalds * base mft record.
9451da177e4SLinus Torvalds * - The attribute list attribute value has a maximum size of 256kb. This
9461da177e4SLinus Torvalds * is imposed by the Windows cache manager.
9471da177e4SLinus Torvalds * - Attribute lists are only used when the attributes of mft record do not
9481da177e4SLinus Torvalds * fit inside the mft record despite all attributes (that can be made
9491da177e4SLinus Torvalds * non-resident) having been made non-resident. This can happen e.g. when:
9501da177e4SLinus Torvalds * - File has a large number of hard links (lots of file name
9511da177e4SLinus Torvalds * attributes present).
9521da177e4SLinus Torvalds * - The mapping pairs array of some non-resident attribute becomes so
9531da177e4SLinus Torvalds * large due to fragmentation that it overflows the mft record.
9541da177e4SLinus Torvalds * - The security descriptor is very complex (not applicable to
9551da177e4SLinus Torvalds * NTFS 3.0 volumes).
9561da177e4SLinus Torvalds * - There are many named streams.
9571da177e4SLinus Torvalds */
9581da177e4SLinus Torvalds typedef struct {
9591da177e4SLinus Torvalds /*Ofs*/
9601da177e4SLinus Torvalds /* 0*/ ATTR_TYPE type; /* Type of referenced attribute. */
9611da177e4SLinus Torvalds /* 4*/ le16 length; /* Byte size of this entry (8-byte aligned). */
9621da177e4SLinus Torvalds /* 6*/ u8 name_length; /* Size in Unicode chars of the name of the
9631da177e4SLinus Torvalds attribute or 0 if unnamed. */
9641da177e4SLinus Torvalds /* 7*/ u8 name_offset; /* Byte offset to beginning of attribute name
9651da177e4SLinus Torvalds (always set this to where the name would
9661da177e4SLinus Torvalds start even if unnamed). */
9671da177e4SLinus Torvalds /* 8*/ leVCN lowest_vcn; /* Lowest virtual cluster number of this portion
9681da177e4SLinus Torvalds of the attribute value. This is usually 0. It
9691da177e4SLinus Torvalds is non-zero for the case where one attribute
9701da177e4SLinus Torvalds does not fit into one mft record and thus
9711da177e4SLinus Torvalds several mft records are allocated to hold
9721da177e4SLinus Torvalds this attribute. In the latter case, each mft
9731da177e4SLinus Torvalds record holds one extent of the attribute and
9741da177e4SLinus Torvalds there is one attribute list entry for each
9751da177e4SLinus Torvalds extent. NOTE: This is DEFINITELY a signed
9761da177e4SLinus Torvalds value! The windows driver uses cmp, followed
9771da177e4SLinus Torvalds by jg when comparing this, thus it treats it
9781da177e4SLinus Torvalds as signed. */
9791da177e4SLinus Torvalds /* 16*/ leMFT_REF mft_reference;/* The reference of the mft record holding
9801da177e4SLinus Torvalds the ATTR_RECORD for this portion of the
9811da177e4SLinus Torvalds attribute value. */
9821da177e4SLinus Torvalds /* 24*/ le16 instance; /* If lowest_vcn = 0, the instance of the
9831da177e4SLinus Torvalds attribute being referenced; otherwise 0. */
9841da177e4SLinus Torvalds /* 26*/ ntfschar name[0]; /* Use when creating only. When reading use
9851da177e4SLinus Torvalds name_offset to determine the location of the
9861da177e4SLinus Torvalds name. */
9871da177e4SLinus Torvalds /* sizeof() = 26 + (attribute_name_length * 2) bytes */
9881da177e4SLinus Torvalds } __attribute__ ((__packed__)) ATTR_LIST_ENTRY;
9891da177e4SLinus Torvalds
9901da177e4SLinus Torvalds /*
9911da177e4SLinus Torvalds * The maximum allowed length for a file name.
9921da177e4SLinus Torvalds */
9931da177e4SLinus Torvalds #define MAXIMUM_FILE_NAME_LENGTH 255
9941da177e4SLinus Torvalds
9951da177e4SLinus Torvalds /*
9961da177e4SLinus Torvalds * Possible namespaces for filenames in ntfs (8-bit).
9971da177e4SLinus Torvalds */
9981da177e4SLinus Torvalds enum {
9991da177e4SLinus Torvalds FILE_NAME_POSIX = 0x00,
10001da177e4SLinus Torvalds /* This is the largest namespace. It is case sensitive and allows all
10011da177e4SLinus Torvalds Unicode characters except for: '\0' and '/'. Beware that in
10027d0ffdb2SAnton Altaparmakov WinNT/2k/2003 by default files which eg have the same name except
10037d0ffdb2SAnton Altaparmakov for their case will not be distinguished by the standard utilities
10047d0ffdb2SAnton Altaparmakov and thus a "del filename" will delete both "filename" and "fileName"
10057d0ffdb2SAnton Altaparmakov without warning. However if for example Services For Unix (SFU) are
10067d0ffdb2SAnton Altaparmakov installed and the case sensitive option was enabled at installation
10077d0ffdb2SAnton Altaparmakov time, then you can create/access/delete such files.
10087d0ffdb2SAnton Altaparmakov Note that even SFU places restrictions on the filenames beyond the
10097d0ffdb2SAnton Altaparmakov '\0' and '/' and in particular the following set of characters is
10107d0ffdb2SAnton Altaparmakov not allowed: '"', '/', '<', '>', '\'. All other characters,
10117d0ffdb2SAnton Altaparmakov including the ones no allowed in WIN32 namespace are allowed.
10127d0ffdb2SAnton Altaparmakov Tested with SFU 3.5 (this is now free) running on Windows XP. */
10131da177e4SLinus Torvalds FILE_NAME_WIN32 = 0x01,
10141da177e4SLinus Torvalds /* The standard WinNT/2k NTFS long filenames. Case insensitive. All
10151da177e4SLinus Torvalds Unicode chars except: '\0', '"', '*', '/', ':', '<', '>', '?', '\',
10161da177e4SLinus Torvalds and '|'. Further, names cannot end with a '.' or a space. */
10171da177e4SLinus Torvalds FILE_NAME_DOS = 0x02,
10181da177e4SLinus Torvalds /* The standard DOS filenames (8.3 format). Uppercase only. All 8-bit
10191da177e4SLinus Torvalds characters greater space, except: '"', '*', '+', ',', '/', ':', ';',
10201da177e4SLinus Torvalds '<', '=', '>', '?', and '\'. */
10211da177e4SLinus Torvalds FILE_NAME_WIN32_AND_DOS = 0x03,
10221da177e4SLinus Torvalds /* 3 means that both the Win32 and the DOS filenames are identical and
10231da177e4SLinus Torvalds hence have been saved in this single filename record. */
10241da177e4SLinus Torvalds } __attribute__ ((__packed__));
10251da177e4SLinus Torvalds
10261da177e4SLinus Torvalds typedef u8 FILE_NAME_TYPE_FLAGS;
10271da177e4SLinus Torvalds
10281da177e4SLinus Torvalds /*
10291da177e4SLinus Torvalds * Attribute: Filename (0x30).
10301da177e4SLinus Torvalds *
10311da177e4SLinus Torvalds * NOTE: Always resident.
10321da177e4SLinus Torvalds * NOTE: All fields, except the parent_directory, are only updated when the
10331da177e4SLinus Torvalds * filename is changed. Until then, they just become out of sync with
10341da177e4SLinus Torvalds * reality and the more up to date values are present in the standard
10351da177e4SLinus Torvalds * information attribute.
10361da177e4SLinus Torvalds * NOTE: There is conflicting information about the meaning of each of the time
10371da177e4SLinus Torvalds * fields but the meaning as defined below has been verified to be
10381da177e4SLinus Torvalds * correct by practical experimentation on Windows NT4 SP6a and is hence
10391da177e4SLinus Torvalds * assumed to be the one and only correct interpretation.
10401da177e4SLinus Torvalds */
10411da177e4SLinus Torvalds typedef struct {
10421da177e4SLinus Torvalds /*hex ofs*/
10431da177e4SLinus Torvalds /* 0*/ leMFT_REF parent_directory; /* Directory this filename is
10441da177e4SLinus Torvalds referenced from. */
10451da177e4SLinus Torvalds /* 8*/ sle64 creation_time; /* Time file was created. */
10461da177e4SLinus Torvalds /* 10*/ sle64 last_data_change_time; /* Time the data attribute was last
10471da177e4SLinus Torvalds modified. */
10481da177e4SLinus Torvalds /* 18*/ sle64 last_mft_change_time; /* Time this mft record was last
10491da177e4SLinus Torvalds modified. */
10501da177e4SLinus Torvalds /* 20*/ sle64 last_access_time; /* Time this mft record was last
10511da177e4SLinus Torvalds accessed. */
10523672b638SAnton Altaparmakov /* 28*/ sle64 allocated_size; /* Byte size of on-disk allocated space
1053a0646a1fSAnton Altaparmakov for the unnamed data attribute. So
1054a0646a1fSAnton Altaparmakov for normal $DATA, this is the
10553672b638SAnton Altaparmakov allocated_size from the unnamed
10563672b638SAnton Altaparmakov $DATA attribute and for compressed
10573672b638SAnton Altaparmakov and/or sparse $DATA, this is the
10583672b638SAnton Altaparmakov compressed_size from the unnamed
1059a0646a1fSAnton Altaparmakov $DATA attribute. For a directory or
1060a0646a1fSAnton Altaparmakov other inode without an unnamed $DATA
1061a0646a1fSAnton Altaparmakov attribute, this is always 0. NOTE:
1062a0646a1fSAnton Altaparmakov This is a multiple of the cluster
1063a0646a1fSAnton Altaparmakov size. */
1064a0646a1fSAnton Altaparmakov /* 30*/ sle64 data_size; /* Byte size of actual data in unnamed
1065a0646a1fSAnton Altaparmakov data attribute. For a directory or
1066a0646a1fSAnton Altaparmakov other inode without an unnamed $DATA
1067a0646a1fSAnton Altaparmakov attribute, this is always 0. */
10681da177e4SLinus Torvalds /* 38*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */
10691da177e4SLinus Torvalds /* 3c*/ union {
10701da177e4SLinus Torvalds /* 3c*/ struct {
10711da177e4SLinus Torvalds /* 3c*/ le16 packed_ea_size; /* Size of the buffer needed to
10721da177e4SLinus Torvalds pack the extended attributes
10731da177e4SLinus Torvalds (EAs), if such are present.*/
10741da177e4SLinus Torvalds /* 3e*/ le16 reserved; /* Reserved for alignment. */
10751da177e4SLinus Torvalds } __attribute__ ((__packed__)) ea;
10761da177e4SLinus Torvalds /* 3c*/ struct {
10771da177e4SLinus Torvalds /* 3c*/ le32 reparse_point_tag; /* Type of reparse point,
10781da177e4SLinus Torvalds present only in reparse
10791da177e4SLinus Torvalds points and only if there are
10801da177e4SLinus Torvalds no EAs. */
10811da177e4SLinus Torvalds } __attribute__ ((__packed__)) rp;
10821da177e4SLinus Torvalds } __attribute__ ((__packed__)) type;
10831da177e4SLinus Torvalds /* 40*/ u8 file_name_length; /* Length of file name in
10841da177e4SLinus Torvalds (Unicode) characters. */
10851da177e4SLinus Torvalds /* 41*/ FILE_NAME_TYPE_FLAGS file_name_type; /* Namespace of the file name.*/
10861da177e4SLinus Torvalds /* 42*/ ntfschar file_name[0]; /* File name in Unicode. */
10871da177e4SLinus Torvalds } __attribute__ ((__packed__)) FILE_NAME_ATTR;
10881da177e4SLinus Torvalds
10891da177e4SLinus Torvalds /*
10901da177e4SLinus Torvalds * GUID structures store globally unique identifiers (GUID). A GUID is a
10911da177e4SLinus Torvalds * 128-bit value consisting of one group of eight hexadecimal digits, followed
10921da177e4SLinus Torvalds * by three groups of four hexadecimal digits each, followed by one group of
10931da177e4SLinus Torvalds * twelve hexadecimal digits. GUIDs are Microsoft's implementation of the
10941da177e4SLinus Torvalds * distributed computing environment (DCE) universally unique identifier (UUID).
10951da177e4SLinus Torvalds * Example of a GUID:
10961da177e4SLinus Torvalds * 1F010768-5A73-BC91-0010A52216A7
10971da177e4SLinus Torvalds */
10981da177e4SLinus Torvalds typedef struct {
10991da177e4SLinus Torvalds le32 data1; /* The first eight hexadecimal digits of the GUID. */
11001da177e4SLinus Torvalds le16 data2; /* The first group of four hexadecimal digits. */
11011da177e4SLinus Torvalds le16 data3; /* The second group of four hexadecimal digits. */
11021da177e4SLinus Torvalds u8 data4[8]; /* The first two bytes are the third group of four
11031da177e4SLinus Torvalds hexadecimal digits. The remaining six bytes are the
11041da177e4SLinus Torvalds final 12 hexadecimal digits. */
11051da177e4SLinus Torvalds } __attribute__ ((__packed__)) GUID;
11061da177e4SLinus Torvalds
11071da177e4SLinus Torvalds /*
11081da177e4SLinus Torvalds * FILE_Extend/$ObjId contains an index named $O. This index contains all
11091da177e4SLinus Torvalds * object_ids present on the volume as the index keys and the corresponding
11101da177e4SLinus Torvalds * mft_record numbers as the index entry data parts. The data part (defined
11111da177e4SLinus Torvalds * below) also contains three other object_ids:
11121da177e4SLinus Torvalds * birth_volume_id - object_id of FILE_Volume on which the file was first
11131da177e4SLinus Torvalds * created. Optional (i.e. can be zero).
11141da177e4SLinus Torvalds * birth_object_id - object_id of file when it was first created. Usually
11151da177e4SLinus Torvalds * equals the object_id. Optional (i.e. can be zero).
11161da177e4SLinus Torvalds * domain_id - Reserved (always zero).
11171da177e4SLinus Torvalds */
11181da177e4SLinus Torvalds typedef struct {
11191da177e4SLinus Torvalds leMFT_REF mft_reference;/* Mft record containing the object_id in
11201da177e4SLinus Torvalds the index entry key. */
11211da177e4SLinus Torvalds union {
11221da177e4SLinus Torvalds struct {
11231da177e4SLinus Torvalds GUID birth_volume_id;
11241da177e4SLinus Torvalds GUID birth_object_id;
11251da177e4SLinus Torvalds GUID domain_id;
11261da177e4SLinus Torvalds } __attribute__ ((__packed__)) origin;
11271da177e4SLinus Torvalds u8 extended_info[48];
11281da177e4SLinus Torvalds } __attribute__ ((__packed__)) opt;
11291da177e4SLinus Torvalds } __attribute__ ((__packed__)) OBJ_ID_INDEX_DATA;
11301da177e4SLinus Torvalds
11311da177e4SLinus Torvalds /*
11321da177e4SLinus Torvalds * Attribute: Object id (NTFS 3.0+) (0x40).
11331da177e4SLinus Torvalds *
11341da177e4SLinus Torvalds * NOTE: Always resident.
11351da177e4SLinus Torvalds */
11361da177e4SLinus Torvalds typedef struct {
11371da177e4SLinus Torvalds GUID object_id; /* Unique id assigned to the
11381da177e4SLinus Torvalds file.*/
11391da177e4SLinus Torvalds /* The following fields are optional. The attribute value size is 16
11401da177e4SLinus Torvalds bytes, i.e. sizeof(GUID), if these are not present at all. Note,
11411da177e4SLinus Torvalds the entries can be present but one or more (or all) can be zero
11421da177e4SLinus Torvalds meaning that that particular value(s) is(are) not defined. */
11431da177e4SLinus Torvalds union {
11441da177e4SLinus Torvalds struct {
11451da177e4SLinus Torvalds GUID birth_volume_id; /* Unique id of volume on which
11461da177e4SLinus Torvalds the file was first created.*/
11471da177e4SLinus Torvalds GUID birth_object_id; /* Unique id of file when it was
11481da177e4SLinus Torvalds first created. */
11491da177e4SLinus Torvalds GUID domain_id; /* Reserved, zero. */
11501da177e4SLinus Torvalds } __attribute__ ((__packed__)) origin;
11511da177e4SLinus Torvalds u8 extended_info[48];
11521da177e4SLinus Torvalds } __attribute__ ((__packed__)) opt;
11531da177e4SLinus Torvalds } __attribute__ ((__packed__)) OBJECT_ID_ATTR;
11541da177e4SLinus Torvalds
11551da177e4SLinus Torvalds /*
11561da177e4SLinus Torvalds * The pre-defined IDENTIFIER_AUTHORITIES used as SID_IDENTIFIER_AUTHORITY in
11571da177e4SLinus Torvalds * the SID structure (see below).
11581da177e4SLinus Torvalds */
11591da177e4SLinus Torvalds //typedef enum { /* SID string prefix. */
11601da177e4SLinus Torvalds // SECURITY_NULL_SID_AUTHORITY = {0, 0, 0, 0, 0, 0}, /* S-1-0 */
11611da177e4SLinus Torvalds // SECURITY_WORLD_SID_AUTHORITY = {0, 0, 0, 0, 0, 1}, /* S-1-1 */
11621da177e4SLinus Torvalds // SECURITY_LOCAL_SID_AUTHORITY = {0, 0, 0, 0, 0, 2}, /* S-1-2 */
11631da177e4SLinus Torvalds // SECURITY_CREATOR_SID_AUTHORITY = {0, 0, 0, 0, 0, 3}, /* S-1-3 */
11641da177e4SLinus Torvalds // SECURITY_NON_UNIQUE_AUTHORITY = {0, 0, 0, 0, 0, 4}, /* S-1-4 */
11651da177e4SLinus Torvalds // SECURITY_NT_SID_AUTHORITY = {0, 0, 0, 0, 0, 5}, /* S-1-5 */
11661da177e4SLinus Torvalds //} IDENTIFIER_AUTHORITIES;
11671da177e4SLinus Torvalds
11681da177e4SLinus Torvalds /*
11691da177e4SLinus Torvalds * These relative identifiers (RIDs) are used with the above identifier
11701da177e4SLinus Torvalds * authorities to make up universal well-known SIDs.
11711da177e4SLinus Torvalds *
11721da177e4SLinus Torvalds * Note: The relative identifier (RID) refers to the portion of a SID, which
11731da177e4SLinus Torvalds * identifies a user or group in relation to the authority that issued the SID.
11741da177e4SLinus Torvalds * For example, the universal well-known SID Creator Owner ID (S-1-3-0) is
11751da177e4SLinus Torvalds * made up of the identifier authority SECURITY_CREATOR_SID_AUTHORITY (3) and
11761da177e4SLinus Torvalds * the relative identifier SECURITY_CREATOR_OWNER_RID (0).
11771da177e4SLinus Torvalds */
11781da177e4SLinus Torvalds typedef enum { /* Identifier authority. */
11791da177e4SLinus Torvalds SECURITY_NULL_RID = 0, /* S-1-0 */
11801da177e4SLinus Torvalds SECURITY_WORLD_RID = 0, /* S-1-1 */
11811da177e4SLinus Torvalds SECURITY_LOCAL_RID = 0, /* S-1-2 */
11821da177e4SLinus Torvalds
11831da177e4SLinus Torvalds SECURITY_CREATOR_OWNER_RID = 0, /* S-1-3 */
11841da177e4SLinus Torvalds SECURITY_CREATOR_GROUP_RID = 1, /* S-1-3 */
11851da177e4SLinus Torvalds
11861da177e4SLinus Torvalds SECURITY_CREATOR_OWNER_SERVER_RID = 2, /* S-1-3 */
11871da177e4SLinus Torvalds SECURITY_CREATOR_GROUP_SERVER_RID = 3, /* S-1-3 */
11881da177e4SLinus Torvalds
11891da177e4SLinus Torvalds SECURITY_DIALUP_RID = 1,
11901da177e4SLinus Torvalds SECURITY_NETWORK_RID = 2,
11911da177e4SLinus Torvalds SECURITY_BATCH_RID = 3,
11921da177e4SLinus Torvalds SECURITY_INTERACTIVE_RID = 4,
11931da177e4SLinus Torvalds SECURITY_SERVICE_RID = 6,
11941da177e4SLinus Torvalds SECURITY_ANONYMOUS_LOGON_RID = 7,
11951da177e4SLinus Torvalds SECURITY_PROXY_RID = 8,
11961da177e4SLinus Torvalds SECURITY_ENTERPRISE_CONTROLLERS_RID=9,
11971da177e4SLinus Torvalds SECURITY_SERVER_LOGON_RID = 9,
11981da177e4SLinus Torvalds SECURITY_PRINCIPAL_SELF_RID = 0xa,
11991da177e4SLinus Torvalds SECURITY_AUTHENTICATED_USER_RID = 0xb,
12001da177e4SLinus Torvalds SECURITY_RESTRICTED_CODE_RID = 0xc,
12011da177e4SLinus Torvalds SECURITY_TERMINAL_SERVER_RID = 0xd,
12021da177e4SLinus Torvalds
12031da177e4SLinus Torvalds SECURITY_LOGON_IDS_RID = 5,
12041da177e4SLinus Torvalds SECURITY_LOGON_IDS_RID_COUNT = 3,
12051da177e4SLinus Torvalds
12061da177e4SLinus Torvalds SECURITY_LOCAL_SYSTEM_RID = 0x12,
12071da177e4SLinus Torvalds
12081da177e4SLinus Torvalds SECURITY_NT_NON_UNIQUE = 0x15,
12091da177e4SLinus Torvalds
12101da177e4SLinus Torvalds SECURITY_BUILTIN_DOMAIN_RID = 0x20,
12111da177e4SLinus Torvalds
12121da177e4SLinus Torvalds /*
12131da177e4SLinus Torvalds * Well-known domain relative sub-authority values (RIDs).
12141da177e4SLinus Torvalds */
12151da177e4SLinus Torvalds
12161da177e4SLinus Torvalds /* Users. */
12171da177e4SLinus Torvalds DOMAIN_USER_RID_ADMIN = 0x1f4,
12181da177e4SLinus Torvalds DOMAIN_USER_RID_GUEST = 0x1f5,
12191da177e4SLinus Torvalds DOMAIN_USER_RID_KRBTGT = 0x1f6,
12201da177e4SLinus Torvalds
12211da177e4SLinus Torvalds /* Groups. */
12221da177e4SLinus Torvalds DOMAIN_GROUP_RID_ADMINS = 0x200,
12231da177e4SLinus Torvalds DOMAIN_GROUP_RID_USERS = 0x201,
12241da177e4SLinus Torvalds DOMAIN_GROUP_RID_GUESTS = 0x202,
12251da177e4SLinus Torvalds DOMAIN_GROUP_RID_COMPUTERS = 0x203,
12261da177e4SLinus Torvalds DOMAIN_GROUP_RID_CONTROLLERS = 0x204,
12271da177e4SLinus Torvalds DOMAIN_GROUP_RID_CERT_ADMINS = 0x205,
12281da177e4SLinus Torvalds DOMAIN_GROUP_RID_SCHEMA_ADMINS = 0x206,
12291da177e4SLinus Torvalds DOMAIN_GROUP_RID_ENTERPRISE_ADMINS= 0x207,
12301da177e4SLinus Torvalds DOMAIN_GROUP_RID_POLICY_ADMINS = 0x208,
12311da177e4SLinus Torvalds
12321da177e4SLinus Torvalds /* Aliases. */
12331da177e4SLinus Torvalds DOMAIN_ALIAS_RID_ADMINS = 0x220,
12341da177e4SLinus Torvalds DOMAIN_ALIAS_RID_USERS = 0x221,
12351da177e4SLinus Torvalds DOMAIN_ALIAS_RID_GUESTS = 0x222,
12361da177e4SLinus Torvalds DOMAIN_ALIAS_RID_POWER_USERS = 0x223,
12371da177e4SLinus Torvalds
12381da177e4SLinus Torvalds DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x224,
12391da177e4SLinus Torvalds DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x225,
12401da177e4SLinus Torvalds DOMAIN_ALIAS_RID_PRINT_OPS = 0x226,
12411da177e4SLinus Torvalds DOMAIN_ALIAS_RID_BACKUP_OPS = 0x227,
12421da177e4SLinus Torvalds
12431da177e4SLinus Torvalds DOMAIN_ALIAS_RID_REPLICATOR = 0x228,
12441da177e4SLinus Torvalds DOMAIN_ALIAS_RID_RAS_SERVERS = 0x229,
12451da177e4SLinus Torvalds DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = 0x22a,
12461da177e4SLinus Torvalds } RELATIVE_IDENTIFIERS;
12471da177e4SLinus Torvalds
12481da177e4SLinus Torvalds /*
12491da177e4SLinus Torvalds * The universal well-known SIDs:
12501da177e4SLinus Torvalds *
12511da177e4SLinus Torvalds * NULL_SID S-1-0-0
12521da177e4SLinus Torvalds * WORLD_SID S-1-1-0
12531da177e4SLinus Torvalds * LOCAL_SID S-1-2-0
12541da177e4SLinus Torvalds * CREATOR_OWNER_SID S-1-3-0
12551da177e4SLinus Torvalds * CREATOR_GROUP_SID S-1-3-1
12561da177e4SLinus Torvalds * CREATOR_OWNER_SERVER_SID S-1-3-2
12571da177e4SLinus Torvalds * CREATOR_GROUP_SERVER_SID S-1-3-3
12581da177e4SLinus Torvalds *
12591da177e4SLinus Torvalds * (Non-unique IDs) S-1-4
12601da177e4SLinus Torvalds *
12611da177e4SLinus Torvalds * NT well-known SIDs:
12621da177e4SLinus Torvalds *
12631da177e4SLinus Torvalds * NT_AUTHORITY_SID S-1-5
12641da177e4SLinus Torvalds * DIALUP_SID S-1-5-1
12651da177e4SLinus Torvalds *
12661da177e4SLinus Torvalds * NETWORD_SID S-1-5-2
12671da177e4SLinus Torvalds * BATCH_SID S-1-5-3
12681da177e4SLinus Torvalds * INTERACTIVE_SID S-1-5-4
12691da177e4SLinus Torvalds * SERVICE_SID S-1-5-6
12701da177e4SLinus Torvalds * ANONYMOUS_LOGON_SID S-1-5-7 (aka null logon session)
12711da177e4SLinus Torvalds * PROXY_SID S-1-5-8
12721da177e4SLinus Torvalds * SERVER_LOGON_SID S-1-5-9 (aka domain controller account)
12731da177e4SLinus Torvalds * SELF_SID S-1-5-10 (self RID)
12741da177e4SLinus Torvalds * AUTHENTICATED_USER_SID S-1-5-11
12751da177e4SLinus Torvalds * RESTRICTED_CODE_SID S-1-5-12 (running restricted code)
12761da177e4SLinus Torvalds * TERMINAL_SERVER_SID S-1-5-13 (running on terminal server)
12771da177e4SLinus Torvalds *
12781da177e4SLinus Torvalds * (Logon IDs) S-1-5-5-X-Y
12791da177e4SLinus Torvalds *
12801da177e4SLinus Torvalds * (NT non-unique IDs) S-1-5-0x15-...
12811da177e4SLinus Torvalds *
12821da177e4SLinus Torvalds * (Built-in domain) S-1-5-0x20
12831da177e4SLinus Torvalds */
12841da177e4SLinus Torvalds
12851da177e4SLinus Torvalds /*
12861da177e4SLinus Torvalds * The SID_IDENTIFIER_AUTHORITY is a 48-bit value used in the SID structure.
12871da177e4SLinus Torvalds *
12881da177e4SLinus Torvalds * NOTE: This is stored as a big endian number, hence the high_part comes
12891da177e4SLinus Torvalds * before the low_part.
12901da177e4SLinus Torvalds */
12911da177e4SLinus Torvalds typedef union {
12921da177e4SLinus Torvalds struct {
12931da177e4SLinus Torvalds u16 high_part; /* High 16-bits. */
12941da177e4SLinus Torvalds u32 low_part; /* Low 32-bits. */
12951da177e4SLinus Torvalds } __attribute__ ((__packed__)) parts;
12961da177e4SLinus Torvalds u8 value[6]; /* Value as individual bytes. */
12971da177e4SLinus Torvalds } __attribute__ ((__packed__)) SID_IDENTIFIER_AUTHORITY;
12981da177e4SLinus Torvalds
12991da177e4SLinus Torvalds /*
13001da177e4SLinus Torvalds * The SID structure is a variable-length structure used to uniquely identify
13011da177e4SLinus Torvalds * users or groups. SID stands for security identifier.
13021da177e4SLinus Torvalds *
13031da177e4SLinus Torvalds * The standard textual representation of the SID is of the form:
13041da177e4SLinus Torvalds * S-R-I-S-S...
13051da177e4SLinus Torvalds * Where:
13061da177e4SLinus Torvalds * - The first "S" is the literal character 'S' identifying the following
13071da177e4SLinus Torvalds * digits as a SID.
13081da177e4SLinus Torvalds * - R is the revision level of the SID expressed as a sequence of digits
13091da177e4SLinus Torvalds * either in decimal or hexadecimal (if the later, prefixed by "0x").
13101da177e4SLinus Torvalds * - I is the 48-bit identifier_authority, expressed as digits as R above.
13111da177e4SLinus Torvalds * - S... is one or more sub_authority values, expressed as digits as above.
13121da177e4SLinus Torvalds *
13131da177e4SLinus Torvalds * Example SID; the domain-relative SID of the local Administrators group on
13141da177e4SLinus Torvalds * Windows NT/2k:
13151da177e4SLinus Torvalds * S-1-5-32-544
13161da177e4SLinus Torvalds * This translates to a SID with:
13171da177e4SLinus Torvalds * revision = 1,
13181da177e4SLinus Torvalds * sub_authority_count = 2,
13191da177e4SLinus Torvalds * identifier_authority = {0,0,0,0,0,5}, // SECURITY_NT_AUTHORITY
13201da177e4SLinus Torvalds * sub_authority[0] = 32, // SECURITY_BUILTIN_DOMAIN_RID
13211da177e4SLinus Torvalds * sub_authority[1] = 544 // DOMAIN_ALIAS_RID_ADMINS
13221da177e4SLinus Torvalds */
13231da177e4SLinus Torvalds typedef struct {
13241da177e4SLinus Torvalds u8 revision;
13251da177e4SLinus Torvalds u8 sub_authority_count;
13261da177e4SLinus Torvalds SID_IDENTIFIER_AUTHORITY identifier_authority;
13271da177e4SLinus Torvalds le32 sub_authority[1]; /* At least one sub_authority. */
13281da177e4SLinus Torvalds } __attribute__ ((__packed__)) SID;
13291da177e4SLinus Torvalds
13301da177e4SLinus Torvalds /*
13311da177e4SLinus Torvalds * Current constants for SIDs.
13321da177e4SLinus Torvalds */
13331da177e4SLinus Torvalds typedef enum {
13341da177e4SLinus Torvalds SID_REVISION = 1, /* Current revision level. */
13351da177e4SLinus Torvalds SID_MAX_SUB_AUTHORITIES = 15, /* Maximum number of those. */
13361da177e4SLinus Torvalds SID_RECOMMENDED_SUB_AUTHORITIES = 1, /* Will change to around 6 in
13371da177e4SLinus Torvalds a future revision. */
13381da177e4SLinus Torvalds } SID_CONSTANTS;
13391da177e4SLinus Torvalds
13401da177e4SLinus Torvalds /*
13411da177e4SLinus Torvalds * The predefined ACE types (8-bit, see below).
13421da177e4SLinus Torvalds */
13431da177e4SLinus Torvalds enum {
13441da177e4SLinus Torvalds ACCESS_MIN_MS_ACE_TYPE = 0,
13451da177e4SLinus Torvalds ACCESS_ALLOWED_ACE_TYPE = 0,
13461da177e4SLinus Torvalds ACCESS_DENIED_ACE_TYPE = 1,
13471da177e4SLinus Torvalds SYSTEM_AUDIT_ACE_TYPE = 2,
13481da177e4SLinus Torvalds SYSTEM_ALARM_ACE_TYPE = 3, /* Not implemented as of Win2k. */
13491da177e4SLinus Torvalds ACCESS_MAX_MS_V2_ACE_TYPE = 3,
13501da177e4SLinus Torvalds
13511da177e4SLinus Torvalds ACCESS_ALLOWED_COMPOUND_ACE_TYPE= 4,
13521da177e4SLinus Torvalds ACCESS_MAX_MS_V3_ACE_TYPE = 4,
13531da177e4SLinus Torvalds
13541da177e4SLinus Torvalds /* The following are Win2k only. */
13551da177e4SLinus Torvalds ACCESS_MIN_MS_OBJECT_ACE_TYPE = 5,
13561da177e4SLinus Torvalds ACCESS_ALLOWED_OBJECT_ACE_TYPE = 5,
13571da177e4SLinus Torvalds ACCESS_DENIED_OBJECT_ACE_TYPE = 6,
13581da177e4SLinus Torvalds SYSTEM_AUDIT_OBJECT_ACE_TYPE = 7,
13591da177e4SLinus Torvalds SYSTEM_ALARM_OBJECT_ACE_TYPE = 8,
13601da177e4SLinus Torvalds ACCESS_MAX_MS_OBJECT_ACE_TYPE = 8,
13611da177e4SLinus Torvalds
13621da177e4SLinus Torvalds ACCESS_MAX_MS_V4_ACE_TYPE = 8,
13631da177e4SLinus Torvalds
13641da177e4SLinus Torvalds /* This one is for WinNT/2k. */
13651da177e4SLinus Torvalds ACCESS_MAX_MS_ACE_TYPE = 8,
13661da177e4SLinus Torvalds } __attribute__ ((__packed__));
13671da177e4SLinus Torvalds
13681da177e4SLinus Torvalds typedef u8 ACE_TYPES;
13691da177e4SLinus Torvalds
13701da177e4SLinus Torvalds /*
13711da177e4SLinus Torvalds * The ACE flags (8-bit) for audit and inheritance (see below).
13721da177e4SLinus Torvalds *
13731da177e4SLinus Torvalds * SUCCESSFUL_ACCESS_ACE_FLAG is only used with system audit and alarm ACE
13741da177e4SLinus Torvalds * types to indicate that a message is generated (in Windows!) for successful
13751da177e4SLinus Torvalds * accesses.
13761da177e4SLinus Torvalds *
13771da177e4SLinus Torvalds * FAILED_ACCESS_ACE_FLAG is only used with system audit and alarm ACE types
13781da177e4SLinus Torvalds * to indicate that a message is generated (in Windows!) for failed accesses.
13791da177e4SLinus Torvalds */
13801da177e4SLinus Torvalds enum {
13811da177e4SLinus Torvalds /* The inheritance flags. */
13821da177e4SLinus Torvalds OBJECT_INHERIT_ACE = 0x01,
13831da177e4SLinus Torvalds CONTAINER_INHERIT_ACE = 0x02,
13841da177e4SLinus Torvalds NO_PROPAGATE_INHERIT_ACE = 0x04,
13851da177e4SLinus Torvalds INHERIT_ONLY_ACE = 0x08,
13861da177e4SLinus Torvalds INHERITED_ACE = 0x10, /* Win2k only. */
13871da177e4SLinus Torvalds VALID_INHERIT_FLAGS = 0x1f,
13881da177e4SLinus Torvalds
13891da177e4SLinus Torvalds /* The audit flags. */
13901da177e4SLinus Torvalds SUCCESSFUL_ACCESS_ACE_FLAG = 0x40,
13911da177e4SLinus Torvalds FAILED_ACCESS_ACE_FLAG = 0x80,
13921da177e4SLinus Torvalds } __attribute__ ((__packed__));
13931da177e4SLinus Torvalds
13941da177e4SLinus Torvalds typedef u8 ACE_FLAGS;
13951da177e4SLinus Torvalds
13961da177e4SLinus Torvalds /*
13971da177e4SLinus Torvalds * An ACE is an access-control entry in an access-control list (ACL).
13981da177e4SLinus Torvalds * An ACE defines access to an object for a specific user or group or defines
13991da177e4SLinus Torvalds * the types of access that generate system-administration messages or alarms
14001da177e4SLinus Torvalds * for a specific user or group. The user or group is identified by a security
14011da177e4SLinus Torvalds * identifier (SID).
14021da177e4SLinus Torvalds *
14031da177e4SLinus Torvalds * Each ACE starts with an ACE_HEADER structure (aligned on 4-byte boundary),
14041da177e4SLinus Torvalds * which specifies the type and size of the ACE. The format of the subsequent
14051da177e4SLinus Torvalds * data depends on the ACE type.
14061da177e4SLinus Torvalds */
14071da177e4SLinus Torvalds typedef struct {
14081da177e4SLinus Torvalds /*Ofs*/
14091da177e4SLinus Torvalds /* 0*/ ACE_TYPES type; /* Type of the ACE. */
14101da177e4SLinus Torvalds /* 1*/ ACE_FLAGS flags; /* Flags describing the ACE. */
14111da177e4SLinus Torvalds /* 2*/ le16 size; /* Size in bytes of the ACE. */
14121da177e4SLinus Torvalds } __attribute__ ((__packed__)) ACE_HEADER;
14131da177e4SLinus Torvalds
14141da177e4SLinus Torvalds /*
14151da177e4SLinus Torvalds * The access mask (32-bit). Defines the access rights.
14161da177e4SLinus Torvalds *
14171da177e4SLinus Torvalds * The specific rights (bits 0 to 15). These depend on the type of the object
14181da177e4SLinus Torvalds * being secured by the ACE.
14191da177e4SLinus Torvalds */
14201da177e4SLinus Torvalds enum {
14211da177e4SLinus Torvalds /* Specific rights for files and directories are as follows: */
14221da177e4SLinus Torvalds
14231da177e4SLinus Torvalds /* Right to read data from the file. (FILE) */
142463cd8854SHarvey Harrison FILE_READ_DATA = cpu_to_le32(0x00000001),
14251da177e4SLinus Torvalds /* Right to list contents of a directory. (DIRECTORY) */
142663cd8854SHarvey Harrison FILE_LIST_DIRECTORY = cpu_to_le32(0x00000001),
14271da177e4SLinus Torvalds
14281da177e4SLinus Torvalds /* Right to write data to the file. (FILE) */
142963cd8854SHarvey Harrison FILE_WRITE_DATA = cpu_to_le32(0x00000002),
14301da177e4SLinus Torvalds /* Right to create a file in the directory. (DIRECTORY) */
143163cd8854SHarvey Harrison FILE_ADD_FILE = cpu_to_le32(0x00000002),
14321da177e4SLinus Torvalds
14331da177e4SLinus Torvalds /* Right to append data to the file. (FILE) */
143463cd8854SHarvey Harrison FILE_APPEND_DATA = cpu_to_le32(0x00000004),
14351da177e4SLinus Torvalds /* Right to create a subdirectory. (DIRECTORY) */
143663cd8854SHarvey Harrison FILE_ADD_SUBDIRECTORY = cpu_to_le32(0x00000004),
14371da177e4SLinus Torvalds
14381da177e4SLinus Torvalds /* Right to read extended attributes. (FILE/DIRECTORY) */
143963cd8854SHarvey Harrison FILE_READ_EA = cpu_to_le32(0x00000008),
14401da177e4SLinus Torvalds
14411da177e4SLinus Torvalds /* Right to write extended attributes. (FILE/DIRECTORY) */
144263cd8854SHarvey Harrison FILE_WRITE_EA = cpu_to_le32(0x00000010),
14431da177e4SLinus Torvalds
14441da177e4SLinus Torvalds /* Right to execute a file. (FILE) */
144563cd8854SHarvey Harrison FILE_EXECUTE = cpu_to_le32(0x00000020),
14461da177e4SLinus Torvalds /* Right to traverse the directory. (DIRECTORY) */
144763cd8854SHarvey Harrison FILE_TRAVERSE = cpu_to_le32(0x00000020),
14481da177e4SLinus Torvalds
14491da177e4SLinus Torvalds /*
14501da177e4SLinus Torvalds * Right to delete a directory and all the files it contains (its
14511da177e4SLinus Torvalds * children), even if the files are read-only. (DIRECTORY)
14521da177e4SLinus Torvalds */
145363cd8854SHarvey Harrison FILE_DELETE_CHILD = cpu_to_le32(0x00000040),
14541da177e4SLinus Torvalds
14551da177e4SLinus Torvalds /* Right to read file attributes. (FILE/DIRECTORY) */
145663cd8854SHarvey Harrison FILE_READ_ATTRIBUTES = cpu_to_le32(0x00000080),
14571da177e4SLinus Torvalds
14581da177e4SLinus Torvalds /* Right to change file attributes. (FILE/DIRECTORY) */
145963cd8854SHarvey Harrison FILE_WRITE_ATTRIBUTES = cpu_to_le32(0x00000100),
14601da177e4SLinus Torvalds
14611da177e4SLinus Torvalds /*
14621da177e4SLinus Torvalds * The standard rights (bits 16 to 23). These are independent of the
14631da177e4SLinus Torvalds * type of object being secured.
14641da177e4SLinus Torvalds */
14651da177e4SLinus Torvalds
14661da177e4SLinus Torvalds /* Right to delete the object. */
146763cd8854SHarvey Harrison DELETE = cpu_to_le32(0x00010000),
14681da177e4SLinus Torvalds
14691da177e4SLinus Torvalds /*
14701da177e4SLinus Torvalds * Right to read the information in the object's security descriptor,
14711da177e4SLinus Torvalds * not including the information in the SACL, i.e. right to read the
14721da177e4SLinus Torvalds * security descriptor and owner.
14731da177e4SLinus Torvalds */
147463cd8854SHarvey Harrison READ_CONTROL = cpu_to_le32(0x00020000),
14751da177e4SLinus Torvalds
14761da177e4SLinus Torvalds /* Right to modify the DACL in the object's security descriptor. */
147763cd8854SHarvey Harrison WRITE_DAC = cpu_to_le32(0x00040000),
14781da177e4SLinus Torvalds
14791da177e4SLinus Torvalds /* Right to change the owner in the object's security descriptor. */
148063cd8854SHarvey Harrison WRITE_OWNER = cpu_to_le32(0x00080000),
14811da177e4SLinus Torvalds
14821da177e4SLinus Torvalds /*
14831da177e4SLinus Torvalds * Right to use the object for synchronization. Enables a process to
14841da177e4SLinus Torvalds * wait until the object is in the signalled state. Some object types
14851da177e4SLinus Torvalds * do not support this access right.
14861da177e4SLinus Torvalds */
148763cd8854SHarvey Harrison SYNCHRONIZE = cpu_to_le32(0x00100000),
14881da177e4SLinus Torvalds
14891da177e4SLinus Torvalds /*
14901da177e4SLinus Torvalds * The following STANDARD_RIGHTS_* are combinations of the above for
14911da177e4SLinus Torvalds * convenience and are defined by the Win32 API.
14921da177e4SLinus Torvalds */
14931da177e4SLinus Torvalds
14941da177e4SLinus Torvalds /* These are currently defined to READ_CONTROL. */
149563cd8854SHarvey Harrison STANDARD_RIGHTS_READ = cpu_to_le32(0x00020000),
149663cd8854SHarvey Harrison STANDARD_RIGHTS_WRITE = cpu_to_le32(0x00020000),
149763cd8854SHarvey Harrison STANDARD_RIGHTS_EXECUTE = cpu_to_le32(0x00020000),
14981da177e4SLinus Torvalds
14991da177e4SLinus Torvalds /* Combines DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER access. */
150063cd8854SHarvey Harrison STANDARD_RIGHTS_REQUIRED = cpu_to_le32(0x000f0000),
15011da177e4SLinus Torvalds
15021da177e4SLinus Torvalds /*
15031da177e4SLinus Torvalds * Combines DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, and
15041da177e4SLinus Torvalds * SYNCHRONIZE access.
15051da177e4SLinus Torvalds */
150663cd8854SHarvey Harrison STANDARD_RIGHTS_ALL = cpu_to_le32(0x001f0000),
15071da177e4SLinus Torvalds
15081da177e4SLinus Torvalds /*
15091da177e4SLinus Torvalds * The access system ACL and maximum allowed access types (bits 24 to
15101da177e4SLinus Torvalds * 25, bits 26 to 27 are reserved).
15111da177e4SLinus Torvalds */
151263cd8854SHarvey Harrison ACCESS_SYSTEM_SECURITY = cpu_to_le32(0x01000000),
151363cd8854SHarvey Harrison MAXIMUM_ALLOWED = cpu_to_le32(0x02000000),
15141da177e4SLinus Torvalds
15151da177e4SLinus Torvalds /*
15161da177e4SLinus Torvalds * The generic rights (bits 28 to 31). These map onto the standard and
15171da177e4SLinus Torvalds * specific rights.
15181da177e4SLinus Torvalds */
15191da177e4SLinus Torvalds
15201da177e4SLinus Torvalds /* Read, write, and execute access. */
152163cd8854SHarvey Harrison GENERIC_ALL = cpu_to_le32(0x10000000),
15221da177e4SLinus Torvalds
15231da177e4SLinus Torvalds /* Execute access. */
152463cd8854SHarvey Harrison GENERIC_EXECUTE = cpu_to_le32(0x20000000),
15251da177e4SLinus Torvalds
15261da177e4SLinus Torvalds /*
15271da177e4SLinus Torvalds * Write access. For files, this maps onto:
15281da177e4SLinus Torvalds * FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA |
15291da177e4SLinus Torvalds * FILE_WRITE_EA | STANDARD_RIGHTS_WRITE | SYNCHRONIZE
15301da177e4SLinus Torvalds * For directories, the mapping has the same numerical value. See
15311da177e4SLinus Torvalds * above for the descriptions of the rights granted.
15321da177e4SLinus Torvalds */
153363cd8854SHarvey Harrison GENERIC_WRITE = cpu_to_le32(0x40000000),
15341da177e4SLinus Torvalds
15351da177e4SLinus Torvalds /*
15361da177e4SLinus Torvalds * Read access. For files, this maps onto:
15371da177e4SLinus Torvalds * FILE_READ_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA |
15381da177e4SLinus Torvalds * STANDARD_RIGHTS_READ | SYNCHRONIZE
15391da177e4SLinus Torvalds * For directories, the mapping has the same numberical value. See
15401da177e4SLinus Torvalds * above for the descriptions of the rights granted.
15411da177e4SLinus Torvalds */
154263cd8854SHarvey Harrison GENERIC_READ = cpu_to_le32(0x80000000),
15431da177e4SLinus Torvalds };
15441da177e4SLinus Torvalds
15451da177e4SLinus Torvalds typedef le32 ACCESS_MASK;
15461da177e4SLinus Torvalds
15471da177e4SLinus Torvalds /*
15481da177e4SLinus Torvalds * The generic mapping array. Used to denote the mapping of each generic
15491da177e4SLinus Torvalds * access right to a specific access mask.
15501da177e4SLinus Torvalds *
15511da177e4SLinus Torvalds * FIXME: What exactly is this and what is it for? (AIA)
15521da177e4SLinus Torvalds */
15531da177e4SLinus Torvalds typedef struct {
15541da177e4SLinus Torvalds ACCESS_MASK generic_read;
15551da177e4SLinus Torvalds ACCESS_MASK generic_write;
15561da177e4SLinus Torvalds ACCESS_MASK generic_execute;
15571da177e4SLinus Torvalds ACCESS_MASK generic_all;
15581da177e4SLinus Torvalds } __attribute__ ((__packed__)) GENERIC_MAPPING;
15591da177e4SLinus Torvalds
15601da177e4SLinus Torvalds /*
15611da177e4SLinus Torvalds * The predefined ACE type structures are as defined below.
15621da177e4SLinus Torvalds */
15631da177e4SLinus Torvalds
15641da177e4SLinus Torvalds /*
15651da177e4SLinus Torvalds * ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, SYSTEM_AUDIT_ACE, SYSTEM_ALARM_ACE
15661da177e4SLinus Torvalds */
15671da177e4SLinus Torvalds typedef struct {
15681da177e4SLinus Torvalds /* 0 ACE_HEADER; -- Unfolded here as gcc doesn't like unnamed structs. */
15691da177e4SLinus Torvalds ACE_TYPES type; /* Type of the ACE. */
15701da177e4SLinus Torvalds ACE_FLAGS flags; /* Flags describing the ACE. */
15711da177e4SLinus Torvalds le16 size; /* Size in bytes of the ACE. */
15721da177e4SLinus Torvalds /* 4*/ ACCESS_MASK mask; /* Access mask associated with the ACE. */
15731da177e4SLinus Torvalds
15741da177e4SLinus Torvalds /* 8*/ SID sid; /* The SID associated with the ACE. */
15751da177e4SLinus Torvalds } __attribute__ ((__packed__)) ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE,
15761da177e4SLinus Torvalds SYSTEM_AUDIT_ACE, SYSTEM_ALARM_ACE;
15771da177e4SLinus Torvalds
15781da177e4SLinus Torvalds /*
15791da177e4SLinus Torvalds * The object ACE flags (32-bit).
15801da177e4SLinus Torvalds */
15811da177e4SLinus Torvalds enum {
158263cd8854SHarvey Harrison ACE_OBJECT_TYPE_PRESENT = cpu_to_le32(1),
158363cd8854SHarvey Harrison ACE_INHERITED_OBJECT_TYPE_PRESENT = cpu_to_le32(2),
15841da177e4SLinus Torvalds };
15851da177e4SLinus Torvalds
15861da177e4SLinus Torvalds typedef le32 OBJECT_ACE_FLAGS;
15871da177e4SLinus Torvalds
15881da177e4SLinus Torvalds typedef struct {
15891da177e4SLinus Torvalds /* 0 ACE_HEADER; -- Unfolded here as gcc doesn't like unnamed structs. */
15901da177e4SLinus Torvalds ACE_TYPES type; /* Type of the ACE. */
15911da177e4SLinus Torvalds ACE_FLAGS flags; /* Flags describing the ACE. */
15921da177e4SLinus Torvalds le16 size; /* Size in bytes of the ACE. */
15931da177e4SLinus Torvalds /* 4*/ ACCESS_MASK mask; /* Access mask associated with the ACE. */
15941da177e4SLinus Torvalds
15951da177e4SLinus Torvalds /* 8*/ OBJECT_ACE_FLAGS object_flags; /* Flags describing the object ACE. */
15961da177e4SLinus Torvalds /* 12*/ GUID object_type;
15971da177e4SLinus Torvalds /* 28*/ GUID inherited_object_type;
15981da177e4SLinus Torvalds
15991da177e4SLinus Torvalds /* 44*/ SID sid; /* The SID associated with the ACE. */
16001da177e4SLinus Torvalds } __attribute__ ((__packed__)) ACCESS_ALLOWED_OBJECT_ACE,
16011da177e4SLinus Torvalds ACCESS_DENIED_OBJECT_ACE,
16021da177e4SLinus Torvalds SYSTEM_AUDIT_OBJECT_ACE,
16031da177e4SLinus Torvalds SYSTEM_ALARM_OBJECT_ACE;
16041da177e4SLinus Torvalds
16051da177e4SLinus Torvalds /*
16061da177e4SLinus Torvalds * An ACL is an access-control list (ACL).
16071da177e4SLinus Torvalds * An ACL starts with an ACL header structure, which specifies the size of
16081da177e4SLinus Torvalds * the ACL and the number of ACEs it contains. The ACL header is followed by
16091da177e4SLinus Torvalds * zero or more access control entries (ACEs). The ACL as well as each ACE
16101da177e4SLinus Torvalds * are aligned on 4-byte boundaries.
16111da177e4SLinus Torvalds */
16121da177e4SLinus Torvalds typedef struct {
16131da177e4SLinus Torvalds u8 revision; /* Revision of this ACL. */
16141da177e4SLinus Torvalds u8 alignment1;
16151da177e4SLinus Torvalds le16 size; /* Allocated space in bytes for ACL. Includes this
16161da177e4SLinus Torvalds header, the ACEs and the remaining free space. */
16171da177e4SLinus Torvalds le16 ace_count; /* Number of ACEs in the ACL. */
16181da177e4SLinus Torvalds le16 alignment2;
16191da177e4SLinus Torvalds /* sizeof() = 8 bytes */
16201da177e4SLinus Torvalds } __attribute__ ((__packed__)) ACL;
16211da177e4SLinus Torvalds
16221da177e4SLinus Torvalds /*
16231da177e4SLinus Torvalds * Current constants for ACLs.
16241da177e4SLinus Torvalds */
16251da177e4SLinus Torvalds typedef enum {
16261da177e4SLinus Torvalds /* Current revision. */
16271da177e4SLinus Torvalds ACL_REVISION = 2,
16281da177e4SLinus Torvalds ACL_REVISION_DS = 4,
16291da177e4SLinus Torvalds
16301da177e4SLinus Torvalds /* History of revisions. */
16311da177e4SLinus Torvalds ACL_REVISION1 = 1,
16321da177e4SLinus Torvalds MIN_ACL_REVISION = 2,
16331da177e4SLinus Torvalds ACL_REVISION2 = 2,
16341da177e4SLinus Torvalds ACL_REVISION3 = 3,
16351da177e4SLinus Torvalds ACL_REVISION4 = 4,
16361da177e4SLinus Torvalds MAX_ACL_REVISION = 4,
16371da177e4SLinus Torvalds } ACL_CONSTANTS;
16381da177e4SLinus Torvalds
16391da177e4SLinus Torvalds /*
16401da177e4SLinus Torvalds * The security descriptor control flags (16-bit).
16411da177e4SLinus Torvalds *
16421da177e4SLinus Torvalds * SE_OWNER_DEFAULTED - This boolean flag, when set, indicates that the SID
16431da177e4SLinus Torvalds * pointed to by the Owner field was provided by a defaulting mechanism
16441da177e4SLinus Torvalds * rather than explicitly provided by the original provider of the
16451da177e4SLinus Torvalds * security descriptor. This may affect the treatment of the SID with
164625985edcSLucas De Marchi * respect to inheritance of an owner.
16471da177e4SLinus Torvalds *
16481da177e4SLinus Torvalds * SE_GROUP_DEFAULTED - This boolean flag, when set, indicates that the SID in
16491da177e4SLinus Torvalds * the Group field was provided by a defaulting mechanism rather than
16501da177e4SLinus Torvalds * explicitly provided by the original provider of the security
16511da177e4SLinus Torvalds * descriptor. This may affect the treatment of the SID with respect to
165225985edcSLucas De Marchi * inheritance of a primary group.
16531da177e4SLinus Torvalds *
16541da177e4SLinus Torvalds * SE_DACL_PRESENT - This boolean flag, when set, indicates that the security
16551da177e4SLinus Torvalds * descriptor contains a discretionary ACL. If this flag is set and the
16561da177e4SLinus Torvalds * Dacl field of the SECURITY_DESCRIPTOR is null, then a null ACL is
16571da177e4SLinus Torvalds * explicitly being specified.
16581da177e4SLinus Torvalds *
16591da177e4SLinus Torvalds * SE_DACL_DEFAULTED - This boolean flag, when set, indicates that the ACL
16601da177e4SLinus Torvalds * pointed to by the Dacl field was provided by a defaulting mechanism
16611da177e4SLinus Torvalds * rather than explicitly provided by the original provider of the
16621da177e4SLinus Torvalds * security descriptor. This may affect the treatment of the ACL with
166325985edcSLucas De Marchi * respect to inheritance of an ACL. This flag is ignored if the
16641da177e4SLinus Torvalds * DaclPresent flag is not set.
16651da177e4SLinus Torvalds *
16661da177e4SLinus Torvalds * SE_SACL_PRESENT - This boolean flag, when set, indicates that the security
16671da177e4SLinus Torvalds * descriptor contains a system ACL pointed to by the Sacl field. If this
16681da177e4SLinus Torvalds * flag is set and the Sacl field of the SECURITY_DESCRIPTOR is null, then
16691da177e4SLinus Torvalds * an empty (but present) ACL is being specified.
16701da177e4SLinus Torvalds *
16711da177e4SLinus Torvalds * SE_SACL_DEFAULTED - This boolean flag, when set, indicates that the ACL
16721da177e4SLinus Torvalds * pointed to by the Sacl field was provided by a defaulting mechanism
16731da177e4SLinus Torvalds * rather than explicitly provided by the original provider of the
16741da177e4SLinus Torvalds * security descriptor. This may affect the treatment of the ACL with
167525985edcSLucas De Marchi * respect to inheritance of an ACL. This flag is ignored if the
16761da177e4SLinus Torvalds * SaclPresent flag is not set.
16771da177e4SLinus Torvalds *
16781da177e4SLinus Torvalds * SE_SELF_RELATIVE - This boolean flag, when set, indicates that the security
16791da177e4SLinus Torvalds * descriptor is in self-relative form. In this form, all fields of the
16801da177e4SLinus Torvalds * security descriptor are contiguous in memory and all pointer fields are
16811da177e4SLinus Torvalds * expressed as offsets from the beginning of the security descriptor.
16821da177e4SLinus Torvalds */
16831da177e4SLinus Torvalds enum {
168463cd8854SHarvey Harrison SE_OWNER_DEFAULTED = cpu_to_le16(0x0001),
168563cd8854SHarvey Harrison SE_GROUP_DEFAULTED = cpu_to_le16(0x0002),
168663cd8854SHarvey Harrison SE_DACL_PRESENT = cpu_to_le16(0x0004),
168763cd8854SHarvey Harrison SE_DACL_DEFAULTED = cpu_to_le16(0x0008),
16881da177e4SLinus Torvalds
168963cd8854SHarvey Harrison SE_SACL_PRESENT = cpu_to_le16(0x0010),
169063cd8854SHarvey Harrison SE_SACL_DEFAULTED = cpu_to_le16(0x0020),
16911da177e4SLinus Torvalds
169263cd8854SHarvey Harrison SE_DACL_AUTO_INHERIT_REQ = cpu_to_le16(0x0100),
169363cd8854SHarvey Harrison SE_SACL_AUTO_INHERIT_REQ = cpu_to_le16(0x0200),
169463cd8854SHarvey Harrison SE_DACL_AUTO_INHERITED = cpu_to_le16(0x0400),
169563cd8854SHarvey Harrison SE_SACL_AUTO_INHERITED = cpu_to_le16(0x0800),
16961da177e4SLinus Torvalds
169763cd8854SHarvey Harrison SE_DACL_PROTECTED = cpu_to_le16(0x1000),
169863cd8854SHarvey Harrison SE_SACL_PROTECTED = cpu_to_le16(0x2000),
169963cd8854SHarvey Harrison SE_RM_CONTROL_VALID = cpu_to_le16(0x4000),
170063cd8854SHarvey Harrison SE_SELF_RELATIVE = cpu_to_le16(0x8000)
17011da177e4SLinus Torvalds } __attribute__ ((__packed__));
17021da177e4SLinus Torvalds
17031da177e4SLinus Torvalds typedef le16 SECURITY_DESCRIPTOR_CONTROL;
17041da177e4SLinus Torvalds
17051da177e4SLinus Torvalds /*
17061da177e4SLinus Torvalds * Self-relative security descriptor. Contains the owner and group SIDs as well
17071da177e4SLinus Torvalds * as the sacl and dacl ACLs inside the security descriptor itself.
17081da177e4SLinus Torvalds */
17091da177e4SLinus Torvalds typedef struct {
17101da177e4SLinus Torvalds u8 revision; /* Revision level of the security descriptor. */
17111da177e4SLinus Torvalds u8 alignment;
17121da177e4SLinus Torvalds SECURITY_DESCRIPTOR_CONTROL control; /* Flags qualifying the type of
17131da177e4SLinus Torvalds the descriptor as well as the following fields. */
17141da177e4SLinus Torvalds le32 owner; /* Byte offset to a SID representing an object's
17151da177e4SLinus Torvalds owner. If this is NULL, no owner SID is present in
17161da177e4SLinus Torvalds the descriptor. */
17171da177e4SLinus Torvalds le32 group; /* Byte offset to a SID representing an object's
17181da177e4SLinus Torvalds primary group. If this is NULL, no primary group
17191da177e4SLinus Torvalds SID is present in the descriptor. */
17201da177e4SLinus Torvalds le32 sacl; /* Byte offset to a system ACL. Only valid, if
17211da177e4SLinus Torvalds SE_SACL_PRESENT is set in the control field. If
17221da177e4SLinus Torvalds SE_SACL_PRESENT is set but sacl is NULL, a NULL ACL
17231da177e4SLinus Torvalds is specified. */
17241da177e4SLinus Torvalds le32 dacl; /* Byte offset to a discretionary ACL. Only valid, if
17251da177e4SLinus Torvalds SE_DACL_PRESENT is set in the control field. If
17261da177e4SLinus Torvalds SE_DACL_PRESENT is set but dacl is NULL, a NULL ACL
17271da177e4SLinus Torvalds (unconditionally granting access) is specified. */
17281da177e4SLinus Torvalds /* sizeof() = 0x14 bytes */
17291da177e4SLinus Torvalds } __attribute__ ((__packed__)) SECURITY_DESCRIPTOR_RELATIVE;
17301da177e4SLinus Torvalds
17311da177e4SLinus Torvalds /*
17321da177e4SLinus Torvalds * Absolute security descriptor. Does not contain the owner and group SIDs, nor
17331da177e4SLinus Torvalds * the sacl and dacl ACLs inside the security descriptor. Instead, it contains
17341da177e4SLinus Torvalds * pointers to these structures in memory. Obviously, absolute security
17351da177e4SLinus Torvalds * descriptors are only useful for in memory representations of security
17361da177e4SLinus Torvalds * descriptors. On disk, a self-relative security descriptor is used.
17371da177e4SLinus Torvalds */
17381da177e4SLinus Torvalds typedef struct {
17391da177e4SLinus Torvalds u8 revision; /* Revision level of the security descriptor. */
17401da177e4SLinus Torvalds u8 alignment;
17411da177e4SLinus Torvalds SECURITY_DESCRIPTOR_CONTROL control; /* Flags qualifying the type of
17421da177e4SLinus Torvalds the descriptor as well as the following fields. */
17431da177e4SLinus Torvalds SID *owner; /* Points to a SID representing an object's owner. If
17441da177e4SLinus Torvalds this is NULL, no owner SID is present in the
17451da177e4SLinus Torvalds descriptor. */
17461da177e4SLinus Torvalds SID *group; /* Points to a SID representing an object's primary
17471da177e4SLinus Torvalds group. If this is NULL, no primary group SID is
17481da177e4SLinus Torvalds present in the descriptor. */
17491da177e4SLinus Torvalds ACL *sacl; /* Points to a system ACL. Only valid, if
17501da177e4SLinus Torvalds SE_SACL_PRESENT is set in the control field. If
17511da177e4SLinus Torvalds SE_SACL_PRESENT is set but sacl is NULL, a NULL ACL
17521da177e4SLinus Torvalds is specified. */
17531da177e4SLinus Torvalds ACL *dacl; /* Points to a discretionary ACL. Only valid, if
17541da177e4SLinus Torvalds SE_DACL_PRESENT is set in the control field. If
17551da177e4SLinus Torvalds SE_DACL_PRESENT is set but dacl is NULL, a NULL ACL
17561da177e4SLinus Torvalds (unconditionally granting access) is specified. */
17571da177e4SLinus Torvalds } __attribute__ ((__packed__)) SECURITY_DESCRIPTOR;
17581da177e4SLinus Torvalds
17591da177e4SLinus Torvalds /*
17601da177e4SLinus Torvalds * Current constants for security descriptors.
17611da177e4SLinus Torvalds */
17621da177e4SLinus Torvalds typedef enum {
17631da177e4SLinus Torvalds /* Current revision. */
17641da177e4SLinus Torvalds SECURITY_DESCRIPTOR_REVISION = 1,
17651da177e4SLinus Torvalds SECURITY_DESCRIPTOR_REVISION1 = 1,
17661da177e4SLinus Torvalds
17671da177e4SLinus Torvalds /* The sizes of both the absolute and relative security descriptors is
17681da177e4SLinus Torvalds the same as pointers, at least on ia32 architecture are 32-bit. */
17691da177e4SLinus Torvalds SECURITY_DESCRIPTOR_MIN_LENGTH = sizeof(SECURITY_DESCRIPTOR),
17701da177e4SLinus Torvalds } SECURITY_DESCRIPTOR_CONSTANTS;
17711da177e4SLinus Torvalds
17721da177e4SLinus Torvalds /*
17731da177e4SLinus Torvalds * Attribute: Security descriptor (0x50). A standard self-relative security
17741da177e4SLinus Torvalds * descriptor.
17751da177e4SLinus Torvalds *
17761da177e4SLinus Torvalds * NOTE: Can be resident or non-resident.
17771da177e4SLinus Torvalds * NOTE: Not used in NTFS 3.0+, as security descriptors are stored centrally
17781da177e4SLinus Torvalds * in FILE_Secure and the correct descriptor is found using the security_id
17791da177e4SLinus Torvalds * from the standard information attribute.
17801da177e4SLinus Torvalds */
17811da177e4SLinus Torvalds typedef SECURITY_DESCRIPTOR_RELATIVE SECURITY_DESCRIPTOR_ATTR;
17821da177e4SLinus Torvalds
17831da177e4SLinus Torvalds /*
17841da177e4SLinus Torvalds * On NTFS 3.0+, all security descriptors are stored in FILE_Secure. Only one
17851da177e4SLinus Torvalds * referenced instance of each unique security descriptor is stored.
17861da177e4SLinus Torvalds *
17871da177e4SLinus Torvalds * FILE_Secure contains no unnamed data attribute, i.e. it has zero length. It
17881da177e4SLinus Torvalds * does, however, contain two indexes ($SDH and $SII) as well as a named data
17891da177e4SLinus Torvalds * stream ($SDS).
17901da177e4SLinus Torvalds *
17911da177e4SLinus Torvalds * Every unique security descriptor is assigned a unique security identifier
17921da177e4SLinus Torvalds * (security_id, not to be confused with a SID). The security_id is unique for
17931da177e4SLinus Torvalds * the NTFS volume and is used as an index into the $SII index, which maps
17941da177e4SLinus Torvalds * security_ids to the security descriptor's storage location within the $SDS
17951da177e4SLinus Torvalds * data attribute. The $SII index is sorted by ascending security_id.
17961da177e4SLinus Torvalds *
17971da177e4SLinus Torvalds * A simple hash is computed from each security descriptor. This hash is used
17981da177e4SLinus Torvalds * as an index into the $SDH index, which maps security descriptor hashes to
17991da177e4SLinus Torvalds * the security descriptor's storage location within the $SDS data attribute.
18001da177e4SLinus Torvalds * The $SDH index is sorted by security descriptor hash and is stored in a B+
18011da177e4SLinus Torvalds * tree. When searching $SDH (with the intent of determining whether or not a
18021da177e4SLinus Torvalds * new security descriptor is already present in the $SDS data stream), if a
18031da177e4SLinus Torvalds * matching hash is found, but the security descriptors do not match, the
18041da177e4SLinus Torvalds * search in the $SDH index is continued, searching for a next matching hash.
18051da177e4SLinus Torvalds *
18061da177e4SLinus Torvalds * When a precise match is found, the security_id coresponding to the security
18071da177e4SLinus Torvalds * descriptor in the $SDS attribute is read from the found $SDH index entry and
18081da177e4SLinus Torvalds * is stored in the $STANDARD_INFORMATION attribute of the file/directory to
18091da177e4SLinus Torvalds * which the security descriptor is being applied. The $STANDARD_INFORMATION
18101da177e4SLinus Torvalds * attribute is present in all base mft records (i.e. in all files and
18111da177e4SLinus Torvalds * directories).
18121da177e4SLinus Torvalds *
18131da177e4SLinus Torvalds * If a match is not found, the security descriptor is assigned a new unique
18141da177e4SLinus Torvalds * security_id and is added to the $SDS data attribute. Then, entries
18151da177e4SLinus Torvalds * referencing the this security descriptor in the $SDS data attribute are
18161da177e4SLinus Torvalds * added to the $SDH and $SII indexes.
18171da177e4SLinus Torvalds *
18181da177e4SLinus Torvalds * Note: Entries are never deleted from FILE_Secure, even if nothing
18191da177e4SLinus Torvalds * references an entry any more.
18201da177e4SLinus Torvalds */
18211da177e4SLinus Torvalds
18221da177e4SLinus Torvalds /*
18231da177e4SLinus Torvalds * This header precedes each security descriptor in the $SDS data stream.
18241da177e4SLinus Torvalds * This is also the index entry data part of both the $SII and $SDH indexes.
18251da177e4SLinus Torvalds */
18261da177e4SLinus Torvalds typedef struct {
18271da177e4SLinus Torvalds le32 hash; /* Hash of the security descriptor. */
18281da177e4SLinus Torvalds le32 security_id; /* The security_id assigned to the descriptor. */
18291da177e4SLinus Torvalds le64 offset; /* Byte offset of this entry in the $SDS stream. */
18301da177e4SLinus Torvalds le32 length; /* Size in bytes of this entry in $SDS stream. */
18311da177e4SLinus Torvalds } __attribute__ ((__packed__)) SECURITY_DESCRIPTOR_HEADER;
18321da177e4SLinus Torvalds
18331da177e4SLinus Torvalds /*
18341da177e4SLinus Torvalds * The $SDS data stream contains the security descriptors, aligned on 16-byte
18351da177e4SLinus Torvalds * boundaries, sorted by security_id in a B+ tree. Security descriptors cannot
18361da177e4SLinus Torvalds * cross 256kib boundaries (this restriction is imposed by the Windows cache
18371da177e4SLinus Torvalds * manager). Each security descriptor is contained in a SDS_ENTRY structure.
18381da177e4SLinus Torvalds * Also, each security descriptor is stored twice in the $SDS stream with a
18391da177e4SLinus Torvalds * fixed offset of 0x40000 bytes (256kib, the Windows cache manager's max size)
18401da177e4SLinus Torvalds * between them; i.e. if a SDS_ENTRY specifies an offset of 0x51d0, then the
1841*6bbf2901SRandy Dunlap * first copy of the security descriptor will be at offset 0x51d0 in the
18421da177e4SLinus Torvalds * $SDS data stream and the second copy will be at offset 0x451d0.
18431da177e4SLinus Torvalds */
18441da177e4SLinus Torvalds typedef struct {
18451da177e4SLinus Torvalds /*Ofs*/
18461da177e4SLinus Torvalds /* 0 SECURITY_DESCRIPTOR_HEADER; -- Unfolded here as gcc doesn't like
18471da177e4SLinus Torvalds unnamed structs. */
18481da177e4SLinus Torvalds le32 hash; /* Hash of the security descriptor. */
18491da177e4SLinus Torvalds le32 security_id; /* The security_id assigned to the descriptor. */
18501da177e4SLinus Torvalds le64 offset; /* Byte offset of this entry in the $SDS stream. */
18511da177e4SLinus Torvalds le32 length; /* Size in bytes of this entry in $SDS stream. */
18521da177e4SLinus Torvalds /* 20*/ SECURITY_DESCRIPTOR_RELATIVE sid; /* The self-relative security
18531da177e4SLinus Torvalds descriptor. */
18541da177e4SLinus Torvalds } __attribute__ ((__packed__)) SDS_ENTRY;
18551da177e4SLinus Torvalds
18561da177e4SLinus Torvalds /*
18571da177e4SLinus Torvalds * The index entry key used in the $SII index. The collation type is
18581da177e4SLinus Torvalds * COLLATION_NTOFS_ULONG.
18591da177e4SLinus Torvalds */
18601da177e4SLinus Torvalds typedef struct {
18611da177e4SLinus Torvalds le32 security_id; /* The security_id assigned to the descriptor. */
18621da177e4SLinus Torvalds } __attribute__ ((__packed__)) SII_INDEX_KEY;
18631da177e4SLinus Torvalds
18641da177e4SLinus Torvalds /*
18651da177e4SLinus Torvalds * The index entry key used in the $SDH index. The keys are sorted first by
18661da177e4SLinus Torvalds * hash and then by security_id. The collation rule is
18671da177e4SLinus Torvalds * COLLATION_NTOFS_SECURITY_HASH.
18681da177e4SLinus Torvalds */
18691da177e4SLinus Torvalds typedef struct {
18701da177e4SLinus Torvalds le32 hash; /* Hash of the security descriptor. */
18711da177e4SLinus Torvalds le32 security_id; /* The security_id assigned to the descriptor. */
18721da177e4SLinus Torvalds } __attribute__ ((__packed__)) SDH_INDEX_KEY;
18731da177e4SLinus Torvalds
18741da177e4SLinus Torvalds /*
18751da177e4SLinus Torvalds * Attribute: Volume name (0x60).
18761da177e4SLinus Torvalds *
18771da177e4SLinus Torvalds * NOTE: Always resident.
18781da177e4SLinus Torvalds * NOTE: Present only in FILE_Volume.
18791da177e4SLinus Torvalds */
18801da177e4SLinus Torvalds typedef struct {
18811da177e4SLinus Torvalds ntfschar name[0]; /* The name of the volume in Unicode. */
18821da177e4SLinus Torvalds } __attribute__ ((__packed__)) VOLUME_NAME;
18831da177e4SLinus Torvalds
18841da177e4SLinus Torvalds /*
18851da177e4SLinus Torvalds * Possible flags for the volume (16-bit).
18861da177e4SLinus Torvalds */
18871da177e4SLinus Torvalds enum {
188863cd8854SHarvey Harrison VOLUME_IS_DIRTY = cpu_to_le16(0x0001),
188963cd8854SHarvey Harrison VOLUME_RESIZE_LOG_FILE = cpu_to_le16(0x0002),
189063cd8854SHarvey Harrison VOLUME_UPGRADE_ON_MOUNT = cpu_to_le16(0x0004),
189163cd8854SHarvey Harrison VOLUME_MOUNTED_ON_NT4 = cpu_to_le16(0x0008),
18921da177e4SLinus Torvalds
189363cd8854SHarvey Harrison VOLUME_DELETE_USN_UNDERWAY = cpu_to_le16(0x0010),
189463cd8854SHarvey Harrison VOLUME_REPAIR_OBJECT_ID = cpu_to_le16(0x0020),
18951da177e4SLinus Torvalds
189663cd8854SHarvey Harrison VOLUME_CHKDSK_UNDERWAY = cpu_to_le16(0x4000),
189763cd8854SHarvey Harrison VOLUME_MODIFIED_BY_CHKDSK = cpu_to_le16(0x8000),
18981da177e4SLinus Torvalds
189963cd8854SHarvey Harrison VOLUME_FLAGS_MASK = cpu_to_le16(0xc03f),
19001da177e4SLinus Torvalds
19011da177e4SLinus Torvalds /* To make our life easier when checking if we must mount read-only. */
190263cd8854SHarvey Harrison VOLUME_MUST_MOUNT_RO_MASK = cpu_to_le16(0xc027),
19031da177e4SLinus Torvalds } __attribute__ ((__packed__));
19041da177e4SLinus Torvalds
19051da177e4SLinus Torvalds typedef le16 VOLUME_FLAGS;
19061da177e4SLinus Torvalds
19071da177e4SLinus Torvalds /*
19081da177e4SLinus Torvalds * Attribute: Volume information (0x70).
19091da177e4SLinus Torvalds *
19101da177e4SLinus Torvalds * NOTE: Always resident.
19111da177e4SLinus Torvalds * NOTE: Present only in FILE_Volume.
19121da177e4SLinus Torvalds * NOTE: Windows 2000 uses NTFS 3.0 while Windows NT4 service pack 6a uses
19131da177e4SLinus Torvalds * NTFS 1.2. I haven't personally seen other values yet.
19141da177e4SLinus Torvalds */
19151da177e4SLinus Torvalds typedef struct {
19161da177e4SLinus Torvalds le64 reserved; /* Not used (yet?). */
19171da177e4SLinus Torvalds u8 major_ver; /* Major version of the ntfs format. */
19181da177e4SLinus Torvalds u8 minor_ver; /* Minor version of the ntfs format. */
19191da177e4SLinus Torvalds VOLUME_FLAGS flags; /* Bit array of VOLUME_* flags. */
19201da177e4SLinus Torvalds } __attribute__ ((__packed__)) VOLUME_INFORMATION;
19211da177e4SLinus Torvalds
19221da177e4SLinus Torvalds /*
19231da177e4SLinus Torvalds * Attribute: Data attribute (0x80).
19241da177e4SLinus Torvalds *
19251da177e4SLinus Torvalds * NOTE: Can be resident or non-resident.
19261da177e4SLinus Torvalds *
19271da177e4SLinus Torvalds * Data contents of a file (i.e. the unnamed stream) or of a named stream.
19281da177e4SLinus Torvalds */
19291da177e4SLinus Torvalds typedef struct {
19301da177e4SLinus Torvalds u8 data[0]; /* The file's data contents. */
19311da177e4SLinus Torvalds } __attribute__ ((__packed__)) DATA_ATTR;
19321da177e4SLinus Torvalds
19331da177e4SLinus Torvalds /*
19341da177e4SLinus Torvalds * Index header flags (8-bit).
19351da177e4SLinus Torvalds */
19361da177e4SLinus Torvalds enum {
19371da177e4SLinus Torvalds /*
19381da177e4SLinus Torvalds * When index header is in an index root attribute:
19391da177e4SLinus Torvalds */
19401da177e4SLinus Torvalds SMALL_INDEX = 0, /* The index is small enough to fit inside the index
19411da177e4SLinus Torvalds root attribute and there is no index allocation
19421da177e4SLinus Torvalds attribute present. */
19431da177e4SLinus Torvalds LARGE_INDEX = 1, /* The index is too large to fit in the index root
19441da177e4SLinus Torvalds attribute and/or an index allocation attribute is
19451da177e4SLinus Torvalds present. */
19461da177e4SLinus Torvalds /*
19471da177e4SLinus Torvalds * When index header is in an index block, i.e. is part of index
19481da177e4SLinus Torvalds * allocation attribute:
19491da177e4SLinus Torvalds */
19501da177e4SLinus Torvalds LEAF_NODE = 0, /* This is a leaf node, i.e. there are no more nodes
19511da177e4SLinus Torvalds branching off it. */
19521da177e4SLinus Torvalds INDEX_NODE = 1, /* This node indexes other nodes, i.e. it is not a leaf
19531da177e4SLinus Torvalds node. */
19541da177e4SLinus Torvalds NODE_MASK = 1, /* Mask for accessing the *_NODE bits. */
19551da177e4SLinus Torvalds } __attribute__ ((__packed__));
19561da177e4SLinus Torvalds
19571da177e4SLinus Torvalds typedef u8 INDEX_HEADER_FLAGS;
19581da177e4SLinus Torvalds
19591da177e4SLinus Torvalds /*
19601da177e4SLinus Torvalds * This is the header for indexes, describing the INDEX_ENTRY records, which
19611da177e4SLinus Torvalds * follow the INDEX_HEADER. Together the index header and the index entries
19621da177e4SLinus Torvalds * make up a complete index.
19631da177e4SLinus Torvalds *
19641da177e4SLinus Torvalds * IMPORTANT NOTE: The offset, length and size structure members are counted
19651da177e4SLinus Torvalds * relative to the start of the index header structure and not relative to the
19661da177e4SLinus Torvalds * start of the index root or index allocation structures themselves.
19671da177e4SLinus Torvalds */
19681da177e4SLinus Torvalds typedef struct {
19691da177e4SLinus Torvalds le32 entries_offset; /* Byte offset to first INDEX_ENTRY
19701da177e4SLinus Torvalds aligned to 8-byte boundary. */
19711da177e4SLinus Torvalds le32 index_length; /* Data size of the index in bytes,
19721da177e4SLinus Torvalds i.e. bytes used from allocated
19731da177e4SLinus Torvalds size, aligned to 8-byte boundary. */
19741da177e4SLinus Torvalds le32 allocated_size; /* Byte size of this index (block),
19751da177e4SLinus Torvalds multiple of 8 bytes. */
19761da177e4SLinus Torvalds /* NOTE: For the index root attribute, the above two numbers are always
19771da177e4SLinus Torvalds equal, as the attribute is resident and it is resized as needed. In
19781da177e4SLinus Torvalds the case of the index allocation attribute the attribute is not
19791da177e4SLinus Torvalds resident and hence the allocated_size is a fixed value and must
19801da177e4SLinus Torvalds equal the index_block_size specified by the INDEX_ROOT attribute
19811da177e4SLinus Torvalds corresponding to the INDEX_ALLOCATION attribute this INDEX_BLOCK
19821da177e4SLinus Torvalds belongs to. */
19831da177e4SLinus Torvalds INDEX_HEADER_FLAGS flags; /* Bit field of INDEX_HEADER_FLAGS. */
19841da177e4SLinus Torvalds u8 reserved[3]; /* Reserved/align to 8-byte boundary. */
19851da177e4SLinus Torvalds } __attribute__ ((__packed__)) INDEX_HEADER;
19861da177e4SLinus Torvalds
19871da177e4SLinus Torvalds /*
19881da177e4SLinus Torvalds * Attribute: Index root (0x90).
19891da177e4SLinus Torvalds *
19901da177e4SLinus Torvalds * NOTE: Always resident.
19911da177e4SLinus Torvalds *
19921da177e4SLinus Torvalds * This is followed by a sequence of index entries (INDEX_ENTRY structures)
19931da177e4SLinus Torvalds * as described by the index header.
19941da177e4SLinus Torvalds *
19951da177e4SLinus Torvalds * When a directory is small enough to fit inside the index root then this
19961da177e4SLinus Torvalds * is the only attribute describing the directory. When the directory is too
1997a80581d0SJustin P. Mattock * large to fit in the index root, on the other hand, two additional attributes
19981da177e4SLinus Torvalds * are present: an index allocation attribute, containing sub-nodes of the B+
19991da177e4SLinus Torvalds * directory tree (see below), and a bitmap attribute, describing which virtual
20001da177e4SLinus Torvalds * cluster numbers (vcns) in the index allocation attribute are in use by an
20011da177e4SLinus Torvalds * index block.
20021da177e4SLinus Torvalds *
20031da177e4SLinus Torvalds * NOTE: The root directory (FILE_root) contains an entry for itself. Other
2004a80581d0SJustin P. Mattock * directories do not contain entries for themselves, though.
20051da177e4SLinus Torvalds */
20061da177e4SLinus Torvalds typedef struct {
20071da177e4SLinus Torvalds ATTR_TYPE type; /* Type of the indexed attribute. Is
20081da177e4SLinus Torvalds $FILE_NAME for directories, zero
20091da177e4SLinus Torvalds for view indexes. No other values
20101da177e4SLinus Torvalds allowed. */
20111da177e4SLinus Torvalds COLLATION_RULE collation_rule; /* Collation rule used to sort the
20121da177e4SLinus Torvalds index entries. If type is $FILE_NAME,
20131da177e4SLinus Torvalds this must be COLLATION_FILE_NAME. */
20141da177e4SLinus Torvalds le32 index_block_size; /* Size of each index block in bytes (in
20151da177e4SLinus Torvalds the index allocation attribute). */
20161da177e4SLinus Torvalds u8 clusters_per_index_block; /* Cluster size of each index block (in
20171da177e4SLinus Torvalds the index allocation attribute), when
20181da177e4SLinus Torvalds an index block is >= than a cluster,
20191da177e4SLinus Torvalds otherwise this will be the log of
20201da177e4SLinus Torvalds the size (like how the encoding of
20211da177e4SLinus Torvalds the mft record size and the index
20221da177e4SLinus Torvalds record size found in the boot sector
20231da177e4SLinus Torvalds work). Has to be a power of 2. */
20241da177e4SLinus Torvalds u8 reserved[3]; /* Reserved/align to 8-byte boundary. */
20251da177e4SLinus Torvalds INDEX_HEADER index; /* Index header describing the
20261da177e4SLinus Torvalds following index entries. */
20271da177e4SLinus Torvalds } __attribute__ ((__packed__)) INDEX_ROOT;
20281da177e4SLinus Torvalds
20291da177e4SLinus Torvalds /*
20301da177e4SLinus Torvalds * Attribute: Index allocation (0xa0).
20311da177e4SLinus Torvalds *
20321da177e4SLinus Torvalds * NOTE: Always non-resident (doesn't make sense to be resident anyway!).
20331da177e4SLinus Torvalds *
20341da177e4SLinus Torvalds * This is an array of index blocks. Each index block starts with an
20351da177e4SLinus Torvalds * INDEX_BLOCK structure containing an index header, followed by a sequence of
20361da177e4SLinus Torvalds * index entries (INDEX_ENTRY structures), as described by the INDEX_HEADER.
20371da177e4SLinus Torvalds */
20381da177e4SLinus Torvalds typedef struct {
20391da177e4SLinus Torvalds /* 0 NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
20401da177e4SLinus Torvalds NTFS_RECORD_TYPE magic; /* Magic is "INDX". */
20411da177e4SLinus Torvalds le16 usa_ofs; /* See NTFS_RECORD definition. */
20421da177e4SLinus Torvalds le16 usa_count; /* See NTFS_RECORD definition. */
20431da177e4SLinus Torvalds
20441da177e4SLinus Torvalds /* 8*/ sle64 lsn; /* $LogFile sequence number of the last
20451da177e4SLinus Torvalds modification of this index block. */
20461da177e4SLinus Torvalds /* 16*/ leVCN index_block_vcn; /* Virtual cluster number of the index block.
20471da177e4SLinus Torvalds If the cluster_size on the volume is <= the
20481da177e4SLinus Torvalds index_block_size of the directory,
20491da177e4SLinus Torvalds index_block_vcn counts in units of clusters,
20501da177e4SLinus Torvalds and in units of sectors otherwise. */
20511da177e4SLinus Torvalds /* 24*/ INDEX_HEADER index; /* Describes the following index entries. */
20521da177e4SLinus Torvalds /* sizeof()= 40 (0x28) bytes */
20531da177e4SLinus Torvalds /*
20541da177e4SLinus Torvalds * When creating the index block, we place the update sequence array at this
20551da177e4SLinus Torvalds * offset, i.e. before we start with the index entries. This also makes sense,
20561da177e4SLinus Torvalds * otherwise we could run into problems with the update sequence array
20571da177e4SLinus Torvalds * containing in itself the last two bytes of a sector which would mean that
20581da177e4SLinus Torvalds * multi sector transfer protection wouldn't work. As you can't protect data
20591da177e4SLinus Torvalds * by overwriting it since you then can't get it back...
20601da177e4SLinus Torvalds * When reading use the data from the ntfs record header.
20611da177e4SLinus Torvalds */
20621da177e4SLinus Torvalds } __attribute__ ((__packed__)) INDEX_BLOCK;
20631da177e4SLinus Torvalds
20641da177e4SLinus Torvalds typedef INDEX_BLOCK INDEX_ALLOCATION;
20651da177e4SLinus Torvalds
20661da177e4SLinus Torvalds /*
20671da177e4SLinus Torvalds * The system file FILE_Extend/$Reparse contains an index named $R listing
20681da177e4SLinus Torvalds * all reparse points on the volume. The index entry keys are as defined
20691da177e4SLinus Torvalds * below. Note, that there is no index data associated with the index entries.
20701da177e4SLinus Torvalds *
20711da177e4SLinus Torvalds * The index entries are sorted by the index key file_id. The collation rule is
20721da177e4SLinus Torvalds * COLLATION_NTOFS_ULONGS. FIXME: Verify whether the reparse_tag is not the
20731da177e4SLinus Torvalds * primary key / is not a key at all. (AIA)
20741da177e4SLinus Torvalds */
20751da177e4SLinus Torvalds typedef struct {
20761da177e4SLinus Torvalds le32 reparse_tag; /* Reparse point type (inc. flags). */
20771da177e4SLinus Torvalds leMFT_REF file_id; /* Mft record of the file containing the
20781da177e4SLinus Torvalds reparse point attribute. */
20791da177e4SLinus Torvalds } __attribute__ ((__packed__)) REPARSE_INDEX_KEY;
20801da177e4SLinus Torvalds
20811da177e4SLinus Torvalds /*
20821da177e4SLinus Torvalds * Quota flags (32-bit).
20831da177e4SLinus Torvalds *
20841da177e4SLinus Torvalds * The user quota flags. Names explain meaning.
20851da177e4SLinus Torvalds */
20861da177e4SLinus Torvalds enum {
208763cd8854SHarvey Harrison QUOTA_FLAG_DEFAULT_LIMITS = cpu_to_le32(0x00000001),
208863cd8854SHarvey Harrison QUOTA_FLAG_LIMIT_REACHED = cpu_to_le32(0x00000002),
208963cd8854SHarvey Harrison QUOTA_FLAG_ID_DELETED = cpu_to_le32(0x00000004),
20901da177e4SLinus Torvalds
209163cd8854SHarvey Harrison QUOTA_FLAG_USER_MASK = cpu_to_le32(0x00000007),
20921da177e4SLinus Torvalds /* This is a bit mask for the user quota flags. */
20931da177e4SLinus Torvalds
20941da177e4SLinus Torvalds /*
20951da177e4SLinus Torvalds * These flags are only present in the quota defaults index entry, i.e.
20961da177e4SLinus Torvalds * in the entry where owner_id = QUOTA_DEFAULTS_ID.
20971da177e4SLinus Torvalds */
209863cd8854SHarvey Harrison QUOTA_FLAG_TRACKING_ENABLED = cpu_to_le32(0x00000010),
209963cd8854SHarvey Harrison QUOTA_FLAG_ENFORCEMENT_ENABLED = cpu_to_le32(0x00000020),
210063cd8854SHarvey Harrison QUOTA_FLAG_TRACKING_REQUESTED = cpu_to_le32(0x00000040),
210163cd8854SHarvey Harrison QUOTA_FLAG_LOG_THRESHOLD = cpu_to_le32(0x00000080),
21021da177e4SLinus Torvalds
210363cd8854SHarvey Harrison QUOTA_FLAG_LOG_LIMIT = cpu_to_le32(0x00000100),
210463cd8854SHarvey Harrison QUOTA_FLAG_OUT_OF_DATE = cpu_to_le32(0x00000200),
210563cd8854SHarvey Harrison QUOTA_FLAG_CORRUPT = cpu_to_le32(0x00000400),
210663cd8854SHarvey Harrison QUOTA_FLAG_PENDING_DELETES = cpu_to_le32(0x00000800),
21071da177e4SLinus Torvalds };
21081da177e4SLinus Torvalds
21091da177e4SLinus Torvalds typedef le32 QUOTA_FLAGS;
21101da177e4SLinus Torvalds
21111da177e4SLinus Torvalds /*
21121da177e4SLinus Torvalds * The system file FILE_Extend/$Quota contains two indexes $O and $Q. Quotas
21131da177e4SLinus Torvalds * are on a per volume and per user basis.
21141da177e4SLinus Torvalds *
21151da177e4SLinus Torvalds * The $Q index contains one entry for each existing user_id on the volume. The
21161da177e4SLinus Torvalds * index key is the user_id of the user/group owning this quota control entry,
21171da177e4SLinus Torvalds * i.e. the key is the owner_id. The user_id of the owner of a file, i.e. the
21181da177e4SLinus Torvalds * owner_id, is found in the standard information attribute. The collation rule
21191da177e4SLinus Torvalds * for $Q is COLLATION_NTOFS_ULONG.
21201da177e4SLinus Torvalds *
21211da177e4SLinus Torvalds * The $O index contains one entry for each user/group who has been assigned
21221da177e4SLinus Torvalds * a quota on that volume. The index key holds the SID of the user_id the
21231da177e4SLinus Torvalds * entry belongs to, i.e. the owner_id. The collation rule for $O is
21241da177e4SLinus Torvalds * COLLATION_NTOFS_SID.
21251da177e4SLinus Torvalds *
21261da177e4SLinus Torvalds * The $O index entry data is the user_id of the user corresponding to the SID.
21271da177e4SLinus Torvalds * This user_id is used as an index into $Q to find the quota control entry
21281da177e4SLinus Torvalds * associated with the SID.
21291da177e4SLinus Torvalds *
21301da177e4SLinus Torvalds * The $Q index entry data is the quota control entry and is defined below.
21311da177e4SLinus Torvalds */
21321da177e4SLinus Torvalds typedef struct {
21331da177e4SLinus Torvalds le32 version; /* Currently equals 2. */
21341da177e4SLinus Torvalds QUOTA_FLAGS flags; /* Flags describing this quota entry. */
21351da177e4SLinus Torvalds le64 bytes_used; /* How many bytes of the quota are in use. */
21361da177e4SLinus Torvalds sle64 change_time; /* Last time this quota entry was changed. */
21371da177e4SLinus Torvalds sle64 threshold; /* Soft quota (-1 if not limited). */
21381da177e4SLinus Torvalds sle64 limit; /* Hard quota (-1 if not limited). */
21391da177e4SLinus Torvalds sle64 exceeded_time; /* How long the soft quota has been exceeded. */
21401da177e4SLinus Torvalds SID sid; /* The SID of the user/object associated with
21411da177e4SLinus Torvalds this quota entry. Equals zero for the quota
21421da177e4SLinus Torvalds defaults entry (and in fact on a WinXP
21431da177e4SLinus Torvalds volume, it is not present at all). */
21441da177e4SLinus Torvalds } __attribute__ ((__packed__)) QUOTA_CONTROL_ENTRY;
21451da177e4SLinus Torvalds
21461da177e4SLinus Torvalds /*
21471da177e4SLinus Torvalds * Predefined owner_id values (32-bit).
21481da177e4SLinus Torvalds */
21491da177e4SLinus Torvalds enum {
215063cd8854SHarvey Harrison QUOTA_INVALID_ID = cpu_to_le32(0x00000000),
215163cd8854SHarvey Harrison QUOTA_DEFAULTS_ID = cpu_to_le32(0x00000001),
215263cd8854SHarvey Harrison QUOTA_FIRST_USER_ID = cpu_to_le32(0x00000100),
21531da177e4SLinus Torvalds };
21541da177e4SLinus Torvalds
21551da177e4SLinus Torvalds /*
21561da177e4SLinus Torvalds * Current constants for quota control entries.
21571da177e4SLinus Torvalds */
21581da177e4SLinus Torvalds typedef enum {
21591da177e4SLinus Torvalds /* Current version. */
21601da177e4SLinus Torvalds QUOTA_VERSION = 2,
21611da177e4SLinus Torvalds } QUOTA_CONTROL_ENTRY_CONSTANTS;
21621da177e4SLinus Torvalds
21631da177e4SLinus Torvalds /*
21641da177e4SLinus Torvalds * Index entry flags (16-bit).
21651da177e4SLinus Torvalds */
21661da177e4SLinus Torvalds enum {
216763cd8854SHarvey Harrison INDEX_ENTRY_NODE = cpu_to_le16(1), /* This entry contains a
21681da177e4SLinus Torvalds sub-node, i.e. a reference to an index block in form of
21691da177e4SLinus Torvalds a virtual cluster number (see below). */
217063cd8854SHarvey Harrison INDEX_ENTRY_END = cpu_to_le16(2), /* This signifies the last
21711da177e4SLinus Torvalds entry in an index block. The index entry does not
21721da177e4SLinus Torvalds represent a file but it can point to a sub-node. */
21731da177e4SLinus Torvalds
217463cd8854SHarvey Harrison INDEX_ENTRY_SPACE_FILLER = cpu_to_le16(0xffff), /* gcc: Force
21751da177e4SLinus Torvalds enum bit width to 16-bit. */
21761da177e4SLinus Torvalds } __attribute__ ((__packed__));
21771da177e4SLinus Torvalds
21781da177e4SLinus Torvalds typedef le16 INDEX_ENTRY_FLAGS;
21791da177e4SLinus Torvalds
21801da177e4SLinus Torvalds /*
21811da177e4SLinus Torvalds * This the index entry header (see below).
21821da177e4SLinus Torvalds */
21831da177e4SLinus Torvalds typedef struct {
21841da177e4SLinus Torvalds /* 0*/ union {
21851da177e4SLinus Torvalds struct { /* Only valid when INDEX_ENTRY_END is not set. */
21861da177e4SLinus Torvalds leMFT_REF indexed_file; /* The mft reference of the file
21871da177e4SLinus Torvalds described by this index
21881da177e4SLinus Torvalds entry. Used for directory
21891da177e4SLinus Torvalds indexes. */
21901da177e4SLinus Torvalds } __attribute__ ((__packed__)) dir;
21911da177e4SLinus Torvalds struct { /* Used for views/indexes to find the entry's data. */
21921da177e4SLinus Torvalds le16 data_offset; /* Data byte offset from this
21931da177e4SLinus Torvalds INDEX_ENTRY. Follows the
21941da177e4SLinus Torvalds index key. */
21951da177e4SLinus Torvalds le16 data_length; /* Data length in bytes. */
21961da177e4SLinus Torvalds le32 reservedV; /* Reserved (zero). */
21971da177e4SLinus Torvalds } __attribute__ ((__packed__)) vi;
21981da177e4SLinus Torvalds } __attribute__ ((__packed__)) data;
21991da177e4SLinus Torvalds /* 8*/ le16 length; /* Byte size of this index entry, multiple of
22001da177e4SLinus Torvalds 8-bytes. */
22011da177e4SLinus Torvalds /* 10*/ le16 key_length; /* Byte size of the key value, which is in the
22021da177e4SLinus Torvalds index entry. It follows field reserved. Not
22031da177e4SLinus Torvalds multiple of 8-bytes. */
22041da177e4SLinus Torvalds /* 12*/ INDEX_ENTRY_FLAGS flags; /* Bit field of INDEX_ENTRY_* flags. */
22051da177e4SLinus Torvalds /* 14*/ le16 reserved; /* Reserved/align to 8-byte boundary. */
22061da177e4SLinus Torvalds /* sizeof() = 16 bytes */
22071da177e4SLinus Torvalds } __attribute__ ((__packed__)) INDEX_ENTRY_HEADER;
22081da177e4SLinus Torvalds
22091da177e4SLinus Torvalds /*
22101da177e4SLinus Torvalds * This is an index entry. A sequence of such entries follows each INDEX_HEADER
22111da177e4SLinus Torvalds * structure. Together they make up a complete index. The index follows either
22121da177e4SLinus Torvalds * an index root attribute or an index allocation attribute.
22131da177e4SLinus Torvalds *
22141da177e4SLinus Torvalds * NOTE: Before NTFS 3.0 only filename attributes were indexed.
22151da177e4SLinus Torvalds */
22161da177e4SLinus Torvalds typedef struct {
22171da177e4SLinus Torvalds /*Ofs*/
22181da177e4SLinus Torvalds /* 0 INDEX_ENTRY_HEADER; -- Unfolded here as gcc dislikes unnamed structs. */
22191da177e4SLinus Torvalds union {
22201da177e4SLinus Torvalds struct { /* Only valid when INDEX_ENTRY_END is not set. */
22211da177e4SLinus Torvalds leMFT_REF indexed_file; /* The mft reference of the file
22221da177e4SLinus Torvalds described by this index
22231da177e4SLinus Torvalds entry. Used for directory
22241da177e4SLinus Torvalds indexes. */
22251da177e4SLinus Torvalds } __attribute__ ((__packed__)) dir;
22261da177e4SLinus Torvalds struct { /* Used for views/indexes to find the entry's data. */
22271da177e4SLinus Torvalds le16 data_offset; /* Data byte offset from this
22281da177e4SLinus Torvalds INDEX_ENTRY. Follows the
22291da177e4SLinus Torvalds index key. */
22301da177e4SLinus Torvalds le16 data_length; /* Data length in bytes. */
22311da177e4SLinus Torvalds le32 reservedV; /* Reserved (zero). */
22321da177e4SLinus Torvalds } __attribute__ ((__packed__)) vi;
22331da177e4SLinus Torvalds } __attribute__ ((__packed__)) data;
22341da177e4SLinus Torvalds le16 length; /* Byte size of this index entry, multiple of
22351da177e4SLinus Torvalds 8-bytes. */
22361da177e4SLinus Torvalds le16 key_length; /* Byte size of the key value, which is in the
22371da177e4SLinus Torvalds index entry. It follows field reserved. Not
22381da177e4SLinus Torvalds multiple of 8-bytes. */
22391da177e4SLinus Torvalds INDEX_ENTRY_FLAGS flags; /* Bit field of INDEX_ENTRY_* flags. */
22401da177e4SLinus Torvalds le16 reserved; /* Reserved/align to 8-byte boundary. */
22411da177e4SLinus Torvalds
22421da177e4SLinus Torvalds /* 16*/ union { /* The key of the indexed attribute. NOTE: Only present
22431da177e4SLinus Torvalds if INDEX_ENTRY_END bit in flags is not set. NOTE: On
22441da177e4SLinus Torvalds NTFS versions before 3.0 the only valid key is the
22451da177e4SLinus Torvalds FILE_NAME_ATTR. On NTFS 3.0+ the following
22461da177e4SLinus Torvalds additional index keys are defined: */
22471da177e4SLinus Torvalds FILE_NAME_ATTR file_name;/* $I30 index in directories. */
22481da177e4SLinus Torvalds SII_INDEX_KEY sii; /* $SII index in $Secure. */
22491da177e4SLinus Torvalds SDH_INDEX_KEY sdh; /* $SDH index in $Secure. */
22501da177e4SLinus Torvalds GUID object_id; /* $O index in FILE_Extend/$ObjId: The
22511da177e4SLinus Torvalds object_id of the mft record found in
22521da177e4SLinus Torvalds the data part of the index. */
22531da177e4SLinus Torvalds REPARSE_INDEX_KEY reparse; /* $R index in
22541da177e4SLinus Torvalds FILE_Extend/$Reparse. */
22551da177e4SLinus Torvalds SID sid; /* $O index in FILE_Extend/$Quota:
22561da177e4SLinus Torvalds SID of the owner of the user_id. */
22571da177e4SLinus Torvalds le32 owner_id; /* $Q index in FILE_Extend/$Quota:
22581da177e4SLinus Torvalds user_id of the owner of the quota
22591da177e4SLinus Torvalds control entry in the data part of
22601da177e4SLinus Torvalds the index. */
22611da177e4SLinus Torvalds } __attribute__ ((__packed__)) key;
22621da177e4SLinus Torvalds /* The (optional) index data is inserted here when creating. */
22631da177e4SLinus Torvalds // leVCN vcn; /* If INDEX_ENTRY_NODE bit in flags is set, the last
22641da177e4SLinus Torvalds // eight bytes of this index entry contain the virtual
22651da177e4SLinus Torvalds // cluster number of the index block that holds the
22661da177e4SLinus Torvalds // entries immediately preceding the current entry (the
22671da177e4SLinus Torvalds // vcn references the corresponding cluster in the data
22681da177e4SLinus Torvalds // of the non-resident index allocation attribute). If
22691da177e4SLinus Torvalds // the key_length is zero, then the vcn immediately
22701da177e4SLinus Torvalds // follows the INDEX_ENTRY_HEADER. Regardless of
22711da177e4SLinus Torvalds // key_length, the address of the 8-byte boundary
227225985edcSLucas De Marchi // aligned vcn of INDEX_ENTRY{_HEADER} *ie is given by
22731da177e4SLinus Torvalds // (char*)ie + le16_to_cpu(ie*)->length) - sizeof(VCN),
22741da177e4SLinus Torvalds // where sizeof(VCN) can be hardcoded as 8 if wanted. */
22751da177e4SLinus Torvalds } __attribute__ ((__packed__)) INDEX_ENTRY;
22761da177e4SLinus Torvalds
22771da177e4SLinus Torvalds /*
22781da177e4SLinus Torvalds * Attribute: Bitmap (0xb0).
22791da177e4SLinus Torvalds *
22801da177e4SLinus Torvalds * Contains an array of bits (aka a bitfield).
22811da177e4SLinus Torvalds *
22821da177e4SLinus Torvalds * When used in conjunction with the index allocation attribute, each bit
22831da177e4SLinus Torvalds * corresponds to one index block within the index allocation attribute. Thus
22841da177e4SLinus Torvalds * the number of bits in the bitmap * index block size / cluster size is the
22851da177e4SLinus Torvalds * number of clusters in the index allocation attribute.
22861da177e4SLinus Torvalds */
22871da177e4SLinus Torvalds typedef struct {
22881da177e4SLinus Torvalds u8 bitmap[0]; /* Array of bits. */
22891da177e4SLinus Torvalds } __attribute__ ((__packed__)) BITMAP_ATTR;
22901da177e4SLinus Torvalds
22911da177e4SLinus Torvalds /*
22921da177e4SLinus Torvalds * The reparse point tag defines the type of the reparse point. It also
22931da177e4SLinus Torvalds * includes several flags, which further describe the reparse point.
22941da177e4SLinus Torvalds *
22951da177e4SLinus Torvalds * The reparse point tag is an unsigned 32-bit value divided in three parts:
22961da177e4SLinus Torvalds *
22971da177e4SLinus Torvalds * 1. The least significant 16 bits (i.e. bits 0 to 15) specifiy the type of
22981da177e4SLinus Torvalds * the reparse point.
22991da177e4SLinus Torvalds * 2. The 13 bits after this (i.e. bits 16 to 28) are reserved for future use.
23001da177e4SLinus Torvalds * 3. The most significant three bits are flags describing the reparse point.
23011da177e4SLinus Torvalds * They are defined as follows:
23021da177e4SLinus Torvalds * bit 29: Name surrogate bit. If set, the filename is an alias for
23031da177e4SLinus Torvalds * another object in the system.
23041da177e4SLinus Torvalds * bit 30: High-latency bit. If set, accessing the first byte of data will
23051da177e4SLinus Torvalds * be slow. (E.g. the data is stored on a tape drive.)
23061da177e4SLinus Torvalds * bit 31: Microsoft bit. If set, the tag is owned by Microsoft. User
23071da177e4SLinus Torvalds * defined tags have to use zero here.
23081da177e4SLinus Torvalds *
23091da177e4SLinus Torvalds * These are the predefined reparse point tags:
23101da177e4SLinus Torvalds */
23111da177e4SLinus Torvalds enum {
231263cd8854SHarvey Harrison IO_REPARSE_TAG_IS_ALIAS = cpu_to_le32(0x20000000),
231363cd8854SHarvey Harrison IO_REPARSE_TAG_IS_HIGH_LATENCY = cpu_to_le32(0x40000000),
231463cd8854SHarvey Harrison IO_REPARSE_TAG_IS_MICROSOFT = cpu_to_le32(0x80000000),
23151da177e4SLinus Torvalds
231663cd8854SHarvey Harrison IO_REPARSE_TAG_RESERVED_ZERO = cpu_to_le32(0x00000000),
231763cd8854SHarvey Harrison IO_REPARSE_TAG_RESERVED_ONE = cpu_to_le32(0x00000001),
231863cd8854SHarvey Harrison IO_REPARSE_TAG_RESERVED_RANGE = cpu_to_le32(0x00000001),
23191da177e4SLinus Torvalds
232063cd8854SHarvey Harrison IO_REPARSE_TAG_NSS = cpu_to_le32(0x68000005),
232163cd8854SHarvey Harrison IO_REPARSE_TAG_NSS_RECOVER = cpu_to_le32(0x68000006),
232263cd8854SHarvey Harrison IO_REPARSE_TAG_SIS = cpu_to_le32(0x68000007),
232363cd8854SHarvey Harrison IO_REPARSE_TAG_DFS = cpu_to_le32(0x68000008),
23241da177e4SLinus Torvalds
232563cd8854SHarvey Harrison IO_REPARSE_TAG_MOUNT_POINT = cpu_to_le32(0x88000003),
23261da177e4SLinus Torvalds
232763cd8854SHarvey Harrison IO_REPARSE_TAG_HSM = cpu_to_le32(0xa8000004),
23281da177e4SLinus Torvalds
232963cd8854SHarvey Harrison IO_REPARSE_TAG_SYMBOLIC_LINK = cpu_to_le32(0xe8000000),
23301da177e4SLinus Torvalds
233163cd8854SHarvey Harrison IO_REPARSE_TAG_VALID_VALUES = cpu_to_le32(0xe000ffff),
23321da177e4SLinus Torvalds };
23331da177e4SLinus Torvalds
23341da177e4SLinus Torvalds /*
23351da177e4SLinus Torvalds * Attribute: Reparse point (0xc0).
23361da177e4SLinus Torvalds *
23371da177e4SLinus Torvalds * NOTE: Can be resident or non-resident.
23381da177e4SLinus Torvalds */
23391da177e4SLinus Torvalds typedef struct {
23401da177e4SLinus Torvalds le32 reparse_tag; /* Reparse point type (inc. flags). */
23411da177e4SLinus Torvalds le16 reparse_data_length; /* Byte size of reparse data. */
23421da177e4SLinus Torvalds le16 reserved; /* Align to 8-byte boundary. */
23431da177e4SLinus Torvalds u8 reparse_data[0]; /* Meaning depends on reparse_tag. */
23441da177e4SLinus Torvalds } __attribute__ ((__packed__)) REPARSE_POINT;
23451da177e4SLinus Torvalds
23461da177e4SLinus Torvalds /*
23471da177e4SLinus Torvalds * Attribute: Extended attribute (EA) information (0xd0).
23481da177e4SLinus Torvalds *
23491da177e4SLinus Torvalds * NOTE: Always resident. (Is this true???)
23501da177e4SLinus Torvalds */
23511da177e4SLinus Torvalds typedef struct {
23521da177e4SLinus Torvalds le16 ea_length; /* Byte size of the packed extended
23531da177e4SLinus Torvalds attributes. */
23541da177e4SLinus Torvalds le16 need_ea_count; /* The number of extended attributes which have
23551da177e4SLinus Torvalds the NEED_EA bit set. */
23561da177e4SLinus Torvalds le32 ea_query_length; /* Byte size of the buffer required to query
23571da177e4SLinus Torvalds the extended attributes when calling
23581da177e4SLinus Torvalds ZwQueryEaFile() in Windows NT/2k. I.e. the
23591da177e4SLinus Torvalds byte size of the unpacked extended
23601da177e4SLinus Torvalds attributes. */
23611da177e4SLinus Torvalds } __attribute__ ((__packed__)) EA_INFORMATION;
23621da177e4SLinus Torvalds
23631da177e4SLinus Torvalds /*
23641da177e4SLinus Torvalds * Extended attribute flags (8-bit).
23651da177e4SLinus Torvalds */
23661da177e4SLinus Torvalds enum {
2367c9c2009aSAnton Altaparmakov NEED_EA = 0x80 /* If set the file to which the EA belongs
2368c9c2009aSAnton Altaparmakov cannot be interpreted without understanding
2369c9c2009aSAnton Altaparmakov the associates extended attributes. */
23701da177e4SLinus Torvalds } __attribute__ ((__packed__));
23711da177e4SLinus Torvalds
23721da177e4SLinus Torvalds typedef u8 EA_FLAGS;
23731da177e4SLinus Torvalds
23741da177e4SLinus Torvalds /*
23751da177e4SLinus Torvalds * Attribute: Extended attribute (EA) (0xe0).
23761da177e4SLinus Torvalds *
23777d0ffdb2SAnton Altaparmakov * NOTE: Can be resident or non-resident.
23781da177e4SLinus Torvalds *
23791da177e4SLinus Torvalds * Like the attribute list and the index buffer list, the EA attribute value is
23801da177e4SLinus Torvalds * a sequence of EA_ATTR variable length records.
23811da177e4SLinus Torvalds */
23821da177e4SLinus Torvalds typedef struct {
23831da177e4SLinus Torvalds le32 next_entry_offset; /* Offset to the next EA_ATTR. */
23841da177e4SLinus Torvalds EA_FLAGS flags; /* Flags describing the EA. */
23857d0ffdb2SAnton Altaparmakov u8 ea_name_length; /* Length of the name of the EA in bytes
23867d0ffdb2SAnton Altaparmakov excluding the '\0' byte terminator. */
23871da177e4SLinus Torvalds le16 ea_value_length; /* Byte size of the EA's value. */
23887d0ffdb2SAnton Altaparmakov u8 ea_name[0]; /* Name of the EA. Note this is ASCII, not
23897d0ffdb2SAnton Altaparmakov Unicode and it is zero terminated. */
23901da177e4SLinus Torvalds u8 ea_value[0]; /* The value of the EA. Immediately follows
23911da177e4SLinus Torvalds the name. */
23921da177e4SLinus Torvalds } __attribute__ ((__packed__)) EA_ATTR;
23931da177e4SLinus Torvalds
23941da177e4SLinus Torvalds /*
23951da177e4SLinus Torvalds * Attribute: Property set (0xf0).
23961da177e4SLinus Torvalds *
23971da177e4SLinus Torvalds * Intended to support Native Structure Storage (NSS) - a feature removed from
23981da177e4SLinus Torvalds * NTFS 3.0 during beta testing.
23991da177e4SLinus Torvalds */
24001da177e4SLinus Torvalds typedef struct {
24011da177e4SLinus Torvalds /* Irrelevant as feature unused. */
24021da177e4SLinus Torvalds } __attribute__ ((__packed__)) PROPERTY_SET;
24031da177e4SLinus Torvalds
24041da177e4SLinus Torvalds /*
24051da177e4SLinus Torvalds * Attribute: Logged utility stream (0x100).
24061da177e4SLinus Torvalds *
24071da177e4SLinus Torvalds * NOTE: Can be resident or non-resident.
24081da177e4SLinus Torvalds *
24091da177e4SLinus Torvalds * Operations on this attribute are logged to the journal ($LogFile) like
24101da177e4SLinus Torvalds * normal metadata changes.
24111da177e4SLinus Torvalds *
24121da177e4SLinus Torvalds * Used by the Encrypting File System (EFS). All encrypted files have this
24131da177e4SLinus Torvalds * attribute with the name $EFS.
24141da177e4SLinus Torvalds */
24151da177e4SLinus Torvalds typedef struct {
24161da177e4SLinus Torvalds /* Can be anything the creator chooses. */
24171da177e4SLinus Torvalds /* EFS uses it as follows: */
24181da177e4SLinus Torvalds // FIXME: Type this info, verifying it along the way. (AIA)
24191da177e4SLinus Torvalds } __attribute__ ((__packed__)) LOGGED_UTILITY_STREAM, EFS_ATTR;
24201da177e4SLinus Torvalds
24211da177e4SLinus Torvalds #endif /* _LINUX_NTFS_LAYOUT_H */
2422