0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LINUX_NTFS3_NTFS_H
0011 #define _LINUX_NTFS3_NTFS_H
0012
0013 #include <linux/blkdev.h>
0014 #include <linux/build_bug.h>
0015 #include <linux/kernel.h>
0016 #include <linux/stddef.h>
0017 #include <linux/string.h>
0018 #include <linux/types.h>
0019
0020 #include "debug.h"
0021
0022
0023
0024
0025 #define NTFS3_CHECK_FREE_CLST
0026
0027 #define NTFS_NAME_LEN 255
0028
0029
0030
0031
0032
0033 #define NTFS_LINK_MAX 4000
0034
0035
0036
0037
0038
0039
0040
0041
0042 #define NTFS_LZNT_MAX_CLUSTER 4096
0043 #define NTFS_LZNT_CUNIT 4
0044 #define NTFS_LZNT_CLUSTERS (1u<<NTFS_LZNT_CUNIT)
0045
0046 struct GUID {
0047 __le32 Data1;
0048 __le16 Data2;
0049 __le16 Data3;
0050 u8 Data4[8];
0051 };
0052
0053
0054
0055
0056
0057
0058
0059 struct cpu_str {
0060 u8 len;
0061 u8 unused;
0062 u16 name[10];
0063 };
0064
0065 struct le_str {
0066 u8 len;
0067 u8 unused;
0068 __le16 name[];
0069 };
0070
0071 static_assert(SECTOR_SHIFT == 9);
0072
0073 #ifdef CONFIG_NTFS3_64BIT_CLUSTER
0074 typedef u64 CLST;
0075 static_assert(sizeof(size_t) == 8);
0076 #else
0077 typedef u32 CLST;
0078 #endif
0079
0080 #define SPARSE_LCN64 ((u64)-1)
0081 #define SPARSE_LCN ((CLST)-1)
0082 #define RESIDENT_LCN ((CLST)-2)
0083 #define COMPRESSED_LCN ((CLST)-3)
0084
0085 #define COMPRESSION_UNIT 4
0086 #define COMPRESS_MAX_CLUSTER 0x1000
0087 #define MFT_INCREASE_CHUNK 1024
0088
0089 enum RECORD_NUM {
0090 MFT_REC_MFT = 0,
0091 MFT_REC_MIRR = 1,
0092 MFT_REC_LOG = 2,
0093 MFT_REC_VOL = 3,
0094 MFT_REC_ATTR = 4,
0095 MFT_REC_ROOT = 5,
0096 MFT_REC_BITMAP = 6,
0097 MFT_REC_BOOT = 7,
0098 MFT_REC_BADCLUST = 8,
0099
0100 MFT_REC_SECURE = 9,
0101 MFT_REC_UPCASE = 10,
0102 MFT_REC_EXTEND = 11,
0103 MFT_REC_RESERVED = 11,
0104 MFT_REC_FREE = 16,
0105 MFT_REC_USER = 24,
0106 };
0107
0108 enum ATTR_TYPE {
0109 ATTR_ZERO = cpu_to_le32(0x00),
0110 ATTR_STD = cpu_to_le32(0x10),
0111 ATTR_LIST = cpu_to_le32(0x20),
0112 ATTR_NAME = cpu_to_le32(0x30),
0113
0114 ATTR_ID = cpu_to_le32(0x40),
0115 ATTR_SECURE = cpu_to_le32(0x50),
0116 ATTR_LABEL = cpu_to_le32(0x60),
0117 ATTR_VOL_INFO = cpu_to_le32(0x70),
0118 ATTR_DATA = cpu_to_le32(0x80),
0119 ATTR_ROOT = cpu_to_le32(0x90),
0120 ATTR_ALLOC = cpu_to_le32(0xA0),
0121 ATTR_BITMAP = cpu_to_le32(0xB0),
0122
0123 ATTR_REPARSE = cpu_to_le32(0xC0),
0124 ATTR_EA_INFO = cpu_to_le32(0xD0),
0125 ATTR_EA = cpu_to_le32(0xE0),
0126 ATTR_PROPERTYSET = cpu_to_le32(0xF0),
0127 ATTR_LOGGED_UTILITY_STREAM = cpu_to_le32(0x100),
0128 ATTR_END = cpu_to_le32(0xFFFFFFFF)
0129 };
0130
0131 static_assert(sizeof(enum ATTR_TYPE) == 4);
0132
0133 enum FILE_ATTRIBUTE {
0134 FILE_ATTRIBUTE_READONLY = cpu_to_le32(0x00000001),
0135 FILE_ATTRIBUTE_HIDDEN = cpu_to_le32(0x00000002),
0136 FILE_ATTRIBUTE_SYSTEM = cpu_to_le32(0x00000004),
0137 FILE_ATTRIBUTE_ARCHIVE = cpu_to_le32(0x00000020),
0138 FILE_ATTRIBUTE_DEVICE = cpu_to_le32(0x00000040),
0139 FILE_ATTRIBUTE_TEMPORARY = cpu_to_le32(0x00000100),
0140 FILE_ATTRIBUTE_SPARSE_FILE = cpu_to_le32(0x00000200),
0141 FILE_ATTRIBUTE_REPARSE_POINT = cpu_to_le32(0x00000400),
0142 FILE_ATTRIBUTE_COMPRESSED = cpu_to_le32(0x00000800),
0143 FILE_ATTRIBUTE_OFFLINE = cpu_to_le32(0x00001000),
0144 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = cpu_to_le32(0x00002000),
0145 FILE_ATTRIBUTE_ENCRYPTED = cpu_to_le32(0x00004000),
0146 FILE_ATTRIBUTE_VALID_FLAGS = cpu_to_le32(0x00007fb7),
0147 FILE_ATTRIBUTE_DIRECTORY = cpu_to_le32(0x10000000),
0148 };
0149
0150 static_assert(sizeof(enum FILE_ATTRIBUTE) == 4);
0151
0152 extern const struct cpu_str NAME_MFT;
0153 extern const struct cpu_str NAME_MIRROR;
0154 extern const struct cpu_str NAME_LOGFILE;
0155 extern const struct cpu_str NAME_VOLUME;
0156 extern const struct cpu_str NAME_ATTRDEF;
0157 extern const struct cpu_str NAME_ROOT;
0158 extern const struct cpu_str NAME_BITMAP;
0159 extern const struct cpu_str NAME_BOOT;
0160 extern const struct cpu_str NAME_BADCLUS;
0161 extern const struct cpu_str NAME_QUOTA;
0162 extern const struct cpu_str NAME_SECURE;
0163 extern const struct cpu_str NAME_UPCASE;
0164 extern const struct cpu_str NAME_EXTEND;
0165 extern const struct cpu_str NAME_OBJID;
0166 extern const struct cpu_str NAME_REPARSE;
0167 extern const struct cpu_str NAME_USNJRNL;
0168
0169 extern const __le16 I30_NAME[4];
0170 extern const __le16 SII_NAME[4];
0171 extern const __le16 SDH_NAME[4];
0172 extern const __le16 SO_NAME[2];
0173 extern const __le16 SQ_NAME[2];
0174 extern const __le16 SR_NAME[2];
0175
0176 extern const __le16 BAD_NAME[4];
0177 extern const __le16 SDS_NAME[4];
0178 extern const __le16 WOF_NAME[17];
0179
0180
0181 struct MFT_REF {
0182 __le32 low;
0183 __le16 high;
0184 __le16 seq;
0185 };
0186
0187 static_assert(sizeof(__le64) == sizeof(struct MFT_REF));
0188
0189 static inline CLST ino_get(const struct MFT_REF *ref)
0190 {
0191 #ifdef CONFIG_NTFS3_64BIT_CLUSTER
0192 return le32_to_cpu(ref->low) | ((u64)le16_to_cpu(ref->high) << 32);
0193 #else
0194 return le32_to_cpu(ref->low);
0195 #endif
0196 }
0197
0198 struct NTFS_BOOT {
0199 u8 jump_code[3];
0200 u8 system_id[8];
0201
0202
0203
0204
0205 u8 bytes_per_sector[2];
0206
0207 u8 sectors_per_clusters;
0208 u8 unused1[7];
0209 u8 media_type;
0210 u8 unused2[2];
0211 __le16 sct_per_track;
0212 __le16 heads;
0213 __le32 hidden_sectors;
0214 u8 unused3[4];
0215 u8 bios_drive_num;
0216 u8 unused4;
0217 u8 signature_ex;
0218 u8 unused5;
0219 __le64 sectors_per_volume;
0220 __le64 mft_clst;
0221 __le64 mft2_clst;
0222 s8 record_size;
0223 u8 unused6[3];
0224 s8 index_size;
0225 u8 unused7[3];
0226 __le64 serial_num;
0227 __le32 check_sum;
0228
0229
0230 u8 boot_code[0x200 - 0x50 - 2 - 4];
0231 u8 boot_magic[2];
0232 };
0233
0234 static_assert(sizeof(struct NTFS_BOOT) == 0x200);
0235
0236 enum NTFS_SIGNATURE {
0237 NTFS_FILE_SIGNATURE = cpu_to_le32(0x454C4946),
0238 NTFS_INDX_SIGNATURE = cpu_to_le32(0x58444E49),
0239 NTFS_CHKD_SIGNATURE = cpu_to_le32(0x444B4843),
0240 NTFS_RSTR_SIGNATURE = cpu_to_le32(0x52545352),
0241 NTFS_RCRD_SIGNATURE = cpu_to_le32(0x44524352),
0242 NTFS_BAAD_SIGNATURE = cpu_to_le32(0x44414142),
0243 NTFS_HOLE_SIGNATURE = cpu_to_le32(0x454C4F48),
0244 NTFS_FFFF_SIGNATURE = cpu_to_le32(0xffffffff),
0245 };
0246
0247 static_assert(sizeof(enum NTFS_SIGNATURE) == 4);
0248
0249
0250 struct NTFS_RECORD_HEADER {
0251
0252 enum NTFS_SIGNATURE sign;
0253 __le16 fix_off;
0254 __le16 fix_num;
0255 __le64 lsn;
0256 };
0257
0258 static_assert(sizeof(struct NTFS_RECORD_HEADER) == 0x10);
0259
0260 static inline int is_baad(const struct NTFS_RECORD_HEADER *hdr)
0261 {
0262 return hdr->sign == NTFS_BAAD_SIGNATURE;
0263 }
0264
0265
0266 enum RECORD_FLAG {
0267 RECORD_FLAG_IN_USE = cpu_to_le16(0x0001),
0268 RECORD_FLAG_DIR = cpu_to_le16(0x0002),
0269 RECORD_FLAG_SYSTEM = cpu_to_le16(0x0004),
0270 RECORD_FLAG_UNKNOWN = cpu_to_le16(0x0008),
0271 };
0272
0273
0274 struct MFT_REC {
0275 struct NTFS_RECORD_HEADER rhdr;
0276
0277 __le16 seq;
0278 __le16 hard_links;
0279 __le16 attr_off;
0280 __le16 flags;
0281 __le32 used;
0282 __le32 total;
0283
0284 struct MFT_REF parent_ref;
0285 __le16 next_attr_id;
0286
0287 __le16 res;
0288 __le32 mft_record;
0289 __le16 fixups[];
0290 };
0291
0292 #define MFTRECORD_FIXUP_OFFSET_1 offsetof(struct MFT_REC, res)
0293 #define MFTRECORD_FIXUP_OFFSET_3 offsetof(struct MFT_REC, fixups)
0294
0295 static_assert(MFTRECORD_FIXUP_OFFSET_1 == 0x2A);
0296 static_assert(MFTRECORD_FIXUP_OFFSET_3 == 0x30);
0297
0298 static inline bool is_rec_base(const struct MFT_REC *rec)
0299 {
0300 const struct MFT_REF *r = &rec->parent_ref;
0301
0302 return !r->low && !r->high && !r->seq;
0303 }
0304
0305 static inline bool is_mft_rec5(const struct MFT_REC *rec)
0306 {
0307 return le16_to_cpu(rec->rhdr.fix_off) >=
0308 offsetof(struct MFT_REC, fixups);
0309 }
0310
0311 static inline bool is_rec_inuse(const struct MFT_REC *rec)
0312 {
0313 return rec->flags & RECORD_FLAG_IN_USE;
0314 }
0315
0316 static inline bool clear_rec_inuse(struct MFT_REC *rec)
0317 {
0318 return rec->flags &= ~RECORD_FLAG_IN_USE;
0319 }
0320
0321
0322 #define RESIDENT_FLAG_INDEXED 0x01
0323
0324 struct ATTR_RESIDENT {
0325 __le32 data_size;
0326 __le16 data_off;
0327 u8 flags;
0328 u8 res;
0329 };
0330
0331 struct ATTR_NONRESIDENT {
0332 __le64 svcn;
0333 __le64 evcn;
0334 __le16 run_off;
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347 u8 c_unit;
0348 u8 res1[5];
0349 __le64 alloc_size;
0350
0351 __le64 data_size;
0352 __le64 valid_size;
0353 __le64 total_size;
0354
0355
0356
0357 };
0358
0359
0360 #define ATTR_FLAG_COMPRESSED cpu_to_le16(0x0001)
0361 #define ATTR_FLAG_COMPRESSED_MASK cpu_to_le16(0x00FF)
0362 #define ATTR_FLAG_ENCRYPTED cpu_to_le16(0x4000)
0363 #define ATTR_FLAG_SPARSED cpu_to_le16(0x8000)
0364
0365 struct ATTRIB {
0366 enum ATTR_TYPE type;
0367 __le32 size;
0368 u8 non_res;
0369 u8 name_len;
0370 __le16 name_off;
0371 __le16 flags;
0372 __le16 id;
0373
0374 union {
0375 struct ATTR_RESIDENT res;
0376 struct ATTR_NONRESIDENT nres;
0377 };
0378 };
0379
0380
0381 #define SIZEOF_RESIDENT 0x18
0382 #define SIZEOF_NONRESIDENT_EX 0x48
0383 #define SIZEOF_NONRESIDENT 0x40
0384
0385 #define SIZEOF_RESIDENT_LE cpu_to_le16(0x18)
0386 #define SIZEOF_NONRESIDENT_EX_LE cpu_to_le16(0x48)
0387 #define SIZEOF_NONRESIDENT_LE cpu_to_le16(0x40)
0388
0389 static inline u64 attr_ondisk_size(const struct ATTRIB *attr)
0390 {
0391 return attr->non_res ? ((attr->flags &
0392 (ATTR_FLAG_COMPRESSED | ATTR_FLAG_SPARSED)) ?
0393 le64_to_cpu(attr->nres.total_size) :
0394 le64_to_cpu(attr->nres.alloc_size))
0395 : ALIGN(le32_to_cpu(attr->res.data_size), 8);
0396 }
0397
0398 static inline u64 attr_size(const struct ATTRIB *attr)
0399 {
0400 return attr->non_res ? le64_to_cpu(attr->nres.data_size) :
0401 le32_to_cpu(attr->res.data_size);
0402 }
0403
0404 static inline bool is_attr_encrypted(const struct ATTRIB *attr)
0405 {
0406 return attr->flags & ATTR_FLAG_ENCRYPTED;
0407 }
0408
0409 static inline bool is_attr_sparsed(const struct ATTRIB *attr)
0410 {
0411 return attr->flags & ATTR_FLAG_SPARSED;
0412 }
0413
0414 static inline bool is_attr_compressed(const struct ATTRIB *attr)
0415 {
0416 return attr->flags & ATTR_FLAG_COMPRESSED;
0417 }
0418
0419 static inline bool is_attr_ext(const struct ATTRIB *attr)
0420 {
0421 return attr->flags & (ATTR_FLAG_SPARSED | ATTR_FLAG_COMPRESSED);
0422 }
0423
0424 static inline bool is_attr_indexed(const struct ATTRIB *attr)
0425 {
0426 return !attr->non_res && (attr->res.flags & RESIDENT_FLAG_INDEXED);
0427 }
0428
0429 static inline __le16 const *attr_name(const struct ATTRIB *attr)
0430 {
0431 return Add2Ptr(attr, le16_to_cpu(attr->name_off));
0432 }
0433
0434 static inline u64 attr_svcn(const struct ATTRIB *attr)
0435 {
0436 return attr->non_res ? le64_to_cpu(attr->nres.svcn) : 0;
0437 }
0438
0439
0440 #define BYTES_PER_RESIDENT(b) (0x18 + (b))
0441
0442 static_assert(sizeof(struct ATTRIB) == 0x48);
0443 static_assert(sizeof(((struct ATTRIB *)NULL)->res) == 0x08);
0444 static_assert(sizeof(((struct ATTRIB *)NULL)->nres) == 0x38);
0445
0446 static inline void *resident_data_ex(const struct ATTRIB *attr, u32 datasize)
0447 {
0448 u32 asize, rsize;
0449 u16 off;
0450
0451 if (attr->non_res)
0452 return NULL;
0453
0454 asize = le32_to_cpu(attr->size);
0455 off = le16_to_cpu(attr->res.data_off);
0456
0457 if (asize < datasize + off)
0458 return NULL;
0459
0460 rsize = le32_to_cpu(attr->res.data_size);
0461 if (rsize < datasize)
0462 return NULL;
0463
0464 return Add2Ptr(attr, off);
0465 }
0466
0467 static inline void *resident_data(const struct ATTRIB *attr)
0468 {
0469 return Add2Ptr(attr, le16_to_cpu(attr->res.data_off));
0470 }
0471
0472 static inline void *attr_run(const struct ATTRIB *attr)
0473 {
0474 return Add2Ptr(attr, le16_to_cpu(attr->nres.run_off));
0475 }
0476
0477
0478 struct ATTR_STD_INFO {
0479 __le64 cr_time;
0480 __le64 m_time;
0481 __le64 c_time;
0482 __le64 a_time;
0483 enum FILE_ATTRIBUTE fa;
0484 __le32 max_ver_num;
0485 __le32 ver_num;
0486 __le32 class_id;
0487 };
0488
0489 static_assert(sizeof(struct ATTR_STD_INFO) == 0x30);
0490
0491 #define SECURITY_ID_INVALID 0x00000000
0492 #define SECURITY_ID_FIRST 0x00000100
0493
0494 struct ATTR_STD_INFO5 {
0495 __le64 cr_time;
0496 __le64 m_time;
0497 __le64 c_time;
0498 __le64 a_time;
0499 enum FILE_ATTRIBUTE fa;
0500 __le32 max_ver_num;
0501 __le32 ver_num;
0502 __le32 class_id;
0503
0504 __le32 owner_id;
0505 __le32 security_id;
0506 __le64 quota_charge;
0507 __le64 usn;
0508
0509
0510 };
0511
0512 static_assert(sizeof(struct ATTR_STD_INFO5) == 0x48);
0513
0514
0515 struct ATTR_LIST_ENTRY {
0516 enum ATTR_TYPE type;
0517 __le16 size;
0518 u8 name_len;
0519 u8 name_off;
0520 __le64 vcn;
0521 struct MFT_REF ref;
0522 __le16 id;
0523 __le16 name[3];
0524
0525 };
0526
0527 static_assert(sizeof(struct ATTR_LIST_ENTRY) == 0x20);
0528
0529 static inline u32 le_size(u8 name_len)
0530 {
0531 return ALIGN(offsetof(struct ATTR_LIST_ENTRY, name) +
0532 name_len * sizeof(short), 8);
0533 }
0534
0535
0536 static inline int le_cmp(const struct ATTR_LIST_ENTRY *le,
0537 const struct ATTRIB *attr)
0538 {
0539 return le->type != attr->type || le->name_len != attr->name_len ||
0540 (!le->name_len &&
0541 memcmp(Add2Ptr(le, le->name_off),
0542 Add2Ptr(attr, le16_to_cpu(attr->name_off)),
0543 le->name_len * sizeof(short)));
0544 }
0545
0546 static inline __le16 const *le_name(const struct ATTR_LIST_ENTRY *le)
0547 {
0548 return Add2Ptr(le, le->name_off);
0549 }
0550
0551
0552 #define FILE_NAME_POSIX 0
0553 #define FILE_NAME_UNICODE 1
0554 #define FILE_NAME_DOS 2
0555 #define FILE_NAME_UNICODE_AND_DOS (FILE_NAME_DOS | FILE_NAME_UNICODE)
0556
0557
0558 struct NTFS_DUP_INFO {
0559 __le64 cr_time;
0560 __le64 m_time;
0561 __le64 c_time;
0562 __le64 a_time;
0563 __le64 alloc_size;
0564 __le64 data_size;
0565 enum FILE_ATTRIBUTE fa;
0566 __le16 ea_size;
0567 __le16 reparse;
0568
0569 };
0570
0571 struct ATTR_FILE_NAME {
0572 struct MFT_REF home;
0573 struct NTFS_DUP_INFO dup;
0574 u8 name_len;
0575 u8 type;
0576 __le16 name[];
0577 };
0578
0579 static_assert(sizeof(((struct ATTR_FILE_NAME *)NULL)->dup) == 0x38);
0580 static_assert(offsetof(struct ATTR_FILE_NAME, name) == 0x42);
0581 #define SIZEOF_ATTRIBUTE_FILENAME 0x44
0582 #define SIZEOF_ATTRIBUTE_FILENAME_MAX (0x42 + 255 * 2)
0583
0584 static inline struct ATTRIB *attr_from_name(struct ATTR_FILE_NAME *fname)
0585 {
0586 return (struct ATTRIB *)((char *)fname - SIZEOF_RESIDENT);
0587 }
0588
0589 static inline u16 fname_full_size(const struct ATTR_FILE_NAME *fname)
0590 {
0591
0592 return offsetof(struct ATTR_FILE_NAME, name) +
0593 fname->name_len * sizeof(short);
0594 }
0595
0596 static inline u8 paired_name(u8 type)
0597 {
0598 if (type == FILE_NAME_UNICODE)
0599 return FILE_NAME_DOS;
0600 if (type == FILE_NAME_DOS)
0601 return FILE_NAME_UNICODE;
0602 return FILE_NAME_POSIX;
0603 }
0604
0605
0606 #define NTFS_IE_HAS_SUBNODES cpu_to_le16(1)
0607 #define NTFS_IE_LAST cpu_to_le16(2)
0608
0609
0610 struct NTFS_DE {
0611 union {
0612 struct MFT_REF ref;
0613 struct {
0614 __le16 data_off;
0615 __le16 data_size;
0616 __le32 res;
0617 } view;
0618 };
0619 __le16 size;
0620 __le16 key_size;
0621 __le16 flags;
0622 __le16 res;
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634 };
0635
0636 static_assert(sizeof(struct NTFS_DE) == 0x10);
0637
0638 static inline void de_set_vbn_le(struct NTFS_DE *e, __le64 vcn)
0639 {
0640 __le64 *v = Add2Ptr(e, le16_to_cpu(e->size) - sizeof(__le64));
0641
0642 *v = vcn;
0643 }
0644
0645 static inline void de_set_vbn(struct NTFS_DE *e, CLST vcn)
0646 {
0647 __le64 *v = Add2Ptr(e, le16_to_cpu(e->size) - sizeof(__le64));
0648
0649 *v = cpu_to_le64(vcn);
0650 }
0651
0652 static inline __le64 de_get_vbn_le(const struct NTFS_DE *e)
0653 {
0654 return *(__le64 *)Add2Ptr(e, le16_to_cpu(e->size) - sizeof(__le64));
0655 }
0656
0657 static inline CLST de_get_vbn(const struct NTFS_DE *e)
0658 {
0659 __le64 *v = Add2Ptr(e, le16_to_cpu(e->size) - sizeof(__le64));
0660
0661 return le64_to_cpu(*v);
0662 }
0663
0664 static inline struct NTFS_DE *de_get_next(const struct NTFS_DE *e)
0665 {
0666 return Add2Ptr(e, le16_to_cpu(e->size));
0667 }
0668
0669 static inline struct ATTR_FILE_NAME *de_get_fname(const struct NTFS_DE *e)
0670 {
0671 return le16_to_cpu(e->key_size) >= SIZEOF_ATTRIBUTE_FILENAME ?
0672 Add2Ptr(e, sizeof(struct NTFS_DE)) :
0673 NULL;
0674 }
0675
0676 static inline bool de_is_last(const struct NTFS_DE *e)
0677 {
0678 return e->flags & NTFS_IE_LAST;
0679 }
0680
0681 static inline bool de_has_vcn(const struct NTFS_DE *e)
0682 {
0683 return e->flags & NTFS_IE_HAS_SUBNODES;
0684 }
0685
0686 static inline bool de_has_vcn_ex(const struct NTFS_DE *e)
0687 {
0688 return (e->flags & NTFS_IE_HAS_SUBNODES) &&
0689 (u64)(-1) != *((u64 *)Add2Ptr(e, le16_to_cpu(e->size) -
0690 sizeof(__le64)));
0691 }
0692
0693 #define MAX_BYTES_PER_NAME_ENTRY \
0694 ALIGN(sizeof(struct NTFS_DE) + \
0695 offsetof(struct ATTR_FILE_NAME, name) + \
0696 NTFS_NAME_LEN * sizeof(short), 8)
0697
0698 struct INDEX_HDR {
0699 __le32 de_off;
0700
0701 __le32 used;
0702
0703 __le32 total;
0704 u8 flags;
0705 u8 res[3];
0706
0707
0708
0709
0710 };
0711
0712 static_assert(sizeof(struct INDEX_HDR) == 0x10);
0713
0714 static inline struct NTFS_DE *hdr_first_de(const struct INDEX_HDR *hdr)
0715 {
0716 u32 de_off = le32_to_cpu(hdr->de_off);
0717 u32 used = le32_to_cpu(hdr->used);
0718 struct NTFS_DE *e = Add2Ptr(hdr, de_off);
0719 u16 esize;
0720
0721 if (de_off >= used || de_off >= le32_to_cpu(hdr->total))
0722 return NULL;
0723
0724 esize = le16_to_cpu(e->size);
0725 if (esize < sizeof(struct NTFS_DE) || de_off + esize > used)
0726 return NULL;
0727
0728 return e;
0729 }
0730
0731 static inline struct NTFS_DE *hdr_next_de(const struct INDEX_HDR *hdr,
0732 const struct NTFS_DE *e)
0733 {
0734 size_t off = PtrOffset(hdr, e);
0735 u32 used = le32_to_cpu(hdr->used);
0736 u16 esize;
0737
0738 if (off >= used)
0739 return NULL;
0740
0741 esize = le16_to_cpu(e->size);
0742
0743 if (esize < sizeof(struct NTFS_DE) ||
0744 off + esize + sizeof(struct NTFS_DE) > used)
0745 return NULL;
0746
0747 return Add2Ptr(e, esize);
0748 }
0749
0750 static inline bool hdr_has_subnode(const struct INDEX_HDR *hdr)
0751 {
0752 return hdr->flags & 1;
0753 }
0754
0755 struct INDEX_BUFFER {
0756 struct NTFS_RECORD_HEADER rhdr;
0757 __le64 vbn;
0758 struct INDEX_HDR ihdr;
0759 };
0760
0761 static_assert(sizeof(struct INDEX_BUFFER) == 0x28);
0762
0763 static inline bool ib_is_empty(const struct INDEX_BUFFER *ib)
0764 {
0765 const struct NTFS_DE *first = hdr_first_de(&ib->ihdr);
0766
0767 return !first || de_is_last(first);
0768 }
0769
0770 static inline bool ib_is_leaf(const struct INDEX_BUFFER *ib)
0771 {
0772 return !(ib->ihdr.flags & 1);
0773 }
0774
0775
0776 enum COLLATION_RULE {
0777 NTFS_COLLATION_TYPE_BINARY = cpu_to_le32(0),
0778
0779 NTFS_COLLATION_TYPE_FILENAME = cpu_to_le32(0x01),
0780
0781 NTFS_COLLATION_TYPE_UINT = cpu_to_le32(0x10),
0782
0783 NTFS_COLLATION_TYPE_SID = cpu_to_le32(0x11),
0784
0785 NTFS_COLLATION_TYPE_SECURITY_HASH = cpu_to_le32(0x12),
0786
0787 NTFS_COLLATION_TYPE_UINTS = cpu_to_le32(0x13)
0788 };
0789
0790 static_assert(sizeof(enum COLLATION_RULE) == 4);
0791
0792
0793 struct INDEX_ROOT {
0794 enum ATTR_TYPE type;
0795 enum COLLATION_RULE rule;
0796 __le32 index_block_size;
0797 u8 index_block_clst;
0798 u8 res[3];
0799 struct INDEX_HDR ihdr;
0800 };
0801
0802 static_assert(sizeof(struct INDEX_ROOT) == 0x20);
0803 static_assert(offsetof(struct INDEX_ROOT, ihdr) == 0x10);
0804
0805 #define VOLUME_FLAG_DIRTY cpu_to_le16(0x0001)
0806 #define VOLUME_FLAG_RESIZE_LOG_FILE cpu_to_le16(0x0002)
0807
0808 struct VOLUME_INFO {
0809 __le64 res1;
0810 u8 major_ver;
0811 u8 minor_ver;
0812 __le16 flags;
0813
0814 };
0815
0816 #define SIZEOF_ATTRIBUTE_VOLUME_INFO 0xc
0817
0818 #define NTFS_LABEL_MAX_LENGTH (0x100 / sizeof(short))
0819 #define NTFS_ATTR_INDEXABLE cpu_to_le32(0x00000002)
0820 #define NTFS_ATTR_DUPALLOWED cpu_to_le32(0x00000004)
0821 #define NTFS_ATTR_MUST_BE_INDEXED cpu_to_le32(0x00000010)
0822 #define NTFS_ATTR_MUST_BE_NAMED cpu_to_le32(0x00000020)
0823 #define NTFS_ATTR_MUST_BE_RESIDENT cpu_to_le32(0x00000040)
0824 #define NTFS_ATTR_LOG_ALWAYS cpu_to_le32(0x00000080)
0825
0826
0827 struct ATTR_DEF_ENTRY {
0828 __le16 name[0x40];
0829 enum ATTR_TYPE type;
0830 __le32 res;
0831 enum COLLATION_RULE rule;
0832 __le32 flags;
0833 __le64 min_sz;
0834 __le64 max_sz;
0835 };
0836
0837 static_assert(sizeof(struct ATTR_DEF_ENTRY) == 0xa0);
0838
0839
0840 struct OBJECT_ID {
0841 struct GUID ObjId;
0842 struct GUID BirthVolumeId;
0843
0844 struct GUID BirthObjectId;
0845
0846
0847
0848 struct GUID DomainId;
0849
0850
0851
0852 };
0853
0854 static_assert(sizeof(struct OBJECT_ID) == 0x40);
0855
0856
0857 struct NTFS_DE_O {
0858 struct NTFS_DE de;
0859 struct GUID ObjId;
0860 struct MFT_REF ref;
0861 struct GUID BirthVolumeId;
0862
0863 struct GUID BirthObjectId;
0864
0865
0866
0867
0868 struct GUID BirthDomainId;
0869
0870
0871
0872 };
0873
0874 static_assert(sizeof(struct NTFS_DE_O) == 0x58);
0875
0876 #define NTFS_OBJECT_ENTRY_DATA_SIZE1 \
0877 0x38
0878 #define NTFS_OBJECT_ENTRY_DATA_SIZE2 \
0879 0x48
0880
0881
0882 struct NTFS_DE_Q {
0883 struct NTFS_DE de;
0884 __le32 owner_id;
0885 __le32 Version;
0886 __le32 flags2;
0887 __le64 BytesUsed;
0888 __le64 ChangeTime;
0889 __le64 WarningLimit;
0890 __le64 HardLimit;
0891 __le64 ExceededTime;
0892
0893
0894 };
0895
0896 #define SIZEOF_NTFS_DE_Q 0x44
0897
0898 #define SecurityDescriptorsBlockSize 0x40000
0899 #define SecurityDescriptorMaxSize 0x20000
0900 #define Log2OfSecurityDescriptorsBlockSize 18
0901
0902 struct SECURITY_KEY {
0903 __le32 hash;
0904 __le32 sec_id;
0905 };
0906
0907
0908 struct SECURITY_HDR {
0909 struct SECURITY_KEY key;
0910 __le64 off;
0911 __le32 size;
0912
0913
0914
0915
0916 } __packed;
0917
0918 #define SIZEOF_SECURITY_HDR 0x14
0919
0920
0921 struct NTFS_DE_SII {
0922 struct NTFS_DE de;
0923 __le32 sec_id;
0924 struct SECURITY_HDR sec_hdr;
0925 } __packed;
0926
0927 #define SIZEOF_SII_DIRENTRY 0x28
0928
0929
0930 struct NTFS_DE_SDH {
0931 struct NTFS_DE de;
0932 struct SECURITY_KEY key;
0933 struct SECURITY_HDR sec_hdr;
0934 __le16 magic[2];
0935 };
0936
0937 #define SIZEOF_SDH_DIRENTRY 0x30
0938
0939 struct REPARSE_KEY {
0940 __le32 ReparseTag;
0941 struct MFT_REF ref;
0942 };
0943
0944 static_assert(offsetof(struct REPARSE_KEY, ref) == 0x04);
0945 #define SIZEOF_REPARSE_KEY 0x0C
0946
0947
0948 struct NTFS_DE_R {
0949 struct NTFS_DE de;
0950 struct REPARSE_KEY key;
0951 u32 zero;
0952 };
0953
0954 static_assert(sizeof(struct NTFS_DE_R) == 0x20);
0955
0956
0957 #define WOF_CURRENT_VERSION cpu_to_le32(1)
0958
0959 #define WOF_PROVIDER_WIM cpu_to_le32(1)
0960
0961 #define WOF_PROVIDER_SYSTEM cpu_to_le32(2)
0962
0963 #define WOF_PROVIDER_CURRENT_VERSION cpu_to_le32(1)
0964
0965 #define WOF_COMPRESSION_XPRESS4K cpu_to_le32(0)
0966 #define WOF_COMPRESSION_LZX32K cpu_to_le32(1)
0967 #define WOF_COMPRESSION_XPRESS8K cpu_to_le32(2)
0968 #define WOF_COMPRESSION_XPRESS16K cpu_to_le32(3)
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979 struct REPARSE_POINT {
0980 __le32 ReparseTag;
0981 __le16 ReparseDataLength;
0982 __le16 Reserved;
0983
0984 struct GUID Guid;
0985
0986
0987
0988
0989 };
0990
0991 static_assert(sizeof(struct REPARSE_POINT) == 0x18);
0992
0993
0994 #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 * 1024)
0995
0996
0997
0998
0999
1000
1001
1002 #define IO_REPARSE_TAG_RESERVED_RANGE 1
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 #define IsReparseTagMicrosoft(_tag) (((_tag)&IO_REPARSE_TAG_MICROSOFT))
1032
1033
1034 #define IsReparseTagNameSurrogate(_tag) (((_tag)&IO_REPARSE_TAG_NAME_SURROGATE))
1035
1036
1037
1038
1039
1040 #define IO_REPARSE_TAG_VALID_VALUES 0xF000FFFF
1041
1042
1043
1044
1045 #define IsReparseTagValid(_tag) \
1046 (!((_tag) & ~IO_REPARSE_TAG_VALID_VALUES) && \
1047 ((_tag) > IO_REPARSE_TAG_RESERVED_RANGE))
1048
1049
1050
1051 enum IO_REPARSE_TAG {
1052 IO_REPARSE_TAG_SYMBOLIC_LINK = cpu_to_le32(0),
1053 IO_REPARSE_TAG_NAME_SURROGATE = cpu_to_le32(0x20000000),
1054 IO_REPARSE_TAG_MICROSOFT = cpu_to_le32(0x80000000),
1055 IO_REPARSE_TAG_MOUNT_POINT = cpu_to_le32(0xA0000003),
1056 IO_REPARSE_TAG_SYMLINK = cpu_to_le32(0xA000000C),
1057 IO_REPARSE_TAG_HSM = cpu_to_le32(0xC0000004),
1058 IO_REPARSE_TAG_SIS = cpu_to_le32(0x80000007),
1059 IO_REPARSE_TAG_DEDUP = cpu_to_le32(0x80000013),
1060 IO_REPARSE_TAG_COMPRESS = cpu_to_le32(0x80000017),
1061
1062
1063
1064
1065
1066
1067
1068 IO_REPARSE_TAG_DFS = cpu_to_le32(0x8000000A),
1069
1070
1071 IO_REPARSE_TAG_FILTER_MANAGER = cpu_to_le32(0x8000000B),
1072
1073
1074
1075
1076 IO_REPARSE_TAG_IFSTEST_CONGRUENT = cpu_to_le32(0x00000009),
1077
1078
1079 IO_REPARSE_TAG_ARKIVIO = cpu_to_le32(0x0000000C),
1080
1081
1082 IO_REPARSE_TAG_SOLUTIONSOFT = cpu_to_le32(0x2000000D),
1083
1084
1085 IO_REPARSE_TAG_COMMVAULT = cpu_to_le32(0x0000000E),
1086
1087
1088 IO_REPARSE_TAG_CLOUD = cpu_to_le32(0x9000001A),
1089 IO_REPARSE_TAG_CLOUD_1 = cpu_to_le32(0x9000101A),
1090 IO_REPARSE_TAG_CLOUD_2 = cpu_to_le32(0x9000201A),
1091 IO_REPARSE_TAG_CLOUD_3 = cpu_to_le32(0x9000301A),
1092 IO_REPARSE_TAG_CLOUD_4 = cpu_to_le32(0x9000401A),
1093 IO_REPARSE_TAG_CLOUD_5 = cpu_to_le32(0x9000501A),
1094 IO_REPARSE_TAG_CLOUD_6 = cpu_to_le32(0x9000601A),
1095 IO_REPARSE_TAG_CLOUD_7 = cpu_to_le32(0x9000701A),
1096 IO_REPARSE_TAG_CLOUD_8 = cpu_to_le32(0x9000801A),
1097 IO_REPARSE_TAG_CLOUD_9 = cpu_to_le32(0x9000901A),
1098 IO_REPARSE_TAG_CLOUD_A = cpu_to_le32(0x9000A01A),
1099 IO_REPARSE_TAG_CLOUD_B = cpu_to_le32(0x9000B01A),
1100 IO_REPARSE_TAG_CLOUD_C = cpu_to_le32(0x9000C01A),
1101 IO_REPARSE_TAG_CLOUD_D = cpu_to_le32(0x9000D01A),
1102 IO_REPARSE_TAG_CLOUD_E = cpu_to_le32(0x9000E01A),
1103 IO_REPARSE_TAG_CLOUD_F = cpu_to_le32(0x9000F01A),
1104
1105 };
1106
1107 #define SYMLINK_FLAG_RELATIVE 1
1108
1109
1110 struct REPARSE_DATA_BUFFER {
1111 __le32 ReparseTag;
1112 __le16 ReparseDataLength;
1113 __le16 Reserved;
1114
1115 union {
1116
1117 struct {
1118 __le16 SubstituteNameOffset;
1119 __le16 SubstituteNameLength;
1120 __le16 PrintNameOffset;
1121 __le16 PrintNameLength;
1122 __le16 PathBuffer[];
1123 } MountPointReparseBuffer;
1124
1125
1126
1127
1128
1129 struct {
1130 __le16 SubstituteNameOffset;
1131 __le16 SubstituteNameLength;
1132 __le16 PrintNameOffset;
1133 __le16 PrintNameLength;
1134
1135 __le32 Flags;
1136 __le16 PathBuffer[];
1137 } SymbolicLinkReparseBuffer;
1138
1139
1140 struct {
1141 __le32 WofVersion;
1142
1143
1144
1145
1146 __le32 WofProvider;
1147 __le32 ProviderVer;
1148 __le32 CompressionFormat;
1149 } CompressReparseBuffer;
1150
1151 struct {
1152 u8 DataBuffer[1];
1153 } GenericReparseBuffer;
1154 };
1155 };
1156
1157
1158
1159 #define FILE_NEED_EA 0x80
1160
1161
1162
1163
1164 struct EA_INFO {
1165 __le16 size_pack;
1166 __le16 count;
1167 __le32 size;
1168 };
1169
1170 static_assert(sizeof(struct EA_INFO) == 8);
1171
1172
1173 struct EA_FULL {
1174 __le32 size;
1175 u8 flags;
1176 u8 name_len;
1177 __le16 elength;
1178 u8 name[];
1179 };
1180
1181 static_assert(offsetof(struct EA_FULL, name) == 8);
1182
1183 #define ACL_REVISION 2
1184 #define ACL_REVISION_DS 4
1185
1186 #define SE_SELF_RELATIVE cpu_to_le16(0x8000)
1187
1188 struct SECURITY_DESCRIPTOR_RELATIVE {
1189 u8 Revision;
1190 u8 Sbz1;
1191 __le16 Control;
1192 __le32 Owner;
1193 __le32 Group;
1194 __le32 Sacl;
1195 __le32 Dacl;
1196 };
1197 static_assert(sizeof(struct SECURITY_DESCRIPTOR_RELATIVE) == 0x14);
1198
1199 struct ACE_HEADER {
1200 u8 AceType;
1201 u8 AceFlags;
1202 __le16 AceSize;
1203 };
1204 static_assert(sizeof(struct ACE_HEADER) == 4);
1205
1206 struct ACL {
1207 u8 AclRevision;
1208 u8 Sbz1;
1209 __le16 AclSize;
1210 __le16 AceCount;
1211 __le16 Sbz2;
1212 };
1213 static_assert(sizeof(struct ACL) == 8);
1214
1215 struct SID {
1216 u8 Revision;
1217 u8 SubAuthorityCount;
1218 u8 IdentifierAuthority[6];
1219 __le32 SubAuthority[];
1220 };
1221 static_assert(offsetof(struct SID, SubAuthority) == 8);
1222
1223 #endif
1224