diff options
Diffstat (limited to 'sfx2/source/doc')
-rw-r--r-- | sfx2/source/doc/docfile.cxx | 963 | ||||
-rw-r--r-- | sfx2/source/doc/docmacromode.cxx | 197 | ||||
-rw-r--r-- | sfx2/source/doc/guisaveas.cxx | 23 | ||||
-rw-r--r-- | sfx2/source/doc/objmisc.cxx | 137 | ||||
-rw-r--r-- | sfx2/source/doc/objserv.cxx | 139 | ||||
-rw-r--r-- | sfx2/source/doc/objstor.cxx | 202 | ||||
-rw-r--r-- | sfx2/source/doc/objxtor.cxx | 3 | ||||
-rw-r--r-- | sfx2/source/doc/sfxbasemodel.cxx | 12 |
8 files changed, 710 insertions, 966 deletions
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 3fec8e40bfb7..32ae33ec3c8b 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -84,6 +84,7 @@ #include <unotools/tempfile.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/componentcontext.hxx> +#include <framework/interaction.hxx> #include <unotools/streamhelper.hxx> #include <unotools/localedatawrapper.hxx> #ifndef _MSGBOX_HXX //autogen @@ -106,6 +107,7 @@ #include <unotools/streamwrap.hxx> #include <rtl/logfile.hxx> +#include <osl/file.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -373,10 +375,9 @@ public: uno::Sequence < util::RevisionTag > aVersions; - ::utl::TempFile* pTempDir; ::utl::TempFile* pTempFile; - uno::Reference < embed::XStorage > m_xReadStorage; + uno::Reference < embed::XStorage > m_xZipStorage; Reference < XInputStream > xInputStream; Reference < XStream > xStream; @@ -452,7 +453,6 @@ SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP ) nFileVersion( 0 ), pOrigFilter( 0 ), aExpireTime( Date() + 10, Time() ), - pTempDir( NULL ), pTempFile( NULL ), nLastStorageError( 0 ), m_bRemoveBackup( sal_False ), @@ -470,9 +470,6 @@ SfxMedium_Impl::~SfxMedium_Impl() if ( pTempFile ) delete pTempFile; - - if ( pTempDir ) - delete pTempDir; } //================================================================ @@ -491,18 +488,6 @@ SfxMedium_Impl::~SfxMedium_Impl() pOutStream( 0 ) //------------------------------------------------------------------ -/* -const SvGlobalName& SfxMedium::GetClassFilter() -{ - GetMedium_Impl(); - if( GetError() ) - return aFilterClass; - if( !bSetFilter && GetStorage() ) - SetClassFilter( GetStorage()->GetClassName() ); - return aFilterClass; -}*/ - -//------------------------------------------------------------------ void SfxMedium::ResetError() { eError = SVSTREAM_OK; @@ -557,15 +542,6 @@ sal_uInt32 SfxMedium::GetErrorCode() const } //------------------------------------------------------------------ -long SfxMedium::GetFileVersion() const -{ - if ( !pImp->nFileVersion && pFilter ) - return pFilter->GetVersion(); - else - return pImp->nFileVersion; -} - -//------------------------------------------------------------------ void SfxMedium::CheckFileDate( const util::DateTime& aInitDate ) { GetInitFileDate( sal_True ); @@ -665,6 +641,7 @@ Reference < XContent > SfxMedium::GetContent() const return pImp->aContent.get(); } +//------------------------------------------------------------------ ::rtl::OUString SfxMedium::GetBaseURL( bool bForSaving ) { ::rtl::OUString aBaseURL; @@ -703,7 +680,7 @@ SvStream* SfxMedium::GetInStream() if ( pInStream ) return pInStream; - if ( pImp->pTempFile || pImp->pTempDir ) + if ( pImp->pTempFile ) { pInStream = new SvFileStream( aName, nStorOpenMode ); @@ -747,7 +724,7 @@ void SfxMedium::CloseInStream_Impl() if ( pInStream && !GetContent().is() ) { - CreateTempFile(); + CreateTempFile( sal_True ); return; } @@ -755,7 +732,7 @@ void SfxMedium::CloseInStream_Impl() if ( pSet ) pSet->ClearItem( SID_INPUTSTREAM ); - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); pImp->xInputStream = uno::Reference< io::XInputStream >(); if ( !pOutStream ) @@ -775,8 +752,7 @@ SvStream* SfxMedium::GetOutStream() { // Create a temp. file if there is none because we always // need one. - if ( !pImp->pTempFile ) - CreateTempFile(); + CreateTempFile( sal_False ); if ( pImp->pTempFile ) { @@ -844,8 +820,7 @@ void SfxMedium::CreateFileStream() GetInStream(); if( pInStream ) { - if ( !pImp->pTempFile ) - CreateTempFile(); + CreateTempFile( sal_False ); pImp->bIsTemp = sal_True; CloseInStream_Impl(); } @@ -942,82 +917,17 @@ sal_Bool SfxMedium::IsPreview_Impl() } //------------------------------------------------------------------ -sal_Bool SfxMedium::TryStorage() -{ - GetStorage(); - - if ( pImp->xStorage.is() ) - return sal_True; - - // this code will be removed when binary filter components are available! - ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr( ::comphelper::getProcessServiceFactory() ); - ::com::sun::star::uno::Reference< ::com::sun::star::util::XArchiver > - xPacker( xSMgr->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.util.Archiver" ) ), ::com::sun::star::uno::UNO_QUERY ); - - if( !xPacker.is() ) - return sal_False; - - // extract extra data - ::rtl::OUString aPath = GetURLObject().PathToFileName(); - ::rtl::OUString aExtraData = xPacker->getExtraData( aPath ); - const ::rtl::OUString aSig1( DEFINE_CONST_UNICODE( "private:" ) ); - String aTmp( '?' ); - aTmp += String::CreateFromAscii("simpress");//pFilter->GetFilterContainer()->GetName(); - const ::rtl::OUString aSig2( aTmp ); - sal_Int32 nIndex1 = aExtraData.indexOf( aSig1 ); - sal_Int32 nIndex2 = aExtraData.indexOf( aSig2 ); - - if( nIndex1 != 0 || nIndex2 == -1 ) - return sal_False; - - nIndex1 += aSig1.getLength(); - ::rtl::OUString aTempDoku = aExtraData.copy( nIndex1, nIndex2 - nIndex1 ); - - // create a temp dir to unpack to - pImp->pTempDir = new ::utl::TempFile( NULL, sal_True ); - pImp->pTempDir->EnableKillingFile( sal_True ); - - // unpack all files to temp dir - ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs; - com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteractionHandler = GetInteractionHandler(); - if (xInteractionHandler.is()) - { - aArgs.realloc(1); - aArgs.getArray()[0].Name = DEFINE_CONST_UNICODE( "InteractionHandler" ); - aArgs.getArray()[0].Value <<= xInteractionHandler ; - } - ::com::sun::star::uno::Sequence< ::rtl::OUString > files(0); - - if( !xPacker->unpack( pImp->pTempDir->GetURL(), aPath, files, aArgs ) ) - return sal_False; - - String aNewName = pImp->pTempDir->GetURL(); - aNewName += '/'; - aNewName += String( aTempDoku ); - CloseInStream_Impl(); - String aTemp; - ::utl::LocalFileHelper::ConvertURLToPhysicalName( aNewName, aTemp ); - SetPhysicalName_Impl( aTemp ); - GetStorage(); - - return pImp->xStorage.is(); -} - -//------------------------------------------------------------------ -sal_Bool SfxMedium::BasedOnOriginalFile_Impl() -{ - return ( !pImp->pTempFile && !( aLogicName.Len() && pImp->m_bSalvageMode ) - && GetURLObject().GetMainURL( INetURLObject::NO_DECODE ).getLength() - && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) - && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ); -} - -//------------------------------------------------------------------ void SfxMedium::StorageBackup_Impl() { ::ucbhelper::Content aOriginalContent; Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv; - if ( BasedOnOriginalFile_Impl() && !pImp->m_aBackupURL.getLength() + + sal_Bool bBasedOnOriginalFile = ( !pImp->pTempFile && !( aLogicName.Len() && pImp->m_bSalvageMode ) + && GetURLObject().GetMainURL( INetURLObject::NO_DECODE ).getLength() + && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) + && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ); + + if ( bBasedOnOriginalFile && !pImp->m_aBackupURL.getLength() && ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, aOriginalContent ) ) { DoInternalBackup_Impl( aOriginalContent ); @@ -1036,26 +946,6 @@ void SfxMedium::StorageBackup_Impl() } //------------------------------------------------------------------ -::rtl::OUString SfxMedium::GetOutputStorageURL_Impl() -{ - String aStorageName; - - if ( aName.Len() ) - { - if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aStorageName ) ) - { - DBG_ERROR("Physical name not convertable!"); - } - } - else - { - aStorageName = GetURLObject().GetMainURL( INetURLObject::NO_DECODE ); - } - - return aStorageName; -} - -//------------------------------------------------------------------ uno::Reference < embed::XStorage > SfxMedium::GetOutputStorage() { if ( GetError() ) @@ -1249,7 +1139,9 @@ sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI ) try { // MediaDescriptor does this check also, the duplication should be avoided in future - pImp->aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bContentReadonly; + Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bContentReadonly; } catch( uno::Exception ) {} @@ -1420,222 +1312,82 @@ sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI ) } //------------------------------------------------------------------ -uno::Reference < embed::XStorage > SfxMedium::GetStorage() +uno::Reference < embed::XStorage > SfxMedium::GetStorage( sal_Bool bCreateTempIfNo ) { if ( pImp->xStorage.is() || bTriedStorage ) return pImp->xStorage; uno::Sequence< uno::Any > aArgs( 2 ); - String aStorageName; - if ( pImp->pTempFile || pImp->pTempDir ) - { - // open storage from the temporary file - if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aStorageName ) ) - { - DBG_ERROR("Physical name not convertable!"); - } + // the medium should be retrieved before temporary file creation + // to let the MediaDescriptor be filled with the streams + GetMedium_Impl(); - CloseOutStream(); - // create the set of the streams based on the temporary file - GetMedium_Impl(); + if ( bCreateTempIfNo ) + CreateTempFile( sal_False ); - OSL_ENSURE( pImp->xStream.is(), "It must be possible to create read write stream access!" ); - if ( pImp->xStream.is() ) - { - aArgs[0] <<= pImp->xStream; - pImp->bStorageBasedOnInStream = sal_True; - } - else - { - CloseStreams_Impl(); - aArgs[0] <<= ::rtl::OUString( aName ); - pImp->bStorageBasedOnInStream = sal_False; - } + GetMedium_Impl(); - aArgs[1] <<= ( nStorOpenMode&STREAM_WRITE ? embed::ElementModes::READWRITE : embed::ElementModes::READ ); + if ( GetError() ) + return pImp->xStorage; - try - { - pImp->xStorage = uno::Reference< embed::XStorage >( - ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ), - uno::UNO_QUERY ); - } - catch( uno::Exception& ) - { - //TODO/LATER: error handling; Error and LastStorageError - } - } - else + SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False); + if ( pRepairItem && pRepairItem->GetValue() ) { - // open the storage from original location - { - GetMedium_Impl(); - if ( GetError() ) - return pImp->xStorage; - - try - { - if ( IsReadOnly() && ::utl::LocalFileHelper::IsLocalFile( aLogicName ) ) - { - //TODO/LATER: performance problem if not controlled by special Mode in SfxMedium - //(should be done only for permanently open storages) - // create a copy, the following method will close all existing streams - CreateTempFile(); - - // create the set of the streams based on the temporary file - GetMedium_Impl(); - - OSL_ENSURE( pImp->xStream.is(), "It must be possible to create read write stream access!" ); - if ( pImp->xStream.is() ) - { - aArgs[0] <<= pImp->xStream; - pImp->bStorageBasedOnInStream = sal_True; - } - else - { - CloseStreams_Impl(); - aArgs[0] <<= ::rtl::OUString( aName ); - pImp->bStorageBasedOnInStream = sal_False; - } - - aArgs[1] <<= embed::ElementModes::READWRITE; - - } - else - { - // there is no explicit request to open the document readonly - - // create a storage on the stream - if ( pImp->xStream.is() ) - { - aArgs[0] <<= pImp->xStream; - aArgs[1] <<= ( ( nStorOpenMode & STREAM_WRITE ) ? - embed::ElementModes::READWRITE : embed::ElementModes::READ ); - - pImp->bStorageBasedOnInStream = sal_True; - } - else - { - // no readwrite stream, but it can be a case of http protocol - sal_Bool bReadOnly = sal_False; - - if ( aLogicName.CompareToAscii( "private:stream", 14 ) != COMPARE_EQUAL - && GetContent().is() ) - { - // unfortunately the content can not always have the interaction handler - // so in some cases it has to be set for some time - Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv; - Reference < ::com::sun::star::ucb::XCommandEnvironment > xOldEnv; - Reference < ::com::sun::star::task::XInteractionHandler > xInteractionHandler = ((SfxMedium*)this)->GetInteractionHandler(); - if ( xInteractionHandler.is() ) - xEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, - Reference< ::com::sun::star::ucb::XProgressHandler >() ); - - if ( xEnv.is() ) - { - xOldEnv = pImp->aContent.getCommandEnvironment(); - pImp->aContent.setCommandEnvironment( xEnv ); - } - - try - { - Any aAny = pImp->aContent.getPropertyValue( - ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsReadOnly" )) ); - - if ( ( aAny >>= bReadOnly ) && bReadOnly ) - { - GetItemSet()->Put( SfxBoolItem(SID_DOC_READONLY, sal_True)); - SetOpenMode( SFX_STREAM_READONLY, sal_False, sal_True ); - } - } - catch( uno::Exception& ) - {} - - if ( xEnv.is() ) - pImp->aContent.setCommandEnvironment( xOldEnv ); - } - - // if the document is opened as readonly the copy should be done according to selected approach - // if the document is opened for editing the copy should be done to use it as a temporary location for changes before the final transfer - // the following method will close all existing streams - CreateTempFile(); + // the storage should be created for repairing mode + CreateTempFile( sal_False ); + GetMedium_Impl(); - // create the set of the streams based on the temporary file - GetMedium_Impl(); + Reference< ::com::sun::star::ucb::XProgressHandler > xProgressHandler; + Reference< ::com::sun::star::task::XStatusIndicator > xStatusIndicator; - OSL_ENSURE( pImp->xStream.is(), "It must be possible to create read write stream access!" ); - if ( pImp->xStream.is() ) - { - aArgs[0] <<= pImp->xStream; - pImp->bStorageBasedOnInStream = sal_True; - } - else - { - CloseStreams_Impl(); - aArgs[0] <<= ::rtl::OUString( aName ); - pImp->bStorageBasedOnInStream = sal_False; - } + SFX_ITEMSET_ARG( GetItemSet(), pxProgressItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, sal_False ); + if( pxProgressItem && ( pxProgressItem->GetValue() >>= xStatusIndicator ) ) + xProgressHandler = Reference< ::com::sun::star::ucb::XProgressHandler >( + new utl::ProgressHandlerWrap( xStatusIndicator ) ); - if ( bReadOnly ) - aArgs[1] <<= embed::ElementModes::READ; - else - aArgs[1] <<= embed::ElementModes::READWRITE; - } - } + uno::Sequence< beans::PropertyValue > aAddProps( 2 ); + aAddProps[0].Name = ::rtl::OUString::createFromAscii( "RepairPackage" ); + aAddProps[0].Value <<= (sal_Bool)sal_True; + aAddProps[1].Name = ::rtl::OUString::createFromAscii( "StatusIndicator" ); + aAddProps[1].Value <<= xProgressHandler; - SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False); - if ( pRepairItem && pRepairItem->GetValue() ) - { - // the storage should be created for repairing mode - CreateTempFile(); - Reference< ::com::sun::star::ucb::XProgressHandler > xProgressHandler; - Reference< ::com::sun::star::task::XStatusIndicator > xStatusIndicator; - - SFX_ITEMSET_ARG( GetItemSet(), pxProgressItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, sal_False ); - if( pxProgressItem && ( pxProgressItem->GetValue() >>= xStatusIndicator ) ) - xProgressHandler = Reference< ::com::sun::star::ucb::XProgressHandler >( - new utl::ProgressHandlerWrap( xStatusIndicator ) ); - - uno::Sequence< beans::PropertyValue > aAddProps( 2 ); - aAddProps[0].Name = ::rtl::OUString::createFromAscii( "RepairPackage" ); - aAddProps[0].Value <<= (sal_Bool)sal_True; - aAddProps[1].Name = ::rtl::OUString::createFromAscii( "StatusIndicator" ); - aAddProps[1].Value <<= xProgressHandler; - - aArgs.realloc( 3 ); - aArgs[0] <<= ::rtl::OUString( aName ); - aArgs[1] <<= embed::ElementModes::READWRITE; - aArgs[2] <<= aAddProps; - - pImp->bStorageBasedOnInStream = sal_False; - } - - pImp->xStorage = uno::Reference< embed::XStorage >( - ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ), - uno::UNO_QUERY ); + // the first arguments will be filled later + aArgs.realloc( 3 ); + aArgs[2] <<= aAddProps; + } - if ( !pImp->xStorage.is() ) - throw uno::RuntimeException(); + if ( pImp->xStream.is() ) + { + // since the storage is based on temporary stream we open it always read-write + aArgs[0] <<= pImp->xStream; + aArgs[1] <<= embed::ElementModes::READWRITE; + pImp->bStorageBasedOnInStream = sal_True; + } + else if ( pImp->xInputStream.is() ) + { + // since the storage is based on temporary stream we open it always read-write + aArgs[0] <<= pImp->xInputStream; + aArgs[1] <<= embed::ElementModes::READ; + pImp->bStorageBasedOnInStream = sal_True; + } + else + { + CloseStreams_Impl(); + aArgs[0] <<= ::rtl::OUString( aName ); + aArgs[1] <<= embed::ElementModes::READ; + pImp->bStorageBasedOnInStream = sal_False; + } - if ( pRepairItem && pRepairItem->GetValue() ) - { - // in repairing mode the mediatype required by filter should be used - ::rtl::OUString aMediaType; - ::rtl::OUString aMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ); - uno::Reference < beans::XPropertySet > xPropSet( pImp->xStorage, uno::UNO_QUERY_THROW ); - xPropSet->getPropertyValue( aMediaTypePropName ) >>= aMediaType; - if ( !aMediaType.getLength() && pFilter ) - xPropSet->setPropertyValue( aMediaTypePropName, - uno::makeAny( ::rtl::OUString( pFilter->GetMimeType() ) ) ); - } - } - catch ( uno::Exception& ) - { - //TODO/MBA: error handling; Error and LastStorageError - pImp->bStorageBasedOnInStream = sal_False; - } - } + try + { + pImp->xStorage = uno::Reference< embed::XStorage >( + ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ), + uno::UNO_QUERY ); + } + catch( uno::Exception& ) + { + // impossibility to create the storage is no error } if( ( pImp->nLastStorageError = GetError() ) != SVSTREAM_OK ) @@ -1643,13 +1395,12 @@ uno::Reference < embed::XStorage > SfxMedium::GetStorage() pImp->xStorage = 0; if ( pInStream ) pInStream->Seek(0); - return NULL; + return uno::Reference< embed::XStorage >(); } bTriedStorage = sal_True; - //TODO/MBA: error handling; Error and LastStorageError - //if ( aStorage->GetError() == SVSTREAM_OK ) + // TODO/LATER: Get versionlist on demand if ( pImp->xStorage.is() ) { SetPasswordToStorage_Impl(); @@ -1716,15 +1467,6 @@ uno::Reference < embed::XStorage > SfxMedium::GetStorage() bResetStorage = TRUE; } - //TODO/MBA: error handling; Error and LastStorageError - if ( pImp->xStorage.is() ) - { /* - if( ( pImp->nLastStorageError = aStorage->GetError() ) != SVSTREAM_OK ) - bResetStorage = TRUE; - else if ( GetFilter() ) - aStorage->SetVersion( GetFilter()->GetVersion() );*/ - } - if ( bResetStorage ) { pImp->xStorage = 0; @@ -1737,28 +1479,25 @@ uno::Reference < embed::XStorage > SfxMedium::GetStorage() } //------------------------------------------------------------------ -uno::Reference< embed::XStorage > SfxMedium::GetLastCommitReadStorage_Impl() +uno::Reference< embed::XStorage > SfxMedium::GetZipStorageToSign_Impl( sal_Bool bReadOnly ) { - if ( !GetError() && !pImp->m_xReadStorage.is() ) + if ( !GetError() && !pImp->m_xZipStorage.is() ) { + // very careful!!! + // if bReadOnly == sal_False and there is no temporary file the original file might be used GetMedium_Impl(); try { - if ( pImp->xInputStream.is() ) + // we can not sign document if there is no stream + // should it be possible at all? + if ( !bReadOnly && pImp->xStream.is() ) { - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[0] <<= pImp->xInputStream; - aArgs[1] <<= embed::ElementModes::READ; - pImp->m_xReadStorage = uno::Reference< embed::XStorage >( - ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ), - uno::UNO_QUERY ); + pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream, embed::ElementModes::READWRITE ); } - else if ( GetStorage().is() ) + else if ( pImp->xInputStream.is() ) { - uno::Reference< embed::XStorage > xTempStor = ::comphelper::OStorageHelper::GetTemporaryStorage(); - GetStorage()->copyLastCommitTo( xTempStor ); - pImp->m_xReadStorage = xTempStor; + pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( ZIP_STORAGE_FORMAT_STRING, pImp->xInputStream ); } } catch( uno::Exception& ) @@ -1770,20 +1509,20 @@ uno::Reference< embed::XStorage > SfxMedium::GetLastCommitReadStorage_Impl() ResetError(); } - return pImp->m_xReadStorage; + return pImp->m_xZipStorage; } //------------------------------------------------------------------ -void SfxMedium::CloseReadStorage_Impl() +void SfxMedium::CloseZipStorage_Impl() { - if ( pImp->m_xReadStorage.is() ) + if ( pImp->m_xZipStorage.is() ) { try { - pImp->m_xReadStorage->dispose(); + pImp->m_xZipStorage->dispose(); } catch( uno::Exception& ) {} - pImp->m_xReadStorage = uno::Reference< embed::XStorage >(); + pImp->m_xZipStorage = uno::Reference< embed::XStorage >(); } } @@ -1885,11 +1624,12 @@ sal_Bool SfxMedium::StorageCommit_Impl() try { xTrans->commit(); - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); bResult = sal_True; } catch ( embed::UseBackupException& aBackupExc ) { + // since the temporary file is created always now, the scenario is close to be impossible if ( !pImp->pTempFile ) { OSL_ENSURE( pImp->m_aBackupURL.getLength(), "No backup on storage commit!\n" ); @@ -1936,9 +1676,6 @@ sal_Bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource, Reference< XOutputStream > aDestStream; ::ucbhelper::Content aOriginalContent; -// actualy it should work even for contents different from file content -// DBG_ASSERT( ::utl::LocalFileHelper::IsLocalFile( aDest.GetMainURL( INetURLObject::NO_DECODE ) ), -// "SfxMedium::TransactedTransferForFS() should be used only for local contents!" ); try { aOriginalContent = ::ucbhelper::Content( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv ); @@ -2241,57 +1978,10 @@ void SfxMedium::Transfer_Impl() catch ( uno::Exception& ) { //TODO/MBA: error handling - //if ( !GetError() ) - // SetError( xStor->GetError(, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )) ); } return; } - if ( pFilter && SOFFICE_FILEFORMAT_60 <= pFilter->GetVersion() ) - { - //TODO/LATER: how?! - /* - SFX_ITEMSET_ARG( GetItemSet(), pItem, SfxBoolItem, SID_UNPACK, sal_False); - if ( pItem && pItem->GetValue() ) - { - // this file must be stored without packing into a JAR file - // check for an existing unpacked storage - SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( GetName(), STREAM_STD_READ ); - if ( !pStream->GetError() ) - { - String aURL = UCBStorage::GetLinkedFile( *pStream ); - if ( aURL.Len() ) - // remove a possibly existing old folder - ::utl::UCBContentHelper::Kill( aURL ); - - DELETEZ( pStream ); - } - - // create a new folder based storage - SvStorageRef xStor = new SvStorage( TRUE, GetName(), STREAM_STD_READWRITE, STORAGE_CREATE_UNPACKED ); - - // copy package into unpacked storage - if ( xStor->GetError() == ERRCODE_NONE && GetStorage()->copyToStorage( xStor ) ) - { - // commit changes, writing will happen now - xStor->Commit(); - - // take new unpacked storage as own storage - if ( pImp->xStorage.is() ) - CloseStorage(); - - CloseStreams_Impl(); - - DELETEZ( pImp->pTempFile ); - ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), aName ); - SetStorage_Impl( xStor ); - } - else if ( !GetError() ) - SetError( xStor->GetError(, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )) ); - return; - }*/ - } - INetURLObject aDest( GetURLObject() ); // source is the temp file written so far @@ -2606,7 +2296,7 @@ void SfxMedium::GetMedium_Impl() // in case the temporary file exists the streams should be initialized from it, // but the original MediaDescriptor should not be changed - sal_Bool bFromTempFile = ( pImp->pTempFile || pImp->pTempDir ); + sal_Bool bFromTempFile = ( pImp->pTempFile != NULL ); if ( !bFromTempFile ) { @@ -2703,54 +2393,6 @@ void SfxMedium::CancelTransfers() pImp->xCancelManager->Cancel(); } -//---------------------------------------------------------------- -/* -String SfxMedium::GetStatusString( const SvProgressArg* pArg ) -{ - String aString; - StringList_Impl aSL( SfxResId( RID_DLSTATUS2 ), (USHORT)pArg->eStatus ); - USHORT nTotal = 0; - - if ( pArg->eStatus == SVBINDSTATUS_ENDDOWNLOADDATA && nTotal <= 1 ) - return aString; - - if( aSL ) - { - INetURLObject aObj( pArg->rStatus ); - aString = aSL.GetString(); - aString.SearchAndReplaceAscii( "$(HOST)", aObj.GetHost() ); - String aTarget = aObj.GetFull(); - if( aTarget.Len() <= 1 && pArg->eStatus != SVBINDSTATUS_CONNECTING ) - aTarget = aObj.GetHost(); - if( pArg->nMax ) - { - aTarget += DEFINE_CONST_UNICODE( " (" ); - AddNumber_Impl( aTarget, pArg->nMax ); - aTarget += ')'; - } - - aString.SearchAndReplaceAscii( "$(TARGET)",aTarget ); - String aNumber; - AddNumber_Impl( aNumber, pArg->nProgress ); - if( pArg->nRate ) - { - aNumber+= DEFINE_CONST_UNICODE( " (" ); - AddNumber_Impl( aNumber, (ULONG)pArg->nRate ); - aNumber+= DEFINE_CONST_UNICODE( "/s)" ); - } - if( pArg->nMax && pArg->nProgress && pArg->nMax != pArg->nProgress ) - { - aNumber += DEFINE_CONST_UNICODE( " [" ); - float aPerc = pArg->nProgress / (float)pArg->nMax; - aNumber += String::CreateFromInt32( (USHORT)(aPerc * 100) ); - aNumber += DEFINE_CONST_UNICODE( "%]" ); - } - aString.SearchAndReplaceAscii( "$(BYTE)", aNumber ); - } - return aString; -} -*/ - sal_Bool SfxMedium::IsRemote() { return bRemote; @@ -2910,7 +2552,7 @@ SfxMedium::SfxMedium( const SfxMedium& rMedium, sal_Bool bTemporary ) pFilter = rMedium.pFilter; Init_Impl(); if( bTemporary ) - CreateTempFile(); + CreateTempFile( sal_True ); } //------------------------------------------------------------------ @@ -2989,7 +2631,7 @@ void SfxMedium::Close() const SvStream *pStream = aStorage->GetSvStream(); if ( pStream && pStream == pInStream ) { - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); pInStream = NULL; pImp->xInputStream = Reference < XInputStream >(); pImp->xLockBytes.Clear(); @@ -3022,7 +2664,7 @@ void SfxMedium::CloseAndRelease() const SvStream *pStream = aStorage->GetSvStream(); if ( pStream && pStream == pInStream ) { - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); pInStream = NULL; pImp->xInputStream = Reference < XInputStream >(); pImp->xLockBytes.Clear(); @@ -3062,7 +2704,7 @@ void SfxMedium::UnlockFile() void SfxMedium::CloseAndReleaseStreams_Impl() { - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); uno::Reference< io::XInputStream > xInToClose = pImp->xInputStream; uno::Reference< io::XOutputStream > xOutToClose; @@ -3184,26 +2826,6 @@ void SfxMedium::SetPhysicalName_Impl( const String& rNameP ) } } -//---------------------------------------------------------------- -void SfxMedium::MoveTempTo_Impl( SfxMedium* pMedium ) -{ - if ( pMedium && pMedium != this && pImp->pTempFile ) - { - if( pMedium->pImp->pTempFile ) - delete pMedium->pImp->pTempFile; - pMedium->pImp->pTempFile = pImp->pTempFile; - - pImp->pTempFile->EnableKillingFile( sal_True ); - pImp->pTempFile = NULL; - - pMedium->aName = pMedium->pImp->pTempFile->GetFileName(); - - pMedium->CloseInStream(); - pMedium->CloseStorage(); - pMedium->pImp->aContent = ::ucbhelper::Content(); - } -} - //------------------------------------------------------------------ void SfxMedium::SetTemporary( sal_Bool bTemp ) { @@ -3407,22 +3029,15 @@ SfxMedium::~SfxMedium() delete pURLObj; delete pImp; } -//------------------------------------------------------------------ +//------------------------------------------------------------------ void SfxMedium::SetItemSet(SfxItemSet *pNewSet) { delete pSet; pSet = pNewSet; } -//------------------------------------------------------------------ -void SfxMedium::SetClassFilter( const SvGlobalName & rFilterClass ) -{ - bSetFilter = sal_True; - aFilterClass = rFilterClass; -} //---------------------------------------------------------------- - const INetURLObject& SfxMedium::GetURLObject() const { if( !pURLObj ) @@ -3755,131 +3370,122 @@ sal_Bool SfxMedium::IsReadOnly() } //---------------------------------------------------------------- -void SfxMedium::TryToSwitchToRepairedTemp() +sal_Bool SfxMedium::SetWritableForUserOnly( const ::rtl::OUString& aURL ) { - // the medium should be opened in repair mode - SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, FALSE ); - if ( pRepairItem && pRepairItem->GetValue() ) + // UCB does not allow to allow write access only for the user, + // use osl API + sal_Bool bResult = sal_False; + + ::osl::DirectoryItem aDirItem; + if ( ::osl::DirectoryItem::get( aURL, aDirItem ) == ::osl::FileBase::E_None ) { - DBG_ASSERT( pImp->xStorage.is(), "Possible performance problem" ); - if ( GetStorage().is() ) + ::osl::FileStatus aFileStatus( FileStatusMask_Attributes ); + if ( aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None + && aFileStatus.isValid( FileStatusMask_Attributes ) ) { - ::utl::TempFile* pTmpFile = new ::utl::TempFile(); - pTmpFile->EnableKillingFile( sal_True ); - ::rtl::OUString aNewName = pTmpFile->GetFileName(); + sal_uInt64 nAttributes = aFileStatus.getAttributes(); - if( aNewName.getLength() ) - { - try - { - uno::Reference < embed::XStorage > xNewStorage = comphelper::OStorageHelper::GetStorageFromURL( aNewName, - embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); - //SvStorageRef aNewStorage = new SvStorage( sal_True, aNewName, STREAM_WRITE | STREAM_TRUNC, STORAGE_TRANSACTED ); - - pImp->xStorage->copyToStorage( xNewStorage ); - //if ( aNewStorage->GetError() == SVSTREAM_OK ) - { - CloseInStream(); - CloseStorage(); - if ( pImp->pTempFile ) - DELETEZ( pImp->pTempFile ); + nAttributes &= ~(Attribute_OwnWrite | + Attribute_GrpWrite | + Attribute_OthWrite | + Attribute_ReadOnly); + nAttributes |= Attribute_OwnWrite; - pImp->pTempFile = pTmpFile; - aName = aNewName; - } - } - catch ( uno::Exception& ) - { - //TODO/MBA: error handling - //SetError( aNewStorage->GetError(, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )) ); - } - } - else - SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); - - if (pImp->pTempFile != pTmpFile) - delete pTmpFile; + bResult = ( osl::File::setAttributes( aURL, nAttributes ) == ::osl::FileBase::E_None ); } - else - SetError( ERRCODE_IO_CANTREAD, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); } + + return bResult; } //---------------------------------------------------------------- -void SfxMedium::CreateTempFile() +void SfxMedium::CreateTempFile( sal_Bool bReplace ) { if ( pImp->pTempFile ) { + if ( !bReplace ) + return; + DELETEZ( pImp->pTempFile ); aName = String(); } - StreamMode nOpenMode = nStorOpenMode; - BOOL bCopy = ( nStorOpenMode == nOpenMode && ! ( nOpenMode & STREAM_TRUNC ) ); - if ( bCopy && !pInStream ) - { - if ( GetContent().is() ) - { - try - { - // make sure that the desired file exists before trying to open - SvMemoryStream aStream(0,0); - ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream ); - Reference< XInputStream > xInput( pInput ); - - InsertCommandArgument aInsertArg; - aInsertArg.Data = xInput; - - aInsertArg.ReplaceExisting = sal_False; - Any aCmdArg; - aCmdArg <<= aInsertArg; - pImp->aContent.executeCommand( ::rtl::OUString::createFromAscii( "insert" ), aCmdArg ); - } - catch ( Exception& ) - { - // it is NOT an error when the stream already exists! - GetInStream(); - } - } - } - - nStorOpenMode = nOpenMode; - ResetError(); - pImp->pTempFile = new ::utl::TempFile(); pImp->pTempFile->EnableKillingFile( sal_True ); aName = pImp->pTempFile->GetFileName(); - if ( !aName.Len() ) + ::rtl::OUString aTmpURL = pImp->pTempFile->GetURL(); + if ( !aName.Len() || !aTmpURL.getLength() ) { SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); return; } - if ( bCopy && pInStream ) + if ( !( nStorOpenMode & STREAM_TRUNC ) ) { - GetOutStream(); - if ( pOutStream ) + if ( GetContent().is() + && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) + && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ) { - char *pBuf = new char [8192]; - sal_uInt32 nErr = ERRCODE_NONE; - - pInStream->Seek(0); - pOutStream->Seek(0); + // if there is already such a document, we should copy it + // if it is a file system use OS copy process + sal_Bool bTransferSuccess = sal_False; + try + { + uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv; + INetURLObject aTmpURLObj( aTmpURL ); + ::rtl::OUString aFileName = aTmpURLObj.getName( INetURLObject::LAST_SEGMENT, + true, + INetURLObject::DECODE_WITH_CHARSET ); + if ( aFileName.getLength() && aTmpURLObj.removeSegment() ) + { + ::ucbhelper::Content aTargetContent( aTmpURLObj.GetMainURL( INetURLObject::NO_DECODE ), xComEnv ); + if ( aTargetContent.transferContent( pImp->aContent, ::ucbhelper::InsertOperation_COPY, aFileName, NameClash::OVERWRITE ) ) + { + SetWritableForUserOnly( aTmpURL ); + bTransferSuccess = sal_True; + } + } + } + catch( uno::Exception& ) + {} - while( !pInStream->IsEof() && nErr == ERRCODE_NONE ) + if ( !bTransferSuccess ) { - sal_uInt32 nRead = pInStream->Read( pBuf, 8192 ); - nErr = pInStream->GetError(); - pOutStream->Write( pBuf, nRead ); + SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); + return; } - delete[] pBuf; + CloseOutStream(); CloseInStream(); } - CloseOutStream_Impl(); + else if ( pInStream ) + { + // the case when there is no URL-access available or this is a remote protocoll + // but there is an input stream + GetOutStream(); + if ( pOutStream ) + { + char *pBuf = new char [8192]; + sal_uInt32 nErr = ERRCODE_NONE; + + pInStream->Seek(0); + pOutStream->Seek(0); + + while( !pInStream->IsEof() && nErr == ERRCODE_NONE ) + { + sal_uInt32 nRead = pInStream->Read( pBuf, 8192 ); + nErr = pInStream->GetError(); + pOutStream->Write( pBuf, nRead ); + } + + delete[] pBuf; + CloseInStream(); + } + CloseOutStream_Impl(); + } + else + CloseInStream(); } - else - CloseInStream(); CloseStorage(); } @@ -3887,6 +3493,7 @@ void SfxMedium::CreateTempFile() //---------------------------------------------------------------- void SfxMedium::CreateTempFileNoCopy() { + // this call always replaces the existing temporary file if ( pImp->pTempFile ) delete pImp->pTempFile; @@ -3944,100 +3551,120 @@ void SfxMedium::SetCharset( ::rtl::OUString aChs ) pImp->aCharset = aChs; } -sal_Bool SfxMedium::SignContents_Impl( sal_Bool bScriptingContent ) +sal_Bool SfxMedium::SignContents_Impl( sal_Bool bScriptingContent, const ::rtl::OUString& aODFVersion, sal_Bool bHasValidDocumentSignature ) { - DBG_ASSERT( GetStorage().is(), "SfxMedium::SignContents_Impl - Storage doesn't exist!" ); - sal_Bool bChanges = FALSE; - ::com::sun::star::uno::Reference< ::com::sun::star::security::XDocumentDigitalSignatures > xD( - comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), ::com::sun::star::uno::UNO_QUERY ); - - // TODO/LATER: error handling - if ( xD.is() && GetStorage().is() ) + // the medium should be closed to be able to sign, the caller is responsible to close it + if ( !IsOpen() && !GetError() ) { - sal_Int32 nEncrMode = IsReadOnly() ? embed::ElementModes::READ - : embed::ElementModes::READWRITE; + // The component should know if there was a valid document signature, since + // it should show a warning in this case + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[0] <<= aODFVersion; + aArgs[1] <<= bHasValidDocumentSignature; + ::com::sun::star::uno::Reference< ::com::sun::star::security::XDocumentDigitalSignatures > xSigner( + comphelper::getProcessServiceFactory()->createInstanceWithArguments( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), + aArgs ), + ::com::sun::star::uno::UNO_QUERY ); - try + if ( xSigner.is() ) { - uno::Reference< embed::XStorage > xMetaInf = GetStorage()->openStorageElement( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), - nEncrMode ); - if ( !xMetaInf.is() ) - throw uno::RuntimeException(); - - if ( bScriptingContent ) + uno::Reference< embed::XStorage > xWriteableZipStor; + if ( !IsReadOnly() ) { - if ( !IsReadOnly() ) + // we can reuse the temporary file if there is one already + CreateTempFile( sal_False ); + GetMedium_Impl(); + + try { - uno::Reference< io::XStream > xStream = xMetaInf->openStreamElement( - xD->getScriptingContentSignatureDefaultStreamName(), - nEncrMode ); - if ( !xStream.is() ) + if ( !pImp->xStream.is() ) throw uno::RuntimeException(); - try + xWriteableZipStor = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream ); + if ( !xWriteableZipStor.is() ) + throw uno::RuntimeException(); + + uno::Reference< embed::XStorage > xMetaInf = xWriteableZipStor->openStorageElement( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), + embed::ElementModes::READWRITE ); + if ( !xMetaInf.is() ) + throw uno::RuntimeException(); + + if ( bScriptingContent ) { - // to leave the stream unencrypted as before - uno::Reference< beans::XPropertySet > xStrmProps( xStream, uno::UNO_QUERY_THROW ); - xStrmProps->setPropertyValue( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ), - uno::makeAny( (sal_Bool)sal_False ) ); + // If the signature has already the document signature it will be removed + // after the scripting signature is inserted. + uno::Reference< io::XStream > xStream( + xMetaInf->openStreamElement( xSigner->getScriptingContentSignatureDefaultStreamName(), + embed::ElementModes::READWRITE ), + uno::UNO_SET_THROW ); + + if ( xSigner->signScriptingContent( GetZipStorageToSign_Impl(), xStream ) ) + { + // remove the document signature if any + ::rtl::OUString aDocSigName = xSigner->getDocumentContentSignatureDefaultStreamName(); + if ( aDocSigName.getLength() && xMetaInf->hasByName( aDocSigName ) ) + xMetaInf->removeElement( aDocSigName ); + + uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW ); + xTransact->commit(); + xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW ); + xTransact->commit(); + + // the temporary file has been written, commit it to the original file + Commit(); + bChanges = TRUE; + } } - catch ( uno::Exception& ) - {} - - if ( xD->signScriptingContent( GetLastCommitReadStorage_Impl(), xStream ) ) + else { - uno::Reference< embed::XTransactedObject > xTrans( xMetaInf, uno::UNO_QUERY ); - xTrans->commit(); - Commit(); - bChanges = TRUE; + uno::Reference< io::XStream > xStream( + xMetaInf->openStreamElement( xSigner->getDocumentContentSignatureDefaultStreamName(), + embed::ElementModes::READWRITE ), + uno::UNO_SET_THROW ); + + if ( xSigner->signDocumentContent( GetZipStorageToSign_Impl(), xStream ) ) + { + uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW ); + xTransact->commit(); + xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW ); + xTransact->commit(); + + // the temporary file has been written, commit it to the original file + Commit(); + bChanges = TRUE; + } } } - else - xD->showScriptingContentSignatures( GetLastCommitReadStorage_Impl(), uno::Reference< io::XInputStream >() ); + catch ( uno::Exception& ) + { + OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" ); + } + + CloseAndRelease(); } else { - if ( !IsReadOnly() ) + try { - uno::Reference< io::XStream > xStream = xMetaInf->openStreamElement( - xD->getDocumentContentSignatureDefaultStreamName(), - nEncrMode ); - if ( !xStream.is() ) - throw uno::RuntimeException(); - - try - { - // to leave the stream unencrypted as before - uno::Reference< beans::XPropertySet > xStrmProps( xStream, uno::UNO_QUERY_THROW ); - xStrmProps->setPropertyValue( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ), - uno::makeAny( (sal_Bool)sal_False ) ); - } - catch ( uno::Exception& ) - {} - - if ( xD->signDocumentContent( GetLastCommitReadStorage_Impl(), xStream ) ) - { - uno::Reference< embed::XTransactedObject > xTrans( xMetaInf, uno::UNO_QUERY ); - xTrans->commit(); - Commit(); - bChanges = TRUE; - } - + if ( bScriptingContent ) + xSigner->showScriptingContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() ); + else + xSigner->showDocumentContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() ); + } + catch( uno::Exception& ) + { + OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" ); } - else - xD->showDocumentContentSignatures( GetLastCommitReadStorage_Impl(), uno::Reference< io::XInputStream >() ); } } - catch( uno::Exception& ) - { - OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" ); - } + + ResetError(); } + return bChanges; } @@ -4152,6 +3779,38 @@ BOOL SfxMedium::IsOpen() const return aResult; } +sal_Bool SfxMedium::CallApproveHandler( const uno::Reference< task::XInteractionHandler >& xHandler, uno::Any aRequest, sal_Bool bAllowAbort ) +{ + sal_Bool bResult = sal_False; + + if ( xHandler.is() ) + { + try + { + uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( bAllowAbort ? 2 : 1 ); + + ::rtl::Reference< ::framework::ContinuationApprove > pApprove( new ::framework::ContinuationApprove() ); + aContinuations[ 0 ] = pApprove.get(); + + if ( bAllowAbort ) + { + ::rtl::Reference< ::framework::ContinuationAbort > pAbort( new ::framework::ContinuationAbort() ); + aContinuations[ 1 ] = pAbort.get(); + } + + uno::Reference< task::XInteractionRequest > xRequest( new ::framework::InteractionRequest( aRequest, aContinuations ) ); + xHandler->handle( xRequest ); + + bResult = pApprove->isSelected(); + } + catch( const Exception& ) + { + } + } + + return bResult; +} + ::rtl::OUString SfxMedium::SwitchDocumentToTempFile() { // the method returns empty string in case of failure @@ -4189,7 +3848,7 @@ BOOL SfxMedium::IsOpen() const GetMedium_Impl(); LockOrigFileOnDemand( sal_False, sal_False ); - CreateTempFile(); + CreateTempFile( sal_True ); GetMedium_Impl(); if ( pImp->xStream.is() ) @@ -4247,7 +3906,7 @@ sal_Bool SfxMedium::SwitchDocumentToFile( ::rtl::OUString aURL ) // open the temporary file based document GetMedium_Impl(); LockOrigFileOnDemand( sal_False, sal_False ); - CreateTempFile(); + CreateTempFile( sal_True ); GetMedium_Impl(); if ( pImp->xStream.is() ) diff --git a/sfx2/source/doc/docmacromode.cxx b/sfx2/source/doc/docmacromode.cxx index e56a65d3f551..f1b889821de7 100644 --- a/sfx2/source/doc/docmacromode.cxx +++ b/sfx2/source/doc/docmacromode.cxx @@ -33,6 +33,7 @@ #include "sfx2/docmacromode.hxx" #include "sfx2/signaturestate.hxx" +#include "sfx2/docfile.hxx" /** === begin UNO includes === **/ #include <com/sun/star/document/MacroExecMode.hpp> @@ -85,14 +86,14 @@ namespace sfx2 //==================================================================== struct DocumentMacroMode_Data { - IMacroDocumentAccess& rDocumentAccess; - sal_Bool bMacroDisabledMessageShown; - sal_Bool bDocMacroDisabledMessageShown; - - DocumentMacroMode_Data( IMacroDocumentAccess& _rDocumentAccess ) - :rDocumentAccess( _rDocumentAccess ) - ,bMacroDisabledMessageShown( sal_False ) - ,bDocMacroDisabledMessageShown( sal_False ) + IMacroDocumentAccess& m_rDocumentAccess; + sal_Bool m_bMacroDisabledMessageShown; + sal_Bool m_bDocMacroDisabledMessageShown; + + DocumentMacroMode_Data( IMacroDocumentAccess& rDocumentAccess ) + :m_rDocumentAccess( rDocumentAccess ) + ,m_bMacroDisabledMessageShown( sal_False ) + ,m_bDocMacroDisabledMessageShown( sal_False ) { } }; @@ -103,85 +104,37 @@ namespace sfx2 namespace { //................................................................ - /** calls the given interaction handler with the given interaction request, offering - the two continuations "Approve" and "Abort" - - @return - <TRUE/> if and only if the given handler handled the the request, and the "Approve" - continuation was selected. - */ - sal_Bool lcl_callInterActionHandler( const Reference< XInteractionHandler >& _rxHandler, const Any& _rRequest ) + void lcl_showGeneralSfxErrorOnce( const Reference< XInteractionHandler >& rxHandler, const sal_Int32 nSfxErrorCode, sal_Bool& rbAlreadyShown ) { - if ( !_rxHandler.is() ) - return sal_False; - - try - { - Sequence< Reference< XInteractionContinuation > > aContinuations(2); - - ::rtl::Reference< ::framework::ContinuationAbort > pAbort( new ::framework::ContinuationAbort() ); - aContinuations[ 0 ] = pAbort.get(); - - ::rtl::Reference< ::framework::ContinuationApprove > pApprove( new ::framework::ContinuationApprove() ); - aContinuations[ 1 ] = pApprove.get(); - - Reference< XInteractionRequest > xRequest( new ::framework::InteractionRequest( _rRequest, aContinuations ) ); - _rxHandler->handle( xRequest ); - - if ( pApprove->isSelected() ) - return sal_True; - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } - return sal_False; - } - - //................................................................ - void lcl_showGeneralSfxErrorOnce( const Reference< XInteractionHandler >& _rxHandler, const sal_Int32 _nSfxErrorCode, sal_Bool& _rbAlreadyShown ) - { - if ( _rbAlreadyShown ) + if ( rbAlreadyShown ) return; ErrorCodeRequest aErrorCodeRequest; - aErrorCodeRequest.ErrCode = _nSfxErrorCode; - - _rbAlreadyShown = lcl_callInterActionHandler( _rxHandler, makeAny( aErrorCodeRequest ) ); - } + aErrorCodeRequest.ErrCode = nSfxErrorCode; - //................................................................ - void lcl_showMacrosDisabledError( const Reference< XInteractionHandler >& _rxHandler, sal_Bool& _rbAlreadyShown ) - { - lcl_showGeneralSfxErrorOnce( _rxHandler, ERRCODE_SFX_MACROS_SUPPORT_DISABLED, _rbAlreadyShown ); + SfxMedium::CallApproveHandler( rxHandler, makeAny( aErrorCodeRequest ), sal_False ); + rbAlreadyShown = sal_True; } //................................................................ - void lcl_showDocumentMacrosDisabledError( const Reference< XInteractionHandler >& _rxHandler, sal_Bool& _rbAlreadyShown ) + void lcl_showMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown ) { - lcl_showGeneralSfxErrorOnce( _rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED, _rbAlreadyShown ); + lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_MACROS_SUPPORT_DISABLED, rbAlreadyShown ); } //................................................................ - sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& _rxHandler, - const ::rtl::OUString& _rDocumentLocation ) + void lcl_showDocumentMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown ) { - DocumentMacroConfirmationRequest aRequest; - aRequest.DocumentURL = _rDocumentLocation; - return lcl_callInterActionHandler( _rxHandler, makeAny( aRequest ) ); + lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED, rbAlreadyShown ); } //................................................................ - sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& _rxHandler, - const ::rtl::OUString& _rDocumentLocation, const Reference< XStorage >& _rxDocStor, - const Sequence< DocumentSignatureInformation >& _rDocSigInfo ) + sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& rxHandler, + const ::rtl::OUString& rDocumentLocation ) { DocumentMacroConfirmationRequest aRequest; - aRequest.DocumentURL = _rDocumentLocation; - aRequest.DocumentStorage = _rxDocStor; - aRequest.DocumentSignatureInformation = _rDocSigInfo; - aRequest.Classification = InteractionClassification_QUERY; - return lcl_callInterActionHandler( _rxHandler, makeAny( aRequest ) ); + aRequest.DocumentURL = rDocumentLocation; + return SfxMedium::CallApproveHandler( rxHandler, makeAny( aRequest ), sal_True ); } } @@ -189,8 +142,8 @@ namespace sfx2 //= DocumentMacroMode //==================================================================== //-------------------------------------------------------------------- - DocumentMacroMode::DocumentMacroMode( IMacroDocumentAccess& _rDocumentAccess ) - :m_pData( new DocumentMacroMode_Data( _rDocumentAccess ) ) + DocumentMacroMode::DocumentMacroMode( IMacroDocumentAccess& rDocumentAccess ) + :m_pData( new DocumentMacroMode_Data( rDocumentAccess ) ) { } @@ -202,26 +155,26 @@ namespace sfx2 //-------------------------------------------------------------------- sal_Bool DocumentMacroMode::allowMacroExecution() { - m_pData->rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::ALWAYS_EXECUTE_NO_WARN ); + m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::ALWAYS_EXECUTE_NO_WARN ); return sal_True; } //-------------------------------------------------------------------- sal_Bool DocumentMacroMode::disallowMacroExecution() { - m_pData->rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::NEVER_EXECUTE ); + m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::NEVER_EXECUTE ); return sal_False; } //-------------------------------------------------------------------- - sal_Bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& _rxInteraction ) + sal_Bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& rxInteraction ) { - sal_uInt16 nMacroExecutionMode = m_pData->rDocumentAccess.getCurrentMacroExecMode(); + sal_uInt16 nMacroExecutionMode = m_pData->m_rDocumentAccess.getCurrentMacroExecMode(); if ( SvtSecurityOptions().IsMacroDisabled() ) { // no macro should be executed at all - lcl_showMacrosDisabledError( _rxInteraction, m_pData->bMacroDisabledMessageShown ); + lcl_showMacrosDisabledError( rxInteraction, m_pData->m_bMacroDisabledMessageShown ); return disallowMacroExecution(); } @@ -273,9 +226,10 @@ namespace sfx2 try { - ::rtl::OUString sReferrer( m_pData->rDocumentAccess.getDocumentLocation() ); + ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() ); // get document location from medium name and check whether it is a trusted one + // the service is created ohne document version, since it is not of interest here ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); Reference< XDocumentDigitalSignatures > xSignatures; if ( aContext.createComponent( "com.sun.star.security.DocumentDigitalSignatures", xSignatures ) ) @@ -295,61 +249,35 @@ namespace sfx2 // at this point it is clear that the document is not in the secure location if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN ) { - lcl_showDocumentMacrosDisabledError( _rxInteraction, m_pData->bDocMacroDisabledMessageShown ); + lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown ); return disallowMacroExecution(); } // check whether the document is signed with trusted certificate - if ( xSignatures.is() && nMacroExecutionMode != MacroExecMode::FROM_LIST ) + if ( nMacroExecutionMode != MacroExecMode::FROM_LIST ) { - Sequence< DocumentSignatureInformation > aScriptingSignatureInformations; - Reference < XStorage > xStore( m_pData->rDocumentAccess.getLastCommitDocumentStorage() ); + // the trusted macro check will also retrieve the signature state ( small optimization ) + sal_Bool bHasTrustedMacroSignature = m_pData->m_rDocumentAccess.hasTrustedScriptingSignature( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ); - sal_uInt16 nSignatureState = m_pData->rDocumentAccess.getScriptingSignatureState(); + sal_uInt16 nSignatureState = m_pData->m_rDocumentAccess.getScriptingSignatureState(); if ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN ) { + // the signature is broken, no macro execution if ( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ) - { - m_pData->rDocumentAccess.showBrokenSignatureWarning( _rxInteraction ); - return disallowMacroExecution(); - } + m_pData->m_rDocumentAccess.showBrokenSignatureWarning( rxInteraction ); + + return disallowMacroExecution(); } - else + else if ( bHasTrustedMacroSignature ) { - if ( ( ( nSignatureState == SIGNATURESTATE_SIGNATURES_OK ) - || ( nSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) - ) - && xStore.is() - ) - { - aScriptingSignatureInformations = - xSignatures->verifyScriptingContentSignatures( xStore, NULL ); - } + // there is trusted macro signature, allow macro execution + return allowMacroExecution(); } - - sal_Int32 nNumOfInfos = aScriptingSignatureInformations.getLength(); - - // from now on sReferrer is the system file path - // sReferrer = INetURLObject::decode( sReferrer, '%', INetURLObject::DECODE_WITH_CHARSET ); - ::rtl::OUString aSystemFileURL; - if ( osl::FileBase::getSystemPathFromFileURL( sReferrer, aSystemFileURL ) == osl::FileBase::E_None ) - sReferrer = aSystemFileURL; - - if ( nNumOfInfos ) + else if ( nSignatureState == SIGNATURESTATE_SIGNATURES_OK + || nSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) { - for ( sal_Int32 i = 0; i < nNumOfInfos; i++ ) - if ( xSignatures->isAuthorTrusted( aScriptingSignatureInformations[i].Signer ) ) - { - // there's at least one author we trust which signed the doc - return allowMacroExecution(); - } - - if ( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ) - { - sal_Bool bApproved = lcl_showMacroWarning( _rxInteraction, - sReferrer, xStore, aScriptingSignatureInformations ); - return ( bApproved ? allowMacroExecution() : disallowMacroExecution() ); - } + // there is valid signature, but it is not from the trusted author + return disallowMacroExecution(); } } @@ -359,9 +287,8 @@ namespace sfx2 ) { if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN ) - { - lcl_showDocumentMacrosDisabledError( _rxInteraction, m_pData->bDocMacroDisabledMessageShown ); - } + lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown ); + return disallowMacroExecution(); } } @@ -381,13 +308,13 @@ namespace sfx2 if ( eAutoConfirm == eNoAutoConfirm ) { - ::rtl::OUString sReferrer( m_pData->rDocumentAccess.getDocumentLocation() ); + ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() ); ::rtl::OUString aSystemFileURL; if ( osl::FileBase::getSystemPathFromFileURL( sReferrer, aSystemFileURL ) == osl::FileBase::E_None ) sReferrer = aSystemFileURL; - bSecure = lcl_showMacroWarning( _rxInteraction, sReferrer ); + bSecure = lcl_showMacroWarning( rxInteraction, sReferrer ); } else bSecure = ( eAutoConfirm == eAutoConfirmApprove ); @@ -398,7 +325,7 @@ namespace sfx2 //-------------------------------------------------------------------- sal_Bool DocumentMacroMode::isMacroExecutionDisallowed() const { - return m_pData->rDocumentAccess.getCurrentMacroExecMode() == MacroExecMode::NEVER_EXECUTE; + return m_pData->m_rDocumentAccess.getCurrentMacroExecMode() == MacroExecMode::NEVER_EXECUTE; } //-------------------------------------------------------------------- @@ -407,7 +334,7 @@ namespace sfx2 sal_Bool bHasMacroLib = sal_False; try { - Reference< XEmbeddedScripts > xScripts( m_pData->rDocumentAccess.getEmbeddedDocumentScripts() ); + Reference< XEmbeddedScripts > xScripts( m_pData->m_rDocumentAccess.getEmbeddedDocumentScripts() ); Reference< XLibraryContainer > xContainer; if ( xScripts.is() ) xContainer.set( xScripts->getBasicLibraries(), UNO_QUERY_THROW ); @@ -457,21 +384,21 @@ namespace sfx2 } //-------------------------------------------------------------------- - sal_Bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& _rxStorage ) + sal_Bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& rxStorage ) { sal_Bool bHasMacros = sal_False; - if ( _rxStorage.is() ) + if ( rxStorage.is() ) { try { static const ::rtl::OUString s_sBasicStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ) ); static const ::rtl::OUString s_sScriptsStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) ) ); - bHasMacros =( ( _rxStorage->hasByName( s_sBasicStorageName ) - && _rxStorage->isStorageElement( s_sBasicStorageName ) + bHasMacros =( ( rxStorage->hasByName( s_sBasicStorageName ) + && rxStorage->isStorageElement( s_sBasicStorageName ) ) - || ( _rxStorage->hasByName( s_sScriptsStorageName ) - && _rxStorage->isStorageElement( s_sScriptsStorageName ) + || ( rxStorage->hasByName( s_sScriptsStorageName ) + && rxStorage->isStorageElement( s_sScriptsStorageName ) ) ); } @@ -484,7 +411,7 @@ namespace sfx2 } //-------------------------------------------------------------------- - sal_Bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& _rxInteraction ) + sal_Bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& rxInteraction ) { sal_Bool bAllow = sal_False; if ( SvtSecurityOptions().IsMacroDisabled() ) @@ -494,9 +421,9 @@ namespace sfx2 } else { - if ( m_pData->rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() ) + if ( m_pData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() ) { - bAllow = adjustMacroMode( _rxInteraction ); + bAllow = adjustMacroMode( rxInteraction ); } else if ( !isMacroExecutionDisallowed() ) { diff --git a/sfx2/source/doc/guisaveas.cxx b/sfx2/source/doc/guisaveas.cxx index c46a467fa41d..5916fb625787 100644 --- a/sfx2/source/doc/guisaveas.cxx +++ b/sfx2/source/doc/guisaveas.cxx @@ -87,6 +87,8 @@ #include <sfxtypes.hxx> #include "alienwarn.hxx" +#include "../appl/app.hrc" + #define DOCPROPSNUM 17 // flags that specify requested operation @@ -1227,7 +1229,8 @@ sal_Bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel >& const ::rtl::OUString& aSlotName, uno::Sequence< beans::PropertyValue >& aArgsSequence, sal_Bool bPreselectPassword, - ::rtl::OUString aSuggestedName ) + ::rtl::OUString aSuggestedName, + sal_uInt16 nDocumentSignatureState ) { ModelData_Impl aModelData( *this, xModel, aArgsSequence ); @@ -1308,6 +1311,24 @@ sal_Bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel >& } } + if ( !( nStoreMode & EXPORT_REQUESTED ) ) + { + // if it is no export, warn user that the signature will be removed + if ( SIGNATURESTATE_SIGNATURES_OK == nDocumentSignatureState + || SIGNATURESTATE_SIGNATURES_INVALID == nDocumentSignatureState + || SIGNATURESTATE_SIGNATURES_NOTVALIDATED == nDocumentSignatureState + || SIGNATURESTATE_SIGNATURES_PARTIAL_OK == nDocumentSignatureState) + { + if ( QueryBox( NULL, SfxResId( RID_XMLSEC_QUERY_LOSINGSIGNATURE ) ).Execute() != RET_YES ) + { + // the user has decided not to store the document + throw task::ErrorCodeIOException( ::rtl::OUString(), + uno::Reference< uno::XInterface >(), + ERRCODE_IO_ABORT ); + } + } + } + // preselect a filter for the storing process uno::Sequence< beans::PropertyValue > aFilterProps = aModelData.GetPreselectedFilter_Impl( nStoreMode ); diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx index a7910c463cf9..816ece081fc3 100644 --- a/sfx2/source/doc/objmisc.cxx +++ b/sfx2/source/doc/objmisc.cxx @@ -87,6 +87,8 @@ #include <comphelper/configurationhelper.hxx> #include <com/sun/star/security/XDocumentDigitalSignatures.hpp> +#include <com/sun/star/task/DocumentMacroConfirmationRequest2.hpp> +#include <com/sun/star/task/InteractionClassification.hpp> #include <com/sun/star/frame/XModel.hpp> using namespace ::com::sun::star; @@ -120,6 +122,7 @@ using namespace ::com::sun::star::container; #include <vcl/svapp.hxx> #include <framework/interaction.hxx> #include <comphelper/storagehelper.hxx> +#include <comphelper/documentconstants.hxx> #include <sfx2/signaturestate.hxx> #include <sfx2/app.hxx> @@ -285,8 +288,6 @@ sal_uInt32 SfxObjectShell::GetErrorCode() const sal_uInt32 lError=pImp->lErr; if(!lError && GetMedium()) lError=GetMedium()->GetErrorCode(); -//REMOVE if(!lError && HasStorage()) -//REMOVE lError= GetStorage()->GetErrorCode(); return lError; } @@ -301,9 +302,6 @@ void SfxObjectShell::ResetError() SfxMedium * pMed = GetMedium(); if( pMed ) pMed->ResetError(); -//REMOVE SvStorage *pStor= HasStorage() ? GetStorage() : 0; -//REMOVE if( pStor ) -//REMOVE pStor->ResetError(); } //------------------------------------------------------------------------- @@ -1234,10 +1232,52 @@ void SfxObjectShell::CheckSecurityOnLoading_Impl() if ( GetMedium() ) xInteraction = GetMedium()->GetInteractionHandler(); - // check macro security - pImp->aMacroMode.checkMacrosOnLoading( xInteraction ); // check if there is a broken signature... CheckForBrokenDocSignatures_Impl( xInteraction ); + + CheckEncryption_Impl( xInteraction ); + + // check macro security + pImp->aMacroMode.checkMacrosOnLoading( xInteraction ); +} + +//------------------------------------------------------------------------- +void SfxObjectShell::CheckEncryption_Impl( const uno::Reference< task::XInteractionHandler >& xHandler ) +{ + ::rtl::OUString aVersion; + sal_Bool bIsEncrypted = sal_False; + sal_Bool bHasNonEncrypted = sal_False; + + try + { + uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW ); + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion; + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasEncryptedEntries" ) ) ) >>= bIsEncrypted; + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasNonEncryptedEntries" ) ) ) >>= bHasNonEncrypted; + } + catch( uno::Exception& ) + { + } + + if ( aVersion.compareTo( ODFVER_012_TEXT ) >= 0 ) + { + // this is ODF1.2 or later + if ( bIsEncrypted && bHasNonEncrypted ) + { + if ( !pImp->m_bIncomplEncrWarnShown ) + { + // this is an encrypted document with nonencrypted streams inside, show the warning + ::com::sun::star::task::ErrorCodeRequest aErrorCode; + aErrorCode.ErrCode = ERRCODE_SFX_INCOMPLETE_ENCRYPTION; + + SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False ); + pImp->m_bIncomplEncrWarnShown = sal_True; + } + + // broken signatures imply no macro execution at all + pImp->aMacroMode.disallowMacroExecution(); + } + } } //------------------------------------------------------------------------- @@ -1476,7 +1516,7 @@ void SfxObjectShell::TemplateDisconnectionAfterLoad() { // some further initializations for templates SetTemplate_Impl( aName, aTemplateName, this ); - pTmpMedium->CreateTempFile(); + pTmpMedium->CreateTempFile( sal_True ); } // templates are never readonly @@ -2086,14 +2126,16 @@ void SfxObjectShell::Invalidate( USHORT nId ) Invalidate_Impl( pFrame->GetBindings(), nId ); } -bool SfxObjectShell::AdjustMacroMode( const String& /*rScriptType*/, bool _bSuppressUI ) +bool SfxObjectShell::AdjustMacroMode( const String& /*rScriptType*/, bool bSuppressUI ) { uno::Reference< task::XInteractionHandler > xInteraction; - if ( pMedium && !_bSuppressUI ) + if ( pMedium && !bSuppressUI ) xInteraction = pMedium->GetInteractionHandler(); CheckForBrokenDocSignatures_Impl( xInteraction ); + CheckEncryption_Impl( xInteraction ); + return pImp->aMacroMode.adjustMacroMode( xInteraction ); } @@ -2325,16 +2367,15 @@ sal_Bool SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode ) return sLocation; } -uno::Reference< embed::XStorage > SfxObjectShell_Impl::getLastCommitDocumentStorage() +uno::Reference< embed::XStorage > SfxObjectShell_Impl::getZipStorageToSign() { Reference < embed::XStorage > xStore; SfxMedium* pMedium( rDocShell.GetMedium() ); OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getLastCommitDocumentStorage: no medium!" ); if ( pMedium ) - { - xStore = pMedium->GetLastCommitReadStorage_Impl(); - } + xStore = pMedium->GetZipStorageToSign_Impl(); + return xStore; } @@ -2348,7 +2389,7 @@ Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY ); } -sal_Int16 SfxObjectShell_Impl::getScriptingSignatureState() const +sal_Int16 SfxObjectShell_Impl::getScriptingSignatureState() { sal_Int16 nSignatureState( rDocShell.GetScriptingSignatureState() ); @@ -2361,6 +2402,72 @@ sal_Int16 SfxObjectShell_Impl::getScriptingSignatureState() const return nSignatureState; } +sal_Bool SfxObjectShell_Impl::hasTrustedScriptingSignature( sal_Bool bAllowUIToAddAuthor ) +{ + sal_Bool bResult = sal_False; + + try + { + ::rtl::OUString aVersion; + try + { + uno::Reference < beans::XPropertySet > xPropSet( rDocShell.GetStorage(), uno::UNO_QUERY_THROW ); + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion; + } + catch( uno::Exception& ) + { + } + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] <<= aVersion; + + uno::Reference< security::XDocumentDigitalSignatures > xSigner( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW ); + + if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN + || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK + || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) + { + uno::Sequence< security::DocumentSignatureInformation > aInfo = rDocShell.ImplAnalyzeSignature( sal_True, xSigner ); + + if ( aInfo.getLength() ) + { + if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN ) + nScriptingSignatureState = rDocShell.ImplCheckSignaturesInformation( aInfo ); + + if ( nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK + || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) + { + for ( sal_Int32 nInd = 0; !bResult && nInd < aInfo.getLength(); nInd++ ) + { + bResult = xSigner->isAuthorTrusted( aInfo[nInd].Signer ); + } + + if ( !bResult && bAllowUIToAddAuthor ) + { + uno::Reference< task::XInteractionHandler > xInteraction; + if ( rDocShell.GetMedium() ) + xInteraction = rDocShell.GetMedium()->GetInteractionHandler(); + + if ( xInteraction.is() ) + { + task::DocumentMacroConfirmationRequest2 aRequest; + aRequest.DocumentURL = getDocumentLocation(); + aRequest.DocumentZipStorage = rDocShell.GetMedium()->GetZipStorageToSign_Impl(); + aRequest.DocumentSignatureInformation = aInfo; + aRequest.DocumentVersion = aVersion; + aRequest.Classification = task::InteractionClassification_QUERY; + bResult = SfxMedium::CallApproveHandler( xInteraction, uno::makeAny( aRequest ), sal_True ); + } + } + } + } + } + } + catch( uno::Exception& ) + {} + + return bResult; +} + void SfxObjectShell_Impl::showBrokenSignatureWarning( const uno::Reference< task::XInteractionHandler >& _rxInteraction ) const { if ( !bSignatureErrorIsShown ) diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 34a3f3159169..8a8512a37af0 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -525,16 +525,6 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) { SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, GetTitle() ); // ??? - // xmlsec05, check with SFX team - sal_uInt16 nState = GetDocumentSignatureState(); - if ( SIGNATURESTATE_SIGNATURES_OK == nState - || SIGNATURESTATE_SIGNATURES_INVALID == nState - || SIGNATURESTATE_SIGNATURES_NOTVALIDATED == nState ) - { - if ( QueryBox( NULL, SfxResId( RID_XMLSEC_QUERY_LOSINGSIGNATURE ) ).Execute() != RET_YES ) - return; - } - if ( nId == SID_SAVEASDOC ) { // in case of plugin mode the SaveAs operation means SaveTo @@ -644,7 +634,8 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) ::rtl::OUString::createFromAscii( pSlot->GetUnoName() ), aDispatchArgs, bPreselectPassword, - GetSharedFileURL() ); + GetSharedFileURL(), + GetDocumentSignatureState() ); } else { @@ -654,11 +645,6 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) ERRCODE_IO_ABORT ); } - // the scripting signature might be preserved - // pImp->nScriptingSignatureState = SIGNATURESTATE_NOSIGNATURES; - pImp->nDocumentSignatureState = SIGNATURESTATE_NOSIGNATURES; - pImp->bSignatureErrorIsShown = sal_False; - // merge aDispatchArgs to the request SfxAllItemSet aResultParams( GetPool() ); TransformParameters( nId, @@ -1085,7 +1071,11 @@ void SfxObjectShell::GetState_Impl(SfxItemSet &rSet) } case SID_MACRO_SIGNATURE: { - rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE, GetScriptingSignatureState() ) ); + // the slot makes sense only if there is a macro in the document + if ( pImp->documentStorageHasMacros() || pImp->aMacroMode.hasMacroLibrary() ) + rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE, GetScriptingSignatureState() ) ); + else + rSet.DisableItem( nWhich ); break; } } @@ -1269,6 +1259,7 @@ sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< sal_Bool bCertValid = sal_True; sal_uInt16 nResult = SIGNATURESTATE_NOSIGNATURES; int nInfos = aInfos.getLength(); + bool bCompleteSignature = true; if( nInfos ) { //These errors of certificates are allowed @@ -1293,11 +1284,14 @@ sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< nResult = SIGNATURESTATE_SIGNATURES_BROKEN; break; // we know enough } + bCompleteSignature &= !aInfos[n].PartialDocumentSignature; } } if ( nResult == SIGNATURESTATE_SIGNATURES_OK && !bCertValid ) nResult = SIGNATURESTATE_SIGNATURES_NOTVALIDATED; + else if ( nResult == SIGNATURESTATE_SIGNATURES_OK && bCertValid && !bCompleteSignature) + nResult = SIGNATURESTATE_SIGNATURES_PARTIAL_OK; // this code must not check whether the document is modified // it should only check the provided info @@ -1305,41 +1299,61 @@ sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< return nResult; } -sal_uInt16 SfxObjectShell::ImplGetSignatureState( sal_Bool bScriptingContent ) +uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnalyzeSignature( sal_Bool bScriptingContent, const uno::Reference< security::XDocumentDigitalSignatures >& xSigner ) { - sal_Int16* pState = bScriptingContent ? &pImp->nScriptingSignatureState : &pImp->nDocumentSignatureState; + uno::Sequence< security::DocumentSignatureInformation > aResult; + uno::Reference< security::XDocumentDigitalSignatures > xLocSigner = xSigner; - if ( *pState == SIGNATURESTATE_UNKNOWN ) + if ( GetMedium() && GetMedium()->GetName().Len() && IsOwnStorageFormat_Impl( *GetMedium()) && GetMedium()->GetStorage().is() ) { - *pState = SIGNATURESTATE_NOSIGNATURES; - - if ( GetMedium() && GetMedium()->GetName().Len() && IsOwnStorageFormat_Impl( *GetMedium()) && GetMedium()->GetStorage().is() ) + try { - try + if ( !xLocSigner.is() ) { - uno::Reference< security::XDocumentDigitalSignatures > xD( - comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), uno::UNO_QUERY ); - - if ( xD.is() ) + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] <<= ::rtl::OUString(); + try { - ::com::sun::star::uno::Sequence< security::DocumentSignatureInformation > aInfos; - if ( bScriptingContent ) - aInfos = xD->verifyScriptingContentSignatures( GetMedium()->GetLastCommitReadStorage_Impl(), - uno::Reference< io::XInputStream >() ); - else - aInfos = xD->verifyDocumentContentSignatures( GetMedium()->GetLastCommitReadStorage_Impl(), - uno::Reference< io::XInputStream >() ); - - *pState = ImplCheckSignaturesInformation( aInfos ); + uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW ); + aArgs[0] = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ); } + catch( uno::Exception& ) + { + } + + xLocSigner.set( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW ); + } - catch( com::sun::star::uno::Exception& ) - { - } + + if ( bScriptingContent ) + aResult = xLocSigner->verifyScriptingContentSignatures( GetMedium()->GetZipStorageToSign_Impl(), + uno::Reference< io::XInputStream >() ); + else + aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(), + uno::Reference< io::XInputStream >() ); + } + catch( com::sun::star::uno::Exception& ) + { } } - if ( *pState == SIGNATURESTATE_SIGNATURES_OK || *pState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) + return aResult; +} + +sal_uInt16 SfxObjectShell::ImplGetSignatureState( sal_Bool bScriptingContent ) +{ + sal_Int16* pState = bScriptingContent ? &pImp->nScriptingSignatureState : &pImp->nDocumentSignatureState; + + if ( *pState == SIGNATURESTATE_UNKNOWN ) + { + *pState = SIGNATURESTATE_NOSIGNATURES; + + uno::Sequence< security::DocumentSignatureInformation > aInfos = ImplAnalyzeSignature( bScriptingContent ); + *pState = ImplCheckSignaturesInformation( aInfos ); + } + + if ( *pState == SIGNATURESTATE_SIGNATURES_OK || *pState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED + || *pState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK) { if ( IsModified() ) *pState = SIGNATURESTATE_SIGNATURES_INVALID; @@ -1415,7 +1429,6 @@ void SfxObjectShell::ImplSign( sal_Bool bScriptingContent ) //When the document is modified then we must not show the digital signatures dialog //If we have come here then the user denied to save. if (!bHasSign) - bNoSig = true; } } @@ -1437,18 +1450,42 @@ void SfxObjectShell::ImplSign( sal_Bool bScriptingContent ) bAllowModifiedBack = sal_True; } - if ( ! bNoSig && GetMedium()->SignContents_Impl( bScriptingContent ) ) + // we have to store to the original document, the original medium should be closed for this time + if ( !bNoSig + && ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) ) { - if ( bScriptingContent ) - pImp->nScriptingSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check - else - pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check + GetMedium()->CloseAndRelease(); + + // We sign only ODF1.2, that means that if this point has been reached, + // the ODF1.2 signing process should be used. + // This code still might be called to show the signature of ODF1.1 document. + sal_Bool bSigned = GetMedium()->SignContents_Impl( + bScriptingContent, + aODFVersion, + pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_OK + || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED + || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK); + + DoSaveCompleted( GetMedium() ); + + if ( bSigned ) + { + if ( bScriptingContent ) + { + pImp->nScriptingSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check + + // adding of scripting signature removes existing document signature + pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check + } + else + pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check - pImp->bSignatureErrorIsShown = sal_False; + pImp->bSignatureErrorIsShown = sal_False; - Invalidate( SID_SIGNATURE ); - Invalidate( SID_MACRO_SIGNATURE ); - Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) ); + Invalidate( SID_SIGNATURE ); + Invalidate( SID_MACRO_SIGNATURE ); + Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) ); + } } if ( bAllowModifiedBack ) diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 602174fb2bf9..2925090868e8 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -36,6 +36,7 @@ #endif #include <svtools/eitem.hxx> #include <svtools/stritem.hxx> +#include <svtools/intitem.hxx> #include <tools/zcodec.hxx> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/frame/XModel.hpp> @@ -665,11 +666,14 @@ sal_Bool SfxObjectShell::DoLoad( SfxMedium *pMed ) xStorProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaTypeFallbackUsed" ) ) ) >>= bWarnMediaTypeFallback; - if ( bWarnMediaTypeFallback && pRepairPackageItem && pRepairPackageItem->GetValue() ) + if ( pRepairPackageItem && pRepairPackageItem->GetValue() ) { + // the macros in repaired documents should be disabled + pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE, document::MacroExecMode::NEVER_EXECUTE ) ); + // the mediatype was retrieved by using fallback solution but this is a repairing mode // so it is acceptable to open the document if there is no contents that required manifest.xml - bWarnMediaTypeFallback = sal_False; //!NoDependencyFromManifest_Impl( xStorage ); + bWarnMediaTypeFallback = sal_False; } if ( bWarnMediaTypeFallback || !xStorage->getElementNames().getLength() ) @@ -1175,7 +1179,7 @@ sal_Bool SfxObjectShell::SaveTo_Impl sal_Bool bStoreToSameLocation = sal_False; // the detection whether the script is changed should be done before saving - sal_Bool bTryToPreservScriptSignature = sal_False; + sal_Bool bTryToPreserveScriptSignature = sal_False; // no way to detect whether a filter is oasis format, have to wait for saving process sal_Bool bNoPreserveForOasis = sal_False; if ( bOwnSource && bOwnTarget @@ -1186,8 +1190,10 @@ sal_Bool SfxObjectShell::SaveTo_Impl AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "MacroSignaturePreserving" ) ) ); // the checking of the library modified state iterates over the libraries, should be done only when required - bTryToPreservScriptSignature = !pImp->pBasicManager->isAnyContainerModified(); - if ( bTryToPreservScriptSignature ) + // currently the check is commented out since it is broken, we have to check the signature every time we save + // TODO/LATER: let isAnyContainerModified() work! + bTryToPreserveScriptSignature = sal_True; // !pImp->pBasicManager->isAnyContainerModified(); + if ( bTryToPreserveScriptSignature ) { // check that the storage format stays the same SvtSaveOptions aSaveOpt; @@ -1203,7 +1209,7 @@ sal_Bool SfxObjectShell::SaveTo_Impl {} // preserve only if the same filter has been used - bTryToPreservScriptSignature = pMedium->GetFilter() && pFilter && pMedium->GetFilter()->GetFilterName() == pFilter->GetFilterName(); + bTryToPreserveScriptSignature = pMedium->GetFilter() && pFilter && pMedium->GetFilter()->GetFilterName() == pFilter->GetFilterName(); bNoPreserveForOasis = ( (aODFVersion.equals( ODFVER_012_TEXT ) && nVersion == SvtSaveOptions::ODFVER_011) || @@ -1473,9 +1479,10 @@ sal_Bool SfxObjectShell::SaveTo_Impl } - if ( bOk && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED ) + if ( bOk && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED && !bPasswdProvided ) { // store the thumbnail representation image + // the thumbnail is not stored in case of encrypted document AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Thumbnail creation." ) ) ); if ( !GenerateAndStoreThumbnail( bPasswdProvided, sal_False, @@ -1594,120 +1601,115 @@ sal_Bool SfxObjectShell::SaveTo_Impl bOk = SaveChildren( TRUE ); } - // if ODF version of oasis format changes on saving the signature should not be preserved - if ( bOk && bTryToPreservScriptSignature && bNoPreserveForOasis ) - bTryToPreservScriptSignature = ( SotStorage::GetVersion( rMedium.GetStorage() ) == SOFFICE_FILEFORMAT_60 ); - - uno::Reference< security::XDocumentDigitalSignatures > xDDSigns; - sal_Bool bScriptSignatureIsCopied = sal_False; - if ( bOk && bTryToPreservScriptSignature ) + if ( bOk ) { - // if the scripting code was not changed and it is signed the signature should be preserved - // unfortunately at this point we have only information whether the basic code has changed or not - // so the only way is to check the signature if the basic was not changed - try - { - xDDSigns = uno::Reference< security::XDocumentDigitalSignatures >( - comphelper::getProcessServiceFactory()->createInstance( - rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), - uno::UNO_QUERY_THROW ); + // if ODF version of oasis format changes on saving the signature should not be preserved + if ( bOk && bTryToPreserveScriptSignature && bNoPreserveForOasis ) + bTryToPreserveScriptSignature = ( SotStorage::GetVersion( rMedium.GetStorage() ) == SOFFICE_FILEFORMAT_60 ); - ::rtl::OUString aScriptSignName = xDDSigns->getScriptingContentSignatureDefaultStreamName(); + uno::Reference< security::XDocumentDigitalSignatures > xDDSigns; + if ( bOk && bTryToPreserveScriptSignature ) + { + AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Copying scripting signature." ) ) ); - if ( aScriptSignName.getLength() ) + // if the scripting code was not changed and it is signed the signature should be preserved + // unfortunately at this point we have only information whether the basic code has changed or not + // so the only way is to check the signature if the basic was not changed + try { - uno::Reference< embed::XStorage > xMetaInf = GetStorage()->openStorageElement( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), - embed::ElementModes::READ ); - uno::Reference< embed::XStorage > xTargetMetaInf = rMedium.GetStorage()->openStorageElement( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), - embed::ElementModes::WRITE ); - - if ( xMetaInf.is() && xTargetMetaInf.is() ) + // get the ODF version of the new medium + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] <<= ::rtl::OUString(); + try + { + uno::Reference < beans::XPropertySet > xPropSet( rMedium.GetStorage(), uno::UNO_QUERY_THROW ); + aArgs[0] = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ); + } + catch( uno::Exception& ) { - xMetaInf->copyElementTo( aScriptSignName, xTargetMetaInf, aScriptSignName ); - - // after loading the UseCommonStoragePassword property might be set to true - // set it to false here, since this is a rare case when it must be so - // TODO/LATER: in future it should be done on loading probably - uno::Reference< beans::XPropertySet > xTargetSignPropSet( - xTargetMetaInf->openStreamElement( aScriptSignName, embed::ElementModes::WRITE ), - uno::UNO_QUERY_THROW ); - xTargetSignPropSet->setPropertyValue( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ), - uno::makeAny( (sal_Bool)sal_False ) ); - - uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY ); - if ( xTransact.is() ) - xTransact->commit(); - bScriptSignatureIsCopied = sal_True; } - } - } - catch( uno::Exception& ) - { - } - } - - if ( bOk ) - { - AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Medium commit." ) ) ); - // transfer data to its destinated location - // the medium commits the storage or the stream it is based on - RegisterTransfer( rMedium ); - bOk = rMedium.Commit(); + xDDSigns = uno::Reference< security::XDocumentDigitalSignatures >( + comphelper::getProcessServiceFactory()->createInstanceWithArguments( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), + aArgs ), + uno::UNO_QUERY_THROW ); - if ( bOk && bScriptSignatureIsCopied ) - { - AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Script signature check." ) ) ); + ::rtl::OUString aScriptSignName = xDDSigns->getScriptingContentSignatureDefaultStreamName(); - // if the script signature was copied it should be checked now - // usually it should be ok, so no additional actions will be done - // but if for any reasong ( f.e. binshell change ) it is broken it should be removed here - // in result the behaviour will work in optimized way in most cases, means in case of signed basic scripts - OSL_ENSURE( !bScriptSignatureIsCopied || xDDSigns.is(), "The signing could not be done without the service!\n" ); - if ( xDDSigns.is() ) - { - try + if ( aScriptSignName.getLength() ) { - bOk = sal_False; - ::com::sun::star::uno::Sequence< security::DocumentSignatureInformation > aInfos = - xDDSigns->verifyScriptingContentSignatures( rMedium.GetLastCommitReadStorage_Impl(), - uno::Reference< io::XInputStream >() ); - sal_uInt16 nState = ImplCheckSignaturesInformation( aInfos ); - if ( nState == SIGNATURESTATE_SIGNATURES_OK || nState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) - { - rMedium.SetCachedSignatureState_Impl( nState ); - bOk = sal_True; - } - else + pMedium->Close(); + + // target medium is still not commited, it should not be closed + // commit the package storage and close it, but leave the streams open + rMedium.StorageCommit_Impl(); + rMedium.CloseStorage(); + + uno::Reference< embed::XStorage > xReadOrig = pMedium->GetZipStorageToSign_Impl(); + if ( !xReadOrig.is() ) + throw uno::RuntimeException(); + uno::Reference< embed::XStorage > xMetaInf = xReadOrig->openStorageElement( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), + embed::ElementModes::READ ); + + uno::Reference< embed::XStorage > xTarget = rMedium.GetZipStorageToSign_Impl( sal_False ); + if ( !xTarget.is() ) + throw uno::RuntimeException(); + uno::Reference< embed::XStorage > xTargetMetaInf = xTarget->openStorageElement( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), + embed::ElementModes::READWRITE ); + + if ( xMetaInf.is() && xTargetMetaInf.is() ) { - // the signature is broken, remove it - rMedium.SetCachedSignatureState_Impl( SIGNATURESTATE_NOSIGNATURES ); - uno::Reference< embed::XStorage > xTargetMetaInf = rMedium.GetStorage()->openStorageElement( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), - embed::ElementModes::WRITE ); + xMetaInf->copyElementTo( aScriptSignName, xTargetMetaInf, aScriptSignName ); + + uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY ); + if ( xTransact.is() ) + xTransact->commit(); - if ( xTargetMetaInf.is() ) + xTargetMetaInf->dispose(); + + // now check the copied signature + uno::Sequence< security::DocumentSignatureInformation > aInfos = + xDDSigns->verifyScriptingContentSignatures( xTarget, + uno::Reference< io::XInputStream >() ); + sal_uInt16 nState = ImplCheckSignaturesInformation( aInfos ); + if ( nState == SIGNATURESTATE_SIGNATURES_OK || nState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED + || nState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK) { - xTargetMetaInf->removeElement( xDDSigns->getScriptingContentSignatureDefaultStreamName() ); - uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY ); + rMedium.SetCachedSignatureState_Impl( nState ); + + // commit the ZipStorage from target medium + xTransact.set( xTarget, uno::UNO_QUERY ); if ( xTransact.is() ) xTransact->commit(); - - bOk = rMedium.Commit(); + } + else + { + // it should not happen, the copies signature is invalid! + // throw the changes away + OSL_ASSERT( "An invalid signature was copied!" ); } } } - catch( uno::Exception ) - { - OSL_ENSURE( sal_False, "This exception must not happen!" ); - } } + catch( uno::Exception& ) + { + } + + pMedium->Close(); + rMedium.CloseZipStorage_Impl(); } + AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Medium commit." ) ) ); + + // transfer data to its destinated location + // the medium commits the storage or the stream it is based on + RegisterTransfer( rMedium ); + bOk = rMedium.Commit(); + if ( bOk ) { AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing is successful." ) ) ); diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx index 26ba76517d8c..95ba194df0cb 100644 --- a/sfx2/source/doc/objxtor.cxx +++ b/sfx2/source/doc/objxtor.cxx @@ -265,6 +265,7 @@ SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell ) ,m_bCreateTempStor( sal_False ) ,m_xDocInfoListener() ,m_bIsInit( sal_False ) + ,m_bIncomplEncrWarnShown( sal_False ) { } @@ -368,7 +369,7 @@ SfxObjectShell::~SfxObjectShell() pImp->xModel = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > (); // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned! - if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage() == pImp->m_xDocStorage ) + if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage( sal_False ) == pImp->m_xDocStorage ) pMedium->CanDisposeStorage_Impl( sal_False ); if ( pImp->mpObjectContainer ) diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index d4b0b3aaf7ab..29219942be01 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -2850,19 +2850,9 @@ void SfxBaseModel::impl_store( const ::rtl::OUString& sURL // TODO/LATER: a general way to set the error context should be available SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, m_pData->m_pObjectShell->GetTitle() ); - ::com::sun::star::uno::Any aInteraction; - ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > lContinuations(1); - ::framework::ContinuationApprove* pApprove = new ::framework::ContinuationApprove(); - lContinuations[0] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >(static_cast< ::com::sun::star::task::XInteractionContinuation* >(pApprove), uno::UNO_QUERY); - ::com::sun::star::task::ErrorCodeRequest aErrorCode; aErrorCode.ErrCode = nErrCode; - aInteraction <<= aErrorCode; - - ::framework::InteractionRequest* pRequest = new ::framework::InteractionRequest(aInteraction,lContinuations); - ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest > xRequest(static_cast< ::com::sun::star::task::XInteractionRequest* >(pRequest), uno::UNO_QUERY); - - xHandler->handle(xRequest); + SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False ); } } |