Browse Source

Add support for ISX versions before 3.0.6.1

This implementation is based on the My Inno Setup Extensions changelog
 http://web.archive.org/web/20010306024721/http://www.wintax.nl/isx/
as well as source for ISX version 2.0.10 and 3.0.6.1 plus some RE.

The oldest ISX version available to be tested was 1.3.10.

Fixes: issue #85
pull/108/head
Daniel Scharrer 7 years ago
parent
commit
4c61bc4da8
  1. 1
      CHANGELOG
  2. 17
      src/setup/component.cpp
  3. 4
      src/setup/file.cpp
  4. 41
      src/setup/header.cpp
  5. 2
      src/setup/info.cpp
  6. 10
      src/setup/item.cpp
  7. 4
      src/setup/run.cpp
  8. 12
      src/setup/task.cpp
  9. 2
      src/setup/type.cpp
  10. 33
      src/setup/version.cpp
  11. 4
      src/setup/version.hpp

1
CHANGELOG

@ -5,6 +5,7 @@ innoextract 1.8 (WIP)
- Added support for a modified Inno Setup 5.5.7 variant
- Added support for a modified Inno Setup 5.5.7 variant with an uppercase (U) in the data version
- Added support for Inno Setup 1.3.x installers with x < 24
- Added support for My Inno Setup Extensions installers older than 3.0.6.1
- Added support for installers using an alternative setup loader magic
- Added support for using boost_{zlib,bzip2} when statically linking Boost
- Fixed extracting files from slices larger than 2 GiB with 32-bit builds

17
src/setup/component.cpp

@ -63,30 +63,33 @@ void component_entry::load(std::istream & is, const version & version) {
} else {
languages.clear();
}
if(version >= INNO_VERSION_EXT(3, 0, 6, 1)) {
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, version.codepage());
} else {
check.clear();
}
if(version >= INNO_VERSION(4, 0, 0)) {
extra_disk_pace_required = util::load<boost::uint64_t>(is);
} else {
extra_disk_pace_required = util::load<boost::uint32_t>(is);
}
if(version >= INNO_VERSION_EXT(3, 0, 6, 1)) {
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(3, 0, 3))) {
level = util::load<boost::int32_t>(is);
} else {
level = 0;
}
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(3, 0, 4))) {
used = util::load_bool(is);
} else {
level = 0, used = true;
used = true;
}
winver.load(is, version);
if(version >= INNO_VERSION(4, 2, 3)) {
options = stored_flags<stored_component_flags_2>(is).get();
} else if(version >= INNO_VERSION_EXT(3, 0, 6, 1)) {
} else if(version >= INNO_VERSION(3, 0, 8) ||
(version.is_isx() && version >= INNO_VERSION_EXT(3, 0, 6, 1))) {
options = stored_flags<stored_component_flags_1>(is).get();
} else {
options = stored_flags<stored_component_flags_0>(is).get();
@ -94,7 +97,7 @@ void component_entry::load(std::istream & is, const version & version) {
if(version >= INNO_VERSION(4, 0, 0)) {
size = util::load<boost::uint64_t>(is);
} else {
} else if(version >= INNO_VERSION(2, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
size = util::load<boost::uint32_t>(is);
}
}

4
src/setup/file.cpp

@ -125,7 +125,7 @@ void file_entry::load(std::istream & is, const version & version) {
flagreader.add(RegisterTypeLib);
flagreader.add(SharedFile);
}
if(version < INNO_VERSION(2, 0, 0)) {
if(version < INNO_VERSION(2, 0, 0) && !version.is_isx()) {
flagreader.add(IsReadmeFile);
}
flagreader.add(CompareTimeStamp);
@ -154,7 +154,7 @@ void file_entry::load(std::istream & is, const version & version) {
flagreader.add(IgnoreVersion);
flagreader.add(PromptIfOlder);
}
if(version >= INNO_VERSION_EXT(3, 0, 6, 1)) {
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION_EXT(3, 0, 6, 1))) {
flagreader.add(DontCopy);
}
if(version >= INNO_VERSION(4, 0, 5)) {

41
src/setup/header.cpp

@ -213,13 +213,16 @@ void header::load(std::istream & is, const version & version) {
} else {
default_user_name.clear(), default_user_organisation.clear();
}
if(version >= INNO_VERSION_EXT(3, 0, 6, 1)) {
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION_EXT(3, 0, 6, 1))) {
is >> util::encoded_string(default_serial, version.codepage());
if(version < INNO_VERSION(5, 2, 5)) {
is >> util::binary_string(compiled_code);
}
} else {
default_serial.clear(), compiled_code.clear();
default_serial.clear();
}
if((version >= INNO_VERSION(4, 0, 0) && version < INNO_VERSION(5, 2, 5)) ||
(version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
is >> util::binary_string(compiled_code);
} else {
compiled_code.clear();
}
if(version >= INNO_VERSION(4, 2, 4)) {
is >> util::encoded_string(app_readme_file, version.codepage());
@ -297,12 +300,16 @@ void header::load(std::istream & is, const version & version) {
permission_count = 0;
}
if(version >= INNO_VERSION(2, 0, 0)) {
if(version >= INNO_VERSION(2, 0, 0) || version.is_isx()) {
type_count = util::load<boost::uint32_t>(is);
component_count = util::load<boost::uint32_t>(is);
} else {
type_count = 0, component_count = 0;
}
if(version >= INNO_VERSION(2, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 17))) {
task_count = util::load<boost::uint32_t>(is);
} else {
type_count = 0, component_count = 0, task_count = 0;
task_count = 0;
}
directory_count = util::load<boost::uint32_t>(is, version.bits());
@ -338,7 +345,7 @@ void header::load(std::istream & is, const version & version) {
} else {
image_back_color = 0;
}
if(version >= INNO_VERSION(2, 0, 0) && version < INNO_VERSION(5, 0, 4)) {
if((version >= INNO_VERSION(2, 0, 0) && version < INNO_VERSION(5, 0, 4)) || version.is_isx()) {
small_image_back_color = util::load<boost::uint32_t>(is);
} else {
small_image_back_color = 0;
@ -386,7 +393,8 @@ void header::load(std::istream & is, const version & version) {
slices_per_disk = 1;
}
if(version >= INNO_VERSION(2, 0, 0) && version < INNO_VERSION(5, 0, 0)) {
if((version >= INNO_VERSION(2, 0, 0) && version < INNO_VERSION(5, 0, 0)) ||
(version.is_isx() && version >= INNO_VERSION(1, 3, 4))) {
install_mode = stored_enum<stored_install_verbosity>(is).get();
} else {
install_mode = NormalInstallMode;
@ -400,7 +408,7 @@ void header::load(std::istream & is, const version & version) {
if(version >= INNO_VERSION(5, 0, 0)) {
uninstall_style = ModernStyle;
} else if(version >= INNO_VERSION(2, 0, 0)) {
} else if(version >= INNO_VERSION(2, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 13))) {
uninstall_style = stored_enum<stored_setup_style>(is).get();
} else {
uninstall_style = ClassicStyle;
@ -412,6 +420,11 @@ void header::load(std::istream & is, const version & version) {
dir_exists_warning = Auto;
}
if(version.is_isx() && version >= INNO_VERSION(2, 0, 10) && version < INNO_VERSION(3, 0, 0)) {
boost::int32_t code_line_offset = util::load<boost::int32_t>(is);
(void)code_line_offset;
}
if(version >= INNO_VERSION(3, 0, 0) && version < INNO_VERSION(3, 0, 3)) {
auto_bool val = stored_enum<stored_bool_auto_no_yes>(is).get();
switch(val) {
@ -423,7 +436,7 @@ void header::load(std::istream & is, const version & version) {
if(version >= INNO_VERSION(5, 3, 7)) {
privileges_required = stored_enum<stored_privileges_1>(is).get();
} else if(version >= INNO_VERSION(3, 0, 4)) {
} else if(version >= INNO_VERSION(3, 0, 4) || (version.is_isx() && version >= INNO_VERSION(3, 0, 3))) {
privileges_required = stored_enum<stored_privileges_0>(is).get();
}
@ -560,8 +573,10 @@ void header::load(std::istream & is, const version & version) {
if(version >= INNO_VERSION(1, 3, 20)) {
flagreader.add(UpdateUninstallLogAppName);
}
if(version >= INNO_VERSION(2, 0, 0)) {
if(version >= INNO_VERSION(2, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 10))) {
flagreader.add(UsePreviousSetupType);
}
if(version >= INNO_VERSION(2, 0, 0)) {
flagreader.add(DisableReadyMemo);
flagreader.add(AlwaysShowComponentsList);
flagreader.add(FlatComponentsList);
@ -589,7 +604,7 @@ void header::load(std::istream & is, const version & version) {
if(version >= INNO_VERSION(3, 0, 3)) {
flagreader.add(RestartIfNeededByRun);
}
if(version >= INNO_VERSION_EXT(3, 0, 6, 1)) {
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(3, 0, 3))) {
flagreader.add(ShowTasksTreeLines);
}
if(version >= INNO_VERSION(4, 0, 0) && version < INNO_VERSION(4, 0, 10)) {

2
src/setup/info.cpp

@ -124,7 +124,7 @@ void load_wizard_and_decompressor(std::istream & is, const setup::version & vers
load_wizard_images(is, version, info.wizard_images, entries);
if(version >= INNO_VERSION(2, 0, 0)) {
if(version >= INNO_VERSION(2, 0, 0) || version.is_isx()) {
load_wizard_images(is, version, info.wizard_images_small, entries);
}

10
src/setup/item.cpp

@ -27,18 +27,22 @@ namespace setup {
void item::load_condition_data(std::istream & is, const version & version) {
if(version >= INNO_VERSION(2, 0, 0)) {
if(version >= INNO_VERSION(2, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 8))) {
is >> util::encoded_string(components, version.codepage());
} else {
components.clear();
}
if(version >= INNO_VERSION(2, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 17))) {
is >> util::encoded_string(tasks, version.codepage());
} else {
components.clear(), tasks.clear();
tasks.clear();
}
if(version >= INNO_VERSION(4, 0, 1)) {
is >> util::encoded_string(languages, version.codepage());
} else {
languages.clear();
}
if(version >= INNO_VERSION_EXT(3, 0, 6, 1)) {
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, version.codepage());
} else {
check.clear();

4
src/setup/run.cpp

@ -62,7 +62,7 @@ void run_entry::load(std::istream & is, const version & version) {
} else {
verb.clear();
}
if(version >= INNO_VERSION(2, 0, 0)) {
if(version >= INNO_VERSION(2, 0, 0) || version.is_isx()) {
is >> util::encoded_string(description, version.codepage());
}
@ -83,7 +83,7 @@ void run_entry::load(std::istream & is, const version & version) {
if(version >= INNO_VERSION(1, 2, 3)) {
flagreader.add(ShellExec);
}
if(version >= INNO_VERSION(1, 3, 9)) {
if(version >= INNO_VERSION(1, 3, 9) || (version.is_isx() && version >= INNO_VERSION(1, 3, 8))) {
flagreader.add(SkipIfDoesntExist);
}
if(version >= INNO_VERSION(2, 0, 0)) {

12
src/setup/task.cpp

@ -39,12 +39,20 @@ void task_entry::load(std::istream & is, const version & version) {
} else {
languages.clear();
}
if(version >= INNO_VERSION_EXT(3, 0, 6, 1)) {
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, version.codepage());
} else {
check.clear();
}
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(3, 0, 3))) {
level = util::load<boost::int32_t>(is);
} else {
level = 0;
}
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(3, 0, 4))) {
used = util::load_bool(is);
} else {
check.clear(), level = 0, used = true;
used = true;
}
winver.load(is, version);

2
src/setup/type.cpp

@ -62,7 +62,7 @@ void type_entry::load(std::istream & is, const version & version) {
} else {
languages.clear();
}
if(version >= INNO_VERSION_EXT(3, 0, 6, 1)) {
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, version.codepage());
} else {
check.clear();

33
src/setup/version.cpp

@ -28,6 +28,7 @@
#include <boost/version.hpp>
#include <boost/static_assert.hpp>
#include <boost/lexical_cast.hpp>
#include "boost/algorithm/string.hpp"
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/size.hpp>
@ -74,25 +75,39 @@ const known_version versions[] = {
{ "Inno Setup Setup Data (1.3.3)", INNO_VERSION_EXT(1, 3, 3, 0), 0 },
{ "Inno Setup Setup Data (1.3.9)", INNO_VERSION_EXT(1, 3, 9, 0), 0 },
{ "Inno Setup Setup Data (1.3.10)", INNO_VERSION_EXT(1, 3, 10, 0), 0 },
{ "Inno Setup Setup Data (1.3.10) with ISX (1.3.10)", INNO_VERSION_EXT(1, 3, 10, 0), version::ISX },
{ "Inno Setup Setup Data (1.3.12) with ISX (1.3.12.1)", INNO_VERSION_EXT(1, 3, 12, 1), version::ISX },
{ "Inno Setup Setup Data (1.3.21)", /* ambiguous */ INNO_VERSION_EXT(1, 3, 21, 0), 0 },
{ "Inno Setup Setup Data (1.3.21) with ISX (1.3.17)", INNO_VERSION_EXT(1, 3, 21, 0), version::ISX },
{ "Inno Setup Setup Data (1.3.24)", INNO_VERSION_EXT(1, 3, 24, 0), 0 },
{ "Inno Setup Setup Data (1.3.21) with ISX (1.3.24)", INNO_VERSION_EXT(1, 3, 24, 0), version::ISX },
{ "Inno Setup Setup Data (1.3.25)", INNO_VERSION_EXT(1, 3, 25, 0), 0 },
{ "Inno Setup Setup Data (1.3.25) with ISX (1.3.25)", INNO_VERSION_EXT(1, 3, 25, 0), version::ISX },
{ "Inno Setup Setup Data (2.0.0)", INNO_VERSION_EXT(2, 0, 0, 0), 0 },
{ "Inno Setup Setup Data (2.0.1)", /* ambiguous */ INNO_VERSION_EXT(2, 0, 1, 0), 0 },
{ "Inno Setup Setup Data (2.0.2)", INNO_VERSION_EXT(2, 0, 2, 0), 0 },
{ "Inno Setup Setup Data (2.0.5)", INNO_VERSION_EXT(2, 0, 5, 0), 0 },
{ "Inno Setup Setup Data (2.0.6a)", INNO_VERSION_EXT(2, 0, 6, 0), 0 },
{ "Inno Setup Setup Data (2.0.6a) with ISX (2.0.3)", INNO_VERSION_EXT(2, 0, 6, 0), version::ISX },
{ "Inno Setup Setup Data (2.0.7)", INNO_VERSION_EXT(2, 0, 7, 0), 0 },
{ "Inno Setup Setup Data (2.0.8)", INNO_VERSION_EXT(2, 0, 8, 0), 0 },
{ "Inno Setup Setup Data (2.0.8) with ISX (2.0.3)", INNO_VERSION_EXT(2, 0, 8, 0), version::ISX },
{ "Inno Setup Setup Data (2.0.8) with ISX (2.0.10)", INNO_VERSION_EXT(2, 0, 10, 0), version::ISX },
{ "Inno Setup Setup Data (2.0.11)", INNO_VERSION_EXT(2, 0, 11, 0), 0 },
{ "Inno Setup Setup Data (2.0.11) with ISX (2.0.11)", INNO_VERSION_EXT(2, 0, 11, 0), version::ISX },
{ "Inno Setup Setup Data (2.0.17)", INNO_VERSION_EXT(2, 0, 17, 0), 0 },
{ "Inno Setup Setup Data (2.0.17) with ISX (2.0.11)", INNO_VERSION_EXT(2, 0, 17, 0), version::ISX },
{ "Inno Setup Setup Data (2.0.18)", INNO_VERSION_EXT(2, 0, 18, 0), 0 },
{ "Inno Setup Setup Data (2.0.18) with ISX (2.0.11)", INNO_VERSION_EXT(2, 0, 18, 0), version::ISX },
{ "Inno Setup Setup Data (3.0.0a)", INNO_VERSION_EXT(3, 0, 0, 0), 0 },
{ "Inno Setup Setup Data (3.0.1)", INNO_VERSION_EXT(3, 0, 1, 0), 0 },
{ "Inno Setup Setup Data (3.0.1) with ISX (3.0.0)", INNO_VERSION_EXT(3, 0, 1, 0), version::ISX },
{ "Inno Setup Setup Data (3.0.3)", /* ambiguous */ INNO_VERSION_EXT(3, 0, 3, 0), 0 },
{ "Inno Setup Setup Data (3.0.3) with ISX (3.0.3)", INNO_VERSION_EXT(3, 0, 3, 0), version::ISX },
{ "Inno Setup Setup Data (3.0.4)", INNO_VERSION_EXT(3, 0, 4, 0), 0 },
{ "My Inno Setup Extensions Setup Data (3.0.4)", INNO_VERSION_EXT(3, 0, 4, 0), version::ISX },
{ "Inno Setup Setup Data (3.0.5)", INNO_VERSION_EXT(3, 0, 5, 0), 0 },
{ "My Inno Setup Extensions Setup Data (3.0.6.1)", INNO_VERSION_EXT(3, 0, 6, 1), 0 },
{ "My Inno Setup Extensions Setup Data (3.0.6.1)", INNO_VERSION_EXT(3, 0, 6, 1), version::ISX },
{ "Inno Setup Setup Data (4.0.0a)", INNO_VERSION_EXT(4, 0, 0, 0), 0 },
{ "Inno Setup Setup Data (4.0.1)", INNO_VERSION_EXT(4, 0, 1, 0), 0 },
{ "Inno Setup Setup Data (4.0.3)", INNO_VERSION_EXT(4, 0, 3, 0), 0 },
@ -181,6 +196,10 @@ std::ostream & operator<<(std::ostream & os, const version & version) {
os << " (" << int(version.bits()) << "-bit)";
}
if(version.is_isx()) {
os << " (isx)";
}
return os;
}
@ -261,6 +280,7 @@ void version::load(std::istream & is) {
throw version_error();
}
value = 0;
size_t bracket = version_str.find('(');
for(; bracket != std::string::npos; bracket = version_str.find('(', bracket + 1)) {
@ -308,21 +328,24 @@ void version::load(std::istream & is) {
}
}
value = INNO_VERSION_EXT(a, b, c, d);
break;
value = std::max(value, INNO_VERSION_EXT(a, b, c, d));
} catch(const boost::bad_lexical_cast &) {
continue;
}
}
if(bracket == std::string::npos) {
if(!value) {
throw version_error();
}
variant = 0;
if(version_str.find("(u)") != std::string::npos || version_str.find("(U)") != std::string::npos) {
if(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")) {
variant |= ISX;
}
known = false;
}

4
src/setup/version.hpp

@ -50,7 +50,8 @@ struct version {
FLAGS(flags,
Bits16,
Unicode
Unicode,
ISX
);
version_constant value;
@ -78,6 +79,7 @@ struct version {
boost::uint16_t bits() const { return (variant & Bits16) ? 16 : 32; }
bool is_unicode() const { return (variant & Unicode); }
bool is_isx() const { return (variant & ISX); }
//! \return the Windows codepage used to encode strings
boost::uint32_t codepage() const { return boost::uint32_t(is_unicode() ? 1200 : 1252); }

Loading…
Cancel
Save