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

📄 fat.c

📁 嵌入式linux(arm9)的平台下
💻 C
字号:
/* * NOTE: This code derived from information obtained from the Microsoft * FAT specification v1.03. The code also uses Microsoft names wherever * possible. * * * 0 Boot Sector * 1 FAT0 * x ... *   FATn *   ... * y Root Dir Entries *   ... * z Clusters for Data/Dir Entries *   ... * * */ #include "fat.h" #include "example.h" #include "partition.h" #include "util.h"typedef struct FATBootSector{	int8	BS_jmpBoot[3];	int8	BS_OEMName[8];	uint8	BPB_BytsPerSec[2];	uint8	BPB_SecPerClus;	uint8	BPB_RsvdSecCnt[2];	uint8	BPB_NumFATs;	uint8	BPB_RootEntCnt[2];	uint8	BPB_TotSec16[2];	uint8	BPB_Media;	uint8	BPB_FATSz16[2];	uint16	BPB_SecPerTrk;	uint16	BPB_NumHeads;	uint8	BPB_HiddSec[4];	uint8	BPB_TotSec32[4];	union	{		struct		{			uint8	BS_DrvNum;			uint8	BS_Reserved1;			uint8	BS_BootSig;			uint8	BS_VolID[4];			uint8	BS_VolLab[11];			uint8	BS_FilSysType[8];		} fat16;		struct		{			uint8	BPB_FATSz32[4];			uint8	BPB_ExtFlags[2];			uint8	BPB_FSVer[2];			uint8	BPB_RootClus[4];			uint8	BPB_FSInfo[2];			uint8	BPB_BkBootSec[2];			uint8	BPB_Reserved[12];			uint8	BS_DrvNum;			uint8	BS_Reserved1;			uint8	BS_BootSig;			uint8	BS_VolID[4];			uint8	BS_VolLab[11];			uint8	BS_FilSysType[8];		} fat32;		uint8 padding[474]; /* to make final size exactly 512 */	} u;	uint8	offset510;	uint8	offset511;} FATBootSector;typedef struct FATDirEntry {	uint8	name[8],ext[3];	/* name and extension */	uint8	attr;		/* attribute bits */	uint8    lcase;		/* Case for base and extension */	uint8	ctime_ms;	/* Creation time, milliseconds */	uint16	ctime;		/* Creation time */	uint16	cdate;		/* Creation date */	uint16	adate;		/* Last access date */	uint16   starthi;	/* High 16 bits of cluster in FAT32 */	uint16	time,date,start;/* time, date and first cluster */	uint32	size;		/* file size (in bytes) */} FATDirEntry;enum FATType{	UNKNOWN,	FAT12,	FAT16,	FAT32};char fatTableCache[512];int fatCachedSector;DiskFunctions fatDiskFunctions;/********************************************************************//* * Structure for managing FAT filesystem */struct FATInfo{	FATBootSector fbs;	int bytesPerSector;	int reservedSectorCount;	unsigned int sectorCount;	int sectorsPerCluster;	int clusterSize;	int clusterCount;	int firstDataSector;	int sectorsPerFAT;	int rootEntryCount;	int directoriesPerSectorCount;	int rootDirSectorCount;	int rootDirSector;	int FATSize;	enum FATType type;	int dataSectorCount;	int rootSector;} fat;#define MAX_CLUSTER_SIZE (512 * 128)typedef struct FatFileHandle{	int currentCluster;	int byteOffset;	int bufferOffset;	char buffer[MAX_CLUSTER_SIZE];	FATDirEntry info;} FatFileHandle;FatFileHandle fatHandle;void displayFATInfo(){	int i;	printf("\n-------------------------------\n");	printf("FAT Info:\n");	printf("     OEMName: '");		for (i = 0; i < 8; ++i) printf("%c", fat.fbs.BS_OEMName[i]);	printf("'\n");	printf("  filesystem: ");	switch(fat.type)	{		case FAT12: printf("FAT12"); break;		case FAT16: printf("FAT16"); break;		case FAT32: printf("FAT32"); break;	}	printf("\n");	printf("  sectorSize: %d\n", fat.bytesPerSector);	printf(" sectorCount: %d\n", fat.sectorCount);	printf(" clusterSize: %d\n", fat.clusterSize);	printf("  clusterCnt: %d\n", fat.clusterCount);	printf(" BPB_NumFATs: %d\n", fat.fbs.BPB_NumFATs);	printf("     fatSize: %d\n", fat.FATSize);	printf(" numRootDirE: %d\n", fat.rootEntryCount);	printf(" dirEPerSect: %d\n", fat.directoriesPerSectorCount);	printf(" sectorsRoot: %d\n", fat.rootDirSectorCount);	printf(" ReservedCnt: %d\n", fat.reservedSectorCount);	printf("  fstDataSec: %d\n", fat.firstDataSector);	printf(" sectPerClus: %d\n", fat.sectorsPerCluster);	printf("    diskSize: %dK\n", (fat.sectorCount * fat.bytesPerSector) >> 10);	printf("-------------------------------\n");}void displayDirectoryEntry(FATDirEntry* handle){	int FATOffset, ThisFATSecNum, ThisFATEntOffset;	int i;	short buffer[2048];		printf("\n-------------------------------\n");	printf("File Info:");	printf("\nFilename: ");	for(i = 0; i < 8; ++i)	{		printf("%c", handle->name[i]);	}	printf(".");	for(i = 0; i < 3; ++i)	{		printf("%c", handle->ext[i]);	}	printf("\nAttributes: %X", handle->attr);	printf("\nSize: %d Bytes", handle->size);	printf("\nStart Cluster: %d\n", handle->start);		FATOffset = handle->start * 2;	ThisFATSecNum = fat.reservedSectorCount + (FATOffset / fat.bytesPerSector);	ThisFATEntOffset = FATOffset % fat.bytesPerSector;	printf("FATOffset: %d\n", FATOffset);	printf("ThisFATSecNum: %d\n", ThisFATSecNum);	printf("ThisFATEntOffset: %d\n", ThisFATEntOffset); 	printf("-------------------------------\n");}int getSectorNumber(int clusterOffset){	return fat.rootSector + (clusterOffset - 2) * fat.fbs.BPB_SecPerClus + fat.firstDataSector;}int getNextCluster(int currentCluster){	int FATOffset, ThisFATSecNum, ThisFATEntOffset, next;	next = 0;	switch(fat.type)	{		case FAT12: break; //not supported		case FAT16: FATOffset = currentCluster * 2;	break;		case FAT32: FATOffset = currentCluster * 4; break;	}	ThisFATSecNum = fat.reservedSectorCount + (FATOffset / fat.bytesPerSector);	ThisFATEntOffset = FATOffset % fat.bytesPerSector;	if(fatCachedSector != ThisFATSecNum)	//is FAT sector cached?	{				fatDiskFunctions.read(fat.rootSector + ThisFATSecNum, 1, (void*)fatTableCache);	//read FAT table sector		fatCachedSector = ThisFATSecNum;	}	//load lower 16-bits of cluster offset (FAT16 offsets are only 16-bits)	next = ((fatTableCache[ThisFATEntOffset+1] & 0x0ff) << 8) | (fatTableCache[ThisFATEntOffset] & 0x0ff);	if(fat.type == FAT32)	//load upper 16-bits of cluster offset		next |= ((fatTableCache[ThisFATEntOffset+2] & 0x0ff) << 16) | 				((fatTableCache[ThisFATEntOffset+3] & 0x0ff) << 24);	return next;}char toUpper(char c){	return (c <= 'z' && c >= 'a') ? c - 0x20 : c;}int compareFileName(char fatName[8], char fatExt[3], const char* searchName){	int i, j;	int period = 0;	DPRINTF("\n");	#if defined(_DEBUG)		printf("Search Name: %s\n", searchName);		printf("Fat Name: ");		for(i = 0; i < 8; ++i)			printf("%c", fatName[i]);		printf(".");		for(i = 0; i < 3; ++i)			printf("%c", fatExt[i]);		printf("\n");	#endif	for(i = 0; i < 13 && searchName[i] != 0; ++i)		if(searchName[i] == '.')			period = i;	if(period > 0 && period < 9 && searchName[i] == 0)	{		//compare names		for(i = 0; i < period; ++i)			if(fatName[i] != toUpper(searchName[i]))				return fatName[i] < toUpper(searchName[i]) ? -1 : 1;		for(; i < 8; ++i)			if(fatName[i] != ' ')				return -1;			//compare extentions		for(i = 0, j = period+1; searchName[j] != 0; ++i, ++j)			if(fatExt[i] != toUpper(searchName[j]))				return fatExt[i] < toUpper(searchName[j]) ? -1 : 1;		for(; i < 3; ++i)			if(fatExt[i] != ' ')				return -1;		return 0;	}	return -1; }int findFile(const char* fileName, FATDirEntry* handle){	int i;	char buffer[MAX_CLUSTER_SIZE];	FATDirEntry* tempHandle;	int sector = fat.rootSector + fat.rootDirSector;	int cluster = 2;	for(i = 0; i < fat.rootEntryCount || fat.rootEntryCount == 0; ++i, ++tempHandle)	{		if((i*sizeof(FATDirEntry)) % (fat.bytesPerSector*fat.sectorsPerCluster) == 0)	//if at cluster boundary			{			fatDiskFunctions.read(sector, fat.sectorsPerCluster, buffer);					tempHandle = (FATDirEntry*)buffer;			if(fat.type == FAT32)								{														cluster = getNextCluster(cluster);	//The root directory on a FAT32 FS is treated like a regular file              				sector = getSectorNumber(cluster);	//Therefore the next cluster of the directory list is located in the FAT table 			}			else				sector += fat.sectorsPerCluster;	//On FAT16 all items in the root directory are sequentially allocated		}		if( tempHandle->name[0] == 0x00 )			return 0;		else		if( tempHandle->name[0] != 0xE5 &&			compareFileName(tempHandle->name, tempHandle->ext, fileName) == 0 )		{			//displayDirectoryEntry(tempHandle);			memCopy(tempHandle, handle, sizeof(FATDirEntry));			return 1;		}	}	return 0;}int fatLoad(DiskFunctions diskFunctions){	fatDiskFunctions = diskFunctions;	char* buffer[2048];		/*	 * Check for MSDOS/FAT filesystem, if yes, then allocate	 * a control structure for managing this filesystem	 */	int i, rootBytes;	/*	 * Read boot sector/partition table sector, sector 0	 */	fat.rootSector = partitionGetRootSector(FAT, 0, fatDiskFunctions.read);		DPRINTF("root sector: %d\n", fat.rootSector);	if(fat.rootSector == -1)		 return 0;	if(fatDiskFunctions.read(fat.rootSector, 1, (short*) &fat.fbs))	{		if ((fat.fbs.offset510 == 0x55) && (fat.fbs.offset511 == 0xAA))		{			fat.bytesPerSector = (fat.fbs.BPB_BytsPerSec[1] << 8) | fat.fbs.BPB_BytsPerSec[0];			/* Check for valid FAT sector size */			switch (fat.bytesPerSector)			{				case 512:				case 1024:				case 2048:				case 4096:					break;				default:					return 0;					break;			}			fat.sectorsPerCluster = fat.fbs.BPB_SecPerClus;			/* Check for valid Cluster size */			switch (fat.sectorsPerCluster)			{				case 1:				case 2:				case 4:				case 8:				case 16:				case 32:				case 64:				case 128:					break;				default:					return 0;					break;			}			/* Check that cluster size does not exceed 32KB */			fat.clusterSize = fat.bytesPerSector * fat.sectorsPerCluster;			if (fat.clusterSize > (32 * 1024))				return 0;			/* Reserved area must be at least 1 sector */			fat.reservedSectorCount =				(fat.fbs.BPB_RsvdSecCnt[0] <<  0) |				(fat.fbs.BPB_RsvdSecCnt[1] <<  8) ;			if (fat.reservedSectorCount == 0)				return 0;			/* Must have at least 1 FAT */			if (fat.fbs.BPB_NumFATs == 0)				return 0;			fat.sectorCount = (fat.fbs.BPB_TotSec16[1] << 8) | fat.fbs.BPB_TotSec16[0];			if (fat.sectorCount == 0)			{				fat.sectorCount =				(fat.fbs.BPB_TotSec32[0] <<  0) |				(fat.fbs.BPB_TotSec32[1] <<  8) |				(fat.fbs.BPB_TotSec32[2] << 16) |				(fat.fbs.BPB_TotSec32[3] << 24) ;			}			fat.sectorsPerCluster = fat.fbs.BPB_SecPerClus;			fat.rootEntryCount = (fat.fbs.BPB_RootEntCnt[1] << 8) | fat.fbs.BPB_RootEntCnt[0];			fat.directoriesPerSectorCount = fat.bytesPerSector / sizeof(FATDirEntry);			rootBytes = ((fat.rootEntryCount * sizeof(FATDirEntry))	+ (fat.bytesPerSector - 1));			fat.rootDirSectorCount =  ((fat.rootEntryCount * sizeof(FATDirEntry))	+ (fat.bytesPerSector - 1)) / fat.bytesPerSector;			/*			 * Check if this is FAT12, FAT16, FAT32			 * take the number of clusters and check that against number of			 * entries in FAT if it were 12-, 16- or 32-bits per entry.			 */			if (fat.fbs.BPB_FATSz16[0] || fat.fbs.BPB_FATSz16[1])			{				fat.FATSize =				(fat.fbs.BPB_FATSz16[0] <<  0) |				(fat.fbs.BPB_FATSz16[1] <<  8) ;			}			else			{				fat.FATSize = 				(fat.fbs.u.fat32.BPB_FATSz32[0] <<  0) |				(fat.fbs.u.fat32.BPB_FATSz32[1] <<  8) |				(fat.fbs.u.fat32.BPB_FATSz32[2] << 16) |				(fat.fbs.u.fat32.BPB_FATSz32[3] << 24) ;			}					fat.rootDirSector = fat.reservedSectorCount + (fat.fbs.BPB_NumFATs * fat.FATSize);			fat.firstDataSector = fat.rootDirSector + fat.rootDirSectorCount;			fat.dataSectorCount = fat.sectorCount - (fat.reservedSectorCount + (fat.fbs.BPB_NumFATs * fat.FATSize) + fat.rootDirSectorCount);			fat.clusterCount = fat.dataSectorCount / fat.fbs.BPB_SecPerClus;			/* FAT12 volumes have no more than 4084 clusters */			if (fat.clusterCount < 4085)			{				fat.type = FAT12;				DPRINTF("FAT12 Partition\n");			}			/* FAT16 volumes have at least 4085 clusters and no more than 655524 */			else if (fat.clusterCount < 65525)			{				fat.type = FAT16;				DPRINTF("FAT16 Partition\n");			}			/* FAT32 volumes have at least 65525 clusters */			else			{				fat.type = FAT32;				DPRINTF("FAT32 Partition\n");			}			//if (fat.type == FAT32) return 0; // doesn't quite work yet						//displayFATInfo();			return 1;		}	}		return 0; /* unable to read disk */}int fatClose(){	return 1;}int fatOpen(const char* fileName){	fatCachedSector = -1;	if(findFile(fileName, &fatHandle.info))	{		DPRINTF("Found File: %s, %d\n", fileName, fatHandle.info.start);		fatHandle.byteOffset = 0;		fatHandle.currentCluster = (fatHandle.info.starthi << 16) | fatHandle.info.start;		fatHandle.bufferOffset = fat.clusterSize;				return fatHandle.info.size;	}	return 0;}int fatRead(void* buffer, int size){		int i;	char* cBuffer = (char*)buffer;	for(i = 0; i < size; ++i, ++fatHandle.byteOffset, ++fatHandle.bufferOffset)	{				if(fatHandle.byteOffset == fatHandle.info.size)			return i;		if(fatHandle.bufferOffset == fat.clusterSize)		{			if(fatHandle.byteOffset != 0)			{				fatHandle.currentCluster = getNextCluster(fatHandle.currentCluster);			}			fatDiskFunctions.read(	getSectorNumber(fatHandle.currentCluster), 									fat.sectorsPerCluster, 									(void*)&fatHandle.buffer); //buffer cluster			fatHandle.bufferOffset = 0;		}		cBuffer[i] = fatHandle.buffer[fatHandle.bufferOffset];		}	return i;}

⌨️ 快捷键说明

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