_mfs_error MFS_Set_file_attributes ( MQX_FILE_PTR mfs_fd_ptr, char _PTR_ pathname, /*[IN] pathname of the specific file */ uchar_ptr attribute_ptr /*[IN] attribute of file */ ) { MFS_DRIVE_STRUCT_PTR drive_ptr; MFS_DIR_ENTRY_PTR dir_entry_ptr; _mfs_error error_code; uint_32 dir_cluster, dir_index; uchar at, attrib; uint_32 prev_cluster= CLUSTER_INVALID; if ( (pathname == NULL) || (*pathname == '\0') ) { return MFS_INVALID_PARAMETER; } #if MFSCFG_READ_ONLY_CHECK if (MFS_is_read_only (mfs_fd_ptr, NULL)) { return MFS_DISK_IS_WRITE_PROTECTED; } #endif error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr ); if ( error_code != MFS_NO_ERROR ) { return error_code; } attrib = *attribute_ptr; attrib &= MFS_ATTR_ARCHIVE | MFS_ATTR_READ_ONLY | MFS_ATTR_HIDDEN_FILE | MFS_ATTR_SYSTEM_FILE; dir_entry_ptr = MFS_Find_entry_on_disk(drive_ptr, pathname, &error_code, &dir_cluster, &dir_index, &prev_cluster); if ( error_code == MFS_NO_ERROR ) { at = dtohc(dir_entry_ptr->ATTRIBUTE); if ( at != *attribute_ptr ) { /* ** The volume-label and the directory-name are mutually exclusive. ** The volume-label cannot act as a directory-name. Check whether ** you are trying to set the attributes to a volume. */ if ( ! ((at & MFS_ATTR_VOLUME_NAME) || (*attribute_ptr & MFS_ATTR_VOLUME_NAME)) ) { htodc(dir_entry_ptr->ATTRIBUTE, *attribute_ptr); drive_ptr->DIR_SECTOR_DIRTY = TRUE; } else { error_code = MFS_ACCESS_DENIED; } } } MFS_unlock(drive_ptr,TRUE); return(error_code); }
_mfs_error MFS_Get_file_attributes ( MQX_FILE_PTR mfs_fd_ptr, /*[IN] pathname of the file */ char _PTR_ pathname, uchar_ptr attribute_ptr ) { MFS_DRIVE_STRUCT_PTR drive_ptr; MFS_DIR_ENTRY_PTR dir_entry_ptr; uint_32 dir_cluster,dir_index; _mfs_error error_code; uchar attribute; uint_32 prev_cluster= CLUSTER_INVALID; if ( (pathname == NULL) || (*pathname == '\0') ) { return MFS_INVALID_PARAMETER; } error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr ); if ( error_code != MFS_NO_ERROR ) { return(error_code); } dir_entry_ptr = MFS_Find_entry_on_disk(drive_ptr, pathname, &error_code, &dir_cluster, &dir_index, &prev_cluster); /* ** When a function locks MFS device, on any error it should not return ** without unlocking it. This can create a deadlock. */ if ( error_code == MFS_NO_ERROR ) { attribute = dtohc(dir_entry_ptr->ATTRIBUTE); *attribute_ptr = attribute; } MFS_unlock(drive_ptr,FALSE); 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_error MFS_Delete_file ( MQX_FILE_PTR mfs_fd_ptr, /*[IN] the MFS device on which to operate */ char_ptr pathname /*[IN] directory and file name of the file to delete */ ) { MFS_DRIVE_STRUCT_PTR drive_ptr; MFS_DIR_ENTRY_PTR dir_entry_ptr; _mfs_error error_code, saved_code = 0; uint_32 dir_cluster, dir_index; uint_32 first_cluster; uint_32 prev_cluster= CLUSTER_INVALID; if ( (pathname == NULL) || (*pathname == '\0') ) { return MFS_INVALID_PARAMETER; } #if MFSCFG_READ_ONLY_CHECK if (MFS_is_read_only (mfs_fd_ptr, NULL)) { return MFS_DISK_IS_WRITE_PROTECTED; } #endif error_code = MFS_lock_dos_disk( mfs_fd_ptr, &drive_ptr ); if ( error_code != MFS_NO_ERROR ) { return error_code; } dir_entry_ptr = MFS_Find_entry_on_disk(drive_ptr, pathname, &error_code, &dir_cluster, &dir_index, &prev_cluster); if ( dir_entry_ptr != NULL ) { if ( dtohc(dir_entry_ptr->ATTRIBUTE) & (MFS_ATTR_DIR_NAME | MFS_ATTR_VOLUME_NAME | MFS_ATTR_READ_ONLY) ) { error_code = MFS_ACCESS_DENIED; } else { first_cluster = clustoh(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER); if ( first_cluster ) { saved_code = MFS_Release_chain(drive_ptr, first_cluster); if ( saved_code != MFS_LOST_CHAIN && saved_code != MFS_NO_ERROR ) { MFS_unlock(drive_ptr,TRUE); return(saved_code); } } /* ** Mark all open files with the same name as erased */ MFS_Delete_handles(drive_ptr, dir_entry_ptr->NAME, first_cluster); *dir_entry_ptr->NAME = MFS_DEL_FILE; drive_ptr->DIR_SECTOR_DIRTY = TRUE; error_code = MFS_remove_lfn_entries(drive_ptr,dir_cluster,dir_index, prev_cluster); } } MFS_unlock(drive_ptr,TRUE); if ( saved_code == MFS_LOST_CHAIN && error_code == MFS_NO_ERROR ) { error_code = saved_code; } return(error_code); }
void *MFS_Open_file ( MFS_DRIVE_STRUCT_PTR drive_ptr, char *pathname, /*[IN] directory and filename of the file to be opened */ unsigned char access, /*[IN] type of access required: read, write or read/write*/ uint32_t *error_ptr /*[IN/OUT] error code is written to this address */ ) { MFS_DIR_ENTRY_PTR dir_entry_ptr; MFS_HANDLE_PTR handle,open_handle; uint32_t dir_cluster, dir_index; _mfs_error error_code; uint32_t prev_cluster= CLUSTER_INVALID; if ( (pathname == NULL) || (*pathname == '\0') ) { if ( error_ptr != NULL ) { *error_ptr = MFS_INVALID_PARAMETER; } return NULL; } error_code = MFS_lock_dos_disk( drive_ptr ); if ( error_code != MFS_NO_ERROR ) { if ( error_ptr != NULL ) { *error_ptr = error_code; } return NULL; } handle = NULL; dir_entry_ptr = MFS_Find_entry_on_disk(drive_ptr, pathname, &error_code, &dir_cluster, &dir_index, &prev_cluster); if ( error_code == MFS_NO_ERROR ) { if ( mqx_dtohc(dir_entry_ptr->ATTRIBUTE) & (MFS_ATTR_DIR_NAME | MFS_ATTR_VOLUME_NAME) ) { error_code = MFS_WRITE_FAULT; } else if ( (mqx_dtohc(dir_entry_ptr->ATTRIBUTE) & MFS_ATTR_READ_ONLY) && ((access == MFS_ACCESS_WRITE_ONLY) || (access == MFS_ACCESS_READ_WRITE)) ) { error_code = MFS_ACCESS_DENIED; } else { // Check to see if the file is already opened open_handle = MFS_Find_handle(drive_ptr, dir_cluster, dir_index); if (open_handle) { // If we are opening to write, the file can't already be opened. if ((access == MFS_ACCESS_WRITE_ONLY) || (access == MFS_ACCESS_READ_WRITE)) { error_code = MFS_SHARING_VIOLATION; } // And if we the file is already opened, it can't be opened to write. // Note that if it is opened for write, it will be the only instance on the list if ((handle->ACCESS == MFS_ACCESS_WRITE_ONLY) || (handle->ACCESS == MFS_ACCESS_READ_WRITE)) { error_code = MFS_SHARING_VIOLATION; } } if (error_code == MFS_NO_ERROR) { handle = MFS_Get_handle(drive_ptr,dir_entry_ptr); if ( handle != NULL ) { handle->ACCESS = access; handle->CURRENT_CLUSTER = 0; handle->PREVIOUS_CLUSTER = 0; handle->DIR_CLUSTER = dir_cluster; handle->DIR_INDEX = dir_index; } else { error_code = MFS_INSUFFICIENT_MEMORY; } } } } MFS_unlock(drive_ptr,FALSE); if ( error_ptr ) { *error_ptr = error_code; } return((void *) handle); }