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