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

📄 msdos_misc.c

📁 DOS/Windows FAT 文件系统实现源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* update node_info_ptr field */    parent_loc->node_access = fat_fd;      return rc;}  /* msdos_get_name_node -- *     This routine is used in two ways: for a new mode creation (a) or for *     search the node which correspondes to the name parameter (b). *     In case (a) 'name' should be set up to NULL and 'name_dir_entry' should  *     point to initialized 32 bytes structure described a new node.  *     In case (b) 'name' should contain a valid string. * *     (a): reading fat-file which correspondes to directory we are going to  *          create node in. If free slot is found write contents of  *          'name_dir_entry' into it. If reach end of fat-file and no free  *          slot found, write 32 bytes to the end of fat-file. * *     (b): reading fat-file which correspondes to directory and trying to  *          find slot with the name field == 'name' parameter * * * PARAMETERS: *     parent_loc     - node description to create node in or to find name in *     name           - NULL or name to find *     paux           - identify a node location on the disk - *                      cluster num and offset inside the cluster  *     name_dir_entry - node to create/placeholder for found node (IN/OUT) * * RETURNS: *     RC_OK, filled aux_struct_ptr and name_dir_entry on success, or -1 if  *     error occured (errno set apropriately) * */intmsdos_get_name_node(    rtems_filesystem_location_info_t *parent_loc,     char                             *name,     fat_auxiliary_t                  *paux,    char                             *name_dir_entry    ){    int              rc = RC_OK;    ssize_t          ret = 0;    msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info;    fat_file_fd_t   *fat_fd = parent_loc->node_access;    unsigned32       dotdot_cln = 0;    /* find name in fat-file which correspondes to the directory */    rc = msdos_find_name_in_fat_file(parent_loc->mt_entry, fat_fd, name, paux,                                     name_dir_entry);    if ((rc != RC_OK) && (rc != MSDOS_NAME_NOT_FOUND_ERR))        return rc;      /* if we search for valid name and name not found -> return */    if ((rc == MSDOS_NAME_NOT_FOUND_ERR) && (name != NULL))        return rc;      /*      * if we try to create new entry and the directory is not big enough      * currently - try to enlarge directory        */    if ((rc == MSDOS_NAME_NOT_FOUND_ERR) && (name == NULL))    {        ret = fat_file_write(parent_loc->mt_entry, fat_fd,                              fat_fd->fat_file_size,                              MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,                              name_dir_entry);        if (ret == -1)            return -1;          /* on success directory is enlarged by a new cluster */        fat_fd->fat_file_size += fs_info->fat.vol.bpc;            /* get cluster num where a new node located */        rc = fat_file_ioctl(parent_loc->mt_entry, fat_fd, F_CLU_NUM,                            fat_fd->fat_file_size - 1, &paux->cln);                                if (rc != RC_OK)            return rc;        /*          * if new cluster allocated succesfully then new node is at very          * beginning of the cluster (offset is computed in bytes)          */        paux->ofs = 0;        return RC_OK;                                                     }                                                                          /*      * if we have deal with ".." - it is a special case :(((      *     * Really, we should return cluster num and offset not of ".." slot, but     * slot which correspondes to real directory name.     */    if ((rc == RC_OK) && (name != NULL))    {        if (strncmp(name, MSDOS_DOTDOT_NAME, MSDOS_SHORT_NAME_LEN) == 0)        {            dotdot_cln = MSDOS_EXTRACT_CLUSTER_NUM((name_dir_entry));            /* are we right under root dir ? */            if (dotdot_cln == 0)            {                 /*                  * we can relax about first_char field - it never should be                  * used for root dir                 */                paux->cln = FAT_ROOTDIR_CLUSTER_NUM;                paux->ofs = 0;            }              else            {                rc = msdos_get_dotdot_dir_info_cluster_num_and_offset(                        parent_loc->mt_entry,                        dotdot_cln,                        paux,                        name_dir_entry                        );                if (rc != RC_OK)                    return rc;            }        }      }    return rc;}/* * msdos_get_dotdot_dir_info_cluster_num_and_offset * * Unfortunately, in general, we cann't work here in fat-file ideologic  * (open fat_file "..", get ".." and ".", open "..", find an entry ...)  * because if we open * fat-file ".." it may happend that we have two different fat-file * descriptors ( for real name of directory and ".." name ) for a single  * file  ( cluster num of both pointers to the same cluster ) * But...we do it because we protected by semaphore *  *//* msdos_get_dotdot_dir_info_cluster_num_and_offset -- *     Get cluster num and offset not of ".." slot, but slot which correspondes  *     to real directory name.    * * PARAMETERS: *     mt_entry       - mount table entry *     cln            - data cluster num extracted drom ".." slot *     paux           - identify a node location on the disk - *                      number of cluster and offset inside the cluster *     dir_entry      - placeholder for found node  * * RETURNS: *     RC_OK, filled 'paux' and 'dir_entry' on success, or -1 if error occured *     (errno set apropriately) * */intmsdos_get_dotdot_dir_info_cluster_num_and_offset(    rtems_filesystem_mount_table_entry_t *mt_entry,     unsigned32                            cln,    fat_auxiliary_t                      *paux,    char                                 *dir_entry    ){    int              rc = RC_OK;    msdos_fs_info_t *fs_info = mt_entry->fs_info;    fat_file_fd_t   *fat_fd = NULL;    unsigned char    dot_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];    unsigned char    dotdot_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];    unsigned char    cur_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];    unsigned32       cl4find = 0;      memset(dot_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);      memset(dotdot_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);    memset(cur_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);      /*     * open fat-file corresponded to ".."     */    rc = fat_file_open(mt_entry, paux->cln, paux->ofs, &fat_fd);    if (rc != RC_OK)        return rc;      fat_fd->info_cln = paux->cln;    fat_fd->info_ofs = paux->ofs;    fat_fd->cln = cln;    fat_fd->fat_file_type = FAT_DIRECTORY;    fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;        fat_fd->map.file_cln = 0;    fat_fd->map.disk_cln = fat_fd->cln;    rc = fat_file_size(mt_entry, fat_fd);    if (rc != RC_OK)    {        fat_file_close(mt_entry, fat_fd);        return rc;    }        /* find "." node in opened directory */    rc = msdos_find_name_in_fat_file(mt_entry, fat_fd, MSDOS_DOT_NAME, paux,                                      dot_node);                                       if (rc != RC_OK)    {        fat_file_close(mt_entry, fat_fd);        return rc;    }      /* find ".." node in opened directory */    rc = msdos_find_name_in_fat_file(mt_entry, fat_fd, MSDOS_DOTDOT_NAME, paux,                                      dotdot_node);                                       if (rc != RC_OK)     {        fat_file_close(mt_entry, fat_fd);        return rc;    }    cl4find = MSDOS_EXTRACT_CLUSTER_NUM(dot_node);      /* close fat-file corresponded to ".." directory */    rc = fat_file_close(mt_entry, fat_fd);    if ( rc != RC_OK )        return rc;    if ( (MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node)) == 0)    {        /*          * we handle root dir for all FAT types in the same way with the          * ordinary directories ( through fat_file_* calls )         */        paux->cln = FAT_ROOTDIR_CLUSTER_NUM;        paux->ofs = 0;    }    /* open fat-file corresponded to second ".." */    rc = fat_file_open(mt_entry, paux->cln, paux->ofs, &fat_fd);    if (rc != RC_OK)        return rc;    fat_fd->info_cln = paux->cln;    fat_fd->info_ofs = paux->ofs;    if ((MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node)) == 0)        fat_fd->cln = fs_info->fat.vol.rdir_cl;    else        fat_fd->cln = MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node);    fat_fd->fat_file_type = FAT_DIRECTORY;    fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;        fat_fd->map.file_cln = 0;    fat_fd->map.disk_cln = fat_fd->cln;    rc = fat_file_size(mt_entry, fat_fd);    if (rc != RC_OK)    {        fat_file_close(mt_entry, fat_fd);        return rc;    }        /* in this directory find slot with specified cluster num */    rc = msdos_find_node_by_cluster_num_in_fat_file(mt_entry, fat_fd, cl4find,                                                     paux, dir_entry);    if (rc != RC_OK)    {        fat_file_close(mt_entry, fat_fd);        return rc;    }    rc = fat_file_close(mt_entry, fat_fd);    return rc;}/* msdos_set_dir_wrt_time_and_date -- *     Write last write date and time for a file to the disk (to corresponded  *     32bytes node)       * * PARAMETERS: *     mt_entry - mount table entry  *     fat_fd   - fat-file descriptor * * RETURNS: *     RC_OK on success, or -1 if error occured (errno set apropriately). * */intmsdos_set_dir_wrt_time_and_date(    rtems_filesystem_mount_table_entry_t *mt_entry,     fat_file_fd_t                        *fat_fd    ){    ssize_t          ret1 = 0, ret2 = 0;    msdos_fs_info_t *fs_info = mt_entry->fs_info;    unsigned short   time_val;    unsigned short   date;    unsigned32       sec = 0;    unsigned32       byte = 0;      msdos_date_unix2dos(fat_fd->mtime, &time_val, &date);      /*      * calculate input for _fat_block_write: convert (cluster num, offset) to     * (sector num, new offset)     */    sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln);    sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2);    /* byte points to start of 32bytes structure */    byte = fat_fd->info_ofs & (fs_info->fat.vol.bps - 1);       time_val = CT_LE_W(time_val);    ret1 = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_WTIME_OFFSET,                            2, (char *)(&time_val));    date = CT_LE_W(date);    ret2 = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_WDATE_OFFSET,                            2, (char *)(&date));    if ( (ret1 < 0) || (ret2 < 0) )        return -1;    return RC_OK;}/* msdos_set_first_cluster_num -- *     Write number of first cluster of the file to the disk (to corresponded  *     32bytes slot)       * * PARAMETERS: *     mt_entry - mount table entry  *     fat_fd   - fat-file descriptor * * RETURNS: *     RC_OK on success, or -1 if error occured * */intmsdos_set_first_cluster_num(    rtems_filesystem_mount_table_entry_t *mt_entry,     fat_file_fd_t                        *fat_fd    ){    ssize_t          ret1 = 0, ret2 = 0;    msdos_fs_info_t *fs_info = mt_entry->fs_info;    unsigned32       new_cln = fat_fd->cln;    unsigned16       le_cl_low = 0;    unsigned16       le_cl_hi = 0;      unsigned32       sec = 0;    unsigned32       byte = 0;    /*      * calculate input for _fat_block_write: convert (cluster num, offset) to     * (sector num, new offset)     */    sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln);    sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2);    /* byte from points to start of 32bytes structure */    byte = fat_fd->info_ofs & (fs_info->fat.vol.bps - 1);     le_cl_low = CT_LE_W((unsigned16)(new_cln & 0x0000FFFF));    ret1 = _fat_block_write(mt_entry, sec, 

⌨️ 快捷键说明

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