📄 final.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fat.h"
byte buf[512];
DPT readMbr[4];
BsFAT16 dbr;
dword TotClus;
dword FATSz;
FILE *p;
dword CurrentClus=0;
char tip[260]="$:\\";
byte FATBuf[512];
word FATSecNum=-1;
struct
{
dword FirstDbr;
dword FirstFAT[2];
dword FirstRoot;
dword FirstData;
}FirstPos;
struct
{
dword ParrentClus;
dword DetailClus;
dword PreClus;
dword NextClus;
word offset;
byte FileNum;
byte Dir_Attr;
word LO;
word HI;
dword FileSize;
}FileInfo,File1,File2;
int initialize()
{
dword i;
int MbrFlag=0,EndFlag=1;
word x,y;
read1(buf,0,p);
if((buf[510] != 0x55) || (buf[511] != 0xAA))
return -1;
for(i=0;i<4;i++)
{
readMbr[i]=*((DPT*)(buf+0x1BE+i*16));
x=y=readMbr[i].SCy;
readMbr[i].SCy=((x<<8)&0x0300)|(y>>2);
x=y=readMbr[i].ECy;
readMbr[i].ECy=((x<<8)&0x0300)|(y>>2);
}
if(readMbr[0].SigAct==0x80)
MbrFlag=1;
while(EndFlag)
{
if(MbrFlag==1)
read1(buf,readMbr[0].PreSec,p);
dbr=*((BsFAT16*)buf);
if((buf[510]!=0x55)||(buf[511]!=0xAA))
{
if(MbrFlag==1)
{
MbrFlag=0;
read1(buf,0,p);
}
else
return -1;
}
else if((dbr.BPB_BytsPerSec%512)!=0)
{
if(MbrFlag==1)
{
MbrFlag=0;
read1(buf,0,p);
}
else
return -1;
}
else if((dbr.BPB_SecPerClus!=1)&&(dbr.BPB_SecPerClus!=2)&&
(dbr.BPB_SecPerClus!=4)&&(dbr.BPB_SecPerClus!=8)&&
(dbr.BPB_SecPerClus!=16)&&(dbr.BPB_SecPerClus!=32)&&
(dbr.BPB_SecPerClus!=64)&&(dbr.BPB_SecPerClus!=128))
{
if(MbrFlag==1)
{
MbrFlag=0;
read1(buf,0,p);
}
else
return -1;
}
else if(dbr.BPB_NumFATs!=2)
{
if(MbrFlag==1)
{
MbrFlag=0;
read1(buf,0,p);
}
else
return -1;
}
else if((dbr.BPB_RootEntCnt*32%dbr.BPB_BytsPerSec)!=0)
{
if(MbrFlag==1)
{
MbrFlag=0;
read1(buf,0,p);
}
else
return -1;
}
else
EndFlag=0;
}
if(MbrFlag==1)
{
if((readMbr[0].SysType!=0x04)&&(readMbr[0].SysType!=0x06)&&
(readMbr[0].SysType!=0x0E)&&(readMbr[0].SysType!=0x14))
return -1;
}
else
{
readMbr[0].PreSec=0;
if(dbr.BPB_BytsPerSec!=512)
return -1;
if(dbr.BPB_FATSz16==0)
return -1;
if(dbr.BS_BootSig==0x29)
{
dbr.BS_FilSysType[5]=0;
if(!strcmp(dbr.BS_FilSysType,"FAT12"))
return -1;
}
}
FATSz=dbr.BPB_FATSz16;
if(dbr.BPB_TotSec16!=0)
TotClus=dbr.BPB_TotSec16;
else
TotClus=dbr.BPB_TotSec32;
TotClus -= dbr.BPB_RsvdSecCnt+FATSz*2+dbr.BPB_RootEntCnt*32/dbr.BPB_BytsPerSec;
TotClus /= dbr.BPB_SecPerClus;
FirstPos.FirstDbr=readMbr[0].PreSec;
FirstPos.FirstFAT[0]=FirstPos.FirstDbr+dbr.BPB_RsvdSecCnt;
FirstPos.FirstFAT[1]=FirstPos.FirstFAT[0]+FATSz;
FirstPos.FirstRoot=FirstPos.FirstFAT[1]+FATSz;
FirstPos.FirstData=FirstPos.FirstRoot+((dbr.BPB_RootEntCnt*32)+(dbr.BPB_BytsPerSec-1))/dbr.BPB_BytsPerSec;
read1(buf,FirstPos.FirstFAT[0],p);
if((buf[0]!=dbr.BPB_Media)||(buf[1]!=0xFF)||(buf[2]!=0xFF)||((buf[3]&0x3F)!=0x3F))
FirstPos.FirstFAT[0]=0;
read1(buf,FirstPos.FirstFAT[1],p);
if((buf[0]!=dbr.BPB_Media)||(buf[1]!=0xFF)||(buf[2]!=0xFF)||((buf[3]&0x3F)!=0x3F))
FirstPos.FirstFAT[1]=0;
if(FirstPos.FirstFAT[0]==0)
{
if(FirstPos.FirstFAT[1]==0)
return -1;
FirstPos.FirstFAT[0]=FirstPos.FirstFAT[1];
}
return 1;
}
/* 读写FAT表,clus为簇号,value为写入clus的值,type为0时为读,为1时为写; */
/* 为2时释放以Clus为首的簇链;3返回一个空簇并标记EOC;返回0表示错误; */
/* 4时显示磁盘空间使用情况;5时找出Clus个空簇并放入pClus指向的数组中; */
/* 6时把pClus指向的簇链写入FAT表中; */
dword RWFAT(dword Clus,word value,byte type,dword *pClus)
{
word FATSec,FATOff;
dword ClusNum=0,TotClusNum=Clus;
double FreeClus=0,size;
int ChangFlag=0,i,EndFlag=1;
char *w="KMGT";
if((type==3)||(type==4)||(type==5))Clus=2;
if(type==6)Clus=pClus[0];
while(EndFlag)
{
if(Clus>TotClus+1)return 0;
FATSec=(Clus*2)/dbr.BPB_BytsPerSec;
FATOff=(Clus*2)%dbr.BPB_BytsPerSec;
if(FATSecNum!=FATSec)
{
if(ChangFlag)
{
write1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
write1(FATBuf,FATSecNum+FirstPos.FirstFAT[1],p);
}
FATSecNum=FATSec;
read1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
}
if(type==0)
return ((word*)FATBuf)[FATOff/2];
else if(type==1)
{
((word*)FATBuf)[FATOff/2]=value;
write1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
write1(FATBuf,FATSecNum+FirstPos.FirstFAT[1],p);
return 1;
}
else if(type==2)
{
Clus=((word*)FATBuf)[FATOff/2];
((word*)FATBuf)[FATOff/2]=0x0000;
ChangFlag=1;
if(Clus>0xFFF7)EndFlag=0;
}
else if(type==3)
{
if(((word*)FATBuf)[FATOff/2]==0)
{
((word*)FATBuf)[FATOff/2]=0xFFFF;
write1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
write1(FATBuf,FATSecNum+FirstPos.FirstFAT[1],p);
return Clus;
}
else Clus++;
}
else if(type==4)
{
if(((word*)FATBuf)[FATOff/2]==0)FreeClus++;
Clus++;
if(Clus>TotClus+1)EndFlag=0;
}
else if(type==5)
{
if(((word*)FATBuf)[FATOff/2]==0)
{
pClus[ClusNum]=Clus;
ClusNum++;
if(ClusNum==TotClusNum)return 1;
Clus++;
}
else Clus++;
}
else if(type==6)
{
if(((word*)FATBuf)[FATOff/2]!=0)return 0;
((word*)FATBuf)[FATOff/2]=pClus[ClusNum+1];
ChangFlag=1;
ClusNum++;
Clus=pClus[ClusNum];
if(Clus>0xFFF7)EndFlag=0;
}
}
if(ChangFlag)
{
write1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
write1(FATBuf,FATSecNum+FirstPos.FirstFAT[1],p);
if(type==3)return ((word*)FATBuf)[FATOff/2];
}
if(type==4)
{
size=dbr.BPB_BytsPerSec*dbr.BPB_SecPerClus/1024;
FreeClus*=size;
i=0;
do
{
if(FreeClus<1024){printf("free:%lf %c\t",FreeClus,w[i]);break;}
else {FreeClus/=1024;i++;}
}while(1);
FreeClus=TotClus*size;
i=0;
do
{
if(FreeClus<1024){printf("totle:%lf %c\n",FreeClus,w[i]);break;}
else {FreeClus/=1024;i++;}
}while(1);
}
return 1;
}
/* 在簇Clus中查找目录名为DirName的目录所在的簇,并根据OpType的值确定各种 */
/* 不同的操作类型,0表示dir显示目录操作,显示簇链内的所有目录和文件; */
/* 1表示cd操作,2表示查找目录指向的簇号; */
/* 3表示找出一个空目录entry,其簇号由函数返回,簇内偏移由entry返回; */
/* 4表示检查目标簇目录里是否为空,空则返回1,否则返回0; */
int search(dword Clus,const char *DirName,byte OpType)
{
dword FirstSec;
byte name[255];
int i,j,m,n=0,k,l,EndFlag=0;
byte a[3];
sDir16 Dir16;
word DirNum=0,FileNum=0;
strcpy(name,DirName);
FileInfo.ParrentClus=FileInfo.DetailClus=FileInfo.PreClus=FileInfo.NextClus=Clus;
do
{
FileInfo.FileNum=0;
if(FileInfo.ParrentClus!=0)
{
FirstSec=((FileInfo.DetailClus-2)*dbr.BPB_SecPerClus)+FirstPos.FirstData;
FileInfo.NextClus=RWFAT(FileInfo.DetailClus,0,0,0);
if((FileInfo.NextClus==0x0000)||(FileInfo.NextClus==0x0001)||((FileInfo.NextClus>=0xFFF0)&&(FileInfo.NextClus<=0xFFF7)))
{printf("Error!\n");getch();return -1;} /* 返回-1值表示出错 */
l=dbr.BPB_SecPerClus;
}
else
{
FirstSec=FirstPos.FirstRoot;
l=dbr.BPB_RootEntCnt*32/dbr.BPB_BytsPerSec;
}
for(i=0;i<l;i++)
{
read1(buf,FirstSec+i,p);
for(j=0;j<dbr.BPB_BytsPerSec/32;j++)
{
Dir16=*((sDir16*)(buf+j*32));
if(Dir16.DIR_Name[0]==0x00)
{
if(OpType==3)
{
FileInfo.offset=i*dbr.BPB_BytsPerSec/32+j;
return 1;
}
goto jmpout;
}
else if(Dir16.DIR_Name[0]==0xE5)
{
if(OpType==3)
{
FileInfo.offset=i*dbr.BPB_BytsPerSec/32+j;
return 1;
}
}
else if(OpType!=3)
{
if(Dir16.DIR_Name[0]==0x05) Dir16.DIR_Name[0]=0xE5;
if((Dir16.DIR_Attr&0x3F)!=0x0F)
{
if((OpType==0)||(OpType==4)) /* dir操作,统计目录信息 */
{
if(OpType==0)
{
k=0;
for(m=0;m<8;m++)
{
if((byte)Dir16.DIR_Name[m]==0x20)break;
putchar(Dir16.DIR_Name[m]);
}
k+=m;
if((byte)Dir16.DIR_Name[8]!=0x20)putchar('.');
for(m=8;m<11;m++)
{
if((byte)Dir16.DIR_Name[m]==0x20)break;
putchar(Dir16.DIR_Name[m]);
}
k+=m-8;
if(k<=6)putchar('\t');
putchar('\t'); putchar('\t');
}
/* 在次添加目录统计信息程序 */
if((Dir16.DIR_Attr&0x18)==0x00) /* Found a file. */
{
FileNum++;
if(OpType==0)printf("\t%10lu B",Dir16.DIR_FileSize);
}
else if((Dir16.DIR_Attr&0x18)==0x10)/* Found a directory. */
{
DirNum++;
if(OpType==0)printf("<dir>");
}
else if((Dir16.DIR_Attr&0x18)==0x08)
/* Found a volume label. */
{ }
if(OpType==0)
{
putchar('\n');
if(++n==23)
{
printf("Press any key to continue!\n");
getch();
n=0;
}
}
}
if(((OpType&0x0F)==2)&&((Dir16.DIR_Attr&0x08)==0x00)) /* 正常查找操作,找到目录项就退出 */
{
FileInfo.FileNum++;
if((OpType&0xF0)==0x30);
else if((OpType&0x10)&&((Dir16.DIR_Attr&0x18)!=0x00))continue;
else if((OpType&0x20)&&((Dir16.DIR_Attr&0x18)!=0x10))continue;
strcpy(name,DirName);
if((n=strlen(name))>12)return -1;
if(!strcmp(name,".")){k=1;while(k<11){name[k]=0x20;k++;}}
else if(!strcmp(name,"..")){k=2;while(k<11){name[k]=0x20;k++;}}
else{
k=0;
while(name[k]!=0){if(name[k]=='.')break;k++;}
if(k>8)return -1;
if((n-k-1)>3)return -1;
if(name[k]==0)while(k<11){name[k]=0x20;k++;}
else
{
a[0]=name[k+1];a[1]=name[k+2];a[2]=name[k+3];
while(k<8){name[k]=0x20;k++;}
while(k<11){if(a[k-8]==0)break;else name[k]=a[k-8];k++;}
while(k<11){name[k]=0x20;k++;}
}
}
for(k=0;k<11;k++)if(name[k]!=Dir16.DIR_Name[k])break;
if(k==11)
{
FileInfo.offset=i*dbr.BPB_BytsPerSec/32+j;
FileInfo.Dir_Attr=Dir16.DIR_Attr;
FileInfo.LO=Dir16.DIR_FstClusLO;
FileInfo.HI=Dir16.DIR_FstClusHI;
FileInfo.FileSize=Dir16.DIR_FileSize;
EndFlag=1;
}
}
}
}
}
}
jmpout:;
if(EndFlag||(FileInfo.ParrentClus==0)||((FileInfo.NextClus>=0xFFF8)&&(FileInfo.NextClus<=0xFFFF)))
break;
FileInfo.PreClus=FileInfo.DetailClus;
FileInfo.DetailClus=FileInfo.NextClus;
}while(1);
if(OpType==0)
{
/* 在此添加显示目录统计信息程序 */
printf("There are %u files,%u directory in this directory.\n",FileNum,DirNum);
return 1;
}
if(((OpType&0x0F)==2)&&(EndFlag==1)) return 1;
if(OpType==3)
{
if(FileInfo.ParrentClus==0)
printf("Error!\nMax number directry entry in the root directry!");
else
{
FileInfo.PreClus=FileInfo.DetailClus;
FileInfo.DetailClus=RWFAT(0,0,3,0);
RWFAT(FileInfo.PreClus,(word)FileInfo.DetailClus,1,0);
FirstSec=((FileInfo.DetailClus-2)*dbr.BPB_SecPerClus)+FirstPos.FirstData;
for(i=0;i<512;i++)buf[i]=0;
for(i=0;i<dbr.BPB_SecPerClus;i++)write1(buf,FirstSec+i,p);
FileInfo.offset=0;
return 1;
}
}
if(OpType==4)
{
if((FileNum==0)&&(DirNum<=2))return 1;
else return 0;
}
return -1;
}
/* 通过递归调用search函数确定path指向的目录所在的簇号, */
/* OpType为1表示cd操作,2表示正常查找目录 */
dword allocal(const char *path,byte OpType)
{
char name[255];
dword clus=CurrentClus;
char TmpTip[260];
int i=0,j=0,k,flag=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -