📄 layout.h
字号:
/* * layout.h - Ntfs on-disk layout structures. Part of the Linux-NTFS project. * * Copyright (c) 2000-2005 Anton Altaparmakov * Copyright (c) 2005 Yura Pakhuchiy * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program/include file is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (in the main directory of the Linux-NTFS * distribution in the file COPYING); if not, write to the Free Software * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#ifndef _NTFS_LAYOUT_H#define _NTFS_LAYOUT_H#include "types.h"#include "endians.h"#include "support.h"/* The NTFS oem_id */#define magicNTFS const_cpu_to_le64(0x202020205346544e) /* "NTFS " */#define NTFS_SB_MAGIC 0x5346544e /* 'NTFS' *//* * Location of bootsector on partition: * The standard NTFS_BOOT_SECTOR is on sector 0 of the partition. * On NT4 and above there is one backup copy of the boot sector to * be found on the last sector of the partition (not normally accessible * from within Windows as the bootsector contained number of sectors * value is one less than the actual value!). * On versions of NT 3.51 and earlier, the backup copy was located at * number of sectors/2 (integer divide), i.e. in the middle of the volume. *//** * struct BIOS_PARAMETER_BLOCK - BIOS parameter block (bpb) structure. */typedef struct { u16 bytes_per_sector; /* Size of a sector in bytes. */ u8 sectors_per_cluster; /* Size of a cluster in sectors. */ u16 reserved_sectors; /* zero */ u8 fats; /* zero */ u16 root_entries; /* zero */ u16 sectors; /* zero */ u8 media_type; /* 0xf8 = hard disk */ u16 sectors_per_fat; /* zero *//*0x0d*/u16 sectors_per_track; /* Required to boot Windows. *//*0x0f*/u16 heads; /* Required to boot Windows. *//*0x11*/u32 hidden_sectors; /* Offset to the start of the partition relative to the disk in sectors. Required to boot Windows. *//*0x15*/u32 large_sectors; /* zero *//* sizeof() = 25 (0x19) bytes */} __attribute__((__packed__)) BIOS_PARAMETER_BLOCK;/** * struct NTFS_BOOT_SECTOR - NTFS boot sector structure. */typedef struct { u8 jump[3]; /* Irrelevant (jump to boot up code).*/ u64 oem_id; /* Magic "NTFS ". *//*0x0b*/BIOS_PARAMETER_BLOCK bpb; /* See BIOS_PARAMETER_BLOCK. */ u8 physical_drive; /* 0x00 floppy, 0x80 hard disk */ u8 current_head; /* zero */ u8 extended_boot_signature; /* 0x80 */ u8 reserved2; /* zero *//*0x28*/s64 number_of_sectors; /* Number of sectors in volume. Gives maximum volume size of 2^63 sectors. Assuming standard sector size of 512 bytes, the maximum byte size is approx. 4.7x10^21 bytes. (-; */ s64 mft_lcn; /* Cluster location of mft data. */ s64 mftmirr_lcn; /* Cluster location of copy of mft. */ s8 clusters_per_mft_record; /* Mft record size in clusters. */ u8 reserved0[3]; /* zero */ s8 clusters_per_index_record; /* Index block size in clusters. */ u8 reserved1[3]; /* zero */ u64 volume_serial_number; /* Irrelevant (serial number). */ u32 checksum; /* Boot sector checksum. *//*0x54*/u8 bootstrap[426]; /* Irrelevant (boot up code). */ u16 end_of_sector_marker; /* End of bootsector magic. Always is 0xaa55 in little endian. *//* sizeof() = 512 (0x200) bytes */} __attribute__((__packed__)) NTFS_BOOT_SECTOR;/** * enum NTFS_RECORD_TYPES - * * Magic identifiers present at the beginning of all ntfs record containing * records (like mft records for example). */typedef enum { /* Found in $MFT/$DATA. */ magic_FILE = const_cpu_to_le32(0x454c4946), /* Mft entry. */ magic_INDX = const_cpu_to_le32(0x58444e49), /* Index buffer. */ magic_HOLE = const_cpu_to_le32(0x454c4f48), /* ? (NTFS 3.0+?) */ /* Found in $LogFile/$DATA. */ magic_RSTR = const_cpu_to_le32(0x52545352), /* Restart page. */ magic_RCRD = const_cpu_to_le32(0x44524352), /* Log record page. */ /* Found in $LogFile/$DATA. (May be found in $MFT/$DATA, also?) */ magic_CHKD = const_cpu_to_le32(0x444b4843), /* Modified by chkdsk. */ /* Found in all ntfs record containing records. */ magic_BAAD = const_cpu_to_le32(0x44414142), /* Failed multi sector transfer was detected. */ /* * Found in $LogFile/$DATA when a page is full or 0xff bytes and is * thus not initialized. User has to initialize the page before using * it. */ magic_empty = const_cpu_to_le32(0xffffffff),/* Record is empty and has to be initialized before it can be used. */} NTFS_RECORD_TYPES;/* * Generic magic comparison macros. Finally found a use for the ## preprocessor * operator! (-8 */#define ntfs_is_magic(x, m) ( (u32)(x) == (u32)magic_##m )#define ntfs_is_magicp(p, m) ( *(u32*)(p) == (u32)magic_##m )/* * Specialised magic comparison macros for the NTFS_RECORD_TYPES defined above. */#define ntfs_is_file_record(x) ( ntfs_is_magic (x, FILE) )#define ntfs_is_file_recordp(p) ( ntfs_is_magicp(p, FILE) )#define ntfs_is_mft_record(x) ( ntfs_is_file_record(x) )#define ntfs_is_mft_recordp(p) ( ntfs_is_file_recordp(p) )#define ntfs_is_indx_record(x) ( ntfs_is_magic (x, INDX) )#define ntfs_is_indx_recordp(p) ( ntfs_is_magicp(p, INDX) )#define ntfs_is_hole_record(x) ( ntfs_is_magic (x, HOLE) )#define ntfs_is_hole_recordp(p) ( ntfs_is_magicp(p, HOLE) )#define ntfs_is_rstr_record(x) ( ntfs_is_magic (x, RSTR) )#define ntfs_is_rstr_recordp(p) ( ntfs_is_magicp(p, RSTR) )#define ntfs_is_rcrd_record(x) ( ntfs_is_magic (x, RCRD) )#define ntfs_is_rcrd_recordp(p) ( ntfs_is_magicp(p, RCRD) )#define ntfs_is_chkd_record(x) ( ntfs_is_magic (x, CHKD) )#define ntfs_is_chkd_recordp(p) ( ntfs_is_magicp(p, CHKD) )#define ntfs_is_baad_record(x) ( ntfs_is_magic (x, BAAD) )#define ntfs_is_baad_recordp(p) ( ntfs_is_magicp(p, BAAD) )#define ntfs_is_empty_record(x) ( ntfs_is_magic (x, empty) )#define ntfs_is_empty_recordp(p) ( ntfs_is_magicp(p, empty) )#define NTFS_BLOCK_SIZE 512#define NTFS_BLOCK_SIZE_BITS 9/** * struct NTFS_RECORD - * * The Update Sequence Array (usa) is an array of the u16 values which belong * to the end of each sector protected by the update sequence record in which * this array is contained. Note that the first entry is the Update Sequence * Number (usn), a cyclic counter of how many times the protected record has * been written to disk. The values 0 and -1 (ie. 0xffff) are not used. All * last u16's of each sector have to be equal to the usn (during reading) or * are set to it (during writing). If they are not, an incomplete multi sector * transfer has occurred when the data was written. * The maximum size for the update sequence array is fixed to: * maximum size = usa_ofs + (usa_count * 2) = 510 bytes * The 510 bytes comes from the fact that the last u16 in the array has to * (obviously) finish before the last u16 of the first 512-byte sector. * This formula can be used as a consistency check in that usa_ofs + * (usa_count * 2) has to be less than or equal to 510. */typedef struct { NTFS_RECORD_TYPES magic;/* A four-byte magic identifying the record type and/or status. */ u16 usa_ofs; /* Offset to the Update Sequence Array (usa) from the start of the ntfs record. */ u16 usa_count; /* Number of u16 sized entries in the usa including the Update Sequence Number (usn), thus the number of fixups is the usa_count minus 1. */} __attribute__((__packed__)) NTFS_RECORD;/** * enum NTFS_SYSTEM_FILES - System files mft record numbers. * * All these files are always marked as used in the bitmap attribute of the * mft; presumably in order to avoid accidental allocation for random other * mft records. Also, the sequence number for each of the system files is * always equal to their mft record number and it is never modified. */typedef enum { FILE_MFT = 0, /* Master file table (mft). Data attribute contains the entries and bitmap attribute records which ones are in use (bit==1). */ FILE_MFTMirr = 1, /* Mft mirror: copy of first four mft records in data attribute. If cluster size > 4kiB, copy of first N mft records, with N = cluster_size / mft_record_size. */ FILE_LogFile = 2, /* Journalling log in data attribute. */ FILE_Volume = 3, /* Volume name attribute and volume information attribute (flags and ntfs version). Windows refers to this file as volume DASD (Direct Access Storage Device). */ FILE_AttrDef = 4, /* Array of attribute definitions in data attribute. */ FILE_root = 5, /* Root directory. */ FILE_Bitmap = 6, /* Allocation bitmap of all clusters (lcns) in data attribute. */ FILE_Boot = 7, /* Boot sector (always at cluster 0) in data attribute. */ FILE_BadClus = 8, /* Contains all bad clusters in the non-resident data attribute. */ FILE_Secure = 9, /* Shared security descriptors in data attribute and two indexes into the descriptors. Appeared in Windows 2000. Before that, this file was named $Quota but was unused. */ FILE_UpCase = 10, /* Uppercase equivalents of all 65536 Unicode characters in data attribute. */ FILE_Extend = 11, /* Directory containing other system files (eg. $ObjId, $Quota, $Reparse and $UsnJrnl). This is new to NTFS3.0. */ FILE_reserved12 = 12, /* Reserved for future use (records 12-15). */ FILE_reserved13 = 13, FILE_reserved14 = 14, FILE_reserved15 = 15, FILE_first_user = 16, /* First user file, used as test limit for whether to allow opening a file or not. */} NTFS_SYSTEM_FILES;/** * enum MFT_RECORD_FLAGS - * * These are the so far known MFT_RECORD_* flags (16-bit) which contain * information about the mft record in which they are present. * * MFT_RECORD_IS_4 exists on all $Extend sub-files. * It seems that it marks it is a metadata file with MFT record >24, however, * it is unknown if it is limited to metadata files only. * * MFT_RECORD_IS_VIEW_INDEX exists on every metafile with a non directory * index, that means an INDEX_ROOT and an INDEX_ALLOCATION with a name other * than "$I30". It is unknown if it is limited to metadata files only. */typedef enum { MFT_RECORD_IN_USE = const_cpu_to_le16(0x0001), MFT_RECORD_IS_DIRECTORY = const_cpu_to_le16(0x0002), MFT_RECORD_IS_4 = const_cpu_to_le16(0x0004), MFT_RECORD_IS_VIEW_INDEX = const_cpu_to_le16(0x0008), MFT_REC_SPACE_FILLER = 0xffff, /* Just to make flags 16-bit. */} __attribute__((__packed__)) MFT_RECORD_FLAGS;/* * mft references (aka file references or file record segment references) are * used whenever a structure needs to refer to a record in the mft. * * A reference consists of a 48-bit index into the mft and a 16-bit sequence * number used to detect stale references. * * For error reporting purposes we treat the 48-bit index as a signed quantity. * * The sequence number is a circular counter (skipping 0) describing how many * times the referenced mft record has been (re)used. This has to match the * sequence number of the mft record being referenced, otherwise the reference * is considered stale and removed (FIXME: only ntfsck or the driver itself?). * * If the sequence number is zero it is assumed that no sequence number * consistency checking should be performed. * * FIXME: Since inodes are 32-bit as of now, the driver needs to always check * for high_part being 0 and if not either BUG(), cause a panic() or handle * the situation in some other way. This shouldn't be a problem as a volume has * to become HUGE in order to need more than 32-bits worth of mft records. * Assuming the standard mft record size of 1kb only the records (never mind * the non-resident attributes, etc.) would require 4Tb of space on their own * for the first 32 bits worth of records. This is only if some strange person * doesn't decide to foul play and make the mft sparse which would be a really * horrible thing to do as it would trash our current driver implementation. )-: * Do I hear screams "we want 64-bit inodes!" ?!? (-; * * FIXME: The mft zone is defined as the first 12% of the volume. This space is * reserved so that the mft can grow contiguously and hence doesn't become * fragmented. Volume free space includes the empty part of the mft zone and * when the volume's free 88% are used up, the mft zone is shrunk by a factor * of 2, thus making more space available for more files/data. This process is * repeated every time there is no more free space except for the mft zone until * there really is no more free space. *//* * Typedef the MFT_REF as a 64-bit value for easier handling. * Also define two unpacking macros to get to the reference (MREF) and * sequence number (MSEQNO) respectively. * The _LE versions are to be applied on little endian MFT_REFs. * Note: The _LE versions will return a CPU endian formatted value! */#define MFT_REF_MASK_CPU 0x0000ffffffffffffULL#define MFT_REF_MASK_LE const_cpu_to_le64(MFT_REF_MASK_CPU)typedef u64 MFT_REF;#define MK_MREF(m, s) ((MFT_REF)(((MFT_REF)(s) << 48) | \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -