VirtualBox

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

Last change on this file since 69067 was 68687, checked in by vboxsync, 7 years ago

iprt/formats/*.h: Use assertcompile.h instead of assert.h.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.0 KB
Line 
1/* $Id: fat.h 68687 2017-09-06 18:11:39Z 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. */
283 uint16_t cReservedSectors;
284 /** 0x10 / 0x05: Number of FATs. */
285 uint8_t cFats;
286 /** 0x11 / 0x06: Max size of the root directory (0 for FAT32). */
287 uint16_t cMaxRootDirEntries;
288 /** 0x13 / 0x08: Total sector count, zero if 32-bit count is used. */
289 uint16_t cTotalSectors16;
290 /** 0x15 / 0x0a: Media ID. */
291 uint8_t bMedia;
292 /** 0x16 / 0x0b: Number of sectors per FAT (0 for FAT32). */
293 uint16_t cSectorsPerFat;
294 /** @} */
295 /** @name New in DOS 3.0
296 * @{ */
297 /** 0x18 / 0x0d: Sectors per track. Zero means reserved and not used. */
298 uint16_t cSectorsPerTrack;
299 /** 0x1a / 0x0f: Number of heads. Zero means reserved and not used. */
300 uint16_t cTracksPerCylinder;
301 /** @} */
302 /** @name New in DOS 3.31
303 * @{ */
304 /** 0x1c / 0x11: Number of hidden sectors preceeding the volume. This is zero
305 * on unpartitioned media. Values higher than 65535 are complicated due to
306 * the field overlapping FATBPB32::cAnotherTotalSectors */
307 uint32_t cHiddenSectors;
308 /** 0x20 / 0x15: Total logical sectors. Used if count >= 64K, otherwise
309 * FATBPB20::cTotalSectors16 is used. Zero if 64-bit value used with FAT32. */
310 uint32_t cTotalSectors32;
311 /** @} */
312} FATBPB331FLAT;
313#pragma pack()
314AssertCompileSize(FATBPB331FLAT, 0x19);
315/** Pointer to a flattened DOS 3.31 BPB. */
316typedef FATBPB331FLAT *PFATBPB331FLAT;
317/** Pointer to a const flattened DOS 3.31 BPB. */
318typedef FATBPB331FLAT *PFATBPB331FLAT;
319
320
321/**
322 * Extended BIOS parameter block (EBPB).
323 */
324#pragma pack(1)
325typedef struct FATEBPB
326{
327 /** The BPB. */
328 FATBPB331FLAT Bpb;
329
330 /** 0x24 / 0x19: BIOS INT13 pysical drive number. */
331 uint8_t bInt13Drive;
332 /** 0x25 / 0x1a: Reserved. NT used bit 0 for indicating dirty FS, and bit 1
333 * for surface scan. */
334 uint8_t bReserved;
335 /** 0x26 / 0x1b: Extended boot signature, FATEBPB_SIGNATURE or
336 * FATEBPB_SIGNATURE_OLD. */
337 uint8_t bExtSignature;
338 /** 0x27 / 0x1c: The volume serial number. */
339 uint32_t uSerialNumber;
340 /** 0x2b / 0x20: The volume label (space padded).
341 * @remarks Not available with FATEBPB_SIGNATURE_OLD */
342 char achLabel[11];
343 /** 0x36 / 0x2b: The file system type (space padded).
344 * @remarks Not available with FATEBPB_SIGNATURE_OLD */
345 char achType[8];
346} FATEBPB;
347#pragma pack()
348AssertCompileSize(FATEBPB, 0x33);
349/** Pointer to an extended BIOS parameter block. */
350typedef FATEBPB *PFATEBPB;
351/** Pointer to a const extended BIOS parameter block. */
352typedef FATEBPB const *PCFATEBPB;
353
354/** FATEBPB::bExtSignature value. */
355#define FATEBPB_SIGNATURE UINT8_C(0x29)
356/** FATEBPB::bExtSignature value used by OS/2 1.0-1.1 and PC DOS 3.4. These
357 * does not have the volume and file system type. */
358#define FATEBPB_SIGNATURE_OLD UINT8_C(0x28)
359
360/**FATEBPB::achType value for FAT12. */
361#define FATEBPB_TYPE_FAT12 "FAT12 "
362/**FATEBPB::achType value for FAT16. */
363#define FATEBPB_TYPE_FAT16 "FAT16 "
364/**FATEBPB::achType value for FAT12/FAT16. */
365#define FATEBPB_TYPE_FAT "FAT32 "
366
367
368/**
369 * FAT32 Extended BIOS parameter block (EBPB).
370 */
371#pragma pack(1)
372typedef struct FAT32EBPB
373{
374 /** The BPB. */
375 FATBPB331FLAT Bpb;
376
377 /** 0x24 / 0x19: Number of sectors per FAT.
378 * @note To avoid confusion with the FATEBPB signature, values which result in
379 * 0x00280000 or 0x00290000 when masked by 0x00ff0000 must not be used. */
380 uint32_t cSectorsPerFat32;
381 /** 0x28 / 0x1d: Flags pertaining to FAT mirroring and other stuff. */
382 uint16_t fFlags;
383 /** 0x2a / 0x1f: FAT32 version number (FAT32EBPB_VERSION_0_0). */
384 uint16_t uVersion;
385 /** 0x2c / 0x21: Cluster number of the root directory. */
386 uint32_t uRootDirCluster;
387 /** 0x30 / 0x25: Logical sector number of the information sector. */
388 uint16_t uInfoSectorNo;
389 /** 0x32 / 0x27: Logical sector number of boot sector copy. */
390 uint16_t uBootSectorCopySectorNo;
391 /** 0x34 / 0x29: Reserved, zero (or 0xf6) filled, preserve. */
392 uint8_t abReserved[12];
393
394 /** 0x40 / 0x35: BIOS INT13 pysical drive number
395 * @remarks Same as FATEBPB::bInt13Drive. */
396 uint8_t bInt13Drive;
397 /** 0x41 / 0x36: Reserved.
398 * @remarks Same as FATEBPB::bReserved. */
399 uint8_t bReserved;
400 /** 0x42 / 0x37: Extended boot signature (FATEBPB_SIGNATURE, or
401 * FATEBPB_SIGNATURE_OLD in some special cases).
402 * @remarks Same as FATEBPB::bExtSignature. */
403 uint8_t bExtSignature;
404 /** 0x43 / 0x38: The volume serial number.
405 * @remarks Same as FATEBPB::uSerialNumber. */
406 uint32_t uSerialNumber;
407 /** 0x47 / 0x3c: The volume label (space padded).
408 * @remarks Not available with FATEBPB_SIGNATURE_OLD
409 * @remarks Same as FATEBPB::achLabel. */
410 char achLabel[11];
411 /** 0x52 / 0x47: The file system type (space padded), or 64-bit logical sector
412 * count if both other count fields are zero. In the latter case, the type is
413 * moved to the OEM name field (FATBOOTSECTOR::achOemName).
414 *
415 * @remarks Not available with FATEBPB_SIGNATURE_OLD
416 * @remarks Same as FATEBPB::achType. */
417 union
418 {
419 /** Type string variant. */
420 char achType[8];
421 /** Total sector count if 4G or higher. */
422 uint64_t cTotalSectors64;
423 } u;
424} FAT32EBPB;
425#pragma pack()
426AssertCompileSize(FAT32EBPB, 0x4f);
427/** Pointer to a FAT32 extended BIOS parameter block. */
428typedef FAT32EBPB *PFAT32EBPB;
429/** Pointer to a const FAT32 extended BIOS parameter block. */
430typedef FAT32EBPB const *PCFAT32EBPB;
431
432/** FAT32 version 0.0 (FAT32EBPB::uVersion). */
433#define FAT32EBPB_VERSION_0_0 UINT16_C(0x0000)
434
435
436/**
437 * FAT boot sector layout.
438 */
439#pragma pack(1)
440typedef struct FATBOOTSECTOR
441{
442 /** 0x000: DOS 2.0+ jump sequence. */
443 uint8_t abJmp[3];
444 /** 0x003: OEM name (who formatted this volume). */
445 char achOemName[8];
446 /** 0x00b: The BIOS parameter block.
447 * This varies a lot in size. */
448 union
449 {
450 FATBPB20 Bpb20;
451 FATBPB30FLAT Bpb30;
452 FATBPB32FLAT Bpb32;
453 FATBPB331FLAT Bpb331;
454 FATEBPB Ebpb;
455 FAT32EBPB Fat32Ebpb;
456 } Bpb;
457 /** 0x05a: Bootloader code/data/stuff. */
458 uint8_t abStuff[0x1a3];
459 /** 0x1fd: Old drive number location (DOS 3.2-3.31). */
460 uint8_t bOldInt13Drive;
461 /** 0x1fe: DOS signature (FATBOOTSECTOR_SIGNATURE). */
462 uint16_t uSignature;
463} FATBOOTSECTOR;
464#pragma pack()
465AssertCompileSize(FATBOOTSECTOR, 0x200);
466/** Pointer to a FAT boot sector. */
467typedef FATBOOTSECTOR *PFATBOOTSECTOR;
468/** Pointer to a const FAT boot sector. */
469typedef FATBOOTSECTOR const *PCFATBOOTSECTOR;
470
471/** Boot sector signature (FATBOOTSECTOR::uSignature). */
472#define FATBOOTSECTOR_SIGNATURE UINT16_C(0xaa55)
473
474
475
476/**
477 * FAT32 info sector (follows the boot sector).
478 */
479typedef struct FAT32INFOSECTOR
480{
481 /** 0x000: Signature \#1 (FAT32INFOSECTOR_SIGNATURE_1). */
482 uint32_t uSignature1;
483 /** Reserved, should be zero. */
484 uint8_t abReserved1[0x1E0];
485 /** 0x1e4: Signature \#1 (FAT32INFOSECTOR_SIGNATURE_2). */
486 uint32_t uSignature2;
487 /** 0x1e8: Last known number of free clusters (informational). */
488 uint32_t cFreeClusters;
489 /** 0x1ec: Last allocated cluster number (informational). This could be used as
490 * an allocation hint when searching for a free cluster. */
491 uint32_t cLastAllocatedCluster;
492 /** 0x1f0: Reserved, should be zero, preserve. */
493 uint8_t abReserved2[12];
494 /** 0x1fc: Signature \#3 (FAT32INFOSECTOR_SIGNATURE_3). */
495 uint32_t uSignature3;
496} FAT32INFOSECTOR;
497AssertCompileSize(FAT32INFOSECTOR, 0x200);
498/** Pointer to a FAT32 info sector. */
499typedef FAT32INFOSECTOR *PFAT32INFOSECTOR;
500/** Pointer to a const FAT32 info sector. */
501typedef FAT32INFOSECTOR const *PCFAT32INFOSECTOR;
502
503#define FAT32INFOSECTOR_SIGNATURE_1 UINT32_C(0x41615252)
504#define FAT32INFOSECTOR_SIGNATURE_2 UINT32_C(0x61417272)
505#define FAT32INFOSECTOR_SIGNATURE_3 UINT32_C(0xaa550000)
506
507
508/** @name Special FAT cluster numbers and limits.
509 * @{ */
510#define FAT_FIRST_DATA_CLUSTER 2 /**< The first data cluster. */
511
512#define FAT_MAX_FAT12_TOTAL_CLUSTERS UINT32_C(0x00000ff6) /**< Maximum number of clusters in a 12-bit FAT . */
513#define FAT_MAX_FAT16_TOTAL_CLUSTERS UINT32_C(0x0000fff6) /**< Maximum number of clusters in a 16-bit FAT . */
514#define FAT_MAX_FAT32_TOTAL_CLUSTERS UINT32_C(0x0ffffff6) /**< Maximum number of clusters in a 32-bit FAT . */
515
516#define FAT_LAST_FAT12_DATA_CLUSTER UINT32_C(0x00000ff5) /**< The last possible data cluster for FAT12. */
517#define FAT_LAST_FAT16_DATA_CLUSTER UINT32_C(0x0000fff5) /**< The last possible data cluster for FAT16. */
518#define FAT_LAST_FAT32_DATA_CLUSTER UINT32_C(0x0ffffff5) /**< The last possible data cluster for FAT32. */
519
520#define FAT_MAX_FAT12_DATA_CLUSTERS UINT32_C(0x00000ff4) /**< Maximum number of data clusters for FAT12. */
521#define FAT_MAX_FAT16_DATA_CLUSTERS UINT32_C(0x0000fff4) /**< Maximum number of data clusters for FAT16. */
522#define FAT_MAX_FAT32_DATA_CLUSTERS UINT32_C(0x0ffffff4) /**< Maximum number of data clusters for FAT32. */
523
524#define FAT_MIN_FAT12_DATA_CLUSTERS UINT32_C(0x00000001) /**< Maximum number of data clusters for FAT12. */
525#define FAT_MIN_FAT16_DATA_CLUSTERS UINT32_C(0x00000ff5) /**< Maximum number of data clusters for FAT16. */
526#define FAT_MIN_FAT32_DATA_CLUSTERS UINT32_C(0x0000fff5) /**< Maximum number of data clusters for FAT32. */
527
528#define FAT_FIRST_FAT12_EOC UINT32_C(0x00000ff8) /**< The first end-of-file-cluster number for FAT12. */
529#define FAT_FIRST_FAT16_EOC UINT32_C(0x0000fff8) /**< The first end-of-file-cluster number for FAT16. */
530#define FAT_FIRST_FAT32_EOC UINT32_C(0x0ffffff8) /**< The first end-of-file-cluster number for FAT32. */
531/** @} */
532
533
534/**
535 * FAT directory entry.
536 */
537typedef struct FATDIRENTRY
538{
539 /** 0x00: The directory entry name.
540 * First character serves as a flag to indicate deleted or not. */
541 uint8_t achName[8+3];
542 /** 0x0b: Attributes (FAT_ATTR_XXX). */
543 uint8_t fAttrib;
544 /** 0x0c: NT case flags (FATDIRENTRY_CASE_F_XXX). */
545 uint8_t fCase;
546 /** 0x0d: Birth milliseconds (DOS 7.0+ w/VFAT). */
547 uint8_t uBirthCentiseconds;
548 /** 0x0e: Birth time (DOS 7.0+ w/VFAT). */
549 uint16_t uBirthTime;
550 /** 0x10: Birth date (DOS 7.0+ w/VFAT). */
551 uint16_t uBirthDate;
552 /** 0x12: Access date (DOS 7.0+ w/ACCDATA in Config.sys). */
553 uint16_t uAccessDate;
554 union
555 {
556 /** 0x14: High cluster word for FAT32. */
557 uint16_t idxClusterHigh;
558 /** 0x14: Index of extended attributes (FAT16/FAT12). */
559 uint16_t idxEAs;
560 } u;
561 /** 0x16: Modify time (PC-DOS 1.1+, MS-DOS 1.20+). */
562 uint16_t uModifyTime;
563 /** 0x18: Modify date. */
564 uint16_t uModifyDate;
565 /** 0x1a: The data cluster index. */
566 uint16_t idxCluster;
567 /** 0x1c: The file size. */
568 uint32_t cbFile;
569} FATDIRENTRY;
570AssertCompileSize(FATDIRENTRY, 0x20);
571AssertCompileMemberOffset(FATDIRENTRY, fAttrib, 0x0b);
572AssertCompileMemberOffset(FATDIRENTRY, fCase, 0x0c);
573AssertCompileMemberOffset(FATDIRENTRY, uBirthCentiseconds, 0x0d);
574AssertCompileMemberOffset(FATDIRENTRY, uBirthTime, 0x0e);
575AssertCompileMemberOffset(FATDIRENTRY, uBirthDate, 0x10);
576AssertCompileMemberOffset(FATDIRENTRY, uAccessDate, 0x12);
577AssertCompileMemberOffset(FATDIRENTRY, u, 0x14);
578AssertCompileMemberOffset(FATDIRENTRY, uModifyTime, 0x16);
579AssertCompileMemberOffset(FATDIRENTRY, uModifyDate, 0x18);
580AssertCompileMemberOffset(FATDIRENTRY, idxCluster, 0x1a);
581AssertCompileMemberOffset(FATDIRENTRY, cbFile, 0x1c);
582/** Pointer to a FAT directory entry. */
583typedef FATDIRENTRY *PFATDIRENTRY;
584/** Pointer to a FAT directory entry. */
585typedef FATDIRENTRY const *PCFATDIRENTRY;
586
587
588/** @name FAT_ATTR_XXX - FATDIRENTRY::fAttrib flags.
589 * @{ */
590#define FAT_ATTR_READONLY UINT8_C(0x01)
591#define FAT_ATTR_HIDDEN UINT8_C(0x02)
592#define FAT_ATTR_SYSTEM UINT8_C(0x04)
593#define FAT_ATTR_VOLUME UINT8_C(0x08)
594#define FAT_ATTR_DIRECTORY UINT8_C(0x10)
595#define FAT_ATTR_ARCHIVE UINT8_C(0x20)
596#define FAT_ATTR_DEVICE UINT8_C(0x40)
597#define FAT_ATTR_RESERVED UINT8_C(0x80)
598#define FAT_ATTR_NAME_SLOT UINT8_C(0x0f) /**< Special attribute value for FATDIRNAMESLOT. */
599/** @} */
600
601/** @name FATDIRENTRY_CASE_F_XXX - FATDIRENTRY::fCase flags.
602 * @{ */
603/** Lower cased base name (first 8 chars). */
604#define FATDIRENTRY_CASE_F_LOWER_BASE UINT8_C(0x08)
605/** Lower cased filename extension (last 3 chars). */
606#define FATDIRENTRY_CASE_F_LOWER_EXT UINT8_C(0x10)
607/** @} */
608
609/** @name FATDIRENTRY_CH0_XXX - FATDIRENTRY::achName[0]
610 * @{ */
611/** Deleted entry. */
612#define FATDIRENTRY_CH0_DELETED UINT8_C(0xe5)
613/** End of used directory entries (MS-DOS 1.25+, PC-DOS 2.0+). */
614#define FATDIRENTRY_CH0_END_OF_DIR UINT8_C(0x00)
615/** The special dot or dot-dot dir aliases (MS-DOS 1.40+, PC-DOS 2.0+).
616 * @remarks 0x2e is the ascii table entry of the '.' character. */
617#define FATDIRENTRY_CH0_DOT_ALIAS UINT8_C(0x2e)
618/** Escaped 0xe5 leadcharacter (DOS 3.0+). */
619#define FATDIRENTRY_CH0_ESC_E5 UINT8_C(0x05)
620/** @} */
621
622
623/**
624 * FAT directory alias name slot.
625 *
626 * Each slot holds 13 UTF-16 (/ UCS-2) characters, so it takes 20 slots to cover
627 * a 255 character long name.
628 */
629#pragma pack(1)
630typedef struct FATDIRNAMESLOT
631{
632 /** The slot sequence number. */
633 uint8_t idSlot;
634 /** The first 5 name chars.
635 * @remarks misaligned */
636 RTUTF16 awcName0[5];
637 /** Attributes (FAT_ATTR_XXX). */
638 uint8_t fAttrib;
639 /** Always zero. */
640 uint8_t fZero;
641 /** Alias checksum. */
642 uint8_t bChecksum;
643 /** The next 6 name chars. */
644 RTUTF16 awcName1[6];
645 /** Always zero (usually cluster entry). */
646 uint16_t idxZero;
647 /** The next 2 name chars. */
648 RTUTF16 awcName2[2];
649} FATDIRNAMESLOT;
650#pragma pack()
651AssertCompileSize(FATDIRNAMESLOT, 0x20);
652/** Pointer to a FAT directory entry. */
653typedef FATDIRNAMESLOT *PFATDIRNAMESLOT;
654/** Pointer to a FAT directory entry. */
655typedef FATDIRNAMESLOT const *PCFATDIRNAMESLOT;
656
657/** Slot ID flag indicating that it's the first slot. */
658#define FATDIRNAMESLOT_FIRST_SLOT_FLAG UINT8_C(0x40)
659/** Highest slot ID recognized. This allows for 260 characters, however many
660 * implementation limits it to 255 or 250. */
661#define FATDIRNAMESLOT_HIGHEST_SLOT_ID UINT8_C(0x14)
662/** Max number of slots recognized. (This is the same as the higest slot ID
663 * because the 0 isn't a valid ID.) */
664#define FATDIRNAMESLOT_MAX_SLOTS FATDIRNAMESLOT_HIGHEST_SLOT_ID
665/** Number of UTF-16 units per slot. */
666#define FATDIRNAMESLOT_CHARS_PER_SLOT (5 + 6 + 2)
667
668
669
670/**
671 * FAT directory entry union.
672 */
673typedef union FATDIRENTRYUNION
674{
675 /** Regular entry view. */
676 FATDIRENTRY Entry;
677 /** Name slot view. */
678 FATDIRNAMESLOT Slot;
679} FATDIRENTRYUNION;
680AssertCompileSize(FATDIRENTRYUNION, 0x20);
681/** Pointer to a FAT directory entry union. */
682typedef FATDIRENTRYUNION *PFATDIRENTRYUNION;
683/** Pointer to a const FAT directory entry union. */
684typedef FATDIRENTRYUNION const *PCFATDIRENTRYUNION;
685
686/** @} */
687
688#endif
689
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