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