public ZipReturn ZipFileOpen(string newFilename, long timestamp, bool readHeaders) { ZipFileClose(); _pZipStatus = ZipStatus.None; _zip64 = false; _centerDirStart = 0; _centerDirSize = 0; _zipFileInfo = null; try { if (!IO.File.Exists(newFilename)) { ZipFileClose(); return ZipReturn.ZipErrorFileNotFound; } _zipFileInfo = new IO.FileInfo(newFilename); if (_zipFileInfo.LastWriteTime != timestamp) { ZipFileClose(); return ZipReturn.ZipErrorTimeStamp; } int errorCode = IO.FileStream.OpenFileRead(newFilename, out _zipFs); if (errorCode != 0) { ZipFileClose(); if (errorCode == 32) return ZipReturn.ZipFileLocked; return ZipReturn.ZipErrorOpeningFile; } } catch (PathTooLongException) { ZipFileClose(); return ZipReturn.ZipFileNameToLong; } catch (IOException) { ZipFileClose(); return ZipReturn.ZipErrorOpeningFile; } ZipOpen = ZipOpenType.OpenRead; if (!readHeaders) return ZipReturn.ZipGood; try { ZipReturn zRet = FindEndOfCentralDirSignature(); if (zRet != ZipReturn.ZipGood) { ZipFileClose(); return zRet; } long endOfCentralDir = _zipFs.Position; zRet = EndOfCentralDirRead(); if (zRet != ZipReturn.ZipGood) { ZipFileClose(); return zRet; } // check if this is a ZIP64 zip and if it is read the Zip64 End Of Central Dir Info if (_centerDirStart == 0xffffffff || _centerDirSize == 0xffffffff || _localFilesCount == 0xffff) { _zip64 = true; _zipFs.Position = endOfCentralDir - 20; zRet = Zip64EndOfCentralDirectoryLocatorRead(); if (zRet != ZipReturn.ZipGood) { ZipFileClose(); return zRet; } _zipFs.Position = (long)_endOfCenterDir64; zRet = Zip64EndOfCentralDirRead(); if (zRet != ZipReturn.ZipGood) { ZipFileClose(); return zRet; } } bool trrntzip = false; // check if the ZIP has a valid TorrentZip file comment if (_fileComment.Length == 22) { if (GetString(_fileComment).Substring(0, 14) == "TORRENTZIPPED-") { CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true); byte[] buffer = new byte[_centerDirSize]; _zipFs.Position = (long)_centerDirStart; crcCs.Read(buffer, 0, (int)_centerDirSize); crcCs.Flush(); crcCs.Close(); uint r = (uint)crcCs.Crc; crcCs.Dispose(); string tcrc = GetString(_fileComment).Substring(14, 8); string zcrc = r.ToString("X8"); if (String.Compare(tcrc, zcrc, StringComparison.Ordinal) == 0) trrntzip = true; } } // now read the central directory _zipFs.Position = (long)_centerDirStart; _localFiles.Clear(); _localFiles.Capacity = (int)_localFilesCount; for (int i = 0; i < _localFilesCount; i++) { LocalFile lc = new LocalFile(_zipFs); zRet = lc.CenteralDirectoryRead(); if (zRet != ZipReturn.ZipGood) { ZipFileClose(); return zRet; } _zip64 |= lc.Zip64; _localFiles.Add(lc); } for (int i = 0; i < _localFilesCount; i++) { zRet = _localFiles[i].LocalFileHeaderRead(); if (zRet != ZipReturn.ZipGood) { ZipFileClose(); return zRet; } trrntzip &= _localFiles[i].TrrntZip; } // check trrntzip file order if (trrntzip) for (int i = 0; i < _localFilesCount - 1; i++) { if (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 (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) _pZipStatus |= ZipStatus.TrrntZip; return ZipReturn.ZipGood; } catch { ZipFileClose(); return ZipReturn.ZipErrorReadingFile; } }
public void ZipFileClose() { if (ZipOpen == ZipOpenType.Closed) { return; } if (ZipOpen == ZipOpenType.OpenRead) { if (_zipFs != null) { _zipFs.Close(); _zipFs.Dispose(); } ZipOpen = ZipOpenType.Closed; return; } _zip64 = false; bool lTrrntzip = true; _centerDirStart = (ulong)_zipFs.Position; if (_centerDirStart >= 0xffffffff) _zip64 = true; CrcCalculatorStream crcCs = new CrcCalculatorStream(_zipFs, true); foreach (LocalFile t in _localFiles) { t.CenteralDirectoryWrite(crcCs); _zip64 |= t.Zip64; lTrrntzip &= t.TrrntZip; } crcCs.Flush(); crcCs.Close(); _centerDirSize = (ulong)_zipFs.Position - _centerDirStart; _fileComment = lTrrntzip ? GetBytes("TORRENTZIPPED-" + crcCs.Crc.ToString("X8")) : new byte[0]; _pZipStatus = lTrrntzip ? ZipStatus.TrrntZip : ZipStatus.None; crcCs.Dispose(); if (_zip64) { _endOfCenterDir64 = (ulong)_zipFs.Position; Zip64EndOfCentralDirWrite(); Zip64EndOfCentralDirectoryLocatorWrite(); } EndOfCentralDirWrite(); _zipFs.SetLength(_zipFs.Position); _zipFs.Flush(); _zipFs.Close(); _zipFs.Dispose(); _zipFileInfo = new IO.FileInfo(_zipFileInfo.FullName); ZipOpen = ZipOpenType.Closed; }