bump product version to 5.0.4.1
[LibreOffice.git] / extensions / source / ole / servprov.cxx
blob2467850649bef20cdcd6b93bc2c98b8b4ba0cd06
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 #ifdef __MINGW32__
23 #define INITGUID
24 #include <initguid.h>
25 #else
26 #include "ole2uno.hxx"
27 #include "unoconversionutilities.hxx"
28 #endif
29 #include "servprov.hxx"
30 #include "unoobjw.hxx"
31 #include "oleobjw.hxx"
32 #include <cppuhelper/queryinterface.hxx>
33 #include <cppuhelper/supportsservice.hxx>
35 using namespace cppu;
36 using namespace osl;
37 using namespace com::sun::star::lang;
38 using namespace com::sun::star::uno;
39 using namespace com::sun::star::bridge;
40 using namespace com::sun::star::bridge::ModelDependent;
43 namespace ole_adapter
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 /*****************************************************************************
54 class implementation ProviderOleWrapper_Impl
56 *****************************************************************************/
58 ProviderOleWrapper_Impl::ProviderOleWrapper_Impl(const Reference<XMultiServiceFactory>& smgr,
59 const Reference<XSingleServiceFactory>& xSFact, GUID* pGuid)
60 : m_xSingleServiceFactory(xSFact),
61 m_smgr( smgr)
63 m_guid = *pGuid;
65 Reference<XInterface> xInt = smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
67 if (xInt.is())
69 Any a= xInt->queryInterface( cppu::UnoType<XBridgeSupplier2>::get() );
70 a >>= m_bridgeSupplier;
75 ProviderOleWrapper_Impl::~ProviderOleWrapper_Impl()
79 sal_Bool ProviderOleWrapper_Impl::registerClass()
81 HRESULT hresult;
83 o2u_attachCurrentThread();
85 hresult = CoRegisterClassObject(
86 m_guid,
87 this,
88 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
89 REGCLS_MULTIPLEUSE,
90 &m_factoryHandle);
92 return (hresult == NOERROR);
95 sal_Bool ProviderOleWrapper_Impl::deregisterClass()
97 HRESULT hresult = CoRevokeClassObject(m_factoryHandle);
99 return (hresult == NOERROR);
102 STDMETHODIMP ProviderOleWrapper_Impl::QueryInterface(REFIID riid, void FAR* FAR* ppv)
104 if(IsEqualIID(riid, IID_IUnknown))
106 AddRef();
107 *ppv = (IUnknown*) (IClassFactory*) this;
108 return NOERROR;
110 else if (IsEqualIID(riid, IID_IClassFactory))
112 AddRef();
113 *ppv = (IClassFactory*) this;
114 return NOERROR;
117 *ppv = NULL;
118 return ResultFromScode(E_NOINTERFACE);
121 STDMETHODIMP_(ULONG) ProviderOleWrapper_Impl::AddRef()
123 return osl_atomic_increment( &m_refCount);
126 STDMETHODIMP_(ULONG) ProviderOleWrapper_Impl::Release()
128 MutexGuard aGuard( Mutex::getGlobalMutex());
129 ULONG refCount = --m_refCount;
130 if (m_refCount == 0)
132 delete this;
135 return refCount;
138 STDMETHODIMP ProviderOleWrapper_Impl::CreateInstance(IUnknown FAR* punkOuter,
139 REFIID riid,
140 void FAR* FAR* ppv)
142 HRESULT ret = ResultFromScode(E_UNEXPECTED);
143 punkOuter = NULL;
145 Reference<XInterface> xInstance;
147 if (m_xSingleServiceFactory.is())
149 xInstance = m_xSingleServiceFactory->createInstance();
151 if (xInstance.is())
153 Any usrAny(&xInstance, cppu::UnoType<decltype(xInstance)>::get());
155 sal_uInt8 arId[16];
156 rtl_getGlobalProcessId( arId );
157 Any oleAny = m_bridgeSupplier->createBridge(usrAny,
158 Sequence<sal_Int8>((sal_Int8*)arId, 16),
159 UNO,
160 OLE);
163 if (oleAny.getValueTypeClass() == cppu::UnoType<sal_uInt32>::get().getTypeClass())
165 VARIANT* pVariant = *(VARIANT**)oleAny.getValue();
167 if (pVariant->vt == VT_DISPATCH)
169 ret = pVariant->pdispVal->QueryInterface(riid, ppv);
172 VariantClear(pVariant);
173 CoTaskMemFree(pVariant);
178 return ret;
181 STDMETHODIMP ProviderOleWrapper_Impl::LockServer(int /*fLock*/)
183 return NOERROR;
186 /*****************************************************************************
188 class implementation OneInstanceOleWrapper_Impl
190 *****************************************************************************/
192 OneInstanceOleWrapper_Impl::OneInstanceOleWrapper_Impl( const Reference<XMultiServiceFactory>& smgr,
193 const Reference<XInterface>& xInst,
194 GUID* pGuid )
195 : m_xInst(xInst)
196 , m_refCount(0)
197 , m_smgr(smgr)
198 , m_factoryHandle(0)
200 m_guid = *pGuid;
202 Reference<XInterface> xInt = m_smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
204 if (xInt.is())
206 Any a= xInt->queryInterface( cppu::UnoType<XBridgeSupplier2>::get() );
207 a >>= m_bridgeSupplier;
211 OneInstanceOleWrapper_Impl::~OneInstanceOleWrapper_Impl()
215 sal_Bool OneInstanceOleWrapper_Impl::registerClass()
217 HRESULT hresult;
219 o2u_attachCurrentThread();
221 hresult = CoRegisterClassObject(
222 m_guid,
223 this,
224 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
225 REGCLS_MULTIPLEUSE,
226 &m_factoryHandle);
228 return (hresult == NOERROR);
231 sal_Bool OneInstanceOleWrapper_Impl::deregisterClass()
233 HRESULT hresult1 = NOERROR;
235 HRESULT hresult2 = CoRevokeClassObject(m_factoryHandle);
237 return (hresult1 == NOERROR && hresult2 == NOERROR);
240 STDMETHODIMP OneInstanceOleWrapper_Impl::QueryInterface(REFIID riid, void FAR* FAR* ppv)
242 if(IsEqualIID(riid, IID_IUnknown))
244 AddRef();
245 *ppv = (IUnknown*) (IClassFactory*) this;
246 return NOERROR;
248 else if (IsEqualIID(riid, IID_IClassFactory))
250 AddRef();
251 *ppv = (IClassFactory*) this;
252 return NOERROR;
255 *ppv = NULL;
256 return ResultFromScode(E_NOINTERFACE);
259 STDMETHODIMP_(ULONG) OneInstanceOleWrapper_Impl::AddRef()
261 return osl_atomic_increment( &m_refCount);
264 STDMETHODIMP_(ULONG) OneInstanceOleWrapper_Impl::Release()
266 MutexGuard oGuard( Mutex::getGlobalMutex());
267 ULONG refCount = --m_refCount;
268 if ( m_refCount == 0)
270 delete this;
273 return refCount;
276 STDMETHODIMP OneInstanceOleWrapper_Impl::CreateInstance(IUnknown FAR* punkOuter,
277 REFIID riid,
278 void FAR* FAR* ppv)
280 HRESULT ret = ResultFromScode(E_UNEXPECTED);
281 punkOuter = NULL;
283 if (m_xInst.is())
285 Any usrAny(&m_xInst, cppu::UnoType<decltype(m_xInst)>::get());
286 sal_uInt8 arId[16];
287 rtl_getGlobalProcessId( arId);
288 Any oleAny = m_bridgeSupplier->createBridge(usrAny,
289 Sequence<sal_Int8>( (sal_Int8*)arId, 16),
290 UNO,
291 OLE);
294 if (oleAny.getValueTypeClass() == TypeClass_UNSIGNED_LONG)
296 VARIANT* pVariant = *(VARIANT**)oleAny.getValue();
298 if ((pVariant->vt == VT_UNKNOWN) || (pVariant->vt == VT_DISPATCH))
300 ret = pVariant->punkVal->QueryInterface(riid, ppv);
303 VariantClear(pVariant);
304 CoTaskMemFree(pVariant);
308 return ret;
311 STDMETHODIMP OneInstanceOleWrapper_Impl::LockServer(int /*fLock*/)
313 return NOERROR;
317 /*****************************************************************************
319 class implementation OleConverter_Impl2
321 *****************************************************************************/
323 OleConverter_Impl2::OleConverter_Impl2( const Reference<XMultiServiceFactory> &smgr):
324 UnoConversionUtilities<OleConverter_Impl2>( smgr)
329 // The XMultiServiceFactory is later set by XInitialization
330 OleConverter_Impl2::OleConverter_Impl2( const Reference<XMultiServiceFactory>& smgr, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass ):
331 UnoConversionUtilities<OleConverter_Impl2>( smgr, unoWrapperClass, comWrapperClass )
336 OleConverter_Impl2::~OleConverter_Impl2()
340 // XBridgeSupplier --------------------------------------------------------------
341 Any SAL_CALL OleConverter_Impl2::createBridge(const Any& modelDepObject,
342 const Sequence< sal_Int8 >& ProcessId,
343 sal_Int16 sourceModelType,
344 sal_Int16 destModelType)
345 throw (IllegalArgumentException,
346 RuntimeException )
348 Any ret;
349 sal_uInt8 arId[16];
350 rtl_getGlobalProcessId( arId );
352 Sequence< sal_Int8 > seqProcessId( (sal_Int8*)arId, 16);
354 if ( seqProcessId == ProcessId)
356 if (sourceModelType == UNO)
358 if (destModelType == UNO)
360 // same model -> copy value only
361 ret = modelDepObject;
363 else if (destModelType == OLE)
365 // convert UNO any into variant
366 VARIANT* pVariant = (VARIANT*) CoTaskMemAlloc(sizeof(VARIANT));
367 VariantInit( pVariant);
370 anyToVariant( pVariant, modelDepObject);
372 catch(...)
374 CoTaskMemFree(pVariant);
375 throw IllegalArgumentException();
377 ret.setValue((void*) &pVariant, cppu::UnoType<sal_uInt32>::get());
379 else
380 throw IllegalArgumentException();
382 else if (sourceModelType == OLE)
384 if (modelDepObject.getValueType() != cppu::UnoType<sal_uInt32>::get())
386 throw IllegalArgumentException();
388 else if (destModelType == OLE)
390 // same model -> copy value only
391 VARIANT* pVariant = (VARIANT*) CoTaskMemAlloc(sizeof(VARIANT));
393 if (NOERROR != VariantCopy(pVariant, *(VARIANT**)modelDepObject.getValue()))
395 CoTaskMemFree(pVariant);
396 throw(IllegalArgumentException());
398 else
400 ret.setValue((void*) &pVariant, cppu::UnoType<sal_uInt32>::get());
403 else if (destModelType == UNO)
405 // convert variant into UNO any
406 VARIANT* pVariant = *(VARIANT**)modelDepObject.getValue();
409 variantToAny(pVariant, ret);
411 catch (const CannotConvertException & e)
413 throw IllegalArgumentException(
414 e.Message, 0, -1);
417 else
418 throw IllegalArgumentException();
421 else
422 throw IllegalArgumentException();
425 return ret;
428 OUString OleConverter_Impl2::getImplementationName()
429 throw (css::uno::RuntimeException, std::exception)
431 return m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL
432 ? OUString("com.sun.star.comp.ole.OleConverter2")
433 : OUString("com.sun.star.comp.ole.OleConverterVar1");
436 sal_Bool OleConverter_Impl2::supportsService(OUString const & ServiceName)
437 throw (css::uno::RuntimeException, std::exception)
439 return cppu::supportsService(this, ServiceName);
442 css::uno::Sequence<OUString> OleConverter_Impl2::getSupportedServiceNames()
443 throw (css::uno::RuntimeException, std::exception)
445 return m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL
446 ? css::uno::Sequence<OUString>{
447 "com.sun.star.bridge.OleBridgeSupplier2",
448 "com.sun.star.bridge.oleautomation.BridgeSupplier"}
449 : css::uno::Sequence<OUString>{
450 "com.sun.star.bridge.OleBridgeSupplierVar1"};
453 // XInitialize ------------------------------------------------------------------------------
454 // the first argument is an XMultiServiceFactory if at all
455 void SAL_CALL OleConverter_Impl2::initialize( const Sequence< Any >& aArguments )
456 throw(Exception, RuntimeException)
458 if( aArguments.getLength() == 1 && aArguments[0].getValueTypeClass() == TypeClass_INTERFACE)
460 Reference < XInterface > xInt;
461 aArguments[0] >>= xInt;
462 Reference <XMultiServiceFactory> xMulti( xInt, UNO_QUERY);
463 m_smgrRemote= xMulti;
467 // UnoConversionUtilities -------------------------------------------------------------------
468 Reference< XInterface > OleConverter_Impl2::createUnoWrapperInstance()
470 if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
472 Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
473 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
474 return Reference<XInterface>( xWeak, UNO_QUERY);
476 else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
478 Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
479 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
480 return Reference<XInterface>( xWeak, UNO_QUERY);
482 else
483 return Reference<XInterface>();
486 Reference< XInterface > OleConverter_Impl2::createComWrapperInstance()
488 Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
489 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
490 return Reference<XInterface>( xWeak, UNO_QUERY);
495 /*****************************************************************************
497 class implementation OleClient_Impl
499 *****************************************************************************/
501 OleClient_Impl::OleClient_Impl( const Reference<XMultiServiceFactory>& smgr):
502 UnoConversionUtilities<OleClient_Impl>( smgr)
504 Reference<XInterface> xInt;// = m_smgr->createInstance(L"com.sun.star.bridge.OleBridgeSupplier2");
506 if (xInt.is())
508 Any a= xInt->queryInterface(cppu::UnoType<XBridgeSupplier2>::get() );
509 a >>= m_bridgeSupplier;
513 OleClient_Impl::~OleClient_Impl()
517 Sequence< OUString > SAL_CALL OleClient_Impl::getAvailableServiceNames() throw( RuntimeException )
519 Sequence< OUString > ret;
521 return ret;
524 OUString OleClient_Impl::getImplementationName()
525 throw (css::uno::RuntimeException, std::exception)
527 return OUString("com.sun.star.comp.ole.OleClient");
530 sal_Bool OleClient_Impl::supportsService(OUString const & ServiceName)
531 throw (css::uno::RuntimeException, std::exception)
533 return cppu::supportsService(this, ServiceName);
536 css::uno::Sequence<OUString> OleClient_Impl::getSupportedServiceNames()
537 throw (css::uno::RuntimeException, std::exception)
539 return css::uno::Sequence<OUString>{
540 "com.sun.star.bridge.OleObjectFactory",
541 "com.sun.star.bridge.oleautomation.Factory"};
544 Reference<XInterface> SAL_CALL OleClient_Impl::createInstance(const OUString& ServiceSpecifier) throw (Exception, RuntimeException )
546 Reference<XInterface> ret;
547 HRESULT result;
548 IUnknown* pUnknown = NULL;
549 CLSID classId;
551 o2u_attachCurrentThread();
553 result = CLSIDFromProgID(
554 reinterpret_cast<LPCWSTR>(ServiceSpecifier.getStr()), //Pointer to the ProgID
555 &classId); //Pointer to the CLSID
558 if (result == NOERROR)
560 result = CoCreateInstance(
561 classId, //Class identifier (CLSID) of the object
562 NULL, //Pointer to whether object is or isn't part of an aggregate
563 CLSCTX_SERVER, //Context for running executable code
564 IID_IUnknown, //Reference to the identifier of the interface
565 (void**)&pUnknown); //Address of output variable that receives
566 // the interface pointer requested in riid
569 if (pUnknown != NULL)
571 Any any;
572 CComVariant variant;
574 V_VT(&variant) = VT_UNKNOWN;
575 V_UNKNOWN(&variant) = pUnknown;
576 // AddRef for Variant
577 pUnknown->AddRef();
579 // When the object is wrapped, then its refcount is increased
580 variantToAny(&variant, any);
581 if (any.getValueTypeClass() == TypeClass_INTERFACE)
583 any >>= ret;
585 pUnknown->Release(); // CoCreateInstance
588 return ret;
591 Reference<XInterface> SAL_CALL OleClient_Impl::createInstanceWithArguments(const OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/) throw (Exception, RuntimeException)
593 return createInstance( ServiceSpecifier);
596 // UnoConversionUtilities -----------------------------------------------------------------------------
597 Reference< XInterface > OleClient_Impl::createUnoWrapperInstance()
599 if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
601 Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
602 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
603 return Reference<XInterface>( xWeak, UNO_QUERY);
605 else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
607 Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
608 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
609 return Reference<XInterface>( xWeak, UNO_QUERY);
611 else
612 return Reference< XInterface>();
614 // UnoConversionUtilities -----------------------------------------------------------------------------
615 Reference< XInterface > OleClient_Impl::createComWrapperInstance( )
617 Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
618 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
619 return Reference<XInterface>( xWeak, UNO_QUERY);
624 /*****************************************************************************
626 class implementation OleServer_Impl
628 *****************************************************************************/
630 OleServer_Impl::OleServer_Impl( const Reference<XMultiServiceFactory>& smgr):
631 m_smgr( smgr)
633 Reference<XInterface> xInt = m_smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
635 if (xInt.is())
637 Any a= xInt->queryInterface( cppu::UnoType<XBridgeSupplier2>::get() );
638 a >>= m_bridgeSupplier;
641 sal_Bool ret = provideInstance( m_smgr, (GUID*)&OID_ServiceManager );
642 (void)ret;
645 OleServer_Impl::~OleServer_Impl()
647 while (!m_wrapperList.empty())
649 (*m_wrapperList.begin())->deregisterClass();
650 (*m_wrapperList.begin())->Release();
651 m_wrapperList.pop_front();
655 OUString OleServer_Impl::getImplementationName()
656 throw (css::uno::RuntimeException, std::exception)
658 return OUString("com.sun.star.comp.ole.OleServer");
661 sal_Bool OleServer_Impl::supportsService(OUString const & ServiceName)
662 throw (css::uno::RuntimeException, std::exception)
664 return cppu::supportsService(this, ServiceName);
667 css::uno::Sequence<OUString> OleServer_Impl::getSupportedServiceNames()
668 throw (css::uno::RuntimeException, std::exception)
670 return css::uno::Sequence<OUString>{
671 "com.sun.star.bridge.OleApplicationRegistration",
672 "com.sun.star.bridge.oleautomation.ApplicationRegistration"};
675 sal_Bool OleServer_Impl::provideService(const Reference<XSingleServiceFactory>& xSFact, GUID* guid)
677 IClassFactoryWrapper* pFac = new ProviderOleWrapper_Impl( m_smgr, xSFact, guid);
679 pFac->AddRef();
681 m_wrapperList.push_back(pFac);
683 return pFac->registerClass();
686 sal_Bool OleServer_Impl::provideInstance(const Reference<XInterface>& xInst, GUID* guid)
688 IClassFactoryWrapper* pFac =
689 new OneInstanceOleWrapper_Impl( m_smgr, xInst, guid );
691 pFac->AddRef();
692 m_wrapperList.push_back(pFac);
694 return pFac->registerClass();
699 } // end namespace
701 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */