LCOV - code coverage report
Current view: top level - libreoffice/cppuhelper/source - shlib.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 91 216 42.1 %
Date: 2012-12-27 Functions: 11 14 78.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      21             : #include "osl/diagnose.h"
      22             : #include "osl/file.hxx"
      23             : #include "osl/mutex.hxx"
      24             : #include "osl/module.hxx"
      25             : #include "rtl/unload.h"
      26             : #include "rtl/ustrbuf.hxx"
      27             : #include "rtl/instance.hxx"
      28             : #include "uno/environment.h"
      29             : #include "uno/mapping.hxx"
      30             : #include "cppuhelper/factory.hxx"
      31             : #include "cppuhelper/shlib.hxx"
      32             : 
      33             : #include "com/sun/star/beans/XPropertySet.hpp"
      34             : 
      35             : #include <stdio.h>
      36             : #include <vector>
      37             : 
      38             : #ifdef ANDROID
      39             : #include <osl/detail/android-bootstrap.h>
      40             : #endif
      41             : 
      42             : #ifdef IOS
      43             : #include <osl/detail/ios-bootstrap.h>
      44             : #endif
      45             : 
      46             : #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
      47             : 
      48             : 
      49             : using namespace ::rtl;
      50             : using namespace ::osl;
      51             : using namespace ::com::sun::star;
      52             : using namespace ::com::sun::star::uno;
      53             : 
      54             : namespace cppu
      55             : {
      56             : 
      57             : #if OSL_DEBUG_LEVEL > 1
      58             : //------------------------------------------------------------------------------
      59             : static inline void out( const char * p ) SAL_THROW(())
      60             : {
      61             :     printf( "%s\n", p );
      62             : }
      63             : static inline void out( const OUString & r ) throw ()
      64             : {
      65             :     OString s( OUStringToOString( r, RTL_TEXTENCODING_ASCII_US ) );
      66             :     out( s.getStr() );
      67             : }
      68             : #endif
      69             : 
      70             : namespace
      71             : {
      72         257 :     class buildAccessDPath
      73             :     {
      74             :     private:
      75             :         ::std::vector< OUString > m_aAccessDPath;
      76             :         bool m_bCPLD_ACCESSPATHSet;
      77             :     public:
      78         257 :         buildAccessDPath() : m_bCPLD_ACCESSPATHSet(false)
      79             :         {
      80         257 :             const char * pEnv = ::getenv( "CPLD_ACCESSPATH" );
      81         257 :             if (pEnv)
      82             :             {
      83           0 :                 m_bCPLD_ACCESSPATHSet = true;
      84             : 
      85           0 :                 OString aEnv( pEnv );
      86           0 :                 sal_Int32 nIndex = 0;
      87           0 :                 do
      88             :                 {
      89             :                     OUString aStr( OStringToOUString(
      90             :                         aEnv.getToken( 0, ';', nIndex ),
      91           0 :                         RTL_TEXTENCODING_ASCII_US ) );
      92           0 :                     OUString aFileUrl;
      93           0 :                     if (FileBase::getFileURLFromSystemPath(aStr, aFileUrl)
      94             :                         != FileBase::E_None)
      95             :                     {
      96             :                         OSL_ASSERT(false);
      97             :                     }
      98           0 :                     m_aAccessDPath.push_back( aFileUrl );
      99           0 :                 } while( nIndex != -1 );
     100             :     #if OSL_G_LEVEL > 1
     101             :                 out( "> cpld: acknowledged following access path(s): \"" );
     102             :                 ::std::vector< OUString >::const_iterator iPos( m_aAccessDPath.begin() );
     103             :                 while (iPos != m_aAccessDPath.end())
     104             :                 {
     105             :                     out( *iPos );
     106             :                     ++iPos;
     107             :                     if (iPos != m_aAccessDPath.end())
     108             :                         out( ";" );
     109             :                 }
     110             :                 out( "\"\n" );
     111             :     #endif
     112             :             }
     113             :             else
     114             :             {
     115             :                 // no access path env set
     116             :     #if OSL_G_LEVEL > 1
     117             :                 out( "=> no CPLD_ACCESSPATH set.\n" );
     118             :     #endif
     119             :             }
     120         257 :         }
     121        4703 :         ::std::vector< OUString >* getAccessDPath() { return m_bCPLD_ACCESSPATHSet ? &m_aAccessDPath : NULL; }
     122             :     };
     123             : 
     124             :     class theAccessDPath : public rtl::Static<buildAccessDPath, theAccessDPath> {};
     125             : }
     126             : 
     127             : #ifndef DISABLE_DYNLOADING
     128             : 
     129        4703 : static const ::std::vector< OUString > * getAccessDPath() SAL_THROW(())
     130             : {
     131        4703 :     return theAccessDPath::get().getAccessDPath();
     132             : }
     133             : 
     134             : //------------------------------------------------------------------------------
     135        4703 : static bool checkAccessPath( OUString * pComp ) throw ()
     136             : {
     137        4703 :     const ::std::vector< OUString > * pPath = getAccessDPath();
     138             : 
     139        4703 :     if (pPath)
     140             :     {
     141           0 :         sal_Bool bAbsolute = (pComp->compareToAscii( "file://" , 7 ) == 0);
     142           0 :         for ( ::std::vector< OUString >::const_iterator iPos( pPath->begin() );
     143           0 :               iPos != pPath->end(); ++iPos )
     144             :         {
     145           0 :             OUString aBaseDir( *iPos );
     146           0 :             OUString aAbs;
     147             : 
     148           0 :             if ( bAbsolute )
     149             :             {
     150           0 :                 aAbs = *pComp;
     151             : #if OSL_DEBUG_LEVEL > 1
     152             :                 out( "> taking path: \"" );
     153             :                 out( aAbs );
     154             : #endif
     155             :             }
     156             :             else
     157             :             {
     158           0 :                 if (osl_File_E_None !=
     159             :                     ::osl_getAbsoluteFileURL(
     160           0 :                         aBaseDir.pData, pComp->pData, &aAbs.pData ))
     161             :                 {
     162           0 :                     continue;
     163             :                 }
     164             : #if OSL_DEBUG_LEVEL > 1
     165             :                 out( "> found path: \"" );
     166             :                 out( aBaseDir );
     167             :                 out( "\" + \"" );
     168             :                 out( *pComp );
     169             :                 out( "\" => \"" );
     170             :                 out( aAbs );
     171             : #endif
     172             :             }
     173             : 
     174           0 :             if (0 == aAbs.indexOf( aBaseDir ) && // still part of it?
     175           0 :                 aBaseDir.getLength() < aAbs.getLength() &&
     176           0 :                 (aBaseDir[ aBaseDir.getLength() -1 ] == (sal_Unicode)'/' ||
     177             :                  // dir boundary
     178           0 :                  aAbs[ aBaseDir.getLength() ] == (sal_Unicode)'/'))
     179             :             {
     180             : #if OSL_DEBUG_LEVEL > 1
     181             :                 out( ": ok.\n" );
     182             : #endif
     183             :                 // load from absolute path
     184           0 :                 *pComp = aAbs;
     185           0 :                 return true;
     186             :             }
     187             : #if OSL_DEBUG_LEVEL > 1
     188             :             else
     189             :             {
     190             :                 out( "\" ...does not match given path \"" );
     191             :                 out( aBaseDir );
     192             :                 out( "\".\n" );
     193             :             }
     194             : #endif
     195           0 :         }
     196           0 :         return false;
     197             :     }
     198             :     else
     199             :     {
     200             :         // no access path env set
     201        4703 :         return true;
     202             :     }
     203             : }
     204             : 
     205             : //------------------------------------------------------------------------------
     206        4703 : static OUString makeComponentPath(
     207             :     const OUString & rLibName, const OUString & rPath )
     208             : {
     209             : #if OSL_DEBUG_LEVEL > 0
     210             :     // No system path allowed here !
     211             :     {
     212             :         OUString aComp;
     213             :         OSL_ASSERT( FileBase::E_None ==
     214             :                     FileBase::getSystemPathFromFileURL( rLibName, aComp ) );
     215             :         OSL_ASSERT(
     216             :             rPath.isEmpty() ||
     217             :             FileBase::E_None ==
     218             :               FileBase::getSystemPathFromFileURL( rPath, aComp ) );
     219             :     }
     220             : #endif
     221             : 
     222        4703 :     OUStringBuffer buf( rPath.getLength() + rLibName.getLength() + 12 );
     223             : 
     224        4703 :     if (!rPath.isEmpty())
     225             :     {
     226        2849 :         buf.append( rPath );
     227        2849 :         if (rPath[ rPath.getLength() -1 ] != '/')
     228        2849 :             buf.append( (sal_Unicode) '/' );
     229             :     }
     230        4703 :     if (! rLibName.endsWithIgnoreAsciiCase( OUSTR(SAL_DLLEXTENSION) ))
     231             :     {
     232             : #if defined SAL_DLLPREFIX
     233           0 :         if (! rLibName.endsWithIgnoreAsciiCase( OUSTR(".uno") ))
     234             :         {
     235           0 :             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(SAL_DLLPREFIX) );
     236             :         }
     237             : #endif
     238           0 :         buf.append( rLibName );
     239           0 :         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION) );
     240             :     }
     241             :     else // name is completely pre/postfixed
     242             :     {
     243        4703 :         buf.append( rLibName );
     244             :     }
     245             : 
     246        4703 :     OUString out( buf.makeStringAndClear() );
     247             : #if OSL_DEBUG_LEVEL > 1
     248             :     OString str( OUStringToOString( out, RTL_TEXTENCODING_ASCII_US ) );
     249             :     OSL_TRACE(OSL_LOG_PREFIX "component path=%s", str.getStr());
     250             : #endif
     251             : 
     252        4703 :     return out;
     253             : }
     254             : 
     255             : //==============================================================================
     256        4703 : static void getLibEnv(oslModule                lib,
     257             :                       uno::Environment       * pEnv,
     258             :                       OUString               * pSourceEnv_name,
     259             :                       uno::Environment const & cTargetEnv,
     260             :                       OUString         const & cImplName = OUString(),
     261             :                       OUString         const & rPrefix = OUString())
     262             : {
     263        4703 :     sal_Char const * pEnvTypeName = NULL;
     264             : 
     265        4703 :     OUString aGetEnvNameExt = rPrefix + OUSTR(COMPONENT_GETENVEXT);
     266             :     component_getImplementationEnvironmentExtFunc pGetImplEnvExt =
     267        4703 :         (component_getImplementationEnvironmentExtFunc)osl_getFunctionSymbol(lib, aGetEnvNameExt.pData);
     268             : 
     269        4703 :     if (pGetImplEnvExt)
     270             :     {
     271           0 :         OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US));
     272           0 :         pGetImplEnvExt(&pEnvTypeName, (uno_Environment **)pEnv, implName.getStr(), cTargetEnv.get());
     273             :     }
     274             :     else
     275             :     {
     276        4703 :         OUString aGetEnvName = rPrefix + OUSTR(COMPONENT_GETENV);
     277             :         component_getImplementationEnvironmentFunc pGetImplEnv =
     278             :             (component_getImplementationEnvironmentFunc)osl_getFunctionSymbol(
     279        4703 :                 lib, aGetEnvName.pData );
     280        4703 :         if (pGetImplEnv)
     281           0 :             pGetImplEnv(&pEnvTypeName, (uno_Environment **)pEnv);
     282             : 
     283             :         else // this symbol used to be mandatory, but is no longer
     284        4703 :             pEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
     285             :     }
     286             : 
     287        4703 :     if (!pEnv->is() && pEnvTypeName)
     288             :     {
     289        4703 :         *pSourceEnv_name = OUString::createFromAscii(pEnvTypeName);
     290        4703 :         const char * pUNO_ENV_LOG = ::getenv( "UNO_ENV_LOG" );
     291        4703 :         if (pUNO_ENV_LOG && rtl_str_getLength(pUNO_ENV_LOG) )
     292             :         {
     293           0 :             OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US));
     294           0 :             OString aEnv( pUNO_ENV_LOG );
     295           0 :             sal_Int32 nIndex = 0;
     296           0 :             do
     297             :             {
     298           0 :                 const OString aStr( aEnv.getToken( 0, ';', nIndex ) );
     299           0 :                 if ( aStr.equals(implName) )
     300             :                 {
     301           0 :                     *pSourceEnv_name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":log"));
     302             :                     break;
     303           0 :                 }
     304           0 :             } while( nIndex != -1 );
     305             :         }
     306        4703 :     }
     307        4703 : }
     308             : 
     309             : #endif
     310             : 
     311        4703 : extern "C" {static void s_getFactory(va_list * pParam)
     312             : {
     313        4703 :     component_getFactoryFunc         pSym      = va_arg(*pParam, component_getFactoryFunc);
     314        4703 :     OString                  const * pImplName = va_arg(*pParam, OString const *);
     315        4703 :     void                           * pSMgr     = va_arg(*pParam, void *);
     316        4703 :     void                           * pKey      = va_arg(*pParam, void *);
     317        4703 :     void                          ** ppSSF     = va_arg(*pParam, void **);
     318             : 
     319        4703 :     *ppSSF = pSym(pImplName->getStr(), pSMgr, pKey);
     320        4703 : }}
     321             : 
     322             : /* For backwards compatibility */
     323        2849 : Reference< XInterface > SAL_CALL loadSharedLibComponentFactory(
     324             :     OUString const & rLibName, OUString const & rPath,
     325             :     OUString const & rImplName,
     326             :     Reference< lang::XMultiServiceFactory > const & xMgr,
     327             :     Reference< registry::XRegistryKey > const & xKey )
     328             :     SAL_THROW( (loader::CannotActivateFactoryException) )
     329             : {
     330        2849 :     return loadSharedLibComponentFactory( rLibName, rPath, rImplName, xMgr, xKey, rtl::OUString() );
     331             : }
     332             : 
     333             : namespace
     334             : {
     335             : 
     336        4703 : Reference< XInterface > invokeComponentFactory(
     337             :     oslGenericFunction pGetter,
     338             :     oslModule lib,
     339             :     OUString const & rModulePath,
     340             :     OUString const & rImplName,
     341             :     Reference< ::com::sun::star::lang::XMultiServiceFactory > const & xMgr,
     342             :     Reference< ::com::sun::star::registry::XRegistryKey > const & xKey,
     343             :     OUString const & rPrefix,
     344             :     OUString &rExcMsg )
     345             : {
     346        4703 :     Reference< XInterface > xRet;
     347        4703 :     uno::Environment currentEnv(Environment::getCurrent());
     348        4703 :     uno::Environment env;
     349        4703 :     OUString aEnvTypeName;
     350             : 
     351             : #ifdef DISABLE_DYNLOADING
     352             :     (void) lib;
     353             :     (void) rPrefix;
     354             :     // It seems that the only UNO components that have
     355             :     // component_getImplementationEnvironment functions are the JDBC
     356             :     // and ADO (whatever that is) database connectivity thingies
     357             :     // neither of which make sense on iOS (which is the only platform
     358             :     // for which DISABLE_DYNLOADING is intended, really). So we can
     359             :     // simoly bypass the getLibEnv() stuff and don't need to wonder
     360             :     // how to find out what function to call at this point if
     361             :     // statically linked.
     362             :     aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
     363             : #else
     364        4703 :     getLibEnv(lib, &env, &aEnvTypeName, currentEnv, rImplName, rPrefix);
     365             : #endif
     366             : 
     367             :     OString aImplName(
     368        4703 :         OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
     369             : 
     370        4703 :     if (!env.is())
     371        4703 :         env = uno::Environment(aEnvTypeName);
     372             : 
     373        4703 :     if (env.is() && currentEnv.is())
     374             :     {
     375             : #if OSL_DEBUG_LEVEL > 1
     376             :         {
     377             :             rtl::OString modPath(rtl::OUStringToOString(rModulePath, RTL_TEXTENCODING_ASCII_US));
     378             :             rtl::OString implName(rtl::OUStringToOString(rImplName, RTL_TEXTENCODING_ASCII_US));
     379             :             rtl::OString envDcp(rtl::OUStringToOString(env.getTypeName(), RTL_TEXTENCODING_ASCII_US));
     380             : 
     381             :             fprintf(stderr, "invokeComponentFactory envDcp:%s implName:%s modPath:%s\n", envDcp.getStr(), implName.getStr(), modPath.getStr());
     382             :         }
     383             : #endif
     384             : 
     385        4703 :         Mapping aCurrent2Env( currentEnv, env );
     386        4703 :         Mapping aEnv2Current( env, currentEnv );
     387             : 
     388        4703 :         if (aCurrent2Env.is() && aEnv2Current.is())
     389             :         {
     390             :             void * pSMgr = aCurrent2Env.mapInterface(
     391        4703 :                 xMgr.get(), ::getCppuType( &xMgr ) );
     392             :             void * pKey = aCurrent2Env.mapInterface(
     393        4703 :                 xKey.get(), ::getCppuType( &xKey ) );
     394             : 
     395        4703 :             void * pSSF = NULL;
     396             : 
     397        4703 :             env.invoke(s_getFactory, pGetter, &aImplName, pSMgr, pKey, &pSSF);
     398             : 
     399        4703 :             if (pKey)
     400             :             {
     401           0 :                 (env.get()->pExtEnv->releaseInterface)(
     402           0 :                     env.get()->pExtEnv, pKey );
     403             :             }
     404        4703 :             if (pSMgr)
     405             :             {
     406        4444 :                 (*env.get()->pExtEnv->releaseInterface)(
     407        4444 :                     env.get()->pExtEnv, pSMgr );
     408             :             }
     409             : 
     410        4703 :             if (pSSF)
     411             :             {
     412             :                 aEnv2Current.mapInterface(
     413             :                     reinterpret_cast< void ** >( &xRet ),
     414        4703 :                     pSSF, ::getCppuType( &xRet ) );
     415        4703 :                 (env.get()->pExtEnv->releaseInterface)(
     416        4703 :                     env.get()->pExtEnv, pSSF );
     417             :             }
     418             :             else
     419             :             {
     420           0 :                 rExcMsg = rModulePath;
     421           0 :                 rExcMsg += OUSTR(": cannot get factory of "
     422           0 :                                  "demanded implementation: ");
     423             :                 rExcMsg += OStringToOUString(
     424           0 :                         aImplName, RTL_TEXTENCODING_ASCII_US );
     425             :             }
     426             :         }
     427             :         else
     428             :         {
     429             :             rExcMsg =
     430           0 :                 OUSTR("cannot get uno mappings: C++ <=> UNO!");
     431        4703 :         }
     432             :     }
     433             :     else
     434             :     {
     435           0 :         rExcMsg = OUSTR("cannot get uno environments!");
     436             :     }
     437             : 
     438        4703 :     return xRet;
     439             : }
     440             : 
     441             : } // namespace
     442             : 
     443             : #ifdef DISABLE_DYNLOADING
     444             : extern "C"
     445             : {
     446             :     extern void * bootstrap_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     447             :     extern void * configmgr_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     448             :     extern void * comphelp_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     449             :     extern void * expwrap_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     450             :     extern void * fastsax_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     451             :     extern void * filterconfig1_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     452             :     extern void * fwk_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     453             :     extern void * introspection_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     454             :     extern void * localebe1_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     455             :     extern void * package2_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     456             :     extern void * reflection_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     457             :     extern void * sfx_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     458             :     extern void * svl_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     459             :     extern void * tk_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     460             :     extern void * stocservices_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     461             :     extern void * i18npool_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     462             :     extern void * ucb_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     463             :     extern void * ucpfile_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     464             :     extern void * utl_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     465             :     extern void * vcl_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     466             :     extern void * xstor_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
     467             : }
     468             : #endif
     469             : 
     470        4703 : Reference< XInterface > SAL_CALL loadSharedLibComponentFactory(
     471             :     OUString const & rLibName, OUString const & rPath,
     472             :     OUString const & rImplName,
     473             :     Reference< lang::XMultiServiceFactory > const & xMgr,
     474             :     Reference< registry::XRegistryKey > const & xKey,
     475             :     OUString const & rPrefix )
     476             :     SAL_THROW( (loader::CannotActivateFactoryException) )
     477             : {
     478             : #ifndef DISABLE_DYNLOADING
     479        4703 :     OUString sLibName(rLibName);
     480             : 
     481             : #ifdef ANDROID
     482             :     if ( rLibName.equals( OUSTR("bootstrap.uno" SAL_DLLEXTENSION) ) )
     483             :         sLibName = OUSTR("libbootstrap.uno" SAL_DLLEXTENSION);
     484             : #endif
     485             : 
     486        4703 :     OUString aModulePath( makeComponentPath( sLibName, rPath ) );
     487        4703 :     if (! checkAccessPath( &aModulePath ))
     488             :     {
     489             :         throw loader::CannotActivateFactoryException(
     490             :             OUSTR("permission denied to load component library: ") +
     491           0 :             aModulePath,
     492           0 :             Reference< XInterface >() );
     493             :     }
     494             : 
     495             :     oslModule lib = osl_loadModule(
     496        4703 :         aModulePath.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
     497        4703 :     if (! lib)
     498             :     {
     499             :         throw loader::CannotActivateFactoryException(
     500           0 :             OUSTR("loading component library failed: ") + aModulePath,
     501           0 :             Reference< XInterface >() );
     502             :     }
     503             : #else
     504             :     (void) rPath;
     505             :     oslModule lib;
     506             :     OUString aModulePath(OUSTR("MAIN"));
     507             :     if (! osl_getModuleHandle( NULL, &lib))
     508             :     {
     509             :         throw loader::CannotActivateFactoryException(
     510             :             OUSTR("osl_getModuleHandle of the executable: "),
     511             :             Reference< XInterface >() );
     512             :     }
     513             : #endif
     514             : 
     515        4703 :     Reference< XInterface > xRet;
     516             : 
     517        4703 :     OUString aExcMsg;
     518             : 
     519        4703 :     OUString aGetFactoryName = rPrefix + OUSTR(COMPONENT_GETFACTORY);
     520             : 
     521        4703 :     oslGenericFunction pSym = NULL;
     522             : 
     523             : #ifdef DISABLE_DYNLOADING
     524             : 
     525             :     // First test library names that aren't app-specific.
     526             :     static lib_to_component_mapping non_app_specific_map[] = {
     527             :         // Sigh, the name under which the bootstrap component is looked for
     528             :         // varies a lot? Or then I just have been confused by some mixed-up
     529             :         // incremental build.
     530             :         { "bootstrap.uno" SAL_DLLEXTENSION, bootstrap_component_getFactory },
     531             :         { "bootstrap.uno.a", bootstrap_component_getFactory },
     532             :         { "libbootstrap.uno.a", bootstrap_component_getFactory },
     533             :         // The rest seems to consistently have a "lib" prefix now
     534             :         { "libconfigmgr.uno.a", configmgr_component_getFactory },
     535             :         { "libcomphelp" CPPU_STRINGIFY(CPPU_ENV) ".a", comphelp_component_getFactory },
     536             :         { "libexpwrap.uno.a", expwrap_component_getFactory },
     537             :         { "libfastsax.uno.a", fastsax_component_getFactory },
     538             :         { "libfilterconfiglo.a", filterconfig1_component_getFactory },
     539             :         { "libfwklo.a", fwk_component_getFactory },
     540             :         { "libi18npool.uno.a", i18npool_component_getFactory },
     541             :         { "libintrospection.uno.a", introspection_component_getFactory },
     542             :         { "liblocalebe1.uno.a", localebe1_component_getFactory },
     543             :         { "libpackage2.a", package2_component_getFactory },
     544             :         { "libreflection.uno.a", reflection_component_getFactory },
     545             :         { "libsfxlo.a", sfx_component_getFactory },
     546             :         { "libstocservices.uno.a", stocservices_component_getFactory },
     547             :         { "libsvllo.a", svl_component_getFactory },
     548             :         { "libtklo.a", tk_component_getFactory },
     549             :         { "libucb1.a", ucb_component_getFactory },
     550             :         { "libucpfile1.a", ucpfile_component_getFactory },
     551             :         { "libutllo.a", utl_component_getFactory },
     552             :         { "libvcllo.a", vcl_component_getFactory },
     553             :         { "libxstor.a", xstor_component_getFactory },
     554             :         { NULL, NULL }
     555             :     };
     556             :     for (int i = 0; pSym == NULL && non_app_specific_map[i].lib != NULL; ++i)
     557             :     {
     558             :         if ( rLibName.equalsAscii( non_app_specific_map[i].lib ) )
     559             :             pSym = (oslGenericFunction) non_app_specific_map[i].component_getFactory_function;
     560             :     }
     561             : 
     562             :     if ( pSym == NULL)
     563             :     {
     564             :         // The call the app-specific lo_get_libmap() to get a mapping for the rest
     565             :         const lib_to_component_mapping *map = lo_get_libmap();
     566             :         for (int i = 0; pSym == NULL && map[i].lib != NULL; ++i)
     567             :         {
     568             :             if ( rLibName.equalsAscii( map[i].lib ) )
     569             :                 pSym = (oslGenericFunction) map[i].component_getFactory_function;
     570             :         }
     571             :         if ( pSym == NULL )
     572             :         {
     573             :             fprintf( stderr, "attempting to load unknown library %s\n", OUStringToOString( rLibName, RTL_TEXTENCODING_ASCII_US ).getStr() );
     574             :             assert( !"Attempt to load unknown library" );
     575             :         }
     576             :     }
     577             : #else
     578             : 
     579        4703 :     if ( pSym == NULL )
     580        4703 :         pSym = osl_getFunctionSymbol( lib, aGetFactoryName.pData );
     581             : #endif
     582             : 
     583        4703 :     if (pSym != 0)
     584             :     {
     585        4703 :         xRet = invokeComponentFactory( pSym, lib, aModulePath, rImplName, xMgr, xKey, rPrefix, aExcMsg );
     586             :     }
     587             :     else
     588             :     {
     589           0 :         aExcMsg = aModulePath;
     590           0 :         aExcMsg += OUSTR(": cannot get symbol: ");
     591           0 :         aExcMsg += aGetFactoryName;
     592             :     }
     593             : 
     594        4703 :     if (! xRet.is())
     595             :     {
     596             : #ifndef DISABLE_DYNLOADING
     597           0 :         osl_unloadModule( lib );
     598             : #endif
     599             : #if OSL_DEBUG_LEVEL > 1
     600             :         out( "### cannot activate factory: " );
     601             :         out( aExcMsg );
     602             :         out( "\n" );
     603             : #endif
     604             :         throw loader::CannotActivateFactoryException(
     605             :             aExcMsg,
     606           0 :             Reference< XInterface >() );
     607             :     }
     608             : 
     609        4703 :     rtl_registerModuleForUnloading( lib);
     610        4703 :     return xRet;
     611             : }
     612             : 
     613           0 : Reference< XInterface > SAL_CALL invokeStaticComponentFactory(
     614             :     oslGenericFunction pGetter,
     615             :     OUString const & rImplName,
     616             :     Reference< ::com::sun::star::lang::XMultiServiceFactory > const & xMgr,
     617             :     Reference< ::com::sun::star::registry::XRegistryKey > const & xKey,
     618             :     OUString const & rPrefix )
     619             :     SAL_THROW( (::com::sun::star::loader::CannotActivateFactoryException) )
     620             : {
     621           0 :     Reference< XInterface > xRet;
     622             :     oslModule pExe;
     623           0 :     OUString aExePath(OUSTR("MAIN"));
     624           0 :     osl_getModuleHandle( NULL, &pExe );
     625           0 :     OUString aExcMsg;
     626             : 
     627           0 :     xRet = invokeComponentFactory( pGetter, pExe, aExePath, rImplName, xMgr, xKey, rPrefix, aExcMsg );
     628             : 
     629           0 :     if (! xRet.is())
     630             :     {
     631             : #if OSL_DEBUG_LEVEL > 1
     632             :         out( "### cannot activate factory: " );
     633             :         out( aExcMsg );
     634             :         out( "\n" );
     635             : #endif
     636             :         throw loader::CannotActivateFactoryException(
     637             :             aExcMsg,
     638           0 :             Reference< XInterface >() );
     639             :     }
     640             : 
     641           0 :     return xRet;
     642             : }
     643             : 
     644             : #ifndef DISABLE_DYNLOADING
     645             : 
     646             : //==============================================================================
     647           0 : extern "C" { static void s_writeInfo(va_list * pParam)
     648             : {
     649           0 :     component_writeInfoFunc         pSym      = va_arg(*pParam, component_writeInfoFunc);
     650           0 :     void                          * pSMgr     = va_arg(*pParam, void *);
     651           0 :     void                          * pKey      = va_arg(*pParam, void *);
     652           0 :     sal_Bool                      * pbRet     = va_arg(*pParam, sal_Bool *);
     653             : 
     654           0 :     *pbRet = pSym(pSMgr, pKey);
     655             : 
     656           0 : }}
     657             : 
     658           0 : void SAL_CALL writeSharedLibComponentInfo(
     659             :     OUString const & rLibName, OUString const & rPath,
     660             :     Reference< lang::XMultiServiceFactory > const & xMgr,
     661             :     Reference< registry::XRegistryKey > const & xKey )
     662             :     SAL_THROW( (registry::CannotRegisterImplementationException) )
     663             : {
     664           0 :     OUString aModulePath( makeComponentPath( rLibName, rPath ) );
     665             : 
     666           0 :     if (! checkAccessPath( &aModulePath ))
     667             :     {
     668             :         throw registry::CannotRegisterImplementationException(
     669             :             OUSTR("permission denied to load component library: ") +
     670           0 :             aModulePath,
     671           0 :             Reference< XInterface >() );
     672             :     }
     673             : 
     674             :     oslModule lib = osl_loadModule(
     675           0 :         aModulePath.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
     676           0 :     if (! lib)
     677             :     {
     678             :         throw registry::CannotRegisterImplementationException(
     679           0 :             OUSTR("loading component library failed: ") + aModulePath,
     680           0 :             Reference< XInterface >() );
     681             :     }
     682             : 
     683           0 :     sal_Bool bRet = sal_False;
     684             : 
     685           0 :     uno::Environment currentEnv(Environment::getCurrent());
     686           0 :     uno::Environment env;
     687             : 
     688           0 :     OUString aEnvTypeName;
     689           0 :     OUString aExcMsg;
     690             : 
     691           0 :     getLibEnv(lib, &env, &aEnvTypeName, currentEnv);
     692             : 
     693           0 :     OUString aWriteInfoName = OUSTR(COMPONENT_WRITEINFO);
     694           0 :     oslGenericFunction pSym = osl_getFunctionSymbol( lib, aWriteInfoName.pData );
     695           0 :     if (pSym != 0)
     696             :     {
     697           0 :         if (!env.is())
     698           0 :             env = uno::Environment(aEnvTypeName);
     699             : 
     700           0 :         if (env.is() && currentEnv.is())
     701             :         {
     702           0 :             Mapping aCurrent2Env( currentEnv, env );
     703           0 :             if (aCurrent2Env.is())
     704             :             {
     705             :                 void * pSMgr = aCurrent2Env.mapInterface(
     706           0 :                     xMgr.get(), ::getCppuType( &xMgr ) );
     707             :                 void * pKey = aCurrent2Env.mapInterface(
     708           0 :                     xKey.get(), ::getCppuType( &xKey ) );
     709           0 :                 if (pKey)
     710             :                 {
     711           0 :                     env.invoke(s_writeInfo, pSym, pSMgr, pKey, &bRet);
     712             : 
     713             : 
     714           0 :                     (*env.get()->pExtEnv->releaseInterface)(
     715           0 :                         env.get()->pExtEnv, pKey );
     716           0 :                     if (! bRet)
     717             :                     {
     718           0 :                         aExcMsg = aModulePath;
     719           0 :                         aExcMsg += OUSTR(": component_writeInfo() "
     720           0 :                                          "returned false!");
     721             :                     }
     722             :                 }
     723             :                 else
     724             :                 {
     725             :                     // key is mandatory
     726           0 :                     aExcMsg = aModulePath;
     727           0 :                     aExcMsg += OUSTR(": registry is mandatory to invoke"
     728           0 :                                      " component_writeInfo()!");
     729             :                 }
     730             : 
     731           0 :                 if (pSMgr)
     732             :                 {
     733           0 :                     (*env.get()->pExtEnv->releaseInterface)(
     734           0 :                         env.get()->pExtEnv, pSMgr );
     735             :                 }
     736             :             }
     737             :             else
     738             :             {
     739           0 :                 aExcMsg = OUSTR("cannot get uno mapping: C++ <=> UNO!");
     740           0 :             }
     741             :         }
     742             :         else
     743             :         {
     744           0 :             aExcMsg = OUSTR("cannot get uno environments!");
     745             :         }
     746             :     }
     747             :     else
     748             :     {
     749           0 :         aExcMsg = aModulePath;
     750           0 :         aExcMsg += OUSTR(": cannot get symbol: ");
     751           0 :         aExcMsg += aWriteInfoName;
     752             :     }
     753             : 
     754             : //!
     755             : //! OK: please look at #88219#
     756             : //!
     757             : //! ::osl_unloadModule( lib);
     758           0 :     if (! bRet)
     759             :     {
     760             : #if OSL_DEBUG_LEVEL > 1
     761             :         out( "### cannot write component info: " );
     762             :         out( aExcMsg );
     763             :         out( "\n" );
     764             : #endif
     765             :         throw registry::CannotRegisterImplementationException(
     766           0 :             aExcMsg, Reference< XInterface >() );
     767           0 :     }
     768           0 : }
     769             : 
     770             : #endif // DISABLE_DYNLOADING
     771             : 
     772             : }
     773             : 
     774             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10