📄 backupfile.c
字号:
}
/*计算文件的起始地址簇号*/
long StartAdd(FDT fdtInfo)
{
int sizeVal[8]={0}; /*扇区信息用两个字节表示文件起始*/
int i=0,j=0;
long stAdd=0;
for (i=0,j=7;i<4;i++)
{
sizeVal[j]=RetByteLow(fdtInfo.startAdd[i]);
sizeVal[j-1]=RetByteHigh(fdtInfo.startAdd[i]);
j=j-2;
}
stAdd=DataConversion(sizeVal,8,16); /*数组表示的数字转换为十进制*/
return stAdd;
}
/*把两个字节的数据转换成二进制,计算日期和时间*/
DARR BytesToBin(int byteVal[])
{
int i=0,val=byteVal[1];
DARR dbyte; /*记录返回的16位二进制*/
for (i=7;i>=0;i--) /*switch to bin*/
{
dbyte.arr[i]=val%2;
val=val/2;
}
val=byteVal[0];
for (i=15;i>=8;i--) /*switch to bin*/
{
dbyte.arr[i]=val%2;
val=val/2;
}
return dbyte;
}
/*返回文件或文件夹创建或更新的时间*/
TIME RetCraeteTime(FDT fdtInfo)
{
int hour[5],min[6],sec[5];
int i=0,j=0;
int timeArr[2]={0};
TIME cTime;
DARR dByte;
for(i=0;i<2;i++)
timeArr[i]=fdtInfo.createTime[i]; /*必须把表示文件更新时间的两个字节存放在临时变量里*/
dByte=BytesToBin(timeArr); /*参数如果直接传fdtInfo.createTime会发生错误*/
for (i=0;i<5;i++) /*小时占5位*/
{
hour[i]=dByte.arr[i];
cTime.hour=(short)DataConversion(hour,5,2);
}
for (i=5,j=0;i<11;i++,j++) /*分钟占6位*/
{
min[j]=dByte.arr[i];
cTime.min=(short)DataConversion(min,6,2);
}
for (i=11,j=0;i<16;i++,j++) /*秒占5位,以2为增量的二进制*/
{
sec[j]=dByte.arr[i];
cTime.sec=(short)DataConversion(sec,5,2)*2;
}
return cTime;
}
/*返回文件或文件夹创建和更新的日期*/
DATE RetCreateDate(FDT fdtInfo)
{
int year[7],mon[4],day[5];
int i=0,j=0;
int dateArr[2];
DATE cData;
DARR dByte;
for(i=0;i<2;i++)
dateArr[i]=fdtInfo.createDate[i]; /*必须把表示文件更新时间的两个字节存放在临时变量里*/
dByte=BytesToBin(dateArr); /*参数如果直接传fdtInfo.createDate会发生错误*/
for (i=0;i<7;i++) /*年占7位,(7位转十进制+1980即为年份)*/
{
year[i]=dByte.arr[i];
cData.year=(short)DataConversion(year,7,2);
}
for (i=7,j=0;i<11;i++,j++) /*月份占7位*/
{
mon[j]=dByte.arr[i];
cData.mon=(short)DataConversion(mon,4,2);
}
for (i=11,j=0;i<16;i++,j++) /*具体哪天占5位*/
{
day[j]=dByte.arr[i];
cData.day=(short)DataConversion(day,5,2);
}
return cData;
}
/*从文件目录表返回长度为32个字节的文件目录项*/
FDT RetCatalog(int catalog,FILE*fp)
{
int j=0,count=0;
// int i;
int cat[CATNUM][CATLEN]; /*总共的文件目录项*/
unsigned int temp;
FDT fdtInfo; /*记录文件目录项各字节代表的内容*/
// for (i=0;i<CATNUM;i++)
// for (j=0;j<CATLEN;j++) /*一个文件目录项占32B*/
// cat[i][j]=fgetc(fp);
fseek(fp,catalog,SEEK_SET);
fdtInfo.isEOF=0;
for (j=0,count=0;j<CATLEN;j++,count++) /*搜索一个文件目录项*/
{
temp=fgetc(fp);
if (j<=7)
fdtInfo.fName[count]=temp; /*前7字节是文件名*/
if (j==8)
count=0;
if(j>=8&&j<=10)
fdtInfo.extName[count]=temp; /*8~10字节是扩展名*/
if(j==22)
count=0;
if(j==11)
fdtInfo.fProperty=temp; /*第11字节记录文件属性*/
if(j==22||j==23)
fdtInfo.createTime[count]=temp; /*22,23字节记录文件修改时间*/
if(j==24)
count=0;
if(j==24||j==25)
fdtInfo.createDate[count]=temp; /*24,25记录文件修改日期*/
if(j==20)
count=2;
if(j==20||j==21) /*文件其始簇,高位*/
fdtInfo.startAdd[count]=temp;
if(j==26)
count=0;
if (j==26||j==27)
fdtInfo.startAdd[count]=temp; /*文件起始簇簇地址*/
if(j==28)
count=0;
if(j>=28&&j<=31) /*共四个字节记录文件大小*/
fdtInfo.fSize[count]=temp;
fdtInfo.isEOF=fdtInfo.isEOF+temp;
}
// rewind(fp);
return fdtInfo;
}
/*计算len个字节的数据所表示的大小*/
long Size(unsigned int byteVals[],int len)
{
int sizeVal[MAXSIZE]={0}; /*byteVal low,byteVal high*/
int i=0,j=0;
long size=0;
for (i=0,j=2*len-1;i<len;i++)
{
sizeVal[j]=RetByteLow(byteVals[i]);
sizeVal[j-1]=RetByteHigh(byteVals[i]);
j=j-2;
}
size=DataConversion(sizeVal,len*2,16);
return size;
}
/*分析文件目录项*/
void AnalyzeFDT(FILE*fp)
{
FDT fdtInfo;
int i=0,cata=0,j=0;
unsigned int temp[4]={0};
printf("FileName\tCreateDateAndTime\tStart\tSize\tproperty\n\n");/*输出项*/
printf("-----------------------------------------------------------------------------------------\n");
// fp=fopen("system.fdt","rb");
for(cata=0;cata<CATNUM;cata++) /*遍历整个FDT*/
{
fdtInfo=RetCatalog(cata*32,fp); /*提取文件目录项*/
if(fdtInfo.isEOF==0) /*文件目录项结束退出*/
break;
if(fdtInfo.fProperty==0x0f||fdtInfo.fName[0]==0xe5) /*属性字节是0x0f表示长文件名,文件名首字节是0xe5表示一删除*/
continue; /*,结束本次循环,不处理长文件名和已经删去的文件(夹)*/
/*显示短文件名或者长文件名的短文件名*/
if (fdtInfo.fName[0]!=0xe5) /*不显示已删除文件(夹)名*/
{
printf("%3d ",++j);
for(i=0;i<8;i++)
printf("%c",fdtInfo.fName[i]);
if(IsFolder(fdtInfo.fProperty)==0) /*文件夹无扩展名,不打印"."*/
printf(".");
else
printf("<DIR");
for(i=0;i<3;i++) /*文件扩展名或者文件夹名*/
printf("%c",fdtInfo.extName[i]);
}
/*显示文件(夹)修改时间*/
printf("\t%4d-%2d-%2d",RetCreateDate(fdtInfo).year+1980,RetCreateDate(fdtInfo).mon,RetCreateDate(fdtInfo).day);
/*显示文件(夹)修改日期*/
printf(" %2d:%2d:%2d",RetCraeteTime(fdtInfo).hour,RetCraeteTime(fdtInfo).min,RetCraeteTime(fdtInfo).sec );
/*显示起始簇地址*/
printf("\t%ld",StartAdd(fdtInfo));
/*显示文件大小*/
if(IsFolder(fdtInfo.fProperty)) /*不显示文件夹的大小*/
printf("\t");
else
{
for(i=0;i<4;i++) /*记录文件大小*/
temp[i]=fdtInfo.fSize[i];
printf("\t%.2fK",(float)(Size(temp,4)/1024));
}
/*显示文件属性*/
printf("\t");
PrintProperty(fdtInfo.fProperty);
// if(cata%10==0)
// getch();
}
getch(); /*接受一个输入字符*/
}
/*显示扇区数据信息*/
void DisSecInfo(FILE*fp,int byte)
{
int i;
for (i=1;i<=byte;i++)
{
printf("%2x",fgetc(fp));
if(i%32==0) /*每行显示32个字节*/
printf("\n");
}
rewind(fp); /*将文件指针指向文件头,这样在一次运行中可以多次显示*/
getch();
}
/*显示长文件名*/
void PrintLongName(FILE*fp,int count)
{
int arr[CATNUM][CATLEN];
int i=0,j=0;
for (i=0;i<CATNUM;i++)
for (j=0;j<CATLEN;j++) /*一个文件目录项占32B*/
arr[i][j]=fgetc(fp);
/*在一个表示长文件名的文件目录项中,字符使用unicode表示,每两个字节一个字符,一个目录项只表示13个字符*/
for (i=1;i<11;) /*1~11字节表示5个字符*/
{
printf("%c",arr[count][i]);
i+=2; /*每两个字节表示一个字符,*/
}
for (i=14;i<26;) /*14~26字节表示6个字符*/
{
printf("%c",arr[count][i]);
i+=2;
}
for (i=28;i<31;) /*28~31表示2个字节*/
{
printf("%c",arr[count][i]);
i+=2;
}
rewind(fp);
}
/*把长文件名的多个文件目录项结合起来成为一个完整的长文件名*/
void CombLongName(FILE*fp)
{
int arrName[CATNUM][CATLEN];
int i=0,j=0,tmp;
ARR isEnd;
for (i=0;i<CATNUM;i++)
for (j=0;j<CATLEN;j++)
arrName[i][j]=fgetc(fp); /*获取文件目录项*/
rewind(fp); /*用完文件指针要重新指向文件头部*/
printf("\n\n");
for(j=0;j<CATNUM;j++)
{
if(arrName[j+1][6]==0x7e&&arrName[j+1][0]!=0xe5)/*如果是长文件名并且没有删除时开始计算*/
{
for (i=0;i<8;i++) /*显示长文件名对应的短文件名*/
{
printf("%c",arrName[j+1][i]);
}
printf(" is short for: ");
isEnd.arr[6]=0;
/*显示长文件名*/
for(tmp=j;isEnd.arr[6]!=1;tmp--) /*循环到文件目录表的第0字节的第6位为1的时候停止 ,表示长文件名结束*/
{
PrintLongName(fp,tmp);
isEnd=ValToBin(arrName[tmp][0],8);
}
printf("\n\n");
}
}
getch();
rewind(fp);
}
/*记录驱动器起始终止扇区*/
CHS RetCHS(int byteVal1,int byteVal2,int byteVal3)
{
CHS chs;
int i,temp1,temp2;
int clyArr[10]={0}; /*前一个字节的高两位和后一个字节合成10位表示柱面*/
temp1=(byteVal2&0xc0)>>6; /*取byteVal2的高两位 */
temp2=byteVal3;
for (i=1;i>=0;i--) /*turn binary*/
{
clyArr[i]=temp1%2;
temp1=temp1/2;
}
for (i=9;i>=2;i--)
{
clyArr[i]=temp2%2;
temp2=temp2/2;
}
chs.cyl=DataConversion(clyArr,10,2);
chs.head=byteVal1;
chs.sec=byteVal2&0x3f; /*取byteVal2的低六位表示扇区值*/
return chs;
}
/*返回扇区数据所代表的具体驱动器属性信息*/
DINFO RetDiskData(FILE *fp)
{
DINFO diskInfo;
int i=0,count=0;
int byteVal=0;
for (i=0;i<SECBYTE;i++)
{
byteVal=fgetc(fp);
if (i==446&&byteVal==0x80) /*is active? */
diskInfo.isActive=1;
if (i==450) /*file system */
diskInfo.fileSysType=byteVal;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -