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

📄 fat.c

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