utility
Embed:
(wiki syntax)
Show/hide line numbers
FatStructs.h
Go to the documentation of this file.
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