1*2a97ec55SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*2a97ec55SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*2a97ec55SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*2a97ec55SAndrew Rist * distributed with this work for additional information 6*2a97ec55SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*2a97ec55SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*2a97ec55SAndrew Rist * "License"); you may not use this file except in compliance 9*2a97ec55SAndrew Rist * with the License. You may obtain a copy of the License at 10*2a97ec55SAndrew Rist * 11*2a97ec55SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*2a97ec55SAndrew Rist * 13*2a97ec55SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*2a97ec55SAndrew Rist * software distributed under the License is distributed on an 15*2a97ec55SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*2a97ec55SAndrew Rist * KIND, either express or implied. See the License for the 17*2a97ec55SAndrew Rist * specific language governing permissions and limitations 18*2a97ec55SAndrew Rist * under the License. 19*2a97ec55SAndrew Rist * 20*2a97ec55SAndrew Rist *************************************************************/ 21*2a97ec55SAndrew Rist 22*2a97ec55SAndrew 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 -------------------------------------------------------------------------------- 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 } 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 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 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 } 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; 1592cdf0e10cSrcweir 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 } 1601cdf0e10cSrcweir 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 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 */ 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 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 } 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 } 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 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 2336cdf0e10cSrcweir VARTYPE IUnknownWrapper_Impl::getElementTypeDesc(const TYPEDESC *desc) 2337cdf0e10cSrcweir { 2338cdf0e10cSrcweir VARTYPE _type( VT_NULL ); 2339cdf0e10cSrcweir 2340cdf0e10cSrcweir if (desc->vt == VT_PTR) 2341cdf0e10cSrcweir { 2342cdf0e10cSrcweir _type = getElementTypeDesc(desc->lptdesc); 2343cdf0e10cSrcweir _type |= VT_BYREF; 2344cdf0e10cSrcweir } 2345cdf0e10cSrcweir else if (desc->vt == VT_SAFEARRAY) 2346cdf0e10cSrcweir { 2347cdf0e10cSrcweir _type = getElementTypeDesc(desc->lptdesc); 2348cdf0e10cSrcweir _type |= VT_ARRAY; 2349cdf0e10cSrcweir } 2350cdf0e10cSrcweir else if (desc->vt == VT_USERDEFINED) 2351cdf0e10cSrcweir { 2352cdf0e10cSrcweir ITypeInfo* thisInfo = getTypeInfo(); //kept by this instance 2353cdf0e10cSrcweir CComPtr<ITypeInfo> spRefInfo; 2354cdf0e10cSrcweir thisInfo->GetRefTypeInfo(desc->hreftype, & spRefInfo.p); 2355cdf0e10cSrcweir if (spRefInfo) 2356cdf0e10cSrcweir { 2357cdf0e10cSrcweir TypeAttr attr(spRefInfo); 2358cdf0e10cSrcweir spRefInfo->GetTypeAttr( & attr); 2359cdf0e10cSrcweir if (attr->typekind == TKIND_ENUM) 2360cdf0e10cSrcweir { 2361cdf0e10cSrcweir //We use the type of the first enum value. 2362cdf0e10cSrcweir if (attr->cVars == 0) 2363cdf0e10cSrcweir { 2364cdf0e10cSrcweir throw BridgeRuntimeError(OUSTR("[automation bridge] Could " 2365cdf0e10cSrcweir "not obtain type description")); 2366cdf0e10cSrcweir } 2367cdf0e10cSrcweir VarDesc var(spRefInfo); 2368cdf0e10cSrcweir spRefInfo->GetVarDesc(0, & var); 2369cdf0e10cSrcweir _type = var->lpvarValue->vt; 2370cdf0e10cSrcweir } 2371cdf0e10cSrcweir else if (attr->typekind == TKIND_INTERFACE) 2372cdf0e10cSrcweir { 2373cdf0e10cSrcweir _type = VT_UNKNOWN; 2374cdf0e10cSrcweir } 2375cdf0e10cSrcweir else if (attr->typekind == TKIND_DISPATCH) 2376cdf0e10cSrcweir { 2377cdf0e10cSrcweir _type = VT_DISPATCH; 2378cdf0e10cSrcweir } 2379cdf0e10cSrcweir else 2380cdf0e10cSrcweir { 2381cdf0e10cSrcweir throw BridgeRuntimeError(OUSTR("[automation bridge] " 2382cdf0e10cSrcweir "Unhandled user defined type.")); 2383cdf0e10cSrcweir } 2384cdf0e10cSrcweir } 2385cdf0e10cSrcweir } 2386cdf0e10cSrcweir else 2387cdf0e10cSrcweir { 2388cdf0e10cSrcweir _type = desc->vt; 2389cdf0e10cSrcweir } 2390cdf0e10cSrcweir return _type; 2391cdf0e10cSrcweir } 2392cdf0e10cSrcweir 2393cdf0e10cSrcweir void IUnknownWrapper_Impl::buildComTlbIndex() 2394cdf0e10cSrcweir { 2395cdf0e10cSrcweir if ( ! m_bComTlbIndexInit) 2396cdf0e10cSrcweir { 2397cdf0e10cSrcweir MutexGuard guard(getBridgeMutex()); 2398cdf0e10cSrcweir { 2399cdf0e10cSrcweir if ( ! m_bComTlbIndexInit) 2400cdf0e10cSrcweir { 2401cdf0e10cSrcweir OUString sError; 2402cdf0e10cSrcweir ITypeInfo* pType= getTypeInfo(); 2403cdf0e10cSrcweir TypeAttr typeAttr(pType); 2404cdf0e10cSrcweir if( SUCCEEDED( pType->GetTypeAttr( &typeAttr))) 2405cdf0e10cSrcweir { 2406cdf0e10cSrcweir for( long i= 0; i < typeAttr->cFuncs; i++) 2407cdf0e10cSrcweir { 2408cdf0e10cSrcweir FuncDesc funcDesc(pType); 2409cdf0e10cSrcweir if( SUCCEEDED( pType->GetFuncDesc( i, &funcDesc))) 2410cdf0e10cSrcweir { 2411cdf0e10cSrcweir CComBSTR memberName; 2412cdf0e10cSrcweir unsigned int pcNames=0; 2413cdf0e10cSrcweir if( SUCCEEDED(pType->GetNames( funcDesc->memid, & memberName, 1, &pcNames))) 2414cdf0e10cSrcweir { 2415cdf0e10cSrcweir OUString usName(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName))); 2416cdf0e10cSrcweir m_mapComFunc.insert( TLBFuncIndexMap::value_type( usName, i)); 2417cdf0e10cSrcweir } 2418cdf0e10cSrcweir else 2419cdf0e10cSrcweir { 2420cdf0e10cSrcweir sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \ 2421cdf0e10cSrcweir "ITypeInfo::GetNames failed."); 2422cdf0e10cSrcweir } 2423cdf0e10cSrcweir } 2424cdf0e10cSrcweir else 2425cdf0e10cSrcweir sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \ 2426cdf0e10cSrcweir "ITypeInfo::GetFuncDesc failed."); 2427cdf0e10cSrcweir } 2428cdf0e10cSrcweir 2429cdf0e10cSrcweir //If we create an Object in JScript and a a property then it 2430cdf0e10cSrcweir //has VARDESC instead of FUNCDESC 2431cdf0e10cSrcweir for (long i = 0; i < typeAttr->cVars; i++) 2432cdf0e10cSrcweir { 2433cdf0e10cSrcweir VarDesc varDesc(pType); 2434cdf0e10cSrcweir if (SUCCEEDED(pType->GetVarDesc(i, & varDesc))) 2435cdf0e10cSrcweir { 2436cdf0e10cSrcweir CComBSTR memberName; 2437cdf0e10cSrcweir unsigned int pcNames = 0; 2438cdf0e10cSrcweir if (SUCCEEDED(pType->GetNames(varDesc->memid, & memberName, 1, &pcNames))) 2439cdf0e10cSrcweir { 2440cdf0e10cSrcweir if (varDesc->varkind == VAR_DISPATCH) 2441cdf0e10cSrcweir { 2442cdf0e10cSrcweir OUString usName(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName))); 2443cdf0e10cSrcweir m_mapComFunc.insert(TLBFuncIndexMap::value_type( 2444cdf0e10cSrcweir usName, i)); 2445cdf0e10cSrcweir } 2446cdf0e10cSrcweir } 2447cdf0e10cSrcweir else 2448cdf0e10cSrcweir { 2449cdf0e10cSrcweir sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \ 2450cdf0e10cSrcweir "ITypeInfo::GetNames failed."); 2451cdf0e10cSrcweir } 2452cdf0e10cSrcweir } 2453cdf0e10cSrcweir else 2454cdf0e10cSrcweir sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \ 2455cdf0e10cSrcweir "ITypeInfo::GetVarDesc failed."); 2456cdf0e10cSrcweir 2457cdf0e10cSrcweir } 2458cdf0e10cSrcweir } 2459cdf0e10cSrcweir else 2460cdf0e10cSrcweir sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \ 2461cdf0e10cSrcweir "ITypeInfo::GetTypeAttr failed."); 2462cdf0e10cSrcweir 2463cdf0e10cSrcweir if (sError.getLength()) 2464cdf0e10cSrcweir { 2465cdf0e10cSrcweir throw BridgeRuntimeError(sError); 2466cdf0e10cSrcweir } 2467cdf0e10cSrcweir 2468cdf0e10cSrcweir m_bComTlbIndexInit = true; 2469cdf0e10cSrcweir } 2470cdf0e10cSrcweir } 2471cdf0e10cSrcweir } 2472cdf0e10cSrcweir } 2473cdf0e10cSrcweir 2474cdf0e10cSrcweir ITypeInfo* IUnknownWrapper_Impl::getTypeInfo() 2475cdf0e10cSrcweir { 2476cdf0e10cSrcweir if( !m_spDispatch) 2477cdf0e10cSrcweir { 2478cdf0e10cSrcweir throw BridgeRuntimeError(OUSTR("The object has no IDispatch interface!")); 2479cdf0e10cSrcweir } 2480cdf0e10cSrcweir 2481cdf0e10cSrcweir if( !m_spTypeInfo ) 2482cdf0e10cSrcweir { 2483cdf0e10cSrcweir MutexGuard guard(getBridgeMutex()); 2484cdf0e10cSrcweir if( ! m_spTypeInfo) 2485cdf0e10cSrcweir { 2486cdf0e10cSrcweir CComPtr< ITypeInfo > spType; 2487cdf0e10cSrcweir if( SUCCEEDED( m_spDispatch->GetTypeInfo( 0, LOCALE_USER_DEFAULT, &spType.p))) 2488cdf0e10cSrcweir 2489cdf0e10cSrcweir { 2490cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 2491cdf0e10cSrcweir 2492cdf0e10cSrcweir //If this is a dual interface then TYPEATTR::typekind is usually TKIND_INTERFACE 2493cdf0e10cSrcweir //We need to get the type description for TKIND_DISPATCH 2494cdf0e10cSrcweir TypeAttr typeAttr(spType.p); 2495cdf0e10cSrcweir if( SUCCEEDED(spType->GetTypeAttr( &typeAttr))) 2496cdf0e10cSrcweir { 2497cdf0e10cSrcweir if (typeAttr->typekind == TKIND_INTERFACE && 2498cdf0e10cSrcweir typeAttr->wTypeFlags & TYPEFLAG_FDUAL) 2499cdf0e10cSrcweir { 2500cdf0e10cSrcweir HREFTYPE refDispatch; 2501cdf0e10cSrcweir if (SUCCEEDED(spType->GetRefTypeOfImplType(::sal::static_int_cast< UINT, int >( -1 ), &refDispatch))) 2502cdf0e10cSrcweir { 2503cdf0e10cSrcweir CComPtr<ITypeInfo> spTypeDisp; 2504cdf0e10cSrcweir if (SUCCEEDED(spType->GetRefTypeInfo(refDispatch, & spTypeDisp))) 2505cdf0e10cSrcweir m_spTypeInfo= spTypeDisp; 2506cdf0e10cSrcweir } 2507cdf0e10cSrcweir else 2508cdf0e10cSrcweir { 2509cdf0e10cSrcweir throw BridgeRuntimeError( 2510cdf0e10cSrcweir OUSTR("[automation bridge] Could not obtain type information " 2511cdf0e10cSrcweir "for dispatch interface." )); 2512cdf0e10cSrcweir } 2513cdf0e10cSrcweir } 2514cdf0e10cSrcweir else if (typeAttr->typekind == TKIND_DISPATCH) 2515cdf0e10cSrcweir { 2516cdf0e10cSrcweir m_spTypeInfo= spType; 2517cdf0e10cSrcweir } 2518cdf0e10cSrcweir else 2519cdf0e10cSrcweir { 2520cdf0e10cSrcweir throw BridgeRuntimeError( 2521cdf0e10cSrcweir OUSTR("[automation bridge] Automation object does not " 2522cdf0e10cSrcweir "provide type information.")); 2523cdf0e10cSrcweir } 2524cdf0e10cSrcweir } 2525cdf0e10cSrcweir } 2526cdf0e10cSrcweir else 2527cdf0e10cSrcweir { 2528cdf0e10cSrcweir throw BridgeRuntimeError(OUSTR("[automation bridge]The dispatch object does not " 2529cdf0e10cSrcweir "support ITypeInfo!")); 2530cdf0e10cSrcweir } 2531cdf0e10cSrcweir } 2532cdf0e10cSrcweir } 2533cdf0e10cSrcweir return m_spTypeInfo; 2534cdf0e10cSrcweir } 2535cdf0e10cSrcweir 2536cdf0e10cSrcweir } // end namespace 2537cdf0e10cSrcweir 2538