1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * 4 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved. 5 * 6 * on-disk ntfs structs 7 */ 8 9 // clang-format off 10 #ifndef _LINUX_NTFS3_NTFS_H 11 #define _LINUX_NTFS3_NTFS_H 12 13 /* TODO: Check 4K MFT record and 512 bytes cluster. */ 14 15 /* Activate this define to use binary search in indexes. */ 16 #define NTFS3_INDEX_BINARY_SEARCH 17 18 /* Check each run for marked clusters. */ 19 #define NTFS3_CHECK_FREE_CLST 20 21 #define NTFS_NAME_LEN 255 22 23 /* ntfs.sys used 500 maximum links on-disk struct allows up to 0xffff. */ 24 #define NTFS_LINK_MAX 0x400 25 //#define NTFS_LINK_MAX 0xffff 26 27 /* 28 * Activate to use 64 bit clusters instead of 32 bits in ntfs.sys. 29 * Logical and virtual cluster number if needed, may be 30 * redefined to use 64 bit value. 31 */ 32 //#define CONFIG_NTFS3_64BIT_CLUSTER 33 34 #define NTFS_LZNT_MAX_CLUSTER 4096 35 #define NTFS_LZNT_CUNIT 4 36 #define NTFS_LZNT_CLUSTERS (1u<<NTFS_LZNT_CUNIT) 37 38 struct GUID { 39 __le32 Data1; 40 __le16 Data2; 41 __le16 Data3; 42 u8 Data4[8]; 43 }; 44 45 /* 46 * This struct repeats layout of ATTR_FILE_NAME 47 * at offset 0x40. 48 * It used to store global constants NAME_MFT/NAME_MIRROR... 49 * most constant names are shorter than 10. 50 */ 51 struct cpu_str { 52 u8 len; 53 u8 unused; 54 u16 name[10]; 55 }; 56 57 struct le_str { 58 u8 len; 59 u8 unused; 60 __le16 name[]; 61 }; 62 63 static_assert(SECTOR_SHIFT == 9); 64 65 #ifdef CONFIG_NTFS3_64BIT_CLUSTER 66 typedef u64 CLST; 67 static_assert(sizeof(size_t) == 8); 68 #else 69 typedef u32 CLST; 70 #endif 71 72 #define SPARSE_LCN64 ((u64)-1) 73 #define SPARSE_LCN ((CLST)-1) 74 #define RESIDENT_LCN ((CLST)-2) 75 #define COMPRESSED_LCN ((CLST)-3) 76 77 #define COMPRESSION_UNIT 4 78 #define COMPRESS_MAX_CLUSTER 0x1000 79 #define MFT_INCREASE_CHUNK 1024 80 81 enum RECORD_NUM { 82 MFT_REC_MFT = 0, 83 MFT_REC_MIRR = 1, 84 MFT_REC_LOG = 2, 85 MFT_REC_VOL = 3, 86 MFT_REC_ATTR = 4, 87 MFT_REC_ROOT = 5, 88 MFT_REC_BITMAP = 6, 89 MFT_REC_BOOT = 7, 90 MFT_REC_BADCLUST = 8, 91 //MFT_REC_QUOTA = 9, 92 MFT_REC_SECURE = 9, // NTFS 3.0 93 MFT_REC_UPCASE = 10, 94 MFT_REC_EXTEND = 11, // NTFS 3.0 95 MFT_REC_RESERVED = 11, 96 MFT_REC_FREE = 16, 97 MFT_REC_USER = 24, 98 }; 99 100 enum ATTR_TYPE { 101 ATTR_ZERO = cpu_to_le32(0x00), 102 ATTR_STD = cpu_to_le32(0x10), 103 ATTR_LIST = cpu_to_le32(0x20), 104 ATTR_NAME = cpu_to_le32(0x30), 105 // ATTR_VOLUME_VERSION on Nt4 106 ATTR_ID = cpu_to_le32(0x40), 107 ATTR_SECURE = cpu_to_le32(0x50), 108 ATTR_LABEL = cpu_to_le32(0x60), 109 ATTR_VOL_INFO = cpu_to_le32(0x70), 110 ATTR_DATA = cpu_to_le32(0x80), 111 ATTR_ROOT = cpu_to_le32(0x90), 112 ATTR_ALLOC = cpu_to_le32(0xA0), 113 ATTR_BITMAP = cpu_to_le32(0xB0), 114 // ATTR_SYMLINK on Nt4 115 ATTR_REPARSE = cpu_to_le32(0xC0), 116 ATTR_EA_INFO = cpu_to_le32(0xD0), 117 ATTR_EA = cpu_to_le32(0xE0), 118 ATTR_PROPERTYSET = cpu_to_le32(0xF0), 119 ATTR_LOGGED_UTILITY_STREAM = cpu_to_le32(0x100), 120 ATTR_END = cpu_to_le32(0xFFFFFFFF) 121 }; 122 123 static_assert(sizeof(enum ATTR_TYPE) == 4); 124 125 enum FILE_ATTRIBUTE { 126 FILE_ATTRIBUTE_READONLY = cpu_to_le32(0x00000001), 127 FILE_ATTRIBUTE_HIDDEN = cpu_to_le32(0x00000002), 128 FILE_ATTRIBUTE_SYSTEM = cpu_to_le32(0x00000004), 129 FILE_ATTRIBUTE_ARCHIVE = cpu_to_le32(0x00000020), 130 FILE_ATTRIBUTE_DEVICE = cpu_to_le32(0x00000040), 131 FILE_ATTRIBUTE_TEMPORARY = cpu_to_le32(0x00000100), 132 FILE_ATTRIBUTE_SPARSE_FILE = cpu_to_le32(0x00000200), 133 FILE_ATTRIBUTE_REPARSE_POINT = cpu_to_le32(0x00000400), 134 FILE_ATTRIBUTE_COMPRESSED = cpu_to_le32(0x00000800), 135 FILE_ATTRIBUTE_OFFLINE = cpu_to_le32(0x00001000), 136 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = cpu_to_le32(0x00002000), 137 FILE_ATTRIBUTE_ENCRYPTED = cpu_to_le32(0x00004000), 138 FILE_ATTRIBUTE_VALID_FLAGS = cpu_to_le32(0x00007fb7), 139 FILE_ATTRIBUTE_DIRECTORY = cpu_to_le32(0x10000000), 140 }; 141 142 static_assert(sizeof(enum FILE_ATTRIBUTE) == 4); 143 144 extern const struct cpu_str NAME_MFT; 145 extern const struct cpu_str NAME_MIRROR; 146 extern const struct cpu_str NAME_LOGFILE; 147 extern const struct cpu_str NAME_VOLUME; 148 extern const struct cpu_str NAME_ATTRDEF; 149 extern const struct cpu_str NAME_ROOT; 150 extern const struct cpu_str NAME_BITMAP; 151 extern const struct cpu_str NAME_BOOT; 152 extern const struct cpu_str NAME_BADCLUS; 153 extern const struct cpu_str NAME_QUOTA; 154 extern const struct cpu_str NAME_SECURE; 155 extern const struct cpu_str NAME_UPCASE; 156 extern const struct cpu_str NAME_EXTEND; 157 extern const struct cpu_str NAME_OBJID; 158 extern const struct cpu_str NAME_REPARSE; 159 extern const struct cpu_str NAME_USNJRNL; 160 161 extern const __le16 I30_NAME[4]; 162 extern const __le16 SII_NAME[4]; 163 extern const __le16 SDH_NAME[4]; 164 extern const __le16 SO_NAME[2]; 165 extern const __le16 SQ_NAME[2]; 166 extern const __le16 SR_NAME[2]; 167 168 extern const __le16 BAD_NAME[4]; 169 extern const __le16 SDS_NAME[4]; 170 extern const __le16 WOF_NAME[17]; /* WofCompressedData */ 171 172 /* MFT record number structure. */ 173 struct MFT_REF { 174 __le32 low; // The low part of the number. 175 __le16 high; // The high part of the number. 176 __le16 seq; // The sequence number of MFT record. 177 }; 178 179 static_assert(sizeof(__le64) == sizeof(struct MFT_REF)); 180 181 static inline CLST ino_get(const struct MFT_REF *ref) 182 { 183 #ifdef CONFIG_NTFS3_64BIT_CLUSTER 184 return le32_to_cpu(ref->low) | ((u64)le16_to_cpu(ref->high) << 32); 185 #else 186 return le32_to_cpu(ref->low); 187 #endif 188 } 189 190 struct NTFS_BOOT { 191 u8 jump_code[3]; // 0x00: Jump to boot code. 192 u8 system_id[8]; // 0x03: System ID, equals "NTFS " 193 194 // NOTE: This member is not aligned(!) 195 // bytes_per_sector[0] must be 0. 196 // bytes_per_sector[1] must be multiplied by 256. 197 u8 bytes_per_sector[2]; // 0x0B: Bytes per sector. 198 199 u8 sectors_per_clusters;// 0x0D: Sectors per cluster. 200 u8 unused1[7]; 201 u8 media_type; // 0x15: Media type (0xF8 - harddisk) 202 u8 unused2[2]; 203 __le16 sct_per_track; // 0x18: number of sectors per track. 204 __le16 heads; // 0x1A: number of heads per cylinder. 205 __le32 hidden_sectors; // 0x1C: number of 'hidden' sectors. 206 u8 unused3[4]; 207 u8 bios_drive_num; // 0x24: BIOS drive number =0x80. 208 u8 unused4; 209 u8 signature_ex; // 0x26: Extended BOOT signature =0x80. 210 u8 unused5; 211 __le64 sectors_per_volume;// 0x28: Size of volume in sectors. 212 __le64 mft_clst; // 0x30: First cluster of $MFT 213 __le64 mft2_clst; // 0x38: First cluster of $MFTMirr 214 s8 record_size; // 0x40: Size of MFT record in clusters(sectors). 215 u8 unused6[3]; 216 s8 index_size; // 0x44: Size of INDX record in clusters(sectors). 217 u8 unused7[3]; 218 __le64 serial_num; // 0x48: Volume serial number 219 __le32 check_sum; // 0x50: Simple additive checksum of all 220 // of the u32's which precede the 'check_sum'. 221 222 u8 boot_code[0x200 - 0x50 - 2 - 4]; // 0x54: 223 u8 boot_magic[2]; // 0x1FE: Boot signature =0x55 + 0xAA 224 }; 225 226 static_assert(sizeof(struct NTFS_BOOT) == 0x200); 227 228 enum NTFS_SIGNATURE { 229 NTFS_FILE_SIGNATURE = cpu_to_le32(0x454C4946), // 'FILE' 230 NTFS_INDX_SIGNATURE = cpu_to_le32(0x58444E49), // 'INDX' 231 NTFS_CHKD_SIGNATURE = cpu_to_le32(0x444B4843), // 'CHKD' 232 NTFS_RSTR_SIGNATURE = cpu_to_le32(0x52545352), // 'RSTR' 233 NTFS_RCRD_SIGNATURE = cpu_to_le32(0x44524352), // 'RCRD' 234 NTFS_BAAD_SIGNATURE = cpu_to_le32(0x44414142), // 'BAAD' 235 NTFS_HOLE_SIGNATURE = cpu_to_le32(0x454C4F48), // 'HOLE' 236 NTFS_FFFF_SIGNATURE = cpu_to_le32(0xffffffff), 237 }; 238 239 static_assert(sizeof(enum NTFS_SIGNATURE) == 4); 240 241 /* MFT Record header structure. */ 242 struct NTFS_RECORD_HEADER { 243 /* Record magic number, equals 'FILE'/'INDX'/'RSTR'/'RCRD'. */ 244 enum NTFS_SIGNATURE sign; // 0x00: 245 __le16 fix_off; // 0x04: 246 __le16 fix_num; // 0x06: 247 __le64 lsn; // 0x08: Log file sequence number, 248 }; 249 250 static_assert(sizeof(struct NTFS_RECORD_HEADER) == 0x10); 251 252 static inline int is_baad(const struct NTFS_RECORD_HEADER *hdr) 253 { 254 return hdr->sign == NTFS_BAAD_SIGNATURE; 255 } 256 257 /* Possible bits in struct MFT_REC.flags. */ 258 enum RECORD_FLAG { 259 RECORD_FLAG_IN_USE = cpu_to_le16(0x0001), 260 RECORD_FLAG_DIR = cpu_to_le16(0x0002), 261 RECORD_FLAG_SYSTEM = cpu_to_le16(0x0004), 262 RECORD_FLAG_UNKNOWN = cpu_to_le16(0x0008), 263 }; 264 265 /* MFT Record structure. */ 266 struct MFT_REC { 267 struct NTFS_RECORD_HEADER rhdr; // 'FILE' 268 269 __le16 seq; // 0x10: Sequence number for this record. 270 __le16 hard_links; // 0x12: The number of hard links to record. 271 __le16 attr_off; // 0x14: Offset to attributes. 272 __le16 flags; // 0x16: See RECORD_FLAG. 273 __le32 used; // 0x18: The size of used part. 274 __le32 total; // 0x1C: Total record size. 275 276 struct MFT_REF parent_ref; // 0x20: Parent MFT record. 277 __le16 next_attr_id; // 0x28: The next attribute Id. 278 279 __le16 res; // 0x2A: High part of MFT record? 280 __le32 mft_record; // 0x2C: Current MFT record number. 281 __le16 fixups[]; // 0x30: 282 }; 283 284 #define MFTRECORD_FIXUP_OFFSET_1 offsetof(struct MFT_REC, res) 285 #define MFTRECORD_FIXUP_OFFSET_3 offsetof(struct MFT_REC, fixups) 286 287 static_assert(MFTRECORD_FIXUP_OFFSET_1 == 0x2A); 288 static_assert(MFTRECORD_FIXUP_OFFSET_3 == 0x30); 289 290 static inline bool is_rec_base(const struct MFT_REC *rec) 291 { 292 const struct MFT_REF *r = &rec->parent_ref; 293 294 return !r->low && !r->high && !r->seq; 295 } 296 297 static inline bool is_mft_rec5(const struct MFT_REC *rec) 298 { 299 return le16_to_cpu(rec->rhdr.fix_off) >= 300 offsetof(struct MFT_REC, fixups); 301 } 302 303 static inline bool is_rec_inuse(const struct MFT_REC *rec) 304 { 305 return rec->flags & RECORD_FLAG_IN_USE; 306 } 307 308 static inline bool clear_rec_inuse(struct MFT_REC *rec) 309 { 310 return rec->flags &= ~RECORD_FLAG_IN_USE; 311 } 312 313 /* Possible values of ATTR_RESIDENT.flags */ 314 #define RESIDENT_FLAG_INDEXED 0x01 315 316 struct ATTR_RESIDENT { 317 __le32 data_size; // 0x10: The size of data. 318 __le16 data_off; // 0x14: Offset to data. 319 u8 flags; // 0x16: Resident flags ( 1 - indexed ). 320 u8 res; // 0x17: 321 }; // sizeof() = 0x18 322 323 struct ATTR_NONRESIDENT { 324 __le64 svcn; // 0x10: Starting VCN of this segment. 325 __le64 evcn; // 0x18: End VCN of this segment. 326 __le16 run_off; // 0x20: Offset to packed runs. 327 // Unit of Compression size for this stream, expressed 328 // as a log of the cluster size. 329 // 330 // 0 means file is not compressed 331 // 1, 2, 3, and 4 are potentially legal values if the 332 // stream is compressed, however the implementation 333 // may only choose to use 4, or possibly 3. Note 334 // that 4 means cluster size time 16. If convenient 335 // the implementation may wish to accept a 336 // reasonable range of legal values here (1-5?), 337 // even if the implementation only generates 338 // a smaller set of values itself. 339 u8 c_unit; // 0x22: 340 u8 res1[5]; // 0x23: 341 __le64 alloc_size; // 0x28: The allocated size of attribute in bytes. 342 // (multiple of cluster size) 343 __le64 data_size; // 0x30: The size of attribute in bytes <= alloc_size. 344 __le64 valid_size; // 0x38: The size of valid part in bytes <= data_size. 345 __le64 total_size; // 0x40: The sum of the allocated clusters for a file. 346 // (present only for the first segment (0 == vcn) 347 // of compressed attribute) 348 349 }; // sizeof()=0x40 or 0x48 (if compressed) 350 351 /* Possible values of ATTRIB.flags: */ 352 #define ATTR_FLAG_COMPRESSED cpu_to_le16(0x0001) 353 #define ATTR_FLAG_COMPRESSED_MASK cpu_to_le16(0x00FF) 354 #define ATTR_FLAG_ENCRYPTED cpu_to_le16(0x4000) 355 #define ATTR_FLAG_SPARSED cpu_to_le16(0x8000) 356 357 struct ATTRIB { 358 enum ATTR_TYPE type; // 0x00: The type of this attribute. 359 __le32 size; // 0x04: The size of this attribute. 360 u8 non_res; // 0x08: Is this attribute non-resident? 361 u8 name_len; // 0x09: This attribute name length. 362 __le16 name_off; // 0x0A: Offset to the attribute name. 363 __le16 flags; // 0x0C: See ATTR_FLAG_XXX. 364 __le16 id; // 0x0E: Unique id (per record). 365 366 union { 367 struct ATTR_RESIDENT res; // 0x10 368 struct ATTR_NONRESIDENT nres; // 0x10 369 }; 370 }; 371 372 /* Define attribute sizes. */ 373 #define SIZEOF_RESIDENT 0x18 374 #define SIZEOF_NONRESIDENT_EX 0x48 375 #define SIZEOF_NONRESIDENT 0x40 376 377 #define SIZEOF_RESIDENT_LE cpu_to_le16(0x18) 378 #define SIZEOF_NONRESIDENT_EX_LE cpu_to_le16(0x48) 379 #define SIZEOF_NONRESIDENT_LE cpu_to_le16(0x40) 380 381 static inline u64 attr_ondisk_size(const struct ATTRIB *attr) 382 { 383 return attr->non_res ? ((attr->flags & 384 (ATTR_FLAG_COMPRESSED | ATTR_FLAG_SPARSED)) ? 385 le64_to_cpu(attr->nres.total_size) : 386 le64_to_cpu(attr->nres.alloc_size)) 387 : ALIGN(le32_to_cpu(attr->res.data_size), 8); 388 } 389 390 static inline u64 attr_size(const struct ATTRIB *attr) 391 { 392 return attr->non_res ? le64_to_cpu(attr->nres.data_size) : 393 le32_to_cpu(attr->res.data_size); 394 } 395 396 static inline bool is_attr_encrypted(const struct ATTRIB *attr) 397 { 398 return attr->flags & ATTR_FLAG_ENCRYPTED; 399 } 400 401 static inline bool is_attr_sparsed(const struct ATTRIB *attr) 402 { 403 return attr->flags & ATTR_FLAG_SPARSED; 404 } 405 406 static inline bool is_attr_compressed(const struct ATTRIB *attr) 407 { 408 return attr->flags & ATTR_FLAG_COMPRESSED; 409 } 410 411 static inline bool is_attr_ext(const struct ATTRIB *attr) 412 { 413 return attr->flags & (ATTR_FLAG_SPARSED | ATTR_FLAG_COMPRESSED); 414 } 415 416 static inline bool is_attr_indexed(const struct ATTRIB *attr) 417 { 418 return !attr->non_res && (attr->res.flags & RESIDENT_FLAG_INDEXED); 419 } 420 421 static inline __le16 const *attr_name(const struct ATTRIB *attr) 422 { 423 return Add2Ptr(attr, le16_to_cpu(attr->name_off)); 424 } 425 426 static inline u64 attr_svcn(const struct ATTRIB *attr) 427 { 428 return attr->non_res ? le64_to_cpu(attr->nres.svcn) : 0; 429 } 430 431 /* The size of resident attribute by its resident size. */ 432 #define BYTES_PER_RESIDENT(b) (0x18 + (b)) 433 434 static_assert(sizeof(struct ATTRIB) == 0x48); 435 static_assert(sizeof(((struct ATTRIB *)NULL)->res) == 0x08); 436 static_assert(sizeof(((struct ATTRIB *)NULL)->nres) == 0x38); 437 438 static inline void *resident_data_ex(const struct ATTRIB *attr, u32 datasize) 439 { 440 u32 asize, rsize; 441 u16 off; 442 443 if (attr->non_res) 444 return NULL; 445 446 asize = le32_to_cpu(attr->size); 447 off = le16_to_cpu(attr->res.data_off); 448 449 if (asize < datasize + off) 450 return NULL; 451 452 rsize = le32_to_cpu(attr->res.data_size); 453 if (rsize < datasize) 454 return NULL; 455 456 return Add2Ptr(attr, off); 457 } 458 459 static inline void *resident_data(const struct ATTRIB *attr) 460 { 461 return Add2Ptr(attr, le16_to_cpu(attr->res.data_off)); 462 } 463 464 static inline void *attr_run(const struct ATTRIB *attr) 465 { 466 return Add2Ptr(attr, le16_to_cpu(attr->nres.run_off)); 467 } 468 469 /* Standard information attribute (0x10). */ 470 struct ATTR_STD_INFO { 471 __le64 cr_time; // 0x00: File creation file. 472 __le64 m_time; // 0x08: File modification time. 473 __le64 c_time; // 0x10: Last time any attribute was modified. 474 __le64 a_time; // 0x18: File last access time. 475 enum FILE_ATTRIBUTE fa; // 0x20: Standard DOS attributes & more. 476 __le32 max_ver_num; // 0x24: Maximum Number of Versions. 477 __le32 ver_num; // 0x28: Version Number. 478 __le32 class_id; // 0x2C: Class Id from bidirectional Class Id index. 479 }; 480 481 static_assert(sizeof(struct ATTR_STD_INFO) == 0x30); 482 483 #define SECURITY_ID_INVALID 0x00000000 484 #define SECURITY_ID_FIRST 0x00000100 485 486 struct ATTR_STD_INFO5 { 487 __le64 cr_time; // 0x00: File creation file. 488 __le64 m_time; // 0x08: File modification time. 489 __le64 c_time; // 0x10: Last time any attribute was modified. 490 __le64 a_time; // 0x18: File last access time. 491 enum FILE_ATTRIBUTE fa; // 0x20: Standard DOS attributes & more. 492 __le32 max_ver_num; // 0x24: Maximum Number of Versions. 493 __le32 ver_num; // 0x28: Version Number. 494 __le32 class_id; // 0x2C: Class Id from bidirectional Class Id index. 495 496 __le32 owner_id; // 0x30: Owner Id of the user owning the file. 497 __le32 security_id; // 0x34: The Security Id is a key in the $SII Index and $SDS. 498 __le64 quota_charge; // 0x38: 499 __le64 usn; // 0x40: Last Update Sequence Number of the file. This is a direct 500 // index into the file $UsnJrnl. If zero, the USN Journal is 501 // disabled. 502 }; 503 504 static_assert(sizeof(struct ATTR_STD_INFO5) == 0x48); 505 506 /* Attribute list entry structure (0x20) */ 507 struct ATTR_LIST_ENTRY { 508 enum ATTR_TYPE type; // 0x00: The type of attribute. 509 __le16 size; // 0x04: The size of this record. 510 u8 name_len; // 0x06: The length of attribute name. 511 u8 name_off; // 0x07: The offset to attribute name. 512 __le64 vcn; // 0x08: Starting VCN of this attribute. 513 struct MFT_REF ref; // 0x10: MFT record number with attribute. 514 __le16 id; // 0x18: struct ATTRIB ID. 515 __le16 name[3]; // 0x1A: Just to align. To get real name can use bNameOffset. 516 517 }; // sizeof(0x20) 518 519 static_assert(sizeof(struct ATTR_LIST_ENTRY) == 0x20); 520 521 static inline u32 le_size(u8 name_len) 522 { 523 return ALIGN(offsetof(struct ATTR_LIST_ENTRY, name) + 524 name_len * sizeof(short), 8); 525 } 526 527 /* Returns 0 if 'attr' has the same type and name. */ 528 static inline int le_cmp(const struct ATTR_LIST_ENTRY *le, 529 const struct ATTRIB *attr) 530 { 531 return le->type != attr->type || le->name_len != attr->name_len || 532 (!le->name_len && 533 memcmp(Add2Ptr(le, le->name_off), 534 Add2Ptr(attr, le16_to_cpu(attr->name_off)), 535 le->name_len * sizeof(short))); 536 } 537 538 static inline __le16 const *le_name(const struct ATTR_LIST_ENTRY *le) 539 { 540 return Add2Ptr(le, le->name_off); 541 } 542 543 /* File name types (the field type in struct ATTR_FILE_NAME). */ 544 #define FILE_NAME_POSIX 0 545 #define FILE_NAME_UNICODE 1 546 #define FILE_NAME_DOS 2 547 #define FILE_NAME_UNICODE_AND_DOS (FILE_NAME_DOS | FILE_NAME_UNICODE) 548 549 /* Filename attribute structure (0x30). */ 550 struct NTFS_DUP_INFO { 551 __le64 cr_time; // 0x00: File creation file. 552 __le64 m_time; // 0x08: File modification time. 553 __le64 c_time; // 0x10: Last time any attribute was modified. 554 __le64 a_time; // 0x18: File last access time. 555 __le64 alloc_size; // 0x20: Data attribute allocated size, multiple of cluster size. 556 __le64 data_size; // 0x28: Data attribute size <= Dataalloc_size. 557 enum FILE_ATTRIBUTE fa; // 0x30: Standard DOS attributes & more. 558 __le16 ea_size; // 0x34: Packed EAs. 559 __le16 reparse; // 0x36: Used by Reparse. 560 561 }; // 0x38 562 563 struct ATTR_FILE_NAME { 564 struct MFT_REF home; // 0x00: MFT record for directory. 565 struct NTFS_DUP_INFO dup;// 0x08: 566 u8 name_len; // 0x40: File name length in words. 567 u8 type; // 0x41: File name type. 568 __le16 name[]; // 0x42: File name. 569 }; 570 571 static_assert(sizeof(((struct ATTR_FILE_NAME *)NULL)->dup) == 0x38); 572 static_assert(offsetof(struct ATTR_FILE_NAME, name) == 0x42); 573 #define SIZEOF_ATTRIBUTE_FILENAME 0x44 574 #define SIZEOF_ATTRIBUTE_FILENAME_MAX (0x42 + 255 * 2) 575 576 static inline struct ATTRIB *attr_from_name(struct ATTR_FILE_NAME *fname) 577 { 578 return (struct ATTRIB *)((char *)fname - SIZEOF_RESIDENT); 579 } 580 581 static inline u16 fname_full_size(const struct ATTR_FILE_NAME *fname) 582 { 583 /* Don't return struct_size(fname, name, fname->name_len); */ 584 return offsetof(struct ATTR_FILE_NAME, name) + 585 fname->name_len * sizeof(short); 586 } 587 588 static inline u8 paired_name(u8 type) 589 { 590 if (type == FILE_NAME_UNICODE) 591 return FILE_NAME_DOS; 592 if (type == FILE_NAME_DOS) 593 return FILE_NAME_UNICODE; 594 return FILE_NAME_POSIX; 595 } 596 597 /* Index entry defines ( the field flags in NtfsDirEntry ). */ 598 #define NTFS_IE_HAS_SUBNODES cpu_to_le16(1) 599 #define NTFS_IE_LAST cpu_to_le16(2) 600 601 /* Directory entry structure. */ 602 struct NTFS_DE { 603 union { 604 struct MFT_REF ref; // 0x00: MFT record number with this file. 605 struct { 606 __le16 data_off; // 0x00: 607 __le16 data_size; // 0x02: 608 __le32 res; // 0x04: Must be 0. 609 } view; 610 }; 611 __le16 size; // 0x08: The size of this entry. 612 __le16 key_size; // 0x0A: The size of File name length in bytes + 0x42. 613 __le16 flags; // 0x0C: Entry flags: NTFS_IE_XXX. 614 __le16 res; // 0x0E: 615 616 // Here any indexed attribute can be placed. 617 // One of them is: 618 // struct ATTR_FILE_NAME AttrFileName; 619 // 620 621 // The last 8 bytes of this structure contains 622 // the VBN of subnode. 623 // !!! Note !!! 624 // This field is presented only if (flags & NTFS_IE_HAS_SUBNODES) 625 // __le64 vbn; 626 }; 627 628 static_assert(sizeof(struct NTFS_DE) == 0x10); 629 630 static inline void de_set_vbn_le(struct NTFS_DE *e, __le64 vcn) 631 { 632 __le64 *v = Add2Ptr(e, le16_to_cpu(e->size) - sizeof(__le64)); 633 634 *v = vcn; 635 } 636 637 static inline void de_set_vbn(struct NTFS_DE *e, CLST vcn) 638 { 639 __le64 *v = Add2Ptr(e, le16_to_cpu(e->size) - sizeof(__le64)); 640 641 *v = cpu_to_le64(vcn); 642 } 643 644 static inline __le64 de_get_vbn_le(const struct NTFS_DE *e) 645 { 646 return *(__le64 *)Add2Ptr(e, le16_to_cpu(e->size) - sizeof(__le64)); 647 } 648 649 static inline CLST de_get_vbn(const struct NTFS_DE *e) 650 { 651 __le64 *v = Add2Ptr(e, le16_to_cpu(e->size) - sizeof(__le64)); 652 653 return le64_to_cpu(*v); 654 } 655 656 static inline struct NTFS_DE *de_get_next(const struct NTFS_DE *e) 657 { 658 return Add2Ptr(e, le16_to_cpu(e->size)); 659 } 660 661 static inline struct ATTR_FILE_NAME *de_get_fname(const struct NTFS_DE *e) 662 { 663 return le16_to_cpu(e->key_size) >= SIZEOF_ATTRIBUTE_FILENAME ? 664 Add2Ptr(e, sizeof(struct NTFS_DE)) : 665 NULL; 666 } 667 668 static inline bool de_is_last(const struct NTFS_DE *e) 669 { 670 return e->flags & NTFS_IE_LAST; 671 } 672 673 static inline bool de_has_vcn(const struct NTFS_DE *e) 674 { 675 return e->flags & NTFS_IE_HAS_SUBNODES; 676 } 677 678 static inline bool de_has_vcn_ex(const struct NTFS_DE *e) 679 { 680 return (e->flags & NTFS_IE_HAS_SUBNODES) && 681 (u64)(-1) != *((u64 *)Add2Ptr(e, le16_to_cpu(e->size) - 682 sizeof(__le64))); 683 } 684 685 #define MAX_BYTES_PER_NAME_ENTRY \ 686 ALIGN(sizeof(struct NTFS_DE) + \ 687 offsetof(struct ATTR_FILE_NAME, name) + \ 688 NTFS_NAME_LEN * sizeof(short), 8) 689 690 struct INDEX_HDR { 691 __le32 de_off; // 0x00: The offset from the start of this structure 692 // to the first NTFS_DE. 693 __le32 used; // 0x04: The size of this structure plus all 694 // entries (quad-word aligned). 695 __le32 total; // 0x08: The allocated size of for this structure plus all entries. 696 u8 flags; // 0x0C: 0x00 = Small directory, 0x01 = Large directory. 697 u8 res[3]; 698 699 // 700 // de_off + used <= total 701 // 702 }; 703 704 static_assert(sizeof(struct INDEX_HDR) == 0x10); 705 706 static inline struct NTFS_DE *hdr_first_de(const struct INDEX_HDR *hdr) 707 { 708 u32 de_off = le32_to_cpu(hdr->de_off); 709 u32 used = le32_to_cpu(hdr->used); 710 struct NTFS_DE *e = Add2Ptr(hdr, de_off); 711 u16 esize; 712 713 if (de_off >= used || de_off >= le32_to_cpu(hdr->total)) 714 return NULL; 715 716 esize = le16_to_cpu(e->size); 717 if (esize < sizeof(struct NTFS_DE) || de_off + esize > used) 718 return NULL; 719 720 return e; 721 } 722 723 static inline struct NTFS_DE *hdr_next_de(const struct INDEX_HDR *hdr, 724 const struct NTFS_DE *e) 725 { 726 size_t off = PtrOffset(hdr, e); 727 u32 used = le32_to_cpu(hdr->used); 728 u16 esize; 729 730 if (off >= used) 731 return NULL; 732 733 esize = le16_to_cpu(e->size); 734 735 if (esize < sizeof(struct NTFS_DE) || 736 off + esize + sizeof(struct NTFS_DE) > used) 737 return NULL; 738 739 return Add2Ptr(e, esize); 740 } 741 742 static inline bool hdr_has_subnode(const struct INDEX_HDR *hdr) 743 { 744 return hdr->flags & 1; 745 } 746 747 struct INDEX_BUFFER { 748 struct NTFS_RECORD_HEADER rhdr; // 'INDX' 749 __le64 vbn; // 0x10: vcn if index >= cluster or vsn id index < cluster 750 struct INDEX_HDR ihdr; // 0x18: 751 }; 752 753 static_assert(sizeof(struct INDEX_BUFFER) == 0x28); 754 755 static inline bool ib_is_empty(const struct INDEX_BUFFER *ib) 756 { 757 const struct NTFS_DE *first = hdr_first_de(&ib->ihdr); 758 759 return !first || de_is_last(first); 760 } 761 762 static inline bool ib_is_leaf(const struct INDEX_BUFFER *ib) 763 { 764 return !(ib->ihdr.flags & 1); 765 } 766 767 /* Index root structure ( 0x90 ). */ 768 enum COLLATION_RULE { 769 NTFS_COLLATION_TYPE_BINARY = cpu_to_le32(0), 770 // $I30 771 NTFS_COLLATION_TYPE_FILENAME = cpu_to_le32(0x01), 772 // $SII of $Secure and $Q of Quota 773 NTFS_COLLATION_TYPE_UINT = cpu_to_le32(0x10), 774 // $O of Quota 775 NTFS_COLLATION_TYPE_SID = cpu_to_le32(0x11), 776 // $SDH of $Secure 777 NTFS_COLLATION_TYPE_SECURITY_HASH = cpu_to_le32(0x12), 778 // $O of ObjId and "$R" for Reparse 779 NTFS_COLLATION_TYPE_UINTS = cpu_to_le32(0x13) 780 }; 781 782 static_assert(sizeof(enum COLLATION_RULE) == 4); 783 784 // 785 struct INDEX_ROOT { 786 enum ATTR_TYPE type; // 0x00: The type of attribute to index on. 787 enum COLLATION_RULE rule; // 0x04: The rule. 788 __le32 index_block_size;// 0x08: The size of index record. 789 u8 index_block_clst; // 0x0C: The number of clusters or sectors per index. 790 u8 res[3]; 791 struct INDEX_HDR ihdr; // 0x10: 792 }; 793 794 static_assert(sizeof(struct INDEX_ROOT) == 0x20); 795 static_assert(offsetof(struct INDEX_ROOT, ihdr) == 0x10); 796 797 #define VOLUME_FLAG_DIRTY cpu_to_le16(0x0001) 798 #define VOLUME_FLAG_RESIZE_LOG_FILE cpu_to_le16(0x0002) 799 800 struct VOLUME_INFO { 801 __le64 res1; // 0x00 802 u8 major_ver; // 0x08: NTFS major version number (before .) 803 u8 minor_ver; // 0x09: NTFS minor version number (after .) 804 __le16 flags; // 0x0A: Volume flags, see VOLUME_FLAG_XXX 805 806 }; // sizeof=0xC 807 808 #define SIZEOF_ATTRIBUTE_VOLUME_INFO 0xc 809 810 #define NTFS_LABEL_MAX_LENGTH (0x100 / sizeof(short)) 811 #define NTFS_ATTR_INDEXABLE cpu_to_le32(0x00000002) 812 #define NTFS_ATTR_DUPALLOWED cpu_to_le32(0x00000004) 813 #define NTFS_ATTR_MUST_BE_INDEXED cpu_to_le32(0x00000010) 814 #define NTFS_ATTR_MUST_BE_NAMED cpu_to_le32(0x00000020) 815 #define NTFS_ATTR_MUST_BE_RESIDENT cpu_to_le32(0x00000040) 816 #define NTFS_ATTR_LOG_ALWAYS cpu_to_le32(0x00000080) 817 818 /* $AttrDef file entry. */ 819 struct ATTR_DEF_ENTRY { 820 __le16 name[0x40]; // 0x00: Attr name. 821 enum ATTR_TYPE type; // 0x80: struct ATTRIB type. 822 __le32 res; // 0x84: 823 enum COLLATION_RULE rule; // 0x88: 824 __le32 flags; // 0x8C: NTFS_ATTR_XXX (see above). 825 __le64 min_sz; // 0x90: Minimum attribute data size. 826 __le64 max_sz; // 0x98: Maximum attribute data size. 827 }; 828 829 static_assert(sizeof(struct ATTR_DEF_ENTRY) == 0xa0); 830 831 /* Object ID (0x40) */ 832 struct OBJECT_ID { 833 struct GUID ObjId; // 0x00: Unique Id assigned to file. 834 struct GUID BirthVolumeId; // 0x10: Birth Volume Id is the Object Id of the Volume on. 835 // which the Object Id was allocated. It never changes. 836 struct GUID BirthObjectId; // 0x20: Birth Object Id is the first Object Id that was 837 // ever assigned to this MFT Record. I.e. If the Object Id 838 // is changed for some reason, this field will reflect the 839 // original value of the Object Id. 840 struct GUID DomainId; // 0x30: Domain Id is currently unused but it is intended to be 841 // used in a network environment where the local machine is 842 // part of a Windows 2000 Domain. This may be used in a Windows 843 // 2000 Advanced Server managed domain. 844 }; 845 846 static_assert(sizeof(struct OBJECT_ID) == 0x40); 847 848 /* O Directory entry structure ( rule = 0x13 ) */ 849 struct NTFS_DE_O { 850 struct NTFS_DE de; 851 struct GUID ObjId; // 0x10: Unique Id assigned to file. 852 struct MFT_REF ref; // 0x20: MFT record number with this file. 853 struct GUID BirthVolumeId; // 0x28: Birth Volume Id is the Object Id of the Volume on 854 // which the Object Id was allocated. It never changes. 855 struct GUID BirthObjectId; // 0x38: Birth Object Id is the first Object Id that was 856 // ever assigned to this MFT Record. I.e. If the Object Id 857 // is changed for some reason, this field will reflect the 858 // original value of the Object Id. 859 // This field is valid if data_size == 0x48. 860 struct GUID BirthDomainId; // 0x48: Domain Id is currently unused but it is intended 861 // to be used in a network environment where the local 862 // machine is part of a Windows 2000 Domain. This may be 863 // used in a Windows 2000 Advanced Server managed domain. 864 }; 865 866 static_assert(sizeof(struct NTFS_DE_O) == 0x58); 867 868 #define NTFS_OBJECT_ENTRY_DATA_SIZE1 \ 869 0x38 // struct NTFS_DE_O.BirthDomainId is not used 870 #define NTFS_OBJECT_ENTRY_DATA_SIZE2 \ 871 0x48 // struct NTFS_DE_O.BirthDomainId is used 872 873 /* Q Directory entry structure ( rule = 0x11 ) */ 874 struct NTFS_DE_Q { 875 struct NTFS_DE de; 876 __le32 owner_id; // 0x10: Unique Id assigned to file 877 __le32 Version; // 0x14: 0x02 878 __le32 flags2; // 0x18: Quota flags, see above 879 __le64 BytesUsed; // 0x1C: 880 __le64 ChangeTime; // 0x24: 881 __le64 WarningLimit; // 0x28: 882 __le64 HardLimit; // 0x34: 883 __le64 ExceededTime; // 0x3C: 884 885 // SID is placed here 886 }; // sizeof() = 0x44 887 888 #define SIZEOF_NTFS_DE_Q 0x44 889 890 #define SecurityDescriptorsBlockSize 0x40000 // 256K 891 #define SecurityDescriptorMaxSize 0x20000 // 128K 892 #define Log2OfSecurityDescriptorsBlockSize 18 893 894 struct SECURITY_KEY { 895 __le32 hash; // Hash value for descriptor 896 __le32 sec_id; // Security Id (guaranteed unique) 897 }; 898 899 /* Security descriptors (the content of $Secure::SDS data stream) */ 900 struct SECURITY_HDR { 901 struct SECURITY_KEY key; // 0x00: Security Key. 902 __le64 off; // 0x08: Offset of this entry in the file. 903 __le32 size; // 0x10: Size of this entry, 8 byte aligned. 904 /* 905 * Security descriptor itself is placed here. 906 * Total size is 16 byte aligned. 907 */ 908 } __packed; 909 910 #define SIZEOF_SECURITY_HDR 0x14 911 912 /* SII Directory entry structure */ 913 struct NTFS_DE_SII { 914 struct NTFS_DE de; 915 __le32 sec_id; // 0x10: Key: sizeof(security_id) = wKeySize 916 struct SECURITY_HDR sec_hdr; // 0x14: 917 } __packed; 918 919 #define SIZEOF_SII_DIRENTRY 0x28 920 921 /* SDH Directory entry structure */ 922 struct NTFS_DE_SDH { 923 struct NTFS_DE de; 924 struct SECURITY_KEY key; // 0x10: Key 925 struct SECURITY_HDR sec_hdr; // 0x18: Data 926 __le16 magic[2]; // 0x2C: 0x00490049 "I I" 927 }; 928 929 #define SIZEOF_SDH_DIRENTRY 0x30 930 931 struct REPARSE_KEY { 932 __le32 ReparseTag; // 0x00: Reparse Tag 933 struct MFT_REF ref; // 0x04: MFT record number with this file 934 }; // sizeof() = 0x0C 935 936 static_assert(offsetof(struct REPARSE_KEY, ref) == 0x04); 937 #define SIZEOF_REPARSE_KEY 0x0C 938 939 /* Reparse Directory entry structure */ 940 struct NTFS_DE_R { 941 struct NTFS_DE de; 942 struct REPARSE_KEY key; // 0x10: Reparse Key. 943 u32 zero; // 0x1c: 944 }; // sizeof() = 0x20 945 946 static_assert(sizeof(struct NTFS_DE_R) == 0x20); 947 948 /* CompressReparseBuffer.WofVersion */ 949 #define WOF_CURRENT_VERSION cpu_to_le32(1) 950 /* CompressReparseBuffer.WofProvider */ 951 #define WOF_PROVIDER_WIM cpu_to_le32(1) 952 /* CompressReparseBuffer.WofProvider */ 953 #define WOF_PROVIDER_SYSTEM cpu_to_le32(2) 954 /* CompressReparseBuffer.ProviderVer */ 955 #define WOF_PROVIDER_CURRENT_VERSION cpu_to_le32(1) 956 957 #define WOF_COMPRESSION_XPRESS4K cpu_to_le32(0) // 4k 958 #define WOF_COMPRESSION_LZX32K cpu_to_le32(1) // 32k 959 #define WOF_COMPRESSION_XPRESS8K cpu_to_le32(2) // 8k 960 #define WOF_COMPRESSION_XPRESS16K cpu_to_le32(3) // 16k 961 962 /* 963 * ATTR_REPARSE (0xC0) 964 * 965 * The reparse struct GUID structure is used by all 3rd party layered drivers to 966 * store data in a reparse point. For non-Microsoft tags, The struct GUID field 967 * cannot be GUID_NULL. 968 * The constraints on reparse tags are defined below. 969 * Microsoft tags can also be used with this format of the reparse point buffer. 970 */ 971 struct REPARSE_POINT { 972 __le32 ReparseTag; // 0x00: 973 __le16 ReparseDataLength;// 0x04: 974 __le16 Reserved; 975 976 struct GUID Guid; // 0x08: 977 978 // 979 // Here GenericReparseBuffer is placed 980 // 981 }; 982 983 static_assert(sizeof(struct REPARSE_POINT) == 0x18); 984 985 /* Maximum allowed size of the reparse data. */ 986 #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 * 1024) 987 988 /* 989 * The value of the following constant needs to satisfy the following 990 * conditions: 991 * (1) Be at least as large as the largest of the reserved tags. 992 * (2) Be strictly smaller than all the tags in use. 993 */ 994 #define IO_REPARSE_TAG_RESERVED_RANGE 1 995 996 /* 997 * The reparse tags are a ULONG. The 32 bits are laid out as follows: 998 * 999 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1000 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 1001 * +-+-+-+-+-----------------------+-------------------------------+ 1002 * |M|R|N|R| Reserved bits | Reparse Tag Value | 1003 * +-+-+-+-+-----------------------+-------------------------------+ 1004 * 1005 * M is the Microsoft bit. When set to 1, it denotes a tag owned by Microsoft. 1006 * All ISVs must use a tag with a 0 in this position. 1007 * Note: If a Microsoft tag is used by non-Microsoft software, the 1008 * behavior is not defined. 1009 * 1010 * R is reserved. Must be zero for non-Microsoft tags. 1011 * 1012 * N is name surrogate. When set to 1, the file represents another named 1013 * entity in the system. 1014 * 1015 * The M and N bits are OR-able. 1016 * The following macros check for the M and N bit values: 1017 */ 1018 1019 /* 1020 * Macro to determine whether a reparse point tag corresponds to a tag 1021 * owned by Microsoft. 1022 */ 1023 #define IsReparseTagMicrosoft(_tag) (((_tag)&IO_REPARSE_TAG_MICROSOFT)) 1024 1025 /* Macro to determine whether a reparse point tag is a name surrogate. */ 1026 #define IsReparseTagNameSurrogate(_tag) (((_tag)&IO_REPARSE_TAG_NAME_SURROGATE)) 1027 1028 /* 1029 * The following constant represents the bits that are valid to use in 1030 * reparse tags. 1031 */ 1032 #define IO_REPARSE_TAG_VALID_VALUES 0xF000FFFF 1033 1034 /* 1035 * Macro to determine whether a reparse tag is a valid tag. 1036 */ 1037 #define IsReparseTagValid(_tag) \ 1038 (!((_tag) & ~IO_REPARSE_TAG_VALID_VALUES) && \ 1039 ((_tag) > IO_REPARSE_TAG_RESERVED_RANGE)) 1040 1041 /* Microsoft tags for reparse points. */ 1042 1043 enum IO_REPARSE_TAG { 1044 IO_REPARSE_TAG_SYMBOLIC_LINK = cpu_to_le32(0), 1045 IO_REPARSE_TAG_NAME_SURROGATE = cpu_to_le32(0x20000000), 1046 IO_REPARSE_TAG_MICROSOFT = cpu_to_le32(0x80000000), 1047 IO_REPARSE_TAG_MOUNT_POINT = cpu_to_le32(0xA0000003), 1048 IO_REPARSE_TAG_SYMLINK = cpu_to_le32(0xA000000C), 1049 IO_REPARSE_TAG_HSM = cpu_to_le32(0xC0000004), 1050 IO_REPARSE_TAG_SIS = cpu_to_le32(0x80000007), 1051 IO_REPARSE_TAG_DEDUP = cpu_to_le32(0x80000013), 1052 IO_REPARSE_TAG_COMPRESS = cpu_to_le32(0x80000017), 1053 1054 /* 1055 * The reparse tag 0x80000008 is reserved for Microsoft internal use. 1056 * May be published in the future. 1057 */ 1058 1059 /* Microsoft reparse tag reserved for DFS */ 1060 IO_REPARSE_TAG_DFS = cpu_to_le32(0x8000000A), 1061 1062 /* Microsoft reparse tag reserved for the file system filter manager. */ 1063 IO_REPARSE_TAG_FILTER_MANAGER = cpu_to_le32(0x8000000B), 1064 1065 /* Non-Microsoft tags for reparse points */ 1066 1067 /* Tag allocated to CONGRUENT, May 2000. Used by IFSTEST. */ 1068 IO_REPARSE_TAG_IFSTEST_CONGRUENT = cpu_to_le32(0x00000009), 1069 1070 /* Tag allocated to ARKIVIO. */ 1071 IO_REPARSE_TAG_ARKIVIO = cpu_to_le32(0x0000000C), 1072 1073 /* Tag allocated to SOLUTIONSOFT. */ 1074 IO_REPARSE_TAG_SOLUTIONSOFT = cpu_to_le32(0x2000000D), 1075 1076 /* Tag allocated to COMMVAULT. */ 1077 IO_REPARSE_TAG_COMMVAULT = cpu_to_le32(0x0000000E), 1078 1079 /* OneDrive?? */ 1080 IO_REPARSE_TAG_CLOUD = cpu_to_le32(0x9000001A), 1081 IO_REPARSE_TAG_CLOUD_1 = cpu_to_le32(0x9000101A), 1082 IO_REPARSE_TAG_CLOUD_2 = cpu_to_le32(0x9000201A), 1083 IO_REPARSE_TAG_CLOUD_3 = cpu_to_le32(0x9000301A), 1084 IO_REPARSE_TAG_CLOUD_4 = cpu_to_le32(0x9000401A), 1085 IO_REPARSE_TAG_CLOUD_5 = cpu_to_le32(0x9000501A), 1086 IO_REPARSE_TAG_CLOUD_6 = cpu_to_le32(0x9000601A), 1087 IO_REPARSE_TAG_CLOUD_7 = cpu_to_le32(0x9000701A), 1088 IO_REPARSE_TAG_CLOUD_8 = cpu_to_le32(0x9000801A), 1089 IO_REPARSE_TAG_CLOUD_9 = cpu_to_le32(0x9000901A), 1090 IO_REPARSE_TAG_CLOUD_A = cpu_to_le32(0x9000A01A), 1091 IO_REPARSE_TAG_CLOUD_B = cpu_to_le32(0x9000B01A), 1092 IO_REPARSE_TAG_CLOUD_C = cpu_to_le32(0x9000C01A), 1093 IO_REPARSE_TAG_CLOUD_D = cpu_to_le32(0x9000D01A), 1094 IO_REPARSE_TAG_CLOUD_E = cpu_to_le32(0x9000E01A), 1095 IO_REPARSE_TAG_CLOUD_F = cpu_to_le32(0x9000F01A), 1096 1097 }; 1098 1099 #define SYMLINK_FLAG_RELATIVE 1 1100 1101 /* Microsoft reparse buffer. (see DDK for details) */ 1102 struct REPARSE_DATA_BUFFER { 1103 __le32 ReparseTag; // 0x00: 1104 __le16 ReparseDataLength; // 0x04: 1105 __le16 Reserved; 1106 1107 union { 1108 /* If ReparseTag == 0xA0000003 (IO_REPARSE_TAG_MOUNT_POINT) */ 1109 struct { 1110 __le16 SubstituteNameOffset; // 0x08 1111 __le16 SubstituteNameLength; // 0x0A 1112 __le16 PrintNameOffset; // 0x0C 1113 __le16 PrintNameLength; // 0x0E 1114 __le16 PathBuffer[]; // 0x10 1115 } MountPointReparseBuffer; 1116 1117 /* 1118 * If ReparseTag == 0xA000000C (IO_REPARSE_TAG_SYMLINK) 1119 * https://msdn.microsoft.com/en-us/library/cc232006.aspx 1120 */ 1121 struct { 1122 __le16 SubstituteNameOffset; // 0x08 1123 __le16 SubstituteNameLength; // 0x0A 1124 __le16 PrintNameOffset; // 0x0C 1125 __le16 PrintNameLength; // 0x0E 1126 // 0-absolute path 1- relative path, SYMLINK_FLAG_RELATIVE 1127 __le32 Flags; // 0x10 1128 __le16 PathBuffer[]; // 0x14 1129 } SymbolicLinkReparseBuffer; 1130 1131 /* If ReparseTag == 0x80000017U */ 1132 struct { 1133 __le32 WofVersion; // 0x08 == 1 1134 /* 1135 * 1 - WIM backing provider ("WIMBoot"), 1136 * 2 - System compressed file provider 1137 */ 1138 __le32 WofProvider; // 0x0C: 1139 __le32 ProviderVer; // 0x10: == 1 WOF_FILE_PROVIDER_CURRENT_VERSION == 1 1140 __le32 CompressionFormat; // 0x14: 0, 1, 2, 3. See WOF_COMPRESSION_XXX 1141 } CompressReparseBuffer; 1142 1143 struct { 1144 u8 DataBuffer[1]; // 0x08: 1145 } GenericReparseBuffer; 1146 }; 1147 }; 1148 1149 /* ATTR_EA_INFO (0xD0) */ 1150 1151 #define FILE_NEED_EA 0x80 // See ntifs.h 1152 /* 1153 *FILE_NEED_EA, indicates that the file to which the EA belongs cannot be 1154 * interpreted without understanding the associated extended attributes. 1155 */ 1156 struct EA_INFO { 1157 __le16 size_pack; // 0x00: Size of buffer to hold in packed form. 1158 __le16 count; // 0x02: Count of EA's with FILE_NEED_EA bit set. 1159 __le32 size; // 0x04: Size of buffer to hold in unpacked form. 1160 }; 1161 1162 static_assert(sizeof(struct EA_INFO) == 8); 1163 1164 /* ATTR_EA (0xE0) */ 1165 struct EA_FULL { 1166 __le32 size; // 0x00: (not in packed) 1167 u8 flags; // 0x04: 1168 u8 name_len; // 0x05: 1169 __le16 elength; // 0x06: 1170 u8 name[]; // 0x08: 1171 }; 1172 1173 static_assert(offsetof(struct EA_FULL, name) == 8); 1174 1175 #define ACL_REVISION 2 1176 #define ACL_REVISION_DS 4 1177 1178 #define SE_SELF_RELATIVE cpu_to_le16(0x8000) 1179 1180 struct SECURITY_DESCRIPTOR_RELATIVE { 1181 u8 Revision; 1182 u8 Sbz1; 1183 __le16 Control; 1184 __le32 Owner; 1185 __le32 Group; 1186 __le32 Sacl; 1187 __le32 Dacl; 1188 }; 1189 static_assert(sizeof(struct SECURITY_DESCRIPTOR_RELATIVE) == 0x14); 1190 1191 struct ACE_HEADER { 1192 u8 AceType; 1193 u8 AceFlags; 1194 __le16 AceSize; 1195 }; 1196 static_assert(sizeof(struct ACE_HEADER) == 4); 1197 1198 struct ACL { 1199 u8 AclRevision; 1200 u8 Sbz1; 1201 __le16 AclSize; 1202 __le16 AceCount; 1203 __le16 Sbz2; 1204 }; 1205 static_assert(sizeof(struct ACL) == 8); 1206 1207 struct SID { 1208 u8 Revision; 1209 u8 SubAuthorityCount; 1210 u8 IdentifierAuthority[6]; 1211 __le32 SubAuthority[]; 1212 }; 1213 static_assert(offsetof(struct SID, SubAuthority) == 8); 1214 1215 #endif /* _LINUX_NTFS3_NTFS_H */ 1216 // clang-format on 1217