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