Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
FatStructs.h
00001 /* Arduino SdFat Library 00002 * Copyright (C) 2009 by William Greiman 00003 * 00004 * This file is part of the Arduino SdFat Library 00005 * 00006 * This Library is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This Library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with the Arduino SdFat Library. If not, see 00018 * <http://www.gnu.org/licenses/>. 00019 */ 00020 #ifndef FatStructs_h 00021 #define FatStructs_h 00022 /** 00023 * \file 00024 * FAT file structures 00025 */ 00026 /* 00027 * mostly from Microsoft document fatgen103.doc 00028 * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx 00029 */ 00030 //------------------------------------------------------------------------------ 00031 /** Value for byte 510 of boot block or MBR */ 00032 uint8_t const BOOTSIG0 = 0X55; 00033 /** Value for byte 511 of boot block or MBR */ 00034 uint8_t const BOOTSIG1 = 0XAA; 00035 //------------------------------------------------------------------------------ 00036 /** 00037 * \struct partitionTable 00038 * \brief MBR partition table entry 00039 * 00040 * A partition table entry for a MBR formatted storage device. 00041 * The MBR partition table has four entries. 00042 */ 00043 struct partitionTable { 00044 /** 00045 * Boot Indicator . Indicates whether the volume is the active 00046 * partition. Legal values include: 0X00. Do not use for booting. 00047 * 0X80 Active partition. 00048 */ 00049 uint8_t boot; 00050 /** 00051 * Head part of Cylinder-head-sector address of the first block in 00052 * the partition. Legal values are 0-255. Only used in old PC BIOS. 00053 */ 00054 uint8_t beginHead; 00055 /** 00056 * Sector part of Cylinder-head-sector address of the first block in 00057 * the partition. Legal values are 1-63. Only used in old PC BIOS. 00058 */ 00059 unsigned beginSector : 6; 00060 /** High bits cylinder for first block in partition. */ 00061 unsigned beginCylinderHigh : 2; 00062 /** 00063 * Combine beginCylinderLow with beginCylinderHigh. Legal values 00064 * are 0-1023. Only used in old PC BIOS. 00065 */ 00066 uint8_t beginCylinderLow; 00067 /** 00068 * Partition type. See defines that begin with PART_TYPE_ for 00069 * some Microsoft partition types. 00070 */ 00071 uint8_t type; 00072 /** 00073 * head part of cylinder-head-sector address of the last sector in the 00074 * partition. Legal values are 0-255. Only used in old PC BIOS. 00075 */ 00076 uint8_t endHead; 00077 /** 00078 * Sector part of cylinder-head-sector address of the last sector in 00079 * the partition. Legal values are 1-63. Only used in old PC BIOS. 00080 */ 00081 unsigned endSector : 6; 00082 /** High bits of end cylinder */ 00083 unsigned endCylinderHigh : 2; 00084 /** 00085 * Combine endCylinderLow with endCylinderHigh. Legal values 00086 * are 0-1023. Only used in old PC BIOS. 00087 */ 00088 uint8_t endCylinderLow; 00089 /** Logical block address of the first block in the partition. */ 00090 uint32_t firstSector; 00091 /** Length of the partition, in blocks. */ 00092 uint32_t totalSectors; 00093 }; 00094 /** Type name for partitionTable */ 00095 typedef struct partitionTable part_t; 00096 //------------------------------------------------------------------------------ 00097 /** 00098 * \struct masterBootRecord 00099 * 00100 * \brief Master Boot Record 00101 * 00102 * The first block of a storage device that is formatted with a MBR. 00103 */ 00104 struct masterBootRecord { 00105 /** Code Area for master boot program. */ 00106 uint8_t codeArea[440]; 00107 /** Optional WindowsNT disk signature. May contain more boot code. */ 00108 uint32_t diskSignature; 00109 /** Usually zero but may be more boot code. */ 00110 uint16_t usuallyZero; 00111 /** Partition tables. */ 00112 part_t part[4]; 00113 /** First MBR signature byte. Must be 0X55 */ 00114 uint8_t mbrSig0; 00115 /** Second MBR signature byte. Must be 0XAA */ 00116 uint8_t mbrSig1; 00117 }; 00118 /** Type name for masterBootRecord */ 00119 typedef struct masterBootRecord mbr_t; 00120 //------------------------------------------------------------------------------ 00121 /** 00122 * \struct biosParmBlock 00123 * 00124 * \brief BIOS parameter block 00125 * 00126 * The BIOS parameter block describes the physical layout of a FAT volume. 00127 */ 00128 struct biosParmBlock { 00129 /** 00130 * Count of bytes per sector. This value may take on only the 00131 * following values: 512, 1024, 2048 or 4096 00132 */ 00133 uint16_t bytesPerSector; 00134 /** 00135 * Number of sectors per allocation unit. This value must be a 00136 * power of 2 that is greater than 0. The legal values are 00137 * 1, 2, 4, 8, 16, 32, 64, and 128. 00138 */ 00139 uint8_t sectorsPerCluster; 00140 /** 00141 * Number of sectors before the first FAT. 00142 * This value must not be zero. 00143 */ 00144 uint16_t reservedSectorCount; 00145 /** The count of FAT data structures on the volume. This field should 00146 * always contain the value 2 for any FAT volume of any type. 00147 */ 00148 uint8_t fatCount; 00149 /** 00150 * For FAT12 and FAT16 volumes, this field contains the count of 00151 * 32-byte directory entries in the root directory. For FAT32 volumes, 00152 * this field must be set to 0. For FAT12 and FAT16 volumes, this 00153 * value should always specify a count that when multiplied by 32 00154 * results in a multiple of bytesPerSector. FAT16 volumes should 00155 * use the value 512. 00156 */ 00157 uint16_t rootDirEntryCount; 00158 /** 00159 * This field is the old 16-bit total count of sectors on the volume. 00160 * This count includes the count of all sectors in all four regions 00161 * of the volume. This field can be 0; if it is 0, then totalSectors32 00162 * must be non-zero. For FAT32 volumes, this field must be 0. For 00163 * FAT12 and FAT16 volumes, this field contains the sector count, and 00164 * totalSectors32 is 0 if the total sector count fits 00165 * (is less than 0x10000). 00166 */ 00167 uint16_t totalSectors16; 00168 /** 00169 * This dates back to the old MS-DOS 1.x media determination and is 00170 * no longer usually used for anything. 0xF8 is the standard value 00171 * for fixed (non-removable) media. For removable media, 0xF0 is 00172 * frequently used. Legal values are 0xF0 or 0xF8-0xFF. 00173 */ 00174 uint8_t mediaType; 00175 /** 00176 * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. 00177 * On FAT32 volumes this field must be 0, and sectorsPerFat32 00178 * contains the FAT size count. 00179 */ 00180 uint16_t sectorsPerFat16; 00181 /** Sectors per track for interrupt 0x13. Not used otherwise. */ 00182 uint16_t sectorsPerTrtack; 00183 /** Number of heads for interrupt 0x13. Not used otherwise. */ 00184 uint16_t headCount; 00185 /** 00186 * Count of hidden sectors preceding the partition that contains this 00187 * FAT volume. This field is generally only relevant for media 00188 * visible on interrupt 0x13. 00189 */ 00190 uint32_t hidddenSectors; 00191 /** 00192 * This field is the new 32-bit total count of sectors on the volume. 00193 * This count includes the count of all sectors in all four regions 00194 * of the volume. This field can be 0; if it is 0, then 00195 * totalSectors16 must be non-zero. 00196 */ 00197 uint32_t totalSectors32; 00198 /** 00199 * Count of sectors occupied by one FAT on FAT32 volumes. 00200 */ 00201 uint32_t sectorsPerFat32; 00202 /** 00203 * This field is only defined for FAT32 media and does not exist on 00204 * FAT12 and FAT16 media. 00205 * Bits 0-3 -- Zero-based number of active FAT. 00206 * Only valid if mirroring is disabled. 00207 * Bits 4-6 -- Reserved. 00208 * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. 00209 * -- 1 means only one FAT is active; it is the one referenced in bits 0-3. 00210 * Bits 8-15 -- Reserved. 00211 */ 00212 uint16_t fat32Flags; 00213 /** 00214 * FAT32 version. High byte is major revision number. 00215 * Low byte is minor revision number. Only 0.0 define. 00216 */ 00217 uint16_t fat32Version; 00218 /** 00219 * Cluster number of the first cluster of the root directory for FAT32. 00220 * This usually 2 but not required to be 2. 00221 */ 00222 uint32_t fat32RootCluster; 00223 /** 00224 * Sector number of FSINFO structure in the reserved area of the 00225 * FAT32 volume. Usually 1. 00226 */ 00227 uint16_t fat32FSInfo; 00228 /** 00229 * If non-zero, indicates the sector number in the reserved area 00230 * of the volume of a copy of the boot record. Usually 6. 00231 * No value other than 6 is recommended. 00232 */ 00233 uint16_t fat32BackBootBlock; 00234 /** 00235 * Reserved for future expansion. Code that formats FAT32 volumes 00236 * should always set all of the bytes of this field to 0. 00237 */ 00238 uint8_t fat32Reserved[12]; 00239 }; 00240 /** Type name for biosParmBlock */ 00241 typedef struct biosParmBlock bpb_t; 00242 //------------------------------------------------------------------------------ 00243 /** 00244 * \struct fat32BootSector 00245 * 00246 * \brief Boot sector for a FAT16 or FAT32 volume. 00247 * 00248 */ 00249 struct fat32BootSector { 00250 /** X86 jmp to boot program */ 00251 uint8_t jmpToBootCode[3]; 00252 /** informational only - don't depend on it */ 00253 char oemName[8]; 00254 /** BIOS Parameter Block */ 00255 bpb_t bpb; 00256 /** for int0x13 use value 0X80 for hard drive */ 00257 uint8_t driveNumber; 00258 /** used by Windows NT - should be zero for FAT */ 00259 uint8_t reserved1; 00260 /** 0X29 if next three fields are valid */ 00261 uint8_t bootSignature; 00262 /** usually generated by combining date and time */ 00263 uint32_t volumeSerialNumber; 00264 /** should match volume label in root dir */ 00265 char volumeLabel[11]; 00266 /** informational only - don't depend on it */ 00267 char fileSystemType[8]; 00268 /** X86 boot code */ 00269 uint8_t bootCode[420]; 00270 /** must be 0X55 */ 00271 uint8_t bootSectorSig0; 00272 /** must be 0XAA */ 00273 uint8_t bootSectorSig1; 00274 }; 00275 //------------------------------------------------------------------------------ 00276 // End Of Chain values for FAT entries 00277 /** FAT16 end of chain value used by Microsoft. */ 00278 uint16_t const FAT16EOC = 0XFFFF; 00279 /** Minimum value for FAT16 EOC. Use to test for EOC. */ 00280 uint16_t const FAT16EOC_MIN = 0XFFF8; 00281 /** FAT32 end of chain value used by Microsoft. */ 00282 uint32_t const FAT32EOC = 0X0FFFFFFF; 00283 /** Minimum value for FAT32 EOC. Use to test for EOC. */ 00284 uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; 00285 /** Mask a for FAT32 entry. Entries are 28 bits. */ 00286 uint32_t const FAT32MASK = 0X0FFFFFFF; 00287 00288 /** Type name for fat32BootSector */ 00289 typedef struct fat32BootSector fbs_t; 00290 //------------------------------------------------------------------------------ 00291 /** 00292 * \struct directoryEntry 00293 * \brief FAT short directory entry 00294 * 00295 * Short means short 8.3 name, not the entry size. 00296 * 00297 * Date Format. A FAT directory entry date stamp is a 16-bit field that is 00298 * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the 00299 * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 00300 * 16-bit word): 00301 * 00302 * Bits 9-15: Count of years from 1980, valid value range 0-127 00303 * inclusive (1980-2107). 00304 * 00305 * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. 00306 * 00307 * Bits 0-4: Day of month, valid value range 1-31 inclusive. 00308 * 00309 * Time Format. A FAT directory entry time stamp is a 16-bit field that has 00310 * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the 00311 * 16-bit word, bit 15 is the MSB of the 16-bit word). 00312 * 00313 * Bits 11-15: Hours, valid value range 0-23 inclusive. 00314 * 00315 * Bits 5-10: Minutes, valid value range 0-59 inclusive. 00316 * 00317 * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). 00318 * 00319 * The valid time range is from Midnight 00:00:00 to 23:59:58. 00320 */ 00321 struct directoryEntry { 00322 /** 00323 * Short 8.3 name. 00324 * The first eight bytes contain the file name with blank fill. 00325 * The last three bytes contain the file extension with blank fill. 00326 */ 00327 uint8_t name[11]; 00328 /** Entry attributes. 00329 * 00330 * The upper two bits of the attribute byte are reserved and should 00331 * always be set to 0 when a file is created and never modified or 00332 * looked at after that. See defines that begin with DIR_ATT_. 00333 */ 00334 uint8_t attributes; 00335 /** 00336 * Reserved for use by Windows NT. Set value to 0 when a file is 00337 * created and never modify or look at it after that. 00338 */ 00339 uint8_t reservedNT; 00340 /** 00341 * The granularity of the seconds part of creationTime is 2 seconds 00342 * so this field is a count of tenths of a second and its valid 00343 * value range is 0-199 inclusive. (WHG note - seems to be hundredths) 00344 */ 00345 uint8_t creationTimeTenths; 00346 /** Time file was created. */ 00347 uint16_t creationTime; 00348 /** Date file was created. */ 00349 uint16_t creationDate; 00350 /** 00351 * Last access date. Note that there is no last access time, only 00352 * a date. This is the date of last read or write. In the case of 00353 * a write, this should be set to the same date as lastWriteDate. 00354 */ 00355 uint16_t lastAccessDate; 00356 /** 00357 * High word of this entry's first cluster number (always 0 for a 00358 * FAT12 or FAT16 volume). 00359 */ 00360 uint16_t firstClusterHigh; 00361 /** Time of last write. File creation is considered a write. */ 00362 uint16_t lastWriteTime; 00363 /** Date of last write. File creation is considered a write. */ 00364 uint16_t lastWriteDate; 00365 /** Low word of this entry's first cluster number. */ 00366 uint16_t firstClusterLow; 00367 /** 32-bit unsigned holding this file's size in bytes. */ 00368 uint32_t fileSize; 00369 }; 00370 //------------------------------------------------------------------------------ 00371 // Definitions for directory entries 00372 // 00373 /** Type name for directoryEntry */ 00374 typedef struct directoryEntry dir_t; 00375 /** escape for name[0] = 0XE5 */ 00376 uint8_t const DIR_NAME_0XE5 = 0X05; 00377 /** name[0] value for entry that is free after being "deleted" */ 00378 uint8_t const DIR_NAME_DELETED = 0XE5; 00379 /** name[0] value for entry that is free and no allocated entries follow */ 00380 uint8_t const DIR_NAME_FREE = 0X00; 00381 /** file is read-only */ 00382 uint8_t const DIR_ATT_READ_ONLY = 0X01; 00383 /** File should hidden in directory listings */ 00384 uint8_t const DIR_ATT_HIDDEN = 0X02; 00385 /** Entry is for a system file */ 00386 uint8_t const DIR_ATT_SYSTEM = 0X04; 00387 /** Directory entry contains the volume label */ 00388 uint8_t const DIR_ATT_VOLUME_ID = 0X08; 00389 /** Entry is for a directory */ 00390 uint8_t const DIR_ATT_DIRECTORY = 0X10; 00391 /** Old DOS archive bit for backup support */ 00392 uint8_t const DIR_ATT_ARCHIVE = 0X20; 00393 /** Test value for long name entry. Test is 00394 (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ 00395 uint8_t const DIR_ATT_LONG_NAME = 0X0F; 00396 /** Test mask for long name entry */ 00397 uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; 00398 /** defined attribute bits */ 00399 uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; 00400 /** Directory entry is part of a long name */ 00401 static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { 00402 return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; 00403 } 00404 /** Mask for file/subdirectory tests */ 00405 uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); 00406 /** Directory entry is for a file */ 00407 static inline uint8_t DIR_IS_FILE(const dir_t* dir) { 00408 return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; 00409 } 00410 /** Directory entry is for a subdirectory */ 00411 static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { 00412 return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; 00413 } 00414 /** Directory entry is for a file or subdirectory */ 00415 static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { 00416 return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; 00417 } 00418 #endif // FatStructs_h
Generated on Thu Jul 14 2022 02:07:54 by
1.7.2