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