[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - Repository.mk scp2/source setup_native/Library_reg_dlls.mk setup_native/Module_setup_native.mk setup_native/source
Mike Kaganski (via logerrit)
logerrit at kemper.freedesktop.org
Tue Jun 4 19:59:09 UTC 2019
Repository.mk | 1
scp2/source/calc/module_calc.scp | 2
scp2/source/draw/module_draw.scp | 2
scp2/source/impress/module_impress.scp | 2
scp2/source/ooo/windowscustomaction_ooo.scp | 41 +
scp2/source/writer/module_writer.scp | 2
setup_native/Library_reg_dlls.mk | 40 +
setup_native/Module_setup_native.mk | 1
setup_native/source/win32/customactions/reg_dlls/reg_dlls.cxx | 281 ++++++++++
setup_native/source/win32/customactions/reg_dlls/reg_dlls.def | 5
10 files changed, 373 insertions(+), 4 deletions(-)
New commits:
commit 7f0ef81cec7e4f64c7fbfce04372d84871244b11
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Wed May 22 19:17:44 2019 +0300
Commit: Aron Budea <aron.budea at collabora.com>
CommitDate: Tue Jun 4 21:58:30 2019 +0200
Register spsupp*.dll during installation
This registers SharePoint integration libraries using regsvr.exe.
Both 32-bit and 64-bit libraries are registered; registration of
SharePoint.OpenDocuments is unconditional (subject to ActiveX
feature install state), substituting respective MSO component.
This only works for 32-bit MSI, because in case of 64-bit MSI, only
64-bit SharePoint DLL is included; this makes the library ~useless
in case of 64-bit MSI, because IE needs 32-bit component absent there.
Proper solution will be created for master branch.
Change-Id: Ic5bf9e7090acfaa17d47cb72b9ebfd483242f656
Reviewed-on: https://gerrit.libreoffice.org/72801
Reviewed-by: Aron Budea <aron.budea at collabora.com>
Tested-by: Aron Budea <aron.budea at collabora.com>
diff --git a/Repository.mk b/Repository.mk
index ca4b1031131c..889643183942 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -668,6 +668,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,PLAINLIBS_OOO,ooobinaryta
instooofiltmsi \
inst_msu_msi \
qslnkmsi \
+ reg_dlls \
reg4allmsdoc \
sdqsmsi \
sellangmsi \
diff --git a/scp2/source/calc/module_calc.scp b/scp2/source/calc/module_calc.scp
index dd31007bb5ca..0f83dec54352 100644
--- a/scp2/source/calc/module_calc.scp
+++ b/scp2/source/calc/module_calc.scp
@@ -74,7 +74,7 @@ Module gid_Module_Prg_Calc_MSO_Reg
Name = "gid_Module_Prg_Calc_MSO_Reg";
Description = "gid_Module_Prg_Calc_MSO_Reg";
Styles = (HIDDEN_ROOT);
- Default = YES;
+ Default = NO;
End
Module gid_Module_Prg_Calc_Other_Reg
diff --git a/scp2/source/draw/module_draw.scp b/scp2/source/draw/module_draw.scp
index 87375797e1c6..c4c835b4ccc1 100644
--- a/scp2/source/draw/module_draw.scp
+++ b/scp2/source/draw/module_draw.scp
@@ -64,7 +64,7 @@ Module gid_Module_Prg_Draw_MSO_Reg
Name = "gid_Module_Prg_Draw_MSO_Reg";
Description = "gid_Module_Prg_Draw_MSO_Reg";
Styles = (HIDDEN_ROOT);
- Default = YES;
+ Default = NO;
End
Module gid_Module_Prg_Draw_Other_Reg
diff --git a/scp2/source/impress/module_impress.scp b/scp2/source/impress/module_impress.scp
index ca335d6973d9..42d62dd9e7c6 100644
--- a/scp2/source/impress/module_impress.scp
+++ b/scp2/source/impress/module_impress.scp
@@ -66,7 +66,7 @@ Module gid_Module_Prg_Impress_MSO_Reg
Name = "gid_Module_Prg_Impress_MSO_Reg";
Description = "gid_Module_Prg_Impress_MSO_Reg";
Styles = (HIDDEN_ROOT);
- Default = YES;
+ Default = NO;
End
Module gid_Module_Prg_Impress_Other_Reg
diff --git a/scp2/source/ooo/windowscustomaction_ooo.scp b/scp2/source/ooo/windowscustomaction_ooo.scp
index bc7201b9b2b4..f98296ca48dc 100644
--- a/scp2/source/ooo/windowscustomaction_ooo.scp
+++ b/scp2/source/ooo/windowscustomaction_ooo.scp
@@ -221,3 +221,44 @@ WindowsCustomAction gid_Customaction_RegisterSomeExtensions
End
#endif /* HAVE_WINDOWS_SDK */
+
+/* Deferred not-impersonated actions that will call regsvr32 to (un)register DLLs.
+ Custom action type 1 (msidbCustomActionTypeDll + msidbCustomActionTypeBinaryData)
+ + 64 (msidbCustomActionTypeContinue) + 1024 (msidbCustomActionTypeInScript)
+ + 2048 (msidbCustomActionTypeNoImpersonate).
+ Since deferred actions don't have access to current DB, the actions depend on
+ immediate-executed action prep_reg_unreg_dlls (see below) that precedes it, and
+ sets this action's CustomActionData property.
+*/
+
+WindowsCustomAction gid_Customaction_reg_dlls
+ Name = "reg_dlls";
+ Typ = "3137";
+ Source = "reg_dlls.dll";
+ Target = "RegDLLs";
+ Inbinarytable = 1;
+ Assignment1 = ("InstallExecuteSequence", "reg_dlls", "InstallFinalize");
+End
+
+WindowsCustomAction gid_Customaction_unreg_dlls
+ Name = "unreg_dlls";
+ Typ = "3137";
+ Source = "reg_dlls.dll";
+ Target = "UnregDLLs";
+ Inbinarytable = 1;
+ Assignment1 = ("InstallExecuteSequence", "unreg_dlls", "UnpublishComponents");
+End
+
+/* Immediately-executed action that adds registration command lines for spsupp[_x64].dll
+ to "[un]reg_dlls" properties.
+ Custom action type 1 (msidbCustomActionTypeDll + msidbCustomActionTypeBinaryData)
+ + 64 (msidbCustomActionTypeContinue).
+*/
+WindowsCustomAction gid_Customaction_prep_reg_dlls
+ Name = "prep_reg_unreg_dlls";
+ Typ = "65";
+ Source = "reg_dlls.dll";
+ Target = "PrepRegUnregDLLs";
+ Inbinarytable = 1;
+ Assignment1 = ("InstallExecuteSequence", "", "behind_CostFinalize");
+End
diff --git a/scp2/source/writer/module_writer.scp b/scp2/source/writer/module_writer.scp
index 9a0ed77ac4b8..ded807099d63 100644
--- a/scp2/source/writer/module_writer.scp
+++ b/scp2/source/writer/module_writer.scp
@@ -65,7 +65,7 @@ Module gid_Module_Prg_Wrt_MSO_Reg
Name = "gid_Module_Prg_Wrt_MSO_Reg";
Description = "gid_Module_Prg_Wrt_MSO_Reg";
Styles = (HIDDEN_ROOT);
- Default = YES;
+ Default = NO;
End
Module gid_Module_Prg_Wrt_Other_Reg
diff --git a/setup_native/Library_reg_dlls.mk b/setup_native/Library_reg_dlls.mk
new file mode 100644
index 000000000000..f0ac9a875c60
--- /dev/null
+++ b/setup_native/Library_reg_dlls.mk
@@ -0,0 +1,40 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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,reg_dlls))
+
+$(eval $(call gb_Library_add_defs,reg_dlls,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,reg_dlls,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,reg_dlls,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/reg_dlls/reg_dlls.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,reg_dlls,\
+ setup_native/source/win32/customactions/reg_dlls/reg_dlls \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,reg_dlls,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ kernel32 \
+ Ole32 \
+ Shell32 \
+ Msi \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Module_setup_native.mk b/setup_native/Module_setup_native.mk
index abf37aff6c86..aa4025a9a7bb 100644
--- a/setup_native/Module_setup_native.mk
+++ b/setup_native/Module_setup_native.mk
@@ -26,6 +26,7 @@ $(eval $(call gb_Module_add_targets,setup_native,\
Library_instooofiltmsi \
Library_inst_msu_msi \
Library_qslnkmsi \
+ Library_reg_dlls \
Library_reg4allmsdoc \
Library_regactivex \
Library_sdqsmsi \
diff --git a/setup_native/source/win32/customactions/reg_dlls/reg_dlls.cxx b/setup_native/source/win32/customactions/reg_dlls/reg_dlls.cxx
new file mode 100644
index 000000000000..e0d3ee3b2cc8
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg_dlls/reg_dlls.cxx
@@ -0,0 +1,281 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 <iomanip>
+#include <memory>
+#include <string>
+#include <sstream>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <Shlobj.h>
+#include <msiquery.h>
+
+namespace
+{
+template <typename IntType> std::string Num2Hex(IntType n)
+{
+ std::stringstream sMsg;
+ sMsg << "0x" << std::uppercase << std::setfill('0') << std::setw(sizeof(n) * 2) << std::hex
+ << n;
+ return sMsg.str();
+}
+
+template <typename IntType> std::string Num2Dec(IntType n)
+{
+ std::stringstream sMsg;
+ sMsg << n;
+ return sMsg.str();
+}
+
+std::string Win32ErrorMessage(const char* sFunc, DWORD nWin32Error)
+{
+ std::stringstream sMsg;
+ sMsg << sFunc << " failed with Win32 error code " << Num2Hex(nWin32Error) << "!";
+
+ return sMsg.str();
+}
+
+void ThrowHResult(const char* sFunc, HRESULT hr)
+{
+ std::stringstream sMsg;
+ sMsg << sFunc << " failed (HRESULT = " << Num2Hex(hr) << ")!";
+
+ throw std::exception(sMsg.str().c_str());
+}
+
+void CheckHResult(const char* sFunc, HRESULT hr)
+{
+ if (FAILED(hr))
+ ThrowHResult(sFunc, hr);
+}
+
+void ThrowWin32Error(const char* sFunc, DWORD nWin32Error)
+{
+ throw std::exception(Win32ErrorMessage(sFunc, nWin32Error).c_str());
+}
+
+void ThrowLastError(const char* sFunc) { ThrowWin32Error(sFunc, GetLastError()); }
+
+void CheckWin32Error(const char* sFunc, DWORD nWin32Error)
+{
+ if (nWin32Error != ERROR_SUCCESS)
+ ThrowWin32Error(sFunc, nWin32Error);
+}
+
+std::wstring GetKnownFolder(const KNOWNFOLDERID& rfid)
+{
+ PWSTR sPath = nullptr;
+ HRESULT hr = SHGetKnownFolderPath(rfid, KF_FLAG_DEFAULT, nullptr, &sPath);
+ CheckHResult("SHGetKnownFolderPath", hr);
+ std::wstring sResult(sPath);
+ CoTaskMemFree(sPath);
+ return sResult;
+}
+
+void WriteLogElem(MSIHANDLE hInst, MSIHANDLE hRecord, std::ostringstream& sTmpl, UINT)
+{
+ MsiRecordSetStringA(hRecord, 0, sTmpl.str().c_str());
+ MsiProcessMessage(hInst, INSTALLMESSAGE_INFO, hRecord);
+}
+
+void RecSetString(MSIHANDLE hRec, UINT nField, LPCSTR sVal)
+{
+ MsiRecordSetStringA(hRec, nField, sVal);
+}
+
+void RecSetString(MSIHANDLE hRec, UINT nField, LPCWSTR sVal)
+{
+ MsiRecordSetStringW(hRec, nField, sVal);
+}
+
+template <class Ch, class... SOther>
+void WriteLogElem(MSIHANDLE hInst, MSIHANDLE hRec, std::ostringstream& sTmpl, UINT nField,
+ const Ch* elem, const SOther&... others)
+{
+ sTmpl << " [" << nField << "]";
+ RecSetString(hRec, nField, elem);
+ WriteLogElem(hInst, hRec, sTmpl, nField + 1, others...);
+}
+
+template <class S1, class... SOther>
+void WriteLogElem(MSIHANDLE hInst, MSIHANDLE hRec, std::ostringstream& sTmpl, UINT nField,
+ const S1& elem, const SOther&... others)
+{
+ WriteLogElem(hInst, hRec, sTmpl, nField, elem.c_str(), others...);
+}
+
+static std::string sLogPrefix;
+
+template <class... StrType> void WriteLog(MSIHANDLE hInst, const StrType&... elements)
+{
+ PMSIHANDLE hRec = MsiCreateRecord(sizeof...(elements));
+ if (!hRec)
+ return;
+
+ std::ostringstream sTemplate;
+ sTemplate << sLogPrefix;
+ WriteLogElem(hInst, hRec, sTemplate, 1, elements...);
+}
+
+std::wstring MsiGetPropertyW(MSIHANDLE hInst, LPCWSTR szName)
+{
+ std::wstring sResult;
+ DWORD nSz = 0;
+ UINT nRet = ::MsiGetPropertyW(hInst, szName, L"", &nSz);
+ if (nRet == ERROR_MORE_DATA)
+ {
+ ++nSz;
+ auto buf = std::make_unique<wchar_t[]>(nSz);
+ CheckWin32Error("MsiGetPropertyW", ::MsiGetPropertyW(hInst, szName, buf.get(), &nSz));
+ sResult = buf.get();
+ WriteLog(hInst, "Property", szName, "=", sResult);
+ }
+ else
+ CheckWin32Error("MsiGetPropertyW", nRet);
+
+ return sResult;
+}
+
+typedef std::unique_ptr<void, decltype(&CloseHandle)> CloseHandleGuard;
+CloseHandleGuard Guard(HANDLE h) { return CloseHandleGuard(h, CloseHandle); }
+
+void RegDLL(MSIHANDLE hInst, const std::wstring& sArgs, bool bUnreg)
+{
+ static std::wstring sRegSvr32 = GetKnownFolder(FOLDERID_System) + L"\\regsvr32.exe";
+
+ try
+ {
+ std::wstring sCmd = L"\"" + sRegSvr32 + L"\" /s ";
+ if (bUnreg)
+ sCmd += L"/u ";
+ sCmd += sArgs;
+ WriteLog(hInst, "Prepared regsvr32 command:", sCmd);
+
+ STARTUPINFOW si{ sizeof(si) };
+ PROCESS_INFORMATION pi{};
+ if (!CreateProcessW(sRegSvr32.c_str(), const_cast<LPWSTR>(sCmd.c_str()), nullptr, nullptr,
+ FALSE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi))
+ ThrowLastError("CreateProcessW");
+ auto aCloseProcHandleGuard(Guard(pi.hProcess));
+ WriteLog(hInst, "CreateProcessW succeeded");
+
+ DWORD nWaitResult = WaitForSingleObject(pi.hProcess, INFINITE);
+ if (nWaitResult != WAIT_OBJECT_0)
+ ThrowWin32Error("WaitForSingleObject", nWaitResult);
+
+ DWORD nExitCode = 0;
+ if (!GetExitCodeProcess(pi.hProcess, &nExitCode))
+ ThrowLastError("GetExitCodeProcess");
+
+ WriteLog(hInst, "regsvr32 returned:", Num2Dec(nExitCode));
+ }
+ catch (std::exception& e)
+ {
+ WriteLog(hInst, e.what());
+ }
+}
+
+void ProcessCustomActionData(MSIHANDLE hInst, bool bUnreg)
+{
+ WriteLog(hInst, "Checking value of CustomActionData");
+ std::wstring sCustomActionData = MsiGetPropertyW(hInst, L"CustomActionData");
+ WriteLog(hInst, "Got CustomActionData value:", sCustomActionData);
+ std::wstringstream ss(sCustomActionData);
+ std::wstring sToken;
+ while (std::getline(ss, sToken, L'|'))
+ {
+ if (!sToken.empty())
+ {
+ RegDLL(hInst, sToken, bUnreg);
+ }
+ }
+}
+} // namespace
+
+// Deferred action "reg_dlls" that must be run from system account. Receives a list of regsvr32
+// arguments: DLLs which need registering, and possibly /i argument with its parameter.
+extern "C" __declspec(dllexport) UINT __stdcall RegDLLs(MSIHANDLE hInstall)
+{
+ sLogPrefix = "RegDLLs:";
+ WriteLog(hInstall, "started");
+
+ ProcessCustomActionData(hInstall, false);
+ return ERROR_SUCCESS;
+}
+
+// Deferred action "unreg_dlls" that must be run from system account. Receives a list of regsvr32
+// arguments: DLLs which need registering, and possibly /i argument with its parameter.
+extern "C" __declspec(dllexport) UINT __stdcall UnregDLLs(MSIHANDLE hInstall)
+{
+ sLogPrefix = "UnregDLLs:";
+ WriteLog(hInstall, "started");
+
+ ProcessCustomActionData(hInstall, true);
+ return ERROR_SUCCESS;
+}
+
+// Immediate action "prep_reg_unreg_dlls". Checks states of the features to prepare custom action data
+// for reg_dlls and unreg_dlls deferred actions.
+extern "C" __declspec(dllexport) UINT __stdcall PrepRegUnregDLLs(MSIHANDLE hInstall)
+{
+ sLogPrefix = "PrepRegUnregDLLs:";
+ WriteLog(hInstall, "started");
+
+ try
+ {
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+ CheckWin32Error("MsiGetFeatureStateW", MsiGetFeatureStateW(hInstall, L"gm_o_Activexcontrol",
+ ¤t_state, &future_state));
+ const bool bRegActiveX
+ = future_state == INSTALLSTATE_LOCAL
+ || (current_state == INSTALLSTATE_LOCAL && (future_state == INSTALLSTATE_UNKNOWN
+ || future_state == INSTALLSTATE_DEFAULT));
+ const bool bUnregActiveX = current_state == INSTALLSTATE_LOCAL
+ && future_state != INSTALLSTATE_UNKNOWN
+ && future_state != INSTALLSTATE_LOCAL
+ && future_state != INSTALLSTATE_DEFAULT;
+
+ if (!bRegActiveX && !bUnregActiveX)
+ return ERROR_SUCCESS;
+
+ // For now, do that unconditionally; TODO: move the component to own feature
+ std::wstring sRegData = L"/i:Substitute_OWSSUPP \"[#spsupp.dll]\"|/i:Substitute_OWSSUPP "
+ L"\"[#spsupp_x64.dll]\"";
+
+ auto SetFormattedPropW = [&](LPCWSTR sProp, LPCWSTR sVal) {
+ PMSIHANDLE hRec = MsiCreateRecord(0);
+ if (!hRec)
+ throw std::exception("MsiCreateRecord failed!");
+ MsiRecordSetStringW(hRec, 0, sVal);
+ DWORD nSz = 0;
+ if (MsiFormatRecordW(hInstall, hRec, L"", &nSz) == ERROR_MORE_DATA)
+ {
+ ++nSz;
+ auto buf = std::make_unique<wchar_t[]>(nSz);
+ CheckWin32Error("MsiFormatRecordW",
+ MsiFormatRecordW(hInstall, hRec, buf.get(), &nSz));
+ CheckWin32Error("MsiSetPropertyW", MsiSetPropertyW(hInstall, sProp, buf.get()));
+ }
+ };
+ if (bRegActiveX)
+ SetFormattedPropW(L"reg_dlls", sRegData.c_str());
+ if (bUnregActiveX)
+ SetFormattedPropW(L"unreg_dlls", sRegData.c_str());
+ }
+ catch (std::exception& e)
+ {
+ WriteLog(hInstall, e.what());
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg_dlls/reg_dlls.def b/setup_native/source/win32/customactions/reg_dlls/reg_dlls.def
new file mode 100644
index 000000000000..ed0d1685dea1
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg_dlls/reg_dlls.def
@@ -0,0 +1,5 @@
+LIBRARY "r.dll"
+EXPORTS
+ RegDLLs
+ UnregDLLs
+ PrepRegUnregDLLs
\ No newline at end of file
More information about the Libreoffice-commits
mailing list