📄 fat.c
字号:
}
if(next)
{
return 0;
}
continue;
}
}
else if(*mac=='?')
{
if(*src==0x20) return 0;
}
else
{
if(!EQU(*src,*mac)) return 0;
}
src++;
mac++;
}
return 1;
}
/**static DRIVER_INFO*get_driver_by_name(char lable)****
功能:
根据磁盘名称在返回驱动器指针
入口:
char lable:磁盘名称,'A'-'Z'
出口:
调用成功返回驱动器指针,否则返回0
调用者:
任意
备注:
无
*************************************************/
static DRIVER_INFO*get_driver_by_name(char lable)
{
DWORD i;
lable=to_upper(lable);
if(lable<START_DRIVER_LABLE||lable>'Z') return (DRIVER_INFO*)0;
i=lable-START_DRIVER_LABLE;
if(i>=MAX_DRIVERS_NUMBER) return (DRIVER_INFO*)0;
return (DRIVER_INFO*)drivers[i];
}
/**static BYTE DOS2FAT(BYTE*lpszName)**********************
功能:
8.3 DOS文件名转换为83 FAT文件名
入口:
BYTE*lpszName:DOS文件名指针
出口:
文件名无效,返回0x00,
全部小写,返回0x08
全部大写,返回0x10
大小写混合,返回0x20
调用者:
内部任意
备注:
1."aaa" --->"AAA "
2."b.aaa" --->"B AAA"
3."aabb.cc" --->"AABB CC "
*********************************************************/
static BYTE DOS2FAT(BYTE*lpszName)
{
BYTE lpszFAT[13];
BYTE i,j;
BYTE NTres;
BOOL bHasLower=0,bHasUpper=0;
BYTE dot=0;
for(i=0;i<9;i++)
{
switch(lpszName[i])
{
case '\\':
case '/':
case ':':
case '*':
case '?':
case '"':
case '<':
case '>':
case '|':
case ' ':
return 0;
case 0x00:/*结束,则剩余的全部为0x20*/
for(;i<11;i++) lpszFAT[i]=0x20;
lpszFAT[i]=0;
for(i=0;i<12;i++) lpszName[i]=lpszFAT[i];
if(lpszName[0]==0x20||!lpszName[0]) return 0;
if(!bHasUpper&&bHasLower) NTres=0x08;
else if(bHasUpper&&!bHasLower) NTres=0x10;
else NTres=0x20;
return NTres;
case '.':/*发现点*/
j=i+1;
for(;i<8;i++) lpszFAT[i]=0x20;
dot=1;
continue;
}
if(is_upper(lpszName[i])) bHasUpper=1;
else if(is_lower(lpszName[i])) bHasLower=1;
lpszFAT[i]=to_upper(lpszName[i]);
}
if(i>=8&&!dot) return 0;
for(i=8;i<12;i++,j++)
{
switch(lpszName[j])
{
case '\\':
case '/':
case ':':
case '*':
case '?':
case '"':
case '<':
case '>':
case '|':
case ' ':
return 0;
case 0x00:
for(;i<11;i++) lpszFAT[i]=0x20;
lpszFAT[i]=0;
for(i=0;i<12;i++) lpszName[i]=lpszFAT[i];
if(lpszName[0]==0x20||!lpszName[0]) return 0;
if(!bHasUpper&&bHasLower) NTres=0x08;
else if(bHasUpper&&!bHasLower) NTres=0x10;
else NTres=0x20;
return NTres;
case '.':
if(dot) return 0;
dot=1;
continue;
}
if(is_upper(lpszName[i])) bHasUpper=1;
else if(is_lower(lpszName[i])) bHasLower=1;
lpszFAT[i]=to_upper(lpszName[j]);
}
lpszFAT[12]=0;
for(i=0;i<12;i++) lpszName[i]=lpszFAT[i];
if(lpszName[0]==0x20||!lpszName[0]) return 0;
if(!bHasUpper&&bHasLower) NTres=0x08;
else if(bHasUpper&&!bHasLower) NTres=0x10;
else NTres=0x20;
return NTres;
}
/**static BOOL FAT2DOS(BYTE*lpszName,BOOL bLower)**********
功能:
83 FAT文件名转换为8.3 DOS文件名
入口:
BYTE*lpszName:FAT文件名指针
BOOL bLower:是否转换成小写
出口:
调用成功返回1,否则返回0
调用者:
内部任意
备注:
DOS名一般为小写,如果需要大写,则必须使用长文件名
*********************************************************/
static BOOL FAT2DOS(BYTE*lpszName,BOOL bLower)
{
BYTE lpszDOS[13];
BYTE i,j;
BYTE dot=0;
for(i=0;i<8;i++)
{
if(lpszName[i]==0x20)
{
if(lpszName[8]==0x20)
{
lpszDOS[i]=0;
SYS_strcpy(lpszName,lpszDOS);
return 1;
}
else
{
lpszDOS[i]='.';
j=i+1;
dot=1;
break;
}
}
if(bLower)
lpszDOS[i]=to_lower(lpszName[i]);
else
lpszDOS[i]=lpszName[i];
}
if(lpszName[8]==0x20||lpszName[8]==0x00)
{
lpszDOS[i]=0;
SYS_strcpy(lpszName,lpszDOS);
return 1;
}
if(i==8&&dot==0)
{
lpszDOS[i]='.';
j=i+1;
}
for(i=8;i<11;i++,j++)
{
if(lpszName[i]==0x20)
{
lpszDOS[j]=0;
SYS_strcpy(lpszName,lpszDOS);
return 1;
}
if(bLower)
lpszDOS[j]=to_lower(lpszName[i]);
else
lpszDOS[j]=lpszName[i];
}
lpszDOS[j]=0;
SYS_strcpy(lpszName,lpszDOS);
return lpszName[0]!=0x20;
}
/**static DWORD get_first_sector_of_cluster(DRIVER_INFO*driver,DWORD dwCluster)****************
功能:
获取簇的第一个扇区地址
入口:
DRIVER_INFO*driver:驱动器结构指针
DWORD dwCluster:簇号码
出口:
返回相对于物理驱动器第一个扇区的扇区地址
调用者:
内部任意
备注:
dwCluster按照Microsoft的PDF,必须保证dwCluster>=2
******************************************************************************************/
static DWORD get_first_sector_of_cluster(DRIVER_INFO*driver,DWORD dwCluster)
{
DWORD dwSector;
if(dwCluster<2)
{
dwSector=driver->dwRootSectorStart;
}
else
{
dwSector=(dwCluster-2)*driver->dwSectorsPerCluster;
dwSector+=driver->dwDataSectorStart;
}
return(dwSector);
}
/**static DWORD get_cluster_of_first_sector(DRIVER_INFO*driver,DWORD dwSector)********
功能:
获取扇区所在的簇地址
入口:
DRIVER_INFO*driver:驱动器结构指针
DWORD dwSector:扇区号
出口:
返回相对于物理驱动器第一个扇区的扇区地址
调用者:
内部任意
备注:
无
******************************************************************************************/
static DWORD get_cluster_of_first_sector(DRIVER_INFO*driver, DWORD dwSector)
{
DWORD dwCluster;
if(driver->bFAT32)
{
dwSector-=driver->dwDataSectorStart;
}
else
{
if(dwSector<driver->dwDataSectorStart)
return 1;
else
dwSector-=driver->dwDataSectorStart;
}
dwCluster=(dwSector/driver->dwSectorsPerCluster)+2;
return(dwCluster);
}
/**static DWORD get_next_cluster_of_file(DRIVER_INFO*driver,DWORD dwFirstCluster)********
功能:
返回一个文件的下一个簇
入口:
DRIVER_INFO*driver:驱动器结构指针
DWORD dwFirstCluster:当前簇号码
出口:
调用成功返回一个有效的簇号,否则返回0x0000
调用者:
内部任意
备注:
无
******************************************************************************************/
static DWORD get_next_cluster_of_file(DRIVER_INFO*driver,DWORD dwFirstCluster)
{
DWORD dwNext=0x0000;
DWORD dwSector;
DWORD dwOffset;
BYTE*lpszOffset;
BYTE* lpszSectors;
DWORD dwSize;
if(!driver||dwFirstCluster<2) return 0x0000;
dwSize=driver->dwBytesPerSector>>(driver->bFAT32+1);
dwSector=driver->dwFATSectorStart[0]+dwFirstCluster/dwSize;
dwOffset=(dwFirstCluster%dwSize)*(driver->bFAT32?4:2);
lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
if(driver->lpfnRead(dwSector,lpszSectors,driver->dwBytesPerSector,driver->user_data))
{
lpszOffset=lpszSectors+dwOffset;
if(driver->bFAT32)
{
dwNext=GETDWORD(lpszOffset);
}
else
{
dwNext=GETWORD(lpszOffset);
}
}
if(dwNext==(DWORD)(driver->bFAT32?0x0fffffff:0xffff)) dwNext=0x0000;
SYS_free(lpszSectors);
return dwNext;
}
/**static BOOL get_fat_entry(DRIVER_INFO*driver,DWORD dwClusters,DWORD*dwSector,DWORD*dwOffset)***************
功能:
获取FAT入口扇区号码和偏移
入口:
DRIVER_INFO*driver:驱动器指针
DWORD dwClusters:簇号
DWORD*dwSector[2]:返回dwClusters在FAT1,FAT2的扇区号
DWORD*dwOffset[2]:返回dwClusters在FAT1,FAT2扇区中的偏移
出口:
调用成功返回1,否则返回0
调用者:
任意
备注:
无
*******************************************************************************************************************/
static BOOL get_fat_entry(DRIVER_INFO*driver,DWORD dwClusters,DWORD*dwSector,DWORD*dwOffset)
{
DWORD start;
DWORD offset;
DWORD size;
if(!driver||dwClusters<2) return 0;
size=driver->dwBytesPerSector>>(driver->bFAT32+1);
start=driver->dwFATSectorStart[0]+dwClusters/size;
offset=(dwClusters%size)*(driver->bFAT32?4:2);
if(dwSector) *dwSector=start;
if(dwOffset) *dwOffset=offset;
return 1;
}
/**static DWORD get_free_fat_entry(DRIVER_INFO*driver,DWORD*dwSector,DWORD*dwOffset)***************
功能:
获取FAT入口扇区号码和偏移
入口:
DRIVER_INFO*driver:驱动器指针
DWORD*dwSector[2]:返回空闲簇在FAT1,FAT2的扇区号
DWORD*dwOffset[2]:返回空闲簇在FAT1,FAT2扇区中的偏移
出口:
调用成功返回空闲的簇号,否则返回0
调用者:
任意
备注:
无
*******************************************************************************************************************/
static DWORD get_free_fat_entry(DRIVER_INFO*driver,DWORD*dwSector,DWORD*dwOffset)
{
DWORD dwStart,dwEnd;
BYTE*lpszSectors;
BYTE*ptr;
DWORD dwFreeCluster=0x0000;
DWORD i,j,k;
DWORD dwSize;
DRIVER_INFO*temp;
if(!driver) return 0;
lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
if(!lpszSectors) return 0;
temp=get_driver_by_name(driver->DriverName);
dwStart=driver->dwFATSectorStart[0];
dwEnd=driver->dwFATSectorStart[1];
dwSize=driver->dwBytesPerSector>>(driver->bFAT32+1);
for(i=dwStart;i<dwEnd;i++)
{
if(!driver->lpfnRead(i,lpszSectors,driver->dwBytesPerSector,driver->user_data))
{
SYS_free(lpszSectors);
return 0;
}
ptr=lpszSectors;
for(j=0;j<dwSize;j++)
{
k=driver->bFAT32?GETDWORD(ptr):GETWORD(ptr);
if(k==0x0000&&dwFreeCluster>=2)
{
if(dwSector) *dwSector=i;
if(dwOffset) *dwOffset=j*(driver->bFAT32+1)*2;
update_fat_entry(driver,dwFreeCluster,driver->bFAT32?0x0fffffff:0xffff);
SYS_free(lpszSectors);
temp->dwFreeClusters--;
return dwFreeCluster;
}
dwFreeCluster++;
}
}
return 0x0000;
}
/**static BOOL update_fat_entry(DRIVER_INFO*driver,DWORD dwCurrentCluster,DWORD dwNextCluster)********
功能:
更新FAT表
入口:
DRIVER_INFO*driver:驱动器指针
DWORD dwCurrentCluster:要更新的簇索引
DWORD dwNextCluster:dwCurrentCluster的下一个簇号
出口:
调用成功返回1,否则返回0
调用者:
内部任意
备注:
无
******************************************************************************************************/
static BOOL update_fat_entry(DRIVER_INFO*driver,DWORD dwCurrentCluster,DWORD dwNextCluster)
{
DWORD dwSector,dwOffset;
BYTE*ptr;
BYTE* lpszSectors;
DWORD size;
DWORD i;
if(!driver) return 0;
lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
size=driver->dwBytesPerSector>>(driver->bFAT32+1);
dwSector=driver->dwFATSectorStart[0]+dwCurrentCluster/size;
dwOffset=(dwCurrentCluster%size)*(driver->bFAT32?4:2);
if(!driver->lpfnRead(dwSector,lpszSectors,driver->dwBytesPerSector,driver->user_data))
{
SYS_free(lpszSectors);
return 0;
}
ptr=lpszSectors+dwOffset;
if(driver->bFAT32)
{
SETDWORD(ptr,dwNextCluster);
}
else
{
SETWORD(ptr,dwNextCluster);
}
for(i=0;i<driver->dwNumFATs;i++)
{
dwSector=driver->dwFATSectorStart[i]+dwCurrentCluster/size;
#if MUST_ERASE_BEFORE_WRITE==1
if(!driver->lpfnErase(dwSector,driver->dwBytesPerSector,driver->user_data))
{
SYS_free(lpszSectors);
return 0;
}
#endif
if(!driver->lpfnWrite(dwSector,lpszSectors,driver->dwBytesPerSector,driver->user_data))
{
SYS_free(lpszSectors);
return 0;
}
}
SYS_free(lpszSectors);
return 1;
}
/**static BOOL get_dir_entry(DRIVER_INFO*driver,BYTE*name,DWORD*dwSector,DWORD*dwOffset,BYTE*dir)**********
功能:
根据文件名称或者目录索引在当前目录中搜索目录信息
入口:
DRIVER_INFO*driver:驱动器指针
BYTE*name:文件名称(FAT格式),如果name==NULL则表示按目录索引查找信息
DWORD*dwSector:扇区号指针
DWORD*dwOffset:偏移指针
BYTE*dir:32字节的目录信息指针
出口:
调用成功返回1,否则返回0
备注:
如果name!=NULL,则name必须为一个有效的FAT格式文件名称
如果name==NULL,则dwSector和dwOffset都不能为NULL,此时dwSector和dwOffset指定目录的索引信息
**********************************************************************************************************/
static BOOL get_dir_entry(DRIVER_INFO*driver,BYTE*name,DWORD*dwSector,DWORD*dwOffset,BYTE*dir)
{
DWORD dwStart,dwEnd;
DWORD dwCluster;
BYTE*lpszSectors;
BYTE*ptr;
#if(SUPPORT_LONG_NAME==1)
BYTE *lPtr;
BYTE longname[256];
#endif
DWORD i,j,k;
if(!driver) return 0;
lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
if(!lpszSectors) return 0;
if(!name)/*如果name==NULL,则采用索引dwSector,dwOffset来获取信息*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -