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 : #include <config_features.h>
21 :
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"
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 :
47 : using namespace ::rtl;
48 : using namespace ::osl;
49 : using namespace ::com::sun::star;
50 : using namespace ::com::sun::star::uno;
51 :
52 : namespace cppu
53 : {
54 :
55 : #if OSL_DEBUG_LEVEL > 1
56 : //------------------------------------------------------------------------------
57 : static inline void out( const char * p ) SAL_THROW(())
58 : {
59 : printf( "%s\n", p );
60 : }
61 : static inline void out( const OUString & r ) throw ()
62 : {
63 : OString s( OUStringToOString( r, RTL_TEXTENCODING_ASCII_US ) );
64 : out( s.getStr() );
65 : }
66 : #endif
67 :
68 : namespace
69 : {
70 384 : class buildAccessDPath
71 : {
72 : private:
73 : ::std::vector< OUString > m_aAccessDPath;
74 : bool m_bCPLD_ACCESSPATHSet;
75 : public:
76 384 : buildAccessDPath() : m_bCPLD_ACCESSPATHSet(false)
77 : {
78 384 : const char * pEnv = ::getenv( "CPLD_ACCESSPATH" );
79 384 : if (pEnv)
80 : {
81 0 : m_bCPLD_ACCESSPATHSet = true;
82 :
83 0 : OString aEnv( pEnv );
84 0 : sal_Int32 nIndex = 0;
85 0 : do
86 : {
87 : OUString aStr( OStringToOUString(
88 : aEnv.getToken( 0, ';', nIndex ),
89 0 : RTL_TEXTENCODING_ASCII_US ) );
90 0 : OUString aFileUrl;
91 0 : if (FileBase::getFileURLFromSystemPath(aStr, aFileUrl)
92 : != FileBase::E_None)
93 : {
94 : OSL_ASSERT(false);
95 : }
96 0 : m_aAccessDPath.push_back( aFileUrl );
97 0 : } 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())
102 : {
103 : out( *iPos );
104 : ++iPos;
105 : if (iPos != m_aAccessDPath.end())
106 : out( ";" );
107 : }
108 : out( "\"\n" );
109 : #endif
110 : }
111 : else
112 : {
113 : // no access path env set
114 : #if OSL_DEBUG_LEVEL > 1
115 : out( "=> no CPLD_ACCESSPATH set.\n" );
116 : #endif
117 : }
118 384 : }
119 9444 : ::std::vector< OUString >* getAccessDPath() { return m_bCPLD_ACCESSPATHSet ? &m_aAccessDPath : NULL; }
120 : };
121 :
122 : class theAccessDPath : public rtl::Static<buildAccessDPath, theAccessDPath> {};
123 : }
124 :
125 : #ifndef DISABLE_DYNLOADING
126 :
127 9444 : static const ::std::vector< OUString > * getAccessDPath() SAL_THROW(())
128 : {
129 9444 : return theAccessDPath::get().getAccessDPath();
130 : }
131 :
132 : //------------------------------------------------------------------------------
133 9444 : static bool checkAccessPath( OUString * pComp ) throw ()
134 : {
135 9444 : const ::std::vector< OUString > * pPath = getAccessDPath();
136 :
137 9444 : if (pPath)
138 : {
139 0 : sal_Bool bAbsolute = pComp->startsWith( "file://" );
140 0 : for ( ::std::vector< OUString >::const_iterator iPos( pPath->begin() );
141 0 : iPos != pPath->end(); ++iPos )
142 : {
143 0 : OUString aBaseDir( *iPos );
144 0 : OUString aAbs;
145 :
146 0 : if ( bAbsolute )
147 : {
148 0 : aAbs = *pComp;
149 : #if OSL_DEBUG_LEVEL > 1
150 : out( "> taking path: \"" );
151 : out( aAbs );
152 : #endif
153 : }
154 : else
155 : {
156 0 : if (osl_File_E_None !=
157 : ::osl_getAbsoluteFileURL(
158 0 : aBaseDir.pData, pComp->pData, &aAbs.pData ))
159 : {
160 0 : continue;
161 : }
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
170 : }
171 :
172 0 : if (0 == aAbs.indexOf( aBaseDir ) && // still part of it?
173 0 : aBaseDir.getLength() < aAbs.getLength() &&
174 0 : (aBaseDir[ aBaseDir.getLength() -1 ] == (sal_Unicode)'/' ||
175 : // dir boundary
176 0 : aAbs[ aBaseDir.getLength() ] == (sal_Unicode)'/'))
177 : {
178 : #if OSL_DEBUG_LEVEL > 1
179 : out( ": ok.\n" );
180 : #endif
181 : // load from absolute path
182 0 : *pComp = aAbs;
183 0 : return true;
184 : }
185 : #if OSL_DEBUG_LEVEL > 1
186 : else
187 : {
188 : out( "\" ...does not match given path \"" );
189 : out( aBaseDir );
190 : out( "\".\n" );
191 : }
192 : #endif
193 0 : }
194 0 : return false;
195 : }
196 : else
197 : {
198 : // no access path env set
199 9444 : return true;
200 : }
201 : }
202 :
203 : //------------------------------------------------------------------------------
204 9444 : static OUString makeComponentPath(
205 : const OUString & rLibName, const OUString & rPath )
206 : {
207 : #if OSL_DEBUG_LEVEL > 0
208 : // No system path allowed here !
209 : {
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 ) );
217 : }
218 : #endif
219 :
220 9444 : OUStringBuffer buf( rPath.getLength() + rLibName.getLength() + 12 );
221 :
222 9444 : if (!rPath.isEmpty())
223 : {
224 0 : buf.append( rPath );
225 0 : if (rPath[ rPath.getLength() -1 ] != '/')
226 0 : buf.append( (sal_Unicode) '/' );
227 : }
228 9444 : if (! rLibName.endsWithIgnoreAsciiCase( SAL_DLLEXTENSION ))
229 : {
230 : #if defined SAL_DLLPREFIX
231 0 : if (! rLibName.endsWithIgnoreAsciiCase( ".uno" ))
232 : {
233 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(SAL_DLLPREFIX) );
234 : }
235 : #endif
236 0 : buf.append( rLibName );
237 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION) );
238 : }
239 : else // name is completely pre/postfixed
240 : {
241 9444 : buf.append( rLibName );
242 : }
243 :
244 9444 : 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
249 :
250 9444 : return out;
251 : }
252 :
253 : //==============================================================================
254 9444 : 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())
260 : {
261 9444 : sal_Char const * pEnvTypeName = NULL;
262 :
263 9444 : OUString aGetEnvNameExt = rPrefix + COMPONENT_GETENVEXT;
264 : component_getImplementationEnvironmentExtFunc pGetImplEnvExt =
265 9444 : (component_getImplementationEnvironmentExtFunc)osl_getFunctionSymbol(lib, aGetEnvNameExt.pData);
266 :
267 9444 : if (pGetImplEnvExt)
268 : {
269 0 : OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US));
270 0 : pGetImplEnvExt(&pEnvTypeName, (uno_Environment **)pEnv, implName.getStr(), cTargetEnv.get());
271 : }
272 : else
273 : {
274 9444 : OUString aGetEnvName = rPrefix + COMPONENT_GETENV;
275 : component_getImplementationEnvironmentFunc pGetImplEnv =
276 : (component_getImplementationEnvironmentFunc)osl_getFunctionSymbol(
277 9444 : lib, aGetEnvName.pData );
278 9444 : if (pGetImplEnv)
279 4 : pGetImplEnv(&pEnvTypeName, (uno_Environment **)pEnv);
280 :
281 : else // this symbol used to be mandatory, but is no longer
282 9440 : pEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
283 : }
284 :
285 9444 : if (!pEnv->is() && pEnvTypeName)
286 : {
287 9444 : *pSourceEnv_name = OUString::createFromAscii(pEnvTypeName);
288 9444 : const char * pUNO_ENV_LOG = ::getenv( "UNO_ENV_LOG" );
289 9444 : if (pUNO_ENV_LOG && rtl_str_getLength(pUNO_ENV_LOG) )
290 : {
291 0 : OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US));
292 0 : OString aEnv( pUNO_ENV_LOG );
293 0 : sal_Int32 nIndex = 0;
294 0 : do
295 : {
296 0 : const OString aStr( aEnv.getToken( 0, ';', nIndex ) );
297 0 : if ( aStr.equals(implName) )
298 : {
299 0 : *pSourceEnv_name += ::rtl::OUString(":log");
300 0 : break;
301 0 : }
302 0 : } while( nIndex != -1 );
303 : }
304 9444 : }
305 9444 : }
306 :
307 : #endif
308 :
309 9444 : extern "C" {static void s_getFactory(va_list * pParam)
310 : {
311 9444 : component_getFactoryFunc pSym = va_arg(*pParam, component_getFactoryFunc);
312 9444 : OString const * pImplName = va_arg(*pParam, OString const *);
313 9444 : void * pSMgr = va_arg(*pParam, void *);
314 9444 : void * pKey = va_arg(*pParam, void *);
315 9444 : void ** ppSSF = va_arg(*pParam, void **);
316 :
317 9444 : *ppSSF = pSym(pImplName->getStr(), pSMgr, pKey);
318 9444 : }}
319 :
320 : /* For backwards compatibility */
321 0 : 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) )
327 : {
328 0 : return loadSharedLibComponentFactory( rLibName, rPath, rImplName, xMgr, xKey, rtl::OUString() );
329 : }
330 :
331 : namespace
332 : {
333 :
334 9444 : 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 )
343 : {
344 9444 : Reference< XInterface > xRet;
345 18888 : uno::Environment currentEnv(Environment::getCurrent());
346 18888 : uno::Environment env;
347 18888 : OUString aEnvTypeName;
348 :
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 9444 : getLibEnv(lib, &env, &aEnvTypeName, currentEnv, rImplName, rPrefix);
363 : #endif
364 :
365 : OString aImplName(
366 18888 : OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
367 :
368 9444 : if (!env.is())
369 9444 : env = uno::Environment(aEnvTypeName);
370 :
371 9444 : if (env.is() && currentEnv.is())
372 : {
373 : #if OSL_DEBUG_LEVEL > 1
374 : {
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));
378 :
379 : fprintf(stderr, "invokeComponentFactory envDcp:%s implName:%s modPath:%s\n", envDcp.getStr(), implName.getStr(), modPath.getStr());
380 : }
381 : #endif
382 :
383 9444 : Mapping aCurrent2Env( currentEnv, env );
384 18888 : Mapping aEnv2Current( env, currentEnv );
385 :
386 9444 : if (aCurrent2Env.is() && aEnv2Current.is())
387 : {
388 : void * pSMgr = aCurrent2Env.mapInterface(
389 9444 : xMgr.get(), ::getCppuType( &xMgr ) );
390 : void * pKey = aCurrent2Env.mapInterface(
391 9444 : xKey.get(), ::getCppuType( &xKey ) );
392 :
393 9444 : void * pSSF = NULL;
394 :
395 9444 : env.invoke(s_getFactory, pGetter, &aImplName, pSMgr, pKey, &pSSF);
396 :
397 9444 : if (pKey)
398 : {
399 0 : (env.get()->pExtEnv->releaseInterface)(
400 0 : env.get()->pExtEnv, pKey );
401 : }
402 9444 : if (pSMgr)
403 : {
404 9444 : (*env.get()->pExtEnv->releaseInterface)(
405 9444 : env.get()->pExtEnv, pSMgr );
406 : }
407 :
408 9444 : if (pSSF)
409 : {
410 : aEnv2Current.mapInterface(
411 : reinterpret_cast< void ** >( &xRet ),
412 9444 : pSSF, ::getCppuType( &xRet ) );
413 9444 : (env.get()->pExtEnv->releaseInterface)(
414 9444 : env.get()->pExtEnv, pSSF );
415 : }
416 : else
417 : {
418 0 : rExcMsg = rModulePath +
419 0 : ": cannot get factory of " +
420 0 : "demanded implementation: " +
421 : OStringToOUString(
422 0 : aImplName, RTL_TEXTENCODING_ASCII_US );
423 : }
424 : }
425 : else
426 : {
427 : rExcMsg =
428 0 : "cannot get uno mappings: C++ <=> UNO!";
429 9444 : }
430 : }
431 : else
432 : {
433 0 : rExcMsg = "cannot get uno environments!";
434 : }
435 :
436 18888 : return xRet;
437 : }
438 :
439 : } // namespace
440 :
441 : #ifdef DISABLE_DYNLOADING
442 : extern "C"
443 : {
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 );
467 : }
468 : #endif
469 :
470 9444 : 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 9444 : OUString sLibName(rLibName);
480 :
481 : #ifdef ANDROID
482 : if ( rLibName.equals( "bootstrap.uno" SAL_DLLEXTENSION ) )
483 : sLibName = "libbootstrap.uno" SAL_DLLEXTENSION;
484 : #endif
485 :
486 18888 : OUString aModulePath( makeComponentPath( sLibName, rPath ) );
487 9444 : if (! checkAccessPath( &aModulePath ))
488 : {
489 : OUString const msg(
490 0 : "permission denied to load component library: " + aModulePath);
491 : SAL_WARN("cppuhelper", msg);
492 : throw loader::CannotActivateFactoryException(msg,
493 0 : Reference< XInterface >() );
494 : }
495 :
496 : oslModule lib = osl_loadModule(
497 9444 : aModulePath.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
498 9444 : if (! lib)
499 : {
500 0 : OUString const msg("loading component library failed: " + aModulePath);
501 : SAL_WARN("cppuhelper", msg);
502 : throw loader::CannotActivateFactoryException(msg,
503 0 : Reference< XInterface >() );
504 : }
505 : #else
506 : (void) rPath;
507 : oslModule lib;
508 : OUString aModulePath("MAIN");
509 : if (! osl_getModuleHandle( NULL, &lib))
510 : {
511 : throw loader::CannotActivateFactoryException(
512 : "osl_getModuleHandle of the executable: ",
513 : Reference< XInterface >() );
514 : }
515 : #endif
516 :
517 9444 : Reference< XInterface > xRet;
518 :
519 18888 : OUString aExcMsg;
520 :
521 18888 : OUString aGetFactoryName = rPrefix + COMPONENT_GETFACTORY;
522 :
523 9444 : oslGenericFunction pSym = NULL;
524 :
525 : #ifdef DISABLE_DYNLOADING
526 :
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 },
535 :
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 }
567 : };
568 : for (int i = 0; pSym == NULL && non_app_specific_map[i].lib != NULL; ++i)
569 : {
570 : if ( rLibName.equalsAscii( non_app_specific_map[i].lib ) )
571 : pSym = (oslGenericFunction) non_app_specific_map[i].component_getFactory_function;
572 : }
573 :
574 : if ( pSym == NULL)
575 : {
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)
579 : {
580 : if ( rLibName.equalsAscii( map[i].lib ) )
581 : pSym = (oslGenericFunction) map[i].component_getFactory_function;
582 : }
583 : if ( pSym == NULL )
584 : {
585 : fprintf( stderr, "attempting to load unknown library %s\n", OUStringToOString( rLibName, RTL_TEXTENCODING_ASCII_US ).getStr() );
586 : assert( !"Attempt to load unknown library" );
587 : }
588 : }
589 : #else
590 :
591 9444 : if ( pSym == NULL )
592 9444 : pSym = osl_getFunctionSymbol( lib, aGetFactoryName.pData );
593 : #endif
594 :
595 9444 : if (pSym != 0)
596 : {
597 9444 : xRet = invokeComponentFactory( pSym, lib, aModulePath, rImplName, xMgr, xKey, rPrefix, aExcMsg );
598 : }
599 : else
600 : {
601 0 : aExcMsg = aModulePath;
602 0 : aExcMsg += ": cannot get symbol: ";
603 0 : aExcMsg += aGetFactoryName;
604 : }
605 :
606 9444 : if (! xRet.is())
607 : {
608 : #ifndef DISABLE_DYNLOADING
609 0 : osl_unloadModule( lib );
610 : #endif
611 : SAL_WARN("cppuhelper", "### cannot activate factory: " << aExcMsg);
612 : throw loader::CannotActivateFactoryException(
613 : aExcMsg,
614 0 : Reference< XInterface >() );
615 : }
616 18888 : return xRet;
617 : }
618 :
619 0 : 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) )
626 : {
627 0 : Reference< XInterface > xRet;
628 : oslModule pExe;
629 0 : OUString aExePath("MAIN");
630 0 : osl_getModuleHandle( NULL, &pExe );
631 0 : OUString aExcMsg;
632 :
633 0 : xRet = invokeComponentFactory( pGetter, pExe, aExePath, rImplName, xMgr, xKey, rPrefix, aExcMsg );
634 :
635 0 : if (! xRet.is())
636 : {
637 : SAL_WARN("cppuhelper", "### cannot activate factory: " << aExcMsg);
638 : throw loader::CannotActivateFactoryException(
639 : aExcMsg,
640 0 : Reference< XInterface >() );
641 : }
642 :
643 0 : return xRet;
644 : }
645 :
646 : #ifndef DISABLE_DYNLOADING
647 :
648 : //==============================================================================
649 0 : extern "C" { static void s_writeInfo(va_list * pParam)
650 : {
651 0 : component_writeInfoFunc pSym = va_arg(*pParam, component_writeInfoFunc);
652 0 : void * pSMgr = va_arg(*pParam, void *);
653 0 : void * pKey = va_arg(*pParam, void *);
654 0 : sal_Bool * pbRet = va_arg(*pParam, sal_Bool *);
655 :
656 0 : *pbRet = pSym(pSMgr, pKey);
657 :
658 0 : }}
659 :
660 0 : 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) )
665 : {
666 0 : OUString aModulePath( makeComponentPath( rLibName, rPath ) );
667 :
668 0 : if (! checkAccessPath( &aModulePath ))
669 : {
670 : OUString const msg(
671 0 : "permission denied to load component library: " + aModulePath);
672 : SAL_WARN("cppuhelper", msg);
673 : throw registry::CannotRegisterImplementationException(msg,
674 0 : Reference< XInterface >() );
675 : }
676 :
677 : oslModule lib = osl_loadModule(
678 0 : aModulePath.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
679 0 : if (! lib)
680 : {
681 0 : OUString const msg("loading component library failed: " + aModulePath);
682 : SAL_WARN("cppuhelper", msg);
683 : throw registry::CannotRegisterImplementationException(msg,
684 0 : Reference< XInterface >() );
685 : }
686 :
687 0 : sal_Bool bRet = sal_False;
688 :
689 0 : uno::Environment currentEnv(Environment::getCurrent());
690 0 : uno::Environment env;
691 :
692 0 : OUString aEnvTypeName;
693 0 : OUString aExcMsg;
694 :
695 0 : getLibEnv(lib, &env, &aEnvTypeName, currentEnv);
696 :
697 0 : OUString aWriteInfoName = COMPONENT_WRITEINFO;
698 0 : oslGenericFunction pSym = osl_getFunctionSymbol( lib, aWriteInfoName.pData );
699 0 : if (pSym != 0)
700 : {
701 0 : if (!env.is())
702 0 : env = uno::Environment(aEnvTypeName);
703 :
704 0 : if (env.is() && currentEnv.is())
705 : {
706 0 : Mapping aCurrent2Env( currentEnv, env );
707 0 : if (aCurrent2Env.is())
708 : {
709 : void * pSMgr = aCurrent2Env.mapInterface(
710 0 : xMgr.get(), ::getCppuType( &xMgr ) );
711 : void * pKey = aCurrent2Env.mapInterface(
712 0 : xKey.get(), ::getCppuType( &xKey ) );
713 0 : if (pKey)
714 : {
715 0 : env.invoke(s_writeInfo, pSym, pSMgr, pKey, &bRet);
716 :
717 :
718 0 : (*env.get()->pExtEnv->releaseInterface)(
719 0 : env.get()->pExtEnv, pKey );
720 0 : if (! bRet)
721 : {
722 0 : aExcMsg = aModulePath;
723 0 : aExcMsg += ": component_writeInfo() "
724 0 : "returned false!";
725 : }
726 : }
727 : else
728 : {
729 : // key is mandatory
730 0 : aExcMsg = aModulePath;
731 0 : aExcMsg += ": registry is mandatory to invoke"
732 0 : " component_writeInfo()!";
733 : }
734 :
735 0 : if (pSMgr)
736 : {
737 0 : (*env.get()->pExtEnv->releaseInterface)(
738 0 : env.get()->pExtEnv, pSMgr );
739 : }
740 : }
741 : else
742 : {
743 0 : aExcMsg = "cannot get uno mapping: C++ <=> UNO!";
744 0 : }
745 : }
746 : else
747 : {
748 0 : aExcMsg = "cannot get uno environments!";
749 : }
750 : }
751 : else
752 : {
753 0 : aExcMsg = aModulePath;
754 0 : aExcMsg += ": cannot get symbol: ";
755 0 : aExcMsg += aWriteInfoName;
756 : }
757 :
758 : //!
759 : //! OK: please look at #88219#
760 : //!
761 : //! ::osl_unloadModule( lib);
762 0 : if (! bRet)
763 : {
764 : SAL_WARN("cppuhelper", "### cannot write component info: " << aExcMsg);
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: */
|