⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 layout.h

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 H
📖 第 1 页 / 共 5 页
字号:
/* 18*/	u16 link_count; 	/* Number of hard links, i.e. the number of
				   directory entries referencing this record.
				   NOTE: Only used in mft base records.
				   NOTE: When deleting a directory entry we
				   check the link_count and if it is 1 we
				   delete the file. Otherwise we delete the
				   FILE_NAME_ATTR being referenced by the
				   directory entry from the mft record and
				   decrement the link_count.
				   FIXME: Careful with Win32 + DOS names! */
/* 20*/	u16 attrs_offset;	/* Byte offset to the first attribute in this
				   mft record from the start of the mft record.
				   NOTE: Must be aligned to 8-byte boundary. */
/* 22*/	MFT_RECORD_FLAGS flags;	/* Bit array of MFT_RECORD_FLAGS. When a file
				   is deleted, the MFT_RECORD_IN_USE flag is
				   set to zero. */
/* 24*/	u32 bytes_in_use;	/* Number of bytes used in this mft record.
				   NOTE: Must be aligned to 8-byte boundary. */
/* 28*/	u32 bytes_allocated;	/* Number of bytes allocated for this mft
				   record. This should be equal to the mft
				   record size. */
/* 32*/	MFT_REF base_mft_record; /* This is zero for base mft records.
				   When it is not zero it is a mft reference
				   pointing to the base mft record to which
				   this record belongs (this is then used to
				   locate the attribute list attribute present
				   in the base record which describes this
				   extension record and hence might need
				   modification when the extension record
				   itself is modified, also locating the
				   attribute list also means finding the other
				   potential extents, belonging to the non-base
				   mft record). */
/* 40*/	u16 next_attr_instance;	/* The instance number that will be
				   assigned to the next attribute added to this
				   mft record. NOTE: Incremented each time
				   after it is used. NOTE: Every time the mft
				   record is reused this number is set to zero.
				   NOTE: The first instance number is always 0.
				 */
/* sizeof() = 42 bytes */
/* NTFS 3.1+ (Windows XP and above) introduce the following additions. */
/* 42*/ //u16 reserved;		/* Reserved/alignment. */
/* 44*/ //u32 mft_record_number;/* Number of this mft record. */
/* sizeof() = 48 bytes */
/*
 * When (re)using the mft record, we place the update sequence array at this
 * offset, i.e. before we start with the attributes. This also makes sense,
 * otherwise we could run into problems with the update sequence array
 * containing in itself the last two bytes of a sector which would mean that
 * multi sector transfer protection wouldn't work. As you can't protect data
 * by overwriting it since you then can't get it back...
 * When reading we obviously use the data from the ntfs record header.
 */
} __attribute__ ((__packed__)) MFT_RECORD;

/*
 * System defined attributes (32-bit). Each attribute type has a corresponding
 * attribute name (Unicode string of maximum 64 character length) as described
 * by the attribute definitions present in the data attribute of the $AttrDef
 * system file. On NTFS 3.0 volumes the names are just as the types are named
 * in the below enum exchanging AT_ for the dollar sign ($). If that isn't a
 * revealing choice of symbol... (-;
 */
typedef enum {
	AT_UNUSED			= const_cpu_to_le32(         0),
	AT_STANDARD_INFORMATION		= const_cpu_to_le32(      0x10),
	AT_ATTRIBUTE_LIST		= const_cpu_to_le32(      0x20),
	AT_FILE_NAME			= const_cpu_to_le32(      0x30),
	AT_OBJECT_ID			= const_cpu_to_le32(      0x40),
	AT_SECURITY_DESCRIPTOR		= const_cpu_to_le32(      0x50),
	AT_VOLUME_NAME			= const_cpu_to_le32(      0x60),
	AT_VOLUME_INFORMATION		= const_cpu_to_le32(      0x70),
	AT_DATA				= const_cpu_to_le32(      0x80),
	AT_INDEX_ROOT			= const_cpu_to_le32(      0x90),
	AT_INDEX_ALLOCATION		= const_cpu_to_le32(      0xa0),
	AT_BITMAP			= const_cpu_to_le32(      0xb0),
	AT_REPARSE_POINT		= const_cpu_to_le32(      0xc0),
	AT_EA_INFORMATION		= const_cpu_to_le32(      0xd0),
	AT_EA				= const_cpu_to_le32(      0xe0),
	AT_PROPERTY_SET			= const_cpu_to_le32(      0xf0),
	AT_LOGGED_UTILITY_STREAM	= const_cpu_to_le32(     0x100),
	AT_FIRST_USER_DEFINED_ATTRIBUTE	= const_cpu_to_le32(    0x1000),
	AT_END				= const_cpu_to_le32(0xffffffff),
} ATTR_TYPES;

/*
 * The collation rules for sorting views/indexes/etc (32-bit).
 *
 * COLLATION_UNICODE_STRING - Collate Unicode strings by comparing their binary
 *	Unicode values, except that when a character can be uppercased, the
 *	upper case value collates before the lower case one.
 * COLLATION_FILE_NAME - Collate file names as Unicode strings. The collation
 *	is done very much like COLLATION_UNICODE_STRING. In fact I have no idea
 *	what the difference is. Perhaps the difference is that file names
 *	would treat some special characters in an odd way (see
 *	unistr.c::ntfs_collate_names() and unistr.c::legal_ansi_char_array[]
 *	for what I mean but COLLATION_UNICODE_STRING would not give any special
 *	treatment to any characters at all, but this is speculation.
 * COLLATION_NTOFS_ULONG - Sorting is done according to ascending u32 key
 * 	values. E.g. used for $SII index in FILE_Secure, which sorts by
 * 	security_id (u32).
 * COLLATION_NTOFS_SID - Sorting is done according to ascending SID values.
 * 	E.g. used for $O index in FILE_Extend/$Quota.
 * COLLATION_NTOFS_SECURITY_HASH - Sorting is done first by ascending hash
 * 	values and second by ascending security_id values. E.g. used for $SDH
 * 	index in FILE_Secure.
 * COLLATION_NTOFS_ULONGS - Sorting is done according to a sequence of ascending
 *	u32 key values. E.g. used for $O index in FILE_Extend/$ObjId, which
 *	sorts by object_id (16-byte), by splitting up the object_id in four
 *	u32 values and using them as individual keys. E.g. take the following
 *	two security_ids, stored as follows on disk:
 *		1st: a1 61 65 b7 65 7b d4 11 9e 3d 00 e0 81 10 42 59
 *		2nd: 38 14 37 d2 d2 f3 d4 11 a5 21 c8 6b 79 b1 97 45
 *	To compare them, they are split into four u32 values each, like so:
 *		1st: 0xb76561a1 0x11d47b65 0xe0003d9e 0x59421081
 *		2nd: 0xd2371438 0x11d4f3d2 0x6bc821a5 0x4597b179
 *	Now, it is apparent why the 2nd object_id collates after the 1st: the
 *	first u32 value of the 1st object_id is less than the first u32 of
 *	the 2nd object_id. If the first u32 values of both object_ids were
 *	equal then the second u32 values would be compared, etc.
 */
typedef enum {
	COLLATION_BINARY	 = const_cpu_to_le32(0), /* Collate by binary
					compare where the first byte is most
					significant. */
	COLLATION_FILE_NAME	 = const_cpu_to_le32(1), /* Collate file names
					as Unicode strings. */
	COLLATION_UNICODE_STRING = const_cpu_to_le32(2), /* Collate Unicode
					strings by comparing their binary
					Unicode values, except that when a
					character can be uppercased, the upper
					case value collates before the lower
					case one. */
	COLLATION_NTOFS_ULONG		= const_cpu_to_le32(16),
	COLLATION_NTOFS_SID		= const_cpu_to_le32(17),
	COLLATION_NTOFS_SECURITY_HASH	= const_cpu_to_le32(18),
	COLLATION_NTOFS_ULONGS		= const_cpu_to_le32(19),
} COLLATION_RULES;

/*
 * The flags (32-bit) describing attribute properties in the attribute
 * definition structure. FIXME: This information is from Regis's information
 * and, according to him, it is not certain and probably incomplete.
 * The INDEXABLE flag is fairly certainly correct as only the file name
 * attribute has this flag set and this is the only attribute indexed in NT4.
 */
typedef enum {
	INDEXABLE	    = const_cpu_to_le32(0x02),	/* Attribute can be
							   indexed. */
	NEED_TO_REGENERATE  = const_cpu_to_le32(0x40),	/* Need to regenerate
							   during regeneration
							   phase. */
	CAN_BE_NON_RESIDENT = const_cpu_to_le32(0x80),	/* Attribute can be
							   non-resident. */
} ATTR_DEF_FLAGS;

/*
 * The data attribute of FILE_AttrDef contains a sequence of attribute
 * definitions for the NTFS volume. With this, it is supposed to be safe for an
 * older NTFS driver to mount a volume containing a newer NTFS version without
 * damaging it (that's the theory. In practice it's: not damaging it too much).
 * Entries are sorted by attribute type. The flags describe whether the
 * attribute can be resident/non-resident and possibly other things, but the
 * actual bits are unknown.
 */
typedef struct {
/*hex ofs*/
/*  0*/	uchar_t name[0x40];		/* Unicode name of the attribute. Zero
					   terminated. */
/* 80*/	ATTR_TYPES type;		/* Type of the attribute. */
/* 84*/	u32 display_rule;		/* Default display rule.
					   FIXME: What does it mean? (AIA) */
/* 88*/ COLLATION_RULES collation_rule;	/* Default collation rule. */
/* 8c*/	ATTR_DEF_FLAGS flags;		/* Flags describing the attribute. */
/* 90*/	u64 min_size;			/* Optional minimum attribute size. */
/* 98*/	u64 max_size;			/* Maximum size of attribute. */
/* sizeof() = 0xa0 or 160 bytes */
} __attribute__ ((__packed__)) ATTR_DEF;

/*
 * Attribute flags (16-bit).
 */
typedef enum {
	ATTR_IS_COMPRESSED	= const_cpu_to_le16(0x0001),
	ATTR_COMPRESSION_MASK	= const_cpu_to_le16(0x00ff),  /* Compression
						method mask. Also, first
						illegal value. */
	ATTR_IS_ENCRYPTED	= const_cpu_to_le16(0x4000),
	ATTR_IS_SPARSE		= const_cpu_to_le16(0x8000),
} __attribute__ ((__packed__)) ATTR_FLAGS;

/*
 * Attribute compression.
 *
 * Only the data attribute is ever compressed in the current ntfs driver in
 * Windows. Further, compression is only applied when the data attribute is
 * non-resident. Finally, to use compression, the maximum allowed cluster size
 * on a volume is 4kib.
 *
 * The compression method is based on independently compressing blocks of X
 * clusters, where X is determined from the compression_unit value found in the
 * non-resident attribute record header (more precisely: X = 2^compression_unit
 * clusters). On Windows NT/2k, X always is 16 clusters (compression_unit = 4).
 *
 * There are three different cases of how a compression block of X clusters
 * can be stored:
 *
 *   1) The data in the block is all zero (a sparse block):
 *	  This is stored as a sparse block in the run list, i.e. the run list
 *	  entry has length = X and lcn = -1. The mapping pairs array actually
 *	  uses a delta_lcn value length of 0, i.e. delta_lcn is not present at
 *	  all, which is then interpreted by the driver as lcn = -1.
 *	  NOTE: Even uncompressed files can be sparse on NTFS 3.0 volumes, then
 *	  the same principles apply as above, except that the length is not
 *	  restricted to being any particular value.
 *
 *   2) The data in the block is not compressed:
 *	  This happens when compression doesn't reduce the size of the block
 *	  in clusters. I.e. if compression has a small effect so that the
 *	  compressed data still occupies X clusters, then the uncompressed data
 *	  is stored in the block.
 *	  This case is recognised by the fact that the run list entry has
 *	  length = X and lcn >= 0. The mapping pairs array stores this as
 *	  normal with a run length of X and some specific delta_lcn, i.e.
 *	  delta_lcn has to be present.
 *
 *   3) The data in the block is compressed:
 *	  The common case. This case is recognised by the fact that the run
 *	  list entry has length L < X and lcn >= 0. The mapping pairs array
 *	  stores this as normal with a run length of X and some specific
 *	  delta_lcn, i.e. delta_lcn has to be present. This run list entry is
 *	  immediately followed by a sparse entry with length = X - L and
 *	  lcn = -1. The latter entry is to make up the vcn counting to the
 *	  full compression block size X.
 *
 * In fact, life is more complicated because adjacent entries of the same type
 * can be coalesced. This means that one has to keep track of the number of
 * clusters handled and work on a basis of X clusters at a time being one
 * block. An example: if length L > X this means that this particular run list
 * entry contains a block of length X and part of one or more blocks of length
 * L - X. Another example: if length L < X, this does not necessarily mean that
 * the block is compressed as it might be that the lcn changes inside the block
 * and hence the following run list entry describes the continuation of the
 * potentially compressed block. The block would be compressed if the
 * following run list entry describes at least X - L sparse clusters, thus
 * making up the compression block length as described in point 3 above. (Of
 * course, there can be several run list entries with small lengths so that the
 * sparse entry does not follow the first data containing entry with
 * length < X.)
 *
 * NOTE: At the end of the compressed attribute value, there most likely is not
 * just the right amount of data to make up a compression block, thus this data
 * is not even attempted to be compressed. It is just stored as is, unless
 * the number of clusters it occupies is reduced when compressed in which case
 * it is stored as a compressed compression block, complete with sparse
 * clusters at the end.
 */

/*
 * Flags of resident attributes (8-bit).
 */
typedef enum {
	RESIDENT_ATTR_IS_INDEXED = 0x01, /* Attribute is referenced in an index
					    (has implications for deleting and
					    modifying the attribute). */
} __attribute__ ((__packed__)) RESIDENT_ATTR_FLAGS;

/*
 * Attribute record header. Always aligned to 8-byte boundary.
 */
typedef struct {
/*Ofs*/
/*  0*/	ATTR_TYPES type;	/* The (32-bit) type of the attribute. */
/*  4*/	u32 length;		/* Byte size of the resident part of the
				   attribute (aligned to 8-byte boundary).
				   Used to get to the next attribute. */
/*  8*/	u8 non_resident;	/* If 0, attribute is resident.
				   If 1, attribute is non-resident. */
/*  9*/	u8 name_length;		/* Unicode character size of name of attribute.
				   0 if unnamed. */
/* 10*/	u16 name_offset;	/* If name_length != 0, the byte offset to the
				   beginning of the name from the attribute
				   record. Note that the name is stored as a
				   Unicode string. When creating, place offset
				   just at the end of the record header. Then,
				   follow with attribute value or mapping pairs
				   array, resident and non-resident attributes
				   respectively, aligning to an 8-byte
				   boundary. */
/* 12*/	ATTR_FLAGS flags;	/* Flags describing the attribute. */
/* 14*/	u16 instance;		/* The instance of this attribute record. This
				   number is unique within this mft record (see
				   MFT_RECORD/next_attribute_instance notes in
				   in mft.h for more details). */
/* 16*/	union {
		/* Resident attributes. */
		struct {
/* 16 */		u32 value_length; /* Byte size of attribute value. */
/* 20 */		u16 value_offset; /* Byte offset of the attribute
					     value from the start of the
					     attribute record. When creating,
					     align to 8-byte boundary if we
					     have a name present as this might
					     not have a length of a multiple
					     of 8-bytes. */
/* 22 */		RESIDENT_ATTR_FLAGS flags; /* See above. */
/* 23 */		s8 reserved;	  /* Reserved/alignment to 8-byte
					     boundary. */
		} __attribute__ ((__packed__)) resident;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -