`
mmdev
  • 浏览: 13428663 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

FAT16文件系统解析(C#版本)

 
阅读更多

今天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]<<8|bytData[17]);
//分区总扇区数(<32M时用)
UInt16BPB_TotSec16=(UInt16)(bytData[20]<<8|bytData[19]);
//每个FAT占的扇区数
UInt16BPB_FATSz16=(UInt16)(bytData[23]<<8|bytData[22]);
//分区总扇区数(>=32M时用)
UInt32BPB_TotSec32=(UInt32)(bytData[35]<<24|bytData[34]<<16|bytData[33]<<8|bytData[32]);
//每个FAT占的扇区数(FAT32)
UInt32BPB_FATSz32=(UInt32)(bytData[39]<<24|bytData[38]<<16|bytData[37]<<8|bytData[36]);

UInt64FATSz
=0,TotSec=0,DataSec=0;
UInt64RootDirSectors
=(UInt64)(((BPB_RootEntCnt*32)+(BPB_BytsPerSec-1))/BPB_BytsPerSec);

if(BPB_FATSz16!=0)
FATSz
=BPB_FATSz16;
else
FATSz
=BPB_FATSz32;

if(BPB_TotSec16!=0)
TotSec
=BPB_TotSec16;
else
TotSec
=BPB_TotSec32;

DataSec
=TotSec-(BPB_RsvdSecCnt+(BPB_NumFATs*FATSz)+RootDirSectors);
UInt64CountofClusters
=DataSec/BPB_SecPerClus;
if(CountofClusters<4085)
{
/*FAT类型是FAT12*/
return1;
}
elseif(CountofClusters<65525)
{
/*FAT类型是FAT16*/
return2;
}
else
{
/*FAT类型是FAT32*/
return3;
}
}
}

分享到:
评论

相关推荐

    FAT32WinForm

    综上所述,"FAT32WinForm"项目涵盖了C#编程、Windows Forms UI设计、文件系统结构理解、二进制数据解析、用户交互等多个方面的知识。通过这个项目,开发者不仅可以深入理解FAT32文件系统,还能提升在.NET环境中开发...

    C#文件恢复源码

    "Code"文件夹则包含实际的C#源代码,这些代码可能包含了上述的各个功能模块,如硬盘扫描类、文件系统解析类、文件重建类等。 在实际使用过程中,开发者或用户首先需要安装Visual Studio 2013,这是源码所指定的开发...

    使用C#彻底的删除文件.txt

    通过上述C#代码实现的`WipeFile`方法,可以在不同文件系统(如FAT16/32和NTFS)下彻底删除指定文件,确保数据的安全性。这种方法特别适用于需要高度保密的场景,如处理敏感数据或个人隐私信息等。需要注意的是,在...

    嵌入式系统中的完整FAT16和FAT32源码,,可以直接操作IDE设备,不需要其它库.zip

    FAT16和FAT32是两种常见的文件系统格式,广泛应用于各种硬件平台,包括微控制器和嵌入式处理器。这个压缩包提供的是可以直接在嵌入式系统上操作FAT16和FAT32文件系统的C语言源码,无需依赖额外的库,这对于资源有限...

    基于KEIL的STM32读取SD卡,含有FATFS文件系统!.zip

    FATFS库使得STM32能够处理标准的FAT文件系统,从而可以在SD卡上执行文件的创建、读取、写入和删除等操作。 在KEIL集成开发环境中,首先需要配置STM32的硬件连接,确保SD卡接口的GPIO、SPI或SDIO接口正确设置。然后...

    第07章 - 文件系统安全1

    FAT文件系统分为FAT16和FAT32两种。FAT16是一个早期的文件系统,适用于小型磁盘和简单的文件结构,最大卷支持4GB。FAT32则扩展了这一限制,理论上可以支持高达2TB的卷,但每个逻辑驱动器的最大容量至少为127GB,超过...

    操作系统文件及磁盘管理

    2. 文件系统:DriveInfo类还提供了获取磁盘文件系统的功能,如FAT32、NTFS等。 3. 磁盘清理:C#可以通过Directory和File类来删除无用文件,释放磁盘空间。例如,可以查找特定类型的临时文件并删除。 4. 磁盘碎片...

    TSK Map 技术宝典

    TSK标准说明部分详细阐述了TSK支持的各种文件系统格式,如FAT、NTFS、EXT等,并介绍了如何与这些文件系统进行交互。理解这些标准,能帮助用户更好地应对不同操作系统和环境下的数据恢复挑战。 在《TSK Map技术宝典...

    C#笔试题C#笔试题

    7. DOS系统:文件分配表(FAT)记录和管理磁盘数据区的使用情况。 8. 函数依赖与范式:关系R(S,D,M),F={S→D,D→M},根据依赖关系,R至少满足第一范式(1NF),但不足以确定是否满足更高的范式。 9. E-R图转换为...

    从Spring Boot FatJar文件写漏洞的一次实践1

    然而,这种打包方式可能允许攻击者利用某些功能来篡改或写入文件系统,从而造成安全风险。 在Spring Boot中,由于放弃了传统的JSP渲染方式,控制器(Controller)通过注解注入到Spring容器中,使得直接上传的JSP...

    深入windows nt文件系统中文版(一到七章)

    第五章深入解析文件分配和空间管理,包括簇、扇区、卷的概念,以及如何通过FAT(File Allocation Table)和MFT来管理文件的空间分配。这部分会解释文件碎片的产生原因和处理方法。 第六章将探讨NTFS的权限和安全...

    类似windows文件查找功能

    在Windows操作系统中,文件查找功能是一项非常实用的工具,它帮助用户快速定位到电脑上的特定文件或文件夹。这项功能的实现基于一系列的文件系统操作和搜索算法,使得用户能够根据文件名、文件类型、修改日期等条件...

    读Windows文件_扇区数据的源码简洁注译版三

    4. 获取文件分配表(FAT)信息:如果是FAT文件系统,需要查询FAT来确定文件在硬盘上的位置;如果是NTFS,需要查询MFT(主文件表)。 5. 读取扇区:使用DeviceIoControl函数,配合IOCTL_DISK_READ_DATA或ReadFile函数...

    雅虎公司C#笔试题

    “DOS文件系统”通常指的是MS-DOS或Windows早期版本所使用的文件系统(如FAT12/FAT16)。题目可能是要求选择正确的文件系统类型。 #### Question 8 关系数据库规范化是数据库设计中的一个重要概念。根据选项,此题...

    测试c#基础考题测试

    - **文件系统:**DOS使用FAT文件系统,了解文件系统的基本概念,如文件、目录等。 **Question8.** - **选项含义不明,但从题目编号推测可能与数据库规范化有关。** - **知识点:** - **数据库规范化:**数据库...

    CSharp_DOS编译器

    - **文件系统**:DOS的文件系统与现代操作系统也有区别,开发者需要了解FAT文件系统的特性,以便正确地访问和操作文件。 总的来说,CSharp_DOS编译器为开发者提供了一种独特的方式,让他们能够在传统的DOS环境中...

    简单的文件搜索器

    1. 文件系统接口:文件搜索器首先需要与操作系统中的文件系统进行交互,如Windows的NTFS、FAT32或Linux的EXT4等。这通常涉及到文件系统API的调用,例如在Windows中使用FindFirstFile、FindNextFile等函数,在Linux中...

    STM32F103标准例程-V3.5库函数版本,stm32f103库函数手册,C#

    8. ALIENTEK MINISTM32 实验29 FATFS文件系统实验:FATFS是一个通用的文件系统驱动,用于在嵌入式系统上实现FAT格式文件系统的读写。这个实验教你如何在STM32F103上集成并使用FATFS。 9. ALIENTEK MINISTM32 实验22...

    文件及文件夹扫描的简单实现源码

    本文将详细解析"文件及文件夹扫描的简单实现源码"的相关知识点,通过源代码分析,帮助你理解如何在C++或C#等编程语言中实现这一功能。 首先,我们需要了解文件系统的基本概念。在Windows中,文件系统是一种组织磁盘...

Global site tag (gtag.js) - Google Analytics