下图是用文件浏览器查看的结果。
磁盘系统的MDR和DBR信息如下。
为了便于后来者,把主要的结构声明代码罗列如下,希望有借鉴意义。
//
基本类 [叶帆工作室]
http://blog.csdn.net/yefanqiu/
public class DiskBase
{
#region // MBR http://blog.csdn.net/yefanqiu/
public struct PartitionTable
{
public byte BootFlag; // 分区活动标志 只能选00H和80H。80H为活动,00H为非活动
public CHS StartCHS; // 分区开始的柱面、磁头、扇区
public byte SystemID; // 分区类型 01 FAT32 04 FAT16<32M 06 FAT16 07 HPFS/NTFS 05 0F 扩展分区
public CHS EndCHS; // 分区结束的柱面、磁头、扇区
public UInt32 RelativeSectors; // 分区起始扇区数,指分区相对于记录该分区的分区表的扇区位置之差 (该分区表:LBA=0x0)。
public UInt32 TotalSectors; // 分区总扇区数
}
public struct CHS
{
public byte Head; // 磁头
public byte Sector; // 扇区 六位
public UInt16 Cylinder; // 柱面 十位
}
public struct MBR
{
public byte [] bytBootCode; // ofs:0.引导代码446字节 "FA 33 C0 8E D0 BC…"
public PartitionTable[] PT; // ofs:446.64个字节 分区表 length=4*16
public UInt16 EndingFlag; // ofs:510.结束标识:0xAA55。
public MBR( byte [] bytData)
{
int i;
bytBootCode = new byte [ 446 ];
for (i = 0 ; i < 446 ; i ++ ) bytBootCode[i] = bytData[i];
PT = new PartitionTable[ 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 // DBR http://blog.csdn.net/yefanqiu/
// 系统引导记录(兼容FAT16和FAT32)
public struct DBR
{
public byte [] BS_JmpBoot; // ofs:0.典型的如:0xEB,0x3E,0x90。
public byte [] BS_OEMName; // ofs:3.典型的如:“MSWIN4.1”。
public UInt16 BPB_BytsPerSec; // ofs:11.每扇区字节数。
public byte BPB_SecPerClus; // ofs:13.每簇扇区数。
public UInt16 BPB_RsvdSecCnt; // ofs:14.保留扇区数,从 DBR到 FAT的扇区数。
public byte BPB_NumFATs; // ofs:16.FAT的个数。
public UInt16 BPB_RootEntCnt; // ofs:17.根目录项数。
public UInt16 BPB_TotSec16; // ofs:19.分区总扇区数(<32M时用)。
public byte BPB_Media; // ofs:21.分区介质标识,优盘一般用 0xF8。
public UInt16 BPB_FATSz16; // ofs:22.每个 FAT占的扇区数。
public UInt16 BPB_SecPerTrk; // ofs:24.每道扇区数。
public UInt16 BPB_NumHeads; // ofs:26.磁头数。
public UInt32 BPB_HiddSec; // ofs:28.隐藏扇区数,从 MBR到 DBR的扇区数。
public UInt32 BPB_TotSec32; // ofs:32.分区总扇区数(>=32M时用)。
// ---------------------
// FAT32特有
public UInt32 BPB_FATSz32; // ofs:36.每个 FAT占的扇区数。
public UInt16 BPB_ExtFlags; // ofs:40.FAT标志
public UInt16 BPB_FSVer; // ofs:42.版本号 高字节主版本 低字节次版本号
public UInt32 BPB_RootClus; // ofs:44.根目录所在第一个簇的簇号,通常该数值为2,但不是必须为2。
public UInt16 BPB_FSInfo; // ofs:48.保留区中FAT32 卷FSINFO 结构所占的扇区数,通常为1。
public UInt16 BPB_BkBootSec; // ofs:50.如果不为0,表示在保留区中引导记录的备份数据所占的扇区数,通常为6。同时不建议使用6 以外的其他数值。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12 )]
public byte [] BPB_Reserved; // ofs:52.备用
// ---------------------
public byte BS_drvNum; // ofs:64/36.软盘使用 0x00,硬盘使用 0x80。
public byte BS_Reserved1; // ofs:65/37.保留。
public byte BS_BootSig; // ofs:66/38.扩展引导标记:0x29。
public byte [] BS_VolID; // ofs:67/39.盘序列号。
public byte [] BS_VolLab; // ofs:71/43.“Msdos ”。
public byte [] BS_FilSysType; // ofs:82/54.“FAT32 ”。
public byte [] ExecutableCode; // ofs:90/62.引导代码。
public UInt16 EndingFlag; // ofs:510.结束标识:0xAA55。
// ---------------------
// 0-未知 1-FAT12 2-FAT16 3-FAT32 其它值为未知
public byte FATType;
// 获取信息
public DBR( byte [] bytData)
{
FATType = IsType(bytData);
int i;
BS_JmpBoot = new byte [ 3 ];
for (i = 0 ; i < 2 ; i ++ ) BS_JmpBoot[i] = bytData[i];
BS_OEMName = new byte [ 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 = new byte [ 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 = new byte [ 4 ];
for (i = 0 ; i < 4 ; i ++ ) BS_VolID[i] = bytData[ 67 + i];
BS_VolLab = new byte [ 11 ];
for (i = 0 ; i < 11 ; i ++ ) BS_VolLab[i] = bytData[ 71 + i];
BS_FilSysType = new byte [ 8 ];
for (i = 0 ; i < 8 ; i ++ ) BS_FilSysType[i] = bytData[ 82 + i];
ExecutableCode = new byte [ 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 = new byte [ 4 ];
for (i = 0 ; i < 4 ; i ++ ) BS_VolID[i] = bytData[ 39 + i];
BS_VolLab = new byte [ 11 ];
for (i = 0 ; i < 11 ; i ++ ) BS_VolLab[i] = bytData[ 43 + i];
BS_FilSysType = new byte [ 8 ];
for (i = 0 ; i < 8 ; i ++ ) BS_FilSysType[i] = bytData[ 54 + i];
ExecutableCode = new byte [ 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 = new byte [ 12 ];
}
// ----------
EndingFlag = (UInt16)(bytData[ 510 ] << 8 | bytData[ 511 ]);
}
#endregion
// 文件系统判断(采用微软的判断方法)
public static byte IsType( byte [] bytData)
{
// 不是合法BPB扇区数据
if (bytData[ 510 ] != 0x55 || bytData[ 511 ] != 0xaa ) return 0 ;
// 跳转指令不合法
if (bytData[ 0 ] != 0xeb && bytData[ 0 ] != 0xe9 ) return 0 ;
// 每扇区包含的字节数(一般为512个字节)
UInt16 BPB_BytsPerSec = (UInt16)(bytData[ 12 ] << 8 | bytData[ 11 ]);
// 仅处理512个字节的扇区
if (BPB_BytsPerSec != 512 ) return 0 ;
// 每簇扇区数
byte BPB_SecPerClus = bytData[ 13 ];
// 保留扇区数
UInt16 BPB_RsvdSecCnt = (UInt16)(bytData[ 15 ] << 8 | bytData[ 14 ]);
// FAT表的个数
byte BPB_NumFATs = bytData[ 16 ];
// FAT表的个数必须为2
if (BPB_NumFATs != 2 ) return 0 ;
// 根目录项数(32字节为单位)
UInt16 BPB_RootEntCnt = (UInt16)(bytData[ 18 ] << 8 | bytData[ 17 ]);
// 分区总扇区数(<32M时用)
UInt16 BPB_TotSec16 = (UInt16)(bytData[ 20 ] << 8 | bytData[ 19 ]);
// 每个FAT占的扇区数
UInt16 BPB_FATSz16 = (UInt16)(bytData[ 23 ] << 8 | bytData[ 22 ]);
// 分区总扇区数(>=32M时用)
UInt32 BPB_TotSec32 = (UInt32)(bytData[ 35 ] << 24 | bytData[ 34 ] << 16 | bytData[ 33 ] << 8 | bytData[ 32 ]);
// 每个FAT占的扇区数(FAT32)
UInt32 BPB_FATSz32 = (UInt32)(bytData[ 39 ] << 24 | bytData[ 38 ] << 16 | bytData[ 37 ] << 8 | bytData[ 36 ]);
UInt64 FATSz = 0 , TotSec = 0 , DataSec = 0 ;
UInt64 RootDirSectors = (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);
UInt64 CountofClusters = DataSec / BPB_SecPerClus;
if (CountofClusters < 4085 )
{
/* FAT 类型是FAT12 */
return 1 ;
}
else if (CountofClusters < 65525 )
{
/* FAT 类型是FAT16 */
return 2 ;
}
else
{
/* FAT 类型是FAT32 */
return 3 ;
}
}
}
public class DiskBase
{
#region // MBR http://blog.csdn.net/yefanqiu/
public struct PartitionTable
{
public byte BootFlag; // 分区活动标志 只能选00H和80H。80H为活动,00H为非活动
public CHS StartCHS; // 分区开始的柱面、磁头、扇区
public byte SystemID; // 分区类型 01 FAT32 04 FAT16<32M 06 FAT16 07 HPFS/NTFS 05 0F 扩展分区
public CHS EndCHS; // 分区结束的柱面、磁头、扇区
public UInt32 RelativeSectors; // 分区起始扇区数,指分区相对于记录该分区的分区表的扇区位置之差 (该分区表:LBA=0x0)。
public UInt32 TotalSectors; // 分区总扇区数
}
public struct CHS
{
public byte Head; // 磁头
public byte Sector; // 扇区 六位
public UInt16 Cylinder; // 柱面 十位
}
public struct MBR
{
public byte [] bytBootCode; // ofs:0.引导代码446字节 "FA 33 C0 8E D0 BC…"
public PartitionTable[] PT; // ofs:446.64个字节 分区表 length=4*16
public UInt16 EndingFlag; // ofs:510.结束标识:0xAA55。
public MBR( byte [] bytData)
{
int i;
bytBootCode = new byte [ 446 ];
for (i = 0 ; i < 446 ; i ++ ) bytBootCode[i] = bytData[i];
PT = new PartitionTable[ 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 // DBR http://blog.csdn.net/yefanqiu/
// 系统引导记录(兼容FAT16和FAT32)
public struct DBR
{
public byte [] BS_JmpBoot; // ofs:0.典型的如:0xEB,0x3E,0x90。
public byte [] BS_OEMName; // ofs:3.典型的如:“MSWIN4.1”。
public UInt16 BPB_BytsPerSec; // ofs:11.每扇区字节数。
public byte BPB_SecPerClus; // ofs:13.每簇扇区数。
public UInt16 BPB_RsvdSecCnt; // ofs:14.保留扇区数,从 DBR到 FAT的扇区数。
public byte BPB_NumFATs; // ofs:16.FAT的个数。
public UInt16 BPB_RootEntCnt; // ofs:17.根目录项数。
public UInt16 BPB_TotSec16; // ofs:19.分区总扇区数(<32M时用)。
public byte BPB_Media; // ofs:21.分区介质标识,优盘一般用 0xF8。
public UInt16 BPB_FATSz16; // ofs:22.每个 FAT占的扇区数。
public UInt16 BPB_SecPerTrk; // ofs:24.每道扇区数。
public UInt16 BPB_NumHeads; // ofs:26.磁头数。
public UInt32 BPB_HiddSec; // ofs:28.隐藏扇区数,从 MBR到 DBR的扇区数。
public UInt32 BPB_TotSec32; // ofs:32.分区总扇区数(>=32M时用)。
// ---------------------
// FAT32特有
public UInt32 BPB_FATSz32; // ofs:36.每个 FAT占的扇区数。
public UInt16 BPB_ExtFlags; // ofs:40.FAT标志
public UInt16 BPB_FSVer; // ofs:42.版本号 高字节主版本 低字节次版本号
public UInt32 BPB_RootClus; // ofs:44.根目录所在第一个簇的簇号,通常该数值为2,但不是必须为2。
public UInt16 BPB_FSInfo; // ofs:48.保留区中FAT32 卷FSINFO 结构所占的扇区数,通常为1。
public UInt16 BPB_BkBootSec; // ofs:50.如果不为0,表示在保留区中引导记录的备份数据所占的扇区数,通常为6。同时不建议使用6 以外的其他数值。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12 )]
public byte [] BPB_Reserved; // ofs:52.备用
// ---------------------
public byte BS_drvNum; // ofs:64/36.软盘使用 0x00,硬盘使用 0x80。
public byte BS_Reserved1; // ofs:65/37.保留。
public byte BS_BootSig; // ofs:66/38.扩展引导标记:0x29。
public byte [] BS_VolID; // ofs:67/39.盘序列号。
public byte [] BS_VolLab; // ofs:71/43.“Msdos ”。
public byte [] BS_FilSysType; // ofs:82/54.“FAT32 ”。
public byte [] ExecutableCode; // ofs:90/62.引导代码。
public UInt16 EndingFlag; // ofs:510.结束标识:0xAA55。
// ---------------------
// 0-未知 1-FAT12 2-FAT16 3-FAT32 其它值为未知
public byte FATType;
// 获取信息
public DBR( byte [] bytData)
{
FATType = IsType(bytData);
int i;
BS_JmpBoot = new byte [ 3 ];
for (i = 0 ; i < 2 ; i ++ ) BS_JmpBoot[i] = bytData[i];
BS_OEMName = new byte [ 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 = new byte [ 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 = new byte [ 4 ];
for (i = 0 ; i < 4 ; i ++ ) BS_VolID[i] = bytData[ 67 + i];
BS_VolLab = new byte [ 11 ];
for (i = 0 ; i < 11 ; i ++ ) BS_VolLab[i] = bytData[ 71 + i];
BS_FilSysType = new byte [ 8 ];
for (i = 0 ; i < 8 ; i ++ ) BS_FilSysType[i] = bytData[ 82 + i];
ExecutableCode = new byte [ 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 = new byte [ 4 ];
for (i = 0 ; i < 4 ; i ++ ) BS_VolID[i] = bytData[ 39 + i];
BS_VolLab = new byte [ 11 ];
for (i = 0 ; i < 11 ; i ++ ) BS_VolLab[i] = bytData[ 43 + i];
BS_FilSysType = new byte [ 8 ];
for (i = 0 ; i < 8 ; i ++ ) BS_FilSysType[i] = bytData[ 54 + i];
ExecutableCode = new byte [ 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 = new byte [ 12 ];
}
// ----------
EndingFlag = (UInt16)(bytData[ 510 ] << 8 | bytData[ 511 ]);
}
#endregion
// 文件系统判断(采用微软的判断方法)
public static byte IsType( byte [] bytData)
{
// 不是合法BPB扇区数据
if (bytData[ 510 ] != 0x55 || bytData[ 511 ] != 0xaa ) return 0 ;
// 跳转指令不合法
if (bytData[ 0 ] != 0xeb && bytData[ 0 ] != 0xe9 ) return 0 ;
// 每扇区包含的字节数(一般为512个字节)
UInt16 BPB_BytsPerSec = (UInt16)(bytData[ 12 ] << 8 | bytData[ 11 ]);
// 仅处理512个字节的扇区
if (BPB_BytsPerSec != 512 ) return 0 ;
// 每簇扇区数
byte BPB_SecPerClus = bytData[ 13 ];
// 保留扇区数
UInt16 BPB_RsvdSecCnt = (UInt16)(bytData[ 15 ] << 8 | bytData[ 14 ]);
// FAT表的个数
byte BPB_NumFATs = bytData[ 16 ];
// FAT表的个数必须为2
if (BPB_NumFATs != 2 ) return 0 ;
// 根目录项数(32字节为单位)
UInt16 BPB_RootEntCnt = (UInt16)(bytData[ 18 ] << 8 | bytData[ 17 ]);
// 分区总扇区数(<32M时用)
UInt16 BPB_TotSec16 = (UInt16)(bytData[ 20 ] << 8 | bytData[ 19 ]);
// 每个FAT占的扇区数
UInt16 BPB_FATSz16 = (UInt16)(bytData[ 23 ] << 8 | bytData[ 22 ]);
// 分区总扇区数(>=32M时用)
UInt32 BPB_TotSec32 = (UInt32)(bytData[ 35 ] << 24 | bytData[ 34 ] << 16 | bytData[ 33 ] << 8 | bytData[ 32 ]);
// 每个FAT占的扇区数(FAT32)
UInt32 BPB_FATSz32 = (UInt32)(bytData[ 39 ] << 24 | bytData[ 38 ] << 16 | bytData[ 37 ] << 8 | bytData[ 36 ]);
UInt64 FATSz = 0 , TotSec = 0 , DataSec = 0 ;
UInt64 RootDirSectors = (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);
UInt64 CountofClusters = DataSec / BPB_SecPerClus;
if (CountofClusters < 4085 )
{
/* FAT 类型是FAT12 */
return 1 ;
}
else if (CountofClusters < 65525 )
{
/* FAT 类型是FAT16 */
return 2 ;
}
else
{
/* FAT 类型是FAT32 */
return 3 ;
}
}
}