⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatfs_supp.c

📁 该工程是从ecos嵌入式系统下移植过来的一个小型的fat16文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    *len -= size;    printf( "total len=%d", *len);    return err;}//==========================================================================// Misc functions // -------------------------------------------------------------------------// init_node()// Initializes file attributes of a new node.  static voidinit_node_fattr(fatfs_node_t     *node,                 const char       *name,                 int               namelen,                mode_t            mode,                cyg_uint32        parent_cluster,                 fatfs_data_pos_t *dentry_pos){    if (namelen == 0)        namelen = 12;        strncpy(node->filename, name, namelen);    node->filename[namelen] = '\0';        node->mode  = mode;    node->ctime =     node->atime =    node->mtime = timeGetTime();    node->priv_data      = 0;    node->size           = 0;    node->cluster        = 0;    node->parent_cluster = parent_cluster;    node->dentry_pos     = *dentry_pos;}// -------------------------------------------------------------------------// is_node_root_node()// Check if the given node is the root dir node  static boolis_node_root_node(fatfs_node_t *node){    return (node->filename[0] == '\0' && node->cluster == 0);}//==========================================================================//==========================================================================// Exported functions // -------------------------------------------------------------------------// fatfs_get_disk_info()// Gets disk info.  intfatfs_get_disk_info(fatfs_disk_t *disk){    int err;    cyg_uint32 sec_num, root_dir_sec_num;    cyg_uint32 data_sec_num, data_clu_num;    fat_boot_record_t boot_rec;    CYG_CHECK_DATA_PTRC(disk);     err = read_boot_record(disk, &boot_rec);    if (err != ENOERR)            return err;    // Check some known boot record values    if (0x29 != boot_rec.ext_sig       ||        0x55 != boot_rec.exe_marker[0] ||        0xAA != boot_rec.exe_marker[1])        return EINVAL;    // Determine number of sectors    if (boot_rec.sec_num_32 != 0)        sec_num = boot_rec.sec_num_32;    else        sec_num = boot_rec.sec_num;        // Number of sectors used by root directory     root_dir_sec_num = ((boot_rec.max_root_dents * DENTRY_SIZE) +                        (boot_rec.bytes_per_sec - 1)) / boot_rec.bytes_per_sec;            // Number of data sectors    data_sec_num = sec_num - (boot_rec.res_sec_num +         (boot_rec.fat_tbls_num * boot_rec.sec_per_fat) + root_dir_sec_num);        // Number of data clusters    data_clu_num = data_sec_num / boot_rec.sec_per_clust;    // Determine the type of FAT based on number of data clusters    if (data_clu_num < 4085)         disk->fat_type = FATFS_FAT12;    else if (data_clu_num < 65525)         disk->fat_type = FATFS_FAT16;    else // FAT32        return EINVAL;        // Sector and cluster sizes     disk->sector_size       = boot_rec.bytes_per_sec;    disk->sector_size_log2  = get_val_log2(disk->sector_size);    disk->cluster_size      = boot_rec.bytes_per_sec * boot_rec.sec_per_clust;    disk->cluster_size_log2 = get_val_log2(disk->cluster_size);    // Sector and cluster size should always be a power of 2    if (0 == disk->sector_size_log2 || 0 == disk->cluster_size_log2)        return EINVAL;    // FAT table and root dir sizes and position    disk->fat_tbl_pos        = boot_rec.bytes_per_sec * boot_rec.res_sec_num;    disk->fat_tbl_size       = boot_rec.bytes_per_sec * boot_rec.sec_per_fat;       disk->fat_tbl_nents      = data_clu_num + 2;    disk->fat_tbls_num       = boot_rec.fat_tbls_num;    disk->fat_root_dir_pos   = disk->fat_tbl_pos +                                disk->fat_tbls_num * disk->fat_tbl_size;    disk->fat_root_dir_size  = boot_rec.max_root_dents * DENTRY_SIZE;    disk->fat_root_dir_nents = boot_rec.max_root_dents;    disk->fat_data_pos       = disk->fat_root_dir_pos + disk->fat_root_dir_size;    return ENOERR;}// -------------------------------------------------------------------------// fatfs_get_root_node()// Gets root dir node. voidfatfs_get_root_node(fatfs_disk_t *disk, fatfs_node_t *node){    CYG_CHECK_DATA_PTRC(disk);    CYG_CHECK_DATA_PTRC(node);        node->mode           = __stat_mode_DIR;    node->size           = disk->fat_root_dir_size;    node->ctime          = 0;    node->atime          = 0;    node->mtime          = 0;    node->filename[0]    = '\0';    node->cluster        = 0;    node->parent_cluster = 0;    node->dentry_pos.cluster      = 0;    node->dentry_pos.cluster_snum = 0;    node->dentry_pos.cluster_pos  = 0;}// -------------------------------------------------------------------------// fatfs_is_node_root_node()// Check if the given node is root dir node. boolfatfs_is_node_root_node(fatfs_node_t *node){    return(is_node_root_node(node));}// -------------------------------------------------------------------------// fatfs_get_dir_entry_node()// Gets dir entry node at given position.// If there is no dir entry at given position the next closest// dir entry and its position are returned. // If EEOF error is returned, then there are no more dir// entries in given dir. intfatfs_get_dir_entry_node(fatfs_disk_t *disk,                         fatfs_node_t *dir,                         cyg_uint32   *pos,                         fatfs_node_t *node){    fat_dir_entry_t dentry;    int err;    CYG_CHECK_DATA_PTRC(disk);    CYG_CHECK_DATA_PTRC(dir);    CYG_CHECK_DATA_PTRC(pos);    CYG_CHECK_DATA_PTRC(node);     err = get_next_dentry(disk, dir, pos, &dentry);      if (err != ENOERR)       return err;    dentry_to_node(&dentry, node);    node->parent_cluster = dir->cluster;    return ENOERR;}// -------------------------------------------------------------------------// fatfs_write_node()// Writes node attributes to its dir entry (to disk). intfatfs_write_file_attr(fatfs_disk_t *disk, fatfs_node_t *node){    fat_dir_entry_t dentry;    int err;    CYG_CHECK_DATA_PTRC(disk);    CYG_CHECK_DATA_PTRC(node);     node_to_dentry(node, &dentry);    err = write_dentry(disk, &dentry.pos, &dentry);    return err;}// -------------------------------------------------------------------------// fatfs_delete_file()// Marks file dir entry as deleted. intfatfs_delete_file(fatfs_disk_t *disk, fatfs_node_t *node){    fat_dir_entry_t dentry;    int err;    CYG_CHECK_DATA_PTRC(disk);    CYG_CHECK_DATA_PTRC(node);    // Can't delete root    if (is_node_root_node(node))        return EINVAL;        printf( "filename='%s'", node->filename);    node_to_dentry(node, &dentry);    // Check if we are about to delete a directory    if (DENTRY_IS_DIR(&dentry))    {        fat_dir_entry_t cdentry;        cyg_uint32 pos = 0;        int i = 0;                printf( "got directory");        // Count number of entries in this dir            while (true)        {            err = get_next_dentry(disk, node, &pos, &cdentry);            if (EEOF == err)                break;            else if (err != ENOERR)                return err;            i++; pos++;        }        printf( "child count=%d", i);                // Check if the dir is empty (except '.' and '..')        if (i > 2)            return EPERM;     }            // Free file clusters    free_cluster_chain(disk, dentry.cluster);    dentry_set_deleted(disk, &dentry);    err = write_dentry(disk, &dentry.pos, &dentry);    return err;} // -------------------------------------------------------------------------// fatfs_create_file()// Creates a new file. intfatfs_create_file(fatfs_disk_t *disk,                   fatfs_node_t *dir,                   const char   *name,                  int           namelen,                  fatfs_node_t *node){    fat_dir_entry_t dentry;    int err;    CYG_CHECK_DATA_PTRC(disk);    CYG_CHECK_DATA_PTRC(dir);    CYG_CHECK_DATA_PTRC(name);    CYG_CHECK_DATA_PTRC(node);     printf( "filename='%s' parent='%s'", name, dir->filename);    dentry.pos.cluster      = dir->cluster;    dentry.pos.cluster_snum = 0;    dentry.pos.cluster_pos  = 0;    // Get free dir entry in parent dir    err = get_free_dentry(disk, &dentry.pos, &dir->tcache);    if (err != ENOERR)        return err;    // Set new file attributes    init_node_fattr(node, name, namelen, __stat_mode_REG,                     dir->cluster, &dentry.pos);     // Write new dir dentry      node_to_dentry(node, &dentry);    err = write_dentry(disk, &dentry.pos, &dentry);    if (err != ENOERR)       return err;     return ENOERR;     }// -------------------------------------------------------------------------// fatfs_create_dir()// Creates a new directory. intfatfs_create_dir(fatfs_disk_t *disk,                  fatfs_node_t *dir,                  const char   *name,                 int           namelen,                 fatfs_node_t *node){    fat_dir_entry_t dentry;    fatfs_node_t    cnode;    cyg_uint32 free_cluster;    int err;    CYG_CHECK_DATA_PTRC(disk);    CYG_CHECK_DATA_PTRC(dir);    CYG_CHECK_DATA_PTRC(name);    CYG_CHECK_DATA_PTRC(node);     printf( "filename='%s' parent='%s'", name, dir->filename);    // Get free cluster    err = find_next_free_cluster(disk, 0, &free_cluster,                                  CO_MARK_LAST | CO_ERASE_NEW);    if (err != ENOERR)        return err;    dentry.pos.cluster      = dir->cluster;    dentry.pos.cluster_snum = 0;    dentry.pos.cluster_pos  = 0;    // Get free dir entry in parent dir    err = get_free_dentry(disk, &dentry.pos, &dir->tcache);    if (err != ENOERR)        return err;    // Set new dir attributes    init_node_fattr(node, name, namelen, __stat_mode_DIR,                     dir->cluster, &dentry.pos);     node->cluster = free_cluster;    // Write new dir dentry      node_to_dentry(node, &dentry);    err = write_dentry(disk, &dentry.pos, &dentry);    if (err != ENOERR)       return err;    // Starting position of new dir entries    dentry.pos.cluster      = node->cluster;    dentry.pos.cluster_snum = 0;    dentry.pos.cluster_pos  = 0;    printf( "Creating '.' entry");    // Set '.' dir attributes    init_node_fattr(&cnode, ".", 0, __stat_mode_DIR,                     node->cluster, &dentry.pos);     cnode.cluster = node->cluster;    // Write '.' dentry    node_to_dentry(&cnode, &dentry);     err = write_dentry(disk, &dentry.pos, &dentry);    if (err != ENOERR)        return err;              dentry.pos.cluster_pos += DENTRY_SIZE;    printf( "Creating '..' entry");    // Set '..' dir attributes    init_node_fattr(&cnode, "..", 0, __stat_mode_DIR,                    node->cluster, &dentry.pos);     cnode.cluster = dir->cluster;        // Write '..' dentry    node_to_dentry(&cnode, &dentry);     err = write_dentry(disk, &dentry.pos, &dentry);    if (err != ENOERR)        return err;      return ENOERR;     }// -------------------------------------------------------------------------// fatfs_trunc_file()// Truncates a file to zero length.intfatfs_trunc_file(fatfs_disk_t *disk, fatfs_node_t *node){    fat_dir_entry_t dentry;    int err;        CYG_CHECK_DATA_PTRC(disk);    CYG_CHECK_DATA_PTRC(node);     printf( "file='%s'", node->filename);      // Check for dir    if (S_ISDIR(node->mode))        return EINVAL;     // Trivial case check    if (0 == node->size)        return ENOERR;       // Free cluster chain     err = free_cluster_chain(disk, node->cluster);    if (err != ENOERR)        return err;        // Flush tcache    fatfs_tcache_flush(disk, &node->tcache);        // Update node attributes    node->cluster = 0;    node->size    = 0;    node->mtime   =    node->atime   = timeGetTime();    // Write dentry    node_to_dentry(node, &dentry);    err = write_dentry(disk, &dentry.pos, &dentry);    if (err != ENOERR)        return err;        return ENOERR;}// -------------------------------------------------------------------------// fat

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -