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

📄 backupfile.c

📁 自己写的磁盘备份小工具,能显示MBR,DBR信息以及8.4G以下的小硬盘备份恢复
💻 C
📖 第 1 页 / 共 3 页
字号:
}

/*计算文件的起始地址簇号*/
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 + -