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

📄 udiskdlg.cpp

📁 一个通过直接读取磁盘扇区的试验程序,对开发单片机读取U盘的程序员,可以了解FAT16的文件系统.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        return ;
	}
	m_ctr_msg.SetWindowText("正在读取文件系统...");
	for(loop = fdt_lba ; loop < data_lba ; loop++ )	//分析处理根目录的内容
	{
		res = SetFilePointer (hDevice, loop * 512, NULL, FILE_BEGIN);
		res = ReadFile (hDevice, fdt_buf, 512, &bytesread, NULL);
		if(( res != 1 ) |  ( bytesread != 512))
		{
			m_ctr_msg.SetWindowText("读取数据失败 !");
			return ;
		}
		for(loop1 = 0 ; loop1 < 512 ; loop1 = loop1 + 32)
		{
			memcpy(&root_dir,&fdt_buf[loop1],sizeof(root_dir));
			if( root_dir.FileName[0] == 0 ) 
				break;
			if( root_dir.FileName[0] != 0xe5 )
			{
				if( root_dir.FileName[0] == 0x05 ) root_dir.FileName[0] = 0xe5;
				if((( root_dir.attribute & 0x08 ) == 0x08 )	&& ( root_dir.attribute != 0x0f ))	//卷标
				{
					memset(buf,0,32);
					memcpy(buf,&root_dir,11);
					for(res = 0 ; res < 11 ;res++)
					{
						if(buf[res] ==' ')
						{
							buf[res] = 0 ;
							break;
						}
					}
					if(res == 11 ) buf[11]=0;
					m_ctr_dir.SetItemText(m_hRoot,buf);
				}
				else Get_dir_file(root_dir,m_hRoot);
			}
		}
		if(loop1 < 512 ) break ;
	}
	m_ctr_msg.SetWindowText("文件系统读取成功!");
}

void CUdiskDlg::Get_dir_file(DIR_tag dir, HTREEITEM hitem)
{
	unsigned char buf[32];
	unsigned char sub_dir_buf[512];
	HTREEITEM hsub_item;
	CString filename;
	struct DIR_tag sub_dir;
	unsigned long sec_number,bytesread;
	int loop ,res,loop1;
	memset(buf,0,12);
//	sec_number = (dir.StartClus - 2 ) * 4 +	data_lba ;	//逻辑扇区号=(簇号 - 2)* 每簇扇区数 + 数据区起始逻辑扇区号
	if(( dir.attribute & 0x10 ) == 0x10 )	//子目录
	{
		memcpy(buf,&dir,11);
		for(loop = 0 ; loop < 11 ; loop++ )
		{
			if( buf[loop] == ' ' )
			{
				buf[loop]=0;
				break;
			}
		}
		hsub_item = m_ctr_dir.InsertItem((const char *)&buf[0],hitem); //添加子目录项
		while(1)
		{
			sec_number = (dir.StartClus - 2 ) * 4 +	data_lba ;	//逻辑扇区号=(簇号 - 2)* 每簇扇区数 + 数据区起始逻辑扇区号
			for(loop = 0 ; loop < 4 ; loop ++ )		//读取1簇子目录数据=4个扇区数据
			{
				res = SetFilePointer (hDevice, sec_number * 512, NULL, FILE_BEGIN);
				res = ReadFile (hDevice, sub_dir_buf, 512, &bytesread, NULL);
				if(( res != 1 ) |  ( bytesread != 512))
				{
					m_ctr_msg.SetWindowText("读取数据失败 !");
					return ;
				}
				for(loop1 = 0 ; loop1 < 512 ; loop1 = loop1 + 32)
				{
					memcpy(&sub_dir,&sub_dir_buf[loop1],sizeof(sub_dir));
					if( sub_dir.FileName[0] == 0 ) break;
					if( sub_dir.FileName[0] != 0xe5 )
					{
						if( sub_dir.FileName[0] == 0x05 ) sub_dir.FileName[0] = 0xe5;
						if(buf[0] != '.' )	Get_dir_file(sub_dir,hsub_item);
					}
				}
				if( loop1 < 512 ) break;//遇到未用目录项,本目录区结束
				sec_number++;
			}
			if( loop1 < 512 ) break;//遇到未用目录项,本目录区结束
			//检查簇链是否结束
			dir.StartClus = Find_next_clus(dir.StartClus) ; //得到下一个簇号
			if(dir.StartClus == 0xffff ) break; //结束簇
		}
	}
	else		//文件
	{
		if(( dir.attribute & 0x0f ) != 0x0f )
		{
			memset(buf,0,13);
			memcpy(buf,&dir,8);
			buf[8]='.';
			memcpy(&buf[9],&dir.ExtName,3);
			filename.Format("%s",buf);
			filename.Replace(" ","");
			m_ctr_dir.InsertItem(filename,hitem);	//添加文件项
		}
	}
}
//已知当前簇号,求下一簇号
unsigned short CUdiskDlg::Find_next_clus(unsigned short now_clus)
{
	unsigned short next_clus;
	unsigned int i,res;
	unsigned char buf[512];
	unsigned long bytesread;
	i = now_clus * 2;	//得到下一个簇号在FAT中的字节偏移量
	i = i / 512 ;		//得到下一个簇号自FAT的偏移扇区
	res = SetFilePointer (hDevice, ( fat1_lba + i ) * 512, NULL, FILE_BEGIN);
	res = ReadFile (hDevice, buf, 512, &bytesread, NULL);
	if(( res != 1 ) |  ( bytesread != 512))
	{
		m_ctr_msg.SetWindowText("读取数据失败 !");
		return 0xffff;
	}
	i = now_clus * 2 - i * 512 ;
	next_clus = 0 ;
	memcpy(&next_clus , &buf[i] , 2 ) ;
	return next_clus;
}

void CUdiskDlg::OnBUTTONsavefile() 
{
	// TODO: Add your control notification handler code here
	HTREEITEM selected_item;
	CString file_name,path,dir,strtemp;
	unsigned short now_clus;
	int res,i,loop;
	struct DIR_tag str_file;
	unsigned char dir_name[15];
	unsigned char buf[512];
	unsigned long bytesread ,sec_number;
	selected_item = m_ctr_dir.GetSelectedItem();
	file_name = m_ctr_dir.GetItemText(selected_item);
	path="";
	m_ctr_msg.SetWindowText("正在查找文件位置...");
	while(selected_item != m_hRoot)
	{
		selected_item = m_ctr_dir.GetParentItem(selected_item);
		if(selected_item == m_hRoot) break ;
		path = m_ctr_dir.GetItemText(selected_item) + "\\"+ path ;
	}
	file_name = path + file_name ;	//取得文件完整路径
/////查找文件起始簇号:
	now_clus = 0;	//设置初始簇号 = 0
	while((res = file_name.Find("\\",0)) != -1)	//文件不在根目录,查找文件所在目录
	{
		path = file_name.Left(res);
		dir = "" ;
		if(now_clus == 0)	//在根目录中查询子目录起始簇
		{
			for( i = fdt_lba ; i < data_lba ; i++ )
			{
				SetFilePointer (hDevice, i * 512, NULL, FILE_BEGIN);	//读取根目录内容
				ReadFile (hDevice, buf, 512, &bytesread, NULL);
				for(loop = 0 ; loop < 512 ; loop = loop + 32)
				{
					memcpy(&str_file,&buf[loop],sizeof(str_file));
					if( str_file.FileName[0] == 0 ) 
					{
						m_ctr_msg.SetWindowText("文件所在目录未找到!");
						return;
					}
					if(( str_file.FileName[0] != 0xe5 ) && (str_file.attribute != 0x0f ) && ((str_file.attribute & 0x10) == 0x10 ))
					{
						if( str_file.FileName[0] == 0x05 ) str_file.FileName[0] = 0xe5;
						memcpy(dir_name,&str_file,11);
						dir_name[11]=0;
						dir.Format("%s",dir_name);
						dir.Replace(" ","");
						if(dir == path)	//找到目录
						{
							memcpy(&now_clus,&str_file.StartClus,2);	//得到该目录所在簇
							file_name = file_name.Right(file_name.GetLength() - file_name.Find("\\",0) - 1 );
							break;
						}
					}
				}
				if(dir == path) break;
			}
			
		}
		else	//在子目录中查找文件所在位置
		{
			sec_number = (now_clus - 2 ) * 4 +	data_lba ;	//逻辑扇区号=(簇号 - 2)* 每簇扇区数 + 数据区起始逻辑扇区号
			for( i = 0 ; i < 4 ; i++ )	//查找1簇=4个扇区
			{
				SetFilePointer (hDevice, (sec_number +i )* 512, NULL, FILE_BEGIN);	//读取子目录内容
				ReadFile (hDevice, buf, 512, &bytesread, NULL);
				for(loop = 0 ; loop < 512 ; loop = loop + 32)
				{
					memcpy(&str_file,&buf[loop],sizeof(str_file));
					if( str_file.FileName[0] == 0 )
					{
						m_ctr_msg.SetWindowText("文件所在目录未找到!");
						return;
					}
					if(( str_file.FileName[0] != 0xe5 ) && (str_file.attribute != 0x0f ) && ((str_file.attribute & 0x10) == 0x10 ))
					{
						if( str_file.FileName[0] == 0x05 ) str_file.FileName[0] = 0xe5;
						memcpy(dir_name,&str_file,11);
						dir_name[11]=0;
						dir.Format("%s",dir_name);
						dir.Replace(" ","");
						if(dir == path)	//找到目录
						{
							memcpy(&now_clus,&str_file.StartClus,2);	//得到该目录所在簇
							file_name = file_name.Right(file_name.GetLength() - file_name.Find("\\",0) - 1 );

							break;
						}
					}
				}
				if(dir == path) break;
			}
			if(dir != path) 
			{
				now_clus = Find_next_clus(now_clus);
				if(now_clus == 0xffff) 
				{
					m_ctr_msg.SetWindowText("文件所在目录未找到!");
					return;
				}
			}
		}
	}
	if(now_clus == 0 )		//文件在根目录
	{
		for( i = fdt_lba ; i < data_lba ; i++ )
		{
			SetFilePointer (hDevice, i * 512, NULL, FILE_BEGIN);	//读取根目录内容
			ReadFile (hDevice, buf, 512, &bytesread, NULL);
			for(loop = 0 ; loop < 512 ; loop = loop + 32)
			{
				memcpy(&str_file,&buf[loop],sizeof(str_file));
				if( str_file.FileName[0] == 0 ) 
				{
					m_ctr_msg.SetWindowText("文件未找到!");
					return;
				}
				if(( str_file.FileName[0] != 0xe5 ) && (str_file.attribute != 0x0f ))
				{
					if( str_file.FileName[0] == 0x05 ) str_file.FileName[0] = 0xe5;
					memcpy(dir_name,&str_file,8);	//取文件名
					dir_name[8]=0;
					dir.Format("%s",dir_name);
					dir.Replace(" ","");
					memcpy(dir_name,&str_file.ExtName,3);//取扩展名
					dir_name[3]=0;
					strtemp.Format("%s",dir_name);
					strtemp.Replace(" ","");
					if(strtemp != "") dir = dir+"."+strtemp;

					if(dir == file_name)	//找到文件
					{
						memcpy(&now_clus,&str_file.StartClus,2);	//得到该文件起始簇
						savefile(str_file.StartClus,str_file.FileLength,file_name);
						break;
					}
				}
			}
			if(dir == path) break;
		}
	}
	else	//文件不在根目录
	{
		while(1)
		{
			sec_number = (now_clus - 2 ) * 4 +	data_lba ;	//逻辑扇区号=(簇号 - 2)* 每簇扇区数 + 数据区起始逻辑扇区号
			for( i = 0 ; i < 4 ; i++ )	//查找1簇=4个扇区
			{
				SetFilePointer (hDevice, (sec_number +i )* 512, NULL, FILE_BEGIN);	//读取子目录内容
				ReadFile (hDevice, buf, 512, &bytesread, NULL);
				for(loop = 0 ; loop < 512 ; loop = loop + 32)
				{
					memcpy(&str_file,&buf[loop],sizeof(str_file));
					if( str_file.FileName[0] == 0 ) 
					{
						m_ctr_msg.SetWindowText("文件未找到!");
						return;
					}
					if(( str_file.FileName[0] != 0xe5 ) && (str_file.attribute != 0x0f ) )
					{
						if( str_file.FileName[0] == 0x05 ) str_file.FileName[0] = 0xe5;
						memcpy(dir_name,&str_file,8);	//取文件名
						dir_name[8]=0;
						dir.Format("%s",dir_name);
						dir.Replace(" ","");
						memcpy(dir_name,&str_file.ExtName,3);//取扩展名
						dir_name[3]=0;
						strtemp.Format("%s",dir_name);
						strtemp.Replace(" ","");
						if(strtemp != "") dir = dir+"."+strtemp;
						if(dir == file_name)	//找到文件
						{
							memcpy(&now_clus,&str_file.StartClus,2);	//得到该文件起始簇
							savefile(str_file.StartClus,str_file.FileLength,file_name);
							break;
						}
					}
					if(dir == file_name) break;
				}
				if(dir == file_name) break;
			}
			if(dir != file_name) 
			{
				now_clus = Find_next_clus(now_clus);
				if(now_clus == 0xffff) 
				{
					m_ctr_msg.SetWindowText("文件未找到!");
					return;
				}
			}
			else break;

		}

	}
	
}

int CUdiskDlg::savefile(unsigned short first_clus, unsigned long file_length,CString File_name)
{

	CFile file;
	CString str;
	unsigned char file_buf[512];
	unsigned long bytes_write ,sec_number,bytesread;
	unsigned short now_clus,i;
	file.Open (File_name, CFile::modeCreate | CFile::modeWrite , NULL ) ;
	now_clus = first_clus ;
	bytes_write = 0 ;
	m_ctr_msg.SetWindowText("正在保存文件...");
	if( file_length != 0 )
	{
		while(1)
		{
			sec_number = (now_clus - 2 ) * 4 +	data_lba ;	//逻辑扇区号=(簇号 - 2)* 每簇扇区数 + 数据区起始逻辑扇区号
			for( i = 0 ; i < 4 ; i++ )	//查找1簇=4个扇区
			{
				SetFilePointer (hDevice, (sec_number +i )* 512, NULL, FILE_BEGIN);	//读取子目录内容
				ReadFile (hDevice, file_buf, 512, &bytesread, NULL);
				if( file_length - bytes_write > 512) 
				{
					file.Write(file_buf,512) ;
					bytes_write = bytes_write + 512 ;
				}
				else 
				{
					file.Write(file_buf,(file_length - bytes_write)) ;
					bytes_write = file_length ;
				}
				str.Format("正在保存文件...   %i%%",bytes_write*100/file_length);
				m_ctr_msg.SetWindowText(str);
				if(bytes_write == file_length ) break;
			}
			if(bytes_write == file_length ) break;
			now_clus = Find_next_clus(now_clus);
		}
	}

	file.Close ();
	if(bytes_write == file_length ) 
	{
		m_ctr_msg.SetWindowText("文件保存成功!");
		return 1;
	}
	else
	{
		m_ctr_msg.SetWindowText("文件保存失败!");
		return 0;
	}
}

⌨️ 快捷键说明

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