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

📄 usbfat16.c

📁 ARM主USB程序
💻 C
📖 第 1 页 / 共 4 页
字号:
		for(i=0;i<page-1;i++)
    	{
        	usbReadPage(block,i,SectorBuffer);
	        memcpy(ClusterBuffer[i], SectorBuffer, BytesPerSector);
    	}
    	for(i=page+1;i< SectorsPerCluster;i++)
    	{
    		usbReadPage(block,i,SectorBuffer);
    	    memcpy(ClusterBuffer[i], SectorBuffer, BytesPerSector);
    	}   
	}*/

    //memcpy(SectorBuffer,ClusterBuffer[page],BytesPerSector);//保持Sectorbuffer作为cache内容保持不变!!
	
	//Erase_Cluster(block);//写入之前,擦除当前簇;
   // for(i=0;i<SectorsPerCluster;i++)//一扇区接一扇区写入
  //  {
    //	for(j=0;j<255;j++);//延时
    	usbWritePage(block,page,ClusterBuffer[page]);
   // } 
	//没有检验
}




///////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


WORD SectorNum2ClusterNum(DWORD SectorNum)
{
	return (WORD)((SectorNum - FirstDataSector) / SectorsPerCluster + 1);//NOTE:NO MBR!!!
}



/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////



DWORD ClusterNum2SectorNum(WORD ClusterNum)
{
	return FirstDataSector + (ClusterNum - 1) * SectorsPerCluster;//NOTE:NO MBR!!!
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// return the first sector number of dir content .
// 0xffffffff indicate failed.//
//从目录区中取得一个目录项


int AllocDir(DWORD ParentDirSectorNum, DIRENTRY* new_dir, _FILE * fp)
{
	BYTE* Cache;
	DIRENTRY *dir;
	DWORD i;
	WORD PrevCluster;
	WORD Cluster;
	DWORD DirSectorNum = ParentDirSectorNum;

	//if(dirname == NULL)
		//return 1;

	if(ParentDirSectorNum == FirstDirSector)//在根目录区
	{
		for(i=0; i<RootDirCount * sizeof(DIRENTRY) / BytesPerSector; i++)
		{
			Cache = GetSectorData(DirSectorNum);
			if(Cache == NULL)
				return 2;
			
			for(dir = (DIRENTRY *)Cache; (BYTE*)dir < Cache + BytesPerSector; dir++)
			{
				if(dir->deName[0] == '\0' || dir->deName[0] == 0xe5)
				{
					memcpy((BYTE *)dir, (BYTE *)new_dir, sizeof(DIRENTRY));	//将新的目录信息写入				
					Flush();//更新disk中该扇区
					if(fp)//更新文件信息
					{
						fp->DirSectorNum = DirSectorNum;//当前目录项所在的扇区地址
						fp->DirIndex = ((BYTE*)dir - Cache) / sizeof(DIRENTRY);//目录索引,即该扇区中第x个目录项
						memcpy((BYTE *)(&fp->dir), (BYTE *)new_dir, sizeof(DIRENTRY));//新的目录信息写到文件结构中
					}
					return 0;//操作成功,退出
				}
			}
			DirSectorNum++;//下一个根目录扇区
		}
		// root dir have no room.
		return 3; 
	}
	
	else//不在根目录区
	{
		Cluster = SectorNum2ClusterNum(DirSectorNum);//
		
		while(Cluster != 0xffff)
		{
			for(i=0; i< SectorsPerCluster; i++)//在整个簇中搜索
			{
				Cache = GetSectorData(DirSectorNum);
				if(Cache == NULL)
					return 2;
				
				for(dir = (DIRENTRY *)Cache; (BYTE*)dir < Cache + BytesPerSector; dir++)
				{
					if(dir->deName[0] == '\0' || dir->deName[0] == 0xe5)
					{
						memcpy((BYTE *)dir, (BYTE *)new_dir, sizeof(DIRENTRY));
						Flush();
						
						if(fp)
						{
							fp->DirSectorNum = DirSectorNum;
							fp->DirIndex = ((BYTE*)dir - Cache) / sizeof(DIRENTRY);
							memcpy((BYTE *)(&fp->dir),(BYTE *)new_dir, sizeof(DIRENTRY));
						}
						return 0;
					}
				}
				DirSectorNum++;//下一个扇区
			}
			//搜索完当前簇,没有空的目录项
			PrevCluster = Cluster;//从FAT表中找出下一簇
			Cluster = GetNextClusterNum(Cluster);
			DirSectorNum = ClusterNum2SectorNum(Cluster);//刷新目录扇区
		}
		//且这已经是最后一个簇
		//
		// we have to extend this parent dir room.
		//
		Cluster = AllocCluster(PrevCluster);//利用FAT表获得一个空簇
		if(Cluster == 0xffff)//没有空簇
			return 4;
		
		DirSectorNum = ClusterNum2SectorNum(Cluster);//空簇做新的目录扇区地址
		
		Cache = GetSectorData(DirSectorNum);
		if(Cache == NULL)
			return 2;
		
		dir = (DIRENTRY *)Cache;
		
		memcpy((BYTE *)dir, (BYTE *)new_dir, sizeof(DIRENTRY));
		Flush();
		
		if(fp)
		{
			fp->DirSectorNum = DirSectorNum;
			fp->DirIndex = ((BYTE*)dir - Cache) / sizeof(DIRENTRY);
			memcpy((BYTE *)(&fp->dir), (BYTE *)new_dir, sizeof(DIRENTRY));
		}
		
		return 0;
	}

	return 5;
}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int DeleteDir(_FILE *file)
{
	BYTE* Cache;
	DIRENTRY *dir;

	Cache = GetSectorData(file->DirSectorNum);//文件在目录区的扇区地址
	if(Cache == NULL)
		return 1;

	dir = (DIRENTRY *)Cache;
	dir += file->DirIndex;//目录的索引号

	dir->deName[0] = 0xe5;//做删除标记
	Flush();

	return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// helper functions

// NULL indicate failed.
// Valid format is full path:	\[8.3\]*DIR_Name检验文件路径字符串是否合法
// limits:
// length < 80 && !(special char)
char* get_valid_format(const char *fullpath)
{
	static char static_path[512];
	char* p=static_path;
	char path[80];
	char* ppath = path;
	int dir_len_count; //count dir len.
	int i;

	if(fullpath == NULL || strlen(fullpath) >=80 || *fullpath != '\\')//第一个字符是‘\’
		return NULL;

	if(strlen(fullpath) > 1 && fullpath[strlen(fullpath)-1] =='\\')//最后一个字符是‘\’
		return NULL;

	strcpy(path, fullpath);
	//strupr(path);
	memset(p, 0, 512);

	for(;;)
	{
		switch(*ppath)
		{
		case 0x00://结束符
			{
				if(dir_len_count != 0) // prev is not '\\'
				{
					for(i=0; i<(11 - dir_len_count); i++)//未满11字节,用blank填满
					{
						*p = 0x20;
						p++;
					}
				}
			}
			return static_path;//返回整个字符串

		case '\\':
			{
				if(p != static_path) // this is not the first '\\'
				{
					if(dir_len_count == 0)// more than one '\\'
						return NULL;

					for(i=0; i<(11 - dir_len_count); i++)
					{
						*p = 0x20;
						p++;
					}
				}
				
				*p = '\\';
				p++;
				
				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 failed.
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;//找不到
}





//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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