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