1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
30 #include "ole2uno.hxx"
33 #pragma warning (push,1)
34 #pragma warning (disable:4548)
37 #include <tools/presys.h>
38 #define _WIN32_WINNT 0x0400
40 #if defined(_MSC_VER) && (_MSC_VER >= 1300)
46 #include <tools/postsys.h>
51 #include <cppuhelper/implbase3.hxx>
52 #include <cppuhelper/implbase4.hxx>
53 #include <cppuhelper/implbase6.hxx>
55 #include <com/sun/star/lang/XInitialization.hpp>
56 #include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>
57 #include <rtl/ustring.hxx>
59 #include <com/sun/star/script/XDefaultProperty.hpp>
60 #include <com/sun/star/script/XDefaultMethod.hpp>
62 #include <typelib/typedescription.hxx>
63 #include "unoconversionutilities.hxx"
64 #include "windata.hxx"
68 using namespace com::sun::star::lang
;
69 using namespace com::sun::star::bridge
;
70 using namespace com::sun::star::bridge::oleautomation
;
77 typedef hash_map
<OUString
, pair
<DISPID
, unsigned short>, hashOUString_Impl
, equalOUString_Impl
> DispIdMap
;
79 typedef hash_multimap
<OUString
, unsigned int, hashOUString_Impl
, equalOUString_Impl
> TLBFuncIndexMap
;
81 // This class wraps an IDispatch and maps XInvocation calls to IDispatch calls on the wrapped object.
82 // If m_TypeDescription is set then this class represents an UNO interface implemented in a COM component.
83 // The interface is not a real interface in terms of an abstract class but is realized through IDispatch.
84 class IUnknownWrapper_Impl
: public WeakImplHelper6
<XInvocation
, XBridgeSupplier2
, XInitialization
, XAutomationObject
, XDefaultProperty
, XDefaultMethod
>,
86 public UnoConversionUtilities
<IUnknownWrapper_Impl
>
90 IUnknownWrapper_Impl(Reference
<XMultiServiceFactory
> &xFactory
,
91 sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
);
93 ~IUnknownWrapper_Impl();
96 Any SAL_CALL
queryInterface(const Type
& t
)
97 throw (RuntimeException
);
100 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection( )
101 throw(RuntimeException
);
102 virtual Any SAL_CALL
invoke( const OUString
& aFunctionName
,
103 const Sequence
< Any
>& aParams
,
104 Sequence
< sal_Int16
>& aOutParamIndex
,
105 Sequence
< Any
>& aOutParam
)
106 throw(IllegalArgumentException
, CannotConvertException
,
107 InvocationTargetException
, RuntimeException
);
108 virtual void SAL_CALL
setValue( const OUString
& aPropertyName
,
110 throw(UnknownPropertyException
, CannotConvertException
,
111 InvocationTargetException
, RuntimeException
);
112 virtual Any SAL_CALL
getValue( const OUString
& aPropertyName
)
113 throw(UnknownPropertyException
, RuntimeException
);
114 virtual sal_Bool SAL_CALL
hasMethod( const OUString
& aName
)
115 throw(RuntimeException
);
116 virtual sal_Bool SAL_CALL
hasProperty( const OUString
& aName
)
117 throw(RuntimeException
);
120 // This interface is implemented to provide a safe way to obtain the original
121 // IUnknown or IDispatch within the function anyToVariant. The function asks
122 // every UNO object for its XBridgeSupplier2 and if it is available uses it to convert
123 // the object with its own supplier.
124 virtual Any SAL_CALL
createBridge( const Any
& modelDepObject
,
125 const Sequence
< sal_Int8
>& aProcessId
,
126 sal_Int16 sourceModelType
,
127 sal_Int16 destModelType
)
128 throw(IllegalArgumentException
, RuntimeException
);
131 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
)
132 throw(Exception
, RuntimeException
);
133 virtual ::rtl::OUString SAL_CALL
getDefaultPropertyName( ) throw (::com::sun::star::uno::RuntimeException
) { return m_sDefaultMember
; }
135 virtual ::rtl::OUString SAL_CALL
getDefaultMethodName( ) throw (::com::sun::star::uno::RuntimeException
) { return m_sDefaultMember
; }
137 // ----------------------------------------------------------------------------
138 virtual Any
invokeWithDispIdUnoTlb(const OUString
& sFunctionName
,
139 const Sequence
< Any
>& Params
,
140 Sequence
<sal_Int16
>& OutParamIndex
,
141 Sequence
< Any
>& OutParam
);
142 // Is used for OleObjectFactory service
143 virtual Any
invokeWithDispIdComTlb(const OUString
& sFuncName
,
144 const Sequence
< Any
>& Params
,
145 Sequence
< sal_Int16
>& OutParamIndex
,
146 Sequence
< Any
>& OutParam
);
148 // virtual void setValueWithDispId(DISPID dispID, const Any& Value);
150 // virtual Any getValueWithDispId(const OUString& sName, DISPID dispID);
153 // UnoConversionUtilities -------------------------------------------------------------------------------
154 virtual Reference
<XInterface
> createUnoWrapperInstance();
155 virtual Reference
<XInterface
> createComWrapperInstance();
157 /**Obtains a FUNCDESC structure for a function.
158 Fills the FUNCDESC structure if ITypeInfo provides information for
159 the function of name sFuncName or pFuncDesc will not be filled in.
160 May throw a BridgeRuntimeError.
162 void getFuncDesc(const OUString
& sFuncName
, FUNCDESC
** pFuncDesc
);
163 /**Obtains a FUNCDESC structures or a VARDESC structure
164 for a property. pFuncDescPut may also contain
165 a structure for a "propertyputref" operation. If pFuncDesc contains a
166 "put ref" or "put" FUNCDESC depends on what was found first in the type
168 Fills the FUNCDESC structure if ITypeInfo provides information for
169 the respective property functions or the structures will not be filled in.
170 May throw a BridgeRuntimeError.
172 void getPropDesc(const OUString
& sFuncName
, FUNCDESC
** pFuncDescGet
,
173 FUNCDESC
** pFuncDescPut
, VARDESC
** pVarDesc
);
174 // These functions are for the case if an object of this class wraps an IDispatch
175 // object that implements UNO interfaces. In that case the member m_seqTypes
176 // is set through XInitialization::initialize.
177 void getMethodInfo(const OUString
& sName
, TypeDescription
& methodDescription
);
178 // After return attributInfo contains typelib_InterfaceAttributeTypeDescription::pAttributeTypeRef
179 void getAttributeInfo(const OUString
& sName
, TypeDescription
& attributeInfo
);
180 // used by get MethodInfo
181 TypeDescription
getInterfaceMemberDescOfCurrentCall(const OUString
& sName
);
182 /** Returns alway a valid ITypeInfo interface or throws a BridgeRuntimeError.
183 The returned interface does not need to be AddRef'ed as long as it is locally
184 used. The interface is kept in the instance of this class.
186 ITypeInfo
* getTypeInfo();
188 /** Returns the DISPID for a function or property name. If true is returned then
189 id contains a valid DISPID.
191 bool getDispid(const OUString
& sFuncName
, DISPID
* id
);
193 /** Gets the element type in a VARIANT like style. E.g. if desc->lptdesc contains
194 a VT_PTR than it is replaced by VT_BYREF and VT_SAFEARRAY is replaced by VT_ARRAY
195 If the TYPEDESC describes an SAFEARRAY then varType is a combination of VT_ARRAY
196 and the element type.
197 The argument desc must be obtained from FUNCDESC::lprgelemdescParam[i].tdesc where
198 FUNCDESC was obtained from the ITypeInfo belonging to wrapped IDispatch.
200 VARTYPE
getElementTypeDesc( const TYPEDESC
*desc
);
201 /** Iterates over all functions and put the names and indices into the map
202 m_mapComFunc of type TLBFuncIndexMap.
203 Call the function every time before accessing the map.
204 Throws a BridgeRuntimeError on failure.
206 void buildComTlbIndex();
208 /** Returns a FUNCDESC structure which contains type information about the
209 current XInvocation::invoke call. The FUNCDESC either describes a method,
210 a property put or a property get operation.
211 It uses the types com.sun.star.bridge.oleautomation.PropertyPutArgument
213 contained in the sequence of in-arguments of invoke to determine if the call is
214 a property put or property get operation.
215 If no adequate FUNCDESC was found, an IllegalArgumentException is thrown.
216 Therefore it is safe to assume that the returned FUNCDESC* is not NULL.
218 @exception IllegalArgumentException
219 Thrown if no adequate FUNCDESC could be found.
221 void getFuncDescForInvoke(const OUString
& sFuncName
,
222 const Sequence
<Any
> & seqArgs
, FUNCDESC
** pFuncDesc
);
224 // Finds out wheter the wrapped IDispatch is an JScript Object. This is is
226 // asking for the property "_environment". If it has the value "JScript"
227 // (case insensitive) then the IDispatch is considered a JScript object.
228 sal_Bool
isJScriptObject();
229 // -------------------------------------------------------------------------------
231 // If UNO interfaces are implemented in JScript objects, VB or C++ COM objects
232 // and those are passed as parameter to a UNO interface function, then
233 // the IDispatch* are wrapped by objects of this class. Assuming that the functions
234 // implemented by the IDispatch object returns another UNO interface then
235 // it has to be wrapped to this type. But this is only possible if an object of this
236 // wrapper class knows what type it is represting. The member m_TypeDescription holds this
238 // m_TypeDescription is only useful when an object wraps an IDispatch object that implements
239 // an UNO interface. The value is set during a call to XInitialization::initialize.
240 Sequence
<Type
> m_seqTypes
;
241 CComPtr
<IUnknown
> m_spUnknown
;
242 CComPtr
<IDispatch
> m_spDispatch
;
243 rtl::OUString m_sTypeName
; // is "" ( not initialised ), "IDispatch" ( we have no idea ) or "SomeLibrary.SomeTypeName" if we managed to get a type
244 /** This value is set dureing XInitialization::initialize. It indicates that the COM interface
245 was transported as VT_DISPATCH in a VARIANT rather then a VT_UNKNOWN
247 sal_Bool m_bOriginalDispatch
;
248 DispIdMap m_dispIdMap
;
249 Reference
<XIdlClass
>* m_pxIdlClass
;
252 // used by isJScriptObject
253 enum JScriptDetermination
{ JScriptUndefined
=0, NoJScript
, IsJScript
};
254 JScriptDetermination m_eJScript
;
255 // The map is filled by buildComTlbIndex
256 // It maps Uno Function names to an index which is used in ITypeInfo::GetFuncDesc
257 TLBFuncIndexMap m_mapComFunc
;
258 // used for synchroizing the computation of the content for m_mapComFunc
259 bool m_bComTlbIndexInit
;
260 // Keeps the ITypeInfo obtained from IDispatch::GetTypeInfo
261 CComPtr
< ITypeInfo
> m_spTypeInfo
;
262 rtl::OUString m_sDefaultMember
;
263 bool m_bHasDfltMethod
;
264 bool m_bHasDfltProperty
;