xref: /AOO41X/main/extensions/source/ole/unoobjw.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_extensions.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "ole2uno.hxx"
32*cdf0e10cSrcweir #include <stdio.h>
33*cdf0e10cSrcweir #include <tools/presys.h>
34*cdf0e10cSrcweir #include <olectl.h>
35*cdf0e10cSrcweir #include <vector>
36*cdf0e10cSrcweir #include <list>
37*cdf0e10cSrcweir #include <hash_map>
38*cdf0e10cSrcweir #include "comifaces.hxx"
39*cdf0e10cSrcweir #include <tools/postsys.h>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <vos/diagnose.hxx>
43*cdf0e10cSrcweir #include <vos/refernce.hxx>
44*cdf0e10cSrcweir #include <tools/debug.hxx>
45*cdf0e10cSrcweir #include <rtl/ustring.hxx>
46*cdf0e10cSrcweir #include <com/sun/star/beans/MethodConcept.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyConcept.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/script/FailReason.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/reflection/ParamInfo.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/beans/XExactName.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/container/NoSuchElementException.hpp>
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir #include <com/sun/star/beans/XMaterialHolder.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/script/XInvocation2.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/script/MemberType.hpp>
56*cdf0e10cSrcweir #include <com/sun/star/reflection/XIdlReflection.hpp>
57*cdf0e10cSrcweir #include <osl/interlck.h>
58*cdf0e10cSrcweir #include <com/sun/star/uno/genfunc.h>
59*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir #include "comifaces.hxx"
62*cdf0e10cSrcweir #include "jscriptclasses.hxx"
63*cdf0e10cSrcweir #include "unotypewrapper.hxx"
64*cdf0e10cSrcweir #include "oleobjw.hxx"
65*cdf0e10cSrcweir #include "unoobjw.hxx"
66*cdf0e10cSrcweir #include "servprov.hxx"
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir using namespace vos;
69*cdf0e10cSrcweir using namespace std;
70*cdf0e10cSrcweir using namespace rtl;
71*cdf0e10cSrcweir using namespace osl;
72*cdf0e10cSrcweir using namespace cppu;
73*cdf0e10cSrcweir using namespace com::sun::star::uno;
74*cdf0e10cSrcweir using namespace com::sun::star::beans;
75*cdf0e10cSrcweir using namespace com::sun::star::container;
76*cdf0e10cSrcweir using namespace com::sun::star::script;
77*cdf0e10cSrcweir using namespace com::sun::star::lang;
78*cdf0e10cSrcweir using namespace com::sun::star::bridge::ModelDependent;
79*cdf0e10cSrcweir using namespace com::sun::star::reflection;
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir #if _MSC_VER < 1200
84*cdf0e10cSrcweir extern "C" const GUID IID_IDispatchEx;
85*cdf0e10cSrcweir #endif
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir namespace ole_adapter
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir hash_map<sal_uInt32, WeakReference<XInterface> > UnoObjToWrapperMap;
90*cdf0e10cSrcweir static sal_Bool writeBackOutParameter(VARIANTARG* pDest, VARIANT* pSource);
91*cdf0e10cSrcweir static sal_Bool writeBackOutParameter2( VARIANTARG* pDest, VARIANT* pSource);
92*cdf0e10cSrcweir static HRESULT mapCannotConvertException( CannotConvertException e, unsigned int * puArgErr);
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir /* Does not throw any exceptions.
96*cdf0e10cSrcweir    Param pInfo can be NULL.
97*cdf0e10cSrcweir  */
98*cdf0e10cSrcweir static void writeExcepinfo(EXCEPINFO * pInfo, const OUString& message)
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir     if (pInfo != NULL)
101*cdf0e10cSrcweir     {
102*cdf0e10cSrcweir         pInfo->wCode = UNO_2_OLE_EXCEPTIONCODE;
103*cdf0e10cSrcweir         pInfo->bstrSource = SysAllocString(L"[automation bridge] ");
104*cdf0e10cSrcweir         pInfo->bstrDescription = SysAllocString(reinterpret_cast<LPCOLESTR>(message.getStr()));
105*cdf0e10cSrcweir     }
106*cdf0e10cSrcweir }
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir /*****************************************************************************
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir 	class implementation: InterfaceOleWrapper_Impl
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir *****************************************************************************/
113*cdf0e10cSrcweir InterfaceOleWrapper_Impl::InterfaceOleWrapper_Impl( Reference<XMultiServiceFactory>& xFactory,
114*cdf0e10cSrcweir 													sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass):
115*cdf0e10cSrcweir 		m_defaultValueType( 0),
116*cdf0e10cSrcweir 		UnoConversionUtilities<InterfaceOleWrapper_Impl>( xFactory, unoWrapperClass, comWrapperClass)
117*cdf0e10cSrcweir {
118*cdf0e10cSrcweir }
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir InterfaceOleWrapper_Impl::~InterfaceOleWrapper_Impl()
121*cdf0e10cSrcweir {
122*cdf0e10cSrcweir     MutexGuard guard(getBridgeMutex());
123*cdf0e10cSrcweir 	// remove entries in global map
124*cdf0e10cSrcweir     IT_Uno it= UnoObjToWrapperMap.find( (sal_uInt32) m_xOrigin.get());
125*cdf0e10cSrcweir     if(it != UnoObjToWrapperMap.end())
126*cdf0e10cSrcweir         UnoObjToWrapperMap.erase(it);
127*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
128*cdf0e10cSrcweir     fprintf(stderr,"[automation bridge] UnoObjToWrapperMap  contains: %i \n",
129*cdf0e10cSrcweir             UnoObjToWrapperMap.size());
130*cdf0e10cSrcweir #endif
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir }
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::QueryInterface(REFIID riid, LPVOID FAR * ppv)
135*cdf0e10cSrcweir {
136*cdf0e10cSrcweir 	HRESULT ret= S_OK;
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir 	if( !ppv)
139*cdf0e10cSrcweir 		return E_POINTER;
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir     if(IsEqualIID(riid, IID_IUnknown))
142*cdf0e10cSrcweir 	{
143*cdf0e10cSrcweir 		AddRef();
144*cdf0e10cSrcweir 		*ppv = (IUnknown*) (IDispatch*) this;
145*cdf0e10cSrcweir     }
146*cdf0e10cSrcweir     else if (IsEqualIID(riid, IID_IDispatch))
147*cdf0e10cSrcweir 	{
148*cdf0e10cSrcweir 		AddRef();
149*cdf0e10cSrcweir 		*ppv = (IDispatch*) this;
150*cdf0e10cSrcweir 	}
151*cdf0e10cSrcweir 	else if( IsEqualIID( riid, __uuidof( IUnoObjectWrapper)))
152*cdf0e10cSrcweir 	{
153*cdf0e10cSrcweir 		AddRef();
154*cdf0e10cSrcweir 		*ppv= (IUnoObjectWrapper*) this;
155*cdf0e10cSrcweir 	}
156*cdf0e10cSrcweir 	else
157*cdf0e10cSrcweir 		ret= E_NOINTERFACE;
158*cdf0e10cSrcweir 	return ret;
159*cdf0e10cSrcweir }
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir STDMETHODIMP_(ULONG) InterfaceOleWrapper_Impl::AddRef()
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir     acquire();
164*cdf0e10cSrcweir     // does not need to guard because one should not rely on the return value of
165*cdf0e10cSrcweir     // AddRef anyway
166*cdf0e10cSrcweir 	return m_refCount;
167*cdf0e10cSrcweir }
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir STDMETHODIMP_(ULONG) InterfaceOleWrapper_Impl::Release()
170*cdf0e10cSrcweir {
171*cdf0e10cSrcweir     ULONG n= m_refCount;
172*cdf0e10cSrcweir     release();
173*cdf0e10cSrcweir     return n - 1;
174*cdf0e10cSrcweir }
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir // IUnoObjectWrapper --------------------------------------------------------
177*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::getWrapperXInterface( Reference<XInterface>* pXInt)
178*cdf0e10cSrcweir {
179*cdf0e10cSrcweir 	*pXInt= Reference<XInterface>( static_cast<XWeak*>( this), UNO_QUERY);
180*cdf0e10cSrcweir 	return pXInt->is() ? S_OK : E_FAIL;
181*cdf0e10cSrcweir }
182*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::getOriginalUnoObject( Reference<XInterface>* pXInt)
183*cdf0e10cSrcweir {
184*cdf0e10cSrcweir 	*pXInt= m_xOrigin;
185*cdf0e10cSrcweir 	return m_xOrigin.is() ? S_OK : E_FAIL;
186*cdf0e10cSrcweir }
187*cdf0e10cSrcweir STDMETHODIMP  InterfaceOleWrapper_Impl::getOriginalUnoStruct( Any * pStruct)
188*cdf0e10cSrcweir {
189*cdf0e10cSrcweir 	HRESULT ret= E_FAIL;
190*cdf0e10cSrcweir 	if( !m_xOrigin.is())
191*cdf0e10cSrcweir 	{
192*cdf0e10cSrcweir 		Reference<XMaterialHolder> xMatHolder( m_xInvocation, UNO_QUERY);
193*cdf0e10cSrcweir 		if( xMatHolder.is())
194*cdf0e10cSrcweir 		{
195*cdf0e10cSrcweir 			Any any = xMatHolder->getMaterial();
196*cdf0e10cSrcweir 			if( any.getValueTypeClass() == TypeClass_STRUCT)
197*cdf0e10cSrcweir 			{
198*cdf0e10cSrcweir 				*pStruct= any;
199*cdf0e10cSrcweir 				ret= S_OK;
200*cdf0e10cSrcweir 			}
201*cdf0e10cSrcweir 		}
202*cdf0e10cSrcweir 	}
203*cdf0e10cSrcweir 	return ret;
204*cdf0e10cSrcweir }
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetTypeInfoCount( unsigned int * /*pctinfo*/ )
207*cdf0e10cSrcweir {
208*cdf0e10cSrcweir 	return E_NOTIMPL ;
209*cdf0e10cSrcweir }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetTypeInfo(unsigned int /*itinfo*/, LCID /*lcid*/, ITypeInfo ** /*pptinfo*/)
212*cdf0e10cSrcweir {
213*cdf0e10cSrcweir 	return E_NOTIMPL;
214*cdf0e10cSrcweir }
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetIDsOfNames(REFIID /*riid*/,
217*cdf0e10cSrcweir 													 OLECHAR ** rgszNames,
218*cdf0e10cSrcweir 													 unsigned int cNames,
219*cdf0e10cSrcweir 													 LCID /*lcid*/,
220*cdf0e10cSrcweir 													 DISPID * rgdispid )
221*cdf0e10cSrcweir {
222*cdf0e10cSrcweir     HRESULT ret = DISP_E_UNKNOWNNAME;
223*cdf0e10cSrcweir     try
224*cdf0e10cSrcweir     {
225*cdf0e10cSrcweir         MutexGuard guard( getBridgeMutex());
226*cdf0e10cSrcweir         if( ! rgdispid)
227*cdf0e10cSrcweir             return E_POINTER;
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir         // ----------------------------------------
230*cdf0e10cSrcweir         if( ! _wcsicmp( *rgszNames, JSCRIPT_VALUE_FUNC) ||
231*cdf0e10cSrcweir             ! _wcsicmp( *rgszNames, BRIDGE_VALUE_FUNC))
232*cdf0e10cSrcweir         {
233*cdf0e10cSrcweir             *rgdispid= DISPID_JSCRIPT_VALUE_FUNC;
234*cdf0e10cSrcweir             return S_OK;
235*cdf0e10cSrcweir         }
236*cdf0e10cSrcweir         else if( ! _wcsicmp( *rgszNames, GET_STRUCT_FUNC) ||
237*cdf0e10cSrcweir                  ! _wcsicmp( *rgszNames, BRIDGE_GET_STRUCT_FUNC))
238*cdf0e10cSrcweir         {
239*cdf0e10cSrcweir             *rgdispid= DISPID_GET_STRUCT_FUNC;
240*cdf0e10cSrcweir             return S_OK;
241*cdf0e10cSrcweir         }
242*cdf0e10cSrcweir         else if( ! _wcsicmp( *rgszNames, BRIDGE_CREATE_TYPE_FUNC))
243*cdf0e10cSrcweir         {
244*cdf0e10cSrcweir             *rgdispid= DISPID_CREATE_TYPE_FUNC;
245*cdf0e10cSrcweir             return S_OK;
246*cdf0e10cSrcweir         }
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir         // ----------------------------------------
249*cdf0e10cSrcweir         if (m_xInvocation.is() && (cNames > 0))
250*cdf0e10cSrcweir         {
251*cdf0e10cSrcweir             OUString name(reinterpret_cast<const sal_Unicode*>(rgszNames[0]));
252*cdf0e10cSrcweir             NameToIdMap::iterator iter = m_nameToDispIdMap.find(name);
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir             if (iter == m_nameToDispIdMap.end())
255*cdf0e10cSrcweir             {
256*cdf0e10cSrcweir                 OUString exactName;
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir                 if (m_xExactName.is())
259*cdf0e10cSrcweir                 {
260*cdf0e10cSrcweir                     exactName = m_xExactName->getExactName(name);
261*cdf0e10cSrcweir                 }
262*cdf0e10cSrcweir                 else
263*cdf0e10cSrcweir                 {
264*cdf0e10cSrcweir                     exactName = name;
265*cdf0e10cSrcweir                 }
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir                 MemberInfo d(0, exactName);
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir                 if (m_xInvocation->hasProperty(exactName))
270*cdf0e10cSrcweir                 {
271*cdf0e10cSrcweir                     d.flags |= DISPATCH_PROPERTYGET;
272*cdf0e10cSrcweir                     d.flags |= DISPATCH_PROPERTYPUT;
273*cdf0e10cSrcweir                     d.flags |= DISPATCH_PROPERTYPUTREF;
274*cdf0e10cSrcweir                 }
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir                 if (m_xInvocation->hasMethod(exactName))
277*cdf0e10cSrcweir                 {
278*cdf0e10cSrcweir                     d.flags |= DISPATCH_METHOD;
279*cdf0e10cSrcweir                 }
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir                 if (d.flags != 0)
282*cdf0e10cSrcweir                 {
283*cdf0e10cSrcweir                     m_MemberInfos.push_back(d);
284*cdf0e10cSrcweir                     iter = m_nameToDispIdMap.insert(NameToIdMap::value_type(exactName, (DISPID)m_MemberInfos.size())).first;
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir                     if (exactName != name)
287*cdf0e10cSrcweir                     {
288*cdf0e10cSrcweir                         iter = m_nameToDispIdMap.insert(NameToIdMap::value_type(name, (DISPID)m_MemberInfos.size())).first;
289*cdf0e10cSrcweir                     }
290*cdf0e10cSrcweir                 }
291*cdf0e10cSrcweir             }
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir             if (iter == m_nameToDispIdMap.end())
294*cdf0e10cSrcweir             {
295*cdf0e10cSrcweir                 ret = DISP_E_UNKNOWNNAME;
296*cdf0e10cSrcweir             }
297*cdf0e10cSrcweir             else
298*cdf0e10cSrcweir             {
299*cdf0e10cSrcweir                 *rgdispid = (*iter).second;
300*cdf0e10cSrcweir                 ret = S_OK;
301*cdf0e10cSrcweir             }
302*cdf0e10cSrcweir         }
303*cdf0e10cSrcweir     }
304*cdf0e10cSrcweir     catch(BridgeRuntimeError& )
305*cdf0e10cSrcweir     {
306*cdf0e10cSrcweir         OSL_ASSERT(0);
307*cdf0e10cSrcweir     }
308*cdf0e10cSrcweir     catch(Exception& )
309*cdf0e10cSrcweir     {
310*cdf0e10cSrcweir         OSL_ASSERT(0);
311*cdf0e10cSrcweir     }
312*cdf0e10cSrcweir 	catch(...)
313*cdf0e10cSrcweir 	{
314*cdf0e10cSrcweir         OSL_ASSERT(0);
315*cdf0e10cSrcweir 	}
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir     return ret;
318*cdf0e10cSrcweir }
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir // "convertDispparamsArgs" converts VARIANTS to their respecting Any counterparts
321*cdf0e10cSrcweir // The parameters "id", "wFlags" and "pdispparams" equal those as used in
322*cdf0e10cSrcweir // IDispatch::Invoke. The function handles special JavaScript
323*cdf0e10cSrcweir // cases where a VARIANT of type VT_DISPATCH is ambiguous and could represent
324*cdf0e10cSrcweir // an object, array ( JavaScript Array object), out parameter and in/out ( JavaScript Array object)
325*cdf0e10cSrcweir //  parameter (JavaScript Array object)
326*cdf0e10cSrcweir // Because all those VT_DISPATCH objects need a different conversion
327*cdf0e10cSrcweir // we have to find out what the object is supposed to be. The function does this
328*cdf0e10cSrcweir // by either using type information or by help of a specialized ValueObject object.
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir // A. Type Information
331*cdf0e10cSrcweir // -----------------------------------------------------------------------------
332*cdf0e10cSrcweir // With the help of type information the kind of parameter can be exactly determined
333*cdf0e10cSrcweir // and an appropriate conversion can be choosen. A problem arises if a method expects
334*cdf0e10cSrcweir // an Any. Then the type info does not tell what the type of the value, that is kept
335*cdf0e10cSrcweir // by the any, should be. In this situation the decision wheter the param is a
336*cdf0e10cSrcweir // sequence or an object is made upon the fact if the object has a property "0"
337*cdf0e10cSrcweir // ( see function "isJScriptArray"). Since this is unsafe it is recommended to use
338*cdf0e10cSrcweir // the JScript value objects within a JScript script on such an occasion.
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir // B. JavaScript Value Object ( class JScriptValue )
341*cdf0e10cSrcweir // -----------------------------------------------------------------------------
342*cdf0e10cSrcweir // A JScriptValue (ValueObject) object is a COM object in that it implements IDispatch and the
343*cdf0e10cSrcweir // IJScriptValue object interface. Such objects are provided by all UNO wrapper
344*cdf0e10cSrcweir // objects used within a JScript script. To obtain an instance one has to call
345*cdf0e10cSrcweir // "_GetValueObject() or Bridge_GetValueObject()" on an UNO wrapper object (class InterfaceOleWrapper_Impl).
346*cdf0e10cSrcweir // A value object is appropriately initialized within the script and passed as
347*cdf0e10cSrcweir // parameter to an UNO object method or property. The convertDispparamsArgs function
348*cdf0e10cSrcweir // can easily find out that a param is such an object by queriing for the
349*cdf0e10cSrcweir // IJScriptValue interface. By this interface one the type and kind ( out, in/out)
350*cdf0e10cSrcweir // can be determined and the right conversion can be applied.
351*cdf0e10cSrcweir // Using ValueObjects we spare us the effort of aquiring and examining type information
352*cdf0e10cSrcweir // in order to figure out what the an IDispatch parameter is meant for.
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir // Normal JScript object parameter can be mixed with JScriptValue object. If an
355*cdf0e10cSrcweir // VARIANT contains an VT_DISPATCH that is no JScriptValue than the type information
356*cdf0e10cSrcweir // is used to find out about the reqired type.
357*cdf0e10cSrcweir void InterfaceOleWrapper_Impl::convertDispparamsArgs(DISPID id,
358*cdf0e10cSrcweir     unsigned short /*wFlags*/, DISPPARAMS* pdispparams, Sequence<Any>& rSeq)
359*cdf0e10cSrcweir {
360*cdf0e10cSrcweir 	HRESULT hr= S_OK;
361*cdf0e10cSrcweir 	sal_Int32 countArgs= pdispparams->cArgs;
362*cdf0e10cSrcweir 	if( countArgs == 0)
363*cdf0e10cSrcweir 		return;
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir 	rSeq.realloc( countArgs);
366*cdf0e10cSrcweir 	Any*	pParams = rSeq.getArray();
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir 	Any anyParam;
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir     //Get type information for the current call
371*cdf0e10cSrcweir     InvocationInfo info;
372*cdf0e10cSrcweir     if( ! getInvocationInfoForCall( id, info))
373*cdf0e10cSrcweir         throw BridgeRuntimeError(
374*cdf0e10cSrcweir             OUSTR("[automation bridge]InterfaceOleWrapper_Impl::convertDispparamsArgs \n"
375*cdf0e10cSrcweir                   "Could not obtain type information for current call."));
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir     for (int i = 0; i < countArgs; i++)
378*cdf0e10cSrcweir     {
379*cdf0e10cSrcweir         if (info.eMemberType == MemberType_METHOD &&
380*cdf0e10cSrcweir             info.aParamModes[ countArgs - i -1 ]  == ParamMode_OUT)
381*cdf0e10cSrcweir             continue;
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir  		if(convertValueObject( & pdispparams->rgvarg[i], anyParam))
384*cdf0e10cSrcweir  		{ //a param is a ValueObject and could be converted
385*cdf0e10cSrcweir             pParams[countArgs - (i + 1)] = anyParam;
386*cdf0e10cSrcweir  			continue;
387*cdf0e10cSrcweir  		}
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir         // If the param is an out, in/out parameter in
390*cdf0e10cSrcweir         // JScript (Array object, with value at index 0) then we
391*cdf0e10cSrcweir         // extract Array[0] and put the value into varParam. At the end of the loop varParam
392*cdf0e10cSrcweir         // is converted if it contains a value otherwise the VARIANT from
393*cdf0e10cSrcweir         // DISPPARAMS is converted.
394*cdf0e10cSrcweir         CComVariant varParam;
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir         // Check for JScript out and in/out paramsobjects (VT_DISPATCH).
397*cdf0e10cSrcweir         // To find them out we use typeinformation of the function being called.
398*cdf0e10cSrcweir         if( pdispparams->rgvarg[i].vt == VT_DISPATCH )
399*cdf0e10cSrcweir         {
400*cdf0e10cSrcweir             if( info.eMemberType == MemberType_METHOD && info.aParamModes[ countArgs - i -1 ]  == ParamMode_INOUT)
401*cdf0e10cSrcweir             {
402*cdf0e10cSrcweir                 // INOUT-param
403*cdf0e10cSrcweir                 // Index ( property) "0" contains the actual IN-param. The object is a JScript
404*cdf0e10cSrcweir                 // Array object.
405*cdf0e10cSrcweir                 // Get the IN-param at index "0"
406*cdf0e10cSrcweir                 IDispatch* pdisp= pdispparams->rgvarg[i].pdispVal;
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir                 OLECHAR* sindex= L"0";
409*cdf0e10cSrcweir                 DISPID id;
410*cdf0e10cSrcweir                 DISPPARAMS noParams= {0,0,0,0};
411*cdf0e10cSrcweir                 if(SUCCEEDED( hr= pdisp->GetIDsOfNames( IID_NULL, &sindex, 1, LOCALE_USER_DEFAULT, &id)))
412*cdf0e10cSrcweir                     hr= pdisp->Invoke( id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
413*cdf0e10cSrcweir                                        & noParams, & varParam, NULL, NULL);
414*cdf0e10cSrcweir                 if( FAILED( hr))
415*cdf0e10cSrcweir                 {
416*cdf0e10cSrcweir                     throw BridgeRuntimeError(
417*cdf0e10cSrcweir                         OUSTR("[automation bridge] Could not determine "
418*cdf0e10cSrcweir                               "if the object has a member \"0\". Error: ") +
419*cdf0e10cSrcweir                         OUString::valueOf(hr));
420*cdf0e10cSrcweir                 }
421*cdf0e10cSrcweir             }
422*cdf0e10cSrcweir         }
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir         if( varParam.vt == VT_EMPTY) // then it was no in/out parameter
425*cdf0e10cSrcweir                  varParam= pdispparams->rgvarg[i];
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir         if(info.eMemberType == MemberType_METHOD)
428*cdf0e10cSrcweir             variantToAny( & varParam, anyParam,
429*cdf0e10cSrcweir                            info.aParamTypes[ countArgs - i - 1]);
430*cdf0e10cSrcweir         else if(info.eMemberType == MemberType_PROPERTY)
431*cdf0e10cSrcweir             variantToAny( & varParam, anyParam, info.aType);
432*cdf0e10cSrcweir         else
433*cdf0e10cSrcweir             OSL_ASSERT(0);
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir         pParams[countArgs - (i + 1)]= anyParam;
436*cdf0e10cSrcweir     }// end for / iterating over all parameters
437*cdf0e10cSrcweir }
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir sal_Bool  InterfaceOleWrapper_Impl::getInvocationInfoForCall( DISPID id, InvocationInfo& info)
440*cdf0e10cSrcweir {
441*cdf0e10cSrcweir     sal_Bool bTypesAvailable= sal_False;
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir     if( !m_xInvocation.is() )return false;
444*cdf0e10cSrcweir     Reference<XInvocation2> inv2( m_xInvocation, UNO_QUERY);
445*cdf0e10cSrcweir     if( inv2.is())
446*cdf0e10cSrcweir     {
447*cdf0e10cSrcweir         // We need the name of the property or method to get its type information.
448*cdf0e10cSrcweir         // The name can be identified through the param "id"
449*cdf0e10cSrcweir         // that is kept as value in the map m_nameToDispIdMap.
450*cdf0e10cSrcweir         // Proplem: the Windows JScript engine sometimes changes small letters to capital
451*cdf0e10cSrcweir         // letters as happens in xidlclass_obj.createObject( var) // in JScript.
452*cdf0e10cSrcweir         // IDispatch::GetIdsOfNames is then called with "CreateObject" !!!
453*cdf0e10cSrcweir         // m_nameToDispIdMap can contain several names for one DISPID but only one is
454*cdf0e10cSrcweir         // the exact one. If there's no m_xExactName and therefore no exact name then
455*cdf0e10cSrcweir         // there's only one entry in the map.
456*cdf0e10cSrcweir         typedef NameToIdMap::const_iterator cit;
457*cdf0e10cSrcweir         OUString sMemberName;
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir         for(cit ci1= m_nameToDispIdMap.begin(); ci1 != m_nameToDispIdMap.end(); ci1++)
460*cdf0e10cSrcweir         {
461*cdf0e10cSrcweir             if( (*ci1).second == id) // iterator is a pair< OUString, DISPID>
462*cdf0e10cSrcweir             {
463*cdf0e10cSrcweir                 sMemberName= (*ci1).first;
464*cdf0e10cSrcweir                 break;
465*cdf0e10cSrcweir             }
466*cdf0e10cSrcweir         }
467*cdf0e10cSrcweir         // Get information for the current call ( property or method).
468*cdf0e10cSrcweir         // There could be similar names which only differ in the cases
469*cdf0e10cSrcweir         // of letters. First we assume that the name which was passed into
470*cdf0e10cSrcweir         // GetIDsOfNames is correct. If we won't get information with that
471*cdf0e10cSrcweir         // name then we have the invocation service use the XExactName interface.
472*cdf0e10cSrcweir         sal_Bool validInfo= sal_True;
473*cdf0e10cSrcweir         InvocationInfo invInfo;
474*cdf0e10cSrcweir         try{
475*cdf0e10cSrcweir             invInfo= inv2->getInfoForName( sMemberName, sal_False);
476*cdf0e10cSrcweir         }
477*cdf0e10cSrcweir         catch( IllegalArgumentException )
478*cdf0e10cSrcweir         {
479*cdf0e10cSrcweir             validInfo= sal_False;
480*cdf0e10cSrcweir         }
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir         if( ! validInfo)
483*cdf0e10cSrcweir         {
484*cdf0e10cSrcweir             invInfo= inv2->getInfoForName( sMemberName, sal_True);
485*cdf0e10cSrcweir         }
486*cdf0e10cSrcweir         if( invInfo.aName.pData)
487*cdf0e10cSrcweir         {
488*cdf0e10cSrcweir             bTypesAvailable= sal_True;
489*cdf0e10cSrcweir             info= invInfo;
490*cdf0e10cSrcweir         }
491*cdf0e10cSrcweir     }
492*cdf0e10cSrcweir     return bTypesAvailable;
493*cdf0e10cSrcweir }
494*cdf0e10cSrcweir // XBridgeSupplier2 ---------------------------------------------------
495*cdf0e10cSrcweir // only bridges itself ( this instance of InterfaceOleWrapper_Impl)from UNO to IDispatch
496*cdf0e10cSrcweir // If sourceModelType is UNO than any UNO interface implemented by InterfaceOleWrapper_Impl
497*cdf0e10cSrcweir // can bridged to IDispatch ( if destModelType == OLE). The IDispatch is
498*cdf0e10cSrcweir // implemented by this class.
499*cdf0e10cSrcweir Any SAL_CALL InterfaceOleWrapper_Impl::createBridge(const Any& modelDepObject,
500*cdf0e10cSrcweir 								const Sequence<sal_Int8>& /*ProcessId*/,
501*cdf0e10cSrcweir 								sal_Int16 sourceModelType,
502*cdf0e10cSrcweir 								sal_Int16 destModelType)
503*cdf0e10cSrcweir 			throw (IllegalArgumentException, RuntimeException)
504*cdf0e10cSrcweir {
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir 	Any retAny;
507*cdf0e10cSrcweir 	if( sourceModelType == UNO && destModelType == OLE &&
508*cdf0e10cSrcweir 		modelDepObject.getValueTypeClass() == TypeClass_INTERFACE )
509*cdf0e10cSrcweir 	{
510*cdf0e10cSrcweir 		Reference<XInterface> xInt;
511*cdf0e10cSrcweir 		if( modelDepObject >>= xInt )
512*cdf0e10cSrcweir 		{
513*cdf0e10cSrcweir 			if( xInt == Reference<XInterface>( static_cast<XWeak*>( this), UNO_QUERY))
514*cdf0e10cSrcweir 			{
515*cdf0e10cSrcweir 				VARIANT *pVar= (VARIANT*)CoTaskMemAlloc( sizeof( VARIANT));
516*cdf0e10cSrcweir 				if( pVar)
517*cdf0e10cSrcweir 				{
518*cdf0e10cSrcweir 					pVar->vt= VT_DISPATCH;
519*cdf0e10cSrcweir 					pVar->pdispVal= static_cast<IDispatch*>( this);
520*cdf0e10cSrcweir 					AddRef();
521*cdf0e10cSrcweir 
522*cdf0e10cSrcweir 					retAny<<= reinterpret_cast< sal_uInt32 >( pVar);
523*cdf0e10cSrcweir 				}
524*cdf0e10cSrcweir 			}
525*cdf0e10cSrcweir 		}
526*cdf0e10cSrcweir 	}
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir 	return retAny;
529*cdf0e10cSrcweir }
530*cdf0e10cSrcweir 
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir // XInitialization --------------------------------------------------
533*cdf0e10cSrcweir void SAL_CALL InterfaceOleWrapper_Impl::initialize( const Sequence< Any >& aArguments )
534*cdf0e10cSrcweir 		throw(Exception, RuntimeException)
535*cdf0e10cSrcweir {
536*cdf0e10cSrcweir 	switch( aArguments.getLength() )
537*cdf0e10cSrcweir 	{
538*cdf0e10cSrcweir 	case 2: // the object wraps an UNO struct
539*cdf0e10cSrcweir 		aArguments[0] >>= m_xInvocation;
540*cdf0e10cSrcweir 		aArguments[1] >>= m_defaultValueType;
541*cdf0e10cSrcweir 		break;
542*cdf0e10cSrcweir 	case 3: // the object wraps an UNO interface
543*cdf0e10cSrcweir 		aArguments[0] >>= m_xInvocation;
544*cdf0e10cSrcweir 		aArguments[1] >>= m_xOrigin;
545*cdf0e10cSrcweir 		aArguments[2] >>= m_defaultValueType;
546*cdf0e10cSrcweir 		break;
547*cdf0e10cSrcweir 	}
548*cdf0e10cSrcweir 
549*cdf0e10cSrcweir 	m_xExactName= Reference<XExactName>( m_xInvocation, UNO_QUERY);
550*cdf0e10cSrcweir }
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir Reference< XInterface > InterfaceOleWrapper_Impl::createUnoWrapperInstance()
553*cdf0e10cSrcweir {
554*cdf0e10cSrcweir 	Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
555*cdf0e10cSrcweir 							m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
556*cdf0e10cSrcweir 	return Reference<XInterface>( xWeak, UNO_QUERY);
557*cdf0e10cSrcweir }
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir Reference<XInterface> InterfaceOleWrapper_Impl::createComWrapperInstance()
560*cdf0e10cSrcweir {
561*cdf0e10cSrcweir 	Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
562*cdf0e10cSrcweir 							m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
563*cdf0e10cSrcweir 	return Reference<XInterface>( xWeak, UNO_QUERY);
564*cdf0e10cSrcweir }
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir // "getType" is used in convertValueObject to map the string denoting the type
569*cdf0e10cSrcweir // to an actual Type object.
570*cdf0e10cSrcweir bool getType( const BSTR name, Type & type)
571*cdf0e10cSrcweir {
572*cdf0e10cSrcweir 	Type retType;
573*cdf0e10cSrcweir 	bool ret = false;
574*cdf0e10cSrcweir 	typelib_TypeDescription	* pDesc= NULL;
575*cdf0e10cSrcweir 	OUString str( reinterpret_cast<const sal_Unicode*>(name));
576*cdf0e10cSrcweir 	typelib_typedescription_getByName( &pDesc, str.pData );
577*cdf0e10cSrcweir 	if( pDesc)
578*cdf0e10cSrcweir 	{
579*cdf0e10cSrcweir 		type = Type( pDesc->pWeakRef );
580*cdf0e10cSrcweir 		typelib_typedescription_release( pDesc);
581*cdf0e10cSrcweir 		ret = true;
582*cdf0e10cSrcweir 	}
583*cdf0e10cSrcweir 	return ret;
584*cdf0e10cSrcweir }
585*cdf0e10cSrcweir 
586*cdf0e10cSrcweir static sal_Bool writeBackOutParameter2( VARIANTARG* pDest, VARIANT* pSource)
587*cdf0e10cSrcweir {
588*cdf0e10cSrcweir 	sal_Bool ret = sal_False;
589*cdf0e10cSrcweir 	HRESULT hr;
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir 	// Handle JScriptValue objects and JScript out params ( Array object )
592*cdf0e10cSrcweir 	CComVariant varDest( *pDest);
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir 	if( SUCCEEDED( varDest.ChangeType(VT_DISPATCH)))
595*cdf0e10cSrcweir 	{
596*cdf0e10cSrcweir 		CComPtr<IDispatch> spDispDest(varDest.pdispVal);
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir 		// special Handling for a JScriptValue object
599*cdf0e10cSrcweir #ifdef __MINGW32__
600*cdf0e10cSrcweir 		CComQIPtr<IJScriptValueObject, &__uuidof(IJScriptValueObject)> spValueDest(spDispDest);
601*cdf0e10cSrcweir #else
602*cdf0e10cSrcweir 		CComQIPtr<IJScriptValueObject> spValueDest(spDispDest);
603*cdf0e10cSrcweir #endif
604*cdf0e10cSrcweir 		if (spValueDest)
605*cdf0e10cSrcweir 		{
606*cdf0e10cSrcweir 			VARIANT_BOOL varBool= VARIANT_FALSE;
607*cdf0e10cSrcweir 			if( SUCCEEDED( hr= spValueDest->IsOutParam( &varBool) )
608*cdf0e10cSrcweir 				&& varBool == VARIANT_TRUE  ||
609*cdf0e10cSrcweir 				SUCCEEDED(hr= spValueDest->IsInOutParam( &varBool) )
610*cdf0e10cSrcweir 				&& varBool == VARIANT_TRUE )
611*cdf0e10cSrcweir 			{
612*cdf0e10cSrcweir 				if( SUCCEEDED( spValueDest->Set( CComVariant(), *pSource)))
613*cdf0e10cSrcweir 					ret= sal_True;
614*cdf0e10cSrcweir 			}
615*cdf0e10cSrcweir 		}
616*cdf0e10cSrcweir 		else if (pDest->vt == VT_DISPATCH)// VT_DISPATCH -> JScript out param
617*cdf0e10cSrcweir 		{
618*cdf0e10cSrcweir 			// We use IDispatchEx because its GetDispID function causes the creation
619*cdf0e10cSrcweir 			// of a property if it does not exist already. This is convenient for
620*cdf0e10cSrcweir 			// out parameters in JScript. Then the user must not specify propery "0"
621*cdf0e10cSrcweir 			// explicitly
622*cdf0e10cSrcweir #ifdef __MINGW32__
623*cdf0e10cSrcweir 			CComQIPtr<IDispatchEx, &__uuidof(IDispatchEx)> spDispEx( spDispDest);
624*cdf0e10cSrcweir #else
625*cdf0e10cSrcweir 			CComQIPtr<IDispatchEx> spDispEx( spDispDest);
626*cdf0e10cSrcweir #endif
627*cdf0e10cSrcweir 			if( spDispEx)
628*cdf0e10cSrcweir 			{
629*cdf0e10cSrcweir 				CComBSTR nullProp(L"0");
630*cdf0e10cSrcweir 				DISPID dwDispID;
631*cdf0e10cSrcweir 				if( SUCCEEDED( spDispEx->GetDispID( nullProp, fdexNameEnsure, &dwDispID)))
632*cdf0e10cSrcweir 				{
633*cdf0e10cSrcweir 					DISPPARAMS dispparams = {NULL, NULL, 1, 1};
634*cdf0e10cSrcweir 					dispparams.rgvarg = pSource;
635*cdf0e10cSrcweir 					DISPID dispidPut = DISPID_PROPERTYPUT;
636*cdf0e10cSrcweir 					dispparams.rgdispidNamedArgs = &dispidPut;
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir 					if (pSource->vt == VT_UNKNOWN || pSource->vt == VT_DISPATCH ||
639*cdf0e10cSrcweir 						(pSource->vt & VT_ARRAY) || (pSource->vt & VT_BYREF))
640*cdf0e10cSrcweir 						hr = spDispEx->InvokeEx(dwDispID, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF,
641*cdf0e10cSrcweir 												&dispparams, NULL, NULL, NULL);
642*cdf0e10cSrcweir 					else
643*cdf0e10cSrcweir 						hr= spDispEx->InvokeEx(dwDispID, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT,
644*cdf0e10cSrcweir 											   &dispparams, NULL, NULL, NULL);
645*cdf0e10cSrcweir 					if( SUCCEEDED(hr))
646*cdf0e10cSrcweir 						ret= sal_True;
647*cdf0e10cSrcweir 				}
648*cdf0e10cSrcweir 			}
649*cdf0e10cSrcweir 		}
650*cdf0e10cSrcweir 		else
651*cdf0e10cSrcweir 			ret= writeBackOutParameter( pDest, pSource);
652*cdf0e10cSrcweir 	}
653*cdf0e10cSrcweir 	else // The param can't be a JScript out-parameter ( an Array object), it could be a VBScript
654*cdf0e10cSrcweir 	{	// param. The function checks itself for correct VBScript params
655*cdf0e10cSrcweir 		ret= writeBackOutParameter( pDest, pSource);
656*cdf0e10cSrcweir 	}
657*cdf0e10cSrcweir 	return ret;
658*cdf0e10cSrcweir }
659*cdf0e10cSrcweir // VisualBasic Script passes arguments as VT_VARIANT | VT_BYREF be it in or out parameter.
660*cdf0e10cSrcweir // Thus we are in charge of freeing an eventual value contained by the inner VARIANT
661*cdf0e10cSrcweir // Please note: VariantCopy doesn't free a VT_BYREF value
662*cdf0e10cSrcweir // The out parameters are expected to have always a valid type
663*cdf0e10cSrcweir static sal_Bool writeBackOutParameter(VARIANTARG* pDest, VARIANT* pSource)
664*cdf0e10cSrcweir {
665*cdf0e10cSrcweir 	HRESULT hr;
666*cdf0e10cSrcweir 	sal_Bool ret = FALSE;
667*cdf0e10cSrcweir 	// Out parameter must be VT_BYREF
668*cdf0e10cSrcweir 	if ((V_VT(pDest) & VT_BYREF) != 0 )
669*cdf0e10cSrcweir 	{
670*cdf0e10cSrcweir 		VARTYPE oleTypeFlags = V_VT(pSource);
671*cdf0e10cSrcweir 
672*cdf0e10cSrcweir 		// if caller accept VARIANT as out parameter, any value must be converted
673*cdf0e10cSrcweir 		if (V_VT(pDest) == (VT_VARIANT | VT_BYREF))
674*cdf0e10cSrcweir 		{
675*cdf0e10cSrcweir 			// When the user provides a VARIANT rather then a concrete type
676*cdf0e10cSrcweir 			// we just copy the source to the out, in/out parameter
677*cdf0e10cSrcweir 			// VT_DISPATCH, VT_UNKNOWN, VT_ARRAY, VT_BSTR in the VARIANT that
678*cdf0e10cSrcweir 			// is contained in pDest are released by VariantCopy
679*cdf0e10cSrcweir 			VariantCopy(V_VARIANTREF(pDest), pSource);
680*cdf0e10cSrcweir 			ret	= sal_True;
681*cdf0e10cSrcweir 		}
682*cdf0e10cSrcweir 		else
683*cdf0e10cSrcweir 		{
684*cdf0e10cSrcweir 			// variantarg and variant must have same type
685*cdf0e10cSrcweir   			if ((V_VT(pDest) & oleTypeFlags) == oleTypeFlags)
686*cdf0e10cSrcweir 			{
687*cdf0e10cSrcweir 				if ((oleTypeFlags & VT_ARRAY) != 0)
688*cdf0e10cSrcweir 				{
689*cdf0e10cSrcweir 					// In / Out Param
690*cdf0e10cSrcweir 					if( *V_ARRAYREF(pDest) != NULL)
691*cdf0e10cSrcweir 						hr= SafeArrayCopyData( V_ARRAY(pSource), *V_ARRAYREF(pDest));
692*cdf0e10cSrcweir 					else
693*cdf0e10cSrcweir 						// Out Param
694*cdf0e10cSrcweir 						hr= SafeArrayCopy(V_ARRAY(pSource), V_ARRAYREF(pDest)) == NOERROR;
695*cdf0e10cSrcweir 					if( SUCCEEDED( hr))
696*cdf0e10cSrcweir 						ret	= sal_True;
697*cdf0e10cSrcweir 				}
698*cdf0e10cSrcweir 				else
699*cdf0e10cSrcweir 				{
700*cdf0e10cSrcweir 					// copy base type
701*cdf0e10cSrcweir 					switch (V_VT(pSource))
702*cdf0e10cSrcweir 					{
703*cdf0e10cSrcweir 					case VT_I2:
704*cdf0e10cSrcweir 					{
705*cdf0e10cSrcweir 						*V_I2REF(pDest) = V_I2(pSource);
706*cdf0e10cSrcweir 						ret	= sal_True;
707*cdf0e10cSrcweir 						break;
708*cdf0e10cSrcweir 					}
709*cdf0e10cSrcweir 					case VT_I4:
710*cdf0e10cSrcweir 						*V_I4REF(pDest) = V_I4(pSource);
711*cdf0e10cSrcweir 						ret	= sal_True;
712*cdf0e10cSrcweir 						break;
713*cdf0e10cSrcweir 					case VT_R4:
714*cdf0e10cSrcweir 						*V_R4REF(pDest) = V_R4(pSource);
715*cdf0e10cSrcweir 						ret	= sal_True;
716*cdf0e10cSrcweir 						break;
717*cdf0e10cSrcweir 					case VT_R8:
718*cdf0e10cSrcweir 						*V_R8REF(pDest) = V_R8(pSource);
719*cdf0e10cSrcweir 						ret	= sal_True;
720*cdf0e10cSrcweir 						break;
721*cdf0e10cSrcweir 					case VT_CY:
722*cdf0e10cSrcweir 						*V_CYREF(pDest) = V_CY(pSource);
723*cdf0e10cSrcweir 						ret	= sal_True;
724*cdf0e10cSrcweir 						break;
725*cdf0e10cSrcweir 					case VT_DATE:
726*cdf0e10cSrcweir 						*V_DATEREF(pDest) = V_DATE(pSource);
727*cdf0e10cSrcweir 						ret	= sal_True;
728*cdf0e10cSrcweir 						break;
729*cdf0e10cSrcweir 					case VT_BSTR:
730*cdf0e10cSrcweir 						SysFreeString( *pDest->pbstrVal);
731*cdf0e10cSrcweir 
732*cdf0e10cSrcweir 						*V_BSTRREF(pDest) = SysAllocString(V_BSTR(pSource));
733*cdf0e10cSrcweir 						ret	= sal_True;
734*cdf0e10cSrcweir 						break;
735*cdf0e10cSrcweir 					case VT_DISPATCH:
736*cdf0e10cSrcweir 						if (*V_DISPATCHREF(pDest) != NULL)
737*cdf0e10cSrcweir 							(*V_DISPATCHREF(pDest))->Release();
738*cdf0e10cSrcweir 
739*cdf0e10cSrcweir 						*V_DISPATCHREF(pDest) = V_DISPATCH(pSource);
740*cdf0e10cSrcweir 
741*cdf0e10cSrcweir 						if (*V_DISPATCHREF(pDest) != NULL)
742*cdf0e10cSrcweir 							(*V_DISPATCHREF(pDest))->AddRef();
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir 						ret	= sal_True;
745*cdf0e10cSrcweir 						break;
746*cdf0e10cSrcweir 					case VT_ERROR:
747*cdf0e10cSrcweir 						*V_ERRORREF(pDest) = V_ERROR(pSource);
748*cdf0e10cSrcweir 						ret	= sal_True;
749*cdf0e10cSrcweir 						break;
750*cdf0e10cSrcweir 					case VT_BOOL:
751*cdf0e10cSrcweir 						*V_BOOLREF(pDest) = V_BOOL(pSource);
752*cdf0e10cSrcweir 						ret	= sal_True;
753*cdf0e10cSrcweir 						break;
754*cdf0e10cSrcweir 					case VT_UNKNOWN:
755*cdf0e10cSrcweir 						if (*V_UNKNOWNREF(pDest) != NULL)
756*cdf0e10cSrcweir 							(*V_UNKNOWNREF(pDest))->Release();
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir 						*V_UNKNOWNREF(pDest) = V_UNKNOWN(pSource);
759*cdf0e10cSrcweir 
760*cdf0e10cSrcweir 						if (*V_UNKNOWNREF(pDest) != NULL)
761*cdf0e10cSrcweir 							(*V_UNKNOWNREF(pDest))->AddRef();
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir 						ret	= sal_True;
764*cdf0e10cSrcweir 						break;
765*cdf0e10cSrcweir 					case VT_I1:
766*cdf0e10cSrcweir 						*V_I1REF(pDest) = V_I1(pSource);
767*cdf0e10cSrcweir 						ret	= sal_True;
768*cdf0e10cSrcweir 						break;
769*cdf0e10cSrcweir 					case VT_UI1:
770*cdf0e10cSrcweir 						*V_UI1REF(pDest) = V_UI1(pSource);
771*cdf0e10cSrcweir 						ret	= sal_True;
772*cdf0e10cSrcweir 						break;
773*cdf0e10cSrcweir 					case VT_UI2:
774*cdf0e10cSrcweir 						*V_UI2REF(pDest) = V_UI2(pSource);
775*cdf0e10cSrcweir 						ret	= sal_True;
776*cdf0e10cSrcweir 						break;
777*cdf0e10cSrcweir 					case VT_UI4:
778*cdf0e10cSrcweir 						*V_UI4REF(pDest) = V_UI4(pSource);
779*cdf0e10cSrcweir 						ret	= sal_True;
780*cdf0e10cSrcweir 						break;
781*cdf0e10cSrcweir 					case VT_INT:
782*cdf0e10cSrcweir 						*V_INTREF(pDest) = V_INT(pSource);
783*cdf0e10cSrcweir 						ret	= sal_True;
784*cdf0e10cSrcweir 						break;
785*cdf0e10cSrcweir 					case VT_UINT:
786*cdf0e10cSrcweir 						*V_UINTREF(pDest) = V_UINT(pSource);
787*cdf0e10cSrcweir 						ret	= sal_True;
788*cdf0e10cSrcweir 						break;
789*cdf0e10cSrcweir 					case VT_DECIMAL:
790*cdf0e10cSrcweir                         memcpy(pDest->pdecVal, pSource, sizeof(DECIMAL));
791*cdf0e10cSrcweir                         ret = sal_True;
792*cdf0e10cSrcweir                         break;
793*cdf0e10cSrcweir 					default:
794*cdf0e10cSrcweir 						break;
795*cdf0e10cSrcweir 					}
796*cdf0e10cSrcweir 				}
797*cdf0e10cSrcweir 			}
798*cdf0e10cSrcweir 			else
799*cdf0e10cSrcweir 			{
800*cdf0e10cSrcweir 				// Handling of special cases
801*cdf0e10cSrcweir 				// Destination and source types are different
802*cdf0e10cSrcweir 				if( pDest->vt == (VT_BSTR | VT_BYREF)
803*cdf0e10cSrcweir 					&& pSource->vt == VT_I2)
804*cdf0e10cSrcweir 				{
805*cdf0e10cSrcweir 					// When the user provides a String as out our in/out parameter
806*cdf0e10cSrcweir 					// and the type is char (TypeClass_CHAR) then we convert to a BSTR
807*cdf0e10cSrcweir 					// instead of VT_I2 as is done otherwise
808*cdf0e10cSrcweir 					OLECHAR buff[]= {0,0};
809*cdf0e10cSrcweir 					buff[0]= pSource->iVal;
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir 					SysFreeString( *pDest->pbstrVal);
812*cdf0e10cSrcweir 					*pDest->pbstrVal= SysAllocString( buff);
813*cdf0e10cSrcweir 					ret = sal_True;
814*cdf0e10cSrcweir 				}
815*cdf0e10cSrcweir 			}
816*cdf0e10cSrcweir 		}
817*cdf0e10cSrcweir 	}
818*cdf0e10cSrcweir 	return ret;
819*cdf0e10cSrcweir }
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::Invoke(DISPID dispidMember,
822*cdf0e10cSrcweir 											  REFIID /*riid*/,
823*cdf0e10cSrcweir 											  LCID /*lcid*/,
824*cdf0e10cSrcweir 											  unsigned short wFlags,
825*cdf0e10cSrcweir                      						  DISPPARAMS * pdispparams,
826*cdf0e10cSrcweir 											  VARIANT * pvarResult,
827*cdf0e10cSrcweir 											  EXCEPINFO * pexcepinfo,
828*cdf0e10cSrcweir                      						  unsigned int * puArgErr )
829*cdf0e10cSrcweir {
830*cdf0e10cSrcweir 	HRESULT ret = S_OK;
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir     try
833*cdf0e10cSrcweir     {
834*cdf0e10cSrcweir         sal_Bool bHandled= sal_False;
835*cdf0e10cSrcweir         ret= InvokeGeneral( dispidMember,  wFlags, pdispparams, pvarResult,  pexcepinfo,
836*cdf0e10cSrcweir                             puArgErr, bHandled);
837*cdf0e10cSrcweir         if( bHandled)
838*cdf0e10cSrcweir             return ret;
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir         if ((dispidMember > 0) && ((size_t)dispidMember <= m_MemberInfos.size()) && m_xInvocation.is())
841*cdf0e10cSrcweir         {
842*cdf0e10cSrcweir             MemberInfo d = m_MemberInfos[dispidMember - 1];
843*cdf0e10cSrcweir             DWORD flags = wFlags & d.flags;
844*cdf0e10cSrcweir 
845*cdf0e10cSrcweir             if (flags != 0)
846*cdf0e10cSrcweir             {
847*cdf0e10cSrcweir                 if ((flags & DISPATCH_METHOD) != 0)
848*cdf0e10cSrcweir                 {
849*cdf0e10cSrcweir                     if (pdispparams->cNamedArgs	> 0)
850*cdf0e10cSrcweir                         ret = DISP_E_NONAMEDARGS;
851*cdf0e10cSrcweir                     else
852*cdf0e10cSrcweir                     {
853*cdf0e10cSrcweir                         Sequence<Any> params;
854*cdf0e10cSrcweir 
855*cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams , params );
856*cdf0e10cSrcweir 
857*cdf0e10cSrcweir                         ret= doInvoke(pdispparams, pvarResult,
858*cdf0e10cSrcweir                                       pexcepinfo, puArgErr, d.name, params);
859*cdf0e10cSrcweir                     }
860*cdf0e10cSrcweir                 }
861*cdf0e10cSrcweir                 else if ((flags & DISPATCH_PROPERTYGET) != 0)
862*cdf0e10cSrcweir                 {
863*cdf0e10cSrcweir                     ret=  doGetProperty( pdispparams, pvarResult,
864*cdf0e10cSrcweir                                          pexcepinfo, d.name);
865*cdf0e10cSrcweir                 }
866*cdf0e10cSrcweir                 else if ((flags & DISPATCH_PROPERTYPUT || flags & DISPATCH_PROPERTYPUTREF) != 0)
867*cdf0e10cSrcweir                 {
868*cdf0e10cSrcweir                     if (pdispparams->cArgs != 1)
869*cdf0e10cSrcweir                         ret = DISP_E_BADPARAMCOUNT;
870*cdf0e10cSrcweir                     else
871*cdf0e10cSrcweir                     {
872*cdf0e10cSrcweir                         Sequence<Any> params;
873*cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
874*cdf0e10cSrcweir                         if(params.getLength() > 0)
875*cdf0e10cSrcweir                             ret= doSetProperty( pdispparams, pvarResult, pexcepinfo, puArgErr, d.name, params);
876*cdf0e10cSrcweir                         else
877*cdf0e10cSrcweir                             ret = DISP_E_BADVARTYPE;
878*cdf0e10cSrcweir                     }
879*cdf0e10cSrcweir                 }
880*cdf0e10cSrcweir             }
881*cdf0e10cSrcweir             else
882*cdf0e10cSrcweir                 ret= DISP_E_MEMBERNOTFOUND;
883*cdf0e10cSrcweir         }
884*cdf0e10cSrcweir         else
885*cdf0e10cSrcweir             ret = DISP_E_MEMBERNOTFOUND;
886*cdf0e10cSrcweir     }
887*cdf0e10cSrcweir     catch(BridgeRuntimeError& e)
888*cdf0e10cSrcweir     {
889*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
890*cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
891*cdf0e10cSrcweir     }
892*cdf0e10cSrcweir     catch(Exception& e)
893*cdf0e10cSrcweir     {
894*cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::Invoke : \n") +
895*cdf0e10cSrcweir                                 e.Message;
896*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
897*cdf0e10cSrcweir 		ret = DISP_E_EXCEPTION;
898*cdf0e10cSrcweir     }
899*cdf0e10cSrcweir 	catch(...)
900*cdf0e10cSrcweir 	{
901*cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::Invoke : \n"
902*cdf0e10cSrcweir                                 "Unexpected exception");
903*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
904*cdf0e10cSrcweir  		ret = DISP_E_EXCEPTION;
905*cdf0e10cSrcweir 	}
906*cdf0e10cSrcweir 
907*cdf0e10cSrcweir 	return ret;
908*cdf0e10cSrcweir }
909*cdf0e10cSrcweir 
910*cdf0e10cSrcweir HRESULT InterfaceOleWrapper_Impl::doInvoke( DISPPARAMS * pdispparams, VARIANT * pvarResult,
911*cdf0e10cSrcweir 							  EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString& name, Sequence<Any>& params)
912*cdf0e10cSrcweir {
913*cdf0e10cSrcweir 
914*cdf0e10cSrcweir 
915*cdf0e10cSrcweir 	HRESULT ret= S_OK;
916*cdf0e10cSrcweir     try
917*cdf0e10cSrcweir     {
918*cdf0e10cSrcweir         Sequence<sal_Int16> 	outIndex;
919*cdf0e10cSrcweir         Sequence<Any> 	outParams;
920*cdf0e10cSrcweir         Any 				returnValue;
921*cdf0e10cSrcweir 
922*cdf0e10cSrcweir         if (pdispparams->cNamedArgs	> 0)
923*cdf0e10cSrcweir             return DISP_E_NONAMEDARGS;
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir         // invoke method and take care of exceptions
926*cdf0e10cSrcweir 		returnValue = m_xInvocation->invoke(name,
927*cdf0e10cSrcweir 											params,
928*cdf0e10cSrcweir 											outIndex,
929*cdf0e10cSrcweir 											outParams);
930*cdf0e10cSrcweir 
931*cdf0e10cSrcweir         // try to write back out parameter
932*cdf0e10cSrcweir         if (outIndex.getLength() > 0)
933*cdf0e10cSrcweir         {
934*cdf0e10cSrcweir             const sal_Int16* pOutIndex = outIndex.getConstArray();
935*cdf0e10cSrcweir             const Any* pOutParams = outParams.getConstArray();
936*cdf0e10cSrcweir 
937*cdf0e10cSrcweir             for (sal_Int32 i = 0; i < outIndex.getLength(); i++)
938*cdf0e10cSrcweir             {
939*cdf0e10cSrcweir                 CComVariant variant;
940*cdf0e10cSrcweir                 // Currently a Sequence is converted to an SafeArray of VARIANTs.
941*cdf0e10cSrcweir                 anyToVariant( &variant, pOutParams[i]);
942*cdf0e10cSrcweir 
943*cdf0e10cSrcweir                 // out parameter need special handling if they are VT_DISPATCH
944*cdf0e10cSrcweir                 // and used in JScript
945*cdf0e10cSrcweir                 int outindex= pOutIndex[i];
946*cdf0e10cSrcweir                 writeBackOutParameter2(&(pdispparams->rgvarg[pdispparams->cArgs - 1 - outindex]),
947*cdf0e10cSrcweir                                        &variant );
948*cdf0e10cSrcweir             }
949*cdf0e10cSrcweir         }
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir         // write back return value
952*cdf0e10cSrcweir         if (pvarResult != NULL)
953*cdf0e10cSrcweir             anyToVariant(pvarResult, returnValue);
954*cdf0e10cSrcweir     }
955*cdf0e10cSrcweir 	catch(IllegalArgumentException & e) //XInvocation::invoke
956*cdf0e10cSrcweir 	{
957*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.Message);
958*cdf0e10cSrcweir 		ret = DISP_E_TYPEMISMATCH;
959*cdf0e10cSrcweir 	}
960*cdf0e10cSrcweir 	catch(CannotConvertException & e) //XInvocation::invoke
961*cdf0e10cSrcweir 	{
962*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.Message);
963*cdf0e10cSrcweir 		ret = mapCannotConvertException( e, puArgErr);
964*cdf0e10cSrcweir 	}
965*cdf0e10cSrcweir 	catch(InvocationTargetException &  e) //XInvocation::invoke
966*cdf0e10cSrcweir 	{
967*cdf0e10cSrcweir         const Any& org = e.TargetException;
968*cdf0e10cSrcweir         Exception excTarget;
969*cdf0e10cSrcweir         org >>= excTarget;
970*cdf0e10cSrcweir         OUString message=
971*cdf0e10cSrcweir             org.getValueType().getTypeName() + OUSTR(": ") + excTarget.Message;
972*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
973*cdf0e10cSrcweir 		ret = DISP_E_EXCEPTION;
974*cdf0e10cSrcweir 	}
975*cdf0e10cSrcweir 	catch(NoSuchMethodException & e) //XInvocation::invoke
976*cdf0e10cSrcweir 	{
977*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.Message);
978*cdf0e10cSrcweir 		ret = DISP_E_MEMBERNOTFOUND;
979*cdf0e10cSrcweir 	}
980*cdf0e10cSrcweir     catch(BridgeRuntimeError & e)
981*cdf0e10cSrcweir     {
982*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
983*cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
984*cdf0e10cSrcweir     }
985*cdf0e10cSrcweir     catch(Exception & e)
986*cdf0e10cSrcweir     {
987*cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n") +
988*cdf0e10cSrcweir                                 e.Message;
989*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
990*cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
991*cdf0e10cSrcweir     }
992*cdf0e10cSrcweir     catch( ... )
993*cdf0e10cSrcweir  	{
994*cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n"
995*cdf0e10cSrcweir                                 "Unexpected exception");
996*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
997*cdf0e10cSrcweir  		ret = DISP_E_EXCEPTION;
998*cdf0e10cSrcweir  	}
999*cdf0e10cSrcweir 	return ret;
1000*cdf0e10cSrcweir }
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir HRESULT InterfaceOleWrapper_Impl::doGetProperty( DISPPARAMS * /*pdispparams*/, VARIANT * pvarResult,
1003*cdf0e10cSrcweir 												EXCEPINFO * pexcepinfo, OUString& name)
1004*cdf0e10cSrcweir {
1005*cdf0e10cSrcweir 	HRESULT ret= S_OK;
1006*cdf0e10cSrcweir 
1007*cdf0e10cSrcweir 	Any value;
1008*cdf0e10cSrcweir 	try
1009*cdf0e10cSrcweir 	{
1010*cdf0e10cSrcweir 		Any returnValue = m_xInvocation->getValue( name);
1011*cdf0e10cSrcweir 		// write back return value
1012*cdf0e10cSrcweir 		if (pvarResult)
1013*cdf0e10cSrcweir             anyToVariant(pvarResult, returnValue);
1014*cdf0e10cSrcweir 	}
1015*cdf0e10cSrcweir 	catch(UnknownPropertyException e) //XInvocation::getValue
1016*cdf0e10cSrcweir 	{
1017*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.Message);
1018*cdf0e10cSrcweir 		ret = DISP_E_MEMBERNOTFOUND;
1019*cdf0e10cSrcweir 	}
1020*cdf0e10cSrcweir     catch(BridgeRuntimeError& e)
1021*cdf0e10cSrcweir     {
1022*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
1023*cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1024*cdf0e10cSrcweir     }
1025*cdf0e10cSrcweir     catch(Exception& e)
1026*cdf0e10cSrcweir     {
1027*cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::doGetProperty : \n") +
1028*cdf0e10cSrcweir                                 e.Message;
1029*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1030*cdf0e10cSrcweir     }
1031*cdf0e10cSrcweir 	catch( ... )
1032*cdf0e10cSrcweir 	{
1033*cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n"
1034*cdf0e10cSrcweir                                 "Unexpected exception");
1035*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1036*cdf0e10cSrcweir  		ret = DISP_E_EXCEPTION;
1037*cdf0e10cSrcweir 	}
1038*cdf0e10cSrcweir 	return  ret;
1039*cdf0e10cSrcweir }
1040*cdf0e10cSrcweir 
1041*cdf0e10cSrcweir HRESULT InterfaceOleWrapper_Impl::doSetProperty( DISPPARAMS * /*pdispparams*/, VARIANT * /*pvarResult*/,
1042*cdf0e10cSrcweir 										EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString& name, Sequence<Any> params)
1043*cdf0e10cSrcweir {
1044*cdf0e10cSrcweir 	HRESULT ret= S_OK;
1045*cdf0e10cSrcweir 
1046*cdf0e10cSrcweir 	try
1047*cdf0e10cSrcweir 	{
1048*cdf0e10cSrcweir 		m_xInvocation->setValue( name, params.getConstArray()[0]);
1049*cdf0e10cSrcweir 	}
1050*cdf0e10cSrcweir 	catch(UnknownPropertyException )
1051*cdf0e10cSrcweir 	{
1052*cdf0e10cSrcweir 		ret = DISP_E_MEMBERNOTFOUND;
1053*cdf0e10cSrcweir 	}
1054*cdf0e10cSrcweir 	catch(CannotConvertException e)
1055*cdf0e10cSrcweir 	{
1056*cdf0e10cSrcweir 		ret= mapCannotConvertException( e, puArgErr);
1057*cdf0e10cSrcweir 	}
1058*cdf0e10cSrcweir 	catch(InvocationTargetException e)
1059*cdf0e10cSrcweir 	{
1060*cdf0e10cSrcweir 		if (pexcepinfo != NULL)
1061*cdf0e10cSrcweir 		{
1062*cdf0e10cSrcweir 			Any org = e.TargetException;
1063*cdf0e10cSrcweir 
1064*cdf0e10cSrcweir 			pexcepinfo->wCode = UNO_2_OLE_EXCEPTIONCODE;
1065*cdf0e10cSrcweir 			pexcepinfo->bstrSource = SysAllocString(L"any ONE component");
1066*cdf0e10cSrcweir 			pexcepinfo->bstrDescription = SysAllocString(
1067*cdf0e10cSrcweir 				reinterpret_cast<LPCOLESTR>(org.getValueType().getTypeName().getStr()));
1068*cdf0e10cSrcweir 		}
1069*cdf0e10cSrcweir 		ret = DISP_E_EXCEPTION;
1070*cdf0e10cSrcweir 	}
1071*cdf0e10cSrcweir 	catch( ... )
1072*cdf0e10cSrcweir 	{
1073*cdf0e10cSrcweir 		ret= DISP_E_EXCEPTION;
1074*cdf0e10cSrcweir 	}
1075*cdf0e10cSrcweir 	return ret;
1076*cdf0e10cSrcweir }
1077*cdf0e10cSrcweir 
1078*cdf0e10cSrcweir HRESULT InterfaceOleWrapper_Impl::InvokeGeneral( DISPID dispidMember, unsigned short wFlags,
1079*cdf0e10cSrcweir 	                     DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
1080*cdf0e10cSrcweir 	                     unsigned int * /*puArgErr*/, sal_Bool& bHandled)
1081*cdf0e10cSrcweir {
1082*cdf0e10cSrcweir 	HRESULT ret= S_OK;
1083*cdf0e10cSrcweir     try
1084*cdf0e10cSrcweir     {
1085*cdf0e10cSrcweir // DISPID_VALUE | The DEFAULT Value is required in JScript when the situation
1086*cdf0e10cSrcweir // is that we put an object into an Array object ( out parameter). We have to return
1087*cdf0e10cSrcweir // IDispatch otherwise the object cannot be accessed from the Script.
1088*cdf0e10cSrcweir         if( dispidMember == DISPID_VALUE && wFlags == DISPATCH_PROPERTYGET
1089*cdf0e10cSrcweir             && m_defaultValueType != VT_EMPTY && pvarResult != NULL)
1090*cdf0e10cSrcweir         {
1091*cdf0e10cSrcweir             bHandled= sal_True;
1092*cdf0e10cSrcweir             if( m_defaultValueType == VT_DISPATCH)
1093*cdf0e10cSrcweir             {
1094*cdf0e10cSrcweir                 pvarResult->vt= VT_DISPATCH;
1095*cdf0e10cSrcweir                 pvarResult->pdispVal= static_cast<IDispatch*>( this);
1096*cdf0e10cSrcweir                 AddRef();
1097*cdf0e10cSrcweir                 ret= S_OK;
1098*cdf0e10cSrcweir             }
1099*cdf0e10cSrcweir         }
1100*cdf0e10cSrcweir // ---------
1101*cdf0e10cSrcweir         // function: _GetValueObject
1102*cdf0e10cSrcweir         else if( dispidMember == DISPID_JSCRIPT_VALUE_FUNC)
1103*cdf0e10cSrcweir         {
1104*cdf0e10cSrcweir             bHandled= sal_True;
1105*cdf0e10cSrcweir             if( !pvarResult)
1106*cdf0e10cSrcweir                 ret= E_POINTER;
1107*cdf0e10cSrcweir             CComObject< JScriptValue>* pValue;
1108*cdf0e10cSrcweir             if( SUCCEEDED( CComObject<JScriptValue>::CreateInstance( &pValue)))
1109*cdf0e10cSrcweir             {
1110*cdf0e10cSrcweir                 pValue->AddRef();
1111*cdf0e10cSrcweir                 pvarResult->vt= VT_DISPATCH;
1112*cdf0e10cSrcweir #ifdef __MINGW32__
1113*cdf0e10cSrcweir                 pvarResult->pdispVal= CComQIPtr<IDispatch, &__uuidof(IDispatch)>(pValue->GetUnknown());
1114*cdf0e10cSrcweir #else
1115*cdf0e10cSrcweir                 pvarResult->pdispVal= CComQIPtr<IDispatch>(pValue->GetUnknown());
1116*cdf0e10cSrcweir #endif
1117*cdf0e10cSrcweir                 ret= S_OK;
1118*cdf0e10cSrcweir             }
1119*cdf0e10cSrcweir             else
1120*cdf0e10cSrcweir                 ret= DISP_E_EXCEPTION;
1121*cdf0e10cSrcweir         }
1122*cdf0e10cSrcweir         else if( dispidMember == DISPID_GET_STRUCT_FUNC)
1123*cdf0e10cSrcweir         {
1124*cdf0e10cSrcweir             bHandled= sal_True;
1125*cdf0e10cSrcweir             sal_Bool bStruct= sal_False;
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir 
1128*cdf0e10cSrcweir             Reference<XInterface> xIntCore=	m_smgr->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection"));
1129*cdf0e10cSrcweir             Reference<XIdlReflection> xRefl( xIntCore, UNO_QUERY);
1130*cdf0e10cSrcweir             if( xRefl.is() )
1131*cdf0e10cSrcweir             {
1132*cdf0e10cSrcweir                 // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1133*cdf0e10cSrcweir                 CComVariant arg;
1134*cdf0e10cSrcweir                 if( pdispparams->cArgs == 1 && SUCCEEDED( arg.ChangeType( VT_BSTR, &pdispparams->rgvarg[0])) )
1135*cdf0e10cSrcweir                 {
1136*cdf0e10cSrcweir                     Reference<XIdlClass> classStruct= xRefl->forName( reinterpret_cast<const sal_Unicode*>(arg.bstrVal));
1137*cdf0e10cSrcweir                     if( classStruct.is())
1138*cdf0e10cSrcweir                     {
1139*cdf0e10cSrcweir                         Any anyStruct;
1140*cdf0e10cSrcweir                         classStruct->createObject( anyStruct);
1141*cdf0e10cSrcweir                         CComVariant var;
1142*cdf0e10cSrcweir                         anyToVariant( &var, anyStruct );
1143*cdf0e10cSrcweir 
1144*cdf0e10cSrcweir                         if( var.vt == VT_DISPATCH)
1145*cdf0e10cSrcweir                         {
1146*cdf0e10cSrcweir                             VariantCopy( pvarResult, & var);
1147*cdf0e10cSrcweir                             bStruct= sal_True;
1148*cdf0e10cSrcweir                         }
1149*cdf0e10cSrcweir                     }
1150*cdf0e10cSrcweir                 }
1151*cdf0e10cSrcweir             }
1152*cdf0e10cSrcweir             ret= bStruct == sal_True ? S_OK : DISP_E_EXCEPTION;
1153*cdf0e10cSrcweir         }
1154*cdf0e10cSrcweir         else if (dispidMember == DISPID_CREATE_TYPE_FUNC)
1155*cdf0e10cSrcweir         {
1156*cdf0e10cSrcweir             bHandled= sal_True;
1157*cdf0e10cSrcweir             if( !pvarResult)
1158*cdf0e10cSrcweir                 ret= E_POINTER;
1159*cdf0e10cSrcweir             // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1160*cdf0e10cSrcweir             CComVariant arg;
1161*cdf0e10cSrcweir             if( pdispparams->cArgs != 1)
1162*cdf0e10cSrcweir                 return DISP_E_BADPARAMCOUNT;
1163*cdf0e10cSrcweir             if (FAILED( arg.ChangeType( VT_BSTR, &pdispparams->rgvarg[0])))
1164*cdf0e10cSrcweir                 return DISP_E_BADVARTYPE;
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir             //check if the provided name represents a valid type
1167*cdf0e10cSrcweir             Type type;
1168*cdf0e10cSrcweir             if (getType(arg.bstrVal, type) == false)
1169*cdf0e10cSrcweir             {
1170*cdf0e10cSrcweir                 writeExcepinfo(pexcepinfo,OUString(
1171*cdf0e10cSrcweir                                    OUSTR("[automation bridge] A UNO type with the name ") +
1172*cdf0e10cSrcweir                                    OUString(reinterpret_cast<const sal_Unicode*>(arg.bstrVal)) + OUSTR(" does not exist!")));
1173*cdf0e10cSrcweir                 return DISP_E_EXCEPTION;
1174*cdf0e10cSrcweir             }
1175*cdf0e10cSrcweir 
1176*cdf0e10cSrcweir             if (createUnoTypeWrapper(arg.bstrVal, pvarResult) == false)
1177*cdf0e10cSrcweir             {
1178*cdf0e10cSrcweir                 writeExcepinfo(pexcepinfo,OUSTR("[automation bridge] InterfaceOleWrapper_Impl::InvokeGeneral\n"
1179*cdf0e10cSrcweir                                                 "Could not initialize UnoTypeWrapper object!"));
1180*cdf0e10cSrcweir                 return DISP_E_EXCEPTION;
1181*cdf0e10cSrcweir             }
1182*cdf0e10cSrcweir         }
1183*cdf0e10cSrcweir     }
1184*cdf0e10cSrcweir     catch(BridgeRuntimeError & e)
1185*cdf0e10cSrcweir     {
1186*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
1187*cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1188*cdf0e10cSrcweir     }
1189*cdf0e10cSrcweir     catch(Exception & e)
1190*cdf0e10cSrcweir     {
1191*cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::InvokeGeneral : \n") +
1192*cdf0e10cSrcweir                                 e.Message;
1193*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1194*cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1195*cdf0e10cSrcweir     }
1196*cdf0e10cSrcweir     catch( ... )
1197*cdf0e10cSrcweir  	{
1198*cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::InvokeGeneral : \n"
1199*cdf0e10cSrcweir                                 "Unexpected exception");
1200*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1201*cdf0e10cSrcweir  		ret = DISP_E_EXCEPTION;
1202*cdf0e10cSrcweir  	}
1203*cdf0e10cSrcweir 	return ret;
1204*cdf0e10cSrcweir }
1205*cdf0e10cSrcweir 
1206*cdf0e10cSrcweir 
1207*cdf0e10cSrcweir 
1208*cdf0e10cSrcweir 
1209*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetDispID(BSTR /*bstrName*/, DWORD /*grfdex*/, DISPID __RPC_FAR* /*pid*/)
1210*cdf0e10cSrcweir {
1211*cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir 	return ret;
1214*cdf0e10cSrcweir }
1215*cdf0e10cSrcweir 
1216*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::InvokeEx(
1217*cdf0e10cSrcweir 	/* [in] */ DISPID /*id*/,
1218*cdf0e10cSrcweir 	/* [in] */ LCID /*lcid*/,
1219*cdf0e10cSrcweir 	/* [in] */ WORD /*wFlags*/,
1220*cdf0e10cSrcweir 	/* [in] */ DISPPARAMS __RPC_FAR* /*pdp*/,
1221*cdf0e10cSrcweir 	/* [out] */ VARIANT __RPC_FAR* /*pvarRes*/,
1222*cdf0e10cSrcweir 	/* [out] */ EXCEPINFO __RPC_FAR* /*pei*/,
1223*cdf0e10cSrcweir 	/* [unique][in] */ IServiceProvider __RPC_FAR* /*pspCaller*/)
1224*cdf0e10cSrcweir {
1225*cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1226*cdf0e10cSrcweir 
1227*cdf0e10cSrcweir 	return ret;
1228*cdf0e10cSrcweir }
1229*cdf0e10cSrcweir 
1230*cdf0e10cSrcweir 
1231*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::DeleteMemberByName(
1232*cdf0e10cSrcweir     /* [in] */ BSTR /*bstr*/,
1233*cdf0e10cSrcweir     /* [in] */ DWORD /*grfdex*/)
1234*cdf0e10cSrcweir {
1235*cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1236*cdf0e10cSrcweir 
1237*cdf0e10cSrcweir 	return ret;
1238*cdf0e10cSrcweir }
1239*cdf0e10cSrcweir 
1240*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::DeleteMemberByDispID(DISPID /*id*/)
1241*cdf0e10cSrcweir {
1242*cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir 	return ret;
1245*cdf0e10cSrcweir }
1246*cdf0e10cSrcweir 
1247*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetMemberProperties(
1248*cdf0e10cSrcweir     /* [in] */ DISPID /*id*/,
1249*cdf0e10cSrcweir     /* [in] */ DWORD /*grfdexFetch*/,
1250*cdf0e10cSrcweir     /* [out] */ DWORD __RPC_FAR* /*pgrfdex*/)
1251*cdf0e10cSrcweir {
1252*cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1253*cdf0e10cSrcweir 
1254*cdf0e10cSrcweir 	return ret;
1255*cdf0e10cSrcweir }
1256*cdf0e10cSrcweir 
1257*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetMemberName(
1258*cdf0e10cSrcweir     /* [in] */ DISPID /*id*/,
1259*cdf0e10cSrcweir     /* [out] */ BSTR __RPC_FAR* /*pbstrName*/)
1260*cdf0e10cSrcweir {
1261*cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1262*cdf0e10cSrcweir 
1263*cdf0e10cSrcweir 	return ret;
1264*cdf0e10cSrcweir }
1265*cdf0e10cSrcweir 
1266*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetNextDispID(
1267*cdf0e10cSrcweir     /* [in] */ DWORD /*grfdex*/,
1268*cdf0e10cSrcweir     /* [in] */ DISPID /*id*/,
1269*cdf0e10cSrcweir     /* [out] */ DISPID __RPC_FAR* /*pid*/)
1270*cdf0e10cSrcweir {
1271*cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1272*cdf0e10cSrcweir 
1273*cdf0e10cSrcweir 	return ret;
1274*cdf0e10cSrcweir }
1275*cdf0e10cSrcweir 
1276*cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetNameSpaceParent(
1277*cdf0e10cSrcweir     /* [out] */ IUnknown __RPC_FAR *__RPC_FAR* /*ppunk*/)
1278*cdf0e10cSrcweir {
1279*cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1280*cdf0e10cSrcweir 
1281*cdf0e10cSrcweir 	return ret;
1282*cdf0e10cSrcweir }
1283*cdf0e10cSrcweir 
1284*cdf0e10cSrcweir 
1285*cdf0e10cSrcweir /*************************************************************************
1286*cdf0e10cSrcweir 
1287*cdf0e10cSrcweir 	UnoObjectWrapperRemoteOpt
1288*cdf0e10cSrcweir 
1289*cdf0e10cSrcweir *************************************************************************/
1290*cdf0e10cSrcweir UnoObjectWrapperRemoteOpt::UnoObjectWrapperRemoteOpt( Reference<XMultiServiceFactory>& aFactory,
1291*cdf0e10cSrcweir 													 sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass):
1292*cdf0e10cSrcweir InterfaceOleWrapper_Impl( aFactory, unoWrapperClass, comWrapperClass),
1293*cdf0e10cSrcweir m_currentId(1)
1294*cdf0e10cSrcweir 
1295*cdf0e10cSrcweir {
1296*cdf0e10cSrcweir }
1297*cdf0e10cSrcweir UnoObjectWrapperRemoteOpt::~UnoObjectWrapperRemoteOpt()
1298*cdf0e10cSrcweir {
1299*cdf0e10cSrcweir }
1300*cdf0e10cSrcweir 
1301*cdf0e10cSrcweir // UnoConversionUtilities
1302*cdf0e10cSrcweir Reference< XInterface > UnoObjectWrapperRemoteOpt::createUnoWrapperInstance()
1303*cdf0e10cSrcweir {
1304*cdf0e10cSrcweir 	Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
1305*cdf0e10cSrcweir 												 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
1306*cdf0e10cSrcweir 	return Reference<XInterface>( xWeak, UNO_QUERY);
1307*cdf0e10cSrcweir }
1308*cdf0e10cSrcweir 
1309*cdf0e10cSrcweir STDMETHODIMP  UnoObjectWrapperRemoteOpt::GetIDsOfNames ( REFIID /*riid*/, OLECHAR ** rgszNames, unsigned int cNames,
1310*cdf0e10cSrcweir 								LCID /*lcid*/, DISPID * rgdispid )
1311*cdf0e10cSrcweir {
1312*cdf0e10cSrcweir 	MutexGuard guard( getBridgeMutex());
1313*cdf0e10cSrcweir 
1314*cdf0e10cSrcweir 	if( ! rgdispid)
1315*cdf0e10cSrcweir 		return E_POINTER;
1316*cdf0e10cSrcweir 	HRESULT ret = E_UNEXPECTED;
1317*cdf0e10cSrcweir 	// ----------------------------------------
1318*cdf0e10cSrcweir 	// _GetValueObject
1319*cdf0e10cSrcweir 	if( ! wcscmp( *rgszNames, JSCRIPT_VALUE_FUNC))
1320*cdf0e10cSrcweir 	{
1321*cdf0e10cSrcweir 		*rgdispid= DISPID_JSCRIPT_VALUE_FUNC;
1322*cdf0e10cSrcweir 		return S_OK;
1323*cdf0e10cSrcweir 	}
1324*cdf0e10cSrcweir 	else if( ! wcscmp( *rgszNames, GET_STRUCT_FUNC))
1325*cdf0e10cSrcweir 	{
1326*cdf0e10cSrcweir 		*rgdispid= DISPID_GET_STRUCT_FUNC;
1327*cdf0e10cSrcweir 		return S_OK;
1328*cdf0e10cSrcweir 	}
1329*cdf0e10cSrcweir 
1330*cdf0e10cSrcweir 	// ----------------------------------------
1331*cdf0e10cSrcweir 	if (m_xInvocation.is() && (cNames > 0))
1332*cdf0e10cSrcweir 	{
1333*cdf0e10cSrcweir 		OUString name(reinterpret_cast<const sal_Unicode*>(rgszNames[0]));
1334*cdf0e10cSrcweir 		// has this name been determined as "bad"
1335*cdf0e10cSrcweir 		BadNameMap::iterator badIter= m_badNameMap.find( name);
1336*cdf0e10cSrcweir 		if( badIter == m_badNameMap.end() )
1337*cdf0e10cSrcweir 		{
1338*cdf0e10cSrcweir 			// name has not been bad before( member exists
1339*cdf0e10cSrcweir 			typedef NameToIdMap::iterator ITnames;
1340*cdf0e10cSrcweir 			pair< ITnames, bool > pair_id= m_nameToDispIdMap.insert( NameToIdMap::value_type(name, m_currentId++));
1341*cdf0e10cSrcweir 			// new ID inserted ?
1342*cdf0e10cSrcweir 			if( pair_id.second )
1343*cdf0e10cSrcweir 			{// yes, now create MemberInfo and ad to IdToMemberInfoMap
1344*cdf0e10cSrcweir 				MemberInfo d(0, name);
1345*cdf0e10cSrcweir 				m_idToMemberInfoMap.insert( IdToMemberInfoMap::value_type( m_currentId - 1, d));
1346*cdf0e10cSrcweir 			}
1347*cdf0e10cSrcweir 
1348*cdf0e10cSrcweir 			*rgdispid = pair_id.first->second;
1349*cdf0e10cSrcweir 			ret = S_OK;
1350*cdf0e10cSrcweir 		}
1351*cdf0e10cSrcweir 		else
1352*cdf0e10cSrcweir 			ret= DISP_E_UNKNOWNNAME;
1353*cdf0e10cSrcweir 	}
1354*cdf0e10cSrcweir 	return ret;
1355*cdf0e10cSrcweir }
1356*cdf0e10cSrcweir 
1357*cdf0e10cSrcweir STDMETHODIMP  UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID /*riid*/, LCID /*lcid*/, unsigned short wFlags,
1358*cdf0e10cSrcweir 	                     DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
1359*cdf0e10cSrcweir 	                     unsigned int * puArgErr )
1360*cdf0e10cSrcweir {
1361*cdf0e10cSrcweir 	HRESULT ret = S_OK;
1362*cdf0e10cSrcweir     try
1363*cdf0e10cSrcweir     {
1364*cdf0e10cSrcweir         sal_Bool bHandled= sal_False;
1365*cdf0e10cSrcweir         ret= InvokeGeneral( dispidMember,  wFlags, pdispparams, pvarResult,  pexcepinfo,
1366*cdf0e10cSrcweir                             puArgErr, bHandled);
1367*cdf0e10cSrcweir         if( bHandled)
1368*cdf0e10cSrcweir             return ret;
1369*cdf0e10cSrcweir 
1370*cdf0e10cSrcweir         if ( dispidMember > 0  && m_xInvocation.is())
1371*cdf0e10cSrcweir         {
1372*cdf0e10cSrcweir 
1373*cdf0e10cSrcweir             IdToMemberInfoMap::iterator it_MemberInfo= m_idToMemberInfoMap.find( dispidMember);
1374*cdf0e10cSrcweir             if( it_MemberInfo != m_idToMemberInfoMap.end() )
1375*cdf0e10cSrcweir             {
1376*cdf0e10cSrcweir                 MemberInfo& info= it_MemberInfo->second;
1377*cdf0e10cSrcweir 
1378*cdf0e10cSrcweir                 Sequence<Any> params; // holds converted any s
1379*cdf0e10cSrcweir                 if( ! info.flags )
1380*cdf0e10cSrcweir                 { // DISPID called for the first time
1381*cdf0e10cSrcweir                     if( wFlags == DISPATCH_METHOD )
1382*cdf0e10cSrcweir                     {
1383*cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1384*cdf0e10cSrcweir 
1385*cdf0e10cSrcweir                         if( FAILED( ret= doInvoke( pdispparams, pvarResult,
1386*cdf0e10cSrcweir                                                    pexcepinfo, puArgErr, info.name, params))
1387*cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1388*cdf0e10cSrcweir                         {
1389*cdf0e10cSrcweir                             // try to get the exact name
1390*cdf0e10cSrcweir                             OUString exactName;
1391*cdf0e10cSrcweir                             if (m_xExactName.is())
1392*cdf0e10cSrcweir                             {
1393*cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1394*cdf0e10cSrcweir                                 // invoke again
1395*cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1396*cdf0e10cSrcweir                                 {
1397*cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doInvoke( pdispparams, pvarResult,
1398*cdf0e10cSrcweir                                                                   pexcepinfo, puArgErr, exactName, params)))
1399*cdf0e10cSrcweir                                         info.name= exactName;
1400*cdf0e10cSrcweir                                 }
1401*cdf0e10cSrcweir                             }
1402*cdf0e10cSrcweir                         }
1403*cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1404*cdf0e10cSrcweir                             info.flags= DISPATCH_METHOD;
1405*cdf0e10cSrcweir                     } //if( wFlags == DISPATCH_METHOD )
1406*cdf0e10cSrcweir 
1407*cdf0e10cSrcweir                     else if( wFlags == DISPATCH_PROPERTYPUT || wFlags == DISPATCH_PROPERTYPUTREF)
1408*cdf0e10cSrcweir                     {
1409*cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1410*cdf0e10cSrcweir                         if( FAILED( ret= doSetProperty( pdispparams, pvarResult,
1411*cdf0e10cSrcweir                                                         pexcepinfo, puArgErr, info.name, params))
1412*cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1413*cdf0e10cSrcweir                         {
1414*cdf0e10cSrcweir                             // try to get the exact name
1415*cdf0e10cSrcweir                             OUString exactName;
1416*cdf0e10cSrcweir                             if (m_xExactName.is())
1417*cdf0e10cSrcweir                             {
1418*cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1419*cdf0e10cSrcweir                                 // invoke again
1420*cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1421*cdf0e10cSrcweir                                 {
1422*cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doSetProperty( pdispparams, pvarResult,
1423*cdf0e10cSrcweir                                                                        pexcepinfo, puArgErr, exactName, params)))
1424*cdf0e10cSrcweir                                         info.name= exactName;
1425*cdf0e10cSrcweir                                 }
1426*cdf0e10cSrcweir                             }
1427*cdf0e10cSrcweir                         }
1428*cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1429*cdf0e10cSrcweir                             info.flags= DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYGET;
1430*cdf0e10cSrcweir                     }
1431*cdf0e10cSrcweir 
1432*cdf0e10cSrcweir                     else if( wFlags == DISPATCH_PROPERTYGET)
1433*cdf0e10cSrcweir                     {
1434*cdf0e10cSrcweir                         if( FAILED( ret= doGetProperty( pdispparams, pvarResult,
1435*cdf0e10cSrcweir                                                         pexcepinfo, info.name))
1436*cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1437*cdf0e10cSrcweir                         {
1438*cdf0e10cSrcweir                             // try to get the exact name
1439*cdf0e10cSrcweir                             OUString exactName;
1440*cdf0e10cSrcweir                             if (m_xExactName.is())
1441*cdf0e10cSrcweir                             {
1442*cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1443*cdf0e10cSrcweir                                 // invoke again
1444*cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1445*cdf0e10cSrcweir                                 {
1446*cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doGetProperty( pdispparams, pvarResult,
1447*cdf0e10cSrcweir                                                                        pexcepinfo, exactName)))
1448*cdf0e10cSrcweir                                         info.name= exactName;
1449*cdf0e10cSrcweir                                 }
1450*cdf0e10cSrcweir                             }
1451*cdf0e10cSrcweir                         }
1452*cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1453*cdf0e10cSrcweir                             info.flags= DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT;
1454*cdf0e10cSrcweir                     }
1455*cdf0e10cSrcweir                     else if( wFlags & DISPATCH_METHOD &&
1456*cdf0e10cSrcweir                              (wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF))
1457*cdf0e10cSrcweir                     {
1458*cdf0e10cSrcweir 
1459*cdf0e10cSrcweir                         OUString exactName;
1460*cdf0e10cSrcweir                         // convert params for DISPATCH_METHOD or DISPATCH_PROPERTYPUT
1461*cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1462*cdf0e10cSrcweir                         // try first as method
1463*cdf0e10cSrcweir                         if( FAILED( ret= doInvoke( pdispparams, pvarResult,
1464*cdf0e10cSrcweir                                                    pexcepinfo, puArgErr, info.name, params))
1465*cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1466*cdf0e10cSrcweir                         {
1467*cdf0e10cSrcweir                             // try to get the exact name
1468*cdf0e10cSrcweir                             if (m_xExactName.is())
1469*cdf0e10cSrcweir                             {
1470*cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1471*cdf0e10cSrcweir                                 // invoke again
1472*cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1473*cdf0e10cSrcweir                                 {
1474*cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doInvoke( pdispparams, pvarResult,
1475*cdf0e10cSrcweir                                                                   pexcepinfo, puArgErr, exactName, params)))
1476*cdf0e10cSrcweir                                         info.name= exactName;
1477*cdf0e10cSrcweir                                 }
1478*cdf0e10cSrcweir                             }
1479*cdf0e10cSrcweir                         }
1480*cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1481*cdf0e10cSrcweir                             info.flags= DISPATCH_METHOD;
1482*cdf0e10cSrcweir 
1483*cdf0e10cSrcweir                         // try as property
1484*cdf0e10cSrcweir 						if( FAILED( ret) && pdispparams->cArgs == 1)
1485*cdf0e10cSrcweir 						{
1486*cdf0e10cSrcweir 							if( FAILED( ret= doSetProperty( pdispparams, pvarResult,
1487*cdf0e10cSrcweir                                                             pexcepinfo, puArgErr, info.name, params))
1488*cdf0e10cSrcweir                                 && ret == DISP_E_MEMBERNOTFOUND)
1489*cdf0e10cSrcweir 							{
1490*cdf0e10cSrcweir 								// try to get the exact name
1491*cdf0e10cSrcweir 								if( exactName.getLength() != 0)
1492*cdf0e10cSrcweir 								{
1493*cdf0e10cSrcweir 									if( SUCCEEDED( ret= doSetProperty( pdispparams, pvarResult,
1494*cdf0e10cSrcweir                                                                        pexcepinfo, puArgErr, exactName, params)))
1495*cdf0e10cSrcweir                                         info.name= exactName;
1496*cdf0e10cSrcweir 								}
1497*cdf0e10cSrcweir 							}
1498*cdf0e10cSrcweir 							if( SUCCEEDED( ret ) )
1499*cdf0e10cSrcweir 								info.flags= DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYGET;
1500*cdf0e10cSrcweir 						}
1501*cdf0e10cSrcweir                     }
1502*cdf0e10cSrcweir                     else if( wFlags & DISPATCH_METHOD && wFlags & DISPATCH_PROPERTYGET)
1503*cdf0e10cSrcweir                     {
1504*cdf0e10cSrcweir                         OUString exactName;
1505*cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1506*cdf0e10cSrcweir 
1507*cdf0e10cSrcweir                         if( FAILED( ret= doInvoke( pdispparams, pvarResult,
1508*cdf0e10cSrcweir                                                    pexcepinfo, puArgErr, info.name, params))
1509*cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1510*cdf0e10cSrcweir                         {
1511*cdf0e10cSrcweir                             // try to get the exact name
1512*cdf0e10cSrcweir                             if (m_xExactName.is())
1513*cdf0e10cSrcweir                             {
1514*cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1515*cdf0e10cSrcweir                                 // invoke again
1516*cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1517*cdf0e10cSrcweir                                 {
1518*cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doInvoke( pdispparams, pvarResult,
1519*cdf0e10cSrcweir                                                                   pexcepinfo, puArgErr, exactName, params)))
1520*cdf0e10cSrcweir                                         info.name= exactName;
1521*cdf0e10cSrcweir                                 }
1522*cdf0e10cSrcweir                             }
1523*cdf0e10cSrcweir                         }
1524*cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1525*cdf0e10cSrcweir                             info.flags= DISPATCH_METHOD;
1526*cdf0e10cSrcweir 
1527*cdf0e10cSrcweir                         // try as property
1528*cdf0e10cSrcweir                         if( FAILED( ret) && pdispparams->cArgs == 1)
1529*cdf0e10cSrcweir                         {
1530*cdf0e10cSrcweir                             if( FAILED( ret= doGetProperty( pdispparams, pvarResult,
1531*cdf0e10cSrcweir                                                             pexcepinfo, info.name))
1532*cdf0e10cSrcweir                                 && ret == DISP_E_MEMBERNOTFOUND)
1533*cdf0e10cSrcweir                             {
1534*cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1535*cdf0e10cSrcweir                                 {
1536*cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doSetProperty( pdispparams, pvarResult,
1537*cdf0e10cSrcweir                                                                        pexcepinfo, puArgErr, exactName, params)))
1538*cdf0e10cSrcweir                                         info.name= exactName;
1539*cdf0e10cSrcweir                                 }
1540*cdf0e10cSrcweir                             }
1541*cdf0e10cSrcweir                             if( SUCCEEDED( ret ) )
1542*cdf0e10cSrcweir                                 info.flags= DISPATCH_PROPERTYGET;
1543*cdf0e10cSrcweir                         }
1544*cdf0e10cSrcweir                     }
1545*cdf0e10cSrcweir 
1546*cdf0e10cSrcweir                     // update �nformation about this member
1547*cdf0e10cSrcweir                     if( ret == DISP_E_MEMBERNOTFOUND)
1548*cdf0e10cSrcweir                     {
1549*cdf0e10cSrcweir                         // Remember the name as not existing
1550*cdf0e10cSrcweir                         // and remove the MemberInfo
1551*cdf0e10cSrcweir                         m_badNameMap[info.name]= sal_False;
1552*cdf0e10cSrcweir                         m_idToMemberInfoMap.erase( it_MemberInfo);
1553*cdf0e10cSrcweir                     }
1554*cdf0e10cSrcweir                 } // if( ! info.flags )
1555*cdf0e10cSrcweir                 else // IdToMemberInfoMap contains a MemberInfo
1556*cdf0e10cSrcweir                 {
1557*cdf0e10cSrcweir                     if( wFlags & DISPATCH_METHOD && info.flags == DISPATCH_METHOD)
1558*cdf0e10cSrcweir                     {
1559*cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1560*cdf0e10cSrcweir 						ret= doInvoke( pdispparams, pvarResult,
1561*cdf0e10cSrcweir                                        pexcepinfo, puArgErr, info.name, params);
1562*cdf0e10cSrcweir                     }
1563*cdf0e10cSrcweir                     else if( (wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF )  &&
1564*cdf0e10cSrcweir                              info.flags & DISPATCH_PROPERTYPUT)
1565*cdf0e10cSrcweir                     {
1566*cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1567*cdf0e10cSrcweir                         ret= doSetProperty( pdispparams, pvarResult,
1568*cdf0e10cSrcweir                                             pexcepinfo, puArgErr, info.name, params);
1569*cdf0e10cSrcweir                     }
1570*cdf0e10cSrcweir                     else if( (wFlags & DISPATCH_PROPERTYGET) && ( info.flags & DISPATCH_PROPERTYGET))
1571*cdf0e10cSrcweir                     {
1572*cdf0e10cSrcweir                         ret= doGetProperty( pdispparams, pvarResult,
1573*cdf0e10cSrcweir                                             pexcepinfo, info.name);
1574*cdf0e10cSrcweir                     }
1575*cdf0e10cSrcweir                     else
1576*cdf0e10cSrcweir                     {
1577*cdf0e10cSrcweir                         ret= DISP_E_MEMBERNOTFOUND;
1578*cdf0e10cSrcweir                     }
1579*cdf0e10cSrcweir                 }
1580*cdf0e10cSrcweir             }//		if( it_MemberInfo != m_idToMemberInfoMap.end() )
1581*cdf0e10cSrcweir             else
1582*cdf0e10cSrcweir                 ret= DISP_E_MEMBERNOTFOUND;
1583*cdf0e10cSrcweir         }
1584*cdf0e10cSrcweir     }
1585*cdf0e10cSrcweir     catch(BridgeRuntimeError& e)
1586*cdf0e10cSrcweir     {
1587*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
1588*cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1589*cdf0e10cSrcweir     }
1590*cdf0e10cSrcweir     catch(Exception& e)
1591*cdf0e10cSrcweir     {
1592*cdf0e10cSrcweir         OUString message= OUSTR("UnoObjectWrapperRemoteOpt::Invoke : \n") +
1593*cdf0e10cSrcweir             e.Message;
1594*cdf0e10cSrcweir             writeExcepinfo(pexcepinfo, message);
1595*cdf0e10cSrcweir             ret = DISP_E_EXCEPTION;
1596*cdf0e10cSrcweir     }
1597*cdf0e10cSrcweir     catch(...)
1598*cdf0e10cSrcweir     {
1599*cdf0e10cSrcweir         OUString message= OUSTR("UnoObjectWrapperRemoteOpt::Invoke : \n"
1600*cdf0e10cSrcweir                                 "Unexpected exception");
1601*cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1602*cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1603*cdf0e10cSrcweir     }
1604*cdf0e10cSrcweir 
1605*cdf0e10cSrcweir     return ret;
1606*cdf0e10cSrcweir }
1607*cdf0e10cSrcweir 
1608*cdf0e10cSrcweir HRESULT	UnoObjectWrapperRemoteOpt::methodInvoke( DISPID /*dispidMember*/, DISPPARAMS * /*pdispparams*/, VARIANT * /*pvarResult*/,
1609*cdf0e10cSrcweir 							  EXCEPINFO * /*pexcepinfo*/, unsigned int * /*puArgErr*/, Sequence<Any> params)
1610*cdf0e10cSrcweir {
1611*cdf0e10cSrcweir 	return S_OK;
1612*cdf0e10cSrcweir }
1613*cdf0e10cSrcweir 
1614*cdf0e10cSrcweir 
1615*cdf0e10cSrcweir // The returned HRESULT is only appropriate for IDispatch::Invoke
1616*cdf0e10cSrcweir static HRESULT mapCannotConvertException( CannotConvertException e, unsigned int * puArgErr)
1617*cdf0e10cSrcweir {
1618*cdf0e10cSrcweir 	HRESULT ret;
1619*cdf0e10cSrcweir 	sal_Bool bWriteIndex= sal_True;
1620*cdf0e10cSrcweir 
1621*cdf0e10cSrcweir 	switch ( e.Reason)
1622*cdf0e10cSrcweir 	{
1623*cdf0e10cSrcweir 		case FailReason::OUT_OF_RANGE:
1624*cdf0e10cSrcweir 			ret = DISP_E_OVERFLOW;
1625*cdf0e10cSrcweir 			break;
1626*cdf0e10cSrcweir 		case FailReason::IS_NOT_NUMBER:
1627*cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1628*cdf0e10cSrcweir 			break;
1629*cdf0e10cSrcweir 		case FailReason::IS_NOT_ENUM:
1630*cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1631*cdf0e10cSrcweir 			break;
1632*cdf0e10cSrcweir 		case FailReason::IS_NOT_BOOL:
1633*cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1634*cdf0e10cSrcweir 			break;
1635*cdf0e10cSrcweir 		case FailReason::NO_SUCH_INTERFACE:
1636*cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1637*cdf0e10cSrcweir 			break;
1638*cdf0e10cSrcweir 		case FailReason::SOURCE_IS_NO_DERIVED_TYPE:
1639*cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1640*cdf0e10cSrcweir 			break;
1641*cdf0e10cSrcweir 		case FailReason::TYPE_NOT_SUPPORTED:
1642*cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1643*cdf0e10cSrcweir 			break;
1644*cdf0e10cSrcweir 		case FailReason::INVALID:
1645*cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1646*cdf0e10cSrcweir 			break;
1647*cdf0e10cSrcweir 		case FailReason::NO_DEFAULT_AVAILABLE:
1648*cdf0e10cSrcweir 			ret = DISP_E_BADPARAMCOUNT;
1649*cdf0e10cSrcweir 			break;
1650*cdf0e10cSrcweir 		case FailReason::UNKNOWN:
1651*cdf0e10cSrcweir 			ret = E_UNEXPECTED;
1652*cdf0e10cSrcweir 			break;
1653*cdf0e10cSrcweir 		default:
1654*cdf0e10cSrcweir 			ret = E_UNEXPECTED;
1655*cdf0e10cSrcweir 			bWriteIndex= sal_False;
1656*cdf0e10cSrcweir 			break;
1657*cdf0e10cSrcweir 	}
1658*cdf0e10cSrcweir 
1659*cdf0e10cSrcweir 	if( bWriteIndex &&  puArgErr != NULL)
1660*cdf0e10cSrcweir 		*puArgErr = e.ArgumentIndex;
1661*cdf0e10cSrcweir 	return ret;
1662*cdf0e10cSrcweir }
1663*cdf0e10cSrcweir 
1664*cdf0e10cSrcweir // The function maps the TypeClass of the any to VARTYPE: If
1665*cdf0e10cSrcweir // the Any contains STRUCT or INTERFACE then the return value
1666*cdf0e10cSrcweir // is VT_DISPATCH. The function is used from o2u_createUnoObjectWrapper
1667*cdf0e10cSrcweir // and the result is put into the constructor of the uno - wrapper
1668*cdf0e10cSrcweir // object. If a client asks the object for DISPID_VALUE and this
1669*cdf0e10cSrcweir // funtion returned VT_DISPATCH then the IDispatch of the same
1670*cdf0e10cSrcweir // object is being returned.
1671*cdf0e10cSrcweir // See InterfaceOleWrapper_Impl::Invoke, InterfaceOleWrapper_Impl::m_defaultValueType
1672*cdf0e10cSrcweir const VARTYPE getVarType( const Any& value)
1673*cdf0e10cSrcweir {
1674*cdf0e10cSrcweir 	VARTYPE ret= VT_EMPTY;
1675*cdf0e10cSrcweir 
1676*cdf0e10cSrcweir 	switch ( value.getValueTypeClass())
1677*cdf0e10cSrcweir 	{
1678*cdf0e10cSrcweir 	case TypeClass_STRUCT: ret= VT_DISPATCH; break;
1679*cdf0e10cSrcweir 	case TypeClass_INTERFACE: ret= VT_DISPATCH; break;
1680*cdf0e10cSrcweir 	default: break;
1681*cdf0e10cSrcweir 	}
1682*cdf0e10cSrcweir 	return ret;
1683*cdf0e10cSrcweir }
1684*cdf0e10cSrcweir 
1685*cdf0e10cSrcweir 
1686*cdf0e10cSrcweir 
1687*cdf0e10cSrcweir 
1688*cdf0e10cSrcweir } // end namespace
1689