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