xref: /trunk/main/setup_native/source/win32/customactions/regactivex/regactivex.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #define UNICODE
29 
30 #ifdef _MSC_VER
31 #pragma warning(push, 1) /* disable warnings within system headers */
32 #endif
33 #include <windows.h>
34 #include <msiquery.h>
35 #ifdef _MSC_VER
36 #pragma warning(pop)
37 #endif
38 
39 #include <string.h>
40 #include <malloc.h>
41 
42 #define CHART_COMPONENT 1
43 #define DRAW_COMPONENT 2
44 #define IMPRESS_COMPONENT 4
45 #define CALC_COMPONENT 8
46 #define WRITER_COMPONENT 16
47 #define MATH_COMPONENT 32
48 
49 // #define OWN_DEBUG_PRINT
50 
51 typedef int ( __stdcall * DllNativeRegProc ) ( int, BOOL, BOOL, const char* );
52 typedef int ( __stdcall * DllNativeUnregProc ) ( int, BOOL, BOOL );
53 
54 BOOL UnicodeEquals( wchar_t* pStr1, wchar_t* pStr2 )
55 {
56     if ( pStr1 == NULL && pStr2 == NULL )
57         return TRUE;
58     else if ( pStr1 == NULL || pStr2 == NULL )
59         return FALSE;
60 
61     while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
62         pStr1++, pStr2++;
63 
64     return ( *pStr1 == 0 && *pStr2 == 0 );
65 }
66 
67 //----------------------------------------------------------
68 char* UnicodeToAnsiString( wchar_t* pUniString )
69 {
70     int len = WideCharToMultiByte(
71         CP_ACP, 0, pUniString, -1, 0, 0, 0, 0 );
72 
73     char* buff = reinterpret_cast<char*>( malloc( len ) );
74 
75     WideCharToMultiByte(
76         CP_ACP, 0, pUniString, -1, buff, len, 0, 0 );
77 
78     return buff;
79 }
80 
81 #ifdef OWN_DEBUG_PRINT
82 void WarningMessageInt( wchar_t* pWarning, unsigned int nValue )
83 {
84     wchar_t pStr[5] = { nValue%10000/1000 + 48, nValue%1000/100 + 48, nValue%100/10 + 48, nValue%10 + 48, 0 };
85     MessageBox(NULL, pStr, pWarning, MB_OK | MB_ICONINFORMATION);
86 }
87 #endif
88 
89 //----------------------------------------------------------
90 void RegisterActiveXNative( const char* pActiveXPath, int nMode, BOOL InstallForAllUser, BOOL InstallFor64Bit )
91 {
92 #ifdef OWN_DEBUG_PRINT
93     MessageBoxW(NULL, L"RegisterActiveXNative", L"Information", MB_OK | MB_ICONINFORMATION);
94     MessageBoxA(NULL, pActiveXPath, "Library Path", MB_OK | MB_ICONINFORMATION);
95 #endif
96 
97     // For Win98/WinME the values should be written to the local machine
98     OSVERSIONINFO       aVerInfo;
99     aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
100     if ( GetVersionEx( &aVerInfo ) && aVerInfo.dwPlatformId != VER_PLATFORM_WIN32_NT )
101         InstallForAllUser = TRUE;
102 
103     HINSTANCE hModule = LoadLibraryExA( pActiveXPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
104     if( !( hModule <= ( HINSTANCE )HINSTANCE_ERROR ) )
105     {
106         DllNativeRegProc pNativeProc = ( DllNativeRegProc )GetProcAddress( hModule, "DllRegisterServerNative" );
107         if( pNativeProc!=NULL )
108         {
109 #ifdef OWN_DEBUG_PRINT
110             MessageBoxA(NULL, pActiveXPath, "Library Path", MB_OK | MB_ICONINFORMATION);
111 #endif
112             int nLen = strlen( pActiveXPath );
113             int nRemoveLen = strlen( "\\so_activex.dll" );
114             if ( nLen > nRemoveLen )
115             {
116                 char* pProgramPath = reinterpret_cast<char*>( malloc( nLen - nRemoveLen + 1 ) );
117                 strncpy( pProgramPath, pActiveXPath, nLen - nRemoveLen );
118                 pProgramPath[ nLen - nRemoveLen ] = 0;
119 
120                 ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit, pProgramPath );
121 
122                 free( pProgramPath );
123             }
124         }
125 
126         FreeLibrary( hModule );
127     }
128 }
129 
130 //----------------------------------------------------------
131 void UnregisterActiveXNative( const char* pActiveXPath, int nMode, BOOL InstallForAllUser, BOOL InstallFor64Bit )
132 {
133     // For Win98/WinME the values should be written to the local machine
134     OSVERSIONINFO       aVerInfo;
135     aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
136     if ( GetVersionEx( &aVerInfo ) && aVerInfo.dwPlatformId != VER_PLATFORM_WIN32_NT )
137         InstallForAllUser = TRUE;
138 
139     HINSTANCE hModule = LoadLibraryExA( pActiveXPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
140     if( !( hModule <= ( HINSTANCE )HINSTANCE_ERROR ) )
141     {
142         DllNativeUnregProc pNativeProc = ( DllNativeUnregProc )GetProcAddress( hModule, "DllUnregisterServerNative" );
143         if( pNativeProc!=NULL )
144             ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit );
145 
146         FreeLibrary( hModule );
147     }
148 }
149 
150 //----------------------------------------------------------
151 BOOL GetMsiProp( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
152 {
153     DWORD sz = 0;
154     if ( MsiGetProperty( hMSI, pPropName, L"", &sz ) == ERROR_MORE_DATA )
155     {
156         sz++;
157         DWORD nbytes = sz * sizeof( wchar_t );
158         wchar_t* buff = reinterpret_cast<wchar_t*>( malloc( nbytes ) );
159         ZeroMemory( buff, nbytes );
160         MsiGetProperty( hMSI, pPropName, buff, &sz );
161         *ppValue = buff;
162 
163         return TRUE;
164     }
165 
166     return FALSE;
167 }
168 
169 //----------------------------------------------------------
170 BOOL GetActiveXControlPath( MSIHANDLE hMSI, char** ppActiveXPath )
171 {
172     wchar_t* pProgPath = NULL;
173     if ( GetMsiProp( hMSI, L"INSTALLLOCATION", &pProgPath ) && pProgPath )
174     {
175         char* pCharProgPath = UnicodeToAnsiString( pProgPath );
176 #ifdef OWN_DEBUG_PRINT
177         MessageBox(NULL, pProgPath, L"Basis Installation Path", MB_OK | MB_ICONINFORMATION);
178         MessageBoxA(NULL, pCharProgPath, "Basis Installation Path( char )", MB_OK | MB_ICONINFORMATION);
179 #endif
180 
181         if ( pCharProgPath )
182         {
183             int nLen = strlen( pCharProgPath );
184             *ppActiveXPath = reinterpret_cast<char*>( malloc( nLen + 23 ) );
185             strncpy( *ppActiveXPath, pCharProgPath, nLen );
186             strncpy( (*ppActiveXPath) + nLen, "program\\so_activex.dll", 22 );
187             (*ppActiveXPath)[nLen+22] = 0;
188 
189             free( pCharProgPath );
190 
191             return TRUE;
192         }
193 
194         free( pProgPath );
195     }
196 
197     return FALSE;
198 }
199 
200 //----------------------------------------------------------
201 BOOL GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDeinstallMode )
202 {
203     // for now the chart is always installed
204     nOldInstallMode = CHART_COMPONENT;
205     nInstallMode = CHART_COMPONENT;
206     nDeinstallMode = 0;
207 
208     INSTALLSTATE current_state;
209     INSTALLSTATE future_state;
210 
211     if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Wrt_Bin", &current_state, &future_state ) )
212     {
213 #ifdef OWN_DEBUG_PRINT
214         WarningMessageInt( L"writer current_state = ", current_state );
215         WarningMessageInt( L"writer future_state = ", future_state );
216 #endif
217 
218         // analyze writer installation mode
219         if ( current_state == INSTALLSTATE_LOCAL )
220             nOldInstallMode |= WRITER_COMPONENT;
221 
222         if ( future_state == INSTALLSTATE_LOCAL
223           || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
224             nInstallMode |= WRITER_COMPONENT;
225         else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
226             nDeinstallMode |= WRITER_COMPONENT;
227     }
228     else
229     {
230         // assert( FALSE );
231     }
232 
233     if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Calc_Bin", &current_state, &future_state ) )
234     {
235 #ifdef OWN_DEBUG_PRINT
236         WarningMessageInt( L"calc current_state = ", current_state );
237         WarningMessageInt( L"calc future_state = ", future_state );
238 #endif
239 
240         // analyze calc installation mode
241         if ( current_state == INSTALLSTATE_LOCAL )
242             nOldInstallMode |= CALC_COMPONENT;
243 
244         if ( future_state == INSTALLSTATE_LOCAL
245           || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
246             nInstallMode |= CALC_COMPONENT;
247         else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
248             nDeinstallMode |= CALC_COMPONENT;
249     }
250     else
251     {
252         // assert( FALSE );
253     }
254 
255     if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Draw_Bin", &current_state, &future_state ) )
256     {
257         // analyze draw installation mode
258         if ( current_state == INSTALLSTATE_LOCAL )
259             nOldInstallMode |= DRAW_COMPONENT;
260 
261         if ( future_state == INSTALLSTATE_LOCAL
262           || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
263             nInstallMode |= DRAW_COMPONENT;
264         else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
265             nDeinstallMode |= DRAW_COMPONENT;
266     }
267     else
268     {
269         // assert( FALSE );
270     }
271 
272     if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Impress_Bin", &current_state, &future_state ) )
273     {
274         // analyze impress installation mode
275         if ( current_state == INSTALLSTATE_LOCAL )
276             nOldInstallMode |= IMPRESS_COMPONENT;
277 
278         if ( future_state == INSTALLSTATE_LOCAL
279           || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
280             nInstallMode |= IMPRESS_COMPONENT;
281         else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
282             nDeinstallMode |= IMPRESS_COMPONENT;
283     }
284     else
285     {
286         // assert( FALSE );
287     }
288 
289     if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Math_Bin", &current_state, &future_state ) )
290     {
291         // analyze math installation mode
292         if ( current_state == INSTALLSTATE_LOCAL )
293             nOldInstallMode |= MATH_COMPONENT;
294 
295         if ( future_state == INSTALLSTATE_LOCAL
296           || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
297             nInstallMode |= MATH_COMPONENT;
298         else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
299             nDeinstallMode |= MATH_COMPONENT;
300     }
301     else
302     {
303         // assert( FALSE );
304     }
305 
306     return TRUE;
307 }
308 
309 //----------------------------------------------------------
310 BOOL MakeInstallForAllUsers( MSIHANDLE hMSI )
311 {
312     BOOL bResult = FALSE;
313     wchar_t* pVal = NULL;
314     if ( GetMsiProp( hMSI, L"ALLUSERS", &pVal ) && pVal )
315     {
316         bResult = UnicodeEquals( pVal , L"1" );
317         free( pVal );
318     }
319 
320     return bResult;
321 }
322 
323 //----------------------------------------------------------
324 BOOL MakeInstallFor64Bit( MSIHANDLE hMSI )
325 {
326     BOOL bResult = FALSE;
327     wchar_t* pVal = NULL;
328     if ( GetMsiProp( hMSI, L"VersionNT64", &pVal ) && pVal )
329     {
330         bResult = TRUE;
331         free( pVal );
332     }
333 
334     return bResult;
335 }
336 //----------------------------------------------------------
337 extern "C" UINT __stdcall InstallActiveXControl( MSIHANDLE hMSI )
338 {
339     int nOldInstallMode = 0;
340     int nInstallMode = 0;
341     int nDeinstallMode = 0;
342 
343 #ifdef OWN_DEBUG_PRINT
344     MessageBox(NULL, L"InstallActiveXControl", L"Information", MB_OK | MB_ICONINFORMATION);
345 #endif
346 
347     INSTALLSTATE current_state;
348     INSTALLSTATE future_state;
349 
350     if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
351     {
352 #ifdef OWN_DEBUG_PRINT
353         MessageBox(NULL, L"InstallActiveXControl Step2", L"Information", MB_OK | MB_ICONINFORMATION);
354 #endif
355 
356         BOOL bInstallForAllUser = MakeInstallForAllUsers( hMSI );
357         BOOL bInstallFor64Bit = MakeInstallFor64Bit( hMSI );
358 
359         char* pActiveXPath = NULL;
360         if ( GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath
361         && GetDelta( hMSI, nOldInstallMode, nInstallMode, nDeinstallMode ) )
362         {
363 #ifdef OWN_DEBUG_PRINT
364             MessageBox(NULL, L"InstallActiveXControl Step3", L"Information", MB_OK | MB_ICONINFORMATION);
365 #endif
366 
367             if ( future_state == INSTALLSTATE_LOCAL
368               || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
369             {
370 #ifdef OWN_DEBUG_PRINT
371                 MessageBox(NULL, L"InstallActiveXControl, adjusting", L"Information", MB_OK | MB_ICONINFORMATION);
372                 WarningMessageInt( L"nInstallMode = ", nInstallMode );
373 #endif
374                 // the control is installed in the new selected configuration
375 
376                 if ( current_state == INSTALLSTATE_LOCAL && nDeinstallMode )
377                     UnregisterActiveXNative( pActiveXPath, nDeinstallMode, bInstallForAllUser, bInstallFor64Bit );
378 
379                 if ( nInstallMode )
380                     RegisterActiveXNative( pActiveXPath, nInstallMode, bInstallForAllUser, bInstallFor64Bit );
381             }
382             else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
383             {
384 #ifdef OWN_DEBUG_PRINT
385                 MessageBox(NULL, L"InstallActiveXControl, removing", L"Information", MB_OK | MB_ICONINFORMATION);
386 #endif
387                 if ( nOldInstallMode )
388                     UnregisterActiveXNative( pActiveXPath, nOldInstallMode, bInstallForAllUser, bInstallFor64Bit );
389             }
390         }
391 
392         if ( pActiveXPath )
393             free( pActiveXPath );
394     }
395     else
396     {
397         // assert( FALSE );
398     }
399 
400     return ERROR_SUCCESS;
401 }
402 
403 //----------------------------------------------------------
404 extern "C" UINT __stdcall DeinstallActiveXControl( MSIHANDLE hMSI )
405 {
406     INSTALLSTATE current_state;
407     INSTALLSTATE future_state;
408 
409 #ifdef OWN_DEBUG_PRINT
410     MessageBox(NULL, L"DeinstallActiveXControl", L"Information", MB_OK | MB_ICONINFORMATION);
411 #endif
412 
413     if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
414     {
415         char* pActiveXPath = NULL;
416         if ( current_state == INSTALLSTATE_LOCAL && GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath )
417         {
418             BOOL bInstallForAllUser = MakeInstallForAllUsers( hMSI );
419             BOOL bInstallFor64Bit = MakeInstallFor64Bit( hMSI );
420 
421             {
422                 UnregisterActiveXNative( pActiveXPath,
423                                         CHART_COMPONENT
424                                         | DRAW_COMPONENT
425                                         | IMPRESS_COMPONENT
426                                         | CALC_COMPONENT
427                                         | WRITER_COMPONENT
428                                         | MATH_COMPONENT,
429                                         bInstallForAllUser,
430                                         bInstallFor64Bit );
431             }
432 
433             free( pActiveXPath );
434         }
435     }
436 
437     return ERROR_SUCCESS;
438 }
439