📄 fat.c
字号:
#include "FAT.h"
#include "UNICODE.H"
#define MAX_DIR_NU_List 20
static INT8U Get_BPB_Flag =0;
INT8U Data_Buffer[512];
BPB sBPB;
BPB *FAT_BPB;
DIR_LIST Sup_Dir;
struct QueueDL
{
DIR_LIST Directory_List[MAX_DIR_NU_List];
INT8U front,rear;
}QU_DIR_List;
void IintQueueDL(struct QueueDL *Q)
{
Q->front = 0;
Q->rear = 0;
}
void EnQueueDL(struct QueueDL *Q, DIR_LIST *x)
{//向队列插入元素
if((Q->rear + 1) % MAX_DIR_NU_List == Q->front)
{//队列满时将产生覆盖
Q->front = (Q->front + 1) % MAX_DIR_NU_List; //使队首元素指向下一个位置
}
Q->rear = (Q->rear + 1) % MAX_DIR_NU_List;
Q->Directory_List[Q->rear].FstClu = x->FstClu;
Q->Directory_List[Q->rear].FileSize = x->FileSize;
}
DIR_LIST *GetElemQDL(struct QueueDL *Q,INT8U pos)
{//读取POS位置的元素
if(pos < 1 || pos > MAX_DIR_NU_List)
return((void *)0);
return(&Q->Directory_List[(Q->front + pos) % MAX_DIR_NU_List]);
}
BPB *Get_BPB(void)
{
SD_read_sector(0 , Data_Buffer);
sBPB.BytsPerSec = ((INT16U)Data_Buffer[OFBPB_BytsPerSec+1] << 8) | Data_Buffer[OFBPB_BytsPerSec];
sBPB.SecPerClus = Data_Buffer[OFBPB_SecPerClus];
sBPB.RsvdSecCnt = ((INT16U)Data_Buffer[OFBPB_RsvdSecCnt+1] << 8) | Data_Buffer[OFBPB_RsvdSecCnt];
sBPB.NumFATs = Data_Buffer[OFBPB_NumFATs];
sBPB.RootEntCnt = ((INT16U)Data_Buffer[OFBPB_RootEntCnt+1] << 8) | Data_Buffer[OFBPB_RootEntCnt];
sBPB.TotSec16 = ((INT16U)Data_Buffer[OFBPB_TotSec16+1] << 8) | Data_Buffer[OFBPB_TotSec16];
sBPB.FATSz16 = ((INT16U)Data_Buffer[OFBPB_FATSz16+1] << 8) | Data_Buffer[OFBPB_FATSz16];
sBPB.HiddSec = ((INT32U)Data_Buffer[OFBPB_HiddSec+3] << 24) | ((INT32U)Data_Buffer[OFBPB_HiddSec+2] << 16) | ((INT32U)Data_Buffer[OFBPB_HiddSec+1] << 8) | Data_Buffer[OFBPB_HiddSec];
sBPB.TotSec32 = ((INT32U)Data_Buffer[OFBPB_TotSec32+3] << 24) | ((INT32U)Data_Buffer[OFBPB_TotSec32+2] << 16) | ((INT32U)Data_Buffer[OFBPB_TotSec32+1] << 8) | Data_Buffer[OFBPB_TotSec32];
sBPB.FATSz32 = ((INT32U)Data_Buffer[OFBPB_FATSz32+3] << 24) | ((INT32U)Data_Buffer[OFBPB_FATSz32+2] << 16) | ((INT32U)Data_Buffer[OFBPB_FATSz32+1] << 8) | Data_Buffer[OFBPB_FATSz32];
sBPB.RootClus = ((INT32U)Data_Buffer[OFBPB_RootClus+3] << 24) | ((INT32U)Data_Buffer[OFBPB_RootClus+2] << 16) | ((INT32U)Data_Buffer[OFBPB_RootClus+1] << 8) | Data_Buffer[OFBPB_RootClus];
RootDirSectors = ((sBPB.RootEntCnt * 32) + (sBPB.BytsPerSec - 1)) / sBPB.BytsPerSec;
if(sBPB.FATSz16 != 0)
FATSize = sBPB.FATSz16;
else
FATSize = sBPB.FATSz32;
FirstDataSector = sBPB.RsvdSecCnt + (sBPB.NumFATs * FATSize) + RootDirSectors;
if(sBPB.TotSec16 != 0)
TotSector = sBPB.TotSec16;
else
TotSector = sBPB.TotSec32;
DataSector = TotSector - (sBPB.RsvdSecCnt + (sBPB.NumFATs * FATSize) + RootDirSectors);
CountOfCluster = DataSector / sBPB.SecPerClus;
if(CountOfCluster < 4085)
sBPB.FilSysType = IsFAT12;
else if(CountOfCluster < 65525)
sBPB.FilSysType = IsFAT16;
else
sBPB.FilSysType = IsFATA32;
return(&sBPB);
}
void Uincode_to_GB(INT16U * x)
{
INT16U a,b,c;
if(((*x) >= 0x0020) && ((*x) <= 0x007E))
{
if((*x) >= 'a' && (*x) <= 'z')
(*x)-='a'-'A';
*x+=0xA380;
return;
}
if((*x)<Unicode[0][0])
{
*x=0x3F3F;
return;
}
if((*x)>Unicode[UNICODE_MAX-1][0])
{
*x=0x3F3F;
return;
}
a=0;
b=UNICODE_MAX-1;
do //采用二分查表法,因为该表为顺序表
{
c=(a+b)/2;
if((*x)==Unicode[c][0])
{
*x=Unicode[c][1];
return;
}
if((*x)<Unicode[c][0])
{
b=(a+b)/2;
}
else
{
a=(a+b+1)/2;
}
} while(a!=b);
if((*x)==Unicode[a][0])
{
*x=Unicode[a][1];
return;
}
*x=0x3F3F; //如果找不到,则显示??
}
void Print_DIR_List(INT16U SecOfDir,INT32U FistDirSecNum)
{
INT16U i,j,k;
INT8U Sname[18];
INT8U temp8u,List_NU=0;
SDIR sSDIR;
DIR_LIST DIR_LISTx;
SDIR *pSD;
pSD = &sSDIR;
for(i = 0;i < SecOfDir;i++)
{
SD_read_sector((FistDirSecNum + i),Data_Buffer);
for(j=0;j<512;(j+=32))
{
pSD->SName[0] = Data_Buffer[j + OFSDIR_SName];
pSD->SName[1] = Data_Buffer[j + OFSDIR_SName + 1];
pSD->Attr = Data_Buffer[j + OFSDIR_Attr];
if(((pSD->Attr & ATTR_LONG_NAME_MASK) != ATTR_LONG_NAME) && (pSD->SName[0] != 0xE5) && (pSD->SName[0] != 0))
{//找到一个活动的短目录项
if((pSD->Attr & ATTR_VOLUME) == 0)
{//找到一个文件或子目录
if((pSD->SName[0] != '.') && (pSD->SName[1] != '.'))
{
List_NU++;
for(k=2;k<=10;k++)
{
pSD -> SName[k] = Data_Buffer[j + OFSDIR_SName + k];
}
if(List_NU/100 != 0)
Sname[0] = List_NU/100 + 48;
else
Sname[0] = ' ';
temp8u = List_NU%100;
if(List_NU/10 != 0)
Sname[1] = temp8u/10 + 48;
else
Sname[1] = ' ';
Sname[2] = temp8u % 10 + 48;
Sname[3] = '-';
temp8u=4;
for(k=0;k<=10;k++)
{
if(pSD -> SName[k] != 0x20)
{
if(k == 8)
{
Sname[temp8u] = '.';
temp8u++;
}
Sname[temp8u] = pSD -> SName[k];
temp8u++;
}
}
Sname[temp8u] = '\n';
Sname[temp8u+1] = '\0';
Sname[16] = '\n';
Sname[17] = '\0';
pSD->FstCluH = Data_Buffer[j + OFSDIR_FstCluH + 1]*256 + Data_Buffer[j + OFSDIR_FstCluH];
pSD->FstCluL = Data_Buffer[j + OFSDIR_FstCluL +1 ]*256+ Data_Buffer[j + OFSDIR_FstCluL];
pSD->FileSize = ((INT32U)Data_Buffer[j + OFSDIR_FileSize + 3] << 24) | ((INT32U)Data_Buffer[j + OFSDIR_FileSize + 2] << 16) | ((INT32U)Data_Buffer[j | OFSDIR_FileSize + 1] << 8) | ((INT32U)Data_Buffer[j + OFSDIR_FileSize]);
DIR_LISTx.FstClu = ((INT32U)pSD -> FstCluH << 16) | pSD -> FstCluL;
DIR_LISTx.FileSize = pSD->FileSize;
EnQueueDL(&QU_DIR_List,&DIR_LISTx);
uar_putchar(Sname);
}
else if(pSD->SName[1] == '.')
{//指向上层目录
pSD->FstCluH = Data_Buffer[j + OFSDIR_FstCluH + 1]*256 + Data_Buffer[j + OFSDIR_FstCluH];
pSD->FstCluL = Data_Buffer[j + OFSDIR_FstCluL +1 ]*256+ Data_Buffer[j + OFSDIR_FstCluL];
pSD->FileSize = ((INT32U)Data_Buffer[j + OFSDIR_FileSize + 3] << 24) | ((INT32U)Data_Buffer[j + OFSDIR_FileSize + 2] << 16) | ((INT32U)Data_Buffer[j | OFSDIR_FileSize + 1] << 8) | ((INT32U)Data_Buffer[j + OFSDIR_FileSize]);
Sup_Dir.FstClu = ((INT32U)pSD -> FstCluH << 16) | pSD -> FstCluL;
Sup_Dir.FileSize = pSD->FileSize;
}
}
}
else if(pSD->SName[0] == 0x00)
{//此目录为空,并且后续的磁盘空间都为空
i = 0xFFF0;
break;
}
}
}
}
void DIR(DIR_LIST *Directory_List)
{
//INT16U i;
INT32U FirstSectorOfCluster; //给定一个簇号N,该簇的第一个扇区
INT32U ThisFATSceNum; //FAT表中包含该簇号N的扇区号
INT16U ThisFATEntOffset; //该簇号N位于FAT表中FAT项的偏移量 INT32U FATOffset;
INT16U NextCluOfFAT16;
INT32U FATOffset;
if(!Get_BPB_Flag)
{
FAT_BPB = Get_BPB();
Get_BPB_Flag = 1;
}
if((Directory_List == (void *)0) || (Directory_List->FstClu == 0))
{//是根目录
if(FAT_BPB -> FilSysType == IsFAT16)
{
FistRootDirSecNum = FAT_BPB->RsvdSecCnt + (FAT_BPB->NumFATs * FAT_BPB->FATSz16);
Print_DIR_List(RootDirSectors,FistRootDirSecNum);
}
}
else if(Directory_List != (void *)0)
{
if(FAT_BPB -> FilSysType == IsFAT16)
{
FATOffset = Directory_List->FstClu * 2;
FirstSectorOfCluster = ((Directory_List->FstClu - 2) * FAT_BPB->SecPerClus) + FirstDataSector;
do
{
ThisFATSceNum = FAT_BPB->RsvdSecCnt + (FATOffset / FAT_BPB->BytsPerSec);
ThisFATEntOffset = FATOffset % FAT_BPB->BytsPerSec;
SD_read_sector(ThisFATSceNum,Data_Buffer);
NextCluOfFAT16 = ((INT16U)Data_Buffer[ThisFATEntOffset + 1] << 8) | Data_Buffer[ThisFATEntOffset];
FATOffset = NextCluOfFAT16 * 2;
Print_DIR_List(FAT_BPB->SecPerClus,FirstSectorOfCluster);
FirstSectorOfCluster = ((NextCluOfFAT16 - 2) * FAT_BPB->SecPerClus) + FirstDataSector;
} while((NextCluOfFAT16 >= 0x0002) && (NextCluOfFAT16 <= 0xFFEF));
}
}
}
void ChDir(INT8U List_NU)
{
DIR_LIST *Dir_List_Nu;
if(List_NU == '/')
{
IintQueueDL(&QU_DIR_List);
DIR((void *)0);
}
else if(List_NU == '.')
{
IintQueueDL(&QU_DIR_List);
DIR(&Sup_Dir);
}
else
{
IintQueueDL(&QU_DIR_List);
Dir_List_Nu = GetElemQDL(&QU_DIR_List,List_NU);
DIR(Dir_List_Nu);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -