📄 fatfs_supp.c
字号:
{ dentry->name[0] = 0xE5;}// -------------------------------------------------------------------------// get_dentry_filename()// Gets the filename from given dir entry. static void get_dentry_filename(fat_dir_entry_t *fde, char *name){ int i = 0; char *cptr = fde->name; char *cname = name; while (*cptr != ' ' && i < 8) { *cname++ = *cptr++; i++; } cptr = fde->ext; if (*cptr != ' ') { *cname++ = '.'; i = 0; while (*cptr != ' ' && i < 3) { *cname++ = *cptr++; i++; } } *cname = '\0'; printf( "dos_name='%s' dos_ext='%s' filename='%s'", fde->name, fde->ext, name);}// -------------------------------------------------------------------------// set_dentry_filename()// Sets the filename to given dir entry. static void set_dentry_filename(fat_dir_entry_t *fde, const char *name, int namelen){ int i, nidx; const char *cname; char *cptr; // Special case check if (name[0] == '.') { if (name[1] == '\0') { strcpy(fde->name, ". "); strcpy(fde->ext, " "); return; } else if (name[1] == '.' && name[2] == '\0') { strcpy(fde->name, ".. "); strcpy(fde->ext, " "); return; } } if (0 == namelen) namelen = 9999; nidx = 0; cname = name; cptr = fde->name; for (i = 0; i < 8; i++) { if (*cname != '.' && *cname != '\0' && nidx++ < namelen) *cptr++ = toupper(*cname++); else *cptr++ = ' '; } *cptr = '\0'; while (*cname != '.' && *cname != '\0' && nidx++ < namelen) cname++; if (*cname == '.' && nidx++ < namelen) cname++; cptr = fde->ext; for (i = 0; i < 3; i++) { if (*cname != '.' && *cname != '\0' && nidx++ < namelen) *cptr++ = toupper(*cname++); else *cptr++ = ' '; } *cptr = '\0'; printf( "filename='%s' namelen=%d dos_name='%s' dos_ext='%s'", name, namelen, fde->name, fde->ext);}// -------------------------------------------------------------------------// get_next_dentry()// Gets next dir entry searching from given position to the end.// Position is expected in DENTRY_SIZE units.// If EEOF is returned there are no more extries in given dir. static intget_next_dentry(fatfs_disk_t *disk, fatfs_node_t *dir, cyg_uint32 *pos, fat_dir_entry_t *dentry){ fatfs_data_pos_t dpos; cyg_uint32 off; int err = ENOERR; // Calculate dentry offset off = *pos * DENTRY_SIZE; printf( "pos=%d off=%d dir=%p cluster=%d", off, *pos, dir, dir->cluster); // Root dir check if (0 == dir->cluster) { dpos.cluster = 0; dpos.cluster_snum = 0; dpos.cluster_pos = off; } else { err = get_data_position_from_off(disk, dir->cluster, off, &dpos, &dir->tcache, false); if (err != ENOERR) return err; } while (true) { // Root dir check if (0 != dir->cluster) { // Change cluster if needed if (!is_pos_inside_cluster(disk, dpos.cluster_pos)) err = get_next_cluster(disk, &dpos, &dir->tcache, CO_NONE); } else { if (*pos >= disk->fat_root_dir_nents) err = EEOF; } if (err != ENOERR) break; err = read_dentry(disk, &dpos, dentry); if (err != ENOERR) return err; if (DENTRY_IS_ZERO(dentry)) { // If we get a ZERO dir entry, we assume that // there are no more entries in current dir printf( "ZERO dentry"); err = EEOF; break; } else if (!DENTRY_IS_DELETED(dentry)) { // Dir entry found printf( "dentry_pos=%d cluster=%d pos=%d", *pos, dpos.cluster, dpos.cluster_pos); break; } // Increment offset and position dpos.cluster_pos += DENTRY_SIZE; (*pos)++; } if (EEOF == err) printf( "end of dir"); // EEOF could be returned if there are no more entries in this // dir - this should be cought by the calling function return err;}// -------------------------------------------------------------------------// get_free_dentry()// Gets free dir entry slot searching from given position.// If an deleated entry is found, its clusters are freed and the// entry is reused. // The directory is extended if needed.static intget_free_dentry(fatfs_disk_t *disk, fatfs_data_pos_t *dpos, fatfs_tcache_t *tcache){ fat_dir_entry_t dentry; fatfs_data_pos_t cdpos; int err = ENOERR; printf( "cluster=%d cluster_snum=%d cluster_pos=%d", dpos->cluster, dpos->cluster_snum, dpos->cluster_pos); cdpos = *dpos; while (true) { // Root dir check if (0 != cdpos.cluster) { // Change cluster if needed if (!is_pos_inside_cluster(disk, cdpos.cluster_pos)) err = get_next_cluster(disk, &cdpos, tcache, CO_EXTEND | CO_ERASE_NEW); } else { if (cdpos.cluster_pos >= disk->fat_root_dir_size) err = ENOSPC; } if (err != ENOERR) return err; err = read_dentry(disk, &cdpos, &dentry); if (err != ENOERR) return err; if (DENTRY_IS_DELETED(&dentry)) { printf( "deleted dentry at cluster=%d cluster_snum=%d " "cluster_pos=%d", cdpos.cluster, cdpos.cluster_snum, cdpos.cluster_pos); // Retrun found dentry position *dpos = cdpos; return ENOERR; } else if (DENTRY_IS_ZERO(&dentry)) { printf( "zero dentry at cluster=%d cluster_snum=%d " "cluster_pos=%d", cdpos.cluster, cdpos.cluster_snum, cdpos.cluster_pos); // Retrun found dentry position *dpos = cdpos; return ENOERR; } // Increment current position cdpos.cluster_pos += DENTRY_SIZE; }} // -------------------------------------------------------------------------// dentry_to_node()// Converts FAT dir entry to node. static voiddentry_to_node(fat_dir_entry_t *dentry, fatfs_node_t *node){ get_dentry_filename(dentry, node->filename); if (DENTRY_IS_DIR(dentry)) node->mode = __stat_mode_DIR; else node->mode = __stat_mode_REG; date_dos2unix(dentry->crt_time, dentry->crt_date, &node->ctime); date_dos2unix(0, dentry->acc_date, &node->atime); date_dos2unix(dentry->wrt_time, dentry->wrt_date, &node->mtime); node->size = dentry->size; node->priv_data = dentry->nt_reserved; node->cluster = dentry->cluster; node->dentry_pos = dentry->pos;}// -------------------------------------------------------------------------// node_to_dentry()// Converts node to FAT dir entry. static voidnode_to_dentry(fatfs_node_t *node, fat_dir_entry_t *dentry){ set_dentry_filename(dentry, node->filename, 0); if (node->mode == __stat_mode_DIR) dentry->attr = DENTRY_ATTR_DIR; else dentry->attr = DENTRY_ATTR_ARCHIVE; date_unix2dos(node->ctime, &dentry->crt_time, &dentry->crt_date); date_unix2dos(node->atime, NULL, &dentry->acc_date); date_unix2dos(node->mtime, &dentry->wrt_time, &dentry->wrt_date); dentry->crt_sec_100 = 0; //FIXME dentry->size = node->size; dentry->nt_reserved = node->priv_data; dentry->cluster = node->cluster; dentry->cluster_HI = 0; dentry->pos = node->dentry_pos;}//==========================================================================// FAT data functions // -------------------------------------------------------------------------// read_data()// Reads data from given position. static intread_data(fatfs_disk_t *disk, void *data, cyg_uint32 *len, fatfs_data_pos_t *dpos, fatfs_tcache_t *tcache){ unsigned char *buf; cyg_uint32 apos; cyg_uint32 size; int err; // Initialize variables and get the absolute starting pos on disk buf = (unsigned char *)data; size = *len; apos = get_data_disk_apos(disk, dpos->cluster, dpos->cluster_pos); err = ENOERR; printf( "len=%d cluster=%d cluster_pos=%d " "cluster_snum=%d apos=%d", *len, dpos->cluster, dpos->cluster_pos, dpos->cluster_snum, apos); while (size > 0) { cyg_uint32 csize; // Check if we are still inside current cluster if (!is_pos_inside_cluster(disk, dpos->cluster_pos)) { // Get next cluster of file and adjust absolute disk position err = get_next_cluster(disk, dpos, tcache, CO_NONE); if (err != ENOERR) goto out; apos = get_data_disk_apos(disk, dpos->cluster, dpos->cluster_pos); } // Adjust the data chunk size to be read to the cluster boundary if (size > (disk->cluster_size - dpos->cluster_pos)) csize = disk->cluster_size - dpos->cluster_pos; else csize = size; printf( "-- len=%d cluster=%d cluster_pos=%d " "cluster_snum=%d apos=%d", csize, dpos->cluster, dpos->cluster_pos, dpos->cluster_snum, apos); // Read data chunk err = ReadBlock((void*)buf, &csize, 0, apos); if (err != ENOERR) goto out; // Adjust running variables buf += csize; dpos->cluster_pos += csize; apos += csize; size -= csize; } out: *len -= size; printf( "total len=%d", *len); return err;}// -------------------------------------------------------------------------// write_data()// Writes data to given position. static intwrite_data(fatfs_disk_t *disk, void *data, cyg_uint32 *len, fatfs_data_pos_t *dpos, fatfs_tcache_t *tcache){ unsigned char *buf; cyg_uint32 apos; cyg_uint32 size; int err; // Initialize variables and get the absolute starting pos on disk buf = (unsigned char *)data; size = *len; apos = get_data_disk_apos(disk, dpos->cluster, dpos->cluster_pos); err = ENOERR; printf( "len=%d cluster=%d cluster_pos=%d " "cluster_snum=%d apos=%d", *len, dpos->cluster, dpos->cluster_pos, dpos->cluster_snum, apos); while (size > 0) { cyg_uint32 csize; // Check if we are still inside current cluster if (!is_pos_inside_cluster(disk, dpos->cluster_pos)) { // Get next cluster of file and adjust absolute disk position, // if at the last cluster try to extend the cluster chain err = get_next_cluster(disk, dpos, tcache, CO_EXTEND); if (err != ENOERR) goto out; apos = get_data_disk_apos(disk, dpos->cluster, dpos->cluster_pos); } // Adjust the data chunk size to be read to the cluster boundary if (size > (disk->cluster_size - dpos->cluster_pos)) csize = disk->cluster_size - dpos->cluster_pos; else csize = size; printf( "-- len=%d cluster=%d cluster_pos=%d " "cluster_snum=%d apos=%d", csize, dpos->cluster, dpos->cluster_pos, dpos->cluster_snum, apos); // Write data chunk err = WriteBlock( (void*)buf, &csize, 0, apos); if (err != ENOERR) goto out; // Adjust running variables buf += csize; dpos->cluster_pos += csize; apos += csize; size -= csize; } out:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -