Beispiel #1
0
        private ZipReturn ZipFileReadHeaders()
        {
            try
            {
                ZipReturn zRet = FindEndOfCentralDirSignature();
                if (zRet != ZipReturn.ZipGood)
                {
                    ZipFileClose();
                    return(zRet);
                }

                ulong endOfCentralDir = (ulong)_zipFs.Position;
                zRet = EndOfCentralDirRead();
                if (zRet != ZipReturn.ZipGood)
                {
                    ZipFileClose();
                    return(zRet);
                }

                // check if ZIP64 header is required
                bool zip64Required = (_centralDirStart == 0xffffffff || _centralDirSize == 0xffffffff || _localFilesCount == 0xffff);

                // check for a ZIP64 header
                _zipFs.Position = (long)endOfCentralDir - 20;
                zRet            = Zip64EndOfCentralDirectoryLocatorRead();
                if (zRet == ZipReturn.ZipGood)
                {
                    _zipFs.Position = (long)_endOfCentralDir64;
                    zRet            = Zip64EndOfCentralDirRead();
                    if (zRet == ZipReturn.ZipGood)
                    {
                        _zip64          = true;
                        endOfCentralDir = _endOfCentralDir64;
                    }
                }

                if (zip64Required && !_zip64)
                {
                    return(ZipReturn.Zip64EndOfCentralDirError);
                }

                offset = (endOfCentralDir - _centralDirSize) - _centralDirStart;

                _centralDirStart += offset;

                bool trrntzip = false;

                // check if the ZIP has a valid TorrentZip file comment
                if (FileComment.Length == 22)
                {
                    if (CompressUtils.GetString(FileComment).Substring(0, 14) == "TORRENTZIPPED-")
                    {
                        CrcCalculatorStream crcCs = new(_zipFs, true);
                        byte[] buffer             = new byte[_centralDirSize];
                        _zipFs.Position = (long)_centralDirStart;
                        crcCs.Read(buffer, 0, (int)_centralDirSize);
                        crcCs.Flush();
                        crcCs.Close();

                        uint r = (uint)crcCs.Crc;
                        crcCs.Dispose();

                        string tcrc = CompressUtils.GetString(FileComment).Substring(14, 8);
                        string zcrc = r.ToString("X8");
                        if (string.Compare(tcrc, zcrc, StringComparison.Ordinal) == 0)
                        {
                            trrntzip = true;
                        }
                    }
                }

                if (zip64Required != _zip64)
                {
                    trrntzip = false;
                }

                // now read the central directory
                _zipFs.Position = (long)_centralDirStart;

                _localFiles.Clear();
                _localFiles.Capacity = (int)_localFilesCount;
                for (int i = 0; i < _localFilesCount; i++)
                {
                    ZipLocalFile lc = new();
                    zRet = lc.CentralDirectoryRead(_zipFs, offset);
                    if (zRet != ZipReturn.ZipGood)
                    {
                        ZipFileClose();
                        return(zRet);
                    }
                    _zip64 |= lc.GetStatus(LocalFileStatus.Zip64);
                    _localFiles.Add(lc);
                }

                for (int i = 0; i < _localFilesCount; i++)
                {
                    zRet = _localFiles[i].LocalFileHeaderRead(_zipFs);
                    if (zRet != ZipReturn.ZipGood)
                    {
                        ZipFileClose();
                        return(zRet);
                    }
                    trrntzip &= _localFiles[i].GetStatus(LocalFileStatus.TrrntZip);
                }

                // check trrntzip file order
                if (trrntzip)
                {
                    for (int i = 0; i < _localFilesCount - 1; i++)
                    {
                        if (CompressUtils.TrrntZipStringCompare(_localFiles[i].Filename, _localFiles[i + 1].Filename) < 0)
                        {
                            continue;
                        }
                        trrntzip = false;
                        break;
                    }
                }

                // check trrntzip directories
                if (trrntzip)
                {
                    for (int i = 0; i < _localFilesCount - 1; i++)
                    {
                        // see if we found a directory
                        string filename0 = _localFiles[i].Filename;
                        if (filename0.Substring(filename0.Length - 1, 1) != "/")
                        {
                            continue;
                        }

                        // see if the next file is in that directory
                        string filename1 = _localFiles[i + 1].Filename;
                        if (filename1.Length <= filename0.Length)
                        {
                            continue;
                        }
                        if (CompressUtils.TrrntZipStringCompare(filename0, filename1.Substring(0, filename0.Length)) != 0)
                        {
                            continue;
                        }

                        // if we found a file in the directory then we do not need the directory entry
                        trrntzip = false;
                        break;
                    }
                }

                if (trrntzip)
                {
                    ZipStatus |= ZipStatus.TrrntZip;
                }

                return(ZipReturn.ZipGood);
            }
            catch
            {
                ZipFileClose();
                return(ZipReturn.ZipErrorReadingFile);
            }
        }
Beispiel #2
0
        internal ZipReturn CentralDirectoryRead(Stream zipFs, ulong offset)
        {
            try
            {
                using BinaryReader br = new(zipFs, Encoding.UTF8, true);
                uint thisSignature = br.ReadUInt32();
                if (thisSignature != CentralDirectoryHeaderSignature)
                {
                    return(ZipReturn.ZipCentralDirError);
                }

                br.ReadUInt16(); // Version Made By

                br.ReadUInt16(); // Version Needed To Extract


                GeneralPurposeBitFlag = br.ReadUInt16();
                _compressionMethod    = br.ReadUInt16();

                ushort lastModFileTime = br.ReadUInt16();
                ushort lastModFileDate = br.ReadUInt16();
                HeaderLastModified = CompressUtils.UtcTicksFromDosDateTime(lastModFileDate, lastModFileTime);

                CRC = ReadCRC(br);

                _compressedSize  = br.ReadUInt32();
                UncompressedSize = br.ReadUInt32();

                ushort fileNameLength    = br.ReadUInt16();
                ushort extraFieldLength  = br.ReadUInt16();
                ushort fileCommentLength = br.ReadUInt16();

                br.ReadUInt16(); // diskNumberStart
                br.ReadUInt16(); // internalFileAttributes
                br.ReadUInt32(); // externalFileAttributes

                RelativeOffsetOfLocalHeader = br.ReadUInt32();


                byte[] bFileName = br.ReadBytes(fileNameLength);
                Filename = (GeneralPurposeBitFlag & (1 << 11)) == 0
                    ? CompressUtils.GetString(bFileName)
                    : Encoding.UTF8.GetString(bFileName, 0, fileNameLength);

                if (extraFieldLength > 0)
                {
                    byte[] extraField = br.ReadBytes(extraFieldLength);

                    ZipReturn zr = ZipExtraField.ReadExtraField(extraField, bFileName, this, ref _compressedSize, ref RelativeOffsetOfLocalHeader, true);
                    if (zr != ZipReturn.ZipGood)
                    {
                        return(zr);
                    }
                }

                RelativeOffsetOfLocalHeader += offset;

                if (CompressUtils.IsCodePage437(Filename) != ((GeneralPurposeBitFlag & (1 << 11)) == 0))
                {
                    SetStatus(LocalFileStatus.TrrntZip, false);
                }

                if (fileCommentLength > 0)
                {
                    byte[] fileComment = br.ReadBytes(fileCommentLength);
                }

                if (Filename.Length > 0)
                {
                    char lastChar = Filename[Filename.Length - 1];
                    IsDirectory = (lastChar == '/' || lastChar == '\\');
                    if (IsDirectory && UncompressedSize > 0)
                    {
                        SetStatus(LocalFileStatus.DirectoryLengthError);
                    }
                }

                /*
                 * 4.4.5 compression method: (2 bytes)
                 *
                 * 0 - (Supported) The file is stored (no compression)
                 * 1 - (Supported) The file is Shrunk
                 * 2 - (Supported) The file is Reduced with compression factor 1
                 * 3 - (Supported) The file is Reduced with compression factor 2
                 * 4 - (Supported) The file is Reduced with compression factor 3
                 * 5 - (Supported) The file is Reduced with compression factor 4
                 * 6 - (Supported) The file is Imploded
                 * 7 - Reserved for Tokenizing compression algorithm
                 * 8 - (Supported) The file is Deflated
                 * 9 - (Supported) Enhanced Deflating using Deflate64(tm)
                 * 10 - PKWARE Data Compression Library Imploding (old IBM TERSE)
                 * 11 - Reserved by PKWARE
                 * 12 - (Supported) File is compressed using BZIP2 algorithm
                 * 13 - Reserved by PKWARE
                 * 14 - (Supported) LZMA
                 * 15 - Reserved by PKWARE
                 * 16 - IBM z/OS CMPSC Compression
                 * 17 - Reserved by PKWARE
                 * 18 - File is compressed using IBM TERSE (new)
                 * 19 - IBM LZ77 z Architecture
                 * 20 - deprecated (use method 93 for zstd)
                 * 93 - (Supported, with external DLL) Zstandard (zstd) Compression
                 * 94 - MP3 Compression
                 * 95 - XZ Compression
                 * 96 - JPEG variant
                 * 97 - WavPack compressed data
                 * 98 - (Supported) PPMd version I, Rev 1
                 * 99 - AE-x encryption marker (see APPENDIX E)
                 */

                switch (_compressionMethod)
                {
                case 0:     // The file is stored (no compression)
                case 8:     // The file is Deflated
                case 9:     // Enhanced Deflating using Deflate64(tm)
                case 12:    // The file is BZIP2 algorithm.
                case 14:    // LZMA
                    return(ZipReturn.ZipGood);

                case 20:
                case 93:     // Zstandard (zstd) Compression
                    return(ZipReturn.ZipGood);

                case 98:     // PPMd version I, Rev 1
                    return(ZipReturn.ZipGood);

                default:
                    return(ZipReturn.ZipUnsupportedCompression);
                }
            }
            catch
            {
                return(ZipReturn.ZipCentralDirError);
            }
        }
Beispiel #3
0
        internal ZipReturn LocalFileHeaderRead(Stream zipFs)
        {
            try
            {
                using (BinaryReader br = new(zipFs, Encoding.UTF8, true))
                {
                    SetStatus(LocalFileStatus.TrrntZip);

                    zipFs.Position = (long)RelativeOffsetOfLocalHeader;
                    uint thisSignature = br.ReadUInt32();
                    if (thisSignature != LocalFileHeaderSignature)
                    {
                        return(ZipReturn.ZipLocalFileHeaderError);
                    }

                    br.ReadUInt16(); // version needed to extract
                    ushort generalPurposeBitFlagLocal = br.ReadUInt16();
                    if (generalPurposeBitFlagLocal != GeneralPurposeBitFlag)
                    {
                        SetStatus(LocalFileStatus.TrrntZip, false);
                    }

                    ushort tshort = br.ReadUInt16();
                    if (tshort != _compressionMethod)
                    {
                        return(ZipReturn.ZipLocalFileHeaderError);
                    }

                    ushort lastModFileTime = br.ReadUInt16();
                    ushort lastModFileDate = br.ReadUInt16();

                    long tTime = CompressUtils.UtcTicksFromDosDateTime(lastModFileDate, lastModFileTime);

                    if (tTime != HeaderLastModified)
                    {
                        SetStatus(LocalFileStatus.DateTimeMisMatch);
                        SetStatus(LocalFileStatus.TrrntZip, false);
                    }

                    LocalFile localHeader = new();
                    localHeader.CRC = ReadCRC(br);
                    ulong localHeaderCompressedSize = br.ReadUInt32();
                    localHeader.UncompressedSize = br.ReadUInt32();
                    ulong localRelativeOffset = 0;

                    ushort fileNameLength   = br.ReadUInt16();
                    ushort extraFieldLength = br.ReadUInt16();


                    byte[] bFileName = br.ReadBytes(fileNameLength);
                    localHeader.Filename = (generalPurposeBitFlagLocal & (1 << 11)) == 0
                        ? CompressUtils.GetString(bFileName)
                        : Encoding.UTF8.GetString(bFileName, 0, fileNameLength);


                    if (extraFieldLength > 0)
                    {
                        byte[] extraField = br.ReadBytes(extraFieldLength);

                        ZipReturn zr = ZipExtraField.ReadExtraField(extraField, bFileName, localHeader, ref localHeaderCompressedSize, ref localRelativeOffset, false);
                        if (zr != ZipReturn.ZipGood)
                        {
                            return(zr);
                        }
                    }

                    if (!CompressUtils.CompareString(Filename, localHeader.Filename))
                    {
                        SetStatus(LocalFileStatus.TrrntZip, false);
                        if (!CompressUtils.CompareStringSlash(Filename.ToLower(), localHeader.Filename.ToLower()))
                        {
                            SetStatus(LocalFileStatus.FilenameMisMatch);
                        }
                    }

                    _dataLocation = (ulong)zipFs.Position;

                    if ((GeneralPurposeBitFlag & 8) == 8)
                    {
                        SetStatus(LocalFileStatus.TrrntZip, false);
                        zipFs.Position += (long)_compressedSize;

                        localHeader.CRC = ReadCRC(br);
                        if (CompressUtils.ByteArrCompare(localHeader.CRC, new byte[] { 0x08, 0x07, 0x4b, 0x50 }))
                        {
                            localHeader.CRC = ReadCRC(br);
                        }

                        if (GetStatus(LocalFileStatus.Zip64))
                        {
                            localHeaderCompressedSize    = br.ReadUInt64();
                            localHeader.UncompressedSize = br.ReadUInt64();
                        }
                        else
                        {
                            localHeaderCompressedSize    = br.ReadUInt32();
                            localHeader.UncompressedSize = br.ReadUInt32();
                        }
                    }

                    if (CompressUtils.IsCodePage437(Filename) != ((GeneralPurposeBitFlag & (1 << 11)) == 0))
                    {
                        SetStatus(LocalFileStatus.TrrntZip, false);
                    }


                    if (!CompressUtils.ByteArrCompare(localHeader.CRC, CRC))
                    {
                        return(ZipReturn.ZipLocalFileHeaderError);
                    }

                    if (localHeaderCompressedSize != _compressedSize)
                    {
                        return(ZipReturn.ZipLocalFileHeaderError);
                    }

                    if (localHeader.UncompressedSize != UncompressedSize)
                    {
                        return(ZipReturn.ZipLocalFileHeaderError);
                    }

                    return(ZipReturn.ZipGood);
                }
            }
            catch
            {
                return(ZipReturn.ZipLocalFileHeaderError);
            }
        }
Beispiel #4
0
        internal ZipReturn LocalFileHeaderReadQuick(Stream zipFs)
        {
            try
            {
                using BinaryReader br = new(zipFs, Encoding.UTF8, true);
                SetStatus(LocalFileStatus.TrrntZip);

                zipFs.Position = (long)RelativeOffsetOfLocalHeader;
                uint thisSignature = br.ReadUInt32();
                if (thisSignature != LocalFileHeaderSignature)
                {
                    return(ZipReturn.ZipLocalFileHeaderError);
                }

                br.ReadUInt16(); // version needed to extract
                GeneralPurposeBitFlag = br.ReadUInt16();
                if ((GeneralPurposeBitFlag & 8) == 8)
                {
                    return(ZipReturn.ZipCannotFastOpen);
                }

                _compressionMethod = br.ReadUInt16();

                ushort lastModFileTime = br.ReadUInt16();
                ushort lastModFileDate = br.ReadUInt16();
                HeaderLastModified = CompressUtils.UtcTicksFromDosDateTime(lastModFileDate, lastModFileTime);

                CRC              = ReadCRC(br);
                _compressedSize  = br.ReadUInt32();
                UncompressedSize = br.ReadUInt32();

                ushort fileNameLength   = br.ReadUInt16();
                ushort extraFieldLength = br.ReadUInt16();

                byte[] bFileName = br.ReadBytes(fileNameLength);

                Filename = (GeneralPurposeBitFlag & (1 << 11)) == 0
                    ? CompressUtils.GetString(bFileName)
                    : Encoding.UTF8.GetString(bFileName, 0, fileNameLength);

                SetStatus(LocalFileStatus.Zip64, false);
                if (extraFieldLength > 0)
                {
                    byte[] extraField = br.ReadBytes(extraFieldLength);

                    ulong     LocalHeader = 0;
                    ZipReturn zr          = ZipExtraField.ReadExtraField(extraField, bFileName, this, ref _compressedSize, ref LocalHeader, false);
                    if (zr != ZipReturn.ZipGood)
                    {
                        return(zr);
                    }
                }

                if (CompressUtils.IsCodePage437(Filename) != ((GeneralPurposeBitFlag & (1 << 11)) == 0))
                {
                    SetStatus(LocalFileStatus.TrrntZip, false);
                }

                _dataLocation = (ulong)zipFs.Position;

                return(ZipReturn.ZipGood);
            }
            catch
            {
                return(ZipReturn.ZipLocalFileHeaderError);
            }
        }
Beispiel #5
0
        private static void AddZip(FileInfo f, DatDir thisDir)
        {
            Zip       zf1    = new Zip();
            ZipReturn result = zf1.ZipFileOpen(f.FullName, -1, true);

            if (result != ZipReturn.ZipGood)
            {
                return;
            }

            zCount += 1;
            if ((zf1.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip)
            {
                tCount += 1;

                Console.WriteLine($"{zCount}   {tCount}    {cCount}");
            }

            else if (zf1.FileComment != null && zf1.FileComment.Length > 0)
            {
                string comments = CompressUtils.GetString(zf1.FileComment);

                if (comments.Length > 13 && comments.Substring(0, 13) == "TORRENTZIPPED")
                {
                    tCount += 1;
                }
                else
                {
                    cCount += 1;
                    Console.WriteLine(f.FullName + "   " + zCount);
                    Console.WriteLine("------------------------");
                    Console.WriteLine(comments);
                }

                Console.WriteLine($"{zCount}   {tCount}    {cCount}");
            }
            //zf1.ZipStatus = ZipStatus.TrrntZip;

            //DatDir ZipDir = new DatDir(zf1.ZipStatus == ZipStatus.TrrntZip ? DatFileType.DirTorrentZip : DatFileType.DirRVZip)
            DatDir ZipDir = new DatDir(DatFileType.UnSet)
            {
                Name  = Path.GetFileNameWithoutExtension(f.Name),
                DGame = new DatGame()
            };

            ZipDir.DGame.Description = ZipDir.Name;
            thisDir.ChildAdd(ZipDir);



            FileScan fs = new FileScan();
            List <FileScan.FileResults> fr = fs.Scan(zf1, !quick, !quick);
            bool isTorrentZipDate          = true;

            for (int i = 0; i < fr.Count; i++)
            {
                LocalFile lf = zf1.GetLocalFile(i);
                if (fr[i].FileStatus != ZipReturn.ZipGood)
                {
                    Console.WriteLine("File Error :" + lf.Filename + " : " + fr[i].FileStatus);
                    continue;
                }

                DatFile df = new DatFile(DatFileType.UnSet)
                {
                    Name         = lf.Filename,
                    Size         = fr[i].Size,
                    CRC          = fr[i].CRC,
                    SHA1         = fr[i].SHA1,
                    DateModified = new DateTime(lf.LastModified).ToString("yyyy/MM/dd HH:mm:ss"),
                    //df.MD5 = zf.MD5(i)
                };
                if (lf.LastModified != 629870671200000000)
                {
                    isTorrentZipDate = false;
                }

                ZipDir.ChildAdd(df);
            }
            zf1.ZipFileClose();
            if (isTorrentZipDate && ZipDir.DatFileType == DatFileType.DirRVZip)
            {
                ZipDir.DatFileType = DatFileType.DirTorrentZip;
            }

            if (ZipDir.DatFileType == DatFileType.DirTorrentZip)
            {
                DatSetCompressionType.SetZip(ZipDir);
                DatClean.RemoveUnNeededDirectoriesFromZip(ZipDir);
            }
        }