f_fat.c

来自「基于arm9的,usb设备(u盘)的读写操作实现.」· C语言 代码 · 共 664 行 · 第 1/2 页

C
664
字号
				nextCluster = F_FAT_GetNextCluster(pHandle, F_FAT_SectorToCluster(pHandle, Cursor->CurrentSectorAddr));
				if(nextCluster == 0)
					return EOF_FATCHAIN;
				nextSector = F_FAT_ClusterToSector(pHandle, nextCluster);
				Cursor->CurrentSectorAddr = nextSector;
				if(F_ReadSector(hFile, Cursor->CurrentSectorAddr, 1, prSectorBuf))
					return F_ERR_DRIVER_READ_FAILURE;
				de = (F_direntry *)prSectorBuf;
			}	
		}
		else
		{
			if(Cursor->DirEntryIndex == 0)
			{
				Cursor->CurrentSectorAddr ++;//= Cursor->SectorOffset;
			}
			if(F_ReadSector(hFile, Cursor->CurrentSectorAddr, 1, prSectorBuf))
					return F_ERR_DRIVER_READ_FAILURE;
			de = (F_direntry *)prSectorBuf;
		}
		
		if(de == NULL)
			return EOF_CLUSTER;
		for(de += Cursor->DirEntryIndex;Cursor->DirEntryIndex<(pHandle->BytesPerSector/DIRENTRY_SIZE); Cursor->DirEntryIndex++)	
		{
			if(*de->deName == SLOT_EMPTY)
			{
				return EOF_CLUSTER;
			}
			if((LFNlen!=0)&&(*de->deName != SLOT_DELETED)&&(de->deAttributes== ATTR_LONG_FILENAME))
			{
				F_FAT_GetLFN((u8 *)de, LFNBuf);
				g_lfnflag = 1;
			}
			if((*de->deName != SLOT_DELETED)&&(de->deAttributes != ATTR_LONG_FILENAME))
			{
				*pde = *de;
				Cursor->DirEntryIndex++;
				return ERR_NONE;
			}
			else
			{
				de++;
			}
		}
		Cursor->DirEntryIndex = 0;
	}
	return EOF_FATCHAIN;
}

u32 F_FAT_GetNextCluster(FAT_HANDLE *pHandle, u32 Cluster)
{
	u32 u32currnetsector = 0, nextCluster = 0;
	u32 sectorIndex = 0, fatmask = 0xffffffff;
	u16 sectorOffset = 0;
	u8 Buffer[512] = {0}, fatoffset = 0;

	if(pHandle->PartType == PART_TYPE_FAT32)
	{
		if(Cluster == 0)
			Cluster = pHandle->FirstDirCluster;
		fatoffset = 4;
		fatmask = FAT32_MASK;
	}
	else if(pHandle->PartType == PART_TYPE_FAT16)
	{
		if(Cluster == 0)
			return 0;
		fatoffset = 2;
		fatmask = FAT16_MASK;
	}

	sectorIndex = Cluster/(pHandle->BytesPerSector/fatoffset);
	sectorOffset = Cluster%(pHandle->BytesPerSector/fatoffset);//by bytes * 4
	u32currnetsector = pHandle->FirstFATSector + sectorIndex;

	if(F_ReadSector(hFile, u32currnetsector, 1, prFATBuffer))
		return F_ERR_DRIVER_READ_FAILURE;
	nextCluster = *((u32 *)(&prFATBuffer[sectorOffset*fatoffset])) & fatmask;
	
	if(nextCluster == fatmask) 
		nextCluster = 0;
	return nextCluster;
}

void F_FAT_BrowsingReset(FAT_HANDLE *pHandle, F_BrowsingCursor *Cursor)
{
	Cursor->CurrentEntryIndex = 0;
	Cursor->CurrentSectorAddr = F_FAT_ClusterToSector(pHandle, pHandle->currentDirCluster);
	Cursor->DirEntryIndex = 0;
	Cursor->SectorOffset = 0;
}

void F_FAT_GetLFN(u8 *debuf, u16 *LFN)
{
	u8 i = 0, LfnCounter = 0, j = 0;

	LfnCounter = debuf[i++]&0x0F;
	for(j = 0;j<5;j++,i +=2)
		LFN[(LfnCounter-1)*13 + j] = debuf[i] + (debuf[i+1]<<8);
	i += 3;
	for(j = 5;j<11;j++,i+=2)
		LFN[(LfnCounter-1)*13 + j] = debuf[i] + (debuf[i+1]<<8);
	i += 2;
	for(j = 11;j<13;j++,i+=2)
		LFN[(LfnCounter-1)*13 + j] = debuf[i] + (debuf[i+1]<<8);	
}

u8 F_FAT_DirEntryToSFN(F_direntry *pde, c8 *SFNBuf, u8 SFNlen)
{
	u8 i,j = 0;

	if(SFNlen < 13)
		return 1;

	memset(SFNBuf,0,SFNlen);

	for(i=0;i<8;i++)
	{
		if(pde->deName[i] == 0x20)
			break;
		else
			SFNBuf[i] = (c8)(pde->deName[i]);
	}
		
	if((pde->deLowerCase & LCASE_BASE) == LCASE_BASE)
		strlwr(SFNBuf);
	
	if(pde->deExtension[0] != 0x20)
	{
		SFNBuf[strlen(SFNBuf)] = '.';
		i = strlen(SFNBuf);

		for(j=0;j<3;j++)
		{
			if(pde->deExtension[j] == 0x20)
				break;
			else
				SFNBuf[i+j] = (c8)(pde->deExtension[j]);
		}
		if((pde->deLowerCase & LCASE_EXT) == LCASE_EXT)
			strlwr(&SFNBuf[i]);
	}

	return 0;
}	

u8 F_FAT_GetFileInfo(F_direntry *pde, F_FileInfo *fileInfo)
{
	u16 date, time;

	fileInfo->fileINF_size = pde->deFileSize;
	fileInfo->fileINF_start_cluster = pde->deStartCluster + (pde->deHighClust<<16);

	return 0;
}

u8 F_FAT_CheckIfLFN(c8 *filename, u8 *fdbnum)
{
	u16 i = 0;
	
	c8 *ePtr;
	u16 eNameLen,eNameOff=0;
	c8 c;

	u16 FirstSpacePos=0;
	u8	SpaceCount=0;
	
	u16 FirstDotPos=0;
	u8 DotNum=0;
	
	u16 ExtPos=0;
	u8	ExtFlag=0;

	u8 SpecialCharExist=0;
	u16 unicode[MAX_LFN_BUF] = {0};

	eNameLen = strlen(filename);
	ePtr = filename;

	eNameOff=i;
	ePtr+=i;

	for(i=eNameOff;i<eNameLen;i++)
	{
		c=ePtr[i];
		
		if(ExtFlag == 1&&c!='.')
		{
			ExtPos++;
		}
		if(c=='.')
		{
			ExtFlag = 1;
			ExtPos = 0;
			
			if(FirstDotPos==0)
				FirstDotPos = i;
			DotNum++;
		}
		else if(c==' ')
		{
			if(FirstSpacePos==0)
				FirstSpacePos = i;
			
			SpaceCount++;
		}
		else if(c== '+'||c== ','||c==';'||c== '='||c=='['||c==']')
		{
			SpecialCharExist=1;
		}
	}
	if((eNameLen-eNameOff > 12)
		||(ExtPos>3)||(DotNum>1)
		||(((FirstSpacePos+SpaceCount)<(eNameLen-eNameOff))&&(SpaceCount>0))
		||(SpecialCharExist)
		|| ((FirstDotPos==0)&&(eNameLen-eNameOff > 8)))
	{
		eNameLen = MX_GB2312StrToUniStr((u8 *)filename, unicode);
		*fdbnum += eNameLen/13;
		if(eNameLen%13 !=0)
			*fdbnum +=1;
		return 1;
	}else
	{
		return 0;
	}
}


u8 F_FAT_GetExtName(c8 * filename, c8 * ExtName)
{
	u8 i = 0,j = 0, namelen = strlen(filename);

	for(i = 0; i<namelen;i++)
	{
		if(filename[i] == '.')
			break;
	}
	if(i== namelen)
		return ERR_NO_EXTNAME;
	i++;
	for(j=0;j<3;j++,i++)
	{
		if(filename[i] != '\0')
			ExtName[j] = filename[i];
		else
			break;
	}
	ExtName[j] = '\0';
	return ERR_NONE;
}

u8 F_FAT_LfnCheckSum(c8 *shortname)
{
	u8 Sum = 0, i;
  	for (i = 0; i < 11; i++)
  	{
    		Sum = (((Sum & 1) << 7) | ((Sum & 0xFE) >> 1)) + shortname[i];
  	}
  	return Sum;
}

void F_FAT_NormalizeName(c8 *oriname, c8 *tarname)
{
	u8 i =0, len = strlen(tarname);
	c8 extname[4] = {0};

	for(;i<len;i++)
	{
		if(tarname[i]!='.')
			oriname[i] = tarname[i];
		else
		{
			F_FAT_GetExtName(tarname, extname);
			break;
		}
	}
	while(i<8)
		oriname[i] = 0x20;

	if(extname[0] != 0)
	{
		for(i = 8;i<11;i++)
			oriname[i] = extname[i-8];
	}
	else
	{
		for(i = 8;i<11;i++)
		{
			if(tarname[i]!='\0')
				oriname[i] = tarname[i];
			else
				break;
		}
	}
	oriname[i] = '\0';
	strupr(oriname);
}

void F_FAT_DirInit(FAT_HANDLE *pHandle)
{
	pHandle->currentDirCluster = pHandle->FirstDirCluster;
}

u8 F_FAT_GetDirLayer(c8 *Direntry, u8 *Layer)
{
	u8 i = 0, layer = 0, j= 0;
	
	if(Direntry[0]!= g_CurrentDir[0])
		return ERR_DIRENTRY;
	memset((u8 *)g_direntry, 0, MAX_DIR_LEN*MAX_LAYER);
	for(layer = 0; layer<MAX_LAYER;layer++)
	{
		for(i=0;i<MAX_DIR_LEN;i++)
		{
			if(Direntry[j] == '\\' || Direntry[j] == '\0')
				break;
			g_direntry[layer][i] = Direntry[j];
			j++;
		}
		if(Direntry[j] == '\0')
			break;
		j++;
	}
	if(Direntry[j]!='\0')
		return ERR_DIRENTRY;
	*Layer = layer+1;
	return ERR_NONE;
}

⌨️ 快捷键说明

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