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