fat.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. /* Copyright (C) 2013 by John Cronin <jncronin@tysos.org>
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. * The above copyright notice and this permission notice shall be included in
  10. * all copies or substantial portions of the Software.
  11. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. * THE SOFTWARE.
  18. */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <stdint.h>
  22. #include <string.h>
  23. #include "dirent.h"
  24. //#include "vfs.h"
  25. #include "fs.h"
  26. #include "errno.h"
  27. #include "util.h"
  28. #include <malloc.h>
  29. #define FAT_DEBUG
  30. struct fat_fs {
  31. struct fs b;
  32. int fat_type;
  33. uint32_t total_sectors;
  34. uint32_t sectors_per_cluster;
  35. uint32_t bytes_per_sector;
  36. char *vol_label;
  37. uint32_t first_fat_sector;
  38. uint32_t first_data_sector;
  39. uint32_t sectors_per_fat;
  40. uint32_t root_dir_entries;
  41. uint32_t root_dir_sectors;
  42. uint32_t first_non_root_sector;
  43. uint32_t root_dir_cluster;
  44. };
  45. // FAT32 extended fields
  46. struct fat_extBS_32
  47. {
  48. uint32_t table_size_32;
  49. uint16_t extended_flags;
  50. uint16_t fat_version;
  51. uint32_t root_cluster;
  52. uint16_t fat_info;
  53. uint16_t backup_BS_sector;
  54. uint8_t reserved_0[12];
  55. uint8_t drive_number;
  56. uint8_t reserved_1;
  57. uint8_t boot_signature;
  58. uint32_t volume_id;
  59. char volume_label[11];
  60. uint8_t fat_type_label[8];
  61. };// __attribute__ ((packed));
  62. // FAT 12/16 extended fields
  63. struct fat_extBS_16
  64. {
  65. uint8_t bios_drive_num;
  66. uint8_t reserved1;
  67. uint8_t boot_signature;
  68. uint32_t volume_id;
  69. char volume_label[11];
  70. uint8_t fat_type_label[8];
  71. };// __attribute__ ((packed));
  72. // Generic FAT fields
  73. struct fat_BS
  74. {
  75. uint8_t bootjmp[3]; // skip 1, we can't have odd struct
  76. uint8_t oem_name[8];
  77. uint16_t bytes_per_sector; // 11
  78. uint8_t sectors_per_cluster; // 13
  79. uint16_t reserved_sector_count; // 14
  80. uint8_t table_count; // 16
  81. uint16_t root_entry_count; // 17
  82. uint16_t total_sectors_16; // 19
  83. uint8_t media_type; // 21
  84. uint16_t table_size_16; // 22
  85. uint16_t sectors_per_track; // 24
  86. uint16_t head_side_count; // 26
  87. uint32_t hidden_sector_count; // 28
  88. uint32_t total_sectors_32; // 32
  89. union
  90. {
  91. struct fat_extBS_32 fat32; // 36
  92. struct fat_extBS_16 fat16;
  93. } ext;
  94. };// __attribute__ ((packed));
  95. void read_fat_bs(uint8_t* buf, struct fat_BS* bs) {
  96. memcpy(bs->bootjmp,buf,3);
  97. memcpy(bs->oem_name,buf+3,8);
  98. bs->bytes_per_sector = read_halfword(buf, 11);
  99. bs->sectors_per_cluster = read_byte(buf, 13);
  100. bs->reserved_sector_count = read_halfword(buf, 14);
  101. bs->table_count = read_byte(buf, 16);
  102. bs->root_entry_count = read_halfword(buf, 17);
  103. bs->total_sectors_16 = read_halfword(buf, 19);
  104. bs->media_type = read_byte(buf, 21);
  105. bs->table_size_16 = read_halfword(buf, 22);
  106. bs->sectors_per_track = read_halfword(buf, 24);
  107. bs->head_side_count = read_halfword(buf, 26);
  108. bs->hidden_sector_count = read_word(buf, 28);
  109. bs->total_sectors_32 = read_word(buf, 32);
  110. if (bs->table_size_16==0) {
  111. memcpy(&bs->ext,buf+36,sizeof(struct fat_extBS_32));
  112. } else {
  113. bs->ext.fat16.bios_drive_num = read_byte(buf,36);
  114. bs->ext.fat16.reserved1 = read_byte(buf,37);
  115. bs->ext.fat16.boot_signature = read_byte(buf,38);
  116. bs->ext.fat16.volume_id = read_word(buf,39);
  117. memcpy(&bs->ext.fat16.volume_label,buf+43,11);
  118. memcpy(&bs->ext.fat16.fat_type_label,buf+54,8);
  119. }
  120. }
  121. #define FAT12 0
  122. #define FAT16 1
  123. #define FAT32 2
  124. #define VFAT 3
  125. static struct dirent *fat_read_dir(struct fat_fs *fs, struct dirent *d);
  126. struct dirent *fat_read_directory(struct fs *fs, char **name);
  127. static uint32_t fat_get_next_bdev_block_num(uint32_t f_block_idx, fs_file *s, void *opaque, int add_blocks);
  128. struct fat_file_block_offset
  129. {
  130. uint32_t f_block;
  131. uint32_t cluster;
  132. };
  133. static const char *fat_names[] = { "FAT12", "FAT16", "FAT32", "VFAT" };
  134. static fs_file *fat_fopen(struct fs *fs, struct dirent *path, const char *mode)
  135. {
  136. /*if(fs != path->fs)
  137. {
  138. errno = EFAULT;
  139. return (vfs_file *)0;
  140. }*/
  141. if(strcmp(mode, "r"))
  142. {
  143. errno = EROFS;
  144. return NULL;
  145. }
  146. struct fs_file *ret = (struct fs_file *)memalign(16,sizeof(struct fs_file));
  147. memset(ret, 0, sizeof(struct fs_file));
  148. ret->fs = fs;
  149. ret->pos = 0;
  150. ret->opaque = path->opaque;
  151. ret->len = (long)path->byte_size;
  152. (void)mode;
  153. return ret;
  154. }
  155. static size_t fat_fread(struct fs *fs, void *ptr, size_t byte_size, fs_file *stream)
  156. {
  157. if(stream->fs != fs)
  158. return -1;
  159. if(stream->opaque == (void *)0)
  160. return -1;
  161. struct fat_file_block_offset opaque;
  162. opaque.cluster = (uint32_t)stream->opaque;
  163. opaque.f_block = 0;
  164. return fs_fread(fat_get_next_bdev_block_num, fs, ptr, byte_size, stream, (void*)&opaque);
  165. }
  166. static int fat_fclose(struct fs *fs, fs_file *fp)
  167. {
  168. (void)fs;
  169. (void)fp;
  170. return 0;
  171. }
  172. int fat_init(struct block_device *parent, struct fs **fs)
  173. {
  174. // Interpret a FAT file system
  175. #ifdef FAT_DEBUG
  176. printf("FAT: looking for a filesytem on %s\r\n", parent->device_name);
  177. #endif
  178. // Read block 0
  179. uint8_t *block_0 = (uint8_t *)memalign(16,512);
  180. int r = block_read(parent, block_0, 512, 0);
  181. if(r < 0)
  182. {
  183. printf("FAT: error %i reading block 0\r\n", r);
  184. return r;
  185. }
  186. if(r != 512)
  187. {
  188. printf("FAT: error reading block 0 (only %i bytes read)\r\n", r);
  189. return -1;
  190. }
  191. // Dump the boot block
  192. #ifdef FAT_DEBUG
  193. int j = 0;
  194. for(int i = 0; i < 90; i++)
  195. {
  196. printf("%02x ", block_0[i]);
  197. j++;
  198. if(j == 8)
  199. {
  200. j = 0;
  201. printf("\r\n");
  202. }
  203. }
  204. if(j != 0)
  205. printf("\r\n");
  206. #endif
  207. //struct fat_BS _bs; // = (struct fat_BS *)block_0;
  208. struct fat_BS* bs = malloc(sizeof(struct fat_BS)+128); //&_bs;
  209. read_fat_bs(block_0, bs);
  210. if(block_0[0] != 0xeb)
  211. {
  212. printf("FAT: not a valid FAT filesystem on %s (%x)\r\n", parent->device_name,
  213. block_0[0]);
  214. return -1;
  215. }
  216. printf("FAT: filesystem seems valid\r\n");
  217. uint32_t total_sectors = (uint32_t)bs->total_sectors_16;
  218. if(total_sectors == 0)
  219. total_sectors = bs->total_sectors_32;
  220. printf("FAT: sectors: %d\r\n",total_sectors);
  221. struct fat_fs *ret = (struct fat_fs *)malloc(sizeof(struct fat_fs));
  222. printf("FAT: 0\r\n");
  223. memset(ret, 0, sizeof(struct fat_fs));
  224. ret->b.fopen = fat_fopen;
  225. ret->b.fread = fat_fread;
  226. ret->b.fclose = fat_fclose;
  227. ret->b.read_directory = fat_read_directory;
  228. ret->b.parent = parent;
  229. printf("FAT: 1\r\n");
  230. ret->total_sectors = total_sectors;
  231. ret->bytes_per_sector = (uint32_t)bs->bytes_per_sector;
  232. ret->root_dir_entries = bs->root_entry_count;
  233. ret->root_dir_sectors = (ret->root_dir_entries * 32 + ret->bytes_per_sector - 1) /
  234. ret->bytes_per_sector; // The + bytes_per_sector - 1 rounds up the sector no
  235. printf("FAT: 2\r\n");
  236. uint32_t fat_size = bs->table_size_16;
  237. if(fat_size == 0)
  238. fat_size = bs->ext.fat32.table_size_32;
  239. printf("FAT: 3\r\n");
  240. uint32_t data_sec = total_sectors - (bs->reserved_sector_count +
  241. bs->table_count * fat_size + ret->root_dir_sectors);
  242. printf("FAT: 4\r\n");
  243. uint32_t total_clusters = data_sec / bs->sectors_per_cluster;
  244. if(total_clusters < 4085)
  245. ret->fat_type = FAT12;
  246. else if(total_clusters < 65525)
  247. ret->fat_type = FAT16;
  248. else
  249. ret->fat_type = FAT32;
  250. ret->b.fs_name = fat_names[ret->fat_type];
  251. ret->sectors_per_cluster = (uint32_t)bs->sectors_per_cluster;
  252. printf("FAT: 5\r\n");
  253. #ifdef FAT_DEBUG
  254. printf("FAT: reading a %s filesystem: total_sectors %i, sectors_per_cluster %i, "
  255. "bytes_per_sector %i\r\n",
  256. ret->b.fs_name, ret->total_sectors, ret->sectors_per_cluster,
  257. ret->bytes_per_sector);
  258. #endif
  259. printf("FAT: 6\r\n");
  260. // Interpret the extended bpb
  261. ret->vol_label = (char *)malloc(12);
  262. if(ret->fat_type == FAT32)
  263. {
  264. // FAT32
  265. strcpy(ret->vol_label, bs->ext.fat32.volume_label);
  266. ret->vol_label[11] = 0;
  267. printf("FAT32: volume label: %s\r\n", ret->vol_label);
  268. ret->first_data_sector = bs->reserved_sector_count + (bs->table_count *
  269. bs->ext.fat32.table_size_32);
  270. ret->first_fat_sector = bs->reserved_sector_count;
  271. ret->first_non_root_sector = ret->first_data_sector;
  272. ret->sectors_per_fat = bs->ext.fat32.table_size_32;
  273. #ifdef FAT_DEBUG
  274. printf("FAT32: first_data_sector: %i, first_fat_sector: %i\r\n",
  275. ret->first_data_sector,
  276. ret->first_fat_sector);
  277. #endif
  278. ret->root_dir_cluster = bs->ext.fat32.root_cluster;
  279. }
  280. else
  281. {
  282. // FAT12/16
  283. strcpy(ret->vol_label, bs->ext.fat16.volume_label);
  284. ret->vol_label[11] = 0;
  285. #ifdef FAT_DEBUG
  286. printf("FAT16: volume label: %s\r\n", ret->vol_label);
  287. #endif
  288. ret->first_data_sector = bs->reserved_sector_count + (bs->table_count *
  289. bs->table_size_16);
  290. ret->first_fat_sector = bs->reserved_sector_count;
  291. ret->sectors_per_fat = bs->table_size_16;
  292. #ifdef FAT_DEBUG
  293. printf("FAT16: first_data_sector: %i, first_fat_sector: %i\r\n",
  294. ret->first_data_sector,
  295. ret->first_fat_sector);
  296. printf("FAT16: root_dir_entries: %i, root_dir_sectors: %i\r\n",
  297. ret->root_dir_entries,
  298. ret->root_dir_sectors);
  299. #endif
  300. ret->first_non_root_sector = ret->first_data_sector + ret->root_dir_sectors;
  301. ret->root_dir_cluster = 2;
  302. }
  303. printf("FAT: 7\r\n");
  304. ret->b.block_size = ret->bytes_per_sector * ret->sectors_per_cluster;
  305. *fs = (struct fs *)ret;
  306. //free(block_0); // FIXME
  307. printf("FAT: found a %s filesystem on %s\r\n", ret->b.fs_name, ret->b.parent->device_name);
  308. return 0;
  309. }
  310. uint32_t get_sector(struct fat_fs *fs, uint32_t rel_cluster)
  311. {/*
  312. #ifdef FAT_DEBUG
  313. printf("FAT: get_sector rel_cluster %i, sector %i\r\n",
  314. rel_cluster,
  315. fs->first_non_root_sector + (rel_cluster - 2) * fs->sectors_per_cluster);
  316. #endif*/
  317. printf("*");
  318. rel_cluster -= 2;
  319. return fs->first_non_root_sector + rel_cluster * fs->sectors_per_cluster;
  320. }
  321. static uint32_t get_next_fat_entry(struct fat_fs *fs, uint32_t current_cluster)
  322. {
  323. switch(fs->fat_type)
  324. {
  325. case FAT16:
  326. {
  327. uint32_t fat_offset = current_cluster << 1; // *2
  328. uint32_t fat_sector = fs->first_fat_sector +
  329. (fat_offset / fs->bytes_per_sector);
  330. uint8_t *buf = (uint8_t *)memalign(16,512);
  331. int br_ret = block_read(fs->b.parent, buf, 512, fat_sector);
  332. if(br_ret < 0)
  333. {
  334. printf("FAT: block_read returned %i\r\n");
  335. return 0x0ffffff7;
  336. }
  337. uint32_t fat_index = fat_offset % fs->bytes_per_sector;
  338. uint32_t next_cluster = (uint32_t)*(uint16_t *)&buf[fat_index];
  339. free(buf);
  340. if(next_cluster >= 0xfff7)
  341. next_cluster |= 0x0fff0000;
  342. return next_cluster;
  343. }
  344. case FAT32:
  345. {
  346. uint32_t fat_offset = current_cluster << 2; // *4
  347. uint32_t fat_sector = fs->first_fat_sector +
  348. (fat_offset / fs->bytes_per_sector);
  349. uint8_t *buf = (uint8_t *)memalign(16,512);
  350. int br_ret = block_read(fs->b.parent, buf, 512, fat_sector);
  351. if(br_ret < 0)
  352. {
  353. printf("FAT: block_read returned %i\r\n");
  354. return 0x0ffffff7;
  355. }
  356. uint32_t fat_index = fat_offset % fs->bytes_per_sector;
  357. uint32_t next_cluster = *(uint32_t *)&buf[fat_index];
  358. free(buf);
  359. return next_cluster & 0x0fffffff; // FAT32 is actually FAT28
  360. }
  361. default:
  362. printf("FAT: fat type %s not supported\r\n", fs->b.fs_name);
  363. return 0;
  364. }
  365. }
  366. struct dirent *fat_read_directory(struct fs *fs, char **name)
  367. {
  368. printf("[fat_read_directory]\r\n");
  369. struct dirent *cur_dir = fat_read_dir((struct fat_fs *)fs, (void*)0);
  370. while(*name)
  371. {
  372. // Search the directory entries for one of the requested name
  373. int found = 0;
  374. while(cur_dir)
  375. {
  376. if(!strcmp(*name, cur_dir->name))
  377. {
  378. if(!cur_dir->is_dir)
  379. {
  380. errno = ENOTDIR;
  381. return (void*)0;
  382. }
  383. found = 1;
  384. cur_dir = fat_read_dir((struct fat_fs *)fs, cur_dir);
  385. name++;
  386. break;
  387. }
  388. cur_dir = cur_dir->next;
  389. }
  390. if(!found)
  391. {
  392. #ifdef FAT_DEBUG
  393. printf("FAT: path part %s not found\r\n", *name);
  394. #endif
  395. errno = ENOENT;
  396. return (void*)0;
  397. }
  398. }
  399. return cur_dir;
  400. }
  401. static uint32_t fat_get_next_bdev_block_num(uint32_t f_block_idx, fs_file *s, void *opaque, int add_blocks)
  402. {
  403. struct fat_file_block_offset *ffbo = (struct fat_file_block_offset *)opaque;
  404. // Iterate through the cluster chain until we reach the appropriate one
  405. while((ffbo->f_block != f_block_idx) && (ffbo->cluster < 0x0ffffff8))
  406. {
  407. ffbo->cluster = get_next_fat_entry((struct fat_fs *)s->fs, ffbo->cluster);
  408. ffbo->f_block++;
  409. }
  410. if(ffbo->cluster < 0x0ffffff8)
  411. return get_sector((struct fat_fs *)s->fs, ffbo->cluster);
  412. else
  413. {
  414. if(add_blocks)
  415. {
  416. printf("FAT: request to extend cluster chain not currently supported\r\n");
  417. }
  418. s->flags |= EOF;
  419. return 0xffffffff;
  420. }
  421. }
  422. struct dirent *fat_read_dir(struct fat_fs *fs, struct dirent *d)
  423. {
  424. printf("[fat_read_dir]\r\n");
  425. int is_root = 0;
  426. struct fat_fs *fat = (struct fat_fs *)fs;
  427. if(d == (void*)0)
  428. is_root = 1;
  429. uint32_t cur_cluster;
  430. uint32_t cur_root_cluster_offset = 0;
  431. if(is_root)
  432. cur_cluster = fat->root_dir_cluster;
  433. else
  434. cur_cluster = (uint32_t)d->opaque;
  435. struct dirent *ret = (void *)0;
  436. struct dirent *prev = (void *)0;
  437. #ifdef FAT_DEBUG
  438. printf("FAT: read_dir: starting directory read from cluster %i\r\n", cur_cluster);
  439. #endif
  440. do
  441. {
  442. /* Read this cluster */
  443. uint32_t cluster_size = fat->bytes_per_sector * fat->sectors_per_cluster;
  444. //("FAT: 10\r\n");
  445. uint8_t *buf = (uint8_t *)memalign(16,cluster_size);
  446. /* Interpret the cluster number to an absolute address */
  447. uint32_t absolute_cluster = cur_cluster - 2;
  448. uint32_t first_data_sector = fat->first_data_sector;
  449. //printf("FAT: 11\r\n");
  450. if(!is_root)
  451. first_data_sector = fat->first_non_root_sector;
  452. //printf("FAT: 12\r\n");
  453. #ifdef FAT_DEBUG
  454. printf("FAT: reading cluster %i (sector %i)\r\n", cur_cluster,
  455. absolute_cluster * fat->sectors_per_cluster + first_data_sector);
  456. #endif
  457. int br_ret = block_read(fat->b.parent, buf, cluster_size,
  458. absolute_cluster * fat->sectors_per_cluster + first_data_sector);
  459. //printf("FAT: 13\r\n");
  460. if(br_ret < 0)
  461. {
  462. printf("FAT: block_read returned %i\r\n", br_ret);
  463. return (void*)0;
  464. }
  465. for(uint32_t ptr = 0; ptr < cluster_size; ptr += 32)
  466. {
  467. //printf("FAT: 14 %d\r\n",ptr);
  468. // Does the entry exist (if the first byte is zero of 0xe5 it doesn't)
  469. if((buf[ptr] == 0) || (buf[ptr] == 0xe5))
  470. continue;
  471. // Is it the directories '.' or '..'?
  472. if(buf[ptr] == '.')
  473. continue;
  474. // Is it a long filename entry (if so ignore)
  475. if(buf[ptr + 11] == 0x0f)
  476. continue;
  477. // Else read it
  478. struct dirent *de = (struct dirent *)memalign(16,sizeof(struct dirent));
  479. memset(de, 0, sizeof(struct dirent));
  480. if(ret == (void *)0)
  481. ret = de;
  482. if(prev != (void *)0)
  483. prev->next = de;
  484. prev = de;
  485. de->name = (char *)memalign(16,13);
  486. de->fs = &fs->b;
  487. // Convert to lowercase on load
  488. int d_idx = 0;
  489. int in_ext = 0;
  490. int has_ext = 0;
  491. for(int i = 0; i < 11; i++)
  492. {
  493. char cur_v = (char)buf[ptr + i];
  494. if(i == 8)
  495. {
  496. in_ext = 1;
  497. de->name[d_idx++] = '.';
  498. }
  499. if(cur_v == ' ')
  500. continue;
  501. if(in_ext)
  502. has_ext = 1;
  503. if((cur_v >= 'A') && (cur_v <= 'Z'))
  504. cur_v = 'a' + cur_v - 'A';
  505. de->name[d_idx++] = cur_v;
  506. }
  507. if(!has_ext)
  508. de->name[d_idx - 1] = 0;
  509. else
  510. de->name[d_idx] = 0;
  511. if(buf[ptr + 11] & 0x10)
  512. de->is_dir = 1;
  513. de->next = (void *)0;
  514. de->byte_size = read_word(buf, ptr + 28);
  515. uint32_t opaque = read_halfword(buf, ptr + 26) |
  516. ((uint32_t)read_halfword(buf, ptr + 20) << 16);
  517. de->opaque = (void*)opaque;
  518. #ifdef FAT_DEBUG
  519. printf("FAT: read dir entry: %s, size %i, cluster %i, ptr %i\r\n",
  520. de->name, de->byte_size, opaque, ptr);
  521. #endif
  522. }
  523. free(buf);
  524. // Get the next cluster
  525. if(is_root && (fs->fat_type != FAT32))
  526. {
  527. cur_root_cluster_offset++;
  528. if(cur_root_cluster_offset < (fat->root_dir_sectors /
  529. fat->sectors_per_cluster))
  530. cur_cluster++;
  531. else
  532. cur_cluster = 0x0ffffff8;
  533. }
  534. else
  535. cur_cluster = get_next_fat_entry(fat, cur_cluster);
  536. #ifdef FAT_DEBUG
  537. printf("FAT: read dir: next cluster %x\r\n", cur_cluster);
  538. #endif
  539. } while(cur_cluster < 0x0ffffff7);
  540. return ret;
  541. }