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