You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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. } __attribute__((packed));
  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. } __attribute__((packed));
  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. } __attribute__((packed));
  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. } __attribute__((packed));
  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. /** Type name for fat32BootSector */
  288. typedef struct fat32BootSector fbs_t;
  289. //------------------------------------------------------------------------------
  290. /**
  291. * \struct directoryEntry
  292. * \brief FAT short directory entry
  293. *
  294. * Short means short 8.3 name, not the entry size.
  295. *
  296. * Date Format. A FAT directory entry date stamp is a 16-bit field that is
  297. * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the
  298. * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the
  299. * 16-bit word):
  300. *
  301. * Bits 9-15: Count of years from 1980, valid value range 0-127
  302. * inclusive (1980-2107).
  303. *
  304. * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive.
  305. *
  306. * Bits 0-4: Day of month, valid value range 1-31 inclusive.
  307. *
  308. * Time Format. A FAT directory entry time stamp is a 16-bit field that has
  309. * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the
  310. * 16-bit word, bit 15 is the MSB of the 16-bit word).
  311. *
  312. * Bits 11-15: Hours, valid value range 0-23 inclusive.
  313. *
  314. * Bits 5-10: Minutes, valid value range 0-59 inclusive.
  315. *
  316. * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds).
  317. *
  318. * The valid time range is from Midnight 00:00:00 to 23:59:58.
  319. */
  320. struct directoryEntry {
  321. /**
  322. * Short 8.3 name.
  323. * The first eight bytes contain the file name with blank fill.
  324. * The last three bytes contain the file extension with blank fill.
  325. */
  326. uint8_t name[11];
  327. /** Entry attributes.
  328. *
  329. * The upper two bits of the attribute byte are reserved and should
  330. * always be set to 0 when a file is created and never modified or
  331. * looked at after that. See defines that begin with DIR_ATT_.
  332. */
  333. uint8_t attributes;
  334. /**
  335. * Reserved for use by Windows NT. Set value to 0 when a file is
  336. * created and never modify or look at it after that.
  337. */
  338. uint8_t reservedNT;
  339. /**
  340. * The granularity of the seconds part of creationTime is 2 seconds
  341. * so this field is a count of tenths of a second and its valid
  342. * value range is 0-199 inclusive. (WHG note - seems to be hundredths)
  343. */
  344. uint8_t creationTimeTenths;
  345. /** Time file was created. */
  346. uint16_t creationTime;
  347. /** Date file was created. */
  348. uint16_t creationDate;
  349. /**
  350. * Last access date. Note that there is no last access time, only
  351. * a date. This is the date of last read or write. In the case of
  352. * a write, this should be set to the same date as lastWriteDate.
  353. */
  354. uint16_t lastAccessDate;
  355. /**
  356. * High word of this entry's first cluster number (always 0 for a
  357. * FAT12 or FAT16 volume).
  358. */
  359. uint16_t firstClusterHigh;
  360. /** Time of last write. File creation is considered a write. */
  361. uint16_t lastWriteTime;
  362. /** Date of last write. File creation is considered a write. */
  363. uint16_t lastWriteDate;
  364. /** Low word of this entry's first cluster number. */
  365. uint16_t firstClusterLow;
  366. /** 32-bit unsigned holding this file's size in bytes. */
  367. uint32_t fileSize;
  368. } __attribute__((packed));
  369. //------------------------------------------------------------------------------
  370. // Definitions for directory entries
  371. //
  372. /** Type name for directoryEntry */
  373. typedef struct directoryEntry dir_t;
  374. /** escape for name[0] = 0XE5 */
  375. uint8_t const DIR_NAME_0XE5 = 0X05;
  376. /** name[0] value for entry that is free after being "deleted" */
  377. uint8_t const DIR_NAME_DELETED = 0XE5;
  378. /** name[0] value for entry that is free and no allocated entries follow */
  379. uint8_t const DIR_NAME_FREE = 0X00;
  380. /** file is read-only */
  381. uint8_t const DIR_ATT_READ_ONLY = 0X01;
  382. /** File should hidden in directory listings */
  383. uint8_t const DIR_ATT_HIDDEN = 0X02;
  384. /** Entry is for a system file */
  385. uint8_t const DIR_ATT_SYSTEM = 0X04;
  386. /** Directory entry contains the volume label */
  387. uint8_t const DIR_ATT_VOLUME_ID = 0X08;
  388. /** Entry is for a directory */
  389. uint8_t const DIR_ATT_DIRECTORY = 0X10;
  390. /** Old DOS archive bit for backup support */
  391. uint8_t const DIR_ATT_ARCHIVE = 0X20;
  392. /** Test value for long name entry. Test is
  393. (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */
  394. uint8_t const DIR_ATT_LONG_NAME = 0X0F;
  395. /** Test mask for long name entry */
  396. uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F;
  397. /** defined attribute bits */
  398. uint8_t const DIR_ATT_DEFINED_BITS = 0X3F;
  399. /** Directory entry is part of a long name */
  400. static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) {
  401. return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME;
  402. }
  403. /** Mask for file/subdirectory tests */
  404. uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY);
  405. /** Directory entry is for a file */
  406. static inline uint8_t DIR_IS_FILE(const dir_t* dir) {
  407. return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0;
  408. }
  409. /** Directory entry is for a subdirectory */
  410. static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {
  411. return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY;
  412. }
  413. /** Directory entry is for a file or subdirectory */
  414. static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) {
  415. return (dir->attributes & DIR_ATT_VOLUME_ID) == 0;
  416. }
  417. #endif // FatStructs_h