VirtualBox

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

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