VirtualBox

source: vbox/trunk/include/iprt/formats/ntfs.h@ 94480

Last change on this file since 94480 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette