update credits
[LibreOffice.git] / cppuhelper / source / shlib.cxx
blobdb741ada70dbed5038211a069108292b1df8b657
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #include <config_features.h>
22 #include "osl/diagnose.h"
23 #include "osl/file.hxx"
24 #include "osl/mutex.hxx"
25 #include "osl/module.hxx"
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"
33 #include "com/sun/star/beans/XPropertySet.hpp"
35 #include <stdio.h>
36 #include <vector>
38 #ifdef ANDROID
39 #include <osl/detail/android-bootstrap.h>
40 #endif
42 #ifdef IOS
43 #include <osl/detail/ios-bootstrap.h>
44 #endif
47 using namespace ::rtl;
48 using namespace ::osl;
49 using namespace ::com::sun::star;
50 using namespace ::com::sun::star::uno;
52 namespace cppu
55 #if OSL_DEBUG_LEVEL > 1
56 //------------------------------------------------------------------------------
57 static inline void out( const char * p ) SAL_THROW(())
59 printf( "%s\n", p );
61 static inline void out( const OUString & r ) throw ()
63 OString s( OUStringToOString( r, RTL_TEXTENCODING_ASCII_US ) );
64 out( s.getStr() );
66 #endif
68 namespace
70 class buildAccessDPath
72 private:
73 ::std::vector< OUString > m_aAccessDPath;
74 bool m_bCPLD_ACCESSPATHSet;
75 public:
76 buildAccessDPath() : m_bCPLD_ACCESSPATHSet(false)
78 const char * pEnv = ::getenv( "CPLD_ACCESSPATH" );
79 if (pEnv)
81 m_bCPLD_ACCESSPATHSet = true;
83 OString aEnv( pEnv );
84 sal_Int32 nIndex = 0;
87 OUString aStr( OStringToOUString(
88 aEnv.getToken( 0, ';', nIndex ),
89 RTL_TEXTENCODING_ASCII_US ) );
90 OUString aFileUrl;
91 if (FileBase::getFileURLFromSystemPath(aStr, aFileUrl)
92 != FileBase::E_None)
94 OSL_ASSERT(false);
96 m_aAccessDPath.push_back( aFileUrl );
97 } while( nIndex != -1 );
98 #if OSL_DEBUG_LEVEL > 1
99 out( "> cpld: acknowledged following access path(s): \"" );
100 ::std::vector< OUString >::const_iterator iPos( m_aAccessDPath.begin() );
101 while (iPos != m_aAccessDPath.end())
103 out( *iPos );
104 ++iPos;
105 if (iPos != m_aAccessDPath.end())
106 out( ";" );
108 out( "\"\n" );
109 #endif
111 else
113 // no access path env set
114 #if OSL_DEBUG_LEVEL > 1
115 out( "=> no CPLD_ACCESSPATH set.\n" );
116 #endif
119 ::std::vector< OUString >* getAccessDPath() { return m_bCPLD_ACCESSPATHSet ? &m_aAccessDPath : NULL; }
122 class theAccessDPath : public rtl::Static<buildAccessDPath, theAccessDPath> {};
125 #ifndef DISABLE_DYNLOADING
127 static const ::std::vector< OUString > * getAccessDPath() SAL_THROW(())
129 return theAccessDPath::get().getAccessDPath();
132 //------------------------------------------------------------------------------
133 static bool checkAccessPath( OUString * pComp ) throw ()
135 const ::std::vector< OUString > * pPath = getAccessDPath();
137 if (pPath)
139 sal_Bool bAbsolute = pComp->startsWith( "file://" );
140 for ( ::std::vector< OUString >::const_iterator iPos( pPath->begin() );
141 iPos != pPath->end(); ++iPos )
143 OUString aBaseDir( *iPos );
144 OUString aAbs;
146 if ( bAbsolute )
148 aAbs = *pComp;
149 #if OSL_DEBUG_LEVEL > 1
150 out( "> taking path: \"" );
151 out( aAbs );
152 #endif
154 else
156 if (osl_File_E_None !=
157 ::osl_getAbsoluteFileURL(
158 aBaseDir.pData, pComp->pData, &aAbs.pData ))
160 continue;
162 #if OSL_DEBUG_LEVEL > 1
163 out( "> found path: \"" );
164 out( aBaseDir );
165 out( "\" + \"" );
166 out( *pComp );
167 out( "\" => \"" );
168 out( aAbs );
169 #endif
172 if (0 == aAbs.indexOf( aBaseDir ) && // still part of it?
173 aBaseDir.getLength() < aAbs.getLength() &&
174 (aBaseDir[ aBaseDir.getLength() -1 ] == (sal_Unicode)'/' ||
175 // dir boundary
176 aAbs[ aBaseDir.getLength() ] == (sal_Unicode)'/'))
178 #if OSL_DEBUG_LEVEL > 1
179 out( ": ok.\n" );
180 #endif
181 // load from absolute path
182 *pComp = aAbs;
183 return true;
185 #if OSL_DEBUG_LEVEL > 1
186 else
188 out( "\" ...does not match given path \"" );
189 out( aBaseDir );
190 out( "\".\n" );
192 #endif
194 return false;
196 else
198 // no access path env set
199 return true;
203 //------------------------------------------------------------------------------
204 static OUString makeComponentPath(
205 const OUString & rLibName, const OUString & rPath )
207 #if OSL_DEBUG_LEVEL > 0
208 // No system path allowed here !
210 OUString aComp;
211 OSL_ASSERT( FileBase::E_None ==
212 FileBase::getSystemPathFromFileURL( rLibName, aComp ) );
213 OSL_ASSERT(
214 rPath.isEmpty() ||
215 FileBase::E_None ==
216 FileBase::getSystemPathFromFileURL( rPath, aComp ) );
218 #endif
220 OUStringBuffer buf( rPath.getLength() + rLibName.getLength() + 12 );
222 if (!rPath.isEmpty())
224 buf.append( rPath );
225 if (rPath[ rPath.getLength() -1 ] != '/')
226 buf.append( (sal_Unicode) '/' );
228 if (! rLibName.endsWithIgnoreAsciiCase( SAL_DLLEXTENSION ))
230 #if defined SAL_DLLPREFIX
231 if (! rLibName.endsWithIgnoreAsciiCase( ".uno" ))
233 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(SAL_DLLPREFIX) );
235 #endif
236 buf.append( rLibName );
237 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION) );
239 else // name is completely pre/postfixed
241 buf.append( rLibName );
244 OUString out( buf.makeStringAndClear() );
245 #if OSL_DEBUG_LEVEL > 1
246 OString str( OUStringToOString( out, RTL_TEXTENCODING_ASCII_US ) );
247 OSL_TRACE(OSL_LOG_PREFIX "component path=%s", str.getStr());
248 #endif
250 return out;
253 //==============================================================================
254 static void getLibEnv(oslModule lib,
255 uno::Environment * pEnv,
256 OUString * pSourceEnv_name,
257 uno::Environment const & cTargetEnv,
258 OUString const & cImplName = OUString(),
259 OUString const & rPrefix = OUString())
261 sal_Char const * pEnvTypeName = NULL;
263 OUString aGetEnvNameExt = rPrefix + COMPONENT_GETENVEXT;
264 component_getImplementationEnvironmentExtFunc pGetImplEnvExt =
265 (component_getImplementationEnvironmentExtFunc)osl_getFunctionSymbol(lib, aGetEnvNameExt.pData);
267 if (pGetImplEnvExt)
269 OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US));
270 pGetImplEnvExt(&pEnvTypeName, (uno_Environment **)pEnv, implName.getStr(), cTargetEnv.get());
272 else
274 OUString aGetEnvName = rPrefix + COMPONENT_GETENV;
275 component_getImplementationEnvironmentFunc pGetImplEnv =
276 (component_getImplementationEnvironmentFunc)osl_getFunctionSymbol(
277 lib, aGetEnvName.pData );
278 if (pGetImplEnv)
279 pGetImplEnv(&pEnvTypeName, (uno_Environment **)pEnv);
281 else // this symbol used to be mandatory, but is no longer
282 pEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
285 if (!pEnv->is() && pEnvTypeName)
287 *pSourceEnv_name = OUString::createFromAscii(pEnvTypeName);
288 const char * pUNO_ENV_LOG = ::getenv( "UNO_ENV_LOG" );
289 if (pUNO_ENV_LOG && rtl_str_getLength(pUNO_ENV_LOG) )
291 OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US));
292 OString aEnv( pUNO_ENV_LOG );
293 sal_Int32 nIndex = 0;
296 const OString aStr( aEnv.getToken( 0, ';', nIndex ) );
297 if ( aStr.equals(implName) )
299 *pSourceEnv_name += ::rtl::OUString(":log");
300 break;
302 } while( nIndex != -1 );
307 #endif
309 extern "C" {static void s_getFactory(va_list * pParam)
311 component_getFactoryFunc pSym = va_arg(*pParam, component_getFactoryFunc);
312 OString const * pImplName = va_arg(*pParam, OString const *);
313 void * pSMgr = va_arg(*pParam, void *);
314 void * pKey = va_arg(*pParam, void *);
315 void ** ppSSF = va_arg(*pParam, void **);
317 *ppSSF = pSym(pImplName->getStr(), pSMgr, pKey);
320 /* For backwards compatibility */
321 Reference< XInterface > SAL_CALL loadSharedLibComponentFactory(
322 OUString const & rLibName, OUString const & rPath,
323 OUString const & rImplName,
324 Reference< lang::XMultiServiceFactory > const & xMgr,
325 Reference< registry::XRegistryKey > const & xKey )
326 SAL_THROW( (loader::CannotActivateFactoryException) )
328 return loadSharedLibComponentFactory( rLibName, rPath, rImplName, xMgr, xKey, rtl::OUString() );
331 namespace
334 Reference< XInterface > invokeComponentFactory(
335 oslGenericFunction pGetter,
336 oslModule lib,
337 OUString const & rModulePath,
338 OUString const & rImplName,
339 Reference< ::com::sun::star::lang::XMultiServiceFactory > const & xMgr,
340 Reference< ::com::sun::star::registry::XRegistryKey > const & xKey,
341 OUString const & rPrefix,
342 OUString &rExcMsg )
344 Reference< XInterface > xRet;
345 uno::Environment currentEnv(Environment::getCurrent());
346 uno::Environment env;
347 OUString aEnvTypeName;
349 #ifdef DISABLE_DYNLOADING
350 (void) lib;
351 (void) rPrefix;
352 // It seems that the only UNO components that have
353 // component_getImplementationEnvironment functions are the JDBC
354 // and ADO (whatever that is) database connectivity thingies
355 // neither of which make sense on iOS and Android (which are the
356 // only platforms for which DISABLE_DYNLOADING is intended,
357 // really). So we can simply bypass the getLibEnv() stuff and
358 // don't need to wonder how to find out what function to call at
359 // this point if statically linked.
360 aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
361 #else
362 getLibEnv(lib, &env, &aEnvTypeName, currentEnv, rImplName, rPrefix);
363 #endif
365 OString aImplName(
366 OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
368 if (!env.is())
369 env = uno::Environment(aEnvTypeName);
371 if (env.is() && currentEnv.is())
373 #if OSL_DEBUG_LEVEL > 1
375 rtl::OString modPath(rtl::OUStringToOString(rModulePath, RTL_TEXTENCODING_ASCII_US));
376 rtl::OString implName(rtl::OUStringToOString(rImplName, RTL_TEXTENCODING_ASCII_US));
377 rtl::OString envDcp(rtl::OUStringToOString(env.getTypeName(), RTL_TEXTENCODING_ASCII_US));
379 fprintf(stderr, "invokeComponentFactory envDcp:%s implName:%s modPath:%s\n", envDcp.getStr(), implName.getStr(), modPath.getStr());
381 #endif
383 Mapping aCurrent2Env( currentEnv, env );
384 Mapping aEnv2Current( env, currentEnv );
386 if (aCurrent2Env.is() && aEnv2Current.is())
388 void * pSMgr = aCurrent2Env.mapInterface(
389 xMgr.get(), ::getCppuType( &xMgr ) );
390 void * pKey = aCurrent2Env.mapInterface(
391 xKey.get(), ::getCppuType( &xKey ) );
393 void * pSSF = NULL;
395 env.invoke(s_getFactory, pGetter, &aImplName, pSMgr, pKey, &pSSF);
397 if (pKey)
399 (env.get()->pExtEnv->releaseInterface)(
400 env.get()->pExtEnv, pKey );
402 if (pSMgr)
404 (*env.get()->pExtEnv->releaseInterface)(
405 env.get()->pExtEnv, pSMgr );
408 if (pSSF)
410 aEnv2Current.mapInterface(
411 reinterpret_cast< void ** >( &xRet ),
412 pSSF, ::getCppuType( &xRet ) );
413 (env.get()->pExtEnv->releaseInterface)(
414 env.get()->pExtEnv, pSSF );
416 else
418 rExcMsg = rModulePath +
419 ": cannot get factory of " +
420 "demanded implementation: " +
421 OStringToOUString(
422 aImplName, RTL_TEXTENCODING_ASCII_US );
425 else
427 rExcMsg =
428 "cannot get uno mappings: C++ <=> UNO!";
431 else
433 rExcMsg = "cannot get uno environments!";
436 return xRet;
439 } // namespace
441 #ifdef DISABLE_DYNLOADING
442 extern "C"
444 extern void * bootstrap_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
445 extern void * configmgr_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
446 extern void * comphelp_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
447 extern void * deployment_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
448 extern void * expwrap_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
449 extern void * fastsax_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
450 extern void * filterconfig1_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
451 extern void * fwk_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
452 extern void * introspection_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
453 extern void * localebe1_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
454 extern void * package2_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
455 extern void * reflection_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
456 extern void * sfx_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
457 extern void * svl_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
458 extern void * tk_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
459 extern void * stocservices_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
460 extern void * i18npool_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
461 extern void * ucb_component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );
462 extern void * ucpexpand1_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 );
468 #endif
470 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) )
478 #ifndef DISABLE_DYNLOADING
479 OUString sLibName(rLibName);
481 #ifdef ANDROID
482 if ( rLibName.equals( "bootstrap.uno" SAL_DLLEXTENSION ) )
483 sLibName = "libbootstrap.uno" SAL_DLLEXTENSION;
484 #endif
486 OUString aModulePath( makeComponentPath( sLibName, rPath ) );
487 if (! checkAccessPath( &aModulePath ))
489 OUString const msg(
490 "permission denied to load component library: " + aModulePath);
491 SAL_WARN("cppuhelper", msg);
492 throw loader::CannotActivateFactoryException(msg,
493 Reference< XInterface >() );
496 oslModule lib = osl_loadModule(
497 aModulePath.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
498 if (! lib)
500 OUString const msg("loading component library failed: " + aModulePath);
501 SAL_WARN("cppuhelper", msg);
502 throw loader::CannotActivateFactoryException(msg,
503 Reference< XInterface >() );
505 #else
506 (void) rPath;
507 oslModule lib;
508 OUString aModulePath("MAIN");
509 if (! osl_getModuleHandle( NULL, &lib))
511 throw loader::CannotActivateFactoryException(
512 "osl_getModuleHandle of the executable: ",
513 Reference< XInterface >() );
515 #endif
517 Reference< XInterface > xRet;
519 OUString aExcMsg;
521 OUString aGetFactoryName = rPrefix + COMPONENT_GETFACTORY;
523 oslGenericFunction pSym = NULL;
525 #ifdef DISABLE_DYNLOADING
527 // First test library names that aren't app-specific.
528 static lib_to_component_mapping non_app_specific_map[] = {
529 // Sigh, the name under which the bootstrap component is looked for
530 // varies a lot? Or then I just have been confused by some mixed-up
531 // incremental build.
532 { "bootstrap.uno" SAL_DLLEXTENSION, bootstrap_component_getFactory },
533 { "bootstrap.uno.a", bootstrap_component_getFactory },
534 { "libbootstrap.uno.a", bootstrap_component_getFactory },
536 // The .uno ones seem to consistently have a "lib" prefix now for Android,
537 // but not iOS, hmm.
538 #ifdef ANDROID
539 { "libintrospection.uno.a", introspection_component_getFactory },
540 { "libreflection.uno.a", reflection_component_getFactory },
541 { "libstocservices.uno.a", stocservices_component_getFactory },
542 #else
543 { "introspection.uno.a", introspection_component_getFactory },
544 { "reflection.uno.a", reflection_component_getFactory },
545 { "stocservices.uno.a", stocservices_component_getFactory },
546 #endif
547 { "libcomphelper.a", comphelp_component_getFactory },
548 { "libconfigmgrlo.a", configmgr_component_getFactory },
549 { "libdeployment.a", deployment_component_getFactory },
550 { "libexpwraplo.a", expwrap_component_getFactory },
551 { "libfastsaxlo.a", fastsax_component_getFactory },
552 { "libfilterconfiglo.a", filterconfig1_component_getFactory },
553 { "libfwklo.a", fwk_component_getFactory },
554 { "libi18npoollo.a", i18npool_component_getFactory },
555 { "liblocalebe1lo.a", localebe1_component_getFactory },
556 { "libpackage2.a", package2_component_getFactory },
557 { "libsfxlo.a", sfx_component_getFactory },
558 { "libsvllo.a", svl_component_getFactory },
559 { "libtklo.a", tk_component_getFactory },
560 { "libucb1.a", ucb_component_getFactory },
561 { "libucpexpand1lo.a", ucpexpand1_component_getFactory },
562 { "libucpfile1.a", ucpfile_component_getFactory },
563 { "libutllo.a", utl_component_getFactory },
564 { "libvcllo.a", vcl_component_getFactory },
565 { "libxstor.a", xstor_component_getFactory },
566 { NULL, NULL }
568 for (int i = 0; pSym == NULL && non_app_specific_map[i].lib != NULL; ++i)
570 if ( rLibName.equalsAscii( non_app_specific_map[i].lib ) )
571 pSym = (oslGenericFunction) non_app_specific_map[i].component_getFactory_function;
574 if ( pSym == NULL)
576 // The call the app-specific lo_get_libmap() to get a mapping for the rest
577 const lib_to_component_mapping *map = lo_get_libmap();
578 for (int i = 0; pSym == NULL && map[i].lib != NULL; ++i)
580 if ( rLibName.equalsAscii( map[i].lib ) )
581 pSym = (oslGenericFunction) map[i].component_getFactory_function;
583 if ( pSym == NULL )
585 fprintf( stderr, "attempting to load unknown library %s\n", OUStringToOString( rLibName, RTL_TEXTENCODING_ASCII_US ).getStr() );
586 assert( !"Attempt to load unknown library" );
589 #else
591 if ( pSym == NULL )
592 pSym = osl_getFunctionSymbol( lib, aGetFactoryName.pData );
593 #endif
595 if (pSym != 0)
597 xRet = invokeComponentFactory( pSym, lib, aModulePath, rImplName, xMgr, xKey, rPrefix, aExcMsg );
599 else
601 aExcMsg = aModulePath;
602 aExcMsg += ": cannot get symbol: ";
603 aExcMsg += aGetFactoryName;
606 if (! xRet.is())
608 #ifndef DISABLE_DYNLOADING
609 osl_unloadModule( lib );
610 #endif
611 SAL_WARN("cppuhelper", "### cannot activate factory: " << aExcMsg);
612 throw loader::CannotActivateFactoryException(
613 aExcMsg,
614 Reference< XInterface >() );
616 return xRet;
619 Reference< XInterface > SAL_CALL invokeStaticComponentFactory(
620 oslGenericFunction pGetter,
621 OUString const & rImplName,
622 Reference< ::com::sun::star::lang::XMultiServiceFactory > const & xMgr,
623 Reference< ::com::sun::star::registry::XRegistryKey > const & xKey,
624 OUString const & rPrefix )
625 SAL_THROW( (::com::sun::star::loader::CannotActivateFactoryException) )
627 Reference< XInterface > xRet;
628 oslModule pExe;
629 OUString aExePath("MAIN");
630 osl_getModuleHandle( NULL, &pExe );
631 OUString aExcMsg;
633 xRet = invokeComponentFactory( pGetter, pExe, aExePath, rImplName, xMgr, xKey, rPrefix, aExcMsg );
635 if (! xRet.is())
637 SAL_WARN("cppuhelper", "### cannot activate factory: " << aExcMsg);
638 throw loader::CannotActivateFactoryException(
639 aExcMsg,
640 Reference< XInterface >() );
643 return xRet;
646 #ifndef DISABLE_DYNLOADING
648 //==============================================================================
649 extern "C" { static void s_writeInfo(va_list * pParam)
651 component_writeInfoFunc pSym = va_arg(*pParam, component_writeInfoFunc);
652 void * pSMgr = va_arg(*pParam, void *);
653 void * pKey = va_arg(*pParam, void *);
654 sal_Bool * pbRet = va_arg(*pParam, sal_Bool *);
656 *pbRet = pSym(pSMgr, pKey);
660 void SAL_CALL writeSharedLibComponentInfo(
661 OUString const & rLibName, OUString const & rPath,
662 Reference< lang::XMultiServiceFactory > const & xMgr,
663 Reference< registry::XRegistryKey > const & xKey )
664 SAL_THROW( (registry::CannotRegisterImplementationException) )
666 OUString aModulePath( makeComponentPath( rLibName, rPath ) );
668 if (! checkAccessPath( &aModulePath ))
670 OUString const msg(
671 "permission denied to load component library: " + aModulePath);
672 SAL_WARN("cppuhelper", msg);
673 throw registry::CannotRegisterImplementationException(msg,
674 Reference< XInterface >() );
677 oslModule lib = osl_loadModule(
678 aModulePath.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
679 if (! lib)
681 OUString const msg("loading component library failed: " + aModulePath);
682 SAL_WARN("cppuhelper", msg);
683 throw registry::CannotRegisterImplementationException(msg,
684 Reference< XInterface >() );
687 sal_Bool bRet = sal_False;
689 uno::Environment currentEnv(Environment::getCurrent());
690 uno::Environment env;
692 OUString aEnvTypeName;
693 OUString aExcMsg;
695 getLibEnv(lib, &env, &aEnvTypeName, currentEnv);
697 OUString aWriteInfoName = COMPONENT_WRITEINFO;
698 oslGenericFunction pSym = osl_getFunctionSymbol( lib, aWriteInfoName.pData );
699 if (pSym != 0)
701 if (!env.is())
702 env = uno::Environment(aEnvTypeName);
704 if (env.is() && currentEnv.is())
706 Mapping aCurrent2Env( currentEnv, env );
707 if (aCurrent2Env.is())
709 void * pSMgr = aCurrent2Env.mapInterface(
710 xMgr.get(), ::getCppuType( &xMgr ) );
711 void * pKey = aCurrent2Env.mapInterface(
712 xKey.get(), ::getCppuType( &xKey ) );
713 if (pKey)
715 env.invoke(s_writeInfo, pSym, pSMgr, pKey, &bRet);
718 (*env.get()->pExtEnv->releaseInterface)(
719 env.get()->pExtEnv, pKey );
720 if (! bRet)
722 aExcMsg = aModulePath;
723 aExcMsg += ": component_writeInfo() "
724 "returned false!";
727 else
729 // key is mandatory
730 aExcMsg = aModulePath;
731 aExcMsg += ": registry is mandatory to invoke"
732 " component_writeInfo()!";
735 if (pSMgr)
737 (*env.get()->pExtEnv->releaseInterface)(
738 env.get()->pExtEnv, pSMgr );
741 else
743 aExcMsg = "cannot get uno mapping: C++ <=> UNO!";
746 else
748 aExcMsg = "cannot get uno environments!";
751 else
753 aExcMsg = aModulePath;
754 aExcMsg += ": cannot get symbol: ";
755 aExcMsg += aWriteInfoName;
759 //! OK: please look at #88219#
761 //! ::osl_unloadModule( lib);
762 if (! bRet)
764 SAL_WARN("cppuhelper", "### cannot write component info: " << aExcMsg);
765 throw registry::CannotRegisterImplementationException(
766 aExcMsg, Reference< XInterface >() );
770 #endif // DISABLE_DYNLOADING
774 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */