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
1179cdf0e10cSrcweir // 2.parameter is a boolean which indicates if the 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)2336*3033dfcfSSteve Yin VARTYPE lcl_getUserDefinedElementType( ITypeInfo* pTypeInfo, const DWORD nHrefType )
2337*3033dfcfSSteve Yin {
2338*3033dfcfSSteve Yin VARTYPE _type( VT_NULL );
2339*3033dfcfSSteve Yin if ( pTypeInfo )
2340*3033dfcfSSteve Yin {
2341*3033dfcfSSteve Yin CComPtr<ITypeInfo> spRefInfo;
2342*3033dfcfSSteve Yin pTypeInfo->GetRefTypeInfo( nHrefType, &spRefInfo.p );
2343*3033dfcfSSteve Yin if ( spRefInfo )
2344*3033dfcfSSteve Yin {
2345*3033dfcfSSteve Yin TypeAttr attr( spRefInfo );
2346*3033dfcfSSteve Yin spRefInfo->GetTypeAttr( &attr );
2347*3033dfcfSSteve Yin if ( attr->typekind == TKIND_ENUM )
2348*3033dfcfSSteve Yin {
2349*3033dfcfSSteve Yin // We use the type of the first enum value.
2350*3033dfcfSSteve Yin if ( attr->cVars == 0 )
2351*3033dfcfSSteve Yin {
2352*3033dfcfSSteve Yin throw BridgeRuntimeError(OUSTR("[automation bridge] Could not obtain type description"));
2353*3033dfcfSSteve Yin }
2354*3033dfcfSSteve Yin VarDesc var( spRefInfo );
2355*3033dfcfSSteve Yin spRefInfo->GetVarDesc( 0, &var );
2356*3033dfcfSSteve Yin _type = var->lpvarValue->vt;
2357*3033dfcfSSteve Yin }
2358*3033dfcfSSteve Yin else if ( attr->typekind == TKIND_INTERFACE )
2359*3033dfcfSSteve Yin {
2360*3033dfcfSSteve Yin _type = VT_UNKNOWN;
2361*3033dfcfSSteve Yin }
2362*3033dfcfSSteve Yin else if ( attr->typekind == TKIND_DISPATCH )
2363*3033dfcfSSteve Yin {
2364*3033dfcfSSteve Yin _type = VT_DISPATCH;
2365*3033dfcfSSteve Yin }
2366*3033dfcfSSteve Yin else if ( attr->typekind == TKIND_ALIAS )
2367*3033dfcfSSteve Yin {
2368*3033dfcfSSteve Yin // TKIND_ALIAS is a type that is an alias for another type. So get that alias type.
2369*3033dfcfSSteve Yin _type = lcl_getUserDefinedElementType( pTypeInfo, attr->tdescAlias.hreftype );
2370*3033dfcfSSteve Yin }
2371*3033dfcfSSteve Yin else
2372*3033dfcfSSteve Yin {
2373*3033dfcfSSteve Yin throw BridgeRuntimeError( OUSTR("[automation bridge] Unhandled user defined type.") );
2374*3033dfcfSSteve Yin }
2375*3033dfcfSSteve Yin }
2376*3033dfcfSSteve Yin }
2377*3033dfcfSSteve Yin return _type;
2378*3033dfcfSSteve Yin }
2379*3033dfcfSSteve 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
2397*3033dfcfSSteve 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