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

📄 fatfs.h

📁 一个朋友给我的FAT文件系统源代码,兼职FAT16/32,针对ARM挂硬盘开发的!
💻 H
字号:
#ifndef __FATFS_H_
#define __FATFS_H_

#include <rt_lib.h>
#include <stdio.h>

enum
{
	FAT12,
	FAT16,
	FAT32
};

#define DOS_BOOT_SEC_NUM	0/* sector number of boot sector */
#define DOS_MIN_CLUST		2/* lowest cluster number used */
#define DOS_SYS_ID_LEN		8/* length of system ID string */
#define DOS_FAT_12BIT_MAX	4085/* max clusters for 12-bit FAT entries*/
#define DOS_NFILES_DEFAULT	8/* default max number of files */

/* Boot sector offsets */
/*   Because the MS-DOS boot sector format has word data items
 *   on odd-byte boundaries, it cannot be represented as a standard C
 *   structure.  Instead, the following symbolic offsets are used to
 *   isolate data items.  Non-string data values longer than 1 byte are
 *   in "Intel 8086" order.
 *
 *   These definitions include fields used by MS-DOS Version 4.0.
 */
#define DOS_BOOT_JMP			0x00/* 8086 jump instruction     (3 bytes)*/
#define DOS_BOOT_SYS_ID			0x03/* system ID string          (8 bytes)*/
#define DOS_BOOT_BYTES_PER_SEC	0x0b/* bytes per sector          (2 bytes)*/
#define DOS_BOOT_SEC_PER_CLUST	0x0d/* sectors per cluster       (1 byte) */
#define DOS_BOOT_NRESRVD_SECS	0x0e/* # of reserved sectors     (2 bytes)*/
#define DOS_BOOT_NFATS			0x10/* # of FAT copies           (1 byte) */
#define DOS_BOOT_MAX_ROOT_ENTS	0x11/* max # of root dir entries (2 bytes)*/
#define DOS_BOOT_NSECTORS		0x13/* total # of sectors on vol (2 bytes)*/
#define DOS_BOOT_MEDIA_BYTE		0x15/* media format ID byte      (1 byte) */
#define DOS_BOOT_SEC_PER_FAT	0x16/* # of sectors per FAT copy (2 bytes)*/
#define DOS_BOOT_SEC_PER_TRACK	0x18/* # of sectors per track    (2 bytes)*/
#define DOS_BOOT_NHEADS			0x1a/* # of heads (surfaces)     (2 bytes)*/
#define DOS_BOOT_NHIDDEN_SECS	0x1c/* # of hidden sectors       (4 bytes)*/
#define DOS_BOOT_LONG_NSECTORS	0x20/* total # of sectors on vol (4 bytes)*/
#define DOS_BOOT_DRIVE_NUM		0x24/* physical drive number     (1 byte) */
#define DOS_BOOT_SIG_REC		0x26/* boot signature record     (1 byte) */
#define DOS_BOOT_VOL_ID			0x27/* binary volume ID number   (4 bytes)*/
#define DOS_BOOT_VOL_LABEL		0x2b/* volume label string      (11 bytes)*/
#define DOS_BOOT_FSTYPE_ID		0x36/* new MS ID, FAT12 or FAT16 */
#define DOS_BOOT_FSTYPE_LEN		0x08/* length in bytes of FSTYPE */
#define DOS_BOOT_FSTYPE_FAT16	"FAT16   "/* FSTYPE_ID FAT16 */
#define DOS_BOOT_FSTYPE_FAT12	"FAT12   "/* FSTYPE_ID FAT12 */
#define DOS_BOOT_SYSID_FAT32	"FAT32   "/* FAT32 SYS_ID, */
#define DOS_BOOT_PART_TBL		0x1be/* first disk partition tbl (16 bytes)*/
#define DOS_EXT_BOOT_SIG		0x29/* value written to boot signature */

/* extended FAT32 fields offsets */
#define DOS32_BOOT_SEC_PER_FAT		0x24/* sectors per FAT           (4 bytes)*/
#define DOS32_BOOT_EXT_FLAGS		0x28/* FAT  miscellaneous flags  (2 bytes)*/
#define DOS32_BOOT_FS_VERSION		0x2a/* file system version       (2 bytes)*/
#define DOS32_BOOT_ROOT_START_CLUST 0x2c/* root start cluster       (4 bytes)*/
#define DOS32_BOOT_FS_INFO_SEC		0x30/* file system info sector   (2 bytes)*/
#define DOS32_BOOT_BOOT_BKUP		0x32/* bkup of boot sector       (2 bytes)*/
#define DOS32_BOOT_RESERVED			0x3a/* reserved area             (6 bytes)*/
#define DOS32_BOOT_BIOS_DRV_NUM		0x40/* 0x80 for hard disk        (1 byte)*/
#define DOS32_BOOT_SIGNATURE		0x42/* ')' (0x29)                (1 byte)*/
#define DOS32_BOOT_VOL_ID			0x43/* binary volume Id          (4 bytes*/
#define DOS32_BOOT_VOL_LABEL		0x47/* volume label string      (11 bytes)*/
#define DOS32_BOOT_FS_TYPE			0x52/* string FAT32 */

#define DOS_BOOT_BUF_SIZE			0x80/* size of buffer large enough to */
/* get boot sector data to */
/* ( without partition table ) */
#define CHK_MAX_PATH		1024/* max path in check disk's message */

#define DOS_MAX_DIR_LEVELS	20/* max expected directory levels */
#define DOS_VOL_LABEL_LEN	11/* length of volume label */

#define DISK_TO_SHORT(pSrc) (short)((*((char *)(pSrc) + 1) << 8) | (*(char *)(pSrc)))
#define DISK_TO_LONG(pSrc)																				   \
	(long)																								   \
		(																								   \
			(*((char *)(pSrc) + 3) << 24) | (*((char *)(pSrc) + 2) << 16) | (*((char *)(pSrc) + 1) << 8) | \
				(*(char *)(pSrc))																		   \
		)
#define SHORT_TO_DISK(src, pDst)	(*(char *)(pDst) = (src) & 0xff, *((char *)(pDst) + 1) = ((src) >> 8) & 0xff)
#define LONG_TO_DISK(src, pDst)																					 \
		(																										 \
			*(char *)(pDst) = (src) & 0xff, *((char *)(pDst) + 1) = ((src) >> 8) & 0xff, *((char *)(pDst) + 2) = \
				(																								 \
					(src) >>																					 \
					16																							 \
				) & 0xff, *((char *)(pDst) + 3) = ((src) >> 24) & 0xff											 \
		)
#define DOS_VX_LONG_NAME_LEN	40/* length of vxWorks proprietary */
	/* long filename */
#define DOS_VFAT_NAME_LEN	255/* max W-95 style name length */

	/* standard directory entry */
#define DOS_DIRENT_STD_LEN	32/* standard directory entry size */

#define DOS_RESERVED_LEN	10/* reserved bytes in regular dir ent */
	/* fully used by VFAT aliases */
#define DOS_STDNAME_LEN 8/* length of filename */
	/* (no extension) */
#define DOS_STDEXT_LEN				3/* length of filename extension */
#define DOS_ATTRIB_OFF				(DOS_STDNAME_LEN + DOS_STDEXT_LEN)
#define DOS_NAME_CASE_OFF			(DOS_ATTRIB_OFF + 1)
#define DOS_CREAT_MS_OFF			(DOS_NAME_CASE_OFF + 1)
#define DOS_CREAT_TIME_OFF			(DOS_CREAT_MS_OFF + 1)
#define DOS_CREAT_DATE_OFF			(DOS_CREAT_TIME_OFF + 2)
#define DOS_LAST_ACCESS_TIME_OFF	NONE
#define DOS_LAST_ACCESS_DATE_OFF	(DOS_CREAT_DATE_OFF + 2)
#define DOS_EXT_START_CLUST_OFF		(DOS_LAST_ACCESS_DATE_OFF + 2)
#define DOS_MODIF_TIME_OFF			(DOS_EXT_START_CLUST_OFF + 2)
#define DOS_MODIF_DATE_OFF			(DOS_MODIF_TIME_OFF + 2)
#define DOS_START_CLUST_OFF			(DOS_MODIF_DATE_OFF + 2)
#define DOS_FILE_SIZE_OFF			(DOS_START_CLUST_OFF + 2)
#define DOS_EXT_FILE_SIZE_OFF		NONE
#define DOS_EXT_FILE_SIZE_LEN		NONE

#define LFN_NAME1_OFF				1
#define LFN_NAME1_LEN				10

#define LFN_NAME2_OFF				14
#define LFN_NAME2_LEN				12

#define LFN_NAME3_OFF				28
#define LFN_NAME3_LEN				4

#define LAST_LONG_ENTRY				0x40

#define START_CLUST_DECODE(pVolDesc, pDirEnt)													   \
			(																					   \
				DISK_TO_SHORT((char *)(pDirEnt) + DOS_START_CLUST_OFF) +						   \
					(																			   \
						((pVolDesc)->fatType == FAT32) ?										   \
							(DISK_TO_SHORT((char *)(pDirEnt) + DOS_EXT_START_CLUST_OFF) << 16) : 0 \
					)																			   \
			)
#define ATTR_READ_ONLY					0x01
#define ATTR_HIDDEN						0x02
#define ATTR_SYSTEM						0x04
#define ATTR_VOLUME_ID					0x08
#define ATTR_DIRECTORY					0x10
#define ATTR_ARCHIVE					0x20
#define ATTR_LONG_NAME					(ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
#define ATTR_LONG_NAME_MASK				(ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID | ATTR_ARCHIVE | ATTR_DIRECTORY)
#define PART_MAX_ENTRIES				4/* Max # of partitions */

#define OFFSET_IN_SEC(pVolDesc, off)	((off) & ((pVolDesc)->bytesPerSec - 1))

	struct _FS_DEV
	{
		HANDLE	hFind;
	HANDLE	hFile;
};

struct _FAT_DESC
{
	ULONG	*buffer;
	ULONG	sector;
};

struct _VOL_DESC
{
	int			volOk;
	ULONG		bootSecNum;
	ULONG		bytesPerSec;
	ULONG		totalSecs;
	ULONG		secPerClust;
	ULONG		nFats;
	ULONG		nHiddenSecs;
	ULONG		nReservedSecs;
	ULONG		secPerFat;
	ULONG		fatType;
	ULONG		volIdOff;
	ULONG		volLabOff;
	ULONG		dataStartSec;
	ULONG		fatStartSec;
	ULONG		dirStartClust;
	ULONG		volId;
	char		bootVolLab[DOS_VOL_LABEL_LEN + 1]; /* volume label */

	_FAT_DESC	fatDesc;
};

struct _FS_PART_TBL
{
	ULONG	startHead;
	ULONG	startSector;
	ULONG	startCylinder;
	ULONG	endHead;
	ULONG	endSector;
	ULONG	endCylinder;
	ULONG	absSector;
	ULONG	totalSecs;
	ULONG	type;
};

struct _DIRENT
{
	ULONG	deNum;
	ULONG	sector;
	ULONG	offset;
};

struct _FILE_DESC
{
	char		cFileName[_MAX_PATH];
	char		cAlternateName[DOS_STDNAME_LEN + DOS_STDEXT_LEN + 2];
	char		attrib;
	ULONG		size;
	ULONG		pos;
	ULONG		curSec;
	ULONG		nSecs;
	ULONG		startClust;
	_VOL_DESC	*pVolDesc;
};

struct _FIND_DESC
{
	_DIRENT		dirEnt;
	char		cFileName[_MAX_PATH];
	_VOL_DESC	*pVolDesc;
};

struct _FIND_DATA
{
	char	cFileName[_MAX_PATH];
	char	cAlternateName[DOS_STDNAME_LEN + DOS_STDEXT_LEN + 1];
	DWORD	dwAttributes;
};

#ifdef __cplusplus
extern "C"
{
#endif

BOOL		fsStart(void);

BOOL		volMount(_FS_PART_TBL *pFs, _VOL_DESC *pVolDesc);
BOOL		dirRead(_VOL_DESC *pVolDesc, _DIRENT *pDirEnt, _FILE_DESC *pFd);
_VOL_DESC	*dirGetVol(const char *path);
ULONG		dirOpen(_VOL_DESC *pVolDesc, const char *path);
BOOL		dirMatch(_VOL_DESC *pVolDesc, _DIRENT *dirEnt, _FILE_DESC *pFd, const char *name);

void		dirLongName(const char *dirEnt, char *pName);
void		dirShortName(const char *dirEnt, char *pName);

ULONG		fatGetNext(_VOL_DESC *pVolDesc, ULONG deNum);

HANDLE		FindFirstFile(const char *lpFileName, _FIND_DATA *lpFindFileData);
BOOL		FindNextFile(HANDLE hFind, _FIND_DATA *lpFindFileData);
void		FindClose(HANDLE hFindFile);

HANDLE		CreateFile(const char *lpFileName);
void		CloseFile(HANDLE hFile);
BOOL		ReadFile(HANDLE hFile, void *lpBuffer, ULONG dwBytesToRead, ULONG *lpBytesReaded);

void		volTest(void);

#ifdef __cplusplus
}

#endif
#endif

⌨️ 快捷键说明

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