Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / extensions / source / ole / servprov.cxx
blobf5a9323d361d6b64464cb4f49de612126f1ca2fc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <vector>
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 <ooo/vba/XHelperInterface.hpp>
37 #include <sal/log.hxx>
39 using namespace cppu;
40 using namespace osl;
41 using namespace com::sun::star::lang;
42 using namespace com::sun::star::uno;
43 using namespace com::sun::star::bridge;
44 using namespace com::sun::star::bridge::ModelDependent;
46 #include <initguid.h>
48 // GUID used since 5.2 ( src569 m)
49 // {82154420-0FBF-11d4-8313-005004526AB4}
50 DEFINE_GUID(OID_ServiceManager, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
52 // FIXME: This GUID is just the above OID_ServiceManager with the
53 // initial part bumped by one. Is that good enough?
54 // {82154421-0FBF-11d4-8313-005004526AB4}
55 DEFINE_GUID(OID_LibreOfficeWriterApplication, 0x82154421, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
57 // For Calc
58 // {82154425-0FBF-11d4-8313-005004526AB4}
59 DEFINE_GUID(OID_LibreOfficeCalcApplication, 0x82154425, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
61 OneInstanceOleWrapper::OneInstanceOleWrapper( const Reference<XMultiServiceFactory>& smgr,
62 std::function<const Reference<XInterface>()> xInstFunction )
63 : m_refCount(0)
64 , m_xInstFunction(xInstFunction)
65 , m_factoryHandle(0)
66 , m_smgr(smgr)
68 Reference<XInterface> xInt = m_smgr->createInstance("com.sun.star.bridge.oleautomation.BridgeSupplier");
70 if (xInt.is())
72 Any a= xInt->queryInterface( cppu::UnoType<XBridgeSupplier2>::get() );
73 a >>= m_bridgeSupplier;
77 OneInstanceOleWrapper::~OneInstanceOleWrapper()
81 bool OneInstanceOleWrapper::registerClass(GUID const * pGuid)
83 HRESULT hresult;
85 o2u_attachCurrentThread();
87 hresult = CoRegisterClassObject(
88 *pGuid,
89 this,
90 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
91 REGCLS_MULTIPLEUSE,
92 &m_factoryHandle);
94 SAL_INFO("extensions.olebridge", "CoRegisterClassObject(" << *pGuid << "): " << WindowsErrorStringFromHRESULT(hresult));
96 return (hresult == NOERROR);
99 bool OneInstanceOleWrapper::deregisterClass()
101 return CoRevokeClassObject(m_factoryHandle) == NOERROR;
104 COM_DECLSPEC_NOTHROW STDMETHODIMP OneInstanceOleWrapper::QueryInterface(REFIID riid, void ** ppv)
106 if(IsEqualIID(riid, IID_IUnknown))
108 AddRef();
109 *ppv = static_cast<IUnknown*>(static_cast<IClassFactory*>(this));
110 return NOERROR;
112 else if (IsEqualIID(riid, IID_IClassFactory))
114 AddRef();
115 *ppv = static_cast<IClassFactory*>(this);
116 return NOERROR;
119 *ppv = nullptr;
120 return ResultFromScode(E_NOINTERFACE);
123 COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) OneInstanceOleWrapper::AddRef()
125 return osl_atomic_increment( &m_refCount);
128 COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) OneInstanceOleWrapper::Release()
130 MutexGuard oGuard( Mutex::getGlobalMutex());
131 ULONG refCount = --m_refCount;
132 if ( m_refCount == 0)
134 delete this;
137 return refCount;
140 COM_DECLSPEC_NOTHROW STDMETHODIMP OneInstanceOleWrapper::CreateInstance(IUnknown*,
141 REFIID riid, void** ppv)
143 comphelper::Automation::AutomationInvokedZone aAutomationActive;
145 SAL_INFO("extensions.olebridge", "OneInstanceOleWrapper::CreateInstance(" << riid << ")");
147 HRESULT ret = ResultFromScode(E_UNEXPECTED);
149 const Reference<XInterface>& xInst = m_xInstFunction();
150 if (xInst.is())
152 Any usrAny(&xInst, cppu::UnoType<decltype(xInst)>::get());
153 sal_uInt8 arId[16];
154 rtl_getGlobalProcessId( arId);
155 Any oleAny = m_bridgeSupplier->createBridge(usrAny,
156 Sequence<sal_Int8>( reinterpret_cast<sal_Int8*>(arId), 16),
157 UNO,
158 OLE);
161 if (auto v = o3tl::tryAccess<sal_uIntPtr>(oleAny))
163 VARIANT* pVariant = reinterpret_cast<VARIANT*>(*v);
165 if ((pVariant->vt == VT_UNKNOWN) || (pVariant->vt == VT_DISPATCH))
167 SAL_INFO("extensions.olebridge", "OneInstanceOleWrapper::Createbridge: punkVal=" << pVariant->punkVal);
168 ret = pVariant->punkVal->QueryInterface(riid, ppv);
171 VariantClear(pVariant);
172 CoTaskMemFree(pVariant);
176 return ret;
179 COM_DECLSPEC_NOTHROW STDMETHODIMP OneInstanceOleWrapper::LockServer(BOOL /*fLock*/)
181 return NOERROR;
184 OleConverter::OleConverter( const Reference<XMultiServiceFactory> &smgr):
185 UnoConversionUtilities<OleConverter>( smgr)
190 // The XMultiServiceFactory is later set by XInitialization
191 OleConverter::OleConverter( const Reference<XMultiServiceFactory>& smgr, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass ):
192 UnoConversionUtilities<OleConverter>( smgr, unoWrapperClass, comWrapperClass )
197 OleConverter::~OleConverter()
201 // XBridgeSupplier --------------------------------------------------------------
202 Any SAL_CALL OleConverter::createBridge(const Any& modelDepObject,
203 const Sequence< sal_Int8 >& ProcessId,
204 sal_Int16 sourceModelType,
205 sal_Int16 destModelType)
207 Any ret;
208 sal_uInt8 arId[16];
209 rtl_getGlobalProcessId( arId );
211 Sequence< sal_Int8 > seqProcessId( reinterpret_cast<sal_Int8*>(arId), 16);
213 if ( seqProcessId == ProcessId)
215 if (sourceModelType == UNO)
217 if (destModelType == UNO)
219 // same model -> copy value only
220 ret = modelDepObject;
222 else if (destModelType == OLE)
224 // convert UNO any into variant
225 VARIANT* pVariant = static_cast<VARIANT*>(CoTaskMemAlloc(sizeof(VARIANT)));
226 VariantInit( pVariant);
229 anyToVariant( pVariant, modelDepObject);
231 catch(...)
233 CoTaskMemFree(pVariant);
234 throw IllegalArgumentException();
236 ret.setValue(static_cast<void*>(&pVariant), cppu::UnoType<sal_uIntPtr>::get());
238 else
239 throw IllegalArgumentException();
241 else if (sourceModelType == OLE)
243 auto v = o3tl::tryAccess<sal_uIntPtr>(modelDepObject);
244 if (!v)
246 throw IllegalArgumentException();
248 else if (destModelType == OLE)
250 // same model -> copy value only
251 VARIANT* pVariant = static_cast<VARIANT*>(CoTaskMemAlloc(sizeof(VARIANT)));
253 if (NOERROR != VariantCopy(pVariant, reinterpret_cast<VARIANT*>(*v)))
255 CoTaskMemFree(pVariant);
256 throw(IllegalArgumentException());
258 else
260 ret.setValue(static_cast<void*>(&pVariant), cppu::UnoType<sal_uIntPtr>::get());
263 else if (destModelType == UNO)
265 // convert variant into UNO any
266 VARIANT* pVariant = reinterpret_cast<VARIANT*>(*v);
269 variantToAny(pVariant, ret);
271 catch (const CannotConvertException & e)
273 throw IllegalArgumentException(
274 e.Message, nullptr, -1);
277 else
278 throw IllegalArgumentException();
281 else
282 throw IllegalArgumentException();
285 return ret;
288 OUString OleConverter::getImplementationName()
290 return m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL
291 ? OUString("com.sun.star.comp.ole.OleConverter2")
292 : OUString("com.sun.star.comp.ole.OleConverterVar1");
295 sal_Bool OleConverter::supportsService(OUString const & ServiceName)
297 return cppu::supportsService(this, ServiceName);
300 css::uno::Sequence<OUString> OleConverter::getSupportedServiceNames()
302 if (m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
304 return css::uno::Sequence<OUString>{
305 "com.sun.star.bridge.OleBridgeSupplier2",
306 "com.sun.star.bridge.oleautomation.BridgeSupplier"};
308 return {"com.sun.star.bridge.OleBridgeSupplierVar1"};
311 // XInitialize ------------------------------------------------------------------------------
312 // the first argument is an XMultiServiceFactory if at all
313 void SAL_CALL OleConverter::initialize( const Sequence< Any >& aArguments )
315 if( aArguments.getLength() == 1 && aArguments[0].getValueTypeClass() == TypeClass_INTERFACE)
317 Reference < XInterface > xInt;
318 aArguments[0] >>= xInt;
319 Reference <XMultiServiceFactory> xMulti( xInt, UNO_QUERY);
320 m_smgrRemote= xMulti;
324 // UnoConversionUtilities -------------------------------------------------------------------
325 Reference< XInterface > OleConverter::createUnoWrapperInstance()
327 if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
329 Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper(
330 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
331 return Reference<XInterface>( xWeak, UNO_QUERY);
333 else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
335 Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
336 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
337 return Reference<XInterface>( xWeak, UNO_QUERY);
339 else
340 return Reference<XInterface>();
343 Reference< XInterface > OleConverter::createComWrapperInstance()
345 Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper(
346 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
347 return Reference<XInterface>( xWeak, UNO_QUERY);
350 OleClient::OleClient( const Reference<XMultiServiceFactory>& smgr):
351 UnoConversionUtilities<OleClient>( smgr)
353 Reference<XInterface> xInt;// = m_smgr->createInstance(L"com.sun.star.bridge.OleBridgeSupplier2");
355 if (xInt.is())
357 Any a= xInt->queryInterface(cppu::UnoType<XBridgeSupplier2>::get() );
358 a >>= m_bridgeSupplier;
362 OleClient::~OleClient()
366 Sequence< OUString > SAL_CALL OleClient::getAvailableServiceNames()
368 Sequence< OUString > ret;
370 return ret;
373 OUString OleClient::getImplementationName()
375 return "com.sun.star.comp.ole.OleClient";
378 sal_Bool OleClient::supportsService(OUString const & ServiceName)
380 return cppu::supportsService(this, ServiceName);
383 css::uno::Sequence<OUString> OleClient::getSupportedServiceNames()
385 return css::uno::Sequence<OUString>{
386 "com.sun.star.bridge.OleObjectFactory",
387 "com.sun.star.bridge.oleautomation.Factory"};
390 Reference<XInterface> SAL_CALL OleClient::createInstance(const OUString& ServiceSpecifier)
392 Reference<XInterface> ret;
393 HRESULT result;
394 IUnknown* pUnknown = nullptr;
395 CLSID classId;
397 o2u_attachCurrentThread();
399 result = CLSIDFromProgID(
400 o3tl::toW(ServiceSpecifier.getStr()), //Pointer to the ProgID
401 &classId); //Pointer to the CLSID
404 if (result == NOERROR)
406 result = CoCreateInstance(
407 classId, //Class identifier (CLSID) of the object
408 nullptr, //Pointer to whether object is or isn't part of an aggregate
409 CLSCTX_SERVER, //Context for running executable code
410 IID_IUnknown, //Reference to the identifier of the interface
411 reinterpret_cast<void**>(&pUnknown)); //Address of output variable that receives
412 // the interface pointer requested in riid
415 if (pUnknown != nullptr)
417 Any any;
418 CComVariant variant;
420 V_VT(&variant) = VT_UNKNOWN;
421 V_UNKNOWN(&variant) = pUnknown;
422 // AddRef for Variant
423 pUnknown->AddRef();
425 // When the object is wrapped, then its refcount is increased
426 variantToAny(&variant, any);
427 if (any.getValueTypeClass() == TypeClass_INTERFACE)
429 any >>= ret;
431 pUnknown->Release(); // CoCreateInstance
434 return ret;
437 Reference<XInterface> SAL_CALL OleClient::createInstanceWithArguments(const OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/)
439 return createInstance( ServiceSpecifier);
442 // UnoConversionUtilities -----------------------------------------------------------------------------
443 Reference< XInterface > OleClient::createUnoWrapperInstance()
445 if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
447 Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper(
448 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
449 return Reference<XInterface>( xWeak, UNO_QUERY);
451 else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
453 Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
454 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
455 return Reference<XInterface>( xWeak, UNO_QUERY);
457 else
458 return Reference< XInterface>();
460 // UnoConversionUtilities -----------------------------------------------------------------------------
461 Reference< XInterface > OleClient::createComWrapperInstance( )
463 Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper(
464 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
465 return Reference<XInterface>( xWeak, UNO_QUERY);
468 OleServer::OleServer( const Reference<XMultiServiceFactory>& smgr):
469 m_smgr( smgr)
471 Reference<XInterface> xInt = m_smgr->createInstance("com.sun.star.bridge.oleautomation.BridgeSupplier");
473 if (xInt.is())
475 Any a= xInt->queryInterface( cppu::UnoType<XBridgeSupplier2>::get() );
476 a >>= m_bridgeSupplier;
479 (void) provideInstance( [&]
481 return m_smgr;
483 &OID_ServiceManager );
485 (void) provideInstance( [&]
487 // We want just one SwVbaGlobals for all Automation clients
488 static const Reference<XInterface> xWordGlobals = m_smgr->createInstance("ooo.vba.word.Globals");
489 const Reference<ooo::vba::XHelperInterface> xHelperInterface(xWordGlobals, UNO_QUERY);
490 Any aApplication = xHelperInterface->Application();
491 Reference<XInterface> xApplication;
492 aApplication >>= xApplication;
493 return xApplication;
495 &OID_LibreOfficeWriterApplication );
497 (void) provideInstance( [&]
499 // Ditto for sc
500 static const Reference<XInterface> xCalcGlobals = m_smgr->createInstance("ooo.vba.excel.Globals");
501 const Reference<ooo::vba::XHelperInterface> xHelperInterface(xCalcGlobals, UNO_QUERY);
502 Any aApplication = xHelperInterface->Application();
503 Reference<XInterface> xApplication;
504 aApplication >>= xApplication;
505 return xApplication;
507 &OID_LibreOfficeCalcApplication );
510 OleServer::~OleServer()
512 for (auto const& elem : m_wrapperList)
514 elem->deregisterClass();
515 elem->Release();
517 m_wrapperList.clear();
520 OUString OleServer::getImplementationName()
522 return "com.sun.star.comp.ole.OleServer";
525 sal_Bool OleServer::supportsService(OUString const & ServiceName)
527 return cppu::supportsService(this, ServiceName);
530 css::uno::Sequence<OUString> OleServer::getSupportedServiceNames()
532 return css::uno::Sequence<OUString>{
533 "com.sun.star.bridge.OleApplicationRegistration",
534 "com.sun.star.bridge.oleautomation.ApplicationRegistration"};
537 bool OleServer::provideInstance(std::function<const Reference<XInterface>()> xInstFunction, GUID const * guid)
539 OneInstanceOleWrapper* pWrapper = new OneInstanceOleWrapper( m_smgr, xInstFunction );
541 pWrapper->AddRef();
542 m_wrapperList.push_back(pWrapper);
544 return pWrapper->registerClass(guid);
547 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */