/********************************************************** * base.c //added by mingxuan 2019-5-17 ***********************************************************/ #include "fat32.h" #include "type.h" #include "const.h" #include "protect.h" #include "string.h" #include "proc.h" #include "tty.h" #include "console.h" #include "global.h" #include "proto.h" #include "fs_const.h" #include "hd.h" #include "fs.h" #include "fs_misc.h" DWORD FAT_END=268435455;//文件簇号结束标记 DWORD TotalSectors=0;//总扇区数,当载入磁盘时,才从DBR中读取。 WORD Bytes_Per_Sector=0;//每个扇区的字节数,当载入磁盘时,才从DBR中读取。 BYTE Sectors_Per_Cluster=0;//每个簇的扇区数,当载入磁盘时,才从DBR中读取。 WORD Reserved_Sector=0;//保留扇区数,当载入磁盘时,才从DBR中读取。 DWORD Sectors_Per_FAT=0;//每个FAT所占的扇区数,当载入磁盘时,才从DBR中读取。 UINT Position_Of_RootDir=0;//根目录的位置。 UINT Position_Of_FAT1=0;//FAT1的位置。 UINT Position_Of_FAT2=0;//FAT2的位置。 extern CHAR cur_path[256]; BYTE FATBuf[1024]={0}; DWORD globalSectorIndex=-1; void ReadSector(BYTE* buf,DWORD sectorIndex) { int fat32_dev = get_fs_dev(PRIMARY_MASTER, FAT32_TYPE); //added by mingxuan 2020-10-27 //RD_SECT_SCHED_FAT(buf, sectorIndex); // deleted by mingxuan 2020-10-27 RD_SECT_SCHED_FAT(fat32_dev, buf, sectorIndex); // modified by mingxuan 2020-10-27 } void WriteSector(BYTE* buf,DWORD sectorIndex) { if(sectorIndex==globalSectorIndex) { memcpy(FATBuf,buf,512);//写FAT表的缓冲区,保持数据同步 } int fat32_dev = get_fs_dev(PRIMARY_MASTER, FAT32_TYPE); //added by mingxuan 2020-10-27 //WR_SECT_SCHED_FAT(buf, sectorIndex); // deleted by mingxuan 2020-10-27 WR_SECT_SCHED_FAT(fat32_dev, buf, sectorIndex); // modified by mingxuan 2020-10-27 } void DeleteAllRecord(DWORD startCluster) { PBYTE buf=NULL; Record record; DWORD off=0; DWORD curClusterIndex=startCluster,nextClusterIndex=0,start=0; DWORD curSectorIndex=0,preSectorIndex=0,off_in_sector=0,last=0; if(startCluster==2) { off=Position_Of_RootDir+(startCluster-2)*Sectors_Per_Cluster*Bytes_Per_Sector+sizeof(Record); }else{ off=Position_Of_RootDir+(startCluster-2)*Sectors_Per_Cluster*Bytes_Per_Sector+2*sizeof(Record); } buf = (PBYTE)K_PHY2LIN(sys_kmalloc(Bytes_Per_Sector*sizeof(BYTE))); last=Reserved_Sector+2*Sectors_Per_FAT+(startCluster-2)*Sectors_Per_Cluster+Sectors_Per_Cluster; do { curSectorIndex=off/Bytes_Per_Sector; off_in_sector=off%Bytes_Per_Sector; if(curSectorIndex!=preSectorIndex) { if(preSectorIndex!=0) { WriteSector(buf,preSectorIndex); } ReadSector(buf,curSectorIndex); preSectorIndex=curSectorIndex; } memcpy(&record,buf+off_in_sector,sizeof(Record)); if(record.filename[0]==0) { WriteSector(buf,curSectorIndex); break; } if(record.filename[0]!=(BYTE)0xE5&&record.filename[0]!=0) { record.filename[0]=(BYTE)0xE5; memcpy(buf+off_in_sector,&record,sizeof(Record)); start=(DWORD)(record.highClusterNum<<16)+(DWORD)record.lowClusterNum; if(record.proByte==(BYTE)0x10)//是子目录 { DeleteAllRecord(start);//删除此子目录 }else{ ClearFATs(start); } } preSectorIndex=curSectorIndex; if(curSectorIndex>=last) { GetNextCluster(curClusterIndex,&nextClusterIndex); if(nextClusterIndex==FAT_END) { WriteSector(buf,curSectorIndex); break; }else{ curClusterIndex=nextClusterIndex; off=Position_Of_RootDir+(curClusterIndex-2)*Sectors_Per_Cluster*Bytes_Per_Sector; } }else{ off+=sizeof(Record); } }while(1); sys_free(buf); ClearFATs(startCluster); } STATE FindClusterForDir(PDWORD pcluster) { PBYTE buf=NULL; DWORD clusterIndex=2,nextClusterIndex=0; DWORD curSectorIndex=0,last=0,offset=0; buf = (PBYTE)K_PHY2LIN(sys_kmalloc(Bytes_Per_Sector*sizeof(BYTE))); if(buf==NULL) { return SYSERROR; } curSectorIndex=Reserved_Sector; last=curSectorIndex+Sectors_Per_FAT; offset=8; for(;curSectorIndexsize%Bytes_Per_Sector==0) { totalSectors=pfile->size/Bytes_Per_Sector; }else{ totalSectors=pfile->size/Bytes_Per_Sector+1; } sectorNum=pfile->off/Bytes_Per_Sector+1; if(off_in_sector!=NULL) { (*off_in_sector)=pfile->off%Bytes_Per_Sector; } curSectorIndex=Reserved_Sector+2*Sectors_Per_FAT+(pfile->start-2)*Sectors_Per_Cluster; do { counter++; if(counter==sectorNum) { if(totalSectors==1) { *sectorIndex=curSectorIndex; *isLastSector=1; }else{ *sectorIndex=curSectorIndex; } break; } GetNextSector(pfile,curSectorIndex,&nextSectorIndex,isLastSector); curSectorIndex=nextSectorIndex; }while(1); } void GetNextSector(PFile pfile,DWORD curSectorIndex,PDWORD nextSectorIndex,PUINT isLastSector) { DWORD temp=0; DWORD curClusterIndex=0,nextClusterIndex=0,last=0; BYTE off_in_cluster=0; temp=curSectorIndex-Reserved_Sector-2*Sectors_Per_FAT; curClusterIndex=temp/Sectors_Per_Cluster+2;//此扇区所在的簇 off_in_cluster=(BYTE)(temp%Sectors_Per_Cluster);//此扇区是所在簇的的几个扇区,从零开始 GetNextCluster(curClusterIndex,&nextClusterIndex); if(nextClusterIndex==FAT_END)//此扇区所在簇是该文件的最后一个簇 { if(pfile->flag==R) { temp=pfile->size%(Sectors_Per_Cluster*Bytes_Per_Sector); if(temp==0)//此文件实际占用了整数个簇 { last=Sectors_Per_Cluster; }else{ if(temp%Bytes_Per_Sector==0) { last=temp/Bytes_Per_Sector; }else{ last=temp/Bytes_Per_Sector+1;//最后一簇实际占用的扇区数 } } }else{ last=Sectors_Per_Cluster; } if(off_in_clusterflag==R) { temp=pfile->size%(Sectors_Per_Cluster*Bytes_Per_Sector); if(temp!=0)//此文件实际占用了整数个簇 { last=temp/Bytes_Per_Sector+1;//最后一簇实际占用的扇区数 if(last==1)//最后一簇实际上只占用了一个扇区 { *isLastSector=1;//那么当前返回的扇区就是此文件的最后一个扇区 }else{ *isLastSector=0; } } } } } } STATE GetNextCluster(DWORD clusterIndex,PDWORD nextCluster) { DWORD sectorIndex=0,offset=0,off_in_sector=0; offset=8+(clusterIndex-2)*sizeof(DWORD); sectorIndex=Reserved_Sector+offset/Bytes_Per_Sector; off_in_sector=offset%Bytes_Per_Sector; if(sectorIndex!=globalSectorIndex) { ReadSector(FATBuf,sectorIndex); globalSectorIndex=sectorIndex; } memcpy(nextCluster,FATBuf+off_in_sector,sizeof(DWORD)); return OK; } STATE ReadRecord(DWORD parentCluster,PCHAR name,PRecord record,PDWORD sectorIndex,PDWORD off_in_sector) { CHAR temp[256]={0}; DWORD curSectorIndex=0,curClusterIndex=parentCluster,off=0,size_of_Record; BYTE *buf; UINT last=0; size_of_Record=sizeof(Record); buf = (PBYTE)K_PHY2LIN(sys_kmalloc(Bytes_Per_Sector*sizeof(BYTE))); do { curSectorIndex=Reserved_Sector+2*Sectors_Per_FAT+(curClusterIndex-2)*Sectors_Per_Cluster; last=curSectorIndex+8; for(;curSectorIndexfilename[0]==0)//没有此目录项 { sys_free(buf); return WRONGPATH; } memset(temp,0,sizeof(temp)); // if(record->sysReserved==0x18)//是长文件名文件的短目录项 // { // do // { // memcpy(&lrecord,buf+off,size_of_Record); // strcpy(temp+offinlongname,lrecord.name1); // offinlongname+=10; // strcpy(temp+offinlongname,lrecord.name2); // offinlongname+=19; // if(lrecord.proByte&0x40!=0) // { // break; // } // if(off>=Bytes_Per_Sector) // { // ReadSector(buf,curSectorIndex); // off=0; // } // }while(1); // }else{ // GetNameFromRecord(*record,temp); // } GetNameFromRecord(*record,temp); if(strcmp(temp,name)==0) { if(sectorIndex!=NULL) { *sectorIndex=curSectorIndex; } if(off_in_sector!=NULL) { *off_in_sector=off; } sys_free(buf); return OK; } } } // GetNextCluster(curClusterIndex,&nextClusterIndex); // if(nextClusterIndex==FAT_END) // { // sys_free(buf); // return WRONGPATH; // }else{ // curClusterIndex=nextClusterIndex; // } }while(1); } void ClearFATs(DWORD startClusterIndex) { PBYTE buf=NULL; DWORD curClusterIndex=startClusterIndex,nextClusterIndex=0; DWORD curSectorIndex=0,preSectorIndex=0,temp=0,offset=0; DWORD clear=0; if(startClusterIndex==0) { return; } buf = (PBYTE)K_PHY2LIN(sys_kmalloc(Bytes_Per_Sector*sizeof(BYTE))); do { temp=(curClusterIndex-2)*sizeof(DWORD)+8; curSectorIndex=Reserved_Sector+temp/Bytes_Per_Sector; offset=temp%Bytes_Per_Sector; if(curSectorIndex!=preSectorIndex) { if(preSectorIndex!=0)//不是第一个扇区 { WriteSector(buf,preSectorIndex); } preSectorIndex=curSectorIndex; ReadSector(buf,curSectorIndex); } memcpy(&nextClusterIndex,buf+offset,sizeof(DWORD)); curClusterIndex=nextClusterIndex; memcpy(buf+offset,&clear,sizeof(DWORD)); preSectorIndex=curSectorIndex; }while(curClusterIndex!=FAT_END); WriteSector(buf,curSectorIndex); sys_free(buf); } STATE ClearRecord(DWORD parentCluster,PCHAR name,PDWORD startCluster) { Record record; DWORD startClusterIndex=0,sectorIndex=0,off_in_sector=0; STATE state; state=ReadRecord(parentCluster,name,&record,§orIndex,&off_in_sector); if(state!=OK) { return state; } record.filename[0]=(BYTE)0xE5; startClusterIndex=((DWORD)record.highClusterNum<<16)+(DWORD)record.lowClusterNum; WriteRecord(record,sectorIndex,off_in_sector); *startCluster=startClusterIndex; return OK; } STATE PathToCluster(PCHAR path, PDWORD cluster) { UINT i=0,j=0,len=0; CHAR name[256]={0}; CHAR fullpath[256]={0}; Record record; DWORD parentCluster=2; STATE state; ToFullPath(path,fullpath); len=strlen(fullpath); for(i=0;i=len)//说明是根目录 { *cluster=2; return OK; } j=0; for(i=i+1;i=Bytes_Per_Sector) { ReadSector(buf,curSectorIndex); offset=0; } }while(1); } else { if(record.proByte!=(BYTE)0x08)//不是卷标 { GetNameFromRecord(record,fullname); if(strcmp(name,fullname)==0)//有重名的文件或目录 { sys_free(buf); return NAMEEXIST; } } } } } }while(1); } void GetNameFromRecord(Record record,PCHAR fullname) { UINT i=0,j=0,point=0; for(i=0;i<8;i++) { if(record.filename[i]==' ') { break; } if(record.filename[i]>='A'&&record.filename[i]<='Z') { fullname[j++]=record.filename[i]+32; }else{ fullname[j++]=record.filename[i]; } } point=j; fullname[j++]='.'; for(i=0;i<3;i++) { if(record.extension[i]>='A'&&record.extension[i]<='Z') { fullname[j++]=record.extension[i]+32; }else{ fullname[j++]=record.extension[i]; } } for(j=j-1;j>=0;j--)//去掉后面的空格 { if(fullname[j]==' '||(fullname[j]=='.'&&j==point)) { fullname[j]=0; }else{ break; } } } void CreateRecord(PCHAR filename,BYTE type,DWORD startCluster,DWORD size,PRecord precord) { WORD time[2]; CHAR name[256]={0}; CHAR ext[256]={0}; if(type==(BYTE)0x08||type==(BYTE)0x10) { FormatDirNameAndExt(filename,name,ext); precord->sysReserved=0x08; }else{ FormatFileNameAndExt(filename,name,ext); precord->sysReserved=0x18; } TimeToBytes(time);//获取当前时间 strcpy((char *)precord->filename,name); strcpy((char *)precord->extension,ext); precord->proByte=type; precord->createMsecond=0; precord->createTime=time[1]; precord->createDate=time[0]; precord->lastAccessDate=time[0]; precord->highClusterNum=(WORD)(startCluster>>16); precord->lastModifiedTime=time[1]; precord->lastModifiedDate=time[0]; precord->lowClusterNum=(WORD)(startCluster&0x0000ffff); precord->filelength=size; } STATE WriteRecord(Record record,DWORD sectorIndex,DWORD off_in_sector) { BYTE *buf=NULL; buf = (PBYTE)K_PHY2LIN(sys_kmalloc(Bytes_Per_Sector*sizeof(BYTE))); ReadSector(buf,sectorIndex); memcpy(buf+off_in_sector,&record,sizeof(Record)); WriteSector(buf,sectorIndex); sys_free(buf); return OK; } STATE WriteFAT(DWORD totalclusters,PDWORD clusters) { PBYTE buf=NULL; DWORD i=0,curSectorIndex=0,preSectorIndex=0,offset=0,off_in_sector=0; buf = (PBYTE)K_PHY2LIN(sys_kmalloc(Bytes_Per_Sector*sizeof(BYTE))); if(buf==NULL) { return SYSERROR; } for(i=0;istart=clusters[0]; WriteFAT(n,clusters); sys_free(clusters); return OK; } STATE AddCluster(DWORD startClusterIndex,DWORD num)//cluster表示该文件或目录所在目录的簇,num表示增加几个簇 { PDWORD clusters=NULL; DWORD curClusterIndex=startClusterIndex,nextClusterIndex=0; // DWORD bytes_per_sector=Sectors_Per_FAT*Bytes_Per_Sector; STATE state; clusters = (PDWORD)K_PHY2LIN(sys_kmalloc((num+1)*sizeof(DWORD))); if(clusters==NULL) { return SYSERROR; } state=FindClusterForFile(num,clusters+1); if(state!=OK) { return state; } do { GetNextCluster(curClusterIndex,&nextClusterIndex); if(nextClusterIndex==FAT_END) { clusters[0]=curClusterIndex; break; }else{ curClusterIndex=nextClusterIndex; } }while(1); WriteFAT(num+1,clusters); sys_free(clusters); return OK; } STATE NeedMoreCluster(PFile pfile,DWORD size,PDWORD number) { DWORD n=0,clusterNum,bytes_per_cluster=0; bytes_per_cluster=Sectors_Per_Cluster*Bytes_Per_Sector; if(pfile->off == 0) { return FALSE; } if(pfile->off%bytes_per_cluster==0)//clusterNum是实际占用的簇的个数 { clusterNum=pfile->off/bytes_per_cluster; }else{ clusterNum=pfile->off/bytes_per_cluster+1; } if(size>clusterNum*bytes_per_cluster-pfile->off)//空间不足需要追加更多的簇 { if((size-(clusterNum*bytes_per_cluster-pfile->off))%bytes_per_cluster==0) { n=(size-(clusterNum*bytes_per_cluster-pfile->off))/bytes_per_cluster; }else{ n=(size-(clusterNum*bytes_per_cluster-pfile->off))/bytes_per_cluster+1; } *number=n; return TRUE;//表示还需要n簇 } return FALSE;//表示目前空间够用,不需要更多的簇 } STATE FindClusterForFile(DWORD totalClusters,PDWORD clusters) { PBYTE buf=NULL; DWORD clusterIndex=1,nextClusterIndex=0; UINT index=0,i=0,j=0; DWORD curSectorIndex=0,off_in_sector=0; buf = (PBYTE)K_PHY2LIN(sys_kmalloc(Bytes_Per_Sector*sizeof(BYTE))); if(buf==NULL) { return SYSERROR; } curSectorIndex=Reserved_Sector; off_in_sector=8; do { ReadSector(buf,curSectorIndex); for(i=off_in_sector;i=totalClusters)//找够了 { sys_free(buf); for(j=0;j=Position_Of_FAT2) { sys_free(buf); return INSUFFICIENTSPACE; }else{ curSectorIndex++; off_in_sector=0; } }while(1); } void ClearClusters(DWORD cluster) { BYTE buf[512]={0}; UINT sectorIndex=0; UINT first=0,last=0; first=Reserved_Sector+2*Sectors_Per_FAT+(cluster-2)*Sectors_Per_Cluster; last=first+8; for(sectorIndex=first;sectorIndex