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 bool Identify(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if (stream.Length < 512) { return(false); } byte[] vHdrB = new byte[Marshal.SizeOf(vHdr)]; stream.Read(vHdrB, 0, Marshal.SizeOf(vHdr)); vHdr = new VdiHeader(); IntPtr headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vHdr)); Marshal.Copy(vHdrB, 0, headerPtr, Marshal.SizeOf(vHdr)); vHdr = (VdiHeader)Marshal.PtrToStructure(headerPtr, typeof(VdiHeader)); Marshal.FreeHGlobal(headerPtr); return(vHdr.magic == VDI_MAGIC); }
public bool Create(string path, MediaType mediaType, Dictionary <string, string> options, ulong sectors, uint sectorSize) { if (sectorSize != 512) { ErrorMessage = "Unsupported sector size"; return(false); } if (!SupportedMediaTypes.Contains(mediaType)) { ErrorMessage = $"Unsupported media format {mediaType}"; return(false); } if ((sectors * sectorSize) / DEFAULT_BLOCK_SIZE > uint.MaxValue) { ErrorMessage = "Too many sectors for selected cluster size"; return(false); } _imageInfo = new ImageInfo { MediaType = mediaType, SectorSize = sectorSize, Sectors = sectors }; try { _writingStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); } catch (IOException e) { ErrorMessage = $"Could not create new image file, exception {e.Message}"; return(false); } uint ibmEntries = (uint)((sectors * sectorSize) / DEFAULT_BLOCK_SIZE); if ((sectors * sectorSize) % DEFAULT_BLOCK_SIZE > 0) { ibmEntries++; } uint headerSectors = 1 + ((ibmEntries * 4) / sectorSize); if ((ibmEntries * 4) % sectorSize != 0) { headerSectors++; } _ibm = new uint[ibmEntries]; _currentWritingPosition = headerSectors * sectorSize; _vHdr = new VdiHeader { creator = DIC_AARU, magic = VDI_MAGIC, majorVersion = 1, minorVersion = 1, headerSize = Marshal.SizeOf <VdiHeader>() - 72, imageType = VdiImageType.Normal, offsetBlocks = sectorSize, offsetData = _currentWritingPosition, sectorSize = sectorSize, size = sectors * sectorSize, blockSize = DEFAULT_BLOCK_SIZE, blocks = ibmEntries, uuid = Guid.NewGuid(), snapshotUuid = Guid.NewGuid() }; for (uint i = 0; i < ibmEntries; i++) { _ibm[i] = VDI_EMPTY; } IsWriting = true; ErrorMessage = null; return(true); }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if (stream.Length < 512) { return(false); } byte[] vHdrB = new byte[Marshal.SizeOf(vHdr)]; stream.Read(vHdrB, 0, Marshal.SizeOf(vHdr)); vHdr = new VdiHeader(); IntPtr headerPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vHdr)); Marshal.Copy(vHdrB, 0, headerPtr, Marshal.SizeOf(vHdr)); vHdr = (VdiHeader)Marshal.PtrToStructure(headerPtr, typeof(VdiHeader)); Marshal.FreeHGlobal(headerPtr); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.creator = {0}", vHdr.creator); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.magic = {0}", vHdr.magic); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.version = {0}.{1}", vHdr.majorVersion, vHdr.minorVersion); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.headerSize = {0}", vHdr.headerSize); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.imageType = {0}", vHdr.imageType); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.imageFlags = {0}", vHdr.imageFlags); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.description = {0}", vHdr.comments); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.offsetBlocks = {0}", vHdr.offsetBlocks); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.offsetData = {0}", vHdr.offsetData); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.cylinders = {0}", vHdr.cylinders); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.heads = {0}", vHdr.heads); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.spt = {0}", vHdr.spt); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.sectorSize = {0}", vHdr.sectorSize); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.size = {0}", vHdr.size); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.blockSize = {0}", vHdr.blockSize); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.blockExtraData = {0}", vHdr.blockExtraData); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.blocks = {0}", vHdr.blocks); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.allocatedBlocks = {0}", vHdr.allocatedBlocks); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.uuid = {0}", vHdr.uuid); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.snapshotUuid = {0}", vHdr.snapshotUuid); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.linkUuid = {0}", vHdr.linkUuid); DicConsole.DebugWriteLine("VirtualBox plugin", "vHdr.parentUuid = {0}", vHdr.parentUuid); if (vHdr.imageType != VdiImageType.Normal) { throw new FeatureSupportedButNotImplementedImageException($"Support for image type {vHdr.imageType} not yet implemented"); } DicConsole.DebugWriteLine("VirtualBox plugin", "Reading Image Block Map"); stream.Seek(vHdr.offsetBlocks, SeekOrigin.Begin); ibm = new uint[vHdr.blocks]; byte[] ibmB = new byte[vHdr.blocks * 4]; stream.Read(ibmB, 0, ibmB.Length); for (int i = 0; i < ibm.Length; i++) { ibm[i] = BitConverter.ToUInt32(ibmB, i * 4); } sectorCache = new Dictionary <ulong, byte[]>(); imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.Sectors = vHdr.size / vHdr.sectorSize; imageInfo.ImageSize = vHdr.size; imageInfo.SectorSize = vHdr.sectorSize; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.MediaType = MediaType.GENERIC_HDD; imageInfo.Comments = vHdr.comments; imageInfo.Version = $"{vHdr.majorVersion}.{vHdr.minorVersion}"; switch (vHdr.creator) { case SUN_VDI: imageInfo.Application = "Sun VirtualBox"; break; case SUN_OLD_VDI: imageInfo.Application = "Sun xVM"; break; case ORACLE_VDI: imageInfo.Application = "Oracle VirtualBox"; break; case QEMUVDI: imageInfo.Application = "QEMU"; break; case INNOTEK_VDI: case INNOTEK_OLD_VDI: imageInfo.Application = "innotek VirtualBox"; break; case DIC_VDI: imageInfo.Application = "DiscImageChef"; break; } imageStream = stream; imageInfo.Cylinders = vHdr.cylinders; imageInfo.Heads = vHdr.heads; imageInfo.SectorsPerTrack = vHdr.spt; return(true); }