public static MasterBootRecord ParseMBR(byte[] buffer)
        {
            var mbr = new MasterBootRecord();

            //copy raw data bytes
            mbr.RawBytes = new byte[buffer.Length];
            Array.Copy(buffer, mbr.RawBytes, mbr.RawBytes.Length);

            //copy bootcode
            mbr.BootCode = new byte[MasterBootRecord.BootCodeSize];
            Array.Copy(buffer, 0, mbr.BootCode, 0, mbr.BootCode.Length);

            //parse drive serial and protection status
            mbr.DriveSerialNo      = Num.ArrayToHexString(buffer, MasterBootRecord.BootCodeSize, 4);
            mbr.CopyProtectionFlag = Num.ArrayToHexString(buffer, MasterBootRecord.BootCodeSize + 4, 2);

            //copy signature
            mbr.Signature = Num.ArrayToHexString(buffer, 510, 2);

            //parse MBR partition table
            mbr.PartitionTable = new List <MbrPartitionTable>();
            for (int i = 0; i < MasterBootRecord.MaxPartition; i++)
            {
                var pdata = new byte[MbrPartitionTable.Length];
                Array.Copy(buffer, MasterBootRecord.PartitionTableIndex + MbrPartitionTable.Length * i, pdata, 0, pdata.Length);
                var ps = new MbrPartitionTable
                {
                    BootFlag      = Num.ArrayToHexString(pdata, 0, 1),
                    ChsBegin      = Num.ArrayToHexString(pdata, 1, 3),
                    FileSystemMbr = Num.ArrayToInt(pdata, 4, 1),
                    ChsEnd        = Num.ArrayToHexString(pdata, 5, 3),
                    StartSector   = Num.ArrayToInt(pdata, 8, 4),
                    TotalSectors  = Num.ArrayToInt(pdata, 12, 4)
                };

                //file system validity check
                if (ps.FileSystemMbr >= (int)FsTypesMbr.FAT12_CHS &&
                    ps.FileSystemMbr <= (int)FsTypesMbr.Extended_LBA &&
                    ps.StartSector > 0 && ps.TotalSectors > 0)
                {
                    mbr.PartitionTable.Add(ps);
                }
                else if (ps.FileSystemMbr == (int)FsTypesMbr.GptParitionSignature)
                {
                    mbr.PartitionTable.Add(ps);
                }
            }

            return(mbr);
        }
示例#2
0
        public virtual void Open()
        {
            //try to read MBR partition
            UpdateProgress(0);
            var mbrdata = new byte[MasterBootRecord.Length];

            _storageIO.Seek(0);
            _storageIO.ReadBytes(mbrdata, mbrdata.Length);
            Mbr = FileSystemBase.ParseMBR(mbrdata);
            UpdateProgress(10);

            //no MBR, add default partition table
            if (Mbr.PartitionTable.Count == 0)
            {
                Mbr = new MasterBootRecord();
                Mbr.PartitionTable = new List <MbrPartitionTable>();
                Mbr.PartitionTable.Add(new MbrPartitionTable {
                    StartSector = 0
                });
            }

            EventLog("\r\nMBR Found: " + (Mbr.IsSignatureValid ? "Yes" : "No"));
            var count = 0;

            if (Mbr.IsSignatureValid)
            {
                EventLog("MBR Partition Count: " + Mbr.PartitionTable.Count);
                foreach (var item in Mbr.PartitionTable)
                {
                    count++;
                    EventLog(string.Format("{0}. MBR Partition => StartSector: 0x{1:X8}, TotalSector: 0x{2:X8}, FileSystemMbr: 0x{3:X2} -> {4}",
                                           count, item.StartSector, item.TotalSectors, item.FileSystemMbr, (FsTypesMbr)item.FileSystemMbr));
                }
            }

            //read boot sectors
            BootSectors = new List <BootSectorCommon>();
            Partitions  = new List <FileSystemBase>();
            foreach (var pt in Mbr.PartitionTable)
            {
                if (pt.FileSystemMbr == (int)FsTypesMbr.GptParitionSignature)
                {
                    EventLog("Error: GPT Partition Table not supported yet!");
                    break;
                }

                var bsdata = new byte[BootSectorCommon.Length];
                _storageIO.Seek(pt.StartSector * FatConst.BytesPerSectorDefault);
                _storageIO.ReadBytes(bsdata, bsdata.Length);
                var bs = FileSystemBase.ParseBootSector(pt, bsdata);
                bs.PartitionId = BootSectors.Count;
                BootSectors.Add(bs);

                var fs = new FileSystemBase(_storageIO);
                if (bs.FsType == FsType.NTFS)
                {
                    fs = new FileSystemNTFS(_storageIO);
                }
                else if (bs.FsType == FsType.ExFAT)
                {
                    fs = new FileSystemExFAT(_storageIO);
                }
                else if (bs.FsType == FsType.FAT12 || bs.FsType == FsType.FAT16 || bs.FsType == FsType.FAT32)
                {
                    fs = new FileSystemFAT(_storageIO);
                }
                fs.OnEventLog += OnEventLog;
                fs.OnProgress += OnProgress;
                fs.BootSector  = bs;
                Partitions.Add(fs);
            }
            UpdateProgress(40);

            count = 0;
            EventLog("\r\nBootSector Partition Count: " + BootSectors.Count);
            foreach (var bs in BootSectors)
            {
                count++;
                EventLog(string.Format("{0}. BS  Partition => StartSector: 0x{1:X8}, TotalSector: 0x{2:X8}, MediaType: 0x{3:X2}, FileSystem: {4}",
                                       count, bs.MbrPartitionTable.First().StartSector, bs.TotalSectors, bs.MediaType, bs.FsType));
            }
            UpdateProgress(100);
        }