nss: upgrade to release 3.73
[LibreOffice.git] / setup_native / source / win32 / customactions / regactivex / regactivex.cxx
blob48b11bd4f4525cff9cf87d6eb389db42d6adda2f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #if !defined WIN32_LEAN_AND_MEAN
21 # define WIN32_LEAN_AND_MEAN
22 #endif
23 #include <windows.h>
24 #include <msiquery.h>
26 #include <cassert>
27 #include <string.h>
28 #include <malloc.h>
30 #define CHART_COMPONENT 1
31 #define DRAW_COMPONENT 2
32 #define IMPRESS_COMPONENT 4
33 #define CALC_COMPONENT 8
34 #define WRITER_COMPONENT 16
35 #define MATH_COMPONENT 32
37 typedef int ( __stdcall * DllNativeRegProc ) ( int, BOOL, BOOL, const wchar_t* );
38 typedef int ( __stdcall * DllNativeUnregProc ) ( int, BOOL, BOOL );
40 static bool UnicodeEquals( wchar_t const * pStr1, wchar_t const * pStr2 )
42 if ( pStr1 == nullptr && pStr2 == nullptr )
43 return true;
44 else if ( pStr1 == nullptr || pStr2 == nullptr )
45 return false;
47 while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
49 pStr1++;
50 pStr2++;
53 return ( *pStr1 == 0 && *pStr2 == 0 );
57 static void RegisterActiveXNative( const wchar_t* pActiveXPath, int nMode, bool InstallForAllUser, bool InstallFor64Bit )
59 HINSTANCE hModule = LoadLibraryExW( pActiveXPath, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH );
60 if( hModule )
62 DllNativeRegProc pNativeProc = reinterpret_cast<DllNativeRegProc>(GetProcAddress( hModule, "DllRegisterServerNative" ));
63 if( pNativeProc!=nullptr )
65 int nLen = wcslen( pActiveXPath );
66 int nRemoveLen = strlen( "\\so_activex.dll" );
67 if ( nLen > nRemoveLen )
69 wchar_t* pProgramPath = static_cast<wchar_t*>( malloc( (nLen - nRemoveLen + 1) * sizeof(wchar_t) ) );
70 assert(pProgramPath); // Don't handle OOM conditions
71 wcsncpy( pProgramPath, pActiveXPath, nLen - nRemoveLen );
72 pProgramPath[ nLen - nRemoveLen ] = 0;
74 ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit, pProgramPath );
76 free( pProgramPath );
80 FreeLibrary( hModule );
85 static void UnregisterActiveXNative( const wchar_t* pActiveXPath, int nMode, bool InstallForAllUser, bool InstallFor64Bit )
87 HINSTANCE hModule = LoadLibraryExW( pActiveXPath, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH );
88 if( hModule )
90 DllNativeUnregProc pNativeProc = reinterpret_cast<DllNativeUnregProc>(GetProcAddress( hModule, "DllUnregisterServerNative" ));
91 if( pNativeProc!=nullptr )
92 ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit );
94 FreeLibrary( hModule );
99 static bool GetMsiPropW( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
101 DWORD sz = 0;
102 if ( MsiGetPropertyW( hMSI, pPropName, const_cast<wchar_t *>(L""), &sz ) == ERROR_MORE_DATA )
104 sz++;
105 DWORD nbytes = sz * sizeof( wchar_t );
106 wchar_t* buff = static_cast<wchar_t*>( malloc( nbytes ) );
107 assert(buff); // Don't handle OOM conditions
108 ZeroMemory( buff, nbytes );
109 MsiGetPropertyW( hMSI, pPropName, buff, &sz );
110 *ppValue = buff;
112 return true;
115 return false;
119 static bool GetActiveXControlPath( MSIHANDLE hMSI, wchar_t** ppActiveXPath )
121 wchar_t* pProgPath = nullptr;
122 if ( GetMsiPropW( hMSI, L"INSTALLLOCATION", &pProgPath ) && pProgPath )
124 int nLen = wcslen( pProgPath );
125 *ppActiveXPath = static_cast<wchar_t*>( malloc( (nLen + 23) * sizeof(wchar_t) ) );
126 wcsncpy( *ppActiveXPath, pProgPath, nLen );
127 wcsncpy( (*ppActiveXPath) + nLen, L"program\\so_activex.dll", 22 );
128 (*ppActiveXPath)[nLen+22] = 0;
130 free(pProgPath);
132 return true;
135 return false;
139 static bool GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDeinstallMode )
141 // for now the chart is always installed
142 nOldInstallMode = CHART_COMPONENT;
143 nInstallMode = CHART_COMPONENT;
144 nDeinstallMode = 0;
146 INSTALLSTATE current_state;
147 INSTALLSTATE future_state;
149 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Wrt_Bin", &current_state, &future_state ) )
151 // analyze writer installation mode
152 if ( current_state == INSTALLSTATE_LOCAL )
153 nOldInstallMode |= WRITER_COMPONENT;
155 if ( future_state == INSTALLSTATE_LOCAL
156 || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
157 nInstallMode |= WRITER_COMPONENT;
158 else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
159 nDeinstallMode |= WRITER_COMPONENT;
161 else
163 // assert( FALSE );
166 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Calc_Bin", &current_state, &future_state ) )
168 // analyze calc installation mode
169 if ( current_state == INSTALLSTATE_LOCAL )
170 nOldInstallMode |= CALC_COMPONENT;
172 if ( future_state == INSTALLSTATE_LOCAL
173 || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
174 nInstallMode |= CALC_COMPONENT;
175 else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
176 nDeinstallMode |= CALC_COMPONENT;
178 else
180 // assert( FALSE );
183 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Draw_Bin", &current_state, &future_state ) )
185 // analyze draw installation mode
186 if ( current_state == INSTALLSTATE_LOCAL )
187 nOldInstallMode |= DRAW_COMPONENT;
189 if ( future_state == INSTALLSTATE_LOCAL
190 || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
191 nInstallMode |= DRAW_COMPONENT;
192 else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
193 nDeinstallMode |= DRAW_COMPONENT;
195 else
197 // assert( FALSE );
200 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Impress_Bin", &current_state, &future_state ) )
202 // analyze impress installation mode
203 if ( current_state == INSTALLSTATE_LOCAL )
204 nOldInstallMode |= IMPRESS_COMPONENT;
206 if ( future_state == INSTALLSTATE_LOCAL
207 || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
208 nInstallMode |= IMPRESS_COMPONENT;
209 else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
210 nDeinstallMode |= IMPRESS_COMPONENT;
212 else
214 // assert( FALSE );
217 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Math_Bin", &current_state, &future_state ) )
219 // analyze math installation mode
220 if ( current_state == INSTALLSTATE_LOCAL )
221 nOldInstallMode |= MATH_COMPONENT;
223 if ( future_state == INSTALLSTATE_LOCAL
224 || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
225 nInstallMode |= MATH_COMPONENT;
226 else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
227 nDeinstallMode |= MATH_COMPONENT;
229 else
231 // assert( FALSE );
234 return true;
238 static bool MakeInstallForAllUsers( MSIHANDLE hMSI )
240 bool bResult = false;
241 wchar_t* pVal = nullptr;
242 if ( GetMsiPropW( hMSI, L"ALLUSERS", &pVal ) && pVal )
244 bResult = UnicodeEquals( pVal , L"1" );
245 free( pVal );
248 return bResult;
252 static bool MakeInstallFor64Bit( MSIHANDLE hMSI )
254 bool bResult = false;
255 wchar_t* pVal = nullptr;
256 if ( GetMsiPropW( hMSI, L"VersionNT64", &pVal ) && pVal )
258 bResult = true;
259 free( pVal );
262 return bResult;
265 extern "C" __declspec(dllexport) UINT __stdcall InstallActiveXControl( MSIHANDLE hMSI )
267 INSTALLSTATE current_state;
268 INSTALLSTATE future_state;
270 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
272 int nOldInstallMode = 0;
273 int nInstallMode = 0;
274 int nDeinstallMode = 0;
275 bool bInstallForAllUser = MakeInstallForAllUsers( hMSI );
276 bool bInstallFor64Bit = MakeInstallFor64Bit( hMSI );
278 wchar_t* pActiveXPath = nullptr;
279 if ( GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath
280 && GetDelta( hMSI, nOldInstallMode, nInstallMode, nDeinstallMode ) )
282 if ( future_state == INSTALLSTATE_LOCAL
283 || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
285 // the control is installed in the new selected configuration
287 if ( current_state == INSTALLSTATE_LOCAL && nDeinstallMode )
288 UnregisterActiveXNative( pActiveXPath, nDeinstallMode, bInstallForAllUser, bInstallFor64Bit );
290 if ( nInstallMode )
291 RegisterActiveXNative( pActiveXPath, nInstallMode, bInstallForAllUser, bInstallFor64Bit );
293 else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
295 if ( nOldInstallMode )
296 UnregisterActiveXNative( pActiveXPath, nOldInstallMode, bInstallForAllUser, bInstallFor64Bit );
300 if ( pActiveXPath )
301 free( pActiveXPath );
303 else
305 // assert( FALSE );
308 return ERROR_SUCCESS;
312 extern "C" __declspec(dllexport) UINT __stdcall DeinstallActiveXControl( MSIHANDLE hMSI )
314 INSTALLSTATE current_state;
315 INSTALLSTATE future_state;
317 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
319 wchar_t* pActiveXPath = nullptr;
320 if ( current_state == INSTALLSTATE_LOCAL && GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath )
322 bool bInstallForAllUser = MakeInstallForAllUsers( hMSI );
323 bool bInstallFor64Bit = MakeInstallFor64Bit( hMSI );
326 UnregisterActiveXNative( pActiveXPath,
327 CHART_COMPONENT
328 | DRAW_COMPONENT
329 | IMPRESS_COMPONENT
330 | CALC_COMPONENT
331 | WRITER_COMPONENT
332 | MATH_COMPONENT,
333 bInstallForAllUser,
334 bInstallFor64Bit );
337 free( pActiveXPath );
341 return ERROR_SUCCESS;
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */