📄 fat.c
字号:
if (headcluster<=FAT_FREE_CLUSTER)
{
*nRelCluster = -1; // FAT_FREE_CLUSTER == 0
return;
}
if (LAST_CLUSTER(headcluster))
{
*nRelCluster = -2; // headcluster == oFat.m_nEOC (End Of Cluster)
return;
}
oFat.m_nLastFreeCluster = headcluster;
while (!LAST_CLUSTER(headcluster)) {
FAT_ClusterFatAddr(headcluster, §or, &offset, sCh);
FAT_GetFat(sector, offset, &headcluster, &sTmp, sCh);
Assert(sTmp>0);
FAT_SetFat(offset, FAT_FREE_CLUSTER, oFat.m_pFatBuffStart, sCh);
if (!headcluster) {
Assert(0);
printf("release_cluster_chain(): headcluster: %d\n", headcluster);
break;
}
if (++count==nLength) break;
}
FAT_WriteFatContent(&nFatContent, sCh);
*nRelCluster = headcluster;
}
/*******************************************************/
/* allocate a cluster chain with specified size */
/*******************************************************/
// FAT table maker
void FAT_AllocateClusterChain(int ucMode, int *numberofcluster, int nPosi, int rstart, int rend, int* uAlloCluster, SDHC* sCh)
{
int start_sector, offset, nHeadCluster=0, pcluster=0;
int cluster=nPosi, clucount=oFat.m_nBpbCountOfClusters+2, size=*numberofcluster;
int nFatContent1;
int nFatContent2;
if (size<=0)
{
*uAlloCluster = 0;
return;
}
while (cluster<clucount) {
int res;
int sTmp;
if (rstart) {
if (cluster>=rstart&&cluster<rend) {
Assert(rend>rstart);
cluster=rend;
if (cluster>=clucount)
break;
}
}
FAT_ClusterFatAddr(cluster, &start_sector, &offset, sCh); // offset: in bytes
printf("allo_cchain(): start_sector: %d, offset: %d\n", start_sector, offset);
FAT_GetFat(start_sector, offset, &sTmp, &res, sCh);
Assert(res>0);
if ((sTmp&oFat.m_nMaskCluster) == FAT_FREE_CLUSTER)
{
int psector, poffset, entry;
if (!nHeadCluster)
nHeadCluster = cluster;
if (pcluster)
{ /* do link here */
FAT_ClusterFatAddr(pcluster, &psector, &poffset, sCh);
FAT_GetFat(psector, poffset, &entry, &res, sCh);
Assert(res>0);
Assert(!(entry&oFat.m_nMaskCluster));
FAT_SetFat(poffset, cluster, oFat.m_pFatBuffStart, sCh);
///WriteFatContent(); // LYS 040429 add //LYS 040507 delete to speed up
}
pcluster = cluster;
if (--size==0)
{ // end processing */
FAT_ClusterFatAddr(pcluster, &psector, &poffset, sCh);
FAT_GetFat(psector, poffset, &entry, &res, sCh);
Assert(res>0);
Assert(!(entry&oFat.m_nMaskCluster));
FAT_SetFat(poffset, oFat.m_nEOC, oFat.m_pFatBuffStart, sCh);
FAT_WriteFatContent(&nFatContent1, sCh);
*uAlloCluster = nHeadCluster;
return;
}
}
cluster++;
}
FAT_WriteFatContent(&nFatContent2, sCh);
// in case of absent memory
if (ucMode) { // do not release cluster chain */
*numberofcluster -= size;
}
else if (nHeadCluster) { // release cluster chain */
int nRelCluster;
FAT_ReleaseClusterChain(nHeadCluster, 1, &nRelCluster, sCh);
*numberofcluster = nHeadCluster = 0;
}
*uAlloCluster = nHeadCluster;
}
/***************************************************************************/
/* for new cluster, we setup 32 entries to termination for long name space */
/***************************************************************************/
//only used in DIR_search_file_entry()
void FAT_AppendProcess(u8 *ucBuffer, int sector, int termination, SDHC* sCh)
{
int i, k;
if (termination==3)
Assert(oFat.m_ucBpbSecPerClus>=2);
for (k=0; k<termination-1; k++) {
u8 *p = ucBuffer;
for (i=0; i<16; i++) {
FAT_CopyEntry(p, TERM_ENTRY_TAG, sCh); //TERM_ENTRY_TAG == 0x0000
p += DIR_ENTRY_SIZE;
}
FAT_WriteSector(ucBuffer, sector+k, 1, sCh);
}
}
/************************************************************************/
/* for term entry, we check if next entry is avaible and do exit */
/************************************************************************/
//only used in DIR_search_file_entry()
void FAT_ProcessTerm(u8 *nPosi, u8 *ucBuffer, int sector, int num, int* nNextEnt, SDHC* sCh)
{
u8 *p = nPosi+DIR_ENTRY_SIZE;
u8 *buff_end=ucBuffer+oFat.m_usBpbBytsPerSec;
if (num > 1) {
FAT_CopyEntry(nPosi, FREE_ENTRY_TAG, sCh);
*nNextEnt = 1;
}
else if (p < buff_end) {
if (p[0] != TERM_ENTRY_TAG0) {
FAT_CopyEntry(p, TERM_ENTRY_TAG, sCh);
FAT_WriteSector(ucBuffer, sector, 1, sCh);
}
*nNextEnt = 0;
}
else {
*nNextEnt = 2;
}
}
/*************************************************************/
/* long file name processing: collect, compare and overwrite */
/*************************************************************/
//only used in DIR_search_file_entry()
void FAT_ProcessLfname(short *lfname, u8 *nPosi, u8 *ucBuffer, int sector, int *pcsum, int* nProLFname, SDHC* sCh)
{
u8 *buff_end = ucBuffer+oFat.m_usBpbBytsPerSec;
int match=-1;
int nLfname;
int ucNerror;
FAT_CollectLFileName(oFat.m_sClfName, nPosi, &nLfname, sCh);
ucNerror = nLfname;
if (ucNerror>0)
{
u8 *p = nPosi+DIR_ENTRY_SIZE; // p: directory entry structure
int nOrphan;
FAT_CheckOrphan(p, &nOrphan, sCh);
if (p<buff_end && nOrphan )
{
ucNerror = -1;
}
else
{
*pcsum = nPosi[13];
FAT_Compare2UnicodeLFileName(oFat.m_sClfName, lfname, &match, sCh);
}
}
if (ucNerror<=0)
{
if (ucNerror==-1)
{ // auto erase invalid entry */
FAT_CopyEntry(nPosi, FREE_ENTRY_TAG, sCh);
FAT_WriteSector(ucBuffer, sector, 1, sCh);
}
*pcsum = 0;
}
*nProLFname = match; // -1 no compare; 0 doesn't match; 1 match */
}
/************************************************************************/
/* match entry processing: check sum, short name compare and info save */
/************************************************************************/
void FAT_MatchProcess(int match, int checksum, u8 *p, ISOFILE *pfile, int* nMatEnt, SDHC* sCh)
{
int i, j, ok=0;
int nComArray;
u32 nEntCluster;
if (match)
{
u8 temp;
FAT_ComputeChkSum(p, &temp, sCh);
if (checksum== temp)
ok = 1;
else
{
ok = 1; Assert(0);
//EPRINTF(("csum:%x:%x\n", checksum, ComputeChkSum(p)));
}
}
else
{
j = -1;
for (i = 0; i<=SF_NAME_LENGTH; i++)
{
if (p[i] == '~')
j = i;
if ((i>=j) && (j >= 0)) {
p[i] = oFat.m_ucFsfname[i];
}
}
for (i=SF_NAME_LENGTH; i>0; i--) {
if (oFat.m_ucFsfname[i-1] != ' ') break;
}
FAT_CompareArray(oFat.m_ucFsfname, p, i, &nComArray, sCh);
ok = !nComArray; //LYS 040102 strncmp() was used.
}
if (ok) {
// Calculate start cluster and save in location */
pfile->size = LSB_GET_4BYTES(p+28);
FAT_GetEntryCluster(p, &nEntCluster, sCh);
pfile->addr = nEntCluster;
pfile->ucAttr = p[11];
*nMatEnt = 1;
}
else
*nMatEnt = 0;
}
/************************************************************************/
/* match entry processing: check sum, short name compare and info save */
/************************************************************************/
void FAT_AttributeFile(u8 *p, int* nAttriFile, SDHC* sCh) // p: FAT32 byte directory entry structure
{
int res;
/* the ucAttr match checking */
if (((p[11]&ATTR_VOLUME_ID)==ATTR_VOLUME_ID)&&((p[11]&ATTR_LONG_NAME)!=ATTR_LONG_NAME))
{ // volume ID */
res=0;
}
else if ((p[11]&ATTR_LONG_NAME)==ATTR_LONG_NAME && p[0]!=FREE_ENTRY_TAG0)
{ // long name */ // 0xe5 == no file or dir in this entry.
res=1;
}
else if (p[0]==DOT_ENTRY_TAG0)
{ // . entry */
res=2;
}
else
{
res=3; // other else */
}
*nAttriFile = res;
}
/************************************************************************/
/* search the specified file on hd, always using unicode long file name */
/************************************************************************/
void FAT_SearchDirFileEntry(int location, short *lfname, int entry_num, u8 ucAttr,
ISOFILE *pfile, int *sector, int *offset, int *clus, int* nSpecFile, SDHC* sCh)
{
char cSfname[SF_NAME_LENGTH+1];
u8 *buff_start, *buff_end;
int precluster;
int cluster = ((location)?location:oFat.m_uBpbRootClus);
int checksum;
int match=0, sector_offset=0, termination=0, num=entry_num;
int start_sector, ftype, longfilename=0;
int nSfnameconv;
int temp;
int nAnoChain;
if ((lfname!=NULL&&entry_num!=1)||(entry_num<1||entry_num>32))
*nSpecFile = 0;
if (lfname)
{
FAT_GenerateSNameFromLName(lfname, cSfname, &temp, sCh);
FAT_FormatSFileName(oFat.m_ucFsfname, cSfname, &nSfnameconv, sCh);
if (nSfnameconv < 0)
*nSpecFile = 0;
}
//buff_start = oFat.m_ucDirBuffStart;
FAT_InitBuffSearchMem(&buff_start, sCh); // LYS 040407
buff_end = buff_start + oFat.m_usBpbBytsPerSec;
*clus = cluster;
while (!LAST_CLUSTER(cluster))
{
u8 *p = buff_start;
int nLba;
FAT_FromClusterToLba(cluster, &nLba, sCh);
start_sector = nLba + sector_offset;
FAT_ReadSector(buff_start, start_sector, 1, sCh);
if (termination > 1)
{
FAT_AppendProcess(buff_start, start_sector, termination, sCh);
if (termination==3)
{
FAT_UnifySector(sector, offset, start_sector, (num-1)*DIR_ENTRY_SIZE, sCh);
}
*nSpecFile = 1;
}
while (p<buff_end)
{
FAT_UnifySector(sector, offset, start_sector, p-buff_start, sCh);
if(p[0]==TERM_ENTRY_TAG0 || termination==1) /*terminating */
{
if (lfname!=NULL)
*nSpecFile = 0;
FAT_ProcessTerm(p, buff_start, start_sector, num, &termination, sCh);
if (!termination)
*nSpecFile = 1;
if (termination==1)
num--;
else
break;
longfilename=0;
}
else if (p[0]==FREE_ENTRY_TAG0) /*deleted file(dir) */
{
if (lfname==NULL) {
if (num>1)
num--;
else
*nSpecFile = 1;
}
longfilename=0;
}
else if ((lfname!=NULL)&&(p[11]&ucAttr)==p[11]) /* match a file we want */
{
num = entry_num;
FAT_AttributeFile(p, &ftype, sCh);
if (ftype==1) { // long name
FAT_ProcessLfname(lfname, p, buff_start, start_sector, &checksum, &match, sCh);
if (!match)
longfilename = 1;
else {
longfilename = 0;
if (match<0)
match = 0;
}
}
else if (ftype>=2&&!longfilename) { // 2: . entry, more than 3: short name
int nMatEnt;
FAT_MatchProcess(match, checksum, p, pfile, &nMatEnt, sCh);
if (nMatEnt) {
*nSpecFile = 1; // short name compare using checksum, oFat.m_ucFsfname
}
match = 0;
longfilename = 0;
}
}
else
{
num = entry_num;
longfilename = 0;
}
if (match)
{
match++;
if (match==3)
{
match = 0;
checksum = 0;
}
}
p += DIR_ENTRY_SIZE;
} // end of while (p<buff_end)
if (termination) {
FAT_WriteSector(buff_start, start_sector, 1, sCh);
}
sector_offset++;
if (!cluster) {
if (sector_offset>=oFat.m_usRootDirSectors)
break;
}
else if (sector_offset>=oFat.m_ucBpbSecPerClus) {
num = entry_num;
sector_offset = 0;
precluster = cluster;
FAT_GetNextCluster(cluster, &cluster, sCh);
Assert(cluster!=0);
if (termination&&LAST_CLUSTER(cluster))
{
int size=1;
FAT_AllocateClusterChain(0, &size, 2, 0, 0, &cluster, sCh);
Assert(cluster);
if (!cluster)
break;
FAT_AppendCluster(precluster, cluster, &nAnoChain, sCh);
if (termination==1)
termination = 3;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -