📄 fat.c
字号:
for(i=0;i<ExtTblLen;i++) { for(j=0;j<strlen(ExtTblOEM[i]);j++) (fsd->PD.FAT_pd.ExtTbl)[i][j]=(uint8)toupper(ExtTblOEM[i][j]); for(k=0;k<3-j;k++) (fsd->PD.FAT_pd.ExtTbl)[i][j+k]=0x20; } fsd->PD.FAT_pd.ExtTblLen=ExtTblLen;}*/void Get_FATType(BPB_boot_common_t *BPB_boot_common, uint8* buf){ uint32 FATSz32; uint32 FATSz, TotSec, DataSec, CountofClusters; //get FATSz32 GET_DWORD(buf,FATSz32,36); BPB_boot_common->FATSz32Estim = FATSz32; //for decisions in another routines //according to LINUX FAT driver if( ((BPB_boot_common->FATSz16) == 0) && (FATSz32 != 0) ) { //FAT32 BPB_boot_common->FATType = 0; } else { //FAT16 or 12 if((BPB_boot_common->FATSz16) != 0) FATSz = BPB_boot_common->FATSz16; else FATSz = FATSz32; if((BPB_boot_common->TotSec16) != 0) TotSec = BPB_boot_common->TotSec16; else TotSec = BPB_boot_common->TotSec32; DataSec = TotSec - (BPB_boot_common->RsvdSecCnt+BPB_boot_common->NumFATs*FATSz+Get_RootDirSectors(BPB_boot_common)); CountofClusters = (DataSec>>get_val_log2(BPB_boot_common->SecPerClust)); if(CountofClusters > 4084) //FAT16 BPB_boot_common->FATType = 2; else //FAT12 BPB_boot_common->FATType = 1; } /* //according to Microsoft spec. if(CountofClusters < 4085) //Volume is FAT12 BPB_boot_common->FATType = 1; else if(CountofClusters < 65525) //Volume is FAT16 BPB_boot_common->FATType = 2; else //Volume is FAT32 BPB_boot_common->FATType = 0; */}boolean check_bpb(uint8 *Secbuf, BPB_boot_common_t *BPB_boot_common){ uint16 Signature; /* Check for the 0xAA55 signature at offset 510 of the boot sector */ GET_WORD(Secbuf,Signature,510); if(Signature!=0xAA55) {#ifdef DEBUGGING printf("Boot sector signature 0xAA55 not found\n");#endif return false; } /* Check volume size. */ if( (!BPB_boot_common->TotSec16) && (!BPB_boot_common->TotSec32) ) {#ifdef DEBUGGING printf("Both BPB_TotSec16 and BPB_TotSec32 are zero\n");#endif return false; } /* BPB_BytsPerSec can be 512, 1024, 2048 or 4096 */ switch (BPB_boot_common->BytesPerSec) { case 512: case 1024: case 2048: case 4096: break; default:#ifdef DEBUGGING printf("Invalid BPB_BytsPerSec\n");#endif return false; } /* BPB_SecPerCluster can be 1, 2, 4, 8, 16, 32, 64, 128 */ switch (BPB_boot_common->SecPerClust) { case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128: break; default:#ifdef DEBUGGING printf("Invalid BPB_SecPerClus\n");#endif return false; } /* BPB_Media can be 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF */ if ((BPB_boot_common->Media != 0xF0) && (BPB_boot_common->Media < 0xF8)) {#ifdef DEBUGGING printf("Invalid BPB_Media\n");#endif return false; } /* BPB_RsvdSecCnt can not be 0x0 */ if(!BPB_boot_common->RsvdSecCnt) {#ifdef DEBUGGING printf("Bogus number of reserved sectors\n");#endif return false; } /* BPB_NumFATs can not be 0x0 */ if(!BPB_boot_common->NumFATs) {#ifdef DEBUGGING printf("bogus number of FAT structure\n");#endif return false; } return true;}GRESULT Get_BPB_BS(FS_DESCRIPTOR *fsd, uint8 *buf){ //uint8 buf[512]; //alloc memory for sector of size 512 GRESULT ReturnCode; fsd->PD.FAT_pd.BPB_boot_common.BytesPerSec = 512; //get sector 0 if ((ReturnCode=Get_SectorRel(buf,0,fsd)) != S_OK) { //sector 0 goes bad, critical error, try at sector 6 (back up) if(ReturnCode == E_FORCED_UNPLUG) return ReturnCode; if ((ReturnCode=Get_SectorRel(buf,6,fsd)) != S_OK) {#ifdef DEBUGGING printf("Can't read sector, EOF!\n");#endif return ReturnCode; } } //fill BPB_BS common structure GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_common.jmpBoot0,0); GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_common.jmpBoot1,1); GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_common.jmpBoot2,2); GET_BYTES(buf,fsd->PD.FAT_pd.BPB_boot_common.OEMName,8,3); (fsd->PD.FAT_pd.BPB_boot_common.OEMName)[8] = '\0'; GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_common.BytesPerSec,11); GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_common.SecPerClust,13); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_common.RsvdSecCnt,14); GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_common.NumFATs,16); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_common.RootEntCnt,17); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_common.TotSec16,19); GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_common.Media,21); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_common.FATSz16,22); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_common.SecPerTrk,24); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_common.NumHeads,26); GET_DWORD(buf,fsd->PD.FAT_pd.BPB_boot_common.HiddSec,28); GET_DWORD(buf,fsd->PD.FAT_pd.BPB_boot_common.TotSec32,32); //Is it really FAT filesystem? if(!check_bpb(buf,&(fsd->PD.FAT_pd.BPB_boot_common))) {#ifdef DEBUGGING printf("Can't detect FAT filesystem!\n");#endif return E_FAIL; } //detection of FAT type Get_FATType(&(fsd->PD.FAT_pd.BPB_boot_common),buf); //fill rest of BPB_BS structure, FAT type is known if(fsd->PD.FAT_pd.BPB_boot_common.FATType == 0) { //FAT 32 GET_DWORD(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.FATSz32,36); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.ExtFlags,40); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.FSVer,42); GET_DWORD(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.RootClus,44); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.FSInfo,48); GET_WORD(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.BkBootSec,50); GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.DrvNum,64); GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.BootSig,66); GET_DWORD(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.VolID,67); //GET_BYTES(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.VolLab,11,71); GET_BYTES(buf,fsd->VolumeName,11,71); //(fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.VolLab)[11] = '\0'; fsd->VolumeNameLength=12; GET_BYTES(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.FilSysType,8,82); (fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.FilSysType)[8] = '\0'; } else { //FAT 12, 16 GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.DrvNum,36); GET_BYTE(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.BootSig,38); GET_DWORD(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.VolID,39); //GET_BYTES(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.VolLab,11,43); GET_BYTES(buf,fsd->VolumeName,11,43); //(fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.VolLab)[11] = '\0'; fsd->VolumeNameLength = 12; GET_BYTES(buf,fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.FilSysType,8,54); (fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.FilSysType)[8] = '\0'; }#ifdef DEBUGGING //print info about FAT printf("Jump code [0] : %x\n",fsd->PD.FAT_pd.BPB_boot_common.jmpBoot0); printf("Jump code [1] : %x\n",fsd->PD.FAT_pd.BPB_boot_common.jmpBoot1); printf("Jump code [2] : %x\n",fsd->PD.FAT_pd.BPB_boot_common.jmpBoot2); printf("OEM name : %s\n",fsd->PD.FAT_pd.BPB_boot_common.OEMName); printf("Bytes per sector : %x\n",fsd->PD.FAT_pd.BPB_boot_common.BytesPerSec); printf("Sectors per cluster : %x\n",fsd->PD.FAT_pd.BPB_boot_common.SecPerClust); printf("Number of reserved sectors : %x\n",fsd->PD.FAT_pd.BPB_boot_common.RsvdSecCnt); printf("Number of copies of fat : %x\n",fsd->PD.FAT_pd.BPB_boot_common.NumFATs); printf("Maximum number of root dir entries : %x\n",fsd->PD.FAT_pd.BPB_boot_common.RootEntCnt); printf("Number of sectors in partition < 32MB : %x\n",fsd->PD.FAT_pd.BPB_boot_common.TotSec16); printf("Media descriptor : %x\n",fsd->PD.FAT_pd.BPB_boot_common.Media); printf("Sectors per FAT : %x\n",fsd->PD.FAT_pd.BPB_boot_common.FATSz16); printf("Sectors per track : %x\n",fsd->PD.FAT_pd.BPB_boot_common.SecPerTrk); printf("Number of heads : %x\n",fsd->PD.FAT_pd.BPB_boot_common.NumHeads); printf("Number of hidden sectors : %x\n",fsd->PD.FAT_pd.BPB_boot_common.HiddSec); printf("Number of sectors in partition : %x\n\n",fsd->PD.FAT_pd.BPB_boot_common.TotSec32); switch (fsd->PD.FAT_pd.BPB_boot_common.FATType) { case 0: printf("FAT type detected : FAT 32\n\n"); break; case 1: printf("FAT type detected : FAT 12\n\n"); break; case 2: printf("FAT type detected : FAT 16\n\n"); break; } switch(fsd->PD.FAT_pd.BPB_boot_common.FATType) { case 1: case 2: printf("Int 0x13 drive number : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.DrvNum); printf("Extended boot signature [0x29] : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.BootSig); printf("Volume serial number : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.VolID); printf("Volume label : %s\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.VolLab); printf("FAT Type (info only) : %s\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_12_16.FilSysType); break; case 0: printf("Sectors per FAT : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.FATSz32); printf("Flags (number of active FATs,...) : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.ExtFlags); printf("Revision number of FAT32 volume : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.FSVer); printf("First cluster of the root directory [2]: %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.RootClus); printf("Sector number of FSINFO structure [1] : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.FSInfo); printf("Sector number of a copy of the BR [6] : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.BkBootSec); printf("Int 0x13 drive number : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.DrvNum); printf("Extended boot signature [0x29] : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.BootSig); printf("Volume serial number : %x\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.VolID); printf("Volume label : %s\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.VolLab); printf("FAT Type (info only) : %s\n",fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.FilSysType); break; }#endif return S_OK;}void LongChainCancel(ENTRY_STUFF_STRUCT *EntryStuff){ if(EntryStuff->LongNameFound) { EntryStuff->LongNameFound = false; }}void NameCopy(uint8 *ItemName, uint16 *LongName, uint16 Length){int i; for(i=0;i<Length;i++) { ItemName[i] = ((uint8*)LongName)[2*i]; }}GRESULT ParseEntry(ENTRY_STUFF_STRUCT *EntryStuff){ uint8 LastLongEntryLength, ShortEntryLength; uint16 String[13]; uint8 Ext[3]; uint16 RecordAddressLo; uint32 RecordAddress; uint8 LDIR_Ord,LDIR_attr; t_conv_param p; LDIR_Ord = (EntryStuff->EntryBuf)[0]; LDIR_attr = (EntryStuff->EntryBuf)[11]; if(((LDIR_attr&ATTR_LONG_NAME_MASK)==ATTR_LONG_NAME)&&(LDIR_Ord!=0xE5)) { //found long name subcomponent if((LDIR_Ord&0x40)==0x40) { //last long entry EntryStuff->LongNameFound = true; EntryStuff->N = LDIR_Ord&0x3F; LastLongEntryLength = ParseLongEntryName(EntryStuff->EntryBuf,String); EntryStuff->WholeLongEntryLength = (EntryStuff->N-1)*13+LastLongEntryLength; EntryStuff->CheckSum = (EntryStuff->EntryBuf)[13]; EntryStuff->StatusLongName = true; memcpy(&(EntryStuff->LongName)[(EntryStuff->N-1)*13],String,LastLongEntryLength*sizeof(uint16)); } else { //long entry, not last if(EntryStuff->LongNameFound == false) //found long entry not last, but there was no last long entry before, so scratch it return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND; if(ParseLongEntryName(EntryStuff->EntryBuf,String)!=13) EntryStuff->StatusLongName = false; if(EntryStuff->CheckSum != (EntryStuff->EntryBuf)[13]) EntryStuff->StatusLongName = false; memcpy(&(EntryStuff->LongName)[(EntryStuff->N-1)*13],String,13*sizeof(uint16)); } (EntryStuff->N)--; return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND; } else { //found something else, as long name subcomponent if(((LDIR_attr&ATTR_LONG_NAME_MASK)!=ATTR_LONG_NAME)&&(LDIR_Ord!=0xE5)) { //short entry ShortEntryLength=ParseShortEntryName(EntryStuff->EntryBuf,String,Ext); GET_WORD(EntryStuff->EntryBuf,RecordAddress,20); RecordAddress=RecordAddress<<16; GET_WORD(EntryStuff->EntryBuf,RecordAddressLo,26); RecordAddress=RecordAddress|RecordAddressLo; if((LDIR_attr&(ATTR_DIRECTORY|ATTR_VOLUME_ID)) == ATTR_DIRECTORY) { //found a directory if( !(((ShortEntryLength==1)&&(String[0]==0x2E)) || ((ShortEntryLength==2)&&(String[0]==0x2E)&&(String[1]==0x2E))) ) { //it is really directory, not . or .. entry (EntryStuff->Dir_item_ptr->dir).DirRecordLba = RecordAddress; GET_WORD(EntryStuff->EntryBuf,(EntryStuff->Dir_item_ptr->dir).WrtDate,24); GET_WORD(EntryStuff->EntryBuf,(EntryStuff->Dir_item_ptr->dir).WrtTime,22); EntryStuff->TypeOfEntry = FAT_DIR_FOUND; if(EntryStuff->LongNameFound) { //directory has long name EntryStuff->LongNameFound = false; if((EntryStuff->CheckSum==ChkSum(EntryStuff->EntryBuf))&&(EntryStuff->StatusLongName)) { //long name is OK //NameCopy((EntryStuff->Dir_item_ptr->dir).Name,EntryStuff->LongName,(EntryStuff->WholeLongEntryLength)*sizeof(uint16)); //WideFileNameToUTF8((uint8*)(EntryStuff->LongName),0,(EntryStuff->Dir_item_ptr->dir).Name,EntryStuff->WholeLongEntryLength,0,0); p.be = 0; p.trunc = 0; p.limit = 0; (EntryStuff->Dir_item_ptr->dir).NameLength = \ WideStringToUTF8((uint8*)(EntryStuff->LongName),(EntryStuff->Dir_item_ptr->dir).Name,EntryStuff->WholeLongEntryLength,&p); if((EntryStuff->Dir_item_ptr->dir).NameLength < 0) return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND; } else { //long name is corrupted
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -