diff options
Diffstat (limited to 'setup_native/source/win32/customactions/reg4msdoc')
28 files changed, 5479 insertions, 0 deletions
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..8cfc1fb08597 --- /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("OFFICEINSTALLLOCATION"), 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, ¤t_state, &future_state); + return (current_state == INSTALLSTATE_LOCAL); +} + +bool IsModuleSelectedForInstallation(MSIHANDLE handle, LPCTSTR name) +{ + INSTALLSTATE current_state; + INSTALLSTATE future_state; + MsiGetFeatureState(handle, name, ¤t_state, &future_state); + return (future_state == INSTALLSTATE_LOCAL); +} + +bool IsModuleSelectedForDeinstallation(MSIHANDLE handle, LPCTSTR name) +{ + INSTALLSTATE current_state; + INSTALLSTATE future_state; + MsiGetFeatureState(handle, name, ¤t_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 |