📄 fat.c
字号:
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 + -