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