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

📄 fat.c

📁 本程序为ST公司开发的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                   NameCopy((EntryStuff->Dir_item_ptr->dir).Name,String,ShortEntryLength*sizeof(uint16));                   (EntryStuff->Dir_item_ptr->dir).NameLength = ShortEntryLength;                 }               }               else               { //no long name for directory                 NameCopy((EntryStuff->Dir_item_ptr->dir).Name,String,ShortEntryLength*sizeof(uint16));                 (EntryStuff->Dir_item_ptr->dir).NameLength = ShortEntryLength;               }               return S_SEARCHED_DIR_FILE_ENTRY_FOUND;           }           else           { //it is . or .. entry               if((ShortEntryLength==2)&&(String[0]==0x2E)&&(String[1]==0x2E))               { // it is .. entry, there is info about parent directory cluster                 /*                 GET_WORD(EntryStuff->EntryBuf,ParentRecordAddress,20);                 ParentRecordAddress=ParentRecordAddress<<16;                 GET_WORD(EntryStuff->EntryBuf,ParentRecordAddressLo,26);                 ParentRecordAddress=ParentRecordAddress|ParentRecordAddressLo;                 (EntryStuff->FAT_private_struct_ptr)->ParentDirFirstClusNum = ParentRecordAddress;                 */               }               return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND;           }         }         else         { //found a file or invalid directory entry           if((LDIR_attr&(ATTR_DIRECTORY|ATTR_VOLUME_ID)) == 0x00)           { //found a file               //look for extension in extension table               if(FindExtInTbl(EntryStuff->ExtTbl,Ext,EntryStuff->ExtTblLen)||(EntryStuff->ExtTblLen==0))               { //ext is in ext table, so fill FILE_STRUCT                 (EntryStuff->Dir_item_ptr->file).ExtentLba = RecordAddress;                 GET_WORD(EntryStuff->EntryBuf,(EntryStuff->Dir_item_ptr->file).WrtDate,24);                 GET_WORD(EntryStuff->EntryBuf,(EntryStuff->Dir_item_ptr->file).WrtTime,22);                 GET_DWORD(EntryStuff->EntryBuf,(EntryStuff->Dir_item_ptr->file).FileSize,28);                 EntryStuff->TypeOfEntry = FAT_FILE_FOUND;                 if(EntryStuff->LongNameFound)                 { //file has long name                   EntryStuff->LongNameFound = false;                   if((EntryStuff->CheckSum==ChkSum(EntryStuff->EntryBuf))&&(EntryStuff->StatusLongName))                   { //long name is OK                     //NameCopy((EntryStuff->Dir_item_ptr->file).Name,EntryStuff->LongName,(EntryStuff->WholeLongEntryLength)*sizeof(uint16));                     p.be = 0;                     p.trunc = 0;                     p.limit = 0;                     (EntryStuff->Dir_item_ptr->file).NameLength = \                     WideFileNameToUTF8((uint8*)(EntryStuff->LongName),(EntryStuff->Dir_item_ptr->file).Name,EntryStuff->WholeLongEntryLength,&p);                     if(0>(EntryStuff->Dir_item_ptr->file).NameLength)                     	return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND;                   }                   else                   { //long name is corrupted                     NameCopy((EntryStuff->Dir_item_ptr->file).Name,String,ShortEntryLength*sizeof(uint16));                     (EntryStuff->Dir_item_ptr->file).NameLength = ShortEntryLength;                   }                 }                 else                 { //no long name for file                   NameCopy((EntryStuff->Dir_item_ptr->file).Name,String,ShortEntryLength*sizeof(uint16));                   (EntryStuff->Dir_item_ptr->file).NameLength = ShortEntryLength;                 }                 return S_SEARCHED_DIR_FILE_ENTRY_FOUND;               }               else               { //ext not in table                 LongChainCancel(EntryStuff);                 return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND;               }           }           else           { //found invalid directory entry             LongChainCancel(EntryStuff);             return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND;           }         }       }       else       { //no short, no long entry, invalid entry         LongChainCancel(EntryStuff);         return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND;       }     }}GRESULT LookForDirFileEntrySectorBasedNext(PRIVATE_DATA_FAT *FAT_private, ENTRY_STUFF_STRUCT *EntryStuff){     ENTRY_ADDRESS PreviousEntryAddress;     uint32 PreviousDirRecordOffset;     uint32 CountOfCycles = 0;     GRESULT ReturnCode;     Get_BytesParamsStruct Get_BytesParams;     //save current position of pointer, restored if there is no next file or dir     PreviousEntryAddress.Cluster = (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster;     PreviousEntryAddress.Byte = (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte;     PreviousDirRecordOffset = EntryStuff->Scan_struct_ptr->DirRecordOffset;     for( ; ; )     { //parse long or short entry, if any       //via 32 bytes blocks         //Are we still in root dir region?         if((EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster >= FAT_private->RootRecordLba + FAT_private->RootDirSec)         {           LongChainCancel(EntryStuff);           //restore original position           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster = PreviousEntryAddress.Cluster;           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte = PreviousEntryAddress.Byte;           EntryStuff->Scan_struct_ptr->DirRecordOffset = PreviousDirRecordOffset;           return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND;         }         //there could still be some dirs         //read one entry         Get_BytesParams.FirstSectorOfCluster = ((EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster);         Get_BytesParams.ClusterOffset = ((EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte);         Get_BytesParams.num = 32;         if((ReturnCode=Get_Bytes(EntryStuff->EntryBuf,EntryStuff->SectorBuffer,&Get_BytesParams,EntryStuff->Scan_struct_ptr->fs_descriptor)) != S_OK)         {           LongChainCancel(EntryStuff);           if(ReturnCode == E_FORCED_UNPLUG)             return ReturnCode;         }         if((ReturnCode == S_OK) && ((EntryStuff->EntryBuf)[0]==0x0))       //all next entries are free         {           LongChainCancel(EntryStuff);           //restore original position           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster = PreviousEntryAddress.Cluster;           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte = PreviousEntryAddress.Byte;           EntryStuff->Scan_struct_ptr->DirRecordOffset = PreviousDirRecordOffset;           return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND;         }         //there is at least one entry         //update current position in root directory         (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte += 32;         EntryStuff->Scan_struct_ptr->DirRecordOffset += 32;         if(ReturnCode != S_OK)           CountOfCycles = 0;         else           CountOfCycles++;         if((EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte >= (FAT_private->BPB_boot_common).BytesPerSec)         { //we moved to next sector           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster += 1;           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte = 0;         }       if((ReturnCode == S_OK) && (ParseEntry(EntryStuff) == S_SEARCHED_DIR_FILE_ENTRY_FOUND))       { //short entry found (dir or file)         //save dir/file entry position (offset from beg. of record) for next possible whole name parsing         if(EntryStuff->TypeOfEntry == FAT_DIR_FOUND)           //found dir           EntryStuff->Dir_item_ptr->dir.ParentOffset = EntryStuff->Scan_struct_ptr->DirRecordOffset-CountOfCycles*32;         else           //found file           EntryStuff->Dir_item_ptr->file.DirRecordOffset = EntryStuff->Scan_struct_ptr->DirRecordOffset-CountOfCycles*32;         return S_SEARCHED_DIR_FILE_ENTRY_FOUND;       }     } //end for}GRESULT LookForDirFileEntryClusterBasedNext(PRIVATE_DATA_FAT *FAT_private, ENTRY_STUFF_STRUCT *EntryStuff){     ENTRY_ADDRESS PreviousEntryAddress;     GRESULT ReturnCode;     uint32 PreviousDirRecordOffset;     uint32 CountOfCycles = 0;     static uint32 Cluster;          Get_BytesParamsStruct Get_BytesParams;          //FatEntryCheck = 0xFFFFFFFF;     //save current position of pointer, restored if there is no next file or dir     PreviousEntryAddress.Cluster = (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster;     PreviousEntryAddress.Byte = (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte;     PreviousDirRecordOffset = EntryStuff->Scan_struct_ptr->DirRecordOffset;     for( ; ; )     { //parse long or short entry, if any       //via 32 bytes blocks         //check if cluster valid         if(EntryStuff->Scan_struct_ptr->FatEntryCheck != (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster)         {             Cluster = (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster;             if(!CheckIfEOF(&FAT_private->BPB_boot_common,Cluster))             { //actual cluster not EOF               if((ReturnCode=Get_FATEntry(EntryStuff->Scan_struct_ptr->fs_descriptor,&Cluster,EntryStuff->SectorBuffer)) != S_OK)    //continue in next cluster               { //error reading FAT table                 LongChainCancel(EntryStuff);                 (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster = PreviousEntryAddress.Cluster;                 (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte = PreviousEntryAddress.Byte;                 EntryStuff->Scan_struct_ptr->DirRecordOffset = PreviousDirRecordOffset;                 EntryStuff->Scan_struct_ptr->FatEntryCheck = 0xFFFFFFFF;                 return ReturnCode;                            }                            }             if(CheckIfEOF(&FAT_private->BPB_boot_common,(EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster)              || CheckIfBadCluster(&FAT_private->BPB_boot_common,Cluster))             { //whole directory record is parsed, nothing to do anymore               LongChainCancel(EntryStuff);               //restore original position               (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster = PreviousEntryAddress.Cluster;               (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte = PreviousEntryAddress.Byte;               EntryStuff->Scan_struct_ptr->DirRecordOffset = PreviousDirRecordOffset;               EntryStuff->Scan_struct_ptr->FatEntryCheck = 0xFFFFFFFF;               return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND;             }                          EntryStuff->Scan_struct_ptr->FatEntryCheck = (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster;         }         //read one entry         Get_BytesParams.FirstSectorOfCluster = Get_FirstSectorofCluster(&FAT_private->BPB_boot_common,FAT_private->FirstDataSector,(EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster);         Get_BytesParams.ClusterOffset = ((EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte);         Get_BytesParams.num = 32;         if((ReturnCode=Get_Bytes(EntryStuff->EntryBuf,EntryStuff->SectorBuffer,&Get_BytesParams,EntryStuff->Scan_struct_ptr->fs_descriptor)) != S_OK)         {           LongChainCancel(EntryStuff);           if(ReturnCode == E_FORCED_UNPLUG)             return ReturnCode;         }         if((ReturnCode == S_OK) && ((EntryStuff->EntryBuf)[0]==0x0))       //all next entries are free         {           LongChainCancel(EntryStuff);           //restore original position           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster = PreviousEntryAddress.Cluster;           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte = PreviousEntryAddress.Byte;           EntryStuff->Scan_struct_ptr->DirRecordOffset = PreviousDirRecordOffset;           return E_SEARCHED_DIR_FILE_ENTRY_NOT_FOUND;         }         //there is at least one entry         //update current position in directory         (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte += 32;         EntryStuff->Scan_struct_ptr->DirRecordOffset += 32;         if(ReturnCode != S_OK)           CountOfCycles = 0;         else           CountOfCycles++;                  if((EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte >= (uint32)(FAT_private->BPB_boot_common.BytesPerSec)*(FAT_private->BPB_boot_common.SecPerClust))         { //we moved to next cluster           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Byte = 0;           (EntryStuff->Scan_struct_ptr->DirEntryAddress).Cluster = Cluster;         }       if((ReturnCode == S_OK) && (ParseEntry(EntryStuff) == S_SEARCHED_DIR_FILE_ENTRY_FOUND))       { //directory short entry found         //save dir/file entry position (offset from beg. of record) for next possible whole name parsing         if(EntryStuff->TypeOfEntry == FAT_DIR_FOUND)           //found dir           EntryStuff->Dir_item_ptr->dir.ParentOffset = EntryStuff->Scan_struct_ptr->DirRecordOffset-CountOfCycles*32;         else           //found file           EntryStuff->Dir_item_ptr->file.DirRecordOffset = EntryStuff->Scan_struct_ptr->DirRecordOffset-CountOfCycles*32;         return S_SEARCHED_DIR_FILE_ENTRY_FOUND;       }     } //end for}GRESULT FAT_Detect(DUID cdid, int partition, FS_DESCRIPTOR *fsd){     GRESULT ReturnCode;     uint8 buf[512];      //inherited      fsd->LargeBlockSize=SYS_DeviceInfoStruct(cdid)->LargeBlockSize;      fsd->Partition=partition;      fsd->PartitionLBA= (SYS_DeviceInfoStruct(cdid)->PartitionLBA)[partition];      fsd->FSType = FS_FAT_TYPE;      fsd->did = cdid;     fsd->PD.FAT_pd.FirstPassGetSector_FAT = true;     if((ReturnCode = Get_BPB_BS(fsd,buf)) != S_OK)       return ReturnCode;     fsd->PD.FAT_pd.ExtTblLen = 0;     if(fsd->PD.FAT_pd.BPB_boot_common.FATType)     { //FAT12 or 16       fsd->PD.FAT_pd.RootRecordLba = Get_FAT12_16_FirstRootDirSecNum(&(fsd->PD.FAT_pd.BPB_boot_common));       fsd->PD.FAT_pd.RootDirSec = Get_RootDirSectors(&(fsd->PD.FAT_pd.BPB_boot_common));     }     else     { //FAT32       fsd->PD.FAT_pd.RootRecordLba = fsd->PD.FAT_pd.BPB_boot_rest.BPB_boot_rest_FAT_32.RootClus;     }     fsd->PD.FAT_pd.FirstDataSector = Get_FirstDataSector(&(fsd->PD.FAT_pd.BPB_boot_common));     return S_TRUE;}GRESULT FAT_GetExtent(SCAN_STRUCT *scans, uint32 *LengthOfExtent, uint8 *SectorBuffer){       uint32 PreviousCluster;       GRESULT ReturnCode;       uint32 BytesPerCluster = (uint32)(scans->fs_descriptor->PD.FAT_pd.BPB_boot_common.BytesPerSec)*scans->fs_descriptor->PD.FAT_pd.BPB_boot_common.SecPerClust;       //certainly one cluster is available       *LengthOfExtent = BytesPerCluster;       for( ; ; )       { //via clusters         PreviousCluster = scans->Cluster;         if((ReturnCode=Get_FATEntry(scans->fs_descriptor,&(scans->Cluster),SectorBuffer)) != S_OK)    //continue in next cluster           return ReturnCode;         if(CheckIfBadCluster(&(scans->fs_descriptor->PD.FAT_pd.BPB_boot_common),scans->Cluster))         { //cluster is bad           *LengthOfExtent -= BytesPerCluster;           return E_FAIL;         }         if(CheckIfEOF(&(scans->fs_descriptor->PD.FAT_pd.BPB_boot_common),scans->Cluster))         { //EOC           return S_OK;         }         if(scans->Cluster != PreviousCluster+1)         { //discontinuity of cluster chain           return S_OK;         }         else         { //continuity of cluster chain           *LengthOfExtent += BytesPerCluster;         }       } //via clusters}void SetEOF(BPB_boot_common_t *BPB_boot_common, uint32 *FATContent){     switch(BPB_boot_common->FATType)     {       case 1: *FATContent = 0x0FF8;               break;       case 2: *FATContent = 0xFFF8;               break;       case 0: *FATContent = 0x0FFFFFF8;               break;     }}GRESULT FAT_GetDirItem(SCAN_STRUCT *scans, DIR_ITEM *item, uint8 *buf){     ENTRY_STUFF_STRUCT EntryStuff;     uint8 EntryBuf[32];           //alloc memory for 32 bytes == 1 entry     GRESULT ReturnCode;     uint32 LengthOfExtent,PrevDirRecordOffset;     if(scans->byte0 == S_FALSE)     { //parse dir record       EntryStuff.EntryBuf = EntryBuf;       EntryStuff.SectorBuffer = buf;       EntryStuff.Scan_struct_ptr = scans;       EntryStuff.Dir_item_ptr = item;       EntryStuff.FAT_private_struct_ptr = &(scans->fs_descriptor->PD.FAT_pd);       EntryStuff.LongNameFound = false;//       EntryStuff.ExtTbl = scans->fs_descriptor->PD.FAT_pd.ExtTbl;       EntryStuff.ExtTblLen = scans->fs_descriptor->PD.FAT_pd.ExtTblLen;       if(scans->DirRecordOffset == 0)

⌨️ 快捷键说明

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