Exemplo n.º 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);
        }
Exemplo n.º 2
0
        public ZipReturn WriteGZip(string filename, Stream sInput, bool isCompressedStream)
        {
            Compress.Utils.DirUtil.CreateDirForFile(filename);

            Stream _zipFs;

            FileStream.OpenFileWrite(filename, out _zipFs);
            using (BinaryWriter zipBw = new BinaryWriter(_zipFs, Encoding.UTF8, true))
            {
                zipBw.Write((byte)0x1f); // ID1 = 0x1f
                zipBw.Write((byte)0x8b); // ID2 = 0x8b
                zipBw.Write((byte)0x08); // CM  = 0x08
                zipBw.Write((byte)0x04); // FLG = 0x04
                zipBw.Write((uint)0);    // MTime = 0
                zipBw.Write((byte)0x00); // XFL = 0x00
                zipBw.Write((byte)0xff); // OS  = 0x00

                // writing FEXTRA
                if (FileHeaderReader.FileHeaderReader.AltHeaderFile(altType))
                {
                    zipBw.Write((short)77);  // XLEN 16+4+8+1+16+20+4+8
                }
                else
                {
                    zipBw.Write((short)28);  // XLEN 16+4+8
                }

                zipBw.Write(md5Hash);          // 16 bytes
                zipBw.Write(crc);              // 4 bytes
                zipBw.Write(uncompressedSize); // 8 bytes

                if (FileHeaderReader.FileHeaderReader.AltHeaderFile(altType))
                {
                    zipBw.Write((byte)altType);              // 1
                    zipBw.Write(altmd5Hash);                 // 16
                    zipBw.Write(altsha1Hash);                // 20
                    zipBw.Write(altcrc);                     // 4
                    zipBw.Write((ulong)uncompressedAltSize); // 8
                }


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

                ulong dataStartPos = (ulong)zipBw.BaseStream.Position;
                if (isCompressedStream)
                {
                    ulong sizetogo = compressedSize;
                    while (sizetogo > 0)
                    {
                        int sizenow = sizetogo > Buffersize ? Buffersize : (int)sizetogo;
                        sInput.Read(Buffer0, 0, sizenow);
                        _zipFs.Write(Buffer0, 0, sizenow);
                        sizetogo -= (ulong)sizenow;
                    }
                }
                else
                {
                    if (uncompressedSize == 0)
                    {
                        _zipFs.WriteByte(03);
                        _zipFs.WriteByte(00);
                    }
                    else
                    {
                        ulong  sizetogo    = uncompressedSize;
                        Stream writeStream = new ZlibBaseStream(_zipFs, CompressionMode.Compress, CompressionLevel.BestCompression, ZlibStreamFlavor.DEFLATE, true);
                        while (sizetogo > 0)
                        {
                            int sizenow = sizetogo > Buffersize ? Buffersize : (int)sizetogo;
                            sInput.Read(Buffer0, 0, sizenow);
                            writeStream.Write(Buffer0, 0, sizenow);
                            sizetogo -= (ulong)sizenow;
                        }

                        writeStream.Flush();
                        writeStream.Close();
                        writeStream.Dispose();
                    }
                }

                compressedSize = (ulong)zipBw.BaseStream.Position - dataStartPos;

                zipBw.Write(crc[3]);
                zipBw.Write(crc[2]);
                zipBw.Write(crc[1]);
                zipBw.Write(crc[0]);
                zipBw.Write((uint)uncompressedSize);
                zipBw.Flush();
                zipBw.Close();
            }

            _zipFs.Close();

            return(ZipReturn.ZipGood);
        }