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