示例#1
0
        public new static Fat32BiosParameterBlock?ContinueParsing(BiosParameterBlock bpb, BinaryReader reader)
        {
            var fat32bpb = new Fat32BiosParameterBlock(bpb);

            fat32bpb.ReadFat32BpbFields(reader);
            return(fat32bpb.ReadEbpbFields(reader) ? fat32bpb : null);
        }
示例#2
0
 /// <summary>
 /// Create a new BIOS Parameter Block using data from another BIOS Parameter Block
 /// </summary>
 /// <remarks>Typically used to move between BPB types</remarks>
 /// <param name="bpb">The BPB to use data from</param>
 protected BiosParameterBlock(BiosParameterBlock bpb)
 {
     BootJump = bpb.BootJump;
     OemId    = bpb.OemId;
     BytesPerLogicalSector    = bpb.BytesPerLogicalSector;
     LogicalSectorsPerCluster = bpb.LogicalSectorsPerCluster;
     ReservedLogicalSectors   = bpb.ReservedLogicalSectors;
     NumberOfFATs             = bpb.NumberOfFATs;
     RootDirectoryEntries     = bpb.RootDirectoryEntries;
     TotalLogicalSectors      = bpb.TotalLogicalSectors;
     MediaDescriptor          = bpb.MediaDescriptor;
     LogicalSectorsPerFAT     = bpb.LogicalSectorsPerFAT;
     PhysicalSectorsPerTrack  = bpb.PhysicalSectorsPerTrack;
     NumberOfHeads            = bpb.NumberOfHeads;
     HiddenSectors            = bpb.HiddenSectors;
 }
示例#3
0
        /// <summary>
        /// Parse a BIOS Parameter Block from a stream
        /// </summary>
        /// <param name="reader">A binary reader around the stream</param>
        /// <param name="offset">The offset in the stream of the BPB</param>
        /// <returns>A BIOS Parameter block</returns>
        public static BiosParameterBlock Parse(BinaryReader reader, long offset)
        {
            reader.BaseStream.Seek(offset, SeekOrigin.Begin); //BPB offset

            var bpb = new BiosParameterBlock
            {
                BytesPerLogicalSector    = reader.ReadUInt16(),
                LogicalSectorsPerCluster = reader.ReadByte(),
                ReservedLogicalSectors   = reader.ReadUInt16(),
                NumberOfFATs             = reader.ReadByte(),
                RootDirectoryEntries     = reader.ReadUInt16(),
                TotalLogicalSectors      = reader.ReadUInt16(),
                MediaDescriptor          = reader.ReadByte(),
                LogicalSectorsPerFAT     = reader.ReadUInt16()
            };

            //Parsing a standard BPB
            if (offset == 0x0B)
            {
                bpb.PhysicalSectorsPerTrack = reader.ReadUInt16();
                bpb.NumberOfHeads           = reader.ReadUInt16();

                if (bpb.TotalLogicalSectors != 0)
                {
                    bpb.HiddenSectors = reader.ReadUInt16();
                    reader.BaseStream.Seek(6, SeekOrigin.Current);
                }
                else
                {
                    bpb.HiddenSectors       = reader.ReadUInt32();
                    bpb.TotalLogicalSectors = reader.ReadUInt32();
                }
            }

            //Parsing an Apricot BPB, which doesn't have the number of heads and SPT, so we have to make some manual adjustments
            else if (offset == 0x50)
            {
                if (bpb.MediaDescriptor == 0xFC) //315k
                {
                    bpb.NumberOfHeads           = 1;
                    bpb.PhysicalSectorsPerTrack = 70;
                }
                else if (bpb.MediaDescriptor == 0xFE) //720k
                {
                    bpb.NumberOfHeads           = 2;
                    bpb.PhysicalSectorsPerTrack = 80;
                }
            }

            if (!bpb.Validate())
            {
                throw new InvalidDataException("At least one of BPB parameters is 0");
            }

            uint tracks = (uint)(bpb.TotalLogicalSectors / bpb.NumberOfHeads / bpb.PhysicalSectorsPerTrack);

            // TODO: This probably needs reviewing to better check BPB params match the correct size
            if (tracks == 0)
            {
                throw new InvalidDataException("BPB paramaters don't match image size");
            }

            // Parsing a standard BPB, read boot sector
            if (offset == 0x0B)
            {
                long endOffset = reader.BaseStream.Position;

                reader.BaseStream.Seek(0, SeekOrigin.Begin);
                bpb.BootJump = reader.ReadBytes(3);
                bpb.OemId    = new string(reader.ReadChars(8)).TrimEnd(' ').ToUpper();

                reader.BaseStream.Seek(endOffset, SeekOrigin.Begin);
            }

            if (bpb.LogicalSectorsPerFAT == 0)
            {
                // This could be a FAT32 BPB.
                return(Fat32BiosParameterBlock.ContinueParsing(bpb, reader) ?? throw new InvalidDataException("FAT size is 0"));
            }
            else
            {
                //So far, the BPB seems to be OK, so try to read it further as a DOS 4.0 BPB.
                return(ExtendedBiosParameterBlock.ContinueParsing(bpb, reader) ?? bpb);
            }
        }
示例#4
0
 public Fat32BiosParameterBlock(BiosParameterBlock bpb) : base(bpb)
 {
 }