summaryrefslogtreecommitdiff
path: root/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx')
-rwxr-xr-xsetup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx530
1 files changed, 530 insertions, 0 deletions
diff --git a/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
new file mode 100755
index 000000000000..b6050cb0c2d5
--- /dev/null
+++ b/setup_native/source/win32/customactions/reg4allmsdoc/reg4allmsi.cxx
@@ -0,0 +1,530 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <string>
+#include <strsafe.h>
+
+//----------------------------------------------------------
+static const CHAR* g_Extensions[] =
+{
+ ".doc", // Microsoft Word Text [0]
+ ".dot", // Microsoft Word Template
+ ".rtf", // rtf text
+ ".docx", // Office Word 2007 XML document
+ ".docm", // Office Word 2007 XML macro-enabled document
+ ".dotx", // Office Word 2007 XML template
+ ".dotm", // Office Word 2007 XML macro-enabled template
+ ".xlw", // Microsoft Excel
+ ".xls", // Microsoft Excel
+ ".xlt", // Microsoft Excel Template
+ ".xlsx", // Office Excel 2007 XML workbook
+ ".xlsm", // Office Excel 2007 XML macro-enabled workbook
+ ".xltx", // Office Excel 2007 XML template
+ ".xltm", // Office Excel 2007 XML macro-enabled template
+ ".xlsb", // Office Excel 2007 binary workbook (BIFF12)
+ ".ppt", // Microsoft Powerpoint
+ ".pps", // Microsoft Powerpoint
+ ".pot", // Microsoft Powerpoint Template
+ ".pptx", // Office PowerPoint 2007 XML presentation
+ ".pptm", // Office PowerPoint 2007 macro-enabled XML presentation
+ ".potx", // Office PowerPoint 2007 XML template
+ ".potm", // Office PowerPoint 2007 macro-enabled XML template
+ ".ppsx", // Office PowerPoint 2007 XML show
+ 0
+};
+
+static const int WORD_START = 0;
+static const int EXCEL_START = 7;
+static const int POWERPOINT_START = 15;
+static const int POWERPOINT_END = 23;
+
+// ".xlam", // Office Excel 2007 XML macro-enabled add-in
+// ".ppam", // Office PowerPoint 2007 macro-enabled XML add-in
+// ".ppsm", // Office PowerPoint 2007 macro-enabled XML show
+
+//----------------------------------------------------------
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
+{
+ CHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugStringA( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCSTR, ... )
+{
+}
+#endif
+
+//----------------------------------------------------------
+static BOOL CheckExtensionInRegistry( LPCSTR lpSubKey )
+{
+ BOOL bRet = false;
+ HKEY hKey = NULL;
+ LONG lResult = RegOpenKeyExA( HKEY_CLASSES_ROOT, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ CHAR szBuffer[1024];
+ DWORD nSize = sizeof( szBuffer );
+
+ lResult = RegQueryValueExA( hKey, "", NULL, NULL, (LPBYTE)szBuffer, &nSize );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ szBuffer[nSize] = '\0';
+ OutputDebugStringFormat( "Found value [%s] for key [%s].\n", szBuffer, lpSubKey );
+
+ if ( strncmp( szBuffer, "WordPad.Document.1", 18 ) == 0 )
+ { // We will replace registration for word pad
+ bRet = true;
+ }
+ else if ( strncmp( szBuffer, "OpenOffice.org.", 15 ) == 0 )
+ { // We will replace registration for our own types, too
+ bRet = true;
+ }
+ else if ( strncmp( szBuffer, "ooostub.", 8 ) == 0 )
+ { // We will replace registration for ooostub, too
+ bRet = true;
+ }
+ else
+ {
+ OutputDebugStringFormat( " Checking OpenWithList of [%s].\n", lpSubKey );
+ HKEY hSubKey;
+ lResult = RegOpenKeyExA( hKey, "OpenWithList", 0, KEY_ENUMERATE_SUB_KEYS, &hSubKey );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ DWORD nIndex = 0;
+ while ( ERROR_SUCCESS == lResult )
+ {
+ nSize = sizeof( szBuffer );
+ lResult = RegEnumKeyExA( hSubKey, nIndex++, szBuffer, &nSize, NULL, NULL, NULL, NULL );
+ if ( ERROR_SUCCESS == lResult )
+ {
+ OutputDebugStringFormat( " Found value [%s] in OpenWithList of [%s].\n", szBuffer, lpSubKey );
+ if ( strncmp( szBuffer, "WordPad.exe", 11 ) == 0 )
+ { // We will replace registration for word pad
+ bRet = true;
+ }
+ else if ( nSize > 0 )
+ bRet = false;
+ }
+ }
+ }
+ else
+ {
+ OutputDebugStringFormat( " No OpenWithList found!\n" );
+ }
+ }
+ }
+ else // no default value found -> return TRUE to register for that key
+ bRet = true;
+
+ RegCloseKey( hKey );
+ }
+ else // no key found -> return TRUE to register for that key
+ bRet = true;
+
+ return bRet;
+}
+
+//----------------------------------------------------------
+static LONG DeleteSubKeyTree( HKEY RootKey, LPCSTR lpKey )
+{
+ HKEY hKey;
+ LONG rc = RegOpenKeyExA( RootKey, lpKey, 0, KEY_READ | DELETE, &hKey );
+
+ if (ERROR_SUCCESS == rc)
+ {
+ LPCSTR lpSubKey;
+ DWORD nMaxSubKeyLen;
+
+ rc = RegQueryInfoKeyA( hKey, 0, 0, 0, 0, &nMaxSubKeyLen, 0, 0, 0, 0, 0, 0 );
+ nMaxSubKeyLen++; // space for trailing '\0'
+ lpSubKey = reinterpret_cast<CHAR*>( _alloca( nMaxSubKeyLen*sizeof(CHAR) ) );
+
+ while (ERROR_SUCCESS == rc)
+ {
+ DWORD nLen = nMaxSubKeyLen;
+ rc = RegEnumKeyExA( hKey, 0, (LPSTR)lpSubKey, &nLen, 0, 0, 0, 0); // always index zero
+
+ if ( ERROR_NO_MORE_ITEMS == rc )
+ {
+ rc = RegDeleteKeyA( RootKey, lpKey );
+ if ( rc == ERROR_SUCCESS )
+ OutputDebugStringFormat( "deleted key [%s] from registry.\n", lpKey );
+ else
+ OutputDebugStringFormat( "RegDeleteKeyA %s returned %ld.\n", lpKey, rc );
+ break;
+ }
+ else if ( rc == ERROR_SUCCESS )
+ {
+ rc = DeleteSubKeyTree( hKey, lpSubKey );
+ if ( ERROR_SUCCESS != rc )
+ OutputDebugStringFormat( "RegDeleteKeyA %s returned %ld.\n", lpSubKey, rc );
+ }
+
+ }
+ RegCloseKey(hKey);
+ }
+ else
+ {
+ OutputDebugStringFormat( "RegOpenKeyExA %s returned %ld.\n", lpKey, rc );
+ }
+
+ return rc;
+}
+
+//----------------------------------------------------------
+static BOOL RemoveExtensionInRegistry( LPCSTR lpSubKey )
+{
+ CHAR szBuffer[4096];
+ DWORD nSize = sizeof( szBuffer );
+ HKEY hKey = NULL;
+ HKEY hSubKey = NULL;
+ LONG lResult = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes", 0, KEY_QUERY_VALUE, &hKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ lResult = RegOpenKeyExA( hKey, lpSubKey, 0, KEY_QUERY_VALUE, &hSubKey );
+
+ if ( ERROR_SUCCESS == lResult )
+ {
+ DWORD nSubKeys = 1;
+ szBuffer[0] = '\0';
+
+ // we get the value of the default key fist and while we are on querying,
+ // we ask for the subkey count, too
+ lResult = RegQueryValueExA( hSubKey, "", NULL, NULL, (LPBYTE)szBuffer, &nSize );
+ if ( ERROR_SUCCESS == lResult )
+ RegQueryInfoKeyA( hSubKey, 0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0 );
+ RegCloseKey( hSubKey );
+
+ // we will remove all key with an default value starting with ooostub but
+ // we have to be careful about MSO keys
+ if ( strncmp( szBuffer, "opendocument.", 13 ) == 0 )
+ {
+ if ( nSubKeys == 0 )
+ {
+ DeleteSubKeyTree( hKey, lpSubKey );
+ }
+ else
+ {
+ lResult = RegOpenKeyExA( hKey, lpSubKey, 0, KEY_SET_VALUE, &hSubKey );
+ if ( ERROR_SUCCESS == lResult )
+ RegDeleteValueA( hSubKey, "" );
+ else
+ OutputDebugStringFormat( "Could not open key %s for deleting: RegOpenKeyEx returned %ld.\n", lpSubKey, lResult );
+ }
+ }
+ }
+
+ RegCloseKey( hKey );
+ }
+
+ return ( ERROR_SUCCESS == lResult );
+}
+
+//----------------------------------------------------------
+bool GetMsiProp( MSIHANDLE handle, LPCSTR name, /*out*/std::string& value )
+{
+ DWORD sz = 0;
+ LPSTR dummy = "";
+ if (MsiGetPropertyA(handle, name, dummy, &sz) == ERROR_MORE_DATA)
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof(TCHAR);
+ LPSTR buff = reinterpret_cast<LPSTR>(_alloca(nbytes));
+ ZeroMemory(buff, nbytes);
+ MsiGetPropertyA(handle, name, buff, &sz);
+ value = buff;
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------
+bool IsSetMsiProp( MSIHANDLE handle, LPCSTR name )
+{
+ std::string val;
+ GetMsiProp( handle, name, val );
+ return (val == "1");
+}
+
+//----------------------------------------------------------
+static void registerForExtension( MSIHANDLE handle, const int nIndex, bool bRegister )
+{
+ CHAR sPropName[256];
+ StringCchCopyA( sPropName, 256, "REGISTER_" );
+ StringCchCatA( sPropName, 256, (g_Extensions[nIndex])+1 );
+ CharUpperBuffA( sPropName+9, 4 );
+
+ if ( bRegister ) {
+ MsiSetPropertyA( handle, sPropName, "1" );
+ OutputDebugStringFormat( "Set MSI property %s.\n", sPropName );
+ } else {
+ MsiSetPropertyA( handle, sPropName, "0" );
+ OutputDebugStringFormat( "Unset MSI property %s.\n", sPropName );
+ }
+}
+
+//----------------------------------------------------------
+static void registerForExtensions( MSIHANDLE handle, BOOL bRegisterAll )
+{ // Check all file extensions
+ int nIndex = 0;
+ while ( g_Extensions[nIndex] != 0 )
+ {
+ BOOL bRegister = bRegisterAll || CheckExtensionInRegistry( g_Extensions[nIndex] );
+ if ( bRegister )
+ registerForExtension( handle, nIndex, true );
+ ++nIndex;
+ }
+}
+
+//----------------------------------------------------------
+static bool checkSomeExtensionInRegistry( const int nStart, const int nEnd )
+{ // Check all file extensions
+ int nIndex = nStart;
+ bool bFound = false;
+
+ while ( !bFound && ( g_Extensions[nIndex] != 0 ) && ( nIndex < nEnd ) )
+ {
+ bFound = ! CheckExtensionInRegistry( g_Extensions[nIndex] );
+
+ if ( bFound )
+ OutputDebugStringFormat( "Found registration for [%s].\n", g_Extensions[nIndex] );
+
+ ++nIndex;
+ }
+ return bFound;
+}
+
+//----------------------------------------------------------
+static void registerSomeExtensions( MSIHANDLE handle, const int nStart, const int nEnd, bool bRegister )
+{ // Check all file extensions
+ int nIndex = nStart;
+
+ while ( ( g_Extensions[nIndex] != 0 ) && ( nIndex < nEnd ) )
+ {
+ registerForExtension( handle, nIndex++, bRegister );
+ }
+}
+
+//----------------------------------------------------------
+//----------------------------------------------------------
+//----------------------------------------------------------
+extern "C" UINT __stdcall LookForRegisteredExtensions( MSIHANDLE handle )
+{
+ OutputDebugStringFormat( "LookForRegisteredExtensions: " );
+
+ INSTALLSTATE current_state;
+ INSTALLSTATE future_state;
+
+ bool bWriterEnabled = false;
+ bool bCalcEnabled = false;
+ bool bImpressEnabled = false;
+ bool bRegisterNone = IsSetMsiProp( handle, "REGISTER_NO_MSO_TYPES" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureState( handle, L"gm_p_Wrt", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bWriterEnabled = true;
+
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Install state Writer is [%d], will be [%d]", current_state, future_state );
+ if ( bWriterEnabled )
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Writer is enabled" );
+ else
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Writer is NOT enabled" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureState( handle, L"gm_p_Calc", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bCalcEnabled = true;
+
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Install state Calc is [%d], will be [%d]", current_state, future_state );
+ if ( bCalcEnabled )
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Calc is enabled" );
+ else
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Calc is NOT enabled" );
+
+ if ( ( ERROR_SUCCESS == MsiGetFeatureState( handle, L"gm_p_Impress", &current_state, &future_state ) ) &&
+ ( (future_state == INSTALLSTATE_LOCAL) || ((current_state == INSTALLSTATE_LOCAL) && (future_state == INSTALLSTATE_UNKNOWN) ) ) )
+ bImpressEnabled = true;
+
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Install state Impress is [%d], will be [%d]", current_state, future_state );
+ if ( bImpressEnabled )
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Impress is enabled" );
+ else
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Impress is NOT enabled" );
+
+ MsiSetPropertyA( handle, "SELECT_WORD", "" );
+ MsiSetPropertyA( handle, "SELECT_EXCEL", "" );
+ MsiSetPropertyA( handle, "SELECT_POWERPOINT", "" );
+
+ if ( ! bRegisterNone )
+ {
+ if ( IsSetMsiProp( handle, "REGISTER_ALL_MSO_TYPES" ) )
+ {
+ if ( bWriterEnabled )
+ MsiSetPropertyA( handle, "SELECT_WORD", "1" );
+ if ( bCalcEnabled )
+ MsiSetPropertyA( handle, "SELECT_EXCEL", "1" );
+ if ( bImpressEnabled )
+ MsiSetPropertyA( handle, "SELECT_POWERPOINT", "1" );
+ }
+ else
+ {
+ if ( bWriterEnabled && ! checkSomeExtensionInRegistry( WORD_START, EXCEL_START ) )
+ {
+ MsiSetPropertyA( handle, "SELECT_WORD", "1" );
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Register for MicroSoft Word" );
+ }
+ if ( bCalcEnabled && ! checkSomeExtensionInRegistry( EXCEL_START, POWERPOINT_START ) )
+ {
+ MsiSetPropertyA( handle, "SELECT_EXCEL", "1" );
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Register for MicroSoft Excel" );
+ }
+ if ( bImpressEnabled && ! checkSomeExtensionInRegistry( POWERPOINT_START, POWERPOINT_END ) )
+ {
+ MsiSetPropertyA( handle, "SELECT_POWERPOINT", "1" );
+ OutputDebugStringFormat( "LookForRegisteredExtensions: Register for MicroSoft PowerPoint" );
+ }
+ }
+ }
+
+ MsiSetPropertyA( handle, "FILETYPEDIALOGUSED", "1" );
+
+ return ERROR_SUCCESS;
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall RegisterSomeExtensions( MSIHANDLE handle )
+{
+ OutputDebugStringFormat( "RegisterSomeExtensions: " );
+
+ if ( IsSetMsiProp( handle, "SELECT_WORD" ) )
+ {
+ registerSomeExtensions( handle, WORD_START, EXCEL_START, true );
+ MsiSetFeatureState( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormat( "RegisterSomeExtensions: Register for MicroSoft Word" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, WORD_START, EXCEL_START, false );
+ MsiSetFeatureState( handle, L"gm_p_Wrt_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+
+ if ( IsSetMsiProp( handle, "SELECT_EXCEL" ) )
+ {
+ registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, true );
+ MsiSetFeatureState( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormat( "RegisterSomeExtensions: Register for MicroSoft Excel" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, false );
+ MsiSetFeatureState( handle, L"gm_p_Calc_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+
+ if ( IsSetMsiProp( handle, "SELECT_POWERPOINT" ) )
+ {
+ registerSomeExtensions( handle, POWERPOINT_START, POWERPOINT_END, true );
+ MsiSetFeatureState( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_LOCAL );
+ OutputDebugStringFormat( "RegisterSomeExtensions: Register for MicroSoft PowerPoint" );
+ }
+ else
+ {
+ registerSomeExtensions( handle, POWERPOINT_START, POWERPOINT_END, false );
+ MsiSetFeatureState( handle, L"gm_p_Impress_MSO_Reg", INSTALLSTATE_ABSENT );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall FindRegisteredExtensions( MSIHANDLE handle )
+{
+ if ( IsSetMsiProp( handle, "FILETYPEDIALOGUSED" ) )
+ {
+ OutputDebugStringFormat( "FindRegisteredExtensions: FILETYPEDIALOGUSED!" );
+ return ERROR_SUCCESS;
+ }
+
+ OutputDebugStringFormat( "FindRegisteredExtensions:" );
+
+ bool bRegisterAll = IsSetMsiProp( handle, "REGISTER_ALL_MSO_TYPES" );
+
+ if ( IsSetMsiProp( handle, "REGISTER_NO_MSO_TYPES" ) )
+ {
+ OutputDebugStringFormat( "FindRegisteredExtensions: Register none!" );
+ return ERROR_SUCCESS;
+ }
+ else if ( bRegisterAll )
+ OutputDebugStringFormat( "FindRegisteredExtensions: Force all on" );
+ else
+ OutputDebugStringFormat( "FindRegisteredExtensions: " );
+
+ // setting the msi properties SELECT_* will force registering for all corresponding
+ // file types
+ if ( IsSetMsiProp( handle, "SELECT_WORD" ) )
+ registerSomeExtensions( handle, WORD_START, EXCEL_START, true );
+ if ( IsSetMsiProp( handle, "SELECT_EXCEL" ) )
+ registerSomeExtensions( handle, EXCEL_START, POWERPOINT_START, true );
+ if ( IsSetMsiProp( handle, "SELECT_POWERPOINT" ) )
+ registerSomeExtensions( handle, POWERPOINT_START, POWERPOINT_END, true );
+
+ registerForExtensions( handle, bRegisterAll );
+
+ return ERROR_SUCCESS;
+}
+
+//----------------------------------------------------------
+extern "C" UINT __stdcall DeleteRegisteredExtensions( MSIHANDLE /*handle*/ )
+{
+ OutputDebugStringFormat( "DeleteRegisteredExtensions\n" );
+
+ // remove all file extensions
+ int nIndex = 0;
+ while ( g_Extensions[nIndex] != 0 )
+ {
+ RemoveExtensionInRegistry( g_Extensions[nIndex] );
+ ++nIndex;
+ }
+
+ return ERROR_SUCCESS;
+}