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 
MigrateInstallPath(MSIHANDLE handle)69 extern "C" UINT __stdcall MigrateInstallPath( MSIHANDLE handle )
70 {
71 	TCHAR	szValue[8192];
72 	DWORD	nValueSize = sizeof(szValue);
73 	HKEY	hKey;
74 	std::_tstring	sInstDir;
75 
76 	std::_tstring	sManufacturer = GetMsiProperty( handle, TEXT("Manufacturer") );
77 	std::_tstring	sDefinedName = GetMsiProperty( handle, TEXT("DEFINEDPRODUCT") );
78 	std::_tstring	sUpdateVersion = GetMsiProperty( handle, TEXT("DEFINEDVERSION") );
79 	std::_tstring	sUpgradeCode = GetMsiProperty( handle, TEXT("UpgradeCode") );
80 
81 	std::_tstring	sProductKey = "Software\\" + sManufacturer + "\\" + sDefinedName +
82 										"\\" + sUpdateVersion + "\\" + sUpgradeCode;
83 
84 	std::_tstring	mystr;
85 	mystr = "ProductKey: " + sProductKey;
86 	// MessageBox( NULL, mystr.c_str(), "ProductKey", MB_OK );
87 
88 	if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER,  sProductKey.c_str(), &hKey ) )
89 	{
90 		if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
91 		{
92 			sInstDir = szValue;
93 			MsiSetProperty(handle, TEXT("INSTALLLOCATION"), sInstDir.c_str());
94 			// MessageBox( NULL, sInstDir.c_str(), "Found in HKEY_CURRENT_USER", MB_OK );
95 		}
96 
97 		RegCloseKey( hKey );
98 	}
99 	else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE,  sProductKey.c_str(), &hKey ) )
100 	{
101 		if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
102 		{
103 			sInstDir = szValue;
104 			MsiSetProperty(handle, TEXT("INSTALLLOCATION"), sInstDir.c_str());
105 			// MessageBox( NULL, sInstDir.c_str(), "Found in HKEY_LOCAL_MACHINE", MB_OK );
106 		}
107 
108 		RegCloseKey( hKey );
109 	}
110 
111 	return ERROR_SUCCESS;
112 
113 }
114