📄 fat.c
字号:
CFReadSector(FirstFatSector + fatoffset,inbuff); //read FAT sector
if(secoffset == (BYTE_PER_SEC-1)) //if this is the case, cluster number is
//on a sector boundary. read the next sector too
{
tmp=(unsigned int)inbuff[BYTE_PER_SEC-1]; //keep first part of cluster number
CFReadSector(FirstFatSector + fatoffset +1,inbuff ); //read next FAT sector
tmp+=(unsigned int)inbuff[0] << 8; //second part of cluster number
}
else
{
cv=(union Convert *)&inbuff[secoffset];
tmp=cv->ui;
}
if(cluster & 0x01) tmp>>=4; //shift to right position
else tmp&=0xFFF; //delete high nibble
return (tmp);
}//if(FATtype==FAT12)
if(FATtype==FAT16)
{
//two bytes per FAT entry
CFReadSector(FirstFatSector + (cluster * 2) / BYTE_PER_SEC, inbuff);
cv=(union Convert *)&inbuff[(cluster * 2) % BYTE_PER_SEC];
return(cv->ui);
}//if(FATtype==FAT16)
if(FATtype==FAT32)
{
//four bytes per FAT entry
CFReadSector(FirstFatSector + (cluster * 4) / BYTE_PER_SEC, inbuff);
cv=(union Convert *)&inbuff[(cluster * 4) % BYTE_PER_SEC];
return( cv->ul & 0x0FFFFFFF );
}//if(FATtype==FAT32)
}
// return 0; //this means free cluster. don't do it
return DISK_FULL; //return impossible cluster number
}
//###########################################################
//first datacluster is cluster 2 !
unsigned long GetFirstSectorOfCluster(unsigned long n)
//###########################################################
{
return (((n - 2) * secPerCluster) + FirstDataSector);
}
//###########################################################
unsigned char GetDriveInformation(void)
//###########################################################
{
unsigned char by,i;
unsigned long DataSec,TotSec;
unsigned long bootSecOffset;
struct MBR *mbr;
struct BootSec *boot;
by=CFIdentify(); //LaufwerksInformationen holen
if(by==0)
{
by=CFReadSector(0,inbuff); //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 *)inbuff;
bootSecOffset=mbr->part1.bootoffset; //Nur den brauche ich
/*
#ifdef F_DEBUG
printf("\nPartitiontable's\n");
for(i=0; i<16; i++) ser_puthex(inbuff[PART1_TABLE_OFFSET+i]);
printf("\n");
for(i=0; i<16; i++) ser_puthex(inbuff[PART1_TABLE_OFFSET+i+16]);
printf("\n");
for(i=0; i<16; i++) ser_puthex(inbuff[PART1_TABLE_OFFSET+i+32]);
printf("\n");
for(i=0; i<16; i++) ser_puthex(inbuff[PART1_TABLE_OFFSET+i+48]);
printf("\n");
#endif
*/
#ifdef F_DEBUG
printf("Statusbyte first Partition: ");
if(mbr->part1.status==0) //Status der Partition 0x00=inactive, 0x80=Boot
{
printf("0x00=No Bootpartition\n");
}
if(mbr->part1.status==0x80)
{
printf("0x80=Bootpartition\n");
}
printf("Partition Type: ");
switch(mbr->part1.type)
{
case 0 : printf("Not used\n"); break;
case 1 : printf("DOS 12-bit FAT\n"); break;
case 4 : printf("DOS 16-bit <32M\n"); break;
case 5 : printf("Extended\n"); break;
case 6 : printf("DOS 16-bit >=32M\n"); break;
case 0xb : printf("Win95 FAT32\n"); break;
case 0xc : printf("Win95 FAT32 (LBA)\n"); break;
case 0xd : printf("Win95 FAT16\n"); break;
case 0xe : printf("Win95 FAT16 (LBA)\n"); break;
case 0xf : printf("Win95 Extended\n"); break;
default : printf("Unknown\n"); break;
}
printf("Bootsector: %lu\n",bootSecOffset);
#endif
by=CFReadSector(bootSecOffset,inbuff); //read bootsector
boot=(struct BootSec *)inbuff;
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
#ifdef F_DEBUG
printf("Sectors per Cluster: %u\n",secPerCluster);
printf("Reserved Sectors: %u\n",boot->BPB_RsvdSecCnt);
printf("Number of FAT's: %u\n",boot->BPB_NumFATs);
printf("Sectors per FAT: %lu\n",FATSz);
printf("Total Sectors (16Bit): %u (32Bit): %lu\n",boot->BPB_TotSec16,boot->BPB_TotSec32);
printf("RootDir Entry's: %u\n",RootEntrys);
#endif
RootDirSectors = ((RootEntrys * 32) + (BYTE_PER_SEC - 1)) / BYTE_PER_SEC;
FirstFatSector= bootSecOffset + boot->BPB_RsvdSecCnt;
FirstRootSector = FirstFatSector + (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);
// DataSec = TotSec - (BPB_ResvdSecCnt + (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
if(CountofClusters < 4085)
{ FATtype=FAT12; endofclusterchain=EOC12; }
else
{
if(CountofClusters < 65525)
{ FATtype=FAT16; endofclusterchain=EOC16; }
else
{
FATtype=FAT32;
endofclusterchain=EOC32;
FAT32RootCluster=boot->eb.rm32.BPB_RootClus;
CurrentDirCluster=FAT32RootCluster;
FirstRootSector=GetFirstSectorOfCluster(FAT32RootCluster);
}
}
#ifdef F_DEBUG
printf("First RootDirSector: %lu\n",FirstRootSector);
printf("First DataSector: %lu\n",FirstDataSector);
printf("Data Sectors of Partition: %lu\n",DataSec);
printf("Data Clusters of Partition: %lu\n",CountofClusters);
printf("First FAT Sector: %lu\n",FirstFatSector);
printf("Type of FAT: FAT%u\n",FATtype);
printf("Bootsector OEM-NAME: ");
for(i=0; i<8; i++) putchar(boot->BS_OEMName[i]); //Bootsector OEM-NAME
printf("\nVolume Label: ");
for(i=0; i<11; i++)
{
if(FATtype!=FAT32) putchar(boot->eb.rm.BS_VolLab[i]); //Volume Label
else putchar(boot->eb.rm32.BS_VolLab[i]);
}
printf("\nFile System String: ");
for(i=0; i<8; i++)
{
if(FATtype!=FAT32) putchar(boot->eb.rm.BS_FilSysType[i]);
else putchar(boot->eb.rm32.BS_FilSysType[i]);
}
printf("\n");
#endif
}
else
{
return F_ERROR; // CF gives no answer
}
#ifdef F_DEBUG
ser_putc(EOT); //End of Transmission
#endif
return F_OK;
}
#undef F_DEBUG
/*
char* ppartid(int partid)
{
char* p;
switch (partid) {
case 0 : p = "Empty"; break;
case 1 : p = "DOS 12-bit FAT"; break;
case 2 : p = "XENIX root"; break;
case 3 : p = "XENIX usr"; break;
case 4 : p = "DOS 16-bit <32M"; break;
case 5 : p = "Extended"; break;
case 6 : p = "DOS 16-bit >=32M"; break;
case 7 : p = "OS/2 HPFS"; break;
case 8 : p = "AIX"; break;
case 9 : p = "AIX bootable"; break;
case 0xa : p = "OS/2 Boot Manag"; break;
case 0xb : p = "Win95 FAT32"; break;
case 0xc : p = "Win95 FAT32 (LBA)"; break;
case 0xd : p = "Win95 FAT16"; break;
case 0xe : p = "Win95 FAT16 (LBA)"; break;
case 0xf : p = "Win95 Extended"; break;
case 0x17 : p = "NTFS"; break;
case 0x40 : p = "Venix 80286"; break;
case 0x51 : p = "Novell?"; break;
case 0x52 : p = "Microport"; break;
case 0x63 : p = "GNU HURD"; break;
case 0x64 :
case 0x65 : p = "Novell Netware"; break;
case 0x75 : p = "PC/IX"; break;
case 0x80 : p = "Old MINIX"; break;
case 0x81 : p = "Linux/MINIX"; break;
case 0x82 : p = "Linux swap"; break;
case 0x83 : p = "Linux native"; break;
case 0x85 : p = "Linux Extended"; break;
case 0x93 : p = "Amoeba"; break;
case 0x94 : p = "Amoeba BBT"; break;
case 0xa5 : p = "BSD/386"; break;
case 0xa6 : p = "OpenBSD"; break;
case 0xa7 : p = "NEXTSTEP"; break;
case 0xb7 : p = "BSDI fs"; break;
case 0xb8 : p = "BSDI swap"; break;
case 0xc7 : p = "Syrinx"; break;
case 0xdb : p = "CP/M"; break;
case 0xe1 : p = "DOS access"; break;
case 0xe3 : p = "DOS R/O"; break;
case 0xf2 : p = "DOS secondary"; break;
case 0xff : p = "BBT"; break;
default : p = "UNKOWN";
}
return p;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -