diff options
Diffstat (limited to 'embeddedobj/source/msole/olepersist.cxx')
-rw-r--r-- | embeddedobj/source/msole/olepersist.cxx | 140 |
1 files changed, 83 insertions, 57 deletions
diff --git a/embeddedobj/source/msole/olepersist.cxx b/embeddedobj/source/msole/olepersist.cxx index 04d5b6433c07..e6af72fedccf 100644 --- a/embeddedobj/source/msole/olepersist.cxx +++ b/embeddedobj/source/msole/olepersist.cxx @@ -41,12 +41,12 @@ #include <com/sun/star/ucb/SimpleFileAccess.hpp> #include <com/sun/star/io/IOException.hpp> -#include <comphelper/processfactory.hxx> #include <comphelper/storagehelper.hxx> #include <comphelper/mimeconfighelper.hxx> #include <comphelper/classids.hxx> #include <osl/diagnose.h> #include <osl/thread.hxx> +#include <rtl/ref.hxx> #include <sal/log.hxx> #include <closepreventer.hxx> @@ -88,14 +88,13 @@ OUString GetNewTempFileURL_Impl( const uno::Reference< uno::XComponentContext >& OUString aResult; - uno::Reference < beans::XPropertySet > xTempFile( + uno::Reference < io::XTempFile > xTempFile( io::TempFile::create(xContext), - uno::UNO_QUERY_THROW ); + uno::UNO_SET_THROW ); try { - xTempFile->setPropertyValue("RemoveFile", uno::makeAny( false ) ); - uno::Any aUrl = xTempFile->getPropertyValue("Uri"); - aUrl >>= aResult; + xTempFile->setRemoveFile( false ); + aResult = xTempFile->getUri(); } catch ( const uno::Exception& ) { @@ -162,16 +161,14 @@ static OUString GetNewFilledTempFile_Impl( const uno::Reference< embed::XOptimiz try { - uno::Reference < beans::XPropertySet > xTempFile( + uno::Reference < io::XTempFile > xTempFile( io::TempFile::create(xContext), - uno::UNO_QUERY ); - uno::Reference < io::XStream > xTempStream( xTempFile, uno::UNO_QUERY_THROW ); + uno::UNO_SET_THROW ); - xParentStorage->copyStreamElementData( aEntryName, xTempStream ); + xParentStorage->copyStreamElementData( aEntryName, xTempFile ); - xTempFile->setPropertyValue("RemoveFile", uno::makeAny( false ) ); - uno::Any aUrl = xTempFile->getPropertyValue("Uri"); - aUrl >>= aResult; + xTempFile->setRemoveFile( false ); + aResult = xTempFile->getUri(); } catch( const uno::RuntimeException& ) { @@ -191,7 +188,7 @@ static OUString GetNewFilledTempFile_Impl( const uno::Reference< embed::XOptimiz static void SetStreamMediaType_Impl( const uno::Reference< io::XStream >& xStream, const OUString& aMediaType ) { uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY_THROW ); - xPropSet->setPropertyValue("MediaType", uno::makeAny( aMediaType ) ); + xPropSet->setPropertyValue("MediaType", uno::Any( aMediaType ) ); } #endif @@ -199,7 +196,7 @@ static void LetCommonStoragePassBeUsed_Impl( const uno::Reference< io::XStream > { uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY_THROW ); xPropSet->setPropertyValue("UseCommonStoragePasswordEncryption", - uno::makeAny( true ) ); + uno::Any( true ) ); } #ifdef _WIN32 @@ -363,9 +360,8 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea if ( !xTargetStream.is() || !xCachedVisualRepresentation.is() ) throw uno::RuntimeException(); - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[0] <<= xTargetStream; - aArgs[1] <<= true; // do not create copy + uno::Sequence< uno::Any > aArgs{ uno::Any(xTargetStream), + uno::Any(true) }; // do not create copy uno::Reference< container::XNameContainer > xNameContainer( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( @@ -393,7 +389,8 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea // write 0xFFFFFFFF at the beginning uno::Sequence< sal_Int8 > aData( 4 ); - * reinterpret_cast<sal_uInt32*>(aData.getArray()) = 0xFFFFFFFF; + auto pData = aData.getArray(); + * reinterpret_cast<sal_uInt32*>(pData) = 0xFFFFFFFF; xTempOutStream->writeBytes( aData ); @@ -406,33 +403,33 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea if ( aSigData[0] == 'B' && aSigData[1] == 'M' ) { // it's a bitmap - aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0; + pData[0] = 0x02; pData[1] = 0; pData[2] = 0; pData[3] = 0; } else { // treat it as a metafile - aData[0] = 0x03; aData[1] = 0; aData[2] = 0; aData[3] = 0; + pData[0] = 0x03; pData[1] = 0; pData[2] = 0; pData[3] = 0; } xTempOutStream->writeBytes( aData ); // write job related information - aData[0] = 0x04; aData[1] = 0; aData[2] = 0; aData[3] = 0; + pData[0] = 0x04; pData[1] = 0; pData[2] = 0; pData[3] = 0; xTempOutStream->writeBytes( aData ); // write aspect - aData[0] = 0x01; aData[1] = 0; aData[2] = 0; aData[3] = 0; + pData[0] = 0x01; pData[1] = 0; pData[2] = 0; pData[3] = 0; xTempOutStream->writeBytes( aData ); // write l-index - * reinterpret_cast<sal_uInt32*>(aData.getArray()) = 0xFFFFFFFF; + * reinterpret_cast<sal_uInt32*>(pData) = 0xFFFFFFFF; xTempOutStream->writeBytes( aData ); // write adv. flags - aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0; + pData[0] = 0x02; pData[1] = 0; pData[2] = 0; pData[3] = 0; xTempOutStream->writeBytes( aData ); // write compression - * reinterpret_cast<sal_uInt32*>(aData.getArray()) = 0x0; + * reinterpret_cast<sal_uInt32*>(pData) = 0x0; xTempOutStream->writeBytes( aData ); // get the size @@ -442,7 +439,7 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea // write width for ( nIndex = 0; nIndex < 4; nIndex++ ) { - aData[nIndex] = static_cast<sal_Int8>( aSize.Width % 0x100 ); + pData[nIndex] = static_cast<sal_Int8>( aSize.Width % 0x100 ); aSize.Width /= 0x100; } xTempOutStream->writeBytes( aData ); @@ -450,7 +447,7 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea // write height for ( nIndex = 0; nIndex < 4; nIndex++ ) { - aData[nIndex] = static_cast<sal_Int8>( aSize.Height % 0x100 ); + pData[nIndex] = static_cast<sal_Int8>( aSize.Height % 0x100 ); aSize.Height /= 0x100; } xTempOutStream->writeBytes( aData ); @@ -473,7 +470,7 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea } for ( sal_Int32 nInd = 0; nInd < 4; nInd++ ) { - aData[nInd] = static_cast<sal_Int8>( static_cast<sal_uInt64>(nLength) % 0x100 ); + pData[nInd] = static_cast<sal_Int8>( static_cast<sal_uInt64>(nLength) % 0x100 ); nLength /= 0x100; } xTempSeek->seek( 36 ); @@ -488,9 +485,9 @@ void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStrea // insert the result file as replacement image OUString aCacheName = "\002OlePres000"; if ( xNameContainer->hasByName( aCacheName ) ) - xNameContainer->replaceByName( aCacheName, uno::makeAny( xTempFile ) ); + xNameContainer->replaceByName( aCacheName, uno::Any( xTempFile ) ); else - xNameContainer->insertByName( aCacheName, uno::makeAny( xTempFile ) ); + xNameContainer->insertByName( aCacheName, uno::Any( xTempFile ) ); uno::Reference< embed::XTransactedObject > xTransacted( xNameContainer, uno::UNO_QUERY_THROW ); xTransacted->commit(); @@ -503,9 +500,8 @@ void OleEmbeddedObject::RemoveVisualCache_Impl( const uno::Reference< io::XStrea if ( !xTargetStream.is() ) throw uno::RuntimeException(); - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[0] <<= xTargetStream; - aArgs[1] <<= true; // do not create copy + uno::Sequence< uno::Any > aArgs{ uno::Any(xTargetStream), + uno::Any(true) }; // do not create copy uno::Reference< container::XNameContainer > xNameContainer( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( "com.sun.star.embed.OLESimpleStorage", @@ -565,9 +561,8 @@ bool OleEmbeddedObject::HasVisReplInStream() { bool bExists = false; - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[0] <<= xStream; - aArgs[1] <<= true; // do not create copy + uno::Sequence< uno::Any > aArgs{ uno::Any(xStream), + uno::Any(true) }; // do not create copy uno::Reference< container::XNameContainer > xNameContainer( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( "com.sun.star.embed.OLESimpleStorage", @@ -600,7 +595,7 @@ bool OleEmbeddedObject::HasVisReplInStream() uno::Reference< io::XStream > OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation_Impl( const uno::Reference< io::XStream >& xStream, bool bAllowToRepair50 ) - throw () + noexcept { uno::Reference< io::XStream > xResult; @@ -609,9 +604,8 @@ uno::Reference< io::XStream > OleEmbeddedObject::TryToRetrieveCachedVisualRepres SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation, retrieving" ); uno::Reference< container::XNameContainer > xNameContainer; - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[0] <<= xStream; - aArgs[1] <<= true; // do not create copy + uno::Sequence< uno::Any > aArgs{ uno::Any(xStream), + uno::Any(true) }; // do not create copy try { xNameContainer.set( @@ -742,6 +736,22 @@ void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStor return; } + uno::Reference<io::XSeekable> xNewSeekable(xNewObjectStream, uno::UNO_QUERY); + if (xNewSeekable.is() && xNewSeekable->getLength() == 0) + { + uno::Reference<io::XSeekable> xOldSeekable(m_xObjectStream, uno::UNO_QUERY); + if (xOldSeekable.is() && xOldSeekable->getLength() > 0) + { + SAL_WARN("embeddedobj.ole", "OleEmbeddedObject::SwitchOwnPersistence(stream version): " + "empty new stream, reusing old one"); + uno::Reference<io::XInputStream> xInput = m_xObjectStream->getInputStream(); + uno::Reference<io::XOutputStream> xOutput = xNewObjectStream->getOutputStream(); + xOldSeekable->seek(0); + comphelper::OStorageHelper::CopyInputToOutput(xInput, xOutput); + xNewSeekable->seek(0); + } + } + try { uno::Reference< lang::XComponent > xComponent( m_xObjectStream, uno::UNO_QUERY ); OSL_ENSURE( !m_xObjectStream.is() || xComponent.is(), "Wrong stream implementation!" ); @@ -767,6 +777,21 @@ void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStor sal_Int32 nStreamMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE; uno::Reference< io::XStream > xNewOwnStream = xNewParentStorage->openStreamElement( aNewName, nStreamMode ); + + uno::Reference<io::XSeekable> xNewSeekable (xNewOwnStream, uno::UNO_QUERY); + if (xNewSeekable.is() && xNewSeekable->getLength() == 0) + { + uno::Reference<io::XSeekable> xOldSeekable(m_xObjectStream, uno::UNO_QUERY); + if (xOldSeekable.is() && xOldSeekable->getLength() > 0) + { + SAL_WARN("embeddedobj.ole", "OleEmbeddedObject::SwitchOwnPersistence: empty new stream, reusing old one"); + uno::Reference<io::XInputStream> xInput = m_xObjectStream->getInputStream(); + uno::Reference<io::XOutputStream> xOutput = xNewOwnStream->getOutputStream(); + comphelper::OStorageHelper::CopyInputToOutput(xInput, xOutput); + xNewSeekable->seek(0); + } + } + SAL_WARN_IF( !xNewOwnStream.is(), "embeddedobj.ole", "The method can not return empty reference!" ); SwitchOwnPersistence( xNewParentStorage, xNewOwnStream, aNewName ); @@ -926,23 +951,23 @@ OUString OleEmbeddedObject::GetTempURL_Impl() } -void OleEmbeddedObject::CreateOleComponent_Impl( OleComponent* pOleComponent ) +void OleEmbeddedObject::CreateOleComponent_Impl( + rtl::Reference<OleComponent> const & pOleComponent ) { if ( !m_pOleComponent ) { m_pOleComponent = pOleComponent ? pOleComponent : new OleComponent( m_xContext, this ); - m_pOleComponent->acquire(); // TODO: needs holder? if ( !m_xClosePreventer.is() ) - m_xClosePreventer.set( static_cast< ::cppu::OWeakObject* >( new OClosePreventer ), - uno::UNO_QUERY ); + m_xClosePreventer = new OClosePreventer; m_pOleComponent->addCloseListener( m_xClosePreventer ); } } -void OleEmbeddedObject::CreateOleComponentAndLoad_Impl( OleComponent* pOleComponent ) +void OleEmbeddedObject::CreateOleComponentAndLoad_Impl( + rtl::Reference<OleComponent> const & pOleComponent ) { if ( !m_pOleComponent ) { @@ -1034,8 +1059,11 @@ void OleEmbeddedObject::StoreToLocation_Impl( const uno::Reference< embed::XStorage >& xStorage, const OUString& sEntName, const uno::Sequence< beans::PropertyValue >& lObjArgs, - bool bSaveAs ) + bool bSaveAs, osl::ResettableMutexGuard& rGuard) { +#ifndef _WIN32 + (void)rGuard; +#endif // TODO: use lObjArgs // TODO: exchange StoreVisualReplacement by SO file format version? @@ -1085,7 +1113,7 @@ void OleEmbeddedObject::StoreToLocation_Impl( #ifdef _WIN32 // if the object was NOT modified after storing it can be just copied // as if it was in loaded state - || ( m_pOleComponent && !m_pOleComponent->IsDirty() ) + || (m_pOleComponent && !ExecUnlocked([this] { return m_pOleComponent->IsDirty(); }, rGuard)) #endif ) { @@ -1457,13 +1485,13 @@ void SAL_CALL OleEmbeddedObject::storeToEntry( const uno::Reference< embed::XSto } // end wrapping related part ==================== - ::osl::MutexGuard aGuard( m_aMutex ); + ::osl::ResettableMutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController ); - StoreToLocation_Impl( xStorage, sEntName, lObjArgs, false ); + StoreToLocation_Impl( xStorage, sEntName, lObjArgs, false, aGuard ); // TODO: should the listener notification be done? } @@ -1484,13 +1512,13 @@ void SAL_CALL OleEmbeddedObject::storeAsEntry( const uno::Reference< embed::XSto } // end wrapping related part ==================== - ::osl::MutexGuard aGuard( m_aMutex ); + ::osl::ResettableMutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController ); - StoreToLocation_Impl( xStorage, sEntName, lObjArgs, true ); + StoreToLocation_Impl( xStorage, sEntName, lObjArgs, true, aGuard ); // TODO: should the listener notification be done here or in saveCompleted? } @@ -1666,7 +1694,7 @@ void SAL_CALL OleEmbeddedObject::storeOwn() // ask container to store the object, the container has to make decision // to do so or not - osl::ClearableMutexGuard aGuard(m_aMutex); + osl::ResettableMutexGuard aGuard(m_aMutex); if ( m_bDisposed ) throw lang::DisposedException(); // TODO @@ -1692,7 +1720,7 @@ void SAL_CALL OleEmbeddedObject::storeOwn() bool bStoreLoaded = true; #ifdef _WIN32 - if ( m_nObjectState != embed::EmbedStates::LOADED && m_pOleComponent && m_pOleComponent->IsDirty() ) + if ( m_nObjectState != embed::EmbedStates::LOADED && m_pOleComponent && ExecUnlocked([this] { return m_pOleComponent->IsDirty(); }, aGuard) ) { bStoreLoaded = false; @@ -1886,13 +1914,12 @@ void SAL_CALL OleEmbeddedObject::breakLink( const uno::Reference< embed::XStorag OUString aOldTempURL = m_aTempURL; m_aTempURL.clear(); - OleComponent* pNewOleComponent = new OleComponent(m_xContext, this); + rtl::Reference<OleComponent> pNewOleComponent = new OleComponent(m_xContext, this); try { pNewOleComponent->InitEmbeddedCopyOfLink(m_pOleComponent); } catch (const uno::Exception&) { - delete pNewOleComponent; if (!m_aTempURL.isEmpty()) KillFile_Impl(m_aTempURL, m_xContext); m_aTempURL = aOldTempURL; @@ -1904,7 +1931,6 @@ void SAL_CALL OleEmbeddedObject::breakLink( const uno::Reference< embed::XStorag } catch (const uno::Exception&) { - delete pNewOleComponent; if (!m_aTempURL.isEmpty()) KillFile_Impl(m_aTempURL, m_xContext); m_aTempURL = aOldTempURL; |