using System; using System.Security.Cryptography; namespace ScreenConnect; public class BlockBufferReadStream : BlockBufferStream { private CursorBuffer danglingUntransformedBuffer; private CursorBuffer danglingTransformedBuffer; private Proc bufferCycler; public bool IsAnyAvailable { get { if (danglingTransformedBuffer.RemainingCount == 0) { return danglingUntransformedBuffer.CompletedCount + base.BufferRemainingCount >= base.BlockSize; } return true; } } protected override ICryptoTransform CreateTransform(byte[] key, byte[] iv) { return Singleton.Instance.CreateDecryptor(key, iv); } protected override void OnBlockSizeChanged() { danglingUntransformedBuffer.CompletedCount.AssertEquals(0); danglingTransformedBuffer.RemainingCount.AssertEquals(0); danglingUntransformedBuffer = CursorBuffer.From(new byte[base.BlockSize]); danglingTransformedBuffer = CursorBuffer.From(new byte[base.BlockSize]); CursorBuffer.ResetToEnd(ref danglingTransformedBuffer); } public void SkipAvailableUntilNonZero() { while (true) { if (danglingTransformedBuffer.RemainingCount != 0) { if (!CursorBuffer.ReadOneIfEquals(ref danglingTransformedBuffer, 0)) { break; } } else if (danglingUntransformedBuffer.CompletedCount == base.BlockSize) { TransformDangling(); } else if (Read(ref danglingUntransformedBuffer) == 0) { break; } } } private void TransformDangling() { CursorBuffer.ResetToBeginning(ref danglingTransformedBuffer); CursorBuffer.ResetToBeginning(ref danglingUntransformedBuffer); CursorBuffer.Transform(ref danglingUntransformedBuffer, ref danglingTransformedBuffer, base.Transform); CursorBuffer.ResetToBeginning(ref danglingTransformedBuffer); CursorBuffer.ResetToBeginning(ref danglingUntransformedBuffer); } public BlockBufferReadStream(Proc bufferCycler) { this.bufferCycler = bufferCycler; } protected override void OnNeedsBufferCycled() { bufferCycler(this); } public bool WaitToRead() { if (IsAnyAvailable) { return true; } return RequestBufferCount(1); } public override int Read(byte[] buffer, int offset, int count) { CursorBuffer destination = CursorBuffer.From(buffer, offset, count); int num; while (true) { if (danglingTransformedBuffer.RemainingCount != 0) { return CursorBuffer.Copy(ref danglingTransformedBuffer, ref destination); } if (danglingUntransformedBuffer.CompletedCount == base.BlockSize) { TransformDangling(); continue; } if (danglingUntransformedBuffer.CompletedCount != 0) { if (!RequestBufferCount(1)) { return 0; } Read(ref danglingUntransformedBuffer); continue; } if (!RequestBufferCount(1)) { return 0; } num = ReadAndTransform(ref destination, base.Transform); if (num != 0) { break; } Read(ref danglingUntransformedBuffer); } return num; } public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } public override void Flush() { throw new NotSupportedException(); } }