📄 fat.c
字号:
#include "fat.h"
UInt16 FAT_GetInt16(unsigned char *pBuf)
{
UInt16 ret;
ret=pBuf[1];
ret=(ret<<8)+pBuf[0];
return ret;
}
UInt32 FAT_GetInt32(unsigned char *pBuf)
{
UInt32 ret;
ret=pBuf[3];
ret=(ret<<8)+pBuf[2];
ret=(ret<<8)+pBuf[1];
ret=(ret<<8)+pBuf[0];
return ret;
}
void FAT_SetInt16(unsigned char *pBuf,UInt16 value)
{
pBuf[1]=(unsigned char)(value>>8);
pBuf[0]=(unsigned char)(value&0xff);
}
void FAT_SetInt32(unsigned char *pBuf,UInt32 value)
{
pBuf[3]=value>>24;
pBuf[2]=value>>16;
pBuf[1]=value>>8;
pBuf[0]=value;
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
unsigned char ChkSum (unsigned char *pFcbName)
{
short FcbNameLen;
unsigned char Sum;
Sum = 0;
for (FcbNameLen=11; FcbNameLen!=0; FcbNameLen--) {
Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *pFcbName++;
}
return (Sum);
}
UInt32 FAT_FileterFileName(unsigned char *FileName, unsigned char *LongFileName)
{
UInt32 namePointer = 0;
unsigned char ch;
if(*FileName == '.') return 0;
while(*FileName == ' ') FileName++;
while(FileName[namePointer] != 0)
{
ch = FileName[namePointer];
if(ch == '\\' || ch == '/' || ch == ':' || ch == '*' || ch == '?'
|| ch == '"' || ch == '<' || ch == '>' || ch == '|') return 0;
namePointer++;
}
while(FileName[namePointer - 1] == '.' || FileName[namePointer - 1] == ' ')
{
FileName[namePointer - 1] = 0;
namePointer--;
}
MemCopy(FileName, LongFileName, namePointer + 1);
return 1;
}
UInt32 FAT_CheckLongShortName(unsigned char *FileName)//return 1:Long. 0:Short 2:混合大小写
{
UInt32 namePointer = 0, namePointer2 = 0;
unsigned char lowFlag = 0, upperFlag = 0, periodNum = 0;
unsigned char ch;
while(1)
{
ch = FileName[namePointer];
if(ch == 0) break;
if(ch <= 'Z' && ch >= 'A') upperFlag++;
if(ch <= 'z' && ch >= 'a') lowFlag++;
if(upperFlag && lowFlag) return 2;
if(periodNum == 1) namePointer2++;
if(ch == '.') periodNum++;
if(periodNum > 1) return 1;
if(ch == ' ') return 1;
if(ch == '+' || ch == '[' || ch == ']' || ch == ';' || ch == ',' || ch == '=') return 1;
if((periodNum == 0 && namePointer >= 8) || (namePointer2 >= 4)) return 1;
namePointer++;
}
return 0;
}
void FAT_Char2UnicodeMemCopy(unsigned char *source, unsigned char *det, UInt16 len)
{
UInt16 ix;
for(ix = 0; ix < len; ix++)
{
FAT_SetInt16(det + ix * 2, *(source + ix));
}
}
void FAT_Unicode2CharMemCopy(unsigned char *source, unsigned char *det, UInt16 len)
{//len是copy多少个字符,而不是字节
UInt16 ix, w_ch;
for(ix = 0; ix < len; ix++)
{
w_ch = FAT_GetInt16(source + ix * 2);
*(det + ix) = (unsigned char)(w_ch & 0xff);
}
}
//这不能填充chksum项,须知道短文件名
//LongFileName是以单字符存储的// i 从1 开始
void GetLongFdt(unsigned char *LongFileName, unsigned char *fdt, unsigned char ShortSum, UInt32 i)
{
UInt32 namePointer = 0;
UInt16 len;
unsigned char name[32];
while(LongFileName[namePointer] != 0) namePointer++;
len = ((namePointer - 1) % 13) + 1;
if((namePointer - 1 + 12) / 13 < i)
{
fdt[0] = 0;
return;
}
if((namePointer - 1 + 12) / 13 == i)
{
FAT_Char2UnicodeMemCopy(LongFileName + (i - 1) * 13, name, len + 1);
fdt[0] = (i | 0x40);
MemSet(fdt + 1, 0xff, 10);
MemSet(fdt + 14, 0xff, 12);
MemSet(fdt + 28, 0xff, 4);
if(len < 5)
{
MemCopy(name, fdt + 1, (len + 1) * 2);//1: 结束字符
}
if(len >= 5 && len < 11)
{
MemCopy(name, fdt + 1, 10);
MemCopy(name + 10, fdt + 14, (len - 5 + 1) * 2);//1: 结束字符
}
if(len >= 11 && len <= 13)
{
MemCopy(name, fdt + 1, 10);
MemCopy(name + 10, fdt + 14, 12);
if(len != 13) MemCopy(name + 22, fdt + 28, (len - 11 + 1) * 2);//1: 结束字符
else MemCopy(name + 22, fdt + 28, (len - 11) * 2);
}
}
else
{
FAT_Char2UnicodeMemCopy(LongFileName + (i - 1) * 13, name, 13);
fdt[0] = i;
MemCopy(name, fdt + 1, 10);
MemCopy(name + 10, fdt + 14, 12);
MemCopy(name + 22, fdt + 28, 4);
}
fdt[11] = 0x0f;
fdt[12] = fdt[26] = fdt[27] = 0;
fdt[13] = ShortSum;
}
/***************************************************
CheckLongFile(unsigned char *, unsigned char *)
如果FileName 如果FileName是长文件名称,
则将预定短文件名称设置好返回长文件fdt的个数.****并要返回预设的短文件名的字符数
如果FileName 如果FileName是短文件名称,
则设置将8.3转换为11格式.返回0
***************************************************/
UInt32 CheckLongFile(unsigned char *LongFileName, unsigned char *ShortName)
{
UInt32 LSflag, namePointer = 0, namePointer2 = 0, entryNum, i, j;
unsigned char ch;
LSflag = FAT_CheckLongShortName(LongFileName);//return 1:Long. 0:Short
MemSet(ShortName, 0x20, 11);
ShortName[11] = 0;
if(LSflag == 1)
{
while(LongFileName[namePointer] != 0)
{
if(LongFileName[namePointer] == '.') namePointer2 = namePointer;
namePointer++;
}
if(LongFileName[namePointer2] == '.')
{
for(i = 0; i <= namePointer2 - 1; i++)
{
if(i == 6)break;
ch = LongFileName[i];
if(ch <= 'z' && ch >= 'a') ch -= 32;
if(ch == '+' || ch == '[' || ch == ']' || ch == ';' || ch == ',' || ch == '=')
ch = '_';
ShortName[i] = ch;
}
namePointer2++;
j = 0;
while(j < 3 && LongFileName[namePointer2] != 0)
{
ShortName[8 + j] = LongFileName[namePointer2];
j++;
namePointer2++;
}
}
else
{
for(i = 0; i <= namePointer - 1; i++)
{
if(i == 6)break;
ch = LongFileName[i];
if(ch <= 'z' && ch >= 'a') ch -= 32;
if(ch == '+' || ch == '[' || ch == ']' || ch == ';' || ch == ',' || ch == '=')
ch = '_';
ShortName[i] = ch;
}
}
ShortName[i] = '~';
ShortName[i + 1] = '1';
entryNum = (namePointer + 12) / 13;
return (entryNum);// || (i << 16));
}
else
{
namePointer = 0, namePointer2 = 0;
while(LongFileName[namePointer] != 0x2E && LongFileName[namePointer] != 0)
namePointer++;
for(i = 0; i <= namePointer - 1; i++)
{
ch = LongFileName[i];
if(ch >= 'a' && ch <= 'z') ch -= 32;
ShortName[i] = ch;
}
if(LongFileName[namePointer] == 0x2E) namePointer++;
while(LongFileName[namePointer] != 0)
{
ch = LongFileName[namePointer];
if(ch >= 'a' && ch <= 'z') ch -= 32;
ShortName[8 + namePointer2] = ch;
namePointer++;
namePointer2++;
}
return 0;
}
}
void FAT_ReadCluster(PDriver pDriver,UInt32 cluster)
{
unsigned int i,sector;
struct FATDriverMessage* pDriverMessage;
pDriverMessage=(struct FATDriverMessage* )pDriver->MessageObject;
if(pDriverMessage->Cluster==cluster||cluster==1)return;
if(pDriverMessage->Cluster>=pDriverMessage->MaxClusNum)return;
if(cluster==0) sector=pDriverMessage->DataAddr;
else sector=pDriverMessage->DataAddr+(cluster-2)*pDriverMessage->SecPerClus;
for(i=0;i<pDriverMessage->SecPerClus;i++)
Driver_ReadSector(pDriver,sector+i,pDriverMessage->ClusterBuf+512*i);
pDriverMessage->Cluster=cluster;
}
void FAT_WriteCluster(PDriver pDriver)
{
unsigned int i,sector;
struct FATDriverMessage* pDriverMessage;
pDriverMessage=(struct FATDriverMessage* )pDriver->MessageObject;
if(pDriverMessage->Cluster>=pDriverMessage->MaxClusNum) return;
if(pDriverMessage->Cluster==0) sector=pDriverMessage->DataAddr;
else sector=pDriverMessage->DataAddr+(pDriverMessage->Cluster-2)*pDriverMessage->SecPerClus;
for(i=0;i<pDriverMessage->SecPerClus;i++)
Driver_WriteSector(pDriver,sector+i,pDriverMessage->ClusterBuf+512*i);
}
void FAT_FileWriteCluster(PFile pFile)
{
unsigned int i,sector;
struct FATDriverMessage* pDriverMessage;
struct FATFileMessage* pFileMessage;
PDriver pDriver=pFile->DriverObject;
pDriverMessage=(struct FATDriverMessage* )pDriver->MessageObject;
pFileMessage=(struct FATFileMessage* )pFile->MessageObject;
if(pFileMessage->Cluster>=pDriverMessage->MaxClusNum) return;
if(pFileMessage->Cluster==0) return;
if(pFileMessage->Cluster==1) return;
sector=pDriverMessage->DataAddr+(pFileMessage->Cluster-2)*pDriverMessage->SecPerClus;
for(i=0;i<pDriverMessage->SecPerClus;i++)
Driver_WriteSector(pDriver,sector+i,pFile->buffer+512*i);
}
void FAT_FileReadCluster(PFile pFile)
{
unsigned int i;
UInt32 sector;
PDriver pDriver;
struct FATDriverMessage* pDriverMessage;
struct FATFileMessage* pFileMessage;
pDriver=pFile->DriverObject;
pDriverMessage=(struct FATDriverMessage* )pDriver->MessageObject;
pFileMessage=(struct FATFileMessage* )pFile->MessageObject;
if(pFileMessage->Cluster>=pDriverMessage->MaxClusNum) return;
if(pFileMessage->Cluster==0)return;
if(pFileMessage->Cluster==1) return;
sector=pDriverMessage->DataAddr+(pFileMessage->Cluster-2)*pDriverMessage->SecPerClus;
for(i=0;i<pDriverMessage->SecPerClus;i++)
Driver_ReadSector(pDriver,sector+i,pFile->buffer+512*i);
}
UInt32 FAT32_GetNextCluster(PDriver pDriver,UInt32 cluster)
{
UInt32 sector,offset;
struct FATDriverMessage* pDriverMessage;
pDriverMessage=(struct FATDriverMessage* )pDriver->MessageObject;
sector=cluster/128+pDriverMessage->Fat1Addr;
offset=(cluster%128)*4;
if(pDriverMessage->fat!=sector)
{
Driver_ReadSector(pDriver,sector,pDriverMessage->FatBuf);
pDriverMessage->fat=sector;
}
cluster=FAT_GetInt32(pDriverMessage->FatBuf+offset);
if(cluster==0)
{
FAT_SetInt32(pDriverMessage->FatBuf+offset,0xffffffff);
Driver_WriteSector(pDriver,sector,pDriverMessage->FatBuf);
}
return cluster;
}
/***********************************************
//查询父目录中,子目录的所在位置,按簇号搜索
************************************************/
UInt32 FAT_SearchCluster(PDirectory pDirectory)
{
UInt32 FolderClus,FstCluster;
unsigned int i,EntryTotal;
UInt32 LongCluster,LongOffset;
struct FATDriverMessage* pDriverMessage;
struct FATDirectoryMessage* pDirectoryMessage;
unsigned char *ClusterBuf;
PDriver pDriver;
pDriver=pDirectory->DriverObject;
pDriverMessage=(struct FATDriverMessage* )pDriver->MessageObject;
pDirectoryMessage=(struct FATDirectoryMessage*)pDirectory->MessageObject;
ClusterBuf=pDriverMessage->ClusterBuf;
FolderClus=pDirectory->FatherMark;
EntryTotal=pDriverMessage->SecPerClus*16;
while(FolderClus<pDriverMessage->MaxClusNum)
{
FAT_ReadCluster(pDriver,FolderClus);
for(i=0;i<EntryTotal;i++)
{
if(ClusterBuf[i*32]==0)return 0;
if(ClusterBuf[i*32]==0xe5)
{
LongCluster=0xfffffff0;
continue;
}
if(ClusterBuf[i*32+11]==0x0f)
{
if(LongCluster==0xfffffff0)
{
LongCluster=FolderClus;
LongOffset=i;
}
continue;
}
FstCluster=FAT_GetInt16(ClusterBuf+i*32+20);
FstCluster<<=16;
FstCluster+=FAT_GetInt16(ClusterBuf+i*32+26);
if(FstCluster==pDirectory->Mark)
{
if(LongCluster==0xfffffff0)
{
pDirectoryMessage->FatherCluster=FolderClus;
pDirectoryMessage->FatherOffset=i;
}
else
{
pDirectoryMessage->FatherCluster=LongCluster;
pDirectoryMessage->FatherOffset=LongOffset;
}
return 1;
}
LongCluster=0xfffffff0;
}
FolderClus=FAT32_GetNextCluster(pDriver,FolderClus);
}
return 0;
}
UInt32 FAT32_SetNextCluster(PDriver pDriver,UInt32 cluster,UInt32 NextCluster)
{
UInt32 sector,offset;
struct FATDriverMessage* pDriverMessage;
pDriverMessage=(struct FATDriverMessage* )pDriver->MessageObject;
sector=cluster/128+pDriverMessage->Fat1Addr;
offset=(cluster%128)*4;
if(pDriverMessage->fat!=sector)
{
Driver_ReadSector(pDriver,sector,pDriverMessage->FatBuf);
pDriverMessage->fat=sector;
}
cluster=FAT_GetInt32(pDriverMessage->FatBuf+offset);
if(cluster>=pDriverMessage->MaxClusNum)
{
FAT_SetInt32(pDriverMessage->FatBuf+offset,NextCluster);
Driver_WriteSector(pDriver,sector,pDriverMessage->FatBuf);
return cluster;
}
return 0;
}
UInt32 FAT32_MallocCluster(PDriver pDriver)
{
struct FATDriverMessage* pDriverMessage;
UInt32 i,j,EndSector;
unsigned char *FatBuf;
pDriverMessage=(struct FATDriverMessage* )pDriver->MessageObject;
FatBuf=pDriverMessage->FatBuf;
EndSector=pDriverMessage->FATSz+pDriverMessage->Fat1Addr;
for(i=0;i<128;i++)
{
if(FAT_GetInt32(FatBuf+i*4)==0)return i;
}
for(j=pDriverMessage->fat+1;j<EndSector;j++)
{
Driver_ReadSector(pDriver,j,FatBuf);
for(i=0;i<128;i++)
if(FAT_GetInt32(FatBuf+i*4)==0)
{
pDriverMessage->fat=j;
return j*128+i;
}
}
for(j=pDriverMessage->Fat1Addr;j<pDriverMessage->fat;j++)
{
Driver_ReadSector(pDriver,j,FatBuf);
for(i=0;i<128;i++)
if(FAT_GetInt32(FatBuf+i*4)==0)
{
pDriverMessage->fat=j;
return j*128+i;
}
}
return 0;
}
void FAT_GetFdt(PDriver pDriver ,UInt32 cluster, UInt32 offset ,struct FATFdt *pFdt)
{
UInt32 EntryTotal, i, j = 0;
struct FATDriverMessage* pDriverMessage;
pDriverMessage = (struct FATDriverMessage* )pDriver->MessageObject;
EntryTotal = pDriverMessage->SecPerClus * 16;
while(cluster < pDriverMessage->MaxClusNum)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -