/// <summary> /// Creates a new stream that contains the XVA image. /// </summary> /// <returns>The new stream</returns> public override SparseStream Build() { TarFileBuilder tarBuilder = new TarFileBuilder(); int[] diskIds; string ovaFileContent = GenerateOvaXml(out diskIds); tarBuilder.AddFile("ova.xml", Encoding.ASCII.GetBytes(ovaFileContent)); int diskIdx = 0; foreach (var diskRec in _disks) { SparseStream diskStream = diskRec.Second; List <StreamExtent> extents = new List <StreamExtent>(diskStream.Extents); int lastChunkAdded = -1; foreach (StreamExtent extent in extents) { int firstChunk = (int)(extent.Start / Sizes.OneMiB); int lastChunk = (int)((extent.Start + extent.Length - 1) / Sizes.OneMiB); for (int i = firstChunk; i <= lastChunk; ++i) { if (i != lastChunkAdded) { HashAlgorithm hashAlg = new SHA1Managed(); Stream chunkStream; long diskBytesLeft = diskStream.Length - (i * Sizes.OneMiB); if (diskBytesLeft < Sizes.OneMiB) { chunkStream = new ConcatStream( Ownership.Dispose, new SubStream(diskStream, i * Sizes.OneMiB, diskBytesLeft), new ZeroStream(Sizes.OneMiB - diskBytesLeft)); } else { chunkStream = new SubStream(diskStream, i * Sizes.OneMiB, Sizes.OneMiB); } HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], i), chunkHashStream); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], i), new ChecksumStream(hashAlg)); lastChunkAdded = i; } } } // Make sure the last chunk is present, filled with zero's if necessary int lastActualChunk = (int)((diskStream.Length - 1) / Sizes.OneMiB); if (lastChunkAdded < lastActualChunk) { HashAlgorithm hashAlg = new SHA1Managed(); Stream chunkStream = new ZeroStream(Sizes.OneMiB); HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], lastActualChunk), chunkHashStream); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], lastActualChunk), new ChecksumStream(hashAlg)); } ++diskIdx; } return(tarBuilder.Build()); }
/// <summary> /// Creates a new stream that contains the XVA image. /// </summary> /// <returns>The new stream.</returns> public override SparseStream Build() { TarFileBuilder tarBuilder = new TarFileBuilder(); int[] diskIds; string ovaFileContent = GenerateOvaXml(out diskIds); tarBuilder.AddFile("ova.xml", Encoding.ASCII.GetBytes(ovaFileContent)); int diskIdx = 0; foreach (DiskRecord diskRec in _disks) { SparseStream diskStream = diskRec.Item2; List <StreamExtent> extents = new List <StreamExtent>(diskStream.Extents); int lastChunkAdded = -1; foreach (StreamExtent extent in extents) { int firstChunk = (int)(extent.Start / Sizes.OneMiB); int lastChunk = (int)((extent.Start + extent.Length - 1) / Sizes.OneMiB); for (int i = firstChunk; i <= lastChunk; ++i) { if (i != lastChunkAdded) { Stream chunkStream; long diskBytesLeft = diskStream.Length - i * Sizes.OneMiB; if (diskBytesLeft < Sizes.OneMiB) { chunkStream = new ConcatStream( Ownership.Dispose, new SubStream(diskStream, i * Sizes.OneMiB, diskBytesLeft), new ZeroStream(Sizes.OneMiB - diskBytesLeft)); } else { chunkStream = new SubStream(diskStream, i * Sizes.OneMiB, Sizes.OneMiB); } Stream chunkHashStream; #if NETCORE IncrementalHash hashAlgCore = IncrementalHash.CreateHash(HashAlgorithmName.SHA1); chunkHashStream = new HashStreamCore(chunkStream, Ownership.Dispose, hashAlgCore); #else HashAlgorithm hashAlgDotnet = new SHA1Managed(); chunkHashStream = new HashStreamDotnet(chunkStream, Ownership.Dispose, hashAlgDotnet); #endif tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], i), chunkHashStream); byte[] hash; #if NETCORE hash = hashAlgCore.GetHashAndReset(); #else hashAlgDotnet.TransformFinalBlock(new byte[0], 0, 0); hash = hashAlgDotnet.Hash; #endif string hashString = BitConverter.ToString(hash).Replace("-", "").ToLower(); byte[] hashStringAscii = Encoding.ASCII.GetBytes(hashString); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], i), hashStringAscii); lastChunkAdded = i; } } } // Make sure the last chunk is present, filled with zero's if necessary int lastActualChunk = (int)((diskStream.Length - 1) / Sizes.OneMiB); if (lastChunkAdded < lastActualChunk) { Stream chunkStream = new ZeroStream(Sizes.OneMiB); Stream chunkHashStream; #if NETCORE IncrementalHash hashAlgCore = IncrementalHash.CreateHash(HashAlgorithmName.SHA1); chunkHashStream = new HashStreamCore(chunkStream, Ownership.Dispose, hashAlgCore); #else HashAlgorithm hashAlgDotnet = new SHA1Managed(); chunkHashStream = new HashStreamDotnet(chunkStream, Ownership.Dispose, hashAlgDotnet); #endif tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], lastActualChunk), chunkHashStream); byte[] hash; #if NETCORE hash = hashAlgCore.GetHashAndReset(); #else hashAlgDotnet.TransformFinalBlock(new byte[0], 0, 0); hash = hashAlgDotnet.Hash; #endif string hashString = BitConverter.ToString(hash).Replace("-", "").ToLower(); byte[] hashStringAscii = Encoding.ASCII.GetBytes(hashString); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], lastActualChunk), hashStringAscii); } ++diskIdx; } return(tarBuilder.Build()); }
/// <summary> /// Creates a new stream that contains the XVA image. /// </summary> /// <returns>The new stream</returns> public override SparseStream Build() { TarFileBuilder tarBuilder = new TarFileBuilder(); int[] diskIds; string ovaFileContent = GenerateOvaXml(out diskIds); tarBuilder.AddFile("ova.xml", Encoding.ASCII.GetBytes(ovaFileContent)); int diskIdx = 0; foreach (var diskRec in _disks) { SparseStream diskStream = diskRec.Second; List<StreamExtent> extents = new List<StreamExtent>(diskStream.Extents); int lastChunkAdded = -1; foreach (StreamExtent extent in extents) { int firstChunk = (int)(extent.Start / Sizes.OneMiB); int lastChunk = (int)((extent.Start + extent.Length - 1) / Sizes.OneMiB); for (int i = firstChunk; i <= lastChunk; ++i) { if (i != lastChunkAdded) { HashAlgorithm hashAlg = new SHA1Managed(); Stream chunkStream; long diskBytesLeft = diskStream.Length - i * Sizes.OneMiB; if(diskBytesLeft < Sizes.OneMiB) { chunkStream = new ConcatStream( Ownership.Dispose, new SubStream(diskStream, i * Sizes.OneMiB, diskBytesLeft), new ZeroStream(Sizes.OneMiB - diskBytesLeft)); } else { chunkStream = new SubStream(diskStream, i * Sizes.OneMiB, Sizes.OneMiB); } HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:X8}", diskIds[diskIdx], i), chunkHashStream); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:X8}.checksum", diskIds[diskIdx], i), new ChecksumStream(hashAlg)); lastChunkAdded = i; } } } // Make sure the last chunk is present, filled with zero's if necessary int lastActualChunk = (int)((diskStream.Length - 1) / Sizes.OneMiB); if (lastChunkAdded < lastActualChunk) { HashAlgorithm hashAlg = new SHA1Managed(); Stream chunkStream = new ZeroStream(Sizes.OneMiB); HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:X8}", diskIds[diskIdx], lastActualChunk), chunkHashStream); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:X8}.checksum", diskIds[diskIdx], lastActualChunk), new ChecksumStream(hashAlg)); } ++diskIdx; } return tarBuilder.Build(); }