예제 #1
0
        public async Task <TcpMessage> Receive(CancellationToken token = default(CancellationToken))
        {
            var packetLengthBytes = new byte[4];

            if (await _stream.ReadAsync(packetLengthBytes, 0, 4, token).ConfigureAwait(false) != 4)
            {
                throw new InvalidOperationException("Couldn't read the packet length");
            }

            int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

            var seqBytes = new byte[4];

            if (await _stream.ReadAsync(seqBytes, 0, 4, token).ConfigureAwait(false) != 4)
            {
                throw new InvalidOperationException("Couldn't read the sequence");
            }

            int seq = BitConverter.ToInt32(seqBytes, 0);

            int readBytes    = 0;
            var body         = new byte[packetLength - 12];
            int neededToRead = packetLength - 12;

            do
            {
                var bodyByte       = new byte[packetLength - 12];
                var availableBytes = await _stream.ReadAsync(bodyByte, 0, neededToRead, token).ConfigureAwait(false);

                neededToRead -= availableBytes;
                Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
                readBytes += availableBytes;
            }while (readBytes != packetLength - 12);

            var crcBytes = new byte[4];

            if (await _stream.ReadAsync(crcBytes, 0, 4, token).ConfigureAwait(false) != 4)
            {
                throw new InvalidOperationException("Couldn't read the crc");
            }

            int checksum = BitConverter.ToInt32(crcBytes, 0);

            byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];

            Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
            Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
            Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
            var crc32 = new Ionic.Crc.CRC32();

            crc32.SlurpBlock(rv, 0, rv.Length);
            var validChecksum = crc32.Crc32Result;

            if (checksum != validChecksum)
            {
                throw new InvalidOperationException("invalid checksum! skip");
            }

            return(new TcpMessage(seq, body));
        }
예제 #2
0
        private bool NameCRCEquals(Int32 NameCRC)
        {
            var mstr = new MemoryStream(_FileNameBytes, false);
            var crc  = new Ionic.Crc.CRC32();

            return(NameCRC == crc.GetCrc32(mstr));
        }
        public void Reset(Stream stream)
        {
            TraceOutput(TraceBits.Session, "-------------------------------------------------------");
            TraceOutput(TraceBits.Session, "Reset {0:X8} firstDone({1})", this.GetHashCode(), _firstWriteDone);

            if (!_firstWriteDone)
            {
                return;
            }

            // reset all status
            _toWrite.Clear();
            _toFill.Clear();
            foreach (var workitem in _pool)
            {
                _toFill.Enqueue(workitem.index);
                workitem.ordinal = -1;
            }

            _firstWriteDone      = false;
            _totalBytesProcessed = 0L;
            _runningCrc          = new Ionic.Crc.CRC32();
            _isClosed            = false;
            _currentlyFilling    = -1;
            _lastFilled          = -1;
            _lastWritten         = -1;
            _latestCompressed    = -1;
            _outStream           = stream;
        }
예제 #4
0
 private static Int32 GetCrc(string fname)
 {
     using (var fs1 = File.OpenRead(fname))
     {
         var checker = new Ionic.Crc.CRC32(true);
         return(checker.GetCrc32(fs1));
     }
 }
예제 #5
0
        public async Task <TcpMessage> Receieve()
        {
            // packet length
            var packetLengthBytes = new byte[4];

            if (!await ReadBuffer(stream, packetLengthBytes))
            {
                return(null);
            }

            int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

            // seq
            var seqBytes = new byte[4];

            if (!await ReadBuffer(stream, seqBytes))
            {
                return(null);
            }

            int seq = BitConverter.ToInt32(seqBytes, 0);

            // body
            var bodyBytes = new byte[packetLength - 12];

            if (!await ReadBuffer(stream, bodyBytes))
            {
                return(null);
            }

            // crc
            var crcBytes = new byte[4];

            if (!await ReadBuffer(stream, crcBytes))
            {
                return(null);
            }

            int checksum = BitConverter.ToInt32(crcBytes, 0);

            byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + bodyBytes.Length];

            Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
            Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
            Buffer.BlockCopy(bodyBytes, 0, rv, packetLengthBytes.Length + seqBytes.Length, bodyBytes.Length);
            var crc32 = new Ionic.Crc.CRC32();

            crc32.SlurpBlock(rv, 0, rv.Length);
            var validChecksum = crc32.Crc32Result;

            if (checksum != validChecksum)
            {
                throw new InvalidOperationException("invalid checksum! skip");
            }

            return(new TcpMessage(seq, bodyBytes));
        }
예제 #6
0
        private static bool IsValidChecksum(byte[] block, int checksum)
        {
            var crc32 = new Ionic.Crc.CRC32();

            crc32.SlurpBlock(block, 0, block.Length);
            var validChecksum = crc32.Crc32Result;

            return(checksum == validChecksum);
        }
        public TcpMessage Receieve()
        {
            lock (_locker)
            {
                var stream = _tcpClient.GetStream();

                var packetLengthBytes = new byte[4];
                if (stream.Read(packetLengthBytes, 0, 4) != 4)
                {
                    throw new InvalidOperationException("Couldn't read the packet length");
                }
                int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

                var seqBytes = new byte[4];
                if (stream.Read(seqBytes, 0, 4) != 4)
                {
                    throw new InvalidOperationException("Couldn't read the sequence");
                }
                int seq = BitConverter.ToInt32(seqBytes, 0);

                int readBytes    = 0;
                var body         = new byte[packetLength - 12];
                int neededToRead = packetLength - 12;

                do
                {
                    var bodyByte       = new byte[packetLength - 12];
                    var availableBytes = stream.Read(bodyByte, 0, neededToRead);
                    neededToRead -= availableBytes;
                    Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
                    readBytes += availableBytes;
                }while (readBytes != packetLength - 12);

                var crcBytes = new byte[4];
                if (stream.Read(crcBytes, 0, 4) != 4)
                {
                    throw new InvalidOperationException("Couldn't read the crc");
                }
                int checksum = BitConverter.ToInt32(crcBytes, 0);

                byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];

                Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
                Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
                Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
                var crc32 = new Ionic.Crc.CRC32();
                crc32.SlurpBlock(rv, 0, rv.Length);
                var validChecksum = crc32.Crc32Result;

                if (checksum != validChecksum)
                {
                    throw new InvalidOperationException("invalid checksum! skip");
                }

                return(new TcpMessage(seq, body));
            }
        }
예제 #8
0
        public static uint CalculateCRCForChunk(string chunkType, byte[] chunkData)
        {
            byte[] chunkTypeBytes = Encoding.UTF8.GetBytes(chunkType);

            Ionic.Crc.CRC32 crc32calculator = new Ionic.Crc.CRC32();
            crc32calculator.SlurpBlock(chunkTypeBytes, 0, chunkTypeBytes.Length);
            crc32calculator.SlurpBlock(chunkData, 0, chunkData.Length);

            return((uint)crc32calculator.Crc32Result);
        }
        private void _DeflateOne(Object wi)
        {
            // compress one buffer
            WorkItem workitem = (WorkItem)wi;

            try
            {
                int             myItem = workitem.index;
                Ionic.Crc.CRC32 crc    = new Ionic.Crc.CRC32();

                // calc CRC on the buffer
                crc.SlurpBlock(workitem.buffer, 0, workitem.inputBytesAvailable);

                // deflate it
                DeflateOneSegment(workitem);

                // update status
                workitem.crc = crc.Crc32Result;
                TraceOutput(TraceBits.Compress,
                            "Compress          wi({0}) ord({1}) len({2})",
                            workitem.index,
                            workitem.ordinal,
                            workitem.compressedBytesAvailable
                            );

                lock (_latestLock)
                {
                    if (workitem.ordinal > _latestCompressed)
                    {
                        _latestCompressed = workitem.ordinal;
                    }
                }
                lock (_toWrite)
                {
                    _toWrite.Enqueue(workitem.index);
                }
                _newlyCompressedBlob.Set();
            }
            catch (System.Exception exc1)
            {
                lock (_eLock)
                {
                    // expose the exception to the main thread
                    if (_pendingException != null)
                    {
                        _pendingException = exc1;
                    }
                }
            }
        }
예제 #10
0
        public async Task<TcpMessage> Receieve()
        {
            var stream = _tcpClient.GetStream();

            var packetLengthBytes = new byte[4];
            if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4)
                throw new InvalidOperationException("Couldn't read the packet length");
            int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

            var seqBytes = new byte[4];
            if (await stream.ReadAsync(seqBytes, 0, 4) != 4)
                throw new InvalidOperationException("Couldn't read the sequence");
            int seq = BitConverter.ToInt32(seqBytes, 0);

            int readBytes = 0;
            var body = new byte[packetLength - 12];
            int neededToRead = packetLength - 12;

            do
            {
                var bodyByte = new byte[packetLength - 12];
                var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead);
                neededToRead -= availableBytes;
                Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
                readBytes += availableBytes;
            }
            while (readBytes != packetLength - 12);

            var crcBytes = new byte[4];
            if (await stream.ReadAsync(crcBytes, 0, 4) != 4)
                throw new InvalidOperationException("Couldn't read the crc");
            int checksum = BitConverter.ToInt32(crcBytes, 0);

            byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];

            Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
            Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
            Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
            var crc32 = new Ionic.Crc.CRC32();
            crc32.SlurpBlock(rv, 0, rv.Length);
            var validChecksum = crc32.Crc32Result;

            if (checksum != validChecksum)
            {
                throw new InvalidOperationException("invalid checksum! skip");
            }

            return new TcpMessage(seq, body);
        }
예제 #11
0
 public ZlibBaseStream(System.IO.Stream stream,
     ZlibStreamFlavor flavor,
     bool leaveOpen)
     : base()
 {
     this._flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     this._stream = stream;
     this._leaveOpen = leaveOpen;
     this._flavor = flavor;
     // workitem 7159
     if (flavor == ZlibStreamFlavor.GZIP)
     {
         this.crc = new Ionic.Crc.CRC32();
     }
 }
예제 #12
0
 public ZlibBaseStream(System.IO.Stream stream,
                       ZlibStreamFlavor flavor,
                       bool leaveOpen)
     : base()
 {
     this._flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     this._stream    = stream;
     this._leaveOpen = leaveOpen;
     this._flavor    = flavor;
     // workitem 7159
     if (flavor == ZlibStreamFlavor.GZIP)
     {
         this.crc = new Ionic.Crc.CRC32();
     }
 }
예제 #13
0
        /// <summary>
        /// Get the CRC of a file stream and return as a string
        /// </summary>
        /// <param name="stream">FileStream</param>
        /// <param name="hashOption">Default = SHA1, also MD5 and CRC32</param>
        /// <param name="headerlength">Number of bytes to skip prior to computing hash. Should try both platform header length and 0 when comparing to known checksum to account for Rom files with dumped intros. Default = 0.</param>
        /// <returns>Returns hash as hex string</returns>
        public static string GetHash(Stream stream, HashOption hashOption = HashOption.SHA1, int headerlength = 0)
        {
            string hash         = "";
            int    streamLength = (int)stream.Length;

            if (streamLength < headerlength)
            {
                return("");
            }
            // Read header and discard
            stream.Seek(headerlength, SeekOrigin.Begin);

            // Read everything after the header into a byte array
            byte[] buffer = new byte[streamLength - headerlength];
            stream.Read(buffer, 0, (streamLength - headerlength));

            switch (hashOption)
            {
            case HashOption.CRC32:
                var crc32 = new Ionic.Crc.CRC32();
                foreach (byte b in buffer)
                {
                    crc32.UpdateCRC(b);
                }
                hash = crc32.Crc32Result.ToString("x8").ToUpper();
                break;

            case HashOption.MD5:
                var    md5       = MD5.Create();
                byte[] hashBytes = md5.ComputeHash(buffer);
                hash = BitConverter.ToString(hashBytes).Replace("-", String.Empty).ToUpper();
                break;

            case HashOption.SHA1:
                SHA1Managed managedSHA1 = new SHA1Managed();
                byte[]      shaBuffer   = managedSHA1.ComputeHash(buffer);
                foreach (byte b in shaBuffer)
                {
                    hash += b.ToString("x2").ToUpper();
                }
                break;
            }

            return(hash);
        }
예제 #14
0
 public ZlibBaseStream(System.IO.Stream stream,
                       CompressionMode compressionMode,
                       CompressionLevel level,
                       ZlibStreamFlavor flavor,
                       bool leaveOpen)
     : base()
 {
     _flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     _stream          = stream;
     _leaveOpen       = leaveOpen;
     _compressionMode = compressionMode;
     _flavor          = flavor;
     _level           = level;
     // workitem 7159
     if (flavor == ZlibStreamFlavor.GZIP)
     {
         crc = new Ionic.Crc.CRC32();
     }
 }
        private void _InitializePoolOfWorkItems()
        {
            _toWrite = new Queue <int>();
            _toFill  = new Queue <int>();
            _pool    = new System.Collections.Generic.List <WorkItem>();
            int nTasks = BufferPairsPerCore * Environment.ProcessorCount;

            nTasks = Math.Min(nTasks, _maxBufferPairs);
            for (int i = 0; i < nTasks; i++)
            {
                _pool.Add(new WorkItem(_bufferSize, _compressLevel, Strategy, i));
                _toFill.Enqueue(i);
            }

            _newlyCompressedBlob = new AutoResetEvent(false);
            _runningCrc          = new Ionic.Crc.CRC32();
            _currentlyFilling    = -1;
            _lastFilled          = -1;
            _lastWritten         = -1;
            _latestCompressed    = -1;
        }
예제 #16
0
        public ZlibBaseStream(System.IO.Stream stream,
                              CompressionMode compressionMode,
                              CompressionLevel level,
                              ZlibStreamFlavor flavor,
                              bool leaveOpen)
            : base()
        {
            this._flushMode = FlushType.None;
            //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
            this._stream          = stream;
            this._leaveOpen       = leaveOpen;
            this._compressionMode = compressionMode;
            this._flavor          = flavor;
            this._level           = level;
            // workitem 7159
            if (flavor == ZlibStreamFlavor.GZIP)
            {
#if !NETFX_CORE
                this.crc = new Ionic.Crc.CRC32();
#else
                throw new NotSupportedException("ZlibStreamFlavor.GZIP is unsupported");
#endif
            }
        }
예제 #17
0
        /// <summary>
        ///   Resets the stream for use with another stream.
        /// </summary>
        /// <remarks>
        ///   Because the ParallelDeflateOutputStream is expensive to create, it
        ///   has been designed so that it can be recycled and re-used.  You have
        ///   to call Close() on the stream first, then you can call Reset() on
        ///   it, to use it again on another stream.
        /// </remarks>
        ///
        /// <param name="stream">
        ///   The new output stream for this era.
        /// </param>
        ///
        /// <example>
        /// <code>
        /// ParallelDeflateOutputStream deflater = null;
        /// foreach (var inputFile in listOfFiles)
        /// {
        ///     string outputFile = inputFile + ".compressed";
        ///     using (System.IO.Stream input = System.IO.File.OpenRead(inputFile))
        ///     {
        ///         using (var outStream = System.IO.File.Create(outputFile))
        ///         {
        ///             if (deflater == null)
        ///                 deflater = new ParallelDeflateOutputStream(outStream,
        ///                                                            CompressionLevel.Best,
        ///                                                            CompressionStrategy.Default,
        ///                                                            true);
        ///             deflater.Reset(outStream);
        ///
        ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
        ///             {
        ///                 deflater.Write(buffer, 0, n);
        ///             }
        ///         }
        ///     }
        /// }
        /// </code>
        /// </example>
        public void Reset(Stream stream)
        {
            TraceOutput(TraceBits.Session, "-------------------------------------------------------");
            TraceOutput(TraceBits.Session, "Reset {0:X8} firstDone({1})", this.GetHashCode(), _firstWriteDone);

            if (!_firstWriteDone) return;

            // reset all status
            _toWrite.Clear();
            _toFill.Clear();
            foreach (var workitem in _pool)
            {
                _toFill.Enqueue(workitem.index);
                workitem.ordinal = -1;
            }

            _firstWriteDone = false;
            _totalBytesProcessed = 0L;
            _runningCrc = new Ionic.Crc.CRC32();
            _isClosed= false;
            _currentlyFilling = -1;
            _lastFilled = -1;
            _lastWritten = -1;
            _latestCompressed = -1;
            _outStream = stream;
        }
예제 #18
0
        private void _InitializePoolOfWorkItems()
        {
            _toWrite = new Queue<int>();
            _toFill = new Queue<int>();
            _pool = new System.Collections.Generic.List<WorkItem>();
            int nTasks = BufferPairsPerCore * Environment.ProcessorCount;
            nTasks = Math.Min(nTasks, _maxBufferPairs);
            for(int i=0; i < nTasks; i++)
            {
                _pool.Add(new WorkItem(_bufferSize, _compressLevel, Strategy, i));
                _toFill.Enqueue(i);
            }

            _newlyCompressedBlob = new AutoResetEvent(false);
            _runningCrc = new Ionic.Crc.CRC32();
            _currentlyFilling = -1;
            _lastFilled = -1;
            _lastWritten = -1;
            _latestCompressed = -1;
        }
예제 #19
0
        private void _DeflateOne(Object wi)
        {
            // compress one buffer
            WorkItem workitem = (WorkItem) wi;
            try
            {
                int myItem = workitem.index;
                Ionic.Crc.CRC32 crc = new Ionic.Crc.CRC32();

                // calc CRC on the buffer
                crc.SlurpBlock(workitem.buffer, 0, workitem.inputBytesAvailable);

                // deflate it
                DeflateOneSegment(workitem);

                // update status
                workitem.crc = crc.Crc32Result;
                TraceOutput(TraceBits.Compress,
                            "Compress          wi({0}) ord({1}) len({2})",
                            workitem.index,
                            workitem.ordinal,
                            workitem.compressedBytesAvailable
                            );

                lock(_latestLock)
                {
                    if (workitem.ordinal > _latestCompressed)
                        _latestCompressed = workitem.ordinal;
                }
                lock (_toWrite)
                {
                    _toWrite.Enqueue(workitem.index);
                }
                _newlyCompressedBlob.Set();
            }
            catch (System.Exception exc1)
            {
                lock(_eLock)
                {
                    // expose the exception to the main thread
                    if (_pendingException!=null)
                        _pendingException = exc1;
                }
            }
        }
예제 #20
0
        private Int32 FigureCrc32()
        {
            if (_crcCalculated == false)
            {
                Stream input = null;
                // get the original stream:
                if (this._Source == ZipEntrySource.WriteDelegate)
                {
                    var output = new Ionic.Crc.CrcCalculatorStream(Stream.Null);
                    // allow the application to write the data
                    this._WriteDelegate(this.FileName, output);
                    _Crc32 = output.Crc;
                }
                else if (this._Source == ZipEntrySource.ZipFile)
                {
                    // nothing to do - the CRC is already set
                }
                else
                {
                    if (this._Source == ZipEntrySource.Stream)
                    {
                        PrepSourceStream();
                        input = this._sourceStream;
                    }
                    else if (this._Source == ZipEntrySource.JitStream)
                    {
                        // allow the application to open the stream
                        if (this._sourceStream == null)
                            _sourceStream = this._OpenDelegate(this.FileName);
                        PrepSourceStream();
                        input = this._sourceStream;
                    }
                    else if (this._Source == ZipEntrySource.ZipOutputStream)
                    {
                    }
                    else
                    {
                        //input = File.OpenRead(LocalFileName);
                        input = File.Open(LocalFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    }

                    var crc32 = new Ionic.Crc.CRC32();
                    _Crc32 = crc32.GetCrc32(input);

                    if (_sourceStream == null)
                    {
#if NETCF
                        input.Close();
#else
                        input.Dispose();
#endif
                    }
                }
                _crcCalculated = true;
            }
            return _Crc32;
        }
예제 #21
0
        public async Task <TcpMessage> Receieve()
        {
            logger.Trace($"Wait for answer {_tcpClient.Available} ...");
            var stream = _tcpClient.GetStream();

            var packetLengthBytes = new byte[4];

            if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4)
            {
                throw new InvalidOperationException("Couldn't read the packet length");
            }
            int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

            logger.Debug("[IN] Packet length: {0}", packetLength);

            var seqBytes = new byte[4];

            if (await stream.ReadAsync(seqBytes, 0, 4) != 4)
            {
                throw new InvalidOperationException("Couldn't read the sequence");
            }
            int seq = BitConverter.ToInt32(seqBytes, 0);

            logger.Debug("[IN] Sequence: {0}", seq);

            int readBytes    = 0;
            var body         = new byte[packetLength - 12];
            int neededToRead = packetLength - 12;

            do
            {
                var bodyByte       = new byte[packetLength - 12];
                var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead);

                neededToRead -= availableBytes;
                Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
                readBytes += availableBytes;
            }while (readBytes != packetLength - 12);

            var crcBytes = new byte[4];

            if (await stream.ReadAsync(crcBytes, 0, 4) != 4)
            {
                throw new InvalidOperationException("Couldn't read the crc");
            }
            int checksum = BitConverter.ToInt32(crcBytes, 0);

            byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];

            Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
            Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
            Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
            var crc32 = new Ionic.Crc.CRC32();

            crc32.SlurpBlock(rv, 0, rv.Length);
            var validChecksum = crc32.Crc32Result;

            if (checksum != validChecksum)
            {
                throw new InvalidOperationException("invalid checksum! skip");
            }

            return(new TcpMessage(seq, body));
        }
예제 #22
0
        public async Task <TcpMessage> Receieve(int timeoutms)
        {
            logger.Trace($"Wait for event {_tcpClient.Available} ...");
            var stream = _tcpClient.GetStream();

            var packetLengthBytes = new byte[4];
            var token             = tokenSource.Token;

            stream.ReadTimeout = timeoutms;
            int bytes = 0;

            try
            {
                bytes = stream.Read(packetLengthBytes, 0, 4);
            } catch (System.IO.IOException io)
            {
                var socketError = io.InnerException as SocketException;
                if (socketError != null && socketError.SocketErrorCode == SocketError.TimedOut)
                {
                    throw new OperationCanceledException();
                }
                throw io;
            }
            if (bytes != 4)
            {
                throw new InvalidOperationException("Couldn't read the packet length");
            }
            int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

            logger.Debug("[IN]* Packet length: {0}", packetLength);

            var seqBytes = new byte[4];

            if (await stream.ReadAsync(seqBytes, 0, 4) != 4)
            {
                throw new InvalidOperationException("Couldn't read the sequence");
            }
            int seq = BitConverter.ToInt32(seqBytes, 0);

            logger.Debug("[IN]* sequence: {0}", seq);

            int readBytes    = 0;
            var body         = new byte[packetLength - 12];
            int neededToRead = packetLength - 12;

            do
            {
                var bodyByte       = new byte[packetLength - 12];
                var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead);

                neededToRead -= availableBytes;
                Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
                readBytes += availableBytes;
            }while (readBytes != packetLength - 12);

            var crcBytes = new byte[4];

            if (await stream.ReadAsync(crcBytes, 0, 4) != 4)
            {
                throw new InvalidOperationException("Couldn't read the crc");
            }
            int checksum = BitConverter.ToInt32(crcBytes, 0);

            byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];

            Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
            Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
            Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
            var crc32 = new Ionic.Crc.CRC32();

            crc32.SlurpBlock(rv, 0, rv.Length);
            var validChecksum = crc32.Crc32Result;

            if (checksum != validChecksum)
            {
                throw new InvalidOperationException("invalid checksum! skip");
            }

            return(new TcpMessage(seq, body));
        }
예제 #23
0
 private static Int32 GetCrc(string fname)
 {
     using (var fs1 = File.OpenRead(fname))
     {
         var checker = new Ionic.Crc.CRC32(true);
         return checker.GetCrc32(fs1);
     }
 }
예제 #24
0
        public static PackedFileHeader FromReader(BinaryReader reader)
        {
            if (new string(reader.ReadChars(HeaderString.Length)) != HeaderString)
            {
                throw new InvalidDataException("Invalid file header.");
            }

            using var crcStream = new MemoryStream();
            using var crcWriter = new BinaryWriter(crcStream);

            var header = new PackedFileHeader();

            header._dataOffset       = reader.ReadUInt32();
            header._compressedSize   = reader.ReadUInt32();
            header._headerVersion    = reader.ReadUInt32();
            header._decompressedSize = reader.ReadUInt32();
            header._dataBlocksCount  = reader.ReadUInt32();

            crcWriter.WriteString(HeaderString);
            crcWriter.Write(header._dataOffset);
            crcWriter.Write(header._compressedSize);
            crcWriter.Write(header._headerVersion);
            crcWriter.Write(header._decompressedSize);
            crcWriter.Write(header._dataBlocksCount);

            if (header._headerVersion == 0x00)
            {
                if (header._dataOffset != 0x40)
                {
                    throw new InvalidDataException("Invalid header size.");
                }

                if (reader.ReadUInt16() != 0)
                {
                    throw new InvalidDataException();
                }

                header._gameVersion = reader.ReadUInt16();

                crcWriter.Write((ushort)0);
                crcWriter.Write((ushort)header._gameVersion);
            }
            else if (header._headerVersion == 0x01)
            {
                if (header._dataOffset != 0x44)
                {
                    throw new InvalidDataException("Invalid header size.");
                }

                header._gameIdentifier = reader.ReadUInt32();
                header._gameVersion    = reader.ReadUInt32();

                crcWriter.Write(header._gameIdentifier);
                crcWriter.Write(header._gameVersion);
            }
            else
            {
                throw new NotSupportedException("Only header version 1 is supported.");
            }

            header._build      = reader.ReadUInt16();
            header._flags      = reader.ReadUInt16();
            header._gameLength = reader.ReadUInt32();
            header._checksum   = reader.ReadUInt32();

            crcWriter.Write(header._build);
            crcWriter.Write(header._flags);
            crcWriter.Write(header._gameLength);
            crcWriter.Write(0U);

            crcStream.Position = 0;
            var crc = new Ionic.Crc.CRC32().GetCrc32(crcStream);

            if (crc != header._checksum)
            {
                throw new InvalidDataException("CRC failed");
            }

            return(header);
        }
예제 #25
0
        public async Task <TcpMessage> Receieve()
        {
            //var stream = _tcpClient.GetStream();

            //var packetLengthBytes = new byte[4];
            //if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4)
            //    throw new InvalidOperationException("Couldn't read the packet length");
            //int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

            //var seqBytes = new byte[4];
            //if (await stream.ReadAsync(seqBytes, 0, 4) != 4)
            //    throw new InvalidOperationException("Couldn't read the sequence");
            //int seq = BitConverter.ToInt32(seqBytes, 0);

            //int readBytes = 0;
            //var body = new byte[packetLength - 12];
            //int neededToRead = packetLength - 12;

            //do
            //{
            //    var bodyByte = new byte[packetLength - 12];
            //    var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead);
            //    neededToRead -= availableBytes;
            //    Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
            //    readBytes += availableBytes;
            //}
            //while (readBytes != packetLength - 12);

            //var crcBytes = new byte[4];
            //if (await stream.ReadAsync(crcBytes, 0, 4) != 4)
            //    throw new InvalidOperationException("Couldn't read the crc");
            //int checksum = BitConverter.ToInt32(crcBytes, 0);

            // packet length
            var packetLengthBytes = new byte[4];

            if (!await ReadBuffer(_stream, packetLengthBytes))
            {
                return(null);
            }

            int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);

            // seq
            var seqBytes = new byte[4];

            if (!await ReadBuffer(_stream, seqBytes))
            {
                return(null);
            }

            int seq = BitConverter.ToInt32(seqBytes, 0);

            // body
            var bodyBytes = new byte[packetLength - 12];

            if (!await ReadBuffer(_stream, bodyBytes))
            {
                return(null);
            }

            // crc
            var crcBytes = new byte[4];

            if (!await ReadBuffer(_stream, crcBytes))
            {
                return(null);
            }

            int checksum = BitConverter.ToInt32(crcBytes, 0);

            byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + bodyBytes.Length];

            Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
            Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
            Buffer.BlockCopy(bodyBytes, 0, rv, packetLengthBytes.Length + seqBytes.Length, bodyBytes.Length);
            var crc32 = new Ionic.Crc.CRC32();

            crc32.SlurpBlock(rv, 0, rv.Length);
            var validChecksum = crc32.Crc32Result;

            if (checksum != validChecksum)
            {
                throw new InvalidOperationException("invalid checksum! skip");
            }

            return(new TcpMessage(seq, bodyBytes));
        }
예제 #26
0
        static void Main(string[] args)
        {
            //args = new string[4];
            //args[0] = "Mob-WorldData.wad";
            //args[1] = "-x";
            //args[2] = "*";
            //args[3] = "mobout";
            System.Diagnostics.Stopwatch MainTimer = new System.Diagnostics.Stopwatch();
            MainTimer.Start();
            string wad  = "";     //wad filename
            string mode = "";     //Operating mode
            string arg1 = "";     //Argument 1 for mode
            string arg2 = "";     //Argument 2 for mode

            bool HadArgs = false; //Whether the user supplied arguments, or just a filename

            //Try grabbing wad name and mode

            try
            {
                wad = args[0];
            }
            catch                                         //If the wad/mode couldn't be grabbed
            {
                Console.WriteLine("Please specify wad!"); //Print error message
                PrintHelp();                              //Print usage info
            }

            try
            {
                mode    = args[1];
                HadArgs = true;
            }
            catch                                                                  //If the wad/mode couldn't be grabbed
            {
                Console.WriteLine("No mode selected. Defaulting to extract all."); //Print error message
                mode = "-x";
                //PrintHelp();    //Print usage info
            }

            //If the user specified a mode, try grabbing arguments for specified mode
            if (HadArgs)
            {
                try
                {
                    if (mode == "-x")   //If extract mode, grab two arguments
                    {
                        arg1 = args[2];
                        arg2 = args[3];
                    }
                    else if (mode == "-r" || mode == "-c" || mode == "-d" || mode == "-a")  //Remove/Create/Diff/Add mode, one arg
                    {
                        arg1 = args[2];
                    }
                    else if (mode != "-i" && mode != "-w2z") //If the mode is not -i (takes no arguments), then we don't know what mode they specified
                    {
                        Console.WriteLine("Invalid mode!");  //Print error
                        PrintHelp();                         //Print usage info
                    }
                }
                catch                                                           //If the arguments were missing, or something else went wrong
                {
                    Console.WriteLine("Invalid arguments for specified mode!"); //Print an error
                    PrintHelp();                                                //Print usage info
                }
            }
            else
            {
                if (!System.IO.File.Exists(wad))
                {
                    Console.WriteLine("Wad file not found!");
                    PrintHelp();
                }

                arg1 = "*"; //Set extraction file-selection to all
                System.Windows.Forms.FolderBrowserDialog fd = new System.Windows.Forms.FolderBrowserDialog();
                fd.Description = "Choose where to save the extracted files";
                MainTimer.Stop();
                if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    MainTimer.Start();
                    arg2         = fd.SelectedPath;
                    ExclusionDir = arg2;
                }
                else
                {
                    Quit();
                }
            }

            FileList[] entries = new FileList[0]; //Pre-init the 'entries' array

            if (mode == "-a")                     //If using file-add mode
            {
                try
                {
                    arg2 = args[3];
                }
                catch
                {
                    Console.WriteLine("No output wad specified. Overwriting original");
                    arg2 = wad;
                }

                string[] InFiles = arg1.Split(':');
                for (int i = 0; i < InFiles.Length; i++)
                {
                    if (!File.Exists(InFiles[i]))
                    {
                        if (!Directory.Exists(InFiles[i]))
                        {
                            Console.WriteLine("{0} could not be found!\nCancelling operation...", InFiles[i]);
                            Quit();
                        }
                        else
                        {
                            Console.WriteLine("{0} is a directory! Processing sub-entries...", InFiles[i]);
                        }
                    }
                    else
                    {
                        Console.WriteLine("{0} added", InFiles[i]);
                    }
                }
                Quit();
            }

            if (mode == "-c")    //Create (wad) mode
            {
                //Make sure the input directory exists
                if (!Directory.Exists(arg1))
                {
                    Console.WriteLine("Input directory not found!");
                    PrintHelp();
                }

                string[] InFiles = Directory.GetFiles(arg1, "*.*", SearchOption.AllDirectories); //Grab a list of all files within the directory
                entries = new FileList[InFiles.Count()];                                         //Make a new FileList for storing these files in the wad
                Console.WriteLine("Filecount: {0}", InFiles.Count());                            //Debug

                //For each file
                Parallel.For(0, InFiles.Count(), i =>
                {
                    entries[i].Filename = InFiles[i].Substring(arg1.Length, InFiles[i].Length - arg1.Length);   //Remove directory info that shouldn't be included in the wad (path up to the wad contents)
                    if (entries[i].Filename.IndexOf("\\") == 0)                                                 //If the entry starts with a \
                    {
                        entries[i].Filename = entries[i].Filename.Substring(1, entries[i].Filename.Length - 1); //Get rid of the slash
                    }
                    entries[i].Filename = entries[i].Filename.Replace('\\', '/');

                    //MemoryStream ms = new MemoryStream(File.ReadAllBytes(InFiles[i]));  //Read
                    entries[i].Data = File.ReadAllBytes(InFiles[i]);    //Read the file into memory
                    entries[i].Size = (uint)entries[i].Data.Length;
                    //Console.WriteLine("{0}, with a size of {1}, was read to memory", entries[i].Filename, entries[i].Size);
                });

                Console.WriteLine("Files read to memory");

                List <byte> WadHeader = new List <byte>();
                List <byte> WadBody   = new List <byte>();

                var crcparam = new CrcSharp.CrcParameters(32, 0x04c11db7, 0, 0, true, true);
                var crc      = new CrcSharp.Crc(crcparam);

                for (int i = 0; i < entries.Length; i++)
                {
                    entries[i].Offset = (uint)WadBody.Count();  //Save the offset for this entry

                    MemoryStream          Compressed = new MemoryStream();
                    Ionic.Zlib.ZlibStream zls        = new Ionic.Zlib.ZlibStream(Compressed, Ionic.Zlib.CompressionMode.Compress, Ionic.Zlib.CompressionLevel.BestCompression, false);
                    zls.Write(entries[i].Data, 0, entries[i].Data.Length);
                    zls.Close();
                    byte[] compdata = Compressed.ToArray();
                    WadBody.AddRange(compdata);                                                //Add the compressed data to the body of the wad
                    entries[i].CRC            = (uint)crc.CalculateAsNumeric(entries[i].Data); //Add the CRC of the compressed data (idk why they do this)
                    entries[i].CompressedSize = (uint)compdata.Length;                         //Save the size of the compressed data
                    //Console.WriteLine("CRC: {0} : {1}", entries[i].CRC.ToString("X8"), entries[i].Filename);    //Debug
                }
                Console.WriteLine("Wad body added");
                //Add wad header info
                WadHeader.AddRange(new byte[] { 0x4B, 0x49, 0x57, 0x41, 0x44, 0x02, 0x00, 0x00, 0x00 }); //Add magic and wad version (2)
                WadHeader.AddRange(BitConverter.GetBytes(entries.Length));                               //Add the file count
                WadHeader.Add(0x01);                                                                     //Add wad2 byte (idk what it is, but it's required)

                int[] offoff = new int[entries.Length];                                                  //Keeps track of the offset for the 'Offset' field in the header (we can't know the offset until the header is finished, so we add it later)

                //Add each file to the wad header
                for (int i = 0; i < entries.Length; i++)
                {
                    offoff[i] = WadHeader.Count();                                             //Save current offset, so that we can update the 'offset' field when the header is finished
                    WadHeader.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x00 });                 //Add filler offset
                    WadHeader.AddRange(BitConverter.GetBytes(entries[i].Size));                //Add uncompresses file size
                    WadHeader.AddRange(BitConverter.GetBytes(entries[i].CompressedSize));      //Add compressed file size
                    WadHeader.Add(0x01);                                                       //Set 'IsCompressed' to 1 (we compress all files, so this is always true)
                    WadHeader.AddRange(BitConverter.GetBytes(entries[i].CRC));                 //Add the compressed-data crc (idk why they have this, because the extracted file has a crc anyway)
                    WadHeader.AddRange(BitConverter.GetBytes(entries[i].Filename.Length + 1)); //Add filename length
                    WadHeader.AddRange(ASCIIEncoding.ASCII.GetBytes(entries[i].Filename));     //Add the filename
                    WadHeader.Add(0x00);                                                       //Add padding
                }
                Console.WriteLine("Wad Header added");
                //Fix the offsets
                for (int i = 0; i < entries.Length; i++)
                {
                    byte[] offsetbytes = BitConverter.GetBytes(WadHeader.Count() + entries[i].Offset);
                    WadHeader[offoff[i]]     = offsetbytes[0];
                    WadHeader[offoff[i] + 1] = offsetbytes[1];
                    WadHeader[offoff[i] + 2] = offsetbytes[2];
                    WadHeader[offoff[i] + 3] = offsetbytes[3];
                }
                Console.WriteLine("Offsets fixed");
                byte[] Output = WadHeader.Concat(WadBody).ToArray();
                File.WriteAllBytes(wad, Output);  //Save
                Console.WriteLine("Wad Saved");
                Quit();
            }

            if (mode != "-c")    //If the tool is not in create mode, check if the wad exists
            {
                if (!System.IO.File.Exists(wad))
                {
                    Console.WriteLine("Wad file not found!");
                    PrintHelp();
                }
                else    //If the file exists
                {
                    Console.WriteLine("Reading wad to memory...");
                    entries = ReadWad(wad);    //Read the wad into the 'entries' array
                }
            }

            if (mode == "-d" && !File.Exists(arg1))  //If using diff mode, and the second file doesn't exist
            {
                Console.WriteLine("Second wad does not exist!");
                PrintHelp();
            }

            if (mode == "-w2z")  //If using Wad2Zip mode
            {
                //Stopwatch for diagnostics
                System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start();

                Console.WriteLine("Calculating CRC's...");

                //For each file in the wad; extract it in-memory, calculate the CRC of the extracted data, and update the entry's CRC field (because this is done in-memory, it should be less than a couple of seconds)
                Parallel.For(0, entries.Length, i =>
                {
                    byte[] filemem = new byte[0];

                    if (entries[i].IsCompressed)   //If the file is marked as compressed
                    {
                        filemem = Ionic.Zlib.ZlibStream.UncompressBuffer(entries[i].Data);
                        Array.Copy(entries[i].Data, 2, entries[i].Data, 0, entries[i].Data.Length - 6);
                    }
                    else    //If the file isn't compressed
                    {
                        filemem = entries[i].Data;
                    }


                    Ionic.Crc.CRC32 crc = new Ionic.Crc.CRC32();
                    entries[i].CRC      = (uint)crc.GetCrc32(new MemoryStream(filemem)); //Replace the entries' crc with the CRC of the compressed data (KI are shit and use their own incompatible polynomials for their checksum, so we need to recalculate it with a standard polynomial)
                });
                stopwatch.Stop();

                //Stopwatch for timing the zip-process
                System.Diagnostics.Stopwatch ziptimer = new System.Diagnostics.Stopwatch();
                ziptimer.Start();
                byte[] outputfile = Zipper(entries);    //Add all file entries to a zip in-memory, and return the zip
                ziptimer.Stop();

                File.WriteAllBytes(wad + ".zip", outputfile);   //Save the created zip to disk (input filename with .zip appended)

                MainTimer.Stop();

                Console.WriteLine("Updated CRC's in {0} Seconds", stopwatch.Elapsed.TotalSeconds);
                Console.WriteLine("Zipped in {0} Seconds", ziptimer.Elapsed.TotalSeconds);
                Console.WriteLine("Total program runtime: {0} Seconds", MainTimer.Elapsed.TotalSeconds);
                Quit(); //Exit
            }


            if (mode == "-i" || mode == "-x" || mode == "-d")
            {
                if (mode == "-i")                                                                                                                             //If using info mode
                {
                    StringBuilder sb = new StringBuilder();                                                                                                   //Make a new stringbuilder (stringbuilder is much faster than just appending strings normally)
                    for (int i = 0; i < entries.Length; i++)                                                                                                  //For each file entry
                    {
                        sb.AppendLine(entries[i].Offset.ToString("X") + ":" + entries[i].CompressedSize + ":" + entries[i].Size + ":" + entries[i].Filename); //Add a newline to the output string, with the offset and filename (offset:filename)
                    }
                    Console.WriteLine(sb);                                                                                                                    //Print the output string
                    MainTimer.Stop();
                    Console.WriteLine("{0} files found in {1} Seconds", entries.Length, MainTimer.Elapsed.TotalSeconds);
                    Quit();            //Quit
                }
                else if (mode == "-d") //If using diff mode
                {
                    Console.WriteLine("Diff-checking {0} and {1}", wad, arg1);
                    bool extract = false;

                    try                 //Try grabbing the output-folder argument
                    {
                        arg2 = args[3]; //Grab fourth argument (starting from 0)
                        try
                        {
                            arg2 = ResolveDir(arg2);

                            extract = true;                                                                                                                            //Enable file-extraction
                        }
                        catch                                                                                                                                          //If something went wrong whlie creating the directory
                        {
                            Console.WriteLine("Error creating directory: {0}\nMaybe you're trying to write to a folder you don't have permission to write in?", arg2); //Let the user know something went wrong
                            Quit();                                                                                                                                    //Exit
                        }
                    }
                    catch                                                                                  //If there isn't an output-folder argument
                    {
                        Console.WriteLine("No output folder specified. No extraction will be performed."); //Print a message stating operating mode
                    }

                    Console.WriteLine("Checking differences...");

                    FileList[] entries2  = ReadWad(arg1);
                    bool[]     ExtractIt = new bool[entries2.Length]; //Create a bool array, which keeps track of which files to extract from the second wad

                    StringBuilder MissingIn1 = new StringBuilder();
                    StringBuilder MissingIn2 = new StringBuilder();
                    StringBuilder DiffIn2    = new StringBuilder();
                    object        threadsync = new object(); //Threadsync is used to prevent threads from overwriting eachothers data

                    //Check what files are missing
                    Parallel.For(0, entries.Length, i =>                         //For each file entry in the first wad
                    {
                        bool Exists = false;                                     //Mark the file as not existing in both wads (default, until proven otherwise)

                        for (int j = 0; j < entries2.Length; j++)                //For each file in second wad
                        {
                            if (entries2[j].Filename == entries[i].Filename)     //If the currently-processes filename in wad 1 is also the same filename in wad2
                            {
                                Exists = true;                                   //Mark the file as existing in both

                                if (entries2[j].CRC != entries[i].CRC)           //If the files have a different CRC
                                {
                                    lock (threadsync)                            //Use a lock to prevent SB from getting corrupt by multiple-accesses
                                    {
                                        DiffIn2.AppendLine(entries[i].Filename); //Add the filename to the 'DiffIn2' sb, so we can print the results later
                                    }
                                    ExtractIt[j] = true;                         //Mark the file in wad2 for extraction, because it's different
                                }

                                break;  //Stop searching for this file, because we've already checked it
                            }
                        }
                        if (!Exists)                                        //If the file wasn't marked as existing
                        {
                            lock (threadsync)                               //Use a lock to prevent SB from getting corrupt by multiple-accesses
                            {
                                MissingIn2.AppendLine(entries[i].Filename); //Add the file to the 'MissingIn2' sb for printing later
                            }
                        }
                    });


                    //Check what files exist in both wads (and whether any files were added)
                    Parallel.For(0, entries2.Length, i =>
                    {
                        bool Exists = false;
                        for (int j = 0; j < entries.Length; j++)
                        {
                            if (entries2[i].Filename == entries[j].Filename)
                            {
                                Exists = true; //Mark the file as existing in both
                                break;         //Stop searching for this file
                            }
                        }
                        if (!Exists)                                        //If the file wasn't marked as existing
                        {
                            lock (threadsync)                               //Use a lock to prevent SB from getting corrupt by multiple-accesses
                            {
                                MissingIn1.AppendLine(entries[i].Filename); //Add the file to the 'MissingIn1' sb for printing later
                            }
                            ExtractIt[i] = true;                            //Mark the file in wad2 for extraction, because it doesn't exist in wad1
                        }
                    });

                    Console.WriteLine("Diff-checking complete!");
                    if (extract)                                                //If the user specified an output directory (extract diff files)
                    {
                        Console.WriteLine("Extracting new/different files..."); //Inform the user that the files will now be extracted

                        Console.WriteLine("Pre-creating directories...");
                        for (int i = 0; i < entries2.Length; i++) //For each file in the second wad
                        {
                            if (ExtractIt[i])                     //If the file is marked for extraction, check it for any subdirectories, and create them if necessary
                            {
                                PreCreate(entries2[i], arg2);     //Call 'PreCreate' for that file, and any required subdirs for that file will be created
                            }
                        }

                        Console.WriteLine("Directories created!\nExtracting...");

                        //For each file in the second wad, check if it's marked for extraction; and if so, extract it.
                        Parallel.For(0, entries2.Length, i =>
                        {
                            if (ExtractIt[i])                                                                                   //If the file was marked for extraction (new/different file)
                            {
                                if (entries2[i].IsCompressed)                                                                   //If the file is marked as compressed
                                {
                                    entries2[i].Data = Ionic.Zlib.ZlibStream.UncompressBuffer(entries2[i].Data);                //Decompress the file
                                }
                                using (FileStream output = new FileStream(arg2 + "\\" + entries2[i].Filename, FileMode.Create)) //Create the file that is being extracted (replaces old files if they exist)
                                {
                                    output.Write(entries2[i].Data, 0, entries2[i].Data.Length);                                 //Write the file from memory to disk
                                }
                            }
                        });
                    }



                    if (MissingIn1.Length > 0 || MissingIn2.Length > 0 || DiffIn2.Length > 0)   //If there were any file differences
                    {
                        Console.WriteLine("Differences found!");

                        if (entries.Length != entries2.Length)
                        {
                            Console.WriteLine("------------------------------File count is different!------------------------------\nOld:{0}\tNew:{1}", entries.Length, entries2.Length);
                        }

                        if (MissingIn1.Length > 0)
                        {
                            Console.WriteLine("------------------------------Files missing in first wad------------------------------\n{0}", MissingIn1);
                        }

                        if (MissingIn2.Length > 0)
                        {
                            Console.WriteLine("------------------------------Files missing in second wad------------------------------\n{0}", MissingIn2);
                        }

                        if (DiffIn2.Length > 0)
                        {
                            Console.WriteLine("------------------------------Files changed------------------------------\n{0}", DiffIn2);
                        }
                    }
                    else
                    {
                        Console.WriteLine("No differences found!");
                    }

                    MainTimer.Stop();
                    Console.WriteLine("Total program runtime: {0} Seconds", MainTimer.Elapsed.TotalSeconds);
                    Quit();
                }
                else if (mode == "-x")   //If using extract mode
                {
                    arg2 = ResolveDir(arg2);
                    if (arg1 != "*")                                                                                                                                                                             //If the user specified a file to extract (not all files)
                    {
                        for (int i = 0; i < entries.Length; i++)                                                                                                                                                 //For each file in the filelist
                        {
                            if (string.Equals(entries[i].Filename, arg1, StringComparison.OrdinalIgnoreCase) || string.Equals(entries[i].Filename.Replace('/', '\\'), arg1, StringComparison.OrdinalIgnoreCase)) //If the file entry matches the user-specified file (ignoring case and slash-direction)
                            {
                                Console.WriteLine("File found!");

                                PreCreate(entries[i], arg2);                                                                   //Check if file is located in a subdirectory. If so, create the appropriate directory structure

                                if (entries[i].IsCompressed)                                                                   //If the file is marked as compressed
                                {
                                    entries[i].Data = Ionic.Zlib.ZlibStream.UncompressBuffer(entries[i].Data);                 //Decompress the data
                                }
                                using (FileStream output = new FileStream(arg2 + "\\" + entries[i].Filename, FileMode.Create)) //Create the file that is being extracted (replaces old files if they exist)
                                {
                                    output.Write(entries[i].Data, 0, entries[i].Data.Length);                                  //Write the file from memory to disk
                                    Console.WriteLine("File extracted to: {0}", arg2 + "\\" + entries[i].Filename.Replace('/', '\\'));
                                }

                                Quit();
                            }
                            //If the filename doesn't match, read the next entry
                        }
                        //If all files have been scanned, and the user-specified file wasn't found; let the user know, and give them some advice
                        Console.WriteLine("'{0}' was not found in the specified wad!", arg1);
                        Console.WriteLine("Make sure you include the file's parent directories");
                        Console.WriteLine("eg: capabilities\\cpu.xml");
                        Quit();
                    }
                    else    //If the file is '*": Don't 'really' need to say else here, because it would have exited previously anyway, but it just makes things more readable
                    {
                        //Create directories in advance, using a single thread (prevents race crash when parallel threads attempt to create the same directory at the same time)
                        Console.WriteLine("Pre-creating directories...");
                        for (int i = 0; i < entries.Length; i++)
                        {
                            PreCreate(entries[i], arg2);    //Pre-create any subdirectories listed in the filename (arg2 is the base directory for extraction)
                        }
                        Console.WriteLine("Directories created!\nExtracting...");

                        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                        stopwatch.Start();

                        Parallel.For(0, entries.Length, i =>
                        {
                            if (entries[i].IsCompressed)   //If the file is marked as compressed
                            {
                                entries[i].Data = Ionic.Zlib.ZlibStream.UncompressBuffer(entries[i].Data);
                            }
                        });

                        stopwatch.Stop();
                        Console.WriteLine("Extraction complete!\nWriting to disk... (this may take some time)");
                        System.Diagnostics.Stopwatch writetimer = new System.Diagnostics.Stopwatch();
                        writetimer.Start();

                        Parallel.For(0, entries.Length, i =>
                        {
                            File.WriteAllBytes(arg2 + "\\" + entries[i].Filename, entries[i].Data);
                        });

                        writetimer.Stop();
                        MainTimer.Stop();
                        Console.WriteLine("Extracted {0} files in {1} Seconds", entries.Length, stopwatch.Elapsed.TotalSeconds);
                        Console.WriteLine("Wrote files in {0} Ms", writetimer.ElapsedMilliseconds);
                        Console.WriteLine("Total program runtime: {0} seconds", MainTimer.Elapsed.TotalSeconds);
                        Quit(); //Exit
                    }
                }
            }
        }
예제 #27
0
        public void Zlib_ParallelDeflateStream()
        {
            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            TestContext.WriteLine("{0}: Zlib_ParallelDeflateStream Start", sw.Elapsed);

            int sz = 256*1024 + this.rnd.Next(120000);
            string FileToCompress = System.IO.Path.Combine(TopLevelDir, String.Format("Zlib_ParallelDeflateStream.{0}.txt", sz));

            CreateAndFillFileText( FileToCompress, sz);

            TestContext.WriteLine("{0}: Created file: {1}", sw.Elapsed, FileToCompress );

            byte[] original = File.ReadAllBytes(FileToCompress);

            int crc1 = DoCrc(FileToCompress);

            TestContext.WriteLine("{0}: Original CRC: {1:X8}", sw.Elapsed, crc1 );

            byte[] working = new byte[WORKING_BUFFER_SIZE];
            int n = -1;
            long originalLength;
            MemoryStream ms1 = new MemoryStream();
            {
                using (FileStream fs1 = File.OpenRead(FileToCompress))
                {
                    originalLength = fs1.Length;
                    using (var compressor = new Ionic.Zlib.ParallelDeflateOutputStream(ms1, true))
                    {
                        while ((n = fs1.Read(working, 0, working.Length)) != 0)
                        {
                            compressor.Write(working, 0, n);
                        }
                    }
                }
                ms1.Seek(0, SeekOrigin.Begin);
            }

            TestContext.WriteLine("{0}: Compressed {1} bytes into {2} bytes", sw.Elapsed,
                                  originalLength, ms1.Length);

            var crc = new Ionic.Crc.CRC32();
            int crc2= 0;
            byte[] decompressedBytes= null;
            using (MemoryStream ms2 = new MemoryStream())
            {
                using (var decompressor = new DeflateStream(ms1, CompressionMode.Decompress, false))
                {
                    while ((n = decompressor.Read(working, 0, working.Length)) != 0)
                    {
                        ms2.Write(working, 0, n);
                    }
                }
                TestContext.WriteLine("{0}: Decompressed", sw.Elapsed);
                TestContext.WriteLine("{0}: Decompressed length: {1}", sw.Elapsed, ms2.Length);
                ms2.Seek(0, SeekOrigin.Begin);
                crc2 = crc.GetCrc32(ms2);
                decompressedBytes = ms2.ToArray();
                TestContext.WriteLine("{0}: Decompressed CRC: {1:X8}", sw.Elapsed, crc2 );
            }


            TestContext.WriteLine("{0}: Checking...", sw.Elapsed );

            bool check = true;
            if (originalLength != decompressedBytes.Length)
            {
                TestContext.WriteLine("Different lengths.");
                check = false;
            }
            else
            {
                for (int i = 0; i < decompressedBytes.Length; i++)
                {
                    if (original[i] != decompressedBytes[i])
                    {
                        TestContext.WriteLine("byte {0} differs", i);
                        check = false;
                        break;
                    }
                }
            }

            Assert.IsTrue(check,"Data check failed");
            TestContext.WriteLine("{0}: Done...", sw.Elapsed );
        }
예제 #28
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MpqArchive"/> class.
        /// </summary>
        /// <param name="sourceStream">The <see cref="Stream"/> containing pre-archive data. Can be <see langword="null"/>.</param>
        /// <param name="inputFiles">The <see cref="MpqFile"/>s that should be added to the archive.</param>
        /// <param name="createOptions"></param>
        /// <param name="leaveOpen">If <see langword="false"/>, the given <paramref name="sourceStream"/> will be disposed when the <see cref="MpqArchive"/> is disposed.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="mpqFiles"/> collection is <see langword="null"/>.</exception>
        public MpqArchive(Stream?sourceStream, IEnumerable <MpqFile> inputFiles, MpqArchiveCreateOptions createOptions, bool leaveOpen = false)
        {
            if (inputFiles is null)
            {
                throw new ArgumentNullException(nameof(inputFiles));
            }

            if (createOptions is null)
            {
                throw new ArgumentNullException(nameof(createOptions));
            }

            _isStreamOwner = !leaveOpen;
            _baseStream    = AlignStream(sourceStream);

            _headerOffset         = _baseStream.Position;
            _blockSize            = BlockSizeModifier << createOptions.BlockSize;
            _archiveFollowsHeader = createOptions.WriteArchiveFirst;

            var signatureName  = Signature.FileName.GetStringHash();
            var listFileName   = ListFile.FileName.GetStringHash();
            var attributesName = Attributes.FileName.GetStringHash();

            var signatureCreateMode  = createOptions.SignatureCreateMode.GetValueOrDefault(MpqFileCreateMode.Prune);
            var listFileCreateMode   = createOptions.ListFileCreateMode.GetValueOrDefault(MpqFileCreateMode.Overwrite);
            var attributesCreateMode = createOptions.AttributesCreateMode.GetValueOrDefault(MpqFileCreateMode.Overwrite);
            var haveSignature        = false;
            var haveListFile         = false;
            var haveAttributes       = false;
            var mpqFiles             = new HashSet <MpqFile>(MpqFileComparer.Default);

            foreach (var mpqFile in inputFiles)
            {
                if (mpqFile is MpqOrphanedFile)
                {
                    continue;
                }

                if (mpqFile.Name == signatureName)
                {
                    if (signatureCreateMode.HasFlag(MpqFileCreateMode.RemoveFlag))
                    {
                        continue;
                    }
                    else
                    {
                        haveSignature = true;
                    }
                }

                if (mpqFile.Name == listFileName)
                {
                    if (listFileCreateMode.HasFlag(MpqFileCreateMode.RemoveFlag))
                    {
                        continue;
                    }
                    else
                    {
                        haveListFile = true;
                    }
                }

                if (mpqFile.Name == attributesName)
                {
                    if (attributesCreateMode.HasFlag(MpqFileCreateMode.RemoveFlag))
                    {
                        continue;
                    }
                    else
                    {
                        haveAttributes = true;
                    }
                }

                if (!mpqFiles.Add(mpqFile))
                {
                    // todo: logging?
                }
            }

            var fileCount = (uint)mpqFiles.Count;

            var wantGenerateSignature = !haveSignature && signatureCreateMode.HasFlag(MpqFileCreateMode.AddFlag);
            var signature             = wantGenerateSignature ? new Signature() : null;

            if (wantGenerateSignature)
            {
                fileCount++;
            }

            var wantGenerateListFile = !haveListFile && listFileCreateMode.HasFlag(MpqFileCreateMode.AddFlag);
            var listFile             = wantGenerateListFile ? new ListFile() : null;

            if (wantGenerateListFile)
            {
                fileCount++;
            }

            var wantGenerateAttributes = !haveAttributes && attributesCreateMode.HasFlag(MpqFileCreateMode.AddFlag);
            var attributes             = wantGenerateAttributes ? new Attributes(createOptions) : null;

            if (wantGenerateAttributes)
            {
                fileCount++;
            }

            _hashTable  = new HashTable(Math.Max(createOptions.HashTableSize ?? fileCount * 8, fileCount));
            _blockTable = new BlockTable();

            using (var writer = new BinaryWriter(_baseStream, new UTF8Encoding(false, true), true))
            {
                // Skip the MPQ header, since its contents will be calculated afterwards.
                writer.Seek((int)MpqHeader.Size, SeekOrigin.Current);

                // Write Archive
                var fileIndex  = 0U;
                var fileOffset = _archiveFollowsHeader ? MpqHeader.Size : throw new NotImplementedException();

                // var gaps = new List<(long Start, long Length)>();
                var endOfStream = _baseStream.Position;

                void InsertMpqFile(MpqFile mpqFile, bool updateEndOfStream, bool allowMultiple = true)
                {
                    if (listFile is not null && mpqFile is MpqKnownFile knownFile)
                    {
                        listFile.FileNames.Add(knownFile.FileName);
                    }

                    mpqFile.AddToArchive(this, fileIndex, out var mpqEntry, out var mpqHash);
                    var hashTableEntries = _hashTable.Add(mpqHash, mpqFile.HashIndex, mpqFile.HashCollisions);

                    if (!allowMultiple && hashTableEntries > 1)
                    {
                        throw new Exception();
                    }

                    var crc32 = 0;

                    if (attributes is not null && attributes.Flags.HasFlag(AttributesFlags.Crc32) && allowMultiple)
                    {
                        mpqFile.MpqStream.Position = 0;
                        crc32 = new Ionic.Crc.CRC32().GetCrc32(mpqFile.MpqStream);
                    }

                    for (var i = 0; i < hashTableEntries; i++)
                    {
                        _blockTable.Add(mpqEntry);
                        if (attributes is not null)
                        {
                            if (attributes.Flags.HasFlag(AttributesFlags.Crc32))
                            {
                                attributes.Crc32s.Add(crc32);
                            }

                            if (attributes.Flags.HasFlag(AttributesFlags.DateTime))
                            {
                                attributes.DateTimes.Add(DateTime.Now);
                            }

                            if (attributes.Flags.HasFlag(AttributesFlags.Unk0x04))
                            {
                                attributes.Unk0x04s.Add(new byte[16]);
                            }
                        }
                    }

                    mpqFile.Dispose();

                    fileIndex += hashTableEntries;
                    if (updateEndOfStream)
                    {
                        endOfStream = _baseStream.Position;
                    }
                }

                // Find files that cannot be decrypted, and need to have a specific position in the archive, because that position is used to calculate the encryption seed.
                var mpqFixedPositionFiles = mpqFiles.Where(mpqFile => mpqFile.IsFilePositionFixed).OrderBy(mpqFile => mpqFile.MpqStream.FilePosition).ToArray();
                if (mpqFixedPositionFiles.Length > 0)
                {
                    if (mpqFixedPositionFiles.First() !.MpqStream.FilePosition < 0)
                    {
                        throw new NotSupportedException($"Cannot place files in front of the header.");
                    }

                    foreach (var mpqFixedPositionFile in mpqFixedPositionFiles)
                    {
                        var position = mpqFixedPositionFile.MpqStream.FilePosition;
                        if (position < endOfStream)
                        {
                            throw new ArgumentException($"Fixed position files overlap with each other and/or the header. Archive cannot be created.", nameof(inputFiles));
                        }

                        if (position > endOfStream)
                        {
                            var gapSize = position - endOfStream;
                            // gaps.Add((endOfStream, gapSize));
                            writer.Seek((int)gapSize, SeekOrigin.Current);
                        }

                        InsertMpqFile(mpqFixedPositionFile, true);
                    }
                }

                foreach (var mpqFile in mpqFiles.Where(mpqFile => !mpqFile.IsFilePositionFixed))
                {
                    // TODO: insert files into the gaps
                    // need to know compressed size of file first, and if file is also encrypted with blockoffsetadjustedkey, encryption needs to happen after gap selection
                    // therefore, can't use current AddToArchive method, which does both compression and encryption at same time

                    // var availableGaps = gaps.Where(gap => gap.Length >= )
                    var selectedPosition = endOfStream;
                    var selectedGap      = false;
                    _baseStream.Position = selectedPosition;

                    InsertMpqFile(mpqFile, !selectedGap);
                }

                var signaturePosition = endOfStream + 8;
                if (signature is not null)
                {
                    _baseStream.Position = endOfStream;

                    using var signatureStream = new MemoryStream();
                    using var signatureWriter = new BinaryWriter(signatureStream);
                    signatureWriter.Write(signature);
                    signatureWriter.Flush();

                    using var signatureMpqFile   = MpqFile.New(signatureStream, Signature.FileName);
                    signatureMpqFile.TargetFlags = MpqFileFlags.Exists;
                    InsertMpqFile(signatureMpqFile, true);
                }

                if (listFile is not null)
                {
                    _baseStream.Position = endOfStream;

                    using var listFileStream = new MemoryStream();
                    using var listFileWriter = new StreamWriter(listFileStream);
                    listFileWriter.WriteListFile(listFile);
                    listFileWriter.Flush();

                    using var listFileMpqFile   = MpqFile.New(listFileStream, ListFile.FileName);
                    listFileMpqFile.TargetFlags = MpqFileFlags.Exists | MpqFileFlags.CompressedMulti | MpqFileFlags.Encrypted | MpqFileFlags.BlockOffsetAdjustedKey;
                    InsertMpqFile(listFileMpqFile, true);
                }

                if (attributes is not null)
                {
                    _baseStream.Position = endOfStream;

                    if (attributes.Flags.HasFlag(AttributesFlags.Crc32))
                    {
                        attributes.Crc32s.Add(0);
                    }

                    if (attributes.Flags.HasFlag(AttributesFlags.DateTime))
                    {
                        attributes.DateTimes.Add(DateTime.Now);
                    }

                    if (attributes.Flags.HasFlag(AttributesFlags.Unk0x04))
                    {
                        attributes.Unk0x04s.Add(new byte[16]);
                    }

                    using var attributesStream = new MemoryStream();
                    using var attributesWriter = new BinaryWriter(attributesStream);
                    attributesWriter.Write(attributes);
                    attributesWriter.Flush();

                    using var attributesMpqFile   = MpqFile.New(attributesStream, Attributes.FileName);
                    attributesMpqFile.TargetFlags = MpqFileFlags.Exists | MpqFileFlags.CompressedMulti | MpqFileFlags.Encrypted | MpqFileFlags.BlockOffsetAdjustedKey;
                    InsertMpqFile(attributesMpqFile, true, false);
                }

                _baseStream.Position = endOfStream;
                _hashTable.WriteTo(writer);
                _blockTable.WriteTo(writer);

                /*if (!_archiveFollowsHeader)
                 * {
                 *  foreach (var mpqFile in mpqFiles)
                 *  {
                 *      mpqFile.WriteTo(writer, true);
                 *  }
                 * }*/

                writer.Seek((int)_headerOffset, SeekOrigin.Begin);

                _mpqHeader = new MpqHeader((uint)_headerOffset, (uint)(endOfStream - fileOffset), _hashTable.Size, _blockTable.Size, createOptions.BlockSize, _archiveFollowsHeader);
                _mpqHeader.WriteTo(writer);

                if (wantGenerateSignature)
                {
                    var archiveBytes = new byte[_mpqHeader.ArchiveSize];
                    _baseStream.Position = _headerOffset;
                    _baseStream.Read(archiveBytes);

                    using var rsa = RSA.Create();

                    rsa.ImportFromPem(createOptions.SignaturePrivateKey);
                    var signatureBytes = rsa.SignData(archiveBytes, HashAlgorithmName.MD5, RSASignaturePadding.Pkcs1);

                    _baseStream.Position = signaturePosition;
                    _baseStream.Write(signatureBytes.Reverse().ToArray());
                }
            }
        }
예제 #29
0
파일: Hooks.cs 프로젝트: Notulp/Pluton.Rust
        public static void SetModded()
        {
            try {
                if (global::Rust.Global.SteamServer == null)
                    return;
                
                using (TimeWarning.New("UpdateServerInformation", 0.1f)) {
                    var steamServer = global::Rust.Global.SteamServer;

                    System.Reflection.Assembly assembly = typeof(ServerMgr).Assembly;
                    byte[] byteArray = System.IO.File.ReadAllBytes(assembly.Location);
                    Ionic.Crc.CRC32 cRC = new Ionic.Crc.CRC32();

                    cRC.SlurpBlock(byteArray, 0, byteArray.Length);

                    string _AssemblyHash = cRC.Crc32Result.ToString("x");

                    steamServer.ServerName = ConVar.Server.hostname;
                    steamServer.MaxPlayers = ConVar.Server.maxplayers;
                    steamServer.Passworded = false;
                    steamServer.MapName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;

                    string gameTags = string.Format("mp{0},cp{1},qp{5},v{2}{3},h{4}", new object[] {
                        ConVar.Server.maxplayers,
                        BasePlayer.activePlayerList.Count,
                        global::Rust.Protocol.network,
                        ConVar.Server.pve ? ",pve" : string.Empty,
                        pluton.enabled ? ",modded,pluton" : string.Empty,
                        _AssemblyHash,
                        ServerMgr.Instance.connectionQueue.Queued
                    });

                    steamServer.GameTags = gameTags;

                    string[] array = ConVar.Server.description.SplitToChunks(100).ToArray();

                    for (int i = 0; i < 16; i++) {
                        if (i < array.Length) {
                            steamServer.SetKey(string.Format("description_{0:00}", i), array[i]);
                        } else {
                            steamServer.SetKey(string.Format("description_{0:00}", i), string.Empty);
                        }
                    }

                    steamServer.SetKey("hash", _AssemblyHash);
                    steamServer.SetKey("world.seed", global::World.Seed.ToString());
                    steamServer.SetKey("world.size", global::World.Size.ToString());
                    steamServer.SetKey("pve", ConVar.Server.pve.ToString());
                    steamServer.SetKey("headerimage", ConVar.Server.headerimage);
                    steamServer.SetKey("url", ConVar.Server.url);
                    steamServer.SetKey("uptime", ((int)Time.realtimeSinceStartup).ToString());
                    steamServer.SetKey("mem_ws", Performance.report.usedMemoryWorkingSetMB.ToString());
                    steamServer.SetKey("mem_pv", Performance.report.usedMemoryPrivateMB.ToString());
                    steamServer.SetKey("gc_mb", Performance.report.memoryAllocations.ToString());
                    steamServer.SetKey("gc_cl", Performance.report.memoryCollections.ToString());
                    steamServer.SetKey("fps", Performance.report.frameRate.ToString());
                    steamServer.SetKey("fps_avg", Performance.report.frameRateAverage.ToString("0.00"));
                    steamServer.SetKey("ent_cnt", BaseNetworkable.serverEntities.Count.ToString());
                    steamServer.SetKey("build", BuildInformation.VersionStampDays.ToString());
                }
            } catch (Exception ex) {
                Logger.LogError("[Hooks] Error while setting the server modded.");
                Logger.LogException(ex);
            }
        }
예제 #30
0
        Int32 FigureCrc32()
        {
            if (_crcCalculated == false)
            {
                Stream input = null;
                // get the original stream:
                if (this._Source == ZipEntrySource.WriteDelegate)
                {
                    var output = new Ionic.Crc.CrcCalculatorStream(Stream.Null);
                    // allow the application to write the data
                    this._WriteDelegate(this.FileName, output);
                    _Crc32 = output.Crc;
                }
                else if (this._Source == ZipEntrySource.ZipFile)
                {
                    // nothing to do - the CRC is already set
                }
                else
                {
                    if (this._Source == ZipEntrySource.Stream)
                    {
                        PrepSourceStream();
                        input = this._sourceStream;
                    }
                    else if (this._Source == ZipEntrySource.JitStream)
                    {
                        // allow the application to open the stream
                        if (this._sourceStream == null)
                            _sourceStream = this._OpenDelegate(this.FileName);
                        PrepSourceStream();
                        input = this._sourceStream;
                    }
                    else if (this._Source == ZipEntrySource.ZipOutputStream)
                    {
                    }
                    else
                    {
                    }

                    var crc32 = new Ionic.Crc.CRC32();
                    _Crc32 = crc32.GetCrc32(input);

                }
                _crcCalculated = true;
            }
            return _Crc32;
        }