summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Repository.mk1
-rw-r--r--external/onlineupdate/Library_install_updateservice.mk54
-rw-r--r--external/onlineupdate/Module_onlineupdate.mk1
-rw-r--r--external/onlineupdate/install_updateservice.cxx179
-rw-r--r--external/onlineupdate/install_updateservice.def4
-rw-r--r--scp2/source/ooo/windowscustomaction_ooo.scp23
6 files changed, 262 insertions, 0 deletions
diff --git a/Repository.mk b/Repository.mk
index 9ef08e814a20..a53d923f36b5 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -743,6 +743,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,PLAINLIBS_OOO,ooobinaryta
sdqsmsi \
sellangmsi \
sn_tools \
+ $(if $(ENABLE_ONLINE_UPDATE_MAR),install_updateservice) \
) \
))
diff --git a/external/onlineupdate/Library_install_updateservice.mk b/external/onlineupdate/Library_install_updateservice.mk
new file mode 100644
index 000000000000..216b81a95a07
--- /dev/null
+++ b/external/onlineupdate/Library_install_updateservice.mk
@@ -0,0 +1,54 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,install_updateservice))
+
+$(eval $(call gb_Library_use_unpacked,install_updateservice,onlineupdate))
+
+$(eval $(call gb_Library_set_include,install_updateservice, \
+ -I$(call gb_UnpackedTarball_get_dir,onlineupdate)/onlineupdate/source/update/common \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,install_updateservice, \
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,install_updateservice, \
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+ $(if $(filter -fsanitize=%,$(CC)),,/fno-sanitize-address-vcasan-lib) \
+))
+
+$(eval $(call gb_Library_add_ldflags,install_updateservice, \
+ /DEF:$(SRCDIR)/external/onlineupdate/install_updateservice.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,install_updateservice, \
+ external/onlineupdate/install_updateservice \
+))
+
+$(eval $(call gb_Library_use_static_libraries,install_updateservice, \
+ updatehelper \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,install_updateservice, \
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ msi \
+ kernel32 \
+ user32 \
+ advapi32 \
+ shell32 \
+ shlwapi \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/onlineupdate/Module_onlineupdate.mk b/external/onlineupdate/Module_onlineupdate.mk
index a6bc698aa3ca..97f7d5c3f7bd 100644
--- a/external/onlineupdate/Module_onlineupdate.mk
+++ b/external/onlineupdate/Module_onlineupdate.mk
@@ -18,6 +18,7 @@ $(eval $(call gb_Module_add_targets,onlineupdate,\
StaticLibrary_updatehelper \
$(if $(filter WNT,$(OS)),\
Executable_update_service \
+ Library_install_updateservice \
WinResTarget_updater )\
Executable_test_updater_dialog \
Executable_mar \
diff --git a/external/onlineupdate/install_updateservice.cxx b/external/onlineupdate/install_updateservice.cxx
new file mode 100644
index 000000000000..4604e55462d6
--- /dev/null
+++ b/external/onlineupdate/install_updateservice.cxx
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <cstddef>
+#include <limits>
+#include <memory>
+#include <string>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+
+#include <pathhash.h>
+
+// Replacements for functions used in
+// workdir/UnpackedTarball/onlineupdate/onlineupdate/source/update/common/pathhash.cpp but not
+// available here:
+
+extern "C" wchar_t* _wcslwr(wchar_t* str)
+{
+ for (auto p = str; *p != L'\0'; ++p)
+ {
+ if (*p >= L'A' && *p <= L'Z')
+ {
+ *p += L'a' - L'A';
+ }
+ }
+ return str;
+};
+
+extern "C" wchar_t* wcsncpy(wchar_t* strDest, wchar_t const* strSource, std::size_t count)
+{
+ for (std::size_t i = 0; i != count; ++i)
+ {
+ strDest[i] = *strSource;
+ if (*strSource != L'\0')
+ {
+ ++strSource;
+ }
+ }
+ return strDest;
+}
+
+namespace
+{
+bool getInstallLocation(MSIHANDLE handle, std::wstring* installLocation)
+{
+ DWORD n = 0;
+ if (MsiGetPropertyW(handle, L"INSTALLLOCATION", const_cast<wchar_t*>(L""), &n)
+ != ERROR_MORE_DATA
+ || n == std::numeric_limits<DWORD>::max())
+ {
+ return false;
+ }
+ ++n;
+ auto buf = std::make_unique<wchar_t[]>(n);
+ if (MsiGetPropertyW(handle, L"INSTALLLOCATION", buf.get(), &n) != ERROR_SUCCESS)
+ {
+ return false;
+ }
+ if (n != 0 && buf[n - 1] == L'\\')
+ {
+ --n;
+ }
+ installLocation->assign(buf.get(), n);
+ return true;
+}
+
+typedef std::unique_ptr<void, decltype(&CloseHandle)> CloseHandleGuard;
+
+CloseHandleGuard guard(HANDLE handle) { return CloseHandleGuard(handle, CloseHandle); }
+
+bool runExecutable(std::wstring const& installLocation, wchar_t const* commandLine)
+{
+ STARTUPINFOW si{};
+ si.cb = sizeof(si);
+ PROCESS_INFORMATION pi{};
+ if (!CreateProcessW((installLocation + L"\\program\\update_service.exe").c_str(),
+ const_cast<LPWSTR>(commandLine), nullptr, nullptr, FALSE, CREATE_NO_WINDOW,
+ nullptr, nullptr, &si, &pi))
+ {
+ return false;
+ }
+ auto const g(guard(pi.hProcess));
+ DWORD res = WaitForSingleObject(pi.hProcess, INFINITE);
+ if (res != WAIT_OBJECT_0)
+ {
+ return false;
+ }
+ DWORD ec = 0;
+ if (!GetExitCodeProcess(pi.hProcess, &ec))
+ {
+ return false;
+ }
+ if (ec != 0)
+ {
+ return false;
+ }
+ return true;
+}
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall InstallUpdateservice(MSIHANDLE handle)
+{
+ std::wstring loc;
+ if (!getInstallLocation(handle, &loc))
+ {
+ return false;
+ }
+ if (!runExecutable(loc, L"install"))
+ {
+ return ERROR_INVALID_FUNCTION;
+ }
+ WCHAR maintenanceServiceKey[MAX_PATH + 1];
+ if (!CalculateRegistryPathFromFilePath(loc.c_str(), maintenanceServiceKey))
+ {
+ return ERROR_INVALID_FUNCTION;
+ }
+ HKEY key;
+ if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, (std::wstring(maintenanceServiceKey) + L"\\0").c_str(),
+ 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_64KEY, nullptr,
+ &key, nullptr)
+ != ERROR_SUCCESS)
+ {
+ return ERROR_INVALID_FUNCTION;
+ }
+ if (RegSetValueExW(key, L"issuer", 0, REG_SZ,
+ reinterpret_cast<BYTE const*>(L"Certum Code Signing 2021 CA"),
+ sizeof L"Certum Code Signing 2021 CA")
+ != ERROR_SUCCESS)
+ {
+ return ERROR_INVALID_FUNCTION;
+ }
+ if (RegSetValueExW(key, L"name", 0, REG_SZ,
+ reinterpret_cast<BYTE const*>(L"The Document Foundation"),
+ sizeof L"The Document Foundation")
+ != ERROR_SUCCESS)
+ {
+ return ERROR_INVALID_FUNCTION;
+ }
+ if (RegCloseKey(key) != ERROR_SUCCESS)
+ {
+ return ERROR_INVALID_FUNCTION;
+ }
+ return ERROR_SUCCESS;
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall UninstallUpdateservice(MSIHANDLE handle)
+{
+ std::wstring loc;
+ if (!getInstallLocation(handle, &loc))
+ {
+ return false;
+ }
+ if (!runExecutable(loc, L"uninstall"))
+ {
+ return ERROR_INVALID_FUNCTION;
+ }
+ WCHAR maintenanceServiceKey[MAX_PATH + 1];
+ if (!CalculateRegistryPathFromFilePath(loc.c_str(), maintenanceServiceKey))
+ {
+ return ERROR_INVALID_FUNCTION;
+ }
+ if (RegDeleteTreeW(HKEY_LOCAL_MACHINE, maintenanceServiceKey) != ERROR_SUCCESS)
+ {
+ return ERROR_INVALID_FUNCTION;
+ }
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/external/onlineupdate/install_updateservice.def b/external/onlineupdate/install_updateservice.def
new file mode 100644
index 000000000000..a210387fce33
--- /dev/null
+++ b/external/onlineupdate/install_updateservice.def
@@ -0,0 +1,4 @@
+LIBRARY "install_updateservice.dll"
+EXPORTS
+ InstallUpdateservice
+ UninstallUpdateservice
diff --git a/scp2/source/ooo/windowscustomaction_ooo.scp b/scp2/source/ooo/windowscustomaction_ooo.scp
index 41b78daad13b..0bd451c04f9d 100644
--- a/scp2/source/ooo/windowscustomaction_ooo.scp
+++ b/scp2/source/ooo/windowscustomaction_ooo.scp
@@ -16,6 +16,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include "config_features.h"
#include "macros.inc"
WindowsCustomAction gid_Customaction_Regallmsdocdll
@@ -244,3 +245,25 @@ WindowsCustomAction gid_Customaction_prep_reg_dlls
Inbinarytable = 1;
Assignment1 = ("InstallExecuteSequence", "", "behind_CostFinalize");
End
+
+#if HAVE_FEATURE_UPDATE_MAR
+
+WindowsCustomAction gid_Customaction_install_updateservice
+ Name = "install_updateservice";
+ Typ = "65";
+ Source = "install_updateservice.dll";
+ Target = "InstallUpdateservice";
+ Inbinarytable = 1;
+ Assignment1 = ("InstallExecuteSequence", "Not REMOVE=\"ALL\"", "end");
+End
+
+WindowsCustomAction gid_Customaction_uninstall_updateservice
+ Name = "uninstall_updateservice";
+ Typ = "65";
+ Source = "install_updateservice.dll";
+ Target = "UninstallUpdateservice";
+ Inbinarytable = 1;
+ Assignment1 = ("InstallExecuteSequence", "REMOVE=\"ALL\"", "MigrateFeatureStates");
+End
+
+#endif