📄 fdtana.c
字号:
if (j==8)
count=0;
if(j>=8&&j<=10)
fdtInfo.extName[count]=cat[catalog][j]; /*8~10字节是扩展名*/
if(j==22)
count=0;
if(j==11)
fdtInfo.fProperty=cat[catalog][j]; /*第11字节记录文件属性*/
if(j==22||j==23)
fdtInfo.createTime[count]=cat[catalog][j]; /*22,23字节记录文件修改时间*/
if(j==24)
count=0;
if(j==24||j==25)
fdtInfo.createDate[count]=cat[catalog][j]; /*24,25记录文件修改日期*/
if(j==26)
count=0;
if (j==26||j==27)
fdtInfo.startAdd[count]=cat[catalog][j]; /*文件起始簇簇地址*/
if(j==28)
count=0;
if(j>=28&&j<=31) /*共四个字节记录文件大小*/
fdtInfo.fSize[count]=cat[catalog][j];
fdtInfo.isEOF=fdtInfo.isEOF+cat[catalog][j];
}
rewind(fp);
return fdtInfo;
}
/*计算len个字节的数据所表示的大小*/
float Size(int byteVals[],int len)
{
int sizeVal[MAXSIZE]={0}; /*byteVal low,byteVal high*/
int i=0,j=0;
float 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=(float)DataConversion(sizeVal,len*2,16);
return size;
}
/*分析文件目录项*/
void AnalyzeFDT(FILE*fp)
{
FDT fdtInfo;
int i=0,cata=0;
int temp[4]={0};
printf("FileName\tCreateDateAndTime\tStart\tSize\tproperty\n\n");/*输出项*/
printf("-----------------------------------------------------------------------------------------\n");
for(cata=0;cata<CATTOTAL;cata++) /*遍历整个FDT*/
{
fdtInfo=RetCatalog(cata,fp); /*提取文件目录项*/
if(fdtInfo.isEOF==0) /*文件目录项结束退出*/
break;
if(fdtInfo.fProperty==0x0f||fdtInfo.fName[0]==0xe5) /*属性字节是0x0f表示长文件名,文件名首字节是0xe5表示一删除*/
continue; /*,结束本次循环,不处理长文件名和已经删去的文件(夹)*/
/*显示短文件名或者长文件名的短文件名*/
if (fdtInfo.fName[0]!=0xe5) /*不显示已删除文件(夹)名*/
{
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[CATTOTAL][CATLEN];
int i=0,j=0;
for (i=0;i<CATTOTAL;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[CATTOTAL][CATLEN];
int i=0,j=0,tmp;
ARR isEnd;
for (i=0;i<CATTOTAL;i++)
for (j=0;j<CATLEN;j++)
arrName[i][j]=fgetc(fp); /*获取文件目录项*/
rewind(fp); /*用完文件指针要重新指向文件头部*/
printf("\n\n");
for(j=0;j<CATTOTAL;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;
if (i>=447&&i<=449) /*start CHS*/
{
diskInfo.byteVals[count]=byteVal;
count++;
}
if (i>=451&&i<=453) /*end CHS*/
{
diskInfo.byteVals[count]=byteVal;
count++;
}
if (i>=458&&i<=461) /*current size */
{
diskInfo.byteVals[count]=byteVal;
count++;
}
if (i>=462&&i<=465) /*is next driver?*/
diskInfo.isNext=diskInfo.isNext+byteVal;
}
rewind(fp);
return diskInfo;
}
/*显示驱动器基本信息*/
void DisDiskInfo(DINFO diskInfo)
{
CHS staCHS,endCHS;
int dSize[4],i;
if(diskInfo.isActive)
printf("\n\nThe disk is Active!\n");
staCHS=RetCHS(diskInfo.byteVals[0],diskInfo.byteVals[1],diskInfo.byteVals[2]);
endCHS=RetCHS(diskInfo.byteVals[3],diskInfo.byteVals[4],diskInfo.byteVals[5]);
printf("The start CHS:%d,%d,%d\n",staCHS.cyl,staCHS.head,staCHS.sec);
printf("The end CHS:%d,%d,%d\n",endCHS.cyl,endCHS.head,endCHS.sec);
if(diskInfo.fileSysType==0x0b||diskInfo.fileSysType==0x0c)
printf("The file system is : FAT32\n");
if(diskInfo.fileSysType==0x86||diskInfo.fileSysType==0x87)
printf("The file system is : NTFS\n");
for (i=0;i<4;i++)
dSize[i]=diskInfo.byteVals[6+i];
printf("This driver size is: %f M\n",(Size(dSize,4)*SECBYTE/1024/1024));
if(diskInfo.isNext)
printf("It has next driver.\n");
else
printf("It's the last driver.\n");
getch();
}
/*一下是读取扇区信息并保存的的代码*/
long RetFDTLBA(FILE *fp)
{
int i,count,arrBPBInfo[512];
long LBA;
int keepSize[2],hiddenSize[4],FATSize[4];
int cluSize,fdtSta[4];
for (i=0,count=0;i<512;i++)
{
arrBPBInfo[i]=fgetc(fp);
if(i==13)
cluSize=arrBPBInfo[i];/*每簇扇区数*/
if (i==14||i==15)
{
keepSize[count]=arrBPBInfo[i];
count++;
}
if(i==16)
count=0;
if(i>=28&&i<=31)
{
hiddenSize[count]=arrBPBInfo[i];
count++;
}
if(i==32)
count=0;
if(i>=36&&i<=39)
{
FATSize[count]=arrBPBInfo[i];
count++;
}
if(i==40)
count=0;
if(i>=44&&i<=47)
{
fdtSta[count]=arrBPBInfo[i];
count++;
}
}
rewind(fp);
LBA=Size(keepSize,2)+Size(hiddenSize,2)+2*Size(FATSize,4)+(Size(fdtSta,4)-2)*cluSize;
return LBA;
}
/*逻辑地址转换为物理地址*/
CHS LBAToCHS(long LBA)
{
CHS fdtAdd;
fdtAdd.cyl=LBA/(255*63);
fdtAdd.head=(LBA/63)%255;
fdtAdd.sec=LBA%63+1;
return fdtAdd;
}
/*读取扇区地址*/
void ReadSector(FILE *fp,int cyl,int head,int sec,int len)
{
char buffer[512*16]={NULL};
int i=0;
biosdisk(0x02,0x80,head,cyl,sec,len,buffer);
for(i=0;i<512*len;i++)
fputc(buffer[i],fp);
rewind(fp);
memset(buffer,0,512*16);
}
/*保存扇区数据*/
void SaveSecData(FILE *fpmbr,FILE *fpdbr,FILE *fpfdt)
{
CHS fdtadd;
long LBA;
ReadSector(fpmbr,0,0,1,1);
ReadSector(fpdbr,0,1,1,1);
LBA=RetFDTLBA(fpdbr);
rewind(fpdbr);
fdtadd=LBAToCHS(LBA);
ReadSector(fpfdt,fdtadd.cyl,fdtadd.head,fdtadd.sec,16);
rewind(fpfdt);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -