1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unoobjw.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #include "ole2uno.hxx"
36 #include <tools/presys.h>
41 #include "comifaces.hxx"
42 #include <tools/postsys.h>
45 #include <vos/diagnose.hxx>
46 #include <vos/refernce.hxx>
47 #include <tools/debug.hxx>
48 #include <rtl/ustring.hxx>
49 #include <com/sun/star/beans/MethodConcept.hpp>
50 #include <com/sun/star/beans/PropertyConcept.hpp>
51 #include <com/sun/star/script/FailReason.hpp>
52 #include <com/sun/star/reflection/ParamInfo.hpp>
53 #include <com/sun/star/beans/XExactName.hpp>
54 #include <com/sun/star/container/NoSuchElementException.hpp>
56 #include <com/sun/star/beans/XMaterialHolder.hpp>
57 #include <com/sun/star/script/XInvocation2.hpp>
58 #include <com/sun/star/script/MemberType.hpp>
59 #include <com/sun/star/reflection/XIdlReflection.hpp>
60 #include <osl/interlck.h>
61 #include <com/sun/star/uno/genfunc.h>
62 #include <cppuhelper/implbase1.hxx>
64 #include "comifaces.hxx"
65 #include "jscriptclasses.hxx"
66 #include "unotypewrapper.hxx"
67 #include "oleobjw.hxx"
68 #include "unoobjw.hxx"
69 #include "servprov.hxx"
76 using namespace com::sun::star::uno
;
77 using namespace com::sun::star::beans
;
78 using namespace com::sun::star::container
;
79 using namespace com::sun::star::script
;
80 using namespace com::sun::star::lang
;
81 using namespace com::sun::star::bridge::ModelDependent
;
82 using namespace com::sun::star::reflection
;
87 extern "C" const GUID IID_IDispatchEx
;
92 hash_map
<sal_uInt32
, WeakReference
<XInterface
> > UnoObjToWrapperMap
;
93 static sal_Bool
writeBackOutParameter(VARIANTARG
* pDest
, VARIANT
* pSource
);
94 static sal_Bool
writeBackOutParameter2( VARIANTARG
* pDest
, VARIANT
* pSource
);
95 static HRESULT
mapCannotConvertException( CannotConvertException e
, unsigned int * puArgErr
);
98 /* Does not throw any exceptions.
99 Param pInfo can be NULL.
101 static void writeExcepinfo(EXCEPINFO
* pInfo
, const OUString
& message
)
105 pInfo
->wCode
= UNO_2_OLE_EXCEPTIONCODE
;
106 pInfo
->bstrSource
= SysAllocString(L
"[automation bridge] ");
107 pInfo
->bstrDescription
= SysAllocString(reinterpret_cast<LPCOLESTR
>(message
.getStr()));
111 /*****************************************************************************
113 class implementation: InterfaceOleWrapper_Impl
115 *****************************************************************************/
116 InterfaceOleWrapper_Impl::InterfaceOleWrapper_Impl( Reference
<XMultiServiceFactory
>& xFactory
,
117 sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
118 m_defaultValueType( 0),
119 UnoConversionUtilities
<InterfaceOleWrapper_Impl
>( xFactory
, unoWrapperClass
, comWrapperClass
)
123 InterfaceOleWrapper_Impl::~InterfaceOleWrapper_Impl()
125 MutexGuard
guard(getBridgeMutex());
126 // remove entries in global map
127 IT_Uno it
= UnoObjToWrapperMap
.find( (sal_uInt32
) m_xOrigin
.get());
128 if(it
!= UnoObjToWrapperMap
.end())
129 UnoObjToWrapperMap
.erase(it
);
130 #if OSL_DEBUG_LEVEL > 0
131 fprintf(stderr
,"[automation bridge] UnoObjToWrapperMap contains: %i \n",
132 UnoObjToWrapperMap
.size());
137 STDMETHODIMP
InterfaceOleWrapper_Impl::QueryInterface(REFIID riid
, LPVOID FAR
* ppv
)
144 if(IsEqualIID(riid
, IID_IUnknown
))
147 *ppv
= (IUnknown
*) (IDispatch
*) this;
149 else if (IsEqualIID(riid
, IID_IDispatch
))
152 *ppv
= (IDispatch
*) this;
154 else if( IsEqualIID( riid
, __uuidof( IUnoObjectWrapper
)))
157 *ppv
= (IUnoObjectWrapper
*) this;
164 STDMETHODIMP_(ULONG
) InterfaceOleWrapper_Impl::AddRef()
167 // does not need to guard because one should not rely on the return value of
172 STDMETHODIMP_(ULONG
) InterfaceOleWrapper_Impl::Release()
179 // IUnoObjectWrapper --------------------------------------------------------
180 STDMETHODIMP
InterfaceOleWrapper_Impl::getWrapperXInterface( Reference
<XInterface
>* pXInt
)
182 *pXInt
= Reference
<XInterface
>( static_cast<XWeak
*>( this), UNO_QUERY
);
183 return pXInt
->is() ? S_OK
: E_FAIL
;
185 STDMETHODIMP
InterfaceOleWrapper_Impl::getOriginalUnoObject( Reference
<XInterface
>* pXInt
)
188 return m_xOrigin
.is() ? S_OK
: E_FAIL
;
190 STDMETHODIMP
InterfaceOleWrapper_Impl::getOriginalUnoStruct( Any
* pStruct
)
195 Reference
<XMaterialHolder
> xMatHolder( m_xInvocation
, UNO_QUERY
);
198 Any any
= xMatHolder
->getMaterial();
199 if( any
.getValueTypeClass() == TypeClass_STRUCT
)
209 STDMETHODIMP
InterfaceOleWrapper_Impl::GetTypeInfoCount( unsigned int * /*pctinfo*/ )
214 STDMETHODIMP
InterfaceOleWrapper_Impl::GetTypeInfo(unsigned int /*itinfo*/, LCID
/*lcid*/, ITypeInfo
** /*pptinfo*/)
219 STDMETHODIMP
InterfaceOleWrapper_Impl::GetIDsOfNames(REFIID
/*riid*/,
220 OLECHAR
** rgszNames
,
225 HRESULT ret
= DISP_E_UNKNOWNNAME
;
228 MutexGuard
guard( getBridgeMutex());
232 // ----------------------------------------
233 if( ! _wcsicmp( *rgszNames
, JSCRIPT_VALUE_FUNC
) ||
234 ! _wcsicmp( *rgszNames
, BRIDGE_VALUE_FUNC
))
236 *rgdispid
= DISPID_JSCRIPT_VALUE_FUNC
;
239 else if( ! _wcsicmp( *rgszNames
, GET_STRUCT_FUNC
) ||
240 ! _wcsicmp( *rgszNames
, BRIDGE_GET_STRUCT_FUNC
))
242 *rgdispid
= DISPID_GET_STRUCT_FUNC
;
245 else if( ! _wcsicmp( *rgszNames
, BRIDGE_CREATE_TYPE_FUNC
))
247 *rgdispid
= DISPID_CREATE_TYPE_FUNC
;
251 // ----------------------------------------
252 if (m_xInvocation
.is() && (cNames
> 0))
254 OUString
name(reinterpret_cast<const sal_Unicode
*>(rgszNames
[0]));
255 NameToIdMap::iterator iter
= m_nameToDispIdMap
.find(name
);
257 if (iter
== m_nameToDispIdMap
.end())
261 if (m_xExactName
.is())
263 exactName
= m_xExactName
->getExactName(name
);
270 MemberInfo
d(0, exactName
);
272 if (m_xInvocation
->hasProperty(exactName
))
274 d
.flags
|= DISPATCH_PROPERTYGET
;
275 d
.flags
|= DISPATCH_PROPERTYPUT
;
276 d
.flags
|= DISPATCH_PROPERTYPUTREF
;
279 if (m_xInvocation
->hasMethod(exactName
))
281 d
.flags
|= DISPATCH_METHOD
;
286 m_MemberInfos
.push_back(d
);
287 iter
= m_nameToDispIdMap
.insert(NameToIdMap::value_type(exactName
, (DISPID
)m_MemberInfos
.size())).first
;
289 if (exactName
!= name
)
291 iter
= m_nameToDispIdMap
.insert(NameToIdMap::value_type(name
, (DISPID
)m_MemberInfos
.size())).first
;
296 if (iter
== m_nameToDispIdMap
.end())
298 ret
= DISP_E_UNKNOWNNAME
;
302 *rgdispid
= (*iter
).second
;
307 catch(BridgeRuntimeError
& )
323 // "convertDispparamsArgs" converts VARIANTS to their respecting Any counterparts
324 // The parameters "id", "wFlags" and "pdispparams" equal those as used in
325 // IDispatch::Invoke. The function handles special JavaScript
326 // cases where a VARIANT of type VT_DISPATCH is ambiguous and could represent
327 // an object, array ( JavaScript Array object), out parameter and in/out ( JavaScript Array object)
328 // parameter (JavaScript Array object)
329 // Because all those VT_DISPATCH objects need a different conversion
330 // we have to find out what the object is supposed to be. The function does this
331 // by either using type information or by help of a specialized ValueObject object.
333 // A. Type Information
334 // -----------------------------------------------------------------------------
335 // With the help of type information the kind of parameter can be exactly determined
336 // and an appropriate conversion can be choosen. A problem arises if a method expects
337 // an Any. Then the type info does not tell what the type of the value, that is kept
338 // by the any, should be. In this situation the decision wheter the param is a
339 // sequence or an object is made upon the fact if the object has a property "0"
340 // ( see function "isJScriptArray"). Since this is unsafe it is recommended to use
341 // the JScript value objects within a JScript script on such an occasion.
343 // B. JavaScript Value Object ( class JScriptValue )
344 // -----------------------------------------------------------------------------
345 // A JScriptValue (ValueObject) object is a COM object in that it implements IDispatch and the
346 // IJScriptValue object interface. Such objects are provided by all UNO wrapper
347 // objects used within a JScript script. To obtain an instance one has to call
348 // "_GetValueObject() or Bridge_GetValueObject()" on an UNO wrapper object (class InterfaceOleWrapper_Impl).
349 // A value object is appropriately initialized within the script and passed as
350 // parameter to an UNO object method or property. The convertDispparamsArgs function
351 // can easily find out that a param is such an object by queriing for the
352 // IJScriptValue interface. By this interface one the type and kind ( out, in/out)
353 // can be determined and the right conversion can be applied.
354 // Using ValueObjects we spare us the effort of aquiring and examining type information
355 // in order to figure out what the an IDispatch parameter is meant for.
357 // Normal JScript object parameter can be mixed with JScriptValue object. If an
358 // VARIANT contains an VT_DISPATCH that is no JScriptValue than the type information
359 // is used to find out about the reqired type.
360 void InterfaceOleWrapper_Impl::convertDispparamsArgs(DISPID id
,
361 unsigned short /*wFlags*/, DISPPARAMS
* pdispparams
, Sequence
<Any
>& rSeq
)
364 sal_Int32 countArgs
= pdispparams
->cArgs
;
368 rSeq
.realloc( countArgs
);
369 Any
* pParams
= rSeq
.getArray();
373 //Get type information for the current call
375 if( ! getInvocationInfoForCall( id
, info
))
376 throw BridgeRuntimeError(
377 OUSTR("[automation bridge]InterfaceOleWrapper_Impl::convertDispparamsArgs \n"
378 "Could not obtain type information for current call."));
380 for (int i
= 0; i
< countArgs
; i
++)
382 if (info
.eMemberType
== MemberType_METHOD
&&
383 info
.aParamModes
[ countArgs
- i
-1 ] == ParamMode_OUT
)
386 if(convertValueObject( & pdispparams
->rgvarg
[i
], anyParam
))
387 { //a param is a ValueObject and could be converted
388 pParams
[countArgs
- (i
+ 1)] = anyParam
;
392 // If the param is an out, in/out parameter in
393 // JScript (Array object, with value at index 0) then we
394 // extract Array[0] and put the value into varParam. At the end of the loop varParam
395 // is converted if it contains a value otherwise the VARIANT from
396 // DISPPARAMS is converted.
397 CComVariant varParam
;
399 // Check for JScript out and in/out paramsobjects (VT_DISPATCH).
400 // To find them out we use typeinformation of the function being called.
401 if( pdispparams
->rgvarg
[i
].vt
== VT_DISPATCH
)
403 if( info
.eMemberType
== MemberType_METHOD
&& info
.aParamModes
[ countArgs
- i
-1 ] == ParamMode_INOUT
)
406 // Index ( property) "0" contains the actual IN-param. The object is a JScript
408 // Get the IN-param at index "0"
409 IDispatch
* pdisp
= pdispparams
->rgvarg
[i
].pdispVal
;
411 OLECHAR
* sindex
= L
"0";
413 DISPPARAMS noParams
= {0,0,0,0};
414 if(SUCCEEDED( hr
= pdisp
->GetIDsOfNames( IID_NULL
, &sindex
, 1, LOCALE_USER_DEFAULT
, &id
)))
415 hr
= pdisp
->Invoke( id
, IID_NULL
, LOCALE_USER_DEFAULT
, DISPATCH_PROPERTYGET
,
416 & noParams
, & varParam
, NULL
, NULL
);
419 throw BridgeRuntimeError(
420 OUSTR("[automation bridge] Could not determine "
421 "if the object has a member \"0\". Error: ") +
422 OUString::valueOf(hr
));
427 if( varParam
.vt
== VT_EMPTY
) // then it was no in/out parameter
428 varParam
= pdispparams
->rgvarg
[i
];
430 if(info
.eMemberType
== MemberType_METHOD
)
431 variantToAny( & varParam
, anyParam
,
432 info
.aParamTypes
[ countArgs
- i
- 1]);
433 else if(info
.eMemberType
== MemberType_PROPERTY
)
434 variantToAny( & varParam
, anyParam
, info
.aType
);
438 pParams
[countArgs
- (i
+ 1)]= anyParam
;
439 }// end for / iterating over all parameters
442 sal_Bool
InterfaceOleWrapper_Impl::getInvocationInfoForCall( DISPID id
, InvocationInfo
& info
)
444 sal_Bool bTypesAvailable
= sal_False
;
446 if( !m_xInvocation
.is() )return false;
447 Reference
<XInvocation2
> inv2( m_xInvocation
, UNO_QUERY
);
450 // We need the name of the property or method to get its type information.
451 // The name can be identified through the param "id"
452 // that is kept as value in the map m_nameToDispIdMap.
453 // Proplem: the Windows JScript engine sometimes changes small letters to capital
454 // letters as happens in xidlclass_obj.createObject( var) // in JScript.
455 // IDispatch::GetIdsOfNames is then called with "CreateObject" !!!
456 // m_nameToDispIdMap can contain several names for one DISPID but only one is
457 // the exact one. If there's no m_xExactName and therefore no exact name then
458 // there's only one entry in the map.
459 typedef NameToIdMap::const_iterator cit
;
460 OUString sMemberName
;
462 for(cit ci1
= m_nameToDispIdMap
.begin(); ci1
!= m_nameToDispIdMap
.end(); ci1
++)
464 if( (*ci1
).second
== id
) // iterator is a pair< OUString, DISPID>
466 sMemberName
= (*ci1
).first
;
470 // Get information for the current call ( property or method).
471 // There could be similar names which only differ in the cases
472 // of letters. First we assume that the name which was passed into
473 // GetIDsOfNames is correct. If we won't get information with that
474 // name then we have the invocation service use the XExactName interface.
475 sal_Bool validInfo
= sal_True
;
476 InvocationInfo invInfo
;
478 invInfo
= inv2
->getInfoForName( sMemberName
, sal_False
);
480 catch( IllegalArgumentException
)
482 validInfo
= sal_False
;
487 invInfo
= inv2
->getInfoForName( sMemberName
, sal_True
);
489 if( invInfo
.aName
.pData
)
491 bTypesAvailable
= sal_True
;
495 return bTypesAvailable
;
497 // XBridgeSupplier2 ---------------------------------------------------
498 // only bridges itself ( this instance of InterfaceOleWrapper_Impl)from UNO to IDispatch
499 // If sourceModelType is UNO than any UNO interface implemented by InterfaceOleWrapper_Impl
500 // can bridged to IDispatch ( if destModelType == OLE). The IDispatch is
501 // implemented by this class.
502 Any SAL_CALL
InterfaceOleWrapper_Impl::createBridge(const Any
& modelDepObject
,
503 const Sequence
<sal_Int8
>& /*ProcessId*/,
504 sal_Int16 sourceModelType
,
505 sal_Int16 destModelType
)
506 throw (IllegalArgumentException
, RuntimeException
)
510 if( sourceModelType
== UNO
&& destModelType
== OLE
&&
511 modelDepObject
.getValueTypeClass() == TypeClass_INTERFACE
)
513 Reference
<XInterface
> xInt
;
514 if( modelDepObject
>>= xInt
)
516 if( xInt
== Reference
<XInterface
>( static_cast<XWeak
*>( this), UNO_QUERY
))
518 VARIANT
*pVar
= (VARIANT
*)CoTaskMemAlloc( sizeof( VARIANT
));
521 pVar
->vt
= VT_DISPATCH
;
522 pVar
->pdispVal
= static_cast<IDispatch
*>( this);
525 retAny
<<= reinterpret_cast< sal_uInt32
>( pVar
);
535 // XInitialization --------------------------------------------------
536 void SAL_CALL
InterfaceOleWrapper_Impl::initialize( const Sequence
< Any
>& aArguments
)
537 throw(Exception
, RuntimeException
)
539 switch( aArguments
.getLength() )
541 case 2: // the object wraps an UNO struct
542 aArguments
[0] >>= m_xInvocation
;
543 aArguments
[1] >>= m_defaultValueType
;
545 case 3: // the object wraps an UNO interface
546 aArguments
[0] >>= m_xInvocation
;
547 aArguments
[1] >>= m_xOrigin
;
548 aArguments
[2] >>= m_defaultValueType
;
552 m_xExactName
= Reference
<XExactName
>( m_xInvocation
, UNO_QUERY
);
555 Reference
< XInterface
> InterfaceOleWrapper_Impl::createUnoWrapperInstance()
557 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper_Impl(
558 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
559 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
562 Reference
<XInterface
> InterfaceOleWrapper_Impl::createComWrapperInstance()
564 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper_Impl(
565 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
566 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
571 // "getType" is used in convertValueObject to map the string denoting the type
572 // to an actual Type object.
573 bool getType( const BSTR name
, Type
& type
)
577 typelib_TypeDescription
* pDesc
= NULL
;
578 OUString
str( reinterpret_cast<const sal_Unicode
*>(name
));
579 typelib_typedescription_getByName( &pDesc
, str
.pData
);
582 type
= Type( pDesc
->pWeakRef
);
583 typelib_typedescription_release( pDesc
);
589 static sal_Bool
writeBackOutParameter2( VARIANTARG
* pDest
, VARIANT
* pSource
)
591 sal_Bool ret
= sal_False
;
594 // Handle JScriptValue objects and JScript out params ( Array object )
595 CComVariant
varDest( *pDest
);
597 if( SUCCEEDED( varDest
.ChangeType(VT_DISPATCH
)))
599 CComPtr
<IDispatch
> spDispDest(varDest
.pdispVal
);
601 // special Handling for a JScriptValue object
603 CComQIPtr
<IJScriptValueObject
, &__uuidof(IJScriptValueObject
)> spValueDest(spDispDest
);
605 CComQIPtr
<IJScriptValueObject
> spValueDest(spDispDest
);
609 VARIANT_BOOL varBool
= VARIANT_FALSE
;
610 if( SUCCEEDED( hr
= spValueDest
->IsOutParam( &varBool
) )
611 && varBool
== VARIANT_TRUE
||
612 SUCCEEDED(hr
= spValueDest
->IsInOutParam( &varBool
) )
613 && varBool
== VARIANT_TRUE
)
615 if( SUCCEEDED( spValueDest
->Set( CComVariant(), *pSource
)))
619 else if (pDest
->vt
== VT_DISPATCH
)// VT_DISPATCH -> JScript out param
621 // We use IDispatchEx because its GetDispID function causes the creation
622 // of a property if it does not exist already. This is convenient for
623 // out parameters in JScript. Then the user must not specify propery "0"
626 CComQIPtr
<IDispatchEx
, &__uuidof(IDispatchEx
)> spDispEx( spDispDest
);
628 CComQIPtr
<IDispatchEx
> spDispEx( spDispDest
);
632 CComBSTR
nullProp(L
"0");
634 if( SUCCEEDED( spDispEx
->GetDispID( nullProp
, fdexNameEnsure
, &dwDispID
)))
636 DISPPARAMS dispparams
= {NULL
, NULL
, 1, 1};
637 dispparams
.rgvarg
= pSource
;
638 DISPID dispidPut
= DISPID_PROPERTYPUT
;
639 dispparams
.rgdispidNamedArgs
= &dispidPut
;
641 if (pSource
->vt
== VT_UNKNOWN
|| pSource
->vt
== VT_DISPATCH
||
642 (pSource
->vt
& VT_ARRAY
) || (pSource
->vt
& VT_BYREF
))
643 hr
= spDispEx
->InvokeEx(dwDispID
, LOCALE_USER_DEFAULT
, DISPATCH_PROPERTYPUTREF
,
644 &dispparams
, NULL
, NULL
, NULL
);
646 hr
= spDispEx
->InvokeEx(dwDispID
, LOCALE_USER_DEFAULT
, DISPATCH_PROPERTYPUT
,
647 &dispparams
, NULL
, NULL
, NULL
);
654 ret
= writeBackOutParameter( pDest
, pSource
);
656 else // The param can't be a JScript out-parameter ( an Array object), it could be a VBScript
657 { // param. The function checks itself for correct VBScript params
658 ret
= writeBackOutParameter( pDest
, pSource
);
662 // VisualBasic Script passes arguments as VT_VARIANT | VT_BYREF be it in or out parameter.
663 // Thus we are in charge of freeing an eventual value contained by the inner VARIANT
664 // Please note: VariantCopy doesn't free a VT_BYREF value
665 // The out parameters are expected to have always a valid type
666 static sal_Bool
writeBackOutParameter(VARIANTARG
* pDest
, VARIANT
* pSource
)
669 sal_Bool ret
= FALSE
;
670 // Out parameter must be VT_BYREF
671 if ((V_VT(pDest
) & VT_BYREF
) != 0 )
673 VARTYPE oleTypeFlags
= V_VT(pSource
);
675 // if caller accept VARIANT as out parameter, any value must be converted
676 if (V_VT(pDest
) == (VT_VARIANT
| VT_BYREF
))
678 // When the user provides a VARIANT rather then a concrete type
679 // we just copy the source to the out, in/out parameter
680 // VT_DISPATCH, VT_UNKNOWN, VT_ARRAY, VT_BSTR in the VARIANT that
681 // is contained in pDest are released by VariantCopy
682 VariantCopy(V_VARIANTREF(pDest
), pSource
);
687 // variantarg and variant must have same type
688 if ((V_VT(pDest
) & oleTypeFlags
) == oleTypeFlags
)
690 if ((oleTypeFlags
& VT_ARRAY
) != 0)
693 if( *V_ARRAYREF(pDest
) != NULL
)
694 hr
= SafeArrayCopyData( V_ARRAY(pSource
), *V_ARRAYREF(pDest
));
697 hr
= SafeArrayCopy(V_ARRAY(pSource
), V_ARRAYREF(pDest
)) == NOERROR
;
704 switch (V_VT(pSource
))
708 *V_I2REF(pDest
) = V_I2(pSource
);
713 *V_I4REF(pDest
) = V_I4(pSource
);
717 *V_R4REF(pDest
) = V_R4(pSource
);
721 *V_R8REF(pDest
) = V_R8(pSource
);
725 *V_CYREF(pDest
) = V_CY(pSource
);
729 *V_DATEREF(pDest
) = V_DATE(pSource
);
733 SysFreeString( *pDest
->pbstrVal
);
735 *V_BSTRREF(pDest
) = SysAllocString(V_BSTR(pSource
));
739 if (*V_DISPATCHREF(pDest
) != NULL
)
740 (*V_DISPATCHREF(pDest
))->Release();
742 *V_DISPATCHREF(pDest
) = V_DISPATCH(pSource
);
744 if (*V_DISPATCHREF(pDest
) != NULL
)
745 (*V_DISPATCHREF(pDest
))->AddRef();
750 *V_ERRORREF(pDest
) = V_ERROR(pSource
);
754 *V_BOOLREF(pDest
) = V_BOOL(pSource
);
758 if (*V_UNKNOWNREF(pDest
) != NULL
)
759 (*V_UNKNOWNREF(pDest
))->Release();
761 *V_UNKNOWNREF(pDest
) = V_UNKNOWN(pSource
);
763 if (*V_UNKNOWNREF(pDest
) != NULL
)
764 (*V_UNKNOWNREF(pDest
))->AddRef();
769 *V_I1REF(pDest
) = V_I1(pSource
);
773 *V_UI1REF(pDest
) = V_UI1(pSource
);
777 *V_UI2REF(pDest
) = V_UI2(pSource
);
781 *V_UI4REF(pDest
) = V_UI4(pSource
);
785 *V_INTREF(pDest
) = V_INT(pSource
);
789 *V_UINTREF(pDest
) = V_UINT(pSource
);
793 memcpy(pDest
->pdecVal
, pSource
, sizeof(DECIMAL
));
803 // Handling of special cases
804 // Destination and source types are different
805 if( pDest
->vt
== (VT_BSTR
| VT_BYREF
)
806 && pSource
->vt
== VT_I2
)
808 // When the user provides a String as out our in/out parameter
809 // and the type is char (TypeClass_CHAR) then we convert to a BSTR
810 // instead of VT_I2 as is done otherwise
811 OLECHAR buff
[]= {0,0};
812 buff
[0]= pSource
->iVal
;
814 SysFreeString( *pDest
->pbstrVal
);
815 *pDest
->pbstrVal
= SysAllocString( buff
);
824 STDMETHODIMP
InterfaceOleWrapper_Impl::Invoke(DISPID dispidMember
,
827 unsigned short wFlags
,
828 DISPPARAMS
* pdispparams
,
829 VARIANT
* pvarResult
,
830 EXCEPINFO
* pexcepinfo
,
831 unsigned int * puArgErr
)
837 sal_Bool bHandled
= sal_False
;
838 ret
= InvokeGeneral( dispidMember
, wFlags
, pdispparams
, pvarResult
, pexcepinfo
,
843 if ((dispidMember
> 0) && ((size_t)dispidMember
<= m_MemberInfos
.size()) && m_xInvocation
.is())
845 MemberInfo d
= m_MemberInfos
[dispidMember
- 1];
846 DWORD flags
= wFlags
& d
.flags
;
850 if ((flags
& DISPATCH_METHOD
) != 0)
852 if (pdispparams
->cNamedArgs
> 0)
853 ret
= DISP_E_NONAMEDARGS
;
856 Sequence
<Any
> params
;
858 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
860 ret
= doInvoke(pdispparams
, pvarResult
,
861 pexcepinfo
, puArgErr
, d
.name
, params
);
864 else if ((flags
& DISPATCH_PROPERTYGET
) != 0)
866 ret
= doGetProperty( pdispparams
, pvarResult
,
869 else if ((flags
& DISPATCH_PROPERTYPUT
|| flags
& DISPATCH_PROPERTYPUTREF
) != 0)
871 if (pdispparams
->cArgs
!= 1)
872 ret
= DISP_E_BADPARAMCOUNT
;
875 Sequence
<Any
> params
;
876 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
877 if(params
.getLength() > 0)
878 ret
= doSetProperty( pdispparams
, pvarResult
, pexcepinfo
, puArgErr
, d
.name
, params
);
880 ret
= DISP_E_BADVARTYPE
;
885 ret
= DISP_E_MEMBERNOTFOUND
;
888 ret
= DISP_E_MEMBERNOTFOUND
;
890 catch(BridgeRuntimeError
& e
)
892 writeExcepinfo(pexcepinfo
, e
.message
);
893 ret
= DISP_E_EXCEPTION
;
897 OUString message
= OUSTR("InterfaceOleWrapper_Impl::Invoke : \n") +
899 writeExcepinfo(pexcepinfo
, message
);
900 ret
= DISP_E_EXCEPTION
;
904 OUString message
= OUSTR("InterfaceOleWrapper_Impl::Invoke : \n"
905 "Unexpected exception");
906 writeExcepinfo(pexcepinfo
, message
);
907 ret
= DISP_E_EXCEPTION
;
913 HRESULT
InterfaceOleWrapper_Impl::doInvoke( DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
,
914 EXCEPINFO
* pexcepinfo
, unsigned int * puArgErr
, OUString
& name
, Sequence
<Any
>& params
)
921 Sequence
<INT16
> outIndex
;
922 Sequence
<Any
> outParams
;
925 if (pdispparams
->cNamedArgs
> 0)
926 return DISP_E_NONAMEDARGS
;
928 // invoke method and take care of exceptions
929 returnValue
= m_xInvocation
->invoke(name
,
934 // try to write back out parameter
935 if (outIndex
.getLength() > 0)
937 const INT16
* pOutIndex
= outIndex
.getConstArray();
938 const Any
* pOutParams
= outParams
.getConstArray();
940 for (sal_Int32 i
= 0; i
< outIndex
.getLength(); i
++)
943 // Currently a Sequence is converted to an SafeArray of VARIANTs.
944 anyToVariant( &variant
, pOutParams
[i
]);
946 // out parameter need special handling if they are VT_DISPATCH
947 // and used in JScript
948 int outindex
= pOutIndex
[i
];
949 writeBackOutParameter2(&(pdispparams
->rgvarg
[pdispparams
->cArgs
- 1 - outindex
]),
954 // write back return value
955 if (pvarResult
!= NULL
)
956 anyToVariant(pvarResult
, returnValue
);
958 catch(IllegalArgumentException
& e
) //XInvocation::invoke
960 writeExcepinfo(pexcepinfo
, e
.Message
);
961 ret
= DISP_E_TYPEMISMATCH
;
963 catch(CannotConvertException
& e
) //XInvocation::invoke
965 writeExcepinfo(pexcepinfo
, e
.Message
);
966 ret
= mapCannotConvertException( e
, puArgErr
);
968 catch(InvocationTargetException
& e
) //XInvocation::invoke
970 const Any
& org
= e
.TargetException
;
974 org
.getValueType().getTypeName() + OUSTR(": ") + excTarget
.Message
;
975 writeExcepinfo(pexcepinfo
, message
);
976 ret
= DISP_E_EXCEPTION
;
978 catch(NoSuchMethodException
& e
) //XInvocation::invoke
980 writeExcepinfo(pexcepinfo
, e
.Message
);
981 ret
= DISP_E_MEMBERNOTFOUND
;
983 catch(BridgeRuntimeError
& e
)
985 writeExcepinfo(pexcepinfo
, e
.message
);
986 ret
= DISP_E_EXCEPTION
;
990 OUString message
= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n") +
992 writeExcepinfo(pexcepinfo
, message
);
993 ret
= DISP_E_EXCEPTION
;
997 OUString message
= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n"
998 "Unexpected exception");
999 writeExcepinfo(pexcepinfo
, message
);
1000 ret
= DISP_E_EXCEPTION
;
1005 HRESULT
InterfaceOleWrapper_Impl::doGetProperty( DISPPARAMS
* /*pdispparams*/, VARIANT
* pvarResult
,
1006 EXCEPINFO
* pexcepinfo
, OUString
& name
)
1013 Any returnValue
= m_xInvocation
->getValue( name
);
1014 // write back return value
1016 anyToVariant(pvarResult
, returnValue
);
1018 catch(UnknownPropertyException e
) //XInvocation::getValue
1020 writeExcepinfo(pexcepinfo
, e
.Message
);
1021 ret
= DISP_E_MEMBERNOTFOUND
;
1023 catch(BridgeRuntimeError
& e
)
1025 writeExcepinfo(pexcepinfo
, e
.message
);
1026 ret
= DISP_E_EXCEPTION
;
1030 OUString message
= OUSTR("InterfaceOleWrapper_Impl::doGetProperty : \n") +
1032 writeExcepinfo(pexcepinfo
, message
);
1036 OUString message
= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n"
1037 "Unexpected exception");
1038 writeExcepinfo(pexcepinfo
, message
);
1039 ret
= DISP_E_EXCEPTION
;
1044 HRESULT
InterfaceOleWrapper_Impl::doSetProperty( DISPPARAMS
* /*pdispparams*/, VARIANT
* /*pvarResult*/,
1045 EXCEPINFO
* pexcepinfo
, unsigned int * puArgErr
, OUString
& name
, Sequence
<Any
> params
)
1051 m_xInvocation
->setValue( name
, params
.getConstArray()[0]);
1053 catch(UnknownPropertyException
)
1055 ret
= DISP_E_MEMBERNOTFOUND
;
1057 catch(CannotConvertException e
)
1059 ret
= mapCannotConvertException( e
, puArgErr
);
1061 catch(InvocationTargetException e
)
1063 if (pexcepinfo
!= NULL
)
1065 Any org
= e
.TargetException
;
1067 pexcepinfo
->wCode
= UNO_2_OLE_EXCEPTIONCODE
;
1068 pexcepinfo
->bstrSource
= SysAllocString(L
"any ONE component");
1069 pexcepinfo
->bstrDescription
= SysAllocString(
1070 reinterpret_cast<LPCOLESTR
>(org
.getValueType().getTypeName().getStr()));
1072 ret
= DISP_E_EXCEPTION
;
1076 ret
= DISP_E_EXCEPTION
;
1081 HRESULT
InterfaceOleWrapper_Impl::InvokeGeneral( DISPID dispidMember
, unsigned short wFlags
,
1082 DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
, EXCEPINFO
* pexcepinfo
,
1083 unsigned int * /*puArgErr*/, sal_Bool
& bHandled
)
1088 // DISPID_VALUE | The DEFAULT Value is required in JScript when the situation
1089 // is that we put an object into an Array object ( out parameter). We have to return
1090 // IDispatch otherwise the object cannot be accessed from the Script.
1091 if( dispidMember
== DISPID_VALUE
&& wFlags
== DISPATCH_PROPERTYGET
1092 && m_defaultValueType
!= VT_EMPTY
&& pvarResult
!= NULL
)
1095 if( m_defaultValueType
== VT_DISPATCH
)
1097 pvarResult
->vt
= VT_DISPATCH
;
1098 pvarResult
->pdispVal
= static_cast<IDispatch
*>( this);
1104 // function: _GetValueObject
1105 else if( dispidMember
== DISPID_JSCRIPT_VALUE_FUNC
)
1110 CComObject
< JScriptValue
>* pValue
;
1111 if( SUCCEEDED( CComObject
<JScriptValue
>::CreateInstance( &pValue
)))
1114 pvarResult
->vt
= VT_DISPATCH
;
1116 pvarResult
->pdispVal
= CComQIPtr
<IDispatch
, &__uuidof(IDispatch
)>(pValue
->GetUnknown());
1118 pvarResult
->pdispVal
= CComQIPtr
<IDispatch
>(pValue
->GetUnknown());
1123 ret
= DISP_E_EXCEPTION
;
1125 else if( dispidMember
== DISPID_GET_STRUCT_FUNC
)
1128 sal_Bool bStruct
= sal_False
;
1131 Reference
<XInterface
> xIntCore
= m_smgr
->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection"));
1132 Reference
<XIdlReflection
> xRefl( xIntCore
, UNO_QUERY
);
1135 // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1137 if( pdispparams
->cArgs
== 1 && SUCCEEDED( arg
.ChangeType( VT_BSTR
, &pdispparams
->rgvarg
[0])) )
1139 Reference
<XIdlClass
> classStruct
= xRefl
->forName( reinterpret_cast<const sal_Unicode
*>(arg
.bstrVal
));
1140 if( classStruct
.is())
1143 classStruct
->createObject( anyStruct
);
1145 anyToVariant( &var
, anyStruct
);
1147 if( var
.vt
== VT_DISPATCH
)
1149 VariantCopy( pvarResult
, & var
);
1155 ret
= bStruct
== sal_True
? S_OK
: DISP_E_EXCEPTION
;
1157 else if (dispidMember
== DISPID_CREATE_TYPE_FUNC
)
1162 // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1164 if( pdispparams
->cArgs
!= 1)
1165 return DISP_E_BADPARAMCOUNT
;
1166 if (FAILED( arg
.ChangeType( VT_BSTR
, &pdispparams
->rgvarg
[0])))
1167 return DISP_E_BADVARTYPE
;
1169 //check if the provided name represents a valid type
1171 if (getType(arg
.bstrVal
, type
) == false)
1173 writeExcepinfo(pexcepinfo
,OUString(
1174 OUSTR("[automation bridge] A UNO type with the name ") +
1175 OUString(reinterpret_cast<const sal_Unicode
*>(arg
.bstrVal
)) + OUSTR(" does not exist!")));
1176 return DISP_E_EXCEPTION
;
1179 if (createUnoTypeWrapper(arg
.bstrVal
, pvarResult
) == false)
1181 writeExcepinfo(pexcepinfo
,OUSTR("[automation bridge] InterfaceOleWrapper_Impl::InvokeGeneral\n"
1182 "Could not initialize UnoTypeWrapper object!"));
1183 return DISP_E_EXCEPTION
;
1187 catch(BridgeRuntimeError
& e
)
1189 writeExcepinfo(pexcepinfo
, e
.message
);
1190 ret
= DISP_E_EXCEPTION
;
1192 catch(Exception
& e
)
1194 OUString message
= OUSTR("InterfaceOleWrapper_Impl::InvokeGeneral : \n") +
1196 writeExcepinfo(pexcepinfo
, message
);
1197 ret
= DISP_E_EXCEPTION
;
1201 OUString message
= OUSTR("InterfaceOleWrapper_Impl::InvokeGeneral : \n"
1202 "Unexpected exception");
1203 writeExcepinfo(pexcepinfo
, message
);
1204 ret
= DISP_E_EXCEPTION
;
1212 STDMETHODIMP
InterfaceOleWrapper_Impl::GetDispID(BSTR
/*bstrName*/, DWORD
/*grfdex*/, DISPID __RPC_FAR
* /*pid*/)
1214 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1219 STDMETHODIMP
InterfaceOleWrapper_Impl::InvokeEx(
1220 /* [in] */ DISPID
/*id*/,
1221 /* [in] */ LCID
/*lcid*/,
1222 /* [in] */ WORD
/*wFlags*/,
1223 /* [in] */ DISPPARAMS __RPC_FAR
* /*pdp*/,
1224 /* [out] */ VARIANT __RPC_FAR
* /*pvarRes*/,
1225 /* [out] */ EXCEPINFO __RPC_FAR
* /*pei*/,
1226 /* [unique][in] */ IServiceProvider __RPC_FAR
* /*pspCaller*/)
1228 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1234 STDMETHODIMP
InterfaceOleWrapper_Impl::DeleteMemberByName(
1235 /* [in] */ BSTR
/*bstr*/,
1236 /* [in] */ DWORD
/*grfdex*/)
1238 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1243 STDMETHODIMP
InterfaceOleWrapper_Impl::DeleteMemberByDispID(DISPID
/*id*/)
1245 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1250 STDMETHODIMP
InterfaceOleWrapper_Impl::GetMemberProperties(
1251 /* [in] */ DISPID
/*id*/,
1252 /* [in] */ DWORD
/*grfdexFetch*/,
1253 /* [out] */ DWORD __RPC_FAR
* /*pgrfdex*/)
1255 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1260 STDMETHODIMP
InterfaceOleWrapper_Impl::GetMemberName(
1261 /* [in] */ DISPID
/*id*/,
1262 /* [out] */ BSTR __RPC_FAR
* /*pbstrName*/)
1264 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1269 STDMETHODIMP
InterfaceOleWrapper_Impl::GetNextDispID(
1270 /* [in] */ DWORD
/*grfdex*/,
1271 /* [in] */ DISPID
/*id*/,
1272 /* [out] */ DISPID __RPC_FAR
* /*pid*/)
1274 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1279 STDMETHODIMP
InterfaceOleWrapper_Impl::GetNameSpaceParent(
1280 /* [out] */ IUnknown __RPC_FAR
*__RPC_FAR
* /*ppunk*/)
1282 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1288 /*************************************************************************
1290 UnoObjectWrapperRemoteOpt
1292 *************************************************************************/
1293 UnoObjectWrapperRemoteOpt::UnoObjectWrapperRemoteOpt( Reference
<XMultiServiceFactory
>& aFactory
,
1294 sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
1295 InterfaceOleWrapper_Impl( aFactory
, unoWrapperClass
, comWrapperClass
),
1300 UnoObjectWrapperRemoteOpt::~UnoObjectWrapperRemoteOpt()
1304 // UnoConversionUtilities
1305 Reference
< XInterface
> UnoObjectWrapperRemoteOpt::createUnoWrapperInstance()
1307 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
1308 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
1309 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
1312 STDMETHODIMP
UnoObjectWrapperRemoteOpt::GetIDsOfNames ( REFIID
/*riid*/, OLECHAR
** rgszNames
, unsigned int cNames
,
1313 LCID
/*lcid*/, DISPID
* rgdispid
)
1315 MutexGuard
guard( getBridgeMutex());
1319 HRESULT ret
= E_UNEXPECTED
;
1320 // ----------------------------------------
1322 if( ! wcscmp( *rgszNames
, JSCRIPT_VALUE_FUNC
))
1324 *rgdispid
= DISPID_JSCRIPT_VALUE_FUNC
;
1327 else if( ! wcscmp( *rgszNames
, GET_STRUCT_FUNC
))
1329 *rgdispid
= DISPID_GET_STRUCT_FUNC
;
1333 // ----------------------------------------
1334 if (m_xInvocation
.is() && (cNames
> 0))
1336 OUString
name(reinterpret_cast<const sal_Unicode
*>(rgszNames
[0]));
1337 // has this name been determined as "bad"
1338 BadNameMap::iterator badIter
= m_badNameMap
.find( name
);
1339 if( badIter
== m_badNameMap
.end() )
1341 // name has not been bad before( member exists
1342 typedef NameToIdMap::iterator ITnames
;
1343 pair
< ITnames
, bool > pair_id
= m_nameToDispIdMap
.insert( NameToIdMap::value_type(name
, m_currentId
++));
1344 // new ID inserted ?
1345 if( pair_id
.second
)
1346 {// yes, now create MemberInfo and ad to IdToMemberInfoMap
1347 MemberInfo
d(0, name
);
1348 m_idToMemberInfoMap
.insert( IdToMemberInfoMap::value_type( m_currentId
- 1, d
));
1351 *rgdispid
= pair_id
.first
->second
;
1355 ret
= DISP_E_UNKNOWNNAME
;
1360 STDMETHODIMP
UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember
, REFIID
/*riid*/, LCID
/*lcid*/, unsigned short wFlags
,
1361 DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
, EXCEPINFO
* pexcepinfo
,
1362 unsigned int * puArgErr
)
1367 sal_Bool bHandled
= sal_False
;
1368 ret
= InvokeGeneral( dispidMember
, wFlags
, pdispparams
, pvarResult
, pexcepinfo
,
1369 puArgErr
, bHandled
);
1373 if ( dispidMember
> 0 && m_xInvocation
.is())
1376 IdToMemberInfoMap::iterator it_MemberInfo
= m_idToMemberInfoMap
.find( dispidMember
);
1377 if( it_MemberInfo
!= m_idToMemberInfoMap
.end() )
1379 MemberInfo
& info
= it_MemberInfo
->second
;
1381 Sequence
<Any
> params
; // holds converted any s
1383 { // DISPID called for the first time
1384 if( wFlags
== DISPATCH_METHOD
)
1386 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1388 if( FAILED( ret
= doInvoke( pdispparams
, pvarResult
,
1389 pexcepinfo
, puArgErr
, info
.name
, params
))
1390 && ret
== DISP_E_MEMBERNOTFOUND
)
1392 // try to get the exact name
1394 if (m_xExactName
.is())
1396 exactName
= m_xExactName
->getExactName( info
.name
);
1398 if( exactName
.getLength() != 0)
1400 if( SUCCEEDED( ret
= doInvoke( pdispparams
, pvarResult
,
1401 pexcepinfo
, puArgErr
, exactName
, params
)))
1402 info
.name
= exactName
;
1406 if( SUCCEEDED( ret
) )
1407 info
.flags
= DISPATCH_METHOD
;
1408 } //if( wFlags == DISPATCH_METHOD )
1410 else if( wFlags
== DISPATCH_PROPERTYPUT
|| wFlags
== DISPATCH_PROPERTYPUTREF
)
1412 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1413 if( FAILED( ret
= doSetProperty( pdispparams
, pvarResult
,
1414 pexcepinfo
, puArgErr
, info
.name
, params
))
1415 && ret
== DISP_E_MEMBERNOTFOUND
)
1417 // try to get the exact name
1419 if (m_xExactName
.is())
1421 exactName
= m_xExactName
->getExactName( info
.name
);
1423 if( exactName
.getLength() != 0)
1425 if( SUCCEEDED( ret
= doSetProperty( pdispparams
, pvarResult
,
1426 pexcepinfo
, puArgErr
, exactName
, params
)))
1427 info
.name
= exactName
;
1431 if( SUCCEEDED( ret
) )
1432 info
.flags
= DISPATCH_PROPERTYPUT
| DISPATCH_PROPERTYGET
;
1435 else if( wFlags
== DISPATCH_PROPERTYGET
)
1437 if( FAILED( ret
= doGetProperty( pdispparams
, pvarResult
,
1438 pexcepinfo
, info
.name
))
1439 && ret
== DISP_E_MEMBERNOTFOUND
)
1441 // try to get the exact name
1443 if (m_xExactName
.is())
1445 exactName
= m_xExactName
->getExactName( info
.name
);
1447 if( exactName
.getLength() != 0)
1449 if( SUCCEEDED( ret
= doGetProperty( pdispparams
, pvarResult
,
1450 pexcepinfo
, exactName
)))
1451 info
.name
= exactName
;
1455 if( SUCCEEDED( ret
) )
1456 info
.flags
= DISPATCH_PROPERTYGET
| DISPATCH_PROPERTYPUT
;
1458 else if( wFlags
& DISPATCH_METHOD
&&
1459 (wFlags
& DISPATCH_PROPERTYPUT
|| wFlags
& DISPATCH_PROPERTYPUTREF
))
1463 // convert params for DISPATCH_METHOD or DISPATCH_PROPERTYPUT
1464 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1465 // try first as method
1466 if( FAILED( ret
= doInvoke( pdispparams
, pvarResult
,
1467 pexcepinfo
, puArgErr
, info
.name
, params
))
1468 && ret
== DISP_E_MEMBERNOTFOUND
)
1470 // try to get the exact name
1471 if (m_xExactName
.is())
1473 exactName
= m_xExactName
->getExactName( info
.name
);
1475 if( exactName
.getLength() != 0)
1477 if( SUCCEEDED( ret
= doInvoke( pdispparams
, pvarResult
,
1478 pexcepinfo
, puArgErr
, exactName
, params
)))
1479 info
.name
= exactName
;
1483 if( SUCCEEDED( ret
) )
1484 info
.flags
= DISPATCH_METHOD
;
1487 if( FAILED( ret
) && pdispparams
->cArgs
== 1)
1489 if( FAILED( ret
= doSetProperty( pdispparams
, pvarResult
,
1490 pexcepinfo
, puArgErr
, info
.name
, params
))
1491 && ret
== DISP_E_MEMBERNOTFOUND
)
1493 // try to get the exact name
1494 if( exactName
.getLength() != 0)
1496 if( SUCCEEDED( ret
= doSetProperty( pdispparams
, pvarResult
,
1497 pexcepinfo
, puArgErr
, exactName
, params
)))
1498 info
.name
= exactName
;
1501 if( SUCCEEDED( ret
) )
1502 info
.flags
= DISPATCH_PROPERTYPUT
| DISPATCH_PROPERTYGET
;
1505 else if( wFlags
& DISPATCH_METHOD
&& wFlags
& DISPATCH_PROPERTYGET
)
1508 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1510 if( FAILED( ret
= doInvoke( pdispparams
, pvarResult
,
1511 pexcepinfo
, puArgErr
, info
.name
, params
))
1512 && ret
== DISP_E_MEMBERNOTFOUND
)
1514 // try to get the exact name
1515 if (m_xExactName
.is())
1517 exactName
= m_xExactName
->getExactName( info
.name
);
1519 if( exactName
.getLength() != 0)
1521 if( SUCCEEDED( ret
= doInvoke( pdispparams
, pvarResult
,
1522 pexcepinfo
, puArgErr
, exactName
, params
)))
1523 info
.name
= exactName
;
1527 if( SUCCEEDED( ret
) )
1528 info
.flags
= DISPATCH_METHOD
;
1531 if( FAILED( ret
) && pdispparams
->cArgs
== 1)
1533 if( FAILED( ret
= doGetProperty( pdispparams
, pvarResult
,
1534 pexcepinfo
, info
.name
))
1535 && ret
== DISP_E_MEMBERNOTFOUND
)
1537 if( exactName
.getLength() != 0)
1539 if( SUCCEEDED( ret
= doSetProperty( pdispparams
, pvarResult
,
1540 pexcepinfo
, puArgErr
, exactName
, params
)))
1541 info
.name
= exactName
;
1544 if( SUCCEEDED( ret
) )
1545 info
.flags
= DISPATCH_PROPERTYGET
;
1549 // update ínformation about this member
1550 if( ret
== DISP_E_MEMBERNOTFOUND
)
1552 // Remember the name as not existing
1553 // and remove the MemberInfo
1554 m_badNameMap
[info
.name
]= sal_False
;
1555 m_idToMemberInfoMap
.erase( it_MemberInfo
);
1557 } // if( ! info.flags )
1558 else // IdToMemberInfoMap contains a MemberInfo
1560 if( wFlags
& DISPATCH_METHOD
&& info
.flags
== DISPATCH_METHOD
)
1562 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1563 ret
= doInvoke( pdispparams
, pvarResult
,
1564 pexcepinfo
, puArgErr
, info
.name
, params
);
1566 else if( (wFlags
& DISPATCH_PROPERTYPUT
|| wFlags
& DISPATCH_PROPERTYPUTREF
) &&
1567 info
.flags
& DISPATCH_PROPERTYPUT
)
1569 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1570 ret
= doSetProperty( pdispparams
, pvarResult
,
1571 pexcepinfo
, puArgErr
, info
.name
, params
);
1573 else if( (wFlags
& DISPATCH_PROPERTYGET
) && ( info
.flags
& DISPATCH_PROPERTYGET
))
1575 ret
= doGetProperty( pdispparams
, pvarResult
,
1576 pexcepinfo
, info
.name
);
1580 ret
= DISP_E_MEMBERNOTFOUND
;
1583 }// if( it_MemberInfo != m_idToMemberInfoMap.end() )
1585 ret
= DISP_E_MEMBERNOTFOUND
;
1588 catch(BridgeRuntimeError
& e
)
1590 writeExcepinfo(pexcepinfo
, e
.message
);
1591 ret
= DISP_E_EXCEPTION
;
1595 OUString message
= OUSTR("UnoObjectWrapperRemoteOpt::Invoke : \n") +
1597 writeExcepinfo(pexcepinfo
, message
);
1598 ret
= DISP_E_EXCEPTION
;
1602 OUString message
= OUSTR("UnoObjectWrapperRemoteOpt::Invoke : \n"
1603 "Unexpected exception");
1604 writeExcepinfo(pexcepinfo
, message
);
1605 ret
= DISP_E_EXCEPTION
;
1611 HRESULT
UnoObjectWrapperRemoteOpt::methodInvoke( DISPID
/*dispidMember*/, DISPPARAMS
* /*pdispparams*/, VARIANT
* /*pvarResult*/,
1612 EXCEPINFO
* /*pexcepinfo*/, unsigned int * /*puArgErr*/, Sequence
<Any
> params
)
1618 // The returned HRESULT is only appropriate for IDispatch::Invoke
1619 static HRESULT
mapCannotConvertException( CannotConvertException e
, unsigned int * puArgErr
)
1622 sal_Bool bWriteIndex
= sal_True
;
1626 case FailReason::OUT_OF_RANGE
:
1627 ret
= DISP_E_OVERFLOW
;
1629 case FailReason::IS_NOT_NUMBER
:
1630 ret
= DISP_E_TYPEMISMATCH
;
1632 case FailReason::IS_NOT_ENUM
:
1633 ret
= DISP_E_TYPEMISMATCH
;
1635 case FailReason::IS_NOT_BOOL
:
1636 ret
= DISP_E_TYPEMISMATCH
;
1638 case FailReason::NO_SUCH_INTERFACE
:
1639 ret
= DISP_E_TYPEMISMATCH
;
1641 case FailReason::SOURCE_IS_NO_DERIVED_TYPE
:
1642 ret
= DISP_E_TYPEMISMATCH
;
1644 case FailReason::TYPE_NOT_SUPPORTED
:
1645 ret
= DISP_E_TYPEMISMATCH
;
1647 case FailReason::INVALID
:
1648 ret
= DISP_E_TYPEMISMATCH
;
1650 case FailReason::NO_DEFAULT_AVAILABLE
:
1651 ret
= DISP_E_BADPARAMCOUNT
;
1653 case FailReason::UNKNOWN
:
1658 bWriteIndex
= sal_False
;
1662 if( bWriteIndex
&& puArgErr
!= NULL
)
1663 *puArgErr
= e
.ArgumentIndex
;
1667 // The function maps the TypeClass of the any to VARTYPE: If
1668 // the Any contains STRUCT or INTERFACE then the return value
1669 // is VT_DISPATCH. The function is used from o2u_createUnoObjectWrapper
1670 // and the result is put into the constructor of the uno - wrapper
1671 // object. If a client asks the object for DISPID_VALUE and this
1672 // funtion returned VT_DISPATCH then the IDispatch of the same
1673 // object is being returned.
1674 // See InterfaceOleWrapper_Impl::Invoke, InterfaceOleWrapper_Impl::m_defaultValueType
1675 const VARTYPE
getVarType( const Any
& value
)
1677 VARTYPE ret
= VT_EMPTY
;
1679 switch ( value
.getValueTypeClass())
1681 case TypeClass_STRUCT
: ret
= VT_DISPATCH
; break;
1682 case TypeClass_INTERFACE
: ret
= VT_DISPATCH
; break;