1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "shlxtmsi.hxx"
23 #include <systools/win32/uwinapi.h>
25 extern "C" __declspec(dllexport
) UINT __stdcall
MigrateInstallPath(MSIHANDLE handle
)
27 std::wstring sInstDir
= GetMsiPropertyW(handle
, L
"INSTALLLOCATION");
28 if (!sInstDir
.empty())
29 return ERROR_SUCCESS
; // Don't overwrite explicitly set value
31 auto RegValue
= [](HKEY hRoot
, const WCHAR
* sKey
, const WCHAR
* sVal
) {
33 WCHAR buf
[32767]; // max longpath
34 DWORD bufsize
= sizeof(buf
); // yes, it is the number of bytes
35 if (RegGetValueW(hRoot
, sKey
, sVal
, RRF_RT_REG_SZ
, nullptr, buf
, &bufsize
) == ERROR_SUCCESS
)
36 sResult
= buf
; // RegGetValueW null-terminates strings
41 const std::wstring sManufacturer
= GetMsiPropertyW( handle
, L
"Manufacturer" );
42 const std::wstring sDefinedName
= GetMsiPropertyW( handle
, L
"DEFINEDPRODUCT" );
43 const std::wstring sUpdateVersion
= GetMsiPropertyW( handle
, L
"DEFINEDVERSION" );
44 const std::wstring sUpgradeCode
= GetMsiPropertyW( handle
, L
"UpgradeCode" );
45 const std::wstring sBrandPackageVersion
= GetMsiPropertyW(handle
, L
"BRANDPACKAGEVERSION");
47 std::wstring sKey
= L
"Software\\" + sManufacturer
+ L
"\\" + sDefinedName
+
48 L
"\\" + sUpdateVersion
+ L
"\\" + sUpgradeCode
;
50 sInstDir
= RegValue(HKEY_CURRENT_USER
, sKey
.c_str(), L
"INSTALLLOCATION");
52 sInstDir
= RegValue(HKEY_LOCAL_MACHINE
, sKey
.c_str(), L
"INSTALLLOCATION");
53 // See #i93032# for layers description
56 sKey
= L
"Software\\LibreOffice\\Layers\\" + sDefinedName
+ L
"\\" + sBrandPackageVersion
;
57 sInstDir
= RegValue(HKEY_CURRENT_USER
, sKey
.c_str(), L
"INSTALLLOCATION");
61 sKey
= L
"Software\\LibreOffice\\Layers_\\" + sDefinedName
+ L
"\\" + sBrandPackageVersion
;
62 sInstDir
= RegValue(HKEY_CURRENT_USER
, sKey
.c_str(), L
"INSTALLLOCATION");
66 sKey
= L
"Software\\LibreOffice\\Layers\\" + sDefinedName
+ L
"\\" + sBrandPackageVersion
;
67 sInstDir
= RegValue(HKEY_LOCAL_MACHINE
, sKey
.c_str(), L
"INSTALLLOCATION");
71 sKey
= L
"Software\\LibreOffice\\Layers_\\" + sDefinedName
+ L
"\\" + sBrandPackageVersion
;
72 sInstDir
= RegValue(HKEY_LOCAL_MACHINE
, sKey
.c_str(), L
"INSTALLLOCATION");
76 std::wistringstream sOlds
{ GetMsiPropertyW(handle
, L
"OLDPRODUCTS") };
78 while (std::getline(sOlds
, sOld
, L
';'))
82 sKey
= L
"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + sOld
;
83 sInstDir
= RegValue(HKEY_LOCAL_MACHINE
, sKey
.c_str(), L
"InstallLocation");
84 if (!sInstDir
.empty())
89 if (!sInstDir
.empty())
90 MsiSetPropertyW(handle
, L
"INSTALLLOCATION", sInstDir
.c_str());
96 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */