www.pudn.com > BackUpFile.rar > BackUpFile.c


#include  
#include  
#include  
#include  
#include               /*TC下运行需要(biosdisk())*/ 
 
/*宏定义*/ 
#define CATNUM   16*60              /*总的文件目录项*/ 
#define CATLEN   32                 /*文件目录项的长度*/ 
#define MAXSIZE  512*16             /*数组的最大容量*/ 
#define HEAD     255                /*每个柱面磁头数*/ 
#define SECTOR   63                 /*每个磁头扇区数*/ 
#define SECBYTE  512                /*每个扇区字节数*/ 
#define SECTOTAL 16                 /*要读的扇区数*/ 
#define StackSize 500                /*栈的最大长度*/ 
 
 
/*结构体类型申明*/ 
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 BPBINFO 
{ 
    unsigned int secSize[2];         /*每扇区字节数*/ 
    unsigned int cluSize;            /*每簇扇区数*/ 
    unsigned int keepSize[2];        /*保留扇区*/ 
    unsigned int fatNum;             /*FAT表数目*/ 
    unsigned int fatSize[4];         /*每FAT扇区数*/ 
    unsigned int secNum[2];          /*每磁道扇区数*/ 
    unsigned int headNum[2];         /*磁头数*/ 
    unsigned int hiddenSize[4];      /*隐藏扇区数*/ 
    unsigned int driverSize[4];      /*当前驱动器总扇区数*/ 
    unsigned int rootStart[4];       /*根目录起始地址*/ 
}BINFO; 
 
typedef struct  FDTInfo             /*记录FDT信息*/ 
{        
    short int fName[8];             /*存放文件名*/ 
    short int extName[3];           /*存放扩展名*/ 
    short int createTime[2]; 
    short int createDate[2]; 
    short int startAdd[4];          /*起始簇地址*/ 
    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; 
 
 
//定义链栈的结构体 
typedef struct node 
{ 
    int data; 
    struct node *next; 
}*linkstack,stacknode; 
 
//置空栈 
linkstack init_linkstack() 
{ 
    linkstack top; 
    top=(linkstack)malloc(sizeof(stacknode)); 
    top->next=NULL; 
    return top; 
} 
 
//判空栈 
int empty_linkstack(linkstack top) 
{ 
    if(top->next==NULL) 
    { 
        printf("栈空\n"); 
        return -1; 
    } 
    else 
        return 1; 
} 
 
//入栈 
linkstack push_linkstack(linkstack *top,int x) 
{ 
    stacknode *s; 
    s=(stacknode *)malloc(sizeof(stacknode)); 
    s->data=x; 
    s->next=*top; 
    *top=s; 
    return *top; 
} 
 
//出栈 
linkstack pop_linkstack(linkstack top,int data[],int n) 
{ 
    stacknode *p; 
    int i; 
    if(top==NULL) 
        return NULL; 
    else 
    { 
        for(i=0;idata; 
        p=top; 
        top=top->next; 
        free(p); 
        } 
        return top; 
    } 
} 
 
 
 
 
/*函数申明*/ 
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(BINFO bpbInfo);                      /*计算FDT的逻辑首地址*/ 
 
CHS LBAToCHS(long LBA);                             /*逻辑地址专为CHS地址*/ 
 
void SaveSecData(FILE *fpmbr,FILE *fpdbr,FILE *fpfdt);    /*读取扇区信息保存*/ 
 
BINFO RetBpbInfo(FILE *fp);                         /*返回驱动器的基本信息*/ 
 
void BackupFile(FILE *fpfdt,FILE *fpdbr,FILE *fpbk,SqStack *s); 
/*主函数*/ 
void main()                                              
{ 
    FILE *fpmbr,*fpdbr,*fpfdt,*fpbk; 
    char ch; 
    DINFO diskInfo; 
    SqStack *S; 
    S = (SqStack *)malloc(sizeof(SqStack)); 
    InitStack(S); 
     
    fpmbr=fopen("MBRInfo.TXT","wb+");                /*MBR信息*/ 
    fpdbr=fopen("DBRInfo.TXT","wb+");                /*DBR信息*/ 
    fpfdt=fopen("FDTInfo.TXT","wb+");                /*FDT信息*/ 
    fpbk=fopen("bk.dat","wb+"); 
 
    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("K.Backup file.\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=='k'||ch=='K') 
            BackupFile(fpfdt,fpdbr,fpbk,S); 
             
        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;ii;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=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=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>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=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; 
    unsigned 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: %.4f M\n",((float)Size(dSize,4)*SECBYTE/1024/1024)); 
//    printf("\n%ld\n",diskInfo.isNext); 
/*    if(diskInfo.isNext) 
        printf("It has next driver.\n"); 
    else  
        printf("It's the last driver.\n"); 
     */ 
    getch(); 
} 
/*一下是读取扇区信息并保存的的代码*/ 
 
BINFO RetBpbInfo(FILE *fp) 
{ 
    int i,count; 
    char arrBPBInfo[512];   /*用整型还是用字符型?*/ 
    BINFO bpbInfo; 
    /*用char的时候一不注意就会出现一些诡异的问题*/ 
    /*    for (i=0,count=0;i<512;i++) 
    arrBPBInfo[i]=fgetc(fp);*/ 
    fread(arrBPBInfo,512,1,fp);/*用fread()时数组必须用字符型*/ 
 
    for(count=0,i=11;count<2;count++,i++) 
        bpbInfo.secSize[count]=arrBPBInfo[i]; 
    bpbInfo.cluSize=arrBPBInfo[13]; 
    for(count=0,i=14;count<2;count++,i++) 
        bpbInfo.keepSize[count]=arrBPBInfo[i]; 
    bpbInfo.fatNum=arrBPBInfo[16]; 
    for(count=0,i=24;count<2;count++,i++) 
        bpbInfo.secNum[count]=arrBPBInfo[i]; 
    for(count=0,i=26;count<2;count++,i++) 
        bpbInfo.headNum[count]=arrBPBInfo[i]; 
    for(count=0,i=28;count<4;count++,i++) 
        bpbInfo.hiddenSize[count]=arrBPBInfo[i]; 
    for(count=0,i=32;count<4;count++,i++) 
        bpbInfo.driverSize[count]=arrBPBInfo[i]; 
    for(count=0,i=36;count<4;count++,i++) 
        bpbInfo.fatSize[count]=arrBPBInfo[i]; 
    for(count=0,i=44;count<4;count++,i++) 
        bpbInfo.rootStart[count]=arrBPBInfo[i]; 
    rewind(fp);   
    return bpbInfo; 
} 
long RetFDTLBA(BINFO bpbInfo) 
{ 
    /*    long keepSize,hiddenSize,fatSize,startClu; 
    keepSize=Size(bpbInfo.keepSize,2); 
    hiddenSize=Size(bpbInfo.hiddenSize,2); 
    fatSize=bpbInfo.fatNum*Size(bpbInfo.fatSize,4); 
    startClu=(Size(bpbInfo.rootStart,4)-2)*bpbInfo.cluSize; 
    return (keepSize+hiddenSize+fatSize+startClu);  */ 
    return (Size(bpbInfo.keepSize,2)+Size(bpbInfo.hiddenSize,2)+bpbInfo.fatNum*Size(bpbInfo.fatSize,4)+(Size(bpbInfo.rootStart,4)-2)*bpbInfo.cluSize); 
} 
/*逻辑地址转换为物理地址*/ 
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); 
    fwrite(buffer,512,len,fp); 
    rewind(fp); 
//    memset(buffer,0,512*16); 
} 
/*保存扇区数据*/ 
void SaveSecData(FILE *fpmbr,FILE *fpdbr,FILE *fpfdt) 
{ 
    CHS fdtadd; 
    BINFO bpbInfo; 
    long LBA; 
    //    DINFO diskInfo; 
 
    ReadSector(fpmbr,0,0,1,1); 
    ReadSector(fpdbr,0,1,1,1); 
    //    diskInfo=RetDiskData(fpmbr); 
 
    bpbInfo=RetBpbInfo(fpdbr);       //获取分区的BPB信息 
    LBA=RetFDTLBA(bpbInfo); 
        rewind(fpdbr); 
    fdtadd=LBAToCHS(LBA); 
    //    printf("FDT start:%d,%d,%d\n",fdtadd.cyl,fdtadd.head,fdtadd.sec); 
    ReadSector(fpfdt,fdtadd.cyl,fdtadd.head,fdtadd.sec,bpbInfo.cluSize); 
    rewind(fpfdt); 
} 
 
//簇链寻址 
void FindClu(FILE *fpdbr,FILE *fpbk,FDT fdtInfo,unsigned int temp[4]) 
{ 
    int i,count; 
    unsigned int buff[512]; 
    CHS bkSec,tmSec; 
    long tmpLBA1,tmpLBA2,fatStart; 
    BINFO bpbInfo=RetBpbInfo(fpdbr); 
 
    fatStart=Size(bpbInfo.keepSize,2)+Size(bpbInfo.hiddenSize,4); 
    tmpLBA1=(((StartAdd(fdtInfo))*4/Size(bpbInfo.secSize,2))+fatStart);//记录的是簇号所在的FAT扇区逻辑地址 
    tmSec=LBAToCHS(tmpLBA1);                                            /*找到簇号所在的fat扇区,保留扇区数+隐藏扇区数=fat入口*/ 
 
    for(i=(int)((StartAdd(fdtInfo))*4%Size(bpbInfo.secSize,2)),count=0;count<4;count++,i++)/*取得表示文件下一簇的簇号*/ 
        temp[count]=buff[i]; 
    for(;temp[1]+temp[2]+temp[3]+temp[0]!=780;)    /*temp[1]+temp[2]+temp[3]+temp[0]!=780||0xff+0xff+0xff+0x0f==780*/ 
    { //判断是否是结束标志 
        bkSec=LBAToCHS((Size(temp,4)-2)*bpbInfo.cluSize+RetFDTLBA(bpbInfo));/*获得下一个要备份的簇*/ 
 
        fseek(fpbk,0,SEEK_END);// 
        ReadSector(fpbk,bkSec.cyl,bkSec.head,bkSec.sec,bpbInfo.cluSize); /*备份第二簇*/ 
        tmpLBA2=(Size(temp,4)*4/Size(bpbInfo.secSize,2))+fatStart; 
 
        if(tmpLBA1!=tmpLBA2)//判断簇号是否在一个扇区 
        { 
            tmpLBA1=tmpLBA2; 
            tmSec=LBAToCHS(tmpLBA2); 
            biosdisk(0x02,0x80,tmSec.head,tmSec.cyl,tmSec.sec,1,buff); 
        } 
        for(i=(int)((Size(temp,4))*4%Size(bpbInfo.secSize,2)),count=0;count<4;count++,i++) 
            temp[count]=buff[i]; 
    } 
} 
//备份根目录下的文件 
void BackupFile(FILE *fpfdt,FILE *fpdbr,FILE *fpbk,SqStack *S) 
{ 
    FDT fdtInfo;             //记录文件的目录登记项 
    CHS bkSec,tmSec,subFdtSec;         //tmSec记录的是表示占用情况的FAT扇区 
    FILE *fpSubFdt[StackSize];    // 
    BINFO bpbInfo;           //记录分区的各个信息 
    int i=0,catNum=0,count; 
    unsigned int temp[4]={0};  //记录簇链中的簇号 
    unsigned char buff[512];   // 
    long tmpLBA1,tmpLBA2,fatStart; 
    long j=0; 
    int fpcount=-1;                //记录目录登记项的个数 
 
    bpbInfo=RetBpbInfo(fpdbr);       //获取分区的BPB信息 
    fatStart=Size(bpbInfo.keepSize,2)+Size(bpbInfo.hiddenSize,4);//获取FAT的其始地址 
    for(catNum=0;catNumtop==-1) 
            { 
                push(S,fpfdt); 
                printf("\nfdt\n"); 
                getch(); 
            } 
            else 
            { 
                printf("\nIt's subFdt\n"); 
                getch(); 
                push(S,fpSubFdt[fpcount]); 
            } 
            BackupFile(fpSubFdt[fpcount],fpdbr,fpbk,S); 
            //为什么程序进入子目录后无法返回上级目录 
        } 
        //本目录登记项遍历完毕后,返回上一级目录 
        else if(fdtInfo.isEOF==0)//目录登记项遍历完毕可能还有另外一个条件:目录登记项没有全零的项 
        { 
            fpfdt=pop(S); 
            if(StackEmpty(S)) 
                exit(-1); 
            BackupFile(fpfdt,fpdbr,fpbk,S); 
        } 
 
    } 
    //    printf("catNum=%d  ",catNum); 
    //    fclose(fptmp); 
    fclose(fpbk); 
    rewind(fpfdt); 
    rewind(fpdbr); 
//    fclose(fpSubFdt); 
    getch(); 
}