LibreOffice Module extensions (master) 1
servprov.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <vector>
21
22#include "ole2uno.hxx"
24#include "servprov.hxx"
25#include "unoobjw.hxx"
26#include "oleobjw.hxx"
27
28#include <com/sun/star/script/CannotConvertException.hpp>
34#include <o3tl/any.hxx>
36#include <ooo/vba/XHelperInterface.hpp>
37#include <sal/log.hxx>
38
39using namespace cppu;
40using namespace osl;
41using namespace com::sun::star::lang;
42using namespace com::sun::star::uno;
43using namespace com::sun::star::bridge;
44using namespace com::sun::star::bridge::ModelDependent;
45
46#include <initguid.h>
47
48// GUID used since 5.2 ( src569 m)
49// {82154420-0FBF-11d4-8313-005004526AB4}
50DEFINE_GUID(OID_ServiceManager, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
51
52// FIXME: This GUID is just the above OID_ServiceManager with the
53// initial part bumped by one. Is that good enough?
54// {82154421-0FBF-11d4-8313-005004526AB4}
55DEFINE_GUID(OID_LibreOfficeWriterApplication, 0x82154421, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
56
57// For Calc
58// {82154425-0FBF-11d4-8313-005004526AB4}
59DEFINE_GUID(OID_LibreOfficeCalcApplication, 0x82154425, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4);
60
62 std::function<const Reference<XInterface>()> xInstFunction )
63 : m_refCount(0)
64 , m_xInstFunction(xInstFunction)
65 , m_factoryHandle(0)
66 , m_smgr(smgr)
67{
68 Reference<XInterface> xInt = m_smgr->createInstance("com.sun.star.bridge.oleautomation.BridgeSupplier");
69
70 if (xInt.is())
71 {
72 Any a= xInt->queryInterface( cppu::UnoType<XBridgeSupplier2>::get() );
74 }
75}
76
78{
79}
80
82{
83 HRESULT hresult;
84
86
87 hresult = CoRegisterClassObject(
88 *pGuid,
89 this,
90 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
91 REGCLS_MULTIPLEUSE,
93
94 SAL_INFO("extensions.olebridge", "CoRegisterClassObject(" << *pGuid << "): " << WindowsErrorStringFromHRESULT(hresult));
95
96 return (hresult == NOERROR);
97}
98
100{
101 return CoRevokeClassObject(m_factoryHandle) == NOERROR;
102}
103
104COM_DECLSPEC_NOTHROW STDMETHODIMP OneInstanceOleWrapper::QueryInterface(REFIID riid, void ** ppv)
105{
106 if(IsEqualIID(riid, IID_IUnknown))
107 {
108 AddRef();
109 *ppv = static_cast<IUnknown*>(static_cast<IClassFactory*>(this));
110 return NOERROR;
111 }
112 else if (IsEqualIID(riid, IID_IClassFactory))
113 {
114 AddRef();
115 *ppv = static_cast<IClassFactory*>(this);
116 return NOERROR;
117 }
118
119 *ppv = nullptr;
120 return ResultFromScode(E_NOINTERFACE);
121}
122
123COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) OneInstanceOleWrapper::AddRef()
124{
125 return osl_atomic_increment( &m_refCount);
126}
127
128COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) OneInstanceOleWrapper::Release()
129{
130 MutexGuard oGuard( Mutex::getGlobalMutex());
131 ULONG refCount = --m_refCount;
132 if ( m_refCount == 0)
133 {
134 delete this;
135 }
136
137 return refCount;
138}
139
140COM_DECLSPEC_NOTHROW STDMETHODIMP OneInstanceOleWrapper::CreateInstance(IUnknown*,
141 REFIID riid, void** ppv)
142{
144
145 SAL_INFO("extensions.olebridge", "OneInstanceOleWrapper::CreateInstance(" << riid << ")");
146
147 HRESULT ret = ResultFromScode(E_UNEXPECTED);
148
149 const Reference<XInterface>& xInst = m_xInstFunction();
150 if (xInst.is())
151 {
152 Any usrAny(&xInst, cppu::UnoType<decltype(xInst)>::get());
153 sal_uInt8 arId[16];
154 rtl_getGlobalProcessId( arId);
155 Any oleAny = m_bridgeSupplier->createBridge(usrAny,
156 Sequence<sal_Int8>( reinterpret_cast<sal_Int8*>(arId), 16),
157 UNO,
158 OLE);
159
160
161 if (auto v = o3tl::tryAccess<sal_uIntPtr>(oleAny))
162 {
163 VARIANT* pVariant = reinterpret_cast<VARIANT*>(*v);
164
165 if ((pVariant->vt == VT_UNKNOWN) || (pVariant->vt == VT_DISPATCH))
166 {
167 SAL_INFO("extensions.olebridge", "OneInstanceOleWrapper::Createbridge: punkVal=" << pVariant->punkVal);
168 ret = pVariant->punkVal->QueryInterface(riid, ppv);
169 }
170
171 VariantClear(pVariant);
172 CoTaskMemFree(pVariant);
173 }
174 }
175
176 return ret;
177}
178
179COM_DECLSPEC_NOTHROW STDMETHODIMP OneInstanceOleWrapper::LockServer(BOOL /*fLock*/)
180{
181 return NOERROR;
182}
183
186
187{
188}
189
190// The XMultiServiceFactory is later set by XInitialization
191OleConverter::OleConverter( const Reference<XMultiServiceFactory>& smgr, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass ):
192 UnoConversionUtilities<OleConverter>( smgr, unoWrapperClass, comWrapperClass )
193
194{
195}
196
198{
199}
200
201// XBridgeSupplier --------------------------------------------------------------
202Any SAL_CALL OleConverter::createBridge(const Any& modelDepObject,
203 const Sequence< sal_Int8 >& ProcessId,
204 sal_Int16 sourceModelType,
205 sal_Int16 destModelType)
206{
207 Any ret;
208 sal_uInt8 arId[16];
209 rtl_getGlobalProcessId( arId );
210
211 Sequence< sal_Int8 > seqProcessId( reinterpret_cast<sal_Int8*>(arId), 16);
212
213 if ( seqProcessId == ProcessId)
214 {
215 if (sourceModelType == UNO)
216 {
217 if (destModelType == UNO)
218 {
219 // same model -> copy value only
220 ret = modelDepObject;
221 }
222 else if (destModelType == OLE)
223 {
224 // convert UNO any into variant
225 VARIANT* pVariant = static_cast<VARIANT*>(CoTaskMemAlloc(sizeof(VARIANT)));
226 VariantInit( pVariant);
227 try
228 {
229 anyToVariant( pVariant, modelDepObject);
230 }
231 catch(...)
232 {
233 CoTaskMemFree(pVariant);
234 throw IllegalArgumentException();
235 }
236 ret.setValue(static_cast<void*>(&pVariant), cppu::UnoType<sal_uIntPtr>::get());
237 }
238 else
239 throw IllegalArgumentException();
240 }
241 else if (sourceModelType == OLE)
242 {
243 auto v = o3tl::tryAccess<sal_uIntPtr>(modelDepObject);
244 if (!v)
245 {
246 throw IllegalArgumentException();
247 }
248 else if (destModelType == OLE)
249 {
250 // same model -> copy value only
251 VARIANT* pVariant = static_cast<VARIANT*>(CoTaskMemAlloc(sizeof(VARIANT)));
252
253 if (NOERROR != VariantCopy(pVariant, reinterpret_cast<VARIANT*>(*v)))
254 {
255 CoTaskMemFree(pVariant);
256 throw(IllegalArgumentException());
257 }
258 else
259 {
260 ret.setValue(static_cast<void*>(&pVariant), cppu::UnoType<sal_uIntPtr>::get());
261 }
262 }
263 else if (destModelType == UNO)
264 {
265 // convert variant into UNO any
266 VARIANT* pVariant = reinterpret_cast<VARIANT*>(*v);
267 try
268 {
269 variantToAny(pVariant, ret);
270 }
271 catch (const CannotConvertException & e)
272 {
273 throw IllegalArgumentException(
274 e.Message, nullptr, -1);
275 }
276 }
277 else
278 throw IllegalArgumentException();
279
280 }
281 else
282 throw IllegalArgumentException();
283 }
284
285 return ret;
286}
287
289{
291 ? OUString("com.sun.star.comp.ole.OleConverter2")
292 : OUString("com.sun.star.comp.ole.OleConverterVar1");
293}
294
295sal_Bool OleConverter::supportsService(OUString const & ServiceName)
296{
298}
299
300css::uno::Sequence<OUString> OleConverter::getSupportedServiceNames()
301{
303 {
304 return css::uno::Sequence<OUString>{
305 "com.sun.star.bridge.OleBridgeSupplier2",
306 "com.sun.star.bridge.oleautomation.BridgeSupplier"};
307 }
308 return {"com.sun.star.bridge.OleBridgeSupplierVar1"};
309}
310
311// XInitialize ------------------------------------------------------------------------------
312// the first argument is an XMultiServiceFactory if at all
313void SAL_CALL OleConverter::initialize( const Sequence< Any >& aArguments )
314{
315 if( aArguments.getLength() == 1 && aArguments[0].getValueTypeClass() == TypeClass_INTERFACE)
316 {
318 aArguments[0] >>= xInt;
319 Reference <XMultiServiceFactory> xMulti( xInt, UNO_QUERY);
320 m_smgrRemote= xMulti;
321 }
322}
323
324// UnoConversionUtilities -------------------------------------------------------------------
326{
328 {
329 Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper(
331 return Reference<XInterface>( xWeak, UNO_QUERY);
332 }
334 {
335 Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
337 return Reference<XInterface>( xWeak, UNO_QUERY);
338 }
339 else
340 return Reference<XInterface>();
341}
342
344{
345 Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper(
347 return Reference<XInterface>( xWeak, UNO_QUERY);
348}
349
352{
353 Reference<XInterface> xInt;// = m_smgr->createInstance(L"com.sun.star.bridge.OleBridgeSupplier2");
354
355 if (xInt.is())
356 {
357 Any a= xInt->queryInterface(cppu::UnoType<XBridgeSupplier2>::get() );
359 }
360}
361
363{
364}
365
367{
369
370 return ret;
371}
372
374{
375 return "com.sun.star.comp.ole.OleClient";
376}
377
378sal_Bool OleClient::supportsService(OUString const & ServiceName)
379{
381}
382
383css::uno::Sequence<OUString> OleClient::getSupportedServiceNames()
384{
385 return css::uno::Sequence<OUString>{
386 "com.sun.star.bridge.OleObjectFactory",
387 "com.sun.star.bridge.oleautomation.Factory"};
388}
389
390Reference<XInterface> SAL_CALL OleClient::createInstance(const OUString& ServiceSpecifier)
391{
393 HRESULT result;
394 IUnknown* pUnknown = nullptr;
395 CLSID classId;
396
398
399 result = CLSIDFromProgID(
400 o3tl::toW(ServiceSpecifier.getStr()), //Pointer to the ProgID
401 &classId); //Pointer to the CLSID
402
403
404 if (result == NOERROR)
405 {
406 result = CoCreateInstance(
407 classId, //Class identifier (CLSID) of the object
408 nullptr, //Pointer to whether object is or isn't part of an aggregate
409 CLSCTX_SERVER, //Context for running executable code
410 IID_IUnknown, //Reference to the identifier of the interface
411 reinterpret_cast<void**>(&pUnknown)); //Address of output variable that receives
412 // the interface pointer requested in riid
413 }
414
415 if (pUnknown != nullptr)
416 {
417 Any any;
418 CComVariant variant;
419
420 V_VT(&variant) = VT_UNKNOWN;
421 V_UNKNOWN(&variant) = pUnknown;
422 // AddRef for Variant
423 pUnknown->AddRef();
424
425 // When the object is wrapped, then its refcount is increased
426 variantToAny(&variant, any);
427 if (any.getValueTypeClass() == TypeClass_INTERFACE)
428 {
429 any >>= ret;
430 }
431 pUnknown->Release(); // CoCreateInstance
432 }
433
434 return ret;
435}
436
437Reference<XInterface> SAL_CALL OleClient::createInstanceWithArguments(const OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/)
438{
439 return createInstance( ServiceSpecifier);
440}
441
442// UnoConversionUtilities -----------------------------------------------------------------------------
444{
446 {
447 Reference<XWeak> xWeak= static_cast<XWeak*>( new InterfaceOleWrapper(
449 return Reference<XInterface>( xWeak, UNO_QUERY);
450 }
452 {
453 Reference<XWeak> xWeak= static_cast<XWeak*>( new UnoObjectWrapperRemoteOpt(
455 return Reference<XInterface>( xWeak, UNO_QUERY);
456 }
457 else
458 return Reference< XInterface>();
459}
460// UnoConversionUtilities -----------------------------------------------------------------------------
462{
463 Reference<XWeak> xWeak= static_cast<XWeak*>( new IUnknownWrapper(
465 return Reference<XInterface>( xWeak, UNO_QUERY);
466}
467
469 m_smgr( smgr)
470{
471 Reference<XInterface> xInt = m_smgr->createInstance("com.sun.star.bridge.oleautomation.BridgeSupplier");
472
473 if (xInt.is())
474 {
475 Any a= xInt->queryInterface( cppu::UnoType<XBridgeSupplier2>::get() );
477 }
478
479 (void) provideInstance( [&]
480 {
481 return m_smgr;
482 },
483 &OID_ServiceManager );
484
485 (void) provideInstance( [&]
486 {
487 // We want just one SwVbaGlobals for all Automation clients
488 static const Reference<XInterface> xWordGlobals = m_smgr->createInstance("ooo.vba.word.Globals");
489 const Reference<ooo::vba::XHelperInterface> xHelperInterface(xWordGlobals, UNO_QUERY);
490 Any aApplication = xHelperInterface->Application();
491 Reference<XInterface> xApplication;
492 aApplication >>= xApplication;
493 return xApplication;
494 },
495 &OID_LibreOfficeWriterApplication );
496
497 (void) provideInstance( [&]
498 {
499 // Ditto for sc
500 static const Reference<XInterface> xCalcGlobals = m_smgr->createInstance("ooo.vba.excel.Globals");
501 const Reference<ooo::vba::XHelperInterface> xHelperInterface(xCalcGlobals, UNO_QUERY);
502 Any aApplication = xHelperInterface->Application();
503 Reference<XInterface> xApplication;
504 aApplication >>= xApplication;
505 return xApplication;
506 },
507 &OID_LibreOfficeCalcApplication );
508}
509
511{
512 for (auto const& elem : m_wrapperList)
513 {
514 elem->deregisterClass();
515 elem->Release();
516 }
517 m_wrapperList.clear();
518}
519
521{
522 return "com.sun.star.comp.ole.OleServer";
523}
524
525sal_Bool OleServer::supportsService(OUString const & ServiceName)
526{
528}
529
530css::uno::Sequence<OUString> OleServer::getSupportedServiceNames()
531{
532 return css::uno::Sequence<OUString>{
533 "com.sun.star.bridge.OleApplicationRegistration",
534 "com.sun.star.bridge.oleautomation.ApplicationRegistration"};
535}
536
537bool OleServer::provideInstance(std::function<const Reference<XInterface>()> xInstFunction, GUID const * guid)
538{
539 OneInstanceOleWrapper* pWrapper = new OneInstanceOleWrapper( m_smgr, xInstFunction );
540
541 pWrapper->AddRef();
542 m_wrapperList.push_back(pWrapper);
543
544 return pWrapper->registerClass(guid);
545}
546
547/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const Any & any
~OleClient() override
Definition: servprov.cxx:362
Reference< XBridgeSupplier2 > m_bridgeSupplier
Definition: servprov.hxx:149
Reference< XInterface > createComWrapperInstance() override
Definition: servprov.cxx:461
Reference< XInterface > SAL_CALL createInstance(const OUString &ServiceSpecifier) override
Definition: servprov.cxx:390
Sequence< OUString > SAL_CALL getAvailableServiceNames() override
Definition: servprov.cxx:366
Reference< XInterface > createUnoWrapperInstance() override
Definition: servprov.cxx:443
sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
Definition: servprov.cxx:378
Reference< XInterface > SAL_CALL createInstanceWithArguments(const OUString &ServiceSpecifier, const Sequence< Any > &Arguments) override
Definition: servprov.cxx:437
OleClient(const Reference< XMultiServiceFactory > &smgr)
Definition: servprov.cxx:350
OUString SAL_CALL getImplementationName() override
Definition: servprov.cxx:373
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: servprov.cxx:383
Any SAL_CALL createBridge(const Any &modelDepObject, const Sequence< sal_Int8 > &ProcessId, sal_Int16 sourceModelType, sal_Int16 destModelType) override
Definition: servprov.cxx:202
Reference< XInterface > createComWrapperInstance() override
Definition: servprov.cxx:343
OUString SAL_CALL getImplementationName() override
Definition: servprov.cxx:288
virtual ~OleConverter() override
Definition: servprov.cxx:197
sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
Definition: servprov.cxx:295
OleConverter(const Reference< XMultiServiceFactory > &smgr)
Definition: servprov.cxx:184
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: servprov.cxx:300
Reference< XInterface > createUnoWrapperInstance() override
Definition: servprov.cxx:325
void SAL_CALL initialize(const Sequence< Any > &aArguments) override
Definition: servprov.cxx:313
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: servprov.cxx:530
std::list< OneInstanceOleWrapper * > m_wrapperList
Definition: servprov.hxx:178
bool provideInstance(std::function< const Reference< XInterface >()> xInstFunction, GUID const *guid)
Definition: servprov.cxx:537
~OleServer() override
Definition: servprov.cxx:510
Reference< XBridgeSupplier2 > m_bridgeSupplier
Definition: servprov.hxx:179
OleServer(const Reference< XMultiServiceFactory > &smgr)
Definition: servprov.cxx:468
OUString SAL_CALL getImplementationName() override
Definition: servprov.cxx:520
Reference< XMultiServiceFactory > m_smgr
Definition: servprov.hxx:181
sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
Definition: servprov.cxx:525
Reference< XBridgeSupplier2 > m_bridgeSupplier
Definition: servprov.hxx:78
bool registerClass(GUID const *pGuid)
Definition: servprov.cxx:81
virtual ~OneInstanceOleWrapper()
Definition: servprov.cxx:77
OneInstanceOleWrapper(const Reference< XMultiServiceFactory > &smgr, std::function< const Reference< XInterface >()> xInstFunction)
Definition: servprov.cxx:61
STDMETHOD() CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv) override
Definition: servprov.cxx:140
Reference< XMultiServiceFactory > m_smgr
Definition: servprov.hxx:79
STDMETHOD() QueryInterface(REFIID riid, void **ppvObj) override
Definition: servprov.cxx:104
STDMETHOD() LockServer(BOOL fLock) override
Definition: servprov.cxx:179
std::function< const Reference< XInterface >()> m_xInstFunction
Definition: servprov.hxx:76
oslInterlockedCount m_refCount
Definition: servprov.hxx:75
All methods are allowed to throw at least a BridgeRuntimeError.
void anyToVariant(VARIANT *pVariant, const Any &rAny)
converts only into oleautomation types, that is there is no VT_I1, VT_UI2, VT_UI4 a sal_Unicode chara...
void variantToAny(const VARIANT *pVariant, Any &rAny, bool bReduceValueRange=true)
Reference< XMultiServiceFactory > m_smgr
Reference< XMultiServiceFactory > m_smgrRemote
ULONG m_refCount
float v
Sequence< PropertyValue > aArguments
uno_Any a
#define SAL_INFO(area, stream)
MetadataImporterPluginType * result
Definition: main.m:195
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
void o2u_attachCurrentThread()
Definition: olethread.cxx:26
const wchar_t *typedef BOOL
DEFINE_GUID(OID_ServiceManager, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4)
COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) OneInstanceOleWrapper
Definition: servprov.cxx:123
unsigned char sal_uInt8
unsigned char sal_Bool
signed char sal_Int8
#define UNO_OBJECT_WRAPPER_REMOTE_OPT
#define INTERFACE_OLE_WRAPPER_IMPL