xref: /AOO41X/main/extensions/source/ole/oleobjw.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 #include "ole2uno.hxx"
31*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include "osl/diagnose.h"
35*cdf0e10cSrcweir #include "osl/doublecheckedlocking.h"
36*cdf0e10cSrcweir #include "osl/thread.h"
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include "boost/scoped_array.hpp"
39*cdf0e10cSrcweir #include <com/sun/star/script/FailReason.hpp>
40*cdf0e10cSrcweir #include <com/sun/star/beans/XMaterialHolder.hpp>
41*cdf0e10cSrcweir #include <com/sun/star/script/XTypeConverter.hpp>
42*cdf0e10cSrcweir #include <com/sun/star/script/FinishEngineEvent.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/script/InterruptReason.hpp>
44*cdf0e10cSrcweir #include <com/sun/star/script/XEngineListener.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/script/XDebugging.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/script/XInvocation.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/script/ContextInformation.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/script/FinishReason.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/script/XEngine.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/script/InterruptEngineEvent.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/script/XLibraryAccess.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/bridge/ModelDependent.hpp>
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir #include "com/sun/star/bridge/oleautomation/NamedArgument.hpp"
55*cdf0e10cSrcweir #include "com/sun/star/bridge/oleautomation/PropertyPutArgument.hpp"
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir #include <typelib/typedescription.hxx>
58*cdf0e10cSrcweir #include <rtl/uuid.h>
59*cdf0e10cSrcweir #include <rtl/memory.h>
60*cdf0e10cSrcweir #include <rtl/ustring.hxx>
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir #include "jscriptclasses.hxx"
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir #include "oleobjw.hxx"
65*cdf0e10cSrcweir #include "unoobjw.hxx"
66*cdf0e10cSrcweir #include <stdio.h>
67*cdf0e10cSrcweir using namespace std;
68*cdf0e10cSrcweir using namespace boost;
69*cdf0e10cSrcweir using namespace osl;
70*cdf0e10cSrcweir using namespace rtl;
71*cdf0e10cSrcweir using namespace cppu;
72*cdf0e10cSrcweir using namespace com::sun::star::script;
73*cdf0e10cSrcweir using namespace com::sun::star::lang;
74*cdf0e10cSrcweir using namespace com::sun::star::bridge;
75*cdf0e10cSrcweir using namespace com::sun::star::bridge::oleautomation;
76*cdf0e10cSrcweir using namespace com::sun::star::bridge::ModelDependent;
77*cdf0e10cSrcweir using namespace ::com::sun::star;
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir #define JSCRIPT_ID_PROPERTY L"_environment"
80*cdf0e10cSrcweir #define JSCRIPT_ID			L"jscript"
81*cdf0e10cSrcweir namespace ole_adapter
82*cdf0e10cSrcweir {
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir // key: XInterface pointer created by Invocation Adapter Factory
86*cdf0e10cSrcweir // value: XInterface pointer to the wrapper class.
87*cdf0e10cSrcweir // Entries to the map are made within
88*cdf0e10cSrcweir // Any createOleObjectWrapper(IUnknown* pUnknown, const Type& aType);
89*cdf0e10cSrcweir // Entries are being deleted if the wrapper class's destructor has been
90*cdf0e10cSrcweir // called.
91*cdf0e10cSrcweir // Before UNO object is wrapped to COM object this map is checked
92*cdf0e10cSrcweir // to see if the UNO object is already a wrapper.
93*cdf0e10cSrcweir hash_map<sal_uInt32, sal_uInt32> AdapterToWrapperMap;
94*cdf0e10cSrcweir // key: XInterface of the wrapper object.
95*cdf0e10cSrcweir // value: XInterface of the Interface created by the Invocation Adapter Factory.
96*cdf0e10cSrcweir // A COM wrapper is responsible for removing the corresponding entry
97*cdf0e10cSrcweir // in AdapterToWrappperMap if it is being destroyed. Because the wrapper does not
98*cdf0e10cSrcweir // know about its adapted interface it uses WrapperToAdapterMap to get the
99*cdf0e10cSrcweir // adapted interface which is then used to locate the entry in AdapterToWrapperMap.
100*cdf0e10cSrcweir hash_map<sal_uInt32,sal_uInt32> WrapperToAdapterMap;
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir hash_map<sal_uInt32, WeakReference<XInterface> > ComPtrToWrapperMap;
103*cdf0e10cSrcweir /*****************************************************************************
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir 	class implementation IUnknownWrapper_Impl
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir *****************************************************************************/
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir IUnknownWrapper_Impl::IUnknownWrapper_Impl( Reference<XMultiServiceFactory>& xFactory,
110*cdf0e10cSrcweir 										   sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass):
111*cdf0e10cSrcweir 	UnoConversionUtilities<IUnknownWrapper_Impl>( xFactory, unoWrapperClass, comWrapperClass),
112*cdf0e10cSrcweir 	m_pxIdlClass( NULL), m_eJScript( JScriptUndefined),
113*cdf0e10cSrcweir     m_bComTlbIndexInit(false),  m_bHasDfltMethod(false), m_bHasDfltProperty(false)
114*cdf0e10cSrcweir {
115*cdf0e10cSrcweir }
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir IUnknownWrapper_Impl::~IUnknownWrapper_Impl()
119*cdf0e10cSrcweir {
120*cdf0e10cSrcweir     o2u_attachCurrentThread();
121*cdf0e10cSrcweir     MutexGuard guard(getBridgeMutex());
122*cdf0e10cSrcweir     XInterface * xIntRoot = (OWeakObject *)this;
123*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
124*cdf0e10cSrcweir     acquire(); // make sure we don't delete us twice because of Reference
125*cdf0e10cSrcweir 	OSL_ASSERT( Reference<XInterface>( static_cast<XWeak*>(this), UNO_QUERY).get() == xIntRoot );
126*cdf0e10cSrcweir #endif
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir 	// remove entries in global maps
129*cdf0e10cSrcweir 	typedef hash_map<sal_uInt32, sal_uInt32>::iterator _IT;
130*cdf0e10cSrcweir 	_IT it=	WrapperToAdapterMap.find( (sal_uInt32) xIntRoot);
131*cdf0e10cSrcweir 	if( it != WrapperToAdapterMap.end())
132*cdf0e10cSrcweir 	{
133*cdf0e10cSrcweir 		sal_uInt32 adapter= it->second;
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir 		AdapterToWrapperMap.erase( adapter);
136*cdf0e10cSrcweir 		WrapperToAdapterMap.erase( it);
137*cdf0e10cSrcweir 	}
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir  	IT_Com it_c= ComPtrToWrapperMap.find( (sal_uInt32) m_spUnknown.p);
140*cdf0e10cSrcweir     if(it_c != ComPtrToWrapperMap.end())
141*cdf0e10cSrcweir         ComPtrToWrapperMap.erase(it_c);
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
144*cdf0e10cSrcweir     fprintf(stderr,"[automation bridge] ComPtrToWrapperMap  contains: %i \n",
145*cdf0e10cSrcweir             ComPtrToWrapperMap.size());
146*cdf0e10cSrcweir #endif
147*cdf0e10cSrcweir }
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir Any IUnknownWrapper_Impl::queryInterface(const Type& t)
150*cdf0e10cSrcweir     throw (RuntimeException)
151*cdf0e10cSrcweir {
152*cdf0e10cSrcweir     if (t == getCppuType(static_cast<Reference<XDefaultMethod>*>( 0)) && !m_bHasDfltMethod )
153*cdf0e10cSrcweir         return Any();
154*cdf0e10cSrcweir     if (t == getCppuType(static_cast<Reference<XDefaultProperty>*>( 0)) && !m_bHasDfltProperty )
155*cdf0e10cSrcweir         return Any();
156*cdf0e10cSrcweir     if (t == getCppuType(static_cast<Reference<XInvocation>*>( 0)) && !m_spDispatch)
157*cdf0e10cSrcweir         return Any();
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir     return WeakImplHelper7<XInvocation, XBridgeSupplier2,
160*cdf0e10cSrcweir         XInitialization, XAutomationObject, XDefaultProperty, XDefaultMethod, XDirectInvocation>::queryInterface(t);
161*cdf0e10cSrcweir }
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir Reference<XIntrospectionAccess> SAL_CALL IUnknownWrapper_Impl::getIntrospection(void)
164*cdf0e10cSrcweir 	throw (RuntimeException )
165*cdf0e10cSrcweir {
166*cdf0e10cSrcweir 	Reference<XIntrospectionAccess> ret;
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir 	return ret;
169*cdf0e10cSrcweir }
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir Any SAL_CALL IUnknownWrapper_Impl::invoke( const OUString& aFunctionName,
174*cdf0e10cSrcweir 			 const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex,
175*cdf0e10cSrcweir 			 Sequence< Any >& aOutParam )
176*cdf0e10cSrcweir 	throw(IllegalArgumentException, CannotConvertException, InvocationTargetException,
177*cdf0e10cSrcweir 		  RuntimeException)
178*cdf0e10cSrcweir {
179*cdf0e10cSrcweir     if ( ! m_spDispatch )
180*cdf0e10cSrcweir     {
181*cdf0e10cSrcweir         throw RuntimeException(
182*cdf0e10cSrcweir             OUSTR("[automation bridge] The object does not have an IDispatch interface"),
183*cdf0e10cSrcweir             Reference<XInterface>());
184*cdf0e10cSrcweir     }
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir     Any ret;
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir     try
189*cdf0e10cSrcweir     {
190*cdf0e10cSrcweir 		o2u_attachCurrentThread();
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir         TypeDescription methodDesc;
193*cdf0e10cSrcweir         getMethodInfo(aFunctionName, methodDesc);
194*cdf0e10cSrcweir         if( methodDesc.is())
195*cdf0e10cSrcweir         {
196*cdf0e10cSrcweir             ret = invokeWithDispIdUnoTlb(aFunctionName,
197*cdf0e10cSrcweir                                          aParams,
198*cdf0e10cSrcweir                                          aOutParamIndex,
199*cdf0e10cSrcweir                                          aOutParam);
200*cdf0e10cSrcweir         }
201*cdf0e10cSrcweir         else
202*cdf0e10cSrcweir         {
203*cdf0e10cSrcweir             ret= invokeWithDispIdComTlb( aFunctionName,
204*cdf0e10cSrcweir                                          aParams,
205*cdf0e10cSrcweir                                          aOutParamIndex,
206*cdf0e10cSrcweir                                          aOutParam);
207*cdf0e10cSrcweir         }
208*cdf0e10cSrcweir     }
209*cdf0e10cSrcweir 	catch (IllegalArgumentException &)
210*cdf0e10cSrcweir 	{
211*cdf0e10cSrcweir 		throw;
212*cdf0e10cSrcweir 	}
213*cdf0e10cSrcweir 	catch (CannotConvertException &)
214*cdf0e10cSrcweir 	{
215*cdf0e10cSrcweir 		throw;
216*cdf0e10cSrcweir 	}
217*cdf0e10cSrcweir     catch (BridgeRuntimeError & e)
218*cdf0e10cSrcweir     {
219*cdf0e10cSrcweir          throw RuntimeException(e.message, Reference<XInterface>());
220*cdf0e10cSrcweir     }
221*cdf0e10cSrcweir     catch (Exception & e)
222*cdf0e10cSrcweir     {
223*cdf0e10cSrcweir         throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
224*cdf0e10cSrcweir                                      "IUnknownWrapper_Impl::invoke ! Message : \n") +
225*cdf0e10cSrcweir                                e.Message, Reference<XInterface>());
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir     }
228*cdf0e10cSrcweir     catch(...)
229*cdf0e10cSrcweir     {
230*cdf0e10cSrcweir         throw RuntimeException(
231*cdf0e10cSrcweir             OUSTR("[automation bridge] unexpected exception in "
232*cdf0e10cSrcweir                   "IUnknownWrapper_Impl::Invoke !"), Reference<XInterface>());
233*cdf0e10cSrcweir     }
234*cdf0e10cSrcweir 	return ret;
235*cdf0e10cSrcweir }
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir void SAL_CALL IUnknownWrapper_Impl::setValue( const OUString& aPropertyName,
238*cdf0e10cSrcweir 				 const Any& aValue )
239*cdf0e10cSrcweir 	throw(UnknownPropertyException, CannotConvertException, InvocationTargetException,
240*cdf0e10cSrcweir 		  RuntimeException)
241*cdf0e10cSrcweir {
242*cdf0e10cSrcweir     if ( ! m_spDispatch )
243*cdf0e10cSrcweir     {
244*cdf0e10cSrcweir         throw RuntimeException(
245*cdf0e10cSrcweir             OUSTR("[automation bridge] The object does not have an IDispatch interface"),
246*cdf0e10cSrcweir             Reference<XInterface>());
247*cdf0e10cSrcweir     }
248*cdf0e10cSrcweir     try
249*cdf0e10cSrcweir 	{
250*cdf0e10cSrcweir 		o2u_attachCurrentThread();
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir 		ITypeInfo * pInfo = getTypeInfo();
253*cdf0e10cSrcweir         FuncDesc aDescGet(pInfo);
254*cdf0e10cSrcweir         FuncDesc aDescPut(pInfo);
255*cdf0e10cSrcweir         VarDesc aVarDesc(pInfo);
256*cdf0e10cSrcweir         getPropDesc(aPropertyName, & aDescGet, & aDescPut, & aVarDesc);
257*cdf0e10cSrcweir         //check if there is such a property at all or if it is read only
258*cdf0e10cSrcweir         if ( ! aDescPut && ! aDescGet && ! aVarDesc)
259*cdf0e10cSrcweir         {
260*cdf0e10cSrcweir             OUString msg(OUSTR("[automation bridge]Property \"") + aPropertyName +
261*cdf0e10cSrcweir                          OUSTR("\" is not supported"));
262*cdf0e10cSrcweir             throw UnknownPropertyException(msg, Reference<XInterface>());
263*cdf0e10cSrcweir         }
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir         if ( (! aDescPut && aDescGet) || aVarDesc
266*cdf0e10cSrcweir              && aVarDesc->wVarFlags == VARFLAG_FREADONLY )
267*cdf0e10cSrcweir         {
268*cdf0e10cSrcweir             //read-only
269*cdf0e10cSrcweir             OUString msg(OUSTR("[automation bridge] Property ") + aPropertyName +
270*cdf0e10cSrcweir                          OUSTR(" is read-only"));
271*cdf0e10cSrcweir             OString sMsg = OUStringToOString(msg, osl_getThreadTextEncoding());
272*cdf0e10cSrcweir             OSL_ENSURE(0, sMsg.getStr());
273*cdf0e10cSrcweir             // ignore silently
274*cdf0e10cSrcweir             return;
275*cdf0e10cSrcweir         }
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir         HRESULT hr= S_OK;
278*cdf0e10cSrcweir         DISPPARAMS dispparams;
279*cdf0e10cSrcweir         CComVariant varArg;
280*cdf0e10cSrcweir         CComVariant varRefArg;
281*cdf0e10cSrcweir         CComVariant varResult;
282*cdf0e10cSrcweir         ExcepInfo excepinfo;
283*cdf0e10cSrcweir         unsigned int uArgErr;
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir         // converting UNO value to OLE variant
286*cdf0e10cSrcweir         DISPID dispidPut= DISPID_PROPERTYPUT;
287*cdf0e10cSrcweir         dispparams.rgdispidNamedArgs = &dispidPut;
288*cdf0e10cSrcweir         dispparams.cArgs = 1;
289*cdf0e10cSrcweir         dispparams.cNamedArgs = 1;
290*cdf0e10cSrcweir         dispparams.rgvarg = & varArg;
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir         OSL_ASSERT(aDescPut || aVarDesc);
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir         VARTYPE vt = 0;
295*cdf0e10cSrcweir         DISPID dispid = 0;
296*cdf0e10cSrcweir         INVOKEKIND invkind = INVOKE_PROPERTYPUT;
297*cdf0e10cSrcweir         //determine the expected type, dispid, invoke kind (DISPATCH_PROPERTYPUT,
298*cdf0e10cSrcweir         //DISPATCH_PROPERTYPUTREF)
299*cdf0e10cSrcweir         if (aDescPut)
300*cdf0e10cSrcweir         {
301*cdf0e10cSrcweir             vt = getElementTypeDesc(& aDescPut->lprgelemdescParam[0].tdesc);
302*cdf0e10cSrcweir             dispid = aDescPut->memid;
303*cdf0e10cSrcweir             invkind = aDescPut->invkind;
304*cdf0e10cSrcweir         }
305*cdf0e10cSrcweir         else
306*cdf0e10cSrcweir         {
307*cdf0e10cSrcweir             vt = getElementTypeDesc( & aVarDesc->elemdescVar.tdesc);
308*cdf0e10cSrcweir             dispid = aVarDesc->memid;
309*cdf0e10cSrcweir             if (vt == VT_UNKNOWN || vt == VT_DISPATCH ||
310*cdf0e10cSrcweir                 (vt & VT_ARRAY) || (vt & VT_BYREF))
311*cdf0e10cSrcweir             {
312*cdf0e10cSrcweir                 invkind = INVOKE_PROPERTYPUTREF;
313*cdf0e10cSrcweir             }
314*cdf0e10cSrcweir         }
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir         // convert the uno argument
317*cdf0e10cSrcweir         if (vt & VT_BYREF)
318*cdf0e10cSrcweir         {
319*cdf0e10cSrcweir             anyToVariant( & varRefArg, aValue, ::sal::static_int_cast< VARTYPE, int >( vt ^ VT_BYREF ) );
320*cdf0e10cSrcweir             varArg.vt = vt;
321*cdf0e10cSrcweir             if( (vt & VT_TYPEMASK) == VT_VARIANT)
322*cdf0e10cSrcweir                 varArg.byref = & varRefArg;
323*cdf0e10cSrcweir 			else if ((vt & VT_TYPEMASK) == VT_DECIMAL)
324*cdf0e10cSrcweir 				varArg.byref = & varRefArg.decVal;
325*cdf0e10cSrcweir             else
326*cdf0e10cSrcweir                 varArg.byref = & varRefArg.byref;
327*cdf0e10cSrcweir         }
328*cdf0e10cSrcweir         else
329*cdf0e10cSrcweir         {
330*cdf0e10cSrcweir             anyToVariant(& varArg, aValue, vt);
331*cdf0e10cSrcweir         }
332*cdf0e10cSrcweir         // call to IDispatch
333*cdf0e10cSrcweir         hr = m_spDispatch->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, ::sal::static_int_cast< WORD, INVOKEKIND >( invkind ),
334*cdf0e10cSrcweir                                  &dispparams, & varResult, & excepinfo, &uArgErr);
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir         // lookup error code
337*cdf0e10cSrcweir         switch (hr)
338*cdf0e10cSrcweir         {
339*cdf0e10cSrcweir 		case S_OK:
340*cdf0e10cSrcweir 			break;
341*cdf0e10cSrcweir 		case DISP_E_BADPARAMCOUNT:
342*cdf0e10cSrcweir 			throw RuntimeException();
343*cdf0e10cSrcweir 			break;
344*cdf0e10cSrcweir 		case DISP_E_BADVARTYPE:
345*cdf0e10cSrcweir 			throw RuntimeException();
346*cdf0e10cSrcweir 			break;
347*cdf0e10cSrcweir 		case DISP_E_EXCEPTION:
348*cdf0e10cSrcweir 			throw InvocationTargetException();
349*cdf0e10cSrcweir 			break;
350*cdf0e10cSrcweir 		case DISP_E_MEMBERNOTFOUND:
351*cdf0e10cSrcweir 			throw UnknownPropertyException();
352*cdf0e10cSrcweir 			break;
353*cdf0e10cSrcweir 		case DISP_E_NONAMEDARGS:
354*cdf0e10cSrcweir 			throw RuntimeException();
355*cdf0e10cSrcweir 			break;
356*cdf0e10cSrcweir 		case DISP_E_OVERFLOW:
357*cdf0e10cSrcweir 			throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
358*cdf0e10cSrcweir                                              static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::OUT_OF_RANGE, uArgErr);
359*cdf0e10cSrcweir 			break;
360*cdf0e10cSrcweir 		case DISP_E_PARAMNOTFOUND:
361*cdf0e10cSrcweir 			throw IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
362*cdf0e10cSrcweir                                             static_cast<XWeak*>(this)), ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr )) ;
363*cdf0e10cSrcweir 			break;
364*cdf0e10cSrcweir 		case DISP_E_TYPEMISMATCH:
365*cdf0e10cSrcweir 			throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
366*cdf0e10cSrcweir                                              static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::UNKNOWN, ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
367*cdf0e10cSrcweir 			break;
368*cdf0e10cSrcweir 		case DISP_E_UNKNOWNINTERFACE:
369*cdf0e10cSrcweir 			throw RuntimeException();
370*cdf0e10cSrcweir 			break;
371*cdf0e10cSrcweir 		case DISP_E_UNKNOWNLCID:
372*cdf0e10cSrcweir 			throw RuntimeException();
373*cdf0e10cSrcweir 			break;
374*cdf0e10cSrcweir 		case DISP_E_PARAMNOTOPTIONAL:
375*cdf0e10cSrcweir 			throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")),static_cast<XInterface*>(
376*cdf0e10cSrcweir                                              static_cast<XWeak*>(this)) , TypeClass_UNKNOWN, FailReason::NO_DEFAULT_AVAILABLE, uArgErr);
377*cdf0e10cSrcweir 			break;
378*cdf0e10cSrcweir 		default:
379*cdf0e10cSrcweir 			throw  RuntimeException();
380*cdf0e10cSrcweir 			break;
381*cdf0e10cSrcweir         }
382*cdf0e10cSrcweir 	}
383*cdf0e10cSrcweir 	catch (CannotConvertException &)
384*cdf0e10cSrcweir 	{
385*cdf0e10cSrcweir 		throw;
386*cdf0e10cSrcweir 	}
387*cdf0e10cSrcweir     catch (UnknownPropertyException &)
388*cdf0e10cSrcweir     {
389*cdf0e10cSrcweir         throw;
390*cdf0e10cSrcweir     }
391*cdf0e10cSrcweir 	catch (BridgeRuntimeError& e)
392*cdf0e10cSrcweir 	{
393*cdf0e10cSrcweir         throw RuntimeException(
394*cdf0e10cSrcweir             e.message, Reference<XInterface>());
395*cdf0e10cSrcweir 	}
396*cdf0e10cSrcweir     catch (Exception & e)
397*cdf0e10cSrcweir     {
398*cdf0e10cSrcweir         throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
399*cdf0e10cSrcweir                                      "IUnknownWrapper_Impl::setValue ! Message : \n") +
400*cdf0e10cSrcweir                                e.Message, Reference<XInterface>());
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir     }
403*cdf0e10cSrcweir 	catch (...)
404*cdf0e10cSrcweir 	{
405*cdf0e10cSrcweir 		throw RuntimeException(
406*cdf0e10cSrcweir             OUSTR("[automation bridge] unexpected exception in "
407*cdf0e10cSrcweir 			"IUnknownWrapper_Impl::setValue !"), Reference<XInterface>());
408*cdf0e10cSrcweir 	}
409*cdf0e10cSrcweir }
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir Any SAL_CALL IUnknownWrapper_Impl::getValue( const OUString& aPropertyName )
412*cdf0e10cSrcweir 		throw(UnknownPropertyException, RuntimeException)
413*cdf0e10cSrcweir {
414*cdf0e10cSrcweir     if ( ! m_spDispatch )
415*cdf0e10cSrcweir     {
416*cdf0e10cSrcweir         throw RuntimeException(
417*cdf0e10cSrcweir             OUSTR("[automation bridge] The object does not have an IDispatch interface"),
418*cdf0e10cSrcweir             Reference<XInterface>());
419*cdf0e10cSrcweir     }
420*cdf0e10cSrcweir 	Any ret;
421*cdf0e10cSrcweir     try
422*cdf0e10cSrcweir     {
423*cdf0e10cSrcweir         o2u_attachCurrentThread();
424*cdf0e10cSrcweir         ITypeInfo * pInfo = getTypeInfo();
425*cdf0e10cSrcweir         // I was going to implement an XServiceInfo interface to allow the type
426*cdf0e10cSrcweir         // of the automation object to be exposed.. but it seems
427*cdf0e10cSrcweir         // from looking at comments in the code that it is possible for
428*cdf0e10cSrcweir         // this object to actually wrap an UNO object ( I guess if automation is
429*cdf0e10cSrcweir         // used from MSO to create Openoffice objects ) Therefore, those objects
430*cdf0e10cSrcweir         // will more than likely already have their own XServiceInfo interface.
431*cdf0e10cSrcweir         // Instead here I chose a name that should be illegal both in COM and
432*cdf0e10cSrcweir         // UNO ( from an IDL point of view ) therefore I think this is a safe
433*cdf0e10cSrcweir         // hack
434*cdf0e10cSrcweir         if ( aPropertyName.equals( rtl::OUString::createFromAscii("$GetTypeName") ))
435*cdf0e10cSrcweir         {
436*cdf0e10cSrcweir             if ( pInfo && m_sTypeName.getLength() == 0 )
437*cdf0e10cSrcweir             {
438*cdf0e10cSrcweir             	 m_sTypeName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IDispatch") );
439*cdf0e10cSrcweir                 CComBSTR sName;
440*cdf0e10cSrcweir 
441*cdf0e10cSrcweir                 if ( SUCCEEDED( pInfo->GetDocumentation( -1, &sName, NULL, NULL, NULL  ) ) )
442*cdf0e10cSrcweir                 {
443*cdf0e10cSrcweir                     rtl::OUString sTmp( reinterpret_cast<const sal_Unicode*>(LPCOLESTR(sName)));
444*cdf0e10cSrcweir                     if ( sTmp.indexOf('_')  == 0 )
445*cdf0e10cSrcweir                        sTmp = sTmp.copy(1);
446*cdf0e10cSrcweir                     // do we own the memory for pTypeLib, msdn doco is vague
447*cdf0e10cSrcweir                     // I'll assume we do
448*cdf0e10cSrcweir                     CComPtr< ITypeLib > pTypeLib;
449*cdf0e10cSrcweir                     unsigned int index;
450*cdf0e10cSrcweir                     if ( SUCCEEDED(  pInfo->GetContainingTypeLib(  &pTypeLib.p, &index )) )
451*cdf0e10cSrcweir                     {
452*cdf0e10cSrcweir                         if ( SUCCEEDED( pTypeLib->GetDocumentation( -1, &sName, NULL, NULL, NULL  ) ) )
453*cdf0e10cSrcweir                         {
454*cdf0e10cSrcweir                             rtl::OUString sLibName( reinterpret_cast<const sal_Unicode*>(LPCOLESTR(sName)));
455*cdf0e10cSrcweir                             m_sTypeName = sLibName.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(".") ) ).concat( sTmp );
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir                         }
458*cdf0e10cSrcweir                     }
459*cdf0e10cSrcweir                 }
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir             }
462*cdf0e10cSrcweir             ret <<= m_sTypeName;
463*cdf0e10cSrcweir             return ret;
464*cdf0e10cSrcweir         }
465*cdf0e10cSrcweir         FuncDesc aDescGet(pInfo);
466*cdf0e10cSrcweir         FuncDesc aDescPut(pInfo);
467*cdf0e10cSrcweir         VarDesc aVarDesc(pInfo);
468*cdf0e10cSrcweir         getPropDesc(aPropertyName, & aDescGet, & aDescPut, & aVarDesc);
469*cdf0e10cSrcweir         if ( ! aDescGet && ! aDescPut && ! aVarDesc)
470*cdf0e10cSrcweir         {
471*cdf0e10cSrcweir             //property not found
472*cdf0e10cSrcweir             OUString msg(OUSTR("[automation bridge]Property \"") + aPropertyName +
473*cdf0e10cSrcweir                          OUSTR("\" is not supported"));
474*cdf0e10cSrcweir             throw UnknownPropertyException(msg, Reference<XInterface>());
475*cdf0e10cSrcweir         }
476*cdf0e10cSrcweir         // write-only should not be possible
477*cdf0e10cSrcweir         OSL_ASSERT(  aDescGet  || ! aDescPut);
478*cdf0e10cSrcweir 
479*cdf0e10cSrcweir         HRESULT hr;
480*cdf0e10cSrcweir         DISPPARAMS dispparams = {0, 0, 0, 0};
481*cdf0e10cSrcweir         CComVariant varResult;
482*cdf0e10cSrcweir         ExcepInfo excepinfo;
483*cdf0e10cSrcweir         unsigned int uArgErr;
484*cdf0e10cSrcweir         DISPID dispid;
485*cdf0e10cSrcweir         if (aDescGet)
486*cdf0e10cSrcweir             dispid = aDescGet->memid;
487*cdf0e10cSrcweir         else if (aVarDesc)
488*cdf0e10cSrcweir             dispid = aVarDesc->memid;
489*cdf0e10cSrcweir         else
490*cdf0e10cSrcweir             dispid = aDescPut->memid;
491*cdf0e10cSrcweir 
492*cdf0e10cSrcweir         hr = m_spDispatch->Invoke(dispid,
493*cdf0e10cSrcweir 								 IID_NULL,
494*cdf0e10cSrcweir 								 LOCALE_USER_DEFAULT,
495*cdf0e10cSrcweir 								 DISPATCH_PROPERTYGET,
496*cdf0e10cSrcweir 								 &dispparams,
497*cdf0e10cSrcweir 								 &varResult,
498*cdf0e10cSrcweir 								 &excepinfo,
499*cdf0e10cSrcweir 								 &uArgErr);
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir         // converting return value and out parameter back to UNO
502*cdf0e10cSrcweir         if (hr == S_OK)
503*cdf0e10cSrcweir         {
504*cdf0e10cSrcweir             // If the com object implements uno interfaces then we have
505*cdf0e10cSrcweir             // to convert the attribute into the expected type.
506*cdf0e10cSrcweir             TypeDescription attrInfo;
507*cdf0e10cSrcweir             getAttributeInfo(aPropertyName, attrInfo);
508*cdf0e10cSrcweir 			if( attrInfo.is() )
509*cdf0e10cSrcweir 				variantToAny( &varResult, ret, Type( attrInfo.get()->pWeakRef));
510*cdf0e10cSrcweir 			else
511*cdf0e10cSrcweir 				variantToAny(&varResult, ret);
512*cdf0e10cSrcweir         }
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir         // lookup error code
515*cdf0e10cSrcweir         switch (hr)
516*cdf0e10cSrcweir         {
517*cdf0e10cSrcweir 		case S_OK:
518*cdf0e10cSrcweir 			break;
519*cdf0e10cSrcweir 		case DISP_E_BADPARAMCOUNT:
520*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
521*cdf0e10cSrcweir                                    Reference<XInterface>());
522*cdf0e10cSrcweir 			break;
523*cdf0e10cSrcweir 		case DISP_E_BADVARTYPE:
524*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
525*cdf0e10cSrcweir                                    Reference<XInterface>());
526*cdf0e10cSrcweir 			break;
527*cdf0e10cSrcweir 		case DISP_E_EXCEPTION:
528*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
529*cdf0e10cSrcweir                                    Reference<XInterface>());
530*cdf0e10cSrcweir 			break;
531*cdf0e10cSrcweir 		case DISP_E_MEMBERNOTFOUND:
532*cdf0e10cSrcweir 			throw UnknownPropertyException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
533*cdf0e10cSrcweir                                    Reference<XInterface>());
534*cdf0e10cSrcweir 			break;
535*cdf0e10cSrcweir 		case DISP_E_NONAMEDARGS:
536*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
537*cdf0e10cSrcweir                                    Reference<XInterface>());
538*cdf0e10cSrcweir 			break;
539*cdf0e10cSrcweir 		case DISP_E_OVERFLOW:
540*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
541*cdf0e10cSrcweir                                    Reference<XInterface>());
542*cdf0e10cSrcweir 			break;
543*cdf0e10cSrcweir 		case DISP_E_PARAMNOTFOUND:
544*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
545*cdf0e10cSrcweir                                    Reference<XInterface>());
546*cdf0e10cSrcweir 			break;
547*cdf0e10cSrcweir 		case DISP_E_TYPEMISMATCH:
548*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
549*cdf0e10cSrcweir                                    Reference<XInterface>());
550*cdf0e10cSrcweir 			break;
551*cdf0e10cSrcweir 		case DISP_E_UNKNOWNINTERFACE:
552*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
553*cdf0e10cSrcweir                                    Reference<XInterface>());
554*cdf0e10cSrcweir 			break;
555*cdf0e10cSrcweir 		case DISP_E_UNKNOWNLCID:
556*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
557*cdf0e10cSrcweir                                    Reference<XInterface>());
558*cdf0e10cSrcweir 			break;
559*cdf0e10cSrcweir 		case DISP_E_PARAMNOTOPTIONAL:
560*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
561*cdf0e10cSrcweir                                    Reference<XInterface>());
562*cdf0e10cSrcweir 			break;
563*cdf0e10cSrcweir 		default:
564*cdf0e10cSrcweir 			throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
565*cdf0e10cSrcweir                                    Reference<XInterface>());
566*cdf0e10cSrcweir 			break;
567*cdf0e10cSrcweir         }
568*cdf0e10cSrcweir     }
569*cdf0e10cSrcweir     catch (UnknownPropertyException& )
570*cdf0e10cSrcweir     {
571*cdf0e10cSrcweir         throw;
572*cdf0e10cSrcweir     }
573*cdf0e10cSrcweir     catch (BridgeRuntimeError& e)
574*cdf0e10cSrcweir 	{
575*cdf0e10cSrcweir         throw RuntimeException(
576*cdf0e10cSrcweir             e.message, Reference<XInterface>());
577*cdf0e10cSrcweir 	}
578*cdf0e10cSrcweir     catch (Exception & e)
579*cdf0e10cSrcweir     {
580*cdf0e10cSrcweir         throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
581*cdf0e10cSrcweir                                      "IUnknownWrapper_Impl::getValue ! Message : \n") +
582*cdf0e10cSrcweir                                e.Message, Reference<XInterface>());
583*cdf0e10cSrcweir     }
584*cdf0e10cSrcweir 	catch (...)
585*cdf0e10cSrcweir 	{
586*cdf0e10cSrcweir 		throw RuntimeException(
587*cdf0e10cSrcweir             OUSTR("[automation bridge] unexpected exception in "
588*cdf0e10cSrcweir 			"IUnknownWrapper_Impl::getValue !"), Reference<XInterface>());
589*cdf0e10cSrcweir 	}
590*cdf0e10cSrcweir 	return ret;
591*cdf0e10cSrcweir }
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir sal_Bool SAL_CALL IUnknownWrapper_Impl::hasMethod( const OUString& aName )
594*cdf0e10cSrcweir 		throw(RuntimeException)
595*cdf0e10cSrcweir {
596*cdf0e10cSrcweir     if ( ! m_spDispatch )
597*cdf0e10cSrcweir     {
598*cdf0e10cSrcweir         throw RuntimeException(
599*cdf0e10cSrcweir             OUSTR("[automation bridge] The object does not have an IDispatch interface"),
600*cdf0e10cSrcweir             Reference<XInterface>());
601*cdf0e10cSrcweir     }
602*cdf0e10cSrcweir 	sal_Bool ret = sal_False;
603*cdf0e10cSrcweir 
604*cdf0e10cSrcweir 	try
605*cdf0e10cSrcweir 	{
606*cdf0e10cSrcweir 		o2u_attachCurrentThread();
607*cdf0e10cSrcweir 		ITypeInfo* pInfo = getTypeInfo();
608*cdf0e10cSrcweir         FuncDesc aDesc(pInfo);
609*cdf0e10cSrcweir         getFuncDesc(aName, & aDesc);
610*cdf0e10cSrcweir 		// Automation properties can have arguments. Those are treated as methods and
611*cdf0e10cSrcweir 		//are called through XInvocation::invoke.
612*cdf0e10cSrcweir 		if ( ! aDesc)
613*cdf0e10cSrcweir 		{
614*cdf0e10cSrcweir 			FuncDesc aDescGet(pInfo);
615*cdf0e10cSrcweir 			FuncDesc aDescPut(pInfo);
616*cdf0e10cSrcweir             VarDesc aVarDesc(pInfo);
617*cdf0e10cSrcweir 			getPropDesc( aName, & aDescGet, & aDescPut, & aVarDesc);
618*cdf0e10cSrcweir 			if (aDescGet  && aDescGet->cParams > 0
619*cdf0e10cSrcweir                 || aDescPut && aDescPut->cParams > 0)
620*cdf0e10cSrcweir 				ret = sal_True;
621*cdf0e10cSrcweir 		}
622*cdf0e10cSrcweir 		else
623*cdf0e10cSrcweir 			ret = sal_True;
624*cdf0e10cSrcweir 	}
625*cdf0e10cSrcweir 	catch (BridgeRuntimeError& e)
626*cdf0e10cSrcweir 	{
627*cdf0e10cSrcweir 		throw RuntimeException(e.message, Reference<XInterface>());
628*cdf0e10cSrcweir 	}
629*cdf0e10cSrcweir     catch (Exception & e)
630*cdf0e10cSrcweir     {
631*cdf0e10cSrcweir         throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
632*cdf0e10cSrcweir                                      "IUnknownWrapper_Impl::hasMethod ! Message : \n") +
633*cdf0e10cSrcweir                                e.Message, Reference<XInterface>());
634*cdf0e10cSrcweir     }
635*cdf0e10cSrcweir 	catch (...)
636*cdf0e10cSrcweir 	{
637*cdf0e10cSrcweir 		throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
638*cdf0e10cSrcweir 			"IUnknownWrapper_Impl::hasMethod !"), Reference<XInterface>());;
639*cdf0e10cSrcweir 	}
640*cdf0e10cSrcweir     return ret;
641*cdf0e10cSrcweir }
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir sal_Bool SAL_CALL IUnknownWrapper_Impl::hasProperty( const OUString& aName )
644*cdf0e10cSrcweir 		throw(RuntimeException)
645*cdf0e10cSrcweir {
646*cdf0e10cSrcweir     if ( ! m_spDispatch )
647*cdf0e10cSrcweir     {
648*cdf0e10cSrcweir         throw RuntimeException(OUSTR("[automation bridge] The object does not have an "
649*cdf0e10cSrcweir 			"IDispatch interface"), Reference<XInterface>());
650*cdf0e10cSrcweir 		return sal_False;
651*cdf0e10cSrcweir 	}
652*cdf0e10cSrcweir 	sal_Bool ret = sal_False;
653*cdf0e10cSrcweir 	try
654*cdf0e10cSrcweir 	{
655*cdf0e10cSrcweir 		o2u_attachCurrentThread();
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir 		ITypeInfo * pInfo = getTypeInfo();
658*cdf0e10cSrcweir         FuncDesc aDescGet(pInfo);
659*cdf0e10cSrcweir         FuncDesc aDescPut(pInfo);
660*cdf0e10cSrcweir         VarDesc aVarDesc(pInfo);
661*cdf0e10cSrcweir         getPropDesc(aName, & aDescGet, & aDescPut, & aVarDesc);
662*cdf0e10cSrcweir 		// Automation properties can have parameters. If so, we access them through
663*cdf0e10cSrcweir 		// XInvocation::invoke. Thas is, hasProperty must return false for such a
664*cdf0e10cSrcweir 		// property
665*cdf0e10cSrcweir         if (aVarDesc
666*cdf0e10cSrcweir             || aDescPut && aDescPut->cParams == 0
667*cdf0e10cSrcweir             || aDescGet && aDescGet->cParams == 0)
668*cdf0e10cSrcweir         {
669*cdf0e10cSrcweir             ret = sal_True;
670*cdf0e10cSrcweir         }
671*cdf0e10cSrcweir 	}
672*cdf0e10cSrcweir 	catch (BridgeRuntimeError& e)
673*cdf0e10cSrcweir 	{
674*cdf0e10cSrcweir 		throw RuntimeException(e.message, Reference<XInterface>());
675*cdf0e10cSrcweir 	}
676*cdf0e10cSrcweir     catch (Exception & e)
677*cdf0e10cSrcweir     {
678*cdf0e10cSrcweir         throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
679*cdf0e10cSrcweir                                      "IUnknownWrapper_Impl::hasProperty ! Message : \n") +
680*cdf0e10cSrcweir                                e.Message, Reference<XInterface>());
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir     }
683*cdf0e10cSrcweir 	catch (...)
684*cdf0e10cSrcweir 	{
685*cdf0e10cSrcweir 		throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
686*cdf0e10cSrcweir 			"IUnknownWrapper_Impl::hasProperty !"), Reference<XInterface>());
687*cdf0e10cSrcweir 	}
688*cdf0e10cSrcweir 	return ret;
689*cdf0e10cSrcweir }
690*cdf0e10cSrcweir 
691*cdf0e10cSrcweir Any SAL_CALL IUnknownWrapper_Impl::createBridge( const Any& modelDepObject,
692*cdf0e10cSrcweir 				const Sequence< sal_Int8 >& /*aProcessId*/, sal_Int16 sourceModelType,
693*cdf0e10cSrcweir 				 sal_Int16 destModelType )
694*cdf0e10cSrcweir 	throw( IllegalArgumentException, RuntimeException)
695*cdf0e10cSrcweir {
696*cdf0e10cSrcweir 	Any ret;
697*cdf0e10cSrcweir 	o2u_attachCurrentThread();
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir 	if (
700*cdf0e10cSrcweir 		(sourceModelType == UNO) &&
701*cdf0e10cSrcweir 		(destModelType == OLE) &&
702*cdf0e10cSrcweir 		(modelDepObject.getValueTypeClass() == TypeClass_INTERFACE)
703*cdf0e10cSrcweir 	   )
704*cdf0e10cSrcweir 	{
705*cdf0e10cSrcweir 		Reference<XInterface> xInt( *(XInterface**) modelDepObject.getValue());
706*cdf0e10cSrcweir 		Reference<XInterface> xSelf( (OWeakObject*)this);
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir 		if (xInt == xSelf)
709*cdf0e10cSrcweir 		{
710*cdf0e10cSrcweir 			VARIANT* pVariant = (VARIANT*) CoTaskMemAlloc(sizeof(VARIANT));
711*cdf0e10cSrcweir 
712*cdf0e10cSrcweir 			VariantInit(pVariant);
713*cdf0e10cSrcweir             if (m_bOriginalDispatch == sal_True)
714*cdf0e10cSrcweir             {
715*cdf0e10cSrcweir 				pVariant->vt = VT_DISPATCH;
716*cdf0e10cSrcweir 				pVariant->pdispVal = m_spDispatch;
717*cdf0e10cSrcweir 				pVariant->pdispVal->AddRef();
718*cdf0e10cSrcweir 			}
719*cdf0e10cSrcweir 			else
720*cdf0e10cSrcweir 			{
721*cdf0e10cSrcweir 				pVariant->vt = VT_UNKNOWN;
722*cdf0e10cSrcweir 				pVariant->punkVal = m_spUnknown;
723*cdf0e10cSrcweir 				pVariant->punkVal->AddRef();
724*cdf0e10cSrcweir 			}
725*cdf0e10cSrcweir 
726*cdf0e10cSrcweir 			ret.setValue((void*)&pVariant, getCppuType( (sal_uInt32*) 0));
727*cdf0e10cSrcweir 		}
728*cdf0e10cSrcweir 	}
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir 	return ret;
731*cdf0e10cSrcweir }
732*cdf0e10cSrcweir /** @internal
733*cdf0e10cSrcweir     @exception IllegalArgumentException
734*cdf0e10cSrcweir     @exception CannotConvertException
735*cdf0e10cSrcweir     @exception InvocationTargetException
736*cdf0e10cSrcweir     @RuntimeException
737*cdf0e10cSrcweir */
738*cdf0e10cSrcweir Any  IUnknownWrapper_Impl::invokeWithDispIdUnoTlb(const OUString& sFunctionName,
739*cdf0e10cSrcweir                                                   const Sequence< Any >& Params,
740*cdf0e10cSrcweir                                                   Sequence< sal_Int16 >& OutParamIndex,
741*cdf0e10cSrcweir                                                   Sequence< Any >& OutParam)
742*cdf0e10cSrcweir {
743*cdf0e10cSrcweir 	Any ret;
744*cdf0e10cSrcweir 	HRESULT hr= S_OK;
745*cdf0e10cSrcweir 
746*cdf0e10cSrcweir 	sal_Int32 parameterCount= Params.getLength();
747*cdf0e10cSrcweir 	sal_Int32 outParameterCount= 0;
748*cdf0e10cSrcweir 	typelib_InterfaceMethodTypeDescription* pMethod= NULL;
749*cdf0e10cSrcweir 	TypeDescription methodDesc;
750*cdf0e10cSrcweir 	getMethodInfo(sFunctionName, methodDesc);
751*cdf0e10cSrcweir 
752*cdf0e10cSrcweir 	// We need to know whether the IDispatch is from a JScript object.
753*cdf0e10cSrcweir 	// Then out and in/out parameters have to be treated differently than
754*cdf0e10cSrcweir 	// with common COM objects.
755*cdf0e10cSrcweir 	sal_Bool bJScriptObject= isJScriptObject();
756*cdf0e10cSrcweir     scoped_array<CComVariant> sarParams;
757*cdf0e10cSrcweir     scoped_array<CComVariant> sarParamsRef;
758*cdf0e10cSrcweir 	CComVariant *pVarParams= NULL;
759*cdf0e10cSrcweir 	CComVariant *pVarParamsRef= NULL;
760*cdf0e10cSrcweir 	sal_Bool bConvRet= sal_True;
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir 	if( methodDesc.is())
763*cdf0e10cSrcweir 	{
764*cdf0e10cSrcweir 		pMethod = (typelib_InterfaceMethodTypeDescription* )methodDesc.get();
765*cdf0e10cSrcweir 		parameterCount = pMethod->nParams;
766*cdf0e10cSrcweir 		// Create the Array for the array being passed in DISPPARAMS
767*cdf0e10cSrcweir 		// the array also contains the outparameter (but not the values)
768*cdf0e10cSrcweir 		if( pMethod->nParams > 0)
769*cdf0e10cSrcweir         {
770*cdf0e10cSrcweir             sarParams.reset(new CComVariant[ parameterCount]);
771*cdf0e10cSrcweir             pVarParams = sarParams.get();
772*cdf0e10cSrcweir         }
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir 		// Create the Array for the out an in/out parameter. These values
775*cdf0e10cSrcweir 		// are referenced by the VT_BYREF VARIANTs in DISPPARAMS.
776*cdf0e10cSrcweir 		// We need to find out the number of out and in/out parameter.
777*cdf0e10cSrcweir 		for( sal_Int32 i=0; i < parameterCount; i++)
778*cdf0e10cSrcweir 		{
779*cdf0e10cSrcweir 			if( pMethod->pParams[i].bOut)
780*cdf0e10cSrcweir 				outParameterCount++;
781*cdf0e10cSrcweir 		}
782*cdf0e10cSrcweir 
783*cdf0e10cSrcweir 		if( !bJScriptObject)
784*cdf0e10cSrcweir 		{
785*cdf0e10cSrcweir             sarParamsRef.reset(new CComVariant[outParameterCount]);
786*cdf0e10cSrcweir 			pVarParamsRef = sarParamsRef.get();
787*cdf0e10cSrcweir 			// build up the parameters for IDispatch::Invoke
788*cdf0e10cSrcweir 			sal_Int32 outParamIndex=0;
789*cdf0e10cSrcweir 			int i = 0;
790*cdf0e10cSrcweir 			try
791*cdf0e10cSrcweir 			{
792*cdf0e10cSrcweir 				for( i= 0; i < parameterCount; i++)
793*cdf0e10cSrcweir 				{
794*cdf0e10cSrcweir 					// In parameter
795*cdf0e10cSrcweir 					if( pMethod->pParams[i].bIn == sal_True && ! pMethod->pParams[i].bOut)
796*cdf0e10cSrcweir 					{
797*cdf0e10cSrcweir 						anyToVariant( &pVarParams[parameterCount - i -1], Params.getConstArray()[i]);
798*cdf0e10cSrcweir 					}
799*cdf0e10cSrcweir 					// Out parameter + in/out parameter
800*cdf0e10cSrcweir 					else if( pMethod->pParams[i].bOut == sal_True)
801*cdf0e10cSrcweir 					{
802*cdf0e10cSrcweir 						CComVariant var;
803*cdf0e10cSrcweir 						if(pMethod->pParams[i].bIn)
804*cdf0e10cSrcweir 						{
805*cdf0e10cSrcweir 							anyToVariant( & var,Params[i]);
806*cdf0e10cSrcweir 							pVarParamsRef[outParamIndex] = var;
807*cdf0e10cSrcweir 						}
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir 						switch( pMethod->pParams[i].pTypeRef->eTypeClass)
810*cdf0e10cSrcweir 						{
811*cdf0e10cSrcweir 						case TypeClass_INTERFACE:
812*cdf0e10cSrcweir 						case TypeClass_STRUCT:
813*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
814*cdf0e10cSrcweir 							{
815*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt= VT_DISPATCH;
816*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].pdispVal= 0;
817*cdf0e10cSrcweir 							}
818*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_DISPATCH | VT_BYREF;
819*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].ppdispVal= &pVarParamsRef[outParamIndex].pdispVal;
820*cdf0e10cSrcweir 							break;
821*cdf0e10cSrcweir 						case TypeClass_ENUM:
822*cdf0e10cSrcweir 						case TypeClass_LONG:
823*cdf0e10cSrcweir 						case TypeClass_UNSIGNED_LONG:
824*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
825*cdf0e10cSrcweir 							{
826*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_I4;
827*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].lVal = 0;
828*cdf0e10cSrcweir 							}
829*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_I4 | VT_BYREF;
830*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].plVal= &pVarParamsRef[outParamIndex].lVal;
831*cdf0e10cSrcweir 							break;
832*cdf0e10cSrcweir 						case TypeClass_SEQUENCE:
833*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
834*cdf0e10cSrcweir 							{
835*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_ARRAY| VT_VARIANT;
836*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].parray= NULL;
837*cdf0e10cSrcweir 							}
838*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_ARRAY| VT_BYREF | VT_VARIANT;
839*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].pparray= &pVarParamsRef[outParamIndex].parray;
840*cdf0e10cSrcweir 							break;
841*cdf0e10cSrcweir 						case TypeClass_ANY:
842*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
843*cdf0e10cSrcweir 							{
844*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_EMPTY;
845*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].lVal = 0;
846*cdf0e10cSrcweir 							}
847*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_VARIANT | VT_BYREF;
848*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].pvarVal = &pVarParamsRef[outParamIndex];
849*cdf0e10cSrcweir 							break;
850*cdf0e10cSrcweir 						case TypeClass_BOOLEAN:
851*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
852*cdf0e10cSrcweir 							{
853*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_BOOL;
854*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].boolVal = 0;
855*cdf0e10cSrcweir 							}
856*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_BOOL| VT_BYREF;
857*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].pboolVal =
858*cdf0e10cSrcweir 								& pVarParamsRef[outParamIndex].boolVal;
859*cdf0e10cSrcweir 							break;
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir 						case TypeClass_STRING:
862*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
863*cdf0e10cSrcweir 							{
864*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_BSTR;
865*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].bstrVal= 0;
866*cdf0e10cSrcweir 							}
867*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_BSTR| VT_BYREF;
868*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].pbstrVal=
869*cdf0e10cSrcweir 								& pVarParamsRef[outParamIndex].bstrVal;
870*cdf0e10cSrcweir 							break;
871*cdf0e10cSrcweir 
872*cdf0e10cSrcweir 						case TypeClass_FLOAT:
873*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
874*cdf0e10cSrcweir 							{
875*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_R4;
876*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].fltVal= 0;
877*cdf0e10cSrcweir 							}
878*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_R4| VT_BYREF;
879*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].pfltVal =
880*cdf0e10cSrcweir 								& pVarParamsRef[outParamIndex].fltVal;
881*cdf0e10cSrcweir 							break;
882*cdf0e10cSrcweir 						case TypeClass_DOUBLE:
883*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
884*cdf0e10cSrcweir 							{
885*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_R8;
886*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].dblVal= 0;
887*cdf0e10cSrcweir 							}
888*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_R8| VT_BYREF;
889*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].pdblVal=
890*cdf0e10cSrcweir 								& pVarParamsRef[outParamIndex].dblVal;
891*cdf0e10cSrcweir 							break;
892*cdf0e10cSrcweir 						case TypeClass_BYTE:
893*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
894*cdf0e10cSrcweir 							{
895*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_UI1;
896*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].bVal= 0;
897*cdf0e10cSrcweir 							}
898*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_UI1| VT_BYREF;
899*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].pbVal=
900*cdf0e10cSrcweir 								& pVarParamsRef[outParamIndex].bVal;
901*cdf0e10cSrcweir 							break;
902*cdf0e10cSrcweir 						case TypeClass_CHAR:
903*cdf0e10cSrcweir 						case TypeClass_SHORT:
904*cdf0e10cSrcweir 						case TypeClass_UNSIGNED_SHORT:
905*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
906*cdf0e10cSrcweir 							{
907*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_I2;
908*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].iVal = 0;
909*cdf0e10cSrcweir 							}
910*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_I2| VT_BYREF;
911*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].piVal=
912*cdf0e10cSrcweir 								& pVarParamsRef[outParamIndex].iVal;
913*cdf0e10cSrcweir 							break;
914*cdf0e10cSrcweir 
915*cdf0e10cSrcweir 						default:
916*cdf0e10cSrcweir 							if( ! pMethod->pParams[i].bIn)
917*cdf0e10cSrcweir 							{
918*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].vt = VT_EMPTY;
919*cdf0e10cSrcweir 								pVarParamsRef[ outParamIndex].lVal = 0;
920*cdf0e10cSrcweir 							}
921*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].vt = VT_VARIANT | VT_BYREF;
922*cdf0e10cSrcweir 							pVarParams[parameterCount - i -1].pvarVal =
923*cdf0e10cSrcweir 								& pVarParamsRef[outParamIndex];
924*cdf0e10cSrcweir 						}
925*cdf0e10cSrcweir 						outParamIndex++;
926*cdf0e10cSrcweir 					} // end else if
927*cdf0e10cSrcweir 				} // end for
928*cdf0e10cSrcweir 			}
929*cdf0e10cSrcweir 			catch (IllegalArgumentException & e)
930*cdf0e10cSrcweir 			{
931*cdf0e10cSrcweir                 e.ArgumentPosition = ::sal::static_int_cast< sal_Int16, int >( i );
932*cdf0e10cSrcweir 				throw;
933*cdf0e10cSrcweir 			}
934*cdf0e10cSrcweir 			catch (CannotConvertException & e)
935*cdf0e10cSrcweir 			{
936*cdf0e10cSrcweir 				e.ArgumentIndex = i;
937*cdf0e10cSrcweir 				throw;
938*cdf0e10cSrcweir 			}
939*cdf0e10cSrcweir 		}
940*cdf0e10cSrcweir 		else // it is an JScriptObject
941*cdf0e10cSrcweir 		{
942*cdf0e10cSrcweir 			int i = 0;
943*cdf0e10cSrcweir 			try
944*cdf0e10cSrcweir 			{
945*cdf0e10cSrcweir 				for( ; i< parameterCount; i++)
946*cdf0e10cSrcweir 				{
947*cdf0e10cSrcweir 					// In parameter
948*cdf0e10cSrcweir 					if( pMethod->pParams[i].bIn == sal_True && ! pMethod->pParams[i].bOut)
949*cdf0e10cSrcweir 					{
950*cdf0e10cSrcweir 						anyToVariant( &pVarParams[parameterCount - i -1], Params.getConstArray()[i]);
951*cdf0e10cSrcweir 					}
952*cdf0e10cSrcweir 					// Out parameter + in/out parameter
953*cdf0e10cSrcweir 					else if( pMethod->pParams[i].bOut == sal_True)
954*cdf0e10cSrcweir 					{
955*cdf0e10cSrcweir 						CComObject<JScriptOutParam>* pParamObject;
956*cdf0e10cSrcweir 						if( SUCCEEDED( CComObject<JScriptOutParam>::CreateInstance( &pParamObject)))
957*cdf0e10cSrcweir 						{
958*cdf0e10cSrcweir 							CComPtr<IUnknown> pUnk(pParamObject->GetUnknown());
959*cdf0e10cSrcweir #ifdef __MINGW32__
960*cdf0e10cSrcweir 							CComQIPtr<IDispatch, &__uuidof(IDispatch)> pDisp( pUnk);
961*cdf0e10cSrcweir #else
962*cdf0e10cSrcweir 							CComQIPtr<IDispatch> pDisp( pUnk);
963*cdf0e10cSrcweir #endif
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir 							pVarParams[ parameterCount - i -1].vt= VT_DISPATCH;
966*cdf0e10cSrcweir 							pVarParams[ parameterCount - i -1].pdispVal= pDisp;
967*cdf0e10cSrcweir 							pVarParams[ parameterCount - i -1].pdispVal->AddRef();
968*cdf0e10cSrcweir 							// if the param is in/out then put the parameter on index 0
969*cdf0e10cSrcweir 							if( pMethod->pParams[i].bIn == sal_True ) // in / out
970*cdf0e10cSrcweir 							{
971*cdf0e10cSrcweir 								CComVariant varParam;
972*cdf0e10cSrcweir 								anyToVariant( &varParam, Params.getConstArray()[i]);
973*cdf0e10cSrcweir 								CComDispatchDriver dispDriver( pDisp);
974*cdf0e10cSrcweir 								if(FAILED( dispDriver.PutPropertyByName( L"0", &varParam)))
975*cdf0e10cSrcweir 									throw BridgeRuntimeError(
976*cdf0e10cSrcweir                                         OUSTR("[automation bridge]IUnknownWrapper_Impl::"
977*cdf0e10cSrcweir                                               "invokeWithDispIdUnoTlb\n"
978*cdf0e10cSrcweir                                               "Could not set property \"0\" for the in/out "
979*cdf0e10cSrcweir                                               "param!"));
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir 							}
982*cdf0e10cSrcweir 						}
983*cdf0e10cSrcweir 						else
984*cdf0e10cSrcweir 						{
985*cdf0e10cSrcweir                             throw BridgeRuntimeError(
986*cdf0e10cSrcweir                                 OUSTR("[automation bridge]IUnknownWrapper_Impl::"
987*cdf0e10cSrcweir                                       "invokeWithDispIdUnoTlb\n"
988*cdf0e10cSrcweir                                       "Could not create out parameter at index: ") +
989*cdf0e10cSrcweir                                 OUString::valueOf((sal_Int32) i));
990*cdf0e10cSrcweir 						}
991*cdf0e10cSrcweir 
992*cdf0e10cSrcweir 					}
993*cdf0e10cSrcweir 				}
994*cdf0e10cSrcweir 			}
995*cdf0e10cSrcweir 			catch (IllegalArgumentException & e)
996*cdf0e10cSrcweir 			{
997*cdf0e10cSrcweir 				e.ArgumentPosition = ::sal::static_int_cast< sal_Int16, int >( i );
998*cdf0e10cSrcweir 				throw;
999*cdf0e10cSrcweir 			}
1000*cdf0e10cSrcweir 			catch (CannotConvertException & e)
1001*cdf0e10cSrcweir 			{
1002*cdf0e10cSrcweir 				e.ArgumentIndex = i;
1003*cdf0e10cSrcweir 				throw;
1004*cdf0e10cSrcweir 			}
1005*cdf0e10cSrcweir 		}
1006*cdf0e10cSrcweir 	}
1007*cdf0e10cSrcweir 	// No type description Available, that is we have to deal with a COM component,
1008*cdf0e10cSrcweir 	// that does not implements UNO interfaces ( IDispatch based)
1009*cdf0e10cSrcweir 	else
1010*cdf0e10cSrcweir 	{
1011*cdf0e10cSrcweir         //We should not run into this block, because invokeWithDispIdComTlb should
1012*cdf0e10cSrcweir         //have been called instead.
1013*cdf0e10cSrcweir         OSL_ASSERT(0);
1014*cdf0e10cSrcweir 	}
1015*cdf0e10cSrcweir 
1016*cdf0e10cSrcweir 
1017*cdf0e10cSrcweir     CComVariant		varResult;
1018*cdf0e10cSrcweir     ExcepInfo 		excepinfo;
1019*cdf0e10cSrcweir     unsigned int 	uArgErr;
1020*cdf0e10cSrcweir     DISPPARAMS dispparams= { pVarParams, NULL, parameterCount, 0};
1021*cdf0e10cSrcweir     // Get the DISPID
1022*cdf0e10cSrcweir     FuncDesc aDesc(getTypeInfo());
1023*cdf0e10cSrcweir     getFuncDesc(sFunctionName, & aDesc);
1024*cdf0e10cSrcweir     // invoking OLE method
1025*cdf0e10cSrcweir     hr = m_spDispatch->Invoke(aDesc->memid,
1026*cdf0e10cSrcweir                              IID_NULL,
1027*cdf0e10cSrcweir                              LOCALE_USER_DEFAULT,
1028*cdf0e10cSrcweir                              DISPATCH_METHOD,
1029*cdf0e10cSrcweir                              &dispparams,
1030*cdf0e10cSrcweir                              &varResult,
1031*cdf0e10cSrcweir                              &excepinfo,
1032*cdf0e10cSrcweir                              &uArgErr);
1033*cdf0e10cSrcweir 
1034*cdf0e10cSrcweir     // converting return value and out parameter back to UNO
1035*cdf0e10cSrcweir     if (hr == S_OK)
1036*cdf0e10cSrcweir     {
1037*cdf0e10cSrcweir         if( outParameterCount && pMethod)
1038*cdf0e10cSrcweir         {
1039*cdf0e10cSrcweir             OutParamIndex.realloc( outParameterCount);
1040*cdf0e10cSrcweir             OutParam.realloc( outParameterCount);
1041*cdf0e10cSrcweir             sal_Int32 outIndex=0;
1042*cdf0e10cSrcweir 			int i = 0;
1043*cdf0e10cSrcweir 			try
1044*cdf0e10cSrcweir 			{
1045*cdf0e10cSrcweir 				for( ; i < parameterCount; i++)
1046*cdf0e10cSrcweir 				{
1047*cdf0e10cSrcweir 					if( pMethod->pParams[i].bOut )
1048*cdf0e10cSrcweir 					{
1049*cdf0e10cSrcweir 						OutParamIndex[outIndex]= (sal_Int16) i;
1050*cdf0e10cSrcweir 						Any outAny;
1051*cdf0e10cSrcweir 						if( !bJScriptObject)
1052*cdf0e10cSrcweir 						{
1053*cdf0e10cSrcweir 							variantToAny( &pVarParamsRef[outIndex], outAny,
1054*cdf0e10cSrcweir 										Type(pMethod->pParams[i].pTypeRef), sal_False);
1055*cdf0e10cSrcweir 							OutParam[outIndex++]= outAny;
1056*cdf0e10cSrcweir 						}
1057*cdf0e10cSrcweir 						else //JScriptObject
1058*cdf0e10cSrcweir 						{
1059*cdf0e10cSrcweir 							if( pVarParams[i].vt == VT_DISPATCH)
1060*cdf0e10cSrcweir 							{
1061*cdf0e10cSrcweir 								CComDispatchDriver pDisp( pVarParams[i].pdispVal);
1062*cdf0e10cSrcweir 								if( pDisp)
1063*cdf0e10cSrcweir 								{
1064*cdf0e10cSrcweir 									CComVariant varOut;
1065*cdf0e10cSrcweir 									if( SUCCEEDED( pDisp.GetPropertyByName( L"0", &varOut)))
1066*cdf0e10cSrcweir 									{
1067*cdf0e10cSrcweir 										variantToAny( &varOut, outAny,
1068*cdf0e10cSrcweir 													Type(pMethod->pParams[parameterCount - 1 - i].pTypeRef), sal_False);
1069*cdf0e10cSrcweir 										OutParam[outParameterCount - 1 - outIndex++]= outAny;
1070*cdf0e10cSrcweir 									}
1071*cdf0e10cSrcweir 									else
1072*cdf0e10cSrcweir 										bConvRet= sal_False;
1073*cdf0e10cSrcweir 								}
1074*cdf0e10cSrcweir 								else
1075*cdf0e10cSrcweir 									bConvRet= sal_False;
1076*cdf0e10cSrcweir 							}
1077*cdf0e10cSrcweir 							else
1078*cdf0e10cSrcweir 								bConvRet= sal_False;
1079*cdf0e10cSrcweir 						}
1080*cdf0e10cSrcweir 					}
1081*cdf0e10cSrcweir 					if( !bConvRet) break;
1082*cdf0e10cSrcweir 				}
1083*cdf0e10cSrcweir 			}
1084*cdf0e10cSrcweir 			catch(IllegalArgumentException & e)
1085*cdf0e10cSrcweir 			{
1086*cdf0e10cSrcweir 				e.ArgumentPosition = ::sal::static_int_cast< sal_Int16, int >( i );
1087*cdf0e10cSrcweir 				throw;
1088*cdf0e10cSrcweir 			}
1089*cdf0e10cSrcweir 			catch(CannotConvertException & e)
1090*cdf0e10cSrcweir 			{
1091*cdf0e10cSrcweir 				e.ArgumentIndex = i;
1092*cdf0e10cSrcweir 				throw;
1093*cdf0e10cSrcweir 			}
1094*cdf0e10cSrcweir         }
1095*cdf0e10cSrcweir         // return value, no type information available
1096*cdf0e10cSrcweir         if ( bConvRet)
1097*cdf0e10cSrcweir 		{
1098*cdf0e10cSrcweir 			try
1099*cdf0e10cSrcweir 			{
1100*cdf0e10cSrcweir 				if( pMethod	)
1101*cdf0e10cSrcweir 					variantToAny(&varResult, ret, Type( pMethod->pReturnTypeRef), sal_False);
1102*cdf0e10cSrcweir 				else
1103*cdf0e10cSrcweir 					variantToAny(&varResult, ret, sal_False);
1104*cdf0e10cSrcweir 			}
1105*cdf0e10cSrcweir 			catch (IllegalArgumentException & e)
1106*cdf0e10cSrcweir 			{
1107*cdf0e10cSrcweir 				e.Message =
1108*cdf0e10cSrcweir 					OUSTR("[automation bridge]IUnknownWrapper_Impl::invokeWithDispIdUnoTlb\n"
1109*cdf0e10cSrcweir 					"Could not convert return value! \n Message: \n") + e.Message;
1110*cdf0e10cSrcweir 				throw;
1111*cdf0e10cSrcweir 			}
1112*cdf0e10cSrcweir 			catch (CannotConvertException & e)
1113*cdf0e10cSrcweir 			{
1114*cdf0e10cSrcweir 				e.Message =
1115*cdf0e10cSrcweir 					OUSTR("[automation bridge]IUnknownWrapper_Impl::invokeWithDispIdUnoTlb\n"
1116*cdf0e10cSrcweir 					"Could not convert return value! \n Message: \n") + e.Message;
1117*cdf0e10cSrcweir 				throw;
1118*cdf0e10cSrcweir 			}
1119*cdf0e10cSrcweir 		}
1120*cdf0e10cSrcweir     }
1121*cdf0e10cSrcweir 
1122*cdf0e10cSrcweir     if( !bConvRet) // conversion of return or out parameter failed
1123*cdf0e10cSrcweir         throw CannotConvertException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Call to COM object failed. Conversion of return or out value failed")),
1124*cdf0e10cSrcweir                                       Reference<XInterface>( static_cast<XWeak*>(this), UNO_QUERY	), TypeClass_UNKNOWN,
1125*cdf0e10cSrcweir                                       FailReason::UNKNOWN, 0);// lookup error code
1126*cdf0e10cSrcweir     // conversion of return or out parameter failed
1127*cdf0e10cSrcweir     switch (hr)
1128*cdf0e10cSrcweir     {
1129*cdf0e10cSrcweir     case S_OK:
1130*cdf0e10cSrcweir         break;
1131*cdf0e10cSrcweir     case DISP_E_BADPARAMCOUNT:
1132*cdf0e10cSrcweir         throw IllegalArgumentException();
1133*cdf0e10cSrcweir         break;
1134*cdf0e10cSrcweir     case DISP_E_BADVARTYPE:
1135*cdf0e10cSrcweir         throw RuntimeException();
1136*cdf0e10cSrcweir         break;
1137*cdf0e10cSrcweir     case DISP_E_EXCEPTION:
1138*cdf0e10cSrcweir         throw InvocationTargetException();
1139*cdf0e10cSrcweir         break;
1140*cdf0e10cSrcweir     case DISP_E_MEMBERNOTFOUND:
1141*cdf0e10cSrcweir         throw IllegalArgumentException();
1142*cdf0e10cSrcweir         break;
1143*cdf0e10cSrcweir     case DISP_E_NONAMEDARGS:
1144*cdf0e10cSrcweir         throw IllegalArgumentException();
1145*cdf0e10cSrcweir         break;
1146*cdf0e10cSrcweir     case DISP_E_OVERFLOW:
1147*cdf0e10cSrcweir         throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
1148*cdf0e10cSrcweir                                          static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::OUT_OF_RANGE, uArgErr);
1149*cdf0e10cSrcweir         break;
1150*cdf0e10cSrcweir     case DISP_E_PARAMNOTFOUND:
1151*cdf0e10cSrcweir         throw IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
1152*cdf0e10cSrcweir                                            static_cast<XWeak*>(this)), ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
1153*cdf0e10cSrcweir         break;
1154*cdf0e10cSrcweir     case DISP_E_TYPEMISMATCH:
1155*cdf0e10cSrcweir         throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")),static_cast<XInterface*>(
1156*cdf0e10cSrcweir                                          static_cast<XWeak*>(this)) , TypeClass_UNKNOWN, FailReason::UNKNOWN, uArgErr);
1157*cdf0e10cSrcweir         break;
1158*cdf0e10cSrcweir     case DISP_E_UNKNOWNINTERFACE:
1159*cdf0e10cSrcweir         throw RuntimeException() ;
1160*cdf0e10cSrcweir         break;
1161*cdf0e10cSrcweir     case DISP_E_UNKNOWNLCID:
1162*cdf0e10cSrcweir         throw RuntimeException() ;
1163*cdf0e10cSrcweir         break;
1164*cdf0e10cSrcweir     case DISP_E_PARAMNOTOPTIONAL:
1165*cdf0e10cSrcweir         throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
1166*cdf0e10cSrcweir                                          static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::NO_DEFAULT_AVAILABLE, uArgErr);
1167*cdf0e10cSrcweir 				break;
1168*cdf0e10cSrcweir     default:
1169*cdf0e10cSrcweir         throw RuntimeException();
1170*cdf0e10cSrcweir         break;
1171*cdf0e10cSrcweir     }
1172*cdf0e10cSrcweir 
1173*cdf0e10cSrcweir 	return ret;
1174*cdf0e10cSrcweir }
1175*cdf0e10cSrcweir 
1176*cdf0e10cSrcweir 
1177*cdf0e10cSrcweir 
1178*cdf0e10cSrcweir // --------------------------
1179*cdf0e10cSrcweir // XInitialization
1180*cdf0e10cSrcweir void SAL_CALL IUnknownWrapper_Impl::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException)
1181*cdf0e10cSrcweir {
1182*cdf0e10cSrcweir 	// 1.parameter is IUnknown
1183*cdf0e10cSrcweir 	// 2.parameter is a boolean which indicates if the the COM pointer was a IUnknown or IDispatch
1184*cdf0e10cSrcweir 	// 3.parameter is a Sequence<Type>
1185*cdf0e10cSrcweir 	o2u_attachCurrentThread();
1186*cdf0e10cSrcweir 	OSL_ASSERT(aArguments.getLength() == 3);
1187*cdf0e10cSrcweir 
1188*cdf0e10cSrcweir     m_spUnknown= *(IUnknown**) aArguments[0].getValue();
1189*cdf0e10cSrcweir #ifdef __MINGW32__
1190*cdf0e10cSrcweir     m_spUnknown->QueryInterface(IID_IDispatch, reinterpret_cast<LPVOID*>( & m_spDispatch.p));
1191*cdf0e10cSrcweir #else
1192*cdf0e10cSrcweir     m_spUnknown.QueryInterface( & m_spDispatch.p);
1193*cdf0e10cSrcweir #endif
1194*cdf0e10cSrcweir 
1195*cdf0e10cSrcweir     aArguments[1] >>= m_bOriginalDispatch;
1196*cdf0e10cSrcweir 	aArguments[2] >>= m_seqTypes;
1197*cdf0e10cSrcweir 
1198*cdf0e10cSrcweir     ITypeInfo* pType = NULL;
1199*cdf0e10cSrcweir     try
1200*cdf0e10cSrcweir     {
1201*cdf0e10cSrcweir         // a COM object implementation that has no TypeInfo is still a legal COM object;
1202*cdf0e10cSrcweir         // such objects can at least be transported through UNO using the bridge
1203*cdf0e10cSrcweir         // so we should allow to create wrappers for them as well
1204*cdf0e10cSrcweir         pType = getTypeInfo();
1205*cdf0e10cSrcweir     }
1206*cdf0e10cSrcweir     catch( BridgeRuntimeError& )
1207*cdf0e10cSrcweir     {}
1208*cdf0e10cSrcweir     catch( Exception& )
1209*cdf0e10cSrcweir     {}
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir     if ( pType )
1212*cdf0e10cSrcweir     {
1213*cdf0e10cSrcweir         try
1214*cdf0e10cSrcweir         {
1215*cdf0e10cSrcweir             // Get Default member
1216*cdf0e10cSrcweir             CComBSTR defaultMemberName;
1217*cdf0e10cSrcweir             if ( SUCCEEDED( pType->GetDocumentation(0, &defaultMemberName, 0, 0, 0 ) ) )
1218*cdf0e10cSrcweir             {
1219*cdf0e10cSrcweir                 OUString usName(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(defaultMemberName)));
1220*cdf0e10cSrcweir                 FuncDesc aDescGet(pType);
1221*cdf0e10cSrcweir                 FuncDesc aDescPut(pType);
1222*cdf0e10cSrcweir                 VarDesc aVarDesc(pType);
1223*cdf0e10cSrcweir                 // see if this is a property first ( more likely to be a property then a method )
1224*cdf0e10cSrcweir                 getPropDesc( usName, & aDescGet, & aDescPut, & aVarDesc);
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir                 if ( !aDescGet && !aDescPut )
1227*cdf0e10cSrcweir                 {
1228*cdf0e10cSrcweir                     getFuncDesc( usName, &aDescGet );
1229*cdf0e10cSrcweir                     if ( !aDescGet )
1230*cdf0e10cSrcweir                         throw BridgeRuntimeError( OUSTR("[automation bridge]IUnknownWrapper_Impl::initialize() Failed to get Function or Property desc. for " ) + usName );
1231*cdf0e10cSrcweir                 }
1232*cdf0e10cSrcweir                 // now for some funny heuristics to make basic understand what to do
1233*cdf0e10cSrcweir                 // a single aDescGet ( that doesn't take any params ) would be
1234*cdf0e10cSrcweir                 // a read only ( defaultmember ) property e.g. this object
1235*cdf0e10cSrcweir                 // should implement XDefaultProperty
1236*cdf0e10cSrcweir                 // a single aDescGet ( that *does* ) take params is basically a
1237*cdf0e10cSrcweir                 // default method e.g. implement XDefaultMethod
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir                 // a DescPut ( I guess we only really support a default param with '1' param ) as a setValue ( but I guess we can leave it through, the object will fail if we don't get it right anyway )
1240*cdf0e10cSrcweir                 if ( aDescPut || ( aDescGet && aDescGet->cParams == 0 ) )
1241*cdf0e10cSrcweir                     m_bHasDfltProperty = true;
1242*cdf0e10cSrcweir                 if ( aDescGet->cParams > 0 )
1243*cdf0e10cSrcweir                     m_bHasDfltMethod = true;
1244*cdf0e10cSrcweir                 if ( m_bHasDfltProperty || m_bHasDfltMethod )
1245*cdf0e10cSrcweir                     m_sDefaultMember = usName;
1246*cdf0e10cSrcweir             }
1247*cdf0e10cSrcweir         }
1248*cdf0e10cSrcweir         catch ( BridgeRuntimeError & e )
1249*cdf0e10cSrcweir         {
1250*cdf0e10cSrcweir             throw RuntimeException( e.message, Reference<XInterface>() );
1251*cdf0e10cSrcweir         }
1252*cdf0e10cSrcweir         catch( Exception& e )
1253*cdf0e10cSrcweir         {
1254*cdf0e10cSrcweir             throw RuntimeException(
1255*cdf0e10cSrcweir                     OUSTR("[automation bridge] unexpected exception in IUnknownWrapper_Impl::initialiase() error message: \n") + e.Message,
1256*cdf0e10cSrcweir                     Reference<XInterface>() );
1257*cdf0e10cSrcweir         }
1258*cdf0e10cSrcweir     }
1259*cdf0e10cSrcweir }
1260*cdf0e10cSrcweir 
1261*cdf0e10cSrcweir // --------------------------
1262*cdf0e10cSrcweir // XDirectInvocation
1263*cdf0e10cSrcweir uno::Any SAL_CALL IUnknownWrapper_Impl::directInvoke( const ::rtl::OUString& aName, const uno::Sequence< uno::Any >& aParams )
1264*cdf0e10cSrcweir     throw (lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
1265*cdf0e10cSrcweir {
1266*cdf0e10cSrcweir 	Any aResult;
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir     if ( !m_spDispatch )
1269*cdf0e10cSrcweir     {
1270*cdf0e10cSrcweir         throw RuntimeException(
1271*cdf0e10cSrcweir             OUSTR("[automation bridge] The object does not have an IDispatch interface"),
1272*cdf0e10cSrcweir             Reference<XInterface>());
1273*cdf0e10cSrcweir     }
1274*cdf0e10cSrcweir 
1275*cdf0e10cSrcweir     o2u_attachCurrentThread();
1276*cdf0e10cSrcweir     DISPID dispid;
1277*cdf0e10cSrcweir     if ( !getDispid( aName, &dispid ) )
1278*cdf0e10cSrcweir         throw IllegalArgumentException(
1279*cdf0e10cSrcweir             OUSTR( "[automation bridge] The object does not have a function or property " )
1280*cdf0e10cSrcweir             + aName, Reference<XInterface>(), 0);
1281*cdf0e10cSrcweir 
1282*cdf0e10cSrcweir 	CComVariant		varResult;
1283*cdf0e10cSrcweir 	ExcepInfo 		excepinfo;
1284*cdf0e10cSrcweir 	unsigned int 	uArgErr = 0;
1285*cdf0e10cSrcweir     INVOKEKIND pInvkinds[2];
1286*cdf0e10cSrcweir     pInvkinds[0] = INVOKE_FUNC;
1287*cdf0e10cSrcweir     pInvkinds[1] = aParams.getLength() ? INVOKE_PROPERTYPUT : INVOKE_PROPERTYGET;
1288*cdf0e10cSrcweir     HRESULT hInvRes = E_FAIL;
1289*cdf0e10cSrcweir 
1290*cdf0e10cSrcweir     // try Invoke first, if it does not work, try put/get property
1291*cdf0e10cSrcweir     for ( sal_Int32 nStep = 0; FAILED( hInvRes ) && nStep < 2; nStep++ )
1292*cdf0e10cSrcweir     {
1293*cdf0e10cSrcweir         DISPPARAMS 		dispparams = {NULL, NULL, 0, 0};
1294*cdf0e10cSrcweir 
1295*cdf0e10cSrcweir         DISPID idPropertyPut = DISPID_PROPERTYPUT;
1296*cdf0e10cSrcweir         scoped_array<DISPID> arDispidNamedArgs;
1297*cdf0e10cSrcweir         scoped_array<CComVariant> ptrArgs;
1298*cdf0e10cSrcweir         scoped_array<CComVariant> ptrRefArgs; // referenced arguments
1299*cdf0e10cSrcweir         CComVariant * arArgs = NULL;
1300*cdf0e10cSrcweir         CComVariant * arRefArgs = NULL;
1301*cdf0e10cSrcweir         bool bVarargParam = false;
1302*cdf0e10cSrcweir 
1303*cdf0e10cSrcweir         dispparams.cArgs = aParams.getLength();
1304*cdf0e10cSrcweir 
1305*cdf0e10cSrcweir         // Determine the number of named arguments
1306*cdf0e10cSrcweir         for ( sal_Int32 nInd = 0; nInd < aParams.getLength(); nInd++ )
1307*cdf0e10cSrcweir             if ( aParams[nInd].getValueType() == getCppuType((NamedArgument*) 0) )
1308*cdf0e10cSrcweir                 dispparams.cNamedArgs ++;
1309*cdf0e10cSrcweir 
1310*cdf0e10cSrcweir         // fill the named arguments
1311*cdf0e10cSrcweir         if ( dispparams.cNamedArgs > 0
1312*cdf0e10cSrcweir           && !( dispparams.cNamedArgs == 1 && pInvkinds[nStep] == INVOKE_PROPERTYPUT ) )
1313*cdf0e10cSrcweir         {
1314*cdf0e10cSrcweir             int nSizeAr = dispparams.cNamedArgs + 1;
1315*cdf0e10cSrcweir             if ( pInvkinds[nStep] == INVOKE_PROPERTYPUT )
1316*cdf0e10cSrcweir                 nSizeAr = dispparams.cNamedArgs;
1317*cdf0e10cSrcweir 
1318*cdf0e10cSrcweir             scoped_array<OLECHAR*> saNames(new OLECHAR*[nSizeAr]);
1319*cdf0e10cSrcweir             OLECHAR ** pNames = saNames.get();
1320*cdf0e10cSrcweir             pNames[0] = const_cast<OLECHAR*>(reinterpret_cast<LPCOLESTR>(aName.getStr()));
1321*cdf0e10cSrcweir 
1322*cdf0e10cSrcweir             int cNamedArg = 0;
1323*cdf0e10cSrcweir             for ( size_t nInd = 0; nInd < dispparams.cArgs; nInd++ )
1324*cdf0e10cSrcweir             {
1325*cdf0e10cSrcweir                 if ( aParams[nInd].getValueType() == getCppuType((NamedArgument*) 0))
1326*cdf0e10cSrcweir                 {
1327*cdf0e10cSrcweir                     const NamedArgument& arg = *(NamedArgument const*)aParams[nInd].getValue();
1328*cdf0e10cSrcweir 
1329*cdf0e10cSrcweir                     //We put the parameter names in reverse order into the array,
1330*cdf0e10cSrcweir                     //so we can use the DISPID array for DISPPARAMS::rgdispidNamedArgs
1331*cdf0e10cSrcweir                     //The first name in the array is the method name
1332*cdf0e10cSrcweir                     pNames[nSizeAr - 1 - cNamedArg++] = const_cast<OLECHAR*>(reinterpret_cast<LPCOLESTR>(arg.Name.getStr()));
1333*cdf0e10cSrcweir                 }
1334*cdf0e10cSrcweir             }
1335*cdf0e10cSrcweir 
1336*cdf0e10cSrcweir             arDispidNamedArgs.reset( new DISPID[nSizeAr] );
1337*cdf0e10cSrcweir             HRESULT hr = getTypeInfo()->GetIDsOfNames( pNames, nSizeAr, arDispidNamedArgs.get() );
1338*cdf0e10cSrcweir             if ( hr == E_NOTIMPL )
1339*cdf0e10cSrcweir                 hr = m_spDispatch->GetIDsOfNames(IID_NULL, pNames, nSizeAr, LOCALE_USER_DEFAULT, arDispidNamedArgs.get() );
1340*cdf0e10cSrcweir 
1341*cdf0e10cSrcweir             if ( SUCCEEDED( hr ) )
1342*cdf0e10cSrcweir             {
1343*cdf0e10cSrcweir                 if ( pInvkinds[nStep] == DISPATCH_PROPERTYPUT )
1344*cdf0e10cSrcweir                 {
1345*cdf0e10cSrcweir                     DISPID*  arIDs = arDispidNamedArgs.get();
1346*cdf0e10cSrcweir                     arIDs[0] = DISPID_PROPERTYPUT;
1347*cdf0e10cSrcweir                     dispparams.rgdispidNamedArgs = arIDs;
1348*cdf0e10cSrcweir                 }
1349*cdf0e10cSrcweir                 else
1350*cdf0e10cSrcweir                 {
1351*cdf0e10cSrcweir                     DISPID*  arIDs = arDispidNamedArgs.get();
1352*cdf0e10cSrcweir                     dispparams.rgdispidNamedArgs = & arIDs[1];
1353*cdf0e10cSrcweir                 }
1354*cdf0e10cSrcweir             }
1355*cdf0e10cSrcweir             else if (hr == DISP_E_UNKNOWNNAME)
1356*cdf0e10cSrcweir             {
1357*cdf0e10cSrcweir                  throw IllegalArgumentException(
1358*cdf0e10cSrcweir                      OUSTR("[automation bridge]One of the named arguments is wrong!"),
1359*cdf0e10cSrcweir                      Reference<XInterface>(), 0);
1360*cdf0e10cSrcweir             }
1361*cdf0e10cSrcweir             else
1362*cdf0e10cSrcweir             {
1363*cdf0e10cSrcweir                 throw InvocationTargetException(
1364*cdf0e10cSrcweir                     OUSTR("[automation bridge] ITypeInfo::GetIDsOfNames returned error ")
1365*cdf0e10cSrcweir                     + OUString::valueOf((sal_Int32) hr, 16), Reference<XInterface>(), Any());
1366*cdf0e10cSrcweir             }
1367*cdf0e10cSrcweir         }
1368*cdf0e10cSrcweir 
1369*cdf0e10cSrcweir         //Convert arguments
1370*cdf0e10cSrcweir         ptrArgs.reset(new CComVariant[dispparams.cArgs]);
1371*cdf0e10cSrcweir         ptrRefArgs.reset(new CComVariant[dispparams.cArgs]);
1372*cdf0e10cSrcweir         arArgs = ptrArgs.get();
1373*cdf0e10cSrcweir         arRefArgs = ptrRefArgs.get();
1374*cdf0e10cSrcweir 
1375*cdf0e10cSrcweir         sal_Int32 nInd = 0;
1376*cdf0e10cSrcweir         try
1377*cdf0e10cSrcweir         {
1378*cdf0e10cSrcweir             sal_Int32 revIndex = 0;
1379*cdf0e10cSrcweir             for ( nInd = 0; nInd < sal_Int32(dispparams.cArgs); nInd++)
1380*cdf0e10cSrcweir             {
1381*cdf0e10cSrcweir                 revIndex = dispparams.cArgs - nInd - 1;
1382*cdf0e10cSrcweir                 arRefArgs[revIndex].byref = 0;
1383*cdf0e10cSrcweir                 Any  anyArg;
1384*cdf0e10cSrcweir                 if ( nInd < aParams.getLength() )
1385*cdf0e10cSrcweir                     anyArg = aParams.getConstArray()[nInd];
1386*cdf0e10cSrcweir 
1387*cdf0e10cSrcweir                 // Property Put arguments
1388*cdf0e10cSrcweir                 if ( anyArg.getValueType() == getCppuType((PropertyPutArgument*)0) )
1389*cdf0e10cSrcweir                 {
1390*cdf0e10cSrcweir                     PropertyPutArgument arg;
1391*cdf0e10cSrcweir                     anyArg >>= arg;
1392*cdf0e10cSrcweir                     anyArg <<= arg.Value;
1393*cdf0e10cSrcweir                 }
1394*cdf0e10cSrcweir                 // named argument
1395*cdf0e10cSrcweir                 if (anyArg.getValueType() == getCppuType((NamedArgument*) 0))
1396*cdf0e10cSrcweir                 {
1397*cdf0e10cSrcweir                     NamedArgument aNamedArgument;
1398*cdf0e10cSrcweir                     anyArg >>= aNamedArgument;
1399*cdf0e10cSrcweir                     anyArg <<= aNamedArgument.Value;
1400*cdf0e10cSrcweir                 }
1401*cdf0e10cSrcweir 
1402*cdf0e10cSrcweir 				if ( nInd < aParams.getLength() && anyArg.getValueTypeClass() != TypeClass_VOID )
1403*cdf0e10cSrcweir 				{
1404*cdf0e10cSrcweir 					anyToVariant( &arArgs[revIndex], anyArg, VT_VARIANT );
1405*cdf0e10cSrcweir 				}
1406*cdf0e10cSrcweir 				else
1407*cdf0e10cSrcweir 				{
1408*cdf0e10cSrcweir 					arArgs[revIndex].vt = VT_ERROR;
1409*cdf0e10cSrcweir 					arArgs[revIndex].scode = DISP_E_PARAMNOTFOUND;
1410*cdf0e10cSrcweir 				}
1411*cdf0e10cSrcweir             }
1412*cdf0e10cSrcweir         }
1413*cdf0e10cSrcweir         catch (IllegalArgumentException & e)
1414*cdf0e10cSrcweir         {
1415*cdf0e10cSrcweir             e.ArgumentPosition = ::sal::static_int_cast< sal_Int16, sal_Int32 >( nInd );
1416*cdf0e10cSrcweir             throw;
1417*cdf0e10cSrcweir         }
1418*cdf0e10cSrcweir         catch (CannotConvertException & e)
1419*cdf0e10cSrcweir         {
1420*cdf0e10cSrcweir             e.ArgumentIndex = nInd;
1421*cdf0e10cSrcweir             throw;
1422*cdf0e10cSrcweir         }
1423*cdf0e10cSrcweir 
1424*cdf0e10cSrcweir         dispparams.rgvarg = arArgs;
1425*cdf0e10cSrcweir         // invoking OLE method
1426*cdf0e10cSrcweir         DWORD localeId = LOCALE_USER_DEFAULT;
1427*cdf0e10cSrcweir         hInvRes = m_spDispatch->Invoke( dispid,
1428*cdf0e10cSrcweir                                         IID_NULL,
1429*cdf0e10cSrcweir                                         localeId,
1430*cdf0e10cSrcweir                                         ::sal::static_int_cast< WORD, INVOKEKIND >( pInvkinds[nStep] ),
1431*cdf0e10cSrcweir                                         &dispparams,
1432*cdf0e10cSrcweir                                         &varResult,
1433*cdf0e10cSrcweir                                         &excepinfo,
1434*cdf0e10cSrcweir                                         &uArgErr);
1435*cdf0e10cSrcweir     }
1436*cdf0e10cSrcweir 
1437*cdf0e10cSrcweir 	// converting return value and out parameter back to UNO
1438*cdf0e10cSrcweir 	if ( SUCCEEDED( hInvRes ) )
1439*cdf0e10cSrcweir 		variantToAny( &varResult, aResult, sal_False );
1440*cdf0e10cSrcweir     else
1441*cdf0e10cSrcweir     {
1442*cdf0e10cSrcweir         // map error codes to exceptions
1443*cdf0e10cSrcweir         OUString message;
1444*cdf0e10cSrcweir         switch ( hInvRes )
1445*cdf0e10cSrcweir         {
1446*cdf0e10cSrcweir             case S_OK:
1447*cdf0e10cSrcweir                 break;
1448*cdf0e10cSrcweir             case DISP_E_BADPARAMCOUNT:
1449*cdf0e10cSrcweir                 throw IllegalArgumentException(OUSTR("[automation bridge] Wrong "
1450*cdf0e10cSrcweir                       "number of arguments. Object returned DISP_E_BADPARAMCOUNT."),
1451*cdf0e10cSrcweir                       0, 0);
1452*cdf0e10cSrcweir                 break;
1453*cdf0e10cSrcweir             case DISP_E_BADVARTYPE:
1454*cdf0e10cSrcweir                 throw RuntimeException(OUSTR("[automation bridge] One or more "
1455*cdf0e10cSrcweir                       "arguments have the wrong type. Object returned "
1456*cdf0e10cSrcweir                       "DISP_E_BADVARTYPE."), 0);
1457*cdf0e10cSrcweir                 break;
1458*cdf0e10cSrcweir             case DISP_E_EXCEPTION:
1459*cdf0e10cSrcweir                     message = OUSTR("[automation bridge]: ");
1460*cdf0e10cSrcweir                     message += OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription),
1461*cdf0e10cSrcweir                         ::SysStringLen(excepinfo.bstrDescription));
1462*cdf0e10cSrcweir                     throw InvocationTargetException(message, Reference<XInterface>(), Any());
1463*cdf0e10cSrcweir                     break;
1464*cdf0e10cSrcweir             case DISP_E_MEMBERNOTFOUND:
1465*cdf0e10cSrcweir                 message = OUSTR("[automation bridge]: A function with the name \"")
1466*cdf0e10cSrcweir                     + aName + OUSTR("\" is not supported. Object returned "
1467*cdf0e10cSrcweir                     "DISP_E_MEMBERNOTFOUND.");
1468*cdf0e10cSrcweir                 throw IllegalArgumentException(message, 0, 0);
1469*cdf0e10cSrcweir                 break;
1470*cdf0e10cSrcweir             case DISP_E_NONAMEDARGS:
1471*cdf0e10cSrcweir                 throw IllegalArgumentException(OUSTR("[automation bridge] Object "
1472*cdf0e10cSrcweir                       "returned DISP_E_NONAMEDARGS"),0, ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
1473*cdf0e10cSrcweir                 break;
1474*cdf0e10cSrcweir             case DISP_E_OVERFLOW:
1475*cdf0e10cSrcweir                 throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[automation bridge] Call failed.")),
1476*cdf0e10cSrcweir                                              static_cast<XInterface*>(
1477*cdf0e10cSrcweir                     static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::OUT_OF_RANGE, uArgErr);
1478*cdf0e10cSrcweir                 break;
1479*cdf0e10cSrcweir             case DISP_E_PARAMNOTFOUND:
1480*cdf0e10cSrcweir                 throw IllegalArgumentException(OUSTR("[automation bridge]Call failed."
1481*cdf0e10cSrcweir                                                      "Object returned DISP_E_PARAMNOTFOUND."),
1482*cdf0e10cSrcweir                                                0, ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
1483*cdf0e10cSrcweir                 break;
1484*cdf0e10cSrcweir             case DISP_E_TYPEMISMATCH:
1485*cdf0e10cSrcweir                 throw CannotConvertException(OUSTR("[automation bridge] Call  failed. "
1486*cdf0e10cSrcweir                                              "Object returned DISP_E_TYPEMISMATCH"),
1487*cdf0e10cSrcweir                     static_cast<XInterface*>(
1488*cdf0e10cSrcweir                     static_cast<XWeak*>(this)) , TypeClass_UNKNOWN, FailReason::UNKNOWN, uArgErr);
1489*cdf0e10cSrcweir                 break;
1490*cdf0e10cSrcweir             case DISP_E_UNKNOWNINTERFACE:
1491*cdf0e10cSrcweir                 throw RuntimeException(OUSTR("[automation bridge] Call failed. "
1492*cdf0e10cSrcweir                                            "Object returned DISP_E_UNKNOWNINTERFACE."),0);
1493*cdf0e10cSrcweir                 break;
1494*cdf0e10cSrcweir             case DISP_E_UNKNOWNLCID:
1495*cdf0e10cSrcweir                 throw RuntimeException(OUSTR("[automation bridge] Call failed. "
1496*cdf0e10cSrcweir                                            "Object returned DISP_E_UNKNOWNLCID."),0);
1497*cdf0e10cSrcweir                 break;
1498*cdf0e10cSrcweir             case DISP_E_PARAMNOTOPTIONAL:
1499*cdf0e10cSrcweir                 throw CannotConvertException(OUSTR("[automation bridge] Call failed."
1500*cdf0e10cSrcweir                       "Object returned DISP_E_PARAMNOTOPTIONAL"),
1501*cdf0e10cSrcweir                             static_cast<XInterface*>(static_cast<XWeak*>(this)),
1502*cdf0e10cSrcweir                                   TypeClass_UNKNOWN, FailReason::NO_DEFAULT_AVAILABLE, uArgErr);
1503*cdf0e10cSrcweir                 break;
1504*cdf0e10cSrcweir             default:
1505*cdf0e10cSrcweir                 throw RuntimeException();
1506*cdf0e10cSrcweir                 break;
1507*cdf0e10cSrcweir         }
1508*cdf0e10cSrcweir     }
1509*cdf0e10cSrcweir 
1510*cdf0e10cSrcweir 	return aResult;
1511*cdf0e10cSrcweir }
1512*cdf0e10cSrcweir 
1513*cdf0e10cSrcweir ::sal_Bool SAL_CALL IUnknownWrapper_Impl::hasMember( const ::rtl::OUString& aName )
1514*cdf0e10cSrcweir     throw (uno::RuntimeException)
1515*cdf0e10cSrcweir {
1516*cdf0e10cSrcweir     if ( ! m_spDispatch )
1517*cdf0e10cSrcweir     {
1518*cdf0e10cSrcweir         throw RuntimeException(
1519*cdf0e10cSrcweir             OUSTR("[automation bridge] The object does not have an IDispatch interface"),
1520*cdf0e10cSrcweir             Reference<XInterface>());
1521*cdf0e10cSrcweir     }
1522*cdf0e10cSrcweir 
1523*cdf0e10cSrcweir     o2u_attachCurrentThread();
1524*cdf0e10cSrcweir     DISPID dispid;
1525*cdf0e10cSrcweir     return getDispid( aName, &dispid );
1526*cdf0e10cSrcweir }
1527*cdf0e10cSrcweir 
1528*cdf0e10cSrcweir 
1529*cdf0e10cSrcweir // UnoConversionUtilities --------------------------------------------------------------------------------
1530*cdf0e10cSrcweir Reference< XInterface > IUnknownWrapper_Impl::createUnoWrapperInstance()
1531*cdf0e10cSrcweir {
1532*cdf0e10cSrcweir 	if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
1533*cdf0e10cSrcweir 	{
1534*cdf0e10cSrcweir 		Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
1535*cdf0e10cSrcweir 								m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
1536*cdf0e10cSrcweir 		return Reference<XInterface>( xWeak, UNO_QUERY);
1537*cdf0e10cSrcweir 	}
1538*cdf0e10cSrcweir 	else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
1539*cdf0e10cSrcweir 	{
1540*cdf0e10cSrcweir 		Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
1541*cdf0e10cSrcweir 								m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
1542*cdf0e10cSrcweir 		return Reference<XInterface>( xWeak, UNO_QUERY);
1543*cdf0e10cSrcweir 	}
1544*cdf0e10cSrcweir 	else
1545*cdf0e10cSrcweir 		return Reference<XInterface>();
1546*cdf0e10cSrcweir }
1547*cdf0e10cSrcweir Reference<XInterface> IUnknownWrapper_Impl::createComWrapperInstance()
1548*cdf0e10cSrcweir {
1549*cdf0e10cSrcweir 	Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
1550*cdf0e10cSrcweir 							m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
1551*cdf0e10cSrcweir 	return Reference<XInterface>( xWeak, UNO_QUERY);
1552*cdf0e10cSrcweir }
1553*cdf0e10cSrcweir 
1554*cdf0e10cSrcweir 
1555*cdf0e10cSrcweir 
1556*cdf0e10cSrcweir void IUnknownWrapper_Impl::getMethodInfo(const OUString& sName, TypeDescription& methodInfo)
1557*cdf0e10cSrcweir {
1558*cdf0e10cSrcweir 	TypeDescription desc= getInterfaceMemberDescOfCurrentCall(sName);
1559*cdf0e10cSrcweir 	if( desc.is())
1560*cdf0e10cSrcweir 	{
1561*cdf0e10cSrcweir 		typelib_TypeDescription* pMember= desc.get();
1562*cdf0e10cSrcweir 		if( pMember->eTypeClass == TypeClass_INTERFACE_METHOD )
1563*cdf0e10cSrcweir 			methodInfo= pMember;
1564*cdf0e10cSrcweir 	}
1565*cdf0e10cSrcweir }
1566*cdf0e10cSrcweir 
1567*cdf0e10cSrcweir void IUnknownWrapper_Impl::getAttributeInfo(const OUString& sName, TypeDescription& attributeInfo)
1568*cdf0e10cSrcweir {
1569*cdf0e10cSrcweir 	TypeDescription desc= getInterfaceMemberDescOfCurrentCall(sName);
1570*cdf0e10cSrcweir 	if( desc.is())
1571*cdf0e10cSrcweir 	{
1572*cdf0e10cSrcweir 		typelib_TypeDescription* pMember= desc.get();
1573*cdf0e10cSrcweir 		if( pMember->eTypeClass == TypeClass_INTERFACE_ATTRIBUTE )
1574*cdf0e10cSrcweir 		{
1575*cdf0e10cSrcweir 			attributeInfo= ((typelib_InterfaceAttributeTypeDescription*)pMember)->pAttributeTypeRef;
1576*cdf0e10cSrcweir 		}
1577*cdf0e10cSrcweir 	}
1578*cdf0e10cSrcweir }
1579*cdf0e10cSrcweir TypeDescription IUnknownWrapper_Impl::getInterfaceMemberDescOfCurrentCall(const OUString& sName)
1580*cdf0e10cSrcweir {
1581*cdf0e10cSrcweir 	TypeDescription ret;
1582*cdf0e10cSrcweir 
1583*cdf0e10cSrcweir 	for( sal_Int32 i=0; i < m_seqTypes.getLength(); i++)
1584*cdf0e10cSrcweir 	{
1585*cdf0e10cSrcweir 		TypeDescription _curDesc( m_seqTypes[i]);
1586*cdf0e10cSrcweir         _curDesc.makeComplete();
1587*cdf0e10cSrcweir 		typelib_InterfaceTypeDescription * pInterface= (typelib_InterfaceTypeDescription*) _curDesc.get();
1588*cdf0e10cSrcweir 		if( pInterface)
1589*cdf0e10cSrcweir 		{
1590*cdf0e10cSrcweir 			typelib_InterfaceMemberTypeDescription* pMember= NULL;
1591*cdf0e10cSrcweir 			//find the member description of the current call
1592*cdf0e10cSrcweir 			for( int i=0; i < pInterface->nAllMembers; i++)
1593*cdf0e10cSrcweir 			{
1594*cdf0e10cSrcweir 				typelib_TypeDescriptionReference* pTypeRefMember = pInterface->ppAllMembers[i];
1595*cdf0e10cSrcweir 				typelib_TypeDescription* pDescMember= NULL;
1596*cdf0e10cSrcweir 				TYPELIB_DANGER_GET( &pDescMember, pTypeRefMember)
1597*cdf0e10cSrcweir 
1598*cdf0e10cSrcweir 				typelib_InterfaceMemberTypeDescription* pInterfaceMember=
1599*cdf0e10cSrcweir 					(typelib_InterfaceMemberTypeDescription*) pDescMember;
1600*cdf0e10cSrcweir 				if( OUString( pInterfaceMember->pMemberName) == sName)
1601*cdf0e10cSrcweir 				{
1602*cdf0e10cSrcweir 					pMember= pInterfaceMember;
1603*cdf0e10cSrcweir 					break;
1604*cdf0e10cSrcweir 				}
1605*cdf0e10cSrcweir 				TYPELIB_DANGER_RELEASE( pDescMember)
1606*cdf0e10cSrcweir 			}
1607*cdf0e10cSrcweir 
1608*cdf0e10cSrcweir 			if( pMember)
1609*cdf0e10cSrcweir 			{
1610*cdf0e10cSrcweir 				ret= (typelib_TypeDescription*)pMember;
1611*cdf0e10cSrcweir 				TYPELIB_DANGER_RELEASE( (typelib_TypeDescription*)pMember);
1612*cdf0e10cSrcweir 			}
1613*cdf0e10cSrcweir 		}
1614*cdf0e10cSrcweir 		if( ret.is())
1615*cdf0e10cSrcweir 			break;
1616*cdf0e10cSrcweir 	}
1617*cdf0e10cSrcweir 	return ret;
1618*cdf0e10cSrcweir }
1619*cdf0e10cSrcweir 
1620*cdf0e10cSrcweir sal_Bool IUnknownWrapper_Impl::isJScriptObject()
1621*cdf0e10cSrcweir {
1622*cdf0e10cSrcweir 	if(  m_eJScript == JScriptUndefined)
1623*cdf0e10cSrcweir 	{
1624*cdf0e10cSrcweir 		CComDispatchDriver disp( m_spDispatch);
1625*cdf0e10cSrcweir 		if( disp)
1626*cdf0e10cSrcweir 		{
1627*cdf0e10cSrcweir 			CComVariant result;
1628*cdf0e10cSrcweir 			if( SUCCEEDED(	disp.GetPropertyByName( JSCRIPT_ID_PROPERTY, &result)))
1629*cdf0e10cSrcweir 			{
1630*cdf0e10cSrcweir 				if(result.vt == VT_BSTR)
1631*cdf0e10cSrcweir 				{
1632*cdf0e10cSrcweir 					CComBSTR name( result.bstrVal);
1633*cdf0e10cSrcweir 					name.ToLower();
1634*cdf0e10cSrcweir 					if( name == CComBSTR(JSCRIPT_ID))
1635*cdf0e10cSrcweir 						m_eJScript= IsJScript;
1636*cdf0e10cSrcweir 				}
1637*cdf0e10cSrcweir 			}
1638*cdf0e10cSrcweir 		}
1639*cdf0e10cSrcweir 		if( m_eJScript == JScriptUndefined)
1640*cdf0e10cSrcweir 			m_eJScript= NoJScript;
1641*cdf0e10cSrcweir 	}
1642*cdf0e10cSrcweir 
1643*cdf0e10cSrcweir 	return m_eJScript == NoJScript ? sal_False : sal_True;
1644*cdf0e10cSrcweir }
1645*cdf0e10cSrcweir 
1646*cdf0e10cSrcweir 
1647*cdf0e10cSrcweir 
1648*cdf0e10cSrcweir /** @internal
1649*cdf0e10cSrcweir     The function ultimately calls IDispatch::Invoke on the wrapped COM object.
1650*cdf0e10cSrcweir     The COM object does not implement UNO Interfaces ( via IDispatch). This
1651*cdf0e10cSrcweir     is the case when the OleObjectFactory service has been used to create a
1652*cdf0e10cSrcweir     component.
1653*cdf0e10cSrcweir     @exception IllegalArgumentException
1654*cdf0e10cSrcweir     @exception CannotConvertException
1655*cdf0e10cSrcweir     @InvocationTargetException
1656*cdf0e10cSrcweir     @RuntimeException
1657*cdf0e10cSrcweir     @BridgeRuntimeError
1658*cdf0e10cSrcweir */
1659*cdf0e10cSrcweir Any  IUnknownWrapper_Impl::invokeWithDispIdComTlb(const OUString& sFuncName,
1660*cdf0e10cSrcweir                                                   const Sequence< Any >& Params,
1661*cdf0e10cSrcweir                                                   Sequence< sal_Int16 >& OutParamIndex,
1662*cdf0e10cSrcweir                                                   Sequence< Any >& OutParam)
1663*cdf0e10cSrcweir {
1664*cdf0e10cSrcweir 	Any ret;
1665*cdf0e10cSrcweir 	HRESULT result;
1666*cdf0e10cSrcweir 
1667*cdf0e10cSrcweir 	DISPPARAMS 		dispparams = {NULL, NULL, 0, 0};
1668*cdf0e10cSrcweir 	CComVariant		varResult;
1669*cdf0e10cSrcweir 	ExcepInfo 		excepinfo;
1670*cdf0e10cSrcweir 	unsigned int 	uArgErr;
1671*cdf0e10cSrcweir 	sal_Int32       i = 0;
1672*cdf0e10cSrcweir     sal_Int32 nUnoArgs = Params.getLength();
1673*cdf0e10cSrcweir     DISPID idPropertyPut = DISPID_PROPERTYPUT;
1674*cdf0e10cSrcweir 	scoped_array<DISPID> arDispidNamedArgs;
1675*cdf0e10cSrcweir 	scoped_array<CComVariant> ptrArgs;
1676*cdf0e10cSrcweir 	scoped_array<CComVariant> ptrRefArgs; // referenced arguments
1677*cdf0e10cSrcweir     CComVariant * arArgs = NULL;
1678*cdf0e10cSrcweir     CComVariant * arRefArgs = NULL;
1679*cdf0e10cSrcweir     sal_Int32 revIndex = 0;
1680*cdf0e10cSrcweir     bool bVarargParam = false;
1681*cdf0e10cSrcweir 
1682*cdf0e10cSrcweir     // Get type info for the call. It can be a method call or property put or
1683*cdf0e10cSrcweir     // property get operation.
1684*cdf0e10cSrcweir     FuncDesc aFuncDesc(getTypeInfo());
1685*cdf0e10cSrcweir     getFuncDescForInvoke(sFuncName, Params, & aFuncDesc);
1686*cdf0e10cSrcweir 
1687*cdf0e10cSrcweir     //Set the array of DISPIDs for named args if it is a property put operation.
1688*cdf0e10cSrcweir     //If there are other named arguments another array is set later on.
1689*cdf0e10cSrcweir     if (aFuncDesc->invkind == INVOKE_PROPERTYPUT
1690*cdf0e10cSrcweir         || aFuncDesc->invkind == INVOKE_PROPERTYPUTREF)
1691*cdf0e10cSrcweir         dispparams.rgdispidNamedArgs = & idPropertyPut;
1692*cdf0e10cSrcweir 
1693*cdf0e10cSrcweir     //Determine the number of named arguments
1694*cdf0e10cSrcweir     for (int iParam = 0; iParam < nUnoArgs; iParam ++)
1695*cdf0e10cSrcweir     {
1696*cdf0e10cSrcweir         const Any & curArg = Params[iParam];
1697*cdf0e10cSrcweir         if (curArg.getValueType() == getCppuType((NamedArgument*) 0))
1698*cdf0e10cSrcweir             dispparams.cNamedArgs ++;
1699*cdf0e10cSrcweir     }
1700*cdf0e10cSrcweir     //In a property put operation a property value is a named argument (DISPID_PROPERTYPUT).
1701*cdf0e10cSrcweir     //Therefore the number of named arguments is increased by one.
1702*cdf0e10cSrcweir     //Although named, the argument is not named in a actual language, such as  Basic,
1703*cdf0e10cSrcweir     //therefore it is never a com.sun.star.bridge.oleautomation.NamedArgument
1704*cdf0e10cSrcweir     if (aFuncDesc->invkind == DISPATCH_PROPERTYPUT
1705*cdf0e10cSrcweir         || aFuncDesc->invkind == DISPATCH_PROPERTYPUTREF)
1706*cdf0e10cSrcweir         dispparams.cNamedArgs ++;
1707*cdf0e10cSrcweir 
1708*cdf0e10cSrcweir     //Determine the number of all arguments and named arguments
1709*cdf0e10cSrcweir     if (aFuncDesc->cParamsOpt == -1)
1710*cdf0e10cSrcweir     {
1711*cdf0e10cSrcweir         //Attribute vararg is set on this method. "Unlimited" number of args
1712*cdf0e10cSrcweir         //supported. There can be no optional or defaultvalue on any of the arguments.
1713*cdf0e10cSrcweir         dispparams.cArgs = nUnoArgs;
1714*cdf0e10cSrcweir     }
1715*cdf0e10cSrcweir     else
1716*cdf0e10cSrcweir     {
1717*cdf0e10cSrcweir         //If there are namesd arguments, then the dispparams.cArgs
1718*cdf0e10cSrcweir         //is the number of supplied args, otherwise it is the expected number.
1719*cdf0e10cSrcweir         if (dispparams.cNamedArgs)
1720*cdf0e10cSrcweir             dispparams.cArgs = nUnoArgs;
1721*cdf0e10cSrcweir         else
1722*cdf0e10cSrcweir             dispparams.cArgs = aFuncDesc->cParams;
1723*cdf0e10cSrcweir     }
1724*cdf0e10cSrcweir 
1725*cdf0e10cSrcweir 	//check if there are not to many arguments supplied
1726*cdf0e10cSrcweir     if (::sal::static_int_cast< sal_uInt32, int >( nUnoArgs ) > dispparams.cArgs)
1727*cdf0e10cSrcweir 	{
1728*cdf0e10cSrcweir 	    OUStringBuffer buf(256);
1729*cdf0e10cSrcweir         buf.appendAscii("[automation bridge] There are too many arguments for this method");
1730*cdf0e10cSrcweir 	    throw IllegalArgumentException( buf.makeStringAndClear(),
1731*cdf0e10cSrcweir 			Reference<XInterface>(), (sal_Int16) dispparams.cArgs);
1732*cdf0e10cSrcweir 	}
1733*cdf0e10cSrcweir 
1734*cdf0e10cSrcweir     //Set up the array of DISPIDs (DISPPARAMS::rgdispidNamedArgs)
1735*cdf0e10cSrcweir     //for the named arguments.
1736*cdf0e10cSrcweir     //If there is only one named arg and if it is because of a property put
1737*cdf0e10cSrcweir     //operation, then we need not set up the DISPID array.
1738*cdf0e10cSrcweir     if (dispparams.cNamedArgs > 0 &&
1739*cdf0e10cSrcweir         ! (dispparams.cNamedArgs == 1 &&
1740*cdf0e10cSrcweir            (aFuncDesc->invkind == INVOKE_PROPERTYPUT ||
1741*cdf0e10cSrcweir             aFuncDesc->invkind == INVOKE_PROPERTYPUT)))
1742*cdf0e10cSrcweir     {
1743*cdf0e10cSrcweir         //set up an array containing the member and parameter names
1744*cdf0e10cSrcweir         //which is then used in ITypeInfo::GetIDsOfNames
1745*cdf0e10cSrcweir         //First determine the size of the array of names which is passed to
1746*cdf0e10cSrcweir         //ITypeInfo::GetIDsOfNames. It must hold the method names + the named
1747*cdf0e10cSrcweir         //args.
1748*cdf0e10cSrcweir         int nSizeAr = dispparams.cNamedArgs + 1;
1749*cdf0e10cSrcweir         if (aFuncDesc->invkind == INVOKE_PROPERTYPUT
1750*cdf0e10cSrcweir             || aFuncDesc->invkind == INVOKE_PROPERTYPUTREF)
1751*cdf0e10cSrcweir         {
1752*cdf0e10cSrcweir             nSizeAr = dispparams.cNamedArgs; //counts the DISID_PROPERTYPUT
1753*cdf0e10cSrcweir         }
1754*cdf0e10cSrcweir 
1755*cdf0e10cSrcweir         scoped_array<OLECHAR*> saNames(new OLECHAR*[nSizeAr]);
1756*cdf0e10cSrcweir         OLECHAR ** arNames = saNames.get();
1757*cdf0e10cSrcweir         arNames[0] = const_cast<OLECHAR*>(reinterpret_cast<LPCOLESTR>(sFuncName.getStr()));
1758*cdf0e10cSrcweir 
1759*cdf0e10cSrcweir         int cNamedArg = 0;
1760*cdf0e10cSrcweir         for (size_t iParams = 0; iParams < dispparams.cArgs; iParams ++)
1761*cdf0e10cSrcweir         {
1762*cdf0e10cSrcweir             const Any &  curArg = Params[iParams];
1763*cdf0e10cSrcweir             if (curArg.getValueType() == getCppuType((NamedArgument*) 0))
1764*cdf0e10cSrcweir             {
1765*cdf0e10cSrcweir                 const NamedArgument& arg = *(NamedArgument const*) curArg.getValue();
1766*cdf0e10cSrcweir 				//We put the parameter names in reverse order into the array,
1767*cdf0e10cSrcweir 				//so we can use the DISPID array for DISPPARAMS::rgdispidNamedArgs
1768*cdf0e10cSrcweir                 //The first name in the array is the method name
1769*cdf0e10cSrcweir                 arNames[nSizeAr - 1 - cNamedArg++] = const_cast<OLECHAR*>(reinterpret_cast<LPCOLESTR>(arg.Name.getStr()));
1770*cdf0e10cSrcweir             }
1771*cdf0e10cSrcweir         }
1772*cdf0e10cSrcweir 
1773*cdf0e10cSrcweir         //Prepare the array of DISPIDs for ITypeInfo::GetIDsOfNames
1774*cdf0e10cSrcweir         //it must be big enough to contain the DISPIDs of the member + parameters
1775*cdf0e10cSrcweir         arDispidNamedArgs.reset(new DISPID[nSizeAr]);
1776*cdf0e10cSrcweir         HRESULT hr = getTypeInfo()->GetIDsOfNames(arNames, nSizeAr,
1777*cdf0e10cSrcweir                                                   arDispidNamedArgs.get());
1778*cdf0e10cSrcweir         if ( hr == E_NOTIMPL )
1779*cdf0e10cSrcweir             hr = m_spDispatch->GetIDsOfNames(IID_NULL, arNames, nSizeAr, LOCALE_USER_DEFAULT, arDispidNamedArgs.get() );
1780*cdf0e10cSrcweir 
1781*cdf0e10cSrcweir 		if (hr == S_OK)
1782*cdf0e10cSrcweir         {
1783*cdf0e10cSrcweir             // In a "property put" operation, the property value is a named param with the
1784*cdf0e10cSrcweir             //special DISPID DISPID_PROPERTYPUT
1785*cdf0e10cSrcweir             if (aFuncDesc->invkind == DISPATCH_PROPERTYPUT
1786*cdf0e10cSrcweir                 || aFuncDesc->invkind == DISPATCH_PROPERTYPUTREF)
1787*cdf0e10cSrcweir             {
1788*cdf0e10cSrcweir                 //Element at index 0 in the DISPID array must be DISPID_PROPERTYPUT
1789*cdf0e10cSrcweir                 //The first item in the array arDispidNamedArgs is the DISPID for
1790*cdf0e10cSrcweir                 //the method. We replace it with DISPID_PROPERTYPUT.
1791*cdf0e10cSrcweir                 DISPID*  arIDs = arDispidNamedArgs.get();
1792*cdf0e10cSrcweir                 arIDs[0] = DISPID_PROPERTYPUT;
1793*cdf0e10cSrcweir                 dispparams.rgdispidNamedArgs = arIDs;
1794*cdf0e10cSrcweir             }
1795*cdf0e10cSrcweir             else
1796*cdf0e10cSrcweir             {
1797*cdf0e10cSrcweir                 //The first item in the array arDispidNamedArgs is the DISPID for
1798*cdf0e10cSrcweir                 //the method. It must be removed
1799*cdf0e10cSrcweir                 DISPID*  arIDs = arDispidNamedArgs.get();
1800*cdf0e10cSrcweir                 dispparams.rgdispidNamedArgs = & arIDs[1];
1801*cdf0e10cSrcweir             }
1802*cdf0e10cSrcweir         }
1803*cdf0e10cSrcweir         else if (hr == DISP_E_UNKNOWNNAME)
1804*cdf0e10cSrcweir         {
1805*cdf0e10cSrcweir              throw IllegalArgumentException(
1806*cdf0e10cSrcweir                  OUSTR("[automation bridge]One of the named arguments is wrong!"),
1807*cdf0e10cSrcweir                  Reference<XInterface>(), 0);
1808*cdf0e10cSrcweir         }
1809*cdf0e10cSrcweir         else
1810*cdf0e10cSrcweir         {
1811*cdf0e10cSrcweir             throw InvocationTargetException(
1812*cdf0e10cSrcweir                 OUSTR("[automation bridge] ITypeInfo::GetIDsOfNames returned error ")
1813*cdf0e10cSrcweir                 + OUString::valueOf((sal_Int32) hr, 16), Reference<XInterface>(), Any());
1814*cdf0e10cSrcweir         }
1815*cdf0e10cSrcweir     }
1816*cdf0e10cSrcweir 
1817*cdf0e10cSrcweir     //Convert arguments
1818*cdf0e10cSrcweir     ptrArgs.reset(new CComVariant[dispparams.cArgs]);
1819*cdf0e10cSrcweir     ptrRefArgs.reset(new CComVariant[dispparams.cArgs]);
1820*cdf0e10cSrcweir     arArgs = ptrArgs.get();
1821*cdf0e10cSrcweir     arRefArgs = ptrRefArgs.get();
1822*cdf0e10cSrcweir 	try
1823*cdf0e10cSrcweir 	{
1824*cdf0e10cSrcweir 		for (i = 0; i < (sal_Int32) dispparams.cArgs; i++)
1825*cdf0e10cSrcweir 		{
1826*cdf0e10cSrcweir 			revIndex= dispparams.cArgs - i -1;
1827*cdf0e10cSrcweir 			arRefArgs[revIndex].byref=0;
1828*cdf0e10cSrcweir 			Any  anyArg;
1829*cdf0e10cSrcweir 			if ( i < nUnoArgs)
1830*cdf0e10cSrcweir 				anyArg= Params.getConstArray()[i];
1831*cdf0e10cSrcweir 
1832*cdf0e10cSrcweir 			//Test if the current parameter is a "vararg" parameter.
1833*cdf0e10cSrcweir 			if (bVarargParam || (aFuncDesc->cParamsOpt == -1 &&
1834*cdf0e10cSrcweir 								aFuncDesc->cParams == (i + 1)))
1835*cdf0e10cSrcweir 			{   //This parameter is from the variable argument list. There is no
1836*cdf0e10cSrcweir 				//type info available, except that it must be a VARIANT
1837*cdf0e10cSrcweir 				bVarargParam = true;
1838*cdf0e10cSrcweir 			}
1839*cdf0e10cSrcweir 
1840*cdf0e10cSrcweir 			unsigned short paramFlags = PARAMFLAG_FOPT | PARAMFLAG_FIN;
1841*cdf0e10cSrcweir 			VARTYPE varType = VT_VARIANT;
1842*cdf0e10cSrcweir 			if ( ! bVarargParam)
1843*cdf0e10cSrcweir 			{
1844*cdf0e10cSrcweir 				paramFlags =
1845*cdf0e10cSrcweir 					aFuncDesc->lprgelemdescParam[i].paramdesc.wParamFlags;
1846*cdf0e10cSrcweir 				varType = getElementTypeDesc(
1847*cdf0e10cSrcweir 					& aFuncDesc->lprgelemdescParam[i].tdesc);
1848*cdf0e10cSrcweir 			}
1849*cdf0e10cSrcweir 			//Make sure that there is a UNO parameter for every
1850*cdf0e10cSrcweir 			// expected parameter. If there is no UNO parameter where the
1851*cdf0e10cSrcweir 			// called function expects one, then it must be optional. Otherwise
1852*cdf0e10cSrcweir 			// its a UNO programming error.
1853*cdf0e10cSrcweir 			if (i  >= nUnoArgs && !(paramFlags & PARAMFLAG_FOPT))
1854*cdf0e10cSrcweir 			{
1855*cdf0e10cSrcweir 				OUStringBuffer buf(256);
1856*cdf0e10cSrcweir 				buf.appendAscii("ole automation bridge: The called function expects an argument at"
1857*cdf0e10cSrcweir 								"position: "); //a different number of arguments")),
1858*cdf0e10cSrcweir 				buf.append(OUString::valueOf((sal_Int32) i));
1859*cdf0e10cSrcweir 				buf.appendAscii(" (index starting at 0).");
1860*cdf0e10cSrcweir 				throw IllegalArgumentException( buf.makeStringAndClear(),
1861*cdf0e10cSrcweir 												Reference<XInterface>(), (sal_Int16) i);
1862*cdf0e10cSrcweir 			}
1863*cdf0e10cSrcweir 
1864*cdf0e10cSrcweir 			// Property Put arguments
1865*cdf0e10cSrcweir 			if (anyArg.getValueType() == getCppuType((PropertyPutArgument*)0))
1866*cdf0e10cSrcweir 			{
1867*cdf0e10cSrcweir 				PropertyPutArgument arg;
1868*cdf0e10cSrcweir 				anyArg >>= arg;
1869*cdf0e10cSrcweir 				anyArg <<= arg.Value;
1870*cdf0e10cSrcweir 			}
1871*cdf0e10cSrcweir 			// named argument
1872*cdf0e10cSrcweir 			if (anyArg.getValueType() == getCppuType((NamedArgument*) 0))
1873*cdf0e10cSrcweir 			{
1874*cdf0e10cSrcweir 				NamedArgument aNamedArgument;
1875*cdf0e10cSrcweir 				anyArg >>= aNamedArgument;
1876*cdf0e10cSrcweir 				anyArg <<= aNamedArgument.Value;
1877*cdf0e10cSrcweir 			}
1878*cdf0e10cSrcweir 			// out param
1879*cdf0e10cSrcweir 			if (paramFlags & PARAMFLAG_FOUT &&
1880*cdf0e10cSrcweir 				! (paramFlags & PARAMFLAG_FIN)  )
1881*cdf0e10cSrcweir 			{
1882*cdf0e10cSrcweir                 VARTYPE type = ::sal::static_int_cast< VARTYPE, int >( varType ^ VT_BYREF );
1883*cdf0e10cSrcweir 				if (i < nUnoArgs)
1884*cdf0e10cSrcweir 				{
1885*cdf0e10cSrcweir 					arRefArgs[revIndex].vt= type;
1886*cdf0e10cSrcweir 				}
1887*cdf0e10cSrcweir 				else
1888*cdf0e10cSrcweir 				{
1889*cdf0e10cSrcweir 					//optional arg
1890*cdf0e10cSrcweir 					arRefArgs[revIndex].vt = VT_ERROR;
1891*cdf0e10cSrcweir 					arRefArgs[revIndex].scode = DISP_E_PARAMNOTFOUND;
1892*cdf0e10cSrcweir 				}
1893*cdf0e10cSrcweir 				if( type == VT_VARIANT )
1894*cdf0e10cSrcweir 				{
1895*cdf0e10cSrcweir 					arArgs[revIndex].vt= VT_VARIANT | VT_BYREF;
1896*cdf0e10cSrcweir 					arArgs[revIndex].byref= &arRefArgs[revIndex];
1897*cdf0e10cSrcweir 				}
1898*cdf0e10cSrcweir 				else
1899*cdf0e10cSrcweir 				{
1900*cdf0e10cSrcweir 					arArgs[revIndex].vt= varType;
1901*cdf0e10cSrcweir 					if (type == VT_DECIMAL)
1902*cdf0e10cSrcweir 						arArgs[revIndex].byref= & arRefArgs[revIndex].decVal;
1903*cdf0e10cSrcweir 					else
1904*cdf0e10cSrcweir 						arArgs[revIndex].byref= & arRefArgs[revIndex].byref;
1905*cdf0e10cSrcweir 				}
1906*cdf0e10cSrcweir 			}
1907*cdf0e10cSrcweir 			// in/out  + in byref params
1908*cdf0e10cSrcweir 			else if (varType & VT_BYREF)
1909*cdf0e10cSrcweir 			{
1910*cdf0e10cSrcweir                 VARTYPE type = ::sal::static_int_cast< VARTYPE, int >( varType ^ VT_BYREF );
1911*cdf0e10cSrcweir 				CComVariant var;
1912*cdf0e10cSrcweir 
1913*cdf0e10cSrcweir 				if (i < nUnoArgs && anyArg.getValueTypeClass() != TypeClass_VOID)
1914*cdf0e10cSrcweir 				{
1915*cdf0e10cSrcweir 					anyToVariant( & arRefArgs[revIndex], anyArg, type);
1916*cdf0e10cSrcweir 				}
1917*cdf0e10cSrcweir 				else if (paramFlags & PARAMFLAG_FHASDEFAULT)
1918*cdf0e10cSrcweir 				{
1919*cdf0e10cSrcweir 					//optional arg with default
1920*cdf0e10cSrcweir 					VariantCopy( & arRefArgs[revIndex],
1921*cdf0e10cSrcweir 								& aFuncDesc->lprgelemdescParam[i].paramdesc.
1922*cdf0e10cSrcweir 								pparamdescex->varDefaultValue);
1923*cdf0e10cSrcweir 				}
1924*cdf0e10cSrcweir 				else
1925*cdf0e10cSrcweir 				{
1926*cdf0e10cSrcweir 					//optional arg
1927*cdf0e10cSrcweir 					//e.g: call func(x) in basic : func() ' no arg supplied
1928*cdf0e10cSrcweir 					OSL_ASSERT(paramFlags & PARAMFLAG_FOPT);
1929*cdf0e10cSrcweir 					arRefArgs[revIndex].vt = VT_ERROR;
1930*cdf0e10cSrcweir 					arRefArgs[revIndex].scode = DISP_E_PARAMNOTFOUND;
1931*cdf0e10cSrcweir 				}
1932*cdf0e10cSrcweir 
1933*cdf0e10cSrcweir 				// Set the converted arguments in the array which will be
1934*cdf0e10cSrcweir 				// DISPPARAMS::rgvarg
1935*cdf0e10cSrcweir 				// byref arg VT_XXX |VT_BYREF
1936*cdf0e10cSrcweir 				arArgs[revIndex].vt = varType;
1937*cdf0e10cSrcweir 				if (revIndex == 0 && aFuncDesc->invkind == INVOKE_PROPERTYPUT)
1938*cdf0e10cSrcweir 				{
1939*cdf0e10cSrcweir 					arArgs[revIndex] = arRefArgs[revIndex];
1940*cdf0e10cSrcweir 				}
1941*cdf0e10cSrcweir 				else if (type == VT_DECIMAL)
1942*cdf0e10cSrcweir 				{
1943*cdf0e10cSrcweir 					arArgs[revIndex].byref= & arRefArgs[revIndex].decVal;
1944*cdf0e10cSrcweir 				}
1945*cdf0e10cSrcweir 				else if (type == VT_VARIANT)
1946*cdf0e10cSrcweir 				{
1947*cdf0e10cSrcweir 					if ( ! (paramFlags & PARAMFLAG_FOUT))
1948*cdf0e10cSrcweir 						arArgs[revIndex] = arRefArgs[revIndex];
1949*cdf0e10cSrcweir 					else
1950*cdf0e10cSrcweir 						arArgs[revIndex].byref = & arRefArgs[revIndex];
1951*cdf0e10cSrcweir 				}
1952*cdf0e10cSrcweir 				else
1953*cdf0e10cSrcweir 				{
1954*cdf0e10cSrcweir 					arArgs[revIndex].byref = & arRefArgs[revIndex].byref;
1955*cdf0e10cSrcweir                     arArgs[revIndex].vt = ::sal::static_int_cast< VARTYPE, int >( arRefArgs[revIndex].vt | VT_BYREF );
1956*cdf0e10cSrcweir 				}
1957*cdf0e10cSrcweir 
1958*cdf0e10cSrcweir 			}
1959*cdf0e10cSrcweir 			// in parameter no VT_BYREF except for array, interfaces
1960*cdf0e10cSrcweir 			else
1961*cdf0e10cSrcweir 			{	// void any stands for optional param
1962*cdf0e10cSrcweir 				if (i < nUnoArgs && anyArg.getValueTypeClass() != TypeClass_VOID)
1963*cdf0e10cSrcweir 				{
1964*cdf0e10cSrcweir 					anyToVariant( & arArgs[revIndex], anyArg, varType);
1965*cdf0e10cSrcweir 				}
1966*cdf0e10cSrcweir 				//optional arg but no void any supplied
1967*cdf0e10cSrcweir 				//Basic:  obj.func() ' first parameter left out because it is optional
1968*cdf0e10cSrcweir 				else if (paramFlags & PARAMFLAG_FHASDEFAULT)
1969*cdf0e10cSrcweir 				{
1970*cdf0e10cSrcweir 					//optional arg with defaulteithter as direct arg : VT_XXX or
1971*cdf0e10cSrcweir 					VariantCopy( & arArgs[revIndex],
1972*cdf0e10cSrcweir 						& aFuncDesc->lprgelemdescParam[i].paramdesc.
1973*cdf0e10cSrcweir 							pparamdescex->varDefaultValue);
1974*cdf0e10cSrcweir 				}
1975*cdf0e10cSrcweir 				else if (paramFlags & PARAMFLAG_FOPT)
1976*cdf0e10cSrcweir 				{
1977*cdf0e10cSrcweir 					arArgs[revIndex].vt = VT_ERROR;
1978*cdf0e10cSrcweir 					arArgs[revIndex].scode = DISP_E_PARAMNOTFOUND;
1979*cdf0e10cSrcweir 				}
1980*cdf0e10cSrcweir                 else
1981*cdf0e10cSrcweir                 {
1982*cdf0e10cSrcweir                     arArgs[revIndex].vt = VT_EMPTY;
1983*cdf0e10cSrcweir                     arArgs[revIndex].lVal = 0;
1984*cdf0e10cSrcweir                 }
1985*cdf0e10cSrcweir 			}
1986*cdf0e10cSrcweir 		}
1987*cdf0e10cSrcweir 	}
1988*cdf0e10cSrcweir     catch (IllegalArgumentException & e)
1989*cdf0e10cSrcweir 	{
1990*cdf0e10cSrcweir 		e.ArgumentPosition = ::sal::static_int_cast< sal_Int16, sal_Int32 >( i );
1991*cdf0e10cSrcweir 		throw;
1992*cdf0e10cSrcweir 	}
1993*cdf0e10cSrcweir 	catch (CannotConvertException & e)
1994*cdf0e10cSrcweir 	{
1995*cdf0e10cSrcweir 		e.ArgumentIndex = i;
1996*cdf0e10cSrcweir 		throw;
1997*cdf0e10cSrcweir 	}
1998*cdf0e10cSrcweir 	dispparams.rgvarg= arArgs;
1999*cdf0e10cSrcweir 	// invoking OLE method
2000*cdf0e10cSrcweir     DWORD localeId = LOCALE_USER_DEFAULT;
2001*cdf0e10cSrcweir 	result = m_spDispatch->Invoke(aFuncDesc->memid,
2002*cdf0e10cSrcweir 								 IID_NULL,
2003*cdf0e10cSrcweir 								 localeId,
2004*cdf0e10cSrcweir 								 ::sal::static_int_cast< WORD, INVOKEKIND >( aFuncDesc->invkind ),
2005*cdf0e10cSrcweir 								 &dispparams,
2006*cdf0e10cSrcweir 								 &varResult,
2007*cdf0e10cSrcweir 								 &excepinfo,
2008*cdf0e10cSrcweir 								 &uArgErr);
2009*cdf0e10cSrcweir 
2010*cdf0e10cSrcweir 	// converting return value and out parameter back to UNO
2011*cdf0e10cSrcweir 	if (result == S_OK)
2012*cdf0e10cSrcweir 	{
2013*cdf0e10cSrcweir 
2014*cdf0e10cSrcweir         // allocate space for the out param Sequence and indices Sequence
2015*cdf0e10cSrcweir         int outParamsCount= 0; // includes in/out parameter
2016*cdf0e10cSrcweir         for (int i = 0; i < aFuncDesc->cParams; i++)
2017*cdf0e10cSrcweir         {
2018*cdf0e10cSrcweir             if (aFuncDesc->lprgelemdescParam[i].paramdesc.wParamFlags &
2019*cdf0e10cSrcweir                 PARAMFLAG_FOUT)
2020*cdf0e10cSrcweir                 outParamsCount++;
2021*cdf0e10cSrcweir         }
2022*cdf0e10cSrcweir 
2023*cdf0e10cSrcweir         OutParamIndex.realloc(outParamsCount);
2024*cdf0e10cSrcweir         OutParam.realloc(outParamsCount);
2025*cdf0e10cSrcweir         // Convert out params
2026*cdf0e10cSrcweir         if (outParamsCount)
2027*cdf0e10cSrcweir         {
2028*cdf0e10cSrcweir             int outParamIndex=0;
2029*cdf0e10cSrcweir             for (int paramIndex = 0; paramIndex < nUnoArgs; paramIndex ++)
2030*cdf0e10cSrcweir             {
2031*cdf0e10cSrcweir                 //Determine the index within the method sinature
2032*cdf0e10cSrcweir                 int realParamIndex = paramIndex;
2033*cdf0e10cSrcweir                 int revParamIndex = dispparams.cArgs - paramIndex - 1;
2034*cdf0e10cSrcweir                 if (Params[paramIndex].getValueType()
2035*cdf0e10cSrcweir                     == getCppuType((NamedArgument*) 0))
2036*cdf0e10cSrcweir                 {
2037*cdf0e10cSrcweir                     //dispparams.rgdispidNamedArgs contains the mapping from index
2038*cdf0e10cSrcweir                     //of named args list to index of parameter list
2039*cdf0e10cSrcweir                     realParamIndex = dispparams.rgdispidNamedArgs[revParamIndex];
2040*cdf0e10cSrcweir                 }
2041*cdf0e10cSrcweir 
2042*cdf0e10cSrcweir                 // no named arg, always come before named args
2043*cdf0e10cSrcweir                 if (! (aFuncDesc->lprgelemdescParam[realParamIndex].paramdesc.wParamFlags
2044*cdf0e10cSrcweir                        & PARAMFLAG_FOUT))
2045*cdf0e10cSrcweir                     continue;
2046*cdf0e10cSrcweir                 Any outAny;
2047*cdf0e10cSrcweir                 // variantToAny is called with the "reduce range" parameter set to sal_False.
2048*cdf0e10cSrcweir                 // That causes VT_I4 values not to be converted down to a "lower" type. That
2049*cdf0e10cSrcweir                 // feature exist for JScript only because it only uses VT_I4 for integer types.
2050*cdf0e10cSrcweir 				try
2051*cdf0e10cSrcweir 				{
2052*cdf0e10cSrcweir 					variantToAny( & arRefArgs[revParamIndex], outAny, sal_False );
2053*cdf0e10cSrcweir 				}
2054*cdf0e10cSrcweir 				catch (IllegalArgumentException & e)
2055*cdf0e10cSrcweir 				{
2056*cdf0e10cSrcweir 					e.ArgumentPosition = (sal_Int16)paramIndex;
2057*cdf0e10cSrcweir 					throw;
2058*cdf0e10cSrcweir 				}
2059*cdf0e10cSrcweir 				catch (CannotConvertException & e)
2060*cdf0e10cSrcweir 				{
2061*cdf0e10cSrcweir 					e.ArgumentIndex = paramIndex;
2062*cdf0e10cSrcweir 					throw;
2063*cdf0e10cSrcweir 				}
2064*cdf0e10cSrcweir                 OutParam[outParamIndex] = outAny;
2065*cdf0e10cSrcweir                 OutParamIndex[outParamIndex] = ::sal::static_int_cast< sal_Int16, int >( paramIndex );
2066*cdf0e10cSrcweir                 outParamIndex++;
2067*cdf0e10cSrcweir             }
2068*cdf0e10cSrcweir             OutParam.realloc(outParamIndex);
2069*cdf0e10cSrcweir             OutParamIndex.realloc(outParamIndex);
2070*cdf0e10cSrcweir         }
2071*cdf0e10cSrcweir         // Return value
2072*cdf0e10cSrcweir 		variantToAny(&varResult, ret, sal_False);
2073*cdf0e10cSrcweir 	}
2074*cdf0e10cSrcweir 
2075*cdf0e10cSrcweir 	// map error codes to exceptions
2076*cdf0e10cSrcweir 	OUString message;
2077*cdf0e10cSrcweir 	switch (result)
2078*cdf0e10cSrcweir 	{
2079*cdf0e10cSrcweir 		case S_OK:
2080*cdf0e10cSrcweir 			break;
2081*cdf0e10cSrcweir 		case DISP_E_BADPARAMCOUNT:
2082*cdf0e10cSrcweir 			throw IllegalArgumentException(OUSTR("[automation bridge] Wrong "
2083*cdf0e10cSrcweir                   "number of arguments. Object returned DISP_E_BADPARAMCOUNT."),
2084*cdf0e10cSrcweir                   0, 0);
2085*cdf0e10cSrcweir 			break;
2086*cdf0e10cSrcweir 		case DISP_E_BADVARTYPE:
2087*cdf0e10cSrcweir 			throw RuntimeException(OUSTR("[automation bridge] One or more "
2088*cdf0e10cSrcweir                   "arguments have the wrong type. Object returned "
2089*cdf0e10cSrcweir                   "DISP_E_BADVARTYPE."), 0);
2090*cdf0e10cSrcweir 			break;
2091*cdf0e10cSrcweir 		case DISP_E_EXCEPTION:
2092*cdf0e10cSrcweir 				message = OUSTR("[automation bridge]: ");
2093*cdf0e10cSrcweir 				message += OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription),
2094*cdf0e10cSrcweir 					::SysStringLen(excepinfo.bstrDescription));
2095*cdf0e10cSrcweir 				throw InvocationTargetException(message, Reference<XInterface>(), Any());
2096*cdf0e10cSrcweir 				break;
2097*cdf0e10cSrcweir 		case DISP_E_MEMBERNOTFOUND:
2098*cdf0e10cSrcweir             message = OUSTR("[automation bridge]: A function with the name \"")
2099*cdf0e10cSrcweir                 + sFuncName + OUSTR("\" is not supported. Object returned "
2100*cdf0e10cSrcweir                 "DISP_E_MEMBERNOTFOUND.");
2101*cdf0e10cSrcweir 			throw IllegalArgumentException(message, 0, 0);
2102*cdf0e10cSrcweir 			break;
2103*cdf0e10cSrcweir 		case DISP_E_NONAMEDARGS:
2104*cdf0e10cSrcweir 			throw IllegalArgumentException(OUSTR("[automation bridge] Object "
2105*cdf0e10cSrcweir                   "returned DISP_E_NONAMEDARGS"),0, ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
2106*cdf0e10cSrcweir 			break;
2107*cdf0e10cSrcweir 		case DISP_E_OVERFLOW:
2108*cdf0e10cSrcweir 			throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[automation bridge] Call failed.")),
2109*cdf0e10cSrcweir                                          static_cast<XInterface*>(
2110*cdf0e10cSrcweir 				static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::OUT_OF_RANGE, uArgErr);
2111*cdf0e10cSrcweir 			break;
2112*cdf0e10cSrcweir 		case DISP_E_PARAMNOTFOUND:
2113*cdf0e10cSrcweir 			throw IllegalArgumentException(OUSTR("[automation bridge]Call failed."
2114*cdf0e10cSrcweir                                                  "Object returned DISP_E_PARAMNOTFOUND."),
2115*cdf0e10cSrcweir                                            0, ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
2116*cdf0e10cSrcweir 			break;
2117*cdf0e10cSrcweir 		case DISP_E_TYPEMISMATCH:
2118*cdf0e10cSrcweir 			throw CannotConvertException(OUSTR("[automation bridge] Call  failed. "
2119*cdf0e10cSrcweir                                          "Object returned DISP_E_TYPEMISMATCH"),
2120*cdf0e10cSrcweir 				static_cast<XInterface*>(
2121*cdf0e10cSrcweir 				static_cast<XWeak*>(this)) , TypeClass_UNKNOWN, FailReason::UNKNOWN, uArgErr);
2122*cdf0e10cSrcweir 			break;
2123*cdf0e10cSrcweir 		case DISP_E_UNKNOWNINTERFACE:
2124*cdf0e10cSrcweir 			throw RuntimeException(OUSTR("[automation bridge] Call failed. "
2125*cdf0e10cSrcweir                                        "Object returned DISP_E_UNKNOWNINTERFACE."),0);
2126*cdf0e10cSrcweir 			break;
2127*cdf0e10cSrcweir 		case DISP_E_UNKNOWNLCID:
2128*cdf0e10cSrcweir 			throw RuntimeException(OUSTR("[automation bridge] Call failed. "
2129*cdf0e10cSrcweir                                        "Object returned DISP_E_UNKNOWNLCID."),0);
2130*cdf0e10cSrcweir 			break;
2131*cdf0e10cSrcweir 		case DISP_E_PARAMNOTOPTIONAL:
2132*cdf0e10cSrcweir 			throw CannotConvertException(OUSTR("[automation bridge] Call failed."
2133*cdf0e10cSrcweir                   "Object returned DISP_E_PARAMNOTOPTIONAL"),
2134*cdf0e10cSrcweir                         static_cast<XInterface*>(static_cast<XWeak*>(this)),
2135*cdf0e10cSrcweir                               TypeClass_UNKNOWN, FailReason::NO_DEFAULT_AVAILABLE, uArgErr);
2136*cdf0e10cSrcweir 			break;
2137*cdf0e10cSrcweir 		default:
2138*cdf0e10cSrcweir 			throw RuntimeException();
2139*cdf0e10cSrcweir 			break;
2140*cdf0e10cSrcweir 	}
2141*cdf0e10cSrcweir 
2142*cdf0e10cSrcweir 	return ret;
2143*cdf0e10cSrcweir }
2144*cdf0e10cSrcweir 
2145*cdf0e10cSrcweir void IUnknownWrapper_Impl::getFuncDescForInvoke(const OUString & sFuncName,
2146*cdf0e10cSrcweir                                                 const Sequence<Any> & seqArgs,
2147*cdf0e10cSrcweir                                                 FUNCDESC** pFuncDesc)
2148*cdf0e10cSrcweir {
2149*cdf0e10cSrcweir     int nUnoArgs = seqArgs.getLength();
2150*cdf0e10cSrcweir     const Any * arArgs = seqArgs.getConstArray();
2151*cdf0e10cSrcweir     ITypeInfo* pInfo = getTypeInfo();
2152*cdf0e10cSrcweir 
2153*cdf0e10cSrcweir     //If the last of the positional arguments is a PropertyPutArgument
2154*cdf0e10cSrcweir     //then obtain the type info for the property put operation.
2155*cdf0e10cSrcweir 
2156*cdf0e10cSrcweir     //The property value is always the last argument, in a positional argument list
2157*cdf0e10cSrcweir     //or in a list of named arguments. A PropertyPutArgument is actually a named argument
2158*cdf0e10cSrcweir     //hence it must not be put in an extra NamedArgument structure
2159*cdf0e10cSrcweir     if (nUnoArgs > 0 &&
2160*cdf0e10cSrcweir         arArgs[nUnoArgs - 1].getValueType() == getCppuType((PropertyPutArgument*) 0))
2161*cdf0e10cSrcweir     {
2162*cdf0e10cSrcweir         // DISPATCH_PROPERTYPUT
2163*cdf0e10cSrcweir         FuncDesc aDescGet(pInfo);
2164*cdf0e10cSrcweir         FuncDesc aDescPut(pInfo);
2165*cdf0e10cSrcweir         VarDesc aVarDesc(pInfo);
2166*cdf0e10cSrcweir         getPropDesc(sFuncName, & aDescGet, & aDescPut, & aVarDesc);
2167*cdf0e10cSrcweir         if ( ! aDescPut)
2168*cdf0e10cSrcweir         {
2169*cdf0e10cSrcweir             throw IllegalArgumentException(
2170*cdf0e10cSrcweir                 OUSTR("[automation bridge] The object does not have a writeable property: ")
2171*cdf0e10cSrcweir                 + sFuncName, Reference<XInterface>(), 0);
2172*cdf0e10cSrcweir         }
2173*cdf0e10cSrcweir         *pFuncDesc = aDescPut.Detach();
2174*cdf0e10cSrcweir     }
2175*cdf0e10cSrcweir     else
2176*cdf0e10cSrcweir     {   // DISPATCH_METHOD
2177*cdf0e10cSrcweir         FuncDesc aFuncDesc(pInfo);
2178*cdf0e10cSrcweir         getFuncDesc(sFuncName, & aFuncDesc);
2179*cdf0e10cSrcweir         if ( ! aFuncDesc)
2180*cdf0e10cSrcweir         {
2181*cdf0e10cSrcweir             // Fallback: DISPATCH_PROPERTYGET can mostly be called as
2182*cdf0e10cSrcweir             // DISPATCH_METHOD
2183*cdf0e10cSrcweir             ITypeInfo * pInfo = getTypeInfo();
2184*cdf0e10cSrcweir             FuncDesc aDescPut(pInfo);
2185*cdf0e10cSrcweir             VarDesc aVarDesc(pInfo);
2186*cdf0e10cSrcweir             getPropDesc(sFuncName, & aFuncDesc, & aDescPut, & aVarDesc);
2187*cdf0e10cSrcweir             if ( ! aFuncDesc )
2188*cdf0e10cSrcweir             {
2189*cdf0e10cSrcweir                 throw IllegalArgumentException(
2190*cdf0e10cSrcweir                     OUSTR("[automation bridge] The object does not have a function"
2191*cdf0e10cSrcweir                           "or readable property \"")
2192*cdf0e10cSrcweir                     + sFuncName, Reference<XInterface>(), 0);
2193*cdf0e10cSrcweir             }
2194*cdf0e10cSrcweir         }
2195*cdf0e10cSrcweir         *pFuncDesc = aFuncDesc.Detach();
2196*cdf0e10cSrcweir     }
2197*cdf0e10cSrcweir }
2198*cdf0e10cSrcweir bool IUnknownWrapper_Impl::getDispid(const OUString& sFuncName, DISPID * id)
2199*cdf0e10cSrcweir {
2200*cdf0e10cSrcweir 	OSL_ASSERT(m_spDispatch);
2201*cdf0e10cSrcweir 	LPOLESTR lpsz = const_cast<LPOLESTR> (reinterpret_cast<LPCOLESTR>(sFuncName.getStr()));
2202*cdf0e10cSrcweir 	HRESULT	hr = m_spDispatch->GetIDsOfNames(IID_NULL, &lpsz, 1, LOCALE_USER_DEFAULT, id);
2203*cdf0e10cSrcweir 	return hr == S_OK ? true : false;
2204*cdf0e10cSrcweir }
2205*cdf0e10cSrcweir void IUnknownWrapper_Impl::getFuncDesc(const OUString & sFuncName, FUNCDESC ** pFuncDesc)
2206*cdf0e10cSrcweir 
2207*cdf0e10cSrcweir {
2208*cdf0e10cSrcweir     OSL_ASSERT( * pFuncDesc == 0);
2209*cdf0e10cSrcweir     buildComTlbIndex();
2210*cdf0e10cSrcweir     typedef TLBFuncIndexMap::const_iterator cit;
2211*cdf0e10cSrcweir 	    typedef TLBFuncIndexMap::iterator it;
2212*cdf0e10cSrcweir     //We assume there is only one entry with the function name. A property
2213*cdf0e10cSrcweir     //would have two entries.
2214*cdf0e10cSrcweir 	cit itIndex= m_mapComFunc.find(sFuncName);
2215*cdf0e10cSrcweir 	if (itIndex == m_mapComFunc.end())
2216*cdf0e10cSrcweir 	{
2217*cdf0e10cSrcweir 		//try case insensive with IDispatch::GetIDsOfNames
2218*cdf0e10cSrcweir 		DISPID id;
2219*cdf0e10cSrcweir 		if (getDispid(sFuncName, &id))
2220*cdf0e10cSrcweir 		{
2221*cdf0e10cSrcweir 			CComBSTR memberName;
2222*cdf0e10cSrcweir             unsigned int pcNames=0;
2223*cdf0e10cSrcweir 			// get the case sensitive name
2224*cdf0e10cSrcweir             if( SUCCEEDED(getTypeInfo()->GetNames( id, & memberName, 1, &pcNames)))
2225*cdf0e10cSrcweir 			{
2226*cdf0e10cSrcweir 				//get the associated index and add an entry to the map
2227*cdf0e10cSrcweir 				//with the name sFuncName which differs in the casing of the letters to
2228*cdf0e10cSrcweir 				//the actual name as obtained from ITypeInfo
2229*cdf0e10cSrcweir 				cit itOrg  = m_mapComFunc.find(OUString(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName))));
2230*cdf0e10cSrcweir 				OSL_ASSERT(itOrg != m_mapComFunc.end());
2231*cdf0e10cSrcweir 				itIndex =
2232*cdf0e10cSrcweir 					m_mapComFunc.insert( TLBFuncIndexMap::value_type
2233*cdf0e10cSrcweir 					( make_pair(sFuncName, itOrg->second ) ));
2234*cdf0e10cSrcweir 			}
2235*cdf0e10cSrcweir 		}
2236*cdf0e10cSrcweir 	}
2237*cdf0e10cSrcweir 
2238*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 1
2239*cdf0e10cSrcweir     // There must only be one entry if sFuncName represents a function or two
2240*cdf0e10cSrcweir     // if it is a property
2241*cdf0e10cSrcweir     pair<cit, cit> p = m_mapComFunc.equal_range(sFuncName.toAsciiLowerCase());
2242*cdf0e10cSrcweir     int numEntries = 0;
2243*cdf0e10cSrcweir     for ( ;p.first != p.second; p.first ++, numEntries ++);
2244*cdf0e10cSrcweir     OSL_ASSERT( ! (numEntries > 3) );
2245*cdf0e10cSrcweir #endif
2246*cdf0e10cSrcweir 	if( itIndex != m_mapComFunc.end())
2247*cdf0e10cSrcweir 	{
2248*cdf0e10cSrcweir         ITypeInfo* pType= getTypeInfo();
2249*cdf0e10cSrcweir         FUNCDESC * pDesc = NULL;
2250*cdf0e10cSrcweir         if (SUCCEEDED(pType->GetFuncDesc(itIndex->second, & pDesc)))
2251*cdf0e10cSrcweir         {
2252*cdf0e10cSrcweir             if (pDesc->invkind == INVOKE_FUNC)
2253*cdf0e10cSrcweir             {
2254*cdf0e10cSrcweir                 (*pFuncDesc) = pDesc;
2255*cdf0e10cSrcweir             }
2256*cdf0e10cSrcweir             else
2257*cdf0e10cSrcweir             {
2258*cdf0e10cSrcweir                 pType->ReleaseFuncDesc(pDesc);
2259*cdf0e10cSrcweir             }
2260*cdf0e10cSrcweir         }
2261*cdf0e10cSrcweir         else
2262*cdf0e10cSrcweir         {
2263*cdf0e10cSrcweir             throw BridgeRuntimeError(OUSTR("[automation bridge] Could not get "
2264*cdf0e10cSrcweir                                            "FUNCDESC for ") + sFuncName);
2265*cdf0e10cSrcweir         }
2266*cdf0e10cSrcweir     }
2267*cdf0e10cSrcweir    //else no entry found for sFuncName, pFuncDesc will not be filled in
2268*cdf0e10cSrcweir }
2269*cdf0e10cSrcweir 
2270*cdf0e10cSrcweir void IUnknownWrapper_Impl::getPropDesc(const OUString & sFuncName, FUNCDESC ** pFuncDescGet,
2271*cdf0e10cSrcweir                                        FUNCDESC** pFuncDescPut, VARDESC** pVarDesc)
2272*cdf0e10cSrcweir {
2273*cdf0e10cSrcweir     OSL_ASSERT( * pFuncDescGet == 0 && * pFuncDescPut == 0);
2274*cdf0e10cSrcweir     buildComTlbIndex();
2275*cdf0e10cSrcweir     typedef TLBFuncIndexMap::const_iterator cit;
2276*cdf0e10cSrcweir     pair<cit, cit> p = m_mapComFunc.equal_range(sFuncName);
2277*cdf0e10cSrcweir     if (p.first == m_mapComFunc.end())
2278*cdf0e10cSrcweir 	{
2279*cdf0e10cSrcweir 		//try case insensive with IDispatch::GetIDsOfNames
2280*cdf0e10cSrcweir 		DISPID id;
2281*cdf0e10cSrcweir 		if (getDispid(sFuncName, &id))
2282*cdf0e10cSrcweir 		{
2283*cdf0e10cSrcweir 			CComBSTR memberName;
2284*cdf0e10cSrcweir             unsigned int pcNames=0;
2285*cdf0e10cSrcweir 			// get the case sensitive name
2286*cdf0e10cSrcweir             if( SUCCEEDED(getTypeInfo()->GetNames( id, & memberName, 1, &pcNames)))
2287*cdf0e10cSrcweir 			{
2288*cdf0e10cSrcweir 				//As opposed to getFuncDesc, we do not add the value because we would
2289*cdf0e10cSrcweir 				// need to find the get and set description for the property. This would
2290*cdf0e10cSrcweir 				//mean to iterate over all FUNCDESCs again.
2291*cdf0e10cSrcweir 				p = m_mapComFunc.equal_range(OUString(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName))));
2292*cdf0e10cSrcweir 			}
2293*cdf0e10cSrcweir 		}
2294*cdf0e10cSrcweir 	}
2295*cdf0e10cSrcweir 
2296*cdf0e10cSrcweir 	for ( int i = 0 ;p.first != p.second; p.first ++, i ++)
2297*cdf0e10cSrcweir 	{
2298*cdf0e10cSrcweir         // There are a maximum of two entries, property put and property get
2299*cdf0e10cSrcweir         OSL_ASSERT( ! (i > 2) );
2300*cdf0e10cSrcweir         ITypeInfo* pType= getTypeInfo();
2301*cdf0e10cSrcweir         FUNCDESC * pFuncDesc = NULL;
2302*cdf0e10cSrcweir         if (SUCCEEDED( pType->GetFuncDesc(p.first->second, & pFuncDesc)))
2303*cdf0e10cSrcweir         {
2304*cdf0e10cSrcweir             if (pFuncDesc->invkind == INVOKE_PROPERTYGET)
2305*cdf0e10cSrcweir             {
2306*cdf0e10cSrcweir                 (*pFuncDescGet) = pFuncDesc;
2307*cdf0e10cSrcweir             }
2308*cdf0e10cSrcweir             else if (pFuncDesc->invkind == INVOKE_PROPERTYPUT ||
2309*cdf0e10cSrcweir                      pFuncDesc->invkind == INVOKE_PROPERTYPUTREF)
2310*cdf0e10cSrcweir             {
2311*cdf0e10cSrcweir                 //a property can have 3 entries, put, put ref, get
2312*cdf0e10cSrcweir                 // If INVOKE_PROPERTYPUTREF or INVOKE_PROPERTYPUT is used
2313*cdf0e10cSrcweir                 //depends on what is found first.
2314*cdf0e10cSrcweir                 if ( * pFuncDescPut)
2315*cdf0e10cSrcweir                 {
2316*cdf0e10cSrcweir                     //we already have found one
2317*cdf0e10cSrcweir                     pType->ReleaseFuncDesc(pFuncDesc);
2318*cdf0e10cSrcweir                 }
2319*cdf0e10cSrcweir                 else
2320*cdf0e10cSrcweir                 {
2321*cdf0e10cSrcweir                     (*pFuncDescPut) = pFuncDesc;
2322*cdf0e10cSrcweir                 }
2323*cdf0e10cSrcweir             }
2324*cdf0e10cSrcweir             else
2325*cdf0e10cSrcweir             {
2326*cdf0e10cSrcweir                 pType->ReleaseFuncDesc(pFuncDesc);
2327*cdf0e10cSrcweir             }
2328*cdf0e10cSrcweir         }
2329*cdf0e10cSrcweir         //ITypeInfo::GetFuncDesc may even provide a funcdesc for a VARDESC
2330*cdf0e10cSrcweir         // with invkind = INVOKE_FUNC. Since this function should only return
2331*cdf0e10cSrcweir         //a value for a real property (XInvokation::hasMethod, ..::hasProperty
2332*cdf0e10cSrcweir         //we need to make sure that sFuncName represents a real property.
2333*cdf0e10cSrcweir         VARDESC * pVD = NULL;
2334*cdf0e10cSrcweir         if (SUCCEEDED(pType->GetVarDesc(p.first->second, & pVD)))
2335*cdf0e10cSrcweir             (*pVarDesc) = pVD;
2336*cdf0e10cSrcweir     }
2337*cdf0e10cSrcweir    //else no entry for sFuncName, pFuncDesc will not be filled in
2338*cdf0e10cSrcweir }
2339*cdf0e10cSrcweir 
2340*cdf0e10cSrcweir VARTYPE IUnknownWrapper_Impl::getElementTypeDesc(const TYPEDESC *desc)
2341*cdf0e10cSrcweir {
2342*cdf0e10cSrcweir 	VARTYPE _type( VT_NULL );
2343*cdf0e10cSrcweir 
2344*cdf0e10cSrcweir 	if (desc->vt == VT_PTR)
2345*cdf0e10cSrcweir 	{
2346*cdf0e10cSrcweir 		_type = getElementTypeDesc(desc->lptdesc);
2347*cdf0e10cSrcweir         _type |= VT_BYREF;
2348*cdf0e10cSrcweir 	}
2349*cdf0e10cSrcweir 	else if (desc->vt == VT_SAFEARRAY)
2350*cdf0e10cSrcweir 	{
2351*cdf0e10cSrcweir 		_type = getElementTypeDesc(desc->lptdesc);
2352*cdf0e10cSrcweir         _type |= VT_ARRAY;
2353*cdf0e10cSrcweir 	}
2354*cdf0e10cSrcweir 	else if (desc->vt == VT_USERDEFINED)
2355*cdf0e10cSrcweir 	{
2356*cdf0e10cSrcweir 		ITypeInfo* thisInfo = getTypeInfo(); //kept by this instance
2357*cdf0e10cSrcweir 		CComPtr<ITypeInfo>	spRefInfo;
2358*cdf0e10cSrcweir 		thisInfo->GetRefTypeInfo(desc->hreftype, & spRefInfo.p);
2359*cdf0e10cSrcweir 		if (spRefInfo)
2360*cdf0e10cSrcweir 		{
2361*cdf0e10cSrcweir 			TypeAttr  attr(spRefInfo);
2362*cdf0e10cSrcweir 			spRefInfo->GetTypeAttr( & attr);
2363*cdf0e10cSrcweir 			if (attr->typekind == TKIND_ENUM)
2364*cdf0e10cSrcweir 			{
2365*cdf0e10cSrcweir 				//We use the type of the first enum value.
2366*cdf0e10cSrcweir 				if (attr->cVars == 0)
2367*cdf0e10cSrcweir 				{
2368*cdf0e10cSrcweir 					throw BridgeRuntimeError(OUSTR("[automation bridge] Could "
2369*cdf0e10cSrcweir 						"not obtain type description"));
2370*cdf0e10cSrcweir 				}
2371*cdf0e10cSrcweir 				VarDesc var(spRefInfo);
2372*cdf0e10cSrcweir 				spRefInfo->GetVarDesc(0, & var);
2373*cdf0e10cSrcweir 				_type = var->lpvarValue->vt;
2374*cdf0e10cSrcweir 			}
2375*cdf0e10cSrcweir 			else if (attr->typekind == TKIND_INTERFACE)
2376*cdf0e10cSrcweir 			{
2377*cdf0e10cSrcweir 				_type = VT_UNKNOWN;
2378*cdf0e10cSrcweir 			}
2379*cdf0e10cSrcweir 			else if (attr->typekind == TKIND_DISPATCH)
2380*cdf0e10cSrcweir 			{
2381*cdf0e10cSrcweir 				_type = VT_DISPATCH;
2382*cdf0e10cSrcweir 			}
2383*cdf0e10cSrcweir 			else
2384*cdf0e10cSrcweir 			{
2385*cdf0e10cSrcweir 				throw BridgeRuntimeError(OUSTR("[automation bridge] "
2386*cdf0e10cSrcweir 					"Unhandled user defined type."));
2387*cdf0e10cSrcweir 			}
2388*cdf0e10cSrcweir 		}
2389*cdf0e10cSrcweir 	}
2390*cdf0e10cSrcweir 	else
2391*cdf0e10cSrcweir 	{
2392*cdf0e10cSrcweir 		_type = desc->vt;
2393*cdf0e10cSrcweir 	}
2394*cdf0e10cSrcweir 	return _type;
2395*cdf0e10cSrcweir }
2396*cdf0e10cSrcweir 
2397*cdf0e10cSrcweir void IUnknownWrapper_Impl::buildComTlbIndex()
2398*cdf0e10cSrcweir {
2399*cdf0e10cSrcweir     if ( ! m_bComTlbIndexInit)
2400*cdf0e10cSrcweir     {
2401*cdf0e10cSrcweir         MutexGuard guard(getBridgeMutex());
2402*cdf0e10cSrcweir         {
2403*cdf0e10cSrcweir             if ( ! m_bComTlbIndexInit)
2404*cdf0e10cSrcweir             {
2405*cdf0e10cSrcweir                 OUString sError;
2406*cdf0e10cSrcweir                 ITypeInfo* pType= getTypeInfo();
2407*cdf0e10cSrcweir                 TypeAttr typeAttr(pType);
2408*cdf0e10cSrcweir                 if( SUCCEEDED( pType->GetTypeAttr( &typeAttr)))
2409*cdf0e10cSrcweir                 {
2410*cdf0e10cSrcweir                     for( long i= 0; i < typeAttr->cFuncs; i++)
2411*cdf0e10cSrcweir                     {
2412*cdf0e10cSrcweir                         FuncDesc funcDesc(pType);
2413*cdf0e10cSrcweir                         if( SUCCEEDED( pType->GetFuncDesc( i, &funcDesc)))
2414*cdf0e10cSrcweir                         {
2415*cdf0e10cSrcweir                             CComBSTR memberName;
2416*cdf0e10cSrcweir                             unsigned int pcNames=0;
2417*cdf0e10cSrcweir                             if( SUCCEEDED(pType->GetNames( funcDesc->memid, & memberName, 1, &pcNames)))
2418*cdf0e10cSrcweir                             {
2419*cdf0e10cSrcweir 								OUString usName(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName)));
2420*cdf0e10cSrcweir                                 m_mapComFunc.insert( TLBFuncIndexMap::value_type( usName, i));
2421*cdf0e10cSrcweir                             }
2422*cdf0e10cSrcweir                             else
2423*cdf0e10cSrcweir                             {
2424*cdf0e10cSrcweir                                 sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
2425*cdf0e10cSrcweir                                                 "ITypeInfo::GetNames failed.");
2426*cdf0e10cSrcweir                             }
2427*cdf0e10cSrcweir                         }
2428*cdf0e10cSrcweir                         else
2429*cdf0e10cSrcweir                             sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
2430*cdf0e10cSrcweir                                             "ITypeInfo::GetFuncDesc failed.");
2431*cdf0e10cSrcweir                     }
2432*cdf0e10cSrcweir 
2433*cdf0e10cSrcweir 					//If we create an Object in JScript and a a property then it
2434*cdf0e10cSrcweir 					//has VARDESC instead of FUNCDESC
2435*cdf0e10cSrcweir                     for (long i = 0; i < typeAttr->cVars; i++)
2436*cdf0e10cSrcweir                     {
2437*cdf0e10cSrcweir                         VarDesc varDesc(pType);
2438*cdf0e10cSrcweir                         if (SUCCEEDED(pType->GetVarDesc(i, & varDesc)))
2439*cdf0e10cSrcweir                         {
2440*cdf0e10cSrcweir                             CComBSTR memberName;
2441*cdf0e10cSrcweir                             unsigned int pcNames = 0;
2442*cdf0e10cSrcweir                             if (SUCCEEDED(pType->GetNames(varDesc->memid, & memberName, 1, &pcNames)))
2443*cdf0e10cSrcweir                             {
2444*cdf0e10cSrcweir 								if (varDesc->varkind == VAR_DISPATCH)
2445*cdf0e10cSrcweir                                 {
2446*cdf0e10cSrcweir 									OUString usName(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName)));
2447*cdf0e10cSrcweir                                     m_mapComFunc.insert(TLBFuncIndexMap::value_type(
2448*cdf0e10cSrcweir                                                         usName, i));
2449*cdf0e10cSrcweir                                 }
2450*cdf0e10cSrcweir                             }
2451*cdf0e10cSrcweir                             else
2452*cdf0e10cSrcweir                             {
2453*cdf0e10cSrcweir                                 sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
2454*cdf0e10cSrcweir                                                 "ITypeInfo::GetNames failed.");
2455*cdf0e10cSrcweir                             }
2456*cdf0e10cSrcweir                         }
2457*cdf0e10cSrcweir                         else
2458*cdf0e10cSrcweir                             sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
2459*cdf0e10cSrcweir                                            "ITypeInfo::GetVarDesc failed.");
2460*cdf0e10cSrcweir 
2461*cdf0e10cSrcweir                     }
2462*cdf0e10cSrcweir                 }
2463*cdf0e10cSrcweir                 else
2464*cdf0e10cSrcweir                     sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
2465*cdf0e10cSrcweir                                     "ITypeInfo::GetTypeAttr failed.");
2466*cdf0e10cSrcweir 
2467*cdf0e10cSrcweir                 if (sError.getLength())
2468*cdf0e10cSrcweir                 {
2469*cdf0e10cSrcweir                     throw BridgeRuntimeError(sError);
2470*cdf0e10cSrcweir                 }
2471*cdf0e10cSrcweir 
2472*cdf0e10cSrcweir                 m_bComTlbIndexInit = true;
2473*cdf0e10cSrcweir             }
2474*cdf0e10cSrcweir         }
2475*cdf0e10cSrcweir     }
2476*cdf0e10cSrcweir }
2477*cdf0e10cSrcweir 
2478*cdf0e10cSrcweir ITypeInfo* IUnknownWrapper_Impl::getTypeInfo()
2479*cdf0e10cSrcweir {
2480*cdf0e10cSrcweir 	if( !m_spDispatch)
2481*cdf0e10cSrcweir     {
2482*cdf0e10cSrcweir         throw BridgeRuntimeError(OUSTR("The object has no IDispatch interface!"));
2483*cdf0e10cSrcweir     }
2484*cdf0e10cSrcweir 
2485*cdf0e10cSrcweir 	if( !m_spTypeInfo )
2486*cdf0e10cSrcweir 	{
2487*cdf0e10cSrcweir         MutexGuard guard(getBridgeMutex());
2488*cdf0e10cSrcweir         if( ! m_spTypeInfo)
2489*cdf0e10cSrcweir         {
2490*cdf0e10cSrcweir             CComPtr< ITypeInfo > spType;
2491*cdf0e10cSrcweir             if( SUCCEEDED( m_spDispatch->GetTypeInfo( 0, LOCALE_USER_DEFAULT, &spType.p)))
2492*cdf0e10cSrcweir 
2493*cdf0e10cSrcweir             {
2494*cdf0e10cSrcweir                 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
2495*cdf0e10cSrcweir 
2496*cdf0e10cSrcweir 				//If this is a dual interface then TYPEATTR::typekind is usually TKIND_INTERFACE
2497*cdf0e10cSrcweir 				//We need to get the type description for TKIND_DISPATCH
2498*cdf0e10cSrcweir 				TypeAttr typeAttr(spType.p);
2499*cdf0e10cSrcweir                 if( SUCCEEDED(spType->GetTypeAttr( &typeAttr)))
2500*cdf0e10cSrcweir 				{
2501*cdf0e10cSrcweir 					if (typeAttr->typekind == TKIND_INTERFACE &&
2502*cdf0e10cSrcweir 							typeAttr->wTypeFlags & TYPEFLAG_FDUAL)
2503*cdf0e10cSrcweir 					{
2504*cdf0e10cSrcweir 						HREFTYPE refDispatch;
2505*cdf0e10cSrcweir 						if (SUCCEEDED(spType->GetRefTypeOfImplType(::sal::static_int_cast< UINT, int >( -1 ), &refDispatch)))
2506*cdf0e10cSrcweir 						{
2507*cdf0e10cSrcweir 							CComPtr<ITypeInfo> spTypeDisp;
2508*cdf0e10cSrcweir 							if (SUCCEEDED(spType->GetRefTypeInfo(refDispatch, & spTypeDisp)))
2509*cdf0e10cSrcweir 								m_spTypeInfo= spTypeDisp;
2510*cdf0e10cSrcweir 						}
2511*cdf0e10cSrcweir 						else
2512*cdf0e10cSrcweir 						{
2513*cdf0e10cSrcweir 							throw BridgeRuntimeError(
2514*cdf0e10cSrcweir 								OUSTR("[automation bridge] Could not obtain type information "
2515*cdf0e10cSrcweir 								"for dispatch interface." ));
2516*cdf0e10cSrcweir 						}
2517*cdf0e10cSrcweir 					}
2518*cdf0e10cSrcweir 					else if (typeAttr->typekind == TKIND_DISPATCH)
2519*cdf0e10cSrcweir 					{
2520*cdf0e10cSrcweir 						m_spTypeInfo= spType;
2521*cdf0e10cSrcweir 					}
2522*cdf0e10cSrcweir 					else
2523*cdf0e10cSrcweir 					{
2524*cdf0e10cSrcweir 						throw BridgeRuntimeError(
2525*cdf0e10cSrcweir 							OUSTR("[automation bridge] Automation object does not "
2526*cdf0e10cSrcweir 							"provide type information."));
2527*cdf0e10cSrcweir 					}
2528*cdf0e10cSrcweir 				}
2529*cdf0e10cSrcweir             }
2530*cdf0e10cSrcweir             else
2531*cdf0e10cSrcweir             {
2532*cdf0e10cSrcweir                 throw BridgeRuntimeError(OUSTR("[automation bridge]The dispatch object does not "
2533*cdf0e10cSrcweir                                                "support ITypeInfo!"));
2534*cdf0e10cSrcweir             }
2535*cdf0e10cSrcweir         }
2536*cdf0e10cSrcweir     }
2537*cdf0e10cSrcweir 	return m_spTypeInfo;
2538*cdf0e10cSrcweir }
2539*cdf0e10cSrcweir 
2540*cdf0e10cSrcweir } // end namespace
2541*cdf0e10cSrcweir 
2542