fat.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  1. /* fat.c - FAT filesystem */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
  5. *
  6. * GRUB 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. * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <grub/fs.h>
  20. #include <grub/disk.h>
  21. #include <grub/file.h>
  22. #include <grub/types.h>
  23. #include <grub/misc.h>
  24. #include <grub/mm.h>
  25. #include <grub/err.h>
  26. #include <grub/dl.h>
  27. #include <grub/charset.h>
  28. #ifndef MODE_EXFAT
  29. #include <grub/fat.h>
  30. #else
  31. #include <grub/exfat.h>
  32. #endif
  33. #include <grub/fshelp.h>
  34. #include <grub/i18n.h>
  35. GRUB_MOD_LICENSE ("GPLv3+");
  36. enum
  37. {
  38. GRUB_FAT_ATTR_READ_ONLY = 0x01,
  39. GRUB_FAT_ATTR_HIDDEN = 0x02,
  40. GRUB_FAT_ATTR_SYSTEM = 0x04,
  41. #ifndef MODE_EXFAT
  42. GRUB_FAT_ATTR_VOLUME_ID = 0x08,
  43. #endif
  44. GRUB_FAT_ATTR_DIRECTORY = 0x10,
  45. GRUB_FAT_ATTR_ARCHIVE = 0x20,
  46. #ifndef MODE_EXFAT
  47. GRUB_FAT_ATTR_LONG_NAME = (GRUB_FAT_ATTR_READ_ONLY
  48. | GRUB_FAT_ATTR_HIDDEN
  49. | GRUB_FAT_ATTR_SYSTEM
  50. | GRUB_FAT_ATTR_VOLUME_ID),
  51. #endif
  52. GRUB_FAT_ATTR_VALID = (GRUB_FAT_ATTR_READ_ONLY
  53. | GRUB_FAT_ATTR_HIDDEN
  54. | GRUB_FAT_ATTR_SYSTEM
  55. | GRUB_FAT_ATTR_DIRECTORY
  56. | GRUB_FAT_ATTR_ARCHIVE
  57. #ifndef MODE_EXFAT
  58. | GRUB_FAT_ATTR_VOLUME_ID
  59. #endif
  60. )
  61. };
  62. #ifdef MODE_EXFAT
  63. typedef struct grub_exfat_bpb grub_current_fat_bpb_t;
  64. #else
  65. typedef struct grub_fat_bpb grub_current_fat_bpb_t;
  66. #endif
  67. #ifdef MODE_EXFAT
  68. enum
  69. {
  70. FLAG_CONTIGUOUS = 2
  71. };
  72. struct grub_fat_dir_entry
  73. {
  74. grub_uint8_t entry_type;
  75. union
  76. {
  77. grub_uint8_t placeholder[31];
  78. struct {
  79. grub_uint8_t secondary_count;
  80. grub_uint16_t checksum;
  81. grub_uint16_t attr;
  82. grub_uint16_t reserved1;
  83. grub_uint32_t c_time;
  84. grub_uint32_t m_time;
  85. grub_uint32_t a_time;
  86. grub_uint8_t c_time_tenth;
  87. grub_uint8_t m_time_tenth;
  88. grub_uint8_t a_time_tenth;
  89. grub_uint8_t reserved2[9];
  90. } GRUB_PACKED file;
  91. struct {
  92. grub_uint8_t flags;
  93. grub_uint8_t reserved1;
  94. grub_uint8_t name_length;
  95. grub_uint16_t name_hash;
  96. grub_uint16_t reserved2;
  97. grub_uint64_t valid_size;
  98. grub_uint32_t reserved3;
  99. grub_uint32_t first_cluster;
  100. grub_uint64_t file_size;
  101. } GRUB_PACKED stream_extension;
  102. struct {
  103. grub_uint8_t flags;
  104. grub_uint16_t str[15];
  105. } GRUB_PACKED file_name;
  106. struct {
  107. grub_uint8_t character_count;
  108. grub_uint16_t str[15];
  109. } GRUB_PACKED volume_label;
  110. } GRUB_PACKED type_specific;
  111. } GRUB_PACKED;
  112. struct grub_fat_dir_node
  113. {
  114. grub_uint32_t attr;
  115. grub_uint32_t first_cluster;
  116. grub_uint64_t file_size;
  117. grub_uint64_t valid_size;
  118. int have_stream;
  119. int is_contiguous;
  120. };
  121. typedef struct grub_fat_dir_node grub_fat_dir_node_t;
  122. #else
  123. struct grub_fat_dir_entry
  124. {
  125. grub_uint8_t name[11];
  126. grub_uint8_t attr;
  127. grub_uint8_t nt_reserved;
  128. grub_uint8_t c_time_tenth;
  129. grub_uint16_t c_time;
  130. grub_uint16_t c_date;
  131. grub_uint16_t a_date;
  132. grub_uint16_t first_cluster_high;
  133. grub_uint16_t w_time;
  134. grub_uint16_t w_date;
  135. grub_uint16_t first_cluster_low;
  136. grub_uint32_t file_size;
  137. } GRUB_PACKED;
  138. struct grub_fat_long_name_entry
  139. {
  140. grub_uint8_t id;
  141. grub_uint16_t name1[5];
  142. grub_uint8_t attr;
  143. grub_uint8_t reserved;
  144. grub_uint8_t checksum;
  145. grub_uint16_t name2[6];
  146. grub_uint16_t first_cluster;
  147. grub_uint16_t name3[2];
  148. } GRUB_PACKED;
  149. typedef struct grub_fat_dir_entry grub_fat_dir_node_t;
  150. #endif
  151. struct grub_fat_data
  152. {
  153. int logical_sector_bits;
  154. grub_uint32_t num_sectors;
  155. grub_uint32_t fat_sector;
  156. grub_uint32_t sectors_per_fat;
  157. int fat_size;
  158. grub_uint32_t root_cluster;
  159. #ifndef MODE_EXFAT
  160. grub_uint32_t root_sector;
  161. grub_uint32_t num_root_sectors;
  162. #endif
  163. int cluster_bits;
  164. grub_uint32_t cluster_eof_mark;
  165. grub_uint32_t cluster_sector;
  166. grub_uint32_t num_clusters;
  167. grub_uint32_t uuid;
  168. };
  169. struct grub_fshelp_node {
  170. grub_disk_t disk;
  171. struct grub_fat_data *data;
  172. grub_uint8_t attr;
  173. #ifndef MODE_EXFAT
  174. grub_uint32_t file_size;
  175. #else
  176. grub_uint64_t file_size;
  177. #endif
  178. grub_uint32_t file_cluster;
  179. grub_uint32_t cur_cluster_num;
  180. grub_uint32_t cur_cluster;
  181. #ifdef MODE_EXFAT
  182. int is_contiguous;
  183. #endif
  184. };
  185. static grub_dl_t my_mod;
  186. #ifndef MODE_EXFAT
  187. static int
  188. fat_log2 (unsigned x)
  189. {
  190. int i;
  191. if (x == 0)
  192. return -1;
  193. for (i = 0; (x & 1) == 0; i++)
  194. x >>= 1;
  195. if (x != 1)
  196. return -1;
  197. return i;
  198. }
  199. #endif
  200. static struct grub_fat_data *
  201. grub_fat_mount (grub_disk_t disk)
  202. {
  203. grub_current_fat_bpb_t bpb;
  204. struct grub_fat_data *data = 0;
  205. grub_uint32_t first_fat, magic;
  206. if (! disk)
  207. goto fail;
  208. data = (struct grub_fat_data *) grub_malloc (sizeof (*data));
  209. if (! data)
  210. goto fail;
  211. /* Read the BPB. */
  212. if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
  213. goto fail;
  214. #ifdef MODE_EXFAT
  215. if (grub_memcmp ((const char *) bpb.oem_name, "EXFAT ",
  216. sizeof (bpb.oem_name)) != 0)
  217. goto fail;
  218. #endif
  219. /* Get the sizes of logical sectors and clusters. */
  220. #ifdef MODE_EXFAT
  221. data->logical_sector_bits = bpb.bytes_per_sector_shift;
  222. #else
  223. data->logical_sector_bits =
  224. fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
  225. #endif
  226. if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS
  227. || data->logical_sector_bits >= 16)
  228. goto fail;
  229. data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS;
  230. #ifdef MODE_EXFAT
  231. data->cluster_bits = bpb.sectors_per_cluster_shift;
  232. #else
  233. data->cluster_bits = fat_log2 (bpb.sectors_per_cluster);
  234. #endif
  235. if (data->cluster_bits < 0 || data->cluster_bits > 25)
  236. goto fail;
  237. data->cluster_bits += data->logical_sector_bits;
  238. /* Get information about FATs. */
  239. #ifdef MODE_EXFAT
  240. data->fat_sector = (grub_le_to_cpu32 (bpb.num_reserved_sectors)
  241. << data->logical_sector_bits);
  242. #else
  243. data->fat_sector = (grub_le_to_cpu16 (bpb.num_reserved_sectors)
  244. << data->logical_sector_bits);
  245. #endif
  246. if (data->fat_sector == 0)
  247. goto fail;
  248. #ifdef MODE_EXFAT
  249. data->sectors_per_fat = (grub_le_to_cpu32 (bpb.sectors_per_fat)
  250. << data->logical_sector_bits);
  251. #else
  252. data->sectors_per_fat = ((bpb.sectors_per_fat_16
  253. ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
  254. : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
  255. << data->logical_sector_bits);
  256. #endif
  257. if (data->sectors_per_fat == 0)
  258. goto fail;
  259. /* Get the number of sectors in this volume. */
  260. #ifdef MODE_EXFAT
  261. data->num_sectors = ((grub_le_to_cpu64 (bpb.num_total_sectors))
  262. << data->logical_sector_bits);
  263. #else
  264. data->num_sectors = ((bpb.num_total_sectors_16
  265. ? grub_le_to_cpu16 (bpb.num_total_sectors_16)
  266. : grub_le_to_cpu32 (bpb.num_total_sectors_32))
  267. << data->logical_sector_bits);
  268. #endif
  269. if (data->num_sectors == 0)
  270. goto fail;
  271. /* Get information about the root directory. */
  272. if (bpb.num_fats == 0)
  273. goto fail;
  274. #ifndef MODE_EXFAT
  275. data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat;
  276. data->num_root_sectors
  277. = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries)
  278. * sizeof (struct grub_fat_dir_entry)
  279. + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1)
  280. >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS))
  281. << (data->logical_sector_bits));
  282. #endif
  283. #ifdef MODE_EXFAT
  284. data->cluster_sector = (grub_le_to_cpu32 (bpb.cluster_offset)
  285. << data->logical_sector_bits);
  286. data->num_clusters = (grub_le_to_cpu32 (bpb.cluster_count)
  287. << data->logical_sector_bits);
  288. #else
  289. data->cluster_sector = data->root_sector + data->num_root_sectors;
  290. data->num_clusters = (((data->num_sectors - data->cluster_sector)
  291. >> data->cluster_bits)
  292. + 2);
  293. #endif
  294. if (data->num_clusters <= 2)
  295. goto fail;
  296. #ifdef MODE_EXFAT
  297. {
  298. /* exFAT. */
  299. data->root_cluster = grub_le_to_cpu32 (bpb.root_cluster);
  300. data->fat_size = 32;
  301. data->cluster_eof_mark = 0xffffffff;
  302. if ((bpb.volume_flags & grub_cpu_to_le16_compile_time (0x1))
  303. && bpb.num_fats > 1)
  304. data->fat_sector += data->sectors_per_fat;
  305. }
  306. #else
  307. if (! bpb.sectors_per_fat_16)
  308. {
  309. /* FAT32. */
  310. grub_uint16_t flags = grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags);
  311. data->root_cluster = grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster);
  312. data->fat_size = 32;
  313. data->cluster_eof_mark = 0x0ffffff8;
  314. if (flags & 0x80)
  315. {
  316. /* Get an active FAT. */
  317. unsigned active_fat = flags & 0xf;
  318. if (active_fat > bpb.num_fats)
  319. goto fail;
  320. data->fat_sector += active_fat * data->sectors_per_fat;
  321. }
  322. if (bpb.num_root_entries != 0 || bpb.version_specific.fat32.fs_version != 0)
  323. goto fail;
  324. }
  325. else
  326. {
  327. /* FAT12 or FAT16. */
  328. data->root_cluster = ~0U;
  329. if (data->num_clusters <= 4085 + 2)
  330. {
  331. /* FAT12. */
  332. data->fat_size = 12;
  333. data->cluster_eof_mark = 0x0ff8;
  334. }
  335. else
  336. {
  337. /* FAT16. */
  338. data->fat_size = 16;
  339. data->cluster_eof_mark = 0xfff8;
  340. }
  341. }
  342. #endif
  343. /* More sanity checks. */
  344. if (data->num_sectors <= data->fat_sector)
  345. goto fail;
  346. if (grub_disk_read (disk,
  347. data->fat_sector,
  348. 0,
  349. sizeof (first_fat),
  350. &first_fat))
  351. goto fail;
  352. first_fat = grub_le_to_cpu32 (first_fat);
  353. if (data->fat_size == 32)
  354. {
  355. first_fat &= 0x0fffffff;
  356. magic = 0x0fffff00;
  357. }
  358. else if (data->fat_size == 16)
  359. {
  360. first_fat &= 0x0000ffff;
  361. magic = 0xff00;
  362. }
  363. else
  364. {
  365. first_fat &= 0x00000fff;
  366. magic = 0x0f00;
  367. }
  368. /* Serial number. */
  369. #ifdef MODE_EXFAT
  370. data->uuid = grub_le_to_cpu32 (bpb.num_serial);
  371. #else
  372. if (bpb.sectors_per_fat_16)
  373. data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);
  374. else
  375. data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
  376. #endif
  377. #ifndef MODE_EXFAT
  378. /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
  379. descriptor, even if it is a so-called superfloppy (e.g. an USB key).
  380. The check may be too strict for this kind of stupid BIOSes, as
  381. they overwrite the media descriptor. */
  382. if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
  383. goto fail;
  384. #else
  385. (void) magic;
  386. #endif
  387. return data;
  388. fail:
  389. grub_free (data);
  390. grub_error (GRUB_ERR_BAD_FS, "not a FAT filesystem");
  391. return 0;
  392. }
  393. static grub_ssize_t
  394. grub_fat_read_data (grub_disk_t disk, grub_fshelp_node_t node,
  395. grub_disk_read_hook_t read_hook, void *read_hook_data,
  396. grub_off_t offset, grub_size_t len, char *buf)
  397. {
  398. grub_size_t size;
  399. grub_uint32_t logical_cluster;
  400. unsigned logical_cluster_bits;
  401. grub_ssize_t ret = 0;
  402. unsigned long sector;
  403. #ifndef MODE_EXFAT
  404. /* This is a special case. FAT12 and FAT16 doesn't have the root directory
  405. in clusters. */
  406. if (node->file_cluster == ~0U)
  407. {
  408. size = (node->data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset;
  409. if (size > len)
  410. size = len;
  411. if (grub_disk_read (disk, node->data->root_sector, offset, size, buf))
  412. return -1;
  413. return size;
  414. }
  415. #endif
  416. #ifdef MODE_EXFAT
  417. if (node->is_contiguous)
  418. {
  419. /* Read the data here. */
  420. sector = (node->data->cluster_sector
  421. + ((node->file_cluster - 2)
  422. << node->data->cluster_bits));
  423. disk->read_hook = read_hook;
  424. disk->read_hook_data = read_hook_data;
  425. grub_disk_read (disk, sector + (offset >> GRUB_DISK_SECTOR_BITS),
  426. offset & (GRUB_DISK_SECTOR_SIZE - 1), len, buf);
  427. disk->read_hook = 0;
  428. if (grub_errno)
  429. return -1;
  430. return len;
  431. }
  432. #endif
  433. /* Calculate the logical cluster number and offset. */
  434. logical_cluster_bits = (node->data->cluster_bits
  435. + GRUB_DISK_SECTOR_BITS);
  436. logical_cluster = offset >> logical_cluster_bits;
  437. offset &= (1ULL << logical_cluster_bits) - 1;
  438. if (logical_cluster < node->cur_cluster_num)
  439. {
  440. node->cur_cluster_num = 0;
  441. node->cur_cluster = node->file_cluster;
  442. }
  443. while (len)
  444. {
  445. while (logical_cluster > node->cur_cluster_num)
  446. {
  447. /* Find next cluster. */
  448. grub_uint32_t next_cluster;
  449. grub_uint32_t fat_offset;
  450. switch (node->data->fat_size)
  451. {
  452. case 32:
  453. fat_offset = node->cur_cluster << 2;
  454. break;
  455. case 16:
  456. fat_offset = node->cur_cluster << 1;
  457. break;
  458. default:
  459. /* case 12: */
  460. fat_offset = node->cur_cluster + (node->cur_cluster >> 1);
  461. break;
  462. }
  463. /* Read the FAT. */
  464. if (grub_disk_read (disk, node->data->fat_sector, fat_offset,
  465. (node->data->fat_size + 7) >> 3,
  466. (char *) &next_cluster))
  467. return -1;
  468. next_cluster = grub_le_to_cpu32 (next_cluster);
  469. switch (node->data->fat_size)
  470. {
  471. case 16:
  472. next_cluster &= 0xFFFF;
  473. break;
  474. case 12:
  475. if (node->cur_cluster & 1)
  476. next_cluster >>= 4;
  477. next_cluster &= 0x0FFF;
  478. break;
  479. }
  480. grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n",
  481. node->data->fat_size, next_cluster);
  482. /* Check the end. */
  483. if (next_cluster >= node->data->cluster_eof_mark)
  484. return ret;
  485. if (next_cluster < 2 || next_cluster >= node->data->num_clusters)
  486. {
  487. grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u",
  488. next_cluster);
  489. return -1;
  490. }
  491. node->cur_cluster = next_cluster;
  492. node->cur_cluster_num++;
  493. }
  494. /* Read the data here. */
  495. sector = (node->data->cluster_sector
  496. + ((node->cur_cluster - 2)
  497. << node->data->cluster_bits));
  498. size = (1 << logical_cluster_bits) - offset;
  499. if (size > len)
  500. size = len;
  501. disk->read_hook = read_hook;
  502. disk->read_hook_data = read_hook_data;
  503. grub_disk_read (disk, sector, offset, size, buf);
  504. disk->read_hook = 0;
  505. if (grub_errno)
  506. return -1;
  507. len -= size;
  508. buf += size;
  509. ret += size;
  510. logical_cluster++;
  511. offset = 0;
  512. }
  513. return ret;
  514. }
  515. struct grub_fat_iterate_context
  516. {
  517. #ifdef MODE_EXFAT
  518. struct grub_fat_dir_node dir;
  519. #else
  520. struct grub_fat_dir_entry dir;
  521. #endif
  522. char *filename;
  523. grub_uint16_t *unibuf;
  524. grub_ssize_t offset;
  525. };
  526. static grub_err_t
  527. grub_fat_iterate_init (struct grub_fat_iterate_context *ctxt)
  528. {
  529. ctxt->offset = -sizeof (struct grub_fat_dir_entry);
  530. #ifndef MODE_EXFAT
  531. /* Allocate space enough to hold a long name. */
  532. ctxt->filename = grub_malloc (0x40 * 13 * GRUB_MAX_UTF8_PER_UTF16 + 1);
  533. ctxt->unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
  534. #else
  535. ctxt->unibuf = grub_malloc (15 * 256 * 2);
  536. ctxt->filename = grub_malloc (15 * 256 * GRUB_MAX_UTF8_PER_UTF16 + 1);
  537. #endif
  538. if (! ctxt->filename || ! ctxt->unibuf)
  539. {
  540. grub_free (ctxt->filename);
  541. grub_free (ctxt->unibuf);
  542. return grub_errno;
  543. }
  544. return GRUB_ERR_NONE;
  545. }
  546. static void
  547. grub_fat_iterate_fini (struct grub_fat_iterate_context *ctxt)
  548. {
  549. grub_free (ctxt->filename);
  550. grub_free (ctxt->unibuf);
  551. }
  552. #ifdef MODE_EXFAT
  553. static grub_err_t
  554. grub_fat_iterate_dir_next (grub_fshelp_node_t node,
  555. struct grub_fat_iterate_context *ctxt)
  556. {
  557. grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir));
  558. while (1)
  559. {
  560. struct grub_fat_dir_entry dir;
  561. ctxt->offset += sizeof (dir);
  562. if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (dir),
  563. (char *) &dir)
  564. != sizeof (dir))
  565. break;
  566. if (dir.entry_type == 0)
  567. break;
  568. if (!(dir.entry_type & 0x80))
  569. continue;
  570. if (dir.entry_type == 0x85)
  571. {
  572. unsigned i, nsec, slots = 0;
  573. nsec = dir.type_specific.file.secondary_count;
  574. ctxt->dir.attr = grub_cpu_to_le16 (dir.type_specific.file.attr);
  575. ctxt->dir.have_stream = 0;
  576. for (i = 0; i < nsec; i++)
  577. {
  578. struct grub_fat_dir_entry sec;
  579. ctxt->offset += sizeof (sec);
  580. if (grub_fat_read_data (node->disk, node, 0, 0,
  581. ctxt->offset, sizeof (sec), (char *) &sec)
  582. != sizeof (sec))
  583. break;
  584. if (!(sec.entry_type & 0x80))
  585. continue;
  586. if (!(sec.entry_type & 0x40))
  587. break;
  588. switch (sec.entry_type)
  589. {
  590. case 0xc0:
  591. ctxt->dir.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster);
  592. ctxt->dir.valid_size
  593. = grub_cpu_to_le64 (sec.type_specific.stream_extension.valid_size);
  594. ctxt->dir.file_size
  595. = grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size);
  596. ctxt->dir.have_stream = 1;
  597. ctxt->dir.is_contiguous = !!(sec.type_specific.stream_extension.flags
  598. & grub_cpu_to_le16_compile_time (FLAG_CONTIGUOUS));
  599. break;
  600. case 0xc1:
  601. {
  602. int j;
  603. for (j = 0; j < 15; j++)
  604. ctxt->unibuf[slots * 15 + j]
  605. = grub_le_to_cpu16 (sec.type_specific.file_name.str[j]);
  606. slots++;
  607. }
  608. break;
  609. default:
  610. grub_dprintf ("exfat", "unknown secondary type 0x%02x\n",
  611. sec.entry_type);
  612. }
  613. }
  614. if (i != nsec)
  615. {
  616. ctxt->offset -= sizeof (dir);
  617. continue;
  618. }
  619. *grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename, ctxt->unibuf,
  620. slots * 15) = '\0';
  621. return 0;
  622. }
  623. /* Allocation bitmap. */
  624. if (dir.entry_type == 0x81)
  625. continue;
  626. /* Upcase table. */
  627. if (dir.entry_type == 0x82)
  628. continue;
  629. /* Volume label. */
  630. if (dir.entry_type == 0x83)
  631. continue;
  632. grub_dprintf ("exfat", "unknown primary type 0x%02x\n",
  633. dir.entry_type);
  634. }
  635. return grub_errno ? : GRUB_ERR_EOF;
  636. }
  637. #else
  638. static grub_err_t
  639. grub_fat_iterate_dir_next (grub_fshelp_node_t node,
  640. struct grub_fat_iterate_context *ctxt)
  641. {
  642. char *filep = 0;
  643. int checksum = -1;
  644. int slot = -1, slots = -1;
  645. while (1)
  646. {
  647. unsigned i;
  648. /* Adjust the offset. */
  649. ctxt->offset += sizeof (ctxt->dir);
  650. /* Read a directory entry. */
  651. if (grub_fat_read_data (node->disk, node, 0, 0,
  652. ctxt->offset, sizeof (ctxt->dir),
  653. (char *) &ctxt->dir)
  654. != sizeof (ctxt->dir) || ctxt->dir.name[0] == 0)
  655. break;
  656. /* Handle long name entries. */
  657. if (ctxt->dir.attr == GRUB_FAT_ATTR_LONG_NAME)
  658. {
  659. struct grub_fat_long_name_entry *long_name
  660. = (struct grub_fat_long_name_entry *) &ctxt->dir;
  661. grub_uint8_t id = long_name->id;
  662. if (id & 0x40)
  663. {
  664. id &= 0x3f;
  665. slots = slot = id;
  666. checksum = long_name->checksum;
  667. }
  668. if (id != slot || slot == 0 || checksum != long_name->checksum)
  669. {
  670. checksum = -1;
  671. continue;
  672. }
  673. slot--;
  674. grub_memcpy (ctxt->unibuf + slot * 13, long_name->name1, 5 * 2);
  675. grub_memcpy (ctxt->unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
  676. grub_memcpy (ctxt->unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
  677. continue;
  678. }
  679. /* Check if this entry is valid. */
  680. if (ctxt->dir.name[0] == 0xe5 || (ctxt->dir.attr & ~GRUB_FAT_ATTR_VALID))
  681. continue;
  682. /* This is a workaround for Japanese. */
  683. if (ctxt->dir.name[0] == 0x05)
  684. ctxt->dir.name[0] = 0xe5;
  685. if (checksum != -1 && slot == 0)
  686. {
  687. grub_uint8_t sum;
  688. for (sum = 0, i = 0; i < sizeof (ctxt->dir.name); i++)
  689. sum = ((sum >> 1) | (sum << 7)) + ctxt->dir.name[i];
  690. if (sum == checksum)
  691. {
  692. int u;
  693. for (u = 0; u < slots * 13; u++)
  694. ctxt->unibuf[u] = grub_le_to_cpu16 (ctxt->unibuf[u]);
  695. *grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename,
  696. ctxt->unibuf,
  697. slots * 13) = '\0';
  698. return GRUB_ERR_NONE;
  699. }
  700. checksum = -1;
  701. }
  702. /* Convert the 8.3 file name. */
  703. filep = ctxt->filename;
  704. if (ctxt->dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
  705. {
  706. for (i = 0; i < sizeof (ctxt->dir.name) && ctxt->dir.name[i]; i++)
  707. *filep++ = ctxt->dir.name[i];
  708. while (i > 0 && ctxt->dir.name[i - 1] == ' ')
  709. {
  710. filep--;
  711. i--;
  712. }
  713. }
  714. else
  715. {
  716. for (i = 0; i < 8 && ctxt->dir.name[i]; i++)
  717. *filep++ = grub_tolower (ctxt->dir.name[i]);
  718. while (i > 0 && ctxt->dir.name[i - 1] == ' ')
  719. {
  720. filep--;
  721. i--;
  722. }
  723. /* XXX should we check that dir position is 0 or 1? */
  724. if (i > 2 || filep[0] != '.' || (i == 2 && filep[1] != '.'))
  725. *filep++ = '.';
  726. for (i = 8; i < 11 && ctxt->dir.name[i]; i++)
  727. *filep++ = grub_tolower (ctxt->dir.name[i]);
  728. while (i > 8 && ctxt->dir.name[i - 1] == ' ')
  729. {
  730. filep--;
  731. i--;
  732. }
  733. if (i == 8)
  734. filep--;
  735. }
  736. *filep = '\0';
  737. return GRUB_ERR_NONE;
  738. }
  739. return grub_errno ? : GRUB_ERR_EOF;
  740. }
  741. #endif
  742. static grub_err_t lookup_file (grub_fshelp_node_t node,
  743. const char *name,
  744. grub_fshelp_node_t *foundnode,
  745. enum grub_fshelp_filetype *foundtype)
  746. {
  747. grub_err_t err;
  748. struct grub_fat_iterate_context ctxt;
  749. err = grub_fat_iterate_init (&ctxt);
  750. if (err)
  751. return err;
  752. while (!(err = grub_fat_iterate_dir_next (node, &ctxt)))
  753. {
  754. #ifdef MODE_EXFAT
  755. if (!ctxt.dir.have_stream)
  756. continue;
  757. #else
  758. if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
  759. continue;
  760. #endif
  761. if (grub_strcasecmp (name, ctxt.filename) == 0)
  762. {
  763. *foundnode = grub_malloc (sizeof (struct grub_fshelp_node));
  764. if (!*foundnode)
  765. return grub_errno;
  766. (*foundnode)->attr = ctxt.dir.attr;
  767. #ifdef MODE_EXFAT
  768. (*foundnode)->file_size = ctxt.dir.file_size;
  769. (*foundnode)->file_cluster = ctxt.dir.first_cluster;
  770. (*foundnode)->is_contiguous = ctxt.dir.is_contiguous;
  771. #else
  772. (*foundnode)->file_size = grub_le_to_cpu32 (ctxt.dir.file_size);
  773. (*foundnode)->file_cluster = ((grub_le_to_cpu16 (ctxt.dir.first_cluster_high) << 16)
  774. | grub_le_to_cpu16 (ctxt.dir.first_cluster_low));
  775. /* If directory points to root, starting cluster is 0 */
  776. if (!(*foundnode)->file_cluster)
  777. (*foundnode)->file_cluster = node->data->root_cluster;
  778. #endif
  779. (*foundnode)->cur_cluster_num = ~0U;
  780. (*foundnode)->data = node->data;
  781. (*foundnode)->disk = node->disk;
  782. *foundtype = ((*foundnode)->attr & GRUB_FAT_ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG;
  783. grub_fat_iterate_fini (&ctxt);
  784. return GRUB_ERR_NONE;
  785. }
  786. }
  787. grub_fat_iterate_fini (&ctxt);
  788. if (err == GRUB_ERR_EOF)
  789. err = 0;
  790. return err;
  791. }
  792. static grub_err_t
  793. grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
  794. void *hook_data)
  795. {
  796. struct grub_fat_data *data = 0;
  797. grub_disk_t disk = device->disk;
  798. grub_fshelp_node_t found = NULL;
  799. grub_err_t err;
  800. struct grub_fat_iterate_context ctxt;
  801. grub_dl_ref (my_mod);
  802. data = grub_fat_mount (disk);
  803. if (! data)
  804. goto fail;
  805. struct grub_fshelp_node root = {
  806. .data = data,
  807. .disk = disk,
  808. .attr = GRUB_FAT_ATTR_DIRECTORY,
  809. .file_size = 0,
  810. .file_cluster = data->root_cluster,
  811. .cur_cluster_num = ~0U,
  812. .cur_cluster = 0,
  813. #ifdef MODE_EXFAT
  814. .is_contiguous = 0,
  815. #endif
  816. };
  817. err = grub_fshelp_find_file_lookup (path, &root, &found, lookup_file, NULL, GRUB_FSHELP_DIR);
  818. if (err)
  819. goto fail;
  820. err = grub_fat_iterate_init (&ctxt);
  821. if (err)
  822. goto fail;
  823. while (!(err = grub_fat_iterate_dir_next (found, &ctxt)))
  824. {
  825. struct grub_dirhook_info info;
  826. grub_memset (&info, 0, sizeof (info));
  827. info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY);
  828. info.case_insensitive = 1;
  829. #ifdef MODE_EXFAT
  830. if (!ctxt.dir.have_stream)
  831. continue;
  832. #else
  833. if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
  834. continue;
  835. #endif
  836. if (hook (ctxt.filename, &info, hook_data))
  837. break;
  838. }
  839. grub_fat_iterate_fini (&ctxt);
  840. if (err == GRUB_ERR_EOF)
  841. err = 0;
  842. fail:
  843. if (found != &root)
  844. grub_free (found);
  845. grub_free (data);
  846. grub_dl_unref (my_mod);
  847. return grub_errno;
  848. }
  849. static grub_err_t
  850. grub_fat_open (grub_file_t file, const char *name)
  851. {
  852. struct grub_fat_data *data = 0;
  853. grub_fshelp_node_t found = NULL;
  854. grub_err_t err;
  855. grub_disk_t disk = file->device->disk;
  856. grub_dl_ref (my_mod);
  857. data = grub_fat_mount (disk);
  858. if (! data)
  859. goto fail;
  860. struct grub_fshelp_node root = {
  861. .data = data,
  862. .disk = disk,
  863. .attr = GRUB_FAT_ATTR_DIRECTORY,
  864. .file_size = 0,
  865. .file_cluster = data->root_cluster,
  866. .cur_cluster_num = ~0U,
  867. .cur_cluster = 0,
  868. #ifdef MODE_EXFAT
  869. .is_contiguous = 0,
  870. #endif
  871. };
  872. err = grub_fshelp_find_file_lookup (name, &root, &found, lookup_file, NULL, GRUB_FSHELP_REG);
  873. if (err)
  874. goto fail;
  875. file->data = found;
  876. file->size = found->file_size;
  877. return GRUB_ERR_NONE;
  878. fail:
  879. if (found != &root)
  880. grub_free (found);
  881. grub_free (data);
  882. grub_dl_unref (my_mod);
  883. return grub_errno;
  884. }
  885. static grub_ssize_t
  886. grub_fat_read (grub_file_t file, char *buf, grub_size_t len)
  887. {
  888. return grub_fat_read_data (file->device->disk, file->data,
  889. file->read_hook, file->read_hook_data,
  890. file->offset, len, buf);
  891. }
  892. static grub_err_t
  893. grub_fat_close (grub_file_t file)
  894. {
  895. grub_fshelp_node_t node = file->data;
  896. grub_free (node->data);
  897. grub_free (node);
  898. grub_dl_unref (my_mod);
  899. return grub_errno;
  900. }
  901. #ifdef MODE_EXFAT
  902. static grub_err_t
  903. grub_fat_label (grub_device_t device, char **label)
  904. {
  905. struct grub_fat_dir_entry dir;
  906. grub_ssize_t offset = -sizeof(dir);
  907. grub_disk_t disk = device->disk;
  908. struct grub_fshelp_node root = {
  909. .disk = disk,
  910. .attr = GRUB_FAT_ATTR_DIRECTORY,
  911. .file_size = 0,
  912. .cur_cluster_num = ~0U,
  913. .cur_cluster = 0,
  914. .is_contiguous = 0,
  915. };
  916. root.data = grub_fat_mount (disk);
  917. if (! root.data)
  918. return grub_errno;
  919. root.file_cluster = root.data->root_cluster;
  920. *label = NULL;
  921. while (1)
  922. {
  923. offset += sizeof (dir);
  924. if (grub_fat_read_data (disk, &root, 0, 0,
  925. offset, sizeof (dir), (char *) &dir)
  926. != sizeof (dir))
  927. break;
  928. if (dir.entry_type == 0)
  929. break;
  930. if (!(dir.entry_type & 0x80))
  931. continue;
  932. /* Volume label. */
  933. if (dir.entry_type == 0x83)
  934. {
  935. grub_size_t chc;
  936. grub_uint16_t t[ARRAY_SIZE (dir.type_specific.volume_label.str)];
  937. grub_size_t i;
  938. *label = grub_malloc (ARRAY_SIZE (dir.type_specific.volume_label.str)
  939. * GRUB_MAX_UTF8_PER_UTF16 + 1);
  940. if (!*label)
  941. {
  942. grub_free (root.data);
  943. return grub_errno;
  944. }
  945. chc = dir.type_specific.volume_label.character_count;
  946. if (chc > ARRAY_SIZE (dir.type_specific.volume_label.str))
  947. chc = ARRAY_SIZE (dir.type_specific.volume_label.str);
  948. for (i = 0; i < chc; i++)
  949. t[i] = grub_le_to_cpu16 (dir.type_specific.volume_label.str[i]);
  950. *grub_utf16_to_utf8 ((grub_uint8_t *) *label, t, chc) = '\0';
  951. }
  952. }
  953. grub_free (root.data);
  954. return grub_errno;
  955. }
  956. #else
  957. static grub_err_t
  958. grub_fat_label (grub_device_t device, char **label)
  959. {
  960. grub_disk_t disk = device->disk;
  961. grub_err_t err;
  962. struct grub_fat_iterate_context ctxt;
  963. struct grub_fshelp_node root = {
  964. .disk = disk,
  965. .attr = GRUB_FAT_ATTR_DIRECTORY,
  966. .file_size = 0,
  967. .cur_cluster_num = ~0U,
  968. .cur_cluster = 0,
  969. };
  970. *label = 0;
  971. grub_dl_ref (my_mod);
  972. root.data = grub_fat_mount (disk);
  973. if (! root.data)
  974. goto fail;
  975. root.file_cluster = root.data->root_cluster;
  976. err = grub_fat_iterate_init (&ctxt);
  977. if (err)
  978. goto fail;
  979. while (!(err = grub_fat_iterate_dir_next (&root, &ctxt)))
  980. if ((ctxt.dir.attr & ~GRUB_FAT_ATTR_ARCHIVE) == GRUB_FAT_ATTR_VOLUME_ID)
  981. {
  982. *label = grub_strdup (ctxt.filename);
  983. break;
  984. }
  985. grub_fat_iterate_fini (&ctxt);
  986. fail:
  987. grub_dl_unref (my_mod);
  988. grub_free (root.data);
  989. return grub_errno;
  990. }
  991. #endif
  992. static grub_err_t
  993. grub_fat_uuid (grub_device_t device, char **uuid)
  994. {
  995. struct grub_fat_data *data;
  996. grub_disk_t disk = device->disk;
  997. grub_dl_ref (my_mod);
  998. data = grub_fat_mount (disk);
  999. if (data)
  1000. {
  1001. char *ptr;
  1002. *uuid = grub_xasprintf ("%04x-%04x",
  1003. (grub_uint16_t) (data->uuid >> 16),
  1004. (grub_uint16_t) data->uuid);
  1005. for (ptr = *uuid; ptr && *ptr; ptr++)
  1006. *ptr = grub_toupper (*ptr);
  1007. }
  1008. else
  1009. *uuid = NULL;
  1010. grub_dl_unref (my_mod);
  1011. grub_free (data);
  1012. return grub_errno;
  1013. }
  1014. #ifdef GRUB_UTIL
  1015. #ifndef MODE_EXFAT
  1016. grub_disk_addr_t
  1017. grub_fat_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn)
  1018. #else
  1019. grub_disk_addr_t
  1020. grub_exfat_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn)
  1021. #endif
  1022. {
  1023. grub_disk_addr_t ret;
  1024. struct grub_fat_data *data;
  1025. data = grub_fat_mount (disk);
  1026. if (!data)
  1027. return 0;
  1028. ret = data->cluster_sector;
  1029. *sec_per_lcn = 1ULL << data->cluster_bits;
  1030. grub_free (data);
  1031. return ret;
  1032. }
  1033. #endif
  1034. static struct grub_fs grub_fat_fs =
  1035. {
  1036. #ifdef MODE_EXFAT
  1037. .name = "exfat",
  1038. #else
  1039. .name = "fat",
  1040. #endif
  1041. .fs_dir = grub_fat_dir,
  1042. .fs_open = grub_fat_open,
  1043. .fs_read = grub_fat_read,
  1044. .fs_close = grub_fat_close,
  1045. .fs_label = grub_fat_label,
  1046. .fs_uuid = grub_fat_uuid,
  1047. #ifdef GRUB_UTIL
  1048. #ifdef MODE_EXFAT
  1049. /* ExFAT BPB is 30 larger than FAT32 one. */
  1050. .reserved_first_sector = 0,
  1051. #else
  1052. .reserved_first_sector = 1,
  1053. #endif
  1054. .blocklist_install = 1,
  1055. #endif
  1056. .next = 0
  1057. };
  1058. #ifdef MODE_EXFAT
  1059. GRUB_MOD_INIT(exfat)
  1060. #else
  1061. GRUB_MOD_INIT(fat)
  1062. #endif
  1063. {
  1064. COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32);
  1065. grub_fs_register (&grub_fat_fs);
  1066. my_mod = mod;
  1067. }
  1068. #ifdef MODE_EXFAT
  1069. GRUB_MOD_FINI(exfat)
  1070. #else
  1071. GRUB_MOD_FINI(fat)
  1072. #endif
  1073. {
  1074. grub_fs_unregister (&grub_fat_fs);
  1075. }