VirtualBox

source: vbox/trunk/include/iprt/formats/fat.h@ 106061

Last change on this file since 106061 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.4 KB
Line 
1/* $Id: fat.h 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * IPRT, File Allocation Table (FAT).
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_fat_h
38#define IPRT_INCLUDED_formats_fat_h
39#ifndef RT_WITHOUT_PRAGMA_ONCE
40# pragma once
41#endif
42
43#include <iprt/types.h>
44#include <iprt/assertcompile.h>
45
46
47/** @defgroup grp_rt_formats_fat File Allocation Table (FAT) structures and definitions
48 * @ingroup grp_rt_formats
49 * @{
50 */
51
52
53/** @name FAT Media byte values
54 * @remarks This isn't as simple as it's made out to be here!
55 * @{ */
56#define FATBPB_MEDIA_FLOPPY_8 UINT8_C(0xe5)
57#define FATBPB_MEDIA_FLOPPY_5_DOT_25 UINT8_C(0xed)
58#define FATBPB_MEDIA_FLOPPY_3_DOT_5 UINT8_C(0xf0)
59/* incomplete, figure out as needed... */
60
61/** Checks if @a a_bMedia is a valid media byte. */
62#define FATBPB_MEDIA_IS_VALID(a_bMedia) ( (uint8_t)(a_bMedia) >= 0xf8 \
63 || (uint8_t)(a_bMedia) == 0xf0 \
64 || (uint8_t)(a_bMedia) == 0xf4 /* obscure - msdos 2.11 */ \
65 || (uint8_t)(a_bMedia) == 0xf5 /* obscure - msdos 2.11 */ \
66 || (uint8_t)(a_bMedia) == 0xed /* obscure - tandy 2000 */ \
67 || (uint8_t)(a_bMedia) == 0xe5 /* obscure - tandy 2000 */ )
68/** @} */
69
70/** Checks if @a a_bFatId is a valid FAT ID byte.
71 * @todo uncertain whether 0xf4 and 0xf5 should be allowed here too. */
72#define FAT_ID_IS_VALID(a_bFatId) ( (uint8_t)(a_bFatId) >= 0xf8 \
73 || (uint8_t)(a_bFatId) == 0xf0 \
74 || (uint8_t)(a_bFatId) == 0xf4 /* obscure - msdos 2.11 */ \
75 || (uint8_t)(a_bFatId) == 0xf5 /* obscure - msdos 2.11 */ \
76 || (uint8_t)(a_bFatId) == 0xed /* obscure, tandy 2000 */ \
77 || (uint8_t)(a_bFatId) == 0xe5 /* obscure, tandy 2000 */ )
78
79/**
80 * The DOS 2.0 BIOS parameter block (BPB).
81 *
82 * This was the first DOS version with a BPB.
83 */
84#pragma pack(1)
85typedef struct FATBPB20
86{
87 /** 0x0b / 0x00: The sector size in bytes. */
88 uint16_t cbSector;
89 /** 0x0d / 0x02: Number of sectors per cluster. */
90 uint8_t cSectorsPerCluster;
91 /** 0x0e / 0x03: Number of reserved sectors before the first FAT. */
92 uint16_t cReservedSectors;
93 /** 0x10 / 0x05: Number of FATs. */
94 uint8_t cFats;
95 /** 0x11 / 0x06: Max size of the root directory (0 for FAT32). */
96 uint16_t cMaxRootDirEntries;
97 /** 0x13 / 0x08: Total sector count, zero if 32-bit count is used. */
98 uint16_t cTotalSectors16;
99 /** 0x15 / 0x0a: Media ID. */
100 uint8_t bMedia;
101 /** 0x16 / 0x0b: Number of sectors per FAT (0 for FAT32). */
102 uint16_t cSectorsPerFat;
103} FATBPB20;
104#pragma pack()
105AssertCompileSize(FATBPB20, 0xd);
106/** Pointer to a DOS 2.0 BPB. */
107typedef FATBPB20 *PFATBPB20;
108/** Pointer to a const DOS 2.0 BPB. */
109typedef FATBPB20 const *PCFATBPB20;
110
111
112/**
113 * The DOS 3.0 BPB changes that survived.
114 */
115#pragma pack(1)
116typedef struct FATBPB30CMN
117{
118 /** DOS v2.0 BPB. */
119 FATBPB20 Bpb20;
120 /** 0x18 / 0x0d: Sectors per track. Zero means reserved and not used. */
121 uint16_t cSectorsPerTrack;
122 /** 0x1a / 0x0f: Number of heads. Zero means reserved and not used. */
123 uint16_t cTracksPerCylinder;
124} FATBPB30CMN;
125#pragma pack()
126AssertCompileSize(FATBPB30CMN, 0x11);
127
128/**
129 * The DOS 3.0 BPB.
130 */
131#pragma pack(1)
132typedef struct FATBPB30
133{
134 /** DOS v3.0 BPB bits that survived. */
135 FATBPB30CMN Core30;
136 /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero
137 * on unpartitioned media. */
138 uint16_t cHiddenSectors;
139} FATBPB30;
140#pragma pack()
141AssertCompileSize(FATBPB30, 0x13);
142/** Pointer to a DOS 3.0 BPB. */
143typedef FATBPB30 *PFATBPB30;
144/** Pointer to a const DOS 3.0 BPB. */
145typedef FATBPB30 const *PCFATBPB30;
146
147/**
148 * The DOS 3.0 BPB, flattened structure.
149 */
150#pragma pack(1)
151typedef struct FATBPB30FLAT
152{
153 /** @name New in DOS 2.0
154 * @{ */
155 /** 0x0b / 0x00: The sector size in bytes. */
156 uint16_t cbSector;
157 /** 0x0d / 0x02: Number of sectors per cluster. */
158 uint8_t cSectorsPerCluster;
159 /** 0x0e / 0x03: Number of reserved sectors before the first FAT. */
160 uint16_t cReservedSectors;
161 /** 0x10 / 0x05: Number of FATs. */
162 uint8_t cFats;
163 /** 0x11 / 0x06: Max size of the root directory (0 for FAT32). */
164 uint16_t cMaxRootDirEntries;
165 /** 0x13 / 0x08: Total sector count, zero if 32-bit count is used. */
166 uint16_t cTotalSectors16;
167 /** 0x15 / 0x0a: Media ID. */
168 uint8_t bMedia;
169 /** 0x16 / 0x0b: Number of sectors per FAT (0 for FAT32). */
170 uint16_t cSectorsPerFat;
171 /** @} */
172 /** @name New in DOS 3.0
173 * @{ */
174 /** 0x18 / 0x0d: Sectors per track. Zero means reserved and not used. */
175 uint16_t cSectorsPerTrack;
176 /** 0x1a / 0x0f: Number of heads. Zero means reserved and not used. */
177 uint16_t cTracksPerCylinder;
178 /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero
179 * on unpartitioned media. */
180 uint16_t cHiddenSectors;
181 /** @} */
182} FATBPB30FLAT;
183#pragma pack()
184AssertCompileSize(FATBPB30FLAT, 0x13);
185/** Pointer to a flattened DOS 3.0 BPB. */
186typedef FATBPB30FLAT *PFATBPB30FLAT;
187/** Pointer to a const flattened DOS 3.0 BPB. */
188typedef FATBPB30FLAT const *PCFATBPB30FLAT;
189
190
191/**
192 * The DOS 3.2 BPB.
193 */
194#pragma pack(1)
195typedef struct FATBPB32
196{
197 /** DOS v3.0 BPB. */
198 FATBPB30 Bpb30;
199 /** 0x1e / 0x13: Number of sectors, including the hidden ones. This is ZERO
200 * in DOS 3.31+. */
201 uint16_t cAnotherTotalSectors;
202} FATBPB32;
203#pragma pack()
204AssertCompileSize(FATBPB32, 0x15);
205/** Pointer to a DOS 3.2 BPB. */
206typedef FATBPB32 *PFATBPB32;
207/** Pointer to const a DOS 3.2 BPB. */
208typedef FATBPB32 const *PCFATBPB32;
209
210/**
211 * The DOS 3.2 BPB, flattened structure.
212 */
213#pragma pack(1)
214typedef struct FATBPB32FLAT
215{
216 /** @name New in DOS 2.0
217 * @{ */
218 /** 0x0b / 0x00: The sector size in bytes. */
219 uint16_t cbSector;
220 /** 0x0d / 0x02: Number of sectors per cluster. */
221 uint8_t cSectorsPerCluster;
222 /** 0x0e / 0x03: Number of reserved sectors before the first FAT. */
223 uint16_t cReservedSectors;
224 /** 0x10 / 0x05: Number of FATs. */
225 uint8_t cFats;
226 /** 0x11 / 0x06: Max size of the root directory (0 for FAT32). */
227 uint16_t cMaxRootDirEntries;
228 /** 0x13 / 0x08: Total sector count, zero if 32-bit count is used. */
229 uint16_t cTotalSectors16;
230 /** 0x15 / 0x0a: Media ID. */
231 uint8_t bMedia;
232 /** 0x16 / 0x0b: Number of sectors per FAT (0 for FAT32). */
233 uint16_t cSectorsPerFat;
234 /** @} */
235 /** @name New in DOS 3.0
236 * @{ */
237 /** 0x18 / 0x0d: Sectors per track. Zero means reserved and not used. */
238 uint16_t cSectorsPerTrack;
239 /** 0x1a / 0x0f: Number of heads. Zero means reserved and not used. */
240 uint16_t cTracksPerCylinder;
241 /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero
242 * on unpartitioned media. */
243 uint16_t cHiddenSectors;
244 /** @} */
245 /** @name New in DOS 3.2
246 * @{ */
247 /** 0x1e / 0x13: Number of sectors, including the hidden ones. This is ZERO
248 * in DOS 3.31+. */
249 uint16_t cAnotherTotalSectors;
250 /** @} */
251} FATBPB32FLAT;
252#pragma pack()
253AssertCompileSize(FATBPB32FLAT, 0x15);
254/** Pointer to a flattened DOS 3.2 BPB. */
255typedef FATBPB32FLAT *PFATBPB32FLAT;
256/** Pointer to a const flattened DOS 3.2 BPB. */
257typedef FATBPB32FLAT const *PCFATBPB32FLAT;
258
259
260/**
261 * The DOS 3.31 BPB.
262 */
263#pragma pack(1)
264typedef struct FATBPB331
265{
266 /** DOS v3.0 BPB bits that survived. */
267 FATBPB30CMN Core30;
268 /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero
269 * on unpartitioned media. Values higher than 65535 are complicated due to
270 * the field overlapping FATBPB32::cAnotherTotalSectors */
271 uint32_t cHiddenSectors;
272 /** 0x20 / 0x15: Total logical sectors. Used if count >= 64K, otherwise
273 * FATBPB20::cTotalSectors16 is used. Zero if 64-bit value used with FAT32. */
274 uint32_t cTotalSectors32;
275} FATBPB331;
276#pragma pack()
277AssertCompileSize(FATBPB331, 0x19);
278/** Pointer to a DOS 3.31 BPB. */
279typedef FATBPB331 *PFATBPB331;
280/** Pointer to a const DOS 3.31 BPB. */
281typedef FATBPB331 const *PCFATBPB331;
282
283/**
284 * The DOS 3.31 BPB, flattened structure.
285 */
286#pragma pack(1)
287typedef struct FATBPB331FLAT
288{
289 /** @name New in DOS 2.0
290 * @{ */
291 /** 0x0b / 0x00: The sector size in bytes. */
292 uint16_t cbSector;
293 /** 0x0d / 0x02: Number of sectors per cluster. */
294 uint8_t cSectorsPerCluster;
295 /** 0x0e / 0x03: Number of reserved sectors before the first FAT (0 for
296 * NTFS). */
297 uint16_t cReservedSectors;
298 /** 0x10 / 0x05: Number of FATs (0 for NTFS). */
299 uint8_t cFats;
300 /** 0x11 / 0x06: Max size of the root directory (0 for FAT32 & NTFS). */
301 uint16_t cMaxRootDirEntries;
302 /** 0x13 / 0x08: Total sector count, zero if 32-bit count is used (and for
303 * NTFS). */
304 uint16_t cTotalSectors16;
305 /** 0x15 / 0x0a: Media ID. */
306 uint8_t bMedia;
307 /** 0x16 / 0x0b: Number of sectors per FAT (0 for FAT32 & NTFS). */
308 uint16_t cSectorsPerFat;
309 /** @} */
310 /** @name New in DOS 3.0
311 * @{ */
312 /** 0x18 / 0x0d: Sectors per track. Zero means reserved and not used. */
313 uint16_t cSectorsPerTrack;
314 /** 0x1a / 0x0f: Number of heads. Zero means reserved and not used. */
315 uint16_t cTracksPerCylinder;
316 /** @} */
317 /** @name New in DOS 3.31
318 * @{ */
319 /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero
320 * on unpartitioned media. Values higher than 65535 are complicated due to
321 * the field overlapping FATBPB32::cAnotherTotalSectors */
322 uint32_t cHiddenSectors;
323 /** 0x20 / 0x15: Total logical sectors. Used if count >= 64K, otherwise
324 * FATBPB20::cTotalSectors16 is used. Zero if 64-bit value used with FAT32.
325 * (Zero for NTFS). */
326 uint32_t cTotalSectors32;
327 /** @} */
328} FATBPB331FLAT;
329#pragma pack()
330AssertCompileSize(FATBPB331FLAT, 0x19);
331/** Pointer to a flattened DOS 3.31 BPB. */
332typedef FATBPB331FLAT *PFATBPB331FLAT;
333/** Pointer to a const flattened DOS 3.31 BPB. */
334typedef FATBPB331FLAT const *PCFATBPB331FLAT;
335
336
337/**
338 * Extended BIOS parameter block (EBPB).
339 */
340#pragma pack(1)
341typedef struct FATEBPB
342{
343 /** The BPB. */
344 FATBPB331FLAT Bpb;
345
346 /** 0x24 / 0x19: BIOS INT13 pysical drive number. */
347 uint8_t bInt13Drive;
348 /** 0x25 / 0x1a: Reserved. NT used bit 0 for indicating dirty FS, and bit 1
349 * for surface scan. */
350 uint8_t bReserved;
351 /** 0x26 / 0x1b: Extended boot signature, FATEBPB_SIGNATURE or
352 * FATEBPB_SIGNATURE_OLD. */
353 uint8_t bExtSignature;
354 /** 0x27 / 0x1c: The volume serial number. */
355 uint32_t uSerialNumber;
356 /** 0x2b / 0x20: The volume label (space padded).
357 * @remarks Not available with FATEBPB_SIGNATURE_OLD */
358 char achLabel[11];
359 /** 0x36 / 0x2b: The file system type (space padded).
360 * @remarks Not available with FATEBPB_SIGNATURE_OLD */
361 char achType[8];
362} FATEBPB;
363#pragma pack()
364AssertCompileSize(FATEBPB, 0x33);
365/** Pointer to an extended BIOS parameter block. */
366typedef FATEBPB *PFATEBPB;
367/** Pointer to a const extended BIOS parameter block. */
368typedef FATEBPB const *PCFATEBPB;
369
370/** FATEBPB::bExtSignature value. */
371#define FATEBPB_SIGNATURE UINT8_C(0x29)
372/** FATEBPB::bExtSignature value used by OS/2 1.0-1.1 and PC DOS 3.4. These
373 * does not have the volume and file system type. */
374#define FATEBPB_SIGNATURE_OLD UINT8_C(0x28)
375
376/**FATEBPB::achType value for FAT12. */
377#define FATEBPB_TYPE_FAT12 "FAT12 "
378/**FATEBPB::achType value for FAT16. */
379#define FATEBPB_TYPE_FAT16 "FAT16 "
380/**FATEBPB::achType value for FAT12/FAT16. */
381#define FATEBPB_TYPE_FAT "FAT32 "
382
383
384/**
385 * FAT32 Extended BIOS parameter block (EBPB).
386 */
387#pragma pack(1)
388typedef struct FAT32EBPB
389{
390 /** The BPB. */
391 FATBPB331FLAT Bpb;
392
393 /** 0x24 / 0x19: Number of sectors per FAT.
394 * @note To avoid confusion with the FATEBPB signature, values which result in
395 * 0x00280000 or 0x00290000 when masked by 0x00ff0000 must not be used. */
396 uint32_t cSectorsPerFat32;
397 /** 0x28 / 0x1d: Flags pertaining to FAT mirroring and other stuff. */
398 uint16_t fFlags;
399 /** 0x2a / 0x1f: FAT32 version number (FAT32EBPB_VERSION_0_0). */
400 uint16_t uVersion;
401 /** 0x2c / 0x21: Cluster number of the root directory. */
402 uint32_t uRootDirCluster;
403 /** 0x30 / 0x25: Logical sector number of the information sector. */
404 uint16_t uInfoSectorNo;
405 /** 0x32 / 0x27: Logical sector number of boot sector copy. */
406 uint16_t uBootSectorCopySectorNo;
407 /** 0x34 / 0x29: Reserved, zero (or 0xf6) filled, preserve. */
408 uint8_t abReserved[12];
409
410 /** 0x40 / 0x35: BIOS INT13 pysical drive number
411 * @remarks Same as FATEBPB::bInt13Drive. */
412 uint8_t bInt13Drive;
413 /** 0x41 / 0x36: Reserved.
414 * @remarks Same as FATEBPB::bReserved. */
415 uint8_t bReserved;
416 /** 0x42 / 0x37: Extended boot signature (FATEBPB_SIGNATURE, or
417 * FATEBPB_SIGNATURE_OLD in some special cases).
418 * @remarks Same as FATEBPB::bExtSignature. */
419 uint8_t bExtSignature;
420 /** 0x43 / 0x38: The volume serial number.
421 * @remarks Same as FATEBPB::uSerialNumber. */
422 uint32_t uSerialNumber;
423 /** 0x47 / 0x3c: The volume label (space padded).
424 * @remarks Not available with FATEBPB_SIGNATURE_OLD
425 * @remarks Same as FATEBPB::achLabel. */
426 char achLabel[11];
427 /** 0x52 / 0x47: The file system type (space padded), or 64-bit logical sector
428 * count if both other count fields are zero. In the latter case, the type is
429 * moved to the OEM name field (FATBOOTSECTOR::achOemName).
430 *
431 * @remarks Not available with FATEBPB_SIGNATURE_OLD
432 * @remarks Same as FATEBPB::achType. */
433 union
434 {
435 /** Type string variant. */
436 char achType[8];
437 /** Total sector count if 4G or higher. */
438 uint64_t cTotalSectors64;
439 } u;
440} FAT32EBPB;
441#pragma pack()
442AssertCompileSize(FAT32EBPB, 0x4f);
443/** Pointer to a FAT32 extended BIOS parameter block. */
444typedef FAT32EBPB *PFAT32EBPB;
445/** Pointer to a const FAT32 extended BIOS parameter block. */
446typedef FAT32EBPB const *PCFAT32EBPB;
447
448/** FAT32 version 0.0 (FAT32EBPB::uVersion). */
449#define FAT32EBPB_VERSION_0_0 UINT16_C(0x0000)
450
451
452/**
453 * NTFS extended BIOS parameter block (NTFSEBPB).
454 */
455#pragma pack(1)
456typedef struct NTFSEBPB
457{
458 /** The BPB. */
459 FATBPB331FLAT Bpb;
460
461 /** 0x24 / 0x19: BIOS INT13 pysical drive number.
462 * @note Same location as FATEBPB::bInt13Drive. */
463 uint8_t bInt13Drive;
464 /** 0x25 / 0x1a: Reserved / flags */
465 uint8_t bReserved;
466 /** 0x26 / 0x1b: Extended boot signature (NTFSEBPB_SIGNATURE).
467 * @note Same location as FATEBPB::bExtSignature. */
468 uint8_t bExtSignature;
469 /** 0x27 / 0x1c: Reserved */
470 uint8_t bReserved2;
471
472 /** 0x28 / 0x1d: Number of sectors. */
473 uint64_t cSectors;
474 /** 0x30 / 0x25: Logical cluster number of the master file table (MFT). */
475 uint64_t uLcnMft;
476 /** 0x38 / 0x2d: Logical cluster number of the MFT mirror. */
477 uint64_t uLcnMftMirror;
478 /** 0x40 / 0x35: Logical clusters per file record segment.
479 * This is a shift count if negative. */
480 int8_t cClustersPerMftRecord;
481 /** 0x41 / 0x36: Reserved. */
482 uint8_t abReserved3[3];
483 /** 0x44 / 0x39: The default logical clusters count per index node.
484 * This is a shift count if negative. */
485 int8_t cClustersPerIndexNode;
486 /** 0x45 / 0x3a: Reserved. */
487 uint8_t abReserved4[3];
488 /** 0x48 / 0x3d: Volume serial number.
489 * @note This is larger than the the FAT serial numbers. */
490 uint64_t uSerialNumber;
491 /** 0x50 / 0x45: Checksum. */
492 uint32_t uChecksum;
493} NTFSEBPB;
494#pragma pack()
495AssertCompileSize(NTFSEBPB, 0x49);
496/** Pointer to a NTFS extended BIOS parameter block. */
497typedef NTFSEBPB *PNTFSEBPB;
498/** Pointer to a const NTFS extended BIOS parameter block. */
499typedef NTFSEBPB const *PCNTFSEBPB;
500
501/** NTFS EBPB signature (NTFSEBPB::bExtSignature). */
502#define NTFSEBPB_SIGNATURE UINT8_C(0x80)
503
504
505/**
506 * FAT boot sector layout.
507 */
508#pragma pack(1)
509typedef struct FATBOOTSECTOR
510{
511 /** 0x000: DOS 2.0+ jump sequence. */
512 uint8_t abJmp[3];
513 /** 0x003: OEM name (who formatted this volume). */
514 char achOemName[8];
515 /** 0x00b: The BIOS parameter block.
516 * This varies a lot in size. */
517 union
518 {
519 FATBPB20 Bpb20;
520 FATBPB30FLAT Bpb30;
521 FATBPB32FLAT Bpb32;
522 FATBPB331FLAT Bpb331;
523 FATEBPB Ebpb;
524 FAT32EBPB Fat32Ebpb;
525 NTFSEBPB Ntfs;
526 } Bpb;
527 /** 0x05a: Bootloader code/data/stuff. */
528 uint8_t abStuff[0x1a3];
529 /** 0x1fd: Old drive number location (DOS 3.2-3.31). */
530 uint8_t bOldInt13Drive;
531 /** 0x1fe: DOS signature (FATBOOTSECTOR_SIGNATURE). */
532 uint16_t uSignature;
533} FATBOOTSECTOR;
534#pragma pack()
535AssertCompileSize(FATBOOTSECTOR, 0x200);
536/** Pointer to a FAT boot sector. */
537typedef FATBOOTSECTOR *PFATBOOTSECTOR;
538/** Pointer to a const FAT boot sector. */
539typedef FATBOOTSECTOR const *PCFATBOOTSECTOR;
540
541/** Boot sector signature (FATBOOTSECTOR::uSignature). */
542#define FATBOOTSECTOR_SIGNATURE UINT16_C(0xaa55)
543
544
545
546/**
547 * FAT32 info sector (follows the boot sector).
548 */
549typedef struct FAT32INFOSECTOR
550{
551 /** 0x000: Signature \#1 (FAT32INFOSECTOR_SIGNATURE_1). */
552 uint32_t uSignature1;
553 /** Reserved, should be zero. */
554 uint8_t abReserved1[0x1E0];
555 /** 0x1e4: Signature \#1 (FAT32INFOSECTOR_SIGNATURE_2). */
556 uint32_t uSignature2;
557 /** 0x1e8: Last known number of free clusters (informational). */
558 uint32_t cFreeClusters;
559 /** 0x1ec: Last allocated cluster number (informational). This could be used as
560 * an allocation hint when searching for a free cluster. */
561 uint32_t cLastAllocatedCluster;
562 /** 0x1f0: Reserved, should be zero, preserve. */
563 uint8_t abReserved2[12];
564 /** 0x1fc: Signature \#3 (FAT32INFOSECTOR_SIGNATURE_3). */
565 uint32_t uSignature3;
566} FAT32INFOSECTOR;
567AssertCompileSize(FAT32INFOSECTOR, 0x200);
568/** Pointer to a FAT32 info sector. */
569typedef FAT32INFOSECTOR *PFAT32INFOSECTOR;
570/** Pointer to a const FAT32 info sector. */
571typedef FAT32INFOSECTOR const *PCFAT32INFOSECTOR;
572
573#define FAT32INFOSECTOR_SIGNATURE_1 UINT32_C(0x41615252)
574#define FAT32INFOSECTOR_SIGNATURE_2 UINT32_C(0x61417272)
575#define FAT32INFOSECTOR_SIGNATURE_3 UINT32_C(0xaa550000)
576
577
578/** @name Special FAT cluster numbers and limits.
579 * @{ */
580#define FAT_FIRST_DATA_CLUSTER 2 /**< The first data cluster. */
581
582#define FAT_MAX_FAT12_TOTAL_CLUSTERS UINT32_C(0x00000ff6) /**< Maximum number of clusters in a 12-bit FAT . */
583#define FAT_MAX_FAT16_TOTAL_CLUSTERS UINT32_C(0x0000fff6) /**< Maximum number of clusters in a 16-bit FAT . */
584#define FAT_MAX_FAT32_TOTAL_CLUSTERS UINT32_C(0x0ffffff6) /**< Maximum number of clusters in a 32-bit FAT . */
585
586#define FAT_LAST_FAT12_DATA_CLUSTER UINT32_C(0x00000ff5) /**< The last possible data cluster for FAT12. */
587#define FAT_LAST_FAT16_DATA_CLUSTER UINT32_C(0x0000fff5) /**< The last possible data cluster for FAT16. */
588#define FAT_LAST_FAT32_DATA_CLUSTER UINT32_C(0x0ffffff5) /**< The last possible data cluster for FAT32. */
589
590#define FAT_MAX_FAT12_DATA_CLUSTERS UINT32_C(0x00000ff4) /**< Maximum number of data clusters for FAT12. */
591#define FAT_MAX_FAT16_DATA_CLUSTERS UINT32_C(0x0000fff4) /**< Maximum number of data clusters for FAT16. */
592#define FAT_MAX_FAT32_DATA_CLUSTERS UINT32_C(0x0ffffff4) /**< Maximum number of data clusters for FAT32. */
593
594#define FAT_MIN_FAT12_DATA_CLUSTERS UINT32_C(0x00000001) /**< Maximum number of data clusters for FAT12. */
595#define FAT_MIN_FAT16_DATA_CLUSTERS UINT32_C(0x00000ff5) /**< Maximum number of data clusters for FAT16. */
596#define FAT_MIN_FAT32_DATA_CLUSTERS UINT32_C(0x0000fff5) /**< Maximum number of data clusters for FAT32. */
597
598#define FAT_FIRST_FAT12_EOC UINT32_C(0x00000ff8) /**< The first end-of-file-cluster number for FAT12. */
599#define FAT_FIRST_FAT16_EOC UINT32_C(0x0000fff8) /**< The first end-of-file-cluster number for FAT16. */
600#define FAT_FIRST_FAT32_EOC UINT32_C(0x0ffffff8) /**< The first end-of-file-cluster number for FAT32. */
601/** @} */
602
603
604/**
605 * FAT directory entry.
606 */
607typedef struct FATDIRENTRY
608{
609 /** 0x00: The directory entry name.
610 * First character serves as a flag to indicate deleted or not. */
611 uint8_t achName[8+3];
612 /** 0x0b: Attributes (FAT_ATTR_XXX). */
613 uint8_t fAttrib;
614 /** 0x0c: NT case flags (FATDIRENTRY_CASE_F_XXX). */
615 uint8_t fCase;
616 /** 0x0d: Birth milliseconds (DOS 7.0+ w/VFAT). */
617 uint8_t uBirthCentiseconds;
618 /** 0x0e: Birth time (DOS 7.0+ w/VFAT). */
619 uint16_t uBirthTime;
620 /** 0x10: Birth date (DOS 7.0+ w/VFAT). */
621 uint16_t uBirthDate;
622 /** 0x12: Access date (DOS 7.0+ w/ACCDATA in Config.sys). */
623 uint16_t uAccessDate;
624 union
625 {
626 /** 0x14: High cluster word for FAT32. */
627 uint16_t idxClusterHigh;
628 /** 0x14: Index of extended attributes (FAT16/FAT12). */
629 uint16_t idxEAs;
630 } u;
631 /** 0x16: Modify time (PC-DOS 1.1+, MS-DOS 1.20+). */
632 uint16_t uModifyTime;
633 /** 0x18: Modify date. */
634 uint16_t uModifyDate;
635 /** 0x1a: The data cluster index. */
636 uint16_t idxCluster;
637 /** 0x1c: The file size. */
638 uint32_t cbFile;
639} FATDIRENTRY;
640AssertCompileSize(FATDIRENTRY, 0x20);
641AssertCompileMemberOffset(FATDIRENTRY, fAttrib, 0x0b);
642AssertCompileMemberOffset(FATDIRENTRY, fCase, 0x0c);
643AssertCompileMemberOffset(FATDIRENTRY, uBirthCentiseconds, 0x0d);
644AssertCompileMemberOffset(FATDIRENTRY, uBirthTime, 0x0e);
645AssertCompileMemberOffset(FATDIRENTRY, uBirthDate, 0x10);
646AssertCompileMemberOffset(FATDIRENTRY, uAccessDate, 0x12);
647AssertCompileMemberOffset(FATDIRENTRY, u, 0x14);
648AssertCompileMemberOffset(FATDIRENTRY, uModifyTime, 0x16);
649AssertCompileMemberOffset(FATDIRENTRY, uModifyDate, 0x18);
650AssertCompileMemberOffset(FATDIRENTRY, idxCluster, 0x1a);
651AssertCompileMemberOffset(FATDIRENTRY, cbFile, 0x1c);
652/** Pointer to a FAT directory entry. */
653typedef FATDIRENTRY *PFATDIRENTRY;
654/** Pointer to a FAT directory entry. */
655typedef FATDIRENTRY const *PCFATDIRENTRY;
656
657
658/** @name FAT_ATTR_XXX - FATDIRENTRY::fAttrib flags.
659 * @{ */
660#define FAT_ATTR_READONLY UINT8_C(0x01)
661#define FAT_ATTR_HIDDEN UINT8_C(0x02)
662#define FAT_ATTR_SYSTEM UINT8_C(0x04)
663#define FAT_ATTR_VOLUME UINT8_C(0x08)
664#define FAT_ATTR_DIRECTORY UINT8_C(0x10)
665#define FAT_ATTR_ARCHIVE UINT8_C(0x20)
666#define FAT_ATTR_DEVICE UINT8_C(0x40)
667#define FAT_ATTR_RESERVED UINT8_C(0x80)
668#define FAT_ATTR_NAME_SLOT UINT8_C(0x0f) /**< Special attribute value for FATDIRNAMESLOT. */
669/** @} */
670
671/** @name FATDIRENTRY_CASE_F_XXX - FATDIRENTRY::fCase flags.
672 * @{ */
673/** Lower cased base name (first 8 chars). */
674#define FATDIRENTRY_CASE_F_LOWER_BASE UINT8_C(0x08)
675/** Lower cased filename extension (last 3 chars). */
676#define FATDIRENTRY_CASE_F_LOWER_EXT UINT8_C(0x10)
677/** @} */
678
679/** @name FATDIRENTRY_CH0_XXX - FATDIRENTRY::achName[0]
680 * @{ */
681/** Deleted entry. */
682#define FATDIRENTRY_CH0_DELETED UINT8_C(0xe5)
683/** End of used directory entries (MS-DOS 1.25+, PC-DOS 2.0+). */
684#define FATDIRENTRY_CH0_END_OF_DIR UINT8_C(0x00)
685/** The special dot or dot-dot dir aliases (MS-DOS 1.40+, PC-DOS 2.0+).
686 * @remarks 0x2e is the ascii table entry of the '.' character. */
687#define FATDIRENTRY_CH0_DOT_ALIAS UINT8_C(0x2e)
688/** Escaped 0xe5 leadcharacter (DOS 3.0+). */
689#define FATDIRENTRY_CH0_ESC_E5 UINT8_C(0x05)
690/** @} */
691
692
693/**
694 * FAT directory alias name slot.
695 *
696 * Each slot holds 13 UTF-16 (/ UCS-2) characters, so it takes 20 slots to cover
697 * a 255 character long name.
698 */
699#pragma pack(1)
700typedef struct FATDIRNAMESLOT
701{
702 /** The slot sequence number. */
703 uint8_t idSlot;
704 /** The first 5 name chars.
705 * @remarks misaligned */
706 RTUTF16 awcName0[5];
707 /** Attributes (FAT_ATTR_XXX). */
708 uint8_t fAttrib;
709 /** Always zero. */
710 uint8_t fZero;
711 /** Alias checksum. */
712 uint8_t bChecksum;
713 /** The next 6 name chars. */
714 RTUTF16 awcName1[6];
715 /** Always zero (usually cluster entry). */
716 uint16_t idxZero;
717 /** The next 2 name chars. */
718 RTUTF16 awcName2[2];
719} FATDIRNAMESLOT;
720#pragma pack()
721AssertCompileSize(FATDIRNAMESLOT, 0x20);
722/** Pointer to a FAT directory entry. */
723typedef FATDIRNAMESLOT *PFATDIRNAMESLOT;
724/** Pointer to a FAT directory entry. */
725typedef FATDIRNAMESLOT const *PCFATDIRNAMESLOT;
726
727/** Slot ID flag indicating that it's the first slot. */
728#define FATDIRNAMESLOT_FIRST_SLOT_FLAG UINT8_C(0x40)
729/** Highest slot ID recognized. This allows for 260 characters, however many
730 * implementation limits it to 255 or 250. */
731#define FATDIRNAMESLOT_HIGHEST_SLOT_ID UINT8_C(0x14)
732/** Max number of slots recognized. (This is the same as the higest slot ID
733 * because the 0 isn't a valid ID.) */
734#define FATDIRNAMESLOT_MAX_SLOTS FATDIRNAMESLOT_HIGHEST_SLOT_ID
735/** Number of UTF-16 units per slot. */
736#define FATDIRNAMESLOT_CHARS_PER_SLOT (5 + 6 + 2)
737
738
739
740/**
741 * FAT directory entry union.
742 */
743typedef union FATDIRENTRYUNION
744{
745 /** Regular entry view. */
746 FATDIRENTRY Entry;
747 /** Name slot view. */
748 FATDIRNAMESLOT Slot;
749} FATDIRENTRYUNION;
750AssertCompileSize(FATDIRENTRYUNION, 0x20);
751/** Pointer to a FAT directory entry union. */
752typedef FATDIRENTRYUNION *PFATDIRENTRYUNION;
753/** Pointer to a const FAT directory entry union. */
754typedef FATDIRENTRYUNION const *PCFATDIRENTRYUNION;
755
756/** @} */
757
758#endif /* !IPRT_INCLUDED_formats_fat_h */
759
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