今天FAT文件系统总算告一个段落了,已经可以非常完美的读取包含FAT16文件系统的磁盘了。由于是采用C#编写,直接借鉴的代码很少,并且考虑到MF不支持二进制序列化,所以对数据结构的解析,是一个一个字节进行的,所以很耗费时间。下面就是程序运行后的结果(可以识别物理磁盘及物理磁盘的分区)。
下图是用文件浏览器查看的结果。
磁盘系统的MDR和DBR信息如下。
为了便于后来者,把主要的结构声明代码罗列如下,希望有借鉴意义。
//基本类[叶帆工作室]http://blog.csdn.net/yefanqiu/
publicclassDiskBase
{
#region//MBRhttp://blog.csdn.net/yefanqiu/
publicstructPartitionTable
{
publicbyteBootFlag;//分区活动标志只能选00H和80H。80H为活动,00H为非活动
publicCHSStartCHS;//分区开始的柱面、磁头、扇区
publicbyteSystemID;//分区类型01FAT3204FAT16<32M06FAT1607HPFS/NTFS050F扩展分区
publicCHSEndCHS;//分区结束的柱面、磁头、扇区
publicUInt32RelativeSectors;//分区起始扇区数,指分区相对于记录该分区的分区表的扇区位置之差(该分区表:LBA=0x0)。
publicUInt32TotalSectors;//分区总扇区数
}
publicstructCHS
{
publicbyteHead;//磁头
publicbyteSector;//扇区六位
publicUInt16Cylinder;//柱面十位
}
publicstructMBR
{
publicbyte[]bytBootCode;//ofs:0.引导代码446字节"FA33C08ED0BC…"
publicPartitionTable[]PT;//ofs:446.64个字节分区表length=4*16
publicUInt16EndingFlag;//ofs:510.结束标识:0xAA55。
publicMBR(byte[]bytData)
{
inti;
bytBootCode=newbyte[446];
for(i=0;i<446;i++)bytBootCode[i]=bytData[i];
PT=newPartitionTable[4];
for(i=0;i<4;i++)
{
PT[i].BootFlag=bytData[446+i*16+0];
PT[i].StartCHS.Head=bytData[446+i*16+1];
PT[i].StartCHS.Sector=(byte)(bytData[446+i*16+2]&0x3f);
PT[i].StartCHS.Cylinder=(UInt16)(((bytData[446+i*16+2]&0xc0)<<2)|bytData[446+i*16+3]);
PT[i].SystemID=bytData[446+i*16+4];
PT[i].EndCHS.Head=bytData[446+i*16+5];
PT[i].EndCHS.Sector=(byte)(bytData[446+i*16+6]&0x3f);
PT[i].EndCHS.Cylinder=(UInt16)(((bytData[446+i*16+6]&0xc0)<<2)|bytData[446+i*16+7]);
PT[i].RelativeSectors=(UInt32)(bytData[446+i*16+11]<<24|bytData[446+i*16+10]<<16|bytData[446+i*16+9]<<8|bytData[446+i*16+8]);
PT[i].TotalSectors=(UInt32)(bytData[446+i*16+15]<<24|bytData[446+i*16+14]<<16|bytData[446+i*16+13]<<8|bytData[446+i*16+12]);
}
EndingFlag=(UInt16)(bytData[510]<<8|bytData[511]);
}
#endregion
#region//DBRhttp://blog.csdn.net/yefanqiu/
//系统引导记录(兼容FAT16和FAT32)
publicstructDBR
{
publicbyte[]BS_JmpBoot;//ofs:0.典型的如:0xEB,0x3E,0x90。
publicbyte[]BS_OEMName;//ofs:3.典型的如:“MSWIN4.1”。
publicUInt16BPB_BytsPerSec;//ofs:11.每扇区字节数。
publicbyteBPB_SecPerClus;//ofs:13.每簇扇区数。
publicUInt16BPB_RsvdSecCnt;//ofs:14.保留扇区数,从DBR到FAT的扇区数。
publicbyteBPB_NumFATs;//ofs:16.FAT的个数。
publicUInt16BPB_RootEntCnt;//ofs:17.根目录项数。
publicUInt16BPB_TotSec16;//ofs:19.分区总扇区数(<32M时用)。
publicbyteBPB_Media;//ofs:21.分区介质标识,优盘一般用0xF8。
publicUInt16BPB_FATSz16;//ofs:22.每个FAT占的扇区数。
publicUInt16BPB_SecPerTrk;//ofs:24.每道扇区数。
publicUInt16BPB_NumHeads;//ofs:26.磁头数。
publicUInt32BPB_HiddSec;//ofs:28.隐藏扇区数,从MBR到DBR的扇区数。
publicUInt32BPB_TotSec32;//ofs:32.分区总扇区数(>=32M时用)。
//---------------------
//FAT32特有
publicUInt32BPB_FATSz32;//ofs:36.每个FAT占的扇区数。
publicUInt16BPB_ExtFlags;//ofs:40.FAT标志
publicUInt16BPB_FSVer;//ofs:42.版本号高字节主版本低字节次版本号
publicUInt32BPB_RootClus;//ofs:44.根目录所在第一个簇的簇号,通常该数值为2,但不是必须为2。
publicUInt16BPB_FSInfo;//ofs:48.保留区中FAT32卷FSINFO结构所占的扇区数,通常为1。
publicUInt16BPB_BkBootSec;//ofs:50.如果不为0,表示在保留区中引导记录的备份数据所占的扇区数,通常为6。同时不建议使用6以外的其他数值。
[MarshalAs(UnmanagedType.ByValArray,SizeConst=12)]
publicbyte[]BPB_Reserved;//ofs:52.备用
//---------------------
publicbyteBS_drvNum;//ofs:64/36.软盘使用0x00,硬盘使用0x80。
publicbyteBS_Reserved1;//ofs:65/37.保留。
publicbyteBS_BootSig;//ofs:66/38.扩展引导标记:0x29。
publicbyte[]BS_VolID;//ofs:67/39.盘序列号。
publicbyte[]BS_VolLab;//ofs:71/43.“Msdos”。
publicbyte[]BS_FilSysType;//ofs:82/54.“FAT32”。
publicbyte[]ExecutableCode;//ofs:90/62.引导代码。
publicUInt16EndingFlag;//ofs:510.结束标识:0xAA55。
//---------------------
//0-未知1-FAT122-FAT163-FAT32其它值为未知
publicbyteFATType;
//获取信息
publicDBR(byte[]bytData)
{
FATType=IsType(bytData);
inti;
BS_JmpBoot=newbyte[3];
for(i=0;i<2;i++)BS_JmpBoot[i]=bytData[i];
BS_OEMName=newbyte[8];
for(i=0;i<8;i++)BS_OEMName[i]=bytData[i+3];
BPB_BytsPerSec=(UInt16)(bytData[12]<<8|bytData[11]);
BPB_SecPerClus=bytData[13];
BPB_RsvdSecCnt=(UInt16)(bytData[15]<<8|bytData[14]);
BPB_NumFATs=bytData[16];
BPB_RootEntCnt=(UInt16)(bytData[18]<<8|bytData[17]);
BPB_TotSec16=(UInt16)(bytData[20]<<8|bytData[19]);
BPB_Media=bytData[21];
BPB_FATSz16=(UInt16)(bytData[23]<<8|bytData[22]);
BPB_SecPerTrk=(UInt16)(bytData[25]<<8|bytData[24]);
BPB_NumHeads=(UInt16)(bytData[27]<<8|bytData[26]);
BPB_HiddSec=(UInt32)(bytData[31]<<24|bytData[30]<<16|bytData[29]<<8|bytData[28]);
BPB_TotSec32=(UInt32)(bytData[35]<<24|bytData[34]<<16|bytData[33]<<8|bytData[32]);
//----------
if(FATType==3)
{
//FAT32
BPB_FATSz32=(UInt32)(bytData[39]<<24|bytData[38]<<16|bytData[37]<<8|bytData[36]);
BPB_ExtFlags=(UInt16)(bytData[41]<<8|bytData[40]);
BPB_FSVer=(UInt16)(bytData[43]<<8|bytData[42]);
BPB_RootClus=(UInt32)(bytData[47]<<24|bytData[46]<<16|bytData[45]<<8|bytData[44]);
BPB_FSInfo=(UInt16)(bytData[49]<<8|bytData[48]);
BPB_BkBootSec=(UInt16)(bytData[51]<<8|bytData[50]);
BPB_Reserved=newbyte[12];
for(i=0;i<12;i++)BPB_Reserved[i]=bytData[i+52];
//----------
BS_drvNum=bytData[64];
BS_Reserved1=bytData[65];
BS_BootSig=bytData[66];
BS_VolID=newbyte[4];
for(i=0;i<4;i++)BS_VolID[i]=bytData[67+i];
BS_VolLab=newbyte[11];
for(i=0;i<11;i++)BS_VolLab[i]=bytData[71+i];
BS_FilSysType=newbyte[8];
for(i=0;i<8;i++)BS_FilSysType[i]=bytData[82+i];
ExecutableCode=newbyte[420];
for(i=0;i<420;i++)ExecutableCode[i]=bytData[90+i];
}
else
{
//FAT16
BS_drvNum=bytData[36];
BS_Reserved1=bytData[37];
BS_BootSig=bytData[38];
BS_VolID=newbyte[4];
for(i=0;i<4;i++)BS_VolID[i]=bytData[39+i];
BS_VolLab=newbyte[11];
for(i=0;i<11;i++)BS_VolLab[i]=bytData[43+i];
BS_FilSysType=newbyte[8];
for(i=0;i<8;i++)BS_FilSysType[i]=bytData[54+i];
ExecutableCode=newbyte[448];
for(i=0;i<448;i++)ExecutableCode[i]=bytData[62+i];
//FAT32
BPB_FATSz32=0;
BPB_ExtFlags=0;
BPB_FSVer=0;
BPB_RootClus=0;
BPB_FSInfo=0;
BPB_BkBootSec=0;
BPB_Reserved=newbyte[12];
}
//----------
EndingFlag=(UInt16)(bytData[510]<<8|bytData[511]);
}
#endregion
//文件系统判断(采用微软的判断方法)
publicstaticbyteIsType(byte[]bytData)
{
//不是合法BPB扇区数据
if(bytData[510]!=0x55||bytData[511]!=0xaa)return0;
//跳转指令不合法
if(bytData[0]!=0xeb&&bytData[0]!=0xe9)return0;
//每扇区包含的字节数(一般为512个字节)
UInt16BPB_BytsPerSec=(UInt16)(bytData[12]<<8|bytData[11]);
//仅处理512个字节的扇区
if(BPB_BytsPerSec!=512)return0;
//每簇扇区数
byteBPB_SecPerClus=bytData[13];
//保留扇区数
UInt16BPB_RsvdSecCnt=(UInt16)(bytData[15]<<8|bytData[14]);
//FAT表的个数
byteBPB_NumFATs=bytData[16];
//FAT表的个数必须为2
if(BPB_NumFATs!=2)return0;
//根目录项数(32字节为单位)
UInt16BPB_RootEntCnt=(UInt16)(bytData[18]<<<span style
分享到:
相关推荐
FAT文件系统解析
FAT16 文件系统格式说明FAT16 文件系统格式说明
单片机读写U盘FAT32或FAT16文件系统.pdf
本版本代码完全兼容FAT16/FAT32文件系统总共两种格式,兼容长文件名, 兼容文字编码GB2312/UNICODE汉字编码(文件名完全支持中文), 实现了支持子目录,实现了支持文件的读取,写入,删除,创建等文件系统常用功能...
FAT文件系统 FAT文件系统 FAT文件系统 FAT文件系统
FAT表(File Allocation Table 文件分配表),是Microsoft在FAT文件系统中用于磁盘数据(文件)索引和定位引进的一种链式结构。假如把磁盘比作一本书,FAT表可以认为相当于书中的目录,而文件就是各个章节的内容。但FAT...
FAT16文件系统说明及代码.本文件是嵌入式FAT文件系统的说明书,嵌入式FAT文件系统的开发和使用人员都可通过阅读该文件,以掌握和使用文件系统。
支持单片机上运行的fat16文件系统,可用
FAT16文件系统知识 FAT16文件系统知识 FAT16文件系统知识
通过FAT文件系统学习,入门文件系统的原理
fat16 文件系统fat16 文件系统fat16 文件系统
全面介绍FAT家族文件系统的详尽资料,全部是简体中文,压缩包内含三本电子书,一齐发出,希望能对学习FAT文件系统的朋友有所帮助。资源免费,欢迎大家下载! 祝大家编程愉快!
详细介绍了FAT文件系统(包括FAT12,FAT16,FAT32),不知是哪位牛人写的电子书详细介绍了FAT文件系统(包括FAT12,FAT16,FAT32),不知是哪位牛人写的电子书详细介绍了FAT文件系统(包括FAT12,FAT16,FAT32),不知是哪位牛人写...
FAT16源代码,实现了文件系统的基本功能
绍了 SD 卡的基本结构和技术特征,详细说明了使用 MSP430单片机和 SD 卡设计的FAT16文件系统,给出了接口电路和相应的软件系统设计。该系统适用于大容量的现场数据采集、存储,并在动态心电图记录系统中得到了应用。
SD卡FAT16文件系统介绍!
SD卡上FAT32, FAT16文件系统源代码
FAT32文件系统原理和FAT32文件系统算法,深入了解。
利用WINHEX查看FAT系统的过程,基础的
手工解析FAT32文件格式浏览文件 后面再学习解析NTFS