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

📄 msdos_misc.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
    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,                             byte + MSDOS_FIRST_CLUSTER_LOW_OFFSET, 2,                            (char *)(&le_cl_low));    le_cl_hi = CT_LE_W((unsigned16)((new_cln & 0xFFFF0000) >> 16));    ret2 = _fat_block_write(mt_entry, sec,                            byte + MSDOS_FIRST_CLUSTER_HI_OFFSET, 2,                            (char *)(&le_cl_hi));    if ( (ret1 < 0) || (ret2 < 0) )        return -1;    return RC_OK;}/* msdos_set_file size -- *     Write file size 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 (errno set apropriately). * */intmsdos_set_file_size(    rtems_filesystem_mount_table_entry_t *mt_entry,     fat_file_fd_t                        *fat_fd    ){    ssize_t          ret = 0;    msdos_fs_info_t *fs_info = mt_entry->fs_info;    unsigned32       le_new_length = 0;    unsigned32       sec = 0;    unsigned32       byte = 0;    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 = (fat_fd->info_ofs & (fs_info->fat.vol.bps - 1));    le_new_length = CT_LE_L((fat_fd->fat_file_size));    ret = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_SIZE_OFFSET, 4,                           (char *)(&le_new_length));    if ( ret < 0 )        return -1;    return RC_OK;}/* * We should not check whether this routine is called for root dir - it * never can happend *//* msdos_set_first_char4file_name -- *     Write first character of the name of the file to the disk (to  *     corresponded 32bytes slot)       * * PARAMETERS: *     mt_entry - mount table entry  *     cl       - number of cluster *     ofs      - offset inside cluster *     fchar    - character to set up * * RETURNS: *     RC_OK on success, or -1 if error occured (errno set apropriately) * */int msdos_set_first_char4file_name(    rtems_filesystem_mount_table_entry_t *mt_entry,     unsigned32                            cl,    unsigned32                            ofs,    unsigned char                         fchar    ){    ssize_t          ret = 0;    msdos_fs_info_t *fs_info = mt_entry->fs_info;    unsigned32       sec = 0;    unsigned32       byte = 0;    sec = fat_cluster_num_to_sector_num(mt_entry, cl);    sec += (ofs >> fs_info->fat.vol.sec_log2);    byte = (ofs & (fs_info->fat.vol.bps - 1));    ret = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_NAME_OFFSET, 1,                            &fchar);    if ( ret < 0)        return -1;    return  RC_OK;}                        /* msdos_dir_is_empty -- *     Check whether directory which correspondes to the fat-file descriptor is  *     empty.       * * PARAMETERS: *     mt_entry - mount table entry  *     fat_fd   - fat-file descriptor    *     ret_val  - placeholder for result  * * RETURNS: *     RC_OK on success, or -1 if error occured * */intmsdos_dir_is_empty(    rtems_filesystem_mount_table_entry_t *mt_entry,    fat_file_fd_t                        *fat_fd,     rtems_boolean                        *ret_val    ){    ssize_t          ret = 0;    msdos_fs_info_t *fs_info = mt_entry->fs_info;    unsigned32       j = 0, i = 0;      /* dir is not empty */    *ret_val = FALSE;    while ((ret = fat_file_read(mt_entry, fat_fd, j * fs_info->fat.vol.bps,                                  fs_info->fat.vol.bps,                                   fs_info->cl_buf)) != FAT_EOF)    {        if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)            return -1;        assert(ret == fs_info->fat.vol.bps);                for (i = 0;              i < fs_info->fat.vol.bps;              i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)        {            if (((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==                  MSDOS_THIS_DIR_ENTRY_EMPTY) ||                 (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)), MSDOS_DOT_NAME,                          MSDOS_SHORT_NAME_LEN) == 0) ||                (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)),                         MSDOS_DOTDOT_NAME,                          MSDOS_SHORT_NAME_LEN) == 0))                continue;            if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==                  MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)            {                *ret_val = TRUE;                return RC_OK;            }            return RC_OK;        }            j++;     }    *ret_val = TRUE;    return RC_OK;}/* msdos_find_name_in_fat_file -- *     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 corresponded to directory we are going to create *          node in. If found free slot write contents of name_dir_entry into *          it.   * *     (b): reading fat-file corresponded to directory and trying to find slot *          with the name field == name parameter * * PARAMETERS: *     mt_entry       - mount table entry  *     fat_fd         - fat-file descriptor    *     name           - NULL or name to find  *     paux           - identify a node location on the disk - *                      number of cluster and offset inside the cluster *     name_dir_entry - node to create/placeholder for found node * * RETURNS: *     RC_OK on success, or error code if error occured (errno set  *     appropriately) * */intmsdos_find_name_in_fat_file(    rtems_filesystem_mount_table_entry_t *mt_entry,    fat_file_fd_t                        *fat_fd,     char                                 *name,     fat_auxiliary_t                      *paux,    char                                 *name_dir_entry    ){    int              rc = RC_OK;    ssize_t          ret = 0;    msdos_fs_info_t *fs_info = mt_entry->fs_info;    unsigned32       i = 0, j = 0;    unsigned32       bts2rd = 0;    if (FAT_FD_OF_ROOT_DIR(fat_fd) &&        (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16)))        bts2rd = fat_fd->fat_file_size;      else        bts2rd = fs_info->fat.vol.bpc;      while ((ret = fat_file_read(mt_entry, fat_fd, (j * bts2rd), bts2rd,                                 fs_info->cl_buf)) != FAT_EOF)     {        if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)            set_errno_and_return_minus_one(EIO);                    assert(ret == bts2rd);            for (i = 0; i < bts2rd; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)        {            /* is the entry empty ? */            if (((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==                  MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY) ||                 ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==                  MSDOS_THIS_DIR_ENTRY_EMPTY))            {                /* whether we are looking for an empty entry */                if (name == NULL)                {                    /* get current cluster number */                    rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM,                                         j * bts2rd, &paux->cln);                    if (rc != RC_OK)                        return rc;                    /* offset is computed in bytes */                    paux->ofs = i;                              /* write new node entry */                    ret = fat_file_write(mt_entry, fat_fd, j * bts2rd + i,                                          MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,                                         name_dir_entry);                    if (ret != MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)                        return -1;                    /*                      * we don't update fat_file_size here - it should not                      * increase                      */                    return RC_OK;                }                /*                  * if name != NULL and there is no more entries in the                  * directory - return name-not-found                 */                if (((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==                      MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY))                    return MSDOS_NAME_NOT_FOUND_ERR;            }                 else            {                /* entry not empty and name != NULL -> compare names */                if (name != NULL)                {                    if (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)), name,                                 MSDOS_SHORT_NAME_LEN) == 0)                    {                        /*                          * we get the entry we looked for - fill auxiliary                          * structure and copy all 32 bytes of the entry                         */                        rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM,                                             j * bts2rd, &paux->cln);                        if (rc != RC_OK)                            return rc;                        /* offset is computed in bytes */                        paux->ofs = i;                        memcpy(name_dir_entry,(fs_info->cl_buf + i),                               MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);                        return RC_OK;                    }                }              }              }                                  j++;    }                            return MSDOS_NAME_NOT_FOUND_ERR;}/* msdos_find_node_by_cluster_num_in_fat_file -- *     Find node with specified number of cluster in fat-file. * * PARAMETERS: *     mt_entry  - mount table entry  *     fat_fd    - fat-file descriptor    *     cl4find   - number of cluster to find  *     paux      - identify a node location on the disk - *                 cluster num and offset inside the cluster *     dir_entry - placeholder for found node * * RETURNS: *     RC_OK on success, or error code if error occured * */intmsdos_find_node_by_cluster_num_in_fat_file(    rtems_filesystem_mount_table_entry_t *mt_entry,    fat_file_fd_t                        *fat_fd,    unsigned32                            cl4find,     fat_auxiliary_t                      *paux,    char                                 *dir_entry    ){    int              rc = RC_OK;    ssize_t          ret = 0;    msdos_fs_info_t *fs_info = mt_entry->fs_info;    unsigned32       bts2rd = 0;      unsigned32       i = 0, j = 0;    if (FAT_FD_OF_ROOT_DIR(fat_fd) &&        (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16)))        bts2rd = fat_fd->fat_file_size;      else        bts2rd = fs_info->fat.vol.bpc;    while ((ret = fat_file_read(mt_entry, fat_fd, j * bts2rd, bts2rd,                                  fs_info->cl_buf)) != FAT_EOF)    {        if ( ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE )            set_errno_and_return_minus_one( EIO );        assert(ret == bts2rd);                for (i = 0; i < bts2rd; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)        {            /* if this and all rest entries are empty - return not-found */            if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==                MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)                return MSDOS_NAME_NOT_FOUND_ERR;            /* if this entry is empty - skip it */             if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==                MSDOS_THIS_DIR_ENTRY_EMPTY)                continue;            /* if get a non-empty entry - compare clusters num */            if (MSDOS_EXTRACT_CLUSTER_NUM((fs_info->cl_buf + i)) == cl4find)            {                /* on success fill aux structure and copy all 32 bytes */                rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM, j * bts2rd,                                     &paux->cln);                if (rc != RC_OK)                    return rc;                paux->ofs = i;                memcpy(dir_entry, fs_info->cl_buf + i,                        MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);                return RC_OK;            }        }                                  j++;    }                            return MSDOS_NAME_NOT_FOUND_ERR;}

⌨️ 快捷键说明

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