update dev300-m58
[ooovba.git] / extensions / source / ole / servprov.cxx
blobf466e566aaf21bd549e6bbf091dc036ed58bf7f4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: servprov.cxx,v $
10 * $Revision: 1.20 $
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"
34 #ifdef __MINGW32__
35 #define INITGUID
36 #include <initguid.h>
37 #else
38 #include "ole2uno.hxx"
39 #include "unoconversionutilities.hxx"
40 #endif
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)
50 #undef _DEBUG
51 #endif
52 #include <atlbase.h>
53 extern CComModule _Module;
54 #include <atlcom.h>
55 #include <tools/postsys.h>
58 using namespace std;
59 using namespace cppu;
60 using namespace rtl;
61 using namespace osl;
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;
69 namespace ole_adapter
72 #include <initguid.h>
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);
77 #ifndef OWNGUID
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);
81 #else
82 // Alternative GUID
83 // {D9BB9D1D-BFA9-4357-9F11-9A2E9061F06E}
84 DEFINE_GUID(OID_ServiceManager, 0xd9bb9d1d, 0xbfa9, 0x4357, 0x9f, 0x11, 0x9a, 0x2e, 0x90, 0x61, 0xf0, 0x6e);
85 #endif
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),
98 m_smgr( smgr)
100 m_guid = *pGuid;
102 Reference<XInterface> xInt = smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
104 if (xInt.is())
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()
119 HRESULT hresult;
121 o2u_attachCurrentThread();
123 hresult = CoRegisterClassObject(
124 m_guid,
125 this,
126 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
127 REGCLS_MULTIPLEUSE,
128 &m_factoryHandle);
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))
144 AddRef();
145 *ppv = (IUnknown*) (IClassFactory*) this;
146 return NOERROR;
148 else if (IsEqualIID(riid, IID_IClassFactory))
150 AddRef();
151 *ppv = (IClassFactory*) this;
152 return NOERROR;
155 *ppv = NULL;
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;
168 if (m_refCount == 0)
170 delete this;
173 return refCount;
176 STDMETHODIMP ProviderOleWrapper_Impl::CreateInstance(IUnknown FAR* punkOuter,
177 REFIID riid,
178 void FAR* FAR* ppv)
180 HRESULT ret = ResultFromScode(E_UNEXPECTED);
181 punkOuter = NULL;
183 Reference<XInterface> xInstance;
185 if (m_xSingleServiceFactory.is())
187 xInstance = m_xSingleServiceFactory->createInstance();
189 if (xInstance.is())
191 Any usrAny(&xInstance, getCppuType( & xInstance));
193 sal_uInt8 arId[16];
194 rtl_getGlobalProcessId( arId );
195 Any oleAny = m_bridgeSupplier->createBridge(usrAny,
196 Sequence<sal_Int8>((sal_Int8*)arId, 16),
197 UNO,
198 OLE);
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);
216 return ret;
219 STDMETHODIMP ProviderOleWrapper_Impl::LockServer(int /*fLock*/)
221 return NOERROR;
224 /*****************************************************************************
226 class implementation OneInstanceOleWrapper_Impl
228 *****************************************************************************/
230 OneInstanceOleWrapper_Impl::OneInstanceOleWrapper_Impl( const Reference<XMultiServiceFactory>& smgr,
231 const Reference<XInterface>& xInst,
232 GUID* pGuid,
233 sal_Bool bAsApplication )
234 : m_xInst(xInst), m_refCount(0),
235 m_smgr( smgr),
236 m_factoryHandle( 0 ),
237 m_bAsApplication( bAsApplication ),
238 m_nApplRegHandle( 0 )
240 m_guid = *pGuid;
242 Reference<XInterface> xInt = m_smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
244 if (xInt.is())
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()
258 HRESULT hresult;
260 o2u_attachCurrentThread();
262 hresult = CoRegisterClassObject(
263 m_guid,
264 this,
265 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
266 REGCLS_MULTIPLEUSE,
267 &m_factoryHandle);
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))
290 AddRef();
291 *ppv = (IUnknown*) (IClassFactory*) this;
292 return NOERROR;
294 else if (IsEqualIID(riid, IID_IClassFactory))
296 AddRef();
297 *ppv = (IClassFactory*) this;
298 return NOERROR;
301 *ppv = NULL;
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)
316 delete this;
319 return refCount;
322 STDMETHODIMP OneInstanceOleWrapper_Impl::CreateInstance(IUnknown FAR* punkOuter,
323 REFIID riid,
324 void FAR* FAR* ppv)
326 HRESULT ret = ResultFromScode(E_UNEXPECTED);
327 punkOuter = NULL;
329 if (m_xInst.is())
331 Any usrAny(&m_xInst, getCppuType( &m_xInst));
332 sal_uInt8 arId[16];
333 rtl_getGlobalProcessId( arId);
334 Any oleAny = m_bridgeSupplier->createBridge(usrAny,
335 Sequence<sal_Int8>( (sal_Int8*)arId, 16),
336 UNO,
337 OLE);
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);
354 return ret;
357 STDMETHODIMP OneInstanceOleWrapper_Impl::LockServer(int /*fLock*/)
359 return NOERROR;
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,
397 RuntimeException )
399 Any ret;
400 sal_uInt8 arId[16];
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);
423 catch(...)
425 CoTaskMemFree(pVariant);
426 throw IllegalArgumentException();
428 ret.setValue((void*) &pVariant, getCppuType((sal_uInt32*)0));
430 else
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());
449 else
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(
465 e.Message, 0, -1);
468 else
469 throw IllegalArgumentException();
472 else
473 throw IllegalArgumentException();
476 return ret;
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);
509 else
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");
535 if (xInt.is())
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;
553 return 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;
565 HRESULT result;
566 IUnknown* pUnknown = NULL;
567 CLSID classId;
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)
589 Any any;
590 CComVariant variant;
592 V_VT(&variant) = VT_UNKNOWN;
593 V_UNKNOWN(&variant) = pUnknown;
594 // AddRef for Variant
595 pUnknown->AddRef();
597 // When the object is wrapped, then its refcount is increased
598 variantToAny(&variant, any);
599 if (any.getValueTypeClass() == TypeClass_INTERFACE)
601 any >>= ret;
603 pUnknown->Release(); // CoCreateInstance
606 return ret;
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);
629 else
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):
649 m_smgr( 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"));
655 if (xInt.is())
657 Any a= xInt->queryInterface( getCppuType(
658 reinterpret_cast< Reference<XBridgeSupplier2>*>(0)));
659 a >>= m_bridgeSupplier;
662 #ifndef OWNGUID
663 sal_Bool bOLERegister = sal_False;
664 #else
665 sal_Bool bOLERegister = sal_True;
666 #endif
667 sal_Bool ret = provideInstance( m_smgr, (GUID*)&OID_ServiceManager, bOLERegister );
668 (void)ret;
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));
686 if( a == Any())
687 return OWeakObject::queryInterface( aType);
688 else
689 return a;
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;
705 if( ! pCollection )
707 MutexGuard guard( Mutex::getGlobalMutex() );
708 if( ! pCollection )
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;
721 if( ! pId )
723 MutexGuard guard( Mutex::getGlobalMutex() );
724 if( ! pId )
726 static OImplementationId id( sal_False );
727 pId = &id;
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);
738 pFac->AddRef();
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 );
749 pFac->AddRef();
750 m_wrapperList.push_back(pFac);
752 return pFac->registerClass();
757 } // end namespace