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

📄 filesys.c

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

	ret = drive->fsysAPI->seek(stream->descriptor, 0, SEEK_CUR, &pos);
	if (ret < 0) {
		return (long)ret;
	}
	else {
		return pos;
	}
}

/*-----------------------------------------------------------------------------*/
int fsSeek(FFILE *stream, long offset, int origin)
{
	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, offset, origin, NULL);
	return ret;
}

/*-----------------------------------------------------------------------------*/
int fsRemove(const char *path)
{
	char		*path2;
	UCHAR		driveNum;
	int			ret;
	const DRIVE_TBL	*drive;

	if (CheckPath(path, &driveNum, &path2) < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

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

	ret = drive->fsysAPI->remove(drive->subDriveNum, (UCHAR*)path2);
	return ret;
}

/*-----------------------------------------------------------------------------*/
int fsRename(const char *oldname, const char *newname)
{
	char		*path;
	UCHAR		driveNum;
	int			ret;
	const DRIVE_TBL	*drive;

	if (CheckPath(oldname, &driveNum, &path) < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

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

	ret = drive->fsysAPI->rename(drive->subDriveNum, (UCHAR*)path, (UCHAR*)newname);
	return ret;
}

/*-----------------------------------------------------------------------------*/
int fsCwd(char **path)
{
	const DRIVE_TBL	*drive;
	char		*path2;
	static char	currPath[FULLPATH_MAX];
	int			i, ret;

	drive = &driveTbl[currDrive];

	strcpy(currPath, drive->driveName);
	i = strlen(currPath);
	currPath[i] = ':';
	i ++;

	if (drive->fsysAPI->cwd != NULL) {
		ret = drive->fsysAPI->cwd(drive->subDriveNum, (UCHAR**)&path2);
		if (ret < 0) {
			currPath[i] = '\0';
			*path = currPath;		/* output drive name only */
			return ret;
		}
		else {
			for( ; i < FULLPATH_MAX; i++, path2++) {
				if (*path2 == 0) {
					break;
				}
				currPath[i] = *path2;
			}
			if (i == FULLPATH_MAX) {
				currPath[i-1] = '\0';
				*path = currPath;
				return E_FILE_PATH_LEN;
			}
		}
	}
	currPath[i] = '\0';
	*path = currPath;
	return E_FILE_OK;
}

/*-----------------------------------------------------------------------------*/
int fsSetAttr(const char *path, UCHAR attr)
{
	char		*path2;
	UCHAR		driveNum;
	int			ret;
	const DRIVE_TBL	*drive;

	if (CheckPath(path, &driveNum, &path2) < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

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

	ret = drive->fsysAPI->setAttr(drive->subDriveNum, (UCHAR*)path2, attr);
	return ret;
}

/*-----------------------------------------------------------------------------*/
int fsChdir(const char *path)
{
	char		*path2;
	UCHAR		driveNum;
	int			ret;
	const DRIVE_TBL	*drive;

	if (CheckPath(path, &driveNum, &path2) < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

	if (*path2 != '\0') {
	/* change directory */
		if (drive->fsysAPI->chdir == NULL) {
			return E_FILE_NOT_SUPPORT;
		}
		ret = drive->fsysAPI->chdir(drive->subDriveNum, (UCHAR*)path2);
		if (ret < 0) {
			return ret;
		}
	}
	else {
	/* change drive */
		if (drive->fsysAPI->getDriveInfo == NULL) {
			return E_FILE_NOT_SUPPORT;
		}
		/* check drive ready */
		ret = drive->fsysAPI->getDriveInfo(drive->subDriveNum, NULL);
		if (ret < 0) {
			return ret;
		}
		currDrive = (UCHAR)driveNum;
	}

	return E_FILE_OK;
}

/*-----------------------------------------------------------------------------*/
int fsMkdir(const char *path)
{
	char		*path2;
	UCHAR		driveNum;
	int			ret;
	const DRIVE_TBL	*drive;

	if (CheckPath(path, &driveNum, &path2) < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

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

	ret = drive->fsysAPI->mkdir(drive->subDriveNum, (UCHAR*)path2);
	return ret;
}


/*-----------------------------------------------------------------------------*/
int fsRmdir(const char *path)
{
	char		*path2;
	UCHAR		driveNum;
	int			ret;
	const DRIVE_TBL	*drive;

	if (CheckPath(path, &driveNum, &path2) < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

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

	ret = drive->fsysAPI->rmdir(drive->subDriveNum, (UCHAR*)path2);
	return ret;
}



/*-----------------------------------------------------------------------------*/
int fsGetFirstEntry(const char *path, char *name, FILE_INFO *finfo)
{
	char		*path2;
	UCHAR		driveNum;
	int			ret;
	const DRIVE_TBL	*drive;

	if (CheckPath(path, &driveNum, &path2) < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

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

	ret = drive->fsysAPI->getFirstEntry(drive->subDriveNum, (UCHAR*)path2, (UCHAR*)name, finfo);
	if (ret >= 0) {
		entryDrive = driveNum;
	}

	return ret;
}

/*-----------------------------------------------------------------------------*/
int fsGetNextEntry(char *name, FILE_INFO *finfo)
{
	const DRIVE_TBL	*drive = &driveTbl[entryDrive];
	int			ret;

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

	ret = drive->fsysAPI->getNextEntry((UCHAR*)name, finfo);
	return ret;
}

/*-----------------------------------------------------------------------------*/
int fsGetFileInfo(const char *path, FILE_INFO *finfo)
{
	char		*path2;
	UCHAR		driveNum;
	int			ret;
	const DRIVE_TBL	*drive;

	if (CheckPath(path, &driveNum, &path2) < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

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

	ret = drive->fsysAPI->getFileInfo(drive->subDriveNum, (UCHAR*)path2, finfo);
	return ret;
}


/*-----------------------------------------------------------------------------*/
int fsGetDriveInfo(char *driveName, DRIVE_INFO *drvInfo)
{
	int			driveNum, ret;
	const DRIVE_TBL	*drive;

	driveNum = CheckDrive(driveName, NULL);
	if (driveNum < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

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

	ret = drive->fsysAPI->getDriveInfo(drive->subDriveNum, drvInfo);
	return ret;
}

/*-----------------------------------------------------------------------------*/
int fsExecute(const char *path)
{
	char		*path2;
	UCHAR		driveNum;
	int			ret;
	const DRIVE_TBL	*drive;

	if (CheckPath(path, &driveNum, &path2) < 0) {
		return E_FILE_DRIVE;
	}
	drive = &driveTbl[driveNum];

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

	ret = drive->fsysAPI->execute(drive->subDriveNum, (UCHAR*)path2);
	return ret;
}


/********************************************************************************
	LOCAL FUNCTIONS
 ********************************************************************************/
/*-----------------------------------------------------------------------------*/
static void InitFileSys(void)
{
	int		i;

	for(i = 0; fsysTbl[i].init != NULL; i++) {
		fsysTbl[i].init(-1);
	}
}


/*-----------------------------------------------------------------------------*/
static void InitFileRes(void)
{
	int		i;

	for(i = 0; i < FILE_MAX; i++) {
		fileRes[i].use_flag = 0;
	}
}



/*-----------------------------------------------------------------------------*/
static int CheckDrive(const char *path, char **path2)
{
	char	driveName[DRIVE_NAME_MAX+1];
	char	c;
	int		i;

	for(i = 0; i < DRIVE_NAME_MAX+1; i++) {
		c = *path;
		if (c == ':') {
			break;
		}

		if (c >= 'a' && c <= 'z') {
			c -= 0x20;
		}
		driveName[i] = c;
		path ++;
	}
	if (i == DRIVE_NAME_MAX+1) {
		return -1;	/* length error or relative path */
	}
	driveName[i] = '\0';

	for(i = 0; driveTbl[i].fsysAPI != NULL; i++) {
		if (strcmp(driveName, driveTbl[i].driveName) == 0) {
			break;
		}
	}
	if (driveTbl[i].fsysAPI == NULL) {
		return -2;	/* drive error */
	}

	if (path2 != NULL) {
		path ++;
		*path2 = (char*)path;
	}

	return i;	/* drive number */

}

/*-----------------------------------------------------------------------------*/
static int CheckPath(const char *path, UCHAR *driveNum, char **path2)
{
	int		ret;

	if (*path == '\\' || *path == '/') {	/* absolute path without drive */
		*driveNum = currDrive;
		*path2 = (char*)path;
	}
	else {
		ret = CheckDrive(path, path2);
		if (ret < 0) {
			if (ret == -2) {	/* drive error */
				return -1;
			}
			else { /* relative path or other */
				*driveNum = currDrive;
				*path2 = (char*)path;
			}
		}
		else {	/* absolute path with drive */
			*driveNum = (UCHAR)ret;
		}
	}
	return 0;
}

⌨️ 快捷键说明

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