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

📄 filedisplay.c

📁 FAT12 文件系统,囊括了文件系统的各个函数,另外还包括了地址映射,适合读写NAND_FLASH
💻 C
字号:
#include <string.h>
#include "fat12.h"
#include "filedisplay.h"

extern BYTE* ReadLgSector(DWORD StartLgSector,BYTE* buffer);
extern WORD  SectorNumToClusterNum(DWORD SectorNum);
extern DWORD ClusterNumToSectorNum(WORD ClusterNum);
extern WORD  GetNextLgClusterNum(WORD LgClusterNum);
extern WORD  SectorsPerCluster; 
extern WORD  BytesPerSector;
extern DWORD RootDirSectors;							
extern WORD  FirstDirSector;
extern const char VolLab[12];	

extern _FILE files[16];


DWORD 	CurrentDirSector; 			// = FirstDirSector;(系统初始化值)
BYTE	CurrentDirSectorIndex = 0; 	//(系统初始化值)




/*************** 函数 BYTE File_Displist(DIRENTRY* DirBuffer, signed char DirLength) ****************/
/* 功能:	从全局变量CurrentDirSector和CurrentDirSectorIndex给出的目录项扇区号内的位置开始寻找有效	*/
/*			目录项,寻找的目录项个数由DirLength确定,将找到的目录项信息存放到DirBuffer中,返回实际找*/
/*			到的目录项个数																			*/
/* 入口参数:DIRENTRY* DirBuffer----目录项缓冲区														*/
/*			signed char DirLength-----要找的目录项个数,正值表示正向搜索,负值表示逆向搜索			*/
/* 出口参数:实际找到的目录项个数																	*/
/* 说明:	第一次调用该函数前,应首先在系统初始化时将两个全局变量CurrentDirSector和				*/
/*			CurrentDirSectorIndex赋头文件中的值,之后不用再赋值,但在返回上一级目录或进入子目录时应	*/
/*			将CurrentDirSector重新赋新进入目录的起始扇区号,CurrentDirSectorIndex赋0,然后再调用此	*/
/*			函数再次搜索新目录下文件和目录,并且新的搜索应该首先是正向搜索,之后可以是逆向搜索。	*/
/* 注意:	逆向搜索时搜索到的文件从DirBuffer的尾部开始存放,文件个数放在函数返回值中,并且搜索到目录*/
/*			簇的头部时结束。																		*/
/****************************************************************************************************/
BYTE File_Displist(DIRENTRY* DirBuffer, signed char DirLength)
{
	DIRENTRY *dir;
	BYTE tempbuffer[512];
	BYTE* Cache;
	DWORD sectornumber;
	DWORD LgCluster;
	BYTE effectivedirnum = 0;
	const char dot[11]    = {'.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
	const char dotdot[11] = {'.', '.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};

	if(DirLength >= 0)//正向搜寻
	{
		if((CurrentDirSector >= FirstDirSector) && (CurrentDirSector < (FirstDirSector + RootDirSectors)))	//在根目录区
		{
			for(sectornumber = CurrentDirSector; sectornumber < (FirstDirSector + RootDirSectors); sectornumber++)
			{
				Cache = ReadLgSector(sectornumber,tempbuffer);			//读取该扇区的512个字节数据到tempbuffer中
				
				//在一个扇区内循环寻找有效目录项
				for(dir = ((DIRENTRY *)Cache + CurrentDirSectorIndex); ((BYTE*)dir < (Cache + BytesPerSector))&&(effectivedirnum < DirLength); dir++)
				{
					if((dir->deName[0] != 0) && (dir->deName[0] != 0xe5))//本项使用或文件未被删除,也就是该目录项有效
					{
						if(memcmp((const char*)dir->deName, VolLab, 11) != 0)
						{
							memcpy((BYTE *)DirBuffer, (BYTE *)dir, sizeof(DIRENTRY));//将有效目录信息写入DirBuffer中				
							DirBuffer++;
							effectivedirnum++;
						}
					}
					else if(dir->deName[0] == 0)
					{
					 return effectivedirnum;	
					}	
				
					if(effectivedirnum == DirLength)						//有效目录项个数已够,返回
				   {	return effectivedirnum;	
				   }
				  	
				  CurrentDirSectorIndex++;
								  	
				}	
					
				CurrentDirSector++;										//有效目录项个数未够,继续寻找
				CurrentDirSectorIndex = 0;	
				
			
			}
			return effectivedirnum;										//搜索完整个根目录区,未找够,返回实际找到的目录项个数
		}
		else															//不在根目录区,此时CurrentDirSector应该大于等于64,进入数据区
		{
			LgCluster = SectorNumToClusterNum(CurrentDirSector);		//计算CurrentDirSector所在逻辑镞号
			
			while(LgCluster != 0x0fff)									//在整个簇链中搜索有效目录项
			{
				for(sectornumber = CurrentDirSector; sectornumber < (ClusterNumToSectorNum(LgCluster)+SectorsPerCluster); sectornumber++)
				{
					Cache = ReadLgSector(sectornumber,tempbuffer);		//读取该扇区的512个字节数据到tempbuffer中
					
					//在一个扇区内循环寻找有效目录项
					for(dir = ((DIRENTRY *)Cache + CurrentDirSectorIndex); ((BYTE*)dir < (Cache + BytesPerSector))&&(effectivedirnum < DirLength); dir++)
					{
						if((dir->deName[0] != 0) && (dir->deName[0] != 0xe5))//本项使用或文件未被删除,也就是该目录项有效
						{
							if( (memcmp((const char*)dir->deName, dot, 11) != 0)&&(memcmp((const char*)dir->deName, dotdot, 11) != 0) )
							{
								memcpy((BYTE *)DirBuffer, (BYTE *)dir, sizeof(DIRENTRY));//将有效目录信息写入DirBuffer中				
								DirBuffer++;
								effectivedirnum++;
							}
						}
						else if(dir->deName[0] == 0)
					  {
					   return effectivedirnum;	
					  }	
					  if(effectivedirnum == DirLength)						//有效目录项个数已够,返回
				     {	return effectivedirnum;	
				  	 }
				  	 
						CurrentDirSectorIndex++;					
					 
					}
					CurrentDirSector++;										//有效目录项个数未够,继续寻找
				  CurrentDirSectorIndex = 0;	
					
				}
				
				LgCluster = GetNextLgClusterNum(LgCluster);				//还未找够数目,从FAT表中找出下一簇
				CurrentDirSector = ClusterNumToSectorNum(LgCluster);
				CurrentDirSectorIndex = 0;
			}
			
			return effectivedirnum;										//在整个簇链搜索完,未找够,返回实际找到的目录项个数
		}
	}
	else//逆向搜寻
	{
		DirLength = 0 - DirLength;
		DirBuffer = DirBuffer + DirLength -1;
		
		if((CurrentDirSector >= FirstDirSector) && (CurrentDirSector < (FirstDirSector + RootDirSectors)))	//在根目录区
		{
			for(sectornumber = CurrentDirSector; sectornumber >= FirstDirSector; sectornumber--)
			{
				Cache = ReadLgSector(sectornumber,tempbuffer);			//读取该扇区的512个字节数据到tempbuffer中
				
				//在一个扇区内循环寻找有效目录项
				for(dir = ((DIRENTRY *)Cache + CurrentDirSectorIndex); ((BYTE*)dir >= Cache)&&(effectivedirnum < DirLength); dir--)
				{
					if((dir->deName[0] != 0) && (dir->deName[0] != 0xe5))//本项使用或文件未被删除,也就是该目录项有效
					{
						if(memcmp((const char*)dir->deName, VolLab, 11) != 0)
						{
							memcpy((BYTE *)DirBuffer, (BYTE *)dir, sizeof(DIRENTRY));//将有效目录信息写入DirBuffer中				
							DirBuffer--;
							effectivedirnum++;
						}
						else											//搜索到根目录区的头部,返回
						{	return effectivedirnum;	}
					}
					else if(dir->deName[0] == 0)
					{
					 return effectivedirnum;	
					}	
				 
				 	if(effectivedirnum == DirLength)						//有效目录项个数已够,返回
				   {	return effectivedirnum;	
				   }
				  CurrentDirSectorIndex--; 
				
				}
				CurrentDirSector--;										//有效目录项个数未够,继续寻找
				CurrentDirSectorIndex = 15;
			
				
				
			}
			return effectivedirnum;										//搜索完整个根目录区,未找够,返回实际找到的目录项个数
		}
		else															//不在根目录区,此时CurrentDirSector应该大于等于64,进入数据区
		{
			LgCluster = SectorNumToClusterNum(CurrentDirSector);		//计算CurrentDirSector所在逻辑镞号
			
			//在一个簇中搜索有效目录项
			for(sectornumber = CurrentDirSector; sectornumber >= ClusterNumToSectorNum(LgCluster); sectornumber--)
			{
				Cache = ReadLgSector(sectornumber,tempbuffer);			//读取该扇区的512个字节数据到tempbuffer中
				
				//在一个扇区内循环寻找有效目录项
				for(dir =((DIRENTRY *)Cache + CurrentDirSectorIndex); ((BYTE*)dir >= Cache)&&(effectivedirnum < DirLength); dir--)
				{
					if((dir->deName[0] != 0) && (dir->deName[0] != 0xe5))//本项使用或文件未被删除,也就是该目录项有效
					{
						if( (memcmp((const char*)dir->deName, dot, 11) != 0)&&(memcmp((const char*)dir->deName, dotdot, 11) != 0) )
						{
							memcpy((BYTE *)DirBuffer, (BYTE *)dir, sizeof(DIRENTRY));//将有效目录信息写入DirBuffer中				
							DirBuffer--;
							effectivedirnum++;
						}
						else											//搜索到子目录区的头部,返回
						{	return effectivedirnum;	}
					}
					else if(dir->deName[0] == 0)
					{
					 return effectivedirnum;	
					}								
					
				 	if(effectivedirnum == DirLength)						//有效目录项个数已够,返回
				   {	return effectivedirnum;	
				   }
				  CurrentDirSectorIndex--; 
				}
			  CurrentDirSector--;										//有效目录项个数未够,继续寻找
				CurrentDirSectorIndex = 15;		
			
			}
				
			return effectivedirnum;										//在一个簇中搜索完,未找够,返回实际找到的目录项个数
		}
	}
}
		
		
/************* 测试程序 **************/
/*void MyDisplist_test(void)
{
	DIRENTRY Buffer1[8],Buffer2[8];	
	int file_num1,file_num2;
	unsigned char effectivedirlength;
	signed char dirlength = 8;
	
	
	file_num1 = file_open("\\SEG");
	CurrentDirSector = files[file_num1].StartSectorNum;
	CurrentDirSectorIndex = 0;
	do
	{
	memset((BYTE *)Buffer1, 0 , sizeof(Buffer1));
	effectivedirlength = File_Displist(Buffer1, dirlength);
  }while(effectivedirlength==dirlength);
	file_close(file_num1);
	
	file_num2 = file_open("\\SEG\\200608");
	CurrentDirSector = files[file_num2].StartSectorNum;
	CurrentDirSectorIndex = 0;
	do
	{
	memset((BYTE *)Buffer2, 0 , sizeof(Buffer2));
	effectivedirlength = File_Displist(Buffer2, dirlength);
  }while(effectivedirlength==dirlength);
	file_close(file_num2);
	
}*/			
		




⌨️ 快捷键说明

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