|
楼主 |
发表于 2012-2-13 15:34:24
|
显示全部楼层
哪一个地方啊? 下面是bozai的fat
#include "include.h"
DWORD FirstDirClust; //first directory cluster
DWORD FirstDataSector; // The first sector number of data
WORD BytesPerSector; // Bytes per sector
DWORD FATsectors; // The amount sector a FAT occupied
WORD SectorsPerClust; // Sector per cluster
DWORD FirstFATSector; // The first FAT sector
DWORD FirstDirSector; // The first Dir sector
DWORD RootDirSectors; // The sector number a Root dir occupied
DWORD RootDirCount; // The count of directory in root dir
BYTE FAT32_Enable;
BYTE TABLE_READ = 0;
DWORD START_CLUSTER = 0x0ffffff8; //when the mcu has large ram
//BYTE FAT_TABLE[512]; //when the mcu has large ram
BYTE LongNameBuffer[MAX_LONG_NAME_SIZE];
BYTE LongNameFlag = 0;
BYTE (* FAT_ReadSector)(DWORD,BYTE *);
BYTE (* FAT_WriteSector)(DWORD,BYTE *);
DWORD (* FAT_ReadCapacity)(void);
//函数指针指向sd卡的读写函数
struct FileInfoStruct FileInfo;//temporarily buffer for file information
//FAT初始化,不含SD的初始化,用之前应先调用sd的初始化
unsigned char FAT_Init()//Initialize of FAT need initialize SD first
{
struct bootsector710 *bs = 0;
struct bpb710 *bpb = 0;
// struct partsector *ps = 0;
struct partrecord *pr = 0;
BYTE buffer[512];
DWORD hidsec=0;
DWORD Capacity;
Capacity = FAT_ReadCapacity();
if(Capacity<0xff)return 1;
if(FAT_ReadSector(0,buffer))return 1;
bs = (struct bootsector710 *)buffer;
pr = (struct partrecord *)((struct partsector *)buffer)->psPart;//first partition
hidsec = pr->prStartLBA;//the hidden sectors
if(hidsec >= Capacity/512)
{
hidsec = 0;
}
else
{
if(FAT_ReadSector(pr->prStartLBA,buffer))return 1;//read the bpb sector
bs = (struct bootsector710 *)buffer;
if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)
{
hidsec = 0;
if(FAT_ReadSector(0,buffer))return 1;//read the bpb sector
bs = (struct bootsector710 *)buffer;
}
}
if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)//对付没有bootsect的sd卡 //dead with the card which has no bootsect
{
return 1;
}
bpb = (struct bpb710 *)bs->bsBPB;
if(bpb->bpbFATsecs)//detemine thd FAT type //do not support FAT12
{
FAT32_Enable=0; //FAT16
FATsectors = bpb->bpbFATsecs;//FAT占用的扇区数 //the sectors number occupied by one fat talbe
FirstDirClust = 2;
}
else
{
FAT32_Enable=1; //FAT32
FATsectors = bpb->bpbBigFATsecs;//FAT占用的扇区数 //the sectors number occupied by one fat talbe
FirstDirClust = bpb->bpbRootClust;
}
BytesPerSector = bpb->bpbBytesPerSec;//每扇区字节数
SectorsPerClust = (BYTE)bpb->bpbSecPerClust;//每簇扇区数
FirstFATSector = bpb->bpbResSectors+hidsec;//第一个FAT表扇区
RootDirCount = bpb->bpbRootDirEnts;//根目录项数
RootDirSectors = (RootDirCount*32)>>9;//根目录占用的扇区数
FirstDirSector = FirstFATSector+bpb->bpbFATs*FATsectors;//第一个目录扇区
FirstDataSector = FirstDirSector+RootDirSectors;//第一个数据扇区
return 0;
}
//读一个簇中的一个扇区
unsigned char FAT_LoadPartCluster(unsigned long cluster,unsigned part,BYTE * buffer)
{
DWORD sector;
sector=(DWORD)FirstDataSector+(DWORD)(cluster-2)*(DWORD)SectorsPerClust;//calculate the actual sector number
if(FAT_ReadSector(sector+part,buffer))return 1;
else return 0;
}
/*
//读整个簇
//Read the a cluster
//Not suitable for system which has few data RAM
unsigned char FAT_LoadCluster(unsigned long cluster,BYTE * buffer)
{
DWORD sector;
unsigned char i;
sector=FirstDataSector+(DWORD)(cluster-2)*(DWORD)SectorsPerClust;//calculate the actual sector number
for(i=0;i<SectorsPerClust;i++)
{
if(FAT_ReadSector(sector+i,buffer+(i<<9)))break;
}
if(i==SectorsPerClust)return 0;
else return 1;
}*/
//读下一簇簇号
//Return the cluster number of next cluster of file
//Suitable for system which has limited RAM
unsigned long FAT_NextCluster(unsigned long cluster)
{
BYTE buffer[512];
DWORD sector;
DWORD offset;
if(FAT32_Enable)offset = cluster/128;
else offset = cluster/256;
if(cluster<2)return 0x0ffffff8;
sector=FirstFATSector+offset;//calculate the actual sector
if(FAT_ReadSector(sector,buffer))return 0x0ffffff8;//read fat table / return 0xfff8 when error occured
if(FAT32_Enable)
{
offset=cluster%128;//find the position
sector=((unsigned long *)buffer)[offset];
}
else
{
offset=cluster%256;//find the position
sector=((unsigned int *)buffer)[offset];
}
return (unsigned long)sector;//return the cluste number
}
/*unsigned long FAT_NextCluster_NEW(unsigned long cluster)
{
//BYTE buffer[512];
BYTE temp;
DWORD sector;
DWORD offset;
if(cluster<2)return 0x0ffffff8;
if(FAT32_Enable)temp = 127;
else temp = 255;
offset = cluster/(temp+1);
sector=FirstFATSector+offset;//calculate the actual sector where the FAT placed
offset=cluster%(temp+1);//find the position //计算出在表中的偏移量
cluster -= offset;//找出需要的起始位置 ,以便于当前保存的起始簇号比较
if(TABLE_READ == 0 || cluster != START_CLUSTER)//从未读过 or 不在已有的FAT表内 需重新读
{
if(FAT_ReadSector(sector,FAT_TABLE))return 0x0ffffff8;//read fat table / return 0xfff8 when error occured
START_CLUSTER = cluster;
TABLE_READ = 1;
}
// if(cluster != START_CLUSTER)//不在已有的FAT表内 需重新读
// {
// if(FAT_ReadSector(sector,FAT_TABLE))return 0x0ffffff8;//read fat table / return 0xfff8 when error occured
// START_CLUSTER = cluster;
// TABLE_READ = 1;
// }
if(FAT32_Enable)
{
// offset=cluster%128;//find the position
sector=((unsigned long *)FAT_TABLE)[offset];
}
else
{
// offset=cluster%256;//find the position
sector=((unsigned int *)FAT_TABLE)[offset];
}
return (unsigned long)sector;//return the cluste number
}*/
//在FAT表内找空簇
//Find a free cluster return the cluster number
unsigned long FAT_FindFreeCluster()
{
BYTE buffer[512];
//DWORD sector;
unsigned int i;
unsigned long cnt;
// sector=FirstFATSector+offset;//calculate the actual sector
//sector=FirstFATSector;
if(FAT32_Enable)
{
for(cnt=0;cnt<FATsectors;cnt++)//find in the FAT table
{
if(FAT_ReadSector(FirstFATSector+cnt,buffer))return 1;//error
for(i=0;i<128;i++)
{
if(((unsigned long *)buffer)==0x00000000)break;//an unused cluster
}
if(i!=128)
{
cnt=cnt*128+i;
return cnt;//return the free cluster number
}
}
}
else
{
for(cnt=0;cnt<FATsectors;cnt++)//find in the FAT table
{
if(FAT_ReadSector(FirstFATSector+cnt,buffer))return 1;//error
for(i=0;i<256;i++)
{
if(((unsigned int *)buffer)==0x0000)break;//an unused cluster
}
if(i!=256)
{
cnt=cnt*256+i;
return cnt;//return the free cluster number
}
}
}
return 1;//error
}
//在cluster指向的目录下找一个空位置记录文件
//find a position to place a item withe the given directory, the parameter is FileInfo who brought the message
unsigned int FAT_FindFreeItem(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;}//read sector
for(offset=0;offset<512;offset+=32)
{
item=(struct direntry *)(&buffer[offset]);
//used item
if(item->deName[0] == 0x00 || item->deName[0] == 0xe5)
//unused item
{
FileInfo->StartCluster = item->deStartCluster + (((unsigned long)item->deHighClust)<<16);//don't care
FileInfo->Size = item->deFileSize;//don't care
FileInfo->Attr = item->deAttributes;//don't care
FileInfo->Sector = FirstDirSector+cnt;//The key parameter record the secoter nuber which the item stored
FileInfo->Offset = offset; //The key parameter record the offset in the sector
free(buffer);//realease
return 0;//done
}
}
}
free(buffer);//release
}
else//other folders//当这是一个其它目录时,程序暂且没考虑到目录内没有空余项是需要另找一个簇来记录
{
tempclust=cluster;
while(1)
{
sector=(unsigned long)FirstDataSector+(tempclust-2)*(unsigned long)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)
{
FileInfo->StartCluster = item->deStartCluster + (((unsigned long)item->deHighClust)<<16);
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)return 1;
}
}
return 1;
}
//显示给定路径下的文件
//display the content of a foler , 0 as root directory
unsigned char FAT_DisDir(BYTE *dir)
{
BYTE *buffer;
DWORD sector;
DWORD cluster;
DWORD tempclust;
unsigned int cnt;
unsigned int offset;
unsigned char i;
struct direntry *item = 0;
cluster = FAT_OpenDir(dir);
if(cluster == 1)return 1;
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]);//pointer convert
//find a valid item and display it
if((item->deName[0] != '.') && (item->deName[0] != 0x00) && (item->deName[0] != 0xe5) && (item->deAttributes != 0x0f))
{
USART0_putchar(0x0d);
USART0_putchar(0x0a);
for(i=0;i<8;i++)//name
{
USART0_putchar(item->deName);
}
if((item->deAttributes & 0x10)==0)USART0_putchar('.');
for(i=0;i<3;i++)//extention
{
USART0_putchar(item->deExtension);
}
}
}
}
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] != '.') && (item->deName[0] != 0x00) && (item->deName[0] != 0xe5) && (item->deAttributes != 0x0f))
{
USART0_putchar(0x0d);
USART0_putchar(0x0a);
for(i=0;i<8;i++)
{
USART0_putchar(item->deName);
}
if((item->deAttributes & 0x10)==0)USART0_putchar('.');
for(i=0;i<3;i++)
{
USART0_putchar(item->deExtension);
}
}
}
}
free(buffer);//release
tempclust=FAT_NextCluster(tempclust);//next cluster
if( tempclust == 0x0ffffff8 )return 1;
if((FAT32_Enable == 0 && tempclust == 0xffff) || tempclust == 0x0fffffff)break;
}
}
return 0;
}
//在给定目录下查找文件
//Find a item in the directory which specify by the parameter "cluster"
//Return the start cluster number
unsigned int FAT_FindItem(unsigned long cluster, BYTE *name, 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))
{
for(i=0;i<11;i++)
{
if(buffer[offset+i]!=name)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)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 0;//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 0;//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(FAT_FindItem(cluster,name, &FileInfo))return 0;//find the file
cluster = FileInfo.StartCluster;
return cluster;
}
// find a directory with the given path
unsigned long FAT_OpenDir(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 0;//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 0;//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 cluster;
if(FAT_FindItem(cluster,name, &FileInfo))return 0;//find the final directory
cluster = FileInfo.StartCluster;
return cluster;
}
unsigned int FAT_Close(struct FileInfoStruct *FileInfo)
{
memset(FileInfo,0,sizeof(&FileInfo));;
return 0;
}
// Output the data of a file
// size 0 means read all of the file
unsigned char FAT_Read(unsigned long pointer, unsigned long size)
{
DWORD sector;
DWORD tempclust=pointer;
BYTE *buffer;
unsigned int i=0,j=0;
sector=(DWORD)FirstDataSector+(DWORD)(tempclust-2)*(DWORD)SectorsPerClust;
if(size==0)size = FileInfo.Size;//whether need to read all
USART0_putchar(0x0d);
USART0_putchar(0x0a);//new line
while(size)
{
buffer=malloc(512);
if(FAT_ReadSector(sector+j,buffer)){free(buffer);return 1;}
if(size<=512)
{
for(i=0;i<size;i++)
{
USART0_putchar(buffer);//output
}
free(buffer);
return 0;//file over
}
else
{
for(i=0;i<512;i++)
{
USART0_putchar(buffer);
}
j++;
if(j==SectorsPerClust)
{
j=0;
free(buffer);
tempclust=FAT_NextCluster(tempclust);//find the next cluster the data was stored
if((FAT32_Enable == 0 && tempclust == 0xffff) || tempclust == 0x0ffffff8 || tempclust == 0x0fffffff)return 1;//error
sector=(DWORD)FirstDataSector+(DWORD)(tempclust-2)*(DWORD)SectorsPerClust;//reculculate the sector
}
else free(buffer);
size-=512;
}
}
return 0;
}
// write data to a file
unsigned char FAT_Write(unsigned long cluster,unsigned char *data,unsigned long size)
{
BYTE buffer[512];
DWORD sector;
unsigned int i;
for(i=0;i<size;i++)
{
buffer=data;
}
sector=(DWORD)FirstDataSector+(DWORD)(cluster-2)*(DWORD)SectorsPerClust;
if(FAT_WriteSector(sector,buffer))return 1;//write the data
return 0;
}
//Delete a file
unsigned char FAT_Delete(BYTE *dir)
{
// BYTE *buffer;
// struct direntry *item;
// WORD cluster;
if(FAT_Open(dir)==0)return 1;//open the file
if(FAT_DelItem(&FileInfo))return 1;//delete it
return 0;
}
//Delete an item
unsigned char FAT_DelItem(struct FileInfoStruct *FileInfo)
{
BYTE *buffer;
struct direntry *item;
DWORD cluster;
DWORD tempclust;
buffer=malloc(512);
if(buffer==0)return 1;
if(FAT_ReadSector(FileInfo->Sector,buffer)){free(buffer);return 1;}
item=(struct direntry *)(&buffer[FileInfo->Offset]);
item->deName[0]=0xe5;//mark it was deleted
if(FAT_WriteSector(FileInfo->Sector,buffer)){free(buffer);return 1;}
free(buffer);
cluster=FileInfo->StartCluster;
if(FileInfo->Attr & 0x10)//if the item is a folder
{
while(1)
{
while(FAT_SelectOneItem(cluster,FileInfo)==0)
{
if(FAT_DelItem(FileInfo))return 1;//nest for deleting folder
}
tempclust=FAT_NextCluster(cluster);//if the folder contain many item
if(tempclust==1)return 1;
if(FAT_ModifyFAT(cluster,0))return 1;//release the fat table
cluster=tempclust;
if(cluster == 0x0ffffff8)return 1;//error
if((FAT32_Enable == 0 && tempclust == 0xffff) || tempclust == 0x0fffffff)break;//the end of the directory
}
}
else// the item is a file
{
while(1)
{
tempclust=FAT_NextCluster(cluster);//save the next cluster
if(tempclust==1)return 1;
if(FAT_ModifyFAT(cluster,0))return 1;//delete curent cluster
cluster=tempclust;
//tempclust=FAT_NextCluster(cluster);
if(cluster == 0x0ffffff8)return 1;//error
if((FAT32_Enable == 0 && tempclust == 0xffff) || tempclust == 0x0fffffff)break;//the end of the file
}
//if(FAT_ModifyFAT(cluster,0))return 1;//delete the final cluster
}
return 0; //done
}
//Rename a directory or a file
unsigned char FAT_Rename(BYTE *dir,BYTE *newname)
{
BYTE name[11];
BYTE *p=dir;
BYTE deep=0;
BYTE i,j;
// BYTE directory=0;
DWORD cluster=0;
BYTE *buffer;
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 != '.') && (*p) )//compatalbe for folder and file
{
if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
else name[j]=*p++;
j++;
}
j=8;
if(*p == '.')//if it is a file
{
p++;
while(*p)
{
if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
else name[j]=*p++;
j++;
}
}
//else ;//It is a directory
if(FAT_FindItem(cluster,name, &FileInfo))return 1;//get the file or directory information
buffer=malloc(512);
if(buffer==0)return 1;
if(FAT_ReadSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//read the item according the information
item=(struct direntry *)(&buffer[FileInfo.Offset]);
//modify the name
p=newname;
for(j=0;j<11;j++)item->deName[j]=0x20;
j=0;
while((*p != '.') && (*p))
{
if(*p>='a' && *p<='z')item->deName[j]=(*p++)-0x20;
else item->deName[j]=*p++;
j++;
}
j=8;
if(*p == '.')//if it is a file
{
p++;
while(*p)
{
if(*p>='a' && *p<='z')item->deName[j]=(*p++)-0x20;
else item->deName[j]=*p++;
j++;
}
}
if(FAT_WriteSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//rewrite the item
free(buffer);
return 0;//done
}
//复制记录项信息
void CopyDirentruyItem(struct direntry *Desti,struct direntry *Source)
{
BYTE i;
for(i=0;i<8;i++)Desti->deName = Source->deName;
for(i=0;i<3;i++)Desti->deExtension = Source->deExtension;
Desti->deAttributes = Source->deAttributes;
Desti->deLowerCase = Source->deLowerCase;
Desti->deCHundredth = Source->deCHundredth;
for(i=0;i<2;i++)Desti->deCTime = Source->deCTime;
for(i=0;i<2;i++)Desti->deCDate = Source->deCDate;
for(i=0;i<2;i++)Desti->deADate = Source->deADate;
Desti->deHighClust = Source->deHighClust;
for(i=0;i<2;i++)Desti->deMTime = Source->deMTime;
for(i=0;i<2;i++)Desti->deMDate = Source->deMDate;
Desti->deStartCluster = Source->deStartCluster;
Desti->deFileSize = Source->deFileSize;
} |
|