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

📄 fat.c

📁 使用IAR430编译源文件
💻 C
📖 第 1 页 / 共 2 页
字号:
     if(GetNextClusterNumber(cluster)==0) break;
     cluster++;
    }

   if(cluster>=currentcluster) return DISK_FULL; // no free cluster found
  }
  
 if(cluster>=maxcluster) return DISK_FULL;
    
 return cluster;
}
#endif //DOS_WRITE

#ifdef DOS_WRITE
//############################################################
// write a cluster number into fat cluster chain
#ifdef USE_FAT32
 unsigned char WriteClusterNumber(unsigned long cluster, unsigned long number)
#else
 unsigned char WriteClusterNumber(unsigned int cluster, unsigned int number)
#endif
//############################################################
{
#ifdef USE_FAT12
 unsigned int tmp, secoffset;
 unsigned long fatoffset;
 unsigned char lo,hi;
#endif

 unsigned long sector;
 unsigned char *p;
 
 if(cluster<maxcluster) //we need to check this ;-)
  {

#ifdef USE_FAT12
   if(FATtype==FAT12)
    {
     //FAT12 has 1.5 Bytes per FAT entry
     fatoffset= (cluster * 3) >>1 ; //multiply by 1.5 (rounds down)
     secoffset = fatoffset % BYTE_PER_SEC; //we need this for later
     fatoffset= fatoffset / BYTE_PER_SEC; //sector offset from FATFirstSector
     sector=FATFirstSector + fatoffset;

     tmp=(unsigned int)number;
     if(cluster & 0x01) tmp<<=4; //shift to right position
     lo=(unsigned char)tmp;
     hi=(unsigned char)(tmp>>8);
     
#ifdef USE_FATBUFFER
     UpdateFATBuffer(sector); //read FAT sector
#else //#ifdef USE_FATBUFFER
     ReadSector(sector,dirbuf); //read FAT sector
#endif //#ifdef USE_FATBUFFER
     if(secoffset == (BYTE_PER_SEC-1)) //if this is the case, cluster number is
                                   //on a sector boundary. read the next sector too
      {
#ifdef USE_FATBUFFER
       p=&fatbuf[BYTE_PER_SEC-1]; //keep first part of cluster number
#else //#ifdef USE_FATBUFFER
       p=&dirbuf[BYTE_PER_SEC-1]; //keep first part of cluster number
#endif //#ifdef USE_FATBUFFER

       if(cluster & 0x01)
        {
         *p&=0x0F;
         *p|=lo;
        }
       else *p=lo;
        
#ifdef USE_FATBUFFER
       FATStatus=1; // we have made an entry, so write before next FAT sector read
       UpdateFATBuffer(sector+1); //read FAT sector
       p=&fatbuf[0]; //second part of cluster number
#else //#ifdef USE_FATBUFFER
       WriteSector(sector,dirbuf);
       ReadSector(sector+1,dirbuf ); //read next FAT sector
       p=&dirbuf[0]; //second part of cluster number
#endif //#ifdef USE_FATBUFFER

       if(cluster & 0x01) *p=hi;
       else
        {
         *p&=0xF0;
         *p|=hi;
        }

#ifdef USE_FATBUFFER
       FATStatus=1; // we have made an entry, so write before next FAT sector read
#else //#ifdef USE_FATBUFFER
       WriteSector(sector+1,dirbuf);
#endif //#ifdef USE_FATBUFFER
      }
     else
      {
#ifdef USE_FATBUFFER
       p=&fatbuf[secoffset];
#else //#ifdef USE_FATBUFFER
       p=&dirbuf[secoffset];
#endif //#ifdef USE_FATBUFFER

       if(cluster & 0x01)
        {
         *p&=0x0F;
         *p++|=lo;
         *p=hi;
        } 
       else
        {
         *p++=lo;
         *p&=0xF0;
         *p|=hi;
        } 

#ifdef USE_FATBUFFER
       FATStatus=1; // we have made an entry, so write before next FAT sector read
#else //#ifdef USE_FATBUFFER
       WriteSector(sector,dirbuf);
#endif //#ifdef USE_FATBUFFER
      } 

    }//if(FATtype==FAT12)
#endif

#ifdef USE_FAT16
   if(FATtype==FAT16)
    {
     //two bytes per FAT entry
     sector=FATFirstSector + (cluster * 2) / BYTE_PER_SEC;

#ifdef USE_FATBUFFER
     UpdateFATBuffer(sector); //read FAT sector
     p=&fatbuf[(cluster * 2) % BYTE_PER_SEC];
#else //#ifdef USE_FATBUFFER
     ReadSector(sector, dirbuf);
     p=&dirbuf[(cluster * 2) % BYTE_PER_SEC];
#endif //#ifdef USE_FATBUFFER

     *p++=(unsigned char)(number);
     *p  =(unsigned char)(number >> 8);

#ifdef USE_FATBUFFER
     FATStatus=1; // we have made an entry, so write before next FAT sector read
#else //#ifdef USE_FATBUFFER
     WriteSector(sector, dirbuf);
#endif //#ifdef USE_FATBUFFER

    }// if(FATtype==FAT16)
#endif //#ifdef USE_FAT16

#ifdef USE_FAT32
   if(FATtype==FAT32)
    {
     //four bytes per FAT entry
     sector=FATFirstSector + (cluster * 4) / BYTE_PER_SEC;

#ifdef USE_FATBUFFER
     UpdateFATBuffer(sector); //read FAT sector
     p=&fatbuf[(cluster * 4) % BYTE_PER_SEC];
#else //#ifdef USE_FATBUFFER
     ReadSector(sector, dirbuf);
     p=&dirbuf[(cluster * 4) % BYTE_PER_SEC];
#endif //#ifdef USE_FATBUFFER

     number&=0x0FFFFFFF;
     
     *p++=(unsigned char)( number);
     *p++=(unsigned char)(number >> 8);
     *p++=(unsigned char)(number >> 16);
     *p  =(unsigned char)(number >> 24);

#ifdef USE_FATBUFFER
     FATStatus=1; // we have made an entry, so write before next FAT sector read
#else //#ifdef USE_FATBUFFER
     WriteSector(sector, dirbuf);
#endif //#ifdef USE_FATBUFFER

    }// if(FATtype==FAT32) 
#endif //#ifdef USE_FAT32
  } // if(cluster<maxcluster) //we need to check this ;-)

 return 0;
}
#endif //DOS_WRITE

//###########################################################
unsigned char GetDriveInformation(void)
//###########################################################
{
 unsigned char by;
 unsigned long DataSec,TotSec;
 unsigned long bootSecOffset;
 unsigned long FATSz; // FATSize

#ifdef USE_FAT32
  unsigned long CountofClusters;
#else
  unsigned long CountofClusters;
#endif

 unsigned int  RootEntrys;

 struct MBR *mbr;
 struct BootSec *boot;
  
 by=IdentifyMedia(); //LaufwerksInformationen holen
 if(by==0)
  {
   by=ReadSector(0,dirbuf); //Lese den MBR. Erster Sektor auf der Platte
                       //enth鋖t max. 4 Partitionstabellen mit jeweils 16Bytes
                       //Die erste f鋘gt bei 0x01BE an, und nur die nehme ich !

   mbr=(struct MBR *)dirbuf;

   bootSecOffset=mbr->part1.bootoffset; //Nur den brauche ich

   by=ReadSector(bootSecOffset,dirbuf);      //read bootsector
   boot=(struct BootSec *)dirbuf;
   
   secPerCluster=boot->BPB_SecPerClus; //Sectors per Cluster
   RootEntrys=boot->BPB_RootEntCnt;    //32 Byte Root Directory Entrys

//Number of sectors for FAT
   if(boot->BPB_FATSz16 != 0) FATSz = boot->BPB_FATSz16;
   else FATSz = boot->eb.rm32.BPB_FATSz32; //F黵 FAT32

   RootDirSectors = ((RootEntrys * 32) + (BYTE_PER_SEC - 1)) / BYTE_PER_SEC;
   
   FATFirstSector= bootSecOffset + boot->BPB_RsvdSecCnt;
   FirstRootSector = FATFirstSector + (boot->BPB_NumFATs * FATSz);
   FirstDataSector = FirstRootSector + RootDirSectors;

   if(boot->BPB_TotSec16 != 0) TotSec = boot->BPB_TotSec16;
   else TotSec = boot->BPB_TotSec32;

//Number of data sectors
   DataSec = TotSec - (boot->BPB_RsvdSecCnt + (boot->BPB_NumFATs * FATSz) + RootDirSectors);

//Number of valid clusters
   CountofClusters = DataSec / secPerCluster;
   maxcluster=CountofClusters+2;

//Note also that the CountofClusters value is exactly that: the count of data clusters
//starting at cluster 2. The maximum valid cluster number for the volume is
//CountofClusters + 1, and the "count of clusters including the two reserved clusters"
// is CountofClusters + 2.

//Das ist laut MS der einzige Weg FAT12,16,32 zu erkennen.
//Der File System String im Bootsektor wird NICHT ausgewertet
   FirstDirCluster=0; // for FAT12 and FAT16
   if(CountofClusters < 4085)
    {
     FATtype=FAT12;
     endofclusterchain=EOC12;
    }
   else
    {
     if(CountofClusters < 65525)
       {
        FATtype=FAT16;
        endofclusterchain=EOC16;
       }
     else
       {
#ifdef USE_FAT32
        FATtype=FAT32;
        endofclusterchain=EOC32;
        FAT32RootCluster=boot->eb.rm32.BPB_RootClus;
        FirstDirCluster=FAT32RootCluster;
        FirstRootSector=GetFirstSectorOfCluster(FAT32RootCluster);
#endif //#ifdef USE_FAT32
       }
    }

  }
 else
  {
   return F_ERROR; // CF gives no answer
  } 

 FileFirstCluster=0;
 FileSize=0;
 FileFlag=0;

#ifdef USE_FATBUFFER
 FATCurrentSector=FATFirstSector;
 ReadSector(FATCurrentSector,fatbuf); //read first FAT sector

 #ifdef DOS_WRITE
  FATStatus=0; // nothing to write til here
 #endif

#endif

 return F_OK;
}

//-----------------------取指定簇号----------------------------------------//

 unsigned char GoToNoCluster(unsigned long cluster_NUM)

//-----------------------zhangbao 06.05.23 创建------------------------------//
 {
   //unsigned long cluster;
   FileCurrentCluster = FileFirstCluster;
   for(; cluster_NUM>0; cluster_NUM--)
   {
     FileCurrentCluster = GetNextClusterNumber(FileCurrentCluster);
   }
    
    
     File1stClusterSector = GetFirstSectorOfCluster(FileCurrentCluster);
     FileCurrentSector = File1stClusterSector;
     ReadSector(FileCurrentSector,iob); //read first sector of file
     
     
     return F_OK;
 }

⌨️ 快捷键说明

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