summaryrefslogtreecommitdiff
path: root/setup_native
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2020-02-03 09:40:12 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2020-02-03 11:31:54 +0100
commit916cbda310a43d46a0789fd8b2c8f15fb86b27b4 (patch)
treea3825a20109af366189fc4c229e604429f1b8197 /setup_native
parent58a2389b82bb1a55ce2c933a37b59ee9a8f6617a (diff)
tdf#130329: detect previous version's install location
Since component ids change across major versions, install location isn't kept automatically for major upgrades. Use OLDPRODUCTS property set during FindRelatedProducts action (see Upgrade table created by solenv/bin/modules/installer/windows/upgrade.pm). Read InstallLocation in existing MigrateInstallPath custom action under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\GUID, where GUID is the value of OLDPRODUCTS. This only reads registry hive for the current installer architecture (32/64 bit), so that the other architecture installation path is not taken into account when old version is of different architecture, to avoid installing into wrong directory when e.g. upgrading from 32-bit to 64-bit, so 64-bit program is not installed to Program Files (x86). Change-Id: Ib9fa004818908a5706c5af040f1a5a36c03d2f36 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87844 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'setup_native')
-rw-r--r--setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx70
1 files changed, 46 insertions, 24 deletions
diff --git a/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
index 66bb99ae18e8..ad34bad8c744 100644
--- a/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
+++ b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
@@ -19,46 +19,68 @@
#include "shlxtmsi.hxx"
#include <algorithm>
+#include <sstream>
#include <systools/win32/uwinapi.h>
-extern "C" __declspec(dllexport) UINT __stdcall MigrateInstallPath( MSIHANDLE handle )
+extern "C" __declspec(dllexport) UINT __stdcall MigrateInstallPath(MSIHANDLE handle)
{
- WCHAR szValue[8192];
- DWORD nValueSize = sizeof(szValue); // yes, it is the number of bytes
- HKEY hKey;
- std::wstring sInstDir;
+ auto RegValue = [](HKEY hRoot, const WCHAR* sKey, const WCHAR* sVal) {
+ std::wstring sResult;
+
+ if (HKEY hKey; RegOpenKeyW(hRoot, sKey, &hKey) == ERROR_SUCCESS)
+ {
+ WCHAR buf[32767]; // max longpath
+ DWORD bufsize = sizeof(buf); // yes, it is the number of bytes
+ if (RegQueryValueExW(hKey, sVal, nullptr, nullptr, reinterpret_cast<LPBYTE>(buf),
+ &bufsize)
+ == ERROR_SUCCESS)
+ {
+ buf[std::min<size_t>(SAL_N_ELEMENTS(buf) - 1, bufsize / sizeof(*buf))] = 0;
+ sResult = buf;
+ }
+ RegCloseKey(hKey);
+ }
+
+ return sResult;
+ };
std::wstring sManufacturer = GetMsiPropertyW( handle, L"Manufacturer" );
std::wstring sDefinedName = GetMsiPropertyW( handle, L"DEFINEDPRODUCT" );
std::wstring sUpdateVersion = GetMsiPropertyW( handle, L"DEFINEDVERSION" );
std::wstring sUpgradeCode = GetMsiPropertyW( handle, L"UpgradeCode" );
- std::wstring sProductKey = L"Software\\" + sManufacturer + L"\\" + sDefinedName +
+ std::wstring sKey = L"Software\\" + sManufacturer + L"\\" + sDefinedName +
L"\\" + sUpdateVersion + L"\\" + sUpgradeCode;
- if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ if (auto sInstDir = RegValue(HKEY_CURRENT_USER, sKey.c_str(), L"INSTALLLOCATION");
+ !sInstDir.empty())
{
- if ( ERROR_SUCCESS == RegQueryValueExW( hKey, L"INSTALLLOCATION", nullptr, nullptr, reinterpret_cast<LPBYTE>(szValue), &nValueSize ) )
- {
- szValue[std::min(static_cast<unsigned int>(SAL_N_ELEMENTS(szValue) - 1), static_cast<unsigned int>(nValueSize / sizeof(*szValue)))] = 0;
- sInstDir = szValue;
- MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
- // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_CURRENT_USER", MB_OK );
- }
-
- RegCloseKey( hKey );
+ MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
+ // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_CURRENT_USER", MB_OK );
}
- else if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ else if (auto sInstDir = RegValue(HKEY_LOCAL_MACHINE, sKey.c_str(), L"INSTALLLOCATION");
+ !sInstDir.empty())
{
- if ( ERROR_SUCCESS == RegQueryValueExW( hKey, L"INSTALLLOCATION", nullptr, nullptr, reinterpret_cast<LPBYTE>(szValue), &nValueSize ) )
+ MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
+ // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_LOCAL_MACHINE", MB_OK );
+ }
+ else if (std::wistringstream sOlds{ GetMsiPropertyW(handle, L"OLDPRODUCTS") }; !sOlds.eof())
+ {
+ std::wstring sOld;
+ bool bFound = false;
+ while (!bFound && std::getline(sOlds, sOld, L';'))
{
- szValue[std::min(static_cast<unsigned int>(SAL_N_ELEMENTS(szValue) - 1), static_cast<unsigned int>(nValueSize / sizeof(*szValue)))] = 0;
- sInstDir = szValue;
- MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
- // MessageBoxW( NULL, sInstDir.c_str(), L"Found in HKEY_LOCAL_MACHINE", MB_OK );
+ if (sOld.empty())
+ continue;
+ sKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + sOld;
+ if (auto sInstDir = RegValue(HKEY_LOCAL_MACHINE, sKey.c_str(), L"InstallLocation");
+ !sInstDir.empty())
+ {
+ MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
+ // MessageBoxW( NULL, sInstDir.c_str(), L"Found in Uninstall", MB_OK );
+ bFound = true;
+ }
}
-
- RegCloseKey( hKey );
}
return ERROR_SUCCESS;