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

📄 hfatfind.c

📁 HFAT32是我依据FAT标准,按照自己的理解写出来的一个FAT文件系统 特性: 1.HFAT32 是一个小型的嵌入式FAT文件系统,可以方便地在nand flash,RAM和SD Card
💻 C
字号:
//---------------------------------------------------------------------------------
// Copyright jinhailiao 2008-2010
// E-mail:   jinhailiao@163.com
// Project:			HFAT16/32
// File:			hfatfind.c
// Description:		
//-------------------------------------------------------------
// Reversion Histroy:
//-------------------------------------------------------------
// Version		date		operations				by who
// 1.0.0		2008-06-26  create                  Kingsea
//---------------------------------------------------------------------------------
#include "hfstype.h"
#include "hfileapi.h"
#include "hfatfind.h"
#include "haiclib.h"
#include "hfatdent.h"
#include "hfatstr.h"
#include "hfatsys.h"
#include "hfatutil.h"


long _hai_findfirstOnFat(S_BYTE disk, S_BYTE *filespec, struct finddata *fileinfo)
{
	S_DWORD clust;
	_SP_FINEINFO pFindInf;

	if ((pFindInf = hai_FatMemAlloc(sizeof(*pFindInf)))==S_NULL)
		return 0;
	if (hai_strlen(filespec)>=FINDINFO_FILEFILTER_MAX)
		return 0;

	clust = _hai_CwdOperate(CWDOPERATE_GETCLUS, S_NULL);
	pFindInf->dev = hai_GetDeviceNum(disk);
	if (DevInf_FatType(pFindInf->dev)==FAT_TYPE_16 && clust == 0)
		pFindInf->SenNum = DevInf_RsvdSec(pFindInf->dev)+DevInf_NumFats(pFindInf->dev)*DevInf_FatSize(pFindInf->dev);
	else
	{
		if (clust == 0)//fat32 root
			clust = DevInf_RootClus(pFindInf->dev);
		pFindInf->SenNum = DevInf_FirstDatSec(pFindInf->dev)+(clust-2)*DevInf_SecPerClust(pFindInf->dev);
	}
	pFindInf->DentNum = 0;
	hai_strcpy(pFindInf->FileFilter, filespec);

	if (_hai_findnextOnFat((long)pFindInf, fileinfo))
	{
		hai_FatMemFree(pFindInf);
		pFindInf = S_NULL;
	}

	return (long)pFindInf;
}

void hai_FillFindData(struct finddata *fileinfo, S_BYTE *DentBuf, S_BYTE *filename)
{
	fileinfo->attrib    = *pDIR_Attr(DentBuf);
	fileinfo->CreatTime = ((S_WORD)(*pDIR_CrtTime(DentBuf))<<16)|*pDIR_CrtDate(DentBuf);//TODO:
	fileinfo->AccesTime = *pDIR_LastAccDate(DentBuf);
	fileinfo->WriteTime = ((S_WORD)(*pDIR_WrtTime(DentBuf))<<16)|*pDIR_WrtDate(DentBuf);
	fileinfo->size      = *pDIR_FileSize(DentBuf);
	hai_strcpy(fileinfo->name, filename);
}

int hai_findnextOnFat16Root(long handle, struct finddata *fileinfo)
{
	S_BYTE ChkSum, LDirOrd = DELETED_DIR_FLAG;
	S_BYTE DentBuf[FAT_DIRENT_SIZE];
	S_BYTE *pSecBuf, SecBuf[FAT_SEC_BUF_MAX];
	S_BYTE tmpname[HAI_FILENAME_MAX+4];
	S_DWORD RootSiz;
	_SP_FINEINFO pFindInf = (_SP_FINEINFO)handle;
	int dev = pFindInf->dev;

	RootSiz  = DevInf_RsvdSec(dev)+DevInf_NumFats(dev)*DevInf_FatSize(dev);
	RootSiz += ((DevInf_RootEntCnt(dev)*FAT_DIRENT_SIZE)+(DevInf_BytsPerSec(dev)-1))/DevInf_BytsPerSec(dev);
	hai_memset(tmpname, 0x00, sizeof(tmpname));
	pSecBuf = SecBuf + pFindInf->DentNum*FAT_DIRENT_SIZE;

	for (; pFindInf->SenNum < RootSiz; pFindInf->SenNum++)
	{//TODO:
		if (_hai_FatDevRead(dev, pFindInf->SenNum, SecBuf))
			return FATERR_DEV_OPERATE_ERR;
		for (; (pSecBuf-SecBuf)<DevInf_BytsPerSec(dev);pSecBuf += FAT_DIRENT_SIZE)
		{
			if (*pDIR_Name(pSecBuf)==EMPTY_DIR_FLAG)//finish
				return FATERR_END_OF_FILE;
			else if (*pDIR_Name(pSecBuf)==DELETED_DIR_FLAG)//invalid dir entry
				LDirOrd = DELETED_DIR_FLAG;
			else if ((*pLDIR_Attr(pSecBuf)&FILE_ATTR_LONG_NAME_MASK)==FILE_ATTR_LONG_NAME)//long name sub-component
			{
				if (*pLDIR_Ord(pSecBuf)&LDIR_LAST_LONG_ENTRY)
				{
					LDirOrd = (*pLDIR_Ord(pSecBuf)&~LDIR_LAST_LONG_ENTRY)-1;
					ChkSum = *pLDIR_Chksum(pSecBuf);
					if (!hai_GetFileNameFromLDent(pSecBuf, tmpname+LDirOrd*LDIR_STR_BYTE_MAX))
						LDirOrd = DELETED_DIR_FLAG;
				}
				else if (LDirOrd==*pLDIR_Ord(pSecBuf) && ChkSum==*pLDIR_Chksum(pSecBuf))
				{
					LDirOrd--;
					if (!hai_GetFileNameFromLDent(pSecBuf, tmpname+LDirOrd*LDIR_STR_BYTE_MAX))
						LDirOrd = DELETED_DIR_FLAG;
				}
				else
				{
					LDirOrd = DELETED_DIR_FLAG;
				}
			}
			else if (((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == 0x00)// find a file
					||((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_DIRECTORY))// find a directory
			{
				if (LDirOrd == 0)//have long name
				{
					hai_Unicode2OtherCode(tmpname);
					if (hai_ShortFileNameChkSum(pSecBuf) != ChkSum)//long name is error
						hai_GetFileNameFromDent(pSecBuf, tmpname);
				}
				else
				{
					hai_GetFileNameFromDent(pSecBuf, tmpname);
				}
				hai_memcpy(DentBuf, pSecBuf, FAT_DIRENT_SIZE);
				pFindInf->DentNum = (pSecBuf-SecBuf)/FAT_DIRENT_SIZE + 1;
				hai_FillFindData(fileinfo, DentBuf, tmpname);
				return FATERR_NO_ERROR;
			}
//			else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_DIRECTORY)// find a directory
//			{
//			}
			else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_VOLUME_ID)// find a volume lab
				LDirOrd = DELETED_DIR_FLAG;
			else
				LDirOrd = DELETED_DIR_FLAG;// illegal dir entry
		}
		pSecBuf = SecBuf;
	}

	return FATERR_END_OF_FILE;
}

int __hai_findnextOnFat(long handle, struct finddata *fileinfo)
{
	S_BYTE ChkSum, LDirOrd = DELETED_DIR_FLAG;
	S_BYTE DentBuf[FAT_DIRENT_SIZE];
	S_BYTE *pSecBuf, SecBuf[FAT_SEC_BUF_MAX];
	S_BYTE tmpname[HAI_FILENAME_MAX+4];
	S_DWORD SecEnd, FirstSec, clust;
	_SP_FINEINFO pFindInf = (_SP_FINEINFO)handle;
	int dev = pFindInf->dev;

	if (DevInf_FatType(dev) == FAT_TYPE_16)
	{
		FirstSec  = DevInf_RsvdSec(dev)+DevInf_NumFats(dev)*DevInf_FatSize(dev);
		FirstSec += ((DevInf_RootEntCnt(dev)*FAT_DIRENT_SIZE)+(DevInf_BytsPerSec(dev)-1))/DevInf_BytsPerSec(dev);
		if (pFindInf->SenNum < FirstSec)
			return hai_findnextOnFat16Root(handle, fileinfo);
	}

	hai_memset(tmpname, 0x00, sizeof(tmpname));
	FirstSec = pFindInf->SenNum - DevInf_FirstDatSec(dev);
	clust  = FirstSec/DevInf_SecPerClust(dev) + 2;

	FirstSec = DevInf_FirstDatSec(dev)+(clust-2)*DevInf_SecPerClust(dev);
	SecEnd = FirstSec + DevInf_SecPerClust(dev);
	
	FirstSec = pFindInf->SenNum;
	pSecBuf = SecBuf + pFindInf->DentNum * FAT_DIRENT_SIZE;

	while (DevInf_FatType(dev)==FAT_TYPE_16?IS_FAT16_INUSE_CLUST(clust):IS_FAT32_INUSE_CLUST(clust))
	{
		for (; FirstSec < SecEnd; FirstSec++)
		{
			if (_hai_FatDevRead(dev, FirstSec, SecBuf))
				return FATERR_DEV_OPERATE_ERR;
			for (; (pSecBuf-SecBuf)<DevInf_BytsPerSec(dev);pSecBuf += FAT_DIRENT_SIZE)
			{
				if (*pDIR_Name(pSecBuf)==EMPTY_DIR_FLAG)//finish
					return FATERR_END_OF_FILE;
				else if (*pDIR_Name(pSecBuf)==DELETED_DIR_FLAG)//invalid dir entry
					LDirOrd = DELETED_DIR_FLAG;
				else if ((*pLDIR_Attr(pSecBuf)&FILE_ATTR_LONG_NAME_MASK)==FILE_ATTR_LONG_NAME)//long name sub-component
				{
					if (*pLDIR_Ord(pSecBuf)&LDIR_LAST_LONG_ENTRY)
					{
						LDirOrd = (*pLDIR_Ord(pSecBuf)&~LDIR_LAST_LONG_ENTRY)-1;
						ChkSum = *pLDIR_Chksum(pSecBuf);
						if (!hai_GetFileNameFromLDent(pSecBuf, tmpname+LDirOrd*LDIR_STR_BYTE_MAX))
							LDirOrd = DELETED_DIR_FLAG;
					}
					else if (LDirOrd==*pLDIR_Ord(pSecBuf) && ChkSum==*pLDIR_Chksum(pSecBuf))
					{
						LDirOrd--;
						if (!hai_GetFileNameFromLDent(pSecBuf, tmpname+LDirOrd*LDIR_STR_BYTE_MAX))
							LDirOrd = DELETED_DIR_FLAG;
					}
					else
					{
						LDirOrd = DELETED_DIR_FLAG;
					}
				}
				else if (((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == 0x00)// find a file
						||((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_DIRECTORY))// find a directory
				{
					if (LDirOrd == 0)//have long name
					{
						hai_Unicode2OtherCode(tmpname);
						if (hai_ShortFileNameChkSum(pSecBuf) != ChkSum)//long name is error
							hai_GetFileNameFromDent(pSecBuf, tmpname);
					}
					else
					{
						hai_GetFileNameFromDent(pSecBuf, tmpname);
					}
					hai_memcpy(DentBuf, pSecBuf, FAT_DIRENT_SIZE);
					pFindInf->SenNum  = FirstSec;
					pFindInf->DentNum = (pSecBuf-SecBuf)/FAT_DIRENT_SIZE + 1;
					hai_FillFindData(fileinfo, DentBuf, tmpname);
					return FATERR_NO_ERROR;
				}
//				else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_DIRECTORY)// find a directory
//				{
//				}
				else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_VOLUME_ID)// find a volume lab
					LDirOrd = DELETED_DIR_FLAG;
				else
					LDirOrd = DELETED_DIR_FLAG;// illegal dir entry
			}
			pSecBuf = SecBuf;
		}
		clust = hai_GetNextCluster(dev, clust);
		FirstSec = DevInf_FirstDatSec(dev) + (clust-2)*DevInf_SecPerClust(dev);//get first sec of clust;
		SecEnd = FirstSec+DevInf_SecPerClust(dev);
	}

	return FATERR_END_OF_FILE;
}

int hai_filefilter(S_BYTE *filerilter, S_BYTE *filename)
{
	return 0;
}

int _hai_findnextOnFat(long handle, struct finddata *fileinfo)
{
	int err;
	_SP_FINEINFO pFindInf = (_SP_FINEINFO)handle;

	do{
		err = __hai_findnextOnFat(handle, fileinfo);
	}while (!err && hai_filefilter(pFindInf->FileFilter, fileinfo->name));

	return err;
}


⌨️ 快捷键说明

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