update credits
[LibreOffice.git] / extensions / source / ole / servprov.cxx
blob9e799071d857af4d1d2ded864da1e0ec7804da6b
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 // http://stackoverflow.com/questions/5839292/error-c1189-after-installing-visual-studio-2010
21 #define _WIN32_WINNT 0x0403
24 #include <vector>
26 #ifdef __MINGW32__
27 #define INITGUID
28 #include <initguid.h>
29 #else
30 #include "ole2uno.hxx"
31 #include "unoconversionutilities.hxx"
32 #endif
33 #include "servprov.hxx"
34 #include "unoobjw.hxx"
35 #include "oleobjw.hxx"
37 using namespace cppu;
38 using namespace osl;
39 using namespace com::sun::star::lang;
40 using namespace com::sun::star::uno;
41 using namespace com::sun::star::bridge;
42 using namespace com::sun::star::bridge::ModelDependent;
45 namespace ole_adapter
48 #include <initguid.h>
50 // GUID used since 5.2 ( src569 m)
51 // {82154420-0FBF-11d4-8313-005004526AB4}
52 DEFINE_GUID(OID_ServiceManager, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
54 /*****************************************************************************
56 class implementation ProviderOleWrapper_Impl
58 *****************************************************************************/
60 ProviderOleWrapper_Impl::ProviderOleWrapper_Impl(const Reference<XMultiServiceFactory>& smgr,
61 const Reference<XSingleServiceFactory>& xSFact, GUID* pGuid)
62 : m_xSingleServiceFactory(xSFact),
63 m_smgr( smgr)
65 m_guid = *pGuid;
67 Reference<XInterface> xInt = smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
69 if (xInt.is())
71 Any a= xInt->queryInterface( ::getCppuType( reinterpret_cast<
72 Reference< XBridgeSupplier2>* >(0)));
73 a >>= m_bridgeSupplier;
78 ProviderOleWrapper_Impl::~ProviderOleWrapper_Impl()
82 sal_Bool ProviderOleWrapper_Impl::registerClass()
84 HRESULT hresult;
86 o2u_attachCurrentThread();
88 hresult = CoRegisterClassObject(
89 m_guid,
90 this,
91 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
92 REGCLS_MULTIPLEUSE,
93 &m_factoryHandle);
95 return (hresult == NOERROR);
98 sal_Bool ProviderOleWrapper_Impl::deregisterClass()
100 HRESULT hresult = CoRevokeClassObject(m_factoryHandle);
102 return (hresult == NOERROR);
105 STDMETHODIMP ProviderOleWrapper_Impl::QueryInterface(REFIID riid, void FAR* FAR* ppv)
107 if(IsEqualIID(riid, IID_IUnknown))
109 AddRef();
110 *ppv = (IUnknown*) (IClassFactory*) this;
111 return NOERROR;
113 else if (IsEqualIID(riid, IID_IClassFactory))
115 AddRef();
116 *ppv = (IClassFactory*) this;
117 return NOERROR;
120 *ppv = NULL;
121 return ResultFromScode(E_NOINTERFACE);
124 STDMETHODIMP_(ULONG) ProviderOleWrapper_Impl::AddRef()
126 return osl_atomic_increment( &m_refCount);
129 STDMETHODIMP_(ULONG) ProviderOleWrapper_Impl::Release()
131 MutexGuard aGuard( Mutex::getGlobalMutex());
132 ULONG refCount = --m_refCount;
133 if (m_refCount == 0)
135 delete this;
138 return refCount;
141 STDMETHODIMP ProviderOleWrapper_Impl::CreateInstance(IUnknown FAR* punkOuter,
142 REFIID riid,
143 void FAR* FAR* ppv)
145 HRESULT ret = ResultFromScode(E_UNEXPECTED);
146 punkOuter = NULL;
148 Reference<XInterface> xInstance;
150 if (m_xSingleServiceFactory.is())
152 xInstance = m_xSingleServiceFactory->createInstance();
154 if (xInstance.is())
156 Any usrAny(&xInstance, getCppuType( & xInstance));
158 sal_uInt8 arId[16];
159 rtl_getGlobalProcessId( arId );
160 Any oleAny = m_bridgeSupplier->createBridge(usrAny,
161 Sequence<sal_Int8>((sal_Int8*)arId, 16),
162 UNO,
163 OLE);
166 if (oleAny.getValueTypeClass() == getCppuType( (sal_uInt32 *)0).getTypeClass())
168 VARIANT* pVariant = *(VARIANT**)oleAny.getValue();
170 if (pVariant->vt == VT_DISPATCH)
172 ret = pVariant->pdispVal->QueryInterface(riid, ppv);
175 VariantClear(pVariant);
176 CoTaskMemFree(pVariant);
181 return ret;
184 STDMETHODIMP ProviderOleWrapper_Impl::LockServer(int /*fLock*/)
186 return NOERROR;
189 /*****************************************************************************
191 class implementation OneInstanceOleWrapper_Impl
193 *****************************************************************************/
195 OneInstanceOleWrapper_Impl::OneInstanceOleWrapper_Impl( const Reference<XMultiServiceFactory>& smgr,
196 const Reference<XInterface>& xInst,
197 GUID* pGuid )
198 : m_xInst(xInst)
199 , m_refCount(0)
200 , m_smgr(smgr)
201 , m_factoryHandle(0)
203 m_guid = *pGuid;
205 Reference<XInterface> xInt = m_smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
207 if (xInt.is())
209 Any a= xInt->queryInterface( getCppuType(
210 reinterpret_cast< Reference<XBridgeSupplier2>*>(0)));
211 a >>= m_bridgeSupplier;
215 OneInstanceOleWrapper_Impl::~OneInstanceOleWrapper_Impl()
219 sal_Bool OneInstanceOleWrapper_Impl::registerClass()
221 HRESULT hresult;
223 o2u_attachCurrentThread();
225 hresult = CoRegisterClassObject(
226 m_guid,
227 this,
228 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
229 REGCLS_MULTIPLEUSE,
230 &m_factoryHandle);
232 return (hresult == NOERROR);
235 sal_Bool OneInstanceOleWrapper_Impl::deregisterClass()
237 HRESULT hresult1 = NOERROR;
239 HRESULT hresult2 = CoRevokeClassObject(m_factoryHandle);
241 return (hresult1 == NOERROR && hresult2 == NOERROR);
244 STDMETHODIMP OneInstanceOleWrapper_Impl::QueryInterface(REFIID riid, void FAR* FAR* ppv)
246 if(IsEqualIID(riid, IID_IUnknown))
248 AddRef();
249 *ppv = (IUnknown*) (IClassFactory*) this;
250 return NOERROR;
252 else if (IsEqualIID(riid, IID_IClassFactory))
254 AddRef();
255 *ppv = (IClassFactory*) this;
256 return NOERROR;
259 *ppv = NULL;
260 return ResultFromScode(E_NOINTERFACE);
263 STDMETHODIMP_(ULONG) OneInstanceOleWrapper_Impl::AddRef()
265 return osl_atomic_increment( &m_refCount);
268 STDMETHODIMP_(ULONG) OneInstanceOleWrapper_Impl::Release()
270 MutexGuard oGuard( Mutex::getGlobalMutex());
271 ULONG refCount = --m_refCount;
272 if ( m_refCount == 0)
274 delete this;
277 return refCount;
280 STDMETHODIMP OneInstanceOleWrapper_Impl::CreateInstance(IUnknown FAR* punkOuter,
281 REFIID riid,
282 void FAR* FAR* ppv)
284 HRESULT ret = ResultFromScode(E_UNEXPECTED);
285 punkOuter = NULL;
287 if (m_xInst.is())
289 Any usrAny(&m_xInst, getCppuType( &m_xInst));
290 sal_uInt8 arId[16];
291 rtl_getGlobalProcessId( arId);
292 Any oleAny = m_bridgeSupplier->createBridge(usrAny,
293 Sequence<sal_Int8>( (sal_Int8*)arId, 16),
294 UNO,
295 OLE);
298 if (oleAny.getValueTypeClass() == TypeClass_UNSIGNED_LONG)
300 VARIANT* pVariant = *(VARIANT**)oleAny.getValue();
302 if ((pVariant->vt == VT_UNKNOWN) || (pVariant->vt == VT_DISPATCH))
304 ret = pVariant->punkVal->QueryInterface(riid, ppv);
307 VariantClear(pVariant);
308 CoTaskMemFree(pVariant);
312 return ret;
315 STDMETHODIMP OneInstanceOleWrapper_Impl::LockServer(int /*fLock*/)
317 return NOERROR;
321 /*****************************************************************************
323 class implementation OleConverter_Impl2
325 *****************************************************************************/
327 OleConverter_Impl2::OleConverter_Impl2( const Reference<XMultiServiceFactory> &smgr):
328 UnoConversionUtilities<OleConverter_Impl2>( smgr)
333 // The XMultiServiceFactory is later set by XInitialization
334 OleConverter_Impl2::OleConverter_Impl2( const Reference<XMultiServiceFactory>& smgr, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass ):
335 UnoConversionUtilities<OleConverter_Impl2>( smgr, unoWrapperClass, comWrapperClass )
340 OleConverter_Impl2::~OleConverter_Impl2()
344 // XBridgeSupplier --------------------------------------------------------------
345 Any SAL_CALL OleConverter_Impl2::createBridge(const Any& modelDepObject,
346 const Sequence< sal_Int8 >& ProcessId,
347 sal_Int16 sourceModelType,
348 sal_Int16 destModelType)
349 throw (IllegalArgumentException,
350 RuntimeException )
352 Any ret;
353 sal_uInt8 arId[16];
354 rtl_getGlobalProcessId( arId );
356 Sequence< sal_Int8 > seqProcessId( (sal_Int8*)arId, 16);
358 if ( seqProcessId == ProcessId)
360 if (sourceModelType == UNO)
362 if (destModelType == UNO)
364 // same model -> copy value only
365 ret = modelDepObject;
367 else if (destModelType == OLE)
369 // convert UNO any into variant
370 VARIANT* pVariant = (VARIANT*) CoTaskMemAlloc(sizeof(VARIANT));
371 VariantInit( pVariant);
374 anyToVariant( pVariant, modelDepObject);
376 catch(...)
378 CoTaskMemFree(pVariant);
379 throw IllegalArgumentException();
381 ret.setValue((void*) &pVariant, getCppuType((sal_uInt32*)0));
383 else
384 throw IllegalArgumentException();
386 else if (sourceModelType == OLE)
388 if (modelDepObject.getValueType() != getCppuType((sal_uInt32*)0))
390 throw IllegalArgumentException();
392 else if (destModelType == OLE)
394 // same model -> copy value only
395 VARIANT* pVariant = (VARIANT*) CoTaskMemAlloc(sizeof(VARIANT));
397 if (NOERROR != VariantCopy(pVariant, *(VARIANT**)modelDepObject.getValue()))
399 CoTaskMemFree(pVariant);
400 throw(IllegalArgumentException());
402 else
404 ret.setValue((void*) &pVariant, getCppuType((sal_uInt32*)0));
407 else if (destModelType == UNO)
409 // convert variant into UNO any
410 VARIANT* pVariant = *(VARIANT**)modelDepObject.getValue();
413 variantToAny(pVariant, ret);
415 catch (const CannotConvertException & e)
417 throw IllegalArgumentException(
418 e.Message, 0, -1);
421 else
422 throw IllegalArgumentException();
425 else
426 throw IllegalArgumentException();
429 return ret;
433 // XInitialize ------------------------------------------------------------------------------
434 // the first argument is an XMultiServiceFactory if at all
435 void SAL_CALL OleConverter_Impl2::initialize( const Sequence< Any >& aArguments )
436 throw(Exception, RuntimeException)
438 if( aArguments.getLength() == 1 && aArguments[0].getValueTypeClass() == TypeClass_INTERFACE)
440 Reference < XInterface > xInt;
441 aArguments[0] >>= xInt;
442 Reference <XMultiServiceFactory> xMulti( xInt, UNO_QUERY);
443 m_smgrRemote= xMulti;
447 // UnoConversionUtilities -------------------------------------------------------------------
448 Reference< XInterface > OleConverter_Impl2::createUnoWrapperInstance()
450 if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
452 Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
453 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
454 return Reference<XInterface>( xWeak, UNO_QUERY);
456 else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
458 Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
459 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
460 return Reference<XInterface>( xWeak, UNO_QUERY);
462 else
463 return Reference<XInterface>();
466 Reference< XInterface > OleConverter_Impl2::createComWrapperInstance()
468 Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
469 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
470 return Reference<XInterface>( xWeak, UNO_QUERY);
475 /*****************************************************************************
477 class implementation OleClient_Impl
479 *****************************************************************************/
481 OleClient_Impl::OleClient_Impl( const Reference<XMultiServiceFactory>& smgr):
482 UnoConversionUtilities<OleClient_Impl>( smgr)
484 Reference<XInterface> xInt;// = m_smgr->createInstance(L"com.sun.star.bridge.OleBridgeSupplier2");
486 if (xInt.is())
488 Any a= xInt->queryInterface(getCppuType(
489 reinterpret_cast<Reference<XBridgeSupplier2>*>(0)));
490 a >>= m_bridgeSupplier;
494 OleClient_Impl::~OleClient_Impl()
498 Sequence< OUString > SAL_CALL OleClient_Impl::getAvailableServiceNames() throw( RuntimeException )
500 Sequence< OUString > ret;
502 return ret;
506 OUString OleClient_Impl::getImplementationName()
508 return OUString(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.comp.ole.OleClient"));
511 Reference<XInterface> SAL_CALL OleClient_Impl::createInstance(const OUString& ServiceSpecifier) throw (Exception, RuntimeException )
513 Reference<XInterface> ret;
514 HRESULT result;
515 IUnknown* pUnknown = NULL;
516 CLSID classId;
518 o2u_attachCurrentThread();
520 result = CLSIDFromProgID(
521 reinterpret_cast<LPCWSTR>(ServiceSpecifier.getStr()), //Pointer to the ProgID
522 &classId); //Pointer to the CLSID
525 if (result == NOERROR)
527 result = CoCreateInstance(
528 classId, //Class identifier (CLSID) of the object
529 NULL, //Pointer to whether object is or isn't part of an aggregate
530 CLSCTX_SERVER, //Context for running executable code
531 IID_IUnknown, //Reference to the identifier of the interface
532 (void**)&pUnknown); //Address of output variable that receives
533 // the interface pointer requested in riid
536 if (pUnknown != NULL)
538 Any any;
539 CComVariant variant;
541 V_VT(&variant) = VT_UNKNOWN;
542 V_UNKNOWN(&variant) = pUnknown;
543 // AddRef for Variant
544 pUnknown->AddRef();
546 // When the object is wrapped, then its refcount is increased
547 variantToAny(&variant, any);
548 if (any.getValueTypeClass() == TypeClass_INTERFACE)
550 any >>= ret;
552 pUnknown->Release(); // CoCreateInstance
555 return ret;
558 Reference<XInterface> SAL_CALL OleClient_Impl::createInstanceWithArguments(const OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/) throw (Exception, RuntimeException)
560 return createInstance( ServiceSpecifier);
563 // UnoConversionUtilities -----------------------------------------------------------------------------
564 Reference< XInterface > OleClient_Impl::createUnoWrapperInstance()
566 if( m_nUnoWrapperClass == INTERFACE_OLE_WRAPPER_IMPL)
568 Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper_Impl(
569 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
570 return Reference<XInterface>( xWeak, UNO_QUERY);
572 else if( m_nUnoWrapperClass == UNO_OBJECT_WRAPPER_REMOTE_OPT)
574 Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
575 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
576 return Reference<XInterface>( xWeak, UNO_QUERY);
578 else
579 return Reference< XInterface>();
581 // UnoConversionUtilities -----------------------------------------------------------------------------
582 Reference< XInterface > OleClient_Impl::createComWrapperInstance( )
584 Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper_Impl(
585 m_smgr, m_nUnoWrapperClass, m_nComWrapperClass));
586 return Reference<XInterface>( xWeak, UNO_QUERY);
591 /*****************************************************************************
593 class implementation OleServer_Impl
595 *****************************************************************************/
597 OleServer_Impl::OleServer_Impl( const Reference<XMultiServiceFactory>& smgr):
598 m_smgr( smgr)
600 Reference<XInterface> xInt = m_smgr->createInstance(reinterpret_cast<const sal_Unicode*>(L"com.sun.star.bridge.oleautomation.BridgeSupplier"));
602 if (xInt.is())
604 Any a= xInt->queryInterface( getCppuType(
605 reinterpret_cast< Reference<XBridgeSupplier2>*>(0)));
606 a >>= m_bridgeSupplier;
609 sal_Bool ret = provideInstance( m_smgr, (GUID*)&OID_ServiceManager );
610 (void)ret;
613 OleServer_Impl::~OleServer_Impl()
615 while (!m_wrapperList.empty())
617 (*m_wrapperList.begin())->deregisterClass();
618 (*m_wrapperList.begin())->Release();
619 m_wrapperList.pop_front();
622 // XInterface --------------------------------------------------
623 Any SAL_CALL OleServer_Impl::queryInterface( const Type& aType ) throw(RuntimeException)
625 Any a= ::cppu::queryInterface( aType, static_cast<XTypeProvider*>(this));
626 if( a == Any())
627 return OWeakObject::queryInterface( aType);
628 else
629 return a;
631 void SAL_CALL OleServer_Impl::acquire( ) throw()
633 OWeakObject::acquire();
635 void SAL_CALL OleServer_Impl::release( ) throw ()
637 OWeakObject::release();
641 // XTypeProvider --------------------------------------------------
642 Sequence< Type > SAL_CALL OleServer_Impl::getTypes( ) throw(RuntimeException)
644 static OTypeCollection *pCollection = 0;
645 if( ! pCollection )
647 MutexGuard guard( Mutex::getGlobalMutex() );
648 if( ! pCollection )
650 static OTypeCollection collection(
651 getCppuType(reinterpret_cast< Reference< XWeak>*>(0)),
652 getCppuType(reinterpret_cast< Reference< XTypeProvider>*>(0)) );
653 pCollection = &collection;
656 return (*pCollection).getTypes();
658 Sequence< sal_Int8 > SAL_CALL OleServer_Impl::getImplementationId() throw(RuntimeException)
660 static OImplementationId *pId = 0;
661 if( ! pId )
663 MutexGuard guard( Mutex::getGlobalMutex() );
664 if( ! pId )
666 static OImplementationId id( sal_False );
667 pId = &id;
670 return (*pId).getImplementationId();
674 sal_Bool OleServer_Impl::provideService(const Reference<XSingleServiceFactory>& xSFact, GUID* guid)
676 IClassFactoryWrapper* pFac = new ProviderOleWrapper_Impl( m_smgr, xSFact, guid);
678 pFac->AddRef();
680 m_wrapperList.push_back(pFac);
682 return pFac->registerClass();
685 sal_Bool OleServer_Impl::provideInstance(const Reference<XInterface>& xInst, GUID* guid)
687 IClassFactoryWrapper* pFac =
688 new OneInstanceOleWrapper_Impl( m_smgr, xInst, guid );
690 pFac->AddRef();
691 m_wrapperList.push_back(pFac);
693 return pFac->registerClass();
698 } // end namespace
700 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */