📄 fat16.cpp
字号:
BYTE* Cache;
struct _DIR *dir;
unsigned int j;
Cache = GetSectorData(Sector);
if(Cache == NULL)
return 0xffffffff;
dir = (struct _DIR *)Cache;
for(j=0; (dir->Name[0] != '\0') && (j< Bpb.BytsPerSec / sizeof(struct _DIR)); j++)
{
if(memcmp((const char*)dir->Name, dirname, 11) == 0 && (!(dir->Attr & ATTR_VOLUME_ID)))// not volumn id or long name entry.
{
if(file != NULL)
{
memset(file, 0, sizeof(struct _file));
file->DirSectorNum = Sector;
file->DirIndex = j;
memcpy(&file->dir, dir, sizeof(struct _DIR));
}
return ClusterNum2SectorNum(dir->FstClusLO);
}
dir++;
}
return 0xffffffff;
}
int SectorGet(DWORD Sector, struct FatGet *fat_get)
{
BYTE* Cache;
struct _DIR *dir;
unsigned int j;
Cache = GetSectorData(Sector);
if(Cache == NULL)
return 1;
dir = (struct _DIR *)Cache;
dir += fat_get->DirIndex;
for(j=fat_get->DirIndex; (dir->Name[0] != '\0') && (j< Bpb.BytsPerSec / sizeof(struct _DIR)); j++)
{
if(dir->Name[0] != ERCHAR && (!(dir->Attr & ATTR_VOLUME_ID)))// not volumn id or long name entry.
{
fat_get->DirSectorNum = Sector;
fat_get->DirIndex = j + 1;
unformat_name(fat_get->filename, dir->Name);
return 0;
}
dir++;
}
return 2;
}
// return the first sector number of dir/file content.
// 0xffffffff indicate failed.
DWORD fat_search(DWORD Sector, const char dirname[11], struct _file *file)
{
unsigned int i;
WORD Cluster;
DWORD FirstSectorOfFile;
//if(dirname == NULL)
//return 0xffffffff;
if(Sector == FirstRootDirSecNum)
{
for(i=0; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
{
FirstSectorOfFile = SectorSearch(Sector++, dirname, file);
if(FirstSectorOfFile != 0xffffffff)
return FirstSectorOfFile;
}
}
else
{
Cluster = SectorNum2ClusterNum(Sector);
// because arg Sector is the first sector of parent dir content,
// so it is the first sector of the cluster.
/*
i = (Sector - FirstDataSector) % Bpb.SecPerClus;
if(i != 0)
{
for(; i< Bpb.SecPerClus; i++)
{
FirstSectorOfFile = SectorSearch(Sector++, dirname, file);
if(FirstSectorOfFile != 0xffffffff)
return FirstSectorOfFile;
}
Cluster = GetNextClusterNum(Cluster);
Sector = ClusterNum2SectorNum(Cluster);
}*/
while(Cluster != 0xffff)
{
for(i=0; i< Bpb.SecPerClus; i++)
{
FirstSectorOfFile = SectorSearch(Sector++, dirname, file);
if(FirstSectorOfFile != 0xffffffff)
return FirstSectorOfFile;
}
Cluster = GetNextClusterNum(Cluster);
Sector = ClusterNum2SectorNum(Cluster);
}
}
return 0xffffffff;
}
// return the first sector number of dir/file content.
// 0xffffffff indicate failed.
// if path is root dir, file arg is ignore.
DWORD fat_locate(const char *path, struct _file *file)
{
DWORD Sector = FirstRootDirSecNum;
char *p;
p = get_valid_format(path);
if(p == NULL)
return 0xffffffff;
// locate first sub dir.
p++;
// locate next sub dir(s).
for(;;)
{
if(*p == NULL)
return Sector;
Sector = fat_search(Sector, p, file);
if(Sector == 0xffffffff)
return 0xffffffff;
p+=12;
}
// we never go here.
return 0xffffffff;
}
void fat_datetime(struct FatDateTime *fatdatetime)
{
SYSTEMTIME systm;
struct FatDate* pdate = &fatdatetime->Date.fatdate;
struct FatTime *ptm = &fatdatetime->Time.fattime;
GetSystemTime(&systm);
pdate->Day = systm.wDay;
pdate->Month = systm.wMonth;
pdate->Year = systm.wYear - 1980;
ptm->Hours = systm.wHour;
ptm->Minutes = systm.wMinute;
ptm->Second_2s = systm.wSecond / 2;
fatdatetime->TimeTenth = (systm.wSecond % 2) * 100 + systm.wMilliseconds / 10;
}
///////////////////////////////////////////////////////////////////
// fat apis
///////////////////////////////////////////////////////////////////
int fat_mkdir( const char *dirname)
{
struct _DIR dir;
DWORD SectorNum;
char path[512];
char name[11];
char *p;
struct FatDateTime tm;
struct _file file;
BYTE* Cache;
struct _DIR *pdir;
WORD NewCluster;
char dot[11] = {'.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
char dotdot[11] = {'.', '.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
// is path format correct ?
p = get_valid_format(dirname);
if(p == NULL)
return 1;
//if exist this dir ?
if(fat_locate(dirname, NULL) != 0xffffffff)
return 4;
//separate path into parent and name
strncpy(name, &p[strlen(p)-11], 11);
strcpy(path, dirname);
p = strrchr(path, '\\');
if(p == path) // it is root dir.
*(p+1) = '\0';
else
*p = '\0';
//locate parent path
SectorNum = fat_locate(path, NULL);
if(SectorNum == 0xffffffff)
return 2;
//fill dir attributes
memset(&dir, 0, sizeof(dir));
memcpy(dir.Name, name, 11);
dir.Attr = ATTR_DIRECTORY;
fat_datetime(&tm);
dir.CrtDate = dir.LstAccDate = dir.WrtDate = tm.Date.Date;
dir.CrtTime = dir.WrtTime = tm.Time.Time;
dir.CrtTimeTenth = tm.TimeTenth;
//alloc one dir
if(AllocDir(SectorNum, &dir, &file) != 0)
return 3;
//alloc a cluster
NewCluster = AllocCluster(0);
if(NewCluster == 0xffff)
return 4;
//flush to disk
Cache = GetSectorData(file.DirSectorNum);
if(Cache == NULL)
return 6;
pdir = (struct _DIR *)Cache;
pdir += file.DirIndex;
pdir->FstClusLO = NewCluster;
Flush();
//create . and .. dir items.
Cache = GetSectorData(ClusterNum2SectorNum(NewCluster));
if(Cache == NULL)
return 6;
pdir = (struct _DIR *)Cache;
memset(pdir, 0, sizeof(struct _DIR));
memcpy(pdir->Name, dot, 11);
pdir->Attr = ATTR_DIRECTORY;
fat_datetime(&tm);
pdir->CrtDate = pdir->LstAccDate = pdir->WrtDate = tm.Date.Date;
pdir->CrtTime = pdir->WrtTime = tm.Time.Time;
pdir->CrtTimeTenth = tm.TimeTenth;
pdir->FstClusLO = NewCluster;
pdir++;
memset(pdir, 0, sizeof(struct _DIR));
memcpy(pdir->Name, dotdot, 11);
pdir->Attr = ATTR_DIRECTORY;
fat_datetime(&tm);
pdir->CrtDate = pdir->LstAccDate = pdir->WrtDate = tm.Date.Date;
pdir->CrtTime = pdir->WrtTime = tm.Time.Time;
pdir->CrtTimeTenth = tm.TimeTenth;
pdir->FstClusLO = SectorNum2ClusterNum(SectorNum);
Flush();
return 0;
}
int fat_rmdir( const char *dirname)
{
DWORD SectorNum;
struct _file file;
char filename[13];
//is dir have no sub dir or file ?
if(fat_getfirst(dirname, filename) == 0)
return 3;
//locate
SectorNum = fat_locate(dirname, &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;
}
struct FatGet fat_get;
int fat_getfirst(const char *path, char* filename)
{
DWORD Sector;
unsigned int i;
WORD Cluster;
//if exist this dir ?
Sector = fat_locate(path, NULL);
if(Sector == 0xffffffff)
return 1;
if(Sector == FirstRootDirSecNum)
{
fat_get.IsRootDir = 1;
fat_get.DirIndex = 2;
for(i=0; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
{
if(SectorGet(Sector++, &fat_get) == 0)
{
strcpy(filename, fat_get.filename);
return 0;
}
}
}
else
{
fat_get.IsRootDir = 0;
fat_get.DirIndex = 2;
Cluster = SectorNum2ClusterNum(Sector);
// because the sector is the first sector of parent dir,
// so it is the first sector of cluster.
/*
i = (Sector - FirstDataSector) % Bpb.SecPerClus;
if(i != 0)
{
for(; i< Bpb.SecPerClus; i++)
{
if(SectorGet(Sector++, &fat_get) == 0)
{
strcpy(filename, fat_get.filename);
return 0;
}
}
Cluster = GetNextClusterNum(Cluster);
Sector = ClusterNum2SectorNum(Cluster);
}*/
while(Cluster != 0xffff)
{
for(i=0; i< Bpb.SecPerClus; i++)
{
if(SectorGet(Sector++, &fat_get) == 0)
{
strcpy(filename, fat_get.filename);
return 0;
}
}
Cluster = GetNextClusterNum(Cluster);
Sector = ClusterNum2SectorNum(Cluster);
}
}
return 2;
}
int fat_getnext(char* filename)
{
DWORD Sector;
unsigned int i;
WORD Cluster;
Sector = fat_get.DirSectorNum;
if(fat_get.IsRootDir)
{
i=(Sector - FirstRootDirSecNum) * Bpb.BytsPerSec / sizeof(struct _DIR) + fat_get.DirIndex +1;
for(; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
{
if(SectorGet(Sector++, &fat_get) == 0)
{
strcpy(filename, fat_get.filename);
return 0;
}
}
}
else
{
Cluster = SectorNum2ClusterNum(Sector);
i = (Sector - FirstDataSector) % Bpb.SecPerClus;
if(i != 0)
{
for(; i< Bpb.SecPerClus; i++)
{
if(SectorGet(Sector++, &fat_get) == 0)
{
strcpy(filename, fat_get.filename);
return 0;
}
}
Cluster = GetNextClusterNum(Cluster);
Sector = ClusterNum2SectorNum(Cluster);
}
while(Cluster != 0xffff)
{
for(i=0; i< Bpb.SecPerClus; i++)
{
if(SectorGet(Sector++, &fat_get) == 0)
{
strcpy(filename, fat_get.filename);
return 0;
}
}
Cluster = GetNextClusterNum(Cluster);
Sector = ClusterNum2SectorNum(Cluster);
}
}
return 2;
}
struct _file handles[16];
int fat_close(int handle)
{
struct _file *fp;
struct FatDateTime tm;
BYTE* Cache;
struct _DIR *dir;
if(handle <0 || handle >= sizeof(handles)/sizeof(struct _file))
return -1;
fp = &handles[handle];
fat_datetime(&tm);
fp->dir.LstAccDate = fp->dir.WrtDate = tm.Date.Date;
fp->dir.WrtTime = tm.Time.Time;
Cache = GetSectorData(fp->DirSectorNum);
if(Cache == NULL)
return -2;
dir = (struct _DIR *)Cache;
dir += fp->DirIndex;
memcpy(dir, &fp->dir, sizeof(struct _DIR));
Flush();
handles[handle].valid = 0;
return 0;
}
int fat_creat(const char* filename, BYTE attribute)
{
struct _DIR dir;
char path[512];
char name[11];
char *p;
DWORD ParentDirSectorNum;
struct FatDateTime tm;
struct _file file;
struct _DIR *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(&dir, 0, sizeof(dir));
memcpy(dir.Name, name, 11);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -