diff options
-rw-r--r-- | extensions/Library_oleautobridge.mk | 1 | ||||
-rw-r--r-- | extensions/source/ole/unoobjw.cxx | 59 |
2 files changed, 60 insertions, 0 deletions
diff --git a/extensions/Library_oleautobridge.mk b/extensions/Library_oleautobridge.mk index ec59f715c504..6aaf5555e250 100644 --- a/extensions/Library_oleautobridge.mk +++ b/extensions/Library_oleautobridge.mk @@ -35,6 +35,7 @@ $(eval $(call gb_Library_use_libraries,oleautobridge,\ cppuhelper \ cppu \ sal \ + tl \ )) $(eval $(call gb_Library_use_system_win32_libs,oleautobridge,\ diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx index 669fe9af36c3..3c8313e4c83e 100644 --- a/extensions/source/ole/unoobjw.cxx +++ b/extensions/source/ole/unoobjw.cxx @@ -56,9 +56,13 @@ #include <osl/diagnose.h> #include <salhelper/simplereferenceobject.hxx> #include <rtl/ustring.hxx> +#include <tools/diagnose_ex.h> #include <sal/log.hxx> #include <com/sun/star/beans/MethodConcept.hpp> #include <com/sun/star/beans/PropertyConcept.hpp> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/frame/TerminationVetoException.hpp> +#include <com/sun/star/frame/XTerminateListener.hpp> #include <com/sun/star/lang/NoSuchMethodException.hpp> #include <com/sun/star/script/CannotConvertException.hpp> #include <com/sun/star/script/FailReason.hpp> @@ -110,6 +114,58 @@ static bool writeBackOutParameter(VARIANTARG* pDest, VARIANT* pSource); static bool writeBackOutParameter2( VARIANTARG* pDest, VARIANT* pSource); static HRESULT mapCannotConvertException(const CannotConvertException &e, unsigned int * puArgErr); +class TerminationVetoer : public WeakImplHelper<css::frame::XTerminateListener> +{ +public: + int mnCount; + +private: + TerminationVetoer() + : mnCount(0) + { + try + { + Reference< css::frame::XDesktop > xDesktop = + css::frame::Desktop::create( comphelper::getProcessComponentContext() ); + xDesktop->addTerminateListener( this ); + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("extensions.ole"); + } + } + +public: + static Reference< TerminationVetoer > get() + { + static TerminationVetoer* pInstance = new TerminationVetoer; + static Reference< TerminationVetoer > aInstance( pInstance ); + + return aInstance; + } + + // XTerminateListener + void SAL_CALL queryTermination( const EventObject& ) override + { + // Always veto termination while an OLE object is active + if (mnCount > 0) + { + throw css::frame::TerminationVetoException(); + } + } + + void SAL_CALL notifyTermination( const EventObject& ) override + { + // ??? + } + + // XEventListener + void SAL_CALL disposing( const css::lang::EventObject& ) override + { + // ??? + } +}; + /* Does not throw any exceptions. Param pInfo can be NULL. */ @@ -128,6 +184,7 @@ InterfaceOleWrapper::InterfaceOleWrapper( Reference<XMultiServiceFactory> const UnoConversionUtilities<InterfaceOleWrapper>( xFactory, unoWrapperClass, comWrapperClass), m_defaultValueType( 0) { + TerminationVetoer::get()->mnCount++; } InterfaceOleWrapper::~InterfaceOleWrapper() @@ -137,6 +194,8 @@ InterfaceOleWrapper::~InterfaceOleWrapper() auto it = UnoObjToWrapperMap.find( reinterpret_cast<sal_uIntPtr>(m_xOrigin.get())); if(it != UnoObjToWrapperMap.end()) UnoObjToWrapperMap.erase(it); + + TerminationVetoer::get()->mnCount--; } STDMETHODIMP InterfaceOleWrapper::QueryInterface(REFIID riid, void ** ppv) |