2000-09-18 15:18:56 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
|
|
|
* $RCSfile: oleobjw.cxx,v $
|
|
|
|
*
|
2000-10-19 12:22:20 +00:00
|
|
|
* $Revision: 1.5 $
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
2000-10-19 12:22:20 +00:00
|
|
|
* last change: $Author: jl $ $Date: 2000-10-19 13:22:20 $
|
2000-09-18 15:18:56 +00:00
|
|
|
*
|
|
|
|
* The Contents of this file are made available subject to the terms of
|
|
|
|
* either of the following licenses
|
|
|
|
*
|
|
|
|
* - GNU Lesser General Public License Version 2.1
|
|
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
|
|
*
|
|
|
|
* Sun Microsystems Inc., October, 2000
|
|
|
|
*
|
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library 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 for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Sun Industry Standards Source License Version 1.1
|
|
|
|
* =================================================
|
|
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
|
|
* Source License Version 1.1 (the "License"); You may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of the
|
|
|
|
* License at http://www.openoffice.org/license.html.
|
|
|
|
*
|
|
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
|
|
* See the License for the specific provisions governing your rights and
|
|
|
|
* obligations concerning the Software.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
|
|
*
|
|
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s): _______________________________________
|
|
|
|
*
|
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#include "ole2uno.hxx"
|
|
|
|
|
|
|
|
#ifndef _OSL_MUTEX_HXX_
|
|
|
|
#include <osl/mutex.hxx>
|
|
|
|
#endif
|
|
|
|
#include <osl/diagnose.h>
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_FAILREASON_HPP_
|
|
|
|
#include <com/sun/star/script/FailReason.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_BEANS_XMATERIALHOLDER_HPP_
|
|
|
|
#include <com/sun/star/beans/XMaterialHolder.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_XTYPECONVERTER_HPP_
|
|
|
|
#include <com/sun/star/script/XTypeConverter.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_FINISHENGINEEVENT_HPP_
|
|
|
|
#include <com/sun/star/script/FinishEngineEvent.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_INTERRUPTREASON_HPP_
|
|
|
|
#include <com/sun/star/script/InterruptReason.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_XENGINELISTENER_HPP_
|
|
|
|
#include <com/sun/star/script/XEngineListener.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_XDEBUGGING_HPP_
|
|
|
|
#include <com/sun/star/script/XDebugging.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_XINVOCATION_HPP_
|
|
|
|
#include <com/sun/star/script/XInvocation.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_CONTEXTINFORMATION_HPP_
|
|
|
|
#include <com/sun/star/script/ContextInformation.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_FINISHREASON_HPP_
|
|
|
|
#include <com/sun/star/script/FinishReason.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_XENGINE_HPP_
|
|
|
|
#include <com/sun/star/script/XEngine.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_INTERRUPTENGINEEVENT_HPP_
|
|
|
|
#include <com/sun/star/script/InterruptEngineEvent.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_SCRIPT_XLIBRARYACCESS_HPP_
|
|
|
|
#include <com/sun/star/script/XLibraryAccess.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_BRIDGE_XBRIDGESUPPLIER_HPP_
|
|
|
|
#include <com/sun/star/bridge/XBridgeSupplier.hpp>
|
|
|
|
#endif
|
|
|
|
//#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
|
|
|
|
//#include <com/sun/star/lang/XUnoTunnel.hpp>
|
|
|
|
//#endif
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_BRIDGE_MODELDEPENDENT_HPP_
|
|
|
|
#include <com/sun/star/bridge/ModelDependent.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <typelib/typedescription.hxx>
|
|
|
|
#include <rtl/uuid.h>
|
|
|
|
#include <rtl/memory.h>
|
|
|
|
#ifndef _RTL_USTRING_
|
|
|
|
#include <rtl/ustring>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//#include <tools/presys.h>
|
|
|
|
|
|
|
|
#include "jscriptclasses.hxx"
|
|
|
|
//#include <tools/postsys.h>
|
|
|
|
|
|
|
|
#include "oleobjw.hxx"
|
|
|
|
#include "unoobjw.hxx"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace osl;
|
|
|
|
using namespace rtl;
|
|
|
|
using namespace cppu;
|
|
|
|
using namespace com::sun::star::lang;
|
|
|
|
using namespace com::sun::star::bridge;
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
|
|
|
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_pDispatch(NULL), m_eJScript( JScriptUndefined)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
IUnknownWrapper_Impl::~IUnknownWrapper_Impl()
|
|
|
|
{
|
|
|
|
OGuard guard( globalWrapperMutex);
|
|
|
|
acquire(); // make sure we don't delete us twice
|
|
|
|
Reference<XInterface> xInt( static_cast<XWeak*>(this), UNO_QUERY);
|
|
|
|
|
|
|
|
// remove entries in global maps
|
|
|
|
typedef hash_map<sal_uInt32, sal_uInt32>::iterator _IT;
|
|
|
|
_IT it= WrapperToAdapterMap.find( (sal_uInt32) xInt.get());
|
|
|
|
if( it != WrapperToAdapterMap.end())
|
|
|
|
{
|
|
|
|
sal_uInt32 adapter= it->second;
|
|
|
|
|
|
|
|
AdapterToWrapperMap.erase( adapter);
|
|
|
|
WrapperToAdapterMap.erase( it);
|
|
|
|
}
|
|
|
|
|
|
|
|
o2u_attachCurrentThread();
|
|
|
|
|
|
|
|
m_pUnknown->Release();
|
|
|
|
if (m_pDispatch)
|
|
|
|
{
|
|
|
|
m_pDispatch->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Reference<XIntrospectionAccess> SAL_CALL IUnknownWrapper_Impl::getIntrospection(void)
|
|
|
|
throw (RuntimeException )
|
|
|
|
{
|
|
|
|
Reference<XIntrospectionAccess> ret;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
DispIdMap::iterator IUnknownWrapper_Impl::getDispIdEntry(const OUString& name)
|
|
|
|
{
|
|
|
|
|
|
|
|
DispIdMap::iterator iter = m_dispIdMap.find(name);
|
|
|
|
|
|
|
|
if (iter == m_dispIdMap.end())
|
|
|
|
{
|
|
|
|
unsigned int flags = 0;
|
|
|
|
HRESULT result;
|
|
|
|
DISPID dispId;
|
|
|
|
OLECHAR* oleNames[1];
|
|
|
|
|
|
|
|
oleNames[0] = (OLECHAR*)name.getStr();
|
|
|
|
|
|
|
|
result = m_pDispatch->GetIDsOfNames(IID_NULL,
|
|
|
|
oleNames,
|
|
|
|
1,
|
|
|
|
LOCALE_SYSTEM_DEFAULT,
|
|
|
|
&dispId);
|
|
|
|
|
|
|
|
if (result == NOERROR)
|
|
|
|
{
|
|
|
|
flags |= DISPATCH_METHOD;
|
|
|
|
flags |= DISPATCH_PROPERTYPUT;
|
|
|
|
flags |= DISPATCH_PROPERTYPUTREF;
|
|
|
|
|
|
|
|
DISPPARAMS dispparams;
|
|
|
|
VARIANT varResult;
|
|
|
|
EXCEPINFO excepinfo;
|
|
|
|
unsigned int uArgErr;
|
|
|
|
|
|
|
|
VariantInit(&varResult);
|
|
|
|
|
|
|
|
// converting UNO parameters to OLE variants
|
|
|
|
dispparams.rgdispidNamedArgs = NULL;
|
|
|
|
dispparams.cArgs = 0;
|
|
|
|
dispparams.cNamedArgs = 0;
|
|
|
|
dispparams.rgvarg = NULL;
|
|
|
|
|
|
|
|
// try to invoke PROPERTY_GET to evaluate if this name denotes a property
|
|
|
|
result = m_pDispatch->Invoke(dispId,
|
|
|
|
IID_NULL,
|
|
|
|
LOCALE_SYSTEM_DEFAULT,
|
|
|
|
DISPATCH_PROPERTYGET,
|
|
|
|
&dispparams,
|
|
|
|
&varResult,
|
|
|
|
&excepinfo,
|
|
|
|
&uArgErr);
|
|
|
|
|
|
|
|
if (result == S_OK)
|
|
|
|
{
|
|
|
|
flags |= DISPATCH_PROPERTYGET;
|
|
|
|
}
|
|
|
|
|
|
|
|
// freeing allocated OLE parameters
|
|
|
|
VariantClear(&varResult);
|
|
|
|
|
|
|
|
if (flags != 0)
|
|
|
|
{
|
|
|
|
iter = ((DispIdMap&)m_dispIdMap).insert(
|
|
|
|
DispIdMap::value_type(name, pair<DISPID, unsigned short>(dispId, flags))).first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return iter;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
setCurrentInvokeCall( aFunctionName);
|
|
|
|
|
|
|
|
Any ret;
|
|
|
|
|
|
|
|
DispIdMap::iterator iter = getDispIdEntry(aFunctionName);
|
|
|
|
|
|
|
|
if ((iter != m_dispIdMap.end()) && (((*iter).second.second & DISPATCH_METHOD) != 0))
|
|
|
|
{
|
|
|
|
TypeDescription methodDesc;
|
|
|
|
getMethodInfo( methodDesc );
|
|
|
|
if( methodDesc.is())
|
|
|
|
ret = invokeWithDispIdUnoTlb((*iter).second.first,
|
|
|
|
aParams,
|
|
|
|
aOutParamIndex,
|
|
|
|
aOutParam);
|
|
|
|
else
|
|
|
|
ret= invokeWithDispIdComTlb( (*iter).second.first, //DISPID
|
|
|
|
aParams,
|
|
|
|
aOutParamIndex,
|
|
|
|
aOutParam);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
throw IllegalArgumentException();
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL IUnknownWrapper_Impl::setValue( const OUString& aPropertyName,
|
|
|
|
const Any& aValue )
|
|
|
|
throw(UnknownPropertyException, CannotConvertException, InvocationTargetException,
|
|
|
|
RuntimeException)
|
|
|
|
{
|
|
|
|
|
|
|
|
DispIdMap::iterator iter = getDispIdEntry(aPropertyName);
|
|
|
|
|
|
|
|
if ((iter != m_dispIdMap.end()) && (((*iter).second.second & DISPATCH_PROPERTYPUT) != 0))
|
|
|
|
{
|
|
|
|
setValueWithDispId((*iter).second.first, aValue);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
throw UnknownPropertyException();
|
|
|
|
}
|
|
|
|
|
|
|
|
Any SAL_CALL IUnknownWrapper_Impl::getValue( const OUString& aPropertyName )
|
|
|
|
throw(UnknownPropertyException, RuntimeException)
|
|
|
|
{
|
|
|
|
setCurrentGetCall( aPropertyName);
|
|
|
|
|
|
|
|
Any ret;
|
|
|
|
|
|
|
|
DispIdMap::iterator iter = getDispIdEntry(aPropertyName);
|
|
|
|
|
|
|
|
if (iter != m_dispIdMap.end() && (((*iter).second.second & DISPATCH_PROPERTYGET) != 0))
|
|
|
|
{
|
|
|
|
ret = getValueWithDispId((*iter).second.first);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
throw UnknownPropertyException();
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool SAL_CALL IUnknownWrapper_Impl::hasMethod( const OUString& aName )
|
|
|
|
throw(RuntimeException)
|
|
|
|
{
|
|
|
|
sal_Bool ret = FALSE;
|
|
|
|
|
|
|
|
o2u_attachCurrentThread();
|
|
|
|
|
|
|
|
DispIdMap::iterator iter = ((IUnknownWrapper_Impl*)this)->getDispIdEntry(aName);
|
|
|
|
|
|
|
|
ret = (
|
|
|
|
(iter != ((IUnknownWrapper_Impl*)this)->m_dispIdMap.end()) &&
|
|
|
|
(((*iter).second.second & DISPATCH_METHOD) != 0)
|
|
|
|
);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool SAL_CALL IUnknownWrapper_Impl::hasProperty( const OUString& aName )
|
|
|
|
throw(RuntimeException)
|
|
|
|
{
|
|
|
|
sal_Bool ret = FALSE;
|
|
|
|
|
|
|
|
o2u_attachCurrentThread();
|
|
|
|
|
|
|
|
DispIdMap::iterator iter = ((IUnknownWrapper_Impl*)this)->getDispIdEntry(aName);
|
|
|
|
|
|
|
|
ret = (
|
|
|
|
(iter != ((IUnknownWrapper_Impl*)this)->m_dispIdMap.end()) &&
|
|
|
|
(((*iter).second.second & DISPATCH_PROPERTYGET) != 0)
|
|
|
|
);
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
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_pDispatch != NULL)
|
|
|
|
{
|
|
|
|
V_VT(pVariant) = VT_DISPATCH;
|
|
|
|
V_DISPATCH(pVariant) = m_pDispatch;
|
|
|
|
m_pDispatch->AddRef();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
V_VT(pVariant) = VT_UNKNOWN;
|
|
|
|
V_UNKNOWN(pVariant) = m_pUnknown;
|
|
|
|
m_pUnknown->AddRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
ret.setValue((void*)&pVariant, getCppuType( (sal_uInt32*) 0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
Any IUnknownWrapper_Impl::invokeWithDispIdUnoTlb(DISPID dispID,
|
|
|
|
const Sequence< Any >& Params,
|
|
|
|
Sequence< sal_Int16 >& OutParamIndex,
|
|
|
|
Sequence< Any >& OutParam)
|
|
|
|
throw ( IllegalArgumentException, CannotConvertException,
|
|
|
|
InvocationTargetException, RuntimeException)
|
|
|
|
{
|
|
|
|
Any ret;
|
|
|
|
HRESULT hr= S_OK;
|
|
|
|
o2u_attachCurrentThread();
|
|
|
|
|
|
|
|
|
|
|
|
sal_Int32 parameterCount= Params.getLength();
|
|
|
|
sal_Int32 outParameterCount= 0;
|
|
|
|
typelib_InterfaceMethodTypeDescription* pMethod= NULL;
|
|
|
|
TypeDescription methodDesc;
|
|
|
|
getMethodInfo( 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();
|
|
|
|
// CComDispatchDriver disp( m_pDispatch);
|
|
|
|
|
|
|
|
CComVariant *pVarParams= NULL;
|
|
|
|
CComVariant *pVarParamsRef= NULL;
|
|
|
|
sal_Bool bConvOk= sal_True;
|
|
|
|
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)
|
|
|
|
pVarParams= new CComVariant[ parameterCount];
|
|
|
|
// 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)
|
|
|
|
{
|
|
|
|
pVarParamsRef= new CComVariant[ outParameterCount];
|
|
|
|
// build up the parameters for IDispatch::Invoke
|
2000-10-19 12:22:20 +00:00
|
|
|
// sal_Int32 inParamIndex=0;
|
2000-09-18 15:18:56 +00:00
|
|
|
sal_Int32 outParamIndex=0;
|
|
|
|
|
|
|
|
for( i= 0; i < parameterCount; i++)
|
|
|
|
{
|
|
|
|
|
|
|
|
// In parameter
|
|
|
|
if( pMethod->pParams[i].bIn == sal_True && ! pMethod->pParams[i].bOut)
|
|
|
|
{
|
2000-10-19 12:22:20 +00:00
|
|
|
bConvOk= anyToVariant( &pVarParams[parameterCount - i -1], Params.getConstArray()[i]);
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
// Out parameter + in/out parameter
|
|
|
|
else if( pMethod->pParams[i].bOut == sal_True)
|
|
|
|
{
|
|
|
|
CComVariant var;
|
|
|
|
switch( pMethod->pParams[i].pTypeRef->eTypeClass)
|
|
|
|
{
|
|
|
|
case TypeClass_INTERFACE:
|
|
|
|
case TypeClass_STRUCT:
|
|
|
|
if( pMethod->pParams[i].bIn && (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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 && (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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 && (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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 && (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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 && (bConvOk= anyToVariant( &var,Params[i])) )
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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 && (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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 && (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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&& (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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 && (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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&& (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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 && (bConvOk= anyToVariant( &var,Params[i])))
|
|
|
|
pVarParamsRef[ outParamIndex]= var;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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
|
|
|
|
if( ! bConvOk) break;
|
|
|
|
} // end for
|
|
|
|
}
|
|
|
|
else // it is an JScriptObject
|
|
|
|
{
|
2000-10-19 12:22:20 +00:00
|
|
|
// sal_Int32 inParamIndex= 0;
|
2000-09-18 15:18:56 +00:00
|
|
|
for( sal_Int32 i= 0; i< parameterCount; i++)
|
|
|
|
{
|
|
|
|
// In parameter
|
|
|
|
if( pMethod->pParams[i].bIn == sal_True && ! pMethod->pParams[i].bOut)
|
|
|
|
{
|
2000-10-19 12:22:20 +00:00
|
|
|
bConvOk= anyToVariant( &pVarParams[parameterCount - i -1], Params.getConstArray()[i]);
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
// 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());
|
|
|
|
CComQIPtr<IDispatch> pDisp( pUnk);
|
|
|
|
|
|
|
|
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;
|
2000-10-19 12:22:20 +00:00
|
|
|
bConvOk= anyToVariant( &varParam, Params.getConstArray()[i]);
|
2000-09-18 15:18:56 +00:00
|
|
|
if( bConvOk)
|
|
|
|
{
|
|
|
|
CComDispatchDriver dispDriver( pDisp);
|
|
|
|
if( pDisp)
|
|
|
|
if( FAILED( dispDriver.PutPropertyByName( L"0", &varParam)))
|
|
|
|
bConvOk= sal_False;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( ! bConvOk) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// No type description Available, that is we have to deal with a COM component,
|
|
|
|
// that does not implements UNO interfaces ( IDispatch based)
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( parameterCount)
|
|
|
|
{
|
|
|
|
pVarParams= new CComVariant[parameterCount];
|
|
|
|
CComVariant var;
|
|
|
|
for( sal_Int32 i= 0; i < parameterCount; i++)
|
|
|
|
{
|
|
|
|
var.Clear();
|
|
|
|
if( bConvOk= anyToVariant( &var, Params[i]))
|
|
|
|
pVarParams[ parameterCount - 1 -i]= var;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bConvOk)
|
|
|
|
{
|
|
|
|
CComVariant varResult;
|
|
|
|
EXCEPINFO excepinfo;
|
|
|
|
unsigned int uArgErr;
|
|
|
|
DISPPARAMS dispparams= { pVarParams, NULL, parameterCount, 0};
|
|
|
|
// invoking OLE method
|
|
|
|
hr = m_pDispatch->Invoke(dispID,
|
|
|
|
IID_NULL,
|
|
|
|
LOCALE_SYSTEM_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;
|
|
|
|
for( sal_Int32 i= 0; i < parameterCount; i++)
|
|
|
|
{
|
|
|
|
if( pMethod->pParams[i].bOut )
|
|
|
|
{
|
|
|
|
OutParamIndex[outIndex]= i;
|
|
|
|
Any outAny;
|
|
|
|
if( !bJScriptObject)
|
|
|
|
{
|
|
|
|
if( bConvRet= variantToAny2( &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)))
|
|
|
|
{
|
|
|
|
if( bConvRet= variantToAny2( &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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// return value, no type information available
|
|
|
|
if ( bConvRet)
|
|
|
|
if( pMethod )
|
|
|
|
bConvRet= variantToAny2(&varResult, ret, Type( pMethod->pReturnTypeRef), sal_False);
|
|
|
|
else
|
|
|
|
bConvRet= variantToAny(&varResult, ret, sal_False);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pVarParams)
|
|
|
|
delete[] pVarParams;
|
|
|
|
// The destructor of CComVariant calls VariantClear which takes null pointers into account
|
|
|
|
// and does not try to destroy them.
|
|
|
|
if( pVarParamsRef)
|
|
|
|
delete[] pVarParamsRef;
|
|
|
|
|
|
|
|
if( !bConvRet) // conversion of return or out parameter failed
|
|
|
|
throw CannotConvertException( L"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(L"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(L"call to OLE object failed", static_cast<XInterface*>(
|
|
|
|
static_cast<XWeak*>(this)), uArgErr);
|
|
|
|
break;
|
|
|
|
case DISP_E_TYPEMISMATCH:
|
|
|
|
throw CannotConvertException(L"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(L"call to OLE object failed", static_cast<XInterface*>(
|
|
|
|
static_cast<XWeak*>(this)), TypeClass_UNKNOWN, FailReason::NO_DEFAULT_AVAILABLE, uArgErr);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw RuntimeException();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( !bConvOk) // conversion of parameters failed
|
|
|
|
{
|
|
|
|
if( pVarParams)
|
|
|
|
delete [] pVarParams;
|
|
|
|
if( pVarParamsRef)
|
|
|
|
delete [] pVarParamsRef;
|
|
|
|
throw CannotConvertException( L"Call to COM object failed. Conversion of in or in/out parameters failed",
|
|
|
|
Reference<XInterface>( static_cast<XWeak*>(this), UNO_QUERY ), TypeClass_UNKNOWN,
|
|
|
|
FailReason::UNKNOWN, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IUnknownWrapper_Impl::setValueWithDispId(DISPID dispID,
|
|
|
|
const Any& Value)
|
|
|
|
throw (UnknownPropertyException,
|
|
|
|
CannotConvertException,
|
|
|
|
InvocationTargetException,
|
|
|
|
RuntimeException)
|
|
|
|
{
|
|
|
|
HRESULT hr= S_OK;
|
|
|
|
DISPPARAMS dispparams;
|
|
|
|
VARIANT varResult;
|
|
|
|
EXCEPINFO excepinfo;
|
|
|
|
unsigned int uArgErr;
|
|
|
|
|
|
|
|
o2u_attachCurrentThread();
|
|
|
|
|
|
|
|
VariantInit(&varResult);
|
|
|
|
|
|
|
|
// converting UNO value to OLE variant
|
|
|
|
DISPID dispidPut= DISPID_PROPERTYPUT;
|
|
|
|
dispparams.rgdispidNamedArgs = &dispidPut;
|
|
|
|
dispparams.cArgs = 1;
|
|
|
|
dispparams.cNamedArgs = 1;
|
|
|
|
|
|
|
|
dispparams.rgvarg = (VARIANTARG*)malloc(sizeof(VARIANTARG));
|
|
|
|
|
|
|
|
anyToVariant(&(dispparams.rgvarg[0]), Value);
|
|
|
|
|
|
|
|
// set OLE property
|
|
|
|
hr = m_pDispatch->Invoke(dispID,
|
|
|
|
IID_NULL,
|
|
|
|
LOCALE_SYSTEM_DEFAULT,
|
|
|
|
DISPATCH_PROPERTYPUT,
|
|
|
|
&dispparams,
|
|
|
|
&varResult,
|
|
|
|
&excepinfo,
|
|
|
|
&uArgErr);
|
|
|
|
|
|
|
|
// freeing allocated OLE parameters
|
|
|
|
VariantClear(&(dispparams.rgvarg[0]));
|
|
|
|
free(dispparams.rgvarg);
|
|
|
|
VariantClear(&varResult);
|
|
|
|
|
|
|
|
// 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(L"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(L"call to OLE object failed", static_cast<XInterface*>(
|
|
|
|
static_cast<XWeak*>(this)), uArgErr) ;
|
|
|
|
break;
|
|
|
|
case DISP_E_TYPEMISMATCH:
|
|
|
|
throw CannotConvertException(L"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(L"call to OLE object failed",static_cast<XInterface*>(
|
|
|
|
static_cast<XWeak*>(this)) , TypeClass_UNKNOWN, FailReason::NO_DEFAULT_AVAILABLE, uArgErr);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw RuntimeException();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Any IUnknownWrapper_Impl::getValueWithDispId(DISPID dispID)
|
|
|
|
throw (UnknownPropertyException,RuntimeException)
|
|
|
|
{
|
|
|
|
Any ret;
|
|
|
|
HRESULT hr;
|
|
|
|
DISPPARAMS dispparams;
|
|
|
|
VARIANT varResult;
|
|
|
|
EXCEPINFO excepinfo;
|
|
|
|
unsigned int uArgErr;
|
|
|
|
|
|
|
|
o2u_attachCurrentThread();
|
|
|
|
|
|
|
|
VariantInit(&varResult);
|
|
|
|
|
|
|
|
// converting UNO parameters to OLE variants
|
|
|
|
dispparams.rgdispidNamedArgs = NULL;
|
|
|
|
dispparams.cArgs = 0;
|
|
|
|
dispparams.cNamedArgs = 0;
|
|
|
|
dispparams.rgvarg = NULL;
|
|
|
|
|
|
|
|
// invoking OLE method
|
|
|
|
hr = m_pDispatch->Invoke(dispID,
|
|
|
|
IID_NULL,
|
|
|
|
LOCALE_SYSTEM_DEFAULT,
|
|
|
|
DISPATCH_PROPERTYGET,
|
|
|
|
&dispparams,
|
|
|
|
&varResult,
|
|
|
|
&excepinfo,
|
|
|
|
&uArgErr);
|
|
|
|
|
|
|
|
// converting return value and out parameter back to UNO
|
|
|
|
if (hr == S_OK)
|
|
|
|
{
|
|
|
|
variantToAny(&varResult, ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
// freeing allocated OLE parameters
|
|
|
|
VariantClear(&varResult);
|
|
|
|
|
|
|
|
// 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 RuntimeException();
|
|
|
|
break;
|
|
|
|
case DISP_E_MEMBERNOTFOUND:
|
|
|
|
throw UnknownPropertyException();
|
|
|
|
break;
|
|
|
|
case DISP_E_NONAMEDARGS:
|
|
|
|
throw RuntimeException();
|
|
|
|
break;
|
|
|
|
case DISP_E_OVERFLOW:
|
|
|
|
throw RuntimeException();
|
|
|
|
break;
|
|
|
|
case DISP_E_PARAMNOTFOUND:
|
|
|
|
throw RuntimeException();
|
|
|
|
break;
|
|
|
|
case DISP_E_TYPEMISMATCH:
|
|
|
|
throw RuntimeException();
|
|
|
|
break;
|
|
|
|
case DISP_E_UNKNOWNINTERFACE:
|
|
|
|
throw RuntimeException();
|
|
|
|
break;
|
|
|
|
case DISP_E_UNKNOWNLCID:
|
|
|
|
throw RuntimeException();
|
|
|
|
break;
|
|
|
|
case DISP_E_PARAMNOTOPTIONAL:
|
|
|
|
throw RuntimeException();
|
|
|
|
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 Sequence<Type> ( not mandatory)
|
|
|
|
HRESULT result;
|
|
|
|
o2u_attachCurrentThread();
|
|
|
|
|
|
|
|
if( aArguments.getLength() == 1)
|
|
|
|
{
|
|
|
|
m_pUnknown= *(IUnknown**) aArguments[0].getValue();
|
|
|
|
result = m_pUnknown->QueryInterface(IID_IDispatch, (void**) &m_pDispatch);
|
|
|
|
m_pUnknown->AddRef();
|
|
|
|
}
|
|
|
|
else if( aArguments.getLength() == 2)
|
|
|
|
{
|
|
|
|
m_pUnknown= *(IUnknown**) aArguments[0].getValue();
|
|
|
|
result = m_pUnknown->QueryInterface(IID_IDispatch, (void**) &m_pDispatch);
|
|
|
|
m_pUnknown->AddRef();
|
|
|
|
|
|
|
|
aArguments[1] >>= m_seqTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnoConversionUtilities --------------------------------------------------------------------------------
|
|
|
|
Reference< XInterface > IUnknownWrapper_Impl::createUnoWrapperInstance()
|
|
|
|
{
|
|
|
|
if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
|
|
|
|
{
|
|
|
|
Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
|
|
|
|
m_xMultiServiceFactory, 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_xMultiServiceFactory, 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_xMultiServiceFactory, m_nUnoWrapperClass, m_nComWrapperClass));
|
|
|
|
return Reference<XInterface>( xWeak, UNO_QUERY);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void IUnknownWrapper_Impl::getMethodInfo( TypeDescription& methodInfo)
|
|
|
|
{
|
|
|
|
TypeDescription desc= getInterfaceMemberDescOfCurrentCall();
|
|
|
|
if( desc.is())
|
|
|
|
{
|
|
|
|
typelib_TypeDescription* pMember= desc.get();
|
|
|
|
if( pMember->eTypeClass == TypeClass_INTERFACE_METHOD )
|
|
|
|
methodInfo= pMember;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TypeDescription IUnknownWrapper_Impl::getInterfaceMemberDescOfCurrentCall( )
|
|
|
|
{
|
|
|
|
TypeDescription ret;
|
|
|
|
OUString usCurrentCall;
|
|
|
|
if( m_usCurrentInvoke.getLength())
|
|
|
|
{
|
|
|
|
usCurrentCall= m_usCurrentInvoke;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
usCurrentCall= m_usCurrentGet;
|
|
|
|
}
|
|
|
|
OSL_ENSURE( usCurrentCall.getLength() != 0, "");
|
|
|
|
|
|
|
|
for( sal_Int32 i=0; i < m_seqTypes.getLength(); i++)
|
|
|
|
{
|
|
|
|
TypeDescription _curDesc( m_seqTypes[i]);
|
|
|
|
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) == usCurrentCall)
|
|
|
|
{
|
|
|
|
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_pDispatch);
|
|
|
|
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 == JSCRIPT_ID)
|
|
|
|
m_eJScript= IsJScript;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( m_eJScript == JScriptUndefined)
|
|
|
|
m_eJScript= NoJScript;
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_eJScript == NoJScript ? sal_False : sal_True;
|
|
|
|
}
|
|
|
|
|
2000-10-16 11:56:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
// 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.
|
2000-09-18 15:18:56 +00:00
|
|
|
Any IUnknownWrapper_Impl::invokeWithDispIdComTlb(DISPID dispID,
|
|
|
|
const Sequence< Any >& Params,
|
|
|
|
Sequence< sal_Int16 >& OutParamIndex,
|
|
|
|
Sequence< Any >& OutParam)
|
|
|
|
throw ( IllegalArgumentException, CannotConvertException,
|
|
|
|
InvocationTargetException, RuntimeException)
|
|
|
|
{
|
|
|
|
Any ret;
|
|
|
|
HRESULT result;
|
|
|
|
|
|
|
|
DISPPARAMS dispparams;
|
|
|
|
CComVariant varResult;
|
|
|
|
EXCEPINFO excepinfo;
|
|
|
|
unsigned int uArgErr;
|
|
|
|
sal_uInt32 i;
|
|
|
|
|
|
|
|
o2u_attachCurrentThread();
|
|
|
|
|
|
|
|
// converting UNO parameters to OLE variants
|
|
|
|
dispparams.rgdispidNamedArgs = NULL;
|
|
|
|
dispparams.cArgs = Params.getLength();
|
|
|
|
dispparams.cNamedArgs = 0;
|
|
|
|
|
|
|
|
CComVariant* arArgs = NULL;
|
|
|
|
CComVariant* arRefArgs= NULL; // referenced arguments
|
|
|
|
|
2000-10-12 12:02:20 +00:00
|
|
|
// Obtain type information via the IDispatch interface
|
|
|
|
getParameterInfo();
|
|
|
|
|
|
|
|
dispparams.cArgs= m_seqCurrentParamTypes.getLength();
|
2000-09-18 15:18:56 +00:00
|
|
|
if (dispparams.cArgs == 0)
|
|
|
|
{
|
|
|
|
dispparams.rgvarg = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
arArgs = new CComVariant[dispparams.cArgs];
|
|
|
|
arRefArgs= new CComVariant[dispparams.cArgs];
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < dispparams.cArgs; i++)
|
|
|
|
{
|
|
|
|
sal_Int32 revIndex= dispparams.cArgs - i -1;
|
|
|
|
arRefArgs[revIndex].byref=0;
|
|
|
|
// out param
|
|
|
|
if (m_seqCurrentParamTypes[i] & PARAMFLAG_FOUT &&
|
|
|
|
! (m_seqCurrentParamTypes[i] & PARAMFLAG_FIN) )
|
|
|
|
{
|
|
|
|
VARTYPE type= m_seqCurrentVartypes[i] ^ VT_BYREF;
|
|
|
|
if( type == VT_VARIANT )
|
|
|
|
{
|
|
|
|
arArgs[revIndex].vt= VT_VARIANT | VT_BYREF;
|
|
|
|
arArgs[revIndex].byref= &arRefArgs[revIndex];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
arRefArgs[revIndex].vt= type;
|
|
|
|
arArgs[revIndex].vt= m_seqCurrentVartypes[i];
|
|
|
|
arArgs[revIndex].byref= &arRefArgs[revIndex].byref;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// in/out param
|
|
|
|
else if( m_seqCurrentParamTypes[i] & PARAMFLAG_FOUT&&
|
|
|
|
m_seqCurrentParamTypes[i] & PARAMFLAG_FIN)
|
|
|
|
{
|
|
|
|
VARTYPE type= m_seqCurrentVartypes[i] ^ VT_BYREF;
|
|
|
|
CComVariant var;
|
|
|
|
anyToVariant( &arRefArgs[revIndex],
|
2000-10-12 12:02:20 +00:00
|
|
|
Params.getConstArray()[i], m_seqCurrentVartypes[i]);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
if( type == VT_VARIANT )
|
|
|
|
{
|
|
|
|
arArgs[revIndex].vt= VT_VARIANT | VT_BYREF;
|
|
|
|
arArgs[revIndex].byref= &arRefArgs[revIndex];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
arArgs[revIndex].vt= arRefArgs[revIndex].vt | VT_BYREF;
|
|
|
|
arArgs[revIndex].byref= &arRefArgs[revIndex].byref;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// in/param
|
|
|
|
else if( m_seqCurrentParamTypes[i] & PARAMFLAG_FIN &&
|
|
|
|
! (m_seqCurrentParamTypes[i] & PARAMFLAG_FOUT))
|
|
|
|
{
|
|
|
|
if( m_seqCurrentVartypes[i] & VT_BYREF)
|
2000-10-13 14:26:06 +00:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
anyToVariant( &arRefArgs[revIndex],
|
2000-10-12 12:02:20 +00:00
|
|
|
Params.getConstArray()[i], m_seqCurrentVartypes[i]);
|
2000-10-13 14:26:06 +00:00
|
|
|
arArgs[revIndex].vt= m_seqCurrentVartypes[i];
|
|
|
|
if( (m_seqCurrentVartypes[i] & 0x0fff ) == VT_VARIANT)
|
|
|
|
arArgs[revIndex].byref= &arRefArgs[revIndex];
|
|
|
|
else
|
|
|
|
arArgs[revIndex].byref= &arRefArgs[revIndex].byref;
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
else
|
|
|
|
anyToVariant( &arArgs[revIndex],
|
2000-10-12 12:02:20 +00:00
|
|
|
Params.getConstArray()[i], m_seqCurrentVartypes[i]);
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dispparams.rgvarg= arArgs;
|
|
|
|
// invoking OLE method
|
|
|
|
result = m_pDispatch->Invoke(dispID,
|
|
|
|
IID_NULL,
|
|
|
|
LOCALE_SYSTEM_DEFAULT,
|
2000-10-13 14:26:06 +00:00
|
|
|
DISPATCH_METHOD,
|
2000-09-18 15:18:56 +00:00
|
|
|
&dispparams,
|
|
|
|
&varResult,
|
|
|
|
&excepinfo,
|
|
|
|
&uArgErr);
|
|
|
|
|
|
|
|
// converting return value and out parameter back to UNO
|
|
|
|
if (result == S_OK)
|
|
|
|
{
|
|
|
|
if ( m_seqCurrentParamTypes.getLength())
|
|
|
|
{
|
|
|
|
// allocate space for the out param Sequence and indices Sequence
|
|
|
|
sal_Int32 outParamsCount= 0; // includes in/out parameter
|
|
|
|
for( sal_Int32 iparams=0; iparams < m_seqCurrentParamTypes.getLength(); iparams++)
|
|
|
|
{
|
|
|
|
if( m_seqCurrentParamTypes[iparams] & PARAMFLAG_FOUT)
|
|
|
|
outParamsCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
OutParamIndex.realloc( outParamsCount);
|
|
|
|
OutParam.realloc( outParamsCount);
|
|
|
|
|
|
|
|
sal_Int32 outParamIndex=0;
|
|
|
|
for( sal_Int32 i=0; i < m_seqCurrentParamTypes.getLength(); i ++)
|
|
|
|
{
|
|
|
|
if( m_seqCurrentParamTypes[i] & PARAMFLAG_FOUT)
|
|
|
|
{
|
|
|
|
OutParamIndex[outParamIndex]= i;
|
2000-10-16 11:56:07 +00:00
|
|
|
// 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.
|
|
|
|
// If JScript objects are used then the function invokeWithDispIdUnoTlb is used
|
|
|
|
// rather then this one.
|
|
|
|
variantToAny( &arRefArgs[dispparams.cArgs - i -1], OutParam[outParamIndex], sal_False );
|
2000-09-18 15:18:56 +00:00
|
|
|
outParamIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Return value
|
|
|
|
variantToAny(&varResult, ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
// lookup error code
|
|
|
|
switch (result)
|
|
|
|
{
|
|
|
|
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(L"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(L"call to OLE object failed", static_cast<XInterface*>(
|
|
|
|
static_cast<XWeak*>(this)), uArgErr);
|
|
|
|
break;
|
|
|
|
case DISP_E_TYPEMISMATCH:
|
|
|
|
throw CannotConvertException(L"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(L"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;
|
|
|
|
}
|
|
|
|
// parameter is an array that contains the referenced parameters
|
|
|
|
// params is an array of VARIANTs that contains values which are referenced by
|
|
|
|
// the VARIANTS in DISPPARAMS::rgvarg
|
|
|
|
//sal_Bool IUnknownWrapper_Impl::prepareOutParams( VARIANT* params, sal_uInt32 count )
|
|
|
|
//{
|
|
|
|
// sal_Bool ret= sal_True;
|
|
|
|
// ITypeInfo* pType= getTypeInfo();
|
|
|
|
// if(! pType )
|
|
|
|
// return sal_False;
|
|
|
|
// // build the map of function names and their tlb index
|
|
|
|
// if( sal_False == isComTlbIndex())
|
|
|
|
// buildComTlbIndex();
|
|
|
|
//
|
|
|
|
// typedef TLBFuncIndexMap::const_iterator cit;
|
|
|
|
// cit itIndex= m_mapComFunc.find( m_usCurrentInvoke );
|
|
|
|
// if( itIndex != m_mapComFunc.end())
|
|
|
|
// {
|
|
|
|
// FUNCDESC* funcDesc= NULL;
|
|
|
|
// if( SUCCEEDED( pType->GetFuncDesc( itIndex->second, &funcDesc)))
|
|
|
|
// {
|
|
|
|
// m_seqCurrentParamTypes.realloc( funcDesc->cParams);
|
|
|
|
// // Examine each param
|
|
|
|
// for( sal_Int16 iparams= 0; iparams < funcDesc->cParams; iparams++)
|
|
|
|
// {
|
|
|
|
// sal_Int32 flags= funcDesc->lprgelemdescParam->paramdesc.wParamFlags;
|
|
|
|
//
|
|
|
|
// // out parameter
|
|
|
|
// if( flags & PARAMFLAG_FOUT &&
|
|
|
|
// ! (flags & PARAMFLAG_FIN))
|
|
|
|
// {
|
|
|
|
// m_seqCurrentParamTypes[ iparams]= (sal_Int32) OUT_PARAM;
|
|
|
|
// VariantClear( ¶ms[iparams] );
|
|
|
|
// params[ iparams].byref=0;
|
|
|
|
// // Get the type
|
|
|
|
// VARTYPE paramType;
|
|
|
|
// if( getElementTypeDesc( & funcDesc->lprgelemdescParam[iparams].tdesc, paramType))
|
|
|
|
// {
|
|
|
|
// // dispparams: VT_VARIANT |VT_BYREF , referenced Value: VT_EMPTY
|
|
|
|
// if( !( paramType & VT_ARRAY) &&
|
|
|
|
// (paramType & VT_TYPEMASK) == VT_VARIANT)
|
|
|
|
// params[iparams].vt= VT_EMPTY;
|
|
|
|
// else
|
|
|
|
// params[iparams].vt= (paramType ^ VT_BYREF);
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// ret= sal_False;
|
|
|
|
// }
|
|
|
|
// // in/out parameter
|
|
|
|
// else if(flags & PARAMFLAG_FIN && flags & PARAMFLAG_FOUT )
|
|
|
|
// m_seqCurrentParamTypes[ iparams]= (sal_Int32) INOUT_PARAM;
|
|
|
|
// // in parameter
|
|
|
|
// else if(flags & PARAMFLAG_FIN && ! (flags & PARAMFLAG_FOUT ))
|
|
|
|
// m_seqCurrentParamTypes[ iparams]= (sal_Int32) IN_PARAM;
|
|
|
|
// }
|
|
|
|
// pType->ReleaseFuncDesc( funcDesc);
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// ret= sal_False;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// ret= sal_False;
|
|
|
|
//
|
|
|
|
// return ret;
|
|
|
|
//}
|
|
|
|
|
|
|
|
sal_Bool IUnknownWrapper_Impl::getParameterInfo()
|
|
|
|
{
|
|
|
|
sal_Bool ret= sal_True;
|
|
|
|
ITypeInfo* pType= getTypeInfo();
|
|
|
|
if(! pType )
|
|
|
|
return sal_False;
|
|
|
|
// build the map of function names and their tlb index
|
|
|
|
if( sal_False == isComTlbIndex())
|
|
|
|
buildComTlbIndex();
|
|
|
|
|
|
|
|
typedef TLBFuncIndexMap::const_iterator cit;
|
|
|
|
cit itIndex= m_mapComFunc.find( m_usCurrentInvoke );
|
|
|
|
if( itIndex != m_mapComFunc.end())
|
|
|
|
{
|
|
|
|
FUNCDESC* funcDesc= NULL;
|
|
|
|
if( SUCCEEDED( pType->GetFuncDesc( itIndex->second, &funcDesc)))
|
|
|
|
{
|
|
|
|
m_seqCurrentParamTypes.realloc( funcDesc->cParams);
|
|
|
|
m_seqCurrentVartypes.realloc( funcDesc->cParams);
|
|
|
|
// Examine each param
|
|
|
|
for( sal_Int16 iparams= 0; iparams < funcDesc->cParams; iparams++)
|
|
|
|
{
|
|
|
|
sal_Int32 flags= funcDesc->lprgelemdescParam[iparams].paramdesc.wParamFlags;
|
|
|
|
m_seqCurrentParamTypes[iparams]= flags & ( PARAMFLAG_FIN | PARAMFLAG_FOUT);
|
2000-10-13 14:26:06 +00:00
|
|
|
// default is PARAMFLAG_IN
|
|
|
|
if( m_seqCurrentParamTypes[iparams] == 0)
|
|
|
|
m_seqCurrentParamTypes[iparams]= PARAMFLAG_FIN;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
if( ! getElementTypeDesc( & funcDesc->lprgelemdescParam[iparams].tdesc,
|
|
|
|
m_seqCurrentVartypes[iparams]))
|
|
|
|
ret= sal_False;
|
|
|
|
|
|
|
|
if( ! ret) break;
|
|
|
|
}
|
|
|
|
pType->ReleaseFuncDesc( funcDesc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret= sal_False;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret= sal_False;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2000-10-12 12:02:20 +00:00
|
|
|
// 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
|
2000-09-18 15:18:56 +00:00
|
|
|
sal_Bool IUnknownWrapper_Impl::getElementTypeDesc( TYPEDESC *desc, VARTYPE& varType )
|
|
|
|
{
|
|
|
|
sal_Bool ret= sal_True;
|
|
|
|
VARTYPE _type;
|
|
|
|
|
|
|
|
if( desc->vt == VT_PTR)
|
|
|
|
{
|
|
|
|
if( getElementTypeDesc( desc->lptdesc, _type))
|
|
|
|
varType= _type | VT_BYREF;
|
|
|
|
else
|
|
|
|
ret= sal_False;
|
|
|
|
}
|
|
|
|
else if( desc->vt == VT_SAFEARRAY )
|
|
|
|
{
|
|
|
|
if( getElementTypeDesc( desc->lptdesc, _type))
|
|
|
|
varType= _type | VT_ARRAY;
|
|
|
|
else
|
|
|
|
sal_False;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
varType= desc->vt;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool IUnknownWrapper_Impl::buildComTlbIndex()
|
|
|
|
{
|
|
|
|
sal_Bool ret= sal_True;
|
|
|
|
|
|
|
|
ITypeInfo* pType= getTypeInfo();
|
|
|
|
if( pType)
|
|
|
|
{
|
|
|
|
TYPEATTR* typeAttr= NULL;
|
|
|
|
if( SUCCEEDED( pType->GetTypeAttr( &typeAttr)))
|
|
|
|
{
|
|
|
|
for( long i= 0; i < typeAttr->cFuncs; i++)
|
|
|
|
{
|
|
|
|
FUNCDESC* funcDesc= NULL;
|
|
|
|
if( SUCCEEDED( pType->GetFuncDesc( i, &funcDesc)))
|
|
|
|
{
|
|
|
|
BSTR memberName= NULL;
|
|
|
|
unsigned int pcNames=0;
|
|
|
|
if( SUCCEEDED(pType->GetNames( funcDesc->memid, & memberName, 1, &pcNames)))
|
|
|
|
{
|
|
|
|
m_mapComFunc.insert( TLBFuncIndexMap::value_type( OUString( memberName), i));
|
|
|
|
SysFreeString( memberName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret= sal_False;
|
|
|
|
pType->ReleaseFuncDesc( funcDesc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret=sal_False;
|
|
|
|
}
|
|
|
|
pType->ReleaseTypeAttr( typeAttr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret= sal_False;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret= sal_False;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline sal_Bool IUnknownWrapper_Impl::isComTlbIndex()
|
|
|
|
{
|
|
|
|
if( m_mapComFunc.size())
|
|
|
|
return sal_True;
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
ITypeInfo* IUnknownWrapper_Impl::getTypeInfo()
|
|
|
|
{
|
|
|
|
HRESULT hr= S_OK;
|
|
|
|
if( !m_pDispatch)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if( !m_spTypeInfo )
|
|
|
|
{
|
|
|
|
LCID localId= GetUserDefaultLCID();
|
|
|
|
CComPtr< ITypeInfo > spType;
|
|
|
|
if( SUCCEEDED( m_pDispatch->GetTypeInfo( 0, localId, &spType.p)))
|
|
|
|
m_spTypeInfo= spType;
|
|
|
|
}
|
|
|
|
return m_spTypeInfo;
|
|
|
|
}
|
|
|
|
} // end namespace
|
|
|
|
|