1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_EXTENSIONS_SOURCE_OLE_OLEOBJW_HXX
21 #define INCLUDED_EXTENSIONS_SOURCE_OLE_OLEOBJW_HXX
23 #include "ole2uno.hxx"
24 #include "wincrap.hxx"
26 #include <unordered_map>
29 #include <cppuhelper/implbase.hxx>
31 #include <com/sun/star/lang/XInitialization.hpp>
32 #include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>
33 #include <com/sun/star/script/XAutomationInvocation.hpp>
34 #include <rtl/ustring.hxx>
36 #include <com/sun/star/script/XDefaultProperty.hpp>
37 #include <com/sun/star/script/XDefaultMethod.hpp>
38 #include <com/sun/star/script/XDirectInvocation.hpp>
40 #include <typelib/typedescription.hxx>
41 #include "unoconversionutilities.hxx"
42 #include "windata.hxx"
45 using namespace com::sun::star::lang
;
46 using namespace com::sun::star::bridge
;
47 using namespace com::sun::star::bridge::oleautomation
;
49 typedef std::unordered_map
<OUString
, pair
<DISPID
, unsigned short>> DispIdMap
;
51 typedef std::unordered_multimap
<OUString
, unsigned int> TLBFuncIndexMap
;
53 // This class wraps an IDispatch and maps XInvocation calls to IDispatch calls on the wrapped object.
54 // If m_TypeDescription is set then this class represents a UNO interface implemented in a COM component.
55 // The interface is not a real interface in terms of an abstract class but is realized through IDispatch.
56 class IUnknownWrapper
: public WeakImplHelper
< XBridgeSupplier2
, XInitialization
, XAutomationObject
, XDefaultProperty
, XDefaultMethod
, XDirectInvocation
, XAutomationInvocation
>,
58 public UnoConversionUtilities
<IUnknownWrapper
>
62 IUnknownWrapper(Reference
<XMultiServiceFactory
> const &xFactory
,
63 sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
);
65 ~IUnknownWrapper() override
;
68 Any SAL_CALL
queryInterface(const Type
& t
) override
;
71 virtual Reference
< XIntrospectionAccess
> SAL_CALL
getIntrospection( ) override
;
72 virtual Any SAL_CALL
invoke( const OUString
& aFunctionName
,
73 const Sequence
< Any
>& aParams
,
74 Sequence
< sal_Int16
>& aOutParamIndex
,
75 Sequence
< Any
>& aOutParam
) override
;
76 virtual void SAL_CALL
setValue( const OUString
& aPropertyName
,
77 const Any
& aValue
) override
;
78 virtual Any SAL_CALL
getValue( const OUString
& aPropertyName
) override
;
79 virtual sal_Bool SAL_CALL
hasMethod( const OUString
& aName
) override
;
80 virtual sal_Bool SAL_CALL
hasProperty( const OUString
& aName
) override
;
83 // This interface is implemented to provide a safe way to obtain the original
84 // IUnknown or IDispatch within the function anyToVariant. The function asks
85 // every UNO object for its XBridgeSupplier2 and if it is available uses it to convert
86 // the object with its own supplier.
87 virtual Any SAL_CALL
createBridge( const Any
& modelDepObject
,
88 const Sequence
< sal_Int8
>& aProcessId
,
89 sal_Int16 sourceModelType
,
90 sal_Int16 destModelType
) override
;
93 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
) override
;
96 virtual OUString SAL_CALL
getDefaultPropertyName( ) override
{ return m_sDefaultMember
; }
99 virtual OUString SAL_CALL
getDefaultMethodName( ) override
{ return m_sDefaultMember
; }
101 virtual css::uno::Any SAL_CALL
invokeGetProperty( const OUString
& aFunctionName
, const css::uno::Sequence
< css::uno::Any
>& aParams
, css::uno::Sequence
< ::sal_Int16
>& aOutParamIndex
, css::uno::Sequence
< css::uno::Any
>& aOutParam
) override
;
102 virtual css::uno::Any SAL_CALL
invokePutProperty( const OUString
& aFunctionName
, const css::uno::Sequence
< css::uno::Any
>& aParams
, css::uno::Sequence
< ::sal_Int16
>& aOutParamIndex
, css::uno::Sequence
< css::uno::Any
>& aOutParam
) override
;
105 virtual css::uno::Any SAL_CALL
directInvoke( const OUString
& aName
, const css::uno::Sequence
< css::uno::Any
>& aParams
) override
;
106 virtual sal_Bool SAL_CALL
hasMember( const OUString
& aName
) override
;
109 Any
invokeWithDispIdComTlb(FuncDesc
& aFuncDesc
,
110 const OUString
& sFuncName
,
111 const Sequence
< Any
>& Params
,
112 Sequence
< sal_Int16
>& OutParamIndex
,
113 Sequence
< Any
>& OutParam
);
118 virtual Any
invokeWithDispIdUnoTlb(const OUString
& sFunctionName
,
119 const Sequence
< Any
>& Params
,
120 Sequence
<sal_Int16
>& OutParamIndex
,
121 Sequence
< Any
>& OutParam
);
122 // Is used for OleObjectFactory service
123 virtual Any
invokeWithDispIdComTlb(const OUString
& sFuncName
,
124 const Sequence
< Any
>& Params
,
125 Sequence
< sal_Int16
>& OutParamIndex
,
126 Sequence
< Any
>& OutParam
);
128 // UnoConversionUtilities -------------------------------------------------------------------------------
129 virtual Reference
<XInterface
> createUnoWrapperInstance() override
;
130 virtual Reference
<XInterface
> createComWrapperInstance() override
;
132 /**Obtains a FUNCDESC structure for a function.
133 Fills the FUNCDESC structure if ITypeInfo provides information for
134 the function of name sFuncName or pFuncDesc will not be filled in.
135 May throw a BridgeRuntimeError.
137 void getFuncDesc(const OUString
& sFuncName
, FUNCDESC
** pFuncDesc
);
138 /**Obtains a FUNCDESC structures or a VARDESC structure
139 for a property. pFuncDescPut may also contain
140 a structure for a "propertyputref" operation. If pFuncDesc contains a
141 "put ref" or "put" FUNCDESC depends on what was found first in the type
143 Fills the FUNCDESC structure if ITypeInfo provides information for
144 the respective property functions or the structures will not be filled in.
145 May throw a BridgeRuntimeError.
147 void getPropDesc(const OUString
& sFuncName
, FUNCDESC
** pFuncDescGet
,
148 FUNCDESC
** pFuncDescPut
, VARDESC
** pVarDesc
);
149 // These functions are for the case if an object of this class wraps an IDispatch
150 // object that implements UNO interfaces. In that case the member m_seqTypes
151 // is set through XInitialization::initialize.
152 void getMethodInfo(const OUString
& sName
, TypeDescription
& methodDescription
);
153 // After return attributInfo contains typelib_InterfaceAttributeTypeDescription::pAttributeTypeRef
154 void getAttributeInfo(const OUString
& sName
, TypeDescription
& attributeInfo
);
155 // used by get MethodInfo
156 TypeDescription
getInterfaceMemberDescOfCurrentCall(const OUString
& sName
);
157 /** Returns always a valid ITypeInfo interface or throws a BridgeRuntimeError.
158 The returned interface does not need to be AddRef'ed as long as it is locally
159 used. The interface is kept in the instance of this class.
161 ITypeInfo
* getTypeInfo();
163 /** Returns the DISPID for a function or property name. If true is returned then
164 id contains a valid DISPID.
167 bool getDispid(const OUString
& sFuncName
, DISPID
* id
);
169 VARTYPE
getUserDefinedElementType( ITypeInfo
* pTypeInfo
, const DWORD nHrefType
);
171 /** Gets the element type in a VARIANT like style. E.g. if desc->lptdesc contains
172 a VT_PTR than it is replaced by VT_BYREF and VT_SAFEARRAY is replaced by VT_ARRAY
173 If the TYPEDESC describes an SAFEARRAY then varType is a combination of VT_ARRAY
174 and the element type.
175 The argument desc must be obtained from FUNCDESC::lprgelemdescParam[i].tdesc where
176 FUNCDESC was obtained from the ITypeInfo belonging to wrapped IDispatch.
178 VARTYPE
getElementTypeDesc( const TYPEDESC
*desc
);
179 /** Iterates over all functions and put the names and indices into the map
180 m_mapComFunc of type TLBFuncIndexMap.
181 Call the function every time before accessing the map.
182 Throws a BridgeRuntimeError on failure.
184 void buildComTlbIndex();
186 /** Returns a FUNCDESC structure which contains type information about the
187 current XInvocation::invoke call. The FUNCDESC either describes a method,
188 a property put or a property get operation.
189 It uses the types com.sun.star.bridge.oleautomation.PropertyPutArgument
191 contained in the sequence of in-arguments of invoke to determine if the call is
192 a property put or property get operation.
193 If no adequate FUNCDESC was found, an IllegalArgumentException is thrown.
194 Therefore it is safe to assume that the returned FUNCDESC* is not NULL.
196 @exception IllegalArgumentException
197 Thrown if no adequate FUNCDESC could be found.
199 void getFuncDescForInvoke(const OUString
& sFuncName
,
200 const Sequence
<Any
> & seqArgs
, FUNCDESC
** pFuncDesc
);
202 // Finds out whether the wrapped IDispatch is a JScript Object. This is
204 // asking for the property "_environment". If it has the value "JScript"
205 // (case insensitive) then the IDispatch is considered a JScript object.
206 bool isJScriptObject();
209 // If UNO interfaces are implemented in JScript objects, VB or C++ COM objects
210 // and those are passed as parameter to a UNO interface function, then
211 // the IDispatch* are wrapped by objects of this class. Assuming that the functions
212 // implemented by the IDispatch object returns another UNO interface then
213 // it has to be wrapped to this type. But this is only possible if an object of this
214 // wrapper class knows what type it is represting. The member m_TypeDescription holds this
216 // m_TypeDescription is only useful when an object wraps an IDispatch object that implements
217 // a UNO interface. The value is set during a call to XInitialization::initialize.
218 Sequence
<Type
> m_seqTypes
;
219 CComPtr
<IUnknown
> m_spUnknown
;
220 CComPtr
<IDispatch
> m_spDispatch
;
221 OUString m_sTypeName
; // is "" ( not initialised ), "IDispatch" ( we have no idea ) or "SomeLibrary.SomeTypeName" if we managed to get a type
222 /** This value is set during XInitialization::initialize. It indicates that the COM interface
223 was transported as VT_DISPATCH in a VARIANT rather than a VT_UNKNOWN
225 bool m_bOriginalDispatch
;
226 DispIdMap m_dispIdMap
;
227 Reference
<XIdlClass
>* m_pxIdlClass
;
230 // used by isJScriptObject
231 enum JScriptDetermination
{ JScriptUndefined
=0, NoJScript
, IsJScript
};
232 JScriptDetermination m_eJScript
;
233 // The map is filled by buildComTlbIndex
234 // It maps Uno Function names to an index which is used in ITypeInfo::GetFuncDesc
235 TLBFuncIndexMap m_mapComFunc
;
236 // used for synchronizing the computation of the content for m_mapComFunc
237 bool m_bComTlbIndexInit
;
238 // Keeps the ITypeInfo obtained from IDispatch::GetTypeInfo
239 CComPtr
< ITypeInfo
> m_spTypeInfo
;
240 OUString m_sDefaultMember
;
241 bool m_bHasDfltMethod
;
242 bool m_bHasDfltProperty
;
247 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */