📄 osfile.c
字号:
/****************************************
查找指定文件名的文件,可以是8.3或者11模式
如果找到文件返回文件在目录表中的项的位置,
否则,返回-1,
*****************************************/
int FindOSFile(char filename[])
{
int j;
char filename1[12]={0};
FormatFileName(filename1,filename);
for(j=0;j<RootEntry && (FileSystemRoot[j].filename[0]!=0x00);j++){
if(!MemcmpNoUpper(filename1, FileSystemRoot[j].filename,11)){ //如果找到某项符合条件
return j;
}
}
return -1;
}
/****************************************
重命名文件
*****************************************/
U8 RenameOSFile(char fromname[], char toname[])
{
char filename1[12]={0};
int pos;
FormatFileName(filename1,toname);
pos=FindOSFile(fromname);
if(pos<0)
return FALSE;
memcpy(FileSystemRoot[pos].filename, filename1, 11);
WriteFileRootFromMem();
return TRUE;
}
//<--------add by threewater
U32 ReadOSFile(OSFILE* pfile ,U8* ReadBuffer, U32 nReadbyte)
{
U32 i,CurrentSector,SecNumOfClus,Current_Cluster;
if(pfile->filemode!=FILEMODE_READ)
return 0;
for(i=0;i<nReadbyte;i++){
if(pfile->filesize<=pfile->fileCurpos)
return i;
(*ReadBuffer)=pfile->Buffer[(pfile->fileCurpos++)%Block_Size];//
ReadBuffer++;
pfile->filebufnum++;//整个文件的读写文置指针
if(pfile->filebufnum==Block_Size){//如果到了缓冲区末尾
pfile->filebufnum=0;
// Pre_Block=pfile->fileCluster;
pfile->fileCluster=Current_Cluster=NextCluster(pfile->fileCluster);
if((pfile->fileCluster==0xffff)||((pfile->fileCluster&0xfff)==0xfff)||(pfile->fileCluster==0xffffffff))//文件结束
return i;
CurrentSector=(Current_Cluster-2)*SecPerClus+FirstDataSec;
for(SecNumOfClus=0;SecNumOfClus<SecPerClus;SecNumOfClus++){
ReadPage(Begin_Cluster+(CurrentSector+SecNumOfClus)/PagePerClus,(CurrentSector+SecNumOfClus)%PagePerClus,databuff);
memcpy(pfile->Buffer+pfile->filebufnum, databuff,512);
pfile->filebufnum+=512;
if(pfile->filebufnum>=Block_Size) {
pfile->filebufnum=0;//缓冲区指针重新指向开头
break;//缓冲区满时中止
}
}
}
}
return i;
}
U32 GetPosOSFile(OSFILE* pfile)
{
return pfile->fileCurpos;
// return pfile->fileCurpos%Block_Size;
}
U32 SeekOSFile(OSFILE* pfile ,U32 nCurPos)
{
U32 i,CurrentSector,SecNumOfClus,Pre_Cluster;
// if(pfile->filemode!=FILEMODE_READ)
// return 0;
if(nCurPos>pfile->filesize)//文件大小越界
return pfile->fileCurpos;
if((nCurPos>=Block_Size)&&(pfile->fileCurpos<Block_Size)){//跨Block 往后Seek
pfile->filebufnum=0;
// Pre_Block=pfile->fileCluster;
pfile->fileCluster=NextCluster(pfile->fileCluster);
if((pfile->fileCluster==0xffff)&&(pfile->fileCluster==0xfff)&&(pfile->fileCluster==0xffffffff))
return i;
CurrentSector=(pfile->fileCluster-2)*SecPerClus+FirstDataSec;
for(SecNumOfClus=0;(SecNumOfClus<SecPerClus)&&((pfile->fileCurpos+pfile->filebufnum)<pfile->filesize);SecNumOfClus++){
ReadPage(Begin_Cluster+(CurrentSector+SecNumOfClus)/PagePerClus,(CurrentSector+SecNumOfClus)%PagePerClus,databuff);
memcpy(pfile->Buffer+pfile->filebufnum, databuff,512);
pfile->filebufnum+=512;
if((pfile->filebufnum>=Block_Size)&&((pfile->fileCurpos+pfile->filebufnum)>=pfile->filesize)) {
pfile->filebufnum=0;//缓冲区指针重新指向开头
break;//缓冲区慢时中止
}
}
pfile->filebufnum =nCurPos-Block_Size;
pfile->fileCurpos =nCurPos;
return nCurPos;
}
else if((nCurPos<Block_Size)&&(pfile->fileCurpos>=Block_Size)){//跨Block 往回Seek
pfile->filebufnum=0;
//查找上一个Cluster
Pre_Cluster=NextCluster(FileSystemRoot[pfile->rootpos].cluster);
while(pfile->fileCluster!=NextCluster(Pre_Cluster)) {Pre_Cluster=NextCluster(Pre_Cluster);}//往后找,直到打到当前簇的上一簇
pfile->fileCluster=Pre_Cluster; //找到了肖前簇的前一簇
if((pfile->fileCluster==0xffff)&&(pfile->fileCluster==0xfff)&&(pfile->fileCluster==0xffffffff))
return i;
CurrentSector=(pfile->fileCluster-2)*SecPerClus+FirstDataSec;
for(SecNumOfClus=0;SecNumOfClus<SecPerClus;SecNumOfClus++){
ReadPage(Begin_Cluster+(CurrentSector+SecNumOfClus)/PagePerClus,(CurrentSector+SecNumOfClus)%PagePerClus,databuff);
memcpy(pfile->Buffer+pfile->filebufnum, databuff,512);
pfile->filebufnum+=512;
if(pfile->filebufnum>=Block_Size) {
pfile->filebufnum=0;//缓冲区指针重新指向开头
break;//缓冲区慢时中止
}
}
pfile->filebufnum =nCurPos;
pfile->fileCurpos =nCurPos;
return nCurPos;
}
//在Block内Seek
else {
pfile->filebufnum=nCurPos%Block_Size;
pfile->fileCurpos=nCurPos;
return nCurPos;
}
return 0;
}
U8 WriteOSFile(OSFILE* pfile, U8* WriteBuffer, U32 nWritebyte)
{
int i=0,j=0;
U32 Pre_Cluster,Current_Cluster;
// if((pfile->filemode&0xf) !=FILEMODE_WRITE)
// return FALSE;
Current_Cluster=pfile->fileCluster;
for(i=0;i<nWritebyte;i++){
// pfile->Buffer[pfile->fileCurpos++]=*WriteBuffer;
// printk("%d ",pfile->fileCurpos%Block_Size);
pfile->Buffer[(pfile->fileCurpos++)%Block_Size]=*WriteBuffer;
WriteBuffer++;
pfile->filebufnum++;
if(pfile->filebufnum>=Block_Size){ //超过一个block大小
//by threewater-------->
// Erase_FileCluster(Current_Block-1);//by threewater
Erase_FileCluster(Current_Cluster);//by threewater
for(j=0;j<SecPerClus;j++) WritePage(Begin_Cluster+(2*Current_Cluster-2)+j/PagePerClus,j%PagePerClus,&pfile->Buffer[j*512]);
pfile->filebufnum=0;
Pre_Cluster=pfile->fileCluster;
pfile->fileCluster=Current_Cluster=NextCluster(pfile->fileCluster);
if(((pfile->fileCluster&0xffff)==0xffff)||((pfile->fileCluster&0xfff)==0xfff)||(pfile->fileCluster==0xffffffff))
pfile->fileCluster=Current_Cluster=AllocateCluster(Pre_Cluster);
DPRINTK("\nPre is %d,Amc:%d",Pre_Cluster,Current_Cluster);
// //满一簇,应该直接分配新的空间,sep 29 by frank
// pfile->fileCluster=AllocateCluster(pfile->fileCluster);
if(pfile->fileCluster==0)
{
pfile->filesize+=i; //by frank
return FALSE;
}
// Write2MemFat(Pre_Block,Current_Block);//by frank,because the link have been established in AllocatedCluster
}
//<-----by threewater
}
if(pfile->fileCurpos>pfile->filesize) pfile->filesize+=nWritebyte; //by threewater
// pfile->filesize+=nWritebyte; //by threewater
return TRUE;
}
int CloseOSFile(OSFILE* pfile)
{
int j;
U32 Current_Cluster;
switch(pfile->filemode&0xf){
case FILEMODE_WRITE:
Current_Cluster=pfile->fileCluster;
// Erase_FileCluster(Current_Block-1);//by threewater
Erase_FileCluster(Current_Cluster);//by frank
//Current_Block was minused 1 in Erase_FileCluster
for(j=0;j<SecPerClus;j++) WritePage(Begin_Cluster+(2*Current_Cluster-2)+j/PagePerClus,j%PagePerClus,&pfile->Buffer[j*512]);
//写入root表<------add by threewater
FileSystemRoot[pfile->rootpos].filelength=pfile->filesize;
// printk("\nFilelength:%d",pfile->filesize);
//写入的时候有同名文件,删除原文件剩余的Cluster
// DeleteFATList(NextCluster(pfile->fileCluster));
//WriteFATFromMem();// write to Flash
//<--------add by threewater
WriteFATFromMem();// write to Flash
WriteFileRootFromMem();
break;
default:
break;
}
OSMemPut(pFileMem, pfile);
//<--------add by threewater
return TRUE;
}
//add by threeweter------------->
//得到指定位置的文件名(包括扩展名),文件位置自动下移
U8 GetNextFileName(U32 *filepos,char filename[])
{
int j;
for(j=*filepos; j<RootEntry; j++){
if(FileSystemRoot[j].filename[0]==0x00)
return FALSE;
if(FileSystemRoot[j].filename[0]!=OSFILE_DELETEMARK){ //找到有效的文件项
//memcpy(filename,&FileSystemRoot[j].filename,11);
memcpy(filename,&FileSystemRoot[j].filename,sizeof(char)*11);
filename[11]=0;
*filepos=j+1;
return TRUE;
}
}
return FALSE;
}
//得到指定位置的文件名(包括扩展名)和大小,文件位置自动下移
static U8 GetNextFNSize(U32 *filepos,char filename[],int *filesize)
{
int j;
for(j=*filepos; j<RootEntry; j++){
if(FileSystemRoot[j].filename[0]==0x00)
return FALSE;
if(FileSystemRoot[j].filename[0]!=OSFILE_DELETEMARK){ //找到有效的文件项
memcpy(filename,&FileSystemRoot[j].filename,11);
filename[11]=0;
if(filesize)
*filesize=FileSystemRoot[j].filelength;
*filepos=j+1;
return TRUE;
}
}
return FALSE;
}
//列出当前位置开始第一个指定扩展名的文件,如果没有,则返回FALSE
U8 ListNextFileName(U32 *filepos, char FileExName[],char filename[])
{
char tmpfilename[11];
for(;;){
if(!GetNextFileName(filepos,tmpfilename))
return FALSE;
if(MemcmpNoUpper(tmpfilename+8,FileExName, 3)==0){
strncpy(filename,tmpfilename,8);
filename[8]=0;
return TRUE;
}
else if(*filepos==512)
return FALSE;
}
}
//<--------add by threewater
int Init_FAT_Info(int AutoFormat)
{
INT8U err;
OSFILE *pfile;
///////////////////////////////////////////////////
//得到引导扇区所在扇区号,如果介质是不带分区的,则0扇区就是BootSector了。
if(ReadPage(Begin_Cluster,0,databuff)==FAIL){
printk("Failed to Read BPB\n");
return FALSE;
}
if(memcmp(databuff, BPB_Data, sizeof(BPB_Data))!=0){ //分区表错误
printk("File Partition Error!\n");
if (AutoFormat==1) //自动格式化
return Format_Fat12Media();
else
return FALSE;
}
if(!((databuff[0]==0xeb)&&(databuff[1]==0x3c)&&(databuff[2]==0x90))){ //通过判断EB ?? 90来看是否已经是BPB了
//带分区的介质
// BootSector=databuff[454]+databuff[455]*256+databuff[456]*(256*256)+databuff[457]*(256*256*256);
printk("\nFile System has error,BPB Sector have been broken.");
pfile=(OSFILE*)OSMemGet(pFileMem,&err);//由于需要缓冲区,故创建一个指针
ReadPage(0,0,databuff);
memcpy(pfile->Buffer,databuff,512);
Write2Flash(Begin_Cluster, BPB_Sector, BPB_Sector, pfile->Buffer);
OSMemPut(pFileMem, pfile);
ReadPage(Begin_Cluster,0,databuff);
if((databuff[0]==0xeb)&&(databuff[1]==0x3c)&&(databuff[2]==0x90))
printk("\nFile System has been repaired successfully.");
}
else BootSector=0;
///////////////////////////////////////////////////
////////////////////////////////////////////////
//得到保留扇区数,总扇区数,总扇区数/每簇扇区数得到簇数,是FAT类型的依据
ReadPage(Begin_Cluster,BootSector,databuff);
RsdSector=databuff[14]+databuff[15]*256;
SecPerClus=databuff[13];
BytesPerSec=databuff[12]*256+databuff[11];
TotalSector=(databuff[20]*256+databuff[19]);
TotalCapacity=TotalSector*BytesPerSec;
TotalCluster=TotalSector/SecPerClus;//FAT16的簇总数=扇区总数/每簇扇区数
// SectorofFatSize=((databuff[22]+databuff[23]*256)); by threewater 2003-12-4
SectorofFatSize=Fat_Sector_Num;
RootEntry=(databuff[18]*256+databuff[17]);
FirstDataSec=BootSector+RsdSector+(SectorofFatSize*2)+((RootEntry*32+(BytesPerSec-1))/BytesPerSec);
if(TotalCluster>65525){ //FAT32的扇区总数和FAT表项长度
FAT_TYPE=FAT32;
if(TotalSector==0) TotalSector=(databuff[32]+databuff[33]*256+databuff[34]*256*256+databuff[35]*256*256*256);
TotalCapacity=TotalSector*BytesPerSec;
TotalCluster=TotalSector/SecPerClus;
SectorofFatSize=(databuff[36]+databuff[37]*256+databuff[38]*256*256+databuff[39]*256*256*256);
if(SectorofFatSize>(TotalCluster*16/512)) SectorofFatSize=((databuff[22]+databuff[23]*256));
RootEntry=(databuff[44]*256+databuff[43]);
FirstDataSec=BootSector+RsdSector+(SectorofFatSize*2)+((RootEntry*32+(BytesPerSec-1))/BytesPerSec);
}
else if((TotalCluster>0)&&(TotalCluster<4085)) {//FAT12
FAT_TYPE=FAT12;
}
else { //FAT16
FAT_TYPE=FAT16;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -