📄 fat.c
字号:
{
if(!dwSector||!dwOffset||!dir||(*dwOffset>=driver->dwBytesPerSector>>5)) return 0;
if(!driver->lpfnRead(*dwSector,lpszSectors,driver->dwBytesPerSector,driver->user_data)) return 0;
ptr=lpszSectors+((*dwOffset)<<5);
if(dir)
{
for(i=0;i<32;i++)
{
*dir++=*ptr++;
}
}
SYS_free(lpszSectors);
return 1;
}
dwCluster=get_cluster_of_first_sector(driver,driver->lpCurrentDir->dwSectors);
if(!dwCluster) return 0;
lpszLongName[0]=0;
while(dwCluster)
{
dwStart=get_first_sector_of_cluster(driver,dwCluster);
if(driver->lpCurrentDir==driver->lpLinks&&!driver->bFAT32)
dwEnd=dwStart+(driver->dwDataSectorStart-driver->dwRootSectorStart);
else
dwEnd=dwStart+driver->dwSectorsPerCluster;
for(;dwStart<dwEnd;dwStart++)
{
if(!driver->lpfnRead(dwStart,lpszSectors,driver->dwBytesPerSector,driver->user_data)) return 0;
ptr=lpszSectors;
for(j=0;j<driver->dwBytesPerSector>>5;j++)
{
if(!ptr[0])
{
SYS_free(lpszSectors);
return 0;
}
if(ptr[0]==0xe5||ptr[0]==0x05)
{
ptr+=32;
lpszLongName[0]=0;
continue;/*被删除*/
}
if(!ptr[26]&&!ptr[27]&&ptr[11]==ATTR_LONG_NAME)/*长文件名入口*/
{
#if(SUPPORT_LONG_NAME==1)
if(ptr[0]&0x40)
{
lPtr=(BYTE*)&longname[255];
}
k=get_long_name_len(ptr);
lPtr-=k;
extract_long_name(lPtr,ptr);
if(ptr[0]==0x01)
{
Unicode2Ascii(lPtr,lpszLongName);
}
#endif
ptr+=32;
continue;
}
for(k=0;k<11;k++)
{
if(ptr[k]!=name[k])
break;
}
if(k==11)/*名称匹配*/
{
if(dwSector) *dwSector=dwStart;
if(dwOffset) *dwOffset=j<<5;
if(dir)
{
for(k=0;k<32;k++)
*dir++=*ptr++;
}
SYS_free(lpszSectors);
return 1;
}
lpszLongName[0]=0;
ptr+=32;
}
}
dwCluster=get_next_cluster_of_file(driver,dwCluster);
}
SYS_free(lpszSectors);
return 0;
}
/**static BOOL get_free_dir_entry(DRIVER_INFO*driver,DWORD*dwSector,DWORD*dwOffset,DWORD*dwFirstCluster)**********
功能:
获取当前目录中空闲的目录入口信息
入口:
DRIVER_INFO*driver:驱动器指针
DWORD*dwSector:接收扇区号
DWORD*dwOffset:接收偏移
DWORD*dwFirstCluster:接收开始簇号
出口:
调用成功返回1,否则返回0
调用者:
内部任意
备注:
dwSector,dwOffset,dwFirstCluster可以用NULL,表示不需要返回改数据
*****************************************************************************************************************/
static BOOL get_free_dir_entry(DRIVER_INFO*driver,DWORD*dwSector,DWORD*dwOffset,DWORD*dwFirstCluster)
{
DWORD dwStart,dwEnd;
DWORD dwCluster,dwOld;
BYTE*lpszSectors;
BYTE*ptr;
DWORD i,j;
if(!driver) return 0;
lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
if(!lpszSectors) return 0;
/*获取当前目录的簇号*/
dwCluster=get_cluster_of_first_sector(driver,driver->lpCurrentDir->dwSectors);
if(!dwCluster) return 0;
while(dwCluster)
{
dwStart=get_first_sector_of_cluster(driver,dwCluster);
if(driver->lpCurrentDir==driver->lpLinks&&!driver->bFAT32)
dwEnd=dwStart+driver->dwDataSectorStart-driver->dwRootSectorStart;
else
dwEnd=dwStart+driver->dwSectorsPerCluster;
for(;dwStart<dwEnd;dwStart++)
{
if(!driver->lpfnRead(dwStart,lpszSectors,driver->dwBytesPerSector,driver->user_data))
{
SYS_free(lpszSectors);
return 0;
}
ptr=lpszSectors;
for(j=0;j<driver->dwBytesPerSector>>5;j++)
{
if(*ptr==0xe5||*ptr==0x00)
{
if(dwSector) *dwSector=dwStart;
if(dwOffset) *dwOffset=j<<5;
if(dwFirstCluster)
{
i=get_free_fat_entry(driver,(void*)0,(void*)0);
if(!i)
{
i=dwEnd;
j=driver->dwBytesPerSector>>5;
continue;
}
*dwFirstCluster=i;
}
SYS_free(lpszSectors);
return 1;
}
ptr+=32;
}
}
dwOld=dwCluster;
dwCluster=get_next_cluster_of_file(driver,dwCluster);
if(!dwCluster)
{
dwCluster=get_free_fat_entry(driver,(DWORD*)0,(DWORD*)0);
if(dwCluster)
{
if(!erase_cluster(driver,dwCluster,0xffffffff)||!update_fat_entry(driver,dwOld,dwCluster)||!update_fat_entry(driver,dwCluster,driver->bFAT32?0x0fffffff:0xffff))
dwCluster=0;
}
}
}
SYS_free(lpszSectors);
return 0;
}
/**static BOOL update_dir_entry(DRIVER_INFO*driver,DWORD dwStart,DWORD dwOffset,BYTE*dir)**********************
功能:
更新目录入口信息
入口:
DRIVER_INFO*driver:逻辑驱动器指针
DWORD dwStart:扇区号
DWORD dwOffset:偏移量
BYTE*dir:32字节的目录入口信息
出口:
调用成功返回1,否则返回0
调用者:
内部任意
备注:
无
**************************************************************************************************************/
static BOOL update_dir_entry(DRIVER_INFO*driver,DWORD dwStart,DWORD dwOffset,BYTE*dir)
{
BYTE*ptr;
DWORD i;
BYTE*lpszSectors;
lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
if(!driver||!dir||!lpszSectors) return 0;
/*读取目录扇区所有内容*/
driver->lpfnRead(dwStart,lpszSectors,driver->dwBytesPerSector,driver->user_data);
/*更新本文件所在的内容*/
ptr=lpszSectors+dwOffset;
for(i=0;i<32;i++) *ptr++=dir[i];
#if (MUST_ERASE_BEFORE_WRITE==1)
driver->lpfnErase(dwStart,driver->dwBytesPerSector,driver->user_data);
#endif
driver->lpfnWrite(dwStart,lpszSectors,driver->dwBytesPerSector,driver->user_data);
SYS_free(lpszSectors);
return 1;
}
/**DWORD get_total_free_clusters(DRIVER_INFO*driver)*********************************
功能:
获取空闲的簇总数
入口:
DRIVER_INFO*driver:驱动器指针
出口:
返回空闲的簇总数
调用者:
内部任意
备注:
无
***********************************************************************************/
static DWORD get_total_free_clusters(DRIVER_INFO*driver)
{
DWORD i,j;
BYTE*ptr;
DWORD dwCluster;
DWORD dwFreeClusters=0;
BYTE* lpszSectors;
DWORD size=driver->dwBytesPerSector>>(driver->bFAT32+1);
lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
if(!lpszSectors) return 0;
for(i=0;i<driver->dwFATsZ;i++)
{
driver->lpfnRead(i+driver->dwFATSectorStart[0],lpszSectors,driver->dwBytesPerSector,driver->user_data);
ptr=lpszSectors;
for(j=0;j<size;j++)
{
if(driver->bFAT32)
{
dwCluster=GETDWORD(ptr);
}
else
{
dwCluster=GETWORD(ptr);
}
if(!dwCluster)
dwFreeClusters++;
}
}
SYS_free(lpszSectors);
return dwFreeClusters;
}
/**static DWORD get_last_cluster_of_file(DRIVER_INFO*driver,DWORD dwFirstCluster,DWORD*dwTotal)*************
功能:
获取文件的最后一个簇号
入口:
DRIVER_INFO*driver:驱动器指针
DWORD dwFirstCluster:文件的首簇
DWORD dwTotal:返回占用簇总数
出口:
调用成功返回最后一个簇号,否则返回0x0000
调用者:
内部任意
备注:
无
**********************************************************************************************/
static DWORD get_last_cluster_of_file(DRIVER_INFO*driver,DWORD dwFirstCluster,DWORD*dwTotal)
{
DWORD dwPrev=dwFirstCluster,dwLast;
DWORD dwEnd;
if(!driver||dwFirstCluster<2) return 0x0000;
dwEnd=driver->bFAT32?0x0fffffff:0xffff;
if(dwTotal) *dwTotal=1;
dwLast=dwPrev;
while(dwLast!=dwEnd)
{
dwLast=get_next_cluster_of_file(driver,dwPrev);
if(dwLast&&dwTotal) (*dwTotal)++;
if(dwLast==dwEnd||dwLast==0x00)
{
return dwPrev;
}
dwPrev=dwLast;
}
return dwPrev;
}
/**static BOOL erase_cluster(DRIVER_INFO*driver,DWORD dwCluster,DWORD dwParent)*****
功能:
对一个簇内所有内容清0
入口:
DRIVER_INFO*driver:驱动器指针
DWORD dwCluster:簇号
DWORD dwParent:0xffffffff,表示不建立".","..",否则是父簇号
出口:
调用成功返回1,否则返回0
调用者:
内部任意
备注:
无
*********************************************************************/
static BOOL erase_cluster(DRIVER_INFO*driver,DWORD dwCluster,DWORD dwParent)
{
DWORD dwStart,dwEnd;
BYTE*lpszSectors;
#if(CREATE_DOT_ENTRY==1)
BYTE*ptr;
BYTE i;
BYTE DOT_NAME[]=". ";
BYTE DOTDOT_NAME[]=".. ";
FAT_TIME ftime;
FAT_DATE fdate;
DWORD dwTime,dwDate;
#endif
lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
if(!lpszSectors) return 0;
SYS_memset(lpszSectors,0,driver->dwBytesPerSector);
#if(CREATE_DOT_ENTRY==1)
if(dwParent!=0xffffffff)
{
ptr=lpszSectors;
ftime=SYS_gettime();
fdate=SYS_getdate();
dwTime=((WORD)ftime.second)|((WORD)ftime.minute<<5)|((WORD)ftime.hour<<11);
dwDate=((WORD)fdate.day)|((WORD)fdate.month<<5)|((WORD)fdate.year<<9);
/*文件名称*/
for(i=0;i<11;i++) *ptr++=DOT_NAME[i];
/*属性*/
*ptr++=ATTR_DIRECTORY|ATTR_ARCHIVE;
/*NTres,如果是0x00表示是有长文件名项或者全部是大写,如果是0x08表示全部小写*/
*ptr++=0x08;
/*CrtTimeTen*/
*ptr++=0x00;
/*CrtTime*/
SETWORD(ptr,dwTime);
/*CrtDate*/
SETWORD(ptr,dwDate);
/*lstAccDate*/
SETWORD(ptr,dwDate);
/*FstClusHi*/
dwStart=(WORD)(dwCluster>>16);
SETWORD(ptr,dwStart);
/*WrtTime*/
SETWORD(ptr,dwTime);
/*WrtDate*/
SETWORD(ptr,dwDate);
/*FstClusLo*/
dwStart=dwCluster&0xffff;
SETWORD(ptr,dwStart);
/*FileSize*/
SETDWORD(ptr,0x0000);
/*文件名称*/
for(i=0;i<11;i++) *ptr++=DOTDOT_NAME[i];
/*属性*/
*ptr++=ATTR_DIRECTORY|ATTR_ARCHIVE;
/*NTres,如果是0x00表示是有长文件名项或者全部是大小,如果是0x08表示全部小写*/
*ptr++=0x08;
/*CrtTimeTen*/
*ptr++=0x00;
/*CrtTime*/
SETWORD(ptr,dwTime);
/*CrtDate*/
SETWORD(ptr,dwDate);
/*lstAccDate*/
SETWORD(ptr,dwDate);
/*FstClusHi*/
dwStart=(WORD)(dwParent>>16);
SETWORD(ptr,dwStart);
/*WrtTime*/
SETWORD(ptr,dwTime);
/*WrtDate*/
SETWORD(ptr,dwDate);
/*FstClusLo*/
dwStart=dwParent&0xffff;
SETWORD(ptr,dwStart);
/*FileSize*/
SETDWORD(ptr,0x0000);
}
#endif
dwStart=get_first_sector_of_cluster(driver,dwCluster);
dwEnd=dwStart+driver->dwSectorsPerCluster;
for(;dwStart<dwEnd;dwStart++)
{
#if(MUST_ERASE_BEFORE_WRITE==1)
if(!driver->lpfnErase(dwStart,driver->dwBytesPerSector,driver->user_data))
{
SYS_free(lpszSectors);
return 0;
}
#endif
if(!driver->lpfnWrite(dwStart,lpszSectors,driver->dwBytesPerSector,driver->user_data))
{
SYS_free(lpszSectors);
return 0;
}
}
SYS_free(lpszSectors);
return 1;
}
/**static void erase_all_clusters_of_file(DRIVER_INFO*driver,DWORD dwFirstCluster)*************
功能:
清除文件所有的簇
入口:
DRIVER_INFO*driver:驱动器指针
DWORD dwFirstCluster:文件的首簇
出口:
无
调用者:
内部任意
备注:
无
**********************************************************************************************/
static void erase_all_clusters_of_file(DRIVER_INFO*driver,DWORD dwFirstCluster)
{
DWORD dwPrev,dwLast=dwFirstCluster;
DWORD dwEnd;
DRIVER_INFO*temp;
if(!driver||dwFirstCluster<2) return;
temp=get_driver_by_name(driver->DriverName);
dwEnd=driver->bFAT32?0x0fffffff:0xffff;
while(dwLast!=dwEnd)
{
dwPrev=dwLast;
dwLast=get_next_cluster_of_file(driver,dwPrev);
update_fat_entry(driver,dwPrev,0x0000);
temp->dwFreeClusters++;
if(!dwLast) break;
}
}
/**static BOOL _mkdir_(DRIVER_INFO*driver,char*path)***************
功能:
在当前目录建立子文件夹
入口:
DRIVER_INFO*driver:驱动器指针
char*path:子目录名
出口:
调用成功返回1,否则返回0
调用者:
内部任意
备注:
无
*******************************************************************/
static BOOL _mkdir_(DRIVER_INFO*driver,char*path)
{
BYTE dir[32];
BYTE i;
BYTE*ptr;
DWORD dwTime,dwDate;
FAT_DATE fdate;
FAT_TIME ftime;
BYTE NTres;
DWORD dwStart,dwOffset;
DWORD dwCluster,dwFreeCluster;
if(!(NTres=DOS2FAT(path))) return 0;
if(get_dir_entry(driver,path,&dwStart,&dwOffset,(BYTE*)0)) return 0;/*已经有了此入口*/
if(!get_free_dir_entry(driver,&dwStart,&dwOffset,&dwFreeCluster)) return 0;
ptr=dir;
ftime=SYS_gettime();
fdate=SYS_getdate();
dwTime=((WORD)ftime.second)|((WORD)ftime.minute<<5)|((WORD)ftime.hour<<11);
dwDate=((WORD)fdate.day)|((WORD)fdate.month<<5)|((WORD)fdate.year<<9);
/*文件名称*/
for(i=0;i<11;i++) *ptr++=path[i];
/*属性*/
*ptr++=ATTR_DIRECTORY|ATTR_ARCHIVE;
/*NTres,如果是0x00表示是有长文件名项或者全部是大小,如果是0x08表示全部小写*/
*ptr++=NTres==0x08?0x08:0x00;
/*CrtTimeTen*/
*ptr++=0x00;
/*CrtTime*/
SETWORD(ptr,dwTime);
/*CrtDate*/
SETWORD(ptr,dwDate);
/*lstAccDate*/
SETWORD(ptr,dwDate);
/*FstClusHi*/
dwCluster=(WORD)(dwFreeCluster>>16);
SETWORD(ptr,dwCluster);
/*WrtTime*/
SETWORD(ptr,dwTime);
/*WrtDate*/
SETWORD(ptr,dwDate);
/*FstClusLo*/
dwCluster=(WORD)(dwFreeCluster&0xffff);
SETWORD(ptr,dwCluster);
/*FileSize*/
SETDWORD(ptr,0x0000);
dwCluster=get_cluster_of_first_sector(driver,driver->lpCurrentDir->dwSectors);
if(dwCluster==0x01) dwCluster=0x0000;
if(!update_dir_entry(driver,dwStart,dwOffset,dir)||!erase_cluster(driver,dwFreeCluster,dwCluster)) return 0;
return 1;
}
/**static BOOL _chdir_(DRIVER_INFO*driver,char*path)******
功能:
进入当前目录的子目录
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -