_mfs_error MFS_Create_subdir ( MFS_DRIVE_STRUCT_PTR drive_ptr, char *pathname /*[IN] pathname of the directory to be created */ ) { MFS_DIR_ENTRY_PTR dir_entry_ptr; uint32_t dir_cluster; uint32_t parent_cluster; uint32_t free_cluster; uint32_t dir_index; _mfs_error error_code; char *temp_dirname; char *temp_filename; if ( (pathname == NULL) || (*pathname == '\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_alloc_2paths(&temp_dirname,&temp_filename); if ( error_code != MFS_NO_ERROR ) { return( error_code ); } error_code = MFS_lock_dos_disk( drive_ptr ); if ( error_code != MFS_NO_ERROR ) { MFS_free_path(temp_dirname); MFS_free_path(temp_filename); return error_code; } MFS_Parse_pathname (temp_dirname, temp_filename, pathname); dir_cluster = drive_ptr->CUR_DIR_CLUSTER; parent_cluster = MFS_Find_directory (drive_ptr, temp_dirname, dir_cluster); dir_cluster = parent_cluster; if ( MFS_is_valid_lfn(temp_filename) ) { if ( dir_cluster != CLUSTER_INVALID ) { /* ** We'll obtain a cluster for the new directory first. If we ** cannot create the directory afterwards, it is easier to re-free ** the cluster than to remove the new entry. */ free_cluster = MFS_Find_unused_cluster_from(drive_ptr, drive_ptr->NEXT_FREE_CLUSTER); if ( free_cluster != CLUSTER_INVALID ) { error_code = MFS_Clear_cluster(drive_ptr, free_cluster); if ( error_code ) { MFS_unlock(drive_ptr,TRUE); MFS_free_path(temp_dirname); MFS_free_path(temp_filename); return( error_code ); } error_code = MFS_Put_fat(drive_ptr, free_cluster, CLUSTER_EOF); dir_entry_ptr = MFS_Create_directory_entry(drive_ptr, temp_filename, MFS_ATTR_DIR_NAME, &dir_cluster, &dir_index, &error_code); if ( error_code == MFS_NO_ERROR ) { clustod(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER, free_cluster); drive_ptr->DIR_SECTOR_DIRTY = TRUE; /* ** We shall now create the "." and ".." entries. */ dir_cluster = free_cluster; dir_entry_ptr = MFS_Create_directory_entry(drive_ptr,".", MFS_ATTR_DIR_NAME, &dir_cluster, &dir_index, &error_code); if ( error_code == MFS_NO_ERROR ) { clustod(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER, free_cluster); drive_ptr->DIR_SECTOR_DIRTY = TRUE; dir_entry_ptr = MFS_Create_directory_entry(drive_ptr,"..", MFS_ATTR_DIR_NAME, &dir_cluster, &dir_index, &error_code); if ( error_code == MFS_NO_ERROR ) { if ( drive_ptr->FAT_TYPE == MFS_FAT32 ) { if ( drive_ptr->BPB32.ROOT_CLUSTER == parent_cluster ) { /* ** Even though the FAT32 root sector can be ** anywhere, it is identified as 0 when referenced ** through a directory entry */ parent_cluster = 0; } } clustod(dir_entry_ptr->HFIRST_CLUSTER, dir_entry_ptr->LFIRST_CLUSTER, parent_cluster); drive_ptr->DIR_SECTOR_DIRTY = TRUE; } } } else { MFS_Put_fat(drive_ptr, free_cluster, CLUSTER_UNUSED); } } else { error_code = MFS_DISK_FULL; } } else { error_code = MFS_PATH_NOT_FOUND; } } else if ( MFS_lfn_dirname_valid(temp_filename) ) { if ( dir_cluster ) { error_code = MFS_FILE_EXISTS; } else { error_code = MFS_CANNOT_CREATE_DIRECTORY; } } else { error_code = MFS_INVALID_PARAMETER; } MFS_free_path(temp_dirname); MFS_free_path(temp_filename); MFS_unlock(drive_ptr,TRUE); return(error_code); }
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); }