diff --git a/SConstruct b/SConstruct index 5e50d9db..fabd14e2 100644 --- a/SConstruct +++ b/SConstruct @@ -492,7 +492,7 @@ def BuildStub(compression, solid, unicode): if solid: suffix = '_solid' if unicode: - suffix += 'W' + suffix += '.5_0' env = stub_uenv.Clone() else: env = stub_env.Clone() diff --git a/Source/build.cpp b/Source/build.cpp index 9602e734..990fa3a4 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -57,6 +57,12 @@ return rc; \ } while (false) +const LONG available_stub_variants[] = +{ + 0x00000000, // classic ANSI stub + 0x00050000 // Unicode stub for Windows 2000 and more recent (5.0+) +}; + using namespace std; namespace { // begin anonymous namespace @@ -116,8 +122,9 @@ CEXEBuild::CEXEBuild() : definedlist.add(_T("NSIS_VERSION"), NSIS_VERSION); + target_minimal_OS=0; build_unicode=false; - definedlist.add(_T("NSIS_CHAR_SIZE"), _T("1")); // this can change after a UnicodeInstaller instruction is found + definedlist.add(_T("NSIS_CHAR_SIZE"), _T("1")); // this can change after a TargetMinimalOS instruction is found // automatically generated header file containing all defines #include @@ -3564,12 +3571,13 @@ void CEXEBuild::VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList) } #ifdef _UNICODE -int CEXEBuild::set_build_unicode(bool unicode_installer) +int CEXEBuild::set_target_minimal_OS(int major, int minor) { - build_unicode = unicode_installer; + target_minimal_OS = MAKELONG(minor,major); + build_unicode = major>=5; definedlist.del(_T("NSIS_UNICODE")); definedlist.del(_T("NSIS_CHAR_SIZE")); - if (unicode_installer) // update defines depending on target installer type + if (build_unicode) // update defines depending on target installer type { definedlist.add(_T("NSIS_UNICODE")); definedlist.add(_T("NSIS_CHAR_SIZE"), _T("2")); @@ -3589,14 +3597,26 @@ int CEXEBuild::set_compressor(const tstring& compressor, const bool solid) { return load_stub(); } +tstring CEXEBuild::get_stub_variant_suffix() +{ + LONG variant = 0; + for (int index = 0; index < COUNTOF(available_stub_variants); index++) + { + if (target_minimal_OS >= available_stub_variants[index]) + variant = available_stub_variants[index]; + else + break; + } + if (variant == 0) + return tstring(); + TCHAR buf[32]; + _stprintf(buf, _T(".%d_%d"), HIWORD(variant), LOWORD(variant)); + return tstring(buf); +} + int CEXEBuild::load_stub() { -#ifdef _UNICODE - if (build_unicode) - return update_exehead(stub_filename+_T('W'), &m_exehead_original_size); - else -#endif - return update_exehead(stub_filename, &m_exehead_original_size); + return update_exehead(stub_filename+get_stub_variant_suffix(), &m_exehead_original_size); } int CEXEBuild::update_exehead(const tstring& file, size_t *size/*=NULL*/) { diff --git a/Source/build.h b/Source/build.h index 528a27c7..fb81535e 100644 --- a/Source/build.h +++ b/Source/build.h @@ -136,8 +136,9 @@ class CEXEBuild { int prepare_uninstaller(); int pack_exe_header(); - int set_build_unicode(bool unicode_installer); + int set_target_minimal_OS(int major, int minor); int set_compressor(const tstring& compressor, const bool solid); + tstring get_stub_variant_suffix(); int load_stub(); int update_exehead(const tstring& file, size_t *size=NULL); void update_exehead(const unsigned char *new_exehead, size_t new_size); @@ -395,6 +396,7 @@ class CEXEBuild { int build_compress_dict_size; bool no_space_texts; + LONG target_minimal_OS; bool build_unicode; bool has_called_write_output; diff --git a/Source/script.cpp b/Source/script.cpp index e68130ad..f767c7d0 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -2686,20 +2686,21 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_OK; #ifdef _UNICODE - case TOK_UNICODEINSTALLER: + case TOK_TARGETMINIMALOS: { if (build_compressor_set) { - ERROR_MSG(_T("Error: can't change type of installer after data already got compressed or header already changed!\n")); + ERROR_MSG(_T("Error: can't change target minimal OS version after data already got compressed or header already changed!\n")); return PS_ERROR; } - int param=line.gettoken_enum(1,_T("off\0on\0")); - if (param==-1) PRINTHELP() - SCRIPT_MSG(_T("UnicodeInstaller: %s\n"),line.gettoken_str(1)); - if (set_build_unicode(param != 0) != PS_OK) + int major = 0, minor = 0; + if (_stscanf(line.gettoken_str(1), _T("%d.%d"), &major, &minor) == 0) + PRINTHELP() + if (set_target_minimal_OS(major,minor) != PS_OK) // Windows 5.0 or more recent requested? => Unicode support { - ERROR_MSG(_T("Error: error while setting type of installer! (stub not found?)\n")); + ERROR_MSG(_T("Error: error while setting target minimal OS! (adequate stub not found?)\n")); return PS_ERROR; } + SCRIPT_MSG(_T("TargetMinimalOS: %d.%d %s\n"),major,minor,build_unicode?_T("(Unicode installer)"):_T("")); } return PS_OK; #endif diff --git a/Source/tokens.cpp b/Source/tokens.cpp index e747c645..ae5309e7 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -217,7 +217,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_STRLEN,_T("StrLen"),2,0,_T("$(user_var: length output) str"),TP_CODE}, {TOK_SUBCAPTION,_T("SubCaption"),2,0,_T("page_number(0-4) new_subcaption"),TP_GLOBAL}, #ifdef _UNICODE -{TOK_UNICODEINSTALLER,_T("UnicodeInstaller"),1,0,_T("(on|off)"),TP_GLOBAL}, +{TOK_TARGETMINIMALOS,_T("TargetMinimalOS"),1,0,_T("windows_version"),TP_GLOBAL}, #endif {TOK_UNINSTALLEXENAME,_T("UninstallExeName"),0,0,_T("no longer supported, use WriteUninstaller from section."),TP_ALL}, {TOK_UNINSTCAPTION,_T("UninstallCaption"),1,0,_T("uninstaller_caption"),TP_GLOBAL}, diff --git a/Source/tokens.h b/Source/tokens.h index 50eb486e..3320ee70 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -71,7 +71,7 @@ enum TOK_VI_ADDKEY, TOK_VI_SETPRODUCTVERSION, #ifdef _UNICODE - TOK_UNICODEINSTALLER, + TOK_TARGETMINIMALOS, #endif TOK_MISCBUTTONTEXT,