LibreOffice Module setup_native (master) 1
regactivex.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#if !defined WIN32_LEAN_AND_MEAN
21# define WIN32_LEAN_AND_MEAN
22#endif
23#include <windows.h>
24#include <msiquery.h>
25
26#include <cassert>
27#include <string.h>
28#include <malloc.h>
29
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
36
37typedef int ( __stdcall * DllNativeRegProc ) ( int, BOOL, BOOL, const wchar_t* );
38typedef int ( __stdcall * DllNativeUnregProc ) ( int, BOOL, BOOL );
39
40static bool UnicodeEquals( wchar_t const * pStr1, wchar_t const * pStr2 )
41{
42 if ( pStr1 == nullptr && pStr2 == nullptr )
43 return true;
44 else if ( pStr1 == nullptr || pStr2 == nullptr )
45 return false;
46
47 while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
48 {
49 pStr1++;
50 pStr2++;
51 }
52
53 return ( *pStr1 == 0 && *pStr2 == 0 );
54}
55
56
57static void RegisterActiveXNative( const wchar_t* pActiveXPath, int nMode, bool InstallForAllUser, bool InstallFor64Bit )
58{
59 HINSTANCE hModule = LoadLibraryExW( pActiveXPath, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH );
60 if( hModule )
61 {
62 DllNativeRegProc pNativeProc = reinterpret_cast<DllNativeRegProc>(GetProcAddress( hModule, "DllRegisterServerNative" ));
63 if( pNativeProc!=nullptr )
64 {
65 int nLen = wcslen( pActiveXPath );
66 int nRemoveLen = strlen( "\\so_activex.dll" );
67 if ( nLen > nRemoveLen )
68 {
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;
73
74 ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit, pProgramPath );
75
76 free( pProgramPath );
77 }
78 }
79
80 FreeLibrary( hModule );
81 }
82}
83
84
85static void UnregisterActiveXNative( const wchar_t* pActiveXPath, int nMode, bool InstallForAllUser, bool InstallFor64Bit )
86{
87 HINSTANCE hModule = LoadLibraryExW( pActiveXPath, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH );
88 if( hModule )
89 {
90 DllNativeUnregProc pNativeProc = reinterpret_cast<DllNativeUnregProc>(GetProcAddress( hModule, "DllUnregisterServerNative" ));
91 if( pNativeProc!=nullptr )
92 ( *pNativeProc )( nMode, InstallForAllUser, InstallFor64Bit );
93
94 FreeLibrary( hModule );
95 }
96}
97
98
99static bool GetMsiPropW( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
100{
101 DWORD sz = 0;
102 if ( MsiGetPropertyW( hMSI, pPropName, const_cast<wchar_t *>(L""), &sz ) == ERROR_MORE_DATA )
103 {
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;
111
112 return true;
113 }
114
115 return false;
116}
117
118
119static bool GetActiveXControlPath( MSIHANDLE hMSI, wchar_t** ppActiveXPath )
120{
121 wchar_t* pProgPath = nullptr;
122 if ( GetMsiPropW( hMSI, L"INSTALLLOCATION", &pProgPath ) && pProgPath )
123 {
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;
129
130 free(pProgPath);
131
132 return true;
133 }
134
135 return false;
136}
137
138
139static bool GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDeinstallMode )
140{
141 // for now the chart is always installed
142 nOldInstallMode = CHART_COMPONENT;
143 nInstallMode = CHART_COMPONENT;
144 nDeinstallMode = 0;
145
146 INSTALLSTATE current_state;
147 INSTALLSTATE future_state;
148
149 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Wrt_Bin", &current_state, &future_state ) )
150 {
151 // analyze writer installation mode
152 if ( current_state == INSTALLSTATE_LOCAL )
153 nOldInstallMode |= WRITER_COMPONENT;
154
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;
160 }
161 else
162 {
163 // assert( FALSE );
164 }
165
166 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Calc_Bin", &current_state, &future_state ) )
167 {
168 // analyze calc installation mode
169 if ( current_state == INSTALLSTATE_LOCAL )
170 nOldInstallMode |= CALC_COMPONENT;
171
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;
177 }
178 else
179 {
180 // assert( FALSE );
181 }
182
183 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Draw_Bin", &current_state, &future_state ) )
184 {
185 // analyze draw installation mode
186 if ( current_state == INSTALLSTATE_LOCAL )
187 nOldInstallMode |= DRAW_COMPONENT;
188
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;
194 }
195 else
196 {
197 // assert( FALSE );
198 }
199
200 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Impress_Bin", &current_state, &future_state ) )
201 {
202 // analyze impress installation mode
203 if ( current_state == INSTALLSTATE_LOCAL )
204 nOldInstallMode |= IMPRESS_COMPONENT;
205
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;
211 }
212 else
213 {
214 // assert( FALSE );
215 }
216
217 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_p_Math_Bin", &current_state, &future_state ) )
218 {
219 // analyze math installation mode
220 if ( current_state == INSTALLSTATE_LOCAL )
221 nOldInstallMode |= MATH_COMPONENT;
222
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;
228 }
229 else
230 {
231 // assert( FALSE );
232 }
233
234 return true;
235}
236
237
238static bool MakeInstallForAllUsers( MSIHANDLE hMSI )
239{
240 bool bResult = false;
241 wchar_t* pVal = nullptr;
242 if ( GetMsiPropW( hMSI, L"ALLUSERS", &pVal ) && pVal )
243 {
244 bResult = UnicodeEquals( pVal , L"1" );
245 free( pVal );
246 }
247
248 return bResult;
249}
250
251
252static bool MakeInstallFor64Bit( MSIHANDLE hMSI )
253{
254 bool bResult = false;
255 wchar_t* pVal = nullptr;
256 if ( GetMsiPropW( hMSI, L"VersionNT64", &pVal ) && pVal )
257 {
258 bResult = true;
259 free( pVal );
260 }
261
262 return bResult;
263}
264
265extern "C" __declspec(dllexport) UINT __stdcall InstallActiveXControl( MSIHANDLE hMSI )
266{
267 INSTALLSTATE current_state;
268 INSTALLSTATE future_state;
269
270 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
271 {
272 int nOldInstallMode = 0;
273 int nInstallMode = 0;
274 int nDeinstallMode = 0;
275 bool bInstallForAllUser = MakeInstallForAllUsers( hMSI );
276 bool bInstallFor64Bit = MakeInstallFor64Bit( hMSI );
277
278 wchar_t* pActiveXPath = nullptr;
279 if ( GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath
280 && GetDelta( hMSI, nOldInstallMode, nInstallMode, nDeinstallMode ) )
281 {
282 if ( future_state == INSTALLSTATE_LOCAL
283 || ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_UNKNOWN ) )
284 {
285 // the control is installed in the new selected configuration
286
287 if ( current_state == INSTALLSTATE_LOCAL && nDeinstallMode )
288 UnregisterActiveXNative( pActiveXPath, nDeinstallMode, bInstallForAllUser, bInstallFor64Bit );
289
290 if ( nInstallMode )
291 RegisterActiveXNative( pActiveXPath, nInstallMode, bInstallForAllUser, bInstallFor64Bit );
292 }
293 else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
294 {
295 if ( nOldInstallMode )
296 UnregisterActiveXNative( pActiveXPath, nOldInstallMode, bInstallForAllUser, bInstallFor64Bit );
297 }
298 }
299
300 if ( pActiveXPath )
301 free( pActiveXPath );
302 }
303 else
304 {
305 // assert( FALSE );
306 }
307
308 return ERROR_SUCCESS;
309}
310
311
312extern "C" __declspec(dllexport) UINT __stdcall DeinstallActiveXControl( MSIHANDLE hMSI )
313{
314 INSTALLSTATE current_state;
315 INSTALLSTATE future_state;
316
317 if ( ERROR_SUCCESS == MsiGetFeatureStateW( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
318 {
319 wchar_t* pActiveXPath = nullptr;
320 if ( current_state == INSTALLSTATE_LOCAL && GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath )
321 {
322 bool bInstallForAllUser = MakeInstallForAllUsers( hMSI );
323 bool bInstallFor64Bit = MakeInstallFor64Bit( hMSI );
324
325 {
326 UnregisterActiveXNative( pActiveXPath,
333 bInstallForAllUser,
334 bInstallFor64Bit );
335 }
336
337 free( pActiveXPath );
338 }
339 }
340
341 return ERROR_SUCCESS;
342}
343
344/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool GetDelta(MSIHANDLE hMSI, int &nOldInstallMode, int &nInstallMode, int &nDeinstallMode)
Definition: regactivex.cxx:139
const wchar_t *typedef BOOL
Definition: regactivex.cxx:38
static bool MakeInstallForAllUsers(MSIHANDLE hMSI)
Definition: regactivex.cxx:238
static bool GetActiveXControlPath(MSIHANDLE hMSI, wchar_t **ppActiveXPath)
Definition: regactivex.cxx:119
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
Definition: regactivex.cxx:38
static bool MakeInstallFor64Bit(MSIHANDLE hMSI)
Definition: regactivex.cxx:252
#define CHART_COMPONENT
Definition: regactivex.cxx:30
static bool UnicodeEquals(wchar_t const *pStr1, wchar_t const *pStr2)
Definition: regactivex.cxx:40
static void UnregisterActiveXNative(const wchar_t *pActiveXPath, int nMode, bool InstallForAllUser, bool InstallFor64Bit)
Definition: regactivex.cxx:85
static bool GetMsiPropW(MSIHANDLE hMSI, const wchar_t *pPropName, wchar_t **ppValue)
Definition: regactivex.cxx:99
static void RegisterActiveXNative(const wchar_t *pActiveXPath, int nMode, bool InstallForAllUser, bool InstallFor64Bit)
Definition: regactivex.cxx:57
#define CALC_COMPONENT
Definition: regactivex.cxx:33
__declspec(dllexport) UINT __stdcall InstallActiveXControl(MSIHANDLE hMSI)
Definition: regactivex.cxx:265
#define WRITER_COMPONENT
Definition: regactivex.cxx:34
#define DRAW_COMPONENT
Definition: regactivex.cxx:31
#define MATH_COMPONENT
Definition: regactivex.cxx:35
#define IMPRESS_COMPONENT
Definition: regactivex.cxx:32
EXTERN_C BOOL BOOL const wchar_t * pProgramPath