//----------------------------------------------------------------------------- // _read_file: Open a file for reading //----------------------------------------------------------------------------- static FL_FILE* _read_file(char *path) { FL_FILE* file; FAT32_ShortEntry sfEntry; // If first call to library, initialise CHECK_FL_INIT(); file = _find_spare_file(); if (file==NULL) return NULL; // Clear filename memset(file->path, '\n', sizeof(file->path)); memset(file->filename, '\n', sizeof(file->filename)); // Split full path into filename and directory path FileString_SplitPath(path, file->path, file->filename); // Check if file already open if (_check_file_open(file)) return FALSE; // If file is in the root dir if (file->path[0]==0) { file->parentcluster = FAT32_GetRootCluster(); file->inRoot = TRUE; } else { file->inRoot = FALSE; // Find parent directory start cluster if (!_open_directory(file->path, &file->parentcluster)) return NULL; } // Using dir cluster address search for filename if (FAT32_GetFileEntry(file->parentcluster, file->filename,&sfEntry)) { // Initialise file details memcpy(file->shortfilename, sfEntry.Name, 11); file->filelength = sfEntry.FileSize; file->bytenum = 0; file->startcluster = (((UINT32)sfEntry.FstClusHI)<<16) + sfEntry.FstClusLO; file->currentBlock = 0xFFFFFFFF; file->inUse = TRUE; FAT32_PurgeFATBuffer(); return file; } return NULL; }
static FL_FILE* _create_file(char *filename, UINT32 size) { FL_FILE* file; FAT32_ShortEntry sfEntry; char shortFilename[11]; int tailNum; // If first call to library, initialise CHECK_FL_INIT(); file = _find_spare_file(); if (file==NULL) return NULL; // Clear filename memset(file->path, '\n', sizeof(file->path)); memset(file->filename, '\n', sizeof(file->filename)); // Split full path into filename and directory path FileString_SplitPath(filename, file->path, file->filename); // Check if file already open if (_check_file_open(file)) return FALSE; // If file is in the root dir if (file->path[0]==0) { file->parentcluster = FAT32_GetRootCluster(); file->inRoot = TRUE; } else { file->inRoot = FALSE; // Find parent directory start cluster if (!_open_directory(file->path, &file->parentcluster)) return NULL; } // Check if same filename exists in directory if (FAT32_GetFileEntry(file->parentcluster, file->filename,&sfEntry)==TRUE) return NULL; // Create the file space for the file file->startcluster = 0; file->filelength = size; if (!FAT32_AllocateFreeSpace(TRUE, &file->startcluster, (file->filelength==0)?1:file->filelength)) return NULL; // Generate a short filename & tail tailNum = 0; do { // Create a standard short filename (without tail) FATMisc_CreateSFN(shortFilename, file->filename); // If second hit or more, generate a ~n tail if (tailNum!=0) FATMisc_GenerateTail((char*)file->shortfilename, shortFilename, tailNum); // Try with no tail if first entry else memcpy(file->shortfilename, shortFilename, 11); // Check if entry exists already or not if (FAT32_SFNexists(file->parentcluster, (char*)file->shortfilename)==FALSE) break; tailNum++; } while (tailNum<9999); if (tailNum==9999) return NULL; // Add file to disk if (!FAT32_AddFileEntry(file->parentcluster, (char*)file->filename, (char*)file->shortfilename, file->startcluster, file->filelength)) return NULL; // General file->bytenum = 0; file->currentBlock = 0xFFFFFFFF; file->inUse = TRUE; FAT32_PurgeFATBuffer(); return file; }
static FL_FILE* _create_file(const char *filename) { FL_FILE* file; struct fat_dir_entry sfEntry; char shortFilename[FAT_SFN_SIZE_FULL]; int tailNum = 0; // No write access? if (!_fs.disk_io.write_sector) return NULL; // Allocate a new file handle file = _allocate_file(); if (!file) return NULL; // Clear filename memset(file->path, '\0', sizeof(file->path)); memset(file->filename, '\0', sizeof(file->filename)); // Split full path into filename and directory path if (fatfs_split_path((char*)filename, file->path, sizeof(file->path), file->filename, sizeof(file->filename)) == -1) { _free_file(file); return NULL; } // Check if file already open if (_check_file_open(file)) { _free_file(file); return NULL; } // If file is in the root dir if (file->path[0] == 0) file->parentcluster = fatfs_get_root_cluster(&_fs); else { // Find parent directory start cluster if (!_open_directory(file->path, &file->parentcluster)) { _free_file(file); return NULL; } } // Check if same filename exists in directory if (fatfs_get_file_entry(&_fs, file->parentcluster, file->filename,&sfEntry) == 1) { _free_file(file); return NULL; } file->startcluster = 0; // Create the file space for the file (at least one clusters worth!) if (!fatfs_allocate_free_space(&_fs, 1, &file->startcluster, 1)) { _free_file(file); return NULL; } #if FATFS_INC_LFN_SUPPORT // Generate a short filename & tail tailNum = 0; do { // Create a standard short filename (without tail) fatfs_lfn_create_sfn(shortFilename, file->filename); // If second hit or more, generate a ~n tail if (tailNum != 0) fatfs_lfn_generate_tail((char*)file->shortfilename, shortFilename, tailNum); // Try with no tail if first entry else memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); // Check if entry exists already or not if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename) == 0) break; tailNum++; } while (tailNum < 9999); // We reached the max number of duplicate short file names (unlikely!) if (tailNum == 9999) { // Delete allocated space fatfs_free_cluster_chain(&_fs, file->startcluster); _free_file(file); return NULL; } #else // Create a standard short filename (without tail) if (!fatfs_lfn_create_sfn(shortFilename, file->filename)) { // Delete allocated space fatfs_free_cluster_chain(&_fs, file->startcluster); _free_file(file); return NULL; } // Copy to SFN space memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); // Check if entry exists already if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename)) { // Delete allocated space fatfs_free_cluster_chain(&_fs, file->startcluster); _free_file(file); return NULL; } #endif // Add file to disk if (!fatfs_add_file_entry(&_fs, file->parentcluster, (char*)file->filename, (char*)file->shortfilename, file->startcluster, 0, 0)) { // Delete allocated space fatfs_free_cluster_chain(&_fs, file->startcluster); _free_file(file); return NULL; } // General file->filelength = 0; file->bytenum = 0; file->file_data.address = 0xFFFFFFFF; file->file_data.dirty = 0; file->filelength_changed = 0; // Quick lookup for next link in the chain file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF; file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF; fatfs_cache_init(&_fs, file); fatfs_fat_purge(&_fs); return file; }
//----------------------------------------------------------------------------- // _open_file: Open a file for reading //----------------------------------------------------------------------------- static FL_FILE* _open_file(const char *path) { FL_FILE* file; struct fat_dir_entry sfEntry; // Allocate a new file handle file = _allocate_file(); if (!file) return NULL; // Clear filename memset(file->path, '\0', sizeof(file->path)); memset(file->filename, '\0', sizeof(file->filename)); // Split full path into filename and directory path if (fatfs_split_path((char*)path, file->path, sizeof(file->path), file->filename, sizeof(file->filename)) == -1) { _free_file(file); return NULL; } // Check if file already open if (_check_file_open(file)) { _free_file(file); return NULL; } // If file is in the root dir if (file->path[0]==0) file->parentcluster = fatfs_get_root_cluster(&_fs); else { // Find parent directory start cluster if (!_open_directory(file->path, &file->parentcluster)) { _free_file(file); return NULL; } } // Using dir cluster address search for filename if (fatfs_get_file_entry(&_fs, file->parentcluster, file->filename,&sfEntry)) // Make sure entry is file not dir! if (fatfs_entry_is_file(&sfEntry)) { // Initialise file details memcpy(file->shortfilename, sfEntry.Name, FAT_SFN_SIZE_FULL); file->filelength = sfEntry.FileSize; file->bytenum = 0; file->startcluster = (((unsigned long)sfEntry.FstClusHI)<<16) + sfEntry.FstClusLO; file->file_data.address = 0xFFFFFFFF; file->file_data.dirty = 0; file->filelength_changed = 0; // Quick lookup for next link in the chain file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF; file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF; fatfs_cache_init(&_fs, file); fatfs_fat_purge(&_fs); return file; } _free_file(file); return NULL; }