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.

FatStructs.h 26KB

10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
10 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. /* FatLib Library
  2. * Copyright (C) 2013 by William Greiman
  3. *
  4. * This file is part of the FatLib 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 FatLib Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef FatStructs_h
  21. #define FatStructs_h
  22. /**
  23. * \file
  24. * \brief 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. /** Value for bootSignature field int FAT/FAT32 boot sector */
  36. uint8_t const EXTENDED_BOOT_SIG = 0X29;
  37. //------------------------------------------------------------------------------
  38. /**
  39. * \struct partitionTable
  40. * \brief MBR partition table entry
  41. *
  42. * A partition table entry for a MBR formatted storage device.
  43. * The MBR partition table has four entries.
  44. */
  45. struct partitionTable {
  46. /**
  47. * Boot Indicator . Indicates whether the volume is the active
  48. * partition. Legal values include: 0X00. Do not use for booting.
  49. * 0X80 Active partition.
  50. */
  51. uint8_t boot;
  52. /**
  53. * Head part of Cylinder-head-sector address of the first block in
  54. * the partition. Legal values are 0-255. Only used in old PC BIOS.
  55. */
  56. uint8_t beginHead;
  57. /**
  58. * Sector part of Cylinder-head-sector address of the first block in
  59. * the partition. Legal values are 1-63. Only used in old PC BIOS.
  60. */
  61. unsigned beginSector : 6;
  62. /** High bits cylinder for first block in partition. */
  63. unsigned beginCylinderHigh : 2;
  64. /**
  65. * Combine beginCylinderLow with beginCylinderHigh. Legal values
  66. * are 0-1023. Only used in old PC BIOS.
  67. */
  68. uint8_t beginCylinderLow;
  69. /**
  70. * Partition type. See defines that begin with PART_TYPE_ for
  71. * some Microsoft partition types.
  72. */
  73. uint8_t type;
  74. /**
  75. * head part of cylinder-head-sector address of the last sector in the
  76. * partition. Legal values are 0-255. Only used in old PC BIOS.
  77. */
  78. uint8_t endHead;
  79. /**
  80. * Sector part of cylinder-head-sector address of the last sector in
  81. * the partition. Legal values are 1-63. Only used in old PC BIOS.
  82. */
  83. unsigned endSector : 6;
  84. /** High bits of end cylinder */
  85. unsigned endCylinderHigh : 2;
  86. /**
  87. * Combine endCylinderLow with endCylinderHigh. Legal values
  88. * are 0-1023. Only used in old PC BIOS.
  89. */
  90. uint8_t endCylinderLow;
  91. /** Logical block address of the first block in the partition. */
  92. uint32_t firstSector;
  93. /** Length of the partition, in blocks. */
  94. uint32_t totalSectors;
  95. } __attribute__((packed));
  96. /** Type name for partitionTable */
  97. typedef struct partitionTable part_t;
  98. //------------------------------------------------------------------------------
  99. /**
  100. * \struct masterBootRecord
  101. *
  102. * \brief Master Boot Record
  103. *
  104. * The first block of a storage device that is formatted with a MBR.
  105. */
  106. struct masterBootRecord {
  107. /** Code Area for master boot program. */
  108. uint8_t codeArea[440];
  109. /** Optional Windows NT disk signature. May contain boot code. */
  110. uint32_t diskSignature;
  111. /** Usually zero but may be more boot code. */
  112. uint16_t usuallyZero;
  113. /** Partition tables. */
  114. part_t part[4];
  115. /** First MBR signature byte. Must be 0X55 */
  116. uint8_t mbrSig0;
  117. /** Second MBR signature byte. Must be 0XAA */
  118. uint8_t mbrSig1;
  119. } __attribute__((packed));
  120. /** Type name for masterBootRecord */
  121. typedef struct masterBootRecord mbr_t;
  122. //------------------------------------------------------------------------------
  123. /**
  124. * \struct fat_boot
  125. *
  126. * \brief Boot sector for a FAT12/FAT16 volume.
  127. *
  128. */
  129. struct fat_boot {
  130. /**
  131. * The first three bytes of the boot sector must be valid,
  132. * executable x 86-based CPU instructions. This includes a
  133. * jump instruction that skips the next non-executable bytes.
  134. */
  135. uint8_t jump[3];
  136. /**
  137. * This is typically a string of characters that identifies
  138. * the operating system that formatted the volume.
  139. */
  140. char oemId[8];
  141. /**
  142. * The size of a hardware sector. Valid decimal values for this
  143. * field are 512, 1024, 2048, and 4096. For most disks used in
  144. * the United States, the value of this field is 512.
  145. */
  146. uint16_t bytesPerSector;
  147. /**
  148. * Number of sectors per allocation unit. This value must be a
  149. * power of 2 that is greater than 0. The legal values are
  150. * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided.
  151. */
  152. uint8_t sectorsPerCluster;
  153. /**
  154. * The number of sectors preceding the start of the first FAT,
  155. * including the boot sector. The value of this field is always 1.
  156. */
  157. uint16_t reservedSectorCount;
  158. /**
  159. * The number of copies of the FAT on the volume.
  160. * The value of this field is always 2.
  161. */
  162. uint8_t fatCount;
  163. /**
  164. * For FAT12 and FAT16 volumes, this field contains the count of
  165. * 32-byte directory entries in the root directory. For FAT32 volumes,
  166. * this field must be set to 0. For FAT12 and FAT16 volumes, this
  167. * value should always specify a count that when multiplied by 32
  168. * results in a multiple of bytesPerSector. FAT16 volumes should
  169. * use the value 512.
  170. */
  171. uint16_t rootDirEntryCount;
  172. /**
  173. * This field is the old 16-bit total count of sectors on the volume.
  174. * This count includes the count of all sectors in all four regions
  175. * of the volume. This field can be 0; if it is 0, then totalSectors32
  176. * must be non-zero. For FAT32 volumes, this field must be 0. For
  177. * FAT12 and FAT16 volumes, this field contains the sector count, and
  178. * totalSectors32 is 0 if the total sector count fits
  179. * (is less than 0x10000).
  180. */
  181. uint16_t totalSectors16;
  182. /**
  183. * This dates back to the old MS-DOS 1.x media determination and is
  184. * no longer usually used for anything. 0xF8 is the standard value
  185. * for fixed (non-removable) media. For removable media, 0xF0 is
  186. * frequently used. Legal values are 0xF0 or 0xF8-0xFF.
  187. */
  188. uint8_t mediaType;
  189. /**
  190. * Count of sectors occupied by one FAT on FAT12/FAT16 volumes.
  191. * On FAT32 volumes this field must be 0, and sectorsPerFat32
  192. * contains the FAT size count.
  193. */
  194. uint16_t sectorsPerFat16;
  195. /** Sectors per track for interrupt 0x13. Not used otherwise. */
  196. uint16_t sectorsPerTrack;
  197. /** Number of heads for interrupt 0x13. Not used otherwise. */
  198. uint16_t headCount;
  199. /**
  200. * Count of hidden sectors preceding the partition that contains this
  201. * FAT volume. This field is generally only relevant for media
  202. * visible on interrupt 0x13.
  203. */
  204. uint32_t hidddenSectors;
  205. /**
  206. * This field is the new 32-bit total count of sectors on the volume.
  207. * This count includes the count of all sectors in all four regions
  208. * of the volume. This field can be 0; if it is 0, then
  209. * totalSectors16 must be non-zero.
  210. */
  211. uint32_t totalSectors32;
  212. /**
  213. * Related to the BIOS physical drive number. Floppy drives are
  214. * identified as 0x00 and physical hard disks are identified as
  215. * 0x80, regardless of the number of physical disk drives.
  216. * Typically, this value is set prior to issuing an INT 13h BIOS
  217. * call to specify the device to access. The value is only
  218. * relevant if the device is a boot device.
  219. */
  220. uint8_t driveNumber;
  221. /** used by Windows NT - should be zero for FAT */
  222. uint8_t reserved1;
  223. /** 0X29 if next three fields are valid */
  224. uint8_t bootSignature;
  225. /**
  226. * A random serial number created when formatting a disk,
  227. * which helps to distinguish between disks.
  228. * Usually generated by combining date and time.
  229. */
  230. uint32_t volumeSerialNumber;
  231. /**
  232. * A field once used to store the volume label. The volume label
  233. * is now stored as a special file in the root directory.
  234. */
  235. char volumeLabel[11];
  236. /**
  237. * A field with a value of either FAT, FAT12 or FAT16,
  238. * depending on the disk format.
  239. */
  240. char fileSystemType[8];
  241. /** X86 boot code */
  242. uint8_t bootCode[448];
  243. /** must be 0X55 */
  244. uint8_t bootSectorSig0;
  245. /** must be 0XAA */
  246. uint8_t bootSectorSig1;
  247. } __attribute__((packed));
  248. /** Type name for FAT Boot Sector */
  249. typedef struct fat_boot fat_boot_t;
  250. //------------------------------------------------------------------------------
  251. /**
  252. * \struct fat32_boot
  253. *
  254. * \brief Boot sector for a FAT32 volume.
  255. *
  256. */
  257. struct fat32_boot {
  258. /**
  259. * The first three bytes of the boot sector must be valid,
  260. * executable x 86-based CPU instructions. This includes a
  261. * jump instruction that skips the next non-executable bytes.
  262. */
  263. uint8_t jump[3];
  264. /**
  265. * This is typically a string of characters that identifies
  266. * the operating system that formatted the volume.
  267. */
  268. char oemId[8];
  269. /**
  270. * The size of a hardware sector. Valid decimal values for this
  271. * field are 512, 1024, 2048, and 4096. For most disks used in
  272. * the United States, the value of this field is 512.
  273. */
  274. uint16_t bytesPerSector;
  275. /**
  276. * Number of sectors per allocation unit. This value must be a
  277. * power of 2 that is greater than 0. The legal values are
  278. * 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided.
  279. */
  280. uint8_t sectorsPerCluster;
  281. /**
  282. * The number of sectors preceding the start of the first FAT,
  283. * including the boot sector. Must not be zero
  284. */
  285. uint16_t reservedSectorCount;
  286. /**
  287. * The number of copies of the FAT on the volume.
  288. * The value of this field is always 2.
  289. */
  290. uint8_t fatCount;
  291. /**
  292. * FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0.
  293. */
  294. uint16_t rootDirEntryCount;
  295. /**
  296. * For FAT32 volumes, this field must be 0.
  297. */
  298. uint16_t totalSectors16;
  299. /**
  300. * This dates back to the old MS-DOS 1.x media determination and is
  301. * no longer usually used for anything. 0xF8 is the standard value
  302. * for fixed (non-removable) media. For removable media, 0xF0 is
  303. * frequently used. Legal values are 0xF0 or 0xF8-0xFF.
  304. */
  305. uint8_t mediaType;
  306. /**
  307. * On FAT32 volumes this field must be 0, and sectorsPerFat32
  308. * contains the FAT size count.
  309. */
  310. uint16_t sectorsPerFat16;
  311. /** Sectors per track for interrupt 0x13. Not used otherwise. */
  312. uint16_t sectorsPerTrack;
  313. /** Number of heads for interrupt 0x13. Not used otherwise. */
  314. uint16_t headCount;
  315. /**
  316. * Count of hidden sectors preceding the partition that contains this
  317. * FAT volume. This field is generally only relevant for media
  318. * visible on interrupt 0x13.
  319. */
  320. uint32_t hidddenSectors;
  321. /**
  322. * Contains the total number of sectors in the FAT32 volume.
  323. */
  324. uint32_t totalSectors32;
  325. /**
  326. * Count of sectors occupied by one FAT on FAT32 volumes.
  327. */
  328. uint32_t sectorsPerFat32;
  329. /**
  330. * This field is only defined for FAT32 media and does not exist on
  331. * FAT12 and FAT16 media.
  332. * Bits 0-3 -- Zero-based number of active FAT.
  333. * Only valid if mirroring is disabled.
  334. * Bits 4-6 -- Reserved.
  335. * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs.
  336. * -- 1 means only one FAT is active; it is the one referenced
  337. * in bits 0-3.
  338. * Bits 8-15 -- Reserved.
  339. */
  340. uint16_t fat32Flags;
  341. /**
  342. * FAT32 version. High byte is major revision number.
  343. * Low byte is minor revision number. Only 0.0 define.
  344. */
  345. uint16_t fat32Version;
  346. /**
  347. * Cluster number of the first cluster of the root directory for FAT32.
  348. * This usually 2 but not required to be 2.
  349. */
  350. uint32_t fat32RootCluster;
  351. /**
  352. * Sector number of FSINFO structure in the reserved area of the
  353. * FAT32 volume. Usually 1.
  354. */
  355. uint16_t fat32FSInfo;
  356. /**
  357. * If non-zero, indicates the sector number in the reserved area
  358. * of the volume of a copy of the boot record. Usually 6.
  359. * No value other than 6 is recommended.
  360. */
  361. uint16_t fat32BackBootBlock;
  362. /**
  363. * Reserved for future expansion. Code that formats FAT32 volumes
  364. * should always set all of the bytes of this field to 0.
  365. */
  366. uint8_t fat32Reserved[12];
  367. /**
  368. * Related to the BIOS physical drive number. Floppy drives are
  369. * identified as 0x00 and physical hard disks are identified as
  370. * 0x80, regardless of the number of physical disk drives.
  371. * Typically, this value is set prior to issuing an INT 13h BIOS
  372. * call to specify the device to access. The value is only
  373. * relevant if the device is a boot device.
  374. */
  375. uint8_t driveNumber;
  376. /** used by Windows NT - should be zero for FAT */
  377. uint8_t reserved1;
  378. /** 0X29 if next three fields are valid */
  379. uint8_t bootSignature;
  380. /**
  381. * A random serial number created when formatting a disk,
  382. * which helps to distinguish between disks.
  383. * Usually generated by combining date and time.
  384. */
  385. uint32_t volumeSerialNumber;
  386. /**
  387. * A field once used to store the volume label. The volume label
  388. * is now stored as a special file in the root directory.
  389. */
  390. char volumeLabel[11];
  391. /**
  392. * A text field with a value of FAT32.
  393. */
  394. char fileSystemType[8];
  395. /** X86 boot code */
  396. uint8_t bootCode[420];
  397. /** must be 0X55 */
  398. uint8_t bootSectorSig0;
  399. /** must be 0XAA */
  400. uint8_t bootSectorSig1;
  401. } __attribute__((packed));
  402. /** Type name for FAT32 Boot Sector */
  403. typedef struct fat32_boot fat32_boot_t;
  404. //------------------------------------------------------------------------------
  405. /** Lead signature for a FSINFO sector */
  406. uint32_t const FSINFO_LEAD_SIG = 0x41615252;
  407. /** Struct signature for a FSINFO sector */
  408. uint32_t const FSINFO_STRUCT_SIG = 0x61417272;
  409. /**
  410. * \struct fat32_fsinfo
  411. *
  412. * \brief FSINFO sector for a FAT32 volume.
  413. *
  414. */
  415. struct fat32_fsinfo {
  416. /** must be 0X52, 0X52, 0X61, 0X41 */
  417. uint32_t leadSignature;
  418. /** must be zero */
  419. uint8_t reserved1[480];
  420. /** must be 0X72, 0X72, 0X41, 0X61 */
  421. uint32_t structSignature;
  422. /**
  423. * Contains the last known free cluster count on the volume.
  424. * If the value is 0xFFFFFFFF, then the free count is unknown
  425. * and must be computed. Any other value can be used, but is
  426. * not necessarily correct. It should be range checked at least
  427. * to make sure it is <= volume cluster count.
  428. */
  429. uint32_t freeCount;
  430. /**
  431. * This is a hint for the FAT driver. It indicates the cluster
  432. * number at which the driver should start looking for free clusters.
  433. * If the value is 0xFFFFFFFF, then there is no hint and the driver
  434. * should start looking at cluster 2.
  435. */
  436. uint32_t nextFree;
  437. /** must be zero */
  438. uint8_t reserved2[12];
  439. /** must be 0X00, 0X00, 0X55, 0XAA */
  440. uint8_t tailSignature[4];
  441. } __attribute__((packed));
  442. /** Type name for FAT32 FSINFO Sector */
  443. typedef struct fat32_fsinfo fat32_fsinfo_t;
  444. //------------------------------------------------------------------------------
  445. // End Of Chain values for FAT entries
  446. /** FAT12 end of chain value used by Microsoft. */
  447. uint16_t const FAT12EOC = 0XFFF;
  448. /** Minimum value for FAT12 EOC. Use to test for EOC. */
  449. uint16_t const FAT12EOC_MIN = 0XFF8;
  450. /** FAT16 end of chain value used by Microsoft. */
  451. uint16_t const FAT16EOC = 0XFFFF;
  452. /** Minimum value for FAT16 EOC. Use to test for EOC. */
  453. uint16_t const FAT16EOC_MIN = 0XFFF8;
  454. /** FAT32 end of chain value used by Microsoft. */
  455. uint32_t const FAT32EOC = 0X0FFFFFFF;
  456. /** Minimum value for FAT32 EOC. Use to test for EOC. */
  457. uint32_t const FAT32EOC_MIN = 0X0FFFFFF8;
  458. /** Mask a for FAT32 entry. Entries are 28 bits. */
  459. uint32_t const FAT32MASK = 0X0FFFFFFF;
  460. //------------------------------------------------------------------------------
  461. /**
  462. * \struct directoryEntry
  463. * \brief FAT short directory entry
  464. *
  465. * Short means short 8.3 name, not the entry size.
  466. *
  467. * Date Format. A FAT directory entry date stamp is a 16-bit field that is
  468. * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the
  469. * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the
  470. * 16-bit word):
  471. *
  472. * Bits 9-15: Count of years from 1980, valid value range 0-127
  473. * inclusive (1980-2107).
  474. *
  475. * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive.
  476. *
  477. * Bits 0-4: Day of month, valid value range 1-31 inclusive.
  478. *
  479. * Time Format. A FAT directory entry time stamp is a 16-bit field that has
  480. * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the
  481. * 16-bit word, bit 15 is the MSB of the 16-bit word).
  482. *
  483. * Bits 11-15: Hours, valid value range 0-23 inclusive.
  484. *
  485. * Bits 5-10: Minutes, valid value range 0-59 inclusive.
  486. *
  487. * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds).
  488. *
  489. * The valid time range is from Midnight 00:00:00 to 23:59:58.
  490. */
  491. struct directoryEntry {
  492. /** Short 8.3 name.
  493. *
  494. * The first eight bytes contain the file name with blank fill.
  495. * The last three bytes contain the file extension with blank fill.
  496. */
  497. uint8_t name[11];
  498. /** Entry attributes.
  499. *
  500. * The upper two bits of the attribute byte are reserved and should
  501. * always be set to 0 when a file is created and never modified or
  502. * looked at after that. See defines that begin with DIR_ATT_.
  503. */
  504. uint8_t attributes;
  505. /**
  506. * Reserved for use by Windows NT. Set value to 0 when a file is
  507. * created and never modify or look at it after that.
  508. */
  509. uint8_t reservedNT;
  510. /**
  511. * The granularity of the seconds part of creationTime is 2 seconds
  512. * so this field is a count of tenths of a second and its valid
  513. * value range is 0-199 inclusive. (WHG note - seems to be hundredths)
  514. */
  515. uint8_t creationTimeTenths;
  516. /** Time file was created. */
  517. uint16_t creationTime;
  518. /** Date file was created. */
  519. uint16_t creationDate;
  520. /**
  521. * Last access date. Note that there is no last access time, only
  522. * a date. This is the date of last read or write. In the case of
  523. * a write, this should be set to the same date as lastWriteDate.
  524. */
  525. uint16_t lastAccessDate;
  526. /**
  527. * High word of this entry's first cluster number (always 0 for a
  528. * FAT12 or FAT16 volume).
  529. */
  530. uint16_t firstClusterHigh;
  531. /** Time of last write. File creation is considered a write. */
  532. uint16_t lastWriteTime;
  533. /** Date of last write. File creation is considered a write. */
  534. uint16_t lastWriteDate;
  535. /** Low word of this entry's first cluster number. */
  536. uint16_t firstClusterLow;
  537. /** 32-bit unsigned holding this file's size in bytes. */
  538. uint32_t fileSize;
  539. } __attribute__((packed));
  540. /** Type name for directoryEntry */
  541. typedef struct directoryEntry dir_t;
  542. //------------------------------------------------------------------------------
  543. // Definitions for directory entries
  544. //
  545. /** escape for name[0] = 0XE5 */
  546. uint8_t const DIR_NAME_0XE5 = 0X05;
  547. /** name[0] value for entry that is free after being "deleted" */
  548. uint8_t const DIR_NAME_DELETED = 0XE5;
  549. /** name[0] value for entry that is free and no allocated entries follow */
  550. uint8_t const DIR_NAME_FREE = 0X00;
  551. /** file is read-only */
  552. uint8_t const DIR_ATT_READ_ONLY = 0X01;
  553. /** File should e hidden in directory listings */
  554. uint8_t const DIR_ATT_HIDDEN = 0X02;
  555. /** Entry is for a system file */
  556. uint8_t const DIR_ATT_SYSTEM = 0X04;
  557. /** Directory entry contains the volume label */
  558. uint8_t const DIR_ATT_VOLUME_ID = 0X08;
  559. /** Entry is for a directory */
  560. uint8_t const DIR_ATT_DIRECTORY = 0X10;
  561. /** Old DOS archive bit for backup support */
  562. uint8_t const DIR_ATT_ARCHIVE = 0X20;
  563. /** Test value for long name entry. Test is
  564. (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */
  565. uint8_t const DIR_ATT_LONG_NAME = 0X0F;
  566. /** Test mask for long name entry */
  567. uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F;
  568. /** defined attribute bits */
  569. uint8_t const DIR_ATT_DEFINED_BITS = 0X3F;
  570. /** Mask for file/subdirectory tests */
  571. uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY);
  572. /** Filename base-name is all lower case */
  573. const uint8_t DIR_NT_LC_BASE = 0X08;
  574. /** Filename extension is all lower case.*/
  575. const uint8_t DIR_NT_LC_EXT = 0X10;
  576. /** Directory entry is for a file
  577. * \param[in] dir Pointer to a directory entry.
  578. *
  579. * \return true if the entry is for a normal file else false.
  580. */
  581. static inline uint8_t DIR_IS_FILE(const dir_t* dir) {
  582. return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0;
  583. }
  584. /** Directory entry is for a file or subdirectory
  585. * \param[in] dir Pointer to a directory entry.
  586. *
  587. * \return true if the entry is for a normal file or subdirectory else false.
  588. */
  589. static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) {
  590. return (dir->attributes & DIR_ATT_VOLUME_ID) == 0;
  591. }
  592. /** Directory entry is part of a long name
  593. * \param[in] dir Pointer to a directory entry.
  594. *
  595. * \return true if the entry is for part of a long name else false.
  596. */
  597. static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) {
  598. return dir->attributes == DIR_ATT_LONG_NAME;
  599. }
  600. /** Directory entry is hidden
  601. * \param[in] dir Pointer to a directory entry.
  602. *
  603. * \return true if the entry is hidden else false.
  604. */
  605. static inline uint8_t DIR_IS_HIDDEN(const dir_t* dir) {
  606. return dir->attributes & DIR_ATT_HIDDEN;
  607. }
  608. /** Directory entry is for a subdirectory
  609. * \param[in] dir Pointer to a directory entry.
  610. *
  611. * \return true if the entry is for a subdirectory else false.
  612. */
  613. static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {
  614. return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY;
  615. }
  616. /** Directory entry is system type
  617. * \param[in] dir Pointer to a directory entry.
  618. *
  619. * \return true if the entry is system else false.
  620. */
  621. static inline uint8_t DIR_IS_SYSTEM(const dir_t* dir) {
  622. return dir->attributes & DIR_ATT_SYSTEM;
  623. }
  624. /** date field for FAT directory entry
  625. * \param[in] year [1980,2107]
  626. * \param[in] month [1,12]
  627. * \param[in] day [1,31]
  628. *
  629. * \return Packed date for dir_t entry.
  630. */
  631. static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
  632. return (year - 1980) << 9 | month << 5 | day;
  633. }
  634. /** year part of FAT directory date field
  635. * \param[in] fatDate Date in packed dir format.
  636. *
  637. * \return Extracted year [1980,2107]
  638. */
  639. static inline uint16_t FAT_YEAR(uint16_t fatDate) {
  640. return 1980 + (fatDate >> 9);
  641. }
  642. /** month part of FAT directory date field
  643. * \param[in] fatDate Date in packed dir format.
  644. *
  645. * \return Extracted month [1,12]
  646. */
  647. static inline uint8_t FAT_MONTH(uint16_t fatDate) {
  648. return (fatDate >> 5) & 0XF;
  649. }
  650. /** day part of FAT directory date field
  651. * \param[in] fatDate Date in packed dir format.
  652. *
  653. * \return Extracted day [1,31]
  654. */
  655. static inline uint8_t FAT_DAY(uint16_t fatDate) {
  656. return fatDate & 0X1F;
  657. }
  658. /** time field for FAT directory entry
  659. * \param[in] hour [0,23]
  660. * \param[in] minute [0,59]
  661. * \param[in] second [0,59]
  662. *
  663. * \return Packed time for dir_t entry.
  664. */
  665. static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) {
  666. return hour << 11 | minute << 5 | second >> 1;
  667. }
  668. /** hour part of FAT directory time field
  669. * \param[in] fatTime Time in packed dir format.
  670. *
  671. * \return Extracted hour [0,23]
  672. */
  673. static inline uint8_t FAT_HOUR(uint16_t fatTime) {
  674. return fatTime >> 11;
  675. }
  676. /** minute part of FAT directory time field
  677. * \param[in] fatTime Time in packed dir format.
  678. *
  679. * \return Extracted minute [0,59]
  680. */
  681. static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
  682. return (fatTime >> 5) & 0X3F;
  683. }
  684. /** second part of FAT directory time field
  685. * Note second/2 is stored in packed time.
  686. *
  687. * \param[in] fatTime Time in packed dir format.
  688. *
  689. * \return Extracted second [0,58]
  690. */
  691. static inline uint8_t FAT_SECOND(uint16_t fatTime) {
  692. return 2*(fatTime & 0X1F);
  693. }
  694. /** Default date for file timestamps is 1 Jan 2000 */
  695. uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
  696. /** Default time for file timestamp is 1 am */
  697. uint16_t const FAT_DEFAULT_TIME = (1 << 11);
  698. //------------------------------------------------------------------------------
  699. /** Dimension of first name field in long directory entry */
  700. const uint8_t LDIR_NAME1_DIM = 5;
  701. /** Dimension of first name field in long directory entry */
  702. const uint8_t LDIR_NAME2_DIM = 6;
  703. /** Dimension of first name field in long directory entry */
  704. const uint8_t LDIR_NAME3_DIM = 2;
  705. /**
  706. * \struct longDirectoryEntry
  707. * \brief FAT long directory entry
  708. */
  709. struct longDirectoryEntry {
  710. /**
  711. * The order of this entry in the sequence of long dir entries
  712. * associated with the short dir entry at the end of the long dir set.
  713. *
  714. * If masked with 0X40 (LAST_LONG_ENTRY), this indicates the
  715. * entry is the last long dir entry in a set of long dir entries.
  716. * All valid sets of long dir entries must begin with an entry having
  717. * this mask.
  718. */
  719. uint8_t ord;
  720. /** Characters 1-5 of the long-name sub-component in this entry. */
  721. uint16_t name1[LDIR_NAME1_DIM];
  722. /** Attributes - must be ATTR_LONG_NAME */
  723. uint8_t attr;
  724. /**
  725. * If zero, indicates a directory entry that is a sub-component of a
  726. * long name. NOTE: Other values reserved for future extensions.
  727. *
  728. * Non-zero implies other directory entry types.
  729. */
  730. uint8_t type;
  731. /**
  732. * Checksum of name in the short dir entry at the end of the
  733. * long dir set.
  734. */
  735. uint8_t chksum;
  736. /** Characters 6-11 of the long-name sub-component in this entry. */
  737. uint16_t name2[LDIR_NAME2_DIM];
  738. /** Must be ZERO. This is an artifact of the FAT "first cluster" */
  739. uint16_t mustBeZero;
  740. /** Characters 12 and 13 of the long-name sub-component in this entry. */
  741. uint16_t name3[LDIR_NAME3_DIM];
  742. } __attribute__((packed));
  743. /** Type name for longDirectoryEntry */
  744. typedef struct longDirectoryEntry ldir_t;
  745. /**
  746. * Ord mast that indicates the entry is the last long dir entry in a
  747. * set of long dir entries. All valid sets of long dir entries must
  748. * begin with an entry having this mask.
  749. */
  750. const uint8_t LDIR_ORD_LAST_LONG_ENTRY = 0X40;
  751. #endif // FatStructs_h