Browse Source

setup: Don't hardcode codepage for non-Unicode installers

pull/108/head
Daniel Scharrer 7 years ago
parent
commit
8af85f702f
  1. 1
      CHANGELOG
  2. 6
      src/cli/extract.cpp
  3. 2
      src/cli/gog.cpp
  4. 36
      src/setup/component.cpp
  5. 4
      src/setup/component.hpp
  6. 47
      src/setup/data.cpp
  7. 4
      src/setup/data.hpp
  8. 11
      src/setup/delete.cpp
  9. 4
      src/setup/delete.hpp
  10. 23
      src/setup/directory.cpp
  11. 4
      src/setup/directory.hpp
  12. 74
      src/setup/file.cpp
  13. 4
      src/setup/file.hpp
  14. 98
      src/setup/header.cpp
  15. 3
      src/setup/header.hpp
  16. 45
      src/setup/icon.cpp
  17. 4
      src/setup/icon.hpp
  18. 107
      src/setup/info.cpp
  19. 13
      src/setup/info.hpp
  20. 19
      src/setup/ini.cpp
  21. 4
      src/setup/ini.hpp
  22. 25
      src/setup/item.cpp
  23. 3
      src/setup/item.hpp
  24. 41
      src/setup/language.cpp
  25. 8
      src/setup/language.hpp
  26. 12
      src/setup/message.cpp
  27. 7
      src/setup/message.hpp
  28. 5
      src/setup/permission.cpp
  29. 4
      src/setup/permission.hpp
  30. 41
      src/setup/registry.cpp
  31. 4
      src/setup/registry.hpp
  32. 47
      src/setup/run.cpp
  33. 4
      src/setup/run.hpp
  34. 31
      src/setup/task.cpp
  35. 4
      src/setup/task.hpp
  36. 21
      src/setup/type.cpp
  37. 4
      src/setup/type.hpp
  38. 3
      src/setup/version.hpp

1
CHANGELOG

@ -9,6 +9,7 @@ innoextract 1.8 (WIP)
- Added support for installers using an alternative setup loader magic
- Added support for using boost_{zlib,bzip2} when statically linking Boost
- Added support for automatically reading external setup.0 files
- Encoding for non-Unicode installers is now determined from the languages supported by the installer
- Implemented parsing of GOG Galaxy architecture constraints
- The architecture-specific suffixes @32bit and @64bit are now used to disambiguate colliding files
- Fixed extracting files from slices larger than 2 GiB with 32-bit builds

6
src/cli/extract.cpp

@ -660,10 +660,10 @@ bool print_file_info(const extract_options & o, const setup::info & info) {
std::cout << '\n';
}
if(o.silent) {
std::cout << util::encoding_name(info.version.codepage()) << '\n';
std::cout << util::encoding_name(info.codepage) << '\n';
} else {
std::cout << "Password encoding: " << color::yellow
<< util::encoding_name(info.version.codepage()) << color::reset << '\n';
<< util::encoding_name(info.codepage) << color::reset << '\n';
}
} else if(!o.quiet) {
std::cout << "Setup is not passworded!\n";
@ -945,7 +945,7 @@ void process_file(const fs::path & file, const extract_options & o) {
log_warning << "Setup contains encrypted files, use the --password option to extract them";
}
} else {
util::from_utf8(o.password, password, info.version.codepage());
util::from_utf8(o.password, password, info.codepage);
if(info.header.options & setup::header::Password) {
crypto::hasher checksum(info.header.password.type);
checksum.update(info.header.password_salt.c_str(), info.header.password_salt.length());

2
src/cli/gog.cpp

@ -75,7 +75,7 @@ std::string get_game_id(const setup::info & info) {
if(boost::iequals(entry.name, "gameID")) {
id = entry.value;
util::to_utf8(id, info.version.codepage());
util::to_utf8(id, info.codepage);
break;
}

36
src/setup/component.cpp

@ -20,6 +20,7 @@
#include "setup/component.hpp"
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
@ -53,51 +54,52 @@ STORED_FLAGS_MAP(stored_component_flags_2,
} // anonymous namespace
void component_entry::load(std::istream & is, const version & version) {
void component_entry::load(std::istream & is, const info & i) {
is >> util::encoded_string(name, version.codepage());
is >> util::encoded_string(description, version.codepage());
is >> util::encoded_string(types, version.codepage());
if(version >= INNO_VERSION(4, 0, 1)) {
is >> util::encoded_string(languages, version.codepage());
is >> util::encoded_string(name, i.codepage);
is >> util::encoded_string(description, i.codepage);
is >> util::encoded_string(types, i.codepage);
if(i.version >= INNO_VERSION(4, 0, 1)) {
is >> util::encoded_string(languages, i.codepage);
} else {
languages.clear();
}
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, version.codepage());
if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, i.codepage);
} else {
check.clear();
}
if(version >= INNO_VERSION(4, 0, 0)) {
if(i.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(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(3, 0, 3))) {
if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.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))) {
if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(3, 0, 4))) {
used = util::load_bool(is);
} else {
used = true;
}
winver.load(is, version);
winver.load(is, i.version);
if(version >= INNO_VERSION(4, 2, 3)) {
if(i.version >= INNO_VERSION(4, 2, 3)) {
options = stored_flags<stored_component_flags_2>(is).get();
} else if(version >= INNO_VERSION(3, 0, 8) ||
(version.is_isx() && version >= INNO_VERSION_EXT(3, 0, 6, 1))) {
} else if(i.version >= INNO_VERSION(3, 0, 8) ||
(i.version.is_isx() && i.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();
}
if(version >= INNO_VERSION(4, 0, 0)) {
if(i.version >= INNO_VERSION(4, 0, 0)) {
size = util::load<boost::uint64_t>(is);
} else if(version >= INNO_VERSION(2, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
} else if(i.version >= INNO_VERSION(2, 0, 0) ||
(i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) {
size = util::load<boost::uint32_t>(is);
}
}

4
src/setup/component.hpp

@ -37,7 +37,7 @@
namespace setup {
struct version;
struct info;
struct component_entry {
@ -68,7 +68,7 @@ struct component_entry {
boost::uint64_t size;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

47
src/setup/data.cpp

@ -22,6 +22,7 @@
#include <cstring>
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/log.hpp"
@ -31,11 +32,11 @@
namespace setup {
void data_entry::load(std::istream & is, const version & version) {
void data_entry::load(std::istream & is, const info & i) {
chunk.first_slice = util::load<boost::uint32_t>(is, version.bits());
chunk.last_slice = util::load<boost::uint32_t>(is, version.bits());
if(version < INNO_VERSION(4, 0, 0)) {
chunk.first_slice = util::load<boost::uint32_t>(is, i.version.bits());
chunk.last_slice = util::load<boost::uint32_t>(is, i.version.bits());
if(i.version < INNO_VERSION(4, 0, 0)) {
if(chunk.first_slice < 1 || chunk.last_slice < 1) {
log_warning << "Unexpected slice number: " << chunk.first_slice
<< " to " << chunk.last_slice;
@ -46,13 +47,13 @@ void data_entry::load(std::istream & is, const version & version) {
chunk.offset = util::load<boost::uint32_t>(is);
if(version >= INNO_VERSION(4, 0, 1)) {
if(i.version >= INNO_VERSION(4, 0, 1)) {
file.offset = util::load<boost::uint64_t>(is);
} else {
file.offset = 0;
}
if(version >= INNO_VERSION(4, 0, 0)) {
if(i.version >= INNO_VERSION(4, 0, 0)) {
file.size = util::load<boost::uint64_t>(is);
chunk.size = util::load<boost::uint64_t>(is);
} else {
@ -61,13 +62,13 @@ void data_entry::load(std::istream & is, const version & version) {
}
uncompressed_size = file.size;
if(version >= INNO_VERSION(5, 3, 9)) {
if(i.version >= INNO_VERSION(5, 3, 9)) {
is.read(file.checksum.sha1, std::streamsize(sizeof(file.checksum.sha1)));
file.checksum.type = crypto::SHA1;
} else if(version >= INNO_VERSION(4, 2, 0)) {
} else if(i.version >= INNO_VERSION(4, 2, 0)) {
is.read(file.checksum.md5, std::streamsize(sizeof(file.checksum.md5)));
file.checksum.type = crypto::MD5;
} else if(version >= INNO_VERSION(4, 0, 1)) {
} else if(i.version >= INNO_VERSION(4, 0, 1)) {
file.checksum.crc32 = util::load<boost::uint32_t>(is);
file.checksum.type = crypto::CRC32;
} else {
@ -75,7 +76,7 @@ void data_entry::load(std::istream & is, const version & version) {
file.checksum.type = crypto::Adler32;
}
if(version.bits() == 16) {
if(i.version.bits() == 16) {
// 16-bit installers use the FAT filetime format
@ -118,37 +119,37 @@ void data_entry::load(std::istream & is, const version & version) {
options = 0;
stored_flag_reader<flags> flagreader(is, version.bits());
stored_flag_reader<flags> flagreader(is, i.version.bits());
flagreader.add(VersionInfoValid);
flagreader.add(VersionInfoNotValid);
if(version >= INNO_VERSION(2, 0, 17) && version < INNO_VERSION(4, 0, 1)) {
if(i.version >= INNO_VERSION(2, 0, 17) && i.version < INNO_VERSION(4, 0, 1)) {
flagreader.add(BZipped);
}
if(version >= INNO_VERSION(4, 0, 10)) {
if(i.version >= INNO_VERSION(4, 0, 10)) {
flagreader.add(TimeStampInUTC);
}
if(version >= INNO_VERSION(4, 1, 0)) {
if(i.version >= INNO_VERSION(4, 1, 0)) {
flagreader.add(IsUninstallerExe);
}
if(version >= INNO_VERSION(4, 1, 8)) {
if(i.version >= INNO_VERSION(4, 1, 8)) {
flagreader.add(CallInstructionOptimized);
}
if(version >= INNO_VERSION(4, 2, 0)) {
if(i.version >= INNO_VERSION(4, 2, 0)) {
flagreader.add(Touch);
}
if(version >= INNO_VERSION(4, 2, 2)) {
if(i.version >= INNO_VERSION(4, 2, 2)) {
flagreader.add(ChunkEncrypted);
}
if(version >= INNO_VERSION(4, 2, 5)) {
if(i.version >= INNO_VERSION(4, 2, 5)) {
flagreader.add(ChunkCompressed);
} else {
options |= ChunkCompressed;
}
if(version >= INNO_VERSION(5, 1, 13)) {
if(i.version >= INNO_VERSION(5, 1, 13)) {
flagreader.add(SolidBreak);
}
if(version >= INNO_VERSION(5, 5, 7)) {
if(i.version >= INNO_VERSION(5, 5, 7)) {
// Actually added in Inno Setup 5.5.9 but the data version was not bumped
flagreader.add(Sign);
flagreader.add(SignOnce);
@ -167,7 +168,7 @@ void data_entry::load(std::istream & is, const version & version) {
}
if(options & ChunkEncrypted) {
if(version >= INNO_VERSION(5, 3, 9)) {
if(i.version >= INNO_VERSION(5, 3, 9)) {
chunk.encryption = stream::ARC4_SHA1;
} else {
chunk.encryption = stream::ARC4_MD5;
@ -177,9 +178,9 @@ void data_entry::load(std::istream & is, const version & version) {
}
if(options & CallInstructionOptimized) {
if(version < INNO_VERSION(5, 2, 0)) {
if(i.version < INNO_VERSION(5, 2, 0)) {
file.filter = stream::InstructionFilter4108;
} else if(version < INNO_VERSION(5, 3, 9)) {
} else if(i.version < INNO_VERSION(5, 3, 9)) {
file.filter = stream::InstructionFilter5200;
} else {
file.filter = stream::InstructionFilter5309;

4
src/setup/data.hpp

@ -39,7 +39,7 @@
namespace setup {
struct version;
struct info;
struct data_entry {
@ -79,7 +79,7 @@ struct data_entry {
*
* \note This function may not be thread-safe on all operating systems.
*/
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

11
src/setup/delete.cpp

@ -20,6 +20,7 @@
#include "setup/delete.hpp"
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
@ -36,17 +37,17 @@ STORED_ENUM_MAP(delete_target_type_map, delete_entry::Files,
} // anonymous namespace
void delete_entry::load(std::istream & is, const version & version) {
void delete_entry::load(std::istream & is, const info & i) {
if(version < INNO_VERSION(1, 3, 0)) {
if(i.version < INNO_VERSION(1, 3, 0)) {
(void)util::load<boost::uint32_t>(is); // uncompressed size of the entry
}
is >> util::encoded_string(name, version.codepage());
is >> util::encoded_string(name, i.codepage);
load_condition_data(is, version);
load_condition_data(is, i);
load_version_data(is, version);
load_version_data(is, i.version);
type = stored_enum<delete_target_type_map>(is).get();
}

4
src/setup/delete.hpp

@ -34,7 +34,7 @@
namespace setup {
struct version;
struct info;
struct delete_entry : public item {
@ -48,7 +48,7 @@ struct delete_entry : public item {
target_type type;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

23
src/setup/directory.cpp

@ -20,6 +20,7 @@
#include "setup/directory.hpp"
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
@ -45,39 +46,39 @@ STORED_FLAGS_MAP(stored_inno_directory_options_1,
} // anonymous namespace
void directory_entry::load(std::istream & is, const version & version) {
void directory_entry::load(std::istream & is, const info & i) {
if(version < INNO_VERSION(1, 3, 0)) {
if(i.version < INNO_VERSION(1, 3, 0)) {
(void)util::load<boost::uint32_t>(is); // uncompressed size of the entry
}
is >> util::encoded_string(name, version.codepage());
is >> util::encoded_string(name, i.codepage);
load_condition_data(is, version);
load_condition_data(is, i);
if(version >= INNO_VERSION(4, 0, 11) && version < INNO_VERSION(4, 1, 0)) {
is >> util::encoded_string(permissions, version.codepage());
if(i.version >= INNO_VERSION(4, 0, 11) && i.version < INNO_VERSION(4, 1, 0)) {
is >> util::binary_string(permissions);
} else {
permissions.clear();
}
if(version >= INNO_VERSION(2, 0, 11)) {
if(i.version >= INNO_VERSION(2, 0, 11)) {
attributes = util::load<boost::uint32_t>(is);
} else {
attributes = 0;
}
load_version_data(is, version);
load_version_data(is, i.version);
if(version >= INNO_VERSION(4, 1, 0)) {
if(i.version >= INNO_VERSION(4, 1, 0)) {
permission = util::load<boost::int16_t>(is);
} else {
permission = boost::int16_t(-1);
}
if(version >= INNO_VERSION(5, 2, 0)) {
if(i.version >= INNO_VERSION(5, 2, 0)) {
options = stored_flags<stored_inno_directory_options_1>(is).get();
} else if(version.bits() != 16) {
} else if(i.version.bits() != 16) {
options = stored_flags<stored_inno_directory_options_0>(is).get();
} else {
options = stored_flags<stored_inno_directory_options_0, 16>(is).get();

4
src/setup/directory.hpp

@ -37,7 +37,7 @@
namespace setup {
struct version;
struct info;
struct directory_entry : public item {
@ -58,7 +58,7 @@ struct directory_entry : public item {
flags options;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

74
src/setup/file.cpp

@ -20,6 +20,7 @@
#include "setup/file.hpp"
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/log.hpp"
@ -70,35 +71,35 @@ NAMES(setup::file_copy_mode, "File Copy Mode",
namespace setup {
void file_entry::load(std::istream & is, const version & version) {
void file_entry::load(std::istream & is, const info & i) {
USE_ENUM_NAMES(file_copy_mode)
options = 0;
if(version < INNO_VERSION(1, 3, 0)) {
if(i.version < INNO_VERSION(1, 3, 0)) {
(void)util::load<boost::uint32_t>(is); // uncompressed size of the entry
}
is >> util::encoded_string(source, version.codepage());
is >> util::encoded_string(destination, version.codepage());
is >> util::encoded_string(install_font_name, version.codepage());
if(version >= INNO_VERSION(5, 2, 5)) {
is >> util::encoded_string(strong_assembly_name, version.codepage());
is >> util::encoded_string(source, i.codepage);
is >> util::encoded_string(destination, i.codepage);
is >> util::encoded_string(install_font_name, i.codepage);
if(i.version >= INNO_VERSION(5, 2, 5)) {
is >> util::encoded_string(strong_assembly_name, i.codepage);
} else {
strong_assembly_name.clear();
}
load_condition_data(is, version);
load_condition_data(is, i);
load_version_data(is, version);
load_version_data(is, i.version);
location = util::load<boost::uint32_t>(is, version.bits());
attributes = util::load<boost::uint32_t>(is, version.bits());
external_size = (version >= INNO_VERSION(4, 0, 0)) ? util::load<boost::uint64_t>(is)
: util::load<boost::uint32_t>(is);
location = util::load<boost::uint32_t>(is, i.version.bits());
attributes = util::load<boost::uint32_t>(is, i.version.bits());
external_size = (i.version >= INNO_VERSION(4, 0, 0)) ? util::load<boost::uint64_t>(is)
: util::load<boost::uint32_t>(is);
if(version < INNO_VERSION(3, 0, 5)) {
if(i.version < INNO_VERSION(3, 0, 5)) {
file_copy_mode copyMode = stored_enum<stored_file_copy_mode>(is).get();
switch(copyMode) {
case cmNormal: options |= PromptIfOlder; break;
@ -108,89 +109,90 @@ void file_entry::load(std::istream & is, const version & version) {
}
}
if(version >= INNO_VERSION(4, 1, 0)) {
if(i.version >= INNO_VERSION(4, 1, 0)) {
permission = util::load<boost::int16_t>(is);
} else {
permission = boost::int16_t(-1);
}
stored_flag_reader<flags> flagreader(is, version.bits());
stored_flag_reader<flags> flagreader(is, i.version.bits());
flagreader.add(ConfirmOverwrite);
flagreader.add(NeverUninstall);
flagreader.add(RestartReplace);
flagreader.add(DeleteAfterInstall);
if(version.bits() != 16) {
if(i.version.bits() != 16) {
flagreader.add(RegisterServer);
flagreader.add(RegisterTypeLib);
flagreader.add(SharedFile);
}
if(version < INNO_VERSION(2, 0, 0) && !version.is_isx()) {
if(i.version < INNO_VERSION(2, 0, 0) && !i.version.is_isx()) {
flagreader.add(IsReadmeFile);
}
flagreader.add(CompareTimeStamp);
flagreader.add(FontIsNotTrueType);
if(version >= INNO_VERSION(1, 2, 5)) {
if(i.version >= INNO_VERSION(1, 2, 5)) {
flagreader.add(SkipIfSourceDoesntExist);
}
if(version >= INNO_VERSION(1, 2, 6)) {
if(i.version >= INNO_VERSION(1, 2, 6)) {
flagreader.add(OverwriteReadOnly);
}
if(version >= INNO_VERSION(1, 3, 21)) {
if(i.version >= INNO_VERSION(1, 3, 21)) {
flagreader.add(OverwriteSameVersion);
flagreader.add(CustomDestName);
}
if(version >= INNO_VERSION(1, 3, 25)) {
if(i.version >= INNO_VERSION(1, 3, 25)) {
flagreader.add(OnlyIfDestFileExists);
}
if(version >= INNO_VERSION(2, 0, 5)) {
if(i.version >= INNO_VERSION(2, 0, 5)) {
flagreader.add(NoRegError);
}
if(version >= INNO_VERSION(3, 0, 1)) {
if(i.version >= INNO_VERSION(3, 0, 1)) {
flagreader.add(UninsRestartDelete);
}
if(version >= INNO_VERSION(3, 0, 5)) {
if(i.version >= INNO_VERSION(3, 0, 5)) {
flagreader.add(OnlyIfDoesntExist);
flagreader.add(IgnoreVersion);
flagreader.add(PromptIfOlder);
}
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION_EXT(3, 0, 6, 1))) {
if(i.version >= INNO_VERSION(4, 0, 0) ||
(i.version.is_isx() && i.version >= INNO_VERSION_EXT(3, 0, 6, 1))) {
flagreader.add(DontCopy);
}
if(version >= INNO_VERSION(4, 0, 5)) {
if(i.version >= INNO_VERSION(4, 0, 5)) {
flagreader.add(UninsRemoveReadOnly);
}
if(version >= INNO_VERSION(4, 1, 8)) {
if(i.version >= INNO_VERSION(4, 1, 8)) {
flagreader.add(RecurseSubDirsExternal);
}
if(version >= INNO_VERSION(4, 2, 1)) {
if(i.version >= INNO_VERSION(4, 2, 1)) {
flagreader.add(ReplaceSameVersionIfContentsDiffer);
}
if(version >= INNO_VERSION(4, 2, 5)) {
if(i.version >= INNO_VERSION(4, 2, 5)) {
flagreader.add(DontVerifyChecksum);
}
if(version >= INNO_VERSION(5, 0, 3)) {
if(i.version >= INNO_VERSION(5, 0, 3)) {
flagreader.add(UninsNoSharedFilePrompt);
}
if(version >= INNO_VERSION(5, 1, 0)) {
if(i.version >= INNO_VERSION(5, 1, 0)) {
flagreader.add(CreateAllSubDirs);
}
if(version >= INNO_VERSION(5, 1, 2)) {
if(i.version >= INNO_VERSION(5, 1, 2)) {
flagreader.add(Bits32);
flagreader.add(Bits64);
}
if(version >= INNO_VERSION(5, 2, 0)) {
if(i.version >= INNO_VERSION(5, 2, 0)) {
flagreader.add(ExternalSizePreset);
flagreader.add(SetNtfsCompression);
flagreader.add(UnsetNtfsCompression);
}
if(version >= INNO_VERSION(5, 2, 5)) {
if(i.version >= INNO_VERSION(5, 2, 5)) {
flagreader.add(GacInstall);
}
options |= flagreader;
if(version.bits() == 16 || version >= INNO_VERSION(5, 0, 0)) {
if(i.version.bits() == 16 || i.version >= INNO_VERSION(5, 0, 0)) {
type = stored_enum<stored_file_type_0>(is).get();
} else {
type = stored_enum<stored_file_type_1>(is).get();

4
src/setup/file.hpp

@ -39,7 +39,7 @@
namespace setup {
struct version;
struct info;
struct file_entry : public item {
@ -113,7 +113,7 @@ struct file_entry : public item {
crypto::checksum checksum;
boost::uint64_t size;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

98
src/setup/header.cpp

@ -26,7 +26,6 @@
#include <boost/static_assert.hpp>
#include "setup/version.hpp"
#include "util/encoding.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
@ -152,38 +151,40 @@ void header::load(std::istream & is, const version & version) {
(void)util::load<boost::uint32_t>(is); // uncompressed size of the setup header
}
is >> util::encoded_string(app_name, version.codepage());
is >> util::encoded_string(app_versioned_name, version.codepage());
is >> util::binary_string(app_name);
is >> util::binary_string(app_versioned_name);
if(version >= INNO_VERSION(1, 3, 0)) {
is >> util::encoded_string(app_id, version.codepage());
is >> util::binary_string(app_id);
} else {
app_id.clear();
}
is >> util::encoded_string(app_copyright, version.codepage());
is >> util::binary_string(app_copyright);
if(version >= INNO_VERSION(1, 3, 0)) {
is >> util::encoded_string(app_publisher, version.codepage());
is >> util::encoded_string(app_publisher_url, version.codepage());
is >> util::binary_string(app_publisher);
is >> util::binary_string(app_publisher_url);
} else {
app_publisher.clear(), app_publisher_url.clear();
}
if(version >= INNO_VERSION(5, 1, 13)) {
is >> util::encoded_string(app_support_phone, version.codepage());
is >> util::binary_string(app_support_phone);
} else {
app_support_phone.clear();
}
if(version >= INNO_VERSION(1, 3, 0)) {
is >> util::encoded_string(app_support_url, version.codepage());
is >> util::encoded_string(app_updates_url, version.codepage());
is >> util::encoded_string(app_version, version.codepage());
is >> util::binary_string(app_support_url);
is >> util::binary_string(app_updates_url);
is >> util::binary_string(app_version);
} else {
app_support_url.clear(), app_updates_url.clear(), app_version.clear();
}
is >> util::encoded_string(default_dir_name, version.codepage());
is >> util::encoded_string(default_group_name, version.codepage());
is >> util::binary_string(default_dir_name);
is >> util::binary_string(default_group_name);
if(version < INNO_VERSION(3, 0, 0)) {
is >> util::ansi_string(uninstall_icon_name);
} else {
uninstall_icon_name.clear();
}
is >> util::encoded_string(base_filename, version.codepage());
is >> util::binary_string(base_filename);
if(version >= INNO_VERSION(1, 3, 0) && version < INNO_VERSION(5, 2, 5)) {
is >> util::ansi_string(license_text);
is >> util::ansi_string(info_before);
@ -192,29 +193,29 @@ void header::load(std::istream & is, const version & version) {
license_text.clear(), info_before.clear(), info_after.clear();
}
if(version >= INNO_VERSION(1, 3, 3)) {
is >> util::encoded_string(uninstall_files_dir, version.codepage());
is >> util::binary_string(uninstall_files_dir);
} else {
uninstall_files_dir.clear();
}
if(version >= INNO_VERSION(1, 3, 6)) {
is >> util::encoded_string(uninstall_name, version.codepage());
is >> util::encoded_string(uninstall_icon, version.codepage());
is >> util::binary_string(uninstall_name);
is >> util::binary_string(uninstall_icon);
} else {
uninstall_name.clear(), uninstall_icon.clear();
}
if(version >= INNO_VERSION(1, 3, 14)) {
is >> util::encoded_string(app_mutex, version.codepage());
is >> util::binary_string(app_mutex);
} else {
app_mutex.clear();
}
if(version >= INNO_VERSION(3, 0, 0)) {
is >> util::encoded_string(default_user_name, version.codepage());
is >> util::encoded_string(default_user_organisation, version.codepage());
is >> util::binary_string(default_user_name);
is >> util::binary_string(default_user_organisation);
} else {
default_user_name.clear(), default_user_organisation.clear();
}
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());
is >> util::binary_string(default_serial);
} else {
default_serial.clear();
}
@ -225,37 +226,37 @@ void header::load(std::istream & is, const version & version) {
compiled_code.clear();
}
if(version >= INNO_VERSION(4, 2, 4)) {
is >> util::encoded_string(app_readme_file, version.codepage());
is >> util::encoded_string(app_contact, version.codepage());
is >> util::encoded_string(app_comments, version.codepage());
is >> util::encoded_string(app_modify_path, version.codepage());
is >> util::binary_string(app_readme_file);
is >> util::binary_string(app_contact);
is >> util::binary_string(app_comments);
is >> util::binary_string(app_modify_path);
} else {
app_readme_file.clear(), app_contact.clear();
app_comments.clear(), app_modify_path.clear();
}
if(version >= INNO_VERSION(5, 3, 8)) {
is >> util::encoded_string(create_uninstall_registry_key, version.codepage());
is >> util::binary_string(create_uninstall_registry_key);
} else {
create_uninstall_registry_key.clear();
}
if(version >= INNO_VERSION(5, 3, 10)) {
is >> util::encoded_string(uninstallable, version.codepage());
is >> util::binary_string(uninstallable);
} else {
uninstallable.clear();
}
if(version >= INNO_VERSION(5, 5, 0)) {
is >> util::encoded_string(close_applications_filter, version.codepage());
is >> util::binary_string(close_applications_filter);
} else {
close_applications_filter.clear();
}
if(version >= INNO_VERSION(5, 5, 6)) {
is >> util::encoded_string(setup_mutex, version.codepage());
is >> util::binary_string(setup_mutex);
} else {
setup_mutex.clear();
}
if(version >= INNO_VERSION(5, 6, 1)) {
is >> util::encoded_string(changes_environment, version.codepage());
is >> util::encoded_string(changes_associations, version.codepage());
is >> util::binary_string(changes_environment);
is >> util::binary_string(changes_associations);
} else {
changes_environment.clear();
changes_associations.clear();
@ -702,6 +703,41 @@ void header::load(std::istream & is, const version & version) {
}
void header::decode(util::codepage_id codepage) {
util::to_utf8(app_name, codepage);
util::to_utf8(app_versioned_name, codepage);
util::to_utf8(app_id, codepage);
util::to_utf8(app_copyright, codepage);
util::to_utf8(app_publisher, codepage);
util::to_utf8(app_publisher_url, codepage);
util::to_utf8(app_support_phone, codepage);
util::to_utf8(app_support_url, codepage);
util::to_utf8(app_updates_url, codepage);
util::to_utf8(app_version, codepage);
util::to_utf8(default_dir_name, codepage);
util::to_utf8(default_group_name, codepage);
util::to_utf8(base_filename, codepage);
util::to_utf8(uninstall_files_dir, codepage);
util::to_utf8(uninstall_name, codepage);
util::to_utf8(uninstall_icon, codepage);
util::to_utf8(app_mutex, codepage);
util::to_utf8(default_user_name, codepage);
util::to_utf8(default_user_organisation, codepage);
util::to_utf8(default_serial, codepage);
util::to_utf8(app_readme_file, codepage);
util::to_utf8(app_contact, codepage);
util::to_utf8(app_comments, codepage);
util::to_utf8(app_modify_path, codepage);
util::to_utf8(create_uninstall_registry_key, codepage);
util::to_utf8(uninstallable, codepage);
util::to_utf8(close_applications_filter, codepage);
util::to_utf8(setup_mutex, codepage);
util::to_utf8(changes_environment, codepage);
util::to_utf8(changes_associations, codepage);
}
} // namespace setup
NAMES(setup::header::flags, "Setup Option",

3
src/setup/header.hpp

@ -36,6 +36,7 @@
#include "crypto/checksum.hpp"
#include "setup/windows.hpp"
#include "stream/chunk.hpp"
#include "util/encoding.hpp"
#include "util/enum.hpp"
#include "util/flags.hpp"
@ -278,6 +279,8 @@ struct header {
void load(std::istream & is, const version & version);
void decode(util::codepage_id codepage);
};
} // namespace setup

45
src/setup/icon.cpp

@ -20,6 +20,7 @@
#include "setup/icon.hpp"
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
@ -36,65 +37,65 @@ STORED_ENUM_MAP(stored_close_setting, icon_entry::NoSetting,
} // anonymous namespace
void icon_entry::load(std::istream & is, const version & version) {
void icon_entry::load(std::istream & is, const info & i) {
if(version < INNO_VERSION(1, 3, 0)) {
if(i.version < INNO_VERSION(1, 3, 0)) {
(void)util::load<boost::uint32_t>(is); // uncompressed size of the entry
}
is >> util::encoded_string(name, version.codepage());
is >> util::encoded_string(filename, version.codepage());
is >> util::encoded_string(parameters, version.codepage());
is >> util::encoded_string(working_dir, version.codepage());
is >> util::encoded_string(icon_file, version.codepage());
is >> util::encoded_string(comment, version.codepage());
is >> util::encoded_string(name, i.codepage);
is >> util::encoded_string(filename, i.codepage);
is >> util::encoded_string(parameters, i.codepage);
is >> util::encoded_string(working_dir, i.codepage);
is >> util::encoded_string(icon_file, i.codepage);
is >> util::encoded_string(comment, i.codepage);
load_condition_data(is, version);
load_condition_data(is, i);
if(version >= INNO_VERSION(5, 3, 5)) {
is >> util::encoded_string(app_user_model_id, version.codepage());
if(i.version >= INNO_VERSION(5, 3, 5)) {
is >> util::encoded_string(app_user_model_id, i.codepage);
} else {
app_user_model_id.clear();
}
load_version_data(is, version);
load_version_data(is, i.version);
icon_index = util::load<boost::int32_t>(is, version.bits());
icon_index = util::load<boost::int32_t>(is, i.version.bits());
if(version >= INNO_VERSION(1, 3, 24)) {
if(i.version >= INNO_VERSION(1, 3, 24)) {
show_command = util::load<boost::int32_t>(is);
} else {
show_command = 1;
}
if(version >= INNO_VERSION(1, 3, 15)) {
if(i.version >= INNO_VERSION(1, 3, 15)) {
close_on_exit = stored_enum<stored_close_setting>(is).get();
} else {
close_on_exit = NoSetting;
}
if(version >= INNO_VERSION(2, 0, 7)) {
if(i.version >= INNO_VERSION(2, 0, 7)) {
hotkey = util::load<boost::uint16_t>(is);
} else {
hotkey = 0;
}
stored_flag_reader<flags> flagreader(is, version.bits());
stored_flag_reader<flags> flagreader(is, i.version.bits());
flagreader.add(NeverUninstall);
if(version < INNO_VERSION(1, 3, 26)) {
if(i.version < INNO_VERSION(1, 3, 26)) {
flagreader.add(RunMinimized);
}
flagreader.add(CreateOnlyIfFileExists);
if(version.bits() != 16) {
if(i.version.bits() != 16) {
flagreader.add(UseAppPaths);
}
if(version >= INNO_VERSION(5, 0, 3)) {
if(i.version >= INNO_VERSION(5, 0, 3)) {
flagreader.add(FolderShortcut);
}
if(version >= INNO_VERSION(5, 4, 2)) {
if(i.version >= INNO_VERSION(5, 4, 2)) {
flagreader.add(ExcludeFromShowInNewInstall);
}
if(version >= INNO_VERSION(5, 5, 0)) {
if(i.version >= INNO_VERSION(5, 5, 0)) {
flagreader.add(PreventPinning);
}

4
src/setup/icon.hpp

@ -37,7 +37,7 @@
namespace setup {
struct version;
struct info;
struct icon_entry : public item {
@ -76,7 +76,7 @@ struct icon_entry : public item {
flags options;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

107
src/setup/info.cpp

@ -42,54 +42,32 @@
#include "setup/task.hpp"
#include "setup/type.hpp"
#include "stream/block.hpp"
#include "util/fstream.hpp"
#include "util/load.hpp"
#include "util/log.hpp"
#include "util/output.hpp"
namespace setup {
namespace {
struct no_arg { };
template <class Entry, class Arg>
void load_entry(std::istream & is, const setup::version & version,
Entry & entity, Arg arg) {
entity.load(is, version, arg);
}
template <class Entry>
void load_entry(std::istream & is, const setup::version & version,
Entry & entity, no_arg arg) {
(void)arg;
entity.load(is, version);
}
template <class Entry, class Arg>
void load_entries(std::istream & is, const setup::version & version,
info::entry_types entry_types, size_t count,
std::vector<Entry> & entries, info::entry_types::enum_type entry_type,
Arg arg = Arg()) {
void info::load_entries(std::istream & is, info::entry_types entry_types, size_t count,
std::vector<Entry> & entries, info::entry_types::enum_type entry_type) {
entries.clear();
if(entry_types & entry_type) {
entries.resize(count);
for(size_t i = 0; i < count; i++) {
Entry & entry = entries[i];
load_entry(is, version, entry, arg);
entries[i].load(is, *this);
}
} else {
for(size_t i = 0; i < count; i++) {
Entry entry;
load_entry(is, version, entry, arg);
entry.load(is, *this);
}
}
}
template <class Entry>
void load_entries(std::istream & is, const setup::version & version,
info::entry_types entry_types, size_t count,
std::vector<Entry> & entries, info::entry_types::enum_type entry_type) {
load_entries<Entry, no_arg>(is, version, entry_types, count, entries, entry_type);
}
namespace {
void load_wizard_images(std::istream & is, const setup::version & version,
std::vector<std::string> & images, info::entry_types entries) {
@ -162,9 +140,11 @@ void check_is_end(stream::block_reader::pointer & is, const char * what) {
} // anonymous namespace
void info::load(std::istream & is, entry_types entries, const setup::version & version) {
void info::try_load(std::istream & is, entry_types entries, util::codepage_id force_codepage) {
if(entries & (Messages | NoSkip)) {
debug("trying to load setup headers for version " << version);
if((entries & (Messages | NoSkip)) || (!version.is_unicode() && !force_codepage)) {
entries |= Languages;
}
@ -172,27 +152,52 @@ void info::load(std::istream & is, entry_types entries, const setup::version & v
header.load(*reader, version);
load_entries(*reader, version, entries, header.language_count, languages, Languages);
load_entries(*reader, entries, header.language_count, languages, Languages);
if(version.is_unicode()) {
// Unicode installers are always UTF16-LE, do not allow users to override that.
codepage = util::cp_utf16le;
} else if(force_codepage) {
codepage = force_codepage;
} else if(languages.empty()) {
codepage = util::cp_windows1252;
} else {
// Non-Unicode installers do not have a defined codepage but instead just assume the
// codepage of the system the installer is run on.
// Look at the list of available languages to guess a suitable codepage.
codepage = languages[0].codepage;
BOOST_FOREACH(const language_entry & language, languages) {
if(language.codepage == util::cp_windows1252) {
codepage = util::cp_windows1252;
break;
}
}
}
header.decode(codepage);
BOOST_FOREACH(language_entry & language, languages) {
language.decode(codepage);
}
if(version < INNO_VERSION(4, 0, 0)) {
load_wizard_and_decompressor(*reader, version, header, *this, entries);
}
load_entries(*reader, version, entries, header.message_count, messages, Messages, languages);
load_entries(*reader, version, entries, header.permission_count, permissions, Permissions);
load_entries(*reader, version, entries, header.type_count, types, Types);
load_entries(*reader, version, entries, header.component_count, components, Components);
load_entries(*reader, version, entries, header.task_count, tasks, Tasks);
load_entries(*reader, version, entries, header.directory_count, directories, Directories);
load_entries(*reader, version, entries, header.file_count, files, Files);
load_entries(*reader, version, entries, header.icon_count, icons, Icons);
load_entries(*reader, version, entries, header.ini_entry_count, ini_entries, IniEntries);
load_entries(*reader, version, entries, header.registry_entry_count, registry_entries, RegistryEntries);
load_entries(*reader, version, entries, header.delete_entry_count, delete_entries, DeleteEntries);
load_entries(*reader, version, entries, header.uninstall_delete_entry_count, uninstall_delete_entries,
load_entries(*reader, entries, header.message_count, messages, Messages);
load_entries(*reader, entries, header.permission_count, permissions, Permissions);
load_entries(*reader, entries, header.type_count, types, Types);
load_entries(*reader, entries, header.component_count, components, Components);
load_entries(*reader, entries, header.task_count, tasks, Tasks);
load_entries(*reader, entries, header.directory_count, directories, Directories);
load_entries(*reader, entries, header.file_count, files, Files);
load_entries(*reader, entries, header.icon_count, icons, Icons);
load_entries(*reader, entries, header.ini_entry_count, ini_entries, IniEntries);
load_entries(*reader, entries, header.registry_entry_count, registry_entries, RegistryEntries);
load_entries(*reader, entries, header.delete_entry_count, delete_entries, DeleteEntries);
load_entries(*reader, entries, header.uninstall_delete_entry_count, uninstall_delete_entries,
UninstallDeleteEntries);
load_entries(*reader, version, entries, header.run_entry_count, run_entries, RunEntries);
load_entries(*reader, version, entries, header.uninstall_run_entry_count, uninstall_run_entries,
load_entries(*reader, entries, header.run_entry_count, run_entries, RunEntries);
load_entries(*reader, entries, header.uninstall_run_entry_count, uninstall_run_entries,
UninstallRunEntries);
if(version >= INNO_VERSION(4, 0, 0)) {
@ -203,12 +208,12 @@ void info::load(std::istream & is, entry_types entries, const setup::version & v
check_is_end(reader, "unknown data at end of primary header stream");
reader = stream::block_reader::get(is, version);
load_entries(*reader, version, entries, header.data_entry_count, data_entries, DataEntries);
load_entries(*reader, entries, header.data_entry_count, data_entries, DataEntries);
check_is_end(reader, "unknown data at end of secondary header stream");
}
void info::load(std::istream & is, entry_types entries) {
void info::load(std::istream & is, entry_types entries, util::codepage_id force_codepage) {
version.load(is);
@ -242,7 +247,7 @@ void info::load(std::istream & is, entry_types entries) {
try {
// Try to parse headers for this version
load(is, entries, version);
try_load(is, entries, force_codepage);
if(warnings) {
// Parsed without errors but with warnings - try other versions first
@ -268,7 +273,7 @@ void info::load(std::istream & is, entry_types entries) {
// Rewind to a previous version that had better results and report those
version.value = listed_version;
warnings.restore();
load(is, entries, version);
try_load(is, entries, force_codepage);
} else {
// Otherwise. report results for the current version
warnings.flush();
@ -289,7 +294,7 @@ void info::load(std::istream & is, entry_types entries) {
}
info::info() { }
info::info() : codepage(0) { }
info::~info() { }
} // namespace setup

13
src/setup/info.hpp

@ -31,6 +31,7 @@
#include "setup/header.hpp"
#include "setup/version.hpp"
#include "util/encoding.hpp"
#include "util/flags.hpp"
namespace setup {
@ -85,6 +86,8 @@ struct info {
setup::version version;
util::codepage_id codepage;
setup::header header;
std::vector<component_entry> components; //! \c Components
@ -126,7 +129,9 @@ struct info {
* \ref loader::offsets::header_offset.
* \param entries What kinds of entries to load.
*/
void load(std::istream & is, entry_types entries);
void load(std::istream & is, entry_types entries, util::codepage_id force_codepage = 0);
private:
/*!
* Load setup headers for a specific version.
@ -141,7 +146,11 @@ struct info {
*
* This function does not set the \ref version member.
*/
void load(std::istream & is, entry_types entries, const setup::version & version);
void try_load(std::istream & is, entry_types entries, util::codepage_id force_codepage);
template <class Entry>
void load_entries(std::istream & is, entry_types entry_types, size_t count,
std::vector<Entry> & entries, entry_types::enum_type entry_type);
};

19
src/setup/ini.cpp

@ -22,6 +22,7 @@
#include <boost/cstdint.hpp>
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
@ -40,25 +41,25 @@ STORED_FLAGS_MAP(stored_ini_flags,
} // anonymous namespace
void ini_entry::load(std::istream & is, const version & version) {
void ini_entry::load(std::istream & is, const info & i) {
if(version < INNO_VERSION(1, 3, 0)) {
if(i.version < INNO_VERSION(1, 3, 0)) {
(void)util::load<boost::uint32_t>(is); // uncompressed size of the entry
}
is >> util::encoded_string(inifile, version.codepage());
is >> util::encoded_string(inifile, i.codepage);
if(inifile.empty()) {
inifile = "{windows}/WIN.INI";
}
is >> util::encoded_string(section, version.codepage());
is >> util::encoded_string(key, version.codepage());
is >> util::encoded_string(value, version.codepage());
is >> util::encoded_string(section, i.codepage);
is >> util::encoded_string(key, i.codepage);
is >> util::encoded_string(value, i.codepage);
load_condition_data(is, version);
load_condition_data(is, i);
load_version_data(is, version);
load_version_data(is, i.version);
if(version.bits() != 16) {
if(i.version.bits() != 16) {
options = stored_flags<stored_ini_flags>(is).get();
} else {
options = stored_flags<stored_ini_flags, 16>(is).get();

4
src/setup/ini.hpp

@ -35,7 +35,7 @@
namespace setup {
struct version;
struct info;
struct ini_entry : public item {
@ -54,7 +54,7 @@ struct ini_entry : public item {
flags options;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

25
src/setup/item.cpp

@ -20,37 +20,38 @@
#include "setup/item.hpp"
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
namespace setup {
void item::load_condition_data(std::istream & is, const version & version) {
void item::load_condition_data(std::istream & is, const info & i) {
if(version >= INNO_VERSION(2, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 8))) {
is >> util::encoded_string(components, version.codepage());
if(i.version >= INNO_VERSION(2, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 8))) {
is >> util::encoded_string(components, i.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());
if(i.version >= INNO_VERSION(2, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 17))) {
is >> util::encoded_string(tasks, i.codepage);
} else {
tasks.clear();
}
if(version >= INNO_VERSION(4, 0, 1)) {
is >> util::encoded_string(languages, version.codepage());
if(i.version >= INNO_VERSION(4, 0, 1)) {
is >> util::encoded_string(languages, i.codepage);
} else {
languages.clear();
}
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, version.codepage());
if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, i.codepage);
} else {
check.clear();
}
if(version >= INNO_VERSION(4, 1, 0)) {
is >> util::encoded_string(after_install, version.codepage());
is >> util::encoded_string(before_install, version.codepage());
if(i.version >= INNO_VERSION(4, 1, 0)) {
is >> util::encoded_string(after_install, i.codepage);
is >> util::encoded_string(before_install, i.codepage);
} else {
after_install.clear(), before_install.clear();
}

3
src/setup/item.hpp

@ -33,6 +33,7 @@
namespace setup {
struct info;
struct version;
struct item {
@ -49,7 +50,7 @@ struct item {
protected:
void load_condition_data(std::istream & is, const version & version);
void load_condition_data(std::istream & is, const info & i);
void load_version_data(std::istream & is, const version & version) {
winver.load(is, version);

41
src/setup/language.cpp

@ -25,6 +25,7 @@
#include "boost/range/begin.hpp"
#include "boost/range/end.hpp"
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
@ -119,17 +120,15 @@ util::codepage_id default_codepage_for_language(boost::uint32_t language) {
} // anonymous namespace
void language_entry::load(std::istream & is, const version & version) {
void language_entry::load(std::istream & is, const info & i) {
if(version >= INNO_VERSION(4, 0, 0)) {
is >> util::encoded_string(name, version.codepage());
} else {
name = "default";
if(i.version >= INNO_VERSION(4, 0, 0)) {
is >> util::binary_string(name);
}
is >> util::binary_string(language_name);
if(version == INNO_VERSION_EXT(5, 5, 7, 1)) {
if(i.version == INNO_VERSION_EXT(5, 5, 7, 1)) {
util::binary_string::skip(is);
}
@ -138,11 +137,11 @@ void language_entry::load(std::istream & is, const version & version) {
is >> util::binary_string(welcome_font);
is >> util::binary_string(copyright_font);
if(version >= INNO_VERSION(4, 0, 0)) {
if(i.version >= INNO_VERSION(4, 0, 0)) {
is >> util::binary_string(data);
}
if(version >= INNO_VERSION(4, 0, 1)) {
if(i.version >= INNO_VERSION(4, 0, 1)) {
is >> util::binary_string(license_text);
is >> util::binary_string(info_before);
is >> util::binary_string(info_after);
@ -152,18 +151,21 @@ void language_entry::load(std::istream & is, const version & version) {
language_id = util::load<boost::uint32_t>(is);
if(version < INNO_VERSION(4, 2, 2)) {
if(i.version < INNO_VERSION(4, 2, 2)) {
codepage = default_codepage_for_language(language_id);
} else if(version < INNO_VERSION(5, 3, 0) || !version.is_unicode()) {
} else if(!i.version.is_unicode()) {
codepage = util::load<boost::uint32_t>(is);
if(!codepage) {
codepage = version.codepage();
codepage = util::cp_windows1252;
}
} else {
if(i.version < INNO_VERSION(5, 3, 0)) {
(void)util::load<boost::uint32_t>(is);
}
codepage = util::cp_utf16le;
}
if(version >= INNO_VERSION(4, 2, 2)) {
if(i.version >= INNO_VERSION(4, 2, 2)) {
util::to_utf8(language_name, util::cp_utf16le);
} else {
util::to_utf8(language_name, codepage);
@ -171,7 +173,7 @@ void language_entry::load(std::istream & is, const version & version) {
dialog_font_size = util::load<boost::uint32_t>(is);
if(version < INNO_VERSION(4, 1, 0)) {
if(i.version < INNO_VERSION(4, 1, 0)) {
dialog_font_standard_height = util::load<boost::uint32_t>(is);
} else {
dialog_font_standard_height = 0;
@ -181,11 +183,11 @@ void language_entry::load(std::istream & is, const version & version) {
welcome_font_size = util::load<boost::uint32_t>(is);
copyright_font_size = util::load<boost::uint32_t>(is);
if(version == INNO_VERSION_EXT(5, 5, 7, 1)) {
if(i.version == INNO_VERSION_EXT(5, 5, 7, 1)) {
util::load<boost::uint32_t>(is); // always 8 or 9?
}
if(version >= INNO_VERSION(5, 2, 3)) {
if(i.version >= INNO_VERSION(5, 2, 3)) {
right_to_left = util::load_bool(is);
} else {
right_to_left = false;
@ -193,4 +195,13 @@ void language_entry::load(std::istream & is, const version & version) {
}
void language_entry::decode(util::codepage_id codepage) {
util::to_utf8(name, codepage);
if(name.empty()) {
name = "default";
}
}
} // namespace setup

8
src/setup/language.hpp

@ -31,9 +31,11 @@
#include <boost/cstdint.hpp>
#include "util/encoding.hpp"
namespace setup {
struct version;
struct info;
struct language_entry {
@ -60,7 +62,9 @@ struct language_entry {
bool right_to_left;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
void decode(util::codepage_id codepage);
};

12
src/setup/message.cpp

@ -22,6 +22,7 @@
#include <boost/cstdint.hpp>
#include "setup/info.hpp"
#include "setup/language.hpp"
#include "setup/version.hpp"
#include "util/encoding.hpp"
@ -29,23 +30,22 @@
namespace setup {
void message_entry::load(std::istream & is, const version & version,
const std::vector<language_entry> & languages) {
void message_entry::load(std::istream & is, const info & i) {
is >> util::encoded_string(name, version.codepage());
is >> util::encoded_string(name, i.codepage);
is >> util::binary_string(value);
language = util::load<boost::int32_t>(is);
boost::uint32_t codepage;
if(language < 0) {
codepage = version.codepage();
} else if(size_t(language) >= languages.size()) {
codepage = i.codepage;
} else if(size_t(language) >= i.languages.size()) {
// Unknown language, don't try to decode
value.clear();
return;
} else {
codepage = languages[size_t(language)].codepage;
codepage = i.languages[size_t(language)].codepage;
}
util::to_utf8(value, codepage);

7
src/setup/message.hpp

@ -28,12 +28,10 @@
#include <string>
#include <iosfwd>
#include <vector>
namespace setup {
struct version;
struct language_entry;
struct info;
struct message_entry {
@ -48,8 +46,7 @@ struct message_entry {
// Index into the default language entry list or -1.
int language;
void load(std::istream & is, const version & version,
const std::vector<language_entry> & languages);
void load(std::istream & is, const info & i);
};

5
src/setup/permission.cpp

@ -20,14 +20,13 @@
#include "setup/permission.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
namespace setup {
void permission_entry::load(std::istream & is, const version & version) {
void permission_entry::load(std::istream & is, const info & i) {
(void)version;
(void)i;
is >> util::binary_string(permissions); // an array of TGrantPermissionEntry's

4
src/setup/permission.hpp

@ -31,7 +31,7 @@
namespace setup {
struct version;
struct info;
struct permission_entry {
@ -39,7 +39,7 @@ struct permission_entry {
std::string permissions;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

41
src/setup/registry.cpp

@ -22,6 +22,7 @@
#include <boost/cstdint.hpp>
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
@ -58,73 +59,73 @@ STORED_ENUM_MAP(stored_registry_entry_type_2, registry_entry::None,
} // anonymous namespace
void registry_entry::load(std::istream & is, const version & version) {
void registry_entry::load(std::istream & is, const info & i) {
if(version < INNO_VERSION(1, 3, 0)) {
if(i.version < INNO_VERSION(1, 3, 0)) {
(void)util::load<boost::uint32_t>(is); // uncompressed size of the entry
}
is >> util::encoded_string(key, version.codepage());
if(version.bits() != 16) {
is >> util::encoded_string(name, version.codepage());
is >> util::encoded_string(key, i.codepage);
if(i.version.bits() != 16) {
is >> util::encoded_string(name, i.codepage);
} else {
name.clear();
}
is >> util::binary_string(value);
load_condition_data(is, version);
load_condition_data(is, i);
if(version >= INNO_VERSION(4, 0, 11) && version < INNO_VERSION(4, 1, 0)) {
is >> util::encoded_string(permissions, version.codepage());
if(i.version >= INNO_VERSION(4, 0, 11) && i.version < INNO_VERSION(4, 1, 0)) {
is >> util::binary_string(permissions);
} else {
permissions.clear();
}
load_version_data(is, version);
load_version_data(is, i.version);
if(version.bits() != 16) {
if(i.version.bits() != 16) {
hive = hive_name(util::load<boost::uint32_t>(is) & ~0x80000000);
} else {
hive = Unset;
}
if(version >= INNO_VERSION(4, 1, 0)) {
if(i.version >= INNO_VERSION(4, 1, 0)) {
permission = util::load<boost::int16_t>(is);
} else {
permission = -1;
}
if(version >= INNO_VERSION(5, 2, 5)) {
if(i.version >= INNO_VERSION(5, 2, 5)) {
type = stored_enum<stored_registry_entry_type_2>(is).get();
} else if(version.bits() != 16) {
} else if(i.version.bits() != 16) {
type = stored_enum<stored_registry_entry_type_1>(is).get();
} else {
type = stored_enum<stored_registry_entry_type_0>(is).get();
}
stored_flag_reader<flags> flagreader(is, version.bits());
stored_flag_reader<flags> flagreader(is, i.version.bits());
if(version.bits() != 16) {
if(i.version.bits() != 16) {
flagreader.add(CreateValueIfDoesntExist);
flagreader.add(UninsDeleteValue);
}
flagreader.add(UninsClearValue);
flagreader.add(UninsDeleteEntireKey);
flagreader.add(UninsDeleteEntireKeyIfEmpty);
if(version >= INNO_VERSION(1, 2, 6)) {
if(i.version >= INNO_VERSION(1, 2, 6)) {
flagreader.add(PreserveStringType);
}
if(version >= INNO_VERSION(1, 3, 9)) {
if(i.version >= INNO_VERSION(1, 3, 9)) {
flagreader.add(DeleteKey);
flagreader.add(DeleteValue);
}
if(version >= INNO_VERSION(1, 3, 12)) {
if(i.version >= INNO_VERSION(1, 3, 12)) {
flagreader.add(NoError);
}
if(version >= INNO_VERSION(1, 3, 16)) {
if(i.version >= INNO_VERSION(1, 3, 16)) {
flagreader.add(DontCreateKey);
}
if(version >= INNO_VERSION(5, 1, 0)) {
if(i.version >= INNO_VERSION(5, 1, 0)) {
flagreader.add(Bits32);
flagreader.add(Bits64);
}

4
src/setup/registry.hpp

@ -36,7 +36,7 @@
namespace setup {
struct version;
struct info;
struct registry_entry : public item {
@ -90,7 +90,7 @@ struct registry_entry : public item {
flags options;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

47
src/setup/run.cpp

@ -22,6 +22,7 @@
#include <boost/cstdint.hpp>
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
@ -38,39 +39,39 @@ STORED_ENUM_MAP(stored_run_wait_condition, run_entry::WaitUntilTerminated,
} // anonymous namespace
void run_entry::load(std::istream & is, const version & version) {
void run_entry::load(std::istream & is, const info & i) {
if(version < INNO_VERSION(1, 3, 0)) {
if(i.version < INNO_VERSION(1, 3, 0)) {
(void)util::load<boost::uint32_t>(is); // uncompressed size of the entry
}
is >> util::encoded_string(name, version.codepage());
is >> util::encoded_string(parameters, version.codepage());
is >> util::encoded_string(working_dir, version.codepage());
if(version >= INNO_VERSION(1, 3, 9)) {
is >> util::encoded_string(run_once_id, version.codepage());
is >> util::encoded_string(name, i.codepage);
is >> util::encoded_string(parameters, i.codepage);
is >> util::encoded_string(working_dir, i.codepage);
if(i.version >= INNO_VERSION(1, 3, 9)) {
is >> util::encoded_string(run_once_id, i.codepage);
} else {
run_once_id.clear();
}
if(version >= INNO_VERSION(2, 0, 2)) {
is >> util::encoded_string(status_message, version.codepage());
if(i.version >= INNO_VERSION(2, 0, 2)) {
is >> util::encoded_string(status_message, i.codepage);
} else {
status_message.clear();
}
if(version >= INNO_VERSION(5, 1, 13)) {
is >> util::encoded_string(verb, version.codepage());
if(i.version >= INNO_VERSION(5, 1, 13)) {
is >> util::encoded_string(verb, i.codepage);
} else {
verb.clear();
}
if(version >= INNO_VERSION(2, 0, 0) || version.is_isx()) {
is >> util::encoded_string(description, version.codepage());
if(i.version >= INNO_VERSION(2, 0, 0) || i.version.is_isx()) {
is >> util::encoded_string(description, i.codepage);
}
load_condition_data(is, version);
load_condition_data(is, i);
load_version_data(is, version);
load_version_data(is, i.version);
if(version >= INNO_VERSION(1, 3, 24)) {
if(i.version >= INNO_VERSION(1, 3, 24)) {
show_command = util::load<boost::int32_t>(is);
} else {
show_command = 0;
@ -78,28 +79,28 @@ void run_entry::load(std::istream & is, const version & version) {
wait = stored_enum<stored_run_wait_condition>(is).get();
stored_flag_reader<flags> flagreader(is, version.bits());
stored_flag_reader<flags> flagreader(is, i.version.bits());
if(version >= INNO_VERSION(1, 2, 3)) {
if(i.version >= INNO_VERSION(1, 2, 3)) {
flagreader.add(ShellExec);
}
if(version >= INNO_VERSION(1, 3, 9) || (version.is_isx() && version >= INNO_VERSION(1, 3, 8))) {
if(i.version >= INNO_VERSION(1, 3, 9) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 8))) {
flagreader.add(SkipIfDoesntExist);
}
if(version >= INNO_VERSION(2, 0, 0)) {
if(i.version >= INNO_VERSION(2, 0, 0)) {
flagreader.add(PostInstall);
flagreader.add(Unchecked);
flagreader.add(SkipIfSilent);
flagreader.add(SkipIfNotSilent);
}
if(version >= INNO_VERSION(2, 0, 8)) {
if(i.version >= INNO_VERSION(2, 0, 8)) {
flagreader.add(HideWizard);
}
if(version >= INNO_VERSION(5, 1, 10)) {
if(i.version >= INNO_VERSION(5, 1, 10)) {
flagreader.add(Bits32);
flagreader.add(Bits64);
}
if(version >= INNO_VERSION(5, 2, 0)) {
if(i.version >= INNO_VERSION(5, 2, 0)) {
flagreader.add(RunAsOriginalUser);
}

4
src/setup/run.hpp

@ -35,7 +35,7 @@
namespace setup {
struct version;
struct info;
struct run_entry : public item {
@ -72,7 +72,7 @@ struct run_entry : public item {
flags options;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

31
src/setup/task.cpp

@ -22,52 +22,53 @@
#include <boost/cstdint.hpp>
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
namespace setup {
void task_entry::load(std::istream & is, const version & version) {
void task_entry::load(std::istream & is, const info & i) {
is >> util::encoded_string(name, version.codepage());
is >> util::encoded_string(description, version.codepage());
is >> util::encoded_string(group_description, version.codepage());
is >> util::encoded_string(components, version.codepage());
if(version >= INNO_VERSION(4, 0, 1)) {
is >> util::encoded_string(languages, version.codepage());
is >> util::encoded_string(name, i.codepage);
is >> util::encoded_string(description, i.codepage);
is >> util::encoded_string(group_description, i.codepage);
is >> util::encoded_string(components, i.codepage);
if(i.version >= INNO_VERSION(4, 0, 1)) {
is >> util::encoded_string(languages, i.codepage);
} else {
languages.clear();
}
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, version.codepage());
if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, i.codepage);
} else {
check.clear();
}
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(3, 0, 3))) {
if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.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))) {
if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(3, 0, 4))) {
used = util::load_bool(is);
} else {
used = true;
}
winver.load(is, version);
winver.load(is, i.version);
stored_flag_reader<flags> flagreader(is);
flagreader.add(Exclusive);
flagreader.add(Unchecked);
if(version >= INNO_VERSION(2, 0, 5)) {
if(i.version >= INNO_VERSION(2, 0, 5)) {
flagreader.add(Restart);
}
if(version >= INNO_VERSION(2, 0, 6)) {
if(i.version >= INNO_VERSION(2, 0, 6)) {
flagreader.add(CheckedOnce);
}
if(version >= INNO_VERSION(4, 2, 3)) {
if(i.version >= INNO_VERSION(4, 2, 3)) {
flagreader.add(DontInheritCheck);
}

4
src/setup/task.hpp

@ -35,7 +35,7 @@
namespace setup {
struct version;
struct info;
struct task_entry {
@ -63,7 +63,7 @@ struct task_entry {
flags options;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

21
src/setup/type.cpp

@ -20,6 +20,7 @@
#include "setup/type.hpp"
#include "setup/info.hpp"
#include "setup/version.hpp"
#include "util/load.hpp"
#include "util/storedenum.hpp"
@ -51,35 +52,35 @@ NAMED_FLAGS(setup::type_flags)
namespace setup {
void type_entry::load(std::istream & is, const version & version) {
void type_entry::load(std::istream & is, const info & i) {
USE_FLAG_NAMES(setup::type_flags)
is >> util::encoded_string(name, version.codepage());
is >> util::encoded_string(description, version.codepage());
if(version >= INNO_VERSION(4, 0, 1)) {
is >> util::encoded_string(languages, version.codepage());
is >> util::encoded_string(name, i.codepage);
is >> util::encoded_string(description, i.codepage);
if(i.version >= INNO_VERSION(4, 0, 1)) {
is >> util::encoded_string(languages, i.codepage);
} else {
languages.clear();
}
if(version >= INNO_VERSION(4, 0, 0) || (version.is_isx() && version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, version.codepage());
if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) {
is >> util::encoded_string(check, i.codepage);
} else {
check.clear();
}
winver.load(is, version);
winver.load(is, i.version);
type_flags options = stored_flags<stored_type_flags>(is).get();
custom_type = ((options & CustomSetupType) != 0);
if(version >= INNO_VERSION(4, 0, 3)) {
if(i.version >= INNO_VERSION(4, 0, 3)) {
type = stored_enum<stored_setup_type>(is).get();
} else {
type = User;
}
if(version >= INNO_VERSION(4, 0, 0)) {
if(i.version >= INNO_VERSION(4, 0, 0)) {
size = util::load<boost::uint64_t>(is);
} else {
size = util::load<boost::uint32_t>(is);

4
src/setup/type.hpp

@ -37,7 +37,7 @@
namespace setup {
struct version;
struct info;
struct type_entry {
@ -63,7 +63,7 @@ struct type_entry {
boost::uint64_t size;
void load(std::istream & is, const version & version);
void load(std::istream & is, const info & i);
};

3
src/setup/version.hpp

@ -81,9 +81,6 @@ struct version {
bool is_unicode() const { return (variant & Unicode) != 0; }
bool is_isx() const { return (variant & ISX) != 0; }
//! \return the Windows codepage used to encode strings
boost::uint32_t codepage() const { return boost::uint32_t(is_unicode() ? 1200 : 1252); }
//! \return true if the version stored might not be correct
bool is_ambiguous() const;

Loading…
Cancel
Save