1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef _UNOOBJW_HXX 25 #define _UNOOBJW_HXX 26 27 #include <com/sun/star/bridge/XBridgeSupplier2.hpp> 28 #include <com/sun/star/beans/XExactName.hpp> 29 #include <com/sun/star/lang/XInitialization.hpp> 30 #include <com/sun/star/script/InvocationInfo.hpp> 31 #include <vos/refernce.hxx> 32 33 #include <tools/presys.h> 34 #include "comifaces.hxx" 35 #include <tools/postsys.h> 36 37 #include "ole2uno.hxx" 38 #include "unoconversionutilities.hxx" 39 40 //#define INVOCATION_SERVICE L"com.sun.star.script.Invocation" 41 #define JSCRIPT_VALUE_FUNC L"_GetValueObject" 42 #define GET_STRUCT_FUNC L"_GetStruct" 43 #define BRIDGE_VALUE_FUNC L"Bridge_GetValueObject" 44 #define BRIDGE_GET_STRUCT_FUNC L"Bridge_GetStruct" 45 #define BRIDGE_CREATE_TYPE_FUNC L"Bridge_CreateType" 46 47 #define DISPID_JSCRIPT_VALUE_FUNC -10l 48 #define DISPID_GET_STRUCT_FUNC -102 49 #define DISPID_CREATE_TYPE_FUNC -103 50 51 using namespace std; 52 using namespace cppu; 53 using namespace com::sun::star::bridge; 54 using namespace com::sun::star::script; 55 namespace ole_adapter 56 { 57 58 59 60 struct hash_IUnknown_Impl 61 { operator ()ole_adapter::hash_IUnknown_Impl62 size_t operator()(const IUnknown* p) const 63 { 64 return (size_t)p; 65 } 66 }; 67 68 struct equal_to_IUnknown_Impl 69 { operator ()ole_adapter::equal_to_IUnknown_Impl70 bool operator()(const IUnknown* s1, const IUnknown* s2) const 71 { 72 return s1 == s2; 73 } 74 }; 75 76 77 78 struct MemberInfo 79 { MemberInfoole_adapter::MemberInfo80 MemberInfo() : flags(0), name() {} MemberInfoole_adapter::MemberInfo81 MemberInfo(WORD f, const OUString& n) : flags(f), name(n) {} 82 83 WORD flags; 84 OUString name; 85 }; 86 87 typedef hash_map 88 < 89 OUString, 90 DISPID, 91 hashOUString_Impl, 92 equalOUString_Impl 93 > NameToIdMap; 94 95 typedef hash_map 96 < 97 OUString, 98 sal_Bool, 99 hashOUString_Impl, 100 equalOUString_Impl 101 > BadNameMap; 102 103 typedef hash_map 104 < 105 DISPID, 106 MemberInfo 107 > IdToMemberInfoMap; 108 109 /***************************************************************************** 110 111 class declaration: InterfaceOleWrapper_Impl 112 113 *****************************************************************************/ 114 115 class InterfaceOleWrapper_Impl : public WeakImplHelper2<XBridgeSupplier2, XInitialization>, 116 public IDispatchEx, 117 public UnoConversionUtilities<InterfaceOleWrapper_Impl>, 118 public IUnoObjectWrapper 119 { 120 public: 121 122 123 InterfaceOleWrapper_Impl(Reference<XMultiServiceFactory>& xFactory, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass); 124 ~InterfaceOleWrapper_Impl(); 125 126 /* IUnknown methods */ 127 STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj); 128 STDMETHOD_(ULONG, AddRef)(); 129 STDMETHOD_(ULONG, Release)(); 130 131 /* IDispatch methods */ 132 STDMETHOD( GetTypeInfoCount )( unsigned int * pctinfo ); 133 STDMETHOD( GetTypeInfo )( unsigned int itinfo, LCID lcid, ITypeInfo ** pptinfo ); 134 STDMETHOD( GetIDsOfNames )( REFIID riid, OLECHAR ** rgszNames, unsigned int cNames, 135 LCID lcid, DISPID * rgdispid ); 136 STDMETHOD( Invoke )( DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags, 137 DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, 138 unsigned int * puArgErr ); 139 140 /* IDispatchEx methods */ 141 142 virtual HRESULT STDMETHODCALLTYPE GetDispID( 143 /* [in] */ BSTR bstrName, 144 /* [in] */ DWORD grfdex, 145 /* [out] */ DISPID __RPC_FAR *pid); 146 147 virtual /* [local] */ HRESULT STDMETHODCALLTYPE InvokeEx( 148 /* [in] */ DISPID id, 149 /* [in] */ LCID lcid, 150 /* [in] */ WORD wFlags, 151 /* [in] */ DISPPARAMS __RPC_FAR *pdp, 152 /* [out] */ VARIANT __RPC_FAR *pvarRes, 153 /* [out] */ EXCEPINFO __RPC_FAR *pei, 154 /* [unique][in] */ IServiceProvider __RPC_FAR *pspCaller); 155 156 virtual HRESULT STDMETHODCALLTYPE DeleteMemberByName( 157 /* [in] */ BSTR bstr, 158 /* [in] */ DWORD grfdex); 159 160 virtual HRESULT STDMETHODCALLTYPE DeleteMemberByDispID( 161 /* [in] */ DISPID id); 162 163 virtual HRESULT STDMETHODCALLTYPE GetMemberProperties( 164 /* [in] */ DISPID id, 165 /* [in] */ DWORD grfdexFetch, 166 /* [out] */ DWORD __RPC_FAR *pgrfdex); 167 168 virtual HRESULT STDMETHODCALLTYPE GetMemberName( 169 /* [in] */ DISPID id, 170 /* [out] */ BSTR __RPC_FAR *pbstrName); 171 172 virtual HRESULT STDMETHODCALLTYPE GetNextDispID( 173 /* [in] */ DWORD grfdex, 174 /* [in] */ DISPID id, 175 /* [out] */ DISPID __RPC_FAR *pid); 176 177 virtual HRESULT STDMETHODCALLTYPE GetNameSpaceParent( 178 /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunk); 179 180 // XBridgeSupplier2 --------------------------------------------------- 181 virtual Any SAL_CALL createBridge(const Any& modelDepObject, 182 const Sequence<sal_Int8>& ProcessId, 183 sal_Int16 sourceModelType, 184 sal_Int16 destModelType); 185 186 //XInitialization ----------------------------------------------------- 187 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ); 188 189 // IUnoObjectWrapper 190 STDMETHOD( getWrapperXInterface)( Reference<XInterface>* pXInt); 191 STDMETHOD( getOriginalUnoObject)( Reference<XInterface>* pXInt); 192 STDMETHOD( getOriginalUnoStruct)( Any * pStruct); 193 194 // UnoConversionUtility 195 virtual Reference< XInterface > createUnoWrapperInstance(); 196 virtual Reference< XInterface > createComWrapperInstance(); 197 198 199 protected: 200 virtual HRESULT doInvoke( DISPPARAMS * pdispparams, VARIANT * pvarResult, 201 EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString & name, Sequence<Any>& params); 202 203 virtual HRESULT doGetProperty( DISPPARAMS * pdispparams, VARIANT * pvarResult, 204 EXCEPINFO * pexcepinfo, OUString & name ); 205 206 virtual HRESULT doSetProperty( DISPPARAMS * pdispparams, VARIANT * pvarResult, 207 EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString & name, Sequence<Any> params); 208 209 virtual HRESULT InvokeGeneral( DISPID dispidMember, unsigned short wFlags, 210 DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, 211 unsigned int * puArgErr, sal_Bool& bHandled); 212 213 void convertDispparamsArgs( DISPID id, unsigned short wFlags, DISPPARAMS* pdispparams, 214 Sequence<Any>& rSeq); 215 216 sal_Bool getInvocationInfoForCall(DISPID id, InvocationInfo& info); 217 218 // vos::ORefCount m_refCount; 219 Reference<XInvocation> m_xInvocation; 220 Reference<XExactName> m_xExactName; 221 Reference<XInterface> m_xOrigin; 222 NameToIdMap m_nameToDispIdMap; 223 vector<MemberInfo> m_MemberInfos; 224 // This member is used to determine the default value 225 // denoted by DISPID_VALUE (0). For proper results in JavaScript 226 // we have to return the default value when we write an object 227 // as out parameter. That is, we get an JScript Array as parameter 228 // and put a wrapped object on index null. The array object tries 229 // to detect the default value. The wrapped object must then return 230 // its own IDispatch* otherwise we cannot access it within the script. 231 // see InterfaceOleWrapper_Impl::Invoke 232 VARTYPE m_defaultValueType; 233 234 }; 235 236 /***************************************************************************** 237 238 class declaration: UnoObjectWrapperRemoteOpt 239 ( Uno Object Wrapper Remote Optimized) 240 This is the UNO wrapper used in the service com.sun.star.bridge.OleBridgeSupplierVar1. 241 Key features: 242 DISPIDs are passed out blindly. That is in GetIDsOfNames is no name checking carried out. 243 Only if Invoke fails the name is being checked. Moreover Invoke tries to figure out 244 if a call is made to a property or method if the flags are DISPATCH_METHOD | DISPATCH_PROPERTYPUT. 245 If something has been found out about a property or member than it is saved 246 in a MemberInfo structure hold by a IdToMemberInfoMap stl map. 247 248 *****************************************************************************/ 249 class UnoObjectWrapperRemoteOpt: public InterfaceOleWrapper_Impl 250 { 251 public: 252 UnoObjectWrapperRemoteOpt( Reference<XMultiServiceFactory>& aFactory, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass); 253 ~UnoObjectWrapperRemoteOpt(); 254 255 STDMETHOD( GetIDsOfNames )( REFIID riid, OLECHAR ** rgszNames, unsigned int cNames, 256 LCID lcid, DISPID * rgdispid ); 257 STDMETHOD( Invoke )( DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags, 258 DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, 259 unsigned int * puArgErr ); 260 261 // UnoConversionUtility 262 // If UNO interfaces are converted in methods of this class then 263 // they are always wrapped with instances of this class 264 virtual Reference< XInterface > createUnoWrapperInstance(); 265 266 protected: 267 268 HRESULT methodInvoke( DISPID dispidMember, DISPPARAMS * pdispparams, VARIANT * pvarResult, 269 EXCEPINFO * pexcepinfo, unsigned int * puArgErr, Sequence<Any> params); 270 // In GetIDsOfNames are blindly passed out, that is without verifying 271 // the name. If two names are passed in during different calls to 272 // GetIDsOfNames and the names differ only in their cases then different 273 // id's are passed out ( e.g. "doSomethingMethod" or "dosomethingmethod"). 274 // In Invoke the DISPID is remapped to the name passed to GetIDsOfNames 275 // and the name is used as parameter for XInvocation::invoke. If invoke 276 // fails because of a wrong name, then m_xExactName ( XExactName) is used 277 // to verify the name. The correct name is then inserted to m_MemberInfos 278 // ( vector<MemberInfo> ). During the next call to Invoke the right name 279 // is used. . 280 281 282 BadNameMap m_badNameMap; 283 284 IdToMemberInfoMap m_idToMemberInfoMap; 285 286 DISPID m_currentId; 287 288 289 }; 290 291 292 293 } // end namespace 294 295 #endif 296