⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesys.c

📁 一个小型的FAT文件系统,支持FAT12/16和目录
💻 C
📖 第 1 页 / 共 2 页
字号:


#include	<stdlib.h>
#include	<string.h>
#include	"filesys.h"
#include	"fsysdef.h"



/********************************************************************************
	MACRO DEFINE
 ********************************************************************************/

#define	DRIVE_NAME_MAX		8
#define	FILE_MAX			5
#define	FULLPATH_MAX		80		/* drive name + directory name */
/********************************************************************************
	TYPE DEFINE
 ********************************************************************************/



/********************************************************************************
	VARIABLE DATA DEFINE
 ********************************************************************************/
#ifdef	FILE_DEBUG
#define	STATIC
#else
#define	STATIC	static
#endif	/* NET_DEBUG */

STATIC UCHAR	init_flag;
STATIC int		fsysError;
STATIC UCHAR	currDrive;
STATIC UCHAR	entryDrive;
STATIC FFILE	fileRes[FILE_MAX];

/********************************************************************************
	PROTO TYPE DECLARATION
 ********************************************************************************/
static void InitFileSys(void);
static void InitFileRes(void);
static int CheckDrive(const char *path, char **path2);
static int CheckPath(const char *path, UCHAR *driveNum, char **path2);


/********************************************************************************
	GLOBAL FUNCTIONS
 ********************************************************************************/
/*-----------------------------------------------------------------------------*/
int fsInit(const char *driveName)
{
	const DRIVE_TBL	*drive;
	int			driveNum, ret;

	if (driveName == NULL) {
		init_flag = 0;
		InitFileSys();
		return E_FILE_OK;
	}

	driveNum = CheckDrive(driveName, NULL);
	if (driveNum < 0) {
		return E_FILE_DRIVE;
	}

	if (init_flag == 0) {
		init_flag = 1;
		currDrive = entryDrive = (UCHAR)driveNum;
		fsysError = 0;
		InitFileRes();
	}

	drive = &driveTbl[driveNum];
#ifdef FILE_DEBUG
	if (drive->fsysAPI->init == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif
	ret = drive->fsysAPI->init(drive->subDriveNum);
	if (ret < 0) {
		return ret;
	}

	return E_FILE_OK;
}

/*-----------------------------------------------------------------------------*/
FFILE *fsOpen(const char *path, const char *mode)
{
	char		*path2;
	UCHAR		driveNum;
	int			i, fd, ret;
	FFILE		*stream;
	const DRIVE_TBL	*drive;

	if (CheckPath(path, &driveNum, &path2) < 0) {
		fsysError = E_FILE_DRIVE;
		return NULL;
	}

	if (!((*mode == 'r' || *mode == 'w' || *mode == 'a') && *(mode+1) == '\0')) {
		fsysError = E_FILE_PARAMETER;
		return NULL;
	}

	/* Get file resource */
	for(i = 0; i < FILE_MAX; i++) {
		if (fileRes[i].use_flag == 0) {
			break;
		}
	}
	if (i == FILE_MAX) {
		fsysError = E_FILE_RESOURCE;
		return NULL;
	}
	stream = &fileRes[i];
	drive = &driveTbl[driveNum];

	if (*mode == 'r') {
#ifdef FILE_DEBUG
		if (drive->fsysAPI->open == NULL) {
			fsysError = E_FILE_NOT_SUPPORT;
			return NULL;
		}
#endif
		fd = drive->fsysAPI->open(drive->subDriveNum, (UCHAR*)path2, OPEN_RD);
	}
	else if (*mode == 'w') {
#ifdef FILE_DEBUG
		if (drive->fsysAPI->open == NULL ||
			drive->fsysAPI->remove == NULL ||
			drive->fsysAPI->create == NULL
		{
			fsysError = E_FILE_NOT_SUPPORT;
			return NULL;
		}
#endif
		ret = drive->fsysAPI->create(drive->subDriveNum, (UCHAR*)path2);
		if (ret < 0) {
			if (ret == E_FILE_EXIST) {
				ret = drive->fsysAPI->remove(drive->subDriveNum, (UCHAR*)path2);
				if (ret < 0) {
					fsysError = ret;
					return NULL;
				}
				drive->fsysAPI->create(drive->subDriveNum, (UCHAR*)path2);
			}
			else {
				fsysError = ret;
				return NULL;
			}
		}
		fd = drive->fsysAPI->open(drive->subDriveNum, (UCHAR*)path2, OPEN_WR);
	}
	else {	/* *mode == 'a' */
#ifdef FILE_DEBUG
		if (drive->fsysAPI->open == NULL ||
			drive->fsysAPI->create == NULL ||
			drive->fsysAPI->seek == NULL
		{
			fsysError = E_FILE_NOT_SUPPORT;
			return NULL;
		}
#endif
		fd = drive->fsysAPI->open(drive->subDriveNum, (UCHAR*)path2, OPEN_WR);
		if (fd < 0) {
			if (fd == E_FILE_PATH) {
				ret = drive->fsysAPI->create(drive->subDriveNum, (UCHAR*)path2);
				if (ret < 0) {
					fsysError = ret;
					return NULL;
				}
				fd = drive->fsysAPI->open(drive->subDriveNum, (UCHAR*)path2, OPEN_WR);
			}
			else {
				fsysError = ret;
				return NULL;
			}
		}
		else {
			drive->fsysAPI->seek(fd, 0, SEEK_END, NULL);
		}
	}
	if (fd < 0) {
		fsysError = fd;
		return NULL;
	}
	stream->use_flag = 1;
	stream->descriptor = fd;
	stream->driveNum = driveNum;

	return stream;
}

/*-----------------------------------------------------------------------------*/
int fsClose(FFILE *stream)
{
	const DRIVE_TBL	*drive;
	int			ret;

	if (!(stream >= &fileRes[0] && stream <= &fileRes[FILE_MAX-1])) {
		return E_FILE_STREAM;
	}
	if (stream->use_flag == 0) {
		return E_FILE_CLOSED;
	}
	drive = &driveTbl[stream->driveNum];

#ifdef FILE_DEBUG
	if (drive->fsysAPI->close == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif

	ret = drive->fsysAPI->close(stream->descriptor);
	return ret;
}

/*-----------------------------------------------------------------------------*/
/*
 big-endian偵曄偊傞応崌丄1僨乕僞偺暲傃傪媡偵偡傞昁梫偁傝乮婎杮偼size=1偺傒僒億乕僩乯丅
 write娭悢傕摨條丅
*/

int fsRead(void *buf, int size, int count, FFILE *stream)
{
	const DRIVE_TBL	*drive;
	int			ret;

	if (!(stream >= &fileRes[0] && stream <= &fileRes[FILE_MAX-1])) {
		return E_FILE_STREAM;
	}
	if (stream->use_flag == 0) {
		return E_FILE_CLOSED;
	}
	drive = &driveTbl[stream->driveNum];

#ifdef FILE_DEBUG
	if (drive->fsysAPI->read == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif

	ret = drive->fsysAPI->read((UCHAR*)buf, size*count, stream->descriptor);

	if (ret < 0) {
		return ret;
	}
	return ret/size;
}


/*-----------------------------------------------------------------------------*/
int fsWrite(const void *buf, int size, int count, FFILE *stream)
{
	const DRIVE_TBL	*drive;
	int			ret;

	if (!(stream >= &fileRes[0] && stream <= &fileRes[FILE_MAX-1])) {
		return E_FILE_STREAM;
	}
	if (stream->use_flag == 0) {
		return E_FILE_CLOSED;
	}
	drive = &driveTbl[stream->driveNum];

#ifdef FILE_DEBUG
	if (drive->fsysAPI->write == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif

	ret = drive->fsysAPI->write((UCHAR*)buf, size*count, stream->descriptor);

	if (ret < 0) {
		return ret;
	}
	return ret/size;
}


/*-----------------------------------------------------------------------------*/
int fsGetc(FFILE *stream)
{
	const DRIVE_TBL	*drive;
	int			ret;
	UCHAR		c;

	if (!(stream >= &fileRes[0] && stream <= &fileRes[FILE_MAX-1])) {
		return E_FILE_STREAM;
	}
	if (stream->use_flag == 0) {
		return E_FILE_CLOSED;
	}
	drive = &driveTbl[stream->driveNum];

#ifdef FILE_DEBUG
	if (drive->fsysAPI->read == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif

	ret = drive->fsysAPI->read(&c, 1, stream->descriptor);
	if (ret > 0) {
		return (int)c;
	}
	else if (ret == 0) {
		return E_FILE_EOF;
	}
	else {	/* ret < 0 */
		return ret;
	}
}

/*-----------------------------------------------------------------------------*/
int fsPutc(int c, FFILE *stream)
{
	const DRIVE_TBL	*drive;
	int			ret;

	if (!(stream >= &fileRes[0] && stream <= &fileRes[FILE_MAX-1])) {
		return E_FILE_STREAM;
	}
	if (stream->use_flag == 0) {
		return E_FILE_CLOSED;
	}
	drive = &driveTbl[stream->driveNum];

#ifdef FILE_DEBUG
	if (drive->fsysAPI->write == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif

	ret = drive->fsysAPI->write((UCHAR*)&c, 1, stream->descriptor);
	if (ret > 0) {
		return c;
	}
	else if (ret == 0) {
		return E_FILE_DISK_FULL;
	}
	else {	/* ret < 0 */
		return ret;
	}
}

/*-----------------------------------------------------------------------------*/
int fsFlush(FFILE *stream)
{
	const DRIVE_TBL	*drive;
	int			ret;

	if (!(stream >= &fileRes[0] && stream <= &fileRes[FILE_MAX-1])) {
		return E_FILE_STREAM;
	}
	if (stream->use_flag == 0) {
		return E_FILE_CLOSED;
	}
	drive = &driveTbl[stream->driveNum];

#ifdef FILE_DEBUG
	if (drive->fsysAPI->flush == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif

	ret = drive->fsysAPI->flush(stream->descriptor);
	return ret;
}

/*-----------------------------------------------------------------------------*/
int fsGetpos(FFILE *stream, long int *pos)
{
	const DRIVE_TBL	*drive;
	int			ret;

	if (!(stream >= &fileRes[0] && stream <= &fileRes[FILE_MAX-1])) {
		return E_FILE_STREAM;
	}
	if (stream->use_flag == 0) {
		return E_FILE_CLOSED;
	}
	drive = &driveTbl[stream->driveNum];

#ifdef FILE_DEBUG
	if (drive->fsysAPI->seek == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif

	ret = drive->fsysAPI->seek(stream->descriptor, 0, SEEK_CUR, pos);
	return ret;
}


/*-----------------------------------------------------------------------------*/
int fsSetpos(FFILE *stream, const long int *pos)
{
	const DRIVE_TBL	*drive;
	int			ret;

	if (!(stream >= &fileRes[0] && stream <= &fileRes[FILE_MAX-1])) {
		return E_FILE_STREAM;
	}
	if (stream->use_flag == 0) {
		return E_FILE_CLOSED;
	}
	drive = &driveTbl[stream->driveNum];

#ifdef FILE_DEBUG
	if (drive->fsysAPI->seek == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif

	ret = drive->fsysAPI->seek(stream->descriptor, *pos, SEEK_SET, NULL);
	return ret;
}


/*-----------------------------------------------------------------------------*/
long fsTell(FFILE *stream)
{
	const DRIVE_TBL	*drive;
	int			ret;
	long		pos;

	if (!(stream >= &fileRes[0] && stream <= &fileRes[FILE_MAX-1])) {
		return E_FILE_STREAM;
	}
	if (stream->use_flag == 0) {
		return E_FILE_CLOSED;
	}
	drive = &driveTbl[stream->driveNum];

#ifdef FILE_DEBUG
	if (drive->fsysAPI->seek == NULL) {
		return E_FILE_NOT_SUPPORT;
	}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -