关于分析FAT12/16/32文件系统的实验

来源:互联网 发布:织梦企业黄页网站源码 编辑:程序博客网 时间:2024/06/06 06:51

首先对硬盘0磁头0柱面1扇区,也就是MBR(Main Boot Record)分析它自0X1BE处开始,16字节为一个数据结构,称为分区信息,具体格式请参考下面实例程序,一般有不超过4个.

这个数据结构可以得到各个分区的始末CHS参数,方便对各个分区的读取.

数据量较小,实例程序需要CCDOS中文支持,贴图为我的486 4.3G硬盘2个FAT分区.

下一篇文章,将会进行BPB数据结构的建立和分析,离我们读取目录,文件很近了..继续关注哦..

/*
   This programme is for read the MBR sector and analyze its content
        Writen by Lunzi QingFeng Studio 2008/01/07
        E-mail:Dragon123321@hotmail.com QQ:123685049
*/

#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <mem.h>

#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned long

struct MBR_FatInfo
{
UINT8 ActiveMark;
UINT8 ParStartHeader;
UINT8 ParStartSector;
UINT8 ParStartCylder;
UINT8 SystemMark;
UINT8 ParEndHeader;
UINT8 ParEndSector;
UINT8 ParEndCylder;
UINT32 NumOfAheadSector;
UINT32 NumOfTotalSector;
};

void readSector(UINT8 buff[]);
void showSector(UINT8 buff[]);
int writeToFile(UINT8 buff[]);

void readSector(UINT8 buff[])
{
union REGS inr,outr;

        inr.h.ah=0x02;           /*NO 2. fuction*/
        inr.h.al=0x01;           /*the number of sectors wanted read*/
        inr.x.bx=buff;           /*save back buffer address ES:BX */
inr.h.ch=0x00;            /*Num of cylder*/
inr.h.cl=0x01;            /*Num of sector*/
inr.h.dh=0x00;        /*Num of header*/
        inr.h.dl=0x80;           /*Num of destnition disk*/
int86(0x13,&inr,&outr);
}

void showSector(UINT8 buff[])
{
        int i;

for(i=0;i<512;i++){
   if(i%24==0){
    printf("/n");
    printf("%4x : ",i);
   }

                printf("%2x ",buff[i]);
}
}


int writeToFile(UINT8 buff[])
{
        FILE *fp;
        int i;

if((fp=fopen("C://MyPro//DiskSec.bin","wat"))==NULL)
        {
   printf("Error:Could not create or open the log file ./n");
                fclose(fp);
                return(0);
        }

for(i=0;i<512;i++){
                fputc(buff[i],fp);
}

        fclose(fp);
        return(1);

}

/*************Main FUNCTION*************/
int main()
{
        UINT8 mbr[512];
int key_Input;

/******/
struct MBR_FatInfo mfi;
char *ptr;
int c=0;

readSector(mbr);
/*
showSector(mbr);

printf("/nWrite the content to a log file press y or Y others for exit !/n");
key_Input=getch();
if(key_Input=='y' || key_Input=='Y')
{
   if(writeToFile(mbr)==1) printf("Successfully write into the log file !");
    else printf("Failed write into the log file!");
}

printf("/nAnalyze this sector press y or Y others for exit !/n");
key_Input=getch();
if(key_Input=='y' || key_Input=='Y')
{
   printf("This sector is the MBR sector,More info:");

}

*/
for(c=0;c<4;c++){
                ptr=memcpy(&mfi,&mbr[(0x1be+c*16)],16);
                if(ptr)
                {    
    printf("/n启动标志 : %2x ",mfi.ActiveMark);
    printf("/n分区起始柱头 : %2x (%d)",mfi.ParStartHeader,mfi.ParStartHeader );
    printf("/t分区起始扇区 : %2x (%d)",mfi.ParStartSector,mfi.ParStartSector);
    printf("/t分区起始柱面 : %2x (%d)",mfi.ParStartCylder,mfi.ParStartCylder);
    printf("/n系统标志 : %2x",mfi.SystemMark);
    printf("/n分区结束柱头 : %2x (%d)",mfi.ParEndHeader,mfi.ParEndHeader);
    printf("/t分区结束扇区 : %2x (%d)",mfi.ParEndSector,mfi.ParEndSector);
    printf("/t分区结束柱面 : %2x (%d)",mfi.ParEndCylder,mfi.ParEndCylder);
    printf("/n分区前置扇区数 : %u",mfi.NumOfAheadSector);
    printf("/n分区扇区总数 : %u",mfi.NumOfTotalSector);
                        printf("/n");
                }
                else
                        printf("Error:Can't copy the memory!");
        }

return (0);
}


到武汉这一个星期的时间里,发生了很多事情,有喜有忧,以致于阻碍了我发文章的速度。

永亮的走让我再次感到了生活的现实与压力之可怕,希望他能在非洲平安,早日回归武汉亲人们的怀抱。。

值得高兴,我找到工作了,呵呵。。好多人呼了一口气,可算放心了,是吧?

有喜有忧,还是平常心吧。。。

今天会连发两篇文章,下面这个是读取了0磁道 1柱头 1扇区的内容,它里面包含了DBR和BPB这两个重要的数据结构,我已经建立了该数据结构,由于我的用机环境的限制,我使用的FAT16文件系统,但是程序稍加修改即可使用于FAT32的BPB读取(白皮书所提到的FAT16和FAT32通过程序计算的方法,我想单独拿出来做--等建驱动库的时候吧,呵呵,好遥远哦)。

本程序仍然使用了中文输出,请在CCDOS环境下编译运行。

关于几个重要参数的计算,是本节的关键:

首先计算根目录所占扇区数:RootDirSectors
然后计算数据区起始地址: FirstDataSector
接着计算根目录扇区号: FirstRootDirSecNum

下一节,重点是如何由这几个参数计算出FAT分区的逻辑第一簇的第一个扇区的地址,并从中取出根目录的信息。

/*
        This programme is for read the BPB sector and caculate the FAT
        Writen by Lunzi QingFeng Studio 2008/01/07
        E-mail:Dragon123321@hotmail.com QQ:123685049
*/

#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <mem.h>

#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned long

typedef struct BPB_FAT16
{
        UINT8 BS_drvNum;
        UINT8 BS_Reserved1;
        UINT8 BS_BootSig;
    UINT8 BS_VolId[4];
    UINT8 BS_VolLab[11];
    UINT8 BS_FileSysType[8];
};

typedef struct BPB_FAT32
{
        UINT32 BPB_FATSz32;
        UINT16 BPB_ExtFlags;
        UINT16 BPB_FSVer;
        UINT32 BPB_RootClus;
        UINT16 BPB_FSInfo;
        UINT16 BPB_BkBootSec;
        UINT8 BPB_Reserved[12];
        UINT8 BS_DrvNum;
        UINT8 BS_Reserved1;
        UINT8 BS_BootSig;
        UINT8 BS_VolId[4];
    UINT8 BS_FilSysType[19];
};

typedef struct BPB_Info
{
    UINT8 BS_jmpBoot[3];
    UINT8 BS_OEMName[8];
        UINT16 BPB_BytsPerSec;
        UINT8 BPB_SecPerClus;
        UINT16 BPB_RsvdSecCnt;
        UINT8 BPB_NumFATs;
        UINT16 BPB_RootEntCnt;
        UINT16 BPB_TotSec16;
        UINT8 BPB_Media;
        UINT16 BPB_FATSz16;
        UINT16 BPB_SecPerTrk;
        UINT16 BPB_NumHeads;
        UINT32 BPB_HiddSec;
        UINT32 BPB_TotSec32;
    union BPB_FATs
        {
        struct BPB_FAT16 FAT16;
        struct BPB_FAT32 FAT32;
    } BPB_FAT;
};

void readSector(int cyl,int header,int sec,UINT8 buff[]);
void showSector(UINT8 buff[]);
int writeToFile(UINT8 buff[]);

void readSector(int cyl,int header,int sec,UINT8 buff[])
{
    union REGS inr,outr;

        inr.h.ah=0x02;           /*NO 2. fuction*/
        inr.h.al=0x01;           /*the number of sectors wanted read*/
        inr.x.bx=buff;           /*save back buffer address ES:BX */
    inr.h.ch=0x3a;            /*Num of cylder*/
    inr.h.cl=0x01;            /*Num of sector*/
    inr.h.dh=0x00;         /*Num of header*/
        inr.h.dl=0x80;           /*Num of destnition disk*/
    int86(0x13,&inr,&outr);
}

void showSector(UINT8 buff[])
{
        int i;

    for(i=0;i<512;i++){
                if(i%24==0){
            printf("/n");
            printf("%4x : ",i);
    }

                printf("%2x ",buff[i]);
    }
}


int writeToFile(UINT8 buff[])
{
        FILE *fp;
        int i;

    if((fp=fopen("C://MyPro//DiskSec.bin","wab"))==NULL)
        {
        printf("Error:Could not create or open the log file ./n");
                fclose(fp);
                return(0);
        }

    for(i=0;i<512;i++){
                fputc(buff[i],fp);
    }

        fclose(fp);
        return(1);

}

/*************Main FUNCTION*************/
int main(int argc,char *argv[])
{
        UINT8 mbr[512];
    int cyl,sec,header;
    int key_Input;
        /*DBR*/
    struct BPB_Info bpb;
    char * ptr;
    int c;
        /*FAT*/
        UINT16 RootDirSectors;
        UINT16 FirstDataSector;
        UINT16 FirstSectorofCluster;
    UINT16 FATSz;
    /*FAT ROOT DIR*/
    UINT16 FirstRootDirSecNum;
/*
    if(argc <= 3 ){
        printf("This Programme need three parameters:Cylder Header Sector /n");
        exit(1);
    }
*/
    cyl=atoi(argv[1]);
    header=atoi(argv[2]);
    sec=atoi(argv[3]);

    readSector(58,0,1,mbr);
/*
    readSector(cyl,header,sec,mbr);

    showSector(mbr);

    printf("/nWrite the content to a log file press Y others for exit !/n");
    key_Input=getch();
    if(key_Input=='y' || key_Input=='Y')
    {
        if(writeToFile(mbr)==1) printf("Successfully write into the log file !");
            else printf("Failed write into the log file!");
    }

    size=62
    printf("%d ",sizeof(bpb));
*/

    ptr=memcpy(&bpb,&mbr[0],sizeof(bpb));
    if(ptr)
    {
        printf("启动代码:");
            for(c=0;c<3;c++)       printf("%2x ",bpb.BS_jmpBoot[c]);
        printf("/tOEM名称:");
                        for(c=0;c<8;c++)       printf("%c",bpb.BS_OEMName[c]);
        printf("/t每扇区字节数:");
            printf("%d",bpb.BPB_BytsPerSec);

                printf("/n每簇扇区数:");
                        printf("%d",bpb.BPB_SecPerClus);
        printf("/t保留扇区的数目:");
                        printf("%d",bpb.BPB_RsvdSecCnt);
                printf("/t本卷中FAT表数目:");
                        printf("%d",bpb.BPB_NumFATs);

                printf("/n根目录中的目录数:");
                        printf("%d",bpb.BPB_RootEntCnt);
                printf("/t本卷中总扇区数16bit:");
                        printf("%d",bpb.BPB_TotSec16);
        printf("/t存储介质类型:");
            printf("0X%2x",bpb.BPB_Media);

                printf("/n一个FAT表所占的扇区数:");
                        printf("%d",bpb.BPB_FATSz16);
                printf("/t每磁道扇区数:");
                        printf("%d",bpb.BPB_SecPerTrk);
                printf("/t磁头数:");
                        printf("%d",bpb.BPB_NumHeads);

                printf("/n此FAT表之前的隐藏扇区数:");
                        printf("%u",bpb.BPB_HiddSec);
                printf("/t本卷中总扇区数32bit:");
                        printf("%u",bpb.BPB_TotSec32);

                printf("/n/n以下内容16和32有所区别,下面的程序以16为介绍:");

                printf("/n驱动器类型参数:");
            printf("0X%2x",bpb.BPB_FAT.FAT16.BS_drvNum);
                printf("/t保留(供NTFS使用):");
            printf("%d",bpb.BPB_FAT.FAT16.BS_Reserved1);
        printf("/t拓展启动标志:");
            printf("0X%2x",bpb.BPB_FAT.FAT16.BS_BootSig);

        printf("/n磁盘卷标:");
            for(c=0;c<11;c++)       printf("%c",bpb.BPB_FAT.FAT16.BS_VolLab[c]);
                printf("/tFAT文件系统类型:");
            for(c=0;c<8;c++)       printf("%c",bpb.BPB_FAT.FAT16.BS_FileSysType[c]);

                printf("/n/n以下为计算FAT的一般步骤:");
        RootDirSectors=((bpb.BPB_RootEntCnt*32)+(bpb.BPB_BytsPerSec))/bpb.BPB_BytsPerSec;

        if(bpb.BPB_FATSz16!=0)
            FATSz=bpb.BPB_FATSz16;
        else
    {
            printf("ERROR:Your FS isn't FAT16,Please change this programme./n");
            exit(0);
    }
        FirstDataSector=bpb.BPB_RsvdSecCnt+(bpb.BPB_NumFATs*FATSz)+RootDirSectors;
        FirstRootDirSecNum=bpb.BPB_RsvdSecCnt+(bpb.BPB_NumFATs*bpb.BPB_FATSz16);
        printf("/n1 首先计算根目录所占扇区数: %d",RootDirSectors);
        printf("/n2 然后计算数据区起始地址: %d",FirstDataSector);
        printf("/n3 接着计算根目录扇区号: %d",FirstRootDirSecNum);
    }
    else
    {
        printf("Can't copy the DBR to the memory!/n");
    }

    return (0);
}

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/b2b160/archive/2009/07/30/4394979.aspx