📄 fsys.c
字号:
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\option.h"
#include "..\inc\Hal.h"
unsigned int m_Offset;
struct _BPB Bpb;
struct _FatGet fat_get;
INT32 RootDirSectors;
INT32 FirstDataSector;
INT32 FirstFatSecNum;
INT32 FirstRootDirSecNum;
struct _FILE handles;
WORD FatCache[512*256];
volatile SYS_INFO_BLOCK DeviceInfo;
#define GETINT16(p) (*(INT8*)p+0x100*(*(INT8*)(p+1)))
#define GETINT32(p) (*(INT8*)p+0x100*(*(INT8*)(p+1))+0x10000*(*(INT8*)(p+2))+0x1000000*(*(INT8*)(p+3)))
#define getyear(p) (p&0x0FE00)>>9
#define getmonth(p) (p&0x01e0)>>5
#define getday(p) (p&0x1F)
#define gethour(p) (p&0x0F800)>>11
#define getminitor(p) (p&0x07e0)>>5
#define getsecond(p) (p&0x1F)
void unformat_name(char * filename, const unsigned char dirname[11])
{
int i;
int j;
memset(filename, 0, 13);
for(i=0; i<8; i++)
{
if(dirname[i] != 0x20)
filename[i] = dirname[i];
else
break;
}
if(dirname[8] != 0x20)
{
filename[i] = '.';
j = i + 1;
for(i=8; i<11; i++,j++)
{
if(dirname[i] != 0x20)
filename[j] = dirname[i];
else
break;
}
}
}
unsigned char SectorGet(INT32 Sector, struct _FatGet *fat_get)
{
BYTE Cache[512];
struct _DIR *dir;
unsigned int j;
if(RBC_Read(Sector,1,(unsigned char *)Cache)==FALSE)return FALSE;
dir = (struct _DIR *)Cache;
dir += fat_get->DirIndex;
for(j=fat_get->DirIndex;(dir->Name[0] != '\0') && (j< Bpb.BytsPerSec / sizeof(struct _DIR)); j++)//Bpb.BytsPerSec / sizeof(struct _DIR)
{
if(dir->Name[0] != 0xE5 && (!(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++;
}
fat_get->DirIndex=0;
return TRUE;
}
unsigned char get_valid_format(const char *fullpath,char static_path[256])
{
char* p=static_path;
char path[256];
char* ppath = path;
int dir_len_count; //count dir len.
int i;
if(fullpath == NULL || strlen(fullpath) >12)
return FALSE;
dir_len_count=0;
strcpy(path, fullpath);
for(i=0;(*ppath!=NULL&&i<12);i++)
{
if( *ppath > 96 && *ppath < 123)
{
*ppath -= 32;
}
ppath++;
}
memset(p, 0, 256);
ppath = path;
for(;;)
{
switch(*ppath)
{
case 0:
if(dir_len_count>=11) return TRUE;
else
{
dir_len_count ++;
*p = 0x20;
p++;
}
continue;
case '.':
{
if(dir_len_count > 8 || dir_len_count ==0)
return FALSE;
if(ppath[1] == '.')
return FALSE;
// if(dir_len_count > 8)
// {
// *p = *ppath;
// p++;
// }
// else
// {
for(i=0; i<(8 - dir_len_count); i++)
{
*p = 0x20;
p++;
}
// }
dir_len_count =8;
ppath++;
continue;
}
break;
case 0x22:
case 0x2A:
case 0x2B:
case 0x2C:
case 0x2F:
case 0x3A:
case 0x3B:
case 0x3C:
case 0x3D:
case 0x3E:
case 0x3F:
case 0x5B:
case 0x5D:
case 0x7C:
return FALSE;
default:
{
if(*ppath < 0x20)
return FALSE;
}
break;
}
*p = *ppath;
dir_len_count ++;
if(dir_len_count >= 11)
return TRUE;
p++;
ppath++;
}
}
WORD SectorNum2ClusterNum(INT32 SectorNum)
{
if(SectorNum < FirstDataSector)
return 0;
else
return (WORD)((SectorNum - FirstDataSector) / Bpb.SecPerClus + 2);
}
INT32 ClusterNum2SectorNum(WORD ClusterNum)
{
return FirstDataSector + (ClusterNum - 2) * Bpb.SecPerClus;
}
INT32 SectorSearch(INT32 Sector, const char dirname[256], struct _FILE *file)
{
BYTE Cache[512];
BYTE filename[256];
struct _DIR *dir;
unsigned int j;
struct _FatGet fat_get;
if(RBC_Read(Sector,1,(unsigned char *)Cache)==FALSE)return 0xffffffff;
dir = (struct _DIR *)Cache;
for(j=0; (dir->Name[0] != '\0') && (j< Bpb.BytsPerSec / sizeof(struct _DIR)); j++)
{
if(dir->Name[0] !=0xE5 && (!(dir->Attr & ATTR_VOLUME_ID)))// not volumn id or long name entry.
{
if(strlen(dirname)>11)
{
fat_get.DirSectorNum=Sector;
fat_get.DirIndex=j+1;
if(fat_get.DirIndex!=1||fat_get.DirSectorNum!=FirstRootDirSecNum)
{
if(GetLongFileName(&fat_get,filename))
{
if(memcmp(filename, dirname, strlen(dirname)) == 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);
}
}
}
}
else
{
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;
}
INT32 Search(INT32 Sector, const char dirname[256], struct _FILE *file)
{
unsigned int i;
WORD Cluster;
INT32 FirstSectorOfFile;
for(i=0; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
{
FirstSectorOfFile = SectorSearch(Sector++, dirname, file);
if(FirstSectorOfFile != 0xffffffff)
return FirstSectorOfFile;
}
return 0xffffffff;
}
unsigned int Locate(const char *filename, struct _FILE *file)
{
INT32 Sector = FirstRootDirSecNum;
static char static_path[256];
char *p=static_path;
if(strlen(filename)<13)
{
if(FALSE == get_valid_format(filename,p))
return FALSE;
}
else
strcpy(p,filename);
Sector = Search(Sector, p, file);
// if(*(p+11) == NULL)
return Sector;
// return 0xFFFFFFFF;
}
int GetLongFileName(struct _FatGet *fat_get, char *filename)
{
WORD TmpLen=0;
unsigned int Sector;
BYTE Cache[512];
struct _DIR *dir;
BYTE *Lfn;
int i;
if(fat_get->DirIndex>=2)Sector=fat_get->DirSectorNum;
else Sector=fat_get->DirSectorNum-1;
if(RBC_Read(Sector,1,Cache)==FALSE)
if(RBC_Read(Sector,1,Cache)==FALSE)
return FALSE;
Lfn = (BYTE *) Cache + 0x20 * (fat_get->DirIndex-1);
dir=(struct _DIR *)((char *) Cache + 0x20 * (fat_get->DirIndex-2));
if((dir->Attr & 0xF) != 0xF)
return TmpLen;
do{
Lfn -= 32;
for(i=0; i<31; i++){
if((i==10) | (i==11) | (i==12) | (i==25) | (i==26))
continue;
filename[TmpLen++] = Lfn[i+1];
if(Lfn[i+1]==0)
break;
i++; //Skip past the Unicode Hi byte
}
if(Lfn<Cache)
{
if(RBC_Read(Sector,1,Cache)==FALSE)
if(RBC_Read(Sector,1,Cache)==FALSE)
return FALSE;
Lfn = Cache+512-32;
}
}while(!(Lfn[0] & 0x40));
filename[TmpLen]=0;
return TmpLen;
}
unsigned char GetFirstFile(char* filename)
{
INT32 Sector;
unsigned int i;
WORD Cluster;
Sector = FirstRootDirSecNum;
fat_get.DirIndex = 0;
for(i=0; i<Bpb.RootEntCnt * sizeof(struct _DIR) / Bpb.BytsPerSec; i++)
{
if(SectorGet(Sector++, &fat_get) == 0)
{
if(fat_get.DirIndex!=1||fat_get.DirSectorNum!=FirstRootDirSecNum)
{
if(GetLongFileName(&fat_get,filename)!=0)
return TRUE;
}
strcpy(filename, fat_get.filename);
return TRUE;
}
}
return FALSE;
}
unsigned char GetnextFile(char* filename)
{
INT32 Sector;
unsigned int i;
WORD Cluster;
Sector = fat_get.DirSectorNum;
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)
{
if(fat_get.DirIndex!=1||fat_get.DirSectorNum!=FirstRootDirSecNum)
{
if(GetLongFileName(&fat_get,filename)!=0)
return TRUE;
}
strcpy(filename, fat_get.filename);
return TRUE;
}
}
return FALSE;
}
unsigned char GetFileStat( const char *filename, struct _STAT* stat)
{
INT32 SectorNum;
struct _FILE file;
SectorNum = Locate(filename, &file);
if(SectorNum == 0xffffffff)
return FALSE;
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 TRUE;
}
unsigned char fat_open(const char* filename)
{
INT32 FirstSectorNum;
if(handles.valid==TRUE) return FALSE;
FirstSectorNum = Locate(filename, &handles);
if(FirstSectorNum == 0xffffffff)
return FALSE;
handles.StartSectorNum = FirstSectorNum;
handles.CurrentSectorNum = handles.StartSectorNum;
handles.SectorOffset = 0;
handles.offset = 0;
handles.valid = 1;
return TRUE;
}
unsigned char fat_close()
{
BYTE Cache[512];
struct _DIR *dir;
if(RBC_Read(handles.DirSectorNum,1,Cache)==FALSE)
if(RBC_Read(handles.DirSectorNum,1,Cache)==FALSE)
return FALSE;
dir = (struct _DIR *)Cache;
dir += handles.DirIndex;
memcpy(dir, &handles.dir, sizeof(struct _DIR));
if(!RBC_Write(handles.DirSectorNum,1,Cache,TRUE))
if(!RBC_Write(handles.DirSectorNum,1,Cache,TRUE))
return FALSE;
handles.valid = 0;
return TRUE;
}
WORD GetNextClusterNum(WORD ClusterNum)
{
return FatCache[ClusterNum];
}
unsigned int fat_read(void* buffer, unsigned int bytes)
{
BYTE Cache[512],*pCache;
unsigned int read_bytes =0;
unsigned int max_copy_bytes_in_sector;
WORD Cluster;
int i;
bytes = (handles.dir.FileSize - handles.offset) > bytes ? bytes : (handles.dir.FileSize - handles.offset);
Cluster = SectorNum2ClusterNum(handles.CurrentSectorNum);
i = (handles.CurrentSectorNum - FirstDataSector) % Bpb.SecPerClus;
if(i != 0)
{
for(; i< Bpb.SecPerClus; i++)
{
if(RBC_Read(handles.CurrentSectorNum,1,(unsigned char *)Cache)==FALSE)return 0;
pCache=Cache;
pCache += handles.SectorOffset;
max_copy_bytes_in_sector = (Bpb.BytsPerSec - handles.SectorOffset) > (bytes - read_bytes) ? (bytes - read_bytes) : (Bpb.BytsPerSec - handles.SectorOffset);
memcpy(buffer, pCache, max_copy_bytes_in_sector);
read_bytes += max_copy_bytes_in_sector;
handles.SectorOffset += max_copy_bytes_in_sector;
handles.offset += max_copy_bytes_in_sector;
buffer = (char*)buffer + max_copy_bytes_in_sector;
if(handles.SectorOffset == Bpb.BytsPerSec)
{
if(i == Bpb.SecPerClus -1)
{
Cluster = GetNextClusterNum(Cluster);
if(Cluster != 0xffff)
handles.CurrentSectorNum = ClusterNum2SectorNum(Cluster);
}
else
handles.CurrentSectorNum ++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -