summaryrefslogtreecommitdiff
path: root/setup_native/source/win32/customactions/shellextensions
diff options
context:
space:
mode:
Diffstat (limited to 'setup_native/source/win32/customactions/shellextensions')
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/checkdirectory.cxx117
-rw-r--r--setup_native/source/win32/customactions/shellextensions/checkpatches.cxx113
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx290
-rw-r--r--setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx130
-rw-r--r--setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx124
-rw-r--r--setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx181
-rw-r--r--setup_native/source/win32/customactions/shellextensions/exports.dxp20
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/iconcache.cxx110
-rw-r--r--setup_native/source/win32/customactions/shellextensions/layerlinks.cxx257
-rw-r--r--setup_native/source/win32/customactions/shellextensions/makefile.mk106
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx117
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/postuninstall.cxx155
-rw-r--r--setup_native/source/win32/customactions/shellextensions/registerextensions.cxx573
-rwxr-xr-xsetup_native/source/win32/customactions/shellextensions/setadmininstall.cxx66
-rw-r--r--setup_native/source/win32/customactions/shellextensions/shellextensions.cxx213
-rw-r--r--setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx142
-rw-r--r--setup_native/source/win32/customactions/shellextensions/upgrade.cxx204
-rw-r--r--setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx242
18 files changed, 3160 insertions, 0 deletions
diff --git a/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx b/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
new file mode 100755
index 000000000000..ebd9de5e7fbe
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkdirectory.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINNT 0x0401
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+static void UnsetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+}
+
+static void SetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty, const std::_tstring&)
+{
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+}
+
+extern "C" UINT __stdcall CheckInstallDirectory(MSIHANDLE handle)
+{
+ std::_tstring sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+ std::_tstring sOfficeHostnamePath = GetMsiProperty(handle, TEXT("OFFICEDIRHOSTNAME"));
+
+ // MessageBox(NULL, sInstallPath.c_str(), "DEBUG", MB_OK);
+
+ // unsetting all properties
+
+ UnsetMsiProperty( handle, TEXT("DIRECTORY_NOT_EMPTY") );
+
+ // 1. Searching for file setup.ini
+
+ std::_tstring sSetupIniPath = sInstallPath + sOfficeHostnamePath + TEXT("\\program\\setup.ini");
+
+ WIN32_FIND_DATA data;
+ HANDLE hdl = FindFirstFile(sSetupIniPath.c_str(), &data);
+
+ // std::_tstring mystr = "Searching for " + sSetupIniPath;
+ // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);
+
+ if ( IsValidHandle(hdl) )
+ {
+ // setup.ini found -> directory cannot be used for installation.
+ SetMsiProperty( handle, TEXT("DIRECTORY_NOT_EMPTY"), TEXT("1") );
+ SetMsiErrorCode( MSI_ERROR_DIRECTORY_NOT_EMPTY );
+ // std::_tstring notEmptyStr = "Directory is not empty. Please choose another installation directory.";
+ // std::_tstring notEmptyTitle = "Directory not empty";
+ // MessageBox(NULL, notEmptyStr.c_str(), notEmptyTitle.c_str(), MB_OK);
+ }
+
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx b/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx
new file mode 100644
index 000000000000..07c84d890316
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkpatches.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINNT 0x0401
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+#include <strsafe.h>
+
+#include <systools/win32/uwinapi.h>
+
+//----------------------------------------------------------
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
+{
+ CHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugStringA( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCSTR, ... )
+{
+}
+#endif
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+static void SetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ MsiSetProperty( handle, sProperty.c_str(), TEXT("1") );
+}
+
+extern "C" UINT __stdcall CheckPatchList( MSIHANDLE handle )
+{
+ std::_tstring sPatchList = GetMsiProperty( handle, TEXT("PATCH") );
+ std::_tstring sRequiredPatch = GetMsiProperty( handle, TEXT("PREREQUIREDPATCH") );
+
+ OutputDebugStringFormat( "CheckPatchList called with PATCH=%s and PRQ= %s\n", sPatchList.c_str(), sRequiredPatch.c_str() );
+
+ if ( ( sPatchList.length() != 0 ) && ( sRequiredPatch.length() != 0 ) )
+ {
+ if ( _tcsstr( sPatchList.c_str(), sRequiredPatch.c_str() ) )
+ {
+ SetMsiProperty( handle, TEXT("IGNOREPREREQUIREDPATCH") );
+ OutputDebugStringFormat( "Set Property IgnorePrerequiredPatch!\n" );
+ }
+ }
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx b/setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx
new file mode 100755
index 000000000000..9a028953fef1
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/checkrunningoffice.cxx
@@ -0,0 +1,290 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+#define WININIT_FILENAME "wininit.ini"
+#define RENAME_SECTION "rename"
+
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
+{
+ _TCHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ _vsntprintf( buffer, elementsof(buffer), pFormat, args );
+ OutputDebugString( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCTSTR, ... )
+{
+}
+#endif
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+static inline bool IsSetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ std::_tstring value = GetMsiProperty(handle, sProperty);
+ return (value.length() > 0);
+}
+
+static inline void UnsetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+}
+
+static inline void SetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+}
+
+static BOOL MoveFileEx9x( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
+{
+ BOOL fSuccess = FALSE; // assume failure
+
+ // Windows 9x has a special mechanism to move files after reboot
+
+ if ( dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT )
+ {
+ CHAR szExistingFileNameA[MAX_PATH];
+ CHAR szNewFileNameA[MAX_PATH] = "NUL";
+
+ // Path names in WININIT.INI must be in short path name form
+
+ if (
+ GetShortPathNameA( lpExistingFileNameA, szExistingFileNameA, MAX_PATH ) &&
+ (!lpNewFileNameA || GetShortPathNameA( lpNewFileNameA, szNewFileNameA, MAX_PATH ))
+ )
+ {
+ CHAR szBuffer[32767]; // The buffer size must not exceed 32K
+ DWORD dwBufLen = GetPrivateProfileSectionA( RENAME_SECTION, szBuffer, elementsof(szBuffer), WININIT_FILENAME );
+
+ CHAR szRename[MAX_PATH]; // This is enough for at most to times 67 chracters
+ strcpy( szRename, szNewFileNameA );
+ strcat( szRename, "=" );
+ strcat( szRename, szExistingFileNameA );
+ size_t lnRename = strlen(szRename);
+
+ if ( dwBufLen + lnRename + 2 <= elementsof(szBuffer) )
+ {
+ CopyMemory( &szBuffer[dwBufLen], szRename, lnRename );
+ szBuffer[dwBufLen + lnRename ] = 0;
+ szBuffer[dwBufLen + lnRename + 1 ] = 0;
+
+ fSuccess = WritePrivateProfileSectionA( RENAME_SECTION, szBuffer, WININIT_FILENAME );
+ }
+ else
+ SetLastError( ERROR_BUFFER_OVERFLOW );
+ }
+ }
+ else
+ {
+
+ fSuccess = MoveFileA( lpExistingFileNameA, lpNewFileNameA );
+
+ if ( !fSuccess && GetLastError() != ERROR_ACCESS_DENIED &&
+ 0 != (dwFlags & (MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) )
+ {
+ BOOL bFailIfExist = 0 == (dwFlags & MOVEFILE_REPLACE_EXISTING);
+
+ fSuccess = CopyFileA( lpExistingFileNameA, lpNewFileNameA, bFailIfExist );
+
+ if ( fSuccess )
+ fSuccess = DeleteFileA( lpExistingFileNameA );
+ }
+
+ }
+
+ return fSuccess;
+}
+
+static BOOL MoveFileExImpl( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
+{
+ if ( 0 > ((LONG)GetVersion())) // High order bit indicates Win 9x
+ return MoveFileEx9x( lpExistingFileNameA, lpNewFileNameA, dwFlags );
+ else
+ return MoveFileExA( lpExistingFileNameA, lpNewFileNameA, dwFlags );
+}
+
+extern "C" UINT __stdcall IsOfficeRunning( MSIHANDLE handle )
+{
+ OSVERSIONINFO osverinfo;
+ osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx( &osverinfo );
+
+ // renaming the vcl resource doesn't work reliable with OS >= Windows Vista
+ if (osverinfo.dwMajorVersion < 6 )
+ {
+ std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ // Property empty -> no office installed
+ if ( sInstDir.length() == 0 )
+ return ERROR_SUCCESS;
+
+ std::_tstring sResourceDir = sInstDir + TEXT("Basis\\program\\resource\\");
+ std::_tstring sPattern = sResourceDir + TEXT("vcl*.res");
+
+// std::_tstring mystr;
+// mystr = "IsOfficeRunning start. Checking file in dir: " + sResourceDir;
+// MessageBox( NULL, mystr.c_str(), "IsOfficeRunning", MB_OK );
+
+ WIN32_FIND_DATA aFindFileData;
+ HANDLE hFind = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( IsValidHandle(hFind) )
+ {
+ BOOL fSuccess = false;
+ bool fRenameSucceeded;
+
+ do
+ {
+ std::_tstring sResourceFile = sResourceDir + aFindFileData.cFileName;
+ std::_tstring sIntermediate = sResourceFile + TEXT(".tmp");
+
+ fRenameSucceeded = MoveFileExImpl( sResourceFile.c_str(), sIntermediate.c_str(), MOVEFILE_REPLACE_EXISTING );
+ if ( fRenameSucceeded )
+ {
+ MoveFileExImpl( sIntermediate.c_str(), sResourceFile.c_str(), 0 );
+ fSuccess = FindNextFile( hFind, &aFindFileData );
+ }
+ } while ( fSuccess && fRenameSucceeded );
+
+ if ( !fRenameSucceeded )
+ {
+ MsiSetProperty(handle, TEXT("OFFICERUNS"), TEXT("1"));
+ SetMsiErrorCode( MSI_ERROR_OFFICE_IS_RUNNING );
+
+// mystr = "Office is running";
+// MessageBox( NULL, mystr.c_str(), "IsOfficeRunning", MB_OK );
+ }
+
+ FindClose( hFind );
+ }
+// mystr = "IsOfficeRunning end";
+// MessageBox( NULL, mystr.c_str(), "IsOfficeRunning", MB_OK );
+ }
+ else
+ {
+ std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+ // Property empty -> no office installed
+ if ( sOfficeInstallPath.length() == 0 )
+ return ERROR_SUCCESS;
+
+ std::_tstring sRenameSrc = sOfficeInstallPath + TEXT("program");
+ std::_tstring sRenameDst = sOfficeInstallPath + TEXT("program_test");
+
+ bool bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
+
+ if ( bSuccess )
+ {
+ MoveFile( sRenameDst.c_str(), sRenameSrc.c_str() );
+ }
+ else
+ {
+ DWORD dwError = GetLastError();
+ LPVOID lpMsgBuf;
+ // When there is no program folder, there could be no running office
+ if ( dwError == ERROR_FILE_NOT_FOUND )
+ return ERROR_SUCCESS;
+ if ( dwError == ERROR_PATH_NOT_FOUND )
+ return ERROR_SUCCESS;
+
+ // The destination folder should never exist, don't know what to do here
+ if ( dwError == ERROR_ALREADY_EXISTS )
+ return ERROR_SUCCESS;
+
+ if ( FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL ))
+ {
+ OutputDebugStringFormat( TEXT("Error Code %d: %s"), dwError, lpMsgBuf );
+ LocalFree( lpMsgBuf );
+ }
+ else
+ OutputDebugStringFormat( TEXT("Error Code %d: Unknown"), dwError );
+
+ MsiSetProperty( handle, TEXT("OFFICERUNS"), TEXT("1") );
+ SetMsiErrorCode( MSI_ERROR_OFFICE_IS_RUNNING );
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+
diff --git a/setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx b/setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx
new file mode 100644
index 000000000000..7dc5194a18cb
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/copyeditiondata.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <new>
+#include <string.h> // <cstring> not supported by old MSC versions
+
+#define WIN32_LEAN_AND_MEAN
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#include <shellapi.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include "boost/scoped_array.hpp"
+
+#define LCL_LENGTH0(s) (sizeof (s) / sizeof *(s))
+#define LCL_STRING0(s) (s), LCL_LENGTH0(s)
+
+namespace {
+
+enum Status { STATUS_NO, STATUS_YES, STATUS_ERROR };
+
+Status fileExists(wchar_t const * path) {
+ return GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES
+ ? GetLastError() == ERROR_FILE_NOT_FOUND ? STATUS_NO : STATUS_ERROR
+ : STATUS_YES;
+}
+
+wchar_t * getProperty(
+ MSIHANDLE install, wchar_t const * name, wchar_t const * suffix,
+ std::size_t suffixLength, wchar_t ** end = NULL)
+{
+ DWORD n = 0;
+ UINT err = MsiGetPropertyW(install, name, L"", &n);
+ if (err != ERROR_SUCCESS && err != ERROR_MORE_DATA) {
+ return NULL;
+ }
+ DWORD n2 = n + suffixLength; //TODO: overflow
+ wchar_t * data = new(std::nothrow) wchar_t[n2];
+ if (data == NULL) {
+ return NULL;
+ }
+ if (MsiGetPropertyW(install, name, data, &n2) != ERROR_SUCCESS || n2 != n) {
+ delete[] data;
+ return NULL;
+ }
+ memcpy(data + n, suffix, suffixLength * sizeof (wchar_t)); //TODO: overflow
+ if (end != NULL) {
+ *end = data + n + suffixLength;
+ }
+ return data;
+}
+
+}
+
+extern "C" UINT __stdcall copyEditionData(MSIHANDLE install) {
+ boost::scoped_array<wchar_t> from(
+ getProperty(install, L"SourceDir", LCL_STRING0(L"edition\0")));
+ if (!from) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ Status stat = fileExists(from.get());
+ if (stat == STATUS_ERROR) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ if (stat == STATUS_NO) {
+ return ERROR_SUCCESS;
+ }
+ wchar_t * end;
+ boost::scoped_array<wchar_t> to(
+ getProperty(
+ install, L"INSTALLLOCATION",
+ LCL_STRING0(L"program\\edition\0"), &end));
+ if (!to) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ stat = fileExists(to.get());
+ if (stat == STATUS_ERROR) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ if (stat == STATUS_YES) {
+ SHFILEOPSTRUCTW opDelete = {
+ NULL, FO_DELETE, to.get(), NULL, FOF_NOCONFIRMATION | FOF_SILENT,
+ FALSE, NULL, NULL }; //TODO: non-NULL hwnd
+ if (SHFileOperationW(&opDelete) != 0) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ }
+ *(end - LCL_LENGTH0(L"\\edition\0")) = L'\0';
+ *(end - LCL_LENGTH0(L"\\edition\0") + 1) = L'\0';
+ SHFILEOPSTRUCTW opCopy = {
+ NULL, FO_COPY, from.get(), to.get(),
+ FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SILENT, FALSE, NULL,
+ NULL }; //TODO: non-NULL hwnd
+ if (SHFileOperationW(&opCopy) != 0) {
+ return ERROR_INSTALL_FAILURE;
+ }
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx b/setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx
new file mode 100644
index 000000000000..517915cb831f
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/copyextensiondata.cxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#include <shellapi.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+#include <string.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+extern "C" UINT __stdcall copyExtensionData(MSIHANDLE handle) {
+
+ std::_tstring sSourceDir = GetMsiProperty( handle, TEXT("SourceDir") );
+ std::_tstring sExtensionDir = sSourceDir + TEXT("extension\\");
+ std::_tstring sPattern = sExtensionDir + TEXT("*.oxt");
+ // std::_tstring mystr;
+
+ // Finding all oxt files in sExtensionDir
+
+ WIN32_FIND_DATA aFindFileData;
+
+ HANDLE hFindOxt = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( hFindOxt != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+ bool fSuccess = true;
+ bool bFailIfExist = true;
+
+ std::_tstring sDestDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ std::_tstring sShareInstallDir = sDestDir + TEXT("share\\extension\\install\\");
+
+ // creating directories
+ std::_tstring sShareDir = sDestDir + TEXT("share");
+ std::_tstring sExtDir = sShareDir + TEXT("\\extension");
+ std::_tstring sExtInstDir = sExtDir + TEXT("\\install");
+ bool bDir = CreateDirectory(sShareDir.c_str(), NULL);
+ bDir = CreateDirectory(sExtDir.c_str(), NULL);
+ bDir = CreateDirectory(sExtInstDir.c_str(), NULL);
+
+ do
+ {
+ std::_tstring sOxtFile = aFindFileData.cFileName;
+
+ std::_tstring sSourceFile = sExtensionDir + sOxtFile;
+ std::_tstring sDestFile = sShareInstallDir + sOxtFile;
+
+ fSuccess = CopyFile( sSourceFile.c_str(), sDestFile.c_str(), bFailIfExist );
+
+ fNextFile = FindNextFile( hFindOxt, &aFindFileData );
+
+ } while ( fNextFile );
+
+ FindClose( hFindOxt );
+ }
+
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx b/setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx
new file mode 100644
index 000000000000..f7cf0247c631
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/dotnetcheck.cxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#include <tchar.h>
+#include <string>
+#include <systools/win32/uwinapi.h>
+
+#include <../tools/seterror.hxx>
+
+using namespace std;
+
+namespace
+{
+ string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ string result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+ return result;
+ }
+
+ inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string& sValue)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), sValue.c_str());
+ }
+
+ void stripFinalBackslash(std::string * path) {
+ std::string::size_type i = path->size();
+ if (i > 1) {
+ --i;
+ if ((*path)[i] == '\\') {
+ path->erase(i);
+ }
+ }
+ }
+
+// Copied more or less verbatim from
+// desktop/source/deployment/inc/dp_version.hxx:1.5 and
+// desktop/source/deployment/misc/dp_version.cxx:1.5:
+
+enum Order { ORDER_LESS, ORDER_EQUAL, ORDER_GREATER };
+
+string getElement(string const & version, string::size_type * index) {
+ while (*index < version.size() && version[*index] == '0') {
+ ++*index;
+ }
+ string::size_type i = *index;
+ *index = version.find('.', i);
+ if (*index == string::npos) {
+ *index = version.size();
+ return string(version, i);
+ } else {
+ ++*index;
+ return string(version, i, *index - 1 - i);
+ }
+}
+
+Order compareVersions(string const & version1, string const & version2) {
+ for (string::size_type i1 = 0, i2 = 0;
+ i1 < version1.size() || i2 < version2.size();)
+ {
+ string e1(getElement(version1, &i1));
+ string e2(getElement(version2, &i2));
+
+ // string myText1 = TEXT("e1: ") + e1;
+ // string myText2 = TEXT("e2: ") + e2;
+ // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
+ // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
+
+ if (e1.size() < e2.size()) {
+ return ORDER_LESS;
+ } else if (e1.size() > e2.size()) {
+ return ORDER_GREATER;
+ } else if (e1 < e2) {
+ return ORDER_LESS;
+ } else if (e1 > e2) {
+ return ORDER_GREATER;
+ }
+ }
+ return ORDER_EQUAL;
+}
+
+} // namespace
+
+extern "C" UINT __stdcall DotNetCheck(MSIHANDLE handle) {
+ string present(GetMsiProperty(handle, TEXT("MsiNetAssemblySupport")));
+ string required(GetMsiProperty(handle, TEXT("REQUIRED_DOTNET_VERSION")));
+
+ // string myText1 = TEXT("MsiNetAssemblySupport: ") + present;
+ // string myText2 = TEXT("REQUIRED_DOTNET_VERSION: ") + required;
+ // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
+ // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
+
+ SetMsiProperty(
+ handle, TEXT("DOTNET_SUFFICIENT"),
+ (present.empty() || compareVersions(present, required) == ORDER_LESS ?
+ TEXT("0") : TEXT("1")));
+
+ // string result(GetMsiProperty(handle, TEXT("DOTNET_SUFFICIENT")));
+ // string myText3 = TEXT("DOTNET_SUFFICIENT: ") + result;
+ // MessageBox(NULL, myText3.c_str(), "DEBUG", MB_OK);
+
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall ShowProperties(MSIHANDLE handle)
+{
+ string property = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+ string myText = TEXT("INSTALLLOCATION: ") + property;
+ MessageBox(NULL, myText.c_str(), "INSTALLLOCATION", MB_OK);
+
+ property = GetMsiProperty(handle, TEXT("Installed"));
+ myText = TEXT("Installed: ") + property;
+ MessageBox(NULL, myText.c_str(), "Installed", MB_OK);
+
+ property = GetMsiProperty(handle, TEXT("PATCH"));
+ myText = TEXT("PATCH: ") + property;
+ MessageBox(NULL, myText.c_str(), "PATCH", MB_OK);
+
+ property = GetMsiProperty(handle, TEXT("REMOVE"));
+ myText = TEXT("REMOVE: ") + property;
+ MessageBox(NULL, myText.c_str(), "REMOVE", MB_OK);
+
+ property = GetMsiProperty(handle, TEXT("ALLUSERS"));
+ myText = TEXT("ALLUSERS: ") + property;
+ MessageBox(NULL, myText.c_str(), "ALLUSERS", MB_OK);
+
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/exports.dxp b/setup_native/source/win32/customactions/shellextensions/exports.dxp
new file mode 100644
index 000000000000..0e53492e460f
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/exports.dxp
@@ -0,0 +1,20 @@
+InstallExecSequenceEntry
+DeinstallExecSequenceEntry
+InstallStartmenuFolderIcon
+DeinstallStartmenuFolderIcon
+SetProductInstallMode
+RebuildShellIconCache
+ExecutePostUninstallScript
+MigrateInstallPath
+CheckInstallDirectory
+SetAdminInstallProperty
+CreateLayerLinks
+RemoveLayerLinks
+DotNetCheck
+ShowProperties
+copyEditionData
+RenamePrgFolder
+RemovePrgFolder
+IsOfficeRunning
+CheckPatchList
+copyExtensionData
diff --git a/setup_native/source/win32/customactions/shellextensions/iconcache.cxx b/setup_native/source/win32/customactions/shellextensions/iconcache.cxx
new file mode 100755
index 000000000000..75b5914bafbc
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/iconcache.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <stdlib.h>
+
+extern "C" UINT __stdcall RebuildShellIconCache(MSIHANDLE)
+{
+ // Rebuild icon cache on windows OS prior XP
+
+ OSVERSIONINFO osverinfo;
+
+ osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ if (
+ GetVersionEx( &osverinfo ) &&
+ VER_PLATFORM_WIN32_NT == osverinfo.dwPlatformId &&
+ (
+ 5 < osverinfo.dwMajorVersion ||
+ 5 == osverinfo.dwMajorVersion && 0 < osverinfo.dwMinorVersion
+ )
+ )
+ {
+ return ERROR_SUCCESS;
+ }
+
+ HKEY hKey;
+ DWORD dwDispostion;
+ LONG lError = RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop\\WindowMetrics"), 0, NULL, REG_OPTION_VOLATILE, KEY_SET_VALUE | KEY_QUERY_VALUE, NULL, &hKey, &dwDispostion );
+
+ if ( ERROR_SUCCESS == lError )
+ {
+ TCHAR szValue[256];
+ TCHAR szTempValue[256];
+ DWORD cbValue = sizeof(szValue);
+ DWORD dwType;
+ int iSize = 0;
+
+ lError = RegQueryValueEx( hKey, TEXT("Shell Icon Size"), 0, &dwType, (LPBYTE)szValue, &cbValue );
+
+ if ( ERROR_SUCCESS == lError )
+ iSize = atoi( szValue );
+
+ if ( !iSize )
+ {
+ iSize = GetSystemMetrics( SM_CXICON );
+ itoa( iSize, szValue, 10 );
+ cbValue = strlen( szValue ) + 1;
+ dwType = REG_SZ;
+ }
+
+ itoa( iSize + 1, szTempValue, 10 );
+ lError = RegSetValueEx( hKey, TEXT("Shell Icon Size"), 0, dwType, (LPBYTE)szTempValue, strlen( szTempValue ) + 1 );
+
+ LRESULT lResult = SendMessageTimeout(
+ HWND_BROADCAST,
+ WM_SETTINGCHANGE,
+ SPI_SETNONCLIENTMETRICS,
+ (LPARAM)TEXT("WindowMetrics"),
+ SMTO_NORMAL|SMTO_ABORTIFHUNG,
+ 0, NULL);
+
+ lError = RegSetValueEx( hKey, TEXT("Shell Icon Size"), 0, dwType, (LPBYTE)szValue, cbValue );
+
+ lResult = SendMessageTimeout(
+ HWND_BROADCAST,
+ WM_SETTINGCHANGE,
+ SPI_SETNONCLIENTMETRICS,
+ (LPARAM)TEXT("WindowMetrics"),
+ SMTO_NORMAL|SMTO_ABORTIFHUNG,
+ 0, NULL);
+
+ lError = RegCloseKey( hKey );
+ }
+
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/layerlinks.cxx b/setup_native/source/win32/customactions/shellextensions/layerlinks.cxx
new file mode 100644
index 000000000000..fb0897e728fe
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/layerlinks.cxx
@@ -0,0 +1,257 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#include <tchar.h>
+#include <string>
+#include <systools/win32/uwinapi.h>
+
+#include <../tools/seterror.hxx>
+
+using namespace std;
+
+namespace
+{
+ string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ string result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+ return result;
+ }
+
+ inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ return (GetMsiProperty(handle, sProperty).length() > 0);
+ }
+
+ inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+ }
+
+ inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string&)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+ }
+
+ void stripFinalBackslash(std::string * path) {
+ std::string::size_type i = path->size();
+ if (i > 1) {
+ --i;
+ if ((*path)[i] == '\\') {
+ path->erase(i);
+ }
+ }
+ }
+} // namespace
+
+extern "C" UINT __stdcall CreateLayerLinks(MSIHANDLE handle)
+{
+ string sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+
+ string sOfficeInstallPath = sInstallPath;
+ string sBasisInstallPath = sInstallPath + TEXT("Basis\\");
+ string sUreInstallPath = sInstallPath + TEXT("URE\\");
+
+ string sBasisLinkPath = sInstallPath + TEXT("basis-link");
+ string sUreLinkPath = sInstallPath + TEXT("Basis\\ure-link");
+
+ if ( IsSetMsiProperty(handle, TEXT("ADMININSTALL")) )
+ {
+ sBasisInstallPath = TEXT("Basis");
+ sUreInstallPath = TEXT("..\\URE");
+ }
+
+ stripFinalBackslash(&sBasisInstallPath);
+ stripFinalBackslash(&sUreInstallPath);
+
+ // string myText1 = TEXT("Creating Basis-Link: ") + sBasisLinkPath;
+ // string myText2 = TEXT("Creating Ure-Link: ") + sUreLinkPath;
+ // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
+ // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
+
+ // creating basis-link in brand layer
+
+ HANDLE h1file = CreateFile(
+ sBasisLinkPath.c_str(),
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (IsValidHandle(h1file))
+ {
+ DWORD dummy;
+
+ // Converting string into UTF-8 encoding and writing into file "basis-link"
+
+ int nCharsRequired = MultiByteToWideChar( CP_ACP, 0, sBasisInstallPath.c_str(), -1, NULL, 0 );
+ if ( nCharsRequired )
+ {
+ LPWSTR lpPathW = new WCHAR[nCharsRequired];
+ if ( MultiByteToWideChar( CP_ACP, 0, sBasisInstallPath.c_str(), -1, lpPathW, nCharsRequired ) )
+ {
+ nCharsRequired = WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, NULL, 0, NULL, NULL );
+ if ( nCharsRequired )
+ {
+ LPSTR lpPathUTF8 = new CHAR[nCharsRequired];
+ WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, lpPathUTF8, nCharsRequired, NULL, NULL );
+
+ // WriteFile( h1file, sBasisInstallPath.c_str(), sBasisInstallPath.size() ,&dummy, 0 );
+ WriteFile( h1file, lpPathUTF8, strlen(lpPathUTF8) ,&dummy, 0 );
+
+ delete lpPathUTF8;
+ }
+ }
+
+ delete lpPathW;
+ }
+
+ CloseHandle(h1file);
+ }
+
+ // creating ure-link in basis layer
+
+ HANDLE h2file = CreateFile(
+ sUreLinkPath.c_str(),
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (IsValidHandle(h2file))
+ {
+ DWORD dummy;
+
+ // Converting string into UTF-8 encoding and writing into file "basis-link"
+
+ int nCharsRequired = MultiByteToWideChar( CP_ACP, 0, sUreInstallPath.c_str(), -1, NULL, 0 );
+ if ( nCharsRequired )
+ {
+ LPWSTR lpPathW = new WCHAR[nCharsRequired];
+ if ( MultiByteToWideChar( CP_ACP, 0, sUreInstallPath.c_str(), -1, lpPathW, nCharsRequired ) )
+ {
+ nCharsRequired = WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, NULL, 0, NULL, NULL );
+ if ( nCharsRequired )
+ {
+ LPSTR lpPathUTF8 = new CHAR[nCharsRequired];
+ WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, lpPathUTF8, nCharsRequired, NULL, NULL );
+
+ // WriteFile( h2file, sUreInstallPath.c_str(), sUreInstallPath.size() ,&dummy, 0 );
+ WriteFile( h2file, lpPathUTF8, strlen(lpPathUTF8) ,&dummy, 0 );
+
+ delete lpPathUTF8;
+ }
+ }
+
+ delete lpPathW;
+ }
+
+ CloseHandle(h2file);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall RemoveLayerLinks(MSIHANDLE handle)
+{
+ string sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+
+ string sOfficeInstallPath = sInstallPath;
+ string sBasisInstallPath = sInstallPath + TEXT("Basis\\");
+ string sUreInstallPath = sInstallPath + TEXT("URE\\");
+
+ string sBasisLinkPath = sOfficeInstallPath + TEXT("basis-link");
+ string sUreLinkPath = sBasisInstallPath + TEXT("ure-link");
+ string sUreDirName = sUreInstallPath + TEXT("bin");
+
+ // string myText2 = TEXT("Deleting Ure-Link: ") + sUreLinkPath;
+ // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
+
+ // Deleting link to basis layer
+ // string myText1 = TEXT("Deleting Basis-Link: ") + sBasisLinkPath;
+ // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
+ DeleteFile(sBasisLinkPath.c_str());
+
+ // Check, if URE is still installed
+ bool ureDirExists = true;
+ WIN32_FIND_DATA aFindData;
+ HANDLE hFindContent = FindFirstFile( sUreDirName.c_str(), &aFindData );
+ if ( hFindContent == INVALID_HANDLE_VALUE ) { ureDirExists = false; }
+ FindClose( hFindContent );
+
+ // if ( ureDirExists )
+ // {
+ // string myText3 = TEXT("URE directory still exists: ") + sUreDirName;
+ // MessageBox(NULL, myText3.c_str(), "DEBUG", MB_OK);
+ // string myText4 = TEXT("URE link NOT removed: ") + sUreLinkPath;
+ // MessageBox(NULL, myText4.c_str(), "DEBUG", MB_OK);
+ // }
+
+ // Deleting link to URE layer, if URE dir no longer exists
+ if ( ! ureDirExists )
+ {
+ // string myText5 = TEXT("URE directory does not exist: ") + sUreDirName;
+ // MessageBox(NULL, myText5.c_str(), "DEBUG", MB_OK);
+ DeleteFile(sUreLinkPath.c_str());
+ // string myText6 = TEXT("URE link removed: ") + sUreLinkPath;
+ // MessageBox(NULL, myText6.c_str(), "DEBUG", MB_OK);
+ }
+
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/makefile.mk b/setup_native/source/win32/customactions/shellextensions/makefile.mk
new file mode 100644
index 000000000000..9eef136a82a4
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/makefile.mk
@@ -0,0 +1,106 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..$/..
+PRJNAME=setup_native
+TARGET=shlxtmsi
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+NO_DEFAULT_STL=TRUE
+DYNAMIC_CRT=
+USE_DEFFILE=TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+CFLAGS+=-D_STLP_USE_STATIC_LIB
+.ENDIF
+
+#Disable precompiled header
+CDEFS+=-Dnot_used_define_to_disable_pch
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)"=="WNT"
+
+UWINAPILIB=
+
+SLOFILES = \
+ $(SLO)$/shellextensions.obj \
+ $(SLO)$/startmenuicon.obj \
+ $(SLO)$/upgrade.obj \
+ $(SLO)$/iconcache.obj \
+ $(SLO)$/postuninstall.obj \
+ $(SLO)$/migrateinstallpath.obj \
+ $(SLO)$/checkdirectory.obj \
+ $(SLO)$/setadmininstall.obj \
+ $(SLO)$/layerlinks.obj \
+ $(SLO)$/dotnetcheck.obj \
+ $(SLO)$/copyeditiondata.obj \
+ $(SLO)$/vistaspecial.obj \
+ $(SLO)$/checkrunningoffice.obj \
+ $(SLO)$/checkpatches.obj \
+ $(SLO)$/copyextensiondata.obj
+
+STDSHL += \
+ $(ADVAPI32LIB)\
+ $(MSILIB)\
+ $(SHELL32LIB)
+
+.IF "$(USE_SYSTEM_STL)" != "YES"
+STDSHL += $(LIBSTLPORTST)
+.ENDIF
+
+.IF "$(COM)"=="GCC"
+STDSHL+= \
+ $(KERNEL32LIB)\
+ -lmsvcrt
+.ENDIF
+
+SHL1OBJS = $(SLOFILES) \
+ $(SLO)$/seterror.obj
+
+SHL1TARGET = $(TARGET)
+SHL1IMPLIB = i$(TARGET)
+
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+SHL1DEPN = $(SLB)$/$(TARGET).lib
+SHL1BASE = 0x1c000000
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+
+.ENDIF
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+# -------------------------------------------------------------------------
+
+
diff --git a/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
new file mode 100755
index 000000000000..c8035799a539
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/migrateinstallpath.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+using namespace std;
+
+namespace
+{
+ std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+ {
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+ }
+} // namespace
+
+extern "C" UINT __stdcall MigrateInstallPath( MSIHANDLE handle )
+{
+ TCHAR szValue[8192];
+ DWORD nValueSize = sizeof(szValue);
+ HKEY hKey;
+ std::_tstring sInstDir;
+
+ std::_tstring sManufacturer = GetMsiProperty( handle, TEXT("Manufacturer") );
+ std::_tstring sDefinedName = GetMsiProperty( handle, TEXT("DEFINEDPRODUCT") );
+ std::_tstring sUpdateVersion = GetMsiProperty( handle, TEXT("DEFINEDVERSION") );
+ std::_tstring sUpgradeCode = GetMsiProperty( handle, TEXT("UpgradeCode") );
+
+ std::_tstring sProductKey = "Software\\" + sManufacturer + "\\" + sDefinedName +
+ "\\" + sUpdateVersion + "\\" + sUpgradeCode;
+
+ std::_tstring mystr;
+ mystr = "ProductKey: " + sProductKey;
+ // MessageBox( NULL, mystr.c_str(), "ProductKey", MB_OK );
+
+ if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ MsiSetProperty(handle, TEXT("INSTALLLOCATION"), sInstDir.c_str());
+ // MessageBox( NULL, sInstDir.c_str(), "Found in HKEY_CURRENT_USER", MB_OK );
+ }
+
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ MsiSetProperty(handle, TEXT("INSTALLLOCATION"), sInstDir.c_str());
+ // MessageBox( NULL, sInstDir.c_str(), "Found in HKEY_LOCAL_MACHINE", MB_OK );
+ }
+
+ RegCloseKey( hKey );
+ }
+
+ return ERROR_SUCCESS;
+
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/postuninstall.cxx b/setup_native/source/win32/customactions/shellextensions/postuninstall.cxx
new file mode 100755
index 000000000000..ea9bfae3864b
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/postuninstall.cxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+#include <io.h>
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+
+static BOOL ExecuteCommand( LPCTSTR lpCommand, BOOL bSync )
+{
+ BOOL fSuccess = FALSE;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+
+ fSuccess = CreateProcess(
+ NULL,
+ (LPTSTR)lpCommand,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ NULL,
+ NULL,
+ &si,
+ &pi
+ );
+
+ if ( fSuccess )
+ {
+ if ( bSync )
+ WaitForSingleObject( pi.hProcess, INFINITE );
+
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ }
+
+ return fSuccess;
+}
+
+extern "C" UINT __stdcall ExecutePostUninstallScript( MSIHANDLE handle )
+{
+ TCHAR szValue[8192];
+ DWORD nValueSize = sizeof(szValue);
+ HKEY hKey;
+ std::_tstring sInstDir;
+
+ std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
+
+ // MessageBox( NULL, sProductKey.c_str(), "Titel", MB_OK );
+
+ if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else
+ return ERROR_SUCCESS;
+
+ std::_tstring sInfFile = sInstDir + TEXT("program\\postuninstall.inf");
+ std::_tstring sCommand = _T("RUNDLL32.EXE ");
+
+ // MessageBox( NULL, sInfFile.c_str(), "Titel", MB_OK );
+
+ if ( (LONG)GetVersion() < 0 )
+ sCommand += _T("setupx.dll");
+ else
+ sCommand += _T("setupapi.dll");
+
+ sCommand += _T(",InstallHinfSection PostUninstall 132 ");
+ sCommand += sInfFile;
+
+ if ( 0 == _taccess( sInfFile.c_str(), 2 ) )
+ ExecuteCommand( sCommand.c_str(), TRUE );
+
+ DeleteFile( sInfFile.c_str() );
+
+ return ERROR_SUCCESS;
+}
+
diff --git a/setup_native/source/win32/customactions/shellextensions/registerextensions.cxx b/setup_native/source/win32/customactions/shellextensions/registerextensions.cxx
new file mode 100644
index 000000000000..3906d2584fd1
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/registerextensions.cxx
@@ -0,0 +1,573 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <msiquery.h>
+#include <shellapi.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+#include <string.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+/** creates a temporary folder with a unique name.
+
+ The returned string is a file URL.
+*/
+static std::_tstring createTempFolder()
+{
+ BOOL bExist = FALSE;
+ TCHAR szTempName[MAX_PATH];
+ do
+ {
+ bExist = FALSE;
+ // Get the temp path.
+ TCHAR lpPathBuffer[MAX_PATH];
+ DWORD dwRetVal = GetTempPath(MAX_PATH, lpPathBuffer);
+ if (dwRetVal > MAX_PATH || (dwRetVal == 0))
+ {
+ //fprintf (stderr, "GetTempPath failed with error %d.\n", GetLastError());
+ return TEXT("");
+ }
+ // Create a temporary file.
+ UINT uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files
+ "upg", // temp file name prefix
+ 0, // create unique name
+ szTempName); // buffer for name
+ if (uRetVal == 0)
+ {
+ //fprintf (stderr, "GetTempFileName failed with error %d.\n", GetLastError());
+ return TEXT("");
+ }
+ //Delete the file
+ BOOL bDel = DeleteFile(szTempName);
+ if (FALSE == bDel)
+ {
+ //fprintf(stderr, "Could not delete temp file. Error %d.\n", GetLastError());
+ return TEXT("");
+ }
+ // Create the directory
+ BOOL bDir = CreateDirectory(szTempName, NULL);
+ if (FALSE == bDir)
+ {
+ DWORD error =GetLastError();
+ if (ERROR_ALREADY_EXISTS == error)
+ {
+ bExist = TRUE;
+ }
+ else
+ {
+ //fprintf(stderr, "CreateDirectory failed with error %d.\n", error);
+ return TEXT("");
+ }
+ }
+ } while(bExist);
+
+ std::_tstring cur(szTempName);
+ //make a file URL from the path
+ std::_tstring ret(TEXT("file:///"));
+ for (std::_tstring::iterator i = cur.begin(); i != cur.end(); i++)
+ {
+ if (*i == '\\')
+ ret.append(TEXT("/"));
+ else
+ ret.push_back(*i);
+ }
+// MessageBox(NULL, ret.c_str(), "createTempFolder", MB_OK);
+ return ret.c_str();
+}
+
+/** deletes the temporary folder.
+ The argument must be a file URL.
+*/
+static void deleteTempFolder(const std::_tstring& sTempFolder)
+{
+ if (sTempFolder.size() == 0)
+ return;
+ //convert the file URL to a path
+ const std::_tstring path(sTempFolder.substr(8));
+ std::_tstring path2;
+// MessageBox(NULL, path.c_str(), "del1", MB_OK);
+ for (std::_tstring::const_iterator i = path.begin(); i != path.end(); i++)
+ {
+ if (*i == '/')
+ path2.append(TEXT("\\"));
+ else
+ path2.push_back(*i);
+ }
+
+ //We need a null terminated string with two nulls in the end
+ //for the SHFILEOPSTRUCT
+ const TCHAR * szTemp = path2.c_str();
+ size_t size = path2.size();
+ TCHAR * szTemp2 = new TCHAR[size + 2];
+ ZeroMemory(szTemp2, (size + 2) * sizeof(TCHAR));
+ memcpy(szTemp2, szTemp, size * sizeof(TCHAR));
+
+// MessageBox(NULL, szTemp2, "del3", MB_OK);
+ SHFILEOPSTRUCT operation =
+ {
+ NULL,
+ FO_DELETE,
+ szTemp2,
+ NULL,
+ FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR,
+ FALSE,
+ NULL,
+ NULL
+ };
+
+ SHFileOperation( &operation);
+ delete [] szTemp2;
+}
+
+
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+/* creates a child process which is specified in lpCommand.
+
+ out_exitCode is the exit code of the child process
+
+
+**/
+static BOOL ExecuteCommand( LPCTSTR lpCommand, DWORD * out_exitCode)
+{
+ BOOL fSuccess = FALSE;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+
+ fSuccess = CreateProcess(
+ NULL,
+ (LPTSTR)lpCommand,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ NULL,
+ NULL,
+ &si,
+ &pi
+ );
+
+ if ( fSuccess )
+ {
+ WaitForSingleObject( pi.hProcess, INFINITE );
+
+ if (!GetExitCodeProcess( pi.hProcess, out_exitCode))
+ fSuccess = FALSE;
+
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ }
+
+ return fSuccess;
+}
+
+static BOOL RemoveCompleteDirectory( std::_tstring sPath )
+{
+ bool bDirectoryRemoved = true;
+
+ std::_tstring mystr;
+ std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*");
+ WIN32_FIND_DATA aFindData;
+
+ // Finding all content in sPath
+
+ HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData );
+
+ if ( hFindContent != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+
+ do
+ {
+ std::_tstring sFileName = aFindData.cFileName;
+ std::_tstring sCurrentDir = TEXT(".");
+ std::_tstring sParentDir = TEXT("..");
+
+ mystr = "Current short file: " + sFileName;
+ // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK);
+
+ if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) &&
+ ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 ))
+ {
+ std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName;
+
+ if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
+ {
+ bool fSuccess = RemoveCompleteDirectory(sCompleteFileName);
+ if ( fSuccess )
+ {
+ mystr = "Successfully removed content of dir " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removing content of " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
+ }
+ }
+ else
+ {
+ bool fSuccess = DeleteFile( sCompleteFileName.c_str() );
+ if ( fSuccess )
+ {
+ mystr = "Successfully removed file " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removal of file " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK);
+ }
+ }
+ }
+
+ fNextFile = FindNextFile( hFindContent, &aFindData );
+
+ } while ( fNextFile );
+
+ FindClose( hFindContent );
+
+ // empty directory can be removed now
+ // RemoveDirectory is only successful, if the last handle to the directory is closed
+ // -> first removing content -> closing handle -> remove empty directory
+
+ bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str());
+
+ if ( fRemoveDirSuccess )
+ {
+ mystr = "Successfully removed dir " + sPath;
+ // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removal of empty directory " + sPath;
+ // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
+ bDirectoryRemoved = false;
+ }
+ }
+
+ return bDirectoryRemoved;
+}
+
+extern "C" UINT __stdcall RegisterExtensions(MSIHANDLE handle)
+{
+ std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
+ std::_tstring sUnoPkgFile = sInstDir + TEXT("program\\unopkg.exe");
+ std::_tstring sShareInstallDir = sInstDir + TEXT("share\\extension\\install\\");
+ std::_tstring sPattern = sShareInstallDir + TEXT("*.oxt");
+ std::_tstring mystr;
+
+ WIN32_FIND_DATA aFindFileData;
+
+ mystr = "unopkg file: " + sUnoPkgFile;
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+
+ mystr = "oxt file directory: " + sShareInstallDir;
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+
+ // Find unopkg.exe
+
+ HANDLE hFindUnopkg = FindFirstFile( sUnoPkgFile.c_str(), &aFindFileData );
+
+ if ( hFindUnopkg != INVALID_HANDLE_VALUE )
+ {
+ // unopkg.exe exists in program directory
+
+ // Finding all oxt files in sShareInstallDir
+
+ HANDLE hFindOxt = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( hFindOxt != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+
+ do
+ {
+ const std::_tstring sTempFolder(createTempFolder());
+ std::_tstring sOxtFile = sShareInstallDir + aFindFileData.cFileName;
+ std::_tstring sCommandPart1 = sUnoPkgFile + " add --shared --suppress-license --bundled " + "\"" + sOxtFile + "\"";
+ std::_tstring sCommand = sCommandPart1
+ + TEXT(" -env:UNO_JAVA_JFW_INSTALL_DATA=$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml")
+ + TEXT(" -env:UserInstallation=") + sTempFolder;
+ mystr = "Command: " + sCommand;
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+
+ DWORD exitCode = 0;
+ bool fSuccess = ExecuteCommand( sCommand.c_str(), & exitCode);
+ // unopkg in OOo 2.2.1 and early had a bug that it failed when receiving
+ // a bootstrap parameter (-env:...) then it exited with a value != 0.
+ if (fSuccess && exitCode != 0)
+ {
+ std::_tstring sCommand = sCommandPart1;
+ mystr = "Command: " + sCommand;
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ fSuccess = ExecuteCommand( sCommand.c_str(), & exitCode);
+ }
+ deleteTempFolder(sTempFolder);
+
+ // if ( fSuccess )
+ // {
+ // mystr = "Executed successfully!";
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ // }
+ // else
+ // {
+ // mystr = "An error occured during execution!";
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ // }
+
+ fNextFile = FindNextFile( hFindOxt, &aFindFileData );
+
+ } while ( fNextFile );
+
+ FindClose( hFindOxt );
+ }
+ }
+ // else
+ // {
+ // mystr = "Error: Did not find " + sUnoPkgFile;
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ // }
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall DeregisterExtensions(MSIHANDLE handle)
+{
+ std::_tstring mystr;
+
+ // Finding the product with the help of the propery FINDPRODUCT,
+ // that contains a Windows Registry key, that points to the install location.
+
+ TCHAR szValue[8192];
+ DWORD nValueSize = sizeof(szValue);
+ HKEY hKey;
+ std::_tstring sInstDir;
+
+ std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
+ // MessageBox( NULL, sProductKey.c_str(), "Titel", MB_OK );
+
+ if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else
+ {
+ return ERROR_SUCCESS;
+ }
+
+ // MessageBox( NULL, sInstDir.c_str(), "install location", MB_OK );
+
+ // Searching for the unopkg.exe
+
+ std::_tstring sUnoPkgFile = sInstDir + TEXT("program\\unopkg.exe");
+ std::_tstring sShareInstallDir = sInstDir + TEXT("share\\extension\\install\\");
+ std::_tstring sPattern = sShareInstallDir + TEXT("*.oxt");
+
+ WIN32_FIND_DATA aFindFileData;
+
+ // Find unopkg.exe
+
+ HANDLE hFindUnopkg = FindFirstFile( sUnoPkgFile.c_str(), &aFindFileData );
+
+ if ( hFindUnopkg != INVALID_HANDLE_VALUE )
+ {
+ // unopkg.exe exists in program directory
+
+ // Finding all oxt files in sShareInstallDir
+
+ HANDLE hFindOxt = FindFirstFile( sPattern.c_str(), &aFindFileData );
+
+ if ( hFindOxt != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+
+ do
+ {
+ const std::_tstring sTempFolder(createTempFolder());
+ // When removing extensions, only the oxt file name is required, without path
+ // Therefore no quoting is required
+ // std::_tstring sOxtFile = sShareInstallDir + aFindFileData.cFileName;
+ std::_tstring sOxtFile = aFindFileData.cFileName;
+ std::_tstring sCommandPart1 = sUnoPkgFile + " remove --shared --bundled " + "\""
+ + sOxtFile + "\"";
+ std::_tstring sCommand = sCommandPart1
+ + TEXT(" -env:UNO_JAVA_JFW_INSTALL_DATA=$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml")
+ + TEXT(" -env:UserInstallation=") + sTempFolder;
+
+ mystr = "Command: " + sCommand;
+ //MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ DWORD exitCode = 0;
+ bool fSuccess = ExecuteCommand( sCommand.c_str(), & exitCode);
+ // unopkg in OOo 2.2.1 and early had a bug that it failed when receiving
+ // a bootstrap parameter (-env:...) then it exited with a value != 0.
+ if (fSuccess && exitCode != 0)
+ {
+ std::_tstring sCommand = sCommandPart1;
+ mystr = "Command: " + sCommand;
+ //MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ fSuccess = ExecuteCommand( sCommand.c_str(), & exitCode);
+ }
+
+ deleteTempFolder(sTempFolder);
+
+ if ( fSuccess )
+ {
+ mystr = "Executed successfully!";
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during execution!";
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ }
+
+ fNextFile = FindNextFile( hFindOxt, &aFindFileData );
+
+ } while ( fNextFile );
+
+ FindClose( hFindOxt );
+ }
+ }
+ // else
+ // {
+ // mystr = "Not found: " + sUnoPkgFile;
+ // MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
+ // }
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall RemoveExtensions(MSIHANDLE handle)
+{
+ std::_tstring mystr;
+
+ // Finding the product with the help of the propery FINDPRODUCT,
+ // that contains a Windows Registry key, that points to the install location.
+
+ TCHAR szValue[8192];
+ DWORD nValueSize = sizeof(szValue);
+ HKEY hKey;
+ std::_tstring sInstDir;
+
+ std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
+ // MessageBox( NULL, sProductKey.c_str(), "Titel", MB_OK );
+
+ if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
+ {
+ if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
+ {
+ sInstDir = szValue;
+ }
+ RegCloseKey( hKey );
+ }
+ else
+ {
+ return ERROR_SUCCESS;
+ }
+
+ // Removing complete directory "share\uno_packages\cache"
+
+ std::_tstring sCacheDir = sInstDir + TEXT("share\\uno_packages\\cache");
+
+ bool fSuccess = RemoveCompleteDirectory( sCacheDir );
+
+ if ( fSuccess )
+ {
+ mystr = "Executed successfully!";
+ // MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during execution!";
+ // MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK);
+ }
+
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx b/setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx
new file mode 100755
index 000000000000..6bd57447f092
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/setadmininstall.cxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINNT 0x0401
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+static void SetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
+{
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+}
+
+extern "C" UINT __stdcall SetAdminInstallProperty(MSIHANDLE handle)
+{
+ SetMsiProperty(handle, TEXT("ADMININSTALL"));
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/shellextensions.cxx b/setup_native/source/win32/customactions/shellextensions/shellextensions.cxx
new file mode 100644
index 000000000000..c779e1e5994e
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/shellextensions.cxx
@@ -0,0 +1,213 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/*
+ Windows shell extensions need to be approved in order to be used by the
+ Windows shell for clarification read the following section from the
+ Microsoft Developers Network Library (MSDN) see
+ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_extending/extensionhandlers/shell_ext.asp
+
+
+ <MSDN>
+ Shell extension handlers run in the Shell process. Because it is a system process,
+ the administrator of a Windows NT system can limit Shell extension handlers to
+ those on an approved list by setting the EnforceShellExtensionSecurity value of the
+ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer key to 1
+ (one).
+ To place a Shell extension handler on the approved list, create a REG_SZ value whose
+ name is the string form of the handler's GUID under
+ HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved.
+
+ The Shell does not use the value that is assigned to the GUID, but it should be set to
+ make inspecting the registry easier.
+
+ Your setup application can add values to the Approved key only if the person installing
+ the application has sufficient privileges. If the attempt to add an extension handler
+ fails, you should inform the user that administrative privileges are required to fully
+ install the application. If the handler is essential to the application, you should fail
+ the setup and notify the user to contact an administrator.
+
+ While there is no need to add values to the Approved key on Windows 95 or Windows 98
+ systems, there is no harm in doing so. The system will simply ignore them. However, there
+ is no guarantee that the key will exist on these systems. Your setup program must be able
+ to handle this case.
+ </MSDN>
+
+ We add the following entries to the respective registry key
+ "{C52AF81D-F7A0-4AAB-8E87-F80A60CCD396}"="OpenOffice.org Column Handler"
+ "{087B3AE3-E237-4467-B8DB-5A38AB959AC9}"="OpenOffice.org Infotip Handler"
+ "{63542C48-9552-494A-84F7-73AA6A7C99C1}"="OpenOffice.org Property Sheet Handler"
+ "{3B092F0C-7696-40E3-A80F-68D74DA84210}"="OpenOffice.org Thumbnail Viewer"
+
+ These shell extensions are implemented in the 'shell' project. We ignore registration
+ failures because of insufficient privileges. The reason is: On systems which restrict the
+ use of shell extensions by applying the aforementioned policy probably only people with
+ sufficient privileges are allowed to install applications anyway. On systems where the
+ use of shell extensions is not restricted registration failures because of insufficient
+ prviliges have no negative effect because the shell extensions will work anyhow.
+*/
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#endif
+#include <tchar.h>
+
+struct RegistryEntry
+{
+ TCHAR* Key;
+ TCHAR* Value;
+};
+
+RegistryEntry ColumnHandler = { TEXT("{C52AF81D-F7A0-4AAB-8E87-F80A60CCD396}"), TEXT("OpenOffice.org Column Handler") };
+RegistryEntry InfotipHandler = { TEXT("{087B3AE3-E237-4467-B8DB-5A38AB959AC9}"), TEXT("OpenOffice.org Infotip Handler") };
+RegistryEntry PropHandler = { TEXT("{63542C48-9552-494A-84F7-73AA6A7C99C1}"), TEXT("OpenOffice.org Property Sheet Handler") };
+RegistryEntry ThumbViewer = { TEXT("{3B092F0C-7696-40E3-A80F-68D74DA84210}"), TEXT("OpenOffice.org Thumbnail Viewer") };
+
+BOOL GetMsiProp( MSIHANDLE hMSI, const char* pPropName, char** ppValue )
+{
+ DWORD sz = 0;
+ if ( MsiGetProperty( hMSI, pPropName, 0, &sz ) == ERROR_MORE_DATA )
+ {
+ sz++;
+ DWORD nbytes = sz * sizeof( char );
+ char* buff = reinterpret_cast<char*>( malloc( nbytes ) );
+ ZeroMemory( buff, nbytes );
+ MsiGetProperty( hMSI, pPropName, buff, &sz );
+ *ppValue = buff;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool IsVersionNT64( MSIHANDLE hMSI )
+{
+ char* pVal = NULL;
+
+ if ( GetMsiProp( hMSI, "VersionNT64", &pVal ) && pVal )
+ {
+ free( pVal );
+ return true;
+ }
+
+ return false;
+}
+
+
+
+
+/*
+ Called during installation when the module "Windows Explorer Extensions" is
+ selected.
+*/
+extern "C" UINT __stdcall InstallExecSequenceEntry(MSIHANDLE hMSI)
+{
+ //MessageBox(NULL, TEXT("InstallExecSequenceEntry"), TEXT("Pythonmsi"), MB_OK | MB_ICONINFORMATION);
+ HKEY hKey;
+
+
+// 06.11.2009 tkr: to provide windows xp as build systems for mingw we need to define KEY_WOW64_64KEY
+// in mingw 3.13 KEY_WOW64_64KEY isn't available < Win2003 systems.
+// Also defined in setup_native\source\win32\customactions\reg64\reg64.cxx,source\win32\customactions\shellextensions\shellextensions.cxx and
+// extensions\source\activex\main\so_activex.cpp
+#ifndef KEY_WOW64_64KEY
+ #define KEY_WOW64_64KEY (0x0100)
+#endif
+
+ if (IsVersionNT64(hMSI))
+ {
+ // Open Windows 64 Bit Registry
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),0, KEY_WRITE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
+ {
+ RegSetValueEx(hKey, ColumnHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ColumnHandler.Value), _tcslen(ColumnHandler.Value) + 1);
+ RegSetValueEx(hKey, InfotipHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(InfotipHandler.Value), _tcslen(InfotipHandler.Value) + 1);
+ RegSetValueEx(hKey, PropHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(PropHandler.Value), _tcslen(PropHandler.Value) + 1);
+ RegSetValueEx(hKey, ThumbViewer.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ThumbViewer.Value), _tcslen(ThumbViewer.Value) + 1);
+
+ RegCloseKey(hKey);
+ }
+
+ // Open Windows 32 Bit Registry on Win64 maschine
+
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),0, KEY_WRITE, &hKey ) == ERROR_SUCCESS)
+ {
+ RegSetValueEx(hKey, ColumnHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ColumnHandler.Value), _tcslen(ColumnHandler.Value) + 1);
+ RegSetValueEx(hKey, InfotipHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(InfotipHandler.Value), _tcslen(InfotipHandler.Value) + 1);
+ RegSetValueEx(hKey, PropHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(PropHandler.Value), _tcslen(PropHandler.Value) + 1);
+ RegSetValueEx(hKey, ThumbViewer.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ThumbViewer.Value), _tcslen(ThumbViewer.Value) + 1);
+
+ RegCloseKey(hKey);
+ }
+
+
+ } else
+ {
+ if (RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), &hKey) == ERROR_SUCCESS)
+ {
+ RegSetValueEx(hKey, ColumnHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ColumnHandler.Value), _tcslen(ColumnHandler.Value) + 1);
+ RegSetValueEx(hKey, InfotipHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(InfotipHandler.Value), _tcslen(InfotipHandler.Value) + 1);
+ RegSetValueEx(hKey, PropHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(PropHandler.Value), _tcslen(PropHandler.Value) + 1);
+ RegSetValueEx(hKey, ThumbViewer.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ThumbViewer.Value), _tcslen(ThumbViewer.Value) + 1);
+
+ RegCloseKey(hKey);
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
+/*
+ Called during deinstallation when the module "Windows Explorer Extensions" has
+ been installed.
+*/
+extern "C" UINT __stdcall DeinstallExecSequenceEntry(MSIHANDLE)
+{
+ //MessageBox(NULL, TEXT("DeinstallExecSequenceEntry"), TEXT("Pythonmsi"), MB_OK | MB_ICONINFORMATION);
+ HKEY hKey;
+ if (RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), &hKey) == ERROR_SUCCESS)
+ {
+ RegDeleteValue(hKey, ColumnHandler.Key);
+ RegDeleteValue(hKey, InfotipHandler.Key);
+ RegDeleteValue(hKey, PropHandler.Key);
+ RegDeleteValue(hKey, ThumbViewer.Key);
+
+ RegCloseKey(hKey);
+ }
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx b/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx
new file mode 100644
index 000000000000..5adab408139d
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/startmenuicon.cxx
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+
+
+std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+/*
+ Called during installation to customize the start menu folder icon.
+ See: http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/custom.asp
+*/
+extern "C" UINT __stdcall InstallStartmenuFolderIcon( MSIHANDLE handle )
+{
+ std::_tstring sOfficeMenuFolder = GetMsiProperty( handle, TEXT("OfficeMenuFolder") );
+ std::_tstring sDesktopFile = sOfficeMenuFolder + TEXT("Desktop.ini");
+
+ // MessageBox(NULL, sDesktopFile.c_str(), TEXT("OfficeMenuFolder"), MB_OK | MB_ICONINFORMATION);
+
+ std::_tstring sIconFile = GetMsiProperty( handle, TEXT("INSTALLLOCATION") ) + TEXT("program\\soffice.exe");
+
+ OSVERSIONINFO osverinfo;
+ osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx( &osverinfo );
+
+ if (osverinfo.dwMajorVersion < 6 /* && osverinfo.dwMinorVersion */ )
+ {
+ // This icon (18) is a Windows folder until XP Version (number is 0 based)
+ WritePrivateProfileString(
+ TEXT(".ShellClassInfo"),
+ TEXT("IconFile"),
+ sIconFile.c_str(),
+ sDesktopFile.c_str() );
+
+ // FYI: in tool 'ResHack' this icon can be found on position '19' (number is 1 based)
+ WritePrivateProfileString(
+ TEXT(".ShellClassInfo"),
+ TEXT("IconIndex"),
+ TEXT("18"),
+ sDesktopFile.c_str() );
+ }
+ // else
+ // {
+ // // at the moment there exists no Vista Icon, so we use the default folder icon.
+ // // add the icon into desktop/util/verinfo.rc
+ // }
+
+ // The value '0' is to avoid a message like "You Are Deleting a System Folder" warning when deleting or moving the folder.
+ WritePrivateProfileString(
+ TEXT(".ShellClassInfo"),
+ TEXT("ConfirmFileOp"),
+ TEXT("0"),
+ sDesktopFile.c_str() );
+
+ /*
+ WritePrivateProfileString(
+ TEXT(".ShellClassInfo"),
+ TEXT("InfoTip"),
+ TEXT("StarOffice Productivity Suite"),
+ sDesktopFile.c_str() );
+ */
+
+ SetFileAttributes( sDesktopFile.c_str(), FILE_ATTRIBUTE_HIDDEN );
+ SetFileAttributes( sOfficeMenuFolder.c_str(), FILE_ATTRIBUTE_SYSTEM );
+
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall DeinstallStartmenuFolderIcon(MSIHANDLE handle)
+{
+ std::_tstring sOfficeMenuFolder = GetMsiProperty( handle, TEXT("OfficeMenuFolder") );
+ std::_tstring sDesktopFile = sOfficeMenuFolder + TEXT("Desktop.ini");
+
+ SetFileAttributes( sDesktopFile.c_str(), FILE_ATTRIBUTE_NORMAL );
+ DeleteFile( sDesktopFile.c_str() );
+
+ SetFileAttributes( sOfficeMenuFolder.c_str(), FILE_ATTRIBUTE_NORMAL );
+
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/upgrade.cxx b/setup_native/source/win32/customactions/shellextensions/upgrade.cxx
new file mode 100644
index 000000000000..1fb2972d433a
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/upgrade.cxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#undef UNICODE
+#undef _UNICODE
+
+#define _WIN32_WINDOWS 0x0410
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#include <tchar.h>
+#include <string>
+
+using namespace std;
+
+namespace
+{
+ // The provided GUID must be without surounding '{}'
+ string GetGuidPart(const string& guid, int index)
+ {
+ assert((guid.length() == 36) && "No GUID or wrong format!");
+ assert(((index > -1) && (index < 5)) && "Out of range!");
+
+ if (index == 0) return string(guid.c_str(), 8);
+ if (index == 1) return string(guid.c_str() + 9, 4);
+ if (index == 2) return string(guid.c_str() + 14, 4);
+ if (index == 3) return string(guid.c_str() + 19, 4);
+ if (index == 4) return string(guid.c_str() + 24, 12);
+
+ return string();
+ }
+
+ void Swap(char* p1, char* p2)
+ {
+ char tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+ }
+
+ string Invert(const string& str)
+ {
+ char* buff = reinterpret_cast<char*>(_alloca(str.length()));
+ strncpy(buff, str.c_str(), str.length());
+
+ char* front = buff;
+ char* back = buff + str.length() - 1;
+
+ while (front < back)
+ Swap(front++, back--);
+
+ return string(buff, str.length());
+ }
+
+ // Convert the upgrade code (which is a GUID) according
+ // to the way the windows installer does when writing it
+ // to the registry
+ // The first 8 bytes will be inverted, from the the last
+ // 8 bytes always the nibbles will be inverted for further
+ // details look in the MSDN under compressed registry keys
+ string ConvertGuid(const string& guid)
+ {
+ string convertedGuid;
+
+ string part = GetGuidPart(guid, 0);
+ convertedGuid = Invert(part);
+
+ part = GetGuidPart(guid, 1);
+ convertedGuid += Invert(part);
+
+ part = GetGuidPart(guid, 2);
+ convertedGuid += Invert(part);
+
+ part = GetGuidPart(guid, 3);
+ convertedGuid += Invert(string(part.c_str(), 2));
+ convertedGuid += Invert(string(part.c_str() + 2, 2));
+
+ part = GetGuidPart(guid, 4);
+ int pos = 0;
+ for (int i = 0; i < 6; i++)
+ {
+ convertedGuid += Invert(string(part.c_str() + pos, 2));
+ pos += 2;
+ }
+ return convertedGuid;
+ }
+
+ string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ string result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+ return result;
+ }
+
+ inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ return (GetMsiProperty(handle, sProperty).length() > 0);
+ }
+
+ inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), NULL);
+ }
+
+ inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty)
+ {
+ MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
+ }
+
+ bool RegistryKeyHasUpgradeSubKey(
+ HKEY hRootKey, const string& regKey, const string& upgradeKey)
+ {
+ HKEY hKey;
+ if (RegOpenKey(hRootKey, regKey.c_str(), &hKey) == ERROR_SUCCESS)
+ {
+ DWORD nSubKeys;
+ DWORD lLongestSubKey;
+
+ if (RegQueryInfoKey(
+ hKey, NULL, NULL, NULL, &nSubKeys, &lLongestSubKey, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+ {
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(lLongestSubKey + 1));
+
+ for (DWORD i = 0; i < nSubKeys; i++)
+ {
+ LONG ret = RegEnumKey(hKey, i, buffer, lLongestSubKey + 1);
+ if ((ret == ERROR_SUCCESS) && (buffer == upgradeKey))
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+} // namespace
+
+extern "C" UINT __stdcall SetProductInstallMode(MSIHANDLE handle)
+{
+ string upgradeCode = GetMsiProperty(handle, TEXT("UpgradeCode"));
+ upgradeCode = ConvertGuid(string(upgradeCode.c_str() + 1, upgradeCode.length() - 2));
+
+ //MessageBox(NULL, upgradeCode.c_str(), TEXT("Debug"), MB_OK);
+
+ if (RegistryKeyHasUpgradeSubKey(
+ HKEY_CURRENT_USER,
+ TEXT("Software\\Microsoft\\Installer\\UpgradeCodes"),
+ upgradeCode) && IsSetMsiProperty(handle, TEXT("ALLUSERS")))
+ {
+ UnsetMsiProperty(handle, TEXT("ALLUSERS"));
+ //MessageBox(NULL, "ALLUSERS removed", "DEBUG", MB_OK);
+ }
+ else if (RegistryKeyHasUpgradeSubKey(
+ HKEY_LOCAL_MACHINE,
+ TEXT("Software\\Classes\\Installer\\UpgradeCodes"),
+ upgradeCode) && !IsSetMsiProperty(handle, TEXT("ALLUSERS")))
+ {
+ SetMsiProperty(handle, TEXT("ALLUSERS"));
+ //MessageBox(NULL, "ALLUSERS set", "DEBUG", MB_OK);
+ }
+ return ERROR_SUCCESS;
+}
diff --git a/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx b/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx
new file mode 100644
index 000000000000..70064b58807c
--- /dev/null
+++ b/setup_native/source/win32/customactions/shellextensions/vistaspecial.cxx
@@ -0,0 +1,242 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#define _WIN32_WINNT 0x0401
+
+#ifdef _MSC_VER
+#pragma warning(push, 1) /* disable warnings within system headers */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <msiquery.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <malloc.h>
+#include <assert.h>
+
+#ifdef UNICODE
+#define _UNICODE
+#define _tstring wstring
+#else
+#define _tstring string
+#endif
+#include <tchar.h>
+#include <string>
+#include <queue>
+#include <stdio.h>
+#include <strsafe.h>
+
+#include <systools/win32/uwinapi.h>
+#include <../tools/seterror.hxx>
+
+//----------------------------------------------------------
+#ifdef DEBUG
+inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
+{
+ CHAR buffer[1024];
+ va_list args;
+
+ va_start( args, pFormat );
+ StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
+ OutputDebugStringA( buffer );
+}
+#else
+static inline void OutputDebugStringFormat( LPCSTR, ... )
+{
+}
+#endif
+
+
+static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
+{
+ std::_tstring result;
+ TCHAR szDummy[1] = TEXT("");
+ DWORD nChars = 0;
+
+ if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
+ {
+ DWORD nBytes = ++nChars * sizeof(TCHAR);
+ LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
+ ZeroMemory( buffer, nBytes );
+ MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
+ result = buffer;
+ }
+
+ return result;
+}
+
+static BOOL RemoveCompleteDirectory( std::_tstring sPath )
+{
+ bool bDirectoryRemoved = true;
+
+ std::_tstring mystr;
+ std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*");
+ WIN32_FIND_DATA aFindData;
+
+ // Finding all content in sPath
+
+ HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData );
+
+ if ( hFindContent != INVALID_HANDLE_VALUE )
+ {
+ bool fNextFile = false;
+ std::_tstring sCurrentDir = TEXT(".");
+ std::_tstring sParentDir = TEXT("..");
+
+ do
+ {
+ std::_tstring sFileName = aFindData.cFileName;
+
+ mystr = "Current short file: " + sFileName;
+ // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK);
+
+ if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) &&
+ ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 ))
+ {
+ std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName;
+
+ if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
+ {
+ bool fSuccess = RemoveCompleteDirectory(sCompleteFileName);
+ if ( fSuccess )
+ {
+ mystr = "Successfully removed content of dir " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removing content of " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
+ }
+ }
+ else
+ {
+ bool fSuccess = DeleteFile( sCompleteFileName.c_str() );
+ if ( fSuccess )
+ {
+ mystr = "Successfully removed file " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removal of file " + sCompleteFileName;
+ // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK);
+ }
+ }
+ }
+
+ fNextFile = FindNextFile( hFindContent, &aFindData );
+
+ } while ( fNextFile );
+
+ FindClose( hFindContent );
+
+ // empty directory can be removed now
+ // RemoveDirectory is only successful, if the last handle to the directory is closed
+ // -> first removing content -> closing handle -> remove empty directory
+
+ bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str());
+
+ if ( fRemoveDirSuccess )
+ {
+ mystr = "Successfully removed dir " + sPath;
+ // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
+ }
+ else
+ {
+ mystr = "An error occured during removal of empty directory " + sPath;
+ // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
+ bDirectoryRemoved = false;
+ }
+ }
+
+ return bDirectoryRemoved;
+}
+
+
+
+extern "C" UINT __stdcall RenamePrgFolder( MSIHANDLE handle )
+{
+ std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+
+ std::_tstring sRenameSrc = sOfficeInstallPath + TEXT("program");
+ std::_tstring sRenameDst = sOfficeInstallPath + TEXT("program_old");
+
+// MessageBox(NULL, sRenameSrc.c_str(), "INSTALLLOCATION", MB_OK);
+
+ bool bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
+ if ( !bSuccess )
+ {
+ TCHAR sAppend[2] = TEXT("0");
+ for ( int i = 0; i < 10; i++ )
+ {
+ sRenameDst = sOfficeInstallPath + TEXT("program_old") + sAppend;
+ bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
+ if ( bSuccess )
+ break;
+ sAppend[0] += 1;
+ }
+ }
+
+#if 0
+ if ( !bSuccess )
+ MessageBox(NULL, "Renaming folder failed", "RenamePrgFolder", MB_OK);
+ else
+ MessageBox(NULL, "Renaming folder successful", "RenamePrgFolder", MB_OK);
+#endif
+
+ return ERROR_SUCCESS;
+}
+
+extern "C" UINT __stdcall RemovePrgFolder( MSIHANDLE handle )
+{
+ std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
+ std::_tstring sRemoveDir = sOfficeInstallPath + TEXT("program_old");
+
+// MessageBox(NULL, sRemoveDir.c_str(), "REMOVING OLD DIR", MB_OK);
+
+ bool bSuccess = RemoveCompleteDirectory( sRemoveDir );
+
+ TCHAR sAppend[2] = TEXT("0");
+ for ( int i = 0; i < 10; i++ )
+ {
+ sRemoveDir = sOfficeInstallPath + TEXT("program_old") + sAppend;
+ bSuccess = RemoveCompleteDirectory( sRemoveDir );
+ sAppend[0] += 1;
+ }
+
+#if 0
+ if ( bSuccess )
+ MessageBox(NULL, "Removing folder successful", "RemovePrgFolder", MB_OK);
+ else
+ MessageBox(NULL, "Removing folder failed", "RemovePrgFolder", MB_OK);
+#endif
+
+ return ERROR_SUCCESS;
+}