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