1 | /* $Id: ntfs.h 106061 2024-09-16 14:03:52Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * IPRT, NT File System (NTFS).
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2017-2024 Oracle and/or its affiliates.
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox base platform packages, as
|
---|
10 | * available from https://www.virtualbox.org.
|
---|
11 | *
|
---|
12 | * This program is free software; you can redistribute it and/or
|
---|
13 | * modify it under the terms of the GNU General Public License
|
---|
14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
15 | * License.
|
---|
16 | *
|
---|
17 | * This program is distributed in the hope that it will be useful, but
|
---|
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
20 | * General Public License for more details.
|
---|
21 | *
|
---|
22 | * You should have received a copy of the GNU General Public License
|
---|
23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
24 | *
|
---|
25 | * The contents of this file may alternatively be used under the terms
|
---|
26 | * of the Common Development and Distribution License Version 1.0
|
---|
27 | * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
|
---|
28 | * in the VirtualBox distribution, in which case the provisions of the
|
---|
29 | * CDDL are applicable instead of those of the GPL.
|
---|
30 | *
|
---|
31 | * You may elect to license modified versions of this file under the
|
---|
32 | * terms and conditions of either the GPL or the CDDL or both.
|
---|
33 | *
|
---|
34 | * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
|
---|
35 | */
|
---|
36 |
|
---|
37 | #ifndef IPRT_INCLUDED_formats_ntfs_h
|
---|
38 | #define IPRT_INCLUDED_formats_ntfs_h
|
---|
39 | #ifndef RT_WITHOUT_PRAGMA_ONCE
|
---|
40 | # pragma once
|
---|
41 | #endif
|
---|
42 |
|
---|
43 | #include <iprt/formats/fat.h>
|
---|
44 |
|
---|
45 |
|
---|
46 | /** @defgroup grp_rt_formats_ntfs NT File System (NTFS) structures and definitions
|
---|
47 | * @ingroup grp_rt_formats
|
---|
48 | * @{
|
---|
49 | */
|
---|
50 |
|
---|
51 | /** Value of the FATBOOTSECTOR::achOemName for an NTFS file system. */
|
---|
52 | #define NTFS_OEM_ID_MAGIC "NTFS "
|
---|
53 |
|
---|
54 |
|
---|
55 | /** @name NTFS_MFT_IDX_XXX - Predefined MFT indexes.
|
---|
56 | * @{ */
|
---|
57 | #define NTFS_MFT_IDX_MFT 0 /**< The MFT itself. */
|
---|
58 | #define NTFS_MFT_IDX_MFT_MIRROR 1 /**< Mirror MFT (partial?). */
|
---|
59 | #define NTFS_MFT_IDX_LOG_FILE 2 /**< Journalling log. */
|
---|
60 | #define NTFS_MFT_IDX_VOLUME 3 /**< Volume attributes. */
|
---|
61 | #define NTFS_MFT_IDX_ATTRIB_DEF 4 /**< Attribute definitions. */
|
---|
62 | #define NTFS_MFT_IDX_ROOT 5 /**< The root directory. */
|
---|
63 | #define NTFS_MFT_IDX_BITMAP 6 /**< Allocation bitmap. */
|
---|
64 | #define NTFS_MFT_IDX_BOOT 7 /**< The boot sector. */
|
---|
65 | #define NTFS_MFT_IDX_BAD_CLUSTER 8 /**< Bad cluster table. */
|
---|
66 | #define NTFS_MFT_IDX_SECURITY 9 /**< Shared security descriptors (w2k and later). */
|
---|
67 | #define NTFS_MFT_IDX_UP_CASE 10 /**< Unicode upper case table. */
|
---|
68 | #define NTFS_MFT_IDX_EXTEND 11 /**< Directory containing further system files. */
|
---|
69 | #define NTFS_MFT_IDX_FIRST_USER 16 /**< The first user file. */
|
---|
70 | /** @} */
|
---|
71 |
|
---|
72 | /**
|
---|
73 | * NTFS MFT record reference.
|
---|
74 | */
|
---|
75 | typedef union NTFSMFTREF
|
---|
76 | {
|
---|
77 | /** unsigned 64-bit view. */
|
---|
78 | uint64_t u64;
|
---|
79 | /** unsigned 32-bit view. */
|
---|
80 | uint32_t au32[2];
|
---|
81 | /** unsigned 16-bit view. */
|
---|
82 | uint16_t au16[4];
|
---|
83 |
|
---|
84 | /** Structured view. */
|
---|
85 | struct
|
---|
86 | {
|
---|
87 | /** Index of the master file table record. */
|
---|
88 | RT_GCC_EXTENSION uint64_t idxMft : 48;
|
---|
89 | /** MFT record reuse sequence number (for catching dangling references). */
|
---|
90 | RT_GCC_EXTENSION uint64_t uRecReuseSeqNo : 16;
|
---|
91 | } s;
|
---|
92 | } NTFSMFTREF;
|
---|
93 | AssertCompileSize(NTFSMFTREF, 8);
|
---|
94 | /** Pointer to a NTFS MFT record reference. */
|
---|
95 | typedef NTFSMFTREF *PNTFSMFTREF;
|
---|
96 | /** Pointer to a const NTFS MFT record reference. */
|
---|
97 | typedef NTFSMFTREF const *PCNTFSMFTREF;
|
---|
98 |
|
---|
99 | /** @name NTFSMFTREF_GET_IDX
|
---|
100 | * Gets the MFT index number (host endian) from a MFT reference. */
|
---|
101 | /** @name NTFSMFTREF_GET_SEQ
|
---|
102 | * Gets the MFT reuse sequence number (host endian) from a MFT reference. */
|
---|
103 | /** @name NTFSMFTREF_SET_IDX
|
---|
104 | * Sets the MFT index number of a MFT reference. */
|
---|
105 | /** @name NTFSMFTREF_SET_SEQ
|
---|
106 | * Sets the MFT reuse sequence number of a MFT reference. */
|
---|
107 | /** @name NTFSMFTREF_SET
|
---|
108 | * Sets the values of a MFT reference. */
|
---|
109 | #ifdef RT_LITTLE_ENDIAN
|
---|
110 | # define NTFSMFTREF_GET_IDX(a_pMftRef) ((a_pMftRef)->s.idxMft)
|
---|
111 | # define NTFSMFTREF_GET_SEQ(a_pMftRef) ((a_pMftRef)->s.uRecReuseSeqNo)
|
---|
112 | # define NTFSMFTREF_SET_SEQ(a_pMftRef, a_uValue) do { (a_pMftRef)->s.uRecReuseSeqNo = (a_uValue); } while (0)
|
---|
113 | # define NTFSMFTREF_SET_IDX(a_pMftRef, a_uValue) do { (a_pMftRef)->s.idxMft = (a_uValue); } while (0)
|
---|
114 | # define NTFSMFTREF_SET(a_pMftRef, a_idx, a_uSeq) \
|
---|
115 | do { \
|
---|
116 | (a_pMftRef)->s.idxMft = (a_idx); \
|
---|
117 | (a_pMftRef)->s.uRecReuseSeqNo = (a_uSeq); \
|
---|
118 | } while (0)
|
---|
119 | #else
|
---|
120 | # define NTFSMFTREF_GET_IDX(a_pMftRef) (RT_LE2H_U64((a_pMftRef)->u64) & UINT64_C(0x0000ffffffffffff))
|
---|
121 | # define NTFSMFTREF_GET_SEQ(a_pMftRef) RT_LE2H_U16((uint16_t)(a_pMftRef)->u64)
|
---|
122 | # define NTFSMFTREF_SET_SEQ(a_pMftRef, a_uValue) do { (a_pMftRef)->au16[3] = RT_H2LE_U16(a_uValue); } while (0)
|
---|
123 | # define NTFSMFTREF_SET_IDX(a_pMftRef, a_uValue) \
|
---|
124 | do { \
|
---|
125 | (a_pMftRef)->au32[0] = RT_H2LE_U32((uint32_t)(a_uValue)); \
|
---|
126 | (a_pMftRef)->au16[2] = RT_H2LE_U16((uint16_t)((a_uValue) >> 32)); \
|
---|
127 | } while (0)
|
---|
128 | # define NTFSMFTREF_SET(a_pMftRef, a_idx, a_uSeq) \
|
---|
129 | do { \
|
---|
130 | (a_pMftRef)->au32[0] = RT_H2LE_U32((uint32_t)(a_idx)); \
|
---|
131 | (a_pMftRef)->au16[2] = RT_H2LE_U16((uint16_t)((a_idx) >> 32)); \
|
---|
132 | (a_pMftRef)->au16[3] = RT_H2LE_U16((uint16_t)(a_uSeq)); \
|
---|
133 | } while (0)
|
---|
134 | #endif
|
---|
135 | /** Check that the reference is zero. */
|
---|
136 | #define NTFSMFTREF_IS_ZERO(a_pMftRef) ((a_pMftRef)->u64 == 0)
|
---|
137 |
|
---|
138 |
|
---|
139 | /**
|
---|
140 | * NTFS record header.
|
---|
141 | */
|
---|
142 | typedef struct NTFSRECHDR
|
---|
143 | {
|
---|
144 | /** Magic number (usually ASCII). */
|
---|
145 | uint32_t uMagic;
|
---|
146 | /** Offset of the update sequence array from the start of the record. */
|
---|
147 | uint16_t offUpdateSeqArray;
|
---|
148 | /** Number of entries in the update sequence array. (uint16_t sized entries) */
|
---|
149 | uint16_t cUpdateSeqEntries;
|
---|
150 | } NTFSRECHDR;
|
---|
151 | AssertCompileSize(NTFSRECHDR, 8);
|
---|
152 | /** Pointer to a NTFS record header. */
|
---|
153 | typedef NTFSRECHDR *PNTFSRECHDR;
|
---|
154 | /** Pointer to a const NTFS record header. */
|
---|
155 | typedef NTFSRECHDR const *PCNTFSRECHDR;
|
---|
156 |
|
---|
157 | /** The multi-sector update sequence stride.
|
---|
158 | * @see https://msdn.microsoft.com/en-us/library/bb470212%28v=vs.85%29.aspx
|
---|
159 | * @see NTFSRECHDR::offUpdateSeqArray, NTFSRECHDR::cUpdateSeqEntries
|
---|
160 | */
|
---|
161 | #define NTFS_MULTI_SECTOR_STRIDE 512
|
---|
162 |
|
---|
163 |
|
---|
164 | /**
|
---|
165 | * NTFS file record (in the MFT).
|
---|
166 | */
|
---|
167 | typedef struct NTFSRECFILE
|
---|
168 | {
|
---|
169 | /** 0x00: Header with NTFSREC_MAGIC_FILE. */
|
---|
170 | NTFSRECHDR Hdr;
|
---|
171 | /** 0x08: Log file sequence number. */
|
---|
172 | uint64_t uLsn;
|
---|
173 | /** 0x10: MFT record reuse sequence number (for dangling MFT references). */
|
---|
174 | uint16_t uRecReuseSeqNo;
|
---|
175 | /** 0x12: Number of hard links. */
|
---|
176 | uint16_t cLinks;
|
---|
177 | /** 0x14: Offset of the first attribute (relative to start of record). */
|
---|
178 | uint16_t offFirstAttrib;
|
---|
179 | /** 0x16: Record flags (NTFSRECFILE_F_XXX). */
|
---|
180 | uint16_t fFlags;
|
---|
181 | /** 0x18: Number of byte in use in this MFT record. */
|
---|
182 | uint32_t cbRecUsed;
|
---|
183 | /** 0x1c: The MFT record size. */
|
---|
184 | uint32_t cbRecSize;
|
---|
185 | /** 0x20: Reference to the base MFT record. */
|
---|
186 | NTFSMFTREF BaseMftRec;
|
---|
187 | /** 0x28: Next attribute instance number. */
|
---|
188 | uint16_t idNextAttrib;
|
---|
189 | /** 0x2a: Padding if NTFS 3.1+, update sequence array if older. */
|
---|
190 | uint16_t uPaddingOrUsa;
|
---|
191 | /** 0x2c: MFT index of this record. */
|
---|
192 | uint32_t idxMftSelf;
|
---|
193 | } NTFSRECFILE;
|
---|
194 | AssertCompileSize(NTFSRECFILE, 0x30);
|
---|
195 | /** Pointer to a NTFS file record. */
|
---|
196 | typedef NTFSRECFILE *PNTFSRECFILE;
|
---|
197 | /** Pointer to a const NTFS file record. */
|
---|
198 | typedef NTFSRECFILE const *PCNTFSRECFILE;
|
---|
199 |
|
---|
200 |
|
---|
201 | /** NTFS 'FILE' record magic value. */
|
---|
202 | #define NTFSREC_MAGIC_FILE RT_H2LE_U32_C(UINT32_C(0x454c4946))
|
---|
203 |
|
---|
204 | /** @name NTFSRECFILE_F_XXX - NTFSRECFILE::fFlags.
|
---|
205 | * @{ */
|
---|
206 | /** MFT record is in use. */
|
---|
207 | #define NTFSRECFILE_F_IN_USE RT_H2LE_U16_C(UINT16_C(0x0001))
|
---|
208 | /** Directory record. */
|
---|
209 | #define NTFSRECFILE_F_DIRECTORY RT_H2LE_U16_C(UINT16_C(0x0002))
|
---|
210 | /** @} */
|
---|
211 |
|
---|
212 |
|
---|
213 | /** @name NTFS_AT_XXX - Attribute types
|
---|
214 | * @{ */
|
---|
215 | #define NTFS_AT_UNUSED RT_H2LE_U32_C(UINT32_C(0x00000000))
|
---|
216 | /** NTFSATSTDINFO */
|
---|
217 | #define NTFS_AT_STANDARD_INFORMATION RT_H2LE_U32_C(UINT32_C(0x00000010))
|
---|
218 | /** NTFSATLISTENTRY */
|
---|
219 | #define NTFS_AT_ATTRIBUTE_LIST RT_H2LE_U32_C(UINT32_C(0x00000020))
|
---|
220 | /** NTFSATFILENAME */
|
---|
221 | #define NTFS_AT_FILENAME RT_H2LE_U32_C(UINT32_C(0x00000030))
|
---|
222 | #define NTFS_AT_OBJECT_ID RT_H2LE_U32_C(UINT32_C(0x00000040))
|
---|
223 | #define NTFS_AT_SECURITY_DESCRIPTOR RT_H2LE_U32_C(UINT32_C(0x00000050))
|
---|
224 | #define NTFS_AT_VOLUME_NAME RT_H2LE_U32_C(UINT32_C(0x00000060))
|
---|
225 | /** NTFSATVOLUMEINFO */
|
---|
226 | #define NTFS_AT_VOLUME_INFORMATION RT_H2LE_U32_C(UINT32_C(0x00000070))
|
---|
227 | #define NTFS_AT_DATA RT_H2LE_U32_C(UINT32_C(0x00000080))
|
---|
228 | /** NTFSATINDEXROOT */
|
---|
229 | #define NTFS_AT_INDEX_ROOT RT_H2LE_U32_C(UINT32_C(0x00000090))
|
---|
230 | #define NTFS_AT_INDEX_ALLOCATION RT_H2LE_U32_C(UINT32_C(0x000000a0))
|
---|
231 | #define NTFS_AT_BITMAP RT_H2LE_U32_C(UINT32_C(0x000000b0))
|
---|
232 | #define NTFS_AT_REPARSE_POINT RT_H2LE_U32_C(UINT32_C(0x000000c0))
|
---|
233 | #define NTFS_AT_EA_INFORMATION RT_H2LE_U32_C(UINT32_C(0x000000d0))
|
---|
234 | #define NTFS_AT_EA RT_H2LE_U32_C(UINT32_C(0x000000e0))
|
---|
235 | #define NTFS_AT_PROPERTY_SET RT_H2LE_U32_C(UINT32_C(0x000000f0))
|
---|
236 | #define NTFS_AT_LOGGED_UTILITY_STREAM RT_H2LE_U32_C(UINT32_C(0x00000100))
|
---|
237 | #define NTFS_AT_FIRST_USER_DEFINED RT_H2LE_U32_C(UINT32_C(0x00001000))
|
---|
238 | #define NTFS_AT_END RT_H2LE_U32_C(UINT32_C(0xffffffff))
|
---|
239 | /** @} */
|
---|
240 |
|
---|
241 | /** @name NTFS_AF_XXX - Attribute flags.
|
---|
242 | * @{ */
|
---|
243 | #define NTFS_AF_COMPR_FMT_NONE RT_H2LE_U16_C(UINT16_C(0x0000))
|
---|
244 | /** See RtlCompressBuffer / COMPRESSION_FORMAT_LZNT1. */
|
---|
245 | #define NTFS_AF_COMPR_FMT_LZNT1 RT_H2LE_U16_C(UINT16_C(0x0001))
|
---|
246 | /** See RtlCompressBuffer / COMPRESSION_FORMAT_XPRESS_HUFF. */
|
---|
247 | #define NTFS_AF_COMPR_FMT_XPRESS RT_H2LE_U16_C(UINT16_C(0x0002))
|
---|
248 | /** See RtlCompressBuffer / COMPRESSION_FORMAT_XPRESS_HUFF. */
|
---|
249 | #define NTFS_AF_COMPR_FMT_XPRESS_HUFF RT_H2LE_U16_C(UINT16_C(0x0003))
|
---|
250 | #define NTFS_AF_COMPR_FMT_MASK RT_H2LE_U16_C(UINT16_C(0x00ff))
|
---|
251 | #define NTFS_AF_ENCRYPTED RT_H2LE_U16_C(UINT16_C(0x4000))
|
---|
252 | #define NTFS_AF_SPARSE RT_H2LE_U16_C(UINT16_C(0x8000))
|
---|
253 | /** @} */
|
---|
254 |
|
---|
255 | /**
|
---|
256 | * NTFS attribute header.
|
---|
257 | *
|
---|
258 | * This has three forms:
|
---|
259 | * - Resident
|
---|
260 | * - Non-resident, no compression
|
---|
261 | * - Non-resident, compressed.
|
---|
262 | *
|
---|
263 | * Each form translates to a different header size.
|
---|
264 | */
|
---|
265 | typedef struct NTFSATTRIBHDR
|
---|
266 | {
|
---|
267 | /** 0x00: Attribute type (NTFS_AT_XXX). */
|
---|
268 | uint32_t uAttrType;
|
---|
269 | /** 0x04: Length of this attribute (resident part). */
|
---|
270 | uint32_t cbAttrib;
|
---|
271 | /** 0x08: Set (1) if non-resident attribute, 0 if resident. */
|
---|
272 | uint8_t fNonResident;
|
---|
273 | /** 0x09: Attribute name length (can be zero). */
|
---|
274 | uint8_t cwcName;
|
---|
275 | /** 0x0a: Offset of the name string (relative to the start of this header). */
|
---|
276 | uint16_t offName;
|
---|
277 | /** 0x0c: NTFS_AF_XXX. */
|
---|
278 | uint16_t fFlags;
|
---|
279 | /** 0x0e: Attribute instance number. Unique within the MFT record. */
|
---|
280 | uint16_t idAttrib;
|
---|
281 | /** 0x10: Data depending on the fNonResident member value. */
|
---|
282 | union
|
---|
283 | {
|
---|
284 | /** Resident attributes. */
|
---|
285 | struct
|
---|
286 | {
|
---|
287 | /** 0x10: Attribute value length. */
|
---|
288 | uint32_t cbValue;
|
---|
289 | /** 0x14: Offset of the value (relative to the start of this header). */
|
---|
290 | uint16_t offValue;
|
---|
291 | /** 0x16: NTFS_RES_AF_XXX. */
|
---|
292 | uint8_t fFlags;
|
---|
293 | /** 0x17: Reserved. */
|
---|
294 | uint8_t bReserved;
|
---|
295 | } Res;
|
---|
296 |
|
---|
297 | /** Non-resident attributes. */
|
---|
298 | struct
|
---|
299 | {
|
---|
300 | /** 0x10: The first virtual cluster containing data.
|
---|
301 | *
|
---|
302 | * This is mainly for internal checking when the run list doesn't fit in one
|
---|
303 | * MFT record. It can also be used to avoid recording a sparse run at the
|
---|
304 | * beginning of the data covered by this attribute record. */
|
---|
305 | int64_t iVcnFirst;
|
---|
306 | /** 0x18: The last virtual cluster containing data (inclusive). */
|
---|
307 | int64_t iVcnLast;
|
---|
308 | /** 0x20: Offset of the mapping pair program. This program gives us a mapping
|
---|
309 | * between VNC and LCN for the attribute value. */
|
---|
310 | uint16_t offMappingPairs;
|
---|
311 | /** 0x22: Power of two compression unit size in clusters (cbCluster << uCompessionUnit).
|
---|
312 | * Zero means uncompressed. */
|
---|
313 | uint8_t uCompressionUnit;
|
---|
314 | /** 0x23: Reserved */
|
---|
315 | uint8_t abReserved[5];
|
---|
316 | /** 0x28: Allocated size (rouneded to cluster).
|
---|
317 | * @note Only set in the first attribute record (iVcnFirst == 0). */
|
---|
318 | int64_t cbAllocated;
|
---|
319 | /** 0x30: The exact length of the data.
|
---|
320 | * @note Only set in the first attribute record (iVcnFirst == 0). */
|
---|
321 | int64_t cbData;
|
---|
322 | /** 0x38: The length of the initialized data. (Not necessarily
|
---|
323 | * rounded up to cluster size.)
|
---|
324 | * @note Only set in the first attribute record (iVcnFirst == 0). */
|
---|
325 | int64_t cbInitialized;
|
---|
326 | /** 0x40: Compressed size if compressed, otherwise absent. */
|
---|
327 | int64_t cbCompressed;
|
---|
328 | } NonRes;
|
---|
329 | } u;
|
---|
330 | } NTFSATTRIBHDR;
|
---|
331 | AssertCompileSize(NTFSATTRIBHDR, 0x48);
|
---|
332 | AssertCompileMemberOffset(NTFSATTRIBHDR, u.Res, 0x10);
|
---|
333 | AssertCompileMemberOffset(NTFSATTRIBHDR, u.Res.bReserved, 0x17);
|
---|
334 | AssertCompileMemberOffset(NTFSATTRIBHDR, u.NonRes, 0x10);
|
---|
335 | AssertCompileMemberOffset(NTFSATTRIBHDR, u.NonRes.cbCompressed, 0x40);
|
---|
336 | /** Pointer to a NTFS attribute header. */
|
---|
337 | typedef NTFSATTRIBHDR *PNTFSATTRIBHDR;
|
---|
338 | /** Pointer to a const NTFS attribute header. */
|
---|
339 | typedef NTFSATTRIBHDR const *PCNTFSATTRIBHDR;
|
---|
340 |
|
---|
341 | /** @name NTFSATTRIBHDR_SIZE_XXX - Attribute header sizes.
|
---|
342 | * @{ */
|
---|
343 | /** Attribute header size for resident values. */
|
---|
344 | #define NTFSATTRIBHDR_SIZE_RESIDENT (0x18)
|
---|
345 | /** Attribute header size for uncompressed non-resident values. */
|
---|
346 | #define NTFSATTRIBHDR_SIZE_NONRES_UNCOMPRESSED (0x40)
|
---|
347 | /** Attribute header size for compressed non-resident values. */
|
---|
348 | #define NTFSATTRIBHDR_SIZE_NONRES_COMPRESSED (0x48)
|
---|
349 | /** @} */
|
---|
350 |
|
---|
351 | /** Get the pointer to the embedded name from an attribute.
|
---|
352 | * @note ASSUMES the caller check that there is a name. */
|
---|
353 | #define NTFSATTRIBHDR_GET_NAME(a_pAttrHdr) ( (PRTUTF16)((uintptr_t)(a_pAttrHdr) + (a_pAttrHdr)->offName) )
|
---|
354 |
|
---|
355 | /** Get the pointer to resident value.
|
---|
356 | * @note ASSUMES the caller checks that it's resident and valid. */
|
---|
357 | #define NTFSATTRIBHDR_GET_RES_VALUE_PTR(a_pAttrHdr) ( (uint8_t *)(a_pAttrHdr) + (a_pAttrHdr)->u.Res.offValue )
|
---|
358 |
|
---|
359 |
|
---|
360 | /** @name NTFS_RES_AF_XXX
|
---|
361 | * @{ */
|
---|
362 | /** Attribute is referenced in an index. */
|
---|
363 | #define NTFS_RES_AF_INDEXED UINT8_C(0x01)
|
---|
364 | /** @} */
|
---|
365 |
|
---|
366 | /**
|
---|
367 | * Attribute list entry (NTFS_AT_ATTRIBUTE_LIST).
|
---|
368 | *
|
---|
369 | * This is used to deal with a file having attributes in more than one MFT
|
---|
370 | * record. A prominent example is an fragment file (unnamed data attribute)
|
---|
371 | * which mapping pairs doesn't fit in a single MFT record.
|
---|
372 | *
|
---|
373 | * This attribute can be non-resident, however it's mapping pair program must
|
---|
374 | * fit in the base MFT record.
|
---|
375 | */
|
---|
376 | typedef struct NTFSATLISTENTRY
|
---|
377 | {
|
---|
378 | /** 0x00: Attribute type (NTFS_AT_XXX). */
|
---|
379 | uint32_t uAttrType;
|
---|
380 | /** 0x04: Length of this entry. */
|
---|
381 | uint16_t cbEntry;
|
---|
382 | /** 0x06: Attribute name length (zero if none). */
|
---|
383 | uint8_t cwcName;
|
---|
384 | /** 0x07: Name offset. */
|
---|
385 | uint8_t offName;
|
---|
386 | /** 0x08: The first VNC for this part of the attribute value. */
|
---|
387 | int64_t iVcnFirst;
|
---|
388 | /** 0x10: The MFT record holding the actual attribute. */
|
---|
389 | NTFSMFTREF InMftRec;
|
---|
390 | /** 0x18: Attribute instance number. Unique within the MFT record. */
|
---|
391 | uint16_t idAttrib;
|
---|
392 | /** 0x1a: Maybe where the attribute name starts. */
|
---|
393 | RT_FLEXIBLE_ARRAY_EXTENSION
|
---|
394 | RTUTF16 wszName[RT_FLEXIBLE_ARRAY];
|
---|
395 | } NTFSATLISTENTRY;
|
---|
396 | AssertCompileMemberOffset(NTFSATLISTENTRY, idAttrib, 0x18);
|
---|
397 | /** Pointer to a NTFS attribute list entry. */
|
---|
398 | typedef NTFSATLISTENTRY *PNTFSATLISTENTRY;
|
---|
399 | /** Pointer to a const NTFS attribute list entry. */
|
---|
400 | typedef NTFSATLISTENTRY const *PCNTFSATLISTENTRY;
|
---|
401 |
|
---|
402 | /** Unaligned minimum entry size (no name). */
|
---|
403 | #define NTFSATLISTENTRY_SIZE_MINIMAL 0x1a
|
---|
404 |
|
---|
405 |
|
---|
406 |
|
---|
407 | /**
|
---|
408 | * NTFS standard file info attribute (NTFS_AT_STANDARD_INFORMATION).
|
---|
409 | */
|
---|
410 | typedef struct NTFSATSTDINFO
|
---|
411 | {
|
---|
412 | /** 0x00: Creation timestamp. */
|
---|
413 | int64_t iCreationTime;
|
---|
414 | /** 0x08: Last data modification timestamp. */
|
---|
415 | int64_t iLastDataModTime;
|
---|
416 | /** 0x10: Last MFT record modification timestamp. */
|
---|
417 | int64_t iLastMftModTime;
|
---|
418 | /** 0x18: Last access timestamp. */
|
---|
419 | int64_t iLastAccessTime;
|
---|
420 | /** 0x20: File attributes. */
|
---|
421 | uint32_t fFileAttribs;
|
---|
422 | /** 0x24: Maximum number of file versions allowed.
|
---|
423 | * @note NTFS 3.x, padding in 1.2 */
|
---|
424 | uint32_t cMaxFileVersions;
|
---|
425 | /** 0x28: Current file version number.
|
---|
426 | * @note NTFS 3.x, padding in 1.2 */
|
---|
427 | uint32_t uFileVersion;
|
---|
428 | /** 0x2c: Class ID (whatever that is).
|
---|
429 | * @note NTFS 3.x, padding in 1.2 */
|
---|
430 | uint32_t idClass;
|
---|
431 | /** 0x30: Owner ID.
|
---|
432 | * Translated via $Q index in NTFS_MFT_IDX_EXTENDED/$Quota.
|
---|
433 | * @note NTFS 3.x, not present in 1.2 */
|
---|
434 | uint32_t idOwner;
|
---|
435 | /** 0x34: Security ID. Translated via $SII index and $SDS data stream in
|
---|
436 | * NTFS_MFT_IDX_SECURITY.
|
---|
437 | * @note NTFS 3.x, not present in 1.2 */
|
---|
438 | uint32_t idSecurity;
|
---|
439 | /** 0x38: Total quota charged for this file.
|
---|
440 | * @note NTFS 3.x, not present in 1.2 */
|
---|
441 | uint64_t cbQuotaChared;
|
---|
442 | /** 0x40: Last update sequence number, index into $UsnJrnl.
|
---|
443 | * @note NTFS 3.x, not present in 1.2 */
|
---|
444 | uint64_t idxUpdateSequence;
|
---|
445 | } NTFSATSTDINFO;
|
---|
446 | AssertCompileSize(NTFSATSTDINFO, 0x48);
|
---|
447 | /** Pointer to NTFS standard file info. */
|
---|
448 | typedef NTFSATSTDINFO *PNTFSATSTDINFO;
|
---|
449 | /** Pointer to const NTFS standard file info. */
|
---|
450 | typedef NTFSATSTDINFO const *PCNTFSATSTDINFO;
|
---|
451 |
|
---|
452 | /** The size of NTFSATSTDINFO in NTFS v1.2 and earlier. */
|
---|
453 | #define NTFSATSTDINFO_SIZE_NTFS_V12 (0x30)
|
---|
454 |
|
---|
455 | /** @name NTFS_FA_XXX - NTFS file attributes (host endian).
|
---|
456 | * @{ */
|
---|
457 | #define NTFS_FA_READONLY UINT32_C(0x00000001)
|
---|
458 | #define NTFS_FA_HIDDEN UINT32_C(0x00000002)
|
---|
459 | #define NTFS_FA_SYSTEM UINT32_C(0x00000004)
|
---|
460 | #define NTFS_FA_DIRECTORY UINT32_C(0x00000010)
|
---|
461 | #define NTFS_FA_ARCHIVE UINT32_C(0x00000020)
|
---|
462 | #define NTFS_FA_DEVICE UINT32_C(0x00000040)
|
---|
463 | #define NTFS_FA_NORMAL UINT32_C(0x00000080)
|
---|
464 | #define NTFS_FA_TEMPORARY UINT32_C(0x00000100)
|
---|
465 | #define NTFS_FA_SPARSE_FILE UINT32_C(0x00000200)
|
---|
466 | #define NTFS_FA_REPARSE_POINT UINT32_C(0x00000400)
|
---|
467 | #define NTFS_FA_COMPRESSED UINT32_C(0x00000800)
|
---|
468 | #define NTFS_FA_OFFLINE UINT32_C(0x00001000)
|
---|
469 | #define NTFS_FA_NOT_CONTENT_INDEXED UINT32_C(0x00002000)
|
---|
470 | #define NTFS_FA_ENCRYPTED UINT32_C(0x00004000)
|
---|
471 | #define NTFS_FA_VALID_FLAGS UINT32_C(0x00007fb7)
|
---|
472 | #define NTFS_FA_VALID_SET_FLAGS UINT32_C(0x000031a7)
|
---|
473 | #define NTFS_FA_DUP_FILE_NAME_INDEX_PRESENT UINT32_C(0x10000000) /**< This means directory apparently. */
|
---|
474 | #define NTFS_FA_DUP_VIEW_INDEX_PRESENT UINT32_C(0x20000000) /**< ?? */
|
---|
475 | /** @} */
|
---|
476 |
|
---|
477 |
|
---|
478 |
|
---|
479 | /**
|
---|
480 | * NTFS filename attribute (NTFS_AT_FILENAME).
|
---|
481 | */
|
---|
482 | typedef struct NTFSATFILENAME
|
---|
483 | {
|
---|
484 | /** 0x00: The parent directory MFT record. */
|
---|
485 | NTFSMFTREF ParentDirMftRec;
|
---|
486 | /** 0x08: Creation timestamp. */
|
---|
487 | int64_t iCreationTime;
|
---|
488 | /** 0x10: Last data modification timestamp. */
|
---|
489 | int64_t iLastDataModTime;
|
---|
490 | /** 0x18: Last MFT record modification timestamp. */
|
---|
491 | int64_t iLastMftModTime;
|
---|
492 | /** 0x20: Last access timestamp. */
|
---|
493 | int64_t iLastAccessTime;
|
---|
494 | /** 0x28: Allocated disk space for the unnamed data attribute. */
|
---|
495 | int64_t cbAllocated;
|
---|
496 | /** 0x30: Actual size of unnamed data attribute. */
|
---|
497 | int64_t cbData;
|
---|
498 | /** 0x38: File attributes (NTFS_FA_XXX). */
|
---|
499 | uint32_t fFileAttribs;
|
---|
500 | union
|
---|
501 | {
|
---|
502 | /** 0x3c: Packed EA length. */
|
---|
503 | uint16_t cbPackedEas;
|
---|
504 | /** 0x3c: Reparse tag, if no EAs. */
|
---|
505 | uint32_t uReparseTag;
|
---|
506 | } u;
|
---|
507 | /** 0x40: Filename length in unicode chars. */
|
---|
508 | uint8_t cwcFilename;
|
---|
509 | /** 0x41: Filename type (NTFS_FILENAME_T_XXX). */
|
---|
510 | uint8_t fFilenameType;
|
---|
511 | /** 0x42: The filename. */
|
---|
512 | RT_FLEXIBLE_ARRAY_EXTENSION
|
---|
513 | RTUTF16 wszFilename[RT_FLEXIBLE_ARRAY];
|
---|
514 | } NTFSATFILENAME;
|
---|
515 | AssertCompileMemberOffset(NTFSATFILENAME, cbData, 0x30);
|
---|
516 | AssertCompileMemberOffset(NTFSATFILENAME, u.cbPackedEas, 0x3c);
|
---|
517 | AssertCompileMemberOffset(NTFSATFILENAME, u.uReparseTag, 0x3c);
|
---|
518 | AssertCompileMemberOffset(NTFSATFILENAME, wszFilename, 0x42);
|
---|
519 | /** Pointer to a NTFS filename attribute. */
|
---|
520 | typedef NTFSATFILENAME *PNTFSATFILENAME;
|
---|
521 | /** Pointer to a const NTFS filename attribute. */
|
---|
522 | typedef NTFSATFILENAME const *PCNTFSATFILENAME;
|
---|
523 |
|
---|
524 | /** @name NTFS_FILENAME_T_XXX - filename types
|
---|
525 | * @{ */
|
---|
526 | #define NTFS_FILENAME_T_POSIX 0
|
---|
527 | #define NTFS_FILENAME_T_WINDOWS 1
|
---|
528 | #define NTFS_FILENAME_T_DOS 2
|
---|
529 | #define NTFS_FILENAME_T_WINDOWS_AND_DSO 3
|
---|
530 | /** @} */
|
---|
531 |
|
---|
532 |
|
---|
533 | /**
|
---|
534 | * NTFS volume information (NTFS_AT_VOLUME_INFORMATION).
|
---|
535 | *
|
---|
536 | * This is found in the special NTFS_MFT_IDX_VOLUME file.
|
---|
537 | */
|
---|
538 | typedef struct NTFSATVOLUMEINFO
|
---|
539 | {
|
---|
540 | /** 0x00: Reserved bytes. */
|
---|
541 | uint8_t abReserved[8];
|
---|
542 | /** 0x08: Major NTFS version number. */
|
---|
543 | uint8_t uMajorVersion;
|
---|
544 | /** 0x09: Minor NTFS version number. */
|
---|
545 | uint8_t uMinorVersion;
|
---|
546 | /** 0x0a: Volume flags (NTFS_VOLUME_F_XXX) */
|
---|
547 | uint16_t fFlags;
|
---|
548 | } NTFSATVOLUMEINFO;
|
---|
549 | AssertCompileSize(NTFSATVOLUMEINFO, 12);
|
---|
550 | /** Pointer to NTFS volume information. */
|
---|
551 | typedef NTFSATVOLUMEINFO *PNTFSATVOLUMEINFO;
|
---|
552 | /** Pointer to const NTFS volume information. */
|
---|
553 | typedef NTFSATVOLUMEINFO const *PCNTFSATVOLUMEINFO;
|
---|
554 |
|
---|
555 | /** @name NTFS_VOLUME_F_XXX
|
---|
556 | * @{ */
|
---|
557 | #define NTFS_VOLUME_F_DIRTY RT_H2LE_U16_C(0x0001) /**< Volume is dirty. */
|
---|
558 | #define NTFS_VOLUME_F_RESIZE_LOG_FILE RT_H2LE_U16_C(0x0002) /**< */
|
---|
559 | #define NTFS_VOLUME_F_UPGRADE_ON_MOUNT RT_H2LE_U16_C(0x0004) /**< */
|
---|
560 | #define NTFS_VOLUME_F_MOUNTED_ON_NT4 RT_H2LE_U16_C(0x0008) /**< */
|
---|
561 | #define NTFS_VOLUME_F_DELETE_USN_UNDERWAY RT_H2LE_U16_C(0x0010) /**< */
|
---|
562 | #define NTFS_VOLUME_F_REPAIR_OBJECT_ID RT_H2LE_U16_C(0x0020) /**< */
|
---|
563 | #define NTFS_VOLUME_F_CHKDSK_UNDERWAY RT_H2LE_U16_C(0x4000) /**< */
|
---|
564 | #define NTFS_VOLUME_F_MODIFIED_BY_CHKDSK RT_H2LE_U16_C(0x8000) /**< */
|
---|
565 |
|
---|
566 | #define NTFS_VOLUME_F_KNOWN_MASK RT_H2LE_U16_C(0xc03f)
|
---|
567 | #define NTFS_VOLUME_F_MOUNT_READONLY_MASK RT_H2LE_U16_C(0xc027)
|
---|
568 | /** @} */
|
---|
569 |
|
---|
570 |
|
---|
571 | /** The attribute name used by the index attributes on NTFS directories,
|
---|
572 | * ASCII stirng variant. */
|
---|
573 | #define NTFS_DIR_ATTRIBUTE_NAME "$I30"
|
---|
574 |
|
---|
575 | /**
|
---|
576 | * NTFS index header.
|
---|
577 | *
|
---|
578 | * This is used by NTFSATINDEXROOT and NTFSATINDEXALLOC as a prelude to the
|
---|
579 | * sequence of entries in a node.
|
---|
580 | */
|
---|
581 | typedef struct NTFSINDEXHDR
|
---|
582 | {
|
---|
583 | /** 0x00: Offset of the first entry relative to this header. */
|
---|
584 | uint32_t offFirstEntry;
|
---|
585 | /** 0x04: Current index size in bytes, including this header. */
|
---|
586 | uint32_t cbUsed;
|
---|
587 | /** 0x08: Number of bytes allocated for the index (including this header). */
|
---|
588 | uint32_t cbAllocated;
|
---|
589 | /** 0x0c: Flags (NTFSINDEXHDR_F_XXX). */
|
---|
590 | uint8_t fFlags;
|
---|
591 | /** 0x0d: Reserved bytes. */
|
---|
592 | uint8_t abReserved[3];
|
---|
593 | /* NTFSIDXENTRYHDR sequence typically follows here */
|
---|
594 | } NTFSINDEXHDR;
|
---|
595 | AssertCompileSize(NTFSINDEXHDR, 16);
|
---|
596 | /** Pointer to a NTFS index header. */
|
---|
597 | typedef NTFSINDEXHDR *PNTFSINDEXHDR;
|
---|
598 | /** Pointer to a const NTFS index header. */
|
---|
599 | typedef NTFSINDEXHDR const *PCNTFSINDEXHDR;
|
---|
600 |
|
---|
601 | /** @name NTFSINDEXHDR_F_XXX
|
---|
602 | * @{ */
|
---|
603 | /** An internal node (as opposed to a leaf node if clear).
|
---|
604 | * This means that the entries will have trailing node references (VCN). */
|
---|
605 | #define NTFSINDEXHDR_F_INTERNAL UINT8_C(0x01)
|
---|
606 | /** @} */
|
---|
607 |
|
---|
608 | /** Gets the pointer to the first entry header for an index. */
|
---|
609 | #define NTFSINDEXHDR_GET_FIRST_ENTRY(a_pIndexHdr) \
|
---|
610 | ( (PNTFSIDXENTRYHDR)((uint8_t *)(a_pIndexHdr) + RT_LE2H_U32((a_pIndexHdr)->offFirstEntry)) )
|
---|
611 |
|
---|
612 |
|
---|
613 | /**
|
---|
614 | * NTFS index root node (NTFS_AT_INDEX_ROOT).
|
---|
615 | *
|
---|
616 | * This is a generic index structure, but is most prominently used for
|
---|
617 | * implementating directories. The index is structured like B-tree, meaning
|
---|
618 | * each node contains multiple entries, and each entry contains data regardless
|
---|
619 | * of whether it's a leaf node or not.
|
---|
620 | *
|
---|
621 | * The index is sorted in ascending order according to the collation rules
|
---|
622 | * defined by the root node (NTFSATINDEXROOT::uCollationRules, see also (see
|
---|
623 | * NTFS_COLLATION_XXX).
|
---|
624 | *
|
---|
625 | * @note The root directory contains a '.' entry, others don't.
|
---|
626 | */
|
---|
627 | typedef struct NTFSATINDEXROOT
|
---|
628 | {
|
---|
629 | /** 0x00: The index type (NTFSATINDEXROOT_TYPE_XXX). */
|
---|
630 | uint32_t uType;
|
---|
631 | /** 0x04: The sorting rules to use (NTFS_COLLATION_XXX). */
|
---|
632 | uint32_t uCollationRules;
|
---|
633 | /** 0x08: Number of bytes in
|
---|
634 | * Index node size (in bytes). */
|
---|
635 | uint32_t cbIndexNode;
|
---|
636 | /** 0x0c: Number of node addresses per node.
|
---|
637 | * This sounds weird right? A subnode is generally addressed as a virtual
|
---|
638 | * cluster when cbIndexNode >= cbCluster, but when clusters are large NTFS uses
|
---|
639 | * 512 bytes chunks.
|
---|
640 | *
|
---|
641 | * (You would've thought it would be simpler to just use cbIndexNode as the
|
---|
642 | * addressing unit, maybe storing the log2 here to avoid a ffs call.) */
|
---|
643 | uint8_t cAddressesPerIndexNode;
|
---|
644 | /** 0x0d: Reserved padding or something. */
|
---|
645 | uint8_t abReserved[3];
|
---|
646 | /** 0x10: Index header detailing the entries that follows. */
|
---|
647 | NTFSINDEXHDR Hdr;
|
---|
648 | /* 0x20: NTFSIDXENTRYHDR sequence typically follows here */
|
---|
649 | } NTFSATINDEXROOT;
|
---|
650 | AssertCompileSize(NTFSATINDEXROOT, 32);
|
---|
651 | /** Pointer to a NTFS index root. */
|
---|
652 | typedef NTFSATINDEXROOT *PNTFSATINDEXROOT;
|
---|
653 | /** Pointer to a const NTFS index root. */
|
---|
654 | typedef NTFSATINDEXROOT const *PCNTFSATINDEXROOT;
|
---|
655 |
|
---|
656 | /** @name NTFSATINDEXROOT_TYPE_XXX
|
---|
657 | * @{ */
|
---|
658 | /** View index. */
|
---|
659 | #define NTFSATINDEXROOT_TYPE_VIEW RT_H2LE_U32_C(UINT32_C(0x00000000))
|
---|
660 | /** Directory index, NTFSATFILENAME follows NTFSINDEXENTRY. */
|
---|
661 | #define NTFSATINDEXROOT_TYPE_DIR RT_H2LE_U32_C(UINT32_C(0x00000030))
|
---|
662 | /** @} */
|
---|
663 |
|
---|
664 | /** @name NTFS_COLLATION_XXX - index sorting rules
|
---|
665 | * @{ */
|
---|
666 | /** Little endian binary compare (or plain byte compare if you like). */
|
---|
667 | #define NTFS_COLLATION_BINARY RT_H2LE_U32_C(UINT32_C(0x00000000))
|
---|
668 | /** Same as NTFS_COLLATION_UNICODE_STRING. */
|
---|
669 | #define NTFS_COLLATION_FILENAME RT_H2LE_U32_C(UINT32_C(0x00000001))
|
---|
670 | /** Compare the uppercased unicode characters. */
|
---|
671 | #define NTFS_COLLATION_UNICODE_STRING RT_H2LE_U32_C(UINT32_C(0x00000002))
|
---|
672 |
|
---|
673 | /** Single little endian 32-bit unsigned integer value as sort key. */
|
---|
674 | #define NTFS_COLLATION_UINT32 RT_H2LE_U32_C(UINT32_C(0x00000010))
|
---|
675 | /** Little endian SID value as sort key. */
|
---|
676 | #define NTFS_COLLATION_SID RT_H2LE_U32_C(UINT32_C(0x00000011))
|
---|
677 | /** Two little endian 32-bit unsigned integer values used as sorting key. */
|
---|
678 | #define NTFS_COLLATION_UINT32_PAIR RT_H2LE_U32_C(UINT32_C(0x00000012))
|
---|
679 | /** Sequence of little endian 32-bit unsigned integer values used as sorting key. */
|
---|
680 | #define NTFS_COLLATION_UINT32_SEQ RT_H2LE_U32_C(UINT32_C(0x00000013))
|
---|
681 | /** @} */
|
---|
682 |
|
---|
683 |
|
---|
684 | /**
|
---|
685 | * NTFS index non-root node.
|
---|
686 | */
|
---|
687 | typedef struct NTFSATINDEXALLOC
|
---|
688 | {
|
---|
689 | /** 0x00: Header with NTFSREC_MAGIC_INDEX_ALLOC. */
|
---|
690 | NTFSRECHDR RecHdr;
|
---|
691 | /** 0x08: Log file sequence number. */
|
---|
692 | uint64_t uLsn;
|
---|
693 | /** 0x10: The node address of this node (for consistency checking and
|
---|
694 | * perhaps data reconstruction).
|
---|
695 | * @see NTFSATINDEXROOT::cAddressesPerIndexNode for node addressing. */
|
---|
696 | int64_t iSelfAddress;
|
---|
697 | /** 0x18: Index header detailing the entries that follows. */
|
---|
698 | NTFSINDEXHDR Hdr;
|
---|
699 | /* 0x28: NTFSIDXENTRYHDR sequence typically follows here */
|
---|
700 | } NTFSATINDEXALLOC;
|
---|
701 | AssertCompileSize(NTFSATINDEXALLOC, 40);
|
---|
702 | /** Pointer to a NTFS index non-root node. */
|
---|
703 | typedef NTFSATINDEXALLOC *PNTFSATINDEXALLOC;
|
---|
704 | /** Pointer to a const NTFS index non-root node. */
|
---|
705 | typedef NTFSATINDEXALLOC const *PCNTFSATINDEXALLOC;
|
---|
706 |
|
---|
707 | /** NTFS 'INDX' attribute magic value (NTFSATINDEXALLOC).
|
---|
708 | * @todo sort out the record / attribute name clash here. */
|
---|
709 | #define NTFSREC_MAGIC_INDEX_ALLOC RT_H2LE_U32_C(UINT32_C(0x58444e49))
|
---|
710 |
|
---|
711 |
|
---|
712 | /**
|
---|
713 | * NTFS index entry header.
|
---|
714 | *
|
---|
715 | * Each entry in a node starts with this header. It is immediately followed by
|
---|
716 | * the key data (NTFSIDXENTRYHDR::cbKey). When
|
---|
717 | *
|
---|
718 | */
|
---|
719 | typedef struct NTFSIDXENTRYHDR
|
---|
720 | {
|
---|
721 | union
|
---|
722 | {
|
---|
723 | /** 0x00: NTFSATINDEXROOT_TYPE_DIR: Reference to the MFT record being indexed here.
|
---|
724 | * @note This is invalid if NTFSIDXENTRYHDR_F_END is set (no key data). */
|
---|
725 | NTFSMFTREF FileMftRec;
|
---|
726 | /** 0x00: NTFSATINDEXROOT_TYPE_VIEW: Go figure later if necessary. */
|
---|
727 | struct
|
---|
728 | {
|
---|
729 | /** 0x00: Offset to the data relative to this header.
|
---|
730 | * @note This is invalid if NTFSIDXENTRYHDR_F_END is set (no key data). */
|
---|
731 | uint16_t offData;
|
---|
732 | /** 0x02: Size of data at offData.
|
---|
733 | * @note This is invalid if NTFSIDXENTRYHDR_F_END is set (no key data). */
|
---|
734 | uint16_t cbData;
|
---|
735 | /** 0x04: Reserved. */
|
---|
736 | uint32_t uReserved;
|
---|
737 | } View;
|
---|
738 | } u;
|
---|
739 |
|
---|
740 | /** 0x08: Size of this entry, 8-byte aligned. */
|
---|
741 | uint16_t cbEntry;
|
---|
742 | /** 0x0a: Key length (unaligned). */
|
---|
743 | uint16_t cbKey;
|
---|
744 | /** 0x0c: Entry flags, NTFSIDXENTRYHDR_F_XXX. */
|
---|
745 | uint16_t fFlags;
|
---|
746 | /** 0x0e: Reserved. */
|
---|
747 | uint16_t uReserved;
|
---|
748 | } NTFSIDXENTRYHDR;
|
---|
749 | AssertCompileSize(NTFSIDXENTRYHDR, 16);
|
---|
750 | /** Pointer to a NTFS index entry header. */
|
---|
751 | typedef NTFSIDXENTRYHDR *PNTFSIDXENTRYHDR;
|
---|
752 | /** Pointer to a const NTFS index entry header. */
|
---|
753 | typedef NTFSIDXENTRYHDR const *PCNTFSIDXENTRYHDR;
|
---|
754 |
|
---|
755 | /** @name NTFSIDXENTRYHDR_F_XXX - NTFSIDXENTRYHDR::fFlags
|
---|
756 | * @{ */
|
---|
757 | /** Indicates an internal node (as opposed to a leaf node).
|
---|
758 | * This indicates that there is a 64-bit integer value at the very end of the
|
---|
759 | * entry (NTFSIDXENTRYHDR::cbEntry - 8) giving the virtual cluster number of the
|
---|
760 | * subnode. The subnode and all its decendants contain keys that are lower than
|
---|
761 | * the key in this entry.
|
---|
762 | */
|
---|
763 | #define NTFSIDXENTRYHDR_F_INTERNAL RT_H2LE_U16_C(UINT16_C(0x0001))
|
---|
764 | /** Set if special end entry in a node.
|
---|
765 | * This does not have any key data, but can point to a subnode with
|
---|
766 | * higher keys. */
|
---|
767 | #define NTFSIDXENTRYHDR_F_END RT_H2LE_U16_C(UINT16_C(0x0002))
|
---|
768 | /** @} */
|
---|
769 |
|
---|
770 | /** Gets the pointer to the next index entry header. */
|
---|
771 | #define NTFSIDXENTRYHDR_GET_NEXT(a_pEntryHdr) \
|
---|
772 | ( (PNTFSIDXENTRYHDR)((uintptr_t)(a_pEntryHdr) + RT_LE2H_U16((a_pEntryHdr)->cbEntry)) )
|
---|
773 | /** Gets the subnode address from an index entry.
|
---|
774 | * @see NTFSATINDEXROOT::cAddressesPerIndexNode for node addressing.
|
---|
775 | * @note Only invoke when NTFSIDXENTRYHDR_F_INTERNAL is set! */
|
---|
776 | #define NTFSIDXENTRYHDR_GET_SUBNODE(a_pEntryHdr) \
|
---|
777 | ( *(int64_t *)((uintptr_t)(a_pEntryHdr) + RT_LE2H_U16((a_pEntryHdr)->cbEntry) - sizeof(int64_t)) )
|
---|
778 |
|
---|
779 | /** @} */
|
---|
780 |
|
---|
781 | #endif /* !IPRT_INCLUDED_formats_ntfs_h */
|
---|
782 |
|
---|