source: bootcd/isolinux/syslinux-6.03/core/fs/ntfs/ntfs.h

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 15.6 KB
Line 
1/*
2 * Copyright (C) 2011-2012 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#include "runlist.h"
21
22#ifndef _NTFS_H_
23#define _NTFS_H_
24
25struct ntfs_bpb {
26    uint8_t jmp_boot[3];
27    char oem_name[8];
28    uint16_t sector_size;
29    uint8_t sec_per_clust;
30    uint16_t res_sectors;
31    uint8_t zero_0[3];
32    uint16_t zero_1;
33    uint8_t media;
34    uint16_t zero_2;
35    uint16_t unused_0;
36    uint16_t unused_1;
37    uint32_t unused_2;
38    uint32_t zero_3;
39    uint32_t unused_3;
40    uint64_t total_sectors;
41    uint64_t mft_lclust;
42    uint64_t mft_mirr_lclust;
43    int8_t clust_per_mft_record;
44    uint8_t unused_4[3];
45    uint8_t clust_per_idx_record;
46    uint8_t unused_5[3];
47    uint64_t vol_serial;
48    uint32_t unused_6;
49
50    uint8_t pad[428];       /* padding to a sector boundary (512 bytes) */
51} __attribute__((__packed__));
52
53/* Function type for an NTFS-version-dependent MFT record lookup */
54struct ntfs_mft_record;
55typedef struct ntfs_mft_record *f_mft_record_lookup(struct fs_info *,
56                                                    uint32_t, block_t *);
57
58struct ntfs_sb_info {
59    block_t mft_blk;                /* The first MFT record block */
60    uint64_t mft_lcn;               /* LCN of the first MFT record */
61    unsigned mft_size;              /* The MFT size in sectors */
62    uint64_t mft_record_size;       /* MFT record size in bytes */
63
64    uint8_t clust_per_idx_record;   /* Clusters per Index Record */
65
66    unsigned long long clusters;    /* Total number of clusters */
67
68    unsigned clust_shift;           /* Based on sectors */
69    unsigned clust_byte_shift;      /* Based on bytes */
70    unsigned clust_mask;
71    unsigned clust_size;
72
73    uint8_t major_ver;              /* Major version from $Volume */
74    uint8_t minor_ver;              /* Minor version from $Volume */
75
76    /* NTFS-version-dependent MFT record lookup function to use */
77    f_mft_record_lookup *mft_record_lookup;
78} __attribute__((__packed__));
79
80/* The NTFS in-memory inode structure */
81struct ntfs_inode {
82    int64_t initialized_size;
83    int64_t allocated_size;
84    unsigned long mft_no;       /* Number of the mft record / inode */
85    uint16_t seq_no;            /* Sequence number of the mft record */
86    uint32_t type;              /* Attribute type of this inode */
87    uint8_t non_resident;
88    union {                 /* Non-resident $DATA attribute */
89        struct {            /* Used only if non_resident flags isn't set */
90            uint32_t offset;    /* Data offset */
91        } resident;
92        struct {            /* Used only if non_resident is set */
93            struct runlist *rlist;
94        } non_resident;
95    } data;
96    uint32_t start_cluster; /* Starting cluster address */
97    sector_t start;         /* Starting sector */
98    sector_t offset;        /* Current sector offset */
99    sector_t here;          /* Sector corresponding to offset */
100};
101
102/* This is structure is used to keep a state for ntfs_readdir() callers.
103 * As NTFS stores directory entries in a complex way, this is structure
104 * ends up saving a state required to find out where we must start from
105 * for the next ntfs_readdir() call.
106 */
107struct ntfs_readdir_state {
108    unsigned long mft_no;       /* MFT record number */
109    bool in_idx_root;           /* It's true if we're still in the INDEX root */
110    uint32_t idx_blks_count;    /* Number of read INDX blocks */
111    uint32_t entries_count;     /* Number of read INDEX entries */
112    int64_t last_vcn;           /* Last VCN of the INDX block */
113};
114
115enum {
116    MAP_UNSPEC,
117    MAP_START           = 1 << 0,
118    MAP_END             = 1 << 1,
119    MAP_ALLOCATED       = 1 << 2,
120    MAP_UNALLOCATED     = 1 << 3,
121    MAP_MASK            = 0x0000000F,
122};
123
124struct mapping_chunk {
125    uint64_t vcn;
126    int64_t lcn;
127    uint64_t len;
128    uint32_t flags;
129};
130
131/* System defined attributes (32-bit)
132 * Each attribute type has a corresponding attribute name (in Unicode)
133 */
134enum {
135    NTFS_AT_UNUSED                      = 0x00,
136    NTFS_AT_STANDARD_INFORMATION        = 0x10,
137    NTFS_AT_ATTR_LIST                   = 0x20,
138    NTFS_AT_FILENAME                    = 0x30,
139    NTFS_AT_OBJ_ID                      = 0x40,
140    NTFS_AT_SECURITY_DESCP              = 0x50,
141    NTFS_AT_VOL_NAME                    = 0x60,
142    NTFS_AT_VOL_INFO                    = 0x70,
143    NTFS_AT_DATA                        = 0x80,
144    NTFS_AT_INDEX_ROOT                  = 0x90,
145    NTFS_AT_INDEX_ALLOCATION            = 0xA0,
146    NTFS_AT_BITMAP                      = 0xB0,
147    NTFS_AT_REPARSE_POINT               = 0xC0,
148    NTFS_AT_EA_INFO                     = 0xD0,
149    NTFS_AT_EA                          = 0xE0,
150    NTFS_AT_PROPERTY_SET                = 0xF0,
151    NTFS_AT_LOGGED_UTIL_STREAM          = 0x100,
152    NTFS_AT_FIRST_USER_DEFINED_ATTR     = 0x1000,
153    NTFS_AT_END                         = 0xFFFFFFFF,
154};
155
156/* NTFS File Permissions (also called attributes in DOS terminology) */
157enum {
158    NTFS_FILE_ATTR_READONLY                     = 0x00000001,
159    NTFS_FILE_ATTR_HIDDEN                       = 0x00000002,
160    NTFS_FILE_ATTR_SYSTEM                       = 0x00000004,
161    NTFS_FILE_ATTR_DIRECTORY                    = 0x00000010,
162    NTFS_FILE_ATTR_ARCHIVE                      = 0x00000020,
163    NTFS_FILE_ATTR_DEVICE                       = 0x00000040,
164    NTFS_FILE_ATTR_NORMAL                       = 0x00000080,
165    NTFS_FILE_ATTR_TEMPORARY                    = 0x00000100,
166    NTFS_FILE_ATTR_SPARSE_FILE                  = 0x00000200,
167    NTFS_FILE_ATTR_REPARSE_POINT                = 0x00000400,
168    NTFS_FILE_ATTR_COMPRESSED                   = 0x00000800,
169    NTFS_FILE_ATTR_OFFLINE                      = 0x00001000,
170    NTFS_FILE_ATTR_NOT_CONTENT_INDEXED          = 0x00002000,
171    NTFS_FILE_ATTR_ENCRYPTED                    = 0x00004000,
172    NTFS_FILE_ATTR_VALID_FLAGS                  = 0x00007FB7,
173    NTFS_FILE_ATTR_VALID_SET_FLAGS              = 0x000031A7,
174    NTFS_FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT  = 0x10000000,
175    NTFS_FILE_ATTR_DUP_VIEW_INDEX_PRESENT       = 0x20000000,
176};
177
178/*
179 * Magic identifiers present at the beginning of all ntfs record containing
180 * records (like mft records for example).
181 */
182enum {
183    /* Found in $MFT/$DATA */
184    NTFS_MAGIC_FILE     = 0x454C4946,   /* MFT entry */
185    NTFS_MAGIC_INDX     = 0x58444E49,   /* Index buffer */
186    NTFS_MAGIC_HOLE     = 0x454C4F48,
187
188    /* Found in $LogFile/$DATA */
189    NTFS_MAGIC_RSTR     = 0x52545352,
190    NTFS_MAGIC_RCRD     = 0x44524352,
191    /* Found in $LogFile/$DATA (May be found in $MFT/$DATA, also ?) */
192    NTFS_MAGIC_CHKDSK   = 0x444B4843,
193    /* Found in all ntfs record containing records. */
194    NTFS_MAGIC_BAAD     = 0x44414142,
195    NTFS_MAGIC_EMPTY    = 0xFFFFFFFF,   /* Record is empty */
196};
197
198struct ntfs_record {
199    uint32_t magic;
200    uint16_t usa_ofs;
201    uint16_t usa_count;
202} __attribute__((__packed__)) NTFS_RECORD;
203
204/* The $MFT metadata file types */
205enum ntfs_system_file {
206    FILE_MFT            = 0,
207    FILE_MFTMirr        = 1,
208    FILE_LogFile        = 2,
209    FILE_Volume         = 3,
210    FILE_AttrDef        = 4,
211    FILE_root           = 5,
212    FILE_Bitmap         = 6,
213    FILE_Boot           = 7,
214    FILE_BadClus        = 8,
215    FILE_Secure         = 9,
216    FILE_UpCase         = 10,
217    FILE_Extend         = 11,
218    FILE_reserved12     = 12,
219    FILE_reserved13     = 13,
220    FILE_reserved14     = 14,
221    FILE_reserved15     = 15,
222    FILE_reserved16     = 16,
223};
224
225enum {
226    MFT_RECORD_IN_USE       = 0x0001,
227    MFT_RECORD_IS_DIRECTORY = 0x0002,
228} __attribute__((__packed__));
229
230struct ntfs_mft_record {
231    uint32_t magic;
232    uint16_t usa_ofs;
233    uint16_t usa_count;
234    uint64_t lsn;
235    uint16_t seq_no;
236    uint16_t link_count;
237    uint16_t attrs_offset;
238    uint16_t flags;     /* MFT record flags */
239    uint32_t bytes_in_use;
240    uint32_t bytes_allocated;
241    uint64_t base_mft_record;
242    uint16_t next_attr_instance;
243    uint16_t reserved;
244    uint32_t mft_record_no;
245} __attribute__((__packed__));   /* 48 bytes */
246
247/* This is the version without the NTFS 3.1+ specific fields */
248struct ntfs_mft_record_old {
249    uint32_t magic;
250    uint16_t usa_ofs;
251    uint16_t usa_count;
252    uint64_t lsn;
253    uint16_t seq_no;
254    uint16_t link_count;
255    uint16_t attrs_offset;
256    uint16_t flags;     /* MFT record flags */
257    uint32_t bytes_in_use;
258    uint32_t bytes_allocated;
259    uint64_t base_mft_record;
260    uint16_t next_attr_instance;
261} __attribute__((__packed__));   /* 42 bytes */
262
263enum {
264    ATTR_DEF_INDEXABLE          = 0x02,
265    ATTR_DEF_MULTIPLE           = 0x04,
266    ATTR_DEF_NOT_ZERO           = 0x08,
267    ATTR_DEF_INDEXED_UNIQUE     = 0x10,
268    ATTR_DEF_NAMED_UNIQUE       = 0x20,
269    ATTR_DEF_RESIDENT           = 0x40,
270    ATTR_DEF_ALWAYS_LOG         = 0x80,
271};
272
273struct ntfs_attr_record {
274    uint32_t type;      /* Attr. type code */
275    uint32_t len;
276    uint8_t non_resident;
277    uint8_t name_len;
278    uint16_t name_offset;
279    uint16_t flags;     /* Attr. flags */
280    uint16_t instance;
281    union {
282        struct {    /* Resident attribute */
283            uint32_t value_len;
284            uint16_t value_offset;
285            uint8_t flags;  /* Flags of resident attributes */
286            int8_t reserved;
287        } __attribute__((__packed__)) resident;
288        struct {    /* Non-resident attributes */
289            uint64_t lowest_vcn;
290            uint64_t highest_vcn;
291            uint16_t mapping_pairs_offset;
292            uint8_t compression_unit;
293            uint8_t reserved[5];
294            int64_t allocated_size;
295            int64_t data_size; /* Byte size of the attribute value.
296                                * Note: it can be larger than
297                                * allocated_size if attribute value is
298                                * compressed or sparse.
299                                */
300            int64_t initialized_size;
301            int64_t compressed_size;
302        } __attribute__((__packed__)) non_resident;
303    } __attribute__((__packed__)) data;
304} __attribute__((__packed__));
305
306/* Attribute: Attribute List (0x20)
307 * Note: it can be either resident or non-resident
308 */
309struct ntfs_attr_list_entry {
310    uint32_t type;
311    uint16_t length;
312    uint8_t name_length;
313    uint8_t name_offset;
314    uint64_t lowest_vcn;
315    uint64_t mft_ref;
316    uint16_t instance;
317    uint16_t name[0];
318} __attribute__((__packed__));
319
320#define NTFS_MAX_FILE_NAME_LEN 255
321
322/* Possible namespaces for filenames in ntfs (8-bit) */
323enum {
324    FILE_NAME_POSIX             = 0x00,
325    FILE_NAME_WIN32             = 0x01,
326    FILE_NAME_DOS               = 0x02,
327    FILE_NAME_WIN32_AND_DOS     = 0x03,
328} __attribute__((__packed__));
329
330/* Attribute: Filename (0x30)
331 * Note: always resident
332 */
333struct ntfs_filename_attr {
334    uint64_t parent_directory;
335    int64_t ctime;
336    int64_t atime;
337    int64_t mtime;
338    int64_t rtime;
339    uint64_t allocated_size;
340    uint64_t data_size;
341    uint32_t file_attrs;
342    union {
343        struct {
344            uint16_t packed_ea_size;
345            uint16_t reserved;      /* reserved for alignment */
346        } __attribute__((__packed__)) ea;
347        struct {
348            uint32_t reparse_point_tag;
349        } __attribute__((__packed__)) rp;
350    } __attribute__((__packed__)) type;
351    uint8_t file_name_len;
352    uint8_t file_name_type;
353    uint16_t file_name[0];          /* File name in Unicode */
354} __attribute__((__packed__));
355
356/* Attribute: Volume Name (0x60)
357 * Note: always resident
358 * Note: Present only in FILE_volume
359 */
360struct ntfs_vol_name {
361    uint16_t name[0];       /* The name of the volume in Unicode */
362} __attribute__((__packed__));
363
364/* Attribute: Volume Information (0x70)
365 * Note: always resident
366 * Note: present only in FILE_Volume
367 */
368struct ntfs_vol_info {
369    uint64_t reserved;
370    uint8_t major_ver;
371    uint8_t minor_ver;
372    uint16_t flags;     /* Volume flags */
373} __attribute__((__packed__));
374
375/* Attribute: Data attribute (0x80)
376 * Note: can be either resident or non-resident
377 */
378struct ntfs_data_attr {
379    uint8_t data[0];
380} __attribute__((__packed__));
381
382/* Index header flags (8-bit) */
383enum {
384    SMALL_INDEX = 0,
385    LARGE_INDEX = 1,
386    LEAF_NODE   = 0,
387    INDEX_NODE  = 1,
388    NODE_MASK   = 1,
389} __attribute__((__packed__));
390
391/* Header for the indexes, describing the INDEX_ENTRY records, which
392 * follow the struct ntfs_idx_header.
393 */
394struct ntfs_idx_header {
395    uint32_t entries_offset;
396    uint32_t index_len;
397    uint32_t allocated_size;
398    uint8_t flags;              /* Index header flags */
399    uint8_t reserved[3];        /* Align to 8-byte boundary */
400} __attribute__((__packed__));
401
402/* Attribute: Index Root (0x90)
403 * Note: always resident
404 */
405struct ntfs_idx_root {
406    uint32_t type;  /* It is $FILE_NAME for directories, zero for view indexes.
407                     * No other values allowed.
408                     */
409    uint32_t collation_rule;
410    uint32_t index_block_size;
411    uint8_t clust_per_index_block;
412    uint8_t reserved[3];
413    struct ntfs_idx_header index;
414} __attribute__((__packed__));
415
416/* Attribute: Index allocation (0xA0)
417 * Note: always non-resident, of course! :-)
418 */
419struct ntfs_idx_allocation {
420    uint32_t magic;
421    uint16_t usa_ofs;           /* Update Sequence Array offsets */
422    uint16_t usa_count;         /* Update Sequence Array number in bytes */
423    int64_t lsn;
424    int64_t index_block_vcn;    /* Virtual cluster number of the index block */
425    struct ntfs_idx_header index;
426} __attribute__((__packed__));
427
428enum {
429    INDEX_ENTRY_NODE            = 1,
430    INDEX_ENTRY_END             = 2,
431    /* force enum bit width to 16-bit */
432    INDEX_ENTRY_SPACE_FILTER    = 0xFFFF,
433} __attribute__((__packed__));
434
435struct ntfs_idx_entry_header {
436    union {
437        struct { /* Only valid when INDEX_ENTRY_END is not set */
438            uint64_t indexed_file;
439        } __attribute__((__packed__)) dir;
440        struct { /* Used for views/indexes to find the entry's data */
441            uint16_t data_offset;
442            uint16_t data_len;
443            uint32_t reservedV;
444        } __attribute__((__packed__)) vi;
445    } __attribute__((__packed__)) data;
446    uint16_t len;
447    uint16_t key_len;
448    uint16_t flags;     /* Index entry flags */
449    uint16_t reserved;  /* Align to 8-byte boundary */
450} __attribute__((__packed__));
451
452struct ntfs_idx_entry {
453    union {
454        struct { /* Only valid when INDEX_ENTRY_END is not set */
455            uint64_t indexed_file;
456        } __attribute__((__packed__)) dir;
457        struct { /* Used for views/indexes to find the entry's data */
458            uint16_t data_offset;
459            uint16_t data_len;
460            uint32_t reservedV;
461        } __attribute__((__packed__)) vi;
462    } __attribute__((__packed__)) data;
463    uint16_t len;
464    uint16_t key_len;
465    uint16_t flags;     /* Index entry flags */
466    uint16_t reserved;  /* Align to 8-byte boundary */
467    union {
468        struct ntfs_filename_attr file_name;
469        //SII_INDEX_KEY sii;
470        //SDH_INDEX_KEY sdh;
471        //GUID object_id;
472        //REPARSE_INDEX_KEY reparse;
473        //SID sid;
474        uint32_t owner_id;
475    } __attribute__((__packed__)) key;
476} __attribute__((__packed__));
477
478static inline struct ntfs_sb_info *NTFS_SB(struct fs_info *fs)
479{
480    return fs->fs_info;
481}
482
483#define NTFS_PVT(i) ((struct ntfs_inode *)((i)->pvt))
484
485#endif /* _NTFS_H_ */
Note: See TracBrowser for help on using the repository browser.