📄 hfatdent.c
字号:
//---------------------------------------------------------------------------------
// 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 + -