1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir /*
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir */
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #define UNICODE
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #ifdef _MSC_VER
36*cdf0e10cSrcweir #pragma warning(push, 1) /* disable warnings within system headers */
37*cdf0e10cSrcweir #endif
38*cdf0e10cSrcweir #define WIN32_LEAN_AND_MEAN
39*cdf0e10cSrcweir #include <windows.h>
40*cdf0e10cSrcweir #include <msiquery.h>
41*cdf0e10cSrcweir #ifdef _MSC_VER
42*cdf0e10cSrcweir #pragma warning(pop)
43*cdf0e10cSrcweir #endif
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #include <malloc.h>
46*cdf0e10cSrcweir //#include <string>
47*cdf0e10cSrcweir //#include <map>
48*cdf0e10cSrcweir #include <strsafe.h>
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir // 10.11.2009 tkr: MinGW doesn't know anything about RegDeleteKeyExW if WINVER < 0x0502.
51*cdf0e10cSrcweir extern "C" {
52*cdf0e10cSrcweir WINADVAPI LONG WINAPI RegDeleteKeyExW(HKEY,LPCWSTR,REGSAM,DWORD);
53*cdf0e10cSrcweir }
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir // 06.11.2009 tkr: to provide windows xp as build systems for mingw we need to define KEY_WOW64_64KEY
56*cdf0e10cSrcweir // in mingw 3.13 KEY_WOW64_64KEY isn't available < Win2003 systems.
57*cdf0e10cSrcweir // Also defined in setup_native\source\win32\customactions\reg64\reg64.cxx,source\win32\customactions\shellextensions\shellextensions.cxx and
58*cdf0e10cSrcweir // extensions\source\activex\main\so_activex.cpp
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir #ifndef KEY_WOW64_64KEY
61*cdf0e10cSrcweir 	#define KEY_WOW64_64KEY	(0x0100)
62*cdf0e10cSrcweir #endif
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir #define TABLE_NAME L"Reg64"
66*cdf0e10cSrcweir #define INSTALLLOCATION L"[INSTALLLOCATION]"
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir bool isInstall4AllUsers;
69*cdf0e10cSrcweir wchar_t * sBasisInstallLocation;
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir enum OPERATION {
73*cdf0e10cSrcweir 	SET,
74*cdf0e10cSrcweir 	REMOVE
75*cdf0e10cSrcweir };
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir #ifdef DEBUG
78*cdf0e10cSrcweir inline void OutputDebugStringFormat( const wchar_t* pFormat, ... )
79*cdf0e10cSrcweir {
80*cdf0e10cSrcweir 	wchar_t    buffer[1024];
81*cdf0e10cSrcweir 	va_list args;
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir 	va_start( args, pFormat );
84*cdf0e10cSrcweir 	StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
85*cdf0e10cSrcweir 	OutputDebugString( buffer );
86*cdf0e10cSrcweir }
87*cdf0e10cSrcweir #else
88*cdf0e10cSrcweir static inline void OutputDebugStringFormat( const wchar_t*, ... )
89*cdf0e10cSrcweir {
90*cdf0e10cSrcweir }
91*cdf0e10cSrcweir #endif
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir bool WriteRegistry( MSIHANDLE & hMSI, OPERATION op, const wchar_t* componentName)
94*cdf0e10cSrcweir {
95*cdf0e10cSrcweir 	INSTALLSTATE current_state;
96*cdf0e10cSrcweir     INSTALLSTATE comp_state;
97*cdf0e10cSrcweir 	UINT ret = MsiGetComponentState( hMSI, componentName, &current_state, &comp_state );
98*cdf0e10cSrcweir 	if ( ERROR_SUCCESS == ret )
99*cdf0e10cSrcweir 	{
100*cdf0e10cSrcweir 		if (current_state == INSTALLSTATE_ABSENT)
101*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_ABSENT");
102*cdf0e10cSrcweir 		else if (current_state == INSTALLSTATE_DEFAULT)
103*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_DEFAULT");
104*cdf0e10cSrcweir 		else if (current_state == INSTALLSTATE_LOCAL)
105*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_LOCAL");
106*cdf0e10cSrcweir 		else if (current_state == INSTALLSTATE_REMOVED)
107*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_REMOVED");
108*cdf0e10cSrcweir 		else if (current_state == INSTALLSTATE_SOURCE)
109*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_SOURCE");
110*cdf0e10cSrcweir 		else if (current_state == INSTALLSTATE_UNKNOWN)
111*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - current_state: INSTALLSTATE_UNKNOWN");
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir 		if (comp_state == INSTALLSTATE_ABSENT)
114*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_ABSENT");
115*cdf0e10cSrcweir 		else if (comp_state == INSTALLSTATE_DEFAULT)
116*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_DEFAULT");
117*cdf0e10cSrcweir 		else if (comp_state == INSTALLSTATE_LOCAL)
118*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_LOCAL");
119*cdf0e10cSrcweir 		else if (comp_state == INSTALLSTATE_REMOVED)
120*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_REMOVED");
121*cdf0e10cSrcweir 		else if (comp_state == INSTALLSTATE_SOURCE)
122*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_SOURCE");
123*cdf0e10cSrcweir 		else if (comp_state == INSTALLSTATE_UNKNOWN)
124*cdf0e10cSrcweir 			OutputDebugStringFormat(L"WriteRegistry - comp_state: INSTALLSTATE_UNKNOWN");
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir 		switch (op)
127*cdf0e10cSrcweir 		{
128*cdf0e10cSrcweir 			case SET :
129*cdf0e10cSrcweir 				if ( comp_state == INSTALLSTATE_LOCAL || ( current_state == INSTALLSTATE_LOCAL && comp_state == INSTALLSTATE_UNKNOWN ) )
130*cdf0e10cSrcweir 				{
131*cdf0e10cSrcweir 					return true;
132*cdf0e10cSrcweir 				}
133*cdf0e10cSrcweir 				break;
134*cdf0e10cSrcweir 			case REMOVE:
135*cdf0e10cSrcweir 				OutputDebugStringFormat(L"WriteRegistry - Remove\n" );
136*cdf0e10cSrcweir 				if ( current_state == INSTALLSTATE_LOCAL && (comp_state == INSTALLSTATE_ABSENT || comp_state == INSTALLSTATE_REMOVED) )
137*cdf0e10cSrcweir 				{
138*cdf0e10cSrcweir 					OutputDebugStringFormat(L"WriteRegistry - To be removed\n" );
139*cdf0e10cSrcweir 					return true;
140*cdf0e10cSrcweir 				}
141*cdf0e10cSrcweir 		}
142*cdf0e10cSrcweir 	} else
143*cdf0e10cSrcweir 	{
144*cdf0e10cSrcweir 		if (ERROR_INVALID_HANDLE == ret) OutputDebugStringFormat(L"WriteRegistry - Invalid handle");
145*cdf0e10cSrcweir 		if (ERROR_UNKNOWN_FEATURE  == ret) OutputDebugStringFormat(L"WriteRegistry - Unknown feature");
146*cdf0e10cSrcweir 	}
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir 	return false;
149*cdf0e10cSrcweir }
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir BOOL UnicodeEquals( wchar_t* pStr1, wchar_t* pStr2 )
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir 	if ( pStr1 == NULL && pStr2 == NULL )
154*cdf0e10cSrcweir 		return TRUE;
155*cdf0e10cSrcweir 	else if ( pStr1 == NULL || pStr2 == NULL )
156*cdf0e10cSrcweir 		return FALSE;
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir 	while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
159*cdf0e10cSrcweir 		pStr1++, pStr2++;
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir 	return ( *pStr1 == 0 && *pStr2 == 0 );
162*cdf0e10cSrcweir }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir BOOL GetMsiProp( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
165*cdf0e10cSrcweir {
166*cdf0e10cSrcweir 	OutputDebugStringFormat(L"GetMsiProp - START\n" );
167*cdf0e10cSrcweir     DWORD sz = 0;
168*cdf0e10cSrcweir 	UINT ret = MsiGetProperty( hMSI, pPropName, L"", &sz );
169*cdf0e10cSrcweir    	if ( ret == ERROR_MORE_DATA )
170*cdf0e10cSrcweir    	{
171*cdf0e10cSrcweir        	sz++;
172*cdf0e10cSrcweir        	DWORD nbytes = sz * sizeof( wchar_t );
173*cdf0e10cSrcweir        	wchar_t* buff = reinterpret_cast<wchar_t*>( malloc( nbytes ) );
174*cdf0e10cSrcweir        	ZeroMemory( buff, nbytes );
175*cdf0e10cSrcweir        	MsiGetProperty( hMSI, pPropName, buff, &sz );
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir 		OutputDebugStringFormat(L"GetMsiProp - Value" );
178*cdf0e10cSrcweir 		OutputDebugStringFormat( buff );
179*cdf0e10cSrcweir    		*ppValue = buff;
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir 		return TRUE;
182*cdf0e10cSrcweir 	} else if (ret  == ERROR_INVALID_HANDLE)
183*cdf0e10cSrcweir 	{
184*cdf0e10cSrcweir 		OutputDebugStringFormat(L"GetMsiProp - ERROR_INVALID_HANDLE" );
185*cdf0e10cSrcweir 	} else if (ret == ERROR_INVALID_PARAMETER)
186*cdf0e10cSrcweir 	{
187*cdf0e10cSrcweir 		OutputDebugStringFormat(L"GetMsiProp - ERROR_INVALID_PARAMETER" );
188*cdf0e10cSrcweir 	} else if (ret == ERROR_SUCCESS)
189*cdf0e10cSrcweir 	{
190*cdf0e10cSrcweir 		OutputDebugStringFormat(L"GetMsiProp - ERROR_SUCCESS" );
191*cdf0e10cSrcweir 	}
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 	OutputDebugStringFormat(L"GetMsiProp - ENDE\n" );
195*cdf0e10cSrcweir 	return FALSE;
196*cdf0e10cSrcweir }
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir bool IsInstallForAllUsers( MSIHANDLE hMSI )
199*cdf0e10cSrcweir {
200*cdf0e10cSrcweir 	OutputDebugStringFormat(L"IsInstallForAllUsers - START\n" );
201*cdf0e10cSrcweir     bool bResult = FALSE;
202*cdf0e10cSrcweir     wchar_t* pVal = NULL;
203*cdf0e10cSrcweir     if ( GetMsiProp( hMSI, L"ALLUSERS", &pVal ) && pVal )
204*cdf0e10cSrcweir 	{
205*cdf0e10cSrcweir     	bResult = UnicodeEquals( pVal , L"1" );
206*cdf0e10cSrcweir 		free( pVal );
207*cdf0e10cSrcweir 	}
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir 	OutputDebugStringFormat(L"IsInstallForAllUsers - ENDE\n" );
210*cdf0e10cSrcweir 	return bResult;
211*cdf0e10cSrcweir }
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir wchar_t* GetBasisInstallLocation( MSIHANDLE hMSI )
214*cdf0e10cSrcweir {
215*cdf0e10cSrcweir 	OutputDebugStringFormat(L"GetBasisInstallLocation - START\n" );
216*cdf0e10cSrcweir     bool bResult = FALSE;
217*cdf0e10cSrcweir     wchar_t* pVal = NULL;
218*cdf0e10cSrcweir     GetMsiProp( hMSI, L"INSTALLLOCATION", &pVal);
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir     OutputDebugStringFormat(L"GetBasisInstallLocation - ENDE\n" );
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir     return pVal;
223*cdf0e10cSrcweir }
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir bool QueryReg64Table(MSIHANDLE& rhDatabase, MSIHANDLE& rhView)
227*cdf0e10cSrcweir {
228*cdf0e10cSrcweir 	OutputDebugStringFormat(L"QueryReg64Table - START\n" );
229*cdf0e10cSrcweir 	int const arraysize = 400;
230*cdf0e10cSrcweir 	wchar_t szSelect[arraysize];
231*cdf0e10cSrcweir 	StringCbPrintfW(szSelect, arraysize * sizeof(wchar_t), L"SELECT * FROM %s",TABLE_NAME);
232*cdf0e10cSrcweir 	OutputDebugStringFormat( szSelect );
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir 	UINT ret = MsiDatabaseOpenView(rhDatabase,szSelect,&rhView);
235*cdf0e10cSrcweir 	if (ret != ERROR_SUCCESS)
236*cdf0e10cSrcweir 	{
237*cdf0e10cSrcweir 		if ( ret == ERROR_BAD_QUERY_SYNTAX)
238*cdf0e10cSrcweir 			OutputDebugStringFormat(L"QueryReg64Table - MsiDatabaseOpenView - FAILED - ERROR_BAD_QUERY_SYNTAX\n" );
239*cdf0e10cSrcweir 		if ( ret == ERROR_INVALID_HANDLE)
240*cdf0e10cSrcweir 			OutputDebugStringFormat(L"QueryReg64Table - MsiDatabaseOpenView - FAILED - ERROR_INVALID_HANDLE\n" );
241*cdf0e10cSrcweir 		return false;
242*cdf0e10cSrcweir 	}
243*cdf0e10cSrcweir 	// execute query - not a parameter query so second parameter is NULL.
244*cdf0e10cSrcweir 	if (MsiViewExecute(rhView,NULL) != ERROR_SUCCESS)
245*cdf0e10cSrcweir 	{
246*cdf0e10cSrcweir 		OutputDebugStringFormat(L"QueryReg64Table - MsiViewExecute - FAILED\n" );
247*cdf0e10cSrcweir 		return false;
248*cdf0e10cSrcweir 	}
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 	OutputDebugStringFormat(L"QueryReg64Table - ENDE\n" );
251*cdf0e10cSrcweir 	return true;
252*cdf0e10cSrcweir }
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir //---------------------------------------
255*cdf0e10cSrcweir bool DeleteRegistryKey(HKEY RootKey, const wchar_t* KeyName)
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir 	int rc = RegDeleteKeyExW(
258*cdf0e10cSrcweir 		RootKey, KeyName, KEY_WOW64_64KEY, 0);
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir 	return (ERROR_SUCCESS == rc);
261*cdf0e10cSrcweir }
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir //---------------------------------------
267*cdf0e10cSrcweir //
268*cdf0e10cSrcweir //---------------------------------------
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir bool SetRegistryKey(HKEY RootKey, const wchar_t* KeyName, const wchar_t* ValueName, const wchar_t* Value)
271*cdf0e10cSrcweir {
272*cdf0e10cSrcweir 	HKEY hSubKey;
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir 	// open or create the desired key
275*cdf0e10cSrcweir 	int rc = RegCreateKeyEx(
276*cdf0e10cSrcweir 		RootKey, KeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_64KEY, 0, &hSubKey, 0);
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir 	if (ERROR_SUCCESS == rc)
279*cdf0e10cSrcweir 	{
280*cdf0e10cSrcweir 		OutputDebugStringFormat(L"SetRegistryKey - Created\n" );
281*cdf0e10cSrcweir 		rc = RegSetValueEx(
282*cdf0e10cSrcweir 			hSubKey, ValueName, 0, REG_SZ, reinterpret_cast<const BYTE*>(Value), (wcslen(Value) + 1) * sizeof(wchar_t));
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir 		RegCloseKey(hSubKey);
285*cdf0e10cSrcweir 	} else {
286*cdf0e10cSrcweir 		OutputDebugStringFormat(L"SetRegistryKey - FAILED\n" );
287*cdf0e10cSrcweir 	}
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir 	return (ERROR_SUCCESS == rc);
291*cdf0e10cSrcweir }
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir bool DoRegEntries( MSIHANDLE& rhMSI, OPERATION op, MSIHANDLE& rhView)
294*cdf0e10cSrcweir {
295*cdf0e10cSrcweir 	OutputDebugStringFormat(L"DoRegEntries - START\n" );
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir 	MSIHANDLE hRecord;
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir 	long lRoot;
300*cdf0e10cSrcweir 	wchar_t  szKey[255];
301*cdf0e10cSrcweir 	wchar_t  szName[255];
302*cdf0e10cSrcweir 	wchar_t  szValue[1024];
303*cdf0e10cSrcweir 	wchar_t  szComponent[255];
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir 	/// read records until there are no more records
306*cdf0e10cSrcweir 	while (MsiViewFetch(rhView,&hRecord) == ERROR_SUCCESS)
307*cdf0e10cSrcweir 	{
308*cdf0e10cSrcweir 		DWORD	 dwKey = 255;
309*cdf0e10cSrcweir 		DWORD	 dwName = 255;
310*cdf0e10cSrcweir 		DWORD	 dwValue = 1024;
311*cdf0e10cSrcweir 		DWORD	 dwComponent = 255;
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir 		szKey[0] = '\0';
314*cdf0e10cSrcweir 		szName[0] = '\0';
315*cdf0e10cSrcweir 		szValue[0] = '\0';
316*cdf0e10cSrcweir 		szComponent[0] = '\0';
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir 		lRoot = MsiRecordGetInteger(hRecord,2);
319*cdf0e10cSrcweir 		MsiRecordGetString(hRecord,3,szKey,&dwKey);
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir 		if (!MsiRecordIsNull(hRecord, 4))
322*cdf0e10cSrcweir 			MsiRecordGetString(hRecord,4,szName,&dwName);
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir 		if (!MsiRecordIsNull(hRecord, 5))
325*cdf0e10cSrcweir 		{
326*cdf0e10cSrcweir 			MsiRecordGetString(hRecord,5,szValue,&dwValue);
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir 			wchar_t* nPos = wcsstr(szValue , INSTALLLOCATION);
331*cdf0e10cSrcweir 			if ( NULL != nPos)
332*cdf0e10cSrcweir 			{
333*cdf0e10cSrcweir 
334*cdf0e10cSrcweir 				DWORD nPrefixSize = nPos - szValue;
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir 				DWORD nPropSize = wcslen(sBasisInstallLocation);
337*cdf0e10cSrcweir 				DWORD nPostfixSize = dwValue - wcslen( INSTALLLOCATION );
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir 				DWORD nNewValueBytes = (nPropSize + nPostfixSize + 1) * sizeof( wchar_t );
340*cdf0e10cSrcweir        			wchar_t* newValue = reinterpret_cast<wchar_t*>( malloc( nNewValueBytes ) );
341*cdf0e10cSrcweir        			ZeroMemory( newValue, nNewValueBytes );
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir 				// prefix
344*cdf0e10cSrcweir 				wcsncpy(newValue, szValue, nPrefixSize);
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir 				// basis location
347*cdf0e10cSrcweir 				wcsncat(newValue, sBasisInstallLocation, nPropSize * sizeof( wchar_t ));
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir 				// postfix
350*cdf0e10cSrcweir 				wcsncat(newValue, nPos + ( wcslen( INSTALLLOCATION ) ), nPropSize * sizeof( wchar_t ));
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir 				wcsncpy(szValue, newValue, nNewValueBytes <=1024? nNewValueBytes: 1024);
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir 				free(newValue);
355*cdf0e10cSrcweir 			}
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir 		}
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir 		MsiRecordGetString(hRecord,6,szComponent,&dwComponent);
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir 		OutputDebugStringFormat(L"****** DoRegEntries *******" );
363*cdf0e10cSrcweir 		OutputDebugStringFormat(L"Root:" );
364*cdf0e10cSrcweir 		HKEY key = HKEY_CURRENT_USER;
365*cdf0e10cSrcweir 		switch (lRoot)
366*cdf0e10cSrcweir 		{
367*cdf0e10cSrcweir 			case(-1):
368*cdf0e10cSrcweir 					if (isInstall4AllUsers)
369*cdf0e10cSrcweir 					{
370*cdf0e10cSrcweir 						key = HKEY_LOCAL_MACHINE;
371*cdf0e10cSrcweir 						OutputDebugStringFormat(L"HKEY_LOCAL_MACHINE" );
372*cdf0e10cSrcweir 					}
373*cdf0e10cSrcweir 					else
374*cdf0e10cSrcweir 					{
375*cdf0e10cSrcweir 						key = HKEY_CURRENT_USER;
376*cdf0e10cSrcweir 						OutputDebugStringFormat(L"HKEY_CURRENT_USER" );
377*cdf0e10cSrcweir 					}
378*cdf0e10cSrcweir 				break;
379*cdf0e10cSrcweir 			case(0):
380*cdf0e10cSrcweir 					key = HKEY_CLASSES_ROOT;
381*cdf0e10cSrcweir 					OutputDebugStringFormat(L"HKEY_CLASSES_ROOT" );
382*cdf0e10cSrcweir 				break;
383*cdf0e10cSrcweir 			case(1):
384*cdf0e10cSrcweir 					key = HKEY_CURRENT_USER;
385*cdf0e10cSrcweir 					OutputDebugStringFormat(L"HKEY_CURRENT_USER" );
386*cdf0e10cSrcweir 				break;
387*cdf0e10cSrcweir 			case(2):
388*cdf0e10cSrcweir 					key = HKEY_LOCAL_MACHINE;
389*cdf0e10cSrcweir 					OutputDebugStringFormat(L"HKEY_LOCAL_MACHINE" );
390*cdf0e10cSrcweir 				break;
391*cdf0e10cSrcweir 			case(3):
392*cdf0e10cSrcweir 					key = HKEY_USERS;
393*cdf0e10cSrcweir 					OutputDebugStringFormat(L"HKEY_USERS" );
394*cdf0e10cSrcweir 				break;
395*cdf0e10cSrcweir 			default:
396*cdf0e10cSrcweir 					OutputDebugStringFormat(L"Unknown Root!" );
397*cdf0e10cSrcweir 				break;
398*cdf0e10cSrcweir 		}
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir 		OutputDebugStringFormat(L"Key:");
401*cdf0e10cSrcweir 		OutputDebugStringFormat( szKey );
402*cdf0e10cSrcweir 		OutputDebugStringFormat(L"Name:");
403*cdf0e10cSrcweir 		OutputDebugStringFormat( szName );
404*cdf0e10cSrcweir 		OutputDebugStringFormat(L"Value:");
405*cdf0e10cSrcweir 		OutputDebugStringFormat( szValue);
406*cdf0e10cSrcweir 		OutputDebugStringFormat(L"Component:");
407*cdf0e10cSrcweir 		OutputDebugStringFormat( szComponent );
408*cdf0e10cSrcweir 		OutputDebugStringFormat(L"*******************" );
409*cdf0e10cSrcweir 		switch (op)
410*cdf0e10cSrcweir 		{
411*cdf0e10cSrcweir 			case SET:
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir 					if (WriteRegistry(rhMSI, SET, szComponent))
414*cdf0e10cSrcweir 					{
415*cdf0e10cSrcweir 						OutputDebugStringFormat(L"DoRegEntries - Write\n" );
416*cdf0e10cSrcweir 						SetRegistryKey(key, szKey, szName, szValue);
417*cdf0e10cSrcweir 					}
418*cdf0e10cSrcweir 				break;
419*cdf0e10cSrcweir 			case REMOVE:
420*cdf0e10cSrcweir 					OutputDebugStringFormat(L"DoRegEntries - PreRemove\n" );
421*cdf0e10cSrcweir 					if (WriteRegistry(rhMSI, REMOVE, szComponent))
422*cdf0e10cSrcweir 					{
423*cdf0e10cSrcweir 						OutputDebugStringFormat(L"DoRegEntries - Remove\n" );
424*cdf0e10cSrcweir 						DeleteRegistryKey(key, szKey);
425*cdf0e10cSrcweir 					}
426*cdf0e10cSrcweir 				break;
427*cdf0e10cSrcweir 		}
428*cdf0e10cSrcweir 	}
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir 	MsiCloseHandle(rhView);
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir 	OutputDebugStringFormat(L"DoRegEntries - ENDE\n" );
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir 	return true;
436*cdf0e10cSrcweir }
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir bool Reg64(MSIHANDLE& rhMSI, OPERATION op)
440*cdf0e10cSrcweir {
441*cdf0e10cSrcweir 	isInstall4AllUsers = IsInstallForAllUsers(rhMSI);
442*cdf0e10cSrcweir 	sBasisInstallLocation = GetBasisInstallLocation(rhMSI);
443*cdf0e10cSrcweir 
444*cdf0e10cSrcweir 	if (NULL == sBasisInstallLocation)
445*cdf0e10cSrcweir 	{
446*cdf0e10cSrcweir 		OutputDebugStringFormat(L"BASISINSTALLLOCATION is NULL\n" );
447*cdf0e10cSrcweir 		return false;
448*cdf0e10cSrcweir 	}
449*cdf0e10cSrcweir 
450*cdf0e10cSrcweir 	MSIHANDLE hView;
451*cdf0e10cSrcweir 	MSIHANDLE hDatabase = MsiGetActiveDatabase(rhMSI);
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir 	QueryReg64Table(hDatabase, hView);
454*cdf0e10cSrcweir 	OutputDebugStringFormat(L"Do something\n" );
455*cdf0e10cSrcweir 	DoRegEntries( rhMSI, op, hView);
456*cdf0e10cSrcweir 	OutputDebugStringFormat(L"Something done\n" );
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir 	MsiCloseHandle(hView);
459*cdf0e10cSrcweir 	MsiCloseHandle(hDatabase);
460*cdf0e10cSrcweir 	free(sBasisInstallLocation);
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir 	return true;
463*cdf0e10cSrcweir }
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir extern "C" UINT __stdcall InstallReg64(MSIHANDLE hMSI)
466*cdf0e10cSrcweir {
467*cdf0e10cSrcweir 	OutputDebugStringFormat(L"InstallReg64\n" );
468*cdf0e10cSrcweir 	Reg64(hMSI, SET);
469*cdf0e10cSrcweir 	return ERROR_SUCCESS;
470*cdf0e10cSrcweir }
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir extern "C" UINT __stdcall DeinstallReg64(MSIHANDLE hMSI)
473*cdf0e10cSrcweir {
474*cdf0e10cSrcweir 	OutputDebugStringFormat(L"DeinstallReg64\n" );
475*cdf0e10cSrcweir 	Reg64(hMSI, REMOVE);
476*cdf0e10cSrcweir 	return ERROR_SUCCESS;
477*cdf0e10cSrcweir }