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

📄 fatfs.cpp

📁 一个朋友给我的FAT文件系统源代码,兼职FAT16/32,针对ARM挂硬盘开发的!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		pDirEnt->offset = 0;

		if (pDirEnt->sector >= pVolDesc->secPerClust)
		{
			pDirEnt->deNum = fatGetNext(pVolDesc, pDirEnt->deNum);
			pDirEnt->sector = 0;
		}
	}
}

_VOL_DESC *dirGetVol(const char *path)
{
	char	drive[_MAX_DRIVE];
	splitpath(path, drive, NULL, NULL, NULL);
	if (drive[0])
	{
		int drv = tolower(drive[0]) - 'c';
		if (drv >= 0 && drv < _countof(volDesc))
		{
			return (&volDesc[drv]);
		}
	}

	return (&volDesc[0]);
}

BOOL dirMatch(_VOL_DESC *pVolDesc, _FILE_DESC *pFd, const char *name)
{
	_DIRENT dirEnt;
	dirEnt.deNum = pFd->startClust;
	dirEnt.sector = 0;
	dirEnt.offset = 0;
	while (dirRead(pVolDesc, &dirEnt, pFd))
	{
		if (wildCompare(name, pFd->cAlternateName) || wildCompare(name, pFd->cFileName))
		{
			return (TRUE);
		}
	}

	return (FALSE);
}

ULONG dirOpen(_VOL_DESC *pVolDesc, const char *path)
{
	char	dir[_MAX_DIR];
	splitpath(path, NULL, dir, NULL, NULL);

	char	*dirName = dir;

	ULONG	deNum = pVolDesc->dirStartClust;
	if (strlen(dirName) > 0)
	{
		char		szName[_MAX_DIR];
		const char	chSep = '\\';
		const char	chNULL = '\0';

		if (*dirName == chSep)
		{
			dirName++;
		}

		while (dirName && *dirName)
		{
			char	*lpsz = strchr(dirName, chSep);
			if (lpsz)
			{
				const int	len = lpsz - dirName;
				strncpy(szName, dirName, len + 1);
				szName[len] = chNULL;
				dirName = lpsz + 1;
			}
			else
			{
				strcpy(szName, dirName);
				dirName = NULL;
			}

			_FILE_DESC	Fd = { 0 };
			Fd.startClust = deNum;
			if (!dirMatch(pVolDesc, &Fd, szName))
			{
				return (-1);
			}

			deNum = Fd.startClust;
		}
	}

	return (deNum);
}

HANDLE FindFirstFile(const char *lpFileName, _FIND_DATA *lpFindFileData)
{
	_FIND_DESC	*pFd;
	if (HeapAlloc(fsDev.hFind, (void **) &pFd) == NOERROR)
	{
		pFd->pVolDesc = dirGetVol(lpFileName);

		_DIRENT *dirEnt = &pFd->dirEnt;
		dirEnt->deNum = dirOpen(pFd->pVolDesc, lpFileName);
		dirEnt->offset = 0;
		dirEnt->sector = 0;

		if (dirEnt->deNum == -1)
		{
			HeapFree(fsDev.hFind, pFd);
			return (NULL);
		}

		char	szFName[_MAX_FNAME];
		char	szExt[_MAX_EXT];
		splitpath(lpFileName, NULL, NULL, szFName, szExt);
		makepath(pFd->cFileName, NULL, NULL, szFName, szExt);

		_FILE_DESC	Fd = { 0 };
		while (dirRead(pFd->pVolDesc, dirEnt, &Fd))
		{
			if (wildCompare(pFd->cFileName, Fd.cFileName) || wildCompare(pFd->cFileName, Fd.cAlternateName))
			{
				strcpy(lpFindFileData->cFileName, Fd.cFileName);
				strcpy(lpFindFileData->cAlternateName, Fd.cAlternateName);
				lpFindFileData->dwAttributes = Fd.attrib;

				return (pFd);
			}
		}
	}

	return (NULL);
}

BOOL FindNextFile(HANDLE hFind, _FIND_DATA *lpFindFileData)
{
	_FIND_DESC	*pFd = (_FIND_DESC *) (hFind);
	_DIRENT		*dirEnt = &pFd->dirEnt;
	_FILE_DESC	Fd = { 0 };
	while (dirRead(pFd->pVolDesc, dirEnt, &Fd))
	{
		if (wildCompare(pFd->cFileName, Fd.cFileName) || wildCompare(pFd->cFileName, Fd.cAlternateName))
		{
			strcpy(lpFindFileData->cFileName, Fd.cFileName);
			strcpy(lpFindFileData->cAlternateName, Fd.cAlternateName);
			lpFindFileData->dwAttributes = Fd.attrib;

			return (TRUE);
		}
	}

	return (FALSE);
}

void FindClose(HANDLE hFind)
{
	HeapFree(fsDev.hFind, hFind);
}

HANDLE CreateFile(const char *lpFileName)
{
	_FILE_DESC	*pFd;
	if (HeapAlloc(fsDev.hFile, (void **)(&pFd)) == NOERROR)
	{
		pFd->pVolDesc = dirGetVol(lpFileName);

		_DIRENT dirEnt;
		dirEnt.deNum = dirOpen(pFd->pVolDesc, lpFileName);
		dirEnt.sector = 0;
		dirEnt.offset = 0;

		char	szFName[_MAX_FNAME];
		char	szExt[_MAX_EXT];
		char	szName[_MAX_PATH];
		splitpath(lpFileName, NULL, NULL, szFName, szExt);
		makepath(szName, NULL, NULL, szFName, szExt);

		while (dirRead(pFd->pVolDesc, &dirEnt, pFd))
		{
			if (stricmp(szName, pFd->cFileName) == 0 || stricmp(szName, pFd->cAlternateName) == 0)
			{
				//				pFd->buffer.buffer = (char *)malloc(BYTES_PER_SEC * pFd->pVolDesc->secPerClust);
				return (pFd);
			}
		}

		HeapFree(fsDev.hFile, pFd);
	}

	return (NULL);
}

void CloseFile(HANDLE hFile)
{
	HeapFree(fsDev.hFile, hFile);
}

BOOL ReadFile(HANDLE hFile, void *lpBuffer, ULONG dwBytesToRead, ULONG *lpBytesReaded)
{
	_FILE_DESC	*pFd = (_FILE_DESC *) (hFile);
	_VOL_DESC	*pVolDesc = pFd->pVolDesc;
	char		*buffer = (char *)lpBuffer;

	if (pFd->attrib & ATTR_DIRECTORY)
	{
		return (FALSE);
	}

	if (dwBytesToRead == 0)
	{
		return (TRUE);
	}

	if (pFd->pos >= pFd->size)
	{
		*lpBytesReaded = 0;
		return (FALSE);
	}

	ULONG	maxBytes = __min(dwBytesToRead, pFd->size - pFd->pos);

	if (pFd->nSecs == 0)
	{
		ULONG	Next = fatGetNext(pVolDesc, SEC_TO_CLUST(pVolDesc, pFd->curSec - 1));
		if (Next != -1)
		{
			pFd->curSec = CLUST_TO_SEC(pVolDesc, Next);
			pFd->nSecs = pVolDesc->secPerClust;
		}
		else
		{
			TRACE0("ERROR seekTo next cluster\r\n");
			return (FALSE);
		}
	}

	ULONG	remainBytes = maxBytes;
	*lpBytesReaded = 0;

	/* for the beginning, process remain part of current sector */
	ULONG	work = OFFSET_IN_SEC(pVolDesc, pFd->pos); /* offset in sector */
	ULONG	numRW;

	if (work != 0)
	{
		numRW = __min(remainBytes, pVolDesc->bytesPerSec - work);
		if (cbioBytesRead(0, pFd->curSec, work, lpBuffer, numRW) != NOERROR)
		{
			TRACE0("ERROR ReadFile\r\n");
			return (FALSE);
		}

		remainBytes -= numRW;
		buffer += numRW;
		pFd->pos += numRW;

		*lpBytesReaded += numRW;

		/* it may be current sector exhausted */
		if (OFFSET_IN_SEC(pVolDesc, pFd->pos) == 0)
		{
			pFd->curSec++;
			pFd->nSecs--;
		}
	}/* if( offset != 0 ) */

	/* main loop: read entire sectors */
	while (remainBytes >= pVolDesc->bytesPerSec)
	{

		/* get next contiguous block, if current already finished */
		if (pFd->nSecs == 0)
		{
			ULONG	Next = fatGetNext(pVolDesc, SEC_TO_CLUST(pVolDesc, pFd->curSec - 1));
			if (Next != -1)
			{
				pFd->curSec = CLUST_TO_SEC(pVolDesc, Next);
				pFd->nSecs = pVolDesc->secPerClust;
			}
			else
			{
				TRACE0("ERROR seek to next clust\r\n");
				return (FALSE);
			}
		}

		/* number of sectors to R/W */
		numRW = __min(remainBytes / BYTES_PER_SEC, pFd->nSecs);

		if (cbioRead(0, pFd->curSec, numRW, buffer) != NOERROR)
		{
			TRACE0("ERROR reading file\r\n");
			return (FALSE);
		}

		/* correct position */
		work = numRW * BYTES_PER_SEC;

		remainBytes -= work;
		buffer += work;
		pFd->pos += work;
		pFd->curSec += numRW;
		pFd->nSecs -= numRW;

		*lpBytesReaded += work;
	}/* while ... */

	/* now process remain part of data, that is shorter, than sector */
	numRW = remainBytes;
	if (numRW > 0)
	{

		/* get next contiguous block, if current already finished */
		if (pFd->nSecs == 0)
		{
			ULONG	Next = fatGetNext(pVolDesc, SEC_TO_CLUST(pVolDesc, pFd->curSec - 1));
			if (Next != -1)
			{
				pFd->curSec = CLUST_TO_SEC(pVolDesc, Next);
				pFd->nSecs = pVolDesc->secPerClust;
			}
			else
			{
				TRACE0("ERROR seek to next clust\r\n");
				return (FALSE);
			}
		}

		if (cbioBytesRead(0, pFd->curSec, 0, buffer, numRW) != NOERROR)
		{
			TRACE0("ERROR reading file\r\n");
			return (FALSE);
		}

		remainBytes -= numRW;
		buffer += numRW;
		pFd->pos += numRW;

		*lpBytesReaded += numRW;
	}

	return (TRUE);
}

void volTest(void)
{
	HANDLE	hFile = CreateFile("驼铃.mp3");
	if (hFile)
	{
		CloseFile(hFile);
	}
}

⌨️ 快捷键说明

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