📄 fat16.c
字号:
{
tempclust=cluster;
while(1)
{
sector=FirstDataSector+(U32)(tempclust-2)*(U32)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(FAT16_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;
FileInfo->Size = item->deFileSize;
FileInfo->Attr = item->deAttributes;
FileInfo->Sector = sector+cnt;
FileInfo->Offset = offset;
free(buffer);
return 0;
}
}
}
free(buffer);//release
tempclust=FAT16_NextCluster(tempclust);//next cluster
if(tempclust == 0xffff || tempclust == 0xfff8)break;
}
}
return 1;
}
//修改FAT表中响应的项
//modify the fat table item with "val","cluster" specify the location
unsigned char FAT16_ModifyFAT(U16 cluster,U16 val)
{
U8 buffer[512];
U32 sector;
U32 offset=cluster/256;
sector=FirstFATSector+offset;//calculate the actual sector
if(FAT16_ReadSector(sector,buffer))return 1;//read fat table
offset=cluster%256;//find the position
offset<<=1;
//sector=buffer[offset+1];
// sector<<=8;
//sector+=buffer[offset];
buffer[offset+1] = val>>8;
buffer[offset] = val;
if(FAT16_WriteSector(sector,buffer))return 1;//write the first fat table
if(FAT16_WriteSector(sector+FATsectors,buffer))return 1;//write the second fat table
return 0;//return the value
}
// make a dir
unsigned char FAT16_MkDir(U8 * dir)
{
U8 name[11];
U8 *p=dir;
U8 deep=0;
U16 i,j;
U32 cluster=0;
U32 lastcluster;//cluster number of last directory
U8 *buffer;
U16 sector;
struct direntry *item;
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(FAT16_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=FAT16_FindFreeCluster();//find a unused cluster
if(cluster==1)return 1;//error
if(FAT16_FindFreeItem(lastcluster,&FileInfo))return 1;//find a unused item
buffer=malloc(512);
if(buffer==0)return 1;
if(FAT16_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 = 0;
item->deCTime[0] = 0;
item->deCTime[1] = 0;
item->deCDate[0] = 0;
item->deCDate[1] = 0;
item->deADate[0] = 0;
item->deADate[1] = 0;
item->deHighClust = 0;
item->deMTime[0] = 0;
item->deMTime[1] = 0;
item->deMDate[0] = 0;
item->deMDate[1] = 0;
item->deStartCluster = cluster;
item->deFileSize = 0;
if(FAT16_WriteSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//write the item
for(j=0;j<512;j++)buffer[j]=0x00;
sector=FirstDataSector+(U32)(cluster-2)*(U32)SectorsPerClust;
for(i=0;i<SectorsPerClust;i++)
{
if(FAT16_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 = 0;
item->deCTime[0] = 0;
item->deCTime[1] = 0;
item->deCDate[0] = 0;
item->deCDate[1] = 0;
item->deADate[0] = 0;
item->deADate[1] = 0;
item->deHighClust = 0;
item->deMTime[0] = 0;
item->deMTime[1] = 0;
item->deMDate[0] = 0;
item->deMDate[1] = 0;
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 = 0;
item->deCTime[0] = 0;
item->deCTime[1] = 0;
item->deCDate[0] = 0;
item->deCDate[1] = 0;
item->deADate[0] = 0;
item->deADate[1] = 0;
item->deHighClust = 0;
item->deMTime[0] = 0;
item->deMTime[1] = 0;
item->deMDate[0] = 0;
item->deMDate[1] = 0;
item->deStartCluster = lastcluster;//last directory
item->deFileSize = 0;
if(FAT16_WriteSector(sector,buffer)){free(buffer);return 1;}//write the data
free(buffer);
if(FAT16_ModifyFAT(cluster,0xffff))return 1;//modify the fat table to sign that the cluster was used
return 0;//done
}
// remove a directory
unsigned char FAT16_RmDir(U8 * dir)
{
if(FAT16_OpenDir(dir)==0)return 1;//find the directory
if(FAT16_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
U16 FAT16_Create(U8 * dir,U32 size)
{
U8 name[11];
U8 *p=dir;
U8 deep=0;
U8 i,j;
U32 cluster=0;
U8 *buffer;
//U16 sector;
struct direntry *item;
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(FAT16_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(FAT16_FindFreeItem(cluster,&FileInfo))return 1;
cluster = FAT16_FindFreeCluster();
if(cluster==1)return 1;
buffer=malloc(512);
if(buffer==0)return 1;
if(FAT16_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 = 0;
item->deCTime[0] = 0;
item->deCTime[1] = 0;
item->deCDate[0] = 0;
item->deCDate[1] = 0;
item->deADate[0] = 0;
item->deADate[1] = 0;
item->deHighClust = 0;
item->deMTime[0] = 0;
item->deMTime[1] = 0;
item->deMDate[0] = 0;
item->deMDate[1] = 0;
item->deStartCluster = cluster;//the cluster number the file was stored
item->deFileSize = size;//the file size
if(FAT16_WriteSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//write the item
free(buffer);
if(FAT16_ModifyFAT(cluster,0xffff))return 1;//modify the fat table
return cluster;//reutn the first cluster number
}
// find the location with the given path
U16 FAT16_Open(U8 * dir)
{
U8 name[11];
U8 *p=dir;
U8 deep=0;
U8 i,j;
U32 cluster=0;
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(FAT16_FindItem(cluster,name, &FileInfo))return 1;//find the directory
cluster = FileInfo.StartCluster;
}
p++;
for(j=0;j<11;j++)name[j]=0x20;
j=0;
while(*p != '.')//file must have a extention
{
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(FAT16_FindItem(cluster,name, &FileInfo))return 1;//find the file
cluster = FileInfo.StartCluster;
return cluster;
}
// find a directory with the given path
U16 FAT16_OpenDir(U8 * dir)
{
U8 name[11];
U8 *p=dir;
U8 deep=0;
U8 i,j;
U32 cluster=0;
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(FAT16_FindItem(cluster,name, &FileInfo))return 1;//find the directory
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++;
}
if(j == 0)return 0;
if(FAT16_FindItem(cluster,name, &FileInfo))return 1;//find the final directory
cluster = FileInfo.StartCluster;
return cluster;
}
U16 FAT16_Close(U16 * p)
{
*p=1;
return 0;
}
// Output the data of a file
// size 0 means read all of the file
unsigned char FAT16_Read(U16 pointer, U32 size)
{
U32 sector;
U32 tempclust=pointer;
U8 *buffer;
U16 i=0,j=0;
sector=FirstDataSector+(U32)(tempclust-2)*(U32)SectorsPerClust;
if(size==0)size = FileInfo.Size;//whether need to read all
USART_putchar(0x0d);
USART_putchar(0x0a);//new line
while(size)
{
buffer=malloc(512);
if(FAT16_ReadSector(sector+j,buffer)){free(buffer);return 1;}
if(size<=512)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -