1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "ole2uno.hxx"
24 #include <unordered_map>
27 #include <osl/diagnose.h>
28 #include <salhelper/simplereferenceobject.hxx>
29 #include <rtl/ustring.hxx>
30 #include <com/sun/star/beans/MethodConcept.hpp>
31 #include <com/sun/star/beans/PropertyConcept.hpp>
32 #include <com/sun/star/script/FailReason.hpp>
33 #include <com/sun/star/reflection/theCoreReflection.hpp>
34 #include <com/sun/star/reflection/ParamInfo.hpp>
35 #include <com/sun/star/beans/XExactName.hpp>
36 #include <com/sun/star/container/NoSuchElementException.hpp>
38 #include <com/sun/star/beans/XMaterialHolder.hpp>
39 #include <com/sun/star/script/XInvocation2.hpp>
40 #include <com/sun/star/script/MemberType.hpp>
41 #include <com/sun/star/reflection/XIdlReflection.hpp>
42 #include <osl/interlck.h>
43 #include <com/sun/star/uno/genfunc.h>
44 #include <comphelper/processfactory.hxx>
45 #include <cppuhelper/implbase1.hxx>
47 #include "comifaces.hxx"
48 #include "jscriptclasses.hxx"
49 #include "unotypewrapper.hxx"
50 #include "oleobjw.hxx"
51 #include "unoobjw.hxx"
52 #include "servprov.hxx"
57 using namespace com::sun::star::uno
;
58 using namespace com::sun::star::beans
;
59 using namespace com::sun::star::container
;
60 using namespace com::sun::star::script
;
61 using namespace com::sun::star::lang
;
62 using namespace com::sun::star::bridge::ModelDependent
;
63 using namespace com::sun::star::reflection
;
66 extern "C" const GUID IID_IDispatchEx
;
71 std::unordered_map
<sal_uInt32
, WeakReference
<XInterface
> > UnoObjToWrapperMap
;
72 static sal_Bool
writeBackOutParameter(VARIANTARG
* pDest
, VARIANT
* pSource
);
73 static sal_Bool
writeBackOutParameter2( VARIANTARG
* pDest
, VARIANT
* pSource
);
74 static HRESULT
mapCannotConvertException(const CannotConvertException
&e
, unsigned int * puArgErr
);
76 /* Does not throw any exceptions.
77 Param pInfo can be NULL.
79 static void writeExcepinfo(EXCEPINFO
* pInfo
, const OUString
& message
)
83 pInfo
->wCode
= UNO_2_OLE_EXCEPTIONCODE
;
84 pInfo
->bstrSource
= SysAllocString(L
"[automation bridge] ");
85 pInfo
->bstrDescription
= SysAllocString(reinterpret_cast<LPCOLESTR
>(message
.getStr()));
89 InterfaceOleWrapper_Impl::InterfaceOleWrapper_Impl( Reference
<XMultiServiceFactory
>& xFactory
,
90 sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
91 m_defaultValueType( 0),
92 UnoConversionUtilities
<InterfaceOleWrapper_Impl
>( xFactory
, unoWrapperClass
, comWrapperClass
)
96 InterfaceOleWrapper_Impl::~InterfaceOleWrapper_Impl()
98 MutexGuard
guard(getBridgeMutex());
99 // remove entries in global map
100 IT_Uno it
= UnoObjToWrapperMap
.find( (sal_uInt32
) m_xOrigin
.get());
101 if(it
!= UnoObjToWrapperMap
.end())
102 UnoObjToWrapperMap
.erase(it
);
103 #if OSL_DEBUG_LEVEL > 0
104 fprintf(stderr
,"[automation bridge] UnoObjToWrapperMap contains: %i \n",
105 UnoObjToWrapperMap
.size());
109 STDMETHODIMP
InterfaceOleWrapper_Impl::QueryInterface(REFIID riid
, LPVOID FAR
* ppv
)
116 if(IsEqualIID(riid
, IID_IUnknown
))
119 *ppv
= (IUnknown
*) (IDispatch
*) this;
121 else if (IsEqualIID(riid
, IID_IDispatch
))
124 *ppv
= (IDispatch
*) this;
126 else if( IsEqualIID( riid
, __uuidof( IUnoObjectWrapper
)))
129 *ppv
= (IUnoObjectWrapper
*) this;
136 STDMETHODIMP_(ULONG
) InterfaceOleWrapper_Impl::AddRef()
139 // does not need to guard because one should not rely on the return value of
144 STDMETHODIMP_(ULONG
) InterfaceOleWrapper_Impl::Release()
151 // IUnoObjectWrapper --------------------------------------------------------
152 STDMETHODIMP
InterfaceOleWrapper_Impl::getWrapperXInterface( Reference
<XInterface
>* pXInt
)
154 *pXInt
= Reference
<XInterface
>( static_cast<XWeak
*>( this), UNO_QUERY
);
155 return pXInt
->is() ? S_OK
: E_FAIL
;
157 STDMETHODIMP
InterfaceOleWrapper_Impl::getOriginalUnoObject( Reference
<XInterface
>* pXInt
)
160 return m_xOrigin
.is() ? S_OK
: E_FAIL
;
162 STDMETHODIMP
InterfaceOleWrapper_Impl::getOriginalUnoStruct( Any
* pStruct
)
167 Reference
<XMaterialHolder
> xMatHolder( m_xInvocation
, UNO_QUERY
);
170 Any any
= xMatHolder
->getMaterial();
171 if( any
.getValueTypeClass() == TypeClass_STRUCT
)
181 STDMETHODIMP
InterfaceOleWrapper_Impl::GetTypeInfoCount( unsigned int * /*pctinfo*/ )
186 STDMETHODIMP
InterfaceOleWrapper_Impl::GetTypeInfo(unsigned int /*itinfo*/, LCID
/*lcid*/, ITypeInfo
** /*pptinfo*/)
191 STDMETHODIMP
InterfaceOleWrapper_Impl::GetIDsOfNames(REFIID
/*riid*/,
192 OLECHAR
** rgszNames
,
197 HRESULT ret
= DISP_E_UNKNOWNNAME
;
200 MutexGuard
guard( getBridgeMutex());
204 if( ! _wcsicmp( *rgszNames
, JSCRIPT_VALUE_FUNC
) ||
205 ! _wcsicmp( *rgszNames
, BRIDGE_VALUE_FUNC
))
207 *rgdispid
= DISPID_JSCRIPT_VALUE_FUNC
;
210 else if( ! _wcsicmp( *rgszNames
, GET_STRUCT_FUNC
) ||
211 ! _wcsicmp( *rgszNames
, BRIDGE_GET_STRUCT_FUNC
))
213 *rgdispid
= DISPID_GET_STRUCT_FUNC
;
216 else if( ! _wcsicmp( *rgszNames
, BRIDGE_CREATE_TYPE_FUNC
))
218 *rgdispid
= DISPID_CREATE_TYPE_FUNC
;
222 if (m_xInvocation
.is() && (cNames
> 0))
224 OUString
name(reinterpret_cast<const sal_Unicode
*>(rgszNames
[0]));
225 NameToIdMap::iterator iter
= m_nameToDispIdMap
.find(name
);
227 if (iter
== m_nameToDispIdMap
.end())
231 if (m_xExactName
.is())
233 exactName
= m_xExactName
->getExactName(name
);
240 MemberInfo
d(0, exactName
);
242 if (m_xInvocation
->hasProperty(exactName
))
244 d
.flags
|= DISPATCH_PROPERTYGET
;
245 d
.flags
|= DISPATCH_PROPERTYPUT
;
246 d
.flags
|= DISPATCH_PROPERTYPUTREF
;
249 if (m_xInvocation
->hasMethod(exactName
))
251 d
.flags
|= DISPATCH_METHOD
;
256 m_MemberInfos
.push_back(d
);
257 iter
= m_nameToDispIdMap
.insert(NameToIdMap::value_type(exactName
, (DISPID
)m_MemberInfos
.size())).first
;
259 if (exactName
!= name
)
261 iter
= m_nameToDispIdMap
.insert(NameToIdMap::value_type(name
, (DISPID
)m_MemberInfos
.size())).first
;
266 if (iter
== m_nameToDispIdMap
.end())
268 ret
= DISP_E_UNKNOWNNAME
;
272 *rgdispid
= (*iter
).second
;
277 catch(const BridgeRuntimeError
&)
281 catch(const Exception
&)
293 // "convertDispparamsArgs" converts VARIANTS to their respecting Any counterparts
294 // The parameters "id", "wFlags" and "pdispparams" equal those as used in
295 // IDispatch::Invoke. The function handles special JavaScript
296 // cases where a VARIANT of type VT_DISPATCH is ambiguous and could represent
297 // an object, array ( JavaScript Array object), out parameter and in/out ( JavaScript Array object)
298 // parameter (JavaScript Array object)
299 // Because all those VT_DISPATCH objects need a different conversion
300 // we have to find out what the object is supposed to be. The function does this
301 // by either using type information or by help of a specialized ValueObject object.
303 // A. Type Information
305 // With the help of type information the kind of parameter can be exactly determined
306 // and an appropriate conversion can be chosen. A problem arises if a method expects
307 // an Any. Then the type info does not tell what the type of the value, that is kept
308 // by the any, should be. In this situation the decision whether the param is a
309 // sequence or an object is made upon the fact if the object has a property "0"
310 // ( see function "isJScriptArray"). Since this is unsafe it is recommended to use
311 // the JScript value objects within a JScript script on such an occasion.
313 // B. JavaScript Value Object ( class JScriptValue )
315 // A JScriptValue (ValueObject) object is a COM object in that it implements IDispatch and the
316 // IJScriptValue object interface. Such objects are provided by all UNO wrapper
317 // objects used within a JScript script. To obtain an instance one has to call
318 // "_GetValueObject() or Bridge_GetValueObject()" on an UNO wrapper object (class InterfaceOleWrapper_Impl).
319 // A value object is appropriately initialized within the script and passed as
320 // parameter to an UNO object method or property. The convertDispparamsArgs function
321 // can easily find out that a param is such an object by querying for the
322 // IJScriptValue interface. By this interface one the type and kind ( out, in/out)
323 // can be determined and the right conversion can be applied.
324 // Using ValueObjects we spare us the effort of acquiring and examining type information
325 // in order to figure out what the an IDispatch parameter is meant for.
327 // Normal JScript object parameter can be mixed with JScriptValue object. If an
328 // VARIANT contains an VT_DISPATCH that is no JScriptValue than the type information
329 // is used to find out about the required type.
330 void InterfaceOleWrapper_Impl::convertDispparamsArgs(DISPID id
,
331 unsigned short /*wFlags*/, DISPPARAMS
* pdispparams
, Sequence
<Any
>& rSeq
)
334 sal_Int32 countArgs
= pdispparams
->cArgs
;
338 rSeq
.realloc( countArgs
);
339 Any
* pParams
= rSeq
.getArray();
343 //Get type information for the current call
345 if( ! getInvocationInfoForCall( id
, info
))
346 throw BridgeRuntimeError(
347 "[automation bridge]InterfaceOleWrapper_Impl::convertDispparamsArgs \n"
348 "Could not obtain type information for current call.");
350 for (int i
= 0; i
< countArgs
; i
++)
352 if (info
.eMemberType
== MemberType_METHOD
&&
353 info
.aParamModes
[ countArgs
- i
-1 ] == ParamMode_OUT
)
356 if(convertValueObject( & pdispparams
->rgvarg
[i
], anyParam
))
357 { //a param is a ValueObject and could be converted
358 pParams
[countArgs
- (i
+ 1)] = anyParam
;
362 // If the param is an out, in/out parameter in
363 // JScript (Array object, with value at index 0) then we
364 // extract Array[0] and put the value into varParam. At the end of the loop varParam
365 // is converted if it contains a value otherwise the VARIANT from
366 // DISPPARAMS is converted.
367 CComVariant varParam
;
369 // Check for JScript out and in/out paramsobjects (VT_DISPATCH).
370 // To find them out we use typeinformation of the function being called.
371 if( pdispparams
->rgvarg
[i
].vt
== VT_DISPATCH
)
373 if( info
.eMemberType
== MemberType_METHOD
&& info
.aParamModes
[ countArgs
- i
-1 ] == ParamMode_INOUT
)
376 // Index ( property) "0" contains the actual IN-param. The object is a JScript
378 // Get the IN-param at index "0"
379 IDispatch
* pdisp
= pdispparams
->rgvarg
[i
].pdispVal
;
381 OLECHAR
* sindex
= L
"0";
383 DISPPARAMS noParams
= {0,0,0,0};
384 if(SUCCEEDED( hr
= pdisp
->GetIDsOfNames( IID_NULL
, &sindex
, 1, LOCALE_USER_DEFAULT
, &id
)))
385 hr
= pdisp
->Invoke( id
, IID_NULL
, LOCALE_USER_DEFAULT
, DISPATCH_PROPERTYGET
,
386 & noParams
, & varParam
, NULL
, NULL
);
389 throw BridgeRuntimeError(
390 "[automation bridge] Could not determine "
391 "if the object has a member \"0\". Error: " +
392 OUString::number(hr
));
397 if( varParam
.vt
== VT_EMPTY
) // then it was no in/out parameter
398 varParam
= pdispparams
->rgvarg
[i
];
400 if(info
.eMemberType
== MemberType_METHOD
)
401 variantToAny( & varParam
, anyParam
,
402 info
.aParamTypes
[ countArgs
- i
- 1]);
403 else if(info
.eMemberType
== MemberType_PROPERTY
)
404 variantToAny( & varParam
, anyParam
, info
.aType
);
408 pParams
[countArgs
- (i
+ 1)]= anyParam
;
409 }// end for / iterating over all parameters
412 sal_Bool
InterfaceOleWrapper_Impl::getInvocationInfoForCall( DISPID id
, InvocationInfo
& info
)
414 sal_Bool bTypesAvailable
= sal_False
;
416 if( !m_xInvocation
.is() )return false;
417 Reference
<XInvocation2
> inv2( m_xInvocation
, UNO_QUERY
);
420 // We need the name of the property or method to get its type information.
421 // The name can be identified through the param "id"
422 // that is kept as value in the map m_nameToDispIdMap.
423 // Proplem: the Windows JScript engine sometimes changes small letters to capital
424 // letters as happens in xidlclass_obj.createObject( var) // in JScript.
425 // IDispatch::GetIdsOfNames is then called with "CreateObject" !!!
426 // m_nameToDispIdMap can contain several names for one DISPID but only one is
427 // the exact one. If there's no m_xExactName and therefore no exact name then
428 // there's only one entry in the map.
429 typedef NameToIdMap::const_iterator cit
;
430 OUString sMemberName
;
432 for(cit ci1
= m_nameToDispIdMap
.begin(); ci1
!= m_nameToDispIdMap
.end(); ++ci1
)
434 if( (*ci1
).second
== id
) // iterator is a pair< OUString, DISPID>
436 sMemberName
= (*ci1
).first
;
440 // Get information for the current call ( property or method).
441 // There could be similar names which only differ in the cases
442 // of letters. First we assume that the name which was passed into
443 // GetIDsOfNames is correct. If we won't get information with that
444 // name then we have the invocation service use the XExactName interface.
445 sal_Bool validInfo
= sal_True
;
446 InvocationInfo invInfo
;
448 invInfo
= inv2
->getInfoForName( sMemberName
, sal_False
);
450 catch(const IllegalArgumentException
&)
452 validInfo
= sal_False
;
457 invInfo
= inv2
->getInfoForName( sMemberName
, sal_True
);
459 if( invInfo
.aName
.pData
)
461 bTypesAvailable
= sal_True
;
465 return bTypesAvailable
;
468 // XBridgeSupplier2 ---------------------------------------------------
469 // only bridges itself ( this instance of InterfaceOleWrapper_Impl)from UNO to IDispatch
470 // If sourceModelType is UNO than any UNO interface implemented by InterfaceOleWrapper_Impl
471 // can bridged to IDispatch ( if destModelType == OLE). The IDispatch is
472 // implemented by this class.
473 Any SAL_CALL
InterfaceOleWrapper_Impl::createBridge(const Any
& modelDepObject
,
474 const Sequence
<sal_Int8
>& /*ProcessId*/,
475 sal_Int16 sourceModelType
,
476 sal_Int16 destModelType
)
477 throw (IllegalArgumentException
, RuntimeException
)
481 if( sourceModelType
== UNO
&& destModelType
== OLE
&&
482 modelDepObject
.getValueTypeClass() == TypeClass_INTERFACE
)
484 Reference
<XInterface
> xInt
;
485 if( modelDepObject
>>= xInt
)
487 if( xInt
== Reference
<XInterface
>( static_cast<XWeak
*>( this), UNO_QUERY
))
489 VARIANT
*pVar
= (VARIANT
*)CoTaskMemAlloc( sizeof( VARIANT
));
492 pVar
->vt
= VT_DISPATCH
;
493 pVar
->pdispVal
= static_cast<IDispatch
*>( this);
496 retAny
<<= reinterpret_cast< sal_uInt32
>( pVar
);
505 // XInitialization --------------------------------------------------
506 void SAL_CALL
InterfaceOleWrapper_Impl::initialize( const Sequence
< Any
>& aArguments
)
507 throw(Exception
, RuntimeException
)
509 switch( aArguments
.getLength() )
511 case 2: // the object wraps an UNO struct
512 aArguments
[0] >>= m_xInvocation
;
513 aArguments
[1] >>= m_defaultValueType
;
515 case 3: // the object wraps an UNO interface
516 aArguments
[0] >>= m_xInvocation
;
517 aArguments
[1] >>= m_xOrigin
;
518 aArguments
[2] >>= m_defaultValueType
;
522 m_xExactName
= Reference
<XExactName
>( m_xInvocation
, UNO_QUERY
);
525 Reference
< XInterface
> InterfaceOleWrapper_Impl::createUnoWrapperInstance()
527 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper_Impl(
528 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
529 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
532 Reference
<XInterface
> InterfaceOleWrapper_Impl::createComWrapperInstance()
534 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper_Impl(
535 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
536 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
539 // "getType" is used in convertValueObject to map the string denoting the type
540 // to an actual Type object.
541 bool getType( const BSTR name
, Type
& type
)
545 typelib_TypeDescription
* pDesc
= NULL
;
546 OUString
str( reinterpret_cast<const sal_Unicode
*>(name
));
547 typelib_typedescription_getByName( &pDesc
, str
.pData
);
550 type
= Type( pDesc
->pWeakRef
);
551 typelib_typedescription_release( pDesc
);
557 static sal_Bool
writeBackOutParameter2( VARIANTARG
* pDest
, VARIANT
* pSource
)
559 sal_Bool ret
= sal_False
;
562 // Handle JScriptValue objects and JScript out params ( Array object )
563 CComVariant
varDest( *pDest
);
565 if( SUCCEEDED( varDest
.ChangeType(VT_DISPATCH
)))
567 CComPtr
<IDispatch
> spDispDest(varDest
.pdispVal
);
569 // special Handling for a JScriptValue object
571 CComQIPtr
<IJScriptValueObject
, &__uuidof(IJScriptValueObject
)> spValueDest(spDispDest
);
573 CComQIPtr
<IJScriptValueObject
> spValueDest(spDispDest
);
577 VARIANT_BOOL varBool
= VARIANT_FALSE
;
578 if( SUCCEEDED( hr
= spValueDest
->IsOutParam( &varBool
) )
579 && varBool
== VARIANT_TRUE
||
580 SUCCEEDED(hr
= spValueDest
->IsInOutParam( &varBool
) )
581 && varBool
== VARIANT_TRUE
)
583 if( SUCCEEDED( spValueDest
->Set( CComVariant(), *pSource
)))
587 else if (pDest
->vt
== VT_DISPATCH
)// VT_DISPATCH -> JScript out param
589 // We use IDispatchEx because its GetDispID function causes the creation
590 // of a property if it does not exist already. This is convenient for
591 // out parameters in JScript. Then the user must not specify propery "0"
594 CComQIPtr
<IDispatchEx
, &__uuidof(IDispatchEx
)> spDispEx( spDispDest
);
596 CComQIPtr
<IDispatchEx
> spDispEx( spDispDest
);
600 CComBSTR
nullProp(L
"0");
602 if( SUCCEEDED( spDispEx
->GetDispID( nullProp
, fdexNameEnsure
, &dwDispID
)))
604 DISPPARAMS dispparams
= {NULL
, NULL
, 1, 1};
605 dispparams
.rgvarg
= pSource
;
606 DISPID dispidPut
= DISPID_PROPERTYPUT
;
607 dispparams
.rgdispidNamedArgs
= &dispidPut
;
609 if (pSource
->vt
== VT_UNKNOWN
|| pSource
->vt
== VT_DISPATCH
||
610 (pSource
->vt
& VT_ARRAY
) || (pSource
->vt
& VT_BYREF
))
611 hr
= spDispEx
->InvokeEx(dwDispID
, LOCALE_USER_DEFAULT
, DISPATCH_PROPERTYPUTREF
,
612 &dispparams
, NULL
, NULL
, NULL
);
614 hr
= spDispEx
->InvokeEx(dwDispID
, LOCALE_USER_DEFAULT
, DISPATCH_PROPERTYPUT
,
615 &dispparams
, NULL
, NULL
, NULL
);
622 ret
= writeBackOutParameter( pDest
, pSource
);
624 else // The param can't be a JScript out-parameter ( an Array object), it could be a VBScript
625 { // param. The function checks itself for correct VBScript params
626 ret
= writeBackOutParameter( pDest
, pSource
);
631 // VisualBasic Script passes arguments as VT_VARIANT | VT_BYREF be it in or out parameter.
632 // Thus we are in charge of freeing an eventual value contained by the inner VARIANT
633 // Please note: VariantCopy doesn't free a VT_BYREF value
634 // The out parameters are expected to have always a valid type
635 static sal_Bool
writeBackOutParameter(VARIANTARG
* pDest
, VARIANT
* pSource
)
638 sal_Bool ret
= FALSE
;
639 // Out parameter must be VT_BYREF
640 if ((V_VT(pDest
) & VT_BYREF
) != 0 )
642 VARTYPE oleTypeFlags
= V_VT(pSource
);
644 // if caller accept VARIANT as out parameter, any value must be converted
645 if (V_VT(pDest
) == (VT_VARIANT
| VT_BYREF
))
647 // When the user provides a VARIANT rather then a concrete type
648 // we just copy the source to the out, in/out parameter
649 // VT_DISPATCH, VT_UNKNOWN, VT_ARRAY, VT_BSTR in the VARIANT that
650 // is contained in pDest are released by VariantCopy
651 VariantCopy(V_VARIANTREF(pDest
), pSource
);
656 // variantarg and variant must have same type
657 if ((V_VT(pDest
) & oleTypeFlags
) == oleTypeFlags
)
659 if ((oleTypeFlags
& VT_ARRAY
) != 0)
662 if( *V_ARRAYREF(pDest
) != NULL
)
663 hr
= SafeArrayCopyData( V_ARRAY(pSource
), *V_ARRAYREF(pDest
));
666 hr
= SafeArrayCopy(V_ARRAY(pSource
), V_ARRAYREF(pDest
)) == NOERROR
;
673 switch (V_VT(pSource
))
677 *V_I2REF(pDest
) = V_I2(pSource
);
682 *V_I4REF(pDest
) = V_I4(pSource
);
686 *V_R4REF(pDest
) = V_R4(pSource
);
690 *V_R8REF(pDest
) = V_R8(pSource
);
694 *V_CYREF(pDest
) = V_CY(pSource
);
698 *V_DATEREF(pDest
) = V_DATE(pSource
);
702 SysFreeString( *pDest
->pbstrVal
);
704 *V_BSTRREF(pDest
) = SysAllocString(V_BSTR(pSource
));
708 if (*V_DISPATCHREF(pDest
) != NULL
)
709 (*V_DISPATCHREF(pDest
))->Release();
711 *V_DISPATCHREF(pDest
) = V_DISPATCH(pSource
);
713 if (*V_DISPATCHREF(pDest
) != NULL
)
714 (*V_DISPATCHREF(pDest
))->AddRef();
719 *V_ERRORREF(pDest
) = V_ERROR(pSource
);
723 *V_BOOLREF(pDest
) = V_BOOL(pSource
);
727 if (*V_UNKNOWNREF(pDest
) != NULL
)
728 (*V_UNKNOWNREF(pDest
))->Release();
730 *V_UNKNOWNREF(pDest
) = V_UNKNOWN(pSource
);
732 if (*V_UNKNOWNREF(pDest
) != NULL
)
733 (*V_UNKNOWNREF(pDest
))->AddRef();
738 *V_I1REF(pDest
) = V_I1(pSource
);
742 *V_UI1REF(pDest
) = V_UI1(pSource
);
746 *V_UI2REF(pDest
) = V_UI2(pSource
);
750 *V_UI4REF(pDest
) = V_UI4(pSource
);
754 *V_INTREF(pDest
) = V_INT(pSource
);
758 *V_UINTREF(pDest
) = V_UINT(pSource
);
762 memcpy(pDest
->pdecVal
, pSource
, sizeof(DECIMAL
));
772 // Handling of special cases
773 // Destination and source types are different
774 if( pDest
->vt
== (VT_BSTR
| VT_BYREF
)
775 && pSource
->vt
== VT_I2
)
777 // When the user provides a String as out our in/out parameter
778 // and the type is char (TypeClass_CHAR) then we convert to a BSTR
779 // instead of VT_I2 as is done otherwise
780 OLECHAR buff
[]= {0,0};
781 buff
[0]= pSource
->iVal
;
783 SysFreeString( *pDest
->pbstrVal
);
784 *pDest
->pbstrVal
= SysAllocString( buff
);
793 STDMETHODIMP
InterfaceOleWrapper_Impl::Invoke(DISPID dispidMember
,
796 unsigned short wFlags
,
797 DISPPARAMS
* pdispparams
,
798 VARIANT
* pvarResult
,
799 EXCEPINFO
* pexcepinfo
,
800 unsigned int * puArgErr
)
806 sal_Bool bHandled
= sal_False
;
807 ret
= InvokeGeneral( dispidMember
, wFlags
, pdispparams
, pvarResult
, pexcepinfo
,
812 if ((dispidMember
> 0) && ((size_t)dispidMember
<= m_MemberInfos
.size()) && m_xInvocation
.is())
814 MemberInfo d
= m_MemberInfos
[dispidMember
- 1];
815 DWORD flags
= wFlags
& d
.flags
;
819 if ((flags
& DISPATCH_METHOD
) != 0)
821 if (pdispparams
->cNamedArgs
> 0)
822 ret
= DISP_E_NONAMEDARGS
;
825 Sequence
<Any
> params
;
827 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
829 ret
= doInvoke(pdispparams
, pvarResult
,
830 pexcepinfo
, puArgErr
, d
.name
, params
);
833 else if ((flags
& DISPATCH_PROPERTYGET
) != 0)
835 ret
= doGetProperty( pdispparams
, pvarResult
,
838 else if ((flags
& DISPATCH_PROPERTYPUT
|| flags
& DISPATCH_PROPERTYPUTREF
) != 0)
840 if (pdispparams
->cArgs
!= 1)
841 ret
= DISP_E_BADPARAMCOUNT
;
844 Sequence
<Any
> params
;
845 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
846 if(params
.getLength() > 0)
847 ret
= doSetProperty( pdispparams
, pvarResult
, pexcepinfo
, puArgErr
, d
.name
, params
);
849 ret
= DISP_E_BADVARTYPE
;
854 ret
= DISP_E_MEMBERNOTFOUND
;
857 ret
= DISP_E_MEMBERNOTFOUND
;
859 catch(const BridgeRuntimeError
& e
)
861 writeExcepinfo(pexcepinfo
, e
.message
);
862 ret
= DISP_E_EXCEPTION
;
864 catch(const Exception
& e
)
866 OUString message
= "InterfaceOleWrapper_Impl::Invoke : \n" +
868 writeExcepinfo(pexcepinfo
, message
);
869 ret
= DISP_E_EXCEPTION
;
873 OUString message
= "InterfaceOleWrapper_Impl::Invoke : \n"
874 "Unexpected exception";
875 writeExcepinfo(pexcepinfo
, message
);
876 ret
= DISP_E_EXCEPTION
;
882 HRESULT
InterfaceOleWrapper_Impl::doInvoke( DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
,
883 EXCEPINFO
* pexcepinfo
, unsigned int * puArgErr
, OUString
& name
, Sequence
<Any
>& params
)
890 Sequence
<sal_Int16
> outIndex
;
891 Sequence
<Any
> outParams
;
894 if (pdispparams
->cNamedArgs
> 0)
895 return DISP_E_NONAMEDARGS
;
897 // invoke method and take care of exceptions
898 returnValue
= m_xInvocation
->invoke(name
,
903 // try to write back out parameter
904 if (outIndex
.getLength() > 0)
906 const sal_Int16
* pOutIndex
= outIndex
.getConstArray();
907 const Any
* pOutParams
= outParams
.getConstArray();
909 for (sal_Int32 i
= 0; i
< outIndex
.getLength(); i
++)
912 // Currently a Sequence is converted to an SafeArray of VARIANTs.
913 anyToVariant( &variant
, pOutParams
[i
]);
915 // out parameter need special handling if they are VT_DISPATCH
916 // and used in JScript
917 int outindex
= pOutIndex
[i
];
918 writeBackOutParameter2(&(pdispparams
->rgvarg
[pdispparams
->cArgs
- 1 - outindex
]),
923 // write back return value
924 if (pvarResult
!= NULL
)
925 anyToVariant(pvarResult
, returnValue
);
927 catch(const IllegalArgumentException
& e
) //XInvocation::invoke
929 writeExcepinfo(pexcepinfo
, e
.Message
);
930 ret
= DISP_E_TYPEMISMATCH
;
932 catch(const CannotConvertException
& e
) //XInvocation::invoke
934 writeExcepinfo(pexcepinfo
, e
.Message
);
935 ret
= mapCannotConvertException( e
, puArgErr
);
937 catch(const InvocationTargetException
& e
) //XInvocation::invoke
939 const Any
& org
= e
.TargetException
;
943 org
.getValueType().getTypeName() + ": " + excTarget
.Message
;
944 writeExcepinfo(pexcepinfo
, message
);
945 ret
= DISP_E_EXCEPTION
;
947 catch(const NoSuchMethodException
& e
) //XInvocation::invoke
949 writeExcepinfo(pexcepinfo
, e
.Message
);
950 ret
= DISP_E_MEMBERNOTFOUND
;
952 catch(const BridgeRuntimeError
& e
)
954 writeExcepinfo(pexcepinfo
, e
.message
);
955 ret
= DISP_E_EXCEPTION
;
957 catch(const Exception
& e
)
959 OUString message
= "InterfaceOleWrapper_Impl::doInvoke : \n" +
961 writeExcepinfo(pexcepinfo
, message
);
962 ret
= DISP_E_EXCEPTION
;
966 OUString message
= "InterfaceOleWrapper_Impl::doInvoke : \n"
967 "Unexpected exception";
968 writeExcepinfo(pexcepinfo
, message
);
969 ret
= DISP_E_EXCEPTION
;
974 HRESULT
InterfaceOleWrapper_Impl::doGetProperty( DISPPARAMS
* /*pdispparams*/, VARIANT
* pvarResult
,
975 EXCEPINFO
* pexcepinfo
, OUString
& name
)
982 Any returnValue
= m_xInvocation
->getValue( name
);
983 // write back return value
985 anyToVariant(pvarResult
, returnValue
);
987 catch(const UnknownPropertyException
& e
) //XInvocation::getValue
989 writeExcepinfo(pexcepinfo
, e
.Message
);
990 ret
= DISP_E_MEMBERNOTFOUND
;
992 catch(const BridgeRuntimeError
& e
)
994 writeExcepinfo(pexcepinfo
, e
.message
);
995 ret
= DISP_E_EXCEPTION
;
997 catch(const Exception
& e
)
999 OUString message
= "InterfaceOleWrapper_Impl::doGetProperty : \n" +
1001 writeExcepinfo(pexcepinfo
, message
);
1005 OUString message
= "InterfaceOleWrapper_Impl::doInvoke : \n"
1006 "Unexpected exception";
1007 writeExcepinfo(pexcepinfo
, message
);
1008 ret
= DISP_E_EXCEPTION
;
1013 HRESULT
InterfaceOleWrapper_Impl::doSetProperty( DISPPARAMS
* /*pdispparams*/, VARIANT
* /*pvarResult*/,
1014 EXCEPINFO
* pexcepinfo
, unsigned int * puArgErr
, OUString
& name
, Sequence
<Any
> params
)
1020 m_xInvocation
->setValue( name
, params
.getConstArray()[0]);
1022 catch(const UnknownPropertyException
&)
1024 ret
= DISP_E_MEMBERNOTFOUND
;
1026 catch(const CannotConvertException
&e
)
1028 ret
= mapCannotConvertException( e
, puArgErr
);
1030 catch(const InvocationTargetException
&e
)
1032 if (pexcepinfo
!= NULL
)
1034 Any org
= e
.TargetException
;
1036 pexcepinfo
->wCode
= UNO_2_OLE_EXCEPTIONCODE
;
1037 pexcepinfo
->bstrSource
= SysAllocString(L
"any ONE component");
1038 pexcepinfo
->bstrDescription
= SysAllocString(
1039 reinterpret_cast<LPCOLESTR
>(org
.getValueType().getTypeName().getStr()));
1041 ret
= DISP_E_EXCEPTION
;
1045 ret
= DISP_E_EXCEPTION
;
1050 HRESULT
InterfaceOleWrapper_Impl::InvokeGeneral( DISPID dispidMember
, unsigned short wFlags
,
1051 DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
, EXCEPINFO
* pexcepinfo
,
1052 unsigned int * /*puArgErr*/, sal_Bool
& bHandled
)
1057 // DISPID_VALUE | The DEFAULT Value is required in JScript when the situation
1058 // is that we put an object into an Array object ( out parameter). We have to return
1059 // IDispatch otherwise the object cannot be accessed from the Script.
1060 if( dispidMember
== DISPID_VALUE
&& wFlags
== DISPATCH_PROPERTYGET
1061 && m_defaultValueType
!= VT_EMPTY
&& pvarResult
!= NULL
)
1064 if( m_defaultValueType
== VT_DISPATCH
)
1066 pvarResult
->vt
= VT_DISPATCH
;
1067 pvarResult
->pdispVal
= static_cast<IDispatch
*>( this);
1073 // function: _GetValueObject
1074 else if( dispidMember
== DISPID_JSCRIPT_VALUE_FUNC
)
1079 CComObject
< JScriptValue
>* pValue
;
1080 if( SUCCEEDED( CComObject
<JScriptValue
>::CreateInstance( &pValue
)))
1083 pvarResult
->vt
= VT_DISPATCH
;
1085 pvarResult
->pdispVal
= CComQIPtr
<IDispatch
, &__uuidof(IDispatch
)>(pValue
->GetUnknown());
1087 pvarResult
->pdispVal
= CComQIPtr
<IDispatch
>(pValue
->GetUnknown());
1092 ret
= DISP_E_EXCEPTION
;
1094 else if( dispidMember
== DISPID_GET_STRUCT_FUNC
)
1097 sal_Bool bStruct
= sal_False
;
1100 Reference
<XIdlReflection
> xRefl
= theCoreReflection::get(comphelper::getComponentContext(m_smgr
));
1101 // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1103 if( pdispparams
->cArgs
== 1 && SUCCEEDED( arg
.ChangeType( VT_BSTR
, &pdispparams
->rgvarg
[0])) )
1105 Reference
<XIdlClass
> classStruct
= xRefl
->forName( reinterpret_cast<const sal_Unicode
*>(arg
.bstrVal
));
1106 if( classStruct
.is())
1109 classStruct
->createObject( anyStruct
);
1111 anyToVariant( &var
, anyStruct
);
1113 if( var
.vt
== VT_DISPATCH
)
1115 VariantCopy( pvarResult
, & var
);
1120 ret
= bStruct
== sal_True
? S_OK
: DISP_E_EXCEPTION
;
1122 else if (dispidMember
== DISPID_CREATE_TYPE_FUNC
)
1127 // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1129 if( pdispparams
->cArgs
!= 1)
1130 return DISP_E_BADPARAMCOUNT
;
1131 if (FAILED( arg
.ChangeType( VT_BSTR
, &pdispparams
->rgvarg
[0])))
1132 return DISP_E_BADVARTYPE
;
1134 //check if the provided name represents a valid type
1136 if (getType(arg
.bstrVal
, type
) == false)
1138 writeExcepinfo(pexcepinfo
,OUString(
1139 "[automation bridge] A UNO type with the name " +
1140 OUString(reinterpret_cast<const sal_Unicode
*>(arg
.bstrVal
)) + " does not exist!"));
1141 return DISP_E_EXCEPTION
;
1144 if (createUnoTypeWrapper(arg
.bstrVal
, pvarResult
) == false)
1146 writeExcepinfo(pexcepinfo
, "[automation bridge] InterfaceOleWrapper_Impl::InvokeGeneral\n"
1147 "Could not initialize UnoTypeWrapper object!");
1148 return DISP_E_EXCEPTION
;
1152 catch(const BridgeRuntimeError
& e
)
1154 writeExcepinfo(pexcepinfo
, e
.message
);
1155 ret
= DISP_E_EXCEPTION
;
1157 catch(const Exception
& e
)
1159 OUString message
= "InterfaceOleWrapper_Impl::InvokeGeneral : \n" +
1161 writeExcepinfo(pexcepinfo
, message
);
1162 ret
= DISP_E_EXCEPTION
;
1166 OUString message
= "InterfaceOleWrapper_Impl::InvokeGeneral : \n"
1167 "Unexpected exception";
1168 writeExcepinfo(pexcepinfo
, message
);
1169 ret
= DISP_E_EXCEPTION
;
1174 STDMETHODIMP
InterfaceOleWrapper_Impl::GetDispID(BSTR
/*bstrName*/, DWORD
/*grfdex*/, DISPID __RPC_FAR
* /*pid*/)
1176 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1181 STDMETHODIMP
InterfaceOleWrapper_Impl::InvokeEx(
1182 /* [in] */ DISPID
/*id*/,
1183 /* [in] */ LCID
/*lcid*/,
1184 /* [in] */ WORD
/*wFlags*/,
1185 /* [in] */ DISPPARAMS __RPC_FAR
* /*pdp*/,
1186 /* [out] */ VARIANT __RPC_FAR
* /*pvarRes*/,
1187 /* [out] */ EXCEPINFO __RPC_FAR
* /*pei*/,
1188 /* [unique][in] */ IServiceProvider __RPC_FAR
* /*pspCaller*/)
1190 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1195 STDMETHODIMP
InterfaceOleWrapper_Impl::DeleteMemberByName(
1196 /* [in] */ BSTR
/*bstr*/,
1197 /* [in] */ DWORD
/*grfdex*/)
1199 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1204 STDMETHODIMP
InterfaceOleWrapper_Impl::DeleteMemberByDispID(DISPID
/*id*/)
1206 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1211 STDMETHODIMP
InterfaceOleWrapper_Impl::GetMemberProperties(
1212 /* [in] */ DISPID
/*id*/,
1213 /* [in] */ DWORD
/*grfdexFetch*/,
1214 /* [out] */ DWORD __RPC_FAR
* /*pgrfdex*/)
1216 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1221 STDMETHODIMP
InterfaceOleWrapper_Impl::GetMemberName(
1222 /* [in] */ DISPID
/*id*/,
1223 /* [out] */ BSTR __RPC_FAR
* /*pbstrName*/)
1225 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1230 STDMETHODIMP
InterfaceOleWrapper_Impl::GetNextDispID(
1231 /* [in] */ DWORD
/*grfdex*/,
1232 /* [in] */ DISPID
/*id*/,
1233 /* [out] */ DISPID __RPC_FAR
* /*pid*/)
1235 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1240 STDMETHODIMP
InterfaceOleWrapper_Impl::GetNameSpaceParent(
1241 /* [out] */ IUnknown __RPC_FAR
*__RPC_FAR
* /*ppunk*/)
1243 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1248 // UnoObjectWrapperRemoteOpt ---------------------------------------------------
1250 UnoObjectWrapperRemoteOpt::UnoObjectWrapperRemoteOpt( Reference
<XMultiServiceFactory
>& aFactory
,
1251 sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
1252 InterfaceOleWrapper_Impl( aFactory
, unoWrapperClass
, comWrapperClass
),
1257 UnoObjectWrapperRemoteOpt::~UnoObjectWrapperRemoteOpt()
1261 // UnoConversionUtilities
1262 Reference
< XInterface
> UnoObjectWrapperRemoteOpt::createUnoWrapperInstance()
1264 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
1265 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
1266 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
1269 STDMETHODIMP
UnoObjectWrapperRemoteOpt::GetIDsOfNames ( REFIID
/*riid*/, OLECHAR
** rgszNames
, unsigned int cNames
,
1270 LCID
/*lcid*/, DISPID
* rgdispid
)
1272 MutexGuard
guard( getBridgeMutex());
1276 HRESULT ret
= E_UNEXPECTED
;
1279 if( ! wcscmp( *rgszNames
, JSCRIPT_VALUE_FUNC
))
1281 *rgdispid
= DISPID_JSCRIPT_VALUE_FUNC
;
1284 else if( ! wcscmp( *rgszNames
, GET_STRUCT_FUNC
))
1286 *rgdispid
= DISPID_GET_STRUCT_FUNC
;
1290 if (m_xInvocation
.is() && (cNames
> 0))
1292 OUString
name(reinterpret_cast<const sal_Unicode
*>(rgszNames
[0]));
1293 // has this name been determined as "bad"
1294 BadNameMap::iterator badIter
= m_badNameMap
.find( name
);
1295 if( badIter
== m_badNameMap
.end() )
1297 // name has not been bad before( member exists
1298 typedef NameToIdMap::iterator ITnames
;
1299 pair
< ITnames
, bool > pair_id
= m_nameToDispIdMap
.insert( NameToIdMap::value_type(name
, m_currentId
++));
1300 // new ID inserted ?
1301 if( pair_id
.second
)
1302 {// yes, now create MemberInfo and ad to IdToMemberInfoMap
1303 MemberInfo
d(0, name
);
1304 m_idToMemberInfoMap
.insert( IdToMemberInfoMap::value_type( m_currentId
- 1, d
));
1307 *rgdispid
= pair_id
.first
->second
;
1311 ret
= DISP_E_UNKNOWNNAME
;
1316 STDMETHODIMP
UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember
, REFIID
/*riid*/, LCID
/*lcid*/, unsigned short wFlags
,
1317 DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
, EXCEPINFO
* pexcepinfo
,
1318 unsigned int * puArgErr
)
1323 sal_Bool bHandled
= sal_False
;
1324 ret
= InvokeGeneral( dispidMember
, wFlags
, pdispparams
, pvarResult
, pexcepinfo
,
1325 puArgErr
, bHandled
);
1329 if ( dispidMember
> 0 && m_xInvocation
.is())
1332 IdToMemberInfoMap::iterator it_MemberInfo
= m_idToMemberInfoMap
.find( dispidMember
);
1333 if( it_MemberInfo
!= m_idToMemberInfoMap
.end() )
1335 MemberInfo
& info
= it_MemberInfo
->second
;
1337 Sequence
<Any
> params
; // holds converted any s
1339 { // DISPID called for the first time
1340 if( wFlags
== DISPATCH_METHOD
)
1342 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1344 if( FAILED( ret
= doInvoke( pdispparams
, pvarResult
,
1345 pexcepinfo
, puArgErr
, info
.name
, params
))
1346 && ret
== DISP_E_MEMBERNOTFOUND
)
1348 // try to get the exact name
1350 if (m_xExactName
.is())
1352 exactName
= m_xExactName
->getExactName( info
.name
);
1354 if( !exactName
.isEmpty() )
1356 if( SUCCEEDED( ret
= doInvoke( pdispparams
, pvarResult
,
1357 pexcepinfo
, puArgErr
, exactName
, params
)))
1358 info
.name
= exactName
;
1362 if( SUCCEEDED( ret
) )
1363 info
.flags
= DISPATCH_METHOD
;
1365 else if( wFlags
== DISPATCH_PROPERTYPUT
|| wFlags
== DISPATCH_PROPERTYPUTREF
)
1367 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1368 if( FAILED( ret
= doSetProperty( pdispparams
, pvarResult
,
1369 pexcepinfo
, puArgErr
, info
.name
, params
))
1370 && ret
== DISP_E_MEMBERNOTFOUND
)
1372 // try to get the exact name
1374 if (m_xExactName
.is())
1376 exactName
= m_xExactName
->getExactName( info
.name
);
1378 if( !exactName
.isEmpty() )
1380 if( SUCCEEDED( ret
= doSetProperty( pdispparams
, pvarResult
,
1381 pexcepinfo
, puArgErr
, exactName
, params
)))
1382 info
.name
= exactName
;
1386 if( SUCCEEDED( ret
) )
1387 info
.flags
= DISPATCH_PROPERTYPUT
| DISPATCH_PROPERTYGET
;
1389 else if( wFlags
== DISPATCH_PROPERTYGET
)
1391 if( FAILED( ret
= doGetProperty( pdispparams
, pvarResult
,
1392 pexcepinfo
, info
.name
))
1393 && ret
== DISP_E_MEMBERNOTFOUND
)
1395 // try to get the exact name
1397 if (m_xExactName
.is())
1399 exactName
= m_xExactName
->getExactName( info
.name
);
1401 if( !exactName
.isEmpty() )
1403 if( SUCCEEDED( ret
= doGetProperty( pdispparams
, pvarResult
,
1404 pexcepinfo
, exactName
)))
1405 info
.name
= exactName
;
1409 if( SUCCEEDED( ret
) )
1410 info
.flags
= DISPATCH_PROPERTYGET
| DISPATCH_PROPERTYPUT
;
1412 else if( wFlags
& DISPATCH_METHOD
&&
1413 (wFlags
& DISPATCH_PROPERTYPUT
|| wFlags
& DISPATCH_PROPERTYPUTREF
))
1417 // convert params for DISPATCH_METHOD or DISPATCH_PROPERTYPUT
1418 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1419 // try first as method
1420 if( FAILED( ret
= doInvoke( pdispparams
, pvarResult
,
1421 pexcepinfo
, puArgErr
, info
.name
, params
))
1422 && ret
== DISP_E_MEMBERNOTFOUND
)
1424 // try to get the exact name
1425 if (m_xExactName
.is())
1427 exactName
= m_xExactName
->getExactName( info
.name
);
1429 if( !exactName
.isEmpty() )
1431 if( SUCCEEDED( ret
= doInvoke( pdispparams
, pvarResult
,
1432 pexcepinfo
, puArgErr
, exactName
, params
)))
1433 info
.name
= exactName
;
1437 if( SUCCEEDED( ret
) )
1438 info
.flags
= DISPATCH_METHOD
;
1441 if( FAILED( ret
) && pdispparams
->cArgs
== 1)
1443 if( FAILED( ret
= doSetProperty( pdispparams
, pvarResult
,
1444 pexcepinfo
, puArgErr
, info
.name
, params
))
1445 && ret
== DISP_E_MEMBERNOTFOUND
)
1447 // try to get the exact name
1448 if( !exactName
.isEmpty() )
1450 if( SUCCEEDED( ret
= doSetProperty( pdispparams
, pvarResult
,
1451 pexcepinfo
, puArgErr
, exactName
, params
)))
1452 info
.name
= exactName
;
1455 if( SUCCEEDED( ret
) )
1456 info
.flags
= DISPATCH_PROPERTYPUT
| DISPATCH_PROPERTYGET
;
1459 else if( wFlags
& DISPATCH_METHOD
&& wFlags
& DISPATCH_PROPERTYGET
)
1462 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1464 if( FAILED( ret
= doInvoke( pdispparams
, pvarResult
,
1465 pexcepinfo
, puArgErr
, info
.name
, params
))
1466 && ret
== DISP_E_MEMBERNOTFOUND
)
1468 // try to get the exact name
1469 if (m_xExactName
.is())
1471 exactName
= m_xExactName
->getExactName( info
.name
);
1473 if( !exactName
.isEmpty() )
1475 if( SUCCEEDED( ret
= doInvoke( pdispparams
, pvarResult
,
1476 pexcepinfo
, puArgErr
, exactName
, params
)))
1477 info
.name
= exactName
;
1481 if( SUCCEEDED( ret
) )
1482 info
.flags
= DISPATCH_METHOD
;
1485 if( FAILED( ret
) && pdispparams
->cArgs
== 1)
1487 if( FAILED( ret
= doGetProperty( pdispparams
, pvarResult
,
1488 pexcepinfo
, info
.name
))
1489 && ret
== DISP_E_MEMBERNOTFOUND
)
1491 if( !exactName
.isEmpty() )
1493 if( SUCCEEDED( ret
= doSetProperty( pdispparams
, pvarResult
,
1494 pexcepinfo
, puArgErr
, exactName
, params
)))
1495 info
.name
= exactName
;
1498 if( SUCCEEDED( ret
) )
1499 info
.flags
= DISPATCH_PROPERTYGET
;
1503 // update information about this member
1504 if( ret
== DISP_E_MEMBERNOTFOUND
)
1506 // Remember the name as not existing
1507 // and remove the MemberInfo
1508 m_badNameMap
[info
.name
]= sal_False
;
1509 m_idToMemberInfoMap
.erase( it_MemberInfo
);
1511 } // if( ! info.flags )
1512 else // IdToMemberInfoMap contains a MemberInfo
1514 if( wFlags
& DISPATCH_METHOD
&& info
.flags
== DISPATCH_METHOD
)
1516 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1517 ret
= doInvoke( pdispparams
, pvarResult
,
1518 pexcepinfo
, puArgErr
, info
.name
, params
);
1520 else if( (wFlags
& DISPATCH_PROPERTYPUT
|| wFlags
& DISPATCH_PROPERTYPUTREF
) &&
1521 info
.flags
& DISPATCH_PROPERTYPUT
)
1523 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1524 ret
= doSetProperty( pdispparams
, pvarResult
,
1525 pexcepinfo
, puArgErr
, info
.name
, params
);
1527 else if( (wFlags
& DISPATCH_PROPERTYGET
) && ( info
.flags
& DISPATCH_PROPERTYGET
))
1529 ret
= doGetProperty( pdispparams
, pvarResult
,
1530 pexcepinfo
, info
.name
);
1534 ret
= DISP_E_MEMBERNOTFOUND
;
1537 }// if( it_MemberInfo != m_idToMemberInfoMap.end() )
1539 ret
= DISP_E_MEMBERNOTFOUND
;
1542 catch(const BridgeRuntimeError
& e
)
1544 writeExcepinfo(pexcepinfo
, e
.message
);
1545 ret
= DISP_E_EXCEPTION
;
1547 catch(const Exception
& e
)
1549 OUString message
= "UnoObjectWrapperRemoteOpt::Invoke : \n" +
1551 writeExcepinfo(pexcepinfo
, message
);
1552 ret
= DISP_E_EXCEPTION
;
1556 OUString message
= "UnoObjectWrapperRemoteOpt::Invoke : \n"
1557 "Unexpected exception";
1558 writeExcepinfo(pexcepinfo
, message
);
1559 ret
= DISP_E_EXCEPTION
;
1565 HRESULT
UnoObjectWrapperRemoteOpt::methodInvoke( DISPID
/*dispidMember*/, DISPPARAMS
* /*pdispparams*/, VARIANT
* /*pvarResult*/,
1566 EXCEPINFO
* /*pexcepinfo*/, unsigned int * /*puArgErr*/, Sequence
<Any
> params
)
1571 // The returned HRESULT is only appropriate for IDispatch::Invoke
1572 static HRESULT
mapCannotConvertException(const CannotConvertException
&e
, unsigned int * puArgErr
)
1575 sal_Bool bWriteIndex
= sal_True
;
1579 case FailReason::OUT_OF_RANGE
:
1580 ret
= DISP_E_OVERFLOW
;
1582 case FailReason::IS_NOT_NUMBER
:
1583 ret
= DISP_E_TYPEMISMATCH
;
1585 case FailReason::IS_NOT_ENUM
:
1586 ret
= DISP_E_TYPEMISMATCH
;
1588 case FailReason::IS_NOT_BOOL
:
1589 ret
= DISP_E_TYPEMISMATCH
;
1591 case FailReason::NO_SUCH_INTERFACE
:
1592 ret
= DISP_E_TYPEMISMATCH
;
1594 case FailReason::SOURCE_IS_NO_DERIVED_TYPE
:
1595 ret
= DISP_E_TYPEMISMATCH
;
1597 case FailReason::TYPE_NOT_SUPPORTED
:
1598 ret
= DISP_E_TYPEMISMATCH
;
1600 case FailReason::INVALID
:
1601 ret
= DISP_E_TYPEMISMATCH
;
1603 case FailReason::NO_DEFAULT_AVAILABLE
:
1604 ret
= DISP_E_BADPARAMCOUNT
;
1606 case FailReason::UNKNOWN
:
1611 bWriteIndex
= sal_False
;
1615 if( bWriteIndex
&& puArgErr
!= NULL
)
1616 *puArgErr
= e
.ArgumentIndex
;
1620 // The function maps the TypeClass of the any to VARTYPE: If
1621 // the Any contains STRUCT or INTERFACE then the return value
1622 // is VT_DISPATCH. The function is used from o2u_createUnoObjectWrapper
1623 // and the result is put into the constructor of the uno - wrapper
1624 // object. If a client asks the object for DISPID_VALUE and this
1625 // function returned VT_DISPATCH then the IDispatch of the same
1626 // object is being returned.
1627 // See InterfaceOleWrapper_Impl::Invoke, InterfaceOleWrapper_Impl::m_defaultValueType
1628 const VARTYPE
getVarType( const Any
& value
)
1630 VARTYPE ret
= VT_EMPTY
;
1632 switch ( value
.getValueTypeClass())
1634 case TypeClass_STRUCT
: ret
= VT_DISPATCH
; break;
1635 case TypeClass_INTERFACE
: ret
= VT_DISPATCH
; break;
1643 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */