From f402d8272c253efdefaf76e697ff826d99f413f1 Mon Sep 17 00:00:00 2001 From: morkt Date: Mon, 29 Jan 2018 03:49:43 +0400 Subject: [PATCH] (ZIP): switched to #ZipLib because Net library does not support encrypted archives. --- ArcFormats/ArcFormats.csproj | 7 ++++++ ArcFormats/ArcZIP.cs | 46 +++++++++++++++++++++++------------- ArcFormats/app.config | 27 ++++++++++++++++++--- ArcFormats/packages.config | 4 ++++ 4 files changed, 65 insertions(+), 19 deletions(-) diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj index 0f65c022..e26c3db1 100644 --- a/ArcFormats/ArcFormats.csproj +++ b/ArcFormats/ArcFormats.csproj @@ -67,7 +67,14 @@ + + ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll + + + ..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + diff --git a/ArcFormats/ArcZIP.cs b/ArcFormats/ArcZIP.cs index 4c960b0a..825d7c61 100644 --- a/ArcFormats/ArcZIP.cs +++ b/ArcFormats/ArcZIP.cs @@ -32,34 +32,37 @@ using System.Linq; using System.Text; using GameRes.Formats.Strings; +using SharpZip = ICSharpCode.SharpZipLib.Zip; + namespace GameRes.Formats.PkWare { internal class ZipEntry : PackedEntry { - public readonly ZipArchiveEntry NativeEntry; + public readonly SharpZip.ZipEntry NativeEntry; - public ZipEntry (ZipArchiveEntry zip_entry) + public ZipEntry (SharpZip.ZipEntry zip_entry) { NativeEntry = zip_entry; - Name = zip_entry.FullName; - Type = FormatCatalog.Instance.GetTypeFromName (zip_entry.FullName); + Name = zip_entry.Name; + Type = FormatCatalog.Instance.GetTypeFromName (zip_entry.Name); IsPacked = true; // design decision of having 32bit entry sizes was made early during GameRes // library development. nevertheless, large files will be extracted correctly // despite the fact that size is reported as uint.MaxValue, because extraction is // performed by .Net framework based on real size value. - Size = (uint)Math.Min (zip_entry.CompressedLength, uint.MaxValue); - UnpackedSize = (uint)Math.Min (zip_entry.Length, uint.MaxValue); - // offset is unknown and reported as '0' for all files. - Offset = 0; + Size = (uint)Math.Min (zip_entry.CompressedSize, uint.MaxValue); + UnpackedSize = (uint)Math.Min (zip_entry.Size, uint.MaxValue); + Offset = zip_entry.Offset; } } internal class PkZipArchive : ArcFile { - readonly ZipArchive m_zip; + readonly SharpZip.ZipFile m_zip; - public PkZipArchive (ArcView arc, ArchiveFormat impl, ICollection dir, ZipArchive native) + public SharpZip.ZipFile Native { get { return m_zip; } } + + public PkZipArchive (ArcView arc, ArchiveFormat impl, ICollection dir, SharpZip.ZipFile native) : base (arc, impl, dir) { m_zip = native; @@ -72,7 +75,7 @@ namespace GameRes.Formats.PkWare if (!_zip_disposed) { if (disposing) - m_zip.Dispose(); + m_zip.Close(); _zip_disposed = true; } base.Dispose (disposing); @@ -109,23 +112,29 @@ namespace GameRes.Formats.PkWare internal ArcFile OpenZipArchive (ArcView file, Stream input) { - var zip = new ZipArchive (input, ZipArchiveMode.Read, false, Encodings.cp932); + SharpZip.ZipConstants.DefaultCodePage = Properties.Settings.Default.ZIPEncodingCP; + var zip = new SharpZip.ZipFile (input); try { - var dir = zip.Entries.Where (z => !z.FullName.EndsWith ("/")) - .Select (z => new ZipEntry (z) as Entry).ToList(); + var files = zip.Cast().Where (z => !z.IsDirectory); + bool has_encrypted = files.Any (z => z.IsCrypted); + if (has_encrypted) + zip.Password = QueryPassword (file); + var dir = files.Select (z => new ZipEntry (z) as Entry).ToList(); return new PkZipArchive (file, this, dir, zip); } catch { - zip.Dispose(); + zip.Close(); throw; } } public override Stream OpenEntry (ArcFile arc, Entry entry) { - return ((ZipEntry)entry).NativeEntry.Open(); + var zarc = (PkZipArchive)arc; + var zent = (ZipEntry)entry; + return zarc.Native.GetInputStream (zent.NativeEntry); } /// @@ -156,6 +165,11 @@ namespace GameRes.Formats.PkWare } } + string QueryPassword (ArcView file) + { + return ""; // TODO + } + public override ResourceOptions GetDefaultOptions () { Encoding enc; diff --git a/ArcFormats/app.config b/ArcFormats/app.config index a39c7467..8acef89e 100644 --- a/ArcFormats/app.config +++ b/ArcFormats/app.config @@ -1,8 +1,8 @@ - + -
+
@@ -180,4 +180,25 @@ - + + + + + + + + + + + + + + + + + + + + + + diff --git a/ArcFormats/packages.config b/ArcFormats/packages.config index 277c5f0d..396c14ce 100644 --- a/ArcFormats/packages.config +++ b/ArcFormats/packages.config @@ -2,4 +2,8 @@ + + + + \ No newline at end of file