diff options
Diffstat (limited to 'setup_native/source/win32/customactions/shellextensions')
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; +} |