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

📄 fat.c

📁 嵌入式文件系统 EFSL 0.3.5 / 嵌入式文件系统 EFSL 0.3.5
💻 C
📖 第 1 页 / 共 2 页
字号:
				part_relSect(fs->part,buf2);			}else{				lb = buf[offset + 1];			}			if(cluster_addr%2==0){				nextcluster = ( ((lb&0x0F)<<8) + (hb) );			}else{				nextcluster = ( (lb<<4) + (hb>>4) );			}			break;		case FAT16:			offset=cluster_addr%256;			nextcluster = *((euint16*)buf + offset);			break;		case FAT32:			offset=cluster_addr%128;			nextcluster = *((euint32*)buf + offset);			break;	}	return(nextcluster);}/*****************************************************************************/ /* ****************************************************************************   * void fat_setNextClusterAddressWBuf(FileSystem *fs,euint32 cluster_addr,euint32 next_cluster_addr,euint8* buf) * Description: This function fills in a fat entry. The entry is cluster_addr and the * data entered is next_cluster_addr. This function is also given a *buf, so it does * not write the data itself, except in the case of FAT 12 cross sector data, where * the second sector is handled by this function. * Return value:*/void fat_setNextClusterAddressWBuf(FileSystem *fs,euint32 cluster_addr,euint32 next_cluster_addr,euint8* buf){	euint16 offset;	euint8 *buf2;			switch(fs->type)	{		case FAT12:			offset = ((cluster_addr%1024)*3/2)%512;			if(offset == 511){				if(cluster_addr%2==0){					buf[offset]=next_cluster_addr&0xFF;				}else{					buf[offset]=(buf[offset]&0xF)+((next_cluster_addr<<4)&0xF0);				}				buf2=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cluster_addr)+1,IOM_MODE_READWRITE);				if(cluster_addr%2==0){					buf2[0]=(buf2[0]&0xF0)+((next_cluster_addr>>8)&0xF);				}else{					buf2[0]=(next_cluster_addr>>4)&0xFF;				}				part_relSect(fs->part,buf2);			}else{				if(cluster_addr%2==0){					buf[offset]=next_cluster_addr&0xFF;					buf[offset+1]=(buf[offset+1]&0xF0)+((next_cluster_addr>>8)&0xF);				}else{					buf[offset]=(buf[offset]&0xF)+((next_cluster_addr<<4)&0xF0);					buf[offset+1]=(next_cluster_addr>>4)&0xFF;				}			}			break;		case FAT16:			offset=cluster_addr%256;			*((euint16*)buf+offset)=next_cluster_addr;			break;		case FAT32:			offset=cluster_addr%128;			*((euint32*)buf+offset)=next_cluster_addr;			break;	}}/*****************************************************************************//* ****************************************************************************   * esint16 fat_getNextClusterChain(FileSystem *fs, ClusterChain *Cache) * Description: This function is to advance the clusterchain of a Cache. * First, the function verifies if the Cache is valid. It could correct it if it  * is not, but this is not done at the time. If the cachen is valid, the next step is * to see what the next cluster is, if this is the End of Clustermark, the cache is * updated to know the lastcluster but will remain untouched otherwise. -1 is returned. * If there are more clusters the function scans the rest of the chain until the next * cluster is no longer lineair, or until it has run out of fat data (only 1 sector) is * examined, namely the one fetched to check for EoC. * With lineair is meant that logical cluster n+1 should be 1 more than logical cluster n * at the disc level. * Return value: 0 on success, or -1 when EoC.*/esint16 fat_getNextClusterChain(FileSystem *fs, ClusterChain *Cache){	euint32 sect,lr,nlr,dc;	esint16 lin=0;	euint8 *buf;	if(Cache->DiscCluster==0)	{		return(-1);	}	sect=fat_getSectorAddressFatEntry(fs,Cache->DiscCluster);	buf=part_getSect(fs->part,sect,IOM_MODE_READONLY);	dc=fat_getNextClusterAddressWBuf(fs,Cache->DiscCluster,buf);	if(fat_isEocMarker(fs,dc))	{		Cache->LastCluster=Cache->DiscCluster;		part_relSect(fs->part,buf);		return(-1);	}		Cache->DiscCluster=dc;	Cache->LogicCluster++;			lr=Cache->DiscCluster-1;	nlr=lr+1;		while(nlr-1==lr && fat_getSectorAddressFatEntry(fs,nlr)==sect)	{		lr=nlr;		nlr=fat_getNextClusterAddressWBuf(fs,lr,buf);		lin++;		}		Cache->Linear=lin-1<0?0:lin-1;		part_relSect(fs->part,buf);	return(0);}/*****************************************************************************//* ****************************************************************************   * esint16 fat_LogicToDiscCluster(FileSystem *fs, ClusterChain *Cache,euint32 logiccluster) * Description: This function is used to follow clusterchains. When called it will convert * a logical cluster, to a disc cluster, using a Cache object. All it does is call * getNextClusterChain in the proper manner, and rewind clusterchains if required. * It is NOT recommended to go backwards in clusterchains, since this will require * scanning the entire chain every time. * Return value: 0 on success and -1 on failure (meaning out of bounds).*/esint16 fat_LogicToDiscCluster(FileSystem *fs, ClusterChain *Cache,euint32 logiccluster){	if(logiccluster<Cache->LogicCluster || Cache->DiscCluster==0){		Cache->LogicCluster=0;		Cache->DiscCluster=Cache->FirstCluster;		Cache->Linear=0;	}		if(Cache->LogicCluster==logiccluster){		return(0);	}		while(Cache->LogicCluster!=logiccluster)	{		if(Cache->Linear!=0)		{			Cache->Linear--;			Cache->LogicCluster++;			Cache->DiscCluster++;		}		else		{			if((fat_getNextClusterChain(fs,Cache))!=0){				return(-1);			}		}	}	return(0);}/*****************************************************************************//* ****************************************************************************   * eint16 fat_allocClusterChain(FileSystem *fs,ClusterChain *Cache,euint32 num_clusters) * Description: This function extends a clusterchain by num_clusters. It returns the * number of clusters it *failed* to allocate.  * Return value: 0 on success, all other values are the number of clusters it could * not allocate.*/eint16 fat_allocClusterChain(FileSystem *fs,ClusterChain *Cache,euint32 num_clusters){	euint32 cc,ncl=num_clusters,lc;	euint8 *bufa=0,*bufb=0;	euint8  overflow=0;	if(Cache->FirstCluster<=1)return(num_clusters);		lc=fs_getLastCluster(fs,Cache);	cc=lc;		while(ncl > 0){		cc++;		if(cc>=fs->DataClusterCount+1){			if(overflow){				bufa=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,lc),IOM_MODE_READWRITE);				fat_setNextClusterAddressWBuf(fs,lc,fat_giveEocMarker(fs),bufa);				Cache->LastCluster=lc;				part_relSect(fs->part,bufa);				return(num_clusters-ncl);			}			cc=2;			overflow++;		}		bufa=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cc),IOM_MODE_READONLY);		if(fat_getNextClusterAddressWBuf(fs,cc,bufa)==0){			bufb=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,lc),IOM_MODE_READWRITE);			fat_setNextClusterAddressWBuf(fs,lc,cc,bufb);			part_relSect(fs->part,bufb);			ncl--;			lc=cc;		}		part_relSect(fs->part,bufa);		if(ncl==0){			bufa=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,lc),IOM_MODE_READWRITE);			fat_setNextClusterAddressWBuf(fs,lc,fat_giveEocMarker(fs),bufa);			Cache->LastCluster=lc;			part_relSect(fs->part,bufa);		}	}	return(0);}/* ****************************************************************************   * eint16 fat_unlinkClusterChain(FileSystem *fs,ClusterChain *Cache) * Description: This function removes a clusterchain. Starting at FirstCluster * it follows the chain until the end, resetting all values to 0. * Return value: 0 on success.*/eint16 fat_unlinkClusterChain(FileSystem *fs,ClusterChain *Cache){	euint32 c,tbd=0;		Cache->LogicCluster=0;	Cache->DiscCluster=Cache->FirstCluster;		c=0;		while(!fat_LogicToDiscCluster(fs,Cache,c++)){		if(tbd!=0){			fat_setNextClusterAddress(fs,tbd,0);		}		tbd=Cache->DiscCluster;	}	fat_setNextClusterAddress(fs,Cache->DiscCluster,0); 	return(0);}euint32 fat_countClustersInChain(FileSystem *fs,euint32 firstcluster){	ClusterChain cache;	euint32 c=0;		if(firstcluster<=1)return(0);		cache.DiscCluster = cache.LogicCluster = cache.LastCluster = cache.Linear = 0;	cache.FirstCluster = firstcluster;		while(!(fat_LogicToDiscCluster(fs,&cache,c++)));		return(c-1);}euint32 fat_DiscToLogicCluster(FileSystem *fs,euint32 firstcluster,euint32 disccluster){	ClusterChain cache;	euint32 c=0,r=0;		cache.DiscCluster = cache.LogicCluster = cache.LastCluster = cache.Linear = 0;	cache.FirstCluster = firstcluster;		while(!(fat_LogicToDiscCluster(fs,&cache,c++)) && !r){		if(cache.DiscCluster == disccluster){			r = cache.LogicCluster;		}	}	return(r);}

⌨️ 快捷键说明

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