📄 fat.c
字号:
{ //start parsing from beginning of record scans->DirEntryAddress.Cluster = scans->DirRecordLba; scans->DirEntryAddress.Byte = 0; if((scans->IsRoot)==true) { //we are in root dir if(EntryStuff.FAT_private_struct_ptr->BPB_boot_common.FATType) { //FAT12 or 16 if((ReturnCode=LookForDirFileEntrySectorBasedNext(EntryStuff.FAT_private_struct_ptr,&EntryStuff)) == S_SEARCHED_DIR_FILE_ENTRY_FOUND) { //dir or file found if(EntryStuff.TypeOfEntry == FAT_DIR_FOUND) return S_DIR_FOUND; else return S_FILE_FOUND; } else //nothing found return ReturnCode; } else { //root dir, FAT32 if((ReturnCode=LookForDirFileEntryClusterBasedNext(EntryStuff.FAT_private_struct_ptr,&EntryStuff)) == S_SEARCHED_DIR_FILE_ENTRY_FOUND) { //dir or file found if(EntryStuff.TypeOfEntry == FAT_DIR_FOUND) return S_DIR_FOUND; else return S_FILE_FOUND; } else //nothing found return ReturnCode; } } else { //we are !not! in root dir if((ReturnCode=LookForDirFileEntryClusterBasedNext(EntryStuff.FAT_private_struct_ptr,&EntryStuff)) == S_SEARCHED_DIR_FILE_ENTRY_FOUND) { //dir or file found if(EntryStuff.TypeOfEntry == FAT_DIR_FOUND) return S_DIR_FOUND; else return S_FILE_FOUND; } else //nothing found return ReturnCode; } } else { //start parsing from last position if((scans->IsRoot)==true) { //we are in root dir if(EntryStuff.FAT_private_struct_ptr->BPB_boot_common.FATType) { //FAT12 or 16 if((ReturnCode=LookForDirFileEntrySectorBasedNext(EntryStuff.FAT_private_struct_ptr,&EntryStuff)) == S_SEARCHED_DIR_FILE_ENTRY_FOUND) { //dir or file found if(EntryStuff.TypeOfEntry == FAT_DIR_FOUND) return S_DIR_FOUND; else return S_FILE_FOUND; } else //nothing found return ReturnCode; } else { //root dir, FAT32 if((ReturnCode=LookForDirFileEntryClusterBasedNext(EntryStuff.FAT_private_struct_ptr,&EntryStuff)) == S_SEARCHED_DIR_FILE_ENTRY_FOUND) { //dir or file found if(EntryStuff.TypeOfEntry == FAT_DIR_FOUND) return S_DIR_FOUND; else return S_FILE_FOUND; } else //nothing found return ReturnCode; } } else { //we are !not! in root dir if((ReturnCode=LookForDirFileEntryClusterBasedNext(EntryStuff.FAT_private_struct_ptr,&EntryStuff)) == S_SEARCHED_DIR_FILE_ENTRY_FOUND) { //dir or file found if(EntryStuff.TypeOfEntry == FAT_DIR_FOUND) return S_DIR_FOUND; else return S_FILE_FOUND; } else //nothing found return ReturnCode; } } } else { //parse file content if(scans->DirRecordOffset == 0) { //start parsing from beginning of file scans->Cluster = scans->DirRecordLba; item->file.ExtentLba = scans->Cluster; //start of extent area ReturnCode = FAT_GetExtent(scans,&LengthOfExtent,buf); item->file.FileSize = LengthOfExtent; //length of extent area scans->DirRecordOffset += LengthOfExtent; if(scans->DirRecordOffset > scans->FileSize) { //not all clusters in cluster chain are filled with data (last one shouldn't be) item->file.FileSize = scans->FileSize; //length of extent area } if(ReturnCode != S_OK) { //error, for sure not possible to continue in parsing scans->DirRecordOffset = 1; //nobody uses this anymore, only to ensure next pass will go through else SetEOF(&(scans->fs_descriptor->PD.FAT_pd.BPB_boot_common),&(scans->Cluster)); } return S_FILE_UPDATE_ITEM; } else { //start parsing from last position if(CheckIfEOF(&(scans->fs_descriptor->PD.FAT_pd.BPB_boot_common),scans->Cluster)) { //EOC return E_EOF; } item->file.ExtentLba = scans->Cluster; //start of extent area PrevDirRecordOffset = scans->DirRecordOffset; ReturnCode=FAT_GetExtent(scans,&LengthOfExtent,buf); item->file.FileSize = LengthOfExtent; //length of extent area scans->DirRecordOffset += LengthOfExtent; if(scans->DirRecordOffset > scans->FileSize) { //not all clusters in cluster chain are filled with data (last one shouldn't be) item->file.FileSize = scans->FileSize-PrevDirRecordOffset; //length of extent area } if(ReturnCode != S_OK) { //error, for sure not possible to continue in parsing SetEOF(&(scans->fs_descriptor->PD.FAT_pd.BPB_boot_common),&(scans->Cluster)); } return S_FILE_ADD_EXTEND; } }}//CODE for detecting partitionsGRESULT Get_ExtPart(DeviceInfoStruct *dis, FS_DESCRIPTOR *fsd, uint32 ExtPartAdd, uint8 *Secbuf){ //uint8 Secbuf[512]; uint32 LogDriveAdd = ExtPartAdd; uint16 Signature; uint32 PartInLogDriveOffset; GRESULT ReturnCode; for( ; ; ) { //via logical drives //read MBR of logical drive if((ReturnCode=Get_SectorAbs(Secbuf,LogDriveAdd,fsd)) != S_OK) return ReturnCode; //is log. drive valid? GET_WORD(Secbuf,Signature,510); if(Signature!=0xAA55) {#ifdef DEBUGGING printf("Logical drive not valid!\n");#endif return S_OK; } //find this logical drive's partition switch(Secbuf[0x1C2]) { //System ID case 0x00: //empty break; case 0x01: //FAT12#ifdef DEBUGGING printf("FAT 12 partition detected in MBR\n");#endif GET_DWORD(Secbuf,PartInLogDriveOffset,0x1C6); (dis->PartitionLBA)[dis->NumPartitions++] = LogDriveAdd + PartInLogDriveOffset; break; case 0x04: //FAT16 <= 32MB#ifdef DEBUGGING printf("FAT 16 <= 32 MB partition detected in MBR\n");#endif GET_DWORD(Secbuf,PartInLogDriveOffset,0x1C6); (dis->PartitionLBA)[dis->NumPartitions++] = LogDriveAdd + PartInLogDriveOffset; break; case 0x06: //FAT16 > 32MB#ifdef DEBUGGING printf("FAT 16 > 32MB partition detected in MBR\n");#endif GET_DWORD(Secbuf,PartInLogDriveOffset,0x1C6); (dis->PartitionLBA)[dis->NumPartitions++] = LogDriveAdd + PartInLogDriveOffset; break; case 0x0B: //FAT32 <= 2GB#ifdef DEBUGGING printf("FAT 32 <= 2GB partition detected in MBR\n");#endif GET_DWORD(Secbuf,PartInLogDriveOffset,0x1C6); (dis->PartitionLBA)[dis->NumPartitions++] = LogDriveAdd + PartInLogDriveOffset; break; case 0x0C: //FAT32 (LBA)#ifdef DEBUGGING printf("FAT 32 LBA partition detected in MBR\n");#endif GET_DWORD(Secbuf,PartInLogDriveOffset,0x1C6); (dis->PartitionLBA)[dis->NumPartitions++] = LogDriveAdd + PartInLogDriveOffset; break; case 0x0E: //FAT16 (LBA)#ifdef DEBUGGING printf("FAT 16 LBA partition detected in MBR\n");#endif GET_DWORD(Secbuf,PartInLogDriveOffset,0x1C6); (dis->PartitionLBA)[dis->NumPartitions++] = LogDriveAdd + PartInLogDriveOffset; break; default:#ifdef DEBUGGING printf("Unrecognized partition!\n");#endif break; } //switch //find next logical drive switch(Secbuf[0x1D2]) { //System ID case 0x00: //empty return S_OK; case 0x05: //extended partition#ifdef DEBUGGING printf("Next logical drive detected in MBR\n");#endif GET_DWORD(Secbuf,PartInLogDriveOffset,0x1D6); LogDriveAdd = ExtPartAdd + PartInLogDriveOffset; break; case 0x0F: //extended partition (LBA)#ifdef DEBUGGING printf("Next drive detected in MBR\n");#endif GET_DWORD(Secbuf,PartInLogDriveOffset,0x1D6); LogDriveAdd = ExtPartAdd + PartInLogDriveOffset; break; } //switch } //for, via logical drives}GRESULT FAT_GetPartitions(DUID cdid, uint8 *Secbuf, FS_DESCRIPTOR *fsd){ //uint8 Secbuf[1024]; //1024B array required, if device block size = 512B GRESULT ReturnCode; uint16 Signature; uint32 ExtPartAdd; int i; DeviceInfoStruct *dis = SYS_DeviceInfoStruct(cdid); fsd->PD.FAT_pd.FirstPassGetSectorAbs_FAT = true; dis->NumPartitions = 0; fsd->LargeBlockSize = dis->LargeBlockSize;#if (0 != HAVE_SDC) fsd->did = cdid;#endif /* HAVE_SDC */ //check if device's block size is less than or equal to C_USB_MAX_DEV_BLOCK_SIZE if(dis->LargeBlockSize > C_USB_MAX_DEV_BLOCK_SIZE) { return E_FAIL; } //read MBR if((ReturnCode=Get_SectorAbs(Secbuf,0,fsd)) != S_OK) return ReturnCode; //check if HDD (with MBR) or SUPERFLOPPY (without MBR) format present GET_WORD(Secbuf,Signature,510); if(Signature != 0xAA55) { //no HDD, no SUPERFLOPPY format#ifdef DEBUGGING printf("Unrecognized removable media\n");#endif return E_FAIL; } /* According to LINUX * Now that the 55aa signature is present, this is probably * either the boot sector of a FAT filesystem or a DOS-type * partition table. Reject this in case the boot indicator * is not 0 or 0x80. */ if( ((Secbuf[0x1BE]!=0)&&(Secbuf[0x1BE]!=0x80)) || ((Secbuf[0x1CE]!=0)&&(Secbuf[0x1CE]!=0x80)) || ((Secbuf[0x1DE]!=0)&&(Secbuf[0x1DE]!=0x80)) || ((Secbuf[0x1EE]!=0)&&(Secbuf[0x1EE]!=0x80)) ) { //no MBR, SUPERFLOPPY format#ifdef DEBUGGING printf("Superfloppy detected\n");#endif (dis->PartitionLBA)[0] = 0; dis->NumPartitions = 1; return S_OK; } //HDD format, may be SUPERFLOPPY format for(i=0x1BE;i<0x1FE;i=i+16) { //via partition table entries //parse entry switch(Secbuf[i+4]) { //System ID case 0x00: //empty break; case 0x01: //FAT12#ifdef DEBUGGING printf("FAT 12 partition detected in MBR\n");#endif GET_DWORD(Secbuf,(dis->PartitionLBA)[dis->NumPartitions++],i+8); break; case 0x04: //FAT16 <= 32MB#ifdef DEBUGGING printf("FAT 16 <= 32 MB partition detected in MBR\n");#endif GET_DWORD(Secbuf,(dis->PartitionLBA)[dis->NumPartitions++],i+8); break; case 0x05: //extended partition#ifdef DEBUGGING printf("Extended partition detected in MBR\n");#endif GET_DWORD(Secbuf,ExtPartAdd,i+8); Get_ExtPart(dis,fsd,ExtPartAdd,Secbuf+512); break; case 0x06: //FAT16 > 32MB#ifdef DEBUGGING printf("FAT 16 > 32MB partition detected in MBR\n");#endif GET_DWORD(Secbuf,(dis->PartitionLBA)[dis->NumPartitions++],i+8); break; case 0x0B: //FAT32 <= 2GB#ifdef DEBUGGING printf("FAT 32 <= 2GB partition detected in MBR\n");#endif GET_DWORD(Secbuf,(dis->PartitionLBA)[dis->NumPartitions++],i+8); break; case 0x0C: //FAT32 (LBA)#ifdef DEBUGGING printf("FAT 32 LBA partition detected in MBR\n");#endif GET_DWORD(Secbuf,(dis->PartitionLBA)[dis->NumPartitions++],i+8); break; case 0x0E: //FAT16 (LBA)#ifdef DEBUGGING printf("FAT 16 LBA partition detected in MBR\n");#endif GET_DWORD(Secbuf,(dis->PartitionLBA)[dis->NumPartitions++],i+8); break; case 0x0F: //extended partition (LBA)#ifdef DEBUGGING printf("Extended LBA partition detected in MBR\n");#endif GET_DWORD(Secbuf,ExtPartAdd,i+8); Get_ExtPart(dis,fsd,ExtPartAdd,Secbuf+512); break; default:#ifdef DEBUGGING printf("Unrecognized partition!\n");#endif break; } //switch } //for, via partitions if(!dis->NumPartitions) { //we supposed HDD format, but no partition found, so suppose SUPERFLOPPY format#ifdef DEBUGGING printf("Superfloppy detected\n");#endif (dis->PartitionLBA)[0] = 0; dis->NumPartitions = 1; } return S_OK;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -