예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
파일: Write.cs 프로젝트: morefun0302/Aaru
        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);
        }
예제 #4
0
        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);
        }