📄 fat.c
字号:
{
if(CORE.CurPathType == DirectoryPath &&
(LongNameDirectoryEntry_Local->dir_attr & ATTR_DIRECTORY))
{
CORE.ClusterOfDirectoryEntry = *(u16*)LongNameDirectoryEntry_Local->dir_first;
CORE.PreEntrySectorNum = CORE.SectorNum;
CORE.PreEntryoffset = CORE.offset;
CORE_offset_add_32(buf);///Directory Entry的位置+32
return(SUCC);
}
else if ( ! (LongNameDirectoryEntry_Local->dir_attr & ATTR_VOLUME_ID))
{
CORE.PreEntrySectorNum = CORE.SectorNum;
CORE.PreEntryoffset = CORE.offset;
CORE_offset_add_32(buf);//Directory Entry的位置+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的位置+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;
if(GetEntryWith8_3Name(buf,EntryName,Extension) == SUCC)
return(SUCC);
break;
}
case ATTR_VOLUME_ID:CORE.Entry_Attr = Directory_Entry_Local->file_attribute;
//case 0:break;
default:
{//从目录读取文件(短文件名)
CORE.Entry_Attr = Directory_Entry_Local->file_attribute;
if(mode == Get_Selected_ENTRIES)
if(CORE.FullPathType == DirectoryPath)
break;
return(GetEntryWith8_3Name(buf,EntryName,Extension));
}
}
CORE.PreEntrySectorNum = CORE.SectorNum;
CORE.PreEntryoffset = CORE.offset;
if(CORE_offset_add_32(buf) == FAIL)
return(FAIL);//Directory Entry的位置+32
}while(1);
return(SUCC);
}
/*===============================================================================
函数
从目录中查找一个Entry
入口:floder_name-文件名,file_extension-扩展名
出口:SUCC,FAIL
===============================================================================*/
static u8 FindEntryStruct(u8 *floder_name,u8 *file_extension)
{
u8 EntryName[256],Extension[20];
u8 Name_Compare_OK,Extension_Compare_OK;
do{ //从目录读取一个Entry
if(GetEntryFromDirectory(EntryName,Extension,Get_Selected_ENTRIES) != SUCC)
{
return(FAIL);
}
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);
}
/*===============================================================================
函数
相对的路径转换成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;
//调用SplitNameFromPath()从RelativePath分离出一个目录或文件元素
Splited_Status = SplitNameFromPath(RelativePath,floder_name,file_extension,&Splited_Count);
if(Splited_Status == FAIL)
return(FAIL);
RelativePath += Splited_Count;
//从目录中查找一个Entry
if(FindEntryStruct(floder_name,file_extension) != SUCC)
{
return(FAIL); //查找失败退出
}//DirectoryType置为非RootDirectory
if(CORE.CurPathType == DirectoryPath)
if(CORE.DirectoryType == RootDirectory)
{
CORE.DirectoryType = NoneRootDirectory;
}
if(Splited_Status == LastSplitedNameofPath)
{
return(SUCC);
}
do{ //调用SplitNameFromPath()从RelativePath分离出一个目录或文件元素
Splited_Status = SplitNameFromPath(RelativePath,floder_name,file_extension,&Splited_Count);
if(Splited_Status == FAIL)
return(FAIL);
else
{ //设置变量,进入目录去查找
CORE.ClusterNum = CORE.ClusterOfDirectoryEntry;
CORE.SectorNum = FirstSectorofCluster(CORE.ClusterNum);
CORE.offset = 0;
}
RelativePath += Splited_Count;
//DirectoryType置为非RootDirectory
if(CORE.CurPathType == DirectoryPath)
if(CORE.DirectoryType == RootDirectory)
{
CORE.DirectoryType = NoneRootDirectory;
}
//从目录中查找一个Entry
if(FindEntryStruct(floder_name,file_extension) != SUCC)
{
return(FAIL); //查找失败退出
}
else if(Splited_Status == LastSplitedNameofPath)
{
return(SUCC);
}
}while(1);
return(SUCC);
}
/*===============================================================================
函数
完整的路径转换成Sector,SectorOffset,Cluster,可用于检查文件是否存在
入口:u8 *filename
出口:SUCC,FAIL
===============================================================================*/
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;
CORE.DirectoryType = RootDirectory;
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);
}
/*===============================================================================
函数
检查文件是否已打开?
入口:FirstClusterOfFile-文件首簇号
出口: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)
{ //FCB的首簇号与文件首簇号相同,则文件已被打开
if(FCB[i].FirstClusterOfFile == FirstClusterOfFile)
return(FileAlreadyopenedByOtherHandle);
}
}
//未发现相同首簇号,文件未打开,返回
return(FileUnopenedByOtherHandle);
}
/*===============================================================================
函数
将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);
//将首簇号写入文件的ENTRY内
read_flash_sector(buf,FCB[FCBsn].Entry_Storedin_Sector);
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;
}
//根据当前CurBlockInBUF计算需要移动CLUSTER数量
ClusterQTY = FCB[FCBsn].CurBlockInBUF / BPB.sector_per_cluster;
NEXTCluster = FCB[FCBsn].FirstClusterOfFile;
//计算需要移动CLUSTER数量
qty = ClusterQTY;
if(FCB[FCBsn].ClusterSNInBUF <= ClusterQTY)
{
ClusterQTY -= FCB[FCBsn].ClusterSNInBUF;
NEXTCluster = FCB[FCBsn].CurClusterInBUF;
}
else
{
NEXTCluster = FCB[FCBsn].FirstClusterOfFile;
}
//移动CLUSTER
while(ClusterQTY)
{TEMP = NEXTCluster;
NEXTCluster = Get_Next_Cluster_From_Current_Cluster(NEXTCluster);
ClusterQTY--;
if(NEXTCluster >= 0xfff4 && NEXTCluster <= 0xffff)
{
if (Allocate_EMPTY_CLUSTER_TO_CUR_CLUSTER_CHAIN(TEMP,&NEXTCluster,buf) == FAIL)
return(FAIL);
}
}
//保存当前CurClusterInBUF及ClusterSNInBUF
FCB[FCBsn].CurClusterInBUF = NEXTCluster;
FCB[FCBsn].ClusterSNInBUF = qty;
//将file buffer回写磁盘
FCBbufSize = FileBUFSize * TotalFileBUFsQTYeachFCB;
BUFoffset = 0;
i = FCB[FCBsn].CurBlockInBUF % BPB.sector_per_cluster;
//获取首扇区
sector = FirstSectorofCluster(NEXTCluster);
wrote_sectors_count = 0;
do{
write_flash_sector(FCB[FCBsn].FileBUF + BUFoffset,sector + i);
wrote_sectors_count++;
i++;
//超过FILE SIZE直接退出
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)
{ //超过簇边界, 转到下一簇继续写
TEMP = NEXTCluster;
NEXTCluster = Get_Next_Cluster_From_Current_Cluster(NEXTCluster);
if(NEXTCluster >= 0xfff4 && NEXTCluster <= 0xffff)
{
if (Allocate_EMPTY_CLUSTER_TO_CUR_CLUSTER_CHAIN(TEMP,&NEXTCluster,buf) == FAIL)
return(FAIL);
}
sector = FirstSectorofCluster(NEXTCluster);
i = 0;
}
}while(1);
//清除Modified_Flag
FCB[FCBsn].Modified_Flag = 0;
//读取文件目录项, 从而更新文件大小
read_flash_sector(buf,FCB[FCBsn].Entry_Storedin_Sector);
i = FCB[FCBsn].Entry_Storedin_Sector_Offset + 28;
FILESIZE = buf[i] + buf[i+1] * 256 + buf[i+2] * 256 * 256+ buf[i+3] * 256 * 256 *256;
//检查文件大小是否已更新?
if(FILESIZE != FCB[FCBsn].FileSize)
{ //检查文件大小已更新,则更新File Directory entry的文件大小
FILESIZE = FCB[FCBsn].FileSize;
buf[i] = (u8)(FILESIZE & 0xff);
buf[i+1] = (u8)((FILESIZE >> 8) & 0xff);
buf[i+2] = (u8)((FILESIZE >> 16) & 0xff);
buf[i+3] = (u8)((FILESIZE >> 24) & 0xff);
write_flash_sector(buf,FCB[FCBsn].Entry_Storedin_Sector);
}
return(SUCC);
}
#endif
/*===============================================================================
函数
基于文件当前的位置,完成更新文件缓冲区
入口:u8 FCBsn
出口:SUCC,FAIL
===============================================================================*/
#if EnableFileBuf
u8 Update_FCB_file_buffer(u8 FCBsn)
{
u16 i;
u16 ClusterQTY,BUFoffset;
u32 FCBbufSize,sector,NEXTCluster,qty;
if(!(FileBUFSize * TotalFileBUFsQTYeachFCB))
return(SUCC);
if(((FCB[FCBsn].cur_position) >= FCB[FCBsn].CurBlockInBUF * FileBUFSize &&
((FCB[FCBsn].cur_position) < (FCB[FCBsn].CurBlockInBUF + TotalFileBUFsQTYeachFCB) * FileBUFSize) ))
{
return(SUCC);
}
if(FCB[FCBsn].Modified_Flag)//检查Modified_Flag,如果不为0,则需要回写FILE BUFFER
if(Writeback_FCB_file_buffer(FCBsn) == FAIL)
return(FAIL);
//根据当前CurBlockInBUF计算需要移动CLUSTER数量
FCB[FCBsn].CurBlockInBUF = FCB[FCBsn].cur_position / FileBUFSize;
ClusterQTY = FCB[FCBsn].CurBlockInBUF / BPB.sector_per_cluster;
NEXTCluster = FCB[FCBsn].FirstClusterOfFile;
qty = ClusterQTY;
//计算需要移动CLUSTER数量
if(FCB[FCBsn].ClusterSNInBUF_for_read <= ClusterQTY)
{
ClusterQTY -= FCB[FCBsn].ClusterSNInBUF_for_read;
NEXTCluster = FCB[FCBsn].CurClusterInBUF_for_read;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -