?? fatfs_supp.c
字號:
// find_and_append_cluster()// Finds a free cluster on disk and appends it to the given cluster. // New cluster is marked as LAST. static intfind_and_append_cluster(fatfs_disk_t *disk, cyg_uint32 cluster, cyg_uint32 *new_cluster, cluster_opts_t opts){ cyg_uint32 free_cluster; int err; printf("cluster=%d", cluster); err = find_next_free_cluster(disk, cluster, &free_cluster, opts | CO_MARK_LAST); if (err != ENOERR) return err; printf( "free_cluster=%d", free_cluster); // Link clusters err = link_cluster(disk, cluster, free_cluster); if (err != ENOERR) return err; *new_cluster = free_cluster; printf( "new_cluster=%d", free_cluster); return ENOERR;}// -------------------------------------------------------------------------// find_nth_cluster0()// Finds nth cluster in chain (ie nth cluster of file).// Searching from given position. static intfind_nth_cluster0(fatfs_disk_t *disk, fatfs_data_pos_t *dpos, cyg_uint32 n, fatfs_tcache_t *tcache){ cyg_uint32 cluster, cluster_snum; int err = ENOERR; // Trivial case check if (dpos->cluster_snum == n) return ENOERR; // First look in cache if (NULL != tcache) { cyg_uint32 c, ln; if (fatfs_tcache_get(disk, tcache, n, &c)) { // Cluster in cache dpos->cluster = c; dpos->cluster_snum = n; printf( "cluster=%d cluster_snum=%d in cache", c, n); return ENOERR; } else if (fatfs_tcache_get_last(disk, tcache, &ln, &c)) { // Cluster not in cache - get last // in cache and search from there dpos->cluster = c; dpos->cluster_snum = ln; printf( "cluster=%d cluster_snum=%d last in cache", c, ln); } else { // Empty cache - put first cluster in fatfs_tcache_set(disk, tcache, dpos->cluster_snum, dpos->cluster); } } cluster = dpos->cluster; cluster_snum = dpos->cluster_snum; printf( "cluster=%d cluster_snum=%d n=%d n_to_search=%d", cluster, cluster_snum, n, n-cluster_snum); // Adjust t while (n > 0) { cyg_uint32 tentry; err = read_tentry(disk, cluster, &tentry); if (err != ENOERR) return err; switch (get_tentry_type(disk, tentry)) { case TENTRY_REGULAR: break; case TENTRY_LAST: // Oops early last cluster printf( "chain end n=%d", n); err = EEOF; // File has less clusters than given n // this err should be caught by the // calling function goto out; default: // Inconsistant FAT table state !!! printf("!!! inconsistant FAT tentry=%x n=%d", tentry, n); err = EIO; goto out; } cluster = get_tentry_next_cluster(disk, tentry); cluster_snum++; if (NULL != tcache) fatfs_tcache_set(disk, tcache, cluster_snum, cluster); n--; } out: dpos->cluster = cluster; dpos->cluster_snum = cluster_snum; printf( "nth cluster=%d cluster_snum=%d", cluster, cluster_snum); return err;}// -------------------------------------------------------------------------// find_nth_cluster()// Finds nth cluster in chain (ie nth cluster of file) searching // from given position. If the chain ends one cluster before the // given nth cluster and the CO_EXTEND is specifide, than the // chain is extended by one cluster. static intfind_nth_cluster(fatfs_disk_t *disk, fatfs_data_pos_t *dpos, cyg_uint32 n, fatfs_tcache_t *tcache, cluster_opts_t opts){ int err; // Find nth cluster err = find_nth_cluster0(disk, dpos, n, tcache); // EEOF meens that the cluster chain ended early if ((err != EEOF) || !(opts & CO_EXTEND)) return err; printf( "cluster_snum=%d n=%d", dpos->cluster_snum, n); // Check if one cluster short if (dpos->cluster_snum == (n - 1)) { // Extend the chain for one cluster cyg_uint32 new_cluster; // Append new cluster to the end of chain err = find_and_append_cluster(disk, dpos->cluster, &new_cluster, opts); if (err != ENOERR) return err; // Update position dpos->cluster = new_cluster; dpos->cluster_snum++; dpos->cluster_pos = 0; printf( "cluster=%d cluster_snum=%d", dpos->cluster, dpos->cluster_snum); // Update cache if (NULL != tcache) fatfs_tcache_set(disk, tcache, dpos->cluster_snum, dpos->cluster); } return err;}// -------------------------------------------------------------------------// get_next_cluster()// Gets next cluster in chain (ie next cluster of file).// If CO_EXTEND is specified and the current cluster is last in // chain then the chain is extended by one cluster.static intget_next_cluster(fatfs_disk_t *disk, fatfs_data_pos_t *dpos, fatfs_tcache_t *tcache, cluster_opts_t opts){ int err; printf( "cluster=%d cluster_snum=%d", dpos->cluster, dpos->cluster_snum); err = find_nth_cluster(disk, dpos, dpos->cluster_snum + 1, tcache, opts); if (err != ENOERR) return err; // Update position dpos->cluster_pos = 0; printf( "cluster=%d cluster_snum=%d", dpos->cluster, dpos->cluster_snum); return ENOERR;}// -------------------------------------------------------------------------// get_data_position_from_off()// Gets data position from given file offset.// If CO_EXTEND is specified the file is extended if // one cluster too short. static int get_data_position_from_off(fatfs_disk_t *disk, cyg_uint32 first_cluster, cyg_uint32 offset, fatfs_data_pos_t *dpos, fatfs_tcache_t *tcache, cluster_opts_t opts){ cyg_uint32 n; int err; // Position inside the cluster dpos->cluster_pos = offset & (disk->cluster_size - 1); // Cluster seq number to be searched for n = offset >> disk->cluster_size_log2; // Start searching from first cluster dpos->cluster = first_cluster; dpos->cluster_snum = 0; printf( "off=%d first_cluster=%d cluster_pos=%d n=%d\n", offset, first_cluster, dpos->cluster_pos, n); err = find_nth_cluster(disk, dpos, n, tcache, opts); // Err could be EEOF wich means that the given // offset if out of given file (cluster chain) return err;}// -------------------------------------------------------------------------// free_cluster_chain()// Marks all clusters FREE from given cluster to the last cluster in chain.static intfree_cluster_chain(fatfs_disk_t *disk, cyg_uint32 start_cluster){ cyg_uint32 c, next_c, tentry; bool last; int err; printf( "start_cluster=%d", start_cluster); c = next_c = start_cluster; last = false; while (!last) { err = read_tentry(disk, c, &tentry); if (err != ENOERR) return err; switch (get_tentry_type(disk, tentry)) { case TENTRY_LAST: // Last cluster in chain last = true; break; case TENTRY_REGULAR: // Get next cluster in chain next_c = get_tentry_next_cluster(disk, tentry); break; default: printf( "!!! inconsistant FAT tentry=%x c=%d", tentry, c); return EIO; } // Set the current tentry to FREE set_tentry_type(disk, &tentry, TENTRY_FREE); err = write_tentry(disk, c, &tentry); if (err != ENOERR) return err; // Next cluster in chain c = next_c; } printf( "last_cluster=%d", c); return ENOERR;}//==========================================================================// FAT dir entry functions // -------------------------------------------------------------------------// print_dentry()// Prints FAT directory entry. #if TDEstatic voidprint_dentry(fat_dir_entry_t* fde){ if (DENTRY_IS_DELETED(fde)) diag_printf("FAT: FDE name: '?%.7s'\n", &fde->name[1]); else diag_printf("FAT: FDE name: '%.8s'\n", fde->name); diag_printf("FAT: FDE ext: '%.3s'\n", fde->ext); diag_printf("FAT: FDE attr: %c%c%c%c%c%c\n", (DENTRY_IS_RDONLY(fde) ? 'R' : '-'), (DENTRY_IS_HIDDEN(fde) ? 'H' : '-'), (DENTRY_IS_SYSTEM(fde) ? 'S' : '-'), (DENTRY_IS_VOLUME(fde) ? 'V' : '-'), (DENTRY_IS_DIR(fde) ? 'D' : '-'), (DENTRY_IS_ARCHIVE(fde) ? 'A' : '-')); diag_printf("FAT: FDE crt time: %u\n", fde->crt_time); diag_printf("FAT: FDE crt date: %u\n", fde->crt_date); diag_printf("FAT: FDE acc date: %u\n", fde->acc_date); diag_printf("FAT: FDE wrt time: %u\n", fde->wrt_time); diag_printf("FAT: FDE wrt date: %u\n", fde->wrt_date); diag_printf("FAT: FDE cluster: %u\n", fde->cluster); diag_printf("FAT: FDE size: %u\n", fde->size);}#endif // TDE// -------------------------------------------------------------------------// read_dentry()// Reads dir entry from disk. // If cluster is 0 reads from root dir. static intread_dentry(fatfs_disk_t *disk, fatfs_data_pos_t *dpos, fat_dir_entry_t *fde){ unsigned char data[DENTRY_SIZE]; cyg_uint32 apos; int len, err; // Check if we are reading the root directory if (0 == dpos->cluster) apos = disk->fat_root_dir_pos + dpos->cluster_pos; else apos = get_data_disk_apos(disk, dpos->cluster, dpos->cluster_pos); printf( "cluster=%d pos=%d apos=%d", dpos->cluster, dpos->cluster_pos, apos); len = DENTRY_SIZE; err = ReadBlock( (void*)data, &len, 0, apos); if (err != ENOERR) return err; GET_BYTES(data, fde->name, 8, 0x00); GET_BYTES(data, fde->ext, 3, 0x08); GET_BYTE(data, fde->attr, 0x0B); GET_BYTE(data, fde->nt_reserved, 0x0C); GET_BYTE(data, fde->crt_sec_100, 0x0D); GET_WORD(data, fde->crt_time, 0x0E); GET_WORD(data, fde->crt_date, 0x10); GET_WORD(data, fde->acc_date, 0x12); GET_WORD(data, fde->cluster_HI, 0x14); GET_WORD(data, fde->wrt_time, 0x16); GET_WORD(data, fde->wrt_date, 0x18); GET_WORD(data, fde->cluster, 0x1A); GET_DWORD(data, fde->size, 0x1C); // Zero terminate strings fde->name[8] = '\0'; fde->ext[3] = '\0'; // Store position fde->pos = *dpos; #if TDE print_dentry(fde);#endif return ENOERR;}// -------------------------------------------------------------------------// write_dentry()// Writes dir entry to disk. // If cluster is 0 writes to root dir. static intwrite_dentry(fatfs_disk_t *disk, fatfs_data_pos_t *dpos, fat_dir_entry_t *fde){ unsigned char data[DENTRY_SIZE]; cyg_uint32 apos; int len, err; // Check if we are writting to the root directory if (0 == dpos->cluster) apos = disk->fat_root_dir_pos + dpos->cluster_pos; else apos = get_data_disk_apos(disk, dpos->cluster, dpos->cluster_pos); printf( "cluster=%d pos=%d apos=%d", dpos->cluster, dpos->cluster_pos, apos); SET_BYTES(data, fde->name, 8, 0x00); SET_BYTES(data, fde->ext, 3, 0x08); SET_BYTE(data, fde->attr, 0x0B); SET_BYTE(data, fde->nt_reserved, 0x0C); SET_BYTE(data, fde->crt_sec_100, 0x0D); SET_WORD(data, fde->crt_time, 0x0E); SET_WORD(data, fde->crt_date, 0x10); SET_WORD(data, fde->acc_date, 0x12); SET_WORD(data, fde->cluster_HI, 0x14); SET_WORD(data, fde->wrt_time, 0x16); SET_WORD(data, fde->wrt_date, 0x18); SET_WORD(data, fde->cluster, 0x1A); SET_DWORD(data, fde->size, 0x1C); len = DENTRY_SIZE; err = WriteBlock( (void*)data, &len, 0, apos); if (err != ENOERR) return err;#if TDE print_dentry(fde);#endif return ENOERR;}// -------------------------------------------------------------------------// dentry_set_deleted()// Sets the dentry filename first char to 0xE5 (ie deleted). static void dentry_set_deleted(fatfs_disk_t *disk, fat_dir_entry_t *dentry)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -