From 098180a06075c2d68fc27da6ec645b47618babfd Mon Sep 17 00:00:00 2001 From: Daniel Scharrer <~@ds.me> Date: Tue, 24 Dec 2024 04:03:43 +0100 Subject: [PATCH] Add support for Inno Setup 6.3.x --- CHANGELOG | 1 + README.md | 2 +- VERSION | 2 +- src/setup/data.cpp | 30 +++++++++++++++++++++++++++++- src/setup/data.hpp | 9 +++++++++ src/setup/header.cpp | 15 ++++++++++++++- src/setup/header.hpp | 4 ++++ src/setup/icon.cpp | 2 +- src/setup/run.cpp | 4 ++++ src/setup/run.hpp | 3 ++- src/setup/version.cpp | 4 +++- 11 files changed, 69 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7808e8d..0241869 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ innoextract 1.10 (TBD) + - Added support for Inno Setup 6.3.x installers - Added support for a modified Inno Setup 5.3.10 variant innoextract 1.9 (2020-08-09) diff --git a/README.md b/README.md index ed63a4c..6cae1f5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # innoextract - A tool to unpack installers created by Inno Setup -[Inno Setup](https://jrsoftware.org/isinfo.php) is a tool to create installers for Microsoft Windows applications. innoextract allows to extract such installers under non-Windows systems without running the actual installer using wine. innoextract currently supports installers created by Inno Setup 1.2.10 to 6.2.2. +[Inno Setup](https://jrsoftware.org/isinfo.php) is a tool to create installers for Microsoft Windows applications. innoextract allows to extract such installers under non-Windows systems without running the actual installer using wine. innoextract currently supports installers created by Inno Setup 1.2.10 to 6.3.3. In addition to standard Inno Setup installers, innoextract also supports some modified Inno Setup variants including Martijn Laan's My Inno Setup Extensions 1.3.10 to 3.0.6.1 as well as GOG.com's Inno Setup-based game installers. innoextract is able to unpack Wadjet Eye Games installers (to play with AGS), Arx Fatalis patches (for use with Arx Libertatis) as well as various other Inno Setup executables. diff --git a/VERSION b/VERSION index 365abe5..e2b4fe9 100644 --- a/VERSION +++ b/VERSION @@ -1,7 +1,7 @@ innoextract 1.10-dev Known working Inno Setup versions: -Inno Setup 1.2.10 to 6.2.2 +Inno Setup 1.2.10 to 6.3.3 Bug tracker: https://innoextract.constexpr.org/issues diff --git a/src/setup/data.cpp b/src/setup/data.cpp index 1c8bcf1..f0a037c 100644 --- a/src/setup/data.cpp +++ b/src/setup/data.cpp @@ -32,6 +32,17 @@ namespace setup { +namespace { + +STORED_ENUM_MAP(stored_sign_mode, data_entry::NoSetting, + data_entry::NoSetting, + data_entry::Yes, + data_entry::Once, + data_entry::Check, +); + +} // anonymous namespace + void data_entry::load(std::istream & is, const info & i) { chunk.first_slice = util::load(is, i.version.bits()); @@ -149,7 +160,7 @@ void data_entry::load(std::istream & is, const info & i) { if(i.version >= INNO_VERSION(5, 1, 13)) { flagreader.add(SolidBreak); } - if(i.version >= INNO_VERSION(5, 5, 7)) { + if(i.version >= INNO_VERSION(5, 5, 7) && i.version < INNO_VERSION(6, 3, 0)) { // Actually added in Inno Setup 5.5.9 but the data version was not bumped flagreader.add(Sign); flagreader.add(SignOnce); @@ -157,6 +168,16 @@ void data_entry::load(std::istream & is, const info & i) { options |= flagreader.finalize(); + if(i.version >= INNO_VERSION(6, 3, 0)) { + sign = stored_enum(is).get(); + } else if(options & SignOnce) { + sign = Once; + } else if(options & Sign) { + sign = Yes; + } else { + sign = NoSetting; + } + if(options & ChunkCompressed) { chunk.compression = i.header.compression; } else { @@ -206,3 +227,10 @@ NAMES(setup::data_entry::flags, "File Location Option", "sign once", "bzipped", ) + +NAMES(setup::data_entry::sign_mode, "Sign Mode", + "no setting", + "yes", + "once", + "check", +) diff --git a/src/setup/data.hpp b/src/setup/data.hpp index fcc2374..49dbb9b 100644 --- a/src/setup/data.hpp +++ b/src/setup/data.hpp @@ -74,6 +74,14 @@ struct data_entry { flags options; + enum sign_mode { + NoSetting, + Yes, + Once, + Check + }; + sign_mode sign; + /*! * Load one data entry. * @@ -86,5 +94,6 @@ struct data_entry { } // namespace setup NAMED_FLAGS(setup::data_entry::flags) +NAMED_ENUM(setup::data_entry::sign_mode) #endif // INNOEXTRACT_SETUP_DATA_HPP diff --git a/src/setup/header.cpp b/src/setup/header.cpp index c9919a4..26ea25e 100644 --- a/src/setup/header.cpp +++ b/src/setup/header.cpp @@ -261,6 +261,11 @@ void header::load(std::istream & is, const version & version) { changes_environment.clear(); changes_associations.clear(); } + if(version >= INNO_VERSION(6, 3, 0)) { + // Valid architectures: 'Unknown', 'x86', 'x64', 'Arm32', 'Arm64' + is >> util::binary_string(architectures_allowed_expr); + is >> util::binary_string(architectures_installed_in_64bit_mode_expr); + } if(version >= INNO_VERSION(5, 2, 5)) { is >> util::ansi_string(license_text); is >> util::ansi_string(info_before); @@ -462,7 +467,10 @@ void header::load(std::istream & is, const version & version) { compression = stored_enum(is).get(); } - if(version >= INNO_VERSION(5, 6, 0)) { + if(version >= INNO_VERSION(6, 3, 0)) { + architectures_allowed = 0; // see architectures_allowed_expr + architectures_installed_in_64bit_mode = 0; // see architectures_installed_in_64bit_mode_expr + } else if(version >= INNO_VERSION(5, 6, 0)) { architectures_allowed = stored_flags(is).get(); architectures_installed_in_64bit_mode = stored_flags(is).get(); } else if(version >= INNO_VERSION(5, 1, 0)) { @@ -662,6 +670,9 @@ void header::load(std::istream & is, const version & version) { flagreader.add(UsePreviousPrivileges); flagreader.add(WizardResizable); } + if(version >= INNO_VERSION(6, 3, 0)) { + flagreader.add(UninstallLogging); + } options |= flagreader.finalize(); @@ -792,6 +803,7 @@ NAMES(setup::header::flags, "Setup Option", "app name_has_consts", "use_previous_privileges", "wizard_resizable", + "uninstall_logging", "uninstallable", "disable dir page", "disable program group page", @@ -812,6 +824,7 @@ NAMES(setup::header::architecture_types, "Architecture", "x86", "x64", "Itanium", + "Arm32", "Arm64", ) diff --git a/src/setup/header.hpp b/src/setup/header.hpp index 9a55a10..8dfc5a5 100644 --- a/src/setup/header.hpp +++ b/src/setup/header.hpp @@ -103,6 +103,7 @@ struct header { AppNameHasConsts, UsePreviousPrivileges, WizardResizable, + UninstallLogging, // Obsolete flags Uninstallable, @@ -126,6 +127,7 @@ struct header { X86, Amd64, IA64, + ARM32, ARM64 ); @@ -165,6 +167,8 @@ struct header { std::string setup_mutex; std::string changes_environment; std::string changes_associations; + std::string architectures_allowed_expr; + std::string architectures_installed_in_64bit_mode_expr; std::string license_text; std::string info_before; std::string info_after; diff --git a/src/setup/icon.cpp b/src/setup/icon.cpp index ffb2906..360e3d5 100644 --- a/src/setup/icon.cpp +++ b/src/setup/icon.cpp @@ -97,7 +97,7 @@ void icon_entry::load(std::istream & is, const info & i) { if(i.version.bits() != 16) { flagreader.add(UseAppPaths); } - if(i.version >= INNO_VERSION(5, 0, 3)) { + if(i.version >= INNO_VERSION(5, 0, 3) && i.version < INNO_VERSION(6, 3, 0)) { flagreader.add(FolderShortcut); } if(i.version >= INNO_VERSION(5, 4, 2)) { diff --git a/src/setup/run.cpp b/src/setup/run.cpp index e3f0aee..9fe1bdf 100644 --- a/src/setup/run.cpp +++ b/src/setup/run.cpp @@ -106,6 +106,9 @@ void run_entry::load(std::istream & is, const info & i) { if(i.version >= INNO_VERSION(6, 1, 0)) { flagreader.add(DontLogParameters); } + if(i.version >= INNO_VERSION(6, 3, 0)) { + flagreader.add(LogOutput); + } options = flagreader.finalize(); } @@ -124,6 +127,7 @@ NAMES(setup::run_entry::flags, "Run Option", "64 bit", "run as original user", "don't log parameters", + "log output", ) NAMES(setup::run_entry::wait_condition, "Run Wait Type", diff --git a/src/setup/run.hpp b/src/setup/run.hpp index be832aa..cead27b 100644 --- a/src/setup/run.hpp +++ b/src/setup/run.hpp @@ -50,7 +50,8 @@ struct run_entry : public item { Bits32, Bits64, RunAsOriginalUser, - DontLogParameters + DontLogParameters, + LogOutput ); enum wait_condition { diff --git a/src/setup/version.cpp b/src/setup/version.cpp index 87d90e9..9fa12dd 100644 --- a/src/setup/version.cpp +++ b/src/setup/version.cpp @@ -183,6 +183,7 @@ const known_version versions[] = { { "Inno Setup Setup Data (5.6.2) (u)", /* prerelease */ INNO_VERSION_EXT(5, 6, 2, 0), version::Unicode }, { "Inno Setup Setup Data (6.0.0) (u)", INNO_VERSION_EXT(6, 0, 0, 0), version::Unicode }, { "Inno Setup Setup Data (6.1.0) (u)", INNO_VERSION_EXT(6, 1, 0, 0), version::Unicode }, + { "Inno Setup Setup Data (6.3.0)", INNO_VERSION_EXT(6, 3, 0, 0), version::Unicode }, }; } // anonymous namespace @@ -345,7 +346,8 @@ void version::load(std::istream & is) { } variant = 0; - if(boost::contains(version_str, "(u)") || boost::contains(version_str, "(U)")) { + if(value >= INNO_VERSION(6, 3, 0) || + boost::contains(version_str, "(u)") || boost::contains(version_str, "(U)")) { variant |= Unicode; } if(boost::contains(version_str, "My Inno Setup Extensions") || boost::contains(version_str, "with ISX")) {