📄 fat.c
字号:
}while(1);
return(SUCC);
}
/*
===============================================================================
函数
从目录读一个Entry
入口:mode = 0:返回所有directory entry
出口:SUCC,FAIL
===============================================================================
*/
static u8 GetEntryFromDirectory(u8 *EntryName, u8 *Extension,u8 mode)
{
struct Directory_Entry_ *Directory_Entry_Local;
struct LongNameDirectoryEntry *LongNameDirectoryEntry_Local;
u8 flag;
u8 buf[512];
read_flash_sector(buf,CORE.SectorNum);
////////////////////////printf("ffffffffCORE.offset =%d,CORE.SectorNum=%dffffff",CORE.offset,CORE.SectorNum);
do{
flag = FILE_NAME; //or = FILE_EXTENSION 0xfe
Directory_Entry_Local = (struct Directory_Entry_ *) (buf + CORE.offset);
if(Directory_Entry_Local->filename[0] == 0x0)
return(FAIL);
if(Directory_Entry_Local->filename[0] == 0xe5)
{
CORE.PreEntrySectorNum = CORE.SectorNum;
CORE.PreEntryoffset = CORE.offset;
if(CORE_offset_add_32(buf) == FAIL) //Directory Entry offset + 32
return(FAIL);
continue;
}
////////////////////////////printf("\ndirectory entry!");
switch(Directory_Entry_Local->file_attribute)
{
case ATTR_LONG_NAME:{////////////////////////////////printf("<long>");
if(GetEntryWithLongFileName(buf,EntryName,Extension) == SUCC)
{
read_flash_sector(buf,CORE.SectorNum);
LongNameDirectoryEntry_Local = (struct LongNameDirectoryEntry *)(buf + CORE.offset);
CORE.Entry_Attr = LongNameDirectoryEntry_Local->dir_attr;
//////////////////////////////printf("LongNameDirectoryEntry_Local->dir_attr = %d",LongNameDirectoryEntry_Local->dir_attr );
if(mode == Get_Selected_ENTRIES)
{
if(CORE.CurPathType == DirectoryPath &&
(LongNameDirectoryEntry_Local->dir_attr & ATTR_DIRECTORY))
{
//////////////////////////////printf("entryname =%s dddddd entry extension = %s\n",EntryName,Extension);
CORE.ClusterOfDirectoryEntry = *(u16*)LongNameDirectoryEntry_Local->dir_first;
CORE.PreEntrySectorNum = CORE.SectorNum;
CORE.PreEntryoffset = CORE.offset;
CORE_offset_add_32(buf);//Directory Entry offset + 32
return(SUCC);
}
else if ( ! (LongNameDirectoryEntry_Local->dir_attr & ATTR_VOLUME_ID))
{//////////////////////////////printf("ATTR_VOLUME_ID = %d entryname =%s XXXxxxx entry extension = %s",ATTR_VOLUME_ID,EntryName,Extension);
CORE.PreEntrySectorNum = CORE.SectorNum;
CORE.PreEntryoffset = CORE.offset;
CORE_offset_add_32(buf);//Directory Entry offset + 32
return(SUCC);
}
}
else
{
CORE.PreEntrySectorNum = CORE.SectorNum;
CORE.PreEntryoffset = CORE.offset;
CORE.ClusterOfDirectoryEntry = *(u16*)LongNameDirectoryEntry_Local->dir_first;
CORE_offset_add_32(buf);//Directory Entry offset + 32
return(SUCC);
}
}
break;
}
case ATTR_DIRECTORY:{
CORE.Entry_Attr = Directory_Entry_Local->file_attribute;
if(mode == Get_Selected_ENTRIES)
if(CORE.FullPathType == FilePath && CORE.CurPathType == FilePath)
break;
//////printf("xxxxxxxxTony");
if(GetEntryWith8_3Name(buf,EntryName,Extension) == SUCC)
return(SUCC);
break;
}
case ATTR_VOLUME_ID:CORE.Entry_Attr = Directory_Entry_Local->file_attribute;//////////////////////////printf("Tony");break;
//case 0:break;
default:
{
CORE.Entry_Attr = Directory_Entry_Local->file_attribute;
if(mode == Get_Selected_ENTRIES)
if(CORE.FullPathType == DirectoryPath)
break;
////////////////////////////printf("Directory_Entry_Local->filename[0] = %d",*(buf + CORE.offset - 1));
//////////////////////////////printf("EntryName=%s Extension=%s",EntryName,Extension);
return(GetEntryWith8_3Name(buf,EntryName,Extension));
}
}
CORE.PreEntrySectorNum = CORE.SectorNum;
CORE.PreEntryoffset = CORE.offset;
if(CORE_offset_add_32(buf) == FAIL) //Directory Entry offset + 32
return(FAIL);
}while(1);
return(SUCC);
}
/*
===============================================================================
函数
从目录中找一个Entry
入口:
出口:SUCC,FAIL
===============================================================================
*/
static u8 FindEntryStruct(u8 *floder_name,u8 *file_extension)
{
u8 EntryName[256],Extension[20];
u8 Name_Compare_OK,Extension_Compare_OK;
do{
if(GetEntryFromDirectory(EntryName,Extension,Get_Selected_ENTRIES) != SUCC)
{
//////////////////////////////printf("FAIL");
return(FAIL);
}
////////////printf("\nentryname =%s XXX entry extension = %s",EntryName,Extension);
//////////printf("\nentryname2 =%s XXX entry extension2 = %s\n\n",floder_name,file_extension);
Name_Compare_OK = OK;
if(stringcmp(EntryName,floder_name) != SUCC)
Name_Compare_OK = unOK;
if(Name_Compare_OK == OK) //检查文件扩展名
{
if(CORE.FullPathType == FilePath && CORE.CurPathType == FilePath)
{
Extension_Compare_OK = OK;
if(stringcmp(Extension,file_extension) != SUCC)
Extension_Compare_OK = unOK;
else
break;
}
else
{
if(Extension[0] == 0)
break;
}
}
}while(1);
return(SUCC);
}
/*
===============================================================================
函数
Relative Path converts To Sector,SectorOffset,Cluster
入口:u8 *filename
出口:SUCC,FAIL
===============================================================================
*/
static u8 RelativePathToSectorCluster(u8 *RelativePath)
{
u8 floder_name[256],file_extension[20];
u8 Splited_Count;
u8 Splited_Status;
//////printf("RelativePath =%s",RelativePath);
//Public variables for path resolution
Splited_Status = SplitNameFromPath(RelativePath,floder_name,file_extension,&Splited_Count);
if(Splited_Status == FAIL)
return(FAIL);
RelativePath += Splited_Count;
//////////////////////////////printf("\nsplited folder name = %s extension name = %s remained path = %s\n",floder_name,file_extension,RelativePath);
if(FindEntryStruct(floder_name,file_extension) != SUCC)
{
return(FAIL);
}
if(CORE.CurPathType == DirectoryPath)
if(CORE.DirectoryType == RootDirectory)
{
CORE.DirectoryType = NoneRootDirectory;
////////////////printf("TOny TONY");
}
if(Splited_Status == LastSplitedNameofPath)
{//CORE.CurPathType = FilePath;
////////////////////////printf("CORE.CurPathType=%d",CORE.CurPathType);
////////printf("ddddddddddxxxxxxxxxxxxxxxxxxxxxxx");
return(SUCC);
}
do{
Splited_Status = SplitNameFromPath(RelativePath,floder_name,file_extension,&Splited_Count);
if(Splited_Status == FAIL)
return(FAIL);
else
{ ////////printf("ddddddddddxxxxxxxxxxxeeeeeeeeeeeeeeefffffffffffffxxxxxxxxxxxx");
//////////////////////////////printf("CORE.ClusterNum = %d ",CORE.ClusterNum);
CORE.ClusterNum = CORE.ClusterOfDirectoryEntry;
CORE.SectorNum = FirstSectorofCluster(CORE.ClusterNum);
CORE.offset = 0;
}
RelativePath += Splited_Count;
if(CORE.CurPathType == DirectoryPath)
if(CORE.DirectoryType == RootDirectory)
{
CORE.DirectoryType = NoneRootDirectory;
}
if(FindEntryStruct(floder_name,file_extension) != SUCC)
{
return(FAIL);
}
else if(Splited_Status == LastSplitedNameofPath)
{////////////////////////printf("CORE.CurPathType=%d",CORE.CurPathType);
return(SUCC);
}
}while(1);
return(SUCC);
}
/*
===============================================================================
函数
Full Path converts To Sector,SectorOffset,Cluster
入口:u8 *filename
出口:SUCC,FAIL(u32 *cluster_no,u32 *sector,u16 *offset)
===============================================================================
*/
static u8 FullPathToSectorCluster(u8 * filename1)
{
u8 buf[260],* filename;
stringcpy(filename1,buf);
filename = buf;
UPCASE(filename);
if( ((* filename) >= 'A' && ( * filename ) <= 'Z')||
((* filename) >= 'a' && ( * filename ) <= 'z') ) //从指定盘符根目录开始寻址
{
if(( * (filename + 1)) == ':')
{
if( *( filename + 2 ) == '\\')
{
if(LengthofString(filename) > Maximum_File_Path_Name)
return(EpathLengthsOVERFLOW);
if(Read_partition_PBP((u8)((*filename) - 'C')) != SUCC)
return(FAIL);
filename += 3;
CORE.SectorNum = CORE.FirstRootDirSecNum;
//////////////////////////////printf("FirstRootDirSecNum %ld",CORE.FirstRootDirSecNum);
CORE.DirectoryType = RootDirectory;
////////////////////////printf("aaaaa");
CORE.offset = 0;
}
}
else
{
if((LengthofString(filename) + LengthofString(CORE.current_folder)) > Maximum_File_Path_Name)
return(EpathLengthsOVERFLOW);
if(CORE.CurrentDirectoryType == RootDirectory)
{
CORE.SectorNum = CORE.FirstRootDirSecNum;
}
else
{
CORE.ClusterNum = CORE.ClusterNOofCurrentFolder;
CORE.SectorNum = FirstSectorofCluster(CORE.ClusterNum);
}
CORE.DirectoryType = CORE.CurrentDirectoryType;
CORE.offset = 0;
}
}
else if((* filename) == '\\')
{
if((LengthofString(filename) + 1) > Maximum_File_Path_Name)
return(EpathLengthsOVERFLOW);
filename ++; //从当前盘符,根目录开始寻址
CORE.SectorNum = CORE.FirstRootDirSecNum;
CORE.DirectoryType = RootDirectory;
CORE.offset = 0;
}
if(*filename)
return(RelativePathToSectorCluster(filename));
else
return(SUCC);
}
/*
===============================================================================
函数
检查文件打开?
入口:u8 FCBsn
出口:FileAlreadyopenedByOtherHandle,FileUnopenedByOtherHandle
===============================================================================
*/
u8 Check_FileOpened_Status(u32 FirstClusterOfFile,u16 j)
{
u8 i;
for(i = 0;i < MaximumFCB;i++)
{
if(i == j)
continue;
if(FCB[i].file_openned_flag == UsedFlag)
{
if(FCB[i].FirstClusterOfFile == FirstClusterOfFile)
return(FileAlreadyopenedByOtherHandle);
}
}
return(FileUnopenedByOtherHandle);
}
/*
===============================================================================
函数
将FCB file buffer回写入磁盘
入口:u8 FCBsn
出口:SUCC,FAIL
===============================================================================
*/
#if EnableFileBuf
u8 Writeback_FCB_file_buffer(u8 FCBsn)
{
u16 i;
u16 ClusterQTY,BUFoffset,TEMP;
u32 FCBbufSize,sector,NEXTCluster,qty;
u8 buf[512];
u32 FILESIZE;
u16 wrote_sectors_count;
//未分配文件首簇号,则执行分配
if(FCB[FCBsn].FirstClusterOfFile == 0)
{
if( Allocate_An_Empty_cluster(&FCB[FCBsn].FirstClusterOfFile,buf)== FAIL)
return(FAIL);
read_flash_sector(buf,FCB[FCBsn].Entry_Storedin_Sector);
////printf("FCB[FCBsn].FirstClusterOfFile =%d",FCB[FCBsn].FirstClusterOfFile);
i = FCB[FCBsn].Entry_Storedin_Sector_Offset + 26;
buf[i] = (u8)(FCB[FCBsn].FirstClusterOfFile & 0xff);
buf[i+1] = (u8)((FCB[FCBsn].FirstClusterOfFile >> 8) & 0xff);
write_flash_sector(buf,FCB[FCBsn].Entry_Storedin_Sector);
FCB[FCBsn].CurClusterInBUF = FCB[FCBsn].FirstClusterOfFile;
}
ClusterQTY = FCB[FCBsn].CurBlockInBUF / BPB.sector_per_cluster;
NEXTCluster = FCB[FCBsn].FirstClusterOfFile;
qty = ClusterQTY;
if(FCB[FCBsn].ClusterSNInBUF <= ClusterQTY)
{
ClusterQTY -= FCB[FCBsn].ClusterSNInBUF;
NEXTCluster = FCB[FCBsn].CurClusterInBUF;
}
else
{
NEXTCluster = FCB[FCBsn].FirstClusterOfFile;
}
while(ClusterQTY)
{TEMP = NEXTCluster;
NEXTCluster = Get_Next_Cluster_From_Current_Cluster(NEXTCluster);
ClusterQTY--;
////////printf("NEXTCluster %d",NEXTCluster );
if(NEXTCluster >= 0xfff4 && NEXTCluster <= 0xffff)
{
if (Allocate_EMPTY_CLUSTER_TO_CUR_CLUSTER_CHAIN(TEMP,&NEXTCluster,buf) == FAIL)
return(FAIL);
}
}
FCB[FCBsn].CurClusterInBUF = NEXTCluster;
FCB[FCBsn].ClusterSNInBUF = qty;
//Wirteback FCB file buffer to physical sector
FCBbufSize = FileBUFSize * TotalFileBUFsQTYeachFCB;
BUFoffset = 0;
i = FCB[FCBsn].CurBlockInBUF % BPB.sector_per_cluster;
sector = FirstSectorofCluster(NEXTCluster);
wrote_sectors_count = 0;
do{
//////////printf("Allocated Cluster %ld BPB.sector_per_cluster %ld",NEXTCluster,BPB.sector_per_cluster);
write_flash_sector(FCB[FCBsn].FileBUF + BUFoffset,sector + i);
wrote_sectors_count++;
i++;
if(((wrote_sectors_count + FCB[FCBsn].CurBlockInBUF) * 512) >= FCB[FCBsn].FileSize)
{
break;
}
BUFoffset += FileBUFSize;
FCBbufSize -= FileBUFSize;
if(FCBbufSize == 0)
{
break;
}
if(i >= BPB.sector_per_cluster)
{
//////////printf("HELLO Allocated Cluster %ld i = %d",NEXTCluster,i);
TEMP = NEXTCluster;
NEXTCluster = Get_Next_Cluster_From_Current_Cluster(NEXTCluster);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -