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