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