public int Read(FileVersion version, byte[] buffer, int offset) { if (version.Major == 0) { ImageType = (ImageType)Utilities.ToUInt32LittleEndian(buffer, offset + 0); Flags = (ImageFlags)Utilities.ToUInt32LittleEndian(buffer, offset + 4); Comment = Utilities.BytesToString(buffer, offset + 8, 256).TrimEnd(new char[] { '\0' }); LegacyGeometry = new GeometryRecord(); LegacyGeometry.Read(buffer, offset + 264); DiskSize = Utilities.ToInt64LittleEndian(buffer, offset + 280); BlockSize = Utilities.ToInt32LittleEndian(buffer, offset + 288); BlockCount = Utilities.ToInt32LittleEndian(buffer, offset + 292); BlocksAllocated = Utilities.ToInt32LittleEndian(buffer, offset + 296); UniqueId = Utilities.ToGuidLittleEndian(buffer, offset + 300); ModificationId = Utilities.ToGuidLittleEndian(buffer, offset + 316); ParentId = Utilities.ToGuidLittleEndian(buffer, offset + 332); HeaderSize = 348; BlocksOffset = HeaderSize + PreHeaderRecord.Size; DataOffset = (uint)(BlocksOffset + (BlockCount * 4)); BlockExtraSize = 0; ParentModificationId = Guid.Empty; } else if (version.Major == 1 && version.Minor == 1) { HeaderSize = Utilities.ToUInt32LittleEndian(buffer, offset + 0); ImageType = (ImageType)Utilities.ToUInt32LittleEndian(buffer, offset + 4); Flags = (ImageFlags)Utilities.ToUInt32LittleEndian(buffer, offset + 8); Comment = Utilities.BytesToString(buffer, offset + 12, 256).TrimEnd(new char[] { '\0' }); BlocksOffset = Utilities.ToUInt32LittleEndian(buffer, offset + 268); DataOffset = Utilities.ToUInt32LittleEndian(buffer, offset + 272); LegacyGeometry = new GeometryRecord(); LegacyGeometry.Read(buffer, offset + 276); DiskSize = Utilities.ToInt64LittleEndian(buffer, offset + 296); BlockSize = Utilities.ToInt32LittleEndian(buffer, offset + 304); BlockExtraSize = Utilities.ToInt32LittleEndian(buffer, offset + 308); BlockCount = Utilities.ToInt32LittleEndian(buffer, offset + 312); BlocksAllocated = Utilities.ToInt32LittleEndian(buffer, offset + 316); UniqueId = Utilities.ToGuidLittleEndian(buffer, offset + 320); ModificationId = Utilities.ToGuidLittleEndian(buffer, offset + 336); ParentId = Utilities.ToGuidLittleEndian(buffer, offset + 352); ParentModificationId = Utilities.ToGuidLittleEndian(buffer, offset + 368); if (HeaderSize > 384) { LChsGeometry = new GeometryRecord(); LChsGeometry.Read(buffer, offset + 384); } } else { throw new IOException("Unrecognized file version: " + version); } return((int)HeaderSize); }
internal static VirtualDiskTypeInfo MakeDiskTypeInfo(string variant) { return(new VirtualDiskTypeInfo() { Name = "VDI", Variant = variant, CanBeHardDisk = true, DeterministicGeometry = true, PreservesBiosGeometry = true, CalcGeometry = c => GeometryRecord.FromCapacity(c).ToGeometry(c), }); }
public static GeometryRecord FromCapacity(long capacity) { GeometryRecord result = new GeometryRecord(); long totalSectors = capacity / 512; if (totalSectors / (16 * 63) <= 1024) { result.Cylinders = (int)Math.Max(totalSectors / (16 * 63), 1); result.Heads = 16; } else if (totalSectors / (32 * 63) <= 1024) { result.Cylinders = (int)Math.Max(totalSectors / (32 * 63), 1); result.Heads = 32; } else if (totalSectors / (64 * 63) <= 1024) { result.Cylinders = (int)(totalSectors / (64 * 63)); result.Heads = 64; } else if (totalSectors / (128 * 63) <= 1024) { result.Cylinders = (int)(totalSectors / (128 * 63)); result.Heads = 128; } else { result.Cylinders = (int)Math.Min(totalSectors / (255 * 63), 1024); result.Heads = 255; } result.Sectors = 63; return(result); }