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

📄 fat.c

📁 针对以arm处理器为核心的嵌入式平台的fat文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
			}
			if(j==0xff)
			{
				if(!_rmdir_(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;
		}
		if(i==0xff||j==0xff) break;
	}
	return (DRIVER_INFO*)driver;
}

/**static BOOL read_one_cluster(INFO*driver,FILE*p,DWORD dwClusters)**********
功能:
	读取一个簇到文件缓冲区中
入口:
	DRIVER_INFO*driver:驱动器结构指针
	FILE*p:文件指针
	DWORD dwClusters:文件的簇号
出口:
调用者:
	内部任意
备注:
	dwCluster按照Microsoft的PDF,必须保证dwCluster>=2
******************************************************************************************/
static BOOL read_one_cluster(DRIVER_INFO* driver,FILE*p,DWORD dwClusters)
{
	BYTE*ptr;
	DWORD dwStart;
	DWORD dwEnd;
	if(!driver||dwClusters<2) return 0;
	dwStart=get_first_sector_of_cluster(driver,dwClusters);
	dwEnd=dwStart+driver->dwSectorsPerCluster;
	ptr=p->lpszBuffers;
	for(;dwStart<dwEnd;dwStart++)
	{
		if(!driver->lpfnRead(dwStart,ptr,driver->dwBytesPerSector,driver->user_data))
			return 0;
		ptr+=driver->dwBytesPerSector;
	}
	return 1;
}

/**static BOOL write_one_cluster(DRIVER_INFO*driver,FILE*p,DWORD dwClusters)**********
功能:
	把文件缓冲区内容写到一个簇中
入口:
	DRIVER_INFO*driver:逻辑驱动器结构指针
	FILE*p:文件指针
	DWORD dwClusters:文件的簇号
出口:
调用者:
	内部任意
备注:
	dwCluster按照Microsoft的PDF,必须保证dwCluster>=2
******************************************************************************************/
static BOOL write_one_cluster(DRIVER_INFO* driver,FILE*p,DWORD dwClusters)
{
	BYTE*ptr;
	DWORD dwStart;
	DWORD dwEnd;
	if(!driver||dwClusters<2) return 0;
	dwStart=get_first_sector_of_cluster(driver,dwClusters);
	dwEnd=dwStart+driver->dwSectorsPerCluster;
	ptr=p->lpszBuffers;
	for(;dwStart<dwEnd;dwStart++)
	{
#if(MUST_ERASE_BEFORE_WRITE==1)
		if(!driver->lpfnErase(dwStart,driver->dwBytesPerSector,driver->user_data))
			return 0;
#endif
		if(!driver->lpfnWrite(dwStart,ptr,driver->dwBytesPerSector,driver->user_data))
			return 0;
		ptr+=driver->dwBytesPerSector;
	}
	return 1;
}

/**static DRIVER_INFO*get_free_driver()*******************************************
功能:
	获取空闲的驱动器指针
入口:
出口:
	调用成功返回有效的驱动器指针,否则返回NULL
调用者:
	任意
备注:
********************************************************************************/
static DRIVER_INFO*get_free_driver()
{
	DWORD i;
	for(i=0;i<MAX_DRIVERS_NUMBER;i++)
	{
		if(drivers[i]) continue;
		drivers[i]=(DRIVER_INFO*)SYS_malloc(sizeof(DRIVER_INFO));
		if(!drivers[i]) break;
		SYS_memset(drivers[i],0,sizeof(DRIVER_INFO));
		drivers[i]->lpLinks=(LINK*)SYS_malloc(sizeof(LINK));
		if(!drivers[i]->lpLinks)
		{
			SYS_free(drivers[i]);
			drivers[i]=(DRIVER_INFO*)0;
			return (DRIVER_INFO*)0;
		}
		drivers[i]->lpLinks->prev=(void*)0;
		drivers[i]->lpLinks->next=(void*)0;
		drivers[i]->lpLinks->name[0]=START_DRIVER_LABLE+i;
		drivers[i]->lpLinks->name[1]=':';
		drivers[i]->lpLinks->name[2]=0;
		drivers[i]->lpCurrentDir=drivers[i]->lpLinks;
		drivers[i]->DriverName=START_DRIVER_LABLE+i;
		return (DRIVER_INFO*)drivers[i];
	}
	return (DRIVER_INFO*)0;
}

/**static BOOL parse_master_patrition(DWORD dwStart,DWORD dwOffset,DRIVER_INFO*driver)****************************************************************
功能:
	主分区参数读取和计算
入口:
	DWORD dwStart:本分区开始扇区(相对于0扇区)
	DWORD dwOffset:本分区开始计算的扇区数(相对于0扇区或者ext分区0扇区)
	DRIVER_INFO*driver:驱动器结构指针
出口:
	成功返回1,否则返回0
调用者:
	FAT_install()
备注:
************************************************************************************************************************************/
static BOOL parse_master_partition(DWORD dwStart,DWORD dwOffset,DRIVER_INFO*driver)
{
	BYTE*lpszSectors;
	BYTE*info;
	BYTE i,bClear;
	BYTE NONAME[]="NO NAME    "; 
	WORD BPB_BytsPerSec=0,BPB_RsveSecCnt=0,BPB_RootEntCnt=0,BPB_TotSec16=0,BPB_FATSz16=0,BPB_SecPerTrk=0;
	WORD BPB_NumHeads=0;
	DWORD BPB_HiddSec=0,BPB_TotSec32=0,BPB_FATSz32=0;
	DWORD dwRootClus=0;
	BYTE BPB_SecPerClus=0,BPB_NumFATs=0,BPB_Media=0;
	
	if(!driver) return 0;
	lpszSectors=(BYTE*)SYS_malloc(driver->dwBytesPerSector);
	if(!lpszSectors) return 0;
	if(!driver->lpfnRead(dwStart,lpszSectors,driver->dwBytesPerSector,driver->user_data)) return 0;
	info=lpszSectors;
	info+=11;
	BPB_BytsPerSec=GETWORD(info);
	BPB_SecPerClus=*info++;
	BPB_RsveSecCnt=GETWORD(info);
	BPB_NumFATs=*info++;
	BPB_RootEntCnt=GETWORD(info);
	BPB_TotSec16=GETWORD(info);
	BPB_Media=*info++;
	BPB_FATSz16=GETWORD(info);
	BPB_SecPerTrk=GETWORD(info);
	BPB_NumHeads=GETWORD(info);
	BPB_HiddSec=GETDWORD(info);
	BPB_TotSec32=GETDWORD(info);
	driver->dwNumFATs=BPB_NumFATs;
	driver->bFAT32=BPB_FATSz16==0;
	if(driver->bFAT32)/*如果是FAT32文件系统*/
	{
		BPB_FATSz32=GETDWORD(info);
		info+=4;
		dwRootClus=GETDWORD(info);/*根目录开始簇号,一般是2,但不一定是2*/
		info+=19;
		driver->dwVOLID=GETDWORD(info);
		bClear=1;
		for(i=0;i<11;i++)
		{
			driver->VolLable[i]=*info++;
			if(driver->VolLable[i]!=NONAME[i]) bClear=0;
		}
		if(bClear) i=0;
		driver->VolLable[i]=0;
		FAT2DOS(driver->VolLable,0);
		driver->dwFATsZ=BPB_FATSz32;
	}
	else
	{
		info+=3;
		driver->dwVOLID=GETDWORD(info);
		bClear=1;
		for(i=0;i<11;i++)
		{
			driver->VolLable[i]=*info++;
			if(driver->VolLable[i]!=NONAME[i]) bClear=0;
		}
		if(bClear) i=0;
		driver->VolLable[i]=0;
		FAT2DOS(driver->VolLable,0);
		driver->dwFATsZ=BPB_FATSz16;
	}
	driver->dwBytesPerSector=BPB_BytsPerSec;
	driver->dwSectorsPerCluster=BPB_SecPerClus;
	/*开始计算参数*/
	driver->dwHideSectorStart=dwOffset;

	driver->dwReservedSectorStart=dwStart;
	dwStart+=BPB_RsveSecCnt;
	for(i=0;i<BPB_NumFATs&&i<2;i++)
	{
		driver->dwFATSectorStart[i]=dwStart;
		if(driver->bFAT32)
			dwStart+=BPB_FATSz32;
		else
			dwStart+=BPB_FATSz16;
	}
	if(!driver->bFAT32)
		driver->dwRootSectorStart=dwStart;
	dwStart+=((BPB_RootEntCnt<<5)+(BPB_BytsPerSec-1))/BPB_BytsPerSec;
	driver->dwDataSectorStart=dwStart;
	if(driver->bFAT32)
		driver->dwRootSectorStart=get_first_sector_of_cluster(driver,dwRootClus);
	driver->lpCurrentDir->dwSectors=driver->dwRootSectorStart;
	driver->dwTotalClusters=((BPB_FATSz32?BPB_FATSz32:BPB_FATSz16)*driver->dwBytesPerSector)/(driver->bFAT32?4:2);
	driver->dwFreeClusters=get_total_free_clusters(driver);
	if(!thisDriver) thisDriver=driver;
	return 1;
}


#if(SUPPORT_EXT_PARTITION==1)
static BYTE parse_ext_partition(DWORD dwStart/*MBR开始扇区*/,DWORD dwBytesPerSector,SECTOR_ERASE lpfnErase,SECTOR_READ lpfnRead,SECTOR_WRITE lpfnWrite,void*user_data)
{
	BYTE*lpszSectors;
	BYTE*info;
	BYTE i;
	DWORD dwTotalDisk=0;
	DRIVER_INFO*driver;
	lpszSectors=(BYTE*)SYS_malloc(dwBytesPerSector);
	if(!lpszSectors) return 0;
	if(!lpfnRead(dwStart,lpszSectors,dwBytesPerSector,user_data))
		return 0;
	info=&lpszSectors[dwBytesPerSector-2-64];
	for(i=0;i<4;i++)
	{
			info+=4;
			switch(*info)
			{
			case 0x04:
			case 0x06:
			case 0x0b:
			case 0x0c:
			case 0x0e:
				info+=4;
				if(!(driver=get_free_driver()))
				{					
					return dwTotalDisk;
				}
				driver->lpfnErase=lpfnErase;
				driver->lpfnRead=lpfnRead;
				driver->lpfnWrite=lpfnWrite;
				driver->user_data=user_data;
				driver->dwBytesPerSector=dwBytesPerSector;
				driver->dwReservedSectorStart=GETDWORD(info);
				info+=4;
				dwTotalDisk+=parse_master_partition(driver->dwReservedSectorStart,0x0000,driver);
				break;
			case 0x05:
			case 0x0f:
				info+=4;
				dwStart=GETDWORD(info);
				info+=4;
				dwTotalDisk+=parse_ext_partition(dwStart,dwBytesPerSector,lpfnErase,lpfnRead,lpfnWrite,user_data);
				break;
			default:
				info+=12;
			}
		}
	SYS_free(lpszSectors);
	return dwTotalDisk;
}
#endif



/**static DWORD detect_bytes_per_sector(SECTOR_READ lpfnRead,void *user_data)******************************
功能:
	自动检测每扇区字节数
入口:
	SECTOR_READ lpfnRead:扇区读指针
	void*user_data:用户数据指针
出口:
	成功返回每扇区字节数,否则返回0
调用者:
	FAT_install()
备注:
	仅仅支持512,1024和2048 3种类型(实际上一般是512)
******************************************************************************************************/
static DWORD detect_bytes_per_sector(SECTOR_READ lpfnRead,void *user_data)
{
	BYTE*buff;
	buff=(BYTE*)SYS_malloc(2048);
	if(!buff) return 0;
	if(lpfnRead(0x0000,buff,512,user_data))
	{
		if(buff[510]!=0x55||buff[511]!=0xaa)
		{
			if(lpfnRead(0x0000,buff,1024,user_data))
			{
				if(buff[1022]!=0x55||buff[1023]!=0xaa)
				{
					if(lpfnRead(0x0000,buff,2048,user_data))
					{
						if(buff[2046]!=0x55||buff[2047]!=0xaa)
						{
							SYS_free(buff);
							return 0x00;
						}
						SYS_free(buff);
						return 2048;
						
					}
		
				}
				SYS_free(buff);
				return 1024;
		
			}
		}
		SYS_free(buff);
		return 512;		

	}
	
	SYS_free(buff);
	return 0;
}

#if (SUPPORT_FORMAT==1)
typedef struct
{
	DWORD dwDiskSize;
	DWORD SecPerCluster;
}CLUSTER_INFO;
static DRIVER_INFO*calc_driver_info(BOOL bFAT32,DWORD dwStart,DWORD dwDiskSize,SECTOR_ERASE lpfnErase,SECTOR_READ lpfnRead,SECTOR_WRITE lpfnWrite,void*user_data)
{
	BYTE sector_per_cluster=0;
	DWORD i;
	DWORD BPB_Total;
	DWORD FATsZ;
	DWORD dwFreeClusters;
	CLUSTER_INFO FAT16[]=
	{
		{720,1},/*360K以上采用0.5K cluster*/
		{32768,2},/*16M以上采用1K cluster*/
		{262144,4},/*128M以上采用2K Cluster*/
		{524288,8},/*256M以上采用4K cluster*/
		{1048576,16},/*512M以上采用8K cluster*/
		{2097152,32},/*1G以上采用16K cluster*/
		{4194304,64},/*2G以上采用32K cluster*/
		{0xffffffff,0},
	};
	CLUSTER_INFO FAT32[]=
	{
#if 1
		{65536,1},/*32M以下,必须使用FAT16*/
#else
		{524288,1},/*32M-256M,用0.5K cluster*/
#endif
		{16777216,8},/*8G以内,用4K cluster*/
		{33554432,16},/*16G以内,用8K cluster*/
		{67108864,32},/*32G以内,用16K cluster*/
		{0xffffffff,0},
	};
	DRIVER_INFO*driver;
	if(bFAT32)
	{
		if(dwDiskSize<65536) bFAT32=0;
		else
		{
			for(i=0;i<sizeof(FAT32)-1;i++)
			{
				if(dwDiskSize>=FAT32[i].dwDiskSize&&dwDiskSize<FAT32[i+1].dwDiskSize)
				{
					sector_per_cluster=FAT32[i].SecPerCluster;
					break;
				}
			}
		}
	}
	if(!bFAT32)
	{
		if(dwDiskSize<720) return (DRIVER_INFO*)0;
		for(i=0;i<sizeof(FAT16)-1;i++)
		{
			if(dwDiskSize>=FAT16[i].dwDiskSize&&dwDiskSize<FAT16[i+1].dwDiskSize)
			{
				sector_per_cluster=FAT16[i].SecPerCluster;
				break;
			}
		}
	}
	if(sector_per_cluster==0x00) return (DRIVER_INFO*)0;

	BPB_Total=dwDiskSize-DEFAULT_RESERVED_SECTORS-DEFAULT_ROOT_ENTRY*sector_per_cluster;
	BPB_Total=BPB_Total/(DWORD)(((bFAT32?8.0:4.0)/(sector_per_cluster+2)/DEFAULT_BYTES_PER_SECTOR+1));
	dwFreeClusters=BPB_Total/sector_per_cluster;
	FATsZ=((dwFreeClusters+2)*(bFAT32?4:2))/DEFAULT_BYTES_PER_SECTOR;	
	driver=(DRIVER_INFO*)get_free_driver();
	if(driver)
	{
		driver->dwBytesPerSector=DEFAULT_BYTES_PER_SECTOR;
		driver->dwSectorsPerCluster=sector_per_cluster;
		driver->dwReservedSectorStart=dwStart;
		driver->dwFATSectorStart[0]=dwStart+DEFAULT_RESERVED_SECTORS;
		driver->dwFATSectorStart[1]=driver->dwFATSectorStart[0]+FATsZ;
		driver->dwRootSectorStart=driver->dwFATSectorStart[1]+FATsZ;
		if(!bFAT32)
			driver->dwDataSectorStart=driver->dwRootSectorStart+DEFAULT_ROOT_ENTRY*sector_per_cluster;
		else
			driver->dwDataSectorStart=driver->dwRootSectorStart;
		driver->dwFreeClusters=dwFreeClusters;
		driver->dwNumFATs=2;
		driver->user_data=user_data;
		driver->bFAT32=bFAT32;
		driver->dwHideSectorStart=0x00000;
		driver->dwFATsZ=FATsZ;
		driver->dwTotalClusters=BPB_Total/sector_per_cluster;
		driver->lpfnErase=lpfnErase;
		driver->lpfnWrite=lpfnWrite;
		driver->lpfnRead=(SECTOR_READ)lpfnRead;
		driver->VolLable[0]=0;

	}
	return driver;
}

/**BOOL FAT_format(DRIVER_INFO*driver,BOOL bFAT32,DWORD dwStartSector,DWORD dwDiskSize,SECTOR_ERASE lpfnErase,SECTOR_READ lpfnRead,SECTOR_WRITE lpfnWrite,void*user_data)***************************************************************************************
功能:
	格式化一个逻辑驱动器
入口:
	DRIVER_INFO*driver:逻辑驱动器指针
	BOOL bFAT32:是否使用FAT32格式化
	DWORD dwStartSector:开始扇区号
	DWORD dwDiskSize:磁盘大小,单位是sectors
	SECTOR_ERASE lpfnErase:扇区擦除函数
	SECTOR_WRITE lpfnWrite:扇区写函数
	void*user_data:用户数据指针
出口:
	调用成功返回1,否则返回0
调用者:
	任意
备注:
	两种使用方法:
	1.driver!=NULL,则忽略dwStartSector和dwDiskSize,使用driver的内部数据进行格式化(如一个驱动器被正常装载后有有效的数据,就可以用这方法,该方法不会改变任何参数)
	2.driver==NULL,则FAT_format()利用后两个参数dwStartSector,dwDiskSize计算适当的参数(利用默认值)
*****************************************************************************************************************************************************************/
BOOL FAT_format(DRIVER_INFO*that,BOOL bFAT32,DWORD dwStartSector,DWORD dwDiskSize,SECTOR_ERASE lpfnErase,SECTOR_READ lpfnRead,SECTOR_WRITE lpfnWrite,void*user_data)
{
	BYTE i;
	DWORD j;
	FAT_DATE fdate;
	FAT_TIME ftime;
	DWORD dwStart,dwEnd;
	DRIVER_INFO*driver=that;
	BYTE DBR[]=
	{
		0xeb,0x58,0x90,0x4d,0x53,0x44,0x4f,0x53,0x35,0x2e,0x30,0x00,0x02,0x04,0x22,0x00,
		0x02,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x3f,0x00,0xff,0x00,0x00,0x00,0x00,0x00,
		0x00,0xc4,0x07,0x00,0xdf,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
		0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x29,0xed,0x55,0x0b,0xe8,0x4e,0x4f,0x20,0x4e,0x41,0x4d,0x45,0x20,0x20,
		0x20,0x20,0x46,0x41,0x54,0x33,0x32,0x20,0x20,0x20,0x33,0xc9,0x8e,0xd1,0xbc,0xf4,
		0x7b,0x8e,0xc1,0x8e,0xd9,0xbd,0x00,0x7c,0x88,0x4e,0x02,0x8a,0x56,0x40,0xb4,0x08,
		0xcd,0x13,0x73,0x05,0xb9,0xff,0xff,0x8a,0xf1,0x66,0x0f,0xb6,0xc6,0x40,0x66,0x0f,
		0xb6,0xd1,0x80,0xe2,0x3f,0xf7,0xe2,0x86,0xcd,0xc0,0xed,0x06,0x41,0x66,0x0f,0xb7,
		0xc9,0x66,0xf7,0xe1,0x66,0x89,0x46,0xf8,0x83,0x7e,0x16,0x00,0x75,0x38,0x83,0x7e,
		0x2a,0x00,0x77,0x32,0x66,0x8b,0x46,0x1c,0x66,0x83,0xc0,0x0c,0xbb,0x00,0x80,0xb9,
		0x01,0x00,0xe8,0x2b,0x00,0xe9,0x48,0x03,0xa0,0xfa,0x7d,0xb4,0x7d,0x8b,0xf0,0xac,
		0x84,0xc0,0x74,0x17,0x3c,0xff,0x74,0x09,0xb4,0x0e,0xbb,0x07,0x00,0xcd,0x10,0xeb,
		0xee,0xa0,0xfb,0x7d,0xeb,0xe5,0xa0,0xf9,0x7d,0xeb,0xe0,0x98,0xcd,0x16,0xcd,0x19,
		0x66,0x60,0x66,0x3b,0x46,0xf8,0x0f,0x82,0x4a,0x00,0x66,0x6a,0x00,0x66,0x50,0x06,
		0x53,0x66,0x68,0x10,0x00,0x01,0x00,0x80,0x7e,0x02,0x00,0x0f,0x85,0x20,0x00,0xb4,
		0x41,0xbb,0xaa,0x55,0x8a,0x56,0x40,0xcd,0x13,0x0f,0x82,0x1c,0x00,0x81,0xfb,0x55,
		0xaa,0x0f,0x85,0x14,0x00,0xf6,0xc1,0x01,0x0f,0x84,0x0d,0x00,0xfe,0x46,0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -