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

📄 hfatutil.c

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


const S_BYTE *FatFlag32 = "FAT32   ";
const S_BYTE *FatFlag16 = "FAT16   ";
const S_BYTE *FatFlag12 = "FAT12   ";


int hai_GetFatType(S_BYTE *BPB)
{
	S_WORD RsvdSec, FatSize, FatNum, RootSiz;
	S_DWORD TotSec, DatSec, DatClus;

#if 0
	if (!(hai_memcmp(pBS_FilSysType(BPB,FAT32_DATA_OFF), FatFlag32, 3/*sBS_FilSysType*/)== 0
		|| hai_memcmp(pBS_FilSysType(BPB,FAT16_DATA_OFF), FatFlag16, 3/*sBS_FilSysType*/)== 0
		|| hai_memcmp(pBS_FilSysType(BPB,FAT12_DATA_OFF), FatFlag12, 3/*sBS_FilSysType*/)== 0))
#else
	if (BPB[510] != 0x55 || BPB[511] != 0xAA)
#endif
		return FAT_TYPE_NO;
	
	RsvdSec = HAI_MAKEWORD(pBPB_RsvdSecCnt(BPB));
	FatSize = HAI_MAKEWORD(pBPB_FATSz16(BPB));
	if (FatSize == 0)
		FatSize = HAI_MAKEWORD(pBPB_FATSz32(BPB));
	FatNum  = (S_WORD)*pBPB_NumFATs(BPB);
	RootSiz = ((HAI_MAKEWORD(pBPB_RootEntCnt(BPB))*FAT_DIRENT_SIZE)+(HAI_MAKEWORD(pBPB_BytsPerSec(BPB))-1))/HAI_MAKEWORD(pBPB_BytsPerSec(BPB));
	TotSec  = (S_DWORD)HAI_MAKEWORD(pBPB_TotSec16(BPB));
	if (TotSec == 0)
		TotSec  = HAI_MAKEDWORD(pBPB_TotSec32(BPB));
	DatSec  = TotSec - (RsvdSec+FatNum*FatSize+RootSiz);
	DatClus = DatSec/(*pBPB_SecPerClus(BPB));
	
	if (DatClus < FAT12_CLST_MAX)
		return FAT_TYPE_12;
	else if (DatClus < FAT16_CLST_MAX)
		return FAT_TYPE_16;
	else
		return FAT_TYPE_32;
}


//following tab was copied from Microsoft window.
struct DSKSZTOSECPERCLUS
{
	S_DWORD DiskSize;
	S_BYTE  SecPerClus;
};

const struct DSKSZTOSECPERCLUS DskTabFat16[] =
{
	{      8400,  0},//SecPerClus为0表示这是一个错误
	{     32680,  2},//disks up to 16MB, 1k clustor
	{    262144,  4},//disks up to 128MB, 2k clustor
	{    524288,  8},//disks up to 256MB, 4k clustor
	{   1048576, 16},//disks up to 512MB, 8k clustor
	//The entries after this point are not used unless FAT16 is forced
	{   2097152, 32},//disks up to 1GB, 16k clustor
	{   4194304, 64},//disks up to 2GB, 32k clustor
	{0xFFFFFFFF,  0}//error
};

const struct DSKSZTOSECPERCLUS DskTabFat32[] =
{
	{     66600,  0},
	{    532480,  1},
	{  16777216,  8},
	{  33554432, 16},
	{  67108864, 32},
	{0xFFFFFFFF, 64}
};

S_BYTE hai_GetSectorPerCluster(S_DWORD TotSec, S_BYTE *pFatType)
{
	int i;
	
	if (*pFatType == FAT_TYPE_NO)
	{
		if (TotSec <= 1048526)
			*pFatType = FAT_TYPE_16;
		else
			*pFatType = FAT_TYPE_32;
	}

	if (*pFatType == FAT_TYPE_16)
	{
		if (TotSec <= 8400 || TotSec > 4194304)
			return 0;
		for (i = 0; i < sizeof(DskTabFat16)/sizeof(DskTabFat16[0]); i++)
			if (TotSec <= DskTabFat16[i].DiskSize)
				break;
		return DskTabFat16[i].SecPerClus;
	}
	else if (*pFatType == FAT_TYPE_32)
	{
		if (TotSec <= 66600 || TotSec > 67108864)
			return 0;
		for (i = 0; i < sizeof(DskTabFat32)/sizeof(DskTabFat32[0]); i++)
			if (TotSec <= DskTabFat32[i].DiskSize)
				break;
		return DskTabFat32[i].SecPerClus;
	}

	return 0;
}

S_DWORD hai_GetFat32FreeCnt(int dev)
{
	S_DWORD TotalClus = (DevInf_TotSec(dev)-(DevInf_RsvdSec(dev)+DevInf_NumFats(dev)*DevInf_FatSize(dev))-1)/DevInf_SecPerClust(dev);

	return TotalClus;
}

int hai_FillBPB(S_BYTE *BPB, SP_FILLBPB pFillBPB)
{
	S_DWORD DateTime = 0x01234567;//hai_GetDateTime32();
	S_DWORD FatDatOff = 0;

	if (pFillBPB->FatType == FAT_TYPE_32)
		FatDatOff = FAT32_DATA_OFF;
	
	*(pBS_jmpBoot(BPB)+0) = 0xEB, *(pBS_jmpBoot(BPB)+1) = 0x00, *(pBS_jmpBoot(BPB)+2) = 0x90;
	hai_memcpy(pBS_OEMName(BPB), "MSWIN4.1", sBS_OEMName);
	HAI_WRITEWORD(pBPB_BytsPerSec(BPB), pFillBPB->SecSize);
	*(pBPB_SecPerClus(BPB)) = pFillBPB->SecPerClus;
	HAI_WRITEWORD(pBPB_RsvdSecCnt(BPB), pFillBPB->RsvdSec);
	*(pBPB_NumFATs(BPB)) = FAT_NUMFATS;
	if (pFillBPB->FatType == FAT_TYPE_32)
		HAI_WRITEWORD(pBPB_RootEntCnt(BPB), 0x00);
	else
		HAI_WRITEWORD(pBPB_RootEntCnt(BPB), pFillBPB->RootEntCnt);
	if (pFillBPB->FatType == FAT_TYPE_16 && pFillBPB->TotSec < 0x10000)
	{
		HAI_WRITEWORD(pBPB_TotSec16(BPB), pFillBPB->TotSec);
		HAI_WRITEDWORD(pBPB_TotSec32(BPB), 0x00);
	}
	else
	{
		HAI_WRITEWORD(pBPB_TotSec16(BPB), 0x00);
		HAI_WRITEDWORD(pBPB_TotSec32(BPB), pFillBPB->TotSec);
	}
	*(pBPB_Media(BPB)) = pFillBPB->Media;
	if (pFillBPB->FatType == FAT_TYPE_32)
		HAI_WRITEWORD(pBPB_FATSz16(BPB), 0x00);
	else
		HAI_WRITEWORD(pBPB_FATSz16(BPB), pFillBPB->FatSize);
	HAI_WRITEWORD(pBPB_SecPerTrk(BPB), 0x00);
	HAI_WRITEWORD(pBPB_NumHeads(BPB), 0x00);
	HAI_WRITEDWORD(pBPB_HiddSec(BPB), 0x00);
	if (pFillBPB->FatType == FAT_TYPE_32)
	{
		HAI_WRITEDWORD(pBPB_FATSz32(BPB), pFillBPB->FatSize);
		//BPB_ExtFlags  Bit0-3(active FAT)  Bit4-6(reserved)  Bit7  Bit8-15(reserved) 
		//           0b0000           0b000        0b0           0b00000000
		HAI_WRITEWORD(pBPB_ExtFlags(BPB), 0x00);
		HAI_WRITEWORD(pBPB_FSVer(BPB), FAT_FILESYS_VER/*0x0103*/);//ver 1.03
		HAI_WRITEDWORD(pBPB_RootClus(BPB), FAT32_ROOT_CLUS);
		HAI_WRITEWORD(pBPB_FSInfo(BPB), FAT32_FSINFO_SEC);
		HAI_WRITEWORD(pBPB_BkBootSec(BPB), FAT32_BKBOOT_SEC);
		hai_memset(pBPB_Reserved(BPB), 0x00, sBPB_Reserved);
	}
	*(pBS_DrvNum(BPB, FatDatOff)) = 0;
	*(pBS_Reserved1(BPB, FatDatOff)) = 0;
	*(pBS_BootSig(BPB, FatDatOff)) = 0x29;//0x00: next three fields are not present
	HAI_WRITEDWORD(pBS_VolID(BPB, FatDatOff), DateTime);//serial number, e.g. date/time
	hai_memcpy(pBS_VOlLab(BPB, FatDatOff), "NO NAME    ", sBS_VOlLab);
	if (pFillBPB->FatType == FAT_TYPE_32)
		hai_memcpy(pBS_FilSysType(BPB, FatDatOff), FatFlag32, sBS_FilSysType);
	else
		hai_memcpy(pBS_FilSysType(BPB, FatDatOff), FatFlag16, sBS_FilSysType);

	BPB[510] = 0x55, BPB[511] = 0xAA;
	
	return 0;
}

S_BYTE hai_JudgeFatType(SP_FILLBPB pFillBPB)
{
	S_DWORD DatClus;
//The methed may be error.
	DatClus = (pFillBPB->TotSec - (pFillBPB->FatSize*2) - 
		(((pFillBPB->RootEntCnt*32)+(pFillBPB->SecSize-1))/pFillBPB->SecSize))/pFillBPB->SecPerClus;

	if (DatClus < FAT12_CLST_MAX)
		return FAT_TYPE_12;
	else if (DatClus < FAT16_CLST_MAX)
		return FAT_TYPE_16;
	else
		return FAT_TYPE_32;
}

S_DWORD hai_CountFatSize(SP_FILLBPB pFillBPB)
{
	S_DWORD RootDirSec, TmpVal1, TmpVal2;

	RootDirSec = ((pFillBPB->RootEntCnt*32)+(pFillBPB->SecSize-1))/pFillBPB->SecSize;
	TmpVal1 = pFillBPB->TotSec - (pFillBPB->RsvdSec + RootDirSec);
	TmpVal2 = ((S_DWORD)256 * pFillBPB->SecPerClus) + 2/*BPB_NumFATs*/;
	if (pFillBPB->FatType == FAT_TYPE_32)
		TmpVal2 = TmpVal2 / 2;

	pFillBPB->FatSize = (TmpVal1 + (TmpVal2-1)) / TmpVal2;

	if (pFillBPB->FatType != FAT_TYPE_32)
		pFillBPB->FatSize &= 0xFFFF;

	return pFillBPB->FatSize;
}

S_DWORD hai_GetNextCluster(int dev, S_DWORD CurClust)
{
	S_DWORD FatOff;
	S_DWORD FatSecNum, FatEntOff;
	S_BYTE SecBuf[FAT_SEC_BUF_MAX];
	
	if (DevInf_FatType(dev) == FAT_TYPE_16)
		FatOff = CurClust << 1;
	else if (DevInf_FatType(dev) == FAT_TYPE_32)
		FatOff = CurClust << 2;
	else
		return 0xFFFFFFFF;

	FatSecNum = DevInf_RsvdSec(dev) + (FatOff/DevInf_BytsPerSec(dev));
	FatEntOff = FatOff%DevInf_BytsPerSec(dev);

	if (_hai_FatDevRead(dev, FatSecNum, SecBuf))
		return 0xFFFFFFFF;
	if (DevInf_FatType(dev) == FAT_TYPE_16)
	{
		CurClust = (S_DWORD)HAI_MAKEWORD(SecBuf+FatEntOff);
		if (CurClust == 0xFFFF)
			CurClust = 0xFFFFFFFF;
	}
	else
	{
		CurClust = HAI_MAKEDWORD(SecBuf+FatEntOff) & 0x0FFFFFFF;//28 bit are valid.
		if (CurClust == 0xFFFFFFF)
			CurClust = 0xFFFFFFFF;
	}

	return CurClust;
}

int hai_FsInfoOperate(int dev, S_DWORD *NxtFree, S_DWORD *FreeCnt)
{
	S_BYTE SecBuf[FAT_SEC_BUF_MAX];

⌨️ 快捷键说明

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