⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdtana.c

📁 1.显示扇区信息 2.显示fat32C盘大小等属性 3.分析C盘根目录下个文件属性 4.显示长文件名
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************/

/*************************************************************************/

#include <stdio.h>
#include <bios.h>              /*TC下运行需要(biosdisk())*/

/*宏定义*/
#define CATTOTAL 16*16              /*总的文件目录项*/
#define CATLEN   32                 /*文件目录项的长度*/
#define MAXSIZE  512*16             /*数组的最大容量*/
#define HEAD     255                /*每个柱面磁头数*/
#define SECTOR   63                 /*每个磁头扇区数*/
#define SECBYTE  512                /*每个扇区字节数*/
#define SECTOTAL 16                 /*要读的扇区数*/


/*结构体类型申明*/
typedef struct CHSVal               /*存放扇区地址*/
{ 
    int cyl;
    int head;
    int sec;
}CHS;

typedef struct createtime           /*记录时间*/
{
    short int sec;
    short int min;
    short int hour;
}TIME;

typedef struct createdate           /*记录日期*/
{
    short int day;
    short int mon;
    short int year;
}DATE;

typedef struct  diskinfo            /*记录磁盘的基本属性*/
{       
    int isActive;                   /*判断是否是活动驱动器*/
    int fileSysType;                /*记录驱动器的文件系统类型*/
    int byteVals[10];               /*记录驱动器的大小以及起始和终止的扇区地址*/
    long isNext;                    /*判断是否是最后一个分区*/
}DINFO;

typedef struct  FDTInfo             /*记录FDT信息*/
{       
    short int fName[8];             /*存放文件名*/
    short int extName[3];           /*存放扩展名*/
    short int createTime[2];
    short int createDate[2];
    short int startAdd[2];          /*起始簇地址*/
    long fSize[4];
    short int fProperty;
    long isEOF;                     /*用来判断FDT是否结束*/
}FDT;
  
typedef struct retArr               /*存放一个数组,处理1个字节*/
{
    int arr[8];
}ARR;
typedef struct DVArr                /*存放一个数组,处理两个字节*/
{
    int arr[16];
}DARR;

/*函数申明*/
void ReadSec(char name[],int cyl,int head,int len); /*读取扇区地址*/

int RetByteLow(int byteVal);                        /*返回一个字节的底4位*/

int RetByteHigh(int byteVal);                       /*返回一个字节的高四位*/

long DataConversion(int arr[],int len,int r);       /*将数组代表的数字转换成十进制(长度为len的Arr是r进制)*/

long StartAdd(FDT fdtInfo);                          /*计算文件的起始地址*/

void PrintProperty(int fProperty);                  /*显示文件属性*/

int IsFolder(int fProperty);                        /*判断FDT代表是否是文件夹*/

FDT RetCatalog(int catalog,FILE*fp);                /*从文件目录表返回长度为32个字节的文件目录项*/

TIME RetCraeteTime(FDT fdtInfo);                    /*返回文件或文件夹创建或更新的时间*/

DATE RetCreateDate(FDT fdtInfo);                    /*返回文件或文件夹创建和更新的日期*/

void AnalyzeFDT(FILE*fp);                           /*分析文件目录项*/

void DisSecInfo(FILE*fp,int byte);                  /*显示扇区数据信息*/

void PrintLongName();                               /*显示长文件名*/

void CombLongName(FILE*fp);                         /*把占多个目录项的长文件名合起来,显示出长文件名全名*/

CHS RetCHS(int byteVal1,int byteVal2,int byteVal3); /*返回起始终止扇区物理地址*/

DINFO RetDiskData(FILE *fp);                        /*返回驱动器基本信息*/

void DisDiskInfo(DINFO diskInfo);                   /*显示分析的驱动器基本信息*/

long RetFDTLBA(FILE *fp);                           /*计算FDT的逻辑首地址*/
  
CHS LBAToCHS(long LBA);                             /*逻辑地址专为CHS地址*/

void SaveSecData();                                 /*读取扇区信息保存*/

/*主函数*/
void main()                                             
{
    FILE *fpmbr,*fpdbr,*fpfdt;
    char ch;
    DINFO diskInfo;

    
    fpmbr=fopen("MBRInfo.TXT","wb+");                /*MBR信息*/
    fpdbr=fopen("DBRInfo.TXT","wb+");                /*DBR信息*/
    fpfdt=fopen("FDTInfo.TXT","wb+");                /*FDT信息*/

    SaveSecData(fpmbr,fpdbr,fpfdt);


    /*以上注释行是动态获取C盘扇区信息的代码,在tc下替换下三行即可动态分析本机C盘信息*/



    diskInfo=RetDiskData(fpmbr);                    /*读取扇区基本信息*/
    while(1) 
    {
        system("cls");                              /*清屏函数*/
        /*菜单显示*/
        printf("\n\nA.Display the sector values of MBR(CHS=0,0,1)\n");
        printf("B.Display the sector values of DBR(CHS=0,1,1)\n"); 
        printf("C.Display the sector values of FDT\n");
        printf("D.Display the basic information of driver C\n");
        printf("E.Display the root directory information of driver C\n");
        printf("F.Display the long name \n");
        printf("Q.Exit the program!\n");
        printf("-----------------------------------------------------------------------------------------\n");
        printf("Please choose one option:");

        scanf("%c",&ch);
        if (ch=='a'||ch=='A')                       /*显示主引导记录所在扇区信息*/
            DisSecInfo(fpmbr,SECBYTE);

        else if(ch=='B'||ch=='b')                        /*显示BPB所在扇区数据*/
            DisSecInfo(fpdbr,SECBYTE);

        else if(ch=='C'||ch=='c')                        /*显示FDT扇区数据*/
            DisSecInfo(fpfdt,SECBYTE*SECTOTAL);

        else if (ch=='D'||ch=='d')                       /*显示C盘的基本属性*/
            DisDiskInfo(diskInfo);

        else if(ch=='E'||ch=='e')                        /*显示C盘根目录各文件(夹)属性*/
            AnalyzeFDT(fpfdt);

        else if(ch=='F'||ch=='f')                        /*显示长文件名*/
            CombLongName(fpfdt);

            
        else if (ch=='Q'||ch=='q')                       /*退出程序*/
        {
            fclose(fpmbr);
            fclose(fpdbr);
            fclose(fpfdt);
            exit(0);
        }
        else if(ch==0x0a||ch==0x0d)                         /*回车或换行不处理*/
            ;
        else                                            /*输入其他字符提示出错*/
        {
            printf("Input Error. Please input again!");
            getch();
        }
    }

}
/*返回一个字节的底4位*/
int RetByteLow(int byteVal)   
{
    return (byteVal&0x0f);                          /*位与运算(对应的两位中有一个为0则结果为0)*/
}
/*返回一个字节的高四位*/
int RetByteHigh(int byteVal)
{
    return ((byteVal>>4)&0x0f);
}
/*将数组代表的数字转换成十进制(长度为len的Arr是r进制)*/
long DataConversion(int arr[],int len,int r)
{
    int i=0,j=0;
    long expt=0;                                    /*记录权位大小*/
    long retVal=0;                                  /*返回十进制值*/
    for (i=0;i<len;i++)     
    {
        expt=arr[i];
        for (j=len-1;j>i;j--)                       /*计算权位*/
            expt=expt*r;
        retVal=retVal+expt;
    }
    return retVal;
}

/*转换成二进制*/
ARR ValToBin(int value,int len)
{
    ARR arrBin;                                     /*记录二进制位*/
    int i=0,val=value;
    for (i=0;i<len;i++)                             /*除2取余*/
    {
        arrBin.arr[i]=val%2;
        val=val/2;
    }
    return arrBin;
}

/*显示文件属性*/
void PrintProperty(int fProperty)
{
    ARR arrBin;
    arrBin=ValToBin(fProperty,8);                   /*把表示文件属性字节数值转为二进制,每一位都代表一个属性*/

    if(arrBin.arr[5])                               /*第6位为1表示归档文件*/
        printf("A,");
    if(arrBin.arr[4])
        printf("sub,");
    if(arrBin.arr[3])
        printf("V,");
    if(arrBin.arr[2])
        printf("S,");
    if(arrBin.arr[1])
        printf("H,");
    if(arrBin.arr[0])
        printf("R,");
    printf("\n");

}

/*判断FDT代表是否是文件夹*/
int IsFolder(int fProperty)
{
    ARR arrBin=ValToBin(fProperty,8);               /*把表示文件属性字节数值转为二进制*/
    return arrBin.arr[4];                           /*第5位(arr[4])如果是1表示是文件夹*/
}

/*计算文件的起始地址簇号*/
long StartAdd(FDT fdtInfo)
{
    int sizeVal[4]={0};                             /*扇区信息用两个字节表示文件起始*/
    int i=0,j=0;
    long stAdd=0;
    for (i=0,j=3;i<2;i++)
    {
        sizeVal[j]=RetByteLow(fdtInfo.startAdd[i]);
        sizeVal[j-1]=RetByteHigh(fdtInfo.startAdd[i]);
        j=j-2;
    }
    stAdd=DataConversion(sizeVal,4,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 i=0,j=0,count=0;
    int cat[CATTOTAL][CATLEN];                          /*总共的文件目录项*/
    FDT fdtInfo;                                        /*记录文件目录项各字节代表的内容*/
    for (i=0;i<CATTOTAL;i++)
        for (j=0;j<CATLEN;j++)                          /*一个文件目录项占32B*/
            cat[i][j]=fgetc(fp);
    fdtInfo.isEOF=0;
    for (j=0,count=0;j<CATLEN;j++,count++)              /*搜索一个文件目录项*/
    {
        if (j<=7)
            fdtInfo.fName[count]=cat[catalog][j];       /*前7字节是文件名*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -