diff options
Diffstat (limited to 'embedserv/source/inprocserv')
-rw-r--r-- | embedserv/source/inprocserv/advisesink.cxx | 168 | ||||
-rw-r--r-- | embedserv/source/inprocserv/advisesink.hxx | 100 | ||||
-rw-r--r-- | embedserv/source/inprocserv/dllentry.cxx | 337 | ||||
-rw-r--r-- | embedserv/source/inprocserv/inprocembobj.cxx | 1703 | ||||
-rw-r--r-- | embedserv/source/inprocserv/inprocembobj.h | 233 | ||||
-rw-r--r-- | embedserv/source/inprocserv/inprocserv.def | 5 |
6 files changed, 2546 insertions, 0 deletions
diff --git a/embedserv/source/inprocserv/advisesink.cxx b/embedserv/source/inprocserv/advisesink.cxx new file mode 100644 index 0000000000..f06cffbf62 --- /dev/null +++ b/embedserv/source/inprocserv/advisesink.cxx @@ -0,0 +1,168 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include "advisesink.hxx" + +namespace inprocserv +{ + +OleWrapperAdviseSink::OleWrapperAdviseSink() +: m_nRefCount( 0 ) +, m_nAspect( DVASPECT_CONTENT ) +, m_nRegID( 0 ) +, m_bObjectAdvise( TRUE ) +, m_nDataRegFlag( 0 ) +, m_nViewRegFlag( 0 ) +, m_bHandleClosed( TRUE ) +, m_bClosed( FALSE ) +{ +} + +OleWrapperAdviseSink::OleWrapperAdviseSink( const sal::systools::COMReference< IAdviseSink >& pListener ) +: m_nRefCount( 0 ) +, m_pListener( pListener ) +, m_nAspect( DVASPECT_CONTENT ) +, m_nRegID( 0 ) +, m_bObjectAdvise( TRUE ) +, m_nDataRegFlag( 0 ) +, m_nViewRegFlag( 0 ) +, m_bHandleClosed( FALSE ) +, m_bClosed( FALSE ) +{ +} + +OleWrapperAdviseSink::OleWrapperAdviseSink( const sal::systools::COMReference< IAdviseSink >& pListener, FORMATETC* pFormatEtc, DWORD nDataRegFlag ) +: m_nRefCount( 0 ) +, m_pListener( pListener ) +, m_nAspect( DVASPECT_CONTENT ) +, m_nRegID( 0 ) +, m_bObjectAdvise( FALSE ) +, m_nDataRegFlag( nDataRegFlag ) +, m_nViewRegFlag( 0 ) +, m_bHandleClosed( FALSE ) +, m_bClosed( FALSE ) +{ + if ( pFormatEtc ) + { + m_pFormatEtc = std::make_unique<FORMATETC>(); + m_pFormatEtc->cfFormat = pFormatEtc->cfFormat; + m_pFormatEtc->ptd = nullptr; + m_pFormatEtc->dwAspect = pFormatEtc->dwAspect; + m_pFormatEtc->lindex = pFormatEtc->lindex; + m_pFormatEtc->tymed = pFormatEtc->tymed; + } +} + +OleWrapperAdviseSink::OleWrapperAdviseSink( const sal::systools::COMReference< IAdviseSink >& pListener, DWORD nAspect, DWORD nViewRegFlag ) +: m_nRefCount( 0 ) +, m_pListener( pListener ) +, m_nAspect( nAspect ) +, m_nRegID( 0 ) +, m_bObjectAdvise( TRUE ) +, m_nDataRegFlag( 0 ) +, m_nViewRegFlag( nViewRegFlag ) +, m_bHandleClosed( FALSE ) +, m_bClosed( FALSE ) +{ +} + +OleWrapperAdviseSink::~OleWrapperAdviseSink() +{} + +STDMETHODIMP OleWrapperAdviseSink::QueryInterface( REFIID riid , void** ppv ) +{ + *ppv=nullptr; + + if ( riid == IID_IUnknown ) + *ppv = static_cast<IUnknown*>(this); + + if ( riid == IID_IAdviseSink ) + *ppv = static_cast<IAdviseSink*>(this); + + if ( *ppv != nullptr ) + { + static_cast<IUnknown*>(*ppv)->AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +STDMETHODIMP_(ULONG) OleWrapperAdviseSink::AddRef() +{ + return ++m_nRefCount; +} + +STDMETHODIMP_(ULONG) OleWrapperAdviseSink::Release() +{ + ULONG nReturn = --m_nRefCount; + if ( m_nRefCount == 0 ) + delete this; + + return nReturn; +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnDataChange( FORMATETC * pFetc, STGMEDIUM * pMedium ) +{ + if ( m_pListener ) + { + m_pListener->OnDataChange( pFetc, pMedium ); + } +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnViewChange( DWORD dwAspect, LONG lindex ) +{ + if ( m_pListener ) + { + m_pListener->OnViewChange( dwAspect, lindex ); + } +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnRename( IMoniker * pMoniker ) +{ + if ( m_pListener ) + { + m_pListener->OnRename( pMoniker ); + } +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnSave() +{ + if ( m_pListener ) + { + m_pListener->OnSave(); + } +} + +STDMETHODIMP_(void) OleWrapperAdviseSink::OnClose() +{ + if ( m_pListener ) + { + m_pListener->OnClose(); + } + + if ( m_bHandleClosed ) + m_bClosed = TRUE; +} + +} // namespace inprocserv + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/embedserv/source/inprocserv/advisesink.hxx b/embedserv/source/inprocserv/advisesink.hxx new file mode 100644 index 0000000000..525a655087 --- /dev/null +++ b/embedserv/source/inprocserv/advisesink.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +#include <memory> + +#if !defined WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <objidl.h> +#include <systools/win32/comtools.hxx> + +namespace inprocserv +{ +class OleWrapperAdviseSink : public IAdviseSink +{ +protected: + ULONG m_nRefCount; + + sal::systools::COMReference<IAdviseSink> m_pListener; + DWORD m_nListenerID; + + std::unique_ptr<FORMATETC> m_pFormatEtc; + DWORD m_nAspect; + + DWORD m_nRegID; + DWORD m_bObjectAdvise; + DWORD m_nDataRegFlag; + DWORD m_nViewRegFlag; + + BOOL m_bHandleClosed; + BOOL m_bClosed; + +public: + // an AdviseSink for own needs, should be created always + OleWrapperAdviseSink(); + + // an AdviseSink for IOleObject interface + explicit OleWrapperAdviseSink(const sal::systools::COMReference<IAdviseSink>& pListener); + + // an AdviseSink for IDataObject interface + OleWrapperAdviseSink(const sal::systools::COMReference<IAdviseSink>& pListener, + FORMATETC* pFormatEtc, DWORD nDataRegFlag); + + // an AdviseSink for IViewObject interface + OleWrapperAdviseSink(const sal::systools::COMReference<IAdviseSink>& pListener, DWORD nAspect, + DWORD nViewRegFlag); + + virtual ~OleWrapperAdviseSink(); + + void SetRegID(DWORD nRegID) { m_nRegID = nRegID; } + DWORD GetRegID() { return m_nRegID; } + + bool IsOleAdvise() { return m_bObjectAdvise; } + DWORD GetDataAdviseFlag() { return m_nDataRegFlag; } + DWORD GetViewAdviseFlag() { return m_nViewRegFlag; } + + FORMATETC* GetFormatEtc() { return m_pFormatEtc.get(); } + DWORD GetAspect() { return m_nAspect; } + sal::systools::COMReference<IAdviseSink>& GetOrigAdvise() { return m_pListener; } + void DisconnectOrigAdvise() { m_pListener = nullptr; } + + void SetClosed() { m_bClosed = TRUE; } + void UnsetClosed() { m_bClosed = FALSE; } + BOOL IsClosed() { return m_bClosed; } + + STDMETHODIMP QueryInterface(REFIID, void**) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + STDMETHODIMP_(void) OnDataChange(FORMATETC*, STGMEDIUM*) override; + STDMETHODIMP_(void) OnViewChange(DWORD, LONG) override; + STDMETHODIMP_(void) OnRename(IMoniker*) override; + STDMETHODIMP_(void) OnSave() override; + STDMETHODIMP_(void) OnClose() override; +}; + +}; // namespace advisesink + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/embedserv/source/inprocserv/dllentry.cxx b/embedserv/source/inprocserv/dllentry.cxx new file mode 100644 index 0000000000..12dee7b0cc --- /dev/null +++ b/embedserv/source/inprocserv/dllentry.cxx @@ -0,0 +1,337 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/types.h> + +#include <stdio.h> +#include "inprocembobj.h" +#include <embservconst.h> + +#include <olectl.h> // declarations of DllRegisterServer/DllUnregisterServer + +static const GUID* guidList[ SUPPORTED_FACTORIES_NUM ] = { + &OID_WriterTextServer, + &OID_WriterOASISTextServer, + &OID_CalcServer, + &OID_CalcOASISServer, + &OID_DrawingServer, + &OID_DrawingOASISServer, + &OID_PresentationServer, + &OID_PresentationOASISServer, + &OID_MathServer, + &OID_MathOASISServer +}; + +static HINSTANCE g_hInstance = nullptr; +static ULONG g_nObj = 0; +static ULONG g_nLock = 0; + + +namespace { + void FillCharFromInt( int nValue, wchar_t* pBuf, int nLen ) + { + int nInd = 0; + while( nInd < nLen ) + { + char nSign = ( nValue / ( 1 << ( ( nLen - nInd - 1 ) * 4 ) ) ) % 16; + if ( nSign >= 0 && nSign <= 9 ) + pBuf[nInd] = nSign + L'0'; + else if (nSign >= 10) + pBuf[nInd] = nSign - 10 + L'a'; + + nInd++; + } + } + + int GetStringFromClassID( const GUID& guid, wchar_t* pBuf, int nLen ) + { + // is not allowed to insert + if ( nLen < 38 ) + return 0; + + pBuf[0] = L'{'; + FillCharFromInt( guid.Data1, &pBuf[1], 8 ); + pBuf[9] = L'-'; + FillCharFromInt( guid.Data2, &pBuf[10], 4 ); + pBuf[14] = L'-'; + FillCharFromInt( guid.Data3, &pBuf[15], 4 ); + pBuf[19] = L'-'; + + int nInd = 0; + for ( nInd = 0; nInd < 2 ; nInd++ ) + FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 2*nInd], 2 ); + pBuf[24] = L'-'; + for ( nInd = 2; nInd < 8 ; nInd++ ) + FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 1 + 2*nInd], 2 ); + pBuf[37] = L'}'; + + return 38; + } + + HRESULT WriteLibraryToRegistry( const wchar_t* pLibrary, DWORD nLen ) + { + HRESULT hRes = E_FAIL; + if ( pLibrary && nLen ) + { + HKEY hKey = nullptr; + + hRes = S_OK; + for ( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ ) + { + const wchar_t pSubKeyTemplate[] = L"Software\\Classes\\CLSID\\.....................................\\InprocHandler32"; + wchar_t pSubKey[std::size(pSubKeyTemplate)]; + wcsncpy(pSubKey, pSubKeyTemplate, std::size(pSubKeyTemplate)); + + int nGuidLen = GetStringFromClassID( *guidList[nInd], &pSubKey[23], 38 ); + + bool bLocalSuccess = false; + if ( nGuidLen == 38 ) + { + if ( ERROR_SUCCESS == RegOpenKeyW( HKEY_LOCAL_MACHINE, pSubKey, &hKey ) ) + { + if ( ERROR_SUCCESS == RegSetValueExW( hKey, L"", 0, REG_SZ, reinterpret_cast<const BYTE*>(pLibrary), nLen*sizeof(wchar_t) ) ) + bLocalSuccess = true; + } + + if ( hKey ) + { + RegCloseKey( hKey ); + hKey = nullptr; + } + } + + if ( !bLocalSuccess ) + hRes = E_FAIL; + } + } + + return hRes; + } +}; + + +// InprocEmbedProvider_Impl declaration + + +namespace inprocserv +{ + +namespace { + +class InprocEmbedProvider_Impl : public IClassFactory, public InprocCountedObject_Impl +{ +public: + + explicit InprocEmbedProvider_Impl( const GUID& guid ); + virtual ~InprocEmbedProvider_Impl(); + + /* IUnknown methods */ + STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj) override; + STDMETHOD_(ULONG, AddRef)() override; + STDMETHOD_(ULONG, Release)() override; + + /* IClassFactory methods */ + STDMETHOD(CreateInstance)(IUnknown* punkOuter, REFIID riid, void** ppv) override; + STDMETHOD(LockServer)(BOOL fLock) override; + +protected: + + ULONG m_refCount; + GUID m_guid; +}; + +} + +}; // namespace inprocserv + + +// Entry points + + +extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/ ) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + } + + return TRUE; // ok +} + + +STDAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID* ppv ) +{ + for( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ ) + if ( *guidList[nInd] == rclsid ) + { + if ( !IsEqualIID( riid, IID_IUnknown ) && !IsEqualIID( riid, IID_IClassFactory ) ) + return E_NOINTERFACE; + + *ppv = new inprocserv::InprocEmbedProvider_Impl( rclsid ); + static_cast<LPUNKNOWN>(*ppv)->AddRef(); + return S_OK; + } + + return E_FAIL; +} + + +STDAPI DllCanUnloadNow() +{ + if ( !g_nObj && !g_nLock ) + return S_OK; + + return S_FALSE; +} + + +STDAPI DllRegisterServer() +{ + HMODULE aCurModule{}; + GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS + | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast<LPCWSTR>(&DllRegisterServer), &aCurModule); + if( aCurModule ) + { + wchar_t aLibPath[1024]; + DWORD nLen = GetModuleFileNameW( aCurModule, aLibPath, 1019 ); + if ( nLen && nLen < 1019 ) + { + aLibPath[nLen++] = 0; + return WriteLibraryToRegistry( aLibPath, nLen ); + } + } + + return E_FAIL; +} + + +STDAPI DllUnregisterServer() +{ + return WriteLibraryToRegistry( L"ole32.dll", 10 ); +} + + +// End of entry points + + +namespace inprocserv +{ + + +// InprocCountedObject_Impl implementation + + +InprocCountedObject_Impl::InprocCountedObject_Impl() +{ + g_nObj++; +} + + +InprocCountedObject_Impl::~InprocCountedObject_Impl() +{ + g_nObj--; +} + + +// InprocEmbedProvider_Impl implementation + + +InprocEmbedProvider_Impl::InprocEmbedProvider_Impl( const GUID& guid ) +: m_refCount( 0 ) +, m_guid( guid ) +{ +} + + +InprocEmbedProvider_Impl::~InprocEmbedProvider_Impl() +{ +} + +// IUnknown + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedProvider_Impl::QueryInterface( REFIID riid, void ** ppv ) +{ + if(IsEqualIID(riid, IID_IUnknown)) + { + AddRef(); + *ppv = static_cast<IUnknown*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IClassFactory)) + { + AddRef(); + *ppv = static_cast<IClassFactory*>(this); + return S_OK; + } + + *ppv = nullptr; + return E_NOINTERFACE; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::AddRef() +{ + return ++m_refCount; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::Release() +{ + sal_Int32 nCount = --m_refCount; + if ( nCount == 0 ) + delete this; + return nCount; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedProvider_Impl::CreateInstance(IUnknown* punkOuter, + REFIID riid, void** ppv) +{ + // TODO/LATER: should the aggregation be supported? + // if ( punkOuter != NULL && riid != IID_IUnknown ) + // return E_NOINTERFACE; + if ( punkOuter != nullptr ) + return CLASS_E_NOAGGREGATION; + + InprocEmbedDocument_Impl* pEmbedDocument = new InprocEmbedDocument_Impl( m_guid ); + pEmbedDocument->AddRef(); + HRESULT hr = pEmbedDocument->QueryInterface( riid, ppv ); + pEmbedDocument->Release(); + + if ( !SUCCEEDED( hr ) ) + *ppv = nullptr; + + return hr; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedProvider_Impl::LockServer( BOOL fLock ) +{ + if ( fLock ) + g_nLock++; + else + g_nLock--; + + return S_OK; +} + +}; // namespace inprocserv + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/embedserv/source/inprocserv/inprocembobj.cxx b/embedserv/source/inprocserv/inprocembobj.cxx new file mode 100644 index 0000000000..b7bf89b667 --- /dev/null +++ b/embedserv/source/inprocserv/inprocembobj.cxx @@ -0,0 +1,1703 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/types.h> + +#include <embservconst.h> +#include "inprocembobj.h" + +namespace inprocserv +{ + +namespace { + +class ULONGGuard +{ + ULONG& m_rValue; + +public: + explicit ULONGGuard( ULONG& rValue ) + : m_rValue( ++rValue ) + { + } + + ~ULONGGuard() { --m_rValue; } +}; + +void SetName( LPCOLESTR pszNameFromOutside, wchar_t*& pOwnName ) +{ + if ( !pszNameFromOutside ) + return; + + // copy the string + size_t nLen = 0; + while( pszNameFromOutside[nLen] != 0 ) + nLen++; + + if ( pOwnName ) + { + delete[] pOwnName; + pOwnName = nullptr; + } + + pOwnName = new wchar_t[nLen+1]; + for ( size_t nInd = 0; nInd < nLen; nInd++ ) + pOwnName[nInd] = pszNameFromOutside[nInd]; + pOwnName[nLen] = 0; +} + +DWORD InsertAdviseLinkToList( const sal::systools::COMReference<OleWrapperAdviseSink>& pOwnAdvise, sal::systools::COMReference< OleWrapperAdviseSink > pAdvises[] ) +{ + // the result should start from 1 in case of success, the element 0 can be used for own needs + DWORD nResult = 0; + + if ( pOwnAdvise ) + { + for ( DWORD nInd = 1; nInd < DEFAULT_ARRAY_LEN && nResult == 0; nInd++ ) + { + if ( pAdvises[nInd].get() == pOwnAdvise.get() ) + { + nResult = nInd; + } + else if ( pAdvises[nInd] == nullptr ) + { + pAdvises[nInd] = pOwnAdvise; + nResult = nInd; + } + } + } + + return nResult; +} + +} + +BOOL InprocEmbedDocument_Impl::CheckDefHandler() +{ + // set the own listener + if ( m_pOleAdvises[0] == nullptr ) + { + m_pOleAdvises[0] = new OleWrapperAdviseSink(); + } + else + { + if ( m_pOleAdvises[0]->IsClosed() ) + { + if ( m_pDefHandler ) + { + // deregister all the listeners + + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + if ( pOleObject ) + { + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + if ( m_pOleAdvises[nInd] ) + { + DWORD nID = m_pOleAdvises[nInd]->GetRegID(); + pOleObject->Unadvise( nID ); + m_pOleAdvises[nInd]->SetRegID( 0 ); + } + + pOleObject->SetClientSite( nullptr ); + } + + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + if ( pIDataObject ) + { + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + if ( m_pDataAdvises[nInd] ) + { + DWORD nID = m_pDataAdvises[nInd]->GetRegID(); + pIDataObject->DUnadvise( nID ); + m_pDataAdvises[nInd]->SetRegID( 0 ); + } + } + + sal::systools::COMReference< IViewObject > pIViewObject(m_pDefHandler, sal::systools::COM_QUERY); + if ( pIViewObject ) + { + if ( m_pViewAdvise ) + pIViewObject->SetAdvise( m_pViewAdvise->GetAspect(), m_pViewAdvise->GetViewAdviseFlag(), nullptr ); + } + + sal::systools::COMReference< IPersistStorage > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + if ( pPersist ) + { + // disconnect the old wrapper from the storage + pPersist->HandsOffStorage(); + } + + m_pDefHandler = nullptr; + } + + m_pOleAdvises[0]->UnsetClosed(); + } + } + + if ( m_nCallsOnStack ) + return FALSE; + + if ( !m_pDefHandler ) + { + // create a new default inprocess handler + HRESULT hr = OleCreateDefaultHandler( m_guid, nullptr, IID_IUnknown, reinterpret_cast<void**>(&m_pDefHandler) ); + if ( SUCCEEDED( hr ) ) + { + if ( m_nInitMode == INIT_FROM_STORAGE ) + { + sal::systools::COMReference< IPersistStorage > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist && m_pStorage ) + hr = pPersist->InitNew( m_pStorage.get() ); + } + else if ( m_nInitMode == LOAD_FROM_STORAGE ) + { + sal::systools::COMReference< IPersistStorage > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist && m_pStorage ) + hr = pPersist->Load( m_pStorage.get() ); + } + else if ( m_nInitMode == LOAD_FROM_FILE ) + { + sal::systools::COMReference< IPersistFile > pPersistFile(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersistFile && m_pFileName ) + hr = pPersistFile->Load( m_pFileName, m_nFileOpenMode ); + } + } + + if ( !SUCCEEDED( hr ) || !m_pDefHandler ) + { + m_pDefHandler = nullptr; + return FALSE; + } + + // register all the listeners new + + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + if ( pOleObject ) + { + if ( m_pClientSite ) + pOleObject->SetClientSite( m_pClientSite.get() ); + + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + if ( m_pOleAdvises[nInd] ) + { + DWORD nRegID = 0; + if ( SUCCEEDED( pOleObject->Advise( m_pOleAdvises[nInd].get(), &nRegID ) ) && nRegID > 0 ) + m_pOleAdvises[nInd]->SetRegID( nRegID ); + } + } + + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + if ( pIDataObject ) + { + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + if ( m_pDataAdvises[nInd] ) + { + DWORD nRegID = 0; + if ( SUCCEEDED( pIDataObject->DAdvise( m_pDataAdvises[nInd]->GetFormatEtc(), m_pDataAdvises[nInd]->GetDataAdviseFlag(), m_pDataAdvises[nInd].get(), &nRegID ) ) && nRegID > 0 ) + m_pDataAdvises[nInd]->SetRegID( nRegID ); + } + } + + sal::systools::COMReference< IViewObject > pIViewObject(m_pDefHandler, sal::systools::COM_QUERY); + if ( pIViewObject ) + { + if ( m_pViewAdvise ) + pIViewObject->SetAdvise( m_pViewAdvise->GetAspect(), m_pViewAdvise->GetViewAdviseFlag(), m_pViewAdvise.get() ); + } + } + + + return TRUE; +} + +void InprocEmbedDocument_Impl::Clean() +{ + m_pDefHandler = nullptr; + + // no DisconnectOrigAdvise() call here, since it is no explicit disconnection + for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ ) + { + m_pOleAdvises[nInd].clear(); + m_pDataAdvises[nInd].clear(); + } + + m_pViewAdvise = nullptr; + + m_nInitMode = NOINIT; + m_pStorage = nullptr; + + if ( m_pOleContainer ) + { + m_pOleContainer->LockContainer( FALSE ); + m_pOleContainer = nullptr; + } + + m_pClientSite = nullptr; + + m_nFileOpenMode = 0; + if ( m_pFileName ) + { + delete m_pFileName; + m_pFileName = nullptr; + } +} + +// IUnknown + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::QueryInterface(REFIID riid, void** ppv) +{ + if(IsEqualIID(riid, IID_IUnknown)) + { + AddRef(); + *ppv = static_cast<IUnknown*>(static_cast<IPersistStorage*>(this)); + return S_OK; + } + else if (IsEqualIID(riid, IID_IPersist)) + { + AddRef(); + *ppv = static_cast<IPersist*>(static_cast<IPersistStorage*>(this)); + return S_OK; + } + else if (IsEqualIID(riid, IID_IPersistStorage)) + { + AddRef(); + *ppv = static_cast<IPersistStorage*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IDataObject)) + { + AddRef(); + *ppv = static_cast<IDataObject*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleObject)) + { + AddRef(); + *ppv = static_cast<IOleObject*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IPersistFile)) + { + AddRef(); + *ppv = static_cast<IPersistFile*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IRunnableObject)) + { + AddRef(); + *ppv = static_cast<IRunnableObject*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IViewObject)) + { + AddRef(); + *ppv = static_cast<IViewObject*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IViewObject2)) + { + AddRef(); + *ppv = static_cast<IViewObject2*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleCache)) + { + AddRef(); + *ppv = static_cast<IOleCache*>(&m_aInternalCache); + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleCache2)) + { + AddRef(); + *ppv = static_cast<IOleCache2*>(&m_aInternalCache); + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleWindow)) + { + AddRef(); + *ppv = static_cast<IOleWindow*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IOleInPlaceObject)) + { + AddRef(); + *ppv = static_cast<IOleInPlaceObject*>(this); + return S_OK; + } + else if (IsEqualIID(riid, IID_IDispatch)) + { + AddRef(); + *ppv = static_cast<IDispatch*>(this); + return S_OK; + } + + *ppv = nullptr; + return ResultFromScode(E_NOINTERFACE); +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::AddRef() +{ + return ++m_refCount; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::Release() +{ + // unfortunately there are reentrance problems in mfc that have to be workarounded + sal_Int32 nCount = m_refCount > 0 ? --m_refCount : 0; + if ( nCount == 0 && !m_bDeleted ) + { + // deleting of this object can trigger deleting of mfc objects that will try to delete this object one more time + m_bDeleted = TRUE; + + Clean(); + delete this; + } + return nCount; +} + +// IPersist + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetClassID( CLSID* pClassId ) +{ + *pClassId = m_guid; + return S_OK; +} + +// IPersistStorage + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::IsDirty() +{ + if ( m_pDefHandler == nullptr || m_pOleAdvises[0] == nullptr || m_pOleAdvises[0]->IsClosed() ) + return S_FALSE; + + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IPersistStorage > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + return pPersist->IsDirty(); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InitNew( IStorage *pStg ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IPersistStorage > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + { + HRESULT hr = pPersist->InitNew( pStg ); + if ( SUCCEEDED( hr ) ) + { + m_nInitMode = INIT_FROM_STORAGE; + m_pStorage = pStg; + + m_nFileOpenMode = 0; + if ( m_pFileName ) + { + delete[] m_pFileName; + m_pFileName = nullptr; + } + } + + return hr; + } + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Load( IStorage *pStg ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IPersistStorage > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + { + HRESULT hr = pPersist->Load( pStg ); + if ( SUCCEEDED( hr ) ) + { + m_nInitMode = LOAD_FROM_STORAGE; + m_pStorage = pStg; + + m_nFileOpenMode = 0; + if ( m_pFileName ) + { + delete[] m_pFileName; + m_pFileName = nullptr; + } + } + + return hr; + } + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Save( IStorage *pStgSave, BOOL fSameAsLoad ) +{ + if ( fSameAsLoad && ( m_pDefHandler == nullptr || m_pOleAdvises[0] == nullptr || m_pOleAdvises[0]->IsClosed() ) ) + return S_OK; + + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IPersistStorage > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + return pPersist->Save( pStgSave, fSameAsLoad ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SaveCompleted( IStorage *pStgNew ) +{ + if ( m_pDefHandler == nullptr || m_pOleAdvises[0] == nullptr || m_pOleAdvises[0]->IsClosed() ) + { + if ( pStgNew ) + m_pStorage = pStgNew; + + return S_OK; + } + + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IPersistStorage > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + { + HRESULT hr = pPersist->SaveCompleted( pStgNew ); + if ( SUCCEEDED( hr ) ) + { + m_nInitMode = LOAD_FROM_STORAGE; + if ( pStgNew ) + { + m_pStorage = pStgNew; + } + + m_nFileOpenMode = 0; + if ( m_pFileName ) + { + delete[] m_pFileName; + m_pFileName = nullptr; + } + } + + return hr; + } + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::HandsOffStorage() +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IPersistStorage > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + { + HRESULT hr = pPersist->HandsOffStorage(); + if ( SUCCEEDED( hr ) ) + { + m_pStorage = nullptr; + } + + return hr; + } + } + + return E_FAIL; +} + +// IPersistFile + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Load( LPCOLESTR pszFileName, DWORD dwMode ) +{ + if ( CheckDefHandler() && pszFileName ) + { + sal::systools::COMReference< IPersistFile > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + { + HRESULT hr = pPersist->Load( pszFileName, dwMode ); + if ( SUCCEEDED( hr ) ) + { + m_nInitMode = LOAD_FROM_FILE; + if ( m_pStorage ) + m_pStorage = nullptr; + + m_nFileOpenMode = dwMode; + // copy the string + SetName( pszFileName, m_pFileName ); + } + + return hr; + } + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Save( LPCOLESTR pszFileName, BOOL fRemember ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IPersistFile > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + return pPersist->Save( pszFileName, fRemember ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SaveCompleted( LPCOLESTR pszFileName ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IPersistFile > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + { + HRESULT hr = pPersist->SaveCompleted( pszFileName ); + if ( SUCCEEDED( hr ) ) + { + m_nInitMode = LOAD_FROM_STORAGE; + if ( m_pStorage ) + m_pStorage = nullptr; + + m_nFileOpenMode = STGM_READWRITE; // was just written + // copy the string + SetName( pszFileName, m_pFileName ); + } + } + + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetCurFile( LPOLESTR *ppszFileName ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IPersistFile > pPersist(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pPersist ) + return pPersist->GetCurFile( ppszFileName ); + } + + return E_FAIL; +} + +// IOleObject + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetClientSite( IOleClientSite* pSite ) +{ + if ( pSite == m_pClientSite.get() ) + return S_OK; + + if ( !pSite ) + { + m_pClientSite = nullptr; + if ( m_pOleContainer ) + { + m_pOleContainer->LockContainer( FALSE ); + m_pOleContainer = nullptr; + } + } + + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + { + HRESULT hr2 = pOleObject->SetClientSite( pSite ); + if ( SUCCEEDED( hr2 ) ) + { + m_pClientSite = pSite; + + if ( m_pOleContainer ) + { + m_pOleContainer->LockContainer( FALSE ); + m_pOleContainer = nullptr; + } + + m_pClientSite->GetContainer( &m_pOleContainer ); + if ( m_pOleContainer ) + m_pOleContainer->LockContainer( TRUE ); + } + + return hr2; + } + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetClientSite( IOleClientSite** pSite ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->GetClientSite( pSite ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj ) +{ + + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + { + pOleObject->SetHostNames( szContainerApp, szContainerObj ); + } + } + + return S_OK; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Close( DWORD dwSaveOption ) +{ + HRESULT ret = S_OK; + if ( m_pDefHandler && CheckDefHandler() ) + { + // no need to close if there is no default handler. + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + { + HRESULT hr = pOleObject->Close( dwSaveOption ); + if (!SUCCEEDED(hr)) + ret = hr; + hr = CoDisconnectObject( static_cast<IUnknown*>(static_cast<IPersistStorage*>(this)), 0 ); + if (!SUCCEEDED(hr) && SUCCEEDED(ret)) + ret = hr; + } + } + + // if the object is closed from outside that means that it should go to uninitialized state + Clean(); + + return ret; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetMoniker( DWORD dwWhichMoniker, IMoniker * pmk ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->SetMoniker( dwWhichMoniker, pmk ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->GetMoniker( dwAssign, dwWhichMoniker, ppmk ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InitFromData( IDataObject * pDataObject, BOOL fCreation, DWORD dwReserved ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->InitFromData( pDataObject, fCreation, dwReserved ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetClipboardData( DWORD dwReserved, IDataObject ** ppDataObject ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->GetClipboardData( dwReserved, ppDataObject ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::DoVerb( + LONG iVerb, + LPMSG pMsg, + IOleClientSite *pActiveSite, + LONG nLong, + HWND hWin, + LPCRECT pRect ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + { + return pOleObject->DoVerb( iVerb, pMsg, pActiveSite, nLong, hWin, pRect ); + } + + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** ppEnumOleVerb ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->EnumVerbs( ppEnumOleVerb ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Update() +{ + + if ( m_pDefHandler && CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->Update(); + } + + return S_OK; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::IsUpToDate() +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->IsUpToDate(); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetUserClassID( CLSID *pClsid ) +{ + if ( pClsid ) + *pClsid = m_guid; + + return S_OK; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetUserType( DWORD dwFormOfType, LPOLESTR * pszUserType ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->GetUserType( dwFormOfType, pszUserType ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetExtent( DWORD dwDrawAspect, SIZEL *psizel ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->SetExtent( dwDrawAspect, psizel ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetExtent( DWORD dwDrawAspect, SIZEL * psizel ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->GetExtent( dwDrawAspect, psizel ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection ) +{ + + if ( !pdwConnection ) + return E_FAIL; + + // CheckDefHandler will set the listener, avoid reusing of old listener + if ( DEFAULT_ARRAY_LEN > *pdwConnection && *pdwConnection > 0 && m_pOleAdvises[*pdwConnection] ) + { + m_pOleAdvises[*pdwConnection]->DisconnectOrigAdvise(); + m_pOleAdvises[*pdwConnection] = nullptr; + } + + if ( pAdvSink && CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + { + sal::systools::COMReference pOwnAdvise(new OleWrapperAdviseSink(pAdvSink)); + DWORD nRegID = 0; + + if ( SUCCEEDED( pOleObject->Advise( pOwnAdvise.get(), &nRegID ) ) && nRegID > 0 ) + { + pOwnAdvise->SetRegID( nRegID ); + *pdwConnection = InsertAdviseLinkToList( pOwnAdvise, m_pOleAdvises ); + if ( *pdwConnection ) + return S_OK; + else + pOleObject->Unadvise( nRegID ); + } + } + } + + // return success always for now + return S_OK; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Unadvise( DWORD dwConnection ) +{ + if ( DEFAULT_ARRAY_LEN > dwConnection && dwConnection > 0 && m_pOleAdvises[dwConnection] ) + { + if ( m_pDefHandler ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + { + DWORD nID = m_pOleAdvises[dwConnection]->GetRegID(); + pOleObject->Unadvise( nID ); + } + } + + m_pOleAdvises[dwConnection]->DisconnectOrigAdvise(); + m_pOleAdvises[dwConnection] = nullptr; + + return S_OK; + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumAdvise( IEnumSTATDATA ** /*ppenumAdvise*/ ) +{ + return E_NOTIMPL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetMiscStatus( DWORD dwAspect, DWORD * pdwStatus ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->GetMiscStatus( dwAspect, pdwStatus ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetColorScheme( LOGPALETTE * pLogpal ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleObject > pOleObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pOleObject ) + return pOleObject->SetColorScheme( pLogpal ); + } + + return E_FAIL; +} + +//IDataObject + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDataObject ) + return pIDataObject->GetData( pFormatetc, pMedium ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDataObject ) + return pIDataObject->GetDataHere( pFormatetc, pMedium ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDataObject ) + return pIDataObject->QueryGetData( pFormatetc ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDataObject ) + return pIDataObject->GetCanonicalFormatEtc( pFormatetcIn, pFormatetcOut ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDataObject ) + return pIDataObject->SetData( pFormatetc, pMedium, fRelease ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDataObject ) + return pIDataObject->EnumFormatEtc( dwDirection, ppFormatetc ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::DAdvise( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection ) +{ + + if ( !pdwConnection ) + return E_FAIL; + + // avoid reusing of the old listener + if ( m_pDefHandler && DEFAULT_ARRAY_LEN > *pdwConnection && *pdwConnection > 0 && m_pDataAdvises[*pdwConnection] ) + { + m_pDataAdvises[*pdwConnection]->DisconnectOrigAdvise(); + m_pDataAdvises[*pdwConnection] = nullptr; + } + + if ( pAdvSink && CheckDefHandler() ) + { + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDataObject ) + { + sal::systools::COMReference pOwnAdvise( new OleWrapperAdviseSink( pAdvSink, pFormatetc, advf ) ); + DWORD nRegID = 0; + + if ( SUCCEEDED( pIDataObject->DAdvise( pFormatetc, advf, pOwnAdvise.get(), &nRegID ) ) && nRegID > 0 ) + { + pOwnAdvise->SetRegID( nRegID ); + *pdwConnection = InsertAdviseLinkToList( pOwnAdvise, m_pDataAdvises ); + if ( *pdwConnection ) + return S_OK; + else + pIDataObject->DUnadvise( nRegID ); + } + } + } + + // return success always for now + return S_OK; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::DUnadvise( DWORD dwConnection ) +{ + if ( m_pDefHandler && DEFAULT_ARRAY_LEN > dwConnection && dwConnection > 0 && m_pDataAdvises[dwConnection] ) + { + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDataObject ) + { + DWORD nID = m_pDataAdvises[dwConnection]->GetRegID(); + pIDataObject->DUnadvise( nID ); + } + } + + m_pDataAdvises[dwConnection]->DisconnectOrigAdvise(); + m_pDataAdvises[dwConnection] = nullptr; + + return S_OK; + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumDAdvise( IEnumSTATDATA ** ppenumAdvise ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDataObject > pIDataObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDataObject ) + return pIDataObject->EnumDAdvise( ppenumAdvise ); + } + + return E_FAIL; +} + +// IRunnableObject + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetRunningClass( LPCLSID lpClsid ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IRunnableObject > pIRunObj(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIRunObj ) + return pIRunObj->GetRunningClass( lpClsid ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Run( LPBINDCTX pbc ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IRunnableObject > pIRunObj(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIRunObj ) + return pIRunObj->Run( pbc ); + } + + return E_FAIL; +} + +BOOL STDMETHODCALLTYPE InprocEmbedDocument_Impl::IsRunning() +{ + if (CheckDefHandler()) + { + sal::systools::COMReference< IRunnableObject > pIRunObj(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIRunObj ) + return pIRunObj->IsRunning(); + } + + return FALSE; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::LockRunning( BOOL fLock, BOOL fLastUnlockCloses ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IRunnableObject > pIRunObj(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIRunObj ) + return pIRunObj->LockRunning( fLock, fLastUnlockCloses ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetContainedObject( BOOL fContained) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IRunnableObject > pIRunObj(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIRunObj ) + return pIRunObj->SetContainedObject( fContained ); + } + + return E_FAIL; +} + + +// IViewObject methods + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Draw( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL ( STDMETHODCALLTYPE *pfnContinue )( ULONG_PTR dwContinue ), ULONG_PTR dwContinue ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IViewObject > pIViewObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIViewObject ) + return pIViewObject->Draw( dwDrawAspect, lindex, pvAspect, ptd, hdcTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, dwContinue ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetColorSet( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IViewObject > pIViewObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIViewObject ) + return pIViewObject->GetColorSet( dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, ppColorSet ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Freeze( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IViewObject > pIViewObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIViewObject ) + return pIViewObject->Freeze( dwDrawAspect, lindex, pvAspect, pdwFreeze ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Unfreeze( DWORD dwFreeze ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IViewObject > pIViewObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIViewObject ) + return pIViewObject->Unfreeze( dwFreeze ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetAdvise( DWORD aspects, DWORD advf, IAdviseSink *pAdvSink ) +{ + + // CheckDefHandler will set the listener, avoid reusing of old listener + if ( m_pViewAdvise ) + { + m_pViewAdvise->DisconnectOrigAdvise(); + m_pViewAdvise = nullptr; + } + + if ( pAdvSink && CheckDefHandler() ) + { + sal::systools::COMReference< IViewObject > pIViewObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIViewObject ) + { + sal::systools::COMReference pOwnAdvise(new OleWrapperAdviseSink(pAdvSink, aspects, advf)); + + if ( SUCCEEDED( pIViewObject->SetAdvise( aspects, advf, pOwnAdvise.get() ) ) ) + { + m_pViewAdvise = pOwnAdvise; + return S_OK; + } + } + } + + return S_OK; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetAdvise( DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink ) +{ + if ( !ppAdvSink ) + return E_INVALIDARG; + + if ( m_pViewAdvise ) + { + if ( pAspects ) + *pAspects = m_pViewAdvise->GetAspect(); + + if ( pAdvf ) + *pAdvf = m_pViewAdvise->GetViewAdviseFlag(); + + *ppAdvSink = m_pViewAdvise->GetOrigAdvise().get(); + if ( *ppAdvSink ) + (*ppAdvSink)->AddRef(); + } + else + *ppAdvSink = nullptr; + + return S_OK; +} + +// IViewObject2 methods + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetExtent( DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IViewObject2 > pIViewObject2(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIViewObject2 ) + return pIViewObject2->GetExtent( dwDrawAspect, lindex, ptd, lpsizel ); + } + + return E_FAIL; +} + + +// IOleWindow methods + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetWindow( HWND *phwnd ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleWindow > pIOleWindow(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleWindow ) + return pIOleWindow->GetWindow( phwnd ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::ContextSensitiveHelp( BOOL fEnterMode ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleWindow > pIOleWindow(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleWindow ) + return pIOleWindow->ContextSensitiveHelp( fEnterMode ); + } + + return E_FAIL; +} + + +// IOleInPlaceObject methods + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InPlaceDeactivate() +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleInPlaceObject > pIOleInPlaceObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleInPlaceObject ) + return pIOleInPlaceObject->InPlaceDeactivate(); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::UIDeactivate() +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleInPlaceObject > pIOleInPlaceObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleInPlaceObject ) + return pIOleInPlaceObject->UIDeactivate(); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetObjectRects( LPCRECT lprcPosRect, LPCRECT lprcClipRect ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleInPlaceObject > pIOleInPlaceObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleInPlaceObject ) + return pIOleInPlaceObject->SetObjectRects( lprcPosRect, lprcClipRect ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::ReactivateAndUndo() +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IOleInPlaceObject > pIOleInPlaceObject(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleInPlaceObject ) + return pIOleInPlaceObject->ReactivateAndUndo(); + } + + return E_FAIL; +} + + +// IDispatch methods + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetTypeInfoCount( UINT *pctinfo ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDispatch > pIDispatch(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDispatch ) + return pIDispatch->GetTypeInfoCount( pctinfo ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDispatch > pIDispatch(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDispatch ) + return pIDispatch->GetTypeInfo( iTInfo, lcid, ppTInfo ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetIDsOfNames( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDispatch > pIDispatch(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDispatch ) + return pIDispatch->GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr ) +{ + if ( CheckDefHandler() ) + { + sal::systools::COMReference< IDispatch > pIDispatch(m_pDefHandler, sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_nCallsOnStack ); // avoid reentrance problem + if ( pIDispatch ) + return pIDispatch->Invoke( dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr ); + } + + return E_FAIL; +} + + +// InternalCacheWrapper + + +// IUnknown + +COM_DECLSPEC_NOTHROW STDMETHODIMP +InprocEmbedDocument_Impl::InternalCacheWrapper::QueryInterface(REFIID riid, void** ppv) +{ + return m_rOwnDocument.QueryInterface( riid, ppv ); +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::InternalCacheWrapper::AddRef() +{ + return m_rOwnDocument.AddRef(); +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::InternalCacheWrapper::Release() +{ + return m_rOwnDocument.Release(); +} + +// IOleCache methods + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::Cache( FORMATETC *pformatetc, DWORD advf, DWORD *pdwConnection ) +{ + if ( m_rOwnDocument.CheckDefHandler() ) + { + sal::systools::COMReference< IOleCache > pIOleCache(m_rOwnDocument.GetDefHandler(), sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleCache ) + return pIOleCache->Cache( pformatetc, advf, pdwConnection ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::Uncache( DWORD dwConnection ) +{ + if ( m_rOwnDocument.CheckDefHandler() ) + { + sal::systools::COMReference< IOleCache > pIOleCache(m_rOwnDocument.GetDefHandler(), sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleCache ) + return pIOleCache->Uncache( dwConnection ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::EnumCache( IEnumSTATDATA **ppenumSTATDATA ) +{ + if ( m_rOwnDocument.CheckDefHandler() ) + { + sal::systools::COMReference< IOleCache > pIOleCache(m_rOwnDocument.GetDefHandler(), sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleCache ) + return pIOleCache->EnumCache( ppenumSTATDATA ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::InitCache( IDataObject *pDataObject ) +{ + if ( m_rOwnDocument.CheckDefHandler() ) + { + sal::systools::COMReference< IOleCache > pIOleCache(m_rOwnDocument.GetDefHandler(), sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleCache ) + return pIOleCache->InitCache( pDataObject ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::SetData( FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease ) +{ + if ( m_rOwnDocument.CheckDefHandler() ) + { + sal::systools::COMReference< IOleCache > pIOleCache(m_rOwnDocument.GetDefHandler(), sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleCache ) + return pIOleCache->SetData( pformatetc, pmedium, fRelease ); + } + + return E_FAIL; +} + +// IOleCache2 methods + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::UpdateCache( LPDATAOBJECT pDataObject, DWORD grfUpdf, LPVOID pReserved ) +{ + if ( m_rOwnDocument.CheckDefHandler() ) + { + sal::systools::COMReference< IOleCache2 > pIOleCache2(m_rOwnDocument.GetDefHandler(), sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleCache2 ) + return pIOleCache2->UpdateCache( pDataObject, grfUpdf, pReserved ); + } + + return E_FAIL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::DiscardCache( DWORD dwDiscardOptions ) +{ + if ( m_rOwnDocument.CheckDefHandler() ) + { + sal::systools::COMReference< IOleCache2 > pIOleCache2(m_rOwnDocument.GetDefHandler(), sal::systools::COM_QUERY); + + ULONGGuard aGuard( m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem + if ( pIOleCache2 ) + return pIOleCache2->DiscardCache( dwDiscardOptions ); + } + + return E_FAIL; +} + +}; // namespace inprocserv + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/embedserv/source/inprocserv/inprocembobj.h b/embedserv/source/inprocserv/inprocembobj.h new file mode 100644 index 0000000000..8591a56c3e --- /dev/null +++ b/embedserv/source/inprocserv/inprocembobj.h @@ -0,0 +1,233 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_EMBEDSERV_SOURCE_INPROCSERV_INPROCEMBOBJ_H +#define INCLUDED_EMBEDSERV_SOURCE_INPROCSERV_INPROCEMBOBJ_H + +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <oleidl.h> + +#include <systools/win32/comtools.hxx> +#include "advisesink.hxx" + +#define DEFAULT_ARRAY_LEN 256 + +namespace inprocserv { + +enum InitModes { + NOINIT, + INIT_FROM_STORAGE, + LOAD_FROM_STORAGE, + LOAD_FROM_FILE +}; + + +// this is a common baseclass that is used to count the objects + +class InprocCountedObject_Impl +{ +public: + InprocCountedObject_Impl(); + ~InprocCountedObject_Impl(); +}; + + +// this is the inprocess embedded object implementation class + +class InprocEmbedDocument_Impl : public InprocCountedObject_Impl + , public IOleObject + , public IDataObject + , public IPersistStorage + , public IPersistFile + , public IRunnableObject + , public IViewObject2 + // , public IExternalConnection + , public IOleInPlaceObject + , public IDispatch +{ + ULONG m_refCount; + BOOLEAN m_bDeleted; + + GUID m_guid; + + sal::systools::COMReference< IUnknown > m_pDefHandler; + InitModes m_nInitMode; + + DWORD m_nFileOpenMode; + wchar_t* m_pFileName; + + sal::systools::COMReference< IStorage > m_pStorage; + + sal::systools::COMReference< IOleClientSite > m_pClientSite; + sal::systools::COMReference< IOleContainer > m_pOleContainer; + + ULONG m_nCallsOnStack; + + // the listeners have wrappers that are directly connected to the object and call the listeners, + // the wrappers will be reconnected correctly to the new default inprocess holder object + sal::systools::COMReference< OleWrapperAdviseSink > m_pOleAdvises[DEFAULT_ARRAY_LEN]; + sal::systools::COMReference< OleWrapperAdviseSink > m_pDataAdvises[DEFAULT_ARRAY_LEN]; + sal::systools::COMReference< OleWrapperAdviseSink > m_pViewAdvise; + + class InternalCacheWrapper final: public IOleCache2 + { + InprocEmbedDocument_Impl& m_rOwnDocument; + + public: + explicit InternalCacheWrapper( InprocEmbedDocument_Impl& rOwnDocument ) + : m_rOwnDocument( rOwnDocument ) + {} + + virtual ~InternalCacheWrapper() {} + + /* IUnknown methods */ + STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj) override; + STDMETHOD_(ULONG, AddRef)() override; + STDMETHOD_(ULONG, Release)() override; + + /* IOleCache2 methods */ + STDMETHOD(Cache)( FORMATETC *pformatetc, DWORD advf, DWORD *pdwConnection) override; + STDMETHOD(Uncache)( DWORD dwConnection) override; + STDMETHOD(EnumCache)( IEnumSTATDATA **ppenumSTATDATA) override; + STDMETHOD(InitCache)( IDataObject *pDataObject) override; + STDMETHOD(SetData)( FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease) override; + STDMETHOD(UpdateCache)( LPDATAOBJECT pDataObject, DWORD grfUpdf, LPVOID pReserved) override; + STDMETHOD(DiscardCache)( DWORD dwDiscardOptions) override; + } m_aInternalCache; + + void Clean(); + + +public: + + explicit InprocEmbedDocument_Impl( const GUID& guid ) + : m_refCount( 0 ) + , m_bDeleted( FALSE ) + , m_guid( guid ) + , m_nInitMode( NOINIT ) + , m_nFileOpenMode( 0 ) + , m_pFileName( nullptr ) + , m_nCallsOnStack( 0 ) + , m_aInternalCache( *this ) + {} + + virtual ~InprocEmbedDocument_Impl() + {} + + BOOL CheckDefHandler(); + sal::systools::COMReference< IUnknown >& GetDefHandler() { return m_pDefHandler; } + + /* IUnknown methods */ + STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj) override; + STDMETHOD_(ULONG, AddRef)() override; + STDMETHOD_(ULONG, Release)() override; + + /* IOleObject methods */ + STDMETHOD(SetClientSite) ( IOleClientSite* pSite ) override; + STDMETHOD(GetClientSite) ( IOleClientSite** pSite ) override; + STDMETHOD(SetHostNames) ( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj ) override; + STDMETHOD(Close) ( DWORD dwSaveOption) override; + STDMETHOD(SetMoniker) ( DWORD dwWhichMoniker, IMoniker *pmk ) override; + STDMETHOD(GetMoniker) ( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk ) override; + STDMETHOD(InitFromData) ( IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved ) override; + STDMETHOD(GetClipboardData) ( DWORD dwReserved, IDataObject **ppDataObject ) override; + STDMETHOD(DoVerb) ( LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect ) override; + STDMETHOD(EnumVerbs) ( IEnumOLEVERB **ppEnumOleVerb ) override; + STDMETHOD(Update) () override; + STDMETHOD(IsUpToDate) () override; + STDMETHOD(GetUserClassID) ( CLSID *pClsid ) override; + STDMETHOD(GetUserType) ( DWORD dwFormOfType, LPOLESTR *pszUserType ) override; + STDMETHOD(SetExtent) ( DWORD dwDrawAspect, SIZEL *psizel ) override; + STDMETHOD(GetExtent) ( DWORD dwDrawAspect, SIZEL *psizel ) override; + STDMETHOD(Advise) ( IAdviseSink *pAdvSink, DWORD *pdwConnection ) override; + STDMETHOD(Unadvise) ( DWORD dwConnection ) override; + STDMETHOD(EnumAdvise) ( IEnumSTATDATA **ppenumAdvise ) override; + STDMETHOD(GetMiscStatus) ( DWORD dwAspect, DWORD *pdwStatus ) override; + STDMETHOD(SetColorScheme) ( LOGPALETTE *pLogpal ) override; + + /* IDataObject methods */ + STDMETHOD(GetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) override; + STDMETHOD(GetDataHere) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium ) override; + STDMETHOD(QueryGetData) ( FORMATETC * pFormatetc ) override; + STDMETHOD(GetCanonicalFormatEtc) ( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut ) override; + STDMETHOD(SetData) ( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease ) override; + STDMETHOD(EnumFormatEtc) ( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc ) override; + STDMETHOD(DAdvise) ( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection ) override; + STDMETHOD(DUnadvise) ( DWORD dwConnection ) override; + STDMETHOD(EnumDAdvise) ( IEnumSTATDATA ** ppenumAdvise ) override; + + /* IPersistMethod */ + STDMETHOD(GetClassID)(CLSID *pClassID) override; + + /* IPersistStorage methods */ + STDMETHOD(IsDirty) () override; + STDMETHOD(InitNew) ( IStorage *pStg ) override; + STDMETHOD(Load) ( IStorage* pStr ) override; + STDMETHOD(Save) ( IStorage *pStgSave, BOOL fSameAsLoad ) override; + STDMETHOD(SaveCompleted) ( IStorage *pStgNew ) override; + STDMETHOD(HandsOffStorage) (void) override; + + /* IPersistFile methods */ + STDMETHOD(Load) ( LPCOLESTR pszFileName, DWORD dwMode ) override; + STDMETHOD(Save) ( LPCOLESTR pszFileName, BOOL fRemember ) override; + STDMETHOD(SaveCompleted) ( LPCOLESTR pszFileName ) override; + STDMETHOD(GetCurFile) ( LPOLESTR *ppszFileName ) override; + + /* IRunnableObject methods */ + STDMETHOD(GetRunningClass) ( LPCLSID lpClsid) override; + STDMETHOD(Run) ( LPBINDCTX pbc) override; + virtual BOOL STDMETHODCALLTYPE IsRunning( void) override; + STDMETHOD(LockRunning) ( BOOL fLock, BOOL fLastUnlockCloses ) override; + STDMETHOD(SetContainedObject) ( BOOL fContained) override; + + /* IViewObject2 methods */ + STDMETHOD(Draw)( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL ( STDMETHODCALLTYPE *pfnContinue )( ULONG_PTR dwContinue ), ULONG_PTR dwContinue) override; + STDMETHOD(GetColorSet)( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet) override; + STDMETHOD(Freeze)( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze) override; + STDMETHOD(Unfreeze)( DWORD dwFreeze) override; + STDMETHOD(SetAdvise)( DWORD aspects, DWORD advf, IAdviseSink *pAdvSink) override; + STDMETHOD(GetAdvise)( DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink) override; + STDMETHOD(GetExtent)( DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel) override; + + /* IOleWindow methods */ + STDMETHOD(GetWindow)( HWND *phwnd) override; + STDMETHOD(ContextSensitiveHelp)( BOOL fEnterMode) override; + + /* IOleInPlaceObject methods */ + STDMETHOD(InPlaceDeactivate)( void) override; + STDMETHOD(UIDeactivate)( void) override; + STDMETHOD(SetObjectRects)( LPCRECT lprcPosRect, LPCRECT lprcClipRect) override; + STDMETHOD(ReactivateAndUndo)( void) override; + + /*IDispatch methods*/ + STDMETHOD(GetTypeInfoCount)( UINT *pctinfo) override; + STDMETHOD(GetTypeInfo)( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) override; + STDMETHOD(GetIDsOfNames)( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) override; + STDMETHOD(Invoke)( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) override; + +}; + +} // namespace inprocserv + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/embedserv/source/inprocserv/inprocserv.def b/embedserv/source/inprocserv/inprocserv.def new file mode 100644 index 0000000000..d731a151f0 --- /dev/null +++ b/embedserv/source/inprocserv/inprocserv.def @@ -0,0 +1,5 @@ +EXPORTS
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE
|