xref: /trunk/main/extensions/source/ole/unoobjw.cxx (revision 07a3d7f1)
12a97ec55SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
32a97ec55SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
42a97ec55SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
52a97ec55SAndrew Rist  * distributed with this work for additional information
62a97ec55SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
72a97ec55SAndrew Rist  * to you under the Apache License, Version 2.0 (the
82a97ec55SAndrew Rist  * "License"); you may not use this file except in compliance
92a97ec55SAndrew Rist  * with the License.  You may obtain a copy of the License at
102a97ec55SAndrew Rist  *
112a97ec55SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
122a97ec55SAndrew Rist  *
132a97ec55SAndrew Rist  * Unless required by applicable law or agreed to in writing,
142a97ec55SAndrew Rist  * software distributed under the License is distributed on an
152a97ec55SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162a97ec55SAndrew Rist  * KIND, either express or implied.  See the License for the
172a97ec55SAndrew Rist  * specific language governing permissions and limitations
182a97ec55SAndrew Rist  * under the License.
192a97ec55SAndrew Rist  *
202a97ec55SAndrew Rist  *************************************************************/
212a97ec55SAndrew Rist 
222a97ec55SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_extensions.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "ole2uno.hxx"
28cdf0e10cSrcweir #include <stdio.h>
29cdf0e10cSrcweir #include <tools/presys.h>
30cdf0e10cSrcweir #include <olectl.h>
31cdf0e10cSrcweir #include <vector>
32cdf0e10cSrcweir #include <list>
33cdf0e10cSrcweir #include <hash_map>
34cdf0e10cSrcweir #include "comifaces.hxx"
35cdf0e10cSrcweir #include <tools/postsys.h>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #include <vos/diagnose.hxx>
39cdf0e10cSrcweir #include <vos/refernce.hxx>
40cdf0e10cSrcweir #include <tools/debug.hxx>
41cdf0e10cSrcweir #include <rtl/ustring.hxx>
42cdf0e10cSrcweir #include <com/sun/star/beans/MethodConcept.hpp>
43cdf0e10cSrcweir #include <com/sun/star/beans/PropertyConcept.hpp>
44cdf0e10cSrcweir #include <com/sun/star/script/FailReason.hpp>
45cdf0e10cSrcweir #include <com/sun/star/reflection/ParamInfo.hpp>
46cdf0e10cSrcweir #include <com/sun/star/beans/XExactName.hpp>
47cdf0e10cSrcweir #include <com/sun/star/container/NoSuchElementException.hpp>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir #include <com/sun/star/beans/XMaterialHolder.hpp>
50cdf0e10cSrcweir #include <com/sun/star/script/XInvocation2.hpp>
51cdf0e10cSrcweir #include <com/sun/star/script/MemberType.hpp>
52cdf0e10cSrcweir #include <com/sun/star/reflection/XIdlReflection.hpp>
53cdf0e10cSrcweir #include <osl/interlck.h>
54cdf0e10cSrcweir #include <com/sun/star/uno/genfunc.h>
55cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
56cdf0e10cSrcweir 
57cdf0e10cSrcweir #include "comifaces.hxx"
58cdf0e10cSrcweir #include "jscriptclasses.hxx"
59cdf0e10cSrcweir #include "unotypewrapper.hxx"
60cdf0e10cSrcweir #include "oleobjw.hxx"
61cdf0e10cSrcweir #include "unoobjw.hxx"
62cdf0e10cSrcweir #include "servprov.hxx"
63cdf0e10cSrcweir 
64cdf0e10cSrcweir using namespace vos;
65cdf0e10cSrcweir using namespace std;
66cdf0e10cSrcweir using namespace rtl;
67cdf0e10cSrcweir using namespace osl;
68cdf0e10cSrcweir using namespace cppu;
69cdf0e10cSrcweir using namespace com::sun::star::uno;
70cdf0e10cSrcweir using namespace com::sun::star::beans;
71cdf0e10cSrcweir using namespace com::sun::star::container;
72cdf0e10cSrcweir using namespace com::sun::star::script;
73cdf0e10cSrcweir using namespace com::sun::star::lang;
74cdf0e10cSrcweir using namespace com::sun::star::bridge::ModelDependent;
75cdf0e10cSrcweir using namespace com::sun::star::reflection;
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 
79cdf0e10cSrcweir #if _MSC_VER < 1200
80cdf0e10cSrcweir extern "C" const GUID IID_IDispatchEx;
81cdf0e10cSrcweir #endif
82cdf0e10cSrcweir 
83cdf0e10cSrcweir namespace ole_adapter
84cdf0e10cSrcweir {
85cdf0e10cSrcweir hash_map<sal_uInt32, WeakReference<XInterface> > UnoObjToWrapperMap;
86cdf0e10cSrcweir static sal_Bool writeBackOutParameter(VARIANTARG* pDest, VARIANT* pSource);
87cdf0e10cSrcweir static sal_Bool writeBackOutParameter2( VARIANTARG* pDest, VARIANT* pSource);
88cdf0e10cSrcweir static HRESULT mapCannotConvertException( CannotConvertException e, unsigned int * puArgErr);
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 
91cdf0e10cSrcweir /* Does not throw any exceptions.
92cdf0e10cSrcweir    Param pInfo can be NULL.
93cdf0e10cSrcweir  */
writeExcepinfo(EXCEPINFO * pInfo,const OUString & message)94cdf0e10cSrcweir static void writeExcepinfo(EXCEPINFO * pInfo, const OUString& message)
95cdf0e10cSrcweir {
96cdf0e10cSrcweir     if (pInfo != NULL)
97cdf0e10cSrcweir     {
98cdf0e10cSrcweir         pInfo->wCode = UNO_2_OLE_EXCEPTIONCODE;
99cdf0e10cSrcweir         pInfo->bstrSource = SysAllocString(L"[automation bridge] ");
100cdf0e10cSrcweir         pInfo->bstrDescription = SysAllocString(reinterpret_cast<LPCOLESTR>(message.getStr()));
101cdf0e10cSrcweir     }
102cdf0e10cSrcweir }
103cdf0e10cSrcweir 
104cdf0e10cSrcweir /*****************************************************************************
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 	class implementation: InterfaceOleWrapper_Impl
107cdf0e10cSrcweir 
108cdf0e10cSrcweir *****************************************************************************/
InterfaceOleWrapper_Impl(Reference<XMultiServiceFactory> & xFactory,sal_uInt8 unoWrapperClass,sal_uInt8 comWrapperClass)109cdf0e10cSrcweir InterfaceOleWrapper_Impl::InterfaceOleWrapper_Impl( Reference<XMultiServiceFactory>& xFactory,
110cdf0e10cSrcweir 													sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass):
111cdf0e10cSrcweir 		m_defaultValueType( 0),
112cdf0e10cSrcweir 		UnoConversionUtilities<InterfaceOleWrapper_Impl>( xFactory, unoWrapperClass, comWrapperClass)
113cdf0e10cSrcweir {
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
~InterfaceOleWrapper_Impl()116cdf0e10cSrcweir InterfaceOleWrapper_Impl::~InterfaceOleWrapper_Impl()
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     MutexGuard guard(getBridgeMutex());
119cdf0e10cSrcweir 	// remove entries in global map
120cdf0e10cSrcweir     IT_Uno it= UnoObjToWrapperMap.find( (sal_uInt32) m_xOrigin.get());
121cdf0e10cSrcweir     if(it != UnoObjToWrapperMap.end())
122cdf0e10cSrcweir         UnoObjToWrapperMap.erase(it);
123cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
124cdf0e10cSrcweir     fprintf(stderr,"[automation bridge] UnoObjToWrapperMap  contains: %i \n",
125cdf0e10cSrcweir             UnoObjToWrapperMap.size());
126cdf0e10cSrcweir #endif
127cdf0e10cSrcweir 
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
QueryInterface(REFIID riid,LPVOID FAR * ppv)130cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::QueryInterface(REFIID riid, LPVOID FAR * ppv)
131cdf0e10cSrcweir {
132cdf0e10cSrcweir 	HRESULT ret= S_OK;
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 	if( !ppv)
135cdf0e10cSrcweir 		return E_POINTER;
136cdf0e10cSrcweir 
137cdf0e10cSrcweir     if(IsEqualIID(riid, IID_IUnknown))
138cdf0e10cSrcweir 	{
139cdf0e10cSrcweir 		AddRef();
140cdf0e10cSrcweir 		*ppv = (IUnknown*) (IDispatch*) this;
141cdf0e10cSrcweir     }
142cdf0e10cSrcweir     else if (IsEqualIID(riid, IID_IDispatch))
143cdf0e10cSrcweir 	{
144cdf0e10cSrcweir 		AddRef();
145cdf0e10cSrcweir 		*ppv = (IDispatch*) this;
146cdf0e10cSrcweir 	}
147cdf0e10cSrcweir 	else if( IsEqualIID( riid, __uuidof( IUnoObjectWrapper)))
148cdf0e10cSrcweir 	{
149cdf0e10cSrcweir 		AddRef();
150cdf0e10cSrcweir 		*ppv= (IUnoObjectWrapper*) this;
151cdf0e10cSrcweir 	}
152cdf0e10cSrcweir 	else
153cdf0e10cSrcweir 		ret= E_NOINTERFACE;
154cdf0e10cSrcweir 	return ret;
155cdf0e10cSrcweir }
156cdf0e10cSrcweir 
STDMETHODIMP_(ULONG)157cdf0e10cSrcweir STDMETHODIMP_(ULONG) InterfaceOleWrapper_Impl::AddRef()
158cdf0e10cSrcweir {
159cdf0e10cSrcweir     acquire();
160cdf0e10cSrcweir     // does not need to guard because one should not rely on the return value of
161cdf0e10cSrcweir     // AddRef anyway
162cdf0e10cSrcweir 	return m_refCount;
163cdf0e10cSrcweir }
164cdf0e10cSrcweir 
STDMETHODIMP_(ULONG)165cdf0e10cSrcweir STDMETHODIMP_(ULONG) InterfaceOleWrapper_Impl::Release()
166cdf0e10cSrcweir {
167cdf0e10cSrcweir     ULONG n= m_refCount;
168cdf0e10cSrcweir     release();
169cdf0e10cSrcweir     return n - 1;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
172cdf0e10cSrcweir // IUnoObjectWrapper --------------------------------------------------------
getWrapperXInterface(Reference<XInterface> * pXInt)173cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::getWrapperXInterface( Reference<XInterface>* pXInt)
174cdf0e10cSrcweir {
175cdf0e10cSrcweir 	*pXInt= Reference<XInterface>( static_cast<XWeak*>( this), UNO_QUERY);
176cdf0e10cSrcweir 	return pXInt->is() ? S_OK : E_FAIL;
177cdf0e10cSrcweir }
getOriginalUnoObject(Reference<XInterface> * pXInt)178cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::getOriginalUnoObject( Reference<XInterface>* pXInt)
179cdf0e10cSrcweir {
180cdf0e10cSrcweir 	*pXInt= m_xOrigin;
181cdf0e10cSrcweir 	return m_xOrigin.is() ? S_OK : E_FAIL;
182cdf0e10cSrcweir }
getOriginalUnoStruct(Any * pStruct)183cdf0e10cSrcweir STDMETHODIMP  InterfaceOleWrapper_Impl::getOriginalUnoStruct( Any * pStruct)
184cdf0e10cSrcweir {
185cdf0e10cSrcweir 	HRESULT ret= E_FAIL;
186cdf0e10cSrcweir 	if( !m_xOrigin.is())
187cdf0e10cSrcweir 	{
188cdf0e10cSrcweir 		Reference<XMaterialHolder> xMatHolder( m_xInvocation, UNO_QUERY);
189cdf0e10cSrcweir 		if( xMatHolder.is())
190cdf0e10cSrcweir 		{
191cdf0e10cSrcweir 			Any any = xMatHolder->getMaterial();
192cdf0e10cSrcweir 			if( any.getValueTypeClass() == TypeClass_STRUCT)
193cdf0e10cSrcweir 			{
194cdf0e10cSrcweir 				*pStruct= any;
195cdf0e10cSrcweir 				ret= S_OK;
196cdf0e10cSrcweir 			}
197cdf0e10cSrcweir 		}
198cdf0e10cSrcweir 	}
199cdf0e10cSrcweir 	return ret;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
GetTypeInfoCount(unsigned int *)202cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetTypeInfoCount( unsigned int * /*pctinfo*/ )
203cdf0e10cSrcweir {
204cdf0e10cSrcweir 	return E_NOTIMPL ;
205cdf0e10cSrcweir }
206cdf0e10cSrcweir 
GetTypeInfo(unsigned int,LCID,ITypeInfo **)207cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetTypeInfo(unsigned int /*itinfo*/, LCID /*lcid*/, ITypeInfo ** /*pptinfo*/)
208cdf0e10cSrcweir {
209cdf0e10cSrcweir 	return E_NOTIMPL;
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
GetIDsOfNames(REFIID,OLECHAR ** rgszNames,unsigned int cNames,LCID,DISPID * rgdispid)212cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetIDsOfNames(REFIID /*riid*/,
213cdf0e10cSrcweir 													 OLECHAR ** rgszNames,
214cdf0e10cSrcweir 													 unsigned int cNames,
215cdf0e10cSrcweir 													 LCID /*lcid*/,
216cdf0e10cSrcweir 													 DISPID * rgdispid )
217cdf0e10cSrcweir {
218cdf0e10cSrcweir     HRESULT ret = DISP_E_UNKNOWNNAME;
219cdf0e10cSrcweir     try
220cdf0e10cSrcweir     {
221cdf0e10cSrcweir         MutexGuard guard( getBridgeMutex());
222cdf0e10cSrcweir         if( ! rgdispid)
223cdf0e10cSrcweir             return E_POINTER;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir         // ----------------------------------------
226cdf0e10cSrcweir         if( ! _wcsicmp( *rgszNames, JSCRIPT_VALUE_FUNC) ||
227cdf0e10cSrcweir             ! _wcsicmp( *rgszNames, BRIDGE_VALUE_FUNC))
228cdf0e10cSrcweir         {
229cdf0e10cSrcweir             *rgdispid= DISPID_JSCRIPT_VALUE_FUNC;
230cdf0e10cSrcweir             return S_OK;
231cdf0e10cSrcweir         }
232cdf0e10cSrcweir         else if( ! _wcsicmp( *rgszNames, GET_STRUCT_FUNC) ||
233cdf0e10cSrcweir                  ! _wcsicmp( *rgszNames, BRIDGE_GET_STRUCT_FUNC))
234cdf0e10cSrcweir         {
235cdf0e10cSrcweir             *rgdispid= DISPID_GET_STRUCT_FUNC;
236cdf0e10cSrcweir             return S_OK;
237cdf0e10cSrcweir         }
238cdf0e10cSrcweir         else if( ! _wcsicmp( *rgszNames, BRIDGE_CREATE_TYPE_FUNC))
239cdf0e10cSrcweir         {
240cdf0e10cSrcweir             *rgdispid= DISPID_CREATE_TYPE_FUNC;
241cdf0e10cSrcweir             return S_OK;
242cdf0e10cSrcweir         }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir         // ----------------------------------------
245cdf0e10cSrcweir         if (m_xInvocation.is() && (cNames > 0))
246cdf0e10cSrcweir         {
247cdf0e10cSrcweir             OUString name(reinterpret_cast<const sal_Unicode*>(rgszNames[0]));
248cdf0e10cSrcweir             NameToIdMap::iterator iter = m_nameToDispIdMap.find(name);
249cdf0e10cSrcweir 
250cdf0e10cSrcweir             if (iter == m_nameToDispIdMap.end())
251cdf0e10cSrcweir             {
252cdf0e10cSrcweir                 OUString exactName;
253cdf0e10cSrcweir 
254cdf0e10cSrcweir                 if (m_xExactName.is())
255cdf0e10cSrcweir                 {
256cdf0e10cSrcweir                     exactName = m_xExactName->getExactName(name);
257cdf0e10cSrcweir                 }
258cdf0e10cSrcweir                 else
259cdf0e10cSrcweir                 {
260cdf0e10cSrcweir                     exactName = name;
261cdf0e10cSrcweir                 }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir                 MemberInfo d(0, exactName);
264cdf0e10cSrcweir 
265cdf0e10cSrcweir                 if (m_xInvocation->hasProperty(exactName))
266cdf0e10cSrcweir                 {
267cdf0e10cSrcweir                     d.flags |= DISPATCH_PROPERTYGET;
268cdf0e10cSrcweir                     d.flags |= DISPATCH_PROPERTYPUT;
269cdf0e10cSrcweir                     d.flags |= DISPATCH_PROPERTYPUTREF;
270cdf0e10cSrcweir                 }
271cdf0e10cSrcweir 
272cdf0e10cSrcweir                 if (m_xInvocation->hasMethod(exactName))
273cdf0e10cSrcweir                 {
274cdf0e10cSrcweir                     d.flags |= DISPATCH_METHOD;
275cdf0e10cSrcweir                 }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir                 if (d.flags != 0)
278cdf0e10cSrcweir                 {
279cdf0e10cSrcweir                     m_MemberInfos.push_back(d);
280cdf0e10cSrcweir                     iter = m_nameToDispIdMap.insert(NameToIdMap::value_type(exactName, (DISPID)m_MemberInfos.size())).first;
281cdf0e10cSrcweir 
282cdf0e10cSrcweir                     if (exactName != name)
283cdf0e10cSrcweir                     {
284cdf0e10cSrcweir                         iter = m_nameToDispIdMap.insert(NameToIdMap::value_type(name, (DISPID)m_MemberInfos.size())).first;
285cdf0e10cSrcweir                     }
286cdf0e10cSrcweir                 }
287cdf0e10cSrcweir             }
288cdf0e10cSrcweir 
289cdf0e10cSrcweir             if (iter == m_nameToDispIdMap.end())
290cdf0e10cSrcweir             {
291cdf0e10cSrcweir                 ret = DISP_E_UNKNOWNNAME;
292cdf0e10cSrcweir             }
293cdf0e10cSrcweir             else
294cdf0e10cSrcweir             {
295cdf0e10cSrcweir                 *rgdispid = (*iter).second;
296cdf0e10cSrcweir                 ret = S_OK;
297cdf0e10cSrcweir             }
298cdf0e10cSrcweir         }
299cdf0e10cSrcweir     }
300cdf0e10cSrcweir     catch(BridgeRuntimeError& )
301cdf0e10cSrcweir     {
302cdf0e10cSrcweir         OSL_ASSERT(0);
303cdf0e10cSrcweir     }
304cdf0e10cSrcweir     catch(Exception& )
305cdf0e10cSrcweir     {
306cdf0e10cSrcweir         OSL_ASSERT(0);
307cdf0e10cSrcweir     }
308cdf0e10cSrcweir 	catch(...)
309cdf0e10cSrcweir 	{
310cdf0e10cSrcweir         OSL_ASSERT(0);
311cdf0e10cSrcweir 	}
312cdf0e10cSrcweir 
313cdf0e10cSrcweir     return ret;
314cdf0e10cSrcweir }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir // "convertDispparamsArgs" converts VARIANTS to their respecting Any counterparts
317cdf0e10cSrcweir // The parameters "id", "wFlags" and "pdispparams" equal those as used in
318cdf0e10cSrcweir // IDispatch::Invoke. The function handles special JavaScript
319cdf0e10cSrcweir // cases where a VARIANT of type VT_DISPATCH is ambiguous and could represent
320cdf0e10cSrcweir // an object, array ( JavaScript Array object), out parameter and in/out ( JavaScript Array object)
321cdf0e10cSrcweir //  parameter (JavaScript Array object)
322cdf0e10cSrcweir // Because all those VT_DISPATCH objects need a different conversion
323cdf0e10cSrcweir // we have to find out what the object is supposed to be. The function does this
324cdf0e10cSrcweir // by either using type information or by help of a specialized ValueObject object.
325cdf0e10cSrcweir 
326cdf0e10cSrcweir // A. Type Information
327cdf0e10cSrcweir // -----------------------------------------------------------------------------
328cdf0e10cSrcweir // With the help of type information the kind of parameter can be exactly determined
329*07a3d7f1SPedro Giffuni // and an appropriate conversion can be chosen. A problem arises if a method expects
330cdf0e10cSrcweir // an Any. Then the type info does not tell what the type of the value, that is kept
331cdf0e10cSrcweir // by the any, should be. In this situation the decision wheter the param is a
332cdf0e10cSrcweir // sequence or an object is made upon the fact if the object has a property "0"
333cdf0e10cSrcweir // ( see function "isJScriptArray"). Since this is unsafe it is recommended to use
334cdf0e10cSrcweir // the JScript value objects within a JScript script on such an occasion.
335cdf0e10cSrcweir 
336cdf0e10cSrcweir // B. JavaScript Value Object ( class JScriptValue )
337cdf0e10cSrcweir // -----------------------------------------------------------------------------
338cdf0e10cSrcweir // A JScriptValue (ValueObject) object is a COM object in that it implements IDispatch and the
339cdf0e10cSrcweir // IJScriptValue object interface. Such objects are provided by all UNO wrapper
340cdf0e10cSrcweir // objects used within a JScript script. To obtain an instance one has to call
341cdf0e10cSrcweir // "_GetValueObject() or Bridge_GetValueObject()" on an UNO wrapper object (class InterfaceOleWrapper_Impl).
342cdf0e10cSrcweir // A value object is appropriately initialized within the script and passed as
343cdf0e10cSrcweir // parameter to an UNO object method or property. The convertDispparamsArgs function
344cdf0e10cSrcweir // can easily find out that a param is such an object by queriing for the
345cdf0e10cSrcweir // IJScriptValue interface. By this interface one the type and kind ( out, in/out)
346cdf0e10cSrcweir // can be determined and the right conversion can be applied.
347*07a3d7f1SPedro Giffuni // Using ValueObjects we spare us the effort of acquiring and examining type information
348cdf0e10cSrcweir // in order to figure out what the an IDispatch parameter is meant for.
349cdf0e10cSrcweir 
350cdf0e10cSrcweir // Normal JScript object parameter can be mixed with JScriptValue object. If an
351cdf0e10cSrcweir // VARIANT contains an VT_DISPATCH that is no JScriptValue than the type information
352cdf0e10cSrcweir // is used to find out about the reqired type.
convertDispparamsArgs(DISPID id,unsigned short,DISPPARAMS * pdispparams,Sequence<Any> & rSeq)353cdf0e10cSrcweir void InterfaceOleWrapper_Impl::convertDispparamsArgs(DISPID id,
354cdf0e10cSrcweir     unsigned short /*wFlags*/, DISPPARAMS* pdispparams, Sequence<Any>& rSeq)
355cdf0e10cSrcweir {
356cdf0e10cSrcweir 	HRESULT hr= S_OK;
357cdf0e10cSrcweir 	sal_Int32 countArgs= pdispparams->cArgs;
358cdf0e10cSrcweir 	if( countArgs == 0)
359cdf0e10cSrcweir 		return;
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 	rSeq.realloc( countArgs);
362cdf0e10cSrcweir 	Any*	pParams = rSeq.getArray();
363cdf0e10cSrcweir 
364cdf0e10cSrcweir 	Any anyParam;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir     //Get type information for the current call
367cdf0e10cSrcweir     InvocationInfo info;
368cdf0e10cSrcweir     if( ! getInvocationInfoForCall( id, info))
369cdf0e10cSrcweir         throw BridgeRuntimeError(
370cdf0e10cSrcweir             OUSTR("[automation bridge]InterfaceOleWrapper_Impl::convertDispparamsArgs \n"
371cdf0e10cSrcweir                   "Could not obtain type information for current call."));
372cdf0e10cSrcweir 
373cdf0e10cSrcweir     for (int i = 0; i < countArgs; i++)
374cdf0e10cSrcweir     {
375cdf0e10cSrcweir         if (info.eMemberType == MemberType_METHOD &&
376cdf0e10cSrcweir             info.aParamModes[ countArgs - i -1 ]  == ParamMode_OUT)
377cdf0e10cSrcweir             continue;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir  		if(convertValueObject( & pdispparams->rgvarg[i], anyParam))
380cdf0e10cSrcweir  		{ //a param is a ValueObject and could be converted
381cdf0e10cSrcweir             pParams[countArgs - (i + 1)] = anyParam;
382cdf0e10cSrcweir  			continue;
383cdf0e10cSrcweir  		}
384cdf0e10cSrcweir 
385cdf0e10cSrcweir         // If the param is an out, in/out parameter in
386cdf0e10cSrcweir         // JScript (Array object, with value at index 0) then we
387cdf0e10cSrcweir         // extract Array[0] and put the value into varParam. At the end of the loop varParam
388cdf0e10cSrcweir         // is converted if it contains a value otherwise the VARIANT from
389cdf0e10cSrcweir         // DISPPARAMS is converted.
390cdf0e10cSrcweir         CComVariant varParam;
391cdf0e10cSrcweir 
392cdf0e10cSrcweir         // Check for JScript out and in/out paramsobjects (VT_DISPATCH).
393cdf0e10cSrcweir         // To find them out we use typeinformation of the function being called.
394cdf0e10cSrcweir         if( pdispparams->rgvarg[i].vt == VT_DISPATCH )
395cdf0e10cSrcweir         {
396cdf0e10cSrcweir             if( info.eMemberType == MemberType_METHOD && info.aParamModes[ countArgs - i -1 ]  == ParamMode_INOUT)
397cdf0e10cSrcweir             {
398cdf0e10cSrcweir                 // INOUT-param
399cdf0e10cSrcweir                 // Index ( property) "0" contains the actual IN-param. The object is a JScript
400cdf0e10cSrcweir                 // Array object.
401cdf0e10cSrcweir                 // Get the IN-param at index "0"
402cdf0e10cSrcweir                 IDispatch* pdisp= pdispparams->rgvarg[i].pdispVal;
403cdf0e10cSrcweir 
404cdf0e10cSrcweir                 OLECHAR* sindex= L"0";
405cdf0e10cSrcweir                 DISPID id;
406cdf0e10cSrcweir                 DISPPARAMS noParams= {0,0,0,0};
407cdf0e10cSrcweir                 if(SUCCEEDED( hr= pdisp->GetIDsOfNames( IID_NULL, &sindex, 1, LOCALE_USER_DEFAULT, &id)))
408cdf0e10cSrcweir                     hr= pdisp->Invoke( id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
409cdf0e10cSrcweir                                        & noParams, & varParam, NULL, NULL);
410cdf0e10cSrcweir                 if( FAILED( hr))
411cdf0e10cSrcweir                 {
412cdf0e10cSrcweir                     throw BridgeRuntimeError(
413cdf0e10cSrcweir                         OUSTR("[automation bridge] Could not determine "
414cdf0e10cSrcweir                               "if the object has a member \"0\". Error: ") +
415cdf0e10cSrcweir                         OUString::valueOf(hr));
416cdf0e10cSrcweir                 }
417cdf0e10cSrcweir             }
418cdf0e10cSrcweir         }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir         if( varParam.vt == VT_EMPTY) // then it was no in/out parameter
421cdf0e10cSrcweir                  varParam= pdispparams->rgvarg[i];
422cdf0e10cSrcweir 
423cdf0e10cSrcweir         if(info.eMemberType == MemberType_METHOD)
424cdf0e10cSrcweir             variantToAny( & varParam, anyParam,
425cdf0e10cSrcweir                            info.aParamTypes[ countArgs - i - 1]);
426cdf0e10cSrcweir         else if(info.eMemberType == MemberType_PROPERTY)
427cdf0e10cSrcweir             variantToAny( & varParam, anyParam, info.aType);
428cdf0e10cSrcweir         else
429cdf0e10cSrcweir             OSL_ASSERT(0);
430cdf0e10cSrcweir 
431cdf0e10cSrcweir         pParams[countArgs - (i + 1)]= anyParam;
432cdf0e10cSrcweir     }// end for / iterating over all parameters
433cdf0e10cSrcweir }
434cdf0e10cSrcweir 
getInvocationInfoForCall(DISPID id,InvocationInfo & info)435cdf0e10cSrcweir sal_Bool  InterfaceOleWrapper_Impl::getInvocationInfoForCall( DISPID id, InvocationInfo& info)
436cdf0e10cSrcweir {
437cdf0e10cSrcweir     sal_Bool bTypesAvailable= sal_False;
438cdf0e10cSrcweir 
439cdf0e10cSrcweir     if( !m_xInvocation.is() )return false;
440cdf0e10cSrcweir     Reference<XInvocation2> inv2( m_xInvocation, UNO_QUERY);
441cdf0e10cSrcweir     if( inv2.is())
442cdf0e10cSrcweir     {
443cdf0e10cSrcweir         // We need the name of the property or method to get its type information.
444cdf0e10cSrcweir         // The name can be identified through the param "id"
445cdf0e10cSrcweir         // that is kept as value in the map m_nameToDispIdMap.
446cdf0e10cSrcweir         // Proplem: the Windows JScript engine sometimes changes small letters to capital
447cdf0e10cSrcweir         // letters as happens in xidlclass_obj.createObject( var) // in JScript.
448cdf0e10cSrcweir         // IDispatch::GetIdsOfNames is then called with "CreateObject" !!!
449cdf0e10cSrcweir         // m_nameToDispIdMap can contain several names for one DISPID but only one is
450cdf0e10cSrcweir         // the exact one. If there's no m_xExactName and therefore no exact name then
451cdf0e10cSrcweir         // there's only one entry in the map.
452cdf0e10cSrcweir         typedef NameToIdMap::const_iterator cit;
453cdf0e10cSrcweir         OUString sMemberName;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir         for(cit ci1= m_nameToDispIdMap.begin(); ci1 != m_nameToDispIdMap.end(); ci1++)
456cdf0e10cSrcweir         {
457cdf0e10cSrcweir             if( (*ci1).second == id) // iterator is a pair< OUString, DISPID>
458cdf0e10cSrcweir             {
459cdf0e10cSrcweir                 sMemberName= (*ci1).first;
460cdf0e10cSrcweir                 break;
461cdf0e10cSrcweir             }
462cdf0e10cSrcweir         }
463cdf0e10cSrcweir         // Get information for the current call ( property or method).
464cdf0e10cSrcweir         // There could be similar names which only differ in the cases
465cdf0e10cSrcweir         // of letters. First we assume that the name which was passed into
466cdf0e10cSrcweir         // GetIDsOfNames is correct. If we won't get information with that
467cdf0e10cSrcweir         // name then we have the invocation service use the XExactName interface.
468cdf0e10cSrcweir         sal_Bool validInfo= sal_True;
469cdf0e10cSrcweir         InvocationInfo invInfo;
470cdf0e10cSrcweir         try{
471cdf0e10cSrcweir             invInfo= inv2->getInfoForName( sMemberName, sal_False);
472cdf0e10cSrcweir         }
473cdf0e10cSrcweir         catch( IllegalArgumentException )
474cdf0e10cSrcweir         {
475cdf0e10cSrcweir             validInfo= sal_False;
476cdf0e10cSrcweir         }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir         if( ! validInfo)
479cdf0e10cSrcweir         {
480cdf0e10cSrcweir             invInfo= inv2->getInfoForName( sMemberName, sal_True);
481cdf0e10cSrcweir         }
482cdf0e10cSrcweir         if( invInfo.aName.pData)
483cdf0e10cSrcweir         {
484cdf0e10cSrcweir             bTypesAvailable= sal_True;
485cdf0e10cSrcweir             info= invInfo;
486cdf0e10cSrcweir         }
487cdf0e10cSrcweir     }
488cdf0e10cSrcweir     return bTypesAvailable;
489cdf0e10cSrcweir }
490cdf0e10cSrcweir // XBridgeSupplier2 ---------------------------------------------------
491cdf0e10cSrcweir // only bridges itself ( this instance of InterfaceOleWrapper_Impl)from UNO to IDispatch
492cdf0e10cSrcweir // If sourceModelType is UNO than any UNO interface implemented by InterfaceOleWrapper_Impl
493cdf0e10cSrcweir // can bridged to IDispatch ( if destModelType == OLE). The IDispatch is
494cdf0e10cSrcweir // implemented by this class.
createBridge(const Any & modelDepObject,const Sequence<sal_Int8> &,sal_Int16 sourceModelType,sal_Int16 destModelType)495cdf0e10cSrcweir Any SAL_CALL InterfaceOleWrapper_Impl::createBridge(const Any& modelDepObject,
496cdf0e10cSrcweir 								const Sequence<sal_Int8>& /*ProcessId*/,
497cdf0e10cSrcweir 								sal_Int16 sourceModelType,
498cdf0e10cSrcweir 								sal_Int16 destModelType)
499cdf0e10cSrcweir 			throw (IllegalArgumentException, RuntimeException)
500cdf0e10cSrcweir {
501cdf0e10cSrcweir 
502cdf0e10cSrcweir 	Any retAny;
503cdf0e10cSrcweir 	if( sourceModelType == UNO && destModelType == OLE &&
504cdf0e10cSrcweir 		modelDepObject.getValueTypeClass() == TypeClass_INTERFACE )
505cdf0e10cSrcweir 	{
506cdf0e10cSrcweir 		Reference<XInterface> xInt;
507cdf0e10cSrcweir 		if( modelDepObject >>= xInt )
508cdf0e10cSrcweir 		{
509cdf0e10cSrcweir 			if( xInt == Reference<XInterface>( static_cast<XWeak*>( this), UNO_QUERY))
510cdf0e10cSrcweir 			{
511cdf0e10cSrcweir 				VARIANT *pVar= (VARIANT*)CoTaskMemAlloc( sizeof( VARIANT));
512cdf0e10cSrcweir 				if( pVar)
513cdf0e10cSrcweir 				{
514cdf0e10cSrcweir 					pVar->vt= VT_DISPATCH;
515cdf0e10cSrcweir 					pVar->pdispVal= static_cast<IDispatch*>( this);
516cdf0e10cSrcweir 					AddRef();
517cdf0e10cSrcweir 
518cdf0e10cSrcweir 					retAny<<= reinterpret_cast< sal_uInt32 >( pVar);
519cdf0e10cSrcweir 				}
520cdf0e10cSrcweir 			}
521cdf0e10cSrcweir 		}
522cdf0e10cSrcweir 	}
523cdf0e10cSrcweir 
524cdf0e10cSrcweir 	return retAny;
525cdf0e10cSrcweir }
526cdf0e10cSrcweir 
527cdf0e10cSrcweir 
528cdf0e10cSrcweir // XInitialization --------------------------------------------------
initialize(const Sequence<Any> & aArguments)529cdf0e10cSrcweir void SAL_CALL InterfaceOleWrapper_Impl::initialize( const Sequence< Any >& aArguments )
530cdf0e10cSrcweir 		throw(Exception, RuntimeException)
531cdf0e10cSrcweir {
532cdf0e10cSrcweir 	switch( aArguments.getLength() )
533cdf0e10cSrcweir 	{
534cdf0e10cSrcweir 	case 2: // the object wraps an UNO struct
535cdf0e10cSrcweir 		aArguments[0] >>= m_xInvocation;
536cdf0e10cSrcweir 		aArguments[1] >>= m_defaultValueType;
537cdf0e10cSrcweir 		break;
538cdf0e10cSrcweir 	case 3: // the object wraps an UNO interface
539cdf0e10cSrcweir 		aArguments[0] >>= m_xInvocation;
540cdf0e10cSrcweir 		aArguments[1] >>= m_xOrigin;
541cdf0e10cSrcweir 		aArguments[2] >>= m_defaultValueType;
542cdf0e10cSrcweir 		break;
543cdf0e10cSrcweir 	}
544cdf0e10cSrcweir 
545cdf0e10cSrcweir 	m_xExactName= Reference<XExactName>( m_xInvocation, UNO_QUERY);
546cdf0e10cSrcweir }
547cdf0e10cSrcweir 
createUnoWrapperInstance()548cdf0e10cSrcweir Reference< XInterface > InterfaceOleWrapper_Impl::createUnoWrapperInstance()
549cdf0e10cSrcweir {
550cdf0e10cSrcweir 	Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
551cdf0e10cSrcweir 							m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
552cdf0e10cSrcweir 	return Reference<XInterface>( xWeak, UNO_QUERY);
553cdf0e10cSrcweir }
554cdf0e10cSrcweir 
createComWrapperInstance()555cdf0e10cSrcweir Reference<XInterface> InterfaceOleWrapper_Impl::createComWrapperInstance()
556cdf0e10cSrcweir {
557cdf0e10cSrcweir 	Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
558cdf0e10cSrcweir 							m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
559cdf0e10cSrcweir 	return Reference<XInterface>( xWeak, UNO_QUERY);
560cdf0e10cSrcweir }
561cdf0e10cSrcweir 
562cdf0e10cSrcweir 
563cdf0e10cSrcweir 
564cdf0e10cSrcweir // "getType" is used in convertValueObject to map the string denoting the type
565cdf0e10cSrcweir // to an actual Type object.
getType(const BSTR name,Type & type)566cdf0e10cSrcweir bool getType( const BSTR name, Type & type)
567cdf0e10cSrcweir {
568cdf0e10cSrcweir 	Type retType;
569cdf0e10cSrcweir 	bool ret = false;
570cdf0e10cSrcweir 	typelib_TypeDescription	* pDesc= NULL;
571cdf0e10cSrcweir 	OUString str( reinterpret_cast<const sal_Unicode*>(name));
572cdf0e10cSrcweir 	typelib_typedescription_getByName( &pDesc, str.pData );
573cdf0e10cSrcweir 	if( pDesc)
574cdf0e10cSrcweir 	{
575cdf0e10cSrcweir 		type = Type( pDesc->pWeakRef );
576cdf0e10cSrcweir 		typelib_typedescription_release( pDesc);
577cdf0e10cSrcweir 		ret = true;
578cdf0e10cSrcweir 	}
579cdf0e10cSrcweir 	return ret;
580cdf0e10cSrcweir }
581cdf0e10cSrcweir 
writeBackOutParameter2(VARIANTARG * pDest,VARIANT * pSource)582cdf0e10cSrcweir static sal_Bool writeBackOutParameter2( VARIANTARG* pDest, VARIANT* pSource)
583cdf0e10cSrcweir {
584cdf0e10cSrcweir 	sal_Bool ret = sal_False;
585cdf0e10cSrcweir 	HRESULT hr;
586cdf0e10cSrcweir 
587cdf0e10cSrcweir 	// Handle JScriptValue objects and JScript out params ( Array object )
588cdf0e10cSrcweir 	CComVariant varDest( *pDest);
589cdf0e10cSrcweir 
590cdf0e10cSrcweir 	if( SUCCEEDED( varDest.ChangeType(VT_DISPATCH)))
591cdf0e10cSrcweir 	{
592cdf0e10cSrcweir 		CComPtr<IDispatch> spDispDest(varDest.pdispVal);
593cdf0e10cSrcweir 
594cdf0e10cSrcweir 		// special Handling for a JScriptValue object
595cdf0e10cSrcweir #ifdef __MINGW32__
596cdf0e10cSrcweir 		CComQIPtr<IJScriptValueObject, &__uuidof(IJScriptValueObject)> spValueDest(spDispDest);
597cdf0e10cSrcweir #else
598cdf0e10cSrcweir 		CComQIPtr<IJScriptValueObject> spValueDest(spDispDest);
599cdf0e10cSrcweir #endif
600cdf0e10cSrcweir 		if (spValueDest)
601cdf0e10cSrcweir 		{
602cdf0e10cSrcweir 			VARIANT_BOOL varBool= VARIANT_FALSE;
603cdf0e10cSrcweir 			if( SUCCEEDED( hr= spValueDest->IsOutParam( &varBool) )
604cdf0e10cSrcweir 				&& varBool == VARIANT_TRUE  ||
605cdf0e10cSrcweir 				SUCCEEDED(hr= spValueDest->IsInOutParam( &varBool) )
606cdf0e10cSrcweir 				&& varBool == VARIANT_TRUE )
607cdf0e10cSrcweir 			{
608cdf0e10cSrcweir 				if( SUCCEEDED( spValueDest->Set( CComVariant(), *pSource)))
609cdf0e10cSrcweir 					ret= sal_True;
610cdf0e10cSrcweir 			}
611cdf0e10cSrcweir 		}
612cdf0e10cSrcweir 		else if (pDest->vt == VT_DISPATCH)// VT_DISPATCH -> JScript out param
613cdf0e10cSrcweir 		{
614cdf0e10cSrcweir 			// We use IDispatchEx because its GetDispID function causes the creation
615cdf0e10cSrcweir 			// of a property if it does not exist already. This is convenient for
616cdf0e10cSrcweir 			// out parameters in JScript. Then the user must not specify propery "0"
617cdf0e10cSrcweir 			// explicitly
618cdf0e10cSrcweir #ifdef __MINGW32__
619cdf0e10cSrcweir 			CComQIPtr<IDispatchEx, &__uuidof(IDispatchEx)> spDispEx( spDispDest);
620cdf0e10cSrcweir #else
621cdf0e10cSrcweir 			CComQIPtr<IDispatchEx> spDispEx( spDispDest);
622cdf0e10cSrcweir #endif
623cdf0e10cSrcweir 			if( spDispEx)
624cdf0e10cSrcweir 			{
625cdf0e10cSrcweir 				CComBSTR nullProp(L"0");
626cdf0e10cSrcweir 				DISPID dwDispID;
627cdf0e10cSrcweir 				if( SUCCEEDED( spDispEx->GetDispID( nullProp, fdexNameEnsure, &dwDispID)))
628cdf0e10cSrcweir 				{
629cdf0e10cSrcweir 					DISPPARAMS dispparams = {NULL, NULL, 1, 1};
630cdf0e10cSrcweir 					dispparams.rgvarg = pSource;
631cdf0e10cSrcweir 					DISPID dispidPut = DISPID_PROPERTYPUT;
632cdf0e10cSrcweir 					dispparams.rgdispidNamedArgs = &dispidPut;
633cdf0e10cSrcweir 
634cdf0e10cSrcweir 					if (pSource->vt == VT_UNKNOWN || pSource->vt == VT_DISPATCH ||
635cdf0e10cSrcweir 						(pSource->vt & VT_ARRAY) || (pSource->vt & VT_BYREF))
636cdf0e10cSrcweir 						hr = spDispEx->InvokeEx(dwDispID, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF,
637cdf0e10cSrcweir 												&dispparams, NULL, NULL, NULL);
638cdf0e10cSrcweir 					else
639cdf0e10cSrcweir 						hr= spDispEx->InvokeEx(dwDispID, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT,
640cdf0e10cSrcweir 											   &dispparams, NULL, NULL, NULL);
641cdf0e10cSrcweir 					if( SUCCEEDED(hr))
642cdf0e10cSrcweir 						ret= sal_True;
643cdf0e10cSrcweir 				}
644cdf0e10cSrcweir 			}
645cdf0e10cSrcweir 		}
646cdf0e10cSrcweir 		else
647cdf0e10cSrcweir 			ret= writeBackOutParameter( pDest, pSource);
648cdf0e10cSrcweir 	}
649cdf0e10cSrcweir 	else // The param can't be a JScript out-parameter ( an Array object), it could be a VBScript
650cdf0e10cSrcweir 	{	// param. The function checks itself for correct VBScript params
651cdf0e10cSrcweir 		ret= writeBackOutParameter( pDest, pSource);
652cdf0e10cSrcweir 	}
653cdf0e10cSrcweir 	return ret;
654cdf0e10cSrcweir }
655cdf0e10cSrcweir // VisualBasic Script passes arguments as VT_VARIANT | VT_BYREF be it in or out parameter.
656cdf0e10cSrcweir // Thus we are in charge of freeing an eventual value contained by the inner VARIANT
657cdf0e10cSrcweir // Please note: VariantCopy doesn't free a VT_BYREF value
658cdf0e10cSrcweir // The out parameters are expected to have always a valid type
writeBackOutParameter(VARIANTARG * pDest,VARIANT * pSource)659cdf0e10cSrcweir static sal_Bool writeBackOutParameter(VARIANTARG* pDest, VARIANT* pSource)
660cdf0e10cSrcweir {
661cdf0e10cSrcweir 	HRESULT hr;
662cdf0e10cSrcweir 	sal_Bool ret = FALSE;
663cdf0e10cSrcweir 	// Out parameter must be VT_BYREF
664cdf0e10cSrcweir 	if ((V_VT(pDest) & VT_BYREF) != 0 )
665cdf0e10cSrcweir 	{
666cdf0e10cSrcweir 		VARTYPE oleTypeFlags = V_VT(pSource);
667cdf0e10cSrcweir 
668cdf0e10cSrcweir 		// if caller accept VARIANT as out parameter, any value must be converted
669cdf0e10cSrcweir 		if (V_VT(pDest) == (VT_VARIANT | VT_BYREF))
670cdf0e10cSrcweir 		{
671cdf0e10cSrcweir 			// When the user provides a VARIANT rather then a concrete type
672cdf0e10cSrcweir 			// we just copy the source to the out, in/out parameter
673cdf0e10cSrcweir 			// VT_DISPATCH, VT_UNKNOWN, VT_ARRAY, VT_BSTR in the VARIANT that
674cdf0e10cSrcweir 			// is contained in pDest are released by VariantCopy
675cdf0e10cSrcweir 			VariantCopy(V_VARIANTREF(pDest), pSource);
676cdf0e10cSrcweir 			ret	= sal_True;
677cdf0e10cSrcweir 		}
678cdf0e10cSrcweir 		else
679cdf0e10cSrcweir 		{
680cdf0e10cSrcweir 			// variantarg and variant must have same type
681cdf0e10cSrcweir   			if ((V_VT(pDest) & oleTypeFlags) == oleTypeFlags)
682cdf0e10cSrcweir 			{
683cdf0e10cSrcweir 				if ((oleTypeFlags & VT_ARRAY) != 0)
684cdf0e10cSrcweir 				{
685cdf0e10cSrcweir 					// In / Out Param
686cdf0e10cSrcweir 					if( *V_ARRAYREF(pDest) != NULL)
687cdf0e10cSrcweir 						hr= SafeArrayCopyData( V_ARRAY(pSource), *V_ARRAYREF(pDest));
688cdf0e10cSrcweir 					else
689cdf0e10cSrcweir 						// Out Param
690cdf0e10cSrcweir 						hr= SafeArrayCopy(V_ARRAY(pSource), V_ARRAYREF(pDest)) == NOERROR;
691cdf0e10cSrcweir 					if( SUCCEEDED( hr))
692cdf0e10cSrcweir 						ret	= sal_True;
693cdf0e10cSrcweir 				}
694cdf0e10cSrcweir 				else
695cdf0e10cSrcweir 				{
696cdf0e10cSrcweir 					// copy base type
697cdf0e10cSrcweir 					switch (V_VT(pSource))
698cdf0e10cSrcweir 					{
699cdf0e10cSrcweir 					case VT_I2:
700cdf0e10cSrcweir 					{
701cdf0e10cSrcweir 						*V_I2REF(pDest) = V_I2(pSource);
702cdf0e10cSrcweir 						ret	= sal_True;
703cdf0e10cSrcweir 						break;
704cdf0e10cSrcweir 					}
705cdf0e10cSrcweir 					case VT_I4:
706cdf0e10cSrcweir 						*V_I4REF(pDest) = V_I4(pSource);
707cdf0e10cSrcweir 						ret	= sal_True;
708cdf0e10cSrcweir 						break;
709cdf0e10cSrcweir 					case VT_R4:
710cdf0e10cSrcweir 						*V_R4REF(pDest) = V_R4(pSource);
711cdf0e10cSrcweir 						ret	= sal_True;
712cdf0e10cSrcweir 						break;
713cdf0e10cSrcweir 					case VT_R8:
714cdf0e10cSrcweir 						*V_R8REF(pDest) = V_R8(pSource);
715cdf0e10cSrcweir 						ret	= sal_True;
716cdf0e10cSrcweir 						break;
717cdf0e10cSrcweir 					case VT_CY:
718cdf0e10cSrcweir 						*V_CYREF(pDest) = V_CY(pSource);
719cdf0e10cSrcweir 						ret	= sal_True;
720cdf0e10cSrcweir 						break;
721cdf0e10cSrcweir 					case VT_DATE:
722cdf0e10cSrcweir 						*V_DATEREF(pDest) = V_DATE(pSource);
723cdf0e10cSrcweir 						ret	= sal_True;
724cdf0e10cSrcweir 						break;
725cdf0e10cSrcweir 					case VT_BSTR:
726cdf0e10cSrcweir 						SysFreeString( *pDest->pbstrVal);
727cdf0e10cSrcweir 
728cdf0e10cSrcweir 						*V_BSTRREF(pDest) = SysAllocString(V_BSTR(pSource));
729cdf0e10cSrcweir 						ret	= sal_True;
730cdf0e10cSrcweir 						break;
731cdf0e10cSrcweir 					case VT_DISPATCH:
732cdf0e10cSrcweir 						if (*V_DISPATCHREF(pDest) != NULL)
733cdf0e10cSrcweir 							(*V_DISPATCHREF(pDest))->Release();
734cdf0e10cSrcweir 
735cdf0e10cSrcweir 						*V_DISPATCHREF(pDest) = V_DISPATCH(pSource);
736cdf0e10cSrcweir 
737cdf0e10cSrcweir 						if (*V_DISPATCHREF(pDest) != NULL)
738cdf0e10cSrcweir 							(*V_DISPATCHREF(pDest))->AddRef();
739cdf0e10cSrcweir 
740cdf0e10cSrcweir 						ret	= sal_True;
741cdf0e10cSrcweir 						break;
742cdf0e10cSrcweir 					case VT_ERROR:
743cdf0e10cSrcweir 						*V_ERRORREF(pDest) = V_ERROR(pSource);
744cdf0e10cSrcweir 						ret	= sal_True;
745cdf0e10cSrcweir 						break;
746cdf0e10cSrcweir 					case VT_BOOL:
747cdf0e10cSrcweir 						*V_BOOLREF(pDest) = V_BOOL(pSource);
748cdf0e10cSrcweir 						ret	= sal_True;
749cdf0e10cSrcweir 						break;
750cdf0e10cSrcweir 					case VT_UNKNOWN:
751cdf0e10cSrcweir 						if (*V_UNKNOWNREF(pDest) != NULL)
752cdf0e10cSrcweir 							(*V_UNKNOWNREF(pDest))->Release();
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 						*V_UNKNOWNREF(pDest) = V_UNKNOWN(pSource);
755cdf0e10cSrcweir 
756cdf0e10cSrcweir 						if (*V_UNKNOWNREF(pDest) != NULL)
757cdf0e10cSrcweir 							(*V_UNKNOWNREF(pDest))->AddRef();
758cdf0e10cSrcweir 
759cdf0e10cSrcweir 						ret	= sal_True;
760cdf0e10cSrcweir 						break;
761cdf0e10cSrcweir 					case VT_I1:
762cdf0e10cSrcweir 						*V_I1REF(pDest) = V_I1(pSource);
763cdf0e10cSrcweir 						ret	= sal_True;
764cdf0e10cSrcweir 						break;
765cdf0e10cSrcweir 					case VT_UI1:
766cdf0e10cSrcweir 						*V_UI1REF(pDest) = V_UI1(pSource);
767cdf0e10cSrcweir 						ret	= sal_True;
768cdf0e10cSrcweir 						break;
769cdf0e10cSrcweir 					case VT_UI2:
770cdf0e10cSrcweir 						*V_UI2REF(pDest) = V_UI2(pSource);
771cdf0e10cSrcweir 						ret	= sal_True;
772cdf0e10cSrcweir 						break;
773cdf0e10cSrcweir 					case VT_UI4:
774cdf0e10cSrcweir 						*V_UI4REF(pDest) = V_UI4(pSource);
775cdf0e10cSrcweir 						ret	= sal_True;
776cdf0e10cSrcweir 						break;
777cdf0e10cSrcweir 					case VT_INT:
778cdf0e10cSrcweir 						*V_INTREF(pDest) = V_INT(pSource);
779cdf0e10cSrcweir 						ret	= sal_True;
780cdf0e10cSrcweir 						break;
781cdf0e10cSrcweir 					case VT_UINT:
782cdf0e10cSrcweir 						*V_UINTREF(pDest) = V_UINT(pSource);
783cdf0e10cSrcweir 						ret	= sal_True;
784cdf0e10cSrcweir 						break;
785cdf0e10cSrcweir 					case VT_DECIMAL:
786cdf0e10cSrcweir                         memcpy(pDest->pdecVal, pSource, sizeof(DECIMAL));
787cdf0e10cSrcweir                         ret = sal_True;
788cdf0e10cSrcweir                         break;
789cdf0e10cSrcweir 					default:
790cdf0e10cSrcweir 						break;
791cdf0e10cSrcweir 					}
792cdf0e10cSrcweir 				}
793cdf0e10cSrcweir 			}
794cdf0e10cSrcweir 			else
795cdf0e10cSrcweir 			{
796cdf0e10cSrcweir 				// Handling of special cases
797cdf0e10cSrcweir 				// Destination and source types are different
798cdf0e10cSrcweir 				if( pDest->vt == (VT_BSTR | VT_BYREF)
799cdf0e10cSrcweir 					&& pSource->vt == VT_I2)
800cdf0e10cSrcweir 				{
801cdf0e10cSrcweir 					// When the user provides a String as out our in/out parameter
802cdf0e10cSrcweir 					// and the type is char (TypeClass_CHAR) then we convert to a BSTR
803cdf0e10cSrcweir 					// instead of VT_I2 as is done otherwise
804cdf0e10cSrcweir 					OLECHAR buff[]= {0,0};
805cdf0e10cSrcweir 					buff[0]= pSource->iVal;
806cdf0e10cSrcweir 
807cdf0e10cSrcweir 					SysFreeString( *pDest->pbstrVal);
808cdf0e10cSrcweir 					*pDest->pbstrVal= SysAllocString( buff);
809cdf0e10cSrcweir 					ret = sal_True;
810cdf0e10cSrcweir 				}
811cdf0e10cSrcweir 			}
812cdf0e10cSrcweir 		}
813cdf0e10cSrcweir 	}
814cdf0e10cSrcweir 	return ret;
815cdf0e10cSrcweir }
816cdf0e10cSrcweir 
Invoke(DISPID dispidMember,REFIID,LCID,unsigned short wFlags,DISPPARAMS * pdispparams,VARIANT * pvarResult,EXCEPINFO * pexcepinfo,unsigned int * puArgErr)817cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::Invoke(DISPID dispidMember,
818cdf0e10cSrcweir 											  REFIID /*riid*/,
819cdf0e10cSrcweir 											  LCID /*lcid*/,
820cdf0e10cSrcweir 											  unsigned short wFlags,
821cdf0e10cSrcweir                      						  DISPPARAMS * pdispparams,
822cdf0e10cSrcweir 											  VARIANT * pvarResult,
823cdf0e10cSrcweir 											  EXCEPINFO * pexcepinfo,
824cdf0e10cSrcweir                      						  unsigned int * puArgErr )
825cdf0e10cSrcweir {
826cdf0e10cSrcweir 	HRESULT ret = S_OK;
827cdf0e10cSrcweir 
828cdf0e10cSrcweir     try
829cdf0e10cSrcweir     {
830cdf0e10cSrcweir         sal_Bool bHandled= sal_False;
831cdf0e10cSrcweir         ret= InvokeGeneral( dispidMember,  wFlags, pdispparams, pvarResult,  pexcepinfo,
832cdf0e10cSrcweir                             puArgErr, bHandled);
833cdf0e10cSrcweir         if( bHandled)
834cdf0e10cSrcweir             return ret;
835cdf0e10cSrcweir 
836cdf0e10cSrcweir         if ((dispidMember > 0) && ((size_t)dispidMember <= m_MemberInfos.size()) && m_xInvocation.is())
837cdf0e10cSrcweir         {
838cdf0e10cSrcweir             MemberInfo d = m_MemberInfos[dispidMember - 1];
839cdf0e10cSrcweir             DWORD flags = wFlags & d.flags;
840cdf0e10cSrcweir 
841cdf0e10cSrcweir             if (flags != 0)
842cdf0e10cSrcweir             {
843cdf0e10cSrcweir                 if ((flags & DISPATCH_METHOD) != 0)
844cdf0e10cSrcweir                 {
845cdf0e10cSrcweir                     if (pdispparams->cNamedArgs	> 0)
846cdf0e10cSrcweir                         ret = DISP_E_NONAMEDARGS;
847cdf0e10cSrcweir                     else
848cdf0e10cSrcweir                     {
849cdf0e10cSrcweir                         Sequence<Any> params;
850cdf0e10cSrcweir 
851cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams , params );
852cdf0e10cSrcweir 
853cdf0e10cSrcweir                         ret= doInvoke(pdispparams, pvarResult,
854cdf0e10cSrcweir                                       pexcepinfo, puArgErr, d.name, params);
855cdf0e10cSrcweir                     }
856cdf0e10cSrcweir                 }
857cdf0e10cSrcweir                 else if ((flags & DISPATCH_PROPERTYGET) != 0)
858cdf0e10cSrcweir                 {
859cdf0e10cSrcweir                     ret=  doGetProperty( pdispparams, pvarResult,
860cdf0e10cSrcweir                                          pexcepinfo, d.name);
861cdf0e10cSrcweir                 }
862cdf0e10cSrcweir                 else if ((flags & DISPATCH_PROPERTYPUT || flags & DISPATCH_PROPERTYPUTREF) != 0)
863cdf0e10cSrcweir                 {
864cdf0e10cSrcweir                     if (pdispparams->cArgs != 1)
865cdf0e10cSrcweir                         ret = DISP_E_BADPARAMCOUNT;
866cdf0e10cSrcweir                     else
867cdf0e10cSrcweir                     {
868cdf0e10cSrcweir                         Sequence<Any> params;
869cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
870cdf0e10cSrcweir                         if(params.getLength() > 0)
871cdf0e10cSrcweir                             ret= doSetProperty( pdispparams, pvarResult, pexcepinfo, puArgErr, d.name, params);
872cdf0e10cSrcweir                         else
873cdf0e10cSrcweir                             ret = DISP_E_BADVARTYPE;
874cdf0e10cSrcweir                     }
875cdf0e10cSrcweir                 }
876cdf0e10cSrcweir             }
877cdf0e10cSrcweir             else
878cdf0e10cSrcweir                 ret= DISP_E_MEMBERNOTFOUND;
879cdf0e10cSrcweir         }
880cdf0e10cSrcweir         else
881cdf0e10cSrcweir             ret = DISP_E_MEMBERNOTFOUND;
882cdf0e10cSrcweir     }
883cdf0e10cSrcweir     catch(BridgeRuntimeError& e)
884cdf0e10cSrcweir     {
885cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
886cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
887cdf0e10cSrcweir     }
888cdf0e10cSrcweir     catch(Exception& e)
889cdf0e10cSrcweir     {
890cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::Invoke : \n") +
891cdf0e10cSrcweir                                 e.Message;
892cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
893cdf0e10cSrcweir 		ret = DISP_E_EXCEPTION;
894cdf0e10cSrcweir     }
895cdf0e10cSrcweir 	catch(...)
896cdf0e10cSrcweir 	{
897cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::Invoke : \n"
898cdf0e10cSrcweir                                 "Unexpected exception");
899cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
900cdf0e10cSrcweir  		ret = DISP_E_EXCEPTION;
901cdf0e10cSrcweir 	}
902cdf0e10cSrcweir 
903cdf0e10cSrcweir 	return ret;
904cdf0e10cSrcweir }
905cdf0e10cSrcweir 
doInvoke(DISPPARAMS * pdispparams,VARIANT * pvarResult,EXCEPINFO * pexcepinfo,unsigned int * puArgErr,OUString & name,Sequence<Any> & params)906cdf0e10cSrcweir HRESULT InterfaceOleWrapper_Impl::doInvoke( DISPPARAMS * pdispparams, VARIANT * pvarResult,
907cdf0e10cSrcweir 							  EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString& name, Sequence<Any>& params)
908cdf0e10cSrcweir {
909cdf0e10cSrcweir 
910cdf0e10cSrcweir 
911cdf0e10cSrcweir 	HRESULT ret= S_OK;
912cdf0e10cSrcweir     try
913cdf0e10cSrcweir     {
914cdf0e10cSrcweir         Sequence<sal_Int16> 	outIndex;
915cdf0e10cSrcweir         Sequence<Any> 	outParams;
916cdf0e10cSrcweir         Any 				returnValue;
917cdf0e10cSrcweir 
918cdf0e10cSrcweir         if (pdispparams->cNamedArgs	> 0)
919cdf0e10cSrcweir             return DISP_E_NONAMEDARGS;
920cdf0e10cSrcweir 
921cdf0e10cSrcweir         // invoke method and take care of exceptions
922cdf0e10cSrcweir 		returnValue = m_xInvocation->invoke(name,
923cdf0e10cSrcweir 											params,
924cdf0e10cSrcweir 											outIndex,
925cdf0e10cSrcweir 											outParams);
926cdf0e10cSrcweir 
927cdf0e10cSrcweir         // try to write back out parameter
928cdf0e10cSrcweir         if (outIndex.getLength() > 0)
929cdf0e10cSrcweir         {
930cdf0e10cSrcweir             const sal_Int16* pOutIndex = outIndex.getConstArray();
931cdf0e10cSrcweir             const Any* pOutParams = outParams.getConstArray();
932cdf0e10cSrcweir 
933cdf0e10cSrcweir             for (sal_Int32 i = 0; i < outIndex.getLength(); i++)
934cdf0e10cSrcweir             {
935cdf0e10cSrcweir                 CComVariant variant;
936cdf0e10cSrcweir                 // Currently a Sequence is converted to an SafeArray of VARIANTs.
937cdf0e10cSrcweir                 anyToVariant( &variant, pOutParams[i]);
938cdf0e10cSrcweir 
939cdf0e10cSrcweir                 // out parameter need special handling if they are VT_DISPATCH
940cdf0e10cSrcweir                 // and used in JScript
941cdf0e10cSrcweir                 int outindex= pOutIndex[i];
942cdf0e10cSrcweir                 writeBackOutParameter2(&(pdispparams->rgvarg[pdispparams->cArgs - 1 - outindex]),
943cdf0e10cSrcweir                                        &variant );
944cdf0e10cSrcweir             }
945cdf0e10cSrcweir         }
946cdf0e10cSrcweir 
947cdf0e10cSrcweir         // write back return value
948cdf0e10cSrcweir         if (pvarResult != NULL)
949cdf0e10cSrcweir             anyToVariant(pvarResult, returnValue);
950cdf0e10cSrcweir     }
951cdf0e10cSrcweir 	catch(IllegalArgumentException & e) //XInvocation::invoke
952cdf0e10cSrcweir 	{
953cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.Message);
954cdf0e10cSrcweir 		ret = DISP_E_TYPEMISMATCH;
955cdf0e10cSrcweir 	}
956cdf0e10cSrcweir 	catch(CannotConvertException & e) //XInvocation::invoke
957cdf0e10cSrcweir 	{
958cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.Message);
959cdf0e10cSrcweir 		ret = mapCannotConvertException( e, puArgErr);
960cdf0e10cSrcweir 	}
961cdf0e10cSrcweir 	catch(InvocationTargetException &  e) //XInvocation::invoke
962cdf0e10cSrcweir 	{
963cdf0e10cSrcweir         const Any& org = e.TargetException;
964cdf0e10cSrcweir         Exception excTarget;
965cdf0e10cSrcweir         org >>= excTarget;
966cdf0e10cSrcweir         OUString message=
967cdf0e10cSrcweir             org.getValueType().getTypeName() + OUSTR(": ") + excTarget.Message;
968cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
969cdf0e10cSrcweir 		ret = DISP_E_EXCEPTION;
970cdf0e10cSrcweir 	}
971cdf0e10cSrcweir 	catch(NoSuchMethodException & e) //XInvocation::invoke
972cdf0e10cSrcweir 	{
973cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.Message);
974cdf0e10cSrcweir 		ret = DISP_E_MEMBERNOTFOUND;
975cdf0e10cSrcweir 	}
976cdf0e10cSrcweir     catch(BridgeRuntimeError & e)
977cdf0e10cSrcweir     {
978cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
979cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
980cdf0e10cSrcweir     }
981cdf0e10cSrcweir     catch(Exception & e)
982cdf0e10cSrcweir     {
983cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n") +
984cdf0e10cSrcweir                                 e.Message;
985cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
986cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
987cdf0e10cSrcweir     }
988cdf0e10cSrcweir     catch( ... )
989cdf0e10cSrcweir  	{
990cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n"
991cdf0e10cSrcweir                                 "Unexpected exception");
992cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
993cdf0e10cSrcweir  		ret = DISP_E_EXCEPTION;
994cdf0e10cSrcweir  	}
995cdf0e10cSrcweir 	return ret;
996cdf0e10cSrcweir }
997cdf0e10cSrcweir 
doGetProperty(DISPPARAMS *,VARIANT * pvarResult,EXCEPINFO * pexcepinfo,OUString & name)998cdf0e10cSrcweir HRESULT InterfaceOleWrapper_Impl::doGetProperty( DISPPARAMS * /*pdispparams*/, VARIANT * pvarResult,
999cdf0e10cSrcweir 												EXCEPINFO * pexcepinfo, OUString& name)
1000cdf0e10cSrcweir {
1001cdf0e10cSrcweir 	HRESULT ret= S_OK;
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir 	Any value;
1004cdf0e10cSrcweir 	try
1005cdf0e10cSrcweir 	{
1006cdf0e10cSrcweir 		Any returnValue = m_xInvocation->getValue( name);
1007cdf0e10cSrcweir 		// write back return value
1008cdf0e10cSrcweir 		if (pvarResult)
1009cdf0e10cSrcweir             anyToVariant(pvarResult, returnValue);
1010cdf0e10cSrcweir 	}
1011cdf0e10cSrcweir 	catch(UnknownPropertyException e) //XInvocation::getValue
1012cdf0e10cSrcweir 	{
1013cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.Message);
1014cdf0e10cSrcweir 		ret = DISP_E_MEMBERNOTFOUND;
1015cdf0e10cSrcweir 	}
1016cdf0e10cSrcweir     catch(BridgeRuntimeError& e)
1017cdf0e10cSrcweir     {
1018cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
1019cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1020cdf0e10cSrcweir     }
1021cdf0e10cSrcweir     catch(Exception& e)
1022cdf0e10cSrcweir     {
1023cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::doGetProperty : \n") +
1024cdf0e10cSrcweir                                 e.Message;
1025cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1026cdf0e10cSrcweir     }
1027cdf0e10cSrcweir 	catch( ... )
1028cdf0e10cSrcweir 	{
1029cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n"
1030cdf0e10cSrcweir                                 "Unexpected exception");
1031cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1032cdf0e10cSrcweir  		ret = DISP_E_EXCEPTION;
1033cdf0e10cSrcweir 	}
1034cdf0e10cSrcweir 	return  ret;
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir 
doSetProperty(DISPPARAMS *,VARIANT *,EXCEPINFO * pexcepinfo,unsigned int * puArgErr,OUString & name,Sequence<Any> params)1037cdf0e10cSrcweir HRESULT InterfaceOleWrapper_Impl::doSetProperty( DISPPARAMS * /*pdispparams*/, VARIANT * /*pvarResult*/,
1038cdf0e10cSrcweir 										EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString& name, Sequence<Any> params)
1039cdf0e10cSrcweir {
1040cdf0e10cSrcweir 	HRESULT ret= S_OK;
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir 	try
1043cdf0e10cSrcweir 	{
1044cdf0e10cSrcweir 		m_xInvocation->setValue( name, params.getConstArray()[0]);
1045cdf0e10cSrcweir 	}
1046cdf0e10cSrcweir 	catch(UnknownPropertyException )
1047cdf0e10cSrcweir 	{
1048cdf0e10cSrcweir 		ret = DISP_E_MEMBERNOTFOUND;
1049cdf0e10cSrcweir 	}
1050cdf0e10cSrcweir 	catch(CannotConvertException e)
1051cdf0e10cSrcweir 	{
1052cdf0e10cSrcweir 		ret= mapCannotConvertException( e, puArgErr);
1053cdf0e10cSrcweir 	}
1054cdf0e10cSrcweir 	catch(InvocationTargetException e)
1055cdf0e10cSrcweir 	{
1056cdf0e10cSrcweir 		if (pexcepinfo != NULL)
1057cdf0e10cSrcweir 		{
1058cdf0e10cSrcweir 			Any org = e.TargetException;
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir 			pexcepinfo->wCode = UNO_2_OLE_EXCEPTIONCODE;
1061cdf0e10cSrcweir 			pexcepinfo->bstrSource = SysAllocString(L"any ONE component");
1062cdf0e10cSrcweir 			pexcepinfo->bstrDescription = SysAllocString(
1063cdf0e10cSrcweir 				reinterpret_cast<LPCOLESTR>(org.getValueType().getTypeName().getStr()));
1064cdf0e10cSrcweir 		}
1065cdf0e10cSrcweir 		ret = DISP_E_EXCEPTION;
1066cdf0e10cSrcweir 	}
1067cdf0e10cSrcweir 	catch( ... )
1068cdf0e10cSrcweir 	{
1069cdf0e10cSrcweir 		ret= DISP_E_EXCEPTION;
1070cdf0e10cSrcweir 	}
1071cdf0e10cSrcweir 	return ret;
1072cdf0e10cSrcweir }
1073cdf0e10cSrcweir 
InvokeGeneral(DISPID dispidMember,unsigned short wFlags,DISPPARAMS * pdispparams,VARIANT * pvarResult,EXCEPINFO * pexcepinfo,unsigned int *,sal_Bool & bHandled)1074cdf0e10cSrcweir HRESULT InterfaceOleWrapper_Impl::InvokeGeneral( DISPID dispidMember, unsigned short wFlags,
1075cdf0e10cSrcweir 	                     DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
1076cdf0e10cSrcweir 	                     unsigned int * /*puArgErr*/, sal_Bool& bHandled)
1077cdf0e10cSrcweir {
1078cdf0e10cSrcweir 	HRESULT ret= S_OK;
1079cdf0e10cSrcweir     try
1080cdf0e10cSrcweir     {
1081cdf0e10cSrcweir // DISPID_VALUE | The DEFAULT Value is required in JScript when the situation
1082cdf0e10cSrcweir // is that we put an object into an Array object ( out parameter). We have to return
1083cdf0e10cSrcweir // IDispatch otherwise the object cannot be accessed from the Script.
1084cdf0e10cSrcweir         if( dispidMember == DISPID_VALUE && wFlags == DISPATCH_PROPERTYGET
1085cdf0e10cSrcweir             && m_defaultValueType != VT_EMPTY && pvarResult != NULL)
1086cdf0e10cSrcweir         {
1087cdf0e10cSrcweir             bHandled= sal_True;
1088cdf0e10cSrcweir             if( m_defaultValueType == VT_DISPATCH)
1089cdf0e10cSrcweir             {
1090cdf0e10cSrcweir                 pvarResult->vt= VT_DISPATCH;
1091cdf0e10cSrcweir                 pvarResult->pdispVal= static_cast<IDispatch*>( this);
1092cdf0e10cSrcweir                 AddRef();
1093cdf0e10cSrcweir                 ret= S_OK;
1094cdf0e10cSrcweir             }
1095cdf0e10cSrcweir         }
1096cdf0e10cSrcweir // ---------
1097cdf0e10cSrcweir         // function: _GetValueObject
1098cdf0e10cSrcweir         else if( dispidMember == DISPID_JSCRIPT_VALUE_FUNC)
1099cdf0e10cSrcweir         {
1100cdf0e10cSrcweir             bHandled= sal_True;
1101cdf0e10cSrcweir             if( !pvarResult)
1102cdf0e10cSrcweir                 ret= E_POINTER;
1103cdf0e10cSrcweir             CComObject< JScriptValue>* pValue;
1104cdf0e10cSrcweir             if( SUCCEEDED( CComObject<JScriptValue>::CreateInstance( &pValue)))
1105cdf0e10cSrcweir             {
1106cdf0e10cSrcweir                 pValue->AddRef();
1107cdf0e10cSrcweir                 pvarResult->vt= VT_DISPATCH;
1108cdf0e10cSrcweir #ifdef __MINGW32__
1109cdf0e10cSrcweir                 pvarResult->pdispVal= CComQIPtr<IDispatch, &__uuidof(IDispatch)>(pValue->GetUnknown());
1110cdf0e10cSrcweir #else
1111cdf0e10cSrcweir                 pvarResult->pdispVal= CComQIPtr<IDispatch>(pValue->GetUnknown());
1112cdf0e10cSrcweir #endif
1113cdf0e10cSrcweir                 ret= S_OK;
1114cdf0e10cSrcweir             }
1115cdf0e10cSrcweir             else
1116cdf0e10cSrcweir                 ret= DISP_E_EXCEPTION;
1117cdf0e10cSrcweir         }
1118cdf0e10cSrcweir         else if( dispidMember == DISPID_GET_STRUCT_FUNC)
1119cdf0e10cSrcweir         {
1120cdf0e10cSrcweir             bHandled= sal_True;
1121cdf0e10cSrcweir             sal_Bool bStruct= sal_False;
1122cdf0e10cSrcweir 
1123cdf0e10cSrcweir 
1124cdf0e10cSrcweir             Reference<XInterface> xIntCore=	m_smgr->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection"));
1125cdf0e10cSrcweir             Reference<XIdlReflection> xRefl( xIntCore, UNO_QUERY);
1126cdf0e10cSrcweir             if( xRefl.is() )
1127cdf0e10cSrcweir             {
1128cdf0e10cSrcweir                 // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1129cdf0e10cSrcweir                 CComVariant arg;
1130cdf0e10cSrcweir                 if( pdispparams->cArgs == 1 && SUCCEEDED( arg.ChangeType( VT_BSTR, &pdispparams->rgvarg[0])) )
1131cdf0e10cSrcweir                 {
1132cdf0e10cSrcweir                     Reference<XIdlClass> classStruct= xRefl->forName( reinterpret_cast<const sal_Unicode*>(arg.bstrVal));
1133cdf0e10cSrcweir                     if( classStruct.is())
1134cdf0e10cSrcweir                     {
1135cdf0e10cSrcweir                         Any anyStruct;
1136cdf0e10cSrcweir                         classStruct->createObject( anyStruct);
1137cdf0e10cSrcweir                         CComVariant var;
1138cdf0e10cSrcweir                         anyToVariant( &var, anyStruct );
1139cdf0e10cSrcweir 
1140cdf0e10cSrcweir                         if( var.vt == VT_DISPATCH)
1141cdf0e10cSrcweir                         {
1142cdf0e10cSrcweir                             VariantCopy( pvarResult, & var);
1143cdf0e10cSrcweir                             bStruct= sal_True;
1144cdf0e10cSrcweir                         }
1145cdf0e10cSrcweir                     }
1146cdf0e10cSrcweir                 }
1147cdf0e10cSrcweir             }
1148cdf0e10cSrcweir             ret= bStruct == sal_True ? S_OK : DISP_E_EXCEPTION;
1149cdf0e10cSrcweir         }
1150cdf0e10cSrcweir         else if (dispidMember == DISPID_CREATE_TYPE_FUNC)
1151cdf0e10cSrcweir         {
1152cdf0e10cSrcweir             bHandled= sal_True;
1153cdf0e10cSrcweir             if( !pvarResult)
1154cdf0e10cSrcweir                 ret= E_POINTER;
1155cdf0e10cSrcweir             // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
1156cdf0e10cSrcweir             CComVariant arg;
1157cdf0e10cSrcweir             if( pdispparams->cArgs != 1)
1158cdf0e10cSrcweir                 return DISP_E_BADPARAMCOUNT;
1159cdf0e10cSrcweir             if (FAILED( arg.ChangeType( VT_BSTR, &pdispparams->rgvarg[0])))
1160cdf0e10cSrcweir                 return DISP_E_BADVARTYPE;
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir             //check if the provided name represents a valid type
1163cdf0e10cSrcweir             Type type;
1164cdf0e10cSrcweir             if (getType(arg.bstrVal, type) == false)
1165cdf0e10cSrcweir             {
1166cdf0e10cSrcweir                 writeExcepinfo(pexcepinfo,OUString(
1167cdf0e10cSrcweir                                    OUSTR("[automation bridge] A UNO type with the name ") +
1168cdf0e10cSrcweir                                    OUString(reinterpret_cast<const sal_Unicode*>(arg.bstrVal)) + OUSTR(" does not exist!")));
1169cdf0e10cSrcweir                 return DISP_E_EXCEPTION;
1170cdf0e10cSrcweir             }
1171cdf0e10cSrcweir 
1172cdf0e10cSrcweir             if (createUnoTypeWrapper(arg.bstrVal, pvarResult) == false)
1173cdf0e10cSrcweir             {
1174cdf0e10cSrcweir                 writeExcepinfo(pexcepinfo,OUSTR("[automation bridge] InterfaceOleWrapper_Impl::InvokeGeneral\n"
1175cdf0e10cSrcweir                                                 "Could not initialize UnoTypeWrapper object!"));
1176cdf0e10cSrcweir                 return DISP_E_EXCEPTION;
1177cdf0e10cSrcweir             }
1178cdf0e10cSrcweir         }
1179cdf0e10cSrcweir     }
1180cdf0e10cSrcweir     catch(BridgeRuntimeError & e)
1181cdf0e10cSrcweir     {
1182cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
1183cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1184cdf0e10cSrcweir     }
1185cdf0e10cSrcweir     catch(Exception & e)
1186cdf0e10cSrcweir     {
1187cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::InvokeGeneral : \n") +
1188cdf0e10cSrcweir                                 e.Message;
1189cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1190cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1191cdf0e10cSrcweir     }
1192cdf0e10cSrcweir     catch( ... )
1193cdf0e10cSrcweir  	{
1194cdf0e10cSrcweir         OUString message= OUSTR("InterfaceOleWrapper_Impl::InvokeGeneral : \n"
1195cdf0e10cSrcweir                                 "Unexpected exception");
1196cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1197cdf0e10cSrcweir  		ret = DISP_E_EXCEPTION;
1198cdf0e10cSrcweir  	}
1199cdf0e10cSrcweir 	return ret;
1200cdf0e10cSrcweir }
1201cdf0e10cSrcweir 
1202cdf0e10cSrcweir 
1203cdf0e10cSrcweir 
1204cdf0e10cSrcweir 
GetDispID(BSTR,DWORD,DISPID __RPC_FAR *)1205cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetDispID(BSTR /*bstrName*/, DWORD /*grfdex*/, DISPID __RPC_FAR* /*pid*/)
1206cdf0e10cSrcweir {
1207cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1208cdf0e10cSrcweir 
1209cdf0e10cSrcweir 	return ret;
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir 
InvokeEx(DISPID,LCID,WORD,DISPPARAMS __RPC_FAR *,VARIANT __RPC_FAR *,EXCEPINFO __RPC_FAR *,IServiceProvider __RPC_FAR *)1212cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::InvokeEx(
1213cdf0e10cSrcweir 	/* [in] */ DISPID /*id*/,
1214cdf0e10cSrcweir 	/* [in] */ LCID /*lcid*/,
1215cdf0e10cSrcweir 	/* [in] */ WORD /*wFlags*/,
1216cdf0e10cSrcweir 	/* [in] */ DISPPARAMS __RPC_FAR* /*pdp*/,
1217cdf0e10cSrcweir 	/* [out] */ VARIANT __RPC_FAR* /*pvarRes*/,
1218cdf0e10cSrcweir 	/* [out] */ EXCEPINFO __RPC_FAR* /*pei*/,
1219cdf0e10cSrcweir 	/* [unique][in] */ IServiceProvider __RPC_FAR* /*pspCaller*/)
1220cdf0e10cSrcweir {
1221cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1222cdf0e10cSrcweir 
1223cdf0e10cSrcweir 	return ret;
1224cdf0e10cSrcweir }
1225cdf0e10cSrcweir 
1226cdf0e10cSrcweir 
DeleteMemberByName(BSTR,DWORD)1227cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::DeleteMemberByName(
1228cdf0e10cSrcweir     /* [in] */ BSTR /*bstr*/,
1229cdf0e10cSrcweir     /* [in] */ DWORD /*grfdex*/)
1230cdf0e10cSrcweir {
1231cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1232cdf0e10cSrcweir 
1233cdf0e10cSrcweir 	return ret;
1234cdf0e10cSrcweir }
1235cdf0e10cSrcweir 
DeleteMemberByDispID(DISPID)1236cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::DeleteMemberByDispID(DISPID /*id*/)
1237cdf0e10cSrcweir {
1238cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir 	return ret;
1241cdf0e10cSrcweir }
1242cdf0e10cSrcweir 
GetMemberProperties(DISPID,DWORD,DWORD __RPC_FAR *)1243cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetMemberProperties(
1244cdf0e10cSrcweir     /* [in] */ DISPID /*id*/,
1245cdf0e10cSrcweir     /* [in] */ DWORD /*grfdexFetch*/,
1246cdf0e10cSrcweir     /* [out] */ DWORD __RPC_FAR* /*pgrfdex*/)
1247cdf0e10cSrcweir {
1248cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir 	return ret;
1251cdf0e10cSrcweir }
1252cdf0e10cSrcweir 
GetMemberName(DISPID,BSTR __RPC_FAR *)1253cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetMemberName(
1254cdf0e10cSrcweir     /* [in] */ DISPID /*id*/,
1255cdf0e10cSrcweir     /* [out] */ BSTR __RPC_FAR* /*pbstrName*/)
1256cdf0e10cSrcweir {
1257cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1258cdf0e10cSrcweir 
1259cdf0e10cSrcweir 	return ret;
1260cdf0e10cSrcweir }
1261cdf0e10cSrcweir 
GetNextDispID(DWORD,DISPID,DISPID __RPC_FAR *)1262cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetNextDispID(
1263cdf0e10cSrcweir     /* [in] */ DWORD /*grfdex*/,
1264cdf0e10cSrcweir     /* [in] */ DISPID /*id*/,
1265cdf0e10cSrcweir     /* [out] */ DISPID __RPC_FAR* /*pid*/)
1266cdf0e10cSrcweir {
1267cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1268cdf0e10cSrcweir 
1269cdf0e10cSrcweir 	return ret;
1270cdf0e10cSrcweir }
1271cdf0e10cSrcweir 
GetNameSpaceParent(IUnknown __RPC_FAR * __RPC_FAR *)1272cdf0e10cSrcweir STDMETHODIMP InterfaceOleWrapper_Impl::GetNameSpaceParent(
1273cdf0e10cSrcweir     /* [out] */ IUnknown __RPC_FAR *__RPC_FAR* /*ppunk*/)
1274cdf0e10cSrcweir {
1275cdf0e10cSrcweir 	HRESULT ret = ResultFromScode(E_NOTIMPL);
1276cdf0e10cSrcweir 
1277cdf0e10cSrcweir 	return ret;
1278cdf0e10cSrcweir }
1279cdf0e10cSrcweir 
1280cdf0e10cSrcweir 
1281cdf0e10cSrcweir /*************************************************************************
1282cdf0e10cSrcweir 
1283cdf0e10cSrcweir 	UnoObjectWrapperRemoteOpt
1284cdf0e10cSrcweir 
1285cdf0e10cSrcweir *************************************************************************/
UnoObjectWrapperRemoteOpt(Reference<XMultiServiceFactory> & aFactory,sal_uInt8 unoWrapperClass,sal_uInt8 comWrapperClass)1286cdf0e10cSrcweir UnoObjectWrapperRemoteOpt::UnoObjectWrapperRemoteOpt( Reference<XMultiServiceFactory>& aFactory,
1287cdf0e10cSrcweir 													 sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass):
1288cdf0e10cSrcweir InterfaceOleWrapper_Impl( aFactory, unoWrapperClass, comWrapperClass),
1289cdf0e10cSrcweir m_currentId(1)
1290cdf0e10cSrcweir 
1291cdf0e10cSrcweir {
1292cdf0e10cSrcweir }
~UnoObjectWrapperRemoteOpt()1293cdf0e10cSrcweir UnoObjectWrapperRemoteOpt::~UnoObjectWrapperRemoteOpt()
1294cdf0e10cSrcweir {
1295cdf0e10cSrcweir }
1296cdf0e10cSrcweir 
1297cdf0e10cSrcweir // UnoConversionUtilities
createUnoWrapperInstance()1298cdf0e10cSrcweir Reference< XInterface > UnoObjectWrapperRemoteOpt::createUnoWrapperInstance()
1299cdf0e10cSrcweir {
1300cdf0e10cSrcweir 	Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
1301cdf0e10cSrcweir 												 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
1302cdf0e10cSrcweir 	return Reference<XInterface>( xWeak, UNO_QUERY);
1303cdf0e10cSrcweir }
1304cdf0e10cSrcweir 
GetIDsOfNames(REFIID,OLECHAR ** rgszNames,unsigned int cNames,LCID,DISPID * rgdispid)1305cdf0e10cSrcweir STDMETHODIMP  UnoObjectWrapperRemoteOpt::GetIDsOfNames ( REFIID /*riid*/, OLECHAR ** rgszNames, unsigned int cNames,
1306cdf0e10cSrcweir 								LCID /*lcid*/, DISPID * rgdispid )
1307cdf0e10cSrcweir {
1308cdf0e10cSrcweir 	MutexGuard guard( getBridgeMutex());
1309cdf0e10cSrcweir 
1310cdf0e10cSrcweir 	if( ! rgdispid)
1311cdf0e10cSrcweir 		return E_POINTER;
1312cdf0e10cSrcweir 	HRESULT ret = E_UNEXPECTED;
1313cdf0e10cSrcweir 	// ----------------------------------------
1314cdf0e10cSrcweir 	// _GetValueObject
1315cdf0e10cSrcweir 	if( ! wcscmp( *rgszNames, JSCRIPT_VALUE_FUNC))
1316cdf0e10cSrcweir 	{
1317cdf0e10cSrcweir 		*rgdispid= DISPID_JSCRIPT_VALUE_FUNC;
1318cdf0e10cSrcweir 		return S_OK;
1319cdf0e10cSrcweir 	}
1320cdf0e10cSrcweir 	else if( ! wcscmp( *rgszNames, GET_STRUCT_FUNC))
1321cdf0e10cSrcweir 	{
1322cdf0e10cSrcweir 		*rgdispid= DISPID_GET_STRUCT_FUNC;
1323cdf0e10cSrcweir 		return S_OK;
1324cdf0e10cSrcweir 	}
1325cdf0e10cSrcweir 
1326cdf0e10cSrcweir 	// ----------------------------------------
1327cdf0e10cSrcweir 	if (m_xInvocation.is() && (cNames > 0))
1328cdf0e10cSrcweir 	{
1329cdf0e10cSrcweir 		OUString name(reinterpret_cast<const sal_Unicode*>(rgszNames[0]));
1330cdf0e10cSrcweir 		// has this name been determined as "bad"
1331cdf0e10cSrcweir 		BadNameMap::iterator badIter= m_badNameMap.find( name);
1332cdf0e10cSrcweir 		if( badIter == m_badNameMap.end() )
1333cdf0e10cSrcweir 		{
1334cdf0e10cSrcweir 			// name has not been bad before( member exists
1335cdf0e10cSrcweir 			typedef NameToIdMap::iterator ITnames;
1336cdf0e10cSrcweir 			pair< ITnames, bool > pair_id= m_nameToDispIdMap.insert( NameToIdMap::value_type(name, m_currentId++));
1337cdf0e10cSrcweir 			// new ID inserted ?
1338cdf0e10cSrcweir 			if( pair_id.second )
1339cdf0e10cSrcweir 			{// yes, now create MemberInfo and ad to IdToMemberInfoMap
1340cdf0e10cSrcweir 				MemberInfo d(0, name);
1341cdf0e10cSrcweir 				m_idToMemberInfoMap.insert( IdToMemberInfoMap::value_type( m_currentId - 1, d));
1342cdf0e10cSrcweir 			}
1343cdf0e10cSrcweir 
1344cdf0e10cSrcweir 			*rgdispid = pair_id.first->second;
1345cdf0e10cSrcweir 			ret = S_OK;
1346cdf0e10cSrcweir 		}
1347cdf0e10cSrcweir 		else
1348cdf0e10cSrcweir 			ret= DISP_E_UNKNOWNNAME;
1349cdf0e10cSrcweir 	}
1350cdf0e10cSrcweir 	return ret;
1351cdf0e10cSrcweir }
1352cdf0e10cSrcweir 
Invoke(DISPID dispidMember,REFIID,LCID,unsigned short wFlags,DISPPARAMS * pdispparams,VARIANT * pvarResult,EXCEPINFO * pexcepinfo,unsigned int * puArgErr)1353cdf0e10cSrcweir STDMETHODIMP  UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID /*riid*/, LCID /*lcid*/, unsigned short wFlags,
1354cdf0e10cSrcweir 	                     DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
1355cdf0e10cSrcweir 	                     unsigned int * puArgErr )
1356cdf0e10cSrcweir {
1357cdf0e10cSrcweir 	HRESULT ret = S_OK;
1358cdf0e10cSrcweir     try
1359cdf0e10cSrcweir     {
1360cdf0e10cSrcweir         sal_Bool bHandled= sal_False;
1361cdf0e10cSrcweir         ret= InvokeGeneral( dispidMember,  wFlags, pdispparams, pvarResult,  pexcepinfo,
1362cdf0e10cSrcweir                             puArgErr, bHandled);
1363cdf0e10cSrcweir         if( bHandled)
1364cdf0e10cSrcweir             return ret;
1365cdf0e10cSrcweir 
1366cdf0e10cSrcweir         if ( dispidMember > 0  && m_xInvocation.is())
1367cdf0e10cSrcweir         {
1368cdf0e10cSrcweir 
1369cdf0e10cSrcweir             IdToMemberInfoMap::iterator it_MemberInfo= m_idToMemberInfoMap.find( dispidMember);
1370cdf0e10cSrcweir             if( it_MemberInfo != m_idToMemberInfoMap.end() )
1371cdf0e10cSrcweir             {
1372cdf0e10cSrcweir                 MemberInfo& info= it_MemberInfo->second;
1373cdf0e10cSrcweir 
1374cdf0e10cSrcweir                 Sequence<Any> params; // holds converted any s
1375cdf0e10cSrcweir                 if( ! info.flags )
1376cdf0e10cSrcweir                 { // DISPID called for the first time
1377cdf0e10cSrcweir                     if( wFlags == DISPATCH_METHOD )
1378cdf0e10cSrcweir                     {
1379cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1380cdf0e10cSrcweir 
1381cdf0e10cSrcweir                         if( FAILED( ret= doInvoke( pdispparams, pvarResult,
1382cdf0e10cSrcweir                                                    pexcepinfo, puArgErr, info.name, params))
1383cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1384cdf0e10cSrcweir                         {
1385cdf0e10cSrcweir                             // try to get the exact name
1386cdf0e10cSrcweir                             OUString exactName;
1387cdf0e10cSrcweir                             if (m_xExactName.is())
1388cdf0e10cSrcweir                             {
1389cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1390cdf0e10cSrcweir                                 // invoke again
1391cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1392cdf0e10cSrcweir                                 {
1393cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doInvoke( pdispparams, pvarResult,
1394cdf0e10cSrcweir                                                                   pexcepinfo, puArgErr, exactName, params)))
1395cdf0e10cSrcweir                                         info.name= exactName;
1396cdf0e10cSrcweir                                 }
1397cdf0e10cSrcweir                             }
1398cdf0e10cSrcweir                         }
1399cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1400cdf0e10cSrcweir                             info.flags= DISPATCH_METHOD;
1401cdf0e10cSrcweir                     } //if( wFlags == DISPATCH_METHOD )
1402cdf0e10cSrcweir 
1403cdf0e10cSrcweir                     else if( wFlags == DISPATCH_PROPERTYPUT || wFlags == DISPATCH_PROPERTYPUTREF)
1404cdf0e10cSrcweir                     {
1405cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1406cdf0e10cSrcweir                         if( FAILED( ret= doSetProperty( pdispparams, pvarResult,
1407cdf0e10cSrcweir                                                         pexcepinfo, puArgErr, info.name, params))
1408cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1409cdf0e10cSrcweir                         {
1410cdf0e10cSrcweir                             // try to get the exact name
1411cdf0e10cSrcweir                             OUString exactName;
1412cdf0e10cSrcweir                             if (m_xExactName.is())
1413cdf0e10cSrcweir                             {
1414cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1415cdf0e10cSrcweir                                 // invoke again
1416cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1417cdf0e10cSrcweir                                 {
1418cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doSetProperty( pdispparams, pvarResult,
1419cdf0e10cSrcweir                                                                        pexcepinfo, puArgErr, exactName, params)))
1420cdf0e10cSrcweir                                         info.name= exactName;
1421cdf0e10cSrcweir                                 }
1422cdf0e10cSrcweir                             }
1423cdf0e10cSrcweir                         }
1424cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1425cdf0e10cSrcweir                             info.flags= DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYGET;
1426cdf0e10cSrcweir                     }
1427cdf0e10cSrcweir 
1428cdf0e10cSrcweir                     else if( wFlags == DISPATCH_PROPERTYGET)
1429cdf0e10cSrcweir                     {
1430cdf0e10cSrcweir                         if( FAILED( ret= doGetProperty( pdispparams, pvarResult,
1431cdf0e10cSrcweir                                                         pexcepinfo, info.name))
1432cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1433cdf0e10cSrcweir                         {
1434cdf0e10cSrcweir                             // try to get the exact name
1435cdf0e10cSrcweir                             OUString exactName;
1436cdf0e10cSrcweir                             if (m_xExactName.is())
1437cdf0e10cSrcweir                             {
1438cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1439cdf0e10cSrcweir                                 // invoke again
1440cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1441cdf0e10cSrcweir                                 {
1442cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doGetProperty( pdispparams, pvarResult,
1443cdf0e10cSrcweir                                                                        pexcepinfo, exactName)))
1444cdf0e10cSrcweir                                         info.name= exactName;
1445cdf0e10cSrcweir                                 }
1446cdf0e10cSrcweir                             }
1447cdf0e10cSrcweir                         }
1448cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1449cdf0e10cSrcweir                             info.flags= DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT;
1450cdf0e10cSrcweir                     }
1451cdf0e10cSrcweir                     else if( wFlags & DISPATCH_METHOD &&
1452cdf0e10cSrcweir                              (wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF))
1453cdf0e10cSrcweir                     {
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir                         OUString exactName;
1456cdf0e10cSrcweir                         // convert params for DISPATCH_METHOD or DISPATCH_PROPERTYPUT
1457cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1458cdf0e10cSrcweir                         // try first as method
1459cdf0e10cSrcweir                         if( FAILED( ret= doInvoke( pdispparams, pvarResult,
1460cdf0e10cSrcweir                                                    pexcepinfo, puArgErr, info.name, params))
1461cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1462cdf0e10cSrcweir                         {
1463cdf0e10cSrcweir                             // try to get the exact name
1464cdf0e10cSrcweir                             if (m_xExactName.is())
1465cdf0e10cSrcweir                             {
1466cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1467cdf0e10cSrcweir                                 // invoke again
1468cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1469cdf0e10cSrcweir                                 {
1470cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doInvoke( pdispparams, pvarResult,
1471cdf0e10cSrcweir                                                                   pexcepinfo, puArgErr, exactName, params)))
1472cdf0e10cSrcweir                                         info.name= exactName;
1473cdf0e10cSrcweir                                 }
1474cdf0e10cSrcweir                             }
1475cdf0e10cSrcweir                         }
1476cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1477cdf0e10cSrcweir                             info.flags= DISPATCH_METHOD;
1478cdf0e10cSrcweir 
1479cdf0e10cSrcweir                         // try as property
1480cdf0e10cSrcweir 						if( FAILED( ret) && pdispparams->cArgs == 1)
1481cdf0e10cSrcweir 						{
1482cdf0e10cSrcweir 							if( FAILED( ret= doSetProperty( pdispparams, pvarResult,
1483cdf0e10cSrcweir                                                             pexcepinfo, puArgErr, info.name, params))
1484cdf0e10cSrcweir                                 && ret == DISP_E_MEMBERNOTFOUND)
1485cdf0e10cSrcweir 							{
1486cdf0e10cSrcweir 								// try to get the exact name
1487cdf0e10cSrcweir 								if( exactName.getLength() != 0)
1488cdf0e10cSrcweir 								{
1489cdf0e10cSrcweir 									if( SUCCEEDED( ret= doSetProperty( pdispparams, pvarResult,
1490cdf0e10cSrcweir                                                                        pexcepinfo, puArgErr, exactName, params)))
1491cdf0e10cSrcweir                                         info.name= exactName;
1492cdf0e10cSrcweir 								}
1493cdf0e10cSrcweir 							}
1494cdf0e10cSrcweir 							if( SUCCEEDED( ret ) )
1495cdf0e10cSrcweir 								info.flags= DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYGET;
1496cdf0e10cSrcweir 						}
1497cdf0e10cSrcweir                     }
1498cdf0e10cSrcweir                     else if( wFlags & DISPATCH_METHOD && wFlags & DISPATCH_PROPERTYGET)
1499cdf0e10cSrcweir                     {
1500cdf0e10cSrcweir                         OUString exactName;
1501cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1502cdf0e10cSrcweir 
1503cdf0e10cSrcweir                         if( FAILED( ret= doInvoke( pdispparams, pvarResult,
1504cdf0e10cSrcweir                                                    pexcepinfo, puArgErr, info.name, params))
1505cdf0e10cSrcweir                             && ret == DISP_E_MEMBERNOTFOUND)
1506cdf0e10cSrcweir                         {
1507cdf0e10cSrcweir                             // try to get the exact name
1508cdf0e10cSrcweir                             if (m_xExactName.is())
1509cdf0e10cSrcweir                             {
1510cdf0e10cSrcweir                                 exactName = m_xExactName->getExactName( info.name);
1511cdf0e10cSrcweir                                 // invoke again
1512cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1513cdf0e10cSrcweir                                 {
1514cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doInvoke( pdispparams, pvarResult,
1515cdf0e10cSrcweir                                                                   pexcepinfo, puArgErr, exactName, params)))
1516cdf0e10cSrcweir                                         info.name= exactName;
1517cdf0e10cSrcweir                                 }
1518cdf0e10cSrcweir                             }
1519cdf0e10cSrcweir                         }
1520cdf0e10cSrcweir                         if( SUCCEEDED( ret ) )
1521cdf0e10cSrcweir                             info.flags= DISPATCH_METHOD;
1522cdf0e10cSrcweir 
1523cdf0e10cSrcweir                         // try as property
1524cdf0e10cSrcweir                         if( FAILED( ret) && pdispparams->cArgs == 1)
1525cdf0e10cSrcweir                         {
1526cdf0e10cSrcweir                             if( FAILED( ret= doGetProperty( pdispparams, pvarResult,
1527cdf0e10cSrcweir                                                             pexcepinfo, info.name))
1528cdf0e10cSrcweir                                 && ret == DISP_E_MEMBERNOTFOUND)
1529cdf0e10cSrcweir                             {
1530cdf0e10cSrcweir                                 if( exactName.getLength() != 0)
1531cdf0e10cSrcweir                                 {
1532cdf0e10cSrcweir                                     if( SUCCEEDED( ret= doSetProperty( pdispparams, pvarResult,
1533cdf0e10cSrcweir                                                                        pexcepinfo, puArgErr, exactName, params)))
1534cdf0e10cSrcweir                                         info.name= exactName;
1535cdf0e10cSrcweir                                 }
1536cdf0e10cSrcweir                             }
1537cdf0e10cSrcweir                             if( SUCCEEDED( ret ) )
1538cdf0e10cSrcweir                                 info.flags= DISPATCH_PROPERTYGET;
1539cdf0e10cSrcweir                         }
1540cdf0e10cSrcweir                     }
1541cdf0e10cSrcweir 
1542cdf0e10cSrcweir                     // update �nformation about this member
1543cdf0e10cSrcweir                     if( ret == DISP_E_MEMBERNOTFOUND)
1544cdf0e10cSrcweir                     {
1545cdf0e10cSrcweir                         // Remember the name as not existing
1546cdf0e10cSrcweir                         // and remove the MemberInfo
1547cdf0e10cSrcweir                         m_badNameMap[info.name]= sal_False;
1548cdf0e10cSrcweir                         m_idToMemberInfoMap.erase( it_MemberInfo);
1549cdf0e10cSrcweir                     }
1550cdf0e10cSrcweir                 } // if( ! info.flags )
1551cdf0e10cSrcweir                 else // IdToMemberInfoMap contains a MemberInfo
1552cdf0e10cSrcweir                 {
1553cdf0e10cSrcweir                     if( wFlags & DISPATCH_METHOD && info.flags == DISPATCH_METHOD)
1554cdf0e10cSrcweir                     {
1555cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1556cdf0e10cSrcweir 						ret= doInvoke( pdispparams, pvarResult,
1557cdf0e10cSrcweir                                        pexcepinfo, puArgErr, info.name, params);
1558cdf0e10cSrcweir                     }
1559cdf0e10cSrcweir                     else if( (wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF )  &&
1560cdf0e10cSrcweir                              info.flags & DISPATCH_PROPERTYPUT)
1561cdf0e10cSrcweir                     {
1562cdf0e10cSrcweir                         convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
1563cdf0e10cSrcweir                         ret= doSetProperty( pdispparams, pvarResult,
1564cdf0e10cSrcweir                                             pexcepinfo, puArgErr, info.name, params);
1565cdf0e10cSrcweir                     }
1566cdf0e10cSrcweir                     else if( (wFlags & DISPATCH_PROPERTYGET) && ( info.flags & DISPATCH_PROPERTYGET))
1567cdf0e10cSrcweir                     {
1568cdf0e10cSrcweir                         ret= doGetProperty( pdispparams, pvarResult,
1569cdf0e10cSrcweir                                             pexcepinfo, info.name);
1570cdf0e10cSrcweir                     }
1571cdf0e10cSrcweir                     else
1572cdf0e10cSrcweir                     {
1573cdf0e10cSrcweir                         ret= DISP_E_MEMBERNOTFOUND;
1574cdf0e10cSrcweir                     }
1575cdf0e10cSrcweir                 }
1576cdf0e10cSrcweir             }//		if( it_MemberInfo != m_idToMemberInfoMap.end() )
1577cdf0e10cSrcweir             else
1578cdf0e10cSrcweir                 ret= DISP_E_MEMBERNOTFOUND;
1579cdf0e10cSrcweir         }
1580cdf0e10cSrcweir     }
1581cdf0e10cSrcweir     catch(BridgeRuntimeError& e)
1582cdf0e10cSrcweir     {
1583cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, e.message);
1584cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1585cdf0e10cSrcweir     }
1586cdf0e10cSrcweir     catch(Exception& e)
1587cdf0e10cSrcweir     {
1588cdf0e10cSrcweir         OUString message= OUSTR("UnoObjectWrapperRemoteOpt::Invoke : \n") +
1589cdf0e10cSrcweir             e.Message;
1590cdf0e10cSrcweir             writeExcepinfo(pexcepinfo, message);
1591cdf0e10cSrcweir             ret = DISP_E_EXCEPTION;
1592cdf0e10cSrcweir     }
1593cdf0e10cSrcweir     catch(...)
1594cdf0e10cSrcweir     {
1595cdf0e10cSrcweir         OUString message= OUSTR("UnoObjectWrapperRemoteOpt::Invoke : \n"
1596cdf0e10cSrcweir                                 "Unexpected exception");
1597cdf0e10cSrcweir         writeExcepinfo(pexcepinfo, message);
1598cdf0e10cSrcweir         ret = DISP_E_EXCEPTION;
1599cdf0e10cSrcweir     }
1600cdf0e10cSrcweir 
1601cdf0e10cSrcweir     return ret;
1602cdf0e10cSrcweir }
1603cdf0e10cSrcweir 
methodInvoke(DISPID,DISPPARAMS *,VARIANT *,EXCEPINFO *,unsigned int *,Sequence<Any> params)1604cdf0e10cSrcweir HRESULT	UnoObjectWrapperRemoteOpt::methodInvoke( DISPID /*dispidMember*/, DISPPARAMS * /*pdispparams*/, VARIANT * /*pvarResult*/,
1605cdf0e10cSrcweir 							  EXCEPINFO * /*pexcepinfo*/, unsigned int * /*puArgErr*/, Sequence<Any> params)
1606cdf0e10cSrcweir {
1607cdf0e10cSrcweir 	return S_OK;
1608cdf0e10cSrcweir }
1609cdf0e10cSrcweir 
1610cdf0e10cSrcweir 
1611cdf0e10cSrcweir // The returned HRESULT is only appropriate for IDispatch::Invoke
mapCannotConvertException(CannotConvertException e,unsigned int * puArgErr)1612cdf0e10cSrcweir static HRESULT mapCannotConvertException( CannotConvertException e, unsigned int * puArgErr)
1613cdf0e10cSrcweir {
1614cdf0e10cSrcweir 	HRESULT ret;
1615cdf0e10cSrcweir 	sal_Bool bWriteIndex= sal_True;
1616cdf0e10cSrcweir 
1617cdf0e10cSrcweir 	switch ( e.Reason)
1618cdf0e10cSrcweir 	{
1619cdf0e10cSrcweir 		case FailReason::OUT_OF_RANGE:
1620cdf0e10cSrcweir 			ret = DISP_E_OVERFLOW;
1621cdf0e10cSrcweir 			break;
1622cdf0e10cSrcweir 		case FailReason::IS_NOT_NUMBER:
1623cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1624cdf0e10cSrcweir 			break;
1625cdf0e10cSrcweir 		case FailReason::IS_NOT_ENUM:
1626cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1627cdf0e10cSrcweir 			break;
1628cdf0e10cSrcweir 		case FailReason::IS_NOT_BOOL:
1629cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1630cdf0e10cSrcweir 			break;
1631cdf0e10cSrcweir 		case FailReason::NO_SUCH_INTERFACE:
1632cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1633cdf0e10cSrcweir 			break;
1634cdf0e10cSrcweir 		case FailReason::SOURCE_IS_NO_DERIVED_TYPE:
1635cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1636cdf0e10cSrcweir 			break;
1637cdf0e10cSrcweir 		case FailReason::TYPE_NOT_SUPPORTED:
1638cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1639cdf0e10cSrcweir 			break;
1640cdf0e10cSrcweir 		case FailReason::INVALID:
1641cdf0e10cSrcweir 			ret = DISP_E_TYPEMISMATCH;
1642cdf0e10cSrcweir 			break;
1643cdf0e10cSrcweir 		case FailReason::NO_DEFAULT_AVAILABLE:
1644cdf0e10cSrcweir 			ret = DISP_E_BADPARAMCOUNT;
1645cdf0e10cSrcweir 			break;
1646cdf0e10cSrcweir 		case FailReason::UNKNOWN:
1647cdf0e10cSrcweir 			ret = E_UNEXPECTED;
1648cdf0e10cSrcweir 			break;
1649cdf0e10cSrcweir 		default:
1650cdf0e10cSrcweir 			ret = E_UNEXPECTED;
1651cdf0e10cSrcweir 			bWriteIndex= sal_False;
1652cdf0e10cSrcweir 			break;
1653cdf0e10cSrcweir 	}
1654cdf0e10cSrcweir 
1655cdf0e10cSrcweir 	if( bWriteIndex &&  puArgErr != NULL)
1656cdf0e10cSrcweir 		*puArgErr = e.ArgumentIndex;
1657cdf0e10cSrcweir 	return ret;
1658cdf0e10cSrcweir }
1659cdf0e10cSrcweir 
1660cdf0e10cSrcweir // The function maps the TypeClass of the any to VARTYPE: If
1661cdf0e10cSrcweir // the Any contains STRUCT or INTERFACE then the return value
1662cdf0e10cSrcweir // is VT_DISPATCH. The function is used from o2u_createUnoObjectWrapper
1663cdf0e10cSrcweir // and the result is put into the constructor of the uno - wrapper
1664cdf0e10cSrcweir // object. If a client asks the object for DISPID_VALUE and this
1665*07a3d7f1SPedro Giffuni // function returned VT_DISPATCH then the IDispatch of the same
1666cdf0e10cSrcweir // object is being returned.
1667cdf0e10cSrcweir // See InterfaceOleWrapper_Impl::Invoke, InterfaceOleWrapper_Impl::m_defaultValueType
getVarType(const Any & value)1668cdf0e10cSrcweir const VARTYPE getVarType( const Any& value)
1669cdf0e10cSrcweir {
1670cdf0e10cSrcweir 	VARTYPE ret= VT_EMPTY;
1671cdf0e10cSrcweir 
1672cdf0e10cSrcweir 	switch ( value.getValueTypeClass())
1673cdf0e10cSrcweir 	{
1674cdf0e10cSrcweir 	case TypeClass_STRUCT: ret= VT_DISPATCH; break;
1675cdf0e10cSrcweir 	case TypeClass_INTERFACE: ret= VT_DISPATCH; break;
1676cdf0e10cSrcweir 	default: break;
1677cdf0e10cSrcweir 	}
1678cdf0e10cSrcweir 	return ret;
1679cdf0e10cSrcweir }
1680cdf0e10cSrcweir 
1681cdf0e10cSrcweir 
1682cdf0e10cSrcweir 
1683cdf0e10cSrcweir 
1684cdf0e10cSrcweir } // end namespace
1685