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

📄 final.c

📁 FAT文件管理系统
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fat.h"

byte    buf[512];
DPT     readMbr[4];
BsFAT16 dbr;
dword   TotClus;
dword   FATSz;
FILE *p;
dword   CurrentClus=0;
char    tip[260]="$:\\";
byte    FATBuf[512];
word    FATSecNum=-1;

struct
{
    dword  FirstDbr;
    dword  FirstFAT[2];
    dword  FirstRoot;
    dword  FirstData;
}FirstPos;

struct
{
    dword ParrentClus;
    dword DetailClus;
    dword PreClus;
    dword NextClus;
    word  offset;
    byte  FileNum;
    byte  Dir_Attr;
    word  LO;
    word  HI;
    dword FileSize;
}FileInfo,File1,File2;

int initialize()
{
    dword i;
    int MbrFlag=0,EndFlag=1;
    word x,y;

    read1(buf,0,p);
    if((buf[510] != 0x55) || (buf[511] != 0xAA))
        return -1;
    for(i=0;i<4;i++)
    {
        readMbr[i]=*((DPT*)(buf+0x1BE+i*16));
        x=y=readMbr[i].SCy;
        readMbr[i].SCy=((x<<8)&0x0300)|(y>>2);
        x=y=readMbr[i].ECy;
        readMbr[i].ECy=((x<<8)&0x0300)|(y>>2);
    }
    
    if(readMbr[0].SigAct==0x80)
        MbrFlag=1;
    
    while(EndFlag)
    {
        if(MbrFlag==1)
            read1(buf,readMbr[0].PreSec,p);
        dbr=*((BsFAT16*)buf);
        if((buf[510]!=0x55)||(buf[511]!=0xAA))
    	{
            if(MbrFlag==1)
    		{
                MbrFlag=0;
                read1(buf,0,p);
    		}
        	else
                return -1;
    	}
        else if((dbr.BPB_BytsPerSec%512)!=0)
    	{
            if(MbrFlag==1)
    		{
                MbrFlag=0;
                read1(buf,0,p);
    		}
        	else
                return -1;
    	}
        else if((dbr.BPB_SecPerClus!=1)&&(dbr.BPB_SecPerClus!=2)&&
            (dbr.BPB_SecPerClus!=4)&&(dbr.BPB_SecPerClus!=8)&&
            (dbr.BPB_SecPerClus!=16)&&(dbr.BPB_SecPerClus!=32)&&
            (dbr.BPB_SecPerClus!=64)&&(dbr.BPB_SecPerClus!=128))
    	{
            if(MbrFlag==1)
    		{
                MbrFlag=0;
                read1(buf,0,p);
    		}
        	else
                return -1;
    	}
        else if(dbr.BPB_NumFATs!=2)
    	{
            if(MbrFlag==1)
    		{
                MbrFlag=0;
                read1(buf,0,p);
    		}
        	else
                return -1;
    	}
        else if((dbr.BPB_RootEntCnt*32%dbr.BPB_BytsPerSec)!=0)
    	{
            if(MbrFlag==1)
    		{
                MbrFlag=0;
                read1(buf,0,p);
    		}
        	else
                return -1;
    	}
        else
            EndFlag=0;
    }
    if(MbrFlag==1)
    {
        if((readMbr[0].SysType!=0x04)&&(readMbr[0].SysType!=0x06)&&
            (readMbr[0].SysType!=0x0E)&&(readMbr[0].SysType!=0x14))
        return -1;
    }
    else
    {
        readMbr[0].PreSec=0;
        if(dbr.BPB_BytsPerSec!=512)
            return -1;
        if(dbr.BPB_FATSz16==0)
            return -1;
        if(dbr.BS_BootSig==0x29)
    	{
            dbr.BS_FilSysType[5]=0;
            if(!strcmp(dbr.BS_FilSysType,"FAT12"))
                return -1;
    	}
    }
    
    FATSz=dbr.BPB_FATSz16;
    if(dbr.BPB_TotSec16!=0)
        TotClus=dbr.BPB_TotSec16;
    else
        TotClus=dbr.BPB_TotSec32;
    
    TotClus -= dbr.BPB_RsvdSecCnt+FATSz*2+dbr.BPB_RootEntCnt*32/dbr.BPB_BytsPerSec;
    TotClus /= dbr.BPB_SecPerClus;

    FirstPos.FirstDbr=readMbr[0].PreSec;
    FirstPos.FirstFAT[0]=FirstPos.FirstDbr+dbr.BPB_RsvdSecCnt;
    FirstPos.FirstFAT[1]=FirstPos.FirstFAT[0]+FATSz;
    FirstPos.FirstRoot=FirstPos.FirstFAT[1]+FATSz;
    FirstPos.FirstData=FirstPos.FirstRoot+((dbr.BPB_RootEntCnt*32)+(dbr.BPB_BytsPerSec-1))/dbr.BPB_BytsPerSec;
    read1(buf,FirstPos.FirstFAT[0],p);
    if((buf[0]!=dbr.BPB_Media)||(buf[1]!=0xFF)||(buf[2]!=0xFF)||((buf[3]&0x3F)!=0x3F))
        FirstPos.FirstFAT[0]=0;
    read1(buf,FirstPos.FirstFAT[1],p);
    if((buf[0]!=dbr.BPB_Media)||(buf[1]!=0xFF)||(buf[2]!=0xFF)||((buf[3]&0x3F)!=0x3F))
        FirstPos.FirstFAT[1]=0;
    if(FirstPos.FirstFAT[0]==0)
    {
        if(FirstPos.FirstFAT[1]==0)
            return -1;
        FirstPos.FirstFAT[0]=FirstPos.FirstFAT[1];
    }
    return 1;
}

/* 读写FAT表,clus为簇号,value为写入clus的值,type为0时为读,为1时为写; */
/* 为2时释放以Clus为首的簇链;3返回一个空簇并标记EOC;返回0表示错误;     */
/* 4时显示磁盘空间使用情况;5时找出Clus个空簇并放入pClus指向的数组中;    */
/* 6时把pClus指向的簇链写入FAT表中;                                      */
dword RWFAT(dword Clus,word value,byte type,dword *pClus)
{
 word FATSec,FATOff;
 dword ClusNum=0,TotClusNum=Clus;
 double FreeClus=0,size;
 int ChangFlag=0,i,EndFlag=1;
 char *w="KMGT";
 if((type==3)||(type==4)||(type==5))Clus=2;
 if(type==6)Clus=pClus[0];
 while(EndFlag)
 {
  if(Clus>TotClus+1)return 0;
  FATSec=(Clus*2)/dbr.BPB_BytsPerSec;
  FATOff=(Clus*2)%dbr.BPB_BytsPerSec;
  if(FATSecNum!=FATSec)
    {
     if(ChangFlag)
      {
       write1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
       write1(FATBuf,FATSecNum+FirstPos.FirstFAT[1],p);
      }
      FATSecNum=FATSec;
      read1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
    }
  if(type==0)
    return ((word*)FATBuf)[FATOff/2];
  else if(type==1)
    {
     ((word*)FATBuf)[FATOff/2]=value;
     write1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
     write1(FATBuf,FATSecNum+FirstPos.FirstFAT[1],p);
     return 1;
    }
  else if(type==2)
    {
     Clus=((word*)FATBuf)[FATOff/2];
     ((word*)FATBuf)[FATOff/2]=0x0000;
     ChangFlag=1;
     if(Clus>0xFFF7)EndFlag=0;
    }
  else if(type==3)
    {
      if(((word*)FATBuf)[FATOff/2]==0)
        {
         ((word*)FATBuf)[FATOff/2]=0xFFFF;
         write1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
         write1(FATBuf,FATSecNum+FirstPos.FirstFAT[1],p);
         return Clus;
        }
      else Clus++;
    }
  else if(type==4)
    {
      if(((word*)FATBuf)[FATOff/2]==0)FreeClus++;
      Clus++;
      if(Clus>TotClus+1)EndFlag=0;
    }
  else if(type==5)
   {
     if(((word*)FATBuf)[FATOff/2]==0)
       {
        pClus[ClusNum]=Clus;
        ClusNum++;
        if(ClusNum==TotClusNum)return 1;
        Clus++;
       }
     else Clus++;
   }
  else if(type==6)
   {
     if(((word*)FATBuf)[FATOff/2]!=0)return 0;
     ((word*)FATBuf)[FATOff/2]=pClus[ClusNum+1];
     ChangFlag=1;
     ClusNum++;
     Clus=pClus[ClusNum];
     if(Clus>0xFFF7)EndFlag=0;
   }
 }

 if(ChangFlag)
  {
    write1(FATBuf,FATSecNum+FirstPos.FirstFAT[0],p);
    write1(FATBuf,FATSecNum+FirstPos.FirstFAT[1],p);
    if(type==3)return ((word*)FATBuf)[FATOff/2];
  }
  if(type==4)
   {
     size=dbr.BPB_BytsPerSec*dbr.BPB_SecPerClus/1024;
     FreeClus*=size;
     i=0;
     do
      {
       if(FreeClus<1024){printf("free:%lf %c\t",FreeClus,w[i]);break;}
       else {FreeClus/=1024;i++;}
      }while(1);
     FreeClus=TotClus*size;
     i=0;
     do
      {
       if(FreeClus<1024){printf("totle:%lf %c\n",FreeClus,w[i]);break;}
       else {FreeClus/=1024;i++;}
      }while(1);
   }
 return 1;
}

 /* 在簇Clus中查找目录名为DirName的目录所在的簇,并根据OpType的值确定各种  */
 /* 不同的操作类型,0表示dir显示目录操作,显示簇链内的所有目录和文件;     */
 /* 1表示cd操作,2表示查找目录指向的簇号;                                  */
 /* 3表示找出一个空目录entry,其簇号由函数返回,簇内偏移由entry返回;      */
 /* 4表示检查目标簇目录里是否为空,空则返回1,否则返回0;                  */
int search(dword Clus,const char *DirName,byte OpType)
{
 dword FirstSec;
 byte name[255];
 int i,j,m,n=0,k,l,EndFlag=0;
 byte a[3];
 sDir16 Dir16;
 word DirNum=0,FileNum=0;
 strcpy(name,DirName);
 FileInfo.ParrentClus=FileInfo.DetailClus=FileInfo.PreClus=FileInfo.NextClus=Clus;
 do
  {
   FileInfo.FileNum=0;
   if(FileInfo.ParrentClus!=0)
   {
    FirstSec=((FileInfo.DetailClus-2)*dbr.BPB_SecPerClus)+FirstPos.FirstData;
    FileInfo.NextClus=RWFAT(FileInfo.DetailClus,0,0,0);
    if((FileInfo.NextClus==0x0000)||(FileInfo.NextClus==0x0001)||((FileInfo.NextClus>=0xFFF0)&&(FileInfo.NextClus<=0xFFF7)))
      {printf("Error!\n");getch();return -1;}    /* 返回-1值表示出错  */
    l=dbr.BPB_SecPerClus;
   }
    else
    {
     FirstSec=FirstPos.FirstRoot;
     l=dbr.BPB_RootEntCnt*32/dbr.BPB_BytsPerSec;
    }
   for(i=0;i<l;i++)
     {
       read1(buf,FirstSec+i,p);
       for(j=0;j<dbr.BPB_BytsPerSec/32;j++)
         {
          Dir16=*((sDir16*)(buf+j*32));
          if(Dir16.DIR_Name[0]==0x00)
            {
             if(OpType==3)
              {
               FileInfo.offset=i*dbr.BPB_BytsPerSec/32+j;
               return 1;
              }
             goto jmpout;
            }
          else if(Dir16.DIR_Name[0]==0xE5)
            {
             if(OpType==3)
              {
               FileInfo.offset=i*dbr.BPB_BytsPerSec/32+j;
               return 1;
              }
            }
          else if(OpType!=3)
            {
             if(Dir16.DIR_Name[0]==0x05) Dir16.DIR_Name[0]=0xE5;
             if((Dir16.DIR_Attr&0x3F)!=0x0F)
              {
                if((OpType==0)||(OpType==4)) /* dir操作,统计目录信息 */
                 {
                  if(OpType==0)
                  {
                   k=0;
                   for(m=0;m<8;m++)
                    {
                      if((byte)Dir16.DIR_Name[m]==0x20)break;
                      putchar(Dir16.DIR_Name[m]);
                    }
                    k+=m;
                   if((byte)Dir16.DIR_Name[8]!=0x20)putchar('.');
                   for(m=8;m<11;m++)
                     {
                       if((byte)Dir16.DIR_Name[m]==0x20)break;
                       putchar(Dir16.DIR_Name[m]);
                     }
                   k+=m-8;
                   if(k<=6)putchar('\t');
                   putchar('\t');  putchar('\t');
                  }
                  /* 在次添加目录统计信息程序 */
                  if((Dir16.DIR_Attr&0x18)==0x00) /* Found a file. */
                    {
                     FileNum++;
                     if(OpType==0)printf("\t%10lu B",Dir16.DIR_FileSize);
                    }
                  else if((Dir16.DIR_Attr&0x18)==0x10)/* Found a directory. */
                    {
                     DirNum++;
                     if(OpType==0)printf("<dir>");
                    }
                  else if((Dir16.DIR_Attr&0x18)==0x08)
                  /* Found a volume label. */
                    { }
                  if(OpType==0)
                   {
                    putchar('\n');
                    if(++n==23)
                     {
                      printf("Press any key to continue!\n");
                      getch();
                      n=0;
                      }
                   }
                 }
                if(((OpType&0x0F)==2)&&((Dir16.DIR_Attr&0x08)==0x00)) /* 正常查找操作,找到目录项就退出 */
                  {
                    FileInfo.FileNum++;
                    if((OpType&0xF0)==0x30);
                    else if((OpType&0x10)&&((Dir16.DIR_Attr&0x18)!=0x00))continue;
                    else if((OpType&0x20)&&((Dir16.DIR_Attr&0x18)!=0x10))continue;
                    strcpy(name,DirName);
                    if((n=strlen(name))>12)return -1;
                    if(!strcmp(name,".")){k=1;while(k<11){name[k]=0x20;k++;}}
                    else if(!strcmp(name,"..")){k=2;while(k<11){name[k]=0x20;k++;}}
                    else{
                    k=0;
                    while(name[k]!=0){if(name[k]=='.')break;k++;}
                    if(k>8)return -1;
                    if((n-k-1)>3)return -1;
                    if(name[k]==0)while(k<11){name[k]=0x20;k++;}
                    else
                     {
                      a[0]=name[k+1];a[1]=name[k+2];a[2]=name[k+3];
                      while(k<8){name[k]=0x20;k++;}
                      while(k<11){if(a[k-8]==0)break;else name[k]=a[k-8];k++;}
                      while(k<11){name[k]=0x20;k++;}
                     }
                     }
                     for(k=0;k<11;k++)if(name[k]!=Dir16.DIR_Name[k])break;
                     if(k==11)
                      {
                        FileInfo.offset=i*dbr.BPB_BytsPerSec/32+j;
                        FileInfo.Dir_Attr=Dir16.DIR_Attr;
                        FileInfo.LO=Dir16.DIR_FstClusLO;
                        FileInfo.HI=Dir16.DIR_FstClusHI;
                        FileInfo.FileSize=Dir16.DIR_FileSize;
                        EndFlag=1;
                       }

                  }
              }
            }

          }
     }
    jmpout:;
    if(EndFlag||(FileInfo.ParrentClus==0)||((FileInfo.NextClus>=0xFFF8)&&(FileInfo.NextClus<=0xFFFF)))
      break;
    FileInfo.PreClus=FileInfo.DetailClus;
    FileInfo.DetailClus=FileInfo.NextClus;
  }while(1);
  if(OpType==0)
    {
     /* 在此添加显示目录统计信息程序 */
     printf("There are %u files,%u directory in this directory.\n",FileNum,DirNum);
     return 1;
    }
  if(((OpType&0x0F)==2)&&(EndFlag==1)) return 1;
  if(OpType==3)
    {
      if(FileInfo.ParrentClus==0)
        printf("Error!\nMax number directry entry in the root directry!");
      else
        {
         FileInfo.PreClus=FileInfo.DetailClus;
         FileInfo.DetailClus=RWFAT(0,0,3,0);
         RWFAT(FileInfo.PreClus,(word)FileInfo.DetailClus,1,0);
         FirstSec=((FileInfo.DetailClus-2)*dbr.BPB_SecPerClus)+FirstPos.FirstData;
         for(i=0;i<512;i++)buf[i]=0;
         for(i=0;i<dbr.BPB_SecPerClus;i++)write1(buf,FirstSec+i,p);
         FileInfo.offset=0;
         return 1;
        }
    }
  if(OpType==4)
   {
    if((FileNum==0)&&(DirNum<=2))return 1;
    else return 0;
   }
 return -1;
}

 /* 通过递归调用search函数确定path指向的目录所在的簇号, */
 /* OpType为1表示cd操作,2表示正常查找目录               */
dword allocal(const char *path,byte OpType)
{
 char name[255];
 dword clus=CurrentClus;
 char TmpTip[260];
 int i=0,j=0,k,flag=0;

⌨️ 快捷键说明

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