1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include "ole2uno.hxx"
23 #include "unoconversionutilities.hxx"
24 #include "servprov.hxx"
25 #include "unoobjw.hxx"
26 #include "oleobjw.hxx"
28 #include <com/sun/star/script/CannotConvertException.hpp>
29 #include <comphelper/automationinvokedzone.hxx>
30 #include <comphelper/windowsdebugoutput.hxx>
31 #include <comphelper/windowserrorstring.hxx>
32 #include <cppuhelper/queryinterface.hxx>
33 #include <cppuhelper/supportsservice.hxx>
34 #include <o3tl/any.hxx>
35 #include <o3tl/char16_t2wchar_t.hxx>
36 #include <officecfg/Office/Common.hxx>
37 #include <ooo/vba/XHelperInterface.hpp>
38 #include <sal/log.hxx>
42 using namespace com::sun::star::lang
;
43 using namespace com::sun::star::uno
;
44 using namespace com::sun::star::bridge
;
45 using namespace com::sun::star::bridge::ModelDependent
;
49 // GUID used since 5.2 ( src569 m)
50 // {82154420-0FBF-11d4-8313-005004526AB4}
51 DEFINE_GUID(OID_ServiceManager
, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
53 // FIXME: This GUID is just the above OID_ServiceManager with the
54 // initial part bumped by one. Is that good enough?
55 // {82154421-0FBF-11d4-8313-005004526AB4}
56 DEFINE_GUID(OID_LibreOfficeWriterApplication
, 0x82154421, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
59 // {82154425-0FBF-11d4-8313-005004526AB4}
60 DEFINE_GUID(OID_LibreOfficeCalcApplication
, 0x82154425, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
62 OneInstanceOleWrapper::OneInstanceOleWrapper( const Reference
<XMultiServiceFactory
>& smgr
,
63 std::function
<const Reference
<XInterface
>()> xInstFunction
)
65 , m_xInstFunction(xInstFunction
)
69 Reference
<XInterface
> xInt
= m_smgr
->createInstance("com.sun.star.bridge.oleautomation.BridgeSupplier");
73 Any a
= xInt
->queryInterface( cppu::UnoType
<XBridgeSupplier2
>::get() );
74 a
>>= m_bridgeSupplier
;
78 OneInstanceOleWrapper::~OneInstanceOleWrapper()
82 bool OneInstanceOleWrapper::registerClass(GUID
const * pGuid
)
86 o2u_attachCurrentThread();
88 hresult
= CoRegisterClassObject(
91 CLSCTX_INPROC_SERVER
| CLSCTX_LOCAL_SERVER
,
95 SAL_INFO("extensions.olebridge", "CoRegisterClassObject(" << *pGuid
<< "): " << WindowsErrorStringFromHRESULT(hresult
));
97 return (hresult
== NOERROR
);
100 bool OneInstanceOleWrapper::deregisterClass()
102 return CoRevokeClassObject(m_factoryHandle
) == NOERROR
;
105 COM_DECLSPEC_NOTHROW STDMETHODIMP
OneInstanceOleWrapper::QueryInterface(REFIID riid
, void ** ppv
)
107 if(IsEqualIID(riid
, IID_IUnknown
))
110 *ppv
= static_cast<IUnknown
*>(static_cast<IClassFactory
*>(this));
113 else if (IsEqualIID(riid
, IID_IClassFactory
))
116 *ppv
= static_cast<IClassFactory
*>(this);
121 return ResultFromScode(E_NOINTERFACE
);
124 COM_DECLSPEC_NOTHROW
STDMETHODIMP_(ULONG
) OneInstanceOleWrapper::AddRef()
126 return osl_atomic_increment( &m_refCount
);
129 COM_DECLSPEC_NOTHROW
STDMETHODIMP_(ULONG
) OneInstanceOleWrapper::Release()
131 MutexGuard
oGuard( Mutex::getGlobalMutex());
132 ULONG refCount
= --m_refCount
;
133 if ( m_refCount
== 0)
141 COM_DECLSPEC_NOTHROW STDMETHODIMP
OneInstanceOleWrapper::CreateInstance(IUnknown
*,
142 REFIID riid
, void** ppv
)
144 comphelper::Automation::AutomationInvokedZone aAutomationActive
;
146 SAL_INFO("extensions.olebridge", "OneInstanceOleWrapper::CreateInstance(" << riid
<< ")");
148 if (officecfg::Office::Common::Security::Scripting::DisableOLEAutomation::get())
150 return ResultFromScode(E_NOINTERFACE
);
153 HRESULT ret
= ResultFromScode(E_UNEXPECTED
);
154 const Reference
<XInterface
>& xInst
= m_xInstFunction();
157 Any
usrAny(&xInst
, cppu::UnoType
<decltype(xInst
)>::get());
159 rtl_getGlobalProcessId( arId
);
160 Any oleAny
= m_bridgeSupplier
->createBridge(usrAny
,
161 Sequence
<sal_Int8
>( reinterpret_cast<sal_Int8
*>(arId
), 16),
166 if (auto v
= o3tl::tryAccess
<sal_uIntPtr
>(oleAny
))
168 VARIANT
* pVariant
= reinterpret_cast<VARIANT
*>(*v
);
170 if ((pVariant
->vt
== VT_UNKNOWN
) || (pVariant
->vt
== VT_DISPATCH
))
172 SAL_INFO("extensions.olebridge", "OneInstanceOleWrapper::Createbridge: punkVal=" << pVariant
->punkVal
);
173 ret
= pVariant
->punkVal
->QueryInterface(riid
, ppv
);
176 VariantClear(pVariant
);
177 CoTaskMemFree(pVariant
);
184 COM_DECLSPEC_NOTHROW STDMETHODIMP
OneInstanceOleWrapper::LockServer(BOOL
/*fLock*/)
189 OleConverter::OleConverter( const Reference
<XMultiServiceFactory
> &smgr
):
190 UnoConversionUtilities
<OleConverter
>( smgr
)
195 // The XMultiServiceFactory is later set by XInitialization
196 OleConverter::OleConverter( const Reference
<XMultiServiceFactory
>& smgr
, sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
197 UnoConversionUtilities
<OleConverter
>( smgr
, unoWrapperClass
, comWrapperClass
)
202 OleConverter::~OleConverter()
206 // XBridgeSupplier --------------------------------------------------------------
207 Any SAL_CALL
OleConverter::createBridge(const Any
& modelDepObject
,
208 const Sequence
< sal_Int8
>& ProcessId
,
209 sal_Int16 sourceModelType
,
210 sal_Int16 destModelType
)
214 rtl_getGlobalProcessId( arId
);
216 Sequence
< sal_Int8
> seqProcessId( reinterpret_cast<sal_Int8
*>(arId
), 16);
218 if ( seqProcessId
== ProcessId
)
220 if (sourceModelType
== UNO
)
222 if (destModelType
== UNO
)
224 // same model -> copy value only
225 ret
= modelDepObject
;
227 else if (destModelType
== OLE
)
229 // convert UNO any into variant
230 VARIANT
* pVariant
= static_cast<VARIANT
*>(CoTaskMemAlloc(sizeof(VARIANT
)));
231 VariantInit( pVariant
);
234 anyToVariant( pVariant
, modelDepObject
);
238 CoTaskMemFree(pVariant
);
239 throw IllegalArgumentException();
241 ret
.setValue(static_cast<void*>(&pVariant
), cppu::UnoType
<sal_uIntPtr
>::get());
244 throw IllegalArgumentException();
246 else if (sourceModelType
== OLE
)
248 auto v
= o3tl::tryAccess
<sal_uIntPtr
>(modelDepObject
);
251 throw IllegalArgumentException();
253 else if (destModelType
== OLE
)
255 // same model -> copy value only
256 VARIANT
* pVariant
= static_cast<VARIANT
*>(CoTaskMemAlloc(sizeof(VARIANT
)));
258 if (NOERROR
!= VariantCopy(pVariant
, reinterpret_cast<VARIANT
*>(*v
)))
260 CoTaskMemFree(pVariant
);
261 throw(IllegalArgumentException());
265 ret
.setValue(static_cast<void*>(&pVariant
), cppu::UnoType
<sal_uIntPtr
>::get());
268 else if (destModelType
== UNO
)
270 // convert variant into UNO any
271 VARIANT
* pVariant
= reinterpret_cast<VARIANT
*>(*v
);
274 variantToAny(pVariant
, ret
);
276 catch (const CannotConvertException
& e
)
278 throw IllegalArgumentException(
279 e
.Message
, nullptr, -1);
283 throw IllegalArgumentException();
287 throw IllegalArgumentException();
293 OUString
OleConverter::getImplementationName()
295 return m_nUnoWrapperClass
== INTERFACE_OLE_WRAPPER_IMPL
296 ? OUString("com.sun.star.comp.ole.OleConverter2")
297 : OUString("com.sun.star.comp.ole.OleConverterVar1");
300 sal_Bool
OleConverter::supportsService(OUString
const & ServiceName
)
302 return cppu::supportsService(this, ServiceName
);
305 css::uno::Sequence
<OUString
> OleConverter::getSupportedServiceNames()
307 if (m_nUnoWrapperClass
== INTERFACE_OLE_WRAPPER_IMPL
)
309 return css::uno::Sequence
<OUString
>{
310 "com.sun.star.bridge.OleBridgeSupplier2",
311 "com.sun.star.bridge.oleautomation.BridgeSupplier"};
313 return {"com.sun.star.bridge.OleBridgeSupplierVar1"};
316 // XInitialize ------------------------------------------------------------------------------
317 // the first argument is an XMultiServiceFactory if at all
318 void SAL_CALL
OleConverter::initialize( const Sequence
< Any
>& aArguments
)
320 if( aArguments
.getLength() == 1 && aArguments
[0].getValueTypeClass() == TypeClass_INTERFACE
)
322 Reference
< XInterface
> xInt
;
323 aArguments
[0] >>= xInt
;
324 Reference
<XMultiServiceFactory
> xMulti( xInt
, UNO_QUERY
);
325 m_smgrRemote
= xMulti
;
329 // UnoConversionUtilities -------------------------------------------------------------------
330 Reference
< XInterface
> OleConverter::createUnoWrapperInstance()
332 if( m_nUnoWrapperClass
== INTERFACE_OLE_WRAPPER_IMPL
)
334 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper(
335 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
336 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
338 else if( m_nUnoWrapperClass
== UNO_OBJECT_WRAPPER_REMOTE_OPT
)
340 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
341 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
342 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
345 return Reference
<XInterface
>();
348 Reference
< XInterface
> OleConverter::createComWrapperInstance()
350 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper(
351 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
352 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
355 OleClient::OleClient( const Reference
<XMultiServiceFactory
>& smgr
):
356 UnoConversionUtilities
<OleClient
>( smgr
)
358 Reference
<XInterface
> xInt
;// = m_smgr->createInstance(L"com.sun.star.bridge.OleBridgeSupplier2");
362 Any a
= xInt
->queryInterface(cppu::UnoType
<XBridgeSupplier2
>::get() );
363 a
>>= m_bridgeSupplier
;
367 OleClient::~OleClient()
371 Sequence
< OUString
> SAL_CALL
OleClient::getAvailableServiceNames()
373 Sequence
< OUString
> ret
;
378 OUString
OleClient::getImplementationName()
380 return "com.sun.star.comp.ole.OleClient";
383 sal_Bool
OleClient::supportsService(OUString
const & ServiceName
)
385 return cppu::supportsService(this, ServiceName
);
388 css::uno::Sequence
<OUString
> OleClient::getSupportedServiceNames()
390 return css::uno::Sequence
<OUString
>{
391 "com.sun.star.bridge.OleObjectFactory",
392 "com.sun.star.bridge.oleautomation.Factory"};
395 Reference
<XInterface
> SAL_CALL
OleClient::createInstance(const OUString
& ServiceSpecifier
)
397 Reference
<XInterface
> ret
;
399 IUnknown
* pUnknown
= nullptr;
402 o2u_attachCurrentThread();
404 result
= CLSIDFromProgID(
405 o3tl::toW(ServiceSpecifier
.getStr()), //Pointer to the ProgID
406 &classId
); //Pointer to the CLSID
409 if (result
== NOERROR
)
411 result
= CoCreateInstance(
412 classId
, //Class identifier (CLSID) of the object
413 nullptr, //Pointer to whether object is or isn't part of an aggregate
414 CLSCTX_SERVER
, //Context for running executable code
415 IID_IUnknown
, //Reference to the identifier of the interface
416 reinterpret_cast<void**>(&pUnknown
)); //Address of output variable that receives
417 // the interface pointer requested in riid
420 if (pUnknown
!= nullptr)
425 V_VT(&variant
) = VT_UNKNOWN
;
426 V_UNKNOWN(&variant
) = pUnknown
;
427 // AddRef for Variant
430 // When the object is wrapped, then its refcount is increased
431 variantToAny(&variant
, any
);
432 if (any
.getValueTypeClass() == TypeClass_INTERFACE
)
436 pUnknown
->Release(); // CoCreateInstance
442 Reference
<XInterface
> SAL_CALL
OleClient::createInstanceWithArguments(const OUString
& ServiceSpecifier
, const Sequence
< Any
>& /*Arguments*/)
444 return createInstance( ServiceSpecifier
);
447 // UnoConversionUtilities -----------------------------------------------------------------------------
448 Reference
< XInterface
> OleClient::createUnoWrapperInstance()
450 if( m_nUnoWrapperClass
== INTERFACE_OLE_WRAPPER_IMPL
)
452 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper(
453 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
454 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
456 else if( m_nUnoWrapperClass
== UNO_OBJECT_WRAPPER_REMOTE_OPT
)
458 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
459 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
460 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
463 return Reference
< XInterface
>();
465 // UnoConversionUtilities -----------------------------------------------------------------------------
466 Reference
< XInterface
> OleClient::createComWrapperInstance( )
468 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper(
469 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
470 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
473 OleServer::OleServer( const Reference
<XMultiServiceFactory
>& smgr
):
476 Reference
<XInterface
> xInt
= m_smgr
->createInstance("com.sun.star.bridge.oleautomation.BridgeSupplier");
480 Any a
= xInt
->queryInterface( cppu::UnoType
<XBridgeSupplier2
>::get() );
481 a
>>= m_bridgeSupplier
;
484 (void) provideInstance( [&]
488 &OID_ServiceManager
);
490 (void) provideInstance( [&]
492 // We want just one SwVbaGlobals for all Automation clients
493 static const Reference
<XInterface
> xWordGlobals
= m_smgr
->createInstance("ooo.vba.word.Globals");
494 const Reference
<ooo::vba::XHelperInterface
> xHelperInterface(xWordGlobals
, UNO_QUERY
);
495 Any aApplication
= xHelperInterface
->Application();
496 Reference
<XInterface
> xApplication
;
497 aApplication
>>= xApplication
;
500 &OID_LibreOfficeWriterApplication
);
502 (void) provideInstance( [&]
505 static const Reference
<XInterface
> xCalcGlobals
= m_smgr
->createInstance("ooo.vba.excel.Globals");
506 const Reference
<ooo::vba::XHelperInterface
> xHelperInterface(xCalcGlobals
, UNO_QUERY
);
507 Any aApplication
= xHelperInterface
->Application();
508 Reference
<XInterface
> xApplication
;
509 aApplication
>>= xApplication
;
512 &OID_LibreOfficeCalcApplication
);
515 OleServer::~OleServer()
517 for (auto const& elem
: m_wrapperList
)
519 elem
->deregisterClass();
522 m_wrapperList
.clear();
525 OUString
OleServer::getImplementationName()
527 return "com.sun.star.comp.ole.OleServer";
530 sal_Bool
OleServer::supportsService(OUString
const & ServiceName
)
532 return cppu::supportsService(this, ServiceName
);
535 css::uno::Sequence
<OUString
> OleServer::getSupportedServiceNames()
537 return css::uno::Sequence
<OUString
>{
538 "com.sun.star.bridge.OleApplicationRegistration",
539 "com.sun.star.bridge.oleautomation.ApplicationRegistration"};
542 bool OleServer::provideInstance(std::function
<const Reference
<XInterface
>()> xInstFunction
, GUID
const * guid
)
544 OneInstanceOleWrapper
* pWrapper
= new OneInstanceOleWrapper( m_smgr
, xInstFunction
);
547 m_wrapperList
.push_back(pWrapper
);
549 return pWrapper
->registerClass(guid
);
552 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */