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

📄 fat.c

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