📄 file.c
字号:
#include "host_811.h"
#include "math.h"
#include "string.h"
extern struct _BPB SimpleBpb;
extern struct _FILE FileControl;
extern FAT_PARAMETER FatParameter;
extern UINT16 FatCache[2][256];
extern UINT8 buf[512];
extern UINT8 Cache[512];
//****************************************************************************
//Functions;
//****************************************************************************
//Converse Byte order
#define ConvTwoBytes(Addr) (*(UINT8*)Addr+0x100*(*(UINT8*)(Addr+1)))
#define ConvFourBytes(Addr) (*(UINT8*)Addr+0x100*(*(UINT8*)(Addr+1))+0x10000*(*(UINT8*)(Addr+2))+0x1000000*(*(UINT8*)(Addr+3)))
UINT8 InitFsys(void);
UINT32 SeekSector(UINT32 Sector, char dirname[11],struct _FILE *file);
UINT16 LinkClusterList(UINT16 Cluster);
UINT16 SeekEmptyCluster(void);
UINT16 GetListCluster(UINT16 Cluster);
UINT32 ClusterToSec(UINT16 Cluster);
UINT16 SecToCluster(UINT32 Sector);
UINT8 CheckFileName(char * filename, UINT8 dirname[11]);
UINT8 LocateDir(struct _DIR* new_dir, struct _FILE * fp);
UINT32 LocateFile( char *filename, struct _FILE *file);
//****************************************************************************
//END of Functions;
//****************************************************************************
extern UINT8 Read(UINT32 dlba,UINT8 blen,UINT8 *pbBuffer);
extern UINT8 Write(UINT32 dlba,UINT8 blen,UINT8 *pbBuffer);
extern void DelayMs(UINT8 nFactor);
extern UINT16 WordSwap(UINT16 input);
UINT8 InitFsys(void)
{
/*UINT*/UINT16 m_Offset;
UINT32 DataSectors,TotalClusters;
///////////////////////////////////////////////////////////////////////
DelayMs(100);
if(Read(0,1,(UINT8 *)buf)==FALSE)
return FALSE;
DelayMs(100);
if(buf[0x00]==0xEB ||buf[0x02]==0x90)
m_Offset=0;
else
m_Offset=ConvTwoBytes((buf+0x1c6));
if(Read(m_Offset,1,(UINT8 *)buf)==FALSE)
return FALSE;
SimpleBpb.BytsPerSec =ConvTwoBytes((&buf[11]));
SimpleBpb.SecPerClus = buf[13];
SimpleBpb.RsvdSecCnt =ConvTwoBytes((&buf[14]));
SimpleBpb.NumFATs = buf[16];
SimpleBpb.RootEntCnt = ConvTwoBytes((&buf[17]));
if((SimpleBpb.TotSec = ConvTwoBytes((&buf[19])))==0)
SimpleBpb.TotSec = ConvFourBytes((&buf[32]));
if((SimpleBpb.FATSz = ConvTwoBytes((&buf[22])))==0)
SimpleBpb.FATSz =ConvFourBytes((&buf[36]));
//------------------------------------------------------------------------
//Compute the corresponding data for Fat information;
//------------------------------------------------------------------------
FatParameter.RootDirSectors= ((SimpleBpb.RootEntCnt * 32) + (SimpleBpb.BytsPerSec - 1)) / SimpleBpb.BytsPerSec;
DataSectors = SimpleBpb.TotSec - (SimpleBpb.RsvdSecCnt + (SimpleBpb.NumFATs * SimpleBpb.FATSz) + FatParameter.RootDirSectors);
TotalClusters = DataSectors / SimpleBpb.SecPerClus;
//判断文件格式是否为fat16;
if(TotalClusters < 4085 || TotalClusters >= 65525)
return FALSE;
FatParameter.FirstFatSecNum=SimpleBpb.RsvdSecCnt+m_Offset;
FatParameter.FirstRootDirSecNum = SimpleBpb.RsvdSecCnt + (SimpleBpb.NumFATs * SimpleBpb.FATSz)+m_Offset;
FatParameter.FirstDataSector = SimpleBpb.RsvdSecCnt + (SimpleBpb.NumFATs * SimpleBpb.FATSz) + FatParameter.RootDirSectors+m_Offset;
return TRUE;
}
UINT16 SeekEmptyCluster()
{
// static UINT16 Cluster=2;//加快寻找进度
UINT16 i,OffSet,j;
// UINT16 i,Cache[256],OffSet;
for(i=0;i<SimpleBpb.FATSz;i++)
{
if(!Read(FatParameter.FirstFatSecNum+i,1,(UINT8 *)Cache))
return FALSE;
for(j=0;j<256;j++)
{
if((Cache[2*i]==0) && (Cache[2*i+1]==0))
return (i*256+j);
}
}
return 0xffff;
//************************************************************************
/* for(i=Cluster;i<SimpleBpb.BytsPerSec * SimpleBpb.FATSz / sizeof(UINT16);i++)
{
OffSet=i%(SimpleBpb.BytsPerSec/2);
if(OffSet==0)
{
if(!Read((i*2/SimpleBpb.BytsPerSec)+FatParameter.FirstFatSecNum,1,(UINT8 *)Cache))
return 0xffff;
}
if(Cache[OffSet]==0)
{
Cluster=i;
return Cluster;
}
}//*end for cycle
//************************************************************************
for(i=2;i<Cluster;i++)
{
OffSet=i%(SimpleBpb.BytsPerSec/2);
if(!Read(i*2/SimpleBpb.BytsPerSec+FatParameter.FirstFatSecNum,1,(UINT8 *)Cache))
return 0xffff;
if(Cache[OffSet]==0x0)
{
Cluster=i;
return Cluster;
}
}//*end for cycl
return 0xffff;*/
}
UINT16 LinkClusterList(UINT16 Cluster)
{
static UINT16 VariedCluster=2;
UINT16 i,OffSet,FixedSec,UpdateSec,j;
UINT8 p;
//////////////////////////////////////////////////////////////////////////////////
if(VariedCluster==2)
{ FatCache[0][256]=0;
// FatCache[1][256]=0;
VariedCluster=3;
}
//VariedCluster=Cluste
FixedSec=Cluster*2/SimpleBpb.BytsPerSec;
if(FatCache[0][256]!=FixedSec+FatParameter.FirstFatSecNum)
{ FatCache[0][256]=0;
// if(FatCache[1][256])
// if(!Write(FixedSec+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[0],TRUE))
// return FALSE;
if(!Read(FixedSec+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[0]))
return FALSE;
}
for(i=FixedSec;i<SimpleBpb.FATSz;i++)
{
if(i!=FixedSec)
{
p=1;
FatCache[0][256]=0;
if(!Read(i+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[1]))
return FALSE;
}
else{
p=0;
FatCache[0][256]=FixedSec+FatParameter.FirstFatSecNum;
}
for(j=0;j<256;j++)
{
if(FatCache[p][j]==0)
{// if(i==FixedSec)
// { p=0;
// FatCache[0][256]=FixedSec+FatParameter.FirstFatSecNum;
// }
//else{
// p=1;
// FatCache[0][256]=0;
// }
FatCache[p][j]=0xffff;
FatCache[0][Cluster%(SimpleBpb.BytsPerSec/2)]=WordSwap((i*256+j));
if(i!=FixedSec)
{ if(!Write(FixedSec+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[0]))
return FALSE;
if(!Write(i+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[p]))
return FALSE;
}
return (i*256+j);
}
}
}
///////////////////////////////////////////////////////////////////////////
FixedSec=Cluster*2/SimpleBpb.BytsPerSec;
if(!Read(FixedSec+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[0]))
return FALSE;
for(i=0;i<FixedSec;i++)
{
if(!Read(i+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[1]))
return FALSE;
for(j=0;j<256;j++)
{
if(FatCache[1][j]==0)
{
FatCache[1][j]=0xffff;
FatCache[0][Cluster%(SimpleBpb.BytsPerSec/2)]=WordSwap((i*256+j));
if(!Write(FixedSec+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[0]))
return FALSE;
if(!Write(i+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[p]))
return FALSE;
return (i*256+j);
}
}
}
return 0Xffff;
/* FixedSec=Cluster*2/SimpleBpb.BytsPerSec;
if(!Read(FixedSec+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[0]))
return FALSE;
for(i=FixedSec;i<SimpleBpb.FATSz;i++)
{
if(!Read(i+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[1]))
return FALSE;
for(j=0;j<256;j++)
{
if(FatCache[1][j]==0)
{ if(i==FixedSec)
p=0;
else p=1;
FatCache[p][j]=0xffff;
FatCache[0][Cluster%(SimpleBpb.BytsPerSec/2)]=WordSwap((i*256+j));
if(!Write(FixedSec+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[0],TRUE))
return FALSE;
if(!Write(i+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[p],TRUE))
return FALSE;
return (i*256+j);
}
}
}
for(i=0;i<FixedSec;i++)
{
if(!Read(i+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[1]))
return FALSE;
for(j=0;j<256;j++)
{
if(FatCache[1][j]==0)
{ if(i==FixedSec)
p=0;
else p=1;
FatCache[p][j]=0xffff;
FatCache[0][Cluster%(SimpleBpb.BytsPerSec/2)]=WordSwap((i*256+j));
if(!Write(FixedSec+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[0],TRUE))
return FALSE;
if(!Write(i+FatParameter.FirstFatSecNum,1,(UINT8 *)FatCache[p],TRUE))
return FALSE;
return (i*256+j);
}
}
}
return 0Xffff;*/
///////////////////////////////////////////////////////////////////////////////
/* FixedSec=Cluster*2/SimpleBpb.BytsPerSec+FatParameter.FirstFatSecNum;
if(!Read(FixedSec,1,(UINT8 *)FatCache[0]))
return FALSE;
for(i=VariedCluster; i<SimpleBpb.BytsPerSec * SimpleBpb.FATSz / sizeof(UINT16); i++)
{
UpdateSec=i*2/SimpleBpb.BytsPerSec+FatParameter.FirstFatSecNum;
OffSet=i%(SimpleBpb.BytsPerSec/2);
if(FixedSec==UpdateSec)
{
p=0;
}
else
{
if(!Read(UpdateSec,1,(UINT8 *)FatCache[1]))
return FALSE;
p=1;
}
///////////////////////////////////////////////////////////////////////////
if(FatCache[p][OffSet]==0)
{
FatCache[p][OffSet]=0xffff;
VariedCluster= i;
FatCache[0][Cluster%(SimpleBpb.BytsPerSec/2)]= WordSwap(VariedCluster);
if(!p)
{
if(!Write(FixedSec,1,(UINT8 *)FatCache[p],TRUE))
return FALSE;
return VariedCluster;
}
if(!Write(FixedSec,1,(UINT8 *)FatCache[0],TRUE))
return FALSE;
if(!Write(UpdateSec,1,(UINT8 *)FatCache[1],TRUE))
return FALSE;
return VariedCluster;
}
}//*----------------end for cycle
//////////////////////////////////////////////////////////////////////////////////
for(i=2;i<VariedCluster;i++)
{
UpdateSec=i*2/SimpleBpb.BytsPerSec+FatParameter.FirstFatSecNum;
OffSet=i%(SimpleBpb.BytsPerSec/2);
if(FixedSec==UpdateSec)
p=0;
else
{
if(!Read(UpdateSec,1,(unsigned char *)FatCache[1]))
return FALSE;
p=1;
}
if(FatCache[p][OffSet]==0)
{
FatCache[p][OffSet]=0xffff;
VariedCluster= i;
FatCache[0][Cluster%(SimpleBpb.BytsPerSec/2)]=WordSwap(VariedCluster);
if(!p)
{
if(!Write(FixedSec,1,(unsigned char *)FatCache[p],TRUE))
return FALSE;
return VariedCluster;;
}
if(!Write(FixedSec,1,(unsigned char *)FatCache[0],TRUE))
return FALSE;
if(!Write(UpdateSec,1,(unsigned char *)FatCache[1],TRUE))
return FALSE;
return VariedCluster;;
}
}//----------------------------end for cycle
/////////////////////////////////////////////////////////////////////////////////
return 0xffff;*/
}
UINT16 GetListCluster(UINT16 Cluster)
{
UINT16 Fatbuf[256];
//////////////////////////////////////////////////////////////////////////////////
if(!Read(2*Cluster/SimpleBpb.BytsPerSec+FatParameter.FirstFatSecNum,1,(UINT8 *)Fatbuf))
return FALSE;
return WordSwap(Fatbuf[Cluster%(SimpleBpb.BytsPerSec/2)]);
}
UINT16 SecToCluster(UINT32 Sector)
{
if(Sector < FatParameter.FirstDataSector)
return FALSE;
else
return (UINT16)((Sector - FatParameter.FirstDataSector) / SimpleBpb.SecPerClus + 2);
}
UINT32 ClusterToSec(UINT16 Cluster)
{
if(Cluster<2)
return (FatParameter.FirstDataSector-1);
return ((Cluster-2)*SimpleBpb.SecPerClus+FatParameter.FirstDataSector);
}
UINT32 SeekSector(UINT32 Sector, char dirname[11], struct _FILE *file)
{
struct _DIR *dir;
/*UINT*/UINT16 j, i;
UINT16 temp,temp1;
///////////////////////////////////////////////////////////////////////////////////
for(i=0; i<SimpleBpb.RootEntCnt * sizeof(struct _DIR) / SimpleBpb.BytsPerSec; i++)
{
if(!Read(Sector,1,(UINT8 *)Cache))
return 0xffffffff;
dir = (struct _DIR *)Cache;
//********************************************************************************
for(j=0; (dir->Name[0] != '\0') && (j< SimpleBpb.BytsPerSec / sizeof(struct _DIR)); j++)
{
if(memcmp(( char*)dir->Name, dirname, 11)== 0)
{
if(file != NULL)
{
memset(file, 0, sizeof(struct _FILE));
file->DirSectorNum = Sector;
file->DirIndex = j; //j 代表了文件中该扇区中的位置(0-15);
memcpy(&file->dir, dir, sizeof(struct _DIR));
}
temp=WordSwap(dir->FstClusLO);
temp1=ClusterToSec(temp);
return temp1;
}
dir++;
}//end for cycle
Sector++;
}//end for cycle
return 0xffffffff;
}
UINT32 LocateFile( char *filename, struct _FILE *file)
{
UINT32 Sector = FatParameter.FirstRootDirSecNum;
char NewFile[12];
char *p=NewFile;
///////////////////////////////////////////////////////////////////////////////
if(!CheckFileName(filename,p))
return FALSE;
Sector = SeekSector(Sector, p, file);
if(*(p+11)==NULL)
return Sector;
return 0Xffffffff;
}
UINT8 LocateDir(struct _DIR* new_dir, struct _FILE * fp)
{
//UINT8 Cache[512];
struct _DIR *dir;
UINT32 i;
UINT32 DirSectorNum = FatParameter.FirstRootDirSecNum;
////////////////////////////////////////////////////////////////////////////////
for(i=0; i<SimpleBpb.RootEntCnt * sizeof(struct _DIR) / SimpleBpb.BytsPerSec; i++)//total root dir sectors;
{
if(!Read(DirSectorNum,1,(UINT8 *)Cache))
return FALSE;
/////////////////////////////////////////////////////////////////////
for(dir = (struct _DIR *)Cache; (UINT8*)dir < Cache + SimpleBpb.BytsPerSec; dir++)
{
if(dir->Name[0] == '\0'||dir->Name[0] == 0xE5)
{
memcpy(dir, new_dir, sizeof(struct _DIR));
if(!Write(DirSectorNum,1,Cache))
if(!Write(DirSectorNum,1,Cache))
return FALSE;
if(fp)
{
fp->DirSectorNum = DirSectorNum;
fp->DirIndex = ((UINT8*)dir - Cache)/sizeof(struct _DIR);
memcpy(&fp->dir, new_dir, sizeof(struct _DIR));
}
return TRUE;
}
}//--------------------------end for cycle
DirSectorNum++;
}//-------------------------------end for cycle
return FALSE;
}
UINT8 CheckFileName( char * oldfilename, char newfilename[11])
{
char* p=newfilename;
char path[12];
char* ppath = path;
int dir_len_count; //count dir len.
int i;
////////////////////////////////////////////////////////////////////////////////////
if(oldfilename==NULL || strlen(oldfilename) >=12)
return FALSE;
dir_len_count=0;
strcpy(path, oldfilename);
//变小写字母为大写
for(i=0;(*ppath!=NULL&&i<12);i++)
{
if( *ppath > 96 && *ppath < 123)
*ppath -= 32;
ppath++;
}
memset(p, 0, 12);
ppath = path;
for(;;)
{
switch(*ppath)
{
case 0:
{
if(dir_len_count>=11)
return TRUE;
else
{
dir_len_count ++;
*p = 0x20;
p++;
}
continue;
}
////////////////////////////////////////////////////////////////////////////////
case '.':
{
if(dir_len_count > 8 || dir_len_count ==0)
{
return FALSE;
}
if(ppath[1] == '.')
{
return FALSE;
}
for(i=0; i<(8 - dir_len_count); i++)
{
*p = 0x20;
p++;
}
dir_len_count =8;
ppath++;
continue;
break;
}
/////////////////////////////////////////////////////////////////////////////////
case 0x22:
case 0x2A:
case 0x2B:
case 0x2C:
case 0x2F:
case 0x3A:
case 0x3B:
case 0x3C:
case 0x3D:
case 0x3E:
case 0x3F:
case 0x5B:
case 0x5D:
case 0x7C:
return FALSE;
/////////////////////////////////////////////////////////////////////////////////
default:
{
if(*ppath < 0x20)
return FALSE;
break;
}
////////////////////////////////////////////////////////////////////////////////
}
*p = *ppath;
dir_len_count ++;
if(dir_len_count >= 11)
return TRUE;
p++;
ppath++;
}//*end for cycle
//return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -