📄 msdos_misc.c
字号:
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 + -