⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 针对以arm处理器为核心的嵌入式平台的fat文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
入口:
	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 + -