xref: /AOO41X/main/setup_native/source/win32/customactions/shellextensions/completeinstallpath.cxx (revision 32b1fd08cf0851da51c0ed68f50bc63c4ee660e0)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #define _WIN32_WINDOWS 0x0410
25 #ifdef _MSC_VER
26 #pragma warning(push, 1) /* disable warnings within system headers */
27 #endif
28 #define WIN32_LEAN_AND_MEAN
29 #include <windows.h>
30 #include <msiquery.h>
31 #ifdef _MSC_VER
32 #pragma warning(pop)
33 #endif
34 
35 #include <malloc.h>
36 
37 #ifdef UNICODE
38 #define _UNICODE
39 #define _tstring    wstring
40 #else
41 #define _tstring    string
42 #endif
43 #include <tchar.h>
44 #include <string>
45 
46 using namespace std;
47 
48 namespace
49 {
GetMsiProperty(MSIHANDLE handle,const std::_tstring & sProperty)50     std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
51     {
52         std::_tstring   result;
53         TCHAR   szDummy[1] = TEXT("");
54         DWORD   nChars = 0;
55 
56         if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
57         {
58             DWORD nBytes = ++nChars * sizeof(TCHAR);
59             LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
60             ZeroMemory( buffer, nBytes );
61             MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
62             result = buffer;
63         }
64 
65         return  result;
66     }
67 } // namespace
68 
CompleteInstallPath(MSIHANDLE handle)69 extern "C" UINT __stdcall CompleteInstallPath( MSIHANDLE handle )
70 {
71     // This CustomAction is necessary for updates from OOo 3.0, OOo 3.1 and OOo 3.2 to versions
72     // OOo 3.3 or later. This is caused by a change of INSTALLLOCATION, that starting with OOo 3.3
73     // contains the name of the product again (instead of only "c:\program files"). Unfortunately
74     // this causes in an update installation, that INSTALLLOCATION is set to "c:\program files",
75     // so that in an OOo 3.3 or later, the directory "program" or "share" are directly created
76     // below "c:\program files".
77 
78     TCHAR   szValue[8192];
79     DWORD   nValueSize = sizeof(szValue);
80     HKEY    hKey;
81     std::_tstring   sInstDir;
82     std::_tstring   mystr;
83 
84     // Reading property OFFICEDIRHOSTNAME_, that contains the part of the path behind
85     // the program files folder.
86 
87     std::_tstring   sInstallLocation = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
88     std::_tstring   sOfficeDirHostname = GetMsiProperty( handle, TEXT("OFFICEDIRHOSTNAME_") );
89 
90     // If sInstallLocation ends with (contains) the string sOfficeDirHostname,
91     // INSTALLLOCATION is good and nothing has to be done here.
92 
93     bool pathCompletionRequired = true;
94 
95     if ( _tcsstr( sInstallLocation.c_str(), sOfficeDirHostname.c_str() ) )
96     {
97         pathCompletionRequired = false;  // nothing to do
98         // mystr = "Nothing to do, officedir is included into installlocation";
99         // MessageBox( NULL, mystr.c_str(), "It is part of installlocation", MB_OK );
100     }
101 
102     // If the path INSTALLLOCATION does not end with this string, INSTALLLOCATION is maybe
103     // transfered from an OOo 3.0, OOo 3.1 and OOo 3.2 and need to be changed therefore.
104 
105     if ( pathCompletionRequired )
106     {
107         std::_tstring   sManufacturer = GetMsiProperty( handle, TEXT("Manufacturer") );
108         std::_tstring   sDefinedName = GetMsiProperty( handle, TEXT("DEFINEDPRODUCT") );
109         std::_tstring   sUpgradeCode = GetMsiProperty( handle, TEXT("UpgradeCode") );
110 
111         // sUpdateVersion can be "3.0", "3.1" or "3.2"
112 
113         std::_tstring   sProductKey30 = "Software\\" + sManufacturer + "\\" + sDefinedName +
114                                             "\\" + "3.0" + "\\" + sUpgradeCode;
115 
116         std::_tstring   sProductKey31 = "Software\\" + sManufacturer + "\\" + sDefinedName +
117                                             "\\" + "3.1" + "\\" + sUpgradeCode;
118 
119         std::_tstring   sProductKey32 = "Software\\" + sManufacturer + "\\" + sDefinedName +
120                                             "\\" + "3.2" + "\\" + sUpgradeCode;
121 
122         // mystr = "ProductKey: " + sProductKey;
123         // MessageBox( NULL, mystr.c_str(), "ProductKey", MB_OK );
124 
125         // mystr = "Checking registry";
126         // MessageBox( NULL, mystr.c_str(), "registry search", MB_OK );
127 
128         bool oldVersionExists = false;
129 
130         if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER,  sProductKey30.c_str(), &hKey ) )
131         {
132             oldVersionExists = true;
133             RegCloseKey( hKey );
134         }
135         else if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER,  sProductKey31.c_str(), &hKey ) )
136         {
137             oldVersionExists = true;
138             RegCloseKey( hKey );
139         }
140         else if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER,  sProductKey32.c_str(), &hKey ) )
141         {
142             oldVersionExists = true;
143             RegCloseKey( hKey );
144         }
145         else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE,  sProductKey30.c_str(), &hKey ) )
146         {
147             oldVersionExists = true;
148             RegCloseKey( hKey );
149         }
150         else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE,  sProductKey31.c_str(), &hKey ) )
151         {
152             oldVersionExists = true;
153             RegCloseKey( hKey );
154         }
155         else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE,  sProductKey32.c_str(), &hKey ) )
156         {
157             oldVersionExists = true;
158             RegCloseKey( hKey );
159         }
160 
161         if ( oldVersionExists )
162         {
163             // Adding the new path content sOfficeDirHostname
164             sInstallLocation = sInstallLocation + sOfficeDirHostname;
165             // Setting the new property value
166             MsiSetProperty(handle, TEXT("INSTALLLOCATION"), sInstallLocation.c_str());
167             // mystr = "Setting path to: " + sInstallLocation;
168             // MessageBox( NULL, mystr.c_str(), "sInstallLocation", MB_OK );
169         }
170     }
171 
172     // mystr = "Ending with INSTALLLOCATION: " + sInstallLocation;
173     // MessageBox( NULL, mystr.c_str(), "END", MB_OK );
174 
175     return ERROR_SUCCESS;
176 }
177