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 // http://stackoverflow.com/questions/5839292/error-c1189-after-installing-visual-studio-2010
21 #define _WIN32_WINNT 0x0403
23 #include "ole2uno.hxx"
24 #include "rtl/ustrbuf.hxx"
27 #include "osl/diagnose.h"
28 #include "osl/doublecheckedlocking.h"
29 #include "osl/thread.h"
31 #include "boost/scoped_array.hpp"
32 #include <com/sun/star/script/FailReason.hpp>
33 #include <com/sun/star/beans/XMaterialHolder.hpp>
34 #include <com/sun/star/script/XTypeConverter.hpp>
35 #include <com/sun/star/script/FinishEngineEvent.hpp>
36 #include <com/sun/star/script/InterruptReason.hpp>
37 #include <com/sun/star/script/XEngineListener.hpp>
38 #include <com/sun/star/script/XDebugging.hpp>
39 #include <com/sun/star/script/XInvocation.hpp>
40 #include <com/sun/star/script/ContextInformation.hpp>
41 #include <com/sun/star/script/FinishReason.hpp>
42 #include <com/sun/star/script/XEngine.hpp>
43 #include <com/sun/star/script/InterruptEngineEvent.hpp>
44 #include <com/sun/star/script/XLibraryAccess.hpp>
45 #include <com/sun/star/bridge/ModelDependent.hpp>
47 #include "com/sun/star/bridge/oleautomation/NamedArgument.hpp"
48 #include "com/sun/star/bridge/oleautomation/PropertyPutArgument.hpp"
50 #include <typelib/typedescription.hxx>
52 #include <rtl/ustring.hxx>
54 #include "jscriptclasses.hxx"
56 #include "oleobjw.hxx"
57 #include "unoobjw.hxx"
60 using namespace boost
;
63 using namespace com::sun::star::script
;
64 using namespace com::sun::star::lang
;
65 using namespace com::sun::star::bridge
;
66 using namespace com::sun::star::bridge::oleautomation
;
67 using namespace com::sun::star::bridge::ModelDependent
;
68 using namespace ::com::sun::star
;
71 #define JSCRIPT_ID_PROPERTY L"_environment"
72 #define JSCRIPT_ID L"jscript"
77 // key: XInterface pointer created by Invocation Adapter Factory
78 // value: XInterface pointer to the wrapper class.
79 // Entries to the map are made within
80 // Any createOleObjectWrapper(IUnknown* pUnknown, const Type& aType);
81 // Entries are being deleted if the wrapper class's destructor has been
83 // Before UNO object is wrapped to COM object this map is checked
84 // to see if the UNO object is already a wrapper.
85 boost::unordered_map
<sal_uInt32
, sal_uInt32
> AdapterToWrapperMap
;
86 // key: XInterface of the wrapper object.
87 // value: XInterface of the Interface created by the Invocation Adapter Factory.
88 // A COM wrapper is responsible for removing the corresponding entry
89 // in AdapterToWrappperMap if it is being destroyed. Because the wrapper does not
90 // know about its adapted interface it uses WrapperToAdapterMap to get the
91 // adapted interface which is then used to locate the entry in AdapterToWrapperMap.
92 boost::unordered_map
<sal_uInt32
,sal_uInt32
> WrapperToAdapterMap
;
94 boost::unordered_map
<sal_uInt32
, WeakReference
<XInterface
> > ComPtrToWrapperMap
;
95 /*****************************************************************************
97 class implementation IUnknownWrapper_Impl
99 *****************************************************************************/
101 IUnknownWrapper_Impl::IUnknownWrapper_Impl( Reference
<XMultiServiceFactory
>& xFactory
,
102 sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
103 UnoConversionUtilities
<IUnknownWrapper_Impl
>( xFactory
, unoWrapperClass
, comWrapperClass
),
104 m_pxIdlClass( NULL
), m_eJScript( JScriptUndefined
),
105 m_bComTlbIndexInit(false), m_bHasDfltMethod(false), m_bHasDfltProperty(false)
110 IUnknownWrapper_Impl::~IUnknownWrapper_Impl()
112 o2u_attachCurrentThread();
113 MutexGuard
guard(getBridgeMutex());
114 XInterface
* xIntRoot
= (OWeakObject
*)this;
115 #if OSL_DEBUG_LEVEL > 0
116 acquire(); // make sure we don't delete us twice because of Reference
117 OSL_ASSERT( Reference
<XInterface
>( static_cast<XWeak
*>(this), UNO_QUERY
).get() == xIntRoot
);
120 // remove entries in global maps
121 typedef boost::unordered_map
<sal_uInt32
, sal_uInt32
>::iterator _IT
;
122 _IT it
= WrapperToAdapterMap
.find( (sal_uInt32
) xIntRoot
);
123 if( it
!= WrapperToAdapterMap
.end())
125 sal_uInt32 adapter
= it
->second
;
127 AdapterToWrapperMap
.erase( adapter
);
128 WrapperToAdapterMap
.erase( it
);
131 IT_Com it_c
= ComPtrToWrapperMap
.find( (sal_uInt32
) m_spUnknown
.p
);
132 if(it_c
!= ComPtrToWrapperMap
.end())
133 ComPtrToWrapperMap
.erase(it_c
);
135 #if OSL_DEBUG_LEVEL > 0
136 fprintf(stderr
,"[automation bridge] ComPtrToWrapperMap contains: %i \n",
137 ComPtrToWrapperMap
.size());
141 Any
IUnknownWrapper_Impl::queryInterface(const Type
& t
)
142 throw (RuntimeException
)
144 if (t
== getCppuType(static_cast<Reference
<XDefaultMethod
>*>( 0)) && !m_bHasDfltMethod
)
146 if (t
== getCppuType(static_cast<Reference
<XDefaultProperty
>*>( 0)) && !m_bHasDfltProperty
)
148 if ( ( t
== getCppuType(static_cast<Reference
<XInvocation
>*>( 0)) || t
== getCppuType(static_cast<Reference
<XAutomationInvocation
>*>( 0)) ) && !m_spDispatch
)
150 // XDirectInvocation seems to be an oracle replacement for XAutomationInvocation, however it is flawed esecially wrt. assumptions about whether to invoke a
151 // Put or Get property, the implementation code has no business guessing that, it's up to the caller to decide that. Worse XDirectInvocation duplicates lots of code.
152 // XAutomationInvocation provides separate calls for put& get
153 // properties. Note: Currently the basic runtime doesn't call put properties directly, it should... after all the basic runtime should know whether it is calling a put or get property.
154 // For the moment for ease of merging we will let the XDirectInvoke and XAuthomationInvocation interfaces stay side by side ( and for the momemnt at least I would prefer the basic
155 // runtime to call XAutomationInvocation instead of XDirectInvoke
156 return WeakImplHelper7
<XBridgeSupplier2
,
157 XInitialization
, XAutomationObject
, XDefaultProperty
, XDefaultMethod
, XDirectInvocation
, XAutomationInvocation
>::queryInterface(t
);
160 Reference
<XIntrospectionAccess
> SAL_CALL
IUnknownWrapper_Impl::getIntrospection(void)
161 throw (RuntimeException
)
163 Reference
<XIntrospectionAccess
> ret
;
168 Any SAL_CALL
IUnknownWrapper_Impl::invokeGetProperty( const OUString
& aPropertyName
, const Sequence
< Any
>& aParams
, Sequence
< sal_Int16
>& aOutParamIndex
, Sequence
< Any
>& aOutParam
)
173 o2u_attachCurrentThread();
174 ITypeInfo
* pInfo
= getTypeInfo();
175 FuncDesc
aDescGet(pInfo
);
176 FuncDesc
aDescPut(pInfo
);
177 VarDesc
aVarDesc(pInfo
);
178 getPropDesc(aPropertyName
, & aDescGet
, & aDescPut
, & aVarDesc
);
181 OUString
msg("[automation bridge]Property \"" + aPropertyName
+
182 "\" is not supported");
183 throw UnknownPropertyException(msg
, Reference
<XInterface
>());
185 aResult
= invokeWithDispIdComTlb( aDescGet
, aPropertyName
, aParams
, aOutParamIndex
, aOutParam
);
187 catch ( const Exception
& e
)
189 throw RuntimeException("[automation bridge] unexpected exception in "
190 "IUnknownWrapper_Impl::invokeGetProperty ! Message : \n" +
191 e
.Message
, Reference
<XInterface
>());
196 Any SAL_CALL
IUnknownWrapper_Impl::invokePutProperty( const OUString
& aPropertyName
, const Sequence
< Any
>& aParams
, Sequence
< sal_Int16
>& aOutParamIndex
, Sequence
< Any
>& aOutParam
)
201 o2u_attachCurrentThread();
202 ITypeInfo
* pInfo
= getTypeInfo();
203 FuncDesc
aDescGet(pInfo
);
204 FuncDesc
aDescPut(pInfo
);
205 VarDesc
aVarDesc(pInfo
);
206 getPropDesc(aPropertyName
, & aDescGet
, & aDescPut
, & aVarDesc
);
209 OUString
msg("[automation bridge]Property \"" + aPropertyName
+
210 "\" is not supported");
211 throw UnknownPropertyException(msg
, Reference
<XInterface
>());
213 aResult
= invokeWithDispIdComTlb( aDescPut
, aPropertyName
, aParams
, aOutParamIndex
, aOutParam
);
215 catch ( const Exception
& e
)
217 throw RuntimeException("[automation bridge] unexpected exception in "
218 "IUnknownWrapper_Impl::invokePutProperty ! Message : \n" +
219 e
.Message
, Reference
<XInterface
>());
225 Any SAL_CALL
IUnknownWrapper_Impl::invoke( const OUString
& aFunctionName
,
226 const Sequence
< Any
>& aParams
, Sequence
< sal_Int16
>& aOutParamIndex
,
227 Sequence
< Any
>& aOutParam
)
228 throw(IllegalArgumentException
, CannotConvertException
, InvocationTargetException
,
231 if ( ! m_spDispatch
)
233 throw RuntimeException(
234 "[automation bridge] The object does not have an IDispatch interface",
235 Reference
<XInterface
>());
242 o2u_attachCurrentThread();
244 TypeDescription methodDesc
;
245 getMethodInfo(aFunctionName
, methodDesc
);
248 ret
= invokeWithDispIdUnoTlb(aFunctionName
,
255 ret
= invokeWithDispIdComTlb( aFunctionName
,
261 catch (const IllegalArgumentException
&)
265 catch (const CannotConvertException
&)
269 catch (const BridgeRuntimeError
& e
)
271 throw RuntimeException(e
.message
, Reference
<XInterface
>());
273 catch (const Exception
& e
)
275 throw RuntimeException("[automation bridge] unexpected exception in "
276 "IUnknownWrapper_Impl::invoke ! Message : \n" +
277 e
.Message
, Reference
<XInterface
>());
282 throw RuntimeException("[automation bridge] unexpected exception in "
283 "IUnknownWrapper_Impl::Invoke !", Reference
<XInterface
>());
288 void SAL_CALL
IUnknownWrapper_Impl::setValue( const OUString
& aPropertyName
,
290 throw(UnknownPropertyException
, CannotConvertException
, InvocationTargetException
,
293 if ( ! m_spDispatch
)
295 throw RuntimeException(
296 "[automation bridge] The object does not have an IDispatch interface",
297 Reference
<XInterface
>());
301 o2u_attachCurrentThread();
303 ITypeInfo
* pInfo
= getTypeInfo();
304 FuncDesc
aDescGet(pInfo
);
305 FuncDesc
aDescPut(pInfo
);
306 VarDesc
aVarDesc(pInfo
);
307 getPropDesc(aPropertyName
, & aDescGet
, & aDescPut
, & aVarDesc
);
308 //check if there is such a property at all or if it is read only
309 if ( ! aDescPut
&& ! aDescGet
&& ! aVarDesc
)
311 OUString
msg("[automation bridge]Property \"" + aPropertyName
+
312 "\" is not supported");
313 throw UnknownPropertyException(msg
, Reference
<XInterface
>());
316 if ( (! aDescPut
&& aDescGet
) || aVarDesc
317 && aVarDesc
->wVarFlags
== VARFLAG_FREADONLY
)
320 OUString
msg("[automation bridge] Property " + aPropertyName
+
322 OString sMsg
= OUStringToOString(msg
, osl_getThreadTextEncoding());
323 OSL_FAIL(sMsg
.getStr());
329 DISPPARAMS dispparams
;
331 CComVariant varRefArg
;
332 CComVariant varResult
;
334 unsigned int uArgErr
;
336 // converting UNO value to OLE variant
337 DISPID dispidPut
= DISPID_PROPERTYPUT
;
338 dispparams
.rgdispidNamedArgs
= &dispidPut
;
339 dispparams
.cArgs
= 1;
340 dispparams
.cNamedArgs
= 1;
341 dispparams
.rgvarg
= & varArg
;
343 OSL_ASSERT(aDescPut
|| aVarDesc
);
347 INVOKEKIND invkind
= INVOKE_PROPERTYPUT
;
348 //determine the expected type, dispid, invoke kind (DISPATCH_PROPERTYPUT,
349 //DISPATCH_PROPERTYPUTREF)
352 vt
= getElementTypeDesc(& aDescPut
->lprgelemdescParam
[0].tdesc
);
353 dispid
= aDescPut
->memid
;
354 invkind
= aDescPut
->invkind
;
358 vt
= getElementTypeDesc( & aVarDesc
->elemdescVar
.tdesc
);
359 dispid
= aVarDesc
->memid
;
360 if (vt
== VT_UNKNOWN
|| vt
== VT_DISPATCH
||
361 (vt
& VT_ARRAY
) || (vt
& VT_BYREF
))
363 invkind
= INVOKE_PROPERTYPUTREF
;
367 // convert the uno argument
370 anyToVariant( & varRefArg
, aValue
, ::sal::static_int_cast
< VARTYPE
, int >( vt
^ VT_BYREF
) );
372 if( (vt
& VT_TYPEMASK
) == VT_VARIANT
)
373 varArg
.byref
= & varRefArg
;
374 else if ((vt
& VT_TYPEMASK
) == VT_DECIMAL
)
375 varArg
.byref
= & varRefArg
.decVal
;
377 varArg
.byref
= & varRefArg
.byref
;
381 anyToVariant(& varArg
, aValue
, vt
);
384 hr
= m_spDispatch
->Invoke(dispid
, IID_NULL
, LOCALE_USER_DEFAULT
, ::sal::static_int_cast
< WORD
, INVOKEKIND
>( invkind
),
385 &dispparams
, & varResult
, & excepinfo
, &uArgErr
);
392 case DISP_E_BADPARAMCOUNT
:
393 throw RuntimeException();
395 case DISP_E_BADVARTYPE
:
396 throw RuntimeException();
398 case DISP_E_EXCEPTION
:
399 throw InvocationTargetException();
401 case DISP_E_MEMBERNOTFOUND
:
402 throw UnknownPropertyException();
404 case DISP_E_NONAMEDARGS
:
405 throw RuntimeException();
407 case DISP_E_OVERFLOW
:
408 throw CannotConvertException(OUString("call to OLE object failed"), static_cast<XInterface
*>(
409 static_cast<XWeak
*>(this)), TypeClass_UNKNOWN
, FailReason::OUT_OF_RANGE
, uArgErr
);
411 case DISP_E_PARAMNOTFOUND
:
412 throw IllegalArgumentException(OUString("call to OLE object failed"), static_cast<XInterface
*>(
413 static_cast<XWeak
*>(this)), ::sal::static_int_cast
< sal_Int16
, unsigned int >( uArgErr
)) ;
415 case DISP_E_TYPEMISMATCH
:
416 throw CannotConvertException(OUString("call to OLE object failed"), static_cast<XInterface
*>(
417 static_cast<XWeak
*>(this)), TypeClass_UNKNOWN
, FailReason::UNKNOWN
, ::sal::static_int_cast
< sal_Int16
, unsigned int >( uArgErr
));
419 case DISP_E_UNKNOWNINTERFACE
:
420 throw RuntimeException();
422 case DISP_E_UNKNOWNLCID
:
423 throw RuntimeException();
425 case DISP_E_PARAMNOTOPTIONAL
:
426 throw CannotConvertException(OUString("call to OLE object failed"),static_cast<XInterface
*>(
427 static_cast<XWeak
*>(this)) , TypeClass_UNKNOWN
, FailReason::NO_DEFAULT_AVAILABLE
, uArgErr
);
430 throw RuntimeException();
434 catch (const CannotConvertException
&)
438 catch (const UnknownPropertyException
&)
442 catch (const BridgeRuntimeError
& e
)
444 throw RuntimeException(
445 e
.message
, Reference
<XInterface
>());
447 catch (const Exception
& e
)
449 throw RuntimeException("[automation bridge] unexpected exception in "
450 "IUnknownWrapper_Impl::setValue ! Message : \n" +
451 e
.Message
, Reference
<XInterface
>());
456 throw RuntimeException(
457 "[automation bridge] unexpected exception in "
458 "IUnknownWrapper_Impl::setValue !", Reference
<XInterface
>());
462 Any SAL_CALL
IUnknownWrapper_Impl::getValue( const OUString
& aPropertyName
)
463 throw(UnknownPropertyException
, RuntimeException
)
465 if ( ! m_spDispatch
)
467 throw RuntimeException(
468 "[automation bridge] The object does not have an IDispatch interface",
469 Reference
<XInterface
>());
474 o2u_attachCurrentThread();
475 ITypeInfo
* pInfo
= getTypeInfo();
476 // I was going to implement an XServiceInfo interface to allow the type
477 // of the automation object to be exposed.. but it seems
478 // from looking at comments in the code that it is possible for
479 // this object to actually wrap an UNO object ( I guess if automation is
480 // used from MSO to create Openoffice objects ) Therefore, those objects
481 // will more than likely already have their own XServiceInfo interface.
482 // Instead here I chose a name that should be illegal both in COM and
483 // UNO ( from an IDL point of view ) therefore I think this is a safe
485 if ( aPropertyName
== "$GetTypeName" )
487 if ( pInfo
&& m_sTypeName
.getLength() == 0 )
489 m_sTypeName
= OUString("IDispatch");
492 if ( SUCCEEDED( pInfo
->GetDocumentation( -1, &sName
, NULL
, NULL
, NULL
) ) )
494 OUString
sTmp( reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(sName
)));
495 if ( sTmp
.indexOf('_') == 0 )
497 // do we own the memory for pTypeLib, msdn doco is vague
499 CComPtr
< ITypeLib
> pTypeLib
;
501 if ( SUCCEEDED( pInfo
->GetContainingTypeLib( &pTypeLib
.p
, &index
)) )
503 if ( SUCCEEDED( pTypeLib
->GetDocumentation( -1, &sName
, NULL
, NULL
, NULL
) ) )
505 OUString
sLibName( reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(sName
)));
506 m_sTypeName
= sLibName
.concat( OUString(".") ).concat( sTmp
);
516 FuncDesc
aDescGet(pInfo
);
517 FuncDesc
aDescPut(pInfo
);
518 VarDesc
aVarDesc(pInfo
);
519 getPropDesc(aPropertyName
, & aDescGet
, & aDescPut
, & aVarDesc
);
520 if ( ! aDescGet
&& ! aDescPut
&& ! aVarDesc
)
523 OUString
msg("[automation bridge]Property \"" + aPropertyName
+
524 "\" is not supported");
525 throw UnknownPropertyException(msg
, Reference
<XInterface
>());
527 // write-only should not be possible
528 OSL_ASSERT( aDescGet
|| ! aDescPut
);
531 DISPPARAMS dispparams
= {0, 0, 0, 0};
532 CComVariant varResult
;
534 unsigned int uArgErr
;
537 dispid
= aDescGet
->memid
;
539 dispid
= aVarDesc
->memid
;
541 dispid
= aDescPut
->memid
;
543 hr
= m_spDispatch
->Invoke(dispid
,
546 DISPATCH_PROPERTYGET
,
552 // converting return value and out parameter back to UNO
555 // If the com object implements uno interfaces then we have
556 // to convert the attribute into the expected type.
557 TypeDescription attrInfo
;
558 getAttributeInfo(aPropertyName
, attrInfo
);
560 variantToAny( &varResult
, ret
, Type( attrInfo
.get()->pWeakRef
));
562 variantToAny(&varResult
, ret
);
570 case DISP_E_BADPARAMCOUNT
:
571 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
572 Reference
<XInterface
>());
574 case DISP_E_BADVARTYPE
:
575 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
576 Reference
<XInterface
>());
578 case DISP_E_EXCEPTION
:
579 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
580 Reference
<XInterface
>());
582 case DISP_E_MEMBERNOTFOUND
:
583 throw UnknownPropertyException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
584 Reference
<XInterface
>());
586 case DISP_E_NONAMEDARGS
:
587 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
588 Reference
<XInterface
>());
590 case DISP_E_OVERFLOW
:
591 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
592 Reference
<XInterface
>());
594 case DISP_E_PARAMNOTFOUND
:
595 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
596 Reference
<XInterface
>());
598 case DISP_E_TYPEMISMATCH
:
599 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
600 Reference
<XInterface
>());
602 case DISP_E_UNKNOWNINTERFACE
:
603 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
604 Reference
<XInterface
>());
606 case DISP_E_UNKNOWNLCID
:
607 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
608 Reference
<XInterface
>());
610 case DISP_E_PARAMNOTOPTIONAL
:
611 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
612 Reference
<XInterface
>());
615 throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
)),
616 Reference
<XInterface
>());
620 catch ( const UnknownPropertyException
& )
624 catch (const BridgeRuntimeError
& e
)
626 throw RuntimeException(
627 e
.message
, Reference
<XInterface
>());
629 catch (const Exception
& e
)
631 throw RuntimeException("[automation bridge] unexpected exception in "
632 "IUnknownWrapper_Impl::getValue ! Message : \n" +
633 e
.Message
, Reference
<XInterface
>());
637 throw RuntimeException(
638 "[automation bridge] unexpected exception in "
639 "IUnknownWrapper_Impl::getValue !", Reference
<XInterface
>());
644 sal_Bool SAL_CALL
IUnknownWrapper_Impl::hasMethod( const OUString
& aName
)
645 throw(RuntimeException
)
647 if ( ! m_spDispatch
)
649 throw RuntimeException(
650 "[automation bridge] The object does not have an IDispatch interface",
651 Reference
<XInterface
>());
653 sal_Bool ret
= sal_False
;
657 o2u_attachCurrentThread();
658 ITypeInfo
* pInfo
= getTypeInfo();
659 FuncDesc
aDesc(pInfo
);
660 getFuncDesc(aName
, & aDesc
);
661 // Automation properties can have arguments. Those are treated as methods and
662 //are called through XInvocation::invoke.
665 FuncDesc
aDescGet(pInfo
);
666 FuncDesc
aDescPut(pInfo
);
667 VarDesc
aVarDesc(pInfo
);
668 getPropDesc( aName
, & aDescGet
, & aDescPut
, & aVarDesc
);
669 if (aDescGet
&& aDescGet
->cParams
> 0
670 || aDescPut
&& aDescPut
->cParams
> 0)
676 catch (const BridgeRuntimeError
& e
)
678 throw RuntimeException(e
.message
, Reference
<XInterface
>());
680 catch (const Exception
& e
)
682 throw RuntimeException("[automation bridge] unexpected exception in "
683 "IUnknownWrapper_Impl::hasMethod ! Message : \n" +
684 e
.Message
, Reference
<XInterface
>());
688 throw RuntimeException("[automation bridge] unexpected exception in "
689 "IUnknownWrapper_Impl::hasMethod !", Reference
<XInterface
>());
694 sal_Bool SAL_CALL
IUnknownWrapper_Impl::hasProperty( const OUString
& aName
)
695 throw(RuntimeException
)
697 if ( ! m_spDispatch
)
699 throw RuntimeException("[automation bridge] The object does not have an "
700 "IDispatch interface", Reference
<XInterface
>());
702 sal_Bool ret
= sal_False
;
705 o2u_attachCurrentThread();
707 ITypeInfo
* pInfo
= getTypeInfo();
708 FuncDesc
aDescGet(pInfo
);
709 FuncDesc
aDescPut(pInfo
);
710 VarDesc
aVarDesc(pInfo
);
711 getPropDesc(aName
, & aDescGet
, & aDescPut
, & aVarDesc
);
713 // we should probably just check the funckind
714 // basic has been modified to handle properties ( 'get' ) props at
715 // least with parameters
716 // additionally you can call invoke(Get|Set)Property on the bridge
717 // you can determine if a property has parameter is hasMethod
718 // returns true for the name
726 catch (const BridgeRuntimeError
& e
)
728 throw RuntimeException(e
.message
, Reference
<XInterface
>());
730 catch (const Exception
& e
)
732 throw RuntimeException("[automation bridge] unexpected exception in "
733 "IUnknownWrapper_Impl::hasProperty ! Message : \n" +
734 e
.Message
, Reference
<XInterface
>());
739 throw RuntimeException("[automation bridge] unexpected exception in "
740 "IUnknownWrapper_Impl::hasProperty !", Reference
<XInterface
>());
745 Any SAL_CALL
IUnknownWrapper_Impl::createBridge( const Any
& modelDepObject
,
746 const Sequence
< sal_Int8
>& /*aProcessId*/, sal_Int16 sourceModelType
,
747 sal_Int16 destModelType
)
748 throw( IllegalArgumentException
, RuntimeException
)
751 o2u_attachCurrentThread();
754 (sourceModelType
== UNO
) &&
755 (destModelType
== OLE
) &&
756 (modelDepObject
.getValueTypeClass() == TypeClass_INTERFACE
)
759 Reference
<XInterface
> xInt( *(XInterface
**) modelDepObject
.getValue());
760 Reference
<XInterface
> xSelf( (OWeakObject
*)this);
764 VARIANT
* pVariant
= (VARIANT
*) CoTaskMemAlloc(sizeof(VARIANT
));
766 VariantInit(pVariant
);
767 if (m_bOriginalDispatch
== sal_True
)
769 pVariant
->vt
= VT_DISPATCH
;
770 pVariant
->pdispVal
= m_spDispatch
;
771 pVariant
->pdispVal
->AddRef();
775 pVariant
->vt
= VT_UNKNOWN
;
776 pVariant
->punkVal
= m_spUnknown
;
777 pVariant
->punkVal
->AddRef();
780 ret
.setValue((void*)&pVariant
, getCppuType( (sal_uInt32
*) 0));
787 @exception IllegalArgumentException
788 @exception CannotConvertException
789 @exception InvocationTargetException
792 Any
IUnknownWrapper_Impl::invokeWithDispIdUnoTlb(const OUString
& sFunctionName
,
793 const Sequence
< Any
>& Params
,
794 Sequence
< sal_Int16
>& OutParamIndex
,
795 Sequence
< Any
>& OutParam
)
800 sal_Int32 parameterCount
= Params
.getLength();
801 sal_Int32 outParameterCount
= 0;
802 typelib_InterfaceMethodTypeDescription
* pMethod
= NULL
;
803 TypeDescription methodDesc
;
804 getMethodInfo(sFunctionName
, methodDesc
);
806 // We need to know whether the IDispatch is from a JScript object.
807 // Then out and in/out parameters have to be treated differently than
808 // with common COM objects.
809 sal_Bool bJScriptObject
= isJScriptObject();
810 scoped_array
<CComVariant
> sarParams
;
811 scoped_array
<CComVariant
> sarParamsRef
;
812 CComVariant
*pVarParams
= NULL
;
813 CComVariant
*pVarParamsRef
= NULL
;
814 sal_Bool bConvRet
= sal_True
;
818 pMethod
= (typelib_InterfaceMethodTypeDescription
* )methodDesc
.get();
819 parameterCount
= pMethod
->nParams
;
820 // Create the Array for the array being passed in DISPPARAMS
821 // the array also contains the outparameter (but not the values)
822 if( pMethod
->nParams
> 0)
824 sarParams
.reset(new CComVariant
[ parameterCount
]);
825 pVarParams
= sarParams
.get();
828 // Create the Array for the out an in/out parameter. These values
829 // are referenced by the VT_BYREF VARIANTs in DISPPARAMS.
830 // We need to find out the number of out and in/out parameter.
831 for( sal_Int32 i
=0; i
< parameterCount
; i
++)
833 if( pMethod
->pParams
[i
].bOut
)
839 sarParamsRef
.reset(new CComVariant
[outParameterCount
]);
840 pVarParamsRef
= sarParamsRef
.get();
841 // build up the parameters for IDispatch::Invoke
842 sal_Int32 outParamIndex
=0;
846 for( i
= 0; i
< parameterCount
; i
++)
849 if( pMethod
->pParams
[i
].bIn
== sal_True
&& ! pMethod
->pParams
[i
].bOut
)
851 anyToVariant( &pVarParams
[parameterCount
- i
-1], Params
.getConstArray()[i
]);
853 // Out parameter + in/out parameter
854 else if( pMethod
->pParams
[i
].bOut
== sal_True
)
857 if(pMethod
->pParams
[i
].bIn
)
859 anyToVariant( & var
,Params
[i
]);
860 pVarParamsRef
[outParamIndex
] = var
;
863 switch( pMethod
->pParams
[i
].pTypeRef
->eTypeClass
)
865 case TypeClass_INTERFACE
:
866 case TypeClass_STRUCT
:
867 if( ! pMethod
->pParams
[i
].bIn
)
869 pVarParamsRef
[ outParamIndex
].vt
= VT_DISPATCH
;
870 pVarParamsRef
[ outParamIndex
].pdispVal
= 0;
872 pVarParams
[parameterCount
- i
-1].vt
= VT_DISPATCH
| VT_BYREF
;
873 pVarParams
[parameterCount
- i
-1].ppdispVal
= &pVarParamsRef
[outParamIndex
].pdispVal
;
877 case TypeClass_UNSIGNED_LONG
:
878 if( ! pMethod
->pParams
[i
].bIn
)
880 pVarParamsRef
[ outParamIndex
].vt
= VT_I4
;
881 pVarParamsRef
[ outParamIndex
].lVal
= 0;
883 pVarParams
[parameterCount
- i
-1].vt
= VT_I4
| VT_BYREF
;
884 pVarParams
[parameterCount
- i
-1].plVal
= &pVarParamsRef
[outParamIndex
].lVal
;
886 case TypeClass_SEQUENCE
:
887 if( ! pMethod
->pParams
[i
].bIn
)
889 pVarParamsRef
[ outParamIndex
].vt
= VT_ARRAY
| VT_VARIANT
;
890 pVarParamsRef
[ outParamIndex
].parray
= NULL
;
892 pVarParams
[parameterCount
- i
-1].vt
= VT_ARRAY
| VT_BYREF
| VT_VARIANT
;
893 pVarParams
[parameterCount
- i
-1].pparray
= &pVarParamsRef
[outParamIndex
].parray
;
896 if( ! pMethod
->pParams
[i
].bIn
)
898 pVarParamsRef
[ outParamIndex
].vt
= VT_EMPTY
;
899 pVarParamsRef
[ outParamIndex
].lVal
= 0;
901 pVarParams
[parameterCount
- i
-1].vt
= VT_VARIANT
| VT_BYREF
;
902 pVarParams
[parameterCount
- i
-1].pvarVal
= &pVarParamsRef
[outParamIndex
];
904 case TypeClass_BOOLEAN
:
905 if( ! pMethod
->pParams
[i
].bIn
)
907 pVarParamsRef
[ outParamIndex
].vt
= VT_BOOL
;
908 pVarParamsRef
[ outParamIndex
].boolVal
= 0;
910 pVarParams
[parameterCount
- i
-1].vt
= VT_BOOL
| VT_BYREF
;
911 pVarParams
[parameterCount
- i
-1].pboolVal
=
912 & pVarParamsRef
[outParamIndex
].boolVal
;
915 case TypeClass_STRING
:
916 if( ! pMethod
->pParams
[i
].bIn
)
918 pVarParamsRef
[ outParamIndex
].vt
= VT_BSTR
;
919 pVarParamsRef
[ outParamIndex
].bstrVal
= 0;
921 pVarParams
[parameterCount
- i
-1].vt
= VT_BSTR
| VT_BYREF
;
922 pVarParams
[parameterCount
- i
-1].pbstrVal
=
923 & pVarParamsRef
[outParamIndex
].bstrVal
;
926 case TypeClass_FLOAT
:
927 if( ! pMethod
->pParams
[i
].bIn
)
929 pVarParamsRef
[ outParamIndex
].vt
= VT_R4
;
930 pVarParamsRef
[ outParamIndex
].fltVal
= 0;
932 pVarParams
[parameterCount
- i
-1].vt
= VT_R4
| VT_BYREF
;
933 pVarParams
[parameterCount
- i
-1].pfltVal
=
934 & pVarParamsRef
[outParamIndex
].fltVal
;
936 case TypeClass_DOUBLE
:
937 if( ! pMethod
->pParams
[i
].bIn
)
939 pVarParamsRef
[ outParamIndex
].vt
= VT_R8
;
940 pVarParamsRef
[ outParamIndex
].dblVal
= 0;
942 pVarParams
[parameterCount
- i
-1].vt
= VT_R8
| VT_BYREF
;
943 pVarParams
[parameterCount
- i
-1].pdblVal
=
944 & pVarParamsRef
[outParamIndex
].dblVal
;
947 if( ! pMethod
->pParams
[i
].bIn
)
949 pVarParamsRef
[ outParamIndex
].vt
= VT_UI1
;
950 pVarParamsRef
[ outParamIndex
].bVal
= 0;
952 pVarParams
[parameterCount
- i
-1].vt
= VT_UI1
| VT_BYREF
;
953 pVarParams
[parameterCount
- i
-1].pbVal
=
954 & pVarParamsRef
[outParamIndex
].bVal
;
957 case TypeClass_SHORT
:
958 case TypeClass_UNSIGNED_SHORT
:
959 if( ! pMethod
->pParams
[i
].bIn
)
961 pVarParamsRef
[ outParamIndex
].vt
= VT_I2
;
962 pVarParamsRef
[ outParamIndex
].iVal
= 0;
964 pVarParams
[parameterCount
- i
-1].vt
= VT_I2
| VT_BYREF
;
965 pVarParams
[parameterCount
- i
-1].piVal
=
966 & pVarParamsRef
[outParamIndex
].iVal
;
970 if( ! pMethod
->pParams
[i
].bIn
)
972 pVarParamsRef
[ outParamIndex
].vt
= VT_EMPTY
;
973 pVarParamsRef
[ outParamIndex
].lVal
= 0;
975 pVarParams
[parameterCount
- i
-1].vt
= VT_VARIANT
| VT_BYREF
;
976 pVarParams
[parameterCount
- i
-1].pvarVal
=
977 & pVarParamsRef
[outParamIndex
];
983 catch (IllegalArgumentException
& e
)
985 e
.ArgumentPosition
= ::sal::static_int_cast
< sal_Int16
, int >( i
);
988 catch (CannotConvertException
& e
)
994 else // it is an JScriptObject
999 for( ; i
< parameterCount
; i
++)
1002 if( pMethod
->pParams
[i
].bIn
== sal_True
&& ! pMethod
->pParams
[i
].bOut
)
1004 anyToVariant( &pVarParams
[parameterCount
- i
-1], Params
.getConstArray()[i
]);
1006 // Out parameter + in/out parameter
1007 else if( pMethod
->pParams
[i
].bOut
== sal_True
)
1009 CComObject
<JScriptOutParam
>* pParamObject
;
1010 if( SUCCEEDED( CComObject
<JScriptOutParam
>::CreateInstance( &pParamObject
)))
1012 CComPtr
<IUnknown
> pUnk(pParamObject
->GetUnknown());
1014 CComQIPtr
<IDispatch
, &__uuidof(IDispatch
)> pDisp( pUnk
);
1016 CComQIPtr
<IDispatch
> pDisp( pUnk
);
1019 pVarParams
[ parameterCount
- i
-1].vt
= VT_DISPATCH
;
1020 pVarParams
[ parameterCount
- i
-1].pdispVal
= pDisp
;
1021 pVarParams
[ parameterCount
- i
-1].pdispVal
->AddRef();
1022 // if the param is in/out then put the parameter on index 0
1023 if( pMethod
->pParams
[i
].bIn
== sal_True
) // in / out
1025 CComVariant varParam
;
1026 anyToVariant( &varParam
, Params
.getConstArray()[i
]);
1027 CComDispatchDriver
dispDriver( pDisp
);
1028 if(FAILED( dispDriver
.PutPropertyByName( L
"0", &varParam
)))
1029 throw BridgeRuntimeError(
1030 "[automation bridge]IUnknownWrapper_Impl::"
1031 "invokeWithDispIdUnoTlb\n"
1032 "Could not set property \"0\" for the in/out "
1039 throw BridgeRuntimeError(
1040 "[automation bridge]IUnknownWrapper_Impl::"
1041 "invokeWithDispIdUnoTlb\n"
1042 "Could not create out parameter at index: " +
1043 OUString::valueOf((sal_Int32
) i
));
1049 catch (IllegalArgumentException
& e
)
1051 e
.ArgumentPosition
= ::sal::static_int_cast
< sal_Int16
, int >( i
);
1054 catch (CannotConvertException
& e
)
1056 e
.ArgumentIndex
= i
;
1061 // No type description Available, that is we have to deal with a COM component,
1062 // that does not implements UNO interfaces ( IDispatch based)
1065 //We should not run into this block, because invokeWithDispIdComTlb should
1066 //have been called instead.
1071 CComVariant varResult
;
1072 ExcepInfo excepinfo
;
1073 unsigned int uArgErr
;
1074 DISPPARAMS dispparams
= { pVarParams
, NULL
, parameterCount
, 0};
1076 FuncDesc
aDesc(getTypeInfo());
1077 getFuncDesc(sFunctionName
, & aDesc
);
1078 // invoking OLE method
1079 hr
= m_spDispatch
->Invoke(aDesc
->memid
,
1081 LOCALE_USER_DEFAULT
,
1088 // converting return value and out parameter back to UNO
1091 if( outParameterCount
&& pMethod
)
1093 OutParamIndex
.realloc( outParameterCount
);
1094 OutParam
.realloc( outParameterCount
);
1095 sal_Int32 outIndex
=0;
1099 for( ; i
< parameterCount
; i
++)
1101 if( pMethod
->pParams
[i
].bOut
)
1103 OutParamIndex
[outIndex
]= (sal_Int16
) i
;
1105 if( !bJScriptObject
)
1107 variantToAny( &pVarParamsRef
[outIndex
], outAny
,
1108 Type(pMethod
->pParams
[i
].pTypeRef
), sal_False
);
1109 OutParam
[outIndex
++]= outAny
;
1111 else //JScriptObject
1113 if( pVarParams
[i
].vt
== VT_DISPATCH
)
1115 CComDispatchDriver
pDisp( pVarParams
[i
].pdispVal
);
1119 if( SUCCEEDED( pDisp
.GetPropertyByName( L
"0", &varOut
)))
1121 variantToAny( &varOut
, outAny
,
1122 Type(pMethod
->pParams
[parameterCount
- 1 - i
].pTypeRef
), sal_False
);
1123 OutParam
[outParameterCount
- 1 - outIndex
++]= outAny
;
1126 bConvRet
= sal_False
;
1129 bConvRet
= sal_False
;
1132 bConvRet
= sal_False
;
1135 if( !bConvRet
) break;
1138 catch(IllegalArgumentException
& e
)
1140 e
.ArgumentPosition
= ::sal::static_int_cast
< sal_Int16
, int >( i
);
1143 catch(CannotConvertException
& e
)
1145 e
.ArgumentIndex
= i
;
1149 // return value, no type information available
1155 variantToAny(&varResult
, ret
, Type( pMethod
->pReturnTypeRef
), sal_False
);
1157 variantToAny(&varResult
, ret
, sal_False
);
1159 catch (IllegalArgumentException
& e
)
1162 "[automation bridge]IUnknownWrapper_Impl::invokeWithDispIdUnoTlb\n"
1163 "Could not convert return value! \n Message: \n" + e
.Message
;
1166 catch (CannotConvertException
& e
)
1169 "[automation bridge]IUnknownWrapper_Impl::invokeWithDispIdUnoTlb\n"
1170 "Could not convert return value! \n Message: \n" + e
.Message
;
1176 if( !bConvRet
) // conversion of return or out parameter failed
1177 throw CannotConvertException( OUString("Call to COM object failed. Conversion of return or out value failed"),
1178 Reference
<XInterface
>( static_cast<XWeak
*>(this), UNO_QUERY
), TypeClass_UNKNOWN
,
1179 FailReason::UNKNOWN
, 0);// lookup error code
1180 // conversion of return or out parameter failed
1185 case DISP_E_BADPARAMCOUNT
:
1186 throw IllegalArgumentException();
1188 case DISP_E_BADVARTYPE
:
1189 throw RuntimeException();
1191 case DISP_E_EXCEPTION
:
1192 throw InvocationTargetException();
1194 case DISP_E_MEMBERNOTFOUND
:
1195 throw IllegalArgumentException();
1197 case DISP_E_NONAMEDARGS
:
1198 throw IllegalArgumentException();
1200 case DISP_E_OVERFLOW
:
1201 throw CannotConvertException(OUString("call to OLE object failed"), static_cast<XInterface
*>(
1202 static_cast<XWeak
*>(this)), TypeClass_UNKNOWN
, FailReason::OUT_OF_RANGE
, uArgErr
);
1204 case DISP_E_PARAMNOTFOUND
:
1205 throw IllegalArgumentException(OUString("call to OLE object failed"), static_cast<XInterface
*>(
1206 static_cast<XWeak
*>(this)), ::sal::static_int_cast
< sal_Int16
, unsigned int >( uArgErr
));
1208 case DISP_E_TYPEMISMATCH
:
1209 throw CannotConvertException(OUString("call to OLE object failed"),static_cast<XInterface
*>(
1210 static_cast<XWeak
*>(this)) , TypeClass_UNKNOWN
, FailReason::UNKNOWN
, uArgErr
);
1212 case DISP_E_UNKNOWNINTERFACE
:
1213 throw RuntimeException() ;
1215 case DISP_E_UNKNOWNLCID
:
1216 throw RuntimeException() ;
1218 case DISP_E_PARAMNOTOPTIONAL
:
1219 throw CannotConvertException(OUString("call to OLE object failed"), static_cast<XInterface
*>(
1220 static_cast<XWeak
*>(this)), TypeClass_UNKNOWN
, FailReason::NO_DEFAULT_AVAILABLE
, uArgErr
);
1223 throw RuntimeException();
1232 // --------------------------
1234 void SAL_CALL
IUnknownWrapper_Impl::initialize( const Sequence
< Any
>& aArguments
) throw(Exception
, RuntimeException
)
1236 // 1.parameter is IUnknown
1237 // 2.parameter is a boolean which indicates if the COM pointer was a IUnknown or IDispatch
1238 // 3.parameter is a Sequence<Type>
1239 o2u_attachCurrentThread();
1240 OSL_ASSERT(aArguments
.getLength() == 3);
1242 m_spUnknown
= *(IUnknown
**) aArguments
[0].getValue();
1244 m_spUnknown
->QueryInterface(IID_IDispatch
, reinterpret_cast<LPVOID
*>( & m_spDispatch
.p
));
1246 m_spUnknown
.QueryInterface( & m_spDispatch
.p
);
1249 aArguments
[1] >>= m_bOriginalDispatch
;
1250 aArguments
[2] >>= m_seqTypes
;
1252 ITypeInfo
* pType
= NULL
;
1255 // a COM object implementation that has no TypeInfo is still a legal COM object;
1256 // such objects can at least be transported through UNO using the bridge
1257 // so we should allow to create wrappers for them as well
1258 pType
= getTypeInfo();
1260 catch( const BridgeRuntimeError
& )
1262 catch( const Exception
& )
1269 // Get Default member
1270 CComBSTR defaultMemberName
;
1271 if ( SUCCEEDED( pType
->GetDocumentation(0, &defaultMemberName
, 0, 0, 0 ) ) )
1273 OUString
usName(reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(defaultMemberName
)));
1274 FuncDesc
aDescGet(pType
);
1275 FuncDesc
aDescPut(pType
);
1276 VarDesc
aVarDesc(pType
);
1277 // see if this is a property first ( more likely to be a property then a method )
1278 getPropDesc( usName
, & aDescGet
, & aDescPut
, & aVarDesc
);
1280 if ( !aDescGet
&& !aDescPut
)
1282 getFuncDesc( usName
, &aDescGet
);
1284 throw BridgeRuntimeError( "[automation bridge]IUnknownWrapper_Impl::initialize() Failed to get Function or Property desc. for " + usName
);
1286 // now for some funny heuristics to make basic understand what to do
1287 // a single aDescGet ( that doesn't take any params ) would be
1288 // a read only ( defaultmember ) property e.g. this object
1289 // should implement XDefaultProperty
1290 // a single aDescGet ( that *does* ) take params is basically a
1291 // default method e.g. implement XDefaultMethod
1293 // a DescPut ( I guess we only really support a default param with '1' param ) as a setValue ( but I guess we can leave it through, the object will fail if we don't get it right anyway )
1294 if ( aDescPut
|| ( aDescGet
&& aDescGet
->cParams
== 0 ) )
1295 m_bHasDfltProperty
= true;
1296 if ( aDescGet
->cParams
> 0 )
1297 m_bHasDfltMethod
= true;
1298 if ( m_bHasDfltProperty
|| m_bHasDfltMethod
)
1299 m_sDefaultMember
= usName
;
1302 catch ( const BridgeRuntimeError
& e
)
1304 throw RuntimeException( e
.message
, Reference
<XInterface
>() );
1306 catch( const Exception
& e
)
1308 throw RuntimeException(
1309 "[automation bridge] unexpected exception in IUnknownWrapper_Impl::initialiase() error message: \n" + e
.Message
,
1310 Reference
<XInterface
>() );
1315 // --------------------------
1316 // XDirectInvocation
1317 uno::Any SAL_CALL
IUnknownWrapper_Impl::directInvoke( const OUString
& aName
, const uno::Sequence
< uno::Any
>& aParams
)
1318 throw (lang::IllegalArgumentException
, script::CannotConvertException
, reflection::InvocationTargetException
, uno::RuntimeException
)
1322 if ( !m_spDispatch
)
1324 throw RuntimeException(
1325 "[automation bridge] The object does not have an IDispatch interface",
1326 Reference
<XInterface
>());
1329 o2u_attachCurrentThread();
1331 if ( !getDispid( aName
, &dispid
) )
1332 throw IllegalArgumentException(
1333 "[automation bridge] The object does not have a function or property "
1334 + aName
, Reference
<XInterface
>(), 0);
1336 CComVariant varResult
;
1337 ExcepInfo excepinfo
;
1338 unsigned int uArgErr
= 0;
1339 INVOKEKIND pInvkinds
[2];
1340 pInvkinds
[0] = INVOKE_FUNC
;
1341 pInvkinds
[1] = aParams
.getLength() ? INVOKE_PROPERTYPUT
: INVOKE_PROPERTYGET
;
1342 HRESULT hInvRes
= E_FAIL
;
1344 // try Invoke first, if it does not work, try put/get property
1345 for ( sal_Int32 nStep
= 0; FAILED( hInvRes
) && nStep
< 2; nStep
++ )
1347 DISPPARAMS dispparams
= {NULL
, NULL
, 0, 0};
1349 DISPID idPropertyPut
= DISPID_PROPERTYPUT
;
1350 scoped_array
<DISPID
> arDispidNamedArgs
;
1351 scoped_array
<CComVariant
> ptrArgs
;
1352 scoped_array
<CComVariant
> ptrRefArgs
; // referenced arguments
1353 CComVariant
* arArgs
= NULL
;
1354 CComVariant
* arRefArgs
= NULL
;
1356 dispparams
.cArgs
= aParams
.getLength();
1358 // Determine the number of named arguments
1359 for ( sal_Int32 nInd
= 0; nInd
< aParams
.getLength(); nInd
++ )
1360 if ( aParams
[nInd
].getValueType() == getCppuType((NamedArgument
*) 0) )
1361 dispparams
.cNamedArgs
++;
1363 // fill the named arguments
1364 if ( dispparams
.cNamedArgs
> 0
1365 && !( dispparams
.cNamedArgs
== 1 && pInvkinds
[nStep
] == INVOKE_PROPERTYPUT
) )
1367 int nSizeAr
= dispparams
.cNamedArgs
+ 1;
1368 if ( pInvkinds
[nStep
] == INVOKE_PROPERTYPUT
)
1369 nSizeAr
= dispparams
.cNamedArgs
;
1371 scoped_array
<OLECHAR
*> saNames(new OLECHAR
*[nSizeAr
]);
1372 OLECHAR
** pNames
= saNames
.get();
1373 pNames
[0] = const_cast<OLECHAR
*>(reinterpret_cast<LPCOLESTR
>(aName
.getStr()));
1376 for ( size_t nInd
= 0; nInd
< dispparams
.cArgs
; nInd
++ )
1378 if ( aParams
[nInd
].getValueType() == getCppuType((NamedArgument
*) 0))
1380 const NamedArgument
& arg
= *(NamedArgument
const*)aParams
[nInd
].getValue();
1382 //We put the parameter names in reverse order into the array,
1383 //so we can use the DISPID array for DISPPARAMS::rgdispidNamedArgs
1384 //The first name in the array is the method name
1385 pNames
[nSizeAr
- 1 - cNamedArg
++] = const_cast<OLECHAR
*>(reinterpret_cast<LPCOLESTR
>(arg
.Name
.getStr()));
1389 arDispidNamedArgs
.reset( new DISPID
[nSizeAr
] );
1390 HRESULT hr
= getTypeInfo()->GetIDsOfNames( pNames
, nSizeAr
, arDispidNamedArgs
.get() );
1391 if ( hr
== E_NOTIMPL
)
1392 hr
= m_spDispatch
->GetIDsOfNames(IID_NULL
, pNames
, nSizeAr
, LOCALE_USER_DEFAULT
, arDispidNamedArgs
.get() );
1394 if ( SUCCEEDED( hr
) )
1396 if ( pInvkinds
[nStep
] == DISPATCH_PROPERTYPUT
)
1398 DISPID
* arIDs
= arDispidNamedArgs
.get();
1399 arIDs
[0] = DISPID_PROPERTYPUT
;
1400 dispparams
.rgdispidNamedArgs
= arIDs
;
1404 DISPID
* arIDs
= arDispidNamedArgs
.get();
1405 dispparams
.rgdispidNamedArgs
= & arIDs
[1];
1408 else if (hr
== DISP_E_UNKNOWNNAME
)
1410 throw IllegalArgumentException(
1411 "[automation bridge]One of the named arguments is wrong!",
1412 Reference
<XInterface
>(), 0);
1416 throw InvocationTargetException(
1417 "[automation bridge] ITypeInfo::GetIDsOfNames returned error "
1418 + OUString::valueOf((sal_Int32
) hr
, 16), Reference
<XInterface
>(), Any());
1423 ptrArgs
.reset(new CComVariant
[dispparams
.cArgs
]);
1424 ptrRefArgs
.reset(new CComVariant
[dispparams
.cArgs
]);
1425 arArgs
= ptrArgs
.get();
1426 arRefArgs
= ptrRefArgs
.get();
1431 sal_Int32 revIndex
= 0;
1432 for ( nInd
= 0; nInd
< sal_Int32(dispparams
.cArgs
); nInd
++)
1434 revIndex
= dispparams
.cArgs
- nInd
- 1;
1435 arRefArgs
[revIndex
].byref
= 0;
1437 if ( nInd
< aParams
.getLength() )
1438 anyArg
= aParams
.getConstArray()[nInd
];
1440 // Property Put arguments
1441 if ( anyArg
.getValueType() == getCppuType((PropertyPutArgument
*)0) )
1443 PropertyPutArgument arg
;
1445 anyArg
<<= arg
.Value
;
1448 if (anyArg
.getValueType() == getCppuType((NamedArgument
*) 0))
1450 NamedArgument aNamedArgument
;
1451 anyArg
>>= aNamedArgument
;
1452 anyArg
<<= aNamedArgument
.Value
;
1455 if ( nInd
< aParams
.getLength() && anyArg
.getValueTypeClass() != TypeClass_VOID
)
1457 anyToVariant( &arArgs
[revIndex
], anyArg
, VT_VARIANT
);
1461 arArgs
[revIndex
].vt
= VT_ERROR
;
1462 arArgs
[revIndex
].scode
= DISP_E_PARAMNOTFOUND
;
1466 catch (IllegalArgumentException
& e
)
1468 e
.ArgumentPosition
= ::sal::static_int_cast
< sal_Int16
, sal_Int32
>( nInd
);
1471 catch (CannotConvertException
& e
)
1473 e
.ArgumentIndex
= nInd
;
1477 dispparams
.rgvarg
= arArgs
;
1478 // invoking OLE method
1479 DWORD localeId
= LOCALE_USER_DEFAULT
;
1480 hInvRes
= m_spDispatch
->Invoke( dispid
,
1483 ::sal::static_int_cast
< WORD
, INVOKEKIND
>( pInvkinds
[nStep
] ),
1490 // converting return value and out parameter back to UNO
1491 if ( SUCCEEDED( hInvRes
) )
1492 variantToAny( &varResult
, aResult
, sal_False
);
1495 // map error codes to exceptions
1501 case DISP_E_BADPARAMCOUNT
:
1502 throw IllegalArgumentException("[automation bridge] Wrong "
1503 "number of arguments. Object returned DISP_E_BADPARAMCOUNT.",
1506 case DISP_E_BADVARTYPE
:
1507 throw RuntimeException("[automation bridge] One or more "
1508 "arguments have the wrong type. Object returned "
1509 "DISP_E_BADVARTYPE.", 0);
1511 case DISP_E_EXCEPTION
:
1512 message
= "[automation bridge]: ";
1513 message
+= OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
),
1514 ::SysStringLen(excepinfo
.bstrDescription
));
1515 throw InvocationTargetException(message
, Reference
<XInterface
>(), Any());
1517 case DISP_E_MEMBERNOTFOUND
:
1518 message
= "[automation bridge]: A function with the name \""
1519 + aName
+ "\" is not supported. Object returned "
1520 "DISP_E_MEMBERNOTFOUND.";
1521 throw IllegalArgumentException(message
, 0, 0);
1523 case DISP_E_NONAMEDARGS
:
1524 throw IllegalArgumentException("[automation bridge] Object "
1525 "returned DISP_E_NONAMEDARGS",0, ::sal::static_int_cast
< sal_Int16
, unsigned int >( uArgErr
));
1527 case DISP_E_OVERFLOW
:
1528 throw CannotConvertException(OUString("[automation bridge] Call failed."),
1529 static_cast<XInterface
*>(
1530 static_cast<XWeak
*>(this)), TypeClass_UNKNOWN
, FailReason::OUT_OF_RANGE
, uArgErr
);
1532 case DISP_E_PARAMNOTFOUND
:
1533 throw IllegalArgumentException("[automation bridge]Call failed."
1534 "Object returned DISP_E_PARAMNOTFOUND.",
1535 0, ::sal::static_int_cast
< sal_Int16
, unsigned int >( uArgErr
));
1537 case DISP_E_TYPEMISMATCH
:
1538 throw CannotConvertException("[automation bridge] Call failed. "
1539 "Object returned DISP_E_TYPEMISMATCH",
1540 static_cast<XInterface
*>(
1541 static_cast<XWeak
*>(this)) , TypeClass_UNKNOWN
, FailReason::UNKNOWN
, uArgErr
);
1543 case DISP_E_UNKNOWNINTERFACE
:
1544 throw RuntimeException("[automation bridge] Call failed. "
1545 "Object returned DISP_E_UNKNOWNINTERFACE.",0);
1547 case DISP_E_UNKNOWNLCID
:
1548 throw RuntimeException("[automation bridge] Call failed. "
1549 "Object returned DISP_E_UNKNOWNLCID.",0);
1551 case DISP_E_PARAMNOTOPTIONAL
:
1552 throw CannotConvertException("[automation bridge] Call failed."
1553 "Object returned DISP_E_PARAMNOTOPTIONAL",
1554 static_cast<XInterface
*>(static_cast<XWeak
*>(this)),
1555 TypeClass_UNKNOWN
, FailReason::NO_DEFAULT_AVAILABLE
, uArgErr
);
1558 throw RuntimeException();
1566 ::sal_Bool SAL_CALL
IUnknownWrapper_Impl::hasMember( const OUString
& aName
)
1567 throw (uno::RuntimeException
)
1569 if ( ! m_spDispatch
)
1571 throw RuntimeException(
1572 "[automation bridge] The object does not have an IDispatch interface",
1573 Reference
<XInterface
>());
1576 o2u_attachCurrentThread();
1578 return getDispid( aName
, &dispid
);
1582 // UnoConversionUtilities --------------------------------------------------------------------------------
1583 Reference
< XInterface
> IUnknownWrapper_Impl::createUnoWrapperInstance()
1585 if( m_nUnoWrapperClass
== INTERFACE_OLE_WRAPPER_IMPL
)
1587 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper_Impl(
1588 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
1589 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
1591 else if( m_nUnoWrapperClass
== UNO_OBJECT_WRAPPER_REMOTE_OPT
)
1593 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
1594 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
1595 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
1598 return Reference
<XInterface
>();
1600 Reference
<XInterface
> IUnknownWrapper_Impl::createComWrapperInstance()
1602 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper_Impl(
1603 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
1604 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
1609 void IUnknownWrapper_Impl::getMethodInfo(const OUString
& sName
, TypeDescription
& methodInfo
)
1611 TypeDescription desc
= getInterfaceMemberDescOfCurrentCall(sName
);
1614 typelib_TypeDescription
* pMember
= desc
.get();
1615 if( pMember
->eTypeClass
== TypeClass_INTERFACE_METHOD
)
1616 methodInfo
= pMember
;
1620 void IUnknownWrapper_Impl::getAttributeInfo(const OUString
& sName
, TypeDescription
& attributeInfo
)
1622 TypeDescription desc
= getInterfaceMemberDescOfCurrentCall(sName
);
1625 typelib_TypeDescription
* pMember
= desc
.get();
1626 if( pMember
->eTypeClass
== TypeClass_INTERFACE_ATTRIBUTE
)
1628 attributeInfo
= ((typelib_InterfaceAttributeTypeDescription
*)pMember
)->pAttributeTypeRef
;
1632 TypeDescription
IUnknownWrapper_Impl::getInterfaceMemberDescOfCurrentCall(const OUString
& sName
)
1634 TypeDescription ret
;
1636 for( sal_Int32 i
=0; i
< m_seqTypes
.getLength(); i
++)
1638 TypeDescription
_curDesc( m_seqTypes
[i
]);
1639 _curDesc
.makeComplete();
1640 typelib_InterfaceTypeDescription
* pInterface
= (typelib_InterfaceTypeDescription
*) _curDesc
.get();
1643 typelib_InterfaceMemberTypeDescription
* pMember
= NULL
;
1644 //find the member description of the current call
1645 for( int i
=0; i
< pInterface
->nAllMembers
; i
++)
1647 typelib_TypeDescriptionReference
* pTypeRefMember
= pInterface
->ppAllMembers
[i
];
1648 typelib_TypeDescription
* pDescMember
= NULL
;
1649 TYPELIB_DANGER_GET( &pDescMember
, pTypeRefMember
)
1651 typelib_InterfaceMemberTypeDescription
* pInterfaceMember
=
1652 (typelib_InterfaceMemberTypeDescription
*) pDescMember
;
1653 if( OUString( pInterfaceMember
->pMemberName
) == sName
)
1655 pMember
= pInterfaceMember
;
1658 TYPELIB_DANGER_RELEASE( pDescMember
)
1663 ret
= (typelib_TypeDescription
*)pMember
;
1664 TYPELIB_DANGER_RELEASE( (typelib_TypeDescription
*)pMember
);
1673 sal_Bool
IUnknownWrapper_Impl::isJScriptObject()
1675 if( m_eJScript
== JScriptUndefined
)
1677 CComDispatchDriver
disp( m_spDispatch
);
1681 if( SUCCEEDED( disp
.GetPropertyByName( JSCRIPT_ID_PROPERTY
, &result
)))
1683 if(result
.vt
== VT_BSTR
)
1685 CComBSTR
name( result
.bstrVal
);
1687 if( name
== CComBSTR(JSCRIPT_ID
))
1688 m_eJScript
= IsJScript
;
1692 if( m_eJScript
== JScriptUndefined
)
1693 m_eJScript
= NoJScript
;
1696 return m_eJScript
== NoJScript
? sal_False
: sal_True
;
1702 The function ultimately calls IDispatch::Invoke on the wrapped COM object.
1703 The COM object does not implement UNO Interfaces ( via IDispatch). This
1704 is the case when the OleObjectFactory service has been used to create a
1706 @exception IllegalArgumentException
1707 @exception CannotConvertException
1708 @InvocationTargetException
1712 Any
IUnknownWrapper_Impl::invokeWithDispIdComTlb(const OUString
& sFuncName
,
1713 const Sequence
< Any
>& Params
,
1714 Sequence
< sal_Int16
>& OutParamIndex
,
1715 Sequence
< Any
>& OutParam
)
1717 // Get type info for the call. It can be a method call or property put or
1718 // property get operation.
1719 FuncDesc
aFuncDesc(getTypeInfo());
1720 getFuncDescForInvoke(sFuncName
, Params
, & aFuncDesc
);
1721 return invokeWithDispIdComTlb( aFuncDesc
, sFuncName
, Params
, OutParamIndex
, OutParam
);
1724 Any
IUnknownWrapper_Impl::invokeWithDispIdComTlb(FuncDesc
& aFuncDesc
,
1725 const OUString
& sFuncName
,
1726 const Sequence
< Any
>& Params
,
1727 Sequence
< sal_Int16
>& OutParamIndex
,
1728 Sequence
< Any
>& OutParam
)
1733 DISPPARAMS dispparams
= {NULL
, NULL
, 0, 0};
1734 CComVariant varResult
;
1735 ExcepInfo excepinfo
;
1736 unsigned int uArgErr
;
1738 sal_Int32 nUnoArgs
= Params
.getLength();
1739 DISPID idPropertyPut
= DISPID_PROPERTYPUT
;
1740 scoped_array
<DISPID
> arDispidNamedArgs
;
1741 scoped_array
<CComVariant
> ptrArgs
;
1742 scoped_array
<CComVariant
> ptrRefArgs
; // referenced arguments
1743 CComVariant
* arArgs
= NULL
;
1744 CComVariant
* arRefArgs
= NULL
;
1745 sal_Int32 revIndex
= 0;
1747 //Set the array of DISPIDs for named args if it is a property put operation.
1748 //If there are other named arguments another array is set later on.
1749 if (aFuncDesc
->invkind
== INVOKE_PROPERTYPUT
1750 || aFuncDesc
->invkind
== INVOKE_PROPERTYPUTREF
)
1751 dispparams
.rgdispidNamedArgs
= & idPropertyPut
;
1753 //Determine the number of named arguments
1754 for (int iParam
= 0; iParam
< nUnoArgs
; iParam
++)
1756 const Any
& curArg
= Params
[iParam
];
1757 if (curArg
.getValueType() == getCppuType((NamedArgument
*) 0))
1758 dispparams
.cNamedArgs
++;
1760 //In a property put operation a property value is a named argument (DISPID_PROPERTYPUT).
1761 //Therefore the number of named arguments is increased by one.
1762 //Although named, the argument is not named in a actual language, such as Basic,
1763 //therefore it is never a com.sun.star.bridge.oleautomation.NamedArgument
1764 if (aFuncDesc
->invkind
== DISPATCH_PROPERTYPUT
1765 || aFuncDesc
->invkind
== DISPATCH_PROPERTYPUTREF
)
1766 dispparams
.cNamedArgs
++;
1768 //Determine the number of all arguments and named arguments
1769 if (aFuncDesc
->cParamsOpt
== -1)
1771 //Attribute vararg is set on this method. "Unlimited" number of args
1772 //supported. There can be no optional or defaultvalue on any of the arguments.
1773 dispparams
.cArgs
= nUnoArgs
;
1777 //If there are namesd arguments, then the dispparams.cArgs
1778 //is the number of supplied args, otherwise it is the expected number.
1779 if (dispparams
.cNamedArgs
)
1780 dispparams
.cArgs
= nUnoArgs
;
1782 dispparams
.cArgs
= aFuncDesc
->cParams
;
1785 //check if there are not to many arguments supplied
1786 if (::sal::static_int_cast
< sal_uInt32
, int >( nUnoArgs
) > dispparams
.cArgs
)
1788 OUStringBuffer
buf(256);
1789 buf
.appendAscii("[automation bridge] There are too many arguments for this method");
1790 throw IllegalArgumentException( buf
.makeStringAndClear(),
1791 Reference
<XInterface
>(), (sal_Int16
) dispparams
.cArgs
);
1794 //Set up the array of DISPIDs (DISPPARAMS::rgdispidNamedArgs)
1795 //for the named arguments.
1796 //If there is only one named arg and if it is because of a property put
1797 //operation, then we need not set up the DISPID array.
1798 if (dispparams
.cNamedArgs
> 0 &&
1799 ! (dispparams
.cNamedArgs
== 1 &&
1800 (aFuncDesc
->invkind
== INVOKE_PROPERTYPUT
||
1801 aFuncDesc
->invkind
== INVOKE_PROPERTYPUTREF
)))
1803 //set up an array containing the member and parameter names
1804 //which is then used in ITypeInfo::GetIDsOfNames
1805 //First determine the size of the array of names which is passed to
1806 //ITypeInfo::GetIDsOfNames. It must hold the method names + the named
1808 int nSizeAr
= dispparams
.cNamedArgs
+ 1;
1809 if (aFuncDesc
->invkind
== INVOKE_PROPERTYPUT
1810 || aFuncDesc
->invkind
== INVOKE_PROPERTYPUTREF
)
1812 nSizeAr
= dispparams
.cNamedArgs
; //counts the DISID_PROPERTYPUT
1815 scoped_array
<OLECHAR
*> saNames(new OLECHAR
*[nSizeAr
]);
1816 OLECHAR
** arNames
= saNames
.get();
1817 arNames
[0] = const_cast<OLECHAR
*>(reinterpret_cast<LPCOLESTR
>(sFuncName
.getStr()));
1820 for (size_t iParams
= 0; iParams
< dispparams
.cArgs
; iParams
++)
1822 const Any
& curArg
= Params
[iParams
];
1823 if (curArg
.getValueType() == getCppuType((NamedArgument
*) 0))
1825 const NamedArgument
& arg
= *(NamedArgument
const*) curArg
.getValue();
1826 //We put the parameter names in reverse order into the array,
1827 //so we can use the DISPID array for DISPPARAMS::rgdispidNamedArgs
1828 //The first name in the array is the method name
1829 arNames
[nSizeAr
- 1 - cNamedArg
++] = const_cast<OLECHAR
*>(reinterpret_cast<LPCOLESTR
>(arg
.Name
.getStr()));
1833 //Prepare the array of DISPIDs for ITypeInfo::GetIDsOfNames
1834 //it must be big enough to contain the DISPIDs of the member + parameters
1835 arDispidNamedArgs
.reset(new DISPID
[nSizeAr
]);
1836 HRESULT hr
= getTypeInfo()->GetIDsOfNames(arNames
, nSizeAr
,
1837 arDispidNamedArgs
.get());
1838 if ( hr
== E_NOTIMPL
)
1839 hr
= m_spDispatch
->GetIDsOfNames(IID_NULL
, arNames
, nSizeAr
, LOCALE_USER_DEFAULT
, arDispidNamedArgs
.get() );
1843 // In a "property put" operation, the property value is a named param with the
1844 //special DISPID DISPID_PROPERTYPUT
1845 if (aFuncDesc
->invkind
== DISPATCH_PROPERTYPUT
1846 || aFuncDesc
->invkind
== DISPATCH_PROPERTYPUTREF
)
1848 //Element at index 0 in the DISPID array must be DISPID_PROPERTYPUT
1849 //The first item in the array arDispidNamedArgs is the DISPID for
1850 //the method. We replace it with DISPID_PROPERTYPUT.
1851 DISPID
* arIDs
= arDispidNamedArgs
.get();
1852 arIDs
[0] = DISPID_PROPERTYPUT
;
1853 dispparams
.rgdispidNamedArgs
= arIDs
;
1857 //The first item in the array arDispidNamedArgs is the DISPID for
1858 //the method. It must be removed
1859 DISPID
* arIDs
= arDispidNamedArgs
.get();
1860 dispparams
.rgdispidNamedArgs
= & arIDs
[1];
1863 else if (hr
== DISP_E_UNKNOWNNAME
)
1865 throw IllegalArgumentException(
1866 "[automation bridge]One of the named arguments is wrong!",
1867 Reference
<XInterface
>(), 0);
1871 throw InvocationTargetException(
1872 "[automation bridge] ITypeInfo::GetIDsOfNames returned error "
1873 + OUString::valueOf((sal_Int32
) hr
, 16), Reference
<XInterface
>(), Any());
1878 ptrArgs
.reset(new CComVariant
[dispparams
.cArgs
]);
1879 ptrRefArgs
.reset(new CComVariant
[dispparams
.cArgs
]);
1880 arArgs
= ptrArgs
.get();
1881 arRefArgs
= ptrRefArgs
.get();
1884 for (i
= 0; i
< (sal_Int32
) dispparams
.cArgs
; i
++)
1886 revIndex
= dispparams
.cArgs
- i
-1;
1887 arRefArgs
[revIndex
].byref
=0;
1890 anyArg
= Params
.getConstArray()[i
];
1892 unsigned short paramFlags
= PARAMFLAG_FOPT
| PARAMFLAG_FIN
;
1893 VARTYPE varType
= VT_VARIANT
;
1894 if (aFuncDesc
->cParamsOpt
!= -1 || aFuncDesc
->cParams
!= (i
+ 1))
1896 paramFlags
= aFuncDesc
->lprgelemdescParam
[i
].paramdesc
.wParamFlags
;
1897 varType
= getElementTypeDesc(&aFuncDesc
->lprgelemdescParam
[i
].tdesc
);
1900 // Make sure that there is a UNO parameter for every
1901 // expected parameter. If there is no UNO parameter where the
1902 // called function expects one, then it must be optional. Otherwise
1903 // its a UNO programming error.
1904 if (i
>= nUnoArgs
&& !(paramFlags
& PARAMFLAG_FOPT
))
1906 OUStringBuffer
buf(256);
1907 buf
.appendAscii("ole automation bridge: The called function expects an argument at"
1908 "position: "); //a different number of arguments")),
1909 buf
.append(OUString::valueOf((sal_Int32
) i
));
1910 buf
.appendAscii(" (index starting at 0).");
1911 throw IllegalArgumentException( buf
.makeStringAndClear(),
1912 Reference
<XInterface
>(), (sal_Int16
) i
);
1915 // Property Put arguments
1916 if (anyArg
.getValueType() == getCppuType((PropertyPutArgument
*)0))
1918 PropertyPutArgument arg
;
1920 anyArg
<<= arg
.Value
;
1923 if (anyArg
.getValueType() == getCppuType((NamedArgument
*) 0))
1925 NamedArgument aNamedArgument
;
1926 anyArg
>>= aNamedArgument
;
1927 anyArg
<<= aNamedArgument
.Value
;
1930 if (paramFlags
& PARAMFLAG_FOUT
&&
1931 ! (paramFlags
& PARAMFLAG_FIN
) )
1933 VARTYPE type
= ::sal::static_int_cast
< VARTYPE
, int >( varType
^ VT_BYREF
);
1936 arRefArgs
[revIndex
].vt
= type
;
1941 arRefArgs
[revIndex
].vt
= VT_ERROR
;
1942 arRefArgs
[revIndex
].scode
= DISP_E_PARAMNOTFOUND
;
1944 if( type
== VT_VARIANT
)
1946 arArgs
[revIndex
].vt
= VT_VARIANT
| VT_BYREF
;
1947 arArgs
[revIndex
].byref
= &arRefArgs
[revIndex
];
1951 arArgs
[revIndex
].vt
= varType
;
1952 if (type
== VT_DECIMAL
)
1953 arArgs
[revIndex
].byref
= & arRefArgs
[revIndex
].decVal
;
1955 arArgs
[revIndex
].byref
= & arRefArgs
[revIndex
].byref
;
1958 // in/out + in byref params
1959 else if (varType
& VT_BYREF
)
1961 VARTYPE type
= ::sal::static_int_cast
< VARTYPE
, int >( varType
^ VT_BYREF
);
1964 if (i
< nUnoArgs
&& anyArg
.getValueTypeClass() != TypeClass_VOID
)
1966 anyToVariant( & arRefArgs
[revIndex
], anyArg
, type
);
1968 else if (paramFlags
& PARAMFLAG_FHASDEFAULT
)
1970 //optional arg with default
1971 VariantCopy( & arRefArgs
[revIndex
],
1972 & aFuncDesc
->lprgelemdescParam
[i
].paramdesc
.
1973 pparamdescex
->varDefaultValue
);
1978 //e.g: call func(x) in basic : func() ' no arg supplied
1979 OSL_ASSERT(paramFlags
& PARAMFLAG_FOPT
);
1980 arRefArgs
[revIndex
].vt
= VT_ERROR
;
1981 arRefArgs
[revIndex
].scode
= DISP_E_PARAMNOTFOUND
;
1984 // Set the converted arguments in the array which will be
1985 // DISPPARAMS::rgvarg
1986 // byref arg VT_XXX |VT_BYREF
1987 arArgs
[revIndex
].vt
= varType
;
1988 if (revIndex
== 0 && aFuncDesc
->invkind
== INVOKE_PROPERTYPUT
)
1990 arArgs
[revIndex
] = arRefArgs
[revIndex
];
1992 else if (type
== VT_DECIMAL
)
1994 arArgs
[revIndex
].byref
= & arRefArgs
[revIndex
].decVal
;
1996 else if (type
== VT_VARIANT
)
1998 if ( ! (paramFlags
& PARAMFLAG_FOUT
))
1999 arArgs
[revIndex
] = arRefArgs
[revIndex
];
2001 arArgs
[revIndex
].byref
= & arRefArgs
[revIndex
];
2005 arArgs
[revIndex
].byref
= & arRefArgs
[revIndex
].byref
;
2006 arArgs
[revIndex
].vt
= ::sal::static_int_cast
< VARTYPE
, int >( arRefArgs
[revIndex
].vt
| VT_BYREF
);
2010 // in parameter no VT_BYREF except for array, interfaces
2012 { // void any stands for optional param
2013 if (i
< nUnoArgs
&& anyArg
.getValueTypeClass() != TypeClass_VOID
)
2015 anyToVariant( & arArgs
[revIndex
], anyArg
, varType
);
2017 //optional arg but no void any supplied
2018 //Basic: obj.func() ' first parameter left out because it is optional
2019 else if (paramFlags
& PARAMFLAG_FHASDEFAULT
)
2021 //optional arg with defaulteithter as direct arg : VT_XXX or
2022 VariantCopy( & arArgs
[revIndex
],
2023 & aFuncDesc
->lprgelemdescParam
[i
].paramdesc
.
2024 pparamdescex
->varDefaultValue
);
2026 else if (paramFlags
& PARAMFLAG_FOPT
)
2028 arArgs
[revIndex
].vt
= VT_ERROR
;
2029 arArgs
[revIndex
].scode
= DISP_E_PARAMNOTFOUND
;
2033 arArgs
[revIndex
].vt
= VT_EMPTY
;
2034 arArgs
[revIndex
].lVal
= 0;
2039 catch (IllegalArgumentException
& e
)
2041 e
.ArgumentPosition
= ::sal::static_int_cast
< sal_Int16
, sal_Int32
>( i
);
2044 catch (CannotConvertException
& e
)
2046 e
.ArgumentIndex
= i
;
2049 dispparams
.rgvarg
= arArgs
;
2050 // invoking OLE method
2051 DWORD localeId
= LOCALE_USER_DEFAULT
;
2052 result
= m_spDispatch
->Invoke(aFuncDesc
->memid
,
2055 ::sal::static_int_cast
< WORD
, INVOKEKIND
>( aFuncDesc
->invkind
),
2061 // converting return value and out parameter back to UNO
2065 // allocate space for the out param Sequence and indices Sequence
2066 int outParamsCount
= 0; // includes in/out parameter
2067 for (int i
= 0; i
< aFuncDesc
->cParams
; i
++)
2069 if (aFuncDesc
->lprgelemdescParam
[i
].paramdesc
.wParamFlags
&
2074 OutParamIndex
.realloc(outParamsCount
);
2075 OutParam
.realloc(outParamsCount
);
2076 // Convert out params
2079 int outParamIndex
=0;
2080 for (int paramIndex
= 0; paramIndex
< nUnoArgs
; paramIndex
++)
2082 //Determine the index within the method sinature
2083 int realParamIndex
= paramIndex
;
2084 int revParamIndex
= dispparams
.cArgs
- paramIndex
- 1;
2085 if (Params
[paramIndex
].getValueType()
2086 == getCppuType((NamedArgument
*) 0))
2088 //dispparams.rgdispidNamedArgs contains the mapping from index
2089 //of named args list to index of parameter list
2090 realParamIndex
= dispparams
.rgdispidNamedArgs
[revParamIndex
];
2093 // no named arg, always come before named args
2094 if (! (aFuncDesc
->lprgelemdescParam
[realParamIndex
].paramdesc
.wParamFlags
2098 // variantToAny is called with the "reduce range" parameter set to sal_False.
2099 // That causes VT_I4 values not to be converted down to a "lower" type. That
2100 // feature exist for JScript only because it only uses VT_I4 for integer types.
2103 variantToAny( & arRefArgs
[revParamIndex
], outAny
, sal_False
);
2105 catch (IllegalArgumentException
& e
)
2107 e
.ArgumentPosition
= (sal_Int16
)paramIndex
;
2110 catch (CannotConvertException
& e
)
2112 e
.ArgumentIndex
= paramIndex
;
2115 OutParam
[outParamIndex
] = outAny
;
2116 OutParamIndex
[outParamIndex
] = ::sal::static_int_cast
< sal_Int16
, int >( paramIndex
);
2119 OutParam
.realloc(outParamIndex
);
2120 OutParamIndex
.realloc(outParamIndex
);
2123 variantToAny(&varResult
, ret
, sal_False
);
2126 // map error codes to exceptions
2132 case DISP_E_BADPARAMCOUNT
:
2133 throw IllegalArgumentException("[automation bridge] Wrong "
2134 "number of arguments. Object returned DISP_E_BADPARAMCOUNT.",
2137 case DISP_E_BADVARTYPE
:
2138 throw RuntimeException("[automation bridge] One or more "
2139 "arguments have the wrong type. Object returned "
2140 "DISP_E_BADVARTYPE.", 0);
2142 case DISP_E_EXCEPTION
:
2143 message
= "[automation bridge]: ";
2144 message
+= OUString(reinterpret_cast<const sal_Unicode
*>(excepinfo
.bstrDescription
),
2145 ::SysStringLen(excepinfo
.bstrDescription
));
2147 throw InvocationTargetException(message
, Reference
<XInterface
>(), Any());
2149 case DISP_E_MEMBERNOTFOUND
:
2150 message
= "[automation bridge]: A function with the name \""
2151 + sFuncName
+ "\" is not supported. Object returned "
2152 "DISP_E_MEMBERNOTFOUND.";
2153 throw IllegalArgumentException(message
, 0, 0);
2155 case DISP_E_NONAMEDARGS
:
2156 throw IllegalArgumentException("[automation bridge] Object "
2157 "returned DISP_E_NONAMEDARGS",0, ::sal::static_int_cast
< sal_Int16
, unsigned int >( uArgErr
));
2159 case DISP_E_OVERFLOW
:
2160 throw CannotConvertException(OUString("[automation bridge] Call failed."),
2161 static_cast<XInterface
*>(
2162 static_cast<XWeak
*>(this)), TypeClass_UNKNOWN
, FailReason::OUT_OF_RANGE
, uArgErr
);
2164 case DISP_E_PARAMNOTFOUND
:
2165 throw IllegalArgumentException("[automation bridge]Call failed."
2166 "Object returned DISP_E_PARAMNOTFOUND.",
2167 0, ::sal::static_int_cast
< sal_Int16
, unsigned int >( uArgErr
));
2169 case DISP_E_TYPEMISMATCH
:
2170 throw CannotConvertException("[automation bridge] Call failed. "
2171 "Object returned DISP_E_TYPEMISMATCH",
2172 static_cast<XInterface
*>(
2173 static_cast<XWeak
*>(this)) , TypeClass_UNKNOWN
, FailReason::UNKNOWN
, uArgErr
);
2175 case DISP_E_UNKNOWNINTERFACE
:
2176 throw RuntimeException("[automation bridge] Call failed. "
2177 "Object returned DISP_E_UNKNOWNINTERFACE.",0);
2179 case DISP_E_UNKNOWNLCID
:
2180 throw RuntimeException("[automation bridge] Call failed. "
2181 "Object returned DISP_E_UNKNOWNLCID.",0);
2183 case DISP_E_PARAMNOTOPTIONAL
:
2184 throw CannotConvertException("[automation bridge] Call failed."
2185 "Object returned DISP_E_PARAMNOTOPTIONAL",
2186 static_cast<XInterface
*>(static_cast<XWeak
*>(this)),
2187 TypeClass_UNKNOWN
, FailReason::NO_DEFAULT_AVAILABLE
, uArgErr
);
2190 throw RuntimeException();
2197 void IUnknownWrapper_Impl::getFuncDescForInvoke(const OUString
& sFuncName
,
2198 const Sequence
<Any
> & seqArgs
,
2199 FUNCDESC
** pFuncDesc
)
2201 int nUnoArgs
= seqArgs
.getLength();
2202 const Any
* arArgs
= seqArgs
.getConstArray();
2203 ITypeInfo
* pInfo
= getTypeInfo();
2205 //If the last of the positional arguments is a PropertyPutArgument
2206 //then obtain the type info for the property put operation.
2208 //The property value is always the last argument, in a positional argument list
2209 //or in a list of named arguments. A PropertyPutArgument is actually a named argument
2210 //hence it must not be put in an extra NamedArgument structure
2212 arArgs
[nUnoArgs
- 1].getValueType() == getCppuType((PropertyPutArgument
*) 0))
2214 // DISPATCH_PROPERTYPUT
2215 FuncDesc
aDescGet(pInfo
);
2216 FuncDesc
aDescPut(pInfo
);
2217 VarDesc
aVarDesc(pInfo
);
2218 getPropDesc(sFuncName
, & aDescGet
, & aDescPut
, & aVarDesc
);
2221 throw IllegalArgumentException(
2222 "[automation bridge] The object does not have a writeable property: "
2223 + sFuncName
, Reference
<XInterface
>(), 0);
2225 *pFuncDesc
= aDescPut
.Detach();
2228 { // DISPATCH_METHOD
2229 FuncDesc
aFuncDesc(pInfo
);
2230 getFuncDesc(sFuncName
, & aFuncDesc
);
2233 // Fallback: DISPATCH_PROPERTYGET can mostly be called as
2235 ITypeInfo
* pInfo
= getTypeInfo();
2236 FuncDesc
aDescPut(pInfo
);
2237 VarDesc
aVarDesc(pInfo
);
2238 getPropDesc(sFuncName
, & aFuncDesc
, & aDescPut
, & aVarDesc
);
2241 throw IllegalArgumentException(
2242 "[automation bridge] The object does not have a function"
2243 "or readable property \""
2244 + sFuncName
, Reference
<XInterface
>(), 0);
2247 *pFuncDesc
= aFuncDesc
.Detach();
2250 bool IUnknownWrapper_Impl::getDispid(const OUString
& sFuncName
, DISPID
* id
)
2252 OSL_ASSERT(m_spDispatch
);
2253 LPOLESTR lpsz
= const_cast<LPOLESTR
> (reinterpret_cast<LPCOLESTR
>(sFuncName
.getStr()));
2254 HRESULT hr
= m_spDispatch
->GetIDsOfNames(IID_NULL
, &lpsz
, 1, LOCALE_USER_DEFAULT
, id
);
2255 return hr
== S_OK
? true : false;
2257 void IUnknownWrapper_Impl::getFuncDesc(const OUString
& sFuncName
, FUNCDESC
** pFuncDesc
)
2260 OSL_ASSERT( * pFuncDesc
== 0);
2262 typedef TLBFuncIndexMap::const_iterator cit
;
2263 typedef TLBFuncIndexMap::iterator it
;
2264 //We assume there is only one entry with the function name. A property
2265 //would have two entries.
2266 cit itIndex
= m_mapComFunc
.find(sFuncName
);
2267 if (itIndex
== m_mapComFunc
.end())
2269 //try case insensive with IDispatch::GetIDsOfNames
2271 if (getDispid(sFuncName
, &id
))
2273 CComBSTR memberName
;
2274 unsigned int pcNames
=0;
2275 // get the case sensitive name
2276 if( SUCCEEDED(getTypeInfo()->GetNames( id
, & memberName
, 1, &pcNames
)))
2278 //get the associated index and add an entry to the map
2279 //with the name sFuncName which differs in the casing of the letters to
2280 //the actual name as obtained from ITypeInfo
2281 OUString
sRealName(reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(memberName
)));
2282 cit itOrg
= m_mapComFunc
.find(sRealName
);
2283 OSL_ASSERT(itOrg
!= m_mapComFunc
.end());
2284 // maybe this is a property, if so we need
2285 // to store either both id's ( put/get ) or
2286 // just the get. Storing both is more consistent
2287 pair
<cit
, cit
> pItems
= m_mapComFunc
.equal_range( sRealName
);
2288 for ( ;pItems
.first
!= pItems
.second
; ++pItems
.first
)
2289 m_mapComFunc
.insert( TLBFuncIndexMap::value_type ( make_pair(sFuncName
, pItems
.first
->second
) ));
2291 m_mapComFunc
.find( sFuncName
);
2296 #if OSL_DEBUG_LEVEL >= 1
2297 // There must only be one entry if sFuncName represents a function or two
2298 // if it is a property
2299 pair
<cit
, cit
> p
= m_mapComFunc
.equal_range(sFuncName
.toAsciiLowerCase());
2301 for ( ;p
.first
!= p
.second
; p
.first
++, numEntries
++);
2302 OSL_ASSERT( ! (numEntries
> 3) );
2304 if( itIndex
!= m_mapComFunc
.end())
2306 ITypeInfo
* pType
= getTypeInfo();
2307 FUNCDESC
* pDesc
= NULL
;
2308 if (SUCCEEDED(pType
->GetFuncDesc(itIndex
->second
, & pDesc
)))
2310 if (pDesc
->invkind
== INVOKE_FUNC
)
2312 (*pFuncDesc
) = pDesc
;
2316 pType
->ReleaseFuncDesc(pDesc
);
2321 throw BridgeRuntimeError("[automation bridge] Could not get "
2322 "FUNCDESC for " + sFuncName
);
2325 //else no entry found for sFuncName, pFuncDesc will not be filled in
2328 void IUnknownWrapper_Impl::getPropDesc(const OUString
& sFuncName
, FUNCDESC
** pFuncDescGet
,
2329 FUNCDESC
** pFuncDescPut
, VARDESC
** pVarDesc
)
2331 OSL_ASSERT( * pFuncDescGet
== 0 && * pFuncDescPut
== 0);
2333 typedef TLBFuncIndexMap::const_iterator cit
;
2334 pair
<cit
, cit
> p
= m_mapComFunc
.equal_range(sFuncName
);
2335 if (p
.first
== m_mapComFunc
.end())
2337 //try case insensive with IDispatch::GetIDsOfNames
2339 if (getDispid(sFuncName
, &id
))
2341 CComBSTR memberName
;
2342 unsigned int pcNames
=0;
2343 // get the case sensitive name
2344 if( SUCCEEDED(getTypeInfo()->GetNames( id
, & memberName
, 1, &pcNames
)))
2346 //As opposed to getFuncDesc, we do not add the value because we would
2347 // need to find the get and set description for the property. This would
2348 //mean to iterate over all FUNCDESCs again.
2349 p
= m_mapComFunc
.equal_range(OUString(reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(memberName
))));
2354 for ( int i
= 0 ;p
.first
!= p
.second
; p
.first
++, i
++)
2356 // There are a maximum of two entries, property put and property get
2357 OSL_ASSERT( ! (i
> 2) );
2358 ITypeInfo
* pType
= getTypeInfo();
2359 FUNCDESC
* pFuncDesc
= NULL
;
2360 if (SUCCEEDED( pType
->GetFuncDesc(p
.first
->second
, & pFuncDesc
)))
2362 if (pFuncDesc
->invkind
== INVOKE_PROPERTYGET
)
2364 (*pFuncDescGet
) = pFuncDesc
;
2366 else if (pFuncDesc
->invkind
== INVOKE_PROPERTYPUT
||
2367 pFuncDesc
->invkind
== INVOKE_PROPERTYPUTREF
)
2369 //a property can have 3 entries, put, put ref, get
2370 // If INVOKE_PROPERTYPUTREF or INVOKE_PROPERTYPUT is used
2371 //depends on what is found first.
2372 if ( * pFuncDescPut
)
2374 //we already have found one
2375 pType
->ReleaseFuncDesc(pFuncDesc
);
2379 (*pFuncDescPut
) = pFuncDesc
;
2384 pType
->ReleaseFuncDesc(pFuncDesc
);
2387 //ITypeInfo::GetFuncDesc may even provide a funcdesc for a VARDESC
2388 // with invkind = INVOKE_FUNC. Since this function should only return
2389 //a value for a real property (XInvokation::hasMethod, ..::hasProperty
2390 //we need to make sure that sFuncName represents a real property.
2391 VARDESC
* pVD
= NULL
;
2392 if (SUCCEEDED(pType
->GetVarDesc(p
.first
->second
, & pVD
)))
2395 //else no entry for sFuncName, pFuncDesc will not be filled in
2398 VARTYPE
IUnknownWrapper_Impl::getUserDefinedElementType( ITypeInfo
* pTypeInfo
, const DWORD nHrefType
)
2400 VARTYPE
_type( VT_NULL
);
2403 CComPtr
<ITypeInfo
> spRefInfo
;
2404 pTypeInfo
->GetRefTypeInfo( nHrefType
, &spRefInfo
.p
);
2407 TypeAttr
attr( spRefInfo
);
2408 spRefInfo
->GetTypeAttr( &attr
);
2409 if ( attr
->typekind
== TKIND_ENUM
)
2411 // We use the type of the first enum value.
2412 if ( attr
->cVars
== 0 )
2414 throw BridgeRuntimeError("[automation bridge] Could not obtain type description");
2416 VarDesc
var( spRefInfo
);
2417 spRefInfo
->GetVarDesc( 0, &var
);
2418 _type
= var
->lpvarValue
->vt
;
2420 else if ( attr
->typekind
== TKIND_INTERFACE
)
2424 else if ( attr
->typekind
== TKIND_DISPATCH
)
2426 _type
= VT_DISPATCH
;
2428 else if ( attr
->typekind
== TKIND_ALIAS
)
2430 // TKIND_ALIAS is a type that is an alias for another type. So get that alias type.
2431 _type
= getUserDefinedElementType( pTypeInfo
, attr
->tdescAlias
.hreftype
);
2435 throw BridgeRuntimeError( "[automation bridge] Unhandled user defined type." );
2442 VARTYPE
IUnknownWrapper_Impl::getElementTypeDesc(const TYPEDESC
*desc
)
2444 VARTYPE
_type( VT_NULL
);
2446 if (desc
->vt
== VT_PTR
)
2448 _type
= getElementTypeDesc(desc
->lptdesc
);
2451 else if (desc
->vt
== VT_SAFEARRAY
)
2453 _type
= getElementTypeDesc(desc
->lptdesc
);
2456 else if (desc
->vt
== VT_USERDEFINED
)
2458 ITypeInfo
* thisInfo
= getTypeInfo(); //kept by this instance
2459 _type
= getUserDefinedElementType( thisInfo
, desc
->hreftype
);
2468 void IUnknownWrapper_Impl::buildComTlbIndex()
2470 if ( ! m_bComTlbIndexInit
)
2472 MutexGuard
guard(getBridgeMutex());
2474 if ( ! m_bComTlbIndexInit
)
2477 ITypeInfo
* pType
= getTypeInfo();
2478 TypeAttr
typeAttr(pType
);
2479 if( SUCCEEDED( pType
->GetTypeAttr( &typeAttr
)))
2481 for( long i
= 0; i
< typeAttr
->cFuncs
; i
++)
2483 FuncDesc
funcDesc(pType
);
2484 if( SUCCEEDED( pType
->GetFuncDesc( i
, &funcDesc
)))
2486 CComBSTR memberName
;
2487 unsigned int pcNames
=0;
2488 if( SUCCEEDED(pType
->GetNames( funcDesc
->memid
, & memberName
, 1, &pcNames
)))
2490 OUString
usName(reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(memberName
)));
2491 m_mapComFunc
.insert( TLBFuncIndexMap::value_type( usName
, i
));
2495 sError
= "[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, "
2496 "ITypeInfo::GetNames failed.";
2500 sError
= "[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, "
2501 "ITypeInfo::GetFuncDesc failed.";
2504 //If we create an Object in JScript and a a property then it
2505 //has VARDESC instead of FUNCDESC
2506 for (long i
= 0; i
< typeAttr
->cVars
; i
++)
2508 VarDesc
varDesc(pType
);
2509 if (SUCCEEDED(pType
->GetVarDesc(i
, & varDesc
)))
2511 CComBSTR memberName
;
2512 unsigned int pcNames
= 0;
2513 if (SUCCEEDED(pType
->GetNames(varDesc
->memid
, & memberName
, 1, &pcNames
)))
2515 if (varDesc
->varkind
== VAR_DISPATCH
)
2517 OUString
usName(reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(memberName
)));
2518 m_mapComFunc
.insert(TLBFuncIndexMap::value_type(
2524 sError
= "[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, "
2525 "ITypeInfo::GetNames failed.";
2529 sError
= "[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, "
2530 "ITypeInfo::GetVarDesc failed.";
2535 sError
= "[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, "
2536 "ITypeInfo::GetTypeAttr failed.";
2538 if (sError
.getLength())
2540 throw BridgeRuntimeError(sError
);
2543 m_bComTlbIndexInit
= true;
2549 ITypeInfo
* IUnknownWrapper_Impl::getTypeInfo()
2553 throw BridgeRuntimeError("The object has no IDispatch interface!");
2558 MutexGuard
guard(getBridgeMutex());
2561 CComPtr
< ITypeInfo
> spType
;
2562 if( SUCCEEDED( m_spDispatch
->GetTypeInfo( 0, LOCALE_USER_DEFAULT
, &spType
.p
)))
2565 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
2567 //If this is a dual interface then TYPEATTR::typekind is usually TKIND_INTERFACE
2568 //We need to get the type description for TKIND_DISPATCH
2569 TypeAttr
typeAttr(spType
.p
);
2570 if( SUCCEEDED(spType
->GetTypeAttr( &typeAttr
)))
2572 if (typeAttr
->typekind
== TKIND_INTERFACE
&&
2573 typeAttr
->wTypeFlags
& TYPEFLAG_FDUAL
)
2575 HREFTYPE refDispatch
;
2576 if (SUCCEEDED(spType
->GetRefTypeOfImplType(::sal::static_int_cast
< UINT
, int >( -1 ), &refDispatch
)))
2578 CComPtr
<ITypeInfo
> spTypeDisp
;
2579 if (SUCCEEDED(spType
->GetRefTypeInfo(refDispatch
, & spTypeDisp
)))
2580 m_spTypeInfo
= spTypeDisp
;
2584 throw BridgeRuntimeError(
2585 "[automation bridge] Could not obtain type information "
2586 "for dispatch interface." );
2589 else if (typeAttr
->typekind
== TKIND_DISPATCH
)
2591 m_spTypeInfo
= spType
;
2595 throw BridgeRuntimeError(
2596 "[automation bridge] Automation object does not "
2597 "provide type information.");
2603 throw BridgeRuntimeError("[automation bridge]The dispatch object does not "
2604 "support ITypeInfo!");
2608 return m_spTypeInfo
;
2613 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */