public VirtualDiskStream(string vhdPath)
 {
     this.vhdFile      = new VhdFileFactory().Create(vhdPath);
     this.blockFactory = vhdFile.GetBlockFactory();
     footerRange       = this.blockFactory.GetFooterRange();
     fileDataRange     = IndexRange.FromLength(0, this.Length - footerRange.Length);
 }
예제 #2
0
        public IndexRange GetFooterRange()
        {
            long startIndex   = this.vhdFile.DataReader.Size - VhdConstants.VHD_FOOTER_SIZE;
            var  logicalRange = IndexRange.FromLength(startIndex, VhdConstants.VHD_FOOTER_SIZE);

            return(logicalRange);
        }
        public override Block Create(uint block)
        {
            if (!vhdFile.BlockAllocationTable.HasData(block))
            {
                if (cachedBlock == null || cachedBlock.BlockIndex != block)
                {
                    cachedBlock = new Block(this)
                    {
                        BlockIndex   = block,
                        VhdUniqueId  = this.vhdFile.Footer.UniqueId,
                        LogicalRange = IndexRange.FromLength(block * GetBlockSize(), vhdFile.Header.BlockSize),
                        BitMap       = null,
                        Empty        = true
                    };
                }
                return(cachedBlock);
            }

            if (cachedBlock == null || cachedBlock.BlockIndex != block)
            {
                cachedBlock = new Block(this)
                {
                    BlockIndex   = block,
                    VhdUniqueId  = this.vhdFile.Footer.UniqueId,
                    LogicalRange = IndexRange.FromLength(block * GetBlockSize(), vhdFile.Header.BlockSize),
                    BitMap       = bitMapFactory.Create(block),
                    Empty        = false
                };
            }
            return(cachedBlock);
        }
예제 #4
0
        public override Block Create(uint block)
        {
            if (!vhdFile.BlockAllocationTable.HasData(block))
            {
                if (cachedBlock == null || cachedBlock.BlockIndex != block)
                {
                    cachedBlock = parentBlockFactory.Create(block);
                }
                return(cachedBlock);
            }

            if (cachedBlock == null || cachedBlock.BlockIndex != block)
            {
                IndexRange logicalRange = IndexRange.FromLength(block * GetBlockSize(), this.GetBlockSize());
                if (ExtraBlockIndex.HasValue && block == ExtraBlockIndex)
                {
                    long startIndex = block * GetBlockSize();
                    long size       = vhdFile.Footer.CurrentSize - startIndex;
                    logicalRange = IndexRange.FromLength(startIndex, size);
                }
                cachedBlock = new Block(this)
                {
                    BlockIndex   = block,
                    VhdUniqueId  = this.vhdFile.Footer.UniqueId,
                    LogicalRange = logicalRange,
                    BitMap       = bitMapFactory.Create(block),
                    Empty        = false
                };
            }
            return(cachedBlock);
        }
예제 #5
0
        public IEnumerable <IndexRange> GetEmptyRanges()
        {
            var blobRange = new List <IndexRange> {
                IndexRange.FromLength(0, this.Length)
            };

            return(IndexRange.SubstractRanges(blobRange, GetPageRanges()));
        }
        /// <summary>
        /// Reads the specified number of bytes from the current position.
        /// </summary>
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (count <= 0)
            {
                return(0);
            }

            try
            {
                var rangeToRead = IndexRange.FromLength(this.position, count);

                int writtenCount = 0;
                if (fileDataRange.Intersection(rangeToRead) == null)
                {
                    int readCountFromFooter;
                    if (TryReadFromFooter(rangeToRead, buffer, offset, out readCountFromFooter))
                    {
                        writtenCount += readCountFromFooter;
                    }
                    return(writtenCount);
                }

                rangeToRead = fileDataRange.Intersection(rangeToRead);

                var startingBlock = ByteToBlock(rangeToRead.StartIndex);
                var endingBlock   = ByteToBlock(rangeToRead.EndIndex);

                for (var blockIndex = startingBlock; blockIndex <= endingBlock; blockIndex++)
                {
                    var currentBlock       = blockFactory.Create(blockIndex);
                    var rangeToReadInBlock = currentBlock.LogicalRange.Intersection(rangeToRead);

                    var copyStartIndex = rangeToReadInBlock.StartIndex % blockFactory.GetBlockSize();
                    Buffer.BlockCopy(currentBlock.Data, (int)copyStartIndex, buffer, offset + writtenCount, (int)rangeToReadInBlock.Length);

                    writtenCount += (int)rangeToReadInBlock.Length;
                }
                this.position += writtenCount;

                return(writtenCount);
            }
            catch (Exception e)
            {
                throw new VhdParsingException("Invalid or Corrupted VHD file", e);
            }
        }
예제 #7
0
 public Block Create(uint block)
 {
     if (!this.HasData(block))
     {
         if (cachedBlock == null || cachedBlock.BlockIndex != block)
         {
             IndexRange logicalRange = IndexRange.FromLength(block * GetBlockSize(), this.GetBlockSize());
             if (extraBlockIndex.HasValue && block == extraBlockIndex)
             {
                 long startIndex = block * GetBlockSize();
                 long size       = this.vhdFile.DataReader.Size - startIndex - VhdConstants.VHD_FOOTER_SIZE;
                 logicalRange = IndexRange.FromLength(startIndex, size);
             }
             cachedBlock = new Block(this)
             {
                 BlockIndex   = block,
                 VhdUniqueId  = this.vhdFile.Footer.UniqueId,
                 LogicalRange = logicalRange,
                 BitMap       = null,
                 Empty        = true
             };
         }
         return(cachedBlock);
     }
     if (cachedBlock == null || cachedBlock.BlockIndex != block)
     {
         IndexRange logicalRange = IndexRange.FromLength(block * GetBlockSize(), this.GetBlockSize());
         if (extraBlockIndex.HasValue && block == extraBlockIndex)
         {
             long startIndex = block * GetBlockSize();
             long size       = this.vhdFile.DataReader.Size - startIndex - VhdConstants.VHD_FOOTER_SIZE;
             logicalRange = IndexRange.FromLength(startIndex, size);
         }
         cachedBlock = new Block(this)
         {
             BlockIndex   = block,
             VhdUniqueId  = this.vhdFile.Footer.UniqueId,
             LogicalRange = logicalRange,
             Empty        = false
         };
     }
     return(cachedBlock);
 }
예제 #8
0
 public IndexRange GetFooterRange()
 {
     return(IndexRange.FromLength(this.GetBlockSize() * this.BlockCount, VhdConstants.VHD_FOOTER_SIZE));
 }
예제 #9
0
 public IndexRange GetFooterRange()
 {
     return(IndexRange.FromLength(this.vhdFile.Footer.CurrentSize, VhdConstants.VHD_FOOTER_SIZE));
 }