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 .
22 #include <com/sun/star/bridge/XBridgeSupplier2.hpp>
23 #include <com/sun/star/beans/XExactName.hpp>
24 #include <com/sun/star/lang/XInitialization.hpp>
25 #include <com/sun/star/script/InvocationInfo.hpp>
26 #include <salhelper/simplereferenceobject.hxx>
27 #include <cppuhelper/implbase.hxx>
29 #include "comifaces.hxx"
30 #include "ole2uno.hxx"
31 #include "unoconversionutilities.hxx"
33 #define JSCRIPT_VALUE_FUNC L"_GetValueObject"
34 #define GET_STRUCT_FUNC L"_GetStruct"
35 #define BRIDGE_VALUE_FUNC L"Bridge_GetValueObject"
36 #define BRIDGE_GET_STRUCT_FUNC L"Bridge_GetStruct"
37 #define BRIDGE_CREATE_TYPE_FUNC L"Bridge_CreateType"
39 #define DISPID_JSCRIPT_VALUE_FUNC -10l
40 #define DISPID_GET_STRUCT_FUNC -102
41 #define DISPID_CREATE_TYPE_FUNC -103
44 using namespace com::sun::star::bridge
;
45 using namespace com::sun::star::script
;
49 MemberInfo() : flags(0), name() {}
50 MemberInfo(WORD f
, const OUString
& n
) : flags(f
), name(n
) {}
56 typedef std::unordered_map
62 typedef std::unordered_map
68 typedef std::unordered_map
74 // An InterfaceOleWrapper object can wrap either a UNO struct or a UNO
75 // interface as a COM IDispatchEx and IUnoObjectWrapper.
77 class InterfaceOleWrapper
: public WeakImplHelper
<XBridgeSupplier2
, XInitialization
>,
79 public IProvideClassInfo
,
80 public IConnectionPointContainer
,
81 public UnoConversionUtilities
<InterfaceOleWrapper
>,
82 public IUnoObjectWrapper
85 InterfaceOleWrapper(Reference
<XMultiServiceFactory
> const & xFactory
, sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
);
86 ~InterfaceOleWrapper() override
;
89 STDMETHOD(QueryInterface
)(REFIID riid
, void ** ppvObj
) override
;
90 STDMETHOD_(ULONG
, AddRef
)() override
;
91 STDMETHOD_(ULONG
, Release
)() override
;
94 STDMETHOD( GetTypeInfoCount
)( UINT
* pctinfo
) override
;
95 STDMETHOD( GetTypeInfo
)( UINT itinfo
, LCID lcid
, ITypeInfo
** pptinfo
) override
;
96 STDMETHOD( GetIDsOfNames
)( REFIID riid
, LPOLESTR
* rgszNames
, UINT cNames
,
97 LCID lcid
, DISPID
* rgdispid
) override
;
98 STDMETHOD( Invoke
)( DISPID dispidMember
, REFIID riid
, LCID lcid
, WORD wFlags
,
99 DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
, EXCEPINFO
* pexcepinfo
,
100 UINT
* puArgErr
) override
;
103 virtual HRESULT STDMETHODCALLTYPE
GetDispID(
104 /* [in] */ BSTR bstrName
,
105 /* [in] */ DWORD grfdex
,
106 /* [out] */ DISPID __RPC_FAR
*pid
) override
;
108 virtual /* [local] */ HRESULT STDMETHODCALLTYPE
InvokeEx(
109 /* [in] */ DISPID id
,
110 /* [in] */ LCID lcid
,
111 /* [in] */ WORD wFlags
,
112 /* [in] */ DISPPARAMS __RPC_FAR
*pdp
,
113 /* [out] */ VARIANT __RPC_FAR
*pvarRes
,
114 /* [out] */ EXCEPINFO __RPC_FAR
*pei
,
115 /* [unique][in] */ IServiceProvider __RPC_FAR
*pspCaller
) override
;
117 virtual HRESULT STDMETHODCALLTYPE
DeleteMemberByName(
118 /* [in] */ BSTR bstr
,
119 /* [in] */ DWORD grfdex
) override
;
121 virtual HRESULT STDMETHODCALLTYPE
DeleteMemberByDispID(
122 /* [in] */ DISPID id
) override
;
124 virtual HRESULT STDMETHODCALLTYPE
GetMemberProperties(
125 /* [in] */ DISPID id
,
126 /* [in] */ DWORD grfdexFetch
,
127 /* [out] */ DWORD __RPC_FAR
*pgrfdex
) override
;
129 virtual HRESULT STDMETHODCALLTYPE
GetMemberName(
130 /* [in] */ DISPID id
,
131 /* [out] */ BSTR __RPC_FAR
*pbstrName
) override
;
133 virtual HRESULT STDMETHODCALLTYPE
GetNextDispID(
134 /* [in] */ DWORD grfdex
,
135 /* [in] */ DISPID id
,
136 /* [out] */ DISPID __RPC_FAR
*pid
) override
;
138 virtual HRESULT STDMETHODCALLTYPE
GetNameSpaceParent(
139 /* [out] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppunk
) override
;
142 virtual HRESULT STDMETHODCALLTYPE
GetClassInfo(
143 /* [out] */ ITypeInfo
**ppTI
) override
;
145 // IConnectionPointContainer
146 virtual HRESULT STDMETHODCALLTYPE
EnumConnectionPoints(
147 /* [out] */ IEnumConnectionPoints
**ppEnum
) override
;
148 virtual HRESULT STDMETHODCALLTYPE
FindConnectionPoint(
149 /* [in] */ REFIID riid
,
150 /* [out] */ IConnectionPoint
**ppCP
) override
;
153 virtual Any SAL_CALL
createBridge(const Any
& modelDepObject
,
154 const Sequence
<sal_Int8
>& ProcessId
,
155 sal_Int16 sourceModelType
,
156 sal_Int16 destModelType
) override
;
159 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
) override
;
162 STDMETHOD( getWrapperXInterface
)( Reference
<XInterface
>* pXInt
) override
;
163 STDMETHOD( getOriginalUnoObject
)( Reference
<XInterface
>* pXInt
) override
;
164 STDMETHOD( getOriginalUnoStruct
)( Any
* pStruct
) override
;
166 // UnoConversionUtility
167 virtual Reference
< XInterface
> createUnoWrapperInstance() override
;
168 virtual Reference
< XInterface
> createComWrapperInstance() override
;
170 const OUString
& getImplementationName() const
172 return m_sImplementationName
;
176 virtual HRESULT
doInvoke( DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
,
177 EXCEPINFO
* pexcepinfo
, unsigned int * puArgErr
, OUString
& name
, Sequence
<Any
>& params
);
179 virtual HRESULT
doGetProperty( DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
,
180 EXCEPINFO
* pexcepinfo
, OUString
& name
);
182 virtual HRESULT
doSetProperty( DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
,
183 EXCEPINFO
* pexcepinfo
, unsigned int * puArgErr
, OUString
& name
, Sequence
<Any
> const & params
);
185 virtual HRESULT
InvokeGeneral( DISPID dispidMember
, unsigned short wFlags
,
186 DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
, EXCEPINFO
* pexcepinfo
,
187 unsigned int * puArgErr
, bool& bHandled
);
189 void convertDispparamsArgs( DISPID id
, unsigned short wFlags
, DISPPARAMS
* pdispparams
,
190 Sequence
<Any
>& rSeq
);
192 bool getInvocationInfoForCall(DISPID id
, InvocationInfo
& info
);
194 Reference
<XInvocation
> m_xInvocation
;
195 Reference
<XExactName
> m_xExactName
;
196 Reference
<XInterface
> m_xOrigin
;
197 NameToIdMap m_nameToDispIdMap
;
198 std::vector
<MemberInfo
> m_MemberInfos
;
199 // This member is used to determine the default value
200 // denoted by DISPID_VALUE (0). For proper results in JavaScript
201 // we have to return the default value when we write an object
202 // as out parameter. That is, we get a JScript Array as parameter
203 // and put a wrapped object on index null. The array object tries
204 // to detect the default value. The wrapped object must then return
205 // its own IDispatch* otherwise we cannot access it within the script.
206 // see InterfaceOleWrapper::Invoke
207 VARTYPE m_defaultValueType
;
209 // The name of the implementation. Can be empty if unknown.
210 OUString m_sImplementationName
;
213 /*****************************************************************************
215 UnoObjectWrapperRemoteOpt = Uno Object Wrapper Remote Optimized
217 This is the UNO wrapper used in the service com.sun.star.bridge.OleBridgeSupplierVar1.
219 DISPIDs are passed out blindly. That is in GetIDsOfNames is no name checking carried out.
220 Only if Invoke fails the name is being checked. Moreover Invoke tries to figure out
221 if a call is made to a property or method if the flags are DISPATCH_METHOD | DISPATCH_PROPERTYPUT.
222 If something has been found out about a property or member than it is saved
223 in a MemberInfo structure hold by an IdToMemberInfoMap stl map.
225 *****************************************************************************/
226 class UnoObjectWrapperRemoteOpt
: public InterfaceOleWrapper
229 UnoObjectWrapperRemoteOpt( Reference
<XMultiServiceFactory
> const & aFactory
, sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
);
230 ~UnoObjectWrapperRemoteOpt() override
;
232 STDMETHOD( GetIDsOfNames
)( REFIID riid
, LPOLESTR
* rgszNames
, UINT cNames
,
233 LCID lcid
, DISPID
* rgdispid
) override
;
234 STDMETHOD( Invoke
)( DISPID dispidMember
, REFIID riid
, LCID lcid
, WORD wFlags
,
235 DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
, EXCEPINFO
* pexcepinfo
,
236 UINT
* puArgErr
) override
;
238 // UnoConversionUtility
239 // If UNO interfaces are converted in methods of this class then
240 // they are always wrapped with instances of this class
241 virtual Reference
< XInterface
> createUnoWrapperInstance() override
;
245 static HRESULT
methodInvoke( DISPID dispidMember
, DISPPARAMS
* pdispparams
, VARIANT
* pvarResult
,
246 EXCEPINFO
* pexcepinfo
, unsigned int * puArgErr
, Sequence
<Any
> const & params
);
247 // In GetIDsOfNames are blindly passed out, that is without verifying
248 // the name. If two names are passed in during different calls to
249 // GetIDsOfNames and the names differ only in their cases then different
250 // id's are passed out ( e.g. "doSomethingMethod" or "dosomethingmethod").
251 // In Invoke the DISPID is remapped to the name passed to GetIDsOfNames
252 // and the name is used as parameter for XInvocation::invoke. If invoke
253 // fails because of a wrong name, then m_xExactName ( XExactName) is used
254 // to verify the name. The correct name is then inserted to m_MemberInfos
255 // ( vector<MemberInfo> ). During the next call to Invoke the right name
259 BadNameMap m_badNameMap
;
261 IdToMemberInfoMap m_idToMemberInfoMap
;
268 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */