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.cxx208
-rw-r--r--setup_native/source/win32/customactions/javafilter/exports.dxp2
-rw-r--r--setup_native/source/win32/customactions/javafilter/jfregca.cxx330
-rw-r--r--setup_native/source/win32/customactions/javafilter/makefile.mk70
-rwxr-xr-xsetup_native/source/win32/customactions/languagepacks/checkrunningofficelanguagepack.cxx218
-rw-r--r--setup_native/source/win32/customactions/languagepacks/exports.dxp4
-rw-r--r--setup_native/source/win32/customactions/languagepacks/lngpckinsthelper.cxx204
-rw-r--r--setup_native/source/win32/customactions/languagepacks/makefile.mk99
-rw-r--r--setup_native/source/win32/customactions/languagepacks/respintest.cxx211
-rwxr-xr-xsetup_native/source/win32/customactions/patch/exports.dxp9
-rwxr-xr-xsetup_native/source/win32/customactions/patch/makefile.mk97
-rwxr-xr-xsetup_native/source/win32/customactions/patch/swappatchfiles.cxx898
-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.cxx221
-rw-r--r--setup_native/source/win32/customactions/quickstarter/quickstarter.hxx18
-rw-r--r--setup_native/source/win32/customactions/quickstarter/remove_quickstart_link.cxx60
-rw-r--r--setup_native/source/win32/customactions/quickstarter/sdqsmsi.dxp2
-rw-r--r--setup_native/source/win32/customactions/quickstarter/shutdown_quickstart.cxx79
-rw-r--r--setup_native/source/win32/customactions/rebase/makefile.mk90
-rw-r--r--setup_native/source/win32/customactions/rebase/rebase.cxx166
-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
-rwxr-xr-xsetup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx530
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/constants.hxx39
-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.cxx102
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/msihelper.hxx184
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/reg4msdocmsi.cxx189
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/register.cxx340
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/register.hxx84
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrar.cxx759
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrar.hxx103
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.cxx351
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.hxx158
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registry.cxx242
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registry.hxx338
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryexception.cxx111
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryexception.hxx104
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.cxx189
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.hxx108
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryw9x.cxx550
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registryw9x.hxx199
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx619
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/registrywnt.hxx202
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/stringconverter.cxx70
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/stringconverter.hxx41
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/userregistrar.cxx136
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/userregistrar.hxx43
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/windowsregistry.cxx79
-rw-r--r--setup_native/source/win32/customactions/reg4msdoc/windowsregistry.hxx40
-rwxr-xr-xsetup_native/source/win32/customactions/reg64/exports.dxp2
-rw-r--r--setup_native/source/win32/customactions/reg64/makefile.mk108
-rwxr-xr-xsetup_native/source/win32/customactions/reg64/reg64.cxx477
-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.cxx438
-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.cxx122
-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.cxx186
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/checkdirectory.cxx117
-rw-r--r--setup_native/source/win32/customactions/shellextensions/checkpatches.cxx113
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx290
-rw-r--r--setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx130
-rw-r--r--setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx124
-rw-r--r--setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx181
-rw-r--r--setup_native/source/win32/customactions/shellextensions/exports.dxp20
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/iconcache.cxx110
-rw-r--r--setup_native/source/win32/customactions/shellextensions/layerlinks.cxx257
-rw-r--r--setup_native/source/win32/customactions/shellextensions/makefile.mk106
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx117
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/postuninstall.cxx155
-rw-r--r--setup_native/source/win32/customactions/shellextensions/registerextensions.cxx573
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/setadmininstall.cxx66
-rw-r--r--setup_native/source/win32/customactions/shellextensions/shellextensions.cxx213
-rw-r--r--setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx142
-rw-r--r--setup_native/source/win32/customactions/shellextensions/upgrade.cxx204
-rw-r--r--setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx242
-rw-r--r--setup_native/source/win32/customactions/tools/checkversion.cxx149
-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.cxx97
-rw-r--r--setup_native/source/win32/customactions/tools/seterror.hxx54
-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.txt140
-rw-r--r--setup_native/source/win32/nsis/brobanner.bmpbin0 -> 8964 bytes
-rw-r--r--setup_native/source/win32/nsis/brobitmap.bmpbin0 -> 52100 bytes
-rw-r--r--setup_native/source/win32/nsis/brosdkbanner.bmpbin0 -> 25818 bytes
-rw-r--r--setup_native/source/win32/nsis/downloadtemplate.nsi432
-rw-r--r--setup_native/source/win32/nsis/ooobanner.bmpbin0 -> 9044 bytes
-rw-r--r--setup_native/source/win32/nsis/ooobitmap.bmpbin0 -> 52576 bytes
-rw-r--r--setup_native/source/win32/nsis/ooosdkbanner.bmpbin0 -> 9044 bytes
-rw-r--r--setup_native/source/win32/nsis/ooosdkbitmap.bmpbin0 -> 154544 bytes
-rwxr-xr-xsetup_native/source/win32/nsis/ooosetup.icobin0 -> 295606 bytes
-rw-r--r--setup_native/source/win32/nsis/urebanner.bmpbin0 -> 25818 bytes
-rwxr-xr-xsetup_native/source/win32/nsis/urebitmap.bmpbin0 -> 154544 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.rc125
-rw-r--r--setup_native/source/win32/stwrapper/stwrapper.cxx495
-rw-r--r--setup_native/source/win32/stwrapper/stwrapper.manifest20
110 files changed, 15658 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..a01e3e1f9a4d
--- /dev/null
+++ b/setup_native/source/win32/customactions/indexingfilter/restartindexingservice.cxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
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..80a8937cbe3a
--- /dev/null
+++ b/setup_native/source/win32/customactions/javafilter/jfregca.cxx
@@ -0,0 +1,330 @@
+/*************************************************************************
+ *
+ * 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 <stdio.h>
+
+#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);
+ }
+}
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 100755
index 000000000000..9a933eea0334
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/checkrunningofficelanguagepack.cxx
@@ -0,0 +1,218 @@
+/*************************************************************************
+ *
+ * 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 <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, elementsof(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, elementsof(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 <= elementsof(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;
+}
+
+
+
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..d01befd5d0d9
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/exports.dxp
@@ -0,0 +1,4 @@
+SetProductInstallationPath
+RegisterLanguagePack
+GetUserInstallMode
+IsOfficeRunning
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..d3a6c81b59ed
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/lngpckinsthelper.cxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
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..69526077c509
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/makefile.mk
@@ -0,0 +1,99 @@
+#*************************************************************************
+#
+# 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)$/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..6a98af8a3f30
--- /dev/null
+++ b/setup_native/source/win32/customactions/languagepacks/respintest.cxx
@@ -0,0 +1,211 @@
+/*************************************************************************
+ *
+ * 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"));
+ }
+} // 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,
+ elementsof(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,
+ elementsof(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,
+ elementsof(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,
+ elementsof(szValue),
+ sSetupiniPath.c_str()
+ );
+
+ if ( szValue[0] )
+ {
+ SetMsiProperty( handle, TEXT("ALLUSERS"), szValue );
+ // MessageBox(NULL, "ALLUSERS set", "DEBUG", MB_OK);
+ }
+
+ return ERROR_SUCCESS;
+}
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..b57f2838bf34
--- /dev/null
+++ b/setup_native/source/win32/customactions/patch/exports.dxp
@@ -0,0 +1,9 @@
+InstallPatchedFiles
+UninstallPatchedFiles
+GetUserInstallMode
+SetProductInstallMode
+ShutDownQuickstarter
+IsOfficeRunning
+SetFeatureState
+SetNewFeatureState
+ShowOnlineUpdateDialog
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..cb8733de20b6
--- /dev/null
+++ b/setup_native/source/win32/customactions/patch/makefile.mk
@@ -0,0 +1,97 @@
+#*************************************************************************
+#
+# 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)$/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 100755
index 000000000000..6285d64ebe3f
--- /dev/null
+++ b/setup_native/source/win32/customactions/patch/swappatchfiles.cxx
@@ -0,0 +1,898 @@
+/*************************************************************************
+ *
+ * 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 <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, elementsof(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, elementsof(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 <= elementsof(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,
+ elementsof(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;
+}
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..25659a0b4109
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/quickstarter.cxx
@@ -0,0 +1,221 @@
+#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 );
+}
+
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..9ec8da1df10f
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/quickstarter.hxx
@@ -0,0 +1,18 @@
+#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 );
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..ef52ecfe2941
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/remove_quickstart_link.cxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..6f931d2b0175
--- /dev/null
+++ b/setup_native/source/win32/customactions/quickstarter/shutdown_quickstart.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
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..dfe1e82e1e9b
--- /dev/null
+++ b/setup_native/source/win32/customactions/rebase/rebase.cxx
@@ -0,0 +1,166 @@
+#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(
+ filePath.c_str(),
+ "",
+ 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;
+}
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 100755
index 000000000000..b6050cb0c2d5
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
@@ -0,0 +1,530 @@
+/*************************************************************************
+ *
+ * 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;
+ }
+ else if ( strncmp( szBuffer, "OpenOffice.org.", 15 ) == 0 )
+ { // We will replace registration for our own types, too
+ bRet = true;
+ }
+ else if ( strncmp( szBuffer, "ooostub.", 8 ) == 0 )
+ { // We will replace registration for ooostub, too
+ bRet = true;
+ }
+ else
+ {
+ OutputDebugStringFormat( " Checking OpenWithList of [%s].\n", lpSubKey );
+ HKEY hSubKey;
+ lResult = RegOpenKeyExA( hKey, "OpenWithList", 0, KEY_ENUMERATE_SUB_KEYS, &hSubKey );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ DWORD nIndex = 0;
+ while ( ERROR_SUCCESS == lResult )
+ {
+ nSize = sizeof( szBuffer );
+ lResult = RegEnumKeyExA( hSubKey, nIndex++, szBuffer, &nSize, NULL, NULL, NULL, NULL );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ OutputDebugStringFormat( " Found value [%s] in OpenWithList of [%s].\n", szBuffer, lpSubKey );
+ if ( strncmp( szBuffer, "WordPad.exe", 11 ) == 0 )
+ { // We will replace registration for word pad
+ bRet = true;
+ }
+ else if ( nSize > 0 )
+ bRet = false;
+ }
+ }
+ }
+ else
+ {
+ OutputDebugStringFormat( " No OpenWithList found!\n" );
+ }
+ }
+ }
+ 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;
+}
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..f37c2060a601
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/constants.hxx
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * 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
+
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..2941ba5a8e27
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/msihelper.cxx
@@ -0,0 +1,102 @@
+#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"));
+}
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..6aa1af9f975b
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/msihelper.hxx
@@ -0,0 +1,184 @@
+#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
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..19623e77ebc3
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/reg4msdocmsi.cxx
@@ -0,0 +1,189 @@
+/*************************************************************************
+ *
+ * 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>
+
+#define ELEMENTS_OF_ARRAY(a) (sizeof(a)/sizeof(a[0]))
+
+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;
+}
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..77d091806acd
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/register.cxx
@@ -0,0 +1,340 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
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..29b9e8bdae00
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/register.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#ifndef _REGISTER_HXX_
+#define _REGISTER_HXX_
+
+#ifndef _CONSTANTS_HXX_
+#include "constants.hxx"
+#endif
+
+#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
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..7919d0fe833d
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrar.cxx
@@ -0,0 +1,759 @@
+// Registrar.cpp: Implementierung der Klasse Registrar.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "registrar.hxx"
+
+#ifndef _REGISTRYVALUEIMPL_HXX_
+#include "RegistryValueImpl.hxx"
+#endif
+#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));
+}
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..529a39d5c9c8
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrar.hxx
@@ -0,0 +1,103 @@
+// Registrar.h: Schnittstelle f�r die Klasse Registrar.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef _REGISTRAR_HXX_
+#define _REGISTRAR_HXX_
+
+#include "registry.hxx"
+#include "registrationcontextinformation.hxx"
+
+#ifndef _CONSTANTS_HXX_
+#include "constants.hxx"
+#endif
+
+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
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..ebe836926337
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.cxx
@@ -0,0 +1,351 @@
+//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);
+}
+
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..aeb6c86c2c3c
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrationcontextinformation.hxx
@@ -0,0 +1,158 @@
+// 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
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..2572a3a2d287
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registry.cxx
@@ -0,0 +1,242 @@
+/*************************************************************************
+ *
+ * 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));
+}
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..791790c1f86c
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registry.hxx
@@ -0,0 +1,338 @@
+/*************************************************************************
+ *
+ * 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
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..9eaa05df38f7
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryexception.cxx
@@ -0,0 +1,111 @@
+// 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)
+{
+};
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..38db0a599e82
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryexception.hxx
@@ -0,0 +1,104 @@
+// 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
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..eabc32f19cff
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.cxx
@@ -0,0 +1,189 @@
+// 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;
+}
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..a64058e29141
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryvalueimpl.hxx
@@ -0,0 +1,108 @@
+// 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
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..620a32f028bb
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryw9x.cxx
@@ -0,0 +1,550 @@
+/*************************************************************************
+ *
+ * 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);
+}
+
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..fce0f14441a3
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registryw9x.hxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * 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
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..361672790630
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx
@@ -0,0 +1,619 @@
+/*************************************************************************
+ *
+ * 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);
+}
+
+
+
+
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..60d625d65a20
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/registrywnt.hxx
@@ -0,0 +1,202 @@
+/*************************************************************************
+ *
+ * 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
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..68d0872ad81a
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/stringconverter.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+#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);
+}
+
+
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..0764da3f64c3
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/stringconverter.hxx
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * 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
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..68d3a1e2205d
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/userregistrar.cxx
@@ -0,0 +1,136 @@
+// 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"
+}
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..926a873e52db
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/userregistrar.hxx
@@ -0,0 +1,43 @@
+// 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
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..1ed544f06806
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/windowsregistry.cxx
@@ -0,0 +1,79 @@
+// 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;
+}
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..a99259d8f0bd
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4msdoc/windowsregistry.hxx
@@ -0,0 +1,40 @@
+// 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
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 100755
index 000000000000..53eb16a99583
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg64/reg64.cxx
@@ -0,0 +1,477 @@
+/*************************************************************************
+*
+ * 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 <string>
+//#include <map>
+#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;
+} \ No newline at end of file
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..037824689a47
--- /dev/null
+++ b/setup_native/source/win32/customactions/regactivex/regactivex.cxx
@@ -0,0 +1,438 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..99efedbb696b
--- /dev/null
+++ b/setup_native/source/win32/customactions/regpatchactivex/regpatchactivex.cxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
+
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..d4dc7d6ecfa6
--- /dev/null
+++ b/setup_native/source/win32/customactions/relnotes/relnotes.cxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * 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.services.openoffice.org/deinstall");
+ aExecInf.lpDirectory = NULL;
+ aExecInf.nShow = SW_SHOWNORMAL;
+
+ SetLastError( 0 );
+ ShellExecuteEx( &aExecInf );
+
+ return ERROR_SUCCESS;
+}
+
diff --git a/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx b/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
new file mode 100755
index 000000000000..ebd9de5e7fbe
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..07c84d890316
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * 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;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx b/setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx
new file mode 100755
index 000000000000..9a028953fef1
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * 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 <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, elementsof(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, elementsof(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 <= elementsof(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;
+}
+
+
+
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..7dc5194a18cb
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..517915cb831f
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..f7cf0247c631
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..0e53492e460f
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/exports.dxp
@@ -0,0 +1,20 @@
+InstallExecSequenceEntry
+DeinstallExecSequenceEntry
+InstallStartmenuFolderIcon
+DeinstallStartmenuFolderIcon
+SetProductInstallMode
+RebuildShellIconCache
+ExecutePostUninstallScript
+MigrateInstallPath
+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 100755
index 000000000000..75b5914bafbc
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/iconcache.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..fb0897e728fe
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/layerlinks.cxx
@@ -0,0 +1,257 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..9eef136a82a4
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/makefile.mk
@@ -0,0 +1,106 @@
+#*************************************************************************
+#
+# 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)$/checkdirectory.obj \
+ $(SLO)$/setadmininstall.obj \
+ $(SLO)$/layerlinks.obj \
+ $(SLO)$/dotnetcheck.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 100755
index 000000000000..c8035799a539
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * 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;
+
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/postuninstall.cxx b/setup_native/source/win32/customactions/shellextensions/postuninstall.cxx
new file mode 100755
index 000000000000..ea9bfae3864b
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/postuninstall.cxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
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..3906d2584fd1
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/registerextensions.cxx
@@ -0,0 +1,573 @@
+/*************************************************************************
+ *
+ * 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 sShareInstallDir = sInstDir + TEXT("share\\extension\\install\\");
+ std::_tstring sPattern = sShareInstallDir + TEXT("*.oxt");
+ std::_tstring mystr;
+
+ WIN32_FIND_DATA aFindFileData;
+
+ mystr = "unopkg file: " + sUnoPkgFile;
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+
+ mystr = "oxt file directory: " + sShareInstallDir;
+ // 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
+
+ // Finding all oxt files in sShareInstallDir
+
+ HANDLE hFindOxt = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( hFindOxt != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+
+ do
+ {
+ const std::_tstring sTempFolder(createTempFolder());
+ std::_tstring sOxtFile = sShareInstallDir + aFindFileData.cFileName;
+ std::_tstring sCommandPart1 = sUnoPkgFile + " add --shared --suppress-license --bundled " + "\"" + sOxtFile + "\"";
+ std::_tstring sCommand = sCommandPart1
+ + 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);
+ // unopkg in OOo 2.2.1 and early had a bug that it failed when receiving
+ // a bootstrap parameter (-env:...) then it exited with a value != 0.
+ if (fSuccess && exitCode != 0)
+ {
+ std::_tstring sCommand = sCommandPart1;
+ mystr = "Command: " + sCommand;
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ 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);
+ // }
+
+ fNextFile = FindNextFile( hFindOxt, &aFindFileData );
+
+ } while ( fNextFile );
+
+ FindClose( hFindOxt );
+ }
+ }
+ // else
+ // {
+ // mystr = "Error: Did not find " + sUnoPkgFile;
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ // }
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall DeregisterExtensions(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;
+ }
+
+ // MessageBox( NULL, sInstDir.c_str(), "install location", MB_OK );
+
+ // Searching for the unopkg.exe
+
+ std::_tstring sUnoPkgFile = sInstDir + TEXT("program\\unopkg.exe");
+ std::_tstring sShareInstallDir = sInstDir + TEXT("share\\extension\\install\\");
+ std::_tstring sPattern = sShareInstallDir + TEXT("*.oxt");
+
+ WIN32_FIND_DATA aFindFileData;
+
+ // Find unopkg.exe
+
+ HANDLE hFindUnopkg = FindFirstFile( sUnoPkgFile.c_str(), &aFindFileData );
+
+ if ( hFindUnopkg != INVALID_HANDLE_VALUE )
+ {
+ // unopkg.exe exists in program directory
+
+ // Finding all oxt files in sShareInstallDir
+
+ HANDLE hFindOxt = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( hFindOxt != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+
+ do
+ {
+ const std::_tstring sTempFolder(createTempFolder());
+ // When removing extensions, only the oxt file name is required, without path
+ // Therefore no quoting is required
+ // std::_tstring sOxtFile = sShareInstallDir + aFindFileData.cFileName;
+ std::_tstring sOxtFile = aFindFileData.cFileName;
+ std::_tstring sCommandPart1 = sUnoPkgFile + " remove --shared --bundled " + "\""
+ + sOxtFile + "\"";
+ std::_tstring sCommand = sCommandPart1
+ + 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);
+ // unopkg in OOo 2.2.1 and early had a bug that it failed when receiving
+ // a bootstrap parameter (-env:...) then it exited with a value != 0.
+ if (fSuccess && exitCode != 0)
+ {
+ std::_tstring sCommand = sCommandPart1;
+ mystr = "Command: " + sCommand;
+ //MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ 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);
+ }
+
+ fNextFile = FindNextFile( hFindOxt, &aFindFileData );
+
+ } while ( fNextFile );
+
+ FindClose( hFindOxt );
+ }
+ }
+ // else
+ // {
+ // mystr = "Not found: " + 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 "share\uno_packages\cache"
+
+ std::_tstring sCacheDir = sInstDir + TEXT("share\\uno_packages\\cache");
+
+ 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;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx b/setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx
new file mode 100755
index 000000000000..6bd57447f092
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..c779e1e5994e
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/shellextensions.cxx
@@ -0,0 +1,213 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..5adab408139d
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..1fb2972d433a
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/upgrade.cxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..70064b58807c
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx
@@ -0,0 +1,242 @@
+/*************************************************************************
+ *
+ * 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;
+}
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..ef30b2f9365f
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/checkversion.cxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * 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;
+}
+
+
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..6d50120ccc18
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/seterror.cxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * 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 );
+}
+
+
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..fad705433aa5
--- /dev/null
+++ b/setup_native/source/win32/customactions/tools/seterror.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * 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
+
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..5185a9ea642e
--- /dev/null
+++ b/setup_native/source/win32/msi-encodinglist.txt
@@ -0,0 +1,140 @@
+# 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-ER 0 1139
+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..7ab14d2a6245
--- /dev/null
+++ b/setup_native/source/win32/nsis/brobanner.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/brobitmap.bmp b/setup_native/source/win32/nsis/brobitmap.bmp
new file mode 100644
index 000000000000..f9e9e9b2d44b
--- /dev/null
+++ b/setup_native/source/win32/nsis/brobitmap.bmp
Binary files differ
diff --git a/setup_native/source/win32/nsis/brosdkbanner.bmp b/setup_native/source/win32/nsis/brosdkbanner.bmp
new file mode 100644
index 000000000000..cbc2704721f8
--- /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..d755dfb5848a
--- /dev/null
+++ b/setup_native/source/win32/nsis/downloadtemplate.nsi
@@ -0,0 +1,432 @@
+!define PRODUCT_NAME "PRODUCTNAMEPLACEHOLDER"
+!define PRODUCT_VERSION "PRODUCTVERSIONPLACEHOLDER"
+!define PRODUCT_PUBLISHER "PUBLISHERPLACEHOLDER"
+!define PRODUCT_WEB_SITE "WEBSITEPLACEHOLDER"
+
+; SetCompressor lzma
+SetCompressor zlib
+
+; 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"
+
+; 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
+
+; 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..ab37b1f587ba
--- /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..c94c3cf0e857
--- /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..ab37b1f587ba
--- /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..86a48d50906a
--- /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 100755
index 000000000000..8a6ee6712814
--- /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..06b8ae0b2a2b
--- /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..654ad1fccf65
--- /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..7951547dcfaf
--- /dev/null
+++ b/setup_native/source/win32/stwrapper/resource.rc
@@ -0,0 +1,125 @@
+#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
+{
+#ifdef LG_D
+ "040704B0", // Germany -> Unicode
+ "040704E4", // Germany -> Windows, Multilingual
+#else
+ "040904B0", // Germany -> Unicode
+ "040904E4", // USA -> Windows, Multilingual
+#endif
+ "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"
+ {
+#ifdef LG_D
+ block "040704E4"
+ {
+ // German StringTable
+ value "CompanyName", "Sun Microsystems, Inc.\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"
+ }
+#else
+ block "040904E4"
+ {
+ // International StringTable
+ value "CompanyName", "Sun Microsystems, Inc.\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"
+ }
+#endif
+ }
+
+ block "VarFileInfo"
+ {
+#ifdef LG_D
+ value "Translation", 0x0407, 1252
+#else
+ value "Translation", 0x0409, 1252
+#endif
+ }
+ }
+
+// 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..b75e8da4cf79
--- /dev/null
+++ b/setup_native/source/win32/stwrapper/stwrapper.cxx
@@ -0,0 +1,495 @@
+#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>
+
+#define elementsof(buf) (sizeof(buf) / sizeof(buf[0]))
+
+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], elementsof( szInstanceURN ));
+ break;
+ }
+
+ case 't':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szTargetURN, lpArgs[i], elementsof( szTargetURN ));
+ break;
+ }
+ case 'p':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szProductName, lpArgs[i], elementsof( szProductName ));
+ break;
+ }
+ case 'e':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szProductVersion, lpArgs[i], elementsof( szProductVersion ));
+ break;
+ }
+ case 'P':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szParentProductName, lpArgs[i], elementsof( szParentProductName ));
+ break;
+ }
+ case 'S':
+ {
+ if ( i < nArgs )
+ ++i;
+ SafeCopy( szProductSource, lpArgs[i], elementsof( 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 \"Sun Microsystems, Inc.\"" ));
+ _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;
+}
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>