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 .
26 #include "ole2uno.hxx"
27 #include "unoconversionutilities.hxx"
29 #include "servprov.hxx"
30 #include "unoobjw.hxx"
31 #include "oleobjw.hxx"
32 #include <cppuhelper/queryinterface.hxx>
33 #include <cppuhelper/supportsservice.hxx>
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
;
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
),
65 Reference
<XInterface
> xInt
= smgr
->createInstance(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.bridge.oleautomation.BridgeSupplier"));
69 Any a
= xInt
->queryInterface( cppu::UnoType
<XBridgeSupplier2
>::get() );
70 a
>>= m_bridgeSupplier
;
75 ProviderOleWrapper_Impl::~ProviderOleWrapper_Impl()
79 sal_Bool
ProviderOleWrapper_Impl::registerClass()
83 o2u_attachCurrentThread();
85 hresult
= CoRegisterClassObject(
88 CLSCTX_INPROC_SERVER
| CLSCTX_LOCAL_SERVER
,
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
))
107 *ppv
= (IUnknown
*) (IClassFactory
*) this;
110 else if (IsEqualIID(riid
, IID_IClassFactory
))
113 *ppv
= (IClassFactory
*) this;
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
;
138 STDMETHODIMP
ProviderOleWrapper_Impl::CreateInstance(IUnknown FAR
* punkOuter
,
142 HRESULT ret
= ResultFromScode(E_UNEXPECTED
);
145 Reference
<XInterface
> xInstance
;
147 if (m_xSingleServiceFactory
.is())
149 xInstance
= m_xSingleServiceFactory
->createInstance();
153 Any
usrAny(&xInstance
, cppu::UnoType
<decltype(xInstance
)>::get());
156 rtl_getGlobalProcessId( arId
);
157 Any oleAny
= m_bridgeSupplier
->createBridge(usrAny
,
158 Sequence
<sal_Int8
>((sal_Int8
*)arId
, 16),
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
);
181 STDMETHODIMP
ProviderOleWrapper_Impl::LockServer(int /*fLock*/)
186 /*****************************************************************************
188 class implementation OneInstanceOleWrapper_Impl
190 *****************************************************************************/
192 OneInstanceOleWrapper_Impl::OneInstanceOleWrapper_Impl( const Reference
<XMultiServiceFactory
>& smgr
,
193 const Reference
<XInterface
>& xInst
,
202 Reference
<XInterface
> xInt
= m_smgr
->createInstance(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.bridge.oleautomation.BridgeSupplier"));
206 Any a
= xInt
->queryInterface( cppu::UnoType
<XBridgeSupplier2
>::get() );
207 a
>>= m_bridgeSupplier
;
211 OneInstanceOleWrapper_Impl::~OneInstanceOleWrapper_Impl()
215 sal_Bool
OneInstanceOleWrapper_Impl::registerClass()
219 o2u_attachCurrentThread();
221 hresult
= CoRegisterClassObject(
224 CLSCTX_INPROC_SERVER
| CLSCTX_LOCAL_SERVER
,
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
))
245 *ppv
= (IUnknown
*) (IClassFactory
*) this;
248 else if (IsEqualIID(riid
, IID_IClassFactory
))
251 *ppv
= (IClassFactory
*) this;
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)
276 STDMETHODIMP
OneInstanceOleWrapper_Impl::CreateInstance(IUnknown FAR
* punkOuter
,
280 HRESULT ret
= ResultFromScode(E_UNEXPECTED
);
285 Any
usrAny(&m_xInst
, cppu::UnoType
<decltype(m_xInst
)>::get());
287 rtl_getGlobalProcessId( arId
);
288 Any oleAny
= m_bridgeSupplier
->createBridge(usrAny
,
289 Sequence
<sal_Int8
>( (sal_Int8
*)arId
, 16),
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
);
311 STDMETHODIMP
OneInstanceOleWrapper_Impl::LockServer(int /*fLock*/)
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
,
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
);
374 CoTaskMemFree(pVariant
);
375 throw IllegalArgumentException();
377 ret
.setValue((void*) &pVariant
, cppu::UnoType
<sal_uInt32
>::get());
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());
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(
418 throw IllegalArgumentException();
422 throw IllegalArgumentException();
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
);
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");
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
;
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
;
548 IUnknown
* pUnknown
= NULL
;
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
)
574 V_VT(&variant
) = VT_UNKNOWN
;
575 V_UNKNOWN(&variant
) = pUnknown
;
576 // AddRef for Variant
579 // When the object is wrapped, then its refcount is increased
580 variantToAny(&variant
, any
);
581 if (any
.getValueTypeClass() == TypeClass_INTERFACE
)
585 pUnknown
->Release(); // CoCreateInstance
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
);
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
):
633 Reference
<XInterface
> xInt
= m_smgr
->createInstance(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.bridge.oleautomation.BridgeSupplier"));
637 Any a
= xInt
->queryInterface( cppu::UnoType
<XBridgeSupplier2
>::get() );
638 a
>>= m_bridgeSupplier
;
641 sal_Bool ret
= provideInstance( m_smgr
, (GUID
*)&OID_ServiceManager
);
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
);
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
);
692 m_wrapperList
.push_back(pFac
);
694 return pFac
->registerClass();
701 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */