summaryrefslogtreecommitdiffstats
path: root/setup_native
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /setup_native
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'setup_native')
-rw-r--r--setup_native/CustomTarget_mac.mk20
-rw-r--r--setup_native/CustomTarget_scripts.mk38
-rw-r--r--setup_native/CustomTarget_spell.mk17
-rw-r--r--setup_native/Library_inst_msu_msi.mk40
-rw-r--r--setup_native/Library_instooofiltmsi.mk38
-rw-r--r--setup_native/Library_qslnkmsi.mk45
-rw-r--r--setup_native/Library_reg4allmsdoc.mk42
-rw-r--r--setup_native/Library_reg_dlls.mk40
-rw-r--r--setup_native/Library_regactivex.mk38
-rw-r--r--setup_native/Library_sdqsmsi.mk45
-rw-r--r--setup_native/Library_sellangmsi.mk46
-rw-r--r--setup_native/Library_shlxtmsi.mk53
-rw-r--r--setup_native/Library_sn_tools.mk43
-rw-r--r--setup_native/Makefile7
-rw-r--r--setup_native/Module_setup_native.mk41
-rw-r--r--setup_native/Package_misc.mk14
-rw-r--r--setup_native/Package_packinfo.mk14
-rw-r--r--setup_native/Package_scripts.mk14
-rw-r--r--setup_native/StaticLibrary_quickstarter.mk24
-rw-r--r--setup_native/StaticLibrary_seterror.mk24
-rw-r--r--setup_native/scripts/admin.pl1244
-rw-r--r--setup_native/scripts/downloadscript.sh104
-rw-r--r--setup_native/scripts/fake-db.spec57
-rw-r--r--setup_native/scripts/install_create.pl60
-rw-r--r--setup_native/scripts/install_linux.sh313
-rw-r--r--setup_native/scripts/langpackscript.sh170
-rw-r--r--setup_native/scripts/mac_install.script27
-rw-r--r--setup_native/scripts/osx_install_languagepack.applescript175
-rw-r--r--setup_native/scripts/uninstall_linux.sh72
-rw-r--r--setup_native/scripts/unpack_update.sh50
-rw-r--r--setup_native/source/mac/Info.plist.langpack53
-rw-r--r--setup_native/source/mac/macinstall.ulf68
-rw-r--r--setup_native/source/mac/ooo3_installer.icnsbin0 -> 42710 bytes
-rw-r--r--setup_native/source/packinfo/DS_Storebin0 -> 12292 bytes
-rw-r--r--setup_native/source/packinfo/DS_Store_Devbin0 -> 12292 bytes
-rw-r--r--setup_native/source/packinfo/DS_Store_Langpackbin0 -> 12292 bytes
-rw-r--r--setup_native/source/packinfo/finals_instsetoo.txt32
-rw-r--r--setup_native/source/packinfo/libreoffice.pcpbin0 -> 20480 bytes
-rw-r--r--setup_native/source/packinfo/linuxcopyrightfile2
-rw-r--r--setup_native/source/packinfo/openofficelanguagepack.pcpbin0 -> 6144 bytes
-rw-r--r--setup_native/source/packinfo/osxdndinstall.pngbin0 -> 62596 bytes
-rw-r--r--setup_native/source/packinfo/package.txt1
-rw-r--r--setup_native/source/packinfo/package_names.txt65
-rw-r--r--setup_native/source/packinfo/package_names_ext.txt21
-rw-r--r--setup_native/source/packinfo/packinfo_brand.txt129
-rw-r--r--setup_native/source/packinfo/packinfo_extensions.txt140
-rw-r--r--setup_native/source/packinfo/packinfo_office.txt1244
-rw-r--r--setup_native/source/packinfo/packinfo_office_help.txt54
-rw-r--r--setup_native/source/packinfo/packinfo_office_lang.txt196
-rw-r--r--setup_native/source/packinfo/packinfo_sdkoo.txt32
-rw-r--r--setup_native/source/packinfo/packinfo_ure.txt49
-rw-r--r--setup_native/source/packinfo/private1copyrightfile2
-rw-r--r--setup_native/source/packinfo/solariscopyrightfile2
-rw-r--r--setup_native/source/packinfo/spellchecker_selection.pl74
-rw-r--r--setup_native/source/packinfo/spellchecker_selection.txt92
-rw-r--r--setup_native/source/packinfo/ure.pcpbin0 -> 6144 bytes
-rw-r--r--setup_native/source/win32/customactions/indexingfilter/instooofiltmsi.def3
-rw-r--r--setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx157
-rw-r--r--setup_native/source/win32/customactions/inst_msu/inst_msu.cxx674
-rw-r--r--setup_native/source/win32/customactions/inst_msu/inst_msu_msi.def5
-rw-r--r--setup_native/source/win32/customactions/quickstarter/qslnkmsi.def3
-rw-r--r--setup_native/source/win32/customactions/quickstarter/quickstarter.cxx131
-rw-r--r--setup_native/source/win32/customactions/quickstarter/quickstarter.hxx36
-rw-r--r--setup_native/source/win32/customactions/quickstarter/remove_quickstart_link.cxx42
-rw-r--r--setup_native/source/win32/customactions/quickstarter/sdqsmsi.def3
-rw-r--r--setup_native/source/win32/customactions/quickstarter/shutdown_quickstart.cxx73
-rw-r--r--setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsdoc.def6
-rw-r--r--setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx519
-rw-r--r--setup_native/source/win32/customactions/reg_dlls/reg_dlls.cxx319
-rw-r--r--setup_native/source/win32/customactions/reg_dlls/reg_dlls.def5
-rw-r--r--setup_native/source/win32/customactions/regactivex/regactivex.cxx344
-rw-r--r--setup_native/source/win32/customactions/regactivex/regactivex.def4
-rw-r--r--setup_native/source/win32/customactions/sellang/sellang.cxx387
-rw-r--r--setup_native/source/win32/customactions/sellang/sellang.def4
-rw-r--r--setup_native/source/win32/customactions/sellang/sorttree.cxx55
-rw-r--r--setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx66
-rw-r--r--setup_native/source/win32/customactions/shellextensions/checkpatches.cxx59
-rw-r--r--setup_native/source/win32/customactions/shellextensions/completeinstallpath.cxx116
-rw-r--r--setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx96
-rw-r--r--setup_native/source/win32/customactions/shellextensions/shlxtmsi.def11
-rw-r--r--setup_native/source/win32/customactions/shellextensions/shlxtmsi.hxx59
-rw-r--r--setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx63
-rw-r--r--setup_native/source/win32/customactions/shellextensions/upgrade.cxx158
-rw-r--r--setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx126
-rw-r--r--setup_native/source/win32/customactions/tools/checkversion.cxx98
-rw-r--r--setup_native/source/win32/customactions/tools/seterror.cxx84
-rw-r--r--setup_native/source/win32/customactions/tools/seterror.hxx36
-rw-r--r--setup_native/source/win32/customactions/tools/sn_tools.def3
-rw-r--r--setup_native/source/win32/desktophelper.txt1
89 files changed, 8917 insertions, 0 deletions
diff --git a/setup_native/CustomTarget_mac.mk b/setup_native/CustomTarget_mac.mk
new file mode 100644
index 000000000..2f35f23cc
--- /dev/null
+++ b/setup_native/CustomTarget_mac.mk
@@ -0,0 +1,20 @@
+# -*- 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_CustomTarget_CustomTarget,setup_native/mac))
+
+$(eval $(call gb_CustomTarget_register_target,setup_native/mac,macinstall.ulf))
+
+$(eval $(call gb_CustomTarget_ulfex_rule,\
+ $(call gb_CustomTarget_get_workdir,setup_native/mac)/macinstall.ulf,\
+ $(SRCDIR)/setup_native/source/mac/macinstall.ulf,\
+ $(foreach lang,$(gb_TRANS_LANGS),\
+ $(gb_POLOCATION)/$(lang)/setup_native/source/mac.po)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/CustomTarget_scripts.mk b/setup_native/CustomTarget_scripts.mk
new file mode 100644
index 000000000..c7f8c5b0a
--- /dev/null
+++ b/setup_native/CustomTarget_scripts.mk
@@ -0,0 +1,38 @@
+# -*- 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/.
+#
+
+scripts_WORKDIR :=$(call gb_CustomTarget_get_workdir,setup_native/scripts)
+
+$(eval $(call gb_CustomTarget_CustomTarget,setup_native/scripts))
+
+ifeq ($(OS),LINUX)
+ifneq ($(filter rpm,$(PKGFORMAT)),)
+$(eval $(call gb_CustomTarget_register_targets,setup_native/scripts,\
+ install \
+ uninstall \
+ noarch/fake-db-1.0-0.noarch.rpm \
+))
+
+$(scripts_WORKDIR)/noarch/fake-db-1.0-0.noarch.rpm: $(SRCDIR)/setup_native/scripts/fake-db.spec
+ mkdir -p $(scripts_WORKDIR)/fake-db-root
+ $(RPM) --define "_builddir $(scripts_WORKDIR)/fake-db-root" \
+ --define "_rpmdir $(scripts_WORKDIR)" -bb $<
+ chmod g+w $(scripts_WORKDIR)/fake-db-root
+
+$(scripts_WORKDIR)/install: $(SRCDIR)/setup_native/scripts/install_linux.sh $(scripts_WORKDIR)/noarch/fake-db-1.0-0.noarch.rpm
+ $(PERL) -w $(SRCDIR)/setup_native/scripts/install_create.pl $^ $@
+ chmod 775 $@
+
+$(scripts_WORKDIR)/uninstall: $(SRCDIR)/setup_native/scripts/uninstall_linux.sh
+ cat $< | tr -d "\015" > $@
+ chmod 775 $@
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/CustomTarget_spell.mk b/setup_native/CustomTarget_spell.mk
new file mode 100644
index 000000000..b18095658
--- /dev/null
+++ b/setup_native/CustomTarget_spell.mk
@@ -0,0 +1,17 @@
+# -*- 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_CustomTarget_CustomTarget,setup_native/spell))
+
+$(eval $(call gb_CustomTarget_register_target,setup_native/spell,spellchecker_selection.hxx))
+
+$(call gb_CustomTarget_get_workdir,setup_native/spell)/spellchecker_selection.hxx: $(SRCDIR)/setup_native/source/packinfo/spellchecker_selection.txt $(SRCDIR)/setup_native/source/packinfo/spellchecker_selection.pl
+ $(PERL) -w $(SRCDIR)/setup_native/source/packinfo/spellchecker_selection.pl <$< >$@
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Library_inst_msu_msi.mk b/setup_native/Library_inst_msu_msi.mk
new file mode 100644
index 000000000..d423b5168
--- /dev/null
+++ b/setup_native/Library_inst_msu_msi.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,inst_msu_msi))
+
+$(eval $(call gb_Library_add_defs,inst_msu_msi,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,inst_msu_msi,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,inst_msu_msi,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/inst_msu/inst_msu_msi.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,inst_msu_msi,\
+ setup_native/source/win32/customactions/inst_msu/inst_msu \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,inst_msu_msi,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ kernel32 \
+ Ole32 \
+ Shell32 \
+ Msi \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Library_instooofiltmsi.mk b/setup_native/Library_instooofiltmsi.mk
new file mode 100644
index 000000000..36e2e2a6b
--- /dev/null
+++ b/setup_native/Library_instooofiltmsi.mk
@@ -0,0 +1,38 @@
+# -*- 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,instooofiltmsi))
+
+$(eval $(call gb_Library_add_defs,instooofiltmsi,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,instooofiltmsi,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,instooofiltmsi,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/indexingfilter/instooofiltmsi.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,instooofiltmsi,\
+ setup_native/source/win32/customactions/indexingfilter/restartindexingservice \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,instooofiltmsi,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ kernel32 \
+ advapi32 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Library_qslnkmsi.mk b/setup_native/Library_qslnkmsi.mk
new file mode 100644
index 000000000..f958534f0
--- /dev/null
+++ b/setup_native/Library_qslnkmsi.mk
@@ -0,0 +1,45 @@
+# -*- 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,qslnkmsi))
+
+$(eval $(call gb_Library_add_defs,qslnkmsi,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,qslnkmsi,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,qslnkmsi,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/quickstarter/qslnkmsi.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,qslnkmsi,\
+ setup_native/source/win32/customactions/quickstarter/remove_quickstart_link \
+))
+
+$(eval $(call gb_Library_use_static_libraries,qslnkmsi,\
+ quickstarter \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,qslnkmsi,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ msi \
+ kernel32 \
+ user32 \
+ advapi32 \
+ shell32 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Library_reg4allmsdoc.mk b/setup_native/Library_reg4allmsdoc.mk
new file mode 100644
index 000000000..816ebbb3f
--- /dev/null
+++ b/setup_native/Library_reg4allmsdoc.mk
@@ -0,0 +1,42 @@
+# -*- 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,reg4allmsdoc))
+
+$(eval $(call gb_Library_add_defs,reg4allmsdoc,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,reg4allmsdoc,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,reg4allmsdoc,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsdoc.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,reg4allmsdoc,\
+ setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,reg4allmsdoc,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ msi \
+ kernel32 \
+ user32 \
+ advapi32 \
+ shell32 \
+ shlwapi \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Library_reg_dlls.mk b/setup_native/Library_reg_dlls.mk
new file mode 100644
index 000000000..f0ac9a875
--- /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/Library_regactivex.mk b/setup_native/Library_regactivex.mk
new file mode 100644
index 000000000..7142b8ee0
--- /dev/null
+++ b/setup_native/Library_regactivex.mk
@@ -0,0 +1,38 @@
+# -*- 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,regactivex))
+
+$(eval $(call gb_Library_add_defs,regactivex,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,regactivex,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,regactivex,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/regactivex/regactivex.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,regactivex,\
+ setup_native/source/win32/customactions/regactivex/regactivex \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,regactivex,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ kernel32 \
+ msi \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Library_sdqsmsi.mk b/setup_native/Library_sdqsmsi.mk
new file mode 100644
index 000000000..ff9a1bd58
--- /dev/null
+++ b/setup_native/Library_sdqsmsi.mk
@@ -0,0 +1,45 @@
+# -*- 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,sdqsmsi))
+
+$(eval $(call gb_Library_add_defs,sdqsmsi,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,sdqsmsi,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,sdqsmsi,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/quickstarter/sdqsmsi.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,sdqsmsi,\
+ setup_native/source/win32/customactions/quickstarter/shutdown_quickstart \
+))
+
+$(eval $(call gb_Library_use_static_libraries,sdqsmsi,\
+ quickstarter \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,sdqsmsi,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ msi \
+ kernel32 \
+ user32 \
+ advapi32 \
+ shell32 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Library_sellangmsi.mk b/setup_native/Library_sellangmsi.mk
new file mode 100644
index 000000000..04f8f6edb
--- /dev/null
+++ b/setup_native/Library_sellangmsi.mk
@@ -0,0 +1,46 @@
+# -*- 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,sellangmsi))
+
+$(eval $(call gb_Library_use_custom_headers,sellangmsi,\
+ setup_native/spell \
+))
+
+$(eval $(call gb_Library_add_defs,sellangmsi,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,sellangmsi,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,sellangmsi,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/sellang/sellang.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,sellangmsi,\
+ setup_native/source/win32/customactions/sellang/sellang \
+ setup_native/source/win32/customactions/sellang/sorttree \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,sellangmsi,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ msi \
+ kernel32 \
+ user32 \
+ advapi32 \
+ shell32 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Library_shlxtmsi.mk b/setup_native/Library_shlxtmsi.mk
new file mode 100644
index 000000000..a4c2fccd2
--- /dev/null
+++ b/setup_native/Library_shlxtmsi.mk
@@ -0,0 +1,53 @@
+# -*- 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,shlxtmsi))
+
+$(eval $(call gb_Library_use_external,shlxtmsi,boost_headers))
+
+$(eval $(call gb_Library_add_defs,shlxtmsi,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,shlxtmsi,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,shlxtmsi,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/shellextensions/shlxtmsi.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,shlxtmsi,\
+ setup_native/source/win32/customactions/shellextensions/startmenuicon \
+ setup_native/source/win32/customactions/shellextensions/upgrade \
+ setup_native/source/win32/customactions/shellextensions/migrateinstallpath \
+ setup_native/source/win32/customactions/shellextensions/completeinstallpath \
+ setup_native/source/win32/customactions/shellextensions/checkdirectory \
+ setup_native/source/win32/customactions/shellextensions/vistaspecial \
+ setup_native/source/win32/customactions/shellextensions/checkpatches \
+))
+
+$(eval $(call gb_Library_use_static_libraries,shlxtmsi,\
+ seterror \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,shlxtmsi,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ msi \
+ kernel32 \
+ advapi32 \
+ shell32 \
+ psapi \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Library_sn_tools.mk b/setup_native/Library_sn_tools.mk
new file mode 100644
index 000000000..aa94f2ebc
--- /dev/null
+++ b/setup_native/Library_sn_tools.mk
@@ -0,0 +1,43 @@
+# -*- 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,sn_tools))
+
+$(eval $(call gb_Library_add_defs,sn_tools,\
+ -U_DLL \
+))
+
+$(eval $(call gb_Library_add_cxxflags,sn_tools,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_Library_add_ldflags,sn_tools,\
+ /DEF:$(SRCDIR)/setup_native/source/win32/customactions/tools/sn_tools.def \
+ /NODEFAULTLIB \
+))
+
+$(eval $(call gb_Library_add_exception_objects,sn_tools,\
+ setup_native/source/win32/customactions/tools/checkversion \
+))
+
+$(eval $(call gb_Library_use_static_libraries,sn_tools,\
+ seterror \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,sn_tools,\
+ libcmt \
+ libcpmt \
+ libucrt \
+ libvcruntime \
+ kernel32 \
+ msi \
+ advapi32 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Makefile b/setup_native/Makefile
new file mode 100644
index 000000000..ccb1c85a0
--- /dev/null
+++ b/setup_native/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Module_setup_native.mk b/setup_native/Module_setup_native.mk
new file mode 100644
index 000000000..42fa14217
--- /dev/null
+++ b/setup_native/Module_setup_native.mk
@@ -0,0 +1,41 @@
+# -*- 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_Module_Module,setup_native))
+
+$(eval $(call gb_Module_add_targets,setup_native,\
+ $(if $(filter MACOSX,$(OS)),CustomTarget_mac) \
+ CustomTarget_spell \
+ $(if $(filter WNT,$(OS)),Package_misc) \
+ Package_packinfo \
+ $(if $(filter LINUX SOLARIS,$(OS)), \
+ CustomTarget_scripts \
+ $(if $(ENABLE_ONLINE_UPDATE),Package_scripts) \
+ ) \
+))
+
+ifeq ($(OS),WNT)
+$(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 \
+ Library_sellangmsi \
+ Library_shlxtmsi \
+ Library_sn_tools \
+ StaticLibrary_quickstarter \
+ StaticLibrary_seterror \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Package_misc.mk b/setup_native/Package_misc.mk
new file mode 100644
index 000000000..a90a39945
--- /dev/null
+++ b/setup_native/Package_misc.mk
@@ -0,0 +1,14 @@
+# -*- 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_Package_Package,setup_native_misc,$(SRCDIR)/setup_native/source))
+
+$(eval $(call gb_Package_add_file,setup_native_misc,$(LIBO_BIN_FOLDER)/desktophelper.txt,win32/desktophelper.txt))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Package_packinfo.mk b/setup_native/Package_packinfo.mk
new file mode 100644
index 000000000..2519ead95
--- /dev/null
+++ b/setup_native/Package_packinfo.mk
@@ -0,0 +1,14 @@
+# -*- 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_Package_Package,setup_native_packinfo,$(SRCDIR)/setup_native/source/packinfo))
+
+$(eval $(call gb_Package_add_file,setup_native_packinfo,$(LIBO_SHARE_FOLDER)/extensions/package.txt,package.txt))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/Package_scripts.mk b/setup_native/Package_scripts.mk
new file mode 100644
index 000000000..2f8fb7944
--- /dev/null
+++ b/setup_native/Package_scripts.mk
@@ -0,0 +1,14 @@
+# -*- 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_Package_Package,setup_native_scripts,$(SRCDIR)/setup_native/scripts))
+
+$(eval $(call gb_Package_add_file,setup_native_scripts,$(LIBO_BIN_FOLDER)/unpack_update,unpack_update.sh))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/StaticLibrary_quickstarter.mk b/setup_native/StaticLibrary_quickstarter.mk
new file mode 100644
index 000000000..0517a7511
--- /dev/null
+++ b/setup_native/StaticLibrary_quickstarter.mk
@@ -0,0 +1,24 @@
+# -*- 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_StaticLibrary_StaticLibrary,quickstarter))
+
+$(eval $(call gb_StaticLibrary_add_defs,quickstarter,\
+ -U_DLL \
+))
+
+$(eval $(call gb_StaticLibrary_add_cxxflags,quickstarter,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_StaticLibrary_add_exception_objects,quickstarter,\
+ setup_native/source/win32/customactions/quickstarter/quickstarter \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/StaticLibrary_seterror.mk b/setup_native/StaticLibrary_seterror.mk
new file mode 100644
index 000000000..922976904
--- /dev/null
+++ b/setup_native/StaticLibrary_seterror.mk
@@ -0,0 +1,24 @@
+# -*- 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_StaticLibrary_StaticLibrary,seterror))
+
+$(eval $(call gb_StaticLibrary_add_defs,seterror,\
+ -U_DLL \
+))
+
+$(eval $(call gb_StaticLibrary_add_cxxflags,seterror,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),/MTd,/MT) \
+))
+
+$(eval $(call gb_StaticLibrary_add_exception_objects,seterror,\
+ setup_native/source/win32/customactions/tools/seterror \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/setup_native/scripts/admin.pl b/setup_native/scripts/admin.pl
new file mode 100644
index 000000000..714da400c
--- /dev/null
+++ b/setup_native/scripts/admin.pl
@@ -0,0 +1,1244 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+use Cwd;
+use File::Copy;
+use File::Temp qw/ :mktemp /;
+
+#################################################################################
+# Global settings
+#################################################################################
+
+BEGIN
+{
+ $prog = "msi installer";
+ $targetdir = "";
+ $databasepath = "";
+ $starttime = "";
+ $globaltempdirname = "ooopackagingXXXXXX";
+ $savetemppath = "";
+ $msiinfo_available = 0;
+ $path_displayed = 0;
+ $localmsidbpath = "";
+
+ $plat = $^O;
+
+ if ( $plat =~ /cygwin/i )
+ {
+ $separator = "/";
+ $pathseparator = "\:";
+ }
+ else
+ {
+ $separator = "\\";
+ $pathseparator = "\;";
+ }
+}
+
+#################################################################################
+# Program information
+#################################################################################
+
+sub usage
+{
+ print <<End;
+----------------------------------------------------------------------
+This program installs a Windows Installer installation set
+without using msiexec.exe. The installation is comparable
+with an administrative installation using the Windows Installer
+service.
+Required parameter:
+-d Path to installation set or msi database
+-t Target directory
+---------------------------------------------------------------------
+End
+ exit(-1);
+}
+
+#################################################################################
+# Collecting parameter
+#################################################################################
+
+sub getparameter
+{
+ if (( $#ARGV < 3 ) || ( $#ARGV > 3 )) { usage(); }
+
+ while ( $#ARGV >= 0 )
+ {
+ my $param = shift(@ARGV);
+
+ if ($param eq "-t") { $targetdir = shift(@ARGV); }
+ elsif ($param eq "-d") { $databasepath = shift(@ARGV); }
+ else
+ {
+ print "\n**********************************************\n";
+ print "Error: Unknown parameter: $param";
+ print "\n**********************************************\n";
+ usage();
+ exit(-1);
+ }
+ }
+}
+
+#################################################################################
+# Checking content of parameter
+#################################################################################
+
+sub controlparameter
+{
+ if ( $targetdir eq "" )
+ {
+ print "\n******************************************************\n";
+ print "Error: Target directory not defined (parameter -t)!";
+ print "\n******************************************************\n";
+ usage();
+ exit(-1);
+ }
+
+ if ( $databasepath eq "" )
+ {
+ print "\n******************************************************\n";
+ print "Error: Path to msi database not defined (parameter -d)!";
+ print "\n******************************************************\n";
+ usage();
+ exit(-1);
+ }
+
+ if ( -d $databasepath )
+ {
+ $databasepath =~ s/\\\s*$//;
+ $databasepath =~ s/\/\s*$//;
+
+ my $msifiles = find_file_with_file_extension("msi", $databasepath);
+
+ if ( $#{$msifiles} < 0 ) { exit_program("ERROR: Did not find msi database in directory $installationdir"); }
+ if ( $#{$msifiles} > 0 ) { exit_program("ERROR: Did find more than one msi database in directory $installationdir"); }
+
+ $databasepath = $databasepath . $separator . ${$msifiles}[0];
+ }
+
+ if ( ! -f $databasepath ) { exit_program("ERROR: Did not find msi database in directory $databasepath."); }
+
+ if ( ! -d $targetdir ) { create_directories($targetdir); }
+}
+
+#############################################################################
+# The program msidb.exe can be located next to the Perl program. Then it is
+# not necessary to find it in the PATH variable.
+#############################################################################
+
+sub check_local_msidb
+{
+ my $msidbname = "msidb.exe";
+ my $perlprogramm = $0;
+ my $path = $perlprogramm;
+
+ get_path_from_fullqualifiedname(\$path);
+
+ $path =~ s/\\\s*$//;
+ $path =~ s/\/\s*$//;
+
+ my $msidbpath = "";
+ if ( $path =~ /^\s*$/ ) { $msidbpath = $msidbname; }
+ else { $msidbpath = $path . $separator . $msidbname; }
+
+ if ( -f $msidbpath )
+ {
+ $localmsidbpath = $msidbpath;
+ print "Using $msidbpath (next to \"admin.pl\")\n";
+ }
+}
+
+#############################################################################
+# Converting a string list with separator $listseparator
+# into an array
+#############################################################################
+
+sub convert_stringlist_into_array
+{
+ my ( $includestringref, $listseparator ) = @_;
+
+ my @newarray = ();
+ my $first;
+ my $last = ${$includestringref};
+
+ while ( $last =~ /^\s*(.+?)\Q$listseparator\E(.+)\s*$/) # "$" for minimal matching
+ {
+ $first = $1;
+ $last = $2;
+ # Problem with two directly following listseparators. For example a path with two ";;" directly behind each other
+ $first =~ s/^$listseparator//;
+ push(@newarray, "$first\n");
+ }
+
+ push(@newarray, "$last\n");
+
+ return \@newarray;
+}
+
+#########################################################
+# Checking the local system
+# Checking existence of needed files in include path
+#########################################################
+
+sub check_system_path
+{
+ my $onefile;
+ my $error = 0;
+ my $pathvariable = $ENV{'PATH'};
+ my $local_pathseparator = $pathseparator;
+
+ if( $^O =~ /cygwin/i )
+ { # When using cygwin's perl the PATH variable is POSIX style and ...
+ $pathvariable = qx{cygpath -mp "$pathvariable"} ;
+ # has to be converted to DOS style for further use.
+ $local_pathseparator = ';';
+ }
+ my $patharrayref = convert_stringlist_into_array(\$pathvariable, $local_pathseparator);
+
+ my @needed_files_in_path = ("expand.exe");
+ if ( $localmsidbpath eq "" ) { push(@needed_files_in_path, "msidb.exe"); } # not found locally -> search in path
+ my @optional_files_in_path = ("msiinfo.exe");
+
+ print("\nChecking required files:\n");
+
+ foreach $onefile ( @needed_files_in_path )
+ {
+ print("... searching $onefile ...");
+
+ my $fileref = get_sourcepath_from_filename_and_includepath(\$onefile, $patharrayref);
+
+ if ( $$fileref eq "" )
+ {
+ $error = 1;
+ print( "$onefile not found\n" );
+ }
+ else
+ {
+ print( "\tFound: $$fileref\n" );
+ }
+ }
+
+ if ( $error ) { exit_program("ERROR: Could not find all needed files in path (using setsolar should help)!"); }
+
+ print("\nChecking optional files:\n");
+
+ foreach $onefile ( @optional_files_in_path )
+ {
+ print("... searching $onefile ...");
+
+ my $fileref = get_sourcepath_from_filename_and_includepath(\$onefile, $patharrayref);
+
+ if ( $$fileref eq "" )
+ {
+ print( "$onefile not found\n" );
+ if ( $onefile eq "msiinfo.exe" ) { $msiinfo_available = 0; }
+ }
+ else
+ {
+ print( "\tFound: $$fileref\n" );
+ if ( $onefile eq "msiinfo.exe" ) { $msiinfo_available = 1; }
+ }
+ }
+
+}
+
+##########################################################################
+# Searching a file in a list of paths
+##########################################################################
+
+sub get_sourcepath_from_filename_and_includepath
+{
+ my ($searchfilenameref, $includepatharrayref) = @_;
+
+ my $onefile = "";
+ my $foundsourcefile = 0;
+
+ for ( my $j = 0; $j <= $#{$includepatharrayref}; $j++ )
+ {
+ my $includepath = ${$includepatharrayref}[$j];
+ $includepath =~ s/^\s*//;
+ $includepath =~ s/\s*$//;
+
+ $onefile = $includepath . $separator . $$searchfilenameref;
+
+ if ( -f $onefile )
+ {
+ $foundsourcefile = 1;
+ last;
+ }
+ }
+
+ if (!($foundsourcefile)) { $onefile = ""; }
+
+ return \$onefile;
+}
+
+########################################################
+# Finding all files with a specified file extension
+# in a specified directory.
+########################################################
+
+sub find_file_with_file_extension
+{
+ my ($extension, $dir) = @_;
+
+ my @allfiles = ();
+ my @sourcefiles = ();
+
+ $dir =~ s/\Q$separator\E\s*$//;
+
+ opendir(DIR, $dir);
+ @sourcefiles = readdir(DIR);
+ closedir(DIR);
+
+ my $onefile;
+
+ foreach $onefile (@sourcefiles)
+ {
+ if ((!($onefile eq ".")) && (!($onefile eq "..")))
+ {
+ if ( $onefile =~ /^\s*(\S.*?)\.$extension\s*$/ )
+ {
+ push(@allfiles, $onefile)
+ }
+ }
+ }
+
+ return \@allfiles;
+}
+
+##############################################################
+# Creating a directory with all parent directories
+##############################################################
+
+sub create_directories
+{
+ my ($directory) = @_;
+
+ if ( ! try_to_create_directory($directory) )
+ {
+ my $parentdir = $directory;
+ get_path_from_fullqualifiedname(\$parentdir);
+ create_directories($parentdir); # recursive
+ }
+
+ create_directory($directory); # now it has to succeed
+}
+
+##############################################################
+# Creating one directory
+##############################################################
+
+sub create_directory
+{
+ my ($directory) = @_;
+
+ if ( ! -d $directory ) { mkdir($directory, 0775); }
+}
+
+##############################################################
+# Trying to create a directory, no error if this fails
+##############################################################
+
+sub try_to_create_directory
+{
+ my ($directory) = @_;
+
+ my $returnvalue = 1;
+ my $created_directory = 0;
+
+ if (!(-d $directory))
+ {
+ $returnvalue = mkdir($directory, 0775);
+
+ if ($returnvalue)
+ {
+ $created_directory = 1;
+
+ my $localcall = "chmod 775 $directory \>\/dev\/null 2\>\&1";
+ system($localcall);
+ }
+ else
+ {
+ $created_directory = 0;
+ }
+ }
+ else
+ {
+ $created_directory = 1;
+ }
+
+ return $created_directory;
+}
+
+###########################################
+# Getting path from full file name
+###########################################
+
+sub get_path_from_fullqualifiedname
+{
+ my ($longfilenameref) = @_;
+
+ if ( $$longfilenameref =~ /\Q$separator\E/ ) # Is there a separator in the path? Otherwise the path is empty.
+ {
+ if ( $$longfilenameref =~ /^\s*(\S.*\Q$separator\E)(\S.+\S?)/ )
+ {
+ $$longfilenameref = $1;
+ }
+ }
+ else
+ {
+ $$longfilenameref = ""; # there is no path
+ }
+}
+
+##############################################################
+# Getting file name from full file name
+##############################################################
+
+sub make_absolute_filename_to_relative_filename
+{
+ my ($longfilenameref) = @_;
+
+ # Either '/' or '\'.
+ if ( $$longfilenameref =~ /^.*[\/\\](\S.+\S?)/ )
+ {
+ $$longfilenameref = $1;
+ }
+}
+
+############################################
+# Exiting the program with an error
+# This function is used instead of "die"
+############################################
+
+sub exit_program
+{
+ my ($message) = @_;
+
+ print "\n***************************************************************\n";
+ print "$message\n";
+ print "***************************************************************\n";
+ remove_complete_directory($savetemppath, 1);
+ print "\n" . get_time_string();
+ exit(-1);
+}
+
+#################################################################################
+# Unpacking cabinet files with expand
+#################################################################################
+
+sub unpack_cabinet_file
+{
+ my ($cabfilename, $unpackdir) = @_;
+
+ my $expandfile = "expand.exe"; # has to be in the PATH
+
+ # expand.exe has to be located in the system directory.
+ # Cygwin has another tool expand.exe, that converts tabs to spaces. This cannot be used of course.
+ # But this wrong expand.exe is typically in the PATH before this expand.exe, to unpack
+ # cabinet files.
+
+ if ( $^O =~ /cygwin/i )
+ {
+ $expandfile = $ENV{'SYSTEMROOT'} . "/system32/expand.exe"; # Has to be located in the systemdirectory
+ $expandfile =~ s/\\/\//;
+ if ( ! -f $expandfile ) { exit_program("ERROR: Did not find file $expandfile in the Windows system folder!"); }
+ }
+
+ my $expandlogfile = $unpackdir . $separator . "expand.log";
+
+ # exclude cabinet file
+ # my $systemcall = $cabarc . " -o X " . $mergemodulehash->{'cabinetfile'};
+
+ my $systemcall = "";
+ if ( $^O =~ /cygwin/i ) {
+ my $localunpackdir = qx{cygpath -w "$unpackdir"};
+ $localunpackdir =~ s/\\/\\\\/g;
+
+ my $localcabfilename = qx{cygpath -w "$cabfilename"};
+ $localcabfilename =~ s/\\/\\\\/g;
+ $localcabfilename =~ s/\s*$//g;
+
+ $systemcall = $expandfile . " " . $localcabfilename . " -F:\* " . $localunpackdir . " \>\/dev\/null 2\>\&1";
+ }
+ else
+ {
+ $systemcall = $expandfile . " " . $cabfilename . " -F:\* " . $unpackdir . " \> " . $expandlogfile;
+ }
+
+ my $returnvalue = system($systemcall);
+
+ if ($returnvalue) { exit_program("ERROR: Could not execute $systemcall !"); }
+}
+
+#################################################################################
+# Extracting tables from msi database
+#################################################################################
+
+sub extract_tables_from_database
+{
+ my ($fullmsidatabasepath, $workdir, $tablelist) = @_;
+
+ my $msidb = "msidb.exe"; # Has to be in the path
+ if ( $localmsidbpath ) { $msidb = $localmsidbpath; }
+ my $infoline = "";
+ my $systemcall = "";
+ my $returnvalue = "";
+
+ if ( $^O =~ /cygwin/i ) {
+ chomp( $fullmsidatabasepath = qx{cygpath -w "$fullmsidatabasepath"} );
+ # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
+ $fullmsidatabasepath =~ s/\\/\\\\/g;
+ $workdir =~ s/\\/\\\\/g;
+ # and if there are still slashes, they also need to be double backslash
+ $fullmsidatabasepath =~ s/\//\\\\/g;
+ $workdir =~ s/\//\\\\/g;
+ }
+
+ # Export of all tables by using "*"
+
+ $systemcall = $msidb . " -d " . $fullmsidatabasepath . " -f " . $workdir . " -e $tablelist";
+ print "\nAnalyzing msi database\n";
+ $returnvalue = system($systemcall);
+
+ if ($returnvalue)
+ {
+ $infoline = "ERROR: Could not execute $systemcall !\n";
+ exit_program($infoline);
+ }
+}
+
+########################################################
+# Check, if this installation set contains
+# internal cabinet files included into the msi
+# database.
+########################################################
+
+sub check_for_internal_cabfiles
+{
+ my ($cabfilehash) = @_;
+
+ my $contains_internal_cabfiles = 0;
+ my %allcabfileshash = ();
+
+ foreach my $filename ( keys %{$cabfilehash} )
+ {
+ if ( $filename =~ /^\s*\#/ ) # starting with a hash
+ {
+ $contains_internal_cabfiles = 1;
+ # setting real filename without hash as key and name with hash as value
+ my $realfilename = $filename;
+ $realfilename =~ s/^\s*\#//;
+ $allcabfileshash{$realfilename} = $filename;
+ }
+ }
+
+ return ( $contains_internal_cabfiles, \%allcabfileshash );
+}
+
+#################################################################
+# Exclude all cab files from the msi database.
+#################################################################
+
+sub extract_cabs_from_database
+{
+ my ($msidatabase, $allcabfiles) = @_;
+
+ my $infoline = "";
+ my $fullsuccess = 1;
+ my $msidb = "msidb.exe"; # Has to be in the path
+ if ( $localmsidbpath ) { $msidb = $localmsidbpath; }
+
+ my @all_excluded_cabfiles = ();
+
+ if( $^O =~ /cygwin/i )
+ {
+ $msidatabase = qx{cygpath -w "$msidatabase"};
+ $msidatabase =~ s/\\/\\\\/g;
+ $msidatabase =~ s/\s*$//g;
+ }
+ else
+ {
+ # msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
+ $msidatabase =~ s/\//\\\\/g;
+ }
+
+ foreach my $onefile ( keys %{$allcabfiles} )
+ {
+ my $systemcall = $msidb . " -d " . $msidatabase . " -x " . $onefile;
+ system($systemcall);
+ push(@all_excluded_cabfiles, $onefile);
+ }
+
+ \@all_excluded_cabfiles;
+}
+
+################################################################################
+# Collect all DiskIds to the corresponding cabinet files from Media.idt.
+################################################################################
+
+sub analyze_media_file
+{
+ my ($filecontent) = @_;
+
+ my %diskidhash = ();
+
+ for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
+ {
+ if ( $i < 3 ) { next; }
+
+ if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
+ {
+ my $diskid = $1;
+ my $cabfile = $4;
+
+ $diskidhash{$cabfile} = $diskid;
+ }
+ }
+
+ return \%diskidhash;
+}
+
+################################################################################
+# Analyzing the content of Directory.idt
+#################################################################################
+
+sub analyze_directory_file
+{
+ my ($filecontent) = @_;
+
+ my %table = ();
+
+ for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
+ {
+ if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; }
+
+ if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\s*$/ )
+ {
+ my $dir = $1;
+ my $parent = $2;
+ my $name = $3;
+
+ if ( $name =~ /^\s*(.*?)\s*\:\s*(.*?)\s*$/ ) { $name = $2; }
+ if ( $name =~ /^\s*(.*?)\s*\|\s*(.*?)\s*$/ ) { $name = $2; }
+
+ my %helphash = ();
+ $helphash{'Directory_Parent'} = $parent;
+ $helphash{'DefaultDir'} = $name;
+ $table{$dir} = \%helphash;
+ }
+ }
+
+ return \%table;
+}
+
+#################################################################################
+# Analyzing the content of Component.idt
+#################################################################################
+
+sub analyze_component_file
+{
+ my ($filecontent) = @_;
+
+ my %table = ();
+
+ for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
+ {
+ if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; }
+
+ if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
+ {
+ my $component = $1;
+ my $dir = $3;
+
+ $table{$component} = $dir;
+ }
+ }
+
+ return \%table;
+}
+
+#################################################################################
+# Analyzing the content of File.idt
+#################################################################################
+
+sub analyze_file_file
+{
+ my ($filecontent) = @_;
+
+ my %table = ();
+ my %fileorder = ();
+ my $maxsequence = 0;
+
+ for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
+ {
+ if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; }
+
+ if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
+ {
+ my $file = $1;
+ my $comp = $2;
+ my $filename = $3;
+ my $sequence = $8;
+
+ if ( $filename =~ /^\s*(.*?)\s*\|\s*(.*?)\s*$/ ) { $filename = $2; }
+
+ my %helphash = ();
+ $helphash{'Component'} = $comp;
+ $helphash{'FileName'} = $filename;
+ $helphash{'Sequence'} = $sequence;
+
+ $table{$file} = \%helphash;
+
+ $fileorder{$sequence} = $file;
+
+ if ( $sequence > $maxsequence ) { $maxsequence = $sequence; }
+ }
+ }
+
+ return (\%table, \%fileorder, $maxsequence);
+}
+
+####################################################################################
+# Recursively creating the directory tree
+####################################################################################
+
+sub create_directory_tree
+{
+ my ($parent, $pathcollector, $fulldir, $dirhash) = @_;
+
+ foreach my $dir ( keys %{$dirhash} )
+ {
+ if (( $dirhash->{$dir}->{'Directory_Parent'} eq $parent ) && ( $dirhash->{$dir}->{'DefaultDir'} ne "." ))
+ {
+ my $dirname = $dirhash->{$dir}->{'DefaultDir'};
+ # Create the directory
+ my $newdir = $fulldir . $separator . $dirname;
+ if ( ! -f $newdir ) { mkdir $newdir; }
+ # Saving in collector
+ $pathcollector->{$dir} = $newdir;
+ # Iteration
+ create_directory_tree($dir, $pathcollector, $newdir, $dirhash);
+ }
+ }
+}
+
+####################################################################################
+# Creating the directory tree
+####################################################################################
+
+sub create_directory_structure
+{
+ my ($dirhash, $targetdir) = @_;
+
+ print "Creating directories\n";
+
+ my %fullpathhash = ();
+
+ my @startparents = ("TARGETDIR", "INSTALLLOCATION");
+
+ foreach $dir (@startparents) { create_directory_tree($dir, \%fullpathhash, $targetdir, $dirhash); }
+
+ # Also adding the paths of the startparents
+ foreach $dir (@startparents)
+ {
+ if ( ! exists($fullpathhash{$dir}) ) { $fullpathhash{$dir} = $targetdir; }
+ }
+
+ return \%fullpathhash;
+}
+
+####################################################################################
+# Cygwin: Setting privileges for files
+####################################################################################
+
+sub change_privileges
+{
+ my ($destfile, $privileges) = @_;
+
+ my $localcall = "chmod $privileges " . "\"" . $destfile . "\"";
+ system($localcall);
+}
+
+####################################################################################
+# Cygwin: Setting privileges for files recursively
+####################################################################################
+
+sub change_privileges_full
+{
+ my ($target) = @_;
+
+ print "Changing privileges\n";
+
+ my $localcall = "chmod -R 755 " . "\"" . $target . "\"";
+ system($localcall);
+}
+
+######################################################
+# Creating a new directory with defined privileges
+######################################################
+
+sub create_directory_with_privileges
+{
+ my ($directory, $privileges) = @_;
+
+ my $returnvalue = 1;
+ my $infoline = "";
+
+ if (!(-d $directory))
+ {
+ my $localprivileges = oct("0".$privileges); # changes "777" to 0777
+ $returnvalue = mkdir($directory, $localprivileges);
+
+ if ($returnvalue)
+ {
+ my $localcall = "chmod $privileges $directory \>\/dev\/null 2\>\&1";
+ system($localcall);
+ }
+ }
+ else
+ {
+ my $localcall = "chmod $privileges $directory \>\/dev\/null 2\>\&1";
+ system($localcall);
+ }
+}
+
+######################################################
+# Creating a unique directory with pid extension
+######################################################
+
+sub create_pid_directory
+{
+ my ($directory) = @_;
+
+ $directory =~ s/\Q$separator\E\s*$//;
+ my $pid = $$; # process id
+ my $time = time(); # time
+
+ $directory = $directory . "_" . $pid . $time;
+
+ if ( ! -d $directory ) { create_directory($directory); }
+ else { exit_program("ERROR: Directory $directory already exists!"); }
+
+ return $directory;
+}
+
+####################################################################################
+# Copying files into installation set
+####################################################################################
+
+sub copy_files_into_directory_structure
+{
+ my ($fileorder, $filehash, $componenthash, $fullpathhash, $maxsequence, $unpackdir, $installdir, $dirhash) = @_;
+
+ print "Copying files\n";
+
+ for ( my $i = 1; $i <= $maxsequence; $i++ )
+ {
+ if ( exists($fileorder->{$i}) )
+ {
+ my $file = $fileorder->{$i};
+ if ( ! exists($filehash->{$file}->{'Component'}) ) { exit_program("ERROR: Did not find component for file: \"$file\"."); }
+ my $component = $filehash->{$file}->{'Component'};
+ if ( ! exists($componenthash->{$component}) ) { exit_program("ERROR: Did not find directory for component: \"$component\"."); }
+ my $dirname = $componenthash->{$component};
+ if ( ! exists($fullpathhash->{$dirname}) ) { exit_program("ERROR: Did not find full directory path for dir: \"$dirname\"."); }
+ my $destdir = $fullpathhash->{$dirname};
+ if ( ! exists($filehash->{$file}->{'FileName'}) ) { exit_program("ERROR: Did not find \"FileName\" for file: \"$file\"."); }
+ my $destfile = $filehash->{$file}->{'FileName'};
+
+ $destfile = $destdir . $separator . $destfile;
+ my $sourcefile = $unpackdir . $separator . $file;
+
+ if ( ! -f $sourcefile )
+ {
+ # It is possible, that this was an unpacked file
+ # Looking in the dirhash, to find the subdirectory in the installation set (the id is $dirname)
+ # subdir is not recursively analyzed, only one directory.
+
+ my $oldsourcefile = $sourcefile;
+ my $subdir = "";
+ if ( exists($dirhash->{$dirname}->{'DefaultDir'}) ) { $subdir = $dirhash->{$dirname}->{'DefaultDir'} . $separator; }
+ my $realfilename = $filehash->{$file}->{'FileName'};
+ my $localinstalldir = $installdir;
+
+ $localinstalldir =~ s/\\\s*$//;
+ $localinstalldir =~ s/\/\s*$//;
+
+ $sourcefile = $localinstalldir . $separator . $subdir . $realfilename;
+
+ if ( ! -f $sourcefile ) { exit_program("ERROR: File not found: \"$oldsourcefile\" (or \"$sourcefile\")."); }
+ }
+
+ my $copyreturn = copy($sourcefile, $destfile);
+
+ if ( ! $copyreturn) { exit_program("ERROR: Could not copy $source to $dest\n"); }
+
+ # if (( $^O =~ /cygwin/i ) && ( $destfile =~ /\.exe\s*$/ )) { change_privileges($destfile, "775"); }
+ }
+ # else # allowing missing sequence numbers ?
+ # {
+ # exit_program("ERROR: No file assigned to sequence $i");
+ # }
+ }
+}
+
+######################################################
+# Removing a complete directory with subdirectories
+######################################################
+
+sub remove_complete_directory
+{
+ my ($directory, $start) = @_;
+
+ my @content = ();
+ my $infoline = "";
+
+ $directory =~ s/\Q$separator\E\s*$//;
+
+ if ( -d $directory )
+ {
+ if ( $start ) { print "Removing directory $directory\n"; }
+
+ opendir(DIR, $directory);
+ @content = readdir(DIR);
+ closedir(DIR);
+
+ my $oneitem;
+
+ foreach $oneitem (@content)
+ {
+ if ((!($oneitem eq ".")) && (!($oneitem eq "..")))
+ {
+ my $item = $directory . $separator . $oneitem;
+
+ if ( -f $item || -l $item ) # deleting files or links
+ {
+ unlink($item);
+ }
+
+ if ( -d $item ) # recursive
+ {
+ remove_complete_directory($item, 0);
+ }
+ }
+ }
+
+ # try to remove empty directory
+ my $returnvalue = rmdir $directory;
+ if ( ! $returnvalue ) { print "Warning: Problem with removing empty dir $directory\n"; }
+ }
+}
+
+####################################################################################
+# Defining a temporary path
+####################################################################################
+
+sub get_temppath
+{
+ my $temppath = "";
+
+ if (( $ENV{'TMP'} ) || ( $ENV{'TEMP'} ))
+ {
+ if ( $ENV{'TMP'} ) { $temppath = $ENV{'TMP'}; }
+ elsif ( $ENV{'TEMP'} ) { $temppath = $ENV{'TEMP'}; }
+
+ $temppath =~ s/\Q$separator\E\s*$//; # removing ending slashes and backslashes
+ $temppath = $temppath . $separator . $globaltempdirname;
+ $temppath = mkdtemp($temppath);
+
+ my $dirsave = $temppath;
+
+ $temppath = $temppath . $separator . "a";
+ $temppath = create_pid_directory($temppath);
+
+ if ( ! -d $temppath ) { exit_program("ERROR: Failed to create directory $temppath ! Possible reason: Wrong privileges in directory $dirsave."); }
+
+ if ( $^O =~ /cygwin/i )
+ {
+ $temppath =~ s/\\/\\\\/g;
+ chomp( $temppath = qx{cygpath -w "$temppath"} );
+ }
+
+ $savetemppath = $temppath;
+ }
+ else
+ {
+ exit_program("ERROR: Could not set temporary directory (TMP and TEMP not set!).");
+ }
+
+ return $temppath;
+}
+
+####################################################################################
+# Reading one file
+####################################################################################
+
+sub read_file
+{
+ my ($localfile) = @_;
+
+ my @localfile = ();
+
+ open( IN, "<$localfile" ) || exit_program("ERROR: Cannot open file $localfile for reading");
+
+ # Don't use "my @localfile = <IN>" here, because
+ # perl has a problem with the internal "large_and_huge_malloc" function
+ # when calling perl using MacOS 10.5 with a perl built with MacOS 10.4
+ while ( $line = <IN> ) {
+ push @localfile, $line;
+ }
+
+ close( IN );
+
+ return \@localfile;
+}
+
+###############################################################
+# Setting the time string for the
+# Summary Information stream in the
+# msi database of the admin installations.
+###############################################################
+
+sub get_sis_time_string
+{
+ # Syntax: <yyyy/mm/dd hh:mm:ss>
+ my $second = (localtime())[0];
+ my $minute = (localtime())[1];
+ my $hour = (localtime())[2];
+ my $day = (localtime())[3];
+ my $month = (localtime())[4];
+ my $year = 1900 + (localtime())[5];
+ $month++;
+
+ if ( $second < 10 ) { $second = "0" . $second; }
+ if ( $minute < 10 ) { $minute = "0" . $minute; }
+ if ( $hour < 10 ) { $hour = "0" . $hour; }
+ if ( $day < 10 ) { $day = "0" . $day; }
+ if ( $month < 10 ) { $month = "0" . $month; }
+
+ my $timestring = $year . "/" . $month . "/" . $day . " " . $hour . ":" . $minute . ":" . $second;
+
+ return $timestring;
+}
+
+###############################################################
+# Writing content of administrative installations into
+# Summary Information Stream of msi database.
+# This is required for example for following
+# patch processes using Windows Installer service.
+###############################################################
+
+sub write_sis_info
+{
+ my ($msidatabase) = @_;
+
+ print "Setting SIS in msi database\n";
+
+ if ( ! -f $msidatabase ) { exit_program("ERROR: Cannot find file $msidatabase"); }
+
+ my $msiinfo = "msiinfo.exe"; # Has to be in the path
+ my $infoline = "";
+ my $systemcall = "";
+ my $returnvalue = "";
+
+ # Required setting for administrative installations:
+ # -w 4 (source files are unpacked), wordcount
+ # -s <date of admin installation>, LastPrinted, Syntax: <yyyy/mm/dd hh:mm:ss>
+ # -l <person_making_admin_installation>, LastSavedBy
+
+ my $wordcount = 4; # Unpacked files
+ my $lastprinted = get_sis_time_string();
+ my $lastsavedby = "Installer";
+
+ my $localmsidatabase = $msidatabase;
+
+ if( $^O =~ /cygwin/i )
+ {
+ $localmsidatabase = qx{cygpath -w "$localmsidatabase"};
+ $localmsidatabase =~ s/\\/\\\\/g;
+ $localmsidatabase =~ s/\s*$//g;
+ }
+
+ $systemcall = $msiinfo . " " . "\"" . $localmsidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby";
+
+ $returnvalue = system($systemcall);
+
+ if ($returnvalue)
+ {
+ $infoline = "ERROR: Could not execute $systemcall !\n";
+ exit_program($infoline);
+ }
+}
+
+###############################################################
+# Convert time string
+###############################################################
+
+sub convert_timestring
+{
+ my ($secondstring) = @_;
+
+ my $timestring = "";
+
+ if ( $secondstring < 60 ) # less than a minute
+ {
+ if ( $secondstring < 10 ) { $secondstring = "0" . $secondstring; }
+ $timestring = "00\:$secondstring min\.";
+ }
+ elsif ( $secondstring < 3600 )
+ {
+ my $minutes = $secondstring / 60;
+ my $seconds = $secondstring % 60;
+ if ( $minutes =~ /(\d*)\.\d*/ ) { $minutes = $1; }
+ if ( $minutes < 10 ) { $minutes = "0" . $minutes; }
+ if ( $seconds < 10 ) { $seconds = "0" . $seconds; }
+ $timestring = "$minutes\:$seconds min\.";
+ }
+ else # more than one hour
+ {
+ my $hours = $secondstring / 3600;
+ my $secondstring = $secondstring % 3600;
+ my $minutes = $secondstring / 60;
+ my $seconds = $secondstring % 60;
+ if ( $hours =~ /(\d*)\.\d*/ ) { $hours = $1; }
+ if ( $minutes =~ /(\d*)\.\d*/ ) { $minutes = $1; }
+ if ( $hours < 10 ) { $hours = "0" . $hours; }
+ if ( $minutes < 10 ) { $minutes = "0" . $minutes; }
+ if ( $seconds < 10 ) { $seconds = "0" . $seconds; }
+ $timestring = "$hours\:$minutes\:$seconds hours";
+ }
+
+ return $timestring;
+}
+
+###############################################################
+# Returning time string for logging
+###############################################################
+
+sub get_time_string
+{
+ my $currenttime = time();
+ $currenttime = $currenttime - $starttime;
+ $currenttime = convert_timestring($currenttime);
+ $currenttime = localtime() . " \(" . $currenttime . "\)\n";
+ return $currenttime;
+}
+
+####################################################################################
+# Simulating an administrative installation
+####################################################################################
+
+$starttime = time();
+
+getparameter();
+controlparameter();
+check_local_msidb();
+check_system_path();
+my $temppath = get_temppath();
+
+print("\nmsi database: $databasepath\n");
+print("Destination directory: $targetdir\n" );
+
+my $helperdir = $temppath . $separator . "installhelper";
+create_directory($helperdir);
+
+# Get File.idt, Component.idt and Directory.idt from database
+
+my $tablelist = "File Directory Component Media CustomAction";
+extract_tables_from_database($databasepath, $helperdir, $tablelist);
+
+# Set unpackdir
+my $unpackdir = $helperdir . $separator . "unpack";
+create_directory($unpackdir);
+
+# Reading media table to check for internal cabinet files
+my $filename = $helperdir . $separator . "Media.idt";
+if ( ! -f $filename ) { exit_program("ERROR: Could not find required file: $filename !"); }
+my $filecontent = read_file($filename);
+my $cabfilehash = analyze_media_file($filecontent);
+
+# Check, if there are internal cab files
+my ( $contains_internal_cabfiles, $all_internal_cab_files) = check_for_internal_cabfiles($cabfilehash);
+
+if ( $contains_internal_cabfiles )
+{
+ # Set unpackdir
+ my $cabdir = $helperdir . $separator . "internal_cabs";
+ create_directory($cabdir);
+ my $from = cwd();
+ chdir($cabdir);
+ # Exclude all cabinet files from database
+ my $all_excluded_cabs = extract_cabs_from_database($databasepath, $all_internal_cab_files);
+ print "Unpacking files from internal cabinet file(s)\n";
+ foreach my $cabfile ( @{$all_excluded_cabs} ) { unpack_cabinet_file($cabfile, $unpackdir); }
+ chdir($from);
+}
+
+# Unpack all cab files into $helperdir, cab files must be located next to msi database
+my $installdir = $databasepath;
+
+get_path_from_fullqualifiedname(\$installdir);
+
+my $databasefilename = $databasepath;
+make_absolute_filename_to_relative_filename(\$databasefilename);
+
+my $cabfiles = find_file_with_file_extension("cab", $installdir);
+
+if (( $#{$cabfiles} < 0 ) && ( ! $contains_internal_cabfiles )) { exit_program("ERROR: Did not find any cab file in directory $installdir"); }
+
+print "Unpacking files from cabinet file(s)\n";
+for ( my $i = 0; $i <= $#{$cabfiles}; $i++ )
+{
+ my $cabfile = $installdir . $separator . ${$cabfiles}[$i];
+ unpack_cabinet_file($cabfile, $unpackdir);
+}
+
+# Reading tables
+$filename = $helperdir . $separator . "Directory.idt";
+$filecontent = read_file($filename);
+my $dirhash = analyze_directory_file($filecontent);
+
+$filename = $helperdir . $separator . "Component.idt";
+$filecontent = read_file($filename);
+my $componenthash = analyze_component_file($filecontent);
+
+$filename = $helperdir . $separator . "File.idt";
+$filecontent = read_file($filename);
+my ( $filehash, $fileorder, $maxsequence ) = analyze_file_file($filecontent);
+
+# Creating the directory structure
+my $fullpathhash = create_directory_structure($dirhash, $targetdir);
+
+# Copying files
+copy_files_into_directory_structure($fileorder, $filehash, $componenthash, $fullpathhash, $maxsequence, $unpackdir, $installdir, $dirhash);
+if ( $^O =~ /cygwin/i ) { change_privileges_full($targetdir); }
+
+my $msidatabase = $targetdir . $separator . $databasefilename;
+my $copyreturn = copy($databasepath, $msidatabase);
+if ( ! $copyreturn) { exit_program("ERROR: Could not copy $source to $dest\n"); }
+
+# Saving info in Summary Information Stream of msi database (required for following patches)
+if ( $msiinfo_available ) { write_sis_info($msidatabase); }
+
+# Removing the helper directory
+remove_complete_directory($temppath, 1);
+
+print "\nSuccessful installation: " . get_time_string();
diff --git a/setup_native/scripts/downloadscript.sh b/setup_native/scripts/downloadscript.sh
new file mode 100644
index 000000000..7246ebcda
--- /dev/null
+++ b/setup_native/scripts/downloadscript.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+linenum=LINENUMBERPLACEHOLDER
+
+UNPACKDIR=/var/tmp/unpack_PRODUCTNAMEPLACEHOLDER
+diskSpaceRequired=DISCSPACEPLACEHOLDER
+checksum=CHECKSUMPLACEHOLDER
+
+EXTRACTONLY="no"
+if [ "$1" = "-x" ]
+then
+ EXTRACTONLY=yes
+fi
+
+# Determining current platform
+
+platform=`uname -s`
+
+case $platform in
+SunOS)
+ tail_prog="tail"
+ ;;
+Linux)
+ tail_prog="tail -n"
+ ;;
+*)
+ tail_prog="tail"
+ ;;
+esac
+
+# Asking for the unpack directory
+
+echo
+echo "Select the directory in which to save the unpacked files. [$UNPACKDIR] "
+read reply leftover
+if [ "x$reply" != "x" ]
+then
+ UNPACKDIR="$reply"
+fi
+
+if [ -d $UNPACKDIR ]; then
+ printf "Directory $UNPACKDIR already exists.\n"
+ printf "Please select a new directory name.\n"
+ exit 1
+fi
+
+# Unpacking
+
+mkdir -m 700 $UNPACKDIR
+
+diskSpace=`df -k $UNPACKDIR | $tail_prog -1 | awk '{if ( $4 ~ /%/) { print $3 } else { print $4 } }'`
+if [ $diskSpace -lt $diskSpaceRequired ]; then
+ printf "The selected drive does not have enough disk space available.\n"
+ printf "PRODUCTNAMEPLACEHOLDER requires at least %s kByte.\n" $diskSpaceRequired
+ exit 1
+fi
+
+trap 'rm -rf $UNPACKDIR; exit 1' HUP INT QUIT TERM
+
+if [ -x /usr/bin/sum ] ; then
+ echo "File is being checked for errors ..."
+
+ sum=`$tail_prog +$linenum $0 | /usr/bin/sum`
+ sum=`echo $sum | awk '{ print $1 }'`
+
+ if [ $sum != $checksum ]; then
+ echo "The download file appears to be corrupted. Please download PRODUCTNAMEPLACEHOLDER again."
+ exit 1
+ fi
+fi
+
+echo "Unpacking ..."
+
+$tail_prog +$linenum $0 | (cd $UNPACKDIR; tar xf -)
+
+echo "All files have been successfully unpacked."
+
+if [ "$EXTRACTONLY" != "yes" ]
+then
+ if [ -f $UNPACKDIR/setup ]
+ then
+ chmod 775 $UNPACKDIR/setup
+ $UNPACKDIR/setup
+ fi
+fi
+
+exit 0
diff --git a/setup_native/scripts/fake-db.spec b/setup_native/scripts/fake-db.spec
new file mode 100644
index 000000000..a7a5c318b
--- /dev/null
+++ b/setup_native/scripts/fake-db.spec
@@ -0,0 +1,57 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+Name: fake-db
+Version: 1.0
+Release: 0
+Summary: This is a dummy package
+Group: dummy
+License: LGPLv3 with MPLv2 on ALv2
+BuildArch: noarch
+AutoReqProv: no
+%define _tmppath /tmp
+#BuildRoot: %{_tmppath}/%{name}-root
+Provides: libgnomevfs-2.so.0
+Provides: libgnomevfs-2.so.0()(64bit)
+Provides: libfreetype.so.6
+Provides: libfreetype.so.6()(64bit)
+Provides: /bin/sh
+Provides: /bin/basename
+Provides: /bin/cat
+Provides: /bin/cp
+Provides: /bin/gawk
+Provides: /bin/grep
+Provides: /bin/ln
+Provides: /bin/ls
+Provides: /bin/mkdir
+Provides: /bin/mv
+Provides: /bin/pwd
+Provides: /bin/rm
+Provides: /bin/sed
+Provides: /bin/sort
+Provides: /bin/touch
+Provides: /usr/bin/cut
+Provides: /usr/bin/dirname
+Provides: /usr/bin/expr
+Provides: /usr/bin/find
+Provides: /usr/bin/tail
+Provides: /usr/bin/tr
+Provides: /usr/bin/wc
+%description
+a dummy package
+%files
diff --git a/setup_native/scripts/install_create.pl b/setup_native/scripts/install_create.pl
new file mode 100644
index 000000000..c7659c40e
--- /dev/null
+++ b/setup_native/scripts/install_create.pl
@@ -0,0 +1,60 @@
+: # -*- perl -*-
+eval 'exec perl -wS $0 ${1+"$@"}'
+ if 0;
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+# create setup self extracting script
+
+if( $#ARGV < 2 )
+ {
+ print <<ENDHELP;
+USAGE: $0 <inputshellscript> <libraryfile> <outputshellscript>
+ <inputshellscript>: the start shell script, located next to this perl script
+ <libraryfile>: the library file, that is included into the shell script
+ <outfile>: the target shellscript
+
+ENDHELP
+ exit;
+ }
+
+$infile = $ARGV[0];
+$library = $ARGV[1];
+$outfile = $ARGV[2];
+
+# read script header
+open( SCRIPT, "<$infile" ) || die "cannot open $infile";
+open( OUTFILE, ">$outfile$$.tmp" ) || die "cannot open $outfile";
+@scriptlines = <SCRIPT>;
+$linenum = $#scriptlines+2;
+foreach (@scriptlines)
+{
+ # lineend conversion (be on the safe side)
+ chomp;
+ $_ =~ tr/\r//;
+ s/^\s*linenum=.*$/linenum=$linenum/;
+ print OUTFILE "$_\n";
+}
+close( SCRIPT );
+close( OUTFILE );
+
+system( "cat $library >>$outfile$$.tmp" );
+rename "$outfile$$.tmp", "$outfile";
+
+chmod 0775, $outfile;
+
+exit;
diff --git a/setup_native/scripts/install_linux.sh b/setup_native/scripts/install_linux.sh
new file mode 100644
index 000000000..df224211e
--- /dev/null
+++ b/setup_native/scripts/install_linux.sh
@@ -0,0 +1,313 @@
+#!/bin/bash
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+ADD="no"
+LINK="no"
+UPDATE="ask"
+UNPACKDIR=""
+USAGE="Usage: $0 [-a,--add] [-l,--link] [-U,--update] [-h,--help] <rpm-source-dir> <office-installation-dir>"
+
+help()
+{
+ echo
+ echo "User Mode Installation script for developer and knowledgeable early access tester"
+ echo
+ echo "This installation method is not intended for use in a production environment!"
+ echo "Using this script is unsupported and completely at your own risk"
+ echo
+ echo "Usage:" $0 [-lU] "<rpm-source-dir> <office-installation-dir>"
+ echo " <rpm-source-dir>: directory *only* containing the Linux rpm packages to be installed"
+ echo " or language pack shell script containing the rpm packages"
+ echo " <office-installation-dir>: directory to where the office will get installed into"
+ echo
+ echo "Optional Parameter:"
+ echo " -a,--add: add to an existing <office-installation-dir>"
+ echo " -l,--link: create a link \"soffice\" in $HOME"
+ echo " -U,--update: update without asking"
+ echo " -h,--help: output this help"
+ echo
+}
+
+try_to_unpack_languagepack_file()
+{
+ FILENAME=$PACKAGE_PATH
+
+ # Checking, if $FILENAME is a language pack.
+ # String "language package" has to exist in the shell script file.
+ # If this is no language pack, the installation is not supported
+
+ SEARCHSTRING=`head --lines=10 $FILENAME | grep "language package"`
+
+ if [ ! -z "$SEARCHSTRING" ]
+ then
+ echo "First parameter $FILENAME is a language pack";
+ else
+ printf "\nERROR: First parameter $FILENAME is a file, but no language pack shell script.\n"
+ echo $USAGE
+ exit 2
+ fi
+
+ echo "Unpacking shell script $FILENAME"
+ TAILLINE=`head --lines=20 $FILENAME | sed --quiet 's/linenum=//p'`
+
+ UNPACKDIR=/var/tmp/install_$$
+ mkdir $UNPACKDIR
+ # UNPACKDIR=`mktemp -d`
+ tail -n +$TAILLINE $FILENAME | gunzip | (cd $UNPACKDIR; tar xvf -)
+
+ # Setting the new package path, in which the packages exist
+ PACKAGE_PATH=$UNPACKDIR
+
+ # Setting variable UPDATE, because an Office installation has to exist, if a language pack shall be installed
+ UPDATE="yes"
+}
+
+#
+# this script is for userland not for root
+#
+
+if [ $UID -eq 0 ]
+then
+ printf "\nThis script is for installation without administrative rights only\nPlease use rpm to install as root\n"
+ help
+ exit 2
+fi
+
+set -- `getopt -u -o 'alhU' -l 'add,link,help,update' -- $*`
+
+if [ $? != 0 ]
+then
+ echo $USAGE
+ exit 2
+fi
+
+for i in $*
+do
+ case $i in
+ -a|--add) ADD="yes"; shift;;
+ -h|--help) help; exit 0;;
+ -l|--link) LINK="yes"; shift;;
+ -U|--update) UPDATE="yes"; shift;;
+ --) shift; break;;
+ esac
+done
+
+if [ $# != 2 ]
+then
+ echo $USAGE
+ echo "Example: $0 . ~/libreoffice"
+ exit 2
+fi
+
+PACKAGE_PATH=$1
+
+#
+# If the first parameter is a shell script (download installation set), the packages have to
+# be unpacked into temp directory
+#
+
+if [ -f "$PACKAGE_PATH" ]
+then
+ try_to_unpack_languagepack_file
+fi
+
+#
+# Check and get the list of packages to install
+#
+
+RPMLIST=`find $PACKAGE_PATH -maxdepth 2 -type f -name "*.rpm" ! -name "*-menus-*" ! -name "*-desktop-integration-*" ! -name "jre*" ! -name "*-userland-*" -print`
+
+if [ -z "$RPMLIST" ]
+then
+ printf "\n$0: No packages found in $PACKAGE_PATH\n"
+ exit 2
+fi
+
+# #163256# check if we are on a debian system...
+if rpm --help | grep debian >/dev/null;
+then
+ DEBIAN_FLAGS="--force-debian --nodeps"
+else
+ DEBIAN_FLAGS=
+fi
+
+#
+# Determine whether this should be an update or a fresh install
+#
+
+INSTALLDIR=$2
+RPM_DB_PATH=${INSTALLDIR}/.RPM_OFFICE_DATABASE
+
+# Check for versionrc
+if [ -f ${INSTALLDIR}/program/versionrc ]; then VERSIONRC=versionrc; fi
+
+if [ "$UPDATE" = "ask" ]
+then
+ PRODUCT=`sed --silent -e "
+/^buildid=/ {
+s/buildid=\(.*\)/ [\1]/
+h
+}
+/^ProductKey=/ {
+s/ProductKey=//
+G
+p
+}" ${INSTALLDIR}/program/${VERSIONRC:-bootstraprc} 2>/dev/null | tr -d "\012"`
+
+ if [ ! -z "$PRODUCT" ]
+ then
+ echo
+ echo "Found an installation of $PRODUCT in $INSTALLDIR"
+ echo
+ while [ "$UPDATE" != "yes" ]
+ do
+ read -a UPDATE -p "Do you want to update this installation (yes/no)? "
+ if [ "$UPDATE" = "no" ]
+ then
+ exit 2
+ fi
+ done
+ elif [ -d $RPM_DB_PATH -a "$ADD" = "no" ]
+ then
+ echo
+ echo "The following packages are already installed in $INSTALLDIR"
+ echo
+ rpm --dbpath `cd $RPM_DB_PATH; pwd` --query --all
+ echo
+ while [ "$UPDATE" != "yes" ]
+ do
+ read -a UPDATE -p "Do you want to continue with this installation (yes/no)? "
+ if [ "$UPDATE" = "no" ]
+ then
+ exit 2
+ fi
+ done
+ else
+ UPDATE="no"
+ fi
+fi
+
+#
+# Check/Create installation directory
+#
+
+if [ "$UPDATE" = "yes" ]
+then
+ # restore original bootstraprc
+ mv -f ${INSTALLDIR}/program/bootstraprc.orig ${INSTALLDIR}/program/bootstraprc 2>/dev/null
+
+ # the RPM_DB_PATH must be absolute
+ if [ ! "${RPM_DB_PATH:0:1}" = "/" ]; then
+ RPM_DB_PATH=`cd ${RPM_DB_PATH}; pwd`
+ fi
+
+ # we should use --freshen for updates to not add languages with patches, but this will break
+ # language packs, so leave it for now ..
+# RPMCMD="--freshen"
+ RPMCMD="--upgrade"
+else
+ rmdir ${INSTALLDIR} 2>/dev/null
+
+ mkdir -p $RPM_DB_PATH || exit 2
+ # XXX why? XXX
+ chmod 700 $RPM_DB_PATH
+
+ # the RPM_DB_PATH must be absolute
+ if [ ! "${RPM_DB_PATH:0:1}" = "/" ]; then
+ RPM_DB_PATH=`cd ${RPM_DB_PATH}; pwd`
+ fi
+
+ # Creating RPM database and initializing
+ if [ "$ADD" = "no" ]; then
+ rpm --initdb --dbpath $RPM_DB_PATH
+ fi
+
+ # Default install command
+ RPMCMD="--install"
+fi
+
+# populate the private rpm database with the dependencies needed
+FAKEDBRPM=/tmp/fake-db-1.0-$$.noarch.rpm
+linenum=???
+tail -n +$linenum $0 > $FAKEDBRPM
+
+rpm ${DEBIAN_FLAGS} --upgrade --ignoresize --dbpath $RPM_DB_PATH $FAKEDBRPM
+
+rm -f $FAKEDBRPM
+
+echo "Packages found:"
+for i in $RPMLIST ; do
+ echo `basename $i`
+done
+
+#
+# Perform the installation
+#
+
+echo
+echo "####################################################################"
+echo "# Installation of the found packages #"
+echo "####################################################################"
+echo
+echo "Path to the database: " $RPM_DB_PATH
+echo "Path to the packages: " $PACKAGE_PATH
+echo "Path to the installation: " $INSTALLDIR
+echo
+echo "Installing the RPMs"
+
+ABSROOT=`cd ${INSTALLDIR}; pwd`
+RELOCATIONS=`rpm -qp --qf "--relocate %{PREFIXES}=${ABSROOT}%{PREFIXES} \n" $RPMLIST | sort -u | tr -d "\012"`
+UserInstallation=\$BRAND_BASE_DIR/../UserInstallation rpm ${DEBIAN_FLAGS} --nodeps $RPMCMD --ignoresize -vh $RELOCATIONS --dbpath $RPM_DB_PATH $RPMLIST
+
+#
+# Create a link into the users home directory
+#
+
+if [ "$LINK" = "yes" ]
+then
+ find `cd "$INSTALLDIR" && pwd` -name soffice -type f -perm /u+x -exec /bin/bash -ce 'ln -sf "$0" "$HOME/soffice" && echo "Creating link from $0 to $HOME/soffice"' {} \;
+fi
+
+if [ "$UPDATE" = "yes" -a ! -f $INSTALLDIR/program/bootstraprc ]
+then
+ echo
+ echo "Update failed due to a bug in RPM, uninstalling .."
+ rpm ${DEBIAN_FLAGS} --erase -v --nodeps --dbpath $RPM_DB_PATH `rpm --query --queryformat "%{NAME} " --package $RPMLIST --dbpath $RPM_DB_PATH`
+ echo
+ echo "Now re-installing new packages .."
+ echo
+ rpm ${DEBIAN_FLAGS} --install --nodeps --ignoresize -vh $RELOCATIONS --dbpath $RPM_DB_PATH $RPMLIST
+ echo
+fi
+
+# patch the "bootstraprc" to create a self-containing installation
+find "$INSTALLDIR" -type f -name bootstraprc -exec /bin/bash -ce 'test ! -e "$0".orig && mv "$0" "$0".orig && sed '\''s,^UserInstallation=$SYSUSERCONFIG.*,UserInstallation=$BRAND_BASE_DIR/../UserInstallation,'\'' "$0".orig > "$0"' {} \;
+
+# if an unpack directory exists, it can be removed now
+if [ ! -z "$UNPACKDIR" ]
+then
+ rm $UNPACKDIR/*.rpm
+ rmdir $UNPACKDIR
+ echo "Removed temporary directory $UNPACKDIR"
+fi
+
+echo
+echo "Installation done ..."
+
+exit 0
diff --git a/setup_native/scripts/langpackscript.sh b/setup_native/scripts/langpackscript.sh
new file mode 100644
index 000000000..4f0dd5484
--- /dev/null
+++ b/setup_native/scripts/langpackscript.sh
@@ -0,0 +1,170 @@
+#!/bin/sh
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+MYUID=`id | sed "s/(.*//g" | sed "s/.*=//"`
+
+if [ $MYUID -ne 0 ]
+then
+ echo You need to have super-user rights to install this language package
+ exit 1
+fi
+
+linenum=LINENUMBERPLACEHOLDER
+
+# Determining current platform
+
+platform=`uname -s`
+
+case $platform in
+SunOS)
+ tail_prog="tail"
+ ;;
+Linux)
+ tail_prog="tail -n"
+ ;;
+*)
+ tail_prog="tail"
+ ;;
+esac
+
+more << "EOF"
+LICENSEFILEPLACEHOLDER
+EOF
+
+agreed=
+while [ x$agreed = x ]; do
+ echo
+ echo "Do you agree to the above license terms? [yes or no] "
+ read reply leftover
+ case $reply in
+ y* | Y*)
+ agreed=1;;
+ n* | N*)
+ echo "If you don't agree to the license you can't install this software";
+ exit 1;;
+ esac
+done
+
+case $platform in
+SunOS)
+ SEARCHPACKAGENAME="BASISPACKAGEPREFIXPLACEHOLDERPRODUCTVERSIONPLACEHOLDER-core01"
+ echo
+ echo "Searching for the FULLPRODUCTNAMELONGPLACEHOLDER installation ..."
+ PACKAGENAME=`pkginfo -x | grep $SEARCHPACKAGENAME | sed "s/ .*//"`
+ if [ "x$PACKAGENAME" != "x" ]
+ then
+ PRODUCTINSTALLLOCATION="`pkginfo -r $PACKAGENAME`"
+ else
+ echo "FULLPRODUCTNAMELONGPLACEHOLDER not installed (no package $SEARCHPACKAGENAME installed)"
+ exit 1
+ fi
+ ;;
+Linux)
+ SEARCHPACKAGENAME="BASISPACKAGEPREFIXPLACEHOLDERPRODUCTVERSIONPLACEHOLDER-core01"
+ FIXPATH="/openoffice.org"
+ echo
+ echo "Searching for the FULLPRODUCTNAMELONGPLACEHOLDER installation ..."
+ RPMNAME=`rpm -qa | grep $SEARCHPACKAGENAME`
+ if [ "x$RPMNAME" != "x" ]
+ then
+ PRODUCTINSTALLLOCATION="`rpm -ql $RPMNAME | head -n 1`"
+ else
+ echo "FULLPRODUCTNAMELONGPLACEHOLDER not installed (no package $SEARCHPACKAGENAME installed)"
+ exit 1
+ fi
+ PRODUCTINSTALLLOCATION=`echo $PRODUCTINSTALLLOCATION | sed "s#${FIXPATH}##"`
+ ;;
+*)
+ echo "Unsupported platform"
+ exit 1
+ ;;
+esac
+
+# Asking for the installation directory
+
+# echo
+# echo "Where do you want to install the language pack ? [$PRODUCTINSTALLLOCATION] "
+# read reply leftover
+# if [ "x$reply" != "x" ]
+# then
+# PRODUCTINSTALLLOCATION="$reply"
+# fi
+
+# Unpacking
+
+outdir=/var/tmp/install_$$
+mkdir $outdir
+
+#diskSpace=`df -k $outdir | $tail_prog -1 | awk '{if ( $4 ~ /%/) { print $3 } else { print $4 } }'`
+#if [ $diskSpace -lt $diskSpaceRequired ]; then
+# printf "You will need at least %s kBytes of free disk space\n" $diskSpaceRequired
+# printf "Please free up the required disk space and try again\n"
+# exit 3
+#fi
+
+trap 'rm -rf $outdir; exit 1' HUP INT QUIT TERM
+echo "Unpacking and installing..."
+
+#if [ -x /usr/bin/sum ] ; then
+# echo "Checksumming..."
+#
+# sum=`/usr/bin/sum $outdir/$outname`
+# index=1
+# for s in $sum
+# do
+# case $index in
+# 1) sum1=$s;
+# index=2;
+# ;;
+# 2) sum2=$s;
+# index=3;
+# ;;
+# esac
+# done
+# if expr $sum1 != <sum1replace> || expr $sum2 != <sum2replace> ; then
+# echo "The download file appears to be corrupted. Please refer"
+# echo "to the Troubleshooting section of the Installation"
+# exit 1
+# fi
+#else
+# echo "Can't find /usr/bin/sum to do checksum. Continuing anyway."
+#fi
+
+case $platform in
+SunOS)
+ $tail_prog +$linenum $0 | gunzip | (cd $outdir; tar xvf -)
+ adminfile=$outdir/admin.$$
+ echo "basedir=$PRODUCTINSTALLLOCATION" > $adminfile
+INSTALLLINES
+ ;;
+Linux)
+ $tail_prog +$linenum $0 | gunzip | (cd $outdir; tar xvf -)
+INSTALLLINES
+ ;;
+*)
+ echo "Unsupported platform"
+ exit 1
+ ;;
+esac
+
+rm -rf $outdir
+
+echo "Done..."
+
+exit 0
diff --git a/setup_native/scripts/mac_install.script b/setup_native/scripts/mac_install.script
new file mode 100644
index 000000000..57609636e
--- /dev/null
+++ b/setup_native/scripts/mac_install.script
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# shell script as a workaround since it is hard to impossible to store compiled
+# applescript in CVS and running osacompile would require a GUI session while
+# building (or root privileges)
+# using osascript only works when the shell script is camouflaged as application
+
+MY_DIR=$(dirname "$0")
+
+osascript "$MY_DIR/osx_install.applescript"
diff --git a/setup_native/scripts/osx_install_languagepack.applescript b/setup_native/scripts/osx_install_languagepack.applescript
new file mode 100644
index 000000000..3b4a116fb
--- /dev/null
+++ b/setup_native/scripts/osx_install_languagepack.applescript
@@ -0,0 +1,175 @@
+(*
+
+ 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/.
+
+ This file incorporates work covered by the following license notice:
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright
+ ownership. The ASF licenses this file to you under the Apache
+ License, Version 2.0 (the "License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of
+ the License at http://www.apache.org/licenses/LICENSE-2.0 .
+
+This script is meant to
+ 1) Identify installed instances of the product
+ 2) check whether the user has write-access (and if not
+ ask for authentication)
+ 3) install the shipped tarball
+*)
+
+-- strings for localisations - to be meant to be replaced
+-- by a makefile or similar
+set OKLabel to "[OKLabel]"
+set InstallLabel to "[InstallLabel]"
+set AbortLabel to "[AbortLabel]"
+set intro to "[IntroText1]
+
+[IntroText2]
+
+[IntroText3]"
+set chooseMyOwn to "[ChooseMyOwnText]"
+set listPrompt to "[ListPromptText]"
+set chooseManual to "[ChooseManualText]"
+set listOKLabel to "[ListOKLabelText]"
+set listCancelLabel to "[ListCancelLabel]"
+set appInvalid to "[AppInvalidText1]
+
+[AppInvalidText2]" -- string will begin with the chosen application's name
+set startInstall to "[StartInstallText1]
+
+[StartInstallText2]"
+set IdentifyQ to "[IdentifyQText]
+
+[IdentifyQText2]"
+set IdentifyYES to "[IdentifyYES]"
+set IdentifyNO to "[IdentifyNO]"
+set installFailed to "[InstallFailedText]"
+set installComplete to "[InstallCompleteText]
+
+[InstallCompleteText2]"
+
+set sourcedir to (do shell script "dirname " & quoted form of POSIX path of (path to of me))
+
+activate
+display dialog intro buttons {AbortLabel, InstallLabel} default button 2
+
+if (button returned of result) is AbortLabel then
+ return 2
+end if
+
+set found_ooos_all to ""
+-- command might return an error if spotlight is disabled completely
+try
+ set found_ooos_all to (do shell script "mdfind \"kMDItemContentType == 'com.apple.application-bundle' && kMDItemDisplayName == '[PRODUCTNAME]'\"")
+end try
+set found_ooos_all to found_ooos_all & "
+" & chooseMyOwn
+
+set found_ooos_all_paragraphs to paragraphs in found_ooos_all
+
+set found_ooos to {}
+repeat with currentApp in found_ooos_all_paragraphs
+ if currentApp does not start with "/Volumes" then
+ copy currentApp to the end of found_ooos
+ end if
+end repeat
+
+-- repeat with oneApp in found_ooos
+-- display dialog oneApp
+-- end repeat
+
+-- the choice returned is of type "list"
+-- Show selection dialog only if more than one or no product was found
+-- The first item is an empty string, if no app was found and no app started with "/Volumes"
+-- The first item is chooseMyOwn, if no app was found and at least one app started with "/Volumes"
+if (get first item of found_ooos as string) is "" then
+ set the choice to (choose from list found_ooos default items (get second item of found_ooos) with prompt listPrompt OK button name listOKLabel cancel button name listCancelLabel)
+ if choice is false then
+ -- do nothing, the user cancelled the installation
+ return 2 --aborted by user
+ else if (choice as string) is chooseMyOwn then
+ -- yeah, one needs to use "choose file", otherwise
+ -- the user would not be able to select the .app
+ set the choice to POSIX path of (choose file with prompt chooseManual of type "com.apple.application-bundle" without showing package contents and invisibles)
+ end if
+else if (get first item of found_ooos as string) is chooseMyOwn then
+ set the choice to (choose from list found_ooos default items (get first item of found_ooos) with prompt listPrompt OK button name listOKLabel cancel button name listCancelLabel)
+ if choice is false then
+ -- do nothing, the user cancelled the installation
+ return 2 --aborted by user
+ else if (choice as string) is chooseMyOwn then
+ -- yeah, one needs to use "choose file", otherwise
+ -- the user would not be able to select the .app
+ set the choice to POSIX path of (choose file with prompt chooseManual of type "com.apple.application-bundle" without showing package contents and invisibles)
+ end if
+else if (get second item of found_ooos as string) is chooseMyOwn then
+ -- set choice to found installation
+ -- set the choice to (get first paragraph of found_ooos)
+ set the choice to (get first item of found_ooos)
+else
+ set the choice to (choose from list found_ooos default items (get first item of found_ooos) with prompt listPrompt OK button name listOKLabel cancel button name listCancelLabel)
+ if choice is false then
+ -- do nothing, the user cancelled the installation
+ return 2 --aborted by user
+ else if (choice as string) is chooseMyOwn then
+ -- yeah, one needs to use "choose file", otherwise
+ -- the user would not be able to select the .app
+ set the choice to POSIX path of (choose file with prompt chooseManual of type "com.apple.application-bundle" without showing package contents and invisibles)
+ end if
+end if
+
+-- now only check whether the path is really from [PRODUCTNAME]
+-- FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=134607
+-- try
+-- do shell script "mdls --raw --name kMDItemDisplayName --name kMDItemVersion " & quoted form of (choice as string) & " | xargs -0 | fgrep '[PRODUCTNAME] [PRODUCTVERSION]'"
+-- on error
+-- display dialog (choice as string) & appInvalid buttons {InstallLabel} default button 1 with icon 0
+-- return 3 --wrong target-directory
+-- end try
+
+(*
+display dialog startInstall buttons {AbortLabel, InstallLabel} default button 2
+
+if (button returned of result) is AbortLabel then
+ return 2
+end if
+*)
+
+-- touch extensions folder to have LO register bundled dictionaries
+set tarCommand to "/usr/bin/tar -C " & quoted form of (choice as string) & " -xjf " & quoted form of sourcedir & "/tarball.tar.bz2 && touch " & quoted form of (choice as string) & "/Contents/Resources/extensions"
+try
+ (* A start of unchanged LO must take place so Gatekeeper will verify
+ the signature prior to installing the languagepack
+ *)
+ set apppath to POSIX path of choice
+ if application apppath is not running then
+ -- this will flash the startcenter once...
+ tell application apppath to activate
+ tell application apppath to quit
+ end if
+ do shell script tarCommand
+
+on error errMSG number errNUM
+ display dialog IdentifyQ buttons {IdentifyYES, IdentifyNO} with icon 2
+ if (button returned of result) is IdentifyYES then
+ try
+ do shell script tarCommand with administrator privileges
+ on error errMSG number errNUM
+ display dialog installFailed buttons {OKLabel} default button 1 with icon 0
+ -- -60005 username/password wrong
+ -- -128 aborted by user
+ -- 2 error from tar - tarball not found (easy to test)
+ return errNUM
+ end try
+ else
+ return 2 -- aborted by user
+ end if
+end try
+
+display dialog installComplete buttons {OKLabel} default button 1
diff --git a/setup_native/scripts/uninstall_linux.sh b/setup_native/scripts/uninstall_linux.sh
new file mode 100644
index 000000000..8ae8ae7ae
--- /dev/null
+++ b/setup_native/scripts/uninstall_linux.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Linux deinstallation
+# No parameter required, all RPMs listed in $HOME/.RPM_OFFICEDATABASE
+# will be removed.
+
+if [ $# -ne 1 ]
+then
+ echo
+ echo "Usage:" $0 "<office-installation-dir>"
+ echo " <inst-destination-dir>: directory where the office to be removed is installed"
+ echo
+ exit 2
+fi
+
+INSTALLDIR=$1
+
+# Check for old style .RPM_OFFICEDATABASE first
+if [ -d ${INSTALLDIR}/.RPM_OFFICEDATABASE ]; then
+ RPM_DB_PATH=${INSTALLDIR}/.RPM_OFFICEDATABASE
+else
+ RPM_DB_PATH=${INSTALLDIR}/.RPM_DATABASE
+fi
+
+# the RPM_DB_PATH must be absolute
+if [ ! "${RPM_DB_PATH:0:1}" = "/" ]; then
+ RPM_DB_PATH=`cd ${RPM_DB_PATH}; pwd`
+fi
+
+RPMLIST=`rpm --dbpath $RPM_DB_PATH --query --all`
+
+# Output ...
+clear
+echo "#########################################"
+echo "# Deinstallation of Office RPMs #"
+echo "#########################################"
+echo
+echo "Path to the RPM database: " $RPM_DB_PATH
+echo "RPMs to deinstall:"
+echo "$RPMLIST"
+echo "===================================================================="
+echo
+
+# Restore original bootstraprc
+mv -f $1/program/bootstraprc.orig $1/program/bootstraprc
+
+rpm --dbpath $RPM_DB_PATH --erase $RPMLIST || exit 2
+
+echo "Removing RPM database ..."
+rm -rf $RPM_DB_PATH
+
+echo
+echo "Deinstallation done."
+
+exit 0
diff --git a/setup_native/scripts/unpack_update.sh b/setup_native/scripts/unpack_update.sh
new file mode 100644
index 000000000..1af4865cd
--- /dev/null
+++ b/setup_native/scripts/unpack_update.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+EXTENSION=`expr "//$1" : '.*\/.*\.\(t.*\)'`
+[ -z $EXTENSION ] && ( echo "Unable to determine file type"; exit 2 )
+
+BASEDIR=`dirname "$1"`
+FOLDER=`basename "$1" ".$EXTENSION"`
+NUM=1
+
+DESTPATH="$BASEDIR/$FOLDER"
+
+while [ -d "$DESTPATH" ]; do
+ NUM=$(expr $NUM + 1)
+ DESTPATH="$BASEDIR/$FOLDER-$NUM"
+done
+
+mkdir "$DESTPATH"
+cd "$DESTPATH"
+
+if [ "$EXTENSION" = "tar.gz" -o "$EXTENSION" = "tgz" ]; then
+ if [ -x /usr/bin/gzcat ]; then
+ /usr/bin/gzcat "$1" | tar -xf -
+ else
+ tar -xzf "$1"
+ fi
+elif [ "$EXTENSION" = "tar.bz2" -o "$EXTENSION" = "tbz2" ]; then
+ /usr/bin/bzcat "$1" | tar -xf -
+else
+ echo "Unsupported type of archive"
+ exit 2
+fi
+
+UPDATE=$(eval ls ./*/update) && SUBFOLDER=$(dirname $UPDATE) && mv $SUBFOLDER/* . && rmdir $SUBFOLDER && echo "$DESTPATH/update"
diff --git a/setup_native/source/mac/Info.plist.langpack b/setup_native/source/mac/Info.plist.langpack
new file mode 100644
index 000000000..2847040e3
--- /dev/null
+++ b/setup_native/source/mac/Info.plist.langpack
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <!-- UTI declarations for macOS >= 10.4 -->
+ <key>UTExportedTypeDeclarations</key>
+
+ <key>UTImportedTypeDeclarations</key>
+
+ <key>CFBundleExecutable</key>
+ <string>[FULLAPPPRODUCTNAME]</string>
+ <key>CFBundleGetInfoString</key>
+ <string>[FULLAPPPRODUCTNAME]</string>
+ <key>CFBundleIconFile</key>
+ <string>ooo3_installer.icns</string>
+ <key>CFBundleShortVersionString</key>
+ <string>9</string>
+ <key>CFBundleIdentifier</key>
+ <string>[BUNDLEIDENTIFIER].langpack</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>[FULLAPPPRODUCTNAME]</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>OOo3</string>
+ <key>LSRequiresCarbon</key>
+ <string>1</string>
+ <key>NSPrincipalClass</key>
+ <string>VCL_NSApplication</string>
+</dict>
+</plist>
+
diff --git a/setup_native/source/mac/macinstall.ulf b/setup_native/source/mac/macinstall.ulf
new file mode 100644
index 000000000..d0a937278
--- /dev/null
+++ b/setup_native/source/mac/macinstall.ulf
@@ -0,0 +1,68 @@
+[OKLabel]
+en-US = "OK"
+
+[InstallLabel]
+en-US = "Install"
+
+[AbortLabel]
+en-US = "Abort"
+
+[IntroText1]
+en-US = "Welcome to the [FULLPRODUCTNAME] Installation Wizard"
+
+[IntroText2]
+en-US = "This installation will update your installed versions of [PRODUCTNAME]"
+
+[IntroText3]
+en-US = "This might take a moment."
+
+[ChooseMyOwnText]
+en-US = "Not listed (choose location in an extra step)"
+
+[ListPromptText]
+en-US = "Choose [PRODUCTNAME] [PRODUCTVERSION] installation for which you want to install the [FULLPRODUCTNAME]"
+
+[ChooseManualText]
+en-US = "Point the dialog to your [PRODUCTNAME] [PRODUCTVERSION] installation."
+
+[ListOKLabelText]
+en-US = "Install"
+
+[ListCancelLabel]
+en-US = "Abort"
+
+[AppInvalidText1]
+en-US = "This is not a valid [PRODUCTNAME] [PRODUCTVERSION] installation."
+
+[AppInvalidText2]
+en-US = "Run the installer again and choose a valid [PRODUCTNAME] [PRODUCTVERSION] installation"
+
+[StartInstallText1]
+en-US = "Click Install to start the installation"
+
+[StartInstallText2]
+en-US = "Installation might take a minute..."
+
+[IdentifyQText]
+en-US = "Installation failed; most likely your account does not have the necessary privileges."
+
+[IdentifyQText2]
+en-US = "Do you want to identify as administrator and try again?"
+
+[IdentifyYES]
+en-US = "Yes, identify"
+
+[IdentifyNO]
+en-US = "No, abort installation"
+
+[InstallFailedText]
+en-US = "Installation failed."
+
+[InstallCompleteText]
+en-US = "Installation of [PRODUCTNAME] language pack completed."
+
+[InstallCompleteText2]
+en-US = "Call '[PRODUCTNAME] - Preferences - Language Settings - Languages' to change the user interface language."
+
+[InstallCompleteTextPatch]
+en-US = "Installation of [FULLPRODUCTNAME] completed"
diff --git a/setup_native/source/mac/ooo3_installer.icns b/setup_native/source/mac/ooo3_installer.icns
new file mode 100644
index 000000000..45fca0fca
--- /dev/null
+++ b/setup_native/source/mac/ooo3_installer.icns
Binary files differ
diff --git a/setup_native/source/packinfo/DS_Store b/setup_native/source/packinfo/DS_Store
new file mode 100644
index 000000000..755f7f6a8
--- /dev/null
+++ b/setup_native/source/packinfo/DS_Store
Binary files differ
diff --git a/setup_native/source/packinfo/DS_Store_Dev b/setup_native/source/packinfo/DS_Store_Dev
new file mode 100644
index 000000000..5d914b18e
--- /dev/null
+++ b/setup_native/source/packinfo/DS_Store_Dev
Binary files differ
diff --git a/setup_native/source/packinfo/DS_Store_Langpack b/setup_native/source/packinfo/DS_Store_Langpack
new file mode 100644
index 000000000..3a8ad71a5
--- /dev/null
+++ b/setup_native/source/packinfo/DS_Store_Langpack
Binary files differ
diff --git a/setup_native/source/packinfo/finals_instsetoo.txt b/setup_native/source/packinfo/finals_instsetoo.txt
new file mode 100644
index 000000000..d5a68d369
--- /dev/null
+++ b/setup_native/source/packinfo/finals_instsetoo.txt
@@ -0,0 +1,32 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Comment line
+# Syntax:
+# Column 1: Product
+# Column 2: pro or nonpro
+# Column 3: languages, comma separated list
+# Column 4: path to msi database in installation set
+# Separator between columns is one or more than one tabulator
+
+# Examples:
+# OpenOffice pro en-US \\<server>\<path>\msi\OOO300_m6_native_packed-1_en-US.9352\openofficeorg30.msi
+# OpenOffice pro en-US,de,es \\<server>\<path>\msi\OOO300_m6_native_packed-1_en-US_de_es.9352\openofficeorg30.msi
+# OpenOffice pro de \\<server>\<path>\msi\OOO300_m6_native_packed-1_de.9352\openofficeorg30.msi
+# OpenOfficeLanguagePack pro es \\<server>\<path>\msi\OOO300_m6_native_packed-1_es.9352\openofficeorg30.msi
+# URE pro en-US \\<server>\<path>\msi\OOO300_m6_native_packed-1_en-US.9352\ure14.msi
diff --git a/setup_native/source/packinfo/libreoffice.pcp b/setup_native/source/packinfo/libreoffice.pcp
new file mode 100644
index 000000000..68c98c655
--- /dev/null
+++ b/setup_native/source/packinfo/libreoffice.pcp
Binary files differ
diff --git a/setup_native/source/packinfo/linuxcopyrightfile b/setup_native/source/packinfo/linuxcopyrightfile
new file mode 100644
index 000000000..6e2c0ef08
--- /dev/null
+++ b/setup_native/source/packinfo/linuxcopyrightfile
@@ -0,0 +1,2 @@
+Copyright 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+Use is subject to license terms.
diff --git a/setup_native/source/packinfo/openofficelanguagepack.pcp b/setup_native/source/packinfo/openofficelanguagepack.pcp
new file mode 100644
index 000000000..013a11ed0
--- /dev/null
+++ b/setup_native/source/packinfo/openofficelanguagepack.pcp
Binary files differ
diff --git a/setup_native/source/packinfo/osxdndinstall.png b/setup_native/source/packinfo/osxdndinstall.png
new file mode 100644
index 000000000..b31d1b52a
--- /dev/null
+++ b/setup_native/source/packinfo/osxdndinstall.png
Binary files differ
diff --git a/setup_native/source/packinfo/package.txt b/setup_native/source/packinfo/package.txt
new file mode 100644
index 000000000..4ec319646
--- /dev/null
+++ b/setup_native/source/packinfo/package.txt
@@ -0,0 +1 @@
+DO NOT DELETE THIS FILE \ No newline at end of file
diff --git a/setup_native/source/packinfo/package_names.txt b/setup_native/source/packinfo/package_names.txt
new file mode 100644
index 000000000..980dc602a
--- /dev/null
+++ b/setup_native/source/packinfo/package_names.txt
@@ -0,0 +1,65 @@
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING Language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-base Base language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-calc Calc language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-draw Draw language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-fonts Language fonts module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-help Language help module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-impress Impress language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-math Math language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-onlineupd Online update language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-res Language resource module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-writer Writer language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-activex ActiveX control for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-base Base module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-calc Calc module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core Core module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-dict-gl Gl dictionary for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-dict-vi Vietnamese dictionary for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-draw Draw module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-emailmerge Email mailmerge module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-gnome-integratn GNOME integration module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-graphicfilter Graphic filter module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-headless Headless display module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-images Images module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-impress Impress module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-kde-integration KDE integration module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-math Math module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-onlineupdate Online update module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-ooofonts 3rd party free fonts for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-ooolinguistic Linguistic module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-pyuno Pyuno module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-spellcheck English spellchecker module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-testtool Testtool module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-writer Writer module for %PRODUCTNAME %PRODUCTVERSION
+%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-xsltfilter XSLT filter samples module for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-af Af dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-cs Cs dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-da Da dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-de De dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-en En dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-es Es dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-et Et dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-fr Fr dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-hu Hu dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-hr Hr dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-it It dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-lt Lt dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-ne Ne dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-nl Nl dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-pl Pl dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-pt Pt dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-ru Ru dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sk Sk dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sl Sl dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sv Sv dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sw Sw dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-th Th dictionary for %PRODUCTNAME %PRODUCTVERSION
+%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-zu Zu dictionary for %PRODUCTNAME %PRODUCTVERSION
+%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION Brand module for %PRODUCTNAME %PRODUCTVERSION
+%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-%LANGUAGESTRING Brand language module for %PRODUCTNAME %PRODUCTVERSION
+%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-base Base brand module for %PRODUCTNAME %PRODUCTVERSION
+%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-calc Calc brand module for %PRODUCTNAME %PRODUCTVERSION
+%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-draw Draw brand module for %PRODUCTNAME %PRODUCTVERSION
+%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-impress Impress brand module for %PRODUCTNAME %PRODUCTVERSION
+%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-math Math brand module for %PRODUCTNAME %PRODUCTVERSION
+%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-writer Writer brand module for %PRODUCTNAME %PRODUCTVERSION
diff --git a/setup_native/source/packinfo/package_names_ext.txt b/setup_native/source/packinfo/package_names_ext.txt
new file mode 100644
index 000000000..ff0c10c05
--- /dev/null
+++ b/setup_native/source/packinfo/package_names_ext.txt
@@ -0,0 +1,21 @@
+%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure UNO Runtime Environment
+SUNWcar Core Architecture, (Root)
+SUNWcsd Core Solaris Devices
+SUNWcsl Core Solaris, (Shared Libs)
+SUNWcsr Core Solaris, (Root)
+SUNWcsu Core Solaris, (Usr)
+SUNWfreetype2 FreeType2 font library
+SUNWgnome-base-libs GNOME base GUI libraries - platform dependent files, /usr filesystem
+SUNWgnome-config GNOME configuration framework - platform dependent files, /usr filesystem
+SUNWgnome-vfs GNOME Virtual File System Framework and application/MIME type registry - platform dependent files, /usr filesystem
+SUNWgzip The GNU Zip (gzip) compression utility
+SUNWmfrun Motif RunTime Kit
+SUNWkvm Core Architecture, (Kvm)
+SUNWlibC Sun Workshop Compilers Bundled libC
+SUNWPython The Python interpreter, libraries and utilities
+SUNWxwplt X Window System platform software
+SUNWxwrtl X Window System & Graphics Runtime Library Links in /usr/lib
+SUNWzlibr The Zip compression library (Root)
+SUNWbtool CCS tools bundled with SunOS
+SUNWxcu4 XCU4 Utilities
+
diff --git a/setup_native/source/packinfo/packinfo_brand.txt b/setup_native/source/packinfo/packinfo_brand.txt
new file mode 100644
index 000000000..97b5d8cc4
--- /dev/null
+++ b/setup_native/source/packinfo/packinfo_brand.txt
@@ -0,0 +1,129 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+Start
+module = "gid_Module_Root_Brand"
+solarispackagename = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-images %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure (Name="UNO Runtime Environment"), %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION"), %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-images (Name="Images module for %PRODUCTNAME %PRODUCTVERSION")"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Brand module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Brand_Prg_Wrt"
+solarispackagename = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-writer"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-writer"
+requires = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-writer %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+solarisrequires = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION,%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-writer"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Writer brand module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Brand_Prg_Calc"
+solarispackagename = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-calc"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-calc"
+requires = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-calc %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+solarisrequires = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION,%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-calc"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Calc brand module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Brand_Prg_Impress"
+solarispackagename = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-impress"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-impress"
+requires = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-impress %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+solarisrequires = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION,%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-impress"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Impress brand module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Brand_Prg_Draw"
+solarispackagename = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-draw"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-draw"
+requires = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-draw %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+solarisrequires = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION,%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-draw"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Draw brand module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Brand_Prg_Math"
+solarispackagename = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-math"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-math"
+requires = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-math %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+solarisrequires = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION,%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-math"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Math brand module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Brand_Prg_Base"
+solarispackagename = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-base"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-base"
+requires = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-base %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+solarisrequires = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION,%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-base"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Base brand module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Langpack_Brand"
+solarispackagename = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION-%LANGUAGESTRING"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-%LANGUAGESTRING"
+requires = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+solarisrequires = "%WITHOUTDOTUNIXPACKAGENAME%BRANDPACKAGEVERSION,%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING (Name="Language module for %PRODUCTNAME %PRODUCTVERSION\, language %LANGUAGESTRING")"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Brand language module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
diff --git a/setup_native/source/packinfo/packinfo_extensions.txt b/setup_native/source/packinfo/packinfo_extensions.txt
new file mode 100644
index 000000000..4bd5b97c0
--- /dev/null
+++ b/setup_native/source/packinfo/packinfo_extensions.txt
@@ -0,0 +1,140 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Format:
+
+# Start
+# scpModule
+# shellscript file (optional)
+# solarispackagename
+# solarisrequires (optional)
+# solarisprovides (optional)
+# packagename
+# linuxreplaces (optional)
+# requires (optional)
+# provides (optional)
+# copyright
+# vendor
+# description
+# destpath
+# End
+
+Start
+module = "gid_Module_Optional_Extensions_MEDIAWIKI"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-extension-mediawiki-publisher"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-extension-mediawiki-publisher"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "MediaWiki publisher extension for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Extensions_NumberText"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-extension-numbertext"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-extension-numbertext"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2009 by FSF.hu"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Numbertext extension for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Extensions_CT2N"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-extension-ct2n"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-extension-ct2n"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "Copyright (c) 2008 Cor Nouws"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "ConvertTextToNumber extension for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Extensions_NLPSolver"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-extension-nlpsolver"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-extension-nlpsolver"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "NLPSolver extension for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Extensions_LanguageTool"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-extension-languagetool"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-extension-languagetool"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2005-2009 by Daniel Naber"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "LanguageTool extension for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Extensions_Script_Provider_For_BS"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-extension-beanshell-script-provider"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-extension-beanshell-script-provider"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Script provider for BeanShell extension for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Extensions_Script_Provider_For_JS"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-extension-javascript-script-provider"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-extension-javascript-script-provider"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Script provider for JavaScript extension for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
diff --git a/setup_native/source/packinfo/packinfo_office.txt b/setup_native/source/packinfo/packinfo_office.txt
new file mode 100644
index 000000000..f3efd5afa
--- /dev/null
+++ b/setup_native/source/packinfo/packinfo_office.txt
@@ -0,0 +1,1244 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Format:
+
+# Start
+# scpModule
+# shellscript file (optional)
+# solarispackagename
+# solarisreplaces (optional)
+# solarisincompat (optional)
+# solarisrequires (optional)
+# solarisprovides (optional)
+# freebsdrequires (optional)
+# freebsdprovides (optional)
+# packagename
+# linuxreplaces (optional)
+# linuxincompat (optional)
+# requires (optional)
+# provides (optional)
+# copyright
+# vendor
+# description
+# destpath
+# End
+
+Start
+module = "gid_Module_Optional_Gnome"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-gnome-integratn"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWgnome-config, SUNWgnome-vfs, SUNWlibC"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-gnome-integration"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+findrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "GNOME integration module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Tde"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-tde-integration"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-tde-integration"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "TDE integration module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Kde"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-kde-integration"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-kde-integration"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "KDE integration module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+linuxreplaces = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core01, %BASISPACKAGEPREFIX%PRODUCTVERSION-core02, %BASISPACKAGEPREFIX%PRODUCTVERSION-core03, %BASISPACKAGEPREFIX%PRODUCTVERSION-core04, %BASISPACKAGEPREFIX%PRODUCTVERSION-core05, %BASISPACKAGEPREFIX%PRODUCTVERSION-core06, %BASISPACKAGEPREFIX%PRODUCTVERSION-core07"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION, %BASISPACKAGEPREFIX%PRODUCTVERSION-ooofonts %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+solarisrequires = "SUNWcar, SUNWkvm, SUNWcsr, SUNWcsu, SUNWcsd, SUNWcsl,
+SUNWxwrtl, SUNWxwplt, SUNWlibC, %SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-ooofonts"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-ooofonts"
+findrequires = "find-requires-x11.sh"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Core module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Prg_Wrt_Bin"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-writer"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-writer"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWlibC"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Writer module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Prg_Calc_Bin"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-calc"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWlibC"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-calc"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Calc module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Prg_Draw_Bin"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-draw"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWlibC"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-draw"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Draw module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Prg_Impress_Bin"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-impress"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWlibC"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-impress"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Impress module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Prg_Base_Bin"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-base"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWlibC"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-base"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Base module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Prg_Math_Bin"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-math"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWlibC"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-math"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Math module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Firebird"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-Firebird"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-firebird"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Firebird module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Grfflt"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-graphicfilter"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-graphicfilter"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Graphic filter module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Xsltfiltersamples"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-xsltfilter"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-xsltfilter"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "XSLT filter samples module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Activexcontrol"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-activex"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-activex"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "ActiveX control for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Onlineupdate"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-onlineupdate"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWlibC, SUNWgzip"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-onlineupdate"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Online update module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Pyuno"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-pyuno"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWPython"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-pyuno"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Pyuno module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_Pyuno_LibreLogo"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-librelogo"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-pyuno,%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-writer,SUNWPython"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-librelogo"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-pyuno,%BASISPACKAGEPREFIX%PRODUCTVERSION-writer"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-pyuno %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-writer %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "LibreLogo toolbar for %PRODUCTNAME %PRODUCTVERSION Writer"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Script_Provider_For_Python"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-python-script-provider"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-python-script-provider"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Script provider for Python for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Files_Images"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-images"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-images"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Images module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Fonts_OOo_Hidden"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-ooofonts"
+solarisrequires = ""
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-ooofonts"
+freebsdrequires = ""
+requires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "3rd party free fonts for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Oo_Linguistic"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-ooolinguistic"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-ooolinguistic"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Linguistic module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Af"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-af"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-af"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Af dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_An"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-an"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-an"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2011 Santiago Paricio, Juan Pablo Martinez"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "An dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Ar"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-ar"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-ar"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2006-2008 by Mohamed Kebdani, 2006-2009 Taha Zerrouki"
+solariscopyright = "solariscopyrightfile"
+vendor = "Ayaspell"
+description = "Ar dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Be"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-be"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-be"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "Copyright (C) 2005 Mikalai Udodau"
+solariscopyright = "solariscopyrightfile"
+vendor = "Mikalai Udodau"
+description = "Be dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Bg"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-bg"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-bg"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "Copyright (C) 2001 Anton Zinoviev, Borislav Mitev, Radostin Radnev"
+solariscopyright = "solariscopyrightfile"
+vendor = "Radostin Radnev"
+description = "Bg dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Bn"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-bn"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-bn"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2002 Dr Abhijit Das, 2002 Taneem Ahmed, 2008 Jamil Ahmed"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Bn dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Bo"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-bo"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-bo"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2016 Elie Roux"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Bo dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Br"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-br"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-br"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2009-2011 by An Drouizig"
+solariscopyright = "solariscopyrightfile"
+vendor = "An Drouizig"
+description = "Br dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Bs"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-bs"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-bs"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2013 by Vedran Ljubović"
+solariscopyright = "solariscopyrightfile"
+vendor = "Vedran Ljubović"
+description = "Bs dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Ca"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-ca"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-ca"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Ca dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Cs"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-cs"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-cs"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Cs dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Da"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-da"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-da"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Da dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_De"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-de"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-de"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "De dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_En"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-en"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-en"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "En dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_El"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-el"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-el"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2002 by Evripidis Papakostas, 2006 by Steve Stavropoulos"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "El dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Es"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-es"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-es"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Es dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Et"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-et"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-et"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Et dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Fr"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-fr"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-fr"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Fr dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Gd"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-gd"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-gd"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2010 by Am Faclair Beag"
+solariscopyright = "solariscopyrightfile"
+vendor = "Kevin Scannel"
+description = "Gd dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Gl"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-gl"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-gl"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Gl dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Gu"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-gu"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-gu"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2009 by Kartik Mistry"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Gu dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_He"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-he"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-he"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "He dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Hi"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-hi"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-hi"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2005 Swapnil {Hajare, Sant}"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Hi dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Hu"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-hu"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-hu"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Hu dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Hr"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-hr"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-hr"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2003-2010 by Denis Lackovic"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Hr dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Id"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-id"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-id"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Indonesian dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Is"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-is"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-is"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The hunspell-is project"
+description = "Is dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_It"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-it"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-it"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "It dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Kmr_Latn"
+solarispackagename = "%PACKAGEPREFIX%WITHOUTDOTUNIXPRODUCTNAME%BRANDPACKAGEVERSION-dict-kmr-Latn"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%WITHOUTDOTUNIXPRODUCTNAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPRODUCTNAME%BRANDPACKAGEVERSION-dict-kmr-Latn"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPRODUCTNAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Kmr-Latn dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Lo"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-lo"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-lo"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2013 by Brian Eugene Wilson, Robert Martin Campbell"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Lo dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Lt"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-lt"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-lt"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Lt dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Lv"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-lv"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-lv"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2004-2005 Janis Vilims, 2002-2010 Janis Eisaks"
+solariscopyright = "solariscopyrightfile"
+vendor = "Dicollecte-LV"
+description = "Lv dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Ne"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-ne"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-ne"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Ne dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Nl"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-nl"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-nl"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Nl dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_No"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-no"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-no"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "No dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Oc"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-oc"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-oc"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2006-2011 by Bruno Gallart"
+solariscopyright = "solariscopyrightfile"
+vendor = "OpenOc.org"
+description = "Occitan-languedocian dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Pl"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-pl"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-pl"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Pl dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Pt_Br"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-pt-BR"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-pt-BR"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Pt-BR dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Pt_Pt"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-pt-PT"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-pt-PT"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Pt-PT dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Ro"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-ro"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-ro"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Ro dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Ru"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-ru"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-ru"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Ru dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Si"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-si"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-si"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2010 by Laknath Semage"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Si dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Sk"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sk"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-sk"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Sk dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Sl"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sl"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-sl"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Sl dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Sq"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sq"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-sq"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2011 by Luan Kelmendi"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Sq dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Sr"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sr"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-sr"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Sr dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Sv"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sv"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-sv"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Sv dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Sw"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-sw"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-sw"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Sw dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Te"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-te"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-te"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2005 by IndLinux, Khadir, 2010 by Arjuna Rao Chavala, 2009 by Santhosh Thottingal"
+solariscopyright = "solariscopyrightfile"
+vendor = "Arjuna Rao Chavala"
+description = "Te dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Th"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-th"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-th"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Th dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Tr"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-tr"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-tr"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2014-2018 by Harun Resit Zafer, Muhammet Kara"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Tr dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Uk"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-uk"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-uk"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "1999-2009 by Vladimir Yakovchuk, Oleg Podgurniy, Dmytro Kovalyov, Maksym Polyakov, Andriy Rysin, Valentyn Solomko, Volodymyr M. Lisivka, Eugeniy Meshcheryakov"
+solariscopyright = "solariscopyrightfile"
+vendor = "Document Foundation"
+description = "Ukrainian dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Vi"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-vi"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-vi"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Vietnamese dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Extension_Dictionary_Zu"
+solarispackagename = "%PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION-dict-zu"
+solarisrequires = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure, %BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, %PACKAGEPREFIX%SOLARISBRANDPACKAGENAME%BRANDPACKAGEVERSION"
+packagename = "%UNIXPACKAGENAME%BRANDPACKAGEVERSION-dict-zu"
+requires = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION,%UNIXPACKAGENAME%BRANDPACKAGEVERSION %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Zu dictionary for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+
+Start
+module = "gid_Module_Optional_OGLTrans"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-ogltrans"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-impress"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-ogltrans"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-impress"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-impress %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "OpenGL slide transitions module for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Optional_PostgresqlSdbc"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-postgresql-sdbc"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-base"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-postgresql-sdbc"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-base"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-base %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "PostgreSQL Connector driver for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Pdfimport"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-extension-pdf-import"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-extension-pdf-import"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "PDF import extension for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Reportbuilder"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-extension-report-builder"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-extension-report-builder"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Report Builder extension for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Libreofficekit"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-libreofficekit-data"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core (Name="Core module for %PRODUCTNAME %PRODUCTVERSION")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-libreofficekit-data"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+linuxpatchrequires = ""
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Libreofficekit data files for %PRODUCTNAME %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
diff --git a/setup_native/source/packinfo/packinfo_office_help.txt b/setup_native/source/packinfo/packinfo_office_help.txt
new file mode 100644
index 000000000..12acde8a4
--- /dev/null
+++ b/setup_native/source/packinfo/packinfo_office_help.txt
@@ -0,0 +1,54 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Format:
+
+# Start
+# scpModule
+# shellscript file (optional)
+# solarispackagename
+# solarisrequires (optional)
+# solarisprovides (optional)
+# packagename
+# linuxreplaces (optional)
+# requires (optional)
+# provides (optional)
+# copyright
+# vendor
+# description
+# destpath
+# End
+
+Start
+module = "gid_Module_Helppack_Help"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-help"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-help"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-help"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Help module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+End
+
+
+# END OF Language depended package definitions
diff --git a/setup_native/source/packinfo/packinfo_office_lang.txt b/setup_native/source/packinfo/packinfo_office_lang.txt
new file mode 100644
index 000000000..a23e4695e
--- /dev/null
+++ b/setup_native/source/packinfo/packinfo_office_lang.txt
@@ -0,0 +1,196 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# Format:
+
+# Start
+# scpModule
+# shellscript file (optional)
+# solarispackagename
+# solarisrequires (optional)
+# solarisprovides (optional)
+# packagename
+# linuxreplaces (optional)
+# requires (optional)
+# provides (optional)
+# copyright
+# vendor
+# description
+# destpath
+# End
+
+Start
+module = "gid_Module_Langpack_Basis"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+End
+
+Start
+module = "gid_Module_Langpack_Fonts"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-fonts"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-fonts"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-fonts"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Language fonts module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+End
+
+Start
+module = "gid_Module_Langpack_Resource"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-res"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-res"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-res"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Language resource module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core"
+End
+
+Start
+module = "gid_Module_Langpack_Writer"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-writer"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-writer"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-writer"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Writer language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-writer"
+End
+
+Start
+module = "gid_Module_Langpack_Calc"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-calc"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-calc"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-calc"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Calc language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-calc"
+End
+
+Start
+module = "gid_Module_Langpack_Impress"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-impress"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-impress"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-impress"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Impress language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-impress"
+End
+
+Start
+module = "gid_Module_Langpack_Draw"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-draw"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-draw"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-draw"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Draw language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-draw"
+End
+
+Start
+module = "gid_Module_Langpack_Math"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-math"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-math"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-math"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Math language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-math"
+End
+
+Start
+module = "gid_Module_Langpack_Base"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-base"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-base"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-base"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Base language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-base"
+End
+
+Start
+module = "gid_Module_Langpack_Onlineupdate"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING-onlineupd"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-%LANGUAGESTRING"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-onlineupd"
+provides = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING-onlineupd"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-%LANGUAGESTRING %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Online update language module for %PRODUCTNAME %PRODUCTVERSION, language %LANGUAGESTRING"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+pkg_list_entry = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-onlineupdate"
+End
+
diff --git a/setup_native/source/packinfo/packinfo_sdkoo.txt b/setup_native/source/packinfo/packinfo_sdkoo.txt
new file mode 100644
index 000000000..4d148fb11
--- /dev/null
+++ b/setup_native/source/packinfo/packinfo_sdkoo.txt
@@ -0,0 +1,32 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+Start
+module = "gid_Module_Root_SDK"
+solarispackagename = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-sdk"
+solarisrequires = "%BASISPACKAGEPREFIX%WITHOUTDOTPRODUCTVERSION-core, SUNWbtool (Name="CCS tools bundled with SunOS"), SUNWxcu4 (Name="XCU4 Utilities")"
+packagename = "%BASISPACKAGEPREFIX%PRODUCTVERSION-sdk"
+freebsdrequires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core"
+requires = "%BASISPACKAGEPREFIX%PRODUCTVERSION-core %PACKAGEVERSION %PACKAGEVERSION-%PACKAGEREVISION"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "Software Development Kit for LibreOffice %PRODUCTVERSION"
+destpath = "/opt"
+packageversion = "%PACKAGEVERSION"
+End
diff --git a/setup_native/source/packinfo/packinfo_ure.txt b/setup_native/source/packinfo/packinfo_ure.txt
new file mode 100644
index 000000000..66e8c66f3
--- /dev/null
+++ b/setup_native/source/packinfo/packinfo_ure.txt
@@ -0,0 +1,49 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+Start
+module = "gid_Module_Root"
+solarispackagename = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure"
+solarisrequires = "SUNWzlibr"
+solarisprovides = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-stdlibs"
+linuxreplaces = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-stdlibs"
+linuxincompat = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-stdlibs"
+packagename = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "UNO Runtime Environment"
+destpath = "/opt"
+packageversion = "%UREPACKAGEVERSION"
+End
+
+Start
+module = "gid_Module_Root_Ure_Hidden"
+solarispackagename = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure"
+solarisrequires = "SUNWzlibr"
+solarisprovides = "%SOLSUREPACKAGEPREFIX%BRANDPACKAGEVERSION-stdlibs"
+linuxreplaces = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-stdlibs"
+linuxincompat = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-stdlibs"
+packagename = "%UREPACKAGEPREFIX%BRANDPACKAGEVERSION-ure"
+copyright = "2020 The Document Foundation"
+solariscopyright = "solariscopyrightfile"
+vendor = "The Document Foundation"
+description = "UNO Runtime Environment"
+destpath = "/opt"
+packageversion = "%UREPACKAGEVERSION"
+End
diff --git a/setup_native/source/packinfo/private1copyrightfile b/setup_native/source/packinfo/private1copyrightfile
new file mode 100644
index 000000000..bc2059a3e
--- /dev/null
+++ b/setup_native/source/packinfo/private1copyrightfile
@@ -0,0 +1,2 @@
+Copyright 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+Use is subject to license terms.
diff --git a/setup_native/source/packinfo/solariscopyrightfile b/setup_native/source/packinfo/solariscopyrightfile
new file mode 100644
index 000000000..6e2c0ef08
--- /dev/null
+++ b/setup_native/source/packinfo/solariscopyrightfile
@@ -0,0 +1,2 @@
+Copyright 2000, 2010 Oracle and/or its affiliates. All rights reserved.
+Use is subject to license terms.
diff --git a/setup_native/source/packinfo/spellchecker_selection.pl b/setup_native/source/packinfo/spellchecker_selection.pl
new file mode 100644
index 000000000..317501397
--- /dev/null
+++ b/setup_native/source/packinfo/spellchecker_selection.pl
@@ -0,0 +1,74 @@
+#
+# 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/.
+#
+
+use List::Util qw[max];
+
+@ARGV == 0 or die 'Usage: translates from stdin to stdout';
+
+my %map = ();
+my $max = 0;
+
+while (<>) {
+ next if /^\s*(#.*)?$/;
+ # Accept combinations of lll-Ssss-CC-vvvvvvvv
+ # XXX NOTE: when changing this also adapt
+ # setup_native/source/win32/customactions/sellang/sellang.cxx
+ # struct InstallLocalized{ char lang[sizeof(...)]; }
+ /^ \s* ([a-z]{2,3}(?:-[A-Z][a-z]{3})?(?:-[A-Z]{2})?(?:-[a-z]{5,8})?) \s* = \s*
+ \"(EMPTY|[a-z]{2,3}(?:-[A-Z][a-z]{3})?(?:-[A-Z]{2})?(?:-[a-z]{5,8})?
+ (?:,[a-z]{2,3}(?:-[A-Z][a-z]{3})?(?:-[A-Z]{2})?(?:-[a-z]{5,8})?)*)\" \s* $/x
+ or die "unexpected input line \"$_\"";
+ my $lang = $1;
+ $lang =~ tr/-/_/;
+ my $dicts = $2;
+ $dicts =~ tr/-/_/;
+ !exists($map{$lang}) or die "duplicate values for $lang";
+ if ($dicts eq 'EMPTY') {
+ @{$map{$lang}} = ();
+ } else {
+ @{$map{$lang}} = split(/,/, $dicts);
+ }
+ push(@{$map{$lang}}, ('en')) unless grep($_ eq 'en', @{$map{$lang}});
+ $max = max($max, scalar(@{$map{$lang}}));
+}
+
+++$max;
+
+print <<EOF;
+// generated by setup_native/source/packinfo/spellchecker_selection.pl
+
+#ifndef INCLUDED_SETUP_NATIVE_SOURCE_PACKINFO_SPELLCHECKER_SELECTION_HXX
+#define INCLUDED_SETUP_NATIVE_SOURCE_PACKINFO_SPELLCHECKER_SELECTION_HXX
+
+#include "sal/config.h"
+
+namespace setup_native {
+
+struct LanguageDictionaries {
+ char const * language;
+ char const * dictionaries[$max];
+};
+
+LanguageDictionaries const languageDictionaries[] = {
+EOF
+
+foreach $i (sort(keys(%map))) {
+ print(" { \"$i\", {");
+ foreach $j (sort(@{$map{$i}})) {
+ print(" \"$j\",");
+ }
+ print(" 0 } },\n");
+}
+
+print <<EOF;
+};
+
+}
+
+#endif
+EOF
diff --git a/setup_native/source/packinfo/spellchecker_selection.txt b/setup_native/source/packinfo/spellchecker_selection.txt
new file mode 100644
index 000000000..89dd8978e
--- /dev/null
+++ b/setup_native/source/packinfo/spellchecker_selection.txt
@@ -0,0 +1,92 @@
+#
+# 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/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+# This file defines the languages of the spellchecker, that are
+# included into the language specific installation sets.
+# First column: Language in the installation set.
+# Second column: Assigned spellchecker languages. Comma separated list.
+
+# The first entry after the "=" is the entry, that will be included into
+# a language pack of the corresponding language. If no spellchecker
+# shall be included into the language pack, the keyword "EMPTY" can
+# be used as first entry.
+
+af = "af"
+ar = "ar"
+be = "be"
+bg = "bg"
+bn = "bn"
+bo = "bo"
+br = "br,fr"
+bs = "bs"
+ca = "ca,an,es,fr,it,oc"
+ca-valencia = "ca,an,es,fr,it,oc"
+cs = "cs"
+da = "da,de"
+de = "de,fr,it"
+el = "el"
+en-US = "en,es,fr"
+en-GB = "en,es,fr"
+en-ZA = "en,es,fr"
+es = "es,an,ca,fr,gl,oc,pt-PT"
+et = "et"
+fr = "fr,es"
+gd = "gd"
+gl = "gl,pt-PT,es"
+gu = "gu"
+he = "he"
+hi = "hi"
+hu = "hu,de"
+hr = "hr,de"
+id = "id"
+is = "is"
+it = "it,de,fr"
+ja = "EMPTY"
+kmr-Latn = "kmr-Latn-TR"
+ko = "EMPTY"
+lo = "lo"
+lt = "lt,de,pl,ru"
+lv = "lv"
+nb = "no,fr,de,es"
+ne = "ne"
+nl = "nl,fr,de"
+nn = "no,fr,de,es"
+oc = "oc,fr"
+pl = "pl,de,ru"
+pt-BR = "pt-BR,es"
+pt = "pt-PT,es"
+ro = "ro,de,hu"
+ru = "ru,de,uk"
+si = "si"
+sk = "sk"
+sl = "sl"
+sq = "sq"
+sv = "sv,de"
+sr = "sr"
+# ! Note the package 'sr' also holds the dictionaries for 'sr-Latn' (formerly 'sh') !
+sr-Latn = "sr"
+sw = "sw"
+te = "te"
+th = "th"
+tr = "tr"
+uk = "uk,ru"
+vi = "vi,fr"
+zh-TW = "EMPTY"
+zh-CN = "EMPTY"
+zu = "zu"
+
diff --git a/setup_native/source/packinfo/ure.pcp b/setup_native/source/packinfo/ure.pcp
new file mode 100644
index 000000000..982656647
--- /dev/null
+++ b/setup_native/source/packinfo/ure.pcp
Binary files differ
diff --git a/setup_native/source/win32/customactions/indexingfilter/instooofiltmsi.def b/setup_native/source/win32/customactions/indexingfilter/instooofiltmsi.def
new file mode 100644
index 000000000..0126556a4
--- /dev/null
+++ b/setup_native/source/win32/customactions/indexingfilter/instooofiltmsi.def
@@ -0,0 +1,3 @@
+LIBRARY "instooofiltmsi.dll"
+EXPORTS
+ RestartIndexingService \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx b/setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx
new file mode 100644
index 000000000..e1c26501b
--- /dev/null
+++ b/setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx
@@ -0,0 +1,157 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/*
+ After installation of the OOo filter for the indexing service
+ it is necessary to restart the indexing service in order to
+ activate the filter. This is the most reliable way to get the
+ indexing service working. We only restart the service if it is
+ already running. If we have insufficient privileges to restart
+ the service we do nothing.
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+
+const wchar_t * const INDEXING_SERVICE_NAME = L"cisvc";
+
+static bool StopIndexingService(SC_HANDLE hService)
+{
+ SERVICE_STATUS status;
+
+ if (ControlService(hService, SERVICE_CONTROL_STOP, &status))
+ {
+ // Check the status until the service is no longer stop pending.
+ if (QueryServiceStatus(hService, &status))
+ {
+ DWORD startTime = GetTickCount();
+ DWORD oldCheckPoint = status.dwCheckPoint;
+
+ while (status.dwCurrentState == SERVICE_STOP_PENDING)
+ {
+ // Do not wait longer than the wait hint. A good interval is
+ // one tenth the wait hint, but no less than 1 second and no
+ // more than 10 seconds.
+ DWORD waitTime = status.dwWaitHint / 10;
+
+ if (waitTime < 1000)
+ waitTime = 1000;
+ else if (waitTime > 10000)
+ waitTime = 10000;
+
+ Sleep(waitTime);
+
+ // Check the status again.
+ if (!QueryServiceStatus(hService, &status) ||
+ (status.dwCurrentState == SERVICE_STOPPED))
+ break;
+
+ if (status.dwCheckPoint > oldCheckPoint)
+ {
+ startTime = GetTickCount();
+ oldCheckPoint = status.dwCheckPoint;
+ }
+ else if ((GetTickCount() - startTime) > status.dwWaitHint)
+ {
+ break; // service doesn't react anymore
+ }
+ }
+ }
+ }
+ return (status.dwCurrentState == SERVICE_STOPPED);
+}
+
+static void StartIndexingService(SC_HANDLE hService)
+{
+ if (StartServiceW(hService, 0, nullptr))
+ {
+ SERVICE_STATUS status;
+
+ // Check the status until the service is no longer stop pending.
+ if (QueryServiceStatus(hService, &status))
+ {
+ DWORD startTime = GetTickCount();
+ DWORD oldCheckPoint = status.dwCheckPoint;
+
+ while (status.dwCurrentState == SERVICE_START_PENDING)
+ {
+ // Do not wait longer than the wait hint. A good interval is
+ // one tenth the wait hint, but no less than 1 second and no
+ // more than 10 seconds.
+ DWORD waitTime = status.dwWaitHint / 10;
+
+ if (waitTime < 1000)
+ waitTime = 1000;
+ else if (waitTime > 10000)
+ waitTime = 10000;
+
+ Sleep(waitTime);
+
+ // Check the status again.
+ if (!QueryServiceStatus(hService, &status) ||
+ (status.dwCurrentState == SERVICE_STOPPED))
+ break;
+
+ if (status.dwCheckPoint > oldCheckPoint)
+ {
+ startTime = GetTickCount();
+ oldCheckPoint = status.dwCheckPoint;
+ }
+ else if ((GetTickCount() - startTime) > status.dwWaitHint)
+ {
+ // service doesn't react anymore
+ break;
+ }
+ }
+ }
+ }
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall RestartIndexingService(MSIHANDLE)
+{
+ SC_HANDLE hSCManager = OpenSCManagerW(
+ nullptr, // local machine
+ nullptr, // ServicesActive database
+ SC_MANAGER_ALL_ACCESS);
+
+ if (hSCManager != nullptr)
+ {
+ SC_HANDLE hIndexingService = OpenServiceW(
+ hSCManager, INDEXING_SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP);
+
+ if (hIndexingService)
+ {
+ SERVICE_STATUS status;
+ ZeroMemory(&status, sizeof(status));
+
+ if (QueryServiceStatus(hIndexingService, &status) &&
+ (status.dwCurrentState == SERVICE_RUNNING))
+ {
+ if (StopIndexingService(hIndexingService))
+ StartIndexingService(hIndexingService);
+ }
+ CloseServiceHandle(hIndexingService);
+ }
+ CloseServiceHandle(hSCManager);
+ }
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/inst_msu/inst_msu.cxx b/setup_native/source/win32/customactions/inst_msu/inst_msu.cxx
new file mode 100644
index 000000000..26f7668ff
--- /dev/null
+++ b/setup_native/source/win32/customactions/inst_msu/inst_msu.cxx
@@ -0,0 +1,674 @@
+/* -*- 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 <memory>
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <Shlobj.h>
+#include <Wuerror.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...);
+}
+
+// Show a warning message box. This will be automatically suppressed in unattended installation.
+void ShowWarning(MSIHANDLE hInst, const std::wstring& sKBNo, const char* sMessage)
+{
+ // Error table's message #25000: "Installing a pre-requisite [2] failed.
+ // You might need to manually install it from Microsoft site to be able to run the product.[3]"
+ PMSIHANDLE hRec = MsiCreateRecord(3);
+ // To show a message from Error table, record's Field 0 must be null
+ MsiRecordSetInteger(hRec, 1, 25000);
+ MsiRecordSetStringW(hRec, 2, sKBNo.c_str());
+ std::string s("\n");
+ s += sMessage;
+ MsiRecordSetStringA(hRec, 3, s.c_str());
+ MsiProcessMessage(hInst, INSTALLMESSAGE_WARNING, hRec);
+}
+
+// Set custom action description visible in progress dialog
+void SetStatusText(MSIHANDLE hInst, const std::wstring& actName, const std::wstring& actDesc)
+{
+ PMSIHANDLE hRec = MsiCreateRecord(3);
+ // For INSTALLMESSAGE_ACTIONSTART, record's Field 0 must be null
+ // Field 1: Action name - must be non-null
+ MsiRecordSetStringW(hRec, 1, actName.c_str());
+ // Field 2: Action description - displayed in dialog
+ MsiRecordSetStringW(hRec, 2, actDesc.c_str());
+ // Let Field 3 stay null - no action template
+ MsiProcessMessage(hInst, INSTALLMESSAGE_ACTIONSTART, hRec);
+}
+
+typedef std::unique_ptr<void, decltype(&CloseHandle)> CloseHandleGuard;
+CloseHandleGuard Guard(HANDLE h) { return CloseHandleGuard(h, CloseHandle); }
+
+typedef std::unique_ptr<const wchar_t, decltype(&DeleteFileW)> DeleteFileGuard;
+DeleteFileGuard Guard(const wchar_t* sFileName) { return DeleteFileGuard(sFileName, DeleteFileW); }
+
+typedef std::unique_ptr<SC_HANDLE__, decltype(&CloseServiceHandle)> CloseServiceHandleGuard;
+CloseServiceHandleGuard Guard(SC_HANDLE h)
+{
+ return CloseServiceHandleGuard(h, CloseServiceHandle);
+}
+
+std::wstring GetTempFile()
+{
+ wchar_t sPath[MAX_PATH + 1];
+ DWORD nResult = GetTempPathW(sizeof(sPath) / sizeof(*sPath), sPath);
+ if (!nResult)
+ ThrowLastError("GetTempPathW");
+
+ wchar_t sFile[MAX_PATH + 1];
+ nResult = GetTempFileNameW(sPath, L"TMP", 0, sFile);
+ if (!nResult)
+ ThrowLastError("GetTempFileNameW");
+ return sFile;
+}
+
+bool IsWow64Process()
+{
+#if !defined _WIN64
+ BOOL bResult = FALSE;
+ typedef BOOL(WINAPI * LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
+ LPFN_ISWOW64PROCESS fnIsWow64Process = reinterpret_cast<LPFN_ISWOW64PROCESS>(
+ GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process"));
+
+ if (fnIsWow64Process)
+ {
+ if (!fnIsWow64Process(GetCurrentProcess(), &bResult))
+ ThrowLastError("IsWow64Process");
+ }
+
+ return bResult;
+#else
+ return false;
+#endif
+}
+
+// This class uses MsiProcessMessage to check for user input: it returns IDCANCEL when user cancels
+// installation. It throws a special exception, to be intercepted in main action function to return
+// corresponding exit code.
+class UserInputChecker
+{
+public:
+ class eUserCancelled
+ {
+ };
+
+ UserInputChecker(MSIHANDLE hInstall)
+ : m_hInstall(hInstall)
+ , m_hProgressRec(MsiCreateRecord(3))
+ {
+ // Use explicit progress messages
+ MsiRecordSetInteger(m_hProgressRec, 1, 1);
+ MsiRecordSetInteger(m_hProgressRec, 2, 1);
+ MsiRecordSetInteger(m_hProgressRec, 3, 0);
+ int nResult = MsiProcessMessage(m_hInstall, INSTALLMESSAGE_PROGRESS, m_hProgressRec);
+ if (nResult == IDCANCEL)
+ throw eUserCancelled();
+ // Prepare the record to following progress update calls
+ MsiRecordSetInteger(m_hProgressRec, 1, 2);
+ MsiRecordSetInteger(m_hProgressRec, 2, 0); // step by 0 - don't move progress
+ MsiRecordSetInteger(m_hProgressRec, 3, 0);
+ }
+
+ void ThrowIfUserCancelled()
+ {
+ // Check if user has cancelled
+ int nResult = MsiProcessMessage(m_hInstall, INSTALLMESSAGE_PROGRESS, m_hProgressRec);
+ if (nResult == IDCANCEL)
+ throw eUserCancelled();
+ }
+
+private:
+ MSIHANDLE m_hInstall;
+ PMSIHANDLE m_hProgressRec;
+};
+
+// Checks if Windows Update service is disabled, and if it is, enables it temporarily.
+// Also stops the service if it's currently running, because it seems that wusa.exe
+// does not freeze when it starts the service itself.
+class WUServiceEnabler
+{
+public:
+ WUServiceEnabler(MSIHANDLE hInstall)
+ : mhInstall(hInstall)
+ , mhService(EnableWUService(hInstall))
+ {
+ }
+
+ ~WUServiceEnabler()
+ {
+ try
+ {
+ if (mhService)
+ {
+ EnsureServiceEnabled(mhInstall, mhService.get(), false);
+ StopService(mhInstall, mhService.get(), false);
+ }
+ }
+ catch (std::exception& e)
+ {
+ WriteLog(mhInstall, e.what());
+ }
+ }
+
+private:
+ static CloseServiceHandleGuard EnableWUService(MSIHANDLE hInstall)
+ {
+ auto hSCM = Guard(OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS));
+ if (!hSCM)
+ ThrowLastError("OpenSCManagerW");
+ WriteLog(hInstall, "Opened service control manager");
+
+ auto hService = Guard(OpenServiceW(hSCM.get(), L"wuauserv",
+ SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG
+ | SERVICE_QUERY_STATUS | SERVICE_STOP));
+ if (!hService)
+ ThrowLastError("OpenServiceW");
+ WriteLog(hInstall, "Obtained WU service handle");
+
+ const DWORD nCurrentStatus = ServiceStatus(hInstall, hService.get());
+ // Stop currently running service to prevent wusa.exe from hanging trying to detect if the
+ // update is applicable (sometimes this freezes it ~indefinitely; it seems that it doesn't
+ // happen if wusa.exe starts the service itself: https://superuser.com/questions/1044528/).
+ // tdf#124794: Wait for service to stop.
+ if (nCurrentStatus == SERVICE_RUNNING)
+ StopService(hInstall, hService.get(), true);
+
+ if (nCurrentStatus == SERVICE_RUNNING
+ || !EnsureServiceEnabled(hInstall, hService.get(), true))
+ {
+ // No need to restore anything back, since we didn't change config
+ hService.reset();
+ WriteLog(hInstall, "Service configuration is unchanged");
+ }
+
+ return hService;
+ }
+
+ // Returns if the service configuration was actually changed
+ static bool EnsureServiceEnabled(MSIHANDLE hInstall, SC_HANDLE hService, bool bEnabled)
+ {
+ bool bConfigChanged = false;
+
+ DWORD nCbRequired = 0;
+ if (!QueryServiceConfigW(hService, nullptr, 0, &nCbRequired))
+ {
+ if (DWORD nError = GetLastError(); nError != ERROR_INSUFFICIENT_BUFFER)
+ ThrowWin32Error("QueryServiceConfigW", nError);
+ }
+ std::unique_ptr<char[]> pBuf(new char[nCbRequired]);
+ LPQUERY_SERVICE_CONFIGW pConfig = reinterpret_cast<LPQUERY_SERVICE_CONFIGW>(pBuf.get());
+ if (!QueryServiceConfigW(hService, pConfig, nCbRequired, &nCbRequired))
+ ThrowLastError("QueryServiceConfigW");
+ WriteLog(hInstall, "Obtained service config");
+
+ DWORD eNewStartType = 0;
+ if (bEnabled && pConfig->dwStartType == SERVICE_DISABLED)
+ {
+ bConfigChanged = true;
+ eNewStartType = SERVICE_DEMAND_START;
+ WriteLog(hInstall, "Service is disabled, and requested to enable");
+ }
+ else if (!bEnabled && pConfig->dwStartType != SERVICE_DISABLED)
+ {
+ bConfigChanged = true;
+ eNewStartType = SERVICE_DISABLED;
+ WriteLog(hInstall, "Service is enabled, and requested to disable");
+ }
+
+ if (bConfigChanged)
+ {
+ if (!ChangeServiceConfigW(hService, SERVICE_NO_CHANGE, eNewStartType, SERVICE_NO_CHANGE,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr))
+ ThrowLastError("ChangeServiceConfigW");
+ WriteLog(hInstall, "WU service config successfully changed");
+ }
+ else
+ WriteLog(hInstall, "No need to modify service config");
+
+ return bConfigChanged;
+ }
+
+ static DWORD ServiceStatus(MSIHANDLE hInstall, SC_HANDLE hService)
+ {
+ SERVICE_STATUS aServiceStatus{};
+ if (!QueryServiceStatus(hService, &aServiceStatus))
+ ThrowLastError("QueryServiceStatus");
+
+ std::string sStatus;
+ switch (aServiceStatus.dwCurrentState)
+ {
+ case SERVICE_STOPPED:
+ sStatus = "SERVICE_STOPPED";
+ break;
+ case SERVICE_START_PENDING:
+ sStatus = "SERVICE_START_PENDING";
+ break;
+ case SERVICE_STOP_PENDING:
+ sStatus = "SERVICE_STOP_PENDING";
+ break;
+ case SERVICE_RUNNING:
+ sStatus = "SERVICE_RUNNING";
+ break;
+ case SERVICE_CONTINUE_PENDING:
+ sStatus = "SERVICE_CONTINUE_PENDING";
+ break;
+ case SERVICE_PAUSE_PENDING:
+ sStatus = "SERVICE_PAUSE_PENDING";
+ break;
+ case SERVICE_PAUSED:
+ sStatus = "SERVICE_PAUSED";
+ break;
+ default:
+ sStatus = Num2Hex(aServiceStatus.dwCurrentState);
+ }
+ WriteLog(hInstall, "Service status is", sStatus);
+
+ return aServiceStatus.dwCurrentState;
+ }
+
+ static void StopService(MSIHANDLE hInstall, SC_HANDLE hService, bool bWait)
+ {
+ try
+ {
+ if (ServiceStatus(hInstall, hService) != SERVICE_STOPPED)
+ {
+ SERVICE_STATUS aServiceStatus{};
+ if (!ControlService(hService, SERVICE_CONTROL_STOP, &aServiceStatus))
+ ThrowLastError("ControlService");
+ WriteLog(hInstall,
+ "Successfully sent SERVICE_CONTROL_STOP code to Windows Update service");
+ if (aServiceStatus.dwCurrentState != SERVICE_STOPPED && bWait)
+ {
+ // Let user cancel too long wait
+ UserInputChecker aInputChecker(hInstall);
+ // aServiceStatus.dwWaitHint is unreasonably high for Windows Update (30000),
+ // so don't use it, but simply poll service status each second
+ for (int nWait = 0; nWait < 30; ++nWait) // arbitrary limit of 30 s
+ {
+ for (int i = 0; i < 2; ++i) // check user input twice a second
+ {
+ Sleep(500);
+ aInputChecker.ThrowIfUserCancelled();
+ }
+
+ if (!QueryServiceStatus(hService, &aServiceStatus))
+ ThrowLastError("QueryServiceStatus");
+
+ if (aServiceStatus.dwCurrentState == SERVICE_STOPPED)
+ break;
+ }
+ }
+ if (aServiceStatus.dwCurrentState == SERVICE_STOPPED)
+ WriteLog(hInstall, "Successfully stopped Windows Update service");
+ else if (bWait)
+ WriteLog(hInstall, "Wait for Windows Update stop timed out - proceeding");
+ }
+ else
+ WriteLog(hInstall, "Windows Update service is not running");
+ }
+ catch (std::exception& e)
+ {
+ WriteLog(hInstall, e.what());
+ }
+ }
+
+ MSIHANDLE mhInstall;
+ CloseServiceHandleGuard mhService;
+};
+}
+
+// Immediate action "unpack_msu" that has access to installation database and properties; checks
+// "InstMSUBinary" property and unpacks the binary with that name to a temporary file; sets
+// "cleanup_msu" and "inst_msu" properties to the full name of the extracted temporary file. These
+// properties will become "CustomActionData" property inside relevant deferred actions.
+extern "C" __declspec(dllexport) UINT __stdcall UnpackMSUForInstall(MSIHANDLE hInstall)
+{
+ try
+ {
+ sLogPrefix = "UnpackMSUForInstall:";
+ WriteLog(hInstall, "started");
+
+ WriteLog(hInstall, "Checking value of InstMSUBinary");
+ wchar_t sInstMSUBinary[MAX_PATH + 10];
+ DWORD nCCh = sizeof(sInstMSUBinary) / sizeof(*sInstMSUBinary);
+ CheckWin32Error("MsiGetPropertyW",
+ MsiGetPropertyW(hInstall, L"InstMSUBinary", sInstMSUBinary, &nCCh));
+ WriteLog(hInstall, "Got InstMSUBinary value:",
+ sInstMSUBinary); // KB2999226|Windows61-KB2999226-x64msu
+ const wchar_t* sBinaryName = wcschr(sInstMSUBinary, L'|');
+ if (!sBinaryName)
+ throw std::exception("No KB number in InstMSUBinary!");
+ // "KB2999226"
+ const std::wstring sKBNo(sInstMSUBinary, sBinaryName - sInstMSUBinary);
+ ++sBinaryName;
+
+ PMSIHANDLE hDatabase = MsiGetActiveDatabase(hInstall);
+ if (!hDatabase)
+ ThrowLastError("MsiGetActiveDatabase");
+ WriteLog(hInstall, "MsiGetActiveDatabase succeeded");
+
+ std::wstringstream sQuery;
+ sQuery << "SELECT `Data` FROM `Binary` WHERE `Name`='" << sBinaryName << "'";
+
+ PMSIHANDLE hBinaryView;
+ CheckWin32Error("MsiDatabaseOpenViewW",
+ MsiDatabaseOpenViewW(hDatabase, sQuery.str().c_str(), &hBinaryView));
+ WriteLog(hInstall, "MsiDatabaseOpenViewW succeeded");
+
+ CheckWin32Error("MsiViewExecute", MsiViewExecute(hBinaryView, 0));
+ WriteLog(hInstall, "MsiViewExecute succeeded");
+
+ PMSIHANDLE hBinaryRecord;
+ CheckWin32Error("MsiViewFetch", MsiViewFetch(hBinaryView, &hBinaryRecord));
+ WriteLog(hInstall, "MsiViewFetch succeeded");
+
+ const std::wstring sBinary = GetTempFile();
+ auto aDeleteFileGuard(Guard(sBinary.c_str()));
+ WriteLog(hInstall, "Temp file path:", sBinary.c_str());
+
+ CheckWin32Error("MsiSetPropertyW",
+ MsiSetPropertyW(hInstall, L"cleanup_msu", sBinary.c_str()));
+
+ {
+ HANDLE hFile = CreateFileW(sBinary.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, nullptr);
+ if (hFile == INVALID_HANDLE_VALUE)
+ ThrowLastError("CreateFileW");
+ auto aFileHandleGuard(Guard(hFile));
+
+ const DWORD nBufSize = 1024 * 1024;
+ std::unique_ptr<char[]> buf(new char[nBufSize]);
+ DWORD nTotal = 0;
+ DWORD nRead;
+ do
+ {
+ nRead = nBufSize;
+ CheckWin32Error("MsiRecordReadStream",
+ MsiRecordReadStream(hBinaryRecord, 1, buf.get(), &nRead));
+
+ if (nRead > 0)
+ {
+ DWORD nWritten;
+ if (!WriteFile(hFile, buf.get(), nRead, &nWritten, nullptr))
+ ThrowLastError("WriteFile");
+ nTotal += nWritten;
+ }
+ } while (nRead == nBufSize);
+
+ WriteLog(hInstall, "Successfully wrote", Num2Dec(nTotal), "bytes");
+ }
+ const std::wstring s_inst_msu = sKBNo + L"|" + sBinary;
+ CheckWin32Error("MsiSetPropertyW",
+ MsiSetPropertyW(hInstall, L"inst_msu", s_inst_msu.c_str()));
+
+ // Don't delete the file: it will be done by following actions (inst_msu or cleanup_msu)
+ (void)aDeleteFileGuard.release();
+ return ERROR_SUCCESS;
+ }
+ catch (std::exception& e)
+ {
+ WriteLog(hInstall, e.what());
+ }
+ return ERROR_INSTALL_FAILURE;
+}
+
+// Deferred action "inst_msu" that must be run from system account. Receives the tempfile name from
+// "CustomActionData" property, and runs wusa.exe to install it. Waits for it and checks exit code.
+extern "C" __declspec(dllexport) UINT __stdcall InstallMSU(MSIHANDLE hInstall)
+{
+ std::wstring sKBNo; // "KB2999226"
+ try
+ {
+ sLogPrefix = "InstallMSU:";
+ WriteLog(hInstall, "started");
+
+ WriteLog(hInstall, "Checking value of CustomActionData");
+ wchar_t sCustomActionData[MAX_PATH + 10]; // "KB2999226|C:\Temp\binary.tmp"
+ DWORD nCCh = sizeof(sCustomActionData) / sizeof(*sCustomActionData);
+ CheckWin32Error("MsiGetPropertyW",
+ MsiGetPropertyW(hInstall, L"CustomActionData", sCustomActionData, &nCCh));
+ WriteLog(hInstall, "Got CustomActionData value:", sCustomActionData);
+ const wchar_t* sBinaryName = wcschr(sCustomActionData, L'|');
+ if (!sBinaryName)
+ throw std::exception("No KB number in CustomActionData!");
+ sKBNo = std::wstring(sCustomActionData, sBinaryName - sCustomActionData);
+ ++sBinaryName;
+ auto aDeleteFileGuard(Guard(sBinaryName));
+
+ SetStatusText(hInstall, L"WU service state check",
+ L"Checking Windows Update service state");
+
+ // In case the Windows Update service is disabled, we temporarily enable it here. We also
+ // stop running WU service, to avoid wusa.exe freeze (see comment in EnableWUService).
+ WUServiceEnabler aWUServiceEnabler(hInstall);
+
+ SetStatusText(hInstall, sKBNo + L" installation", L"Installing " + sKBNo);
+
+ const bool bWow64Process = IsWow64Process();
+ WriteLog(hInstall, "Is Wow64 Process:", bWow64Process ? "YES" : "NO");
+ std::wstring sWUSAPath = bWow64Process ? GetKnownFolder(FOLDERID_Windows) + L"\\SysNative"
+ : GetKnownFolder(FOLDERID_System);
+ sWUSAPath += L"\\wusa.exe";
+ WriteLog(hInstall, "Prepared wusa path:", sWUSAPath);
+
+ std::wstring sWUSACmd
+ = L"\"" + sWUSAPath + L"\" \"" + sBinaryName + L"\" /quiet /norestart";
+ WriteLog(hInstall, "Prepared wusa command:", sWUSACmd);
+
+ STARTUPINFOW si{};
+ si.cb = sizeof(si);
+ PROCESS_INFORMATION pi{};
+ if (!CreateProcessW(sWUSAPath.c_str(), const_cast<LPWSTR>(sWUSACmd.c_str()), nullptr,
+ nullptr, FALSE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi))
+ ThrowLastError("CreateProcessW");
+ CloseHandle(pi.hThread);
+ auto aCloseProcHandleGuard(Guard(pi.hProcess));
+ WriteLog(hInstall, "CreateProcessW succeeded");
+
+ {
+ // This block waits when the started wusa.exe process finishes. Since it's possible
+ // for wusa.exe in some circumstances to wait really long (indefinitely?), we check
+ // for user input here.
+ UserInputChecker aInputChecker(hInstall);
+ for (;;)
+ {
+ DWORD nWaitResult = WaitForSingleObject(pi.hProcess, 500);
+ if (nWaitResult == WAIT_OBJECT_0)
+ break; // wusa.exe finished
+ else if (nWaitResult == WAIT_TIMEOUT)
+ aInputChecker.ThrowIfUserCancelled();
+ else
+ ThrowWin32Error("WaitForSingleObject", nWaitResult);
+ }
+ }
+
+ DWORD nExitCode = 0;
+ if (!GetExitCodeProcess(pi.hProcess, &nExitCode))
+ ThrowLastError("GetExitCodeProcess");
+
+ HRESULT hr = static_cast<HRESULT>(nExitCode);
+
+ // HRESULT_FROM_WIN32 is defined as an inline function in SDK 8.1 without the constexpr
+ // And it won't work to place it inside the switch statement.
+ if (HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED) == hr)
+ {
+ hr = ERROR_SUCCESS_REBOOT_REQUIRED;
+ }
+
+ switch (hr)
+ {
+ case S_OK:
+ case WU_S_ALREADY_INSTALLED:
+ case WU_E_NOT_APPLICABLE: // Windows could lie us about its version, etc.
+ case ERROR_SUCCESS_REBOOT_REQUIRED:
+ case WU_S_REBOOT_REQUIRED:
+ WriteLog(hInstall, "wusa.exe succeeded with exit code", Num2Hex(nExitCode));
+ return ERROR_SUCCESS;
+
+ default:
+ ThrowHResult("Execution of wusa.exe", hr);
+ }
+ }
+ catch (const UserInputChecker::eUserCancelled&)
+ {
+ return ERROR_INSTALL_USEREXIT;
+ }
+ catch (std::exception& e)
+ {
+ WriteLog(hInstall, e.what());
+ ShowWarning(hInstall, sKBNo, e.what());
+ }
+ return ERROR_SUCCESS; // Do not break on MSU installation errors
+}
+
+// Rollback deferred action "cleanup_msu" that is executed on error or cancel.
+// It removes the temporary file created by UnpackMSUForInstall action.
+// MUST be placed IMMEDIATELY AFTER "unpack_msu" in execute sequence.
+extern "C" __declspec(dllexport) UINT __stdcall CleanupMSU(MSIHANDLE hInstall)
+{
+ try
+ {
+ sLogPrefix = "CleanupMSU:";
+ WriteLog(hInstall, "started");
+
+ WriteLog(hInstall, "Checking value of CustomActionData");
+ wchar_t sBinaryName[MAX_PATH + 1];
+ DWORD nCCh = sizeof(sBinaryName) / sizeof(*sBinaryName);
+ CheckWin32Error("MsiGetPropertyW",
+ MsiGetPropertyW(hInstall, L"CustomActionData", sBinaryName, &nCCh));
+ WriteLog(hInstall, "Got CustomActionData value:", sBinaryName);
+
+ if (!DeleteFileW(sBinaryName))
+ {
+ if (DWORD nError = GetLastError(); nError != ERROR_FILE_NOT_FOUND)
+ ThrowWin32Error("DeleteFileW", nError);
+ }
+ WriteLog(hInstall, "File successfully removed");
+ }
+ catch (std::exception& e)
+ {
+ WriteLog(hInstall, e.what());
+ }
+ // Always return success - we don't want rollback to fail.
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/inst_msu/inst_msu_msi.def b/setup_native/source/win32/customactions/inst_msu/inst_msu_msi.def
new file mode 100644
index 000000000..49ade9c01
--- /dev/null
+++ b/setup_native/source/win32/customactions/inst_msu/inst_msu_msi.def
@@ -0,0 +1,5 @@
+LIBRARY "inst_msu_msi.dll"
+EXPORTS
+ UnpackMSUForInstall
+ InstallMSU
+ CleanupMSU \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/quickstarter/qslnkmsi.def b/setup_native/source/win32/customactions/quickstarter/qslnkmsi.def
new file mode 100644
index 000000000..f50a3a396
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/qslnkmsi.def
@@ -0,0 +1,3 @@
+LIBRARY "qslnkmsi.dll"
+EXPORTS
+ RemoveQuickstarterLink \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/quickstarter/quickstarter.cxx b/setup_native/source/win32/customactions/quickstarter/quickstarter.cxx
new file mode 100644
index 000000000..960274f39
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/quickstarter.cxx
@@ -0,0 +1,131 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "quickstarter.hxx"
+
+#include <psapi.h>
+
+#include <malloc.h>
+
+std::wstring GetOfficeInstallationPathW(MSIHANDLE handle)
+{
+ std::wstring progpath;
+ DWORD sz = 0;
+ PWSTR dummy = const_cast<PWSTR>(L"");
+
+ if (MsiGetPropertyW(handle, L"INSTALLLOCATION", dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++; // space for the final '\0'
+ DWORD nbytes = sz * sizeof(WCHAR);
+ PWSTR buff = static_cast<PWSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetPropertyW(handle, L"INSTALLLOCATION", buff, &sz);
+ progpath = buff;
+ }
+ return progpath;
+}
+
+std::wstring GetOfficeProductNameW(MSIHANDLE handle)
+{
+ std::wstring productname;
+ DWORD sz = 0;
+ PWSTR dummy = const_cast<PWSTR>(L"");
+
+ if (MsiGetPropertyW(handle, L"ProductName", dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++; // space for the final '\0'
+ DWORD nbytes = sz * sizeof(WCHAR);
+ PWSTR buff = static_cast<PWSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetPropertyW(handle, L"ProductName", buff, &sz);
+ productname = buff;
+ }
+ return productname;
+}
+
+std::wstring GetQuickstarterLinkNameW(MSIHANDLE handle)
+{
+ std::wstring quickstarterlinkname;
+ DWORD sz = 0;
+ PWSTR dummy = const_cast<PWSTR>(L"");
+
+ if (MsiGetPropertyW(handle, L"Quickstarterlinkname", dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++; // space for the final '\0'
+ DWORD nbytes = sz * sizeof(WCHAR);
+ PWSTR buff = static_cast<PWSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetPropertyW(handle, L"Quickstarterlinkname", buff, &sz);
+ quickstarterlinkname = buff;
+ }
+ else if (MsiGetPropertyW(handle, L"ProductName", dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++; // space for the final '\0'
+ DWORD nbytes = sz * sizeof(WCHAR);
+ PWSTR buff = static_cast<PWSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetPropertyW(handle, L"ProductName", buff, &sz);
+ quickstarterlinkname = buff;
+ }
+ return quickstarterlinkname;
+}
+
+static bool IsValidHandle( HANDLE handle )
+{
+ return nullptr != handle && INVALID_HANDLE_VALUE != handle;
+}
+
+static DWORD WINAPI GetModuleFileNameExW_( HANDLE hProcess, HMODULE hModule, PWSTR lpFileName, DWORD nSize )
+{
+ static auto lpProc = []() {
+ HMODULE hLibrary = LoadLibraryW(L"PSAPI.DLL");
+ decltype(GetModuleFileNameExW)* pRet = nullptr;
+ if (hLibrary)
+ pRet = reinterpret_cast<decltype(GetModuleFileNameExW)*>(
+ GetProcAddress(hLibrary, "GetModuleFileNameExW"));
+ return pRet;
+ }();
+
+ if ( lpProc )
+ return lpProc( hProcess, hModule, lpFileName, nSize );
+
+ return 0;
+
+}
+
+std::wstring GetProcessImagePathW( DWORD dwProcessId )
+{
+ std::wstring sImagePath;
+
+ HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId );
+
+ if ( IsValidHandle( hProcess ) )
+ {
+ WCHAR szPathBuffer[MAX_PATH] = L"";
+
+ if ( GetModuleFileNameExW_( hProcess, nullptr, szPathBuffer, sizeof(szPathBuffer)/sizeof(szPathBuffer[0]) ) )
+ sImagePath = szPathBuffer;
+
+ CloseHandle( hProcess );
+ }
+
+ return sImagePath;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/quickstarter/quickstarter.hxx b/setup_native/source/win32/customactions/quickstarter/quickstarter.hxx
new file mode 100644
index 000000000..2370f4691
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/quickstarter.hxx
@@ -0,0 +1,36 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SETUP_NATIVE_SOURCE_WIN32_CUSTOMACTIONS_QUICKSTARTER_QUICKSTARTER_HXX
+#define INCLUDED_SETUP_NATIVE_SOURCE_WIN32_CUSTOMACTIONS_QUICKSTARTER_QUICKSTARTER_HXX
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+
+#include <string>
+
+std::wstring GetOfficeInstallationPathW(MSIHANDLE handle);
+std::wstring GetOfficeProductNameW(MSIHANDLE handle);
+std::wstring GetQuickstarterLinkNameW(MSIHANDLE handle);
+std::wstring GetProcessImagePathW(DWORD dwProcessId);
+
+#endif // INCLUDED_SETUP_NATIVE_SOURCE_WIN32_CUSTOMACTIONS_QUICKSTARTER_QUICKSTARTER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/quickstarter/remove_quickstart_link.cxx b/setup_native/source/win32/customactions/quickstarter/remove_quickstart_link.cxx
new file mode 100644
index 000000000..68faed45a
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/remove_quickstart_link.cxx
@@ -0,0 +1,42 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "quickstarter.hxx"
+
+#include <shlobj.h>
+
+extern "C" __declspec(dllexport) UINT __stdcall RemoveQuickstarterLink( MSIHANDLE hMSI )
+{
+ WCHAR szStartupPath[MAX_PATH];
+
+ if ( SHGetSpecialFolderPathW( nullptr, szStartupPath, CSIDL_STARTUP, FALSE ) )
+ {
+ std::wstring sQuickstartLinkPath = szStartupPath;
+
+ sQuickstartLinkPath += L"\\";
+ sQuickstartLinkPath += GetQuickstarterLinkNameW( hMSI );
+ sQuickstartLinkPath += L".lnk";
+
+ DeleteFileW( sQuickstartLinkPath.c_str() );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/quickstarter/sdqsmsi.def b/setup_native/source/win32/customactions/quickstarter/sdqsmsi.def
new file mode 100644
index 000000000..c8df896e5
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/sdqsmsi.def
@@ -0,0 +1,3 @@
+LIBRARY "sdqsmsi.dll"
+EXPORTS
+ ShutDownQuickstarter \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/quickstarter/shutdown_quickstart.cxx b/setup_native/source/win32/customactions/quickstarter/shutdown_quickstart.cxx
new file mode 100644
index 000000000..c93b000e4
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/shutdown_quickstart.cxx
@@ -0,0 +1,73 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "quickstarter.hxx"
+
+#include <systools/win32/qswin32.h>
+
+static BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam )
+{
+ MSIHANDLE hMSI = static_cast< MSIHANDLE >( lParam );
+ WCHAR szClassName[sizeof(QUICKSTART_CLASSNAME)/sizeof(WCHAR) + 1];
+
+ int nCharsCopied = GetClassNameW( hWnd, szClassName, sizeof(szClassName)/sizeof(szClassName[0]) );
+
+ if ( nCharsCopied && !_wcsicmp( QUICKSTART_CLASSNAME, szClassName ) )
+ {
+ DWORD dwProcessId;
+
+ if ( GetWindowThreadProcessId( hWnd, &dwProcessId ) )
+ {
+ std::wstring sImagePath = GetProcessImagePathW( dwProcessId );
+ std::wstring sOfficeImageDir = GetOfficeInstallationPathW( hMSI ) + L"program\\";
+
+ if ( !_wcsnicmp( sImagePath.c_str(), sOfficeImageDir.c_str(), sOfficeImageDir.length() ) )
+ {
+ UINT uMsgShutdownQuickstart = RegisterWindowMessageW( SHUTDOWN_QUICKSTART_MESSAGE );
+
+ if ( uMsgShutdownQuickstart )
+ SendMessageW( hWnd, uMsgShutdownQuickstart, 0, 0 );
+
+
+ HANDLE hProcess = OpenProcess( SYNCHRONIZE, FALSE, dwProcessId );
+
+ if ( hProcess )
+ {
+ WaitForSingleObject( hProcess, 30000 ); // Wait at most 30 seconds for process to terminate
+ CloseHandle( hProcess );
+ }
+
+ return FALSE;
+ }
+
+ }
+ }
+
+ return TRUE;
+}
+
+
+extern "C" __declspec(dllexport) UINT __stdcall ShutDownQuickstarter( MSIHANDLE hMSI )
+{
+ EnumWindows( EnumWindowsProc, hMSI );
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsdoc.def b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsdoc.def
new file mode 100644
index 000000000..cea8b4699
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsdoc.def
@@ -0,0 +1,6 @@
+LIBRARY "reg4allmsdoc.dll"
+EXPORTS
+ FindRegisteredExtensions
+ LookForRegisteredExtensions
+ RegisterSomeExtensions
+ RestoreRegAllMSDoc \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
new file mode 100644
index 000000000..1a2e82eb7
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
@@ -0,0 +1,519 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+
+#include <malloc.h>
+#include <string>
+#include <strsafe.h>
+
+static const WCHAR* g_Extensions[] =
+{
+ L".doc", // Microsoft Word Text [0]
+ L".dot", // Microsoft Word Template
+ L".wps", // Kingsoft Writer Document
+ L".wpt", // Kingsoft Writer Template
+ L".rtf", // rtf text
+ L".docx", // Office Word 2007 XML document
+ L".docm", // Office Word 2007 XML macro-enabled document
+ L".dotx", // Office Word 2007 XML template
+ L".dotm", // Office Word 2007 XML macro-enabled template
+ L".xlw", // Microsoft Excel
+ L".xls", // Microsoft Excel
+ L".xlt", // Microsoft Excel Template
+ L".xlsx", // Office Excel 2007 XML workbook
+ L".xlsm", // Office Excel 2007 XML macro-enabled workbook
+ L".xltx", // Office Excel 2007 XML template
+ L".xltm", // Office Excel 2007 XML macro-enabled template
+ L".xlsb", // Office Excel 2007 binary workbook (BIFF12)
+ L".iqy", // Microsoft Excel Web Query File
+ L".et", // Kingsoft Spreadsheet
+ L".ett", // Kingsoft SpreadSheet Template
+ L".ppt", // Microsoft Powerpoint
+ L".pps", // Microsoft Powerpoint
+ L".pot", // Microsoft Powerpoint Template
+ L".pptx", // Office PowerPoint 2007 XML presentation
+ L".pptm", // Office PowerPoint 2007 macro-enabled XML presentation
+ L".potx", // Office PowerPoint 2007 XML template
+ L".potm", // Office PowerPoint 2007 macro-enabled XML template
+ L".ppsx", // Office PowerPoint 2007 XML show
+ L".dps", // Kingsoft Presentation
+ L".dpt", // Kingsoft Presentation Template
+ L".vsd", // Visio 2000/XP/2003 document
+ L".vst", // Visio 2000/XP/2003 template
+ nullptr
+};
+
+static const int WORD_START = 0;
+static const int EXCEL_START = 9;
+static const int POWERPOINT_START = 20;
+static const int VISIO_START = 30;
+static const int VISIO_END = 32;
+
+// ".xlam", // Office Excel 2007 XML macro-enabled add-in
+// ".ppam", // Office PowerPoint 2007 macro-enabled XML add-in
+// ".ppsm", // Office PowerPoint 2007 macro-enabled XML show
+
+#ifdef DEBUG
+inline void OutputDebugStringFormatW( LPCWSTR pFormat, ... )
+{
+ WCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfW( buffer, sizeof(buffer)/sizeof(*buffer), pFormat, args );
+ OutputDebugStringW( buffer );
+ va_end(args);
+}
+#else
+static void OutputDebugStringFormatW( LPCWSTR, ... )
+{
+}
+#endif
+
+static bool CheckExtensionInRegistry( LPCWSTR lpSubKey )
+{
+ bool bRet = false;
+ HKEY hKey = nullptr;
+ LONG lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ WCHAR szBuffer[1024];
+ DWORD nSize = sizeof( szBuffer );
+
+ lResult = RegQueryValueExW( hKey, L"", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &nSize );
+ if ( ERROR_SUCCESS == lResult && nSize > 0 )
+ {
+ szBuffer[nSize/sizeof(*szBuffer)] = L'\0';
+ OutputDebugStringFormatW( L"Found value [%s] for key [%s].\n", szBuffer, lpSubKey );
+
+ if ( wcsncmp( szBuffer, L"WordPad.Document.1", 18 ) == 0 )
+ { // We will replace registration for WordPad (alas, on XP only) FIXME
+ bRet = true;
+ }
+ else if ( wcsncmp( szBuffer, L"LibreOffice.", 12 ) == 0 )
+ { // We will replace registration for our own types, too
+ bRet = true;
+ }
+ else if ( wcsncmp( szBuffer, L"lostub.", 7 ) == 0 )
+ { // We will replace registration for lostub, too
+ bRet = true;
+ }
+ else // we have a default value -> do not register, see fdo#39791
+ bRet = false;
+ }
+ else // no default value found -> return TRUE to register for that key
+ bRet = true;
+
+ RegCloseKey( hKey );
+ }
+ else // no key found -> return TRUE to register for that key
+ bRet = true;
+
+ return bRet;
+}
+
+static bool GetMsiPropW( MSIHANDLE handle, LPCWSTR name, /*out*/std::wstring& value )
+{
+ DWORD sz = 0;
+ LPWSTR dummy = const_cast<LPWSTR>(L"");
+ if (MsiGetPropertyW(handle, name, dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof(WCHAR);
+ LPWSTR buff = static_cast<LPWSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetPropertyW(handle, name, buff, &sz);
+ value = buff;
+ return true;
+ }
+ return false;
+}
+
+static bool IsSetMsiPropW( MSIHANDLE handle, LPCWSTR name )
+{
+ std::wstring val;
+ GetMsiPropW( handle, name, val );
+ return (val == L"1");
+}
+
+static void registerForExtension( MSIHANDLE handle, const int nIndex, bool bRegister )
+{
+ WCHAR sPropName[256];
+ StringCchCopyW( sPropName, 256, L"REGISTER_" );
+ StringCchCatW( sPropName, 256, (g_Extensions[nIndex])+1 );
+ CharUpperBuffW( sPropName+9, 4 );
+
+ if ( bRegister ) {
+ MsiSetPropertyW( handle, sPropName, L"1" );
+ OutputDebugStringFormatW( L"Set MSI property %s.\n", sPropName );
+ } else {
+ MsiSetPropertyW( handle, sPropName, L"0" );
+ OutputDebugStringFormatW( L"Unset MSI property %s.\n", sPropName );
+ }
+}
+
+static void saveOldRegistration( LPCWSTR lpSubKey )
+{
+ HKEY hKey = nullptr;
+ LONG lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, lpSubKey, 0,
+ KEY_QUERY_VALUE|KEY_SET_VALUE, &hKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ WCHAR szBuffer[1024];
+ DWORD nSize = sizeof( szBuffer );
+
+ lResult = RegQueryValueExW( hKey, L"", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &nSize );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ szBuffer[nSize/sizeof(*szBuffer)] = L'\0';
+
+ // No need to save associations for our own types
+ if ( wcsncmp( szBuffer, L"LibreOffice.", 12 ) != 0 )
+ {
+ // Save the old association
+ RegSetValueExW( hKey, L"LOBackupAssociation", 0,
+ REG_SZ, reinterpret_cast<LPBYTE>(szBuffer), nSize );
+ // Also save what the old association means, just so we can try to verify
+ // if/when restoring it that the old application still exists
+ HKEY hKey2 = nullptr;
+ lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, szBuffer, 0,
+ KEY_QUERY_VALUE, &hKey2 );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ nSize = sizeof( szBuffer );
+ lResult = RegQueryValueExW( hKey2, L"", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &nSize );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ RegSetValueExW( hKey, L"LOBackupAssociationDeref", 0,
+ REG_SZ, reinterpret_cast<LPBYTE>(szBuffer), nSize );
+ }
+ RegCloseKey( hKey2 );
+ }
+ }
+ }
+ RegCloseKey( hKey );
+ }
+}
+
+static void registerForExtensions( MSIHANDLE handle, bool bRegisterAll )
+{ // Check all file extensions
+ int nIndex = 0;
+ while ( g_Extensions[nIndex] != nullptr )
+ {
+ saveOldRegistration( g_Extensions[nIndex] );
+
+ bool bRegister = bRegisterAll || CheckExtensionInRegistry( g_Extensions[nIndex] );
+ if ( bRegister )
+ registerForExtension( handle, nIndex, true );
+ ++nIndex;
+ }
+}
+
+static bool checkSomeExtensionInRegistry( const int nStart, const int nEnd )
+{ // Check all file extensions
+ int nIndex = nStart;
+ bool bFound = false;
+
+ while ( !bFound && (nIndex < nEnd) && (g_Extensions[nIndex] != nullptr) )
+ {
+ bFound = ! CheckExtensionInRegistry( g_Extensions[nIndex] );
+
+ if ( bFound )
+ OutputDebugStringFormatW( L"Found registration for [%s].\n", g_Extensions[nIndex] );
+
+ ++nIndex;
+ }
+ return bFound;
+}
+
+static void registerSomeExtensions( MSIHANDLE handle, const int nStart, const int nEnd, bool bRegister )
+{ // Check all file extensions
+ int nIndex = nStart;
+
+ while ( (nIndex < nEnd) && (g_Extensions[nIndex] != nullptr) )
+ {
+ registerForExtension( handle, nIndex++, bRegister );
+ }
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall LookForRegisteredExtensions( MSIHANDLE handle )
+{
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: " );
+
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+
+ bool bWriterEnabled = false;
+ bool bCalcEnabled = false;
+ bool bImpressEnabled = false;
+ bool bDrawEnabled = false;
+ bool bRegisterNone = IsSetMsiPropW( handle, L"REGISTER_NO_MSO_TYPES" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureStateW( handle, L"gm_p_Wrt", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bWriterEnabled = true;
+
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Install state Writer is [%d], will be [%d]", current_state, future_state );
+ if ( bWriterEnabled )
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Writer is enabled" );
+ else
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Writer is NOT enabled" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureStateW( handle, L"gm_p_Calc", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bCalcEnabled = true;
+
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Install state Calc is [%d], will be [%d]", current_state, future_state );
+ if ( bCalcEnabled )
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Calc is enabled" );
+ else
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Calc is NOT enabled" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureStateW( handle, L"gm_p_Impress", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bImpressEnabled = true;
+
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Install state Impress is [%d], will be [%d]", current_state, future_state );
+ if ( bImpressEnabled )
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Impress is enabled" );
+ else
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Impress is NOT enabled" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureStateW( handle, L"gm_p_Draw", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bDrawEnabled = true;
+
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Install state Draw is [%d], will be [%d]", current_state, future_state );
+ if ( bImpressEnabled )
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Draw is enabled" );
+ else
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Draw is NOT enabled" );
+
+ MsiSetPropertyW( handle, L"SELECT_WORD", L"" );
+ MsiSetPropertyW( handle, L"SELECT_EXCEL", L"" );
+ MsiSetPropertyW( handle, L"SELECT_POWERPOINT", L"" );
+ MsiSetPropertyW( handle, L"SELECT_VISIO", L"" );
+
+ if ( ! bRegisterNone )
+ {
+ if ( IsSetMsiPropW( handle, L"REGISTER_ALL_MSO_TYPES" ) )
+ {
+ if ( bWriterEnabled )
+ MsiSetPropertyW( handle, L"SELECT_WORD", L"1" );
+ if ( bCalcEnabled )
+ MsiSetPropertyW( handle, L"SELECT_EXCEL", L"1" );
+ if ( bImpressEnabled )
+ MsiSetPropertyW( handle, L"SELECT_POWERPOINT", L"1" );
+ if ( bDrawEnabled )
+ MsiSetPropertyW( handle, L"SELECT_VISIO", L"1" );
+ }
+ else
+ {
+ if ( bWriterEnabled && ! checkSomeExtensionInRegistry( WORD_START, EXCEL_START ) )
+ {
+ MsiSetPropertyW( handle, L"SELECT_WORD", L"1" );
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Register for Microsoft Word" );
+ }
+ if ( bCalcEnabled && ! checkSomeExtensionInRegistry( EXCEL_START, POWERPOINT_START ) )
+ {
+ MsiSetPropertyW( handle, L"SELECT_EXCEL", L"1" );
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Register for Microsoft Excel" );
+ }
+ if ( bImpressEnabled && ! checkSomeExtensionInRegistry( POWERPOINT_START, VISIO_START ) )
+ {
+ MsiSetPropertyW( handle, L"SELECT_POWERPOINT", L"1" );
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Register for Microsoft PowerPoint" );
+ }
+ if ( bImpressEnabled && ! checkSomeExtensionInRegistry( VISIO_START, VISIO_END ) )
+ {
+ MsiSetPropertyW( handle, L"SELECT_VISIO", L"1" );
+ OutputDebugStringFormatW( L"LookForRegisteredExtensions: Register for Microsoft Visio" );
+ }
+ }
+ }
+
+ MsiSetPropertyW( handle, L"FILETYPEDIALOGUSED", L"1" );
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall RegisterSomeExtensions( MSIHANDLE handle )
+{
+ OutputDebugStringFormatW( L"RegisterSomeExtensions: " );
+
+ if ( IsSetMsiPropW( handle, L"SELECT_WORD" ) )
+ {
+ registerSomeExtensions( handle, WORD_START, EXCEL_START, true );
+ MsiSetFeatureStateW( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormatW( L"RegisterSomeExtensions: Register for Microsoft Word" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, WORD_START, EXCEL_START, false );
+ MsiSetFeatureStateW( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+
+ if ( IsSetMsiPropW( handle, L"SELECT_EXCEL" ) )
+ {
+ registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, true );
+ MsiSetFeatureStateW( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormatW( L"RegisterSomeExtensions: Register for Microsoft Excel" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, false );
+ MsiSetFeatureStateW( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+
+ if ( IsSetMsiPropW( handle, L"SELECT_POWERPOINT" ) )
+ {
+ registerSomeExtensions( handle, POWERPOINT_START, VISIO_START, true );
+ MsiSetFeatureStateW( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormatW( L"RegisterSomeExtensions: Register for Microsoft PowerPoint" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, POWERPOINT_START, VISIO_START, false );
+ MsiSetFeatureStateW( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+
+ if ( IsSetMsiPropW( handle, L"SELECT_VISIO" ) )
+ {
+ registerSomeExtensions( handle, VISIO_START, VISIO_END, true );
+ MsiSetFeatureStateW( handle, L"gm_p_Draw_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormatW( L"RegisterSomeExtensions: Register for Microsoft Visio" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, VISIO_START, VISIO_END, false );
+ MsiSetFeatureStateW( handle, L"gm_p_Draw_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+ return ERROR_SUCCESS;
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall FindRegisteredExtensions( MSIHANDLE handle )
+{
+ if ( IsSetMsiPropW( handle, L"FILETYPEDIALOGUSED" ) )
+ {
+ OutputDebugStringFormatW( L"FindRegisteredExtensions: FILETYPEDIALOGUSED!" );
+ return ERROR_SUCCESS;
+ }
+
+ OutputDebugStringFormatW( L"FindRegisteredExtensions:" );
+
+ bool bRegisterAll = IsSetMsiPropW( handle, L"REGISTER_ALL_MSO_TYPES" );
+
+ if ( IsSetMsiPropW( handle, L"REGISTER_NO_MSO_TYPES" ) )
+ {
+ OutputDebugStringFormatW( L"FindRegisteredExtensions: Register none!" );
+ return ERROR_SUCCESS;
+ }
+ else if ( bRegisterAll )
+ OutputDebugStringFormatW( L"FindRegisteredExtensions: Force all on" );
+ else
+ OutputDebugStringFormatW( L"FindRegisteredExtensions: " );
+
+ // setting the msi properties SELECT_* will force registering for all corresponding
+ // file types
+ if ( IsSetMsiPropW( handle, L"SELECT_WORD" ) )
+ registerSomeExtensions( handle, WORD_START, EXCEL_START, true );
+ if ( IsSetMsiPropW( handle, L"SELECT_EXCEL" ) )
+ registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, true );
+ if ( IsSetMsiPropW( handle, L"SELECT_POWERPOINT" ) )
+ registerSomeExtensions( handle, POWERPOINT_START, VISIO_START, true );
+ if ( IsSetMsiPropW( handle, L"SELECT_VISIO" ) )
+ registerSomeExtensions( handle, VISIO_START, VISIO_END, true );
+
+ registerForExtensions( handle, bRegisterAll );
+
+ return ERROR_SUCCESS;
+}
+
+static void restoreOldRegistration( LPCWSTR lpSubKey )
+{
+ HKEY hKey = nullptr;
+ LONG lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, lpSubKey, 0,
+ KEY_QUERY_VALUE|KEY_SET_VALUE, &hKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ WCHAR szBuffer[1024];
+ DWORD nSize = sizeof( szBuffer );
+
+ lResult = RegQueryValueExW( hKey, L"LOBackupAssociation", nullptr, nullptr,
+ reinterpret_cast<LPBYTE>(szBuffer), &nSize );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ szBuffer[nSize/sizeof(*szBuffer)] = L'\0';
+ HKEY hKey2 = nullptr;
+ lResult = RegOpenKeyExW( HKEY_CLASSES_ROOT, szBuffer, 0,
+ KEY_QUERY_VALUE, &hKey2 );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ WCHAR szBuffer2[1024];
+ DWORD nSize2 = sizeof( szBuffer2 );
+
+ lResult = RegQueryValueExW( hKey2, L"", nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer2), &nSize2 );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ WCHAR szBuffer3[1024];
+ DWORD nSize3 = sizeof( szBuffer3 );
+
+ // Try to verify that the old association is OK to restore
+ lResult = RegQueryValueExW( hKey, L"LOBackupAssociationDeref", nullptr, nullptr,
+ reinterpret_cast<LPBYTE>(szBuffer3), &nSize3 );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ if ( nSize2 == nSize3 && wcsncmp (szBuffer2, szBuffer3, nSize2/sizeof(*szBuffer2)) == 0)
+ {
+ // Yep. So restore it
+ RegSetValueExW( hKey, L"", 0, REG_SZ, reinterpret_cast<LPBYTE>(szBuffer), nSize );
+ }
+ }
+ }
+ RegCloseKey( hKey2 );
+ }
+ RegDeleteValueW( hKey, L"LOBackupAssociation" );
+ }
+ RegDeleteValueW( hKey, L"LOBackupAssociationDeref" );
+ RegCloseKey( hKey );
+ }
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall RestoreRegAllMSDoc( MSIHANDLE /*handle*/ )
+{
+ OutputDebugStringFormatW( L"RestoreRegAllMSDoc\n" );
+
+ int nIndex = 0;
+ while ( g_Extensions[nIndex] != nullptr )
+ {
+ restoreOldRegistration( g_Extensions[nIndex] );
+ ++nIndex;
+ }
+
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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 000000000..c7b1cc742
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg_dlls/reg_dlls.cxx
@@ -0,0 +1,319 @@
+/* -*- 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, const_cast<wchar_t*>(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{};
+ si.cb = 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_SubstMSO;
+ INSTALLSTATE future_state_SubstMSO;
+ CheckWin32Error("MsiGetFeatureStateW",
+ MsiGetFeatureStateW(hInstall, L"gm_SharePointSupport_SubstMSO",
+ &current_state_SubstMSO, &future_state_SubstMSO));
+
+ WriteLog(hInstall, "gm_SharePointSupport_SubstMSO state:", //
+ "current", std::to_string(current_state_SubstMSO), //
+ "future", std::to_string(future_state_SubstMSO)); //
+
+ INSTALLSTATE current_state_Main;
+ INSTALLSTATE future_state_Main;
+ CheckWin32Error("MsiGetFeatureStateW",
+ MsiGetFeatureStateW(hInstall, L"gm_o_SharePointSupport",
+ &current_state_Main, &future_state_Main));
+
+ WriteLog(hInstall, "gm_o_SharePointSupport state:", //
+ "current", std::to_string(current_state_Main), //
+ "future", std::to_string(future_state_Main)); //
+
+ const bool bUnregSubstMSO = current_state_SubstMSO == INSTALLSTATE_LOCAL
+ && future_state_SubstMSO == INSTALLSTATE_ABSENT;
+ const bool bUnregMain
+ = current_state_Main == INSTALLSTATE_LOCAL && future_state_Main == INSTALLSTATE_ABSENT;
+ const bool bRegSubstMSO = current_state_SubstMSO == INSTALLSTATE_ABSENT
+ && future_state_SubstMSO == INSTALLSTATE_LOCAL;
+ // basic registration is needed when either:
+ // 1. gm_o_SharePointSupport is installed;
+ // 2. gm_SharePointSupport_SubstMSO is uninstalled (and unregisters everything), but
+ // gm_o_SharePointSupport is not, so needs to be re-registered
+ const bool bRegMain
+ = (current_state_Main == INSTALLSTATE_ABSENT && future_state_Main == INSTALLSTATE_LOCAL)
+ || (bUnregSubstMSO && !bUnregMain);
+
+ std::wstring sUnregStr;
+ if (bUnregSubstMSO)
+ {
+ sUnregStr = L"/i:Substitute_OWSSUPP \"[#spsupp_x86.dll]\"|"
+ L"/i:Substitute_OWSSUPP \"[#spsupp_x64.dll]\"";
+ }
+ else if (bUnregMain)
+ {
+ sUnregStr = L"\"[#spsupp_x86.dll]\"|\"[#spsupp_x64.dll]\"";
+ }
+
+ std::wstring sRegStr;
+ if (bRegSubstMSO)
+ {
+ sRegStr = L"/i:Substitute_OWSSUPP \"[#spsupp_x86.dll]\"|"
+ L"/i:Substitute_OWSSUPP \"[#spsupp_x64.dll]\"";
+ }
+ else if (bRegMain)
+ {
+ sRegStr = L"\"[#spsupp_x86.dll]\"|\"[#spsupp_x64.dll]\"";
+ }
+
+ auto SetFormattedPropW = [&](LPCWSTR sProp, const std::wstring& sVal) {
+ PMSIHANDLE hRec = MsiCreateRecord(0);
+ if (!hRec)
+ throw std::exception("MsiCreateRecord failed!");
+ MsiRecordSetStringW(hRec, 0, sVal.c_str());
+ DWORD nSz = 0;
+ if (MsiFormatRecordW(hInstall, hRec, const_cast<wchar_t*>(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 (!sRegStr.empty())
+ SetFormattedPropW(L"reg_dlls", sRegStr);
+ if (!sUnregStr.empty())
+ SetFormattedPropW(L"unreg_dlls", sUnregStr);
+ }
+ 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 000000000..d0f31c491
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg_dlls/reg_dlls.def
@@ -0,0 +1,5 @@
+LIBRARY "reg_dlls.dll"
+EXPORTS
+ RegDLLs
+ UnregDLLs
+ PrepRegUnregDLLs
diff --git a/setup_native/source/win32/customactions/regactivex/regactivex.cxx b/setup_native/source/win32/customactions/regactivex/regactivex.cxx
new file mode 100644
index 000000000..48b11bd4f
--- /dev/null
+++ b/setup_native/source/win32/customactions/regactivex/regactivex.cxx
@@ -0,0 +1,344 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <msiquery.h>
+
+#include <cassert>
+#include <string.h>
+#include <malloc.h>
+
+#define CHART_COMPONENT 1
+#define DRAW_COMPONENT 2
+#define IMPRESS_COMPONENT 4
+#define CALC_COMPONENT 8
+#define WRITER_COMPONENT 16
+#define MATH_COMPONENT 32
+
+typedef int ( __stdcall * DllNativeRegProc ) ( int, BOOL, BOOL, const wchar_t* );
+typedef int ( __stdcall * DllNativeUnregProc ) ( int, BOOL, BOOL );
+
+static bool UnicodeEquals( wchar_t const * pStr1, wchar_t const * pStr2 )
+{
+ if ( pStr1 == nullptr && pStr2 == nullptr )
+ return true;
+ else if ( pStr1 == nullptr || pStr2 == nullptr )
+ return false;
+
+ while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
+ {
+ pStr1++;
+ pStr2++;
+ }
+
+ return ( *pStr1 == 0 && *pStr2 == 0 );
+}
+
+
+static void RegisterActiveXNative( const wchar_t* pActiveXPath, int nMode, bool InstallForAllUser, bool InstallFor64Bit )
+{
+ HINSTANCE hModule = LoadLibraryExW( pActiveXPath, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH );
+ if( hModule )
+ {
+ DllNativeRegProc pNativeProc = reinterpret_cast<DllNativeRegProc>(GetProcAddress( hModule, "DllRegisterServerNative" ));
+ if( pNativeProc!=nullptr )
+ {
+ int nLen = wcslen( pActiveXPath );
+ int nRemoveLen = strlen( "\\so_activex.dll" );
+ if ( nLen > nRemoveLen )
+ {
+ wchar_t* pProgramPath = static_cast<wchar_t*>( malloc( (nLen - nRemoveLen + 1) * sizeof(wchar_t) ) );
+ assert(pProgramPath); // Don't handle OOM conditions
+ wcsncpy( pProgramPath, pActiveXPath, nLen - nRemoveLen );
+ pProgramPath[ nLen - nRemoveLen ] = 0;
+
+ ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit, pProgramPath );
+
+ free( pProgramPath );
+ }
+ }
+
+ FreeLibrary( hModule );
+ }
+}
+
+
+static void UnregisterActiveXNative( const wchar_t* pActiveXPath, int nMode, bool InstallForAllUser, bool InstallFor64Bit )
+{
+ HINSTANCE hModule = LoadLibraryExW( pActiveXPath, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH );
+ if( hModule )
+ {
+ DllNativeUnregProc pNativeProc = reinterpret_cast<DllNativeUnregProc>(GetProcAddress( hModule, "DllUnregisterServerNative" ));
+ if( pNativeProc!=nullptr )
+ ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit );
+
+ FreeLibrary( hModule );
+ }
+}
+
+
+static bool GetMsiPropW( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
+{
+ DWORD sz = 0;
+ if ( MsiGetPropertyW( hMSI, pPropName, const_cast<wchar_t *>(L""), &sz ) == ERROR_MORE_DATA )
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof( wchar_t );
+ wchar_t* buff = static_cast<wchar_t*>( malloc( nbytes ) );
+ assert(buff); // Don't handle OOM conditions
+ ZeroMemory( buff, nbytes );
+ MsiGetPropertyW( hMSI, pPropName, buff, &sz );
+ *ppValue = buff;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+static bool GetActiveXControlPath( MSIHANDLE hMSI, wchar_t** ppActiveXPath )
+{
+ wchar_t* pProgPath = nullptr;
+ if ( GetMsiPropW( hMSI, L"INSTALLLOCATION", &pProgPath ) && pProgPath )
+ {
+ int nLen = wcslen( pProgPath );
+ *ppActiveXPath = static_cast<wchar_t*>( malloc( (nLen + 23) * sizeof(wchar_t) ) );
+ wcsncpy( *ppActiveXPath, pProgPath, nLen );
+ wcsncpy( (*ppActiveXPath) + nLen, L"program\\so_activex.dll", 22 );
+ (*ppActiveXPath)[nLen+22] = 0;
+
+ free(pProgPath);
+
+ return true;
+ }
+
+ return false;
+}
+
+
+static bool GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDeinstallMode )
+{
+ // for now the chart is always installed
+ nOldInstallMode = CHART_COMPONENT;
+ nInstallMode = CHART_COMPONENT;
+ nDeinstallMode = 0;
+
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+
+ if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Wrt_Bin", &current_state, &future_state ) )
+ {
+ // analyze writer installation mode
+ if ( current_state == INSTALLSTATE_LOCAL )
+ nOldInstallMode |= WRITER_COMPONENT;
+
+ if ( future_state == INSTALLSTATE_LOCAL
+ || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
+ nInstallMode |= WRITER_COMPONENT;
+ else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
+ nDeinstallMode |= WRITER_COMPONENT;
+ }
+ else
+ {
+ // assert( FALSE );
+ }
+
+ if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Calc_Bin", &current_state, &future_state ) )
+ {
+ // analyze calc installation mode
+ if ( current_state == INSTALLSTATE_LOCAL )
+ nOldInstallMode |= CALC_COMPONENT;
+
+ if ( future_state == INSTALLSTATE_LOCAL
+ || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
+ nInstallMode |= CALC_COMPONENT;
+ else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
+ nDeinstallMode |= CALC_COMPONENT;
+ }
+ else
+ {
+ // assert( FALSE );
+ }
+
+ if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Draw_Bin", &current_state, &future_state ) )
+ {
+ // analyze draw installation mode
+ if ( current_state == INSTALLSTATE_LOCAL )
+ nOldInstallMode |= DRAW_COMPONENT;
+
+ if ( future_state == INSTALLSTATE_LOCAL
+ || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
+ nInstallMode |= DRAW_COMPONENT;
+ else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
+ nDeinstallMode |= DRAW_COMPONENT;
+ }
+ else
+ {
+ // assert( FALSE );
+ }
+
+ if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Impress_Bin", &current_state, &future_state ) )
+ {
+ // analyze impress installation mode
+ if ( current_state == INSTALLSTATE_LOCAL )
+ nOldInstallMode |= IMPRESS_COMPONENT;
+
+ if ( future_state == INSTALLSTATE_LOCAL
+ || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
+ nInstallMode |= IMPRESS_COMPONENT;
+ else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
+ nDeinstallMode |= IMPRESS_COMPONENT;
+ }
+ else
+ {
+ // assert( FALSE );
+ }
+
+ if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Math_Bin", &current_state, &future_state ) )
+ {
+ // analyze math installation mode
+ if ( current_state == INSTALLSTATE_LOCAL )
+ nOldInstallMode |= MATH_COMPONENT;
+
+ if ( future_state == INSTALLSTATE_LOCAL
+ || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
+ nInstallMode |= MATH_COMPONENT;
+ else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
+ nDeinstallMode |= MATH_COMPONENT;
+ }
+ else
+ {
+ // assert( FALSE );
+ }
+
+ return true;
+}
+
+
+static bool MakeInstallForAllUsers( MSIHANDLE hMSI )
+{
+ bool bResult = false;
+ wchar_t* pVal = nullptr;
+ if ( GetMsiPropW( hMSI, L"ALLUSERS", &pVal ) && pVal )
+ {
+ bResult = UnicodeEquals( pVal , L"1" );
+ free( pVal );
+ }
+
+ return bResult;
+}
+
+
+static bool MakeInstallFor64Bit( MSIHANDLE hMSI )
+{
+ bool bResult = false;
+ wchar_t* pVal = nullptr;
+ if ( GetMsiPropW( hMSI, L"VersionNT64", &pVal ) && pVal )
+ {
+ bResult = true;
+ free( pVal );
+ }
+
+ return bResult;
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall InstallActiveXControl( MSIHANDLE hMSI )
+{
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+
+ if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
+ {
+ int nOldInstallMode = 0;
+ int nInstallMode = 0;
+ int nDeinstallMode = 0;
+ bool bInstallForAllUser = MakeInstallForAllUsers( hMSI );
+ bool bInstallFor64Bit = MakeInstallFor64Bit( hMSI );
+
+ wchar_t* pActiveXPath = nullptr;
+ if ( GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath
+ && GetDelta( hMSI, nOldInstallMode, nInstallMode, nDeinstallMode ) )
+ {
+ if ( future_state == INSTALLSTATE_LOCAL
+ || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
+ {
+ // the control is installed in the new selected configuration
+
+ if ( current_state == INSTALLSTATE_LOCAL && nDeinstallMode )
+ UnregisterActiveXNative( pActiveXPath, nDeinstallMode, bInstallForAllUser, bInstallFor64Bit );
+
+ if ( nInstallMode )
+ RegisterActiveXNative( pActiveXPath, nInstallMode, bInstallForAllUser, bInstallFor64Bit );
+ }
+ else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
+ {
+ if ( nOldInstallMode )
+ UnregisterActiveXNative( pActiveXPath, nOldInstallMode, bInstallForAllUser, bInstallFor64Bit );
+ }
+ }
+
+ if ( pActiveXPath )
+ free( pActiveXPath );
+ }
+ else
+ {
+ // assert( FALSE );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+extern "C" __declspec(dllexport) UINT __stdcall DeinstallActiveXControl( MSIHANDLE hMSI )
+{
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+
+ if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
+ {
+ wchar_t* pActiveXPath = nullptr;
+ if ( current_state == INSTALLSTATE_LOCAL && GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath )
+ {
+ bool bInstallForAllUser = MakeInstallForAllUsers( hMSI );
+ bool bInstallFor64Bit = MakeInstallFor64Bit( hMSI );
+
+ {
+ UnregisterActiveXNative( pActiveXPath,
+ CHART_COMPONENT
+ | DRAW_COMPONENT
+ | IMPRESS_COMPONENT
+ | CALC_COMPONENT
+ | WRITER_COMPONENT
+ | MATH_COMPONENT,
+ bInstallForAllUser,
+ bInstallFor64Bit );
+ }
+
+ free( pActiveXPath );
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/regactivex/regactivex.def b/setup_native/source/win32/customactions/regactivex/regactivex.def
new file mode 100644
index 000000000..8a4c744d7
--- /dev/null
+++ b/setup_native/source/win32/customactions/regactivex/regactivex.def
@@ -0,0 +1,4 @@
+LIBRARY "regactivex.dll"
+EXPORTS
+ InstallActiveXControl
+ DeinstallActiveXControl \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/sellang/sellang.cxx b/setup_native/source/win32/customactions/sellang/sellang.cxx
new file mode 100644
index 000000000..3154e1190
--- /dev/null
+++ b/setup_native/source/win32/customactions/sellang/sellang.cxx
@@ -0,0 +1,387 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/* Currently the "all" installer has a bit over 100 UI languages, and
+ * I doubt it will grow a lot over that.
+ */
+#define MAX_LANGUAGES 200
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#include <malloc.h>
+
+#include <cassert>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sal/macros.h>
+#include <systools/win32/uwinapi.h>
+#include <algorithm>
+
+#include <spellchecker_selection.hxx>
+
+static bool GetMsiPropA( MSIHANDLE hMSI, const char* pPropName, char** ppValue )
+{
+ DWORD sz = 0;
+ if ( MsiGetPropertyA( hMSI, pPropName, const_cast<char *>(""), &sz ) == ERROR_MORE_DATA ) {
+ sz++;
+ DWORD nbytes = sz * sizeof( char );
+ char* buff = static_cast<char*>( malloc( nbytes ) );
+ assert(buff); // Don't handle OOM conditions
+ ZeroMemory( buff, nbytes );
+ MsiGetPropertyA( hMSI, pPropName, buff, &sz );
+ *ppValue = buff;
+ return ( strlen(buff) > 0 );
+ }
+ return false;
+}
+
+static const char *
+langid_to_string( LANGID langid )
+{
+ /* Map from LANGID to string. The languages below are now in
+ * alphabetical order of codes as in
+ * l10ntools/source/ulfconv/msi-encodinglist.txt. Only the
+ * language part is returned in the string.
+ */
+ switch (PRIMARYLANGID (langid)) {
+ case LANG_AFRIKAANS: return "af";
+ case LANG_AMHARIC: return "am";
+ case LANG_ARABIC: return "ar";
+ case LANG_ASSAMESE: return "as";
+ case LANG_BELARUSIAN: return "be";
+ case LANG_BULGARIAN: return "bg";
+ case LANG_BENGALI: return "bn";
+ case LANG_BRETON: return "br";
+ case LANG_CATALAN: return "ca";
+ case LANG_CZECH: return "cs";
+ case LANG_WELSH: return "cy";
+ case LANG_DANISH: return "da";
+ case LANG_GERMAN: return "de";
+ case LANG_GREEK: return "el";
+ case LANG_ENGLISH: return "en";
+ case LANG_SPANISH: return "es";
+ case LANG_ESTONIAN: return "et";
+ case LANG_BASQUE: return "eu";
+ case LANG_FARSI: return "fa";
+ case LANG_FINNISH: return "fi";
+ case LANG_FAEROESE: return "fo";
+ case LANG_FRENCH: return "fr";
+ case LANG_IRISH: return "ga";
+ case LANG_GALICIAN: return "gl";
+ case LANG_GUJARATI: return "gu";
+ case LANG_HEBREW: return "he";
+ case LANG_HINDI: return "hi";
+ case LANG_HUNGARIAN: return "hu";
+ case LANG_ARMENIAN: return "hy";
+ case LANG_INDONESIAN: return "id";
+ case LANG_ICELANDIC: return "is";
+ case LANG_ITALIAN: return "it";
+ case LANG_JAPANESE: return "ja";
+ case LANG_GEORGIAN: return "ka";
+ case LANG_KAZAK: return "kk";
+ case LANG_KHMER: return "km";
+ case LANG_KANNADA: return "kn";
+ case LANG_KOREAN: return "ko";
+ case LANG_KASHMIRI: return "ks";
+ case LANG_LAO: return "lo";
+ case LANG_LITHUANIAN: return "lt";
+ case LANG_LATVIAN: return "lv";
+ case LANG_MACEDONIAN: return "mk";
+ case LANG_MALAYALAM: return "ml";
+ case LANG_MONGOLIAN: return "mn";
+ case LANG_MARATHI: return "mr";
+ case LANG_MALAY: return "ms";
+ case LANG_MALTESE: return "mt";
+ case LANG_NEPALI: return "ne";
+ case LANG_DUTCH: return "nl";
+ case LANG_SOTHO: return "ns";
+ case LANG_ORIYA: return "or";
+ case LANG_PUNJABI: return "pa";
+ case LANG_POLISH: return "pl";
+ case LANG_PORTUGUESE: return "pt";
+ case LANG_ROMANSH: return "rm";
+ case LANG_ROMANIAN: return "ro";
+ case LANG_RUSSIAN: return "ru";
+ case LANG_KINYARWANDA: return "rw";
+ case LANG_SANSKRIT: return "sa";
+ case LANG_UPPER_SORBIAN: return "sb";
+ case LANG_SINDHI: return "sd";
+ case LANG_SLOVAK: return "sk";
+ case LANG_SLOVENIAN: return "sl";
+ case LANG_ALBANIAN: return "sq";
+ case LANG_SWEDISH: return "sv";
+ case LANG_SWAHILI: return "sw";
+ case LANG_TAMIL: return "ta";
+ case LANG_TELUGU: return "te";
+ case LANG_TAJIK: return "tg";
+ case LANG_THAI: return "th";
+ case LANG_TIGRIGNA: return "ti";
+ case LANG_TSWANA: return "tn";
+ case LANG_TURKISH: return "tr";
+ case LANG_TATAR: return "tt";
+ case LANG_UKRAINIAN: return "uk";
+ case LANG_URDU: return "ur";
+ case LANG_UZBEK: return "uz";
+ case LANG_VIETNAMESE: return "vi";
+ case LANG_XHOSA: return "xh";
+ case LANG_CHINESE: return "zh";
+ case LANG_ZULU: return "zu";
+ /* Special cases */
+ default:
+ switch (langid) {
+ case MAKELANGID(LANG_SERBIAN, 0x05): return "bs";
+ case MAKELANGID(LANG_SERBIAN, SUBLANG_DEFAULT): return "hr";
+ case MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL): return "nb";
+ case MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_NYNORSK): return "nn";
+ case MAKELANGID(LANG_SERBIAN, SUBLANG_SERBIAN_LATIN): return "sh";
+ case MAKELANGID(LANG_SERBIAN, SUBLANG_SERBIAN_CYRILLIC): return "sr";
+ default: return nullptr;
+ }
+ }
+}
+
+/* Here we collect the UI languages present on the system;
+ * MAX_LANGUAGES is certainly enough for that
+ */
+static const char *ui_langs[MAX_LANGUAGES];
+static int num_ui_langs = 0;
+
+static void add_ui_lang(char const * lang)
+{
+ if (lang != nullptr && num_ui_langs != SAL_N_ELEMENTS(ui_langs)) {
+ ui_langs[num_ui_langs++] = lang;
+ }
+}
+
+static BOOL CALLBACK
+enum_ui_lang_proc (LPTSTR language, LONG_PTR /* unused_lParam */)
+{
+ long langid = strtol(language, nullptr, 16);
+ if (langid > 0xFFFF)
+ return TRUE;
+ add_ui_lang(langid_to_string(static_cast<LANGID>(langid)));
+ if (num_ui_langs == SAL_N_ELEMENTS(ui_langs) )
+ return FALSE;
+ return TRUE;
+}
+
+static bool
+present_in_ui_langs(const char *lang)
+{
+ for (int i = 0; i < num_ui_langs; i++)
+ {
+ if (strchr (lang, '_') != nullptr)
+ if (memcmp (ui_langs[i], lang, std::min(strlen(ui_langs[i]), strlen(lang))) == 0)
+ return true;
+ if (strcmp (ui_langs[i], lang) == 0)
+ return true;
+ }
+ return false;
+}
+
+namespace {
+
+/* TODO-BCP47: unlimit this, and if possible change from '_' to '-' separator
+ * to ease things. */
+// XXX NOTE: the sizeof needs to follow what is accepted in
+// setup_native/source/packinfo/spellchecker_selection.pl
+struct InstallLocalized {
+ char lang[sizeof("lll_Ssss_CC_vvvvvvvv")];
+ bool install;
+};
+
+void addMatchingDictionaries(
+ char const * lang, InstallLocalized * dicts, int ndicts)
+{
+ for (int i = 0; i != SAL_N_ELEMENTS(setup_native::languageDictionaries);
+ ++i)
+ {
+ if (strcmp(lang, setup_native::languageDictionaries[i].language) == 0) {
+ for (char const * const * p = setup_native::languageDictionaries[i].
+ dictionaries;
+ *p != nullptr; ++p)
+ {
+ for (int j = 0; j != ndicts; ++j) {
+ if (_stricmp(*p, dicts[j].lang) == 0) {
+ dicts[j].install = true;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall SelectLanguage( MSIHANDLE handle )
+{
+ char feature[100];
+ MSIHANDLE database, view, record;
+ DWORD length;
+ int nlangs = 0;
+ InstallLocalized langs[MAX_LANGUAGES];
+ int ndicts = 0;
+ InstallLocalized dicts[MAX_LANGUAGES];
+
+ database = MsiGetActiveDatabase(handle);
+
+ if (MsiDatabaseOpenViewA(database, "SELECT Feature from Feature WHERE Feature_Parent = 'gm_Langpack_Languageroot'", &view) != ERROR_SUCCESS) {
+ MsiCloseHandle(database);
+ return ERROR_SUCCESS;
+ }
+
+ if (MsiViewExecute(view, NULL) != ERROR_SUCCESS) {
+ MsiCloseHandle(view);
+ MsiCloseHandle(database);
+ return ERROR_SUCCESS;
+ }
+
+ while (nlangs < MAX_LANGUAGES &&
+ MsiViewFetch(view, &record) == ERROR_SUCCESS) {
+ length = sizeof(feature);
+ if (MsiRecordGetStringA(record, 1, feature, &length) != ERROR_SUCCESS) {
+ MsiCloseHandle(record);
+ MsiCloseHandle(view);
+ MsiCloseHandle(database);
+ return ERROR_SUCCESS;
+ }
+
+ /* Keep track of what langpacks are included in this installer.
+ */
+ strcpy(langs[nlangs].lang, feature + strlen("gm_Langpack_r_"));
+ langs[nlangs].install = false;
+ ++nlangs;
+
+ MsiCloseHandle(record);
+ }
+
+ MsiCloseHandle(view);
+
+ /* Keep track of what dictionaries are included in this installer:
+ */
+ if (MsiDatabaseOpenViewA(
+ database,
+ ("SELECT Feature from Feature WHERE"
+ " Feature_Parent = 'gm_Dictionaries'"),
+ &view)
+ == ERROR_SUCCESS)
+ {
+ if (MsiViewExecute(view, NULL) == ERROR_SUCCESS) {
+ while (ndicts < MAX_LANGUAGES &&
+ MsiViewFetch(view, &record) == ERROR_SUCCESS)
+ {
+ length = sizeof(feature);
+ if (MsiRecordGetStringA(record, 1, feature, &length)
+ == ERROR_SUCCESS)
+ {
+ if (strncmp(
+ feature, "gm_r_ex_Dictionary_",
+ strlen("gm_r_ex_Dictionary_"))
+ == 0)
+ {
+ strcpy(
+ dicts[ndicts].lang,
+ feature + strlen("gm_r_ex_Dictionary_"));
+ dicts[ndicts].install = false;
+ ++ndicts;
+ }
+ }
+ MsiCloseHandle(record);
+ }
+ }
+ MsiCloseHandle(view);
+ }
+
+ /* Keep track of what UI languages are relevant, either the ones explicitly
+ * requested with the UI_LANGS property, or all available on the system:
+ */
+ char* pVal = nullptr;
+ if ( (GetMsiPropA( handle, "UI_LANGS", &pVal )) && pVal ) {
+ char *str_ptr;
+ str_ptr = strtok(pVal, ",");
+ for(; str_ptr != nullptr ;) {
+ add_ui_lang(str_ptr);
+ str_ptr = strtok(nullptr, ",");
+ }
+ } else {
+ add_ui_lang(langid_to_string(GetSystemDefaultUILanguage()));
+ add_ui_lang(langid_to_string(LANGIDFROMLCID(GetThreadLocale())));
+ //TODO: are the above two explicit additions necessary, or will
+ // those values always be included in the below EnumUILanguages
+ // anyway?
+ EnumUILanguagesA(enum_ui_lang_proc, 0, 0);
+ }
+
+ // If the set of langpacks that match any of the relevant UI languages is
+ // non-empty, select just those matching langpacks; otherwise, if an en_US
+ // langpack is included, select just that langpack (this happens if, e.g.,
+ // a multi-language en-US,de,es,fr,it,pt-BR installation set is installed on
+ // a Finnish Windows); otherwise, select all langpacks (this happens if,
+ // e.g., a single-language de installation set is installed on a Finnish
+ // Windows):
+ bool matches = false;
+ for (int i = 0; i < nlangs; i++) {
+ if (present_in_ui_langs(langs[i].lang)) {
+ langs[i].install = true;
+ matches = true;
+ }
+ }
+ if (!matches) {
+ for (int i = 0; i < nlangs; i++) {
+ if (strcmp(langs[i].lang, "en_US") == 0) {
+ langs[i].install = true;
+ matches = true;
+ break;
+ }
+ }
+ if (!matches) {
+ for (int i = 0; i < nlangs; i++) {
+ langs[i].install = true;
+ }
+ }
+ }
+
+ for (int i = 0; i < nlangs; i++) {
+ if (langs[i].install) {
+ addMatchingDictionaries(langs[i].lang, dicts, ndicts);
+ } else {
+ sprintf(feature, "gm_Langpack_r_%s", langs[i].lang);
+ MsiSetFeatureStateA(handle, feature, INSTALLSTATE_ABSENT);
+ }
+ }
+
+ // Select just those dictionaries that match any of the selected langpacks:
+ for (int i = 0; i != ndicts; ++i) {
+ if (!dicts[i].install) {
+ sprintf(feature, "gm_r_ex_Dictionary_%s", dicts[i].lang);
+ MsiSetFeatureStateA(handle, feature, INSTALLSTATE_ABSENT);
+ }
+ }
+
+ MsiCloseHandle(database);
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/sellang/sellang.def b/setup_native/source/win32/customactions/sellang/sellang.def
new file mode 100644
index 000000000..8d3c4d44c
--- /dev/null
+++ b/setup_native/source/win32/customactions/sellang/sellang.def
@@ -0,0 +1,4 @@
+LIBRARY "sellangmsi.dll"
+EXPORTS
+ SelectLanguage
+ SortTree \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/sellang/sorttree.cxx b/setup_native/source/win32/customactions/sellang/sorttree.cxx
new file mode 100644
index 000000000..cb44675b9
--- /dev/null
+++ b/setup_native/source/win32/customactions/sellang/sorttree.cxx
@@ -0,0 +1,55 @@
+/* -*- 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/.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msi.h>
+#include <commctrl.h>
+
+extern "C" __declspec(dllexport) UINT __stdcall SortTree(MSIHANDLE)
+{
+ // Sort items (languages) in SelectionTree control, fdo#46355
+
+ HWND hwndMSI = FindWindowW(L"MsiDialogCloseClass", nullptr);
+ if (hwndMSI == nullptr)
+ {
+ OutputDebugStringW(L"SortTree: MsiDialogCloseClass not found\n");
+ return ERROR_SUCCESS;
+ }
+ HWND hwndTV = FindWindowExW(hwndMSI, nullptr, L"SysTreeView32", nullptr);
+ if (hwndTV == nullptr)
+ {
+ OutputDebugStringW(L"SortTree: SysTreeView32 not found\n");
+ return ERROR_SUCCESS;
+ }
+ HTREEITEM optional = TreeView_GetRoot(hwndTV);
+ if (optional == nullptr)
+ {
+ OutputDebugStringW(L"SortTree: Optional Components branch not found\n");
+ return ERROR_SUCCESS;
+ }
+ HTREEITEM dicts = TreeView_GetChild(hwndTV, optional);
+ if (dicts == nullptr)
+ {
+ OutputDebugStringW(L"SortTree: Dictionaries branch not found\n");
+ return ERROR_SUCCESS;
+ }
+ TreeView_SortChildren(hwndTV, dicts, TRUE);
+ HTREEITEM langs = TreeView_GetNextSibling(hwndTV, optional);
+ if (langs == nullptr)
+ {
+ OutputDebugStringW(L"SortTree: Additional UI Languages branch not found\n");
+ return ERROR_SUCCESS;
+ }
+ TreeView_SortChildren(hwndTV, langs, TRUE);
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx b/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
new file mode 100644
index 000000000..5c6865995
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
@@ -0,0 +1,66 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "shlxtmsi.hxx"
+
+#include <malloc.h>
+#include <assert.h>
+
+#include <queue>
+#include <stdio.h>
+
+#include <systools/win32/uwinapi.h>
+#include "../tools/seterror.hxx"
+
+extern "C" __declspec(dllexport) UINT __stdcall CheckInstallDirectory(MSIHANDLE handle)
+{
+ std::wstring sInstallPath = GetMsiPropertyW(handle, L"INSTALLLOCATION");
+ std::wstring sOfficeHostnamePath = GetMsiPropertyW(handle, L"OFFICEDIRHOSTNAME");
+
+ // MessageBoxW(NULL, sInstallPath.c_str(), L"DEBUG", MB_OK);
+
+ // unsetting all properties
+
+ UnsetMsiPropertyW( handle, L"DIRECTORY_NOT_EMPTY" );
+
+ // 1. Searching for file setup.ini
+
+ std::wstring sSetupIniPath = sInstallPath + sOfficeHostnamePath + L"\\program\\setup.ini";
+
+ WIN32_FIND_DATAW data;
+ HANDLE hdl = FindFirstFileW(sSetupIniPath.c_str(), &data);
+
+ // std::wstring mystr = L"Searching for " + sSetupIniPath;
+ // MessageBoxW(NULL, mystr.c_str(), L"DEBUG", MB_OK);
+
+ if ( IsValidHandle(hdl) )
+ {
+ // setup.ini found -> directory cannot be used for installation.
+ SetMsiPropertyW( handle, L"DIRECTORY_NOT_EMPTY", L"1" );
+ SetMsiErrorCode( MSI_ERROR_DIRECTORY_NOT_EMPTY );
+ // std::wstring notEmptyStr = L"Directory is not empty. Please choose another installation directory.";
+ // std::wstring notEmptyTitle = L"Directory not empty";
+ // MessageBoxW(NULL, notEmptyStr.c_str(), notEmptyTitle.c_str(), MB_OK);
+ FindClose(hdl);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx b/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx
new file mode 100644
index 000000000..0a879dc1b
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx
@@ -0,0 +1,59 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "shlxtmsi.hxx"
+#include <strsafe.h>
+#include <systools/win32/uwinapi.h>
+
+#ifdef DEBUG
+inline void OutputDebugStringFormatW( PCWSTR pFormat, ... )
+{
+ WCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfW( buffer, SAL_N_ELEMENTS(buffer), pFormat, args );
+ OutputDebugStringW( buffer );
+ va_end(args);
+}
+#else
+static void OutputDebugStringFormatW( PCWSTR, ... )
+{
+}
+#endif
+
+extern "C" __declspec(dllexport) UINT __stdcall CheckPatchList( MSIHANDLE handle )
+{
+ std::wstring sPatchList = GetMsiPropertyW( handle, L"PATCH" );
+ std::wstring sRequiredPatch = GetMsiPropertyW( handle, L"PREREQUIREDPATCH" );
+
+ OutputDebugStringFormatW( L"CheckPatchList called with PATCH=%s and PRQ=%s\n", sPatchList.c_str(), sRequiredPatch.c_str() );
+
+ if ( ( sPatchList.length() != 0 ) && ( sRequiredPatch.length() != 0 ) )
+ {
+ if ( wcsstr( sPatchList.c_str(), sRequiredPatch.c_str() ) )
+ {
+ SetMsiPropertyW( handle, L"IGNOREPREREQUIREDPATCH", L"1" );
+ OutputDebugStringFormatW( L"Set Property IgnorePrerequiredPatch!\n" );
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/completeinstallpath.cxx b/setup_native/source/win32/customactions/shellextensions/completeinstallpath.cxx
new file mode 100644
index 000000000..787041ed8
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/completeinstallpath.cxx
@@ -0,0 +1,116 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "shlxtmsi.hxx"
+
+#include <malloc.h>
+
+extern "C" __declspec(dllexport) UINT __stdcall CompleteInstallPath( MSIHANDLE handle )
+{
+ // This CustomAction is necessary for updates from OOo 3.0, OOo 3.1 and OOo 3.2 to versions
+ // OOo 3.3 or later. This is caused by a change of INSTALLLOCATION, that starting with OOo 3.3
+ // contains the name of the product again (instead of only "c:\program files"). Unfortunately
+ // this causes in an update installation, that INSTALLLOCATION is set to "c:\program files",
+ // so that in an OOo 3.3 or later, the directory "program" or "share" are directly created
+ // below "c:\program files".
+
+ HKEY hKey;
+
+ // Reading property OFFICEDIRHOSTNAME_, that contains the part of the path behind
+ // the program files folder.
+
+ std::wstring sInstallLocation = GetMsiPropertyW( handle, L"INSTALLLOCATION" );
+ std::wstring sOfficeDirHostname = GetMsiPropertyW( handle, L"OFFICEDIRHOSTNAME_" );
+
+ // If sInstallLocation ends with (contains) the string sOfficeDirHostname,
+ // INSTALLLOCATION is good and nothing has to be done here.
+
+ bool pathCompletionRequired = true;
+
+ if ( wcsstr( sInstallLocation.c_str(), sOfficeDirHostname.c_str() ) )
+ {
+ pathCompletionRequired = false; // nothing to do
+ }
+
+ // If the path INSTALLLOCATION does not end with this string, INSTALLLOCATION is maybe
+ // transferred from an OOo 3.0, OOo 3.1 and OOo 3.2 and need to be changed therefore.
+
+ if ( pathCompletionRequired )
+ {
+ std::wstring sManufacturer = GetMsiPropertyW( handle, L"Manufacturer" );
+ std::wstring sDefinedName = GetMsiPropertyW( handle, L"DEFINEDPRODUCT" );
+ std::wstring sUpgradeCode = GetMsiPropertyW( handle, L"UpgradeCode" );
+
+ // sUpdateVersion can be "3.0", "3.1" or "3.2"
+
+ std::wstring sProductKey30 = L"Software\\" + sManufacturer + L"\\" + sDefinedName +
+ L"\\" L"3.0" L"\\" + sUpgradeCode;
+
+ std::wstring sProductKey31 = L"Software\\" + sManufacturer + L"\\" + sDefinedName +
+ L"\\" L"3.1" L"\\" + sUpgradeCode;
+
+ std::wstring sProductKey32 = L"Software\\" + sManufacturer + L"\\" + sDefinedName +
+ L"\\" L"3.2" L"\\" + sUpgradeCode;
+
+ bool oldVersionExists = false;
+
+ if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_CURRENT_USER, sProductKey30.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_CURRENT_USER, sProductKey31.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_CURRENT_USER, sProductKey32.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_LOCAL_MACHINE, sProductKey30.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_LOCAL_MACHINE, sProductKey31.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_LOCAL_MACHINE, sProductKey32.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+
+ if ( oldVersionExists )
+ {
+ // Adding the new path content sOfficeDirHostname
+ sInstallLocation += sOfficeDirHostname;
+ // Setting the new property value
+ MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstallLocation.c_str());
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
new file mode 100644
index 000000000..10c817169
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
@@ -0,0 +1,96 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "shlxtmsi.hxx"
+#include <algorithm>
+#include <sstream>
+#include <systools/win32/uwinapi.h>
+
+extern "C" __declspec(dllexport) UINT __stdcall MigrateInstallPath(MSIHANDLE handle)
+{
+ std::wstring sInstDir = GetMsiPropertyW(handle, L"INSTALLLOCATION");
+ if (!sInstDir.empty())
+ return ERROR_SUCCESS; // Don't overwrite explicitly set value
+
+ auto RegValue = [](HKEY hRoot, const WCHAR* sKey, const WCHAR* sVal) {
+ std::wstring sResult;
+ WCHAR buf[32767]; // max longpath
+ DWORD bufsize = sizeof(buf); // yes, it is the number of bytes
+ if (RegGetValueW(hRoot, sKey, sVal, RRF_RT_REG_SZ, nullptr, buf, &bufsize) == ERROR_SUCCESS)
+ sResult = buf; // RegGetValueW null-terminates strings
+
+ return sResult;
+ };
+
+ const std::wstring sManufacturer = GetMsiPropertyW( handle, L"Manufacturer" );
+ const std::wstring sDefinedName = GetMsiPropertyW( handle, L"DEFINEDPRODUCT" );
+ const std::wstring sUpdateVersion = GetMsiPropertyW( handle, L"DEFINEDVERSION" );
+ const std::wstring sUpgradeCode = GetMsiPropertyW( handle, L"UpgradeCode" );
+ const std::wstring sBrandPackageVersion = GetMsiPropertyW(handle, L"BRANDPACKAGEVERSION");
+
+ std::wstring sKey = L"Software\\" + sManufacturer + L"\\" + sDefinedName +
+ L"\\" + sUpdateVersion + L"\\" + sUpgradeCode;
+
+ sInstDir = RegValue(HKEY_CURRENT_USER, sKey.c_str(), L"INSTALLLOCATION");
+ if (sInstDir.empty())
+ sInstDir = RegValue(HKEY_LOCAL_MACHINE, sKey.c_str(), L"INSTALLLOCATION");
+ // See #i93032# for layers description
+ if (sInstDir.empty())
+ {
+ sKey = L"Software\\LibreOffice\\Layers\\" + sDefinedName + L"\\" + sBrandPackageVersion;
+ sInstDir = RegValue(HKEY_CURRENT_USER, sKey.c_str(), L"INSTALLLOCATION");
+ }
+ if (sInstDir.empty())
+ {
+ sKey = L"Software\\LibreOffice\\Layers_\\" + sDefinedName + L"\\" + sBrandPackageVersion;
+ sInstDir = RegValue(HKEY_CURRENT_USER, sKey.c_str(), L"INSTALLLOCATION");
+ }
+ if (sInstDir.empty())
+ {
+ sKey = L"Software\\LibreOffice\\Layers\\" + sDefinedName + L"\\" + sBrandPackageVersion;
+ sInstDir = RegValue(HKEY_LOCAL_MACHINE, sKey.c_str(), L"INSTALLLOCATION");
+ }
+ if (sInstDir.empty())
+ {
+ sKey = L"Software\\LibreOffice\\Layers_\\" + sDefinedName + L"\\" + sBrandPackageVersion;
+ sInstDir = RegValue(HKEY_LOCAL_MACHINE, sKey.c_str(), L"INSTALLLOCATION");
+ }
+ if (sInstDir.empty())
+ {
+ std::wistringstream sOlds{ GetMsiPropertyW(handle, L"OLDPRODUCTS") };
+ std::wstring sOld;
+ while (std::getline(sOlds, sOld, L';'))
+ {
+ if (sOld.empty())
+ continue;
+ sKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + sOld;
+ sInstDir = RegValue(HKEY_LOCAL_MACHINE, sKey.c_str(), L"InstallLocation");
+ if (!sInstDir.empty())
+ break;
+ }
+ }
+
+ if (!sInstDir.empty())
+ MsiSetPropertyW(handle, L"INSTALLLOCATION", sInstDir.c_str());
+
+ return ERROR_SUCCESS;
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/shlxtmsi.def b/setup_native/source/win32/customactions/shellextensions/shlxtmsi.def
new file mode 100644
index 000000000..e0e667953
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/shlxtmsi.def
@@ -0,0 +1,11 @@
+LIBRARY "shlxtmsi.dll"
+EXPORTS
+ CheckInstallDirectory
+ CheckPatchList
+ CompleteInstallPath
+ MigrateInstallPath
+ InstallStartmenuFolderIcon
+ DeinstallStartmenuFolderIcon
+ SetProductInstallMode
+ RenamePrgFolder
+ RemovePrgFolder
diff --git a/setup_native/source/win32/customactions/shellextensions/shlxtmsi.hxx b/setup_native/source/win32/customactions/shellextensions/shlxtmsi.hxx
new file mode 100644
index 000000000..3a08060be
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/shlxtmsi.hxx
@@ -0,0 +1,59 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SETUP_NATIVE_SOURCE_WIN32_CUSTOMACTIONS_SHELLEXTENSIONS_SHLXTMSI_HXX
+#define INCLUDED_SETUP_NATIVE_SOURCE_WIN32_CUSTOMACTIONS_SHELLEXTENSIONS_SHLXTMSI_HXX
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+
+#include <string>
+
+static inline std::wstring GetMsiPropertyW( MSIHANDLE handle, const std::wstring& sProperty )
+{
+ std::wstring result;
+ WCHAR szDummy[1] = L"";
+ DWORD nChars = 0;
+
+ if ( MsiGetPropertyW( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(WCHAR);
+ PWSTR buffer = static_cast<PWSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetPropertyW( handle, sProperty.c_str(), buffer, &nChars );
+ result = buffer;
+ }
+
+ return result;
+}
+
+static inline void SetMsiPropertyW( MSIHANDLE handle, const std::wstring& sProperty, const std::wstring& sValue )
+{
+ MsiSetPropertyW( handle, sProperty.c_str(), sValue.c_str() );
+}
+
+static inline void UnsetMsiPropertyW( MSIHANDLE handle, const std::wstring& sProperty )
+{
+ MsiSetPropertyW( handle, sProperty.c_str(), nullptr );
+}
+
+#endif // INCLUDED_SETUP_NATIVE_SOURCE_WIN32_CUSTOMACTIONS_SHELLEXTENSIONS_SHLXTMSI_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx b/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx
new file mode 100644
index 000000000..6e95c6e1e
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx
@@ -0,0 +1,63 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "shlxtmsi.hxx"
+
+#include <malloc.h>
+
+/*
+ Called during installation to customize the start menu folder icon.
+ See: http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/custom.asp
+*/
+extern "C" __declspec(dllexport) UINT __stdcall InstallStartmenuFolderIcon( MSIHANDLE handle )
+{
+ std::wstring sOfficeMenuFolder = GetMsiPropertyW( handle, L"OfficeMenuFolder" );
+ std::wstring sDesktopFile = sOfficeMenuFolder + L"Desktop.ini";
+
+ // at the moment there exists no Vista Icon, so we use the default folder icon.
+ // add the icon into desktop/util/verinfo.rc
+
+ // The value '0' is to avoid a message like "You Are Deleting a System Folder" warning when deleting or moving the folder.
+ WritePrivateProfileStringW(
+ L".ShellClassInfo",
+ L"ConfirmFileOp",
+ L"0",
+ sDesktopFile.c_str() );
+
+ SetFileAttributesW( sDesktopFile.c_str(), FILE_ATTRIBUTE_HIDDEN );
+ SetFileAttributesW( sOfficeMenuFolder.c_str(), FILE_ATTRIBUTE_SYSTEM );
+
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall DeinstallStartmenuFolderIcon(MSIHANDLE handle)
+{
+ std::wstring sOfficeMenuFolder = GetMsiPropertyW( handle, L"OfficeMenuFolder" );
+ std::wstring sDesktopFile = sOfficeMenuFolder + L"Desktop.ini";
+
+ SetFileAttributesW( sDesktopFile.c_str(), FILE_ATTRIBUTE_NORMAL );
+ DeleteFileW( sDesktopFile.c_str() );
+
+ SetFileAttributesW( sOfficeMenuFolder.c_str(), FILE_ATTRIBUTE_NORMAL );
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/upgrade.cxx b/setup_native/source/win32/customactions/shellextensions/upgrade.cxx
new file mode 100644
index 000000000..494cfaeda
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/upgrade.cxx
@@ -0,0 +1,158 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "shlxtmsi.hxx"
+
+#include <malloc.h>
+#include <assert.h>
+
+namespace
+{
+ // The provided GUID must be without surrounding '{}'
+ std::wstring GetGuidPart(const std::wstring& guid, int index)
+ {
+ assert((guid.length() == 36) && "No GUID or wrong format!");
+ assert(((index > -1) && (index < 5)) && "Out of range!");
+
+ if (index == 0) return std::wstring(guid.c_str(), 8);
+ if (index == 1) return std::wstring(guid.c_str() + 9, 4);
+ if (index == 2) return std::wstring(guid.c_str() + 14, 4);
+ if (index == 3) return std::wstring(guid.c_str() + 19, 4);
+ if (index == 4) return std::wstring(guid.c_str() + 24, 12);
+
+ return std::wstring();
+ }
+
+ void Swap(wchar_t* p1, wchar_t* p2)
+ {
+ wchar_t tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+ }
+
+ std::wstring Invert(const std::wstring& str)
+ {
+ wchar_t* buff = static_cast<wchar_t*>(_alloca(str.length()*sizeof(wchar_t)));
+ wcsncpy(buff, str.c_str(), str.length());
+
+ wchar_t* front = buff;
+ wchar_t* back = buff + str.length() - 1;
+
+ while (front < back)
+ Swap(front++, back--);
+
+ return std::wstring(buff, str.length());
+ }
+
+ // Convert the upgrade code (which is a GUID) according
+ // to the way the windows installer does when writing it
+ // to the registry
+ // The first 8 bytes will be inverted, from the last
+ // 8 bytes always the nibbles will be inverted for further
+ // details look in the MSDN under compressed registry keys
+ std::wstring ConvertGuid(const std::wstring& guid)
+ {
+ std::wstring convertedGuid;
+
+ std::wstring part = GetGuidPart(guid, 0);
+ convertedGuid = Invert(part);
+
+ part = GetGuidPart(guid, 1);
+ convertedGuid += Invert(part);
+
+ part = GetGuidPart(guid, 2);
+ convertedGuid += Invert(part);
+
+ part = GetGuidPart(guid, 3);
+ convertedGuid += Invert(std::wstring(part.c_str(), 2));
+ convertedGuid += Invert(std::wstring(part.c_str() + 2, 2));
+
+ part = GetGuidPart(guid, 4);
+ int pos = 0;
+ for (int i = 0; i < 6; i++)
+ {
+ convertedGuid += Invert(std::wstring(part.c_str() + pos, 2));
+ pos += 2;
+ }
+ return convertedGuid;
+ }
+
+ bool IsSetMsiPropertyW(MSIHANDLE handle, const std::wstring& sProperty)
+ {
+ return (GetMsiPropertyW(handle, sProperty).length() > 0);
+ }
+
+ void SetMsiPropertyW(MSIHANDLE handle, const std::wstring& sProperty)
+ {
+ MsiSetPropertyW(handle, sProperty.c_str(), L"1");
+ }
+
+ bool RegistryKeyHasUpgradeSubKey(
+ HKEY hRootKey, const std::wstring& regKey, const std::wstring& upgradeKey)
+ {
+ HKEY hKey;
+ if (RegOpenKeyW(hRootKey, regKey.c_str(), &hKey) == ERROR_SUCCESS)
+ {
+ DWORD nSubKeys;
+ DWORD lLongestSubKey;
+
+ if (RegQueryInfoKeyW(
+ hKey, nullptr, nullptr, nullptr, &nSubKeys, &lLongestSubKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS)
+ {
+ LPWSTR buffer = static_cast<LPWSTR>(_alloca((lLongestSubKey + 1)*sizeof(WCHAR)));
+
+ for (DWORD i = 0; i < nSubKeys; i++)
+ {
+ LONG ret = RegEnumKeyW(hKey, i, buffer, lLongestSubKey + 1);
+ if ((ret == ERROR_SUCCESS) && (buffer == upgradeKey))
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+} // namespace
+
+extern "C" __declspec(dllexport) UINT __stdcall SetProductInstallMode(MSIHANDLE handle)
+{
+ std::wstring upgradeCode = GetMsiPropertyW(handle, L"UpgradeCode");
+ upgradeCode = ConvertGuid(std::wstring(upgradeCode.c_str() + 1, upgradeCode.length() - 2));
+
+ // MessageBoxW(NULL, upgradeCode.c_str(), "Debug", MB_OK);
+
+ if (RegistryKeyHasUpgradeSubKey(
+ HKEY_CURRENT_USER,
+ L"Software\\Microsoft\\Installer\\UpgradeCodes",
+ upgradeCode) && IsSetMsiPropertyW(handle, L"ALLUSERS"))
+ {
+ UnsetMsiPropertyW(handle, L"ALLUSERS");
+ // MessageBoxW(NULL, L"ALLUSERS removed", L"DEBUG", MB_OK);
+ }
+ else if (RegistryKeyHasUpgradeSubKey(
+ HKEY_LOCAL_MACHINE,
+ L"Software\\Classes\\Installer\\UpgradeCodes",
+ upgradeCode) && !IsSetMsiPropertyW(handle, L"ALLUSERS"))
+ {
+ SetMsiPropertyW(handle, L"ALLUSERS");
+ // MessageBoxW(NULL, L"ALLUSERS set", L"DEBUG", MB_OK);
+ }
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx b/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx
new file mode 100644
index 000000000..e61f4a43f
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx
@@ -0,0 +1,126 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "shlxtmsi.hxx"
+
+#include <strsafe.h>
+
+#include <systools/win32/uwinapi.h>
+#include "../tools/seterror.hxx"
+
+static bool RemoveCompleteDirectoryW(const std::wstring& rPath)
+{
+ bool bDirectoryRemoved = true;
+
+ std::wstring sPattern = rPath + L"\\" + L"*.*";
+ WIN32_FIND_DATAW aFindData;
+
+ // Finding all content in rPath
+
+ HANDLE hFindContent = FindFirstFileW( sPattern.c_str(), &aFindData );
+
+ if ( hFindContent != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+ std::wstring sCurrentDir = L".";
+ std::wstring sParentDir = L"..";
+
+ do
+ {
+ std::wstring sFileName = aFindData.cFileName;
+
+ if (( wcscmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) &&
+ ( wcscmp(sFileName.c_str(),sParentDir.c_str()) != 0 ))
+ {
+ std::wstring sCompleteFileName = rPath + L"\\" + sFileName;
+
+ if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
+ {
+ RemoveCompleteDirectoryW(sCompleteFileName);
+ }
+ else
+ {
+ DeleteFileW( sCompleteFileName.c_str() );
+ }
+ }
+
+ fNextFile = FindNextFileW( hFindContent, &aFindData );
+
+ } while ( fNextFile );
+
+ FindClose( hFindContent );
+
+ // empty directory can be removed now
+ // RemoveDirectory is only successful, if the last handle to the directory is closed
+ // -> first removing content -> closing handle -> remove empty directory
+
+
+ if( !( RemoveDirectoryW(rPath.c_str()) ) )
+ {
+ bDirectoryRemoved = false;
+ }
+ }
+
+ return bDirectoryRemoved;
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall RenamePrgFolder( MSIHANDLE handle )
+{
+ std::wstring sOfficeInstallPath = GetMsiPropertyW(handle, L"INSTALLLOCATION");
+
+ std::wstring sRenameSrc = sOfficeInstallPath + L"program";
+ std::wstring sRenameDst = sOfficeInstallPath + L"program_old";
+
+ bool bSuccess = MoveFileW( sRenameSrc.c_str(), sRenameDst.c_str() );
+ if ( !bSuccess )
+ {
+ WCHAR sAppend[2] = L"0";
+ for ( int i = 0; i < 10; i++ )
+ {
+ sRenameDst = sOfficeInstallPath + L"program_old" + sAppend;
+ bSuccess = MoveFileW( sRenameSrc.c_str(), sRenameDst.c_str() );
+ if ( bSuccess )
+ break;
+ sAppend[0] += 1;
+ }
+ }
+
+ // ? This succeeds unconditionally, even if bSuccess is false!
+ return ERROR_SUCCESS;
+}
+
+extern "C" __declspec(dllexport) UINT __stdcall RemovePrgFolder( MSIHANDLE handle )
+{
+ std::wstring sOfficeInstallPath = GetMsiPropertyW(handle, L"INSTALLLOCATION");
+ std::wstring sRemoveDir = sOfficeInstallPath + L"program_old";
+
+ RemoveCompleteDirectoryW( sRemoveDir );
+
+ WCHAR sAppend[2] = L"0";
+ for ( int i = 0; i < 10; i++ )
+ {
+ sRemoveDir = sOfficeInstallPath + L"program_old" + sAppend;
+ RemoveCompleteDirectoryW( sRemoveDir );
+ sAppend[0] += 1;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/tools/checkversion.cxx b/setup_native/source/win32/customactions/tools/checkversion.cxx
new file mode 100644
index 000000000..3f0b30f3c
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/checkversion.cxx
@@ -0,0 +1,98 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+
+#include <cassert>
+#include <string.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <strsafe.h>
+
+#include "seterror.hxx"
+
+
+static bool GetMsiPropW( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
+{
+ DWORD sz = 0;
+ if ( MsiGetPropertyW( hMSI, pPropName, const_cast<wchar_t *>(L""), &sz ) == ERROR_MORE_DATA )
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof( wchar_t );
+ wchar_t* buff = static_cast<wchar_t*>( malloc( nbytes ) );
+ assert(buff); // Don't handle OOM conditions
+ ZeroMemory( buff, nbytes );
+ MsiGetPropertyW( hMSI, pPropName, buff, &sz );
+ *ppValue = buff;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+#ifdef DEBUG
+inline void OutputDebugStringFormatW( PCWSTR pFormat, ... )
+{
+ WCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfW( buffer, sizeof(buffer)/sizeof(buffer[0]), pFormat, args );
+ OutputDebugStringW( buffer );
+ va_end(args);
+}
+#else
+static void OutputDebugStringFormatW( PCWSTR, ... )
+{
+}
+#endif
+
+
+extern "C" __declspec(dllexport) UINT __stdcall CheckVersions( MSIHANDLE hMSI )
+{
+ // MessageBoxW(NULL, L"CheckVersions", L"Information", MB_OK | MB_ICONINFORMATION);
+
+ wchar_t* pVal = nullptr;
+
+ if ( GetMsiPropW( hMSI, L"NEWPRODUCTS", &pVal ) && pVal )
+ {
+ OutputDebugStringFormatW( L"DEBUG: NEWPRODUCTS found [%s]", pVal );
+ if ( *pVal != 0 )
+ SetMsiErrorCode( MSI_ERROR_NEW_VERSION_FOUND );
+ free( pVal );
+ }
+ pVal = nullptr;
+ if ( GetMsiPropW( hMSI, L"OLDPRODUCTS", &pVal ) && pVal )
+ {
+ OutputDebugStringFormatW( L"DEBUG: OLDPRODUCTS found [%s]", pVal );
+ if ( *pVal != 0 )
+ SetMsiErrorCode( MSI_ERROR_OLD_VERSION_FOUND );
+ free( pVal );
+ }
+ pVal = nullptr;
+
+ return ERROR_SUCCESS;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/tools/seterror.cxx b/setup_native/source/win32/customactions/tools/seterror.cxx
new file mode 100644
index 000000000..f1800ffb7
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/seterror.cxx
@@ -0,0 +1,84 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <string.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <strsafe.h>
+
+#include "seterror.hxx"
+
+
+#ifdef DEBUG
+inline void OutputDebugStringFormatW( PCWSTR pFormat, ... )
+{
+ WCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfW( buffer, sizeof(buffer)/sizeof(buffer[0]), pFormat, args );
+ OutputDebugStringW( buffer );
+ va_end(args);
+}
+#else
+static void OutputDebugStringFormatW( PCWSTR, ... )
+{
+}
+#endif
+
+
+void SetMsiErrorCode( int nErrorCode )
+{
+ const WCHAR sMemMapName[] = L"Global\\MsiErrorObject";
+
+ HANDLE hMapFile;
+ int *pBuf;
+
+ hMapFile = OpenFileMappingW(
+ FILE_MAP_ALL_ACCESS, // read/write access
+ FALSE, // do not inherit the name
+ sMemMapName ); // name of mapping object
+
+ if ( hMapFile == nullptr ) // can not set error code
+ {
+ OutputDebugStringFormatW( L"Could not open map file (%d).\n", GetLastError() );
+ return;
+ }
+
+ pBuf = static_cast<int*>(MapViewOfFile( hMapFile, // handle to map object
+ FILE_MAP_ALL_ACCESS, // read/write permission
+ 0,
+ 0,
+ sizeof( int ) ));
+ if ( pBuf )
+ {
+ *pBuf = nErrorCode;
+ UnmapViewOfFile( pBuf );
+ }
+ else
+ OutputDebugStringFormatW( L"Could not map view of file (%d).\n", GetLastError() );
+
+ CloseHandle( hMapFile );
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/tools/seterror.hxx b/setup_native/source/win32/customactions/tools/seterror.hxx
new file mode 100644
index 000000000..010af4a8c
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/seterror.hxx
@@ -0,0 +1,36 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SETUP_NATIVE_SOURCE_WIN32_CUSTOMACTIONS_TOOLS_SETERROR_HXX
+#define INCLUDED_SETUP_NATIVE_SOURCE_WIN32_CUSTOMACTIONS_TOOLS_SETERROR_HXX
+
+
+// list of own error codes
+
+#define MSI_ERROR_NEW_VERSION_FOUND 9010
+#define MSI_ERROR_OLD_VERSION_FOUND 9012
+
+#define MSI_ERROR_DIRECTORY_NOT_EMPTY 9030
+
+
+void SetMsiErrorCode( int nErrorCode );
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/tools/sn_tools.def b/setup_native/source/win32/customactions/tools/sn_tools.def
new file mode 100644
index 000000000..3c881861b
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/sn_tools.def
@@ -0,0 +1,3 @@
+LIBRARY "sn_tools.dll"
+EXPORTS
+ CheckVersions \ No newline at end of file
diff --git a/setup_native/source/win32/desktophelper.txt b/setup_native/source/win32/desktophelper.txt
new file mode 100644
index 000000000..c7540116c
--- /dev/null
+++ b/setup_native/source/win32/desktophelper.txt
@@ -0,0 +1 @@
+# File used for desktop link