public static DiskImage Create(DiskImage hdd) { byte[] headBytes = hdd.ReadBytes(hdd.Length - 512, 512); VhdHeader head = Program.ToStructFromBigEndian <VhdHeader>(headBytes); if (head.CookieStr != "conectix") { throw new Exception("missing magic string"); } if (head.FileFormatVersion != 0x00010000) { throw new Exception("upsupported version"); } //TODO: validate checksum if (head.DiskType == DiskType.Fixed) { return(new FixedVhd(hdd, in head)); } else if (head.DiskType == DiskType.Dynamic) { return(new DynamicVhd(hdd, in head)); } else { throw new Exception("Only fixed size VHDs are supported."); } }
void readBlock(Span <byte> array, long blockOffset, int blockStartNdx) { if (blockOffset == -1) { array.Fill(0); } else { mHdd.ReadBytes(array, blockOffset + blockStartNdx); } }
unsafe public VdiDiskImage(DiskImage hdd) : base(hdd) { var headBytes = hdd.ReadBytes(0, sizeof(VdiHeader)); VdiHeader head = Program.ToStruct <VdiHeader>(headBytes); if (head.ImageSig != VdiMagic) { throw new Exception("Wrong magic."); } if (head.Version != VdiVersion) { throw new Exception("Wrong version."); } if (head.SizeOfHeader != VdiHeadSize) { throw new Exception("Wrong size."); } if (head.ImageType != ImageType.Dynamic) { throw new NotImplementedException("Only dynamic is supported."); } var dataOffset = head.OffsetData; mBlockOffsets = new long[head.BlocksInHdd]; mBlockSize = (int)head.BlockSize; for (long i = 0; i < head.BlocksInHdd; i++) { uint blockLoc; hdd.Get <uint>(head.OffsetBlocks + i * 4, out blockLoc); if (blockLoc == ~0u) { mBlockOffsets[i] = -1; } else { mBlockOffsets[i] = dataOffset + blockLoc * mBlockSize; } } }
public override void ReadBytes(Span <byte> dest, long offset) { CheckOffsets(offset, dest.Length); mHdd.ReadBytes(dest, mOffset + offset); }