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 throw (IllegalArgumentException, RuntimeException); 186 187 //XInitialization ----------------------------------------------------- 188 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException); 189 190 // IUnoObjectWrapper 191 STDMETHOD( getWrapperXInterface)( Reference<XInterface>* pXInt); 192 STDMETHOD( getOriginalUnoObject)( Reference<XInterface>* pXInt); 193 STDMETHOD( getOriginalUnoStruct)( Any * pStruct); 194 195 // UnoConversionUtility 196 virtual Reference< XInterface > createUnoWrapperInstance(); 197 virtual Reference< XInterface > createComWrapperInstance(); 198 199 200 protected: 201 virtual HRESULT doInvoke( DISPPARAMS * pdispparams, VARIANT * pvarResult, 202 EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString & name, Sequence<Any>& params); 203 204 virtual HRESULT doGetProperty( DISPPARAMS * pdispparams, VARIANT * pvarResult, 205 EXCEPINFO * pexcepinfo, OUString & name ); 206 207 virtual HRESULT doSetProperty( DISPPARAMS * pdispparams, VARIANT * pvarResult, 208 EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString & name, Sequence<Any> params); 209 210 virtual HRESULT InvokeGeneral( DISPID dispidMember, unsigned short wFlags, 211 DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, 212 unsigned int * puArgErr, sal_Bool& bHandled); 213 214 void convertDispparamsArgs( DISPID id, unsigned short wFlags, DISPPARAMS* pdispparams, 215 Sequence<Any>& rSeq); 216 217 sal_Bool getInvocationInfoForCall(DISPID id, InvocationInfo& info); 218 219 // vos::ORefCount m_refCount; 220 Reference<XInvocation> m_xInvocation; 221 Reference<XExactName> m_xExactName; 222 Reference<XInterface> m_xOrigin; 223 NameToIdMap m_nameToDispIdMap; 224 vector<MemberInfo> m_MemberInfos; 225 // This member is used to determine the default value 226 // denoted by DISPID_VALUE (0). For proper results in JavaScript 227 // we have to return the default value when we write an object 228 // as out parameter. That is, we get an JScript Array as parameter 229 // and put a wrapped object on index null. The array object tries 230 // to detect the default value. The wrapped object must then return 231 // its own IDispatch* otherwise we cannot access it within the script. 232 // see InterfaceOleWrapper_Impl::Invoke 233 VARTYPE m_defaultValueType; 234 235 }; 236 237 /***************************************************************************** 238 239 class declaration: UnoObjectWrapperRemoteOpt 240 ( Uno Object Wrapper Remote Optimized) 241 This is the UNO wrapper used in the service com.sun.star.bridge.OleBridgeSupplierVar1. 242 Key features: 243 DISPIDs are passed out blindly. That is in GetIDsOfNames is no name checking carried out. 244 Only if Invoke fails the name is being checked. Moreover Invoke tries to figure out 245 if a call is made to a property or method if the flags are DISPATCH_METHOD | DISPATCH_PROPERTYPUT. 246 If something has been found out about a property or member than it is saved 247 in a MemberInfo structure hold by a IdToMemberInfoMap stl map. 248 249 *****************************************************************************/ 250 class UnoObjectWrapperRemoteOpt: public InterfaceOleWrapper_Impl 251 { 252 public: 253 UnoObjectWrapperRemoteOpt( Reference<XMultiServiceFactory>& aFactory, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass); 254 ~UnoObjectWrapperRemoteOpt(); 255 256 STDMETHOD( GetIDsOfNames )( REFIID riid, OLECHAR ** rgszNames, unsigned int cNames, 257 LCID lcid, DISPID * rgdispid ); 258 STDMETHOD( Invoke )( DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags, 259 DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, 260 unsigned int * puArgErr ); 261 262 // UnoConversionUtility 263 // If UNO interfaces are converted in methods of this class then 264 // they are always wrapped with instances of this class 265 virtual Reference< XInterface > createUnoWrapperInstance(); 266 267 protected: 268 269 HRESULT methodInvoke( DISPID dispidMember, DISPPARAMS * pdispparams, VARIANT * pvarResult, 270 EXCEPINFO * pexcepinfo, unsigned int * puArgErr, Sequence<Any> params); 271 // In GetIDsOfNames are blindly passed out, that is without verifying 272 // the name. If two names are passed in during different calls to 273 // GetIDsOfNames and the names differ only in their cases then different 274 // id's are passed out ( e.g. "doSomethingMethod" or "dosomethingmethod"). 275 // In Invoke the DISPID is remapped to the name passed to GetIDsOfNames 276 // and the name is used as parameter for XInvocation::invoke. If invoke 277 // fails because of a wrong name, then m_xExactName ( XExactName) is used 278 // to verify the name. The correct name is then inserted to m_MemberInfos 279 // ( vector<MemberInfo> ). During the next call to Invoke the right name 280 // is used. . 281 282 283 BadNameMap m_badNameMap; 284 285 IdToMemberInfoMap m_idToMemberInfoMap; 286 287 DISPID m_currentId; 288 289 290 }; 291 292 293 294 } // end namespace 295 296 #endif 297