2 * Copyright (C) Paulo Alcantara <pcacjr@gmail.com>
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.
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.
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.
27 uint8_t sec_per_clust;
38 uint64_t total_sectors;
40 uint64_t mft_mirr_lclust;
41 int8_t clust_per_mft_record;
43 uint8_t clust_per_idx_record;
48 uint8_t pad[428]; /* padding to a sector boundary (512 bytes) */
49 } __attribute__((__packed__));
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 */
57 uint8_t clust_per_idx_record; /* Clusters per Index Record */
59 unsigned long long clusters; /* Total number of clusters */
61 unsigned clust_shift; /* Based on sectors */
62 unsigned clust_byte_shift; /* Based on bytes */
66 } __attribute__((__packed__));
68 /* The NTFS in-memory inode structure */
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 */
77 uint32_t idx_blks_count;
78 uint32_t entries_count;
80 union { /* Non-resident $DATA attribute */
81 struct { /* Used only if non_resident flags isn't set */
82 uint32_t offset; /* Data offset */
84 struct { /* Used only if non_resident is set */
85 struct runlist *rlist;
89 struct { /* It is a directory, $MFT, or an index inode */
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 */
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 */
107 MAP_ALLOCATED = 1 << 2,
108 MAP_UNALLOCATED = 1 << 3,
109 MAP_MASK = 0x0000000F,
112 struct mapping_chunk {
119 /* System defined attributes (32-bit)
120 * Each attribute type has a corresponding attribute name (in Unicode)
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,
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,
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,
144 /* NTFS File Permissions (also called attributes in DOS terminology) */
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,
166 /* The collation rules for sorting views/indexes/etc (32-bit) */
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,
178 * Magic identifiers present at the beginning of all ntfs record containing
179 * records (like mft records for example).
182 /* Found in $MFT/$DATA */
183 NTFS_MAGIC_FILE = 0x454C4946, /* MFT entry */
184 NTFS_MAGIC_INDX = 0x58444E49, /* Index buffer */
185 NTFS_MAGIC_HOLE = 0x454C4F48,
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 */
201 } __attribute__((__packed__)) NTFS_RECORD;
203 /* The $MFT metadata file types */
217 FILE_reserved12 = 12,
218 FILE_reserved13 = 13,
219 FILE_reserved14 = 14,
220 FILE_reserved15 = 15,
221 FILE_reserved16 = 16,
225 MFT_RECORD_IN_USE = 0x0001,
226 MFT_RECORD_IS_DIRECTORY = 0x0002,
227 } __attribute__((__packed__));
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;
243 uint32_t mft_record_no;
244 } __attribute__((__packed__)) MFT_RECORD; /* 48 bytes */
246 /* This is the version without the NTFS 3.1+ specific fields */
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 */
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,
275 uint32_t display_rule;
276 uint32_t collation_rule;
277 uint32_t flags; /* Attr def flags */
280 } __attribute__((__packed__)) ATTR_DEF;
282 /* Attribute flags (16-bit) */
284 ATTR_IS_COMPRESSED = 0x0001,
285 ATTR_COMPRESSION_MASK = 0x00FF,
287 ATTR_IS_ENCRYPTED = 0x4000,
288 ATTR_IS_SPARSE = 0x8000,
289 } __attribute__((__packed__));
291 /* Flags of resident attributes (8-bit) */
293 RESIDENT_ATTR_IS_INDEXED = 0x01,
294 } __attribute__((__packed__));
297 uint32_t type; /* Attr. type code */
299 uint8_t non_resident;
301 uint16_t name_offset;
302 uint16_t flags; /* Attr. flags */
305 struct { /* Resident attribute */
307 uint16_t value_offset;
308 uint8_t flags; /* Flags of resident attributes */
310 } __attribute__((__packed__)) resident;
311 struct { /* Non-resident attributes */
313 uint64_t highest_vcn;
314 uint16_t mapping_pairs_offset;
315 uint8_t compression_unit;
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;
324 /* Attribute: Standard Information (0x10)
325 * Note: always resident
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;
343 uint64_t quota_charged;
345 } __attribute__((__packed__)) v3;
346 } __attribute__((__packed__)) ver;
347 } __attribute__((__packed__)) STANDARD_INFORMATION;
349 /* Attribute: Attribute List (0x20)
350 * Note: can be either resident or non-resident
360 uint16_t name[0]; /* Name in Unicode */
361 /* sizeof() = 26 + (attribute_name_length * 2) bytes */
362 } __attribute__((__packed__)) ATTR_LIST_ENTRY;
364 #define NTFS_MAX_FILE_NAME_LEN 255
366 /* Possible namespaces for filenames in ntfs (8-bit) */
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__));
374 /* Attribute: Filename (0x30)
375 * Note: always resident
378 uint64_t parent_directory;
383 uint64_t allocated_size;
388 uint16_t __packed___ea_size;
389 uint16_t reserved; /* reserved for alignment */
390 } __attribute__((__packed__)) ea;
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;
400 /* Attribute: Volume Name (0x60)
401 * Note: always resident
402 * Note: Present only in FILE_volume
405 uint16_t name[0]; /* The name of the volume in Unicode */
406 } __attribute__((__packed__)) VOLUME_NAME;
408 /* Volume flags (16-bit) */
410 VOLUME_IS_DIRTY = 0x0001,
411 VOLUME_RESIZE_LOG_FILE = 0x0002,
412 VOLUME_UPGRADE_ON_MOUNT = 0x0004,
413 VOLUME_MOUNTED_ON_NT4 = 0x0008,
415 VOLUME_DELETE_USN_UNDERWAY = 0x0010,
416 VOLUME_REPAIR_OBJECT_ID = 0x0020,
418 VOLUME_CHKDSK_UNDERWAY = 0x4000,
419 VOLUME_MODIFIED_BY_CHKDSK = 0x8000,
421 VOLUME_FLAGS_MASK = 0xC03F,
423 VOLUME_MUST_MOUNT_RO_MASK = 0xC027,
424 } __attribute__((__packed__));
426 /* Attribute: Volume Information (0x70)
427 * Note: always resident
428 * Note: present only in FILE_Volume
434 uint16_t flags; /* Volume flags */
435 } __attribute__((__packed__)) VOLUME_INFORMATION;
437 /* Attribute: Data attribute (0x80)
438 * Note: can be either resident or non-resident
442 } __attribute__((__packed__)) DATA_ATTR;
444 /* Index header flags (8-bit) */
451 } __attribute__((__packed__));
453 /* Header for the indexes, describing the INDEX_ENTRY records, which
454 * follow the INDEX_HEADER.
457 uint32_t entries_offset;
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;
464 /* Attribute: Index Root (0x90)
465 * Note: always resident
468 uint32_t type; /* It is $FILE_NAME for directories, zero for view indexes.
469 * No other values allowed.
471 uint32_t collation_rule;
472 uint32_t index_block_size;
473 uint8_t clust_per_index_block;
476 } __attribute__((__packed__)) INDEX_ROOT;
478 /* Attribute: Index allocation (0xA0)
479 * Note: always non-resident, of course! :-)
483 uint16_t usa_ofs; /* Update Sequence Array offsets */
484 uint16_t usa_count; /* Update Sequence Array number in bytes */
486 int64_t index_block_vcn; /* Virtual cluster number of the index block */
488 } __attribute__((__packed__)) INDEX_BLOCK;
490 typedef INDEX_BLOCK INDEX_ALLOCATION;
493 INDEX_ENTRY_NODE = 1,
495 /* force enum bit width to 16-bit */
496 INDEX_ENTRY_SPACE_FILTER = 0xFFFF,
497 } __attribute__((__packed__));
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;
508 } __attribute__((__packed__)) vi;
509 } __attribute__((__packed__)) data;
512 uint16_t flags; /* Index entry flags */
513 uint16_t reserved; /* Align to 8-byte boundary */
514 } __attribute__((__packed__)) INDEX_ENTRY_HEADER;
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;
525 } __attribute__((__packed__)) vi;
526 } __attribute__((__packed__)) data;
529 uint16_t flags; /* Index entry flags */
530 uint16_t reserved; /* Align to 8-byte boundary */
532 FILE_NAME_ATTR file_name;
536 //REPARSE_INDEX_KEY reparse;
539 } __attribute__((__packed__)) key;
540 } __attribute__((__packed__)) INDEX_ENTRY;
543 uint8_t bitmap[0]; /* Array of bits */
544 } __attribute__((__packed__)) BITMAP_ATTR;
546 static inline struct ntfs_sb_info *NTFS_SB(struct fs_info *fs)
551 #define NTFS_PVT(i) ((struct ntfs_inode *)((i)->pvt))
553 #endif /* _NTFS_H_ */