private void CreateWriterWorkItemForExistingChunk(int writePosition, out ChunkHeader chunkHeader) { var md5 = MD5.Create(); var stream = GetWriteStream(_filename); try { chunkHeader = ReadHeader(stream); if (chunkHeader.Version == (byte)ChunkVersions.Unaligned) { Log.Verbose("Upgrading ongoing file {chunk} to version 3", _filename); var newHeader = new ChunkHeader((byte)ChunkVersions.Aligned, chunkHeader.ChunkSize, chunkHeader.ChunkStartNumber, chunkHeader.ChunkEndNumber, false, chunkHeader.ChunkId); stream.Seek(0, SeekOrigin.Begin); chunkHeader = newHeader; var head = newHeader.AsByteArray(); stream.Write(head, 0, head.Length); stream.Flush(); stream.Seek(0, SeekOrigin.Begin); } } catch { stream.Dispose(); ((IDisposable)md5).Dispose(); throw; } var realPosition = GetRawPosition(writePosition); MD5Hash.ContinuousHashFor(md5, stream, 0, realPosition); stream.Position = realPosition; // this reordering fixes bug in Mono implementation of FileStream _writerWorkItem = new WriterWorkItem(stream, null, md5); }
public void VerifyFileHash() { if (!IsReadOnly) { throw new InvalidOperationException("You can't verify hash of not-completed TFChunk."); } var workItem = GetReaderWorkItem(); try { var footer = ReadFooter(workItem.Stream); byte[] hash; using (var md5 = MD5.Create()) { workItem.Stream.Seek(0, SeekOrigin.Begin); // hash header and data MD5Hash.ContinuousHashFor(md5, workItem.Stream, 0, ChunkHeader.Size + footer.ActualDataSize); // hash mapping and footer except MD5 hash sum which should always be last MD5Hash.ContinuousHashFor(md5, workItem.Stream, ChunkHeader.Size + footer.ActualChunkSize, footer.MapSize + ChunkFooter.Size - ChunkFooter.ChecksumSize); md5.TransformFinalBlock(new byte[0], 0, 0); hash = md5.Hash; } if (footer.MD5Hash == null || footer.MD5Hash.Length != hash.Length) { throw new HashValidationException(); } for (int i = 0; i < hash.Length; ++i) { if (footer.MD5Hash[i] != hash[i]) { throw new HashValidationException(); } } } finally { ReturnReaderWorkItem(workItem); } }
public void VerifyFileHash() { if (!IsReadOnly) { throw new InvalidOperationException("You can't verify hash of not-completed TFChunk."); } Log.Trace("Verifying hash for TFChunk '{0}'...", _filename); #if __MonoCS__ using (var reader = AcquireReader()) { reader.Stream.Seek(0, SeekOrigin.Begin); var stream = reader.Stream; #else using (var reader = UnbufferedFileReadStream.Open(_filename)) { var stream = reader; #endif var footer = _chunkFooter; byte[] hash; using (var md5 = MD5.Create()) { // hash header and data MD5Hash.ContinuousHashFor(md5, stream, 0, ChunkHeader.Size + footer.PhysicalDataSize); // hash mapping and footer except MD5 hash sum which should always be last MD5Hash.ContinuousHashFor(md5, stream, ChunkHeader.Size + footer.PhysicalDataSize, footer.MapSize + ChunkFooter.Size - ChunkFooter.ChecksumSize); md5.TransformFinalBlock(Empty.ByteArray, 0, 0); hash = md5.Hash; } if (footer.MD5Hash == null || footer.MD5Hash.Length != hash.Length) { throw new HashValidationException(); } for (int i = 0; i < hash.Length; ++i) { if (footer.MD5Hash[i] != hash[i]) { throw new HashValidationException(); } } } }
private void CreateWriterWorkItemForExistingChunk(int writePosition, out ChunkHeader chunkHeader) { var md5 = MD5.Create(); var stream = new FileStream(_filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, WriteBufferSize, FileOptions.SequentialScan); try { chunkHeader = ReadHeader(stream); } catch { stream.Dispose(); ((IDisposable)md5).Dispose(); throw; } var realPosition = GetRawPosition(writePosition); MD5Hash.ContinuousHashFor(md5, stream, 0, realPosition); stream.Position = realPosition; // this reordering fixes bug in Mono implementation of FileStream _writerWorkItem = new WriterWorkItem(stream, null, md5); }
private void CreateWriterWorkItemForExistingChunk(int writePosition, out ChunkHeader chunkHeader) { var md5 = MD5.Create(); var stream = new FileStream(_filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, WriteBufferSize, FileOptions.SequentialScan); var writer = new BinaryWriter(stream); try { chunkHeader = ReadHeader(stream); } catch { stream.Dispose(); ((IDisposable)md5).Dispose(); throw; } var realPosition = GetRealPosition(writePosition, inMemory: false); stream.Position = realPosition; MD5Hash.ContinuousHashFor(md5, stream, 0, realPosition); _writerWorkItem = new WriterWorkItem(stream, writer, md5); }