#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-function" struct fatfs_ctx; #define __FAT_ACCESS_H__ #define __FAT_DEFS_H__ #define __FAT_OPTS_H__ #define FATFS_IS_LITTLE_ENDIAN 1 #define FATFS_MAX_LONG_FILENAME 260 #define FATFS_MAX_OPEN_FILES 2 #define FAT_BUFFER_SECTORS 1 #define FAT_BUFFERS 1 #define FATFS_INC_WRITE_SUPPORT 1 #define FATFS_INC_LFN_SUPPORT 1 #define FATFS_DIR_LIST_SUPPORT 1 #define FATFS_INC_TIME_DATE_SUPPORT 0 #define FATFS_INC_FORMAT_SUPPORT 1 #define FAT_SECTOR_SIZE 512 #define __FAT_TYPES_H__ #define FATFS_DEF_UINT32_AS_INT typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; #define NULL 0 #define FAT_HTONS(n) (n) #define FAT_HTONL(n) (n) #define STRUCT_PACK #define STRUCT_PACK_BEGIN #define STRUCT_PACK_END #define STRUCT_PACKED __attribute__ ((packed)) #define BS_JMPBOOT 0 #define BS_OEMNAME 3 #define BPB_BYTSPERSEC 11 #define BPB_SECPERCLUS 13 #define BPB_RSVDSECCNT 14 #define BPB_NUMFATS 16 #define BPB_ROOTENTCNT 17 #define BPB_TOTSEC16 19 #define BPB_MEDIA 21 #define BPB_FATSZ16 22 #define BPB_SECPERTRK 24 #define BPB_NUMHEADS 26 #define BPB_HIDDSEC 28 #define BPB_TOTSEC32 32 #define BS_FAT_DRVNUM 36 #define BS_FAT_BOOTSIG 38 #define BS_FAT_VOLID 39 #define BS_FAT_VOLLAB 43 #define BS_FAT_FILSYSTYPE 54 #define BPB_FAT32_FATSZ32 36 #define BPB_FAT32_EXTFLAGS 40 #define BPB_FAT32_FSVER 42 #define BPB_FAT32_ROOTCLUS 44 #define BPB_FAT32_FSINFO 48 #define BPB_FAT32_BKBOOTSEC 50 #define BS_FAT32_DRVNUM 64 #define BS_FAT32_BOOTSIG 66 #define BS_FAT32_VOLID 67 #define BS_FAT32_VOLLAB 71 #define BS_FAT32_FILSYSTYPE 82 #define FAT_TYPE_FAT12 1 #define FAT_TYPE_FAT16 2 #define FAT_TYPE_FAT32 3 #define SIGNATURE_POSITION 510 #define SIGNATURE_VALUE 0xAA55 #define PARTITION1_TYPECODE_LOCATION 450 #define FAT32_TYPECODE1 0x0B #define FAT32_TYPECODE2 0x0C #define PARTITION1_LBA_BEGIN_LOCATION 454 #define PARTITION1_SIZE_LOCATION 458 #define FAT_DIR_ENTRY_SIZE 32 #define FAT_SFN_SIZE_FULL 11 #define FAT_SFN_SIZE_PARTIAL 8 #define FILE_ATTR_READ_ONLY 0x01 #define FILE_ATTR_HIDDEN 0x02 #define FILE_ATTR_SYSTEM 0x04 #define FILE_ATTR_SYSHID 0x06 #define FILE_ATTR_VOLUME_ID 0x08 #define FILE_ATTR_DIRECTORY 0x10 #define FILE_ATTR_ARCHIVE 0x20 #define FILE_ATTR_LFN_TEXT 0x0F #define FILE_HEADER_BLANK 0x00 #define FILE_HEADER_DELETED 0xE5 #define FILE_TYPE_DIR 0x10 #define FILE_TYPE_FILE 0x20 #define FAT_TIME_HOURS_SHIFT 11 #define FAT_TIME_HOURS_MASK 0x1F #define FAT_TIME_MINUTES_SHIFT 5 #define FAT_TIME_MINUTES_MASK 0x3F #define FAT_TIME_SECONDS_SHIFT 0 #define FAT_TIME_SECONDS_MASK 0x1F #define FAT_TIME_SECONDS_SCALE 2 #define FAT_DATE_YEAR_SHIFT 9 #define FAT_DATE_YEAR_MASK 0x7F #define FAT_DATE_MONTH_SHIFT 5 #define FAT_DATE_MONTH_MASK 0xF #define FAT_DATE_DAY_SHIFT 0 #define FAT_DATE_DAY_MASK 0x1F #define FAT_DATE_YEAR_OFFSET 1980 #define FAT32_LAST_CLUSTER 0xFFFFFFFF #define FAT32_INVALID_CLUSTER 0xFFFFFFFF STRUCT_PACK_BEGIN struct fat_dir_entry STRUCT_PACK { uint8 Name[11]; uint8 Attr; uint8 NTRes; uint8 CrtTimeTenth; uint8 CrtTime[2]; uint8 CrtDate[2]; uint8 LstAccDate[2]; uint16 FstClusHI; uint8 WrtTime[2]; uint8 WrtDate[2]; uint16 FstClusLO; uint32 FileSize; } STRUCT_PACKED; STRUCT_PACK_END #define FAT_INIT_OK 0 #define FAT_INIT_MEDIA_ACCESS_ERROR (-1) #define FAT_INIT_INVALID_SECTOR_SIZE (-2) #define FAT_INIT_INVALID_SIGNATURE (-3) #define FAT_INIT_ENDIAN_ERROR (-4) #define FAT_INIT_WRONG_FILESYS_TYPE (-5) #define FAT_INIT_WRONG_PARTITION_TYPE (-6) #define FAT_INIT_STRUCT_PACKING (-7) #define FAT_DIR_ENTRIES_PER_SECTOR (FAT_SECTOR_SIZE / FAT_DIR_ENTRY_SIZE) typedef int (*fn_diskio_read) (struct fatfs_ctx* ctx, uint32 sector, uint8* buffer, uint32 sector_count); typedef int (*fn_diskio_write) (struct fatfs_ctx* ctx, uint32 sector, uint8* buffer, uint32 sector_count); struct disk_if { fn_diskio_read read_media; fn_diskio_write write_media; }; struct fat_buffer; struct fat_buffer { uint8 sector[FAT_SECTOR_SIZE * FAT_BUFFER_SECTORS]; uint32 address; int dirty; uint8* ptr; struct fat_buffer* next; }; typedef enum eFatType { FAT_TYPE_16, FAT_TYPE_32 } tFatType; struct fatfs { uint8 sectors_per_cluster; uint32 cluster_begin_lba; uint32 rootdir_first_cluster; uint32 rootdir_first_sector; uint32 rootdir_sectors; uint32 fat_begin_lba; uint16 fs_info_sector; uint32 lba_begin; uint32 fat_sectors; uint32 next_free_cluster; uint16 root_entry_count; uint16 reserved_sectors; uint8 num_of_fats; tFatType fat_type; struct disk_if disk_io; void (*fl_lock) (void); void (*fl_unlock) (void); struct fat_buffer currentsector; struct fat_buffer* fat_buffer_head; struct fat_buffer fat_buffers[FAT_BUFFERS]; }; struct fs_dir_list_status { uint32 sector; uint32 cluster; uint8 offset; }; struct fs_dir_ent { char filename[FATFS_MAX_LONG_FILENAME]; uint8 is_dir; uint32 cluster; uint32 size; }; int fatfs_init (struct fatfs_ctx* ctx, struct fatfs* fs); uint32 fatfs_lba_of_cluster (struct fatfs* fs, uint32 Cluster_Number); int fatfs_sector_reader (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Startcluster, uint32 offset, uint8* target); int fatfs_sector_read (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 lba, uint8* target, uint32 count); int fatfs_sector_write (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 lba, uint8* target, uint32 count); int fatfs_read_sector (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 cluster, uint32 sector, uint8* target); int fatfs_write_sector (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 cluster, uint32 sector, uint8* target); void fatfs_show_details (struct fatfs* fs); uint32 fatfs_get_root_cluster (struct fatfs* fs); uint32 fatfs_get_file_entry (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Cluster, char* nametofind, struct fat_dir_entry* sfEntry); int fatfs_sfn_exists (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Cluster, char* shortname); int fatfs_update_file_length (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Cluster, char* shortname, uint32 fileLength); int fatfs_mark_file_deleted (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Cluster, char* shortname); void fatfs_list_directory_start (struct fatfs* fs, struct fs_dir_list_status* dirls, uint32 StartCluster); int fatfs_list_directory_next (struct fatfs_ctx* ctx, struct fatfs* fs, struct fs_dir_list_status* dirls, struct fs_dir_ent* entry); int fatfs_update_timestamps (struct fat_dir_entry* directoryEntry, int create, int modify, int access); #define __FAT_FORMAT_H__ int fatfs_format (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 volume_sectors, const char* name); int fatfs_format_fat16 (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 volume_sectors, const char* name); int fatfs_format_fat32 (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 volume_sectors, const char* name); #define __FAT_MISC_H__ #define MAX_LONGFILENAME_ENTRIES 20 #define MAX_LFN_ENTRY_LENGTH 13 #define GET_32BIT_WORD(buffer, location) \ (((uint32)buffer[location + 3] << 24) + ((uint32)buffer[location + 2] << 16) + \ ((uint32)buffer[location + 1] << 8) + (uint32)buffer[location + 0]) #define GET_16BIT_WORD(buffer, location) \ (((uint16)buffer[location + 1] << 8) + (uint16)buffer[location + 0]) #define SET_32BIT_WORD(buffer, location, value) \ { \ buffer[location + 0] = (uint8)((value) & 0xFF); \ buffer[location + 1] = (uint8)((value >> 8) & 0xFF); \ buffer[location + 2] = (uint8)((value >> 16) & 0xFF); \ buffer[location + 3] = (uint8)((value >> 24) & 0xFF); \ } #define SET_16BIT_WORD(buffer, location, value) \ { \ buffer[location + 0] = (uint8)((value) & 0xFF); \ buffer[location + 1] = (uint8)((value >> 8) & 0xFF); \ } struct lfn_cache { uint8 String[MAX_LONGFILENAME_ENTRIES][MAX_LFN_ENTRY_LENGTH]; uint8 Null; uint8 no_of_strings; }; void fatfs_lfn_cache_init (struct lfn_cache* lfn, int wipeTable); void fatfs_lfn_cache_entry (struct lfn_cache* lfn, uint8* entryBuffer); char* fatfs_lfn_cache_get (struct lfn_cache* lfn); int fatfs_entry_lfn_text (struct fat_dir_entry* entry); int fatfs_entry_lfn_invalid (struct fat_dir_entry* entry); int fatfs_entry_lfn_exists (struct lfn_cache* lfn, struct fat_dir_entry* entry); int fatfs_entry_sfn_only (struct fat_dir_entry* entry); int fatfs_entry_is_dir (struct fat_dir_entry* entry); int fatfs_entry_is_file (struct fat_dir_entry* entry); int fatfs_lfn_entries_required (char* filename); void fatfs_filename_to_lfn (char* filename, uint8* buffer, int entry, uint8 sfnChk); void fatfs_sfn_create_entry (char* shortfilename, uint32 size, uint32 startCluster, struct fat_dir_entry* entry, int dir); int fatfs_lfn_create_sfn (char* sfn_output, char* filename); int fatfs_lfn_generate_tail (char* sfn_output, char* sfn_input, uint32 tailNum); void fatfs_convert_from_fat_time (uint16 fat_time, int* hours, int* minutes, int* seconds); void fatfs_convert_from_fat_date (uint16 fat_date, int* day, int* month, int* year); uint16 fatfs_convert_to_fat_time (int hours, int minutes, int seconds); uint16 fatfs_convert_to_fat_date (int day, int month, int year); void fatfs_print_sector (uint32 sector, uint8* data); #define __FILESTRING_H__ int fatfs_total_path_levels (char* path); int fatfs_get_substring (char* Path, int levelreq, char* output, int max_len); int fatfs_split_path (char* FullPath, char* Path, int max_path, char* FileName, int max_filename); int fatfs_compare_names (char* strA, char* strB); int fatfs_string_ends_with_slash (char* path); int fatfs_get_sfn_display_name (char* out, char* in); int fatfs_get_extension (char* filename, char* out, int maxlen); int fatfs_create_path_string (char* path, char* filename, char* out, int maxlen); #define __FAT_CACHE_H__ #define __FAT_FILELIB_H__ #define __FAT_LIST_H__ #define FAT_ASSERT(x) #define FAT_INLINE struct fat_list; struct fat_node { struct fat_node* previous; struct fat_node* next; }; struct fat_list { struct fat_node* head; struct fat_node* tail; }; #define fat_list_entry(p, t, m) p ? ((t*)((char*)(p) - (char*)(&((t*)0)->m))) : 0 #define fat_list_next(l, p) (p)->next #define fat_list_prev(l, p) (p)->previous #define fat_list_first(l) (l)->head #define fat_list_last(l) (l)->tail #define fat_list_for_each(l, p) for ((p) = (l)->head; (p); (p) = (p)->next) static FAT_INLINE void fat_list_init (struct fat_list* list) { FAT_ASSERT (list); list->head = list->tail = 0; } static FAT_INLINE void fat_list_remove (struct fat_list* list, struct fat_node* node) { FAT_ASSERT (list); FAT_ASSERT (node); if (!node->previous) list->head = node->next; else node->previous->next = node->next; if (!node->next) list->tail = node->previous; else node->next->previous = node->previous; } static FAT_INLINE void fat_list_insert_after (struct fat_list* list, struct fat_node* node, struct fat_node* new_node) { FAT_ASSERT (list); FAT_ASSERT (node); FAT_ASSERT (new_node); new_node->previous = node; new_node->next = node->next; if (!node->next) list->tail = new_node; else node->next->previous = new_node; node->next = new_node; } static FAT_INLINE void fat_list_insert_before (struct fat_list* list, struct fat_node* node, struct fat_node* new_node) { FAT_ASSERT (list); FAT_ASSERT (node); FAT_ASSERT (new_node); new_node->previous = node->previous; new_node->next = node; if (!node->previous) list->head = new_node; else node->previous->next = new_node; node->previous = new_node; } static FAT_INLINE void fat_list_insert_first (struct fat_list* list, struct fat_node* node) { FAT_ASSERT (list); FAT_ASSERT (node); if (!list->head) { list->head = node; list->tail = node; node->previous = 0; node->next = 0; } else fat_list_insert_before (list, list->head, node); } static FAT_INLINE void fat_list_insert_last (struct fat_list* list, struct fat_node* node) { FAT_ASSERT (list); FAT_ASSERT (node); if (!list->tail) fat_list_insert_first (list, node); else fat_list_insert_after (list, list->tail, node); } static FAT_INLINE int fat_list_is_empty (struct fat_list* list) { FAT_ASSERT (list); return !list->head; } static FAT_INLINE struct fat_node* fat_list_pop_head (struct fat_list* list) { struct fat_node* node; FAT_ASSERT (list); node = fat_list_first (list); if (node) fat_list_remove (list, node); return node; } #define SEEK_CUR 1 #define SEEK_END 2 #define SEEK_SET 0 #define EOF (-1) struct sFL_FILE; struct cluster_lookup { uint32 ClusterIdx; uint32 CurrentCluster; }; typedef struct sFL_FILE { uint32 parentcluster; uint32 startcluster; uint32 bytenum; uint32 filelength; int filelength_changed; char path[FATFS_MAX_LONG_FILENAME]; char filename[FATFS_MAX_LONG_FILENAME]; uint8 shortfilename[11]; struct cluster_lookup last_fat_lookup; uint8 file_data_sector[FAT_SECTOR_SIZE]; uint32 file_data_address; int file_data_dirty; uint8 flags; #define FILE_READ (1 << 0) #define FILE_WRITE (1 << 1) #define FILE_APPEND (1 << 2) #define FILE_BINARY (1 << 3) #define FILE_ERASE (1 << 4) #define FILE_CREATE (1 << 5) struct fat_node list_node; } FL_FILE; void fl_init (struct fatfs_ctx* ctx); void fl_attach_locks (struct fatfs_ctx* ctx, void (*lock) (void), void (*unlock) (void)); int fl_attach_media (struct fatfs_ctx* ctx, fn_diskio_read rd, fn_diskio_write wr); void fl_shutdown (struct fatfs_ctx* ctx); void* fl_fopen (struct fatfs_ctx* ctx, const char* path, const char* modifiers); void fl_fclose (struct fatfs_ctx* ctx, void* file); int fl_fflush (struct fatfs_ctx* ctx, void* file); int fl_fgetc (struct fatfs_ctx* ctx, void* file); char* fl_fgets (struct fatfs_ctx* ctx, char* s, int n, void* f); int fl_fputc (struct fatfs_ctx* ctx, int c, void* file); int fl_fputs (struct fatfs_ctx* ctx, const char* str, void* file); int fl_fwrite (struct fatfs_ctx* ctx, const void* data, int size, int count, void* file); int fl_fread (struct fatfs_ctx* ctx, void* data, int size, int count, void* file); int fl_fseek (struct fatfs_ctx* ctx, void* file, long offset, int origin); int fl_fgetpos (struct fatfs_ctx* ctx, void* file, uint32* position); long fl_ftell (struct fatfs_ctx* ctx, void* f); int fl_feof (struct fatfs_ctx* ctx, void* f); int fl_remove (struct fatfs_ctx* ctx, const char* filename); typedef struct fs_dir_list_status FL_DIR; typedef struct fs_dir_ent fl_dirent; FL_DIR* fl_opendir (struct fatfs_ctx* ctx, const char* path, FL_DIR* dir); int fl_readdir (struct fatfs_ctx* ctx, FL_DIR* dirls, fl_dirent* entry); int fl_closedir (struct fatfs_ctx* ctx, FL_DIR* dir); void fl_listdirectory (struct fatfs_ctx* ctx, const char* path); int fl_createdirectory (struct fatfs_ctx* ctx, const char* path); int fl_is_dir (struct fatfs_ctx* ctx, const char* path); int fl_format (struct fatfs_ctx* ctx, uint32 volume_sectors, const char* name); int fatfs_cache_init (struct fatfs* fs, FL_FILE* file); int fatfs_cache_get_next_cluster (struct fatfs* fs, FL_FILE* file, uint32 clusterIdx, uint32* pNextCluster); int fatfs_cache_set_next_cluster (struct fatfs* fs, FL_FILE* file, uint32 clusterIdx, uint32 nextCluster); #define __FAT_TABLE_H__ void fatfs_fat_init (struct fatfs* fs); int fatfs_fat_purge (struct fatfs_ctx* ctx, struct fatfs* fs); uint32 fatfs_find_next_cluster (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 current_cluster); void fatfs_set_fs_info_next_free_cluster (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 newValue); int fatfs_find_blank_cluster (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 start_cluster, uint32* free_cluster); int fatfs_fat_set_cluster (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 cluster, uint32 next_cluster); int fatfs_fat_add_cluster_to_chain (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 start_cluster, uint32 newEntry); int fatfs_free_cluster_chain (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 start_cluster); uint32 fatfs_count_free_clusters (struct fatfs_ctx* ctx, struct fatfs* fs); #define __FAT_WRITE_H__ int fatfs_add_file_entry (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 dirCluster, char* filename, char* shortfilename, uint32 startCluster, uint32 size, int dir); int fatfs_add_free_space (struct fatfs_ctx* ctx, struct fatfs* fs, uint32* startCluster, uint32 clusters); int fatfs_allocate_free_space (struct fatfs_ctx* ctx, struct fatfs* fs, int newFile, uint32* startCluster, uint32 size); #pragma clang diagnostic pop