tinyfatfs/rtfslite.h
2015-10-11 13:58:55 -04:00

315 lines
12 KiB
C

/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright EBS Inc. 1987-2012
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
#ifndef __RTFSLITE__
#include <string.h>
#define ANSImemset memset
#define ANSImemcmp memcmp
#define ANSImemcpy memcpy
#define RTFSL_INCLUDE_SUBDIRECTORIES 1
#define RTFSL_INCLUDE_FAT32 1
#define RTFSL_INCLUDE_FAT12 1
#define RTFSL_INCLUDE_MBR_SUPPORT 1 /* 180 bytes, need 3rd option as well */
#define RTFSL_INCLUDE_WRITE_SUPPORT 1 /* XXX bytes */
#define RTFSL_INCLUDE_FAILSAFE_SUPPORT 1 /* XXX bytes */
#define RTFSL_INCLUDE_SECURE_DIGITAL 1
#define RTFSL_CFG_FILE_FRAG_BUFFER_SIZE 4
#define RTFSL_CFG_FSBUFFERSIZESECTORS 1
#define RTFSL_CFG_FSBUFFERSIZEBYTES (RTFSL_CFG_FSBUFFERSIZESECTORS*512)
#define RTFSL_CFG_NFILES 2
#define RTFSL_CFG_MAXBLOCKSIZE 512
#define RTFSL_CFG_NUMBUFFERS 2
/* Set this to 1 build a minimum system supporting only the API functions
rtfsl_load_file and rtfsl_setpath. If being able to load only from the root is
acceptable you can reduce footprint further by setting RTFSL_INCLUDE_SUBDIRECTORIES to 0 */
#define RTFSL_INCLUDE_LOAD_ONLY 0
#if (RTFSL_INCLUDE_LOAD_ONLY)
#undef RTFSL_INCLUDE_WRITE_SUPPORT
#undef RTFSL_INCLUDE_FAILSAFE_SUPPORT
#undef RTFSL_INCLUDE_SECURE_DIGITAL
#undef RTFSL_CFG_NFILES
#undef RTFSL_CFG_NUMBUFFERS
#define RTFSL_INCLUDE_WRITE_SUPPORT 0
#define RTFSL_INCLUDE_FAILSAFE_SUPPORT 0
#define RTFSL_INCLUDE_SECURE_DIGITAL 0
#define RTFSL_CFG_NFILES 1
#define RTFSL_CFG_NUMBUFFERS 1
#endif
#define RTFSL_ERROR_NONE 0
#define RTFSL_ERROR_ARGS -1
#define RTFSL_ERROR_CONSISTENCY -2
#define RTFSL_ERROR_DIR_FULL -3
#define RTFSL_ERROR_DISK_FULL -4
#define RTFSL_ERROR_FDALLOC -5
#define RTFSL_ERROR_FORMAT -6
#define RTFSL_ERROR_JOURNAL_FULL -7
#define RTFSL_ERROR_JOURNAL_NONE -8
#define RTFSL_ERROR_NOTFOUND -9
#define RTFSL_ERROR_PATH -10
#define RTFSL_ERROR_EXIST -11
#define RTFSL_ERROR_ENOTEMPTY -12
#define RTFSL_ERROR_TEST -13
#define RTFSL_ERROR_IO_WRITE_PROTECT -14
#define RTFSL_ERROR_IO_NO_MEDIA -15
#define RTFSL_ERROR_IO_ERROR -16
#define RTFSL_WRITE_CLUSTER 0x8000000
#define RTFSL_ALLOC_CLUSTER 0x4000000
#define RTFSL_MASK_COMMAND 0xC000000
#define RTFSL_JOURNALFULL_CLUSTER 0xffffffff
#define RTFSL_JOURNALDELETED_CLUSTER 0xfffffffe
#define RTFSL_FIO_OP_WRITE 0x01
#define RTFSL_FIO_OP_APPEND 0x02
void rtfsl_get_system_date(unsigned short *time, unsigned short *date);
int rtfsl_read_sectors(unsigned long sector,int count, unsigned char *buffer);
int rtfsl_write_sectors(unsigned long sector, int count, unsigned char *buffer);
struct rtfsl_dosinode {
unsigned char fname[8];
unsigned char fext[3];
unsigned char fattribute; /* File attributes */
unsigned char reservednt;
unsigned char create10msincrement;
unsigned short ctime; /* time & date create */
unsigned short cdate;
unsigned short adate; /* Date last accessed */
unsigned short fclusterhi; /* This is where fat32 stores file location */
unsigned short ftime; /* time & date lastmodified */
unsigned short fdate;
unsigned short fcluster; /* Cluster for data file */
unsigned long fsize; /* File size */
};
struct rtfsl_drive
{
unsigned long partition_base;
unsigned long partition_size;
unsigned long maxfindex;
unsigned long numsecs;
unsigned long secpfat;
unsigned long rootbegin;
unsigned long firstclblock;
unsigned long free_alloc;
unsigned long next_alloc;
unsigned long end_cluster_marker;
unsigned short bytespsector;
unsigned long bytespcluster;
unsigned short secreserved;
unsigned short numroot;
#define RTFSL_IOTYPE_FILE_FLAG 0x01
#define RTFSL_FAT_CHANGED_FLAG 0x02 /* For FAT32 systems this is set when freespece has changed and the infosec needs a flush */
unsigned short flags;
unsigned short infosec;
unsigned short backup;
unsigned char secpalloc;
unsigned char numfats;
unsigned char fasize;
unsigned char **pathnamearray;
};
struct rtfsl_file {
unsigned long sector;
struct rtfsl_dosinode dos_inode;
unsigned long file_pointer;
unsigned long file_pointer_at_segment_base;
unsigned long segment_size_bytes;
unsigned long next_segment_base;
unsigned long cluster_segment_array[RTFSL_CFG_FILE_FRAG_BUFFER_SIZE][2];
unsigned short index;
#define TRTFSFILE_ISROOT_DIR 0x01
#define TRTFSFILE_DIRTY 0x02
#define TRTFSFILE_SECTOR_REGION 0x04
#define TRTFSFILE_ALLOCATED 0x08
#define TRTFSFILE_ISMKDIR 0x10
unsigned char rtfsl_file_flags;
#define RTFSL_ENTRY_TYPE_ERASED 1 /* Must be power of 2. */
#define RTFSL_ENTRY_TYPE_DIRECTORY 2
#define RTFSL_ENTRY_TYPE_VOLUME 4
#define RTFSL_ENTRY_TYPE_LFN 8
#define RTFSL_ENTRY_TYPE_FILE 16
#define RTFSL_ENTRY_TYPE_EOF 32
#define RTFSL_ENTRY_AVAILABLE (RTFSL_ENTRY_TYPE_ERASED|RTFSL_ENTRY_TYPE_EOF)
unsigned char rtfsl_direntry_type;
};
/* Structure for use by rtfsl_gfirst, rtfsl_gnext */
struct rtfsl_dstat {
unsigned char fnameandext[12]; /* Null terminated file and extension */
unsigned char fattribute; /* File attributes */
unsigned short ftime; /* time & date lastmodified. See date */
unsigned short fdate; /* and time handlers for getting info */
unsigned short ctime; /* time & date created */
unsigned short cdate;
unsigned short atime; /* time & date accessed */
unsigned short adate; /* Date last accessed */
unsigned long fsize; /* File size */
/* INTERNAL */
struct rtfsl_file directory_file;
struct rtfsl_file current_matched_file;
unsigned char *nametomatch;
};
/* Structure for use by rtfsl_stat and rtfsl_fstat */
struct rtfsl_statstructure
{
int st_dev; /* (0) */
int st_ino; /* (0) */
unsigned long st_mode; /* (0) */
int st_nlink; /* (0) */
int st_rdev; /* (0) */
unsigned long st_size; /* file size, in bytes */
unsigned long st_atime; /* last access date in high 16 bits */
unsigned long st_mtime; /* last modification date|time */
unsigned long st_ctime; /* file create date|time */
unsigned long st_blksize; /* optimal blocksize for I/O (cluster size) */
unsigned long st_blocks; /* blocks allocated for file */
unsigned char fattribute; /* File attributes - DOS attributes
(non standard but useful) */
};
#define PCDELETE (unsigned char) 0xE5
#define ARDONLY 0x1 /* MS-DOS File attributes */
#define AHIDDEN 0x2
#define ASYSTEM 0x4
#define AVOLUME 0x8
#define ADIRENT 0x10
#define ARCHIVE 0x20
#define ANORMAL 0x00
#define CHICAGO_EXT 0x0f /* Chicago extended filename attribute */
#define PSEEK_SET 0 /* offset from begining of file*/
#define PSEEK_CUR 1 /* offset from current file pointer*/
#define PSEEK_END 2 /* offset from end of file*/
unsigned long to_ULONG( unsigned char *from);
unsigned short to_USHORT( unsigned char *from);
void fr_USHORT(unsigned char *to, unsigned short from);
void fr_ULONG(unsigned char *to, unsigned long from);
int rtfsl_diskopen(void);
unsigned long rtfsl_cl2sector(unsigned long cluster);
int rtfsl_finode_get( struct rtfsl_file *pfile, unsigned long sector, unsigned short index);
unsigned long rtfsl_sec2cluster( unsigned long sector);
int rtfsl_finode_open(struct rtfsl_file *pfile);
int rtfsl_root_finode_open(struct rtfsl_file *pfile);
long rtfsl_load_next_segment(struct rtfsl_file *pfile,unsigned long current_cluster);
typedef int (*DirScanCallback) (struct rtfsl_file const *pcurrent_entry_file, void *puser_data);
typedef unsigned long (*FileScanCallback) (struct rtfsl_file const *pfile, unsigned long start_sector, unsigned long nbytes, void *puser_data);
int rtfsl_enumerate_file(struct rtfsl_file *pfile,FileScanCallback pCallback, void *puser_data);
int rtfsl_enumerate_directory(struct rtfsl_file *pdirectory_file,struct rtfsl_file *pcurrent_entry_file,DirScanCallback pCallback, void *puser_data);
int rtfsl_read_sector_buffer(unsigned long sector);
int rtfsl_flush_sector_buffer(int bufferhandle,int force);
void rtfsl_mark_sector_buffer(int bufferhandle);
int rtfsl_flush_all_buffers(void);
int fatop_buff_get_frag(unsigned long current_cluster, unsigned long *pnext_cluster, unsigned long max_length);
int rtfsl_open_path(unsigned char **pathlist,unsigned char *pentryname, struct rtfsl_file *directory_file, struct rtfsl_file *ptarget_file);
int rtfsl_clzero(unsigned long cluster);
int rtfsl_load_file(unsigned char *filename, unsigned long load_address);
void rtfsl_setpath(unsigned char **pathnamearray);
int rtfsl_gfirst(struct rtfsl_dstat *statobj, unsigned char *name);
int rtfsl_gnext(struct rtfsl_dstat *statobj);
void rtfsl_done(struct rtfsl_dstat *statobj);
int rtfsl_alloc_fd(void);
int _rtfsl_open(unsigned char *name,unsigned char attributes);
int rtfsl_open(unsigned char *name);
#define rtfsl_dir_open(N) _rtfsl_open(N,ADIRENT)
int rtfsl_read(int fd, unsigned char *in_buff, int count);
int rtfsl_close(int fd);
long rtfsl_lseek(int fd, long offset, int origin);
int rtfsl_fstat(int fd, struct rtfsl_statstructure *pstat);
int rtfsl_write(int fd, unsigned char *in_buff, int count);
int rtfsl_flush(int fd);
int rtfsl_flush_info_sec(void);
int rtfsl_create(unsigned char *name, unsigned char attribute);
int rtfsl_mkdir (unsigned char *name);
int rtfsl_rmdir(unsigned char *name);
int _rtfsl_delete(unsigned char *name, unsigned char attribute);
int rtfsl_delete(unsigned char *name);
int rtfsl_rename(unsigned char *name, unsigned char *newname);
unsigned long rtfslfs_cluster_remap(unsigned long cluster,unsigned long value);
int rtfslfs_cluster_map(unsigned long cluster,unsigned long value);
int rtfslfs_dirent_remap(unsigned long sector,unsigned long index, struct rtfsl_dosinode *p_dos_inode,int reading);
#define RTFSLFS_JTEST 1
#define RTFSLFS_JCLEAR 2
#define RTFSLFS_JREAD 3
#define RTFSLFS_JWRITE 4
int rtfslfs_start(void);
int rtfslfs_flush(void);
int rtfslfs_restore(void);
int rtfslfs_sync(void);
int rtfslfs_access_journal(int command);
#if (RTFSL_INCLUDE_FAILSAFE_SUPPORT)
typedef unsigned long treplacement_record[2];
struct rtfsl_failsafe_context {
/* Current cache */
int journal_buffer_size;
int journal_buffer_free;
unsigned char *journal_buffer;
#define REPLACEMENT_RECORD_SIZE_BYTES 8
#define REPLACEMENT_DOSINODESIZE_SIZE_BYTES 32
unsigned long *preplacement_record_count; /* The first entry in the journal is reserved for replacement_record_count:replacement_dosinode_count */
unsigned long *pcurrent_dosinode_offset; /* The second entry in the journal is reserved for replacement_record_count:replacement_dosinode_count */
treplacement_record *preplacement_records;
#define RTFSLFS_WRITE_DIRENTRY 0x1
#define RTFSLFS_MAPPED_CL_FOUND 0x2
unsigned char flags;
};
#endif
extern const char *dotname;
extern const char *dotdotname;
extern const unsigned char end_name[11];
struct rtfsl_context {
struct rtfsl_drive current_dr;
struct rtfsl_file rtfsl_files[RTFSL_CFG_NFILES];
unsigned long current_buffered_sectors[RTFSL_CFG_NUMBUFFERS];
unsigned char buffer_pool_agingstack[RTFSL_CFG_NUMBUFFERS];
unsigned char *pcurrent_buffer_pool;
unsigned long buffer_pool_dirty;
#if (RTFSL_INCLUDE_SECURE_DIGITAL)
unsigned long buffer_isfiledata;
#endif
#if (RTFSL_INCLUDE_FAILSAFE_SUPPORT)
struct rtfsl_failsafe_context rtfsl_failsafe_context;
unsigned char rtfslfs_sector_buffer[RTFSL_CFG_FSBUFFERSIZEBYTES];
struct rtfsl_failsafe_context *rtfsl_current_failsafe_context;
#endif
};
extern struct rtfsl_context rtfsl;
extern unsigned char rtfsl_sector_buffer[];
#define rtfsl_buffer_address(H) rtfsl.pcurrent_buffer_pool+((H)*rtfsl.current_dr.bytespsector)
#endif /* __RTFSLITE__ */