summaryrefslogtreecommitdiff
path: root/setup_native
diff options
context:
space:
mode:
Diffstat (limited to 'setup_native')
-rw-r--r--setup_native/prj/build.lst1
-rw-r--r--setup_native/source/win32/customactions/languagepacks/respintest.cxx33
-rw-r--r--setup_native/source/win32/customactions/patch/exports.dxp8
-rw-r--r--setup_native/source/win32/customactions/patch/makefile.mk75
-rw-r--r--setup_native/source/win32/customactions/patch/swappatchfiles.cxx717
5 files changed, 1 insertions, 833 deletions
diff --git a/setup_native/prj/build.lst b/setup_native/prj/build.lst
index 1c3bf5301ce1..fb45ce854aff 100644
--- a/setup_native/prj/build.lst
+++ b/setup_native/prj/build.lst
@@ -15,7 +15,6 @@ pk setup_native\source\win32\customactions\quickstarter nmake - w sn_quic
pk setup_native\source\win32\customactions\shellextensions nmake - w sn_shellextensions sn_tools.w NULL
pk setup_native\source\win32\customactions\indexingfilter nmake - w sn_indexingfilter NULL
pk setup_native\source\win32\customactions\languagepacks nmake - w sn_languagepacks sn_shellextensions.w sn_tools.w NULL
-pk setup_native\source\win32\customactions\patch nmake - w sn_patch sn_languagepacks.w sn_shellextensions.w sn_quickstarter.w sn_tools.w NULL
pk setup_native\source\win32\wintools\makecab nmake - u sn_makecab NULL
pk setup_native\source\win32\wintools\msidb nmake - u sn_msidb NULL
pk setup_native\source\win32\wintools\msiinfo nmake - u sn_msiinfo NULL
diff --git a/setup_native/source/win32/customactions/languagepacks/respintest.cxx b/setup_native/source/win32/customactions/languagepacks/respintest.cxx
index 3362a7ad7e82..f757a880f912 100644
--- a/setup_native/source/win32/customactions/languagepacks/respintest.cxx
+++ b/setup_native/source/win32/customactions/languagepacks/respintest.cxx
@@ -150,38 +150,7 @@ extern "C" UINT __stdcall GetUserInstallMode(MSIHANDLE handle)
return ERROR_SUCCESS;
}
- // 3. Only for patch: Comparing "PRODUCTMINOR from property table and "ProductMinor" from InfoFile
-
- string isPatch = GetMsiProperty(handle, TEXT("ISPATCH"));
-
- if (isPatch=="1")
- {
- string ProductMinor = GetMsiProperty(handle, TEXT("PRODUCTBUILDID"));
- int PatchProductMinor = atoi(ProductMinor.c_str());
-
- szValue[0] = '\0';
-
- GetPrivateProfileString(
- TEXT("Bootstrap"),
- TEXT("ProductBuildid"),
- TEXT("8918"),
- szValue,
- SAL_N_ELEMENTS(szValue),
- sSetupiniPath.c_str()
- );
-
- int InstalledProductMinor = atoi(szValue);
-
- if ( InstalledProductMinor >= PatchProductMinor )
- {
- SetMsiProperty( handle, TEXT("PATCHISOLDER"), TEXT("YES") );
- // MessageBox(NULL, "PATCHISOLDER set", "DEBUG", MB_OK);
- SetMsiErrorCode( MSI_ERROR_PATCHISOLDER );
- return ERROR_SUCCESS;
- }
- }
-
- // 4. Setting property ALLUSERS with value from "setup.ini"
+ // 3. Setting property ALLUSERS with value from "setup.ini"
szValue[0] = '\0';
diff --git a/setup_native/source/win32/customactions/patch/exports.dxp b/setup_native/source/win32/customactions/patch/exports.dxp
deleted file mode 100644
index bb660772a68b..000000000000
--- a/setup_native/source/win32/customactions/patch/exports.dxp
+++ /dev/null
@@ -1,8 +0,0 @@
-InstallPatchedFiles
-UninstallPatchedFiles
-GetUserInstallMode
-SetProductInstallMode
-ShutDownQuickstarter
-SetFeatureState
-SetNewFeatureState
-ShowOnlineUpdateDialog
diff --git a/setup_native/source/win32/customactions/patch/makefile.mk b/setup_native/source/win32/customactions/patch/makefile.mk
deleted file mode 100644
index 81ff1c4878f7..000000000000
--- a/setup_native/source/win32/customactions/patch/makefile.mk
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# This file is part of the LibreOffice project.
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#
-# This file incorporates work covered by the following license notice:
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed
-# with this work for additional information regarding copyright
-# ownership. The ASF licenses this file to you under the Apache
-# License, Version 2.0 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.apache.org/licenses/LICENSE-2.0 .
-#
-
-PRJ=..$/..$/..$/..
-PRJNAME=setup_native
-TARGET=patchmsi
-
-# --- Settings -----------------------------------------------------
-
-ENABLE_EXCEPTIONS=TRUE
-NO_DEFAULT_STL=TRUE
-DYNAMIC_CRT=
-USE_DEFFILE=TRUE
-
-.INCLUDE : settings.mk
-
-# --- Files --------------------------------------------------------
-
-.IF "$(OS)"=="WNT" && "$(WINDOWS_SDK_HOME)"!=""
-
-UWINAPILIB=
-
-SLOFILES = \
- $(SLO)$/swappatchfiles.obj
-
-STDSHL += \
- $(ADVAPI32LIB)\
- $(MSILIB)\
- $(SHELL32LIB)
-
-.IF "$(COM)"=="GCC"
-STDSHL+= \
- $(KERNEL32LIB)\
- -lmsvcrt
-.ENDIF
-
-
-SHL1OBJS = $(SLOFILES) \
- $(SLO)$/respintest.obj \
- $(SLO)$/shutdown_quickstart.obj \
- $(SLO)$/quickstarter.obj \
- $(SLO)$/upgrade.obj \
- $(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/patch/swappatchfiles.cxx b/setup_native/source/win32/customactions/patch/swappatchfiles.cxx
deleted file mode 100644
index f2eb25428b6c..000000000000
--- a/setup_native/source/win32/customactions/patch/swappatchfiles.cxx
+++ /dev/null
@@ -1,717 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#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>
-
-#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 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 = MoveFileExA( sFileName1.c_str(), sTempFileName.c_str(), MOVEFILE_REPLACE_EXISTING);
-
- if ( fSuccess )
- {
- fSuccess = MoveFileExA( sFileName2.c_str(), sFileName1.c_str(), MOVEFILE_REPLACE_EXISTING );
-
- if ( fSuccess )
- {
- fSuccess = MoveFileExA( sTempFileName.c_str(), sFileName2.c_str(),
- MOVEFILE_REPLACE_EXISTING );
- if ( !fSuccess )
- {
- MoveFileExA( sFileName1.c_str(), sFileName2.c_str(), MOVEFILE_REPLACE_EXISTING );
- }
- }
- else
- {
- MoveFileExA( 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 = MoveFileExA( 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("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("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 SetFeatureState( MSIHANDLE handle )
-{
-
- // 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));
-
- // 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;
- }
- else
- {
- registryRoot = HKEY_CURRENT_USER;
- registryKey = TEXT("Software\\Microsoft\\Installer\\Features\\") + productCode;
- }
-
- // 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;
-
- // 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 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("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: */