📄 fat16.cpp
字号:
dir.Attr = attribute;
fat_datetime(&tm);
dir.CrtDate = dir.LstAccDate = dir.WrtDate = tm.Date.Date;
dir.CrtTime = dir.WrtTime = tm.Time.Time;
dir.CrtTimeTenth = tm.TimeTenth;
dir.FileSize = 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 = (struct _DIR *)Cache;
pdir += file.DirIndex;
pdir->FstClusLO = NewCluster;
Flush();
return fat_open(filename);
}
long fat_lseek(int handle, long offset, int origin)
{
struct _file *fp;
WORD Cluster;
unsigned int len;
int i;
if(handle <0 || handle >= sizeof(handles)/sizeof(struct _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.FileSize + offset;
}
break;
default:
return -2;
}
// re-locate CurrentSectorNum, SectorOffset
Cluster = fp->dir.FstClusLO;
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
len = 0;
while(Cluster != 0xffff)
{
for(i=0; i< Bpb.SecPerClus; i++)
{
len += Bpb.BytsPerSec;
if(len >= fp->offset)
{
fp->SectorOffset = fp->offset % Bpb.BytsPerSec;
return fp->offset;
}
fp->CurrentSectorNum ++;
}
Cluster = GetNextClusterNum(Cluster);
fp->CurrentSectorNum = ClusterNum2SectorNum(Cluster);
}
return handles[handle].offset;
}
int fat_open(const char* filename)
{
int i;
struct _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;
struct _file *fp;
WORD Cluster;
int i;
if(handle <0 || handle >= sizeof(handles)/sizeof(struct _file))
return 0;
fp = &handles[handle];
bytes = (fp->dir.FileSize - fp->offset) > bytes ? bytes : (fp->dir.FileSize - fp->offset);
Cluster = SectorNum2ClusterNum(fp->CurrentSectorNum);
i = (fp->CurrentSectorNum - FirstDataSector) % Bpb.SecPerClus;
if(i != 0)
{
for(; i< Bpb.SecPerClus; i++)
{
Cache = GetSectorData(fp->CurrentSectorNum);
if(Cache == NULL)
return 0;
Cache += fp->SectorOffset;
max_copy_bytes_in_sector = (Bpb.BytsPerSec - fp->SectorOffset) > (bytes - read_bytes) ? (bytes - read_bytes) : (Bpb.BytsPerSec - 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 == Bpb.BytsPerSec)
{
if(i == Bpb.SecPerClus -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< Bpb.SecPerClus; i++)
{
Cache = GetSectorData(fp->CurrentSectorNum);
if(Cache == NULL)
return 0;
Cache += fp->SectorOffset;
max_copy_bytes_in_sector = (Bpb.BytsPerSec - fp->SectorOffset) > (bytes - read_bytes) ? (bytes - read_bytes) : (Bpb.BytsPerSec - 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 == Bpb.BytsPerSec)
{
if(i == Bpb.SecPerClus -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;
struct _file *fp;
WORD Cluster;
WORD PrevCluster;
int i;
if(handle <0 || handle >= sizeof(handles)/sizeof(struct _file))
return 0;
fp = &handles[handle];
Cluster = SectorNum2ClusterNum(fp->CurrentSectorNum);
PrevCluster = Cluster;
i = (fp->CurrentSectorNum - FirstDataSector) % Bpb.SecPerClus;
if(i != 0)
{
for(; i< Bpb.SecPerClus; i++)
{
Cache = GetSectorData(fp->CurrentSectorNum);
if(Cache == NULL)
return 0;
Cache += fp->SectorOffset;
max_write_bytes_in_sector = (Bpb.BytsPerSec - fp->SectorOffset) > (bytes - write_bytes) ? (bytes - write_bytes) : (Bpb.BytsPerSec - 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.FileSize += max_write_bytes_in_sector;
if(fp->SectorOffset == Bpb.BytsPerSec)
{
if(i == Bpb.SecPerClus -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< Bpb.SecPerClus; i++)
{
Cache = GetSectorData(fp->CurrentSectorNum);
if(Cache == NULL)
return 0;
Cache += fp->SectorOffset;
max_write_bytes_in_sector = (Bpb.BytsPerSec - fp->SectorOffset) > (bytes - write_bytes) ? (bytes - write_bytes) : (Bpb.BytsPerSec - 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.FileSize += max_write_bytes_in_sector;
if(fp->SectorOffset == Bpb.BytsPerSec)
{
if(i == Bpb.SecPerClus -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;
struct _file file;
//locate
SectorNum = fat_locate(filename, &file);
if(SectorNum == 0xffffffff)
return 4;
// is it a dir ?
if(file.dir.Attr & ATTR_DIRECTORY)
return 6;
if(DeleteDir(&file) != 0)
return 5;
FreeCluster(file.dir.FstClusLO);
return 0;
}
int fat_get_stat( const char *filename, struct _stat* stat)
{
DWORD SectorNum;
struct _file file;
//locate
SectorNum = fat_locate(filename, &file);
if(SectorNum == 0xffffffff)
return 1;
stat->Attr = file.dir.Attr;
stat->CrtDate = file.dir.CrtDate;
stat->CrtTime = file.dir.CrtTime;
stat->CrtTimeTenth = file.dir.CrtTimeTenth;
stat->FileSize = file.dir.FileSize;
stat->LstAccDate = file.dir.LstAccDate;
stat->WrtDate = file.dir.WrtDate;
stat->WrtTime = file.dir.WrtTime;
return 0;
}
int fat_set_stat( const char *filename, struct _stat* stat)
{
DWORD SectorNum;
struct _file file;
BYTE* Cache;
struct _DIR *dir;
//locate
SectorNum = fat_locate(filename, &file);
if(SectorNum == 0xffffffff)
return 1;
file.dir.Attr = stat->Attr;
file.dir.CrtDate = stat->CrtDate;
file.dir.CrtTime = stat->CrtTime;
file.dir.CrtTimeTenth = stat->CrtTimeTenth;
file.dir.FileSize = 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 = (struct _DIR *)Cache;
dir += file.DirIndex;
memcpy(dir, &file.dir, sizeof(struct _DIR));
Flush();
return 0;
}
int fat_rename( const char *oldname, const char *newname )
{
struct _DIR dir;
char path[512];
char newpath[512];
char name[11];
char new_name[11];
char *p;
DWORD ParentDirSectorNum;
struct _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(&dir, &old_file.dir, sizeof(struct _DIR));
memcpy(dir.Name, 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 + -