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

📄 hfatdent.c

📁 HFAT32是我依据FAT标准,按照自己的理解写出来的一个FAT文件系统 特性: 1.HFAT32 是一个小型的嵌入式FAT文件系统,可以方便地在nand flash,RAM和SD Card
💻 C
📖 第 1 页 / 共 3 页
字号:
{
	int LongName;
	int err, DentCnt = 1;
	S_BYTE Name83[16], dentbuf2[FAT_DIRENT_SIZE];
	S_WORD dentNum;
	S_DWORD SecNum, IdleClus;
	
	if (IS_FILE_ATTR(dentbuf, FILE_ATTR_VOLUME_ID))
		return FATERR_UNKNOWN_ERR;
	if (hai_Make83Format(pName, Name83)==0)
		return FATERR_INVALID_FILENAME;

	while (!hai_FindShortName(dev, StartClust, Name83, dentbuf2))
		hai_MakeNumericTailName(Name83);
	if (LongName = hai_strcmp(pName, Name83))
	{
		DentCnt += (hai_CountChar(pName)+(LDIR_STR_CHAR_MAX-1))/LDIR_STR_CHAR_MAX;
		hai_memset(dentbuf2, 0x00, sizeof(dentbuf2));
	}
	else
	{
		pName = S_NULL;//only use Name83
	}
		
	SecNum = hai_AllocDent(dev, StartClust, DentCnt, &dentNum);
	if (!SecNum)
		return FATERR_NO_DISK_SPACE;
	IdleClus = hai_AllocIdleClust(dev);
	if (!IdleClus)
		return FATERR_NO_DISK_SPACE;
	err = hai_InitDirectory(dev, IdleClus, StartClust);
	if (!err)
	{
		hai_FillDent(dentbuf, Name83, *pDIR_Attr(dentbuf), 0x00, IdleClus);
		err = hai_WriteDent(dev, SecNum, dentNum, pName, dentbuf);
	}
	return err;
}

S_DWORD hai_CreateFileDent(int dev, S_DWORD clust, const S_BYTE *file, S_WORD *DentNum, S_BYTE *DentBuf)
{
	int LongName;
	int DentCnt = 1;
	S_BYTE Name83[16];
	S_DWORD SecNum;
	
	if (hai_Make83Format(file, Name83)==0)
		return 0;

	while (!hai_FindShortName(dev, clust, Name83, DentBuf))
		hai_MakeNumericTailName(Name83);
	if (LongName = hai_strcmp(file, Name83))
		DentCnt += (hai_CountChar(file)+(LDIR_STR_CHAR_MAX-1))/LDIR_STR_CHAR_MAX;
	else
		file = S_NULL;//only use Name83
		
	SecNum = hai_AllocDent(dev, clust, DentCnt, DentNum);
	if (SecNum)
	{
		hai_FillDent(DentBuf, Name83, 0x00, 0x00, 0x00);
		if (hai_WriteDent(dev, SecNum, *DentNum, file, DentBuf))
			SecNum = 0;
	}
	return SecNum;
}

int hai_LocationDentOnFAT16Root(int dev, const S_BYTE *DentName, S_DWORD *DSecNum, S_WORD *DentNum, S_DWORD *LDSecNum, S_WORD *LDentNum, S_BYTE *DentBuf)
{
	S_BYTE ChkSum, LDirOrd = DELETED_DIR_FLAG;
	S_BYTE *pSecBuf, SecBuf[FAT_SEC_BUF_MAX];
	S_BYTE tmpname[HAI_FILENAME_MAX+4];
	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);

	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
				return FATERR_INVALID_FILENAME;
			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);
					*LDSecNum = RootSec, *LDentNum = (pSecBuf-SecBuf)/FAT_DIRENT_SIZE;
					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)
						tmpname[0] = '\0';
				}
				else
				{
					hai_GetFileNameFromDent(pSecBuf, tmpname);
					*LDSecNum = RootSec, *LDentNum = (pSecBuf-SecBuf)/FAT_DIRENT_SIZE;
				}
				if (!hai_stricmp(DentName, tmpname))
				{
					hai_memcpy(DentBuf, pSecBuf, FAT_DIRENT_SIZE);
					*DentNum = (pSecBuf-SecBuf)/FAT_DIRENT_SIZE;
					*DSecNum = RootSec;
					return FATERR_NO_ERROR;
				}
				LDirOrd = DELETED_DIR_FLAG;
			}
//			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
		}
	}

	return FATERR_INVALID_FILENAME;
}

int hai_LocationDent(int dev, S_DWORD clust, const S_BYTE *DentName, S_DWORD *DSecNum, S_WORD *DentNum, S_DWORD *LDSecNum, S_WORD *LDentNum, S_BYTE *DentBuf)
{
	S_BYTE ChkSum, LDirOrd = DELETED_DIR_FLAG;
	S_BYTE *pSecBuf, SecBuf[FAT_SEC_BUF_MAX];
	S_DWORD SecStart, SecEnd;
	S_BYTE tmpname[HAI_FILENAME_MAX+4];

	if (DevInf_FatType(dev) == FAT_TYPE_16 && clust == 0)
		return hai_LocationDentOnFAT16Root(dev, DentName, DSecNum, DentNum, LDSecNum, LDentNum, DentBuf);
	
	if (clust == 0) // FAT32 rootclust
		clust = DevInf_RootClus(dev);

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

	while (DevInf_FatType(dev)==FAT_TYPE_16?IS_FAT16_INUSE_CLUST(clust):IS_FAT32_INUSE_CLUST(clust))
	{
		SecStart = DevInf_FirstDatSec(dev) + (clust-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
					return FATERR_INVALID_FILENAME;
				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);
						*LDSecNum = SecStart, *LDentNum = (pSecBuf-SecBuf)/FAT_DIRENT_SIZE;
						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)
							tmpname[0] = '\0';
					}
					else
					{
						hai_GetFileNameFromDent(pSecBuf, tmpname);
						*LDSecNum = SecStart, *LDentNum = (pSecBuf-SecBuf)/FAT_DIRENT_SIZE;
					}
					if (!hai_stricmp(DentName, tmpname))
					{
						hai_memcpy(DentBuf, pSecBuf, FAT_DIRENT_SIZE);
						*DentNum = (pSecBuf-SecBuf)/FAT_DIRENT_SIZE;
						*DSecNum = SecStart;
						return FATERR_NO_ERROR;
					}
					LDirOrd = DELETED_DIR_FLAG;
				}
//				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
			}
		}
		clust = hai_GetNextCluster(dev, clust);
	}

	return FATERR_INVALID_FILENAME;
}

int hai_FindDent(int dev, S_DWORD clust, const S_BYTE *DentName, S_BYTE *DentBuf)
{
	S_WORD DentNum, LDentNum;
	S_DWORD DSecNum, LDSecNum;

	return hai_LocationDent(dev, clust, DentName, &DSecNum, &DentNum, &LDSecNum, &LDentNum, DentBuf);
}

int hai_RemoveDentOnFat16Root(int dev, S_DWORD DSecNum, S_WORD DentNum, S_DWORD LDSecNum, S_WORD LDentNum, S_BYTE *DentBuf)
{
	S_BYTE *pSecBuf, *bSecBuf, SecBuf[FAT_SEC_BUF_MAX];

	if (_hai_FatDevRead(dev, LDSecNum, SecBuf))
		return FATERR_DEV_OPERATE_ERR;

	bSecBuf = SecBuf+DentNum*FAT_DIRENT_SIZE;
	pSecBuf = SecBuf+LDentNum*FAT_DIRENT_SIZE;
	while (1)
	{
		if (pSecBuf == SecBuf+DevInf_BytsPerSec(dev))
		{
			if (_hai_FatDevWrite(dev, LDSecNum, SecBuf))
				return FATERR_DEV_OPERATE_ERR;
			if (_hai_FatDevRead(dev, ++LDSecNum, SecBuf))
				return FATERR_DEV_OPERATE_ERR;
			pSecBuf = SecBuf;
		}
		*pDIR_Name(pSecBuf) = DELETED_DIR_FLAG;
		if (LDSecNum==DSecNum && pSecBuf==bSecBuf)
		{
			hai_memcpy(DentBuf, pSecBuf, FAT_DIRENT_SIZE);
			break;
		}
		pSecBuf  += FAT_DIRENT_SIZE;
	}
	if (_hai_FatDevWrite(dev, LDSecNum, SecBuf))
		return FATERR_DEV_OPERATE_ERR;

	return FATERR_NO_ERROR;
}

int hai_RemoveDent(int dev, S_DWORD DSecNum, S_WORD DentNum, S_DWORD LDSecNum, S_WORD LDentNum, S_BYTE *DentBuf)
{
	S_BYTE *pSecBuf, *bSecBuf, SecBuf[FAT_SEC_BUF_MAX];
	S_DWORD FirstSec, SecOff, TmpClust;

	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 (LDSecNum < FirstSec)
			return hai_RemoveDentOnFat16Root(dev, DSecNum, DentNum, LDSecNum, LDentNum, DentBuf);
	}
	
	TmpClust = (LDSecNum-DevInf_FirstDatSec(dev))/DevInf_SecPerClust(dev) + 2;
	FirstSec = DevInf_FirstDatSec(dev)+(TmpClust-2)*DevInf_SecPerClust(dev);
	SecOff   = (LDSecNum-DevInf_FirstDatSec(dev))%DevInf_SecPerClust(dev);
	
	if (_hai_FatDevRead(dev, FirstSec+SecOff, SecBuf))
		return FATERR_DEV_OPERATE_ERR;
	pSecBuf = SecBuf+LDentNum*FAT_DIRENT_SIZE;
	bSecBuf = SecBuf+DentNum*FAT_DIRENT_SIZE;

	while (1)
	{
		if (pSecBuf == SecBuf+DevInf_BytsPerSec(dev))
		{
			if (_hai_FatDevWrite(dev, FirstSec+SecOff, SecBuf))
				return FATERR_DEV_OPERATE_ERR;
			if (SecOff+1 == DevInf_SecPerClust(dev))//clust end
			{
				TmpClust = hai_GetNextCluster(dev, TmpClust);
				FirstSec = DevInf_FirstDatSec(dev)+(TmpClust-2)*DevInf_SecPerClust(dev);
				SecOff   = 0;
			}
			else
				SecOff++;
			if (_hai_FatDevRead(dev, FirstSec+SecOff, SecBuf))
				return FATERR_DEV_OPERATE_ERR;
			pSecBuf = SecBuf;
		}
		*pDIR_Name(pSecBuf) = DELETED_DIR_FLAG;
		if (FirstSec+SecOff==DSecNum && pSecBuf==bSecBuf)
		{
			hai_memcpy(DentBuf, pSecBuf, FAT_DIRENT_SIZE);
			break;
		}
		pSecBuf  += FAT_DIRENT_SIZE;
	}
	if (_hai_FatDevWrite(dev, FirstSec+SecOff, SecBuf))
		return FATERR_DEV_OPERATE_ERR;
	
	return FATERR_NO_ERROR;
}


⌨️ 快捷键说明

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