VirtualBox

Changeset 68239 in vbox


Ignore:
Timestamp:
Aug 2, 2017 12:39:12 PM (7 years ago)
Author:
vboxsync
Message:

Unattended: Added detectedOSLanguages and language attributes to deal with the windows installer's stupid UILanguage requirement. The specified language must be supported by the installation media, probably by way of lang.ini, which means we need to implement UDF support to really get this right. For now, looking for language specifier in the ISO name (ASSUMES filename unchanged since MSDN download).

Location:
trunk/src/VBox
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp

    r68213 r68239  
    13371337    Bstr bstrDetectedFlavor;
    13381338    CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedOSFlavor)(bstrDetectedFlavor.asOutParam()), RTEXITCODE_FAILURE);
     1339    Bstr bstrDetectedLanguages;
     1340    CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedOSLanguages)(bstrDetectedLanguages.asOutParam()), RTEXITCODE_FAILURE);
    13391341    Bstr bstrDetectedHints;
    13401342    CHECK_ERROR2_RET(hrc, ptrUnattended, COMGETTER(DetectedOSHints)(bstrDetectedHints.asOutParam()), RTEXITCODE_FAILURE);
     
    13431345                 "OSVersion=\"%ls\"\n"
    13441346                 "OSFlavor=\"%ls\"\n"
     1347                 "OSLanguages=\"%ls\"\n"
    13451348                 "OSHints=\"%ls\"\n",
    13461349                 bstrDetectedOSTypeId.raw(),
    13471350                 bstrDetectedVersion.raw(),
    13481351                 bstrDetectedFlavor.raw(),
     1352                 bstrDetectedLanguages.raw(),
    13491353                 bstrDetectedHints.raw());
    13501354    else
    13511355    {
    13521356        RTMsgInfo("Detected '%s' to be:\n", szIsoPath);
    1353         RTPrintf("    OS TypeId  = %ls\n"
    1354                  "    OS Version = %ls\n"
    1355                  "    OS Flavor  = %ls\n"
    1356                  "    OS Hints   = %ls\n",
     1357        RTPrintf("    OS TypeId    = %ls\n"
     1358                 "    OS Version   = %ls\n"
     1359                 "    OS Flavor    = %ls\n"
     1360                 "    OS Languages = %ls\n"
     1361                 "    OS Hints     = %ls\n",
    13571362                 bstrDetectedOSTypeId.raw(),
    13581363                 bstrDetectedVersion.raw(),
    13591364                 bstrDetectedFlavor.raw(),
     1365                 bstrDetectedLanguages.raw(),
    13601366                 bstrDetectedHints.raw());
    13611367    }
     
    13981404        { "--validation-kit-iso",               'K', RTGETOPT_REQ_STRING },
    13991405        { "--locale",                           'l', RTGETOPT_REQ_STRING },
    1400         { "--country",                          'L', RTGETOPT_REQ_STRING },
     1406        { "--country",                          'Y', RTGETOPT_REQ_STRING },
    14011407        { "--time-zone",                        'z', RTGETOPT_REQ_STRING },
    14021408        { "--proxy",                            'y', RTGETOPT_REQ_STRING },
     
    14111417        { "--post-install-command",             'P', RTGETOPT_REQ_STRING },
    14121418        { "--extra-install-kernel-parameters",  'I', RTGETOPT_REQ_STRING },
     1419        { "--language",                         'L', RTGETOPT_REQ_STRING },
    14131420        // start vm related options:
    14141421        { "--session-type",                     'S', RTGETOPT_REQ_STRING },
     
    14971504                break;
    14981505
    1499             case 'L':   // --country
     1506            case 'Y':   // --country
    15001507                CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Country)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
    15011508                break;
     
    15521559            case 'I':   // --extra-install-kernel-parameters
    15531560                CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(ExtraInstallKernelParameters)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
     1561                break;
     1562
     1563            case 'L':   // --language
     1564                CHECK_ERROR2_RET(hrc, ptrUnattended, COMSETTER(Language)(Bstr(ValueUnion.psz).raw()), RTEXITCODE_FAILURE);
    15541565                break;
    15551566
     
    16781689    SHOW_STR_ATTR(PostInstallCommand,            "postInstallCommand");
    16791690    SHOW_STR_ATTR(ExtraInstallKernelParameters,  "extraInstallKernelParameters");
     1691    SHOW_STR_ATTR(Language,                      "language");
    16801692    SHOW_STR_ATTR(DetectedOSTypeId,              "detectedOSTypeId");
    16811693    SHOW_STR_ATTR(DetectedOSVersion,             "detectedOSVersion");
    16821694    SHOW_STR_ATTR(DetectedOSFlavor,              "detectedOSFlavor");
     1695    SHOW_STR_ATTR(DetectedOSLanguages,           "detectedOSLanguages");
    16831696    SHOW_STR_ATTR(DetectedOSHints,               "detectedOSHints");
    16841697
  • trunk/src/VBox/Main/UnattendedTemplates/win_nt6_unattended.xml

    r68222 r68239  
    88            publicKeyToken="31bf3856ad364e35" language="neutral"
    99            versionScope="nonSxS">
    10             <InputLocale>@@VBOX_INSERT_DASH_LOCALE@@</InputLocale>
     10            <InputLocale>en-US</InputLocale>
    1111            <SystemLocale>@@VBOX_INSERT_DASH_LOCALE@@</SystemLocale>
    12             <UILanguage>@@VBOX_INSERT_DASH_LOCALE@@</UILanguage>
    1312            <UserLocale>@@VBOX_INSERT_DASH_LOCALE@@</UserLocale>
     13            <!-- UILanguage must match the installation media language.  Stuff like de-CH does not work for
     14                 example de_windows_7_enterprise_with_sp1_x64_dvd_u_677649.iso.  However, stupidly we cannot
     15                 omit this element (kudos to brilliant minds at MS).  -->
     16            <UILanguage>@@VBOX_INSERT_LANGUAGE@@</UILanguage>
    1417        </component>
    1518
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r68133 r68239  
    37783778  <interface
    37793779    name="IUnattended" extends="$unknown"
    3780     uuid="3107e9fd-7b3a-4008-91de-24273f605a8e"
     3780    uuid="6f89464f-7193-426c-a41f-522e8f537fa0"
    37813781    wsmap="managed"
    37823782    reservedMethods="4" reservedAttributes="16"
     
    39233923    </attribute>
    39243924
     3925    <attribute name="language" type="wstring">
     3926      <desc>
     3927        This is more or less a Windows specific setting for choosing the UI language
     3928        setting of the installer.
     3929
     3930        The value should be from the list availble via <link to="IUnattended::detectedOSLanguages"/>.
     3931        The typical format is {language-code}-{COUNTRY} but windows may also use
     3932        {16-bit code}:{32-bit code} or insert another component between the language
     3933        and country codes.  We consider the format guest OS specific.
     3934
     3935        Note that it is crucial that this is correctly specified for Windows
     3936        installations.  If an unsupported value is given the installer will ask
     3937        for an installation language and wait for user input.  Best to leave it
     3938        to the default value.
     3939
     3940        The default is the first one from <link to="IUnattended::detectedOSLanguages"/>.
     3941      </desc>
     3942    </attribute>
     3943
    39253944    <attribute name="country" type="wstring">
    39263945      <desc>
     
    40674086    </attribute>
    40684087
     4088    <attribute name="detectedOSLanguages" type="wstring" readonly="yes">
     4089      <desc>
     4090        The space separated list of (Windows) installation UI languages we detected (lang.ini).
     4091
     4092        The language specifier format is specific to the guest OS.  They are
     4093        used to set <link to="IUnattended::language"/>.
     4094
     4095        Set by <link to="IUnattended::detectIsoOS"/> or <link to="IUnattended::prepare"/>.
     4096
     4097        Partially implemented.
     4098      </desc>
     4099    </attribute>
     4100
    40694101    <attribute name="detectedOSHints" type="wstring" readonly="yes">
    40704102      <desc>
     
    40824114        Detects the OS on the ISO given by <link to="IUnattended::isoPath"/> and sets
    40834115        <link to="IUnattended::detectedOSTypeId"/>, <link to="IUnattended::detectedOSVersion"/>
    4084         <link to="IUnattended::detectedOSFlavor"/>, and <link to="IUnattended::detectedOSHints"/>.
    4085 
    4086         Not yet implemented.
     4116        <link to="IUnattended::detectedOSFlavor"/>, <link to="IUnattended::detectedOSLanguages"/>,
     4117        and <link to="IUnattended::detectedOSHints"/>.
     4118
     4119        Not really yet implemented.
    40874120      </desc>
    40884121    </method>
  • trunk/src/VBox/Main/include/UnattendedImpl.h

    r68164 r68239  
    6060    PCRTTIMEZONEINFO i_getTimeZoneInfo() const;
    6161    Utf8Str const &i_getLocale() const;
     62    Utf8Str const &i_getLanguage() const;
    6263    Utf8Str const &i_getCountry() const;
    6364    bool           i_isMinimalInstallation() const;
     
    100101    PCRTTIMEZONEINFO mpTimeZoneInfo;
    101102    Utf8Str         mStrLocale;
     103    Utf8Str         mStrLanguage;           /**< (only relevant for windows at the moment) */
    102104    Utf8Str         mStrCountry;
    103105    RTCList<RTCString, RTCString *> mPackageSelectionAdjustments;
     
    110112    Utf8Str         mStrPostInstallCommand;
    111113    Utf8Str         mStrExtraInstallKernelParameters;
     114
     115    bool            mfDoneDetectIsoOS;         /**< Set by detectIsoOS(), cleared by setIsoPath(). */
    112116    Utf8Str         mStrDetectedOSTypeId;
    113117    Utf8Str         mStrDetectedOSVersion;
    114118    Utf8Str         mStrDetectedOSFlavor;
     119    RTCList<RTCString, RTCString *> mDetectedOSLanguages; /**< (only relevant for windows at the moment) */
    115120    Utf8Str         mStrDetectedOSHints;
    116121    /** @} */
     
    166171    HRESULT getLocale(com::Utf8Str &aLocale);
    167172    HRESULT setLocale(const com::Utf8Str &aLocale);
     173    HRESULT getLanguage(com::Utf8Str &aLanguage);
     174    HRESULT setLanguage(const com::Utf8Str &aLanguage);
    168175    HRESULT getCountry(com::Utf8Str &aCountry);
    169176    HRESULT setCountry(const com::Utf8Str &aCountry);
     
    190197    HRESULT getDetectedOSTypeId(com::Utf8Str &aDetectedOSTypeId);
    191198    HRESULT getDetectedOSVersion(com::Utf8Str &aDetectedOSVersion);
     199    HRESULT getDetectedOSLanguages(com::Utf8Str &aDetectedOSLanguages);
    192200    HRESULT getDetectedOSFlavor(com::Utf8Str &aDetectedOSFlavor);
    193201    HRESULT getDetectedOSHints(com::Utf8Str &aDetectedOSHints);
  • trunk/src/VBox/Main/src-server/UnattendedImpl.cpp

    r68222 r68239  
    151151Unattended::Unattended()
    152152    : mhThreadReconfigureVM(NIL_RTNATIVETHREAD), mfRtcUseUtc(false), mfGuestOs64Bit(false)
    153     , mpInstaller(NULL), mpTimeZoneInfo(NULL), mfIsDefaultAuxiliaryBasePath(true)
     153    , mpInstaller(NULL), mpTimeZoneInfo(NULL), mfIsDefaultAuxiliaryBasePath(true), mfDoneDetectIsoOS(false)
    154154{ }
    155155
     
    231231HRESULT Unattended::detectIsoOS()
    232232{
     233    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     234
     235    /*
     236     * Just fake up some windows installation media locale (for <UILanguage>).
     237     * Note! The translation here isn't perfect.  Feel free to send us a patch.
     238     */
     239    /** @todo Looks like we can get this from sources/lang.ini as well as
     240     *        sources/??-* and boot/??-*.  Will require UDF reader. */
     241    char        szTmp[16];
     242    const char *pszFilename = RTPathFilename(mStrIsoPath.c_str());
     243    if (   pszFilename
     244        && RT_C_IS_ALPHA(pszFilename[0])
     245        && RT_C_IS_ALPHA(pszFilename[1])
     246        && (pszFilename[2] == '-' || pszFilename[2] == '_') )
     247    {
     248        szTmp[0] = RT_C_TO_LOWER(pszFilename[0]);
     249        szTmp[1] = RT_C_TO_LOWER(pszFilename[1]);
     250        szTmp[2] = '-';
     251        if (szTmp[0] == 'e' && szTmp[1] == 'n')
     252            strcpy(&szTmp[3], "US");
     253        else if (szTmp[0] == 'a' && szTmp[1] == 'r')
     254            strcpy(&szTmp[3], "SA");
     255        else if (szTmp[0] == 'd' && szTmp[1] == 'a')
     256            strcpy(&szTmp[3], "DK");
     257        else if (szTmp[0] == 'e' && szTmp[1] == 't')
     258            strcpy(&szTmp[3], "EE");
     259        else if (szTmp[0] == 'e' && szTmp[1] == 'l')
     260            strcpy(&szTmp[3], "GR");
     261        else if (szTmp[0] == 'h' && szTmp[1] == 'e')
     262            strcpy(&szTmp[3], "IL");
     263        else if (szTmp[0] == 'j' && szTmp[1] == 'a')
     264            strcpy(&szTmp[3], "JP");
     265        else if (szTmp[0] == 's' && szTmp[1] == 'v')
     266            strcpy(&szTmp[3], "SE");
     267        else if (szTmp[0] == 'u' && szTmp[1] == 'k')
     268            strcpy(&szTmp[3], "UA");
     269        else if (szTmp[0] == 'c' && szTmp[1] == 's')
     270            strcpy(szTmp, "cs-CZ");
     271        else if (szTmp[0] == 'n' && szTmp[1] == 'o')
     272            strcpy(szTmp, "nb-NO");
     273        else if (szTmp[0] == 'p' && szTmp[1] == 'p')
     274            strcpy(szTmp, "pt-PT");
     275        else if (szTmp[0] == 'p' && szTmp[1] == 't')
     276            strcpy(szTmp, "pt-BR");
     277        else if (szTmp[0] == 'c' && szTmp[1] == 'n')
     278            strcpy(szTmp, "zh-CN");
     279        else if (szTmp[0] == 'h' && szTmp[1] == 'k')
     280            strcpy(szTmp, "zh-HK");
     281        else if (szTmp[0] == 't' && szTmp[1] == 'w')
     282            strcpy(szTmp, "zh-TW");
     283        else if (szTmp[0] == 's' && szTmp[1] == 'r')
     284            strcpy(szTmp, "sr-Latn-CS"); /* hmm */
     285        else
     286        {
     287            szTmp[3] = RT_C_TO_UPPER(pszFilename[0]);
     288            szTmp[4] = RT_C_TO_UPPER(pszFilename[1]);
     289            szTmp[5] = '\0';
     290        }
     291    }
     292    else
     293        strcpy(szTmp, "en-US");
     294    try
     295    {
     296        mDetectedOSLanguages.clear();
     297        mDetectedOSLanguages.append(szTmp);
     298    }
     299    catch (std::bad_alloc)
     300    {
     301        return E_OUTOFMEMORY;
     302    }
     303
     304    /** @todo implement actual detection logic. */
    233305    return E_NOTIMPL;
    234306}
     
    319391
    320392    /*
     393     * Do media detection if it haven't been done yet.
     394     */
     395    if (!mfDoneDetectIsoOS)
     396    {
     397        hrc = detectIsoOS();
     398        if (FAILED(hrc) && hrc != E_NOTIMPL)
     399            return hrc;
     400    }
     401
     402    /*
    321403     * Do some default property stuff and check other properties.
    322404     */
     
    334416                mStrLocale = "en_US";
    335417            Assert(RTLOCALE_IS_LANGUAGE2_UNDERSCORE_COUNTRY2(mStrLocale));
     418        }
     419
     420        if (mStrLanguage.isEmpty())
     421        {
     422            if (mDetectedOSLanguages.size() > 0)
     423                mStrLanguage = mDetectedOSLanguages[0];
     424            else
     425                mStrLanguage.assign(mStrLocale).findReplace('_', '-');
    336426        }
    337427
     
    10531143    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    10541144    AssertReturn(mpInstaller == NULL, setErrorBoth(E_FAIL, VERR_WRONG_ORDER, tr("Cannot change after prepare() has been called")));
    1055     mStrIsoPath = isoPath;
     1145    mStrIsoPath       = isoPath;
     1146    mfDoneDetectIsoOS = false;
    10561147    return S_OK;
    10571148}
     
    12161307    }
    12171308    return setError(E_INVALIDARG, tr("Expected two lower cased letters, an underscore, and two upper cased letters"));
     1309}
     1310
     1311HRESULT Unattended::getLanguage(com::Utf8Str &aLanguage)
     1312{
     1313    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     1314    aLanguage = mStrLanguage;
     1315    return S_OK;
     1316}
     1317
     1318HRESULT Unattended::setLanguage(const com::Utf8Str &aLanguage)
     1319{
     1320    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1321    AssertReturn(mpInstaller == NULL, setErrorBoth(E_FAIL, VERR_WRONG_ORDER, tr("Cannot change after prepare() has been called")));
     1322    mStrLanguage = aLanguage;
     1323    return S_OK;
    12181324}
    12191325
     
    15281634}
    15291635
     1636HRESULT Unattended::getDetectedOSLanguages(com::Utf8Str &aDetectedOSLanguages)
     1637{
     1638    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     1639    aDetectedOSLanguages = RTCString::join(mDetectedOSLanguages, " ");
     1640    return S_OK;
     1641}
     1642
    15301643HRESULT Unattended::getDetectedOSHints(com::Utf8Str &aDetectedOSHints)
    15311644{
     
    16081721    Assert(isReadLockedOnCurrentThread());
    16091722    return mStrLocale;
     1723}
     1724
     1725Utf8Str const &Unattended::i_getLanguage() const
     1726{
     1727    Assert(isReadLockedOnCurrentThread());
     1728    return mStrLanguage;
    16101729}
    16111730
  • trunk/src/VBox/Main/src-server/UnattendedScript.cpp

    r68222 r68239  
    565565        rValue.replace(2, 1, "-");
    566566    }
     567    else if (IS_PLACEHOLDER_MATCH("LANGUAGE"))
     568        rValue = mpUnattended->i_getLanguage();
    567569    else if (IS_PLACEHOLDER_MATCH("COUNTRY"))
    568570        rValue = mpUnattended->i_getCountry();
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette