📄 fat.c
字号:
if(FAT_ReadSector(FirstDirSector+cnt,buffer)){free(buffer);return 1;}
for(offset=0;offset<512;offset+=32)
{
item=(struct direntry *)(&buffer[offset]);
if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5) && (item->deAttributes != 0x0f))
{
for(i=0;i<11;i++)
{
if(buffer[offset+i]!=name[i])break;
}
if(i==11)
{
//return the parameter of the item
FileInfo->StartCluster = item->deStartCluster + (((unsigned long)item->deHighClust)<<16);//don't care
FileInfo->Size = item->deFileSize;
FileInfo->Attr = item->deAttributes;
FileInfo->Sector = FirstDirSector+cnt;
FileInfo->Offset = offset;
free(buffer);
return 0;
}
}
}
}
free(buffer);//release
}
else//other folders
{
tempclust=cluster;
while(1)
{
sector=(DWORD)FirstDataSector+(DWORD)(tempclust-2)*(DWORD)SectorsPerClust;//calculate the actual sector number
buffer=malloc(512);//apply memory
if(buffer==0)return 1;//if failed
for(cnt=0;cnt<SectorsPerClust;cnt++)
{
if(FAT_ReadSector(sector+cnt,buffer)){free(buffer);return 1;}
for(offset=0;offset<512;offset+=32)
{
item=(struct direntry *)(&buffer[offset]);
if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5) && (item->deAttributes != 0x0f))
{
for(i=0;i<11;i++)
{
if(buffer[offset+i]!=name[i])break;
}
if(i==11)
{
FileInfo->StartCluster = item->deStartCluster + (((unsigned long)item->deHighClust)<<16);//don't care
FileInfo->Size = item->deFileSize;
FileInfo->Attr = item->deAttributes;
FileInfo->Sector = sector+cnt;
FileInfo->Offset = offset;
free(buffer);
return 0;
}
}
}
}
free(buffer);//release
tempclust=FAT_NextCluster(tempclust);//next cluster
if((FAT32_Enable == 0 && tempclust == 0xffff) || tempclust == 0x0ffffff8 || tempclust == 0x0fffffff)break;
}
}
return 1;
}
//挑选一个未使用的记录项
//select the first unsed item in the given cluster
//for delete a foler or a file
unsigned char FAT_SelectOneItem(unsigned long cluster,struct FileInfoStruct *FileInfo)
{
BYTE *buffer;
DWORD tempclust;
DWORD sector;
unsigned int cnt;
unsigned int offset;
// unsigned char i;
struct direntry *item = 0;
if(cluster==0 && FAT32_Enable==0)// root directory
{
buffer=malloc(512);//apply memory
if(buffer==0)return 1;//if failed
for(cnt=0;cnt<RootDirSectors;cnt++)
{
if(FAT_ReadSector(FirstDirSector+cnt,buffer)){free(buffer);return 1;}
for(offset=0;offset<512;offset+=32)
{
item=(struct direntry *)(&buffer[offset]);
if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5) && (item->deAttributes != 0x0f))
{
//return the parameter of the item
FileInfo->StartCluster = item->deStartCluster + (((unsigned long)item->deHighClust)<<16);//don't care
FileInfo->Size = item->deFileSize;
FileInfo->Attr = item->deAttributes;
FileInfo->Sector = FirstDirSector+cnt;
FileInfo->Offset = offset;
free(buffer);
return 0;
}
}
}
free(buffer);//release
}
else//other folders
{
tempclust=cluster;
while(1)
{
sector=(DWORD)FirstDataSector+(DWORD)(tempclust-2)*(DWORD)SectorsPerClust;//calculate the actual sector number
buffer=malloc(512);//apply memory
if(buffer==0)return 1;//if failed
for(cnt=0;cnt<SectorsPerClust;cnt++)
{
if(FAT_ReadSector(sector+cnt,buffer)){free(buffer);return 1;}
for(offset=0;offset<512;offset+=32)
{
item=(struct direntry *)(&buffer[offset]);
if((item->deName[0] != 0x2e) && (item->deName[0] != 0x00) && (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
{
FileInfo->StartCluster = item->deStartCluster + (((unsigned long)item->deHighClust)<<16);//don't care
FileInfo->Size = item->deFileSize;
FileInfo->Attr = item->deAttributes;
FileInfo->Sector = sector+cnt;
FileInfo->Offset = offset;
free(buffer);
return 0;
}
}
}
free(buffer);//release
tempclust=FAT_NextCluster(tempclust);//next cluster
if((FAT32_Enable == 0 && tempclust == 0xffff) || tempclust == 0x0ffffff8 || tempclust == 0x0fffffff)break;
}
}
return 1;
}
//修改FAT表中响应的项
//modify the fat table item with "val","cluster" specify the location
unsigned char FAT_ModifyFAT(unsigned long cluster,unsigned long val)
{
BYTE buffer[512];
DWORD sector;
DWORD offset;
if(FAT32_Enable)offset = cluster/128;
else offset = cluster/256;
sector=FirstFATSector+offset;//calculate the actual sector
if(FAT_ReadSector(sector,buffer))return 1;//read fat table
if(FAT32_Enable)
{
offset=cluster%128;
offset<<=2;
buffer[offset+3]=val>>24;
buffer[offset+2]=val>>16;
buffer[offset+1]=val>>8;
buffer[offset]=val;
}
else
{
offset=cluster%256;//find the position
offset<<=1;
buffer[offset+1] = val>>8;
buffer[offset] = val;
}
//sector=buffer[offset+1];
// sector<<=8;
//sector+=buffer[offset];
if(FAT_WriteSector(sector,buffer))return 1;//write the first fat table
if(FAT_WriteSector(sector+FATsectors,buffer))return 1;//write the second fat table
return 0;//return the value
}
// make a dir
unsigned char FAT_MkDir(BYTE * dir)
{
BYTE name[11];
BYTE *p=dir;
BYTE deep=0;
WORD i,j;
DWORD cluster=0;
DWORD lastcluster;//cluster number of last directory
BYTE *buffer;
DWORD sector;
struct direntry *item;
if(FAT32_Enable)cluster=FirstDirClust;
if(*p != '\\')return 1;//invalid path
while(*p)
{
if(*p == '\\')
{
deep++;//the deepth of the path
}
p++;
}
p=dir;
for(i=0;i<deep-1;i++)
{
p++;
for(j=0;j<11;j++)name[j]=0x20;
j=0;
while(*p != '\\')
{
if((*p) >= 'a' && (*p) <= 'z')name[j] = (*p++)-0x20;
else name[j] = *p++;
j++;
}
if(FAT_FindItem(cluster,name, &FileInfo))return 1;//find the location of each directory
cluster = FileInfo.StartCluster;//point to next directory
}
p++;
for(j=0;j<11;j++)name[j]=0x20;
j=0;
while(*p)
{
if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
else name[j]=*p++;
j++;
}
lastcluster=cluster;//save as last directory
cluster=FAT_FindFreeCluster();//find a unused cluster
if(cluster==1)return 1;//error
if(FAT_FindFreeItem(lastcluster,&FileInfo))return 1;//find a unused item
buffer=malloc(512);
if(buffer==0)return 1;
if(FAT_ReadSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//read the sector which the item is in
item=(struct direntry *)(&buffer[FileInfo.Offset]);//pointer convert
for(j=0;j<8;j++)item->deName[j] = name[j];
for(j=0;j<3;j++)item->deExtension[j] = 0x20;
item->deAttributes = ATTR_DIRECTORY;
item->deLowerCase = LCASE_BASE | LCASE_EXT;
item->deCHundredth = 0x00;
item->deCTime[0] = 0x00;
item->deCTime[1] = 0x60;
item->deCDate[0] = 0x5c;
item->deCDate[1] = 0x09;
item->deADate[0] = 0x8e;
item->deADate[1] = 0x35;
item->deHighClust = cluster>>16;
item->deMTime[0] = 0x00;
item->deMTime[1] = 0x60;
item->deMDate[0] = 0x50;
item->deMDate[1] = 0x0a;
item->deStartCluster = cluster;
item->deFileSize = 0;
if(FAT_WriteSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//write the item
for(j=0;j<512;j++)buffer[j]=0x00;
sector=(DWORD)FirstDataSector+(DWORD)(cluster-2)*(DWORD)SectorsPerClust;
for(i=0;i<SectorsPerClust;i++)
{
if(FAT_WriteSector(sector+i,buffer)){free(buffer);return 1;}//clear the data in the directory
}
//create "." directory
item=(struct direntry *)(&buffer[0]);
item->deName[0] = '.';
for(j=1;j<8;j++)item->deName[j] = 0x20;
for(j=0;j<3;j++)item->deExtension[j] = 0x20;
item->deAttributes = ATTR_DIRECTORY;
item->deLowerCase = LCASE_BASE | LCASE_EXT;
item->deCHundredth = 0x00;
item->deCTime[0] = 0x00;
item->deCTime[1] = 0x60;
item->deCDate[0] = 0x5c;
item->deCDate[1] = 0x09;
item->deADate[0] = 0x8e;
item->deADate[1] = 0x35;
item->deHighClust = cluster>>16;
item->deMTime[0] = 0x00;
item->deMTime[1] = 0x60;
item->deMDate[0] = 0x50;
item->deMDate[1] = 0x0a;
item->deStartCluster = cluster;//the directory itself
item->deFileSize = 0;
//creat ".." directory
item=(struct direntry *)(&buffer[32]);
item->deName[0] = '.';
item->deName[1] = '.';
for(j=2;j<8;j++)item->deName[j] = 0x20;
for(j=0;j<3;j++)item->deExtension[j] = 0x20;//no extention
item->deAttributes = ATTR_DIRECTORY;//directory
item->deLowerCase = LCASE_BASE | LCASE_EXT;
item->deCHundredth = 0x00;
item->deCTime[0] = 0x00;
item->deCTime[1] = 0x60;
item->deCDate[0] = 0x5c;
item->deCDate[1] = 0x09;
item->deADate[0] = 0x8e;
item->deADate[1] = 0x35;
item->deHighClust = lastcluster>>16;
item->deMTime[0] = 0x00;
item->deMTime[1] = 0x60;
item->deMDate[0] = 0x50;
item->deMDate[1] = 0x0a;
item->deStartCluster = lastcluster;//last directory
item->deFileSize = 0;
if(FAT_WriteSector(sector,buffer)){free(buffer);return 1;}//write the data
free(buffer);
if(FAT32_Enable)
{
if(FAT_ModifyFAT(cluster,0x0fffffff))return 1;//modify the fat table to sign that the cluster was used
}
else
{
if(FAT_ModifyFAT(cluster,0xffff))return 1;//modify the fat table to sign that the cluster was used
}
return 0;//done
}
// remove a directory
unsigned char FAT_RmDir(BYTE * dir)
{
if(FAT_OpenDir(dir)==0)return 1;//find the directory
if(FAT_DelItem(&FileInfo))return 1;//delete it
return 0;
}
// creat a file, for convenience we designate the size
// return the start sector of the new file
unsigned long FAT_Create(BYTE * dir,unsigned long size)
{
BYTE name[11];
BYTE *p=dir;
BYTE deep=0;
BYTE i,j;
DWORD cluster=0;
BYTE *buffer;
//WORD sector;
struct direntry *item;
if(FAT32_Enable)cluster=FirstDirClust;
if(*p != '\\')return 1;//invalid path
while(*p)
{
if(*p == '\\')
{
deep++;
}
p++;
}
p=dir;
for(i=0;i<deep-1;i++)
{
p++;
for(j=0;j<11;j++)name[j]=0x20;
j=0;
while(*p != '\\')
{
if((*p) >= 'a' && (*p) <= 'z')name[j] = (*p++)-0x20;
else name[j] = *p++;
j++;
}
if(FAT_FindItem(cluster,name, &FileInfo))return 1;
cluster = FileInfo.StartCluster;
}
p++;
for(j=0;j<11;j++)name[j]=0x20;
j=0;
while(*p != '.')
{
if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
else name[j]=*p++;
j++;
}
j=8;
p++;
while(*p)
{
if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
else name[j]=*p++;
j++;
}
if(FAT_FindFreeItem(cluster,&FileInfo))return 1;
cluster = FAT_FindFreeCluster();
if(cluster==1)return 1;
buffer=malloc(512);
if(buffer==0)return 1;
if(FAT_ReadSector(FileInfo.Sector,buffer)){free(buffer);return 1;}
item=(struct direntry *)(&buffer[FileInfo.Offset]);
for(j=0;j<8;j++)item->deName[j] = name[j];
for(j=0;j<3;j++)item->deExtension[j] = name[8+j];
item->deAttributes = ATTR_ARCHIVE;//file
item->deLowerCase = LCASE_BASE | LCASE_EXT;
item->deCHundredth = 0x00;
item->deCTime[0] = 0x00;
item->deCTime[1] = 0x60;
item->deCDate[0] = 0x5c;
item->deCDate[1] = 0x09;
item->deADate[0] = 0x8e;
item->deADate[1] = 0x35;
item->deHighClust = cluster>>16;
item->deMTime[0] = 0x00;
item->deMTime[1] = 0x60;
item->deMDate[0] = 0x50;
item->deMDate[1] = 0x0a;
item->deStartCluster = cluster;//the cluster number the file was stored
item->deFileSize = size;//the file size
if(FAT_WriteSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//write the item
free(buffer);
if(FAT32_Enable)
{
if(FAT_ModifyFAT(cluster,0x0fffffff))return 1;//modify the fat table to sign that the cluster was used
}
else
{
if(FAT_ModifyFAT(cluster,0xffff))return 1;//modify the fat table
}
return cluster;//reutn the first cluster number
}
// find the location with the given path
unsigned long FAT_Open(BYTE * dir)
{
BYTE name[11];
BYTE *p=dir;
BYTE deep=0;
BYTE i,j;
DWORD cluster=0;
if(FAT32_Enable)cluster=FirstDirClust;
if(*p != '\\')return 1;//invalid path
while(*p)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -