summaryrefslogtreecommitdiff
path: root/extensions/source/ole
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/source/ole')
-rw-r--r--extensions/source/ole/comifaces.hxx72
-rw-r--r--extensions/source/ole/jscriptclasses.cxx324
-rw-r--r--extensions/source/ole/jscriptclasses.hxx163
-rw-r--r--extensions/source/ole/makefile.mk129
-rw-r--r--extensions/source/ole/ole2uno.cxx76
-rw-r--r--extensions/source/ole/ole2uno.hxx147
-rw-r--r--extensions/source/ole/oleautobridge.uno.dxp4
-rw-r--r--extensions/source/ole/oledll.cxx72
-rw-r--r--extensions/source/ole/oleobjw.cxx2391
-rw-r--r--extensions/source/ole/oleobjw.hxx284
-rw-r--r--extensions/source/ole/olethread.cxx79
-rw-r--r--extensions/source/ole/servprov.cxx757
-rw-r--r--extensions/source/ole/servprov.hxx279
-rw-r--r--extensions/source/ole/servreg.cxx176
-rw-r--r--extensions/source/ole/unoconversionutilities.hxx2452
-rw-r--r--extensions/source/ole/unoobjw.cxx1690
-rw-r--r--extensions/source/ole/unoobjw.hxx302
-rw-r--r--extensions/source/ole/unotypewrapper.cxx181
-rw-r--r--extensions/source/ole/unotypewrapper.hxx103
-rw-r--r--extensions/source/ole/windata.cxx42
-rw-r--r--extensions/source/ole/windata.hxx201
21 files changed, 9924 insertions, 0 deletions
diff --git a/extensions/source/ole/comifaces.hxx b/extensions/source/ole/comifaces.hxx
new file mode 100644
index 000000000000..d33f350b8f70
--- /dev/null
+++ b/extensions/source/ole/comifaces.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef __COMIFACES_HXX
+#define __COMIFACES_HXX
+
+#include <com/sun/star/uno/XInterface.hpp>
+
+using namespace com::sun::star::uno;
+
+#ifdef __MINGW32__
+DEFINE_GUID(IID_IJScriptValueObject, 0xe40a2331, 0x3bc1, 0x11d4, 0x83, 0x21, 0x00, 0x50, 0x04, 0x52, 0x6a, 0xb4);
+DEFINE_GUID(IID_IUnoObjectWrapper, 0x7B5C3410, 0x66FA, 0x11d4, 0x83, 0x2A, 0x00, 0x50, 0x04, 0x52, 0x6A, 0xB4);
+DEFINE_GUID(IID_IUnoTypeWrapper, 0x8BB66591, 0xA544, 0x4de9, 0x82, 0x2C, 0x57, 0xAB, 0x57, 0xBC, 0xED, 0x1C);
+#endif
+MIDL_INTERFACE("e40a2331-3bc1-11d4-8321-005004526ab4")
+IJScriptValueObject: public IUnknown
+{
+ STDMETHOD( Set)( VARIANT type, VARIANT value)= 0;
+ STDMETHOD( Get)( VARIANT *val)= 0;
+ STDMETHOD( InitOutParam)()= 0;
+ STDMETHOD( InitInOutParam)( VARIANT type, VARIANT value)= 0;
+ STDMETHOD( IsOutParam)( VARIANT_BOOL * flag)= 0;
+ STDMETHOD( IsInOutParam)( VARIANT_BOOL * flag)= 0;
+ STDMETHOD( GetValue)( BSTR* type, VARIANT *value)= 0;
+
+};
+
+MIDL_INTERFACE("7B5C3410-66FA-11d4-832A-005004526AB4")
+IUnoObjectWrapper: public IUnknown
+{
+ STDMETHOD( getWrapperXInterface)( Reference<XInterface>* pInt)=0;
+ STDMETHOD( getOriginalUnoObject)( Reference<XInterface>* pInt)=0;
+ STDMETHOD( getOriginalUnoStruct)( Any * pStruct)=0;
+
+};
+
+MIDL_INTERFACE("8BB66591-A544-4de9-822C-57AB57BCED1C")
+IUnoTypeWrapper: public IUnknown
+{
+ STDMETHOD(put_Name)(BSTR val) = 0;
+ STDMETHOD(get_Name)(BSTR* pVal) = 0;
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/jscriptclasses.cxx b/extensions/source/ole/jscriptclasses.cxx
new file mode 100644
index 000000000000..5b5083a0c848
--- /dev/null
+++ b/extensions/source/ole/jscriptclasses.cxx
@@ -0,0 +1,324 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include "jscriptclasses.hxx"
+
+//========================================================================
+// JScriptValue
+//========================================================================
+JScriptValue::JScriptValue(): m_bOutParam(0), m_bInOutParam(0)
+{
+}
+
+JScriptValue::~JScriptValue()
+{
+}
+
+
+// JScriptValue, IDispatch --------------------------------------------
+STDMETHODIMP JScriptValue::GetTypeInfoCount(UINT* /*pctinfo*/)
+{
+ return E_NOTIMPL;
+}
+
+// JScriptValue, IDispatch --------------------------------------------
+STDMETHODIMP JScriptValue::GetTypeInfo( UINT /*iTInfo*/,
+ LCID /*lcid*/,
+ ITypeInfo** /*ppTInfo*/)
+{
+ return E_NOTIMPL;
+}
+
+// JScriptValue, IDispatch --------------------------------------------
+STDMETHODIMP JScriptValue::GetIDsOfNames( REFIID /*riid*/,
+ LPOLESTR *rgszNames,
+ UINT /*cNames*/,
+ LCID /*lcid*/,
+ DISPID *rgDispId)
+{
+ if( !rgDispId)
+ return E_POINTER;
+
+
+ HRESULT ret= S_OK;
+ CComBSTR name(*rgszNames);
+ name.ToLower();
+
+ if( name == CComBSTR( L"set") )
+ *rgDispId= 1;
+ else if( name == CComBSTR( L"get") )
+ *rgDispId= 2;
+ else if( name == CComBSTR( L"initoutparam") )
+ *rgDispId= 3;
+ else if( name == CComBSTR( L"initinoutparam") )
+ *rgDispId= 4;
+ else
+ ret= DISP_E_UNKNOWNNAME;
+
+ return ret;
+}
+
+// JScriptValue, IDispatch --------------------------------------------
+STDMETHODIMP JScriptValue::Invoke( DISPID dispIdMember,
+ REFIID /*riid*/,
+ LCID /*lcid*/,
+ WORD wFlags,
+ DISPPARAMS *pDispParams,
+ VARIANT *pVarResult,
+ EXCEPINFO* /*pExcepInfo*/,
+ UINT* /*puArgErr*/)
+{
+ if( pDispParams->cNamedArgs)
+ return DISP_E_NONAMEDARGS;
+
+
+ HRESULT ret= S_OK;
+ switch( dispIdMember)
+ {
+ case 0: // DISPID_VALUE
+ if( wFlags & DISPATCH_PROPERTYGET && pVarResult)
+ {
+ if( FAILED( VariantCopy( pVarResult, &m_varValue)))
+ ret= E_FAIL;
+ }
+ else
+ ret= E_POINTER;
+ break;
+ case 1:
+ if( wFlags & DISPATCH_METHOD)
+ ret= Set( pDispParams->rgvarg[1], pDispParams->rgvarg[0]);
+ if( FAILED( ret))
+ ret= DISP_E_EXCEPTION;
+ break;
+ case 2:
+ if( wFlags & DISPATCH_METHOD)
+ ret= Get( pVarResult);
+ if( FAILED( ret))
+ ret= DISP_E_EXCEPTION;
+ break;
+ case 3:
+ if( wFlags & DISPATCH_METHOD)
+ ret= InitOutParam();
+ if( FAILED( ret))
+ ret= DISP_E_EXCEPTION;
+ break;
+ case 4:
+ if( wFlags & DISPATCH_METHOD)
+ ret= InitInOutParam( pDispParams->rgvarg[1], pDispParams->rgvarg[0]);
+ if( FAILED( ret))
+ ret= DISP_E_EXCEPTION;
+ break;
+ default:
+ ret= DISP_E_MEMBERNOTFOUND;
+ break;
+ }
+
+ return ret;
+}
+
+// JScriptValue, IScriptOutParam-----------------------
+STDMETHODIMP JScriptValue::Set( VARIANT type, VARIANT value)
+{
+ Lock();
+ HRESULT hr= S_OK;
+ m_varValue.Clear();
+ hr= VariantCopyInd( &m_varValue, &value);
+ VARIANT var;
+ VariantInit( &var);
+ if( SUCCEEDED( hr= VariantChangeType( &var, &type, 0, VT_BSTR)))
+ m_bstrType= var.bstrVal;
+ Unlock();
+ return hr;
+}
+// JScriptValue, IScriptOutParam-----------------------
+STDMETHODIMP JScriptValue::Get( VARIANT *val)
+{
+ Lock();
+ if( !val)
+ return E_POINTER;
+ HRESULT hr= VariantCopy( val, &m_varValue);
+ Unlock();
+ return hr;
+}
+
+STDMETHODIMP JScriptValue::InitOutParam()
+{
+ Lock();
+ m_varValue.Clear();
+ m_bOutParam= true;
+ m_bInOutParam= false;
+ Unlock();
+ return S_OK;
+}
+
+STDMETHODIMP JScriptValue::InitInOutParam( VARIANT type, VARIANT value)
+{
+ Lock();
+ m_bInOutParam= true;
+ m_bOutParam= false;
+ Unlock();
+ return Set( type, value);
+}
+
+STDMETHODIMP JScriptValue::IsOutParam( VARIANT_BOOL * flag)
+{
+ Lock();
+ if( !flag)
+ return E_POINTER;
+ *flag= m_bOutParam ? VARIANT_TRUE : VARIANT_FALSE;
+ Unlock();
+ return S_OK;
+}
+
+STDMETHODIMP JScriptValue::IsInOutParam( VARIANT_BOOL * flag)
+{
+ Lock();
+ if( !flag)
+ return E_POINTER;
+ *flag= m_bInOutParam ? VARIANT_TRUE : VARIANT_FALSE;
+ Unlock();
+ return S_OK;
+}
+
+STDMETHODIMP JScriptValue::GetValue( BSTR* type, VARIANT *value)
+{
+ Lock();
+ if( !type || !value)
+ return E_POINTER;
+ HRESULT hr;
+ if( SUCCEEDED( hr= m_bstrType.CopyTo( type)))
+ hr= VariantCopy( value, &m_varValue);
+ Unlock();
+ return hr;
+}
+
+//##########################################################################################
+// JScriptOutValue
+//##########################################################################################
+
+JScriptOutParam::JScriptOutParam()
+{
+}
+
+JScriptOutParam::~JScriptOutParam()
+{
+}
+
+
+// JScriptOutParam, IDispatch --------------------------------------------
+STDMETHODIMP JScriptOutParam::GetTypeInfoCount(UINT* /*pctinfo*/)
+{
+ return E_NOTIMPL;
+}
+
+// JScriptOutParam, IDispatch --------------------------------------------
+STDMETHODIMP JScriptOutParam::GetTypeInfo( UINT /*iTInfo*/,
+ LCID /*lcid*/,
+ ITypeInfo** /*ppTInfo*/)
+{
+ return E_NOTIMPL;
+}
+
+// JScriptOutParam, IDispatch --------------------------------------------
+STDMETHODIMP JScriptOutParam::GetIDsOfNames( REFIID /*riid*/,
+ LPOLESTR *rgszNames,
+ UINT /*cNames*/,
+ LCID /*lcid*/,
+ DISPID *rgDispId)
+{
+ if( !rgDispId)
+ return E_POINTER;
+
+
+ HRESULT ret= S_OK;
+ CComBSTR name(*rgszNames);
+ name.ToLower();
+
+ if( name == CComBSTR( L"0") )
+ *rgDispId= 1;
+ else
+ ret= DISP_E_UNKNOWNNAME;
+
+ return ret;
+}
+
+// JScriptOutParam, IDispatch --------------------------------------------
+STDMETHODIMP JScriptOutParam::Invoke( DISPID dispIdMember,
+ REFIID /*riid*/,
+ LCID /*lcid*/,
+ WORD wFlags,
+ DISPPARAMS *pDispParams,
+ VARIANT *pVarResult,
+ EXCEPINFO* /*pExcepInfo*/,
+ UINT* /*puArgErr*/)
+{
+ HRESULT ret= S_OK;
+ switch( dispIdMember)
+ {
+ case 0: // DISPID_VALUE
+ if( wFlags & DISPATCH_PROPERTYGET && pVarResult)
+ {
+ if( FAILED( VariantCopy( pVarResult, &m_varValue)))
+ ret= E_FAIL;
+ }
+ else if( wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF)
+ {
+ m_varValue.Clear();
+ if( FAILED( VariantCopyInd( &m_varValue, &pDispParams->rgvarg[0])))
+ ret= E_FAIL;
+ }
+ else
+ ret= E_POINTER;
+ break;
+ case 1: //
+ if( wFlags & DISPATCH_PROPERTYGET && pVarResult)
+ {
+ if( FAILED( VariantCopy( pVarResult, &m_varValue)))
+ ret= E_FAIL;
+ }
+ else if( wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF)
+ {
+ m_varValue.Clear();
+ if( FAILED( VariantCopyInd( &m_varValue, &pDispParams->rgvarg[0])))
+ ret= E_FAIL;
+ }
+ else
+ ret= E_POINTER;
+ break;
+
+ default:
+ ret= DISP_E_MEMBERNOTFOUND;
+ break;
+ }
+
+ return ret;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/jscriptclasses.hxx b/extensions/source/ole/jscriptclasses.hxx
new file mode 100644
index 000000000000..7eab4bd8c8aa
--- /dev/null
+++ b/extensions/source/ole/jscriptclasses.hxx
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef __JSCRIPTCLASSES_HXX
+#define __JSCRIPTCLASSES_HXX
+
+
+#pragma warning (push,1)
+#pragma warning (disable:4548)
+
+#include <tools/presys.h>
+#define STRICT
+#define _WIN32_WINNT 0x0403
+#define _WIN32_DCOM
+#if OSL_DEBUG_LEVEL > 0
+//#define _ATL_DEBUG_INTERFACES
+#endif
+#include <atlbase.h>
+extern CComModule _Module;
+#include <atlcom.h>
+#include <tools/postsys.h>
+
+#pragma warning (pop)
+#pragma warning (disable:4505)
+ // disable "unreferenced local function has been removed" globally
+
+#include "comifaces.hxx"
+
+
+
+// Sequences are represented by prepending "[]", e.g. []char, [][]byte, [][][]object, etc.
+
+// To make a JScriptValue object to an out parameter, call
+// "InitOutParam" and to make it a in/out parameter call
+// "InitInOutParam"
+
+// If the object represents an out parameter then the value can after the call
+// be retrived by "Get".
+
+// From JavaScript the functions Get, Set, InitOutParam and InitInOutParam are
+// used, that is they are accessible through IDispatch. The functions are used
+// by the bridge.
+
+class JScriptValue:
+ public CComObjectRootEx<CComMultiThreadModel>,
+ public IJScriptValueObject,
+ public IDispatch
+{
+public:
+ JScriptValue();
+ virtual ~JScriptValue();
+
+ BEGIN_COM_MAP(JScriptValue)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(IJScriptValueObject)
+ END_COM_MAP()
+
+ // IDispatch -------------------------------------------
+ STDMETHOD( GetTypeInfoCount)(UINT *pctinfo);
+
+ STDMETHOD( GetTypeInfo)( UINT iTInfo,
+ LCID lcid,
+ ITypeInfo **ppTInfo);
+
+ STDMETHOD( GetIDsOfNames)( REFIID riid,
+ LPOLESTR *rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID *rgDispId);
+
+ STDMETHOD( Invoke)( DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS *pDispParams,
+ VARIANT *pVarResult,
+ EXCEPINFO *pExcepInfo,
+ UINT *puArgErr);
+ // IJScriptOutParam --------------------------------------
+
+ STDMETHOD( Set)( VARIANT type, VARIANT value);
+ STDMETHOD( Get)( VARIANT *val);
+ STDMETHOD( InitOutParam)();
+ STDMETHOD( InitInOutParam)( VARIANT type, VARIANT value);
+ STDMETHOD( IsOutParam)( VARIANT_BOOL * flag);
+ STDMETHOD( IsInOutParam)( VARIANT_BOOL * flag);
+ STDMETHOD( GetValue)( BSTR* type, VARIANT *value);
+
+
+ CComVariant m_varValue;
+ CComBSTR m_bstrType;
+ unsigned m_bOutParam: 1;
+ unsigned m_bInOutParam: 1;
+
+};
+
+// If a class is implemented in JScript, then its method
+class JScriptOutParam:
+ public CComObjectRootEx<CComMultiThreadModel>,
+ public IDispatch
+{
+public:
+ JScriptOutParam();
+ virtual ~JScriptOutParam();
+
+ BEGIN_COM_MAP(JScriptOutParam)
+ COM_INTERFACE_ENTRY(IDispatch)
+ END_COM_MAP()
+
+ // IDispatch -------------------------------------------
+ STDMETHOD( GetTypeInfoCount)(UINT *pctinfo);
+
+ STDMETHOD( GetTypeInfo)( UINT iTInfo,
+ LCID lcid,
+ ITypeInfo **ppTInfo);
+
+ STDMETHOD( GetIDsOfNames)( REFIID riid,
+ LPOLESTR *rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID *rgDispId);
+
+ STDMETHOD( Invoke)( DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS *pDispParams,
+ VARIANT *pVarResult,
+ EXCEPINFO *pExcepInfo,
+ UINT *puArgErr);
+
+
+private:
+ CComVariant m_varValue;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/makefile.mk b/extensions/source/ole/makefile.mk
new file mode 100644
index 000000000000..e20e83e0f1e7
--- /dev/null
+++ b/extensions/source/ole/makefile.mk
@@ -0,0 +1,129 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+# -----------------------------------------------------------------
+
+PRJNAME=extensions
+TARGET=oleautobridge.uno
+TARGET2=oleautobridge2.uno
+
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+LIBTARGET=NO
+USE_DEFFILE=YES
+
+USE_DEFFILE=TRUE
+
+INCPRE+= $(foreach,i,$(ATL_INCLUDE) -I$(i))
+
+# --- Settings -----------------------------------------------------
+
+.IF "$(GUI)" == "WNT" && "$(DISABLE_ATL)"==""
+
+.IF "$(USE_STLP_DEBUG)"!=""
+CDEFS+=-D_DEBUG
+.ENDIF # "$(USE_STLP_DEBUG)"!=""
+
+SLOFILES= \
+ $(SLO)$/servreg.obj \
+ $(SLO)$/servprov.obj \
+ $(SLO)$/unoobjw.obj \
+ $(SLO)$/oleobjw.obj \
+ $(SLO)$/olethread.obj \
+ $(SLO)$/oledll.obj \
+ $(SLO)$/jscriptclasses.obj \
+ $(SLO)$/ole2uno.obj \
+ $(SLO)$/windata.obj \
+ $(SLO)$/unotypewrapper.obj
+
+SECOND_BUILD=OWNGUID
+OWNGUID_SLOFILES=$(SLOFILES)
+OWNGUIDCDEFS+= -DOWNGUID
+
+# the original library
+SHL1TARGET=$(TARGET)
+SHL1STDLIBS=\
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(OLE32LIB) \
+ $(UUIDLIB) \
+ $(ADVAPI32LIB) \
+ $(OLEAUT32LIB)
+
+.IF "$(COM)"=="MSC"
+.IF "$(WINDOWS_VISTA_PSDK)"!="" || "$(CCNUMVER)"<="001399999999"
+.IF "$(USE_STLP_DEBUG)" != ""
+ SHL1STDLIBS+= $(ATL_LIB)$/atlsd.lib
+.ELSE
+ SHL1STDLIBS+= $(ATL_LIB)$/atls.lib
+.ENDIF
+.ENDIF # "$(WINDOWS_VISTA_PSDK)"!="" || "$(CCNUMVER)"<="001399999999"
+.ENDIF # "$(COM)"=="MSC"
+
+SHL1LIBS=
+SHL1OBJS=$(SLOFILES)
+
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=$(SHL1TARGET).dxp
+
+# the second library
+SHL2TARGET=$(TARGET2)
+SHL2STDLIBS=\
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(OLE32LIB) \
+ $(UUIDLIB) \
+ $(ADVAPI32LIB) \
+ $(OLEAUT32LIB)
+
+.IF "$(COM)"=="MSC"
+.IF "$(WINDOWS_VISTA_PSDK)"!="" || "$(CCNUMVER)"<="001399999999"
+.IF "$(USE_STLP_DEBUG)" != ""
+ SHL2STDLIBS+= $(ATL_LIB)$/atlsd.lib
+.ELSE
+ SHL2STDLIBS+= $(ATL_LIB)$/atls.lib
+.ENDIF
+.ENDIF # "$(WINDOWS_VISTA_PSDK)"!="" || "$(CCNUMVER)"<="001399999999"
+.ENDIF # "$(COM)"=="MSC"
+
+SHL2LIBS=
+SHL2OBJS=$(REAL_OWNGUID_SLOFILES)
+
+DEF2NAME=$(SHL2TARGET)
+DEF2EXPORTFILE=$(TARGET).dxp
+
+.ENDIF
+
+#----------------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/extensions/source/ole/ole2uno.cxx b/extensions/source/ole/ole2uno.cxx
new file mode 100644
index 000000000000..16060432ac75
--- /dev/null
+++ b/extensions/source/ole/ole2uno.cxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include "osl/getglobalmutex.hxx"
+#include "rtl/instance.hxx"
+#include "ole2uno.hxx"
+
+using namespace osl;
+namespace ole_adapter
+{
+
+struct MutexInit
+{
+ Mutex * operator () ()
+ {
+ static Mutex aInstance;
+ return &aInstance;
+ }
+};
+
+
+Mutex * getBridgeMutex()
+{
+ return rtl_Instance< Mutex, MutexInit, ::osl::MutexGuard,
+ ::osl::GetGlobalMutex >::create(
+ MutexInit(), ::osl::GetGlobalMutex());
+}
+
+
+// Mutex* getBridgeMutex()
+// {
+// static Mutex* pMutex= NULL;
+
+// if( ! pMutex)
+// {
+// MutexGuard guard( Mutex::getGlobalMutex() );
+// if( !pMutex)
+// {
+// static Mutex aMutex;
+// pMutex= &aMutex;
+// }
+// }
+// return pMutex;
+// }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/ole2uno.hxx b/extensions/source/ole/ole2uno.hxx
new file mode 100644
index 000000000000..fc3ad87ce0b5
--- /dev/null
+++ b/extensions/source/ole/ole2uno.hxx
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _OLE2UNO_HXX
+#define _OLE2UNO_HXX
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define STRICT
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+
+#define _WIN32_DCOM
+#if OSL_DEBUG_LEVEL > 0
+//#define _ATL_DEBUG_INTERFACES
+#endif
+
+#pragma warning (push,1)
+#pragma warning (disable:4917)
+#pragma warning (disable:4005)
+#pragma warning (disable:4548)
+
+#include <tools/prewin.h>
+#include <tchar.h>
+#if (_MSC_VER >= 1200) || defined(__MINGW32__)
+#include <dispex.h>
+#endif
+#include <tools/postwin.h>
+
+#include <tools/presys.h>
+#include <list>
+#include <tools/postsys.h>
+
+#pragma warning (pop)
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/bridge/XBridgeSupplier2.hpp>
+#include <com/sun/star/bridge/ModelDependent.hpp>
+#include <com/sun/star/reflection/InvocationTargetException.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/factory.hxx>
+#include <sal/types.h>
+#include <typelib/typeclass.h>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <rtl/process.h>
+#include <rtl/uuid.h>
+
+#define UNO_2_OLE_EXCEPTIONCODE 1001
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::script;
+using namespace com::sun::star::registry;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::beans;
+using namespace osl;
+using namespace rtl;
+using namespace std;
+
+
+
+namespace ole_adapter
+{
+
+const VARTYPE getVarType( const Any& val);
+/* creates a Type object for a given type name.
+
+ The function returns false if the name does not represent
+ a valid type.
+*/
+bool getType( BSTR name, Type & type);
+void o2u_attachCurrentThread();
+
+struct equalOUString_Impl
+{
+ bool operator()(const OUString & s1, const OUString & s2) const
+ {
+ return s1 == s2;
+ }
+};
+
+struct hashOUString_Impl
+{
+ size_t operator()(const OUString & rName) const
+ {
+ return rName.hashCode();
+ }
+};
+
+
+class BridgeRuntimeError
+{
+public:
+ BridgeRuntimeError(const OUString& sMessage)
+ {
+ message = sMessage;
+ }
+ OUString message;
+};
+
+
+Mutex* getBridgeMutex();
+
+} // end namespace
+
+
+
+#endif // _OLE2UNO_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/oleautobridge.uno.dxp b/extensions/source/ole/oleautobridge.uno.dxp
new file mode 100644
index 000000000000..e7947188aa92
--- /dev/null
+++ b/extensions/source/ole/oleautobridge.uno.dxp
@@ -0,0 +1,4 @@
+component_writeInfo @100
+component_getFactory @101
+component_getImplementationEnvironment @102
+component_canUnload @103
diff --git a/extensions/source/ole/oledll.cxx b/extensions/source/ole/oledll.cxx
new file mode 100644
index 000000000000..5346aa940cf7
--- /dev/null
+++ b/extensions/source/ole/oledll.cxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#define STRICT
+#define _WIN32_WINNT 0x0403
+#define _WIN32_DCOM
+
+#pragma warning (push,1)
+#pragma warning (disable:4548)
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_STLP_DEBUG)
+#undef _DEBUG
+#endif
+#ifdef __MINGW32__
+#define _INIT_ATL_COMMON_VARS
+#endif
+#include <atlbase.h>
+CComModule _Module;
+#include <atlcom.h>
+
+#pragma warning (pop)
+
+BEGIN_OBJECT_MAP(ObjectMap)
+END_OBJECT_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// DLL Entry Point
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ _Module.Init(ObjectMap, hInstance, NULL);
+ DisableThreadLibraryCalls(hInstance);
+ }
+ else if (dwReason == DLL_PROCESS_DETACH)
+ {
+ _Module.Term();
+ }
+ return TRUE; // ok
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/oleobjw.cxx b/extensions/source/ole/oleobjw.cxx
new file mode 100644
index 000000000000..20359a21901b
--- /dev/null
+++ b/extensions/source/ole/oleobjw.cxx
@@ -0,0 +1,2391 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include "ole2uno.hxx"
+#include "rtl/ustrbuf.hxx"
+
+
+#include "osl/diagnose.h"
+#include "osl/doublecheckedlocking.h"
+#include "osl/thread.h"
+
+#include "boost/scoped_array.hpp"
+#include <com/sun/star/script/FailReason.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/FinishEngineEvent.hpp>
+#include <com/sun/star/script/InterruptReason.hpp>
+#include <com/sun/star/script/XEngineListener.hpp>
+#include <com/sun/star/script/XDebugging.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/script/ContextInformation.hpp>
+#include <com/sun/star/script/FinishReason.hpp>
+#include <com/sun/star/script/XEngine.hpp>
+#include <com/sun/star/script/InterruptEngineEvent.hpp>
+#include <com/sun/star/script/XLibraryAccess.hpp>
+#include <com/sun/star/script/BasicErrorException.hpp>
+#include <com/sun/star/bridge/ModelDependent.hpp>
+
+#include "com/sun/star/bridge/oleautomation/NamedArgument.hpp"
+#include "com/sun/star/bridge/oleautomation/PropertyPutArgument.hpp"
+
+#include <typelib/typedescription.hxx>
+#include <rtl/uuid.h>
+#include <rtl/memory.h>
+#include <rtl/ustring.hxx>
+
+#include "jscriptclasses.hxx"
+
+#include "oleobjw.hxx"
+#include "unoobjw.hxx"
+#include <stdio.h>
+using namespace std;
+using namespace boost;
+using namespace osl;
+using namespace rtl;
+using namespace cppu;
+using namespace com::sun::star::script;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::bridge;
+using namespace com::sun::star::bridge::oleautomation;
+using namespace com::sun::star::bridge::ModelDependent;
+
+#define JSCRIPT_ID_PROPERTY L"_environment"
+#define JSCRIPT_ID L"jscript"
+namespace ole_adapter
+{
+
+
+// key: XInterface pointer created by Invocation Adapter Factory
+// value: XInterface pointer to the wrapper class.
+// Entries to the map are made within
+// Any createOleObjectWrapper(IUnknown* pUnknown, const Type& aType);
+// Entries are being deleted if the wrapper class's destructor has been
+// called.
+// Before UNO object is wrapped to COM object this map is checked
+// to see if the UNO object is already a wrapper.
+hash_map<sal_uInt32, sal_uInt32> AdapterToWrapperMap;
+// key: XInterface of the wrapper object.
+// value: XInterface of the Interface created by the Invocation Adapter Factory.
+// A COM wrapper is responsible for removing the corresponding entry
+// in AdapterToWrappperMap if it is being destroyed. Because the wrapper does not
+// know about its adapted interface it uses WrapperToAdapterMap to get the
+// adapted interface which is then used to locate the entry in AdapterToWrapperMap.
+hash_map<sal_uInt32,sal_uInt32> WrapperToAdapterMap;
+
+hash_map<sal_uInt32, WeakReference<XInterface> > ComPtrToWrapperMap;
+/*****************************************************************************
+
+ class implementation IUnknownWrapper_Impl
+
+*****************************************************************************/
+
+IUnknownWrapper_Impl::IUnknownWrapper_Impl( Reference<XMultiServiceFactory>& xFactory,
+ sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass):
+ UnoConversionUtilities<IUnknownWrapper_Impl>( xFactory, unoWrapperClass, comWrapperClass),
+ m_pxIdlClass( NULL), m_eJScript( JScriptUndefined),
+ m_bComTlbIndexInit(false), m_bHasDfltMethod(false), m_bHasDfltProperty(false)
+{
+}
+
+
+IUnknownWrapper_Impl::~IUnknownWrapper_Impl()
+{
+ o2u_attachCurrentThread();
+ MutexGuard guard(getBridgeMutex());
+ XInterface * xIntRoot = (OWeakObject *)this;
+#if OSL_DEBUG_LEVEL > 0
+ acquire(); // make sure we don't delete us twice because of Reference
+ OSL_ASSERT( Reference<XInterface>( static_cast<XWeak*>(this), UNO_QUERY).get() == xIntRoot );
+#endif
+
+ // remove entries in global maps
+ typedef hash_map<sal_uInt32, sal_uInt32>::iterator _IT;
+ _IT it= WrapperToAdapterMap.find( (sal_uInt32) xIntRoot);
+ if( it != WrapperToAdapterMap.end())
+ {
+ sal_uInt32 adapter= it->second;
+
+ AdapterToWrapperMap.erase( adapter);
+ WrapperToAdapterMap.erase( it);
+ }
+
+ IT_Com it_c= ComPtrToWrapperMap.find( (sal_uInt32) m_spUnknown.p);
+ if(it_c != ComPtrToWrapperMap.end())
+ ComPtrToWrapperMap.erase(it_c);
+
+#if OSL_DEBUG_LEVEL > 0
+ fprintf(stderr,"[automation bridge] ComPtrToWrapperMap contains: %i \n",
+ ComPtrToWrapperMap.size());
+#endif
+}
+
+Any IUnknownWrapper_Impl::queryInterface(const Type& t)
+ throw (RuntimeException)
+{
+ if (t == getCppuType(static_cast<Reference<XDefaultMethod>*>( 0)) && !m_bHasDfltMethod )
+ return Any();
+ if (t == getCppuType(static_cast<Reference<XDefaultProperty>*>( 0)) && !m_bHasDfltProperty )
+ return Any();
+ if ( ( t == getCppuType(static_cast<Reference<XInvocation>*>( 0)) || t == getCppuType(static_cast<Reference<XAutomationInvocation>*>( 0)) ) && !m_spDispatch)
+ return Any();
+
+ return WeakImplHelper6<XAutomationInvocation, XBridgeSupplier2,
+ XInitialization, XAutomationObject, XDefaultProperty, XDefaultMethod>::queryInterface(t);
+}
+
+Reference<XIntrospectionAccess> SAL_CALL IUnknownWrapper_Impl::getIntrospection(void)
+ throw (RuntimeException )
+{
+ Reference<XIntrospectionAccess> ret;
+
+ return ret;
+}
+
+Any SAL_CALL IUnknownWrapper_Impl::invokeGetProperty( const OUString& aPropertyName, const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam )
+{
+ Any aResult;
+ try
+ {
+ o2u_attachCurrentThread();
+ ITypeInfo * pInfo = getTypeInfo();
+ FuncDesc aDescGet(pInfo);
+ FuncDesc aDescPut(pInfo);
+ VarDesc aVarDesc(pInfo);
+ getPropDesc(aPropertyName, & aDescGet, & aDescPut, & aVarDesc);
+ if ( !aDescGet )
+ {
+ OUString msg(OUSTR("[automation bridge]Property \"") + aPropertyName +
+ OUSTR("\" is not supported"));
+ throw UnknownPropertyException(msg, Reference<XInterface>());
+ }
+ aResult = invokeWithDispIdComTlb( aDescGet, aPropertyName, aParams, aOutParamIndex, aOutParam );
+ }
+ catch ( Exception& e )
+ {
+ throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::invokeGetProperty ! Message : \n") +
+ e.Message, Reference<XInterface>());
+ }
+ return aResult;
+}
+
+Any SAL_CALL IUnknownWrapper_Impl::invokePutProperty( const OUString& aPropertyName, const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam )
+{
+ Any aResult;
+ try
+ {
+ o2u_attachCurrentThread();
+ ITypeInfo * pInfo = getTypeInfo();
+ FuncDesc aDescGet(pInfo);
+ FuncDesc aDescPut(pInfo);
+ VarDesc aVarDesc(pInfo);
+ getPropDesc(aPropertyName, & aDescGet, & aDescPut, & aVarDesc);
+ if ( !aDescPut )
+ {
+ OUString msg(OUSTR("[automation bridge]Property \"") + aPropertyName +
+ OUSTR("\" is not supported"));
+ throw UnknownPropertyException(msg, Reference<XInterface>());
+ }
+ aResult = invokeWithDispIdComTlb( aDescPut, aPropertyName, aParams, aOutParamIndex, aOutParam );
+ }
+ catch ( Exception& e )
+ {
+ throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::invokePutProperty ! Message : \n") +
+ e.Message, Reference<XInterface>());
+ }
+ return aResult;
+}
+
+
+Any SAL_CALL IUnknownWrapper_Impl::invoke( const OUString& aFunctionName,
+ const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex,
+ Sequence< Any >& aOutParam )
+ throw(IllegalArgumentException, CannotConvertException, InvocationTargetException,
+ RuntimeException)
+{
+ if ( ! m_spDispatch )
+ {
+ throw RuntimeException(
+ OUSTR("[automation bridge] The object does not have an IDispatch interface"),
+ Reference<XInterface>());
+ }
+
+ Any ret;
+
+ try
+ {
+ o2u_attachCurrentThread();
+
+ TypeDescription methodDesc;
+ getMethodInfo(aFunctionName, methodDesc);
+ if( methodDesc.is())
+ {
+ ret = invokeWithDispIdUnoTlb(aFunctionName,
+ aParams,
+ aOutParamIndex,
+ aOutParam);
+ }
+ else
+ {
+ ret= invokeWithDispIdComTlb( aFunctionName,
+ aParams,
+ aOutParamIndex,
+ aOutParam);
+ }
+ }
+ catch (IllegalArgumentException &)
+ {
+ throw;
+ }
+ catch (CannotConvertException &)
+ {
+ throw;
+ }
+ catch (InvocationTargetException &)
+ {
+ throw;
+ }
+ catch (BridgeRuntimeError & e)
+ {
+ throw RuntimeException(e.message, Reference<XInterface>());
+ }
+ catch (Exception & e)
+ {
+ throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::invoke ! Message : \n") +
+ e.Message, Reference<XInterface>());
+
+ }
+ catch(...)
+ {
+ throw RuntimeException(
+ OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::Invoke !"), Reference<XInterface>());
+ }
+ return ret;
+}
+
+void SAL_CALL IUnknownWrapper_Impl::setValue( const OUString& aPropertyName,
+ const Any& aValue )
+ throw(UnknownPropertyException, CannotConvertException, InvocationTargetException,
+ RuntimeException)
+{
+ if ( ! m_spDispatch )
+ {
+ throw RuntimeException(
+ OUSTR("[automation bridge] The object does not have an IDispatch interface"),
+ Reference<XInterface>());
+ }
+ try
+ {
+ o2u_attachCurrentThread();
+
+ ITypeInfo * pInfo = getTypeInfo();
+ FuncDesc aDescGet(pInfo);
+ FuncDesc aDescPut(pInfo);
+ VarDesc aVarDesc(pInfo);
+ getPropDesc(aPropertyName, & aDescGet, & aDescPut, & aVarDesc);
+ //check if there is such a property at all or if it is read only
+ if ( ! aDescPut && ! aDescGet && ! aVarDesc)
+ {
+ OUString msg(OUSTR("[automation bridge]Property \"") + aPropertyName +
+ OUSTR("\" is not supported"));
+ throw UnknownPropertyException(msg, Reference<XInterface>());
+ }
+
+ if ( (! aDescPut && aDescGet) || aVarDesc
+ && aVarDesc->wVarFlags == VARFLAG_FREADONLY )
+ {
+ //read-only
+ OUString msg(OUSTR("[automation bridge] Property ") + aPropertyName +
+ OUSTR(" is read-only"));
+ OString sMsg = OUStringToOString(msg, osl_getThreadTextEncoding());
+ OSL_ENSURE(0, sMsg.getStr());
+ // ignore silently
+ return;
+ }
+
+ HRESULT hr= S_OK;
+ DISPPARAMS dispparams;
+ CComVariant varArg;
+ CComVariant varRefArg;
+ CComVariant varResult;
+ ExcepInfo excepinfo;
+ unsigned int uArgErr;
+
+ // converting UNO value to OLE variant
+ DISPID dispidPut= DISPID_PROPERTYPUT;
+ dispparams.rgdispidNamedArgs = &dispidPut;
+ dispparams.cArgs = 1;
+ dispparams.cNamedArgs = 1;
+ dispparams.rgvarg = & varArg;
+
+ OSL_ASSERT(aDescPut || aVarDesc);
+
+ VARTYPE vt = 0;
+ DISPID dispid = 0;
+ INVOKEKIND invkind = INVOKE_PROPERTYPUT;
+ //determine the expected type, dispid, invoke kind (DISPATCH_PROPERTYPUT,
+ //DISPATCH_PROPERTYPUTREF)
+ if (aDescPut)
+ {
+ vt = getElementTypeDesc(& aDescPut->lprgelemdescParam[0].tdesc);
+ dispid = aDescPut->memid;
+ invkind = aDescPut->invkind;
+ }
+ else
+ {
+ vt = getElementTypeDesc( & aVarDesc->elemdescVar.tdesc);
+ dispid = aVarDesc->memid;
+ if (vt == VT_UNKNOWN || vt == VT_DISPATCH ||
+ (vt & VT_ARRAY) || (vt & VT_BYREF))
+ {
+ invkind = INVOKE_PROPERTYPUTREF;
+ }
+ }
+
+ // convert the uno argument
+ if (vt & VT_BYREF)
+ {
+ anyToVariant( & varRefArg, aValue, ::sal::static_int_cast< VARTYPE, int >( vt ^ VT_BYREF ) );
+ varArg.vt = vt;
+ if( (vt & VT_TYPEMASK) == VT_VARIANT)
+ varArg.byref = & varRefArg;
+ else if ((vt & VT_TYPEMASK) == VT_DECIMAL)
+ varArg.byref = & varRefArg.decVal;
+ else
+ varArg.byref = & varRefArg.byref;
+ }
+ else
+ {
+ anyToVariant(& varArg, aValue, vt);
+ }
+ // call to IDispatch
+ hr = m_spDispatch->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, ::sal::static_int_cast< WORD, INVOKEKIND >( invkind ),
+ &dispparams, & varResult, & excepinfo, &uArgErr);
+
+ // lookup error code
+ switch (hr)
+ {
+ case S_OK:
+ break;
+ case DISP_E_BADPARAMCOUNT:
+ throw RuntimeException();
+ break;
+ case DISP_E_BADVARTYPE:
+ throw RuntimeException();
+ break;
+ case DISP_E_EXCEPTION:
+ throw InvocationTargetException();
+ break;
+ case DISP_E_MEMBERNOTFOUND:
+ throw UnknownPropertyException();
+ break;
+ case DISP_E_NONAMEDARGS:
+ throw RuntimeException();
+ break;
+ case DISP_E_OVERFLOW:
+ throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
+ static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::OUT_OF_RANGE, uArgErr);
+ break;
+ case DISP_E_PARAMNOTFOUND:
+ throw IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
+ static_cast<XWeak*>(this)), ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr )) ;
+ break;
+ case DISP_E_TYPEMISMATCH:
+ throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
+ static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::UNKNOWN, ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
+ break;
+ case DISP_E_UNKNOWNINTERFACE:
+ throw RuntimeException();
+ break;
+ case DISP_E_UNKNOWNLCID:
+ throw RuntimeException();
+ break;
+ case DISP_E_PARAMNOTOPTIONAL:
+ throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")),static_cast<XInterface*>(
+ static_cast<XWeak*>(this)) , TypeClass_UNKNOWN, FailReason::NO_DEFAULT_AVAILABLE, uArgErr);
+ break;
+ default:
+ throw RuntimeException();
+ break;
+ }
+ }
+ catch (CannotConvertException &)
+ {
+ throw;
+ }
+ catch (UnknownPropertyException &)
+ {
+ throw;
+ }
+ catch (BridgeRuntimeError& e)
+ {
+ throw RuntimeException(
+ e.message, Reference<XInterface>());
+ }
+ catch (Exception & e)
+ {
+ throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::setValue ! Message : \n") +
+ e.Message, Reference<XInterface>());
+
+ }
+ catch (...)
+ {
+ throw RuntimeException(
+ OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::setValue !"), Reference<XInterface>());
+ }
+}
+
+Any SAL_CALL IUnknownWrapper_Impl::getValue( const OUString& aPropertyName )
+ throw(UnknownPropertyException, RuntimeException)
+{
+ if ( ! m_spDispatch )
+ {
+ throw RuntimeException(
+ OUSTR("[automation bridge] The object does not have an IDispatch interface"),
+ Reference<XInterface>());
+ }
+ Any ret;
+ try
+ {
+ o2u_attachCurrentThread();
+ ITypeInfo * pInfo = getTypeInfo();
+ // I was going to implement an XServiceInfo interface to allow the type
+ // of the automation object to be exposed.. but it seems
+ // from looking at comments in the code that it is possible for
+ // this object to actually wrap an UNO object ( I guess if automation is
+ // used from MSO to create Openoffice objects ) Therefore, those objects
+ // will more than likely already have their own XServiceInfo interface.
+ // Instead here I chose a name that should be illegal both in COM and
+ // UNO ( from an IDL point of view ) therefore I think this is a safe
+ // hack
+ if ( aPropertyName.equals( rtl::OUString::createFromAscii("$GetTypeName") ))
+ {
+ if ( pInfo && m_sTypeName.getLength() == 0 )
+ {
+ m_sTypeName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IDispatch") );
+ CComBSTR sName;
+
+ if ( SUCCEEDED( pInfo->GetDocumentation( -1, &sName, NULL, NULL, NULL ) ) )
+ {
+ rtl::OUString sTmp( reinterpret_cast<const sal_Unicode*>(LPCOLESTR(sName)));
+ if ( sTmp.indexOf('_') == 0 )
+ sTmp = sTmp.copy(1);
+ // do we own the memory for pTypeLib, msdn doco is vague
+ // I'll assume we do
+ CComPtr< ITypeLib > pTypeLib;
+ unsigned int index;
+ if ( SUCCEEDED( pInfo->GetContainingTypeLib( &pTypeLib.p, &index )) )
+ {
+ if ( SUCCEEDED( pTypeLib->GetDocumentation( -1, &sName, NULL, NULL, NULL ) ) )
+ {
+ rtl::OUString sLibName( reinterpret_cast<const sal_Unicode*>(LPCOLESTR(sName)));
+ m_sTypeName = sLibName.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(".") ) ).concat( sTmp );
+
+ }
+ }
+ }
+
+ }
+ ret <<= m_sTypeName;
+ return ret;
+ }
+ FuncDesc aDescGet(pInfo);
+ FuncDesc aDescPut(pInfo);
+ VarDesc aVarDesc(pInfo);
+ getPropDesc(aPropertyName, & aDescGet, & aDescPut, & aVarDesc);
+ if ( ! aDescGet && ! aDescPut && ! aVarDesc)
+ {
+ //property not found
+ OUString msg(OUSTR("[automation bridge]Property \"") + aPropertyName +
+ OUSTR("\" is not supported"));
+ throw UnknownPropertyException(msg, Reference<XInterface>());
+ }
+ // write-only should not be possible
+ OSL_ASSERT( aDescGet || ! aDescPut);
+
+ HRESULT hr;
+ DISPPARAMS dispparams = {0, 0, 0, 0};
+ CComVariant varResult;
+ ExcepInfo excepinfo;
+ unsigned int uArgErr;
+ DISPID dispid;
+ if (aDescGet)
+ dispid = aDescGet->memid;
+ else if (aVarDesc)
+ dispid = aVarDesc->memid;
+ else
+ dispid = aDescPut->memid;
+
+ hr = m_spDispatch->Invoke(dispid,
+ IID_NULL,
+ LOCALE_USER_DEFAULT,
+ DISPATCH_PROPERTYGET,
+ &dispparams,
+ &varResult,
+ &excepinfo,
+ &uArgErr);
+
+ // converting return value and out parameter back to UNO
+ if (hr == S_OK)
+ {
+ // If the com object implements uno interfaces then we have
+ // to convert the attribute into the expected type.
+ TypeDescription attrInfo;
+ getAttributeInfo(aPropertyName, attrInfo);
+ if( attrInfo.is() )
+ variantToAny( &varResult, ret, Type( attrInfo.get()->pWeakRef));
+ else
+ variantToAny(&varResult, ret);
+ }
+
+ // lookup error code
+ switch (hr)
+ {
+ case S_OK:
+ break;
+ case DISP_E_BADPARAMCOUNT:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_BADVARTYPE:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_EXCEPTION:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_MEMBERNOTFOUND:
+ throw UnknownPropertyException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_NONAMEDARGS:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_OVERFLOW:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_PARAMNOTFOUND:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_TYPEMISMATCH:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_UNKNOWNINTERFACE:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_UNKNOWNLCID:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ case DISP_E_PARAMNOTOPTIONAL:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ default:
+ throw RuntimeException(OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription)),
+ Reference<XInterface>());
+ break;
+ }
+ }
+ catch (UnknownPropertyException& )
+ {
+ throw;
+ }
+ catch (BridgeRuntimeError& e)
+ {
+ throw RuntimeException(
+ e.message, Reference<XInterface>());
+ }
+ catch (Exception & e)
+ {
+ throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::getValue ! Message : \n") +
+ e.Message, Reference<XInterface>());
+ }
+ catch (...)
+ {
+ throw RuntimeException(
+ OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::getValue !"), Reference<XInterface>());
+ }
+ return ret;
+}
+
+sal_Bool SAL_CALL IUnknownWrapper_Impl::hasMethod( const OUString& aName )
+ throw(RuntimeException)
+{
+ if ( ! m_spDispatch )
+ {
+ throw RuntimeException(
+ OUSTR("[automation bridge] The object does not have an IDispatch interface"),
+ Reference<XInterface>());
+ }
+ sal_Bool ret = sal_False;
+
+ try
+ {
+ o2u_attachCurrentThread();
+ ITypeInfo* pInfo = getTypeInfo();
+ FuncDesc aDesc(pInfo);
+ getFuncDesc(aName, & aDesc);
+ // Automation properties can have arguments. Those are treated as methods and
+ //are called through XInvocation::invoke.
+ if ( ! aDesc)
+ {
+ FuncDesc aDescGet(pInfo);
+ FuncDesc aDescPut(pInfo);
+ VarDesc aVarDesc(pInfo);
+ getPropDesc( aName, & aDescGet, & aDescPut, & aVarDesc);
+ if (aDescGet && aDescGet->cParams > 0
+ || aDescPut && aDescPut->cParams > 0)
+ ret = sal_True;
+ }
+ else
+ ret = sal_True;
+ }
+ catch (BridgeRuntimeError& e)
+ {
+ throw RuntimeException(e.message, Reference<XInterface>());
+ }
+ catch (Exception & e)
+ {
+ throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::hasMethod ! Message : \n") +
+ e.Message, Reference<XInterface>());
+ }
+ catch (...)
+ {
+ throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::hasMethod !"), Reference<XInterface>());;
+ }
+ return ret;
+}
+
+sal_Bool SAL_CALL IUnknownWrapper_Impl::hasProperty( const OUString& aName )
+ throw(RuntimeException)
+{
+ if ( ! m_spDispatch )
+ {
+ throw RuntimeException(OUSTR("[automation bridge] The object does not have an "
+ "IDispatch interface"), Reference<XInterface>());
+ return sal_False;
+ }
+ sal_Bool ret = sal_False;
+ try
+ {
+ o2u_attachCurrentThread();
+
+ ITypeInfo * pInfo = getTypeInfo();
+ FuncDesc aDescGet(pInfo);
+ FuncDesc aDescPut(pInfo);
+ VarDesc aVarDesc(pInfo);
+ getPropDesc(aName, & aDescGet, & aDescPut, & aVarDesc);
+
+ // we should probably just check the funckind
+ // basic has been modified to handle properties ( 'get' ) props at
+ // least with paramaters
+ // additionally you can call invoke(Get|Set)Property on the bridge
+ // you can determine if a property has parameter is hasMethod
+ // returns true for the name
+ if (aVarDesc
+ || aDescPut
+ || aDescGet )
+ {
+ ret = sal_True;
+ }
+ }
+ catch (BridgeRuntimeError& e)
+ {
+ throw RuntimeException(e.message, Reference<XInterface>());
+ }
+ catch (Exception & e)
+ {
+ throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::hasProperty ! Message : \n") +
+ e.Message, Reference<XInterface>());
+
+ }
+ catch (...)
+ {
+ throw RuntimeException(OUSTR("[automation bridge] unexpected exception in "
+ "IUnknownWrapper_Impl::hasProperty !"), Reference<XInterface>());
+ }
+ return ret;
+}
+
+Any SAL_CALL IUnknownWrapper_Impl::createBridge( const Any& modelDepObject,
+ const Sequence< sal_Int8 >& /*aProcessId*/, sal_Int16 sourceModelType,
+ sal_Int16 destModelType )
+ throw( IllegalArgumentException, RuntimeException)
+{
+ Any ret;
+ o2u_attachCurrentThread();
+
+ if (
+ (sourceModelType == UNO) &&
+ (destModelType == OLE) &&
+ (modelDepObject.getValueTypeClass() == TypeClass_INTERFACE)
+ )
+ {
+ Reference<XInterface> xInt( *(XInterface**) modelDepObject.getValue());
+ Reference<XInterface> xSelf( (OWeakObject*)this);
+
+ if (xInt == xSelf)
+ {
+ VARIANT* pVariant = (VARIANT*) CoTaskMemAlloc(sizeof(VARIANT));
+
+ VariantInit(pVariant);
+ if (m_bOriginalDispatch == sal_True)
+ {
+ pVariant->vt = VT_DISPATCH;
+ pVariant->pdispVal = m_spDispatch;
+ pVariant->pdispVal->AddRef();
+ }
+ else
+ {
+ pVariant->vt = VT_UNKNOWN;
+ pVariant->punkVal = m_spUnknown;
+ pVariant->punkVal->AddRef();
+ }
+
+ ret.setValue((void*)&pVariant, getCppuType( (sal_uInt32*) 0));
+ }
+ }
+
+ return ret;
+}
+/** @internal
+ @exception IllegalArgumentException
+ @exception CannotConvertException
+ @exception InvocationTargetException
+ @RuntimeException
+*/
+Any IUnknownWrapper_Impl::invokeWithDispIdUnoTlb(const OUString& sFunctionName,
+ const Sequence< Any >& Params,
+ Sequence< sal_Int16 >& OutParamIndex,
+ Sequence< Any >& OutParam)
+{
+ Any ret;
+ HRESULT hr= S_OK;
+
+ sal_Int32 parameterCount= Params.getLength();
+ sal_Int32 outParameterCount= 0;
+ typelib_InterfaceMethodTypeDescription* pMethod= NULL;
+ TypeDescription methodDesc;
+ getMethodInfo(sFunctionName, methodDesc);
+
+ // We need to know whether the IDispatch is from a JScript object.
+ // Then out and in/out parameters have to be treated differently than
+ // with common COM objects.
+ sal_Bool bJScriptObject= isJScriptObject();
+ scoped_array<CComVariant> sarParams;
+ scoped_array<CComVariant> sarParamsRef;
+ CComVariant *pVarParams= NULL;
+ CComVariant *pVarParamsRef= NULL;
+ sal_Bool bConvRet= sal_True;
+
+ if( methodDesc.is())
+ {
+ pMethod = (typelib_InterfaceMethodTypeDescription* )methodDesc.get();
+ parameterCount = pMethod->nParams;
+ // Create the Array for the array being passed in DISPPARAMS
+ // the array also contains the outparameter (but not the values)
+ if( pMethod->nParams > 0)
+ {
+ sarParams.reset(new CComVariant[ parameterCount]);
+ pVarParams = sarParams.get();
+ }
+
+ // Create the Array for the out an in/out parameter. These values
+ // are referenced by the VT_BYREF VARIANTs in DISPPARAMS.
+ // We need to find out the number of out and in/out parameter.
+ for( sal_Int32 i=0; i < parameterCount; i++)
+ {
+ if( pMethod->pParams[i].bOut)
+ outParameterCount++;
+ }
+
+ if( !bJScriptObject)
+ {
+ sarParamsRef.reset(new CComVariant[outParameterCount]);
+ pVarParamsRef = sarParamsRef.get();
+ // build up the parameters for IDispatch::Invoke
+ sal_Int32 outParamIndex=0;
+ int i = 0;
+ try
+ {
+ for( i= 0; i < parameterCount; i++)
+ {
+ // In parameter
+ if( pMethod->pParams[i].bIn == sal_True && ! pMethod->pParams[i].bOut)
+ {
+ anyToVariant( &pVarParams[parameterCount - i -1], Params.getConstArray()[i]);
+ }
+ // Out parameter + in/out parameter
+ else if( pMethod->pParams[i].bOut == sal_True)
+ {
+ CComVariant var;
+ if(pMethod->pParams[i].bIn)
+ {
+ anyToVariant( & var,Params[i]);
+ pVarParamsRef[outParamIndex] = var;
+ }
+
+ switch( pMethod->pParams[i].pTypeRef->eTypeClass)
+ {
+ case TypeClass_INTERFACE:
+ case TypeClass_STRUCT:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt= VT_DISPATCH;
+ pVarParamsRef[ outParamIndex].pdispVal= 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_DISPATCH | VT_BYREF;
+ pVarParams[parameterCount - i -1].ppdispVal= &pVarParamsRef[outParamIndex].pdispVal;
+ break;
+ case TypeClass_ENUM:
+ case TypeClass_LONG:
+ case TypeClass_UNSIGNED_LONG:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_I4;
+ pVarParamsRef[ outParamIndex].lVal = 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_I4 | VT_BYREF;
+ pVarParams[parameterCount - i -1].plVal= &pVarParamsRef[outParamIndex].lVal;
+ break;
+ case TypeClass_SEQUENCE:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_ARRAY| VT_VARIANT;
+ pVarParamsRef[ outParamIndex].parray= NULL;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_ARRAY| VT_BYREF | VT_VARIANT;
+ pVarParams[parameterCount - i -1].pparray= &pVarParamsRef[outParamIndex].parray;
+ break;
+ case TypeClass_ANY:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_EMPTY;
+ pVarParamsRef[ outParamIndex].lVal = 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_VARIANT | VT_BYREF;
+ pVarParams[parameterCount - i -1].pvarVal = &pVarParamsRef[outParamIndex];
+ break;
+ case TypeClass_BOOLEAN:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_BOOL;
+ pVarParamsRef[ outParamIndex].boolVal = 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_BOOL| VT_BYREF;
+ pVarParams[parameterCount - i -1].pboolVal =
+ & pVarParamsRef[outParamIndex].boolVal;
+ break;
+
+ case TypeClass_STRING:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_BSTR;
+ pVarParamsRef[ outParamIndex].bstrVal= 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_BSTR| VT_BYREF;
+ pVarParams[parameterCount - i -1].pbstrVal=
+ & pVarParamsRef[outParamIndex].bstrVal;
+ break;
+
+ case TypeClass_FLOAT:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_R4;
+ pVarParamsRef[ outParamIndex].fltVal= 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_R4| VT_BYREF;
+ pVarParams[parameterCount - i -1].pfltVal =
+ & pVarParamsRef[outParamIndex].fltVal;
+ break;
+ case TypeClass_DOUBLE:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_R8;
+ pVarParamsRef[ outParamIndex].dblVal= 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_R8| VT_BYREF;
+ pVarParams[parameterCount - i -1].pdblVal=
+ & pVarParamsRef[outParamIndex].dblVal;
+ break;
+ case TypeClass_BYTE:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_UI1;
+ pVarParamsRef[ outParamIndex].bVal= 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_UI1| VT_BYREF;
+ pVarParams[parameterCount - i -1].pbVal=
+ & pVarParamsRef[outParamIndex].bVal;
+ break;
+ case TypeClass_CHAR:
+ case TypeClass_SHORT:
+ case TypeClass_UNSIGNED_SHORT:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_I2;
+ pVarParamsRef[ outParamIndex].iVal = 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_I2| VT_BYREF;
+ pVarParams[parameterCount - i -1].piVal=
+ & pVarParamsRef[outParamIndex].iVal;
+ break;
+
+ default:
+ if( ! pMethod->pParams[i].bIn)
+ {
+ pVarParamsRef[ outParamIndex].vt = VT_EMPTY;
+ pVarParamsRef[ outParamIndex].lVal = 0;
+ }
+ pVarParams[parameterCount - i -1].vt = VT_VARIANT | VT_BYREF;
+ pVarParams[parameterCount - i -1].pvarVal =
+ & pVarParamsRef[outParamIndex];
+ }
+ outParamIndex++;
+ } // end else if
+ } // end for
+ }
+ catch (IllegalArgumentException & e)
+ {
+ e.ArgumentPosition = ::sal::static_int_cast< sal_Int16, int >( i );
+ throw;
+ }
+ catch (CannotConvertException & e)
+ {
+ e.ArgumentIndex = i;
+ throw;
+ }
+ }
+ else // it is an JScriptObject
+ {
+ int i = 0;
+ try
+ {
+ for( ; i< parameterCount; i++)
+ {
+ // In parameter
+ if( pMethod->pParams[i].bIn == sal_True && ! pMethod->pParams[i].bOut)
+ {
+ anyToVariant( &pVarParams[parameterCount - i -1], Params.getConstArray()[i]);
+ }
+ // Out parameter + in/out parameter
+ else if( pMethod->pParams[i].bOut == sal_True)
+ {
+ CComObject<JScriptOutParam>* pParamObject;
+ if( SUCCEEDED( CComObject<JScriptOutParam>::CreateInstance( &pParamObject)))
+ {
+ CComPtr<IUnknown> pUnk(pParamObject->GetUnknown());
+#ifdef __MINGW32__
+ CComQIPtr<IDispatch, &__uuidof(IDispatch)> pDisp( pUnk);
+#else
+ CComQIPtr<IDispatch> pDisp( pUnk);
+#endif
+
+ pVarParams[ parameterCount - i -1].vt= VT_DISPATCH;
+ pVarParams[ parameterCount - i -1].pdispVal= pDisp;
+ pVarParams[ parameterCount - i -1].pdispVal->AddRef();
+ // if the param is in/out then put the parameter on index 0
+ if( pMethod->pParams[i].bIn == sal_True ) // in / out
+ {
+ CComVariant varParam;
+ anyToVariant( &varParam, Params.getConstArray()[i]);
+ CComDispatchDriver dispDriver( pDisp);
+ if(FAILED( dispDriver.PutPropertyByName( L"0", &varParam)))
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]IUnknownWrapper_Impl::"
+ "invokeWithDispIdUnoTlb\n"
+ "Could not set property \"0\" for the in/out "
+ "param!"));
+
+ }
+ }
+ else
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]IUnknownWrapper_Impl::"
+ "invokeWithDispIdUnoTlb\n"
+ "Could not create out parameter at index: ") +
+ OUString::valueOf((sal_Int32) i));
+ }
+
+ }
+ }
+ }
+ catch (IllegalArgumentException & e)
+ {
+ e.ArgumentPosition = ::sal::static_int_cast< sal_Int16, int >( i );
+ throw;
+ }
+ catch (CannotConvertException & e)
+ {
+ e.ArgumentIndex = i;
+ throw;
+ }
+ }
+ }
+ // No type description Available, that is we have to deal with a COM component,
+ // that does not implements UNO interfaces ( IDispatch based)
+ else
+ {
+ //We should not run into this block, because invokeWithDispIdComTlb should
+ //have been called instead.
+ OSL_ASSERT(0);
+ }
+
+
+ CComVariant varResult;
+ ExcepInfo excepinfo;
+ unsigned int uArgErr;
+ DISPPARAMS dispparams= { pVarParams, NULL, parameterCount, 0};
+ // Get the DISPID
+ FuncDesc aDesc(getTypeInfo());
+ getFuncDesc(sFunctionName, & aDesc);
+ // invoking OLE method
+ hr = m_spDispatch->Invoke(aDesc->memid,
+ IID_NULL,
+ LOCALE_USER_DEFAULT,
+ DISPATCH_METHOD,
+ &dispparams,
+ &varResult,
+ &excepinfo,
+ &uArgErr);
+
+ // converting return value and out parameter back to UNO
+ if (hr == S_OK)
+ {
+ if( outParameterCount && pMethod)
+ {
+ OutParamIndex.realloc( outParameterCount);
+ OutParam.realloc( outParameterCount);
+ sal_Int32 outIndex=0;
+ int i = 0;
+ try
+ {
+ for( ; i < parameterCount; i++)
+ {
+ if( pMethod->pParams[i].bOut )
+ {
+ OutParamIndex[outIndex]= (sal_Int16) i;
+ Any outAny;
+ if( !bJScriptObject)
+ {
+ variantToAny( &pVarParamsRef[outIndex], outAny,
+ Type(pMethod->pParams[i].pTypeRef), sal_False);
+ OutParam[outIndex++]= outAny;
+ }
+ else //JScriptObject
+ {
+ if( pVarParams[i].vt == VT_DISPATCH)
+ {
+ CComDispatchDriver pDisp( pVarParams[i].pdispVal);
+ if( pDisp)
+ {
+ CComVariant varOut;
+ if( SUCCEEDED( pDisp.GetPropertyByName( L"0", &varOut)))
+ {
+ variantToAny( &varOut, outAny,
+ Type(pMethod->pParams[parameterCount - 1 - i].pTypeRef), sal_False);
+ OutParam[outParameterCount - 1 - outIndex++]= outAny;
+ }
+ else
+ bConvRet= sal_False;
+ }
+ else
+ bConvRet= sal_False;
+ }
+ else
+ bConvRet= sal_False;
+ }
+ }
+ if( !bConvRet) break;
+ }
+ }
+ catch(IllegalArgumentException & e)
+ {
+ e.ArgumentPosition = ::sal::static_int_cast< sal_Int16, int >( i );
+ throw;
+ }
+ catch(CannotConvertException & e)
+ {
+ e.ArgumentIndex = i;
+ throw;
+ }
+ }
+ // return value, no type information available
+ if ( bConvRet)
+ {
+ try
+ {
+ if( pMethod )
+ variantToAny(&varResult, ret, Type( pMethod->pReturnTypeRef), sal_False);
+ else
+ variantToAny(&varResult, ret, sal_False);
+ }
+ catch (IllegalArgumentException & e)
+ {
+ e.Message =
+ OUSTR("[automation bridge]IUnknownWrapper_Impl::invokeWithDispIdUnoTlb\n"
+ "Could not convert return value! \n Message: \n") + e.Message;
+ throw;
+ }
+ catch (CannotConvertException & e)
+ {
+ e.Message =
+ OUSTR("[automation bridge]IUnknownWrapper_Impl::invokeWithDispIdUnoTlb\n"
+ "Could not convert return value! \n Message: \n") + e.Message;
+ throw;
+ }
+ }
+ }
+
+ if( !bConvRet) // conversion of return or out parameter failed
+ throw CannotConvertException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Call to COM object failed. Conversion of return or out value failed")),
+ Reference<XInterface>( static_cast<XWeak*>(this), UNO_QUERY ), TypeClass_UNKNOWN,
+ FailReason::UNKNOWN, 0);// lookup error code
+ // conversion of return or out parameter failed
+ switch (hr)
+ {
+ case S_OK:
+ break;
+ case DISP_E_BADPARAMCOUNT:
+ throw IllegalArgumentException();
+ break;
+ case DISP_E_BADVARTYPE:
+ throw RuntimeException();
+ break;
+ case DISP_E_EXCEPTION:
+ throw InvocationTargetException();
+ break;
+ case DISP_E_MEMBERNOTFOUND:
+ throw IllegalArgumentException();
+ break;
+ case DISP_E_NONAMEDARGS:
+ throw IllegalArgumentException();
+ break;
+ case DISP_E_OVERFLOW:
+ throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
+ static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::OUT_OF_RANGE, uArgErr);
+ break;
+ case DISP_E_PARAMNOTFOUND:
+ throw IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
+ static_cast<XWeak*>(this)), ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
+ break;
+ case DISP_E_TYPEMISMATCH:
+ throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")),static_cast<XInterface*>(
+ static_cast<XWeak*>(this)) , TypeClass_UNKNOWN, FailReason::UNKNOWN, uArgErr);
+ break;
+ case DISP_E_UNKNOWNINTERFACE:
+ throw RuntimeException() ;
+ break;
+ case DISP_E_UNKNOWNLCID:
+ throw RuntimeException() ;
+ break;
+ case DISP_E_PARAMNOTOPTIONAL:
+ throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("call to OLE object failed")), static_cast<XInterface*>(
+ static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::NO_DEFAULT_AVAILABLE, uArgErr);
+ break;
+ default:
+ throw RuntimeException();
+ break;
+ }
+
+ return ret;
+}
+
+
+
+ // --------------------------
+// XInitialization
+void SAL_CALL IUnknownWrapper_Impl::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException)
+{
+ // 1.parameter is IUnknown
+ // 2.parameter is a boolean which indicates if the the COM pointer was a IUnknown or IDispatch
+ // 3.parameter is a Sequence<Type>
+ o2u_attachCurrentThread();
+ OSL_ASSERT(aArguments.getLength() == 3);
+
+ m_spUnknown= *(IUnknown**) aArguments[0].getValue();
+#ifdef __MINGW32__
+ m_spUnknown->QueryInterface(IID_IDispatch, reinterpret_cast<LPVOID*>( & m_spDispatch.p));
+#else
+ m_spUnknown.QueryInterface( & m_spDispatch.p);
+#endif
+
+ aArguments[1] >>= m_bOriginalDispatch;
+ aArguments[2] >>= m_seqTypes;
+
+ ITypeInfo* pType = NULL;
+ try
+ {
+ // a COM object implementation that has no TypeInfo is still a legal COM object;
+ // such objects can at least be transported through UNO using the bridge
+ // so we should allow to create wrappers for them as well
+ pType = getTypeInfo();
+ }
+ catch( BridgeRuntimeError& )
+ {}
+ catch( Exception& )
+ {}
+
+ if ( pType )
+ {
+ try
+ {
+ // Get Default member
+ CComBSTR defaultMemberName;
+ if ( SUCCEEDED( pType->GetDocumentation(0, &defaultMemberName, 0, 0, 0 ) ) )
+ {
+ OUString usName(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(defaultMemberName)));
+ FuncDesc aDescGet(pType);
+ FuncDesc aDescPut(pType);
+ VarDesc aVarDesc(pType);
+ // see if this is a property first ( more likely to be a property then a method )
+ getPropDesc( usName, & aDescGet, & aDescPut, & aVarDesc);
+
+ if ( !aDescGet && !aDescPut )
+ {
+ getFuncDesc( usName, &aDescGet );
+ if ( !aDescGet )
+ throw BridgeRuntimeError( OUSTR("[automation bridge]IUnknownWrapper_Impl::initialize() Failed to get Function or Property desc. for " ) + usName );
+ }
+ // now for some funny heuristics to make basic understand what to do
+ // a single aDescGet ( that doesn't take any params ) would be
+ // a read only ( defaultmember ) property e.g. this object
+ // should implement XDefaultProperty
+ // a single aDescGet ( that *does* ) take params is basically a
+ // default method e.g. implement XDefaultMethod
+
+ // a DescPut ( I guess we only really support a default param with '1' param ) as a setValue ( but I guess we can leave it through, the object will fail if we don't get it right anyway )
+ if ( aDescPut || ( aDescGet && aDescGet->cParams == 0 ) )
+ m_bHasDfltProperty = true;
+ if ( aDescGet->cParams > 0 )
+ m_bHasDfltMethod = true;
+ if ( m_bHasDfltProperty || m_bHasDfltMethod )
+ m_sDefaultMember = usName;
+ }
+ }
+ catch ( BridgeRuntimeError & e )
+ {
+ throw RuntimeException( e.message, Reference<XInterface>() );
+ }
+ catch( Exception& e )
+ {
+ throw RuntimeException(
+ OUSTR("[automation bridge] unexpected exception in IUnknownWrapper_Impl::initialiase() error message: \n") + e.Message,
+ Reference<XInterface>() );
+ }
+ }
+}
+
+// UnoConversionUtilities --------------------------------------------------------------------------------
+Reference< XInterface > IUnknownWrapper_Impl::createUnoWrapperInstance()
+{
+ if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
+ {
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+ }
+ else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
+ {
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+ }
+ else
+ return Reference<XInterface>();
+}
+Reference<XInterface> IUnknownWrapper_Impl::createComWrapperInstance()
+{
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+}
+
+
+
+void IUnknownWrapper_Impl::getMethodInfo(const OUString& sName, TypeDescription& methodInfo)
+{
+ TypeDescription desc= getInterfaceMemberDescOfCurrentCall(sName);
+ if( desc.is())
+ {
+ typelib_TypeDescription* pMember= desc.get();
+ if( pMember->eTypeClass == TypeClass_INTERFACE_METHOD )
+ methodInfo= pMember;
+ }
+}
+
+void IUnknownWrapper_Impl::getAttributeInfo(const OUString& sName, TypeDescription& attributeInfo)
+{
+ TypeDescription desc= getInterfaceMemberDescOfCurrentCall(sName);
+ if( desc.is())
+ {
+ typelib_TypeDescription* pMember= desc.get();
+ if( pMember->eTypeClass == TypeClass_INTERFACE_ATTRIBUTE )
+ {
+ attributeInfo= ((typelib_InterfaceAttributeTypeDescription*)pMember)->pAttributeTypeRef;
+ }
+ }
+}
+TypeDescription IUnknownWrapper_Impl::getInterfaceMemberDescOfCurrentCall(const OUString& sName)
+{
+ TypeDescription ret;
+
+ for( sal_Int32 i=0; i < m_seqTypes.getLength(); i++)
+ {
+ TypeDescription _curDesc( m_seqTypes[i]);
+ _curDesc.makeComplete();
+ typelib_InterfaceTypeDescription * pInterface= (typelib_InterfaceTypeDescription*) _curDesc.get();
+ if( pInterface)
+ {
+ typelib_InterfaceMemberTypeDescription* pMember= NULL;
+ //find the member description of the current call
+ for( int i=0; i < pInterface->nAllMembers; i++)
+ {
+ typelib_TypeDescriptionReference* pTypeRefMember = pInterface->ppAllMembers[i];
+ typelib_TypeDescription* pDescMember= NULL;
+ TYPELIB_DANGER_GET( &pDescMember, pTypeRefMember)
+
+ typelib_InterfaceMemberTypeDescription* pInterfaceMember=
+ (typelib_InterfaceMemberTypeDescription*) pDescMember;
+ if( OUString( pInterfaceMember->pMemberName) == sName)
+ {
+ pMember= pInterfaceMember;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pDescMember)
+ }
+
+ if( pMember)
+ {
+ ret= (typelib_TypeDescription*)pMember;
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription*)pMember);
+ }
+ }
+ if( ret.is())
+ break;
+ }
+ return ret;
+}
+
+sal_Bool IUnknownWrapper_Impl::isJScriptObject()
+{
+ if( m_eJScript == JScriptUndefined)
+ {
+ CComDispatchDriver disp( m_spDispatch);
+ if( disp)
+ {
+ CComVariant result;
+ if( SUCCEEDED( disp.GetPropertyByName( JSCRIPT_ID_PROPERTY, &result)))
+ {
+ if(result.vt == VT_BSTR)
+ {
+ CComBSTR name( result.bstrVal);
+ name.ToLower();
+ if( name == CComBSTR(JSCRIPT_ID))
+ m_eJScript= IsJScript;
+ }
+ }
+ }
+ if( m_eJScript == JScriptUndefined)
+ m_eJScript= NoJScript;
+ }
+
+ return m_eJScript == NoJScript ? sal_False : sal_True;
+}
+
+
+
+/** @internal
+ The function ultimately calls IDispatch::Invoke on the wrapped COM object.
+ The COM object does not implement UNO Interfaces ( via IDispatch). This
+ is the case when the OleObjectFactory service has been used to create a
+ component.
+ @exception IllegalArgumentException
+ @exception CannotConvertException
+ @InvocationTargetException
+ @RuntimeException
+ @BridgeRuntimeError
+*/
+Any IUnknownWrapper_Impl::invokeWithDispIdComTlb(const OUString& sFuncName,
+ const Sequence< Any >& Params,
+ Sequence< sal_Int16 >& OutParamIndex,
+ Sequence< Any >& OutParam)
+{
+ // Get type info for the call. It can be a method call or property put or
+ // property get operation.
+ FuncDesc aFuncDesc(getTypeInfo());
+ getFuncDescForInvoke(sFuncName, Params, & aFuncDesc);
+ return invokeWithDispIdComTlb( aFuncDesc, sFuncName, Params, OutParamIndex, OutParam );
+}
+
+Any IUnknownWrapper_Impl::invokeWithDispIdComTlb(FuncDesc& aFuncDesc,
+ const OUString& sFuncName,
+ const Sequence< Any >& Params,
+ Sequence< sal_Int16 >& OutParamIndex,
+ Sequence< Any >& OutParam)
+{
+ Any ret;
+ HRESULT result;
+
+ DISPPARAMS dispparams = {NULL, NULL, 0, 0};
+ CComVariant varResult;
+ ExcepInfo excepinfo;
+ unsigned int uArgErr;
+ sal_Int32 i = 0;
+ sal_Int32 nUnoArgs = Params.getLength();
+ DISPID idPropertyPut = DISPID_PROPERTYPUT;
+ scoped_array<DISPID> arDispidNamedArgs;
+ scoped_array<CComVariant> ptrArgs;
+ scoped_array<CComVariant> ptrRefArgs; // referenced arguments
+ CComVariant * arArgs = NULL;
+ CComVariant * arRefArgs = NULL;
+ sal_Int32 revIndex = 0;
+ bool bVarargParam = false;
+
+
+ //Set the array of DISPIDs for named args if it is a property put operation.
+ //If there are other named arguments another array is set later on.
+ if (aFuncDesc->invkind == INVOKE_PROPERTYPUT
+ || aFuncDesc->invkind == INVOKE_PROPERTYPUTREF)
+ dispparams.rgdispidNamedArgs = & idPropertyPut;
+
+ //Determine the number of named arguments
+ for (int iParam = 0; iParam < nUnoArgs; iParam ++)
+ {
+ const Any & curArg = Params[iParam];
+ if (curArg.getValueType() == getCppuType((NamedArgument*) 0))
+ dispparams.cNamedArgs ++;
+ }
+ //In a property put operation a property value is a named argument (DISPID_PROPERTYPUT).
+ //Therefore the number of named arguments is increased by one.
+ //Although named, the argument is not named in a actual language, such as Basic,
+ //therefore it is never a com.sun.star.bridge.oleautomation.NamedArgument
+ if (aFuncDesc->invkind == DISPATCH_PROPERTYPUT
+ || aFuncDesc->invkind == DISPATCH_PROPERTYPUTREF)
+ dispparams.cNamedArgs ++;
+
+ //Determine the number of all arguments and named arguments
+ if (aFuncDesc->cParamsOpt == -1)
+ {
+ //Attribute vararg is set on this method. "Unlimited" number of args
+ //supported. There can be no optional or defaultvalue on any of the arguments.
+ dispparams.cArgs = nUnoArgs;
+ }
+ else
+ {
+ //If there are namesd arguments, then the dispparams.cArgs
+ //is the number of supplied args, otherwise it is the expected number.
+ if (dispparams.cNamedArgs)
+ dispparams.cArgs = nUnoArgs;
+ else
+ dispparams.cArgs = aFuncDesc->cParams;
+ }
+
+ //check if there are not to many arguments supplied
+ if (::sal::static_int_cast< sal_uInt32, int >( nUnoArgs ) > dispparams.cArgs)
+ {
+ OUStringBuffer buf(256);
+ buf.appendAscii("[automation bridge] There are too many arguments for this method");
+ throw IllegalArgumentException( buf.makeStringAndClear(),
+ Reference<XInterface>(), (sal_Int16) dispparams.cArgs);
+ }
+
+ //Set up the array of DISPIDs (DISPPARAMS::rgdispidNamedArgs)
+ //for the named arguments.
+ //If there is only one named arg and if it is because of a property put
+ //operation, then we need not set up the DISPID array.
+ if (dispparams.cNamedArgs > 0 &&
+ ! (dispparams.cNamedArgs == 1 &&
+ (aFuncDesc->invkind == INVOKE_PROPERTYPUT ||
+ aFuncDesc->invkind == INVOKE_PROPERTYPUT)))
+ {
+ //set up an array containing the member and parameter names
+ //which is then used in ITypeInfo::GetIDsOfNames
+ //First determine the size of the array of names which is passed to
+ //ITypeInfo::GetIDsOfNames. It must hold the method names + the named
+ //args.
+ int nSizeAr = dispparams.cNamedArgs + 1;
+ if (aFuncDesc->invkind == INVOKE_PROPERTYPUT
+ || aFuncDesc->invkind == INVOKE_PROPERTYPUTREF)
+ {
+ nSizeAr = dispparams.cNamedArgs; //counts the DISID_PROPERTYPUT
+ }
+
+ scoped_array<OLECHAR*> saNames(new OLECHAR*[nSizeAr]);
+ OLECHAR ** arNames = saNames.get();
+ arNames[0] = const_cast<OLECHAR*>(reinterpret_cast<LPCOLESTR>(sFuncName.getStr()));
+
+ int cNamedArg = 0;
+ for (size_t iParams = 0; iParams < dispparams.cArgs; iParams ++)
+ {
+ const Any & curArg = Params[iParams];
+ if (curArg.getValueType() == getCppuType((NamedArgument*) 0))
+ {
+ const NamedArgument& arg = *(NamedArgument const*) curArg.getValue();
+ //We put the parameter names in reverse order into the array,
+ //so we can use the DISPID array for DISPPARAMS::rgdispidNamedArgs
+ //The first name in the array is the method name
+ arNames[nSizeAr - 1 - cNamedArg++] = const_cast<OLECHAR*>(reinterpret_cast<LPCOLESTR>(arg.Name.getStr()));
+ }
+ }
+
+ //Prepare the array of DISPIDs for ITypeInfo::GetIDsOfNames
+ //it must be big enough to contain the DISPIDs of the member + parameters
+ arDispidNamedArgs.reset(new DISPID[nSizeAr]);
+ HRESULT hr = getTypeInfo()->GetIDsOfNames(arNames, nSizeAr,
+ arDispidNamedArgs.get());
+ if ( hr == E_NOTIMPL )
+ hr = m_spDispatch->GetIDsOfNames(IID_NULL, arNames, nSizeAr, LOCALE_USER_DEFAULT, arDispidNamedArgs.get() );
+
+ if (hr == S_OK)
+ {
+ // In a "property put" operation, the property value is a named param with the
+ //special DISPID DISPID_PROPERTYPUT
+ if (aFuncDesc->invkind == DISPATCH_PROPERTYPUT
+ || aFuncDesc->invkind == DISPATCH_PROPERTYPUTREF)
+ {
+ //Element at index 0 in the DISPID array must be DISPID_PROPERTYPUT
+ //The first item in the array arDispidNamedArgs is the DISPID for
+ //the method. We replace it with DISPID_PROPERTYPUT.
+ DISPID* arIDs = arDispidNamedArgs.get();
+ arIDs[0] = DISPID_PROPERTYPUT;
+ dispparams.rgdispidNamedArgs = arIDs;
+ }
+ else
+ {
+ //The first item in the array arDispidNamedArgs is the DISPID for
+ //the method. It must be removed
+ DISPID* arIDs = arDispidNamedArgs.get();
+ dispparams.rgdispidNamedArgs = & arIDs[1];
+ }
+ }
+ else if (hr == DISP_E_UNKNOWNNAME)
+ {
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]One of the named arguments is wrong!"),
+ Reference<XInterface>(), 0);
+ }
+ else
+ {
+ throw InvocationTargetException(
+ OUSTR("[automation bridge] ITypeInfo::GetIDsOfNames returned error ")
+ + OUString::valueOf((sal_Int32) hr, 16), Reference<XInterface>(), Any());
+ }
+ }
+
+ //Convert arguments
+ ptrArgs.reset(new CComVariant[dispparams.cArgs]);
+ ptrRefArgs.reset(new CComVariant[dispparams.cArgs]);
+ arArgs = ptrArgs.get();
+ arRefArgs = ptrRefArgs.get();
+ try
+ {
+ for (i = 0; i < (sal_Int32) dispparams.cArgs; i++)
+ {
+ revIndex= dispparams.cArgs - i -1;
+ arRefArgs[revIndex].byref=0;
+ Any anyArg;
+ if ( i < nUnoArgs)
+ anyArg= Params.getConstArray()[i];
+
+ //Test if the current parameter is a "vararg" parameter.
+ if (bVarargParam || (aFuncDesc->cParamsOpt == -1 &&
+ aFuncDesc->cParams == (i + 1)))
+ { //This parameter is from the variable argument list. There is no
+ //type info available, except that it must be a VARIANT
+ bVarargParam = true;
+ }
+
+ unsigned short paramFlags = PARAMFLAG_FOPT | PARAMFLAG_FIN;
+ VARTYPE varType = VT_VARIANT;
+ if ( ! bVarargParam)
+ {
+ paramFlags =
+ aFuncDesc->lprgelemdescParam[i].paramdesc.wParamFlags;
+ varType = getElementTypeDesc(
+ & aFuncDesc->lprgelemdescParam[i].tdesc);
+ }
+ //Make sure that there is a UNO parameter for every
+ // expected parameter. If there is no UNO parameter where the
+ // called function expects one, then it must be optional. Otherwise
+ // its a UNO programming error.
+ if (i >= nUnoArgs && !(paramFlags & PARAMFLAG_FOPT))
+ {
+ OUStringBuffer buf(256);
+ buf.appendAscii("ole automation bridge: The called function expects an argument at"
+ "position: "); //a different number of arguments")),
+ buf.append(OUString::valueOf((sal_Int32) i));
+ buf.appendAscii(" (index starting at 0).");
+ throw IllegalArgumentException( buf.makeStringAndClear(),
+ Reference<XInterface>(), (sal_Int16) i);
+ }
+ //make sure we get no void any for an in parameter. In StarBasic
+ //this may be caused by
+ // Dim arg
+ // obj.func(arg)
+ //A void any is allowed if the parameter is optional
+ if ( ! (aFuncDesc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FOPT)
+ && (i < nUnoArgs) && (paramFlags & PARAMFLAG_FIN) &&
+ Params.getConstArray()[i].getValueTypeClass() == TypeClass_VOID)
+ {
+ OUStringBuffer buf(256);
+ buf.appendAscii("ole automation bridge: The argument at position: ");
+ buf.append(OUString::valueOf((sal_Int32) i));
+ buf.appendAscii(" (index starts with 0) is uninitialized.");
+ throw IllegalArgumentException( buf.makeStringAndClear(),
+ Reference<XInterface>(), (sal_Int16) i);
+ }
+
+ // Property Put arguments
+ if (anyArg.getValueType() == getCppuType((PropertyPutArgument*)0))
+ {
+ PropertyPutArgument arg;
+ anyArg >>= arg;
+ anyArg <<= arg.Value;
+ }
+ // named argument
+ if (anyArg.getValueType() == getCppuType((NamedArgument*) 0))
+ {
+ NamedArgument aNamedArgument;
+ anyArg >>= aNamedArgument;
+ anyArg <<= aNamedArgument.Value;
+ }
+ // out param
+ if (paramFlags & PARAMFLAG_FOUT &&
+ ! (paramFlags & PARAMFLAG_FIN) )
+ {
+ VARTYPE type = ::sal::static_int_cast< VARTYPE, int >( varType ^ VT_BYREF );
+ if (i < nUnoArgs)
+ {
+ arRefArgs[revIndex].vt= type;
+ }
+ else
+ {
+ //optional arg
+ arRefArgs[revIndex].vt = VT_ERROR;
+ arRefArgs[revIndex].scode = DISP_E_PARAMNOTFOUND;
+ }
+ if( type == VT_VARIANT )
+ {
+ arArgs[revIndex].vt= VT_VARIANT | VT_BYREF;
+ arArgs[revIndex].byref= &arRefArgs[revIndex];
+ }
+ else
+ {
+ arArgs[revIndex].vt= varType;
+ if (type == VT_DECIMAL)
+ arArgs[revIndex].byref= & arRefArgs[revIndex].decVal;
+ else
+ arArgs[revIndex].byref= & arRefArgs[revIndex].byref;
+ }
+ }
+ // in/out + in byref params
+ else if (varType & VT_BYREF)
+ {
+ VARTYPE type = ::sal::static_int_cast< VARTYPE, int >( varType ^ VT_BYREF );
+ CComVariant var;
+
+ if (i < nUnoArgs && anyArg.getValueTypeClass() != TypeClass_VOID)
+ {
+ anyToVariant( & arRefArgs[revIndex], anyArg, type);
+ }
+ else if (paramFlags & PARAMFLAG_FHASDEFAULT)
+ {
+ //optional arg with default
+ VariantCopy( & arRefArgs[revIndex],
+ & aFuncDesc->lprgelemdescParam[i].paramdesc.
+ pparamdescex->varDefaultValue);
+ }
+ else
+ {
+ //optional arg
+ //e.g: call func(x) in basic : func() ' no arg supplied
+ OSL_ASSERT(paramFlags & PARAMFLAG_FOPT);
+ arRefArgs[revIndex].vt = VT_ERROR;
+ arRefArgs[revIndex].scode = DISP_E_PARAMNOTFOUND;
+ }
+
+ // Set the converted arguments in the array which will be
+ // DISPPARAMS::rgvarg
+ // byref arg VT_XXX |VT_BYREF
+ arArgs[revIndex].vt = varType;
+ if (revIndex == 0 && aFuncDesc->invkind == INVOKE_PROPERTYPUT)
+ {
+ arArgs[revIndex] = arRefArgs[revIndex];
+ }
+ else if (type == VT_DECIMAL)
+ {
+ arArgs[revIndex].byref= & arRefArgs[revIndex].decVal;
+ }
+ else if (type == VT_VARIANT)
+ {
+ if ( ! (paramFlags & PARAMFLAG_FOUT))
+ arArgs[revIndex] = arRefArgs[revIndex];
+ else
+ arArgs[revIndex].byref = & arRefArgs[revIndex];
+ }
+ else
+ {
+ arArgs[revIndex].byref = & arRefArgs[revIndex].byref;
+ arArgs[revIndex].vt = ::sal::static_int_cast< VARTYPE, int >( arRefArgs[revIndex].vt | VT_BYREF );
+ }
+
+ }
+ // in parameter no VT_BYREF except for array, interfaces
+ else
+ { // void any stands for optional param
+ if (i < nUnoArgs && anyArg.getValueTypeClass() != TypeClass_VOID)
+ {
+ anyToVariant( & arArgs[revIndex], anyArg, varType);
+ }
+ //optional arg but no void any supplied
+ //Basic: obj.func() ' first parameter left out because it is optional
+ else if (paramFlags & PARAMFLAG_FHASDEFAULT)
+ {
+ //optional arg with defaulteithter as direct arg : VT_XXX or
+ VariantCopy( & arArgs[revIndex],
+ & aFuncDesc->lprgelemdescParam[i].paramdesc.
+ pparamdescex->varDefaultValue);
+ }
+ else
+ {
+ OSL_ASSERT(paramFlags & PARAMFLAG_FOPT);
+ arArgs[revIndex].vt = VT_ERROR;
+ arArgs[revIndex].scode = DISP_E_PARAMNOTFOUND;
+ }
+ }
+ }
+ }
+ catch (IllegalArgumentException & e)
+ {
+ e.ArgumentPosition = ::sal::static_int_cast< sal_Int16, sal_Int32 >( i );
+ throw;
+ }
+ catch (CannotConvertException & e)
+ {
+ e.ArgumentIndex = i;
+ throw;
+ }
+ dispparams.rgvarg= arArgs;
+ // invoking OLE method
+ DWORD localeId = LOCALE_USER_DEFAULT;
+ result = m_spDispatch->Invoke(aFuncDesc->memid,
+ IID_NULL,
+ localeId,
+ ::sal::static_int_cast< WORD, INVOKEKIND >( aFuncDesc->invkind ),
+ &dispparams,
+ &varResult,
+ &excepinfo,
+ &uArgErr);
+
+ // converting return value and out parameter back to UNO
+ if (result == S_OK)
+ {
+
+ // allocate space for the out param Sequence and indices Sequence
+ int outParamsCount= 0; // includes in/out parameter
+ for (int i = 0; i < aFuncDesc->cParams; i++)
+ {
+ if (aFuncDesc->lprgelemdescParam[i].paramdesc.wParamFlags &
+ PARAMFLAG_FOUT)
+ outParamsCount++;
+ }
+
+ OutParamIndex.realloc(outParamsCount);
+ OutParam.realloc(outParamsCount);
+ // Convert out params
+ if (outParamsCount)
+ {
+ int outParamIndex=0;
+ for (int paramIndex = 0; paramIndex < nUnoArgs; paramIndex ++)
+ {
+ //Determine the index within the method sinature
+ int realParamIndex = paramIndex;
+ int revParamIndex = dispparams.cArgs - paramIndex - 1;
+ if (Params[paramIndex].getValueType()
+ == getCppuType((NamedArgument*) 0))
+ {
+ //dispparams.rgdispidNamedArgs contains the mapping from index
+ //of named args list to index of parameter list
+ realParamIndex = dispparams.rgdispidNamedArgs[revParamIndex];
+ }
+
+ // no named arg, always come before named args
+ if (! (aFuncDesc->lprgelemdescParam[realParamIndex].paramdesc.wParamFlags
+ & PARAMFLAG_FOUT))
+ continue;
+ Any outAny;
+ // variantToAny is called with the "reduce range" parameter set to sal_False.
+ // That causes VT_I4 values not to be converted down to a "lower" type. That
+ // feature exist for JScript only because it only uses VT_I4 for integer types.
+ try
+ {
+ variantToAny( & arRefArgs[revParamIndex], outAny, sal_False );
+ }
+ catch (IllegalArgumentException & e)
+ {
+ e.ArgumentPosition = (sal_Int16)paramIndex;
+ throw;
+ }
+ catch (CannotConvertException & e)
+ {
+ e.ArgumentIndex = paramIndex;
+ throw;
+ }
+ OutParam[outParamIndex] = outAny;
+ OutParamIndex[outParamIndex] = ::sal::static_int_cast< sal_Int16, int >( paramIndex );
+ outParamIndex++;
+ }
+ OutParam.realloc(outParamIndex);
+ OutParamIndex.realloc(outParamIndex);
+ }
+ // Return value
+ variantToAny(&varResult, ret, sal_False);
+ }
+
+ // map error codes to exceptions
+ OUString message;
+ switch (result)
+ {
+ case S_OK:
+ break;
+ case DISP_E_BADPARAMCOUNT:
+ throw IllegalArgumentException(OUSTR("[automation bridge] Wrong "
+ "number of arguments. Object returned DISP_E_BADPARAMCOUNT."),
+ 0, 0);
+ break;
+ case DISP_E_BADVARTYPE:
+ throw RuntimeException(OUSTR("[automation bridge] One or more "
+ "arguments have the wrong type. Object returned "
+ "DISP_E_BADVARTYPE."), 0);
+ break;
+ case DISP_E_EXCEPTION:
+ {
+ message = OUSTR("[automation bridge]: ");
+ message += OUString(reinterpret_cast<const sal_Unicode*>(excepinfo.bstrDescription),
+ ::SysStringLen(excepinfo.bstrDescription));
+
+ // Add for VBA, to throw an exception with the correct error code and message.
+ sal_Int32 nErrorCode = excepinfo.wCode;
+ if ( nErrorCode == 0 )
+ {
+ // The low 16-bit of scode describing the error or warning.
+ nErrorCode = ( excepinfo.scode & 0xFFFF );
+ }
+ BasicErrorException aBasicErrExp(message, Reference<XInterface>(), nErrorCode, message);
+ throw InvocationTargetException(message, Reference<XInterface>(), makeAny(aBasicErrExp));
+ // End add
+
+ break;
+ }
+ case DISP_E_MEMBERNOTFOUND:
+ message = OUSTR("[automation bridge]: A function with the name \"")
+ + sFuncName + OUSTR("\" is not supported. Object returned "
+ "DISP_E_MEMBERNOTFOUND.");
+ throw IllegalArgumentException(message, 0, 0);
+ break;
+ case DISP_E_NONAMEDARGS:
+ throw IllegalArgumentException(OUSTR("[automation bridge] Object "
+ "returned DISP_E_NONAMEDARGS"),0, ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
+ break;
+ case DISP_E_OVERFLOW:
+ throw CannotConvertException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[automation bridge] Call failed.")),
+ static_cast<XInterface*>(
+ static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::OUT_OF_RANGE, uArgErr);
+ break;
+ case DISP_E_PARAMNOTFOUND:
+ throw IllegalArgumentException(OUSTR("[automation bridge]Call failed."
+ "Object returned DISP_E_PARAMNOTFOUND."),
+ 0, ::sal::static_int_cast< sal_Int16, unsigned int >( uArgErr ));
+ break;
+ case DISP_E_TYPEMISMATCH:
+ throw CannotConvertException(OUSTR("[automation bridge] Call failed. "
+ "Object returned DISP_E_TYPEMISMATCH"),
+ static_cast<XInterface*>(
+ static_cast<XWeak*>(this)) , TypeClass_UNKNOWN, FailReason::UNKNOWN, uArgErr);
+ break;
+ case DISP_E_UNKNOWNINTERFACE:
+ throw RuntimeException(OUSTR("[automation bridge] Call failed. "
+ "Object returned DISP_E_UNKNOWNINTERFACE."),0);
+ break;
+ case DISP_E_UNKNOWNLCID:
+ throw RuntimeException(OUSTR("[automation bridge] Call failed. "
+ "Object returned DISP_E_UNKNOWNLCID."),0);
+ break;
+ case DISP_E_PARAMNOTOPTIONAL:
+ throw CannotConvertException(OUSTR("[automation bridge] Call failed."
+ "Object returned DISP_E_PARAMNOTOPTIONAL"),
+ static_cast<XInterface*>(static_cast<XWeak*>(this)),
+ TypeClass_UNKNOWN, FailReason::NO_DEFAULT_AVAILABLE, uArgErr);
+ break;
+ default:
+ throw RuntimeException();
+ break;
+ }
+
+ return ret;
+}
+
+void IUnknownWrapper_Impl::getFuncDescForInvoke(const OUString & sFuncName,
+ const Sequence<Any> & seqArgs,
+ FUNCDESC** pFuncDesc)
+{
+ int nUnoArgs = seqArgs.getLength();
+ const Any * arArgs = seqArgs.getConstArray();
+ ITypeInfo* pInfo = getTypeInfo();
+
+ //If the last of the positional arguments is a PropertyPutArgument
+ //then obtain the type info for the property put operation.
+
+ //The property value is always the last argument, in a positional argument list
+ //or in a list of named arguments. A PropertyPutArgument is actually a named argument
+ //hence it must not be put in an extra NamedArgument structure
+ if (nUnoArgs > 0 &&
+ arArgs[nUnoArgs - 1].getValueType() == getCppuType((PropertyPutArgument*) 0))
+ {
+ // DISPATCH_PROPERTYPUT
+ FuncDesc aDescGet(pInfo);
+ FuncDesc aDescPut(pInfo);
+ VarDesc aVarDesc(pInfo);
+ getPropDesc(sFuncName, & aDescGet, & aDescPut, & aVarDesc);
+ if ( ! aDescPut)
+ {
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge] The object does not have a writeable property: ")
+ + sFuncName, Reference<XInterface>(), 0);
+ }
+ *pFuncDesc = aDescPut.Detach();
+ }
+ else
+ { // DISPATCH_METHOD
+ FuncDesc aFuncDesc(pInfo);
+ getFuncDesc(sFuncName, & aFuncDesc);
+ if ( ! aFuncDesc)
+ {
+ // Fallback: DISPATCH_PROPERTYGET can mostly be called as
+ // DISPATCH_METHOD
+ ITypeInfo * pInfo = getTypeInfo();
+ FuncDesc aDescPut(pInfo);
+ VarDesc aVarDesc(pInfo);
+ getPropDesc(sFuncName, & aFuncDesc, & aDescPut, & aVarDesc);
+ if ( ! aFuncDesc )
+ {
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge] The object does not have a function"
+ "or readable property \"")
+ + sFuncName, Reference<XInterface>(), 0);
+ }
+ }
+ *pFuncDesc = aFuncDesc.Detach();
+ }
+}
+bool IUnknownWrapper_Impl::getDispid(const OUString& sFuncName, DISPID * id)
+{
+ OSL_ASSERT(m_spDispatch);
+ LPOLESTR lpsz = const_cast<LPOLESTR> (reinterpret_cast<LPCOLESTR>(sFuncName.getStr()));
+ HRESULT hr = m_spDispatch->GetIDsOfNames(IID_NULL, &lpsz, 1, LOCALE_USER_DEFAULT, id);
+ return hr == S_OK ? true : false;
+}
+void IUnknownWrapper_Impl::getFuncDesc(const OUString & sFuncName, FUNCDESC ** pFuncDesc)
+
+{
+ OSL_ASSERT( * pFuncDesc == 0);
+ buildComTlbIndex();
+ typedef TLBFuncIndexMap::const_iterator cit;
+ typedef TLBFuncIndexMap::iterator it;
+ //We assume there is only one entry with the function name. A property
+ //would have two entries.
+ cit itIndex= m_mapComFunc.find(sFuncName);
+ if (itIndex == m_mapComFunc.end())
+ {
+ //try case insensive with IDispatch::GetIDsOfNames
+ DISPID id;
+ if (getDispid(sFuncName, &id))
+ {
+ CComBSTR memberName;
+ unsigned int pcNames=0;
+ // get the case sensitive name
+ if( SUCCEEDED(getTypeInfo()->GetNames( id, & memberName, 1, &pcNames)))
+ {
+ //get the associated index and add an entry to the map
+ //with the name sFuncName which differs in the casing of the letters to
+ //the actual name as obtained from ITypeInfo
+ OUString sRealName(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName)));
+ cit itOrg = m_mapComFunc.find(sRealName);
+ OSL_ASSERT(itOrg != m_mapComFunc.end());
+ // maybe this is a property, if so we need
+ // to store either both id's ( put/get ) or
+ // just the get. Storing both is more consistent
+ pair<cit, cit> pItems = m_mapComFunc.equal_range( sRealName );
+ for ( ;pItems.first != pItems.second; ++pItems.first )
+ m_mapComFunc.insert( TLBFuncIndexMap::value_type ( make_pair(sFuncName, pItems.first->second ) ));
+ itIndex =
+ m_mapComFunc.find( sFuncName );
+ }
+ }
+ }
+
+#if OSL_DEBUG_LEVEL >= 1
+ // There must only be one entry if sFuncName represents a function or two
+ // if it is a property
+ pair<cit, cit> p = m_mapComFunc.equal_range(sFuncName.toAsciiLowerCase());
+ int numEntries = 0;
+ for ( ;p.first != p.second; p.first ++, numEntries ++);
+ OSL_ASSERT( ! (numEntries > 3) );
+#endif
+ if( itIndex != m_mapComFunc.end())
+ {
+ ITypeInfo* pType= getTypeInfo();
+ FUNCDESC * pDesc = NULL;
+ if (SUCCEEDED(pType->GetFuncDesc(itIndex->second, & pDesc)))
+ {
+ if (pDesc->invkind == INVOKE_FUNC)
+ {
+ (*pFuncDesc) = pDesc;
+ }
+ else
+ {
+ pType->ReleaseFuncDesc(pDesc);
+ }
+ }
+ else
+ {
+ throw BridgeRuntimeError(OUSTR("[automation bridge] Could not get "
+ "FUNCDESC for ") + sFuncName);
+ }
+ }
+ //else no entry found for sFuncName, pFuncDesc will not be filled in
+}
+
+void IUnknownWrapper_Impl::getPropDesc(const OUString & sFuncName, FUNCDESC ** pFuncDescGet,
+ FUNCDESC** pFuncDescPut, VARDESC** pVarDesc)
+{
+ OSL_ASSERT( * pFuncDescGet == 0 && * pFuncDescPut == 0);
+ buildComTlbIndex();
+ typedef TLBFuncIndexMap::const_iterator cit;
+ pair<cit, cit> p = m_mapComFunc.equal_range(sFuncName);
+ if (p.first == m_mapComFunc.end())
+ {
+ //try case insensive with IDispatch::GetIDsOfNames
+ DISPID id;
+ if (getDispid(sFuncName, &id))
+ {
+ CComBSTR memberName;
+ unsigned int pcNames=0;
+ // get the case sensitive name
+ if( SUCCEEDED(getTypeInfo()->GetNames( id, & memberName, 1, &pcNames)))
+ {
+ //As opposed to getFuncDesc, we do not add the value because we would
+ // need to find the get and set description for the property. This would
+ //mean to iterate over all FUNCDESCs again.
+ p = m_mapComFunc.equal_range(OUString(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName))));
+ }
+ }
+ }
+
+ for ( int i = 0 ;p.first != p.second; p.first ++, i ++)
+ {
+ // There are a maximum of two entries, property put and property get
+ OSL_ASSERT( ! (i > 2) );
+ ITypeInfo* pType= getTypeInfo();
+ FUNCDESC * pFuncDesc = NULL;
+ if (SUCCEEDED( pType->GetFuncDesc(p.first->second, & pFuncDesc)))
+ {
+ if (pFuncDesc->invkind == INVOKE_PROPERTYGET)
+ {
+ (*pFuncDescGet) = pFuncDesc;
+ }
+ else if (pFuncDesc->invkind == INVOKE_PROPERTYPUT ||
+ pFuncDesc->invkind == INVOKE_PROPERTYPUTREF)
+ {
+ //a property can have 3 entries, put, put ref, get
+ // If INVOKE_PROPERTYPUTREF or INVOKE_PROPERTYPUT is used
+ //depends on what is found first.
+ if ( * pFuncDescPut)
+ {
+ //we already have found one
+ pType->ReleaseFuncDesc(pFuncDesc);
+ }
+ else
+ {
+ (*pFuncDescPut) = pFuncDesc;
+ }
+ }
+ else
+ {
+ pType->ReleaseFuncDesc(pFuncDesc);
+ }
+ }
+ //ITypeInfo::GetFuncDesc may even provide a funcdesc for a VARDESC
+ // with invkind = INVOKE_FUNC. Since this function should only return
+ //a value for a real property (XInvokation::hasMethod, ..::hasProperty
+ //we need to make sure that sFuncName represents a real property.
+ VARDESC * pVD = NULL;
+ if (SUCCEEDED(pType->GetVarDesc(p.first->second, & pVD)))
+ (*pVarDesc) = pVD;
+ }
+ //else no entry for sFuncName, pFuncDesc will not be filled in
+}
+
+VARTYPE IUnknownWrapper_Impl::getUserDefinedElementType( ITypeInfo* pTypeInfo, const DWORD nHrefType )
+{
+ VARTYPE _type( VT_NULL );
+ if ( pTypeInfo )
+ {
+ CComPtr<ITypeInfo> spRefInfo;
+ pTypeInfo->GetRefTypeInfo( nHrefType, &spRefInfo.p );
+ if ( spRefInfo )
+ {
+ TypeAttr attr( spRefInfo );
+ spRefInfo->GetTypeAttr( &attr );
+ if ( attr->typekind == TKIND_ENUM )
+ {
+ // We use the type of the first enum value.
+ if ( attr->cVars == 0 )
+ {
+ throw BridgeRuntimeError(OUSTR("[automation bridge] Could not obtain type description"));
+ }
+ VarDesc var( spRefInfo );
+ spRefInfo->GetVarDesc( 0, &var );
+ _type = var->lpvarValue->vt;
+ }
+ else if ( attr->typekind == TKIND_INTERFACE )
+ {
+ _type = VT_UNKNOWN;
+ }
+ else if ( attr->typekind == TKIND_DISPATCH )
+ {
+ _type = VT_DISPATCH;
+ }
+ else if ( attr->typekind == TKIND_ALIAS )
+ {
+ // TKIND_ALIAS is a type that is an alias for another type. So get that alias type.
+ _type = getUserDefinedElementType( pTypeInfo, attr->tdescAlias.hreftype );
+ }
+ else
+ {
+ throw BridgeRuntimeError( OUSTR("[automation bridge] Unhandled user defined type.") );
+ }
+ }
+ }
+ return _type;
+}
+
+VARTYPE IUnknownWrapper_Impl::getElementTypeDesc(const TYPEDESC *desc)
+{
+ VARTYPE _type( VT_NULL );
+
+ if (desc->vt == VT_PTR)
+ {
+ _type = getElementTypeDesc(desc->lptdesc);
+ _type |= VT_BYREF;
+ }
+ else if (desc->vt == VT_SAFEARRAY)
+ {
+ _type = getElementTypeDesc(desc->lptdesc);
+ _type |= VT_ARRAY;
+ }
+ else if (desc->vt == VT_USERDEFINED)
+ {
+ ITypeInfo* thisInfo = getTypeInfo(); //kept by this instance
+ _type = getUserDefinedElementType( thisInfo, desc->hreftype );
+ }
+ else
+ {
+ _type = desc->vt;
+ }
+ return _type;
+}
+
+void IUnknownWrapper_Impl::buildComTlbIndex()
+{
+ if ( ! m_bComTlbIndexInit)
+ {
+ MutexGuard guard(getBridgeMutex());
+ {
+ if ( ! m_bComTlbIndexInit)
+ {
+ OUString sError;
+ ITypeInfo* pType= getTypeInfo();
+ TypeAttr typeAttr(pType);
+ if( SUCCEEDED( pType->GetTypeAttr( &typeAttr)))
+ {
+ for( long i= 0; i < typeAttr->cFuncs; i++)
+ {
+ FuncDesc funcDesc(pType);
+ if( SUCCEEDED( pType->GetFuncDesc( i, &funcDesc)))
+ {
+ CComBSTR memberName;
+ unsigned int pcNames=0;
+ if( SUCCEEDED(pType->GetNames( funcDesc->memid, & memberName, 1, &pcNames)))
+ {
+ OUString usName(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName)));
+ m_mapComFunc.insert( TLBFuncIndexMap::value_type( usName, i));
+ }
+ else
+ {
+ sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
+ "ITypeInfo::GetNames failed.");
+ }
+ }
+ else
+ sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
+ "ITypeInfo::GetFuncDesc failed.");
+ }
+
+ //If we create an Object in JScript and a a property then it
+ //has VARDESC instead of FUNCDESC
+ for (long i = 0; i < typeAttr->cVars; i++)
+ {
+ VarDesc varDesc(pType);
+ if (SUCCEEDED(pType->GetVarDesc(i, & varDesc)))
+ {
+ CComBSTR memberName;
+ unsigned int pcNames = 0;
+ if (SUCCEEDED(pType->GetNames(varDesc->memid, & memberName, 1, &pcNames)))
+ {
+ if (varDesc->varkind == VAR_DISPATCH)
+ {
+ OUString usName(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(memberName)));
+ m_mapComFunc.insert(TLBFuncIndexMap::value_type(
+ usName, i));
+ }
+ }
+ else
+ {
+ sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
+ "ITypeInfo::GetNames failed.");
+ }
+ }
+ else
+ sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
+ "ITypeInfo::GetVarDesc failed.");
+
+ }
+ }
+ else
+ sError = OUSTR("[automation bridge] IUnknownWrapper_Impl::buildComTlbIndex, " \
+ "ITypeInfo::GetTypeAttr failed.");
+
+ if (sError.getLength())
+ {
+ throw BridgeRuntimeError(sError);
+ }
+
+ m_bComTlbIndexInit = true;
+ }
+ }
+ }
+}
+
+ITypeInfo* IUnknownWrapper_Impl::getTypeInfo()
+{
+ if( !m_spDispatch)
+ {
+ throw BridgeRuntimeError(OUSTR("The object has no IDispatch interface!"));
+ }
+
+ if( !m_spTypeInfo )
+ {
+ MutexGuard guard(getBridgeMutex());
+ if( ! m_spTypeInfo)
+ {
+ CComPtr< ITypeInfo > spType;
+ if( SUCCEEDED( m_spDispatch->GetTypeInfo( 0, LOCALE_USER_DEFAULT, &spType.p)))
+
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+
+ //If this is a dual interface then TYPEATTR::typekind is usually TKIND_INTERFACE
+ //We need to get the type description for TKIND_DISPATCH
+ TypeAttr typeAttr(spType.p);
+ if( SUCCEEDED(spType->GetTypeAttr( &typeAttr)))
+ {
+ if (typeAttr->typekind == TKIND_INTERFACE &&
+ typeAttr->wTypeFlags & TYPEFLAG_FDUAL)
+ {
+ HREFTYPE refDispatch;
+ if (SUCCEEDED(spType->GetRefTypeOfImplType(::sal::static_int_cast< UINT, int >( -1 ), &refDispatch)))
+ {
+ CComPtr<ITypeInfo> spTypeDisp;
+ if (SUCCEEDED(spType->GetRefTypeInfo(refDispatch, & spTypeDisp)))
+ m_spTypeInfo= spTypeDisp;
+ }
+ else
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] Could not obtain type information "
+ "for dispatch interface." ));
+ }
+ }
+ else if (typeAttr->typekind == TKIND_DISPATCH)
+ {
+ m_spTypeInfo= spType;
+ }
+ else
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] Automation object does not "
+ "provide type information."));
+ }
+ }
+ }
+ else
+ {
+ throw BridgeRuntimeError(OUSTR("[automation bridge]The dispatch object does not "
+ "support ITypeInfo!"));
+ }
+ }
+ }
+ return m_spTypeInfo;
+}
+
+} // end namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/oleobjw.hxx b/extensions/source/ole/oleobjw.hxx
new file mode 100644
index 000000000000..0f926695eaab
--- /dev/null
+++ b/extensions/source/ole/oleobjw.hxx
@@ -0,0 +1,284 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __OLEOBJW_HXX
+#define __OLEOBJW_HXX
+#include "ole2uno.hxx"
+
+#ifdef _MSC_VER
+#pragma warning (push,1)
+#pragma warning (disable:4548)
+#endif
+
+#include <tools/presys.h>
+#define _WIN32_WINNT 0x0403
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#undef _DEBUG
+#endif
+#include <atlbase.h>
+#include <vector>
+#include <hash_map>
+#include <tools/postsys.h>
+
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/implbase6.hxx>
+
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>
+#include <com/sun/star/script//XAutomationInvocation.hpp>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/script/XDefaultProperty.hpp>
+#include <com/sun/star/script/XDefaultMethod.hpp>
+
+#include <typelib/typedescription.hxx>
+#include "unoconversionutilities.hxx"
+#include "windata.hxx"
+using namespace cppu;
+using namespace rtl;
+using namespace std;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::bridge;
+using namespace com::sun::star::bridge::oleautomation;
+
+namespace ole_adapter
+{
+
+
+
+typedef hash_map<OUString, pair<DISPID, unsigned short>, hashOUString_Impl, equalOUString_Impl> DispIdMap;
+
+typedef hash_multimap<OUString, unsigned int, hashOUString_Impl, equalOUString_Impl> TLBFuncIndexMap;
+
+// This class wraps an IDispatch and maps XInvocation calls to IDispatch calls on the wrapped object.
+// If m_TypeDescription is set then this class represents an UNO interface implemented in a COM component.
+// The interface is not a real interface in terms of an abstract class but is realized through IDispatch.
+class IUnknownWrapper_Impl : public WeakImplHelper6<XAutomationInvocation, XBridgeSupplier2, XInitialization, XAutomationObject, XDefaultProperty, XDefaultMethod>,
+
+ public UnoConversionUtilities<IUnknownWrapper_Impl>
+
+{
+public:
+ IUnknownWrapper_Impl(Reference<XMultiServiceFactory> &xFactory,
+ sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass);
+
+ ~IUnknownWrapper_Impl();
+
+ //XInterface
+ Any SAL_CALL queryInterface(const Type& t)
+ throw (RuntimeException);
+
+ // XInvokation
+ virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection( )
+ throw(RuntimeException);
+ virtual Any SAL_CALL invoke( const OUString& aFunctionName,
+ const Sequence< Any >& aParams,
+ Sequence< sal_Int16 >& aOutParamIndex,
+ Sequence< Any >& aOutParam )
+ throw(IllegalArgumentException, CannotConvertException,
+ InvocationTargetException, RuntimeException);
+ virtual void SAL_CALL setValue( const OUString& aPropertyName,
+ const Any& aValue )
+ throw(UnknownPropertyException, CannotConvertException,
+ InvocationTargetException, RuntimeException);
+ virtual Any SAL_CALL getValue( const OUString& aPropertyName )
+ throw(UnknownPropertyException, RuntimeException);
+ virtual sal_Bool SAL_CALL hasMethod( const OUString& aName )
+ throw(RuntimeException);
+ virtual sal_Bool SAL_CALL hasProperty( const OUString& aName )
+ throw(RuntimeException);
+
+ // XBridgeSupplier2
+ // This interface is implemented to provide a safe way to obtain the original
+ // IUnknown or IDispatch within the function anyToVariant. The function asks
+ // every UNO object for its XBridgeSupplier2 and if it is available uses it to convert
+ // the object with its own supplier.
+ virtual Any SAL_CALL createBridge( const Any& modelDepObject,
+ const Sequence< sal_Int8 >& aProcessId,
+ sal_Int16 sourceModelType,
+ sal_Int16 destModelType )
+ throw(IllegalArgumentException, RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any >& aArguments )
+ throw(Exception, RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDefaultPropertyName( ) throw (::com::sun::star::uno::RuntimeException) { return m_sDefaultMember; }
+protected:
+ virtual ::rtl::OUString SAL_CALL getDefaultMethodName( ) throw (::com::sun::star::uno::RuntimeException) { return m_sDefaultMember; }
+
+ virtual ::com::sun::star::uno::Any SAL_CALL invokeGetProperty( const ::rtl::OUString& aFunctionName, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams, ::com::sun::star::uno::Sequence< ::sal_Int16 >& aOutParamIndex, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::script::CannotConvertException, ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL invokePutProperty( const ::rtl::OUString& aFunctionName, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams, ::com::sun::star::uno::Sequence< ::sal_Int16 >& aOutParamIndex, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::script::CannotConvertException, ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // ----------------------------------------------------------------------------
+ virtual Any invokeWithDispIdUnoTlb(const OUString& sFunctionName,
+ const Sequence< Any >& Params,
+ Sequence<sal_Int16 >& OutParamIndex,
+ Sequence< Any >& OutParam);
+ // Is used for OleObjectFactory service
+ virtual Any invokeWithDispIdComTlb(const OUString& sFuncName,
+ const Sequence< Any >& Params,
+ Sequence< sal_Int16 >& OutParamIndex,
+ Sequence< Any >& OutParam);
+
+ Any IUnknownWrapper_Impl::invokeWithDispIdComTlb(FuncDesc& aFuncDesc,
+ const OUString& sFuncName,
+ const Sequence< Any >& Params,
+ Sequence< sal_Int16 >& OutParamIndex,
+ Sequence< Any >& OutParam);
+
+// virtual void setValueWithDispId(DISPID dispID, const Any& Value);
+
+// virtual Any getValueWithDispId(const OUString& sName, DISPID dispID);
+
+
+ // UnoConversionUtilities -------------------------------------------------------------------------------
+ virtual Reference<XInterface> createUnoWrapperInstance();
+ virtual Reference<XInterface> createComWrapperInstance();
+
+ /**Obtains a FUNCDESC structure for a function.
+ Fills the FUNCDESC structure if ITypeInfo provides information for
+ the function of name sFuncName or pFuncDesc will not be filled in.
+ May throw a BridgeRuntimeError.
+ */
+ void getFuncDesc(const OUString & sFuncName, FUNCDESC ** pFuncDesc);
+ /**Obtains a FUNCDESC structures or a VARDESC structure
+ for a property. pFuncDescPut may also contain
+ a structure for a "propertyputref" operation. If pFuncDesc contains a
+ "put ref" or "put" FUNCDESC depends on what was found first in the type
+ description.
+ Fills the FUNCDESC structure if ITypeInfo provides information for
+ the respective property functions or the structures will not be filled in.
+ May throw a BridgeRuntimeError.
+ */
+ void getPropDesc(const OUString & sFuncName, FUNCDESC ** pFuncDescGet,
+ FUNCDESC** pFuncDescPut, VARDESC ** pVarDesc);
+ // These functions are for the case if an object of this class wraps an IDispatch
+ // object that implements UNO interfaces. In that case the member m_seqTypes
+ // is set through XInitialization::initialize.
+ void getMethodInfo(const OUString& sName, TypeDescription& methodDescription);
+ // After return attributInfo contains typelib_InterfaceAttributeTypeDescription::pAttributeTypeRef
+ void getAttributeInfo(const OUString& sName, TypeDescription& attributeInfo);
+ // used by get MethodInfo
+ TypeDescription getInterfaceMemberDescOfCurrentCall(const OUString& sName);
+ /** Returns alway a valid ITypeInfo interface or throws a BridgeRuntimeError.
+ The returned interface does not need to be AddRef'ed as long as it is locally
+ used. The interface is kept in the instance of this class.
+ */
+ ITypeInfo* getTypeInfo();
+
+ /** Returns the DISPID for a function or property name. If true is returned then
+ id contains a valid DISPID.
+ */
+
+ bool getDispid(const OUString& sFuncName, DISPID * id);
+
+ VARTYPE getUserDefinedElementType( ITypeInfo* pTypeInfo, const DWORD nHrefType );
+
+ /** Gets the element type in a VARIANT like style. E.g. if desc->lptdesc contains
+ a VT_PTR than it is replaced by VT_BYREF and VT_SAFEARRAY is replaced by VT_ARRAY
+ If the TYPEDESC describes an SAFEARRAY then varType is a combination of VT_ARRAY
+ and the element type.
+ The argument desc must be obtained from FUNCDESC::lprgelemdescParam[i].tdesc where
+ FUNCDESC was obtained from the ITypeInfo belonging to wrapped IDispatch.
+ */
+ VARTYPE getElementTypeDesc( const TYPEDESC *desc);
+ /** Iterates over all functions and put the names and indices into the map
+ m_mapComFunc of type TLBFuncIndexMap.
+ Call the function every time before accessing the map.
+ Throws a BridgeRuntimeError on failure.
+ */
+ void buildComTlbIndex();
+
+ /** Returns a FUNCDESC structure which contains type information about the
+ current XInvocation::invoke call. The FUNCDESC either describes a method,
+ a property put or a property get operation.
+ It uses the types com.sun.star.bridge.oleautomation.PropertyPutArgument
+ which can be
+ contained in the sequence of in-arguments of invoke to determine if the call is
+ a property put or property get operation.
+ If no adequate FUNCDESC was found, an IllegalArgumentException is thrown.
+ Therefore it is safe to assume that the returned FUNCDESC* is not NULL.
+
+ @exception IllegalArgumentException
+ Thrown if no adequate FUNCDESC could be found.
+ */
+ void getFuncDescForInvoke(const OUString & sFuncName,
+ const Sequence<Any> & seqArgs, FUNCDESC** pFuncDesc);
+
+ // Finds out wheter the wrapped IDispatch is an JScript Object. This is is
+ // done by
+ // asking for the property "_environment". If it has the value "JScript"
+ // (case insensitive) then the IDispatch is considered a JScript object.
+ sal_Bool isJScriptObject();
+ // -------------------------------------------------------------------------------
+
+ // If UNO interfaces are implemented in JScript objects, VB or C++ COM objects
+ // and those are passed as parameter to a UNO interface function, then
+ // the IDispatch* are wrapped by objects of this class. Assuming that the functions
+ // implemented by the IDispatch object returns another UNO interface then
+ // it has to be wrapped to this type. But this is only possible if an object of this
+ // wrapper class knows what type it is represting. The member m_TypeDescription holds this
+ // information.
+ // m_TypeDescription is only useful when an object wraps an IDispatch object that implements
+ // an UNO interface. The value is set during a call to XInitialization::initialize.
+ Sequence<Type> m_seqTypes;
+ CComPtr<IUnknown> m_spUnknown;
+ CComPtr<IDispatch> m_spDispatch;
+ rtl::OUString m_sTypeName; // is "" ( not initialised ), "IDispatch" ( we have no idea ) or "SomeLibrary.SomeTypeName" if we managed to get a type
+ /** This value is set dureing XInitialization::initialize. It indicates that the COM interface
+ was transported as VT_DISPATCH in a VARIANT rather then a VT_UNKNOWN
+ */
+ sal_Bool m_bOriginalDispatch;
+ DispIdMap m_dispIdMap;
+ Reference<XIdlClass>* m_pxIdlClass;
+
+
+ // used by isJScriptObject
+ enum JScriptDetermination{ JScriptUndefined=0, NoJScript, IsJScript};
+ JScriptDetermination m_eJScript;
+ // The map is filled by buildComTlbIndex
+ // It maps Uno Function names to an index which is used in ITypeInfo::GetFuncDesc
+ TLBFuncIndexMap m_mapComFunc;
+ // used for synchroizing the computation of the content for m_mapComFunc
+ bool m_bComTlbIndexInit;
+ // Keeps the ITypeInfo obtained from IDispatch::GetTypeInfo
+ CComPtr< ITypeInfo > m_spTypeInfo;
+ rtl::OUString m_sDefaultMember;
+ bool m_bHasDfltMethod;
+ bool m_bHasDfltProperty;
+};
+
+} // end namespace
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/olethread.cxx b/extensions/source/ole/olethread.cxx
new file mode 100644
index 000000000000..bd6f5fbceeec
--- /dev/null
+++ b/extensions/source/ole/olethread.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#if defined _MSC_VER && ( _MSC_VER >= 1200 )
+#define _WIN32_WINNT 0x0400
+#endif
+
+#include "ole2uno.hxx"
+
+#include <tools/presys.h>
+#include <tools/postsys.h>
+
+#include <osl/thread.hxx>
+
+using namespace std;
+
+namespace ole_adapter
+{
+// CoInitializeEx *
+typedef DECLSPEC_IMPORT HRESULT (STDAPICALLTYPE *ptrCoInitEx)( LPVOID, DWORD);
+// CoInitialize *
+typedef DECLSPEC_IMPORT HRESULT (STDAPICALLTYPE *ptrCoInit)( LPVOID);
+
+void o2u_attachCurrentThread()
+{
+ static osl::ThreadData oleThreadData;
+
+ if ((sal_Bool)(sal_IntPtr)oleThreadData.getData() != sal_True)
+ {
+ HINSTANCE inst= LoadLibrary( _T("ole32.dll"));
+ if( inst )
+ {
+ HRESULT hr;
+ // Try DCOM
+ ptrCoInitEx initFuncEx= (ptrCoInitEx)GetProcAddress( inst, _T("CoInitializeEx"));
+ if( initFuncEx)
+ hr= initFuncEx( NULL, COINIT_MULTITHREADED);
+ // No DCOM, try COM
+ else
+ {
+ ptrCoInit initFunc= (ptrCoInit)GetProcAddress( inst,_T("CoInitialize"));
+ if( initFunc)
+ hr= initFunc( NULL);
+ }
+ }
+ oleThreadData.setData((void*)sal_True);
+ }
+}
+
+} // end namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/servprov.cxx b/extensions/source/ole/servprov.cxx
new file mode 100644
index 000000000000..ecf45a4ce074
--- /dev/null
+++ b/extensions/source/ole/servprov.cxx
@@ -0,0 +1,757 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#ifdef __MINGW32__
+#define INITGUID
+#include <initguid.h>
+#else
+#include "ole2uno.hxx"
+#include "unoconversionutilities.hxx"
+#endif
+#include "servprov.hxx"
+#include "unoobjw.hxx"
+#include "oleobjw.hxx"
+#include <rtl/unload.h>
+
+#include <tools/presys.h>
+#define _WIN32_WINNT 0x0403
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#undef _DEBUG
+#endif
+#include <atlbase.h>
+extern CComModule _Module;
+#include <atlcom.h>
+#include <tools/postsys.h>
+
+
+using namespace std;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::bridge;
+using namespace com::sun::star::bridge::ModelDependent;
+
+
+
+namespace ole_adapter
+{
+
+#include <initguid.h>
+// prior 5.2 ( src569 ver m)
+// {3ECF78F0-B149-11D2-8EBE-00105AD848AF}
+//DEFINE_GUID(OID_ServiceManager, 0x3ECF78F0, 0xB149, 0x11d2, 0x8E, 0xBE, 0x00, 0x10, 0x5A, 0xD8, 0x48, 0xAF);
+
+#ifndef OWNGUID
+// GUID used since 5.2 ( src569 m)
+// {82154420-0FBF-11d4-8313-005004526AB4}
+DEFINE_GUID(OID_ServiceManager, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
+#else
+// Alternative GUID
+// {D9BB9D1D-BFA9-4357-9F11-9A2E9061F06E}
+DEFINE_GUID(OID_ServiceManager, 0xd9bb9d1d, 0xbfa9, 0x4357, 0x9f, 0x11, 0x9a, 0x2e, 0x90, 0x61, 0xf0, 0x6e);
+#endif
+
+extern rtl_StandardModuleCount globalModuleCount;
+
+/*****************************************************************************
+
+ class implementation ProviderOleWrapper_Impl
+
+*****************************************************************************/
+
+ProviderOleWrapper_Impl::ProviderOleWrapper_Impl(const Reference<XMultiServiceFactory>& smgr,
+ const Reference<XSingleServiceFactory>& xSFact, GUID* pGuid)
+ : m_xSingleServiceFactory(xSFact),
+ m_smgr( smgr)
+{
+ m_guid = *pGuid;
+
+ Reference<XInterface> xInt = smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
+
+ if (xInt.is())
+ {
+ Any a= xInt->queryInterface( ::getCppuType( reinterpret_cast<
+ Reference< XBridgeSupplier2>* >(0)));
+ a >>= m_bridgeSupplier;
+
+ }
+}
+
+ProviderOleWrapper_Impl::~ProviderOleWrapper_Impl()
+{
+}
+
+sal_Bool ProviderOleWrapper_Impl::registerClass()
+{
+ HRESULT hresult;
+
+ o2u_attachCurrentThread();
+
+ hresult = CoRegisterClassObject(
+ m_guid,
+ this,
+ CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
+ REGCLS_MULTIPLEUSE,
+ &m_factoryHandle);
+
+ return (hresult == NOERROR);
+}
+
+sal_Bool ProviderOleWrapper_Impl::deregisterClass()
+{
+ HRESULT hresult = CoRevokeClassObject(m_factoryHandle);
+
+ return (hresult == NOERROR);
+}
+
+STDMETHODIMP ProviderOleWrapper_Impl::QueryInterface(REFIID riid, void FAR* FAR* ppv)
+{
+ if(IsEqualIID(riid, IID_IUnknown))
+ {
+ AddRef();
+ *ppv = (IUnknown*) (IClassFactory*) this;
+ return NOERROR;
+ }
+ else if (IsEqualIID(riid, IID_IClassFactory))
+ {
+ AddRef();
+ *ppv = (IClassFactory*) this;
+ return NOERROR;
+ }
+
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG) ProviderOleWrapper_Impl::AddRef()
+{
+ return osl_incrementInterlockedCount( &m_refCount);
+}
+
+STDMETHODIMP_(ULONG) ProviderOleWrapper_Impl::Release()
+{
+ MutexGuard aGuard( Mutex::getGlobalMutex());
+ ULONG refCount = --m_refCount;
+ if (m_refCount == 0)
+ {
+ delete this;
+ }
+
+ return refCount;
+}
+
+STDMETHODIMP ProviderOleWrapper_Impl::CreateInstance(IUnknown FAR* punkOuter,
+ REFIID riid,
+ void FAR* FAR* ppv)
+{
+ HRESULT ret = ResultFromScode(E_UNEXPECTED);
+ punkOuter = NULL;
+
+ Reference<XInterface> xInstance;
+
+ if (m_xSingleServiceFactory.is())
+ {
+ xInstance = m_xSingleServiceFactory->createInstance();
+
+ if (xInstance.is())
+ {
+ Any usrAny(&xInstance, getCppuType( & xInstance));
+
+ sal_uInt8 arId[16];
+ rtl_getGlobalProcessId( arId );
+ Any oleAny = m_bridgeSupplier->createBridge(usrAny,
+ Sequence<sal_Int8>((sal_Int8*)arId, 16),
+ UNO,
+ OLE);
+
+
+ if (oleAny.getValueTypeClass() == getCppuType( (sal_uInt32 *)0).getTypeClass())
+ {
+ VARIANT* pVariant = *(VARIANT**)oleAny.getValue();
+
+ if (pVariant->vt == VT_DISPATCH)
+ {
+ ret = pVariant->pdispVal->QueryInterface(riid, ppv);
+ }
+
+ VariantClear(pVariant);
+ CoTaskMemFree(pVariant);
+ }
+ }
+ }
+
+ return ret;
+}
+
+STDMETHODIMP ProviderOleWrapper_Impl::LockServer(int /*fLock*/)
+{
+ return NOERROR;
+}
+
+/*****************************************************************************
+
+ class implementation OneInstanceOleWrapper_Impl
+
+*****************************************************************************/
+
+OneInstanceOleWrapper_Impl::OneInstanceOleWrapper_Impl( const Reference<XMultiServiceFactory>& smgr,
+ const Reference<XInterface>& xInst,
+ GUID* pGuid,
+ sal_Bool bAsApplication )
+ : m_xInst(xInst), m_refCount(0),
+ m_smgr( smgr),
+ m_factoryHandle( 0 ),
+ m_bAsApplication( bAsApplication ),
+ m_nApplRegHandle( 0 )
+{
+ m_guid = *pGuid;
+
+ Reference<XInterface> xInt = m_smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
+
+ if (xInt.is())
+ {
+ Any a= xInt->queryInterface( getCppuType(
+ reinterpret_cast< Reference<XBridgeSupplier2>*>(0)));
+ a >>= m_bridgeSupplier;
+ }
+}
+
+OneInstanceOleWrapper_Impl::~OneInstanceOleWrapper_Impl()
+{
+}
+
+sal_Bool OneInstanceOleWrapper_Impl::registerClass()
+{
+ HRESULT hresult;
+
+ o2u_attachCurrentThread();
+
+ hresult = CoRegisterClassObject(
+ m_guid,
+ this,
+ CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
+ REGCLS_MULTIPLEUSE,
+ &m_factoryHandle);
+
+ if ( hresult == NOERROR && m_bAsApplication )
+ hresult = RegisterActiveObject( this, m_guid, ACTIVEOBJECT_WEAK, &m_nApplRegHandle );
+
+ return (hresult == NOERROR);
+}
+
+sal_Bool OneInstanceOleWrapper_Impl::deregisterClass()
+{
+ HRESULT hresult1 = NOERROR;
+ if ( m_bAsApplication )
+ hresult1 = RevokeActiveObject( m_nApplRegHandle, NULL );
+
+ HRESULT hresult2 = CoRevokeClassObject(m_factoryHandle);
+
+ return (hresult1 == NOERROR && hresult2 == NOERROR);
+}
+
+STDMETHODIMP OneInstanceOleWrapper_Impl::QueryInterface(REFIID riid, void FAR* FAR* ppv)
+{
+ if(IsEqualIID(riid, IID_IUnknown))
+ {
+ AddRef();
+ *ppv = (IUnknown*) (IClassFactory*) this;
+ return NOERROR;
+ }
+ else if (IsEqualIID(riid, IID_IClassFactory))
+ {
+ AddRef();
+ *ppv = (IClassFactory*) this;
+ return NOERROR;
+ }
+
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG) OneInstanceOleWrapper_Impl::AddRef()
+{
+ return osl_incrementInterlockedCount( &m_refCount);
+}
+
+STDMETHODIMP_(ULONG) OneInstanceOleWrapper_Impl::Release()
+{
+ MutexGuard oGuard( Mutex::getGlobalMutex());
+ ULONG refCount = --m_refCount;
+ if ( m_refCount == 0)
+ {
+ delete this;
+ }
+
+ return refCount;
+}
+
+STDMETHODIMP OneInstanceOleWrapper_Impl::CreateInstance(IUnknown FAR* punkOuter,
+ REFIID riid,
+ void FAR* FAR* ppv)
+{
+ HRESULT ret = ResultFromScode(E_UNEXPECTED);
+ punkOuter = NULL;
+
+ if (m_xInst.is())
+ {
+ Any usrAny(&m_xInst, getCppuType( &m_xInst));
+ sal_uInt8 arId[16];
+ rtl_getGlobalProcessId( arId);
+ Any oleAny = m_bridgeSupplier->createBridge(usrAny,
+ Sequence<sal_Int8>( (sal_Int8*)arId, 16),
+ UNO,
+ OLE);
+
+
+ if (oleAny.getValueTypeClass() == TypeClass_UNSIGNED_LONG)
+ {
+ VARIANT* pVariant = *(VARIANT**)oleAny.getValue();
+
+ if ((pVariant->vt == VT_UNKNOWN) || (pVariant->vt == VT_DISPATCH))
+ {
+ ret = pVariant->punkVal->QueryInterface(riid, ppv);
+ }
+
+ VariantClear(pVariant);
+ CoTaskMemFree(pVariant);
+ }
+ }
+
+ return ret;
+}
+
+STDMETHODIMP OneInstanceOleWrapper_Impl::LockServer(int /*fLock*/)
+{
+ return NOERROR;
+}
+
+
+/*****************************************************************************
+
+ class implementation OleConverter_Impl2
+
+*****************************************************************************/
+
+OleConverter_Impl2::OleConverter_Impl2( const Reference<XMultiServiceFactory> &smgr):
+ UnoConversionUtilities<OleConverter_Impl2>( smgr)
+
+{
+ // library unloading support
+ globalModuleCount.modCnt.acquire( &globalModuleCount.modCnt);
+}
+
+// The XMultiServiceFactory is later set by XInitialization
+OleConverter_Impl2::OleConverter_Impl2( const Reference<XMultiServiceFactory>& smgr, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass ):
+ UnoConversionUtilities<OleConverter_Impl2>( smgr, unoWrapperClass, comWrapperClass )
+
+{
+ //library unloading support
+ globalModuleCount.modCnt.acquire( &globalModuleCount.modCnt);
+}
+
+OleConverter_Impl2::~OleConverter_Impl2()
+{
+ globalModuleCount.modCnt.release( &globalModuleCount.modCnt);
+}
+
+// XBridgeSupplier --------------------------------------------------------------
+Any SAL_CALL OleConverter_Impl2::createBridge(const Any& modelDepObject,
+ const Sequence< sal_Int8 >& ProcessId,
+ sal_Int16 sourceModelType,
+ sal_Int16 destModelType)
+ throw (IllegalArgumentException,
+ RuntimeException )
+{
+ Any ret;
+ sal_uInt8 arId[16];
+ rtl_getGlobalProcessId( arId );
+
+ Sequence< sal_Int8 > seqProcessId( (sal_Int8*)arId, 16);
+
+ if ( seqProcessId == ProcessId)
+ {
+ if (sourceModelType == UNO)
+ {
+ if (destModelType == UNO)
+ {
+ // same model -> copy value only
+ ret = modelDepObject;
+ }
+ else if (destModelType == OLE)
+ {
+ // convert UNO any into variant
+ VARIANT* pVariant = (VARIANT*) CoTaskMemAlloc(sizeof(VARIANT));
+ VariantInit( pVariant);
+ try
+ {
+ anyToVariant( pVariant, modelDepObject);
+ }
+ catch(...)
+ {
+ CoTaskMemFree(pVariant);
+ throw IllegalArgumentException();
+ }
+ ret.setValue((void*) &pVariant, getCppuType((sal_uInt32*)0));
+ }
+ else
+ throw IllegalArgumentException();
+ }
+ else if (sourceModelType == OLE)
+ {
+ if (modelDepObject.getValueType() != getCppuType((sal_uInt32*)0))
+ {
+ throw IllegalArgumentException();
+ }
+ else if (destModelType == OLE)
+ {
+ // same model -> copy value only
+ VARIANT* pVariant = (VARIANT*) CoTaskMemAlloc(sizeof(VARIANT));
+
+ if (NOERROR != VariantCopy(pVariant, *(VARIANT**)modelDepObject.getValue()))
+ {
+ CoTaskMemFree(pVariant);
+ throw(IllegalArgumentException());
+ }
+ else
+ {
+ ret.setValue((void*) &pVariant, getCppuType((sal_uInt32*)0));
+ }
+ }
+ else if (destModelType == UNO)
+ {
+ // convert variant into UNO any
+ VARIANT* pVariant = *(VARIANT**)modelDepObject.getValue();
+ try
+ {
+ variantToAny(pVariant, ret);
+ }
+ catch (CannotConvertException & e)
+ {
+ throw IllegalArgumentException(
+ e.Message, 0, -1);
+ }
+ }
+ else
+ throw IllegalArgumentException();
+
+ }
+ else
+ throw IllegalArgumentException();
+ }
+
+ return ret;
+}
+
+
+// XInitialize ------------------------------------------------------------------------------
+// the first argument is an XMultiServiceFactory if at all
+void SAL_CALL OleConverter_Impl2::initialize( const Sequence< Any >& aArguments )
+ throw(Exception, RuntimeException)
+{
+ if( aArguments.getLength() == 1 && aArguments[0].getValueTypeClass() == TypeClass_INTERFACE)
+ {
+ Reference < XInterface > xInt;
+ aArguments[0] >>= xInt;
+ Reference <XMultiServiceFactory> xMulti( xInt, UNO_QUERY);
+ m_smgrRemote= xMulti;
+ }
+}
+
+// UnoConversionUtilities -------------------------------------------------------------------
+Reference< XInterface > OleConverter_Impl2::createUnoWrapperInstance()
+{
+ if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
+ {
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+ }
+ else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
+ {
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+ }
+ else
+ return Reference<XInterface>();
+}
+
+Reference< XInterface > OleConverter_Impl2::createComWrapperInstance()
+{
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+}
+
+
+
+/*****************************************************************************
+
+ class implementation OleClient_Impl
+
+*****************************************************************************/
+
+OleClient_Impl::OleClient_Impl( const Reference<XMultiServiceFactory>& smgr):
+ UnoConversionUtilities<OleClient_Impl>( smgr)
+{
+ // library unloading support
+ globalModuleCount.modCnt.acquire( &globalModuleCount.modCnt);
+ Reference<XInterface> xInt;// = m_smgr->createInstance(L"com.sun.star.bridge.OleBridgeSupplier2");
+
+ if (xInt.is())
+ {
+ Any a= xInt->queryInterface(getCppuType(
+ reinterpret_cast<Reference<XBridgeSupplier2>*>(0)));
+ a >>= m_bridgeSupplier;
+ }
+}
+
+OleClient_Impl::~OleClient_Impl()
+{
+ // library unloading support
+ globalModuleCount.modCnt.release( &globalModuleCount.modCnt);
+}
+
+Sequence< OUString > SAL_CALL OleClient_Impl::getAvailableServiceNames() throw( RuntimeException )
+{
+ Sequence< OUString > ret;
+
+ return ret;
+}
+
+
+OUString OleClient_Impl::getImplementationName()
+{
+ return OUString(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.comp.ole.OleClient"));
+}
+
+Reference<XInterface> SAL_CALL OleClient_Impl::createInstance(const OUString& ServiceSpecifier) throw (Exception, RuntimeException )
+{
+ Reference<XInterface> ret;
+ HRESULT result;
+ IUnknown* pUnknown = NULL;
+ CLSID classId;
+
+ o2u_attachCurrentThread();
+
+ result = CLSIDFromProgID(
+ reinterpret_cast<LPCWSTR>(ServiceSpecifier.getStr()), //Pointer to the ProgID
+ &classId); //Pointer to the CLSID
+
+
+ if (result == NOERROR)
+ {
+ result = CoCreateInstance(
+ classId, //Class identifier (CLSID) of the object
+ NULL, //Pointer to whether object is or isn't part of an aggregate
+ CLSCTX_SERVER, //Context for running executable code
+ IID_IUnknown, //Reference to the identifier of the interface
+ (void**)&pUnknown); //Address of output variable that receives
+ // the interface pointer requested in riid
+ }
+
+ if (pUnknown != NULL)
+ {
+ Any any;
+ CComVariant variant;
+
+ V_VT(&variant) = VT_UNKNOWN;
+ V_UNKNOWN(&variant) = pUnknown;
+ // AddRef for Variant
+ pUnknown->AddRef();
+
+ // When the object is wrapped, then its refcount is increased
+ variantToAny(&variant, any);
+ if (any.getValueTypeClass() == TypeClass_INTERFACE)
+ {
+ any >>= ret;
+ }
+ pUnknown->Release(); // CoCreateInstance
+ }
+
+ return ret;
+}
+
+Reference<XInterface> SAL_CALL OleClient_Impl::createInstanceWithArguments(const OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/) throw (Exception, RuntimeException)
+{
+ return createInstance( ServiceSpecifier);
+}
+
+// UnoConversionUtilities -----------------------------------------------------------------------------
+Reference< XInterface > OleClient_Impl::createUnoWrapperInstance()
+{
+ if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
+ {
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+ }
+ else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
+ {
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+ }
+ else
+ return Reference< XInterface>();
+}
+// UnoConversionUtilities -----------------------------------------------------------------------------
+Reference< XInterface > OleClient_Impl::createComWrapperInstance( )
+{
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+}
+
+
+
+/*****************************************************************************
+
+ class implementation OleServer_Impl
+
+*****************************************************************************/
+
+OleServer_Impl::OleServer_Impl( const Reference<XMultiServiceFactory>& smgr):
+ m_smgr( smgr)
+{
+ //library unloading support
+ globalModuleCount.modCnt.acquire( &globalModuleCount.modCnt);
+ Reference<XInterface> xInt = m_smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
+
+ if (xInt.is())
+ {
+ Any a= xInt->queryInterface( getCppuType(
+ reinterpret_cast< Reference<XBridgeSupplier2>*>(0)));
+ a >>= m_bridgeSupplier;
+ }
+
+#ifndef OWNGUID
+ sal_Bool bOLERegister = sal_False;
+#else
+ sal_Bool bOLERegister = sal_True;
+#endif
+ sal_Bool ret = provideInstance( m_smgr, (GUID*)&OID_ServiceManager, bOLERegister );
+ (void)ret;
+}
+
+OleServer_Impl::~OleServer_Impl()
+{
+ while (!m_wrapperList.empty())
+ {
+ (*m_wrapperList.begin())->deregisterClass();
+ (*m_wrapperList.begin())->Release();
+ m_wrapperList.pop_front();
+ }
+ //library unloading support
+ globalModuleCount.modCnt.release( &globalModuleCount.modCnt);
+}
+// XInterface --------------------------------------------------
+Any SAL_CALL OleServer_Impl::queryInterface( const Type& aType ) throw(RuntimeException)
+{
+ Any a= ::cppu::queryInterface( aType, static_cast<XTypeProvider*>(this));
+ if( a == Any())
+ return OWeakObject::queryInterface( aType);
+ else
+ return a;
+}
+void SAL_CALL OleServer_Impl::acquire( ) throw()
+{
+ OWeakObject::acquire();
+}
+void SAL_CALL OleServer_Impl::release( ) throw ()
+{
+ OWeakObject::release();
+}
+
+
+// XTypeProvider --------------------------------------------------
+Sequence< Type > SAL_CALL OleServer_Impl::getTypes( ) throw(RuntimeException)
+{
+ static OTypeCollection *pCollection = 0;
+ if( ! pCollection )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pCollection )
+ {
+ static OTypeCollection collection(
+ getCppuType(reinterpret_cast< Reference< XWeak>*>(0)),
+ getCppuType(reinterpret_cast< Reference< XTypeProvider>*>(0)) );
+ pCollection = &collection;
+ }
+ }
+ return (*pCollection).getTypes();
+}
+Sequence< sal_Int8 > SAL_CALL OleServer_Impl::getImplementationId() throw(RuntimeException)
+{
+ static OImplementationId *pId = 0;
+ if( ! pId )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pId )
+ {
+ static OImplementationId id( sal_False );
+ pId = &id;
+ }
+ }
+ return (*pId).getImplementationId();
+}
+
+
+sal_Bool OleServer_Impl::provideService(const Reference<XSingleServiceFactory>& xSFact, GUID* guid)
+{
+ IClassFactoryWrapper* pFac = new ProviderOleWrapper_Impl( m_smgr, xSFact, guid);
+
+ pFac->AddRef();
+
+ m_wrapperList.push_back(pFac);
+
+ return pFac->registerClass();
+}
+
+sal_Bool OleServer_Impl::provideInstance(const Reference<XInterface>& xInst, GUID* guid, sal_Bool bAsApplication )
+{
+ IClassFactoryWrapper* pFac = new OneInstanceOleWrapper_Impl( m_smgr, xInst, guid, bAsApplication );
+
+ pFac->AddRef();
+ m_wrapperList.push_back(pFac);
+
+ return pFac->registerClass();
+}
+
+
+
+} // end namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/servprov.hxx b/extensions/source/ole/servprov.hxx
new file mode 100644
index 000000000000..49091b1fcd38
--- /dev/null
+++ b/extensions/source/ole/servprov.hxx
@@ -0,0 +1,279 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SERVPROV_HXX
+#define _SERVPROV_HXX
+
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+#include "ole2uno.hxx"
+#include "unoconversionutilities.hxx"
+
+
+using namespace com::sun::star::bridge;
+using namespace cppu;
+using namespace std;
+
+namespace ole_adapter
+{
+Reference< XInterface> SAL_CALL ConverterProvider_CreateInstance( const Reference<XMultiServiceFactory> & xSMgr)
+ throw( Exception);
+Reference< XInterface> SAL_CALL ConverterProvider_CreateInstance2( const Reference<XMultiServiceFactory> & xSMgr)
+ throw( Exception);
+Reference< XInterface> SAL_CALL ConverterProvider_CreateInstanceVar1( const Reference<XMultiServiceFactory> & xSMgr)
+ throw( Exception);
+Reference<XInterface> SAL_CALL OleClient_CreateInstance( const Reference<XMultiServiceFactory> & xSMgr)
+ throw( Exception);
+Reference<XInterface> SAL_CALL OleServer_CreateInstance( const Reference<XMultiServiceFactory> & xSMgr)
+ throw( Exception);
+/*****************************************************************************
+
+ class declaration IClassFactoryWrapper
+
+ Specify abstract helper methods on class factories, which provide
+ UNO objects. These methods are used by objects of class OleServer_Impl,
+ to handle the OLE registration of different class factories.
+
+*****************************************************************************/
+
+class IClassFactoryWrapper : public IClassFactory
+{
+public:
+
+ virtual sal_Bool registerClass() = 0;
+ virtual sal_Bool deregisterClass() = 0;
+};
+
+/*****************************************************************************
+
+ class declaration ProviderOleWrapper_Impl
+
+ Provides an UNO service provider as OLE class factory. Handle the
+ OLE registration by overloading the abstract methods from
+ IClassFactoryWrapper.
+
+ Acts as a COM class factory. When IClassFactory::CreateInstance is being called
+ then it creates an service by help of the XSingleServiceFactory member and maps
+ maps it to a COM object.
+
+*****************************************************************************/
+
+class ProviderOleWrapper_Impl : public IClassFactoryWrapper
+{
+public:
+
+ ProviderOleWrapper_Impl( const Reference<XMultiServiceFactory>& smgr,
+ const Reference<XSingleServiceFactory>& xSFactory, GUID* pGuid);
+ virtual ~ProviderOleWrapper_Impl();
+
+ sal_Bool registerClass();
+ sal_Bool deregisterClass();
+
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj);
+ STDMETHOD_(ULONG, AddRef)();
+ STDMETHOD_(ULONG, Release)();
+
+ /* IClassFactory methods */
+ STDMETHOD(CreateInstance)(IUnknown FAR* punkOuter, REFIID riid, void FAR* FAR* ppv);
+ STDMETHOD(LockServer)(int fLock);
+
+protected:
+
+ oslInterlockedCount m_refCount;
+ Reference<XSingleServiceFactory> m_xSingleServiceFactory;
+ GUID m_guid;
+ DWORD m_factoryHandle;
+ Reference<XBridgeSupplier2> m_bridgeSupplier;
+ Reference<XMultiServiceFactory> m_smgr;
+};
+
+/*****************************************************************************
+
+ class declaration OneInstanceOleWrapper_Impl
+
+ Provides an single UNO object as OLE object. Handle the
+ OLE registration by overloading the abstract methods from
+ IClassFactoryWrapper.
+
+ Acts as a COM class factory. When IClassFactory::CreateInstance is being called
+ then it maps the XInstance member it to a COM object.
+
+*****************************************************************************/
+
+class OneInstanceOleWrapper_Impl : public IClassFactoryWrapper
+{
+public:
+
+ OneInstanceOleWrapper_Impl( const Reference<XMultiServiceFactory>& smgr, const Reference<XInterface>& xInst, GUID* pGuid, sal_Bool bAsApplication );
+ virtual ~OneInstanceOleWrapper_Impl();
+
+ sal_Bool registerClass();
+ sal_Bool deregisterClass();
+
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj);
+ STDMETHOD_(ULONG, AddRef)();
+ STDMETHOD_(ULONG, Release)();
+
+ /* IClassFactory methods */
+ STDMETHOD(CreateInstance)(IUnknown FAR* punkOuter, REFIID riid, void FAR* FAR* ppv);
+ STDMETHOD(LockServer)(int fLock);
+
+protected:
+
+ oslInterlockedCount m_refCount;
+ Reference<XInterface> m_xInst;
+ GUID m_guid;
+ DWORD m_factoryHandle;
+ Reference<XBridgeSupplier2> m_bridgeSupplier;
+ Reference<XMultiServiceFactory> m_smgr;
+ unsigned long m_nApplRegHandle;
+ sal_Bool m_bAsApplication;
+};
+
+/*****************************************************************************
+
+ class declaration OleConverter_Impl2
+
+ Implementation of the UNO service com.sun.star.bridge.OleBridgeSupplier2.
+
+*****************************************************************************/
+
+// This class realizes the service com.sun.star.bridge.OleBridgeSupplier2 and
+// com.sun.star.bridge.OleBridgeSupplierVar1. The class implements XBridgeSupplier2
+// instead of XBridgeSuppplier as done by class OleConverter_Impl. The XBridgeSupplier2
+// interface does not need a Maschine Id in its createBridge function anymore,
+// If an UNO interface is to be converted then the member m_nUnoWrapperClass determines
+// what wrapper class is to be used. There are currently InterfaceOleWrapper_Impl and
+// UnoObjectWrapperRemoteOpt. The first is used for the OleBridgeSupplier2 and the
+// latter for OleBridgeSupplierVar1.
+// The m_nComWrapperClass specifies the class which is used as wrapper for COM interfaces.
+// Currently there is only one class available ( IUnknownWrapper_Impl).
+class OleConverter_Impl2 : public WeakImplHelper2<XBridgeSupplier2, XInitialization>,
+ public UnoConversionUtilities<OleConverter_Impl2>
+{
+public:
+ OleConverter_Impl2( const Reference<XMultiServiceFactory>& smgr);
+ OleConverter_Impl2( const Reference<XMultiServiceFactory>& smgr, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass );
+ virtual ~OleConverter_Impl2();
+
+ // XBridgeSupplier2 ---------------------------------------------------
+
+ virtual Any SAL_CALL createBridge(const Any& modelDepObject,
+ const Sequence<sal_Int8>& ProcessId,
+ sal_Int16 sourceModelType,
+ sal_Int16 destModelType)
+ throw (IllegalArgumentException, RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException);
+
+ // Abstract struct UnoConversionUtilities
+ virtual Reference< XInterface > createUnoWrapperInstance();
+ virtual Reference< XInterface > createComWrapperInstance();
+protected:
+
+};
+
+
+/*****************************************************************************
+
+ class declaration OleClient_Impl
+
+ Implementation of the UNO service com.sun.star.bridge.OleObjectFactory.
+
+*****************************************************************************/
+
+
+class OleClient_Impl : public WeakImplHelper1<XMultiServiceFactory>,
+ public UnoConversionUtilities<OleClient_Impl>
+{
+public:
+ OleClient_Impl( const Reference<XMultiServiceFactory>& smgr);
+ ~OleClient_Impl();
+
+ // XMultiServiceFactory
+ virtual Reference<XInterface> SAL_CALL createInstance(const OUString& ServiceSpecifier) throw( Exception, RuntimeException);
+ virtual Reference<XInterface> SAL_CALL createInstanceWithArguments(const OUString& ServiceSpecifier, const Sequence< Any >& Arguments) throw (Exception, RuntimeException);
+ Sequence< OUString > SAL_CALL getAvailableServiceNames() throw (RuntimeException);
+
+ // Abstract struct UnoConversionUtilities
+ virtual Reference< XInterface > createUnoWrapperInstance();
+ virtual Reference< XInterface > createComWrapperInstance();
+
+
+ OUString getImplementationName();
+protected:
+ Reference<XBridgeSupplier2> m_bridgeSupplier;
+};
+
+/*****************************************************************************
+
+ class declaration OleServer_Impl
+
+ Implementation of the UNO service com.sun.star.bridge.OleApplicationRegistration.
+ Register the calling application as OLE automation server for
+ standard OLE object. The objects will be registered while instanciating
+ this implementation and deregistrated, if this implementation is destroyed.
+
+*****************************************************************************/
+
+class OleServer_Impl : public OWeakObject, XTypeProvider
+{
+public:
+ OleServer_Impl( const Reference<XMultiServiceFactory> &smgr);
+ ~OleServer_Impl();
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type& aType ) throw(RuntimeException);
+ virtual void SAL_CALL acquire( ) throw ();
+ virtual void SAL_CALL release( ) throw ();
+
+ // XTypeProvider
+ virtual Sequence< Type > SAL_CALL getTypes( ) throw(RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(RuntimeException);
+
+protected:
+
+ sal_Bool provideService(const Reference<XSingleServiceFactory>& xMulFact, GUID* guid);
+ sal_Bool provideInstance(const Reference<XInterface>& xInst, GUID* guid, sal_Bool bAsApplication );
+
+ list< IClassFactoryWrapper* > m_wrapperList;
+ Reference< XBridgeSupplier2 > m_bridgeSupplier;
+
+ Reference<XMultiServiceFactory> m_smgr;
+};
+
+} // end namespace
+#endif
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/servreg.cxx b/extensions/source/ole/servreg.cxx
new file mode 100644
index 000000000000..16a99df48fa4
--- /dev/null
+++ b/extensions/source/ole/servreg.cxx
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <rtl/unload.h>
+#include <osl/time.h>
+#include "ole2uno.hxx"
+#include "servprov.hxx"
+#include <rtl/ustring.hxx>
+#include <cppuhelper/factory.hxx>
+using namespace rtl;
+using namespace ole_adapter;
+using namespace cppu;
+
+namespace ole_adapter
+{
+rtl_StandardModuleCount globalModuleCount= MODULE_COUNT_INIT;
+
+
+
+Reference<XInterface> SAL_CALL ConverterProvider_CreateInstance2( const Reference<XMultiServiceFactory> & xSMgr)
+ throw(Exception)
+{
+ Reference<XInterface> xService = *new OleConverter_Impl2( xSMgr);
+ return xService;
+}
+
+Reference<XInterface> SAL_CALL ConverterProvider_CreateInstanceVar1( const Reference<XMultiServiceFactory> & xSMgr)
+ throw(Exception)
+{
+ Reference<XInterface> xService = *new OleConverter_Impl2( xSMgr, UNO_OBJECT_WRAPPER_REMOTE_OPT, IUNKNOWN_WRAPPER_IMPL);
+ return xService;
+}
+
+Reference<XInterface> SAL_CALL OleClient_CreateInstance( const Reference<XMultiServiceFactory> & xSMgr)
+ throw(Exception)
+{
+ Reference<XInterface> xService = *new OleClient_Impl( xSMgr);
+ return xService;
+}
+
+Reference<XInterface> SAL_CALL OleServer_CreateInstance( const Reference<XMultiServiceFactory> & xSMgr)
+ throw (Exception)
+{
+ Reference<XInterface > xService = *new OleServer_Impl(xSMgr);
+ return xService;
+}
+} // end namespace
+
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ )
+{
+ void * pRet = 0;
+
+ OUString aImplName( OUString::createFromAscii( pImplName ) );
+ Reference< XSingleServiceFactory > xFactory;
+ Sequence<OUString> seqServiceNames;
+ if (pServiceManager && aImplName.equals( reinterpret_cast<const sal_Unicode*>(L"com.sun.star.comp.ole.OleConverter2") ))
+ {
+ xFactory= createSingleFactory( reinterpret_cast< XMultiServiceFactory*>(pServiceManager),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.ole.OleConverter2")),
+ ConverterProvider_CreateInstance2, seqServiceNames,
+ &globalModuleCount.modCnt );
+ }
+ else if (pServiceManager && aImplName.equals( reinterpret_cast<const sal_Unicode*>(L"com.sun.star.comp.ole.OleConverterVar1") ))
+ {
+ xFactory= createSingleFactory( reinterpret_cast<XMultiServiceFactory*>(pServiceManager),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.ole.OleConverterVar1")),
+ ConverterProvider_CreateInstanceVar1, seqServiceNames,
+ &globalModuleCount.modCnt );
+ }
+ else if(pServiceManager && aImplName.equals(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.comp.ole.OleClient")))
+ {
+ xFactory= createSingleFactory( reinterpret_cast< XMultiServiceFactory*>(pServiceManager),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.ole.OleClient")),
+ OleClient_CreateInstance, seqServiceNames,
+ &globalModuleCount.modCnt);
+ }
+ else if(pServiceManager && aImplName.equals(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.comp.ole.OleServer")))
+ {
+ xFactory= createOneInstanceFactory( reinterpret_cast< XMultiServiceFactory*>(pServiceManager),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.ole.OleServer")),
+ OleServer_CreateInstance, seqServiceNames,
+ &globalModuleCount.modCnt);
+ }
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
+
+extern "C" sal_Bool SAL_CALL component_writeInfo( void * /*pServiceManager*/, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ //deprecated
+ Reference<XRegistryKey> xNewKey =
+ reinterpret_cast<XRegistryKey*>( pRegistryKey)->createKey(reinterpret_cast<const sal_Unicode*>(L"/com.sun.star.comp.ole.OleConverter2/UNO/SERVICES"));
+ xNewKey->createKey(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.OleBridgeSupplier2"));
+
+ xNewKey->createKey(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
+
+ //deprecated
+ xNewKey =
+ reinterpret_cast<XRegistryKey*>( pRegistryKey)->createKey(reinterpret_cast<const sal_Unicode*>(L"/com.sun.star.comp.ole.OleConverterVar1/UNO/SERVICES"));
+ xNewKey->createKey(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.OleBridgeSupplierVar1"));
+
+ //deprecated
+ xNewKey =
+ reinterpret_cast<XRegistryKey*>( pRegistryKey)->createKey(reinterpret_cast<const sal_Unicode*>(L"/com.sun.star.comp.ole.OleClient/UNO/SERVICES"));
+ xNewKey->createKey(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.OleObjectFactory"));
+
+ xNewKey->createKey(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.Factory"));
+ //deprecated
+ xNewKey =
+ reinterpret_cast<XRegistryKey*>( pRegistryKey)->createKey(reinterpret_cast<const sal_Unicode*>(L"/com.sun.star.comp.ole.OleServer/UNO/SERVICES"));
+ xNewKey->createKey(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.OleApplicationRegistration"));
+
+ xNewKey->createKey(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.ApplicationRegistration"));
+
+ return sal_True;
+ }
+ catch (InvalidRegistryException &)
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+
+extern "C" sal_Bool component_canUnload( TimeValue* libUnused)
+{
+ return globalModuleCount.canUnload( &globalModuleCount, libUnused);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/unoconversionutilities.hxx b/extensions/source/ole/unoconversionutilities.hxx
new file mode 100644
index 000000000000..1970b08fd843
--- /dev/null
+++ b/extensions/source/ole/unoconversionutilities.hxx
@@ -0,0 +1,2452 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _UNO_CONVERSION_UTILITIES
+#define _UNO_CONVERSION_UTILITIES
+
+#include "boost/scoped_array.hpp"
+#include "com/sun/star/script/XInvocationAdapterFactory.hpp"
+#include "com/sun/star/script/XInvocationAdapterFactory2.hpp"
+#include "com/sun/star/script/XTypeConverter.hpp"
+#include "com/sun/star/script/FailReason.hpp"
+#include "com/sun/star/bridge/oleautomation/Date.hpp"
+#include "com/sun/star/bridge/oleautomation/Currency.hpp"
+#include "com/sun/star/bridge/oleautomation/SCode.hpp"
+#include "com/sun/star/bridge/oleautomation/Decimal.hpp"
+#include "typelib/typedescription.hxx"
+#include "ole2uno.hxx"
+
+#include "unotypewrapper.hxx"
+#include <hash_map>
+
+// for some reason DECIMAL_NEG (wtypes.h) which contains BYTE is not resolved.
+typedef unsigned char BYTE;
+// classes for wrapping uno objects
+#define INTERFACE_OLE_WRAPPER_IMPL 1
+#define UNO_OBJECT_WRAPPER_REMOTE_OPT 2
+
+#define INVOCATION_SERVICE reinterpret_cast<const sal_Unicode*>(L"com.sun.star.script.Invocation")
+
+
+// classes for wrapping ole objects
+#define IUNKNOWN_WRAPPER_IMPL 1
+
+#define INTERFACE_ADAPTER_FACTORY reinterpret_cast<const sal_Unicode*>(L"com.sun.star.script.InvocationAdapterFactory")
+// COM or JScript objects implementing UNO interfaces have to implement this property
+#define SUPPORTED_INTERFACES_PROP L"_implementedInterfaces"
+// Second property without leading underscore for use in VB
+#define SUPPORTED_INTERFACES_PROP2 L"Bridge_ImplementedInterfaces"
+
+using namespace com::sun::star::script;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::uno;
+#ifdef __MINGW32__
+using namespace com::sun::star::bridge;
+using namespace com::sun::star::bridge::ModelDependent;
+#endif
+using namespace com::sun::star::bridge::oleautomation;
+using namespace boost;
+namespace ole_adapter
+{
+extern hash_map<sal_uInt32, sal_uInt32> AdapterToWrapperMap;
+extern hash_map<sal_uInt32, sal_uInt32> WrapperToAdapterMap;
+typedef hash_map<sal_uInt32, sal_uInt32>::iterator IT_Wrap;
+typedef hash_map<sal_uInt32, sal_uInt32>::iterator CIT_Wrap;
+//Maps IUnknown pointers to a weak reference of the respective wrapper class (e.g.
+// IUnknownWrapperImpl. It is the responsibility of the wrapper to remove the entry when
+// it is being destroyed.
+// Used to ensure that an Automation object is always mapped to the same UNO objects.
+extern hash_map<sal_uInt32, WeakReference<XInterface> > ComPtrToWrapperMap;
+typedef hash_map<sal_uInt32, WeakReference<XInterface> >::iterator IT_Com;
+typedef hash_map<sal_uInt32, WeakReference<XInterface> >::const_iterator CIT_Com;
+
+// Maps XInterface pointers to a weak reference of its wrapper class (i.e.
+// InterfaceOleWrapper_Impl). It is the responsibility of the wrapper to remove the entry when
+// it is being destroyed. It is used to ensure the identity of objects. That is, an UNO interface
+// is mapped to IDispatch which is kept alive in the COM environment. If the same
+// UNO interface is mapped again to COM then the IDispach of the first mapped instance
+// must be returned.
+extern hash_map<sal_uInt32, WeakReference<XInterface> > UnoObjToWrapperMap;
+typedef hash_map<sal_uInt32, WeakReference<XInterface> >::iterator IT_Uno;
+typedef hash_map<sal_uInt32, WeakReference<XInterface> >::const_iterator CIT_Uno;
+#ifdef __MINGW32__
+inline void reduceRange( Any& any);
+#endif
+
+
+
+
+// createUnoObjectWrapper gets a wrapper instance by calling createUnoWrapperInstance
+ // and initializes it via XInitialization. The wrapper object is required to implement
+ // XBridgeSupplier so that it can convert itself to IDispatch.
+ // class T: Deriving class ( must implement XInterface )
+/** All methods are allowed to throw at least a BridgeRuntimeError.
+ */
+template< class >
+class UnoConversionUtilities
+{
+public:
+ UnoConversionUtilities( const Reference<XMultiServiceFactory> & smgr):
+ m_nUnoWrapperClass( INTERFACE_OLE_WRAPPER_IMPL),
+ m_nComWrapperClass( IUNKNOWN_WRAPPER_IMPL),
+ m_smgr( smgr)
+ {}
+
+ UnoConversionUtilities( const Reference<XMultiServiceFactory> & xFactory, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass )
+ : m_smgr( xFactory), m_nComWrapperClass( comWrapperClass), m_nUnoWrapperClass( unoWrapperClass)
+ {}
+
+ virtual ~UnoConversionUtilities() {}
+ /** converts only into oleautomation types, that is there is no VT_I1, VT_UI2, VT_UI4
+ a sal_Unicode character is converted into a BSTR.
+ @exception com.sun.star.lang.IllegalArgumentException
+ If the any was inappropriate for conversion.
+ @exception com.sun.star.script.CannotConvertException
+ The any contains a type class for which no conversion is provided.
+ */
+ void anyToVariant(VARIANT* pVariant, const Any& rAny);
+ void anyToVariant(VARIANT* pVariant, const Any& rAny, VARTYPE type);
+
+ /** @exception com.sun.star.lang.IllegalArgumentException
+ If rSeq does not contain a sequence then the exception is thrown.
+ */
+ SAFEARRAY* createUnoSequenceWrapper(const Any& rSeq);
+ /** @exception com.sun.star.lang.IllegalArgumentException
+ If rSeq does not contain a sequence or elemtype has no proper value
+ then the exception is thrown.
+ */
+ SAFEARRAY* createUnoSequenceWrapper(const Any& rSeq, VARTYPE elemtype);
+ /**
+ @exception com.sun.star.lang.IllegalArgumentException
+ If rObj does not contain a struct or interface
+ */
+ void createUnoObjectWrapper(const Any & rObj, VARIANT * pVar);
+ /** @exception CannotConvertException
+ Thrown if the VARIANT contains a type that cannot be coerced in the expected Any.
+ ArgumentIndex is 0.
+ @IllegalArgumentException
+ Thrown if the VARIANT is inappropriate for conversion. ArgumentPosition is -1,
+ */
+ void variantToAny(const VARIANT* pVariant, Any& rAny, sal_Bool bReduceValueRange = sal_True);
+ /** This method converts variants arguments in calls from COM -> UNO. Only then
+ the expected UNO type is known.
+ @exception CannotConvertException
+ Thrown if the VARIANT contains a type that cannot be coerced in the expected Any.
+ ArgumentIndex is 0.
+ @IllegalArgumentException
+ Thrown if the VARIANT is inappropriate for conversion. ArgumentPosition is -1,
+ */
+ void variantToAny( const VARIANTARG* pArg, Any& rAny, const Type& ptype, sal_Bool bReduceValueRange = sal_True);
+
+ /**
+ @exception IllegalArgumentException
+ -if pVar does not contain VT_UNKNOWN or VT_DISPATCH or
+ pVar is used for a particular UNO type which is not supported by pVar
+ */
+ Any createOleObjectWrapper(VARIANT* pVar, const Type& aType= Type());
+
+ /*
+ Return true means var contained a ValueObject, and it was successfully converted.
+ The result is in any. It an error occurred a BridgeRuntimeError will be thrown.
+ */
+ bool convertValueObject( const VARIANTARG *var, Any& any);
+ void dispatchExObject2Sequence( const VARIANTARG* pvar, Any& anySeq, const Type& type);
+
+ Sequence<Any> createOleArrayWrapperOfDim(SAFEARRAY* pArray, unsigned int dimCount, unsigned int actDim, long* index,
+ VARTYPE type, const Type& unotype);
+ Sequence<Any> createOleArrayWrapper(SAFEARRAY* pArray, VARTYPE type, const Type& unotype= Type());
+
+
+ VARTYPE mapTypeClassToVartype( TypeClass type);
+ Reference< XSingleServiceFactory > getInvocationFactory(const Any& anyObject);
+
+
+ virtual Reference< XInterface > createUnoWrapperInstance()=0;
+ virtual Reference< XInterface > createComWrapperInstance()=0;
+
+ static sal_Bool isJScriptArray(const VARIANT* pvar);
+
+ Sequence<Type> getImplementedInterfaces(IUnknown* pUnk);
+
+protected:
+ Reference<XInterface> createAdapter(const Sequence<Type>& types, const Reference<XInterface>& receiver);
+
+ // helper function for Sequence conversion
+ void getElementCountAndTypeOfSequence( const Any& rSeq, sal_Int32 dim, Sequence< sal_Int32 >& seqElementCounts, TypeDescription& typeDesc);
+ // helper function for Sequence conversion
+ sal_Bool incrementMultidimensionalIndex(sal_Int32 dimensions, const sal_Int32 * parDimensionLength,
+ sal_Int32 * parMultidimensionalIndex);
+ // helper function for Sequence conversion
+ size_t getOleElementSize( VARTYPE type);
+
+ Type getElementTypeOfSequence( const Type& seqType);
+
+ //Provides a typeconverter
+ Reference<XTypeConverter> getTypeConverter();
+
+ // This member determines what class is used to convert a UNO object
+ // or struct to a COM object. It is passed along to the o2u_anyToVariant
+ // function in the createBridge function implementation
+ sal_uInt8 m_nUnoWrapperClass;
+ sal_uInt8 m_nComWrapperClass;
+
+ // The servicemanager is either a local smgr or remote when the service
+ // com.sun.star.bridge.OleBridgeSupplierVar1 is used. This service can be
+ // created by createInstanceWithArguments where one can supply a service
+ // manager that is to be used.
+ // Local service manager as supplied by the loader when the creator function
+ // of the service is being called.
+ Reference<XMultiServiceFactory> m_smgr;
+ // An explicitly supplied service manager when the service
+ // com.sun.star.bridge.OleBridgeSupplierVar1 is used. That can be a remote
+ // manager.
+ Reference<XMultiServiceFactory> m_smgrRemote;
+ Reference<XSingleServiceFactory> m_xInvocationFactoryLocal;
+ Reference<XSingleServiceFactory> m_xInvocationFactoryRemote;
+
+private:
+ // Holds the type converter which is used for sequence conversion etc.
+ // Use the getTypeConverter function to obtain the interface.
+ Reference<XTypeConverter> m_typeConverter;
+
+
+};
+
+// ask the object for XBridgeSupplier2 and on success bridges
+// the uno object to IUnknown or IDispatch.
+// return true the UNO object supports
+template < class T >
+bool convertSelfToCom( T& unoInterface, VARIANT * pVar)
+{
+ bool ret = false;
+ Reference< XInterface > xInt( unoInterface, UNO_QUERY);
+ if( xInt.is())
+ {
+ Reference< XBridgeSupplier2 > xSupplier( xInt, UNO_QUERY);
+ if( xSupplier.is())
+ {
+ sal_Int8 arId[16];
+ rtl_getGlobalProcessId( (sal_uInt8*)arId);
+ Sequence<sal_Int8> seqId( arId, 16);
+ Any anySource;
+ anySource <<= xInt;
+ Any anyDisp= xSupplier->createBridge( anySource, seqId, UNO, OLE);
+ if( anyDisp.getValueTypeClass() == TypeClass_UNSIGNED_LONG)
+ {
+ VARIANT* pvariant= *(VARIANT**)anyDisp.getValue();
+ HRESULT hr;
+ if (FAILED(hr = VariantCopy(pVar, pvariant)))
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] convertSelfToCom\n"
+ "VariantCopy failed! Error: ") +
+ OUString::valueOf(hr));
+ VariantClear( pvariant);
+ CoTaskMemFree( pvariant);
+ ret = true;
+ }
+ }
+ }
+ return ret;
+}
+
+
+
+// Gets the invocation factory depending on the Type in the Any.
+// The factory can be created by a local or remote multi service factory.
+// In case there is a remote multi service factory available there are
+// some services or types for which the local factory is used. The exceptions
+// are: all structs.
+// Param anyObject - contains the object ( interface, struct) for what we need an invocation object.
+//
+template<class T>
+Reference< XSingleServiceFactory > UnoConversionUtilities<T>::getInvocationFactory(const Any& anyObject)
+{
+ Reference< XSingleServiceFactory > retVal;
+ MutexGuard guard( getBridgeMutex());
+ if( anyObject.getValueTypeClass() != TypeClass_STRUCT &&
+ m_smgrRemote.is() )
+ {
+ if( ! m_xInvocationFactoryRemote.is() )
+ m_xInvocationFactoryRemote= Reference<XSingleServiceFactory>(
+ m_smgrRemote->createInstance( INVOCATION_SERVICE), UNO_QUERY);
+ retVal= m_xInvocationFactoryRemote;
+ }
+ else
+ {
+ if( ! m_xInvocationFactoryLocal.is() )
+ m_xInvocationFactoryLocal= Reference<XSingleServiceFactory>(
+ m_smgr->createInstance(INVOCATION_SERVICE ), UNO_QUERY);
+ retVal= m_xInvocationFactoryLocal;
+ }
+ return retVal;
+}
+
+template<class T>
+void UnoConversionUtilities<T>::variantToAny( const VARIANTARG* pArg, Any& rAny, const Type& ptype, sal_Bool bReduceValueRange /* = sal_True */)
+{
+ try
+ {
+ HRESULT hr;
+ bool bFail = false;
+ bool bCannotConvert = false;
+ CComVariant var;
+
+ // There is no need to support indirect values, since they're not supported by UNO
+ if( FAILED(hr= VariantCopyInd( &var, const_cast<VARIANTARG*>(pArg)))) // remove VT_BYREF
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] UnoConversionUtilities<T>::variantToAny \n"
+ "VariantCopyInd failed for reason : ") + OUString::valueOf(hr));
+ bool bHandled = convertValueObject( & var, rAny);
+ if( bHandled)
+ OSL_ENSURE( rAny.getValueType() == ptype, "type in Value Object must match the type parameter");
+
+ if( ! bHandled)
+ {
+ // convert into a variant type that is the equivalent to the type
+ // the sequence expects. Thus variantToAny produces the correct type
+ // E.g. An Array object contains VT_I4 and the sequence expects shorts
+ // than the vartype must be changed. The reason is, you can't specify the
+ // type in JavaScript and the script engine determines the type beeing used.
+ switch( ptype.getTypeClass())
+ {
+ case TypeClass_CHAR: // could be: new Array( 12, 'w', "w")
+ if( var.vt == VT_BSTR)
+ {
+ if(SUCCEEDED( hr= VariantChangeType( &var, &var, 0, VT_BSTR)))
+ rAny.setValue( (void*)V_BSTR( &var), ptype);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ }
+ else
+ {
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_I2)))
+ rAny.setValue((void*) & var.iVal, ptype);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ }
+ break;
+ case TypeClass_INTERFACE: // could also be an IUnknown
+ case TypeClass_STRUCT:
+ {
+ rAny = createOleObjectWrapper( & var, ptype);
+ break;
+ }
+ case TypeClass_ENUM:
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_I4)))
+ rAny.setValue((void*) & var.lVal, ptype);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_SEQUENCE:
+ // There are different ways of receiving a sequence:
+ // 1: JScript, VARTYPE: VT_DISPATCH
+ // 2. VBScript simple arraysVT_VARIANT|VT_BYREF the referenced VARIANT contains
+ // a VT_ARRAY| <type>
+ // 3. VBSrcript multi dimensional arrays: VT_ARRAY|VT_BYREF
+ if( pArg->vt == VT_DISPATCH)
+ {
+ dispatchExObject2Sequence( pArg, rAny, ptype);
+ }
+ else
+ {
+ if ((var.vt & VT_ARRAY) != 0)
+ {
+ VARTYPE oleType = ::sal::static_int_cast< VARTYPE, int >( var.vt ^ VT_ARRAY );
+ Sequence<Any> unoSeq = createOleArrayWrapper( var.parray, oleType, ptype);
+ Reference<XTypeConverter> conv = getTypeConverter();
+ if (conv.is())
+ {
+ try
+ {
+ Any anySeq = makeAny(unoSeq);
+ Any convAny = conv->convertTo(anySeq, ptype);
+ rAny = convAny;
+ }
+ catch (IllegalArgumentException& e)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]com.sun.star.lang.IllegalArgumentException "
+ "in UnoConversionUtilities<T>::variantToAny! Message: ") +
+ e.Message);
+ }
+ catch (CannotConvertException& e)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]com.sun.star.script.CannotConvertException "
+ "in UnoConversionUtilities<T>::variantToAny! Message: ") +
+ e.Message);
+ }
+ }
+ }
+ }
+ break;
+ case TypeClass_VOID:
+ rAny.setValue(NULL,Type());
+ break;
+ case TypeClass_ANY: // Any
+ // There could be a JScript Array that needs special handling
+ // If an Any is expected and this Any must contain a Sequence
+ // then we cannot figure out what element type is required.
+ // Therefore we convert to Sequence< Any >
+ if( pArg->vt == VT_DISPATCH && isJScriptArray( pArg))
+ {
+ dispatchExObject2Sequence( pArg, rAny,
+ getCppuType((Sequence<Any>*) 0));
+ }
+ else if (pArg->vt == VT_DECIMAL)
+ {
+ //Decimal maps to hyper in calls from COM -> UNO
+ // It does not matter if we create a sal_uInt64 or sal_Int64,
+ // because the UNO object is called through invocation which
+ //will do a type conversion if necessary
+ if (var.decVal.sign == 0)
+ {
+ // positive value
+ variantToAny( & var, rAny, getCppuType( (sal_uInt64*) 0),
+ bReduceValueRange);
+ }
+ else
+ {
+ //negative value
+ variantToAny( & var, rAny, getCppuType( (sal_Int64*) 0),
+ bReduceValueRange);
+ }
+ }
+ else
+ {
+ variantToAny( & var, rAny);
+ }
+ break;
+ case TypeClass_BOOLEAN: // VARIANT could be VARIANT_BOOL or other
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_BOOL)))
+ variantToAny( & var, rAny);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_STRING: // UString
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_BSTR)))
+ variantToAny( & var, rAny);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_FLOAT: // float
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_R4)))
+ variantToAny( & var, rAny);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_DOUBLE: // double
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_R8)))
+ variantToAny(& var, rAny);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_BYTE: // BYTE
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_I1)))
+ variantToAny( & var, rAny);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_SHORT: // INT16
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_I2)))
+ variantToAny( & var, rAny);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_LONG:
+ if(SUCCEEDED(hr = VariantChangeType(& var, &var, 0, VT_I4)))
+ variantToAny( & var, rAny, bReduceValueRange);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_HYPER:
+ if(SUCCEEDED(hr = VariantChangeType(& var, &var, 0, VT_DECIMAL)))
+ {
+ if (var.decVal.Lo64 > SAL_CONST_UINT64(0x8000000000000000)
+ || var.decVal.Hi32 > 0
+ || var.decVal.scale > 0)
+ {
+ bFail = true;
+ break;
+ }
+ sal_Int64 value = var.decVal.Lo64;
+ if (var.decVal.sign == DECIMAL_NEG)
+ value |= SAL_CONST_UINT64(0x8000000000000000);
+ rAny <<= value;
+ }
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_UNSIGNED_SHORT: // UINT16
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_UI2)))
+ variantToAny( & var, rAny);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_UNSIGNED_LONG:
+ if(SUCCEEDED(hr = VariantChangeType( & var, &var, 0, VT_UI4)))
+ variantToAny( & var, rAny, bReduceValueRange);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_UNSIGNED_HYPER:
+ if(SUCCEEDED(hr = VariantChangeType(& var, &var, 0, VT_DECIMAL)))
+ {
+ if (var.decVal.Hi32 > 0 || var.decVal.scale > 0)
+ {
+ bFail = true;
+ break;
+ }
+ rAny <<= var.decVal.Lo64;
+ }
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ case TypeClass_TYPE:
+ if(SUCCEEDED(hr = VariantChangeType(& var, &var, 0, VT_UNKNOWN)))
+ variantToAny( & var, rAny);
+ else if (hr == DISP_E_TYPEMISMATCH)
+ bCannotConvert = true;
+ else
+ bFail = true;
+ break;
+ default:
+// case TypeClass_SERVICE: break; // meta construct
+// case TypeClass_TYPEDEF: break;
+// case TypeClass_UNION: break;
+// case TypeClass_MODULE: break; // module
+// case TypeClass_EXCEPTION: break;
+// case TypeClass_ARRAY: break; // there's no Array at the moment
+// case TypeClass_UNKNOWN: break;
+ bCannotConvert = true;
+ break;
+ }
+ }
+ if (bCannotConvert)
+ throw CannotConvertException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::variantToAny \n"
+ "Cannot convert the value of vartype :\"") +
+ OUString::valueOf((sal_Int32) var.vt) +
+ OUSTR("\" to the expected UNO type of type class: ") +
+ OUString::valueOf((sal_Int32) ptype.getTypeClass()),
+ 0, TypeClass_UNKNOWN, FailReason::TYPE_NOT_SUPPORTED,0);
+
+ if (bFail)
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>:variantToAny\n"
+ "The provided VARIANT of type\" ") + OUString::valueOf((sal_Int32) var.vt) +
+ OUSTR("\" is unappropriate for conversion!"), Reference<XInterface>(), -1);
+ }
+ catch (CannotConvertException &)
+ {
+ throw;
+ }
+ catch (IllegalArgumentException &)
+ {
+ throw;
+ }
+ catch (BridgeRuntimeError &)
+ {
+ throw;
+ }
+ catch (Exception & e)
+ {
+ throw BridgeRuntimeError(OUSTR("[automation bridge] unexpected exception in "
+ "UnoConversionUtilities<T>::variantToAny ! Message : \n") +
+ e.Message);
+ }
+ catch(...)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] unexpected exception in "
+ "UnoConversionUtilities<T>::variantToAny !"));
+ }
+}
+
+// The function only converts Sequences to SAFEARRAYS with elements of the type
+// specified by the parameter type. Everything else is forwarded to
+// anyToVariant(VARIANT* pVariant, const Any& rAny)
+// Param type must not be VT_BYREF
+template<class T>
+void UnoConversionUtilities<T>::anyToVariant(VARIANT* pVariant, const Any& rAny, VARTYPE type)
+{
+ try
+ {
+ HRESULT hr= S_OK;
+
+ OSL_ASSERT( (type & VT_BYREF) == 0);
+ if (type & VT_ARRAY)
+ {
+ type ^= VT_ARRAY;
+ SAFEARRAY* ar= createUnoSequenceWrapper( rAny, type);
+ if( ar)
+ {
+ VariantClear( pVariant);
+ pVariant->vt= ::sal::static_int_cast< VARTYPE, int >( VT_ARRAY | type );
+ pVariant->byref= ar;
+ }
+ }
+ else if(type == VT_VARIANT)
+ {
+ anyToVariant(pVariant, rAny);
+ }
+ else
+ {
+ CComVariant var;
+ anyToVariant( &var, rAny);
+ if(FAILED(hr = VariantChangeType(&var, &var, 0, type)))
+ {
+ if (hr == DISP_E_TYPEMISMATCH)
+ throw CannotConvertException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
+ "Cannot convert the value of type :\"") +
+ rAny.getValueTypeName() +
+ OUSTR("\" to the expected Automation type of VARTYPE: ") +
+ OUString::valueOf((sal_Int32)type),
+ 0, TypeClass_UNKNOWN, FailReason::TYPE_NOT_SUPPORTED,0);
+
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
+ "Conversion of any with ") +
+ rAny.getValueType().getTypeName() +
+ OUSTR(" to VARIANT with type: ") + OUString::valueOf((sal_Int32) type) +
+ OUSTR(" failed! Error code: ") + OUString::valueOf(hr));
+
+ }
+ if(FAILED(hr = VariantCopy(pVariant, &var)))
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
+ "VariantCopy failed for reason: ") + OUString::valueOf(hr));
+ }
+ }
+ }
+ catch (IllegalArgumentException &)
+ {
+ throw;
+ }
+ catch (CannotConvertException & )
+ {
+ throw;
+ }
+ catch (BridgeRuntimeError&)
+ {
+ throw;
+ }
+ catch(Exception & e)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
+ "Unexpected exception occurred. Message: ") + e.Message);
+ }
+ catch(...)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
+ "Unexpected exception occurred."));
+ }
+}
+
+template<class T>
+void UnoConversionUtilities<T>::anyToVariant(VARIANT* pVariant, const Any& rAny)
+{
+ bool bIllegal = false;
+ try
+ {
+ switch (rAny.getValueTypeClass())
+ {
+ case TypeClass_INTERFACE:
+ {
+ Reference<XInterface> xInt;
+ if (rAny >>= xInt)
+ {
+ createUnoObjectWrapper(rAny, pVariant);
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ break;
+ }
+ case TypeClass_STRUCT:
+ {
+ if (rAny.getValueType() == getCppuType((Date*)0))
+ {
+ Date d;
+ if (rAny >>= d)
+ {
+ pVariant->vt = VT_DATE;
+ pVariant->date = d.Value;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ }
+ else if(rAny.getValueType() == getCppuType((Decimal*)0))
+ {
+ Decimal d;
+ if (rAny >>= d)
+ {
+ pVariant->vt = VT_DECIMAL;
+ pVariant->decVal.scale = d.Scale;
+ pVariant->decVal.sign = d.Sign;
+ pVariant->decVal.Lo32 = d.LowValue;
+ pVariant->decVal.Mid32 = d.MiddleValue;
+ pVariant->decVal.Hi32 = d.HighValue;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ }
+ else if (rAny.getValueType() == getCppuType((Currency*)0))
+ {
+ Currency c;
+ if (rAny >>= c)
+ {
+ pVariant->vt = VT_CY;
+ pVariant->cyVal.int64 = c.Value;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ }
+ else if(rAny.getValueType() == getCppuType((SCode*)0))
+ {
+ SCode s;
+ if (rAny >>= s)
+ {
+ pVariant->vt = VT_ERROR;
+ pVariant->scode = s.Value;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ }
+ else
+ {
+ createUnoObjectWrapper(rAny, pVariant);
+ }
+ break;
+ }
+ case TypeClass_SEQUENCE: // sequence ??? SafeArray descriptor
+ {
+ SAFEARRAY* pArray = createUnoSequenceWrapper(rAny);
+ if (pArray)
+ {
+ V_VT(pVariant) = VT_ARRAY | VT_VARIANT;
+ V_ARRAY(pVariant) = pArray;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ break;
+ }
+ case TypeClass_VOID:
+ {
+ HRESULT hr = S_OK;
+ if (FAILED(hr = VariantClear(pVariant)))
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant\n"
+ "VariantClear failed with error:") + OUString::valueOf(hr));
+ }
+ break;
+ }
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool value;
+ if (rAny >>= value)
+ {
+ pVariant->vt = VT_BOOL;
+ pVariant->boolVal = value == sal_True? VARIANT_TRUE: VARIANT_FALSE;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ break;
+ }
+ case TypeClass_CHAR:
+ {
+ // Because VT_UI2 does not conform to oleautomation we convert into VT_I2 instead
+ sal_uInt16 value = *(sal_Unicode*) rAny.getValue();
+ pVariant->vt = VT_I2;
+ pVariant->iVal = value;
+ break;
+ }
+ case TypeClass_STRING:
+ {
+ OUString value;
+ if (rAny >>= value)
+ {
+ pVariant->vt = VT_BSTR;
+ pVariant->bstrVal = SysAllocString(reinterpret_cast<LPCOLESTR>(value.getStr()));
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ break;
+ }
+ case TypeClass_FLOAT:
+ {
+ float value;
+ if (rAny >>= value)
+ {
+ pVariant->vt = VT_R4;
+ pVariant->fltVal = value;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ break;
+ }
+ case TypeClass_DOUBLE:
+ {
+ double value;
+ if (rAny >>= value)
+ {
+ pVariant->vt = VT_R8;
+ pVariant->dblVal = value;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ break;
+ }
+ case TypeClass_BYTE:
+ {
+ // ole automation does not know a signed char but only unsigned char
+ sal_Int8 value;
+ if (rAny >>= value)
+ {
+ pVariant->vt = VT_UI1;
+ pVariant->bVal = value;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ break;
+ }
+ case TypeClass_SHORT: // INT16
+ case TypeClass_UNSIGNED_SHORT: // UINT16
+ {
+ sal_Int16 value;
+ if (rAny >>= value)
+ {
+ pVariant->vt = VT_I2;
+ pVariant->iVal = value;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ break;
+ }
+ case TypeClass_ENUM:
+ {
+ sal_Int32 value = *(sal_Int32*) rAny.getValue();
+ pVariant->vt = VT_I4;
+ pVariant->lVal= value;
+ break;
+ }
+ case TypeClass_LONG:
+ case TypeClass_UNSIGNED_LONG:
+ {
+ sal_Int32 value;
+ if (rAny >>= value)
+ {
+ pVariant->vt = VT_I4;
+ pVariant->lVal= value;
+ }
+ else
+ {
+ bIllegal = true;
+ }
+ break;
+ }
+ case TypeClass_HYPER:
+ {
+
+ pVariant->vt = VT_DECIMAL;
+ pVariant->decVal.scale = 0;
+ pVariant->decVal.sign = 0;
+ pVariant->decVal.Hi32 = 0;
+
+ sal_Int64 value;
+ rAny >>= value;
+
+ if (value & SAL_CONST_UINT64(0x8000000000000000))
+ pVariant->decVal.sign = DECIMAL_NEG;
+
+ pVariant->decVal.Lo64 = value;
+ break;
+ }
+ case TypeClass_UNSIGNED_HYPER:
+ {
+ pVariant->vt = VT_DECIMAL;
+ pVariant->decVal.scale = 0;
+ pVariant->decVal.sign = 0;
+ pVariant->decVal.Hi32 = 0;
+
+ sal_uInt64 value;
+ rAny >>= value;
+ pVariant->decVal.Lo64 = value;
+ break;
+ }
+ case TypeClass_TYPE:
+ {
+ Type type;
+ rAny >>= type;
+ CComVariant var;
+ if (createUnoTypeWrapper(type.getTypeName(), & var) == false)
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] UnoConversionUtilities<T>::anyToVariant \n"
+ "Error during conversion of UNO type to Automation object!"));
+
+ if (FAILED(VariantCopy(pVariant, &var)))
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] UnoConversionUtilities<T>::anyToVariant \n"
+ "Unexpected error!"));
+ break;
+ }
+ default:
+ //TypeClass_SERVICE:
+ //TypeClass_EXCEPTION:
+ //When a InvocationTargetException is thrown when calling XInvocation::invoke
+ //on a UNO object, then the target exception is directly used to create a
+ //EXEPINFO structure
+ //TypeClass_TYPEDEF
+ //TypeClass_ANY:
+ //TypeClass_UNKNOWN:
+ //TypeClass_UNSIGNED_OCTET:
+ // TypeClass_UNION:
+ // TypeClass_ARRAY:
+ // TypeClass_UNSIGNED_INT:
+ // TypeClass_UNSIGNED_BYTE:
+ // TypeClass_MODULE:
+ throw CannotConvertException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant\n"
+ "There is no conversion for this UNO type to a Automation type."
+ "The destination type class is the type class of the UNO "
+ "argument which was to be converted."),
+ Reference<XInterface>(), rAny.getValueTypeClass(),
+ FailReason::TYPE_NOT_SUPPORTED, 0);
+
+ break;
+ }
+ if (bIllegal)
+ {
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant\n"
+ "The provided any of type\" ") + rAny.getValueType().getTypeName() +
+ OUSTR("\" is unappropriate for conversion!"), Reference<XInterface>(), -1);
+
+ }
+ }
+ catch (CannotConvertException & )
+ {
+ throw;
+ }
+ catch (IllegalArgumentException & )
+ {
+ throw;
+ }
+ catch(BridgeRuntimeError&)
+ {
+ throw;
+ }
+ catch(Exception & e)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
+ "Unexpected exception occurred. Message: ") + e.Message);
+ }
+ catch(...)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
+ "Unexpected exception occurred. ") );
+ }
+}
+
+// Creates an SAFEARRAY of the specified element and if necessary
+// creates a SAFEARRAY whith multiple dimensions.
+// Used by sal_Bool anyToVariant(VARIANT* pVariant, const Any& rAny, VARTYPE type);
+template<class T>
+SAFEARRAY* UnoConversionUtilities<T>::createUnoSequenceWrapper(const Any& rSeq, VARTYPE elemtype)
+{
+ if (rSeq.getValueTypeClass() != TypeClass_SEQUENCE)
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::createUnoSequenceWrapper \n"
+ "The any does not contain a sequence!"), 0, 0);
+ if (elemtype == VT_NULL || elemtype == VT_EMPTY)
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::createUnoSequenceWrapper \n"
+ "No element type supplied!"),0, -1);
+ SAFEARRAY* pArray= NULL;
+ // Get the dimensions. This is done by examining the type name string
+ // The count of brackets determines the dimensions.
+ OUString sTypeName= rSeq.getValueType().getTypeName();
+ sal_Int32 dims=0;
+ for(sal_Int32 lastIndex=0;(lastIndex= sTypeName.indexOf( L'[', lastIndex)) != -1; lastIndex++,dims++);
+
+ //get the maximum number of elements per dimensions and the typedescription of the elements
+ Sequence<sal_Int32> seqElementCounts( dims);
+ TypeDescription elementTypeDesc;
+ getElementCountAndTypeOfSequence( rSeq, 1, seqElementCounts, elementTypeDesc );
+
+ if( elementTypeDesc.is() )
+ {
+ // set up the SAFEARRAY
+ scoped_array<SAFEARRAYBOUND> sarSafeArrayBound(new SAFEARRAYBOUND[dims]);
+ SAFEARRAYBOUND* prgsabound= sarSafeArrayBound.get();
+ for( sal_Int32 i=0; i < dims; i++)
+ {
+ //prgsabound[0] is the right most dimension
+ prgsabound[dims - i - 1].lLbound = 0;
+ prgsabound[dims - i - 1].cElements = seqElementCounts[i];
+ }
+
+ typelib_TypeDescription* rawTypeDesc= elementTypeDesc.get();
+ sal_Int32 elementSize= rawTypeDesc->nSize;
+ size_t oleElementSize= getOleElementSize( elemtype);
+ // SafeArrayCreate clears the memory for the data itself.
+ pArray = SafeArrayCreate(elemtype, dims, prgsabound);
+
+ // convert the Sequence's elements and populate the SAFEARRAY
+ if( pArray)
+ {
+ // Iterate over every Sequence that contains the actual elements
+ void* pSAData;
+ if( SUCCEEDED( SafeArrayAccessData( pArray, &pSAData)))
+ {
+ const sal_Int32* parElementCount= seqElementCounts.getConstArray();
+ uno_Sequence * pMultiSeq= *(uno_Sequence* const*) rSeq.getValue();
+ sal_Int32 dimsSeq= dims - 1;
+
+ // arDimSeqIndizes contains the current index of a block of data.
+ // E.g. Sequence<Sequence<sal_Int32>> , the index would refer to Sequence<sal_Int32>
+ // In this case arDimSeqIndices would have the size 1. That is the elements are not counted
+ // but the Sequences that contain those elements.
+ // The indices ar 0 based
+ scoped_array<sal_Int32> sarDimsSeqIndices;
+ sal_Int32* arDimsSeqIndices= NULL;
+ if( dimsSeq > 0)
+ {
+ sarDimsSeqIndices.reset(new sal_Int32[dimsSeq]);
+ arDimsSeqIndices = sarDimsSeqIndices.get();
+ memset( arDimsSeqIndices, 0, sizeof( sal_Int32 ) * dimsSeq);
+ }
+
+ char* psaCurrentData= (char*)pSAData;
+
+ do
+ {
+ // Get the Sequence at the current index , see arDimsSeqIndices
+ uno_Sequence * pCurrentSeq= pMultiSeq;
+ sal_Int32 curDim=1; // 1 based
+ sal_Bool skipSeq= sal_False;
+ while( curDim <= dimsSeq )
+ {
+ // get the Sequence at the index if valid
+ if( pCurrentSeq->nElements > arDimsSeqIndices[ curDim - 1] ) // don't point to Nirvana
+ {
+ // size of Sequence is 4
+ sal_Int32 offset= arDimsSeqIndices[ curDim - 1] * 4;
+ pCurrentSeq= *(uno_Sequence**) &pCurrentSeq->elements[ offset];
+ curDim++;
+ }
+ else
+ {
+ // There is no Sequence at this index, so skip this index
+ skipSeq= sal_True;
+ break;
+ }
+ }
+
+ if( skipSeq)
+ continue;
+
+ // Calculate the current position within the datablock of the SAFEARRAY
+ // for the next Sequence.
+ sal_Int32 memOffset= 0;
+ sal_Int32 dimWeight= parElementCount[ dims - 1]; // size of the rightmost dimension
+ for(sal_Int16 idims=0; idims < dimsSeq; idims++ )
+ {
+ memOffset+= arDimsSeqIndices[dimsSeq - 1 - idims] * dimWeight;
+ // now determine the weight of the dimension to the left of the current.
+ if( dims - 2 - idims >=0)
+ dimWeight*= parElementCount[dims - 2 - idims];
+ }
+ psaCurrentData= (char*)pSAData + memOffset * oleElementSize;
+ // convert the Sequence and put the elements into the Safearray
+ for( sal_Int32 i= 0; i < pCurrentSeq->nElements; i++)
+ {
+ Any unoElement( pCurrentSeq->elements + i * elementSize, rawTypeDesc );
+ // The any is being converted into an VARIANT which value is then copied
+ // to the SAFEARRAY's data block. When copying one has to follow the rules for
+ // copying certain types, as are VT_DISPATCH, VT_UNKNOWN, VT_VARIANT, VT_BSTR.
+ // To increase performance, we just do a memcpy of VARIANT::byref. This is possible
+ // because anyToVariant has already followed the copying rules. To make this
+ // work there must not be a VariantClear.
+ // One Exception is VARIANT because I don't know how VariantCopy works.
+
+ VARIANT var;
+ VariantInit( &var);
+ anyToVariant( &var, unoElement);
+ if( elemtype == VT_VARIANT )
+ {
+ VariantCopy( ( VARIANT*)psaCurrentData, &var);
+ VariantClear( &var);
+ }
+ else
+ memcpy( psaCurrentData, &var.byref, oleElementSize);
+
+ psaCurrentData+= oleElementSize;
+ }
+ }
+ while( incrementMultidimensionalIndex( dimsSeq, parElementCount, arDimsSeqIndices));
+
+ SafeArrayUnaccessData( pArray);
+ }
+ }
+ }
+ return pArray;
+}
+
+// Increments a multi dimensional index.
+// Returns true as long as the index has been successfully incremented, false otherwise.
+// False is also returned if an overflow of the most significant dimension occurs. E.g.
+// assume an array with the dimensions (2,2), then the lowest index is (0,0) and the highest
+// index is (1,1). If the function is being called with the index (1,1) then the overflow would
+// occur, with the result (0,0) and a sal_False as return value.
+// Param dimensions - number of dimensions
+// Param parDimensionsLength - The array contains the size of each dimension, that is the
+// size of the array equals the parameter dimensions.
+// The rightmost dimensions is the least significant one
+// ( parDimensionsLengths[ dimensions -1 ] ).
+// Param parMultiDimensionalIndex - The array contains the index. Each dimension index is
+// 0 based.
+template<class T>
+sal_Bool UnoConversionUtilities<T>::incrementMultidimensionalIndex(sal_Int32 dimensions,
+ const sal_Int32 * parDimensionLengths,
+ sal_Int32 * parMultidimensionalIndex)
+{
+ if( dimensions < 1)
+ return sal_False;
+
+ sal_Bool ret= sal_True;
+ sal_Bool carry= sal_True; // to get into the while loop
+
+ sal_Int32 currentDimension= dimensions; //most significant is 1
+ while( carry)
+ {
+ parMultidimensionalIndex[ currentDimension - 1]++;
+ // if carryover, set index to 0 and handle carry on a level above
+ if( parMultidimensionalIndex[ currentDimension - 1] > (parDimensionLengths[ currentDimension - 1] - 1))
+ parMultidimensionalIndex[ currentDimension - 1]= 0;
+ else
+ carry= sal_False;
+
+ currentDimension --;
+ // if dimensions drops below 1 and carry is set than then all indices are 0 again
+ // this is signalled by returning sal_False
+ if( currentDimension < 1 && carry)
+ {
+ carry= sal_False;
+ ret= sal_False;
+ }
+ }
+ return ret;
+}
+
+// Determines the size of a certain OLE type. The function takes
+// only those types into account which are oleautomation types and
+// can have a value ( unless VT_NULL, VT_EMPTY, VT_ARRAY, VT_BYREF).
+// Currently used in createUnoSequenceWrapper to calculate addresses
+// for data within a SAFEARRAY.
+template<class T>
+size_t UnoConversionUtilities<T>::getOleElementSize( VARTYPE type)
+{
+ size_t size;
+ switch( type)
+ {
+ case VT_BOOL: size= sizeof( VARIANT_BOOL);break;
+ case VT_UI1: size= sizeof( unsigned char);break;
+ case VT_R8: size= sizeof( double);break;
+ case VT_R4: size= sizeof( float);break;
+ case VT_I2: size= sizeof( short);break;
+ case VT_I4: size= sizeof( long);break;
+ case VT_BSTR: size= sizeof( BSTR); break;
+ case VT_ERROR: size= sizeof( SCODE); break;
+ case VT_DISPATCH:
+ case VT_UNKNOWN: size= sizeof( IUnknown*); break;
+ case VT_VARIANT: size= sizeof( VARIANT);break;
+ default: size= 0;
+ }
+ return size;
+}
+
+//If a Sequence is being converted into a SAFEARRAY then we possibly have
+// to create a SAFEARRAY with multiple dimensions. This is the case when a
+// Sequence contains Sequences ( Sequence< Sequence < XXX > > ). The leftmost
+// Sequence in the declaration is assumed to represent dimension 1. Because
+// all Sequence elements of a Sequence can have different length, we have to
+// determine the maximum length which is then the length of the respective
+// dimension.
+// getElementCountAndTypeOfSequence determines the length of each dimension and calls itself recursively
+// in the process.
+// param rSeq - an Any that has to contain a Sequence
+// param dim - the dimension for which the number of elements is being determined,
+// must be one.
+// param seqElementCounts - countains the maximum number of elements for each
+// dimension. Index 0 contains the number of dimension one.
+// After return the Sequence contains the maximum number of
+// elements for each dimension.
+// The length of the Sequence must equal the number of dimensions.
+// param typeClass - TypeClass of the element type that is no Sequence, e.g.
+// Sequence< Sequence <Sequence <sal_Int32> > > - type is sal_Int32)
+template<class T>
+void UnoConversionUtilities<T>::getElementCountAndTypeOfSequence( const Any& rSeq, sal_Int32 dim,
+ Sequence< sal_Int32 >& seqElementCounts, TypeDescription& typeDesc)
+{
+ sal_Int32 dimCount= (*(uno_Sequence* const *) rSeq.getValue())->nElements;
+ if( dimCount > seqElementCounts[ dim-1])
+ seqElementCounts[ dim-1]= dimCount;
+
+ // we need the element type to construct the any that is
+ // passed into getElementCountAndTypeOfSequence again
+ typelib_TypeDescription* pSeqDesc= NULL;
+ rSeq.getValueTypeDescription( &pSeqDesc);
+ typelib_TypeDescriptionReference* pElementDescRef= ((typelib_IndirectTypeDescription*)pSeqDesc)->pType;
+
+ // if the elements are Sequences than do recursion
+ if( dim < seqElementCounts.getLength() )
+ {
+ uno_Sequence* pSeq = *(uno_Sequence* const*) rSeq.getValue();
+ uno_Sequence** arSequences= (uno_Sequence**)pSeq->elements;
+ for( sal_Int32 i=0; i < dimCount; i++)
+ {
+ uno_Sequence* arElement= arSequences[ i];
+ getElementCountAndTypeOfSequence( Any( &arElement, pElementDescRef), dim + 1 , seqElementCounts, typeDesc);
+ }
+ }
+ else
+ {
+ // determine the element type ( e.g. Sequence< Sequence <Sequence <sal_Int32> > > - type is sal_Int32)
+ typeDesc= pElementDescRef;
+ }
+ typelib_typedescription_release( pSeqDesc);
+}
+
+
+template<class T>
+SAFEARRAY* UnoConversionUtilities<T>::createUnoSequenceWrapper(const Any& rSeq)
+{
+ SAFEARRAY* pArray = NULL;
+ sal_uInt32 n = 0;
+
+ if( rSeq.getValueTypeClass() != TypeClass_SEQUENCE )
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::createUnoSequenceWrapper\n"
+ "The UNO argument is not a sequence"), 0, -1);
+
+ uno_Sequence * punoSeq= *(uno_Sequence**) rSeq.getValue();
+
+ typelib_TypeDescriptionReference* pSeqTypeRef= rSeq.getValueTypeRef();
+ typelib_TypeDescription* pSeqType= NULL;
+ TYPELIB_DANGER_GET( &pSeqType, pSeqTypeRef);
+ typelib_IndirectTypeDescription * pSeqIndDec= (typelib_IndirectTypeDescription*) pSeqType;
+
+
+ typelib_TypeDescriptionReference * pSeqElementTypeRef= pSeqIndDec->pType;
+ TYPELIB_DANGER_RELEASE( pSeqType);
+
+ typelib_TypeDescription* pSeqElementDesc= NULL;
+ TYPELIB_DANGER_GET( &pSeqElementDesc, pSeqElementTypeRef);
+
+ // try to find VARIANT type that is related to the UNO type of the sequence elements
+ // the sequence as a sequence element should be handled in a special way
+ VARTYPE eTargetElementType = VT_EMPTY;
+ if ( pSeqElementDesc->eTypeClass != TypeClass_SEQUENCE )
+ eTargetElementType = mapTypeClassToVartype( static_cast< TypeClass >( pSeqElementDesc->eTypeClass ) );
+
+ if ( eTargetElementType != VT_EMPTY )
+ pArray = createUnoSequenceWrapper( rSeq, eTargetElementType );
+
+ if ( !pArray )
+ {
+ sal_Int32 nElementSize= pSeqElementDesc->nSize;
+ n= punoSeq->nElements;
+
+ SAFEARRAYBOUND rgsabound[1];
+ rgsabound[0].lLbound = 0;
+ rgsabound[0].cElements = n;
+ VARIANT oleElement;
+ long safeI[1];
+
+ pArray = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
+
+ Any unoElement;
+ // sal_uInt8 * pSeqData= (sal_uInt8*) punoSeq->pElements;
+ sal_uInt8 * pSeqData= (sal_uInt8*) punoSeq->elements;
+
+ for (sal_uInt32 i = 0; i < n; i++)
+ {
+ unoElement.setValue( pSeqData + i * nElementSize, pSeqElementDesc);
+ VariantInit(&oleElement);
+
+ anyToVariant(&oleElement, unoElement);
+
+ safeI[0] = i;
+ SafeArrayPutElement(pArray, safeI, &oleElement);
+
+ VariantClear(&oleElement);
+ }
+ }
+
+ TYPELIB_DANGER_RELEASE( pSeqElementDesc);
+
+ return pArray;
+}
+
+/* The argument rObj can contain
+- UNO struct
+- UNO interface
+- UNO interface created by this bridge (adapter factory)
+- UNO interface created by this bridge ( COM Wrapper)
+
+pVar must be initialized.
+*/
+template<class T>
+void UnoConversionUtilities<T>::createUnoObjectWrapper(const Any & rObj, VARIANT * pVar)
+{
+ MutexGuard guard(getBridgeMutex());
+
+ Reference<XInterface> xInt;
+
+ TypeClass tc = rObj.getValueTypeClass();
+ if (tc != TypeClass_INTERFACE && tc != TypeClass_STRUCT)
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::createUnoObjectWrapper \n"
+ "Cannot create an Automation interface for a UNO type which is not "
+ "a struct or interface!"), 0, -1);
+
+ if (rObj.getValueTypeClass() == TypeClass_INTERFACE)
+ {
+ if (! (rObj >>= xInt))
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge] UnoConversionUtilities<T>::createUnoObjectWrapper\n "
+ "Could not create wrapper object for UNO object!"), 0, -1);
+ //If XInterface is NULL, which is a valid value, then simply return NULL.
+ if ( ! xInt.is())
+ {
+ pVar->vt = VT_UNKNOWN;
+ pVar->punkVal = NULL;
+ return;
+ }
+ //make sure we have the main XInterface which is used with a map
+ xInt = Reference<XInterface>(xInt, UNO_QUERY);
+ //If there is already a wrapper for the UNO object then use it
+
+ Reference<XInterface> xIntWrapper;
+ // Does a UNO wrapper exist already ?
+ IT_Uno it_uno = UnoObjToWrapperMap.find( (sal_uInt32) xInt.get());
+ if(it_uno != UnoObjToWrapperMap.end())
+ {
+ xIntWrapper = it_uno->second;
+ if (xIntWrapper.is())
+ {
+ convertSelfToCom(xIntWrapper, pVar);
+ return;
+ }
+ }
+ // Is the object a COM wrapper ( either XInvocation, or Adapter object)
+ // or does it suppy an IDispatch by its own ?
+ else
+ {
+ Reference<XInterface> xIntComWrapper = xInt;
+ typedef hash_map<sal_uInt32,sal_uInt32>::iterator _IT;
+ // Adapter? then get the COM wrapper to which the adapter delegates its calls
+ _IT it= AdapterToWrapperMap.find( (sal_uInt32) xInt.get());
+ if( it != AdapterToWrapperMap.end() )
+ xIntComWrapper= reinterpret_cast<XInterface*>(it->second);
+
+ if (convertSelfToCom(xIntComWrapper, pVar))
+ return;
+ }
+ }
+ // If we have no UNO wrapper nor the IDispatch yet then we have to create
+ // a wrapper. For that we need an XInvocation from the UNO object.
+
+ // get an XInvocation or create one using the invocation service
+ Reference<XInvocation> xInv(xInt, UNO_QUERY);
+ if ( ! xInv.is())
+ {
+ Reference<XSingleServiceFactory> xInvFactory= getInvocationFactory(rObj);
+ if (xInvFactory.is())
+ {
+ Sequence<Any> params(1);
+ params.getArray()[0] = rObj;
+ Reference<XInterface> xInt = xInvFactory->createInstanceWithArguments(params);
+ xInv= Reference<XInvocation>(xInt, UNO_QUERY);
+ }
+ }
+
+ if (xInv.is())
+ {
+ Reference<XInterface> xNewWrapper = createUnoWrapperInstance();
+ Reference<XInitialization> xInitWrapper(xNewWrapper, UNO_QUERY);
+ if (xInitWrapper.is())
+ {
+ VARTYPE vartype= getVarType( rObj);
+
+ if (xInt.is())
+ {
+ Any params[3];
+ params[0] <<= xInv;
+ params[1] <<= xInt;
+ params[2] <<= vartype;
+ xInitWrapper->initialize( Sequence<Any>(params, 3));
+ }
+ else
+ {
+ Any params[2];
+ params[0] <<= xInv;
+ params[1] <<= vartype;
+ xInitWrapper->initialize( Sequence<Any>(params, 2));
+ }
+
+ // put the newly created object into a map. If the same object will
+ // be mapped again and there is already a wrapper then the old wrapper
+ // will be used.
+ if(xInt.is()) // only interfaces
+ UnoObjToWrapperMap[(sal_uInt32) xInt.get()]= xNewWrapper;
+ convertSelfToCom(xNewWrapper, pVar);
+ return;
+ }
+ }
+}
+
+template<class T>
+void UnoConversionUtilities<T>::variantToAny( const VARIANT* pVariant, Any& rAny,
+ sal_Bool bReduceValueRange /* = sal_True */)
+{
+ HRESULT hr = S_OK;
+ try
+ {
+ CComVariant var;
+
+ // There is no need to support indirect values, since they're not supported by UNO
+ if( FAILED(hr= VariantCopyInd( &var, const_cast<VARIANTARG*>(pVariant)))) // remove VT_BYREF
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] UnoConversionUtilities<T>::variantToAny \n"
+ "VariantCopyInd failed for reason : ") + OUString::valueOf(hr));
+
+ if ( ! convertValueObject( & var, rAny))
+ {
+ if ((var.vt & VT_ARRAY) > 0)
+ {
+ VARTYPE oleTypeFlags = ::sal::static_int_cast< VARTYPE, int >( var.vt ^ VT_ARRAY );
+
+ Sequence<Any> unoSeq = createOleArrayWrapper(var.parray, oleTypeFlags);
+ rAny.setValue( &unoSeq, getCppuType( &unoSeq));
+ }
+ else
+ {
+ switch (var.vt)
+ {
+ case VT_EMPTY:
+ rAny.setValue(NULL, Type());
+ break;
+ case VT_NULL:
+ rAny.setValue(NULL, Type());
+ break;
+ case VT_I2:
+ rAny.setValue( & var.iVal, getCppuType( (sal_Int16*)0));
+ break;
+ case VT_I4:
+ rAny.setValue( & var.lVal, getCppuType( (sal_Int32*)0));
+ // necessary for use in JavaScript ( see "reduceRange")
+ if( bReduceValueRange)
+ reduceRange(rAny);
+ break;
+ case VT_R4:
+ rAny.setValue( & var.fltVal, getCppuType( (float*)0));
+ break;
+ case VT_R8:
+ rAny.setValue(& var.dblVal, getCppuType( (double*)0));
+ break;
+ case VT_CY:
+ {
+ Currency cy(var.cyVal.int64);
+ rAny <<= cy;
+ break;
+ }
+ case VT_DATE:
+ {
+ Date d(var.date);
+ rAny <<= d;
+ break;
+ }
+ case VT_BSTR:
+ {
+ OUString b(reinterpret_cast<const sal_Unicode*>(var.bstrVal));
+ rAny.setValue( &b, getCppuType( &b));
+ break;
+ }
+ case VT_UNKNOWN:
+ case VT_DISPATCH:
+ {
+ //check if it is a UNO type
+#ifdef __MINGW32__
+ CComQIPtr<IUnoTypeWrapper, &__uuidof(IUnoTypeWrapper)> spType((IUnknown*) var.byref);
+#else
+ CComQIPtr<IUnoTypeWrapper> spType((IUnknown*) var.byref);
+#endif
+ if (spType)
+ {
+ CComBSTR sName;
+ if (FAILED(spType->get_Name(&sName)))
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::variantToAny \n"
+ "Failed to get the type name from a UnoTypeWrapper!"));
+ Type type;
+ if (getType(sName, type) == false)
+ {
+ throw CannotConvertException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::variantToAny \n"
+ "A UNO type with the name: ") + OUString(reinterpret_cast<const sal_Unicode*>(LPCOLESTR(sName))) +
+ OUSTR("does not exist!"),
+ 0, TypeClass_UNKNOWN, FailReason::TYPE_NOT_SUPPORTED,0);
+ }
+ rAny <<= type;
+ }
+ else
+ {
+ rAny = createOleObjectWrapper( & var);
+ }
+ break;
+ }
+ case VT_ERROR:
+ {
+ SCode scode(var.scode);
+ rAny <<= scode;
+ break;
+ }
+ case VT_BOOL:
+ {
+ sal_Bool b= var.boolVal == VARIANT_TRUE;
+ rAny.setValue( &b, getCppuType( &b));
+ break;
+ }
+ case VT_I1:
+ rAny.setValue( & var.cVal, getCppuType((sal_Int8*)0));
+ break;
+ case VT_UI1: // there is no unsigned char in UNO
+ rAny.setValue( & var.bVal, getCppuType( (sal_Int8*)0));
+ break;
+ case VT_UI2:
+ rAny.setValue( & var.uiVal, getCppuType( (sal_uInt16*)0));
+ break;
+ case VT_UI4:
+ rAny.setValue( & var.ulVal, getCppuType( (sal_uInt32*)0));
+ break;
+ case VT_INT:
+ rAny.setValue( & var.intVal, getCppuType( (sal_Int32*)0));
+ break;
+ case VT_UINT:
+ rAny.setValue( & var.uintVal, getCppuType( (sal_uInt32*)0));
+ break;
+ case VT_VOID:
+ rAny.setValue( NULL, Type());
+ break;
+ case VT_DECIMAL:
+ {
+ Decimal dec;
+ dec.Scale = var.decVal.scale;
+ dec.Sign = var.decVal.sign;
+ dec.LowValue = var.decVal.Lo32;
+ dec.MiddleValue = var.decVal.Mid32;
+ dec.HighValue = var.decVal.Hi32;
+ rAny <<= dec;
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ catch (IllegalArgumentException & )
+ {
+ throw;
+ }
+ catch (CannotConvertException &)
+ {
+ throw;
+ }
+ catch (BridgeRuntimeError & )
+ {
+ throw;
+ }
+ catch (Exception & e)
+ {
+ throw BridgeRuntimeError(OUSTR("[automation bridge] unexpected exception in "
+ "UnoConversionUtilities<T>::variantToAny ! Message : \n") +
+ e.Message);
+ }
+ catch(...)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] unexpected exception in "
+ "UnoConversionUtilities<T>::variantToAny !"));
+ }
+
+}
+// The function converts an IUnknown* into an UNO interface or struct. The
+// IUnknown pointer can constitute different kind of objects:
+// 1. a wrapper of an UNO struct (the wrapper was created by this bridge)
+// 2. a wrapper of an UNO interface (created by this bridge)
+// 3. a dispatch object that implements UNO interfaces
+// 4. a dispatch object.
+
+// If the parameter "aType" has a value then the COM object ( pUnknown) is supposed to
+// implement the interface described by "aType". Moreover it ( pUnknown) can implement
+// several other
+// UNO interfaces in which case it has to support the SUPPORTED_INTERFACES_PROP (see
+// #define) property. That property contains all names of interfaces.
+// "pUnknown" is wrapped by a COM wrapper object that implements XInvocation, e.g.
+// IUnknownWrapper_Impl. Additionally an object of type "aType" is created by help
+// of the INTERFACE_ADAPTER_FACTORY (see #define) service. The implementation of
+// "aType" calls on the COM wrapper's XInvocation::invoke. If the COM object supports
+// more then one UNO interfaces, as can be determined by the property
+// SUPPORTED_INTERFACES_PROP, then the INTERFACE_ADAPTER_FACTORY creates an object that
+// implements all these interfaces.
+// This is only done if "pUnknown" is not already a UNO wrapper,
+// that is it is actually NOT an UNO object that was converted to a COM object. If it is an
+// UNO wrapper than the original UNO object is being extracted, queried for "aType" (if
+// it is no struct) and returned.
+template<class T>
+#ifdef __MINGW32__
+Any UnoConversionUtilities<T>::createOleObjectWrapper(VARIANT* pVar, const Type& aType)
+#else
+Any UnoConversionUtilities<T>::createOleObjectWrapper(VARIANT* pVar, const Type& aType= Type())
+#endif
+{
+ //To allow passing "Nothing" in VS 2008 we need to accept VT_EMPTY
+ if (pVar->vt != VT_UNKNOWN && pVar->vt != VT_DISPATCH && pVar->vt != VT_EMPTY)
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
+ "The VARIANT does not contain an object type! "), 0, -1);
+
+ MutexGuard guard( getBridgeMutex());
+
+ CComPtr<IUnknown> spUnknown;
+ CComPtr<IDispatch> spDispatch;
+
+ if (pVar->vt == VT_UNKNOWN)
+ {
+ spUnknown = pVar->punkVal;
+ if (spUnknown)
+#ifdef __MINGW32__
+ spUnknown->QueryInterface( IID_IDispatch, reinterpret_cast<LPVOID*>( & spDispatch.p));
+#else
+ spUnknown.QueryInterface( & spDispatch.p);
+#endif
+ }
+ else if (pVar->vt == VT_DISPATCH && pVar->pdispVal != NULL)
+ {
+ CComPtr<IDispatch> spDispatch(pVar->pdispVal);
+ if (spDispatch)
+#ifdef __MINGW32__
+ spDispatch->QueryInterface( IID_IUnknown, reinterpret_cast<LPVOID*>( & spUnknown.p));
+#else
+ spDispatch.QueryInterface( & spUnknown.p);
+#endif
+ }
+
+ static Type VOID_TYPE= Type();
+ Any ret;
+ //If no Type is provided and pVar contains IUnknown then we return a XInterface.
+ //If pVar contains an IDispatch then we return a XInvocation.
+ Type desiredType = aType;
+
+ if (aType == VOID_TYPE)
+ {
+ switch (pVar->vt)
+ {
+ case VT_EMPTY:
+ case VT_UNKNOWN:
+ desiredType = getCppuType((Reference<XInterface>*) 0);
+ break;
+ case VT_DISPATCH:
+ desiredType = getCppuType((Reference<XInvocation>*) 0);
+ break;
+ default:
+ desiredType = aType;
+ }
+ }
+
+ // COM pointer are NULL, no wrapper required
+ if (spUnknown == NULL)
+ {
+ Reference<XInterface> xInt;
+ if( aType.getTypeClass() == TypeClass_INTERFACE)
+ ret.setValue( &xInt, aType);
+ else if( aType.getTypeClass() == TypeClass_STRUCT)
+ ret.setValue( NULL, aType);
+ else
+ ret <<= xInt;
+ return ret;
+ }
+
+
+ // Check if "spUnknown" is a UNO wrapper, that is an UNO object that has been
+ // passed to COM. Then it supports IUnoObjectWrapper
+ // and we extract the original UNO object.
+#ifdef __MINGW32__
+ CComQIPtr<IUnoObjectWrapper, &__uuidof(IUnoObjectWrapper)> spUno( spUnknown);
+#else
+ CComQIPtr<IUnoObjectWrapper> spUno( spUnknown);
+#endif
+ if( spUno)
+ { // it is a wrapper
+ Reference<XInterface> xInt;
+ if( SUCCEEDED( spUno->getOriginalUnoObject( &xInt)))
+ {
+ ret <<= xInt;
+ }
+ else
+ {
+ Any any;
+ if( SUCCEEDED( spUno->getOriginalUnoStruct(&any)))
+ ret= any;
+ }
+ return ret;
+ }
+
+ // "spUnknown" is a real COM object.
+ // Before we create a new wrapper object we check if there is an existing wrapper
+ // There can be two kinds of wrappers, those who wrap dispatch - UNO objects, and those who
+ // wrap ordinary dispatch objects. The dispatch-UNO objects usually are adapted to represent
+ // particular UNO interfaces.
+ Reference<XInterface> xIntWrapper;
+ CIT_Com cit_currWrapper= ComPtrToWrapperMap.find( reinterpret_cast<sal_uInt32>(spUnknown.p));
+ if(cit_currWrapper != ComPtrToWrapperMap.end())
+ xIntWrapper = cit_currWrapper->second;
+ if (xIntWrapper.is())
+ {
+ //Try to find an adapter for the wrapper
+ //find the proper Adapter. The pointer in the WrapperToAdapterMap are valid as long as
+ //we get a pointer to the wrapper from ComPtrToWrapperMap, because the Adapter hold references
+ //to the wrapper.
+ CIT_Wrap it = WrapperToAdapterMap.find((sal_uInt32) xIntWrapper.get());
+ if (it == WrapperToAdapterMap.end())
+ {
+ // No adapter available.
+ //The COM component could be a UNO object. Then we need to provide
+ // a proxy that implements all interfaces
+ Sequence<Type> seqTypes= getImplementedInterfaces(spUnknown);
+ Reference<XInterface> xIntAdapter;
+ if (seqTypes.getLength() > 0)
+ {
+ //It is a COM UNO object
+ xIntAdapter = createAdapter(seqTypes, xIntWrapper);
+ }
+ else
+ {
+ // Some ordinary COM object
+ xIntAdapter = xIntWrapper;
+ }
+ // return the wrapper directly, return XInterface or XInvocation
+ ret = xIntWrapper->queryInterface(desiredType);
+ if ( ! ret.hasValue())
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
+ "The COM object is not suitable for the UNO type: ") +
+ desiredType.getTypeName(), 0, -1);
+ }
+ else
+ {
+ //There is an adapter available
+ Reference<XInterface> xIntAdapter((XInterface*) it->second);
+ ret = xIntAdapter->queryInterface( desiredType);
+ if ( ! ret.hasValue())
+ throw IllegalArgumentException(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
+ "The COM object is not suitable for the UNO type: ") +
+ desiredType.getTypeName(), 0, -1);
+ }
+
+ return ret;
+ }
+ // No existing wrapper. Therefore create a new proxy.
+ // If the object implements UNO interfaces then get the types.
+ Sequence<Type> seqTypes = getImplementedInterfaces(spUnknown);
+ if (seqTypes.getLength() == 0 &&
+ aType != VOID_TYPE && aType != getCppuType((Reference<XInvocation>*)0))
+ {
+ seqTypes = Sequence<Type>( & aType, 1);
+ }
+
+ //There is no existing wrapper, therefore we create one for the real COM object
+ Reference<XInterface> xIntNewProxy= createComWrapperInstance();
+ if ( ! xIntNewProxy.is())
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
+ "Could not create proxy object for COM object!"));
+
+ // initialize the COM wrapper
+ Reference<XInitialization> xInit( xIntNewProxy, UNO_QUERY);
+ OSL_ASSERT( xInit.is());
+
+ Any params[3];
+#ifdef __MINGW32__
+ params[0] <<= reinterpret_cast<sal_uInt32>( spUnknown.p );
+#else
+ params[0] <<= (sal_uInt32) spUnknown.p;
+#endif
+ sal_Bool bDisp = pVar->vt == VT_DISPATCH ? sal_True : sal_False;
+ params[1].setValue( & bDisp, getBooleanCppuType());
+ params[2] <<= seqTypes;
+
+ xInit->initialize( Sequence<Any>( params, 3));
+#ifdef __MINGW32__
+ ComPtrToWrapperMap[reinterpret_cast<sal_uInt32>( spUnknown.p )]= xIntNewProxy;
+#else
+ ComPtrToWrapperMap[reinterpret_cast<sal_uInt32>(spUnknown.p)]= xIntNewProxy;
+#endif
+
+ // we have a wrapper object
+ //The wrapper implements already XInvocation and XInterface. If
+ //param aType is void then the object is supposed to have XInvocation.
+ if (aType == getCppuType((Reference<XInvocation>*)0) ||
+ (aType == VOID_TYPE && seqTypes.getLength() == 0 ))
+ {
+ ret = xIntNewProxy->queryInterface(desiredType);
+ }
+ else
+ {
+ Reference<XInterface> xIntAdapter =
+ createAdapter(seqTypes, xIntNewProxy);
+ ret = xIntAdapter->queryInterface(desiredType);
+ }
+ return ret;
+}
+template<class T>
+Reference<XInterface> UnoConversionUtilities<T>::createAdapter(const Sequence<Type>& seqTypes,
+ const Reference<XInterface>& receiver)
+{
+ Reference< XInterface> xIntAdapterFac;
+ xIntAdapterFac= m_smgr->createInstance(INTERFACE_ADAPTER_FACTORY);
+ // We create an adapter object that does not only implement the required type but also
+ // all types that the COM object pretends to implement. An COM object must therefore
+ // support the property "_implementedInterfaces".
+ Reference<XInterface> xIntAdapted;
+ Reference<XInvocation> xInv(receiver, UNO_QUERY);
+ Reference<XInvocationAdapterFactory2> xAdapterFac( xIntAdapterFac, UNO_QUERY);
+ if( xAdapterFac.is())
+ xIntAdapted= xAdapterFac->createAdapter( xInv, seqTypes);
+
+ if( xIntAdapted.is())
+ {
+ // Put the pointer to the wrapper object and the interface pointer of the adapted interface
+ // in a global map. Thus we can determine in a call to createUnoObjectWrapper whether the UNO
+ // object is a wrapped COM object. In that case we extract the original COM object rather than
+ // creating a wrapper around the UNO object.
+ typedef hash_map<sal_uInt32,sal_uInt32>::value_type VALUE;
+ AdapterToWrapperMap.insert( VALUE( (sal_uInt32) xIntAdapted.get(), (sal_uInt32) receiver.get()));
+ WrapperToAdapterMap.insert( VALUE( (sal_uInt32) receiver.get(), (sal_uInt32) xIntAdapted.get()));
+ }
+ else
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
+ "Could not create a proxy for COM object! Creation of adapter failed."));
+ }
+ return xIntAdapted;
+}
+// "convertValueObject" converts a JScriptValue object contained in "var" into
+// an any. The type contained in the any is stipulated by a "type value" thas
+// was set within the JScript script on the value object ( see JScriptValue).
+template<class T>
+bool UnoConversionUtilities<T>::convertValueObject( const VARIANTARG *var, Any& any)
+{
+ bool ret = false;
+ try
+ {
+ bool bFail = false;
+ HRESULT hr= S_OK;
+ CComVariant varDisp;
+
+ if(SUCCEEDED(hr = varDisp.ChangeType( VT_DISPATCH, var)))
+ {
+ CComPtr <IJScriptValueObject> spValue;
+ VARIANT_BOOL varBool;
+ CComBSTR bstrType;
+ CComVariant varValue;
+ CComPtr<IDispatch> spDisp( varDisp.pdispVal);
+ if(spDisp)
+ {
+ if(SUCCEEDED( spDisp->QueryInterface( __uuidof( IJScriptValueObject),
+ reinterpret_cast<void**> (&spValue))))
+ {
+ ret = true; // is is a ValueObject
+ //If it is an out - param then it does not need to be converted. In/out and
+ // in params does so.
+ if (SUCCEEDED(hr= spValue->IsOutParam( &varBool)))
+ {
+ // if varBool == true then no conversion needed because out param
+ if (varBool == VARIANT_FALSE)
+ {
+ if(SUCCEEDED(hr = spValue->GetValue( & bstrType, & varValue)))
+ {
+ Type type;
+ if (getType(bstrType, type))
+ variantToAny( & varValue, any, type);
+ else
+ bFail = true;
+ }
+ else
+ bFail = true;
+ }
+ }
+ else
+ bFail = true;;
+ }
+ }
+ }
+ else if( hr != DISP_E_TYPEMISMATCH && hr != E_NOINTERFACE)
+ bFail = true;
+
+ if (bFail)
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] Conversion of ValueObject failed "));
+ }
+ catch (BridgeRuntimeError &)
+ {
+ throw;
+ }
+ catch (Exception & e)
+ {
+ throw BridgeRuntimeError(OUSTR("[automation bridge] unexpected exception in "
+ "UnoConversionUtilities<T>::convertValueObject ! Message : \n") +
+ e.Message);
+ }
+ catch(...)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] unexpected exception in "
+ "UnoConversionUtilities<T>::convertValueObject !"));
+ }
+ return ret;
+}
+
+template<class T>
+void UnoConversionUtilities<T>::dispatchExObject2Sequence( const VARIANTARG* pvar, Any& anySeq, const Type& type)
+{
+ try
+ {
+ bool bFail = false;
+ if( pvar->vt != VT_DISPATCH)
+ throw BridgeRuntimeError(OUSTR("[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
+ "Conversion of dispatch object to Sequence failed!"));
+ IDispatchEx* pdispEx;
+ HRESULT hr;
+ if( FAILED( hr= pvar->pdispVal->QueryInterface( IID_IDispatchEx,
+ reinterpret_cast<void**>( &pdispEx))))
+ throw BridgeRuntimeError(OUSTR("[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
+ "Conversion of dispatch object to Sequence failed!"));
+
+ DISPID dispid;
+ OUString sindex;
+ DISPPARAMS param= {0,0,0,0};
+ CComVariant result;
+
+ OLECHAR* sLength= L"length";
+
+ // Get the length of the array. Can also be obtained throu GetNextDispID. The
+ // method only returns DISPIDs of the array data. Their names are like "0", "1" etc.
+ if( FAILED( hr= pdispEx->GetIDsOfNames(IID_NULL, &sLength , 1, LOCALE_USER_DEFAULT, &dispid)))
+ throw BridgeRuntimeError(OUSTR("[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
+ "Conversion of dispatch object to Sequence failed!"));
+ if( FAILED( hr= pdispEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
+ &param, &result, NULL, NULL)))
+ throw BridgeRuntimeError(OUSTR("[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
+ "Conversion of dispatch object to Sequence failed!"));
+ if( FAILED( VariantChangeType( &result, &result, 0, VT_I4)))
+ throw BridgeRuntimeError(OUSTR("[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
+ "Conversion of dispatch object to Sequence failed!"));
+ long length= result.lVal;
+
+ result.Clear();
+
+ // get a few basic facts about the sequence, and reallocate:
+ // create the Sequences
+ // get the size of the elements
+ typelib_TypeDescription *pDesc= NULL;
+ type.getDescription( &pDesc);
+
+ typelib_IndirectTypeDescription *pSeqDesc= reinterpret_cast<typelib_IndirectTypeDescription*>(pDesc);
+ typelib_TypeDescriptionReference *pSeqElemDescRef= pSeqDesc->pType; // type of the Sequence' elements
+ Type elemType( pSeqElemDescRef);
+ _typelib_TypeDescription* pSeqElemDesc=NULL;
+ TYPELIB_DANGER_GET( &pSeqElemDesc, pSeqElemDescRef)
+ sal_uInt32 nelementSize= pSeqElemDesc->nSize;
+ TYPELIB_DANGER_RELEASE( pSeqElemDesc)
+
+ uno_Sequence *p_uno_Seq;
+ uno_sequence_construct( &p_uno_Seq, pDesc, NULL, length, cpp_acquire);
+
+ typelib_TypeClass typeElement= pSeqDesc->pType->eTypeClass;
+ char *pArray= p_uno_Seq->elements;
+
+ // Get All properties in the object, convert their values to the expected type and
+ // put them into the passed in sequence
+ for( sal_Int32 i= 0; i< length; i++)
+ {
+ OUString ousIndex=OUString::valueOf( i);
+ OLECHAR* sindex = (OLECHAR*)ousIndex.getStr();
+
+ if( FAILED( hr= pdispEx->GetIDsOfNames(IID_NULL, &sindex , 1, LOCALE_USER_DEFAULT, &dispid)))
+ {
+ throw BridgeRuntimeError(OUSTR("[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
+ "Conversion of dispatch object to Sequence failed!"));
+ }
+ if( FAILED( hr= pdispEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
+ &param, &result, NULL, NULL)))
+ {
+ throw BridgeRuntimeError(OUSTR("[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
+ "Conversion of dispatch object to Sequence failed!"));
+ }
+
+ // If the result is VT_DISPATCH than the Sequence's element type could be Sequence
+ // Look that up in the CoreReflection to make clear.
+ // That requires a recursiv conversion
+ Any any;
+ // Destination address within the out-Sequence "anySeq" where to copy the next converted element
+ void* pDest= (void*)(pArray + (i * nelementSize));
+
+ if( result.vt & VT_DISPATCH && typeElement == typelib_TypeClass_SEQUENCE)
+ {
+ variantToAny( &result, any, elemType, sal_False);
+ // copy the converted VARIANT, that is a Sequence to the Sequence
+ uno_Sequence * p_unoSeq= *(uno_Sequence**)any.getValue();
+ // just copy the pointer of the uno_Sequence
+ // nelementSize should be 4 !!!!
+ memcpy( pDest, &p_unoSeq, nelementSize);
+ osl_incrementInterlockedCount( &p_unoSeq->nRefCount);
+ }
+ else // Element type is no Sequence -> do one conversion
+ {
+ variantToAny( &result, any, elemType, sal_False);
+ if( typeElement == typelib_TypeClass_ANY)
+ {
+ // copy the converted VARIANT to the Sequence
+ uno_type_assignData( pDest, pSeqElemDescRef , &any, pSeqElemDescRef,cpp_queryInterface,
+ cpp_acquire, cpp_release);
+ }
+ else
+ {
+ // type after conversion must be the element type of the sequence
+ OSL_ENSURE( (any.getValueTypeClass() == typeElement), "wrong conversion");
+ uno_type_assignData( pDest, pSeqElemDescRef,const_cast<void*>( any.getValue()), any.getValueTypeRef(),
+ cpp_queryInterface, cpp_acquire, cpp_release);
+ }
+ }
+ } // else
+ result.Clear();
+ anySeq.setValue( &p_uno_Seq, pDesc);
+ uno_destructData( &p_uno_Seq, pDesc, cpp_release);
+ typelib_typedescription_release( pDesc);
+
+ if (bFail)
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] Conversion of ValueObject failed "));
+ }
+ catch (BridgeRuntimeError & )
+ {
+ throw;
+ }
+ catch (Exception & e)
+ {
+ throw BridgeRuntimeError(OUSTR("[automation bridge] unexpected exception in "
+ "UnoConversionUtilities<T>::convertValueObject ! Message : \n") +
+ e.Message);
+ }
+ catch(...)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] unexpected exception in "
+ "UnoConversionUtilities<T>::convertValueObject !"));
+ }
+}
+
+/* The argument unotype is the type that is expected by the currently called UNO function.
+ For example: []long, [][]long. If the function calls itself recursively then the element type
+ is passed on. For example a two dimensional SAFEARRAY of type VT_I4 is to be converted. Then
+ unotype has to be either void or [][]long. When the function calls itself recursivly then
+ it passes the element type which is []long.
+*/
+template<class T>
+Sequence<Any> UnoConversionUtilities<T>::createOleArrayWrapperOfDim(SAFEARRAY* pArray,
+ unsigned int dimCount, unsigned int actDim, long* index, VARTYPE type, const Type& unotype)
+{
+ HRESULT hr= S_OK;
+ long lBound;
+ long uBound;
+ long nCountElements;
+
+ SafeArrayGetLBound(pArray, actDim, &lBound);
+ SafeArrayGetUBound(pArray, actDim, &uBound);
+ nCountElements= uBound - lBound +1;
+
+ Sequence<Any> anySeq(nCountElements);
+ Any* pUnoArray = anySeq.getArray();
+
+ for (index[actDim - 1] = lBound; index[actDim - 1] <= uBound; index[actDim - 1]++)
+ {
+ if (actDim > 1 )
+ {
+ Sequence<Any> element = createOleArrayWrapperOfDim(pArray, dimCount,
+ actDim - 1, index, type, getElementTypeOfSequence(unotype));
+
+ pUnoArray[index[actDim - 1] - lBound].setValue(&element, getCppuType(&element));
+ }
+ else
+ {
+ VARIANT variant;
+
+ VariantInit(&variant);
+
+ V_VT(&variant) = type;
+
+ switch (type)
+ {
+ case VT_I2:
+ SafeArrayGetElement(pArray, index, &V_I2(&variant));
+ break;
+ case VT_I4:
+ SafeArrayGetElement(pArray, index, &V_I4(&variant));
+ break;
+ case VT_R4:
+ SafeArrayGetElement(pArray, index, &V_R4(&variant));
+ break;
+ case VT_R8:
+ SafeArrayGetElement(pArray, index, &V_R8(&variant));
+ break;
+ case VT_CY:
+ SafeArrayGetElement(pArray, index, &V_CY(&variant));
+ break;
+ case VT_DATE:
+ SafeArrayGetElement(pArray, index, &V_DATE(&variant));
+ break;
+ case VT_BSTR:
+ hr= SafeArrayGetElement(pArray, index, &V_BSTR(&variant));
+ break;
+ case VT_DISPATCH:
+ SafeArrayGetElement(pArray, index, &V_DISPATCH(&variant));
+ break;
+ case VT_ERROR:
+ SafeArrayGetElement(pArray, index, &V_ERROR(&variant));
+ break;
+ case VT_BOOL:
+ SafeArrayGetElement(pArray, index, &V_BOOL(&variant));
+ break;
+ case VT_VARIANT:
+ SafeArrayGetElement(pArray, index, &variant);
+ break;
+ case VT_UNKNOWN:
+ SafeArrayGetElement(pArray, index, &V_UNKNOWN(&variant));
+ break;
+ case VT_I1:
+ SafeArrayGetElement(pArray, index, &V_I1(&variant));
+ break;
+ case VT_UI1:
+ SafeArrayGetElement(pArray, index, &V_UI1(&variant));
+ break;
+ case VT_UI2:
+ SafeArrayGetElement(pArray, index, &V_UI2(&variant));
+ break;
+ case VT_UI4:
+ SafeArrayGetElement(pArray, index, &V_UI4(&variant));
+ break;
+ default:
+ break;
+ }
+
+ if( unotype.getTypeClass() == TypeClass_VOID)
+ // the function was called without specifying the destination type
+ variantToAny(&variant, pUnoArray[index[actDim - 1] - lBound], sal_False);
+ else
+ variantToAny(&variant, pUnoArray[index[actDim - 1] - lBound],
+ getElementTypeOfSequence(unotype), sal_False);
+
+ VariantClear(&variant);
+ }
+ }
+ return anySeq;
+}
+
+template<class T>
+Type UnoConversionUtilities<T>::getElementTypeOfSequence( const Type& seqType)
+{
+ Type retValue;
+ if( seqType.getTypeClass() != TypeClass_VOID)
+ {
+ OSL_ASSERT( seqType.getTypeClass() == TypeClass_SEQUENCE);
+ typelib_IndirectTypeDescription* pDescSeq= NULL;
+ seqType.getDescription((typelib_TypeDescription** ) & pDescSeq);
+ retValue = Type(pDescSeq->pType);
+ typelib_typedescription_release( (typelib_TypeDescription*) pDescSeq);
+ }
+ return retValue;
+}
+template<class T>
+Sequence<Any> UnoConversionUtilities<T>::createOleArrayWrapper(SAFEARRAY* pArray, VARTYPE type, const Type& unoType)
+{
+ sal_uInt32 dim = SafeArrayGetDim(pArray);
+
+ Sequence<Any> ret;
+
+ if (dim > 0)
+ {
+ scoped_array<long> sarIndex(new long[dim]);
+ long * index = sarIndex.get();
+
+ for (unsigned int i = 0; i < dim; i++)
+ {
+ index[i] = 0;
+ }
+
+ ret = createOleArrayWrapperOfDim(pArray, dim, dim, index, type, unoType);
+ }
+
+ return ret;
+}
+
+// If an VARIANT has the type VT_DISPATCH it can either be an JScript Array
+// or some other object. This function finds out if it is such an array or
+// not. Currently there's no way to make sure it's an array
+// so we assume that when the object has a property "0" then it is an Array.
+// An JScript has property like "0", "1", "2" etc. which represent the
+// value at the corresponding index of the array
+template<class T>
+sal_Bool UnoConversionUtilities<T>::isJScriptArray(const VARIANT* rvar)
+{
+ OSL_ENSURE( rvar->vt == VT_DISPATCH, "param is not a VT_DISPATCH");
+ HRESULT hr;
+ OLECHAR* sindex= L"0";
+ DISPID id;
+ if ( rvar->vt == VT_DISPATCH && rvar->pdispVal )
+ {
+ hr= rvar->pdispVal->GetIDsOfNames( IID_NULL, &sindex, 1,
+ LOCALE_USER_DEFAULT, &id);
+
+ if( SUCCEEDED ( hr) )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+template<class T>
+VARTYPE UnoConversionUtilities<T>::mapTypeClassToVartype( TypeClass type)
+{
+ VARTYPE ret;
+ switch( type)
+ {
+ case TypeClass_INTERFACE: ret= VT_DISPATCH;
+ break;
+ case TypeClass_STRUCT: ret= VT_DISPATCH;
+ break;
+ case TypeClass_ENUM: ret= VT_I4;
+ break;
+ case TypeClass_SEQUENCE: ret= VT_ARRAY;
+ break;
+ case TypeClass_ANY: ret= VT_VARIANT;
+ break;
+ case TypeClass_BOOLEAN: ret= VT_BOOL;
+ break;
+ case TypeClass_CHAR: ret= VT_I2;
+ break;
+ case TypeClass_STRING: ret= VT_BSTR;
+ break;
+ case TypeClass_FLOAT: ret= VT_R4;
+ break;
+ case TypeClass_DOUBLE: ret= VT_R8;
+ break;
+ case TypeClass_BYTE: ret= VT_UI1;
+ break;
+ case TypeClass_SHORT: ret= VT_I2;
+ break;
+ case TypeClass_LONG: ret= VT_I4;
+ break;
+ case TypeClass_UNSIGNED_SHORT: ret= VT_UI2;
+ break;
+ case TypeClass_UNSIGNED_LONG: ret= VT_UI4;
+ break;
+ default:
+ ret= VT_EMPTY;
+ }
+ return ret;
+}
+
+template<class T>
+Sequence<Type> UnoConversionUtilities<T>::getImplementedInterfaces(IUnknown* pUnk)
+{
+ Sequence<Type> seqTypes;
+ CComDispatchDriver disp( pUnk);
+ if( disp)
+ {
+ CComVariant var;
+ HRESULT hr= S_OK;
+ // There are two different property names possible.
+ if( FAILED( hr= disp.GetPropertyByName( SUPPORTED_INTERFACES_PROP, &var)))
+ {
+ hr= disp.GetPropertyByName( SUPPORTED_INTERFACES_PROP2, &var);
+ }
+ if (SUCCEEDED( hr))
+ {
+ // we exspect an array( SafeArray or IDispatch) of Strings.
+ Any anyNames;
+ variantToAny( &var, anyNames, getCppuType( (Sequence<Any>*) 0));
+ Sequence<Any> seqAny;
+ if( anyNames >>= seqAny)
+ {
+ seqTypes.realloc( seqAny.getLength());
+ for( sal_Int32 i=0; i < seqAny.getLength(); i++)
+ {
+ OUString typeName;
+ seqAny[i] >>= typeName;
+ seqTypes[i]= Type( TypeClass_INTERFACE, typeName);
+ }
+ }
+ }
+ }
+ return seqTypes;
+}
+template<class T>
+Reference<XTypeConverter> UnoConversionUtilities<T>::getTypeConverter()
+{
+ if ( ! m_typeConverter.is())
+ {
+ MutexGuard guard(getBridgeMutex());
+ if ( ! m_typeConverter.is())
+ {
+ Reference<XInterface> xIntConverter =
+ m_smgr->createInstance(OUSTR("com.sun.star.script.Converter"));
+ if (xIntConverter.is())
+ m_typeConverter = Reference<XTypeConverter>(xIntConverter, UNO_QUERY);
+ }
+ }
+ return m_typeConverter;
+}
+
+// This function tries to the change the type of a value (contained in the Any)
+// to the smallest possible that can hold the value. This is actually done only
+// for types of VT_I4 (see o2u_variantToAny). The reason is the following:
+// JavaScript passes integer values always as VT_I4. If there is a parameter or
+// property of type any then the bridge converts the any's content according
+// to "o2u_variantToAny". Because the VARTYPE is VT_I4 the value would be converted
+// to TypeClass_LONG. Say the method XPropertySet::setPropertyValue( string name, any value)
+// would be called on an object and the property actually is of TypeClass_SHORT.
+// After conversion of the VARIANT parameter the Any would contain type
+// TypeClass_LONG. Because the corereflection does not cast from long to short
+// the "setPropertValue" would fail as the value has not the right type.
+
+// The corereflection does convert small integer types to bigger types.
+// Therefore we can reduce the type if possible and avoid the above mentioned
+// problem.
+
+// The function is not used when elements are to be converted for Sequences.
+
+#ifndef _REDUCE_RANGE
+#define _REDUCE_RANGE
+inline void reduceRange( Any& any)
+{
+ OSL_ASSERT( any.getValueTypeClass() == TypeClass_LONG);
+
+ sal_Int32 value= *(sal_Int32*)any.getValue();
+ if( value <= 0x7f && value >= -0x80)
+ {// -128 bis 127
+ sal_Int8 charVal= static_cast<sal_Int8>( value);
+ any.setValue( &charVal, getCppuType( (sal_Int8*)0));
+ }
+ else if( value <= 0x7fff && value >= -0x8000)
+ {// -32768 bis 32767
+ sal_Int16 shortVal= static_cast<sal_Int16>( value);
+ any.setValue( &shortVal, getCppuType( (sal_Int16*)0));
+ }
+}
+#endif
+
+
+
+} // end namespace
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx
new file mode 100644
index 000000000000..9cd131487dc4
--- /dev/null
+++ b/extensions/source/ole/unoobjw.cxx
@@ -0,0 +1,1690 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#include "ole2uno.hxx"
+#include <stdio.h>
+#include <tools/presys.h>
+#include <olectl.h>
+#include <vector>
+#include <list>
+#include <hash_map>
+#include "comifaces.hxx"
+#include <tools/postsys.h>
+
+
+#include <osl/diagnose.h>
+#include <salhelper/simplereferenceobject.hxx>
+#include <tools/debug.hxx>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/PropertyConcept.hpp>
+#include <com/sun/star/script/FailReason.hpp>
+#include <com/sun/star/reflection/ParamInfo.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/script/XInvocation2.hpp>
+#include <com/sun/star/script/MemberType.hpp>
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <osl/interlck.h>
+#include <com/sun/star/uno/genfunc.h>
+#include <cppuhelper/implbase1.hxx>
+
+#include "comifaces.hxx"
+#include "jscriptclasses.hxx"
+#include "unotypewrapper.hxx"
+#include "oleobjw.hxx"
+#include "unoobjw.hxx"
+#include "servprov.hxx"
+
+using namespace std;
+using namespace rtl;
+using namespace osl;
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace com::sun::star::script;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::bridge::ModelDependent;
+using namespace com::sun::star::reflection;
+
+
+
+#if _MSC_VER < 1200
+extern "C" const GUID IID_IDispatchEx;
+#endif
+
+namespace ole_adapter
+{
+hash_map<sal_uInt32, WeakReference<XInterface> > UnoObjToWrapperMap;
+static sal_Bool writeBackOutParameter(VARIANTARG* pDest, VARIANT* pSource);
+static sal_Bool writeBackOutParameter2( VARIANTARG* pDest, VARIANT* pSource);
+static HRESULT mapCannotConvertException( CannotConvertException e, unsigned int * puArgErr);
+
+
+/* Does not throw any exceptions.
+ Param pInfo can be NULL.
+ */
+static void writeExcepinfo(EXCEPINFO * pInfo, const OUString& message)
+{
+ if (pInfo != NULL)
+ {
+ pInfo->wCode = UNO_2_OLE_EXCEPTIONCODE;
+ pInfo->bstrSource = SysAllocString(L"[automation bridge] ");
+ pInfo->bstrDescription = SysAllocString(reinterpret_cast<LPCOLESTR>(message.getStr()));
+ }
+}
+
+/*****************************************************************************
+
+ class implementation: InterfaceOleWrapper_Impl
+
+*****************************************************************************/
+InterfaceOleWrapper_Impl::InterfaceOleWrapper_Impl( Reference<XMultiServiceFactory>& xFactory,
+ sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass):
+ m_defaultValueType( 0),
+ UnoConversionUtilities<InterfaceOleWrapper_Impl>( xFactory, unoWrapperClass, comWrapperClass)
+{
+}
+
+InterfaceOleWrapper_Impl::~InterfaceOleWrapper_Impl()
+{
+ MutexGuard guard(getBridgeMutex());
+ // remove entries in global map
+ IT_Uno it= UnoObjToWrapperMap.find( (sal_uInt32) m_xOrigin.get());
+ if(it != UnoObjToWrapperMap.end())
+ UnoObjToWrapperMap.erase(it);
+#if OSL_DEBUG_LEVEL > 0
+ fprintf(stderr,"[automation bridge] UnoObjToWrapperMap contains: %i \n",
+ UnoObjToWrapperMap.size());
+#endif
+
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::QueryInterface(REFIID riid, LPVOID FAR * ppv)
+{
+ HRESULT ret= S_OK;
+
+ if( !ppv)
+ return E_POINTER;
+
+ if(IsEqualIID(riid, IID_IUnknown))
+ {
+ AddRef();
+ *ppv = (IUnknown*) (IDispatch*) this;
+ }
+ else if (IsEqualIID(riid, IID_IDispatch))
+ {
+ AddRef();
+ *ppv = (IDispatch*) this;
+ }
+ else if( IsEqualIID( riid, __uuidof( IUnoObjectWrapper)))
+ {
+ AddRef();
+ *ppv= (IUnoObjectWrapper*) this;
+ }
+ else
+ ret= E_NOINTERFACE;
+ return ret;
+}
+
+STDMETHODIMP_(ULONG) InterfaceOleWrapper_Impl::AddRef()
+{
+ acquire();
+ // does not need to guard because one should not rely on the return value of
+ // AddRef anyway
+ return m_refCount;
+}
+
+STDMETHODIMP_(ULONG) InterfaceOleWrapper_Impl::Release()
+{
+ ULONG n= m_refCount;
+ release();
+ return n - 1;
+}
+
+// IUnoObjectWrapper --------------------------------------------------------
+STDMETHODIMP InterfaceOleWrapper_Impl::getWrapperXInterface( Reference<XInterface>* pXInt)
+{
+ *pXInt= Reference<XInterface>( static_cast<XWeak*>( this), UNO_QUERY);
+ return pXInt->is() ? S_OK : E_FAIL;
+}
+STDMETHODIMP InterfaceOleWrapper_Impl::getOriginalUnoObject( Reference<XInterface>* pXInt)
+{
+ *pXInt= m_xOrigin;
+ return m_xOrigin.is() ? S_OK : E_FAIL;
+}
+STDMETHODIMP InterfaceOleWrapper_Impl::getOriginalUnoStruct( Any * pStruct)
+{
+ HRESULT ret= E_FAIL;
+ if( !m_xOrigin.is())
+ {
+ Reference<XMaterialHolder> xMatHolder( m_xInvocation, UNO_QUERY);
+ if( xMatHolder.is())
+ {
+ Any any = xMatHolder->getMaterial();
+ if( any.getValueTypeClass() == TypeClass_STRUCT)
+ {
+ *pStruct= any;
+ ret= S_OK;
+ }
+ }
+ }
+ return ret;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::GetTypeInfoCount( unsigned int * /*pctinfo*/ )
+{
+ return E_NOTIMPL ;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::GetTypeInfo(unsigned int /*itinfo*/, LCID /*lcid*/, ITypeInfo ** /*pptinfo*/)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::GetIDsOfNames(REFIID /*riid*/,
+ OLECHAR ** rgszNames,
+ unsigned int cNames,
+ LCID /*lcid*/,
+ DISPID * rgdispid )
+{
+ HRESULT ret = DISP_E_UNKNOWNNAME;
+ try
+ {
+ MutexGuard guard( getBridgeMutex());
+ if( ! rgdispid)
+ return E_POINTER;
+
+ // ----------------------------------------
+ if( ! _wcsicmp( *rgszNames, JSCRIPT_VALUE_FUNC) ||
+ ! _wcsicmp( *rgszNames, BRIDGE_VALUE_FUNC))
+ {
+ *rgdispid= DISPID_JSCRIPT_VALUE_FUNC;
+ return S_OK;
+ }
+ else if( ! _wcsicmp( *rgszNames, GET_STRUCT_FUNC) ||
+ ! _wcsicmp( *rgszNames, BRIDGE_GET_STRUCT_FUNC))
+ {
+ *rgdispid= DISPID_GET_STRUCT_FUNC;
+ return S_OK;
+ }
+ else if( ! _wcsicmp( *rgszNames, BRIDGE_CREATE_TYPE_FUNC))
+ {
+ *rgdispid= DISPID_CREATE_TYPE_FUNC;
+ return S_OK;
+ }
+
+ // ----------------------------------------
+ if (m_xInvocation.is() && (cNames > 0))
+ {
+ OUString name(reinterpret_cast<const sal_Unicode*>(rgszNames[0]));
+ NameToIdMap::iterator iter = m_nameToDispIdMap.find(name);
+
+ if (iter == m_nameToDispIdMap.end())
+ {
+ OUString exactName;
+
+ if (m_xExactName.is())
+ {
+ exactName = m_xExactName->getExactName(name);
+ }
+ else
+ {
+ exactName = name;
+ }
+
+ MemberInfo d(0, exactName);
+
+ if (m_xInvocation->hasProperty(exactName))
+ {
+ d.flags |= DISPATCH_PROPERTYGET;
+ d.flags |= DISPATCH_PROPERTYPUT;
+ d.flags |= DISPATCH_PROPERTYPUTREF;
+ }
+
+ if (m_xInvocation->hasMethod(exactName))
+ {
+ d.flags |= DISPATCH_METHOD;
+ }
+
+ if (d.flags != 0)
+ {
+ m_MemberInfos.push_back(d);
+ iter = m_nameToDispIdMap.insert(NameToIdMap::value_type(exactName, (DISPID)m_MemberInfos.size())).first;
+
+ if (exactName != name)
+ {
+ iter = m_nameToDispIdMap.insert(NameToIdMap::value_type(name, (DISPID)m_MemberInfos.size())).first;
+ }
+ }
+ }
+
+ if (iter == m_nameToDispIdMap.end())
+ {
+ ret = DISP_E_UNKNOWNNAME;
+ }
+ else
+ {
+ *rgdispid = (*iter).second;
+ ret = S_OK;
+ }
+ }
+ }
+ catch(BridgeRuntimeError& )
+ {
+ OSL_ASSERT(0);
+ }
+ catch(Exception& )
+ {
+ OSL_ASSERT(0);
+ }
+ catch(...)
+ {
+ OSL_ASSERT(0);
+ }
+
+ return ret;
+}
+
+// "convertDispparamsArgs" converts VARIANTS to their respecting Any counterparts
+// The parameters "id", "wFlags" and "pdispparams" equal those as used in
+// IDispatch::Invoke. The function handles special JavaScript
+// cases where a VARIANT of type VT_DISPATCH is ambiguous and could represent
+// an object, array ( JavaScript Array object), out parameter and in/out ( JavaScript Array object)
+// parameter (JavaScript Array object)
+// Because all those VT_DISPATCH objects need a different conversion
+// we have to find out what the object is supposed to be. The function does this
+// by either using type information or by help of a specialized ValueObject object.
+
+// A. Type Information
+// -----------------------------------------------------------------------------
+// With the help of type information the kind of parameter can be exactly determined
+// and an appropriate conversion can be choosen. A problem arises if a method expects
+// an Any. Then the type info does not tell what the type of the value, that is kept
+// by the any, should be. In this situation the decision wheter the param is a
+// sequence or an object is made upon the fact if the object has a property "0"
+// ( see function "isJScriptArray"). Since this is unsafe it is recommended to use
+// the JScript value objects within a JScript script on such an occasion.
+
+// B. JavaScript Value Object ( class JScriptValue )
+// -----------------------------------------------------------------------------
+// A JScriptValue (ValueObject) object is a COM object in that it implements IDispatch and the
+// IJScriptValue object interface. Such objects are provided by all UNO wrapper
+// objects used within a JScript script. To obtain an instance one has to call
+// "_GetValueObject() or Bridge_GetValueObject()" on an UNO wrapper object (class InterfaceOleWrapper_Impl).
+// A value object is appropriately initialized within the script and passed as
+// parameter to an UNO object method or property. The convertDispparamsArgs function
+// can easily find out that a param is such an object by queriing for the
+// IJScriptValue interface. By this interface one the type and kind ( out, in/out)
+// can be determined and the right conversion can be applied.
+// Using ValueObjects we spare us the effort of aquiring and examining type information
+// in order to figure out what the an IDispatch parameter is meant for.
+
+// Normal JScript object parameter can be mixed with JScriptValue object. If an
+// VARIANT contains an VT_DISPATCH that is no JScriptValue than the type information
+// is used to find out about the reqired type.
+void InterfaceOleWrapper_Impl::convertDispparamsArgs(DISPID id,
+ unsigned short /*wFlags*/, DISPPARAMS* pdispparams, Sequence<Any>& rSeq)
+{
+ HRESULT hr= S_OK;
+ sal_Int32 countArgs= pdispparams->cArgs;
+ if( countArgs == 0)
+ return;
+
+ rSeq.realloc( countArgs);
+ Any* pParams = rSeq.getArray();
+
+ Any anyParam;
+
+ //Get type information for the current call
+ InvocationInfo info;
+ if( ! getInvocationInfoForCall( id, info))
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge]InterfaceOleWrapper_Impl::convertDispparamsArgs \n"
+ "Could not obtain type information for current call."));
+
+ for (int i = 0; i < countArgs; i++)
+ {
+ if (info.eMemberType == MemberType_METHOD &&
+ info.aParamModes[ countArgs - i -1 ] == ParamMode_OUT)
+ continue;
+
+ if(convertValueObject( & pdispparams->rgvarg[i], anyParam))
+ { //a param is a ValueObject and could be converted
+ pParams[countArgs - (i + 1)] = anyParam;
+ continue;
+ }
+
+ // If the param is an out, in/out parameter in
+ // JScript (Array object, with value at index 0) then we
+ // extract Array[0] and put the value into varParam. At the end of the loop varParam
+ // is converted if it contains a value otherwise the VARIANT from
+ // DISPPARAMS is converted.
+ CComVariant varParam;
+
+ // Check for JScript out and in/out paramsobjects (VT_DISPATCH).
+ // To find them out we use typeinformation of the function being called.
+ if( pdispparams->rgvarg[i].vt == VT_DISPATCH )
+ {
+ if( info.eMemberType == MemberType_METHOD && info.aParamModes[ countArgs - i -1 ] == ParamMode_INOUT)
+ {
+ // INOUT-param
+ // Index ( property) "0" contains the actual IN-param. The object is a JScript
+ // Array object.
+ // Get the IN-param at index "0"
+ IDispatch* pdisp= pdispparams->rgvarg[i].pdispVal;
+
+ OLECHAR* sindex= L"0";
+ DISPID id;
+ DISPPARAMS noParams= {0,0,0,0};
+ if(SUCCEEDED( hr= pdisp->GetIDsOfNames( IID_NULL, &sindex, 1, LOCALE_USER_DEFAULT, &id)))
+ hr= pdisp->Invoke( id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
+ & noParams, & varParam, NULL, NULL);
+ if( FAILED( hr))
+ {
+ throw BridgeRuntimeError(
+ OUSTR("[automation bridge] Could not determine "
+ "if the object has a member \"0\". Error: ") +
+ OUString::valueOf(hr));
+ }
+ }
+ }
+
+ if( varParam.vt == VT_EMPTY) // then it was no in/out parameter
+ varParam= pdispparams->rgvarg[i];
+
+ if(info.eMemberType == MemberType_METHOD)
+ variantToAny( & varParam, anyParam,
+ info.aParamTypes[ countArgs - i - 1]);
+ else if(info.eMemberType == MemberType_PROPERTY)
+ variantToAny( & varParam, anyParam, info.aType);
+ else
+ OSL_ASSERT(0);
+
+ pParams[countArgs - (i + 1)]= anyParam;
+ }// end for / iterating over all parameters
+}
+
+sal_Bool InterfaceOleWrapper_Impl::getInvocationInfoForCall( DISPID id, InvocationInfo& info)
+{
+ sal_Bool bTypesAvailable= sal_False;
+
+ if( !m_xInvocation.is() )return false;
+ Reference<XInvocation2> inv2( m_xInvocation, UNO_QUERY);
+ if( inv2.is())
+ {
+ // We need the name of the property or method to get its type information.
+ // The name can be identified through the param "id"
+ // that is kept as value in the map m_nameToDispIdMap.
+ // Proplem: the Windows JScript engine sometimes changes small letters to capital
+ // letters as happens in xidlclass_obj.createObject( var) // in JScript.
+ // IDispatch::GetIdsOfNames is then called with "CreateObject" !!!
+ // m_nameToDispIdMap can contain several names for one DISPID but only one is
+ // the exact one. If there's no m_xExactName and therefore no exact name then
+ // there's only one entry in the map.
+ typedef NameToIdMap::const_iterator cit;
+ OUString sMemberName;
+
+ for(cit ci1= m_nameToDispIdMap.begin(); ci1 != m_nameToDispIdMap.end(); ci1++)
+ {
+ if( (*ci1).second == id) // iterator is a pair< OUString, DISPID>
+ {
+ sMemberName= (*ci1).first;
+ break;
+ }
+ }
+ // Get information for the current call ( property or method).
+ // There could be similar names which only differ in the cases
+ // of letters. First we assume that the name which was passed into
+ // GetIDsOfNames is correct. If we won't get information with that
+ // name then we have the invocation service use the XExactName interface.
+ sal_Bool validInfo= sal_True;
+ InvocationInfo invInfo;
+ try{
+ invInfo= inv2->getInfoForName( sMemberName, sal_False);
+ }
+ catch( IllegalArgumentException )
+ {
+ validInfo= sal_False;
+ }
+
+ if( ! validInfo)
+ {
+ invInfo= inv2->getInfoForName( sMemberName, sal_True);
+ }
+ if( invInfo.aName.pData)
+ {
+ bTypesAvailable= sal_True;
+ info= invInfo;
+ }
+ }
+ return bTypesAvailable;
+}
+// XBridgeSupplier2 ---------------------------------------------------
+// only bridges itself ( this instance of InterfaceOleWrapper_Impl)from UNO to IDispatch
+// If sourceModelType is UNO than any UNO interface implemented by InterfaceOleWrapper_Impl
+// can bridged to IDispatch ( if destModelType == OLE). The IDispatch is
+// implemented by this class.
+Any SAL_CALL InterfaceOleWrapper_Impl::createBridge(const Any& modelDepObject,
+ const Sequence<sal_Int8>& /*ProcessId*/,
+ sal_Int16 sourceModelType,
+ sal_Int16 destModelType)
+ throw (IllegalArgumentException, RuntimeException)
+{
+
+ Any retAny;
+ if( sourceModelType == UNO && destModelType == OLE &&
+ modelDepObject.getValueTypeClass() == TypeClass_INTERFACE )
+ {
+ Reference<XInterface> xInt;
+ if( modelDepObject >>= xInt )
+ {
+ if( xInt == Reference<XInterface>( static_cast<XWeak*>( this), UNO_QUERY))
+ {
+ VARIANT *pVar= (VARIANT*)CoTaskMemAlloc( sizeof( VARIANT));
+ if( pVar)
+ {
+ pVar->vt= VT_DISPATCH;
+ pVar->pdispVal= static_cast<IDispatch*>( this);
+ AddRef();
+
+ retAny<<= reinterpret_cast< sal_uInt32 >( pVar);
+ }
+ }
+ }
+ }
+
+ return retAny;
+}
+
+
+// XInitialization --------------------------------------------------
+void SAL_CALL InterfaceOleWrapper_Impl::initialize( const Sequence< Any >& aArguments )
+ throw(Exception, RuntimeException)
+{
+ switch( aArguments.getLength() )
+ {
+ case 2: // the object wraps an UNO struct
+ aArguments[0] >>= m_xInvocation;
+ aArguments[1] >>= m_defaultValueType;
+ break;
+ case 3: // the object wraps an UNO interface
+ aArguments[0] >>= m_xInvocation;
+ aArguments[1] >>= m_xOrigin;
+ aArguments[2] >>= m_defaultValueType;
+ break;
+ }
+
+ m_xExactName= Reference<XExactName>( m_xInvocation, UNO_QUERY);
+}
+
+Reference< XInterface > InterfaceOleWrapper_Impl::createUnoWrapperInstance()
+{
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+}
+
+Reference<XInterface> InterfaceOleWrapper_Impl::createComWrapperInstance()
+{
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+}
+
+
+
+// "getType" is used in convertValueObject to map the string denoting the type
+// to an actual Type object.
+bool getType( const BSTR name, Type & type)
+{
+ Type retType;
+ bool ret = false;
+ typelib_TypeDescription * pDesc= NULL;
+ OUString str( reinterpret_cast<const sal_Unicode*>(name));
+ typelib_typedescription_getByName( &pDesc, str.pData );
+ if( pDesc)
+ {
+ type = Type( pDesc->pWeakRef );
+ typelib_typedescription_release( pDesc);
+ ret = true;
+ }
+ return ret;
+}
+
+static sal_Bool writeBackOutParameter2( VARIANTARG* pDest, VARIANT* pSource)
+{
+ sal_Bool ret = sal_False;
+ HRESULT hr;
+
+ // Handle JScriptValue objects and JScript out params ( Array object )
+ CComVariant varDest( *pDest);
+
+ if( SUCCEEDED( varDest.ChangeType(VT_DISPATCH)))
+ {
+ CComPtr<IDispatch> spDispDest(varDest.pdispVal);
+
+ // special Handling for a JScriptValue object
+#ifdef __MINGW32__
+ CComQIPtr<IJScriptValueObject, &__uuidof(IJScriptValueObject)> spValueDest(spDispDest);
+#else
+ CComQIPtr<IJScriptValueObject> spValueDest(spDispDest);
+#endif
+ if (spValueDest)
+ {
+ VARIANT_BOOL varBool= VARIANT_FALSE;
+ if( SUCCEEDED( hr= spValueDest->IsOutParam( &varBool) )
+ && varBool == VARIANT_TRUE ||
+ SUCCEEDED(hr= spValueDest->IsInOutParam( &varBool) )
+ && varBool == VARIANT_TRUE )
+ {
+ if( SUCCEEDED( spValueDest->Set( CComVariant(), *pSource)))
+ ret= sal_True;
+ }
+ }
+ else if (pDest->vt == VT_DISPATCH)// VT_DISPATCH -> JScript out param
+ {
+ // We use IDispatchEx because its GetDispID function causes the creation
+ // of a property if it does not exist already. This is convenient for
+ // out parameters in JScript. Then the user must not specify propery "0"
+ // explicitly
+#ifdef __MINGW32__
+ CComQIPtr<IDispatchEx, &__uuidof(IDispatchEx)> spDispEx( spDispDest);
+#else
+ CComQIPtr<IDispatchEx> spDispEx( spDispDest);
+#endif
+ if( spDispEx)
+ {
+ CComBSTR nullProp(L"0");
+ DISPID dwDispID;
+ if( SUCCEEDED( spDispEx->GetDispID( nullProp, fdexNameEnsure, &dwDispID)))
+ {
+ DISPPARAMS dispparams = {NULL, NULL, 1, 1};
+ dispparams.rgvarg = pSource;
+ DISPID dispidPut = DISPID_PROPERTYPUT;
+ dispparams.rgdispidNamedArgs = &dispidPut;
+
+ if (pSource->vt == VT_UNKNOWN || pSource->vt == VT_DISPATCH ||
+ (pSource->vt & VT_ARRAY) || (pSource->vt & VT_BYREF))
+ hr = spDispEx->InvokeEx(dwDispID, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF,
+ &dispparams, NULL, NULL, NULL);
+ else
+ hr= spDispEx->InvokeEx(dwDispID, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT,
+ &dispparams, NULL, NULL, NULL);
+ if( SUCCEEDED(hr))
+ ret= sal_True;
+ }
+ }
+ }
+ else
+ ret= writeBackOutParameter( pDest, pSource);
+ }
+ else // The param can't be a JScript out-parameter ( an Array object), it could be a VBScript
+ { // param. The function checks itself for correct VBScript params
+ ret= writeBackOutParameter( pDest, pSource);
+ }
+ return ret;
+}
+// VisualBasic Script passes arguments as VT_VARIANT | VT_BYREF be it in or out parameter.
+// Thus we are in charge of freeing an eventual value contained by the inner VARIANT
+// Please note: VariantCopy doesn't free a VT_BYREF value
+// The out parameters are expected to have always a valid type
+static sal_Bool writeBackOutParameter(VARIANTARG* pDest, VARIANT* pSource)
+{
+ HRESULT hr;
+ sal_Bool ret = FALSE;
+ // Out parameter must be VT_BYREF
+ if ((V_VT(pDest) & VT_BYREF) != 0 )
+ {
+ VARTYPE oleTypeFlags = V_VT(pSource);
+
+ // if caller accept VARIANT as out parameter, any value must be converted
+ if (V_VT(pDest) == (VT_VARIANT | VT_BYREF))
+ {
+ // When the user provides a VARIANT rather then a concrete type
+ // we just copy the source to the out, in/out parameter
+ // VT_DISPATCH, VT_UNKNOWN, VT_ARRAY, VT_BSTR in the VARIANT that
+ // is contained in pDest are released by VariantCopy
+ VariantCopy(V_VARIANTREF(pDest), pSource);
+ ret = sal_True;
+ }
+ else
+ {
+ // variantarg and variant must have same type
+ if ((V_VT(pDest) & oleTypeFlags) == oleTypeFlags)
+ {
+ if ((oleTypeFlags & VT_ARRAY) != 0)
+ {
+ // In / Out Param
+ if( *V_ARRAYREF(pDest) != NULL)
+ hr= SafeArrayCopyData( V_ARRAY(pSource), *V_ARRAYREF(pDest));
+ else
+ // Out Param
+ hr= SafeArrayCopy(V_ARRAY(pSource), V_ARRAYREF(pDest)) == NOERROR;
+ if( SUCCEEDED( hr))
+ ret = sal_True;
+ }
+ else
+ {
+ // copy base type
+ switch (V_VT(pSource))
+ {
+ case VT_I2:
+ {
+ *V_I2REF(pDest) = V_I2(pSource);
+ ret = sal_True;
+ break;
+ }
+ case VT_I4:
+ *V_I4REF(pDest) = V_I4(pSource);
+ ret = sal_True;
+ break;
+ case VT_R4:
+ *V_R4REF(pDest) = V_R4(pSource);
+ ret = sal_True;
+ break;
+ case VT_R8:
+ *V_R8REF(pDest) = V_R8(pSource);
+ ret = sal_True;
+ break;
+ case VT_CY:
+ *V_CYREF(pDest) = V_CY(pSource);
+ ret = sal_True;
+ break;
+ case VT_DATE:
+ *V_DATEREF(pDest) = V_DATE(pSource);
+ ret = sal_True;
+ break;
+ case VT_BSTR:
+ SysFreeString( *pDest->pbstrVal);
+
+ *V_BSTRREF(pDest) = SysAllocString(V_BSTR(pSource));
+ ret = sal_True;
+ break;
+ case VT_DISPATCH:
+ if (*V_DISPATCHREF(pDest) != NULL)
+ (*V_DISPATCHREF(pDest))->Release();
+
+ *V_DISPATCHREF(pDest) = V_DISPATCH(pSource);
+
+ if (*V_DISPATCHREF(pDest) != NULL)
+ (*V_DISPATCHREF(pDest))->AddRef();
+
+ ret = sal_True;
+ break;
+ case VT_ERROR:
+ *V_ERRORREF(pDest) = V_ERROR(pSource);
+ ret = sal_True;
+ break;
+ case VT_BOOL:
+ *V_BOOLREF(pDest) = V_BOOL(pSource);
+ ret = sal_True;
+ break;
+ case VT_UNKNOWN:
+ if (*V_UNKNOWNREF(pDest) != NULL)
+ (*V_UNKNOWNREF(pDest))->Release();
+
+ *V_UNKNOWNREF(pDest) = V_UNKNOWN(pSource);
+
+ if (*V_UNKNOWNREF(pDest) != NULL)
+ (*V_UNKNOWNREF(pDest))->AddRef();
+
+ ret = sal_True;
+ break;
+ case VT_I1:
+ *V_I1REF(pDest) = V_I1(pSource);
+ ret = sal_True;
+ break;
+ case VT_UI1:
+ *V_UI1REF(pDest) = V_UI1(pSource);
+ ret = sal_True;
+ break;
+ case VT_UI2:
+ *V_UI2REF(pDest) = V_UI2(pSource);
+ ret = sal_True;
+ break;
+ case VT_UI4:
+ *V_UI4REF(pDest) = V_UI4(pSource);
+ ret = sal_True;
+ break;
+ case VT_INT:
+ *V_INTREF(pDest) = V_INT(pSource);
+ ret = sal_True;
+ break;
+ case VT_UINT:
+ *V_UINTREF(pDest) = V_UINT(pSource);
+ ret = sal_True;
+ break;
+ case VT_DECIMAL:
+ memcpy(pDest->pdecVal, pSource, sizeof(DECIMAL));
+ ret = sal_True;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Handling of special cases
+ // Destination and source types are different
+ if( pDest->vt == (VT_BSTR | VT_BYREF)
+ && pSource->vt == VT_I2)
+ {
+ // When the user provides a String as out our in/out parameter
+ // and the type is char (TypeClass_CHAR) then we convert to a BSTR
+ // instead of VT_I2 as is done otherwise
+ OLECHAR buff[]= {0,0};
+ buff[0]= pSource->iVal;
+
+ SysFreeString( *pDest->pbstrVal);
+ *pDest->pbstrVal= SysAllocString( buff);
+ ret = sal_True;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::Invoke(DISPID dispidMember,
+ REFIID /*riid*/,
+ LCID /*lcid*/,
+ unsigned short wFlags,
+ DISPPARAMS * pdispparams,
+ VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo,
+ unsigned int * puArgErr )
+{
+ HRESULT ret = S_OK;
+
+ try
+ {
+ sal_Bool bHandled= sal_False;
+ ret= InvokeGeneral( dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo,
+ puArgErr, bHandled);
+ if( bHandled)
+ return ret;
+
+ if ((dispidMember > 0) && ((size_t)dispidMember <= m_MemberInfos.size()) && m_xInvocation.is())
+ {
+ MemberInfo d = m_MemberInfos[dispidMember - 1];
+ DWORD flags = wFlags & d.flags;
+
+ if (flags != 0)
+ {
+ if ((flags & DISPATCH_METHOD) != 0)
+ {
+ if (pdispparams->cNamedArgs > 0)
+ ret = DISP_E_NONAMEDARGS;
+ else
+ {
+ Sequence<Any> params;
+
+ convertDispparamsArgs(dispidMember, wFlags, pdispparams , params );
+
+ ret= doInvoke(pdispparams, pvarResult,
+ pexcepinfo, puArgErr, d.name, params);
+ }
+ }
+ else if ((flags & DISPATCH_PROPERTYGET) != 0)
+ {
+ ret= doGetProperty( pdispparams, pvarResult,
+ pexcepinfo, d.name);
+ }
+ else if ((flags & DISPATCH_PROPERTYPUT || flags & DISPATCH_PROPERTYPUTREF) != 0)
+ {
+ if (pdispparams->cArgs != 1)
+ ret = DISP_E_BADPARAMCOUNT;
+ else
+ {
+ Sequence<Any> params;
+ convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
+ if(params.getLength() > 0)
+ ret= doSetProperty( pdispparams, pvarResult, pexcepinfo, puArgErr, d.name, params);
+ else
+ ret = DISP_E_BADVARTYPE;
+ }
+ }
+ }
+ else
+ ret= DISP_E_MEMBERNOTFOUND;
+ }
+ else
+ ret = DISP_E_MEMBERNOTFOUND;
+ }
+ catch(BridgeRuntimeError& e)
+ {
+ writeExcepinfo(pexcepinfo, e.message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch(Exception& e)
+ {
+ OUString message= OUSTR("InterfaceOleWrapper_Impl::Invoke : \n") +
+ e.Message;
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch(...)
+ {
+ OUString message= OUSTR("InterfaceOleWrapper_Impl::Invoke : \n"
+ "Unexpected exception");
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+
+ return ret;
+}
+
+HRESULT InterfaceOleWrapper_Impl::doInvoke( DISPPARAMS * pdispparams, VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString& name, Sequence<Any>& params)
+{
+
+
+ HRESULT ret= S_OK;
+ try
+ {
+ Sequence<INT16> outIndex;
+ Sequence<Any> outParams;
+ Any returnValue;
+
+ if (pdispparams->cNamedArgs > 0)
+ return DISP_E_NONAMEDARGS;
+
+ // invoke method and take care of exceptions
+ returnValue = m_xInvocation->invoke(name,
+ params,
+ outIndex,
+ outParams);
+
+ // try to write back out parameter
+ if (outIndex.getLength() > 0)
+ {
+ const INT16* pOutIndex = outIndex.getConstArray();
+ const Any* pOutParams = outParams.getConstArray();
+
+ for (sal_Int32 i = 0; i < outIndex.getLength(); i++)
+ {
+ CComVariant variant;
+ // Currently a Sequence is converted to an SafeArray of VARIANTs.
+ anyToVariant( &variant, pOutParams[i]);
+
+ // out parameter need special handling if they are VT_DISPATCH
+ // and used in JScript
+ int outindex= pOutIndex[i];
+ writeBackOutParameter2(&(pdispparams->rgvarg[pdispparams->cArgs - 1 - outindex]),
+ &variant );
+ }
+ }
+
+ // write back return value
+ if (pvarResult != NULL)
+ anyToVariant(pvarResult, returnValue);
+ }
+ catch(IllegalArgumentException & e) //XInvocation::invoke
+ {
+ writeExcepinfo(pexcepinfo, e.Message);
+ ret = DISP_E_TYPEMISMATCH;
+ }
+ catch(CannotConvertException & e) //XInvocation::invoke
+ {
+ writeExcepinfo(pexcepinfo, e.Message);
+ ret = mapCannotConvertException( e, puArgErr);
+ }
+ catch(InvocationTargetException & e) //XInvocation::invoke
+ {
+ const Any& org = e.TargetException;
+ Exception excTarget;
+ org >>= excTarget;
+ OUString message=
+ org.getValueType().getTypeName() + OUSTR(": ") + excTarget.Message;
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch(NoSuchMethodException & e) //XInvocation::invoke
+ {
+ writeExcepinfo(pexcepinfo, e.Message);
+ ret = DISP_E_MEMBERNOTFOUND;
+ }
+ catch(BridgeRuntimeError & e)
+ {
+ writeExcepinfo(pexcepinfo, e.message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch(Exception & e)
+ {
+ OUString message= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n") +
+ e.Message;
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch( ... )
+ {
+ OUString message= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n"
+ "Unexpected exception");
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+ return ret;
+}
+
+HRESULT InterfaceOleWrapper_Impl::doGetProperty( DISPPARAMS * /*pdispparams*/, VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo, OUString& name)
+{
+ HRESULT ret= S_OK;
+
+ Any value;
+ try
+ {
+ Any returnValue = m_xInvocation->getValue( name);
+ // write back return value
+ if (pvarResult)
+ anyToVariant(pvarResult, returnValue);
+ }
+ catch(UnknownPropertyException e) //XInvocation::getValue
+ {
+ writeExcepinfo(pexcepinfo, e.Message);
+ ret = DISP_E_MEMBERNOTFOUND;
+ }
+ catch(BridgeRuntimeError& e)
+ {
+ writeExcepinfo(pexcepinfo, e.message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch(Exception& e)
+ {
+ OUString message= OUSTR("InterfaceOleWrapper_Impl::doGetProperty : \n") +
+ e.Message;
+ writeExcepinfo(pexcepinfo, message);
+ }
+ catch( ... )
+ {
+ OUString message= OUSTR("InterfaceOleWrapper_Impl::doInvoke : \n"
+ "Unexpected exception");
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+ return ret;
+}
+
+HRESULT InterfaceOleWrapper_Impl::doSetProperty( DISPPARAMS * /*pdispparams*/, VARIANT * /*pvarResult*/,
+ EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString& name, Sequence<Any> params)
+{
+ HRESULT ret= S_OK;
+
+ try
+ {
+ m_xInvocation->setValue( name, params.getConstArray()[0]);
+ }
+ catch(UnknownPropertyException )
+ {
+ ret = DISP_E_MEMBERNOTFOUND;
+ }
+ catch(CannotConvertException e)
+ {
+ ret= mapCannotConvertException( e, puArgErr);
+ }
+ catch(InvocationTargetException e)
+ {
+ if (pexcepinfo != NULL)
+ {
+ Any org = e.TargetException;
+
+ pexcepinfo->wCode = UNO_2_OLE_EXCEPTIONCODE;
+ pexcepinfo->bstrSource = SysAllocString(L"any ONE component");
+ pexcepinfo->bstrDescription = SysAllocString(
+ reinterpret_cast<LPCOLESTR>(org.getValueType().getTypeName().getStr()));
+ }
+ ret = DISP_E_EXCEPTION;
+ }
+ catch( ... )
+ {
+ ret= DISP_E_EXCEPTION;
+ }
+ return ret;
+}
+
+HRESULT InterfaceOleWrapper_Impl::InvokeGeneral( DISPID dispidMember, unsigned short wFlags,
+ DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
+ unsigned int * /*puArgErr*/, sal_Bool& bHandled)
+{
+ HRESULT ret= S_OK;
+ try
+ {
+// DISPID_VALUE | The DEFAULT Value is required in JScript when the situation
+// is that we put an object into an Array object ( out parameter). We have to return
+// IDispatch otherwise the object cannot be accessed from the Script.
+ if( dispidMember == DISPID_VALUE && wFlags == DISPATCH_PROPERTYGET
+ && m_defaultValueType != VT_EMPTY && pvarResult != NULL)
+ {
+ bHandled= sal_True;
+ if( m_defaultValueType == VT_DISPATCH)
+ {
+ pvarResult->vt= VT_DISPATCH;
+ pvarResult->pdispVal= static_cast<IDispatch*>( this);
+ AddRef();
+ ret= S_OK;
+ }
+ }
+// ---------
+ // function: _GetValueObject
+ else if( dispidMember == DISPID_JSCRIPT_VALUE_FUNC)
+ {
+ bHandled= sal_True;
+ if( !pvarResult)
+ ret= E_POINTER;
+ CComObject< JScriptValue>* pValue;
+ if( SUCCEEDED( CComObject<JScriptValue>::CreateInstance( &pValue)))
+ {
+ pValue->AddRef();
+ pvarResult->vt= VT_DISPATCH;
+#ifdef __MINGW32__
+ pvarResult->pdispVal= CComQIPtr<IDispatch, &__uuidof(IDispatch)>(pValue->GetUnknown());
+#else
+ pvarResult->pdispVal= CComQIPtr<IDispatch>(pValue->GetUnknown());
+#endif
+ ret= S_OK;
+ }
+ else
+ ret= DISP_E_EXCEPTION;
+ }
+ else if( dispidMember == DISPID_GET_STRUCT_FUNC)
+ {
+ bHandled= sal_True;
+ sal_Bool bStruct= sal_False;
+
+
+ Reference<XInterface> xIntCore= m_smgr->createInstance( OUString::createFromAscii("com.sun.star.reflection.CoreReflection"));
+ Reference<XIdlReflection> xRefl( xIntCore, UNO_QUERY);
+ if( xRefl.is() )
+ {
+ // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
+ CComVariant arg;
+ if( pdispparams->cArgs == 1 && SUCCEEDED( arg.ChangeType( VT_BSTR, &pdispparams->rgvarg[0])) )
+ {
+ Reference<XIdlClass> classStruct= xRefl->forName( reinterpret_cast<const sal_Unicode*>(arg.bstrVal));
+ if( classStruct.is())
+ {
+ Any anyStruct;
+ classStruct->createObject( anyStruct);
+ CComVariant var;
+ anyToVariant( &var, anyStruct );
+
+ if( var.vt == VT_DISPATCH)
+ {
+ VariantCopy( pvarResult, & var);
+ bStruct= sal_True;
+ }
+ }
+ }
+ }
+ ret= bStruct == sal_True ? S_OK : DISP_E_EXCEPTION;
+ }
+ else if (dispidMember == DISPID_CREATE_TYPE_FUNC)
+ {
+ bHandled= sal_True;
+ if( !pvarResult)
+ ret= E_POINTER;
+ // the first parameter is in DISPPARAMS rgvargs contains the name of the struct.
+ CComVariant arg;
+ if( pdispparams->cArgs != 1)
+ return DISP_E_BADPARAMCOUNT;
+ if (FAILED( arg.ChangeType( VT_BSTR, &pdispparams->rgvarg[0])))
+ return DISP_E_BADVARTYPE;
+
+ //check if the provided name represents a valid type
+ Type type;
+ if (getType(arg.bstrVal, type) == false)
+ {
+ writeExcepinfo(pexcepinfo,OUString(
+ OUSTR("[automation bridge] A UNO type with the name ") +
+ OUString(reinterpret_cast<const sal_Unicode*>(arg.bstrVal)) + OUSTR(" does not exist!")));
+ return DISP_E_EXCEPTION;
+ }
+
+ if (createUnoTypeWrapper(arg.bstrVal, pvarResult) == false)
+ {
+ writeExcepinfo(pexcepinfo,OUSTR("[automation bridge] InterfaceOleWrapper_Impl::InvokeGeneral\n"
+ "Could not initialize UnoTypeWrapper object!"));
+ return DISP_E_EXCEPTION;
+ }
+ }
+ }
+ catch(BridgeRuntimeError & e)
+ {
+ writeExcepinfo(pexcepinfo, e.message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch(Exception & e)
+ {
+ OUString message= OUSTR("InterfaceOleWrapper_Impl::InvokeGeneral : \n") +
+ e.Message;
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch( ... )
+ {
+ OUString message= OUSTR("InterfaceOleWrapper_Impl::InvokeGeneral : \n"
+ "Unexpected exception");
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+ return ret;
+}
+
+
+
+
+STDMETHODIMP InterfaceOleWrapper_Impl::GetDispID(BSTR /*bstrName*/, DWORD /*grfdex*/, DISPID __RPC_FAR* /*pid*/)
+{
+ HRESULT ret = ResultFromScode(E_NOTIMPL);
+
+ return ret;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::InvokeEx(
+ /* [in] */ DISPID /*id*/,
+ /* [in] */ LCID /*lcid*/,
+ /* [in] */ WORD /*wFlags*/,
+ /* [in] */ DISPPARAMS __RPC_FAR* /*pdp*/,
+ /* [out] */ VARIANT __RPC_FAR* /*pvarRes*/,
+ /* [out] */ EXCEPINFO __RPC_FAR* /*pei*/,
+ /* [unique][in] */ IServiceProvider __RPC_FAR* /*pspCaller*/)
+{
+ HRESULT ret = ResultFromScode(E_NOTIMPL);
+
+ return ret;
+}
+
+
+STDMETHODIMP InterfaceOleWrapper_Impl::DeleteMemberByName(
+ /* [in] */ BSTR /*bstr*/,
+ /* [in] */ DWORD /*grfdex*/)
+{
+ HRESULT ret = ResultFromScode(E_NOTIMPL);
+
+ return ret;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::DeleteMemberByDispID(DISPID /*id*/)
+{
+ HRESULT ret = ResultFromScode(E_NOTIMPL);
+
+ return ret;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::GetMemberProperties(
+ /* [in] */ DISPID /*id*/,
+ /* [in] */ DWORD /*grfdexFetch*/,
+ /* [out] */ DWORD __RPC_FAR* /*pgrfdex*/)
+{
+ HRESULT ret = ResultFromScode(E_NOTIMPL);
+
+ return ret;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::GetMemberName(
+ /* [in] */ DISPID /*id*/,
+ /* [out] */ BSTR __RPC_FAR* /*pbstrName*/)
+{
+ HRESULT ret = ResultFromScode(E_NOTIMPL);
+
+ return ret;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::GetNextDispID(
+ /* [in] */ DWORD /*grfdex*/,
+ /* [in] */ DISPID /*id*/,
+ /* [out] */ DISPID __RPC_FAR* /*pid*/)
+{
+ HRESULT ret = ResultFromScode(E_NOTIMPL);
+
+ return ret;
+}
+
+STDMETHODIMP InterfaceOleWrapper_Impl::GetNameSpaceParent(
+ /* [out] */ IUnknown __RPC_FAR *__RPC_FAR* /*ppunk*/)
+{
+ HRESULT ret = ResultFromScode(E_NOTIMPL);
+
+ return ret;
+}
+
+
+/*************************************************************************
+
+ UnoObjectWrapperRemoteOpt
+
+*************************************************************************/
+UnoObjectWrapperRemoteOpt::UnoObjectWrapperRemoteOpt( Reference<XMultiServiceFactory>& aFactory,
+ sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass):
+InterfaceOleWrapper_Impl( aFactory, unoWrapperClass, comWrapperClass),
+m_currentId(1)
+
+{
+}
+UnoObjectWrapperRemoteOpt::~UnoObjectWrapperRemoteOpt()
+{
+}
+
+// UnoConversionUtilities
+Reference< XInterface > UnoObjectWrapperRemoteOpt::createUnoWrapperInstance()
+{
+ Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
+ m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
+ return Reference<XInterface>( xWeak, UNO_QUERY);
+}
+
+STDMETHODIMP UnoObjectWrapperRemoteOpt::GetIDsOfNames ( REFIID /*riid*/, OLECHAR ** rgszNames, unsigned int cNames,
+ LCID /*lcid*/, DISPID * rgdispid )
+{
+ MutexGuard guard( getBridgeMutex());
+
+ if( ! rgdispid)
+ return E_POINTER;
+ HRESULT ret = E_UNEXPECTED;
+ // ----------------------------------------
+ // _GetValueObject
+ if( ! wcscmp( *rgszNames, JSCRIPT_VALUE_FUNC))
+ {
+ *rgdispid= DISPID_JSCRIPT_VALUE_FUNC;
+ return S_OK;
+ }
+ else if( ! wcscmp( *rgszNames, GET_STRUCT_FUNC))
+ {
+ *rgdispid= DISPID_GET_STRUCT_FUNC;
+ return S_OK;
+ }
+
+ // ----------------------------------------
+ if (m_xInvocation.is() && (cNames > 0))
+ {
+ OUString name(reinterpret_cast<const sal_Unicode*>(rgszNames[0]));
+ // has this name been determined as "bad"
+ BadNameMap::iterator badIter= m_badNameMap.find( name);
+ if( badIter == m_badNameMap.end() )
+ {
+ // name has not been bad before( member exists
+ typedef NameToIdMap::iterator ITnames;
+ pair< ITnames, bool > pair_id= m_nameToDispIdMap.insert( NameToIdMap::value_type(name, m_currentId++));
+ // new ID inserted ?
+ if( pair_id.second )
+ {// yes, now create MemberInfo and ad to IdToMemberInfoMap
+ MemberInfo d(0, name);
+ m_idToMemberInfoMap.insert( IdToMemberInfoMap::value_type( m_currentId - 1, d));
+ }
+
+ *rgdispid = pair_id.first->second;
+ ret = S_OK;
+ }
+ else
+ ret= DISP_E_UNKNOWNNAME;
+ }
+ return ret;
+}
+
+STDMETHODIMP UnoObjectWrapperRemoteOpt::Invoke ( DISPID dispidMember, REFIID /*riid*/, LCID /*lcid*/, unsigned short wFlags,
+ DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
+ unsigned int * puArgErr )
+{
+ HRESULT ret = S_OK;
+ try
+ {
+ sal_Bool bHandled= sal_False;
+ ret= InvokeGeneral( dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo,
+ puArgErr, bHandled);
+ if( bHandled)
+ return ret;
+
+ if ( dispidMember > 0 && m_xInvocation.is())
+ {
+
+ IdToMemberInfoMap::iterator it_MemberInfo= m_idToMemberInfoMap.find( dispidMember);
+ if( it_MemberInfo != m_idToMemberInfoMap.end() )
+ {
+ MemberInfo& info= it_MemberInfo->second;
+
+ Sequence<Any> params; // holds converted any s
+ if( ! info.flags )
+ { // DISPID called for the first time
+ if( wFlags == DISPATCH_METHOD )
+ {
+ convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
+
+ if( FAILED( ret= doInvoke( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, info.name, params))
+ && ret == DISP_E_MEMBERNOTFOUND)
+ {
+ // try to get the exact name
+ OUString exactName;
+ if (m_xExactName.is())
+ {
+ exactName = m_xExactName->getExactName( info.name);
+ // invoke again
+ if( exactName.getLength() != 0)
+ {
+ if( SUCCEEDED( ret= doInvoke( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, exactName, params)))
+ info.name= exactName;
+ }
+ }
+ }
+ if( SUCCEEDED( ret ) )
+ info.flags= DISPATCH_METHOD;
+ } //if( wFlags == DISPATCH_METHOD )
+
+ else if( wFlags == DISPATCH_PROPERTYPUT || wFlags == DISPATCH_PROPERTYPUTREF)
+ {
+ convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
+ if( FAILED( ret= doSetProperty( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, info.name, params))
+ && ret == DISP_E_MEMBERNOTFOUND)
+ {
+ // try to get the exact name
+ OUString exactName;
+ if (m_xExactName.is())
+ {
+ exactName = m_xExactName->getExactName( info.name);
+ // invoke again
+ if( exactName.getLength() != 0)
+ {
+ if( SUCCEEDED( ret= doSetProperty( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, exactName, params)))
+ info.name= exactName;
+ }
+ }
+ }
+ if( SUCCEEDED( ret ) )
+ info.flags= DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYGET;
+ }
+
+ else if( wFlags == DISPATCH_PROPERTYGET)
+ {
+ if( FAILED( ret= doGetProperty( pdispparams, pvarResult,
+ pexcepinfo, info.name))
+ && ret == DISP_E_MEMBERNOTFOUND)
+ {
+ // try to get the exact name
+ OUString exactName;
+ if (m_xExactName.is())
+ {
+ exactName = m_xExactName->getExactName( info.name);
+ // invoke again
+ if( exactName.getLength() != 0)
+ {
+ if( SUCCEEDED( ret= doGetProperty( pdispparams, pvarResult,
+ pexcepinfo, exactName)))
+ info.name= exactName;
+ }
+ }
+ }
+ if( SUCCEEDED( ret ) )
+ info.flags= DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT;
+ }
+ else if( wFlags & DISPATCH_METHOD &&
+ (wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF))
+ {
+
+ OUString exactName;
+ // convert params for DISPATCH_METHOD or DISPATCH_PROPERTYPUT
+ convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
+ // try first as method
+ if( FAILED( ret= doInvoke( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, info.name, params))
+ && ret == DISP_E_MEMBERNOTFOUND)
+ {
+ // try to get the exact name
+ if (m_xExactName.is())
+ {
+ exactName = m_xExactName->getExactName( info.name);
+ // invoke again
+ if( exactName.getLength() != 0)
+ {
+ if( SUCCEEDED( ret= doInvoke( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, exactName, params)))
+ info.name= exactName;
+ }
+ }
+ }
+ if( SUCCEEDED( ret ) )
+ info.flags= DISPATCH_METHOD;
+
+ // try as property
+ if( FAILED( ret) && pdispparams->cArgs == 1)
+ {
+ if( FAILED( ret= doSetProperty( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, info.name, params))
+ && ret == DISP_E_MEMBERNOTFOUND)
+ {
+ // try to get the exact name
+ if( exactName.getLength() != 0)
+ {
+ if( SUCCEEDED( ret= doSetProperty( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, exactName, params)))
+ info.name= exactName;
+ }
+ }
+ if( SUCCEEDED( ret ) )
+ info.flags= DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYGET;
+ }
+ }
+ else if( wFlags & DISPATCH_METHOD && wFlags & DISPATCH_PROPERTYGET)
+ {
+ OUString exactName;
+ convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
+
+ if( FAILED( ret= doInvoke( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, info.name, params))
+ && ret == DISP_E_MEMBERNOTFOUND)
+ {
+ // try to get the exact name
+ if (m_xExactName.is())
+ {
+ exactName = m_xExactName->getExactName( info.name);
+ // invoke again
+ if( exactName.getLength() != 0)
+ {
+ if( SUCCEEDED( ret= doInvoke( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, exactName, params)))
+ info.name= exactName;
+ }
+ }
+ }
+ if( SUCCEEDED( ret ) )
+ info.flags= DISPATCH_METHOD;
+
+ // try as property
+ if( FAILED( ret) && pdispparams->cArgs == 1)
+ {
+ if( FAILED( ret= doGetProperty( pdispparams, pvarResult,
+ pexcepinfo, info.name))
+ && ret == DISP_E_MEMBERNOTFOUND)
+ {
+ if( exactName.getLength() != 0)
+ {
+ if( SUCCEEDED( ret= doSetProperty( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, exactName, params)))
+ info.name= exactName;
+ }
+ }
+ if( SUCCEEDED( ret ) )
+ info.flags= DISPATCH_PROPERTYGET;
+ }
+ }
+
+ // update ínformation about this member
+ if( ret == DISP_E_MEMBERNOTFOUND)
+ {
+ // Remember the name as not existing
+ // and remove the MemberInfo
+ m_badNameMap[info.name]= sal_False;
+ m_idToMemberInfoMap.erase( it_MemberInfo);
+ }
+ } // if( ! info.flags )
+ else // IdToMemberInfoMap contains a MemberInfo
+ {
+ if( wFlags & DISPATCH_METHOD && info.flags == DISPATCH_METHOD)
+ {
+ convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
+ ret= doInvoke( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, info.name, params);
+ }
+ else if( (wFlags & DISPATCH_PROPERTYPUT || wFlags & DISPATCH_PROPERTYPUTREF ) &&
+ info.flags & DISPATCH_PROPERTYPUT)
+ {
+ convertDispparamsArgs(dispidMember, wFlags, pdispparams, params );
+ ret= doSetProperty( pdispparams, pvarResult,
+ pexcepinfo, puArgErr, info.name, params);
+ }
+ else if( (wFlags & DISPATCH_PROPERTYGET) && ( info.flags & DISPATCH_PROPERTYGET))
+ {
+ ret= doGetProperty( pdispparams, pvarResult,
+ pexcepinfo, info.name);
+ }
+ else
+ {
+ ret= DISP_E_MEMBERNOTFOUND;
+ }
+ }
+ }// if( it_MemberInfo != m_idToMemberInfoMap.end() )
+ else
+ ret= DISP_E_MEMBERNOTFOUND;
+ }
+ }
+ catch(BridgeRuntimeError& e)
+ {
+ writeExcepinfo(pexcepinfo, e.message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch(Exception& e)
+ {
+ OUString message= OUSTR("UnoObjectWrapperRemoteOpt::Invoke : \n") +
+ e.Message;
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+ catch(...)
+ {
+ OUString message= OUSTR("UnoObjectWrapperRemoteOpt::Invoke : \n"
+ "Unexpected exception");
+ writeExcepinfo(pexcepinfo, message);
+ ret = DISP_E_EXCEPTION;
+ }
+
+ return ret;
+}
+
+HRESULT UnoObjectWrapperRemoteOpt::methodInvoke( DISPID /*dispidMember*/, DISPPARAMS * /*pdispparams*/, VARIANT * /*pvarResult*/,
+ EXCEPINFO * /*pexcepinfo*/, unsigned int * /*puArgErr*/, Sequence<Any> params)
+{
+ return S_OK;
+}
+
+
+// The returned HRESULT is only appropriate for IDispatch::Invoke
+static HRESULT mapCannotConvertException( CannotConvertException e, unsigned int * puArgErr)
+{
+ HRESULT ret;
+ sal_Bool bWriteIndex= sal_True;
+
+ switch ( e.Reason)
+ {
+ case FailReason::OUT_OF_RANGE:
+ ret = DISP_E_OVERFLOW;
+ break;
+ case FailReason::IS_NOT_NUMBER:
+ ret = DISP_E_TYPEMISMATCH;
+ break;
+ case FailReason::IS_NOT_ENUM:
+ ret = DISP_E_TYPEMISMATCH;
+ break;
+ case FailReason::IS_NOT_BOOL:
+ ret = DISP_E_TYPEMISMATCH;
+ break;
+ case FailReason::NO_SUCH_INTERFACE:
+ ret = DISP_E_TYPEMISMATCH;
+ break;
+ case FailReason::SOURCE_IS_NO_DERIVED_TYPE:
+ ret = DISP_E_TYPEMISMATCH;
+ break;
+ case FailReason::TYPE_NOT_SUPPORTED:
+ ret = DISP_E_TYPEMISMATCH;
+ break;
+ case FailReason::INVALID:
+ ret = DISP_E_TYPEMISMATCH;
+ break;
+ case FailReason::NO_DEFAULT_AVAILABLE:
+ ret = DISP_E_BADPARAMCOUNT;
+ break;
+ case FailReason::UNKNOWN:
+ ret = E_UNEXPECTED;
+ break;
+ default:
+ ret = E_UNEXPECTED;
+ bWriteIndex= sal_False;
+ break;
+ }
+
+ if( bWriteIndex && puArgErr != NULL)
+ *puArgErr = e.ArgumentIndex;
+ return ret;
+}
+
+// The function maps the TypeClass of the any to VARTYPE: If
+// the Any contains STRUCT or INTERFACE then the return value
+// is VT_DISPATCH. The function is used from o2u_createUnoObjectWrapper
+// and the result is put into the constructor of the uno - wrapper
+// object. If a client asks the object for DISPID_VALUE and this
+// funtion returned VT_DISPATCH then the IDispatch of the same
+// object is being returned.
+// See InterfaceOleWrapper_Impl::Invoke, InterfaceOleWrapper_Impl::m_defaultValueType
+const VARTYPE getVarType( const Any& value)
+{
+ VARTYPE ret= VT_EMPTY;
+
+ switch ( value.getValueTypeClass())
+ {
+ case TypeClass_STRUCT: ret= VT_DISPATCH; break;
+ case TypeClass_INTERFACE: ret= VT_DISPATCH; break;
+ default: break;
+ }
+ return ret;
+}
+
+
+
+
+} // end namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/unoobjw.hxx b/extensions/source/ole/unoobjw.hxx
new file mode 100644
index 000000000000..e007dd662883
--- /dev/null
+++ b/extensions/source/ole/unoobjw.hxx
@@ -0,0 +1,302 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _UNOOBJW_HXX
+#define _UNOOBJW_HXX
+
+#include <com/sun/star/bridge/XBridgeSupplier2.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/script/InvocationInfo.hpp>
+#include <salhelper/simplereferenceobject.hxx>
+
+#include <tools/presys.h>
+#include "comifaces.hxx"
+#include <tools/postsys.h>
+
+#include "ole2uno.hxx"
+#include "unoconversionutilities.hxx"
+
+//#define INVOCATION_SERVICE L"com.sun.star.script.Invocation"
+#define JSCRIPT_VALUE_FUNC L"_GetValueObject"
+#define GET_STRUCT_FUNC L"_GetStruct"
+#define BRIDGE_VALUE_FUNC L"Bridge_GetValueObject"
+#define BRIDGE_GET_STRUCT_FUNC L"Bridge_GetStruct"
+#define BRIDGE_CREATE_TYPE_FUNC L"Bridge_CreateType"
+
+#define DISPID_JSCRIPT_VALUE_FUNC -10l
+#define DISPID_GET_STRUCT_FUNC -102
+#define DISPID_CREATE_TYPE_FUNC -103
+
+using namespace std;
+using namespace cppu;
+using namespace com::sun::star::bridge;
+using namespace com::sun::star::script;
+namespace ole_adapter
+{
+
+
+
+struct hash_IUnknown_Impl
+{
+ size_t operator()(const IUnknown* p) const
+ {
+ return (size_t)p;
+ }
+};
+
+struct equal_to_IUnknown_Impl
+{
+ bool operator()(const IUnknown* s1, const IUnknown* s2) const
+ {
+ return s1 == s2;
+ }
+};
+
+
+
+struct MemberInfo
+{
+ MemberInfo() : flags(0), name() {}
+ MemberInfo(WORD f, const OUString& n) : flags(f), name(n) {}
+
+ WORD flags;
+ OUString name;
+};
+
+typedef hash_map
+<
+ OUString,
+ DISPID,
+ hashOUString_Impl,
+ equalOUString_Impl
+> NameToIdMap;
+
+typedef hash_map
+<
+ OUString,
+ sal_Bool,
+ hashOUString_Impl,
+ equalOUString_Impl
+> BadNameMap;
+
+typedef hash_map
+<
+ DISPID,
+ MemberInfo
+> IdToMemberInfoMap;
+
+/*****************************************************************************
+
+ class declaration: InterfaceOleWrapper_Impl
+
+*****************************************************************************/
+
+class InterfaceOleWrapper_Impl : public WeakImplHelper2<XBridgeSupplier2, XInitialization>,
+ public IDispatchEx,
+ public UnoConversionUtilities<InterfaceOleWrapper_Impl>,
+ public IUnoObjectWrapper
+{
+public:
+
+
+ InterfaceOleWrapper_Impl(Reference<XMultiServiceFactory>& xFactory, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass);
+ ~InterfaceOleWrapper_Impl();
+
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj);
+ STDMETHOD_(ULONG, AddRef)();
+ STDMETHOD_(ULONG, Release)();
+
+ /* IDispatch methods */
+ STDMETHOD( GetTypeInfoCount )( unsigned int * pctinfo );
+ STDMETHOD( GetTypeInfo )( unsigned int itinfo, LCID lcid, ITypeInfo ** pptinfo );
+ STDMETHOD( GetIDsOfNames )( REFIID riid, OLECHAR ** rgszNames, unsigned int cNames,
+ LCID lcid, DISPID * rgdispid );
+ STDMETHOD( Invoke )( DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags,
+ DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
+ unsigned int * puArgErr );
+
+ /* IDispatchEx methods */
+
+ virtual HRESULT STDMETHODCALLTYPE GetDispID(
+ /* [in] */ BSTR bstrName,
+ /* [in] */ DWORD grfdex,
+ /* [out] */ DISPID __RPC_FAR *pid);
+
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE InvokeEx(
+ /* [in] */ DISPID id,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [in] */ DISPPARAMS __RPC_FAR *pdp,
+ /* [out] */ VARIANT __RPC_FAR *pvarRes,
+ /* [out] */ EXCEPINFO __RPC_FAR *pei,
+ /* [unique][in] */ IServiceProvider __RPC_FAR *pspCaller);
+
+ virtual HRESULT STDMETHODCALLTYPE DeleteMemberByName(
+ /* [in] */ BSTR bstr,
+ /* [in] */ DWORD grfdex);
+
+ virtual HRESULT STDMETHODCALLTYPE DeleteMemberByDispID(
+ /* [in] */ DISPID id);
+
+ virtual HRESULT STDMETHODCALLTYPE GetMemberProperties(
+ /* [in] */ DISPID id,
+ /* [in] */ DWORD grfdexFetch,
+ /* [out] */ DWORD __RPC_FAR *pgrfdex);
+
+ virtual HRESULT STDMETHODCALLTYPE GetMemberName(
+ /* [in] */ DISPID id,
+ /* [out] */ BSTR __RPC_FAR *pbstrName);
+
+ virtual HRESULT STDMETHODCALLTYPE GetNextDispID(
+ /* [in] */ DWORD grfdex,
+ /* [in] */ DISPID id,
+ /* [out] */ DISPID __RPC_FAR *pid);
+
+ virtual HRESULT STDMETHODCALLTYPE GetNameSpaceParent(
+ /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunk);
+
+ // XBridgeSupplier2 ---------------------------------------------------
+ virtual Any SAL_CALL createBridge(const Any& modelDepObject,
+ const Sequence<sal_Int8>& ProcessId,
+ sal_Int16 sourceModelType,
+ sal_Int16 destModelType)
+ throw (IllegalArgumentException, RuntimeException);
+
+ //XInitialization -----------------------------------------------------
+ virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException);
+
+ // IUnoObjectWrapper
+ STDMETHOD( getWrapperXInterface)( Reference<XInterface>* pXInt);
+ STDMETHOD( getOriginalUnoObject)( Reference<XInterface>* pXInt);
+ STDMETHOD( getOriginalUnoStruct)( Any * pStruct);
+
+ // UnoConversionUtility
+ virtual Reference< XInterface > createUnoWrapperInstance();
+ virtual Reference< XInterface > createComWrapperInstance();
+
+
+protected:
+ virtual HRESULT doInvoke( DISPPARAMS * pdispparams, VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString & name, Sequence<Any>& params);
+
+ virtual HRESULT doGetProperty( DISPPARAMS * pdispparams, VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo, OUString & name );
+
+ virtual HRESULT doSetProperty( DISPPARAMS * pdispparams, VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString & name, Sequence<Any> params);
+
+ virtual HRESULT InvokeGeneral( DISPID dispidMember, unsigned short wFlags,
+ DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
+ unsigned int * puArgErr, sal_Bool& bHandled);
+
+ void convertDispparamsArgs( DISPID id, unsigned short wFlags, DISPPARAMS* pdispparams,
+ Sequence<Any>& rSeq);
+
+ sal_Bool getInvocationInfoForCall(DISPID id, InvocationInfo& info);
+
+ Reference<XInvocation> m_xInvocation;
+ Reference<XExactName> m_xExactName;
+ Reference<XInterface> m_xOrigin;
+ NameToIdMap m_nameToDispIdMap;
+ vector<MemberInfo> m_MemberInfos;
+ // This member is used to determine the default value
+ // denoted by DISPID_VALUE (0). For proper results in JavaScript
+ // we have to return the default value when we write an object
+ // as out parameter. That is, we get an JScript Array as parameter
+ // and put a wrapped object on index null. The array object tries
+ // to detect the default value. The wrapped object must then return
+ // its own IDispatch* otherwise we cannot access it within the script.
+ // see InterfaceOleWrapper_Impl::Invoke
+ VARTYPE m_defaultValueType;
+
+};
+
+/*****************************************************************************
+
+ class declaration: UnoObjectWrapperRemoteOpt
+ ( Uno Object Wrapper Remote Optimized)
+ This is the UNO wrapper used in the service com.sun.star.bridge.OleBridgeSupplierVar1.
+ Key features:
+ DISPIDs are passed out blindly. That is in GetIDsOfNames is no name checking carried out.
+ Only if Invoke fails the name is being checked. Moreover Invoke tries to figure out
+ if a call is made to a property or method if the flags are DISPATCH_METHOD | DISPATCH_PROPERTYPUT.
+ If something has been found out about a property or member than it is saved
+ in a MemberInfo structure hold by a IdToMemberInfoMap stl map.
+
+*****************************************************************************/
+class UnoObjectWrapperRemoteOpt: public InterfaceOleWrapper_Impl
+{
+public:
+ UnoObjectWrapperRemoteOpt( Reference<XMultiServiceFactory>& aFactory, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass);
+ ~UnoObjectWrapperRemoteOpt();
+
+ STDMETHOD( GetIDsOfNames )( REFIID riid, OLECHAR ** rgszNames, unsigned int cNames,
+ LCID lcid, DISPID * rgdispid );
+ STDMETHOD( Invoke )( DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags,
+ DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
+ unsigned int * puArgErr );
+
+ // UnoConversionUtility
+ // If UNO interfaces are converted in methods of this class then
+ // they are always wrapped with instances of this class
+ virtual Reference< XInterface > createUnoWrapperInstance();
+
+protected:
+
+ HRESULT methodInvoke( DISPID dispidMember, DISPPARAMS * pdispparams, VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo, unsigned int * puArgErr, Sequence<Any> params);
+ // In GetIDsOfNames are blindly passed out, that is without verifying
+ // the name. If two names are passed in during different calls to
+ // GetIDsOfNames and the names differ only in their cases then different
+ // id's are passed out ( e.g. "doSomethingMethod" or "dosomethingmethod").
+ // In Invoke the DISPID is remapped to the name passed to GetIDsOfNames
+ // and the name is used as parameter for XInvocation::invoke. If invoke
+ // fails because of a wrong name, then m_xExactName ( XExactName) is used
+ // to verify the name. The correct name is then inserted to m_MemberInfos
+ // ( vector<MemberInfo> ). During the next call to Invoke the right name
+ // is used. .
+
+
+ BadNameMap m_badNameMap;
+
+ IdToMemberInfoMap m_idToMemberInfoMap;
+
+ DISPID m_currentId;
+
+
+};
+
+
+
+} // end namespace
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/unotypewrapper.cxx b/extensions/source/ole/unotypewrapper.cxx
new file mode 100644
index 000000000000..7461d7d0e62f
--- /dev/null
+++ b/extensions/source/ole/unotypewrapper.cxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include "unotypewrapper.hxx"
+#include "rtl/ustring.hxx"
+
+
+bool createUnoTypeWrapper(BSTR sTypeName, VARIANT * pVar)
+{
+ bool ret = false;
+ OSL_ASSERT(sTypeName && pVar);
+ CComObject< UnoTypeWrapper>* pObj;
+ VariantClear(pVar);
+ if( SUCCEEDED( CComObject<UnoTypeWrapper>::CreateInstance( &pObj)))
+ {
+ pObj->AddRef();
+ pVar->vt= VT_DISPATCH;
+#ifdef __MINGW32__
+ pVar->pdispVal= CComQIPtr<IDispatch, &__uuidof(IDispatch)>(pObj->GetUnknown());
+#else
+ pVar->pdispVal= CComQIPtr<IDispatch>(pObj->GetUnknown());
+#endif
+ //now set the value, e.i. the name of the type
+#ifdef __MINGW32__
+ CComQIPtr<IUnoTypeWrapper, &__uuidof(IUnoTypeWrapper)> spType(pVar->pdispVal);
+#else
+ CComQIPtr<IUnoTypeWrapper> spType(pVar->pdispVal);
+#endif
+ OSL_ASSERT(spType);
+ if (SUCCEEDED(spType->put_Name(sTypeName)))
+ {
+ ret = true;
+ }
+ }
+ return ret;
+}
+
+
+bool createUnoTypeWrapper(const rtl::OUString& sTypeName, VARIANT * pVar)
+{
+ CComBSTR bstr(reinterpret_cast<LPCOLESTR>(sTypeName.getStr()));
+ return createUnoTypeWrapper(bstr, pVar);
+}
+
+UnoTypeWrapper::UnoTypeWrapper()
+{
+}
+
+UnoTypeWrapper::~UnoTypeWrapper()
+{
+}
+
+
+// UnoTypeWrapper, IDispatch --------------------------------------------
+STDMETHODIMP UnoTypeWrapper::GetTypeInfoCount(UINT* /*pctinfo*/)
+{
+ return E_NOTIMPL;
+}
+
+// UnoTypeWrapper, IDispatch --------------------------------------------
+STDMETHODIMP UnoTypeWrapper::GetTypeInfo( UINT /*iTInfo*/,
+ LCID /*lcid*/,
+ ITypeInfo** /*ppTInfo*/)
+{
+ return E_NOTIMPL;
+}
+
+// UnoTypeWrapper, IDispatch --------------------------------------------
+STDMETHODIMP UnoTypeWrapper::GetIDsOfNames( REFIID /*riid*/,
+ LPOLESTR *rgszNames,
+ UINT /*cNames*/,
+ LCID /*lcid*/,
+ DISPID *rgDispId)
+{
+ if( !rgDispId)
+ return E_POINTER;
+
+ HRESULT ret= S_OK;
+ CComBSTR name(*rgszNames);
+ name.ToLower();
+
+ if( name == CComBSTR( L"name") )
+ *rgDispId= DISPID_VALUE;
+ else
+ ret= DISP_E_UNKNOWNNAME;
+
+ return ret;
+}
+
+// UnoTypeWrapper, IDispatch --------------------------------------------
+STDMETHODIMP UnoTypeWrapper::Invoke( DISPID dispIdMember,
+ REFIID /*riid*/,
+ LCID /*lcid*/,
+ WORD wFlags,
+ DISPPARAMS *pDispParams,
+ VARIANT *pVarResult,
+ EXCEPINFO* /*pExcepInfo*/,
+ UINT* /*puArgErr*/)
+{
+ if (pDispParams == NULL)
+ return DISP_E_EXCEPTION;
+
+ if( pDispParams->cNamedArgs)
+ return DISP_E_NONAMEDARGS;
+
+
+ HRESULT ret= S_OK;
+ switch( dispIdMember)
+ {
+ case DISPID_VALUE: // DISPID_VALUE
+ if (wFlags & DISPATCH_PROPERTYGET)
+ {
+ if (pVarResult == NULL)
+ {
+ ret = E_POINTER;
+ break;
+ }
+ get_Name( & pVarResult->bstrVal);
+ pVarResult->vt = VT_BSTR;
+ }
+ break;
+ default:
+ ret= DISP_E_MEMBERNOTFOUND;
+ break;
+ }
+
+ return ret;
+}
+
+// IUnoTypeWrapper-----------------------
+STDMETHODIMP UnoTypeWrapper::put_Name(BSTR val)
+{
+ Lock();
+ HRESULT hr = S_OK;
+ m_sName = val;
+ Unlock();
+ return hr;
+}
+
+// (UnoTypeWrapper-----------------------
+STDMETHODIMP UnoTypeWrapper::get_Name(BSTR *pVal)
+{
+ Lock();
+ HRESULT hr = S_OK;
+ if( !pVal)
+ return E_POINTER;
+ *pVal = m_sName.Copy();
+ Unlock();
+ return hr;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/unotypewrapper.hxx b/extensions/source/ole/unotypewrapper.hxx
new file mode 100644
index 000000000000..f09fd9bfbbb2
--- /dev/null
+++ b/extensions/source/ole/unotypewrapper.hxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef UNO_TYPE_WRAPPER_HXX
+#define UNO_TYPE_WRAPPER_HXX
+
+#pragma warning (push,1)
+#pragma warning (disable:4548)
+
+#include <tools/presys.h>
+#define STRICT
+#define _WIN32_WINNT 0x0403
+#define _WIN32_DCOM
+#if OSL_DEBUG_LEVEL > 0
+//#define _ATL_DEBUG_INTERFACES
+#endif
+#include <atlbase.h>
+extern CComModule _Module;
+#include <atlcom.h>
+#include <tools/postsys.h>
+
+#pragma warning (pop)
+#pragma warning (disable:4505)
+ // disable "unreferenced local function has been removed" globally
+
+#include "comifaces.hxx"
+
+/* creates an UnoTypWrapper and sets the Name property to the value
+ specified by sTypeName.
+ Returns true if the object could be created and initialized.
+ */
+bool createUnoTypeWrapper(BSTR sTypeName, VARIANT * pVariant);
+bool createUnoTypeWrapper(const rtl::OUString& sTypeName, VARIANT * pVar);
+
+class UnoTypeWrapper:
+ public CComObjectRootEx<CComMultiThreadModel>,
+ public IUnoTypeWrapper,
+ public IDispatch
+{
+public:
+ UnoTypeWrapper();
+ virtual ~UnoTypeWrapper();
+
+ BEGIN_COM_MAP(UnoTypeWrapper)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(IUnoTypeWrapper)
+ END_COM_MAP()
+
+ // IDispatch -------------------------------------------
+ STDMETHOD( GetTypeInfoCount)(UINT *pctinfo);
+
+ STDMETHOD( GetTypeInfo)( UINT iTInfo,
+ LCID lcid,
+ ITypeInfo **ppTInfo);
+
+ STDMETHOD( GetIDsOfNames)( REFIID riid,
+ LPOLESTR *rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID *rgDispId);
+
+ STDMETHOD( Invoke)( DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS *pDispParams,
+ VARIANT *pVarResult,
+ EXCEPINFO *pExcepInfo,
+ UINT *puArgErr);
+ // IUnoTypeWrapper --------------------------------------
+ STDMETHOD(put_Name)(BSTR val);
+ STDMETHOD(get_Name)(BSTR* pVal);
+
+ CComBSTR m_sName;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/windata.cxx b/extensions/source/ole/windata.cxx
new file mode 100644
index 000000000000..e4047e3b184c
--- /dev/null
+++ b/extensions/source/ole/windata.cxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include "windata.hxx"
+
+
+namespace ole_adapter
+{
+
+
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/ole/windata.hxx b/extensions/source/ole/windata.hxx
new file mode 100644
index 000000000000..fce3d4af5e9c
--- /dev/null
+++ b/extensions/source/ole/windata.hxx
@@ -0,0 +1,201 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef AUTOMATION_BRIDGE_WINDATA_HXX
+#define AUTOMATION_BRIDGE_WINDATA_HXX
+
+#pragma warning (push,1)
+#pragma warning (disable:4668)
+#pragma warning (disable:4548)
+#include "oleidl.h"
+
+#include <atlbase.h>
+#pragma warning (pop)
+#include "osl/diagnose.h"
+
+namespace ole_adapter
+{
+//Wrapper for VARDESC
+class VarDesc
+{
+ VARDESC* operator = (const VarDesc*);
+ VarDesc(const VarDesc&);
+// Construction
+public:
+ CComPtr< ITypeInfo > m_pTypeInfo;
+ VARDESC* m_pVarDesc;
+
+ VarDesc(ITypeInfo* pTypeInfo) :
+ m_pVarDesc(NULL),
+ m_pTypeInfo(pTypeInfo)
+ {
+ OSL_ASSERT(pTypeInfo);
+ }
+ ~VarDesc()
+ {
+ if (m_pVarDesc != NULL)
+ {
+ m_pTypeInfo->ReleaseVarDesc(m_pVarDesc);
+ }
+ }
+
+ VARDESC* operator->()
+ {
+ return m_pVarDesc;
+ }
+
+ VARDESC** operator&()
+ {
+ return &m_pVarDesc;
+ }
+
+ operator VARDESC* ()
+ {
+ return m_pVarDesc;
+ }
+};
+
+//Wrapper for FUNCDESC structure
+class FuncDesc
+{
+ FUNCDESC* operator = (const FuncDesc &);
+ FuncDesc(const FuncDesc&);
+ CComPtr<ITypeInfo> m_pTypeInfo;
+ FUNCDESC * m_pFuncDesc;
+
+public:
+
+ FuncDesc(ITypeInfo * pTypeInfo) :
+ m_pFuncDesc(NULL),
+ m_pTypeInfo(pTypeInfo)
+ {
+ OSL_ASSERT(pTypeInfo);
+ }
+ ~FuncDesc()
+ {
+ ReleaseFUNCDESC();
+ }
+
+ FUNCDESC* operator -> ()
+ {
+ return m_pFuncDesc;
+ }
+
+ FUNCDESC** operator & ()
+ {
+ return & m_pFuncDesc;
+ }
+
+ operator FUNCDESC* ()
+ {
+ return m_pFuncDesc;
+ }
+
+ FUNCDESC* operator = (FUNCDESC* pDesc)
+ {
+ ReleaseFUNCDESC();
+ m_pFuncDesc = pDesc;
+ return m_pFuncDesc;
+ }
+ FUNCDESC* Detach()
+ {
+ FUNCDESC* pDesc = m_pFuncDesc;
+ m_pFuncDesc = NULL;
+ return pDesc;
+ }
+
+ void ReleaseFUNCDESC()
+ {
+ if (m_pFuncDesc != NULL)
+ {
+ m_pTypeInfo->ReleaseFuncDesc(m_pFuncDesc);
+ }
+ m_pFuncDesc = NULL;
+ }
+};
+//Wrapper for EXCEPINFO structure
+class ExcepInfo : public EXCEPINFO
+{
+ EXCEPINFO* operator = (const ExcepInfo& );
+ ExcepInfo(const ExcepInfo &);
+public:
+ ExcepInfo()
+ {
+ memset(this, 0, sizeof(ExcepInfo));
+ }
+ ~ExcepInfo()
+ {
+ if (bstrSource != NULL)
+ ::SysFreeString(bstrSource);
+ if (bstrDescription != NULL)
+ ::SysFreeString(bstrDescription);
+ if (bstrHelpFile != NULL)
+ ::SysFreeString(bstrHelpFile);
+ }
+};
+
+//Wrapper for TYPEATTR
+class TypeAttr
+{
+ TYPEATTR* operator = (const TypeAttr &);
+ TypeAttr(const TypeAttr &);
+public:
+ CComPtr< ITypeInfo > m_pTypeInfo;
+ TYPEATTR* m_pTypeAttr;
+
+ TypeAttr(ITypeInfo* pTypeInfo) :
+ m_pTypeAttr( NULL ),
+ m_pTypeInfo( pTypeInfo )
+ {
+ OSL_ASSERT(pTypeInfo);
+ }
+ ~TypeAttr() throw()
+ {
+ if (m_pTypeAttr != NULL)
+ {
+ m_pTypeInfo->ReleaseTypeAttr(m_pTypeAttr);
+ }
+ }
+
+ TYPEATTR** operator&() throw()
+ {
+ return &m_pTypeAttr;
+ }
+
+ TYPEATTR* operator->() throw()
+ {
+ return m_pTypeAttr;
+ }
+};
+
+
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */