📄 fat.cpp
字号:
return TRUE;
}
INT FAT::GetFirstSecOfClu(INT ClusterNum)
{
INT FirstSec=BPB.ReservedSectors+BPB.FatNum*BPB.SectorsPerFAT
+(ClusterNum-2)*BPB.SectorsPerCluster;
return FirstSec;
}
BOOL FAT::GetEntryAddr(CHAR *sPath, DIRINCLU &DirEnt)
{
TRACE("In GetEntryAddr: %d\n",strlen(sPath));
if(IsLongFileName(sPath))
{
GetShortPathName((char*)sPath,(char*)sPath,strlen(sPath));
}
PATHINFO PathInfo;
PathInfo.nLayer=-1;
PathInfo.pNext=NULL;
if(!BreakPath(sPath,PathInfo))
{
return FALSE;
}
CHAR *ClusterBuffer=new CHAR[GetClusterSize()];
INT ClusterNum=BPB.RootEntry;
if(!ClusterBuffer)
{
return FALSE;
}
if(!ReadCluster(ClusterNum,ClusterBuffer))
{
return FALSE;
}
PATHINFO *pCur=PathInfo.pNext;//the first layer is "M:",need not to be found.
DIRINCLU EntInClu;
Directory_FAT EntryContent;
while(pCur)
{
while(!GetEntryAddr(ClusterNum,ClusterBuffer,(CHAR*)pCur->ByteArray.GetData(),EntInClu))
{
ClusterNum=GetNextCluster(ClusterNum);
if(ClusterNum==-1)//indicates reach the end of this cluster
{
return FALSE;
}
if(!ReadCluster(ClusterNum,ClusterBuffer))
{
return FALSE;
}
}
if(!GetEntryContent(ClusterBuffer,EntInClu.DirOffset,EntryContent))
{
return FALSE;
}
ClusterNum=EntryContent.StartCluster;
if(!ReadCluster(ClusterNum,ClusterBuffer))
{
return FALSE;
}
pCur=pCur->pNext;
}
DirEnt.ClusterNum=EntInClu.ClusterNum;
DirEnt.DirOffset=EntInClu.DirOffset;
return TRUE;
}
BOOL FAT::BreakPath(const CHAR *sPath, PATHINFO &PathInfo)
{
int j=0,Layer=0;
PATHINFO *p=&PathInfo;
TRACE("%d\n",strlen(sPath));
for(int i=0;i<strlen(sPath);i++)
{
if(sPath[i]==0x5C)//0x5C='\'
{
if(!CopyByteStr(p->ByteArray,sPath,j,i))
{
return FALSE;
}
j=i+1;
p->nLayer=Layer;
p->pNext=new PATHINFO;
if(!p->pNext)
{
return FALSE;
}
p->pNext->nLayer=0;
p->pNext->pNext=NULL;
p=p->pNext;
Layer++;
}
}
if(!CopyByteStr(p->ByteArray,sPath,j,i))
{
return FALSE;
}
p->nLayer=Layer;
return TRUE;
}
BOOL FAT::IsLongFileName(const CHAR *sPath)
{
PATHINFO PathInfo,*p;
BreakPath(sPath,PathInfo);
for(p=&PathInfo; p; p=p->pNext)
{
CString temp(p->ByteArray.GetData());
if(int PointPos=temp.Find("."))
{
if(PointPos>7)
{
return FALSE;
}
if(p->ByteArray.GetSize()-(PointPos+1)>3)
{
return FALSE;
}
}
else if(p->ByteArray.GetSize()>8)
{
DeletePathInfo(PathInfo);
return TRUE;
}
}
DeletePathInfo(PathInfo);
return FALSE;
}
BOOL FAT::CopyByteStr(CByteArray &Destination, const CHAR *Source, INT BeginIndex, INT EndIndex)
{
if(sizeof(Source)<=0)
{
return FALSE;
}
if(EndIndex<BeginIndex)
{
return FALSE;
}
if(BeginIndex>=strlen(Source)&&EndIndex>=strlen(Source))
{
return FALSE;
}
for(int i=BeginIndex; i<EndIndex; i++)
{
Destination.SetAtGrow(i-BeginIndex,Source[i]);
}
Destination.SetAtGrow(i-BeginIndex,0);
return TRUE;
}
BOOL FAT::DeletePathInfo(PATHINFO &PathInfo)
{
PATHINFO *p=PathInfo.pNext,*q=PathInfo.pNext->pNext;
while(q)
{
delete p;
p=q;
q=p->pNext;
}
delete p;
return TRUE;
}
BOOL FAT::GetEntryAddr(INT ClusterNum, CHAR* ClusterBuffer, CHAR* FileName, DIRINCLU &DirInClu)
{
int EntryIndex=0;
Directory_FAT EntryContent;
while(EntryIndex<GetClusterSize()/32)
{
GetEntryContent(ClusterBuffer,EntryIndex,EntryContent);
if(IsFileNameEqual(FileName,EntryContent))
{
DirInClu.ClusterNum=ClusterNum;
DirInClu.DirOffset=EntryIndex;
return TRUE;
}
EntryIndex++;
}
return FALSE;
}
INT FAT::GetClusterSize()
{
return BPB.BytesPerSector*BPB.SectorsPerCluster;
}
BOOL FAT::GetEntryContent(CHAR *ClusterBuffer, INT EntryIndex, Directory_FAT &EntryContent)
{
if(sizeof(ClusterBuffer)<=0)
{
return FALSE;
}
if(EntryIndex<0||EntryIndex>=GetClusterSize()/32)
{
return FALSE;
}
int Ent=EntryIndex*32;
CopyElements(EntryContent.FileName,&ClusterBuffer[Ent],8);
EntryContent.FileName[8]=0;
CopyElements(EntryContent.ExtName,&ClusterBuffer[Ent+0x08],3);
EntryContent.ExtName[3]=0;
EntryContent.Archives=0;
EntryContent.Directory=0;
EntryContent.Hidden=0;
EntryContent.ReadOnly=0;
EntryContent.System=0;
EntryContent.Volume=0;
if(ClusterBuffer[Ent+0xB]&1)
{
EntryContent.ReadOnly=1;
}
if(ClusterBuffer[Ent+0xB]&2)
{
EntryContent.Hidden=1;
}
if(ClusterBuffer[Ent+0xB]&4)
{
EntryContent.System=1;
}
if(ClusterBuffer[Ent+0xB]&8)
{
EntryContent.Volume=1;
}
if(ClusterBuffer[Ent+0xB]&16)
{
EntryContent.Directory=1;
}
if(ClusterBuffer[Ent+0xB]&32)
{
EntryContent.Archives=1;
}
CopyElements(EntryContent.Reserved,&ClusterBuffer[Ent+0xC],sizeof(EntryContent.Reserved));
EntryContent.Reserved[10]=0;
int temp=(unsigned char)ClusterBuffer[Ent+0x16+1]*0x100
+(unsigned char)ClusterBuffer[Ent+0x16];
EntryContent.FileCreTime.Hour=temp/2048;
EntryContent.FileCreTime.Min=(temp%2048)/32;
EntryContent.FileCreTime.Sec=((temp%2048)%32)*2-2;
TRACE("\n%x,%x",ClusterBuffer[0x19],ClusterBuffer[0x18]);
temp=(unsigned char)ClusterBuffer[Ent+0x18+1]*0x100+
(unsigned char)ClusterBuffer[Ent+0x18];
EntryContent.FileCreDate.Year=temp/512+1980;
EntryContent.FileCreDate.Mon=(temp%512)/32;
EntryContent.FileCreDate.Day=(temp%512)%32;
EntryContent.StartCluster=(unsigned char)ClusterBuffer[Ent+0x1A+1]*0x100+
(unsigned char)ClusterBuffer[Ent+0x1A];
EntryContent.FileLength=(unsigned char)ClusterBuffer[Ent+0x1C+3]*0x100*0x100*0x100
+(unsigned char)ClusterBuffer[Ent+0x1C+2]*0x100*0x100+
(unsigned char)ClusterBuffer[Ent+0x1C+1]*0x100+(unsigned char)ClusterBuffer[Ent+0x1C];
return TRUE;
}
INT FAT::GetNextCluster(INT CurCluster)
{
INT SectorNum=BPB.ReservedSectors+CurCluster/128;//128 Clusters take one sector FAT
ABS_SEC_BUF buffer;
buffer.IsValid=-1;
if(!ReadSector(SectorNum,buffer))
{
return FALSE;
}
INT Offset=(CurCluster%128)*4;
INT n= (buffer.Data[Offset+3]&0x0F)*0x100*0x100*0x100
+buffer.Data[Offset+2]*0x100*0x100
+buffer.Data[Offset+1]*0x100
+buffer.Data[Offset];
if(n==0xFFFFFFF)//到达文件末尾
{
return -1;
}
return n;
}
BOOL FAT::IsFileNameEqual(CHAR *FileName, Directory_FAT EntryContent)
{//FileName represents the whole file name, FilName the main name, and ExtName the extension name.
CHAR FilName[9]=" ",ExtName[4]=" ";
if(!SplitFileName(FileName,FilName,ExtName))
{
return FALSE;
}
strupr(FilName);
strupr(ExtName);
strupr(EntryContent.FileName);
strupr(EntryContent.ExtName);
if((strcmp(FilName,EntryContent.FileName)!=0))
{
return FALSE;
}
if(strcmp(ExtName,EntryContent.ExtName)!=0)
{
return FALSE;
}
return TRUE;
}
BOOL FAT::SplitFileName(const CHAR* FileName,CHAR* FilName, CHAR* ExtName)
{
int PointPos;
for(int i=0; i<strlen(FileName); i++)
{
FilName[i]=FileName[i];
if(FileName[i]=='.')
{
PointPos=i;
CopyElements(ExtName,&FileName[PointPos+1],3);
break;
}
}
if(i<8)
{
while(i<8)
{
FilName[i]=' ';
i++;
}
}
return TRUE;
}
BOOL FAT::SetEntryContent(CHAR *sPath, Directory_FAT EntryContent)
{
DIRINCLU DirEnt;
if(!GetEntryAddr(sPath,DirEnt))
{
return FALSE;
}
CHAR *ClusterBuffer=new CHAR[GetClusterSize()];
if(ClusterBuffer)
{
if(!ReadCluster(DirEnt.ClusterNum,ClusterBuffer))
{
return FALSE;
}
strcpy(&ClusterBuffer[DirEnt.DirOffset*32],EntryContent.FileName);
strcpy(&ClusterBuffer[DirEnt.DirOffset*32+0x08],EntryContent.ExtName);
if(EntryContent.ReadOnly)
{
ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=1;
}
if(EntryContent.Hidden)
{
ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=2;
}
if(EntryContent.System)
{
ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=4;
}
if(EntryContent.Volume)
{
ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=8;
}
if(EntryContent.Directory)
{
ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=16;
}
if(EntryContent.Archives)
{
ClusterBuffer[DirEnt.DirOffset*32+0x0B]|=32;
}
strcpy(&ClusterBuffer[DirEnt.DirOffset*32+0xC],EntryContent.Reserved);
WORD Time,Date;
Time=EntryContent.FileCreTime.Hour*2048+EntryContent.FileCreTime.Min*32
+EntryContent.FileCreTime.Sec/2;
ClusterBuffer[DirEnt.DirOffset*32+0x16]=Time%0x100;
ClusterBuffer[DirEnt.DirOffset*32+0x16+1]=Time/0x100;
Date=(EntryContent.FileCreDate.Year-1980)*512+EntryContent.FileCreDate.Mon*32
+EntryContent.FileCreDate.Day;
ClusterBuffer[DirEnt.DirOffset*32+0x18]=Date%0x100;
ClusterBuffer[DirEnt.DirOffset*32+0x18+1]=Date/0x100;
ClusterBuffer[DirEnt.DirOffset*32+0x1A]=EntryContent.StartCluster%0x100;
ClusterBuffer[DirEnt.DirOffset*32+0x1A+1]=EntryContent.StartCluster/0x100;
ClusterBuffer[DirEnt.DirOffset*32+0x1C]=EntryContent.FileLength%0x100;
ClusterBuffer[DirEnt.DirOffset*32+0x1C+1]=(EntryContent.FileLength/0x100)%0x100;
ClusterBuffer[DirEnt.DirOffset*32+0x1C+2]=(EntryContent.FileLength/0x10000)%0x100;
ClusterBuffer[DirEnt.DirOffset*32+0x1C+3]=EntryContent.FileLength/0x1000000;
}
if(!WriteCluster(DirEnt.ClusterNum,ClusterBuffer))
{
return FALSE;
}
delete[] ClusterBuffer;
return TRUE;
}
BOOL FAT::GetEntryContent(CHAR *sPath, Directory_FAT &EntryContent)
{
DIRINCLU DirEnt;
if(!GetEntryAddr(sPath,DirEnt))
{
return FALSE;
}
CHAR *ClusterBuffer=new CHAR[GetClusterSize()];
if(!ClusterBuffer)
{
return FALSE;
}
if(!ReadCluster(DirEnt.ClusterNum,ClusterBuffer))
{
return FALSE;
}
if(!GetEntryContent(ClusterBuffer,DirEnt.DirOffset,EntryContent))
{
return FALSE;
}
delete[] ClusterBuffer;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -