summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndy Shaw <andy.shaw@qt.io>2017-12-08 10:59:10 +0100
committerAndy Shaw <andy.shaw@qt.io>2017-12-12 10:37:06 +0000
commitbc50de22b20747ee82e459b7a5df854c7bd7cba5 (patch)
tree2748170b7ca489816e4ef39b41dee3f412aa1f70 /src
parent28399e39ce885a2f12be27c5c0556c6c6363005d (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.cpp51
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 &regPath, 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 &regPath,
const QString &name,
@@ -82,6 +124,10 @@ UpdateOperation::Error writeSetting(const QString &regPath,
// 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 &regPath,
}
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);
}