summaryrefslogtreecommitdiff
path: root/setup_native/source/win32
diff options
context:
space:
mode:
Diffstat (limited to 'setup_native/source/win32')
-rw-r--r--setup_native/source/win32/customactions/indexingfilter/exports.dxp3
-rw-r--r--setup_native/source/win32/customactions/indexingfilter/makefile.mk68
-rw-r--r--setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx210
-rw-r--r--setup_native/source/win32/customactions/javafilter/exports.dxp2
-rw-r--r--setup_native/source/win32/customactions/javafilter/jfregca.cxx332
-rw-r--r--setup_native/source/win32/customactions/javafilter/makefile.mk70
-rw-r--r--setup_native/source/win32/customactions/languagepacks/checkrunningofficelanguagepack.cxx221
-rw-r--r--setup_native/source/win32/customactions/languagepacks/exports.dxp6
-rw-r--r--setup_native/source/win32/customactions/languagepacks/lngpckinsthelper.cxx206
-rw-r--r--setup_native/source/win32/customactions/languagepacks/makefile.mk100
-rw-r--r--setup_native/source/win32/customactions/languagepacks/respintest.cxx215
-rwxr-xr-xsetup_native/source/win32/customactions/patch/exports.dxp11
-rwxr-xr-xsetup_native/source/win32/customactions/patch/makefile.mk98
-rw-r--r--setup_native/source/win32/customactions/patch/swappatchfiles.cxx902
-rw-r--r--setup_native/source/win32/customactions/quickstarter/exports.dxp3
-rw-r--r--setup_native/source/win32/customactions/quickstarter/makefile.mk102
-rw-r--r--setup_native/source/win32/customactions/quickstarter/qslnkmsi.dxp2
-rw-r--r--setup_native/source/win32/customactions/quickstarter/quickstarter.cxx223
-rw-r--r--setup_native/source/win32/customactions/quickstarter/quickstarter.hxx21
-rw-r--r--setup_native/source/win32/customactions/quickstarter/remove_quickstart_link.cxx63
-rw-r--r--setup_native/source/win32/customactions/quickstarter/sdqsmsi.dxp2
-rw-r--r--setup_native/source/win32/customactions/quickstarter/shutdown_quickstart.cxx81
-rw-r--r--setup_native/source/win32/customactions/rebase/makefile.mk90
-rw-r--r--setup_native/source/win32/customactions/rebase/rebase.cxx169
-rw-r--r--setup_native/source/win32/customactions/rebase/rebase.dxp1
-rw-r--r--setup_native/source/win32/customactions/reg4allmsdoc/exports.dxp3
-rw-r--r--setup_native/source/win32/customactions/reg4allmsdoc/makefile.mk83
-rw-r--r--setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx504
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/constants.hxx42
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/exports.dxp3
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/makefile.mk96
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/msihelper.cxx105
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/msihelper.hxx187
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/reg4msdocmsi.cxx190
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/register.cxx342
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/register.hxx85
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrar.cxx760
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrar.hxx104
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.cxx353
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.hxx161
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registry.cxx245
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registry.hxx337
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryexception.cxx88
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryexception.hxx107
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.cxx192
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.hxx111
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryw9x.cxx538
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryw9x.hxx202
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx607
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrywnt.hxx205
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/stringconverter.cxx72
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/stringconverter.hxx44
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/userregistrar.cxx139
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/userregistrar.hxx46
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/windowsregistry.cxx58
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/windowsregistry.hxx43
-rwxr-xr-xsetup_native/source/win32/customactions/reg64/exports.dxp2
-rw-r--r--setup_native/source/win32/customactions/reg64/makefile.mk108
-rw-r--r--setup_native/source/win32/customactions/reg64/reg64.cxx466
-rw-r--r--setup_native/source/win32/customactions/regactivex/exports.dxp2
-rw-r--r--setup_native/source/win32/customactions/regactivex/makefile.mk70
-rw-r--r--setup_native/source/win32/customactions/regactivex/regactivex.cxx441
-rw-r--r--setup_native/source/win32/customactions/regpatchactivex/exports.dxp1
-rw-r--r--setup_native/source/win32/customactions/regpatchactivex/makefile.mk93
-rw-r--r--setup_native/source/win32/customactions/regpatchactivex/regpatchactivex.cxx124
-rw-r--r--setup_native/source/win32/customactions/relnotes/exports.dxp3
-rw-r--r--setup_native/source/win32/customactions/relnotes/makefile.mk83
-rw-r--r--setup_native/source/win32/customactions/relnotes/relnotes.cxx188
-rw-r--r--setup_native/source/win32/customactions/sellang/exports.dxp1
-rw-r--r--setup_native/source/win32/customactions/sellang/makefile.mk79
-rw-r--r--setup_native/source/win32/customactions/sellang/sellang.cxx351
-rw-r--r--setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx120
-rw-r--r--setup_native/source/win32/customactions/shellextensions/checkpatches.cxx116
-rw-r--r--setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx293
-rw-r--r--setup_native/source/win32/customactions/shellextensions/completeinstallpath.cxx183
-rw-r--r--setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx133
-rw-r--r--setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx127
-rw-r--r--setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx184
-rw-r--r--setup_native/source/win32/customactions/shellextensions/exports.dxp23
-rw-r--r--setup_native/source/win32/customactions/shellextensions/iconcache.cxx113
-rw-r--r--setup_native/source/win32/customactions/shellextensions/layerlinks.cxx260
-rw-r--r--setup_native/source/win32/customactions/shellextensions/makefile.mk108
-rw-r--r--setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx120
-rw-r--r--setup_native/source/win32/customactions/shellextensions/postuninstall.cxx157
-rw-r--r--setup_native/source/win32/customactions/shellextensions/registerextensions.cxx430
-rw-r--r--setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx69
-rw-r--r--setup_native/source/win32/customactions/shellextensions/shellextensions.cxx216
-rw-r--r--setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx145
-rw-r--r--setup_native/source/win32/customactions/shellextensions/upgrade.cxx207
-rw-r--r--setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx245
-rw-r--r--setup_native/source/win32/customactions/tools/checkversion.cxx151
-rw-r--r--setup_native/source/win32/customactions/tools/exports.dxp1
-rw-r--r--setup_native/source/win32/customactions/tools/makefile.mk84
-rw-r--r--setup_native/source/win32/customactions/tools/seterror.cxx99
-rw-r--r--setup_native/source/win32/customactions/tools/seterror.hxx56
-rw-r--r--setup_native/source/win32/desktophelper.txt1
-rwxr-xr-xsetup_native/source/win32/get_retval.bat3
-rw-r--r--setup_native/source/win32/msi-encodinglist.txt141
-rw-r--r--setup_native/source/win32/nsis/brobanner.bmpbin0 -> 18150 bytes
-rw-r--r--setup_native/source/win32/nsis/brobanner.svg667
-rw-r--r--setup_native/source/win32/nsis/brobitmap.bmpbin0 -> 153558 bytes
-rw-r--r--setup_native/source/win32/nsis/brobitmap.svg1011
-rw-r--r--setup_native/source/win32/nsis/brosdkbanner.bmpbin0 -> 18150 bytes
-rw-r--r--setup_native/source/win32/nsis/downloadtemplate.nsi457
-rw-r--r--setup_native/source/win32/nsis/ooobanner.bmpbin0 -> 6274 bytes
-rw-r--r--setup_native/source/win32/nsis/ooobitmap.bmpbin0 -> 52242 bytes
-rw-r--r--setup_native/source/win32/nsis/ooosdkbanner.bmpbin0 -> 7106 bytes
-rw-r--r--setup_native/source/win32/nsis/ooosdkbitmap.bmpbin0 -> 52242 bytes
-rw-r--r--setup_native/source/win32/nsis/ooosetup.icobin0 -> 4286 bytes
-rw-r--r--setup_native/source/win32/nsis/urebanner.bmpbin0 -> 7106 bytes
-rwxr-xr-xsetup_native/source/win32/nsis/urebitmap.bmpbin0 -> 52242 bytes
-rw-r--r--setup_native/source/win32/patchlist.txt2
-rw-r--r--setup_native/source/win32/stwrapper/makefile.mk50
-rw-r--r--setup_native/source/win32/stwrapper/resource.rc102
-rw-r--r--setup_native/source/win32/stwrapper/stwrapper.cxx497
-rw-r--r--setup_native/source/win32/stwrapper/stwrapper.manifest20
116 files changed, 17856 insertions, 0 deletions
diff --git a/setup_native/source/win32/customactions/indexingfilter/exports.dxp b/setup_native/source/win32/customactions/indexingfilter/exports.dxp
new file mode 100644
index 000000000000..bb23f3d02803
--- /dev/null
+++ b/setup_native/source/win32/customactions/indexingfilter/exports.dxp
@@ -0,0 +1,3 @@
+RestartIndexingService
+
+ \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/indexingfilter/makefile.mk b/setup_native/source/win32/customactions/indexingfilter/makefile.mk
new file mode 100644
index 000000000000..0298d05960db
--- /dev/null
+++ b/setup_native/source/win32/customactions/indexingfilter/makefile.mk
@@ -0,0 +1,68 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=instooofiltmsi
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+DYNAMIC_CRT=
+NO_DEFAULT_STL=TRUE
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = $(SLO)$/restartindexingservice.obj
+
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
+
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 000000000000..0b030b956570
--- /dev/null
+++ b/setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/*
+ 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.
+*/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+/*
+ Advapi.dll needs to be loaded dynamically because the service
+ control functions are not available under Windows 9x.
+*/
+typedef BOOL (__stdcall * CloseServiceHandle_t)(SC_HANDLE);
+typedef BOOL (__stdcall * ControlService_t)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
+typedef SC_HANDLE (__stdcall * OpenSCManager_t)(LPCSTR, LPCSTR, DWORD);
+typedef SC_HANDLE (__stdcall * OpenService_t)(SC_HANDLE, LPCSTR, DWORD);
+typedef BOOL (__stdcall * QueryServiceStatus_t)(SC_HANDLE, LPSERVICE_STATUS);
+typedef BOOL (__stdcall * StartService_t)(SC_HANDLE, DWORD, LPCSTR*);
+
+CloseServiceHandle_t CloseServiceHandle_ = NULL;
+ControlService_t ControlService_ = NULL;
+OpenSCManager_t OpenSCManager_ = NULL;
+OpenService_t OpenService_ = NULL;
+QueryServiceStatus_t QueryServiceStatus_ = NULL;
+StartService_t StartService_ = NULL;
+
+const LPTSTR INDEXING_SERVICE_NAME = TEXT("cisvc");
+
+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);
+}
+
+void StartIndexingService(SC_HANDLE hService)
+{
+ if (StartService_(hService, 0, NULL))
+ {
+ 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" UINT __stdcall RestartIndexingService(MSIHANDLE)
+{
+ //MessageBox(NULL, TEXT("Restarting Indexing Service"), TEXT("Message"), MB_OK | MB_ICONINFORMATION);
+
+ HMODULE hAdvapi32 = LoadLibrary("advapi32.dll");
+
+ if (hAdvapi32)
+ {
+ CloseServiceHandle_ = reinterpret_cast<CloseServiceHandle_t>(GetProcAddress(hAdvapi32, "CloseServiceHandle"));
+ ControlService_ = reinterpret_cast<ControlService_t>(GetProcAddress(hAdvapi32, "ControlService"));
+ OpenSCManager_ = reinterpret_cast<OpenSCManager_t>(GetProcAddress(hAdvapi32, "OpenSCManagerA"));
+ OpenService_ = reinterpret_cast<OpenService_t>(GetProcAddress(hAdvapi32, "OpenServiceA"));
+ QueryServiceStatus_ = reinterpret_cast<QueryServiceStatus_t>(GetProcAddress(hAdvapi32, "QueryServiceStatus"));
+ StartService_ = reinterpret_cast<StartService_t>(GetProcAddress(hAdvapi32, "StartServiceA"));
+ }
+
+ /* On systems other than Windows 2000/XP the service API
+ functions might not be available */
+ if (!hAdvapi32 ||
+ !(CloseServiceHandle_ && ControlService_ && OpenSCManager_ && OpenService_ && QueryServiceStatus_ && StartService_))
+ return ERROR_SUCCESS;
+
+ SC_HANDLE hSCManager = OpenSCManager_(
+ NULL, // local machine
+ NULL, // ServicesActive database
+ SC_MANAGER_ALL_ACCESS);
+
+ if (hSCManager != NULL)
+ {
+ SC_HANDLE hIndexingService = OpenService_(
+ 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/javafilter/exports.dxp b/setup_native/source/win32/customactions/javafilter/exports.dxp
new file mode 100644
index 000000000000..209a9ed2a5f3
--- /dev/null
+++ b/setup_native/source/win32/customactions/javafilter/exports.dxp
@@ -0,0 +1,2 @@
+install_jf
+uninstall_jf
diff --git a/setup_native/source/win32/customactions/javafilter/jfregca.cxx b/setup_native/source/win32/customactions/javafilter/jfregca.cxx
new file mode 100644
index 000000000000..638ff1c9f8ae
--- /dev/null
+++ b/setup_native/source/win32/customactions/javafilter/jfregca.cxx
@@ -0,0 +1,332 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#include <windows.h>
+#include <msi.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#if defined UNICODE
+#define _UNICODE
+#endif
+#include <tchar.h>
+
+//Simple function prototypes
+bool update_activesync_regvalues(bool, bool, char** );
+void createKeys(HKEY hKey, char **);
+void deleteKeys(HKEY hKey, char **);
+bool isMulti(MSIHANDLE);
+
+//Simple data arrays for registry values
+TCHAR *pxlData[8]= {
+ "{C6AB3E74-9F4F-4370-8120-A8A6FABB7A7C}", //CLSID 1 - key name at InstalledFilters Key
+ "{43887C67-4D5D-4127-BAAC-87A288494C7C}", //CLSID 2 - key value for Default Export
+ ".pxl", //Registry key for device type - already there if ActiveSync installerd
+ ".sxc", //New registry key for SO docs
+ "InstalledFilters", //Sub-key of device/so doc key
+ "DefaultImport", //Key name added at device/so level key
+ "DefaultExport", //Key name added at device/so level key
+ "Binary Copy", //Key value for DefaultImport
+};
+
+TCHAR *pswData[8] = {
+ "{BDD611C3-7BAB-460F-8711-5B9AC9EF6020}", //CLSID 1 - key name at InstalledFilters Key
+ "{CB43F086-838D-4FA4-B5F6-3406B9A57439}", //CLSID 2 - key value for Default Export
+ ".psw", //Registry key for device type - already there if ActiveSync installe
+ ".sxw", //New registry key for SO docs
+ "InstalledFilters", //Sub-key of device/so doc key
+ "DefaultImport", //Key name added at device/so level key
+ "DefaultExport", //Key name added at device/so level key
+ "Binary Copy", //Key value for DefaultImport
+};
+
+
+//index into registry value arrays
+#define CLSID1 0
+#define CLSID2 1
+#define DEVICE_PATH 2
+#define SO_PATH 3
+#define IF_PATH 4
+#define DEFIMPORT_KEY 5
+#define DEFEXPORT_KEY 6
+#define BC_VALUE 7
+
+//Constants for Registry buffers
+const int MAX_KEY_LENGTH=255;
+const int MAX_VALUE_NAME=16383;
+
+BOOL APIENTRY DllMain( HANDLE,
+ DWORD ul_reason,
+ LPVOID
+ )
+{
+ switch (ul_reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
+extern "C" UINT install_jf ( MSIHANDLE hModule ) {
+ bool bMulti = isMulti(hModule);
+#ifdef _JRGREG_DEBUG
+ MessageBox(NULL, bMulti ? "Multi" : "Single", "Install", MB_OK);
+#endif
+ update_activesync_regvalues(bMulti, true, pxlData);
+ update_activesync_regvalues(bMulti, true, pswData);
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT uninstall_jf ( MSIHANDLE hModule ) {
+ bool bMulti = isMulti(hModule);
+#ifdef _JRGREG_DEBUG
+ MessageBox(NULL, bMulti ? "Multi" : "Single", "Uninstall", MB_OK);
+#endif
+ update_activesync_regvalues(false, bMulti, pxlData);
+ update_activesync_regvalues(false, bMulti, pswData);
+
+ return ERROR_SUCCESS;
+}
+
+/**
+ Determines if this is being installed on a per user or a machine wide basis
+ @param hModule
+ [in] a valid msi handle.
+
+
+ @returns
+ <TRUE/>if this is a multi-user install.
+*/
+bool isMulti( MSIHANDLE hModule ) {
+ TCHAR* szValueBuf = NULL;
+ DWORD cchValueBuf = 0;
+ bool bRet = false;
+ UINT uiStat = MsiGetProperty(hModule, TEXT("ALLUSERS"), TEXT(""), &cchValueBuf);
+ if (ERROR_MORE_DATA == uiStat)
+ {
+ ++cchValueBuf; // on output does not include terminating null, so add 1
+ szValueBuf = new TCHAR[cchValueBuf];
+ if (szValueBuf)
+ {
+ uiStat = MsiGetProperty(hModule, TEXT("ALLUSERS"), szValueBuf, &cchValueBuf);
+ }
+ }
+ if (ERROR_SUCCESS != uiStat)
+ {
+ return false;
+ }
+ bRet = _tcscmp(szValueBuf, TEXT("1")) == 0;
+ delete [] szValueBuf;
+
+ return bRet;
+}
+
+/**
+ Add or remove ActiveSync integration entries from the registry
+ @param bMultiUser
+ [in] <TRUE/>if this is a multiuser install (<FALSE/> for single user install)
+
+ @param bInstall
+ [in] <TRUE/>if installing
+
+ @param data
+ [in] an array of string containing names of registry keys and values
+
+
+ @returns
+ <TRUE/>if this is a multi-user install.
+*/
+
+bool update_activesync_regvalues(bool bMultiUser, bool bInstall, char **data) {
+ bool bReturn = false;
+ CHAR SUKey[] = "Software\\Microsoft\\Windows CE Services\\Partners";
+ CHAR MUKey[] = "Software\\Microsoft\\Windows CE Services\\Filters";
+ HKEY hKey;
+
+ if (bMultiUser) {
+ if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)MUKey, 0, KEY_ALL_ACCESS, &hKey)) {
+ return false;
+ }
+ if (bInstall) {
+ createKeys(hKey, data);
+ } else {
+ deleteKeys(hKey, data);
+ }
+ bReturn = true;
+ } else {
+ if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, (LPCSTR)SUKey, 0, KEY_ALL_ACCESS, &hKey)) {
+ return false;
+ }
+
+ CHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
+ DWORD cbName; // size of name string
+ CHAR achClass[MAX_PATH] = ""; // buffer for class name
+ DWORD cchClassName = MAX_PATH; // size of class string
+ DWORD cSubKeys=0; // number of subkeys
+ DWORD cbMaxSubKey; // longest subkey size
+ DWORD cchMaxClass; // longest class string
+ DWORD cValues; // number of values for key
+ DWORD cchMaxValue; // longest value name
+ DWORD cbMaxValueData; // longest value data
+ DWORD cbSecurityDescriptor; // size of security descriptor
+ FILETIME ftLastWriteTime; // last write time
+
+ // Get the class name and the value count.
+ if (ERROR_SUCCESS == RegQueryInfoKey(
+ hKey, // key handle
+ achClass, // buffer for class name
+ &cchClassName, // size of class string
+ NULL, // reserved
+ &cSubKeys, // number of subkeys
+ &cbMaxSubKey, // longest subkey size
+ &cchMaxClass, // longest class string
+ &cValues, // number of values for this key
+ &cchMaxValue, // longest value name
+ &cbMaxValueData, // longest value data
+ &cbSecurityDescriptor, // security descriptor
+ &ftLastWriteTime)) { // last write time
+
+ if (cSubKeys) {
+ for (DWORD i=0; i<cSubKeys; i++) {
+ cbName = 1024;
+ if (ERROR_SUCCESS == RegEnumKeyEx(hKey,i,achKey,&cbName,NULL,NULL,NULL,&ftLastWriteTime)) {
+ HKEY subKey;
+ if (ERROR_SUCCESS == RegOpenKeyEx(hKey, achKey, 0, KEY_ALL_ACCESS, &subKey)) {
+ if (ERROR_SUCCESS == RegOpenKeyEx(subKey, "Filters", 0, KEY_ALL_ACCESS, &subKey)) {
+ if (bInstall) {
+ createKeys(subKey, data);
+ } else {
+ deleteKeys(subKey, data);
+ }
+ RegCloseKey(subKey);
+ }
+ }
+ }
+ }
+ }
+
+ bReturn = true;
+ }
+ }
+ if (hKey != NULL) {
+ RegCloseKey(hKey);
+ }
+
+ return bReturn;
+}
+
+/**
+ Create Registry Keys
+
+ @param hKey
+ [in] Handle to the parent registry key
+
+ @param data
+ [in] an array of string containing names of registry keys and values
+*/
+
+void createKeys(HKEY hKey, char **data) {
+
+ LPCSTR clsid1 = data[CLSID1];
+ LPCSTR clsid2 = data[CLSID2];
+ LPCSTR devicePath = data[DEVICE_PATH];
+ LPCSTR soPath = data[SO_PATH];
+ LPCSTR defImport = data[DEFIMPORT_KEY];
+ LPCSTR defExport = data[DEFEXPORT_KEY];
+ LPCSTR binaryCopy = data[BC_VALUE];
+ LPCSTR IFPath = data[IF_PATH];
+
+ HKEY deviceKey, deviceIFKey, soKey, soIFKey;
+
+ if (ERROR_SUCCESS == RegOpenKeyEx(hKey,devicePath,0,KEY_ALL_ACCESS, &deviceKey)) {
+ if (ERROR_SUCCESS == RegOpenKeyEx(deviceKey,IFPath,0,KEY_ALL_ACCESS, &deviceIFKey)) {
+ RegSetValueEx(deviceIFKey, clsid1, 0, REG_SZ, NULL, NULL);
+ }
+ }
+
+ if (ERROR_SUCCESS == RegCreateKeyEx(hKey, soPath, 0, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &soKey, NULL)) {
+ RegSetValueEx(soKey, defExport, 0, REG_SZ, (LPBYTE)binaryCopy, strlen(binaryCopy));
+ RegSetValueEx(soKey, defImport, 0, REG_SZ, (LPBYTE)clsid2, strlen(clsid2));
+
+
+ if (ERROR_SUCCESS == RegCreateKeyEx(soKey, IFPath, 0, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &soIFKey, NULL)) {
+ RegSetValueEx(soIFKey, clsid2, 0, REG_SZ, NULL, NULL);
+ }
+ }
+}
+
+/**
+ Delete registry keys
+
+ @param hKey
+ [in] Handle to the parent registry key
+*/
+void deleteKeys(HKEY hKey, TCHAR **data) {
+ LPCSTR clsid1 = data[CLSID1];
+ LPCSTR clsid2 = data[CLSID2];
+ LPCSTR devicePath = data[DEVICE_PATH];
+ LPCSTR soPath = data[SO_PATH];
+ LPCSTR defImport = data[DEFIMPORT_KEY];
+ LPCSTR defExport = data[DEFEXPORT_KEY];
+ LPCSTR IFPath = data[IF_PATH];
+
+ HKEY deviceKey, deviceIFKey, soKey, soIFKey;
+
+ if (ERROR_SUCCESS == RegOpenKeyEx(hKey,devicePath,0,KEY_ALL_ACCESS, &deviceKey)) {
+ if (ERROR_SUCCESS == RegOpenKeyEx(deviceKey,IFPath,0,KEY_ALL_ACCESS, &deviceIFKey)) {
+ RegDeleteValue(deviceIFKey, clsid1);
+ }
+ }
+
+ if (ERROR_SUCCESS == RegOpenKeyEx(hKey, soPath, 0, KEY_ALL_ACCESS, &soKey)) {
+ RegDeleteValue(soKey, defExport);
+ RegDeleteValue(soKey, defImport);
+
+ if (ERROR_SUCCESS == RegOpenKeyEx(soKey, IFPath, 0, KEY_ALL_ACCESS, &soIFKey)) {
+ RegDeleteValue(soIFKey, clsid2);
+ RegCloseKey(soIFKey);
+ RegDeleteKey(soKey, IFPath);
+ }
+ RegCloseKey(soKey);
+ RegDeleteKey(hKey, soPath);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/javafilter/makefile.mk b/setup_native/source/win32/customactions/javafilter/makefile.mk
new file mode 100644
index 000000000000..3ee19cff53b4
--- /dev/null
+++ b/setup_native/source/win32/customactions/javafilter/makefile.mk
@@ -0,0 +1,70 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=jfregca
+
+
+# --- Settings -----------------------------------------------------
+
+NO_DEFAULT_STL=TRUE
+ENABLE_EXCEPTIONS=TRUE
+DYNAMIC_CRT=
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = $(SLO)$/jfregca.obj
+
+STDSHL += \
+ $(ADVAPI32LIB)\
+ $(MSILIB)
+
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
diff --git a/setup_native/source/win32/customactions/languagepacks/checkrunningofficelanguagepack.cxx b/setup_native/source/win32/customactions/languagepacks/checkrunningofficelanguagepack.cxx
new file mode 100644
index 000000000000..1bebed752e18
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/checkrunningofficelanguagepack.cxx
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+#include <sal/macros.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+#define WININIT_FILENAME "wininit.ini"
+#define RENAME_SECTION "rename"
+
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ _TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ _vsntprintf( buffer, SAL_N_ELEMENTS(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+static inline bool IsSetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ std::_tstring value = GetMsiProperty(handle, sProperty);
+ return (value.length() > 0);
+}
+
+static inline void UnsetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+}
+
+static inline void SetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+}
+
+static BOOL MoveFileEx9x( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
+{
+ BOOL fSuccess = FALSE; // assume failure
+
+ // Windows 9x has a special mechanism to move files after reboot
+
+ if ( dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT )
+ {
+ CHAR szExistingFileNameA[MAX_PATH];
+ CHAR szNewFileNameA[MAX_PATH] = "NUL";
+
+ // Path names in WININIT.INI must be in short path name form
+
+ if (
+ GetShortPathNameA( lpExistingFileNameA, szExistingFileNameA, MAX_PATH ) &&
+ (!lpNewFileNameA || GetShortPathNameA( lpNewFileNameA, szNewFileNameA, MAX_PATH ))
+ )
+ {
+ CHAR szBuffer[32767]; // The buffer size must not exceed 32K
+ DWORD dwBufLen = GetPrivateProfileSectionA( RENAME_SECTION, szBuffer, SAL_N_ELEMENTS(szBuffer), WININIT_FILENAME );
+
+ CHAR szRename[MAX_PATH]; // This is enough for at most to times 67 chracters
+ strcpy( szRename, szNewFileNameA );
+ strcat( szRename, "=" );
+ strcat( szRename, szExistingFileNameA );
+ size_t lnRename = strlen(szRename);
+
+ if ( dwBufLen + lnRename + 2 <= SAL_N_ELEMENTS(szBuffer) )
+ {
+ CopyMemory( &szBuffer[dwBufLen], szRename, lnRename );
+ szBuffer[dwBufLen + lnRename ] = 0;
+ szBuffer[dwBufLen + lnRename + 1 ] = 0;
+
+ fSuccess = WritePrivateProfileSectionA( RENAME_SECTION, szBuffer, WININIT_FILENAME );
+ }
+ else
+ SetLastError( ERROR_BUFFER_OVERFLOW );
+ }
+ }
+ else
+ {
+
+ fSuccess = MoveFileA( lpExistingFileNameA, lpNewFileNameA );
+
+ if ( !fSuccess && GetLastError() != ERROR_ACCESS_DENIED &&
+ 0 != (dwFlags & (MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) )
+ {
+ BOOL bFailIfExist = 0 == (dwFlags & MOVEFILE_REPLACE_EXISTING);
+
+ fSuccess = CopyFileA( lpExistingFileNameA, lpNewFileNameA, bFailIfExist );
+
+ if ( fSuccess )
+ fSuccess = DeleteFileA( lpExistingFileNameA );
+ }
+
+ }
+
+ return fSuccess;
+}
+
+static BOOL MoveFileExImpl( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
+{
+ if ( 0 > ((LONG)GetVersion())) // High order bit indicates Win 9x
+ return MoveFileEx9x( lpExistingFileNameA, lpNewFileNameA, dwFlags );
+ else
+ return MoveFileExA( lpExistingFileNameA, lpNewFileNameA, dwFlags );
+}
+
+extern "C" UINT __stdcall IsOfficeRunning( MSIHANDLE handle )
+{
+ std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ std::_tstring sResourceDir = sInstDir + TEXT("Basis\\program\\resource\\");
+ std::_tstring sPattern = sResourceDir + TEXT("vcl*.res");
+
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ BOOL fSuccess = false;
+ bool fRenameSucceeded;
+
+ do
+ {
+ std::_tstring sResourceFile = sResourceDir + aFindFileData.cFileName;
+ std::_tstring sIntermediate = sResourceFile + TEXT(".tmp");
+
+ fRenameSucceeded = MoveFileExImpl( sResourceFile.c_str(), sIntermediate.c_str(), MOVEFILE_REPLACE_EXISTING );
+ if ( fRenameSucceeded )
+ {
+ MoveFileExImpl( sIntermediate.c_str(), sResourceFile.c_str(), 0 );
+ fSuccess = FindNextFile( hFind, &aFindFileData );
+ }
+ } while ( fSuccess && fRenameSucceeded );
+
+ if ( !fRenameSucceeded )
+ {
+ MsiSetProperty(handle, TEXT("OFFICERUNS"), TEXT("1"));
+ SetMsiErrorCode( MSI_ERROR_OFFICE_IS_RUNNING );
+ }
+
+ FindClose( hFind );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/languagepacks/exports.dxp b/setup_native/source/win32/customactions/languagepacks/exports.dxp
new file mode 100644
index 000000000000..c098a38d547f
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/exports.dxp
@@ -0,0 +1,6 @@
+SetProductInstallationPath
+RegisterLanguagePack
+GetUserInstallMode
+IsOfficeRunning
+RegisterExtensions
+
diff --git a/setup_native/source/win32/customactions/languagepacks/lngpckinsthelper.cxx b/setup_native/source/win32/customactions/languagepacks/lngpckinsthelper.cxx
new file mode 100644
index 000000000000..f6f6a4c0c3b9
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/lngpckinsthelper.cxx
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <tchar.h>
+#include <string>
+#include <stdexcept>
+#include <vector>
+
+class RegistryKeyGuard
+{
+public:
+ RegistryKeyGuard(HKEY hkey = 0) :
+ hkey_(hkey)
+ {
+ }
+
+ ~RegistryKeyGuard()
+ {
+ if (hkey_)
+ RegCloseKey(hkey_);
+ }
+private:
+ HKEY hkey_;
+
+private:
+ RegistryKeyGuard(const RegistryKeyGuard&);
+ RegistryKeyGuard& operator=(const RegistryKeyGuard&);
+};
+
+typedef std::vector<TCHAR> CharacterBuffer_t;
+
+/* throws std::runtime_error when the value "Path" could
+ not be found or contains an empty string or is not of
+ type REG_SZ. All such conditions are invalid for a
+ properly installed product. */
+std::string FindProductInstallationPath(HKEY hkey)
+{
+ DWORD nSubKeys;
+ DWORD lLongestSubKey;
+
+ if (RegQueryInfoKey(hkey, NULL, NULL, NULL, &nSubKeys, &lLongestSubKey, NULL, NULL, NULL, NULL, NULL, NULL) !=
+ ERROR_SUCCESS)
+ throw std::runtime_error("Cannot query info for registery key");
+
+ CharacterBuffer_t buff(lLongestSubKey + 1);
+
+ for (DWORD i = 0; i < nSubKeys; i++)
+ {
+ buff[0] = 0;
+ LONG ret = RegEnumKey(hkey, i, &buff[0], buff.size());
+
+ if ((ret != ERROR_SUCCESS) && (ret != ERROR_MORE_DATA))
+ throw std::runtime_error("Error enumerating registry key");
+
+ HKEY hSubKey;
+ if (RegOpenKey(hkey, &buff[0], &hSubKey) != ERROR_SUCCESS)
+ continue;
+
+ RegistryKeyGuard guard(hSubKey);
+
+ DWORD type;
+ TCHAR pbuff[MAX_PATH];
+ DWORD size = sizeof(pbuff);
+ if ((RegQueryValueEx(
+ hSubKey, TEXT("Path"), NULL, &type, reinterpret_cast<LPBYTE>(pbuff), &size) != ERROR_SUCCESS) ||
+ (type != REG_SZ))
+ continue;
+
+ std::string path(pbuff);
+ std::string::size_type idx = path.rfind("program\\soffice.exe");
+ if (idx != std::string::npos)
+ return path.substr(0, idx);
+ } // for
+
+ throw std::runtime_error("No valid product path found");
+}
+
+UINT GetInstallProperty(MSIHANDLE handle, LPCTSTR name, CharacterBuffer_t* buffer)
+{
+ DWORD size = buffer->size();
+ UINT ret = MsiGetProperty(handle, name, &(*buffer)[0], &size);
+
+ if (ret == ERROR_MORE_DATA)
+ {
+ buffer->resize(size + 1);
+ size = buffer->size();
+ ret = MsiGetProperty(handle, name, &(*buffer)[0], &size);
+ }
+ return ret;
+}
+
+/*
+ Try to find the installation path to an already installed product.
+ The installation path will be written in the Windows registry
+ during the installation. There may exist different products in
+ parallel e.g. StarOffice, StarSuite, OpenOffice.org. It will be
+ searched in this order for an installed product. If a product
+ will be found the path to the product will be set in the property
+ "INSTALLLOCATION" else nothing will be done.
+*/
+extern "C" UINT __stdcall SetProductInstallationPath(MSIHANDLE handle)
+{
+ //MessageBox(NULL, TEXT("SetProductInstallationPath"), TEXT("Language Pack Installation Helper"), MB_OK | MB_ICONINFORMATION);
+
+ try
+ {
+ CharacterBuffer_t regKeyProdPath(MAX_PATH);
+
+ GetInstallProperty(handle, TEXT("REGKEYPRODPATH"), &regKeyProdPath);
+
+ HKEY hKey;
+ if ((RegOpenKey(HKEY_CURRENT_USER, &regKeyProdPath[0], &hKey) == ERROR_SUCCESS) ||
+ (RegOpenKey(HKEY_LOCAL_MACHINE, &regKeyProdPath[0], &hKey) == ERROR_SUCCESS))
+ {
+ RegistryKeyGuard guard(hKey);
+ std::string path = FindProductInstallationPath(hKey);
+ MsiSetProperty(handle, TEXT("INSTALLLOCATION"), path.c_str());
+ }
+ }
+ catch(std::runtime_error& ex)
+ {
+ ex = ex; // no warnings
+ }
+ return ERROR_SUCCESS;
+}
+
+void MakeCfgimportCommandLine(CharacterBuffer_t* productPath)
+{
+ char* p = &(*productPath)[0] + lstrlen(&(*productPath)[0]) - 1;
+
+ if (*p != '\\')
+ lstrcat(&(*productPath)[0], "\\program\\configimport.exe --spool");
+ else
+ lstrcat(&(*productPath)[0], "program\\configimport.exe --spool");
+}
+
+/*
+ Calls configimport.exe --spool
+*/
+extern "C" UINT __stdcall RegisterLanguagePack(MSIHANDLE handle)
+{
+ //MessageBox(NULL, TEXT("RegisterLanguagePack"), TEXT("Language Pack Installation Helper"), MB_OK | MB_ICONINFORMATION);
+
+ CharacterBuffer_t productPath(MAX_PATH);
+ GetInstallProperty(handle, TEXT("INSTALLLOCATION"), &productPath);
+ MakeCfgimportCommandLine(&productPath);
+
+ STARTUPINFO si;
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+
+ PROCESS_INFORMATION pi;
+ ZeroMemory(&pi, sizeof(pi));
+
+ if (CreateProcess(
+ NULL, &productPath[0], NULL, NULL,
+ FALSE, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS, NULL,
+ NULL, &si, &pi))
+ {
+ // Wait until child process exits.
+ WaitForSingleObject(pi.hProcess, INFINITE);
+
+ // Close process and thread handles.
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/languagepacks/makefile.mk b/setup_native/source/win32/customactions/languagepacks/makefile.mk
new file mode 100644
index 000000000000..8da47ab1cc4f
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/makefile.mk
@@ -0,0 +1,100 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=lngpckinsthlp
+
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+#Disable precompiled header
+CDEFS+=-Dnot_used_define_to_disable_pch
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = $(SLO)$/lngpckinsthelper.obj \
+ $(SLO)$/respintest.obj \
+ $(SLO)$/checkrunningofficelanguagepack.obj
+
+STDSHL+= \
+ $(ADVAPI32LIB) \
+ $(MSILIB) \
+ $(SHELL32LIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+STDSHL+=$(LIBSTLPORTST)
+.ENDIF
+
+SHL1OBJS = $(SLOFILES) \
+ $(SLO)$/seterror.obj
+
+.IF "$(COM)"=="GCC"
+STDSHL+= \
+ $(KERNEL32LIB)\
+ -lmsvcrt
+.ENDIF
+
+#SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1OBJS = $(SLOFILES) \
+ $(SLO)$/registerextensions.obj \
+ $(SLO)$/seterror.obj
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
+
diff --git a/setup_native/source/win32/customactions/languagepacks/respintest.cxx b/setup_native/source/win32/customactions/languagepacks/respintest.cxx
new file mode 100644
index 000000000000..5f979a81fa68
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/respintest.cxx
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#include <tchar.h>
+#include <string>
+#include <sal/macros.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+using namespace std;
+
+namespace
+{
+ string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ string result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+ return result;
+ }
+
+ inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ return (GetMsiProperty(handle, sProperty).length() > 0);
+ }
+
+ inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+ }
+
+ inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string&)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+ }
+} // namespace
+
+extern "C" UINT __stdcall GetUserInstallMode(MSIHANDLE handle)
+{
+ string sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+
+ // MessageBox(NULL, sOfficeInstallPath.c_str(), "DEBUG", MB_OK);
+
+ // unsetting all properties
+
+ UnsetMsiProperty( handle, TEXT("INVALIDDIRECTORY") );
+ UnsetMsiProperty( handle, TEXT("ISWRONGPRODUCT") );
+ UnsetMsiProperty( handle, TEXT("PATCHISOLDER") );
+ UnsetMsiProperty( handle, TEXT("ALLUSERS") );
+
+ // 1. Searching for "ProductCode" in setup.ini
+
+ string sSetupiniPath = sOfficeInstallPath + TEXT("program\\setup.ini");
+
+ TCHAR szValue[32767];
+
+ GetPrivateProfileString(
+ TEXT("Bootstrap"),
+ TEXT("ProductCode"),
+ TEXT("INVALIDDIRECTORY"),
+ szValue,
+ SAL_N_ELEMENTS(szValue),
+ sSetupiniPath.c_str()
+ );
+
+ if ( !_tcsicmp( szValue, TEXT("INVALIDDIRECTORY") ) )
+ {
+ // No setup.ini or no "ProductCode" in setup.ini. This is an invalid directory.
+ SetMsiProperty( handle, TEXT("INVALIDDIRECTORY"), TEXT("YES") );
+ // MessageBox(NULL, "INVALIDDIRECTORY set, no setup.ini or ProductCode in setup.ini.", "DEBUG", MB_OK);
+ SetMsiErrorCode( MSI_ERROR_INVALIDDIRECTORY );
+ return ERROR_SUCCESS;
+ }
+
+ // 2. Comparing first three characters of "PRODUCTMAJOR" from property table and "buildid" from InfoFile
+
+ szValue[0] = '\0';
+
+ GetPrivateProfileString(
+ TEXT("Bootstrap"),
+ TEXT("buildid"),
+ TEXT("ISWRONGPRODUCT"),
+ szValue,
+ SAL_N_ELEMENTS(szValue),
+ sSetupiniPath.c_str()
+ );
+
+ if ( !_tcsicmp( szValue, TEXT("ISWRONGPRODUCT") ) )
+ {
+ SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
+ // MessageBox(NULL, "ISWRONGPRODUCT 1 set after searching buildid", "DEBUG", MB_OK);
+ SetMsiErrorCode( MSI_ERROR_ISWRONGPRODUCT );
+ return ERROR_SUCCESS;
+ }
+
+ string ProductMajor = GetMsiProperty(handle, TEXT("PRODUCTMAJOR"));
+
+ // Comparing the first three characters, for example "680"
+ // If not equal, this version is not suited for patch or language pack
+
+ if (_tcsnicmp(ProductMajor.c_str(), szValue, 3))
+ {
+ SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
+ // MessageBox(NULL, "ISWRONGPRODUCT 2 set after searching PRODUCTMAJOR", "DEBUG", MB_OK);
+ SetMsiErrorCode( MSI_ERROR_ISWRONGPRODUCT );
+ return ERROR_SUCCESS;
+ }
+
+ // 3. Only for patch: Comparing "PRODUCTMINOR from property table and "ProductMinor" from InfoFile
+
+ string isPatch = GetMsiProperty(handle, TEXT("ISPATCH"));
+
+ if (isPatch=="1")
+ {
+ string ProductMinor = GetMsiProperty(handle, TEXT("PRODUCTBUILDID"));
+ int PatchProductMinor = atoi(ProductMinor.c_str());
+
+ szValue[0] = '\0';
+
+ GetPrivateProfileString(
+ TEXT("Bootstrap"),
+ TEXT("ProductBuildid"),
+ TEXT("8918"),
+ szValue,
+ SAL_N_ELEMENTS(szValue),
+ sSetupiniPath.c_str()
+ );
+
+ int InstalledProductMinor = atoi(szValue);
+
+ if ( InstalledProductMinor >= PatchProductMinor )
+ {
+ SetMsiProperty( handle, TEXT("PATCHISOLDER"), TEXT("YES") );
+ // MessageBox(NULL, "PATCHISOLDER set", "DEBUG", MB_OK);
+ SetMsiErrorCode( MSI_ERROR_PATCHISOLDER );
+ return ERROR_SUCCESS;
+ }
+ }
+
+ // 4. Setting property ALLUSERS with value from "setup.ini"
+
+ szValue[0] = '\0';
+
+ GetPrivateProfileString(
+ TEXT("Bootstrap"),
+ TEXT("ALLUSERS"),
+ TEXT(""),
+ szValue,
+ SAL_N_ELEMENTS(szValue),
+ sSetupiniPath.c_str()
+ );
+
+ if ( szValue[0] )
+ {
+ SetMsiProperty( handle, TEXT("ALLUSERS"), szValue );
+ // MessageBox(NULL, "ALLUSERS set", "DEBUG", MB_OK);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/patch/exports.dxp b/setup_native/source/win32/customactions/patch/exports.dxp
new file mode 100755
index 000000000000..dd5eb4dcf7c8
--- /dev/null
+++ b/setup_native/source/win32/customactions/patch/exports.dxp
@@ -0,0 +1,11 @@
+InstallPatchedFiles
+UninstallPatchedFiles
+GetUserInstallMode
+SetProductInstallMode
+ShutDownQuickstarter
+IsOfficeRunning
+SetFeatureState
+SetNewFeatureState
+ShowOnlineUpdateDialog
+RegisterExtensions
+RemoveExtensions
diff --git a/setup_native/source/win32/customactions/patch/makefile.mk b/setup_native/source/win32/customactions/patch/makefile.mk
new file mode 100755
index 000000000000..57705389248f
--- /dev/null
+++ b/setup_native/source/win32/customactions/patch/makefile.mk
@@ -0,0 +1,98 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=patchmsi
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+#Disable precompiled header
+CDEFS+=-Dnot_used_define_to_disable_pch
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = \
+ $(SLO)$/swappatchfiles.obj
+
+STDSHL += \
+ $(ADVAPI32LIB)\
+ $(MSILIB)\
+ $(SHELL32LIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+STDSHL += $(LIBSTLPORTST)
+.ENDIF
+
+.IF "$(COM)"=="GCC"
+STDSHL+= \
+ $(KERNEL32LIB)\
+ -lmsvcrt
+.ENDIF
+
+#SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1OBJS = $(SLOFILES) \
+ $(SLO)$/respintest.obj \
+ $(SLO)$/shutdown_quickstart.obj \
+ $(SLO)$/quickstarter.obj \
+ $(SLO)$/upgrade.obj \
+ $(SLO)$/registerextensions.obj \
+ $(SLO)$/seterror.obj
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
diff --git a/setup_native/source/win32/customactions/patch/swappatchfiles.cxx b/setup_native/source/win32/customactions/patch/swappatchfiles.cxx
new file mode 100644
index 000000000000..2ef10553e239
--- /dev/null
+++ b/setup_native/source/win32/customactions/patch/swappatchfiles.cxx
@@ -0,0 +1,902 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+#include <sal/macros.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+#define WININIT_FILENAME "wininit.ini"
+#define RENAME_SECTION "rename"
+
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ _TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ _vsntprintf( buffer, SAL_N_ELEMENTS(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+// The provided GUID must be without surounding '{}'
+static std::_tstring GetGuidPart(const std::_tstring& 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::_tstring(guid.c_str(), 8);
+ if (index == 1) return std::_tstring(guid.c_str() + 9, 4);
+ if (index == 2) return std::_tstring(guid.c_str() + 14, 4);
+ if (index == 3) return std::_tstring(guid.c_str() + 19, 4);
+ if (index == 4) return std::_tstring(guid.c_str() + 24, 12);
+
+ return std::_tstring();
+}
+
+static void Swap(char* p1, char* p2)
+{
+ char tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+}
+
+static std::_tstring Invert(const std::_tstring& str)
+{
+ char* buff = reinterpret_cast<char*>(_alloca(str.length()));
+ strncpy(buff, str.c_str(), str.length());
+
+ char* front = buff;
+ char* back = buff + str.length() - 1;
+
+ while (front < back)
+ Swap(front++, back--);
+
+ return std::_tstring(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 the last
+// 8 bytes always the nibbles will be inverted for further
+// details look in the MSDN under compressed registry keys
+static std::_tstring ConvertGuid(const std::_tstring& guid)
+{
+ std::_tstring convertedGuid;
+
+ std::_tstring 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::_tstring(part.c_str(), 2));
+ convertedGuid += Invert(std::_tstring(part.c_str() + 2, 2));
+
+ part = GetGuidPart(guid, 4);
+ int pos = 0;
+ for (int i = 0; i < 6; i++)
+ {
+ convertedGuid += Invert(std::_tstring(part.c_str() + pos, 2));
+ pos += 2;
+ }
+ return convertedGuid;
+}
+
+static inline bool IsSetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ std::_tstring value = GetMsiProperty(handle, sProperty);
+ return (value.length() > 0);
+}
+
+static inline void UnsetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+}
+
+static inline void SetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+}
+
+static BOOL MoveFileEx9x( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
+{
+ BOOL fSuccess = FALSE; // assume failure
+
+ // Windows 9x has a special mechanism to move files after reboot
+
+ if ( dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT )
+ {
+ CHAR szExistingFileNameA[MAX_PATH];
+ CHAR szNewFileNameA[MAX_PATH] = "NUL";
+
+ // Path names in WININIT.INI must be in short path name form
+
+ if (
+ GetShortPathNameA( lpExistingFileNameA, szExistingFileNameA, MAX_PATH ) &&
+ (!lpNewFileNameA || GetShortPathNameA( lpNewFileNameA, szNewFileNameA, MAX_PATH ))
+ )
+ {
+ CHAR szBuffer[32767]; // The buffer size must not exceed 32K
+ DWORD dwBufLen = GetPrivateProfileSectionA( RENAME_SECTION, szBuffer, SAL_N_ELEMENTS(szBuffer), WININIT_FILENAME );
+
+ CHAR szRename[MAX_PATH]; // This is enough for at most to times 67 chracters
+ strcpy( szRename, szNewFileNameA );
+ strcat( szRename, "=" );
+ strcat( szRename, szExistingFileNameA );
+ size_t lnRename = strlen(szRename);
+
+ if ( dwBufLen + lnRename + 2 <= SAL_N_ELEMENTS(szBuffer) )
+ {
+ CopyMemory( &szBuffer[dwBufLen], szRename, lnRename );
+ szBuffer[dwBufLen + lnRename ] = 0;
+ szBuffer[dwBufLen + lnRename + 1 ] = 0;
+
+ fSuccess = WritePrivateProfileSectionA( RENAME_SECTION, szBuffer, WININIT_FILENAME );
+ }
+ else
+ SetLastError( ERROR_BUFFER_OVERFLOW );
+ }
+ }
+ else
+ {
+
+ fSuccess = MoveFileA( lpExistingFileNameA, lpNewFileNameA );
+
+ if ( !fSuccess && GetLastError() != ERROR_ACCESS_DENIED &&
+ 0 != (dwFlags & (MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) )
+ {
+ BOOL bFailIfExist = 0 == (dwFlags & MOVEFILE_REPLACE_EXISTING);
+
+ fSuccess = CopyFileA( lpExistingFileNameA, lpNewFileNameA, bFailIfExist );
+
+ if ( fSuccess )
+ fSuccess = DeleteFileA( lpExistingFileNameA );
+ }
+
+ }
+
+ return fSuccess;
+}
+
+static BOOL MoveFileExImpl( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
+{
+ if ( 0 > ((LONG)GetVersion())) // High order bit indicates Win 9x
+ return MoveFileEx9x( lpExistingFileNameA, lpNewFileNameA, dwFlags );
+ else
+ return MoveFileExA( lpExistingFileNameA, lpNewFileNameA, dwFlags );
+}
+
+static bool SwapFiles( const std::_tstring& sFileName1, const std::_tstring& sFileName2 )
+{
+ std::_tstring sTempFileName = sFileName1 + TEXT(".tmp");
+
+ bool fSuccess = true;
+
+ //Try to move the original file to a temp file
+ fSuccess = MoveFileExImpl( sFileName1.c_str(), sTempFileName.c_str(), MOVEFILE_REPLACE_EXISTING);
+
+ std::_tstring mystr;
+
+ if ( fSuccess )
+ {
+ fSuccess = MoveFileExImpl( sFileName2.c_str(), sFileName1.c_str(), MOVEFILE_REPLACE_EXISTING );
+
+ if ( fSuccess )
+ {
+ fSuccess = MoveFileExImpl( sTempFileName.c_str(), sFileName2.c_str(),
+ MOVEFILE_REPLACE_EXISTING );
+ if ( !fSuccess )
+ {
+ MoveFileExImpl( sFileName1.c_str(), sFileName2.c_str(), MOVEFILE_REPLACE_EXISTING );
+ }
+ }
+ else
+ {
+ MoveFileExImpl( sTempFileName.c_str(), sFileName1.c_str(), MOVEFILE_REPLACE_EXISTING );
+ }
+ }
+ else
+ {
+ //It could be that there is no original file and therefore copying the original to a temp
+ // file failed. Examine if there is no original and if so then move file2 to file1
+
+ WIN32_FIND_DATA data;
+ HANDLE hdl = FindFirstFile(sFileName1.c_str(), &data);
+ if (hdl == INVALID_HANDLE_VALUE)
+ {
+ fSuccess = MoveFileExImpl( sFileName2.c_str(), sFileName1.c_str(), MOVEFILE_REPLACE_EXISTING );
+
+ // if ( fSuccess )
+ // {
+ // mystr = "Success";
+ // MessageBox( NULL, mystr.c_str(), "Titel", MB_OK );
+ // }
+ // else
+ // {
+ // char buff[256];
+ // wsprintf(buff, "Failure %d", GetLastError());
+ // MessageBox( NULL, buff, "Titel", MB_OK );
+ // }
+ }
+ else
+ {
+ FindClose(hdl);
+ }
+ }
+
+ OutputDebugStringFormat( TEXT("%s <-> %s: %s"), sFileName1.c_str(), sFileName2.c_str(), fSuccess ? TEXT("OK") : TEXT("FAILED") );
+
+ if (!fSuccess )
+ {
+ DWORD dwError = GetLastError();
+ LPVOID lpMsgBuf;
+ if ( FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL ))
+ {
+ OutputDebugStringFormat( TEXT("Error Code %d: %s"), dwError, lpMsgBuf );
+ LocalFree( lpMsgBuf );
+ }
+ else
+ OutputDebugStringFormat( TEXT("Error Code %d: Unknown"), dwError );
+ SetMsiErrorCode( dwError );
+ }
+
+ return fSuccess;
+}
+
+static std::_tstring strip( const std::_tstring& s, _TCHAR c )
+{
+ std::_tstring result = s;
+
+ std::_tstring::size_type f;
+
+ do
+ {
+ f = result.find( c );
+ if ( f != std::_tstring::npos )
+ result.erase( f, 1 );
+ } while ( f != std::_tstring::npos );
+
+ return result;
+}
+
+static std::_tstring trim( const std::_tstring& rString )
+{
+ std::_tstring temp = rString;
+
+ while ( temp.length() && temp[0] == ' ' || temp[0] == '\t' )
+ temp.erase( 0, 1 );
+
+ std::_tstring::size_type len = temp.length();
+
+ while ( len && temp[len-1] == ' ' || temp[len-1] == '\t' )
+ {
+ temp.erase( len - 1, 1 );
+ len = temp.length();
+ }
+
+ return temp;
+}
+
+static bool readLine( FILE *fp, std::_tstring& rLine )
+{
+ _TCHAR szBuffer[1024];
+ bool bSuccess = false;
+ bool bEOL = false;
+ std::_tstring line;
+
+
+ while ( !bEOL && _fgetts( szBuffer, sizeof(szBuffer), fp ) )
+ {
+ int len = _tcslen(szBuffer);
+
+ bSuccess = true;
+
+ while ( len && szBuffer[len - 1] == '\n' )
+ {
+ szBuffer[--len] = 0;
+ bEOL = true;
+ }
+
+ line.append( szBuffer );
+ }
+
+ rLine = line;
+ return bSuccess;
+}
+
+
+static std::_tstring getProfileString(
+ const std::_tstring& aFileName,
+ const std::_tstring& aSectionName,
+ const std::_tstring& aKeyName,
+ const std::_tstring& aDefault = _T("") )
+{
+ FILE *fp = _tfopen( aFileName.c_str(), _T("r") );
+ std::_tstring retValue = aDefault.length() ? aDefault : _T("");
+
+ if ( fp )
+ {
+ std::_tstring line;
+ std::_tstring section;
+
+ while ( readLine( fp, line ) )
+ {
+ line = trim( line );
+
+ if ( line.length() && line[0] == '[' )
+ {
+ line.erase( 0, 1 );
+ std::_tstring::size_type end = line.find( ']', 0 );
+
+ if ( std::_tstring::npos != end )
+ section = trim( line.substr( 0, end ) );
+ }
+ else
+ {
+
+ std::_tstring::size_type iEqualSign = line.find( '=', 0 );
+
+ if ( iEqualSign != std::_tstring::npos )
+ {
+ std::_tstring keyname = line.substr( 0, iEqualSign );
+ keyname = trim( keyname );
+
+ std::_tstring value = line.substr( iEqualSign + 1 /*, std::_tstring::npos */ );
+ value = trim( value );
+
+ if (
+ 0 == _tcsicmp( section.c_str(), aSectionName.c_str() ) &&
+ 0 == _tcsicmp( keyname.c_str(), aKeyName.c_str() )
+ )
+ {
+ retValue = value;
+ break;
+ }
+ }
+ }
+ }
+
+ fclose( fp );
+ }
+
+ return retValue;
+}
+
+static std::queue< std::_tstring > getProfileSections( const std::_tstring& aFileName )
+{
+ FILE *fp = _tfopen( aFileName.c_str(), _T("r") );
+ std::queue< std::_tstring > aResult;
+
+ OutputDebugStringFormat( TEXT("*** Retrieving Section Names ****") );
+
+ if ( fp )
+ {
+ std::_tstring line;
+ std::_tstring section;
+
+ while ( readLine( fp, line ) )
+ {
+ line = trim( line );
+
+ if ( line.length() && line[0] == '[' )
+ {
+ line.erase( 0, 1 );
+ std::_tstring::size_type end = line.find( ']', 0 );
+
+ if ( std::_tstring::npos != end )
+ section = trim( line.substr( 0, end ) );
+
+ aResult.push( section );
+
+ OutputDebugStringFormat( TEXT("Section: %s"), section.c_str() );
+
+ }
+ }
+
+ fclose( fp );
+ }
+
+ OutputDebugStringFormat( TEXT("*** Done Section Names ***") );
+
+ return aResult;
+}
+
+static std::queue< std::_tstring > getProfileKeys( const std::_tstring& aFileName, const std::_tstring& aSectionName )
+{
+ FILE *fp = _tfopen( aFileName.c_str(), _T("r") );
+ std::queue< std::_tstring > aResult;
+
+ OutputDebugStringFormat( TEXT("*** Retrieving Key Names for [%s] ***"), aSectionName.c_str() );
+
+ if ( fp )
+ {
+ std::_tstring line;
+ std::_tstring section;
+
+ while ( readLine( fp, line ) )
+ {
+ line = trim( line );
+
+ if ( line.length() && line[0] == '[' )
+ {
+ line.erase( 0, 1 );
+ std::_tstring::size_type end = line.find( ']', 0 );
+
+ if ( std::_tstring::npos != end )
+ section = trim( line.substr( 0, end ) );
+ }
+ else
+ {
+
+ std::_tstring::size_type iEqualSign = line.find( '=', 0 );
+
+ if ( iEqualSign != std::_tstring::npos )
+ {
+ std::_tstring keyname = line.substr( 0, iEqualSign );
+ keyname = trim( keyname );
+
+ if ( 0 == _tcsicmp( section.c_str(), aSectionName.c_str() ) )
+ {
+ aResult.push( keyname );
+
+ OutputDebugStringFormat( keyname.c_str() );
+
+ }
+ }
+ }
+ }
+
+ fclose( fp );
+ }
+
+ OutputDebugStringFormat( TEXT("*** Done Key Names for [%s] ***"), aSectionName.c_str() );
+
+ return aResult;
+}
+
+extern "C" UINT __stdcall InstallPatchedFiles( MSIHANDLE handle )
+{
+ std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ std::_tstring sProgramDir = sInstDir + TEXT("Basis\\program\\");
+ std::_tstring sPatchFile = sProgramDir + TEXT("patchlist.txt");
+
+ std::queue< std::_tstring > aSectionNames;
+ std::queue< std::_tstring > aKeyNames;
+
+ OutputDebugStringA( "Starting Custom Action" );
+
+ // std::_tstring mystr;
+ // mystr = "Patchfile: " + sPatchFile;
+ // MessageBox( NULL, mystr.c_str(), "Patchfile", MB_OK );
+
+ aSectionNames = getProfileSections( sPatchFile );
+ while ( !aSectionNames.empty() )
+ {
+ std::_tstring sSectionName = aSectionNames.front();
+ if ( std::_tstring(TEXT("_root")) == sSectionName ) { sSectionName = TEXT(""); }
+ // mystr = "Section: " + sSectionName;
+ // MessageBox( NULL, mystr.c_str(), "Titel", MB_OK );
+
+ aKeyNames = getProfileKeys( sPatchFile, sSectionName );
+ while ( !aKeyNames.empty() )
+ {
+ std::_tstring sKeyName = aKeyNames.front();
+ std::_tstring sValue = getProfileString( sPatchFile, sSectionName, sKeyName );
+
+ if ( sValue.length() )
+ {
+ std::_tstring sFileName1 = sKeyName;
+ std::_tstring sExtension = sValue;
+ std::_tstring sFileName2;
+
+ sFileName1 = strip( sFileName1, '\"' );
+ sExtension = strip( sExtension, '\"' );
+
+ sFileName1 = sInstDir + sSectionName + sFileName1;
+ sFileName2 = sFileName1 + sExtension;
+
+ // mystr = "Convert: " + sFileName1 + " to " + sFileName2;
+ // MessageBox( NULL, mystr.c_str(), "Titel", MB_OK );
+
+ SwapFiles( sFileName1, sFileName2 );
+ }
+
+ aKeyNames.pop();
+ }
+
+ aSectionNames.pop();
+ }
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall UninstallPatchedFiles( MSIHANDLE handle )
+{
+ TCHAR szValue[8192];
+ DWORD nValueSize = sizeof(szValue);
+ HKEY hKey;
+
+ std::_tstring sInstDir;
+
+ std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
+
+ if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else
+ return ERROR_SUCCESS;
+
+ std::_tstring sProgramDir = sInstDir + TEXT("Basis\\program\\");
+ std::_tstring sPatchFile = sProgramDir + TEXT("patchlist.txt");
+
+ std::queue< std::_tstring > aSectionNames;
+ std::queue< std::_tstring > aKeyNames;
+
+ // std::_tstring mystr;
+ // mystr = "Patchfile: " + sPatchFile;
+ // MessageBox( NULL, mystr.c_str(), "Titel", MB_OK );
+
+ aSectionNames = getProfileSections( sPatchFile );
+ while ( !aSectionNames.empty() )
+ {
+ std::_tstring sSectionName = aSectionNames.front();
+ if ( std::_tstring(TEXT("_root")) == sSectionName ) { sSectionName = TEXT(""); }
+ // mystr = "Section: " + sSectionName;
+ // MessageBox( NULL, mystr.c_str(), "Titel", MB_OK );
+
+ aKeyNames = getProfileKeys( sPatchFile, sSectionName );
+ while( !aKeyNames.empty() )
+ {
+ std::_tstring sKeyName = aKeyNames.front();
+ std::_tstring sValue = getProfileString( sPatchFile, sSectionName, sKeyName );
+
+ if ( sValue.length() )
+ {
+ std::_tstring sFileName1 = sKeyName;
+ std::_tstring sExtension = sValue;
+ std::_tstring sFileName2;
+
+ sFileName1 = strip( sFileName1, '\"' );
+ sExtension = strip( sExtension, '\"' );
+
+ sFileName1 = sInstDir + sSectionName + sFileName1;
+ sFileName2 = sFileName1 + sExtension;
+
+ // mystr = "Convert: " + sFileName1 + " to " + sFileName2;
+ // MessageBox( NULL, mystr.c_str(), "Titel", MB_OK );
+
+ SwapFiles( sFileName2, sFileName1 );
+ }
+
+ aKeyNames.pop();
+ }
+
+ aSectionNames.pop();
+ }
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall IsOfficeRunning( MSIHANDLE handle )
+{
+ std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ std::_tstring sResourceDir = sInstDir + TEXT("Basis\\program\\resource\\");
+ std::_tstring sPattern = sResourceDir + TEXT("vcl*.res");
+
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ BOOL fSuccess = false;
+ bool fRenameSucceeded;
+
+ do
+ {
+ std::_tstring sResourceFile = sResourceDir + aFindFileData.cFileName;
+ std::_tstring sIntermediate = sResourceFile + TEXT(".tmp");
+
+ fRenameSucceeded = MoveFileExImpl( sResourceFile.c_str(), sIntermediate.c_str(), MOVEFILE_REPLACE_EXISTING );
+ if ( fRenameSucceeded )
+ {
+ MoveFileExImpl( sIntermediate.c_str(), sResourceFile.c_str(), 0 );
+ fSuccess = FindNextFile( hFind, &aFindFileData );
+ }
+ } while ( fSuccess && fRenameSucceeded );
+
+ if ( !fRenameSucceeded )
+ {
+ MsiSetProperty(handle, TEXT("OFFICERUNS"), TEXT("1"));
+ SetMsiErrorCode( MSI_ERROR_OFFICE_IS_RUNNING );
+ }
+
+ FindClose( hFind );
+ }
+
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall SetFeatureState( MSIHANDLE handle )
+{
+ std::_tstring mystr;
+
+ // 1. Reading Product Code from setup.ini of installed Office
+
+ std::_tstring sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+ // MessageBox(NULL, sInstallPath.c_str(), "INSTALLLOCATION", MB_OK);
+ std::_tstring sSetupiniPath = sInstallPath + TEXT("program\\setup.ini");
+
+ TCHAR szProductCode[32767];
+
+ GetPrivateProfileString(
+ TEXT("Bootstrap"),
+ TEXT("ProductCode"),
+ TEXT("NOTFOUND"),
+ szProductCode,
+ SAL_N_ELEMENTS(szProductCode),
+ sSetupiniPath.c_str()
+ );
+
+ if ( !_tcsicmp( szProductCode, TEXT("NOTFOUND") ) )
+ {
+ // No setup.ini or no "ProductCode" in setup.ini. This is an invalid directory.
+ // MessageBox(NULL, "NOTFOUND set", "DEBUG", MB_OK);
+ return ERROR_SUCCESS;
+ }
+
+ // 2. Converting Product code
+
+ std::_tstring productCode = TEXT(szProductCode);
+ productCode = ConvertGuid(std::_tstring(productCode.c_str() + 1, productCode.length() - 2));
+ mystr = TEXT("Changed product code: ") + productCode;
+ // MessageBox(NULL, mystr.c_str(), "ProductCode", MB_OK);
+
+ // 3. Setting path in the Windows registry to find installed features
+
+ std::_tstring registryKey;
+ HKEY registryRoot;
+
+ if ( IsSetMsiProperty(handle, TEXT("ALLUSERS")) )
+ {
+ registryRoot = HKEY_LOCAL_MACHINE;
+ registryKey = TEXT("Software\\Classes\\Installer\\Features\\") + productCode;
+ mystr = registryKey;
+ // MessageBox( NULL, mystr.c_str(), "ALLUSERS", MB_OK );
+ }
+ else
+ {
+ registryRoot = HKEY_CURRENT_USER;
+ registryKey = TEXT("Software\\Microsoft\\Installer\\Features\\") + productCode;
+ mystr = registryKey;
+ // MessageBox( NULL, mystr.c_str(), "ALLUSERS", MB_OK );
+ }
+
+ // 4. Collecting all installed features from Windows registry
+
+ HKEY hKey;
+ if (RegOpenKey(registryRoot, registryKey.c_str(), &hKey) == ERROR_SUCCESS)
+ {
+ int counter = 0;
+ // DWORD counter = 0;
+ LONG lEnumResult;
+
+ do
+ {
+ TCHAR szValueName[8192];
+ DWORD nValueNameSize = sizeof(szValueName);
+ LPDWORD pValueNameSize = &nValueNameSize;
+ TCHAR szValueData[8192];
+ DWORD nValueDataSize = sizeof(szValueData);
+
+ lEnumResult = RegEnumValue( hKey, counter, szValueName, pValueNameSize, NULL, NULL, (LPBYTE)szValueData, &nValueDataSize);
+
+ if ( ERROR_SUCCESS == lEnumResult )
+ {
+ std::_tstring sValueName = szValueName;
+ std::_tstring sValueData = szValueData;
+
+ // mystr = sValueName;
+ // MessageBox( NULL, mystr.c_str(), "ValueName", MB_OK );
+ // mystr = sValueData;
+ // MessageBox( NULL, mystr.c_str(), "ValueData", MB_OK );
+
+ // Does this feature exist in this patch?
+ if ( IsSetMsiProperty(handle, sValueName) )
+ {
+ // Feature is not installed, if szValueData starts with a "square" (ascii 6)
+ if ( 6 == szValueData[0] )
+ {
+ MsiSetFeatureState(handle,sValueName.c_str(),INSTALLSTATE_ABSENT); // do not install this feature
+ // mystr = TEXT("Do NOT install: ") + sValueName;
+ // MessageBox( NULL, mystr.c_str(), "ValueName", MB_OK );
+ }
+ else
+ {
+ MsiSetFeatureState(handle,sValueName.c_str(),INSTALLSTATE_LOCAL); // do install this feature
+ // mystr = TEXT("Do install: ") + sValueName;
+ // MessageBox( NULL, mystr.c_str(), "ValueName", MB_OK );
+ }
+ }
+ }
+
+ counter = counter + 1;
+
+ } while ( ERROR_SUCCESS == lEnumResult );
+
+ RegCloseKey( hKey );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall SetNewFeatureState( MSIHANDLE handle )
+{
+ std::_tstring mystr;
+ std::_tstring sValueName;
+
+ sValueName = TEXT("gm_o_Onlineupdate");
+
+ if (IsSetMsiProperty(handle, TEXT("SELECT_OU_FEATURE")))
+ {
+ MsiSetFeatureState(handle,sValueName.c_str(),INSTALLSTATE_LOCAL); // do install this feature
+ // mystr = TEXT("OnlineUpdate wird installiert!");
+ // MessageBox(NULL, mystr.c_str(), "INSTALLSTATE_LOCAL", MB_OK);
+ }
+ else
+ {
+ MsiSetFeatureState(handle,sValueName.c_str(),INSTALLSTATE_ABSENT); // do not install this feature
+ // mystr = TEXT("OnlineUpdate wird NICHT installiert!");
+ // MessageBox(NULL, mystr.c_str(), "INSTALLSTATE_ABSENT", MB_OK);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall ShowOnlineUpdateDialog( MSIHANDLE handle )
+{
+ // Checking existence of file "updchk.uno.dll", which shows, that
+ // Online Update functionality is always available. Then the dialog
+ // that offers the Online Update is superfluous.
+
+ std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ std::_tstring sProgramDir = sInstDir + TEXT("Basis\\program\\");
+ std::_tstring sSearchFile = sProgramDir + TEXT("updchk.uno.dll");
+
+ WIN32_FIND_DATA data;
+ HANDLE hdl = FindFirstFile(sSearchFile.c_str(), &data);
+ if (hdl != INVALID_HANDLE_VALUE) // the file exists
+ {
+ // std::_tstring mystr;
+ // mystr = "Found file: " + sSearchFile;
+ // MessageBox( NULL, mystr.c_str(), "Found file", MB_OK );
+
+ // And finally setting property SHOW_ONLINEUPDATE_DIALOG
+ // to hide this dialog
+ UnsetMsiProperty(handle, TEXT("SHOW_ONLINEUPDATE_DIALOG"));
+
+ // Setting SELECT_OU_FEATURE to 1, which is probably superfluous
+ // because this is already the default value. But only this
+ // guarantees, that CustomAction SetNewFeatureState always sets
+ // the correct FeatureState for "gm_o_Onlineupdate", if it is
+ // already installed.
+ SetMsiProperty(handle, TEXT("SELECT_OU_FEATURE"));
+ }
+ else
+ {
+ // std::_tstring mystr;
+ // mystr = "Did not find file: " + sSearchFile;
+ // MessageBox( NULL, mystr.c_str(), "File not found", MB_OK );
+
+ // If the file does not exist, the Online Update dialog
+ // has to be shown.
+ SetMsiProperty(handle, TEXT("SHOW_ONLINEUPDATE_DIALOG"));
+ FindClose(hdl);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/quickstarter/exports.dxp b/setup_native/source/win32/customactions/quickstarter/exports.dxp
new file mode 100644
index 000000000000..c1343f8e7e76
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/exports.dxp
@@ -0,0 +1,3 @@
+InstallExecSequenceEntry
+DeinstallExecSequenceEntry
+ \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/quickstarter/makefile.mk b/setup_native/source/win32/customactions/quickstarter/makefile.mk
new file mode 100644
index 000000000000..0861c20efed8
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/makefile.mk
@@ -0,0 +1,102 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=quickstarter
+TARGET1=sdqsmsi
+TARGET2=qslnkmsi
+
+# --- Settings -----------------------------------------------------
+
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+UWINAPILIB=
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+STDSHL += \
+ $(ADVAPI32LIB)\
+ $(SHELL32LIB)\
+ $(MSILIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+STDSHL += $(LIBSTLPORTST)
+.ENDIF
+
+.IF "$(COM)"=="GCC"
+STDSHL+= \
+ $(KERNEL32LIB)\
+ -lmsvcrt
+.ENDIF
+
+SHL1OBJS = $(SLO)$/shutdown_quickstart.obj \
+ $(SLO)$/quickstarter.obj
+
+SHL1TARGET = $(TARGET1)
+SHL1IMPLIB = i$(TARGET1)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+SHL1DEPN=$(SHL1OBJS)
+DEF1EXPORTFILE=$(TARGET1).dxp
+
+# --- Files --------------------------------------------------------
+
+SHL2OBJS = $(SLO)$/remove_quickstart_link.obj \
+ $(SLO)$/quickstarter.obj
+
+SHL2TARGET = $(TARGET2)
+SHL2IMPLIB = i$(TARGET2)
+
+SHL2DEF = $(MISC)$/$(SHL2TARGET).def
+SHL2BASE = 0x1c000000
+DEF2NAME=$(SHL2TARGET)
+SHL2DEPN=$(SHL1OBJS)
+DEF2EXPORTFILE=$(TARGET2).dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
diff --git a/setup_native/source/win32/customactions/quickstarter/qslnkmsi.dxp b/setup_native/source/win32/customactions/quickstarter/qslnkmsi.dxp
new file mode 100644
index 000000000000..56f67cc93783
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/qslnkmsi.dxp
@@ -0,0 +1,2 @@
+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 000000000000..fbb4982a96f4
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/quickstarter.cxx
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "quickstarter.hxx"
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#include <psapi.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+#include <tlhelp32.h>
+#include <malloc.h>
+
+std::string GetOfficeInstallationPath(MSIHANDLE handle)
+{
+ std::string progpath;
+ DWORD sz = 0;
+ LPTSTR dummy = TEXT("");
+
+ if (MsiGetProperty(handle, TEXT("INSTALLLOCATION"), dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++; // space for the final '\0'
+ DWORD nbytes = sz * sizeof(TCHAR);
+ LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetProperty(handle, TEXT("INSTALLLOCATION"), buff, &sz);
+ progpath = buff;
+ }
+ return progpath;
+}
+
+std::string GetOfficeProductName(MSIHANDLE handle)
+{
+ std::string productname;
+ DWORD sz = 0;
+ LPTSTR dummy = TEXT("");
+
+ if (MsiGetProperty(handle, TEXT("ProductName"), dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++; // space for the final '\0'
+ DWORD nbytes = sz * sizeof(TCHAR);
+ LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetProperty(handle, TEXT("ProductName"), buff, &sz);
+ productname = buff;
+ }
+ return productname;
+}
+
+std::string GetQuickstarterLinkName(MSIHANDLE handle)
+{
+ std::string quickstarterlinkname;
+ DWORD sz = 0;
+ LPTSTR dummy = TEXT("");
+
+ if (MsiGetProperty(handle, TEXT("Quickstarterlinkname"), dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++; // space for the final '\0'
+ DWORD nbytes = sz * sizeof(TCHAR);
+ LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetProperty(handle, TEXT("Quickstarterlinkname"), buff, &sz);
+ quickstarterlinkname = buff;
+ }
+ else if (MsiGetProperty(handle, TEXT("ProductName"), dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++; // space for the final '\0'
+ DWORD nbytes = sz * sizeof(TCHAR);
+ LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetProperty(handle, TEXT("ProductName"), buff, &sz);
+ quickstarterlinkname = buff;
+ }
+ return quickstarterlinkname;
+}
+
+inline bool IsValidHandle( HANDLE handle )
+{
+ return NULL != handle && INVALID_HANDLE_VALUE != handle;
+}
+
+
+static HANDLE WINAPI _CreateToolhelp32Snapshot( DWORD dwFlags, DWORD th32ProcessID )
+{
+ typedef HANDLE (WINAPI *FN_PROC)( DWORD dwFlags, DWORD th32ProcessID );
+ static FN_PROC lpProc = NULL;
+
+ HANDLE hSnapshot = NULL;
+
+ if ( !lpProc )
+ {
+ HMODULE hLibrary = GetModuleHandle("KERNEL32.DLL");
+
+ if ( hLibrary )
+ lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "CreateToolhelp32Snapshot" ));
+ }
+
+ if ( lpProc )
+ hSnapshot = lpProc( dwFlags, th32ProcessID );
+
+ return hSnapshot;
+}
+
+static BOOL WINAPI _Process32First( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 )
+{
+ typedef BOOL (WINAPI *FN_PROC)( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 );
+ static FN_PROC lpProc = NULL;
+
+ BOOL fSuccess = FALSE;
+
+ if ( !lpProc )
+ {
+ HMODULE hLibrary = GetModuleHandle("KERNEL32.DLL");
+
+ if ( hLibrary )
+ lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "Process32First" ));
+ }
+
+ if ( lpProc )
+ fSuccess = lpProc( hSnapshot, lppe32 );
+
+ return fSuccess;
+}
+
+static BOOL WINAPI _Process32Next( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 )
+{
+ typedef BOOL (WINAPI *FN_PROC)( HANDLE hSnapshot, PROCESSENTRY32 *lppe32 );
+ static FN_PROC lpProc = NULL;
+
+ BOOL fSuccess = FALSE;
+
+ if ( !lpProc )
+ {
+ HMODULE hLibrary = GetModuleHandle("KERNEL32.DLL");
+
+ if ( hLibrary )
+ lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "Process32Next" ));
+ }
+
+ if ( lpProc )
+ fSuccess = lpProc( hSnapshot, lppe32 );
+
+ return fSuccess;
+}
+
+static std::string GetProcessImagePath_9x( DWORD dwProcessId )
+{
+ std::string sImagePath;
+
+ HANDLE hSnapshot = _CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
+
+ if ( IsValidHandle( hSnapshot ) )
+ {
+ PROCESSENTRY32 pe32 = { 0 };
+
+ pe32.dwSize = sizeof(PROCESSENTRY32);
+
+ BOOL fSuccess = _Process32First( hSnapshot, &pe32 );
+ bool found = false;
+
+ while ( !found && fSuccess )
+ {
+ if ( pe32.th32ProcessID == dwProcessId )
+ {
+ found = true;
+ sImagePath = pe32.szExeFile;
+ }
+
+ if ( !found )
+ fSuccess = _Process32Next( hSnapshot, &pe32 );
+ }
+
+ CloseHandle( hSnapshot );
+ }
+
+ return sImagePath;
+}
+
+static DWORD WINAPI _GetModuleFileNameExA( HANDLE hProcess, HMODULE hModule, LPSTR lpFileName, DWORD nSize )
+{
+ typedef DWORD (WINAPI *FN_PROC)( HANDLE hProcess, HMODULE hModule, LPSTR lpFileName, DWORD nSize );
+
+ static FN_PROC lpProc = NULL;
+
+ if ( !lpProc )
+ {
+ HMODULE hLibrary = LoadLibrary("PSAPI.DLL");
+
+ if ( hLibrary )
+ lpProc = reinterpret_cast< FN_PROC >(GetProcAddress( hLibrary, "GetModuleFileNameExA" ));
+ }
+
+ if ( lpProc )
+ return lpProc( hProcess, hModule, lpFileName, nSize );
+
+ return 0;
+
+}
+
+static std::string GetProcessImagePath_NT( DWORD dwProcessId )
+{
+ std::string sImagePath;
+
+ HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId );
+
+ if ( IsValidHandle( hProcess ) )
+ {
+ CHAR szPathBuffer[MAX_PATH] = "";
+
+ if ( _GetModuleFileNameExA( hProcess, NULL, szPathBuffer, sizeof(szPathBuffer) ) )
+ sImagePath = szPathBuffer;
+
+ CloseHandle( hProcess );
+ }
+
+ return sImagePath;
+}
+
+std::string GetProcessImagePath( DWORD dwProcessId )
+{
+ return (LONG)GetVersion() < 0 ? GetProcessImagePath_9x( dwProcessId ) : GetProcessImagePath_NT( dwProcessId );
+}
+
+/* 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 000000000000..d02532e08cce
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/quickstarter.hxx
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#pragma once
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string>
+
+std::string GetOfficeInstallationPath(MSIHANDLE handle);
+std::string GetOfficeProductName(MSIHANDLE handle);
+std::string GetQuickstarterLinkName(MSIHANDLE handle);
+std::string GetProcessImagePath( DWORD dwProcessId );
+
+/* 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 000000000000..1d1b3c61d67a
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/remove_quickstart_link.cxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#pragma warning(disable: 4917)
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <shlobj.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string>
+#include "quickstarter.hxx"
+
+
+extern "C" UINT __stdcall RemoveQuickstarterLink( MSIHANDLE hMSI )
+{
+ CHAR szStartupPath[MAX_PATH];
+
+ if ( SHGetSpecialFolderPathA( NULL, szStartupPath, CSIDL_STARTUP, FALSE ) )
+ {
+ std::string sQuickstartLinkPath = szStartupPath;
+
+ sQuickstartLinkPath += "\\";
+ sQuickstartLinkPath += GetQuickstarterLinkName( hMSI );
+ sQuickstartLinkPath += ".lnk";
+
+ DeleteFileA( sQuickstartLinkPath.c_str() );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/quickstarter/sdqsmsi.dxp b/setup_native/source/win32/customactions/quickstarter/sdqsmsi.dxp
new file mode 100644
index 000000000000..49ec00aff0d8
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/sdqsmsi.dxp
@@ -0,0 +1,2 @@
+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 000000000000..86e9585044ae
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/shutdown_quickstart.cxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "quickstarter.hxx"
+#include <setup_native/qswin32.h>
+
+static BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam )
+{
+ MSIHANDLE hMSI = static_cast< MSIHANDLE >( lParam );
+ CHAR szClassName[sizeof(QUICKSTART_CLASSNAMEA) + 1];
+
+ int nCharsCopied = GetClassName( hWnd, szClassName, sizeof( szClassName ) );
+
+ if ( nCharsCopied && !stricmp( QUICKSTART_CLASSNAMEA, szClassName ) )
+ {
+ DWORD dwProcessId;
+
+ if ( GetWindowThreadProcessId( hWnd, &dwProcessId ) )
+ {
+ std::string sImagePath = GetProcessImagePath( dwProcessId );
+ std::string sOfficeImageDir = GetOfficeInstallationPath( hMSI ) + "program\\";
+
+ if ( !strnicmp( sImagePath.c_str(), sOfficeImageDir.c_str(), sOfficeImageDir.length() ) )
+ {
+ UINT uMsgShutdownQuickstart = RegisterWindowMessageA( SHUTDOWN_QUICKSTART_MESSAGEA );
+
+ if ( uMsgShutdownQuickstart )
+ SendMessageA( 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" 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/rebase/makefile.mk b/setup_native/source/win32/customactions/rebase/makefile.mk
new file mode 100644
index 000000000000..47cd8fd59c87
--- /dev/null
+++ b/setup_native/source/win32/customactions/rebase/makefile.mk
@@ -0,0 +1,90 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=rebase
+
+# --- Settings -----------------------------------------------------
+
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+MINGW_NODLL=YES
+
+.INCLUDE : settings.mk
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+UWINAPILIB=
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+STDSHL += \
+ $(ADVAPI32LIB)\
+ $(SHELL32LIB)\
+ $(MSILIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+STDSHL += $(LIBSTLPORTST)
+.ENDIF
+
+.IF "$(COM)"=="GCC"
+STDSHL+= \
+ $(KERNEL32LIB)\
+ -lmsvcrt \
+ $(PSDK_HOME)$/lib$/imagehlp.lib
+.ELSE
+STDSHL+= \
+ Imagehlp.lib
+.ENDIF
+
+SHL1OBJS = \
+ $(SLO)$/rebase.obj
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+SHL1DEPN=$(SHL1OBJS)
+DEF1EXPORTFILE=$(TARGET).dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
diff --git a/setup_native/source/win32/customactions/rebase/rebase.cxx b/setup_native/source/win32/customactions/rebase/rebase.cxx
new file mode 100644
index 000000000000..1eb3fedbf2f0
--- /dev/null
+++ b/setup_native/source/win32/customactions/rebase/rebase.cxx
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#undef UNICODE
+#undef _UNICODE
+
+#pragma once
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#include <imagehlp.h>
+#include <tchar.h>
+#include <strsafe.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <time.h>
+#include <string>
+
+const DWORD PE_Signature = 0x00004550;
+
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
+{
+ CHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugStringA( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCSTR, ... )
+{
+}
+#endif
+
+static bool IsValidHandle( HANDLE handle )
+{
+ return NULL != handle && INVALID_HANDLE_VALUE != handle;
+}
+
+static std::string GetMsiProperty(MSIHANDLE handle, const std::string& sProperty)
+{
+ std::string result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+ return result;
+}
+
+static BOOL rebaseImage( const std::string& filePath, LPVOID address )
+{
+ ULONG ulOldImageSize;
+ ULONG_PTR lpOldImageBase;
+ ULONG ulNewImageSize;
+ ULONG_PTR lpNewImageBase = reinterpret_cast<ULONG_PTR>(address);
+
+ BOOL bResult = ReBaseImage(
+ (PSTR)filePath.c_str(),
+ (PSTR)"",
+ TRUE,
+ FALSE,
+ FALSE,
+ 0,
+ &ulOldImageSize,
+ &lpOldImageBase,
+ &ulNewImageSize,
+ &lpNewImageBase,
+ (ULONG)time(NULL) );
+
+ return bResult;
+}
+
+static BOOL rebaseImage( MSIHANDLE /*handle*/, const std::string& sFilePath, LPVOID address )
+{
+ std::string mystr;
+ mystr = "Full file: " + sFilePath;
+
+ BOOL bResult = rebaseImage( sFilePath, address );
+
+ if ( !bResult )
+ {
+ OutputDebugStringFormat( "Rebasing library %s failed", mystr.c_str() );
+ }
+
+ return bResult;
+}
+
+static BOOL rebaseImagesInFolder( MSIHANDLE handle, const std::string& sPath, LPVOID address )
+{
+ std::string sDir = sPath;
+ std::string sPattern = sPath + TEXT("*.dll");
+
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ BOOL fSuccess = false;
+
+ do
+ {
+ std::string sLibFile = sDir + aFindFileData.cFileName;
+ rebaseImage( handle, sLibFile, address );
+ fSuccess = FindNextFile( hFind, &aFindFileData );
+ }
+ while ( fSuccess );
+
+ FindClose( hFind );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static BOOL rebaseImages( MSIHANDLE handle, LPVOID pAddress )
+{
+ std::string sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+
+ std::string sBasisDir = sInstallPath + TEXT("Basis\\program\\");
+ std::string sOfficeDir = sInstallPath + TEXT("program\\");
+ std::string sUreDir = sInstallPath + TEXT("URE\\bin\\");
+
+ BOOL bResult = rebaseImagesInFolder( handle, sBasisDir, pAddress );
+ bResult &= rebaseImagesInFolder( handle, sOfficeDir, pAddress );
+ bResult &= rebaseImagesInFolder( handle, sUreDir, pAddress );
+
+ return bResult;
+}
+
+static BOOL IsServerSystem( MSIHANDLE /*handle*/ )
+{
+ OSVERSIONINFOEX osVersionInfoEx;
+ osVersionInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&osVersionInfoEx));
+
+ if ( osVersionInfoEx.wProductType != VER_NT_WORKSTATION )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+extern "C" BOOL __stdcall RebaseLibrariesOnProperties( MSIHANDLE handle )
+{
+ static LPVOID pDefault = reinterpret_cast<LPVOID>(0x10000000);
+
+ std::string sDontOptimizeLibs = GetMsiProperty(handle, TEXT("DONTOPTIMIZELIBS"));
+ if ( sDontOptimizeLibs.length() > 0 && sDontOptimizeLibs == "1" )
+ return TRUE;
+
+ if ( !IsServerSystem( handle ))
+ return rebaseImages( handle, pDefault );
+
+ return TRUE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/rebase/rebase.dxp b/setup_native/source/win32/customactions/rebase/rebase.dxp
new file mode 100644
index 000000000000..47ea23951f04
--- /dev/null
+++ b/setup_native/source/win32/customactions/rebase/rebase.dxp
@@ -0,0 +1 @@
+RebaseLibrariesOnProperties
diff --git a/setup_native/source/win32/customactions/reg4allmsdoc/exports.dxp b/setup_native/source/win32/customactions/reg4allmsdoc/exports.dxp
new file mode 100644
index 000000000000..566981ba569e
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4allmsdoc/exports.dxp
@@ -0,0 +1,3 @@
+FindRegisteredExtensions
+LookForRegisteredExtensions
+RegisterSomeExtensions \ No newline at end of file
diff --git a/setup_native/source/win32/customactions/reg4allmsdoc/makefile.mk b/setup_native/source/win32/customactions/reg4allmsdoc/makefile.mk
new file mode 100644
index 000000000000..d58291966ef2
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4allmsdoc/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=reg4allmsdoc
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+CFLAGS+=-DUNICODE -D_UNICODE
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = $(SLO)$/reg4allmsi.obj
+
+SHL1STDLIBS= $(KERNEL32LIB)\
+ $(USER32LIB)\
+ $(ADVAPI32LIB)\
+ $(SHELL32LIB)\
+ $(MSILIB)\
+ $(SHLWAPILIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+SHL1STDLIBS+=$(LIBSTLPORTST)
+.ENDIF
+
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
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 000000000000..54a471acf095
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
@@ -0,0 +1,504 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <string>
+#include <strsafe.h>
+
+//----------------------------------------------------------
+static const CHAR* g_Extensions[] =
+{
+ ".doc", // Microsoft Word Text [0]
+ ".dot", // Microsoft Word Template
+ ".rtf", // rtf text
+ ".docx", // Office Word 2007 XML document
+ ".docm", // Office Word 2007 XML macro-enabled document
+ ".dotx", // Office Word 2007 XML template
+ ".dotm", // Office Word 2007 XML macro-enabled template
+ ".xlw", // Microsoft Excel
+ ".xls", // Microsoft Excel
+ ".xlt", // Microsoft Excel Template
+ ".xlsx", // Office Excel 2007 XML workbook
+ ".xlsm", // Office Excel 2007 XML macro-enabled workbook
+ ".xltx", // Office Excel 2007 XML template
+ ".xltm", // Office Excel 2007 XML macro-enabled template
+ ".xlsb", // Office Excel 2007 binary workbook (BIFF12)
+ ".ppt", // Microsoft Powerpoint
+ ".pps", // Microsoft Powerpoint
+ ".pot", // Microsoft Powerpoint Template
+ ".pptx", // Office PowerPoint 2007 XML presentation
+ ".pptm", // Office PowerPoint 2007 macro-enabled XML presentation
+ ".potx", // Office PowerPoint 2007 XML template
+ ".potm", // Office PowerPoint 2007 macro-enabled XML template
+ ".ppsx", // Office PowerPoint 2007 XML show
+ 0
+};
+
+static const int WORD_START = 0;
+static const int EXCEL_START = 7;
+static const int POWERPOINT_START = 15;
+static const int POWERPOINT_END = 23;
+
+// ".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 OutputDebugStringFormat( LPCSTR pFormat, ... )
+{
+ CHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugStringA( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCSTR, ... )
+{
+}
+#endif
+
+//----------------------------------------------------------
+static BOOL CheckExtensionInRegistry( LPCSTR lpSubKey )
+{
+ BOOL bRet = false;
+ HKEY hKey = NULL;
+ LONG lResult = RegOpenKeyExA( HKEY_CLASSES_ROOT, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ CHAR szBuffer[1024];
+ DWORD nSize = sizeof( szBuffer );
+
+ lResult = RegQueryValueExA( hKey, "", NULL, NULL, (LPBYTE)szBuffer, &nSize );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ szBuffer[nSize] = '\0';
+ OutputDebugStringFormat( "Found value [%s] for key [%s].\n", szBuffer, lpSubKey );
+
+ if ( strncmp( szBuffer, "WordPad.Document.1", 18 ) == 0 )
+ { // We will replace registration for word pad
+ bRet = true;
+ }
+ if ( strncmp( szBuffer, "OpenOffice.org.", 15 ) == 0 )
+ { // We will replace registration for our own types, too
+ bRet = true;
+ }
+ if ( strncmp( szBuffer, "ooostub.", 8 ) == 0 )
+ { // We will replace registration for ooostub, too
+ bRet = true;
+ }
+ }
+ 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 LONG DeleteSubKeyTree( HKEY RootKey, LPCSTR lpKey )
+{
+ HKEY hKey;
+ LONG rc = RegOpenKeyExA( RootKey, lpKey, 0, KEY_READ | DELETE, &hKey );
+
+ if (ERROR_SUCCESS == rc)
+ {
+ LPCSTR lpSubKey;
+ DWORD nMaxSubKeyLen;
+
+ rc = RegQueryInfoKeyA( hKey, 0, 0, 0, 0, &nMaxSubKeyLen, 0, 0, 0, 0, 0, 0 );
+ nMaxSubKeyLen++; // space for trailing '\0'
+ lpSubKey = reinterpret_cast<CHAR*>( _alloca( nMaxSubKeyLen*sizeof(CHAR) ) );
+
+ while (ERROR_SUCCESS == rc)
+ {
+ DWORD nLen = nMaxSubKeyLen;
+ rc = RegEnumKeyExA( hKey, 0, (LPSTR)lpSubKey, &nLen, 0, 0, 0, 0); // always index zero
+
+ if ( ERROR_NO_MORE_ITEMS == rc )
+ {
+ rc = RegDeleteKeyA( RootKey, lpKey );
+ if ( rc == ERROR_SUCCESS )
+ OutputDebugStringFormat( "deleted key [%s] from registry.\n", lpKey );
+ else
+ OutputDebugStringFormat( "RegDeleteKeyA %s returned %ld.\n", lpKey, rc );
+ break;
+ }
+ else if ( rc == ERROR_SUCCESS )
+ {
+ rc = DeleteSubKeyTree( hKey, lpSubKey );
+ if ( ERROR_SUCCESS != rc )
+ OutputDebugStringFormat( "RegDeleteKeyA %s returned %ld.\n", lpSubKey, rc );
+ }
+
+ }
+ RegCloseKey(hKey);
+ }
+ else
+ {
+ OutputDebugStringFormat( "RegOpenKeyExA %s returned %ld.\n", lpKey, rc );
+ }
+
+ return rc;
+}
+
+//----------------------------------------------------------
+static BOOL RemoveExtensionInRegistry( LPCSTR lpSubKey )
+{
+ CHAR szBuffer[4096];
+ DWORD nSize = sizeof( szBuffer );
+ HKEY hKey = NULL;
+ HKEY hSubKey = NULL;
+ LONG lResult = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes", 0, KEY_QUERY_VALUE, &hKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ lResult = RegOpenKeyExA( hKey, lpSubKey, 0, KEY_QUERY_VALUE, &hSubKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ DWORD nSubKeys = 1;
+ szBuffer[0] = '\0';
+
+ // we get the value of the default key fist and while we are on querying,
+ // we ask for the subkey count, too
+ lResult = RegQueryValueExA( hSubKey, "", NULL, NULL, (LPBYTE)szBuffer, &nSize );
+ if ( ERROR_SUCCESS == lResult )
+ RegQueryInfoKeyA( hSubKey, 0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0 );
+ RegCloseKey( hSubKey );
+
+ // we will remove all key with an default value starting with ooostub but
+ // we have to be careful about MSO keys
+ if ( strncmp( szBuffer, "opendocument.", 13 ) == 0 )
+ {
+ if ( nSubKeys == 0 )
+ {
+ DeleteSubKeyTree( hKey, lpSubKey );
+ }
+ else
+ {
+ lResult = RegOpenKeyExA( hKey, lpSubKey, 0, KEY_SET_VALUE, &hSubKey );
+ if ( ERROR_SUCCESS == lResult )
+ RegDeleteValueA( hSubKey, "" );
+ else
+ OutputDebugStringFormat( "Could not open key %s for deleting: RegOpenKeyEx returned %ld.\n", lpSubKey, lResult );
+ }
+ }
+ }
+
+ RegCloseKey( hKey );
+ }
+
+ return ( ERROR_SUCCESS == lResult );
+}
+
+//----------------------------------------------------------
+bool GetMsiProp( MSIHANDLE handle, LPCSTR name, /*out*/std::string& value )
+{
+ DWORD sz = 0;
+ LPSTR dummy = "";
+ if (MsiGetPropertyA(handle, name, dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof(TCHAR);
+ LPSTR buff = reinterpret_cast<LPSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetPropertyA(handle, name, buff, &sz);
+ value = buff;
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------
+bool IsSetMsiProp( MSIHANDLE handle, LPCSTR name )
+{
+ std::string val;
+ GetMsiProp( handle, name, val );
+ return (val == "1");
+}
+
+//----------------------------------------------------------
+static void registerForExtension( MSIHANDLE handle, const int nIndex, bool bRegister )
+{
+ CHAR sPropName[256];
+ StringCchCopyA( sPropName, 256, "REGISTER_" );
+ StringCchCatA( sPropName, 256, (g_Extensions[nIndex])+1 );
+ CharUpperBuffA( sPropName+9, 4 );
+
+ if ( bRegister ) {
+ MsiSetPropertyA( handle, sPropName, "1" );
+ OutputDebugStringFormat( "Set MSI property %s.\n", sPropName );
+ } else {
+ MsiSetPropertyA( handle, sPropName, "0" );
+ OutputDebugStringFormat( "Unset MSI property %s.\n", sPropName );
+ }
+}
+
+//----------------------------------------------------------
+static void registerForExtensions( MSIHANDLE handle, BOOL bRegisterAll )
+{ // Check all file extensions
+ int nIndex = 0;
+ while ( g_Extensions[nIndex] != 0 )
+ {
+ 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 && ( g_Extensions[nIndex] != 0 ) && ( nIndex < nEnd ) )
+ {
+ bFound = ! CheckExtensionInRegistry( g_Extensions[nIndex] );
+
+ if ( bFound )
+ OutputDebugStringFormat( "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 ( ( g_Extensions[nIndex] != 0 ) && ( nIndex < nEnd ) )
+ {
+ registerForExtension( handle, nIndex++, bRegister );
+ }
+}
+
+//----------------------------------------------------------
+//----------------------------------------------------------
+//----------------------------------------------------------
+extern "C" UINT __stdcall LookForRegisteredExtensions( MSIHANDLE handle )
+{
+ OutputDebugStringFormat( "LookForRegisteredExtensions: " );
+
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+
+ bool bWriterEnabled = false;
+ bool bCalcEnabled = false;
+ bool bImpressEnabled = false;
+ bool bRegisterNone = IsSetMsiProp( handle, "REGISTER_NO_MSO_TYPES" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureState( handle, L"gm_p_Wrt", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bWriterEnabled = true;
+
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Install state Writer is [%d], will be [%d]", current_state, future_state );
+ if ( bWriterEnabled )
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Writer is enabled" );
+ else
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Writer is NOT enabled" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureState( handle, L"gm_p_Calc", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bCalcEnabled = true;
+
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Install state Calc is [%d], will be [%d]", current_state, future_state );
+ if ( bCalcEnabled )
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Calc is enabled" );
+ else
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Calc is NOT enabled" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureState( handle, L"gm_p_Impress", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bImpressEnabled = true;
+
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Install state Impress is [%d], will be [%d]", current_state, future_state );
+ if ( bImpressEnabled )
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Impress is enabled" );
+ else
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Impress is NOT enabled" );
+
+ MsiSetPropertyA( handle, "SELECT_WORD", "" );
+ MsiSetPropertyA( handle, "SELECT_EXCEL", "" );
+ MsiSetPropertyA( handle, "SELECT_POWERPOINT", "" );
+
+ if ( ! bRegisterNone )
+ {
+ if ( IsSetMsiProp( handle, "REGISTER_ALL_MSO_TYPES" ) )
+ {
+ if ( bWriterEnabled )
+ MsiSetPropertyA( handle, "SELECT_WORD", "1" );
+ if ( bCalcEnabled )
+ MsiSetPropertyA( handle, "SELECT_EXCEL", "1" );
+ if ( bImpressEnabled )
+ MsiSetPropertyA( handle, "SELECT_POWERPOINT", "1" );
+ }
+ else
+ {
+ if ( bWriterEnabled && ! checkSomeExtensionInRegistry( WORD_START, EXCEL_START ) )
+ {
+ MsiSetPropertyA( handle, "SELECT_WORD", "1" );
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Register for MicroSoft Word" );
+ }
+ if ( bCalcEnabled && ! checkSomeExtensionInRegistry( EXCEL_START, POWERPOINT_START ) )
+ {
+ MsiSetPropertyA( handle, "SELECT_EXCEL", "1" );
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Register for MicroSoft Excel" );
+ }
+ if ( bImpressEnabled && ! checkSomeExtensionInRegistry( POWERPOINT_START, POWERPOINT_END ) )
+ {
+ MsiSetPropertyA( handle, "SELECT_POWERPOINT", "1" );
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Register for MicroSoft PowerPoint" );
+ }
+ }
+ }
+
+ MsiSetPropertyA( handle, "FILETYPEDIALOGUSED", "1" );
+
+ return ERROR_SUCCESS;
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall RegisterSomeExtensions( MSIHANDLE handle )
+{
+ OutputDebugStringFormat( "RegisterSomeExtensions: " );
+
+ if ( IsSetMsiProp( handle, "SELECT_WORD" ) )
+ {
+ registerSomeExtensions( handle, WORD_START, EXCEL_START, true );
+ MsiSetFeatureState( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormat( "RegisterSomeExtensions: Register for MicroSoft Word" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, WORD_START, EXCEL_START, false );
+ MsiSetFeatureState( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+
+ if ( IsSetMsiProp( handle, "SELECT_EXCEL" ) )
+ {
+ registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, true );
+ MsiSetFeatureState( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormat( "RegisterSomeExtensions: Register for MicroSoft Excel" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, false );
+ MsiSetFeatureState( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+
+ if ( IsSetMsiProp( handle, "SELECT_POWERPOINT" ) )
+ {
+ registerSomeExtensions( handle, POWERPOINT_START, POWERPOINT_END, true );
+ MsiSetFeatureState( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormat( "RegisterSomeExtensions: Register for MicroSoft PowerPoint" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, POWERPOINT_START, POWERPOINT_END, false );
+ MsiSetFeatureState( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall FindRegisteredExtensions( MSIHANDLE handle )
+{
+ if ( IsSetMsiProp( handle, "FILETYPEDIALOGUSED" ) )
+ {
+ OutputDebugStringFormat( "FindRegisteredExtensions: FILETYPEDIALOGUSED!" );
+ return ERROR_SUCCESS;
+ }
+
+ OutputDebugStringFormat( "FindRegisteredExtensions:" );
+
+ bool bRegisterAll = IsSetMsiProp( handle, "REGISTER_ALL_MSO_TYPES" );
+
+ if ( IsSetMsiProp( handle, "REGISTER_NO_MSO_TYPES" ) )
+ {
+ OutputDebugStringFormat( "FindRegisteredExtensions: Register none!" );
+ return ERROR_SUCCESS;
+ }
+ else if ( bRegisterAll )
+ OutputDebugStringFormat( "FindRegisteredExtensions: Force all on" );
+ else
+ OutputDebugStringFormat( "FindRegisteredExtensions: " );
+
+ // setting the msi properties SELECT_* will force registering for all corresponding
+ // file types
+ if ( IsSetMsiProp( handle, "SELECT_WORD" ) )
+ registerSomeExtensions( handle, WORD_START, EXCEL_START, true );
+ if ( IsSetMsiProp( handle, "SELECT_EXCEL" ) )
+ registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, true );
+ if ( IsSetMsiProp( handle, "SELECT_POWERPOINT" ) )
+ registerSomeExtensions( handle, POWERPOINT_START, POWERPOINT_END, true );
+
+ registerForExtensions( handle, bRegisterAll );
+
+ return ERROR_SUCCESS;
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall DeleteRegisteredExtensions( MSIHANDLE /*handle*/ )
+{
+ OutputDebugStringFormat( "DeleteRegisteredExtensions\n" );
+
+ // remove all file extensions
+ int nIndex = 0;
+ while ( g_Extensions[nIndex] != 0 )
+ {
+ RemoveExtensionInRegistry( g_Extensions[nIndex] );
+ ++nIndex;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/constants.hxx b/setup_native/source/win32/customactions/reg4msdoc/constants.hxx
new file mode 100644
index 000000000000..21b576b97dda
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/constants.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+ #ifndef _CONSTANTS_HXX_
+ #define _CONSTANTS_HXX_
+
+extern const int MSWORD;
+extern const int MSEXCEL;
+extern const int MSPOWERPOINT;
+extern const int DEFAULT_HTML_EDITOR_FOR_IE;
+extern const int HTML_EDITOR;
+extern const int DEFAULT_SHELL_HTML_EDITOR;
+
+ #endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/exports.dxp b/setup_native/source/win32/customactions/reg4msdoc/exports.dxp
new file mode 100644
index 000000000000..0f3d16886098
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/exports.dxp
@@ -0,0 +1,3 @@
+InstallUiSequenceEntry
+InstallExecSequenceEntry
+DeinstallExecSequenceEntry
diff --git a/setup_native/source/win32/customactions/reg4msdoc/makefile.mk b/setup_native/source/win32/customactions/reg4msdoc/makefile.mk
new file mode 100644
index 000000000000..fe2bf60949be
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/makefile.mk
@@ -0,0 +1,96 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=reg4msdocmsi
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+MINGW_NODLL=YES
+
+.INCLUDE : settings.mk
+
+CFLAGS+=-DUNICODE -D_UNICODE
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = $(SLO)$/msihelper.obj\
+ $(SLO)$/windowsregistry.obj\
+ $(SLO)$/userregistrar.obj\
+ $(SLO)$/stringconverter.obj\
+ $(SLO)$/registrywnt.obj\
+ $(SLO)$/registryw9x.obj\
+ $(SLO)$/registryvalueimpl.obj\
+ $(SLO)$/registryexception.obj\
+ $(SLO)$/registry.obj\
+ $(SLO)$/registrationcontextinformation.obj\
+ $(SLO)$/registrar.obj\
+ $(SLO)$/register.obj\
+ $(SLO)$/reg4msdocmsi.obj
+
+SHL1STDLIBS= $(KERNEL32LIB)\
+ $(USER32LIB)\
+ $(ADVAPI32LIB)\
+ $(SHELL32LIB)\
+ $(MSILIB)\
+ $(SHLWAPILIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+SHL1STDLIBS+=$(LIBSTLPORTST)
+.ENDIF
+
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
diff --git a/setup_native/source/win32/customactions/reg4msdoc/msihelper.cxx b/setup_native/source/win32/customactions/reg4msdoc/msihelper.cxx
new file mode 100644
index 000000000000..648d4f33fdd3
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/msihelper.cxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "msihelper.hxx"
+
+#include <malloc.h>
+#include <assert.h>
+
+bool GetMsiProp(MSIHANDLE handle, LPCTSTR name, /*out*/std::wstring& value)
+{
+ DWORD sz = 0;
+ LPTSTR dummy = TEXT("");
+ if (MsiGetProperty(handle, name, dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof(TCHAR);
+ LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetProperty(handle, name, buff, &sz);
+ value = buff;
+ return true;
+ }
+ return false;
+}
+
+void SetMsiProp(MSIHANDLE handle, LPCTSTR name)
+{
+ MsiSetProperty(handle, name, TEXT("1"));
+}
+
+void UnsetMsiProp(MSIHANDLE handle, LPCTSTR name)
+{
+ MsiSetProperty(handle, name, TEXT(""));
+}
+
+bool IsSetMsiProp(MSIHANDLE handle, LPCTSTR name)
+{
+ std::wstring val;
+ GetMsiProp(handle, name, val);
+ return (val == TEXT("1"));
+}
+
+bool IsMsiPropNotEmpty(MSIHANDLE handle, LPCTSTR name)
+{
+ std::wstring val;
+ GetMsiProp(handle, name, val);
+ return (val != TEXT(""));
+}
+
+bool IsAllUserInstallation(MSIHANDLE handle)
+{
+ return IsSetMsiProp(handle, TEXT("ALLUSERS"));
+}
+
+std::wstring GetOfficeInstallationPath(MSIHANDLE handle)
+{
+ std::wstring progpath;
+ GetMsiProp(handle, TEXT("INSTALLLOCATION"), progpath);
+ return progpath;
+}
+
+std::wstring GetOfficeExecutablePath(MSIHANDLE handle)
+{
+ std::wstring exepath = GetOfficeInstallationPath(handle);
+ exepath += TEXT("program\\soffice.exe");
+ return exepath;
+}
+
+std::wstring GetProductName(MSIHANDLE handle)
+{
+ std::wstring prodname;
+ GetMsiProp(handle, TEXT("ProductName"), prodname);
+ return prodname;
+}
+
+bool IsModuleInstalled(MSIHANDLE handle, LPCTSTR name)
+{
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+ MsiGetFeatureState(handle, name, &current_state, &future_state);
+ return (current_state == INSTALLSTATE_LOCAL);
+}
+
+bool IsModuleSelectedForInstallation(MSIHANDLE handle, LPCTSTR name)
+{
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+ MsiGetFeatureState(handle, name, &current_state, &future_state);
+ return (future_state == INSTALLSTATE_LOCAL);
+}
+
+bool IsModuleSelectedForDeinstallation(MSIHANDLE handle, LPCTSTR name)
+{
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+ MsiGetFeatureState(handle, name, &current_state, &future_state);
+ return ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_ABSENT));
+}
+
+bool IsCompleteDeinstallation(MSIHANDLE handle)
+{
+ std::wstring rm;
+ GetMsiProp(handle, TEXT("REMOVE"), rm);
+ return (rm == TEXT("ALL"));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/msihelper.hxx b/setup_native/source/win32/customactions/reg4msdoc/msihelper.hxx
new file mode 100644
index 000000000000..483a66986859
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/msihelper.hxx
@@ -0,0 +1,187 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#ifndef INCLUDED_MSIHELPER_HXX
+#define INCLUDED_MSIHELPER_HXX
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string>
+
+/**
+ Get the value of the named property
+
+ @param handle
+ [in] a valid msi handle.
+
+ @param name
+ [in] the name of the property.
+
+ @param value
+ [out] receives thes value of the property.
+
+ @returns
+ <TRUE/>if the property was found.
+*/
+bool GetMsiProp(MSIHANDLE handle, LPCTSTR name, /*out*/std::wstring& value);
+
+/**
+ Set the value of a binary property which can only
+ have the values "0" or "1" to "1".
+
+ @param handle
+ [in] a valid msi handle.
+
+ @param name
+ [in] the name of the property.
+*/
+void SetMsiProp(MSIHANDLE handle, LPCTSTR name);
+
+/**
+ Set the value of a binary property which can only
+ have the values "0" or "1" to "0".
+
+ @param handle
+ [in] a valid msi handle.
+
+ @param name
+ [in] the name of the property.
+*/
+void UnsetMsiProp(MSIHANDLE handle, LPCTSTR name);
+
+/**
+ Returns whether a certain property is set meaning
+ its value is "1". This method should be used for
+ binary properties whose value can be "0" or "1".
+
+ @returns
+ <TRUE/>if the value of the specified property is
+ "1" else if the property is not defined or its
+ value is other than "1" <FALSE/> will be returned.
+*/
+bool IsSetMsiProp(MSIHANDLE handle, LPCTSTR name);
+
+/**
+ Returns whether a certain property is set meaning
+ its value is not empty. This method should be used for
+ properties, that can have different values.
+
+ @returns
+ <TRUE/>if the value of the specified property is
+ not empty. If it is empty <FALSE/> will be returned.
+*/
+bool IsMsiPropNotEmpty(MSIHANDLE handle, LPCTSTR name);
+
+/**
+ Query if this is an installation for all user or not.
+
+ @param handle
+ [in] a valid msi handle.
+
+ @returns
+ <TRUE/>if this is an all user installation
+*/
+bool IsAllUserInstallation(MSIHANDLE handle);
+
+/**
+ Returns the destination folder of the office installation
+ as system path. The returned path contains a final '\'.
+
+ @param handle
+ [in] a valid msi handle.
+
+ @returns
+ the destination path of the office installation finalized
+ with a '\'.
+*/
+std::wstring GetOfficeInstallationPath(MSIHANDLE handle);
+
+/**
+ Returns the absolute path of the office executable that
+ will be installed as system path.
+
+ @param handle
+ [in] a valid msi handle.
+
+ @returns
+ the absolute system path of the office executable (e.g.
+ (C:\Program Files\StarOffice 8\program\soffice.exe").
+*/
+std::wstring GetOfficeExecutablePath(MSIHANDLE handle);
+
+/**
+ Get the name of the office that will be installed
+ (e.g. StarOffice 8, StarSuite 8, ...).
+
+ @param handle
+ [in] a valid msi handle.
+
+ @returns
+ the name of the office product that will be installed.
+*/
+std::wstring GetProductName(MSIHANDLE handle);
+
+/**
+ Determine if the specified module is installed locally.
+
+ @param handle
+ [in] a valid msi handle.
+
+ @param name
+ [in] the name of the module.
+
+ @returns
+ <TRUE/>if the specified module is installed locally.
+*/
+bool IsModuleInstalled(MSIHANDLE handle, LPCTSTR name);
+
+/**
+ Determine if the specified module is selected to be installed
+ locally.
+
+ @param handle
+ [in] a valid msi handle.
+
+ @param name
+ [in] the name of the module.
+
+ @returns
+ <TRUE/>if the specified module is about to be installed locally.
+*/
+bool IsModuleSelectedForInstallation(MSIHANDLE handle, LPCTSTR name);
+
+/**
+ Determine if the specified module which is locally installed is
+ selected for deinstallation.
+
+ @param handle
+ [in] a valid msi handle.
+
+ @param name
+ [in] the name of the module.
+
+ @returns
+ <TRUE/>if the specified module is about to be deinstalled.
+*/
+bool IsModuleSelectedForDeinstallation(MSIHANDLE handle, LPCTSTR name);
+
+/**
+ Determine whether this is a complete uninstallation or not.
+
+ @param handle
+ [in] a valid msi handle.
+
+ @returns
+ <TRUE/>if this is a complete deinstallation.
+*/
+bool IsCompleteDeinstallation(MSIHANDLE handle);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/reg4msdocmsi.cxx b/setup_native/source/win32/customactions/reg4msdoc/reg4msdocmsi.cxx
new file mode 100644
index 000000000000..e3f930ccfcbd
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/reg4msdocmsi.cxx
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <tchar.h>
+#include "register.hxx"
+#include "msihelper.hxx"
+
+#include <memory>
+#include <string>
+
+void DetermineWordPreselectionState(MSIHANDLE handle)
+{
+ if (query_preselect_registration_for_ms_application(handle, MSWORD))
+ SetMsiProp(handle, TEXT("SELECT_WORD"));
+}
+
+void DetermineExcelPreselectionState(MSIHANDLE handle)
+{
+ if (query_preselect_registration_for_ms_application(handle, MSEXCEL))
+ SetMsiProp(handle, TEXT("SELECT_EXCEL"));
+}
+
+void DeterminePowerPointPreselectionState(MSIHANDLE handle)
+{
+ if (query_preselect_registration_for_ms_application(handle, MSPOWERPOINT))
+ SetMsiProp(handle, TEXT("SELECT_POWERPOINT"));
+}
+
+extern "C" UINT __stdcall InstallUiSequenceEntry(MSIHANDLE handle)
+{
+ //MessageBox(NULL, TEXT("InstallUiSequenceEntry"), TEXT("Information"), MB_OK | MB_ICONINFORMATION);
+
+ if (IsModuleSelectedForInstallation(handle, TEXT("gm_p_Wrt_Bin")))
+ {
+ DetermineWordPreselectionState(handle);
+ }
+ else if (IsModuleInstalled(handle, TEXT("gm_p_Wrt_Bin")) &&
+ !IsModuleSelectedForDeinstallation(handle, TEXT("gm_p_Wrt_Bin")) &&
+ IsRegisteredFor(handle, MSWORD))
+ {
+ SetMsiProp(handle, TEXT("SELECT_WORD"));
+ }
+ else
+ {
+ UnsetMsiProp(handle, TEXT("SELECT_WORD"));
+ }
+
+ if (IsModuleSelectedForInstallation(handle, TEXT("gm_p_Calc_Bin")))
+ {
+ DetermineExcelPreselectionState(handle);
+ }
+ else if (IsModuleInstalled(handle, TEXT("gm_p_Calc_Bin")) &&
+ !IsModuleSelectedForDeinstallation(handle, TEXT("gm_p_Calc_Bin")) &&
+ IsRegisteredFor(handle, MSEXCEL))
+ {
+ SetMsiProp(handle, TEXT("SELECT_EXCEL"));
+ }
+ else
+ {
+ UnsetMsiProp(handle, TEXT("SELECT_EXCEL"));
+ }
+
+ if (IsModuleSelectedForInstallation(handle, TEXT("gm_p_Impress_Bin")))
+ {
+ DeterminePowerPointPreselectionState(handle);
+ }
+ else if (IsModuleInstalled(handle, TEXT("gm_p_Impress_Bin")) &&
+ !IsModuleSelectedForDeinstallation(handle, TEXT("gm_p_Impress_Bin")) &&
+ IsRegisteredFor(handle, MSPOWERPOINT))
+ {
+ SetMsiProp(handle, TEXT("SELECT_POWERPOINT"));
+ }
+ else
+ {
+ UnsetMsiProp(handle, TEXT("SELECT_POWERPOINT"));
+ }
+
+ SetMsiProp(handle, TEXT("UI_SEQUENCE_EXECUTED"));
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall InstallExecSequenceEntry(MSIHANDLE handle)
+{
+ //MessageBox(NULL, TEXT("InstallExecSequenceEntry"), TEXT("Information"), MB_OK | MB_ICONINFORMATION);
+
+ // Do nothing in repair mode.
+ // Then UI_SEQUENCE_EXECUTED is not set and Installed is set!
+ // In silent installation UI_SEQUENCE_EXECUTED is also not set, but Installed is not set.
+ if ((!IsSetMsiProp(handle, TEXT("UI_SEQUENCE_EXECUTED"))) && (IsMsiPropNotEmpty(handle, TEXT("Installed")))) { return ERROR_SUCCESS; }
+
+ int reg4 = 0;
+ int unreg4 = 0;
+
+ // we always register as html editor for Internet Explorer
+ // if writer is installed because there's no harm if we do so
+ if (IsModuleSelectedForInstallation(handle, TEXT("gm_p_Wrt_Bin")))
+ reg4 |= HTML_EDITOR;
+
+ if (IsSetMsiProp(handle, TEXT("SELECT_WORD")) && !IsRegisteredFor(handle, MSWORD))
+ reg4 |= MSWORD;
+ else if (!IsSetMsiProp(handle, TEXT("SELECT_WORD")) && IsRegisteredFor(handle, MSWORD))
+ unreg4 |= MSWORD;
+
+ if (IsSetMsiProp(handle, TEXT("SELECT_EXCEL")) && !IsRegisteredFor(handle, MSEXCEL))
+ reg4 |= MSEXCEL;
+ else if (!IsSetMsiProp(handle, TEXT("SELECT_EXCEL")) && IsRegisteredFor(handle, MSEXCEL))
+ unreg4 |= MSEXCEL;
+
+ if (IsSetMsiProp(handle, TEXT("SELECT_POWERPOINT")) && !IsRegisteredFor(handle, MSPOWERPOINT))
+ reg4 |= MSPOWERPOINT;
+ else if (!IsSetMsiProp(handle, TEXT("SELECT_POWERPOINT")) && IsRegisteredFor(handle, MSPOWERPOINT))
+ unreg4 |= MSPOWERPOINT;
+
+ if (reg4)
+ {
+ Register4MsDoc(handle, reg4);
+ }
+
+ if (unreg4)
+ {
+ Unregister4MsDoc(handle, unreg4);
+ }
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall DeinstallExecSequenceEntry(MSIHANDLE handle)
+{
+ //MessageBox(NULL, TEXT("DeinstallExecSequenceEntry"), TEXT("Information"), MB_OK | MB_ICONINFORMATION);
+
+ if (IsCompleteDeinstallation(handle))
+ {
+ Unregister4MsDocAll(handle);
+ return ERROR_SUCCESS;
+ }
+
+ if (IsModuleSelectedForDeinstallation(handle, TEXT("gm_p_Wrt_Bin")))
+ {
+ Unregister4MsDoc(handle, MSWORD | HTML_EDITOR);
+ }
+
+ if (IsModuleSelectedForDeinstallation(handle, TEXT("gm_p_Calc_Bin")))
+ {
+ Unregister4MsDoc(handle, MSEXCEL);
+ }
+
+ if (IsModuleSelectedForDeinstallation(handle, TEXT("gm_p_Impress_Bin")))
+ {
+ Unregister4MsDoc(handle, MSPOWERPOINT);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/register.cxx b/setup_native/source/win32/customactions/reg4msdoc/register.cxx
new file mode 100644
index 000000000000..a23d0ea67934
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/register.cxx
@@ -0,0 +1,342 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "register.hxx"
+#include "registryexception.hxx"
+#include "registrationcontextinformation.hxx"
+#include "userregistrar.hxx"
+#include "windowsregistry.hxx"
+#include "stringconverter.hxx"
+#include "msihelper.hxx"
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#pragma warning(disable: 4917)
+#endif
+#include <shlobj.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+
+#include <assert.h>
+#ifdef _MSC_VER
+#pragma warning(disable: 4350)
+#endif
+
+typedef std::auto_ptr<Registrar> RegistrarPtr;
+
+namespace /* private */
+{
+ RegistrarPtr CreateRegistrar(bool InstallForAllUser, const RegistrationContextInformation& RegCtx)
+ {
+ RegistrarPtr RegPtr;
+
+ if (InstallForAllUser)
+ RegPtr = RegistrarPtr(new Registrar(RegCtx));
+ else
+ RegPtr = RegistrarPtr(new UserRegistrar(RegCtx));
+
+ return RegPtr;
+ }
+} // namespace private
+
+bool query_preselect_registration_for_ms_application(MSIHANDLE handle, int Register)
+{
+ bool preselect = false;
+
+ try
+ {
+ RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
+ RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
+
+ if (Register & MSWORD)
+ preselect = CurrentRegistrar->QueryPreselectMsWordRegistration();
+ else if (Register & MSEXCEL)
+ preselect = CurrentRegistrar->QueryPreselectMsExcelRegistration();
+ else if (Register & MSPOWERPOINT)
+ preselect = CurrentRegistrar->QueryPreselectMsPowerPointRegistration();
+ }
+ catch(RegistryException&)
+ {
+ assert(false);
+ }
+ return preselect;
+}
+
+//-----------------------------------------
+// registers StarOffice for MS document
+// types and as default HTML editor if
+// specified
+//-----------------------------------------
+
+void Register4MsDoc(MSIHANDLE handle, int Register)
+{
+ try
+ {
+ RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
+ RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
+
+ if ((Register & MSWORD))
+ CurrentRegistrar->RegisterForMsWord();
+
+ if ((Register & MSEXCEL))
+ CurrentRegistrar->RegisterForMsExcel();
+
+ if ((Register & MSPOWERPOINT))
+ CurrentRegistrar->RegisterForMsPowerPoint();
+
+ if ((Register & HTML_EDITOR))
+ CurrentRegistrar->RegisterAsHtmlEditorForInternetExplorer();
+
+ if ((Register & DEFAULT_SHELL_HTML_EDITOR))
+ {
+ CurrentRegistrar->RegisterAsDefaultHtmlEditorForInternetExplorer();
+ CurrentRegistrar->RegisterAsDefaultShellHtmlEditor();
+ }
+ }
+ catch(RegistryException&)
+ {
+ assert(false);
+ }
+
+ if (Register)
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
+}
+
+void Unregister4MsDoc(MSIHANDLE handle, int Unregister)
+{
+ try
+ {
+ RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
+ RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
+
+ if ((Unregister & MSWORD) && CurrentRegistrar->IsRegisteredFor(MSWORD))
+ CurrentRegistrar->UnregisterForMsWord();
+
+ if ((Unregister & HTML_EDITOR) && CurrentRegistrar->IsRegisteredFor(HTML_EDITOR))
+ CurrentRegistrar->UnregisterAsHtmlEditorForInternetExplorer();
+
+ if ((Unregister & MSEXCEL) && CurrentRegistrar->IsRegisteredFor(MSEXCEL))
+ CurrentRegistrar->UnregisterForMsExcel();
+
+ if ((Unregister & MSPOWERPOINT) && CurrentRegistrar->IsRegisteredFor(MSPOWERPOINT))
+ CurrentRegistrar->UnregisterForMsPowerPoint();
+
+ if ((Unregister & DEFAULT_HTML_EDITOR_FOR_IE) && CurrentRegistrar->IsRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE))
+ CurrentRegistrar->UnregisterAsDefaultHtmlEditorForInternetExplorer();
+
+ if ((Unregister & DEFAULT_SHELL_HTML_EDITOR) && CurrentRegistrar->IsRegisteredFor(DEFAULT_SHELL_HTML_EDITOR))
+ CurrentRegistrar->UnregisterAsDefaultShellHtmlEditor();
+ }
+ catch(RegistryException&)
+ {
+ assert(false);
+ }
+
+ if (Unregister)
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
+}
+
+//-----------------------------------------
+// restores the entries for the selected
+// registry entries
+// Algorithm:
+//
+// 1.
+// Target key exist (e.g. '.doc')
+// Default value == soffice.?
+// Backup key != empty
+// Action: Replace Default value with backup
+// key
+//
+// 2.
+// Target key exist
+// Default value == soffice.?
+// Backup key == empty
+// Action: delete default value
+//
+// 3.
+// Target key exist
+// Default value != soffice.?
+// Action: nop
+//
+// 4.
+// Target key does not exist
+// Action: nop
+//-----------------------------------------
+
+void Unregister4MsDocAll(MSIHANDLE handle)
+{
+ try
+ {
+ RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
+ RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
+
+ CurrentRegistrar->UnregisterAllAndCleanUpRegistry();
+ }
+ catch(RegistryException&)
+ {
+ assert(false);
+ }
+}
+
+//-----------------------------------------
+// restores lost settings formerly made
+// with Register4MsDoc
+//-----------------------------------------
+
+void RepairRegister4MsDocSettings(MSIHANDLE handle)
+{
+ try
+ {
+ RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
+ RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
+
+ CurrentRegistrar->RepairRegistrationState();
+ }
+ catch(RegistryException&)
+ {
+ assert(false);
+ }
+}
+
+bool IsRegisteredFor(MSIHANDLE handle, int State)
+{
+ bool Registered = false;
+
+ try
+ {
+ RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
+ RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
+
+ Registered = CurrentRegistrar->IsRegisteredFor(State);
+ }
+ catch(RegistryException&)
+ {
+ assert(false);
+ }
+ return Registered;
+}
+
+#define SO60_UNINSTALL_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\StarOffice 6.0"
+#define SO_BACKUP_KEY L"soffice6.bak"
+#define REGMSDOCSTATE L"Reg4MsDocState"
+#define SOFTWARE_CLASSES L"Software\\Classes"
+
+int FixReturnRegistrationState(MSIHANDLE handle)
+{
+ int registration_state = 0;
+
+ try
+ {
+ WindowsRegistry registry;
+
+ RegistryValue rv_regmsdocstate = RegistryValue(
+ new RegistryValueImpl(REGMSDOCSTATE, 0));
+
+ RegistryKey so_bak_key;
+
+ if (IsAllUserInstallation(handle))
+ {
+ RegistryKey hkcr_key = registry.GetClassesRootKey();
+
+ if (hkcr_key->HasSubKey(SO_BACKUP_KEY))
+ so_bak_key = hkcr_key->OpenSubKey(SO_BACKUP_KEY);
+ else
+ so_bak_key = hkcr_key->CreateSubKey(SO_BACKUP_KEY);
+
+ if (!so_bak_key->HasValue(REGMSDOCSTATE))
+ {
+ // set a defined value
+ so_bak_key->SetValue(rv_regmsdocstate);
+
+ RegistryKey hklm_key = registry.GetLocalMachineKey();
+
+ if (hklm_key->HasSubKey(SO60_UNINSTALL_KEY))
+ {
+ RegistryKey so_uninst_key =
+ hklm_key->OpenSubKey(SO60_UNINSTALL_KEY);
+
+ if (so_uninst_key->HasValue(REGMSDOCSTATE))
+ so_bak_key->CopyValue(so_uninst_key, REGMSDOCSTATE);
+ }
+ }
+ }
+ else
+ {
+ RegistryKey hkcu_classes_key =
+ registry.GetCurrentUserKey()->OpenSubKey(SOFTWARE_CLASSES);
+
+ so_bak_key = hkcu_classes_key->CreateSubKey(SO_BACKUP_KEY);
+
+ if (!so_bak_key->HasValue(REGMSDOCSTATE))
+ {
+ // set a defined value
+ so_bak_key->SetValue(rv_regmsdocstate);
+
+ RegistryKey hklm_sftw_classes =
+ registry.GetLocalMachineKey()->OpenSubKey(SOFTWARE_CLASSES, false);
+
+ RegistryKey so_bak_key_old;
+
+ if (hklm_sftw_classes->HasSubKey(SO_BACKUP_KEY))
+ {
+ so_bak_key_old = hklm_sftw_classes->OpenSubKey(SO_BACKUP_KEY, false);
+
+ if (so_bak_key_old->HasValue(REGMSDOCSTATE))
+ so_bak_key->CopyValue(so_bak_key_old, REGMSDOCSTATE);
+ }
+ else // try the uninstall key
+ {
+ RegistryKey hklm_key = registry.GetLocalMachineKey();
+
+ if (hklm_key->HasSubKey(SO60_UNINSTALL_KEY))
+ {
+ RegistryKey so_uninst_key =
+ hklm_key->OpenSubKey(SO60_UNINSTALL_KEY);
+
+ if (so_uninst_key->HasValue(REGMSDOCSTATE))
+ so_bak_key->CopyValue(so_uninst_key, REGMSDOCSTATE);
+ }
+ }
+ }
+ }
+
+ rv_regmsdocstate = so_bak_key->GetValue(REGMSDOCSTATE);
+ registration_state = rv_regmsdocstate->GetDataAsInt();
+ }
+ catch(RegistryException&)
+ {
+ registration_state = 0;
+ }
+
+ return registration_state;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/register.hxx b/setup_native/source/win32/customactions/reg4msdoc/register.hxx
new file mode 100644
index 000000000000..964c4be894df
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/register.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _REGISTER_HXX_
+#define _REGISTER_HXX_
+
+#include "constants.hxx"
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msi.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string>
+
+const int MOD_WRITER = 0x1;
+const int MOD_CALC = 0x2;
+const int MOD_IMPRESS = 0x4;
+const int MOD_ACTIVEX = 0x40;
+
+/* registers StarOffice for MS document
+ types and as default HTML editor if
+ specified */
+void Register4MsDoc(MSIHANDLE handle, int Register);
+
+void Unregister4MsDoc(MSIHANDLE handle, int Unregister);
+
+/* restores the entries for the selected
+ registry entries */
+void Unregister4MsDocAll(MSIHANDLE handle);
+
+/* restores lost settings formerly made
+ with Register4MsDoc */
+void RepairRegister4MsDocSettings(MSIHANDLE handle);
+
+/** Returns whether we are registered for */
+bool IsRegisteredFor(MSIHANDLE handle, int State);
+
+/** Returns whether we should preselect the
+ registration checkbox for a certain
+ application type or not */
+bool query_preselect_registration_for_ms_application(
+ MSIHANDLE handle, int Register);
+
+// StarOffice 6.0 saved the registration
+// state in HKEY_LOCAL_MACHINE\Software\
+// Microsoft\Windows\CurrentVersion\Uninstall\
+// StarOffice 6.0\Reg4MsdocState we move this
+// value if available to the new registry
+// location
+int FixReturnRegistrationState(MSIHANDLE handle);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registrar.cxx b/setup_native/source/win32/customactions/reg4msdoc/registrar.cxx
new file mode 100644
index 000000000000..45fbed4819d2
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrar.cxx
@@ -0,0 +1,760 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// Registrar.cpp: Implementierung der Klasse Registrar.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "registrar.hxx"
+
+#include "RegistryValueImpl.hxx"
+#include "windowsregistry.hxx"
+#include "registryexception.hxx"
+
+#include <assert.h>
+#ifdef _MSC_VER
+#pragma warning(disable: 4350 4482)
+#include "strsafe.h"
+#endif
+
+//----------------------------------------------------------
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+//----------------------------------------------------------
+
+const int MSWORD = 0x1;
+const int MSEXCEL = 0x2;
+const int MSPOWERPOINT = 0x4;
+const int DEFAULT_HTML_EDITOR_FOR_IE = 0x8;
+const int HTML_EDITOR = 0x10;
+const int DEFAULT_SHELL_HTML_EDITOR = 0x20;
+
+namespace /* private */
+{
+ const std::wstring HTM_OPENWITHLIST = L".htm\\OpenWithList";
+ const std::wstring APPLICATIONS = L"Applications";
+ const std::wstring SHELL_EDIT_COMMAND = L"shell\\edit\\command";
+ const std::wstring HTML_EDIT = L"HTML Edit";
+ const std::wstring HTML_EDIT_DISPLAY_NAME = L"Edit Display Name";
+ const std::wstring SHELL_EDIT_COMMAND_BACKUP = L"Shell Edit Cmd";
+ const std::wstring DEFAULT_HTML_EDITOR = L"Default HTML Editor";
+ const std::wstring MS_IE_DEF_HTML_EDITOR = L"Software\\Microsoft\\Internet Explorer\\Default HTML Editor";
+ const std::wstring MS_IE_DEF_HTML_EDITOR_SHL_EDIT_CMD = L"Software\\Microsoft\\Internet Explorer\\Default HTML Editor\\shell\\edit\\command";
+}
+
+Registrar::Registrar(const RegistrationContextInformation& RegContext) :
+ m_ContextInformation(RegContext),
+ FORWARD_KEY_PREFIX(L"OpenOffice.org"),//FORWARD_KEY_PREFIX(L"soffice6"),
+ DEFAULT_VALUE_NAME(L""),
+ BACKUP_VALUE_NAME(L"Backup"),
+ PRIVATE_BACKUP_KEY_NAME(L"OpenOffice.org.reg4msdocmsi"),//PRIVATE_BACKUP_KEY_NAME(L"soffice6.bak"),
+ REGISTRATION_STATE(L"Reg4MsDocState")
+{
+ m_RootKey = WindowsRegistry().GetClassesRootKey();
+}
+
+Registrar::~Registrar()
+{
+}
+
+void Registrar::RegisterForMsWord() const
+{
+ assert(m_RootKey.get());
+
+ RegisterForMsOfficeApplication(
+ m_ContextInformation.GetWordDocumentFileExtension(),
+ m_ContextInformation.GetWordDocumentDisplayName(),
+ m_ContextInformation.GetWordDocumentDefaultIconEntry(),
+ m_ContextInformation.GetWordDocumentDefaultShellCommand(),
+ m_ContextInformation.ShellNewCommandDisplayName(),
+ RegistrationContextInformation::Writer);
+
+ RegisterForMsOfficeApplication(
+ m_ContextInformation.GetWordTemplateFileExtension(),
+ m_ContextInformation.GetWordTemplateDisplayName(),
+ m_ContextInformation.GetWordTemplateDefaultIconEntry(),
+ m_ContextInformation.GetWordTemplateDefaultShellCommand(),
+ m_ContextInformation.ShellNewCommandDisplayName(),
+ RegistrationContextInformation::Writer);
+
+ RegisterForMsOfficeApplication(
+ m_ContextInformation.GetRtfDocumentFileExtension(),
+ m_ContextInformation.GetRtfDocumentDisplayName(),
+ m_ContextInformation.GetRtfDocumentDefaultIconEntry(),
+ m_ContextInformation.GetRtfDocumentDefaultShellCommand(),
+ m_ContextInformation.ShellNewCommandDisplayName(),
+ RegistrationContextInformation::Writer);
+
+ SaveRegisteredFor(MSWORD);
+}
+
+void Registrar::UnregisterForMsWord() const
+{
+ assert(m_RootKey.get());
+
+ try
+ {
+ UnregisterForMsOfficeApplication(
+ m_ContextInformation.GetWordDocumentFileExtension());
+ }
+ catch(RegistryKeyNotFoundException&)
+ {}
+
+ try
+ {
+ UnregisterForMsOfficeApplication(
+ m_ContextInformation.GetWordTemplateFileExtension());
+ }
+ catch(RegistryKeyNotFoundException&)
+ {}
+
+ try
+ {
+ UnregisterForMsOfficeApplication(
+ m_ContextInformation.GetRtfDocumentFileExtension());
+ }
+ catch(RegistryKeyNotFoundException&)
+ {}
+
+ SaveNotRegisteredFor(MSWORD);
+}
+
+bool Registrar::QueryPreselectForMsApplication(const std::wstring& file_extension) const
+{
+ bool preselect = false;
+
+ // We use HKCR else we would not see that a registration for
+ // MS Office applications already exist if we are about to
+ // register in HKCU\Software\Classes
+ RegistryKey root_key = WindowsRegistry().GetClassesRootKey();
+
+ if (!root_key->HasSubKey(file_extension))
+ {
+ preselect = true;
+ OutputDebugStringFormat( TEXT("QueryPreselect: No SubKey found for (%s), preselected!\n"), file_extension.c_str() );
+ }
+ else
+ {
+ RegistryKey RegKey = root_key->OpenSubKey(file_extension, false);
+
+ if (RegKey->HasValue(DEFAULT_VALUE_NAME))
+ {
+ RegistryValue RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
+
+ if (REG_SZ == RegVal->GetType() &&
+ IsOpenOfficeRegisteredForMsApplication(RegVal->GetDataAsUniString()))
+ {
+ preselect = true;
+ OutputDebugStringFormat( TEXT("QueryPreselect: (%s) registered to Office, preselected!\n"), file_extension.c_str() );
+ }
+ else if ( (REG_SZ == RegVal->GetType()) && ! root_key->HasSubKey( RegVal->GetDataAsUniString() ) )
+ {
+ preselect = true;
+ OutputDebugStringFormat( TEXT("QueryPreselect: (%s) registered but destination is empty, preselected!\n"), file_extension.c_str() );
+ }
+ }
+ else
+ {
+ preselect = true;
+ OutputDebugStringFormat( TEXT("QueryPreselect: No default found for SubKey (%s), preselected!\n"), file_extension.c_str() );
+ }
+ }
+ return preselect;
+}
+
+bool Registrar::QueryPreselectMsWordRegistration() const
+{
+ return QueryPreselectForMsApplication(
+ m_ContextInformation.GetWordDocumentFileExtension());
+}
+
+void Registrar::RegisterForMsExcel() const
+{
+ assert(m_RootKey.get());
+
+ RegisterForMsOfficeApplication(
+ m_ContextInformation.GetExcelSheetFileExtension(),
+ m_ContextInformation.GetExcelSheetDisplayName(),
+ m_ContextInformation.GetExcelSheetDefaultIconEntry(),
+ m_ContextInformation.GetExcelSheetDefaultShellCommand(),
+ m_ContextInformation.ShellNewCommandDisplayName(),
+ RegistrationContextInformation::Calc);
+
+ RegisterForMsOfficeApplication(
+ m_ContextInformation.GetExcelTemplateFileExtension(),
+ m_ContextInformation.GetExcelTemplateDisplayName(),
+ m_ContextInformation.GetExcelTemplateDefaultIconEntry(),
+ m_ContextInformation.GetExcelTemplateDefaultShellCommand(),
+ m_ContextInformation.ShellNewCommandDisplayName(),
+ RegistrationContextInformation::Calc);
+
+ SaveRegisteredFor(MSEXCEL);
+}
+
+void Registrar::UnregisterForMsExcel() const
+{
+ assert(m_RootKey.get());
+
+ try
+ {
+ UnregisterForMsOfficeApplication(
+ m_ContextInformation.GetExcelSheetFileExtension());
+ }
+ catch(RegistryKeyNotFoundException&)
+ {}
+
+ try
+ {
+ UnregisterForMsOfficeApplication(
+ m_ContextInformation.GetExcelTemplateFileExtension());
+ }
+ catch(RegistryKeyNotFoundException&)
+ {}
+
+ SaveNotRegisteredFor(MSEXCEL);
+}
+
+bool Registrar::QueryPreselectMsExcelRegistration() const
+{
+ return QueryPreselectForMsApplication(
+ m_ContextInformation.GetExcelSheetFileExtension());
+}
+
+void Registrar::RegisterForMsPowerPoint() const
+{
+ assert(m_RootKey.get());
+
+ RegisterForMsOfficeApplication(
+ m_ContextInformation.GetPowerPointDocumentFileExtension(),
+ m_ContextInformation.GetPowerPointDocumentDisplayName(),
+ m_ContextInformation.GetPowerPointDocumentDefaultIconEntry(),
+ m_ContextInformation.GetPowerPointDocumentDefaultShellCommand(),
+ m_ContextInformation.ShellNewCommandDisplayName(),
+ RegistrationContextInformation::Impress);
+
+ RegisterForMsOfficeApplication(
+ m_ContextInformation.GetPowerPointShowFileExtension(),
+ m_ContextInformation.GetPowerPointShowDisplayName(),
+ m_ContextInformation.GetPowerPointShowDefaultIconEntry(),
+ m_ContextInformation.GetPowerPointShowDefaultShellCommand(),
+ m_ContextInformation.ShellNewCommandDisplayName(),
+ RegistrationContextInformation::Impress);
+
+ RegisterForMsOfficeApplication(
+ m_ContextInformation.GetPowerPointTemplateFileExtension(),
+ m_ContextInformation.GetPowerPointTemplateDisplayName(),
+ m_ContextInformation.GetPowerPointTemplateDefaultIconEntry(),
+ m_ContextInformation.GetPowerPointTemplateDefaultShellCommand(),
+ m_ContextInformation.ShellNewCommandDisplayName(),
+ RegistrationContextInformation::Impress);
+
+ SaveRegisteredFor(MSPOWERPOINT);
+}
+
+void Registrar::UnregisterForMsPowerPoint() const
+{
+ assert(m_RootKey.get());
+
+ try
+ {
+ UnregisterForMsOfficeApplication(
+ m_ContextInformation.GetPowerPointDocumentFileExtension());
+ }
+ catch(RegistryKeyNotFoundException&)
+ {}
+
+ try
+ {
+ UnregisterForMsOfficeApplication(
+ m_ContextInformation.GetPowerPointShowFileExtension());
+ }
+ catch(RegistryKeyNotFoundException&)
+ {}
+
+ try
+ {
+ UnregisterForMsOfficeApplication(
+ m_ContextInformation.GetPowerPointTemplateFileExtension());
+ }
+ catch(RegistryKeyNotFoundException&)
+ {}
+
+ SaveNotRegisteredFor(MSPOWERPOINT);
+}
+
+//-----------------------------------------
+/*
+*/
+bool Registrar::QueryPreselectMsPowerPointRegistration() const
+{
+ return QueryPreselectForMsApplication( m_ContextInformation.GetPowerPointDocumentFileExtension()) &&
+ QueryPreselectForMsApplication( m_ContextInformation.GetPowerPointShowFileExtension());
+}
+
+//-----------------------------------------
+/** The documentation says we have to
+ make the following entries to register
+ a html editor for the Internet Explorer
+ HKCR\.htm\OpenWithList\App Friendly Name\shell\edit\command
+ But the reality shows that this works only
+ with Internet Explorer 5.x
+ Internet Explorer 6.0 wants the follwoing
+ entries:
+ HKCR\.htm\OpenWithList\App.exe
+ HKCR\Applications\App.ex\shell\edit\command
+*/
+void Registrar::RegisterAsHtmlEditorForInternetExplorer() const
+{
+ assert(m_RootKey.get());
+
+ std::wstring OOFriendlyAppName = m_ContextInformation.GetOpenOfficeFriendlyAppName();
+
+ std::wstring RegKeyName = HTM_OPENWITHLIST + std::wstring(L"\\") + OOFriendlyAppName;
+ RegistryKey RegKey = m_RootKey->CreateSubKey(RegKeyName);
+
+ RegKey = RegKey->CreateSubKey(SHELL_EDIT_COMMAND);
+
+ RegistryValue RegVal(
+ new RegistryValueImpl(
+ DEFAULT_VALUE_NAME,
+ m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open,
+ RegistrationContextInformation::Writer)));
+
+ RegKey->SetValue(RegVal);
+
+ RegKeyName = APPLICATIONS + std::wstring(L"\\") + OOFriendlyAppName;
+ RegKey = m_RootKey->CreateSubKey(RegKeyName);
+
+ RegVal->SetName(L"FriendlyAppName");
+ RegVal->SetValue(OOFriendlyAppName);
+ RegKey->SetValue(RegVal);
+
+ RegKey = RegKey->CreateSubKey(SHELL_EDIT_COMMAND);
+ RegVal->SetName(DEFAULT_VALUE_NAME);
+ RegVal->SetValue(
+ m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open,
+ RegistrationContextInformation::Writer));
+ RegKey->SetValue(RegVal);
+
+ SaveRegisteredFor(HTML_EDITOR);
+}
+
+void Registrar::UnregisterAsHtmlEditorForInternetExplorer() const
+{
+ assert(m_RootKey.get());
+
+ try
+ {
+ std::wstring OOFriendlyAppName = m_ContextInformation.GetOpenOfficeFriendlyAppName();
+
+ RegistryKey aRegKey = m_RootKey->OpenSubKey( APPLICATIONS );
+ if ( aRegKey->HasSubKey( OOFriendlyAppName ) )
+ aRegKey->DeleteSubKeyTree( OOFriendlyAppName );
+
+ aRegKey = m_RootKey->OpenSubKey( HTM_OPENWITHLIST );
+ if ( aRegKey->HasSubKey( OOFriendlyAppName ) )
+ aRegKey->DeleteSubKeyTree( OOFriendlyAppName );
+ }
+ catch(RegistryKeyNotFoundException&)
+ {}
+
+ SaveNotRegisteredFor(HTML_EDITOR);
+}
+
+void Registrar::RegisterAsDefaultHtmlEditorForInternetExplorer() const
+{
+ assert(m_RootKey.get());
+
+ RegistryKey RegistrationRootKey = GetRootKeyForDefHtmlEditorForIERegistration();
+
+ RegistryKey RegKey = RegistrationRootKey->CreateSubKey(MS_IE_DEF_HTML_EDITOR_SHL_EDIT_CMD);
+
+ RegistryValue RegVal = RegistryValue(new RegistryValueImpl(DEFAULT_VALUE_NAME, L""));
+
+ if (RegKey->HasValue(DEFAULT_VALUE_NAME))
+ {
+ RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
+
+ std::wstring CmdLine = RegVal->GetDataAsUniString();
+
+ if (std::wstring::npos == CmdLine.find(m_ContextInformation.GetOpenOfficeExecutableName()))
+ {
+ RegistryKey BackupRegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME + L"\\" + DEFAULT_HTML_EDITOR);
+
+ if (RegKey->HasValue(DEFAULT_VALUE_NAME))
+ BackupRegKey->CopyValue(RegKey, DEFAULT_VALUE_NAME);
+
+ RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR);
+ if (RegKey->HasValue(L"Description"))
+ BackupRegKey->CopyValue(RegKey, L"Description");
+ }
+ }
+
+ RegVal->SetValue(
+ m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open,
+ RegistrationContextInformation::Writer));
+ RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR_SHL_EDIT_CMD);
+ RegKey->SetValue(RegVal);
+
+ RegVal->SetName(L"Description");
+ RegVal->SetValue(m_ContextInformation.GetOpenOfficeFriendlyAppName());
+ RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR);
+ RegKey->SetValue(RegVal);
+
+ SaveRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE);
+}
+
+void Registrar::UnregisterAsDefaultHtmlEditorForInternetExplorer() const
+{
+ assert(m_RootKey.get());
+
+ RegistryKey RegistrationRootKey = GetRootKeyForDefHtmlEditorForIERegistration();
+
+ RegistryKey RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR_SHL_EDIT_CMD);
+
+ if (RegKey->HasValue(DEFAULT_VALUE_NAME))
+ {
+ RegistryValue RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
+
+ std::wstring CmdLine = RegVal->GetDataAsUniString();
+
+ if (std::wstring::npos != CmdLine.find(m_ContextInformation.GetOpenOfficeExecutableName()))
+ {
+ RegistryKey BackupRegKey = m_RootKey->OpenSubKey(PRIVATE_BACKUP_KEY_NAME);
+
+ if (BackupRegKey->HasSubKey(DEFAULT_HTML_EDITOR))
+ {
+ BackupRegKey = BackupRegKey->OpenSubKey(DEFAULT_HTML_EDITOR);
+
+ if (BackupRegKey->HasValue(DEFAULT_VALUE_NAME))
+ RegKey->CopyValue(BackupRegKey, DEFAULT_VALUE_NAME);
+ else
+ RegKey->DeleteValue(DEFAULT_VALUE_NAME);
+
+ RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR);
+
+ if (BackupRegKey->HasValue(L"Description"))
+ RegKey->CopyValue(BackupRegKey, L"Description");
+ else
+ RegKey->DeleteValue(L"Description");
+ }
+ else
+ {
+ RegKey->DeleteValue(DEFAULT_VALUE_NAME);
+ RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR);
+ RegKey->DeleteValue(L"Description");
+ }
+ }
+ }
+
+ SaveNotRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE);
+}
+
+void Registrar::RegisterAsDefaultShellHtmlEditor() const
+{
+ assert(m_RootKey.get());
+
+ RegistryKey RegKey = m_RootKey->CreateSubKey(L".htm");
+
+ RegistryValue RegVal = RegistryValue(
+ new RegistryValueImpl(DEFAULT_VALUE_NAME, L""));
+
+ if (RegKey->HasValue(DEFAULT_VALUE_NAME))
+ RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
+
+ std::wstring HtmFwdKey = RegVal->GetDataAsUniString();
+ if (0 == HtmFwdKey.length() || !m_RootKey->HasSubKey(HtmFwdKey))
+ HtmFwdKey = L".htm";
+
+ RegKey = m_RootKey->CreateSubKey(HtmFwdKey + L"\\" + SHELL_EDIT_COMMAND);
+
+ if (RegKey->HasValue(DEFAULT_VALUE_NAME))
+ {
+ RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
+
+ std::wstring CmdLine = RegVal->GetDataAsUniString();
+
+ // backup old values if we are not in place
+ if (std::wstring::npos == CmdLine.find(m_ContextInformation.GetOpenOfficeExecutableName()))
+ {
+ RegistryKey BackupRegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME + L"\\" + HTML_EDIT);
+ BackupRegKey->CopyValue(RegKey, DEFAULT_VALUE_NAME, SHELL_EDIT_COMMAND_BACKUP);
+ }
+ }
+
+ RegVal->SetValue(
+ m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open,
+ RegistrationContextInformation::Writer));
+
+ RegKey->SetValue(RegVal);
+
+ SaveRegisteredFor(DEFAULT_SHELL_HTML_EDITOR);
+}
+
+void Registrar::UnregisterAsDefaultShellHtmlEditor() const
+{
+ assert(m_RootKey.get());
+
+ try
+ {
+ RegistryKey RegKey = m_RootKey->OpenSubKey(L".htm");
+
+ RegistryValue RegVal = RegistryValue(
+ new RegistryValueImpl(DEFAULT_VALUE_NAME, L""));
+
+ if (RegKey->HasValue(DEFAULT_VALUE_NAME))
+ RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
+
+ std::wstring HtmFwdKey = RegVal->GetDataAsUniString();
+
+ if (0 == HtmFwdKey.length() || !m_RootKey->HasSubKey(HtmFwdKey))
+ HtmFwdKey = L".htm";
+
+ RegKey = m_RootKey->OpenSubKey(HtmFwdKey + L"\\" + SHELL_EDIT_COMMAND);
+
+ RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
+
+ std::wstring CmdLine = RegVal->GetDataAsUniString();
+
+ if (std::wstring::npos != CmdLine.find(m_ContextInformation.GetOpenOfficeExecutableName()))
+ {
+ RegistryKey BackupRegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME + L"\\" + HTML_EDIT);
+
+ if (BackupRegKey->HasValue(SHELL_EDIT_COMMAND_BACKUP))
+ RegKey->CopyValue(BackupRegKey, SHELL_EDIT_COMMAND_BACKUP, DEFAULT_VALUE_NAME);
+ else
+ RegKey->DeleteValue(DEFAULT_VALUE_NAME);
+ }
+ }
+ catch(RegistryKeyNotFoundException&)
+ {
+ }
+
+ SaveNotRegisteredFor(DEFAULT_SHELL_HTML_EDITOR);
+}
+
+void Registrar::SaveRegisteredFor(int State) const
+{
+ assert(m_RootKey.get());
+
+ int NewState = GetRegisterState();
+ NewState |= State;
+ SetRegisterState(NewState);
+}
+
+void Registrar::SaveNotRegisteredFor(int State) const
+{
+ assert(m_RootKey.get());
+
+ int NewState = GetRegisterState();
+ NewState &= ~State;
+ SetRegisterState(NewState);
+}
+
+int Registrar::GetRegisterState() const
+{
+ int State = 0;
+
+ RegistryKey RegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME);
+
+ if (RegKey->HasValue(REGISTRATION_STATE))
+ {
+ RegistryValue RegVal = RegKey->GetValue(REGISTRATION_STATE);
+ if (REG_DWORD == RegVal->GetType())
+ State = RegVal->GetDataAsInt();
+ }
+
+ return State;
+}
+
+void Registrar::SetRegisterState(int NewState) const
+{
+ RegistryKey RegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME);
+ RegistryValue RegVal = RegistryValue(new RegistryValueImpl(REGISTRATION_STATE, NewState));
+ RegKey->SetValue(RegVal);
+}
+
+bool Registrar::IsRegisteredFor(int State) const
+{
+ assert(m_RootKey.get());
+
+ RegistryKey RegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME);
+
+ int SavedState = 0;
+
+ if (RegKey->HasValue(REGISTRATION_STATE))
+ {
+ RegistryValue RegVal = RegKey->GetValue(REGISTRATION_STATE);
+ if (REG_DWORD == RegVal->GetType())
+ SavedState = RegVal->GetDataAsInt();
+ }
+
+ return ((SavedState & State) == State);
+}
+
+//--------------------------------------
+/** Restore the last registration state (necessary for
+ Setup repair) */
+void Registrar::RepairRegistrationState() const
+{
+ assert(m_RootKey.get());
+
+ if (IsRegisteredFor(MSWORD))
+ RegisterForMsWord();
+
+ if (IsRegisteredFor(MSEXCEL))
+ RegisterForMsExcel();
+
+ if (IsRegisteredFor(MSPOWERPOINT))
+ RegisterForMsPowerPoint();
+
+ if (IsRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE))
+ RegisterAsDefaultHtmlEditorForInternetExplorer();
+
+ if (IsRegisteredFor(HTML_EDITOR))
+ RegisterAsHtmlEditorForInternetExplorer();
+
+ if (IsRegisteredFor(DEFAULT_SHELL_HTML_EDITOR))
+ RegisterAsDefaultShellHtmlEditor();
+}
+
+/** Unregisters all and delete all Registry keys we have written */
+void Registrar::UnregisterAllAndCleanUpRegistry() const
+{
+ assert(m_RootKey.get());
+
+ if (IsRegisteredFor(MSWORD))
+ UnregisterForMsWord();
+
+ if (IsRegisteredFor(MSEXCEL))
+ UnregisterForMsExcel();
+
+ if (IsRegisteredFor(MSPOWERPOINT))
+ UnregisterForMsPowerPoint();
+
+ if (IsRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE))
+ UnregisterAsDefaultHtmlEditorForInternetExplorer();
+
+ if (IsRegisteredFor(HTML_EDITOR))
+ UnregisterAsHtmlEditorForInternetExplorer();
+
+ if (IsRegisteredFor(DEFAULT_SHELL_HTML_EDITOR))
+ UnregisterAsDefaultShellHtmlEditor();
+
+ if (m_RootKey->HasSubKey(PRIVATE_BACKUP_KEY_NAME))
+ m_RootKey->DeleteSubKeyTree(PRIVATE_BACKUP_KEY_NAME);
+}
+
+void Registrar::RegisterForMsOfficeApplication(
+ const std::wstring& FileExtension,
+ const std::wstring& DocumentDisplayName,
+ const std::wstring& DefaultIconEntry,
+ const std::wstring& DefaultShellCommand,
+ const std::wstring& ShellNewCommandDisplayName,
+ const RegistrationContextInformation::OFFICE_APPLICATION eOfficeApp) const
+{
+ assert(m_RootKey.get());
+
+ std::wstring ForwardKeyName = FORWARD_KEY_PREFIX + FileExtension;
+
+ RegistryKey ForwardKey = m_RootKey->CreateSubKey(ForwardKeyName);
+ RegistryValue RegVal(new RegistryValueImpl(std::wstring(DEFAULT_VALUE_NAME), DocumentDisplayName));
+ ForwardKey->SetValue(RegVal);
+
+ RegistryKey RegKey = ForwardKey->CreateSubKey(L"DefaultIcon");
+ RegVal->SetValue(DefaultIconEntry);
+ RegKey->SetValue(RegVal);
+
+ RegistryKey RegKeyShell = ForwardKey->CreateSubKey(L"shell");
+ RegVal->SetValue(DefaultShellCommand);
+ RegKeyShell->SetValue(RegVal);
+
+ RegKey = RegKeyShell->CreateSubKey(L"new");
+ RegVal->SetValue(ShellNewCommandDisplayName);
+ RegKey->SetValue(RegVal);
+
+ RegKey = RegKey->CreateSubKey(L"command");
+ RegVal->SetValue(m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::New, eOfficeApp));
+ RegKey->SetValue(RegVal);
+
+ RegKey = RegKeyShell->CreateSubKey(L"open\\command");
+ RegVal->SetValue(m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open, eOfficeApp));
+ RegKey->SetValue(RegVal);
+
+ RegKey = RegKeyShell->CreateSubKey(L"print\\command");
+ RegVal->SetValue(m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Print, eOfficeApp));
+ RegKey->SetValue(RegVal);
+
+ RegKey = RegKeyShell->CreateSubKey(L"printto\\command");
+ RegVal->SetValue(m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Printto, eOfficeApp));
+ RegKey->SetValue(RegVal);
+
+ // set the new forward key under the appropriate extension
+ RegKey = m_RootKey->CreateSubKey(FileExtension);
+
+ if (RegKey->HasValue(DEFAULT_VALUE_NAME))
+ {
+ RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
+
+ if (REG_SZ == RegVal->GetType())
+ {
+ std::wstring str = RegVal->GetDataAsUniString();
+ if (!IsOpenOfficeRegisteredForMsApplication(str))
+ ForwardKey->CopyValue(RegKey, DEFAULT_VALUE_NAME, BACKUP_VALUE_NAME);
+ }
+ }
+
+ RegVal->SetValue(ForwardKeyName);
+ RegKey->SetValue(RegVal);
+}
+
+void Registrar::UnregisterForMsOfficeApplication(const std::wstring& FileExtension) const
+{
+ std::wstring FwdRegKeyName = FORWARD_KEY_PREFIX + FileExtension;
+
+ if (m_RootKey->HasSubKey(FileExtension))
+ {
+ RegistryKey RegKey = m_RootKey->OpenSubKey(FileExtension);
+
+ if (RegKey->HasValue(DEFAULT_VALUE_NAME))
+ {
+ RegistryValue RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
+ if (REG_SZ == RegVal->GetType() &&
+ IsOpenOfficeRegisteredForMsApplication(RegVal->GetDataAsUniString()))
+ {
+ RegistryKey FwdRegKey = m_RootKey->CreateSubKey(FwdRegKeyName);
+
+ if (FwdRegKey->HasValue(BACKUP_VALUE_NAME))
+ RegKey->CopyValue(FwdRegKey, BACKUP_VALUE_NAME, DEFAULT_VALUE_NAME);
+ else
+ RegKey->DeleteValue(DEFAULT_VALUE_NAME);
+ }
+ }
+ }
+
+ if (m_RootKey->HasSubKey(FwdRegKeyName))
+ m_RootKey->DeleteSubKeyTree(FwdRegKeyName);
+}
+
+RegistryKey Registrar::GetRootKeyForDefHtmlEditorForIERegistration() const
+{
+ return WindowsRegistry().GetLocalMachineKey();
+}
+
+bool Registrar::IsOpenOfficeRegisteredForMsApplication(const std::wstring& DocumentExtensionDefValue) const
+{
+ return (std::wstring::npos != DocumentExtensionDefValue.find(FORWARD_KEY_PREFIX));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registrar.hxx b/setup_native/source/win32/customactions/reg4msdoc/registrar.hxx
new file mode 100644
index 000000000000..851b12f8daf7
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrar.hxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// Registrar.h: Schnittstelle f�r die Klasse Registrar.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef _REGISTRAR_HXX_
+#define _REGISTRAR_HXX_
+
+#include "registry.hxx"
+#include "registrationcontextinformation.hxx"
+
+#include "constants.hxx"
+
+class Registrar
+{
+public:
+
+ Registrar(const RegistrationContextInformation& RegContext);
+
+ virtual ~Registrar();
+
+ bool IsRegisteredFor(int State) const;
+
+ virtual void RegisterForMsWord() const;
+ virtual void UnregisterForMsWord() const;
+ virtual bool QueryPreselectMsWordRegistration() const;
+
+ virtual void RegisterForMsExcel() const;
+ virtual void UnregisterForMsExcel() const;
+ virtual bool QueryPreselectMsExcelRegistration() const;
+
+ virtual void RegisterForMsPowerPoint() const;
+ virtual void UnregisterForMsPowerPoint() const;
+ virtual bool QueryPreselectMsPowerPointRegistration() const;
+
+ virtual void RegisterAsHtmlEditorForInternetExplorer() const;
+ virtual void UnregisterAsHtmlEditorForInternetExplorer() const;
+
+ virtual void RegisterAsDefaultHtmlEditorForInternetExplorer() const;
+ virtual void UnregisterAsDefaultHtmlEditorForInternetExplorer() const;
+
+ virtual void RegisterAsDefaultShellHtmlEditor() const;
+ virtual void UnregisterAsDefaultShellHtmlEditor() const;
+
+ /** Restore the last registration state (necessary for
+ Setup repair)
+ */
+ virtual void RepairRegistrationState() const;
+
+ /** Unregisters all and delete all Registry keys we have written
+ */
+ virtual void UnregisterAllAndCleanUpRegistry() const;
+
+protected:
+
+ virtual void RegisterForMsOfficeApplication(
+ const std::wstring& FileExtension,
+ const std::wstring& DocumentDisplayName,
+ const std::wstring& DefaultIconEntry,
+ const std::wstring& DefaultShellCommand,
+ const std::wstring& ShellNewCommandDisplayName,
+ const RegistrationContextInformation::OFFICE_APPLICATION eOfficeApp) const;
+
+ virtual void UnregisterForMsOfficeApplication(
+ const std::wstring& FileExtension) const;
+
+ virtual RegistryKey GetRootKeyForDefHtmlEditorForIERegistration() const;
+
+ void SaveRegisteredFor(int State) const;
+ void SaveNotRegisteredFor(int State) const;
+
+ int GetRegisterState() const;
+ void SetRegisterState(int NewState) const;
+
+ virtual bool QueryPreselectForMsApplication(const std::wstring& file_extension) const;
+
+ /** A helper function (for readability) returns true if OpenOffice is already
+ registered for a MS application
+
+ @param DocumentExtensionDefValue
+ The default value of the appropriate document extension Registry key
+ */
+ bool IsOpenOfficeRegisteredForMsApplication(const std::wstring& DocumentExtensionDefValue) const;
+
+protected:
+ const RegistrationContextInformation& m_ContextInformation;
+
+ const std::wstring FORWARD_KEY_PREFIX;
+ const std::wstring DEFAULT_VALUE_NAME;
+ const std::wstring BACKUP_VALUE_NAME;
+ const std::wstring PRIVATE_BACKUP_KEY_NAME;
+ const std::wstring REGISTRATION_STATE;
+
+ RegistryKey m_RootKey;
+
+// prevent copy/assignment
+private:
+ Registrar(const Registrar&);
+ Registrar& operator=(const Registrar&);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.cxx b/setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.cxx
new file mode 100644
index 000000000000..189b7e3074ae
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.cxx
@@ -0,0 +1,353 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+//Implementierung der Klasse RegistrationContextInformation.
+
+#include <assert.h>
+#include "registrationcontextinformation.hxx"
+#include "msihelper.hxx"
+
+#define WINDOWS_LEAN_AND_MEAN
+#include <windows.h>
+#include <assert.h>
+#include <algorithm>
+
+namespace /* private */
+{
+ const int MAX_REGKEY_LENGTH_WIN9X = 16300;
+}
+
+RegistrationContextInformation::RegistrationContextInformation(MSIHANDLE hMsi, const std::wstring& OpenOfficeExecutablePath) :
+ msihandle_(hMsi),
+ m_IsWin9x(true),
+ m_OOExecPath(OpenOfficeExecutablePath)
+{
+ OSVERSIONINFOA osverinfo;
+ ZeroMemory(&osverinfo, sizeof(osverinfo));
+ osverinfo.dwOSVersionInfoSize = sizeof(osverinfo);
+ GetVersionExA(&osverinfo);
+
+ m_IsWin9x = (osverinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
+ assert(m_OOExecPath.length());
+ ExtractOpenOfficeExecNameFromPath();
+}
+
+std::wstring RegistrationContextInformation::GetWordDocumentDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_MS_WORD_DOCUMENT"), str);
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("Microsoft Word Document");
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetWordDocumentFileExtension() const
+{
+ return std::wstring(TEXT(".doc"));
+}
+
+std::wstring RegistrationContextInformation::GetWordDocumentDefaultIconEntry() const
+{
+ return m_OOExecPath + std::wstring(TEXT(",1"));
+}
+
+std::wstring RegistrationContextInformation::GetWordDocumentDefaultShellCommand() const
+{
+ return std::wstring(TEXT("open"));
+}
+
+std::wstring RegistrationContextInformation::GetWordTemplateDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_MS_WORD_TEMPLATE"), str);
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("Microsoft Word Template");
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetWordTemplateFileExtension() const
+{
+ return std::wstring(TEXT(".dot"));
+}
+
+std::wstring RegistrationContextInformation::GetWordTemplateDefaultIconEntry() const
+{
+ return m_OOExecPath + std::wstring(TEXT(",2"));
+}
+
+std::wstring RegistrationContextInformation::GetWordTemplateDefaultShellCommand() const
+{
+ return std::wstring(TEXT("new"));
+}
+
+std::wstring RegistrationContextInformation::GetRtfDocumentDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_RTF_DOCUMENT"), str);
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("Rich Text Document");
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetRtfDocumentFileExtension() const
+{
+ return std::wstring(TEXT(".rtf"));
+}
+
+std::wstring RegistrationContextInformation::GetRtfDocumentDefaultIconEntry() const
+{
+ return m_OOExecPath + std::wstring(TEXT(",1"));
+}
+
+std::wstring RegistrationContextInformation::GetRtfDocumentDefaultShellCommand() const
+{
+ return std::wstring(TEXT("open"));
+}
+
+std::wstring RegistrationContextInformation::GetExcelSheetDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_MS_EXCEL_WORKSHEET"), str);
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("Microsoft Excel Worksheet");
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetExcelSheetFileExtension() const
+{
+ return std::wstring(TEXT(".xls"));
+}
+
+std::wstring RegistrationContextInformation::GetExcelSheetDefaultIconEntry() const
+{
+ return m_OOExecPath + std::wstring(TEXT(",3"));
+}
+
+std::wstring RegistrationContextInformation::GetExcelSheetDefaultShellCommand() const
+{
+ return std::wstring(TEXT("open"));
+}
+
+std::wstring RegistrationContextInformation::GetExcelTemplateDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_MS_EXCEL_TEMPLATE"), str);
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("Microsoft Excel Template");
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetExcelTemplateFileExtension() const
+{
+ return std::wstring(TEXT(".xlt"));
+}
+
+std::wstring RegistrationContextInformation::GetExcelTemplateDefaultIconEntry() const
+{
+ return m_OOExecPath + std::wstring(TEXT(",4"));
+}
+
+std::wstring RegistrationContextInformation::GetExcelTemplateDefaultShellCommand() const
+{
+ return std::wstring(TEXT("new"));
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointDocumentDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_MS_POWERPOINT_PRESENTATION"), str);
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("Microsoft PowerPoint Presentation");
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointDocumentFileExtension() const
+{
+ return std::wstring(TEXT(".ppt"));
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointDocumentDefaultIconEntry() const
+{
+ return m_OOExecPath + std::wstring(TEXT(",7"));
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointDocumentDefaultShellCommand() const
+{
+ return std::wstring(TEXT("open"));
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointTemplateDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_MS_POWERPOINT_TEMPLATE"), str);
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("Microsoft PowerPoint Template");
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointTemplateFileExtension() const
+{
+ return std::wstring(TEXT(".pot"));
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointTemplateDefaultIconEntry() const
+{
+ return m_OOExecPath + std::wstring(TEXT(",8"));
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointTemplateDefaultShellCommand() const
+{
+ return std::wstring(TEXT("new"));
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointShowDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_MS_POWERPOINT_SHOW"), str);
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("Microsoft PowerPoint Show");
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointShowFileExtension() const
+{
+ return std::wstring(TEXT(".pps"));
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointShowDefaultIconEntry() const
+{
+ return m_OOExecPath + std::wstring(TEXT(",7"));
+}
+
+std::wstring RegistrationContextInformation::GetPowerPointShowDefaultShellCommand() const
+{
+ return std::wstring(TEXT("open"));
+}
+
+//----------------------------------------------
+/** The string for the "New" command that should appear
+ in the Explorer context menu when someone right
+ clicks a Microsoft document
+*/
+std::wstring RegistrationContextInformation::ShellNewCommandDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_NEW_DISPLAY_NAME"), str);
+ std::wstring::size_type idx = str.find(TEXT("~"));
+
+ if(std::wstring::npos != idx)
+ str.replace(idx, 1, TEXT("&"));
+
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("&New");
+
+ return str;
+}
+
+/** The string for the "Edit" command that should
+ appear in the Explorer context menu when someone
+ right clicks a document
+*/
+std::wstring RegistrationContextInformation::ShellEditCommandDisplayName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("STR_EDIT"), str);
+ std::wstring::size_type idx = str.find(TEXT("~"));
+
+ if(std::wstring::npos != idx)
+ str.replace(idx, 1, TEXT("&"));
+
+ if (m_IsWin9x && !IsConvertableToAnsi(str))
+ str = TEXT("&Edit");
+
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetOpenOfficeFriendlyAppName() const
+{
+ std::wstring str;
+ GetMsiProp(msihandle_, TEXT("ProductName"), str);
+ return str;
+}
+
+std::wstring RegistrationContextInformation::GetOpenOfficeExecutablePath() const
+{
+ return m_OOExecPath;
+}
+
+//----------------------------------------------
+/** The name of the executable (currently "soffice.exe"
+ but may change in the future, who knows) */
+std::wstring RegistrationContextInformation::GetOpenOfficeExecutableName() const
+{
+ return m_OOExecName;
+}
+
+/** A command line for the specified shell command */
+std::wstring RegistrationContextInformation::GetOpenOfficeCommandline(SHELL_COMMAND ShellCommand,
+ OFFICE_APPLICATION OfficeApp) const
+{
+ // quote the path to OpenOffice, this is important
+ // for Windows 9x
+ std::wstring cmd_line = std::wstring(TEXT("\"")) + m_OOExecPath + std::wstring(TEXT("\""));
+
+ switch( OfficeApp )
+ {
+ case Writer:
+ cmd_line += std::wstring( TEXT( " -writer" ) );
+ break;
+ case Calc:
+ cmd_line += std::wstring( TEXT( " -calc" ) );
+ break;
+ case Impress:
+ cmd_line += std::wstring( TEXT( " -impress" ) );
+ break;
+ case Office: // default to std command line
+ break;
+ // default: no default to find new added enums at compile time
+ }
+ switch(ShellCommand)
+ {
+ case New:
+ cmd_line += std::wstring(TEXT(" -n \"%1\""));
+ break;
+ case Open:
+ cmd_line += std::wstring(TEXT(" -o \"%1\""));
+ break;
+ case Print:
+ cmd_line += std::wstring(TEXT(" -p \"%1\""));
+ break;
+ case Printto:
+ cmd_line += std::wstring(TEXT(" -pt \"%2\" \"%1\""));
+ break;
+ // default: no default to find new added enums at compile time
+ }
+ return cmd_line;
+}
+
+bool RegistrationContextInformation::IsConvertableToAnsi(const std::wstring& String) const
+{
+ char buff[MAX_REGKEY_LENGTH_WIN9X];
+ BOOL bUsedDefChar = 0;
+
+ if (String.length() > 0)
+ {
+ WideCharToMultiByte(
+ CP_ACP,
+ WC_COMPOSITECHECK | WC_DEFAULTCHAR,
+ String.c_str(),
+ static_cast<int>(String.length()),
+ buff,
+ sizeof(buff),
+ NULL,
+ &bUsedDefChar);
+ }
+ return !bUsedDefChar;
+}
+
+void RegistrationContextInformation::ExtractOpenOfficeExecNameFromPath()
+{
+ std::wstring::size_type idx = m_OOExecPath.find_last_of(TEXT('\\'));
+ assert(idx != std::wstring::npos); // assert valid path
+ m_OOExecName = m_OOExecPath.substr(idx + 1);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.hxx b/setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.hxx
new file mode 100644
index 000000000000..91a42e6b58d7
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.hxx
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// MsOfficeDocumentInformation.h: Schnittstelle f�r die Klasse MsOfficeDocumentInformation.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef _REGISTRATIONCONTEXTINFORMATION_HXX_
+#define _REGISTRATIONCONTEXTINFORMATION_HXX_
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msi.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string>
+
+/** A simple implementation class that returns the
+ appropriate display names for the Microsoft
+ Office document types.
+ Under Windows 9x this class checks if the
+ document display name is convertable to an ANSI
+ string and if not returns an english default.
+ So we avoid garbage if soemone for instance
+ installs an japanese StarOffice/OpenOffice
+ under a German Windows 98 for instance.
+*/
+class RegistrationContextInformation
+{
+public:
+
+ enum SHELL_COMMAND {New, Open, Print, Printto};
+ enum OFFICE_APPLICATION {Office, Writer, Calc, Impress};
+
+ RegistrationContextInformation(MSIHANDLE hMsi, const std::wstring& OpenOfficeExecutablePath);
+
+ /** Word document information
+ The icon index is the index of the icon
+ in soffice.exe to be associated with
+ word document files
+ */
+ std::wstring GetWordDocumentDisplayName() const;
+ std::wstring GetWordDocumentFileExtension() const;
+ std::wstring GetWordDocumentDefaultIconEntry() const;
+ std::wstring GetWordDocumentDefaultShellCommand() const;
+
+ /** Word template information
+ The icon index is the index of the icon
+ in soffice.exe to be associated with
+ word template files
+ */
+ std::wstring GetWordTemplateDisplayName() const;
+ std::wstring GetWordTemplateFileExtension() const;
+ std::wstring GetWordTemplateDefaultIconEntry() const;
+ std::wstring GetWordTemplateDefaultShellCommand() const;
+
+ /** Rtf document information
+ The icon index is the index of the icon
+ in soffice.exe to be associated with
+ rtf document files
+ */
+ std::wstring GetRtfDocumentDisplayName() const;
+ std::wstring GetRtfDocumentFileExtension() const;
+ std::wstring GetRtfDocumentDefaultIconEntry() const;
+ std::wstring GetRtfDocumentDefaultShellCommand() const;
+
+ /** Excel sheet information
+ The icon index is the index of the icon
+ in soffice.exe to be associated with
+ Excel sheets
+ */
+ std::wstring GetExcelSheetDisplayName() const;
+ std::wstring GetExcelSheetFileExtension() const;
+ std::wstring GetExcelSheetDefaultIconEntry() const;
+ std::wstring GetExcelSheetDefaultShellCommand() const;
+
+ /** Excel template information
+ The icon index is the index of the icon
+ in soffice.exe to be associated with
+ Excel template files
+ */
+ std::wstring GetExcelTemplateDisplayName() const;
+ std::wstring GetExcelTemplateFileExtension() const;
+ std::wstring GetExcelTemplateDefaultIconEntry() const;
+ std::wstring GetExcelTemplateDefaultShellCommand() const;
+
+ /** PowerPoint document information
+ The icon index is the index of the icon
+ in soffice.exe to be associated with
+ PowerPoint document files
+ */
+ std::wstring GetPowerPointDocumentDisplayName() const;
+ std::wstring GetPowerPointDocumentFileExtension() const;
+ std::wstring GetPowerPointDocumentDefaultIconEntry() const;
+ std::wstring GetPowerPointDocumentDefaultShellCommand() const;
+
+ /** PowerPoint template information
+ The icon index is the index of the icon
+ in soffice.exe to be associated with
+ PowerPoint template files
+ */
+ std::wstring GetPowerPointTemplateDisplayName() const;
+ std::wstring GetPowerPointTemplateFileExtension() const;
+ std::wstring GetPowerPointTemplateDefaultIconEntry() const;
+ std::wstring GetPowerPointTemplateDefaultShellCommand() const;
+
+ /** PowerPoint Show information
+ */
+ std::wstring GetPowerPointShowDisplayName() const;
+ std::wstring GetPowerPointShowFileExtension() const;
+ std::wstring GetPowerPointShowDefaultIconEntry() const;
+ std::wstring GetPowerPointShowDefaultShellCommand() const;
+
+ /** The string for the "New" command that should appear
+ in the Explorer context menu when someone right
+ clicks a Microsoft document
+ */
+ std::wstring ShellNewCommandDisplayName() const;
+
+ /** The string for the "Edit" command that should
+ appear in the Explorer context menu when someone
+ right clicks a document
+ */
+ std::wstring ShellEditCommandDisplayName() const;
+
+ /** A friendly name for the application
+ */
+ std::wstring GetOpenOfficeFriendlyAppName() const;
+
+ /** The path to the StarOffice/OpenOffice executable
+ */
+ std::wstring GetOpenOfficeExecutablePath() const;
+
+ /** The name of the executable (currently "soffice.exe"
+ but may change in the future, who knows)
+ */
+ std::wstring GetOpenOfficeExecutableName() const;
+
+ /** A command line for the specified shell command
+ */
+ std::wstring GetOpenOfficeCommandline(SHELL_COMMAND ShellCommand,
+ OFFICE_APPLICATION OfficeApp) const;
+
+private:
+ bool IsConvertableToAnsi(const std::wstring& String) const;
+
+ void ExtractOpenOfficeExecNameFromPath();
+
+private:
+ MSIHANDLE msihandle_;
+ bool m_IsWin9x;
+ std::wstring m_OOExecPath;
+ std::wstring m_OOExecName;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registry.cxx b/setup_native/source/win32/customactions/reg4msdoc/registry.cxx
new file mode 100644
index 000000000000..bc277997b92b
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registry.cxx
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "registry.hxx"
+
+#include <Shlwapi.h>
+#include <assert.h>
+#include <algorithm>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4786 4350)
+#endif
+
+//-----------------------------------------------------
+/** Create instance and open the specified Registry key
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ RegistryKeyNotFoundException
+*/
+RegistryKeyImpl::RegistryKeyImpl(HKEY RootKey, const std::wstring& KeyName) :
+ m_hRootKey(RootKey),
+ m_hSubKey(0),
+ m_KeyName(KeyName),
+ m_IsWriteable(false)
+{
+}
+
+//-----------------------------------------------------
+/** Create instance and open the specified Registry key
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ RegistryKeyNotFoundException
+*/
+RegistryKeyImpl::RegistryKeyImpl(HKEY RootKey) :
+ m_hRootKey(RootKey),
+ m_hSubKey(0),
+ m_IsWriteable(false)
+{
+}
+
+//-----------------------------------------------------
+/** Create an instances of the specified Registry key,
+ the key is assumed to be already opened.
+*/
+RegistryKeyImpl::RegistryKeyImpl(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable) :
+ m_hRootKey(RootKey),
+ m_hSubKey(SubKey),
+ m_KeyName(KeyName),
+ m_IsWriteable(Writeable)
+{
+}
+
+//-----------------------------------------------------
+/**
+*/
+RegistryKeyImpl::~RegistryKeyImpl()
+{
+ if (IsOpen())
+ Close();
+}
+
+
+//############################################
+// Queries
+//############################################
+
+
+//-----------------------------------------------------
+/** The name of the key at hand, maybe empty
+ if this is any of the root keys
+*/
+std::wstring RegistryKeyImpl::GetName() const
+{
+ return m_KeyName;
+}
+
+//-----------------------------------------------------
+/**
+*/
+bool RegistryKeyImpl::IsOpen() const
+{
+ return m_hSubKey != 0;
+}
+
+//-----------------------------------------------------
+/** Is this one of the root keys
+ HKEY_CLASSES_ROOT
+ HKEY_CURRENT_USER
+ etc.
+*/
+bool RegistryKeyImpl::IsRootKey() const
+{
+ return (0 == m_KeyName.length());
+}
+
+//-----------------------------------------------------
+/** Do we have write access on the key at hand
+*/
+bool RegistryKeyImpl::IsWriteable() const
+{
+ return m_IsWriteable;
+}
+
+//-----------------------------------------------------
+/** Convenience function to determine if the
+ Registry key at hand has the specified
+ value
+
+ @precond IsOpen = true
+
+ throws RegistryAccessDenyException
+*/
+bool RegistryKeyImpl::HasValue(const std::wstring& Name) const
+{
+ StringListPtr names = GetSubValueNames();
+
+ StringList::iterator iter_end = names->end();
+ StringList::iterator iter = std::find(names->begin(), iter_end, Name);
+
+ return (iter != iter_end);
+}
+
+struct CompareNamesCaseInsensitive
+{
+ CompareNamesCaseInsensitive(const std::wstring& Name) :
+ name_(Name)
+ {}
+
+ bool operator() (const std::wstring& value)
+ {
+ return (0 == StrCmpI(value.c_str(), name_.c_str()));
+ }
+
+ std::wstring name_;
+};
+
+//-----------------------------------------------------
+/** Convenience function to determine if the
+ Registry key at hand has the specified
+ sub-key
+
+ @precond IsOpen = true
+
+ throws RegistryAccessDenyException
+*/
+bool RegistryKeyImpl::HasSubKey(const std::wstring& Name) const
+{
+ StringListPtr names = GetSubKeyNames();
+
+ StringList::iterator iter_end = names->end();
+ StringList::iterator iter = std::find_if(names->begin(), iter_end, CompareNamesCaseInsensitive(Name));
+
+ return (iter != iter_end);
+}
+
+//-----------------------------------------------------
+/**
+*/
+void RegistryKeyImpl::Close()
+{
+ if (RegCloseKey(m_hSubKey) != ERROR_SUCCESS) {
+ assert(false);
+ }
+
+ m_hSubKey = 0;
+ m_IsWriteable = false;
+}
+
+//-----------------------------------------------------
+/** Copies the specified value from RegistryKey to
+ the registry key at hand, if a value with this
+ name already exist under the registry key at hand
+ it will be overwritten
+
+ @precond IsOpen = true
+ IsWriteable = true
+ RegistryKey.HasSubValue(Name) = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDeniedException
+ RegistryValueNotFoundException
+*/
+void RegistryKeyImpl::CopyValue(const RegistryKey& RegistryKey, const std::wstring& Name)
+{
+ assert(RegistryKey->HasValue(Name));
+#ifdef __MINGW32__
+ SetValue((const RegistryValue&)(RegistryKey->GetValue(Name)));
+#else
+ SetValue(RegistryKey->GetValue(Name));
+#endif
+ assert(HasValue(Name));
+}
+
+/** Copies the specified value from RegistryKey to
+ the registry key at hand under a new name,
+ if a value with this name already exist there
+ it will be overwritten
+
+ @precond IsOpen = true
+ IsWriteable = true
+ RegistryKey.HasSubValue(Name) = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDeniedException
+ RegistryValueNotFoundException
+*/
+void RegistryKeyImpl::CopyValue(const RegistryKey& RegistryKey, const std::wstring& Name, const std::wstring& NewName)
+{
+ assert(RegistryKey->HasValue(Name));
+
+ RegistryValue RegVal = RegistryKey->GetValue(Name);
+ RegVal->SetName(NewName);
+ SetValue(RegVal);
+
+ assert(HasValue(NewName));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registry.hxx b/setup_native/source/win32/customactions/reg4msdoc/registry.hxx
new file mode 100644
index 000000000000..d993060ae560
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registry.hxx
@@ -0,0 +1,337 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _REGISTRY_HXX_
+#define _REGISTRY_HXX_
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <memory>
+#include <vector>
+#include <string>
+
+#include "registryvalueimpl.hxx"
+
+//---------------------------------------
+// forward declaration
+//---------------------------------------
+
+class RegistryKeyImpl;
+
+//---------------------------------------
+// typedefs
+//---------------------------------------
+
+typedef std::auto_ptr<RegistryKeyImpl> RegistryKey;
+typedef std::vector<std::wstring> StringList;
+typedef std::auto_ptr<StringList> StringListPtr;
+
+class RegistryKeyImpl
+{
+public:
+
+ //############################################
+ // Destruction
+ //############################################
+
+ virtual ~RegistryKeyImpl();
+
+
+ //############################################
+ // Queries
+ //############################################
+
+
+ /** The name of the key at hand, maybe empty
+ if this is any of the root keys
+ */
+ std::wstring GetName() const;
+
+ /** The number of sub values of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+ */
+ virtual size_t GetSubValueCount() const = 0;
+
+ /** The number of sub-keys of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+ */
+ virtual size_t GetSubKeyCount() const = 0;
+
+ bool IsOpen() const;
+
+ /** Do we have write access on the key at hand
+ */
+ bool IsWriteable() const;
+
+ /** The StringList will be allocated on the heap,
+ so this is in fact a transfer of ownership
+ to the caller
+
+ @precond IsOpen = true
+
+ @throws RegistryIOException
+ */
+ virtual StringListPtr GetSubKeyNames() const = 0;
+
+ /** The StringList will be allocated on the heap,
+ so this is in fact a transfer of ownership
+ to the caller
+
+ @precond IsOpen = true
+
+ @throws RegistryIOException
+ */
+ virtual StringListPtr GetSubValueNames() const = 0;
+
+ /** Get the specified registry value
+
+ @precond IsOpen = true
+ */
+ virtual RegistryValue GetValue(const std::wstring& Name) const = 0;
+
+ /** Get the specified registry value, return the given
+ default value if value not found
+
+ @precond IsOpen = true
+ */
+ virtual RegistryValue GetValue(const std::wstring& Name, const RegistryValue& Default) const = 0;
+
+ /** Convenience function to determine if the
+ Registry key at hand has the specified
+ value
+
+ @precond IsOpen = true
+
+ throws RegistryAccessDenyException
+ */
+ bool HasValue(const std::wstring& Name) const;
+
+ /** Convenience function to determine if the
+ Registry key at hand has the specified
+ sub-key
+
+ @precond IsOpen = true
+
+ throws RegistryAccessDenyException
+ */
+ bool HasSubKey(const std::wstring& Name) const;
+
+
+ //############################################
+ // Commands
+ //############################################
+
+
+ /** Open the registry key, has no effect if
+ the key is already open
+
+ @precond IsOpen = false
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ */
+ virtual void Open(bool Writeable = true) = 0;
+
+ /** Close the registry key at hand, further
+ using it without re-opening may cause
+ RegistryIOExceptions to be thrown
+
+ This is a template method that calls
+ ImplClose which has to be overwritten
+ by sub-classes
+ */
+ void Close();
+
+ /** Open the specified sub-key of the registry key
+ at hand
+
+ @precond IsOpen = true
+ HasSubKey(Name) = true
+
+ @throws RegistryIOException
+ RegistryKeyNotFoundException
+ RegistryAccessDeniedException
+ */
+ virtual RegistryKey OpenSubKey(const std::wstring& Name, bool Writeable = true) = 0;
+
+ /** Creates a new sub-key below the key at hand
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual RegistryKey CreateSubKey(const std::wstring& Name) = 0;
+
+ /** Deletes a sub-key below the key at hand, the
+ key must not have sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual void DeleteSubKey(const std::wstring& Name) = 0;
+
+ /** Deletes a sub-key below the key at hand with all
+ its sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true;
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual void DeleteSubKeyTree(const std::wstring& Name) = 0;
+
+ /** Delete the specified value
+
+ @precond IsOpen = true
+ IsWriteable = true
+ HasValue(Name) = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDeniedException
+ RegistryValueNotFoundException
+ */
+ virtual void DeleteValue(const std::wstring& Name) = 0;
+
+ /** Set the specified registry value
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual void SetValue(const RegistryValue& Value) = 0;
+
+
+ /** Copies the specified value from RegistryKey to
+ the registry key at hand, if a value with this
+ name already exist under the registry key at hand
+ it will be overwritten
+
+ @precond IsOpen = true
+ IsWriteable = true
+ RegistryKey.HasSubValue(Name) = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDeniedException
+ RegistryValueNotFoundException
+ */
+ virtual void CopyValue(const RegistryKey& RegistryKey, const std::wstring& Name);
+
+ /** Copies the specified value from RegistryKey to
+ the registry key at hand under a new name,
+ if a value with this name already exist there
+ it will be overwritten
+
+ @precond IsOpen = true
+ IsWriteable = true
+ RegistryKey.HasSubValue(Name) = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDeniedException
+ RegistryValueNotFoundException
+ */
+ virtual void CopyValue(const RegistryKey& RegistryKey, const std::wstring& Name, const std::wstring& NewName);
+
+ //############################################
+ // Creation
+ // only possible through WindowsRegistry class
+ //############################################
+
+
+protected:
+ /** Create instance of the specified Registry key
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ RegistryKeyNotFoundException
+ */
+ RegistryKeyImpl(HKEY RootKey, const std::wstring& KeyName);
+
+ /** Create instance of the specified Registry key.
+ RootKey should only one of the predefined
+ keys HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,
+ HKEY_LOCAL_MACHINE, HKEY_USERS
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ RegistryKeyNotFoundException
+ */
+ RegistryKeyImpl(HKEY RootKey);
+
+ /** Create an instances of the specified Registry key,
+ the key is assumed to be already opened.
+ */
+ RegistryKeyImpl(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable = true);
+
+ /** Is this one of the root keys
+ HKEY_CLASSES_ROOT
+ HKEY_CURRENT_USER
+ etc.
+ */
+ bool IsRootKey() const;
+
+protected:
+ HKEY m_hRootKey;
+ HKEY m_hSubKey;
+ std::wstring m_KeyName;
+ bool m_IsWriteable;
+
+// prevent copy and assignment
+private:
+ RegistryKeyImpl(const RegistryKeyImpl&);
+ RegistryKeyImpl& operator=(const RegistryKeyImpl&);
+
+//######################################
+// Friend declarations
+//######################################
+
+friend class WindowsRegistry;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registryexception.cxx b/setup_native/source/win32/customactions/reg4msdoc/registryexception.cxx
new file mode 100644
index 000000000000..e7e66825ed4b
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryexception.cxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// RegistryException.cpp: Implementierung der Klasse RegistryException.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "registryexception.hxx"
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Konstruktion/Destruktion
+//////////////////////////////////////////////////////////////////////
+
+RegistryException::RegistryException(long ErrorCode) :
+ m_ErrorCode(ErrorCode),
+ m_ErrorMsg(0)
+{
+}
+
+RegistryException::~RegistryException() throw()
+{
+ if (m_ErrorMsg)
+ LocalFree(m_ErrorMsg);
+}
+
+const char* RegistryException::what() const throw()
+{
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ m_ErrorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &m_ErrorMsg,
+ 0,
+ NULL);
+
+ return reinterpret_cast<char*>(m_ErrorMsg);
+}
+
+long RegistryException::GetErrorCode() const
+{
+ return m_ErrorCode;
+}
+
+//#######################################
+// Thrown when a Registry key is accessed
+// that is closed
+//#######################################
+
+RegistryIOException::RegistryIOException(long ErrorCode) :
+ RegistryException(ErrorCode)
+{
+};
+
+RegistryNoWriteAccessException::RegistryNoWriteAccessException(long ErrorCode) :
+ RegistryException(ErrorCode)
+{
+};
+
+RegistryAccessDeniedException::RegistryAccessDeniedException(long ErrorCode) :
+ RegistryException(ErrorCode)
+{
+};
+
+RegistryValueNotFoundException::RegistryValueNotFoundException(long ErrorCode) :
+ RegistryException(ErrorCode)
+{
+};
+
+RegistryKeyNotFoundException::RegistryKeyNotFoundException(long ErrorCode) :
+ RegistryException(ErrorCode)
+{
+};
+
+RegistryInvalidOperationException::RegistryInvalidOperationException(long ErrorCode) :
+ RegistryException(ErrorCode)
+{
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registryexception.hxx b/setup_native/source/win32/customactions/reg4msdoc/registryexception.hxx
new file mode 100644
index 000000000000..4ea3a2098853
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryexception.hxx
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// RegistryException.h: Schnittstelle für die Klasse RegistryException.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef _REGISTRYEXCEPTION_HXX_
+#define _REGISTRYEXCEPTION_HXX_
+
+#include <exception>
+
+//#######################################
+// Base class for all Registry exceptions
+//#######################################
+
+class RegistryException : public std::exception
+{
+public:
+
+ RegistryException(long ErrorCode);
+
+ virtual ~RegistryException() throw();
+
+ /**
+ @descr Returns a string that describes the error if
+ available, else NULL will be returned. The
+ returned string is only temporary so the caller
+ has to copy it if he needs the string further.
+ */
+ virtual const char* what() const throw();
+
+ /**
+ @descr Returns the error code.
+ */
+
+ long GetErrorCode() const;
+
+private:
+ long m_ErrorCode;
+ void* m_ErrorMsg;
+};
+
+//#######################################
+// Thrown when a Registry key is accessed
+// that is closed
+//#######################################
+
+class RegistryIOException : public RegistryException
+{
+public:
+ RegistryIOException(long ErrorCode);
+};
+
+//#######################################
+// Thrown when trying to write to a readonly registry key
+//#######################################
+
+class RegistryNoWriteAccessException : public RegistryException
+{
+public:
+ RegistryNoWriteAccessException(long ErrorCode);
+};
+
+//#######################################
+// Thrown when trying to access an registry key, with improper
+// access rights
+//#######################################
+
+class RegistryAccessDeniedException : public RegistryException
+{
+public:
+ RegistryAccessDeniedException(long ErrorCode);
+};
+
+//#######################################
+// A specified registry value could not be read because it is not
+// available
+//#######################################
+
+class RegistryValueNotFoundException : public RegistryException
+{
+public:
+ RegistryValueNotFoundException(long ErrorCode);
+};
+
+//#######################################
+// A specified registry key was not found
+//#######################################
+
+class RegistryKeyNotFoundException : public RegistryException
+{
+public:
+ RegistryKeyNotFoundException(long ErrorCode);
+};
+
+//#######################################
+// A specified registry operation is invalid
+//#######################################
+
+class RegistryInvalidOperationException : public RegistryException
+{
+public:
+ RegistryInvalidOperationException(long ErrorCode);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.cxx b/setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.cxx
new file mode 100644
index 000000000000..d9012fcd087d
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.cxx
@@ -0,0 +1,192 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// RegistryValueImpl.cpp: Implementierung der Klasse RegistryValueImpl.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "registryvalueimpl.hxx"
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#include "stringconverter.hxx"
+
+//#################################
+// Creation/Destruction
+//#################################
+
+//--------------------------------------------
+/**
+*/
+RegistryValueImpl::RegistryValueImpl(const std::wstring& Name, int Value) :
+ m_Name(Name),
+ m_Type(REG_DWORD),
+ m_IntData(Value)
+{
+}
+
+//--------------------------------------------
+/**
+*/
+RegistryValueImpl::RegistryValueImpl(const std::wstring& Name, const std::wstring& Value) :
+ m_Name(Name),
+ m_Type(REG_SZ),
+ m_StringData(Value),
+ m_IntData(0)
+{
+}
+
+//--------------------------------------------
+/**
+*/
+RegistryValueImpl::RegistryValueImpl(const std::wstring& Name, const std::string& Value) :
+ m_Name(Name),
+ m_Type(REG_SZ),
+ m_IntData(0)
+{
+ m_StringData = AnsiToUnicodeString(Value);
+}
+
+#if (_MSC_VER >= 1300)
+RegistryValueImpl::RegistryValueImpl(const RegistryValueImpl& s) :
+ m_Name(s.m_Name),
+ m_Type(s.m_Type),
+ m_StringData(s.m_StringData),
+ m_IntData(s.m_IntData)
+ {
+}
+#endif
+//--------------------------------------------
+/**
+*/
+RegistryValueImpl::~RegistryValueImpl()
+{
+}
+
+//#################################
+// Query
+//#################################
+
+//--------------------------------------------
+/** Returns the name of the value
+*/
+std::wstring RegistryValueImpl::GetName() const
+{
+ return m_Name;
+}
+
+//--------------------------------------------
+/** Return the size of data held
+*/
+size_t RegistryValueImpl::GetDataSize() const
+{
+ size_t size = 0;
+
+ if (REG_DWORD == m_Type)
+ size = sizeof(m_IntData);
+ else if (REG_SZ == m_Type)
+ size = m_StringData.length() ? ((m_StringData.length() + 1) * sizeof(wchar_t)) : 0;
+
+ return size;
+}
+
+//--------------------------------------------
+/** Get a pointer to the data buffer
+ in order to copy the data
+*/
+const void* RegistryValueImpl::GetDataBuffer() const
+{
+ const void* pData = 0;
+
+ if (REG_DWORD == m_Type)
+ pData = reinterpret_cast<const void*>(&m_IntData);
+ else if (REG_SZ == m_Type)
+ pData = reinterpret_cast<const void*>(m_StringData.c_str());
+
+ return pData;
+}
+
+//--------------------------------------------
+/** Returns the data as string
+*/
+std::wstring RegistryValueImpl::GetDataAsUniString() const
+{
+ assert(REG_SZ == m_Type);
+ return m_StringData;
+}
+
+//--------------------------------------------
+/** Returns the data as string
+*/
+std::string RegistryValueImpl::GetDataAsAnsiString() const
+{
+ assert(REG_SZ == m_Type);
+ return UnicodeToAnsiString(m_StringData);
+}
+
+//--------------------------------------------
+/** Returns the data as number
+*/
+int RegistryValueImpl::GetDataAsInt() const
+{
+ assert(REG_DWORD == m_Type);
+ return m_IntData;
+}
+
+//--------------------------------------------
+/** Returns the type of the data
+*/
+int RegistryValueImpl::GetType() const
+{
+ return m_Type;
+}
+
+
+//#################################
+// Command
+//#################################
+
+
+//--------------------------------------------
+/** Set a new name
+*/
+void RegistryValueImpl::SetName(const std::wstring& NewName)
+{
+ m_Name = NewName;
+}
+
+//--------------------------------------------
+/**
+*/
+void RegistryValueImpl::SetValue(const std::wstring& NewValue)
+{
+ m_Type = REG_SZ;
+ m_StringData = NewValue;
+}
+
+//--------------------------------------------
+/**
+*/
+void RegistryValueImpl::SetValue(const std::string& NewValue)
+{
+ m_Type = REG_SZ;
+ m_StringData = AnsiToUnicodeString(NewValue);
+}
+
+//--------------------------------------------
+/**
+*/
+void RegistryValueImpl::SetValue(int NewValue)
+{
+ m_Type = REG_DWORD;
+ m_IntData = NewValue;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.hxx b/setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.hxx
new file mode 100644
index 000000000000..1f4df3353359
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.hxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// RegistryValueImpl.h: Schnittstelle für die Klasse RegistryValueImpl.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef _REGISTRYVALUEIMPL_HXX_
+#define _REGISTRYVALUEIMPL_HXX_
+
+#include <memory>
+#include <string>
+
+class RegistryValueImpl
+{
+public:
+
+ //#################################
+ // Creation/Destruction
+ //#################################
+
+ RegistryValueImpl(const std::wstring& Name, int Value);
+
+ RegistryValueImpl(const std::wstring& Name, const std::wstring& Value);
+
+ RegistryValueImpl(const std::wstring& Name, const std::string& Value);
+
+ #if (_MSC_VER >= 1300)
+ RegistryValueImpl::RegistryValueImpl(const RegistryValueImpl& s);
+ #endif
+
+ virtual ~RegistryValueImpl();
+
+
+ //#################################
+ // Query
+ //#################################
+
+
+ /** Returns the name of the value
+ */
+ std::wstring GetName() const;
+
+ /** Return the size of data held
+ */
+ size_t GetDataSize() const;
+
+ /** Get a pointer to the data buffer
+ in order to copy the data
+ */
+ const void* GetDataBuffer() const;
+
+ /** Returns the data as unicode string
+
+ @precond GetType = STRING
+ */
+ std::wstring GetDataAsUniString() const;
+
+ /** Returns the data as ansi string
+
+ @precond GetType = STRING
+ */
+ std::string GetDataAsAnsiString() const;
+
+ /** Returns the data as number
+
+ @precond GetType = NUMBER
+ */
+ int GetDataAsInt() const;
+
+ /** Returns the type of the data
+ */
+ int GetType() const;
+
+ //#################################
+ // Command
+ //#################################
+
+
+ /** Set a new name
+ */
+ void SetName(const std::wstring& NewName);
+
+ /**
+ */
+ void SetValue(const std::wstring& NewValue);
+
+ /**
+ */
+ void SetValue(const std::string& NewValue);
+
+ /**
+ */
+ void SetValue(int NewValue);
+
+ //#################################
+ // Private data
+ //#################################
+
+private:
+ std::wstring m_Name;
+ int m_Type;
+ std::wstring m_StringData;
+ int m_IntData;
+};
+
+
+typedef std::auto_ptr<RegistryValueImpl> RegistryValue;
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registryw9x.cxx b/setup_native/source/win32/customactions/reg4msdoc/registryw9x.cxx
new file mode 100644
index 000000000000..30e1cf07c5b5
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryw9x.cxx
@@ -0,0 +1,538 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "registryw9x.hxx"
+
+#include <windows.h>
+#include <malloc.h>
+#include "registryvalueimpl.hxx"
+#include "registryexception.hxx"
+#include "stringconverter.hxx"
+
+#include <assert.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4786 4350)
+#endif
+
+const size_t MAX_TMP_BUFF_SIZE = 1024 * sizeof(wchar_t);
+
+
+//############################################
+// Creation
+// only possible through WindowsRegistry class
+//############################################
+
+
+//-----------------------------------------------------
+/** Create instance and open the specified Registry key
+*/
+RegistryKeyImplWin9x::RegistryKeyImplWin9x(HKEY RootKey, const std::wstring& KeyName) :
+ RegistryKeyImpl(RootKey, KeyName)
+{
+}
+
+//-----------------------------------------------------
+/** Create instance and open the specified Registry key
+*/
+RegistryKeyImplWin9x::RegistryKeyImplWin9x(HKEY RootKey) :
+ RegistryKeyImpl(RootKey)
+{
+}
+
+//-----------------------------------------------------
+/** Create an instances of the specified Registry key,
+ the key is assumed to be already opened.
+*/
+RegistryKeyImplWin9x::RegistryKeyImplWin9x(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable) :
+ RegistryKeyImpl(RootKey, SubKey, KeyName, Writeable)
+{
+}
+
+
+//############################################
+// Queries
+//############################################
+
+
+//-----------------------------------------------------
+/** The number of sub values of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+*/
+size_t RegistryKeyImplWin9x::GetSubValueCount() const
+{
+ assert(IsOpen());
+
+ DWORD nSubValues = 0;
+
+ LONG rc = RegQueryInfoKeyA(
+ m_hSubKey,
+ 0, 0, 0, 0, 0, 0, &nSubValues, 0, 0, 0, 0);
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ return nSubValues;
+}
+
+//-----------------------------------------------------
+/** The number of sub-keys of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+*/
+size_t RegistryKeyImplWin9x::GetSubKeyCount() const
+{
+ assert(IsOpen());
+
+ DWORD nSubKeys = 0;
+
+ LONG rc = RegQueryInfoKeyA(
+ m_hSubKey,
+ 0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0);
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ return nSubKeys;
+}
+
+StringListPtr RegistryKeyImplWin9x::GetSubKeyNames() const
+{
+ assert(IsOpen());
+
+ char buff[1024];
+ DWORD buff_size = sizeof(buff);
+ FILETIME ftime;
+
+ StringList* key_names = new StringList();
+
+ LONG rc = ERROR_SUCCESS;
+
+ for (DWORD i = 0; /* left empty */; i++)
+ {
+ rc = RegEnumKeyExA(
+ m_hSubKey, i, buff, &buff_size,
+ 0, 0, 0, &ftime);
+
+ if (ERROR_SUCCESS != rc &&
+ ERROR_MORE_DATA != rc)
+ break;
+
+ buff_size = sizeof(buff);
+
+ key_names->push_back(AnsiToUnicodeString(buff));
+ }
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ return (StringListPtr) key_names;
+}
+
+StringListPtr RegistryKeyImplWin9x::GetSubValueNames() const
+{
+ assert(IsOpen());
+
+ char buff[1024];
+ DWORD buff_size = sizeof(buff);
+
+ StringList* value_names = new StringList();
+
+ LONG rc = ERROR_SUCCESS;
+
+ for (DWORD i = 0; /* left empty */; i++)
+ {
+ rc = RegEnumValueA(
+ m_hSubKey, i, buff, &buff_size,
+ 0, 0, 0, 0);
+
+ if (ERROR_SUCCESS != rc &&
+ ERROR_MORE_DATA != rc)
+ break;
+
+ buff_size = sizeof(buff);
+
+ value_names->push_back(AnsiToUnicodeString(buff));
+ }
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ return (StringListPtr) value_names;
+}
+
+//-----------------------------------------------------
+/** Get the specified registry value
+
+ @precond IsOpen = true
+*/
+RegistryValue RegistryKeyImplWin9x::GetValue(const std::wstring& Name) const
+{
+ assert(IsOpen());
+
+ DWORD Type;
+ char buff[MAX_TMP_BUFF_SIZE];
+ DWORD size = sizeof(buff);
+
+ LONG rc = RegQueryValueExA(
+ m_hSubKey,
+ UnicodeToAnsiString(Name).c_str(),
+ 0,
+ &Type,
+ reinterpret_cast<LPBYTE>(buff),
+ &size);
+
+ if (ERROR_FILE_NOT_FOUND == rc)
+ throw RegistryValueNotFoundException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ RegistryValue regval;
+
+ if (REG_DWORD == Type)
+ {
+ regval = RegistryValue(new RegistryValueImpl(Name, *(reinterpret_cast<int*>(buff))));
+ }
+ else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
+ {
+ if (size > 0)
+ regval = RegistryValue(new RegistryValueImpl(Name, std::string(reinterpret_cast<char*>(buff))));
+ else
+ regval = RegistryValue(new RegistryValueImpl(Name, std::string()));
+ }
+ else
+ {
+ assert(false);
+ }
+
+ return regval;
+}
+
+//-----------------------------------------------------
+/** Get the specified registry value, return the given
+ default value if value not found
+
+ @precond IsOpen = true
+*/
+RegistryValue RegistryKeyImplWin9x::GetValue(const std::wstring& Name, const RegistryValue& Default) const
+{
+ assert(IsOpen());
+
+ DWORD Type;
+ char buff[MAX_TMP_BUFF_SIZE];
+ DWORD size = sizeof(buff);
+
+ LONG rc = RegQueryValueExA(
+ m_hSubKey,
+ UnicodeToAnsiString(Name).c_str(),
+ 0,
+ &Type,
+ reinterpret_cast<LPBYTE>(buff),
+ &size);
+
+ if (ERROR_FILE_NOT_FOUND == rc)
+ {
+ #if !defined(__MINGW32__) && (_MSC_VER < 1300)
+ return Default;
+ #else
+ RegistryValue regval_ptr;
+ regval_ptr = RegistryValue(new RegistryValueImpl(*Default));
+ return regval_ptr;
+ #endif
+ }
+
+ if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ RegistryValue regval;
+
+ if (REG_DWORD == Type)
+ regval = RegistryValue(new RegistryValueImpl(Name, *reinterpret_cast<int*>(buff)));
+ else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
+ regval = RegistryValue(new RegistryValueImpl(Name, std::string(reinterpret_cast<char*>(buff))));
+ else
+ assert(false);
+
+ return regval;
+}
+
+
+//############################################
+// Commands
+//############################################
+
+
+//-----------------------------------------------------
+/** Open the registry key, has no effect if
+ the key is already open
+
+ @precond IsOpen = false
+
+ @throws RegistryKeyNotFoundException
+ RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+*/
+void RegistryKeyImplWin9x::Open(bool Writeable)
+{
+ assert(!IsOpen());
+
+ REGSAM regsam = KEY_READ;
+
+ if (Writeable)
+ regsam |= KEY_WRITE;
+
+ LONG rc = RegOpenKeyExA(
+ m_hRootKey,
+ UnicodeToAnsiString(m_KeyName).c_str(),
+ 0,
+ regsam,
+ &m_hSubKey);
+
+ if (ERROR_FILE_NOT_FOUND == rc)
+ throw RegistryKeyNotFoundException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ m_IsWriteable = Writeable;
+
+ assert(IsOpen());
+}
+
+//-----------------------------------------------------
+/** Open the specified sub-key of the registry key
+ at hand
+
+ @precond IsOpen = true
+ HasSubKey(Name) = true
+
+ @throws RegistryIOException
+ RegistryKeyNotFoundException
+ RegistryAccessDeniedException
+*/
+RegistryKey RegistryKeyImplWin9x::OpenSubKey(const std::wstring& Name, bool Writeable)
+{
+ RegistryKey regkey(new RegistryKeyImplWin9x(m_hSubKey, Name));
+ regkey->Open(Writeable);
+ return regkey;
+}
+
+//-----------------------------------------------------
+/** Creates a new sub-key below the key at hand
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+*/
+
+RegistryKey RegistryKeyImplWin9x::CreateSubKey(const std::wstring& Name)
+{
+ assert(IsOpen());
+ assert(IsWriteable());
+
+ HKEY hRoot = IsRootKey() ? m_hRootKey : m_hSubKey;
+
+ HKEY hKey;
+
+ LONG rc = RegCreateKeyExA(
+ hRoot,
+ UnicodeToAnsiString(Name).c_str(),
+ 0,
+ 0,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WRITE,
+ 0,
+ &hKey,
+ 0);
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ return RegistryKey(new RegistryKeyImplWin9x(hRoot, hKey, Name));
+}
+
+//-----------------------------------------------------
+/** Deletes a sub-key below the key at hand, the
+ key must not have sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+*/
+void RegistryKeyImplWin9x::DeleteSubKey(const std::wstring& Name)
+{
+ assert(IsOpen());
+ assert(IsWriteable());
+ assert(HasSubKey(Name));
+
+ RegistryKey SubKey = OpenSubKey(Name);
+
+ size_t nSubKeyCount = SubKey->GetSubKeyCount();
+
+ assert(0 == nSubKeyCount);
+
+ if (nSubKeyCount)
+ throw RegistryInvalidOperationException(ERROR_NOT_SUPPORTED);
+
+ LONG rc = RegDeleteKeyA(m_hSubKey, UnicodeToAnsiString(Name).c_str());
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+}
+
+//-----------------------------------------------------
+/** Deletes a sub-key below the key at hand with all
+ its sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true;
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+*/
+void RegistryKeyImplWin9x::DeleteSubKeyTree(const std::wstring& Name)
+{
+ LONG rc = RegDeleteKeyA(m_hSubKey, UnicodeToAnsiString(Name).c_str());
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+}
+
+//-----------------------------------------------------
+/** Delete the specified value
+
+ @precond IsOpen = true
+ IsWriteable = true
+ HasValue(Name) = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDeniedException
+ RegistryValueNotFoundException
+*/
+void RegistryKeyImplWin9x::DeleteValue(const std::wstring& Name)
+{
+ assert(IsOpen());
+ assert(HasValue(Name));
+ assert(IsWriteable());
+
+ LONG rc = RegDeleteValueA(
+ m_hSubKey,
+ UnicodeToAnsiString(Name).c_str());
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryNoWriteAccessException(rc);
+ else if (ERROR_FILE_NOT_FOUND == rc)
+ throw RegistryValueNotFoundException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+}
+
+//-----------------------------------------------------
+/** Set the specified registry value
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+*/
+void RegistryKeyImplWin9x::SetValue(const RegistryValue& Value)
+{
+ assert(IsOpen());
+ assert(IsWriteable());
+
+ LONG rc = ERROR_SUCCESS;
+
+ if (REG_SZ == Value->GetType())
+ {
+ std::string AnsiStr = Value->GetDataAsAnsiString();
+
+ rc = RegSetValueExA(
+ m_hSubKey,
+ UnicodeToAnsiString(Value->GetName()).c_str(),
+ 0,
+ Value->GetType(),
+ reinterpret_cast<const unsigned char*>(AnsiStr.c_str()),
+ static_cast<DWORD>((AnsiStr.length() + 1)));
+ }
+ else
+ {
+ rc = RegSetValueExA(
+ m_hSubKey,
+ UnicodeToAnsiString(Value->GetName()).c_str(),
+ 0,
+ Value->GetType(),
+ reinterpret_cast<const unsigned char*>(Value->GetDataBuffer()),
+ static_cast<DWORD>(Value->GetDataSize()));
+ }
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registryw9x.hxx b/setup_native/source/win32/customactions/reg4msdoc/registryw9x.hxx
new file mode 100644
index 000000000000..46c25cb898cf
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryw9x.hxx
@@ -0,0 +1,202 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _REGISTRYW9X_HXX_
+#define _REGISTRYW9X_HXX_
+
+#include "registry.hxx"
+#include "registry.hxx"
+
+//---------------------------------------
+// constants
+//---------------------------------------
+
+class RegistryKeyImplWin9x : public RegistryKeyImpl
+{
+public:
+
+ //############################################
+ // Queries
+ //############################################
+
+ /** The number of sub values of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+ */
+ virtual size_t GetSubValueCount() const;
+
+ /** The number of sub-keys of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+ */
+ virtual size_t GetSubKeyCount() const;
+
+ virtual StringListPtr GetSubKeyNames() const;
+
+ virtual StringListPtr GetSubValueNames() const;
+
+ /** Get the specified registry value
+
+ @precond IsOpen = true
+ */
+ virtual RegistryValue GetValue(const std::wstring& Name) const;
+
+ /** Get the specified registry value, return the given
+ default value if value not found
+
+ @precond IsOpen = true
+ */
+ virtual RegistryValue GetValue(const std::wstring& Name, const RegistryValue& Default) const;
+
+ //############################################
+ // Commands
+ //############################################
+
+ /** Open the registry key, has no effect if
+ the key is already open
+
+ @precond IsOpen = false
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ */
+ virtual void Open(bool Writeable = true);
+
+ /** Open the specified sub-key of the registry key
+ at hand
+
+ @precond IsOpen = true
+ HasSubKey(Name) = true
+
+ @throws RegistryIOException
+ RegistryKeyNotFoundException
+ RegistryAccessDeniedException
+ */
+ virtual RegistryKey OpenSubKey(const std::wstring& Name, bool Writeable = true);
+
+ /** Creates a new sub-key below the key at hand
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual RegistryKey CreateSubKey(const std::wstring& Name);
+
+ /** Deletes a sub-key below the key at hand, the
+ key must not have sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual void DeleteSubKey(const std::wstring& Name);
+
+ /** Deletes a sub-key below the key at hand with all
+ its sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true;
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual void DeleteSubKeyTree(const std::wstring& Name);
+
+ /** Delete the specified value
+
+ @precond IsOpen = true
+ IsWriteable = true
+ HasValue(Name) = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDeniedException
+ RegistryValueNotFoundException
+ */
+ virtual void DeleteValue(const std::wstring& Name);
+
+ /** Set the specified registry value
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual void SetValue(const RegistryValue& Value);
+
+ //############################################
+ // Creation
+ //
+ // only possible through WindowsRegistry class
+ //############################################
+
+protected:
+ /** Create instance and open the specified Registry key
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ RegistryKeyNotFoundException
+ */
+ RegistryKeyImplWin9x(HKEY RootKey, const std::wstring& KeyName);
+
+ /** Create instance and open the specified Registry key
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ RegistryKeyNotFoundException
+ */
+ RegistryKeyImplWin9x(HKEY RootKey);
+
+ /** Create an instances of the specified Registry key,
+ the key is assumed to be already opened.
+ */
+ RegistryKeyImplWin9x(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable = true);
+
+// prevent copy/assignment
+private:
+ RegistryKeyImplWin9x(const RegistryKeyImplWin9x&);
+ RegistryKeyImplWin9x& operator=(const RegistryKeyImplWin9x&);
+
+//######################################
+// Friend declarations
+//######################################
+
+friend class WindowsRegistry;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx b/setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx
new file mode 100644
index 000000000000..8776e0edd0e0
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx
@@ -0,0 +1,607 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include "registrywnt.hxx"
+#include "registryvalueimpl.hxx"
+#include "registryexception.hxx"
+
+#include <assert.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4786 4350)
+#endif
+
+const size_t MAX_TMP_BUFF_SIZE = 1024 * sizeof(wchar_t);
+
+
+//############################################
+// Creation
+// only possible through WindowsRegistry class
+//############################################
+
+
+//-----------------------------------------------------
+/** Create instance and open the specified Registry key
+*/
+RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey, const std::wstring& KeyName) :
+ RegistryKeyImpl(RootKey, KeyName)
+{
+}
+
+//-----------------------------------------------------
+/** Create instance and open the specified Registry key
+*/
+RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey) :
+ RegistryKeyImpl(RootKey)
+{
+}
+
+//-----------------------------------------------------
+/** Create an instances of the specified Registry key,
+ the key is assumed to be already opened.
+*/
+RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable) :
+ RegistryKeyImpl(RootKey, SubKey, KeyName, Writeable)
+{
+}
+
+
+//############################################
+// Queries
+//############################################
+
+
+//-----------------------------------------------------
+/** The number of sub values of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+*/
+size_t RegistryKeyImplWinNT::GetSubValueCount() const
+{
+ assert(IsOpen());
+
+ DWORD nSubValues = 0;
+
+ LONG rc = RegQueryInfoKeyW(
+ m_hSubKey,
+ 0, 0, 0, 0, 0, 0, &nSubValues, 0, 0, 0, 0);
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ return nSubValues;
+}
+
+//-----------------------------------------------------
+/** The number of sub-keys of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+*/
+size_t RegistryKeyImplWinNT::GetSubKeyCount() const
+{
+ assert(IsOpen());
+
+ DWORD nSubKeys = 0;
+
+ LONG rc = RegQueryInfoKeyA(
+ m_hSubKey,
+ 0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0);
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ return nSubKeys;
+}
+
+StringListPtr RegistryKeyImplWinNT::GetSubKeyNames() const
+{
+ assert(IsOpen());
+
+ wchar_t buff[1024];
+ DWORD buff_size = sizeof(buff);
+ FILETIME ftime;
+
+ StringList* key_names = new StringList();
+
+ LONG rc = ERROR_SUCCESS;
+
+ for (DWORD i = 0; /* left empty */; i++)
+ {
+ rc = RegEnumKeyExW(
+ m_hSubKey, i, buff, &buff_size,
+ 0, 0, 0, &ftime);
+
+ if (ERROR_SUCCESS != rc &&
+ ERROR_MORE_DATA != rc)
+ break;
+
+ buff_size = sizeof(buff);
+
+ key_names->push_back(buff);
+ }
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+#if (_MSC_VER < 1300) && !defined(__MINGW32__)
+ return key_names;
+#else
+ return (StringListPtr) key_names;
+#endif
+}
+
+StringListPtr RegistryKeyImplWinNT::GetSubValueNames() const
+{
+ assert(IsOpen());
+
+ wchar_t buff[1024];
+ DWORD buff_size = sizeof(buff);
+
+ StringList* value_names = new StringList();
+
+ LONG rc = ERROR_SUCCESS;
+
+ for (DWORD i = 0; /* left empty */; i++)
+ {
+ rc = RegEnumValueW(
+ m_hSubKey, i, buff, &buff_size,
+ 0, 0, 0, 0);
+
+ if (ERROR_SUCCESS != rc &&
+ ERROR_MORE_DATA != rc)
+ break;
+
+ buff_size = sizeof(buff);
+
+ value_names->push_back(buff);
+ }
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+#if (_MSC_VER < 1300) && !defined(__MINGW32__)
+ return value_names;
+#else
+ return (StringListPtr) value_names;
+#endif
+}
+
+//-----------------------------------------------------
+/** Get the specified registry value
+
+ @precond IsOpen = true
+*/
+RegistryValue RegistryKeyImplWinNT::GetValue(const std::wstring& Name) const
+{
+ assert(IsOpen());
+
+ DWORD Type;
+ wchar_t buff[MAX_TMP_BUFF_SIZE];
+ DWORD size = sizeof(buff);
+
+ LONG rc = RegQueryValueExW(
+ m_hSubKey,
+ Name.c_str(),
+ 0,
+ &Type,
+ reinterpret_cast<LPBYTE>(buff),
+ &size);
+
+ if (ERROR_FILE_NOT_FOUND == rc)
+ throw RegistryValueNotFoundException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ RegistryValue regval;
+
+ if (REG_DWORD == Type)
+ {
+ regval = RegistryValue(new RegistryValueImpl(Name, *(reinterpret_cast<int*>(buff))));
+ }
+ else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
+ {
+ if (size > 0)
+ regval = RegistryValue(new RegistryValueImpl(Name, std::wstring(reinterpret_cast<wchar_t*>(buff))));
+ else
+ regval = RegistryValue(new RegistryValueImpl(Name, std::wstring()));
+ }
+ else
+ {
+ assert(false);
+ }
+
+ return regval;
+}
+
+//-----------------------------------------------------
+/** Get the specified registry value, return the given
+ default value if value not found
+
+ @precond IsOpen = true
+*/
+RegistryValue RegistryKeyImplWinNT::GetValue(const std::wstring& Name, const RegistryValue& Default) const
+{
+ assert(IsOpen());
+
+ DWORD Type;
+ wchar_t buff[MAX_TMP_BUFF_SIZE];
+ DWORD size = sizeof(buff);
+
+ LONG rc = RegQueryValueExW(
+ m_hSubKey,
+ Name.c_str(),
+ 0,
+ &Type,
+ reinterpret_cast<LPBYTE>(buff),
+ &size);
+
+ if (ERROR_FILE_NOT_FOUND == rc)
+ {
+ #if (_MSC_VER < 1300) && !defined(__MINGW32__)
+ return Default;
+ #else
+ RegistryValue regval_ptr;
+ regval_ptr = RegistryValue(new RegistryValueImpl(*Default));
+ return regval_ptr;
+ #endif
+ }
+
+ if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ RegistryValue regval;
+
+ if (REG_DWORD == Type)
+ regval = RegistryValue(new RegistryValueImpl(Name, *reinterpret_cast<int*>(buff)));
+ else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
+ regval = RegistryValue(new RegistryValueImpl(Name, std::wstring(reinterpret_cast<wchar_t*>(buff))));
+ else
+ assert(false);
+
+ return regval;
+}
+
+
+//############################################
+// Commands
+//############################################
+
+
+//-----------------------------------------------------
+/** Open the registry key, has no effect if
+ the key is already open
+
+ @precond IsOpen = false
+
+ @throws RegistryKeyNotFoundException
+ RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+*/
+void RegistryKeyImplWinNT::Open(bool Writeable)
+{
+ assert(!IsOpen());
+
+ REGSAM regsam = KEY_READ;
+
+ if (Writeable)
+ regsam |= KEY_WRITE;
+
+ LONG rc = RegOpenKeyExW(
+ m_hRootKey,
+ m_KeyName.c_str(),
+ 0,
+ regsam,
+ &m_hSubKey);
+
+ if (ERROR_FILE_NOT_FOUND == rc)
+ throw RegistryKeyNotFoundException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ m_IsWriteable = Writeable;
+
+ assert(IsOpen());
+}
+
+//-----------------------------------------------------
+/** Open the specified sub-key of the registry key
+ at hand
+
+ @precond IsOpen = true
+ HasSubKey(Name) = true
+
+ @throws RegistryIOException
+ RegistryKeyNotFoundException
+ RegistryAccessDeniedException
+*/
+RegistryKey RegistryKeyImplWinNT::OpenSubKey(const std::wstring& Name, bool Writeable)
+{
+ RegistryKey regkey(new RegistryKeyImplWinNT(m_hSubKey, Name));
+ regkey->Open(Writeable);
+ return regkey;
+}
+
+//-----------------------------------------------------
+/** Creates a new sub-key below the key at hand
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+*/
+
+RegistryKey RegistryKeyImplWinNT::CreateSubKey(const std::wstring& Name)
+{
+ assert(IsOpen());
+ assert(IsWriteable());
+
+ HKEY hRoot = IsRootKey() ? m_hRootKey : m_hSubKey;
+
+ HKEY hKey;
+
+ LONG rc = RegCreateKeyExW(
+ hRoot,
+ Name.c_str(),
+ 0,
+ 0,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WRITE,
+ 0,
+ &hKey,
+ 0);
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ return RegistryKey(new RegistryKeyImplWinNT(hRoot, hKey, Name));
+}
+
+//-----------------------------------------------------
+/** Deletes a sub-key below the key at hand, the
+ key must not have sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+*/
+void RegistryKeyImplWinNT::DeleteSubKey(const std::wstring& Name)
+{
+ assert(IsOpen());
+ assert(IsWriteable());
+ assert(HasSubKey(Name));
+
+ RegistryKey SubKey = OpenSubKey(Name);
+
+ size_t nSubKeyCount = SubKey->GetSubKeyCount();
+
+ assert(0 == nSubKeyCount);
+
+ if (nSubKeyCount)
+ throw RegistryInvalidOperationException(ERROR_NOT_SUPPORTED);
+
+ LONG rc = RegDeleteKeyW(m_hSubKey, Name.c_str());
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+}
+
+//-----------------------------------------------------
+/** Deletes a sub-key below the key at hand with all
+ its sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true;
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+*/
+void RegistryKeyImplWinNT::DeleteSubKeyTree(const std::wstring& Name)
+{
+ ImplDeleteSubKeyTree(m_hSubKey, Name);
+}
+
+//-----------------------------------------------------
+/** Deletes a sub-key below the key at hand with all
+ its sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true;
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+*/
+LONG RegistryKeyImplWinNT::ImplDeleteSubKeyTree(HKEY RootKey, const std::wstring& Name)
+{
+ assert(IsOpen());
+
+ HKEY hKey;
+
+ LONG rc = RegOpenKeyExW(
+ RootKey,
+ Name.c_str(),
+ 0,
+ KEY_READ | DELETE,
+ &hKey);
+
+ if (ERROR_SUCCESS == rc)
+ {
+ wchar_t* lpSubKey;
+ DWORD nMaxSubKeyLen;
+
+ rc = RegQueryInfoKeyW(
+ hKey, 0, 0, 0, 0,
+ &nMaxSubKeyLen,
+ 0, 0, 0, 0, 0, 0);
+
+ nMaxSubKeyLen++; // space for trailing '\0'
+
+ lpSubKey = reinterpret_cast<wchar_t*>(
+ _alloca(nMaxSubKeyLen*sizeof(wchar_t)));
+
+ while (ERROR_SUCCESS == rc)
+ {
+ DWORD nLen = nMaxSubKeyLen;
+
+ rc = RegEnumKeyExW(
+ hKey,
+ 0, // always index zero
+ lpSubKey,
+ &nLen,
+ 0, 0, 0, 0);
+
+ if (ERROR_NO_MORE_ITEMS == rc)
+ {
+ rc = RegDeleteKeyW(RootKey, Name.c_str());
+ break;
+ }
+ else if (rc == ERROR_SUCCESS)
+ {
+ rc = ImplDeleteSubKeyTree(hKey, lpSubKey);
+ }
+
+ } // while
+
+ RegCloseKey(hKey);
+
+ } // if
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_FILE_NOT_FOUND == rc)
+ throw RegistryKeyNotFoundException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+
+ return rc;
+}
+
+//-----------------------------------------------------
+/** Delete the specified value
+
+ @precond IsOpen = true
+ IsWriteable = true
+ HasValue(Name) = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDeniedException
+ RegistryValueNotFoundException
+*/
+void RegistryKeyImplWinNT::DeleteValue(const std::wstring& Name)
+{
+ assert(IsOpen());
+ assert(HasValue(Name));
+ assert(IsWriteable());
+
+ LONG rc = RegDeleteValueW(
+ m_hSubKey,
+ Name.c_str());
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryNoWriteAccessException(rc);
+ else if (ERROR_FILE_NOT_FOUND == rc)
+ throw RegistryValueNotFoundException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+}
+
+//-----------------------------------------------------
+/** Set the specified registry value
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+*/
+void RegistryKeyImplWinNT::SetValue(const RegistryValue& Value)
+{
+ assert(IsOpen());
+ assert(IsWriteable());
+
+ LONG rc = RegSetValueExW(
+ m_hSubKey,
+ Value->GetName().c_str(),
+ 0,
+ Value->GetType(),
+ reinterpret_cast<const unsigned char*>(Value->GetDataBuffer()),
+ static_cast<DWORD>(Value->GetDataSize()));
+
+ if (ERROR_INVALID_HANDLE == rc)
+ throw RegistryIOException(rc);
+ else if (ERROR_ACCESS_DENIED == rc)
+ throw RegistryAccessDeniedException(rc);
+ else if (ERROR_SUCCESS != rc)
+ throw RegistryException(rc);
+}
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registrywnt.hxx b/setup_native/source/win32/customactions/reg4msdoc/registrywnt.hxx
new file mode 100644
index 000000000000..517327f34582
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrywnt.hxx
@@ -0,0 +1,205 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _REGISTRYWNT_HXX_
+#define _REGISTRYWNT_HXX_
+
+#include "registry.hxx"
+
+//---------------------------------------
+// constants
+//---------------------------------------
+
+class RegistryKeyImplWinNT : public RegistryKeyImpl
+{
+public:
+
+ //############################################
+ // Queries
+ //############################################
+
+ /** The number of sub values of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+ */
+ virtual size_t GetSubValueCount() const;
+
+ /** The number of sub-keys of the key at hand
+
+ @precond IsOpen = true
+
+ @throws
+ */
+ virtual size_t GetSubKeyCount() const;
+
+ virtual StringListPtr GetSubKeyNames() const;
+
+ virtual StringListPtr GetSubValueNames() const;
+
+ /** Get the specified registry value
+
+ @precond IsOpen = true
+ */
+ virtual RegistryValue GetValue(const std::wstring& Name) const;
+
+ /** Get the specified registry value, return the given
+ default value if value not found
+
+ @precond IsOpen = true
+ */
+ virtual RegistryValue GetValue(const std::wstring& Name, const RegistryValue& Default) const;
+
+ //############################################
+ // Commands
+ //############################################
+
+ /** Open the registry key, has no effect if
+ the key is already open
+
+ @precond IsOpen = false
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ */
+ virtual void Open(bool Writeable = true);
+
+ /** Open the specified sub-key of the registry key
+ at hand
+
+ @precond IsOpen = true
+ HasSubKey(Name) = true
+
+ @throws RegistryIOException
+ RegistryKeyNotFoundException
+ RegistryAccessDeniedException
+ */
+ virtual RegistryKey OpenSubKey(const std::wstring& Name, bool Writeable = true);
+
+ /** Creates a new sub-key below the key at hand
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual RegistryKey CreateSubKey(const std::wstring& Name);
+
+ /** Deletes a sub-key below the key at hand, the
+ key must not have sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual void DeleteSubKey(const std::wstring& Name);
+
+ /** Deletes a sub-key below the key at hand with all
+ its sub-keys
+
+ @precond IsOpen = true
+ IsWriteable = true;
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual void DeleteSubKeyTree(const std::wstring& Name);
+
+ /** Delete the specified value
+
+ @precond IsOpen = true
+ IsWriteable = true
+ HasValue(Name) = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDeniedException
+ RegistryValueNotFoundException
+ */
+ virtual void DeleteValue(const std::wstring& Name);
+
+ /** Set the specified registry value
+
+ @precond IsOpen = true
+ IsWriteable = true
+
+ @throws RegistryIOException
+ RegistryWriteAccessDenyException
+ */
+ virtual void SetValue(const RegistryValue& Value);
+
+ //############################################
+ // Creation
+ //
+ // only possible through WindowsRegistry class
+ //############################################
+
+protected:
+ /** Create instance and open the specified Registry key
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ RegistryKeyNotFoundException
+ */
+ RegistryKeyImplWinNT(HKEY RootKey, const std::wstring& KeyName);
+
+ /** Create instance and open the specified Registry key
+
+ @throws RegistryWriteAccessDenyException
+ RegistryAccessDenyException
+ RegistryKeyNotFoundException
+ */
+ RegistryKeyImplWinNT(HKEY RootKey);
+
+ /** Create an instances of the specified Registry key,
+ the key is assumed to be already opened.
+ */
+ RegistryKeyImplWinNT(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable = true);
+
+private:
+
+ LONG ImplDeleteSubKeyTree(HKEY RootKey, const std::wstring& Name);
+
+//prevent copy and assignment
+private:
+ RegistryKeyImplWinNT(const RegistryKeyImplWinNT&);
+ RegistryKeyImplWinNT& operator=(const RegistryKeyImplWinNT&);
+
+//######################################
+// Friend declarations
+//######################################
+
+friend class WindowsRegistry;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/stringconverter.cxx b/setup_native/source/win32/customactions/reg4msdoc/stringconverter.cxx
new file mode 100644
index 000000000000..db38d568e877
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/stringconverter.cxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "stringconverter.hxx"
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+/** Convert a Unicode string to an ANSI string based on CP_ACP
+*/
+std::string UnicodeToAnsiString(const std::wstring& UniString)
+{
+ int len = WideCharToMultiByte(
+ CP_ACP, 0, UniString.c_str(), -1, 0, 0, 0, 0);
+
+ char* buff = reinterpret_cast<char*>(_alloca(len));
+
+ WideCharToMultiByte(
+ CP_ACP, 0, UniString.c_str(), -1, buff, len, 0, 0);
+
+ return std::string(buff);
+}
+
+/** Convert an ANSI string to unicode based on CP_ACP
+*/
+std::wstring AnsiToUnicodeString(const std::string& AnsiString)
+{
+ int len = MultiByteToWideChar(
+ CP_ACP, 0, AnsiString.c_str(), -1, 0, 0);
+
+ wchar_t* buff = reinterpret_cast<wchar_t*>(_alloca(len * sizeof(wchar_t)));
+
+ MultiByteToWideChar(
+ CP_ACP, 0, AnsiString.c_str(), -1, buff, len);
+
+ return std::wstring(buff);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/stringconverter.hxx b/setup_native/source/win32/customactions/reg4msdoc/stringconverter.hxx
new file mode 100644
index 000000000000..c8fcbd56f627
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/stringconverter.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STRINGCONVERTER_HXX_
+#define _STRINGCONVERTER_HXX_
+
+#include <string>
+
+/** Convert a Unicode string to an ANSI string based on CP_ACP
+*/
+std::string UnicodeToAnsiString(const std::wstring& UniString);
+
+/** Convert an ANSI string to unicode based on CP_ACP
+*/
+std::wstring AnsiToUnicodeString(const std::string& AnsiString);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/userregistrar.cxx b/setup_native/source/win32/customactions/reg4msdoc/userregistrar.cxx
new file mode 100644
index 000000000000..986bf0d28cb6
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/userregistrar.cxx
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// UserRegistrar.cpp: Implementierung der Klasse UserRegistrar.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "userregistrar.hxx"
+#include "registryvalueimpl.hxx"
+#include "windowsregistry.hxx"
+#include "registryexception.hxx"
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4350)
+#endif
+
+//--------------------------------------
+/**
+*/
+UserRegistrar::UserRegistrar(const RegistrationContextInformation& RegContext) :
+ Registrar(RegContext)
+{
+ RegistryKey RegKey = WindowsRegistry().GetCurrentUserKey();
+ m_RootKey = RegKey->OpenSubKey(L"Software\\Classes");
+}
+
+//###################################
+// Command
+//###################################
+
+//--------------------------------------
+/**
+*/
+void UserRegistrar::UnregisterAsHtmlEditorForInternetExplorer() const
+{
+ Registrar::UnregisterAsHtmlEditorForInternetExplorer();
+
+ DeleteHtmFileAssociationKeys();
+
+ try
+ {
+ RegistryKey RegKey = m_RootKey->OpenSubKey(L"Applications");
+ if ((0 == RegKey->GetSubValueCount()) && (0 == RegKey->GetSubKeyCount()))
+ {
+ RegKey->Close();
+ m_RootKey->DeleteSubKey(L"Applications");
+ }
+ }
+ catch(RegistryKeyNotFoundException&)
+ {
+ }
+}
+
+//--------------------------------------
+/**
+*/
+void UserRegistrar::RegisterAsDefaultShellHtmlEditor() const
+{
+ RegistryKey LocalHtmKey = m_RootKey->CreateSubKey(L".htm");
+
+ if (!LocalHtmKey->HasValue(DEFAULT_VALUE_NAME))
+ {
+ RegistryKey HKCRKey = WindowsRegistry().GetClassesRootKey();
+
+ if (HKCRKey->HasSubKey(L".htm"))
+ {
+ RegistryKey RootHtmKey = HKCRKey->OpenSubKey(L".htm", false);
+
+ if (RootHtmKey->HasValue(DEFAULT_VALUE_NAME))
+ {
+ RegistryValue RegVal = RootHtmKey->GetValue(DEFAULT_VALUE_NAME);
+
+ std::wstring RootHtmFwdKey = RegVal->GetDataAsUniString();
+
+ if (HKCRKey->HasSubKey(RootHtmFwdKey))
+ {
+ m_RootKey->CreateSubKey(RootHtmFwdKey);
+ LocalHtmKey->CopyValue(RootHtmKey, DEFAULT_VALUE_NAME);
+ }
+ }
+ }
+ }
+
+ // calling base class method
+ Registrar::RegisterAsDefaultShellHtmlEditor();
+}
+
+//--------------------------------------
+/**
+*/
+void UserRegistrar::UnregisterAsDefaultShellHtmlEditor() const
+{
+ // calling base class method
+ Registrar::UnregisterAsDefaultShellHtmlEditor();
+ DeleteHtmFileAssociationKeys();
+}
+
+//--------------------------------------
+/**
+*/
+void UserRegistrar::UnregisterForMsOfficeApplication(
+ const std::wstring& FileExtension) const
+{
+ /// calling base class method
+ Registrar::UnregisterForMsOfficeApplication(FileExtension);
+
+ if (m_RootKey->HasSubKey(FileExtension))
+ {
+ RegistryKey RegKey = m_RootKey->OpenSubKey(FileExtension);
+
+ if ((0 == RegKey->GetSubKeyCount()) && (0 == RegKey->GetSubValueCount()))
+ {
+ RegKey->Close();
+ m_RootKey->DeleteSubKey(FileExtension);
+ }
+ }
+}
+
+//--------------------------------------
+/**
+*/
+RegistryKey UserRegistrar::GetRootKeyForDefHtmlEditorForIERegistration() const
+{
+ return WindowsRegistry().GetCurrentUserKey();
+}
+
+//--------------------------------------
+/**
+*/
+void UserRegistrar::DeleteHtmFileAssociationKeys() const
+{
+ // Later delete the created keys if they are empty and have not changed meanwhile.
+ // Remeber: if we create a new registry key in the user part of the
+ // registry, changes to that key via the merged key HKEY_CLASSES_ROOT
+ // go into the user branch HKEY_CURRENT_USER and are not visible for other users.
+ // so we must carefully detect if the keys have not changed in order to prevent accidentally
+ // deleting a key and so destroying existing associations
+ // See MSDN: "Merged View of HKEY_CLASSES_ROOT"
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/userregistrar.hxx b/setup_native/source/win32/customactions/reg4msdoc/userregistrar.hxx
new file mode 100644
index 000000000000..f4b674a717e7
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/userregistrar.hxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// UserRegistrar.h: Schnittstelle für die Klasse UserRegistrar.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef _USERREGISTRAR_HXX_
+#define _USERREGISTRAR_HXX_
+
+#include "registrar.hxx"
+
+class UserRegistrar : public Registrar
+{
+public:
+
+ //###################################
+ // Creation
+ //###################################
+
+ UserRegistrar(const RegistrationContextInformation& RegContext);
+
+ //###################################
+ // Command
+ //###################################
+
+ virtual void UnregisterAsHtmlEditorForInternetExplorer() const;
+
+ virtual void RegisterAsDefaultShellHtmlEditor() const;
+ virtual void UnregisterAsDefaultShellHtmlEditor() const;
+
+protected:
+ virtual void UnregisterForMsOfficeApplication(
+ const std::wstring& FileExtension) const;
+
+ virtual RegistryKey GetRootKeyForDefHtmlEditorForIERegistration() const;
+
+private:
+
+ /** Delete the privately created file associations
+ for htm files if the keys are empty
+ */
+ void DeleteHtmFileAssociationKeys() const;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/windowsregistry.cxx b/setup_native/source/win32/customactions/reg4msdoc/windowsregistry.cxx
new file mode 100644
index 000000000000..e06f1e51bd51
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/windowsregistry.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// WindowsRegistry.cpp: Implementierung der Klasse WindowsRegistry.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "windowsregistry.hxx"
+#include "registrywnt.hxx"
+#include "registryw9x.hxx"
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4350)
+#endif
+
+WindowsRegistry::WindowsRegistry()
+{
+ OSVERSIONINFOA osverinfo;
+ ZeroMemory(&osverinfo, sizeof(osverinfo));
+ osverinfo.dwOSVersionInfoSize = sizeof(osverinfo);
+ GetVersionExA(&osverinfo);
+
+ m_IsWinNT = (osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+RegistryKey WindowsRegistry::GetClassesRootKey(bool Writeable) const
+{
+ return GetRegistryKey(HKEY_CLASSES_ROOT, Writeable);
+}
+
+RegistryKey WindowsRegistry::GetCurrentUserKey(bool Writeable) const
+{
+ return GetRegistryKey(HKEY_CURRENT_USER, Writeable);
+}
+
+RegistryKey WindowsRegistry::GetLocalMachineKey(bool Writeable) const
+{
+ return GetRegistryKey(HKEY_LOCAL_MACHINE, Writeable);
+}
+
+RegistryKey WindowsRegistry::GetUserKey(bool Writeable) const
+{
+ return GetRegistryKey(HKEY_USERS, Writeable);
+}
+
+RegistryKey WindowsRegistry::GetRegistryKey(HKEY RootKey, bool Writeable) const
+{
+ RegistryKey regkey;
+
+ if (m_IsWinNT)
+ regkey = RegistryKey(new RegistryKeyImplWinNT(RootKey));
+ else
+ regkey = RegistryKey(new RegistryKeyImplWin9x(RootKey));
+
+ regkey->Open(Writeable);
+
+ return regkey;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg4msdoc/windowsregistry.hxx b/setup_native/source/win32/customactions/reg4msdoc/windowsregistry.hxx
new file mode 100644
index 000000000000..1b1cb5e2829e
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/windowsregistry.hxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// WindowsRegistry.h: Schnittstelle für die Klasse WindowsRegistry.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef _WINDOWSREGISTRY_HXX_
+#define _WINDOWSREGISTRY_HXX_
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include "Registry.hxx"
+
+/** Basically a factory class
+*/
+class WindowsRegistry
+{
+public:
+ WindowsRegistry();
+
+ RegistryKey GetClassesRootKey(bool Writeable = true) const;
+
+ RegistryKey GetCurrentUserKey(bool Writeable = true) const;
+
+ RegistryKey GetLocalMachineKey(bool Writeable = true) const;
+
+ RegistryKey GetUserKey(bool Writeable = true) const;
+
+private:
+ RegistryKey GetRegistryKey(HKEY RootKey, bool Writeable) const;
+
+private:
+ bool m_IsWinNT;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/reg64/exports.dxp b/setup_native/source/win32/customactions/reg64/exports.dxp
new file mode 100755
index 000000000000..3282da1eeac0
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg64/exports.dxp
@@ -0,0 +1,2 @@
+InstallReg64
+DeinstallReg64
diff --git a/setup_native/source/win32/customactions/reg64/makefile.mk b/setup_native/source/win32/customactions/reg64/makefile.mk
new file mode 100644
index 000000000000..04117c10365d
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg64/makefile.mk
@@ -0,0 +1,108 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=reg64msi
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+EXTERNAL_WARNINGS_NOT_ERRORS := TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+#Disable precompiled header
+CDEFS+=-Dnot_used_define_to_disable_pch
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = \
+ $(SLO)$/reg64.obj
+
+STDSHL += \
+ $(KERNEL32LIB)\
+ $(USER32LIB)\
+ $(ADVAPI32LIB)\
+ $(SHELL32LIB)\
+ $(MSILIB)\
+ $(SHLWAPILIB)\
+
+# msvcprt.lib
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1OBJS=$(SLOFILES)
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+
+# --- mapimailer --------------------------------------------------------
+
+#TARGETTYPE=CUI
+
+#OBJFILES= $(OBJ)$/reg64.obj
+
+#APP1TARGET=reg64
+#APP1OBJS=$(OBJFILES)
+#APP1STDLIBS=$(KERNEL32LIB)\
+# $(ADVAPI32LIB)\
+# $(MSILIB)\
+# $(SHELL32LIB)\
+# msvcprt.lib\
+# $(OLE32LIB)\
+# $(COMCTL32LIB)\
+# $(UUIDLIB)
+
+
+#APP1DEF=$(MISC)$/$(APP1TARGET).def
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+INCLUDE!:=$(subst,/stl, $(INCLUDE))
+.EXPORT : INCLUDE
+
+# -------------------------------------------------------------------------
+
+
diff --git a/setup_native/source/win32/customactions/reg64/reg64.cxx b/setup_native/source/win32/customactions/reg64/reg64.cxx
new file mode 100644
index 000000000000..d9d3d50e540a
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg64/reg64.cxx
@@ -0,0 +1,466 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#define UNICODE
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <strsafe.h>
+
+// 10.11.2009 tkr: MinGW doesn't know anything about RegDeleteKeyExW if WINVER < 0x0502.
+extern "C" {
+WINADVAPI LONG WINAPI RegDeleteKeyExW(HKEY,LPCWSTR,REGSAM,DWORD);
+}
+
+// 06.11.2009 tkr: to provide windows xp as build systems for mingw we need to define KEY_WOW64_64KEY
+// in mingw 3.13 KEY_WOW64_64KEY isn't available < Win2003 systems.
+// Also defined in setup_native\source\win32\customactions\reg64\reg64.cxx,source\win32\customactions\shellextensions\shellextensions.cxx and
+// extensions\source\activex\main\so_activex.cpp
+
+#ifndef KEY_WOW64_64KEY
+ #define KEY_WOW64_64KEY (0x0100)
+#endif
+
+
+#define TABLE_NAME L"Reg64"
+#define INSTALLLOCATION L"[INSTALLLOCATION]"
+
+bool isInstall4AllUsers;
+wchar_t * sBasisInstallLocation;
+
+
+enum OPERATION {
+ SET,
+ REMOVE
+};
+
+#ifdef DEBUG
+inline void OutputDebugStringFormat( const wchar_t* pFormat, ... )
+{
+ wchar_t buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( const wchar_t*, ... )
+{
+}
+#endif
+
+bool WriteRegistry( MSIHANDLE & hMSI, OPERATION op, const wchar_t* componentName)
+{
+ INSTALLSTATE current_state;
+ INSTALLSTATE comp_state;
+ UINT ret = MsiGetComponentState( hMSI, componentName, &current_state, &comp_state );
+ if ( ERROR_SUCCESS == ret )
+ {
+ if (current_state == INSTALLSTATE_ABSENT)
+ OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_ABSENT");
+ else if (current_state == INSTALLSTATE_DEFAULT)
+ OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_DEFAULT");
+ else if (current_state == INSTALLSTATE_LOCAL)
+ OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_LOCAL");
+ else if (current_state == INSTALLSTATE_REMOVED)
+ OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_REMOVED");
+ else if (current_state == INSTALLSTATE_SOURCE)
+ OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_SOURCE");
+ else if (current_state == INSTALLSTATE_UNKNOWN)
+ OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_UNKNOWN");
+
+ if (comp_state == INSTALLSTATE_ABSENT)
+ OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_ABSENT");
+ else if (comp_state == INSTALLSTATE_DEFAULT)
+ OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_DEFAULT");
+ else if (comp_state == INSTALLSTATE_LOCAL)
+ OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_LOCAL");
+ else if (comp_state == INSTALLSTATE_REMOVED)
+ OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_REMOVED");
+ else if (comp_state == INSTALLSTATE_SOURCE)
+ OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_SOURCE");
+ else if (comp_state == INSTALLSTATE_UNKNOWN)
+ OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_UNKNOWN");
+
+ switch (op)
+ {
+ case SET :
+ if ( comp_state == INSTALLSTATE_LOCAL || ( current_state == INSTALLSTATE_LOCAL && comp_state == INSTALLSTATE_UNKNOWN ) )
+ {
+ return true;
+ }
+ break;
+ case REMOVE:
+ OutputDebugStringFormat(L"WriteRegistry - Remove\n" );
+ if ( current_state == INSTALLSTATE_LOCAL && (comp_state == INSTALLSTATE_ABSENT || comp_state == INSTALLSTATE_REMOVED) )
+ {
+ OutputDebugStringFormat(L"WriteRegistry - To be removed\n" );
+ return true;
+ }
+ }
+ } else
+ {
+ if (ERROR_INVALID_HANDLE == ret) OutputDebugStringFormat(L"WriteRegistry - Invalid handle");
+ if (ERROR_UNKNOWN_FEATURE == ret) OutputDebugStringFormat(L"WriteRegistry - Unknown feature");
+ }
+
+ return false;
+}
+
+BOOL UnicodeEquals( wchar_t* pStr1, wchar_t* pStr2 )
+{
+ if ( pStr1 == NULL && pStr2 == NULL )
+ return TRUE;
+ else if ( pStr1 == NULL || pStr2 == NULL )
+ return FALSE;
+
+ while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
+ pStr1++, pStr2++;
+
+ return ( *pStr1 == 0 && *pStr2 == 0 );
+}
+
+BOOL GetMsiProp( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
+{
+ OutputDebugStringFormat(L"GetMsiProp - START\n" );
+ DWORD sz = 0;
+ UINT ret = MsiGetProperty( hMSI, pPropName, L"", &sz );
+ if ( ret == ERROR_MORE_DATA )
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof( wchar_t );
+ wchar_t* buff = reinterpret_cast<wchar_t*>( malloc( nbytes ) );
+ ZeroMemory( buff, nbytes );
+ MsiGetProperty( hMSI, pPropName, buff, &sz );
+
+ OutputDebugStringFormat(L"GetMsiProp - Value" );
+ OutputDebugStringFormat( buff );
+ *ppValue = buff;
+
+ return TRUE;
+ } else if (ret == ERROR_INVALID_HANDLE)
+ {
+ OutputDebugStringFormat(L"GetMsiProp - ERROR_INVALID_HANDLE" );
+ } else if (ret == ERROR_INVALID_PARAMETER)
+ {
+ OutputDebugStringFormat(L"GetMsiProp - ERROR_INVALID_PARAMETER" );
+ } else if (ret == ERROR_SUCCESS)
+ {
+ OutputDebugStringFormat(L"GetMsiProp - ERROR_SUCCESS" );
+ }
+
+
+ OutputDebugStringFormat(L"GetMsiProp - ENDE\n" );
+ return FALSE;
+}
+
+bool IsInstallForAllUsers( MSIHANDLE hMSI )
+{
+ OutputDebugStringFormat(L"IsInstallForAllUsers - START\n" );
+ bool bResult = FALSE;
+ wchar_t* pVal = NULL;
+ if ( GetMsiProp( hMSI, L"ALLUSERS", &pVal ) && pVal )
+ {
+ bResult = UnicodeEquals( pVal , L"1" );
+ free( pVal );
+ }
+
+ OutputDebugStringFormat(L"IsInstallForAllUsers - ENDE\n" );
+ return bResult;
+}
+
+wchar_t* GetBasisInstallLocation( MSIHANDLE hMSI )
+{
+ OutputDebugStringFormat(L"GetBasisInstallLocation - START\n" );
+ bool bResult = FALSE;
+ wchar_t* pVal = NULL;
+ GetMsiProp( hMSI, L"INSTALLLOCATION", &pVal);
+
+ OutputDebugStringFormat(L"GetBasisInstallLocation - ENDE\n" );
+
+ return pVal;
+}
+
+
+bool QueryReg64Table(MSIHANDLE& rhDatabase, MSIHANDLE& rhView)
+{
+ OutputDebugStringFormat(L"QueryReg64Table - START\n" );
+ int const arraysize = 400;
+ wchar_t szSelect[arraysize];
+ StringCbPrintfW(szSelect, arraysize * sizeof(wchar_t), L"SELECT * FROM %s",TABLE_NAME);
+ OutputDebugStringFormat( szSelect );
+
+ UINT ret = MsiDatabaseOpenView(rhDatabase,szSelect,&rhView);
+ if (ret != ERROR_SUCCESS)
+ {
+ if ( ret == ERROR_BAD_QUERY_SYNTAX)
+ OutputDebugStringFormat(L"QueryReg64Table - MsiDatabaseOpenView - FAILED - ERROR_BAD_QUERY_SYNTAX\n" );
+ if ( ret == ERROR_INVALID_HANDLE)
+ OutputDebugStringFormat(L"QueryReg64Table - MsiDatabaseOpenView - FAILED - ERROR_INVALID_HANDLE\n" );
+ return false;
+ }
+ // execute query - not a parameter query so second parameter is NULL.
+ if (MsiViewExecute(rhView,NULL) != ERROR_SUCCESS)
+ {
+ OutputDebugStringFormat(L"QueryReg64Table - MsiViewExecute - FAILED\n" );
+ return false;
+ }
+
+ OutputDebugStringFormat(L"QueryReg64Table - ENDE\n" );
+ return true;
+}
+
+//---------------------------------------
+bool DeleteRegistryKey(HKEY RootKey, const wchar_t* KeyName)
+{
+ int rc = RegDeleteKeyExW(
+ RootKey, KeyName, KEY_WOW64_64KEY, 0);
+
+ return (ERROR_SUCCESS == rc);
+}
+
+bool SetRegistryKey(HKEY RootKey, const wchar_t* KeyName, const wchar_t* ValueName, const wchar_t* Value)
+{
+ HKEY hSubKey;
+
+ // open or create the desired key
+ int rc = RegCreateKeyEx(
+ RootKey, KeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_64KEY, 0, &hSubKey, 0);
+
+ if (ERROR_SUCCESS == rc)
+ {
+ OutputDebugStringFormat(L"SetRegistryKey - Created\n" );
+ rc = RegSetValueEx(
+ hSubKey, ValueName, 0, REG_SZ, reinterpret_cast<const BYTE*>(Value), (wcslen(Value) + 1) * sizeof(wchar_t));
+
+ RegCloseKey(hSubKey);
+ } else {
+ OutputDebugStringFormat(L"SetRegistryKey - FAILED\n" );
+ }
+
+
+ return (ERROR_SUCCESS == rc);
+}
+
+bool DoRegEntries( MSIHANDLE& rhMSI, OPERATION op, MSIHANDLE& rhView)
+{
+ OutputDebugStringFormat(L"DoRegEntries - START\n" );
+
+ MSIHANDLE hRecord;
+
+ long lRoot;
+ wchar_t szKey[255];
+ wchar_t szName[255];
+ wchar_t szValue[1024];
+ wchar_t szComponent[255];
+
+ /// read records until there are no more records
+ while (MsiViewFetch(rhView,&hRecord) == ERROR_SUCCESS)
+ {
+ DWORD dwKey = 255;
+ DWORD dwName = 255;
+ DWORD dwValue = 1024;
+ DWORD dwComponent = 255;
+
+ szKey[0] = '\0';
+ szName[0] = '\0';
+ szValue[0] = '\0';
+ szComponent[0] = '\0';
+
+ lRoot = MsiRecordGetInteger(hRecord,2);
+ MsiRecordGetString(hRecord,3,szKey,&dwKey);
+
+ if (!MsiRecordIsNull(hRecord, 4))
+ MsiRecordGetString(hRecord,4,szName,&dwName);
+
+ if (!MsiRecordIsNull(hRecord, 5))
+ {
+ MsiRecordGetString(hRecord,5,szValue,&dwValue);
+
+
+
+ wchar_t* nPos = wcsstr(szValue , INSTALLLOCATION);
+ if ( NULL != nPos)
+ {
+
+ DWORD nPrefixSize = nPos - szValue;
+
+ DWORD nPropSize = wcslen(sBasisInstallLocation);
+ DWORD nPostfixSize = dwValue - wcslen( INSTALLLOCATION );
+
+ DWORD nNewValueBytes = (nPropSize + nPostfixSize + 1) * sizeof( wchar_t );
+ wchar_t* newValue = reinterpret_cast<wchar_t*>( malloc( nNewValueBytes ) );
+ ZeroMemory( newValue, nNewValueBytes );
+
+ // prefix
+ wcsncpy(newValue, szValue, nPrefixSize);
+
+ // basis location
+ wcsncat(newValue, sBasisInstallLocation, nPropSize * sizeof( wchar_t ));
+
+ // postfix
+ wcsncat(newValue, nPos + ( wcslen( INSTALLLOCATION ) ), nPropSize * sizeof( wchar_t ));
+
+ wcsncpy(szValue, newValue, nNewValueBytes <=1024? nNewValueBytes: 1024);
+
+ free(newValue);
+ }
+
+ }
+
+
+ MsiRecordGetString(hRecord,6,szComponent,&dwComponent);
+
+ OutputDebugStringFormat(L"****** DoRegEntries *******" );
+ OutputDebugStringFormat(L"Root:" );
+ HKEY key = HKEY_CURRENT_USER;
+ switch (lRoot)
+ {
+ case(-1):
+ if (isInstall4AllUsers)
+ {
+ key = HKEY_LOCAL_MACHINE;
+ OutputDebugStringFormat(L"HKEY_LOCAL_MACHINE" );
+ }
+ else
+ {
+ key = HKEY_CURRENT_USER;
+ OutputDebugStringFormat(L"HKEY_CURRENT_USER" );
+ }
+ break;
+ case(0):
+ key = HKEY_CLASSES_ROOT;
+ OutputDebugStringFormat(L"HKEY_CLASSES_ROOT" );
+ break;
+ case(1):
+ key = HKEY_CURRENT_USER;
+ OutputDebugStringFormat(L"HKEY_CURRENT_USER" );
+ break;
+ case(2):
+ key = HKEY_LOCAL_MACHINE;
+ OutputDebugStringFormat(L"HKEY_LOCAL_MACHINE" );
+ break;
+ case(3):
+ key = HKEY_USERS;
+ OutputDebugStringFormat(L"HKEY_USERS" );
+ break;
+ default:
+ OutputDebugStringFormat(L"Unknown Root!" );
+ break;
+ }
+
+ OutputDebugStringFormat(L"Key:");
+ OutputDebugStringFormat( szKey );
+ OutputDebugStringFormat(L"Name:");
+ OutputDebugStringFormat( szName );
+ OutputDebugStringFormat(L"Value:");
+ OutputDebugStringFormat( szValue);
+ OutputDebugStringFormat(L"Component:");
+ OutputDebugStringFormat( szComponent );
+ OutputDebugStringFormat(L"*******************" );
+ switch (op)
+ {
+ case SET:
+
+ if (WriteRegistry(rhMSI, SET, szComponent))
+ {
+ OutputDebugStringFormat(L"DoRegEntries - Write\n" );
+ SetRegistryKey(key, szKey, szName, szValue);
+ }
+ break;
+ case REMOVE:
+ OutputDebugStringFormat(L"DoRegEntries - PreRemove\n" );
+ if (WriteRegistry(rhMSI, REMOVE, szComponent))
+ {
+ OutputDebugStringFormat(L"DoRegEntries - Remove\n" );
+ DeleteRegistryKey(key, szKey);
+ }
+ break;
+ }
+ }
+
+ MsiCloseHandle(rhView);
+
+
+ OutputDebugStringFormat(L"DoRegEntries - ENDE\n" );
+
+ return true;
+}
+
+
+bool Reg64(MSIHANDLE& rhMSI, OPERATION op)
+{
+ isInstall4AllUsers = IsInstallForAllUsers(rhMSI);
+ sBasisInstallLocation = GetBasisInstallLocation(rhMSI);
+
+ if (NULL == sBasisInstallLocation)
+ {
+ OutputDebugStringFormat(L"BASISINSTALLLOCATION is NULL\n" );
+ return false;
+ }
+
+ MSIHANDLE hView;
+ MSIHANDLE hDatabase = MsiGetActiveDatabase(rhMSI);
+
+ QueryReg64Table(hDatabase, hView);
+ OutputDebugStringFormat(L"Do something\n" );
+ DoRegEntries( rhMSI, op, hView);
+ OutputDebugStringFormat(L"Something done\n" );
+
+ MsiCloseHandle(hView);
+ MsiCloseHandle(hDatabase);
+ free(sBasisInstallLocation);
+
+ return true;
+}
+
+extern "C" UINT __stdcall InstallReg64(MSIHANDLE hMSI)
+{
+ OutputDebugStringFormat(L"InstallReg64\n" );
+ Reg64(hMSI, SET);
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall DeinstallReg64(MSIHANDLE hMSI)
+{
+ OutputDebugStringFormat(L"DeinstallReg64\n" );
+ Reg64(hMSI, REMOVE);
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/regactivex/exports.dxp b/setup_native/source/win32/customactions/regactivex/exports.dxp
new file mode 100644
index 000000000000..0ad8ce403a81
--- /dev/null
+++ b/setup_native/source/win32/customactions/regactivex/exports.dxp
@@ -0,0 +1,2 @@
+InstallActiveXControl
+DeinstallActiveXControl
diff --git a/setup_native/source/win32/customactions/regactivex/makefile.mk b/setup_native/source/win32/customactions/regactivex/makefile.mk
new file mode 100644
index 000000000000..cc71dc39ada1
--- /dev/null
+++ b/setup_native/source/win32/customactions/regactivex/makefile.mk
@@ -0,0 +1,70 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=regactivex
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = $(SLO)$/regactivex.obj
+
+STDSHL += \
+ $(MSILIB)
+
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
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 000000000000..0cf89eca1ebc
--- /dev/null
+++ b/setup_native/source/win32/customactions/regactivex/regactivex.cxx
@@ -0,0 +1,441 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define UNICODE
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#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
+
+// #define OWN_DEBUG_PRINT
+
+typedef int ( __stdcall * DllNativeRegProc ) ( int, BOOL, BOOL, const char* );
+typedef int ( __stdcall * DllNativeUnregProc ) ( int, BOOL, BOOL );
+
+BOOL UnicodeEquals( wchar_t* pStr1, wchar_t* pStr2 )
+{
+ if ( pStr1 == NULL && pStr2 == NULL )
+ return TRUE;
+ else if ( pStr1 == NULL || pStr2 == NULL )
+ return FALSE;
+
+ while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
+ pStr1++, pStr2++;
+
+ return ( *pStr1 == 0 && *pStr2 == 0 );
+}
+
+//----------------------------------------------------------
+char* UnicodeToAnsiString( wchar_t* pUniString )
+{
+ int len = WideCharToMultiByte(
+ CP_ACP, 0, pUniString, -1, 0, 0, 0, 0 );
+
+ char* buff = reinterpret_cast<char*>( malloc( len ) );
+
+ WideCharToMultiByte(
+ CP_ACP, 0, pUniString, -1, buff, len, 0, 0 );
+
+ return buff;
+}
+
+#ifdef OWN_DEBUG_PRINT
+void WarningMessageInt( wchar_t* pWarning, unsigned int nValue )
+{
+ wchar_t pStr[5] = { nValue%10000/1000 + 48, nValue%1000/100 + 48, nValue%100/10 + 48, nValue%10 + 48, 0 };
+ MessageBox(NULL, pStr, pWarning, MB_OK | MB_ICONINFORMATION);
+}
+#endif
+
+//----------------------------------------------------------
+void RegisterActiveXNative( const char* pActiveXPath, int nMode, BOOL InstallForAllUser, BOOL InstallFor64Bit )
+{
+#ifdef OWN_DEBUG_PRINT
+ MessageBoxW(NULL, L"RegisterActiveXNative", L"Information", MB_OK | MB_ICONINFORMATION);
+ MessageBoxA(NULL, pActiveXPath, "Library Path", MB_OK | MB_ICONINFORMATION);
+#endif
+
+ // For Win98/WinME the values should be written to the local machine
+ OSVERSIONINFO aVerInfo;
+ aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
+ if ( GetVersionEx( &aVerInfo ) && aVerInfo.dwPlatformId != VER_PLATFORM_WIN32_NT )
+ InstallForAllUser = TRUE;
+
+ HINSTANCE hModule = LoadLibraryExA( pActiveXPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
+ if( !( hModule <= ( HINSTANCE )HINSTANCE_ERROR ) )
+ {
+ DllNativeRegProc pNativeProc = ( DllNativeRegProc )GetProcAddress( hModule, "DllRegisterServerNative" );
+ if( pNativeProc!=NULL )
+ {
+#ifdef OWN_DEBUG_PRINT
+ MessageBoxA(NULL, pActiveXPath, "Library Path", MB_OK | MB_ICONINFORMATION);
+#endif
+ int nLen = strlen( pActiveXPath );
+ int nRemoveLen = strlen( "\\so_activex.dll" );
+ if ( nLen > nRemoveLen )
+ {
+ char* pProgramPath = reinterpret_cast<char*>( malloc( nLen - nRemoveLen + 1 ) );
+ strncpy( pProgramPath, pActiveXPath, nLen - nRemoveLen );
+ pProgramPath[ nLen - nRemoveLen ] = 0;
+
+ ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit, pProgramPath );
+
+ free( pProgramPath );
+ }
+ }
+
+ FreeLibrary( hModule );
+ }
+}
+
+//----------------------------------------------------------
+void UnregisterActiveXNative( const char* pActiveXPath, int nMode, BOOL InstallForAllUser, BOOL InstallFor64Bit )
+{
+ // For Win98/WinME the values should be written to the local machine
+ OSVERSIONINFO aVerInfo;
+ aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
+ if ( GetVersionEx( &aVerInfo ) && aVerInfo.dwPlatformId != VER_PLATFORM_WIN32_NT )
+ InstallForAllUser = TRUE;
+
+ HINSTANCE hModule = LoadLibraryExA( pActiveXPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
+ if( !( hModule <= ( HINSTANCE )HINSTANCE_ERROR ) )
+ {
+ DllNativeUnregProc pNativeProc = ( DllNativeUnregProc )GetProcAddress( hModule, "DllUnregisterServerNative" );
+ if( pNativeProc!=NULL )
+ ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit );
+
+ FreeLibrary( hModule );
+ }
+}
+
+//----------------------------------------------------------
+BOOL GetMsiProp( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
+{
+ DWORD sz = 0;
+ if ( MsiGetProperty( hMSI, pPropName, L"", &sz ) == ERROR_MORE_DATA )
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof( wchar_t );
+ wchar_t* buff = reinterpret_cast<wchar_t*>( malloc( nbytes ) );
+ ZeroMemory( buff, nbytes );
+ MsiGetProperty( hMSI, pPropName, buff, &sz );
+ *ppValue = buff;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//----------------------------------------------------------
+BOOL GetActiveXControlPath( MSIHANDLE hMSI, char** ppActiveXPath )
+{
+ wchar_t* pProgPath = NULL;
+ if ( GetMsiProp( hMSI, L"INSTALLLOCATION", &pProgPath ) && pProgPath )
+ {
+ char* pCharProgPath = UnicodeToAnsiString( pProgPath );
+#ifdef OWN_DEBUG_PRINT
+ MessageBox(NULL, pProgPath, L"Basis Installation Path", MB_OK | MB_ICONINFORMATION);
+ MessageBoxA(NULL, pCharProgPath, "Basis Installation Path( char )", MB_OK | MB_ICONINFORMATION);
+#endif
+
+ if ( pCharProgPath )
+ {
+ int nLen = strlen( pCharProgPath );
+ *ppActiveXPath = reinterpret_cast<char*>( malloc( nLen + 23 ) );
+ strncpy( *ppActiveXPath, pCharProgPath, nLen );
+ strncpy( (*ppActiveXPath) + nLen, "program\\so_activex.dll", 22 );
+ (*ppActiveXPath)[nLen+22] = 0;
+
+ free( pCharProgPath );
+
+ return TRUE;
+ }
+
+ free( pProgPath );
+ }
+
+ return FALSE;
+}
+
+//----------------------------------------------------------
+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 == MsiGetFeatureState( hMSI, L"gm_p_Wrt_Bin", &current_state, &future_state ) )
+ {
+#ifdef OWN_DEBUG_PRINT
+ WarningMessageInt( L"writer current_state = ", current_state );
+ WarningMessageInt( L"writer future_state = ", future_state );
+#endif
+
+ // 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 == MsiGetFeatureState( hMSI, L"gm_p_Calc_Bin", &current_state, &future_state ) )
+ {
+#ifdef OWN_DEBUG_PRINT
+ WarningMessageInt( L"calc current_state = ", current_state );
+ WarningMessageInt( L"calc future_state = ", future_state );
+#endif
+
+ // 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 == MsiGetFeatureState( 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 == MsiGetFeatureState( 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 == MsiGetFeatureState( 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;
+}
+
+//----------------------------------------------------------
+BOOL MakeInstallForAllUsers( MSIHANDLE hMSI )
+{
+ BOOL bResult = FALSE;
+ wchar_t* pVal = NULL;
+ if ( GetMsiProp( hMSI, L"ALLUSERS", &pVal ) && pVal )
+ {
+ bResult = UnicodeEquals( pVal , L"1" );
+ free( pVal );
+ }
+
+ return bResult;
+}
+
+//----------------------------------------------------------
+BOOL MakeInstallFor64Bit( MSIHANDLE hMSI )
+{
+ BOOL bResult = FALSE;
+ wchar_t* pVal = NULL;
+ if ( GetMsiProp( hMSI, L"VersionNT64", &pVal ) && pVal )
+ {
+ bResult = TRUE;
+ free( pVal );
+ }
+
+ return bResult;
+}
+//----------------------------------------------------------
+extern "C" UINT __stdcall InstallActiveXControl( MSIHANDLE hMSI )
+{
+ int nOldInstallMode = 0;
+ int nInstallMode = 0;
+ int nDeinstallMode = 0;
+
+#ifdef OWN_DEBUG_PRINT
+ MessageBox(NULL, L"InstallActiveXControl", L"Information", MB_OK | MB_ICONINFORMATION);
+#endif
+
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+
+ if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
+ {
+#ifdef OWN_DEBUG_PRINT
+ MessageBox(NULL, L"InstallActiveXControl Step2", L"Information", MB_OK | MB_ICONINFORMATION);
+#endif
+
+ BOOL bInstallForAllUser = MakeInstallForAllUsers( hMSI );
+ BOOL bInstallFor64Bit = MakeInstallFor64Bit( hMSI );
+
+ char* pActiveXPath = NULL;
+ if ( GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath
+ && GetDelta( hMSI, nOldInstallMode, nInstallMode, nDeinstallMode ) )
+ {
+#ifdef OWN_DEBUG_PRINT
+ MessageBox(NULL, L"InstallActiveXControl Step3", L"Information", MB_OK | MB_ICONINFORMATION);
+#endif
+
+ if ( future_state == INSTALLSTATE_LOCAL
+ || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
+ {
+#ifdef OWN_DEBUG_PRINT
+ MessageBox(NULL, L"InstallActiveXControl, adjusting", L"Information", MB_OK | MB_ICONINFORMATION);
+ WarningMessageInt( L"nInstallMode = ", nInstallMode );
+#endif
+ // 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 )
+ {
+#ifdef OWN_DEBUG_PRINT
+ MessageBox(NULL, L"InstallActiveXControl, removing", L"Information", MB_OK | MB_ICONINFORMATION);
+#endif
+ if ( nOldInstallMode )
+ UnregisterActiveXNative( pActiveXPath, nOldInstallMode, bInstallForAllUser, bInstallFor64Bit );
+ }
+ }
+
+ if ( pActiveXPath )
+ free( pActiveXPath );
+ }
+ else
+ {
+ // assert( FALSE );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall DeinstallActiveXControl( MSIHANDLE hMSI )
+{
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+
+#ifdef OWN_DEBUG_PRINT
+ MessageBox(NULL, L"DeinstallActiveXControl", L"Information", MB_OK | MB_ICONINFORMATION);
+#endif
+
+ if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
+ {
+ char* pActiveXPath = NULL;
+ 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/regpatchactivex/exports.dxp b/setup_native/source/win32/customactions/regpatchactivex/exports.dxp
new file mode 100644
index 000000000000..c1d75133584b
--- /dev/null
+++ b/setup_native/source/win32/customactions/regpatchactivex/exports.dxp
@@ -0,0 +1 @@
+PatchActiveXControl
diff --git a/setup_native/source/win32/customactions/regpatchactivex/makefile.mk b/setup_native/source/win32/customactions/regpatchactivex/makefile.mk
new file mode 100644
index 000000000000..d79593abcc69
--- /dev/null
+++ b/setup_native/source/win32/customactions/regpatchactivex/makefile.mk
@@ -0,0 +1,93 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=regpatchactivex
+USE_DEFFILE=TRUE
+
+.IF "$(GUI)"=="WNT"
+
+# --- Settings -----------------------------------------------------
+
+# NO_DEFAULT_STL=TRUE
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE : settings.mk
+
+STDSHL=
+# SOLARINC!:=$(SOLARINC:s/stl//)
+
+# --- Files --------------------------------------------------------
+
+INCPRE+=.\Include
+.DIRCACHE=NO
+# CFLAGS+=-E
+
+SLOFILES = $(SLO)$/regpatchactivex.obj
+
+.IF "$(COM)"=="GCC"
+SHL1STDLIBS += -lstdc++
+.IF "$(MINGW_GCCLIB_EH)"=="YES"
+SHL1STDLIBS += -lgcc_eh
+.ENDIF
+SHL1STDLIBS += -lgcc -lmingw32 -lmoldname -lmsvcrt
+.ELSE
+SHL1STDLIBS=
+.ENDIF
+
+SHL1STDLIBS+= $(KERNEL32LIB)\
+ $(USER32LIB)\
+ $(ADVAPI32LIB)\
+ $(SHELL32LIB)\
+ $(MSILIB)
+.IF "$(COM)"!="GCC"
+SHL1STDLIBS+= libcmt.lib
+.ENDIF
+
+
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+#SHL1TARGET = $(TARGET)$(DLLPOSTFIX)
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
+
+.ENDIF
+
diff --git a/setup_native/source/win32/customactions/regpatchactivex/regpatchactivex.cxx b/setup_native/source/win32/customactions/regpatchactivex/regpatchactivex.cxx
new file mode 100644
index 000000000000..800fde54eab5
--- /dev/null
+++ b/setup_native/source/win32/customactions/regpatchactivex/regpatchactivex.cxx
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define UNICODE
+
+#ifdef _MSC_VER
+#pragma warning(push,1) // disable warnings within system headers
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string.h>
+#include <malloc.h>
+#include <stdio.h>
+
+//----------------------------------------------------------
+BOOL UnicodeEquals( wchar_t* pStr1, wchar_t* pStr2 )
+{
+ if ( pStr1 == NULL && pStr2 == NULL )
+ return TRUE;
+ else if ( pStr1 == NULL || pStr2 == NULL )
+ return FALSE;
+
+ while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
+ pStr1++, pStr2++;
+
+ return ( *pStr1 == 0 && *pStr2 == 0 );
+}
+
+//----------------------------------------------------------
+BOOL GetMsiProp( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
+{
+ DWORD sz = 0;
+ if ( MsiGetProperty( hMSI, pPropName, L"", &sz ) == ERROR_MORE_DATA )
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof( wchar_t );
+ wchar_t* buff = reinterpret_cast<wchar_t*>( malloc( nbytes ) );
+ ZeroMemory( buff, nbytes );
+ MsiGetProperty( hMSI, pPropName, buff, &sz );
+ *ppValue = buff;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//----------------------------------------------------------
+BOOL MakeInstallForAllUsers( MSIHANDLE hMSI )
+{
+ BOOL bResult = FALSE;
+ wchar_t* pVal = NULL;
+ if ( GetMsiProp( hMSI, L"ALLUSERS", &pVal ) && pVal )
+ {
+ bResult = UnicodeEquals( pVal , L"1" );
+ free( pVal );
+ }
+
+ return bResult;
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall PatchActiveXControl( MSIHANDLE hMSI )
+{
+ // MessageBox(NULL, L"PatchActiveXControl", L"Information", MB_OK | MB_ICONINFORMATION);
+
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+
+ if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
+ {
+ BOOL bInstallForAllUsers = MakeInstallForAllUsers( hMSI );
+
+ if ( future_state == INSTALLSTATE_LOCAL
+ || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
+ {
+ HKEY hkey = NULL;
+ char* aSubKey = "Software\\Classes\\MIME\\DataBase\\Content Type\\application/vnd.sun.xml.base";
+ if ( ERROR_SUCCESS == RegCreateKeyA(bInstallForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, &hkey) )
+ {
+ RegDeleteValueA( hkey, "CLSID" );
+ RegCloseKey( hkey ), hkey = NULL;
+ }
+ }
+ }
+ else
+ {
+ // assert( FALSE );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/relnotes/exports.dxp b/setup_native/source/win32/customactions/relnotes/exports.dxp
new file mode 100644
index 000000000000..55a454d3d58f
--- /dev/null
+++ b/setup_native/source/win32/customactions/relnotes/exports.dxp
@@ -0,0 +1,3 @@
+ShowReleaseNotesBefore
+ShowReleaseNotesAfter
+ShowSurveyAfter
diff --git a/setup_native/source/win32/customactions/relnotes/makefile.mk b/setup_native/source/win32/customactions/relnotes/makefile.mk
new file mode 100644
index 000000000000..4c29ead8bd6c
--- /dev/null
+++ b/setup_native/source/win32/customactions/relnotes/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=relnotes
+
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+CDEFS+=-DUNICODE
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CDEFS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+UWINAPILIB=
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+SLOFILES = $(SLO)$/relnotes.obj
+
+STDSHL+= \
+ $(ADVAPI32LIB)\
+ $(SHELL32LIB)\
+ $(MSILIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+STDSHL+=$(LIBSTLPORTST)
+.ENDIF
+
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
+
diff --git a/setup_native/source/win32/customactions/relnotes/relnotes.cxx b/setup_native/source/win32/customactions/relnotes/relnotes.cxx
new file mode 100644
index 000000000000..48aaf9b417bd
--- /dev/null
+++ b/setup_native/source/win32/customactions/relnotes/relnotes.cxx
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push,1) // disable warnings within system headers
+#pragma warning(disable: 4917)
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#include <shlobj.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <strsafe.h>
+#include <string>
+
+//----------------------------------------------------------
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+
+//----------------------------------------------------------
+inline bool IsValidHandle( HANDLE handle )
+{
+ return (NULL != handle) && (INVALID_HANDLE_VALUE != handle);
+}
+
+//----------------------------------------------------------
+static bool GetMsiProp(MSIHANDLE handle, LPCTSTR name, /*out*/std::wstring& value)
+{
+ DWORD sz = 0;
+ LPTSTR dummy = TEXT("");
+ if (MsiGetProperty(handle, name, dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof(TCHAR);
+ LPTSTR buff = reinterpret_cast<LPTSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetProperty(handle, name, buff, &sz);
+ value = buff;
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------
+//----------------------------------------------------------
+//----------------------------------------------------------
+UINT ShowReleaseNotes( TCHAR* pFileName, TCHAR* pFilePath )
+{
+ TCHAR sFullPath[ MAX_PATH ];
+
+ if ( FAILED( StringCchCopy( sFullPath, MAX_PATH, pFilePath ) ) )
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: ShowReleaseNotes: Could not copy path [%s]"), pFilePath );
+ return ERROR_SUCCESS;
+ }
+
+ if ( FAILED( StringCchCat( sFullPath, MAX_PATH, pFileName ) ) )
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: ShowReleaseNotes: Could not append filename [%s]"), pFileName );
+ return ERROR_SUCCESS;
+ }
+
+ HANDLE hFile = CreateFile( sFullPath, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if ( IsValidHandle(hFile) )
+ {
+ CloseHandle( hFile );
+ OutputDebugStringFormat( TEXT("DEBUG: ShowReleaseNotes: Found file [%s]"), sFullPath );
+
+ SHELLEXECUTEINFOW aExecInf;
+ ZeroMemory( &aExecInf, sizeof( aExecInf ) );
+
+ aExecInf.cbSize = sizeof( aExecInf );
+ aExecInf.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
+ aExecInf.lpVerb = TEXT("open");
+ aExecInf.lpFile = sFullPath;
+ aExecInf.lpDirectory = NULL;
+ aExecInf.nShow = SW_SHOWNORMAL;
+
+ SetLastError( 0 );
+ ShellExecuteEx( &aExecInf );
+ }
+ else
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: ShowReleaseNotes: File not found [%s]"), sFullPath );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall ShowReleaseNotesBefore( MSIHANDLE )
+{
+ TCHAR szPath[MAX_PATH];
+
+ if( FAILED( SHGetSpecialFolderPath( NULL, szPath, CSIDL_COMMON_DOCUMENTS, true ) ) )
+ return ERROR_SUCCESS;
+
+ OutputDebugString( TEXT("DEBUG: ShowReleaseNotesBefore called") );
+
+ return ShowReleaseNotes( TEXT("\\sun\\releasenote1.url"), szPath );
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall ShowReleaseNotesAfter( MSIHANDLE )
+{
+ TCHAR szPath[MAX_PATH];
+
+ if( FAILED( SHGetSpecialFolderPath( NULL, szPath, CSIDL_COMMON_DOCUMENTS, true ) ) )
+ return ERROR_SUCCESS;
+
+ OutputDebugString( TEXT("DEBUG: ShowReleaseNotesAfter called") );
+
+ return ShowReleaseNotes( TEXT("\\sun\\releasenote2.url"), szPath );
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall ShowSurveyAfter( MSIHANDLE handle )
+{
+ std::wstring prodname;
+
+ GetMsiProp( handle, TEXT("ProductName"), prodname );
+ std::wstring::size_type nIndex = prodname.find( TEXT( "OpenOffice.org" ) );
+ if( std::wstring::npos == nIndex )
+ return ERROR_SUCCESS;
+
+ OutputDebugString( TEXT("DEBUG: ShowSurveyAfter called") );
+
+ SHELLEXECUTEINFOW aExecInf;
+ ZeroMemory( &aExecInf, sizeof( aExecInf ) );
+
+ aExecInf.cbSize = sizeof( aExecInf );
+ aExecInf.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
+ aExecInf.lpVerb = TEXT("open");
+ aExecInf.lpFile = TEXT("http://surveys.libreoffice.org/deinstall");
+ aExecInf.lpDirectory = NULL;
+ aExecInf.nShow = SW_SHOWNORMAL;
+
+ SetLastError( 0 );
+ ShellExecuteEx( &aExecInf );
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/sellang/exports.dxp b/setup_native/source/win32/customactions/sellang/exports.dxp
new file mode 100644
index 000000000000..cc6dd8d32e47
--- /dev/null
+++ b/setup_native/source/win32/customactions/sellang/exports.dxp
@@ -0,0 +1 @@
+SelectLanguage
diff --git a/setup_native/source/win32/customactions/sellang/makefile.mk b/setup_native/source/win32/customactions/sellang/makefile.mk
new file mode 100644
index 000000000000..e2110ce708c9
--- /dev/null
+++ b/setup_native/source/win32/customactions/sellang/makefile.mk
@@ -0,0 +1,79 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 3.
+#
+#
+# GNU Lesser General Public License Version 3
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=sellangmsi
+
+.IF "$(GUI)"=="WNT"
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+
+# --- Files --------------------------------------------------------
+
+UWINAPILIB=
+
+SLOFILES = \
+ $(SLO)$/sellang.obj
+
+SHL1STDLIBS= kernel32.lib\
+ user32.lib\
+ advapi32.lib\
+ shell32.lib\
+ msi.lib\
+ $(LIBSTLPORTST)
+
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
+
+.ENDIF
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 000000000000..a031606d1823
--- /dev/null
+++ b/setup_native/source/win32/customactions/sellang/sellang.cxx
@@ -0,0 +1,351 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 3.
+ *
+ *
+ * GNU Lesser General Public License Version 3
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#define WIN32_LEAN_AND_MEAN
+#define _WIN32_WINNT 0x0500
+#undef WINVER
+#define WINVER 0x0500
+
+#pragma warning(push, 1) /* disable warnings within system headers as
+ * warnings are now treated as errors...
+ */
+#include <windows.h>
+#include <msiquery.h>
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <stdio.h>
+#pragma warning(pop)
+
+#include <sal/macros.h>
+#include <systools/win32/uwinapi.h>
+
+/* #define VERBOSE_DEBUG_OUTPUT 1 */
+
+static const char *
+langid_to_string( LANGID langid, int *have_default_lang )
+{
+ /* Map from LANGID to string. The languages below are in the same
+ * seemingly random order as in
+ * setup_native/source/win32/msi-encodinglist.txt.
+ * Only the language part is returned in the string.
+ */
+ switch (PRIMARYLANGID (langid)) {
+ case LANG_ENGLISH:
+ if (have_default_lang != NULL &&
+ langid == MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT))
+ *have_default_lang = 1;
+ return "en";
+#define CASE(primary, name) \
+ case LANG_##primary: return #name
+ CASE(PORTUGUESE, pt);
+ CASE(RUSSIAN, ru);
+ CASE(GREEK, el);
+ CASE(DUTCH, nl);
+ CASE(FRENCH, fr);
+ CASE(SPANISH, es);
+ CASE(FINNISH, fi);
+ CASE(HUNGARIAN, hu);
+ CASE(CATALAN, ca);
+ CASE(ITALIAN, it);
+ CASE(CZECH, cs);
+ CASE(SLOVAK, sk);
+ CASE(DANISH, da);
+ CASE(SWEDISH, sv);
+ CASE(POLISH, pl);
+ CASE(GERMAN, de);
+ CASE(THAI, th);
+ CASE(ESTONIAN, et);
+ CASE(JAPANESE, ja);
+ CASE(KOREAN, ko);
+ // CASE(KHMER, km);
+ // CASE(WELSH, cy);
+ CASE(CHINESE, zh);
+ CASE(TURKISH, tr);
+ CASE(HINDI, hi);
+ CASE(PUNJABI, pa);
+ CASE(TAMIL, ta);
+ CASE(ARABIC, ar);
+ CASE(HEBREW, he);
+ CASE(AFRIKAANS, af);
+ CASE(ALBANIAN, sq);
+ CASE(ARMENIAN, hy);
+ CASE(BASQUE, eu);
+ CASE(BELARUSIAN, be);
+ CASE(BENGALI, bn);
+ CASE(BULGARIAN, bg);
+ CASE(ICELANDIC, is);
+ CASE(INDONESIAN, id);
+ // CASE(LAO, lo);
+ CASE(LATVIAN, lv);
+ CASE(LITHUANIAN, lt);
+ // CASE(MALTESE, mt);
+ // CASE(ROMANSH, rm);
+ CASE(ROMANIAN, ro);
+ // CASE(KINYARWANDA, rw);
+ CASE(SANSKRIT, sa);
+ // CASE(SETSWANA, tn);
+ CASE(FARSI, fa);
+ CASE(FAEROESE, fo);
+ CASE(SLOVENIAN, sl);
+ // CASE(SORBIAN, sb);
+ // CASE(SUTU, st);
+ CASE(SWAHILI, sw);
+ CASE(TATAR, tt);
+ // CASE(TSONGA, ts);
+ CASE(UKRAINIAN, uk);
+ CASE(URDU, ur);
+ CASE(VIETNAMESE, vi);
+ // CASE(XHOSA, xh);
+ // CASE(YIDDISH, yi);
+ // CASE(ZULU, zu);
+ CASE(GUJARATI, gu);
+ // CASE(BRETON, br);
+ CASE(NEPALI, ne);
+ // CASE(NDEBELE, nr);
+ // CASE(SWAZI, ss);
+ // CASE(VENDA, ve);
+ // CASE(IRISH, ga);
+ CASE(MACEDONIAN, mk);
+ CASE(TELUGU, te);
+ CASE(MALAYALAM, ml);
+ CASE(MARATHI, mr);
+ CASE(ORIYA, or);
+ // CASE(KURDISH, ku);
+ // CASE(TAGALOG, tg);
+ // CASE(TIGRINYA, ti);
+ CASE(GALICIAN, gl);
+ CASE(KANNADA, kn);
+ CASE(MALAY, ms);
+ // CASE(TAJIK, tg);
+ CASE(GEORGIAN, ka);
+ // CASE(ESPERANTO, eo);
+#undef CASE
+ /* Special cases */
+ default:
+ switch (langid) {
+ case MAKELANGID(LANG_SERBIAN, 0x05): return "bs";
+#define CASE(primary, sub, name) \
+ case MAKELANGID(LANG_##primary, SUBLANG_##sub): return #name
+
+ CASE(NORWEGIAN, NORWEGIAN_BOKMAL, nb);
+ CASE(NORWEGIAN, NORWEGIAN_NYNORSK, nn);
+ CASE(SERBIAN, DEFAULT, hr);
+ CASE(SERBIAN, SERBIAN_LATIN, sh);
+ CASE(SERBIAN, SERBIAN_CYRILLIC, sr);
+ // CASE(SOTHO, DEFAULT, ns);
+ // CASE(SOTHO, SOTHO_SOUTHERN, st);
+#undef CASE
+ default: return "";
+ }
+ }
+}
+
+static const char *ui_langs[100];
+static int num_ui_langs = 0;
+
+BOOL CALLBACK
+enum_ui_lang_proc (LPTSTR language, LONG_PTR /* unused_lParam */)
+{
+ long langid = strtol(language, NULL, 16);
+ if (langid > 0xFFFF)
+ return TRUE;
+ ui_langs[num_ui_langs] = langid_to_string((LANGID) langid, NULL);
+ num_ui_langs++;
+ 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 (memcmp (ui_langs[i], lang, 2) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+extern "C" UINT __stdcall SelectLanguage( MSIHANDLE handle )
+{
+#ifdef VERBOSE_DEBUG_OUTPUT
+ char tem[2000];
+#endif
+ char feature[100];
+ MSIHANDLE database, view, record;
+ DWORD length;
+ int nlangs = 0;
+ /* Keeping this code simple and stupid... won't bother with any
+ * dynamic arrays or whatnot. 100 is more than enough for this purpose.
+ */
+ char langs[100][6];
+
+ database = MsiGetActiveDatabase(handle);
+
+ if (MsiDatabaseOpenViewA(database, "SELECT Feature from Feature WHERE Feature_Parent = 'gm_Langpack_Languageroot'", &view) != ERROR_SUCCESS) {
+ MsiCloseHandle(database);
+ return ERROR_SUCCESS;
+ }
+
+#ifdef VERBOSE_DEBUG_OUTPUT
+ MessageBoxA(NULL, "MsiDatabaseOpenViewA success!", "SelectLanguage", MB_OK);
+#endif
+
+ if (MsiViewExecute(view, NULL) != ERROR_SUCCESS) {
+ MsiCloseHandle(view);
+ MsiCloseHandle(database);
+ return ERROR_SUCCESS;
+ }
+
+#ifdef VERBOSE_DEBUG_OUTPUT
+ MessageBoxA(NULL, "MsiViewExecute success!", "SelectLanguage", MB_OK);
+#endif
+
+ while (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 languages are included in this installer, if
+ * it is a multilanguage one.
+ */
+ if (strcmp(feature, "gm_Langpack_r_en_US") != 0)
+ strcpy(langs[nlangs++], feature + strlen("gm_Langpack_r_"));
+
+ MsiCloseHandle(record);
+ }
+
+ MsiCloseHandle(view);
+
+ if (nlangs > 0) {
+ /* Deselect those languages that don't match any of the UI languages
+ * available on the system.
+ */
+
+ int i;
+ int have_system_default_lang = 0;
+ const char *system_default_lang = langid_to_string(GetSystemDefaultUILanguage(), &have_system_default_lang);
+ const char *user_locale_lang = langid_to_string(LANGIDFROMLCID(GetThreadLocale()), NULL);
+
+#ifdef VERBOSE_DEBUG_OUTPUT
+ sprintf(tem, "GetSystemDefaultUILanguage(): %#x = %s", GetSystemDefaultUILanguage(), system_default_lang);
+ MessageBoxA(NULL, tem, "SelectLanguage", MB_OK);
+#endif
+
+ EnumUILanguagesA(enum_ui_lang_proc, 0, 0);
+
+#ifdef VERBOSE_DEBUG_OUTPUT
+ sprintf(tem, "Have %d UI languages: ", num_ui_langs);
+ for (i = 0; i < num_ui_langs; i++) {
+ char *p = tem + strlen(tem);
+ sprintf(p, "%s%s",
+ ui_langs[i],
+ (i + 1 < num_ui_langs) ? ", " : "");
+ }
+ MessageBoxA(NULL, tem, "SelectLanguage", MB_OK);
+#endif
+
+ /* If one of the alternative languages in a multi-language installer
+ * is the system default UI language, deselect those languages that
+ * aren't among the UI languages available on the system.
+ * (On most Windows installations, just one UI language is present,
+ * which obviously is the same as the default UI language. But
+ * we want to be generic.)
+ * If none of the languages in a multi-language installer is the
+ * system default UI language (this happens now in 2.4.0 where we
+ * cannot put as many UI languages into the installer as we would
+ * like, but only half a dozen: en-US,de,es,fr,it,pt-BR), pretend
+ * that English is the system default UI language,
+ * so that we will by default deselect everything except
+ * English. We don't want to by default install all half dozen
+ * languages for an unsuspecting user of a Finnish Windows, for
+ * instance. Sigh.
+ */
+ if (system_default_lang[0]) {
+ for (i = 0; i < nlangs; i++) {
+ if (memcmp (system_default_lang, langs[i], 2) == 0) {
+#ifdef VERBOSE_DEBUG_OUTPUT
+ sprintf(tem, "We have the system default language %s in the installer", system_default_lang);
+ MessageBoxA(NULL, tem, "SelectLanguage", MB_OK);
+#endif
+ have_system_default_lang = 1;
+ }
+ }
+ }
+
+ if (!have_system_default_lang) {
+#ifdef VERBOSE_DEBUG_OUTPUT
+ sprintf(tem, "We don't have the system default language %s in the installer, so pretend that English is the system default, sigh.", system_default_lang);
+ MessageBoxA(NULL, tem, "SelectLanguage", MB_OK);
+#endif
+ system_default_lang = "en";
+ have_system_default_lang = 1;
+ }
+ if (have_system_default_lang) {
+ for (i = 0; i < nlangs; i++) {
+ if (memcmp(system_default_lang, langs[i], 2) != 0 &&
+ memcmp(user_locale_lang, langs[i], 2) != 0 &&
+ !present_in_ui_langs(langs[i])) {
+ UINT rc;
+ sprintf(feature, "gm_Langpack_r_%s", langs[i]);
+ rc = MsiSetFeatureStateA(handle, feature, INSTALLSTATE_ABSENT);
+ if (rc != ERROR_SUCCESS) {
+#ifdef VERBOSE_DEBUG_OUTPUT
+ sprintf(tem, "MsiSetFeatureStateA %s failed: %d", feature, rc);
+ MessageBoxA(NULL, tem, "SelectLanguage", MB_OK);
+#endif
+ } else {
+#ifdef VERBOSE_DEBUG_OUTPUT
+ sprintf(tem, "MsiSetFeatureStateA %s OK!", feature);
+ MessageBoxA(NULL, tem, "SelectLanguage", MB_OK);
+#endif
+ }
+ }
+ }
+ }
+ }
+
+ MsiCloseHandle(database);
+
+ 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 000000000000..58159cabd56f
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINNT 0x0401
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+static void UnsetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+}
+
+static void SetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty, const std::_tstring&)
+{
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+}
+
+extern "C" UINT __stdcall CheckInstallDirectory(MSIHANDLE handle)
+{
+ std::_tstring sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+ std::_tstring sOfficeHostnamePath = GetMsiProperty(handle, TEXT("OFFICEDIRHOSTNAME"));
+
+ // MessageBox(NULL, sInstallPath.c_str(), "DEBUG", MB_OK);
+
+ // unsetting all properties
+
+ UnsetMsiProperty( handle, TEXT("DIRECTORY_NOT_EMPTY") );
+
+ // 1. Searching for file setup.ini
+
+ std::_tstring sSetupIniPath = sInstallPath + sOfficeHostnamePath + TEXT("\\program\\setup.ini");
+
+ WIN32_FIND_DATA data;
+ HANDLE hdl = FindFirstFile(sSetupIniPath.c_str(), &data);
+
+ // std::_tstring mystr = "Searching for " + sSetupIniPath;
+ // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);
+
+ if ( IsValidHandle(hdl) )
+ {
+ // setup.ini found -> directory cannot be used for installation.
+ SetMsiProperty( handle, TEXT("DIRECTORY_NOT_EMPTY"), TEXT("1") );
+ SetMsiErrorCode( MSI_ERROR_DIRECTORY_NOT_EMPTY );
+ // std::_tstring notEmptyStr = "Directory is not empty. Please choose another installation directory.";
+ // std::_tstring notEmptyTitle = "Directory not empty";
+ // MessageBox(NULL, notEmptyStr.c_str(), notEmptyTitle.c_str(), MB_OK);
+ }
+
+ 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 000000000000..01ba1ab13b16
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINNT 0x0401
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+#include <strsafe.h>
+
+#include <systools/win32/uwinapi.h>
+
+//----------------------------------------------------------
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
+{
+ CHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugStringA( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCSTR, ... )
+{
+}
+#endif
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+static void SetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ MsiSetProperty( handle, sProperty.c_str(), TEXT("1") );
+}
+
+extern "C" UINT __stdcall CheckPatchList( MSIHANDLE handle )
+{
+ std::_tstring sPatchList = GetMsiProperty( handle, TEXT("PATCH") );
+ std::_tstring sRequiredPatch = GetMsiProperty( handle, TEXT("PREREQUIREDPATCH") );
+
+ OutputDebugStringFormat( "CheckPatchList called with PATCH=%s and PRQ= %s\n", sPatchList.c_str(), sRequiredPatch.c_str() );
+
+ if ( ( sPatchList.length() != 0 ) && ( sRequiredPatch.length() != 0 ) )
+ {
+ if ( _tcsstr( sPatchList.c_str(), sRequiredPatch.c_str() ) )
+ {
+ SetMsiProperty( handle, TEXT("IGNOREPREREQUIREDPATCH") );
+ OutputDebugStringFormat( "Set Property IgnorePrerequiredPatch!\n" );
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx b/setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx
new file mode 100644
index 000000000000..f50c795c5c8a
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx
@@ -0,0 +1,293 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+#include <sal/macros.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+#define WININIT_FILENAME "wininit.ini"
+#define RENAME_SECTION "rename"
+
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ _TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ _vsntprintf( buffer, SAL_N_ELEMENTS(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+static inline bool IsSetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ std::_tstring value = GetMsiProperty(handle, sProperty);
+ return (value.length() > 0);
+}
+
+static inline void UnsetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+}
+
+static inline void SetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+}
+
+static BOOL MoveFileEx9x( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
+{
+ BOOL fSuccess = FALSE; // assume failure
+
+ // Windows 9x has a special mechanism to move files after reboot
+
+ if ( dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT )
+ {
+ CHAR szExistingFileNameA[MAX_PATH];
+ CHAR szNewFileNameA[MAX_PATH] = "NUL";
+
+ // Path names in WININIT.INI must be in short path name form
+
+ if (
+ GetShortPathNameA( lpExistingFileNameA, szExistingFileNameA, MAX_PATH ) &&
+ (!lpNewFileNameA || GetShortPathNameA( lpNewFileNameA, szNewFileNameA, MAX_PATH ))
+ )
+ {
+ CHAR szBuffer[32767]; // The buffer size must not exceed 32K
+ DWORD dwBufLen = GetPrivateProfileSectionA( RENAME_SECTION, szBuffer, SAL_N_ELEMENTS(szBuffer), WININIT_FILENAME );
+
+ CHAR szRename[MAX_PATH]; // This is enough for at most to times 67 chracters
+ strcpy( szRename, szNewFileNameA );
+ strcat( szRename, "=" );
+ strcat( szRename, szExistingFileNameA );
+ size_t lnRename = strlen(szRename);
+
+ if ( dwBufLen + lnRename + 2 <= SAL_N_ELEMENTS(szBuffer) )
+ {
+ CopyMemory( &szBuffer[dwBufLen], szRename, lnRename );
+ szBuffer[dwBufLen + lnRename ] = 0;
+ szBuffer[dwBufLen + lnRename + 1 ] = 0;
+
+ fSuccess = WritePrivateProfileSectionA( RENAME_SECTION, szBuffer, WININIT_FILENAME );
+ }
+ else
+ SetLastError( ERROR_BUFFER_OVERFLOW );
+ }
+ }
+ else
+ {
+
+ fSuccess = MoveFileA( lpExistingFileNameA, lpNewFileNameA );
+
+ if ( !fSuccess && GetLastError() != ERROR_ACCESS_DENIED &&
+ 0 != (dwFlags & (MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) )
+ {
+ BOOL bFailIfExist = 0 == (dwFlags & MOVEFILE_REPLACE_EXISTING);
+
+ fSuccess = CopyFileA( lpExistingFileNameA, lpNewFileNameA, bFailIfExist );
+
+ if ( fSuccess )
+ fSuccess = DeleteFileA( lpExistingFileNameA );
+ }
+
+ }
+
+ return fSuccess;
+}
+
+static BOOL MoveFileExImpl( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
+{
+ if ( 0 > ((LONG)GetVersion())) // High order bit indicates Win 9x
+ return MoveFileEx9x( lpExistingFileNameA, lpNewFileNameA, dwFlags );
+ else
+ return MoveFileExA( lpExistingFileNameA, lpNewFileNameA, dwFlags );
+}
+
+extern "C" UINT __stdcall IsOfficeRunning( MSIHANDLE handle )
+{
+ OSVERSIONINFO osverinfo;
+ osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx( &osverinfo );
+
+ // renaming the vcl resource doesn't work reliable with OS >= Windows Vista
+ if (osverinfo.dwMajorVersion < 6 )
+ {
+ std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ // Property empty -> no office installed
+ if ( sInstDir.length() == 0 )
+ return ERROR_SUCCESS;
+
+ std::_tstring sResourceDir = sInstDir + TEXT("Basis\\program\\resource\\");
+ std::_tstring sPattern = sResourceDir + TEXT("vcl*.res");
+
+// std::_tstring mystr;
+// mystr = "IsOfficeRunning start. Checking file in dir: " + sResourceDir;
+// MessageBox( NULL, mystr.c_str(), "IsOfficeRunning", MB_OK );
+
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ BOOL fSuccess = false;
+ bool fRenameSucceeded;
+
+ do
+ {
+ std::_tstring sResourceFile = sResourceDir + aFindFileData.cFileName;
+ std::_tstring sIntermediate = sResourceFile + TEXT(".tmp");
+
+ fRenameSucceeded = MoveFileExImpl( sResourceFile.c_str(), sIntermediate.c_str(), MOVEFILE_REPLACE_EXISTING );
+ if ( fRenameSucceeded )
+ {
+ MoveFileExImpl( sIntermediate.c_str(), sResourceFile.c_str(), 0 );
+ fSuccess = FindNextFile( hFind, &aFindFileData );
+ }
+ } while ( fSuccess && fRenameSucceeded );
+
+ if ( !fRenameSucceeded )
+ {
+ MsiSetProperty(handle, TEXT("OFFICERUNS"), TEXT("1"));
+ SetMsiErrorCode( MSI_ERROR_OFFICE_IS_RUNNING );
+
+// mystr = "Office is running";
+// MessageBox( NULL, mystr.c_str(), "IsOfficeRunning", MB_OK );
+ }
+
+ FindClose( hFind );
+ }
+// mystr = "IsOfficeRunning end";
+// MessageBox( NULL, mystr.c_str(), "IsOfficeRunning", MB_OK );
+ }
+ else
+ {
+ std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+ // Property empty -> no office installed
+ if ( sOfficeInstallPath.length() == 0 )
+ return ERROR_SUCCESS;
+
+ std::_tstring sRenameSrc = sOfficeInstallPath + TEXT("program");
+ std::_tstring sRenameDst = sOfficeInstallPath + TEXT("program_test");
+
+ bool bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
+
+ if ( bSuccess )
+ {
+ MoveFile( sRenameDst.c_str(), sRenameSrc.c_str() );
+ }
+ else
+ {
+ DWORD dwError = GetLastError();
+ LPVOID lpMsgBuf;
+ // When there is no program folder, there could be no running office
+ if ( dwError == ERROR_FILE_NOT_FOUND )
+ return ERROR_SUCCESS;
+ if ( dwError == ERROR_PATH_NOT_FOUND )
+ return ERROR_SUCCESS;
+
+ // The destination folder should never exist, don't know what to do here
+ if ( dwError == ERROR_ALREADY_EXISTS )
+ return ERROR_SUCCESS;
+
+ if ( FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL ))
+ {
+ OutputDebugStringFormat( TEXT("Error Code %d: %s"), dwError, lpMsgBuf );
+ LocalFree( lpMsgBuf );
+ }
+ else
+ OutputDebugStringFormat( TEXT("Error Code %d: Unknown"), dwError );
+
+ MsiSetProperty( handle, TEXT("OFFICERUNS"), TEXT("1") );
+ SetMsiErrorCode( MSI_ERROR_OFFICE_IS_RUNNING );
+ }
+ }
+
+ 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 000000000000..7b7453a1f70e
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/completeinstallpath.cxx
@@ -0,0 +1,183 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+using namespace std;
+
+namespace
+{
+ std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+ {
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+ }
+} // namespace
+
+extern "C" 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".
+
+ TCHAR szValue[8192];
+ DWORD nValueSize = sizeof(szValue);
+ HKEY hKey;
+ std::_tstring sInstDir;
+ std::_tstring mystr;
+
+ // Reading property OFFICEDIRHOSTNAME_, that contains the part of the path behind
+ // the program files folder.
+
+ std::_tstring sInstallLocation = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ std::_tstring sOfficeDirHostname = GetMsiProperty( handle, TEXT("OFFICEDIRHOSTNAME_") );
+
+ // If sInstallLocation ends with (contains) the string sOfficeDirHostname,
+ // INSTALLLOCATION is good and nothing has to be done here.
+
+ bool pathCompletionRequired = true;
+
+ if ( _tcsstr( sInstallLocation.c_str(), sOfficeDirHostname.c_str() ) )
+ {
+ pathCompletionRequired = false; // nothing to do
+ // mystr = "Nothing to do, officedir is included into installlocation";
+ // MessageBox( NULL, mystr.c_str(), "It is part of installlocation", MB_OK );
+ }
+
+ // If the path INSTALLLOCATION does not end with this string, INSTALLLOCATION is maybe
+ // transfered from an OOo 3.0, OOo 3.1 and OOo 3.2 and need to be changed therefore.
+
+ if ( pathCompletionRequired )
+ {
+ std::_tstring sManufacturer = GetMsiProperty( handle, TEXT("Manufacturer") );
+ std::_tstring sDefinedName = GetMsiProperty( handle, TEXT("DEFINEDPRODUCT") );
+ std::_tstring sUpgradeCode = GetMsiProperty( handle, TEXT("UpgradeCode") );
+
+ // sUpdateVersion can be "3.0", "3.1" or "3.2"
+
+ std::_tstring sProductKey30 = "Software\\" + sManufacturer + "\\" + sDefinedName +
+ "\\" + "3.0" + "\\" + sUpgradeCode;
+
+ std::_tstring sProductKey31 = "Software\\" + sManufacturer + "\\" + sDefinedName +
+ "\\" + "3.1" + "\\" + sUpgradeCode;
+
+ std::_tstring sProductKey32 = "Software\\" + sManufacturer + "\\" + sDefinedName +
+ "\\" + "3.2" + "\\" + sUpgradeCode;
+
+ // mystr = "ProductKey: " + sProductKey;
+ // MessageBox( NULL, mystr.c_str(), "ProductKey", MB_OK );
+
+ // mystr = "Checking registry";
+ // MessageBox( NULL, mystr.c_str(), "registry search", MB_OK );
+
+ bool oldVersionExists = false;
+
+ if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey30.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey31.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey32.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey30.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey31.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey32.c_str(), &hKey ) )
+ {
+ oldVersionExists = true;
+ RegCloseKey( hKey );
+ }
+
+ if ( oldVersionExists )
+ {
+ // Adding the new path content sOfficeDirHostname
+ sInstallLocation = sInstallLocation + sOfficeDirHostname;
+ // Setting the new property value
+ MsiSetProperty(handle, TEXT("INSTALLLOCATION"), sInstallLocation.c_str());
+ // mystr = "Setting path to: " + sInstallLocation;
+ // MessageBox( NULL, mystr.c_str(), "sInstallLocation", MB_OK );
+ }
+ }
+
+ // mystr = "Ending with INSTALLLOCATION: " + sInstallLocation;
+ // MessageBox( NULL, mystr.c_str(), "END", MB_OK );
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx b/setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx
new file mode 100644
index 000000000000..c816a71a3de1
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <new>
+#include <string.h> // <cstring> not supported by old MSC versions
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include "boost/scoped_array.hpp"
+
+#define LCL_LENGTH0(s) (sizeof (s) / sizeof *(s))
+#define LCL_STRING0(s) (s), LCL_LENGTH0(s)
+
+namespace {
+
+enum Status { STATUS_NO, STATUS_YES, STATUS_ERROR };
+
+Status fileExists(wchar_t const * path) {
+ return GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES
+ ? GetLastError() == ERROR_FILE_NOT_FOUND ? STATUS_NO : STATUS_ERROR
+ : STATUS_YES;
+}
+
+wchar_t * getProperty(
+ MSIHANDLE install, wchar_t const * name, wchar_t const * suffix,
+ std::size_t suffixLength, wchar_t ** end = NULL)
+{
+ DWORD n = 0;
+ UINT err = MsiGetPropertyW(install, name, L"", &n);
+ if (err != ERROR_SUCCESS && err != ERROR_MORE_DATA) {
+ return NULL;
+ }
+ DWORD n2 = n + suffixLength; //TODO: overflow
+ wchar_t * data = new(std::nothrow) wchar_t[n2];
+ if (data == NULL) {
+ return NULL;
+ }
+ if (MsiGetPropertyW(install, name, data, &n2) != ERROR_SUCCESS || n2 != n) {
+ delete[] data;
+ return NULL;
+ }
+ memcpy(data + n, suffix, suffixLength * sizeof (wchar_t)); //TODO: overflow
+ if (end != NULL) {
+ *end = data + n + suffixLength;
+ }
+ return data;
+}
+
+}
+
+extern "C" UINT __stdcall copyEditionData(MSIHANDLE install) {
+ boost::scoped_array<wchar_t> from(
+ getProperty(install, L"SourceDir", LCL_STRING0(L"edition\0")));
+ if (!from) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ Status stat = fileExists(from.get());
+ if (stat == STATUS_ERROR) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ if (stat == STATUS_NO) {
+ return ERROR_SUCCESS;
+ }
+ wchar_t * end;
+ boost::scoped_array<wchar_t> to(
+ getProperty(
+ install, L"INSTALLLOCATION",
+ LCL_STRING0(L"program\\edition\0"), &end));
+ if (!to) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ stat = fileExists(to.get());
+ if (stat == STATUS_ERROR) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ if (stat == STATUS_YES) {
+ SHFILEOPSTRUCTW opDelete = {
+ NULL, FO_DELETE, to.get(), NULL, FOF_NOCONFIRMATION | FOF_SILENT,
+ FALSE, NULL, NULL }; //TODO: non-NULL hwnd
+ if (SHFileOperationW(&opDelete) != 0) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ }
+ *(end - LCL_LENGTH0(L"\\edition\0")) = L'\0';
+ *(end - LCL_LENGTH0(L"\\edition\0") + 1) = L'\0';
+ SHFILEOPSTRUCTW opCopy = {
+ NULL, FO_COPY, from.get(), to.get(),
+ FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SILENT, FALSE, NULL,
+ NULL }; //TODO: non-NULL hwnd
+ if (SHFileOperationW(&opCopy) != 0) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx b/setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx
new file mode 100644
index 000000000000..d94b65459d8a
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#include <shellapi.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+#include <string.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+extern "C" UINT __stdcall copyExtensionData(MSIHANDLE handle) {
+
+ std::_tstring sSourceDir = GetMsiProperty( handle, TEXT("SourceDir") );
+ std::_tstring sExtensionDir = sSourceDir + TEXT("extension\\");
+ std::_tstring sPattern = sExtensionDir + TEXT("*.oxt");
+ // std::_tstring mystr;
+
+ // Finding all oxt files in sExtensionDir
+
+ WIN32_FIND_DATA aFindFileData;
+
+ HANDLE hFindOxt = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( hFindOxt != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+ bool fSuccess = true;
+ bool bFailIfExist = true;
+
+ std::_tstring sDestDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ std::_tstring sShareInstallDir = sDestDir + TEXT("share\\extension\\install\\");
+
+ // creating directories
+ std::_tstring sShareDir = sDestDir + TEXT("share");
+ std::_tstring sExtDir = sShareDir + TEXT("\\extension");
+ std::_tstring sExtInstDir = sExtDir + TEXT("\\install");
+ bool bDir = CreateDirectory(sShareDir.c_str(), NULL);
+ bDir = CreateDirectory(sExtDir.c_str(), NULL);
+ bDir = CreateDirectory(sExtInstDir.c_str(), NULL);
+
+ do
+ {
+ std::_tstring sOxtFile = aFindFileData.cFileName;
+
+ std::_tstring sSourceFile = sExtensionDir + sOxtFile;
+ std::_tstring sDestFile = sShareInstallDir + sOxtFile;
+
+ fSuccess = CopyFile( sSourceFile.c_str(), sDestFile.c_str(), bFailIfExist );
+
+ fNextFile = FindNextFile( hFindOxt, &aFindFileData );
+
+ } while ( fNextFile );
+
+ FindClose( hFindOxt );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx b/setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx
new file mode 100644
index 000000000000..ffd6ef1a87dd
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#include <tchar.h>
+#include <string>
+#include <systools/win32/uwinapi.h>
+
+#include <../tools/seterror.hxx>
+
+using namespace std;
+
+namespace
+{
+ string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ string result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+ return result;
+ }
+
+ inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string& sValue)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), sValue.c_str());
+ }
+
+ void stripFinalBackslash(std::string * path) {
+ std::string::size_type i = path->size();
+ if (i > 1) {
+ --i;
+ if ((*path)[i] == '\\') {
+ path->erase(i);
+ }
+ }
+ }
+
+// Copied more or less verbatim from
+// desktop/source/deployment/inc/dp_version.hxx:1.5 and
+// desktop/source/deployment/misc/dp_version.cxx:1.5:
+
+enum Order { ORDER_LESS, ORDER_EQUAL, ORDER_GREATER };
+
+string getElement(string const & version, string::size_type * index) {
+ while (*index < version.size() && version[*index] == '0') {
+ ++*index;
+ }
+ string::size_type i = *index;
+ *index = version.find('.', i);
+ if (*index == string::npos) {
+ *index = version.size();
+ return string(version, i);
+ } else {
+ ++*index;
+ return string(version, i, *index - 1 - i);
+ }
+}
+
+Order compareVersions(string const & version1, string const & version2) {
+ for (string::size_type i1 = 0, i2 = 0;
+ i1 < version1.size() || i2 < version2.size();)
+ {
+ string e1(getElement(version1, &i1));
+ string e2(getElement(version2, &i2));
+
+ // string myText1 = TEXT("e1: ") + e1;
+ // string myText2 = TEXT("e2: ") + e2;
+ // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
+ // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
+
+ if (e1.size() < e2.size()) {
+ return ORDER_LESS;
+ } else if (e1.size() > e2.size()) {
+ return ORDER_GREATER;
+ } else if (e1 < e2) {
+ return ORDER_LESS;
+ } else if (e1 > e2) {
+ return ORDER_GREATER;
+ }
+ }
+ return ORDER_EQUAL;
+}
+
+} // namespace
+
+extern "C" UINT __stdcall DotNetCheck(MSIHANDLE handle) {
+ string present(GetMsiProperty(handle, TEXT("MsiNetAssemblySupport")));
+ string required(GetMsiProperty(handle, TEXT("REQUIRED_DOTNET_VERSION")));
+
+ // string myText1 = TEXT("MsiNetAssemblySupport: ") + present;
+ // string myText2 = TEXT("REQUIRED_DOTNET_VERSION: ") + required;
+ // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
+ // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
+
+ SetMsiProperty(
+ handle, TEXT("DOTNET_SUFFICIENT"),
+ (present.empty() || compareVersions(present, required) == ORDER_LESS ?
+ TEXT("0") : TEXT("1")));
+
+ // string result(GetMsiProperty(handle, TEXT("DOTNET_SUFFICIENT")));
+ // string myText3 = TEXT("DOTNET_SUFFICIENT: ") + result;
+ // MessageBox(NULL, myText3.c_str(), "DEBUG", MB_OK);
+
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall ShowProperties(MSIHANDLE handle)
+{
+ string property = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+ string myText = TEXT("INSTALLLOCATION: ") + property;
+ MessageBox(NULL, myText.c_str(), "INSTALLLOCATION", MB_OK);
+
+ property = GetMsiProperty(handle, TEXT("Installed"));
+ myText = TEXT("Installed: ") + property;
+ MessageBox(NULL, myText.c_str(), "Installed", MB_OK);
+
+ property = GetMsiProperty(handle, TEXT("PATCH"));
+ myText = TEXT("PATCH: ") + property;
+ MessageBox(NULL, myText.c_str(), "PATCH", MB_OK);
+
+ property = GetMsiProperty(handle, TEXT("REMOVE"));
+ myText = TEXT("REMOVE: ") + property;
+ MessageBox(NULL, myText.c_str(), "REMOVE", MB_OK);
+
+ property = GetMsiProperty(handle, TEXT("ALLUSERS"));
+ myText = TEXT("ALLUSERS: ") + property;
+ MessageBox(NULL, myText.c_str(), "ALLUSERS", MB_OK);
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/exports.dxp b/setup_native/source/win32/customactions/shellextensions/exports.dxp
new file mode 100644
index 000000000000..5826d339274a
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/exports.dxp
@@ -0,0 +1,23 @@
+InstallExecSequenceEntry
+DeinstallExecSequenceEntry
+InstallStartmenuFolderIcon
+DeinstallStartmenuFolderIcon
+SetProductInstallMode
+RebuildShellIconCache
+ExecutePostUninstallScript
+CompleteInstallPath
+MigrateInstallPath
+RegisterExtensions
+RemoveExtensions
+CheckInstallDirectory
+SetAdminInstallProperty
+CreateLayerLinks
+RemoveLayerLinks
+DotNetCheck
+ShowProperties
+copyEditionData
+RenamePrgFolder
+RemovePrgFolder
+IsOfficeRunning
+CheckPatchList
+copyExtensionData
diff --git a/setup_native/source/win32/customactions/shellextensions/iconcache.cxx b/setup_native/source/win32/customactions/shellextensions/iconcache.cxx
new file mode 100644
index 000000000000..daba7fb8c7d7
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/iconcache.cxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <stdlib.h>
+
+extern "C" UINT __stdcall RebuildShellIconCache(MSIHANDLE)
+{
+ // Rebuild icon cache on windows OS prior XP
+
+ OSVERSIONINFO osverinfo;
+
+ osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ if (
+ GetVersionEx( &osverinfo ) &&
+ VER_PLATFORM_WIN32_NT == osverinfo.dwPlatformId &&
+ (
+ 5 < osverinfo.dwMajorVersion ||
+ 5 == osverinfo.dwMajorVersion && 0 < osverinfo.dwMinorVersion
+ )
+ )
+ {
+ return ERROR_SUCCESS;
+ }
+
+ HKEY hKey;
+ DWORD dwDispostion;
+ LONG lError = RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, NULL, REG_OPTION_VOLATILE, KEY_SET_VALUE | KEY_QUERY_VALUE, NULL, &hKey, &dwDispostion );
+
+ if ( ERROR_SUCCESS == lError )
+ {
+ TCHAR szValue[256];
+ TCHAR szTempValue[256];
+ DWORD cbValue = sizeof(szValue);
+ DWORD dwType;
+ int iSize = 0;
+
+ lError = RegQueryValueEx( hKey, TEXT("Shell Icon Size"), 0, &dwType, (LPBYTE)szValue, &cbValue );
+
+ if ( ERROR_SUCCESS == lError )
+ iSize = atoi( szValue );
+
+ if ( !iSize )
+ {
+ iSize = GetSystemMetrics( SM_CXICON );
+ itoa( iSize, szValue, 10 );
+ cbValue = strlen( szValue ) + 1;
+ dwType = REG_SZ;
+ }
+
+ itoa( iSize + 1, szTempValue, 10 );
+ lError = RegSetValueEx( hKey, TEXT("Shell Icon Size"), 0, dwType, (LPBYTE)szTempValue, strlen( szTempValue ) + 1 );
+
+ LRESULT lResult = SendMessageTimeout(
+ HWND_BROADCAST,
+ WM_SETTINGCHANGE,
+ SPI_SETNONCLIENTMETRICS,
+ (LPARAM)TEXT("WindowMetrics"),
+ SMTO_NORMAL|SMTO_ABORTIFHUNG,
+ 0, NULL);
+
+ lError = RegSetValueEx( hKey, TEXT("Shell Icon Size"), 0, dwType, (LPBYTE)szValue, cbValue );
+
+ lResult = SendMessageTimeout(
+ HWND_BROADCAST,
+ WM_SETTINGCHANGE,
+ SPI_SETNONCLIENTMETRICS,
+ (LPARAM)TEXT("WindowMetrics"),
+ SMTO_NORMAL|SMTO_ABORTIFHUNG,
+ 0, NULL);
+
+ lError = RegCloseKey( hKey );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/layerlinks.cxx b/setup_native/source/win32/customactions/shellextensions/layerlinks.cxx
new file mode 100644
index 000000000000..11c9757ff921
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/layerlinks.cxx
@@ -0,0 +1,260 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#include <tchar.h>
+#include <string>
+#include <systools/win32/uwinapi.h>
+
+#include <../tools/seterror.hxx>
+
+using namespace std;
+
+namespace
+{
+ string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ string result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+ return result;
+ }
+
+ inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ return (GetMsiProperty(handle, sProperty).length() > 0);
+ }
+
+ inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+ }
+
+ inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string&)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+ }
+
+ void stripFinalBackslash(std::string * path) {
+ std::string::size_type i = path->size();
+ if (i > 1) {
+ --i;
+ if ((*path)[i] == '\\') {
+ path->erase(i);
+ }
+ }
+ }
+} // namespace
+
+extern "C" UINT __stdcall CreateLayerLinks(MSIHANDLE handle)
+{
+ string sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+
+ string sOfficeInstallPath = sInstallPath;
+ string sBasisInstallPath = sInstallPath + TEXT("Basis\\");
+ string sUreInstallPath = sInstallPath + TEXT("URE\\");
+
+ string sBasisLinkPath = sInstallPath + TEXT("basis-link");
+ string sUreLinkPath = sInstallPath + TEXT("Basis\\ure-link");
+
+ if ( IsSetMsiProperty(handle, TEXT("ADMININSTALL")) )
+ {
+ sBasisInstallPath = TEXT("Basis");
+ sUreInstallPath = TEXT("..\\URE");
+ }
+
+ stripFinalBackslash(&sBasisInstallPath);
+ stripFinalBackslash(&sUreInstallPath);
+
+ // string myText1 = TEXT("Creating Basis-Link: ") + sBasisLinkPath;
+ // string myText2 = TEXT("Creating Ure-Link: ") + sUreLinkPath;
+ // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
+ // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
+
+ // creating basis-link in brand layer
+
+ HANDLE h1file = CreateFile(
+ sBasisLinkPath.c_str(),
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (IsValidHandle(h1file))
+ {
+ DWORD dummy;
+
+ // Converting string into UTF-8 encoding and writing into file "basis-link"
+
+ int nCharsRequired = MultiByteToWideChar( CP_ACP, 0, sBasisInstallPath.c_str(), -1, NULL, 0 );
+ if ( nCharsRequired )
+ {
+ LPWSTR lpPathW = new WCHAR[nCharsRequired];
+ if ( MultiByteToWideChar( CP_ACP, 0, sBasisInstallPath.c_str(), -1, lpPathW, nCharsRequired ) )
+ {
+ nCharsRequired = WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, NULL, 0, NULL, NULL );
+ if ( nCharsRequired )
+ {
+ LPSTR lpPathUTF8 = new CHAR[nCharsRequired];
+ WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, lpPathUTF8, nCharsRequired, NULL, NULL );
+
+ // WriteFile( h1file, sBasisInstallPath.c_str(), sBasisInstallPath.size() ,&dummy, 0 );
+ WriteFile( h1file, lpPathUTF8, strlen(lpPathUTF8) ,&dummy, 0 );
+
+ delete lpPathUTF8;
+ }
+ }
+
+ delete lpPathW;
+ }
+
+ CloseHandle(h1file);
+ }
+
+ // creating ure-link in basis layer
+
+ HANDLE h2file = CreateFile(
+ sUreLinkPath.c_str(),
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (IsValidHandle(h2file))
+ {
+ DWORD dummy;
+
+ // Converting string into UTF-8 encoding and writing into file "basis-link"
+
+ int nCharsRequired = MultiByteToWideChar( CP_ACP, 0, sUreInstallPath.c_str(), -1, NULL, 0 );
+ if ( nCharsRequired )
+ {
+ LPWSTR lpPathW = new WCHAR[nCharsRequired];
+ if ( MultiByteToWideChar( CP_ACP, 0, sUreInstallPath.c_str(), -1, lpPathW, nCharsRequired ) )
+ {
+ nCharsRequired = WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, NULL, 0, NULL, NULL );
+ if ( nCharsRequired )
+ {
+ LPSTR lpPathUTF8 = new CHAR[nCharsRequired];
+ WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, lpPathUTF8, nCharsRequired, NULL, NULL );
+
+ // WriteFile( h2file, sUreInstallPath.c_str(), sUreInstallPath.size() ,&dummy, 0 );
+ WriteFile( h2file, lpPathUTF8, strlen(lpPathUTF8) ,&dummy, 0 );
+
+ delete lpPathUTF8;
+ }
+ }
+
+ delete lpPathW;
+ }
+
+ CloseHandle(h2file);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall RemoveLayerLinks(MSIHANDLE handle)
+{
+ string sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+
+ string sOfficeInstallPath = sInstallPath;
+ string sBasisInstallPath = sInstallPath + TEXT("Basis\\");
+ string sUreInstallPath = sInstallPath + TEXT("URE\\");
+
+ string sBasisLinkPath = sOfficeInstallPath + TEXT("basis-link");
+ string sUreLinkPath = sBasisInstallPath + TEXT("ure-link");
+ string sUreDirName = sUreInstallPath + TEXT("bin");
+
+ // string myText2 = TEXT("Deleting Ure-Link: ") + sUreLinkPath;
+ // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
+
+ // Deleting link to basis layer
+ // string myText1 = TEXT("Deleting Basis-Link: ") + sBasisLinkPath;
+ // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
+ DeleteFile(sBasisLinkPath.c_str());
+
+ // Check, if URE is still installed
+ bool ureDirExists = true;
+ WIN32_FIND_DATA aFindData;
+ HANDLE hFindContent = FindFirstFile( sUreDirName.c_str(), &aFindData );
+ if ( hFindContent == INVALID_HANDLE_VALUE ) { ureDirExists = false; }
+ FindClose( hFindContent );
+
+ // if ( ureDirExists )
+ // {
+ // string myText3 = TEXT("URE directory still exists: ") + sUreDirName;
+ // MessageBox(NULL, myText3.c_str(), "DEBUG", MB_OK);
+ // string myText4 = TEXT("URE link NOT removed: ") + sUreLinkPath;
+ // MessageBox(NULL, myText4.c_str(), "DEBUG", MB_OK);
+ // }
+
+ // Deleting link to URE layer, if URE dir no longer exists
+ if ( ! ureDirExists )
+ {
+ // string myText5 = TEXT("URE directory does not exist: ") + sUreDirName;
+ // MessageBox(NULL, myText5.c_str(), "DEBUG", MB_OK);
+ DeleteFile(sUreLinkPath.c_str());
+ // string myText6 = TEXT("URE link removed: ") + sUreLinkPath;
+ // MessageBox(NULL, myText6.c_str(), "DEBUG", MB_OK);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/makefile.mk b/setup_native/source/win32/customactions/shellextensions/makefile.mk
new file mode 100644
index 000000000000..23fe24bb6ceb
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/makefile.mk
@@ -0,0 +1,108 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=shlxtmsi
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+#Disable precompiled header
+CDEFS+=-Dnot_used_define_to_disable_pch
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = \
+ $(SLO)$/shellextensions.obj \
+ $(SLO)$/startmenuicon.obj \
+ $(SLO)$/upgrade.obj \
+ $(SLO)$/iconcache.obj \
+ $(SLO)$/postuninstall.obj \
+ $(SLO)$/migrateinstallpath.obj \
+ $(SLO)$/completeinstallpath.obj \
+ $(SLO)$/checkdirectory.obj \
+ $(SLO)$/setadmininstall.obj \
+ $(SLO)$/layerlinks.obj \
+ $(SLO)$/dotnetcheck.obj \
+ $(SLO)$/registerextensions.obj \
+ $(SLO)$/copyeditiondata.obj \
+ $(SLO)$/vistaspecial.obj \
+ $(SLO)$/checkrunningoffice.obj \
+ $(SLO)$/checkpatches.obj \
+ $(SLO)$/copyextensiondata.obj
+
+STDSHL += \
+ $(ADVAPI32LIB)\
+ $(MSILIB)\
+ $(SHELL32LIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+STDSHL += $(LIBSTLPORTST)
+.ENDIF
+
+.IF "$(COM)"=="GCC"
+STDSHL+= \
+ $(KERNEL32LIB)\
+ -lmsvcrt
+.ENDIF
+
+SHL1OBJS = $(SLOFILES) \
+ $(SLO)$/seterror.obj
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
+
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 000000000000..a487309c53f2
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+using namespace std;
+
+namespace
+{
+ std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+ {
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+ }
+} // namespace
+
+extern "C" UINT __stdcall MigrateInstallPath( MSIHANDLE handle )
+{
+ TCHAR szValue[8192];
+ DWORD nValueSize = sizeof(szValue);
+ HKEY hKey;
+ std::_tstring sInstDir;
+
+ std::_tstring sManufacturer = GetMsiProperty( handle, TEXT("Manufacturer") );
+ std::_tstring sDefinedName = GetMsiProperty( handle, TEXT("DEFINEDPRODUCT") );
+ std::_tstring sUpdateVersion = GetMsiProperty( handle, TEXT("DEFINEDVERSION") );
+ std::_tstring sUpgradeCode = GetMsiProperty( handle, TEXT("UpgradeCode") );
+
+ std::_tstring sProductKey = "Software\\" + sManufacturer + "\\" + sDefinedName +
+ "\\" + sUpdateVersion + "\\" + sUpgradeCode;
+
+ std::_tstring mystr;
+ mystr = "ProductKey: " + sProductKey;
+ // MessageBox( NULL, mystr.c_str(), "ProductKey", MB_OK );
+
+ if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ MsiSetProperty(handle, TEXT("INSTALLLOCATION"), sInstDir.c_str());
+ // MessageBox( NULL, sInstDir.c_str(), "Found in HKEY_CURRENT_USER", MB_OK );
+ }
+
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ MsiSetProperty(handle, TEXT("INSTALLLOCATION"), sInstDir.c_str());
+ // MessageBox( NULL, sInstDir.c_str(), "Found in HKEY_LOCAL_MACHINE", MB_OK );
+ }
+
+ RegCloseKey( hKey );
+ }
+
+ return ERROR_SUCCESS;
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/postuninstall.cxx b/setup_native/source/win32/customactions/shellextensions/postuninstall.cxx
new file mode 100644
index 000000000000..d4ac16aec8a3
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/postuninstall.cxx
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+#include <io.h>
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+
+static BOOL ExecuteCommand( LPCTSTR lpCommand, BOOL bSync )
+{
+ BOOL fSuccess = FALSE;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+
+ fSuccess = CreateProcess(
+ NULL,
+ (LPTSTR)lpCommand,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ NULL,
+ NULL,
+ &si,
+ &pi
+ );
+
+ if ( fSuccess )
+ {
+ if ( bSync )
+ WaitForSingleObject( pi.hProcess, INFINITE );
+
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ }
+
+ return fSuccess;
+}
+
+extern "C" UINT __stdcall ExecutePostUninstallScript( MSIHANDLE handle )
+{
+ TCHAR szValue[8192];
+ DWORD nValueSize = sizeof(szValue);
+ HKEY hKey;
+ std::_tstring sInstDir;
+
+ std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
+
+ // MessageBox( NULL, sProductKey.c_str(), "Titel", MB_OK );
+
+ if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else
+ return ERROR_SUCCESS;
+
+ std::_tstring sInfFile = sInstDir + TEXT("program\\postuninstall.inf");
+ std::_tstring sCommand = _T("RUNDLL32.EXE ");
+
+ // MessageBox( NULL, sInfFile.c_str(), "Titel", MB_OK );
+
+ if ( (LONG)GetVersion() < 0 )
+ sCommand += _T("setupx.dll");
+ else
+ sCommand += _T("setupapi.dll");
+
+ sCommand += _T(",InstallHinfSection PostUninstall 132 ");
+ sCommand += sInfFile;
+
+ if ( 0 == _taccess( sInfFile.c_str(), 2 ) )
+ ExecuteCommand( sCommand.c_str(), TRUE );
+
+ DeleteFile( sInfFile.c_str() );
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/registerextensions.cxx b/setup_native/source/win32/customactions/shellextensions/registerextensions.cxx
new file mode 100644
index 000000000000..9075436e0412
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/registerextensions.cxx
@@ -0,0 +1,430 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#include <shellapi.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+#include <string.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+/** creates a temporary folder with a unique name.
+
+ The returned string is a file URL.
+*/
+static std::_tstring createTempFolder()
+{
+ BOOL bExist = FALSE;
+ TCHAR szTempName[MAX_PATH];
+ do
+ {
+ bExist = FALSE;
+ // Get the temp path.
+ TCHAR lpPathBuffer[MAX_PATH];
+ DWORD dwRetVal = GetTempPath(MAX_PATH, lpPathBuffer);
+ if (dwRetVal > MAX_PATH || (dwRetVal == 0))
+ {
+ //fprintf (stderr, "GetTempPath failed with error %d.\n", GetLastError());
+ return TEXT("");
+ }
+ // Create a temporary file.
+ UINT uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files
+ "upg", // temp file name prefix
+ 0, // create unique name
+ szTempName); // buffer for name
+ if (uRetVal == 0)
+ {
+ //fprintf (stderr, "GetTempFileName failed with error %d.\n", GetLastError());
+ return TEXT("");
+ }
+ //Delete the file
+ BOOL bDel = DeleteFile(szTempName);
+ if (FALSE == bDel)
+ {
+ //fprintf(stderr, "Could not delete temp file. Error %d.\n", GetLastError());
+ return TEXT("");
+ }
+ // Create the directory
+ BOOL bDir = CreateDirectory(szTempName, NULL);
+ if (FALSE == bDir)
+ {
+ DWORD error =GetLastError();
+ if (ERROR_ALREADY_EXISTS == error)
+ {
+ bExist = TRUE;
+ }
+ else
+ {
+ //fprintf(stderr, "CreateDirectory failed with error %d.\n", error);
+ return TEXT("");
+ }
+ }
+ } while(bExist);
+
+ std::_tstring cur(szTempName);
+ //make a file URL from the path
+ std::_tstring ret(TEXT("file:///"));
+ for (std::_tstring::iterator i = cur.begin(); i != cur.end(); i++)
+ {
+ if (*i == '\\')
+ ret.append(TEXT("/"));
+ else
+ ret.push_back(*i);
+ }
+// MessageBox(NULL, ret.c_str(), "createTempFolder", MB_OK);
+ return ret.c_str();
+}
+
+/** deletes the temporary folder.
+ The argument must be a file URL.
+*/
+static void deleteTempFolder(const std::_tstring& sTempFolder)
+{
+ if (sTempFolder.size() == 0)
+ return;
+ //convert the file URL to a path
+ const std::_tstring path(sTempFolder.substr(8));
+ std::_tstring path2;
+// MessageBox(NULL, path.c_str(), "del1", MB_OK);
+ for (std::_tstring::const_iterator i = path.begin(); i != path.end(); i++)
+ {
+ if (*i == '/')
+ path2.append(TEXT("\\"));
+ else
+ path2.push_back(*i);
+ }
+
+ //We need a null terminated string with two nulls in the end
+ //for the SHFILEOPSTRUCT
+ const TCHAR * szTemp = path2.c_str();
+ size_t size = path2.size();
+ TCHAR * szTemp2 = new TCHAR[size + 2];
+ ZeroMemory(szTemp2, (size + 2) * sizeof(TCHAR));
+ memcpy(szTemp2, szTemp, size * sizeof(TCHAR));
+
+// MessageBox(NULL, szTemp2, "del3", MB_OK);
+ SHFILEOPSTRUCT operation =
+ {
+ NULL,
+ FO_DELETE,
+ szTemp2,
+ NULL,
+ FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR,
+ FALSE,
+ NULL,
+ NULL
+ };
+
+ SHFileOperation( &operation);
+ delete [] szTemp2;
+}
+
+
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+/* creates a child process which is specified in lpCommand.
+
+ out_exitCode is the exit code of the child process
+
+
+**/
+static BOOL ExecuteCommand( LPCTSTR lpCommand, DWORD * out_exitCode)
+{
+ BOOL fSuccess = FALSE;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+
+ fSuccess = CreateProcess(
+ NULL,
+ (LPTSTR)lpCommand,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ NULL,
+ NULL,
+ &si,
+ &pi
+ );
+
+ if ( fSuccess )
+ {
+ WaitForSingleObject( pi.hProcess, INFINITE );
+
+ if (!GetExitCodeProcess( pi.hProcess, out_exitCode))
+ fSuccess = FALSE;
+
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ }
+
+ return fSuccess;
+}
+
+static BOOL RemoveCompleteDirectory( std::_tstring sPath )
+{
+ bool bDirectoryRemoved = true;
+
+ std::_tstring mystr;
+ std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*");
+ WIN32_FIND_DATA aFindData;
+
+ // Finding all content in sPath
+
+ HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData );
+
+ if ( hFindContent != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+
+ do
+ {
+ std::_tstring sFileName = aFindData.cFileName;
+ std::_tstring sCurrentDir = TEXT(".");
+ std::_tstring sParentDir = TEXT("..");
+
+ mystr = "Current short file: " + sFileName;
+ // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK);
+
+ if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) &&
+ ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 ))
+ {
+ std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName;
+
+ if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
+ {
+ bool fSuccess = RemoveCompleteDirectory(sCompleteFileName);
+ if ( fSuccess )
+ {
+ mystr = "Successfully removed content of dir " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removing content of " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
+ }
+ }
+ else
+ {
+ bool fSuccess = DeleteFile( sCompleteFileName.c_str() );
+ if ( fSuccess )
+ {
+ mystr = "Successfully removed file " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removal of file " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK);
+ }
+ }
+ }
+
+ fNextFile = FindNextFile( 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
+
+ bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str());
+
+ if ( fRemoveDirSuccess )
+ {
+ mystr = "Successfully removed dir " + sPath;
+ // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removal of empty directory " + sPath;
+ // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
+ bDirectoryRemoved = false;
+ }
+ }
+
+ return bDirectoryRemoved;
+}
+
+extern "C" UINT __stdcall RegisterExtensions(MSIHANDLE handle)
+{
+ std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ std::_tstring sUnoPkgFile = sInstDir + TEXT("program\\unopkg.exe");
+ std::_tstring mystr;
+
+ WIN32_FIND_DATA aFindFileData;
+
+ mystr = "unopkg file: " + sUnoPkgFile;
+ //MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+
+ // Find unopkg.exe
+ HANDLE hFindUnopkg = FindFirstFile( sUnoPkgFile.c_str(), &aFindFileData );
+
+ if ( hFindUnopkg != INVALID_HANDLE_VALUE )
+ {
+ // unopkg.exe exists in program directory
+
+ const std::_tstring sTempFolder(createTempFolder());
+ std::_tstring sCommandPart1 = sUnoPkgFile + " sync";
+ std::_tstring sCommand = sCommandPart1
+ + TEXT(" -env:BUNDLED_EXTENSIONS_USER=$BRAND_BASE_DIR/share/prereg/bundled")
+ + TEXT(" -env:UNO_JAVA_JFW_INSTALL_DATA=$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml")
+ + TEXT(" -env:UserInstallation=") + sTempFolder;
+ mystr = "Command: " + sCommand;
+ //MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+
+ DWORD exitCode = 0;
+ bool fSuccess = ExecuteCommand( sCommand.c_str(), & exitCode);
+
+ deleteTempFolder(sTempFolder);
+
+// if ( fSuccess )
+// {
+// mystr = "Executed successfully!";
+// MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+// }
+// else
+// {
+// mystr = "An error occured during execution!";
+// MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+// }
+
+ FindClose( hFindUnopkg );
+ }
+// else
+// {
+// mystr = "Error: Did not find " + sUnoPkgFile;
+// MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+// }
+
+ return ERROR_SUCCESS;
+}
+
+
+extern "C" UINT __stdcall RemoveExtensions(MSIHANDLE handle)
+{
+ std::_tstring mystr;
+
+ // Finding the product with the help of the propery FINDPRODUCT,
+ // that contains a Windows Registry key, that points to the install location.
+
+ TCHAR szValue[8192];
+ DWORD nValueSize = sizeof(szValue);
+ HKEY hKey;
+ std::_tstring sInstDir;
+
+ std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
+ //MessageBox( NULL, sProductKey.c_str(), "Titel", MB_OK );
+
+ if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else
+ {
+ return ERROR_SUCCESS;
+ }
+
+ // Removing complete directory "Basis\presets\bundled"
+
+ std::_tstring sCacheDir = sInstDir + TEXT("share\\prereg\\bundled");
+
+ bool fSuccess = RemoveCompleteDirectory( sCacheDir );
+
+// if ( fSuccess )
+// {
+// mystr = "Executed successfully!";
+// MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK);
+// }
+// else
+// {
+// mystr = "An error occured during execution!";
+// MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK);
+// }
+
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx b/setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx
new file mode 100644
index 000000000000..f9dfc5cb99bc
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINNT 0x0401
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+static void SetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+}
+
+extern "C" UINT __stdcall SetAdminInstallProperty(MSIHANDLE handle)
+{
+ SetMsiProperty(handle, TEXT("ADMININSTALL"));
+ return ERROR_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/shellextensions/shellextensions.cxx b/setup_native/source/win32/customactions/shellextensions/shellextensions.cxx
new file mode 100644
index 000000000000..c26b0ca0d0c2
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/shellextensions.cxx
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/*
+ Windows shell extensions need to be approved in order to be used by the
+ Windows shell for clarification read the following section from the
+ Microsoft Developers Network Library (MSDN) see
+ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_extending/extensionhandlers/shell_ext.asp
+
+
+ <MSDN>
+ Shell extension handlers run in the Shell process. Because it is a system process,
+ the administrator of a Windows NT system can limit Shell extension handlers to
+ those on an approved list by setting the EnforceShellExtensionSecurity value of the
+ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer key to 1
+ (one).
+ To place a Shell extension handler on the approved list, create a REG_SZ value whose
+ name is the string form of the handler's GUID under
+ HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved.
+
+ The Shell does not use the value that is assigned to the GUID, but it should be set to
+ make inspecting the registry easier.
+
+ Your setup application can add values to the Approved key only if the person installing
+ the application has sufficient privileges. If the attempt to add an extension handler
+ fails, you should inform the user that administrative privileges are required to fully
+ install the application. If the handler is essential to the application, you should fail
+ the setup and notify the user to contact an administrator.
+
+ While there is no need to add values to the Approved key on Windows 95 or Windows 98
+ systems, there is no harm in doing so. The system will simply ignore them. However, there
+ is no guarantee that the key will exist on these systems. Your setup program must be able
+ to handle this case.
+ </MSDN>
+
+ We add the following entries to the respective registry key
+ "{C52AF81D-F7A0-4AAB-8E87-F80A60CCD396}"="OpenOffice.org Column Handler"
+ "{087B3AE3-E237-4467-B8DB-5A38AB959AC9}"="OpenOffice.org Infotip Handler"
+ "{63542C48-9552-494A-84F7-73AA6A7C99C1}"="OpenOffice.org Property Sheet Handler"
+ "{3B092F0C-7696-40E3-A80F-68D74DA84210}"="OpenOffice.org Thumbnail Viewer"
+
+ These shell extensions are implemented in the 'shell' project. We ignore registration
+ failures because of insufficient privileges. The reason is: On systems which restrict the
+ use of shell extensions by applying the aforementioned policy probably only people with
+ sufficient privileges are allowed to install applications anyway. On systems where the
+ use of shell extensions is not restricted registration failures because of insufficient
+ prviliges have no negative effect because the shell extensions will work anyhow.
+*/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#endif
+#include <tchar.h>
+
+struct RegistryEntry
+{
+ TCHAR* Key;
+ TCHAR* Value;
+};
+
+RegistryEntry ColumnHandler = { TEXT("{C52AF81D-F7A0-4AAB-8E87-F80A60CCD396}"), TEXT("OpenOffice.org Column Handler") };
+RegistryEntry InfotipHandler = { TEXT("{087B3AE3-E237-4467-B8DB-5A38AB959AC9}"), TEXT("OpenOffice.org Infotip Handler") };
+RegistryEntry PropHandler = { TEXT("{63542C48-9552-494A-84F7-73AA6A7C99C1}"), TEXT("OpenOffice.org Property Sheet Handler") };
+RegistryEntry ThumbViewer = { TEXT("{3B092F0C-7696-40E3-A80F-68D74DA84210}"), TEXT("OpenOffice.org Thumbnail Viewer") };
+
+BOOL GetMsiProp( MSIHANDLE hMSI, const char* pPropName, char** ppValue )
+{
+ DWORD sz = 0;
+ if ( MsiGetProperty( hMSI, pPropName, 0, &sz ) == ERROR_MORE_DATA )
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof( char );
+ char* buff = reinterpret_cast<char*>( malloc( nbytes ) );
+ ZeroMemory( buff, nbytes );
+ MsiGetProperty( hMSI, pPropName, buff, &sz );
+ *ppValue = buff;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool IsVersionNT64( MSIHANDLE hMSI )
+{
+ char* pVal = NULL;
+
+ if ( GetMsiProp( hMSI, "VersionNT64", &pVal ) && pVal )
+ {
+ free( pVal );
+ return true;
+ }
+
+ return false;
+}
+
+
+
+
+/*
+ Called during installation when the module "Windows Explorer Extensions" is
+ selected.
+*/
+extern "C" UINT __stdcall InstallExecSequenceEntry(MSIHANDLE hMSI)
+{
+ //MessageBox(NULL, TEXT("InstallExecSequenceEntry"), TEXT("Pythonmsi"), MB_OK | MB_ICONINFORMATION);
+ HKEY hKey;
+
+
+// 06.11.2009 tkr: to provide windows xp as build systems for mingw we need to define KEY_WOW64_64KEY
+// in mingw 3.13 KEY_WOW64_64KEY isn't available < Win2003 systems.
+// Also defined in setup_native\source\win32\customactions\reg64\reg64.cxx,source\win32\customactions\shellextensions\shellextensions.cxx and
+// extensions\source\activex\main\so_activex.cpp
+#ifndef KEY_WOW64_64KEY
+ #define KEY_WOW64_64KEY (0x0100)
+#endif
+
+ if (IsVersionNT64(hMSI))
+ {
+ // Open Windows 64 Bit Registry
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),0, KEY_WRITE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
+ {
+ RegSetValueEx(hKey, ColumnHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ColumnHandler.Value), _tcslen(ColumnHandler.Value) + 1);
+ RegSetValueEx(hKey, InfotipHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(InfotipHandler.Value), _tcslen(InfotipHandler.Value) + 1);
+ RegSetValueEx(hKey, PropHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(PropHandler.Value), _tcslen(PropHandler.Value) + 1);
+ RegSetValueEx(hKey, ThumbViewer.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ThumbViewer.Value), _tcslen(ThumbViewer.Value) + 1);
+
+ RegCloseKey(hKey);
+ }
+
+ // Open Windows 32 Bit Registry on Win64 maschine
+
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),0, KEY_WRITE, &hKey ) == ERROR_SUCCESS)
+ {
+ RegSetValueEx(hKey, ColumnHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ColumnHandler.Value), _tcslen(ColumnHandler.Value) + 1);
+ RegSetValueEx(hKey, InfotipHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(InfotipHandler.Value), _tcslen(InfotipHandler.Value) + 1);
+ RegSetValueEx(hKey, PropHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(PropHandler.Value), _tcslen(PropHandler.Value) + 1);
+ RegSetValueEx(hKey, ThumbViewer.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ThumbViewer.Value), _tcslen(ThumbViewer.Value) + 1);
+
+ RegCloseKey(hKey);
+ }
+
+
+ } else
+ {
+ if (RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), &hKey) == ERROR_SUCCESS)
+ {
+ RegSetValueEx(hKey, ColumnHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ColumnHandler.Value), _tcslen(ColumnHandler.Value) + 1);
+ RegSetValueEx(hKey, InfotipHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(InfotipHandler.Value), _tcslen(InfotipHandler.Value) + 1);
+ RegSetValueEx(hKey, PropHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(PropHandler.Value), _tcslen(PropHandler.Value) + 1);
+ RegSetValueEx(hKey, ThumbViewer.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ThumbViewer.Value), _tcslen(ThumbViewer.Value) + 1);
+
+ RegCloseKey(hKey);
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
+/*
+ Called during deinstallation when the module "Windows Explorer Extensions" has
+ been installed.
+*/
+extern "C" UINT __stdcall DeinstallExecSequenceEntry(MSIHANDLE)
+{
+ //MessageBox(NULL, TEXT("DeinstallExecSequenceEntry"), TEXT("Pythonmsi"), MB_OK | MB_ICONINFORMATION);
+ HKEY hKey;
+ if (RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), &hKey) == ERROR_SUCCESS)
+ {
+ RegDeleteValue(hKey, ColumnHandler.Key);
+ RegDeleteValue(hKey, InfotipHandler.Key);
+ RegDeleteValue(hKey, PropHandler.Key);
+ RegDeleteValue(hKey, ThumbViewer.Key);
+
+ RegCloseKey(hKey);
+ }
+ return ERROR_SUCCESS;
+}
+
+/* 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 000000000000..9c5e6d4eb416
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+
+std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+/*
+ 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" UINT __stdcall InstallStartmenuFolderIcon( MSIHANDLE handle )
+{
+ std::_tstring sOfficeMenuFolder = GetMsiProperty( handle, TEXT("OfficeMenuFolder") );
+ std::_tstring sDesktopFile = sOfficeMenuFolder + TEXT("Desktop.ini");
+
+ // MessageBox(NULL, sDesktopFile.c_str(), TEXT("OfficeMenuFolder"), MB_OK | MB_ICONINFORMATION);
+
+ std::_tstring sIconFile = GetMsiProperty( handle, TEXT("INSTALLLOCATION") ) + TEXT("program\\soffice.exe");
+
+ OSVERSIONINFO osverinfo;
+ osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx( &osverinfo );
+
+ if (osverinfo.dwMajorVersion < 6 /* && osverinfo.dwMinorVersion */ )
+ {
+ // This icon (18) is a Windows folder until XP Version (number is 0 based)
+ WritePrivateProfileString(
+ TEXT(".ShellClassInfo"),
+ TEXT("IconFile"),
+ sIconFile.c_str(),
+ sDesktopFile.c_str() );
+
+ // FYI: in tool 'ResHack' this icon can be found on position '19' (number is 1 based)
+ WritePrivateProfileString(
+ TEXT(".ShellClassInfo"),
+ TEXT("IconIndex"),
+ TEXT("18"),
+ sDesktopFile.c_str() );
+ }
+ // else
+ // {
+ // // 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.
+ WritePrivateProfileString(
+ TEXT(".ShellClassInfo"),
+ TEXT("ConfirmFileOp"),
+ TEXT("0"),
+ sDesktopFile.c_str() );
+
+ /*
+ WritePrivateProfileString(
+ TEXT(".ShellClassInfo"),
+ TEXT("InfoTip"),
+ TEXT("StarOffice Productivity Suite"),
+ sDesktopFile.c_str() );
+ */
+
+ SetFileAttributes( sDesktopFile.c_str(), FILE_ATTRIBUTE_HIDDEN );
+ SetFileAttributes( sOfficeMenuFolder.c_str(), FILE_ATTRIBUTE_SYSTEM );
+
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall DeinstallStartmenuFolderIcon(MSIHANDLE handle)
+{
+ std::_tstring sOfficeMenuFolder = GetMsiProperty( handle, TEXT("OfficeMenuFolder") );
+ std::_tstring sDesktopFile = sOfficeMenuFolder + TEXT("Desktop.ini");
+
+ SetFileAttributes( sDesktopFile.c_str(), FILE_ATTRIBUTE_NORMAL );
+ DeleteFile( sDesktopFile.c_str() );
+
+ SetFileAttributes( 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 000000000000..6280bfb5b2e5
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/upgrade.cxx
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#include <tchar.h>
+#include <string>
+
+using namespace std;
+
+namespace
+{
+ // The provided GUID must be without surounding '{}'
+ string GetGuidPart(const string& guid, int index)
+ {
+ assert((guid.length() == 36) && "No GUID or wrong format!");
+ assert(((index > -1) && (index < 5)) && "Out of range!");
+
+ if (index == 0) return string(guid.c_str(), 8);
+ if (index == 1) return string(guid.c_str() + 9, 4);
+ if (index == 2) return string(guid.c_str() + 14, 4);
+ if (index == 3) return string(guid.c_str() + 19, 4);
+ if (index == 4) return string(guid.c_str() + 24, 12);
+
+ return string();
+ }
+
+ void Swap(char* p1, char* p2)
+ {
+ char tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+ }
+
+ string Invert(const string& str)
+ {
+ char* buff = reinterpret_cast<char*>(_alloca(str.length()));
+ strncpy(buff, str.c_str(), str.length());
+
+ char* front = buff;
+ char* back = buff + str.length() - 1;
+
+ while (front < back)
+ Swap(front++, back--);
+
+ return string(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 the last
+ // 8 bytes always the nibbles will be inverted for further
+ // details look in the MSDN under compressed registry keys
+ string ConvertGuid(const string& guid)
+ {
+ string convertedGuid;
+
+ string 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(string(part.c_str(), 2));
+ convertedGuid += Invert(string(part.c_str() + 2, 2));
+
+ part = GetGuidPart(guid, 4);
+ int pos = 0;
+ for (int i = 0; i < 6; i++)
+ {
+ convertedGuid += Invert(string(part.c_str() + pos, 2));
+ pos += 2;
+ }
+ return convertedGuid;
+ }
+
+ string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ string result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+ return result;
+ }
+
+ inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ return (GetMsiProperty(handle, sProperty).length() > 0);
+ }
+
+ inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+ }
+
+ inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+ }
+
+ bool RegistryKeyHasUpgradeSubKey(
+ HKEY hRootKey, const string& regKey, const string& upgradeKey)
+ {
+ HKEY hKey;
+ if (RegOpenKey(hRootKey, regKey.c_str(), &hKey) == ERROR_SUCCESS)
+ {
+ DWORD nSubKeys;
+ DWORD lLongestSubKey;
+
+ if (RegQueryInfoKey(
+ hKey, NULL, NULL, NULL, &nSubKeys, &lLongestSubKey, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+ {
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(lLongestSubKey + 1));
+
+ for (DWORD i = 0; i < nSubKeys; i++)
+ {
+ LONG ret = RegEnumKey(hKey, i, buffer, lLongestSubKey + 1);
+ if ((ret == ERROR_SUCCESS) && (buffer == upgradeKey))
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+} // namespace
+
+extern "C" UINT __stdcall SetProductInstallMode(MSIHANDLE handle)
+{
+ string upgradeCode = GetMsiProperty(handle, TEXT("UpgradeCode"));
+ upgradeCode = ConvertGuid(string(upgradeCode.c_str() + 1, upgradeCode.length() - 2));
+
+ //MessageBox(NULL, upgradeCode.c_str(), TEXT("Debug"), MB_OK);
+
+ if (RegistryKeyHasUpgradeSubKey(
+ HKEY_CURRENT_USER,
+ TEXT("Software\\Microsoft\\Installer\\UpgradeCodes"),
+ upgradeCode) && IsSetMsiProperty(handle, TEXT("ALLUSERS")))
+ {
+ UnsetMsiProperty(handle, TEXT("ALLUSERS"));
+ //MessageBox(NULL, "ALLUSERS removed", "DEBUG", MB_OK);
+ }
+ else if (RegistryKeyHasUpgradeSubKey(
+ HKEY_LOCAL_MACHINE,
+ TEXT("Software\\Classes\\Installer\\UpgradeCodes"),
+ upgradeCode) && !IsSetMsiProperty(handle, TEXT("ALLUSERS")))
+ {
+ SetMsiProperty(handle, TEXT("ALLUSERS"));
+ //MessageBox(NULL, "ALLUSERS set", "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 000000000000..badd20ae241e
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINNT 0x0401
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+#include <strsafe.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+//----------------------------------------------------------
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
+{
+ CHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugStringA( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCSTR, ... )
+{
+}
+#endif
+
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+static BOOL RemoveCompleteDirectory( std::_tstring sPath )
+{
+ bool bDirectoryRemoved = true;
+
+ std::_tstring mystr;
+ std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*");
+ WIN32_FIND_DATA aFindData;
+
+ // Finding all content in sPath
+
+ HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData );
+
+ if ( hFindContent != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+ std::_tstring sCurrentDir = TEXT(".");
+ std::_tstring sParentDir = TEXT("..");
+
+ do
+ {
+ std::_tstring sFileName = aFindData.cFileName;
+
+ mystr = "Current short file: " + sFileName;
+ // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK);
+
+ if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) &&
+ ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 ))
+ {
+ std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName;
+
+ if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
+ {
+ bool fSuccess = RemoveCompleteDirectory(sCompleteFileName);
+ if ( fSuccess )
+ {
+ mystr = "Successfully removed content of dir " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removing content of " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
+ }
+ }
+ else
+ {
+ bool fSuccess = DeleteFile( sCompleteFileName.c_str() );
+ if ( fSuccess )
+ {
+ mystr = "Successfully removed file " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removal of file " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK);
+ }
+ }
+ }
+
+ fNextFile = FindNextFile( 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
+
+ bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str());
+
+ if ( fRemoveDirSuccess )
+ {
+ mystr = "Successfully removed dir " + sPath;
+ // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removal of empty directory " + sPath;
+ // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
+ bDirectoryRemoved = false;
+ }
+ }
+
+ return bDirectoryRemoved;
+}
+
+
+
+extern "C" UINT __stdcall RenamePrgFolder( MSIHANDLE handle )
+{
+ std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+
+ std::_tstring sRenameSrc = sOfficeInstallPath + TEXT("program");
+ std::_tstring sRenameDst = sOfficeInstallPath + TEXT("program_old");
+
+// MessageBox(NULL, sRenameSrc.c_str(), "INSTALLLOCATION", MB_OK);
+
+ bool bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
+ if ( !bSuccess )
+ {
+ TCHAR sAppend[2] = TEXT("0");
+ for ( int i = 0; i < 10; i++ )
+ {
+ sRenameDst = sOfficeInstallPath + TEXT("program_old") + sAppend;
+ bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
+ if ( bSuccess )
+ break;
+ sAppend[0] += 1;
+ }
+ }
+
+#if 0
+ if ( !bSuccess )
+ MessageBox(NULL, "Renaming folder failed", "RenamePrgFolder", MB_OK);
+ else
+ MessageBox(NULL, "Renaming folder successful", "RenamePrgFolder", MB_OK);
+#endif
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall RemovePrgFolder( MSIHANDLE handle )
+{
+ std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+ std::_tstring sRemoveDir = sOfficeInstallPath + TEXT("program_old");
+
+// MessageBox(NULL, sRemoveDir.c_str(), "REMOVING OLD DIR", MB_OK);
+
+ bool bSuccess = RemoveCompleteDirectory( sRemoveDir );
+
+ TCHAR sAppend[2] = TEXT("0");
+ for ( int i = 0; i < 10; i++ )
+ {
+ sRemoveDir = sOfficeInstallPath + TEXT("program_old") + sAppend;
+ bSuccess = RemoveCompleteDirectory( sRemoveDir );
+ sAppend[0] += 1;
+ }
+
+#if 0
+ if ( bSuccess )
+ MessageBox(NULL, "Removing folder successful", "RemovePrgFolder", MB_OK);
+ else
+ MessageBox(NULL, "Removing folder failed", "RemovePrgFolder", MB_OK);
+#endif
+
+ 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 000000000000..b978301fb57a
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/checkversion.cxx
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define UNICODE
+
+#ifdef _MSC_VER
+#pragma warning(push,1) // disable warnings within system headers
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string.h>
+#include <malloc.h>
+#include <stdio.h>
+#include "strsafe.h"
+
+#include <seterror.hxx>
+
+//----------------------------------------------------------
+BOOL GetMsiProp( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
+{
+ DWORD sz = 0;
+ if ( MsiGetProperty( hMSI, pPropName, L"", &sz ) == ERROR_MORE_DATA )
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof( wchar_t );
+ wchar_t* buff = reinterpret_cast<wchar_t*>( malloc( nbytes ) );
+ ZeroMemory( buff, nbytes );
+ MsiGetProperty( hMSI, pPropName, buff, &sz );
+ *ppValue = buff;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//----------------------------------------------------------
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall CheckVersions( MSIHANDLE hMSI )
+{
+ // MessageBox(NULL, L"CheckVersions", L"Information", MB_OK | MB_ICONINFORMATION);
+
+ wchar_t* pVal = NULL;
+
+ if ( GetMsiProp( hMSI, L"NEWPRODUCTS", &pVal ) && pVal )
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: NEWPRODUCTS found [%s]"), pVal );
+ if ( *pVal != 0 )
+ SetMsiErrorCode( MSI_ERROR_NEW_VERSION_FOUND );
+ free( pVal );
+ }
+ pVal = NULL;
+ if ( GetMsiProp( hMSI, L"SAMEPRODUCTS", &pVal ) && pVal )
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: SAMEPRODUCTS found [%s]"), pVal );
+ if ( *pVal != 0 )
+ SetMsiErrorCode( MSI_ERROR_SAME_VERSION_FOUND );
+ free( pVal );
+ }
+ pVal = NULL;
+ if ( GetMsiProp( hMSI, L"OLDPRODUCTS", &pVal ) && pVal )
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: OLDPRODUCTS found [%s]"), pVal );
+ if ( *pVal != 0 )
+ SetMsiErrorCode( MSI_ERROR_OLD_VERSION_FOUND );
+ free( pVal );
+ }
+ pVal = NULL;
+ if ( GetMsiProp( hMSI, L"BETAPRODUCTS", &pVal ) && pVal )
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: BETAPRODUCTS found [%s]"), pVal );
+ if ( *pVal != 0 )
+ SetMsiErrorCode( MSI_ERROR_OLD_VERSION_FOUND );
+ free( pVal );
+ }
+
+ pVal = NULL;
+ if ( GetMsiProp( hMSI, L"NEWPRODUCTSPATCH", &pVal ) && pVal )
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: NEWPRODUCTSPATCH found [%s]"), pVal );
+ if ( *pVal != 0 )
+ SetMsiErrorCode( MSI_ERROR_NEW_PATCH_FOUND );
+ free( pVal );
+ }
+ pVal = NULL;
+ if ( GetMsiProp( hMSI, L"SAMEPRODUCTSPATCH", &pVal ) && pVal )
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: SAMEPRODUCTSPATCH found [%s]"), pVal );
+ if ( *pVal != 0 )
+ SetMsiErrorCode( MSI_ERROR_SAME_PATCH_FOUND );
+ free( pVal );
+ }
+ pVal = NULL;
+ if ( GetMsiProp( hMSI, L"OLDPRODUCTSPATCH", &pVal ) && pVal )
+ {
+ OutputDebugStringFormat( TEXT("DEBUG: OLDPRODUCTSPATCH found [%s]"), pVal );
+ if ( *pVal != 0 )
+ SetMsiErrorCode( MSI_ERROR_OLD_PATCH_FOUND );
+ free( pVal );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/customactions/tools/exports.dxp b/setup_native/source/win32/customactions/tools/exports.dxp
new file mode 100644
index 000000000000..18d82240f49e
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/exports.dxp
@@ -0,0 +1 @@
+CheckVersions
diff --git a/setup_native/source/win32/customactions/tools/makefile.mk b/setup_native/source/win32/customactions/tools/makefile.mk
new file mode 100644
index 000000000000..4e8d791eff15
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=sn_tools
+
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = $(SLO)$/seterror.obj \
+ $(SLO)$/checkversion.obj
+
+SHL1OBJS = $(SLOFILES)
+
+STDSHL+= \
+ $(ADVAPI32LIB)\
+ $(MSILIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+STDSHL+=$(LIBSTLPORTST)
+.ENDIF
+
+#SHL1LIBS = $(SLB)$/$(TARGET).lib
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
+
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 000000000000..c9c74ec43d18
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/seterror.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define UNICODE
+
+#ifdef _MSC_VER
+#pragma warning(push,1) // disable warnings within system headers
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <string.h>
+#include <malloc.h>
+#include <stdio.h>
+#include "strsafe.h"
+
+#include <seterror.hxx>
+
+//----------------------------------------------------------
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+
+//----------------------------------------------------------
+void SetMsiErrorCode( int nErrorCode )
+{
+ const TCHAR sMemMapName[] = TEXT( "Global\\MsiErrorObject" );
+
+ HANDLE hMapFile;
+ int *pBuf;
+
+ hMapFile = OpenFileMapping(
+ FILE_MAP_ALL_ACCESS, // read/write access
+ FALSE, // do not inherit the name
+ sMemMapName ); // name of mapping object
+
+ if ( hMapFile == NULL ) // can not set error code
+ {
+ OutputDebugStringFormat( TEXT("Could not open map file (%d).\n"), GetLastError() );
+ return;
+ }
+
+ pBuf = (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
+ OutputDebugStringFormat( TEXT("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 000000000000..3a2a1b047d9f
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/seterror.hxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SETERROR_HXX_
+#define _SETERROR_HXX_
+
+//----------------------------------------------------------
+// list of own error codes
+
+#define MSI_ERROR_INVALIDDIRECTORY 9001
+#define MSI_ERROR_ISWRONGPRODUCT 9002
+#define MSI_ERROR_PATCHISOLDER 9003
+
+#define MSI_ERROR_NEW_VERSION_FOUND 9010
+#define MSI_ERROR_SAME_VERSION_FOUND 9011
+#define MSI_ERROR_OLD_VERSION_FOUND 9012
+#define MSI_ERROR_NEW_PATCH_FOUND 9013
+#define MSI_ERROR_SAME_PATCH_FOUND 9014
+#define MSI_ERROR_OLD_PATCH_FOUND 9015
+
+#define MSI_ERROR_OFFICE_IS_RUNNING 9020
+
+#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/desktophelper.txt b/setup_native/source/win32/desktophelper.txt
new file mode 100644
index 000000000000..c7540116c671
--- /dev/null
+++ b/setup_native/source/win32/desktophelper.txt
@@ -0,0 +1 @@
+# File used for desktop link
diff --git a/setup_native/source/win32/get_retval.bat b/setup_native/source/win32/get_retval.bat
new file mode 100755
index 000000000000..d1a10539be7f
--- /dev/null
+++ b/setup_native/source/win32/get_retval.bat
@@ -0,0 +1,3 @@
+echo off
+call %*
+echo %1 returned %ERRORLEVEL% \ No newline at end of file
diff --git a/setup_native/source/win32/msi-encodinglist.txt b/setup_native/source/win32/msi-encodinglist.txt
new file mode 100644
index 000000000000..efa0f57b87ae
--- /dev/null
+++ b/setup_native/source/win32/msi-encodinglist.txt
@@ -0,0 +1,141 @@
+# Syntax: language ANSI-Codepage LCID
+# comment lines begin with hash
+af 1252 1078 # Afrikaans
+ar 1256 1025
+ar-SA 1256 1025
+as-IN 0 1101 # Assamese
+as 0 1101 # Assamese
+ast 1252 1610
+be-BY 1251 1059 # Belarusian
+bg 1251 1026 # Bulgarian
+bn 0 2117 # Bengali
+bn-BD 0 2117 # Bengali Bangladesh
+bn-IN 0 1093 # Bengali India
+br 1252 1150 # Breton
+brx 0 1603 # Bodo (India)
+bs 0 5146 # bosnian
+bo 0 2121
+ca 1252 1027 # Catalan
+cs 1250 1029 # Czech
+cy 1252 1106 # Welsh
+da 1252 1030
+de 1252 1031
+dgo 0 1604 # Dogri (India)
+dz 0 2129 # Dzongkha (same ID as tibetan bhutan (s. i40713))
+el 1253 1032
+en-GB 1252 2057
+en-US 1252 1033
+en-ZA 1252 7177
+eo 0 1553 # Esperanto
+es 1252 1034
+et 1257 1061
+eu 1252 1069 # Basque
+fa 0 1065 # Farsi
+fi 1252 1035
+fo 1252 1080 # Faroese
+fr 1252 1036
+fr-CA 1252 3084
+ga 0 2108 # Irish
+gd 0 1084 # Gaelic (Scotland)
+gl 1252 1110 # Galician
+gu 0 1095 # Gujarati
+gu-IN 0 1095 # Gujarati
+he 1255 1037
+hi 0 1081
+hr 1250 1050 # Croatian
+hu 1250 1038
+hy 0 1067 # Armenian
+id 1252 1057 # Indonesian
+is 1252 1039 # Icelandic
+it 1252 1040
+ja 932 1041
+ka 0 1079 # Georgian
+km 0 1107 # Khmer
+kn 0 1099 # Kannada
+kn-IN 0 1099 # Kannada
+ko 949 1042
+kok 0 1111 # Konkani
+ks 0 1120 # Kashmiri
+ku 0 1574
+kid 1252 1033 # key id pseudo language
+ky 0 2100
+lo 0 1108 # Lao
+lt 1257 1063 # Lithuanian
+lv 1257 1062 # Latvian
+mai 0 1605 # Maithili (India)
+mk 1251 1071 # Macedonian
+ml-IN 0 1100
+ml 0 1100
+mn 0 1104 # Mongolian
+mni 0 1112 # Manipuri
+mn-TR 0 2128 # Mongolian Classical/traditional
+mr 0 1102 # Marathi
+mr-IN 0 1102
+ms 0 1086 # Malay (Malaysian)
+mt 0 1082 # Maltese
+my 0 1109 # Burmese
+nb 1252 1044
+ne 0 1121 # Nepali
+nl 1252 1043
+nn 1252 2068
+no 1252 1044
+nr 0 1580 # Ndebele South
+ns 0 1132 # Northern Sotho (Sepedi)
+or 0 1096 # Oriya
+oc 1252 1154 # Occitan-lengadocian
+or-IN 0 1096
+pa-IN 0 1094 # Punjabi
+pap 0 2171
+om 0 2162
+pl 1250 1045
+pt 1252 2070
+pt-BR 1252 1046
+pt-PT 1252 2070
+ps 0 2171
+ca-XV 1252 32771 # Catalan Valencian
+rm 0 1047 # Raeto-Romance
+ro 1250 1048 # Romanian
+ru 1251 1049
+rw 0 1569 # Kinyarwanda
+sa-IN 0 1103 # Sanskrit
+sat 0 1606 # Santali
+sb 0 1070 # Sorbian
+sc 0 3047
+sd 0 1113 # Sindhi
+sh 1250 2074 # Serbian Latin
+sk 1250 1051 # Slovak
+sl 1250 1060 # Slovenian
+sq 1250 1052 # Albanian
+sr 1251 3098 # Serbian Cyrillic
+sr-SP 1251 3098 # Serbian Cyrillic
+ss 0 1579 # Swazi
+st 0 1072 # Southern Sotho, Sutu
+sv 1252 1053
+sw 1252 1089 # Swahili
+sw-TZ 1252 1089 # Swahili
+si 0 2133
+ta 0 1097 # Tamil
+ta-IN 0 1097 # Tamil
+te-IN 0 1098
+te 0 1098
+tg 0 1064 # Tajik
+th 874 1054
+ti 0 1139 # Tigrinya
+ti-ER 0 1139 # Tigrinya
+tn 0 1074 # Setsuana
+tr 1254 1055 # Turkish
+ts 0 1073 # Tsonga
+tt 1251 1092 # Tatar
+uk 1251 1058 # Ukrainian
+ur 1256 1056 # Urdu
+ur-IN 0 2080
+uz 0 1091 # Uzbek (Latin)
+ug 0 2200
+ve 0 1075 # Venda
+vi 1258 1066 # Vietnamese
+xh 0 1076 # Xhosa
+yi 0 1085 # Yiddish
+zh-CN 936 2052
+zh-TW 950 1028
+zu 0 1077 # Zulu
+kk 0 1087
diff --git a/setup_native/source/win32/nsis/brobanner.bmp b/setup_native/source/win32/nsis/brobanner.bmp
new file mode 100644
index 000000000000..0a2961accbda
--- /dev/null
+++ b/setup_native/source/win32/nsis/brobanner.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/brobanner.svg b/setup_native/source/win32/nsis/brobanner.svg
new file mode 100644
index 000000000000..041386d7cea9
--- /dev/null
+++ b/setup_native/source/win32/nsis/brobanner.svg
@@ -0,0 +1,667 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="103"
+ height="58"
+ id="svg3229"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="Installation (banner_OOorg_standard).svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0">
+ <defs
+ id="defs3231">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective3237" />
+ <inkscape:perspective
+ id="perspective2777"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4800" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective3742" />
+ <inkscape:perspective
+ id="perspective3744"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2870" />
+ <inkscape:perspective
+ id="perspective2500"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2531" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2854" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ id="perspective4034" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ id="perspective3939" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ id="perspective3852" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 21.26 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="62.360001 : 21.26 : 1"
+ inkscape:persp3d-origin="31.18 : 14.173333 : 1"
+ id="perspective3771" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ id="perspective59" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective3532" />
+ <inkscape:perspective
+ id="perspective2543"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2818"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2521" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4715" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4717" />
+ <inkscape:perspective
+ id="perspective4719"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4721"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4723"
+ inkscape:persp3d-origin="31.18 : 14.173333 : 1"
+ inkscape:vp_z="62.360001 : 21.26 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 21.26 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4725"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4727"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4729"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4731"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4733"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4735" />
+ <inkscape:perspective
+ id="perspective4737"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4739" />
+ <inkscape:perspective
+ id="perspective4741"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4743"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4211" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 12.41 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="391.03 : 12.41 : 1"
+ inkscape:persp3d-origin="195.515 : 8.2733332 : 1"
+ id="perspective3301" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 12.41 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="399.49701 : 12.41 : 1"
+ inkscape:persp3d-origin="199.7485 : 8.2733332 : 1"
+ id="perspective3226" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 18.512501 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="393.207 : 18.512501 : 1"
+ inkscape:persp3d-origin="196.6035 : 12.341667 : 1"
+ id="perspective3158" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 18.512501 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="393.207 : 18.512501 : 1"
+ inkscape:persp3d-origin="196.6035 : 12.341667 : 1"
+ id="perspective3146" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2625" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2623" />
+ <inkscape:perspective
+ id="perspective2621"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2619"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2617"
+ inkscape:persp3d-origin="31.18 : 14.173333 : 1"
+ inkscape:vp_z="62.360001 : 21.26 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 21.26 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2615"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2613"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2611"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2609"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2607"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2753" />
+ <inkscape:perspective
+ id="perspective2604"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2602" />
+ <inkscape:perspective
+ id="perspective2600"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2598"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 18.512501 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="401.944 : 18.512501 : 1"
+ inkscape:persp3d-origin="200.972 : 12.341667 : 1"
+ id="perspective2645" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 18.512501 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="385.51999 : 18.512501 : 1"
+ inkscape:persp3d-origin="192.75999 : 12.341667 : 1"
+ id="perspective2633" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 48.070499 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="212.035 : 48.070499 : 1"
+ inkscape:persp3d-origin="106.0175 : 32.047 : 1"
+ id="perspective2474" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 48.070499 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="212.035 : 48.070499 : 1"
+ inkscape:persp3d-origin="106.0175 : 32.047 : 1"
+ id="perspective2426" />
+ <inkscape:perspective
+ id="perspective2592"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="7.8135634"
+ inkscape:cx="47.884284"
+ inkscape:cy="27.859947"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1264"
+ inkscape:window-height="750"
+ inkscape:window-x="0"
+ inkscape:window-y="14"
+ showguides="true"
+ inkscape:guide-bbox="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="6.203125,39.566406"
+ id="guide2462" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="6.4960938,39.835938"
+ id="guide2464" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="7.8046875,17.640625"
+ id="guide2466" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="98.285156,17.5"
+ id="guide2468" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata3234">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Camada 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-565.64286,-466.2193)">
+ <text
+ transform="scale(1.0168078,0.98347)"
+ font-size="103.091"
+ id="text43"
+ style="font-size:48.89245605px;font-family:Vegur-Regular"
+ x="1429.27"
+ y="552.60571" />
+ <text
+ transform="scale(0.9979479,1.0020563)"
+ font-size="103.091"
+ id="text3748"
+ style="font-size:91.03964996px;font-family:Vegur-Regular"
+ x="1305.9132"
+ y="429.15198" />
+ <g
+ id="g2905"
+ inkscape:export-filename="C:\Users\Marcelo\Desktop\Trabalhos\LibreOffice\Finais\Telas\Installation (banner_OOorg_standard).png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/banner_OOorg_standard.bmp.png"
+ y="466.2193"
+ x="565.64288"
+ height="58"
+ width="103"
+ id="rect12423"
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="matrix(0.1694148,0,0,0.1694148,607.63264,451.4171)"
+ id="g2870">
+ <g
+ id="g4513"
+ transform="translate(-397.1353,-52.392239)">
+ <g
+ style="fill:#000000"
+ transform="matrix(1.1041871,0,0,1.1275051,240.59949,350.39632)"
+ id="g3252">
+ <path
+ style="fill:#000000"
+ d="M 17.816,4.488 L 10.744,4.488 L 10.744,24.48 L 7.004,24.48 L 7.004,4.488 L 0,4.488 L 0,1.428 L 17.816,1.428 L 17.816,4.488 z"
+ id="path3254" />
+ <path
+ style="fill:#000000"
+ d="M 23.604186,10.37 C 24.930186,8.568 26.596186,7.616 28.840186,7.616 C 32.274186,7.616 34.246186,9.792 34.246186,13.532 L 34.246186,24.48 L 30.506186,24.48 L 30.506186,15.368 C 30.506186,12.206 30.098186,10.506 27.514186,10.506 C 25.168186,10.506 23.536186,12.648 23.536186,15.708 L 23.536186,24.48 L 19.796186,24.48 L 19.796186,2.9698466e-14 L 23.536186,2.9698466e-14 L 23.536186,10.37 L 23.604186,10.37 z"
+ id="path3256" />
+ <path
+ style="fill:#000000"
+ d="M 46.298814,21.931 C 47.896814,21.931 49.324814,21.591 50.718814,20.979 L 51.092814,23.801 C 49.392814,24.583 47.828814,24.821 45.618814,24.821 C 40.790814,24.821 37.389814,22.067 37.389814,16.593 C 37.389814,11.323 40.925814,7.617 45.651814,7.617 C 49.901814,7.617 52.315814,11.051 52.315814,14.893 C 52.315814,15.743 52.281814,16.525 52.179814,17.239 L 41.232814,17.239 C 41.436814,20.196 43.135814,21.931 46.298814,21.931 z M 48.677814,14.484 C 48.575814,12.274 47.759814,10.506 45.345814,10.506 C 43.101814,10.506 41.775814,12.036 41.401814,14.484 L 48.677814,14.484 z"
+ id="path3258" />
+ <path
+ style="fill:#000000"
+ d="M 70.02901,1.258 C 78.35901,1.258 83.22101,5.134 83.22101,12.546 C 83.22101,20.774 76.18301,24.65 69.58701,24.65 C 67.30901,24.65 64.96301,24.548 62.92301,24.344 L 62.92301,1.632 C 65.23501,1.394 68.05701,1.258 70.02901,1.258 z M 66.66301,21.522 C 67.68301,21.59 68.87301,21.624 69.92701,21.624 C 74.85701,21.624 79.07301,18.904 79.07301,12.954 C 79.07301,7.344 75.60501,4.284 69.96101,4.284 C 68.87301,4.284 67.51301,4.318 66.66301,4.42 L 66.66301,21.522 z"
+ id="path3260" />
+ <path
+ style="fill:#000000"
+ d="M 101.66244,16.218 C 101.66244,21.42 98.194443,24.82 93.468443,24.82 C 88.742443,24.82 85.274443,21.42 85.274443,16.218 C 85.274443,11.016 88.742443,7.616 93.468443,7.616 C 98.194443,7.616 101.66244,11.016 101.66244,16.218 z M 97.651443,16.218 C 97.651443,12.546 96.087443,10.506 93.469443,10.506 C 90.851443,10.506 89.287443,12.546 89.287443,16.218 C 89.287443,19.89 90.851443,21.93 93.469443,21.93 C 96.087443,21.93 97.651443,19.891 97.651443,16.218 z"
+ id="path3262" />
+ <path
+ style="fill:#000000"
+ d="M 113.02567,21.931 C 114.35167,21.931 115.88167,21.591 117.13967,21.047 L 117.51367,23.869 C 116.32367,24.447 114.48767,24.821 112.20967,24.821 C 107.17767,24.821 103.91367,21.523 103.91367,16.593 C 103.91367,10.915 107.75567,7.617 112.92367,7.617 C 115.06567,7.617 116.83367,8.093 117.68367,8.603 L 117.30967,11.425 C 116.25567,10.915 114.86167,10.507 113.29767,10.507 C 110.10167,10.507 107.92567,12.377 107.92567,16.151 C 107.92567,19.958 109.89767,21.931 113.02567,21.931 z"
+ id="path3264" />
+ <path
+ style="fill:#000000"
+ d="M 131.29089,22.066 C 129.96489,23.868 128.26489,24.82 126.05489,24.82 C 122.62089,24.82 120.64889,22.644 120.64889,18.904 L 120.64889,7.956 L 124.38889,7.956 L 124.38889,17.068 C 124.38889,20.23 124.76289,21.93 127.38089,21.93 C 129.69289,21.93 131.35889,19.822 131.35889,16.728 L 131.35889,7.956 L 135.09889,7.956 L 135.09889,24.48 L 131.46089,24.48 L 131.35889,22.066 L 131.29089,22.066 z"
+ id="path3266" />
+ <path
+ style="fill:#000000"
+ d="M 152.78142,11.05 C 154.09704,8.432 156.01986,7.616 157.97641,7.616 C 161.14737,7.616 162.96899,9.588 162.96899,13.226 L 162.96899,24.48 L 159.25829,24.48 L 159.25829,14.382 C 159.25829,11.628 158.48241,10.506 156.6608,10.506 C 154.46811,10.506 153.08503,12.614 153.08503,16.388 L 153.08503,24.48 L 149.37432,24.48 L 149.37432,14.382 C 149.37432,11.628 148.59845,10.506 146.77683,10.506 C 144.58414,10.506 143.20106,12.75 143.20106,16.388 L 143.20106,24.48 L 139.49036,24.48 L 139.49036,7.956 L 143.09986,7.956 L 143.20106,10.37 L 143.26853,10.37 C 144.34801,8.636 145.86602,7.616 148.09244,7.616 C 150.2514,7.616 152.03928,8.568 152.68022,11.05 L 152.78142,11.05 z"
+ id="path3268" />
+ <path
+ style="fill:#000000"
+ d="M 175.00552,21.931 C 176.60352,21.931 178.03152,21.591 179.42552,20.979 L 179.79952,23.801 C 178.09952,24.583 176.53552,24.821 174.32552,24.821 C 169.49752,24.821 166.09652,22.067 166.09652,16.593 C 166.09652,11.323 169.63252,7.617 174.35852,7.617 C 178.60852,7.617 181.02252,11.051 181.02252,14.893 C 181.02252,15.743 180.98852,16.525 180.88652,17.239 L 169.93852,17.239 C 170.14452,20.196 171.84352,21.931 175.00552,21.931 z M 177.38552,14.484 C 177.28352,12.274 176.46752,10.506 174.05352,10.506 C 171.80952,10.506 170.48352,12.036 170.10952,14.484 L 177.38552,14.484 z"
+ id="path3270" />
+ <path
+ style="fill:#000000"
+ d="M 188.24105,10.37 C 189.56705,8.568 191.23305,7.616 193.47705,7.616 C 196.91105,7.616 198.88305,9.792 198.88305,13.532 L 198.88305,24.48 L 195.14305,24.48 L 195.14305,15.368 C 195.14305,12.206 194.73505,10.506 192.15105,10.506 C 189.80505,10.506 188.17305,12.648 188.17305,15.708 L 188.17305,24.48 L 184.43305,24.48 L 184.43305,7.956 L 188.07105,7.956 L 188.17305,10.37 L 188.24105,10.37 L 188.24105,10.37 z"
+ id="path3272" />
+ <path
+ style="fill:#000000"
+ d="M 212.15806,10.846 L 208.07806,10.846 L 208.07806,19.584 C 208.07806,21.454 209.03006,21.93 210.35606,21.93 C 211.07006,21.93 211.51206,21.862 212.22606,21.624 L 212.60006,24.378 C 211.61406,24.684 210.45806,24.82 208.96206,24.82 C 206.27606,24.82 204.33806,23.528 204.33806,20.502 L 204.33806,10.846 L 201.65206,10.846 L 201.65206,7.956 L 204.33806,7.956 L 204.33806,4.216 L 208.07806,4.216 L 208.07806,7.956 L 212.15806,7.956 L 212.15806,10.846 z"
+ id="path3274" />
+ <path
+ style="fill:#000000"
+ d="M 223.13443,24.48 L 223.13443,1.428 L 235.98743,1.428 L 235.98743,4.488 L 226.87543,4.488 L 226.87543,11.39 L 234.83143,11.39 L 234.83143,14.416 L 226.87543,14.416 L 226.87543,24.48 L 223.13443,24.48 z"
+ id="path3276" />
+ <path
+ style="fill:#000000"
+ d="M 254.15374,16.218 C 254.15374,21.42 250.68474,24.82 245.95974,24.82 C 241.23274,24.82 237.76574,21.42 237.76574,16.218 C 237.76574,11.016 241.23374,7.616 245.95974,7.616 C 250.68574,7.616 254.15374,11.016 254.15374,16.218 z M 250.14174,16.218 C 250.14174,12.546 248.57874,10.506 245.95974,10.506 C 243.34074,10.506 241.77774,12.546 241.77774,16.218 C 241.77774,19.89 243.34074,21.93 245.95974,21.93 C 248.57874,21.93 250.14174,19.891 250.14174,16.218 z"
+ id="path3278" />
+ <path
+ style="fill:#000000"
+ d="M 267.8887,22.063898 C 266.58161,23.867273 264.90584,24.82 262.72735,24.82 C 259.34231,24.82 257.39843,22.642339 257.39843,18.899485 L 257.39843,7.9431301 L 261.08511,7.9431301 L 261.08511,17.062084 C 261.08511,20.226497 261.45378,21.927794 264.03445,21.927794 C 266.31348,21.927794 267.95573,19.818186 267.95573,16.721824 L 267.95573,7.9431301 L 271.6424,7.9431301 L 271.6424,24.479741 L 268.05628,24.479741 L 267.95474,22.063898 L 267.8887,22.063898 z"
+ id="path3280" />
+ <path
+ style="fill:#000000"
+ d="M 279.95412,10.358155 C 281.26762,8.5546424 282.91792,7.6018432 285.13978,7.6018432 C 288.54242,7.6018432 290.49485,9.7796698 290.49485,13.522809 L 290.49485,24.48 L 286.79109,24.48 L 286.79109,15.36035 C 286.79109,12.195697 286.38692,10.494269 283.82727,10.494269 C 281.5024,10.494269 279.88578,12.638067 279.88578,15.700636 L 279.88578,24.48 L 276.18101,24.48 L 276.18101,7.9421286 L 279.78572,7.9421286 L 279.88677,10.358155 L 279.95412,10.358155 L 279.95412,10.358155 z"
+ id="path3282" />
+ <path
+ style="fill:#000000"
+ d="M 300.95303,24.82 C 296.42828,24.82 293.70502,21.383151 293.70502,16.517117 C 293.70502,11.344829 296.73353,7.6017268 301.1572,7.6017268 C 303.47212,7.6017268 305.03642,8.452432 306.36352,10.187871 L 306.43157,10.187871 L 306.43157,-0.02059181 L 310.17368,-0.02059181 L 310.17368,24.479718 L 306.53265,24.479718 L 306.43057,22.233856 L 306.36251,22.233856 C 304.96736,23.936267 303.29998,24.82 300.95303,24.82 z M 302.10999,10.494124 C 299.14953,10.494124 297.72035,12.774014 297.72035,16.244891 C 297.72035,19.681741 299.2166,21.927603 302.17704,21.927603 C 304.79722,21.927603 306.43157,19.919938 306.43157,16.891428 L 306.43157,15.530299 C 306.43157,12.331648 304.59305,10.494124 302.10999,10.494124 z"
+ id="path3284" />
+ <path
+ style="fill:#000000"
+ d="M 327.13912,13.293431 L 327.13912,24.478977 L 323.48917,24.478977 L 323.38686,22.160023 L 323.31866,22.160023 C 322.3638,23.865136 320.76099,24.82 318.57845,24.82 C 315.81617,24.82 313.3608,22.739761 313.3608,19.465942 C 313.3608,15.407772 317.31566,13.804965 320.99971,13.804965 C 321.92047,13.804965 322.70382,13.907272 323.38686,14.009579 L 323.38686,13.634454 C 323.38686,11.520113 322.32869,10.462942 319.80613,10.462942 C 318.61255,10.462942 317.04385,10.769863 315.54335,11.417806 L 315.16822,8.5873172 C 316.90744,7.8711694 318.71486,7.564249 320.52228,7.564249 C 324.88837,7.564249 327.13912,9.6444877 327.13912,13.293431 z M 323.38788,16.362636 C 322.77403,16.260329 322.02378,16.192125 321.23842,16.192125 C 319.22639,16.192125 317.45407,17.112886 317.45407,19.261329 C 317.45407,21.102852 318.47714,22.057716 320.04585,22.057716 C 321.92147,22.057716 323.38788,20.250295 323.38788,17.317499 L 323.38788,16.362636 z"
+ id="path3286" />
+ <path
+ style="fill:#000000"
+ d="M 340.41792,10.810029 L 336.32742,10.810029 L 336.32742,19.570522 C 336.32742,21.445335 337.28187,21.922561 338.61128,21.922561 C 339.32712,21.922561 339.77026,21.854386 340.48609,21.615773 L 340.86106,24.376863 C 339.87253,24.68365 338.71255,24.82 337.2127,24.82 C 334.51978,24.82 332.57679,23.524674 332.57679,20.490884 L 332.57679,10.810029 L 329.88388,10.810029 L 329.88388,7.9125894 L 332.57679,7.9125894 L 332.57679,4.162962 L 336.32642,4.162962 L 336.32642,7.9125894 L 340.41692,7.9125894 L 340.41692,10.810029 L 340.41792,10.810029 z"
+ id="path3288" />
+ <path
+ style="fill:#000000"
+ d="M 343.61816,3.7929297 C 343.61816,2.5660193 344.6065,1.577675 345.83341,1.577675 C 347.06132,1.577675 348.04866,2.5660193 348.04866,3.7929297 C 348.04866,5.0198399 347.06132,6.0081843 345.83341,6.0081843 C 344.6075,6.0081843 343.61816,5.0198399 343.61816,3.7929297 z M 343.95896,7.9167114 L 347.70786,7.9167114 L 347.70786,24.48 L 343.95896,24.48 L 343.95896,7.9167114 z"
+ id="path3290" />
+ <path
+ style="fill:#000000"
+ d="M 367.46488,16.192768 C 367.46488,21.410027 363.9857,24.82 359.24684,24.82 C 354.50597,24.82 351.0288,21.410027 351.0288,16.192768 C 351.0288,10.975509 354.50698,7.565536 359.24684,7.565536 C 363.9857,7.565536 367.46488,10.975509 367.46488,16.192768 z M 363.44011,16.192768 C 363.44011,12.509997 361.87251,10.464013 359.24583,10.464013 C 356.61915,10.464013 355.05157,12.509997 355.05157,16.192768 C 355.05157,19.875539 356.61915,21.921523 359.24583,21.921523 C 361.87251,21.921523 363.44011,19.876542 363.44011,16.192768 z"
+ id="path3292" />
+ <path
+ style="fill:#000000"
+ d="M 374.56395,10.357078 C 375.89116,8.553428 377.55869,7.6005562 379.80374,7.6005562 C 383.24189,7.6005562 385.2147,9.778549 385.2147,13.521974 L 385.2147,24.48 L 381.47228,24.48 L 381.47228,15.359656 C 381.47228,12.19476 381.0639,10.493203 378.47753,10.493203 C 376.12839,10.493203 374.49489,12.637165 374.49489,15.699967 L 374.49489,24.48 L 370.75146,24.48 L 370.75146,7.9408675 L 374.3938,7.9408675 L 374.49589,10.357078 L 374.56395,10.357078 L 374.56395,10.357078 z"
+ id="path3294" />
+ </g>
+ <g
+ style="fill:#000000"
+ transform="translate(0,-8.52e-3)"
+ id="g2496">
+ <path
+ style="fill:#18a303;fill-opacity:1"
+ d="M 288.61033,302.30636 C 288.61033,316.95039 276.54431,324.37515 259.73741,324.37515 C 253.96283,324.37515 246.74356,323.75659 240.76141,322.93047 L 240.76141,254.97429 C 248.18617,254.04646 256.22949,253.42582 261.38551,253.42582 C 277.78143,253.42582 286.75466,260.7468 286.75466,270.95714 C 286.75466,278.3819 281.49485,283.84721 274.79243,286.21973 L 274.79243,286.42522 C 283.6598,289.10702 288.61033,294.15926 288.61033,302.30636 z M 261.38551,282.7118 C 268.19172,282.7118 271.69757,279.61902 271.69757,273.63686 C 271.69757,268.06778 268.60478,264.45814 261.59101,264.45814 C 259.83705,264.45814 257.15732,264.56193 254.57931,264.97499 L 254.57931,282.7118 L 261.38551,282.7118 z M 254.57931,293.33313 L 254.57931,312.92562 C 257.36282,313.2349 260.04462,313.33868 262.20957,313.33868 C 269.42883,313.33868 273.75873,310.14211 273.75873,303.74897 C 273.75873,296.73727 270.04531,293.33313 261.69272,293.33313 L 254.57931,293.33313 z"
+ id="path2451" />
+ <path
+ style="fill:#18a303;fill-opacity:1"
+ d="M 328.80624,285.90837 C 324.26877,286.11594 320.96842,286.93999 318.18491,288.89945 C 314.98834,291.16818 313.13059,294.77782 313.13059,304.88438 L 313.13059,323.8583 L 299.31269,323.8583 L 299.31269,273.53516 L 312.82132,273.53516 L 313.13059,282.50631 L 313.33816,282.50631 C 316.22545,276.93722 322.51481,272.91452 329.11552,272.50354 L 328.80624,285.90837 z"
+ id="path2453" />
+ <path
+ style="fill:#000000"
+ d="M 402.97074,288.89945 C 402.97074,312.51463 385.64491,324.88785 368.11567,324.88785 C 350.58435,324.88785 333.2606,312.51463 333.2606,288.89945 C 333.2606,265.28427 350.58643,252.91105 368.11567,252.91105 C 385.64699,252.91105 402.97074,265.28427 402.97074,288.89945 z M 390.38995,288.89945 C 390.38995,271.16264 381.00574,262.0877 368.11567,262.0877 C 355.22561,262.0877 345.84139,271.16264 345.84139,288.89945 C 345.84139,306.63626 355.22561,315.7112 368.11567,315.7112 C 381.00574,315.7112 390.38995,306.63626 390.38995,288.89945 z"
+ id="path2455" />
+ <path
+ style="fill:#000000"
+ d="M 436.85305,248.57908 C 440.04962,248.57908 442.73142,249.19763 444.89637,250.02376 L 443.76304,258.37636 C 442.01115,257.7578 440.04962,257.34474 437.57539,257.34474 C 430.35612,257.34474 426.3355,262.50076 426.3355,270.85336 L 426.3355,273.74065 L 438.91629,273.74065 L 438.91629,282.50631 L 426.3355,282.50631 L 426.3355,323.8583 L 414.99183,323.8583 L 414.99183,282.50631 L 406.74094,282.50631 L 406.74094,273.74065 L 414.99183,273.74065 L 414.99183,272.39975 C 414.99183,257.55023 423.54992,248.57908 436.85305,248.57908 z"
+ id="path2457" />
+ <path
+ style="fill:#000000"
+ d="M 466.9653,248.57908 C 470.16187,248.57908 472.84366,249.19763 475.00861,250.02376 L 473.87528,258.37636 C 472.1234,257.7578 470.16187,257.34474 467.68764,257.34474 C 460.46837,257.34474 456.44775,262.50076 456.44775,270.85336 L 456.44775,273.74065 L 469.02854,273.74065 L 469.02854,282.50631 L 456.44775,282.50631 L 456.44775,323.8583 L 445.10408,323.8583 L 445.10408,282.50631 L 436.85319,282.50631 L 436.85319,273.74065 L 445.10408,273.74065 L 445.10408,272.39975 C 445.10408,257.55023 453.66217,248.57908 466.9653,248.57908 z"
+ id="path2459" />
+ <path
+ style="fill:#000000"
+ d="M 476.55998,261.26365 C 476.55998,257.55023 479.55106,254.56123 483.2624,254.56123 C 486.97374,254.56123 489.96482,257.55023 489.96482,261.26365 C 489.96482,264.97707 486.97374,267.96607 483.2624,267.96607 C 479.54898,267.96607 476.55998,264.97499 476.55998,261.26365 z M 477.58953,273.74065 L 488.9332,273.74065 L 488.9332,323.8583 L 477.58953,323.8583 L 477.58953,273.74065 z"
+ id="path2461" />
+ <path
+ style="fill:#000000"
+ d="M 524.07112,316.12426 C 528.09381,316.12426 532.73299,315.09264 536.54812,313.44247 L 537.68145,322.00263 C 534.07182,323.75452 528.5048,324.88992 521.59481,324.88992 C 506.33223,324.88992 496.43324,314.88715 496.43324,299.93592 C 496.43324,282.71388 508.08619,272.7111 523.75976,272.7111 C 530.25669,272.7111 535.61821,274.15371 538.1983,275.70218 L 537.06497,284.26235 C 533.86632,282.71388 529.64021,281.47676 524.89724,281.47676 C 515.20375,281.47676 508.60304,287.14756 508.60304,298.59502 C 508.60096,310.14419 514.58312,316.12426 524.07112,316.12426 z"
+ id="path2463" />
+ <path
+ style="fill:#000000"
+ d="M 570.32982,316.12426 C 575.17657,316.12426 579.50647,315.09264 583.73466,313.23697 L 584.86799,321.79714 C 579.71196,324.16966 574.969,324.88992 568.2645,324.88992 C 553.62047,324.88992 543.3105,316.53733 543.3105,299.93592 C 543.3105,283.95099 554.03561,272.7111 568.36829,272.7111 C 581.25835,272.7111 588.57933,283.12694 588.57933,294.77989 C 588.57933,297.35791 588.47554,299.72835 588.16627,301.89538 L 554.96137,301.89538 C 555.58201,310.86445 560.74011,316.12426 570.32982,316.12426 z M 577.54701,293.5407 C 577.23773,286.83828 574.7635,281.47469 567.44045,281.47469 C 560.63425,281.47469 556.61363,286.11594 555.47822,293.5407 L 577.54701,293.5407 z"
+ id="path2465" />
+ <path
+ style="fill:#18a303;fill-opacity:1"
+ d="M 619.87131,321.0748 L 621.00464,312.10364 C 626.77923,314.68166 632.14282,315.71328 637.29885,315.71328 C 646.06451,315.71328 651.52981,311.69058 651.52981,305.09195 C 651.52981,299.42115 646.06451,294.47061 635.33939,293.95584 L 635.33939,285.19018 C 644.10505,284.57163 649.67206,279.72488 649.67206,273.53723 C 649.67206,267.76265 644.82532,264.15301 638.22668,264.15301 C 634.20399,264.15301 629.7703,265.18464 625.33662,267.45337 L 624.20329,258.48222 C 629.66859,256.1097 634.9284,254.97637 641.11397,254.97637 C 653.28377,254.97637 662.25493,261.67879 662.25493,271.37228 C 662.25493,279.82866 655.13944,285.39775 647.30162,287.66649 L 647.30162,287.87406 C 656.89341,289.62594 664.1106,295.7098 664.1106,304.47754 C 664.1106,317.5731 652.45765,324.89407 636.782,324.89407 C 630.80192,324.88992 624.51049,323.65073 619.87131,321.0748 z"
+ id="path2467" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ id="g4297"
+ style="fill:#800000"
+ transform="translate(-1144.4568,291.80656)" />
+ <text
+ transform="scale(1.0168078,0.98347)"
+ font-size="103.091"
+ id="text2722"
+ style="font-size:48.89245605px;font-family:Vegur-Regular"
+ x="1320.4735"
+ y="360.42868" />
+ <text
+ transform="scale(0.9979479,1.0020563)"
+ font-size="103.091"
+ id="text2724"
+ style="font-size:91.03964996px;font-family:Vegur-Regular"
+ x="1195.0607"
+ y="240.53946" />
+ </g>
+</svg>
diff --git a/setup_native/source/win32/nsis/brobitmap.bmp b/setup_native/source/win32/nsis/brobitmap.bmp
new file mode 100644
index 000000000000..680c643bff56
--- /dev/null
+++ b/setup_native/source/win32/nsis/brobitmap.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/brobitmap.svg b/setup_native/source/win32/nsis/brobitmap.svg
new file mode 100644
index 000000000000..084b5cea73fe
--- /dev/null
+++ b/setup_native/source/win32/nsis/brobitmap.svg
@@ -0,0 +1,1011 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="163"
+ height="312.00006"
+ id="svg3270"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="Installation (install_OOorg3_standard).svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0">
+ <defs
+ id="defs3272">
+ <linearGradient
+ id="linearGradient7426">
+ <stop
+ id="stop7428"
+ offset="0"
+ style="stop-color:#f2f2f2;stop-opacity:1" />
+ <stop
+ id="stop7430"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective3278" />
+ <inkscape:perspective
+ id="perspective2777"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7426"
+ id="linearGradient2551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2963636,0,0,0.109589,464.0661,256.3074)"
+ x1="286.08203"
+ y1="-1.6191231"
+ x2="286.08203"
+ y2="357.27634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7426"
+ id="linearGradient2576"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2963636,0,0,0.109589,464.0661,527.3074)"
+ x1="275.5"
+ y1="369.22446"
+ x2="275.5"
+ y2="-3.224514" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7426"
+ id="linearGradient2648"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2963636,0,0,0.109589,464.0661,527.3074)"
+ x1="275.5"
+ y1="369.22446"
+ x2="275.5"
+ y2="-3.224514" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7426"
+ id="linearGradient2650"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2963636,0,0,0.109589,464.0661,256.3074)"
+ x1="286.08203"
+ y1="-1.6191231"
+ x2="286.08203"
+ y2="357.27634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7426"
+ id="linearGradient2687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2963636,0,0,0.109589,464.0661,256.3074)"
+ x1="286.08203"
+ y1="-1.6191231"
+ x2="286.08203"
+ y2="357.27634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7426"
+ id="linearGradient2712"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2963636,0,0,0.109589,464.0661,527.3074)"
+ x1="275.5"
+ y1="369.22446"
+ x2="275.5"
+ y2="-3.224514" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4800" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective3742" />
+ <inkscape:perspective
+ id="perspective3744"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2870" />
+ <inkscape:perspective
+ id="perspective2558"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2531" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2854" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ id="perspective4034" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ id="perspective3939" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ id="perspective3852" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 21.26 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="62.360001 : 21.26 : 1"
+ inkscape:persp3d-origin="31.18 : 14.173333 : 1"
+ id="perspective3771" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ id="perspective59" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective3532" />
+ <inkscape:perspective
+ id="perspective2543"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2818"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7426"
+ id="linearGradient2557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2963636,0,0,0.109589,464.0661,256.3074)"
+ x1="286.08203"
+ y1="-1.6191231"
+ x2="286.08203"
+ y2="357.27634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7426"
+ id="linearGradient2582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2963636,0,0,0.109589,464.0661,527.3074)"
+ x1="275.5"
+ y1="369.22446"
+ x2="275.5"
+ y2="-3.224514" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2521" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4715" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4717" />
+ <inkscape:perspective
+ id="perspective4719"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4721"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4723"
+ inkscape:persp3d-origin="31.18 : 14.173333 : 1"
+ inkscape:vp_z="62.360001 : 21.26 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 21.26 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4725"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4727"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4729"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4731"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4733"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4735" />
+ <inkscape:perspective
+ id="perspective4737"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4739" />
+ <inkscape:perspective
+ id="perspective4741"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4743"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective4211" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 12.41 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="391.03 : 12.41 : 1"
+ inkscape:persp3d-origin="195.515 : 8.2733332 : 1"
+ id="perspective3301" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 12.41 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="399.49701 : 12.41 : 1"
+ inkscape:persp3d-origin="199.7485 : 8.2733332 : 1"
+ id="perspective3226" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 18.512501 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="393.207 : 18.512501 : 1"
+ inkscape:persp3d-origin="196.6035 : 12.341667 : 1"
+ id="perspective3158" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 18.512501 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="393.207 : 18.512501 : 1"
+ inkscape:persp3d-origin="196.6035 : 12.341667 : 1"
+ id="perspective3146" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2738" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2736" />
+ <inkscape:perspective
+ id="perspective2734"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2732"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2730"
+ inkscape:persp3d-origin="31.18 : 14.173333 : 1"
+ inkscape:vp_z="62.360001 : 21.26 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 21.26 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2728"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2726"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2724"
+ inkscape:persp3d-origin="420.94501 : 198.42668 : 1"
+ inkscape:vp_z="841.89001 : 297.64001 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 297.64001 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2722"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2720"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2753" />
+ <inkscape:perspective
+ id="perspective2717"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective2715" />
+ <inkscape:perspective
+ id="perspective2713"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2711"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 18.512501 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="401.944 : 18.512501 : 1"
+ inkscape:persp3d-origin="200.972 : 12.341667 : 1"
+ id="perspective2645" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 18.512501 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="385.51999 : 18.512501 : 1"
+ inkscape:persp3d-origin="192.75999 : 12.341667 : 1"
+ id="perspective2633" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 48.070499 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="212.035 : 48.070499 : 1"
+ inkscape:persp3d-origin="106.0175 : 32.047 : 1"
+ id="perspective2474" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 48.070499 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="212.035 : 48.070499 : 1"
+ inkscape:persp3d-origin="106.0175 : 32.047 : 1"
+ id="perspective2426" />
+ <inkscape:perspective
+ id="perspective2705"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.86454968"
+ inkscape:cx="61.810684"
+ inkscape:cy="115.50357"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1264"
+ inkscape:window-height="750"
+ inkscape:window-x="0"
+ inkscape:window-y="14"
+ showguides="true"
+ inkscape:guide-bbox="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="19.710938,118.07812"
+ id="guide2516" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="20,118.55078"
+ id="guide2518" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="21.710938,88.113281"
+ id="guide2520" />
+ <sodipodi:guide
+ orientation="1,0"
+ position="145.44141,87.875"
+ id="guide2522" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata3275">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Camada 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-464.21428,-256.36217)">
+ <g
+ id="g3083"
+ inkscape:export-filename="C:\Users\Marcelo\Desktop\Trabalhos\LibreOffice\Finais\Telas\Installation (install_OOorg3_standard).png"
+ inkscape:export-xdpi="89.956017"
+ inkscape:export-ydpi="89.956017">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect11604"
+ width="163"
+ height="312"
+ x="464.29398"
+ y="256.65631"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/install_OOorg3_standard.bmp.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="matrix(0.2304648,0,0,0.2304648,294.59926,364.26495)"
+ id="g3049">
+ <g
+ id="g3252"
+ transform="matrix(1.1041871,0,0,1.1275051,876.92792,475.41355)"
+ style="fill:#000000">
+ <path
+ id="path3254"
+ d="M 17.816,4.488 L 10.744,4.488 L 10.744,24.48 L 7.004,24.48 L 7.004,4.488 L 0,4.488 L 0,1.428 L 17.816,1.428 L 17.816,4.488 z"
+ style="fill:#000000" />
+ <path
+ id="path3256"
+ d="M 23.604186,10.37 C 24.930186,8.568 26.596186,7.616 28.840186,7.616 C 32.274186,7.616 34.246186,9.792 34.246186,13.532 L 34.246186,24.48 L 30.506186,24.48 L 30.506186,15.368 C 30.506186,12.206 30.098186,10.506 27.514186,10.506 C 25.168186,10.506 23.536186,12.648 23.536186,15.708 L 23.536186,24.48 L 19.796186,24.48 L 19.796186,2.9698466e-14 L 23.536186,2.9698466e-14 L 23.536186,10.37 L 23.604186,10.37 z"
+ style="fill:#000000" />
+ <path
+ id="path3258"
+ d="M 46.298814,21.931 C 47.896814,21.931 49.324814,21.591 50.718814,20.979 L 51.092814,23.801 C 49.392814,24.583 47.828814,24.821 45.618814,24.821 C 40.790814,24.821 37.389814,22.067 37.389814,16.593 C 37.389814,11.323 40.925814,7.617 45.651814,7.617 C 49.901814,7.617 52.315814,11.051 52.315814,14.893 C 52.315814,15.743 52.281814,16.525 52.179814,17.239 L 41.232814,17.239 C 41.436814,20.196 43.135814,21.931 46.298814,21.931 z M 48.677814,14.484 C 48.575814,12.274 47.759814,10.506 45.345814,10.506 C 43.101814,10.506 41.775814,12.036 41.401814,14.484 L 48.677814,14.484 z"
+ style="fill:#000000" />
+ <path
+ id="path3260"
+ d="M 70.02901,1.258 C 78.35901,1.258 83.22101,5.134 83.22101,12.546 C 83.22101,20.774 76.18301,24.65 69.58701,24.65 C 67.30901,24.65 64.96301,24.548 62.92301,24.344 L 62.92301,1.632 C 65.23501,1.394 68.05701,1.258 70.02901,1.258 z M 66.66301,21.522 C 67.68301,21.59 68.87301,21.624 69.92701,21.624 C 74.85701,21.624 79.07301,18.904 79.07301,12.954 C 79.07301,7.344 75.60501,4.284 69.96101,4.284 C 68.87301,4.284 67.51301,4.318 66.66301,4.42 L 66.66301,21.522 z"
+ style="fill:#000000" />
+ <path
+ id="path3262"
+ d="M 101.66244,16.218 C 101.66244,21.42 98.194443,24.82 93.468443,24.82 C 88.742443,24.82 85.274443,21.42 85.274443,16.218 C 85.274443,11.016 88.742443,7.616 93.468443,7.616 C 98.194443,7.616 101.66244,11.016 101.66244,16.218 z M 97.651443,16.218 C 97.651443,12.546 96.087443,10.506 93.469443,10.506 C 90.851443,10.506 89.287443,12.546 89.287443,16.218 C 89.287443,19.89 90.851443,21.93 93.469443,21.93 C 96.087443,21.93 97.651443,19.891 97.651443,16.218 z"
+ style="fill:#000000" />
+ <path
+ id="path3264"
+ d="M 113.02567,21.931 C 114.35167,21.931 115.88167,21.591 117.13967,21.047 L 117.51367,23.869 C 116.32367,24.447 114.48767,24.821 112.20967,24.821 C 107.17767,24.821 103.91367,21.523 103.91367,16.593 C 103.91367,10.915 107.75567,7.617 112.92367,7.617 C 115.06567,7.617 116.83367,8.093 117.68367,8.603 L 117.30967,11.425 C 116.25567,10.915 114.86167,10.507 113.29767,10.507 C 110.10167,10.507 107.92567,12.377 107.92567,16.151 C 107.92567,19.958 109.89767,21.931 113.02567,21.931 z"
+ style="fill:#000000" />
+ <path
+ id="path3266"
+ d="M 131.29089,22.066 C 129.96489,23.868 128.26489,24.82 126.05489,24.82 C 122.62089,24.82 120.64889,22.644 120.64889,18.904 L 120.64889,7.956 L 124.38889,7.956 L 124.38889,17.068 C 124.38889,20.23 124.76289,21.93 127.38089,21.93 C 129.69289,21.93 131.35889,19.822 131.35889,16.728 L 131.35889,7.956 L 135.09889,7.956 L 135.09889,24.48 L 131.46089,24.48 L 131.35889,22.066 L 131.29089,22.066 z"
+ style="fill:#000000" />
+ <path
+ id="path3268"
+ d="M 152.78142,11.05 C 154.09704,8.432 156.01986,7.616 157.97641,7.616 C 161.14737,7.616 162.96899,9.588 162.96899,13.226 L 162.96899,24.48 L 159.25829,24.48 L 159.25829,14.382 C 159.25829,11.628 158.48241,10.506 156.6608,10.506 C 154.46811,10.506 153.08503,12.614 153.08503,16.388 L 153.08503,24.48 L 149.37432,24.48 L 149.37432,14.382 C 149.37432,11.628 148.59845,10.506 146.77683,10.506 C 144.58414,10.506 143.20106,12.75 143.20106,16.388 L 143.20106,24.48 L 139.49036,24.48 L 139.49036,7.956 L 143.09986,7.956 L 143.20106,10.37 L 143.26853,10.37 C 144.34801,8.636 145.86602,7.616 148.09244,7.616 C 150.2514,7.616 152.03928,8.568 152.68022,11.05 L 152.78142,11.05 z"
+ style="fill:#000000" />
+ <path
+ id="path3270"
+ d="M 175.00552,21.931 C 176.60352,21.931 178.03152,21.591 179.42552,20.979 L 179.79952,23.801 C 178.09952,24.583 176.53552,24.821 174.32552,24.821 C 169.49752,24.821 166.09652,22.067 166.09652,16.593 C 166.09652,11.323 169.63252,7.617 174.35852,7.617 C 178.60852,7.617 181.02252,11.051 181.02252,14.893 C 181.02252,15.743 180.98852,16.525 180.88652,17.239 L 169.93852,17.239 C 170.14452,20.196 171.84352,21.931 175.00552,21.931 z M 177.38552,14.484 C 177.28352,12.274 176.46752,10.506 174.05352,10.506 C 171.80952,10.506 170.48352,12.036 170.10952,14.484 L 177.38552,14.484 z"
+ style="fill:#000000" />
+ <path
+ id="path3272"
+ d="M 188.24105,10.37 C 189.56705,8.568 191.23305,7.616 193.47705,7.616 C 196.91105,7.616 198.88305,9.792 198.88305,13.532 L 198.88305,24.48 L 195.14305,24.48 L 195.14305,15.368 C 195.14305,12.206 194.73505,10.506 192.15105,10.506 C 189.80505,10.506 188.17305,12.648 188.17305,15.708 L 188.17305,24.48 L 184.43305,24.48 L 184.43305,7.956 L 188.07105,7.956 L 188.17305,10.37 L 188.24105,10.37 L 188.24105,10.37 z"
+ style="fill:#000000" />
+ <path
+ id="path3274"
+ d="M 212.15806,10.846 L 208.07806,10.846 L 208.07806,19.584 C 208.07806,21.454 209.03006,21.93 210.35606,21.93 C 211.07006,21.93 211.51206,21.862 212.22606,21.624 L 212.60006,24.378 C 211.61406,24.684 210.45806,24.82 208.96206,24.82 C 206.27606,24.82 204.33806,23.528 204.33806,20.502 L 204.33806,10.846 L 201.65206,10.846 L 201.65206,7.956 L 204.33806,7.956 L 204.33806,4.216 L 208.07806,4.216 L 208.07806,7.956 L 212.15806,7.956 L 212.15806,10.846 z"
+ style="fill:#000000" />
+ <path
+ id="path3276"
+ d="M 223.13443,24.48 L 223.13443,1.428 L 235.98743,1.428 L 235.98743,4.488 L 226.87543,4.488 L 226.87543,11.39 L 234.83143,11.39 L 234.83143,14.416 L 226.87543,14.416 L 226.87543,24.48 L 223.13443,24.48 z"
+ style="fill:#000000" />
+ <path
+ id="path3278"
+ d="M 254.15374,16.218 C 254.15374,21.42 250.68474,24.82 245.95974,24.82 C 241.23274,24.82 237.76574,21.42 237.76574,16.218 C 237.76574,11.016 241.23374,7.616 245.95974,7.616 C 250.68574,7.616 254.15374,11.016 254.15374,16.218 z M 250.14174,16.218 C 250.14174,12.546 248.57874,10.506 245.95974,10.506 C 243.34074,10.506 241.77774,12.546 241.77774,16.218 C 241.77774,19.89 243.34074,21.93 245.95974,21.93 C 248.57874,21.93 250.14174,19.891 250.14174,16.218 z"
+ style="fill:#000000" />
+ <path
+ id="path3280"
+ d="M 267.8887,22.063898 C 266.58161,23.867273 264.90584,24.82 262.72735,24.82 C 259.34231,24.82 257.39843,22.642339 257.39843,18.899485 L 257.39843,7.9431301 L 261.08511,7.9431301 L 261.08511,17.062084 C 261.08511,20.226497 261.45378,21.927794 264.03445,21.927794 C 266.31348,21.927794 267.95573,19.818186 267.95573,16.721824 L 267.95573,7.9431301 L 271.6424,7.9431301 L 271.6424,24.479741 L 268.05628,24.479741 L 267.95474,22.063898 L 267.8887,22.063898 z"
+ style="fill:#000000" />
+ <path
+ id="path3282"
+ d="M 279.95412,10.358155 C 281.26762,8.5546424 282.91792,7.6018432 285.13978,7.6018432 C 288.54242,7.6018432 290.49485,9.7796698 290.49485,13.522809 L 290.49485,24.48 L 286.79109,24.48 L 286.79109,15.36035 C 286.79109,12.195697 286.38692,10.494269 283.82727,10.494269 C 281.5024,10.494269 279.88578,12.638067 279.88578,15.700636 L 279.88578,24.48 L 276.18101,24.48 L 276.18101,7.9421286 L 279.78572,7.9421286 L 279.88677,10.358155 L 279.95412,10.358155 L 279.95412,10.358155 z"
+ style="fill:#000000" />
+ <path
+ id="path3284"
+ d="M 300.95303,24.82 C 296.42828,24.82 293.70502,21.383151 293.70502,16.517117 C 293.70502,11.344829 296.73353,7.6017268 301.1572,7.6017268 C 303.47212,7.6017268 305.03642,8.452432 306.36352,10.187871 L 306.43157,10.187871 L 306.43157,-0.02059181 L 310.17368,-0.02059181 L 310.17368,24.479718 L 306.53265,24.479718 L 306.43057,22.233856 L 306.36251,22.233856 C 304.96736,23.936267 303.29998,24.82 300.95303,24.82 z M 302.10999,10.494124 C 299.14953,10.494124 297.72035,12.774014 297.72035,16.244891 C 297.72035,19.681741 299.2166,21.927603 302.17704,21.927603 C 304.79722,21.927603 306.43157,19.919938 306.43157,16.891428 L 306.43157,15.530299 C 306.43157,12.331648 304.59305,10.494124 302.10999,10.494124 z"
+ style="fill:#000000" />
+ <path
+ id="path3286"
+ d="M 327.13912,13.293431 L 327.13912,24.478977 L 323.48917,24.478977 L 323.38686,22.160023 L 323.31866,22.160023 C 322.3638,23.865136 320.76099,24.82 318.57845,24.82 C 315.81617,24.82 313.3608,22.739761 313.3608,19.465942 C 313.3608,15.407772 317.31566,13.804965 320.99971,13.804965 C 321.92047,13.804965 322.70382,13.907272 323.38686,14.009579 L 323.38686,13.634454 C 323.38686,11.520113 322.32869,10.462942 319.80613,10.462942 C 318.61255,10.462942 317.04385,10.769863 315.54335,11.417806 L 315.16822,8.5873172 C 316.90744,7.8711694 318.71486,7.564249 320.52228,7.564249 C 324.88837,7.564249 327.13912,9.6444877 327.13912,13.293431 z M 323.38788,16.362636 C 322.77403,16.260329 322.02378,16.192125 321.23842,16.192125 C 319.22639,16.192125 317.45407,17.112886 317.45407,19.261329 C 317.45407,21.102852 318.47714,22.057716 320.04585,22.057716 C 321.92147,22.057716 323.38788,20.250295 323.38788,17.317499 L 323.38788,16.362636 z"
+ style="fill:#000000" />
+ <path
+ id="path3288"
+ d="M 340.41792,10.810029 L 336.32742,10.810029 L 336.32742,19.570522 C 336.32742,21.445335 337.28187,21.922561 338.61128,21.922561 C 339.32712,21.922561 339.77026,21.854386 340.48609,21.615773 L 340.86106,24.376863 C 339.87253,24.68365 338.71255,24.82 337.2127,24.82 C 334.51978,24.82 332.57679,23.524674 332.57679,20.490884 L 332.57679,10.810029 L 329.88388,10.810029 L 329.88388,7.9125894 L 332.57679,7.9125894 L 332.57679,4.162962 L 336.32642,4.162962 L 336.32642,7.9125894 L 340.41692,7.9125894 L 340.41692,10.810029 L 340.41792,10.810029 z"
+ style="fill:#000000" />
+ <path
+ id="path3290"
+ d="M 343.61816,3.7929297 C 343.61816,2.5660193 344.6065,1.577675 345.83341,1.577675 C 347.06132,1.577675 348.04866,2.5660193 348.04866,3.7929297 C 348.04866,5.0198399 347.06132,6.0081843 345.83341,6.0081843 C 344.6075,6.0081843 343.61816,5.0198399 343.61816,3.7929297 z M 343.95896,7.9167114 L 347.70786,7.9167114 L 347.70786,24.48 L 343.95896,24.48 L 343.95896,7.9167114 z"
+ style="fill:#000000" />
+ <path
+ id="path3292"
+ d="M 367.46488,16.192768 C 367.46488,21.410027 363.9857,24.82 359.24684,24.82 C 354.50597,24.82 351.0288,21.410027 351.0288,16.192768 C 351.0288,10.975509 354.50698,7.565536 359.24684,7.565536 C 363.9857,7.565536 367.46488,10.975509 367.46488,16.192768 z M 363.44011,16.192768 C 363.44011,12.509997 361.87251,10.464013 359.24583,10.464013 C 356.61915,10.464013 355.05157,12.509997 355.05157,16.192768 C 355.05157,19.875539 356.61915,21.921523 359.24583,21.921523 C 361.87251,21.921523 363.44011,19.876542 363.44011,16.192768 z"
+ style="fill:#000000" />
+ <path
+ id="path3294"
+ d="M 374.56395,10.357078 C 375.89116,8.553428 377.55869,7.6005562 379.80374,7.6005562 C 383.24189,7.6005562 385.2147,9.778549 385.2147,13.521974 L 385.2147,24.48 L 381.47228,24.48 L 381.47228,15.359656 C 381.47228,12.19476 381.0639,10.493203 378.47753,10.493203 C 376.12839,10.493203 374.49489,12.637165 374.49489,15.699967 L 374.49489,24.48 L 370.75146,24.48 L 370.75146,7.9408675 L 374.3938,7.9408675 L 374.49589,10.357078 L 374.56395,10.357078 L 374.56395,10.357078 z"
+ style="fill:#000000" />
+ </g>
+ <g
+ id="g2496"
+ transform="translate(636.32843,125.00871)"
+ style="fill:#000000">
+ <path
+ id="path2451"
+ d="M 288.61033,302.30636 C 288.61033,316.95039 276.54431,324.37515 259.73741,324.37515 C 253.96283,324.37515 246.74356,323.75659 240.76141,322.93047 L 240.76141,254.97429 C 248.18617,254.04646 256.22949,253.42582 261.38551,253.42582 C 277.78143,253.42582 286.75466,260.7468 286.75466,270.95714 C 286.75466,278.3819 281.49485,283.84721 274.79243,286.21973 L 274.79243,286.42522 C 283.6598,289.10702 288.61033,294.15926 288.61033,302.30636 z M 261.38551,282.7118 C 268.19172,282.7118 271.69757,279.61902 271.69757,273.63686 C 271.69757,268.06778 268.60478,264.45814 261.59101,264.45814 C 259.83705,264.45814 257.15732,264.56193 254.57931,264.97499 L 254.57931,282.7118 L 261.38551,282.7118 z M 254.57931,293.33313 L 254.57931,312.92562 C 257.36282,313.2349 260.04462,313.33868 262.20957,313.33868 C 269.42883,313.33868 273.75873,310.14211 273.75873,303.74897 C 273.75873,296.73727 270.04531,293.33313 261.69272,293.33313 L 254.57931,293.33313 z"
+ style="fill:#18a303;fill-opacity:1" />
+ <path
+ id="path2453"
+ d="M 328.80624,285.90837 C 324.26877,286.11594 320.96842,286.93999 318.18491,288.89945 C 314.98834,291.16818 313.13059,294.77782 313.13059,304.88438 L 313.13059,323.8583 L 299.31269,323.8583 L 299.31269,273.53516 L 312.82132,273.53516 L 313.13059,282.50631 L 313.33816,282.50631 C 316.22545,276.93722 322.51481,272.91452 329.11552,272.50354 L 328.80624,285.90837 z"
+ style="fill:#18a303;fill-opacity:1" />
+ <path
+ id="path2455"
+ d="M 402.97074,288.89945 C 402.97074,312.51463 385.64491,324.88785 368.11567,324.88785 C 350.58435,324.88785 333.2606,312.51463 333.2606,288.89945 C 333.2606,265.28427 350.58643,252.91105 368.11567,252.91105 C 385.64699,252.91105 402.97074,265.28427 402.97074,288.89945 z M 390.38995,288.89945 C 390.38995,271.16264 381.00574,262.0877 368.11567,262.0877 C 355.22561,262.0877 345.84139,271.16264 345.84139,288.89945 C 345.84139,306.63626 355.22561,315.7112 368.11567,315.7112 C 381.00574,315.7112 390.38995,306.63626 390.38995,288.89945 z"
+ style="fill:#000000" />
+ <path
+ id="path2457"
+ d="M 436.85305,248.57908 C 440.04962,248.57908 442.73142,249.19763 444.89637,250.02376 L 443.76304,258.37636 C 442.01115,257.7578 440.04962,257.34474 437.57539,257.34474 C 430.35612,257.34474 426.3355,262.50076 426.3355,270.85336 L 426.3355,273.74065 L 438.91629,273.74065 L 438.91629,282.50631 L 426.3355,282.50631 L 426.3355,323.8583 L 414.99183,323.8583 L 414.99183,282.50631 L 406.74094,282.50631 L 406.74094,273.74065 L 414.99183,273.74065 L 414.99183,272.39975 C 414.99183,257.55023 423.54992,248.57908 436.85305,248.57908 z"
+ style="fill:#000000" />
+ <path
+ id="path2459"
+ d="M 466.9653,248.57908 C 470.16187,248.57908 472.84366,249.19763 475.00861,250.02376 L 473.87528,258.37636 C 472.1234,257.7578 470.16187,257.34474 467.68764,257.34474 C 460.46837,257.34474 456.44775,262.50076 456.44775,270.85336 L 456.44775,273.74065 L 469.02854,273.74065 L 469.02854,282.50631 L 456.44775,282.50631 L 456.44775,323.8583 L 445.10408,323.8583 L 445.10408,282.50631 L 436.85319,282.50631 L 436.85319,273.74065 L 445.10408,273.74065 L 445.10408,272.39975 C 445.10408,257.55023 453.66217,248.57908 466.9653,248.57908 z"
+ style="fill:#000000" />
+ <path
+ id="path2461"
+ d="M 476.55998,261.26365 C 476.55998,257.55023 479.55106,254.56123 483.2624,254.56123 C 486.97374,254.56123 489.96482,257.55023 489.96482,261.26365 C 489.96482,264.97707 486.97374,267.96607 483.2624,267.96607 C 479.54898,267.96607 476.55998,264.97499 476.55998,261.26365 z M 477.58953,273.74065 L 488.9332,273.74065 L 488.9332,323.8583 L 477.58953,323.8583 L 477.58953,273.74065 z"
+ style="fill:#000000" />
+ <path
+ id="path2463"
+ d="M 524.07112,316.12426 C 528.09381,316.12426 532.73299,315.09264 536.54812,313.44247 L 537.68145,322.00263 C 534.07182,323.75452 528.5048,324.88992 521.59481,324.88992 C 506.33223,324.88992 496.43324,314.88715 496.43324,299.93592 C 496.43324,282.71388 508.08619,272.7111 523.75976,272.7111 C 530.25669,272.7111 535.61821,274.15371 538.1983,275.70218 L 537.06497,284.26235 C 533.86632,282.71388 529.64021,281.47676 524.89724,281.47676 C 515.20375,281.47676 508.60304,287.14756 508.60304,298.59502 C 508.60096,310.14419 514.58312,316.12426 524.07112,316.12426 z"
+ style="fill:#000000" />
+ <path
+ id="path2465"
+ d="M 570.32982,316.12426 C 575.17657,316.12426 579.50647,315.09264 583.73466,313.23697 L 584.86799,321.79714 C 579.71196,324.16966 574.969,324.88992 568.2645,324.88992 C 553.62047,324.88992 543.3105,316.53733 543.3105,299.93592 C 543.3105,283.95099 554.03561,272.7111 568.36829,272.7111 C 581.25835,272.7111 588.57933,283.12694 588.57933,294.77989 C 588.57933,297.35791 588.47554,299.72835 588.16627,301.89538 L 554.96137,301.89538 C 555.58201,310.86445 560.74011,316.12426 570.32982,316.12426 z M 577.54701,293.5407 C 577.23773,286.83828 574.7635,281.47469 567.44045,281.47469 C 560.63425,281.47469 556.61363,286.11594 555.47822,293.5407 L 577.54701,293.5407 z"
+ style="fill:#000000" />
+ <path
+ id="path2467"
+ d="M 619.87131,321.0748 L 621.00464,312.10364 C 626.77923,314.68166 632.14282,315.71328 637.29885,315.71328 C 646.06451,315.71328 651.52981,311.69058 651.52981,305.09195 C 651.52981,299.42115 646.06451,294.47061 635.33939,293.95584 L 635.33939,285.19018 C 644.10505,284.57163 649.67206,279.72488 649.67206,273.53723 C 649.67206,267.76265 644.82532,264.15301 638.22668,264.15301 C 634.20399,264.15301 629.7703,265.18464 625.33662,267.45337 L 624.20329,258.48222 C 629.66859,256.1097 634.9284,254.97637 641.11397,254.97637 C 653.28377,254.97637 662.25493,261.67879 662.25493,271.37228 C 662.25493,279.82866 655.13944,285.39775 647.30162,287.66649 L 647.30162,287.87406 C 656.89341,289.62594 664.1106,295.7098 664.1106,304.47754 C 664.1106,317.5731 652.45765,324.89407 636.782,324.89407 C 630.80192,324.88992 624.51049,323.65073 619.87131,321.0748 z"
+ style="fill:#18a303;fill-opacity:1" />
+ </g>
+ </g>
+ <rect
+ y="527.36218"
+ x="464.21429"
+ height="40"
+ width="163"
+ id="rect11610"
+ style="fill:url(#linearGradient2582);fill-opacity:1;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/install_OOorg3_standard.bmp.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ transform="translate(76.21425,-1536.3622)"
+ id="g11680"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/install_OOorg3_standard.bmp.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 432.93612,2084.725 C 432.18148,2084.706 431.43803,2085.1779 431.14306,2085.8632 C 430.84807,2086.5485 431.02025,2087.4039 431.55836,2087.9261 L 447.75462,2104.1736 C 448.27697,2104.6968 449.12749,2104.8703 449.81733,2104.5942 C 450.50718,2104.3182 450.99483,2103.6092 450.99999,2102.875 L 450.99999,2086.5974 C 451.00199,2085.6166 450.09611,2084.7233 449.10176,2084.725 L 432.93612,2084.725 L 432.93612,2084.725 z"
+ id="path11682"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 532.93616,1984.7249 C 532.18152,1984.7059 531.43807,1985.1778 531.1431,1985.8631 C 530.84811,1986.5484 531.02029,1987.4038 531.5584,1987.926 L 547.75466,2004.1735 C 548.27701,2004.6967 549.12753,2004.8702 549.81737,2004.5941 C 550.50722,2004.3181 550.99487,2003.6091 551.00003,2002.8749 L 551.00003,1986.5973 C 551.00203,1985.6165 550.09615,1984.7232 549.1018,1984.7249 L 532.93616,1984.7249 L 532.93616,1984.7249 z"
+ id="path11684"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11686"
+ d="M 532.93616,2084.7249 C 532.18152,2084.7059 531.43807,2085.1778 531.1431,2085.8631 C 530.84811,2086.5484 531.02029,2087.4038 531.5584,2087.926 L 547.75466,2104.1735 C 548.27701,2104.6967 549.12753,2104.8702 549.81737,2104.5941 C 550.50722,2104.3181 550.99487,2103.6091 551.00003,2102.8749 L 551.00003,2086.5973 C 551.00203,2085.6165 550.09615,2084.7232 549.1018,2084.7249 L 532.93616,2084.7249 L 532.93616,2084.7249 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.125;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 512.93616,2084.7249 C 512.18152,2084.7059 511.43807,2085.1778 511.1431,2085.8631 C 510.84811,2086.5484 511.02029,2087.4038 511.5584,2087.926 L 527.75466,2104.1735 C 528.27701,2104.6967 529.12753,2104.8702 529.81737,2104.5941 C 530.50722,2104.3181 530.99487,2103.6091 531.00003,2102.8749 L 531.00003,2086.5973 C 531.00203,2085.6165 530.09615,2084.7232 529.1018,2084.7249 L 512.93616,2084.7249 L 512.93616,2084.7249 z"
+ id="path11688"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11690"
+ d="M 492.93616,2084.7249 C 492.18152,2084.7059 491.43807,2085.1778 491.1431,2085.8631 C 490.84811,2086.5484 491.02029,2087.4038 491.5584,2087.926 L 507.75466,2104.1735 C 508.27701,2104.6967 509.12753,2104.8702 509.81737,2104.5941 C 510.50722,2104.3181 510.99487,2103.6091 511.00003,2102.8749 L 511.00003,2086.5973 C 511.00203,2085.6165 510.09615,2084.7232 509.1018,2084.7249 L 492.93616,2084.7249 L 492.93616,2084.7249 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.075;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 472.93616,2084.7249 C 472.18152,2084.7059 471.43807,2085.1778 471.1431,2085.8631 C 470.84811,2086.5484 471.02029,2087.4038 471.5584,2087.926 L 487.75466,2104.1735 C 488.27701,2104.6967 489.12753,2104.8702 489.81737,2104.5941 C 490.50722,2104.3181 490.99487,2103.6091 491.00003,2102.8749 L 491.00003,2086.5973 C 491.00203,2085.6165 490.09615,2084.7232 489.1018,2084.7249 L 472.93616,2084.7249 L 472.93616,2084.7249 z"
+ id="path11692"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11694"
+ d="M 452.93616,2084.7249 C 452.18152,2084.7059 451.43807,2085.1778 451.1431,2085.8631 C 450.84811,2086.5484 451.02029,2087.4038 451.5584,2087.926 L 467.75466,2104.1735 C 468.27701,2104.6967 469.12753,2104.8702 469.81737,2104.5941 C 470.50722,2104.3181 470.99487,2103.6091 471.00003,2102.8749 L 471.00003,2086.5973 C 471.00203,2085.6165 470.09615,2084.7232 469.1018,2084.7249 L 452.93616,2084.7249 L 452.93616,2084.7249 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 532.93616,2064.7249 C 532.18152,2064.7059 531.43807,2065.1778 531.1431,2065.8631 C 530.84811,2066.5484 531.02029,2067.4038 531.5584,2067.926 L 547.75466,2084.1735 C 548.27701,2084.6967 549.12753,2084.8702 549.81737,2084.5941 C 550.50722,2084.3181 550.99487,2083.6091 551.00003,2082.8749 L 551.00003,2066.5973 C 551.00203,2065.6165 550.09615,2064.7232 549.1018,2064.7249 L 532.93616,2064.7249 L 532.93616,2064.7249 z"
+ id="path11696"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11698"
+ d="M 512.93616,2064.7249 C 512.18152,2064.7059 511.43807,2065.1778 511.1431,2065.8631 C 510.84811,2066.5484 511.02029,2067.4038 511.5584,2067.926 L 527.75466,2084.1735 C 528.27701,2084.6967 529.12753,2084.8702 529.81737,2084.5941 C 530.50722,2084.3181 530.99487,2083.6091 531.00003,2082.8749 L 531.00003,2066.5973 C 531.00203,2065.6165 530.09615,2064.7232 529.1018,2064.7249 L 512.93616,2064.7249 L 512.93616,2064.7249 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.075;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 492.93616,2064.7249 C 492.18152,2064.7059 491.43807,2065.1778 491.1431,2065.8631 C 490.84811,2066.5484 491.02029,2067.4038 491.5584,2067.926 L 507.75466,2084.1735 C 508.27701,2084.6967 509.12753,2084.8702 509.81737,2084.5941 C 510.50722,2084.3181 510.99487,2083.6091 511.00003,2082.8749 L 511.00003,2066.5973 C 511.00203,2065.6165 510.09615,2064.7232 509.1018,2064.7249 L 492.93616,2064.7249 L 492.93616,2064.7249 z"
+ id="path11700"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11702"
+ d="M 472.93616,2064.7249 C 472.18152,2064.7059 471.43807,2065.1778 471.1431,2065.8631 C 470.84811,2066.5484 471.02029,2067.4038 471.5584,2067.926 L 487.75466,2084.1735 C 488.27701,2084.6967 489.12753,2084.8702 489.81737,2084.5941 C 490.50722,2084.3181 490.99487,2083.6091 491.00003,2082.8749 L 491.00003,2066.5973 C 491.00203,2065.6165 490.09615,2064.7232 489.1018,2064.7249 L 472.93616,2064.7249 L 472.93616,2064.7249 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 452.93616,2064.7249 C 452.18152,2064.7059 451.43807,2065.1778 451.1431,2065.8631 C 450.84811,2066.5484 451.02029,2067.4038 451.5584,2067.926 L 467.75466,2084.1735 C 468.27701,2084.6967 469.12753,2084.8702 469.81737,2084.5941 C 470.50722,2084.3181 470.99487,2083.6091 471.00003,2082.8749 L 471.00003,2066.5973 C 471.00203,2065.6165 470.09615,2064.7232 469.1018,2064.7249 L 452.93616,2064.7249 L 452.93616,2064.7249 z"
+ id="path11704"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11706"
+ d="M 532.93616,2044.7249 C 532.18152,2044.7059 531.43807,2045.1778 531.1431,2045.8631 C 530.84811,2046.5484 531.02029,2047.4038 531.5584,2047.926 L 547.75466,2064.1735 C 548.27701,2064.6967 549.12753,2064.8702 549.81737,2064.5941 C 550.50722,2064.3181 550.99487,2063.6091 551.00003,2062.8749 L 551.00003,2046.5973 C 551.00203,2045.6165 550.09615,2044.7232 549.1018,2044.7249 L 532.93616,2044.7249 L 532.93616,2044.7249 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.075;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 512.93616,2044.7249 C 512.18152,2044.7059 511.43807,2045.1778 511.1431,2045.8631 C 510.84811,2046.5484 511.02029,2047.4038 511.5584,2047.926 L 527.75466,2064.1735 C 528.27701,2064.6967 529.12753,2064.8702 529.81737,2064.5941 C 530.50722,2064.3181 530.99487,2063.6091 531.00003,2062.8749 L 531.00003,2046.5973 C 531.00203,2045.6165 530.09615,2044.7232 529.1018,2044.7249 L 512.93616,2044.7249 z"
+ id="path11708"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11710"
+ d="M 492.93616,2044.7249 C 492.18152,2044.7059 491.43807,2045.1778 491.1431,2045.8631 C 490.84811,2046.5484 491.02029,2047.4038 491.5584,2047.926 L 507.75466,2064.1735 C 508.27701,2064.6967 509.12753,2064.8702 509.81737,2064.5941 C 510.50722,2064.3181 510.99487,2063.6091 511.00003,2062.8749 L 511.00003,2046.5973 C 511.00203,2045.6165 510.09615,2044.7232 509.1018,2044.7249 L 492.93616,2044.7249 L 492.93616,2044.7249 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 472.93616,2044.7249 C 472.18152,2044.7059 471.43807,2045.1778 471.1431,2045.8631 C 470.84811,2046.5484 471.02029,2047.4038 471.5584,2047.926 L 487.75466,2064.1735 C 488.27701,2064.6967 489.12753,2064.8702 489.81737,2064.5941 C 490.50722,2064.3181 490.99487,2063.6091 491.00003,2062.8749 L 491.00003,2046.5973 C 491.00203,2045.6165 490.09615,2044.7232 489.1018,2044.7249 L 472.93616,2044.7249 L 472.93616,2044.7249 z"
+ id="path11712"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 532.93616,2024.7249 C 532.18152,2024.7059 531.43807,2025.1778 531.1431,2025.8631 C 530.84811,2026.5484 531.02029,2027.4038 531.5584,2027.926 L 547.75466,2044.1735 C 548.27701,2044.6967 549.12753,2044.8702 549.81737,2044.5941 C 550.50722,2044.3181 550.99487,2043.6091 551.00003,2042.8749 L 551.00003,2026.5973 C 551.00203,2025.6165 550.09615,2024.7232 549.1018,2024.7249 L 532.93616,2024.7249 L 532.93616,2024.7249 z"
+ id="path11714"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11716"
+ d="M 512.93616,2024.7249 C 512.18152,2024.7059 511.43807,2025.1778 511.1431,2025.8631 C 510.84811,2026.5484 511.02029,2027.4038 511.5584,2027.926 L 527.75466,2044.1735 C 528.27701,2044.6967 529.12753,2044.8702 529.81737,2044.5941 C 530.50722,2044.3181 530.99487,2043.6091 531.00003,2042.8749 L 531.00003,2026.5973 C 531.00203,2025.6165 530.09615,2024.7232 529.1018,2024.7249 L 512.93616,2024.7249 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 492.93616,2024.7249 C 492.18152,2024.7059 491.43807,2025.1778 491.1431,2025.8631 C 490.84811,2026.5484 491.02029,2027.4038 491.5584,2027.926 L 507.75466,2044.1735 C 508.27701,2044.6967 509.12753,2044.8702 509.81737,2044.5941 C 510.50722,2044.3181 510.99487,2043.6091 511.00003,2042.8749 L 511.00003,2026.5973 C 511.00203,2025.6165 510.09615,2024.7232 509.1018,2024.7249 L 492.93616,2024.7249 L 492.93616,2024.7249 z"
+ id="path11718"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11720"
+ d="M 532.93616,2004.7249 C 532.18152,2004.7059 531.43807,2005.1778 531.1431,2005.8631 C 530.84811,2006.5484 531.02029,2007.4038 531.5584,2007.926 L 547.75466,2024.1735 C 548.27701,2024.6967 549.12753,2024.8702 549.81737,2024.5941 C 550.50722,2024.3181 550.99487,2023.6091 551.00003,2022.8749 L 551.00003,2006.5973 C 551.00203,2005.6165 550.09615,2004.7232 549.1018,2004.7249 L 532.93616,2004.7249 L 532.93616,2004.7249 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 512.93616,2004.7249 C 512.18152,2004.7059 511.43807,2005.1778 511.1431,2005.8631 C 510.84811,2006.5484 511.02029,2007.4038 511.5584,2007.926 L 527.75466,2024.1735 C 528.27701,2024.6967 529.12753,2024.8702 529.81737,2024.5941 C 530.50722,2024.3181 530.99487,2023.6091 531.00003,2022.8749 L 531.00003,2006.5973 C 531.00203,2005.6165 530.09615,2004.7232 529.1018,2004.7249 L 512.93616,2004.7249 z"
+ id="path11722"
+ sodipodi:nodetypes="csccscccc" />
+ </g>
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/install_OOorg3_standard.bmp.png"
+ style="fill:url(#linearGradient2557);fill-opacity:1;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect11741"
+ width="163"
+ height="40"
+ x="464.21429"
+ y="256.36215" />
+ <g
+ transform="translate(464.21428,-2776.3622)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/install_OOorg3_standard.bmp.png"
+ id="g11959">
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 101.93612,3032.725 C 101.18148,3032.706 100.43803,3033.1779 100.14306,3033.8632 C 99.848073,3034.5485 100.02025,3035.4039 100.55836,3035.9261 L 116.75462,3052.1736 C 117.27697,3052.6968 118.12749,3052.8703 118.81733,3052.5942 C 119.50718,3052.3182 119.99483,3051.6092 119.99999,3050.875 L 119.99999,3034.5974 C 120.00199,3033.6166 119.09611,3032.7233 118.10176,3032.725 L 101.93612,3032.725 L 101.93612,3032.725 z"
+ id="path11745"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 1.9361232,3132.725 C 1.1814832,3132.706 0.4380332,3133.1779 0.1430632,3133.8632 C -0.1519268,3134.5485 0.0202532,3135.4039 0.5583632,3135.9261 L 16.754623,3152.1736 C 17.276973,3152.6968 18.127493,3152.8703 18.817333,3152.5942 C 19.507183,3152.3182 19.994833,3151.6092 19.999993,3150.875 L 19.999993,3134.5974 C 20.001993,3133.6166 19.096113,3132.7233 18.101763,3132.725 L 1.9361232,3132.725 L 1.9361232,3132.725 z"
+ id="path11747"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11749"
+ d="M 1.9361232,3032.725 C 1.1814832,3032.706 0.4380332,3033.1779 0.1430632,3033.8632 C -0.1519268,3034.5485 0.0202532,3035.4039 0.5583632,3035.9261 L 16.754623,3052.1736 C 17.276973,3052.6968 18.127493,3052.8703 18.817333,3052.5942 C 19.507183,3052.3182 19.994833,3051.6092 19.999993,3050.875 L 19.999993,3034.5974 C 20.001993,3033.6166 19.096113,3032.7233 18.101763,3032.725 L 1.9361232,3032.725 L 1.9361232,3032.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.125;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 21.936123,3032.725 C 21.181483,3032.706 20.438033,3033.1779 20.143063,3033.8632 C 19.848073,3034.5485 20.020253,3035.4039 20.558363,3035.9261 L 36.754623,3052.1736 C 37.276973,3052.6968 38.127493,3052.8703 38.817333,3052.5942 C 39.507183,3052.3182 39.994833,3051.6092 39.999993,3050.875 L 39.999993,3034.5974 C 40.001993,3033.6166 39.096113,3032.7233 38.101763,3032.725 L 21.936123,3032.725 L 21.936123,3032.725 z"
+ id="path11751"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11753"
+ d="M 41.936123,3032.725 C 41.181483,3032.706 40.438033,3033.1779 40.143063,3033.8632 C 39.848073,3034.5485 40.020253,3035.4039 40.558363,3035.9261 L 56.754623,3052.1736 C 57.276973,3052.6968 58.127493,3052.8703 58.817333,3052.5942 C 59.507183,3052.3182 59.994833,3051.6092 59.999993,3050.875 L 59.999993,3034.5974 C 60.001993,3033.6166 59.096113,3032.7233 58.101763,3032.725 L 41.936123,3032.725 L 41.936123,3032.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.075;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 61.936123,3032.725 C 61.181483,3032.706 60.438033,3033.1779 60.143063,3033.8632 C 59.848073,3034.5485 60.020253,3035.4039 60.558363,3035.9261 L 76.754623,3052.1736 C 77.276973,3052.6968 78.127493,3052.8703 78.817333,3052.5942 C 79.507183,3052.3182 79.994833,3051.6092 79.999993,3050.875 L 79.999993,3034.5974 C 80.001993,3033.6166 79.096113,3032.7233 78.101763,3032.725 L 61.936123,3032.725 L 61.936123,3032.725 z"
+ id="path11755"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11757"
+ d="M 81.936123,3032.725 C 81.181483,3032.706 80.438033,3033.1779 80.143063,3033.8632 C 79.848073,3034.5485 80.020253,3035.4039 80.558363,3035.9261 L 96.754623,3052.1736 C 97.276973,3052.6968 98.127493,3052.8703 98.817333,3052.5942 C 99.50718,3052.3182 99.99483,3051.6092 99.99999,3050.875 L 99.99999,3034.5974 C 100.00199,3033.6166 99.09611,3032.7233 98.101763,3032.725 L 81.936123,3032.725 L 81.936123,3032.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 1.9361232,3052.725 C 1.1814832,3052.706 0.4380332,3053.1779 0.1430632,3053.8632 C -0.1519268,3054.5485 0.0202532,3055.4039 0.5583632,3055.9261 L 16.754623,3072.1736 C 17.276973,3072.6968 18.127493,3072.8703 18.817333,3072.5942 C 19.507183,3072.3182 19.994833,3071.6092 19.999993,3070.875 L 19.999993,3054.5974 C 20.001993,3053.6166 19.096113,3052.7233 18.101763,3052.725 L 1.9361232,3052.725 L 1.9361232,3052.725 z"
+ id="path11759"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11761"
+ d="M 21.936123,3052.725 C 21.181483,3052.706 20.438033,3053.1779 20.143063,3053.8632 C 19.848073,3054.5485 20.020253,3055.4039 20.558363,3055.9261 L 36.754623,3072.1736 C 37.276973,3072.6968 38.127493,3072.8703 38.817333,3072.5942 C 39.507183,3072.3182 39.994833,3071.6092 39.999993,3070.875 L 39.999993,3054.5974 C 40.001993,3053.6166 39.096113,3052.7233 38.101763,3052.725 L 21.936123,3052.725 L 21.936123,3052.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.075;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 41.936123,3052.725 C 41.181483,3052.706 40.438033,3053.1779 40.143063,3053.8632 C 39.848073,3054.5485 40.020253,3055.4039 40.558363,3055.9261 L 56.754623,3072.1736 C 57.276973,3072.6968 58.127493,3072.8703 58.817333,3072.5942 C 59.507183,3072.3182 59.994833,3071.6092 59.999993,3070.875 L 59.999993,3054.5974 C 60.001993,3053.6166 59.096113,3052.7233 58.101763,3052.725 L 41.936123,3052.725 L 41.936123,3052.725 z"
+ id="path11763"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11765"
+ d="M 61.936123,3052.725 C 61.181483,3052.706 60.438033,3053.1779 60.143063,3053.8632 C 59.848073,3054.5485 60.020253,3055.4039 60.558363,3055.9261 L 76.754623,3072.1736 C 77.276973,3072.6968 78.127493,3072.8703 78.817333,3072.5942 C 79.507183,3072.3182 79.994833,3071.6092 79.999993,3070.875 L 79.999993,3054.5974 C 80.001993,3053.6166 79.096113,3052.7233 78.101763,3052.725 L 61.936123,3052.725 L 61.936123,3052.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 81.936123,3052.725 C 81.181483,3052.706 80.438033,3053.1779 80.143063,3053.8632 C 79.848073,3054.5485 80.020253,3055.4039 80.558363,3055.9261 L 96.754623,3072.1736 C 97.276973,3072.6968 98.127493,3072.8703 98.817333,3072.5942 C 99.50718,3072.3182 99.99483,3071.6092 99.99999,3070.875 L 99.99999,3054.5974 C 100.00199,3053.6166 99.09611,3052.7233 98.101763,3052.725 L 81.936123,3052.725 L 81.936123,3052.725 z"
+ id="path11767"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11769"
+ d="M 1.9361232,3072.725 C 1.1814832,3072.706 0.4380332,3073.1779 0.1430632,3073.8632 C -0.1519268,3074.5485 0.0202532,3075.4039 0.5583632,3075.9261 L 16.754623,3092.1736 C 17.276973,3092.6968 18.127493,3092.8703 18.817333,3092.5942 C 19.507183,3092.3182 19.994833,3091.6092 19.999993,3090.875 L 19.999993,3074.5974 C 20.001993,3073.6166 19.096113,3072.7233 18.101763,3072.725 L 1.9361232,3072.725 L 1.9361232,3072.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.075;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 21.936123,3072.725 C 21.181483,3072.706 20.438033,3073.1779 20.143063,3073.8632 C 19.848073,3074.5485 20.020253,3075.4039 20.558363,3075.9261 L 36.754623,3092.1736 C 37.276973,3092.6968 38.127493,3092.8703 38.817333,3092.5942 C 39.507183,3092.3182 39.994833,3091.6092 39.999993,3090.875 L 39.999993,3074.5974 C 40.001993,3073.6166 39.096113,3072.7233 38.101763,3072.725 L 21.936123,3072.725 L 21.936123,3072.725 z"
+ id="path11771"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11773"
+ d="M 41.936123,3072.725 C 41.181483,3072.706 40.438033,3073.1779 40.143063,3073.8632 C 39.848073,3074.5485 40.020253,3075.4039 40.558363,3075.9261 L 56.754623,3092.1736 C 57.276973,3092.6968 58.127493,3092.8703 58.817333,3092.5942 C 59.507183,3092.3182 59.994833,3091.6092 59.999993,3090.875 L 59.999993,3074.5974 C 60.001993,3073.6166 59.096113,3072.7233 58.101763,3072.725 L 41.936123,3072.725 L 41.936123,3072.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 61.936123,3072.725 C 61.181483,3072.706 60.438033,3073.1779 60.143063,3073.8632 C 59.848073,3074.5485 60.020253,3075.4039 60.558363,3075.9261 L 76.754623,3092.1736 C 77.276973,3092.6968 78.127493,3092.8703 78.817333,3092.5942 C 79.507183,3092.3182 79.994833,3091.6092 79.999993,3090.875 L 79.999993,3074.5974 C 80.001993,3073.6166 79.096113,3072.7233 78.101763,3072.725 L 61.936123,3072.725 L 61.936123,3072.725 z"
+ id="path11775"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.05;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 1.9361232,3092.725 C 1.1814832,3092.706 0.4380332,3093.1779 0.1430632,3093.8632 C -0.1519268,3094.5485 0.0202532,3095.4039 0.5583632,3095.9261 L 16.754623,3112.1736 C 17.276973,3112.6968 18.127493,3112.8703 18.817333,3112.5942 C 19.507183,3112.3182 19.994833,3111.6092 19.999993,3110.875 L 19.999993,3094.5974 C 20.001993,3093.6166 19.096113,3092.7233 18.101763,3092.725 L 1.9361232,3092.725 L 1.9361232,3092.725 z"
+ id="path11777"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11779"
+ d="M 21.936123,3092.725 C 21.181483,3092.706 20.438033,3093.1779 20.143063,3093.8632 C 19.848073,3094.5485 20.020253,3095.4039 20.558363,3095.9261 L 36.754623,3112.1736 C 37.276973,3112.6968 38.127493,3112.8703 38.817333,3112.5942 C 39.507183,3112.3182 39.994833,3111.6092 39.999993,3110.875 L 39.999993,3094.5974 C 40.001993,3093.6166 39.096113,3092.7233 38.101763,3092.725 L 21.936123,3092.725 L 21.936123,3092.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 41.936123,3092.725 C 41.181483,3092.706 40.438033,3093.1779 40.143063,3093.8632 C 39.848073,3094.5485 40.020253,3095.4039 40.558363,3095.9261 L 56.754623,3112.1736 C 57.276973,3112.6968 58.127493,3112.8703 58.817333,3112.5942 C 59.507183,3112.3182 59.994833,3111.6092 59.999993,3110.875 L 59.999993,3094.5974 C 60.001993,3093.6166 59.096113,3092.7233 58.101763,3092.725 L 41.936123,3092.725 L 41.936123,3092.725 z"
+ id="path11781"
+ sodipodi:nodetypes="csccscccc" />
+ <path
+ sodipodi:nodetypes="csccscccc"
+ id="path11783"
+ d="M 1.9361232,3112.725 C 1.1814832,3112.706 0.4380332,3113.1779 0.1430632,3113.8632 C -0.1519268,3114.5485 0.0202532,3115.4039 0.5583632,3115.9261 L 16.754623,3132.1736 C 17.276973,3132.6968 18.127493,3132.8703 18.817333,3132.5942 C 19.507183,3132.3182 19.994833,3131.6092 19.999993,3130.875 L 19.999993,3114.5974 C 20.001993,3113.6166 19.096113,3112.7233 18.101763,3112.725 L 1.9361232,3112.725 L 1.9361232,3112.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.025;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.01000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 21.936123,3112.725 C 21.181483,3112.706 20.438033,3113.1779 20.143063,3113.8632 C 19.848073,3114.5485 20.020253,3115.4039 20.558363,3115.9261 L 36.754623,3132.1736 C 37.276973,3132.6968 38.127493,3132.8703 38.817333,3132.5942 C 39.507183,3132.3182 39.994833,3131.6092 39.999993,3130.875 L 39.999993,3114.5974 C 40.001993,3113.6166 39.096113,3112.7233 38.101763,3112.725 L 21.936123,3112.725 L 21.936123,3112.725 z"
+ id="path11785"
+ sodipodi:nodetypes="csccscccc" />
+ </g>
+ <g
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/install_OOorg3_standard.bmp.png"
+ transform="translate(456.21428,-2742.3622)"
+ id="g11984">
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 101.93612,3074.7256 C 101.18148,3074.7066 100.43803,3075.1785 100.14306,3075.8638 C 99.84807,3076.5491 100.02025,3077.4045 100.55836,3077.9267 L 116.75462,3094.1742 C 117.27697,3094.6974 118.12749,3094.8709 118.81733,3094.5948 C 119.50718,3094.3188 119.99483,3093.6098 119.99999,3092.8756 L 119.99999,3076.598 C 120.00199,3075.6172 119.09611,3074.7239 118.10176,3074.7256 L 101.93612,3074.7256 L 101.93612,3074.7256 z"
+ id="path11734"
+ sodipodi:nodetypes="csccscccc"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/intro.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/intro.png"
+ id="path11895"
+ d="M 57.40206,3074.725 C 56.405981,3074.74 55.509994,3075.6501 55.51173,3076.6463 L 55.51173,3150.8032 C 55.51003,3151.7993 56.406014,3152.7099 57.40206,3152.7244 L 118.07864,3152.7244 C 119.08505,3152.7244 120.00156,3151.8096 119.99996,3150.8032 L 119.99996,3103.049 C 120.00296,3102.545 119.7975,3102.0429 119.44216,3101.6855 L 93.19443,3075.3138 C 92.84215,3074.9473 92.33924,3074.7301 91.83091,3074.725 L 57.40206,3074.725 L 57.40206,3074.725 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ sodipodi:nodetypes="ccccccccccc" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.86823654;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
+ d="M 57.40206,3074.725 C 56.35235,3074.7402 55.509901,3075.5965 55.51173,3076.6463 L 55.51173,3150.8032 C 55.509956,3151.853 56.352389,3152.7092 57.40206,3152.7244 L 118.07864,3152.7244 C 118.58844,3152.7252 119.07761,3152.5231 119.4381,3152.1626 C 119.7986,3151.8022 120.00077,3151.313 119.99996,3150.8032 L 119.99996,3103.049 C 120.00293,3102.5384 119.80217,3102.0476 119.44216,3101.6855 L 93.19443,3075.3138 C 92.837431,3074.9424 92.346043,3074.7302 91.83091,3074.725 L 57.40206,3074.725 L 57.40206,3074.725 z M 59.32339,3078.5676 L 91.02519,3078.5676 L 116.15732,3103.8238 L 116.15732,3148.8818 L 59.32339,3148.8818 L 59.32339,3078.5676 z"
+ id="path11736"
+ inkscape:export-filename="/home/christoph/Desktop/LibreOffice Artwork/intro.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <text
+ transform="scale(1.0168078,0.98347)"
+ font-size="103.091"
+ id="text43"
+ style="font-size:48.89245605px;font-family:Vegur-Regular"
+ x="2336.854"
+ y="540.82001" />
+ <text
+ transform="scale(0.9979479,1.0020563)"
+ font-size="103.091"
+ id="text3748"
+ style="font-size:91.03964996px;font-family:Vegur-Regular"
+ x="2230.6494"
+ y="417.58487" />
+ </g>
+</svg>
diff --git a/setup_native/source/win32/nsis/brosdkbanner.bmp b/setup_native/source/win32/nsis/brosdkbanner.bmp
new file mode 100644
index 000000000000..0a2961accbda
--- /dev/null
+++ b/setup_native/source/win32/nsis/brosdkbanner.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/downloadtemplate.nsi b/setup_native/source/win32/nsis/downloadtemplate.nsi
new file mode 100644
index 000000000000..30ee215038af
--- /dev/null
+++ b/setup_native/source/win32/nsis/downloadtemplate.nsi
@@ -0,0 +1,457 @@
+!define PRODUCT_NAME "PRODUCTNAMEPLACEHOLDER"
+!define PRODUCT_VERSION "PRODUCTVERSIONPLACEHOLDER"
+!define PRODUCT_PUBLISHER "PUBLISHERPLACEHOLDER"
+!define PRODUCT_WEB_SITE "WEBSITEPLACEHOLDER"
+
+SetCompressor lzma
+; SetCompressor zlib
+; Helpful for debugging, disable for products
+; RequestExecutionLevel user
+
+; MUI 1.67 compatible ------
+!include "MUI.nsh"
+
+Function .onInit
+ Call GetParameters
+ Pop $1
+ ;MessageBox MB_OK "$1"
+
+ Push $1
+ Push "/HELP="
+ Call GetOptions
+ Pop $2
+ ;MessageBox MB_OK "HELP: $2"
+
+ StrCmp $2 "ON" showhelp nohelp
+ showhelp:
+ MessageBox MB_OK|MB_ICONINFORMATION \
+ "DOWNLOADNAMEPLACEHOLDER options: $\n $\n \
+ /S : Silent installation $\n \
+ /D=<path> : NSIS installation directory (must be the last option!) $\n \
+ /EXTRACTONLY=ON : NSIS only extracts the PRODUCTNAMEPLACEHOLDER PRODUCTVERSIONPLACEHOLDER installation set $\n \
+ /INSTALLLOCATION=<path> : PRODUCTNAMEPLACEHOLDER PRODUCTVERSIONPLACEHOLDER installation directory $\n \
+ /POSTREMOVE=ON : Removes the unpacked installation set after PRODUCTNAMEPLACEHOLDER PRODUCTVERSIONPLACEHOLDER installation $\n \
+ /INSTALLJAVA=ON : Installs JRE located in sub directory java, if exists $\n \
+ /GUILEVEL=<guilevel> : Setting Windows Installer GUI level: qr, qb, qn, qf, ... $\n \
+ /PARAM1=$\"key=value$\" : Flexible parameter 1. Example: /PARAM1=$\"INSTALLLEVEL=70$\" $\n \
+ /PARAM2=$\"key=value$\" : Flexible parameter 2. $\n \
+ /PARAM3=$\"key=value$\" : Flexible parameter 3. $\n \
+ /HELP=ON : Shows this help $\n"
+ Quit
+ GoTo onInitDone
+
+ nohelp:
+
+ StrCmp $INSTDIR "" pathnotset pathset
+ pathnotset:
+
+ IfSilent onInitSilent onInitNoSilent
+
+ onInitSilent:
+ StrCpy $INSTDIR "$TEMP\PRODUCTPATHPLACEHOLDER Installation Files"
+ GoTo onInitDone
+
+ onInitNoSilent:
+ StrCpy $INSTDIR "$DESKTOP\PRODUCTPATHPLACEHOLDER Installation Files"
+ GoTo onInitDone
+
+ onInitDone:
+ pathset:
+
+FunctionEnd
+
+Function GetParameters
+
+ Push $R0
+ Push $R1
+ Push $R2
+ Push $R3
+
+ StrCpy $R2 1
+
+ StrLen $R3 $CMDLINE
+
+ ;Check for quote or space
+ StrCpy $R0 $CMDLINE $R2
+
+ StrCmp $R0 '"' 0 +3
+ StrCpy $R1 '"'
+ Goto loop
+ StrCpy $R1 " "
+
+ loop:
+ IntOp $R2 $R2 + 1
+ StrCpy $R0 $CMDLINE 1 $R2
+ StrCmp $R0 $R1 get
+ StrCmp $R2 $R3 get
+ Goto loop
+
+ get:
+ IntOp $R2 $R2 + 1
+ StrCpy $R0 $CMDLINE 1 $R2
+ StrCmp $R0 " " get
+ StrCpy $R0 $CMDLINE "" $R2
+
+ Pop $R3
+ Pop $R2
+ Pop $R1
+ Exch $R0
+
+FunctionEnd
+
+Function GetOptions
+
+ Exch $1
+ Exch
+ Exch $0
+ Exch
+ Push $2
+ Push $3
+ Push $4
+ Push $5
+ Push $6
+ Push $7
+
+ StrCpy $2 $1 '' 1
+ StrCpy $1 $1 1
+ StrLen $3 $2
+ StrCpy $7 0
+
+ begin:
+ StrCpy $4 -1
+ StrCpy $6 ''
+
+ quote:
+ IntOp $4 $4 + 1
+ StrCpy $5 $0 1 $4
+ StrCmp $5$7 '0' notfound
+ StrCmp $5 '' trimright
+ StrCmp $5 '"' 0 +7
+ StrCmp $6 '' 0 +3
+ StrCpy $6 '"'
+ goto quote
+ StrCmp $6 '"' 0 +3
+ StrCpy $6 ''
+ goto quote
+ StrCmp $5 `'` 0 +7
+ StrCmp $6 `` 0 +3
+ StrCpy $6 `'`
+ goto quote
+ StrCmp $6 `'` 0 +3
+ StrCpy $6 ``
+ goto quote
+ StrCmp $5 '`' 0 +7
+ StrCmp $6 '' 0 +3
+ StrCpy $6 '`'
+ goto quote
+ StrCmp $6 '`' 0 +3
+ StrCpy $6 ''
+ goto quote
+ StrCmp $6 '"' quote
+ StrCmp $6 `'` quote
+ StrCmp $6 '`' quote
+ StrCmp $5 $1 0 quote
+ StrCmp $7 0 trimleft trimright
+
+ trimleft:
+ IntOp $4 $4 + 1
+ StrCpy $5 $0 $3 $4
+ StrCmp $5 '' notfound
+ StrCmp $5 $2 0 quote
+ IntOp $4 $4 + $3
+ StrCpy $0 $0 '' $4
+ StrCpy $4 $0 1
+ StrCmp $4 ' ' 0 +3
+ StrCpy $0 $0 '' 1
+ goto -3
+ StrCpy $7 1
+ goto begin
+
+ trimright:
+ StrCpy $0 $0 $4
+ StrCpy $4 $0 1 -1
+ StrCmp $4 ' ' 0 +3
+ StrCpy $0 $0 -1
+ goto -3
+ StrCpy $3 $0 1
+ StrCpy $4 $0 1 -1
+ StrCmp $3 $4 0 end
+ StrCmp $3 '"' +3
+ StrCmp $3 `'` +2
+ StrCmp $3 '`' 0 end
+ StrCpy $0 $0 -1 1
+ goto end
+
+ notfound:
+ StrCpy $0 ''
+
+ end:
+ Pop $7
+ Pop $6
+ Pop $5
+ Pop $4
+ Pop $3
+ Pop $2
+ Pop $1
+ Exch $0
+
+FunctionEnd
+
+; MUI Settings
+!define MUI_HEADERIMAGE
+!define MUI_HEADERIMAGE_RIGHT
+!define MUI_HEADERIMAGE_BITMAP_NOSTRETCH
+!define MUI_HEADERIMAGE_BITMAP BANNERBMPPLACEHOLDER
+!define MUI_WELCOMEFINISHPAGE_BITMAP WELCOMEBMPPLACEHOLDER
+!define MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH
+!define MUI_WELCOMEPAGE_TITLE_3LINES
+!define MUI_ABORTWARNING
+!define MUI_ICON "SETUPICOPLACEHOLDER"
+!define MUI_CUSTOMFUNCTION_GUIINIT SetupBranding
+!define MUI_CUSTOMFUNCTION_UNGUIINIT SetupBranding
+
+; Welcome page
+!insertmacro MUI_PAGE_WELCOME
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES
+
+#231#!macro MUI_LANGUAGE_PACK LANGUAGE
+#231# !verbose push
+#231# !verbose ${MUI_VERBOSE}
+#231# !insertmacro MUI_INSERT
+#231# LoadLanguageFile "NSISPATHPLACEHOLDER\${LANGUAGE}_pack.nlf"
+#231# ;Set default language file for MUI and backup user setting
+#231# !ifdef LANGFILE_DEFAULT
+#231# !define MUI_LANGFILE_DEFAULT_TEMP "${LANGFILE_DEFAULT}"
+#231# !undef LANGFILE_DEFAULT
+#231# !endif
+#231# !define LANGFILE_DEFAULT "${NSISDIR}\Contrib\Language files\English.nsh"
+#231# ;Include language file
+#231# !insertmacro LANGFILE_INCLUDE "NSISPATHPLACEHOLDER\${LANGUAGE}_pack.nsh"
+#231# ;Restore user setting for default language file
+#231# !undef LANGFILE_DEFAULT
+#231# !ifdef MUI_LANGFILE_DEFAULT_TEMP
+#231# !define LANGFILE_DEFAULT "${MUI_LANGFILE_DEFAULT}"
+#231# !endif
+#231# ;Add language to list of languages for selection dialog
+#231# !ifndef MUI_LANGDLL_LANGUAGES
+#231# !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' "
+#231# !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' "
+#231# !else
+#231# !ifdef MUI_LANGDLL_LANGUAGES_TEMP
+#231# !undef MUI_LANGDLL_LANGUAGES_TEMP
+#231# !endif
+#231# !define MUI_LANGDLL_LANGUAGES_TEMP "${MUI_LANGDLL_LANGUAGES}"
+#231# !undef MUI_LANGDLL_LANGUAGES
+#231# !ifdef MUI_LANGDLL_LANGUAGES_CP_TEMP
+#231# !undef MUI_LANGDLL_LANGUAGES_CP_TEMP
+#231# !endif
+#231# !define MUI_LANGDLL_LANGUAGES_CP_TEMP "${MUI_LANGDLL_LANGUAGES_CP}"
+#231# !undef MUI_LANGDLL_LANGUAGES_CP
+#231# !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' ${MUI_LANGDLL_LANGUAGES_TEMP}"
+#231# !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' ${MUI_LANGDLL_LANGUAGES_CP_TEMP}"
+#231# !endif
+#231# !verbose pop
+#231#!macroend
+
+#204#!macro MUI_LANGUAGE_PACK LANGUAGE
+#204# !verbose push
+#204# !verbose ${MUI_VERBOSE}
+#204# !include "NSISPATHPLACEHOLDER\${LANGUAGE}_pack.nsh"
+#204# !verbose pop
+#204#!macroend
+
+#204#!macro MUI_LANGUAGEFILE_PACK_BEGIN LANGUAGE
+#204# !ifndef MUI_INSERT
+#204# !define MUI_INSERT
+#204# !insertmacro MUI_INSERT
+#204# !endif
+#204# LoadLanguageFile "NSISPATHPLACEHOLDER\${LANGUAGE}_pack.nlf"
+#204#!macroend
+
+; Language files
+ALLLANGUAGESPLACEHOLDER
+
+Function SetupBranding
+ File "/oname=$PLUGINSDIR\modern-header.bmp" BANNERBMPPLACEHOLDER
+ File "/oname=$PLUGINSDIR\modern-header-br.bmp" BANNERBMPPLACEHOLDER_BR
+ File "/oname=$PLUGINSDIR\modern-wizard.bmp" WELCOMEBMPPLACEHOLDER
+ File "/oname=$PLUGINSDIR\modern-wizard-br.bmp" WELCOMEBMPPLACEHOLDER_BR
+
+ ; use broffice specific branding if executable name begins BrOffice
+ StrCpy $0 $EXEFILE 8
+; messageBox MB_OK "ExeName: $0 - chopped $EXEFILE"
+ StrCmp $0 "BrOffice" BrOfficeSplash DefaultSplash
+ DefaultSplash:
+; messageBox MB_OK "LibreOffice"
+ SetBrandingImage /IMGID=1046 "$PLUGINSDIR\modern-header.bmp"
+ !insertmacro INSTALLOPTIONS_WRITE "ioSpecial.ini" "Field 1" "Text" "$PLUGINSDIR\modern-wizard.bmp"
+ GoTo atEnd
+ BrOfficeSplash:
+; messageBox MB_OK "BrOffice"
+ SetBrandingImage /IMGID=1046 "$PLUGINSDIR\modern-header-br.bmp"
+ !insertmacro INSTALLOPTIONS_WRITE "ioSpecial.ini" "Field 1" "Text" "$PLUGINSDIR\modern-wizard-br.bmp"
+ GoTo atEnd
+ atEnd:
+FunctionEnd
+
+; Reserve files
+;!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
+
+; MUI end ------
+
+Name "PRODUCTNAMEPLACEHOLDER PRODUCTVERSIONPLACEHOLDER"
+OutFile "OUTPUTDIRPLACEHOLDER\DOWNLOADNAMEPLACEHOLDER"
+; InstallDir "$DESKTOP\PRODUCTNAMEPLACEHOLDER PRODUCTVERSIONPLACEHOLDER Installation Files"
+; ShowInstDetails show
+Section "MainSection" SEC01
+ALLFILESPLACEHOLDER
+SectionEnd
+
+Section -Post
+
+ StrCpy $R9 "false"
+
+ Call GetParameters
+ Pop $1
+
+ Push $1
+ Push "/EXTRACTONLY="
+ Call GetOptions
+ Pop $2
+ ;MessageBox MB_OK "EXTRACTONLY: $2"
+
+ StrCmp $2 "ON" onPostDone callsetup
+ callsetup:
+
+ Push $1
+ Push "/INSTALLLOCATION="
+ Call GetOptions
+ Pop $2
+ ;MessageBox MB_OK "INSTALLLOCATION: $2"
+
+ StrCmp $2 "" installnotset installset
+ installset:
+ StrCpy $3 'INSTALLLOCATION="$2"'
+ installnotset:
+
+ Push $1
+ Push "/INSTALLJAVA="
+ Call GetOptions
+ Pop $2
+ ;MessageBox MB_OK "INSTALLJAVA: $2"
+
+ StrCmp $2 "ON" setinstalljava setdontinstalljava
+ setinstalljava:
+ StrCpy $R9 "true"
+ setdontinstalljava:
+
+ Push $1
+ Push "/GUILEVEL="
+ Call GetOptions
+ Pop $2
+
+ StrCmp $2 "" dontsetguilevel setguilevel
+ setguilevel:
+ StrCpy $7 "/"
+ StrCpy $7 $7$2
+ GoTo afterguilevel
+ dontsetguilevel:
+ StrCpy $7 "/qr"
+ afterguilevel:
+
+ ;MessageBox MB_OK "GUILEVEL: $7"
+
+ Push $1
+ Push "/PARAM1="
+ Call GetOptions
+ Pop $2
+ ;MessageBox MB_OK "PARAM1: $2"
+
+ StrCmp $2 "" param1notset param1set
+ param1set:
+ StrCpy $4 "$2"
+ param1notset:
+
+
+ Push $1
+ Push "/PARAM2="
+ Call GetOptions
+ Pop $2
+ ;MessageBox MB_OK "PARAM2: $2"
+
+ StrCmp $2 "" param2notset param2set
+ param2set:
+ StrCpy $5 "$2"
+ param2notset:
+
+
+ Push $1
+ Push "/PARAM3="
+ Call GetOptions
+ Pop $2
+ ;MessageBox MB_OK "PARAM3: $2"
+
+ StrCmp $2 "" param3notset param3set
+ param3set:
+ StrCpy $6 "$2"
+ param3notset:
+
+ IfSilent onPostSilent onPostNoSilent
+
+ onPostSilent:
+ Push $1
+ Push "/POSTREMOVE="
+ Call GetOptions
+ Pop $2
+ ;MessageBox MB_OK "POSTREMOVE: $2"
+
+ StrCmp $2 "ON" postremovesilent nopostremovesilent
+ nopostremovesilent:
+ StrCmp $R9 "true" installjava1 dontinstalljava1
+ installjava1:
+ ExecWait '$INSTDIR\java\WINDOWSJAVAFILENAMEPLACEHOLDER /s /v"/qn REBOOT=Suppress"'
+ dontinstalljava1:
+ ExecWait "$INSTDIR\setup.exe -lang $LANGUAGE $3 $4 $5 $6 $7 -ignore_running" $0
+ SetErrorLevel $0
+ Quit
+ GoTo onPostDone
+ postremovesilent:
+ StrCmp $R9 "true" installjava2 dontinstalljava2
+ installjava2:
+ ExecWait '$INSTDIR\java\WINDOWSJAVAFILENAMEPLACEHOLDER /s /v"/qn REBOOT=Suppress"'
+ dontinstalljava2:
+ ExecWait "$INSTDIR\setup.exe -lang $LANGUAGE $3 $4 $5 $6 $7 -ignore_running" $0
+ RMDir /r $INSTDIR
+ RMDir $INSTDIR
+ SetErrorLevel $0
+ Quit
+ GoTo onPostDone
+
+ onPostNoSilent:
+ Push $1
+ Push "/POSTREMOVE="
+ Call GetOptions
+ Pop $2
+ ;MessageBox MB_OK "POSTREMOVE: $2"
+
+ StrCmp $2 "ON" postremove nopostremove
+ nopostremove:
+ Exec "$INSTDIR\setup.exe -lang $LANGUAGE $3 $4 $5 $6"
+ Quit
+ GoTo onPostDone
+ postremove:
+ StrCmp $R9 "true" installjava3 dontinstalljava3
+ installjava3:
+ ExecWait '$INSTDIR\java\WINDOWSJAVAFILENAMEPLACEHOLDER /s /v"/qr REBOOT=Suppress"'
+ dontinstalljava3:
+ ExecWait "$INSTDIR\setup.exe -lang $LANGUAGE $3 $4 $5 $6" $0
+ RMDir /r $INSTDIR
+ RMDir $INSTDIR
+ SetErrorLevel $0
+ Quit
+ GoTo onPostDone
+
+ onPostDone:
+
+SectionEnd
diff --git a/setup_native/source/win32/nsis/ooobanner.bmp b/setup_native/source/win32/nsis/ooobanner.bmp
new file mode 100644
index 000000000000..58665b5e6bfd
--- /dev/null
+++ b/setup_native/source/win32/nsis/ooobanner.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/ooobitmap.bmp b/setup_native/source/win32/nsis/ooobitmap.bmp
new file mode 100644
index 000000000000..11acb28b1aad
--- /dev/null
+++ b/setup_native/source/win32/nsis/ooobitmap.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/ooosdkbanner.bmp b/setup_native/source/win32/nsis/ooosdkbanner.bmp
new file mode 100644
index 000000000000..a453f1fcdd05
--- /dev/null
+++ b/setup_native/source/win32/nsis/ooosdkbanner.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/ooosdkbitmap.bmp b/setup_native/source/win32/nsis/ooosdkbitmap.bmp
new file mode 100644
index 000000000000..11acb28b1aad
--- /dev/null
+++ b/setup_native/source/win32/nsis/ooosdkbitmap.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/ooosetup.ico b/setup_native/source/win32/nsis/ooosetup.ico
new file mode 100644
index 000000000000..bed4687fb0a2
--- /dev/null
+++ b/setup_native/source/win32/nsis/ooosetup.ico
Binary files differ
diff --git a/setup_native/source/win32/nsis/urebanner.bmp b/setup_native/source/win32/nsis/urebanner.bmp
new file mode 100644
index 000000000000..a453f1fcdd05
--- /dev/null
+++ b/setup_native/source/win32/nsis/urebanner.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/urebitmap.bmp b/setup_native/source/win32/nsis/urebitmap.bmp
new file mode 100755
index 000000000000..11acb28b1aad
--- /dev/null
+++ b/setup_native/source/win32/nsis/urebitmap.bmp
Binary files differ
diff --git a/setup_native/source/win32/patchlist.txt b/setup_native/source/win32/patchlist.txt
new file mode 100644
index 000000000000..e0d5a7e6a358
--- /dev/null
+++ b/setup_native/source/win32/patchlist.txt
@@ -0,0 +1,2 @@
+# Windows patch file list
+
diff --git a/setup_native/source/win32/stwrapper/makefile.mk b/setup_native/source/win32/stwrapper/makefile.mk
new file mode 100644
index 000000000000..ca035b4a9ad0
--- /dev/null
+++ b/setup_native/source/win32/stwrapper/makefile.mk
@@ -0,0 +1,50 @@
+PRJ=..$/..$/..
+
+PRJNAME=setup_native
+TARGET=stclient_wrapper
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+TARGETTYPE=GUI
+USE_DEFFILE=TRUE
+#DYNAMIC_CRT:=
+NO_DEFAULT_STL=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Resources ----------------------------------------------------
+
+RCFILES=resource.rc
+
+# --- Files --------------------------------------------------------
+
+OBJFILES=\
+ $(OBJ)$/stwrapper.obj
+
+APP1OBJS=$(OBJ)$/stwrapper.obj
+
+APP1NOSAL=TRUE
+
+APP1TARGET=$(TARGET)
+
+APP1NOSVRES=$(RES)$/$(TARGET).res
+
+UWINAPILIB:=
+
+STDLIB1=\
+ $(GDI32LIB)\
+ $(COMCTL32LIB)\
+ $(COMDLG32LIB)\
+ $(ADVAPI32LIB)\
+ $(SHELL32LIB)
+
+DLLPRE =
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(OBJ)$/stwrapper.obj: $(INCCOM)$/_version.h
+
+#$(RCFILES) : resource.rc
diff --git a/setup_native/source/win32/stwrapper/resource.rc b/setup_native/source/win32/stwrapper/resource.rc
new file mode 100644
index 000000000000..8683faac0d4a
--- /dev/null
+++ b/setup_native/source/win32/stwrapper/resource.rc
@@ -0,0 +1,102 @@
+#define VERSION 1
+#define SUBVERSION 0
+//#define VERVARIANT 0
+// .0 + VER_CONCEPT
+// .100 + VER_ALPHA
+// .200 + VER_BETA
+// .300 + VER_GAMMA
+// .500 + VER_FINAL
+//#define VER_CONCEPT 0
+//#define VER_BETA 6
+#define VER_FINAL 0
+
+#define VER_DAY 1
+#define VER_MONTH 4
+#define VER_YEAR 09
+
+
+// Header
+#if defined(_MSC_VER) && (_MSC_VER < 1500)
+#include "winres.h"
+#else
+#define WINVER 0x0500
+#include "winresrc.h"
+#endif
+#include "verinfo.hrc"
+
+#define VER_FIRSTYEAR 07
+
+#if !defined(ENGLISH)
+#define LG_D // generate always german version
+#endif
+
+// -----------------------------------------------------------------------
+// language/character set specification table
+// -----------------------------------------------------------------------
+
+RCD_LANGUAGE rcdata
+{
+ "040904B0", // USA -> Unicode
+ "040904E4", // USA -> Windows, Multilingual
+ "04090000", // USA -> 7-Bit-ASCII
+ 0 // end of table
+}
+
+// -----------------------------------------------------------------------
+// version information
+// -----------------------------------------------------------------------
+
+VS_VERSION_INFO versioninfo
+ fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+ fileflagsmask 0x3F
+ fileflags
+#if defined(DEBUG)
+ VS_FF_DEBUG |
+#endif
+#ifdef VER_PREL
+ VS_FF_PRERELEASE |
+#endif
+ 0
+#ifndef WIN32
+ fileos VOS_DOS_WINDOWS16
+#else
+ fileos VOS_NT_WINDOWS32
+#endif
+ filetype VFT_APP
+ {
+ block "StringFileInfo"
+ {
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "The Document Foundation\0"
+ value "FileDescription", "Service Tags Wrapper\0"
+ value "FileVersion", PPS(VER_LEVEL) "\0"
+ value "ProductVersion", PPS(VER_LEVEL) "\0"
+ value "OriginalFilename", "STCLIENT_WRAPPER.EXE\0"
+ value "InternalName", "stclient_wrapper\0"
+ value "LegalCopyright", S_CRIGHT " Sun Microsystems, Inc.\0"
+ }
+ }
+
+ block "VarFileInfo"
+ {
+ value "Translation", 0x0409, 1252
+ }
+ }
+
+// version binary entry
+VS_VERSION_INFO rcdata
+{
+ 0xF0, "sw", 0x0F, VER_YEAR, VER_MONTH, VER_DAY,
+ VERSION, SUBVERSION, VERVARIANT, VER_COUNT
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Manifest section
+//
+1 24 stwrapper.manifest
+
diff --git a/setup_native/source/win32/stwrapper/stwrapper.cxx b/setup_native/source/win32/stwrapper/stwrapper.cxx
new file mode 100644
index 000000000000..b4e22cf7afca
--- /dev/null
+++ b/setup_native/source/win32/stwrapper/stwrapper.cxx
@@ -0,0 +1,497 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#define WIN32_LEAN_AND_MEAN
+
+#ifdef _MSC_VER
+#pragma warning(disable:4668 4917) // disable warnings for system headers
+#endif
+
+#include <windows.h>
+#include <windowsx.h>
+#include <shellapi.h>
+#include <shlobj.h>
+#include <tchar.h>
+
+#include <stdio.h>
+#include <sal/macros.h>
+
+enum PathResult
+{
+ PATHRESULT_OK,
+ PATHRESULT_API_NOT_SUPPORTED,
+ PATHRESULT_EXE_NOT_FOUND
+};
+
+const int MAXCMDLINELEN = 32768;
+
+static TCHAR g_szSTInstallationPath[MAX_PATH] = TEXT("");
+static TCHAR g_szOperatingSystem[256] = TEXT("");
+
+static const TCHAR g_szSTExecutable[256] = TEXT("stclient.exe");
+
+//***************************************************************************
+
+LONG RegReadValue( HKEY hBaseKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPVOID lpData, DWORD cbData )
+{
+ HKEY hKey = NULL;
+ LONG lResult( 0 );
+
+ lResult = RegOpenKeyEx( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ lResult = RegQueryValueEx( hKey, lpValueName, NULL, NULL, (LPBYTE)lpData, &cbData );
+ RegCloseKey( hKey );
+ }
+
+ return lResult;
+}
+
+//***************************************************************************
+
+static LPTSTR *GetCommandArgs( int *pArgc )
+{
+#ifdef UNICODE
+ return CommandLineToArgvW( GetCommandLineW(), pArgc );
+#else
+ *pArgc = __argc;
+ return __argv;
+#endif
+}
+
+//***************************************************************************
+
+static bool IsSupportedPlatform()
+{
+ OSVERSIONINFO aOsVersion;
+
+ ZeroMemory( &aOsVersion, sizeof( OSVERSIONINFO ));
+ aOsVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+
+ // Try to determine OS version
+ if ( GetVersionEx( &aOsVersion ))
+ {
+ switch ( aOsVersion.dwPlatformId )
+ {
+ case VER_PLATFORM_WIN32_NT: // Windows NT based
+ return true;
+
+ case VER_PLATFORM_WIN32_WINDOWS: // Windows Me/98/95.
+ case VER_PLATFORM_WIN32s: // Win32s
+ return false;
+
+ default:
+ return false;
+ }
+ }
+
+ return false;
+}
+
+//***************************************************************************
+
+static LPCTSTR GetOperatingSystemString()
+{
+ OSVERSIONINFO aOsVersion;
+
+ ZeroMemory( &aOsVersion, sizeof( OSVERSIONINFO ));
+ aOsVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+
+ _tcscpy( g_szOperatingSystem, TEXT( "Microsoft Windows" ));
+
+ // Try to determine OS version
+ if ( GetVersionEx( &aOsVersion ))
+ {
+ switch ( aOsVersion.dwPlatformId )
+ {
+ // Test for the Windows NT product family.
+ case VER_PLATFORM_WIN32_NT:
+ {
+ if ( aOsVersion.dwMajorVersion == 3 )
+ {
+ _tcscat( g_szOperatingSystem, TEXT( " NT 3." ));
+ if ( aOsVersion.dwMinorVersion == 0 )
+ _tcscat( g_szOperatingSystem, TEXT( "0" ));
+ else if ( aOsVersion.dwMinorVersion == 5 )
+ _tcscat( g_szOperatingSystem, TEXT( "5" ));
+ else if ( aOsVersion.dwMinorVersion == 51 )
+ _tcscat( g_szOperatingSystem, TEXT( "51" ));
+ }
+ else if ( aOsVersion.dwMajorVersion == 4 )
+ _tcscat( g_szOperatingSystem, TEXT( " NT 4.0" ));
+ else if ( aOsVersion.dwMajorVersion == 5 )
+ {
+ if ( aOsVersion.dwMinorVersion == 0 )
+ _tcscat( g_szOperatingSystem, TEXT( " 2000" ));
+ else if ( aOsVersion.dwMinorVersion == 1 )
+ _tcscat( g_szOperatingSystem, TEXT( " XP" ));
+ else if ( aOsVersion.dwMinorVersion == 2 )
+ _tcscat( g_szOperatingSystem, TEXT( " Server 2003" ));
+ }
+ else if ( aOsVersion.dwMajorVersion == 6 )
+ {
+ if ( aOsVersion.dwMinorVersion == 0 )
+ _tcscat( g_szOperatingSystem, " Vista" );
+ }
+ }
+ break;
+
+ // Test for the Windows Me/98/95.
+ case VER_PLATFORM_WIN32_WINDOWS:
+ {
+ if ( aOsVersion.dwMinorVersion == 0 )
+ _tcscat( g_szOperatingSystem, TEXT( " 95" ));
+ else if ( aOsVersion.dwMinorVersion == 10 )
+ _tcscat( g_szOperatingSystem, TEXT( " 98" ));
+ else if ( aOsVersion.dwMinorVersion == 90 )
+ _tcscat( g_szOperatingSystem, TEXT( " Me" ));
+ }
+ break;
+ }
+ }
+
+ return g_szOperatingSystem;
+}
+
+//***************************************************************************
+
+static bool FileExists( LPCTSTR lpPathToFile )
+{
+ bool bResult = false;
+ HANDLE hFind;
+ WIN32_FIND_DATA FindFileData;
+
+ hFind = FindFirstFile( lpPathToFile, &FindFileData );
+
+ if ( hFind != INVALID_HANDLE_VALUE )
+ {
+ FindClose( hFind );
+ bResult = true;
+ }
+
+ return bResult;
+}
+
+//***************************************************************************
+
+static bool GetProgramFilesFolder( LPTSTR strPath )
+{
+ bool bRet = false;
+ HINSTANCE hLibrary;
+
+ if (( hLibrary = LoadLibrary( "shell32.dll" )) != NULL )
+ {
+ BOOL (WINAPI *pSHGetSpecialFolderPathA)( HWND, LPSTR, int, BOOL );
+
+ pSHGetSpecialFolderPathA = (BOOL (WINAPI *)(HWND, LPSTR, int, BOOL))GetProcAddress( hLibrary, "SHGetSpecialFolderPathA" );
+
+ if ( pSHGetSpecialFolderPathA )
+ {
+ if ( pSHGetSpecialFolderPathA( NULL, strPath, CSIDL_PROGRAM_FILES, TRUE ))
+ bRet = true;
+ }
+ }
+
+ FreeLibrary( hLibrary );
+
+ return ( bRet );
+}
+
+//***************************************************************************
+
+static PathResult RetrieveExecutablePath( LPTSTR szExecutablePath )
+{
+ PathResult eRet = PATHRESULT_API_NOT_SUPPORTED;
+ TCHAR szProgramFilesFolder[MAX_PATH];
+
+ if ( GetProgramFilesFolder( szProgramFilesFolder ))
+ {
+ size_t nLen = _tcslen( szProgramFilesFolder );
+ if ( nLen > 0 )
+ {
+ _tcscpy( szExecutablePath, szProgramFilesFolder );
+ if ( szProgramFilesFolder[nLen-1] != '\\' )
+ _tcscat( szExecutablePath, TEXT( "\\" ));
+ _tcscat( szExecutablePath, TEXT( "Sun\\servicetag\\" ));
+ _tcscat( szExecutablePath, g_szSTExecutable );
+ eRet = FileExists( szExecutablePath ) ? PATHRESULT_OK : PATHRESULT_EXE_NOT_FOUND;
+ }
+ }
+
+ return eRet;
+}
+
+//***************************************************************************
+
+static void SafeCopy( LPTSTR lpTarget, LPCSTR lpSource, size_t nMaxLen )
+{
+ size_t nLen = _tcslen( lpSource );
+ size_t nCopy = ( nLen < size_t( nMaxLen-1 )) ? nLen : nMaxLen-1;
+ _tcsncpy( lpTarget, lpSource, nMaxLen-1 );
+ *(lpTarget+nCopy) = 0;
+}
+
+//***************************************************************************
+
+int WINAPI _tWinMain( HINSTANCE /*hInstance*/, HINSTANCE, LPTSTR, int )
+{
+ const DWORD ERR_NO_RECORDS_FOUND = 225;
+ const DWORD ERR_DUP_RECORD = 226;
+
+ DWORD dwExitCode = (DWORD)1;
+
+ int nArgs = 0;
+ LPTSTR* lpArgs = GetCommandArgs( &nArgs );
+
+ if ( !IsSupportedPlatform() )
+ {
+ // Return 0 for a successful run on not supported platforms
+ // We don't want that the Office tries to start us forever.
+ return 0;
+ }
+
+ if ( nArgs >= 11 )
+ {
+ TCHAR szTargetURN[1024] = {0};
+ TCHAR szProductName[1024] = {0};
+ TCHAR szProductVersion[1024] = {0};
+ TCHAR szParentProductName[1024] = {0};
+ TCHAR szProductSource[1024] = {0};
+ TCHAR szInstanceURN[1024] = {0};
+
+// -i) INSTANCE_URN="$2"; shift;;
+// -t) TARGET_URN="$2"; shift;;
+// -p) PRODUCT_NAME="$2"; shift;;
+// -e) PRODUCT_VERSION="$2"; shift;;
+// -P) PARENT_PRODUCT_NAME="$2"; shift;;
+// -S) PRODUCT_SOURCE="$2"; shift;;
+// "usage: $0 [-i <instance urn>] -p <product name> -e <product version> -t <urn> -S <source> -P <parent product name>"
+
+ int i = 1;
+ while ( i < nArgs )
+ {
+ LPTSTR lpArg = lpArgs[i];
+ if ( _tcslen( lpArg ) >= 2 )
+ {
+ if ( lpArg[0] == '-' )
+ {
+ switch ( lpArg[1] )
+ {
+ case 'i':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szInstanceURN, lpArgs[i], SAL_N_ELEMENTS( szInstanceURN ));
+ break;
+ }
+
+ case 't':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szTargetURN, lpArgs[i], SAL_N_ELEMENTS( szTargetURN ));
+ break;
+ }
+ case 'p':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szProductName, lpArgs[i], SAL_N_ELEMENTS( szProductName ));
+ break;
+ }
+ case 'e':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szProductVersion, lpArgs[i], SAL_N_ELEMENTS( szProductVersion ));
+ break;
+ }
+ case 'P':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szParentProductName, lpArgs[i], SAL_N_ELEMENTS( szParentProductName ));
+ break;
+ }
+ case 'S':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szProductSource, lpArgs[i], SAL_N_ELEMENTS( szProductSource ));
+ break;
+ }
+
+ default:
+ break;
+ } // switch
+ }
+ }
+
+ ++i;
+ }
+
+ if ( RetrieveExecutablePath( g_szSTInstallationPath ) == PATHRESULT_OK )
+ {
+ BOOL bSuccess = TRUE;
+ BOOL bProcessStarted = FALSE;
+
+ STARTUPINFO aStartupInfo;
+ PROCESS_INFORMATION aProcessInfo;
+ LPTSTR lpCommandLine = 0;
+
+ ZeroMemory( &aStartupInfo, sizeof( aStartupInfo ));
+ aStartupInfo.cb = sizeof( aStartupInfo );
+ ZeroMemory( &aProcessInfo, sizeof( aProcessInfo ));
+
+ if ( _tcslen( szInstanceURN ) == 0 )
+ {
+ // TEST=`${STCLIENT} -f -t ${TARGET_URN}`
+ lpCommandLine = new TCHAR[MAXCMDLINELEN];
+
+ _tcscpy( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, g_szSTInstallationPath );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, TEXT( " -f" ));
+ _tcscat( lpCommandLine, TEXT( " -t "));
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, szTargetURN );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+
+ bSuccess = CreateProcess(
+ NULL,
+ lpCommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ CREATE_NO_WINDOW,
+ NULL,
+ NULL,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ bProcessStarted = TRUE;
+
+ // wait until process ends to receive exit code
+ WaitForSingleObject( aProcessInfo.hProcess, INFINITE );
+
+ delete []lpCommandLine;
+ }
+
+ if ( bSuccess )
+ {
+ DWORD dwSTClientExitCode( ERR_NO_RECORDS_FOUND );
+ if ( bProcessStarted )
+ {
+ GetExitCodeProcess( aProcessInfo.hProcess, &dwSTClientExitCode );
+ dwSTClientExitCode &= 0x000000ff;
+
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+ }
+
+ if ( dwSTClientExitCode == ERR_NO_RECORDS_FOUND )
+ {
+ // output=`${STCLIENT} -a [-i "${INSTANCE_URN}"] -p "${PRODUCT_NAME}" -e "${PRODUCT_VERSION}" -t "${TARGET_URN}" -S "${PRODUCT_SOURCE}" -P "${PARENT_PRODUCT_NAME}" -m "Sun Microsystems, Inc." -A ${uname} -z global`
+ lpCommandLine = new TCHAR[MAXCMDLINELEN];
+
+ _tcscpy( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, g_szSTInstallationPath );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, TEXT( " -a" ));
+ if ( _tcslen( szInstanceURN ) > 0 )
+ {
+ _tcscat( lpCommandLine, TEXT( " -i " ));
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, szInstanceURN );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ }
+ _tcscat( lpCommandLine, TEXT( " -p " ));
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, szProductName );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, TEXT( " -e " ));
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, szProductVersion );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, TEXT( " -t " ));
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, szTargetURN );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, TEXT( " -S " ));
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, szProductSource );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, TEXT( " -P " ));
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, szParentProductName );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, TEXT( " -m \"The Document Foundation\"" ));
+ _tcscat( lpCommandLine, TEXT( " -A " ));
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, GetOperatingSystemString() );
+ _tcscat( lpCommandLine, TEXT( "\"" ));
+ _tcscat( lpCommandLine, TEXT( " -z global" ));
+
+ ZeroMemory( &aStartupInfo, sizeof( aStartupInfo ));
+ aStartupInfo.cb = sizeof(aStartupInfo);
+ ZeroMemory( &aProcessInfo, sizeof( aProcessInfo ));
+
+ bSuccess = CreateProcess(
+ NULL,
+ lpCommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ CREATE_NO_WINDOW,
+ NULL,
+ NULL,
+ &aStartupInfo,
+ &aProcessInfo );
+
+ delete []lpCommandLine;
+
+ // wait until process ends to receive exit code
+ WaitForSingleObject( aProcessInfo.hProcess, INFINITE );
+
+ dwSTClientExitCode = 0;
+ GetExitCodeProcess( aProcessInfo.hProcess, &dwSTClientExitCode );
+ dwSTClientExitCode &= 0x000000ff;
+
+ CloseHandle( aProcessInfo.hProcess );
+ CloseHandle( aProcessInfo.hThread );
+
+ if ( !bSuccess )
+ dwExitCode = 1; // couldn't start stclient process
+ else
+ {
+ if ( _tcslen( szInstanceURN ) > 0 )
+ {
+ // don't register again if we registered in a previous run
+ // or we called stclient successfully.
+ if (( dwSTClientExitCode == ERR_DUP_RECORD ) ||
+ ( dwSTClientExitCode == 0 ))
+ dwExitCode = 0;
+ else
+ dwExitCode = 1; // other errors
+ }
+ else
+ dwExitCode = ( dwSTClientExitCode == 0 ) ? 0 : 1;
+ }
+ }
+ else if ( dwSTClientExitCode == 0 )
+ dwExitCode = 0; // already registered
+ else
+ dwExitCode = 1; // other errors
+ }
+ else
+ dwExitCode = 1; // couldn't start stclient
+ }
+ else
+ dwExitCode = 1; // no executable found
+ }
+ else
+ dwExitCode = 0; // wrong number of arguments
+
+ return dwExitCode;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/setup_native/source/win32/stwrapper/stwrapper.manifest b/setup_native/source/win32/stwrapper/stwrapper.manifest
new file mode 100644
index 000000000000..ec639e45cb04
--- /dev/null
+++ b/setup_native/source/win32/stwrapper/stwrapper.manifest
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- Copyright © 1981-2001 Microsoft Corporation -->
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+ <assemblyIdentity
+ type="win32"
+ name="Service Tags Wrapper"
+ version="1.0.0.0"
+ processorArchitecture="x86"
+ />
+ <description>OpenOffice.org Installer</description>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <dependency>
+ </dependency>
+</assembly>