From bc50de22b20747ee82e459b7a5df854c7bd7cba5 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 8 Dec 2017 10:59:10 +0100 Subject: 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 --- .../installer/environmentvariablesoperation.cpp | 51 ++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src') 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(keyPath.utf16()), 0, + KEY_READ, &handle); + if (res == ERROR_SUCCESS) { + DWORD dataType; + DWORD dataSize; + res = RegQueryValueEx(handle, reinterpret_cast(name.utf16()), 0, + &dataType, 0, &dataSize); + setAsExpandSZ = (res == ERROR_SUCCESS) && (dataType == REG_EXPAND_SZ); + if (setAsExpandSZ) { + RegCloseKey(handle); + res = RegOpenKeyEx(hkey, reinterpret_cast(keyPath.utf16()), 0, + KEY_SET_VALUE, &handle); + if (res == ERROR_SUCCESS) { + const QByteArray data(reinterpret_cast(value.utf16()), + (value.length() + 1) * 2); + res = RegSetValueEx(handle, reinterpret_cast(name.utf16()), 0, REG_EXPAND_SZ, + reinterpret_cast(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 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(regPath, name, oldValue, errorString, &dontcare); } -- cgit v1.2.3