Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / setup_native / source / win32 / customactions / shellextensions / completeinstallpath.cxx
blob4c338210517adb0ca63d8554fd3d15809001f553
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #define _WIN32_WINDOWS 0x0410
30 #ifdef _MSC_VER
31 #pragma warning(push, 1) /* disable warnings within system headers */
32 #endif
33 #define WIN32_LEAN_AND_MEAN
34 #include <windows.h>
35 #include <msiquery.h>
36 #ifdef _MSC_VER
37 #pragma warning(pop)
38 #endif
40 #include <malloc.h>
42 #ifdef UNICODE
43 #define _UNICODE
44 #define _tstring wstring
45 #else
46 #define _tstring string
47 #endif
48 #include <tchar.h>
49 #include <string>
51 using namespace std;
53 namespace
55 std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
57 std::_tstring result;
58 TCHAR szDummy[1] = TEXT("");
59 DWORD nChars = 0;
61 if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
63 DWORD nBytes = ++nChars * sizeof(TCHAR);
64 LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
65 ZeroMemory( buffer, nBytes );
66 MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
67 result = buffer;
70 return result;
72 } // namespace
74 extern "C" UINT __stdcall CompleteInstallPath( MSIHANDLE handle )
76 // This CustomAction is necessary for updates from OOo 3.0, OOo 3.1 and OOo 3.2 to versions
77 // OOo 3.3 or later. This is caused by a change of INSTALLLOCATION, that starting with OOo 3.3
78 // contains the name of the product again (instead of only "c:\program files"). Unfortunately
79 // this causes in an update installation, that INSTALLLOCATION is set to "c:\program files",
80 // so that in an OOo 3.3 or later, the directory "program" or "share" are directly created
81 // below "c:\program files".
83 TCHAR szValue[8192];
84 DWORD nValueSize = sizeof(szValue);
85 HKEY hKey;
87 // Reading property OFFICEDIRHOSTNAME_, that contains the part of the path behind
88 // the program files folder.
90 std::_tstring sInstallLocation = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
91 std::_tstring sOfficeDirHostname = GetMsiProperty( handle, TEXT("OFFICEDIRHOSTNAME_") );
93 // If sInstallLocation ends with (contains) the string sOfficeDirHostname,
94 // INSTALLLOCATION is good and nothing has to be done here.
96 bool pathCompletionRequired = true;
98 if ( _tcsstr( sInstallLocation.c_str(), sOfficeDirHostname.c_str() ) )
100 pathCompletionRequired = false; // nothing to do
103 // If the path INSTALLLOCATION does not end with this string, INSTALLLOCATION is maybe
104 // transfered from an OOo 3.0, OOo 3.1 and OOo 3.2 and need to be changed therefore.
106 if ( pathCompletionRequired )
108 std::_tstring sManufacturer = GetMsiProperty( handle, TEXT("Manufacturer") );
109 std::_tstring sDefinedName = GetMsiProperty( handle, TEXT("DEFINEDPRODUCT") );
110 std::_tstring sUpgradeCode = GetMsiProperty( handle, TEXT("UpgradeCode") );
112 // sUpdateVersion can be "3.0", "3.1" or "3.2"
114 std::_tstring sProductKey30 = "Software\\" + sManufacturer + "\\" + sDefinedName +
115 "\\" + "3.0" + "\\" + sUpgradeCode;
117 std::_tstring sProductKey31 = "Software\\" + sManufacturer + "\\" + sDefinedName +
118 "\\" + "3.1" + "\\" + sUpgradeCode;
120 std::_tstring sProductKey32 = "Software\\" + sManufacturer + "\\" + sDefinedName +
121 "\\" + "3.2" + "\\" + sUpgradeCode;
123 bool oldVersionExists = false;
125 if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey30.c_str(), &hKey ) )
127 oldVersionExists = true;
128 RegCloseKey( hKey );
130 else if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey31.c_str(), &hKey ) )
132 oldVersionExists = true;
133 RegCloseKey( hKey );
135 else if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, sProductKey32.c_str(), &hKey ) )
137 oldVersionExists = true;
138 RegCloseKey( hKey );
140 else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey30.c_str(), &hKey ) )
142 oldVersionExists = true;
143 RegCloseKey( hKey );
145 else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey31.c_str(), &hKey ) )
147 oldVersionExists = true;
148 RegCloseKey( hKey );
150 else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sProductKey32.c_str(), &hKey ) )
152 oldVersionExists = true;
153 RegCloseKey( hKey );
156 if ( oldVersionExists )
158 // Adding the new path content sOfficeDirHostname
159 sInstallLocation = sInstallLocation + sOfficeDirHostname;
160 // Setting the new property value
161 MsiSetProperty(handle, TEXT("INSTALLLOCATION"), sInstallLocation.c_str());
165 return ERROR_SUCCESS;
168 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */