1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: servprov.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
38 #include "ole2uno.hxx"
39 #include "unoconversionutilities.hxx"
41 #include "servprov.hxx"
42 #include "unoobjw.hxx"
43 #include "oleobjw.hxx"
44 #include <rtl/unload.h>
46 #include <tools/presys.h>
47 #define _WIN32_WINNT 0x0400
49 #if defined(_MSC_VER) && (_MSC_VER >= 1300)
53 extern CComModule _Module
;
55 #include <tools/postsys.h>
62 using namespace com::sun::star::lang
;
63 using namespace com::sun::star::uno
;
64 using namespace com::sun::star::bridge
;
65 using namespace com::sun::star::bridge::ModelDependent
;
73 // prior 5.2 ( src569 ver m)
74 // {3ECF78F0-B149-11D2-8EBE-00105AD848AF}
75 //DEFINE_GUID(OID_ServiceManager, 0x3ECF78F0, 0xB149, 0x11d2, 0x8E, 0xBE, 0x00, 0x10, 0x5A, 0xD8, 0x48, 0xAF);
78 // GUID used since 5.2 ( src569 m)
79 // {82154420-0FBF-11d4-8313-005004526AB4}
80 DEFINE_GUID(OID_ServiceManager
, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
83 // {D9BB9D1D-BFA9-4357-9F11-9A2E9061F06E}
84 DEFINE_GUID(OID_ServiceManager
, 0xd9bb9d1d, 0xbfa9, 0x4357, 0x9f, 0x11, 0x9a, 0x2e, 0x90, 0x61, 0xf0, 0x6e);
87 extern rtl_StandardModuleCount globalModuleCount
;
89 /*****************************************************************************
91 class implementation ProviderOleWrapper_Impl
93 *****************************************************************************/
95 ProviderOleWrapper_Impl::ProviderOleWrapper_Impl(const Reference
<XMultiServiceFactory
>& smgr
,
96 const Reference
<XSingleServiceFactory
>& xSFact
, GUID
* pGuid
)
97 : m_xSingleServiceFactory(xSFact
),
102 Reference
<XInterface
> xInt
= smgr
->createInstance(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.bridge.oleautomation.BridgeSupplier"));
106 Any a
= xInt
->queryInterface( ::getCppuType( reinterpret_cast<
107 Reference
< XBridgeSupplier2
>* >(0)));
108 a
>>= m_bridgeSupplier
;
113 ProviderOleWrapper_Impl::~ProviderOleWrapper_Impl()
117 sal_Bool
ProviderOleWrapper_Impl::registerClass()
121 o2u_attachCurrentThread();
123 hresult
= CoRegisterClassObject(
126 CLSCTX_INPROC_SERVER
| CLSCTX_LOCAL_SERVER
,
130 return (hresult
== NOERROR
);
133 sal_Bool
ProviderOleWrapper_Impl::deregisterClass()
135 HRESULT hresult
= CoRevokeClassObject(m_factoryHandle
);
137 return (hresult
== NOERROR
);
140 STDMETHODIMP
ProviderOleWrapper_Impl::QueryInterface(REFIID riid
, void FAR
* FAR
* ppv
)
142 if(IsEqualIID(riid
, IID_IUnknown
))
145 *ppv
= (IUnknown
*) (IClassFactory
*) this;
148 else if (IsEqualIID(riid
, IID_IClassFactory
))
151 *ppv
= (IClassFactory
*) this;
156 return ResultFromScode(E_NOINTERFACE
);
159 STDMETHODIMP_(ULONG
) ProviderOleWrapper_Impl::AddRef()
161 return osl_incrementInterlockedCount( &m_refCount
);
164 STDMETHODIMP_(ULONG
) ProviderOleWrapper_Impl::Release()
166 MutexGuard
aGuard( Mutex::getGlobalMutex());
167 ULONG refCount
= --m_refCount
;
176 STDMETHODIMP
ProviderOleWrapper_Impl::CreateInstance(IUnknown FAR
* punkOuter
,
180 HRESULT ret
= ResultFromScode(E_UNEXPECTED
);
183 Reference
<XInterface
> xInstance
;
185 if (m_xSingleServiceFactory
.is())
187 xInstance
= m_xSingleServiceFactory
->createInstance();
191 Any
usrAny(&xInstance
, getCppuType( & xInstance
));
194 rtl_getGlobalProcessId( arId
);
195 Any oleAny
= m_bridgeSupplier
->createBridge(usrAny
,
196 Sequence
<sal_Int8
>((sal_Int8
*)arId
, 16),
201 if (oleAny
.getValueTypeClass() == getCppuType( (sal_uInt32
*)0).getTypeClass())
203 VARIANT
* pVariant
= *(VARIANT
**)oleAny
.getValue();
205 if (pVariant
->vt
== VT_DISPATCH
)
207 ret
= pVariant
->pdispVal
->QueryInterface(riid
, ppv
);
210 VariantClear(pVariant
);
211 CoTaskMemFree(pVariant
);
219 STDMETHODIMP
ProviderOleWrapper_Impl::LockServer(int /*fLock*/)
224 /*****************************************************************************
226 class implementation OneInstanceOleWrapper_Impl
228 *****************************************************************************/
230 OneInstanceOleWrapper_Impl::OneInstanceOleWrapper_Impl( const Reference
<XMultiServiceFactory
>& smgr
,
231 const Reference
<XInterface
>& xInst
,
233 sal_Bool bAsApplication
)
234 : m_xInst(xInst
), m_refCount(0),
236 m_factoryHandle( 0 ),
237 m_bAsApplication( bAsApplication
),
238 m_nApplRegHandle( 0 )
242 Reference
<XInterface
> xInt
= m_smgr
->createInstance(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.bridge.oleautomation.BridgeSupplier"));
246 Any a
= xInt
->queryInterface( getCppuType(
247 reinterpret_cast< Reference
<XBridgeSupplier2
>*>(0)));
248 a
>>= m_bridgeSupplier
;
252 OneInstanceOleWrapper_Impl::~OneInstanceOleWrapper_Impl()
256 sal_Bool
OneInstanceOleWrapper_Impl::registerClass()
260 o2u_attachCurrentThread();
262 hresult
= CoRegisterClassObject(
265 CLSCTX_INPROC_SERVER
| CLSCTX_LOCAL_SERVER
,
269 if ( hresult
== NOERROR
&& m_bAsApplication
)
270 hresult
= RegisterActiveObject( this, m_guid
, ACTIVEOBJECT_WEAK
, &m_nApplRegHandle
);
272 return (hresult
== NOERROR
);
275 sal_Bool
OneInstanceOleWrapper_Impl::deregisterClass()
277 HRESULT hresult1
= NOERROR
;
278 if ( m_bAsApplication
)
279 hresult1
= RevokeActiveObject( m_nApplRegHandle
, NULL
);
281 HRESULT hresult2
= CoRevokeClassObject(m_factoryHandle
);
283 return (hresult1
== NOERROR
&& hresult2
== NOERROR
);
286 STDMETHODIMP
OneInstanceOleWrapper_Impl::QueryInterface(REFIID riid
, void FAR
* FAR
* ppv
)
288 if(IsEqualIID(riid
, IID_IUnknown
))
291 *ppv
= (IUnknown
*) (IClassFactory
*) this;
294 else if (IsEqualIID(riid
, IID_IClassFactory
))
297 *ppv
= (IClassFactory
*) this;
302 return ResultFromScode(E_NOINTERFACE
);
305 STDMETHODIMP_(ULONG
) OneInstanceOleWrapper_Impl::AddRef()
307 return osl_incrementInterlockedCount( &m_refCount
);
310 STDMETHODIMP_(ULONG
) OneInstanceOleWrapper_Impl::Release()
312 MutexGuard
oGuard( Mutex::getGlobalMutex());
313 ULONG refCount
= --m_refCount
;
314 if ( m_refCount
== 0)
322 STDMETHODIMP
OneInstanceOleWrapper_Impl::CreateInstance(IUnknown FAR
* punkOuter
,
326 HRESULT ret
= ResultFromScode(E_UNEXPECTED
);
331 Any
usrAny(&m_xInst
, getCppuType( &m_xInst
));
333 rtl_getGlobalProcessId( arId
);
334 Any oleAny
= m_bridgeSupplier
->createBridge(usrAny
,
335 Sequence
<sal_Int8
>( (sal_Int8
*)arId
, 16),
340 if (oleAny
.getValueTypeClass() == TypeClass_UNSIGNED_LONG
)
342 VARIANT
* pVariant
= *(VARIANT
**)oleAny
.getValue();
344 if ((pVariant
->vt
== VT_UNKNOWN
) || (pVariant
->vt
== VT_DISPATCH
))
346 ret
= pVariant
->punkVal
->QueryInterface(riid
, ppv
);
349 VariantClear(pVariant
);
350 CoTaskMemFree(pVariant
);
357 STDMETHODIMP
OneInstanceOleWrapper_Impl::LockServer(int /*fLock*/)
363 /*****************************************************************************
365 class implementation OleConverter_Impl2
367 *****************************************************************************/
369 OleConverter_Impl2::OleConverter_Impl2( const Reference
<XMultiServiceFactory
> &smgr
):
370 UnoConversionUtilities
<OleConverter_Impl2
>( smgr
)
373 // library unloading support
374 globalModuleCount
.modCnt
.acquire( &globalModuleCount
.modCnt
);
377 // The XMultiServiceFactory is later set by XInitialization
378 OleConverter_Impl2::OleConverter_Impl2( const Reference
<XMultiServiceFactory
>& smgr
, sal_uInt8 unoWrapperClass
, sal_uInt8 comWrapperClass
):
379 UnoConversionUtilities
<OleConverter_Impl2
>( smgr
, unoWrapperClass
, comWrapperClass
)
382 //library unloading support
383 globalModuleCount
.modCnt
.acquire( &globalModuleCount
.modCnt
);
386 OleConverter_Impl2::~OleConverter_Impl2()
388 globalModuleCount
.modCnt
.release( &globalModuleCount
.modCnt
);
391 // XBridgeSupplier --------------------------------------------------------------
392 Any SAL_CALL
OleConverter_Impl2::createBridge(const Any
& modelDepObject
,
393 const Sequence
< sal_Int8
>& ProcessId
,
394 sal_Int16 sourceModelType
,
395 sal_Int16 destModelType
)
396 throw (IllegalArgumentException
,
401 rtl_getGlobalProcessId( arId
);
403 Sequence
< sal_Int8
> seqProcessId( (sal_Int8
*)arId
, 16);
405 if ( seqProcessId
== ProcessId
)
407 if (sourceModelType
== UNO
)
409 if (destModelType
== UNO
)
411 // same model -> copy value only
412 ret
= modelDepObject
;
414 else if (destModelType
== OLE
)
416 // convert UNO any into variant
417 VARIANT
* pVariant
= (VARIANT
*) CoTaskMemAlloc(sizeof(VARIANT
));
418 VariantInit( pVariant
);
421 anyToVariant( pVariant
, modelDepObject
);
425 CoTaskMemFree(pVariant
);
426 throw IllegalArgumentException();
428 ret
.setValue((void*) &pVariant
, getCppuType((sal_uInt32
*)0));
431 throw IllegalArgumentException();
433 else if (sourceModelType
== OLE
)
435 if (modelDepObject
.getValueType() != getCppuType((sal_uInt32
*)0))
437 throw IllegalArgumentException();
439 else if (destModelType
== OLE
)
441 // same model -> copy value only
442 VARIANT
* pVariant
= (VARIANT
*) CoTaskMemAlloc(sizeof(VARIANT
));
444 if (NOERROR
!= VariantCopy(pVariant
, *(VARIANT
**)modelDepObject
.getValue()))
446 CoTaskMemFree(pVariant
);
447 throw(IllegalArgumentException());
451 ret
.setValue((void*) &pVariant
, getCppuType((sal_uInt32
*)0));
454 else if (destModelType
== UNO
)
456 // convert variant into UNO any
457 VARIANT
* pVariant
= *(VARIANT
**)modelDepObject
.getValue();
460 variantToAny(pVariant
, ret
);
462 catch (CannotConvertException
& e
)
464 throw IllegalArgumentException(
469 throw IllegalArgumentException();
473 throw IllegalArgumentException();
480 // XInitialize ------------------------------------------------------------------------------
481 // the first argument is an XMultiServiceFactory if at all
482 void SAL_CALL
OleConverter_Impl2::initialize( const Sequence
< Any
>& aArguments
)
483 throw(Exception
, RuntimeException
)
485 if( aArguments
.getLength() == 1 && aArguments
[0].getValueTypeClass() == TypeClass_INTERFACE
)
487 Reference
< XInterface
> xInt
;
488 aArguments
[0] >>= xInt
;
489 Reference
<XMultiServiceFactory
> xMulti( xInt
, UNO_QUERY
);
490 m_smgrRemote
= xMulti
;
494 // UnoConversionUtilities -------------------------------------------------------------------
495 Reference
< XInterface
> OleConverter_Impl2::createUnoWrapperInstance()
497 if( m_nUnoWrapperClass
== INTERFACE_OLE_WRAPPER_IMPL
)
499 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper_Impl(
500 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
501 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
503 else if( m_nUnoWrapperClass
== UNO_OBJECT_WRAPPER_REMOTE_OPT
)
505 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
506 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
507 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
510 return Reference
<XInterface
>();
513 Reference
< XInterface
> OleConverter_Impl2::createComWrapperInstance()
515 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper_Impl(
516 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
517 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
522 /*****************************************************************************
524 class implementation OleClient_Impl
526 *****************************************************************************/
528 OleClient_Impl::OleClient_Impl( const Reference
<XMultiServiceFactory
>& smgr
):
529 UnoConversionUtilities
<OleClient_Impl
>( smgr
)
531 // library unloading support
532 globalModuleCount
.modCnt
.acquire( &globalModuleCount
.modCnt
);
533 Reference
<XInterface
> xInt
;// = m_smgr->createInstance(L"com.sun.star.bridge.OleBridgeSupplier2");
537 Any a
= xInt
->queryInterface(getCppuType(
538 reinterpret_cast<Reference
<XBridgeSupplier2
>*>(0)));
539 a
>>= m_bridgeSupplier
;
543 OleClient_Impl::~OleClient_Impl()
545 // library unloading support
546 globalModuleCount
.modCnt
.release( &globalModuleCount
.modCnt
);
549 Sequence
< OUString
> SAL_CALL
OleClient_Impl::getAvailableServiceNames() throw( RuntimeException
)
551 Sequence
< OUString
> ret
;
557 OUString
OleClient_Impl::getImplementationName()
559 return OUString(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.comp.ole.OleClient"));
562 Reference
<XInterface
> SAL_CALL
OleClient_Impl::createInstance(const OUString
& ServiceSpecifier
) throw (Exception
, RuntimeException
)
564 Reference
<XInterface
> ret
;
566 IUnknown
* pUnknown
= NULL
;
569 o2u_attachCurrentThread();
571 result
= CLSIDFromProgID(
572 reinterpret_cast<LPCWSTR
>(ServiceSpecifier
.getStr()), //Pointer to the ProgID
573 &classId
); //Pointer to the CLSID
576 if (result
== NOERROR
)
578 result
= CoCreateInstance(
579 classId
, //Class identifier (CLSID) of the object
580 NULL
, //Pointer to whether object is or isn't part of an aggregate
581 CLSCTX_SERVER
, //Context for running executable code
582 IID_IUnknown
, //Reference to the identifier of the interface
583 (void**)&pUnknown
); //Address of output variable that receives
584 // the interface pointer requested in riid
587 if (pUnknown
!= NULL
)
592 V_VT(&variant
) = VT_UNKNOWN
;
593 V_UNKNOWN(&variant
) = pUnknown
;
594 // AddRef for Variant
597 // When the object is wrapped, then its refcount is increased
598 variantToAny(&variant
, any
);
599 if (any
.getValueTypeClass() == TypeClass_INTERFACE
)
603 pUnknown
->Release(); // CoCreateInstance
609 Reference
<XInterface
> SAL_CALL
OleClient_Impl::createInstanceWithArguments(const OUString
& ServiceSpecifier
, const Sequence
< Any
>& /*Arguments*/) throw (Exception
, RuntimeException
)
611 return createInstance( ServiceSpecifier
);
614 // UnoConversionUtilities -----------------------------------------------------------------------------
615 Reference
< XInterface
> OleClient_Impl::createUnoWrapperInstance()
617 if( m_nUnoWrapperClass
== INTERFACE_OLE_WRAPPER_IMPL
)
619 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new InterfaceOleWrapper_Impl(
620 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
621 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
623 else if( m_nUnoWrapperClass
== UNO_OBJECT_WRAPPER_REMOTE_OPT
)
625 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new UnoObjectWrapperRemoteOpt(
626 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
627 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
630 return Reference
< XInterface
>();
632 // UnoConversionUtilities -----------------------------------------------------------------------------
633 Reference
< XInterface
> OleClient_Impl::createComWrapperInstance( )
635 Reference
<XWeak
> xWeak
= static_cast<XWeak
*>( new IUnknownWrapper_Impl(
636 m_smgr
, m_nUnoWrapperClass
, m_nComWrapperClass
));
637 return Reference
<XInterface
>( xWeak
, UNO_QUERY
);
642 /*****************************************************************************
644 class implementation OleServer_Impl
646 *****************************************************************************/
648 OleServer_Impl::OleServer_Impl( const Reference
<XMultiServiceFactory
>& smgr
):
651 //library unloading support
652 globalModuleCount
.modCnt
.acquire( &globalModuleCount
.modCnt
);
653 Reference
<XInterface
> xInt
= m_smgr
->createInstance(reinterpret_cast<const sal_Unicode
*>(L
"com.sun.star.bridge.oleautomation.BridgeSupplier"));
657 Any a
= xInt
->queryInterface( getCppuType(
658 reinterpret_cast< Reference
<XBridgeSupplier2
>*>(0)));
659 a
>>= m_bridgeSupplier
;
663 sal_Bool bOLERegister
= sal_False
;
665 sal_Bool bOLERegister
= sal_True
;
667 sal_Bool ret
= provideInstance( m_smgr
, (GUID
*)&OID_ServiceManager
, bOLERegister
);
671 OleServer_Impl::~OleServer_Impl()
673 while (!m_wrapperList
.empty())
675 (*m_wrapperList
.begin())->deregisterClass();
676 (*m_wrapperList
.begin())->Release();
677 m_wrapperList
.pop_front();
679 //library unloading support
680 globalModuleCount
.modCnt
.release( &globalModuleCount
.modCnt
);
682 // XInterface --------------------------------------------------
683 Any SAL_CALL
OleServer_Impl::queryInterface( const Type
& aType
) throw(RuntimeException
)
685 Any a
= ::cppu::queryInterface( aType
, static_cast<XTypeProvider
*>(this));
687 return OWeakObject::queryInterface( aType
);
691 void SAL_CALL
OleServer_Impl::acquire( ) throw()
693 OWeakObject::acquire();
695 void SAL_CALL
OleServer_Impl::release( ) throw ()
697 OWeakObject::release();
701 // XTypeProvider --------------------------------------------------
702 Sequence
< Type
> SAL_CALL
OleServer_Impl::getTypes( ) throw(RuntimeException
)
704 static OTypeCollection
*pCollection
= 0;
707 MutexGuard
guard( Mutex::getGlobalMutex() );
710 static OTypeCollection
collection(
711 getCppuType(reinterpret_cast< Reference
< XWeak
>*>(0)),
712 getCppuType(reinterpret_cast< Reference
< XTypeProvider
>*>(0)) );
713 pCollection
= &collection
;
716 return (*pCollection
).getTypes();
718 Sequence
< sal_Int8
> SAL_CALL
OleServer_Impl::getImplementationId() throw(RuntimeException
)
720 static OImplementationId
*pId
= 0;
723 MutexGuard
guard( Mutex::getGlobalMutex() );
726 static OImplementationId
id( sal_False
);
730 return (*pId
).getImplementationId();
734 sal_Bool
OleServer_Impl::provideService(const Reference
<XSingleServiceFactory
>& xSFact
, GUID
* guid
)
736 IClassFactoryWrapper
* pFac
= new ProviderOleWrapper_Impl( m_smgr
, xSFact
, guid
);
740 m_wrapperList
.push_back(pFac
);
742 return pFac
->registerClass();
745 sal_Bool
OleServer_Impl::provideInstance(const Reference
<XInterface
>& xInst
, GUID
* guid
, sal_Bool bAsApplication
)
747 IClassFactoryWrapper
* pFac
= new OneInstanceOleWrapper_Impl( m_smgr
, xInst
, guid
, bAsApplication
);
750 m_wrapperList
.push_back(pFac
);
752 return pFac
->registerClass();