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

📄 hfatfile.c

📁 HaiBIOS 是为我的S3C2410开发板写的一个启动程序。 C盘是RAMDISK
💻 C
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------------
// Copyright jinhailiao 2008-2010
// E-mail:   jinhailiao@163.com
// Project:			HFAT16/32
// File:			hfatfile.c
// Description:		
//-------------------------------------------------------------
// Reversion Histroy:
//-------------------------------------------------------------
// Version		date		operations				by who
// 1.0.0		2008-06-26  create                  Kingsea
//---------------------------------------------------------------------------------
#include "hfstype.h"
#include "hfileapi.h"
#include "hfilesys.h"
#include "hfatfile.h"
#include "hfatsys.h"
#include "haiclib.h"
#include "hfatstr.h"
#include "hfatdent.h"

const struct FILECONST fileconst[] =
{
	{"a"  , _H_O_WRONLY|_H_O_CREAT|_H_O_APPEND|_H_O_TEXT},
	{"r"  , _H_O_RDONLY|_H_O_TEXT},
	{"w"  , _H_O_WRONLY|_H_O_CREAT|_H_O_TRUNC|_H_O_TEXT},
	{"ab" , _H_O_WRONLY|_H_O_CREAT|_H_O_APPEND|_H_O_BINARY},
	{"rb" , _H_O_RDONLY|_H_O_BINARY},
	{"wb" , _H_O_WRONLY|_H_O_CREAT|_H_O_TRUNC|_H_O_BINARY},
	{"a+" , _H_O_RDWR|_H_O_CREAT|_H_O_APPEND|_H_O_TEXT},
	{"r+" , _H_O_RDWR|_H_O_TEXT},
	{"w+" , _H_O_RDWR|_H_O_CREAT|_H_O_TRUNC|_H_O_TEXT},
	{"a+b", _H_O_RDWR|_H_O_CREAT|_H_O_APPEND|_H_O_BINARY},
	{"r+b", _H_O_RDWR|_H_O_BINARY},
	{"w+b", _H_O_RDWR|_H_O_CREAT|_H_O_TRUNC|_H_O_BINARY},
	{"ab+", _H_O_RDWR|_H_O_CREAT|_H_O_APPEND|_H_O_BINARY},
	{"rb+", _H_O_RDWR|_H_O_BINARY},
	{"wb+", _H_O_RDWR|_H_O_CREAT|_H_O_TRUNC|_H_O_BINARY}
};

void _hai_GetFileInfo(SP_FATFILEINF pfileinf, S_BYTE *DentBuf)
{
	S_WORD ClustHi = HAI_MAKEWORD(pDIR_FstClusHI(DentBuf));
	S_WORD ClustLo = HAI_MAKEWORD(pDIR_FstClusLO(DentBuf));

	hai_memcpy(pfileinf->DirName, DentBuf, sDIR_Name);
	pfileinf->CrtTimeTenth = *pDIR_CrtTimeTenth(DentBuf);
	pfileinf->CrtTime = HAI_MAKEWORD(pDIR_CrtTime(DentBuf));
	pfileinf->CrtDate = HAI_MAKEWORD(pDIR_CrtDate(DentBuf));
	pfileinf->LastAccDate = HAI_MAKEWORD(pDIR_LastAccDate(DentBuf));
	pfileinf->WrtTime = HAI_MAKEWORD(pDIR_WrtTime(DentBuf));
	pfileinf->WrtDate = HAI_MAKEWORD(pDIR_WrtDate(DentBuf));
	pfileinf->FirstClust = HAI_COMBDWORD(ClustHi, ClustLo);
	pfileinf->FileSize = HAI_MAKEDWORD(pDIR_FileSize(DentBuf));
}

int _hai_CheckFileOpenOnFat(int dev, void *fileop, S_DWORD DentSec, S_WORD DentNum, S_BYTE *DentBuf)
{
	SH_FATFILEOP hFileOp = (SH_FATFILEOP)fileop;
	SP_FATFILEINF pfileinf = hFileOp->pfileinf;
	S_WORD ClustHi = HAI_MAKEWORD(pDIR_FstClusHI(DentBuf));
	S_WORD ClustLo = HAI_MAKEWORD(pDIR_FstClusLO(DentBuf));

	if (pfileinf->dev == dev && pfileinf->DentSec == DentSec && pfileinf->DentNum == DentNum
		&& pfileinf->attrib == *pDIR_Attr(DentBuf) && pfileinf->FirstClust == HAI_COMBDWORD(ClustHi, ClustLo))
		return 1;
	return 0;
}

int _hai_FlushFileBuf(int dev, SP_FILEBUF pFileBuf)
{
	int err;
	S_DWORD SecNum;

	if (pFileBuf->flush == 0)
		return 0;
	SecNum = DevInf_FirstDatSec(dev) + (pFileBuf->Clust-2)*DevInf_SecPerClust(dev) + pFileBuf->SecNum;
	if ((err = _hai_FatDevWrite(dev, SecNum, pFileBuf->SecBuf)) == 0)
		pFileBuf->flush = 0;

	return err;
}

int _hai_Flush2ReadFileBuf(int dev, S_DWORD Clust, S_BYTE SecNum, SP_FILEBUF pFileBuf)
{
	int err;
	S_DWORD Secuter;

	if (Clust==pFileBuf->Clust && SecNum==pFileBuf->SecNum)
		return 0;
	if (err = _hai_FlushFileBuf(dev, pFileBuf))
		return err;

	Secuter = DevInf_FirstDatSec(dev) + (Clust-2)*DevInf_SecPerClust(dev) + SecNum;
	if (err = _hai_FatDevRead(dev, Secuter, pFileBuf->SecBuf)) 
	{
		hai_memset(pFileBuf, 0x00, sizeof(*pFileBuf));
	}
	else
	{
		pFileBuf->flush = 0;
		pFileBuf->Clust = Clust;
		pFileBuf->SecNum = SecNum;
	}

	return err;
}


SP_FATFILEINF _hai_OpenFileOnFat(int dev, const S_BYTE *file, S_WORD mode)
{
	int err;
	S_BYTE ShareOpen = 0;
	S_WORD DentNum, LDentNum;
	S_DWORD DSecNum = 0, LDSecNum = 0;
	S_DWORD clust;
	S_BYTE DentBuf[FAT_DIRENT_SIZE];
	SP_FATFILEINF pfileinf;
	SH_FATFILEOP hfileop;

	if ((pfileinf = hai_FatMemAlloc(sizeof(*pfileinf))) == S_NULL)
		return S_NULL;
	hai_memset(pfileinf, 0x00, sizeof(*pfileinf));
	clust = _hai_CwdOperate(CWDOPERATE_GETCLUS, S_NULL);
	err = hai_LocationDent(dev, clust, file, &DSecNum, &DentNum, &LDSecNum, &LDentNum, DentBuf);
	if (err == FATERR_INVALID_FILENAME)
	{
		if (mode&_H_O_CREAT)
		{
			DSecNum = hai_CreateFileDent(dev, clust, file, &DentNum, DentBuf);
			err = hai_LocationDent(dev, clust, file, &DSecNum, &DentNum, &LDSecNum, &LDentNum, DentBuf);
		}
		if (err)
		{
			hai_FatMemFree(pfileinf);
			pfileinf = S_NULL;
		}
	}
	else if (err == FATERR_NO_ERROR)
	{
		if (IS_FILE_ATTR(DentBuf, FILE_ATTR_DIRECTORY))
		{
			hai_FatMemFree(pfileinf);
			pfileinf = S_NULL;
		}
		else if (hfileop = (SH_FATFILEOP)_hai_CheckFileIsOpened(dev, DSecNum, DentNum, DentBuf))
		{
			hai_FatMemFree(pfileinf);
			pfileinf = S_NULL;
			if (!(mode&_H_O_WRONLY))
			{
				pfileinf = hfileop->pfileinf;
				pfileinf->OpenCnt += 1;
				ShareOpen = 1;
			}
		}
		else if ((mode&_H_O_WRONLY)&&(IS_FILE_ATTR(DentBuf, FILE_ATTR_READ_ONLY)))
		{
			hai_FatMemFree(pfileinf);
			pfileinf = S_NULL;
		}
		else if (mode&_H_O_TRUNC)
		{
			if (_hai_TruncateFile(dev, DSecNum, DentNum))
			{
				hai_FatMemFree(pfileinf);
				pfileinf = S_NULL;
			}
			else
			{
				HAI_WRITEWORD(pDIR_FstClusHI(DentBuf), 0x00);
				HAI_WRITEWORD(pDIR_FstClusLO(DentBuf), 0x00);
				HAI_WRITEDWORD(pDIR_FileSize(DentBuf), 0x00);
			}
		}
	}
	else
	{
		hai_FatMemFree(pfileinf);
		pfileinf = S_NULL;
	}

	if(pfileinf && !ShareOpen)
	{
		pfileinf->dev = dev;
		pfileinf->DentNum = DentNum;
		pfileinf->DentSec = DSecNum;
		pfileinf->OpenCnt = 1;
		_hai_GetFileInfo(pfileinf, DentBuf);
		pfileinf->pSecbuf = hai_FatMemAlloc(sizeof(S_FILEBUF));
		if (pfileinf->pSecbuf)
			hai_memset(pfileinf->pSecbuf, 0x00, sizeof(S_FILEBUF));
	}

	return pfileinf;
}

SH_FATFILEOP _hai_fopenOnFat(S_BYTE disk, const S_BYTE *file, const char *mode)
{
	int i;
	SH_FATFILEOP hfile;

	if ((hfile = hai_FatMemAlloc(sizeof(*hfile))) == S_NULL)
		return S_NULL;
	hai_memset(hfile, 0x00, sizeof(*hfile));
	hfile->dev = hai_GetDeviceNum(disk);
	for (i = 0; i < sizeof(fileconst)/sizeof(fileconst[0]); i++)
	{
		if (!hai_strcmp(fileconst[i].mode, mode))
		{
			hfile->mode = fileconst[i].val;
			break;
		}
	}
	if (hfile->mode == 0)
	{
		hai_FatMemFree(hfile);
		return S_NULL;
	}

	hai_DiskOperateLock(hfile->dev);
	hfile->pfileinf = _hai_OpenFileOnFat(hfile->dev, file, hfile->mode);
	hai_DiskOperateUnlock(hfile->dev);
	if (hfile->pfileinf == S_NULL)
	{
		hai_FatMemFree(hfile);
		hfile = S_NULL;
	}

	return hfile;
}

int _hai_fcloseOnFat(S_BYTE disk, SH_FATFILEOP hFileOp)
{
	int err = FATERR_INVALID_DISK;
	S_BYTE *pSecBuf, SecBuf[FAT_SEC_BUF_MAX];
	SP_FATFILEINF pFileInf;

	if (hFileOp->dev != hai_GetDeviceNum(disk) || hFileOp->pfileinf == S_NULL)
		goto FCLOSE_ERR;
	if (!hai_FatDevExist(hFileOp->dev))
		goto FCLOSE_ERR;

	err = FATERR_NO_ERROR;
	pFileInf = hFileOp->pfileinf;
	if (--pFileInf->OpenCnt == 0)
	{
		hai_DiskOperateLock(hFileOp->dev);
		if (err = _hai_FatDevRead(hFileOp->dev, pFileInf->DentSec, SecBuf))
			goto FCLOSE_ERR;
		pSecBuf = SecBuf + pFileInf->DentNum*FAT_DIRENT_SIZE;
		if (hai_memcmp(pSecBuf, pFileInf->DirName, sDIR_Name))
		{
			err = FATERR_FILE_NOFIND;
			goto FCLOSE_ERR;
		}
		hai_UpdateDent(pSecBuf, (S_BYTE)((hFileOp->mode&_H_O_WRONLY)==_H_O_WRONLY));
		HAI_WRITEWORD(pDIR_FstClusHI(pSecBuf), pFileInf->FirstClust>>16);
		HAI_WRITEWORD(pDIR_FstClusLO(pSecBuf), pFileInf->FirstClust);
		HAI_WRITEDWORD(pDIR_FileSize(pSecBuf), pFileInf->FileSize);
		if (err = _hai_FatDevWrite(hFileOp->dev, pFileInf->DentSec, SecBuf))
			goto FCLOSE_ERR;
		if (pFileInf->pSecbuf)
		{
			if (err = _hai_FlushFileBuf(pFileInf->dev, pFileInf->pSecbuf))
				goto FCLOSE_ERR;
			hai_FatMemFree(pFileInf->pSecbuf);
		}
		hai_DiskOperateUnlock(hFileOp->dev);
		hai_FatMemFree(pFileInf);
	}
	hai_FatMemFree(hFileOp);

FCLOSE_ERR:
	hFileOp->err = err;
	return err;
}

S_DWORD _hai_FindFileLastClust(SP_FATFILEINF pFileInf)
{
	int dev = pFileInf->dev;
	S_BYTE SecBuf[FAT_SEC_BUF_MAX];
	S_DWORD Sec, BakSec = 0x00;
	S_DWORD Offset, CurClust, NxtClust;

	if (pFileInf->FirstClust == 0)//still not alloc clust
		return 0;
	CurClust = pFileInf->FirstClust;
	while (DevInf_FatType(dev)==FAT_TYPE_16?IS_FAT16_INUSE_CLUST(CurClust):IS_FAT32_INUSE_CLUST(CurClust))
	{
		if (DevInf_FatType(dev) == FAT_TYPE_32)
		{
			Sec = (CurClust<<2)/DevInf_BytsPerSec(dev) + DevInf_RsvdSec(dev);
			if (Sec != BakSec)
			{
				BakSec = Sec;
				if (_hai_FatDevRead(dev, Sec, SecBuf))
					return 0xFFFFFFFF;
			}
			Offset = (CurClust<<2)%DevInf_BytsPerSec(dev);
			NxtClust = HAI_MAKEDWORD(SecBuf+Offset)&FAT32_CLUST_VALIDBIT_MASK;
			if (IS_FAT32_INUSE_CLUST(NxtClust))
				CurClust = NxtClust;
			else
				break;
		}
		else
		{
			Sec = (CurClust<<1)/DevInf_BytsPerSec(dev) + DevInf_RsvdSec(dev);
			if (Sec != BakSec)
			{
				BakSec = Sec;
				if (_hai_FatDevRead(dev, Sec, SecBuf))
					return 0xFFFFFFFF;
			}
			Offset = (CurClust<<1)%DevInf_BytsPerSec(dev);
			NxtClust = HAI_MAKEWORD(SecBuf+Offset);
			if (IS_FAT16_INUSE_CLUST(NxtClust))
				CurClust = NxtClust;
			else
				break;
		}
	}

	return CurClust;
}

int _hai_AllocDiskSpace4File(SP_FATFILEINF pFileInf, S_DWORD total)
{
	int dev = pFileInf->dev;
	int ClustCnt, NeedClust;
	S_DWORD CurClust, num = DevInf_BytsPerSec(dev)*DevInf_SecPerClust(dev);

	ClustCnt = (pFileInf->FileSize + (num-1))/num;
	NeedClust = (total + (num-1))/num;
	if (NeedClust <= ClustCnt)
		return 0;
	if (pFileInf->LastClust == 0)
		pFileInf->LastClust = _hai_FindFileLastClust(pFileInf);
	if (pFileInf->LastClust == 0xFFFFFFFF)
	{
		pFileInf->LastClust = 0x00;
		return FATERR_DEV_OPERATE_ERR;
	}

	CurClust = pFileInf->LastClust;
	while (ClustCnt++ < NeedClust)
	{
		num = hai_AllocIdleClust(dev);
		if (num == 0)
			return FATERR_NO_DISK_SPACE;
		if (pFileInf->FirstClust == 0x00)
		{
			pFileInf->FirstClust = num;
			CurClust = num;
		}
		else
		{
			if (hai_LinkClust(dev, CurClust, num))
				return FATERR_DEV_OPERATE_ERR;
			CurClust = num;
		}
	}
	pFileInf->LastClust = num;
	
	return 0;
}

S_DWORD hai_FindSpecifyClust(int dev, S_DWORD StartClust, S_DWORD NoClust)
{
	S_BYTE SecBuf[FAT_SEC_BUF_MAX];
	S_DWORD Sec, BakSec = 0x00;
	S_DWORD Offset, NxtClust, ClustCnt = 0;

	if (NoClust < 1)
		return StartClust;
	while ((ClustCnt++<NoClust)&&(DevInf_FatType(dev)==FAT_TYPE_16?IS_FAT16_INUSE_CLUST(StartClust):IS_FAT32_INUSE_CLUST(StartClust)))
	{
		if (DevInf_FatType(dev) == FAT_TYPE_32)
		{
			Sec = (StartClust<<2)/DevInf_BytsPerSec(dev) + DevInf_RsvdSec(dev);
			if (Sec != BakSec)
			{
				BakSec = Sec;
				if (_hai_FatDevRead(dev, Sec, SecBuf))
					return 0xFFFFFFFF;
			}
			Offset = (StartClust<<2)%DevInf_BytsPerSec(dev);
			NxtClust = HAI_MAKEDWORD(SecBuf+Offset)&FAT32_CLUST_VALIDBIT_MASK;
			if (IS_FAT32_INUSE_CLUST(NxtClust))
				StartClust = NxtClust;
			else

⌨️ 快捷键说明

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