_mfs_error MFS_Update_entry ( MFS_DRIVE_STRUCT_PTR drive_ptr, /*[IN] the drive on which to operate */ MFS_HANDLE_PTR handle /*[IN] Update this file */ ) { uint_32 dir_index; uint_32 dir_cluster; _mfs_error error_code = MFS_NO_ERROR; MFS_DIR_ENTRY_PTR dir_entry_ptr; uint_32 prev_cluster; #if MFSCFG_READ_ONLY_CHECK if (MFS_is_read_only (NULL, drive_ptr)) { return MFS_DISK_IS_WRITE_PROTECTED; } #endif if ( handle == NULL ) { error_code = MFS_INVALID_HANDLE; } else { dir_cluster = handle->DIR_CLUSTER; dir_index = handle->DIR_INDEX; dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &dir_cluster, &dir_index, &prev_cluster, MFS_ATTR_ANY, &error_code); if ( dir_entry_ptr == NULL && !error_code ) { error_code = MFS_FILE_NOT_FOUND; } else { _mem_copy(&handle->DIR_ENTRY, dir_entry_ptr, sizeof(MFS_DIR_ENTRY)); drive_ptr->DIR_SECTOR_DIRTY = TRUE; } } return(error_code); }
_mfs_error MFS_Get_volume ( MFS_DRIVE_STRUCT_PTR drive_ptr, char *volume_name /*[OUT] name of the volune */ ) { MFS_DIR_ENTRY_PTR dir_entry_ptr; _mfs_error error_code; uint32_t vol_cluster, vol_index, i; char *disk_vol_name; uint32_t prev_cluster= CLUSTER_INVALID; if ( volume_name == NULL ) { return( MFS_INVALID_PARAMETER ); } error_code = MFS_lock_dos_disk(drive_ptr); if ( !error_code ) { vol_cluster = ROOT_CLUSTER(drive_ptr); vol_index = 0; dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &vol_cluster, &vol_index, &prev_cluster, MFS_ATTR_VOLUME_NAME, &error_code); if ( dir_entry_ptr ) { disk_vol_name = dir_entry_ptr->NAME; for ( i = 0 ; i < SFILENAME_SIZE - 1; i++ ) { *volume_name++ = *disk_vol_name++; } } *volume_name = '\0'; } MFS_unlock(drive_ptr,FALSE); return( error_code ); }
_mfs_error MFS_Get_volume ( MQX_FILE_PTR mfs_fd_ptr, /*[IN] pointer to the file struct returned by fopen("MFS...:",..); */ char_ptr volume_name /*[OUT] name of the volune */ ) { MFS_DRIVE_STRUCT_PTR drive_ptr; MFS_DIR_ENTRY_PTR dir_entry_ptr; _mfs_error error_code; uint_32 vol_cluster, vol_index, i; char_ptr disk_vol_name; uint_32 prev_cluster= CLUSTER_INVALID; if ( volume_name == NULL ) { return( MFS_INVALID_PARAMETER ); } error_code = MFS_lock_dos_disk(mfs_fd_ptr, &drive_ptr); if ( !error_code ) { vol_cluster = ROOT_CLUSTER(drive_ptr); vol_index = 0; dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &vol_cluster, &vol_index, &prev_cluster, MFS_ATTR_VOLUME_NAME, &error_code); if ( dir_entry_ptr ) { disk_vol_name = dir_entry_ptr->NAME; for ( i = 0 ; i < SFILENAME_SIZE - 1; i++ ) { *volume_name++ = *disk_vol_name++; } } *volume_name = '\0'; } MFS_unlock(drive_ptr,FALSE); return( error_code ); }
_mfs_error MFS_Find_next_slave ( MFS_DRIVE_STRUCT_PTR drive_ptr, /*[IN] drive context */ void *search_next_ptr /*[IN] address of search data block indicating the current criteria and the results ** of the last search results of this search are placed in this data block */ ) { MFS_SEARCH_DATA_PTR transfer_ptr; MFS_INTERNAL_SEARCH_PTR internal_search_ptr; MFS_DIR_ENTRY_PTR dir_entry_ptr; _mfs_error error_code; uint32_t len; bool found; bool match_all; bool eightdotthree = FALSE; char *lfn; char sname[SFILENAME_SIZE+1]; uint32_t dotfile = 0; MFS_DIR_ENTRY saved_dir_entry; transfer_ptr = (MFS_SEARCH_DATA_PTR) search_next_ptr; error_code = MFS_NO_ERROR; found = FALSE; if ( transfer_ptr ) { internal_search_ptr = &transfer_ptr->INTERNAL_SEARCH_DATA; if ( MFS_alloc_path(&lfn)!= MFS_NO_ERROR ) { return MFS_INSUFFICIENT_MEMORY; } match_all = MFS_Check_search_string_for_all(internal_search_ptr->SRC_PTR); if ( !match_all ) { dotfile = MFS_Is_dot_directory(internal_search_ptr->SRC_PTR); if ( dotfile == 0 ) { eightdotthree = MFS_Check_search_string_for_8dot3( internal_search_ptr->SRC_PTR); } } do { dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &internal_search_ptr->CURRENT_CLUSTER, &internal_search_ptr->DIR_ENTRY_INDEX, &internal_search_ptr->PREV_CLUSTER, internal_search_ptr->ATTRIBUTE & (~ATTR_EXCLUSIVE), &error_code); if ( dir_entry_ptr == NULL && !error_code ) { error_code = MFS_FILE_NOT_FOUND; break; } if ( internal_search_ptr->CURRENT_CLUSTER == CLUSTER_INVALID ) { error_code = MFS_FILE_NOT_FOUND; break; } if ( dir_entry_ptr == NULL ) { break; } saved_dir_entry=*dir_entry_ptr; /* Make sure the entry is not an LFN entry */ if ( *dir_entry_ptr->ATTRIBUTE != MFS_ATTR_LFN ) { MFS_Compress_nondotfile (dir_entry_ptr->NAME, sname); if ( match_all ) { found = TRUE; } else { if ( dotfile != 0 ) { if ( dotfile == 1 ) { found = internal_search_ptr->FULLNAME[0] == dir_entry_ptr->NAME[0]; } else if ( dotfile == 2 ) { found = (internal_search_ptr->FULLNAME[0] == dir_entry_ptr->NAME[0]) && (internal_search_ptr->FULLNAME[1] == dir_entry_ptr->NAME[1]); } else { found = FALSE; /* This shouldn't happen */ } } else if ( eightdotthree ) { found = MFS_Wildcard_match(internal_search_ptr->FILENAME, dir_entry_ptr->NAME); } else { if ( MFS_get_lfn_dir_cluster(drive_ptr, search_next_ptr, sname, lfn) == MFS_NO_ERROR ) { found = MFS_lfn_match(internal_search_ptr->SRC_PTR, lfn, 0); } else { found = MFS_lfn_match(internal_search_ptr->SRC_PTR, sname, 0); } } } } if ( !error_code ) { error_code = MFS_Increment_dir_index(drive_ptr, &internal_search_ptr->CURRENT_CLUSTER, &internal_search_ptr->DIR_ENTRY_INDEX, &internal_search_ptr->PREV_CLUSTER); } } while ( (error_code == MFS_NO_ERROR) && (found == FALSE) ); if ( error_code == MFS_NO_ERROR ) { transfer_ptr->ATTRIBUTE = mqx_dtohc(saved_dir_entry.ATTRIBUTE); transfer_ptr->TIME = mqx_dtohs(saved_dir_entry.TIME); transfer_ptr->DATE = mqx_dtohs(saved_dir_entry.DATE); transfer_ptr->FILE_SIZE = mqx_dtohl(saved_dir_entry.FILE_SIZE); /* Transfer the filename */ len = _strnlen(sname,13); if ( sname[len-1] == '.' ) { sname[len-1] = '\0'; } strncpy(transfer_ptr->NAME, sname, 13); } MFS_free_path((void *)lfn); } else { error_code = MFS_INVALID_MEMORY_BLOCK_ADDRESS; } return(error_code); }
MFS_DIR_ENTRY_PTR MFS_Find_entry_on_disk ( MFS_DRIVE_STRUCT_PTR drive_ptr, /*[IN] drive context */ char *pathname, /*[IN] pathname of the file */ _mfs_error_ptr error_ptr, /*[IN/OUT] resulting error code is written to this address*/ uint32_t *dir_cluster_ptr, /*[OUT] the cluster in which the dir entry is located */ uint32_t *dir_index_ptr, /*[OUT] the index within the dir cluster where the entry is located */ uint32_t *prev_cluster_ptr /*[OUT] the cluster previous to dir cluster */ ) { MFS_DIR_ENTRY_PTR dir_entry_ptr; char *temp_dirname; char *temp_filename; uint32_t first_cluster; *error_ptr = MFS_alloc_2paths(&temp_dirname,&temp_filename); if ( *error_ptr != MFS_NO_ERROR ) { return( NULL ); } *error_ptr = MFS_NO_ERROR; dir_entry_ptr = NULL; if ( pathname ) { MFS_Parse_pathname(temp_dirname, temp_filename, pathname); /* ** Is this a relative or an absolute file search ? */ if ( *pathname == '\\' || *pathname == '/' ) { first_cluster = ROOT_CLUSTER(drive_ptr); } else { first_cluster = drive_ptr->CUR_DIR_CLUSTER; } /* first_cluster will now store the current_cluster # */ first_cluster = MFS_Find_directory(drive_ptr, temp_dirname, first_cluster); *prev_cluster_ptr = CLUSTER_INVALID; if ( first_cluster == CLUSTER_INVALID ) { *error_ptr = MFS_PATH_NOT_FOUND; } else { *dir_index_ptr = 0; *dir_cluster_ptr = first_cluster; /* ** Checking for the superset of filename chars will allow ** finding something like \mydir\.. */ if ( !MFS_lfn_dirname_valid(temp_filename) ) { dir_entry_ptr = NULL; *error_ptr = MFS_INVALID_PARAMETER; } else { dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, temp_filename, dir_cluster_ptr, dir_index_ptr, prev_cluster_ptr, MFS_ATTR_ANY, error_ptr); if ( dir_entry_ptr == NULL && !*error_ptr ) { *error_ptr = MFS_FILE_NOT_FOUND; } } } } else { *error_ptr = MFS_INVALID_PARAMETER; } MFS_free_path(temp_dirname); MFS_free_path(temp_filename); return(dir_entry_ptr); }
/*FUNCTION*------------------------------------------------------------------- * * Function Name : MFS_Find_directory * Returned Value : starting_cluster of the specified directory * Comments : Search through the file structure to find the specified * directory. Will search either from the current directory or from the * root directory. Returns the starting cluster number of the specified * directory. If the specified directory cannot be found, then * CLUSTER_INVALID is returned. * *END*---------------------------------------------------------------------*/ uint32_t MFS_Find_directory ( MFS_DRIVE_STRUCT_PTR drive_ptr, /*[IN] drive context */ char *path_ptr, /*[IN] specific directory to search for */ uint32_t first_cluster /*[IN] start searching in this cluster, used for a relative search*/ ) { MFS_DIR_ENTRY_PTR dir_entry_ptr; char *directory; uint32_t current_cluster; uint32_t dir_index; _mfs_error error_code; bool flag; uint32_t prev_cluster = CLUSTER_INVALID; unsigned char attribute; if ( MFS_alloc_path(&directory)!= MFS_NO_ERROR ) { return( CLUSTER_INVALID ); } if ( *path_ptr == '\\' || *path_ptr == '/' ) { current_cluster = ROOT_CLUSTER(drive_ptr); path_ptr++; } else { current_cluster = first_cluster; } while ( path_ptr ) { if ( *path_ptr ) { path_ptr = MFS_Parse_next_filename(path_ptr, directory); if ( !MFS_lfn_dirname_valid(directory) ) { current_cluster = CLUSTER_INVALID; break; } flag = FALSE; if ( current_cluster == 0 ) flag = TRUE; if ( drive_ptr->FAT_TYPE == MFS_FAT32 ) { if ( current_cluster == drive_ptr->BPB32.ROOT_CLUSTER ) { flag = TRUE; } } if ( flag ) { /* ** Special treatment for '.' and '..' in root directory */ dir_index = MFS_Is_dot_directory(directory); if ( dir_index == 1 ) { /* Return the value of the root cluster */ MFS_free_path(directory); return ROOT_CLUSTER(drive_ptr); } else if ( dir_index == 2 ) { MFS_free_path(directory); return(CLUSTER_INVALID); } } dir_index = 0; dir_entry_ptr = MFS_Find_directory_entry( drive_ptr, directory, ¤t_cluster, &dir_index, &prev_cluster, (~ATTR_EXCLUSIVE), &error_code); if ( dir_entry_ptr == NULL ) { current_cluster = CLUSTER_INVALID; break; } else { attribute = mqx_dtohc(dir_entry_ptr->ATTRIBUTE); if ( attribute & MFS_ATTR_DIR_NAME ) { current_cluster = clustoh(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER); if ( current_cluster == 0 && drive_ptr->FAT_TYPE == MFS_FAT32 ) { current_cluster = drive_ptr->BPB32.ROOT_CLUSTER; } } else { // Found an entry, but it is not a directory MFS_free_path(directory); return(CLUSTER_INVALID); } } } else { break; } } MFS_free_path(directory); return(current_cluster); }
_mfs_error MFS_Set_volume ( MFS_DRIVE_STRUCT_PTR drive_ptr, char *volume_name /*[IN] name to use for the volune */ ) { MFS_DIR_ENTRY_PTR dir_entry_ptr; _mfs_error error_code; uint32_t vol_cluster, vol_index; uint32_t prev_cluster= CLUSTER_INVALID; if ( volume_name == NULL ) { return( MFS_INVALID_PARAMETER ); } if ( *volume_name == '\0' ) { return( MFS_INVALID_PARAMETER ); } #if MFSCFG_READ_ONLY_CHECK if (MFS_is_read_only (drive_ptr)) { return MFS_DISK_IS_WRITE_PROTECTED; } #endif error_code = MFS_lock_dos_disk(drive_ptr); if ( !error_code ) { vol_cluster = ROOT_CLUSTER(drive_ptr); vol_index = 0; dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &vol_cluster, &vol_index, &prev_cluster, MFS_ATTR_VOLUME_NAME, &error_code); if ( dir_entry_ptr ) { MFS_Expand_dotfile(volume_name, dir_entry_ptr->NAME); *dir_entry_ptr->ATTRIBUTE = MFS_ATTR_VOLUME_NAME; drive_ptr->DIR_SECTOR_DIRTY = TRUE; } else if ( !error_code ) { vol_cluster = ROOT_CLUSTER(drive_ptr); vol_index = 0; dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &vol_cluster, &vol_index, &prev_cluster, MFS_ATTR_ANY, &error_code); if ( dir_entry_ptr ) { MFS_Expand_dotfile(volume_name, dir_entry_ptr->NAME); *dir_entry_ptr->ATTRIBUTE = MFS_ATTR_VOLUME_NAME; drive_ptr->DIR_SECTOR_DIRTY = TRUE; } } } MFS_unlock(drive_ptr,TRUE); return( error_code ); }
_mfs_error MFS_Remove_subdir ( MFS_DRIVE_STRUCT_PTR drive_ptr, char *pathname /*[IN] pathname of the directory to be removed */ ) { _mfs_error error_code, saved_error = 0; uint32_t dir_cluster, parent_cluster, dir_index; MFS_DIR_ENTRY_PTR dir_entry_ptr; uint32_t prev_cluster= CLUSTER_INVALID; uint32_t parent_prev_cluster= CLUSTER_INVALID; if ( (pathname == NULL) || (*pathname == '\0') ) { return MFS_INVALID_PARAMETER; } error_code = MFS_lock_dos_disk( drive_ptr ); if ( error_code != MFS_NO_ERROR ) { return error_code; } dir_entry_ptr = MFS_Find_entry_on_disk (drive_ptr, pathname, &error_code, &parent_cluster, &dir_index, &parent_prev_cluster); if ( dir_entry_ptr ) { if ( mqx_dtohc(dir_entry_ptr->ATTRIBUTE) & MFS_ATTR_DIR_NAME ) { dir_cluster = clustoh(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER); if ( dir_cluster != drive_ptr->CUR_DIR_CLUSTER ) { dir_index = 2; /* Skip over '.' and '..' */ dir_entry_ptr = MFS_Find_directory_entry (drive_ptr, NULL, &dir_cluster, &dir_index, &prev_cluster, MFS_ATTR_ANY, &error_code); if ( dir_entry_ptr == NULL && !error_code ) { dir_index = 0; dir_entry_ptr = MFS_Find_entry_on_disk (drive_ptr, pathname, &error_code, &parent_cluster, &dir_index, &parent_prev_cluster); if ( dir_entry_ptr ) { *dir_entry_ptr->NAME = MFS_DEL_FILE; drive_ptr->DIR_SECTOR_DIRTY = TRUE; error_code = MFS_remove_lfn_entries(drive_ptr, parent_cluster, dir_index, parent_prev_cluster); if ( !error_code ) { saved_error = MFS_Release_chain(drive_ptr, dir_cluster); } } } else if ( dir_entry_ptr != NULL && !error_code ) { error_code = MFS_FILE_EXISTS; } } else { error_code = MFS_ATTEMPT_TO_REMOVE_CURRENT_DIR; } } else { error_code = MFS_WRITE_FAULT; } } else { error_code = MFS_PATH_NOT_FOUND; } MFS_unlock(drive_ptr,TRUE); if ( saved_error == MFS_LOST_CHAIN && error_code == MFS_NO_ERROR ) { error_code = saved_error; } return(error_code); }
MFS_DIR_ENTRY_PTR MFS_Create_directory_entry ( MFS_DRIVE_STRUCT_PTR drive_ptr, /*[IN] the drive on which to operate */ char_ptr filename_ptr, /*[IN] pointer to the file's name */ char attribute, /*[IN] attribute to be assigned to the file */ uint_32_ptr dir_cluster_ptr, /*[IN/OUT] indicates cluster in which the entry was put.*/ uint_32_ptr dir_index_ptr, /*[IN/OUT] index of the location of new file within the directory */ uint_32_ptr error_ptr /*[IN/OUT] error_return_address */ ) { MFS_DIR_ENTRY_PTR dir_entry_ptr, dir_entry_ptr1; MFS_DIR_ENTRY_PTR temp_entry_ptr; TIME_STRUCT time; DATE_STRUCT clk_time; uint_32 dir_index, saved_index, temp_index; uint_32 entry_cluster, saved_cluster, temp_cluster; uint_32 needed_entries, i; int_32 length; boolean found_all = FALSE; char temp_name[SFILENAME_SIZE+1], short_name[SFILENAME_SIZE+1]; uchar checksum = 0; uint_32 prev_cluster= CLUSTER_INVALID, saved_prev_cluster, temp_prev_cluster; dir_entry_ptr = NULL; entry_cluster = *dir_cluster_ptr; dir_index = 0; /* ** Check for duplicate file */ if ( filename_ptr == NULL ) { *error_ptr = MFS_INVALID_PARAMETER; } else if ( *filename_ptr == '\0' ) { *error_ptr = MFS_FILE_NOT_FOUND; } #if MFSCFG_READ_ONLY_CHECK else if (MFS_is_read_only (NULL, drive_ptr)) { *error_ptr = MFS_DISK_IS_WRITE_PROTECTED; } #endif else if ( (dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, filename_ptr, &entry_cluster, &dir_index, &prev_cluster, MFS_ATTR_ANY, error_ptr)) != NULL ) { *error_ptr = MFS_FILE_EXISTS; } else { /* ** Search for an empty slot */ dir_index = 0; dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, attribute, error_ptr); if ( MFS_Dirname_valid(filename_ptr) ) { found_all = TRUE; } if ( dir_entry_ptr == NULL && !*error_ptr ) { found_all = TRUE; } /* ** Save it now because we might not go into the while loop ** If we don't go into while, we lose original values when these ** variables are restored after the while loop */ saved_cluster = entry_cluster; saved_index = dir_index; while ( !found_all ) { /* Calculate the amount of extra entries needed for LFN's */ saved_cluster = entry_cluster; saved_index = dir_index; for ( needed_entries = (strlen(filename_ptr) + 12) / 13; needed_entries >= 1 && !found_all; needed_entries-- ) { *error_ptr = MFS_Increment_dir_index(drive_ptr, &entry_cluster, &dir_index, NULL); if ( entry_cluster == CLUSTER_EOF && !*error_ptr ) { /* This means the LFN will span a cluster. */ found_all = TRUE; break; } temp_index = dir_index; temp_cluster = entry_cluster; temp_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, MFS_ATTR_ANY,error_ptr); if ( *error_ptr ) { return NULL; } if ( !temp_entry_ptr ) { found_all = TRUE; dir_entry_ptr = NULL; break; } else if ( dir_index == temp_index && temp_cluster == entry_cluster ) { continue; } else { break; } } if ( needed_entries == 0 ) { found_all = TRUE; } if ( found_all ) { dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &saved_cluster, &saved_index, &saved_prev_cluster, MFS_ATTR_ANY,error_ptr); } } entry_cluster = saved_cluster; dir_index = saved_index; if ( dir_entry_ptr == NULL && !*error_ptr ) { /* ** Empty spot not found... get a new cluster and use the first entry. */ dir_index = 0; if ( entry_cluster == 0 ) { *error_ptr = MFS_ROOT_DIR_FULL; return(NULL); } else { *error_ptr = MFS_Add_cluster_to_chain(drive_ptr, entry_cluster, &entry_cluster); if ( *error_ptr == MFS_NO_ERROR ) { *error_ptr = MFS_Clear_cluster(drive_ptr, entry_cluster); if ( *error_ptr ) { return(NULL); } dir_entry_ptr = (pointer) drive_ptr->DIR_SECTOR_PTR; *error_ptr = MFS_Write_back_fat(drive_ptr); if ( *error_ptr ) { return(NULL); } } } } } if ( *error_ptr == MFS_NO_ERROR ) { /* At this point we have one of the following cases ** ** 1. We have a normal 8.3 filename and an empty slot for it ** 2. We have a LFN, and a slot which has enough consecutive free slots ** to store the LFN, followed by the actual entry */ /* If the file is a normal 8.3 file */ if ( MFS_Dirname_valid(filename_ptr) ) { _mem_zero(dir_entry_ptr, sizeof (MFS_DIR_ENTRY)); htodc(dir_entry_ptr->ATTRIBUTE, attribute); MFS_Expand_dotfile(filename_ptr, dir_entry_ptr->NAME); _time_get(&time); _time_to_date(&time, &clk_time); NORMALIZE_DATE(&clk_time); htods(dir_entry_ptr->TIME, PACK_TIME(clk_time)); htods(dir_entry_ptr->DATE, PACK_DATE(clk_time)); drive_ptr->DIR_SECTOR_DIRTY = TRUE; } else { /* Case where the file is a LFN */ length = strlen(filename_ptr); /* Get the 8.3 name and calculate the checksum */ temp_index = 0; temp_cluster = *dir_cluster_ptr; *error_ptr = MFS_lfn_to_sfn(filename_ptr, temp_name); if ( !*error_ptr ) { do { dir_entry_ptr1 = MFS_Find_directory_entry(drive_ptr, temp_name, &temp_cluster, &temp_index, &temp_prev_cluster, MFS_ATTR_ANY, error_ptr); if ( !*error_ptr && dir_entry_ptr1 != NULL ) { MFS_increment_lfn(temp_name); temp_index = 0; } } while ( !*error_ptr && dir_entry_ptr1 != NULL ); dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, attribute, error_ptr); /* ** The memory should be cleared after finding the directory entry. */ _mem_zero(dir_entry_ptr, sizeof (MFS_DIR_ENTRY)); /* Setup the final slot */ ((MFS_LNAME_ENTRY_PTR) dir_entry_ptr)->ID |= MFS_LFN_END; drive_ptr->DIR_SECTOR_DIRTY = TRUE; MFS_Expand_dotfile(temp_name,short_name); checksum = MFS_lfn_checksum(short_name); } while ( length && !*error_ptr ) { i = length - ((length -1) % 13 + 1); *error_ptr = MFS_lfn_name_to_entry(filename_ptr + i, (MFS_LNAME_ENTRY_PTR) dir_entry_ptr); /* Set the entry number, the checksum value and the attribute */ ((MFS_LNAME_ENTRY_PTR) dir_entry_ptr)->ID |= (length + 12) / 13; ((MFS_LNAME_ENTRY_PTR) dir_entry_ptr)->ALIAS_CHECKSUM= checksum; ((MFS_LNAME_ENTRY_PTR) dir_entry_ptr)->ATTR = MFS_ATTR_LFN; drive_ptr->DIR_SECTOR_DIRTY = TRUE; length -= (length - i); if ( length < 0 ) { length = 0; } if ( length && !*error_ptr ) { dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, attribute, error_ptr); if ( dir_entry_ptr == NULL && !*error_ptr ) { /* No empty spots... We need to get a new cluster */ dir_index = 0; if ( entry_cluster == 0 ) { *error_ptr = MFS_ROOT_DIR_FULL; return(NULL); } else { *error_ptr = MFS_Add_cluster_to_chain( drive_ptr, entry_cluster, &entry_cluster); if ( *error_ptr == MFS_NO_ERROR ) { *error_ptr = MFS_Clear_cluster(drive_ptr, entry_cluster); if ( *error_ptr ) { return(NULL); } dir_entry_ptr = (pointer) drive_ptr->DIR_SECTOR_PTR; *error_ptr = MFS_Write_back_fat(drive_ptr); if ( *error_ptr ) { return(NULL); } } } } _mem_zero(dir_entry_ptr, sizeof (MFS_DIR_ENTRY)); drive_ptr->DIR_SECTOR_DIRTY = TRUE; } } /* LFN is written, so write the actual entry */ if ( !*error_ptr ) { dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, "", &entry_cluster, &dir_index, &prev_cluster, attribute, error_ptr); if ( dir_entry_ptr == NULL && !*error_ptr ) { dir_index = 0; if ( entry_cluster == 0 ) { *error_ptr = MFS_ROOT_DIR_FULL; return(NULL); } else { *error_ptr = MFS_Add_cluster_to_chain( drive_ptr, entry_cluster, &entry_cluster); if ( *error_ptr == MFS_NO_ERROR ) { *error_ptr = MFS_Clear_cluster(drive_ptr, entry_cluster); if ( *error_ptr ) { return(NULL); } dir_entry_ptr = (pointer) drive_ptr->DIR_SECTOR_PTR; *error_ptr = MFS_Write_back_fat(drive_ptr); if ( *error_ptr ) { return(NULL); } } } } _mem_zero(dir_entry_ptr, sizeof (MFS_DIR_ENTRY)); htodc(dir_entry_ptr->ATTRIBUTE, attribute); MFS_Expand_dotfile(temp_name, dir_entry_ptr->NAME); _time_get(&time); _time_to_date(&time, &clk_time); NORMALIZE_DATE(&clk_time); htods(dir_entry_ptr->TIME, PACK_TIME(clk_time)); htods(dir_entry_ptr->DATE, PACK_DATE(clk_time)); drive_ptr->DIR_SECTOR_DIRTY = TRUE; } } if ( *error_ptr ) { return(NULL); } } *dir_cluster_ptr = entry_cluster; *dir_index_ptr = dir_index; return(dir_entry_ptr); }
MFS_DIR_ENTRY_PTR MFS_Create_entry_slave ( MFS_DRIVE_STRUCT_PTR drive_ptr, /*[IN] the drive on which to operate */ uchar attr, /*[IN] attribute to be given to the new file */ char_ptr pathname, /*[IN] directory and file name to be given to the new file */ uint_32_ptr cluster_ptr, /*[OUT] cluster # in the directory where the entry was created */ uint_32_ptr index_ptr, /*[OUT] index # in the directory where the entry was created*/ _mfs_error_ptr error_ptr, /*[IN/OUT] error code is written to this address */ boolean overwrite /*[IN] if TRUE, we will overwrite an existing entry w/the same name */ ) { MFS_DIR_ENTRY_PTR dir_entry_ptr; char_ptr temp_dirname; char_ptr temp_filename; uchar at; uint_32 dir_cluster; uint_32 dir_index; uint_32 vol_cluster, vol_index; _mfs_error error_code; uint_32 prev_cluster; #if MFSCFG_READ_ONLY_CHECK if (MFS_is_read_only (NULL, drive_ptr)) { if ( error_ptr ) { *error_ptr = MFS_DISK_IS_WRITE_PROTECTED; } return NULL; } #endif dir_index = 0; dir_cluster = drive_ptr->CUR_DIR_CLUSTER; dir_entry_ptr = NULL; error_code = MFS_alloc_2paths(&temp_dirname,&temp_filename); if ( error_code ) { return( NULL ); } error_code = MFS_Parse_pathname(temp_dirname, temp_filename, pathname); if ( error_code == MFS_NO_ERROR ) { dir_cluster = MFS_Find_directory(drive_ptr, temp_dirname, dir_cluster); if ( dir_cluster == CLUSTER_INVALID ) { error_code = MFS_PATH_NOT_FOUND; } else { if ( MFS_is_valid_lfn(temp_filename) ) { if ( attr & MFS_ATTR_VOLUME_NAME ) { /* ** If creating a volume label, it must be in the root ** directory. */ if ( dir_cluster == 0 ) { vol_cluster = 0; vol_index = 0; dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &vol_cluster, &vol_index, &prev_cluster, MFS_ATTR_VOLUME_NAME, &error_code); if ( dir_entry_ptr ) { error_code = MFS_ALREADY_ASSIGNED; } } else { error_code = MFS_ACCESS_DENIED; } } if ( error_code == MFS_NO_ERROR ) { dir_entry_ptr = MFS_Create_directory_entry(drive_ptr, temp_filename, attr, &dir_cluster, &dir_index, &error_code); /* if dir_entry_ptr == NULL ** we couldn't create a new entry. ** if not NULL, it may be a brand new entry (MFS_NO_ERROR) or ** an old one (MFS_FILE_EXISTS) */ if ( dir_entry_ptr != NULL ) { at = dtohc(dir_entry_ptr->ATTRIBUTE); if ( (error_code != MFS_NO_ERROR) && (overwrite == FALSE) ) { dir_entry_ptr = NULL; } else if ( (error_code == MFS_FILE_EXISTS) && ((at & MFS_ATTR_DIR_NAME) != (attr & MFS_ATTR_DIR_NAME)) || ((at & MFS_ATTR_VOLUME_NAME) != (attr & MFS_ATTR_VOLUME_NAME)) ) { error_code = MFS_WRITE_FAULT; dir_entry_ptr = NULL; } else if ( at & MFS_ATTR_READ_ONLY && error_code != MFS_NO_ERROR ) { /* ** If not freshly created */ error_code = MFS_ACCESS_DENIED; dir_entry_ptr = NULL; } } *cluster_ptr = dir_cluster; *index_ptr = dir_index; } } else { error_code = MFS_INVALID_PARAMETER; dir_entry_ptr = NULL; } } } if ( error_ptr ) { *error_ptr = error_code; } MFS_free_path(temp_filename); MFS_free_path(temp_dirname); return(dir_entry_ptr); }