53 #define CFS_FAT_DEBUG 1
57 #define PRINTERROR(...) printf(__VA_ARGS__)
59 #define PRINTERROR(...)
62 #define PRINTDEBUG(...) printf(__VA_ARGS__)
64 #define PRINTDEBUG(...)
67 #define PRINTF(...) printf(__VA_ARGS__)
72 #define ATTR_READ_ONLY 0x01
73 #define ATTR_HIDDEN 0x02
74 #define ATTR_SYSTEM 0x04
75 #define ATTR_VOLUME_ID 0x08
76 #define ATTR_DIRECTORY 0x10
77 #define ATTR_ARCHIVE 0x20
78 #define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
80 #define FAT_FLAG_FREE 0x00
81 #define FAT_FLAG_DELETED 0xE5
83 uint8_t sector_buffer[512];
84 uint32_t sector_buffer_addr = 0;
85 uint8_t sector_buffer_dirty = 0;
87 uint16_t cfs_readdir_offset = 0;
92 uint32_t first_data_sector;
95 #define CLUSTER_TO_SECTOR(cluster_num) (((cluster_num - 2) * mounted.info.BPB_SecPerClus) + mounted.first_data_sector)
96 #define SECTOR_TO_CLUSTER(sector_num) (((sector_num - mounted.first_data_sector) / mounted.info.BPB_SecPerClus) + 2)
107 #ifdef FAT_COOPERATIVE
110 extern uint8_t coop_step_allowed;
111 extern uint8_t next_step_type;
119 extern QueueEntry queue[FAT_COOP_QUEUE_SIZE];
120 extern uint16_t queue_start, queue_len;
124 static uint8_t is_EOC(uint32_t fat_entry);
125 static uint32_t get_free_cluster(uint32_t start_cluster);
126 static uint16_t _get_free_cluster_16();
127 static uint16_t _get_free_cluster_32();
128 static uint32_t find_nth_cluster(uint32_t start_cluster, uint32_t n);
129 static void reset_cluster_chain(
struct dir_entry *dir_ent);
130 static void add_cluster_to_file(
int fd);
131 static uint32_t read_fat_entry(uint32_t cluster_num);
132 static void write_fat_entry(uint32_t cluster_num, uint32_t value);
133 static void calc_fat_block(uint32_t cur_cluster, uint32_t *fat_sec_num, uint32_t *ent_offset);
134 static uint8_t _make_valid_name(
const char *path, uint8_t start, uint8_t end,
char *name);
135 static void pr_reset(
struct PathResolver *rsolv);
136 static uint8_t pr_get_next_path_part(
struct PathResolver *rsolv);
137 static uint8_t pr_is_current_path_part_a_file(
struct PathResolver *rsolv);
138 static uint8_t read_sector(uint32_t sector_addr);
139 static uint8_t read_next_sector();
140 static uint8_t lookup(
const char *name,
struct dir_entry *
dir_entry, uint32_t *dir_entry_sector, uint16_t *dir_entry_offset);
141 static uint8_t get_dir_entry(
const char *path,
struct dir_entry *dir_ent, uint32_t *dir_entry_sector, uint16_t *dir_entry_offset, uint8_t create);
142 static uint8_t add_directory_entry_to_current(
struct dir_entry *dir_ent, uint32_t *dir_entry_sector, uint16_t *dir_entry_offset);
143 static void update_dir_entry(
int fd);
144 static void remove_dir_entry(uint32_t dir_entry_sector, uint16_t dir_entry_offset);
145 static uint8_t load_next_sector_of_file(
int fd, uint32_t clusters, uint8_t clus_offset, uint8_t write);
146 static void make_readable_entry(
struct dir_entry *dir,
struct cfs_dirent *dirent);
147 static uint8_t _is_file(
struct dir_entry *dir_ent);
148 static uint8_t _cfs_flags_ok(
int flags,
struct dir_entry *dir_ent);
149 static int fat_read_write(
int fd,
const void *buf,
unsigned int len,
unsigned char write);
155 is_EOC(uint32_t fat_entry)
157 if (
mounted.info.type == FAT16) {
158 if (fat_entry >= 0xFFF8) {
162 }
else if (
mounted.info.type == FAT32) {
163 if ((fat_entry & 0x0FFFFFFF) >= 0x0FFFFFF8) {
179 get_free_cluster(uint32_t start_cluster)
181 uint32_t fat_sec_num = 0;
182 uint32_t ent_offset = 0;
186 calc_fat_block(start_cluster, &fat_sec_num, &ent_offset);
191 if (read_sector(fat_sec_num) != 0) {
192 PRINTERROR(
"\nERROR: read_sector() failed!");
196 if (
mounted.info.type == FAT16) {
197 i = _get_free_cluster_16();
198 }
else if (
mounted.info.type == FAT32) {
199 i = _get_free_cluster_32();
204 ent_offset = ((fat_sec_num - 1) -
mounted.info.BPB_RsvdSecCnt) *
mounted.info.BPB_BytesPerSec + i;
205 if (
mounted.info.type == FAT16) {
207 }
else if (
mounted.info.type == FAT32) {
211 PRINTF(
"\nfat.c: get_free_cluster(start_cluster = %lu) = %lu", start_cluster, ent_offset);
216 _get_free_cluster_16()
221 for (i = 0; i < 512; i += 2) {
222 entry = (((uint16_t) sector_buffer[i]) << 8) + ((uint16_t) sector_buffer[i + 1]);
237 _get_free_cluster_32()
245 for (i = 0; i < 512; i += 4) {
246 entry = (((uint32_t) sector_buffer[i + 3]) << 24) + (((uint32_t) sector_buffer[i + 2]) << 16) + (((uint32_t) sector_buffer[i + 1]) << 8) + ((uint32_t) sector_buffer[i]);
248 if ((entry & 0x0FFFFFFF) == 0) {
259 find_nth_cluster(uint32_t start_cluster, uint32_t n)
261 uint32_t cluster = start_cluster,
264 for (i = 0; i < n; i++) {
265 cluster = read_fat_entry(cluster);
268 PRINTF(
"\nfat.c: find_nth_cluster( start_cluster = %lu, n = %lu ) = %lu", start_cluster, n, cluster);
276 reset_cluster_chain(
struct dir_entry *dir_ent)
278 uint32_t cluster = (((uint32_t) dir_ent->DIR_FstClusHI) << 16) + dir_ent->DIR_FstClusLO;
279 uint32_t next_cluster = read_fat_entry(cluster);
281 while (!is_EOC(cluster) && cluster >= 2) {
282 write_fat_entry(cluster, 0L);
283 cluster = next_cluster;
284 next_cluster = read_fat_entry(cluster);
287 write_fat_entry(cluster, 0L);
295 add_cluster_to_file(
int fd)
298 uint32_t free_cluster = get_free_cluster(0);
300 uint32_t n = cluster;
301 PRINTF(
"\nfat.c: add_cluster_to_file( fd = %d ) = void", fd);
305 write_fat_entry(free_cluster, EOC);
306 fat_file_pool[fd].dir_entry.DIR_FstClusHI = (uint16_t) (free_cluster >> 16);
307 fat_file_pool[fd].dir_entry.DIR_FstClusLO = (uint16_t) (free_cluster);
309 update_dir_entry(fd);
315 PRINTF(
"\n\tfat.c: File was empty, now has first cluster %lu added to Chain", free_cluster);
321 n = read_fat_entry(cluster);
325 write_fat_entry(cluster, free_cluster);
326 write_fat_entry(free_cluster, EOC);
328 PRINTF(
"\n\tfat.c: File was NOT empty, now has cluster %lu as %lu. cluster to Chain", free_cluster,
fat_file_pool[fd].n);
333 print_current_sector()
338 for (i = 0; i < 512; i++) {
339 printf(
"%02x", sector_buffer[i]);
340 if (((i + 1) % 2) == 0) {
343 if (((i + 1) % 32) == 0) {
350 print_cluster_chain(
int fd)
353 printf(
"\nClusterchain for fd = %d\n", fd);
355 printf(
"%lu ->", cluster);
356 }
while (!is_EOC(cluster = read_fat_entry(cluster)));
357 printf(
"%lu\n", cluster);
363 printf(
"\nFile Info for fd = %d", fd);
364 printf(
"\n\toffset = %lu",
fat_fd_pool[fd].offset);
368 printf(
"\n\t\tdir_entry_sector = %lu",
fat_file_pool[fd].dir_entry_sector);
369 printf(
"\n\t\tdir_entry_offset = %u",
fat_file_pool[fd].dir_entry_offset);
370 printf(
"\n\t\tnth_cluster = %lu",
fat_file_pool[fd].nth_cluster);
372 printf(
"\n\t\tdir_entry");
373 printf(
"\n\t\t\tDIR_Name = %c%c%c%c%c%c%c%c%c%c%c",
fat_file_pool[fd].
dir_entry.DIR_Name[0],
fat_file_pool[fd].dir_entry.DIR_Name[1],
fat_file_pool[fd].dir_entry.DIR_Name[2],
fat_file_pool[fd].dir_entry.DIR_Name[3],
fat_file_pool[fd].dir_entry.DIR_Name[4],
fat_file_pool[fd].dir_entry.DIR_Name[5],
fat_file_pool[fd].dir_entry.DIR_Name[6],
fat_file_pool[fd].dir_entry.DIR_Name[7],
fat_file_pool[fd].dir_entry.DIR_Name[8],
fat_file_pool[fd].dir_entry.DIR_Name[9],
fat_file_pool[fd].dir_entry.DIR_Name[10]);
390 printf(
"\nDirectory Entry");
391 printf(
"\n\tDIR_Name = %c%c%c%c%c%c%c%c%c%c%c", dir_entry->DIR_Name[0], dir_entry->DIR_Name[1], dir_entry->DIR_Name[2], dir_entry->DIR_Name[3], dir_entry->DIR_Name[4], dir_entry->DIR_Name[5], dir_entry->DIR_Name[6], dir_entry->DIR_Name[7], dir_entry->DIR_Name[8], dir_entry->DIR_Name[9], dir_entry->DIR_Name[10]);
392 printf(
"\n\tDIR_Attr = %x", dir_entry->DIR_Attr);
393 printf(
"\n\tDIR_NTRes = %x", dir_entry->DIR_NTRes);
394 printf(
"\n\tCrtTimeTenth = %x", dir_entry->CrtTimeTenth);
395 printf(
"\n\tDIR_CrtTime = %x", dir_entry->
DIR_CrtTime);
396 printf(
"\n\tDIR_CrtDate = %x", dir_entry->
DIR_CrtDate);
398 printf(
"\n\tDIR_FstClusHI = %x", dir_entry->DIR_FstClusHI);
399 printf(
"\n\tDIR_WrtTime = %x", dir_entry->
DIR_WrtTime);
400 printf(
"\n\tDIR_WrtDate = %x", dir_entry->
DIR_WrtDate);
401 printf(
"\n\tDIR_FstClusLO = %x", dir_entry->DIR_FstClusLO);
402 printf(
"\n\tDIR_FileSize = %lu Bytes", dir_entry->
DIR_FileSize);
439 read_fat_entry(uint32_t cluster_num)
441 uint32_t fat_sec_num = 0,
444 calc_fat_block(cluster_num, &fat_sec_num, &ent_offset);
445 if (read_sector(fat_sec_num) != 0) {
446 PRINTERROR(
"\nError while reading FAT entry for cluster %ld", cluster_num);
450 if (
mounted.info.type == FAT16) {
451 PRINTF(
"\nfat.c: read_fat_entry( cluster_num = %lu ) = %lu", cluster_num, (uint32_t) (((uint16_t) sector_buffer[ent_offset + 1]) << 8) + ((uint16_t) sector_buffer[ent_offset]));
452 return (uint32_t) (((uint16_t) sector_buffer[ent_offset + 1]) << 8) + ((uint16_t) sector_buffer[ent_offset]);
453 }
else if (
mounted.info.type == FAT32) {
454 PRINTF(
"\nfat.c: read_fat_entry( cluster_num = %lu ) = %lu", cluster_num,
455 (((((uint32_t) sector_buffer[ent_offset + 3]) << 24) +
456 (((uint32_t) sector_buffer[ent_offset + 2]) << 16) +
457 (((uint32_t) sector_buffer[ent_offset + 1]) << 8) +
458 ((uint32_t) sector_buffer[ent_offset + 0]))
461 return (((((uint32_t) sector_buffer[ent_offset + 3]) << 24) +
462 (((uint32_t) sector_buffer[ent_offset + 2]) << 16) +
463 (((uint32_t) sector_buffer[ent_offset + 1]) << 8) +
464 ((uint32_t) sector_buffer[ent_offset + 0]))
468 PRINTF(
"\nfat.c: read_fat_entry( cluster_num = %lu ) = EOC", cluster_num);
475 write_fat_entry(uint32_t cluster_num, uint32_t value)
477 uint32_t fat_sec_num = 0,
480 calc_fat_block(cluster_num, &fat_sec_num, &ent_offset);
481 read_sector(fat_sec_num);
482 PRINTF(
"\nfat.c: write_fat_entry( cluster_num = %lu, value = %lu ) = void", cluster_num, value);
485 if (
mounted.info.type == FAT16) {
486 sector_buffer[ent_offset + 1] = (uint8_t) (value >> 8);
487 sector_buffer[ent_offset] = (uint8_t) (value);
488 }
else if (
mounted.info.type == FAT32) {
489 sector_buffer[ent_offset + 3] = ((uint8_t) (value >> 24) & 0x0FFF) + (0xF000 & sector_buffer[ent_offset + 3]);
490 sector_buffer[ent_offset + 2] = (uint8_t) (value >> 16);
491 sector_buffer[ent_offset + 1] = (uint8_t) (value >> 8);
492 sector_buffer[ent_offset] = (uint8_t) (value);
495 sector_buffer_dirty = 1;
503 calc_fat_block(uint32_t cur_cluster, uint32_t *fat_sec_num, uint32_t *ent_offset)
505 uint32_t N = cur_cluster;
507 if (
mounted.info.type == FAT16) {
509 }
else if (
mounted.info.type == FAT32) {
513 *fat_sec_num =
mounted.info.BPB_RsvdSecCnt + (*ent_offset /
mounted.info.BPB_BytesPerSec);
514 *ent_offset = *ent_offset %
mounted.info.BPB_BytesPerSec;
515 PRINTF(
"\nfat.c: calc_fat_block( cur_cluster = %lu, *fat_sec_num = %lu, *ent_offset = %lu ) = void", cur_cluster, *fat_sec_num, *ent_offset);
520 _make_valid_name(
const char *path, uint8_t start, uint8_t end,
char *name)
526 memset(name, 0x20, 11);
529 for (i = 0, idx = 0; i < end - start; ++i, ++idx) {
532 PRINTF(
"\nfat.c: _make_valid_name( path = %s, start = %u, end = %u, name = %s ) = 2", path, start, end, name);
537 if (path[start + i] ==
'.') {
539 PRINTF(
"\nfat.c: _make_valid_name( path = %s, start = %u, end = %u, name = %s ) = 3", path, start, end, name);
548 if (!dot_found && idx > 7) {
549 PRINTF(
"\nfat.c: _make_valid_name( path = %s, start = %u, end = %u, name = %s ) = 4", path, start, end, name);
553 name[idx] = toupper(path[start + i]);
556 PRINTF(
"\nfat.c: _make_valid_name( path = %s, start = %u, end = %u, name = %s ) = 0", path, start, end, name);
561 pr_reset(
struct PathResolver *rsolv)
566 memset(rsolv->name,
'\0', 11);
570 pr_get_next_path_part(
struct PathResolver *rsolv)
574 if (rsolv->path ==
NULL) {
578 rsolv->start = rsolv->end;
580 if (rsolv->path[rsolv->start] ==
'/') {
584 for (i = rsolv->start; rsolv->path[i] !=
'\0'; i++) {
585 if (rsolv->path[i] !=
'/') {
589 if (rsolv->path[rsolv->end] ==
'/' || rsolv->path[rsolv->end] ==
'\0') {
590 return _make_valid_name(rsolv->path, rsolv->start, rsolv->end, rsolv->name);
598 pr_is_current_path_part_a_file(
struct PathResolver *rsolv)
600 if (rsolv->path[rsolv->end] ==
'/') {
602 }
else if (rsolv->path[rsolv->end] ==
'\0') {
616 if (!sector_buffer_dirty) {
620 #ifdef FAT_COOPERATIVE
621 if (!coop_step_allowed) {
622 next_step_type = WRITE;
625 coop_step_allowed = 0;
629 PRINTF(
"\nfat.c: fat_flush(): Flushing sector %lu", sector_buffer_addr);
631 PRINTERROR(
"\nfat.c: fat_flush(): DiskIO-Error occured");
634 sector_buffer_dirty = 0;
643 read_sector(uint32_t sector_addr)
645 if (sector_buffer_addr == sector_addr && sector_addr != 0) {
646 PRINTF(
"\nfat.c: fat_read_sector( sector_addr = 0x%lX ) = 0", sector_addr);
652 sector_buffer_addr = sector_addr;
654 #ifdef FAT_COOPERATIVE
655 if (!coop_step_allowed) {
656 next_step_type = READ;
659 coop_step_allowed = 0;
664 PRINTERROR(
"\nfat.c: Error while reading sector 0x%lX", sector_addr);
665 sector_buffer_addr = 0;
669 PRINTF(
"\nfat.c: read_sector( sector_addr = 0x%lX ) = 0", sector_addr);
681 PRINTF(
"\nread_next_sector()");
685 uint32_t save_sbuff_addr = sector_buffer_addr;
687 if ((sector_buffer_addr -
mounted.first_data_sector + 1) %
mounted.info.BPB_SecPerClus == 0) {
688 PRINTDEBUG(
"\nCluster end, trying to load next");
690 uint32_t entry = read_fat_entry(SECTOR_TO_CLUSTER(sector_buffer_addr));
693 PRINTDEBUG(
"\nis_EOC! (%ld)", sector_buffer_addr);
695 read_sector(save_sbuff_addr);
700 return read_sector(CLUSTER_TO_SECTOR(entry));
703 return read_sector(sector_buffer_addr + 1);
727 parse_bootsector(uint8_t *buffer,
struct FAT_Info *info)
732 info->BPB_SecPerClus = buffer[13];
733 info->BPB_RsvdSecCnt = buffer[14] + (((uint16_t) buffer[15]) << 8);
734 info->BPB_NumFATs = buffer[16];
735 info->BPB_RootEntCnt = buffer[17] + (((uint16_t) buffer[18]) << 8);
736 info->BPB_TotSec = buffer[19] + (((uint16_t) buffer[20]) << 8);
737 if (info->BPB_TotSec == 0) {
738 info->BPB_TotSec = buffer[32] +
739 (((uint32_t) buffer[33]) << 8) +
740 (((uint32_t) buffer[34]) << 16) +
741 (((uint32_t) buffer[35]) << 24);
744 info->BPB_Media = buffer[21];
745 info->BPB_FATSz = buffer[22] + (((uint16_t) buffer[23]) << 8);
746 if (info->BPB_FATSz == 0) {
747 info->BPB_FATSz = buffer[36] +
748 (((uint32_t) buffer[37]) << 8) +
749 (((uint32_t) buffer[38]) << 16) +
750 (((uint32_t) buffer[39]) << 24);
753 info->BPB_RootClus = buffer[44] +
754 (((uint32_t) buffer[45]) << 8) +
755 (((uint32_t) buffer[46]) << 16) +
756 (((uint32_t) buffer[47]) << 24);
759 if ((buffer[54] == 'F') && (buffer[55] == 'A') && (buffer[56] == 'T')) {
761 if (buffer[58] ==
'2') {
763 }
else if (buffer[58] ==
'6') {
766 info->type = FAT_INVALID;
769 }
else if ((buffer[82] ==
'F') && (buffer[83] ==
'A') && (buffer[84] ==
'T')) {
772 info->type = FAT_INVALID;
783 if (info->BPB_BytesPerSec * info->BPB_SecPerClus > 32 * ((uint32_t) 1024)) {
787 if (info->BPB_NumFATs > 2) {
791 if (info->BPB_TotSec == 0) {
795 if (info->BPB_FATSz == 0) {
799 if (buffer[510] != 0x55 || buffer[511] != 0xaa) {
806 #define DIR_ENTRY_SIZE 32
810 uint32_t RootDirSectors = 0;
820 if (parse_bootsector(sector_buffer, &(
mounted.info)) != 0) {
836 RootDirSectors = ((
mounted.info.BPB_RootEntCnt * DIR_ENTRY_SIZE) + (
mounted.info.BPB_BytesPerSec - 1)) /
mounted.info.BPB_BytesPerSec;
856 for (i = 0; i < FAT_FD_POOL_SIZE; i++) {
862 sector_buffer_addr = 0;
873 PRINTF(
"\nfat.c: cfs_open( name = %s, flags = %x) = ?", name, flags);
875 #ifndef FAT_COOPERATIVE
876 for (i = 0; i < FAT_FD_POOL_SIZE; i++) {
885 PRINTF(
"\nfat.c: cfs_open(): No free FileDescriptors available!");
889 fd = queue[queue_start].ret_value;
899 PRINTF(
"\nfat.c: cfs_open(): Could not fetch the directory entry!");
903 if (!_is_file(&dir_ent)) {
904 PRINTF(
"\nfat.c: cfs_open(): Directory entry is not a file!");
908 if (!_cfs_flags_ok(flags, &dir_ent)) {
909 PRINTF(
"\nfat.c: cfs_open(): Invalid flags!!");
913 fat_file_pool[fd].cluster = dir_ent.DIR_FstClusLO + (((uint32_t) dir_ent.DIR_FstClusHI) << 16);
923 if (flags & CFS_APPEND) {
924 PRINTF(
"\nfat.c: cfs_open(): Seek to end of file (APPEND)!");
929 PRINTF(
"\nfat.c: cfs_open( name = %s, flags = %x) = %d", name, flags, fd);
936 if (fd < 0 || fd >= FAT_FD_POOL_SIZE) {
937 PRINTERROR(
"\nfat.c: cfs_close: Invalid fd");
942 PRINTERROR(
"\nfat.c: cfs_close: file not found\n");
946 update_dir_entry(fd);
952 cfs_read(
int fd,
void *buf,
unsigned int len)
960 return fat_read_write(fd, buf, len, 0);
964 cfs_write(
int fd,
const void *buf,
unsigned int len)
966 return fat_read_write(fd, buf, len, 1);
970 fat_read_write(
int fd,
const void *buf,
unsigned int len,
unsigned char write)
979 uint8_t *buffer = (uint8_t *) buf;
986 if (size_left < len) {
992 PRINTDEBUG(
"Empty cluster or zero file size");
997 while (load_next_sector_of_file(fd, clusters, clus_offset, write) == 0) {
998 PRINTF(
"\nfat.c: cfs_write(): Writing in sector %lu", sector_buffer_addr);
999 for (i = offset; i <
mounted.info.BPB_BytesPerSec && j < len; i++, j++,
fat_fd_pool[fd].offset++) {
1001 #ifndef FAT_COOPERATIVE
1002 sector_buffer[i] = buffer[j];
1004 sector_buffer[i] = get_item_from_buffer(buffer, j);
1013 buffer[j] = sector_buffer[i];
1018 sector_buffer_dirty = 1;
1022 clus_offset = (clus_offset + 1) %
mounted.info.BPB_SecPerClus;
1023 if (clus_offset == 0) {
1038 if (fd < 0 || fd >= FAT_FD_POOL_SIZE) {
1074 if (!get_dir_entry(name, &dir_ent, §or, &offset, 0)) {
1078 if (_is_file(&dir_ent)) {
1079 reset_cluster_chain(&dir_ent);
1080 remove_dir_entry(sector, offset);
1094 uint32_t dir_cluster = get_dir_entry(name, &dir_ent, §or, &offset, 0);
1096 cfs_readdir_offset = 0;
1098 if (dir_cluster == 0) {
1102 memcpy(dirp, &dir_ent,
sizeof (
struct dir_entry));
1113 uint32_t dir_off = cfs_readdir_offset * 32;
1114 uint16_t cluster_num = dir_off /
mounted.info.BPB_SecPerClus;
1117 cluster = find_nth_cluster((((uint32_t) dir_ent->DIR_FstClusHI) << 16) + dir_ent->DIR_FstClusLO, (uint32_t) cluster_num);
1122 if (read_sector(CLUSTER_TO_SECTOR(cluster) + dir_off /
mounted.info.BPB_BytesPerSec) != 0) {
1126 memcpy(&entry, &(sector_buffer[dir_off %
mounted.info.BPB_BytesPerSec]), sizeof (
struct dir_entry));
1129 make_readable_entry(&entry, dirent);
1131 cfs_readdir_offset++;
1138 cfs_readdir_offset = 0;
1153 lookup(
const char *name,
struct dir_entry *
dir_entry, uint32_t *dir_entry_sector, uint16_t *dir_entry_offset)
1156 PRINTF(
"\nfat.c: BEGIN lookup( name = %c%c%c%c%c%c%c%c%c%c%c, dir_entry = %p, *dir_entry_sector = %lu, *dir_entry_offset = %u) = ?", name[0], name[1], name[2], name[3], name[4], name[5], name[6], name[7], name[8], name[9], name[10], dir_entry, *dir_entry_sector, *dir_entry_offset);
1159 for (i = 0; i < 512; i += 32) {
1160 PRINTF(
"\nfat.c: lookup(): name = %c%c%c%c%c%c%c%c%c%c%c", name[0], name[1], name[2], name[3], name[4], name[5], name[6], name[7], name[8], name[9], name[10]);
1161 PRINTF(
"\nfat.c: lookup(): sec_buf = %c%c%c%c%c%c%c%c%c%c%c", sector_buffer[i + 0], sector_buffer[i + 1], sector_buffer[i + 2], sector_buffer[i + 3], sector_buffer[i + 4], sector_buffer[i + 5], sector_buffer[i + 6], sector_buffer[i + 7], sector_buffer[i + 8], sector_buffer[i + 9], sector_buffer[i + 10]);
1162 if (memcmp(name, &(sector_buffer[i]), 11) == 0) {
1163 memcpy(dir_entry, &(sector_buffer[i]),
sizeof (
struct dir_entry));
1164 *dir_entry_sector = sector_buffer_addr;
1165 *dir_entry_offset = i;
1166 PRINTF(
"\nfat.c: END lookup( name = %c%c%c%c%c%c%c%c%c%c%c, dir_entry = %p, *dir_entry_sector = %lu, *dir_entry_offset = %u) = 0", name[0], name[1], name[2], name[3], name[4], name[5], name[6], name[7], name[8], name[9], name[10], dir_entry, *dir_entry_sector, *dir_entry_offset);
1171 if (sector_buffer[i] == FAT_FLAG_FREE) {
1172 PRINTF(
"\nfat.c: lookup(): No more directory entries");
1173 PRINTF(
"\nfat.c: END lookup( name = %c%c%c%c%c%c%c%c%c%c%c, dir_entry = %p, *dir_entry_sector = %lu, *dir_entry_offset = %u) = 1", name[0], name[1], name[2], name[3], name[4], name[5], name[6], name[7], name[8], name[9], name[10], dir_entry, *dir_entry_sector, *dir_entry_offset);
1180 if ((fns = read_next_sector()) != 0) {
1181 PRINTF(
"\nfat.c: END lookup( name = %c%c%c%c%c%c%c%c%c%c%c, dir_entry = %p, *dir_entry_sector = %lu, *dir_entry_offset = %u) = 2", name[0], name[1], name[2], name[3], name[4], name[5], name[6], name[7], name[8], name[9], name[10], dir_entry, *dir_entry_sector, *dir_entry_offset);
1186 PRINTF(
"\nfat.c: END lookup( name = %c%c%c%c%c%c%c%c%c%c%c, dir_entry = %p, *dir_entry_sector = %lu, *dir_entry_offset = %u) = 0", name[0], name[1], name[2], name[3], name[4], name[5], name[6], name[7], name[8], name[9], name[10], dir_entry, *dir_entry_sector, *dir_entry_offset);
1200 get_dir_entry(
const char *path,
struct dir_entry *dir_ent, uint32_t *dir_entry_sector, uint16_t *dir_entry_offset, uint8_t create)
1202 uint32_t first_root_dir_sec_num = 0;
1203 uint32_t file_sector_num = 0;
1205 struct PathResolver pr;
1206 PRINTF(
"\nfat.c: get_dir_entry( path = %s, dir_ent = %p, *dir_entry_sector = %lu, *dir_entry_offset = %u, create = %u ) = ?", path, dir_ent, *dir_entry_sector, *dir_entry_offset, create);
1211 if (
mounted.info.type == FAT16) {
1213 first_root_dir_sec_num =
mounted.info.BPB_RsvdSecCnt + (
mounted.info.BPB_NumFATs *
mounted.info.BPB_FATSz);
1214 }
else if (
mounted.info.type == FAT32) {
1216 first_root_dir_sec_num = CLUSTER_TO_SECTOR(
mounted.info.BPB_RootClus);
1218 PRINTF(
"\nfat.c: get_dir_entry(): first_root_dir_sec_num = %lu", first_root_dir_sec_num);
1220 file_sector_num = first_root_dir_sec_num;
1221 for (i = 0; pr_get_next_path_part(&pr) == 0 && i < 255; i++) {
1222 read_sector(file_sector_num);
1223 if (lookup(pr.name, dir_ent, dir_entry_sector, dir_entry_offset) != 0) {
1224 PRINTF(
"\nfat.c: get_dir_entry(): Current path part doesn't exist!");
1225 if (pr_is_current_path_part_a_file(&pr) && create) {
1226 PRINTF(
"\nfat.c: get_dir_entry(): Current path part describes a file and it should be created!");
1227 memset(dir_ent, 0,
sizeof (
struct dir_entry));
1228 memcpy(dir_ent->DIR_Name, pr.name, 11);
1229 dir_ent->DIR_Attr = 0;
1230 return add_directory_entry_to_current(dir_ent, dir_entry_sector, dir_entry_offset);
1234 file_sector_num = CLUSTER_TO_SECTOR(dir_ent->DIR_FstClusLO + (((uint32_t) dir_ent->DIR_FstClusHI) << 16));
1235 PRINTF(
"\nfat.c: get_dir_entry(): file_sector_num = %lu", file_sector_num);
1238 if (file_sector_num == first_root_dir_sec_num) {
1253 add_directory_entry_to_current(
struct dir_entry *dir_ent, uint32_t *dir_entry_sector, uint16_t *dir_entry_offset)
1261 PRINTF(
"\nfat.c: add_directory_entry_to_current( dir_ent = %p, *dir_entry_sector = %lu, *dir_entry_offset = %u ) = ?", dir_ent, *dir_entry_sector, *dir_entry_offset);
1264 for (i = 0; i < 512; i += 32) {
1265 if (sector_buffer[i] == FAT_FLAG_FREE || sector_buffer[i] == FAT_FLAG_DELETED) {
1266 memcpy(&(sector_buffer[i]), dir_ent,
sizeof (
struct dir_entry));
1267 sector_buffer_dirty = 1;
1268 *dir_entry_sector = sector_buffer_addr;
1269 *dir_entry_offset = i;
1270 PRINTF(
"\nfat.c: add_directory_entry_to_current(): Found empty directory entry! *dir_entry_sector = %lu, *dir_entry_offset = %u", *dir_entry_sector, *dir_entry_offset);
1276 PRINTF(
"\nfat.c: add_directory_entry_to_current(): No free entry in current sector (sector_buffer_addr = %lu) reading next sector!", sector_buffer_addr);
1277 if ((ret = read_next_sector()) != 0) {
1280 uint32_t last_sector = sector_buffer_addr;
1281 uint32_t free_cluster = get_free_cluster(SECTOR_TO_CLUSTER(sector_buffer_addr));
1282 PRINTF(
"\nfat.c: add_directory_entry_to_current(): The directory cluster chain is too short, we need to add another cluster!");
1284 write_fat_entry(SECTOR_TO_CLUSTER(last_sector), free_cluster);
1285 write_fat_entry(free_cluster, EOC);
1286 PRINTF(
"\nfat.c: add_directory_entry_to_current(): cluster %lu added to chain of sector_buffer_addr cluster %lu", free_cluster, SECTOR_TO_CLUSTER(sector_buffer_addr));
1290 uint32_t first_free_sector = CLUSTER_TO_SECTOR(free_cluster);
1291 memset(sector_buffer, 0x00, 512);
1292 for (i = 0; i <
mounted.info.BPB_SecPerClus; i++) {
1293 sector_buffer_addr = first_free_sector + i;
1294 sector_buffer_dirty = 1;
1298 if (read_sector(CLUSTER_TO_SECTOR(free_cluster)) == 0) {
1299 memcpy(&(sector_buffer[0]), dir_ent,
sizeof (
struct dir_entry));
1300 sector_buffer_dirty = 1;
1301 *dir_entry_sector = sector_buffer_addr;
1302 *dir_entry_offset = 0;
1303 PRINTF(
"\nfat.c: add_directory_entry_to_current(): read of the newly added cluster successful! *dir_entry_sector = %lu, *dir_entry_offset = %u", *dir_entry_sector, *dir_entry_offset);
1315 update_dir_entry(
int fd)
1317 PRINTF(
"\nfat.c: update_dir_entry( fd = %d ) = void ", fd);
1319 PRINTERROR(
"\nfat.c: update_dir_entry(): error reading the sector containing the directory entry");
1324 sector_buffer_dirty = 1;
1328 remove_dir_entry(uint32_t dir_entry_sector, uint16_t dir_entry_offset)
1330 PRINTF(
"\nfat.c: remove_dir_entry( dir_entry_sector = %lu, dir_entry_offset = %u ) = void ", dir_entry_sector, dir_entry_offset);
1331 if (read_sector(dir_entry_sector) != 0) {
1332 PRINTERROR(
"\nfat.c: remove_dir_entry(): error reading the sector containing the directory entry");
1336 memset(&(sector_buffer[dir_entry_offset]), 0,
sizeof (
struct dir_entry));
1337 sector_buffer[dir_entry_offset] = FAT_FLAG_DELETED;
1338 sector_buffer_dirty = 1;
1343 load_next_sector_of_file(
int fd, uint32_t clusters, uint8_t clus_offset, uint8_t write)
1345 uint32_t cluster = 0;
1346 PRINTF(
"\nfat.c: load_next_sector_of_file( fd = %d, clusters = %lu, clus_offset = %u, write = %u ) = ?", fd, clusters, clus_offset, write);
1350 PRINTF(
"\nfat.c: load_next_sector_of_file(): we know nth cluster already");
1354 PRINTF(
"\nfat.c: load_next_sector_of_file(): we need the cluster n and are at n-1");
1358 PRINTF(
"\nfat.c: load_next_sector_of_file(): We are somewhere else, need to iterate the chain until nth cluster");
1359 cluster = find_nth_cluster(
fat_file_pool[fd].cluster, clusters);
1361 PRINTF(
"\nfat.c: load_next_sector_of_file(): fat_file_pool[%d].nth_cluster = %lu, fat_file_pool[%d].n = %lu", fd,
fat_file_pool[fd].nth_cluster, fd,
fat_file_pool[fd].n);
1364 if (cluster == 0 || is_EOC(cluster)) {
1365 PRINTF(
"\nfat.c: load_next_sector_of_file(): Either file is empty or current cluster is EOC!");
1367 PRINTF(
"\nfat.c: load_next_sector_of_file(): write flag enabled! adding cluster to file!");
1368 add_cluster_to_file(fd);
1379 return read_sector(CLUSTER_TO_SECTOR(cluster) + clus_offset);
1386 if (fd < 0 || fd >= FAT_FD_POOL_SIZE) {
1408 for (fat_block = 0; fat_block <
mounted.info.BPB_FATSz; fat_block++) {
1410 for (fat_number = 2; fat_number <=
mounted.info.BPB_NumFATs; fat_number++) {
1418 make_readable_entry(
struct dir_entry *dir,
struct cfs_dirent *dirent)
1422 for (i = 0, j = 0; i < 11; i++) {
1423 if (dir->DIR_Name[i] !=
' ') {
1424 dirent->name[j] = dir->DIR_Name[i];
1429 dirent->name[j] =
'.';
1451 for (i = 0; i < 32; ++i) {
1452 if (test == value) {
1470 uint32_t po2 = ((uint32_t) 1) << 31;
1472 while (value < po2) {
1480 _is_file(
struct dir_entry *dir_ent)
1482 if (dir_ent->DIR_Attr & ATTR_DIRECTORY) {
1486 if (dir_ent->DIR_Attr & ATTR_VOLUME_ID) {
1494 _cfs_flags_ok(
int flags,
struct dir_entry *dir_ent)
1496 if (((flags &
CFS_APPEND) || (flags &
CFS_WRITE)) && (dir_ent->DIR_Attr & ATTR_READ_ONLY)) {