📄 backupfile.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <malloc.h>
#include <bios.h> /*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;i<n;i++)
{
data[i]=top->data;
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;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表示是文件夹*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -