summaryrefslogtreecommitdiffstats
path: root/embedserv/source/inprocserv/inprocembobj.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /embedserv/source/inprocserv/inprocembobj.cxx
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'embedserv/source/inprocserv/inprocembobj.cxx')
-rw-r--r--embedserv/source/inprocserv/inprocembobj.cxx1777
1 files changed, 1777 insertions, 0 deletions
diff --git a/embedserv/source/inprocserv/inprocembobj.cxx b/embedserv/source/inprocserv/inprocembobj.cxx
new file mode 100644
index 000000000..23a1df21a
--- /dev/null
+++ b/embedserv/source/inprocserv/inprocembobj.cxx
@@ -0,0 +1,1777 @@
+/* -*- 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 {
+
+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 ComSmart<OleWrapperAdviseSink>& pOwnAdvise, ComSmart< 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] == pOwnAdvise )
+ {
+ 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
+
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+ if ( SUCCEEDED( hr ) && 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 );
+ }
+
+ ComSmart< IDataObject > pIDataObject;
+ hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+ if ( SUCCEEDED( hr ) && 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 );
+ }
+ }
+
+ ComSmart< IViewObject > pIViewObject;
+ hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
+ if ( SUCCEEDED( hr ) && pIViewObject )
+ {
+ if ( m_pViewAdvise )
+ pIViewObject->SetAdvise( m_pViewAdvise->GetAspect(), m_pViewAdvise->GetViewAdviseFlag(), nullptr );
+ }
+
+ ComSmart< IPersistStorage > pPersist;
+ hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
+ if ( SUCCEEDED( hr ) && 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 )
+ {
+ ComSmart< IPersistStorage > pPersist;
+ hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist && m_pStorage )
+ hr = pPersist->InitNew( m_pStorage.get() );
+ }
+ else if ( m_nInitMode == LOAD_FROM_STORAGE )
+ {
+ ComSmart< IPersistStorage > pPersist;
+ hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist && m_pStorage )
+ hr = pPersist->Load( m_pStorage.get() );
+ }
+ else if ( m_nInitMode == LOAD_FROM_FILE )
+ {
+ ComSmart< IPersistFile > pPersistFile;
+ hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersistFile) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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
+
+ ComSmart< IOleObject > pOleObject;
+ hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+ if ( SUCCEEDED( hr ) && 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 );
+ }
+ }
+
+ ComSmart< IDataObject > pIDataObject;
+ hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+ if ( SUCCEEDED( hr ) && 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 );
+ }
+ }
+
+ ComSmart< IViewObject > pIViewObject;
+ hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
+ if ( SUCCEEDED( hr ) && 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++ )
+ {
+ if ( m_pOleAdvises[nInd] )
+ {
+ ComSmart< OleWrapperAdviseSink > pAdvise = m_pOleAdvises[nInd];
+ m_pOleAdvises[nInd] = nullptr;
+ }
+
+ if ( m_pDataAdvises[nInd] )
+ {
+ ComSmart< OleWrapperAdviseSink > pAdvise = m_pDataAdvises[nInd];
+ m_pDataAdvises[nInd] = nullptr;
+ }
+ }
+
+ 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 FAR* FAR* 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() )
+ {
+ ComSmart< IPersistStorage > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist )
+ return pPersist->IsDirty();
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InitNew( IStorage *pStg )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IPersistStorage > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist )
+ {
+ 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() )
+ {
+ ComSmart< IPersistStorage > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist )
+ {
+ 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() )
+ {
+ ComSmart< IPersistStorage > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IPersistStorage > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist )
+ {
+ 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() )
+ {
+ ComSmart< IPersistStorage > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist )
+ {
+ 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 )
+ {
+ ComSmart< IPersistFile > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist )
+ {
+ 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() )
+ {
+ ComSmart< IPersistFile > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist )
+ return pPersist->Save( pszFileName, fRemember );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SaveCompleted( LPCOLESTR pszFileName )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IPersistFile > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pPersist )
+ {
+ 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() )
+ {
+ ComSmart< IPersistFile > pPersist;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersist) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ return pOleObject->GetClientSite( pSite );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj )
+{
+
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ {
+ hr = 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.
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ {
+ 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() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ return pOleObject->SetMoniker( dwWhichMoniker, pmk );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ return pOleObject->InitFromData( pDataObject, fCreation, dwReserved );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetClipboardData( DWORD dwReserved, IDataObject ** ppDataObject )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ {
+ hr = pOleObject->DoVerb( iVerb, pMsg, pActiveSite, nLong, hWin, pRect );
+ return hr;
+ }
+
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** ppEnumOleVerb )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ return pOleObject->EnumVerbs( ppEnumOleVerb );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Update()
+{
+
+ if ( m_pDefHandler && CheckDefHandler() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ return pOleObject->Update();
+ }
+
+ return S_OK;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::IsUpToDate()
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ return pOleObject->GetUserType( dwFormOfType, pszUserType );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetExtent( DWORD dwDrawAspect, SIZEL *psizel )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ return pOleObject->SetExtent( dwDrawAspect, psizel );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetExtent( DWORD dwDrawAspect, SIZEL * psizel )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ {
+ ComSmart<IAdviseSink> aListener(pAdvSink);
+ ComSmart<OleWrapperAdviseSink> pOwnAdvise(new OleWrapperAdviseSink(aListener));
+ 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 )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ return pOleObject->GetMiscStatus( dwAspect, pdwStatus );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetColorScheme( LOGPALETTE * pLogpal )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleObject > pOleObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pOleObject )
+ return pOleObject->SetColorScheme( pLogpal );
+ }
+
+ return E_FAIL;
+}
+
+//IDataObject
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IDataObject > pIDataObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIDataObject )
+ return pIDataObject->GetData( pFormatetc, pMedium );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IDataObject > pIDataObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIDataObject )
+ return pIDataObject->GetDataHere( pFormatetc, pMedium );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IDataObject > pIDataObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIDataObject )
+ return pIDataObject->QueryGetData( pFormatetc );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IDataObject > pIDataObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIDataObject )
+ return pIDataObject->GetCanonicalFormatEtc( pFormatetcIn, pFormatetcOut );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IDataObject > pIDataObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIDataObject )
+ return pIDataObject->SetData( pFormatetc, pMedium, fRelease );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IDataObject > pIDataObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IDataObject > pIDataObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIDataObject )
+ {
+ ComSmart< OleWrapperAdviseSink > pOwnAdvise( new OleWrapperAdviseSink( ComSmart<IAdviseSink>( 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() )
+ {
+ ComSmart< IDataObject > pIDataObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IDataObject > pIDataObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIDataObject )
+ return pIDataObject->EnumDAdvise( ppenumAdvise );
+ }
+
+ return E_FAIL;
+}
+
+// IRunnableObject
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetRunningClass( LPCLSID lpClsid )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IRunnableObject > pIRunObj;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIRunObj )
+ return pIRunObj->GetRunningClass( lpClsid );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Run( LPBINDCTX pbc )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IRunnableObject > pIRunObj;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIRunObj )
+ return pIRunObj->Run( pbc );
+ }
+
+ return E_FAIL;
+}
+
+BOOL STDMETHODCALLTYPE InprocEmbedDocument_Impl::IsRunning()
+{
+ if (CheckDefHandler())
+ {
+ ComSmart< IRunnableObject > pIRunObj;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIRunObj )
+ return pIRunObj->IsRunning();
+ }
+
+ return FALSE;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::LockRunning( BOOL fLock, BOOL fLastUnlockCloses )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IRunnableObject > pIRunObj;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIRunObj )
+ return pIRunObj->LockRunning( fLock, fLastUnlockCloses );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetContainedObject( BOOL fContained)
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IRunnableObject > pIRunObj;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IViewObject > pIViewObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IViewObject > pIViewObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IViewObject > pIViewObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIViewObject )
+ return pIViewObject->Freeze( dwDrawAspect, lindex, pvAspect, pdwFreeze );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Unfreeze( DWORD dwFreeze )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IViewObject > pIViewObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IViewObject > pIViewObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIViewObject )
+ {
+ ComSmart<IAdviseSink> aListener(pAdvSink);
+ ComSmart<OleWrapperAdviseSink> pOwnAdvise(new OleWrapperAdviseSink(aListener, 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() )
+ {
+ ComSmart< IViewObject2 > pIViewObject2;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject2, reinterpret_cast<void**>(&pIViewObject2) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIViewObject2 )
+ return pIViewObject2->GetExtent( dwDrawAspect, lindex, ptd, lpsizel );
+ }
+
+ return E_FAIL;
+}
+
+
+// IOleWindow methods
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetWindow( HWND *phwnd )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleWindow > pIOleWindow;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleWindow, reinterpret_cast<void**>(&pIOleWindow) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleWindow )
+ return pIOleWindow->GetWindow( phwnd );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::ContextSensitiveHelp( BOOL fEnterMode )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleWindow > pIOleWindow;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleWindow, reinterpret_cast<void**>(&pIOleWindow) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleWindow )
+ return pIOleWindow->ContextSensitiveHelp( fEnterMode );
+ }
+
+ return E_FAIL;
+}
+
+
+// IOleInPlaceObject methods
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InPlaceDeactivate()
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleInPlaceObject > pIOleInPlaceObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, reinterpret_cast<void**>(&pIOleInPlaceObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleInPlaceObject )
+ return pIOleInPlaceObject->InPlaceDeactivate();
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::UIDeactivate()
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleInPlaceObject > pIOleInPlaceObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, reinterpret_cast<void**>(&pIOleInPlaceObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleInPlaceObject )
+ return pIOleInPlaceObject->UIDeactivate();
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetObjectRects( LPCRECT lprcPosRect, LPCRECT lprcClipRect )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleInPlaceObject > pIOleInPlaceObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, reinterpret_cast<void**>(&pIOleInPlaceObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleInPlaceObject )
+ return pIOleInPlaceObject->SetObjectRects( lprcPosRect, lprcClipRect );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::ReactivateAndUndo()
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IOleInPlaceObject > pIOleInPlaceObject;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, reinterpret_cast<void**>(&pIOleInPlaceObject) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleInPlaceObject )
+ return pIOleInPlaceObject->ReactivateAndUndo();
+ }
+
+ return E_FAIL;
+}
+
+
+// IDispatch methods
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetTypeInfoCount( UINT *pctinfo )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IDispatch > pIDispatch;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, reinterpret_cast<void**>(&pIDispatch) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIDispatch )
+ return pIDispatch->GetTypeInfoCount( pctinfo );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo )
+{
+ if ( CheckDefHandler() )
+ {
+ ComSmart< IDispatch > pIDispatch;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, reinterpret_cast<void**>(&pIDispatch) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IDispatch > pIDispatch;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, reinterpret_cast<void**>(&pIDispatch) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IDispatch > pIDispatch;
+ HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, reinterpret_cast<void**>(&pIDispatch) );
+
+ ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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 FAR* FAR* 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() )
+ {
+ ComSmart< IOleCache > pIOleCache;
+ HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
+
+ ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleCache )
+ return pIOleCache->Cache( pformatetc, advf, pdwConnection );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::Uncache( DWORD dwConnection )
+{
+ if ( m_rOwnDocument.CheckDefHandler() )
+ {
+ ComSmart< IOleCache > pIOleCache;
+ HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
+
+ ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleCache )
+ return pIOleCache->Uncache( dwConnection );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::EnumCache( IEnumSTATDATA **ppenumSTATDATA )
+{
+ if ( m_rOwnDocument.CheckDefHandler() )
+ {
+ ComSmart< IOleCache > pIOleCache;
+ HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
+
+ ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleCache )
+ return pIOleCache->EnumCache( ppenumSTATDATA );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::InitCache( IDataObject *pDataObject )
+{
+ if ( m_rOwnDocument.CheckDefHandler() )
+ {
+ ComSmart< IOleCache > pIOleCache;
+ HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
+
+ ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IOleCache > pIOleCache;
+ HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
+
+ ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && 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() )
+ {
+ ComSmart< IOleCache2 > pIOleCache2;
+ HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache2, reinterpret_cast<void**>(&pIOleCache2) );
+
+ ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleCache2 )
+ return pIOleCache2->UpdateCache( pDataObject, grfUpdf, pReserved );
+ }
+
+ return E_FAIL;
+}
+
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::DiscardCache( DWORD dwDiscardOptions )
+{
+ if ( m_rOwnDocument.CheckDefHandler() )
+ {
+ ComSmart< IOleCache2 > pIOleCache2;
+ HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache2, reinterpret_cast<void**>(&pIOleCache2) );
+
+ ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
+ if ( SUCCEEDED( hr ) && pIOleCache2 )
+ return pIOleCache2->DiscardCache( dwDiscardOptions );
+ }
+
+ return E_FAIL;
+}
+
+}; // namespace inprocserv
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */