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 assert(*ppActiveXPath
&& "Don't handle OOM conditions");
127 wcsncpy( *ppActiveXPath
, pProgPath
, nLen
);
128 wcsncpy( (*ppActiveXPath
) + nLen
, L
"program\\so_activex.dll", 22 );
129 (*ppActiveXPath
)[nLen
+22] = 0;
140 static bool GetDelta( MSIHANDLE hMSI
, int& nOldInstallMode
, int& nInstallMode
, int& nDeinstallMode
)
142 // for now the chart is always installed
143 nOldInstallMode
= CHART_COMPONENT
;
144 nInstallMode
= CHART_COMPONENT
;
147 INSTALLSTATE current_state
;
148 INSTALLSTATE future_state
;
150 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Wrt_Bin", ¤t_state
, &future_state
) )
152 // analyze writer installation mode
153 if ( current_state
== INSTALLSTATE_LOCAL
)
154 nOldInstallMode
|= WRITER_COMPONENT
;
156 if ( future_state
== INSTALLSTATE_LOCAL
157 || ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_UNKNOWN
) )
158 nInstallMode
|= WRITER_COMPONENT
;
159 else if ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_ABSENT
)
160 nDeinstallMode
|= WRITER_COMPONENT
;
167 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Calc_Bin", ¤t_state
, &future_state
) )
169 // analyze calc installation mode
170 if ( current_state
== INSTALLSTATE_LOCAL
)
171 nOldInstallMode
|= CALC_COMPONENT
;
173 if ( future_state
== INSTALLSTATE_LOCAL
174 || ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_UNKNOWN
) )
175 nInstallMode
|= CALC_COMPONENT
;
176 else if ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_ABSENT
)
177 nDeinstallMode
|= CALC_COMPONENT
;
184 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Draw_Bin", ¤t_state
, &future_state
) )
186 // analyze draw installation mode
187 if ( current_state
== INSTALLSTATE_LOCAL
)
188 nOldInstallMode
|= DRAW_COMPONENT
;
190 if ( future_state
== INSTALLSTATE_LOCAL
191 || ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_UNKNOWN
) )
192 nInstallMode
|= DRAW_COMPONENT
;
193 else if ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_ABSENT
)
194 nDeinstallMode
|= DRAW_COMPONENT
;
201 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Impress_Bin", ¤t_state
, &future_state
) )
203 // analyze impress installation mode
204 if ( current_state
== INSTALLSTATE_LOCAL
)
205 nOldInstallMode
|= IMPRESS_COMPONENT
;
207 if ( future_state
== INSTALLSTATE_LOCAL
208 || ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_UNKNOWN
) )
209 nInstallMode
|= IMPRESS_COMPONENT
;
210 else if ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_ABSENT
)
211 nDeinstallMode
|= IMPRESS_COMPONENT
;
218 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_p_Math_Bin", ¤t_state
, &future_state
) )
220 // analyze math installation mode
221 if ( current_state
== INSTALLSTATE_LOCAL
)
222 nOldInstallMode
|= MATH_COMPONENT
;
224 if ( future_state
== INSTALLSTATE_LOCAL
225 || ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_UNKNOWN
) )
226 nInstallMode
|= MATH_COMPONENT
;
227 else if ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_ABSENT
)
228 nDeinstallMode
|= MATH_COMPONENT
;
239 static bool MakeInstallForAllUsers( MSIHANDLE hMSI
)
241 bool bResult
= false;
242 wchar_t* pVal
= nullptr;
243 if ( GetMsiPropW( hMSI
, L
"ALLUSERS", &pVal
) && pVal
)
245 bResult
= UnicodeEquals( pVal
, L
"1" );
253 static bool MakeInstallFor64Bit( MSIHANDLE hMSI
)
255 bool bResult
= false;
256 wchar_t* pVal
= nullptr;
257 if ( GetMsiPropW( hMSI
, L
"VersionNT64", &pVal
) && pVal
)
266 extern "C" __declspec(dllexport
) UINT __stdcall
InstallActiveXControl( MSIHANDLE hMSI
)
268 INSTALLSTATE current_state
;
269 INSTALLSTATE future_state
;
271 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_o_Activexcontrol", ¤t_state
, &future_state
) )
273 int nOldInstallMode
= 0;
274 int nInstallMode
= 0;
275 int nDeinstallMode
= 0;
276 bool bInstallForAllUser
= MakeInstallForAllUsers( hMSI
);
277 bool bInstallFor64Bit
= MakeInstallFor64Bit( hMSI
);
279 wchar_t* pActiveXPath
= nullptr;
280 if ( GetActiveXControlPath( hMSI
, &pActiveXPath
) && pActiveXPath
281 && GetDelta( hMSI
, nOldInstallMode
, nInstallMode
, nDeinstallMode
) )
283 if ( future_state
== INSTALLSTATE_LOCAL
284 || ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_UNKNOWN
) )
286 // the control is installed in the new selected configuration
288 if ( current_state
== INSTALLSTATE_LOCAL
&& nDeinstallMode
)
289 UnregisterActiveXNative( pActiveXPath
, nDeinstallMode
, bInstallForAllUser
, bInstallFor64Bit
);
292 RegisterActiveXNative( pActiveXPath
, nInstallMode
, bInstallForAllUser
, bInstallFor64Bit
);
294 else if ( current_state
== INSTALLSTATE_LOCAL
&& future_state
== INSTALLSTATE_ABSENT
)
296 if ( nOldInstallMode
)
297 UnregisterActiveXNative( pActiveXPath
, nOldInstallMode
, bInstallForAllUser
, bInstallFor64Bit
);
302 free( pActiveXPath
);
309 return ERROR_SUCCESS
;
313 extern "C" __declspec(dllexport
) UINT __stdcall
DeinstallActiveXControl( MSIHANDLE hMSI
)
315 INSTALLSTATE current_state
;
316 INSTALLSTATE future_state
;
318 if ( ERROR_SUCCESS
== MsiGetFeatureStateW( hMSI
, L
"gm_o_Activexcontrol", ¤t_state
, &future_state
) )
320 wchar_t* pActiveXPath
= nullptr;
321 if ( current_state
== INSTALLSTATE_LOCAL
&& GetActiveXControlPath( hMSI
, &pActiveXPath
) && pActiveXPath
)
323 bool bInstallForAllUser
= MakeInstallForAllUsers( hMSI
);
324 bool bInstallFor64Bit
= MakeInstallFor64Bit( hMSI
);
327 UnregisterActiveXNative( pActiveXPath
,
338 free( pActiveXPath
);
342 return ERROR_SUCCESS
;
345 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */