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

📄 hfatdent.c

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

int _hai_TruncateFile(int dev, S_DWORD SecNum, S_WORD DentNum)
{
	int err;
	S_BYTE *pSecBuf, SecBuf[FAT_SEC_BUF_MAX];
	S_WORD ClustHi;
	S_WORD ClustLo;
	S_DWORD FstClust;

	if (err = _hai_FatDevRead(dev, SecNum, SecBuf))
		return err;
	pSecBuf = SecBuf+DentNum*FAT_DIRENT_SIZE;
	ClustHi = HAI_MAKEWORD(pDIR_FstClusHI(pSecBuf));
	ClustLo = HAI_MAKEWORD(pDIR_FstClusLO(pSecBuf));
	FstClust = HAI_COMBDWORD(ClustHi, ClustLo);
	if ((err = hai_UnlinkClust(dev, FstClust))==0x00)
	{
		HAI_WRITEWORD(pDIR_FstClusHI(pSecBuf), 0x00);
		HAI_WRITEWORD(pDIR_FstClusLO(pSecBuf), 0x00);
		HAI_WRITEDWORD(pDIR_FileSize(pSecBuf), 0x00);
		err = _hai_FatDevWrite(dev, SecNum, SecBuf);
	}
	
	return err;
}

S_BYTE hai_ShortFileNameChkSum(S_BYTE *pName)
{
	int i = 0;
	S_BYTE sum = 0;

	for (i = 0; i < 11; i++)
		sum = ((sum&1)?0x80:0x00) + (sum>>1) + pName[i];
	
	return sum;
}

void hai_FillDent(S_BYTE *dent, S_BYTE *Name83, S_BYTE attr, S_DWORD filesize, S_DWORD clust)
{
	S_WORD Time = hai_GetTime16();
	S_WORD Date = hai_GetDate16();

	hai_memset(dent, 0x00, FAT_DIRENT_SIZE);
	hai_WriteShortName2Dent(dent, Name83);
	*pDIR_Attr(dent) = attr;
	*pDIR_CrtTimeTenth(dent) = hai_GetTimeTenth8();
	HAI_WRITEWORD(pDIR_CrtTime(dent), Time);
	HAI_WRITEWORD(pDIR_CrtDate(dent), Date);
	HAI_WRITEWORD(pDIR_LastAccDate(dent), Date);
	HAI_WRITEWORD(pDIR_FstClusHI(dent), clust>>16);
	HAI_WRITEWORD(pDIR_WrtTime(dent), Time);
	HAI_WRITEWORD(pDIR_WrtDate(dent), Date);
	HAI_WRITEWORD(pDIR_FstClusLO(dent), clust);
	HAI_WRITEDWORD(pDIR_FileSize(dent), filesize);
}

void hai_UpdateDent(S_BYTE *dent, S_BYTE IsWrite)
{
	S_WORD Time = hai_GetTime16();
	S_WORD Date = hai_GetDate16();

	HAI_WRITEWORD(pDIR_LastAccDate(dent), Date);
	if (IsWrite)
	{
		HAI_WRITEWORD(pDIR_WrtTime(dent), Time);
		HAI_WRITEWORD(pDIR_WrtDate(dent), Date);
	}
}

S_WORD hai_FillLDent(S_BYTE *dent, const S_BYTE *LongName, S_BYTE ChkSum, S_BYTE Order)
{
	S_BYTE NameBuf[LDIR_STR_BYTE_MAX];
	S_WORD len = hai_CountByteUni(LongName);

	if (len > LDIR_STR_BYTE_MAX)
		len = LDIR_STR_BYTE_MAX;
	hai_memcpy(NameBuf, LongName, len);
	if (len < LDIR_STR_BYTE_MAX)
	{
		NameBuf[len] = 0, NameBuf[len+1] = 0;
		hai_memset(NameBuf+len+2, 0xFF, LDIR_STR_BYTE_MAX-len-2);
	}

	*pLDIR_Ord(dent) = Order;
	*pLDIR_Attr(dent) = FILE_ATTR_LONG_NAME;
	*pLDIR_Type(dent) = 0;
	*pLDIR_Chksum(dent) = ChkSum;
	HAI_WRITEWORD(pLDIR_FstClusLO(dent), 0x00);
	hai_memcpy(pLDIR_Name1(dent), NameBuf, sLDIR_Name1);
	hai_memcpy(pLDIR_Name2(dent), NameBuf+sLDIR_Name1, sLDIR_Name2);
	hai_memcpy(pLDIR_Name3(dent), NameBuf+sLDIR_Name1+sLDIR_Name2, sLDIR_Name3);

	return (S_WORD)len;
}

#if 0
int hai_FindDentOnFAT16Root(int dev, S_BYTE *dentName, S_BYTE *dentbuf)
{
	S_BYTE LDirOrd = DELETED_DIR_FLAG;
	S_BYTE *pSecBuf;
	S_DWORD RootSec = DevInf_RsvdSec(dev)+DevInf_NumFats(dev)*DevInf_FatSize(dev);
	S_DWORD RootSiz = ((DevInf_RootEntCnt(dev)*FAT_DIRENT_SIZE)+(DevInf_BytsPerSec(dev)-1))/DevInf_BytsPerSec(dev);
	S_BYTE SecBuf[FAT_SEC_BUF_MAX];
	S_BYTE tmpname[HAI_FILENAME_MAX+4], *pLDir = tmpname;

	if (!*dentName || IS_FAT_CUR_DIR(dentName) || IS_FAT_BACK_DIR(dentName))
		return FATERR_INVALID_PATH;

	hai_memset(tmpname, 0x00, sizeof(tmpname));

	for (RootSiz += RootSec; RootSec < RootSiz; RootSec++)
	{
		if (_hai_FatDevRead(dev, RootSec, SecBuf))
			return FATERR_DEV_OPERATE_ERR;
		for (pSecBuf = SecBuf; (pSecBuf-SecBuf)<DevInf_BytsPerSec(dev);pSecBuf += FAT_DIRENT_SIZE)
		{
			if (*pDIR_Name(pSecBuf)==EMPTY_DIR_FLAG)//finish
			{
				if (!hai_stricmp(dentName, tmpname))//compare previous
					return 0;						
				return FATERR_INVALID_PATH;
			}
			else if (*pDIR_Name(pSecBuf)==DELETED_DIR_FLAG)//invalid dir entry
				LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
			else if ((*pLDIR_Attr(pSecBuf)&FILE_ATTR_LONG_NAME_MASK)==FILE_ATTR_LONG_NAME)//long name sub-component
			{
				if (LDirOrd+1 == (*pLDIR_Ord(pSecBuf)&~LDIR_LAST_LONG_ENTRY))
				{
					int num = hai_GetFileNameFromLDent(pSecBuf, pLDir);
					if (!num)
					{
						LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
						continue;
					}
					if (*pLDIR_Ord(pSecBuf)&LDIR_LAST_LONG_ENTRY)
					{
						if (hai_ShortFileNameChkSum(dentbuf)==*pLDIR_Chksum(pSecBuf) && !hai_stricmp(dentName, tmpname))
							return 0;
						LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
					}
					else
					{
						if (num == LDIR_STR_CHAR_MAX)//because it stores 26 char in one long dent
							LDirOrd += 1, pLDir += num;
						else//be error
							LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
					}
				}
			}
			else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == 0x00)// find a file
			{
				if (!hai_stricmp(dentName, tmpname))//compare previous
					return 0;						
				LDirOrd = 0, pLDir = tmpname;
				hai_memcpy(dentbuf, pSecBuf, FAT_DIRENT_SIZE);
				hai_GetFileNameFromDent(dentbuf, tmpname);
			}
			else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_DIRECTORY)// find a directory
			{
				if (!hai_stricmp(dentName, tmpname))//compare previous
					return 0;						
				LDirOrd = 0, pLDir = tmpname;
				hai_memcpy(dentbuf, pSecBuf, FAT_DIRENT_SIZE);
				hai_GetFileNameFromDent(dentbuf, tmpname);
			}
			else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_VOLUME_ID)// find a volume lab
				LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
			else
				LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;// illegal dir entry
		}
	}

	return FATERR_INVALID_PATH;
}

int hai_GetDent(int dev, S_DWORD StartClust, S_BYTE *filename, S_BYTE *dentbuf)
{
	S_BYTE LDirOrd = DELETED_DIR_FLAG;
	int err = FATERR_INVALID_PATH;
	S_DWORD SecStart, SecEnd;
	S_BYTE *pSecBuf;
	S_BYTE SecBuf[FAT_SEC_BUF_MAX];
	S_BYTE tmpname[HAI_FILENAME_MAX+4], *pLDir = tmpname;

	if (DevInf_FatType(dev)== FAT_TYPE_16 && StartClust == 0)
		return hai_FindDentOnFAT16Root(dev, filename, dentbuf);

	if (StartClust == 0) // FAT32 rootclust
		StartClust = DevInf_RootClus(dev);

	hai_memset(tmpname, 0x00, sizeof(tmpname));

	while (DevInf_FatType(dev)==FAT_TYPE_16?IS_FAT16_INUSE_CLUST(StartClust):IS_FAT32_INUSE_CLUST(StartClust))
	{
		SecStart = DevInf_FirstDatSec(dev) + (StartClust-2)*DevInf_SecPerClust(dev);//get first sec of clust;
		for (SecEnd = SecStart+DevInf_SecPerClust(dev); SecStart < SecEnd; SecStart++)
		{
			if (_hai_FatDevRead(dev, SecStart, SecBuf))
				return FATERR_DEV_OPERATE_ERR;
			for (pSecBuf = SecBuf; (pSecBuf-SecBuf)<DevInf_BytsPerSec(dev);pSecBuf += FAT_DIRENT_SIZE)
			{
				if (*pDIR_Name(pSecBuf)==EMPTY_DIR_FLAG)//finish
				{
					if (!hai_stricmp(filename, tmpname))//compare previous
						return 0;						
					return FATERR_INVALID_PATH;
				}
				else if (*pDIR_Name(pSecBuf)==DELETED_DIR_FLAG)//invalid dir entry
					LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
				else if ((*pLDIR_Attr(pSecBuf)&FILE_ATTR_LONG_NAME_MASK)==FILE_ATTR_LONG_NAME)//long name sub-component
				{
					if (LDirOrd+1 == (*pLDIR_Ord(pSecBuf)&~LDIR_LAST_LONG_ENTRY))
					{
						int num = hai_GetFileNameFromLDent(pSecBuf, pLDir);
						if (!num)
						{
							LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
							continue;
						}
						if (*pLDIR_Ord(pSecBuf)&LDIR_LAST_LONG_ENTRY)
						{
							if (hai_ShortFileNameChkSum(dentbuf)==*pLDIR_Chksum(pSecBuf) && !hai_stricmp(filename, tmpname))
								return 0;
							LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
						}
						else
						{
							if (num == LDIR_STR_CHAR_MAX)//because it stores 26 char in one long dent
								LDirOrd += 1, pLDir += num;
							else//be error
								LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
						}
					}
				}
				else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == 0x00)// find a file
				{
					if (!hai_stricmp(filename, tmpname))//compare previous
						return 0;						
					LDirOrd = 0, pLDir = tmpname;
					hai_memcpy(dentbuf, pSecBuf, FAT_DIRENT_SIZE);
					hai_GetFileNameFromDent(dentbuf, tmpname);
				}
				else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_DIRECTORY)// find a directory
				{
					if (!hai_stricmp(filename, tmpname))
						return 0;						
					LDirOrd = 0, pLDir = tmpname;
					hai_memcpy(dentbuf, pSecBuf, FAT_DIRENT_SIZE);
					hai_GetFileNameFromDent(dentbuf, tmpname);
				}
				else if ((*pDIR_Attr(pSecBuf)&(FILE_ATTR_DIRECTORY|FILE_ATTR_VOLUME_ID)) == FILE_ATTR_VOLUME_ID)// find a volume lab
					LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;
				else
					LDirOrd = DELETED_DIR_FLAG, pLDir = tmpname;// illegal dir entry
			}
		}
		StartClust = hai_GetNextCluster(dev, StartClust);
	}
	
	return err;
}
#endif

int hai_SearchDent(int Dev, S_DWORD StartClust, const S_BYTE *path, S_BYTE *dentbuf)
{
	int err = 0;
	S_BYTE dirname[HAI_FILENAME_MAX+4];

	if (DevInf_FatType(Dev) == FAT_TYPE_16 && StartClust == 0) // FAT32 rootclust
		StartClust = DevInf_RootClus(Dev);
	*pDIR_Attr(dentbuf) = FILE_ATTR_DIRECTORY;
	HAI_WRITEWORD(pDIR_FstClusHI(dentbuf), StartClust>>16);
	HAI_WRITEWORD(pDIR_FstClusLO(dentbuf), StartClust);

	hai_memset(dirname, 0x00, sizeof(dirname));
	path = hai_GetOneDirName(path, dirname);
	while (dirname[0])
	{
		StartClust = GetDentClust(dentbuf);
		if (!IS_FAT_CUR_DIR(dirname))
			err = hai_FindDent(Dev, StartClust, dirname, dentbuf);
		if (err || !IS_FILE_ATTR(dentbuf, FILE_ATTR_DIRECTORY))
		{
			if (err == FATERR_NO_ERROR)
				err = FATERR_INVALID_PATH;
			break;
		}
		hai_memset(dirname, 0x00, sizeof(dirname));
		path = hai_GetOneDirName(path, dirname);
	}
	
	return err;
}

int hai_FindShortNameOnFAT16Root(int dev, S_BYTE *Name83, S_BYTE *dentbuf)
{
	S_BYTE *pSecBuf;
	S_DWORD RootSec = DevInf_RsvdSec(dev)+DevInf_NumFats(dev)*DevInf_FatSize(dev);
	S_DWORD RootSiz = ((DevInf_RootEntCnt(dev)*FAT_DIRENT_SIZE)+(DevInf_BytsPerSec(dev)-1))/DevInf_BytsPerSec(dev);
	S_BYTE SecBuf[FAT_SEC_BUF_MAX];
	S_BYTE tmpname[HAI_FILENAME_MAX+4];

	if (!*Name83 || IS_FAT_CUR_DIR(Name83) || IS_FAT_BACK_DIR(Name83))
		return FATERR_INVALID_PATH;

	hai_memset(tmpname, 0x00, sizeof(tmpname));

	for (RootSiz += RootSec; RootSec < RootSiz; RootSec++)

⌨️ 快捷键说明

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