📄 fat.c
字号:
入口:
DRIVER_INFO*driver:驱动器指针
char*path:路径名
出口:
调用成功返回1,否则返回0
调用者:
内部任意
备注:
无
*********************************************************/
static BOOL _chdir_(DRIVER_INFO*driver,char*path)
{
DWORD dwCluster;
LINK*next,*prev;
BYTE i;
BYTE dir[32];
if(path[0]=='\\')
{
prev=driver->lpCurrentDir->prev;/*指向当前目录的上层目录*/
next=driver->lpCurrentDir;
while(prev)
{
SYS_free(next);
next=prev;
prev=prev->prev;
}
driver->lpCurrentDir=driver->lpLinks;
driver->lpLinks->next=(LINK*)0;
return 1;
}
else if(path[0]=='.'&&path[1]=='.')
{
prev=driver->lpCurrentDir->prev;
if(!prev) return 0;
prev->next=(void*)0;
SYS_free(driver->lpCurrentDir);
driver->lpCurrentDir=prev;
return 1;
}
else if(path[0]=='.'&&path[1]==0)
{
return 1;
}
if(!DOS2FAT(path)) return 0;
if(!get_dir_entry(driver,path,(DWORD*)0,(DWORD*)0,dir)) return 0;
if((DIR_ATTR(dir)&ATTR_DIRECTORY)!=ATTR_DIRECTORY) return 0;
dwCluster=DIR_FIRSTCLUSTER(dir);
dwCluster=get_first_sector_of_cluster(driver,dwCluster);
if(!dwCluster) return 0;
next=(LINK*)SYS_malloc(sizeof(LINK));
if(!next) return 0;
next->prev=driver->lpCurrentDir;
next->next=(void*)0;
next->dwSectors=dwCluster;
for(i=0;i<11;i++) next->name[i]=path[i];
next->name[11]=0;
driver->lpCurrentDir->next=next;
driver->lpCurrentDir=next;
return 1;
}
/**static BOOL _rmdir_(DRIVER_INFO*driver,char*path)**********************
功能:
在当前目录删除子目录
入口:
DRIVER_INFO*driver:驱动器指针
char*path:子目录名
出口:
调用成功返回1,否则返回0
调用者:
内部任意
备注:
无
************************************************************************/
static BOOL _rmdir_(DRIVER_INFO*driver,char*path)
{
DWORD dwStart,dwOffset,dwCluster;
DWORD i,dwSize;
BYTE dir[32];
BYTE*lpszSectors;
BYTE*ptr;
DRIVER_INFO*temp;
/*文件名是否有效*/
if(!DOS2FAT(path)) return 0;
/*要删除,必须目录表中有该项*/
if(!get_dir_entry(driver,path,&dwStart,&dwOffset,dir)) return 0;
/*不能是只读属性*/
if(dir[11]&ATTR_READONLY) return 0;
/*内存不足*/
if(!(lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector)))
return 0;
/*以下代码检测该文件夹内是否有任何的子文件夹和文件,如果有,则不能删除,返回0*/
dwCluster=DIR_FIRSTCLUSTER(dir);
dwSize=driver->dwBytesPerSector>>5;
dwStart=get_first_sector_of_cluster(driver,dwCluster);
dwOffset=dwStart+driver->dwSectorsPerCluster;
for(;dwStart<dwOffset;dwStart++)
{
if(!driver->lpfnRead(dwStart,lpszSectors,driver->dwBytesPerSector,driver->user_data))
{
SYS_free(lpszSectors);
return 0;
}
ptr=lpszSectors;
for(i=0;i<dwSize;i++)
{
if(ptr[0]=='.'||ptr[0]==0||ptr[0]==0x05||ptr[0]==0xe5) ;
else if(!ptr[26]&&!ptr[27]&&ptr[11]==ATTR_LONG_NAME) ;
else
{
SYS_free(lpszSectors);
return 0;
}
ptr+=32;
}
}
temp=get_driver_by_name(driver->DriverName);
/*重新获取一次目录信息*/
get_dir_entry(driver,path,&dwStart,&dwOffset,dir);
/*标注为删除*/
dir[0]=0xe5;
/*更新FAT和目录项*/
if(!update_dir_entry(driver,dwStart,dwOffset,dir)||!update_fat_entry(driver,dwCluster,0x0000))
{
SYS_free(lpszSectors);
return 0;
}
temp->dwFreeClusters++;
SYS_free(lpszSectors);
return 1;
}
/**static void destroy_driver_links(DRIVER_INFO*dst)*********************************
功能:
删除驱动器路径指针
入口:
DRIVER_INFO*dst:目标指针
出口:
无
调用者:
内部任意
备注:
无
******************************************************************************/
static void destroy_driver_links(DRIVER_INFO*driver)
{
LINK *curr,*prev;
if(!driver) return;
curr=driver->lpCurrentDir;
if(curr)/*确保driver->lpLinks被初始化过*/
{
prev=curr->prev;
SYS_free(curr);
while(prev)
{
curr=prev->prev;
SYS_free(prev);
prev=curr;
}
}
}
/**static BOOL copy_driver_info(DRIVER_INFO*dst,DRIVER_INFO*src)**************
功能:
DRIVER_INFO*指针拷贝
入口:
DRIVER_INFO*dst:目标指针
DRIVER_INFO*src:源指针
出口:
调用成功返回1,否则返回0
调用者:
内部任意
备注:
无
******************************************************************************/
static BOOL copy_driver_info(DRIVER_INFO*dst,DRIVER_INFO*src)
{
LINK*next,*src_link,*dst_link;
BYTE i;
if(!dst||!src) return 0;
if(dst->lpLinks!=dst->lpCurrentDir)/*不在根目录*/
{
_chdir_(dst,"\\");
}
dst->lpLinks=(LINK*)SYS_malloc(sizeof(LINK));
if(!dst->lpLinks) return 0;
SYS_memset(dst->lpLinks,0,sizeof(LINK));
dst->lpCurrentDir=dst->lpLinks;
dst->lpLinks->prev=(void*)0;
dst->lpLinks->next=(void*)0;
dst->lpLinks->dwSectors=src->lpLinks->dwSectors;
for(i=0;i<12;i++) dst->lpLinks->name[i]=src->lpLinks->name[i];
/*开始复制目录列表*/
dst_link=dst->lpLinks;
src_link=src->lpLinks->next;
while(src_link)
{
next=(LINK*)SYS_malloc(sizeof(LINK));
if(!next) return 0;
next->prev=dst_link;
next->next=(void*)0;
next->dwSectors=src_link->dwSectors;
for(i=0;i<12;i++) next->name[i]=src_link->name[i];
dst_link->next=next;
if(src->lpCurrentDir==src_link)
{
dst->lpCurrentDir=next;
}
dst_link=dst_link->next;
src_link=src_link->next;
}
/*复制其他信息*/
dst->bFAT32=src->bFAT32;
dst->DriverName=src->DriverName;
dst->dwBytesPerSector=src->dwBytesPerSector;
dst->dwDataSectorStart=src->dwDataSectorStart;
dst->dwFATSectorStart[0]=src->dwFATSectorStart[0];
dst->dwFATSectorStart[1]=src->dwFATSectorStart[1];
dst->dwFATsZ=src->dwFATsZ;
dst->dwFreeClusters=src->dwFreeClusters;
dst->dwHideSectorStart=src->dwHideSectorStart;
dst->dwNumFATs=src->dwNumFATs;
dst->dwReservedSectorStart=src->dwReservedSectorStart;
dst->dwRootSectorStart=src->dwRootSectorStart;
dst->dwSectorsPerCluster=src->dwSectorsPerCluster;
dst->dwTotalClusters=src->dwTotalClusters;
dst->dwVOLID=src->dwVOLID;
dst->lpfnErase=src->lpfnErase;
dst->lpfnRead=src->lpfnRead;
dst->lpfnWrite=src->lpfnWrite;
dst->user_data=src->user_data;
return 1;
}
/**static int extract_path_name(BYTE*src,BYTE*dst)*****************************
功能:
从一个字串中检测出第一个路径名
入口:
BYTE*src:字串指针
BYTE*dst:保存路径的指针
出口:
如果调用成功返回头部去除的字节数,否则返回0
调用者:
parse_path_information()
备注:
字串结束返回的是0xff
*****************************************************************************/
static int extract_path_name(BYTE*src,BYTE*dst)
{
int i=0;
while(1)
{
switch(*src)
{
case 0x00:
*dst=0;
if(i)
return 0xff;
return 0x00;
case ':':
*dst++=':';
*dst=0;
if(*(src+1))
return i+1;
return 0xff;
case '\\':
if(i)
{
*dst=0;
}
else
{
*dst++='\\';
*dst++=0;
}
if(*(src+1))
return i+1;
return 0xff;
}
*dst++=*src++;
i++;
}
return 0;
}
/**static DRIVER_INFO*parse_path_information(BYTE*path,int opt)****************
功能:
分析文件名中的路径信息
入口:
BYTE*path:文件名称
int opt:调用函数类型
出口:
成功则返回文件所在的驱动器结构指针的拷贝,否则返回NULL
调用者:
内部任意
备注:
可以有下列几种形式的文件名称:
1."C:demo.txt"
2."C:\\demo.txt"
3."C:\\list\\demo\\demo.txt"
4."\demo.txt"
5."demo.txt"
*********************************************************************************/
static DRIVER_INFO* parse_path_information(BYTE*path,int opt)
{
DRIVER_INFO*driver,*temp;
BYTE*path_old=path;
BYTE lpszFirst[256];
BYTE lpszSecond[256];
int i,j;
BOOL root=0;
if(!path||!path[0]||!(driver=(DRIVER_INFO*)SYS_malloc(sizeof(DRIVER_INFO))))
return (DRIVER_INFO*)0;
SYS_memset(driver,0,sizeof(DRIVER_INFO));
/*先检测最前部有没有盘符*/
i=extract_path_name(path,lpszFirst);
if(!i) return (DRIVER_INFO*)0;
if(lpszFirst[1]==':')/*有盘符则获取该盘符*/
{
temp=get_driver_by_name(lpszFirst[0]);
if(!temp)
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
if(opt==PARSE_CHDIR)/*如果是chdir,则不需要建立driver的拷贝,直接使用原来的指针*/
{
destroy_driver_links(driver);
SYS_free(driver);
driver=temp;
}
else
{
if(!copy_driver_info(driver,temp))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
path+=i;
}
else/*无盘符,则拷贝thisDriver到driver中*/
{
if(opt==PARSE_CHDIR)/*如果是chdir,则不需要建立driver的拷贝,直接使用原来的指针*/
{
destroy_driver_links(driver);
SYS_free(driver);
driver=thisDriver;
}
else
{
if(!copy_driver_info(driver,thisDriver))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
}
while(1)
{
i=j=0x00;
lpszFirst[0]=0;
lpszSecond[0]=0;
i=extract_path_name(path,lpszFirst);
if(!i)
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
if(i!=0xff)
{
path+=i;
j=extract_path_name(path,lpszSecond);
if(!j)
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
if(j!=0xff) path+=j;
}
if(root==1&&(lpszFirst[0]=='\\'||lpszSecond[0]=='\\'))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
else
root=1;
switch(opt)
{
case PARSE_FOPEN:/*fopen()调用*/
if(i==0xff)
{
SYS_strcpy(path_old,lpszFirst);
return driver;
}
else
{
if(!_chdir_(driver,lpszFirst))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
if(!j) break;
if(j==0xff)
{
SYS_strcpy(path_old,lpszSecond);
return driver;
}
else if(j)
{
if(!_chdir_(driver,lpszSecond))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
break;
case PARSE_MKDIR:
if(i==0xff)
{
if(!_mkdir_(driver,lpszFirst))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
else
{
if(!_chdir_(driver,lpszFirst))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
if(j==0xff)
{
if(!_mkdir_(driver,lpszSecond))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
else if(j)
{
if(!_chdir_(driver,lpszSecond))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
break;
case PARSE_CHDIR:
if(!_chdir_(driver,lpszFirst))
{
return (DRIVER_INFO*)0;
}
if(i!=0xff)
{
if(!_chdir_(driver,lpszSecond))
{
return (DRIVER_INFO*)0;
}
}
break;
case PARSE_RMDIR:
if(i==0xff)
{
if(!_rmdir_(driver,lpszFirst))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
}
else
{
if(!_chdir_(driver,lpszFirst))
{
destroy_driver_links(driver);
SYS_free(driver);
return (DRIVER_INFO*)0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -