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

📄 fat.c

📁 s3c6400 ADS下官方测试程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (headcluster<=FAT_FREE_CLUSTER)
	{
		*nRelCluster = -1;  // FAT_FREE_CLUSTER == 0
		return;
	}
	if (LAST_CLUSTER(headcluster))
	{
		*nRelCluster = -2;  // headcluster == oFat.m_nEOC (End Of Cluster)
		return;
	}
	oFat.m_nLastFreeCluster = headcluster;

	while (!LAST_CLUSTER(headcluster)) {
		FAT_ClusterFatAddr(headcluster, &sector, &offset, sCh);
		FAT_GetFat(sector, offset, &headcluster, &sTmp, sCh);
		Assert(sTmp>0);
		FAT_SetFat(offset, FAT_FREE_CLUSTER, oFat.m_pFatBuffStart, sCh);
		if (!headcluster) {
			Assert(0);
			printf("release_cluster_chain(): headcluster: %d\n", headcluster);
			break;
		}
		if (++count==nLength) break;
	}

	FAT_WriteFatContent(&nFatContent, sCh);
	*nRelCluster = headcluster;
}

/*******************************************************/
/* allocate a cluster chain with specified size        */
/*******************************************************/
// FAT table maker

void FAT_AllocateClusterChain(int ucMode, int *numberofcluster, int nPosi, int rstart, int rend, int* uAlloCluster, SDHC* sCh)
{
	int start_sector, offset, nHeadCluster=0, pcluster=0;
	int cluster=nPosi, clucount=oFat.m_nBpbCountOfClusters+2, size=*numberofcluster;
	int nFatContent1;
	int nFatContent2;

	if (size<=0)
	{
		*uAlloCluster = 0;
		return;
	}
	while (cluster<clucount) {
		int res;
		int sTmp;

		if (rstart) {
			if (cluster>=rstart&&cluster<rend) {
				Assert(rend>rstart);
				cluster=rend;
				if (cluster>=clucount)
					break;
			}
		}

		FAT_ClusterFatAddr(cluster, &start_sector, &offset, sCh);  // offset: in bytes
		printf("allo_cchain(): start_sector: %d, offset: %d\n", start_sector, offset);

		FAT_GetFat(start_sector, offset, &sTmp, &res, sCh);
		Assert(res>0);
		if ((sTmp&oFat.m_nMaskCluster) == FAT_FREE_CLUSTER) 
		{
			int psector, poffset, entry;
			if (!nHeadCluster) 
				nHeadCluster = cluster;
			if (pcluster) 
			{  /* do link here */
				FAT_ClusterFatAddr(pcluster, &psector, &poffset, sCh);
				FAT_GetFat(psector, poffset, &entry, &res, sCh);
				Assert(res>0);
				Assert(!(entry&oFat.m_nMaskCluster));
				FAT_SetFat(poffset, cluster, oFat.m_pFatBuffStart, sCh);
				///WriteFatContent();  // LYS 040429 add  //LYS 040507 delete to speed up
			}
			pcluster = cluster;
			if (--size==0) 
			{     // end processing */
				FAT_ClusterFatAddr(pcluster, &psector, &poffset, sCh);
				FAT_GetFat(psector, poffset, &entry, &res, sCh);
				Assert(res>0);
				Assert(!(entry&oFat.m_nMaskCluster));
				FAT_SetFat(poffset, oFat.m_nEOC, oFat.m_pFatBuffStart, sCh);

				FAT_WriteFatContent(&nFatContent1, sCh);
				*uAlloCluster = nHeadCluster;
				return;
			}
		}
		cluster++;
	}

	FAT_WriteFatContent(&nFatContent2, sCh);
	// in case of absent memory
	if (ucMode) { // do not release cluster chain */
		*numberofcluster -= size;
	}
	else if (nHeadCluster) { // release cluster chain */
		int nRelCluster;
		FAT_ReleaseClusterChain(nHeadCluster, 1, &nRelCluster, sCh);
		*numberofcluster = nHeadCluster = 0;
	}
	*uAlloCluster = nHeadCluster;
}

/***************************************************************************/
/* for new cluster, we setup 32 entries to termination for long name space */
/***************************************************************************/
//only used in DIR_search_file_entry()
void FAT_AppendProcess(u8 *ucBuffer, int sector, int termination, SDHC* sCh)
{
	int i, k;

	if (termination==3)
		Assert(oFat.m_ucBpbSecPerClus>=2);
	for (k=0; k<termination-1; k++) {
		u8 *p = ucBuffer;
		for (i=0; i<16; i++) {
			FAT_CopyEntry(p, TERM_ENTRY_TAG, sCh);  //TERM_ENTRY_TAG == 0x0000
			p += DIR_ENTRY_SIZE;
		}
		FAT_WriteSector(ucBuffer, sector+k, 1, sCh);
	}
}

/************************************************************************/
/* for term entry, we check if next entry is avaible and do exit        */
/************************************************************************/
//only used in DIR_search_file_entry()
void FAT_ProcessTerm(u8 *nPosi, u8 *ucBuffer, int sector, int num, int* nNextEnt, SDHC* sCh)
{
	u8 *p = nPosi+DIR_ENTRY_SIZE;
	u8 *buff_end=ucBuffer+oFat.m_usBpbBytsPerSec;

	if (num > 1) {
		FAT_CopyEntry(nPosi, FREE_ENTRY_TAG, sCh);
		*nNextEnt = 1;
	}
	else if (p < buff_end) {
		if (p[0] != TERM_ENTRY_TAG0) {
			FAT_CopyEntry(p, TERM_ENTRY_TAG, sCh);
			FAT_WriteSector(ucBuffer, sector, 1, sCh);
		}
		*nNextEnt =  0;
	}
	else {
		*nNextEnt = 2;
	}
}

/*************************************************************/
/* long file name processing: collect, compare and overwrite */
/*************************************************************/
//only used in DIR_search_file_entry()
void FAT_ProcessLfname(short *lfname, u8 *nPosi, u8 *ucBuffer, int sector, int *pcsum, int* nProLFname, SDHC* sCh)
{
	u8 *buff_end = ucBuffer+oFat.m_usBpbBytsPerSec;
	int match=-1;
	int nLfname;
	int ucNerror;

	FAT_CollectLFileName(oFat.m_sClfName, nPosi, &nLfname, sCh);
	ucNerror = nLfname;

	if (ucNerror>0)
	{
		u8 *p = nPosi+DIR_ENTRY_SIZE;    // p: directory entry structure
		int nOrphan;
		FAT_CheckOrphan(p, &nOrphan, sCh);
		if (p<buff_end && nOrphan )
		{
			ucNerror = -1;
		}
		else
		{
			*pcsum = nPosi[13];
			FAT_Compare2UnicodeLFileName(oFat.m_sClfName, lfname, &match, sCh);
		}
	}
	if (ucNerror<=0)
	{
		if (ucNerror==-1)
		{ // auto erase invalid entry */
			FAT_CopyEntry(nPosi, FREE_ENTRY_TAG, sCh);
			FAT_WriteSector(ucBuffer, sector, 1, sCh);
		}
		*pcsum = 0;
	}
	*nProLFname = match; // -1 no compare; 0 doesn't match; 1 match */
}
/************************************************************************/
/* match entry processing: check sum, short name compare and info save  */
/************************************************************************/
void FAT_MatchProcess(int match, int checksum, u8 *p, ISOFILE *pfile, int* nMatEnt, SDHC* sCh)
{
	int i, j, ok=0;
	int nComArray;
	u32 nEntCluster;

	if (match)
	{
		u8 temp;
		FAT_ComputeChkSum(p, &temp, sCh);
		if (checksum== temp)
			ok = 1;
		else
		{
			ok = 1; Assert(0);
			//EPRINTF(("csum:%x:%x\n", checksum, ComputeChkSum(p)));
		}
	}
	else
	{
		j = -1;
		for (i = 0; i<=SF_NAME_LENGTH; i++)
		{
			if (p[i] == '~')
				j = i;
			if ((i>=j) && (j >= 0)) {
				p[i] = oFat.m_ucFsfname[i];
			}
		}

		for (i=SF_NAME_LENGTH; i>0; i--) {
			if (oFat.m_ucFsfname[i-1] != ' ') break;
		}

		FAT_CompareArray(oFat.m_ucFsfname, p, i, &nComArray, sCh);
		ok = !nComArray;  //LYS 040102 strncmp() was used.
	}
	if (ok) {
		// Calculate start cluster and save in location */
		pfile->size = LSB_GET_4BYTES(p+28);

		FAT_GetEntryCluster(p, &nEntCluster, sCh);
		pfile->addr = nEntCluster;
		pfile->ucAttr = p[11];
		*nMatEnt = 1;
	}
	else
		*nMatEnt = 0;
}

/************************************************************************/
/* match entry processing: check sum, short name compare and info save  */
/************************************************************************/
void FAT_AttributeFile(u8 *p, int* nAttriFile, SDHC* sCh)  // p: FAT32 byte directory entry structure
{
	int res;

	/* the ucAttr match checking */
	if (((p[11]&ATTR_VOLUME_ID)==ATTR_VOLUME_ID)&&((p[11]&ATTR_LONG_NAME)!=ATTR_LONG_NAME))
	{ // volume ID */
		res=0;
	}
	else if ((p[11]&ATTR_LONG_NAME)==ATTR_LONG_NAME && p[0]!=FREE_ENTRY_TAG0)
	{ // long name */  // 0xe5 == no file or dir in this entry.
		res=1;
	}
	else if (p[0]==DOT_ENTRY_TAG0)
	{	// . entry */
		res=2;
	}
	else
	{
		res=3;		// other else */
	}
	*nAttriFile = res;
}

/************************************************************************/
/* search the specified file on hd, always using unicode long file name */
/************************************************************************/
void FAT_SearchDirFileEntry(int location, short *lfname, int entry_num, u8 ucAttr,
	ISOFILE *pfile, int *sector, int *offset, int *clus, int* nSpecFile, SDHC* sCh)
{
	char cSfname[SF_NAME_LENGTH+1];
	u8 *buff_start, *buff_end;
	int precluster;
	int cluster = ((location)?location:oFat.m_uBpbRootClus);
	int checksum;
	int match=0, sector_offset=0, termination=0, num=entry_num;
	int start_sector, ftype, longfilename=0;
	int nSfnameconv;
	int temp;
	int nAnoChain;

	if ((lfname!=NULL&&entry_num!=1)||(entry_num<1||entry_num>32))
		*nSpecFile = 0;
	if (lfname)
	{
		FAT_GenerateSNameFromLName(lfname, cSfname, &temp, sCh);

		FAT_FormatSFileName(oFat.m_ucFsfname, cSfname, &nSfnameconv, sCh);
		if (nSfnameconv < 0)
			*nSpecFile = 0;
	}
	//buff_start = oFat.m_ucDirBuffStart;
	FAT_InitBuffSearchMem(&buff_start, sCh);  // LYS 040407
	buff_end = buff_start + oFat.m_usBpbBytsPerSec;
	*clus = cluster;

	while (!LAST_CLUSTER(cluster))
	{
		u8 *p = buff_start;
		int nLba;

		FAT_FromClusterToLba(cluster, &nLba, sCh);
		start_sector = nLba + sector_offset;
		FAT_ReadSector(buff_start, start_sector, 1, sCh);
		if (termination > 1)
		{
			FAT_AppendProcess(buff_start, start_sector, termination, sCh);
			if (termination==3)
			{
				FAT_UnifySector(sector, offset, start_sector, (num-1)*DIR_ENTRY_SIZE, sCh);
			}
			*nSpecFile = 1;
		}
		while (p<buff_end)
		{
			FAT_UnifySector(sector, offset, start_sector, p-buff_start, sCh);
			if(p[0]==TERM_ENTRY_TAG0 || termination==1) /*terminating */
			{
				if (lfname!=NULL)
					*nSpecFile = 0;
				FAT_ProcessTerm(p, buff_start, start_sector, num, &termination, sCh);
				if (!termination)
					*nSpecFile = 1;
				if (termination==1)
					num--;
				else
					break;
				longfilename=0;
			}
			else if (p[0]==FREE_ENTRY_TAG0) /*deleted file(dir) */
			{
				if (lfname==NULL) {
					if (num>1)
						num--;
					else
						*nSpecFile = 1;
				}
				longfilename=0;
			}
			else if ((lfname!=NULL)&&(p[11]&ucAttr)==p[11]) /* match a file we want */
			{
				num = entry_num;
				FAT_AttributeFile(p, &ftype, sCh);
				if (ftype==1) {  // long name
					FAT_ProcessLfname(lfname, p, buff_start, start_sector, &checksum, &match, sCh);
					if (!match)
						longfilename = 1;
					else {
						longfilename = 0;
						if (match<0)
							match = 0;
					}
				}
				else if (ftype>=2&&!longfilename) {  // 2: . entry, more than 3: short name
					int nMatEnt;
					FAT_MatchProcess(match, checksum, p, pfile, &nMatEnt, sCh);
					if (nMatEnt) {
						*nSpecFile = 1;   // short name compare using checksum, oFat.m_ucFsfname
					}
					match = 0;
					longfilename = 0;
				}
			}
			else
			{
				num = entry_num;
				longfilename = 0;
			}
			if (match)
			{
				match++;
				if (match==3)
				{
					match = 0;
					checksum = 0;
				}
			}
			p += DIR_ENTRY_SIZE;
		} // end of while (p<buff_end)
		if (termination) {
			FAT_WriteSector(buff_start, start_sector, 1, sCh);
		}
		sector_offset++;
		if (!cluster) {
			if (sector_offset>=oFat.m_usRootDirSectors)
				break;
		}
		else if (sector_offset>=oFat.m_ucBpbSecPerClus) {
			num = entry_num;
			sector_offset = 0;
			precluster = cluster;
			FAT_GetNextCluster(cluster, &cluster, sCh);
			Assert(cluster!=0);
			if (termination&&LAST_CLUSTER(cluster))
			{
				int size=1;
				FAT_AllocateClusterChain(0, &size, 2, 0, 0, &cluster, sCh);
				Assert(cluster);
				if (!cluster)
					break;

				FAT_AppendCluster(precluster, cluster, &nAnoChain, sCh);
				if (termination==1)
					termination = 3;
			}
		}

⌨️ 快捷键说明

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