FatStructs.h
1 /* Arduino SdFat Library 2 * Copyright (C) 2009 by William Greiman 3 * 4 * This file is part of the Arduino SdFat Library 5 * 6 * This Library is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This Library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with the Arduino SdFat Library. If not, see 18 * <http://www.gnu.org/licenses/>. 19 */ 20 #ifndef FatStructs_h 21 #define FatStructs_h 22 /** 23 * \file 24 * FAT file structures 25 */ 26 /* 27 * mostly from Microsoft document fatgen103.doc 28 * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx 29 */ 30 //------------------------------------------------------------------------------ 31 /** Value for byte 510 of boot block or MBR */ 32 uint8_t const BOOTSIG0 = 0X55; 33 /** Value for byte 511 of boot block or MBR */ 34 uint8_t const BOOTSIG1 = 0XAA; 35 //------------------------------------------------------------------------------ 36 /** 37 * \struct partitionTable 38 * \brief MBR partition table entry 39 * 40 * A partition table entry for a MBR formatted storage device. 41 * The MBR partition table has four entries. 42 */ 43 struct partitionTable { 44 /** 45 * Boot Indicator . Indicates whether the volume is the active 46 * partition. Legal values include: 0X00. Do not use for booting. 47 * 0X80 Active partition. 48 */ 49 uint8_t boot; 50 /** 51 * Head part of Cylinder-head-sector address of the first block in 52 * the partition. Legal values are 0-255. Only used in old PC BIOS. 53 */ 54 uint8_t beginHead; 55 /** 56 * Sector part of Cylinder-head-sector address of the first block in 57 * the partition. Legal values are 1-63. Only used in old PC BIOS. 58 */ 59 unsigned beginSector : 6; 60 /** High bits cylinder for first block in partition. */ 61 unsigned beginCylinderHigh : 2; 62 /** 63 * Combine beginCylinderLow with beginCylinderHigh. Legal values 64 * are 0-1023. Only used in old PC BIOS. 65 */ 66 uint8_t beginCylinderLow; 67 /** 68 * Partition type. See defines that begin with PART_TYPE_ for 69 * some Microsoft partition types. 70 */ 71 uint8_t type; 72 /** 73 * head part of cylinder-head-sector address of the last sector in the 74 * partition. Legal values are 0-255. Only used in old PC BIOS. 75 */ 76 uint8_t endHead; 77 /** 78 * Sector part of cylinder-head-sector address of the last sector in 79 * the partition. Legal values are 1-63. Only used in old PC BIOS. 80 */ 81 unsigned endSector : 6; 82 /** High bits of end cylinder */ 83 unsigned endCylinderHigh : 2; 84 /** 85 * Combine endCylinderLow with endCylinderHigh. Legal values 86 * are 0-1023. Only used in old PC BIOS. 87 */ 88 uint8_t endCylinderLow; 89 /** Logical block address of the first block in the partition. */ 90 uint32_t firstSector; 91 /** Length of the partition, in blocks. */ 92 uint32_t totalSectors; 93 }; 94 /** Type name for partitionTable */ 95 typedef struct partitionTable part_t; 96 //------------------------------------------------------------------------------ 97 /** 98 * \struct masterBootRecord 99 * 100 * \brief Master Boot Record 101 * 102 * The first block of a storage device that is formatted with a MBR. 103 */ 104 struct masterBootRecord { 105 /** Code Area for master boot program. */ 106 uint8_t codeArea[440]; 107 /** Optional WindowsNT disk signature. May contain more boot code. */ 108 uint32_t diskSignature; 109 /** Usually zero but may be more boot code. */ 110 uint16_t usuallyZero; 111 /** Partition tables. */ 112 part_t part[4]; 113 /** First MBR signature byte. Must be 0X55 */ 114 uint8_t mbrSig0; 115 /** Second MBR signature byte. Must be 0XAA */ 116 uint8_t mbrSig1; 117 }; 118 /** Type name for masterBootRecord */ 119 typedef struct masterBootRecord mbr_t; 120 //------------------------------------------------------------------------------ 121 /** 122 * \struct biosParmBlock 123 * 124 * \brief BIOS parameter block 125 * 126 * The BIOS parameter block describes the physical layout of a FAT volume. 127 */ 128 struct biosParmBlock { 129 /** 130 * Count of bytes per sector. This value may take on only the 131 * following values: 512, 1024, 2048 or 4096 132 */ 133 uint16_t bytesPerSector; 134 /** 135 * Number of sectors per allocation unit. This value must be a 136 * power of 2 that is greater than 0. The legal values are 137 * 1, 2, 4, 8, 16, 32, 64, and 128. 138 */ 139 uint8_t sectorsPerCluster; 140 /** 141 * Number of sectors before the first FAT. 142 * This value must not be zero. 143 */ 144 uint16_t reservedSectorCount; 145 /** The count of FAT data structures on the volume. This field should 146 * always contain the value 2 for any FAT volume of any type. 147 */ 148 uint8_t fatCount; 149 /** 150 * For FAT12 and FAT16 volumes, this field contains the count of 151 * 32-byte directory entries in the root directory. For FAT32 volumes, 152 * this field must be set to 0. For FAT12 and FAT16 volumes, this 153 * value should always specify a count that when multiplied by 32 154 * results in a multiple of bytesPerSector. FAT16 volumes should 155 * use the value 512. 156 */ 157 uint16_t rootDirEntryCount; 158 /** 159 * This field is the old 16-bit total count of sectors on the volume. 160 * This count includes the count of all sectors in all four regions 161 * of the volume. This field can be 0; if it is 0, then totalSectors32 162 * must be non-zero. For FAT32 volumes, this field must be 0. For 163 * FAT12 and FAT16 volumes, this field contains the sector count, and 164 * totalSectors32 is 0 if the total sector count fits 165 * (is less than 0x10000). 166 */ 167 uint16_t totalSectors16; 168 /** 169 * This dates back to the old MS-DOS 1.x media determination and is 170 * no longer usually used for anything. 0xF8 is the standard value 171 * for fixed (non-removable) media. For removable media, 0xF0 is 172 * frequently used. Legal values are 0xF0 or 0xF8-0xFF. 173 */ 174 uint8_t mediaType; 175 /** 176 * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. 177 * On FAT32 volumes this field must be 0, and sectorsPerFat32 178 * contains the FAT size count. 179 */ 180 uint16_t sectorsPerFat16; 181 /** Sectors per track for interrupt 0x13. Not used otherwise. */ 182 uint16_t sectorsPerTrtack; 183 /** Number of heads for interrupt 0x13. Not used otherwise. */ 184 uint16_t headCount; 185 /** 186 * Count of hidden sectors preceding the partition that contains this 187 * FAT volume. This field is generally only relevant for media 188 * visible on interrupt 0x13. 189 */ 190 uint32_t hidddenSectors; 191 /** 192 * This field is the new 32-bit total count of sectors on the volume. 193 * This count includes the count of all sectors in all four regions 194 * of the volume. This field can be 0; if it is 0, then 195 * totalSectors16 must be non-zero. 196 */ 197 uint32_t totalSectors32; 198 /** 199 * Count of sectors occupied by one FAT on FAT32 volumes. 200 */ 201 uint32_t sectorsPerFat32; 202 /** 203 * This field is only defined for FAT32 media and does not exist on 204 * FAT12 and FAT16 media. 205 * Bits 0-3 -- Zero-based number of active FAT. 206 * Only valid if mirroring is disabled. 207 * Bits 4-6 -- Reserved. 208 * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. 209 * -- 1 means only one FAT is active; it is the one referenced in bits 0-3. 210 * Bits 8-15 -- Reserved. 211 */ 212 uint16_t fat32Flags; 213 /** 214 * FAT32 version. High byte is major revision number. 215 * Low byte is minor revision number. Only 0.0 define. 216 */ 217 uint16_t fat32Version; 218 /** 219 * Cluster number of the first cluster of the root directory for FAT32. 220 * This usually 2 but not required to be 2. 221 */ 222 uint32_t fat32RootCluster; 223 /** 224 * Sector number of FSINFO structure in the reserved area of the 225 * FAT32 volume. Usually 1. 226 */ 227 uint16_t fat32FSInfo; 228 /** 229 * If non-zero, indicates the sector number in the reserved area 230 * of the volume of a copy of the boot record. Usually 6. 231 * No value other than 6 is recommended. 232 */ 233 uint16_t fat32BackBootBlock; 234 /** 235 * Reserved for future expansion. Code that formats FAT32 volumes 236 * should always set all of the bytes of this field to 0. 237 */ 238 uint8_t fat32Reserved[12]; 239 }; 240 /** Type name for biosParmBlock */ 241 typedef struct biosParmBlock bpb_t; 242 //------------------------------------------------------------------------------ 243 /** 244 * \struct fat32BootSector 245 * 246 * \brief Boot sector for a FAT16 or FAT32 volume. 247 * 248 */ 249 struct fat32BootSector { 250 /** X86 jmp to boot program */ 251 uint8_t jmpToBootCode[3]; 252 /** informational only - don't depend on it */ 253 char oemName[8]; 254 /** BIOS Parameter Block */ 255 bpb_t bpb; 256 /** for int0x13 use value 0X80 for hard drive */ 257 uint8_t driveNumber; 258 /** used by Windows NT - should be zero for FAT */ 259 uint8_t reserved1; 260 /** 0X29 if next three fields are valid */ 261 uint8_t bootSignature; 262 /** usually generated by combining date and time */ 263 uint32_t volumeSerialNumber; 264 /** should match volume label in root dir */ 265 char volumeLabel[11]; 266 /** informational only - don't depend on it */ 267 char fileSystemType[8]; 268 /** X86 boot code */ 269 uint8_t bootCode[420]; 270 /** must be 0X55 */ 271 uint8_t bootSectorSig0; 272 /** must be 0XAA */ 273 uint8_t bootSectorSig1; 274 }; 275 //------------------------------------------------------------------------------ 276 // End Of Chain values for FAT entries 277 /** FAT16 end of chain value used by Microsoft. */ 278 uint16_t const FAT16EOC = 0XFFFF; 279 /** Minimum value for FAT16 EOC. Use to test for EOC. */ 280 uint16_t const FAT16EOC_MIN = 0XFFF8; 281 /** FAT32 end of chain value used by Microsoft. */ 282 uint32_t const FAT32EOC = 0X0FFFFFFF; 283 /** Minimum value for FAT32 EOC. Use to test for EOC. */ 284 uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; 285 /** Mask a for FAT32 entry. Entries are 28 bits. */ 286 uint32_t const FAT32MASK = 0X0FFFFFFF; 287 288 /** Type name for fat32BootSector */ 289 typedef struct fat32BootSector fbs_t; 290 //------------------------------------------------------------------------------ 291 /** 292 * \struct directoryEntry 293 * \brief FAT short directory entry 294 * 295 * Short means short 8.3 name, not the entry size. 296 * 297 * Date Format. A FAT directory entry date stamp is a 16-bit field that is 298 * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the 299 * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 300 * 16-bit word): 301 * 302 * Bits 9-15: Count of years from 1980, valid value range 0-127 303 * inclusive (1980-2107). 304 * 305 * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. 306 * 307 * Bits 0-4: Day of month, valid value range 1-31 inclusive. 308 * 309 * Time Format. A FAT directory entry time stamp is a 16-bit field that has 310 * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the 311 * 16-bit word, bit 15 is the MSB of the 16-bit word). 312 * 313 * Bits 11-15: Hours, valid value range 0-23 inclusive. 314 * 315 * Bits 5-10: Minutes, valid value range 0-59 inclusive. 316 * 317 * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). 318 * 319 * The valid time range is from Midnight 00:00:00 to 23:59:58. 320 */ 321 struct directoryEntry { 322 /** 323 * Short 8.3 name. 324 * The first eight bytes contain the file name with blank fill. 325 * The last three bytes contain the file extension with blank fill. 326 */ 327 uint8_t name[11]; 328 /** Entry attributes. 329 * 330 * The upper two bits of the attribute byte are reserved and should 331 * always be set to 0 when a file is created and never modified or 332 * looked at after that. See defines that begin with DIR_ATT_. 333 */ 334 uint8_t attributes; 335 /** 336 * Reserved for use by Windows NT. Set value to 0 when a file is 337 * created and never modify or look at it after that. 338 */ 339 uint8_t reservedNT; 340 /** 341 * The granularity of the seconds part of creationTime is 2 seconds 342 * so this field is a count of tenths of a second and its valid 343 * value range is 0-199 inclusive. (WHG note - seems to be hundredths) 344 */ 345 uint8_t creationTimeTenths; 346 /** Time file was created. */ 347 uint16_t creationTime; 348 /** Date file was created. */ 349 uint16_t creationDate; 350 /** 351 * Last access date. Note that there is no last access time, only 352 * a date. This is the date of last read or write. In the case of 353 * a write, this should be set to the same date as lastWriteDate. 354 */ 355 uint16_t lastAccessDate; 356 /** 357 * High word of this entry's first cluster number (always 0 for a 358 * FAT12 or FAT16 volume). 359 */ 360 uint16_t firstClusterHigh; 361 /** Time of last write. File creation is considered a write. */ 362 uint16_t lastWriteTime; 363 /** Date of last write. File creation is considered a write. */ 364 uint16_t lastWriteDate; 365 /** Low word of this entry's first cluster number. */ 366 uint16_t firstClusterLow; 367 /** 32-bit unsigned holding this file's size in bytes. */ 368 uint32_t fileSize; 369 }; 370 //------------------------------------------------------------------------------ 371 // Definitions for directory entries 372 // 373 /** Type name for directoryEntry */ 374 typedef struct directoryEntry dir_t; 375 /** escape for name[0] = 0XE5 */ 376 uint8_t const DIR_NAME_0XE5 = 0X05; 377 /** name[0] value for entry that is free after being "deleted" */ 378 uint8_t const DIR_NAME_DELETED = 0XE5; 379 /** name[0] value for entry that is free and no allocated entries follow */ 380 uint8_t const DIR_NAME_FREE = 0X00; 381 /** file is read-only */ 382 uint8_t const DIR_ATT_READ_ONLY = 0X01; 383 /** File should hidden in directory listings */ 384 uint8_t const DIR_ATT_HIDDEN = 0X02; 385 /** Entry is for a system file */ 386 uint8_t const DIR_ATT_SYSTEM = 0X04; 387 /** Directory entry contains the volume label */ 388 uint8_t const DIR_ATT_VOLUME_ID = 0X08; 389 /** Entry is for a directory */ 390 uint8_t const DIR_ATT_DIRECTORY = 0X10; 391 /** Old DOS archive bit for backup support */ 392 uint8_t const DIR_ATT_ARCHIVE = 0X20; 393 /** Test value for long name entry. Test is 394 (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ 395 uint8_t const DIR_ATT_LONG_NAME = 0X0F; 396 /** Test mask for long name entry */ 397 uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; 398 /** defined attribute bits */ 399 uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; 400 /** Directory entry is part of a long name */ 401 static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { 402 return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; 403 } 404 /** Mask for file/subdirectory tests */ 405 uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); 406 /** Directory entry is for a file */ 407 static inline uint8_t DIR_IS_FILE(const dir_t* dir) { 408 return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; 409 } 410 /** Directory entry is for a subdirectory */ 411 static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { 412 return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; 413 } 414 /** Directory entry is for a file or subdirectory */ 415 static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { 416 return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; 417 } 418 #endif // FatStructs_h