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