diff options
author | Andy Shaw <andy.shaw@qt.io> | 2017-12-08 10:59:10 +0100 |
---|---|---|
committer | Andy Shaw <andy.shaw@qt.io> | 2017-12-12 10:37:06 +0000 |
commit | bc50de22b20747ee82e459b7a5df854c7bd7cba5 (patch) | |
tree | 2748170b7ca489816e4ef39b41dee3f412aa1f70 /src | |
parent | 28399e39ce885a2f12be27c5c0556c6c6363005d (diff) |
Provide special handling of REG_EXPAND_SZ when setting environment variables
Since some registry settings with regard to the environment variables can
have the type set to REG_EXPAND_SZ then we need to ensure that this is
respected. Otherwise it will be changed to REG_SZ due to a limitation with
QSettings.
Task-number: QTIFW-794
Change-Id: Icaede82b151496367e531050082d416e19e15b56
Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/installer/environmentvariablesoperation.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/libs/installer/environmentvariablesoperation.cpp b/src/libs/installer/environmentvariablesoperation.cpp index b80951d2b..7a8dbfb5a 100644 --- a/src/libs/installer/environmentvariablesoperation.cpp +++ b/src/libs/installer/environmentvariablesoperation.cpp @@ -65,6 +65,48 @@ static void broadcastEnvironmentChange() namespace { +bool handleRegExpandSz(const QString ®Path, const QString &name, + const QString &value, QString *errorString, + bool *error) +{ + bool setAsExpandSZ = false; +#ifdef Q_OS_WIN + // Account for when it is originally REG_EXPAND_SZ as we don't want + // to lose this setting (see Path environment variable) + const bool isLocalKey = regPath.startsWith(QStringLiteral("HKEY_LOCAL")); + HKEY hkey = isLocalKey ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + // Drop the HKEY...\\ part + const QString keyPath = regPath.mid(isLocalKey ? 19 : 18, -1); + HKEY handle; + LONG res = RegOpenKeyEx(hkey, reinterpret_cast<const wchar_t *>(keyPath.utf16()), 0, + KEY_READ, &handle); + if (res == ERROR_SUCCESS) { + DWORD dataType; + DWORD dataSize; + res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(name.utf16()), 0, + &dataType, 0, &dataSize); + setAsExpandSZ = (res == ERROR_SUCCESS) && (dataType == REG_EXPAND_SZ); + if (setAsExpandSZ) { + RegCloseKey(handle); + res = RegOpenKeyEx(hkey, reinterpret_cast<const wchar_t *>(keyPath.utf16()), 0, + KEY_SET_VALUE, &handle); + if (res == ERROR_SUCCESS) { + const QByteArray data(reinterpret_cast<const char *>(value.utf16()), + (value.length() + 1) * 2); + res = RegSetValueEx(handle, reinterpret_cast<const wchar_t *>(name.utf16()), 0, REG_EXPAND_SZ, + reinterpret_cast<const unsigned char*>(data.constData()), data.size()); + RegCloseKey(handle); + } + if (res != ERROR_SUCCESS) { + *errorString = UpdateOperation::tr("Cannot write to registry path %1.").arg(regPath); + *error = true; + } + } + } +#endif + return setAsExpandSZ; +} + template <typename SettingsType> UpdateOperation::Error writeSetting(const QString ®Path, const QString &name, @@ -82,6 +124,10 @@ UpdateOperation::Error writeSetting(const QString ®Path, // remember old value for undo *oldValue = registry.value(name).toString(); + bool error = false; + if (handleRegExpandSz(regPath, name, value, errorString, &error)) + return error ? UpdateOperation::UserDefinedError : UpdateOperation::NoError; + // set the new value registry.setValue(name, value); registry.sync(); @@ -108,6 +154,11 @@ UpdateOperation::Error undoSetting(const QString ®Path, } if (actual != value) //key changed, don't undo return UpdateOperation::UserDefinedError; + + bool error = false; + if (handleRegExpandSz(regPath, name, oldValue, errorString, &error)) + return error ? UpdateOperation::UserDefinedError : UpdateOperation::NoError; + QString dontcare; return writeSetting<SettingsType>(regPath, name, oldValue, errorString, &dontcare); } |