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"
21 #if _WIN32_WINNT != 0x403
22 #error wrong _WIN32_WINNT
27 #include <boost/unordered_map.hpp>
30 #include <osl/diagnose.h>
31 #include <salhelper/simplereferenceobject.hxx>
32 #include <rtl/ustring.hxx>
33 #include <com/sun/star/beans/MethodConcept.hpp>
34 #include <com/sun/star/beans/PropertyConcept.hpp>
35 #include <com/sun/star/script/FailReason.hpp>
36 #include <com/sun/star/reflection/theCoreReflection.hpp>
37 #include <com/sun/star/reflection/ParamInfo.hpp>
38 #include <com/sun/star/beans/XExactName.hpp>
39 #include <com/sun/star/container/NoSuchElementException.hpp>
41 #include <com/sun/star/beans/XMaterialHolder.hpp>
42 #include <com/sun/star/script/XInvocation2.hpp>
43 #include <com/sun/star/script/MemberType.hpp>
44 #include <com/sun/star/reflection/XIdlReflection.hpp>
45 #include <osl/interlck.h>
46 #include <com/sun/star/uno/genfunc.h>
47 #include <comphelper/processfactory.hxx>
48 #include <cppuhelper/implbase1.hxx>
50 #include "comifaces.hxx"
51 #include "jscriptclasses.hxx"
52 #include "unotypewrapper.hxx"
53 #include "oleobjw.hxx"
54 #include "unoobjw.hxx"
55 #include "servprov.hxx"
60 using namespace com::sun::star::uno
;
61 using namespace com::sun::star::beans
;
62 using namespace com::sun::star::container
;
63 using namespace com::sun::star::script
;
64 using namespace com::sun::star::lang
;
65 using namespace com::sun::star::bridge::ModelDependent
;
66 using namespace com::sun::star::reflection
;
70 extern "C" const GUID IID_IDispatchEx
;
75 boost::unordered_map
<sal_uInt32
, WeakReference
<XInterface
> > UnoObjToWrapperMap
;
76 static sal_Bool
writeBackOutParameter(VARIANTARG
* pDest
, VARIANT
* pSource
);
77 static sal_Bool
writeBackOutParameter2( VARIANTARG
* pDest
, VARIANT
* pSource
);
78 static HRESULT
mapCannotConvertException(const CannotConvertException
&e
, unsigned int * puArgErr
);
81 /* Does not throw any exceptions.
82 Param pInfo can be NULL.
84 static void writeExcepinfo(EXCEPINFO
* pInfo
, const OUString
& message
)
88 pInfo
->wCode
= UNO_2_OLE_EXCEPTIONCODE
;
89 pInfo
->bstrSource
= SysAllocString(L
"[automation bridge] ");
90 pInfo
->bstrDescription
= SysAllocString(reinterpret_cast<LPCOLESTR
>(message
.getStr()));
94 /*****************************************************************************
96 class implementation: InterfaceOleWrapper_Impl
98 *****************************************************************************/
99 InterfaceOleWrapper_Impl::InterfaceOleWrapper_Impl( Reference
<XMultiServiceFactory
>& xFactory
,
100 sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
101 m_defaultValueType( 0),
102 UnoConversionUtilities
<InterfaceOleWrapper_Impl
>( xFactory
, unoWrapperClass
, comWrapperClass
)
106 InterfaceOleWrapper_Impl::~InterfaceOleWrapper_Impl()
108 MutexGuard
guard(getBridgeMutex());
109 // remove entries in global map
110 IT_Uno it
= UnoObjToWrapperMap
.find( (sal_uInt32
) m_xOrigin
.get());
111 if(it
!= UnoObjToWrapperMap
.end())
112 UnoObjToWrapperMap
.erase(it
);
113 #if OSL_DEBUG_LEVEL > 0
114 fprintf(stderr
,"[automation bridge] UnoObjToWrapperMap contains: %i \n",
115 UnoObjToWrapperMap
.size());
120 STDMETHODIMP
InterfaceOleWrapper_Impl::QueryInterface(REFIID riid
, LPVOID FAR
* ppv
)
127 if(IsEqualIID(riid
, IID_IUnknown
))
130 *ppv
= (IUnknown
*) (IDispatch
*) this;
132 else if (IsEqualIID(riid
, IID_IDispatch
))
135 *ppv
= (IDispatch
*) this;
137 else if( IsEqualIID( riid
, __uuidof( IUnoObjectWrapper
)))
140 *ppv
= (IUnoObjectWrapper
*) this;
147 STDMETHODIMP_(ULONG
) InterfaceOleWrapper_Impl::AddRef()
150 // does not need to guard because one should not rely on the return value of
155 STDMETHODIMP_(ULONG
) InterfaceOleWrapper_Impl::Release()
162 // IUnoObjectWrapper --------------------------------------------------------
163 STDMETHODIMP
InterfaceOleWrapper_Impl::getWrapperXInterface( Reference
<XInterface
>* pXInt
)
165 *pXInt
= Reference
<XInterface
>( static_cast<XWeak
*>( this), UNO_QUERY
);
166 return pXInt
->is() ? S_OK
: E_FAIL
;
168 STDMETHODIMP
InterfaceOleWrapper_Impl::getOriginalUnoObject( Reference
<XInterface
>* pXInt
)
171 return m_xOrigin
.is() ? S_OK
: E_FAIL
;
173 STDMETHODIMP
InterfaceOleWrapper_Impl::getOriginalUnoStruct( Any
* pStruct
)
178 Reference
<XMaterialHolder
> xMatHolder( m_xInvocation
, UNO_QUERY
);
181 Any any
= xMatHolder
->getMaterial();
182 if( any
.getValueTypeClass() == TypeClass_STRUCT
)
192 STDMETHODIMP
InterfaceOleWrapper_Impl::GetTypeInfoCount( unsigned int * /*pctinfo*/ )
197 STDMETHODIMP
InterfaceOleWrapper_Impl::GetTypeInfo(unsigned int /*itinfo*/, LCID
/*lcid*/, ITypeInfo
** /*pptinfo*/)
202 STDMETHODIMP
InterfaceOleWrapper_Impl::GetIDsOfNames(REFIID
/*riid*/,
203 OLECHAR
** rgszNames
,
208 HRESULT ret
= DISP_E_UNKNOWNNAME
;
211 MutexGuard
guard( getBridgeMutex());
215 // ----------------------------------------
216 if( ! _wcsicmp( *rgszNames
, JSCRIPT_VALUE_FUNC
) ||
217 ! _wcsicmp( *rgszNames
, BRIDGE_VALUE_FUNC
))
219 *rgdispid
= DISPID_JSCRIPT_VALUE_FUNC
;
222 else if( ! _wcsicmp( *rgszNames
, GET_STRUCT_FUNC
) ||
223 ! _wcsicmp( *rgszNames
, BRIDGE_GET_STRUCT_FUNC
))
225 *rgdispid
= DISPID_GET_STRUCT_FUNC
;
228 else if( ! _wcsicmp( *rgszNames
, BRIDGE_CREATE_TYPE_FUNC
))
230 *rgdispid
= DISPID_CREATE_TYPE_FUNC
;
234 // ----------------------------------------
235 if (m_xInvocation
.is() && (cNames
> 0))
237 OUString
name(reinterpret_cast<const sal_Unicode
*>(rgszNames
[0]));
238 NameToIdMap::iterator iter
= m_nameToDispIdMap
.find(name
);
240 if (iter
== m_nameToDispIdMap
.end())
244 if (m_xExactName
.is())
246 exactName
= m_xExactName
->getExactName(name
);
253 MemberInfo
d(0, exactName
);
255 if (m_xInvocation
->hasProperty(exactName
))
257 d
.flags
|= DISPATCH_PROPERTYGET
;
258 d
.flags
|= DISPATCH_PROPERTYPUT
;
259 d
.flags
|= DISPATCH_PROPERTYPUTREF
;
262 if (m_xInvocation
->hasMethod(exactName
))
264 d
.flags
|= DISPATCH_METHOD
;
269 m_MemberInfos
.push_back(d
);
270 iter
= m_nameToDispIdMap
.insert(NameToIdMap::value_type(exactName
, (DISPID
)m_MemberInfos
.size())).first
;
272 if (exactName
!= name
)
274 iter
= m_nameToDispIdMap
.insert(NameToIdMap::value_type(name
, (DISPID
)m_MemberInfos
.size())).first
;
279 if (iter
== m_nameToDispIdMap
.end())
281 ret
= DISP_E_UNKNOWNNAME
;
285 *rgdispid
= (*iter
).second
;
290 catch(const BridgeRuntimeError
&)
294 catch(const Exception
&)
306 // "convertDispparamsArgs" converts VARIANTS to their respecting Any counterparts
307 // The parameters "id", "wFlags" and "pdispparams" equal those as used in
308 // IDispatch::Invoke. The function handles special JavaScript
309 // cases where a VARIANT of type VT_DISPATCH is ambiguous and could represent
310 // an object, array ( JavaScript Array object), out parameter and in/out ( JavaScript Array object)
311 // parameter (JavaScript Array object)
312 // Because all those VT_DISPATCH objects need a different conversion
313 // we have to find out what the object is supposed to be. The function does this
314 // by either using type information or by help of a specialized ValueObject object.
316 // A. Type Information
317 // -----------------------------------------------------------------------------
318 // With the help of type information the kind of parameter can be exactly determined
319 // and an appropriate conversion can be choosen. A problem arises if a method expects
320 // an Any. Then the type info does not tell what the type of the value, that is kept
321 // by the any, should be. In this situation the decision wheter the param is a
322 // sequence or an object is made upon the fact if the object has a property "0"
323 // ( see function "isJScriptArray"). Since this is unsafe it is recommended to use
324 // the JScript value objects within a JScript script on such an occasion.
326 // B. JavaScript Value Object ( class JScriptValue )
327 // -----------------------------------------------------------------------------
328 // A JScriptValue (ValueObject) object is a COM object in that it implements IDispatch and the
329 // IJScriptValue object interface. Such objects are provided by all UNO wrapper
330 // objects used within a JScript script. To obtain an instance one has to call
331 // "_GetValueObject() or Bridge_GetValueObject()" on an UNO wrapper object (class InterfaceOleWrapper_Impl).
332 // A value object is appropriately initialized within the script and passed as
333 // parameter to an UNO object method or property. The convertDispparamsArgs function
334 // can easily find out that a param is such an object by queriing for the
335 // IJScriptValue interface. By this interface one the type and kind ( out, in/out)
336 // can be determined and the right conversion can be applied.
337 // Using ValueObjects we spare us the effort of aquiring and examining type information
338 // in order to figure out what the an IDispatch parameter is meant for.
340 // Normal JScript object parameter can be mixed with JScriptValue object. If an
341 // VARIANT contains an VT_DISPATCH that is no JScriptValue than the type information
342 // is used to find out about the reqired type.
343 void InterfaceOleWrapper_Impl::convertDispparamsArgs(DISPID id
,
344 unsigned short /*wFlags*/, DISPPARAMS
* pdispparams
, Sequence
<Any
>& rSeq
)
347 sal_Int32 countArgs
= pdispparams
->cArgs
;
351 rSeq
.realloc( countArgs
);
352 Any
* pParams
= rSeq
.getArray();
356 //Get type information for the current call
358 if( ! getInvocationInfoForCall( id
, info
))
359 throw BridgeRuntimeError(
360 "[automation bridge]InterfaceOleWrapper_Impl::convertDispparamsArgs \n"
361 "Could not obtain type information for current call.");
363 for (int i
= 0; i
< countArgs
; i
++)
365 if (info
.eMemberType
== MemberType_METHOD
&&
366 info
.aParamModes
[ countArgs
- i
-1 ] == ParamMode_OUT
)
369 if(convertValueObject( & pdispparams
->rgvarg
[i
], anyParam
))
370 { //a param is a ValueObject and could be converted
371 pParams
[countArgs
- (i
+ 1)] = anyParam
;
375 // If the param is an out, in/out parameter in
376 // JScript (Array object, with value at index 0) then we
377 // extract Array[0] and put the value into varParam. At the end of the loop varParam
378 // is converted if it contains a value otherwise the VARIANT from
379 // DISPPARAMS is converted.
380 CComVariant varParam
;
382 // Check for JScript out and in/out paramsobjects (VT_DISPATCH).
383 // To find them out we use typeinformation of the function being called.
384 if( pdispparams
->rgvarg
[i
].vt
== VT_DISPATCH
)
386 if( info
.eMemberType
== MemberType_METHOD
&& info
.aParamModes
[ countArgs
- i
-1 ] == ParamMode_INOUT
)
389 // Index ( property) "0" contains the actual IN-param. The object is a JScript
391 // Get the IN-param at index "0"
392 IDispatch
* pdisp
= pdispparams
->rgvarg
[i
].pdispVal
;
394 OLECHAR
* sindex
= L
"0";
396 DISPPARAMS noParams
= {0,0,0,0};
397 if(SUCCEEDED( hr
= pdisp
->GetIDsOfNames( IID_NULL
, &sindex
, 1, LOCALE_USER_DEFAULT
, &id
)))
398 hr
= pdisp
->Invoke( id
, IID_NULL
, LOCALE_USER_DEFAULT
, DISPATCH_PROPERTYGET
,
399 & noParams
, & varParam
, NULL
, NULL
);
402 throw BridgeRuntimeError(
403 "[automation bridge] Could not determine "
404 "if the object has a member \"0\". Error: " +
405 OUString::valueOf(hr
));
410 if( varParam
.vt
== VT_EMPTY
) // then it was no in/out parameter
411 varParam
= pdispparams
->rgvarg
[i
];
413 if(info
.eMemberType
== MemberType_METHOD
)
414 variantToAny( & varParam
, anyParam
,
415 info
.aParamTypes
[ countArgs
- i
- 1]);
416 else if(info
.eMemberType
== MemberType_PROPERTY
)
417 variantToAny( & varParam
, anyParam
, info
.aType
);
421 pParams
[countArgs
- (i
+ 1)]= anyParam
;
422 }// end for / iterating over all parameters
425 sal_Bool
InterfaceOleWrapper_Impl::getInvocationInfoForCall( DISPID id
, InvocationInfo
& info
)
427 sal_Bool bTypesAvailable
= sal_False
;
429 if( !m_xInvocation
.is() )return false;
430 Reference
<XInvocation2
> inv2( m_xInvocation
, UNO_QUERY
);
433 // We need the name of the property or method to get its type information.
434 // The name can be identified through the param "id"
435 // that is kept as value in the map m_nameToDispIdMap.
436 // Proplem: the Windows JScript engine sometimes changes small letters to capital
437 // letters as happens in xidlclass_obj.createObject( var) // in JScript.
438 // IDispatch::GetIdsOfNames is then called with "CreateObject" !!!
439 // m_nameToDispIdMap can contain several names for one DISPID but only one is
440 // the exact one. If there's no m_xExactName and therefore no exact name then
441 // there's only one entry in the map.
442 typedef NameToIdMap::const_iterator cit
;
443 OUString sMemberName
;
445 for(cit ci1
= m_nameToDispIdMap
.begin(); ci1
!= m_nameToDispIdMap
.end(); ++ci1
)
447 if( (*ci1
).second
== id
) // iterator is a pair< OUString, DISPID>
449 sMemberName
= (*ci1
).first
;
453 // Get information for the current call ( property or method).
454 // There could be similar names which only differ in the cases
455 // of letters. First we assume that the name which was passed into
456 // GetIDsOfNames is correct. If we won't get information with that
457 // name then we have the invocation service use the XExactName interface.
458 sal_Bool validInfo
= sal_True
;
459 InvocationInfo invInfo
;
461 invInfo
= inv2
->getInfoForName( sMemberName
, sal_False
);
463 catch(const IllegalArgumentException
&)
465 validInfo
= sal_False
;
470 invInfo
= inv2
->getInfoForName( sMemberName
, sal_True
);
472 if( invInfo
.aName
.pData
)
474 bTypesAvailable
= sal_True
;
478 return bTypesAvailable
;
480 // XBridgeSupplier2 ---------------------------------------------------
481 // only bridges itself ( this instance of InterfaceOleWrapper_Impl)from UNO to IDispatch
482 // If sourceModelType is UNO than any UNO interface implemented by InterfaceOleWrapper_Impl
483 // can bridged to IDispatch ( if destModelType == OLE). The IDispatch is
484 // implemented by this class.
485 Any SAL_CALL
InterfaceOleWrapper_Impl::createBridge(const Any
& modelDepObject
,
486 const Sequence
<sal_Int8
>& /*ProcessId*/,
487 sal_Int16 sourceModelType
,
488 sal_Int16 destModelType
)
489 throw (IllegalArgumentException
, RuntimeException
)
493 if( sourceModelType
== UNO
&& destModelType
== OLE
&&
494 modelDepObject
.getValueTypeClass() == TypeClass_INTERFACE
)
496 Reference
<XInterface
> xInt
;
497 if( modelDepObject
>>= xInt
)
499 if( xInt
== Reference
<XInterface
>( static_cast<XWeak
*>( this), UNO_QUERY
))
501 VARIANT
*pVar
= (VARIANT
*)CoTaskMemAlloc( sizeof( VARIANT
));
504 pVar
->vt
= VT_DISPATCH
;
505 pVar
->pdispVal
= static_cast<IDispatch
*>( this);
508 retAny
<<= reinterpret_cast< sal_uInt32
>( pVar
);
518 // XInitialization --------------------------------------------------
519 void SAL_CALL
InterfaceOleWrapper_Impl::initialize( const Sequence
< Any
>& aArguments
)
520 throw(Exception
, RuntimeException
)
522 switch( aArguments
.getLength() )
524 case 2: // the object wraps an UNO struct
525 aArguments
[0] >>= m_xInvocation
;
526 aArguments
[1] >>= m_defaultValueType
;
528 case 3: // the object wraps an UNO interface
529 aArguments
[0] >>= m_xInvocation
;
530 aArguments
[1] >>= m_xOrigin
;
531 aArguments
[2] >>= m_defaultValueType
;
535 m_xExactName
= Reference
<XExactName
>( m_xInvocation
, UNO_QUERY
);
538 Reference
< XInterface
> InterfaceOleWrapper_Impl::createUnoWrapperInstance()
540 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper_Impl(
541 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
542 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
545 Reference
<XInterface
> InterfaceOleWrapper_Impl::createComWrapperInstance()
547 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper_Impl(
548 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
549 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
554 // "getType" is used in convertValueObject to map the string denoting the type
555 // to an actual Type object.
556 bool getType( const BSTR name
, Type
& type
)
560 typelib_TypeDescription
* pDesc
= NULL
;
561 OUString
str( reinterpret_cast<const sal_Unicode
*>(name
));
562 typelib_typedescription_getByName( &pDesc
, str
.pData
);
565 type
= Type( pDesc
->pWeakRef
);
566 typelib_typedescription_release( pDesc
);
572 static sal_Bool
writeBackOutParameter2( VARIANTARG
* pDest
, VARIANT
* pSource
)
574 sal_Bool ret
= sal_False
;
577 // Handle JScriptValue objects and JScript out params ( Array object )
578 CComVariant
varDest( *pDest
);
580 if( SUCCEEDED( varDest
.ChangeType(VT_DISPATCH
)))
582 CComPtr
<IDispatch
> spDispDest(varDest
.pdispVal
);
584 // special Handling for a JScriptValue object
586 CComQIPtr
<IJScriptValueObject
, &__uuidof(IJScriptValueObject
)> spValueDest(spDispDest
);
588 CComQIPtr
<IJScriptValueObject
> spValueDest(spDispDest
);
592 VARIANT_BOOL varBool
= VARIANT_FALSE
;
593 if( SUCCEEDED( hr
= spValueDest
->IsOutParam( &varBool
) )
594 && varBool
== VARIANT_TRUE
||
595 SUCCEEDED(hr
= spValueDest
->IsInOutParam( &varBool
) )
596 && varBool
== VARIANT_TRUE
)
598 if( SUCCEEDED( spValueDest
->Set( CComVariant(), *pSource
)))
602 else if (pDest
->vt
== VT_DISPATCH
)// VT_DISPATCH -> JScript out param
604 // We use IDispatchEx because its GetDispID function causes the creation
605 // of a property if it does not exist already. This is convenient for
606 // out parameters in JScript. Then the user must not specify propery "0"
609 CComQIPtr
<IDispatchEx
, &__uuidof(IDispatchEx
)> spDispEx( spDispDest
);
611 CComQIPtr
<IDispatchEx
> spDispEx( spDispDest
);
615 CComBSTR
nullProp(L
"0");
617 if( SUCCEEDED( spDispEx
->GetDispID( nullProp
, fdexNameEnsure
, &dwDispID
)))
619 DISPPARAMS dispparams
= {NULL
, NULL
, 1, 1};
620 dispparams
.rgvarg
= pSource
;
621 DISPID dispidPut
= DISPID_PROPERTYPUT
;
622 dispparams
.rgdispidNamedArgs
= &dispidPut
;
624 if (pSource
->vt
== VT_UNKNOWN
|| pSource
->vt
== VT_DISPATCH
||
625 (pSource
->vt
& VT_ARRAY
) || (pSource
->vt
& VT_BYREF
))
626 hr
= spDispEx
->InvokeEx(dwDispID
, LOCALE_USER_DEFAULT
, DISPATCH_PROPERTYPUTREF
,
627 &dispparams
, NULL
, NULL
, NULL
);
629 hr
= spDispEx
->InvokeEx(dwDispID
, LOCALE_USER_DEFAULT
, DISPATCH_PROPERTYPUT
,
630 &dispparams
, NULL
, NULL
, NULL
);
637 ret
= writeBackOutParameter( pDest
, pSource
);
639 else // The param can't be a JScript out-parameter ( an Array object), it could be a VBScript
640 { // param. The function checks itself for correct VBScript params
641 ret
= writeBackOutParameter( pDest
, pSource
);
645 // VisualBasic Script passes arguments as VT_VARIANT | VT_BYREF be it in or out parameter.
646 // Thus we are in charge of freeing an eventual value contained by the inner VARIANT
647 // Please note: VariantCopy doesn't free a VT_BYREF value
648 // The out parameters are expected to have always a valid type
649 static sal_Bool
writeBackOutParameter(VARIANTARG
* pDest
, VARIANT
* pSource
)
652 sal_Bool ret
= FALSE
;
653 // Out parameter must be VT_BYREF
654 if ((V_VT(pDest
) & VT_BYREF
) != 0 )
656 VARTYPE oleTypeFlags
= V_VT(pSource
);
658 // if caller accept VARIANT as out parameter, any value must be converted
659 if (V_VT(pDest
) == (VT_VARIANT
| VT_BYREF
))
661 // When the user provides a VARIANT rather then a concrete type
662 // we just copy the source to the out, in/out parameter
663 // VT_DISPATCH, VT_UNKNOWN, VT_ARRAY, VT_BSTR in the VARIANT that
664 // is contained in pDest are released by VariantCopy
665 VariantCopy(V_VARIANTREF(pDest
), pSource
);
670 // variantarg and variant must have same type
671 if ((V_VT(pDest
) & oleTypeFlags
) == oleTypeFlags
)
673 if ((oleTypeFlags
& VT_ARRAY
) != 0)
676 if( *V_ARRAYREF(pDest
) != NULL
)
677 hr
= SafeArrayCopyData( V_ARRAY(pSource
), *V_ARRAYREF(pDest
));
680 hr
= SafeArrayCopy(V_ARRAY(pSource
), V_ARRAYREF(pDest
)) == NOERROR
;
687 switch (V_VT(pSource
))
691 *V_I2REF(pDest
) = V_I2(pSource
);
696 *V_I4REF(pDest
) = V_I4(pSource
);
700 *V_R4REF(pDest
) = V_R4(pSource
);
704 *V_R8REF(pDest
) = V_R8(pSource
);
708 *V_CYREF(pDest
) = V_CY(pSource
);
712 *V_DATEREF(pDest
) = V_DATE(pSource
);
716 SysFreeString( *pDest
->pbstrVal
);
718 *V_BSTRREF(pDest
) = SysAllocString(V_BSTR(pSource
));
722 if (*V_DISPATCHREF(pDest
) != NULL
)
723 (*V_DISPATCHREF(pDest
))->Release();
725 *V_DISPATCHREF(pDest
) = V_DISPATCH(pSource
);
727 if (*V_DISPATCHREF(pDest
) != NULL
)
728 (*V_DISPATCHREF(pDest
))->AddRef();
733 *V_ERRORREF(pDest
) = V_ERROR(pSource
);
737 *V_BOOLREF(pDest
) = V_BOOL(pSource
);
741 if (*V_UNKNOWNREF(pDest
) != NULL
)
742 (*V_UNKNOWNREF(pDest
))->Release();
744 *V_UNKNOWNREF(pDest
) = V_UNKNOWN(pSource
);
746 if (*V_UNKNOWNREF(pDest
) != NULL
)
747 (*V_UNKNOWNREF(pDest
))->AddRef();
752 *V_I1REF(pDest
) = V_I1(pSource
);
756 *V_UI1REF(pDest
) = V_UI1(pSource
);
760 *V_UI2REF(pDest
) = V_UI2(pSource
);
764 *V_UI4REF(pDest
) = V_UI4(pSource
);
768 *V_INTREF(pDest
) = V_INT(pSource
);
772 *V_UINTREF(pDest
) = V_UINT(pSource
);
776 memcpy(pDest
->pdecVal
, pSource
, sizeof(DECIMAL
));
786 // Handling of special cases
787 // Destination and source types are different
788 if( pDest
->vt
== (VT_BSTR
| VT_BYREF
)
789 && pSource
->vt
== VT_I2
)
791 // When the user provides a String as out our in/out parameter
792 // and the type is char (TypeClass_CHAR) then we convert to a BSTR
793 // instead of VT_I2 as is done otherwise
794 OLECHAR buff
[]= {0,0};
795 buff
[0]= pSource
->iVal
;
797 SysFreeString( *pDest
->pbstrVal
);
798 *pDest
->pbstrVal
= SysAllocString( buff
);
807 STDMETHODIMP
InterfaceOleWrapper_Impl::Invoke(DISPID dispidMember
,
810 unsigned short wFlags
,
811 DISPPARAMS
* pdispparams
,
812 VARIANT
* pvarResult
,
813 EXCEPINFO
* pexcepinfo
,
814 unsigned int * puArgErr
)
820 sal_Bool bHandled
= sal_False
;
821 ret
= InvokeGeneral( dispidMember
, wFlags
, pdispparams
, pvarResult
, pexcepinfo
,
826 if ((dispidMember
> 0) && ((size_t)dispidMember
<= m_MemberInfos
.size()) && m_xInvocation
.is())
828 MemberInfo d
= m_MemberInfos
[dispidMember
- 1];
829 DWORD flags
= wFlags
& d
.flags
;
833 if ((flags
& DISPATCH_METHOD
) != 0)
835 if (pdispparams
->cNamedArgs
> 0)
836 ret
= DISP_E_NONAMEDARGS
;
839 Sequence
<Any
> params
;
841 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
843 ret
= doInvoke(pdispparams
, pvarResult
,
844 pexcepinfo
, puArgErr
, d
.name
, params
);
847 else if ((flags
& DISPATCH_PROPERTYGET
) != 0)
849 ret
= doGetProperty( pdispparams
, pvarResult
,
852 else if ((flags
& DISPATCH_PROPERTYPUT
|| flags
& DISPATCH_PROPERTYPUTREF
) != 0)
854 if (pdispparams
->cArgs
!= 1)
855 ret
= DISP_E_BADPARAMCOUNT
;
858 Sequence
<Any
> params
;
859 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
860 if(params
.getLength() > 0)
861 ret
= doSetProperty( pdispparams
, pvarResult
, pexcepinfo
, puArgErr
, d
.name
, params
);
863 ret
= DISP_E_BADVARTYPE
;
868 ret
= DISP_E_MEMBERNOTFOUND
;
871 ret
= DISP_E_MEMBERNOTFOUND
;
873 catch(const BridgeRuntimeError
& e
)
875 writeExcepinfo(pexcepinfo
, e
.message
);
876 ret
= DISP_E_EXCEPTION
;
878 catch(const Exception
& e
)
880 OUString message
= "InterfaceOleWrapper_Impl::Invoke : \n" +
882 writeExcepinfo(pexcepinfo
, message
);
883 ret
= DISP_E_EXCEPTION
;
887 OUString message
= "InterfaceOleWrapper_Impl::Invoke : \n"
888 "Unexpected exception";
889 writeExcepinfo(pexcepinfo
, message
);
890 ret
= DISP_E_EXCEPTION
;
896 HRESULT
InterfaceOleWrapper_Impl::doInvoke( DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
,
897 EXCEPINFO
* pexcepinfo
, unsigned int * puArgErr
, OUString
& name
, Sequence
<Any
>& params
)
904 Sequence
<sal_Int16
> outIndex
;
905 Sequence
<Any
> outParams
;
908 if (pdispparams
->cNamedArgs
> 0)
909 return DISP_E_NONAMEDARGS
;
911 // invoke method and take care of exceptions
912 returnValue
= m_xInvocation
->invoke(name
,
917 // try to write back out parameter
918 if (outIndex
.getLength() > 0)
920 const sal_Int16
* pOutIndex
= outIndex
.getConstArray();
921 const Any
* pOutParams
= outParams
.getConstArray();
923 for (sal_Int32 i
= 0; i
< outIndex
.getLength(); i
++)
926 // Currently a Sequence is converted to an SafeArray of VARIANTs.
927 anyToVariant( &variant
, pOutParams
[i
]);
929 // out parameter need special handling if they are VT_DISPATCH
930 // and used in JScript
931 int outindex
= pOutIndex
[i
];
932 writeBackOutParameter2(&(pdispparams
->rgvarg
[pdispparams
->cArgs
- 1 - outindex
]),
937 // write back return value
938 if (pvarResult
!= NULL
)
939 anyToVariant(pvarResult
, returnValue
);
941 catch(const IllegalArgumentException
& e
) //XInvocation::invoke
943 writeExcepinfo(pexcepinfo
, e
.Message
);
944 ret
= DISP_E_TYPEMISMATCH
;
946 catch(const CannotConvertException
& e
) //XInvocation::invoke
948 writeExcepinfo(pexcepinfo
, e
.Message
);
949 ret
= mapCannotConvertException( e
, puArgErr
);
951 catch(const InvocationTargetException
& e
) //XInvocation::invoke
953 const Any
& org
= e
.TargetException
;
957 org
.getValueType().getTypeName() + ": " + excTarget
.Message
;
958 writeExcepinfo(pexcepinfo
, message
);
959 ret
= DISP_E_EXCEPTION
;
961 catch(const NoSuchMethodException
& e
) //XInvocation::invoke
963 writeExcepinfo(pexcepinfo
, e
.Message
);
964 ret
= DISP_E_MEMBERNOTFOUND
;
966 catch(const BridgeRuntimeError
& e
)
968 writeExcepinfo(pexcepinfo
, e
.message
);
969 ret
= DISP_E_EXCEPTION
;
971 catch(const Exception
& e
)
973 OUString message
= "InterfaceOleWrapper_Impl::doInvoke : \n" +
975 writeExcepinfo(pexcepinfo
, message
);
976 ret
= DISP_E_EXCEPTION
;
980 OUString message
= "InterfaceOleWrapper_Impl::doInvoke : \n"
981 "Unexpected exception";
982 writeExcepinfo(pexcepinfo
, message
);
983 ret
= DISP_E_EXCEPTION
;
988 HRESULT
InterfaceOleWrapper_Impl::doGetProperty( DISPPARAMS
* /*pdispparams*/, VARIANT
* pvarResult
,
989 EXCEPINFO
* pexcepinfo
, OUString
& name
)
996 Any returnValue
= m_xInvocation
->getValue( name
);
997 // write back return value
999 anyToVariant(pvarResult
, returnValue
);
1001 catch(const UnknownPropertyException
& e
) //XInvocation::getValue
1003 writeExcepinfo(pexcepinfo
, e
.Message
);
1004 ret
= DISP_E_MEMBERNOTFOUND
;
1006 catch(const BridgeRuntimeError
& e
)
1008 writeExcepinfo(pexcepinfo
, e
.message
);
1009 ret
= DISP_E_EXCEPTION
;
1011 catch(const Exception
& e
)
1013 OUString message
= "InterfaceOleWrapper_Impl::doGetProperty : \n" +
1015 writeExcepinfo(pexcepinfo
, message
);
1019 OUString message
= "InterfaceOleWrapper_Impl::doInvoke : \n"
1020 "Unexpected exception";
1021 writeExcepinfo(pexcepinfo
, message
);
1022 ret
= DISP_E_EXCEPTION
;
1027 HRESULT
InterfaceOleWrapper_Impl::doSetProperty( DISPPARAMS
* /*pdispparams*/, VARIANT
* /*pvarResult*/,
1028 EXCEPINFO
* pexcepinfo
, unsigned int * puArgErr
, OUString
& name
, Sequence
<Any
> params
)
1034 m_xInvocation
->setValue( name
, params
.getConstArray()[0]);
1036 catch(const UnknownPropertyException
&)
1038 ret
= DISP_E_MEMBERNOTFOUND
;
1040 catch(const CannotConvertException
&e
)
1042 ret
= mapCannotConvertException( e
, puArgErr
);
1044 catch(const InvocationTargetException
&e
)
1046 if (pexcepinfo
!= NULL
)
1048 Any org
= e
.TargetException
;
1050 pexcepinfo
->wCode
= UNO_2_OLE_EXCEPTIONCODE
;
1051 pexcepinfo
->bstrSource
= SysAllocString(L
"any ONE component");
1052 pexcepinfo
->bstrDescription
= SysAllocString(
1053 reinterpret_cast<LPCOLESTR
>(org
.getValueType().getTypeName().getStr()));
1055 ret
= DISP_E_EXCEPTION
;
1059 ret
= DISP_E_EXCEPTION
;
1064 HRESULT
InterfaceOleWrapper_Impl::InvokeGeneral( DISPID dispidMember
, unsigned short wFlags
,
1065 DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
, EXCEPINFO
* pexcepinfo
,
1066 unsigned int * /*puArgErr*/, sal_Bool
& bHandled
)
1071 // DISPID_VALUE | The DEFAULT Value is required in JScript when the situation
1072 // is that we put an object into an Array object ( out parameter). We have to return
1073 // IDispatch otherwise the object cannot be accessed from the Script.
1074 if( dispidMember
== DISPID_VALUE
&& wFlags
== DISPATCH_PROPERTYGET
1075 && m_defaultValueType
!= VT_EMPTY
&& pvarResult
!= NULL
)
1078 if( m_defaultValueType
== VT_DISPATCH
)
1080 pvarResult
->vt
= VT_DISPATCH
;
1081 pvarResult
->pdispVal
= static_cast<IDispatch
*>( this);
1087 // function: _GetValueObject
1088 else if( dispidMember
== DISPID_JSCRIPT_VALUE_FUNC
)
1093 CComObject
< JScriptValue
>* pValue
;
1094 if( SUCCEEDED( CComObject
<JScriptValue
>::CreateInstance( &pValue
)))
1097 pvarResult
->vt
= VT_DISPATCH
;
1099 pvarResult
->pdispVal
= CComQIPtr
<IDispatch
, &__uuidof(IDispatch
)>(pValue
->GetUnknown());
1101 pvarResult
->pdispVal
= CComQIPtr
<IDispatch
>(pValue
->GetUnknown());
1106 ret
= DISP_E_EXCEPTION
;
1108 else if( dispidMember
== DISPID_GET_STRUCT_FUNC
)
1111 sal_Bool bStruct
= sal_False
;
1114 Reference
<XIdlReflection
> xRefl
= theCoreReflection::get(comphelper::getComponentContext(m_smgr
));
1115 // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1117 if( pdispparams
->cArgs
== 1 && SUCCEEDED( arg
.ChangeType( VT_BSTR
, &pdispparams
->rgvarg
[0])) )
1119 Reference
<XIdlClass
> classStruct
= xRefl
->forName( reinterpret_cast<const sal_Unicode
*>(arg
.bstrVal
));
1120 if( classStruct
.is())
1123 classStruct
->createObject( anyStruct
);
1125 anyToVariant( &var
, anyStruct
);
1127 if( var
.vt
== VT_DISPATCH
)
1129 VariantCopy( pvarResult
, & var
);
1134 ret
= bStruct
== sal_True
? S_OK
: DISP_E_EXCEPTION
;
1136 else if (dispidMember
== DISPID_CREATE_TYPE_FUNC
)
1141 // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1143 if( pdispparams
->cArgs
!= 1)
1144 return DISP_E_BADPARAMCOUNT
;
1145 if (FAILED( arg
.ChangeType( VT_BSTR
, &pdispparams
->rgvarg
[0])))
1146 return DISP_E_BADVARTYPE
;
1148 //check if the provided name represents a valid type
1150 if (getType(arg
.bstrVal
, type
) == false)
1152 writeExcepinfo(pexcepinfo
,OUString(
1153 "[automation bridge] A UNO type with the name " +
1154 OUString(reinterpret_cast<const sal_Unicode
*>(arg
.bstrVal
)) + " does not exist!"));
1155 return DISP_E_EXCEPTION
;
1158 if (createUnoTypeWrapper(arg
.bstrVal
, pvarResult
) == false)
1160 writeExcepinfo(pexcepinfo
, "[automation bridge] InterfaceOleWrapper_Impl::InvokeGeneral\n"
1161 "Could not initialize UnoTypeWrapper object!");
1162 return DISP_E_EXCEPTION
;
1166 catch(const BridgeRuntimeError
& e
)
1168 writeExcepinfo(pexcepinfo
, e
.message
);
1169 ret
= DISP_E_EXCEPTION
;
1171 catch(const Exception
& e
)
1173 OUString message
= "InterfaceOleWrapper_Impl::InvokeGeneral : \n" +
1175 writeExcepinfo(pexcepinfo
, message
);
1176 ret
= DISP_E_EXCEPTION
;
1180 OUString message
= "InterfaceOleWrapper_Impl::InvokeGeneral : \n"
1181 "Unexpected exception";
1182 writeExcepinfo(pexcepinfo
, message
);
1183 ret
= DISP_E_EXCEPTION
;
1191 STDMETHODIMP
InterfaceOleWrapper_Impl::GetDispID(BSTR
/*bstrName*/, DWORD
/*grfdex*/, DISPID __RPC_FAR
* /*pid*/)
1193 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1198 STDMETHODIMP
InterfaceOleWrapper_Impl::InvokeEx(
1199 /* [in] */ DISPID
/*id*/,
1200 /* [in] */ LCID
/*lcid*/,
1201 /* [in] */ WORD
/*wFlags*/,
1202 /* [in] */ DISPPARAMS __RPC_FAR
* /*pdp*/,
1203 /* [out] */ VARIANT __RPC_FAR
* /*pvarRes*/,
1204 /* [out] */ EXCEPINFO __RPC_FAR
* /*pei*/,
1205 /* [unique][in] */ IServiceProvider __RPC_FAR
* /*pspCaller*/)
1207 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1213 STDMETHODIMP
InterfaceOleWrapper_Impl::DeleteMemberByName(
1214 /* [in] */ BSTR
/*bstr*/,
1215 /* [in] */ DWORD
/*grfdex*/)
1217 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1222 STDMETHODIMP
InterfaceOleWrapper_Impl::DeleteMemberByDispID(DISPID
/*id*/)
1224 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1229 STDMETHODIMP
InterfaceOleWrapper_Impl::GetMemberProperties(
1230 /* [in] */ DISPID
/*id*/,
1231 /* [in] */ DWORD
/*grfdexFetch*/,
1232 /* [out] */ DWORD __RPC_FAR
* /*pgrfdex*/)
1234 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1239 STDMETHODIMP
InterfaceOleWrapper_Impl::GetMemberName(
1240 /* [in] */ DISPID
/*id*/,
1241 /* [out] */ BSTR __RPC_FAR
* /*pbstrName*/)
1243 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1248 STDMETHODIMP
InterfaceOleWrapper_Impl::GetNextDispID(
1249 /* [in] */ DWORD
/*grfdex*/,
1250 /* [in] */ DISPID
/*id*/,
1251 /* [out] */ DISPID __RPC_FAR
* /*pid*/)
1253 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1258 STDMETHODIMP
InterfaceOleWrapper_Impl::GetNameSpaceParent(
1259 /* [out] */ IUnknown __RPC_FAR
*__RPC_FAR
* /*ppunk*/)
1261 HRESULT ret
= ResultFromScode(E_NOTIMPL
);
1267 /*************************************************************************
1269 UnoObjectWrapperRemoteOpt
1271 *************************************************************************/
1272 UnoObjectWrapperRemoteOpt::UnoObjectWrapperRemoteOpt( Reference
<XMultiServiceFactory
>& aFactory
,
1273 sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
1274 InterfaceOleWrapper_Impl( aFactory
, unoWrapperClass
, comWrapperClass
),
1279 UnoObjectWrapperRemoteOpt::~UnoObjectWrapperRemoteOpt()
1283 // UnoConversionUtilities
1284 Reference
< XInterface
> UnoObjectWrapperRemoteOpt::createUnoWrapperInstance()
1286 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
1287 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
1288 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
1291 STDMETHODIMP
UnoObjectWrapperRemoteOpt::GetIDsOfNames ( REFIID
/*riid*/, OLECHAR
** rgszNames
, unsigned int cNames
,
1292 LCID
/*lcid*/, DISPID
* rgdispid
)
1294 MutexGuard
guard( getBridgeMutex());
1298 HRESULT ret
= E_UNEXPECTED
;
1299 // ----------------------------------------
1301 if( ! wcscmp( *rgszNames
, JSCRIPT_VALUE_FUNC
))
1303 *rgdispid
= DISPID_JSCRIPT_VALUE_FUNC
;
1306 else if( ! wcscmp( *rgszNames
, GET_STRUCT_FUNC
))
1308 *rgdispid
= DISPID_GET_STRUCT_FUNC
;
1312 // ----------------------------------------
1313 if (m_xInvocation
.is() && (cNames
> 0))
1315 OUString
name(reinterpret_cast<const sal_Unicode
*>(rgszNames
[0]));
1316 // has this name been determined as "bad"
1317 BadNameMap::iterator badIter
= m_badNameMap
.find( name
);
1318 if( badIter
== m_badNameMap
.end() )
1320 // name has not been bad before( member exists
1321 typedef NameToIdMap::iterator ITnames
;
1322 pair
< ITnames
, bool > pair_id
= m_nameToDispIdMap
.insert( NameToIdMap::value_type(name
, m_currentId
++));
1323 // new ID inserted ?
1324 if( pair_id
.second
)
1325 {// yes, now create MemberInfo and ad to IdToMemberInfoMap
1326 MemberInfo
d(0, name
);
1327 m_idToMemberInfoMap
.insert( IdToMemberInfoMap::value_type( m_currentId
- 1, d
));
1330 *rgdispid
= pair_id
.first
->second
;
1334 ret
= DISP_E_UNKNOWNNAME
;
1339 STDMETHODIMP
UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember
, REFIID
/*riid*/, LCID
/*lcid*/, unsigned short wFlags
,
1340 DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
, EXCEPINFO
* pexcepinfo
,
1341 unsigned int * puArgErr
)
1346 sal_Bool bHandled
= sal_False
;
1347 ret
= InvokeGeneral( dispidMember
, wFlags
, pdispparams
, pvarResult
, pexcepinfo
,
1348 puArgErr
, bHandled
);
1352 if ( dispidMember
> 0 && m_xInvocation
.is())
1355 IdToMemberInfoMap::iterator it_MemberInfo
= m_idToMemberInfoMap
.find( dispidMember
);
1356 if( it_MemberInfo
!= m_idToMemberInfoMap
.end() )
1358 MemberInfo
& info
= it_MemberInfo
->second
;
1360 Sequence
<Any
> params
; // holds converted any s
1362 { // DISPID called for the first time
1363 if( wFlags
== DISPATCH_METHOD
)
1365 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1367 if( FAILED( ret
= doInvoke( pdispparams
, pvarResult
,
1368 pexcepinfo
, puArgErr
, info
.name
, params
))
1369 && ret
== DISP_E_MEMBERNOTFOUND
)
1371 // try to get the exact name
1373 if (m_xExactName
.is())
1375 exactName
= m_xExactName
->getExactName( info
.name
);
1377 if( !exactName
.isEmpty() )
1379 if( SUCCEEDED( ret
= doInvoke( pdispparams
, pvarResult
,
1380 pexcepinfo
, puArgErr
, exactName
, params
)))
1381 info
.name
= exactName
;
1385 if( SUCCEEDED( ret
) )
1386 info
.flags
= DISPATCH_METHOD
;
1387 } //if( wFlags == DISPATCH_METHOD )
1389 else if( wFlags
== DISPATCH_PROPERTYPUT
|| wFlags
== DISPATCH_PROPERTYPUTREF
)
1391 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1392 if( FAILED( ret
= doSetProperty( pdispparams
, pvarResult
,
1393 pexcepinfo
, puArgErr
, info
.name
, params
))
1394 && ret
== DISP_E_MEMBERNOTFOUND
)
1396 // try to get the exact name
1398 if (m_xExactName
.is())
1400 exactName
= m_xExactName
->getExactName( info
.name
);
1402 if( !exactName
.isEmpty() )
1404 if( SUCCEEDED( ret
= doSetProperty( pdispparams
, pvarResult
,
1405 pexcepinfo
, puArgErr
, exactName
, params
)))
1406 info
.name
= exactName
;
1410 if( SUCCEEDED( ret
) )
1411 info
.flags
= DISPATCH_PROPERTYPUT
| DISPATCH_PROPERTYGET
;
1414 else if( wFlags
== DISPATCH_PROPERTYGET
)
1416 if( FAILED( ret
= doGetProperty( pdispparams
, pvarResult
,
1417 pexcepinfo
, info
.name
))
1418 && ret
== DISP_E_MEMBERNOTFOUND
)
1420 // try to get the exact name
1422 if (m_xExactName
.is())
1424 exactName
= m_xExactName
->getExactName( info
.name
);
1426 if( !exactName
.isEmpty() )
1428 if( SUCCEEDED( ret
= doGetProperty( pdispparams
, pvarResult
,
1429 pexcepinfo
, exactName
)))
1430 info
.name
= exactName
;
1434 if( SUCCEEDED( ret
) )
1435 info
.flags
= DISPATCH_PROPERTYGET
| DISPATCH_PROPERTYPUT
;
1437 else if( wFlags
& DISPATCH_METHOD
&&
1438 (wFlags
& DISPATCH_PROPERTYPUT
|| wFlags
& DISPATCH_PROPERTYPUTREF
))
1442 // convert params for DISPATCH_METHOD or DISPATCH_PROPERTYPUT
1443 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1444 // try first as method
1445 if( FAILED( ret
= doInvoke( pdispparams
, pvarResult
,
1446 pexcepinfo
, puArgErr
, info
.name
, params
))
1447 && ret
== DISP_E_MEMBERNOTFOUND
)
1449 // try to get the exact name
1450 if (m_xExactName
.is())
1452 exactName
= m_xExactName
->getExactName( info
.name
);
1454 if( !exactName
.isEmpty() )
1456 if( SUCCEEDED( ret
= doInvoke( pdispparams
, pvarResult
,
1457 pexcepinfo
, puArgErr
, exactName
, params
)))
1458 info
.name
= exactName
;
1462 if( SUCCEEDED( ret
) )
1463 info
.flags
= DISPATCH_METHOD
;
1466 if( FAILED( ret
) && pdispparams
->cArgs
== 1)
1468 if( FAILED( ret
= doSetProperty( pdispparams
, pvarResult
,
1469 pexcepinfo
, puArgErr
, info
.name
, params
))
1470 && ret
== DISP_E_MEMBERNOTFOUND
)
1472 // try to get the exact name
1473 if( !exactName
.isEmpty() )
1475 if( SUCCEEDED( ret
= doSetProperty( pdispparams
, pvarResult
,
1476 pexcepinfo
, puArgErr
, exactName
, params
)))
1477 info
.name
= exactName
;
1480 if( SUCCEEDED( ret
) )
1481 info
.flags
= DISPATCH_PROPERTYPUT
| DISPATCH_PROPERTYGET
;
1484 else if( wFlags
& DISPATCH_METHOD
&& wFlags
& DISPATCH_PROPERTYGET
)
1487 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1489 if( FAILED( ret
= doInvoke( pdispparams
, pvarResult
,
1490 pexcepinfo
, puArgErr
, info
.name
, params
))
1491 && ret
== DISP_E_MEMBERNOTFOUND
)
1493 // try to get the exact name
1494 if (m_xExactName
.is())
1496 exactName
= m_xExactName
->getExactName( info
.name
);
1498 if( !exactName
.isEmpty() )
1500 if( SUCCEEDED( ret
= doInvoke( pdispparams
, pvarResult
,
1501 pexcepinfo
, puArgErr
, exactName
, params
)))
1502 info
.name
= exactName
;
1506 if( SUCCEEDED( ret
) )
1507 info
.flags
= DISPATCH_METHOD
;
1510 if( FAILED( ret
) && pdispparams
->cArgs
== 1)
1512 if( FAILED( ret
= doGetProperty( pdispparams
, pvarResult
,
1513 pexcepinfo
, info
.name
))
1514 && ret
== DISP_E_MEMBERNOTFOUND
)
1516 if( !exactName
.isEmpty() )
1518 if( SUCCEEDED( ret
= doSetProperty( pdispparams
, pvarResult
,
1519 pexcepinfo
, puArgErr
, exactName
, params
)))
1520 info
.name
= exactName
;
1523 if( SUCCEEDED( ret
) )
1524 info
.flags
= DISPATCH_PROPERTYGET
;
1528 // update ínformation about this member
1529 if( ret
== DISP_E_MEMBERNOTFOUND
)
1531 // Remember the name as not existing
1532 // and remove the MemberInfo
1533 m_badNameMap
[info
.name
]= sal_False
;
1534 m_idToMemberInfoMap
.erase( it_MemberInfo
);
1536 } // if( ! info.flags )
1537 else // IdToMemberInfoMap contains a MemberInfo
1539 if( wFlags
& DISPATCH_METHOD
&& info
.flags
== DISPATCH_METHOD
)
1541 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1542 ret
= doInvoke( pdispparams
, pvarResult
,
1543 pexcepinfo
, puArgErr
, info
.name
, params
);
1545 else if( (wFlags
& DISPATCH_PROPERTYPUT
|| wFlags
& DISPATCH_PROPERTYPUTREF
) &&
1546 info
.flags
& DISPATCH_PROPERTYPUT
)
1548 convertDispparamsArgs(dispidMember
, wFlags
, pdispparams
, params
);
1549 ret
= doSetProperty( pdispparams
, pvarResult
,
1550 pexcepinfo
, puArgErr
, info
.name
, params
);
1552 else if( (wFlags
& DISPATCH_PROPERTYGET
) && ( info
.flags
& DISPATCH_PROPERTYGET
))
1554 ret
= doGetProperty( pdispparams
, pvarResult
,
1555 pexcepinfo
, info
.name
);
1559 ret
= DISP_E_MEMBERNOTFOUND
;
1562 }// if( it_MemberInfo != m_idToMemberInfoMap.end() )
1564 ret
= DISP_E_MEMBERNOTFOUND
;
1567 catch(const BridgeRuntimeError
& e
)
1569 writeExcepinfo(pexcepinfo
, e
.message
);
1570 ret
= DISP_E_EXCEPTION
;
1572 catch(const Exception
& e
)
1574 OUString message
= "UnoObjectWrapperRemoteOpt::Invoke : \n" +
1576 writeExcepinfo(pexcepinfo
, message
);
1577 ret
= DISP_E_EXCEPTION
;
1581 OUString message
= "UnoObjectWrapperRemoteOpt::Invoke : \n"
1582 "Unexpected exception";
1583 writeExcepinfo(pexcepinfo
, message
);
1584 ret
= DISP_E_EXCEPTION
;
1590 HRESULT
UnoObjectWrapperRemoteOpt::methodInvoke( DISPID
/*dispidMember*/, DISPPARAMS
* /*pdispparams*/, VARIANT
* /*pvarResult*/,
1591 EXCEPINFO
* /*pexcepinfo*/, unsigned int * /*puArgErr*/, Sequence
<Any
> params
)
1597 // The returned HRESULT is only appropriate for IDispatch::Invoke
1598 static HRESULT
mapCannotConvertException(const CannotConvertException
&e
, unsigned int * puArgErr
)
1601 sal_Bool bWriteIndex
= sal_True
;
1605 case FailReason::OUT_OF_RANGE
:
1606 ret
= DISP_E_OVERFLOW
;
1608 case FailReason::IS_NOT_NUMBER
:
1609 ret
= DISP_E_TYPEMISMATCH
;
1611 case FailReason::IS_NOT_ENUM
:
1612 ret
= DISP_E_TYPEMISMATCH
;
1614 case FailReason::IS_NOT_BOOL
:
1615 ret
= DISP_E_TYPEMISMATCH
;
1617 case FailReason::NO_SUCH_INTERFACE
:
1618 ret
= DISP_E_TYPEMISMATCH
;
1620 case FailReason::SOURCE_IS_NO_DERIVED_TYPE
:
1621 ret
= DISP_E_TYPEMISMATCH
;
1623 case FailReason::TYPE_NOT_SUPPORTED
:
1624 ret
= DISP_E_TYPEMISMATCH
;
1626 case FailReason::INVALID
:
1627 ret
= DISP_E_TYPEMISMATCH
;
1629 case FailReason::NO_DEFAULT_AVAILABLE
:
1630 ret
= DISP_E_BADPARAMCOUNT
;
1632 case FailReason::UNKNOWN
:
1637 bWriteIndex
= sal_False
;
1641 if( bWriteIndex
&& puArgErr
!= NULL
)
1642 *puArgErr
= e
.ArgumentIndex
;
1646 // The function maps the TypeClass of the any to VARTYPE: If
1647 // the Any contains STRUCT or INTERFACE then the return value
1648 // is VT_DISPATCH. The function is used from o2u_createUnoObjectWrapper
1649 // and the result is put into the constructor of the uno - wrapper
1650 // object. If a client asks the object for DISPID_VALUE and this
1651 // funtion returned VT_DISPATCH then the IDispatch of the same
1652 // object is being returned.
1653 // See InterfaceOleWrapper_Impl::Invoke, InterfaceOleWrapper_Impl::m_defaultValueType
1654 const VARTYPE
getVarType( const Any
& value
)
1656 VARTYPE ret
= VT_EMPTY
;
1658 switch ( value
.getValueTypeClass())
1660 case TypeClass_STRUCT
: ret
= VT_DISPATCH
; break;
1661 case TypeClass_INTERFACE
: ret
= VT_DISPATCH
; break;
1672 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */