VirtualBox

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

Last change on this file since 75704 was 69910, checked in by vboxsync, 7 years ago

IPRT/ntfsvfs.cpp: More on the subject of directories (indexes).

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