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