示例#1
0
        private ZipReturn ReadBody(bool deepScan)
        {
            using (BinaryReader zipBr = new BinaryReader(_zipFs, Encoding.UTF8, true))
            {
                byte ID1 = zipBr.ReadByte();
                byte ID2 = zipBr.ReadByte();

                if ((ID1 != 0x1f) || (ID2 != 0x8b))
                {
                    _zipFs.Close();
                    return(ZipReturn.ZipSignatureError);
                }

                byte CM = zipBr.ReadByte();
                if (CM != 8)
                {
                    _zipFs.Close();
                    return(ZipReturn.ZipUnsupportedCompression);
                }

                byte FLG = zipBr.ReadByte();


                uint MTime = zipBr.ReadUInt32();
                byte XFL   = zipBr.ReadByte();
                byte OS    = zipBr.ReadByte();

                //if FLG.FEXTRA set
                if ((FLG & 0x4) == 0x4)
                {
                    int    XLen  = zipBr.ReadInt16();
                    byte[] bytes = zipBr.ReadBytes(XLen);

                    if (XLen == 28)
                    {
                        md5Hash = new byte[16];
                        Array.Copy(bytes, 0, md5Hash, 0, 16);
                        crc = new byte[4];
                        Array.Copy(bytes, 16, crc, 0, 4);
                        uncompressedSize = BitConverter.ToUInt64(bytes, 20);
                    }

                    if (XLen == 77)
                    {
                        md5Hash = new byte[16];
                        Array.Copy(bytes, 0, md5Hash, 0, 16);
                        crc = new byte[4];
                        Array.Copy(bytes, 16, crc, 0, 4);
                        uncompressedSize = BitConverter.ToUInt64(bytes, 20);
                        altType          = (HeaderFileType)bytes[28];
                        altmd5Hash       = new byte[16];
                        Array.Copy(bytes, 29, altmd5Hash, 0, 16);
                        altsha1Hash = new byte[20];
                        Array.Copy(bytes, 45, altsha1Hash, 0, 20);
                        altcrc = new byte[4];
                        Array.Copy(bytes, 65, altcrc, 0, 4);
                        uncompressedAltSize = BitConverter.ToUInt64(bytes, 69);
                    }
                }

                //if FLG.FNAME set
                if ((FLG & 0x8) == 0x8)
                {
                    int    XLen  = zipBr.ReadInt16();
                    byte[] bytes = zipBr.ReadBytes(XLen);
                }

                //if FLG.FComment set
                if ((FLG & 0x10) == 0x10)
                {
                    int    XLen  = zipBr.ReadInt16();
                    byte[] bytes = zipBr.ReadBytes(XLen);
                }

                //if FLG.FHCRC set
                if ((FLG & 0x2) == 0x2)
                {
                    uint crc16 = zipBr.ReadUInt16();
                }
            }

            compressedSize = (ulong)(_zipFs.Length - _zipFs.Position) - 8;

            datapos = _zipFs.Position;
            if (deepScan)
            {
                if (Buffer0 == null)
                {
                    Buffer0 = new byte[Buffersize];
                }

                if (Buffer1 == null)
                {
                    Buffer1 = new byte[Buffersize];
                }

                Stream ds = new ZlibBaseStream(_zipFs, CompressionMode.Decompress, CompressionLevel.Default, ZlibStreamFlavor.DEFLATE, true);

                ThreadLoadBuffer lbuffer = new ThreadLoadBuffer(ds);

                ThreadCRC  crc32 = new ThreadCRC();
                ThreadMD5  md5   = new ThreadMD5();
                ThreadSHA1 sha1  = new ThreadSHA1();

                ulong uncompressedRead = 0;
                int   bufferRead       = ds.Read(Buffer0, 0, Buffersize);
                uncompressedRead += (ulong)bufferRead;
                bool whichBuffer = true;

                while (bufferRead > 0)
                {
                    // trigger the buffer loading worker
                    lbuffer.Trigger(whichBuffer ? Buffer1 : Buffer0, Buffersize);

                    byte[] buffer = whichBuffer ? Buffer0 : Buffer1;

                    // trigger the hashing workers
                    crc32.Trigger(buffer, bufferRead);
                    md5.Trigger(buffer, bufferRead);
                    sha1.Trigger(buffer, bufferRead);

                    lbuffer.Wait();
                    crc32.Wait();
                    md5.Wait();
                    sha1.Wait();

                    // setup next loop around
                    bufferRead        = lbuffer.SizeRead;
                    uncompressedRead += (ulong)bufferRead;
                    whichBuffer       = !whichBuffer;
                }

                // tell all the workers we are finished
                lbuffer.Finish();
                crc32.Finish();
                md5.Finish();
                sha1.Finish();

                // get the results
                byte[] testcrc  = crc32.Hash;
                byte[] testmd5  = md5.Hash;
                byte[] testsha1 = sha1.Hash;

                // cleanup
                lbuffer.Dispose();
                crc32.Dispose();
                md5.Dispose();
                sha1.Dispose();

                ds.Close();
                ds.Dispose();

                if (uncompressedSize != 0)
                {
                    if (uncompressedSize != uncompressedRead)
                    {
                        _zipFs.Close();
                        return(ZipReturn.ZipDecodeError);
                    }
                }
                else
                {
                    uncompressedSize = uncompressedRead;
                }

                if (crc != null)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        if (crc[i] == testcrc[i])
                        {
                            continue;
                        }

                        _zipFs.Close();
                        return(ZipReturn.ZipDecodeError);
                    }
                }
                else
                {
                    crc = testcrc;
                }

                if (md5Hash != null)
                {
                    for (int i = 0; i < 16; i++)
                    {
                        if (md5Hash[i] == testmd5[i])
                        {
                            continue;
                        }

                        _zipFs.Close();
                        return(ZipReturn.ZipDecodeError);
                    }
                }
                else
                {
                    md5Hash = testmd5;
                }

                if (sha1Hash != null)
                {
                    for (int i = 0; i < 20; i++)
                    {
                        if (sha1Hash[i] == testsha1[i])
                        {
                            continue;
                        }

                        _zipFs.Close();
                        return(ZipReturn.ZipDecodeError);
                    }
                }
                else
                {
                    sha1Hash = testsha1;
                }
            }

            _zipFs.Position = _zipFs.Length - 8;
            byte[] gzcrc;
            uint   gzLength;

            using (BinaryReader zipBr = new BinaryReader(_zipFs, Encoding.UTF8, true))
            {
                gzcrc    = zipBr.ReadBytes(4);
                gzLength = zipBr.ReadUInt32();
            }

            if (crc != null)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (gzcrc[3 - i] == crc[i])
                    {
                        continue;
                    }

                    _zipFs.Close();
                    return(ZipReturn.ZipDecodeError);
                }
            }
            else
            {
                crc = new[] { gzcrc[3], gzcrc[2], gzcrc[1], gzcrc[0] };
            }

            if (uncompressedSize != 0)
            {
                if (gzLength != (uncompressedSize & 0xffffffff))
                {
                    _zipFs.Close();
                    return(ZipReturn.ZipDecodeError);
                }
            }

            return(ZipReturn.ZipGood);
        }
示例#2
0
        /// <summary>
        /// Retrieve file information for a single file
        /// </summary>
        /// <param name="input">Filename to get information from</param>
        /// <param name="size">Size of the input stream</param>
        /// <param name="hashes">Hashes to include in the information</param>
        /// <param name="keepReadOpen">True if the underlying read stream should be kept open, false otherwise</param>
        /// <returns>Populated BaseFile object if success, empty one on error</returns>
        public static BaseFile GetInfo(Stream input, long size = -1, Hash hashes = Hash.Standard, bool keepReadOpen = false)
        {
            // If we want to automatically set the size
            if (size == -1)
            {
                size = input.Length;
            }

            try
            {
                // Get a list of hashers to run over the buffer
                List <Hasher> hashers = new List <Hasher>();

                if (hashes.HasFlag(Hash.CRC))
                {
                    hashers.Add(new Hasher(Hash.CRC));
                }
                if (hashes.HasFlag(Hash.MD5))
                {
                    hashers.Add(new Hasher(Hash.MD5));
                }
                if (hashes.HasFlag(Hash.SHA1))
                {
                    hashers.Add(new Hasher(Hash.SHA1));
                }
                if (hashes.HasFlag(Hash.SHA256))
                {
                    hashers.Add(new Hasher(Hash.SHA256));
                }
                if (hashes.HasFlag(Hash.SHA384))
                {
                    hashers.Add(new Hasher(Hash.SHA384));
                }
                if (hashes.HasFlag(Hash.SHA512))
                {
                    hashers.Add(new Hasher(Hash.SHA512));
                }
                if (hashes.HasFlag(Hash.SpamSum))
                {
                    hashers.Add(new Hasher(Hash.SpamSum));
                }

                // Initialize the hashing helpers
                var    loadBuffer = new ThreadLoadBuffer(input);
                int    buffersize = 3 * 1024 * 1024;
                byte[] buffer0    = new byte[buffersize];
                byte[] buffer1    = new byte[buffersize];

                /*
                 * Please note that some of the following code is adapted from
                 * RomVault. This is a modified version of how RomVault does
                 * threaded hashing. As such, some of the terminology and code
                 * is the same, though variable names and comments may have
                 * been tweaked to better fit this code base.
                 */

                // Pre load the first buffer
                long refsize = size;
                int  next    = refsize > buffersize ? buffersize : (int)refsize;
                input.Read(buffer0, 0, next);
                int current = next;
                refsize -= next;
                bool bufferSelect = true;

                while (current > 0)
                {
                    // Trigger the buffer load on the second buffer
                    next = refsize > buffersize ? buffersize : (int)refsize;
                    if (next > 0)
                    {
                        loadBuffer.Trigger(bufferSelect ? buffer1 : buffer0, next);
                    }

                    byte[] buffer = bufferSelect ? buffer0 : buffer1;

                    // Run hashes in parallel
                    Parallel.ForEach(hashers, Globals.ParallelOptions, h => h.Process(buffer, current));

                    // Wait for the load buffer worker, if needed
                    if (next > 0)
                    {
                        loadBuffer.Wait();
                    }

                    // Setup for the next hashing step
                    current      = next;
                    refsize     -= next;
                    bufferSelect = !bufferSelect;
                }

                // Finalize all hashing helpers
                loadBuffer.Finish();
                Parallel.ForEach(hashers, Globals.ParallelOptions, h => h.Terminate());

                // Get the results
                BaseFile baseFile = new BaseFile()
                {
                    Size    = size,
                    CRC     = hashes.HasFlag(Hash.CRC) ? hashers.First(h => h.HashType == Hash.CRC).GetHash() : null,
                    MD5     = hashes.HasFlag(Hash.MD5) ? hashers.First(h => h.HashType == Hash.MD5).GetHash() : null,
                    SHA1    = hashes.HasFlag(Hash.SHA1) ? hashers.First(h => h.HashType == Hash.SHA1).GetHash() : null,
                    SHA256  = hashes.HasFlag(Hash.SHA256) ? hashers.First(h => h.HashType == Hash.SHA256).GetHash() : null,
                    SHA384  = hashes.HasFlag(Hash.SHA384) ? hashers.First(h => h.HashType == Hash.SHA384).GetHash() : null,
                    SHA512  = hashes.HasFlag(Hash.SHA512) ? hashers.First(h => h.HashType == Hash.SHA512).GetHash() : null,
                    SpamSum = hashes.HasFlag(Hash.SpamSum) ? hashers.First(h => h.HashType == Hash.SpamSum).GetHash() : null,
                };

                // Dispose of the hashers
                loadBuffer.Dispose();
                hashers.ForEach(h => h.Dispose());

                return(baseFile);
            }
            catch (IOException ex)
            {
                LoggerImpl.Warning(ex, "An exception occurred during hashing.");
                return(new BaseFile());
            }
            finally
            {
                if (!keepReadOpen)
                {
                    input.Dispose();
                }
                else
                {
                    input.SeekIfPossible();
                }
            }
        }
示例#3
0
        public static int CheckSumRead(string filename, bool testDeep, out byte[] crc, out byte[] bMD5, out byte[] bSHA1)
        {
            bMD5  = null;
            bSHA1 = null;
            crc   = null;

            Stream           ds      = null;
            ThreadLoadBuffer lbuffer = null;
            ThreadCRC        tcrc32  = null;
            ThreadMD5        tmd5    = null;
            ThreadSHA1       tsha1   = null;

            try
            {
                int errorCode = FileStream.OpenFileRead(filename, out ds);
                if (errorCode != 0)
                {
                    return(errorCode);
                }

                lbuffer = new ThreadLoadBuffer(ds);
                tcrc32  = new ThreadCRC();
                if (testDeep)
                {
                    tmd5  = new ThreadMD5();
                    tsha1 = new ThreadSHA1();
                }

                long sizetogo = ds.Length;

                // Pre load the first buffer0
                int sizeNext = sizetogo > Buffersize ? Buffersize : (int)sizetogo;
                ds.Read(Buffer0, 0, sizeNext);
                int sizebuffer = sizeNext;
                sizetogo -= sizeNext;
                bool whichBuffer = true;

                while ((sizebuffer > 0) && !lbuffer.errorState)
                {
                    sizeNext = sizetogo > Buffersize ? Buffersize : (int)sizetogo;

                    if (sizeNext > 0)
                    {
                        lbuffer.Trigger(whichBuffer ? Buffer1 : Buffer0, sizeNext);
                    }

                    byte[] buffer = whichBuffer ? Buffer0 : Buffer1;
                    tcrc32.Trigger(buffer, sizebuffer);
                    tmd5?.Trigger(buffer, sizebuffer);
                    tsha1?.Trigger(buffer, sizebuffer);

                    if (sizeNext > 0)
                    {
                        lbuffer.Wait();
                    }
                    tcrc32.Wait();
                    tmd5?.Wait();
                    tsha1?.Wait();

                    sizebuffer  = sizeNext;
                    sizetogo   -= sizeNext;
                    whichBuffer = !whichBuffer;
                }

                lbuffer.Finish();
                tcrc32.Finish();
                tmd5?.Finish();
                tsha1?.Finish();

                ds.Close();
            }
            catch
            {
                ds?.Close();
                lbuffer?.Dispose();
                tcrc32?.Dispose();
                tmd5?.Dispose();
                tsha1?.Dispose();

                return(0x17); // need to remember what this number is for
            }

            if (lbuffer.errorState)
            {
                ds?.Close();
                lbuffer?.Dispose();
                tcrc32?.Dispose();
                tmd5?.Dispose();
                tsha1?.Dispose();

                return(0x17); // need to remember what this number is for
            }

            crc = tcrc32.Hash;
            if (testDeep)
            {
                bMD5  = tmd5.Hash;
                bSHA1 = tsha1.Hash;
            }

            lbuffer.Dispose();
            tcrc32.Dispose();
            tmd5?.Dispose();
            tsha1?.Dispose();

            return(0);
        }
示例#4
0
        private int CheckSumRead(Stream inStream, FileResults fileResults, ulong totalSize, bool testcrc, bool testDeep)
        {
            if (_buffer0 == null)
            {
                _buffer0 = new byte[Buffersize];
                _buffer1 = new byte[Buffersize];
            }

            fileResults.MD5  = null;
            fileResults.SHA1 = null;
            fileResults.CRC  = null;

            ThreadLoadBuffer lbuffer = null;

            ThreadCRC  tcrc32 = null;
            ThreadMD5  tmd5   = null;
            ThreadSHA1 tsha1  = null;

            ThreadCRC  altCrc32 = null;
            ThreadMD5  altMd5   = null;
            ThreadSHA1 altSha1  = null;

            try
            {
                int  maxHeaderSize = 128;
                long sizetogo      = (long)totalSize;
                int  sizenow       = maxHeaderSize < sizetogo ? maxHeaderSize : (int)sizetogo;
                inStream.Read(_buffer0, 0, sizenow);
                fileResults.HeaderFileType = FileHeaderReader.GetType(_buffer0, sizenow, out int actualHeaderSize);


                // if the file has no header then just use the main hash checkers.
                if (fileResults.HeaderFileType == HeaderFileType.Nothing || actualHeaderSize == 0)
                {
                    // no header found & not reading hashes.
                    if (!(testcrc || testDeep))
                    {
                        return(0);
                    }

                    // no header found so just push the initial buffer read into the hash checkers.
                    // and then continue with the rest of the file.
                    tcrc32 = new ThreadCRC();
                    if (testDeep)
                    {
                        tmd5  = new ThreadMD5();
                        tsha1 = new ThreadSHA1();
                    }
                    tcrc32.Trigger(_buffer0, sizenow);
                    tmd5?.Trigger(_buffer0, sizenow);
                    tsha1?.Trigger(_buffer0, sizenow);
                    tcrc32.Wait();
                    tmd5?.Wait();
                    tsha1?.Wait();

                    sizetogo -= sizenow;
                }
                else
                {
                    // header found
                    fileResults.AltSize = (ulong)((long)totalSize - actualHeaderSize);
                    //setup main hash checkers
                    if (testcrc || testDeep)
                    {
                        tcrc32 = new ThreadCRC();
                    }

                    altCrc32 = new ThreadCRC();
                    if (testDeep)
                    {
                        tmd5    = new ThreadMD5();
                        tsha1   = new ThreadSHA1();
                        altMd5  = new ThreadMD5();
                        altSha1 = new ThreadSHA1();
                    }

                    if (sizenow > actualHeaderSize)
                    {
                        // Already read more than the header, so we need to split what we read into the 2 hash checkers

                        // first scan the header part from what we have already read.
                        // scan what we read so far with just the main hashers
                        tcrc32?.Trigger(_buffer0, actualHeaderSize);
                        tmd5?.Trigger(_buffer0, actualHeaderSize);
                        tsha1?.Trigger(_buffer0, actualHeaderSize);
                        tcrc32?.Wait();
                        tmd5?.Wait();
                        tsha1?.Wait();

                        // put the rest of what we read into the second buffer, and scan with all hashers
                        int restSize = sizenow - actualHeaderSize;
                        for (int i = 0; i < restSize; i++)
                        {
                            _buffer1[i] = _buffer0[actualHeaderSize + i];
                        }
                        tcrc32?.Trigger(_buffer1, restSize);
                        tmd5?.Trigger(_buffer1, restSize);
                        tsha1?.Trigger(_buffer1, restSize);
                        altCrc32.Trigger(_buffer1, restSize);
                        altMd5?.Trigger(_buffer1, restSize);
                        altSha1?.Trigger(_buffer1, restSize);

                        tcrc32?.Wait();
                        tmd5?.Wait();
                        tsha1?.Wait();
                        altCrc32.Wait();
                        altMd5?.Wait();
                        altSha1?.Wait();

                        sizetogo -= sizenow;
                    }
                    else
                    {
                        // Read less than the length of the header so read the rest of the header.
                        // then continue to reader the full rest of the file.

                        // scan what we read so far
                        tcrc32?.Trigger(_buffer0, sizenow);
                        tmd5?.Trigger(_buffer0, sizenow);
                        tsha1?.Trigger(_buffer0, sizenow);
                        tcrc32?.Wait();
                        tmd5?.Wait();
                        tsha1?.Wait();

                        sizetogo -= sizenow;

                        // now read the rest of the header.
                        sizenow = actualHeaderSize - sizenow;
                        inStream.Read(_buffer0, 0, sizenow);

                        // scan the rest of the header
                        tcrc32?.Trigger(_buffer0, sizenow);
                        tmd5?.Trigger(_buffer0, sizenow);
                        tsha1?.Trigger(_buffer0, sizenow);
                        tcrc32?.Wait();
                        tmd5?.Wait();
                        tsha1?.Wait();

                        sizetogo -= sizenow;
                    }
                }

                lbuffer = new ThreadLoadBuffer(inStream);

                // Pre load the first buffer0
                int sizeNext = sizetogo > Buffersize ? Buffersize : (int)sizetogo;
                inStream.Read(_buffer0, 0, sizeNext);
                int sizebuffer = sizeNext;
                sizetogo -= sizeNext;
                bool whichBuffer = true;

                while (sizebuffer > 0 && !lbuffer.errorState)
                {
                    sizeNext = sizetogo > Buffersize ? Buffersize : (int)sizetogo;

                    if (sizeNext > 0)
                    {
                        lbuffer.Trigger(whichBuffer ? _buffer1 : _buffer0, sizeNext);
                    }

                    byte[] buffer = whichBuffer ? _buffer0 : _buffer1;
                    tcrc32?.Trigger(buffer, sizebuffer);
                    tmd5?.Trigger(buffer, sizebuffer);
                    tsha1?.Trigger(buffer, sizebuffer);

                    altCrc32?.Trigger(buffer, sizebuffer);
                    altMd5?.Trigger(buffer, sizebuffer);
                    altSha1?.Trigger(buffer, sizebuffer);


                    if (sizeNext > 0)
                    {
                        lbuffer.Wait();
                    }
                    tcrc32?.Wait();
                    tmd5?.Wait();
                    tsha1?.Wait();
                    altCrc32?.Wait();
                    altMd5?.Wait();
                    altSha1?.Wait();

                    sizebuffer  = sizeNext;
                    sizetogo   -= sizeNext;
                    whichBuffer = !whichBuffer;
                }

                lbuffer.Finish();
                tcrc32?.Finish();
                tmd5?.Finish();
                tsha1?.Finish();
                altCrc32?.Finish();
                altMd5?.Finish();
                altSha1?.Finish();
            }
            catch
            {
                lbuffer?.Dispose();
                tcrc32?.Dispose();
                tmd5?.Dispose();
                tsha1?.Dispose();
                altCrc32?.Dispose();
                altMd5?.Dispose();
                altSha1?.Dispose();

                return(0x17); // need to remember what this number is for
            }

            if (lbuffer.errorState)
            {
                lbuffer.Dispose();
                tcrc32?.Dispose();
                tmd5?.Dispose();
                tsha1?.Dispose();
                altCrc32?.Dispose();
                altMd5?.Dispose();
                altSha1?.Dispose();

                return(0x17); // need to remember what this number is for
            }

            fileResults.CRC     = tcrc32?.Hash;
            fileResults.SHA1    = tsha1?.Hash;
            fileResults.MD5     = tmd5?.Hash;
            fileResults.AltCRC  = altCrc32?.Hash;
            fileResults.AltSHA1 = altSha1?.Hash;
            fileResults.AltMD5  = altMd5?.Hash;

            lbuffer.Dispose();
            tcrc32?.Dispose();
            tmd5?.Dispose();
            tsha1?.Dispose();
            altCrc32?.Dispose();
            altMd5?.Dispose();
            altSha1?.Dispose();

            return(0);
        }
示例#5
0
        /// <summary>
        /// Get hashes from an input file path
        /// </summary>
        /// <param name="filename">Path to the input file</param>
        /// <returns>True if hashing was successful, false otherwise</returns>
        protected static bool GetFileHashes(string filename, out long size, out string crc32, out string md5, out string sha1)
        {
            // Set all initial values
            size = -1; crc32 = null; md5 = null; sha1 = null;

            // If the file doesn't exist, we can't do anything
            if (!File.Exists(filename))
            {
                return(false);
            }

            // Set the file size
            size = new FileInfo(filename).Length;

            // Open the input file
            var input = File.OpenRead(filename);

            try
            {
                // Get a list of hashers to run over the buffer
                List <Hasher> hashers = new List <Hasher>
                {
                    new Hasher(Hash.CRC),
                    new Hasher(Hash.MD5),
                    new Hasher(Hash.SHA1),
                    new Hasher(Hash.SHA256),
                    new Hasher(Hash.SHA384),
                    new Hasher(Hash.SHA512),
                };

                // Initialize the hashing helpers
                var    loadBuffer = new ThreadLoadBuffer(input);
                int    buffersize = 3 * 1024 * 1024;
                byte[] buffer0    = new byte[buffersize];
                byte[] buffer1    = new byte[buffersize];

                /*
                 * Please note that some of the following code is adapted from
                 * RomVault. This is a modified version of how RomVault does
                 * threaded hashing. As such, some of the terminology and code
                 * is the same, though variable names and comments may have
                 * been tweaked to better fit this code base.
                 */

                // Pre load the first buffer
                long refsize = size;
                int  next    = refsize > buffersize ? buffersize : (int)refsize;
                input.Read(buffer0, 0, next);
                int current = next;
                refsize -= next;
                bool bufferSelect = true;

                while (current > 0)
                {
                    // Trigger the buffer load on the second buffer
                    next = refsize > buffersize ? buffersize : (int)refsize;
                    if (next > 0)
                    {
                        loadBuffer.Trigger(bufferSelect ? buffer1 : buffer0, next);
                    }

                    byte[] buffer = bufferSelect ? buffer0 : buffer1;

                    // Run hashes in parallel
                    Parallel.ForEach(hashers, h => h.Process(buffer, current));

                    // Wait for the load buffer worker, if needed
                    if (next > 0)
                    {
                        loadBuffer.Wait();
                    }

                    // Setup for the next hashing step
                    current      = next;
                    refsize     -= next;
                    bufferSelect = !bufferSelect;
                }

                // Finalize all hashing helpers
                loadBuffer.Finish();
                Parallel.ForEach(hashers, h => h.Terminate());

                // Get the results
                crc32 = hashers.First(h => h.HashType == Hash.CRC).GetHashString();
                md5   = hashers.First(h => h.HashType == Hash.MD5).GetHashString();
                sha1  = hashers.First(h => h.HashType == Hash.SHA1).GetHashString();
                //sha256 = hashers.First(h => h.HashType == Hash.SHA256).GetHashString();
                //sha384 = hashers.First(h => h.HashType == Hash.SHA384).GetHashString();
                //sha512 = hashers.First(h => h.HashType == Hash.SHA512).GetHashString();

                // Dispose of the hashers
                loadBuffer.Dispose();
                hashers.ForEach(h => h.Dispose());

                return(true);
            }
            catch (IOException ex)
            {
                return(false);
            }
            finally
            {
                input.Dispose();
            }

            return(false);
        }
示例#6
0
        public void DeepScan()
        {
            if (_buffer0 == null)
            {
                _buffer0 = new byte[Buffersize];
                _buffer1 = new byte[Buffersize];
            }

            for (int index = 0; index < _localFiles.Count; index++)
            {
                if (_localFiles[index].isDirectory || (_localFiles[index].UncompressedSize == 0))
                {
                    _localFiles[index].md5 = new byte[]
                    { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
                    _localFiles[index].sha1 = new byte[]
                    {
                        0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
                        0xaf, 0xd8, 0x07, 0x09
                    };
                    _localFiles[index].FileStatus = ZipReturn.ZipGood;

                    continue;
                }

                ulong     sizetogo;
                Stream    inStream;
                ZipReturn zr = ZipFileOpenReadStream(index, out inStream, out sizetogo);
                if (zr != ZipReturn.ZipGood)
                {
                    continue;
                }

                if (inStream == null)
                {
                    continue;
                }


                ThreadLoadBuffer lbuffer = new ThreadLoadBuffer(inStream);
                ThreadCRC        tcrc32  = new ThreadCRC();
                ThreadMD5        tmd5    = new ThreadMD5();
                ThreadSHA1       tsha1   = new ThreadSHA1();

                // Pre load the first buffer0
                int sizeNext = sizetogo > Buffersize ? Buffersize : (int)sizetogo;
                inStream.Read(_buffer0, 0, sizeNext);
                int sizebuffer = sizeNext;
                sizetogo -= (ulong)sizeNext;
                bool whichBuffer = true;

                while ((sizebuffer > 0) && !lbuffer.errorState)
                {
                    sizeNext = sizetogo > Buffersize ? Buffersize : (int)sizetogo;

                    if (sizeNext > 0)
                    {
                        lbuffer.Trigger(whichBuffer ? _buffer1 : _buffer0, sizeNext);
                    }

                    byte[] buffer = whichBuffer ? _buffer0 : _buffer1;
                    tcrc32.Trigger(buffer, sizebuffer);
                    tmd5.Trigger(buffer, sizebuffer);
                    tsha1.Trigger(buffer, sizebuffer);

                    if (sizeNext > 0)
                    {
                        lbuffer.Wait();
                    }
                    tcrc32.Wait();
                    tmd5.Wait();
                    tsha1.Wait();

                    sizebuffer  = sizeNext;
                    sizetogo   -= (ulong)sizeNext;
                    whichBuffer = !whichBuffer;
                }

                if (lbuffer.errorState)
                {
                    lbuffer.Dispose();
                    tcrc32.Dispose();
                    tmd5.Dispose();
                    tsha1.Dispose();
                    _localFiles[index].FileStatus = ZipReturn.ZipDecodeError;
                    continue;
                }

                lbuffer.Finish();
                tcrc32.Finish();
                tmd5.Finish();
                tsha1.Finish();

                byte[] testcrc = tcrc32.Hash;
                _localFiles[index].md5  = tmd5.Hash;
                _localFiles[index].sha1 = tsha1.Hash;

                lbuffer.Dispose();
                tcrc32.Dispose();
                tmd5.Dispose();
                tsha1.Dispose();

                _localFiles[index].FileStatus = Util.ByteArrCompare(_localFiles[index].crc, testcrc)
                    ? ZipReturn.ZipGood
                    : ZipReturn.ZipCRCDecodeError;
            }
        }
示例#7
0
        /// <summary>
        /// Retrieve file information for a single file
        /// </summary>
        /// <param name="input">Filename to get information from</param>
        /// <returns>Formatted string representing the hashes, null on error</returns>
        public static string GetInfo(string input)
        {
            // If the file doesn't exist, return null
            if (!File.Exists(input))
            {
                return(null);
            }

            // Get the file length
            long size = new FileInfo(input).Length;

            // Open the file
            Stream inputStream = File.OpenRead(input);

            try
            {
                // Get a list of hashers to run over the buffer
                List <Hasher> hashers = new List <Hasher>
                {
                    new Hasher(Hash.CRC),
                    new Hasher(Hash.MD5),
                    new Hasher(Hash.SHA1),
                    new Hasher(Hash.SHA256),
                };

                // Initialize the hashing helpers
                var    loadBuffer = new ThreadLoadBuffer(inputStream);
                int    buffersize = 3 * 1024 * 1024;
                byte[] buffer0    = new byte[buffersize];
                byte[] buffer1    = new byte[buffersize];

                /*
                 * Please note that some of the following code is adapted from
                 * RomVault. This is a modified version of how RomVault does
                 * threaded hashing. As such, some of the terminology and code
                 * is the same, though variable names and comments may have
                 * been tweaked to better fit this code base.
                 */

                // Pre load the first buffer
                long refsize = size;
                int  next    = refsize > buffersize ? buffersize : (int)refsize;
                inputStream.Read(buffer0, 0, next);
                int current = next;
                refsize -= next;
                bool bufferSelect = true;

                while (current > 0)
                {
                    // Trigger the buffer load on the second buffer
                    next = refsize > buffersize ? buffersize : (int)refsize;
                    if (next > 0)
                    {
                        loadBuffer.Trigger(bufferSelect ? buffer1 : buffer0, next);
                    }

                    byte[] buffer = bufferSelect ? buffer0 : buffer1;

                    // Run hashes in parallel
                    Parallel.ForEach(hashers, h => h.Process(buffer, current));

                    // Wait for the load buffer worker, if needed
                    if (next > 0)
                    {
                        loadBuffer.Wait();
                    }

                    // Setup for the next hashing step
                    current      = next;
                    refsize     -= next;
                    bufferSelect = !bufferSelect;
                }

                // Finalize all hashing helpers
                loadBuffer.Finish();
                Parallel.ForEach(hashers, h => h.Terminate());

                // Get the results
                string result = $"Size: {size}\n"
                                + $"CRC32: {ByteArrayToString(hashers.First(h => h.HashType == Hash.CRC).GetHash()) ?? ""}\n"
                                + $"MD5: {ByteArrayToString(hashers.First(h => h.HashType == Hash.MD5).GetHash()) ?? ""}\n"
                                + $"SHA1: {ByteArrayToString(hashers.First(h => h.HashType == Hash.SHA1).GetHash()) ?? ""}\n"
                                + $"SHA256: {ByteArrayToString(hashers.First(h => h.HashType == Hash.SHA256).GetHash()) ?? ""}\n";

                // Dispose of the hashers
                loadBuffer.Dispose();
                hashers.ForEach(h => h.Dispose());

                return(result);
            }
            catch
            {
                return(null);
            }
            finally
            {
                inputStream.Dispose();
            }
        }