summaryrefslogtreecommitdiff
path: root/setup_native/source/win32/customactions/patch/swappatchfiles.cxx
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2012-01-28 20:52:45 +0100
committerMichael Stahl <mstahl@redhat.com>2012-01-28 20:52:45 +0100
commit2e626373db2412ac22e8c5c27a60d11cd29e875b (patch)
tree9e9f67205cd5b72f1031721273e1534a3a1e5b0f /setup_native/source/win32/customactions/patch/swappatchfiles.cxx
parentf7ee7bbd5174b084f018c2ec94d8c70c98ee04da (diff)
replace obsolete "master" branch with README that points at new repoHEADmaster-deletedmaster
Diffstat (limited to 'setup_native/source/win32/customactions/patch/swappatchfiles.cxx')
-rw-r--r--setup_native/source/win32/customactions/patch/swappatchfiles.cxx845
1 files changed, 0 insertions, 845 deletions
diff --git a/setup_native/source/win32/customactions/patch/swappatchfiles.cxx b/setup_native/source/win32/customactions/patch/swappatchfiles.cxx
deleted file mode 100644
index 24fdb121b..000000000
--- a/setup_native/source/win32/customactions/patch/swappatchfiles.cxx
+++ /dev/null
@@ -1,845 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * 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 <sal/macros.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, SAL_N_ELEMENTS(buffer), pFormat, args );
- OutputDebugString( buffer );
-}
-#else
-static inline void OutputDebugStringFormat( LPCTSTR, ... )
-{
-}
-#endif
-
-static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
-{
- std::_tstring result;
- TCHAR szDummy[1] = TEXT("");
- DWORD nChars = 0;
-
- if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
- {
- DWORD nBytes = ++nChars * sizeof(TCHAR);
- LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
- ZeroMemory( buffer, nBytes );
- MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
- result = buffer;
- }
-
- return result;
-}
-
-// The provided GUID must be without surounding '{}'
-static std::_tstring GetGuidPart(const std::_tstring& guid, int index)
-{
- assert((guid.length() == 36) && "No GUID or wrong format!");
- assert(((index > -1) && (index < 5)) && "Out of range!");
-
- if (index == 0) return std::_tstring(guid.c_str(), 8);
- if (index == 1) return std::_tstring(guid.c_str() + 9, 4);
- if (index == 2) return std::_tstring(guid.c_str() + 14, 4);
- if (index == 3) return std::_tstring(guid.c_str() + 19, 4);
- if (index == 4) return std::_tstring(guid.c_str() + 24, 12);
-
- return std::_tstring();
-}
-
-static void Swap(char* p1, char* p2)
-{
- char tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
-}
-
-static std::_tstring Invert(const std::_tstring& str)
-{
- char* buff = reinterpret_cast<char*>(_alloca(str.length()));
- strncpy(buff, str.c_str(), str.length());
-
- char* front = buff;
- char* back = buff + str.length() - 1;
-
- while (front < back)
- Swap(front++, back--);
-
- return std::_tstring(buff, str.length());
-}
-
-// Convert the upgrade code (which is a GUID) according
-// to the way the windows installer does when writing it
-// to the registry
-// The first 8 bytes will be inverted, from the the last
-// 8 bytes always the nibbles will be inverted for further
-// details look in the MSDN under compressed registry keys
-static std::_tstring ConvertGuid(const std::_tstring& guid)
-{
- std::_tstring convertedGuid;
-
- std::_tstring part = GetGuidPart(guid, 0);
- convertedGuid = Invert(part);
-
- part = GetGuidPart(guid, 1);
- convertedGuid += Invert(part);
-
- part = GetGuidPart(guid, 2);
- convertedGuid += Invert(part);
-
- part = GetGuidPart(guid, 3);
- convertedGuid += Invert(std::_tstring(part.c_str(), 2));
- convertedGuid += Invert(std::_tstring(part.c_str() + 2, 2));
-
- part = GetGuidPart(guid, 4);
- int pos = 0;
- for (int i = 0; i < 6; i++)
- {
- convertedGuid += Invert(std::_tstring(part.c_str() + pos, 2));
- pos += 2;
- }
- return convertedGuid;
-}
-
-static inline bool IsSetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
-{
- std::_tstring value = GetMsiProperty(handle, sProperty);
- return (value.length() > 0);
-}
-
-static inline void UnsetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
-{
- MsiSetProperty(handle, sProperty.c_str(), NULL);
-}
-
-static inline void SetMsiProperty(MSIHANDLE handle, const std::_tstring& sProperty)
-{
- MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
-}
-
-static BOOL MoveFileEx9x( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
-{
- BOOL fSuccess = FALSE; // assume failure
-
- // Windows 9x has a special mechanism to move files after reboot
-
- if ( dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT )
- {
- CHAR szExistingFileNameA[MAX_PATH];
- CHAR szNewFileNameA[MAX_PATH] = "NUL";
-
- // Path names in WININIT.INI must be in short path name form
-
- if (
- GetShortPathNameA( lpExistingFileNameA, szExistingFileNameA, MAX_PATH ) &&
- (!lpNewFileNameA || GetShortPathNameA( lpNewFileNameA, szNewFileNameA, MAX_PATH ))
- )
- {
- CHAR szBuffer[32767]; // The buffer size must not exceed 32K
- DWORD dwBufLen = GetPrivateProfileSectionA( RENAME_SECTION, szBuffer, SAL_N_ELEMENTS(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 <= SAL_N_ELEMENTS(szBuffer) )
- {
- CopyMemory( &szBuffer[dwBufLen], szRename, lnRename );
- szBuffer[dwBufLen + lnRename ] = 0;
- szBuffer[dwBufLen + lnRename + 1 ] = 0;
-
- fSuccess = WritePrivateProfileSectionA( RENAME_SECTION, szBuffer, WININIT_FILENAME );
- }
- else
- SetLastError( ERROR_BUFFER_OVERFLOW );
- }
- }
- else
- {
-
- fSuccess = MoveFileA( lpExistingFileNameA, lpNewFileNameA );
-
- if ( !fSuccess && GetLastError() != ERROR_ACCESS_DENIED &&
- 0 != (dwFlags & (MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) )
- {
- BOOL bFailIfExist = 0 == (dwFlags & MOVEFILE_REPLACE_EXISTING);
-
- fSuccess = CopyFileA( lpExistingFileNameA, lpNewFileNameA, bFailIfExist );
-
- if ( fSuccess )
- fSuccess = DeleteFileA( lpExistingFileNameA );
- }
-
- }
-
- return fSuccess;
-}
-
-static BOOL MoveFileExImpl( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags )
-{
- if ( 0 > ((LONG)GetVersion())) // High order bit indicates Win 9x
- return MoveFileEx9x( lpExistingFileNameA, lpNewFileNameA, dwFlags );
- else
- return MoveFileExA( lpExistingFileNameA, lpNewFileNameA, dwFlags );
-}
-
-static bool SwapFiles( const std::_tstring& sFileName1, const std::_tstring& sFileName2 )
-{
- std::_tstring sTempFileName = sFileName1 + TEXT(".tmp");
-
- bool fSuccess = true;
-
- //Try to move the original file to a temp file
- fSuccess = MoveFileExImpl( sFileName1.c_str(), sTempFileName.c_str(), MOVEFILE_REPLACE_EXISTING);
-
- std::_tstring mystr;
-
- if ( fSuccess )
- {
- fSuccess = MoveFileExImpl( sFileName2.c_str(), sFileName1.c_str(), MOVEFILE_REPLACE_EXISTING );
-
- if ( fSuccess )
- {
- fSuccess = MoveFileExImpl( sTempFileName.c_str(), sFileName2.c_str(),
- MOVEFILE_REPLACE_EXISTING );
- if ( !fSuccess )
- {
- MoveFileExImpl( sFileName1.c_str(), sFileName2.c_str(), MOVEFILE_REPLACE_EXISTING );
- }
- }
- else
- {
- MoveFileExImpl( sTempFileName.c_str(), sFileName1.c_str(), MOVEFILE_REPLACE_EXISTING );
- }
- }
- else
- {
- //It could be that there is no original file and therefore copying the original to a temp
- // file failed. Examine if there is no original and if so then move file2 to file1
-
- WIN32_FIND_DATA data;
- HANDLE hdl = FindFirstFile(sFileName1.c_str(), &data);
- if (hdl == INVALID_HANDLE_VALUE)
- {
- fSuccess = MoveFileExImpl( sFileName2.c_str(), sFileName1.c_str(), MOVEFILE_REPLACE_EXISTING );
- }
- else
- {
- FindClose(hdl);
- }
- }
-
- OutputDebugStringFormat( TEXT("%s <-> %s: %s"), sFileName1.c_str(), sFileName2.c_str(), fSuccess ? TEXT("OK") : TEXT("FAILED") );
-
- if (!fSuccess )
- {
- DWORD dwError = GetLastError();
- LPVOID lpMsgBuf;
- if ( FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL ))
- {
- OutputDebugStringFormat( TEXT("Error Code %d: %s"), dwError, lpMsgBuf );
- LocalFree( lpMsgBuf );
- }
- else
- OutputDebugStringFormat( TEXT("Error Code %d: Unknown"), dwError );
- SetMsiErrorCode( dwError );
- }
-
- return fSuccess;
-}
-
-static std::_tstring strip( const std::_tstring& s, _TCHAR c )
-{
- std::_tstring result = s;
-
- std::_tstring::size_type f;
-
- do
- {
- f = result.find( c );
- if ( f != std::_tstring::npos )
- result.erase( f, 1 );
- } while ( f != std::_tstring::npos );
-
- return result;
-}
-
-static std::_tstring trim( const std::_tstring& rString )
-{
- std::_tstring temp = rString;
-
- while ( temp.length() && temp[0] == ' ' || temp[0] == '\t' )
- temp.erase( 0, 1 );
-
- std::_tstring::size_type len = temp.length();
-
- while ( len && temp[len-1] == ' ' || temp[len-1] == '\t' )
- {
- temp.erase( len - 1, 1 );
- len = temp.length();
- }
-
- return temp;
-}
-
-static bool readLine( FILE *fp, std::_tstring& rLine )
-{
- _TCHAR szBuffer[1024];
- bool bSuccess = false;
- bool bEOL = false;
- std::_tstring line;
-
-
- while ( !bEOL && _fgetts( szBuffer, sizeof(szBuffer), fp ) )
- {
- int len = _tcslen(szBuffer);
-
- bSuccess = true;
-
- while ( len && szBuffer[len - 1] == '\n' )
- {
- szBuffer[--len] = 0;
- bEOL = true;
- }
-
- line.append( szBuffer );
- }
-
- rLine = line;
- return bSuccess;
-}
-
-
-static std::_tstring getProfileString(
- const std::_tstring& aFileName,
- const std::_tstring& aSectionName,
- const std::_tstring& aKeyName,
- const std::_tstring& aDefault = _T("") )
-{
- FILE *fp = _tfopen( aFileName.c_str(), _T("r") );
- std::_tstring retValue = aDefault.length() ? aDefault : _T("");
-
- if ( fp )
- {
- std::_tstring line;
- std::_tstring section;
-
- while ( readLine( fp, line ) )
- {
- line = trim( line );
-
- if ( line.length() && line[0] == '[' )
- {
- line.erase( 0, 1 );
- std::_tstring::size_type end = line.find( ']', 0 );
-
- if ( std::_tstring::npos != end )
- section = trim( line.substr( 0, end ) );
- }
- else
- {
-
- std::_tstring::size_type iEqualSign = line.find( '=', 0 );
-
- if ( iEqualSign != std::_tstring::npos )
- {
- std::_tstring keyname = line.substr( 0, iEqualSign );
- keyname = trim( keyname );
-
- std::_tstring value = line.substr( iEqualSign + 1 /*, std::_tstring::npos */ );
- value = trim( value );
-
- if (
- 0 == _tcsicmp( section.c_str(), aSectionName.c_str() ) &&
- 0 == _tcsicmp( keyname.c_str(), aKeyName.c_str() )
- )
- {
- retValue = value;
- break;
- }
- }
- }
- }
-
- fclose( fp );
- }
-
- return retValue;
-}
-
-static std::queue< std::_tstring > getProfileSections( const std::_tstring& aFileName )
-{
- FILE *fp = _tfopen( aFileName.c_str(), _T("r") );
- std::queue< std::_tstring > aResult;
-
- OutputDebugStringFormat( TEXT("*** Retrieving Section Names ****") );
-
- if ( fp )
- {
- std::_tstring line;
- std::_tstring section;
-
- while ( readLine( fp, line ) )
- {
- line = trim( line );
-
- if ( line.length() && line[0] == '[' )
- {
- line.erase( 0, 1 );
- std::_tstring::size_type end = line.find( ']', 0 );
-
- if ( std::_tstring::npos != end )
- section = trim( line.substr( 0, end ) );
-
- aResult.push( section );
-
- OutputDebugStringFormat( TEXT("Section: %s"), section.c_str() );
-
- }
- }
-
- fclose( fp );
- }
-
- OutputDebugStringFormat( TEXT("*** Done Section Names ***") );
-
- return aResult;
-}
-
-static std::queue< std::_tstring > getProfileKeys( const std::_tstring& aFileName, const std::_tstring& aSectionName )
-{
- FILE *fp = _tfopen( aFileName.c_str(), _T("r") );
- std::queue< std::_tstring > aResult;
-
- OutputDebugStringFormat( TEXT("*** Retrieving Key Names for [%s] ***"), aSectionName.c_str() );
-
- if ( fp )
- {
- std::_tstring line;
- std::_tstring section;
-
- while ( readLine( fp, line ) )
- {
- line = trim( line );
-
- if ( line.length() && line[0] == '[' )
- {
- line.erase( 0, 1 );
- std::_tstring::size_type end = line.find( ']', 0 );
-
- if ( std::_tstring::npos != end )
- section = trim( line.substr( 0, end ) );
- }
- else
- {
-
- std::_tstring::size_type iEqualSign = line.find( '=', 0 );
-
- if ( iEqualSign != std::_tstring::npos )
- {
- std::_tstring keyname = line.substr( 0, iEqualSign );
- keyname = trim( keyname );
-
- if ( 0 == _tcsicmp( section.c_str(), aSectionName.c_str() ) )
- {
- aResult.push( keyname );
-
- OutputDebugStringFormat( keyname.c_str() );
-
- }
- }
- }
- }
-
- fclose( fp );
- }
-
- OutputDebugStringFormat( TEXT("*** Done Key Names for [%s] ***"), aSectionName.c_str() );
-
- return aResult;
-}
-
-extern "C" UINT __stdcall InstallPatchedFiles( MSIHANDLE handle )
-{
- std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
- std::_tstring sProgramDir = sInstDir + TEXT("Basis\\program\\");
- std::_tstring sPatchFile = sProgramDir + TEXT("patchlist.txt");
-
- std::queue< std::_tstring > aSectionNames;
- std::queue< std::_tstring > aKeyNames;
-
- OutputDebugStringA( "Starting Custom Action" );
-
- aSectionNames = getProfileSections( sPatchFile );
- while ( !aSectionNames.empty() )
- {
- std::_tstring sSectionName = aSectionNames.front();
- if ( std::_tstring(TEXT("_root")) == sSectionName ) { sSectionName = TEXT(""); }
-
- aKeyNames = getProfileKeys( sPatchFile, sSectionName );
- while ( !aKeyNames.empty() )
- {
- std::_tstring sKeyName = aKeyNames.front();
- std::_tstring sValue = getProfileString( sPatchFile, sSectionName, sKeyName );
-
- if ( sValue.length() )
- {
- std::_tstring sFileName1 = sKeyName;
- std::_tstring sExtension = sValue;
- std::_tstring sFileName2;
-
- sFileName1 = strip( sFileName1, '\"' );
- sExtension = strip( sExtension, '\"' );
-
- sFileName1 = sInstDir + sSectionName + sFileName1;
- sFileName2 = sFileName1 + sExtension;
-
- SwapFiles( sFileName1, sFileName2 );
- }
-
- aKeyNames.pop();
- }
-
- aSectionNames.pop();
- }
-
- return ERROR_SUCCESS;
-}
-
-extern "C" UINT __stdcall UninstallPatchedFiles( MSIHANDLE handle )
-{
- TCHAR szValue[8192];
- DWORD nValueSize = sizeof(szValue);
- HKEY hKey;
-
- std::_tstring sInstDir;
-
- std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
-
- if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey.c_str(), &hKey ) )
- {
- if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
- {
- sInstDir = szValue;
- }
- RegCloseKey( hKey );
- }
- else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey.c_str(), &hKey ) )
- {
- if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
- {
- sInstDir = szValue;
- }
- RegCloseKey( hKey );
- }
- else
- return ERROR_SUCCESS;
-
- std::_tstring sProgramDir = sInstDir + TEXT("Basis\\program\\");
- std::_tstring sPatchFile = sProgramDir + TEXT("patchlist.txt");
-
- std::queue< std::_tstring > aSectionNames;
- std::queue< std::_tstring > aKeyNames;
-
- aSectionNames = getProfileSections( sPatchFile );
- while ( !aSectionNames.empty() )
- {
- std::_tstring sSectionName = aSectionNames.front();
- if ( std::_tstring(TEXT("_root")) == sSectionName ) { sSectionName = TEXT(""); }
-
- aKeyNames = getProfileKeys( sPatchFile, sSectionName );
- while( !aKeyNames.empty() )
- {
- std::_tstring sKeyName = aKeyNames.front();
- std::_tstring sValue = getProfileString( sPatchFile, sSectionName, sKeyName );
-
- if ( sValue.length() )
- {
- std::_tstring sFileName1 = sKeyName;
- std::_tstring sExtension = sValue;
- std::_tstring sFileName2;
-
- sFileName1 = strip( sFileName1, '\"' );
- sExtension = strip( sExtension, '\"' );
-
- sFileName1 = sInstDir + sSectionName + sFileName1;
- sFileName2 = sFileName1 + sExtension;
-
- SwapFiles( sFileName2, sFileName1 );
- }
-
- aKeyNames.pop();
- }
-
- aSectionNames.pop();
- }
-
- return ERROR_SUCCESS;
-}
-
-extern "C" UINT __stdcall IsOfficeRunning( MSIHANDLE handle )
-{
- std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
- std::_tstring sResourceDir = sInstDir + TEXT("Basis\\program\\resource\\");
- std::_tstring sPattern = sResourceDir + TEXT("vcl*.res");
-
- WIN32_FIND_DATA aFindFileData;
- HANDLE hFind = FindFirstFile( sPattern.c_str(), &aFindFileData );
-
- if ( IsValidHandle(hFind) )
- {
- BOOL fSuccess = false;
- bool fRenameSucceeded;
-
- do
- {
- std::_tstring sResourceFile = sResourceDir + aFindFileData.cFileName;
- std::_tstring sIntermediate = sResourceFile + TEXT(".tmp");
-
- fRenameSucceeded = MoveFileExImpl( sResourceFile.c_str(), sIntermediate.c_str(), MOVEFILE_REPLACE_EXISTING );
- if ( fRenameSucceeded )
- {
- MoveFileExImpl( sIntermediate.c_str(), sResourceFile.c_str(), 0 );
- fSuccess = FindNextFile( hFind, &aFindFileData );
- }
- } while ( fSuccess && fRenameSucceeded );
-
- if ( !fRenameSucceeded )
- {
- MsiSetProperty(handle, TEXT("OFFICERUNS"), TEXT("1"));
- SetMsiErrorCode( MSI_ERROR_OFFICE_IS_RUNNING );
- }
-
- FindClose( hFind );
- }
-
-
- return ERROR_SUCCESS;
-}
-
-extern "C" UINT __stdcall SetFeatureState( MSIHANDLE handle )
-{
- std::_tstring mystr;
-
- // 1. Reading Product Code from setup.ini of installed Office
-
- std::_tstring sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
- std::_tstring sSetupiniPath = sInstallPath + TEXT("program\\setup.ini");
-
- TCHAR szProductCode[32767];
-
- GetPrivateProfileString(
- TEXT("Bootstrap"),
- TEXT("ProductCode"),
- TEXT("NOTFOUND"),
- szProductCode,
- SAL_N_ELEMENTS(szProductCode),
- sSetupiniPath.c_str()
- );
-
- if ( !_tcsicmp( szProductCode, TEXT("NOTFOUND") ) )
- {
- // No setup.ini or no "ProductCode" in setup.ini. This is an invalid directory.
- return ERROR_SUCCESS;
- }
-
- // 2. Converting Product code
-
- std::_tstring productCode = TEXT(szProductCode);
- productCode = ConvertGuid(std::_tstring(productCode.c_str() + 1, productCode.length() - 2));
- mystr = TEXT("Changed product code: ") + productCode;
-
- // 3. Setting path in the Windows registry to find installed features
-
- std::_tstring registryKey;
- HKEY registryRoot;
-
- if ( IsSetMsiProperty(handle, TEXT("ALLUSERS")) )
- {
- registryRoot = HKEY_LOCAL_MACHINE;
- registryKey = TEXT("Software\\Classes\\Installer\\Features\\") + productCode;
- mystr = registryKey;
- }
- else
- {
- registryRoot = HKEY_CURRENT_USER;
- registryKey = TEXT("Software\\Microsoft\\Installer\\Features\\") + productCode;
- mystr = registryKey;
- }
-
- // 4. Collecting all installed features from Windows registry
-
- HKEY hKey;
- if (RegOpenKey(registryRoot, registryKey.c_str(), &hKey) == ERROR_SUCCESS)
- {
- int counter = 0;
- LONG lEnumResult;
-
- do
- {
- TCHAR szValueName[8192];
- DWORD nValueNameSize = sizeof(szValueName);
- LPDWORD pValueNameSize = &nValueNameSize;
- TCHAR szValueData[8192];
- DWORD nValueDataSize = sizeof(szValueData);
-
- lEnumResult = RegEnumValue( hKey, counter, szValueName, pValueNameSize, NULL, NULL, (LPBYTE)szValueData, &nValueDataSize);
-
- if ( ERROR_SUCCESS == lEnumResult )
- {
- std::_tstring sValueName = szValueName;
- std::_tstring sValueData = szValueData;
-
- // Does this feature exist in this patch?
- if ( IsSetMsiProperty(handle, sValueName) )
- {
- // Feature is not installed, if szValueData starts with a "square" (ascii 6)
- if ( 6 == szValueData[0] )
- {
- MsiSetFeatureState(handle,sValueName.c_str(),INSTALLSTATE_ABSENT); // do not install this feature
- }
- else
- {
- MsiSetFeatureState(handle,sValueName.c_str(),INSTALLSTATE_LOCAL); // do install this feature
- }
- }
- }
-
- counter = counter + 1;
-
- } while ( ERROR_SUCCESS == lEnumResult );
-
- RegCloseKey( hKey );
- }
-
- return ERROR_SUCCESS;
-}
-
-extern "C" UINT __stdcall SetNewFeatureState( MSIHANDLE handle )
-{
- std::_tstring mystr;
- std::_tstring sValueName;
-
- sValueName = TEXT("gm_o_Onlineupdate");
-
- if (IsSetMsiProperty(handle, TEXT("SELECT_OU_FEATURE")))
- {
- MsiSetFeatureState(handle,sValueName.c_str(),INSTALLSTATE_LOCAL); // do install this feature
- }
- else
- {
- MsiSetFeatureState(handle,sValueName.c_str(),INSTALLSTATE_ABSENT); // do not install this feature
- }
-
- return ERROR_SUCCESS;
-}
-
-extern "C" UINT __stdcall ShowOnlineUpdateDialog( MSIHANDLE handle )
-{
- // Checking existence of file "updchk.uno.dll", which shows, that
- // Online Update functionality is always available. Then the dialog
- // that offers the Online Update is superfluous.
-
- std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
- std::_tstring sProgramDir = sInstDir + TEXT("Basis\\program\\");
- std::_tstring sSearchFile = sProgramDir + TEXT("updchk.uno.dll");
-
- WIN32_FIND_DATA data;
- HANDLE hdl = FindFirstFile(sSearchFile.c_str(), &data);
- if (hdl != INVALID_HANDLE_VALUE) // the file exists
- {
- // And finally setting property SHOW_ONLINEUPDATE_DIALOG
- // to hide this dialog
- UnsetMsiProperty(handle, TEXT("SHOW_ONLINEUPDATE_DIALOG"));
-
- // Setting SELECT_OU_FEATURE to 1, which is probably superfluous
- // because this is already the default value. But only this
- // guarantees, that CustomAction SetNewFeatureState always sets
- // the correct FeatureState for "gm_o_Onlineupdate", if it is
- // already installed.
- SetMsiProperty(handle, TEXT("SELECT_OU_FEATURE"));
- }
- else
- {
- // If the file does not exist, the Online Update dialog
- // has to be shown.
- SetMsiProperty(handle, TEXT("SHOW_ONLINEUPDATE_DIALOG"));
- FindClose(hdl);
- }
-
- return ERROR_SUCCESS;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */