1*9d7e27acSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9d7e27acSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9d7e27acSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9d7e27acSAndrew Rist * distributed with this work for additional information 6*9d7e27acSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9d7e27acSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9d7e27acSAndrew Rist * "License"); you may not use this file except in compliance 9*9d7e27acSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*9d7e27acSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*9d7e27acSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9d7e27acSAndrew Rist * software distributed under the License is distributed on an 15*9d7e27acSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9d7e27acSAndrew Rist * KIND, either express or implied. See the License for the 17*9d7e27acSAndrew Rist * specific language governing permissions and limitations 18*9d7e27acSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*9d7e27acSAndrew Rist *************************************************************/ 21*9d7e27acSAndrew Rist 22*9d7e27acSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_cppuhelper.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "osl/diagnose.h" 28cdf0e10cSrcweir #include "osl/file.hxx" 29cdf0e10cSrcweir #include "osl/mutex.hxx" 30cdf0e10cSrcweir #include "osl/module.hxx" 31cdf0e10cSrcweir #include "rtl/unload.h" 32cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 33cdf0e10cSrcweir #include "uno/environment.h" 34cdf0e10cSrcweir #include "uno/mapping.hxx" 35cdf0e10cSrcweir #include "cppuhelper/factory.hxx" 36cdf0e10cSrcweir #include "cppuhelper/shlib.hxx" 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include "com/sun/star/beans/XPropertySet.hpp" 39cdf0e10cSrcweir 40cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 41cdf0e10cSrcweir #include <stdio.h> 42cdf0e10cSrcweir #endif 43cdf0e10cSrcweir #include <vector> 44cdf0e10cSrcweir 45cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 46cdf0e10cSrcweir 47cdf0e10cSrcweir 48cdf0e10cSrcweir using namespace ::rtl; 49cdf0e10cSrcweir using namespace ::osl; 50cdf0e10cSrcweir using namespace ::com::sun::star; 51cdf0e10cSrcweir using namespace ::com::sun::star::uno; 52cdf0e10cSrcweir 53cdf0e10cSrcweir namespace cppu 54cdf0e10cSrcweir { 55cdf0e10cSrcweir 56cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 57cdf0e10cSrcweir //------------------------------------------------------------------------------ 58cdf0e10cSrcweir static inline void out( const char * p ) SAL_THROW( () ) 59cdf0e10cSrcweir { 60cdf0e10cSrcweir printf( p ); 61cdf0e10cSrcweir } 62cdf0e10cSrcweir static inline void out( const OUString & r ) throw () 63cdf0e10cSrcweir { 64cdf0e10cSrcweir OString s( OUStringToOString( r, RTL_TEXTENCODING_ASCII_US ) ); 65cdf0e10cSrcweir out( s.getStr() ); 66cdf0e10cSrcweir } 67cdf0e10cSrcweir #endif 68cdf0e10cSrcweir 69cdf0e10cSrcweir //------------------------------------------------------------------------------ 70cdf0e10cSrcweir static const ::std::vector< OUString > * getAccessDPath() SAL_THROW( () ) 71cdf0e10cSrcweir { 72cdf0e10cSrcweir static ::std::vector< OUString > * s_p = 0; 73cdf0e10cSrcweir static bool s_bInit = false; 74cdf0e10cSrcweir 75cdf0e10cSrcweir if (! s_bInit) 76cdf0e10cSrcweir { 77cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 78cdf0e10cSrcweir if (! s_bInit) 79cdf0e10cSrcweir { 80cdf0e10cSrcweir const char * pEnv = ::getenv( "CPLD_ACCESSPATH" ); 81cdf0e10cSrcweir if (pEnv) 82cdf0e10cSrcweir { 83cdf0e10cSrcweir static ::std::vector< OUString > s_v; 84cdf0e10cSrcweir 85cdf0e10cSrcweir OString aEnv( pEnv ); 86cdf0e10cSrcweir sal_Int32 nIndex = 0; 87cdf0e10cSrcweir do 88cdf0e10cSrcweir { 89cdf0e10cSrcweir OUString aStr( OStringToOUString( 90cdf0e10cSrcweir aEnv.getToken( 0, ';', nIndex ), 91cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US ) ); 92cdf0e10cSrcweir OUString aFileUrl; 93cdf0e10cSrcweir if (FileBase::getFileURLFromSystemPath(aStr, aFileUrl) 94cdf0e10cSrcweir != FileBase::E_None) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir OSL_ASSERT(false); 97cdf0e10cSrcweir } 98cdf0e10cSrcweir s_v.push_back( aFileUrl ); 99cdf0e10cSrcweir } while( nIndex != -1 ); 100cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 101cdf0e10cSrcweir out( "> cpld: acknowledged following access path(s): \"" ); 102cdf0e10cSrcweir ::std::vector< OUString >::const_iterator iPos( s_v.begin() ); 103cdf0e10cSrcweir while (iPos != s_v.end()) 104cdf0e10cSrcweir { 105cdf0e10cSrcweir out( *iPos ); 106cdf0e10cSrcweir ++iPos; 107cdf0e10cSrcweir if (iPos != s_v.end()) 108cdf0e10cSrcweir out( ";" ); 109cdf0e10cSrcweir } 110cdf0e10cSrcweir out( "\"\n" ); 111cdf0e10cSrcweir #endif 112cdf0e10cSrcweir s_p = & s_v; 113cdf0e10cSrcweir } 114cdf0e10cSrcweir else 115cdf0e10cSrcweir { 116cdf0e10cSrcweir // no access path env set 117cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 118cdf0e10cSrcweir out( "=> no CPLD_ACCESSPATH set.\n" ); 119cdf0e10cSrcweir #endif 120cdf0e10cSrcweir } 121cdf0e10cSrcweir s_bInit = true; 122cdf0e10cSrcweir } 123cdf0e10cSrcweir } 124cdf0e10cSrcweir 125cdf0e10cSrcweir return s_p; 126cdf0e10cSrcweir } 127cdf0e10cSrcweir 128cdf0e10cSrcweir //------------------------------------------------------------------------------ 129cdf0e10cSrcweir static bool checkAccessPath( OUString * pComp ) throw () 130cdf0e10cSrcweir { 131cdf0e10cSrcweir const ::std::vector< OUString > * pPath = getAccessDPath(); 132cdf0e10cSrcweir 133cdf0e10cSrcweir if (pPath) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir sal_Bool bAbsolute = (pComp->compareToAscii( "file://" , 7 ) == 0); 136cdf0e10cSrcweir for ( ::std::vector< OUString >::const_iterator iPos( pPath->begin() ); 137cdf0e10cSrcweir iPos != pPath->end(); ++iPos ) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir OUString aBaseDir( *iPos ); 140cdf0e10cSrcweir OUString aAbs; 141cdf0e10cSrcweir 142cdf0e10cSrcweir if ( bAbsolute ) 143cdf0e10cSrcweir { 144cdf0e10cSrcweir aAbs = *pComp; 145cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 146cdf0e10cSrcweir out( "> taking path: \"" ); 147cdf0e10cSrcweir out( aAbs ); 148cdf0e10cSrcweir #endif 149cdf0e10cSrcweir } 150cdf0e10cSrcweir else 151cdf0e10cSrcweir { 152cdf0e10cSrcweir if (osl_File_E_None != 153cdf0e10cSrcweir ::osl_getAbsoluteFileURL( 154cdf0e10cSrcweir aBaseDir.pData, pComp->pData, &aAbs.pData )) 155cdf0e10cSrcweir { 156cdf0e10cSrcweir continue; 157cdf0e10cSrcweir } 158cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 159cdf0e10cSrcweir out( "> found path: \"" ); 160cdf0e10cSrcweir out( aBaseDir ); 161cdf0e10cSrcweir out( "\" + \"" ); 162cdf0e10cSrcweir out( *pComp ); 163cdf0e10cSrcweir out( "\" => \"" ); 164cdf0e10cSrcweir out( aAbs ); 165cdf0e10cSrcweir #endif 166cdf0e10cSrcweir } 167cdf0e10cSrcweir 168cdf0e10cSrcweir if (0 == aAbs.indexOf( aBaseDir ) && // still part of it? 169cdf0e10cSrcweir aBaseDir.getLength() < aAbs.getLength() && 170cdf0e10cSrcweir (aBaseDir[ aBaseDir.getLength() -1 ] == (sal_Unicode)'/' || 171cdf0e10cSrcweir // dir boundary 172cdf0e10cSrcweir aAbs[ aBaseDir.getLength() ] == (sal_Unicode)'/')) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 175cdf0e10cSrcweir out( ": ok.\n" ); 176cdf0e10cSrcweir #endif 177cdf0e10cSrcweir // load from absolute path 178cdf0e10cSrcweir *pComp = aAbs; 179cdf0e10cSrcweir return true; 180cdf0e10cSrcweir } 181cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 182cdf0e10cSrcweir else 183cdf0e10cSrcweir { 184cdf0e10cSrcweir out( "\" ...does not match given path \"" ); 185cdf0e10cSrcweir out( aBaseDir ); 186cdf0e10cSrcweir out( "\".\n" ); 187cdf0e10cSrcweir } 188cdf0e10cSrcweir #endif 189cdf0e10cSrcweir } 190cdf0e10cSrcweir return false; 191cdf0e10cSrcweir } 192cdf0e10cSrcweir else 193cdf0e10cSrcweir { 194cdf0e10cSrcweir // no access path env set 195cdf0e10cSrcweir return true; 196cdf0e10cSrcweir } 197cdf0e10cSrcweir } 198cdf0e10cSrcweir 199cdf0e10cSrcweir //------------------------------------------------------------------------------ 200cdf0e10cSrcweir static inline sal_Int32 endsWith( 201cdf0e10cSrcweir const OUString & rText, const OUString & rEnd ) SAL_THROW( () ) 202cdf0e10cSrcweir { 203cdf0e10cSrcweir if (rText.getLength() >= rEnd.getLength() && 204cdf0e10cSrcweir rEnd.equalsIgnoreAsciiCase( 205cdf0e10cSrcweir rText.copy( rText.getLength() - rEnd.getLength() ) )) 206cdf0e10cSrcweir { 207cdf0e10cSrcweir return rText.getLength() - rEnd.getLength(); 208cdf0e10cSrcweir } 209cdf0e10cSrcweir return -1; 210cdf0e10cSrcweir } 211cdf0e10cSrcweir 212cdf0e10cSrcweir //------------------------------------------------------------------------------ 213cdf0e10cSrcweir static OUString makeComponentPath( 214cdf0e10cSrcweir const OUString & rLibName, const OUString & rPath ) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 217cdf0e10cSrcweir // No system path allowed here ! 218cdf0e10cSrcweir { 219cdf0e10cSrcweir OUString aComp; 220cdf0e10cSrcweir OSL_ASSERT( FileBase::E_None == 221cdf0e10cSrcweir FileBase::getSystemPathFromFileURL( rLibName, aComp ) ); 222cdf0e10cSrcweir OSL_ASSERT( 223cdf0e10cSrcweir ! rPath.getLength() || 224cdf0e10cSrcweir FileBase::E_None == 225cdf0e10cSrcweir FileBase::getSystemPathFromFileURL( rPath, aComp ) ); 226cdf0e10cSrcweir } 227cdf0e10cSrcweir #endif 228cdf0e10cSrcweir 229cdf0e10cSrcweir OUStringBuffer buf( rPath.getLength() + rLibName.getLength() + 12 ); 230cdf0e10cSrcweir 231cdf0e10cSrcweir if (0 != rPath.getLength()) 232cdf0e10cSrcweir { 233cdf0e10cSrcweir buf.append( rPath ); 234cdf0e10cSrcweir if (rPath[ rPath.getLength() -1 ] != '/') 235cdf0e10cSrcweir buf.append( (sal_Unicode) '/' ); 236cdf0e10cSrcweir } 237cdf0e10cSrcweir sal_Int32 nEnd = endsWith( rLibName, OUSTR(SAL_DLLEXTENSION) ); 238cdf0e10cSrcweir if (nEnd < 0) // !endsWith 239cdf0e10cSrcweir { 240cdf0e10cSrcweir #ifndef OS2 241cdf0e10cSrcweir //this is always triggered with .uno components 242cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL >= 2) 243cdf0e10cSrcweir OSL_ENSURE( 244cdf0e10cSrcweir !"### library name has no proper extension!", 245cdf0e10cSrcweir OUStringToOString( rLibName, RTL_TEXTENCODING_ASCII_US ).getStr() ); 246cdf0e10cSrcweir #endif 247cdf0e10cSrcweir #endif // OS2 248cdf0e10cSrcweir 249cdf0e10cSrcweir #if defined SAL_DLLPREFIX 250cdf0e10cSrcweir nEnd = endsWith( rLibName, OUSTR(".uno") ); 251cdf0e10cSrcweir if (nEnd < 0) // !endsWith 252cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(SAL_DLLPREFIX) ); 253cdf0e10cSrcweir #endif 254cdf0e10cSrcweir buf.append( rLibName ); 255cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION) ); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir else // name is completely pre/postfixed 258cdf0e10cSrcweir { 259cdf0e10cSrcweir buf.append( rLibName ); 260cdf0e10cSrcweir } 261cdf0e10cSrcweir 262cdf0e10cSrcweir OUString out( buf.makeStringAndClear() ); 263cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 264cdf0e10cSrcweir OString str( OUStringToOString( out, RTL_TEXTENCODING_ASCII_US ) ); 265cdf0e10cSrcweir OSL_TRACE( "component path=%s\n", str.getStr() ); 266cdf0e10cSrcweir #endif 267cdf0e10cSrcweir 268cdf0e10cSrcweir return out; 269cdf0e10cSrcweir } 270cdf0e10cSrcweir 271cdf0e10cSrcweir //============================================================================== 272cdf0e10cSrcweir static OUString getLibEnv(OUString const & aModulePath, 273cdf0e10cSrcweir oslModule lib, 274cdf0e10cSrcweir uno::Environment * pEnv, 275cdf0e10cSrcweir OUString * pSourceEnv_name, 276cdf0e10cSrcweir uno::Environment const & cTargetEnv, 277cdf0e10cSrcweir OUString const & cImplName = OUString()) 278cdf0e10cSrcweir { 279cdf0e10cSrcweir OUString aExcMsg; 280cdf0e10cSrcweir 281cdf0e10cSrcweir sal_Char const * pEnvTypeName = NULL; 282cdf0e10cSrcweir 283cdf0e10cSrcweir OUString aGetEnvNameExt = OUSTR(COMPONENT_GETENVEXT); 284cdf0e10cSrcweir component_getImplementationEnvironmentExtFunc pGetImplEnvExt = 285cdf0e10cSrcweir (component_getImplementationEnvironmentExtFunc)osl_getFunctionSymbol(lib, aGetEnvNameExt.pData); 286cdf0e10cSrcweir 287cdf0e10cSrcweir if (pGetImplEnvExt) 288cdf0e10cSrcweir { 289cdf0e10cSrcweir OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US)); 290cdf0e10cSrcweir pGetImplEnvExt(&pEnvTypeName, (uno_Environment **)pEnv, implName.getStr(), cTargetEnv.get()); 291cdf0e10cSrcweir } 292cdf0e10cSrcweir else 293cdf0e10cSrcweir { 294cdf0e10cSrcweir OUString aGetEnvName = OUSTR(COMPONENT_GETENV); 295cdf0e10cSrcweir component_getImplementationEnvironmentFunc pGetImplEnv = 296cdf0e10cSrcweir (component_getImplementationEnvironmentFunc)osl_getFunctionSymbol( 297cdf0e10cSrcweir lib, aGetEnvName.pData ); 298cdf0e10cSrcweir if (pGetImplEnv) 299cdf0e10cSrcweir pGetImplEnv(&pEnvTypeName, (uno_Environment **)pEnv); 300cdf0e10cSrcweir 301cdf0e10cSrcweir else 302cdf0e10cSrcweir { 303cdf0e10cSrcweir aExcMsg = aModulePath; 304cdf0e10cSrcweir aExcMsg += OUSTR(": cannot get symbol: "); 305cdf0e10cSrcweir aExcMsg += aGetEnvName; 306cdf0e10cSrcweir aExcMsg += OUSTR("- nor: "); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir } 309cdf0e10cSrcweir 310cdf0e10cSrcweir if (!pEnv->is() && pEnvTypeName) 311cdf0e10cSrcweir { 312cdf0e10cSrcweir *pSourceEnv_name = OUString::createFromAscii(pEnvTypeName); 313cdf0e10cSrcweir const char * pUNO_ENV_LOG = ::getenv( "UNO_ENV_LOG" ); 314cdf0e10cSrcweir if (pUNO_ENV_LOG && rtl_str_getLength(pUNO_ENV_LOG) ) 315cdf0e10cSrcweir { 316cdf0e10cSrcweir OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US)); 317cdf0e10cSrcweir OString aEnv( pUNO_ENV_LOG ); 318cdf0e10cSrcweir sal_Int32 nIndex = 0; 319cdf0e10cSrcweir do 320cdf0e10cSrcweir { 321cdf0e10cSrcweir const OString aStr( aEnv.getToken( 0, ';', nIndex ) ); 322cdf0e10cSrcweir if ( aStr.equals(implName) ) 323cdf0e10cSrcweir { 324cdf0e10cSrcweir *pSourceEnv_name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":log")); 325cdf0e10cSrcweir break; 326cdf0e10cSrcweir } 327cdf0e10cSrcweir } while( nIndex != -1 ); 328cdf0e10cSrcweir } 329cdf0e10cSrcweir 330cdf0e10cSrcweir } 331cdf0e10cSrcweir 332cdf0e10cSrcweir return aExcMsg; 333cdf0e10cSrcweir } 334cdf0e10cSrcweir 335cdf0e10cSrcweir extern "C" {static void s_getFactory(va_list * pParam) 336cdf0e10cSrcweir { 337cdf0e10cSrcweir component_getFactoryFunc pSym = va_arg(*pParam, component_getFactoryFunc); 338cdf0e10cSrcweir OString const * pImplName = va_arg(*pParam, OString const *); 339cdf0e10cSrcweir void * pSMgr = va_arg(*pParam, void *); 340cdf0e10cSrcweir void * pKey = va_arg(*pParam, void *); 341cdf0e10cSrcweir void ** ppSSF = va_arg(*pParam, void **); 342cdf0e10cSrcweir 343cdf0e10cSrcweir *ppSSF = pSym(pImplName->getStr(), pSMgr, pKey); 344cdf0e10cSrcweir }} 345cdf0e10cSrcweir 346cdf0e10cSrcweir Reference< XInterface > SAL_CALL loadSharedLibComponentFactory( 347cdf0e10cSrcweir OUString const & rLibName, OUString const & rPath, 348cdf0e10cSrcweir OUString const & rImplName, 349cdf0e10cSrcweir Reference< lang::XMultiServiceFactory > const & xMgr, 350cdf0e10cSrcweir Reference< registry::XRegistryKey > const & xKey ) 351cdf0e10cSrcweir SAL_THROW( (loader::CannotActivateFactoryException) ) 352cdf0e10cSrcweir { 353cdf0e10cSrcweir OUString aModulePath( makeComponentPath( rLibName, rPath ) ); 354cdf0e10cSrcweir if (! checkAccessPath( &aModulePath )) 355cdf0e10cSrcweir { 356cdf0e10cSrcweir throw loader::CannotActivateFactoryException( 357cdf0e10cSrcweir OUSTR("permission denied to load component library: ") + 358cdf0e10cSrcweir aModulePath, 359cdf0e10cSrcweir Reference< XInterface >() ); 360cdf0e10cSrcweir } 361cdf0e10cSrcweir 362cdf0e10cSrcweir oslModule lib = osl_loadModule( 363cdf0e10cSrcweir aModulePath.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL ); 364cdf0e10cSrcweir if (! lib) 365cdf0e10cSrcweir { 366cdf0e10cSrcweir throw loader::CannotActivateFactoryException( 367cdf0e10cSrcweir OUSTR("loading component library failed: ") + aModulePath, 368cdf0e10cSrcweir Reference< XInterface >() ); 369cdf0e10cSrcweir } 370cdf0e10cSrcweir 371cdf0e10cSrcweir Reference< XInterface > xRet; 372cdf0e10cSrcweir 373cdf0e10cSrcweir uno::Environment currentEnv(Environment::getCurrent()); 374cdf0e10cSrcweir uno::Environment env; 375cdf0e10cSrcweir 376cdf0e10cSrcweir OUString aEnvTypeName; 377cdf0e10cSrcweir 378cdf0e10cSrcweir OUString aExcMsg = getLibEnv(aModulePath, lib, &env, &aEnvTypeName, currentEnv, rImplName); 379cdf0e10cSrcweir if (!aExcMsg.getLength()) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir OUString aGetFactoryName = OUSTR(COMPONENT_GETFACTORY); 382cdf0e10cSrcweir oslGenericFunction pSym = osl_getFunctionSymbol( lib, aGetFactoryName.pData ); 383cdf0e10cSrcweir if (pSym != 0) 384cdf0e10cSrcweir { 385cdf0e10cSrcweir OString aImplName( 386cdf0e10cSrcweir OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) ); 387cdf0e10cSrcweir 388cdf0e10cSrcweir if (!env.is()) 389cdf0e10cSrcweir env = uno::Environment(aEnvTypeName); 390cdf0e10cSrcweir 391cdf0e10cSrcweir if (env.is() && currentEnv.is()) 392cdf0e10cSrcweir { 393cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 394cdf0e10cSrcweir { 395cdf0e10cSrcweir rtl::OString libName(rtl::OUStringToOString(rLibName, RTL_TEXTENCODING_ASCII_US)); 396cdf0e10cSrcweir rtl::OString implName(rtl::OUStringToOString(rImplName, RTL_TEXTENCODING_ASCII_US)); 397cdf0e10cSrcweir rtl::OString envDcp(rtl::OUStringToOString(env.getTypeName(), RTL_TEXTENCODING_ASCII_US)); 398cdf0e10cSrcweir 399cdf0e10cSrcweir fprintf(stderr, "loadSharedLibComponentFactory envDcp: %-12.12s implName: %30.30s libName: %-15.15s\n", envDcp.getStr(), implName.getStr() + (implName.getLength() > 30 ? implName.getLength() - 30 : 0), libName.getStr()); 400cdf0e10cSrcweir } 401cdf0e10cSrcweir #endif 402cdf0e10cSrcweir 403cdf0e10cSrcweir Mapping aCurrent2Env( currentEnv, env ); 404cdf0e10cSrcweir Mapping aEnv2Current( env, currentEnv ); 405cdf0e10cSrcweir 406cdf0e10cSrcweir if (aCurrent2Env.is() && aEnv2Current.is()) 407cdf0e10cSrcweir { 408cdf0e10cSrcweir void * pSMgr = aCurrent2Env.mapInterface( 409cdf0e10cSrcweir xMgr.get(), ::getCppuType( &xMgr ) ); 410cdf0e10cSrcweir void * pKey = aCurrent2Env.mapInterface( 411cdf0e10cSrcweir xKey.get(), ::getCppuType( &xKey ) ); 412cdf0e10cSrcweir 413cdf0e10cSrcweir void * pSSF = NULL; 414cdf0e10cSrcweir 415cdf0e10cSrcweir env.invoke(s_getFactory, pSym, &aImplName, pSMgr, pKey, &pSSF); 416cdf0e10cSrcweir 417cdf0e10cSrcweir if (pKey) 418cdf0e10cSrcweir { 419cdf0e10cSrcweir (env.get()->pExtEnv->releaseInterface)( 420cdf0e10cSrcweir env.get()->pExtEnv, pKey ); 421cdf0e10cSrcweir } 422cdf0e10cSrcweir if (pSMgr) 423cdf0e10cSrcweir { 424cdf0e10cSrcweir (*env.get()->pExtEnv->releaseInterface)( 425cdf0e10cSrcweir env.get()->pExtEnv, pSMgr ); 426cdf0e10cSrcweir } 427cdf0e10cSrcweir 428cdf0e10cSrcweir if (pSSF) 429cdf0e10cSrcweir { 430cdf0e10cSrcweir aEnv2Current.mapInterface( 431cdf0e10cSrcweir reinterpret_cast< void ** >( &xRet ), 432cdf0e10cSrcweir pSSF, ::getCppuType( &xRet ) ); 433cdf0e10cSrcweir (env.get()->pExtEnv->releaseInterface)( 434cdf0e10cSrcweir env.get()->pExtEnv, pSSF ); 435cdf0e10cSrcweir } 436cdf0e10cSrcweir else 437cdf0e10cSrcweir { 438cdf0e10cSrcweir aExcMsg = aModulePath; 439cdf0e10cSrcweir aExcMsg += OUSTR(": cannot get factory of " 440cdf0e10cSrcweir "demanded implementation: "); 441cdf0e10cSrcweir aExcMsg += OStringToOUString( 442cdf0e10cSrcweir aImplName, RTL_TEXTENCODING_ASCII_US ); 443cdf0e10cSrcweir } 444cdf0e10cSrcweir } 445cdf0e10cSrcweir else 446cdf0e10cSrcweir { 447cdf0e10cSrcweir aExcMsg = 448cdf0e10cSrcweir OUSTR("cannot get uno mappings: C++ <=> UNO!"); 449cdf0e10cSrcweir } 450cdf0e10cSrcweir } 451cdf0e10cSrcweir else 452cdf0e10cSrcweir { 453cdf0e10cSrcweir aExcMsg = OUSTR("cannot get uno environments!"); 454cdf0e10cSrcweir } 455cdf0e10cSrcweir } 456cdf0e10cSrcweir else 457cdf0e10cSrcweir { 458cdf0e10cSrcweir aExcMsg = aModulePath; 459cdf0e10cSrcweir aExcMsg += OUSTR(": cannot get symbol: "); 460cdf0e10cSrcweir aExcMsg += aGetFactoryName; 461cdf0e10cSrcweir } 462cdf0e10cSrcweir } 463cdf0e10cSrcweir 464cdf0e10cSrcweir if (! xRet.is()) 465cdf0e10cSrcweir { 466cdf0e10cSrcweir osl_unloadModule( lib ); 467cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 468cdf0e10cSrcweir out( "### cannot activate factory: " ); 469cdf0e10cSrcweir out( aExcMsg ); 470cdf0e10cSrcweir out( "\n" ); 471cdf0e10cSrcweir #endif 472cdf0e10cSrcweir throw loader::CannotActivateFactoryException( 473cdf0e10cSrcweir aExcMsg, 474cdf0e10cSrcweir Reference< XInterface >() ); 475cdf0e10cSrcweir } 476cdf0e10cSrcweir 477cdf0e10cSrcweir rtl_registerModuleForUnloading( lib); 478cdf0e10cSrcweir return xRet; 479cdf0e10cSrcweir } 480cdf0e10cSrcweir 481cdf0e10cSrcweir //============================================================================== 482cdf0e10cSrcweir extern "C" { static void s_writeInfo(va_list * pParam) 483cdf0e10cSrcweir { 484cdf0e10cSrcweir component_writeInfoFunc pSym = va_arg(*pParam, component_writeInfoFunc); 485cdf0e10cSrcweir void * pSMgr = va_arg(*pParam, void *); 486cdf0e10cSrcweir void * pKey = va_arg(*pParam, void *); 487cdf0e10cSrcweir sal_Bool * pbRet = va_arg(*pParam, sal_Bool *); 488cdf0e10cSrcweir 489cdf0e10cSrcweir *pbRet = pSym(pSMgr, pKey); 490cdf0e10cSrcweir 491cdf0e10cSrcweir }} 492cdf0e10cSrcweir 493cdf0e10cSrcweir void SAL_CALL writeSharedLibComponentInfo( 494cdf0e10cSrcweir OUString const & rLibName, OUString const & rPath, 495cdf0e10cSrcweir Reference< lang::XMultiServiceFactory > const & xMgr, 496cdf0e10cSrcweir Reference< registry::XRegistryKey > const & xKey ) 497cdf0e10cSrcweir SAL_THROW( (registry::CannotRegisterImplementationException) ) 498cdf0e10cSrcweir { 499cdf0e10cSrcweir OUString aModulePath( makeComponentPath( rLibName, rPath ) ); 500cdf0e10cSrcweir 501cdf0e10cSrcweir if (! checkAccessPath( &aModulePath )) 502cdf0e10cSrcweir { 503cdf0e10cSrcweir throw registry::CannotRegisterImplementationException( 504cdf0e10cSrcweir OUSTR("permission denied to load component library: ") + 505cdf0e10cSrcweir aModulePath, 506cdf0e10cSrcweir Reference< XInterface >() ); 507cdf0e10cSrcweir } 508cdf0e10cSrcweir 509cdf0e10cSrcweir oslModule lib = osl_loadModule( 510cdf0e10cSrcweir aModulePath.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL ); 511cdf0e10cSrcweir if (! lib) 512cdf0e10cSrcweir { 513cdf0e10cSrcweir throw registry::CannotRegisterImplementationException( 514cdf0e10cSrcweir OUSTR("loading component library failed: ") + aModulePath, 515cdf0e10cSrcweir Reference< XInterface >() ); 516cdf0e10cSrcweir } 517cdf0e10cSrcweir 518cdf0e10cSrcweir sal_Bool bRet = sal_False; 519cdf0e10cSrcweir 520cdf0e10cSrcweir uno::Environment currentEnv(Environment::getCurrent()); 521cdf0e10cSrcweir uno::Environment env; 522cdf0e10cSrcweir 523cdf0e10cSrcweir OUString aEnvTypeName; 524cdf0e10cSrcweir OUString aExcMsg = getLibEnv(aModulePath, lib, &env, &aEnvTypeName, currentEnv); 525cdf0e10cSrcweir if (!aExcMsg.getLength()) 526cdf0e10cSrcweir { 527cdf0e10cSrcweir OUString aWriteInfoName = OUSTR(COMPONENT_WRITEINFO); 528cdf0e10cSrcweir oslGenericFunction pSym = osl_getFunctionSymbol( lib, aWriteInfoName.pData ); 529cdf0e10cSrcweir if (pSym != 0) 530cdf0e10cSrcweir { 531cdf0e10cSrcweir if (!env.is()) 532cdf0e10cSrcweir env = uno::Environment(aEnvTypeName); 533cdf0e10cSrcweir 534cdf0e10cSrcweir if (env.is() && currentEnv.is()) 535cdf0e10cSrcweir { 536cdf0e10cSrcweir Mapping aCurrent2Env( currentEnv, env ); 537cdf0e10cSrcweir if (aCurrent2Env.is()) 538cdf0e10cSrcweir { 539cdf0e10cSrcweir void * pSMgr = aCurrent2Env.mapInterface( 540cdf0e10cSrcweir xMgr.get(), ::getCppuType( &xMgr ) ); 541cdf0e10cSrcweir void * pKey = aCurrent2Env.mapInterface( 542cdf0e10cSrcweir xKey.get(), ::getCppuType( &xKey ) ); 543cdf0e10cSrcweir if (pKey) 544cdf0e10cSrcweir { 545cdf0e10cSrcweir env.invoke(s_writeInfo, pSym, pSMgr, pKey, &bRet); 546cdf0e10cSrcweir 547cdf0e10cSrcweir 548cdf0e10cSrcweir (*env.get()->pExtEnv->releaseInterface)( 549cdf0e10cSrcweir env.get()->pExtEnv, pKey ); 550cdf0e10cSrcweir if (! bRet) 551cdf0e10cSrcweir { 552cdf0e10cSrcweir aExcMsg = aModulePath; 553cdf0e10cSrcweir aExcMsg += OUSTR(": component_writeInfo() " 554cdf0e10cSrcweir "returned false!"); 555cdf0e10cSrcweir } 556cdf0e10cSrcweir } 557cdf0e10cSrcweir else 558cdf0e10cSrcweir { 559cdf0e10cSrcweir // key is mandatory 560cdf0e10cSrcweir aExcMsg = aModulePath; 561cdf0e10cSrcweir aExcMsg += OUSTR(": registry is mandatory to invoke" 562cdf0e10cSrcweir " component_writeInfo()!"); 563cdf0e10cSrcweir } 564cdf0e10cSrcweir 565cdf0e10cSrcweir if (pSMgr) 566cdf0e10cSrcweir { 567cdf0e10cSrcweir (*env.get()->pExtEnv->releaseInterface)( 568cdf0e10cSrcweir env.get()->pExtEnv, pSMgr ); 569cdf0e10cSrcweir } 570cdf0e10cSrcweir } 571cdf0e10cSrcweir else 572cdf0e10cSrcweir { 573cdf0e10cSrcweir aExcMsg = OUSTR("cannot get uno mapping: C++ <=> UNO!"); 574cdf0e10cSrcweir } 575cdf0e10cSrcweir } 576cdf0e10cSrcweir else 577cdf0e10cSrcweir { 578cdf0e10cSrcweir aExcMsg = OUSTR("cannot get uno environments!"); 579cdf0e10cSrcweir } 580cdf0e10cSrcweir } 581cdf0e10cSrcweir else 582cdf0e10cSrcweir { 583cdf0e10cSrcweir aExcMsg = aModulePath; 584cdf0e10cSrcweir aExcMsg += OUSTR(": cannot get symbol: "); 585cdf0e10cSrcweir aExcMsg += aWriteInfoName; 586cdf0e10cSrcweir } 587cdf0e10cSrcweir } 588cdf0e10cSrcweir 589cdf0e10cSrcweir //! 590cdf0e10cSrcweir //! OK: please look at #88219# 591cdf0e10cSrcweir //! 592cdf0e10cSrcweir //! ::osl_unloadModule( lib); 593cdf0e10cSrcweir if (! bRet) 594cdf0e10cSrcweir { 595cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 596cdf0e10cSrcweir out( "### cannot write component info: " ); 597cdf0e10cSrcweir out( aExcMsg ); 598cdf0e10cSrcweir out( "\n" ); 599cdf0e10cSrcweir #endif 600cdf0e10cSrcweir throw registry::CannotRegisterImplementationException( 601cdf0e10cSrcweir aExcMsg, Reference< XInterface >() ); 602cdf0e10cSrcweir } 603cdf0e10cSrcweir } 604cdf0e10cSrcweir 605cdf0e10cSrcweir } 606