1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
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 )
44 else if ( pStr1
== nullptr || pStr2
== nullptr )
47 while( *pStr1
== *pStr2
&& *pStr1
&& *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
);
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
);
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
);
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
)
102 if ( MsiGetPropertyW( hMSI
, pPropName
, const_cast<wchar_t *>(L
""), &sz
) == ERROR_MORE_DATA
)
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
);
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;
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
;
146 INSTALLSTATE current_state
;
147 INSTALLSTATE future_state
;
149 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Wrt_Bin", ¤t_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
;
166 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Calc_Bin", ¤t_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
;
183 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Draw_Bin", ¤t_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
;
200 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Impress_Bin", ¤t_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
;
217 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Math_Bin", ¤t_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
;
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" );
252 static bool MakeInstallFor64Bit( MSIHANDLE hMSI
)
254 bool bResult
= false;
255 wchar_t* pVal
= nullptr;
256 if ( GetMsiPropW( hMSI
, L
"VersionNT64", &pVal
) && pVal
)
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", ¤t_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
);
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
);
301 free( pActiveXPath
);
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", ¤t_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
,
337 free( pActiveXPath
);
341 return ERROR_SUCCESS
;
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */