ntfs: use a runlist for handling multiple data runs
[profile/ivi/syslinux.git] / core / fs / ntfs / ntfs.h
1 /*
2  * Copyright (C) Paulo Alcantara <pcacjr@gmail.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc.,
17  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #ifndef _NTFS_H_
21 #define _NTFS_H_
22
23 struct ntfs_bpb {
24     uint8_t jmp_boot[3];
25     char oem_name[8];
26     uint16_t sector_size;
27     uint8_t sec_per_clust;
28     uint16_t res_sectors;
29     uint8_t zero_0[3];
30     uint16_t zero_1;
31     uint8_t media;
32     uint16_t zero_2;
33     uint16_t unused_0;
34     uint16_t unused_1;
35     uint32_t unused_2;
36     uint32_t zero_3;
37     uint32_t unused_3;
38     uint64_t total_sectors;
39     uint64_t mft_lclust;
40     uint64_t mft_mirr_lclust;
41     int8_t clust_per_mft_record;
42     uint8_t unused_4[3];
43     uint8_t clust_per_idx_record;
44     uint8_t unused_5[3];
45     uint64_t vol_serial;
46     uint32_t unused_6;
47
48     uint8_t pad[428];       /* padding to a sector boundary (512 bytes) */
49 } __attribute__((__packed__));
50
51 struct ntfs_sb_info {
52     block_t mft_blk;                /* The first MFT record block */
53     uint64_t mft_lcn;               /* LCN of the first MFT record */
54     unsigned mft_size;              /* The MFT size in sectors */
55     uint64_t mft_record_size;       /* MFT record size in bytes */
56
57     uint8_t clust_per_idx_record;   /* Clusters per Index Record */
58
59     unsigned long long clusters;    /* Total number of clusters */
60
61     unsigned clust_shift;           /* Based on sectors */
62     unsigned clust_byte_shift;      /* Based on bytes */
63     unsigned clust_mask;
64     unsigned clust_size;
65
66 } __attribute__((__packed__));
67
68 /* The NTFS in-memory inode structure */
69 struct ntfs_inode {
70     int64_t initialized_size;
71     int64_t allocated_size;
72     unsigned long mft_no;       /* Number of the mft record / inode */
73     uint16_t seq_no;            /* Sequence number of the mft record */
74     uint32_t type;              /* Attribute type of this inode */
75     uint8_t non_resident;
76     bool in_idx_root;
77     uint32_t idx_blks_count;
78     uint32_t entries_count;
79     int64_t last_vcn;
80     union {                 /* Non-resident $DATA attribute */
81         struct {            /* Used only if non_resident flags isn't set */
82             uint32_t offset;    /* Data offset */
83         } resident;
84         struct {            /* Used only if non_resident is set */
85             struct runlist *rlist;
86         } non_resident;
87     } data;
88     union {
89         struct {    /* It is a directory, $MFT, or an index inode */
90             uint32_t blk_size;
91             uint32_t vcn_size;
92             uint32_t collation_rule;
93             uint8_t blk_size_shift;     /* log2 of the above */
94             uint8_t vcn_size_shift;     /* log2 of the above */
95         } index;
96     } itype;
97     uint32_t start_cluster; /* Starting cluster address */
98     sector_t start;         /* Starting sector */
99     sector_t offset;        /* Current sector offset */
100     sector_t here;          /* Sector corresponding to offset */
101 };
102
103 enum {
104     MAP_UNSPEC,
105     MAP_START           = 1 << 0,
106     MAP_END             = 1 << 1,
107     MAP_ALLOCATED       = 1 << 2,
108     MAP_UNALLOCATED     = 1 << 3,
109     MAP_MASK            = 0x0000000F,
110 };
111
112 struct mapping_chunk {
113     uint64_t vcn;
114     int64_t lcn;
115     uint64_t len;
116     uint32_t flags;
117 };
118
119 /* System defined attributes (32-bit)
120  * Each attribute type has a corresponding attribute name (in Unicode)
121  */
122 enum {
123     NTFS_AT_UNUSED                      = 0x00,
124     NTFS_AT_STANDARD_INFORMATION        = 0x10,
125     NTFS_AT_ATTR_LIST                   = 0x20,
126     NTFS_AT_FILENAME                    = 0x30,
127     NTFS_AT_OBJ_ID                      = 0x40,
128     NTFS_AT_SECURITY_DESCP              = 0x50,
129     NTFS_AT_VOL_NAME                    = 0x60,
130     NTFS_AT_VOL_INFO                    = 0x70,
131     NTFS_AT_DATA                        = 0x80,
132     NTFS_AT_INDEX_ROOT                  = 0x90,
133     NTFS_AT_INDEX_ALLOCATION            = 0xA0,
134     NTFS_AT_BITMAP                      = 0xB0,
135     NTFS_AT_REPARSE_POINT               = 0xC0,
136     NTFS_AT_EA_INFO                     = 0xD0,
137     NTFS_AT_EA                          = 0xE0,
138     NTFS_AT_PROPERTY_SET                = 0xF0,
139     NTFS_AT_LOGGED_UTIL_STREAM          = 0x100,
140     NTFS_AT_FIRST_USER_DEFINED_ATTR     = 0x1000,
141     NTFS_AT_END                         = 0xFFFFFFFF,
142 };
143
144 /* NTFS File Permissions (also called attributes in DOS terminology) */
145 enum {
146     NTFS_FILE_ATTR_READONLY                     = 0x00000001,
147     NTFS_FILE_ATTR_HIDDEN                       = 0x00000002,
148     NTFS_FILE_ATTR_SYSTEM                       = 0x00000004,
149     NTFS_FILE_ATTR_DIRECTORY                    = 0x00000010,
150     NTFS_FILE_ATTR_ARCHIVE                      = 0x00000020,
151     NTFS_FILE_ATTR_DEVICE                       = 0x00000040,
152     NTFS_FILE_ATTR_NORMAL                       = 0x00000080,
153     NTFS_FILE_ATTR_TEMPORARY                    = 0x00000100,
154     NTFS_FILE_ATTR_SPARSE_FILE                  = 0x00000200,
155     NTFS_FILE_ATTR_REPARSE_POINT                = 0x00000400,
156     NTFS_FILE_ATTR_COMPRESSED                   = 0x00000800,
157     NTFS_FILE_ATTR_OFFLINE                      = 0x00001000,
158     NTFS_FILE_ATTR_NOT_CONTENT_INDEXED          = 0x00002000,
159     NTFS_FILE_ATTR_ENCRYPTED                    = 0x00004000,
160     NTFS_FILE_ATTR_VALID_FLAGS                  = 0x00007FB7,
161     NTFS_FILE_ATTR_VALID_SET_FLAGS              = 0x000031A7,
162     NTFS_FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT  = 0x10000000,
163     NTFS_FILE_ATTR_DUP_VIEW_INDEX_PRESENT       = 0x20000000,
164 };
165
166 /* The collation rules for sorting views/indexes/etc (32-bit) */
167 enum {
168     NTFS_COLLATION_BINARY               = 0x00,
169     NTFS_COLLATION_FILE_NAME            = 0x01,
170     NTFS_COLLATION_UNICODE_STRING       = 0x02,
171     NTFS_COLLATION_NTOFS_ULONG          = 0x10,
172     NTFS_COLLATION_NTOFS_SID            = 0x11,
173     NTFS_COLLATION_NTOFS_SECURITY_HASH  = 0x12,
174     NTFS_COLLATION_NTOFS_ULONGS         = 0x13,
175 };
176
177 /*
178  * Magic identifiers present at the beginning of all ntfs record containing
179  * records (like mft records for example).
180  */
181 enum {
182     /* Found in $MFT/$DATA */
183     NTFS_MAGIC_FILE     = 0x454C4946,   /* MFT entry */
184     NTFS_MAGIC_INDX     = 0x58444E49,   /* Index buffer */
185     NTFS_MAGIC_HOLE     = 0x454C4F48,
186
187     /* Found in $LogFile/$DATA */
188     NTFS_MAGIC_RSTR     = 0x52545352,
189     NTFS_MAGIC_RCRD     = 0x44524352,
190     /* Found in $LogFile/$DATA (May be found in $MFT/$DATA, also ?) */
191     NTFS_MAGIC_CHKDSK   = 0x444B4843,
192     /* Found in all ntfs record containing records. */
193     NTFS_MAGIC_BAAD     = 0x44414142,
194     NTFS_MAGIC_EMPTY    = 0xFFFFFFFF,   /* Record is empty */
195 };
196
197 typedef struct {
198     uint32_t magic;
199     uint16_t usa_ofs;
200     uint16_t usa_count;
201 } __attribute__((__packed__)) NTFS_RECORD;
202
203 /* The $MFT metadata file types */
204 typedef enum {
205     FILE_MFT            = 0,
206     FILE_MFTMirr        = 1,
207     FILE_LogFile        = 2,
208     FILE_Volume         = 3,
209     FILE_AttrDef        = 4,
210     FILE_root           = 5,
211     FILE_Bitmap         = 6,
212     FILE_Boot           = 7,
213     FILE_BadClus        = 8,
214     FILE_Secure         = 9,
215     FILE_UpCase         = 10,
216     FILE_Extend         = 11,
217     FILE_reserved12     = 12,
218     FILE_reserved13     = 13,
219     FILE_reserved14     = 14,
220     FILE_reserved15     = 15,
221     FILE_reserved16     = 16,
222 } NTFS_SYSTEM_FILES;
223
224 enum {
225     MFT_RECORD_IN_USE       = 0x0001,
226     MFT_RECORD_IS_DIRECTORY = 0x0002,
227 } __attribute__((__packed__));
228
229 typedef struct {
230     uint32_t magic;
231     uint16_t usa_ofs;
232     uint16_t usa_count;
233     uint64_t lsn;
234     uint16_t seq_no;
235     uint16_t link_count;
236     uint16_t attrs_offset;
237     uint16_t flags;     /* MFT record flags */
238     uint32_t bytes_in_use;
239     uint32_t bytes_allocated;
240     uint64_t base_mft_record;
241     uint16_t next_attr_instance;
242     uint16_t reserved;
243     uint32_t mft_record_no;
244 } __attribute__((__packed__)) MFT_RECORD;   /* 48 bytes */
245
246 /* This is the version without the NTFS 3.1+ specific fields */
247 typedef struct {
248     uint32_t magic;
249     uint16_t usa_ofs;
250     uint16_t usa_count;
251     uint64_t lsn;
252     uint16_t seq_no;
253     uint16_t link_count;
254     uint16_t attrs_offset;
255     uint16_t flags;     /* MFT record flags */
256     uint32_t bytes_in_use;
257     uint32_t bytes_allocated;
258     uint64_t base_mft_record;
259     uint16_t next_attr_instance;
260 } __attribute__((__packed__)) MFT_RECORD_OLD;   /* 42 bytes */
261
262 enum {
263     ATTR_DEF_INDEXABLE          = 0x02,
264     ATTR_DEF_MULTIPLE           = 0x04,
265     ATTR_DEF_NOT_ZERO           = 0x08,
266     ATTR_DEF_INDEXED_UNIQUE     = 0x10,
267     ATTR_DEF_NAMED_UNIQUE       = 0x20,
268     ATTR_DEF_RESIDENT           = 0x40,
269     ATTR_DEF_ALWAYS_LOG         = 0x80,
270 };
271
272 typedef struct {
273     uint16_t name[0x40];
274     uint32_t type;
275     uint32_t display_rule;
276     uint32_t collation_rule;
277     uint32_t flags;     /* Attr def flags */
278     uint64_t min_size;
279     uint64_t max_size;
280 } __attribute__((__packed__)) ATTR_DEF;
281
282 /* Attribute flags (16-bit) */
283 enum {
284     ATTR_IS_COMPRESSED      = 0x0001,
285     ATTR_COMPRESSION_MASK   = 0x00FF,
286
287     ATTR_IS_ENCRYPTED       = 0x4000,
288     ATTR_IS_SPARSE          = 0x8000,
289 } __attribute__((__packed__));
290
291 /* Flags of resident attributes (8-bit) */
292 enum {
293     RESIDENT_ATTR_IS_INDEXED = 0x01,
294 } __attribute__((__packed__));
295
296 typedef struct {
297     uint32_t type;      /* Attr. type code */
298     uint32_t len;
299     uint8_t non_resident;
300     uint8_t name_len;
301     uint16_t name_offset;
302     uint16_t flags;     /* Attr. flags */
303     uint16_t instance;
304     union {
305         struct {    /* Resident attribute */
306             uint32_t value_len;
307             uint16_t value_offset;
308             uint8_t flags;  /* Flags of resident attributes */
309             int8_t reserved;
310         } __attribute__((__packed__)) resident;
311         struct {    /* Non-resident attributes */
312             uint64_t lowest_vcn;
313             uint64_t highest_vcn;
314             uint16_t mapping_pairs_offset;
315             uint8_t compression_unit;
316             uint8_t reserved[5];
317             int64_t allocated_size;
318             int64_t initialized_size;
319             int64_t compressed_size;
320         } __attribute__((__packed__)) non_resident;
321     } __attribute__((__packed__)) data;
322 } __attribute__((__packed__)) ATTR_RECORD;
323
324 /* Attribute: Standard Information (0x10)
325  * Note: always resident
326  */
327 typedef struct {
328     int64_t ctime;
329     int64_t atime;
330     int64_t mtime;
331     int64_t rtime;
332     uint32_t file_attrs;
333     union {
334         struct {    /* NTFS 1.2 (48 bytes) */
335             uint8_t reserved12[12];
336         } __attribute__((__packed__)) v1;
337         struct {    /* NTFS 3.x (72 bytes) */
338             uint32_t max_version;
339             uint32_t version;
340             uint32_t class_id;
341             uint32_t owner_id;
342             uint32_t sec_id;
343             uint64_t quota_charged;
344             int64_t usn;
345         } __attribute__((__packed__)) v3;
346     } __attribute__((__packed__)) ver;
347 } __attribute__((__packed__)) STANDARD_INFORMATION;
348
349 /* Attribute: Attribute List (0x20)
350  * Note: can be either resident or non-resident
351  */
352 typedef struct {
353     uint32_t type;
354     uint16_t len;
355     uint8_t name_len;
356     uint8_t name_offset;
357     uint64_t lowest_vcn;
358     uint64_t mft_ref;
359     uint16_t instance;
360     uint16_t name[0];       /* Name in Unicode */
361     /* sizeof() = 26 + (attribute_name_length * 2) bytes */
362 } __attribute__((__packed__)) ATTR_LIST_ENTRY;
363
364 #define NTFS_MAX_FILE_NAME_LEN 255
365
366 /* Possible namespaces for filenames in ntfs (8-bit) */
367 enum {
368     FILE_NAME_POSIX             = 0x00,
369     FILE_NAME_WIN32             = 0x01,
370     FILE_NAME_DOS               = 0x02,
371     FILE_NAME_WIN32_AND_DOS     = 0x03,
372 } __attribute__((__packed__));
373
374 /* Attribute: Filename (0x30)
375  * Note: always resident
376  */
377 typedef struct {
378     uint64_t parent_directory;
379     int64_t ctime;
380     int64_t atime;
381     int64_t mtime;
382     int64_t rtime;
383     uint64_t allocated_size;
384     uint64_t data_size;
385     uint32_t file_attrs;
386     union {
387         struct {
388             uint16_t __packed___ea_size;
389             uint16_t reserved;      /* reserved for alignment */
390         } __attribute__((__packed__)) ea;
391         struct {
392             uint32_t reparse_point_tag;
393         } __attribute__((__packed__)) rp;
394     } __attribute__((__packed__)) type;
395     uint8_t file_name_len;
396     uint8_t file_name_type;
397     uint16_t file_name[0];          /* File name in Unicode */
398 } __attribute__((__packed__)) FILE_NAME_ATTR;
399
400 /* Attribute: Volume Name (0x60)
401  * Note: always resident
402  * Note: Present only in FILE_volume
403  */
404 typedef struct {
405     uint16_t name[0];       /* The name of the volume in Unicode */
406 } __attribute__((__packed__)) VOLUME_NAME;
407
408 /* Volume flags (16-bit) */
409 enum {
410     VOLUME_IS_DIRTY             = 0x0001,
411     VOLUME_RESIZE_LOG_FILE      = 0x0002,
412     VOLUME_UPGRADE_ON_MOUNT     = 0x0004,
413     VOLUME_MOUNTED_ON_NT4       = 0x0008,
414
415     VOLUME_DELETE_USN_UNDERWAY  = 0x0010,
416     VOLUME_REPAIR_OBJECT_ID     = 0x0020,
417
418     VOLUME_CHKDSK_UNDERWAY      = 0x4000,
419     VOLUME_MODIFIED_BY_CHKDSK   = 0x8000,
420
421     VOLUME_FLAGS_MASK           = 0xC03F,
422
423     VOLUME_MUST_MOUNT_RO_MASK   = 0xC027,
424 } __attribute__((__packed__));
425
426 /* Attribute: Volume Information (0x70)
427  * Note: always resident
428  * Note: present only in FILE_Volume
429  */
430 typedef struct {
431     uint64_t reserved;
432     uint8_t major_ver;
433     uint8_t minor_ver;
434     uint16_t flags;     /* Volume flags */
435 } __attribute__((__packed__)) VOLUME_INFORMATION;
436
437 /* Attribute: Data attribute (0x80)
438  * Note: can be either resident or non-resident
439  */
440 typedef struct {
441     uint8_t data[0];
442 } __attribute__((__packed__)) DATA_ATTR;
443
444 /* Index header flags (8-bit) */
445 enum {
446     SMALL_INDEX = 0,
447     LARGE_INDEX = 1,
448     LEAF_NODE   = 0,
449     INDEX_NODE  = 1,
450     NODE_MASK   = 1,
451 } __attribute__((__packed__));
452
453 /* Header for the indexes, describing the INDEX_ENTRY records, which
454  * follow the INDEX_HEADER.
455  */
456 typedef struct {
457     uint32_t entries_offset;
458     uint32_t index_len;
459     uint32_t allocated_size;
460     uint8_t flags;              /* Index header flags */
461     uint8_t reserved[3];        /* Align to 8-byte boundary */
462 } __attribute__((__packed__)) INDEX_HEADER;
463
464 /* Attribute: Index Root (0x90)
465  * Note: always resident
466  */
467 typedef struct {
468     uint32_t type;  /* It is $FILE_NAME for directories, zero for view indexes.
469                      * No other values allowed.
470                      */
471     uint32_t collation_rule;
472     uint32_t index_block_size;
473     uint8_t clust_per_index_block;
474     uint8_t reserved[3];
475     INDEX_HEADER index;
476 } __attribute__((__packed__)) INDEX_ROOT;
477
478 /* Attribute: Index allocation (0xA0)
479  * Note: always non-resident, of course! :-)
480  */
481 typedef struct {
482     uint32_t magic;
483     uint16_t usa_ofs;           /* Update Sequence Array offsets */
484     uint16_t usa_count;         /* Update Sequence Array number in bytes */
485     int64_t lsn;
486     int64_t index_block_vcn;    /* Virtual cluster number of the index block */
487     INDEX_HEADER index;
488 } __attribute__((__packed__)) INDEX_BLOCK;
489
490 typedef INDEX_BLOCK INDEX_ALLOCATION;
491
492 enum {
493     INDEX_ENTRY_NODE            = 1,
494     INDEX_ENTRY_END             = 2,
495     /* force enum bit width to 16-bit */
496     INDEX_ENTRY_SPACE_FILTER    = 0xFFFF,
497 } __attribute__((__packed__));
498
499 typedef struct {
500     union {
501         struct { /* Only valid when INDEX_ENTRY_END is not set */
502             uint64_t indexed_file;
503         } __attribute__((__packed__)) dir;
504         struct { /* Used for views/indexes to find the entry's data */
505             uint16_t data_offset;
506             uint16_t data_len;
507             uint32_t reservedV;
508         } __attribute__((__packed__)) vi;
509     } __attribute__((__packed__)) data;
510     uint16_t len;
511     uint16_t key_len;
512     uint16_t flags;     /* Index entry flags */
513     uint16_t reserved;  /* Align to 8-byte boundary */
514 } __attribute__((__packed__)) INDEX_ENTRY_HEADER;
515
516 typedef struct {
517     union {
518         struct { /* Only valid when INDEX_ENTRY_END is not set */
519             uint64_t indexed_file;
520         } __attribute__((__packed__)) dir;
521         struct { /* Used for views/indexes to find the entry's data */
522             uint16_t data_offset;
523             uint16_t data_len;
524             uint32_t reservedV;
525         } __attribute__((__packed__)) vi;
526     } __attribute__((__packed__)) data;
527     uint16_t len;
528     uint16_t key_len;
529     uint16_t flags;     /* Index entry flags */
530     uint16_t reserved;  /* Align to 8-byte boundary */
531     union {
532         FILE_NAME_ATTR file_name;
533         //SII_INDEX_KEY sii;
534         //SDH_INDEX_KEY sdh;
535         //GUID object_id;
536         //REPARSE_INDEX_KEY reparse;
537         //SID sid;
538         uint32_t owner_id;
539     } __attribute__((__packed__)) key;
540 } __attribute__((__packed__)) INDEX_ENTRY;
541
542 typedef struct {
543     uint8_t bitmap[0];      /* Array of bits */
544 } __attribute__((__packed__)) BITMAP_ATTR;
545
546 static inline struct ntfs_sb_info *NTFS_SB(struct fs_info *fs)
547 {
548     return fs->fs_info;
549 }
550
551 #define NTFS_PVT(i) ((struct ntfs_inode *)((i)->pvt))
552
553 #endif /* _NTFS_H_ */