xref: /aoo42x/main/cppu/source/uno/lbenv.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_cppu.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "cppu/EnvDcp.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "sal/alloca.h"
34*cdf0e10cSrcweir #include "osl/diagnose.h"
35*cdf0e10cSrcweir #include "osl/interlck.h"
36*cdf0e10cSrcweir #include "osl/mutex.hxx"
37*cdf0e10cSrcweir #include "osl/module.h"
38*cdf0e10cSrcweir #include "osl/process.h"
39*cdf0e10cSrcweir #include "rtl/process.h"
40*cdf0e10cSrcweir #include "rtl/unload.h"
41*cdf0e10cSrcweir #include "rtl/string.hxx"
42*cdf0e10cSrcweir #include "rtl/ustring.hxx"
43*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
44*cdf0e10cSrcweir #include "rtl/instance.hxx"
45*cdf0e10cSrcweir #include "typelib/typedescription.h"
46*cdf0e10cSrcweir #include "uno/dispatcher.h"
47*cdf0e10cSrcweir #include "uno/environment.h"
48*cdf0e10cSrcweir #include "uno/lbnames.h"
49*cdf0e10cSrcweir #include "prim.hxx"
50*cdf0e10cSrcweir #include "destr.hxx"
51*cdf0e10cSrcweir #include "loadmodule.hxx"
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir #include <hash_map>
54*cdf0e10cSrcweir #include <vector>
55*cdf0e10cSrcweir #include <stdio.h>
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir using ::rtl::OUString;
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir namespace
61*cdf0e10cSrcweir {
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir //------------------------------------------------------------------------------
64*cdf0e10cSrcweir inline static bool td_equals( typelib_InterfaceTypeDescription * pTD1,
65*cdf0e10cSrcweir                               typelib_InterfaceTypeDescription * pTD2 )
66*cdf0e10cSrcweir {
67*cdf0e10cSrcweir     return (pTD1 == pTD2 ||
68*cdf0e10cSrcweir             (((typelib_TypeDescription *)pTD1)->pTypeName->length ==
69*cdf0e10cSrcweir              ((typelib_TypeDescription *)pTD2)->pTypeName->length &&
70*cdf0e10cSrcweir              ::rtl_ustr_compare(
71*cdf0e10cSrcweir                  ((typelib_TypeDescription *) pTD1)->pTypeName->buffer,
72*cdf0e10cSrcweir                  ((typelib_TypeDescription *) pTD2)->pTypeName->buffer ) == 0));
73*cdf0e10cSrcweir }
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir struct ObjectEntry;
76*cdf0e10cSrcweir struct uno_DefaultEnvironment;
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir //------------------------------------------------------------------------------
79*cdf0e10cSrcweir struct InterfaceEntry
80*cdf0e10cSrcweir {
81*cdf0e10cSrcweir     sal_Int32 refCount;
82*cdf0e10cSrcweir     void * pInterface;
83*cdf0e10cSrcweir     uno_freeProxyFunc fpFreeProxy;
84*cdf0e10cSrcweir     typelib_InterfaceTypeDescription * pTypeDescr;
85*cdf0e10cSrcweir };
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir struct ObjectEntry
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir     OUString oid;
90*cdf0e10cSrcweir     sal_Int32 nRef;
91*cdf0e10cSrcweir     ::std::vector< InterfaceEntry > aInterfaces;
92*cdf0e10cSrcweir     bool mixedObject;
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir     inline ObjectEntry( const OUString & rOId_ );
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir     inline void append(
97*cdf0e10cSrcweir         uno_DefaultEnvironment * pEnv,
98*cdf0e10cSrcweir         void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
99*cdf0e10cSrcweir         uno_freeProxyFunc fpFreeProxy );
100*cdf0e10cSrcweir     inline InterfaceEntry * find(
101*cdf0e10cSrcweir         typelib_InterfaceTypeDescription * pTypeDescr );
102*cdf0e10cSrcweir     inline sal_Int32 find( void * iface_ptr, ::std::size_t pos );
103*cdf0e10cSrcweir };
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir //------------------------------------------------------------------------------
106*cdf0e10cSrcweir struct FctPtrHash :
107*cdf0e10cSrcweir     public ::std::unary_function< const void *, ::std::size_t >
108*cdf0e10cSrcweir {
109*cdf0e10cSrcweir     ::std::size_t operator () ( const void * pKey ) const
110*cdf0e10cSrcweir         { return (::std::size_t) pKey; }
111*cdf0e10cSrcweir };
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir //------------------------------------------------------------------------------
114*cdf0e10cSrcweir struct FctOUStringHash :
115*cdf0e10cSrcweir     public ::std::unary_function< const OUString &, ::std::size_t >
116*cdf0e10cSrcweir {
117*cdf0e10cSrcweir     ::std::size_t operator () ( const OUString & rKey ) const
118*cdf0e10cSrcweir         { return rKey.hashCode(); }
119*cdf0e10cSrcweir };
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir // mapping from environment name to environment
122*cdf0e10cSrcweir typedef ::std::hash_map<
123*cdf0e10cSrcweir     OUString, uno_Environment *, FctOUStringHash,
124*cdf0e10cSrcweir     ::std::equal_to< OUString > > OUString2EnvironmentMap;
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir // mapping from ptr to object entry
127*cdf0e10cSrcweir typedef ::std::hash_map<
128*cdf0e10cSrcweir     void *, ObjectEntry *, FctPtrHash,
129*cdf0e10cSrcweir     ::std::equal_to< void * > > Ptr2ObjectMap;
130*cdf0e10cSrcweir // mapping from oid to object entry
131*cdf0e10cSrcweir typedef ::std::hash_map<
132*cdf0e10cSrcweir     OUString, ObjectEntry *, FctOUStringHash,
133*cdf0e10cSrcweir     ::std::equal_to< OUString > > OId2ObjectMap;
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir //==============================================================================
137*cdf0e10cSrcweir struct EnvironmentsData
138*cdf0e10cSrcweir {
139*cdf0e10cSrcweir     ::osl::Mutex mutex;
140*cdf0e10cSrcweir     OUString2EnvironmentMap aName2EnvMap;
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir     EnvironmentsData() : isDisposing(false) {}
143*cdf0e10cSrcweir     ~EnvironmentsData();
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir     inline void getEnvironment(
146*cdf0e10cSrcweir         uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext );
147*cdf0e10cSrcweir     inline void registerEnvironment( uno_Environment ** ppEnv );
148*cdf0e10cSrcweir     inline void getRegisteredEnvironments(
149*cdf0e10cSrcweir         uno_Environment *** pppEnvs, sal_Int32 * pnLen,
150*cdf0e10cSrcweir         uno_memAlloc memAlloc, const OUString & rEnvDcp );
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir     bool isDisposing;
153*cdf0e10cSrcweir };
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir namespace
156*cdf0e10cSrcweir {
157*cdf0e10cSrcweir     struct theEnvironmentsData : public rtl::Static< EnvironmentsData, theEnvironmentsData > {};
158*cdf0e10cSrcweir }
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir //==============================================================================
161*cdf0e10cSrcweir struct uno_DefaultEnvironment : public uno_ExtEnvironment
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir     sal_Int32 nRef;
164*cdf0e10cSrcweir     sal_Int32 nWeakRef;
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir     ::osl::Mutex mutex;
167*cdf0e10cSrcweir     Ptr2ObjectMap aPtr2ObjectMap;
168*cdf0e10cSrcweir     OId2ObjectMap aOId2ObjectMap;
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir     uno_DefaultEnvironment(
171*cdf0e10cSrcweir         const OUString & rEnvDcp_, void * pContext_ );
172*cdf0e10cSrcweir     ~uno_DefaultEnvironment();
173*cdf0e10cSrcweir };
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir //______________________________________________________________________________
176*cdf0e10cSrcweir inline ObjectEntry::ObjectEntry( OUString const & rOId_ )
177*cdf0e10cSrcweir     : oid( rOId_ ),
178*cdf0e10cSrcweir       nRef( 0 ),
179*cdf0e10cSrcweir       mixedObject( false )
180*cdf0e10cSrcweir {
181*cdf0e10cSrcweir     aInterfaces.reserve( 2 );
182*cdf0e10cSrcweir }
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir //______________________________________________________________________________
185*cdf0e10cSrcweir inline void ObjectEntry::append(
186*cdf0e10cSrcweir     uno_DefaultEnvironment * pEnv,
187*cdf0e10cSrcweir     void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
188*cdf0e10cSrcweir     uno_freeProxyFunc fpFreeProxy )
189*cdf0e10cSrcweir {
190*cdf0e10cSrcweir     InterfaceEntry aNewEntry;
191*cdf0e10cSrcweir     if (! fpFreeProxy)
192*cdf0e10cSrcweir         (*pEnv->acquireInterface)( pEnv, pInterface );
193*cdf0e10cSrcweir     aNewEntry.refCount = 1;
194*cdf0e10cSrcweir     aNewEntry.pInterface = pInterface;
195*cdf0e10cSrcweir     aNewEntry.fpFreeProxy = fpFreeProxy;
196*cdf0e10cSrcweir     typelib_typedescription_acquire( (typelib_TypeDescription *) pTypeDescr );
197*cdf0e10cSrcweir     aNewEntry.pTypeDescr = pTypeDescr;
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir     ::std::pair< Ptr2ObjectMap::iterator, bool > insertion(
200*cdf0e10cSrcweir         pEnv->aPtr2ObjectMap.insert( Ptr2ObjectMap::value_type(
201*cdf0e10cSrcweir                                          pInterface, this ) ) );
202*cdf0e10cSrcweir     OSL_ASSERT( insertion.second ||
203*cdf0e10cSrcweir                 (find( pInterface, 0 ) >= 0 &&
204*cdf0e10cSrcweir                  // points to the same object entry:
205*cdf0e10cSrcweir                  insertion.first->second == this) );
206*cdf0e10cSrcweir     aInterfaces.push_back( aNewEntry );
207*cdf0e10cSrcweir }
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir //______________________________________________________________________________
210*cdf0e10cSrcweir inline InterfaceEntry * ObjectEntry::find(
211*cdf0e10cSrcweir     typelib_InterfaceTypeDescription * pTypeDescr_ )
212*cdf0e10cSrcweir {
213*cdf0e10cSrcweir     OSL_ASSERT( ! aInterfaces.empty() );
214*cdf0e10cSrcweir     if (aInterfaces.empty())
215*cdf0e10cSrcweir         return 0;
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir     // shortcut common case:
218*cdf0e10cSrcweir     OUString const & type_name =
219*cdf0e10cSrcweir         OUString::unacquired(
220*cdf0e10cSrcweir             &((typelib_TypeDescription *) pTypeDescr_)->pTypeName );
221*cdf0e10cSrcweir     if (type_name.equalsAsciiL(
222*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ))
223*cdf0e10cSrcweir     {
224*cdf0e10cSrcweir         return &aInterfaces[ 0 ];
225*cdf0e10cSrcweir     }
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir     ::std::size_t nSize = aInterfaces.size();
228*cdf0e10cSrcweir     for ( ::std::size_t nPos = 0; nPos < nSize; ++nPos )
229*cdf0e10cSrcweir     {
230*cdf0e10cSrcweir         typelib_InterfaceTypeDescription * pITD =
231*cdf0e10cSrcweir             aInterfaces[ nPos ].pTypeDescr;
232*cdf0e10cSrcweir         while (pITD)
233*cdf0e10cSrcweir         {
234*cdf0e10cSrcweir             if (td_equals( pITD, pTypeDescr_ ))
235*cdf0e10cSrcweir                 return &aInterfaces[ nPos ];
236*cdf0e10cSrcweir             pITD = pITD->pBaseTypeDescription;
237*cdf0e10cSrcweir         }
238*cdf0e10cSrcweir     }
239*cdf0e10cSrcweir     return 0;
240*cdf0e10cSrcweir }
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir //______________________________________________________________________________
243*cdf0e10cSrcweir inline sal_Int32 ObjectEntry::find(
244*cdf0e10cSrcweir     void * iface_ptr, ::std::size_t pos )
245*cdf0e10cSrcweir {
246*cdf0e10cSrcweir     ::std::size_t size = aInterfaces.size();
247*cdf0e10cSrcweir     for ( ; pos < size; ++pos )
248*cdf0e10cSrcweir     {
249*cdf0e10cSrcweir         if (aInterfaces[ pos ].pInterface == iface_ptr)
250*cdf0e10cSrcweir             return pos;
251*cdf0e10cSrcweir     }
252*cdf0e10cSrcweir     return -1;
253*cdf0e10cSrcweir }
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir extern "C"
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir //------------------------------------------------------------------------------
259*cdf0e10cSrcweir static void SAL_CALL defenv_registerInterface(
260*cdf0e10cSrcweir     uno_ExtEnvironment * pEnv, void ** ppInterface,
261*cdf0e10cSrcweir     rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
262*cdf0e10cSrcweir {
263*cdf0e10cSrcweir     OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
264*cdf0e10cSrcweir     OUString const & rOId = OUString::unacquired( &pOId );
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir     uno_DefaultEnvironment * that =
267*cdf0e10cSrcweir         static_cast< uno_DefaultEnvironment * >( pEnv );
268*cdf0e10cSrcweir     ::osl::ClearableMutexGuard guard( that->mutex );
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir     // try to insert dummy 0:
271*cdf0e10cSrcweir     std::pair<OId2ObjectMap::iterator, bool> const insertion(
272*cdf0e10cSrcweir         that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, 0 ) ) );
273*cdf0e10cSrcweir     if (insertion.second)
274*cdf0e10cSrcweir     {
275*cdf0e10cSrcweir         ObjectEntry * pOEntry = new ObjectEntry( rOId );
276*cdf0e10cSrcweir         insertion.first->second = pOEntry;
277*cdf0e10cSrcweir         ++pOEntry->nRef; // another register call on object
278*cdf0e10cSrcweir         pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
279*cdf0e10cSrcweir     }
280*cdf0e10cSrcweir     else // object entry exists
281*cdf0e10cSrcweir     {
282*cdf0e10cSrcweir         ObjectEntry * pOEntry = insertion.first->second;
283*cdf0e10cSrcweir         ++pOEntry->nRef; // another register call on object
284*cdf0e10cSrcweir         InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir         if (pIEntry) // type entry exists
287*cdf0e10cSrcweir         {
288*cdf0e10cSrcweir             ++pIEntry->refCount;
289*cdf0e10cSrcweir             if (pIEntry->pInterface != *ppInterface)
290*cdf0e10cSrcweir             {
291*cdf0e10cSrcweir                 void * pInterface = pIEntry->pInterface;
292*cdf0e10cSrcweir                 (*pEnv->acquireInterface)( pEnv, pInterface );
293*cdf0e10cSrcweir                 guard.clear();
294*cdf0e10cSrcweir                 (*pEnv->releaseInterface)( pEnv, *ppInterface );
295*cdf0e10cSrcweir                 *ppInterface = pInterface;
296*cdf0e10cSrcweir             }
297*cdf0e10cSrcweir         }
298*cdf0e10cSrcweir         else
299*cdf0e10cSrcweir         {
300*cdf0e10cSrcweir             pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
301*cdf0e10cSrcweir         }
302*cdf0e10cSrcweir     }
303*cdf0e10cSrcweir }
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir //------------------------------------------------------------------------------
306*cdf0e10cSrcweir static void SAL_CALL defenv_registerProxyInterface(
307*cdf0e10cSrcweir     uno_ExtEnvironment * pEnv, void ** ppInterface, uno_freeProxyFunc freeProxy,
308*cdf0e10cSrcweir     rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
309*cdf0e10cSrcweir {
310*cdf0e10cSrcweir     OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr && freeProxy,
311*cdf0e10cSrcweir                 "### null ptr!" );
312*cdf0e10cSrcweir     OUString const & rOId = OUString::unacquired( &pOId );
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir     uno_DefaultEnvironment * that =
315*cdf0e10cSrcweir         static_cast< uno_DefaultEnvironment * >( pEnv );
316*cdf0e10cSrcweir     ::osl::ClearableMutexGuard guard( that->mutex );
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir     // try to insert dummy 0:
319*cdf0e10cSrcweir     std::pair<OId2ObjectMap::iterator, bool> const insertion(
320*cdf0e10cSrcweir         that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, 0 ) ) );
321*cdf0e10cSrcweir     if (insertion.second)
322*cdf0e10cSrcweir     {
323*cdf0e10cSrcweir         ObjectEntry * pOEntry = new ObjectEntry( rOId );
324*cdf0e10cSrcweir         insertion.first->second = pOEntry;
325*cdf0e10cSrcweir         ++pOEntry->nRef; // another register call on object
326*cdf0e10cSrcweir         pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
327*cdf0e10cSrcweir     }
328*cdf0e10cSrcweir     else // object entry exists
329*cdf0e10cSrcweir     {
330*cdf0e10cSrcweir         ObjectEntry * pOEntry = insertion.first->second;
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir         // first registration was an original, then registerProxyInterface():
333*cdf0e10cSrcweir         pOEntry->mixedObject |=
334*cdf0e10cSrcweir             (!pOEntry->aInterfaces.empty() &&
335*cdf0e10cSrcweir              pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0);
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir         ++pOEntry->nRef; // another register call on object
338*cdf0e10cSrcweir         InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir         if (pIEntry) // type entry exists
341*cdf0e10cSrcweir         {
342*cdf0e10cSrcweir             if (pIEntry->pInterface == *ppInterface)
343*cdf0e10cSrcweir             {
344*cdf0e10cSrcweir                 ++pIEntry->refCount;
345*cdf0e10cSrcweir             }
346*cdf0e10cSrcweir             else
347*cdf0e10cSrcweir             {
348*cdf0e10cSrcweir                 void * pInterface = pIEntry->pInterface;
349*cdf0e10cSrcweir                 (*pEnv->acquireInterface)( pEnv, pInterface );
350*cdf0e10cSrcweir                 --pOEntry->nRef; // manual revoke of proxy to be freed
351*cdf0e10cSrcweir                 guard.clear();
352*cdf0e10cSrcweir                 (*freeProxy)( pEnv, *ppInterface );
353*cdf0e10cSrcweir                 *ppInterface = pInterface;
354*cdf0e10cSrcweir             }
355*cdf0e10cSrcweir         }
356*cdf0e10cSrcweir         else
357*cdf0e10cSrcweir         {
358*cdf0e10cSrcweir             pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
359*cdf0e10cSrcweir         }
360*cdf0e10cSrcweir     }
361*cdf0e10cSrcweir }
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir //------------------------------------------------------------------------------
364*cdf0e10cSrcweir static void SAL_CALL s_stub_defenv_revokeInterface(va_list * pParam)
365*cdf0e10cSrcweir {
366*cdf0e10cSrcweir 	uno_ExtEnvironment * pEnv       = va_arg(*pParam, uno_ExtEnvironment *);
367*cdf0e10cSrcweir 	void               * pInterface = va_arg(*pParam, void *);
368*cdf0e10cSrcweir 
369*cdf0e10cSrcweir     OSL_ENSURE( pEnv && pInterface, "### null ptr!" );
370*cdf0e10cSrcweir     uno_DefaultEnvironment * that =
371*cdf0e10cSrcweir         static_cast< uno_DefaultEnvironment * >( pEnv );
372*cdf0e10cSrcweir     ::osl::ClearableMutexGuard guard( that->mutex );
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir     Ptr2ObjectMap::const_iterator const iFind(
375*cdf0e10cSrcweir         that->aPtr2ObjectMap.find( pInterface ) );
376*cdf0e10cSrcweir     OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() );
377*cdf0e10cSrcweir     ObjectEntry * pOEntry = iFind->second;
378*cdf0e10cSrcweir     if (! --pOEntry->nRef)
379*cdf0e10cSrcweir     {
380*cdf0e10cSrcweir         // cleanup maps
381*cdf0e10cSrcweir         that->aOId2ObjectMap.erase( pOEntry->oid );
382*cdf0e10cSrcweir         sal_Int32 nPos;
383*cdf0e10cSrcweir         for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
384*cdf0e10cSrcweir         {
385*cdf0e10cSrcweir             that->aPtr2ObjectMap.erase( pOEntry->aInterfaces[nPos].pInterface );
386*cdf0e10cSrcweir         }
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir         // the last proxy interface of the environment might kill this
389*cdf0e10cSrcweir         // environment, because of releasing its language binding!!!
390*cdf0e10cSrcweir         guard.clear();
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir         // release interfaces
393*cdf0e10cSrcweir         for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
394*cdf0e10cSrcweir         {
395*cdf0e10cSrcweir             InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos];
396*cdf0e10cSrcweir             typelib_typedescription_release(
397*cdf0e10cSrcweir                 (typelib_TypeDescription *) rEntry.pTypeDescr );
398*cdf0e10cSrcweir             if (rEntry.fpFreeProxy) // is proxy or used interface?
399*cdf0e10cSrcweir             {
400*cdf0e10cSrcweir                 (*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface );
401*cdf0e10cSrcweir             }
402*cdf0e10cSrcweir             else
403*cdf0e10cSrcweir             {
404*cdf0e10cSrcweir                 (*pEnv->releaseInterface)( pEnv, rEntry.pInterface );
405*cdf0e10cSrcweir             }
406*cdf0e10cSrcweir         }
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir         delete pOEntry;
409*cdf0e10cSrcweir     }
410*cdf0e10cSrcweir     else if (pOEntry->mixedObject)
411*cdf0e10cSrcweir     {
412*cdf0e10cSrcweir         OSL_ASSERT( !pOEntry->aInterfaces.empty() &&
413*cdf0e10cSrcweir                     pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0 );
414*cdf0e10cSrcweir 
415*cdf0e10cSrcweir         sal_Int32 index = pOEntry->find( pInterface, 1 );
416*cdf0e10cSrcweir         OSL_ASSERT( index > 0 );
417*cdf0e10cSrcweir         if (index > 0)
418*cdf0e10cSrcweir         {
419*cdf0e10cSrcweir             InterfaceEntry & entry = pOEntry->aInterfaces[ index ];
420*cdf0e10cSrcweir             OSL_ASSERT( entry.pInterface == pInterface );
421*cdf0e10cSrcweir             if (entry.fpFreeProxy != 0)
422*cdf0e10cSrcweir             {
423*cdf0e10cSrcweir                 --entry.refCount;
424*cdf0e10cSrcweir                 if (entry.refCount == 0)
425*cdf0e10cSrcweir                 {
426*cdf0e10cSrcweir                     uno_freeProxyFunc fpFreeProxy = entry.fpFreeProxy;
427*cdf0e10cSrcweir                     typelib_TypeDescription * pTypeDescr =
428*cdf0e10cSrcweir                         reinterpret_cast< typelib_TypeDescription * >(
429*cdf0e10cSrcweir                             entry.pTypeDescr );
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir                     pOEntry->aInterfaces.erase(
432*cdf0e10cSrcweir                         pOEntry->aInterfaces.begin() + index );
433*cdf0e10cSrcweir                     if (pOEntry->find( pInterface, index ) < 0)
434*cdf0e10cSrcweir                     {
435*cdf0e10cSrcweir                         // proxy ptr not registered for another interface:
436*cdf0e10cSrcweir                         // remove from ptr map
437*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
438*cdf0e10cSrcweir                         ::std::size_t erased =
439*cdf0e10cSrcweir #endif
440*cdf0e10cSrcweir                               that->aPtr2ObjectMap.erase( pInterface );
441*cdf0e10cSrcweir                         OSL_ASSERT( erased == 1 );
442*cdf0e10cSrcweir                     }
443*cdf0e10cSrcweir 
444*cdf0e10cSrcweir                     guard.clear();
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir                     typelib_typedescription_release( pTypeDescr );
447*cdf0e10cSrcweir                     (*fpFreeProxy)( pEnv, pInterface );
448*cdf0e10cSrcweir                 }
449*cdf0e10cSrcweir             }
450*cdf0e10cSrcweir         }
451*cdf0e10cSrcweir     }
452*cdf0e10cSrcweir }
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir static void SAL_CALL defenv_revokeInterface(uno_ExtEnvironment * pEnv, void * pInterface)
455*cdf0e10cSrcweir {
456*cdf0e10cSrcweir 	uno_Environment_invoke(&pEnv->aBase, s_stub_defenv_revokeInterface, pEnv, pInterface);
457*cdf0e10cSrcweir }
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir //------------------------------------------------------------------------------
460*cdf0e10cSrcweir static void SAL_CALL defenv_getObjectIdentifier(
461*cdf0e10cSrcweir     uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
462*cdf0e10cSrcweir {
463*cdf0e10cSrcweir     OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
464*cdf0e10cSrcweir     if (*ppOId)
465*cdf0e10cSrcweir     {
466*cdf0e10cSrcweir         ::rtl_uString_release( *ppOId );
467*cdf0e10cSrcweir         *ppOId = 0;
468*cdf0e10cSrcweir     }
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir     uno_DefaultEnvironment * that =
471*cdf0e10cSrcweir         static_cast< uno_DefaultEnvironment * >( pEnv );
472*cdf0e10cSrcweir     ::osl::ClearableMutexGuard guard( that->mutex );
473*cdf0e10cSrcweir 
474*cdf0e10cSrcweir     Ptr2ObjectMap::const_iterator const iFind(
475*cdf0e10cSrcweir         that->aPtr2ObjectMap.find( pInterface ) );
476*cdf0e10cSrcweir     if (iFind == that->aPtr2ObjectMap.end())
477*cdf0e10cSrcweir     {
478*cdf0e10cSrcweir         guard.clear();
479*cdf0e10cSrcweir         (*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface );
480*cdf0e10cSrcweir     }
481*cdf0e10cSrcweir     else
482*cdf0e10cSrcweir     {
483*cdf0e10cSrcweir         rtl_uString * hstr = iFind->second->oid.pData;
484*cdf0e10cSrcweir         rtl_uString_acquire( hstr );
485*cdf0e10cSrcweir         *ppOId = hstr;
486*cdf0e10cSrcweir     }
487*cdf0e10cSrcweir }
488*cdf0e10cSrcweir 
489*cdf0e10cSrcweir //------------------------------------------------------------------------------
490*cdf0e10cSrcweir static void SAL_CALL defenv_getRegisteredInterface(
491*cdf0e10cSrcweir     uno_ExtEnvironment * pEnv, void ** ppInterface,
492*cdf0e10cSrcweir     rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
493*cdf0e10cSrcweir {
494*cdf0e10cSrcweir     OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
495*cdf0e10cSrcweir     if (*ppInterface)
496*cdf0e10cSrcweir     {
497*cdf0e10cSrcweir         (*pEnv->releaseInterface)( pEnv, *ppInterface );
498*cdf0e10cSrcweir         *ppInterface = 0;
499*cdf0e10cSrcweir     }
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir     OUString const & rOId = OUString::unacquired( &pOId );
502*cdf0e10cSrcweir     uno_DefaultEnvironment * that =
503*cdf0e10cSrcweir         static_cast< uno_DefaultEnvironment * >( pEnv );
504*cdf0e10cSrcweir     ::osl::MutexGuard guard( that->mutex );
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir     OId2ObjectMap::const_iterator const iFind
507*cdf0e10cSrcweir         ( that->aOId2ObjectMap.find( rOId ) );
508*cdf0e10cSrcweir     if (iFind != that->aOId2ObjectMap.end())
509*cdf0e10cSrcweir     {
510*cdf0e10cSrcweir         InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr );
511*cdf0e10cSrcweir         if (pIEntry)
512*cdf0e10cSrcweir         {
513*cdf0e10cSrcweir             (*pEnv->acquireInterface)( pEnv, pIEntry->pInterface );
514*cdf0e10cSrcweir             *ppInterface = pIEntry->pInterface;
515*cdf0e10cSrcweir         }
516*cdf0e10cSrcweir     }
517*cdf0e10cSrcweir }
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir //------------------------------------------------------------------------------
520*cdf0e10cSrcweir static void SAL_CALL defenv_getRegisteredInterfaces(
521*cdf0e10cSrcweir     uno_ExtEnvironment * pEnv, void *** pppInterfaces, sal_Int32 * pnLen,
522*cdf0e10cSrcweir     uno_memAlloc memAlloc )
523*cdf0e10cSrcweir {
524*cdf0e10cSrcweir     OSL_ENSURE( pEnv && pppInterfaces && pnLen && memAlloc, "### null ptr!" );
525*cdf0e10cSrcweir     uno_DefaultEnvironment * that =
526*cdf0e10cSrcweir         static_cast< uno_DefaultEnvironment * >( pEnv );
527*cdf0e10cSrcweir     ::osl::MutexGuard guard( that->mutex );
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir     sal_Int32 nLen = that->aPtr2ObjectMap.size();
530*cdf0e10cSrcweir     sal_Int32 nPos = 0;
531*cdf0e10cSrcweir     void ** ppInterfaces = (void **) (*memAlloc)( nLen * sizeof (void *) );
532*cdf0e10cSrcweir 
533*cdf0e10cSrcweir     Ptr2ObjectMap::const_iterator iPos( that->aPtr2ObjectMap.begin() );
534*cdf0e10cSrcweir     Ptr2ObjectMap::const_iterator const iEnd( that->aPtr2ObjectMap.end() );
535*cdf0e10cSrcweir     while (iPos != iEnd)
536*cdf0e10cSrcweir     {
537*cdf0e10cSrcweir         (*pEnv->acquireInterface)( pEnv, ppInterfaces[nPos++] = (*iPos).first );
538*cdf0e10cSrcweir         ++iPos;
539*cdf0e10cSrcweir     }
540*cdf0e10cSrcweir 
541*cdf0e10cSrcweir     *pppInterfaces = ppInterfaces;
542*cdf0e10cSrcweir     *pnLen = nLen;
543*cdf0e10cSrcweir }
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir //------------------------------------------------------------------------------
546*cdf0e10cSrcweir static void SAL_CALL defenv_acquire( uno_Environment * pEnv )
547*cdf0e10cSrcweir {
548*cdf0e10cSrcweir     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
549*cdf0e10cSrcweir     ::osl_incrementInterlockedCount( &that->nWeakRef );
550*cdf0e10cSrcweir     ::osl_incrementInterlockedCount( &that->nRef );
551*cdf0e10cSrcweir }
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir //------------------------------------------------------------------------------
554*cdf0e10cSrcweir static void SAL_CALL defenv_release( uno_Environment * pEnv )
555*cdf0e10cSrcweir {
556*cdf0e10cSrcweir     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
557*cdf0e10cSrcweir     if (! ::osl_decrementInterlockedCount( &that->nRef ))
558*cdf0e10cSrcweir     {
559*cdf0e10cSrcweir         // invoke dispose callback
560*cdf0e10cSrcweir         if (pEnv->environmentDisposing)
561*cdf0e10cSrcweir         {
562*cdf0e10cSrcweir             (*pEnv->environmentDisposing)( pEnv );
563*cdf0e10cSrcweir         }
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir         OSL_ENSURE( that->aOId2ObjectMap.empty(), "### object entries left!" );
566*cdf0e10cSrcweir     }
567*cdf0e10cSrcweir     // free memory if no weak refs left
568*cdf0e10cSrcweir     if (! ::osl_decrementInterlockedCount( &that->nWeakRef ))
569*cdf0e10cSrcweir     {
570*cdf0e10cSrcweir         delete that;
571*cdf0e10cSrcweir     }
572*cdf0e10cSrcweir }
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir //------------------------------------------------------------------------------
575*cdf0e10cSrcweir static void SAL_CALL defenv_acquireWeak( uno_Environment * pEnv )
576*cdf0e10cSrcweir {
577*cdf0e10cSrcweir     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
578*cdf0e10cSrcweir     ::osl_incrementInterlockedCount( &that->nWeakRef );
579*cdf0e10cSrcweir }
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir //------------------------------------------------------------------------------
582*cdf0e10cSrcweir static void SAL_CALL defenv_releaseWeak( uno_Environment * pEnv )
583*cdf0e10cSrcweir {
584*cdf0e10cSrcweir     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
585*cdf0e10cSrcweir     if (! ::osl_decrementInterlockedCount( &that->nWeakRef ))
586*cdf0e10cSrcweir     {
587*cdf0e10cSrcweir         delete that;
588*cdf0e10cSrcweir     }
589*cdf0e10cSrcweir }
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir //------------------------------------------------------------------------------
592*cdf0e10cSrcweir static void SAL_CALL defenv_harden(
593*cdf0e10cSrcweir     uno_Environment ** ppHardEnv, uno_Environment * pEnv )
594*cdf0e10cSrcweir {
595*cdf0e10cSrcweir     if (*ppHardEnv)
596*cdf0e10cSrcweir     {
597*cdf0e10cSrcweir         (*(*ppHardEnv)->release)( *ppHardEnv );
598*cdf0e10cSrcweir         *ppHardEnv = 0;
599*cdf0e10cSrcweir     }
600*cdf0e10cSrcweir 
601*cdf0e10cSrcweir     EnvironmentsData & rData = theEnvironmentsData::get();
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir     if (rData.isDisposing)
604*cdf0e10cSrcweir         return;
605*cdf0e10cSrcweir 
606*cdf0e10cSrcweir     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
607*cdf0e10cSrcweir     {
608*cdf0e10cSrcweir     ::osl::MutexGuard guard( rData.mutex );
609*cdf0e10cSrcweir     if (1 == ::osl_incrementInterlockedCount( &that->nRef )) // is dead
610*cdf0e10cSrcweir     {
611*cdf0e10cSrcweir         that->nRef = 0;
612*cdf0e10cSrcweir         return;
613*cdf0e10cSrcweir     }
614*cdf0e10cSrcweir     }
615*cdf0e10cSrcweir     ::osl_incrementInterlockedCount( &that->nWeakRef );
616*cdf0e10cSrcweir     *ppHardEnv = pEnv;
617*cdf0e10cSrcweir }
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir //------------------------------------------------------------------------------
620*cdf0e10cSrcweir static void SAL_CALL defenv_dispose( uno_Environment * )
621*cdf0e10cSrcweir {
622*cdf0e10cSrcweir }
623*cdf0e10cSrcweir }
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir //______________________________________________________________________________
626*cdf0e10cSrcweir uno_DefaultEnvironment::uno_DefaultEnvironment(
627*cdf0e10cSrcweir     const OUString & rEnvDcp_, void * pContext_ )
628*cdf0e10cSrcweir     : nRef( 0 ),
629*cdf0e10cSrcweir       nWeakRef( 0 )
630*cdf0e10cSrcweir {
631*cdf0e10cSrcweir     uno_Environment * that = reinterpret_cast< uno_Environment * >(this);
632*cdf0e10cSrcweir     that->pReserved = 0;
633*cdf0e10cSrcweir     // functions
634*cdf0e10cSrcweir     that->acquire = defenv_acquire;
635*cdf0e10cSrcweir     that->release = defenv_release;
636*cdf0e10cSrcweir     that->acquireWeak = defenv_acquireWeak;
637*cdf0e10cSrcweir     that->releaseWeak = defenv_releaseWeak;
638*cdf0e10cSrcweir     that->harden = defenv_harden;
639*cdf0e10cSrcweir     that->dispose = defenv_dispose;
640*cdf0e10cSrcweir     that->pExtEnv = this;
641*cdf0e10cSrcweir     // identifier
642*cdf0e10cSrcweir     ::rtl_uString_acquire( rEnvDcp_.pData );
643*cdf0e10cSrcweir     that->pTypeName = rEnvDcp_.pData;
644*cdf0e10cSrcweir     that->pContext = pContext_;
645*cdf0e10cSrcweir 
646*cdf0e10cSrcweir     // will be late initialized
647*cdf0e10cSrcweir     that->environmentDisposing = 0;
648*cdf0e10cSrcweir 
649*cdf0e10cSrcweir     uno_ExtEnvironment::registerInterface = defenv_registerInterface;
650*cdf0e10cSrcweir     uno_ExtEnvironment::registerProxyInterface = defenv_registerProxyInterface;
651*cdf0e10cSrcweir     uno_ExtEnvironment::revokeInterface = defenv_revokeInterface;
652*cdf0e10cSrcweir     uno_ExtEnvironment::getObjectIdentifier = defenv_getObjectIdentifier;
653*cdf0e10cSrcweir     uno_ExtEnvironment::getRegisteredInterface = defenv_getRegisteredInterface;
654*cdf0e10cSrcweir     uno_ExtEnvironment::getRegisteredInterfaces =
655*cdf0e10cSrcweir         defenv_getRegisteredInterfaces;
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir }
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir //______________________________________________________________________________
660*cdf0e10cSrcweir uno_DefaultEnvironment::~uno_DefaultEnvironment()
661*cdf0e10cSrcweir {
662*cdf0e10cSrcweir     ::rtl_uString_release( ((uno_Environment *) this)->pTypeName );
663*cdf0e10cSrcweir }
664*cdf0e10cSrcweir 
665*cdf0e10cSrcweir //==============================================================================
666*cdf0e10cSrcweir static void writeLine(
667*cdf0e10cSrcweir     void * stream, const sal_Char * pLine, const sal_Char * pFilter )
668*cdf0e10cSrcweir {
669*cdf0e10cSrcweir     if (pFilter && *pFilter)
670*cdf0e10cSrcweir     {
671*cdf0e10cSrcweir         // lookup pFilter in pLine
672*cdf0e10cSrcweir         while (*pLine)
673*cdf0e10cSrcweir         {
674*cdf0e10cSrcweir             if (*pLine == *pFilter)
675*cdf0e10cSrcweir             {
676*cdf0e10cSrcweir                 sal_Int32 nPos = 1;
677*cdf0e10cSrcweir                 while (pLine[nPos] && pFilter[nPos] == pLine[nPos])
678*cdf0e10cSrcweir                 {
679*cdf0e10cSrcweir                     ++nPos;
680*cdf0e10cSrcweir                 }
681*cdf0e10cSrcweir                 if (! pFilter[nPos])
682*cdf0e10cSrcweir                 {
683*cdf0e10cSrcweir                     if (stream)
684*cdf0e10cSrcweir                     {
685*cdf0e10cSrcweir                         fprintf( (FILE *) stream, "%s\n", pLine );
686*cdf0e10cSrcweir                     }
687*cdf0e10cSrcweir                     else
688*cdf0e10cSrcweir                     {
689*cdf0e10cSrcweir                         OSL_TRACE( pLine );
690*cdf0e10cSrcweir                         OSL_TRACE( "\n" );
691*cdf0e10cSrcweir                     }
692*cdf0e10cSrcweir                 }
693*cdf0e10cSrcweir             }
694*cdf0e10cSrcweir             ++pLine;
695*cdf0e10cSrcweir         }
696*cdf0e10cSrcweir     }
697*cdf0e10cSrcweir     else
698*cdf0e10cSrcweir     {
699*cdf0e10cSrcweir         if (stream)
700*cdf0e10cSrcweir         {
701*cdf0e10cSrcweir             fprintf( (FILE *) stream, "%s\n", pLine );
702*cdf0e10cSrcweir         }
703*cdf0e10cSrcweir         else
704*cdf0e10cSrcweir         {
705*cdf0e10cSrcweir             fprintf( stderr, "%s\n", pLine );
706*cdf0e10cSrcweir         }
707*cdf0e10cSrcweir     }
708*cdf0e10cSrcweir }
709*cdf0e10cSrcweir 
710*cdf0e10cSrcweir //==============================================================================
711*cdf0e10cSrcweir static void writeLine(
712*cdf0e10cSrcweir     void * stream, const OUString & rLine, const sal_Char * pFilter )
713*cdf0e10cSrcweir {
714*cdf0e10cSrcweir     ::rtl::OString aLine( ::rtl::OUStringToOString(
715*cdf0e10cSrcweir                               rLine, RTL_TEXTENCODING_ASCII_US ) );
716*cdf0e10cSrcweir     writeLine( stream, aLine.getStr(), pFilter );
717*cdf0e10cSrcweir }
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir //##############################################################################
720*cdf0e10cSrcweir extern "C" void SAL_CALL uno_dumpEnvironment(
721*cdf0e10cSrcweir     void * stream, uno_Environment * pEnv, const sal_Char * pFilter )
722*cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
723*cdf0e10cSrcweir {
724*cdf0e10cSrcweir     OSL_ENSURE( pEnv, "### null ptr!" );
725*cdf0e10cSrcweir     ::rtl::OUStringBuffer buf;
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir     if (! pEnv->pExtEnv)
728*cdf0e10cSrcweir     {
729*cdf0e10cSrcweir         writeLine( stream, "###################################"
730*cdf0e10cSrcweir                    "###########################################", pFilter );
731*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment: ") );
732*cdf0e10cSrcweir         buf.append( pEnv->pTypeName );
733*cdf0e10cSrcweir         writeLine( stream, buf.makeStringAndClear(), pFilter );
734*cdf0e10cSrcweir         writeLine( stream, "NO INTERFACE INFORMATION AVAILABLE!", pFilter );
735*cdf0e10cSrcweir         return;
736*cdf0e10cSrcweir     }
737*cdf0e10cSrcweir 
738*cdf0e10cSrcweir     writeLine( stream, "########################################"
739*cdf0e10cSrcweir                "######################################", pFilter );
740*cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment dump: ") );
741*cdf0e10cSrcweir     buf.append( pEnv->pTypeName );
742*cdf0e10cSrcweir     writeLine( stream, buf.makeStringAndClear(), pFilter );
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir     uno_DefaultEnvironment * that =
745*cdf0e10cSrcweir         reinterpret_cast< uno_DefaultEnvironment * >(pEnv);
746*cdf0e10cSrcweir     ::osl::MutexGuard guard( that->mutex );
747*cdf0e10cSrcweir 
748*cdf0e10cSrcweir     Ptr2ObjectMap ptr2obj( that->aPtr2ObjectMap );
749*cdf0e10cSrcweir     OId2ObjectMap::const_iterator iPos( that->aOId2ObjectMap.begin() );
750*cdf0e10cSrcweir     while (iPos != that->aOId2ObjectMap.end())
751*cdf0e10cSrcweir     {
752*cdf0e10cSrcweir         ObjectEntry * pOEntry = iPos->second;
753*cdf0e10cSrcweir 
754*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("+ ") );
755*cdf0e10cSrcweir         if (pOEntry->mixedObject)
756*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("mixed ") );
757*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("object entry: nRef=") );
758*cdf0e10cSrcweir         buf.append( pOEntry->nRef, 10 );
759*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; oid=\"") );
760*cdf0e10cSrcweir         buf.append( pOEntry->oid );
761*cdf0e10cSrcweir         buf.append( (sal_Unicode) '\"' );
762*cdf0e10cSrcweir         writeLine( stream, buf.makeStringAndClear(), pFilter );
763*cdf0e10cSrcweir 
764*cdf0e10cSrcweir         for ( ::std::size_t nPos = 0;
765*cdf0e10cSrcweir               nPos < pOEntry->aInterfaces.size(); ++nPos )
766*cdf0e10cSrcweir         {
767*cdf0e10cSrcweir             const InterfaceEntry & rIEntry = pOEntry->aInterfaces[nPos];
768*cdf0e10cSrcweir 
769*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("  - ") );
770*cdf0e10cSrcweir             buf.append(
771*cdf0e10cSrcweir                 ((typelib_TypeDescription *) rIEntry.pTypeDescr)->pTypeName );
772*cdf0e10cSrcweir             if (rIEntry.fpFreeProxy)
773*cdf0e10cSrcweir             {
774*cdf0e10cSrcweir                 buf.appendAscii(
775*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM("; proxy free=0x") );
776*cdf0e10cSrcweir                 buf.append(
777*cdf0e10cSrcweir                     reinterpret_cast< sal_IntPtr >(rIEntry.fpFreeProxy), 16 );
778*cdf0e10cSrcweir             }
779*cdf0e10cSrcweir             else
780*cdf0e10cSrcweir             {
781*cdf0e10cSrcweir                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; original") );
782*cdf0e10cSrcweir             }
783*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; ptr=0x") );
784*cdf0e10cSrcweir             buf.append(
785*cdf0e10cSrcweir                 reinterpret_cast< sal_IntPtr >(rIEntry.pInterface), 16 );
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir             if (pOEntry->find( rIEntry.pInterface, nPos + 1 ) < 0)
788*cdf0e10cSrcweir             {
789*cdf0e10cSrcweir                 ::std::size_t erased = ptr2obj.erase( rIEntry.pInterface );
790*cdf0e10cSrcweir                 if (erased != 1)
791*cdf0e10cSrcweir                 {
792*cdf0e10cSrcweir                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
793*cdf0e10cSrcweir                                          " (ptr not found in map!)") );
794*cdf0e10cSrcweir                 }
795*cdf0e10cSrcweir             }
796*cdf0e10cSrcweir             writeLine( stream, buf.makeStringAndClear(), pFilter );
797*cdf0e10cSrcweir         }
798*cdf0e10cSrcweir         ++iPos;
799*cdf0e10cSrcweir     }
800*cdf0e10cSrcweir     if (! ptr2obj.empty())
801*cdf0e10cSrcweir         writeLine( stream, "ptr map inconsistency!!!", pFilter );
802*cdf0e10cSrcweir     writeLine( stream, "#####################################"
803*cdf0e10cSrcweir                "#########################################", pFilter );
804*cdf0e10cSrcweir }
805*cdf0e10cSrcweir 
806*cdf0e10cSrcweir //##############################################################################
807*cdf0e10cSrcweir extern "C" void SAL_CALL uno_dumpEnvironmentByName(
808*cdf0e10cSrcweir     void * stream, rtl_uString * pEnvDcp, const sal_Char * pFilter )
809*cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
810*cdf0e10cSrcweir {
811*cdf0e10cSrcweir     uno_Environment * pEnv = 0;
812*cdf0e10cSrcweir     uno_getEnvironment( &pEnv, pEnvDcp, 0 );
813*cdf0e10cSrcweir     if (pEnv)
814*cdf0e10cSrcweir     {
815*cdf0e10cSrcweir         ::uno_dumpEnvironment( stream, pEnv, pFilter );
816*cdf0e10cSrcweir         (*pEnv->release)( pEnv );
817*cdf0e10cSrcweir     }
818*cdf0e10cSrcweir     else
819*cdf0e10cSrcweir     {
820*cdf0e10cSrcweir         ::rtl::OUStringBuffer buf( 32 );
821*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment \"") );
822*cdf0e10cSrcweir         buf.append( pEnvDcp );
823*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not exist!") );
824*cdf0e10cSrcweir         writeLine( stream, buf.makeStringAndClear(), pFilter );
825*cdf0e10cSrcweir     }
826*cdf0e10cSrcweir }
827*cdf0e10cSrcweir 
828*cdf0e10cSrcweir //------------------------------------------------------------------------------
829*cdf0e10cSrcweir inline static const OUString & unoenv_getStaticOIdPart()
830*cdf0e10cSrcweir {
831*cdf0e10cSrcweir     static OUString * s_pStaticOidPart = 0;
832*cdf0e10cSrcweir     if (! s_pStaticOidPart)
833*cdf0e10cSrcweir     {
834*cdf0e10cSrcweir         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
835*cdf0e10cSrcweir         if (! s_pStaticOidPart)
836*cdf0e10cSrcweir         {
837*cdf0e10cSrcweir             ::rtl::OUStringBuffer aRet( 64 );
838*cdf0e10cSrcweir             aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
839*cdf0e10cSrcweir             // pid
840*cdf0e10cSrcweir             oslProcessInfo info;
841*cdf0e10cSrcweir             info.Size = sizeof(oslProcessInfo);
842*cdf0e10cSrcweir             if (::osl_getProcessInfo( 0, osl_Process_IDENTIFIER, &info ) ==
843*cdf0e10cSrcweir                 osl_Process_E_None)
844*cdf0e10cSrcweir             {
845*cdf0e10cSrcweir                 aRet.append( (sal_Int64)info.Ident, 16 );
846*cdf0e10cSrcweir             }
847*cdf0e10cSrcweir             else
848*cdf0e10cSrcweir             {
849*cdf0e10cSrcweir                 aRet.appendAscii(
850*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM("unknown process id") );
851*cdf0e10cSrcweir             }
852*cdf0e10cSrcweir             // good guid
853*cdf0e10cSrcweir             sal_uInt8 ar[16];
854*cdf0e10cSrcweir             ::rtl_getGlobalProcessId( ar );
855*cdf0e10cSrcweir             aRet.append( (sal_Unicode)';' );
856*cdf0e10cSrcweir             for ( sal_Int32 i = 0; i < 16; ++i )
857*cdf0e10cSrcweir                 aRet.append( (sal_Int32)ar[i], 16 );
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir             static OUString s_aStaticOidPart( aRet.makeStringAndClear() );
860*cdf0e10cSrcweir             s_pStaticOidPart = &s_aStaticOidPart;
861*cdf0e10cSrcweir         }
862*cdf0e10cSrcweir     }
863*cdf0e10cSrcweir     return *s_pStaticOidPart;
864*cdf0e10cSrcweir }
865*cdf0e10cSrcweir 
866*cdf0e10cSrcweir extern "C"
867*cdf0e10cSrcweir {
868*cdf0e10cSrcweir 
869*cdf0e10cSrcweir //------------------------------------------------------------------------------
870*cdf0e10cSrcweir static void SAL_CALL unoenv_computeObjectIdentifier(
871*cdf0e10cSrcweir     uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
872*cdf0e10cSrcweir {
873*cdf0e10cSrcweir     OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
874*cdf0e10cSrcweir     if (*ppOId)
875*cdf0e10cSrcweir     {
876*cdf0e10cSrcweir         ::rtl_uString_release( *ppOId );
877*cdf0e10cSrcweir         *ppOId = 0;
878*cdf0e10cSrcweir     }
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir     uno_Interface * pUnoI = (uno_Interface *)
881*cdf0e10cSrcweir         ::cppu::binuno_queryInterface(
882*cdf0e10cSrcweir             pInterface, *typelib_static_type_getByTypeClass(
883*cdf0e10cSrcweir                 typelib_TypeClass_INTERFACE ) );
884*cdf0e10cSrcweir     if (0 != pUnoI)
885*cdf0e10cSrcweir     {
886*cdf0e10cSrcweir         (*pUnoI->release)( pUnoI );
887*cdf0e10cSrcweir         // interface
888*cdf0e10cSrcweir         ::rtl::OUStringBuffer oid( 64 );
889*cdf0e10cSrcweir         oid.append( reinterpret_cast< sal_Int64 >(pUnoI), 16 );
890*cdf0e10cSrcweir         oid.append( static_cast< sal_Unicode >(';') );
891*cdf0e10cSrcweir         // environment[context]
892*cdf0e10cSrcweir         oid.append( ((uno_Environment *) pEnv)->pTypeName );
893*cdf0e10cSrcweir         oid.append( static_cast< sal_Unicode >('[') );
894*cdf0e10cSrcweir         oid.append( reinterpret_cast< sal_Int64 >(
895*cdf0e10cSrcweir                         reinterpret_cast<
896*cdf0e10cSrcweir                         uno_Environment * >(pEnv)->pContext ), 16 );
897*cdf0e10cSrcweir         // process;good guid
898*cdf0e10cSrcweir         oid.append( unoenv_getStaticOIdPart() );
899*cdf0e10cSrcweir         OUString aStr( oid.makeStringAndClear() );
900*cdf0e10cSrcweir         ::rtl_uString_acquire( *ppOId = aStr.pData );
901*cdf0e10cSrcweir     }
902*cdf0e10cSrcweir }
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir //==============================================================================
905*cdf0e10cSrcweir static void SAL_CALL unoenv_acquireInterface(
906*cdf0e10cSrcweir     uno_ExtEnvironment *, void * pUnoI_ )
907*cdf0e10cSrcweir {
908*cdf0e10cSrcweir     uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
909*cdf0e10cSrcweir     (*pUnoI->acquire)( pUnoI );
910*cdf0e10cSrcweir }
911*cdf0e10cSrcweir 
912*cdf0e10cSrcweir //==============================================================================
913*cdf0e10cSrcweir static void SAL_CALL unoenv_releaseInterface(
914*cdf0e10cSrcweir     uno_ExtEnvironment *, void * pUnoI_ )
915*cdf0e10cSrcweir {
916*cdf0e10cSrcweir     uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
917*cdf0e10cSrcweir     (*pUnoI->release)( pUnoI );
918*cdf0e10cSrcweir }
919*cdf0e10cSrcweir }
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir //______________________________________________________________________________
922*cdf0e10cSrcweir EnvironmentsData::~EnvironmentsData()
923*cdf0e10cSrcweir {
924*cdf0e10cSrcweir     ::osl::MutexGuard guard( mutex );
925*cdf0e10cSrcweir     isDisposing = true;
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir     for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
928*cdf0e10cSrcweir           iPos != aName2EnvMap.end(); ++iPos )
929*cdf0e10cSrcweir     {
930*cdf0e10cSrcweir         uno_Environment * pWeak = iPos->second;
931*cdf0e10cSrcweir         uno_Environment * pHard = 0;
932*cdf0e10cSrcweir         (*pWeak->harden)( &pHard, pWeak );
933*cdf0e10cSrcweir         (*pWeak->releaseWeak)( pWeak );
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir         if (pHard)
936*cdf0e10cSrcweir         {
937*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
938*cdf0e10cSrcweir             ::uno_dumpEnvironment( 0, pHard, 0 );
939*cdf0e10cSrcweir #endif
940*cdf0e10cSrcweir             (*pHard->dispose)( pHard ); // send explicit dispose
941*cdf0e10cSrcweir             (*pHard->release)( pHard );
942*cdf0e10cSrcweir         }
943*cdf0e10cSrcweir     }
944*cdf0e10cSrcweir }
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir //______________________________________________________________________________
947*cdf0e10cSrcweir inline void EnvironmentsData::getEnvironment(
948*cdf0e10cSrcweir     uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext )
949*cdf0e10cSrcweir {
950*cdf0e10cSrcweir     if (*ppEnv)
951*cdf0e10cSrcweir     {
952*cdf0e10cSrcweir         (*(*ppEnv)->release)( *ppEnv );
953*cdf0e10cSrcweir         *ppEnv = 0;
954*cdf0e10cSrcweir     }
955*cdf0e10cSrcweir 
956*cdf0e10cSrcweir     OUString aKey(
957*cdf0e10cSrcweir         OUString::valueOf( reinterpret_cast< sal_IntPtr >(pContext) ) );
958*cdf0e10cSrcweir     aKey += rEnvDcp;
959*cdf0e10cSrcweir 
960*cdf0e10cSrcweir     // try to find registered mapping
961*cdf0e10cSrcweir     OUString2EnvironmentMap::const_iterator const iFind(
962*cdf0e10cSrcweir         aName2EnvMap.find( aKey ) );
963*cdf0e10cSrcweir     if (iFind != aName2EnvMap.end())
964*cdf0e10cSrcweir     {
965*cdf0e10cSrcweir         uno_Environment * pWeak = iFind->second;
966*cdf0e10cSrcweir         (*pWeak->harden)( ppEnv, pWeak );
967*cdf0e10cSrcweir     }
968*cdf0e10cSrcweir }
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir //______________________________________________________________________________
971*cdf0e10cSrcweir inline void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv )
972*cdf0e10cSrcweir {
973*cdf0e10cSrcweir     OSL_ENSURE( ppEnv, "### null ptr!" );
974*cdf0e10cSrcweir     uno_Environment * pEnv =  *ppEnv;
975*cdf0e10cSrcweir 
976*cdf0e10cSrcweir     OUString aKey(
977*cdf0e10cSrcweir         OUString::valueOf( reinterpret_cast< sal_IntPtr >(pEnv->pContext) ) );
978*cdf0e10cSrcweir     aKey += pEnv->pTypeName;
979*cdf0e10cSrcweir 
980*cdf0e10cSrcweir     // try to find registered environment
981*cdf0e10cSrcweir     OUString2EnvironmentMap::const_iterator const iFind(
982*cdf0e10cSrcweir         aName2EnvMap.find( aKey ) );
983*cdf0e10cSrcweir     if (iFind == aName2EnvMap.end())
984*cdf0e10cSrcweir     {
985*cdf0e10cSrcweir         (*pEnv->acquireWeak)( pEnv );
986*cdf0e10cSrcweir         ::std::pair< OUString2EnvironmentMap::iterator, bool > insertion(
987*cdf0e10cSrcweir             aName2EnvMap.insert(
988*cdf0e10cSrcweir                 OUString2EnvironmentMap::value_type( aKey, pEnv ) ) );
989*cdf0e10cSrcweir         OSL_ENSURE(
990*cdf0e10cSrcweir             insertion.second, "### insertion of env into map failed?!" );
991*cdf0e10cSrcweir     }
992*cdf0e10cSrcweir     else
993*cdf0e10cSrcweir     {
994*cdf0e10cSrcweir         uno_Environment * pHard = 0;
995*cdf0e10cSrcweir         uno_Environment * pWeak = iFind->second;
996*cdf0e10cSrcweir         (*pWeak->harden)( &pHard, pWeak );
997*cdf0e10cSrcweir         if (pHard)
998*cdf0e10cSrcweir         {
999*cdf0e10cSrcweir             if (pEnv)
1000*cdf0e10cSrcweir                 (*pEnv->release)( pEnv );
1001*cdf0e10cSrcweir             *ppEnv = pHard;
1002*cdf0e10cSrcweir         }
1003*cdf0e10cSrcweir         else // registered one is dead
1004*cdf0e10cSrcweir         {
1005*cdf0e10cSrcweir             (*pWeak->releaseWeak)( pWeak );
1006*cdf0e10cSrcweir             (*pEnv->acquireWeak)( pEnv );
1007*cdf0e10cSrcweir             aName2EnvMap[ aKey ] = pEnv;
1008*cdf0e10cSrcweir         }
1009*cdf0e10cSrcweir     }
1010*cdf0e10cSrcweir }
1011*cdf0e10cSrcweir 
1012*cdf0e10cSrcweir //______________________________________________________________________________
1013*cdf0e10cSrcweir inline void EnvironmentsData::getRegisteredEnvironments(
1014*cdf0e10cSrcweir     uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
1015*cdf0e10cSrcweir     const OUString & rEnvDcp )
1016*cdf0e10cSrcweir {
1017*cdf0e10cSrcweir     OSL_ENSURE( pppEnvs && pnLen && memAlloc, "### null ptr!" );
1018*cdf0e10cSrcweir 
1019*cdf0e10cSrcweir     // max size
1020*cdf0e10cSrcweir     uno_Environment ** ppFound = (uno_Environment **)alloca(
1021*cdf0e10cSrcweir         sizeof(uno_Environment *) * aName2EnvMap.size() );
1022*cdf0e10cSrcweir     sal_Int32 nSize = 0;
1023*cdf0e10cSrcweir 
1024*cdf0e10cSrcweir     // find matching environment
1025*cdf0e10cSrcweir     for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
1026*cdf0e10cSrcweir           iPos != aName2EnvMap.end(); ++iPos )
1027*cdf0e10cSrcweir     {
1028*cdf0e10cSrcweir         uno_Environment * pWeak = iPos->second;
1029*cdf0e10cSrcweir         if (!rEnvDcp.getLength() ||
1030*cdf0e10cSrcweir             rEnvDcp.equals( pWeak->pTypeName ))
1031*cdf0e10cSrcweir         {
1032*cdf0e10cSrcweir             ppFound[nSize] = 0;
1033*cdf0e10cSrcweir             (*pWeak->harden)( &ppFound[nSize], pWeak );
1034*cdf0e10cSrcweir             if (ppFound[nSize])
1035*cdf0e10cSrcweir                 ++nSize;
1036*cdf0e10cSrcweir         }
1037*cdf0e10cSrcweir     }
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir     *pnLen = nSize;
1040*cdf0e10cSrcweir     if (nSize)
1041*cdf0e10cSrcweir     {
1042*cdf0e10cSrcweir         *pppEnvs = (uno_Environment **) (*memAlloc)(
1043*cdf0e10cSrcweir             sizeof (uno_Environment *) * nSize );
1044*cdf0e10cSrcweir         OSL_ASSERT( *pppEnvs );
1045*cdf0e10cSrcweir         while (nSize--)
1046*cdf0e10cSrcweir         {
1047*cdf0e10cSrcweir             (*pppEnvs)[nSize] = ppFound[nSize];
1048*cdf0e10cSrcweir         }
1049*cdf0e10cSrcweir     }
1050*cdf0e10cSrcweir     else
1051*cdf0e10cSrcweir     {
1052*cdf0e10cSrcweir         *pppEnvs = 0;
1053*cdf0e10cSrcweir     }
1054*cdf0e10cSrcweir }
1055*cdf0e10cSrcweir 
1056*cdf0e10cSrcweir static bool loadEnv(OUString const  & cLibStem,
1057*cdf0e10cSrcweir 					uno_Environment * pEnv,
1058*cdf0e10cSrcweir 					void            * /*pContext*/)
1059*cdf0e10cSrcweir {
1060*cdf0e10cSrcweir 	// late init with some code from matching uno language binding
1061*cdf0e10cSrcweir 	// will be unloaded by environment
1062*cdf0e10cSrcweir 	oslModule hMod = cppu::detail::loadModule( cLibStem );
1063*cdf0e10cSrcweir 
1064*cdf0e10cSrcweir 	if (!hMod)
1065*cdf0e10cSrcweir 		return false;
1066*cdf0e10cSrcweir 
1067*cdf0e10cSrcweir 	OUString aSymbolName(RTL_CONSTASCII_USTRINGPARAM(UNO_INIT_ENVIRONMENT));
1068*cdf0e10cSrcweir 	uno_initEnvironmentFunc fpInit = (uno_initEnvironmentFunc)
1069*cdf0e10cSrcweir 		::osl_getFunctionSymbol( hMod, aSymbolName.pData );
1070*cdf0e10cSrcweir 	if (!fpInit)
1071*cdf0e10cSrcweir 	{
1072*cdf0e10cSrcweir 		::osl_unloadModule( hMod );
1073*cdf0e10cSrcweir 		return false;
1074*cdf0e10cSrcweir 	}
1075*cdf0e10cSrcweir 
1076*cdf0e10cSrcweir 	(*fpInit)( pEnv ); // init of environment
1077*cdf0e10cSrcweir 	::rtl_registerModuleForUnloading( hMod );
1078*cdf0e10cSrcweir 
1079*cdf0e10cSrcweir 	return true;
1080*cdf0e10cSrcweir }
1081*cdf0e10cSrcweir 
1082*cdf0e10cSrcweir 
1083*cdf0e10cSrcweir extern "C"
1084*cdf0e10cSrcweir {
1085*cdf0e10cSrcweir 
1086*cdf0e10cSrcweir //------------------------------------------------------------------------------
1087*cdf0e10cSrcweir static uno_Environment * initDefaultEnvironment(
1088*cdf0e10cSrcweir     const OUString & rEnvDcp, void * pContext )
1089*cdf0e10cSrcweir {
1090*cdf0e10cSrcweir     uno_Environment * pEnv = &(new uno_DefaultEnvironment( rEnvDcp, pContext ))->aBase;
1091*cdf0e10cSrcweir 	(*pEnv->acquire)( pEnv );
1092*cdf0e10cSrcweir 
1093*cdf0e10cSrcweir 	OUString envTypeName = cppu::EnvDcp::getTypeName(rEnvDcp);
1094*cdf0e10cSrcweir 
1095*cdf0e10cSrcweir     // create default environment
1096*cdf0e10cSrcweir     if (envTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
1097*cdf0e10cSrcweir     {
1098*cdf0e10cSrcweir         uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
1099*cdf0e10cSrcweir 		that->computeObjectIdentifier = unoenv_computeObjectIdentifier;
1100*cdf0e10cSrcweir 		that->acquireInterface = unoenv_acquireInterface;
1101*cdf0e10cSrcweir 		that->releaseInterface = unoenv_releaseInterface;
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir 		OUString envPurpose = cppu::EnvDcp::getPurpose(rEnvDcp);
1104*cdf0e10cSrcweir 		if (envPurpose.getLength())
1105*cdf0e10cSrcweir 		{
1106*cdf0e10cSrcweir 			rtl::OUString libStem = envPurpose.copy(envPurpose.lastIndexOf(':') + 1);
1107*cdf0e10cSrcweir 			libStem += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_uno_uno") );
1108*cdf0e10cSrcweir 
1109*cdf0e10cSrcweir 			if(!loadEnv(libStem, pEnv, pContext))
1110*cdf0e10cSrcweir 			{
1111*cdf0e10cSrcweir 				pEnv->release(pEnv);
1112*cdf0e10cSrcweir 				return NULL;
1113*cdf0e10cSrcweir 			}
1114*cdf0e10cSrcweir 		}
1115*cdf0e10cSrcweir     }
1116*cdf0e10cSrcweir     else
1117*cdf0e10cSrcweir     {
1118*cdf0e10cSrcweir         // late init with some code from matching uno language binding
1119*cdf0e10cSrcweir         ::rtl::OUStringBuffer aLibName( 16 );
1120*cdf0e10cSrcweir         aLibName.append( envTypeName );
1121*cdf0e10cSrcweir         aLibName.appendAscii( RTL_CONSTASCII_STRINGPARAM("_uno" ) );
1122*cdf0e10cSrcweir         OUString aStr( aLibName.makeStringAndClear() );
1123*cdf0e10cSrcweir 
1124*cdf0e10cSrcweir 		if (!loadEnv(aStr, pEnv, pContext))
1125*cdf0e10cSrcweir 		{
1126*cdf0e10cSrcweir 			pEnv->release(pEnv);
1127*cdf0e10cSrcweir 			return NULL;
1128*cdf0e10cSrcweir 		}
1129*cdf0e10cSrcweir     }
1130*cdf0e10cSrcweir 
1131*cdf0e10cSrcweir     return pEnv;
1132*cdf0e10cSrcweir }
1133*cdf0e10cSrcweir 
1134*cdf0e10cSrcweir //##############################################################################
1135*cdf0e10cSrcweir void SAL_CALL uno_createEnvironment(
1136*cdf0e10cSrcweir     uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
1137*cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
1138*cdf0e10cSrcweir {
1139*cdf0e10cSrcweir     OSL_ENSURE( ppEnv, "### null ptr!" );
1140*cdf0e10cSrcweir     if (*ppEnv)
1141*cdf0e10cSrcweir         (*(*ppEnv)->release)( *ppEnv );
1142*cdf0e10cSrcweir 
1143*cdf0e10cSrcweir     OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
1144*cdf0e10cSrcweir     *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
1145*cdf0e10cSrcweir }
1146*cdf0e10cSrcweir 
1147*cdf0e10cSrcweir //##############################################################################
1148*cdf0e10cSrcweir void SAL_CALL uno_direct_getEnvironment(
1149*cdf0e10cSrcweir     uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
1150*cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
1151*cdf0e10cSrcweir {
1152*cdf0e10cSrcweir     OSL_ENSURE( ppEnv, "### null ptr!" );
1153*cdf0e10cSrcweir     OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
1154*cdf0e10cSrcweir 
1155*cdf0e10cSrcweir     EnvironmentsData & rData = theEnvironmentsData::get();
1156*cdf0e10cSrcweir 
1157*cdf0e10cSrcweir     ::osl::MutexGuard guard( rData.mutex );
1158*cdf0e10cSrcweir     rData.getEnvironment( ppEnv, rEnvDcp, pContext );
1159*cdf0e10cSrcweir     if (! *ppEnv)
1160*cdf0e10cSrcweir     {
1161*cdf0e10cSrcweir         *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
1162*cdf0e10cSrcweir         if (*ppEnv)
1163*cdf0e10cSrcweir         {
1164*cdf0e10cSrcweir             // register new environment:
1165*cdf0e10cSrcweir             rData.registerEnvironment( ppEnv );
1166*cdf0e10cSrcweir         }
1167*cdf0e10cSrcweir     }
1168*cdf0e10cSrcweir }
1169*cdf0e10cSrcweir 
1170*cdf0e10cSrcweir //##############################################################################
1171*cdf0e10cSrcweir void SAL_CALL uno_getRegisteredEnvironments(
1172*cdf0e10cSrcweir     uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
1173*cdf0e10cSrcweir     rtl_uString * pEnvDcp )
1174*cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
1175*cdf0e10cSrcweir {
1176*cdf0e10cSrcweir     EnvironmentsData & rData = theEnvironmentsData::get();
1177*cdf0e10cSrcweir 
1178*cdf0e10cSrcweir     ::osl::MutexGuard guard( rData.mutex );
1179*cdf0e10cSrcweir     rData.getRegisteredEnvironments(
1180*cdf0e10cSrcweir         pppEnvs, pnLen, memAlloc,
1181*cdf0e10cSrcweir         (pEnvDcp ? OUString(pEnvDcp) : OUString()) );
1182*cdf0e10cSrcweir }
1183*cdf0e10cSrcweir 
1184*cdf0e10cSrcweir } // extern "C"
1185*cdf0e10cSrcweir 
1186*cdf0e10cSrcweir }
1187*cdf0e10cSrcweir 
1188