📄 fat16.c
字号:
Cluster = GetNextClusterNum(Cluster);
Sector = ClusterNum2SectorNum(Cluster);
}
}
return 2;
}
_FILE handles[16];
int fat_close(int handle)
{
_FILE *fp;
FatDateTime tm;
BYTE* Cache;
DIRENTRY *dir;
if(handle <0 || handle >= sizeof(handles)/sizeof(_FILE))
return -1;
fp = &handles[handle];
fat_datetime(&tm);
fp->dir.LstAccDate = fp->dir.WrtDate = tm.Date;
fp->dir.WrtTime = tm.Time;
Cache = GetSectorData(fp->DirSectorNum);
if(Cache == NULL)
return -2;
dir = (DIRENTRY *)Cache;
dir += fp->DirIndex;
memcpy((BYTE *)dir, (BYTE *)&fp->dir, sizeof(DIRENTRY));
Flush();
FlushFAT();
handles[handle].valid = 0;
return 0;
}
int fat_creat(const char* filename, BYTE attribute)
{
DIRENTRY dir;
char path[512];
char name[11];
char *p;
DWORD ParentDirSectorNum;
FatDateTime tm;
_FILE file;
DIRENTRY *pdir;
WORD NewCluster;
BYTE* Cache;
// is path format correct ?
p = get_valid_format(filename);
if(p == NULL)
return -2;
//if exist this file ?
if(fat_locate(filename, NULL) != 0xffffffff)
return -3;
//separate path into parent and name
strncpy(name, &p[strlen(p)-11], 11);
strcpy(path, filename);
p = strrchr(path, '\\');
*p = '\0';
//locate parent path
ParentDirSectorNum = fat_locate(path, NULL);
if(ParentDirSectorNum == 0xffffffff)
return -4;
//fill dir attributes
memset((BYTE *)&dir, 0, sizeof(dir));
memcpy((BYTE *)(dir.deName), name, 11);
dir.deAttributes = attribute;
fat_datetime(&tm);
dir.CrtDate = dir.LstAccDate = dir.WrtDate = tm.Date;
dir.CrtTime = dir.WrtTime = tm.Time;
dir.CrtTimeTenth = tm.TimeTenth;
dir.deFileSize = 0;
//alloc one dir
if(AllocDir(ParentDirSectorNum, &dir, &file) != 0)
return -5;
//alloc a cluster
NewCluster = AllocCluster(0);
if(NewCluster == 0xffff)
return -6;
//flush to disk
Cache = GetSectorData(file.DirSectorNum);
if(Cache == NULL)
return -7;
pdir = (DIRENTRY *)Cache;
pdir += file.DirIndex;
pdir->deStartCluster= NewCluster;
Flush();
return fat_open(filename);
}
long fat_lseek(int handle, long offset, int origin)
{
_FILE *fp;
WORD Cluster;
unsigned int len;
int i;
if(handle <0 || handle >= sizeof(handles)/sizeof(_FILE))
return 0;
fp = &handles[handle];
switch(origin)
{
case SEEK_SET:
{
if(offset < 0)
return (-1);
fp->offset = offset;
}
break;
case SEEK_CUR:
{
if((fp->offset + offset) <0 )
return (-1);
fp->offset += offset;
}
break;
case SEEK_END:
{
if((fp->offset + offset) <0 )
return (-1);
fp->offset = fp->dir.deFileSize + offset;
}
break;
default:
return (-2);
}
// re-locate CurrentSectorNum, SectorOffset
Cluster = fp->dir.deStartCluster;
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
len = 0;
while(Cluster != 0xffff)
{
for(i=0; i< SectorsPerCluster; i++)
{
len += BytesPerSector;
if(len >= fp->offset)
{
fp->SectorOffset = fp->offset % BytesPerSector;
return fp->offset;
}
fp->CurrentSectorNum ++;
}
Cluster = GetNextClusterNum(Cluster);
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
}
return handles[handle].offset;
}
int fat_open(const char* filename)
{
int i;
_FILE * fp = NULL;
DWORD FirstSectorNum;
for(i=0; i<16; i++)
{
if(!handles[i].valid)
{
fp = &handles[i];
break;
}
}
if(fp == NULL)
return -1;
FirstSectorNum = fat_locate(filename, fp);
if(FirstSectorNum == 0xffffffff)
return -2;
fp->StartSectorNum = FirstSectorNum;
fp->CurrentSectorNum = fp->StartSectorNum;
fp->SectorOffset = 0;
fp->offset = 0;
fp->valid = 1;
return i;
}
unsigned int fat_read(int handle, void* buffer, unsigned int bytes)
{
BYTE* Cache;
unsigned int read_bytes =0;
unsigned int max_copy_bytes_in_sector;
_FILE *fp;
WORD Cluster;
int i;
if(handle <0 || handle >= sizeof(handles)/sizeof(_FILE))
return 0;
fp = &handles[handle];
bytes = (fp->dir.deFileSize - fp->offset) > bytes ? bytes : (fp->dir.deFileSize - fp->offset);
Cluster = SectorNum2ClusterNum(fp->CurrentSectorNum);
i = (fp->CurrentSectorNum - FirstDataSector) % SectorsPerCluster;
if(i != 0)
{
for(; i< SectorsPerCluster; i++)
{
Cache = GetSectorData(fp->CurrentSectorNum);
if(Cache == NULL)
return 0;
Cache += fp->SectorOffset;
max_copy_bytes_in_sector = (BytesPerSector - fp->SectorOffset) > (bytes - read_bytes) ? (bytes - read_bytes) : (BytesPerSector- fp->SectorOffset);
memcpy(buffer, Cache, max_copy_bytes_in_sector);
read_bytes += max_copy_bytes_in_sector;
fp->SectorOffset += max_copy_bytes_in_sector;
fp->offset += max_copy_bytes_in_sector;
buffer = (char*)buffer + max_copy_bytes_in_sector;
if(fp->SectorOffset == BytesPerSector)
{
if(i == SectorsPerCluster -1)
{
Cluster = GetNextClusterNum(Cluster);
if(Cluster != 0xffff)
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
}
else
fp->CurrentSectorNum ++;
fp->SectorOffset = 0;
}
if(read_bytes == bytes)
{
return bytes;
}
}
}
while(Cluster != 0xffff)
{
for(i=0; i< SectorsPerCluster; i++)
{
Cache = GetSectorData(fp->CurrentSectorNum);
if(Cache == NULL)
return 0;
Cache += fp->SectorOffset;
max_copy_bytes_in_sector = (BytesPerSector- fp->SectorOffset) > (bytes - read_bytes) ? (bytes - read_bytes) : (BytesPerSector- fp->SectorOffset);
memcpy(buffer, Cache, max_copy_bytes_in_sector);
read_bytes += max_copy_bytes_in_sector;
fp->SectorOffset += max_copy_bytes_in_sector;
fp->offset += max_copy_bytes_in_sector;
buffer = (char*)buffer + max_copy_bytes_in_sector;
if(fp->SectorOffset == BytesPerSector)
{
if(i == SectorsPerCluster -1)
{
Cluster = GetNextClusterNum(Cluster);
if(Cluster != 0xffff)
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
}
else
fp->CurrentSectorNum ++;
fp->SectorOffset = 0;
}
if(read_bytes == bytes)
{
return bytes;
}
}
}
return 0;
}
unsigned int fat_write(int handle, const char* buffer, unsigned int bytes)
{
BYTE* Cache;
unsigned int write_bytes =0;
unsigned int max_write_bytes_in_sector;
_FILE *fp;
WORD Cluster;
WORD PrevCluster;
int i;
if(handle <0 || handle >= sizeof(handles)/sizeof(_FILE))
return 0;
fp = &handles[handle];
Cluster = SectorNum2ClusterNum(fp->CurrentSectorNum);
PrevCluster = Cluster;
i = (fp->CurrentSectorNum - FirstDataSector) % SectorsPerCluster;
if(i != 0)
{
for(; i< SectorsPerCluster; i++)
{
Cache = GetSectorData(fp->CurrentSectorNum);
if(Cache == NULL)
return 0;
Cache += fp->SectorOffset;
max_write_bytes_in_sector = (BytesPerSector- fp->SectorOffset) > (bytes - write_bytes) ? (bytes - write_bytes) : (BytesPerSector - fp->SectorOffset);
memcpy(Cache, buffer, max_write_bytes_in_sector);
Flush();
write_bytes += max_write_bytes_in_sector;
fp->SectorOffset += max_write_bytes_in_sector;
fp->offset += max_write_bytes_in_sector;
buffer = (char*)buffer + max_write_bytes_in_sector;
fp->dir.deFileSize += max_write_bytes_in_sector;
if(fp->SectorOffset == BytesPerSector)
{
if(i == SectorsPerCluster -1)
{
PrevCluster = Cluster;
Cluster = GetNextClusterNum(Cluster);
if(Cluster != 0xffff)
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
else
{
Cluster = AllocCluster(PrevCluster);
if(Cluster == 0xffff)
return 0;
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
}
}
else
fp->CurrentSectorNum ++;
fp->SectorOffset = 0;
}
if(write_bytes == bytes)
{
return bytes;
}
}
}
for(;;)
{
for(i=0; i< SectorsPerCluster; i++)
{
Cache = GetSectorData(fp->CurrentSectorNum);
if(Cache == NULL)
return 0;
Cache += fp->SectorOffset;
max_write_bytes_in_sector = (BytesPerSector - fp->SectorOffset) > (bytes - write_bytes) ? (bytes - write_bytes) : (BytesPerSector - fp->SectorOffset);
memcpy(Cache, buffer, max_write_bytes_in_sector);
Flush();
write_bytes += max_write_bytes_in_sector;
fp->SectorOffset += max_write_bytes_in_sector;
fp->offset += max_write_bytes_in_sector;
buffer = (char*)buffer + max_write_bytes_in_sector;
fp->dir.deFileSize += max_write_bytes_in_sector;
if(fp->SectorOffset == BytesPerSector)
{
if(i == SectorsPerCluster -1)
{
PrevCluster = Cluster;
Cluster = GetNextClusterNum(Cluster);
if(Cluster != 0xffff)
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
else
{
Cluster = AllocCluster(PrevCluster);
if(Cluster == 0xffff)
return 0;
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
}
}
else
fp->CurrentSectorNum ++;
fp->SectorOffset = 0;
}
if(write_bytes == bytes)
{
return bytes;
}
}
}
// we can not reach here.
return 0;
}
int fat_remove( const char *filename)
{
DWORD SectorNum;
_FILE file;
//locate
SectorNum = fat_locate(filename, &file);
if(SectorNum == 0xffffffff)
return 4;
// is it a dir ?
if(file.dir.deAttributes & ATTR_DIRECTORY)
return 6;
if(DeleteDir(&file) != 0)
return 5;
FreeCluster(file.dir.deStartCluster);
return 0;
}
int fat_get_stat( const char *filename, _STAT * stat)
{
DWORD SectorNum;
_FILE file;
//locate
SectorNum = fat_locate(filename, &file);
if(SectorNum == 0xffffffff)
return 1;
stat->Attr = file.dir.deAttributes;
stat->CrtDate = file.dir.CrtDate;
stat->CrtTime = file.dir.CrtTime;
stat->CrtTimeTenth = file.dir.CrtTimeTenth;
stat->FileSize = file.dir.deFileSize;
stat->LstAccDate = file.dir.LstAccDate;
stat->WrtDate = file.dir.WrtDate;
stat->WrtTime = file.dir.WrtTime;
return 0;
}
int fat_set_stat( const char *filename, _STAT * stat)
{
DWORD SectorNum;
_FILE file;
BYTE* Cache;
DIRENTRY *dir;
//locate
SectorNum = fat_locate(filename, &file);
if(SectorNum == 0xffffffff)
return 1;
file.dir.deAttributes = stat->Attr;
file.dir.CrtDate = stat->CrtDate;
file.dir.CrtTime = stat->CrtTime;
file.dir.CrtTimeTenth = stat->CrtTimeTenth;
file.dir.deFileSize = stat->FileSize;
file.dir.LstAccDate = stat->LstAccDate;
file.dir.WrtDate = stat->WrtDate;
file.dir.WrtTime = stat->WrtTime;
Cache = GetSectorData(file.DirSectorNum);
if(Cache == NULL)
return 2;
dir = (DIRENTRY *)Cache;
dir += file.DirIndex;
memcpy((BYTE *)dir, (BYTE *)&file.dir, sizeof(DIRENTRY));
Flush();
return 0;
}
int fat_rename( const char *oldname, const char *newname )
{
DIRENTRY dir;
char path[512];
char newpath[512];
char name[11];
char new_name[11];
char *p;
DWORD ParentDirSectorNum;
_FILE old_file;
//
//check oldname file
//
// is path format correct ?
p = get_valid_format(oldname);
if(p == NULL)
return -2;
//if exist this file ?
if(fat_locate(oldname, &old_file) == 0xffffffff)
return -3;
//separate path into parent and name
strncpy(name, &p[strlen(p)-11], 11);
strcpy(path, oldname);
p = strrchr(path, '\\');
*p = '\0';
//
//check newname file
//
if(strchr(newname, '\\') != NULL)
return -2;
sprintf(newpath, "%s\\%s", path, newname);
// is path format correct ?
p = get_valid_format(newpath);
if(p == NULL)
return -2;
//if exist this file ?
if(fat_locate(newpath, NULL) != 0xffffffff)
return -3;
//separate path into parent and name
strncpy(new_name, &p[strlen(p)-11], 11);
//locate parent path
ParentDirSectorNum = fat_locate(path, NULL);
if(ParentDirSectorNum == 0xffffffff)
return -4;
//fill dir attributes
memcpy((BYTE *)&dir,(BYTE *)(&old_file.dir), sizeof(DIRENTRY));
memcpy((BYTE *)dir.deName, new_name, 11);
//alloc one dir
if(AllocDir(ParentDirSectorNum, &dir, NULL) != 0)
return -5;
//delete old one
if(DeleteDir(&old_file) != 0)
return -6;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -