public
class
DiskBase
... {
...#region
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
//系统引导记录(兼容FAT16和FAT32)#region //系统引导记录(兼容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;
}
}
}
... {
...#region
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
//系统引导记录(兼容FAT16和FAT32)#region //系统引导记录(兼容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;
}
}
}