1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
35 #include "ole2uno.hxx"
36 #include "unoconversionutilities.hxx"
38 #include "servprov.hxx"
39 #include "unoobjw.hxx"
40 #include "oleobjw.hxx"
41 #include <rtl/unload.h>
43 #include <tools/presys.h>
44 #define _WIN32_WINNT 0x0400
46 #if defined(_MSC_VER) && (_MSC_VER >= 1300)
50 extern CComModule _Module
;
52 #include <tools/postsys.h>
59 using namespace com::sun::star::lang
;
60 using namespace com::sun::star::uno
;
61 using namespace com::sun::star::bridge
;
62 using namespace com::sun::star::bridge::ModelDependent
;
70 // prior 5.2 ( src569 ver m)
71 // {3ECF78F0-B149-11D2-8EBE-00105AD848AF}
72 //DEFINE_GUID(OID_ServiceManager, 0x3ECF78F0, 0xB149, 0x11d2, 0x8E, 0xBE, 0x00, 0x10, 0x5A, 0xD8, 0x48, 0xAF);
75 // GUID used since 5.2 ( src569 m)
76 // {82154420-0FBF-11d4-8313-005004526AB4}
77 DEFINE_GUID(OID_ServiceManager
, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
80 // {D9BB9D1D-BFA9-4357-9F11-9A2E9061F06E}
81 DEFINE_GUID(OID_ServiceManager
, 0xd9bb9d1d, 0xbfa9, 0x4357, 0x9f, 0x11, 0x9a, 0x2e, 0x90, 0x61, 0xf0, 0x6e);
84 extern rtl_StandardModuleCount globalModuleCount
;
86 /*****************************************************************************
88 class implementation ProviderOleWrapper_Impl
90 *****************************************************************************/
92 ProviderOleWrapper_Impl::ProviderOleWrapper_Impl(const Reference
<XMultiServiceFactory
>& smgr
,
93 const Reference
<XSingleServiceFactory
>& xSFact
, GUID
* pGuid
)
94 : m_xSingleServiceFactory(xSFact
),
99 Reference
<XInterface
> xInt
= smgr
->createInstance(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.bridge.oleautomation.BridgeSupplier"));
103 Any a
= xInt
->queryInterface( ::getCppuType( reinterpret_cast<
104 Reference
< XBridgeSupplier2
>* >(0)));
105 a
>>= m_bridgeSupplier
;
110 ProviderOleWrapper_Impl::~ProviderOleWrapper_Impl()
114 sal_Bool
ProviderOleWrapper_Impl::registerClass()
118 o2u_attachCurrentThread();
120 hresult
= CoRegisterClassObject(
123 CLSCTX_INPROC_SERVER
| CLSCTX_LOCAL_SERVER
,
127 return (hresult
== NOERROR
);
130 sal_Bool
ProviderOleWrapper_Impl::deregisterClass()
132 HRESULT hresult
= CoRevokeClassObject(m_factoryHandle
);
134 return (hresult
== NOERROR
);
137 STDMETHODIMP
ProviderOleWrapper_Impl::QueryInterface(REFIID riid
, void FAR
* FAR
* ppv
)
139 if(IsEqualIID(riid
, IID_IUnknown
))
142 *ppv
= (IUnknown
*) (IClassFactory
*) this;
145 else if (IsEqualIID(riid
, IID_IClassFactory
))
148 *ppv
= (IClassFactory
*) this;
153 return ResultFromScode(E_NOINTERFACE
);
156 STDMETHODIMP_(ULONG
) ProviderOleWrapper_Impl::AddRef()
158 return osl_incrementInterlockedCount( &m_refCount
);
161 STDMETHODIMP_(ULONG
) ProviderOleWrapper_Impl::Release()
163 MutexGuard
aGuard( Mutex::getGlobalMutex());
164 ULONG refCount
= --m_refCount
;
173 STDMETHODIMP
ProviderOleWrapper_Impl::CreateInstance(IUnknown FAR
* punkOuter
,
177 HRESULT ret
= ResultFromScode(E_UNEXPECTED
);
180 Reference
<XInterface
> xInstance
;
182 if (m_xSingleServiceFactory
.is())
184 xInstance
= m_xSingleServiceFactory
->createInstance();
188 Any
usrAny(&xInstance
, getCppuType( & xInstance
));
191 rtl_getGlobalProcessId( arId
);
192 Any oleAny
= m_bridgeSupplier
->createBridge(usrAny
,
193 Sequence
<sal_Int8
>((sal_Int8
*)arId
, 16),
198 if (oleAny
.getValueTypeClass() == getCppuType( (sal_uInt32
*)0).getTypeClass())
200 VARIANT
* pVariant
= *(VARIANT
**)oleAny
.getValue();
202 if (pVariant
->vt
== VT_DISPATCH
)
204 ret
= pVariant
->pdispVal
->QueryInterface(riid
, ppv
);
207 VariantClear(pVariant
);
208 CoTaskMemFree(pVariant
);
216 STDMETHODIMP
ProviderOleWrapper_Impl::LockServer(int /*fLock*/)
221 /*****************************************************************************
223 class implementation OneInstanceOleWrapper_Impl
225 *****************************************************************************/
227 OneInstanceOleWrapper_Impl::OneInstanceOleWrapper_Impl( const Reference
<XMultiServiceFactory
>& smgr
,
228 const Reference
<XInterface
>& xInst
,
230 sal_Bool bAsApplication
)
231 : m_xInst(xInst
), m_refCount(0),
233 m_factoryHandle( 0 ),
234 m_bAsApplication( bAsApplication
),
235 m_nApplRegHandle( 0 )
239 Reference
<XInterface
> xInt
= m_smgr
->createInstance(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.bridge.oleautomation.BridgeSupplier"));
243 Any a
= xInt
->queryInterface( getCppuType(
244 reinterpret_cast< Reference
<XBridgeSupplier2
>*>(0)));
245 a
>>= m_bridgeSupplier
;
249 OneInstanceOleWrapper_Impl::~OneInstanceOleWrapper_Impl()
253 sal_Bool
OneInstanceOleWrapper_Impl::registerClass()
257 o2u_attachCurrentThread();
259 hresult
= CoRegisterClassObject(
262 CLSCTX_INPROC_SERVER
| CLSCTX_LOCAL_SERVER
,
266 if ( hresult
== NOERROR
&& m_bAsApplication
)
267 hresult
= RegisterActiveObject( this, m_guid
, ACTIVEOBJECT_WEAK
, &m_nApplRegHandle
);
269 return (hresult
== NOERROR
);
272 sal_Bool
OneInstanceOleWrapper_Impl::deregisterClass()
274 HRESULT hresult1
= NOERROR
;
275 if ( m_bAsApplication
)
276 hresult1
= RevokeActiveObject( m_nApplRegHandle
, NULL
);
278 HRESULT hresult2
= CoRevokeClassObject(m_factoryHandle
);
280 return (hresult1
== NOERROR
&& hresult2
== NOERROR
);
283 STDMETHODIMP
OneInstanceOleWrapper_Impl::QueryInterface(REFIID riid
, void FAR
* FAR
* ppv
)
285 if(IsEqualIID(riid
, IID_IUnknown
))
288 *ppv
= (IUnknown
*) (IClassFactory
*) this;
291 else if (IsEqualIID(riid
, IID_IClassFactory
))
294 *ppv
= (IClassFactory
*) this;
299 return ResultFromScode(E_NOINTERFACE
);
302 STDMETHODIMP_(ULONG
) OneInstanceOleWrapper_Impl::AddRef()
304 return osl_incrementInterlockedCount( &m_refCount
);
307 STDMETHODIMP_(ULONG
) OneInstanceOleWrapper_Impl::Release()
309 MutexGuard
oGuard( Mutex::getGlobalMutex());
310 ULONG refCount
= --m_refCount
;
311 if ( m_refCount
== 0)
319 STDMETHODIMP
OneInstanceOleWrapper_Impl::CreateInstance(IUnknown FAR
* punkOuter
,
323 HRESULT ret
= ResultFromScode(E_UNEXPECTED
);
328 Any
usrAny(&m_xInst
, getCppuType( &m_xInst
));
330 rtl_getGlobalProcessId( arId
);
331 Any oleAny
= m_bridgeSupplier
->createBridge(usrAny
,
332 Sequence
<sal_Int8
>( (sal_Int8
*)arId
, 16),
337 if (oleAny
.getValueTypeClass() == TypeClass_UNSIGNED_LONG
)
339 VARIANT
* pVariant
= *(VARIANT
**)oleAny
.getValue();
341 if ((pVariant
->vt
== VT_UNKNOWN
) || (pVariant
->vt
== VT_DISPATCH
))
343 ret
= pVariant
->punkVal
->QueryInterface(riid
, ppv
);
346 VariantClear(pVariant
);
347 CoTaskMemFree(pVariant
);
354 STDMETHODIMP
OneInstanceOleWrapper_Impl::LockServer(int /*fLock*/)
360 /*****************************************************************************
362 class implementation OleConverter_Impl2
364 *****************************************************************************/
366 OleConverter_Impl2::OleConverter_Impl2( const Reference
<XMultiServiceFactory
> &smgr
):
367 UnoConversionUtilities
<OleConverter_Impl2
>( smgr
)
370 // library unloading support
371 globalModuleCount
.modCnt
.acquire( &globalModuleCount
.modCnt
);
374 // The XMultiServiceFactory is later set by XInitialization
375 OleConverter_Impl2::OleConverter_Impl2( const Reference
<XMultiServiceFactory
>& smgr
, sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
376 UnoConversionUtilities
<OleConverter_Impl2
>( smgr
, unoWrapperClass
, comWrapperClass
)
379 //library unloading support
380 globalModuleCount
.modCnt
.acquire( &globalModuleCount
.modCnt
);
383 OleConverter_Impl2::~OleConverter_Impl2()
385 globalModuleCount
.modCnt
.release( &globalModuleCount
.modCnt
);
388 // XBridgeSupplier --------------------------------------------------------------
389 Any SAL_CALL
OleConverter_Impl2::createBridge(const Any
& modelDepObject
,
390 const Sequence
< sal_Int8
>& ProcessId
,
391 sal_Int16 sourceModelType
,
392 sal_Int16 destModelType
)
393 throw (IllegalArgumentException
,
398 rtl_getGlobalProcessId( arId
);
400 Sequence
< sal_Int8
> seqProcessId( (sal_Int8
*)arId
, 16);
402 if ( seqProcessId
== ProcessId
)
404 if (sourceModelType
== UNO
)
406 if (destModelType
== UNO
)
408 // same model -> copy value only
409 ret
= modelDepObject
;
411 else if (destModelType
== OLE
)
413 // convert UNO any into variant
414 VARIANT
* pVariant
= (VARIANT
*) CoTaskMemAlloc(sizeof(VARIANT
));
415 VariantInit( pVariant
);
418 anyToVariant( pVariant
, modelDepObject
);
422 CoTaskMemFree(pVariant
);
423 throw IllegalArgumentException();
425 ret
.setValue((void*) &pVariant
, getCppuType((sal_uInt32
*)0));
428 throw IllegalArgumentException();
430 else if (sourceModelType
== OLE
)
432 if (modelDepObject
.getValueType() != getCppuType((sal_uInt32
*)0))
434 throw IllegalArgumentException();
436 else if (destModelType
== OLE
)
438 // same model -> copy value only
439 VARIANT
* pVariant
= (VARIANT
*) CoTaskMemAlloc(sizeof(VARIANT
));
441 if (NOERROR
!= VariantCopy(pVariant
, *(VARIANT
**)modelDepObject
.getValue()))
443 CoTaskMemFree(pVariant
);
444 throw(IllegalArgumentException());
448 ret
.setValue((void*) &pVariant
, getCppuType((sal_uInt32
*)0));
451 else if (destModelType
== UNO
)
453 // convert variant into UNO any
454 VARIANT
* pVariant
= *(VARIANT
**)modelDepObject
.getValue();
457 variantToAny(pVariant
, ret
);
459 catch (CannotConvertException
& e
)
461 throw IllegalArgumentException(
466 throw IllegalArgumentException();
470 throw IllegalArgumentException();
477 // XInitialize ------------------------------------------------------------------------------
478 // the first argument is an XMultiServiceFactory if at all
479 void SAL_CALL
OleConverter_Impl2::initialize( const Sequence
< Any
>& aArguments
)
480 throw(Exception
, RuntimeException
)
482 if( aArguments
.getLength() == 1 && aArguments
[0].getValueTypeClass() == TypeClass_INTERFACE
)
484 Reference
< XInterface
> xInt
;
485 aArguments
[0] >>= xInt
;
486 Reference
<XMultiServiceFactory
> xMulti( xInt
, UNO_QUERY
);
487 m_smgrRemote
= xMulti
;
491 // UnoConversionUtilities -------------------------------------------------------------------
492 Reference
< XInterface
> OleConverter_Impl2::createUnoWrapperInstance()
494 if( m_nUnoWrapperClass
== INTERFACE_OLE_WRAPPER_IMPL
)
496 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper_Impl(
497 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
498 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
500 else if( m_nUnoWrapperClass
== UNO_OBJECT_WRAPPER_REMOTE_OPT
)
502 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
503 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
504 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
507 return Reference
<XInterface
>();
510 Reference
< XInterface
> OleConverter_Impl2::createComWrapperInstance()
512 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper_Impl(
513 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
514 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
519 /*****************************************************************************
521 class implementation OleClient_Impl
523 *****************************************************************************/
525 OleClient_Impl::OleClient_Impl( const Reference
<XMultiServiceFactory
>& smgr
):
526 UnoConversionUtilities
<OleClient_Impl
>( smgr
)
528 // library unloading support
529 globalModuleCount
.modCnt
.acquire( &globalModuleCount
.modCnt
);
530 Reference
<XInterface
> xInt
;// = m_smgr->createInstance(L"com.sun.star.bridge.OleBridgeSupplier2");
534 Any a
= xInt
->queryInterface(getCppuType(
535 reinterpret_cast<Reference
<XBridgeSupplier2
>*>(0)));
536 a
>>= m_bridgeSupplier
;
540 OleClient_Impl::~OleClient_Impl()
542 // library unloading support
543 globalModuleCount
.modCnt
.release( &globalModuleCount
.modCnt
);
546 Sequence
< OUString
> SAL_CALL
OleClient_Impl::getAvailableServiceNames() throw( RuntimeException
)
548 Sequence
< OUString
> ret
;
554 OUString
OleClient_Impl::getImplementationName()
556 return OUString(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.comp.ole.OleClient"));
559 Reference
<XInterface
> SAL_CALL
OleClient_Impl::createInstance(const OUString
& ServiceSpecifier
) throw (Exception
, RuntimeException
)
561 Reference
<XInterface
> ret
;
563 IUnknown
* pUnknown
= NULL
;
566 o2u_attachCurrentThread();
568 result
= CLSIDFromProgID(
569 reinterpret_cast<LPCWSTR
>(ServiceSpecifier
.getStr()), //Pointer to the ProgID
570 &classId
); //Pointer to the CLSID
573 if (result
== NOERROR
)
575 result
= CoCreateInstance(
576 classId
, //Class identifier (CLSID) of the object
577 NULL
, //Pointer to whether object is or isn't part of an aggregate
578 CLSCTX_SERVER
, //Context for running executable code
579 IID_IUnknown
, //Reference to the identifier of the interface
580 (void**)&pUnknown
); //Address of output variable that receives
581 // the interface pointer requested in riid
584 if (pUnknown
!= NULL
)
589 V_VT(&variant
) = VT_UNKNOWN
;
590 V_UNKNOWN(&variant
) = pUnknown
;
591 // AddRef for Variant
594 // When the object is wrapped, then its refcount is increased
595 variantToAny(&variant
, any
);
596 if (any
.getValueTypeClass() == TypeClass_INTERFACE
)
600 pUnknown
->Release(); // CoCreateInstance
606 Reference
<XInterface
> SAL_CALL
OleClient_Impl::createInstanceWithArguments(const OUString
& ServiceSpecifier
, const Sequence
< Any
>& /*Arguments*/) throw (Exception
, RuntimeException
)
608 return createInstance( ServiceSpecifier
);
611 // UnoConversionUtilities -----------------------------------------------------------------------------
612 Reference
< XInterface
> OleClient_Impl::createUnoWrapperInstance()
614 if( m_nUnoWrapperClass
== INTERFACE_OLE_WRAPPER_IMPL
)
616 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper_Impl(
617 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
618 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
620 else if( m_nUnoWrapperClass
== UNO_OBJECT_WRAPPER_REMOTE_OPT
)
622 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
623 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
624 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
627 return Reference
< XInterface
>();
629 // UnoConversionUtilities -----------------------------------------------------------------------------
630 Reference
< XInterface
> OleClient_Impl::createComWrapperInstance( )
632 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper_Impl(
633 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
634 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
639 /*****************************************************************************
641 class implementation OleServer_Impl
643 *****************************************************************************/
645 OleServer_Impl::OleServer_Impl( const Reference
<XMultiServiceFactory
>& smgr
):
648 //library unloading support
649 globalModuleCount
.modCnt
.acquire( &globalModuleCount
.modCnt
);
650 Reference
<XInterface
> xInt
= m_smgr
->createInstance(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.bridge.oleautomation.BridgeSupplier"));
654 Any a
= xInt
->queryInterface( getCppuType(
655 reinterpret_cast< Reference
<XBridgeSupplier2
>*>(0)));
656 a
>>= m_bridgeSupplier
;
660 sal_Bool bOLERegister
= sal_False
;
662 sal_Bool bOLERegister
= sal_True
;
664 sal_Bool ret
= provideInstance( m_smgr
, (GUID
*)&OID_ServiceManager
, bOLERegister
);
668 OleServer_Impl::~OleServer_Impl()
670 while (!m_wrapperList
.empty())
672 (*m_wrapperList
.begin())->deregisterClass();
673 (*m_wrapperList
.begin())->Release();
674 m_wrapperList
.pop_front();
676 //library unloading support
677 globalModuleCount
.modCnt
.release( &globalModuleCount
.modCnt
);
679 // XInterface --------------------------------------------------
680 Any SAL_CALL
OleServer_Impl::queryInterface( const Type
& aType
) throw(RuntimeException
)
682 Any a
= ::cppu::queryInterface( aType
, static_cast<XTypeProvider
*>(this));
684 return OWeakObject::queryInterface( aType
);
688 void SAL_CALL
OleServer_Impl::acquire( ) throw()
690 OWeakObject::acquire();
692 void SAL_CALL
OleServer_Impl::release( ) throw ()
694 OWeakObject::release();
698 // XTypeProvider --------------------------------------------------
699 Sequence
< Type
> SAL_CALL
OleServer_Impl::getTypes( ) throw(RuntimeException
)
701 static OTypeCollection
*pCollection
= 0;
704 MutexGuard
guard( Mutex::getGlobalMutex() );
707 static OTypeCollection
collection(
708 getCppuType(reinterpret_cast< Reference
< XWeak
>*>(0)),
709 getCppuType(reinterpret_cast< Reference
< XTypeProvider
>*>(0)) );
710 pCollection
= &collection
;
713 return (*pCollection
).getTypes();
715 Sequence
< sal_Int8
> SAL_CALL
OleServer_Impl::getImplementationId() throw(RuntimeException
)
717 static OImplementationId
*pId
= 0;
720 MutexGuard
guard( Mutex::getGlobalMutex() );
723 static OImplementationId
id( sal_False
);
727 return (*pId
).getImplementationId();
731 sal_Bool
OleServer_Impl::provideService(const Reference
<XSingleServiceFactory
>& xSFact
, GUID
* guid
)
733 IClassFactoryWrapper
* pFac
= new ProviderOleWrapper_Impl( m_smgr
, xSFact
, guid
);
737 m_wrapperList
.push_back(pFac
);
739 return pFac
->registerClass();
742 sal_Bool
OleServer_Impl::provideInstance(const Reference
<XInterface
>& xInst
, GUID
* guid
, sal_Bool bAsApplication
)
744 IClassFactoryWrapper
* pFac
= new OneInstanceOleWrapper_Impl( m_smgr
, xInst
, guid
, bAsApplication
);
747 m_wrapperList
.push_back(pFac
);
749 return pFac
->registerClass();