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

📄 fat16.c

📁 杭州立宇泰ARMsys-P型ARM开发板BIOS代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				ppath++;
				dir_len_count =0;
				continue;
			}
			break;

		case '.':
			{
				if(dir_len_count > 8 || dir_len_count ==0) // '\\.' check
					return NULL;

				if(ppath[1] == '.' || ppath[1] == '\\') // more than one '.' or '.\\' check
					return NULL;

				for(i=0; i<(8 - dir_len_count); i++)
				{
					*p = 0x20;
					p++;
				}

				dir_len_count =8;
				ppath++;
				continue;
			}
			break;

		case 0x22://非法字符
		case 0x2A:
		case 0x2B:
		case 0x2C:
		case 0x2F:
		case 0x3A:
		case 0x3B:
		case 0x3C:
		case 0x3D:
		case 0x3E:
		case 0x3F:
		case 0x5B:
		case 0x5D:
		case 0x7C:
			return NULL;

		default:
			{
				if(*ppath < 0x20)
					return NULL;				
			}
			break;
		}

		*p = *ppath;
		dir_len_count ++;

		if(dir_len_count > 11)
			return NULL;

		p++;
		ppath++;
	}

	return static_path;
}

//11个字符,其中8个字符为文件名,3个字符为文件后缀
void unformat_name(char * filename, const unsigned char dirname[11])
{
	int i;
	int j;

	memset(filename, 0, 13);

	for(i=0; i<8; i++)
	{
		if(dirname[i] != 0x20)
			filename[i] = dirname[i];
		else
			break;
	}
	
	if(dirname[8] != 0x20)
	{
		filename[i] = '.';
		j = i + 1;
		
		for(i=8; i<11; i++,j++)
		{
			if(dirname[i] != 0x20)
				filename[j] = dirname[i];
			else
				break;
		}
	}
}

//在所给的sector内寻找与dirname名称相同的项目
DWORD SectorSearch(DWORD Sector, const char dirname[11],  _FILE *file)
{
	BYTE* Cache;
	DIRENTRY *dir;
	unsigned int j;

	Cache = GetSectorData(Sector);
	if(Cache == NULL)
		return 0xffffffff;
	
	dir = (DIRENTRY *)Cache;
	for(j=0; (dir->deName[0] != '\0') && (j< BytesPerSector / sizeof(DIRENTRY)); j++)//不是空的目录项,在整个扇区搜索
	{
		if(memcmp((const char*)dir->deName, dirname, 11) == 0 && (!(dir->deAttributes & ATTR_VOLUME)))// not volumn id or long name entry.
		//如果目录名/文件名相同,且不是卷标项目
		{
			if(file != NULL)
			{
				memset((BYTE *)file, 0, sizeof(_FILE));
				file->DirSectorNum = Sector;
				file->DirIndex = j;
				memcpy((BYTE *)(&file->dir), (BYTE *)dir, sizeof(DIRENTRY));
			}
			return ClusterNum2SectorNum(dir->deStartCluster);//返回该目录/文件的起始簇号
		}
		dir++;
	}
	return 0xffffffff;
}

//在所给sector内寻找未被删除且不是卷标项的目录项,记录项目名称
int SectorGet(DWORD Sector, FatGet *fat_get)
{
	BYTE* Cache;
	DIRENTRY *dir;
	unsigned int j;

	Cache = GetSectorData(Sector);
	if(Cache == NULL)
		return 1;

	dir = (DIRENTRY *)Cache;
	dir += fat_get->DirIndex;

	for(j=fat_get->DirIndex; (dir->deName[0] != '\0') && (j< BytesPerSector / sizeof(DIRENTRY)); j++)
	{
		if(dir->deName[0] != 0xe5 && (!(dir->deAttributes & ATTR_VOLUME)))// not volumn id or long name entry.
		{
			fat_get->DirSectorNum = Sector;
			fat_get->DirIndex = j + 1;
			unformat_name(fat_get->filename, dir->deName);
			return 0;
		}
		dir++;
	}
	return 2;
}

//在根目录区或者数据区寻找是否有与dirname名称相同的项目
// return the first sector number of dir/file entry.
// 0xffffffff indicate NULLed.
DWORD Fat_search(DWORD Sector, const char dirname[11], _FILE *file)
{	
	unsigned int i;
	WORD Cluster;
	DWORD FirstSectorOfFile;

	//if(dirname == NULL)
		//return 0xffffffff;
	
	if(Sector == FirstDirSector)//指定根目录
	{
		for(i=0; i<(RootDirCount * sizeof(DIRENTRY) / BytesPerSector); i++)//在整个根目录区寻找
		{
			FirstSectorOfFile = SectorSearch(Sector++, dirname, file);//寻找与dirname名称相同的目录/文件
			if(FirstSectorOfFile != 0xffffffff)                       //返回目录/文件的第一簇
				return FirstSectorOfFile;
		}
	}
	else
	{
		Cluster = SectorNum2ClusterNum(Sector);//非根目录

		// because arg Sector is the first sector of parent dir content,
		// so it is the first sector of the cluster.
		/*
		i = (Sector - FirstDataSector) % Bpb.SecPerClus;
		
		if(i != 0)
		{
			for(; i< Bpb.SecPerClus; i++)
			{
				FirstSectorOfFile = SectorSearch(Sector++, dirname, file);
				if(FirstSectorOfFile != 0xffffffff)
					return FirstSectorOfFile;
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}*/
		
		while(Cluster != 0xffff)//不是最后一簇
		{
			for(i=0; i< SectorsPerCluster; i++)
			{
				FirstSectorOfFile = SectorSearch(Sector++, dirname, file);//寻找名称相同的目录/文件项
				if(FirstSectorOfFile != 0xffffffff)
					return FirstSectorOfFile;
			}

			Cluster = GetNextClusterNum(Cluster);
			Sector = ClusterNum2SectorNum(Cluster);
		}
	}

	return 0xffffffff;//找不到
}

//定位文件,即在根目录区查找到它的第一级目录,在下一个簇查找到它的第二级目录,直到最终定位文件。
// return the first sector number of dir/file content.
// 0xffffffff indicate NULLed.
// if path is root dir, file arg is ignore.
DWORD Fat_locate(const char *path, _FILE *file)
{
	DWORD Sector = FirstDirSector;
	char *p;

	p = get_valid_format(path);//判断是否合法
	if(p == NULL)
		return 0xffffffff;

	// locate first sub dir.
	p++;//忽略第一个‘\’

	// locate next sub dir(s).
	for(;;)
	{
		if(*p == NULL)
			return Sector;
		Sector = Fat_search(Sector, p, file);//在根目录区寻找是否有与P同名的目录/文件项
		if(Sector == 0xffffffff)
			return 0xffffffff;
		p+=12;
	}
	// we never go here.
	return 0xffffffff;
}
//获得当前的系统时间
void Fat_datetime(FatDateTime *fatdatetime)
{
	int year,month,day,weekday,hour,min,sec;
	WORD pdate = fatdatetime->Date;
	WORD ptm = fatdatetime->Time;
	
	rRTCCON = 0x01;    //RTC R/W enable, 1/32768, Normal(merge), No reset
	if(rBCDYEAR == 0x99) 
	    year = 0x1999;
	else 
	    year = 0x2000 + rBCDYEAR;
	month=rBCDMON;
	day=rBCDDAY;
	weekday=rBCDDATE;
	hour=rBCDHOUR;
	min=rBCDMIN;
	sec=rBCDSEC;
	rRTCCON = 0x0;    //RTC R/W disable(for power consumption), 1/32768, Normal(merge), No reset
	
	pdate = ((day << DD_DAY_SHIFT)&DD_DAY_MASK)+((month <<DD_MONTH_SHIFT)&DD_MONTH_MASK)
	        +(((year-1980) <<DD_YEAR_SHIFT)&DD_YEAR_MASK);
	
	ptm = ((hour<<DT_HOURS_SHIFT)&DT_HOURS_MASK)+((min<<DT_MINUTES_SHIFT)&DT_MINUTES_MASK)
	      +(((sec/2)<<DT_2SECONDS_SHIFT)&DT_2SECONDS_MASK);
	
	fatdatetime->TimeTenth = (sec % 2) * 100; //+ systm.wMilliseconds / 10;
}

///////////////////////////////////////////////////////////////////
// fat apis
///////////////////////////////////////////////////////////////////
//创建目录
int Fat_mkdir( const char *dirname) //仅1级目录: 父目录\新目录
{
	DIRENTRY dir;
	DWORD SectorNum;
	char path[512];
	char name[11];
	char *p;
	FatDateTime tm;
	_FILE file;	
	BYTE* Cache;
	DIRENTRY *pdir;
	WORD NewCluster;
	char dot[11] = {'.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
	char dotdot[11] = {'.', '.', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};

	// is path format correct ?
	p = get_valid_format(dirname);
	if(p == NULL)
		return 1;

	//if exist this dir ?
	if(Fat_locate(dirname, NULL) != 0xffffffff)
		return 4;

	//separate path into parent and name(directory name)
	strncpy(name, &p[strlen(p)-11], 11);//拷贝新的目录名->name
    //获得了文件的第一级目录(parent path)名称
	strcpy(path, dirname);
	p = strrchr(path, '\\');//返回path中‘\’第一次出现的指针
	if(p == path) // it is root dir.
		*(p+1) = '\0';
	else
		*p = '\0';
    
	//locate parent path
	SectorNum = Fat_locate(path, NULL);//获取第一级目录指向第一个扇区的地址
	if(SectorNum == 0xffffffff)
		return 2;

	//fill dir attributes
	memset((BYTE *)&dir, 0, sizeof(dir));
	memcpy((BYTE *)(dir.deName), name, 11);
	dir.deAttributes = ATTR_DIRECTORY;//目录属性
	Fat_datetime(&tm);
	dir.CrtDate = dir.LstAccDate = dir.WrtDate = tm.Date;
	dir.CrtTime = dir.WrtTime = tm.Time;
	dir.CrtTimeTenth = tm.TimeTenth;

	//alloc one dir在父目录所指的扇区下获得一个新的目录项
	if(AllocDir(SectorNum, &dir, &file) != 0)
		return 3;

	//alloc a cluster
	NewCluster = AllocCluster(0);
	if(NewCluster == 0xffff)
		return 4;

	//flush to disk
	Cache = GetSectorData(file.DirSectorNum);//将新的目录项所在扇区读入
	if(Cache == NULL)
		return 6;

	pdir = (DIRENTRY *)Cache;
	pdir += file.DirIndex;

	pdir->deStartCluster = NewCluster;//指向新的一簇
	Flush();

	//create . and .. dir items.
	Cache = GetSectorData(ClusterNum2SectorNum(NewCluster));//将新簇的第一个扇区读入
	if(Cache == NULL)
		return 6;

	pdir = (DIRENTRY *)Cache;//获得一个目录项本地目录:.

⌨️ 快捷键说明

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