LCOV - code coverage report
Current view: top level - sfx2/source/doc - docfile.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 933 1651 56.5 %
Date: 2015-06-13 12:38:46 Functions: 97 121 80.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_features.h>
      21             : 
      22             : #include <sfx2/docfile.hxx>
      23             : #include <sfx2/signaturestate.hxx>
      24             : 
      25             : #include <uno/mapping.hxx>
      26             : #include <com/sun/star/task/InteractionHandler.hpp>
      27             : #include <com/sun/star/uno/Reference.h>
      28             : #include <com/sun/star/ucb/XContent.hpp>
      29             : #include <com/sun/star/container/XChild.hpp>
      30             : #include <com/sun/star/document/XDocumentRevisionListPersistence.hpp>
      31             : #include <com/sun/star/document/LockedDocumentRequest.hpp>
      32             : #include <com/sun/star/document/OwnLockOnDocumentRequest.hpp>
      33             : #include <com/sun/star/document/LockFileIgnoreRequest.hpp>
      34             : #include <com/sun/star/document/ChangedByOthersRequest.hpp>
      35             : #include <com/sun/star/beans/XPropertySet.hpp>
      36             : #include <com/sun/star/embed/XTransactedObject.hpp>
      37             : #include <com/sun/star/embed/ElementModes.hpp>
      38             : #include <com/sun/star/embed/UseBackupException.hpp>
      39             : #include <com/sun/star/embed/XOptimizedStorage.hpp>
      40             : #include <com/sun/star/ucb/InteractiveIOException.hpp>
      41             : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
      42             : #include <com/sun/star/ucb/CommandFailedException.hpp>
      43             : #include <com/sun/star/ucb/CommandAbortedException.hpp>
      44             : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
      45             : #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
      46             : #include <com/sun/star/ucb/XContentProvider.hpp>
      47             : #include <com/sun/star/ucb/XProgressHandler.hpp>
      48             : #include <com/sun/star/ucb/XCommandInfo.hpp>
      49             : #include <com/sun/star/io/XOutputStream.hpp>
      50             : #include <com/sun/star/io/XInputStream.hpp>
      51             : #include <com/sun/star/io/XTruncate.hpp>
      52             : #include <com/sun/star/io/XStreamListener.hpp>
      53             : #include <com/sun/star/io/XSeekable.hpp>
      54             : #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
      55             : #include <com/sun/star/lang/XInitialization.hpp>
      56             : #include <com/sun/star/ucb/InsertCommandArgument.hpp>
      57             : #include <com/sun/star/ucb/NameClash.hpp>
      58             : #include <com/sun/star/ucb/TransferInfo.hpp>
      59             : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
      60             : #include <com/sun/star/ucb/OpenMode.hpp>
      61             : #include <com/sun/star/logging/DocumentIOLogRing.hpp>
      62             : #include <com/sun/star/logging/XSimpleLogRing.hpp>
      63             : #include <cppuhelper/implbase1.hxx>
      64             : #include <com/sun/star/beans/PropertyValue.hpp>
      65             : #include <com/sun/star/security/DocumentSignatureInformation.hpp>
      66             : #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
      67             : #include <tools/urlobj.hxx>
      68             : #include <unotools/tempfile.hxx>
      69             : #include <comphelper/processfactory.hxx>
      70             : #include <comphelper/interaction.hxx>
      71             : #include <framework/interaction.hxx>
      72             : #include <unotools/streamhelper.hxx>
      73             : #include <unotools/localedatawrapper.hxx>
      74             : #include <vcl/msgbox.hxx>
      75             : #include <svl/stritem.hxx>
      76             : #include <svl/eitem.hxx>
      77             : #include <svl/lckbitem.hxx>
      78             : #include <svtools/sfxecode.hxx>
      79             : #include <svl/itemset.hxx>
      80             : #include <svl/intitem.hxx>
      81             : #include <svtools/svparser.hxx>
      82             : #include <cppuhelper/weakref.hxx>
      83             : 
      84             : #include <unotools/streamwrap.hxx>
      85             : 
      86             : #include <osl/file.hxx>
      87             : 
      88             : #include <comphelper/storagehelper.hxx>
      89             : #include <unotools/mediadescriptor.hxx>
      90             : #include <comphelper/docpasswordhelper.hxx>
      91             : #include <tools/datetime.hxx>
      92             : #include <tools/inetmime.hxx>
      93             : #include <unotools/pathoptions.hxx>
      94             : #include <svtools/asynclink.hxx>
      95             : #include <svl/inettype.hxx>
      96             : #include <ucbhelper/commandenvironment.hxx>
      97             : #include <unotools/localfilehelper.hxx>
      98             : #include <unotools/ucbstreamhelper.hxx>
      99             : #include <unotools/ucbhelper.hxx>
     100             : #include <unotools/progresshandlerwrap.hxx>
     101             : #include <ucbhelper/content.hxx>
     102             : #include <ucbhelper/interactionrequest.hxx>
     103             : #include <sot/stg.hxx>
     104             : #include <sot/storage.hxx>
     105             : #include <unotools/saveopt.hxx>
     106             : #include <svl/documentlockfile.hxx>
     107             : #include <com/sun/star/document/DocumentRevisionListPersistence.hpp>
     108             : 
     109             : #include "helper.hxx"
     110             : #include <sfx2/request.hxx>
     111             : #include <sfx2/app.hxx>
     112             : #include <sfx2/frame.hxx>
     113             : #include <sfx2/fcontnr.hxx>
     114             : #include <sfx2/docfilt.hxx>
     115             : #include <sfx2/objsh.hxx>
     116             : #include <sfx2/docfac.hxx>
     117             : #include "doc.hrc"
     118             : #include "openflag.hxx"
     119             : #include <sfx2/sfxresid.hxx>
     120             : #include "sfxacldetect.hxx"
     121             : #include <officecfg/Office/Common.hxx>
     122             : 
     123             : #include <boost/noncopyable.hpp>
     124             : #include <boost/scoped_ptr.hpp>
     125             : 
     126             : using namespace ::com::sun::star;
     127             : using namespace ::com::sun::star::uno;
     128             : using namespace ::com::sun::star::ucb;
     129             : using namespace ::com::sun::star::beans;
     130             : using namespace ::com::sun::star::io;
     131             : 
     132             : namespace {
     133             : 
     134             : #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
     135             : 
     136             : static const sal_Int8 LOCK_UI_NOLOCK = 0;
     137             : static const sal_Int8 LOCK_UI_SUCCEEDED = 1;
     138             : static const sal_Int8 LOCK_UI_TRY = 2;
     139             : 
     140          32 : bool IsSystemFileLockingUsed()
     141             : {
     142             : #if HAVE_FEATURE_MACOSX_SANDBOX
     143             :     return true;
     144             : #else
     145          32 :     return officecfg::Office::Common::Misc::UseDocumentSystemFileLocking::get();
     146             : #endif
     147             : }
     148             : 
     149             : 
     150           0 : bool IsOOoLockFileUsed()
     151             : {
     152             : #if HAVE_FEATURE_MACOSX_SANDBOX
     153             :     return false;
     154             : #else
     155           0 :     return officecfg::Office::Common::Misc::UseDocumentOOoLockFile::get();
     156             : #endif
     157             : }
     158             : 
     159        5666 : bool IsLockingUsed()
     160             : {
     161        5666 :     return officecfg::Office::Common::Misc::UseLocking::get();
     162             : }
     163             : 
     164             : #endif
     165             : 
     166             : } // anonymous namespace
     167             : 
     168             : class SfxMedium_Impl : boost::noncopyable
     169             : {
     170             : public:
     171             :     StreamMode m_nStorOpenMode;
     172             :     sal_uInt32 m_eError;
     173             : 
     174             :     ::ucbhelper::Content aContent;
     175             :     bool bUpdatePickList:1;
     176             :     bool bIsTemp:1;
     177             :     bool bDownloadDone:1;
     178             :     bool bIsStorage:1;
     179             :     bool bUseInteractionHandler:1;
     180             :     bool bAllowDefaultIntHdl:1;
     181             :     bool bDisposeStorage:1;
     182             :     bool bStorageBasedOnInStream:1;
     183             :     bool m_bSalvageMode:1;
     184             :     bool m_bVersionsAlreadyLoaded:1;
     185             :     bool m_bLocked:1;
     186             :     bool m_bGotDateTime:1;
     187             :     bool m_bRemoveBackup:1;
     188             :     bool m_bOriginallyReadOnly:1;
     189             :     bool m_bTriedStorage:1;
     190             :     bool m_bRemote:1;
     191             :     bool m_bInputStreamIsReadOnly:1;
     192             :     bool m_bInCheckIn:1;
     193             : 
     194             :     OUString m_aName;
     195             :     OUString m_aLogicName;
     196             :     OUString m_aLongName;
     197             : 
     198             :     mutable SfxItemSet* m_pSet;
     199             :     mutable INetURLObject* m_pURLObj;
     200             : 
     201             :     const SfxFilter* m_pFilter;
     202             :     boost::scoped_ptr<SfxFilter> m_pCustomFilter;
     203             : 
     204             :     SfxMedium*       pAntiImpl;
     205             :     SvStream* m_pInStream;
     206             :     SvStream* m_pOutStream;
     207             : 
     208             :     const SfxFilter* pOrigFilter;
     209             :     OUString    aOrigURL;
     210             :     DateTime         aExpireTime;
     211             :     SfxFrameWeakRef  wLoadTargetFrame;
     212             :     SvKeyValueIteratorRef xAttributes;
     213             : 
     214             :     svtools::AsynchronLink  aDoneLink;
     215             : 
     216             :     uno::Sequence < util::RevisionTag > aVersions;
     217             : 
     218             :     ::utl::TempFile*           pTempFile;
     219             : 
     220             :     uno::Reference<embed::XStorage> xStorage;
     221             :     uno::Reference<embed::XStorage> m_xZipStorage;
     222             :     uno::Reference<io::XInputStream> m_xInputStreamToLoadFrom;
     223             :     uno::Reference<io::XInputStream> xInputStream;
     224             :     uno::Reference<io::XStream> xStream;
     225             :     uno::Reference<io::XStream> m_xLockingStream;
     226             :     uno::Reference<task::XInteractionHandler> xInteraction;
     227             :     uno::Reference<logging::XSimpleLogRing> m_xLogRing;
     228             : 
     229             :     sal_uInt32                  nLastStorageError;
     230             : 
     231             :     OUString m_aBackupURL;
     232             : 
     233             :     // the following member is changed and makes sense only during saving
     234             :     // TODO/LATER: in future the signature state should be controlled by the medium not by the document
     235             :     //             in this case the member will hold this information
     236             :     SignatureState             m_nSignatureState;
     237             : 
     238             :     util::DateTime m_aDateTime;
     239             : 
     240             :     SfxMedium_Impl( SfxMedium* pAntiImplP );
     241             :     ~SfxMedium_Impl();
     242             : 
     243        3552 :     OUString getFilterMimeType()
     244        3552 :     { return m_pFilter == 0 ? OUString() : m_pFilter->GetMimeType(); }
     245             : };
     246             : 
     247             : 
     248       12371 : SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP ) :
     249       24742 :     m_nStorOpenMode(SFX_STREAM_READWRITE),
     250             :     m_eError(SVSTREAM_OK),
     251             :     bUpdatePickList(true),
     252             :     bIsTemp( false ),
     253             :     bDownloadDone( true ),
     254             :     bIsStorage( false ),
     255             :     bUseInteractionHandler( true ),
     256             :     bAllowDefaultIntHdl( false ),
     257             :     bDisposeStorage( false ),
     258             :     bStorageBasedOnInStream( false ),
     259             :     m_bSalvageMode( false ),
     260             :     m_bVersionsAlreadyLoaded( false ),
     261             :     m_bLocked( false ),
     262             :     m_bGotDateTime( false ),
     263             :     m_bRemoveBackup( false ),
     264             :     m_bOriginallyReadOnly(false),
     265             :     m_bTriedStorage(false),
     266             :     m_bRemote(false),
     267             :     m_bInputStreamIsReadOnly(false),
     268             :     m_bInCheckIn(false),
     269             :     m_pSet(NULL),
     270             :     m_pURLObj(NULL),
     271             :     m_pFilter(NULL),
     272             :     pAntiImpl( pAntiImplP ),
     273             :     m_pInStream(NULL),
     274             :     m_pOutStream(NULL),
     275             :     pOrigFilter( 0 ),
     276       24742 :     aExpireTime( Date( Date::SYSTEM ) + 10, tools::Time( tools::Time::SYSTEM ) ),
     277             :     pTempFile( NULL ),
     278             :     nLastStorageError( 0 ),
     279       61855 :     m_nSignatureState( SignatureState::NOSIGNATURES )
     280             : {
     281       12371 :     aDoneLink.CreateMutex();
     282       12371 : }
     283             : 
     284             : 
     285       24704 : SfxMedium_Impl::~SfxMedium_Impl()
     286             : {
     287       12352 :     aDoneLink.ClearPendingCall();
     288             : 
     289       12352 :     delete pTempFile;
     290       12352 :     delete m_pSet;
     291       12352 :     delete m_pURLObj;
     292       12352 : }
     293             : 
     294        4759 : void SfxMedium::ResetError()
     295             : {
     296        4759 :     pImp->m_eError = SVSTREAM_OK;
     297        4759 :     if( pImp->m_pInStream )
     298        3155 :         pImp->m_pInStream->ResetError();
     299        4759 :     if( pImp->m_pOutStream )
     300           0 :         pImp->m_pOutStream->ResetError();
     301        4759 : }
     302             : 
     303             : 
     304         497 : sal_uInt32 SfxMedium::GetLastStorageCreationState()
     305             : {
     306         497 :     return pImp->nLastStorageError;
     307             : }
     308             : 
     309             : 
     310         373 : void SfxMedium::AddLog( const OUString& aMessage )
     311             : {
     312         373 :     if ( !pImp->m_xLogRing.is() )
     313             :     {
     314             :         try
     315             :         {
     316         373 :             Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
     317         373 :             pImp->m_xLogRing.set( logging::DocumentIOLogRing::get(xContext) );
     318             :         }
     319           5 :         catch( const uno::Exception& )
     320             :         {}
     321             :     }
     322             : 
     323         373 :     if ( pImp->m_xLogRing.is() )
     324         368 :         pImp->m_xLogRing->logString( aMessage );
     325         373 : }
     326             : 
     327             : 
     328         373 : void SfxMedium::SetError( sal_uInt32 nError, const OUString& aLogMessage )
     329             : {
     330         373 :     pImp->m_eError = nError;
     331         373 :     if ( pImp->m_eError != ERRCODE_NONE && !aLogMessage.isEmpty() )
     332         373 :         AddLog( aLogMessage );
     333         373 : }
     334             : 
     335             : 
     336       76914 : sal_uInt32 SfxMedium::GetErrorCode() const
     337             : {
     338       76914 :     sal_uInt32 lError = pImp->m_eError;
     339       76914 :     if(!lError && pImp->m_pInStream)
     340       38127 :         lError = pImp->m_pInStream->GetErrorCode();
     341       76914 :     if(!lError && pImp->m_pOutStream)
     342         687 :         lError = pImp->m_pOutStream->GetErrorCode();
     343       76914 :     return lError;
     344             : }
     345             : 
     346             : 
     347           2 : void SfxMedium::CheckFileDate( const util::DateTime& aInitDate )
     348             : {
     349           2 :     GetInitFileDate( true );
     350           2 :     if ( pImp->m_aDateTime.Seconds != aInitDate.Seconds
     351           2 :       || pImp->m_aDateTime.Minutes != aInitDate.Minutes
     352           2 :       || pImp->m_aDateTime.Hours != aInitDate.Hours
     353           2 :       || pImp->m_aDateTime.Day != aInitDate.Day
     354           2 :       || pImp->m_aDateTime.Month != aInitDate.Month
     355           2 :       || pImp->m_aDateTime.Year != aInitDate.Year )
     356             :     {
     357           0 :         uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
     358             : 
     359           0 :         if ( xHandler.is() )
     360             :         {
     361             :             try
     362             :             {
     363             :                 ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
     364           0 :                     document::ChangedByOthersRequest() ) );
     365           0 :                 uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 );
     366           0 :                 aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() );
     367           0 :                 aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() );
     368           0 :                 xInteractionRequestImpl->setContinuations( aContinuations );
     369             : 
     370           0 :                 xHandler->handle( xInteractionRequestImpl.get() );
     371             : 
     372           0 :                 ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xInteractionRequestImpl->getSelection();
     373           0 :                 if ( uno::Reference< task::XInteractionAbort >( xSelected.get(), uno::UNO_QUERY ).is() )
     374             :                 {
     375           0 :                     SetError( ERRCODE_ABORT, OUString( OSL_LOG_PREFIX  ) );
     376           0 :                 }
     377             :             }
     378           0 :             catch ( const uno::Exception& )
     379             :             {}
     380           0 :         }
     381             :     }
     382           2 : }
     383             : 
     384        1491 : bool SfxMedium::DocNeedsFileDateCheck() const
     385             : {
     386        1491 :     return ( !IsReadOnly() && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) );
     387             : }
     388             : 
     389         921 : util::DateTime SfxMedium::GetInitFileDate( bool bIgnoreOldValue )
     390             : {
     391         921 :     if ( ( bIgnoreOldValue || !pImp->m_bGotDateTime ) && !pImp->m_aLogicName.isEmpty() )
     392             :     {
     393             :         try
     394             :         {
     395         920 :             uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
     396        1840 :             ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, comphelper::getProcessComponentContext() );
     397             : 
     398         920 :             aContent.getPropertyValue("DateModified") >>= pImp->m_aDateTime;
     399        1829 :             pImp->m_bGotDateTime = true;
     400             :         }
     401          11 :         catch ( const ::com::sun::star::uno::Exception& )
     402             :         {
     403             :         }
     404             :     }
     405             : 
     406         921 :     return pImp->m_aDateTime;
     407             : }
     408             : 
     409             : 
     410       36636 : Reference < XContent > SfxMedium::GetContent() const
     411             : {
     412       36636 :     if ( !pImp->aContent.get().is() )
     413             :     {
     414       15256 :         Reference < ::com::sun::star::ucb::XContent > xContent;
     415       30512 :         Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
     416             : 
     417       15256 :         SFX_ITEMSET_ARG( pImp->m_pSet, pItem, SfxUnoAnyItem, SID_CONTENT, false);
     418       15256 :         if ( pItem )
     419        2517 :             pItem->GetValue() >>= xContent;
     420             : 
     421       15256 :         if ( xContent.is() )
     422             :         {
     423             :             try
     424             :             {
     425        2517 :                 pImp->aContent = ::ucbhelper::Content( xContent, xEnv, comphelper::getProcessComponentContext() );
     426             :             }
     427           0 :             catch ( const Exception& )
     428             :             {
     429             :             }
     430             :         }
     431             :         else
     432             :         {
     433             :             // TODO: SAL_WARN( "sfx.doc", "SfxMedium::GetContent()\nCreate Content? This code exists as fallback only. Please clarify, why its used.");
     434       12739 :             OUString aURL;
     435       12739 :             if ( !pImp->m_aName.isEmpty() )
     436        7425 :                 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->m_aName, aURL );
     437        5314 :             else if ( !pImp->m_aLogicName.isEmpty() )
     438          33 :                 aURL = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
     439       12739 :             if (!aURL.isEmpty() )
     440        7458 :                 (void)::ucbhelper::Content::create( aURL, xEnv, comphelper::getProcessComponentContext(), pImp->aContent );
     441       15256 :         }
     442             :     }
     443             : 
     444       36636 :     return pImp->aContent.get();
     445             : }
     446             : 
     447        5674 : OUString SfxMedium::GetBaseURL( bool bForSaving )
     448             : {
     449        5674 :     OUString aBaseURL;
     450        5674 :     const SfxStringItem* pBaseURLItem = static_cast<const SfxStringItem*>( GetItemSet()->GetItem(SID_DOC_BASEURL) );
     451        5674 :     if ( pBaseURLItem )
     452        1592 :         aBaseURL = pBaseURLItem->GetValue();
     453        4082 :     else if ( GetContent().is() )
     454             :     {
     455             :         try
     456             :         {
     457        3789 :             Any aAny = pImp->aContent.getPropertyValue("BaseURI");
     458        3785 :             aAny >>= aBaseURL;
     459             :         }
     460           2 :         catch ( const ::com::sun::star::uno::Exception& )
     461             :         {
     462             :         }
     463             : 
     464        3787 :         if ( aBaseURL.isEmpty() )
     465        3787 :             aBaseURL = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
     466             :     }
     467             : 
     468        5674 :     if ( bForSaving )
     469             :     {
     470        1458 :         SvtSaveOptions aOpt;
     471        1458 :         bool bIsRemote = IsRemote();
     472        1458 :         if( (bIsRemote && !aOpt.IsSaveRelINet()) || (!pImp->m_bRemote && !aOpt.IsSaveRelFSys()) )
     473           0 :             return OUString();
     474             :     }
     475             : 
     476        5674 :     return aBaseURL;
     477             : }
     478             : 
     479         487 : bool SfxMedium::IsSkipImages()
     480             : {
     481         487 :     const SfxStringItem* pSkipImagesItem = static_cast<const SfxStringItem*>( GetItemSet()->GetItem(SID_FILE_FILTEROPTIONS) );
     482         487 :     return pSkipImagesItem && pSkipImagesItem->GetValue() == "SkipImages";
     483             : }
     484             : 
     485        9423 : SvStream* SfxMedium::GetInStream()
     486             : {
     487        9423 :     if ( pImp->m_pInStream )
     488        1095 :         return pImp->m_pInStream;
     489             : 
     490        8328 :     if ( pImp->pTempFile )
     491             :     {
     492           1 :         pImp->m_pInStream = new SvFileStream(pImp->m_aName, pImp->m_nStorOpenMode);
     493             : 
     494           1 :         pImp->m_eError = pImp->m_pInStream->GetError();
     495             : 
     496           3 :         if (!pImp->m_eError && (pImp->m_nStorOpenMode & StreamMode::WRITE)
     497           3 :                     && ! pImp->m_pInStream->IsWritable() )
     498             :         {
     499           0 :             pImp->m_eError = ERRCODE_IO_ACCESSDENIED;
     500           0 :             delete pImp->m_pInStream;
     501           0 :             pImp->m_pInStream = NULL;
     502             :         }
     503             :         else
     504           1 :             return pImp->m_pInStream;
     505             :     }
     506             : 
     507        8327 :     GetMedium_Impl();
     508             : 
     509        8327 :     if ( GetError() )
     510         364 :         return NULL;
     511             : 
     512        7963 :     return pImp->m_pInStream;
     513             : }
     514             : 
     515             : 
     516       10710 : void SfxMedium::CloseInStream()
     517             : {
     518       10710 :     CloseInStream_Impl();
     519       10710 : }
     520             : 
     521       29047 : void SfxMedium::CloseInStream_Impl()
     522             : {
     523             :     // if there is a storage based on the InStream, we have to
     524             :     // close the storage, too, because otherwise the storage
     525             :     // would use an invalid ( deleted ) stream.
     526       29047 :     if ( pImp->m_pInStream && pImp->xStorage.is() )
     527             :     {
     528        2180 :         if ( pImp->bStorageBasedOnInStream )
     529        2180 :             CloseStorage();
     530             :     }
     531             : 
     532       29047 :     if ( pImp->m_pInStream && !GetContent().is() )
     533             :     {
     534        4995 :         CreateTempFile( true );
     535       34042 :         return;
     536             :     }
     537             : 
     538       24052 :     DELETEZ( pImp->m_pInStream );
     539       24052 :     if ( pImp->m_pSet )
     540       23770 :         pImp->m_pSet->ClearItem( SID_INPUTSTREAM );
     541             : 
     542       24052 :     CloseZipStorage_Impl();
     543       24052 :     pImp->xInputStream.clear();
     544             : 
     545       24052 :     if ( !pImp->m_pOutStream )
     546             :     {
     547             :         // output part of the stream is not used so the whole stream can be closed
     548             :         // TODO/LATER: is it correct?
     549       18326 :         pImp->xStream.clear();
     550       18326 :         if ( pImp->m_pSet )
     551       18044 :             pImp->m_pSet->ClearItem( SID_STREAM );
     552             :     }
     553             : }
     554             : 
     555             : 
     556        6434 : SvStream* SfxMedium::GetOutStream()
     557             : {
     558        6434 :     if ( !pImp->m_pOutStream )
     559             :     {
     560             :         // Create a temp. file if there is none because we always
     561             :         // need one.
     562        5774 :         CreateTempFile( false );
     563             : 
     564        5774 :         if ( pImp->pTempFile )
     565             :         {
     566             :             // On windows we try to re-use XOutStream from xStream if that exists;
     567             :             // because opening new SvFileStream in this situation may fail with ERROR_SHARING_VIOLATION
     568             :             // TODO: this is a horrible hack that should probably be removed,
     569             :             // somebody needs to investigate this more thoroughly...
     570        5774 :             if (getenv("SFX_MEDIUM_REUSE_STREAM") && pImp->xStream.is())
     571             :             {
     572             :                 assert(pImp->xStream->getOutputStream().is()); // need that...
     573             :                 pImp->m_pOutStream = utl::UcbStreamHelper::CreateStream(
     574           0 :                         pImp->xStream, false);
     575             :             }
     576             :             else
     577             :             {
     578             :             // On Unix don't try to re-use XOutStream from xStream if that exists;
     579             :             // it causes fdo#59022 (fails opening files via SMB on Linux)
     580             :                 pImp->m_pOutStream = new SvFileStream(
     581        5774 :                             pImp->m_aName, STREAM_STD_READWRITE);
     582             :             }
     583        5774 :             CloseStorage();
     584             :         }
     585             :     }
     586             : 
     587        6434 :     return pImp->m_pOutStream;
     588             : }
     589             : 
     590             : 
     591        2779 : bool SfxMedium::CloseOutStream()
     592             : {
     593        2779 :     CloseOutStream_Impl();
     594        2779 :     return true;
     595             : }
     596             : 
     597       26391 : bool SfxMedium::CloseOutStream_Impl()
     598             : {
     599       26391 :     if ( pImp->m_pOutStream )
     600             :     {
     601             :         // if there is a storage based on the OutStream, we have to
     602             :         // close the storage, too, because otherwise the storage
     603             :         // would use an invalid ( deleted ) stream.
     604             :         //TODO/MBA: how to deal with this?!
     605             :         //maybe we need a new flag when the storage was created from the outstream
     606        5774 :         if ( pImp->xStorage.is() )
     607             :         {
     608           0 :                 CloseStorage();
     609             :         }
     610             : 
     611        5774 :         delete pImp->m_pOutStream;
     612        5774 :         pImp->m_pOutStream = NULL;
     613             :     }
     614             : 
     615       26391 :     if ( !pImp->m_pInStream )
     616             :     {
     617             :         // input part of the stream is not used so the whole stream can be closed
     618             :         // TODO/LATER: is it correct?
     619       23659 :         pImp->xStream.clear();
     620       23659 :         if ( pImp->m_pSet )
     621       23377 :             pImp->m_pSet->ClearItem( SID_STREAM );
     622             :     }
     623             : 
     624       26391 :     return true;
     625             : }
     626             : 
     627             : 
     628         102 : const OUString& SfxMedium::GetPhysicalName() const
     629             : {
     630         102 :     if ( pImp->m_aName.isEmpty() && !pImp->m_aLogicName.isEmpty() )
     631           1 :         const_cast<SfxMedium*>(this)->CreateFileStream();
     632             : 
     633             :     // return the name then
     634         102 :     return pImp->m_aName;
     635             : }
     636             : 
     637             : 
     638           1 : void SfxMedium::CreateFileStream()
     639             : {
     640           1 :     ForceSynchronStream_Impl( true );
     641           1 :     GetInStream();
     642           1 :     if( pImp->m_pInStream )
     643             :     {
     644           1 :         CreateTempFile( false );
     645           1 :         pImp->bIsTemp = true;
     646           1 :         CloseInStream_Impl();
     647             :     }
     648           1 : }
     649             : 
     650             : 
     651         839 : bool SfxMedium::Commit()
     652             : {
     653         839 :     if( pImp->xStorage.is() )
     654         105 :         StorageCommit_Impl();
     655         734 :     else if( pImp->m_pOutStream  )
     656         685 :         pImp->m_pOutStream->Flush();
     657          49 :     else if( pImp->m_pInStream  )
     658           0 :         pImp->m_pInStream->Flush();
     659             : 
     660         839 :     if ( GetError() == SVSTREAM_OK )
     661             :     {
     662             :         // does something only in case there is a temporary file ( means aName points to different location than aLogicName )
     663         839 :         Transfer_Impl();
     664             :     }
     665             : 
     666         839 :     bool bResult = ( GetError() == SVSTREAM_OK );
     667             : 
     668         839 :     if ( bResult && DocNeedsFileDateCheck() )
     669         837 :         GetInitFileDate( true );
     670             : 
     671             :     // remove truncation mode from the flags
     672         839 :     pImp->m_nStorOpenMode &= (~StreamMode::TRUNC);
     673         839 :     return bResult;
     674             : }
     675             : 
     676             : 
     677        1637 : bool SfxMedium::IsStorage()
     678             : {
     679        1637 :     if ( pImp->xStorage.is() )
     680         782 :         return true;
     681             : 
     682         855 :     if ( pImp->m_bTriedStorage )
     683         155 :         return pImp->bIsStorage;
     684             : 
     685         700 :     if ( pImp->pTempFile )
     686             :     {
     687          48 :         OUString aURL;
     688          48 :         if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->m_aName, aURL ) )
     689             :         {
     690             :             SAL_WARN( "sfx.doc", "Physical name not convertible!");
     691             :         }
     692          48 :         pImp->bIsStorage = SotStorage::IsStorageFile( aURL ) && !SotStorage::IsOLEStorage( aURL);
     693          48 :         if ( !pImp->bIsStorage )
     694          48 :             pImp->m_bTriedStorage = true;
     695             :     }
     696         652 :     else if ( GetInStream() )
     697             :     {
     698         301 :         pImp->bIsStorage = SotStorage::IsStorageFile( pImp->m_pInStream ) && !SotStorage::IsOLEStorage( pImp->m_pInStream );
     699         301 :         if ( !pImp->m_pInStream->GetError() && !pImp->bIsStorage )
     700         279 :             pImp->m_bTriedStorage = true;
     701             :     }
     702             : 
     703         700 :     return pImp->bIsStorage;
     704             : }
     705             : 
     706             : 
     707           0 : bool SfxMedium::IsPreview_Impl()
     708             : {
     709           0 :     bool bPreview = false;
     710           0 :     SFX_ITEMSET_ARG( GetItemSet(), pPreview, SfxBoolItem, SID_PREVIEW, false);
     711           0 :     if ( pPreview )
     712           0 :         bPreview = pPreview->GetValue();
     713             :     else
     714             :     {
     715           0 :         SFX_ITEMSET_ARG( GetItemSet(), pFlags, SfxStringItem, SID_OPTIONS, false);
     716           0 :         if ( pFlags )
     717             :         {
     718           0 :             OUString aFileFlags = pFlags->GetValue();
     719           0 :             aFileFlags = aFileFlags.toAsciiUpperCase();
     720           0 :             if ( -1 != aFileFlags.indexOf( 'B' ) )
     721           0 :                 bPreview = true;
     722             :         }
     723             :     }
     724             : 
     725           0 :     return bPreview;
     726             : }
     727             : 
     728             : 
     729           1 : void SfxMedium::StorageBackup_Impl()
     730             : {
     731           1 :     ::ucbhelper::Content aOriginalContent;
     732           2 :     Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
     733             : 
     734           2 :     bool bBasedOnOriginalFile = ( !pImp->pTempFile && !( !pImp->m_aLogicName.isEmpty() && pImp->m_bSalvageMode )
     735           3 :         && !GetURLObject().GetMainURL( INetURLObject::NO_DECODE ).isEmpty()
     736           2 :         && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
     737           3 :         && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) );
     738             : 
     739           3 :     if ( bBasedOnOriginalFile && pImp->m_aBackupURL.isEmpty()
     740           4 :       && ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, comphelper::getProcessComponentContext(), aOriginalContent ) )
     741             :     {
     742           1 :         DoInternalBackup_Impl( aOriginalContent );
     743           1 :         if( pImp->m_aBackupURL.isEmpty() )
     744           0 :             SetError( ERRCODE_SFX_CANTCREATEBACKUP, OUString( OSL_LOG_PREFIX  ) );
     745           1 :     }
     746           1 : }
     747             : 
     748             : 
     749           1 : OUString SfxMedium::GetBackup_Impl()
     750             : {
     751           1 :     if ( pImp->m_aBackupURL.isEmpty() )
     752           1 :         StorageBackup_Impl();
     753             : 
     754           1 :     return pImp->m_aBackupURL;
     755             : }
     756             : 
     757             : 
     758         849 : uno::Reference < embed::XStorage > SfxMedium::GetOutputStorage()
     759             : {
     760         849 :     if ( GetError() )
     761           0 :         return uno::Reference< embed::XStorage >();
     762             : 
     763             :     // if the medium was constructed with a Storage: use this one, not a temp. storage
     764             :     // if a temporary storage already exists: use it
     765         849 :     if ( pImp->xStorage.is() && ( pImp->m_aLogicName.isEmpty() || pImp->pTempFile ) )
     766         744 :         return pImp->xStorage;
     767             : 
     768             :     // if necessary close stream that was used for reading
     769         105 :     if ( pImp->m_pInStream && !pImp->m_pInStream->IsWritable() )
     770           0 :         CloseInStream();
     771             : 
     772             :     DBG_ASSERT( !pImp->m_pOutStream, "OutStream in a readonly Medium?!" );
     773             : 
     774             :     // TODO/LATER: The current solution is to store the document temporary and then copy it to the target location;
     775             :     // in future it should be stored directly and then copied to the temporary location, since in this case no
     776             :     // file attributes have to be preserved and system copying mechanics could be used instead of streaming.
     777         105 :     CreateTempFileNoCopy();
     778             : 
     779         105 :     return GetStorage();
     780             : }
     781             : 
     782             : 
     783        2370 : void SfxMedium::SetEncryptionDataToStorage_Impl()
     784             : {
     785             :     // in case media-descriptor contains password it should be used on opening
     786        2370 :     if ( pImp->xStorage.is() && pImp->m_pSet )
     787             :     {
     788        2370 :         uno::Sequence< beans::NamedValue > aEncryptionData;
     789        2370 :         if ( GetEncryptionData_Impl( pImp->m_pSet, aEncryptionData ) )
     790             :         {
     791             :             // replace the password with encryption data
     792           6 :             pImp->m_pSet->ClearItem( SID_PASSWORD );
     793           6 :             pImp->m_pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
     794             : 
     795             :             try
     796             :             {
     797           6 :                 ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( pImp->xStorage, aEncryptionData );
     798             :             }
     799           0 :             catch( const uno::Exception& )
     800             :             {
     801             :                 SAL_WARN( "sfx.doc", "It must be possible to set a common password for the storage" );
     802             :                 // TODO/LATER: set the error code in case of problem
     803             :                 // SetError( ERRCODE_IO_GENERAL, OUString( OSL_LOG_PREFIX  ) );
     804             :             }
     805        2370 :         }
     806             :     }
     807        2370 : }
     808             : 
     809             : #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
     810             : 
     811             : // FIXME: Hmm actually lock files should be used for sftp: documents
     812             : // even if !HAVE_FEATURE_MULTIUSER_ENVIRONMENT. Only the use of lock
     813             : // files for *local* documents is unnecessary in that case. But
     814             : // actually, the checks for sftp: here are just wishful thinking; I
     815             : // don't this there is any support for actually editing documents
     816             : // behind sftp: URLs anyway.
     817             : 
     818             : // Sure, there could perhaps be a 3rd-party extension that brings UCB
     819             : // the potential to handle files behind sftp:. But there could also be
     820             : // an extension that handles some arbitrary foobar: scheme *and* it
     821             : // could be that lock files would be the correct thing to use for
     822             : // foobar: documents, too. But the hardcoded test below won't know
     823             : // that. Clearly the knowledge whether lock files should be used or
     824             : // not for some URL scheme belongs in UCB, not here.
     825             : 
     826             : 
     827           0 : sal_Int8 SfxMedium::ShowLockedDocumentDialog( const LockFileEntry& aData, bool bIsLoading, bool bOwnLock )
     828             : {
     829           0 :     sal_Int8 nResult = LOCK_UI_NOLOCK;
     830             : 
     831             :     // show the interaction regarding the document opening
     832           0 :     uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
     833             : 
     834           0 :     if ( ::svt::DocumentLockFile::IsInteractionAllowed() && xHandler.is() && ( bIsLoading || bOwnLock ) )
     835             :     {
     836           0 :         OUString aDocumentURL = GetURLObject().GetLastName();
     837           0 :         OUString aInfo;
     838           0 :         ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl;
     839             : 
     840           0 :         if ( bOwnLock )
     841             :         {
     842           0 :             aInfo = aData[LockFileComponent::EDITTIME];
     843             : 
     844           0 :             xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
     845           0 :                 document::OwnLockOnDocumentRequest( OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo, !bIsLoading ) ) );
     846             :         }
     847             :         else /*logically therefore bIsLoading is set */
     848             :         {
     849           0 :             if ( !aData[LockFileComponent::OOOUSERNAME].isEmpty() )
     850           0 :                 aInfo = aData[LockFileComponent::OOOUSERNAME];
     851             :             else
     852           0 :                 aInfo = aData[LockFileComponent::SYSUSERNAME];
     853             : 
     854           0 :             if ( !aInfo.isEmpty() && !aData[LockFileComponent::EDITTIME].isEmpty() )
     855             :             {
     856           0 :                 aInfo +=  " ( " ;
     857           0 :                 aInfo += aData[LockFileComponent::EDITTIME];
     858           0 :                 aInfo += " )";
     859             :             }
     860             : 
     861           0 :             xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
     862           0 :                 document::LockedDocumentRequest( OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) );
     863             :         }
     864             : 
     865           0 :         uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 );
     866           0 :         aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() );
     867           0 :         aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() );
     868           0 :         aContinuations[2] = new ::ucbhelper::InteractionDisapprove( xInteractionRequestImpl.get() );
     869           0 :         xInteractionRequestImpl->setContinuations( aContinuations );
     870             : 
     871           0 :         xHandler->handle( xInteractionRequestImpl.get() );
     872             : 
     873           0 :         ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xInteractionRequestImpl->getSelection();
     874           0 :         if ( uno::Reference< task::XInteractionAbort >( xSelected.get(), uno::UNO_QUERY ).is() )
     875             :         {
     876           0 :             SetError( ERRCODE_ABORT, OUString( OSL_LOG_PREFIX  ) );
     877             :         }
     878           0 :         else if ( uno::Reference< task::XInteractionDisapprove >( xSelected.get(), uno::UNO_QUERY ).is() )
     879             :         {
     880             :             // own lock on loading, user has selected to ignore the lock
     881             :             // own lock on saving, user has selected to ignore the lock
     882             :             // alien lock on loading, user has selected to edit a copy of document
     883             :             // TODO/LATER: alien lock on saving, user has selected to do SaveAs to different location
     884           0 :             if ( bIsLoading && !bOwnLock )
     885             :             {
     886             :                 // means that a copy of the document should be opened
     887           0 :                 GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, true ) );
     888             :             }
     889           0 :             else if ( bOwnLock )
     890           0 :                 nResult = LOCK_UI_SUCCEEDED;
     891             :         }
     892             :         else // if ( XSelected == aContinuations[1] )
     893             :         {
     894             :             // own lock on loading, user has selected to open readonly
     895             :             // own lock on saving, user has selected to open readonly
     896             :             // alien lock on loading, user has selected to retry saving
     897             :             // TODO/LATER: alien lock on saving, user has selected to retry saving
     898             : 
     899           0 :             if ( bIsLoading )
     900           0 :                 GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
     901             :             else
     902           0 :                 nResult = LOCK_UI_TRY;
     903           0 :         }
     904             :     }
     905             :     else
     906             :     {
     907           0 :         if ( bIsLoading )
     908             :         {
     909             :             // if no interaction handler is provided the default answer is open readonly
     910             :             // that usually happens in case the document is loaded per API
     911             :             // so the document must be opened readonly for backward compatibility
     912           0 :             GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
     913             :         }
     914             :         else
     915           0 :             SetError( ERRCODE_IO_ACCESSDENIED, OUString( OSL_LOG_PREFIX  ) );
     916             : 
     917             :     }
     918             : 
     919           0 :     return nResult;
     920             : }
     921             : 
     922             : namespace
     923             : {
     924          32 :     bool isSuitableProtocolForLocking(const OUString & rLogicName)
     925             :     {
     926          32 :         INetURLObject aUrl( rLogicName );
     927          32 :         INetProtocol eProt = aUrl.GetProtocol();
     928             : #if HAVE_FEATURE_MACOSX_SANDBOX
     929             :         return eProt == INetProtocol::Sftp;
     930             : #else
     931          32 :         return eProt == INetProtocol::File || eProt == INetProtocol::Sftp;
     932             : #endif
     933             :     }
     934             : }
     935             : 
     936             : #endif // HAVE_FEATURE_MULTIUSER_ENVIRONMENT
     937             : 
     938             : // sets SID_DOC_READONLY if the document cannot be opened for editing
     939             : // if user cancel the loading the ERROR_ABORT is set
     940        5666 : void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI )
     941             : {
     942             : #if !HAVE_FEATURE_MULTIUSER_ENVIRONMENT
     943             :     (void) bLoading;
     944             :     (void) bNoUI;
     945             : #else
     946        5666 :     if (!IsLockingUsed() || GetURLObject().HasError())
     947        5618 :         return;
     948             : 
     949             :     try
     950             :     {
     951          48 :         if ( pImp->m_bLocked && bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
     952             :         {
     953             :             // if the document is already locked the system locking might be temporarely off after storing
     954             :             // check whether the system file locking should be taken again
     955           8 :             GetLockingStream_Impl();
     956             :         }
     957             : 
     958          48 :         bool bResult = pImp->m_bLocked;
     959             : 
     960          48 :         if ( !bResult )
     961             :         {
     962             :             // no read-write access is necessary on loading if the document is explicitly opened as copy
     963          40 :             SFX_ITEMSET_ARG( GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, false);
     964          40 :             bResult = ( bLoading && pTemplateItem && pTemplateItem->GetValue() );
     965             :         }
     966             : 
     967          48 :         if ( !bResult && !IsReadOnly() )
     968             :         {
     969          32 :             bool bContentReadonly = false;
     970          32 :             if ( bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
     971             :             {
     972             :                 // let the original document be opened to check the possibility to open it for editing
     973             :                 // and to let the writable stream stay open to hold the lock on the document
     974          21 :                 GetLockingStream_Impl();
     975             :             }
     976             : 
     977             :             // "IsReadOnly" property does not allow to detect whether the file is readonly always
     978             :             // so we try always to open the file for editing
     979             :             // the file is readonly only in case the read-write stream can not be opened
     980          32 :             if ( bLoading && !pImp->m_xLockingStream.is() )
     981             :             {
     982             :                 try
     983             :                 {
     984             :                     // MediaDescriptor does this check also, the duplication should be avoided in future
     985           0 :                     Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
     986           0 :                     ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, comphelper::getProcessComponentContext() );
     987           0 :                     aContent.getPropertyValue("IsReadOnly") >>= bContentReadonly;
     988             :                 }
     989           0 :                 catch( const uno::Exception& ) {}
     990             : 
     991             : #if EXTRA_ACL_CHECK
     992             :                 // This block was introduced as a fix to i#102464, but removing
     993             :                 // this does not make the problem re-appear.  But leaving this
     994             :                 // part would interfere with documents saved in samba share.  This
     995             :                 // affects Windows only.
     996             :                 if ( !bContentReadonly )
     997             :                 {
     998             :                     // the file is not readonly, check the ACL
     999             : 
    1000             :                     OUString aPhysPath;
    1001             :                     if ( ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), aPhysPath ) )
    1002             :                         bContentReadonly = IsReadonlyAccordingACL( aPhysPath.getStr() );
    1003             :                 }
    1004             : #endif
    1005             :             }
    1006             : 
    1007             :             // do further checks only if the file not readonly in fs
    1008          32 :             if ( !bContentReadonly )
    1009             :             {
    1010             :                 // the special file locking should be used only for suitable URLs
    1011          32 :                 if ( isSuitableProtocolForLocking( pImp->m_aLogicName ) )
    1012             :                 {
    1013             : 
    1014             :                     // in case of storing the document should request the output before locking
    1015          32 :                     if ( bLoading )
    1016             :                     {
    1017             :                         // let the stream be opened to check the system file locking
    1018          21 :                         GetMedium_Impl();
    1019          21 :                         if (GetError() != ERRCODE_NONE) {
    1020           0 :                             return;
    1021             :                         }
    1022             :                     }
    1023             : 
    1024          32 :                     sal_Int8 bUIStatus = LOCK_UI_NOLOCK;
    1025             : 
    1026             :                     // check whether system file locking has been used, the default value is false
    1027          32 :                     bool bUseSystemLock = ::utl::LocalFileHelper::IsLocalFile( pImp->m_aLogicName ) && IsSystemFileLockingUsed();
    1028             : 
    1029             :                     // TODO/LATER: This implementation does not allow to detect the system lock on saving here, actually this is no big problem
    1030             :                     // if system lock is used the writeable stream should be available
    1031          32 :                     bool bHandleSysLocked = ( bLoading && bUseSystemLock && !pImp->xStream.is() && !pImp->m_pOutStream );
    1032             : 
    1033          32 :                     do
    1034             :                     {
    1035             :                         try
    1036             :                         {
    1037          32 :                             ::svt::DocumentLockFile aLockFile( pImp->m_aLogicName );
    1038          32 :                             if ( !bHandleSysLocked )
    1039             :                             {
    1040             :                                 try
    1041             :                                 {
    1042          32 :                                     bResult = aLockFile.CreateOwnLockFile();
    1043             :                                 }
    1044           0 :                                 catch ( const ucb::InteractiveIOException& e )
    1045             :                                 {
    1046             :                                     // exception means that the lock file can not be successfully accessed
    1047             :                                     // in this case it should be ignored if system file locking is anyway active
    1048           0 :                                     if ( bUseSystemLock || !IsOOoLockFileUsed() )
    1049             :                                     {
    1050           0 :                                         bResult = true;
    1051             :                                         // take the ownership over the lock file
    1052           0 :                                         aLockFile.OverwriteOwnLockFile();
    1053             :                                     }
    1054           0 :                                     else if ( e.Code == IOErrorCode_INVALID_PARAMETER )
    1055             :                                     {
    1056             :                                         // system file locking is not active, ask user whether he wants to open the document without any locking
    1057           0 :                                         uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler();
    1058             : 
    1059           0 :                                         if ( xHandler.is() )
    1060             :                                         {
    1061             :                                             ::rtl::Reference< ::ucbhelper::InteractionRequest > xIgnoreRequestImpl
    1062           0 :                                                 = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockFileIgnoreRequest() ) );
    1063             : 
    1064           0 :                                             uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 2 );
    1065           0 :                                             aContinuations[0] = new ::ucbhelper::InteractionAbort( xIgnoreRequestImpl.get() );
    1066           0 :                                             aContinuations[1] = new ::ucbhelper::InteractionApprove( xIgnoreRequestImpl.get() );
    1067           0 :                                             xIgnoreRequestImpl->setContinuations( aContinuations );
    1068             : 
    1069           0 :                                             xHandler->handle( xIgnoreRequestImpl.get() );
    1070             : 
    1071           0 :                                             ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xIgnoreRequestImpl->getSelection();
    1072           0 :                                             bResult = uno::Reference< task::XInteractionApprove >( xSelected.get(), uno::UNO_QUERY ).is();
    1073           0 :                                         }
    1074             :                                     }
    1075             :                                 }
    1076           0 :                                 catch ( const uno::Exception& )
    1077             :                                 {
    1078             :                                     // exception means that the lock file can not be successfully accessed
    1079             :                                     // in this case it should be ignored if system file locking is anyway active
    1080           0 :                                     if ( bUseSystemLock || !IsOOoLockFileUsed() )
    1081             :                                     {
    1082           0 :                                         bResult = true;
    1083             :                                         // take the ownership over the lock file
    1084           0 :                                         aLockFile.OverwriteOwnLockFile();
    1085             :                                     }
    1086             :                                 }
    1087             : 
    1088             :                                 // in case OOo locking is turned off the lock file is still written if possible
    1089             :                                 // but it is ignored while deciding whether the document should be opened for editing or not
    1090          32 :                                 if ( !bResult && !IsOOoLockFileUsed() )
    1091             :                                 {
    1092           0 :                                     bResult = true;
    1093             :                                     // take the ownership over the lock file
    1094           0 :                                     aLockFile.OverwriteOwnLockFile();
    1095             :                                 }
    1096             :                             }
    1097             : 
    1098             : 
    1099          32 :                             if ( !bResult )
    1100             :                             {
    1101           0 :                                 LockFileEntry aData;
    1102             :                                 try
    1103             :                                 {
    1104             :                                     // impossibility to get data is no real problem
    1105           0 :                                     aData = aLockFile.GetLockData();
    1106             :                                 }
    1107           0 :                                 catch( const uno::Exception& )
    1108             :                                 {
    1109             :                                 }
    1110             : 
    1111           0 :                                 bool bOwnLock = false;
    1112             : 
    1113           0 :                                 if ( !bHandleSysLocked )
    1114             :                                 {
    1115           0 :                                     LockFileEntry aOwnData = svt::LockFileCommon::GenerateOwnEntry();
    1116           0 :                                     bOwnLock = aOwnData[LockFileComponent::SYSUSERNAME].equals( aData[LockFileComponent::SYSUSERNAME] );
    1117             : 
    1118           0 :                                     if ( bOwnLock
    1119           0 :                                       && aOwnData[LockFileComponent::LOCALHOST].equals( aData[LockFileComponent::LOCALHOST] )
    1120           0 :                                       && aOwnData[LockFileComponent::USERURL].equals( aData[LockFileComponent::USERURL] ) )
    1121             :                                     {
    1122             :                                         // this is own lock from the same installation, it could remain because of crash
    1123           0 :                                         bResult = true;
    1124           0 :                                     }
    1125             :                                 }
    1126             : 
    1127           0 :                                 if ( !bResult && !bNoUI )
    1128             :                                 {
    1129           0 :                                     bUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock );
    1130           0 :                                     if ( bUIStatus == LOCK_UI_SUCCEEDED )
    1131             :                                     {
    1132             :                                         // take the ownership over the lock file
    1133           0 :                                         bResult = aLockFile.OverwriteOwnLockFile();
    1134             :                                     }
    1135             :                                 }
    1136             : 
    1137           0 :                                 bHandleSysLocked = false;
    1138          32 :                             }
    1139             :                         }
    1140           0 :                         catch( const uno::Exception& )
    1141             :                         {
    1142             :                         }
    1143          32 :                     } while( !bResult && bUIStatus == LOCK_UI_TRY );
    1144             : 
    1145          32 :                     pImp->m_bLocked = bResult;
    1146             :                 }
    1147             :                 else
    1148             :                 {
    1149             :                     // this is no file URL, check whether the file is readonly
    1150           0 :                     bResult = !bContentReadonly;
    1151             :                 }
    1152             :             }
    1153             :         }
    1154             : 
    1155          48 :         if ( !bResult && GetError() == ERRCODE_NONE )
    1156             :         {
    1157             :             // the error should be set in case it is storing process
    1158             :             // or the document has been opened for editing explicitly
    1159           7 :             SFX_ITEMSET_ARG( pImp->m_pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, false );
    1160             : 
    1161           7 :             if ( !bLoading || (pReadOnlyItem && !pReadOnlyItem->GetValue()) )
    1162           0 :                 SetError( ERRCODE_IO_ACCESSDENIED, OUString( OSL_LOG_PREFIX  ) );
    1163             :             else
    1164           7 :                 GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
    1165             :         }
    1166             : 
    1167             :         // when the file is locked, get the current file date
    1168          48 :         if ( bResult && DocNeedsFileDateCheck() )
    1169          41 :             GetInitFileDate( true );
    1170             :     }
    1171           0 :     catch( const uno::Exception& )
    1172             :     {
    1173             :         SAL_WARN( "sfx.doc", "Locking exception: high probability, that the content has not been created" );
    1174             :     }
    1175             : #endif
    1176             : }
    1177             : 
    1178             : 
    1179       16562 : uno::Reference < embed::XStorage > SfxMedium::GetStorage( bool bCreateTempIfNo )
    1180             : {
    1181       16562 :     if ( pImp->xStorage.is() || pImp->m_bTriedStorage )
    1182       13694 :         return pImp->xStorage;
    1183             : 
    1184        2868 :     uno::Sequence< uno::Any > aArgs( 2 );
    1185             : 
    1186             :     // the medium should be retrieved before temporary file creation
    1187             :     // to let the MediaDescriptor be filled with the streams
    1188        2868 :     GetMedium_Impl();
    1189             : 
    1190        2868 :     if ( bCreateTempIfNo )
    1191        2842 :         CreateTempFile( false );
    1192             : 
    1193        2868 :     GetMedium_Impl();
    1194             : 
    1195        2868 :     if ( GetError() )
    1196           6 :         return pImp->xStorage;
    1197             : 
    1198        2862 :     SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, false);
    1199        2862 :     if ( pRepairItem && pRepairItem->GetValue() )
    1200             :     {
    1201             :         // the storage should be created for repairing mode
    1202           0 :         CreateTempFile( false );
    1203           0 :         GetMedium_Impl();
    1204             : 
    1205           0 :         Reference< ::com::sun::star::ucb::XProgressHandler > xProgressHandler;
    1206           0 :         Reference< ::com::sun::star::task::XStatusIndicator > xStatusIndicator;
    1207             : 
    1208           0 :         SFX_ITEMSET_ARG( GetItemSet(), pxProgressItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, false );
    1209           0 :         if( pxProgressItem && ( pxProgressItem->GetValue() >>= xStatusIndicator ) )
    1210           0 :             xProgressHandler = Reference< ::com::sun::star::ucb::XProgressHandler >(
    1211           0 :                                     new utl::ProgressHandlerWrap( xStatusIndicator ) );
    1212             : 
    1213           0 :         uno::Sequence< beans::PropertyValue > aAddProps( 2 );
    1214           0 :         aAddProps[0].Name = "RepairPackage";
    1215           0 :         aAddProps[0].Value <<= true;
    1216           0 :         aAddProps[1].Name = "StatusIndicator";
    1217           0 :         aAddProps[1].Value <<= xProgressHandler;
    1218             : 
    1219             :         // the first arguments will be filled later
    1220           0 :         aArgs.realloc( 3 );
    1221           0 :         aArgs[2] <<= aAddProps;
    1222             :     }
    1223             : 
    1224        2862 :     if ( pImp->xStream.is() )
    1225             :     {
    1226             :         // since the storage is based on temporary stream we open it always read-write
    1227        2836 :         aArgs[0] <<= pImp->xStream;
    1228        2836 :         aArgs[1] <<= embed::ElementModes::READWRITE;
    1229        2836 :         pImp->bStorageBasedOnInStream = true;
    1230             :     }
    1231          26 :     else if ( pImp->xInputStream.is() )
    1232             :     {
    1233             :         // since the storage is based on temporary stream we open it always read-write
    1234          26 :         aArgs[0] <<= pImp->xInputStream;
    1235          26 :         aArgs[1] <<= embed::ElementModes::READ;
    1236          26 :         pImp->bStorageBasedOnInStream = true;
    1237             :     }
    1238             :     else
    1239             :     {
    1240           0 :         CloseStreams_Impl();
    1241           0 :         aArgs[0] <<= pImp->m_aName;
    1242           0 :         aArgs[1] <<= embed::ElementModes::READ;
    1243           0 :         pImp->bStorageBasedOnInStream = false;
    1244             :     }
    1245             : 
    1246             :     try
    1247             :     {
    1248        5231 :         pImp->xStorage = uno::Reference< embed::XStorage >(
    1249        5723 :                             ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ),
    1250        2370 :                             uno::UNO_QUERY );
    1251             :     }
    1252         492 :     catch( const uno::Exception& )
    1253             :     {
    1254             :         // impossibility to create the storage is no error
    1255             :     }
    1256             : 
    1257        2862 :     if( ( pImp->nLastStorageError = GetError() ) != SVSTREAM_OK )
    1258             :     {
    1259           0 :         pImp->xStorage = 0;
    1260           0 :         if ( pImp->m_pInStream )
    1261           0 :             pImp->m_pInStream->Seek(0);
    1262           0 :         return uno::Reference< embed::XStorage >();
    1263             :     }
    1264             : 
    1265        2862 :     pImp->m_bTriedStorage = true;
    1266             : 
    1267             :     // TODO/LATER: Get versionlist on demand
    1268        2862 :     if ( pImp->xStorage.is() )
    1269             :     {
    1270        2370 :         SetEncryptionDataToStorage_Impl();
    1271        2370 :         GetVersionList();
    1272             :     }
    1273             : 
    1274        2862 :     SFX_ITEMSET_ARG( pImp->m_pSet, pVersion, SfxInt16Item, SID_VERSION, false);
    1275             : 
    1276        2862 :     bool bResetStorage = false;
    1277        2862 :     if ( pVersion && pVersion->GetValue() )
    1278             :     {
    1279             :         // Read all available versions
    1280           0 :         if ( pImp->aVersions.getLength() )
    1281             :         {
    1282             :             // Search for the version fits the comment
    1283             :             // The versions are numbered startign with 1, versions with
    1284             :             // negative versions numbers are counted backwards from the
    1285             :             // current version
    1286           0 :             short nVersion = pVersion ? pVersion->GetValue() : 0;
    1287           0 :             if ( nVersion<0 )
    1288           0 :                 nVersion = ( (short) pImp->aVersions.getLength() ) + nVersion;
    1289           0 :             else if ( nVersion )
    1290           0 :                 nVersion--;
    1291             : 
    1292           0 :             util::RevisionTag& rTag = pImp->aVersions[nVersion];
    1293             :             {
    1294             :                 // Open SubStorage for all versions
    1295           0 :                 uno::Reference < embed::XStorage > xSub = pImp->xStorage->openStorageElement( "Versions",
    1296           0 :                         embed::ElementModes::READ );
    1297             : 
    1298             :                 DBG_ASSERT( xSub.is(), "Version list, but no Versions!" );
    1299             : 
    1300             :                 // There the version is stored as packed Stream
    1301           0 :                 uno::Reference < io::XStream > xStr = xSub->openStreamElement( rTag.Identifier, embed::ElementModes::READ );
    1302           0 :                 SvStream* pStream = utl::UcbStreamHelper::CreateStream( xStr );
    1303           0 :                 if ( pStream && pStream->GetError() == SVSTREAM_OK )
    1304             :                 {
    1305             :                     // Unpack Stream  in TempDir
    1306           0 :                     ::utl::TempFile aTempFile;
    1307           0 :                     OUString          aTmpName = aTempFile.GetURL();
    1308           0 :                     SvFileStream    aTmpStream( aTmpName, SFX_STREAM_READWRITE );
    1309             : 
    1310           0 :                     pStream->ReadStream( aTmpStream );
    1311           0 :                     aTmpStream.Close();
    1312             : 
    1313             :                     // Open data as Storage
    1314           0 :                     pImp->m_nStorOpenMode = SFX_STREAM_READONLY;
    1315           0 :                     pImp->xStorage = comphelper::OStorageHelper::GetStorageFromURL( aTmpName, embed::ElementModes::READ );
    1316           0 :                     pImp->bStorageBasedOnInStream = false;
    1317           0 :                     OUString aTemp;
    1318           0 :                     ::utl::LocalFileHelper::ConvertURLToPhysicalName( aTmpName, aTemp );
    1319           0 :                     SetPhysicalName_Impl( aTemp );
    1320             : 
    1321           0 :                     pImp->bIsTemp = true;
    1322           0 :                     GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
    1323             :                     // TODO/MBA
    1324           0 :                     pImp->aVersions.realloc(0);
    1325             :                 }
    1326             :                 else
    1327           0 :                     bResetStorage = true;
    1328             :             }
    1329             :         }
    1330             :         else
    1331           0 :             bResetStorage = true;
    1332             :     }
    1333             : 
    1334        2862 :     if ( bResetStorage )
    1335             :     {
    1336           0 :         pImp->xStorage.clear();
    1337           0 :         if ( pImp->m_pInStream )
    1338           0 :             pImp->m_pInStream->Seek( 0L );
    1339             :     }
    1340             : 
    1341        2862 :     pImp->bIsStorage = pImp->xStorage.is();
    1342        2862 :     return pImp->xStorage;
    1343             : }
    1344             : 
    1345             : 
    1346         214 : uno::Reference< embed::XStorage > SfxMedium::GetZipStorageToSign_Impl( bool bReadOnly )
    1347             : {
    1348         214 :     if ( !GetError() && !pImp->m_xZipStorage.is() )
    1349             :     {
    1350         214 :         GetMedium_Impl();
    1351             : 
    1352             :         try
    1353             :         {
    1354             :             // we can not sign document if there is no stream
    1355             :             // should it be possible at all?
    1356         214 :             if ( !bReadOnly && pImp->xStream.is() )
    1357             :             {
    1358           0 :                 pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream, embed::ElementModes::READWRITE );
    1359             :             }
    1360         214 :             else if ( pImp->xInputStream.is() )
    1361             :             {
    1362         214 :                 pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( ZIP_STORAGE_FORMAT_STRING, pImp->xInputStream );
    1363             :             }
    1364             :         }
    1365           0 :         catch( const uno::Exception& )
    1366             :         {
    1367             :             SAL_WARN( "sfx.doc", "No possibility to get readonly version of storage from medium!" );
    1368             :         }
    1369             : 
    1370         214 :         if ( GetError() ) // do not remove warnings
    1371           0 :             ResetError();
    1372             :     }
    1373             : 
    1374         214 :     return pImp->m_xZipStorage;
    1375             : }
    1376             : 
    1377             : 
    1378       29294 : void SfxMedium::CloseZipStorage_Impl()
    1379             : {
    1380       29294 :     if ( pImp->m_xZipStorage.is() )
    1381             :     {
    1382             :         try {
    1383         210 :             pImp->m_xZipStorage->dispose();
    1384           0 :         } catch( const uno::Exception& )
    1385             :         {}
    1386             : 
    1387         210 :         pImp->m_xZipStorage.clear();
    1388             :     }
    1389       29294 : }
    1390             : 
    1391       17938 : void SfxMedium::CloseStorage()
    1392             : {
    1393       17938 :     if ( pImp->xStorage.is() )
    1394             :     {
    1395        3503 :         uno::Reference < lang::XComponent > xComp( pImp->xStorage, uno::UNO_QUERY );
    1396             :         // in the salvage mode the medium does not own the storage
    1397        3503 :         if ( pImp->bDisposeStorage && !pImp->m_bSalvageMode )
    1398             :         {
    1399             :             try {
    1400        1995 :                 xComp->dispose();
    1401           0 :             } catch( const uno::Exception& )
    1402             :             {
    1403             :                 SAL_WARN( "sfx.doc", "Medium's storage is already disposed!" );
    1404             :             }
    1405             :         }
    1406             : 
    1407        3503 :         pImp->xStorage.clear();
    1408        3503 :         pImp->bStorageBasedOnInStream = false;
    1409             :     }
    1410             : 
    1411       17938 :     pImp->m_bTriedStorage = false;
    1412       17938 :     pImp->bIsStorage = false;
    1413       17938 : }
    1414             : 
    1415        6094 : void SfxMedium::CanDisposeStorage_Impl( bool bDisposeStorage )
    1416             : {
    1417        6094 :     pImp->bDisposeStorage = bDisposeStorage;
    1418        6094 : }
    1419             : 
    1420           0 : bool SfxMedium::WillDisposeStorageOnClose_Impl()
    1421             : {
    1422           0 :     return pImp->bDisposeStorage;
    1423             : }
    1424             : 
    1425       26621 : StreamMode SfxMedium::GetOpenMode() const
    1426             : {
    1427       26621 :     return pImp->m_nStorOpenMode;
    1428             : }
    1429             : 
    1430          49 : void SfxMedium::SetOpenMode( StreamMode nStorOpen,
    1431             :                              bool bDontClose )
    1432             : {
    1433          49 :     if ( pImp->m_nStorOpenMode != nStorOpen )
    1434             :     {
    1435           0 :         pImp->m_nStorOpenMode = nStorOpen;
    1436             : 
    1437           0 :         if( !bDontClose )
    1438             :         {
    1439           0 :             if ( pImp->xStorage.is() )
    1440           0 :                 CloseStorage();
    1441             : 
    1442           0 :             CloseStreams_Impl();
    1443             :         }
    1444             :     }
    1445          49 : }
    1446             : 
    1447             : 
    1448           0 : bool SfxMedium::UseBackupToRestore_Impl( ::ucbhelper::Content& aOriginalContent,
    1449             :                                             const Reference< ::com::sun::star::ucb::XCommandEnvironment >& xComEnv )
    1450             : {
    1451             :     try
    1452             :     {
    1453           0 :         ::ucbhelper::Content aTransactCont( pImp->m_aBackupURL, xComEnv, comphelper::getProcessComponentContext() );
    1454             : 
    1455           0 :         Reference< XInputStream > aOrigInput = aTransactCont.openStream();
    1456           0 :         aOriginalContent.writeStream( aOrigInput, true );
    1457           0 :         return true;
    1458             :     }
    1459           0 :     catch( const Exception& )
    1460             :     {
    1461             :         // in case of failure here the backup file should not be removed
    1462             :         // TODO/LATER: a message should be used to let user know about the backup
    1463           0 :         pImp->m_bRemoveBackup = false;
    1464             :         // TODO/LATER: needs a specific error code
    1465           0 :         pImp->m_eError = ERRCODE_IO_GENERAL;
    1466             :     }
    1467             : 
    1468           0 :     return false;
    1469             : }
    1470             : 
    1471             : 
    1472         105 : bool SfxMedium::StorageCommit_Impl()
    1473             : {
    1474         105 :     bool bResult = false;
    1475         105 :     Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
    1476         210 :     ::ucbhelper::Content aOriginalContent;
    1477             : 
    1478         105 :     if ( pImp->xStorage.is() )
    1479             :     {
    1480         105 :         if ( !GetError() )
    1481             :         {
    1482         105 :             uno::Reference < embed::XTransactedObject > xTrans( pImp->xStorage, uno::UNO_QUERY );
    1483         105 :             if ( xTrans.is() )
    1484             :             {
    1485             :                 try
    1486             :                 {
    1487         105 :                     xTrans->commit();
    1488         105 :                     CloseZipStorage_Impl();
    1489         105 :                     bResult = true;
    1490             :                 }
    1491           0 :                 catch ( const embed::UseBackupException& aBackupExc )
    1492             :                 {
    1493             :                     // since the temporary file is created always now, the scenario is close to be impossible
    1494           0 :                     if ( !pImp->pTempFile )
    1495             :                     {
    1496             :                         OSL_ENSURE( !pImp->m_aBackupURL.isEmpty(), "No backup on storage commit!\n" );
    1497           0 :                         if ( !pImp->m_aBackupURL.isEmpty()
    1498           0 :                             && ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ),
    1499             :                                                         xDummyEnv, comphelper::getProcessComponentContext(),
    1500           0 :                                                         aOriginalContent ) )
    1501             :                         {
    1502             :                             // use backup to restore the file
    1503             :                             // the storage has already disconnected from original location
    1504           0 :                             CloseAndReleaseStreams_Impl();
    1505           0 :                             if ( !UseBackupToRestore_Impl( aOriginalContent, xDummyEnv ) )
    1506             :                             {
    1507             :                                 // connect the medium to the temporary file of the storage
    1508           0 :                                 pImp->aContent = ::ucbhelper::Content();
    1509           0 :                                 pImp->m_aName = aBackupExc.TemporaryFileURL;
    1510             :                                 OSL_ENSURE( !pImp->m_aName.isEmpty(), "The exception _must_ contain the temporary URL!\n" );
    1511             :                             }
    1512             :                         }
    1513             : 
    1514           0 :                         if ( !GetError() )
    1515           0 :                             SetError( ERRCODE_IO_GENERAL, OUString( OSL_LOG_PREFIX  ) );
    1516             :                     }
    1517             :                 }
    1518           0 :                 catch ( const uno::Exception& )
    1519             :                 {
    1520             :                     //TODO/LATER: improve error handling
    1521           0 :                     SetError( ERRCODE_IO_GENERAL, OUString( OSL_LOG_PREFIX  ) );
    1522             :                 }
    1523         105 :             }
    1524             :         }
    1525             :     }
    1526             : 
    1527         210 :     return bResult;
    1528             : }
    1529             : 
    1530             : 
    1531         836 : bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource,
    1532             :                                                  const INetURLObject& aDest,
    1533             :                                                  const Reference< ::com::sun::star::ucb::XCommandEnvironment >& xComEnv )
    1534             : {
    1535         836 :     bool bResult = false;
    1536         836 :     Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
    1537        1672 :     Reference< XOutputStream > aDestStream;
    1538        1672 :     ::ucbhelper::Content aOriginalContent;
    1539             : 
    1540             :     try
    1541             :     {
    1542         836 :         aOriginalContent = ::ucbhelper::Content( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv, comphelper::getProcessComponentContext() );
    1543             :     }
    1544           0 :     catch ( const ::com::sun::star::ucb::CommandAbortedException& )
    1545             :     {
    1546           0 :         pImp->m_eError = ERRCODE_ABORT;
    1547             :     }
    1548           0 :     catch ( const ::com::sun::star::ucb::CommandFailedException& )
    1549             :     {
    1550           0 :         pImp->m_eError = ERRCODE_ABORT;
    1551             :     }
    1552           0 :     catch (const ::com::sun::star::ucb::ContentCreationException& ex)
    1553             :     {
    1554           0 :         pImp->m_eError = ERRCODE_IO_GENERAL;
    1555           0 :         if (
    1556           0 :             (ex.eError == ::com::sun::star::ucb::ContentCreationError_NO_CONTENT_PROVIDER    ) ||
    1557           0 :             (ex.eError == ::com::sun::star::ucb::ContentCreationError_CONTENT_CREATION_FAILED)
    1558             :            )
    1559             :         {
    1560           0 :             pImp->m_eError = ERRCODE_IO_NOTEXISTSPATH;
    1561             :         }
    1562             :     }
    1563           0 :     catch (const ::com::sun::star::uno::Exception&)
    1564             :     {
    1565           0 :        pImp->m_eError = ERRCODE_IO_GENERAL;
    1566             :     }
    1567             : 
    1568         836 :     if( !pImp->m_eError || (pImp->m_eError & ERRCODE_WARNING_MASK) )
    1569             :     {
    1570         836 :         if ( pImp->xStorage.is() )
    1571         105 :             CloseStorage();
    1572             : 
    1573         836 :         CloseStreams_Impl();
    1574             : 
    1575         836 :         ::ucbhelper::Content aTempCont;
    1576         836 :         if( ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, comphelper::getProcessComponentContext(), aTempCont ) )
    1577             :         {
    1578         836 :             bool bTransactStarted = false;
    1579         836 :             SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, false );
    1580         836 :                SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, false );
    1581         836 :             bool bRename = pRename && pRename->GetValue();
    1582         836 :             bool bOverWrite = pOverWrite ? pOverWrite->GetValue() : !bRename;
    1583             : 
    1584             :             try
    1585             :             {
    1586         836 :                 if( bOverWrite && ::utl::UCBContentHelper::IsDocument( aDest.GetMainURL( INetURLObject::NO_DECODE ) ) )
    1587             :                 {
    1588         819 :                     if( pImp->m_aBackupURL.isEmpty() )
    1589         818 :                         DoInternalBackup_Impl( aOriginalContent );
    1590             : 
    1591         819 :                     if( !pImp->m_aBackupURL.isEmpty() )
    1592             :                     {
    1593         819 :                         Reference< XInputStream > aTempInput = aTempCont.openStream();
    1594         819 :                         bTransactStarted = true;
    1595         819 :                         aOriginalContent.setPropertyValue( "Size", uno::makeAny( (sal_Int64)0 ) );
    1596         819 :                         aOriginalContent.writeStream( aTempInput, bOverWrite );
    1597         819 :                         bResult = true;
    1598             :                     }
    1599             :                     else
    1600             :                     {
    1601           0 :                         pImp->m_eError = ERRCODE_SFX_CANTCREATEBACKUP;
    1602             :                     }
    1603             :                 }
    1604             :                 else
    1605             :                 {
    1606          17 :                     Reference< XInputStream > aTempInput = aTempCont.openStream();
    1607          17 :                     aOriginalContent.writeStream( aTempInput, bOverWrite );
    1608          17 :                     bResult = true;
    1609             :                 }
    1610             :             }
    1611           0 :             catch ( const ::com::sun::star::ucb::CommandAbortedException& )
    1612             :             {
    1613           0 :                 pImp->m_eError = ERRCODE_ABORT;
    1614             :             }
    1615           0 :             catch ( const ::com::sun::star::ucb::CommandFailedException& )
    1616             :             {
    1617           0 :                 pImp->m_eError = ERRCODE_ABORT;
    1618             :             }
    1619           0 :             catch ( const ::com::sun::star::ucb::InteractiveIOException& r )
    1620             :             {
    1621           0 :                 if ( r.Code == IOErrorCode_ACCESS_DENIED )
    1622           0 :                     pImp->m_eError = ERRCODE_IO_ACCESSDENIED;
    1623           0 :                 else if ( r.Code == IOErrorCode_NOT_EXISTING )
    1624           0 :                     pImp->m_eError = ERRCODE_IO_NOTEXISTS;
    1625           0 :                 else if ( r.Code == IOErrorCode_CANT_READ )
    1626           0 :                     pImp->m_eError = ERRCODE_IO_CANTREAD;
    1627             :                 else
    1628           0 :                     pImp->m_eError = ERRCODE_IO_GENERAL;
    1629             :             }
    1630           0 :             catch ( const ::com::sun::star::uno::Exception& )
    1631             :             {
    1632           0 :                 pImp->m_eError = ERRCODE_IO_GENERAL;
    1633             :             }
    1634             : 
    1635         836 :                if ( bResult )
    1636             :                {
    1637         836 :                 if ( pImp->pTempFile )
    1638             :                 {
    1639         836 :                     pImp->pTempFile->EnableKillingFile( true );
    1640         836 :                        delete pImp->pTempFile;
    1641         836 :                        pImp->pTempFile = NULL;
    1642             :                 }
    1643             :                }
    1644           0 :             else if ( bTransactStarted )
    1645             :             {
    1646           0 :                 UseBackupToRestore_Impl( aOriginalContent, xDummyEnv );
    1647             :             }
    1648             :         }
    1649             :         else
    1650           0 :             pImp->m_eError = ERRCODE_IO_CANTREAD;
    1651             :     }
    1652             : 
    1653        1672 :     return bResult;
    1654             : }
    1655             : 
    1656             : 
    1657           0 : bool SfxMedium::TryDirectTransfer( const OUString& aURL, SfxItemSet& aTargetSet )
    1658             : {
    1659           0 :     if ( GetError() )
    1660           0 :         return false;
    1661             : 
    1662             :     // if the document had no password it should be stored without password
    1663             :     // if the document had password it should be stored with the same password
    1664             :     // otherwise the stream copying can not be done
    1665           0 :     SFX_ITEMSET_ARG( &aTargetSet, pNewPassItem, SfxStringItem, SID_PASSWORD, false );
    1666           0 :     SFX_ITEMSET_ARG( GetItemSet(), pOldPassItem, SfxStringItem, SID_PASSWORD, false );
    1667           0 :     if ( ( !pNewPassItem && !pOldPassItem )
    1668           0 :       || ( pNewPassItem && pOldPassItem && pNewPassItem->GetValue() == pOldPassItem->GetValue() ) )
    1669             :     {
    1670             :         // the filter must be the same
    1671           0 :         SFX_ITEMSET_ARG( &aTargetSet, pNewFilterItem, SfxStringItem, SID_FILTER_NAME, false );
    1672           0 :         SFX_ITEMSET_ARG( GetItemSet(), pOldFilterItem, SfxStringItem, SID_FILTER_NAME, false );
    1673           0 :         if ( pNewFilterItem && pOldFilterItem && pNewFilterItem->GetValue() == pOldFilterItem->GetValue() )
    1674             :         {
    1675             :             // get the input stream and copy it
    1676             :             // in case of success return true
    1677           0 :             uno::Reference< io::XInputStream > xInStream = GetInputStream();
    1678             : 
    1679           0 :             ResetError();
    1680           0 :             if ( xInStream.is() )
    1681             :             {
    1682             :                 try
    1683             :                 {
    1684           0 :                     uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
    1685           0 :                     sal_Int64 nPos = 0;
    1686           0 :                     if ( xSeek.is() )
    1687             :                     {
    1688           0 :                         nPos = xSeek->getPosition();
    1689           0 :                         xSeek->seek( 0 );
    1690             :                     }
    1691             : 
    1692           0 :                     uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
    1693           0 :                     ::ucbhelper::Content aTargetContent( aURL, xEnv, comphelper::getProcessComponentContext() );
    1694             : 
    1695           0 :                     InsertCommandArgument aInsertArg;
    1696           0 :                     aInsertArg.Data = xInStream;
    1697           0 :                        SFX_ITEMSET_ARG( &aTargetSet, pRename, SfxBoolItem, SID_RENAME, false );
    1698           0 :                        SFX_ITEMSET_ARG( &aTargetSet, pOverWrite, SfxBoolItem, SID_OVERWRITE, false );
    1699           0 :                        if ( (pOverWrite && !pOverWrite->GetValue()) // argument says: never overwrite
    1700           0 :                          || (pRename && pRename->GetValue()) ) // argument says: rename file
    1701           0 :                         aInsertArg.ReplaceExisting = false;
    1702             :                        else
    1703           0 :                         aInsertArg.ReplaceExisting = true; // default is overwrite existing files
    1704             : 
    1705           0 :                     Any aCmdArg;
    1706           0 :                     aCmdArg <<= aInsertArg;
    1707             :                     aTargetContent.executeCommand( OUString( "insert"  ),
    1708           0 :                                                     aCmdArg );
    1709             : 
    1710           0 :                     if ( xSeek.is() )
    1711           0 :                         xSeek->seek( nPos );
    1712             : 
    1713           0 :                     return true;
    1714             :                 }
    1715           0 :                 catch( const uno::Exception& )
    1716             :                 {}
    1717           0 :             }
    1718             :         }
    1719             :     }
    1720             : 
    1721           0 :     return false;
    1722             : }
    1723             : 
    1724             : 
    1725         839 : void SfxMedium::Transfer_Impl()
    1726             : {
    1727             :     // The transfer is required only in two cases: either if there is a temporary file or if there is a salvage item
    1728         839 :     OUString aNameURL;
    1729         839 :     if ( pImp->pTempFile )
    1730         838 :         aNameURL = pImp->pTempFile->GetURL();
    1731           1 :     else if ( !pImp->m_aLogicName.isEmpty() && pImp->m_bSalvageMode )
    1732             :     {
    1733             :         // makes sense only in case logic name is set
    1734           0 :         if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->m_aName, aNameURL ) )
    1735             :             SAL_WARN( "sfx.doc", "The medium name is not convertible!" );
    1736             :     }
    1737             : 
    1738         839 :     if ( !aNameURL.isEmpty() && ( !pImp->m_eError || (pImp->m_eError & ERRCODE_WARNING_MASK) ) )
    1739             :     {
    1740             :         SAL_INFO( "sfx.doc", "SfxMedium::Transfer_Impl, copying to target" );
    1741             : 
    1742         838 :         Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
    1743        1674 :         Reference< XOutputStream > rOutStream;
    1744             : 
    1745             :         // in case an output stream is provided from outside and the URL is correct
    1746             :         // commit to the stream
    1747         838 :         if (pImp->m_aLogicName.startsWith("private:stream"))
    1748             :         {
    1749             :             // TODO/LATER: support storing to SID_STREAM
    1750           2 :             SFX_ITEMSET_ARG( pImp->m_pSet, pOutStreamItem, SfxUnoAnyItem, SID_OUTPUTSTREAM, false);
    1751           2 :             if( pOutStreamItem && ( pOutStreamItem->GetValue() >>= rOutStream ) )
    1752             :             {
    1753           2 :                 if ( pImp->xStorage.is() )
    1754           0 :                     CloseStorage();
    1755             : 
    1756           2 :                 CloseStreams_Impl();
    1757             : 
    1758           2 :                 INetURLObject aSource( aNameURL );
    1759           4 :                 ::ucbhelper::Content aTempCont;
    1760           2 :                 if( ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, comphelper::getProcessComponentContext(), aTempCont ) )
    1761             :                 {
    1762             :                     try
    1763             :                     {
    1764             :                         sal_Int32 nRead;
    1765           2 :                         sal_Int32 nBufferSize = 32767;
    1766           2 :                         Sequence < sal_Int8 > aSequence ( nBufferSize );
    1767           4 :                         Reference< XInputStream > aTempInput = aTempCont.openStream();
    1768             : 
    1769           2 :                         do
    1770             :                         {
    1771           2 :                             nRead = aTempInput->readBytes ( aSequence, nBufferSize );
    1772           2 :                             if ( nRead < nBufferSize )
    1773             :                             {
    1774           2 :                                 Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead );
    1775           2 :                                 rOutStream->writeBytes ( aTempBuf );
    1776             :                             }
    1777             :                             else
    1778           0 :                                 rOutStream->writeBytes ( aSequence );
    1779             :                         }
    1780             :                         while ( nRead == nBufferSize );
    1781             : 
    1782             :                         // remove temporary file
    1783           2 :                         if ( pImp->pTempFile )
    1784             :                         {
    1785           2 :                             pImp->pTempFile->EnableKillingFile( true );
    1786           2 :                             delete pImp->pTempFile;
    1787           2 :                             pImp->pTempFile = NULL;
    1788           2 :                         }
    1789             :                     }
    1790           0 :                     catch( const Exception& )
    1791             :                     {}
    1792           2 :                 }
    1793             :             }
    1794             :             else
    1795             :             {
    1796             :                 SAL_WARN( "sfx.doc", "Illegal Output stream parameter!" );
    1797           0 :                 SetError( ERRCODE_IO_GENERAL, OUString( OSL_LOG_PREFIX  ) );
    1798             :             }
    1799             : 
    1800             :             // free the reference
    1801           2 :             if ( pImp->m_pSet )
    1802           2 :                 pImp->m_pSet->ClearItem( SID_OUTPUTSTREAM );
    1803             : 
    1804           2 :             return;
    1805             :         }
    1806             : 
    1807         836 :         GetContent();
    1808         836 :         if ( !pImp->aContent.get().is() )
    1809             :         {
    1810           0 :             pImp->m_eError = ERRCODE_IO_NOTEXISTS;
    1811           0 :             return;
    1812             :         }
    1813             : 
    1814         836 :         SFX_ITEMSET_ARG( GetItemSet(), pSegmentSize, SfxInt32Item, SID_SEGMENTSIZE, false);
    1815         836 :         if ( pSegmentSize )
    1816             :         {
    1817             :             // this file must be stored into a disk spanned package
    1818             :             try
    1819             :             {
    1820           0 :                 uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetStorageFromURL( GetName(),
    1821           0 :                         embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
    1822             : 
    1823             :                 // set segment size property; package will automatically be divided in pieces fitting
    1824             :                 // into this size
    1825           0 :                 ::com::sun::star::uno::Any aAny;
    1826           0 :                 aAny <<= pSegmentSize->GetValue();
    1827             : 
    1828           0 :                 uno::Reference < beans::XPropertySet > xSet( pImp->xStorage, uno::UNO_QUERY );
    1829           0 :                 xSet->setPropertyValue("SegmentSize", aAny );
    1830             : 
    1831             :                 // copy the temporary storage into the disk spanned package
    1832           0 :                 GetStorage()->copyToStorage( xStor );
    1833           0 :                 uno::Reference < embed::XTransactedObject > xTrans( pImp->xStorage, uno::UNO_QUERY );
    1834           0 :                 if ( xTrans.is() )
    1835           0 :                     xTrans->commit();
    1836             : 
    1837             :             }
    1838           0 :             catch ( const uno::Exception& )
    1839             :             {
    1840             :                 //TODO/MBA: error handling
    1841             :             }
    1842           0 :             return;
    1843             :         }
    1844             : 
    1845        1672 :         INetURLObject aDest( GetURLObject() );
    1846             : 
    1847             :         // source is the temp file written so far
    1848        1672 :         INetURLObject aSource( aNameURL );
    1849             : 
    1850             :         // a special case, an interaction handler should be used for
    1851             :         // authentication in case it is available
    1852        1672 :         Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
    1853        1672 :            Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = GetInteractionHandler();
    1854         836 :         if (xInteractionHandler.is())
    1855        2073 :             xComEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler,
    1856        1382 :                                                       Reference< ::com::sun::star::ucb::XProgressHandler >() );
    1857             : 
    1858        1672 :         OUString aDestURL( aDest.GetMainURL( INetURLObject::NO_DECODE ) );
    1859             : 
    1860         836 :         if ( ::utl::LocalFileHelper::IsLocalFile( aDestURL ) || !aDest.removeSegment() )
    1861             :         {
    1862         836 :             TransactedTransferForFS_Impl( aSource, aDest, xComEnv );
    1863             : 
    1864             :             // Hideous - no clean way to do this, so we re-open the file just to fsync it
    1865         836 :             osl::File aFile( aDestURL );
    1866         836 :             if ( aFile.open( osl_File_OpenFlag_Write ) == osl::FileBase::E_None )
    1867             :             {
    1868         836 :                 aFile.sync();
    1869             :                 SAL_INFO( "sfx.doc", "fsync'd saved file '" << aDestURL << "'" );
    1870         836 :                 aFile.close();
    1871         836 :             }
    1872             :         }
    1873             :         else
    1874             :         {
    1875             :             // create content for the parent folder and call transfer on that content with the source content
    1876             :             // and the destination file name as parameters
    1877           0 :             ::ucbhelper::Content aSourceContent;
    1878           0 :             ::ucbhelper::Content aTransferContent;
    1879             : 
    1880           0 :             ::ucbhelper::Content aDestContent;
    1881           0 :             (void)::ucbhelper::Content::create( aDestURL, xComEnv, comphelper::getProcessComponentContext(), aDestContent );
    1882             :             // For checkin, we need the object URL, not the parent folder:
    1883           0 :             if ( !IsInCheckIn( ) )
    1884             :             {
    1885             :                 // Get the parent URL from the XChild if possible: why would the URL necessarily have
    1886             :                 // a hierarchical path? It's not always the case for CMIS.
    1887           0 :                 Reference< ::com::sun::star::container::XChild> xChild( aDestContent.get(), uno::UNO_QUERY );
    1888           0 :                 OUString sParentUrl;
    1889           0 :                 if ( xChild.is( ) )
    1890             :                 {
    1891           0 :                     Reference< ::com::sun::star::ucb::XContent > xParent( xChild->getParent( ), uno::UNO_QUERY );
    1892           0 :                     if ( xParent.is( ) )
    1893             :                     {
    1894           0 :                         sParentUrl = xParent->getIdentifier( )->getContentIdentifier();
    1895           0 :                     }
    1896             :                 }
    1897             : 
    1898           0 :                 if ( sParentUrl.isEmpty() )
    1899           0 :                     aDestURL = aDest.GetMainURL( INetURLObject::NO_DECODE );
    1900             :                         // adjust to above aDest.removeSegment()
    1901             :                 else
    1902           0 :                     aDestURL = sParentUrl;
    1903             :             }
    1904             : 
    1905             :             // LongName wasn't defined anywhere, only used here... get the Title instead
    1906             :             // as it's less probably empty
    1907           0 :             OUString aFileName;
    1908           0 :             Any aAny = aDestContent.getPropertyValue("Title");
    1909           0 :             aAny >>= aFileName;
    1910           0 :             aAny = aDestContent.getPropertyValue( OUString("ObjectId" ) );
    1911           0 :             OUString sObjectId;
    1912           0 :             aAny >>= sObjectId;
    1913           0 :             if ( aFileName.isEmpty() )
    1914           0 :                 aFileName = GetURLObject().getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
    1915             : 
    1916             :             try
    1917             :             {
    1918           0 :                 aTransferContent = ::ucbhelper::Content( aDestURL, xComEnv, comphelper::getProcessComponentContext() );
    1919             :             }
    1920           0 :             catch (const ::com::sun::star::ucb::ContentCreationException& ex)
    1921             :             {
    1922           0 :                 pImp->m_eError = ERRCODE_IO_GENERAL;
    1923           0 :                 if (
    1924           0 :                     (ex.eError == ::com::sun::star::ucb::ContentCreationError_NO_CONTENT_PROVIDER    ) ||
    1925           0 :                     (ex.eError == ::com::sun::star::ucb::ContentCreationError_CONTENT_CREATION_FAILED)
    1926             :                    )
    1927             :                 {
    1928           0 :                     pImp->m_eError = ERRCODE_IO_NOTEXISTSPATH;
    1929             :                 }
    1930             :             }
    1931           0 :             catch (const ::com::sun::star::uno::Exception&)
    1932             :             {
    1933           0 :                 pImp->m_eError = ERRCODE_IO_GENERAL;
    1934             :             }
    1935             : 
    1936           0 :             if ( !pImp->m_eError || (pImp->m_eError & ERRCODE_WARNING_MASK) )
    1937             :             {
    1938             :                 // free resources, otherwise the transfer may fail
    1939           0 :                 if ( pImp->xStorage.is() )
    1940           0 :                     CloseStorage();
    1941             : 
    1942           0 :                 CloseStreams_Impl();
    1943             : 
    1944           0 :                 (void)::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, comphelper::getProcessComponentContext(), aSourceContent );
    1945             : 
    1946             :                 // check for external parameters that may customize the handling of NameClash situations
    1947           0 :                 SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, false );
    1948           0 :                 SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, false );
    1949             :                 sal_Int32 nNameClash;
    1950           0 :                 if ( pOverWrite && !pOverWrite->GetValue() )
    1951             :                     // argument says: never overwrite
    1952           0 :                     nNameClash = NameClash::ERROR;
    1953           0 :                 else if ( pRename && pRename->GetValue() )
    1954             :                     // argument says: rename file
    1955           0 :                     nNameClash = NameClash::RENAME;
    1956             :                 else
    1957             :                     // default is overwrite existing files
    1958           0 :                     nNameClash = NameClash::OVERWRITE;
    1959             : 
    1960             :                 try
    1961             :                 {
    1962           0 :                     OUString aMimeType = pImp->getFilterMimeType();
    1963           0 :                     ::ucbhelper::InsertOperation eOperation = ::ucbhelper::InsertOperation_COPY;
    1964           0 :                     bool bMajor = false;
    1965           0 :                     OUString sComment;
    1966           0 :                     if ( IsInCheckIn( ) )
    1967             :                     {
    1968           0 :                         eOperation = ::ucbhelper::InsertOperation_CHECKIN;
    1969           0 :                         SFX_ITEMSET_ARG( GetItemSet(), pMajor, SfxBoolItem, SID_DOCINFO_MAJOR, false );
    1970           0 :                         bMajor = pMajor && pMajor->GetValue( );
    1971           0 :                         SFX_ITEMSET_ARG( GetItemSet(), pComments, SfxStringItem, SID_DOCINFO_COMMENTS, false );
    1972           0 :                         if ( pComments )
    1973           0 :                             sComment = pComments->GetValue( );
    1974             :                     }
    1975           0 :                     OUString sResultURL;
    1976           0 :                     if (!aTransferContent.transferContent( aSourceContent, eOperation,
    1977           0 :                                 aFileName, nNameClash, aMimeType, bMajor, sComment, &sResultURL, sObjectId))
    1978           0 :                         pImp->m_eError = ERRCODE_IO_GENERAL;
    1979           0 :                     else if ( !sResultURL.isEmpty( ) )  // Likely to happen only for checkin
    1980           0 :                         SwitchDocumentToFile( sResultURL );
    1981             :                 }
    1982           0 :                 catch ( const ::com::sun::star::ucb::CommandAbortedException& )
    1983             :                 {
    1984           0 :                     pImp->m_eError = ERRCODE_ABORT;
    1985             :                 }
    1986           0 :                 catch ( const ::com::sun::star::ucb::CommandFailedException& )
    1987             :                 {
    1988           0 :                     pImp->m_eError = ERRCODE_ABORT;
    1989             :                 }
    1990           0 :                 catch ( const ::com::sun::star::ucb::InteractiveIOException& r )
    1991             :                 {
    1992           0 :                     if ( r.Code == IOErrorCode_ACCESS_DENIED )
    1993           0 :                         pImp->m_eError = ERRCODE_IO_ACCESSDENIED;
    1994           0 :                     else if ( r.Code == IOErrorCode_NOT_EXISTING )
    1995           0 :                         pImp->m_eError = ERRCODE_IO_NOTEXISTS;
    1996           0 :                     else if ( r.Code == IOErrorCode_CANT_READ )
    1997           0 :                         pImp->m_eError = ERRCODE_IO_CANTREAD;
    1998             :                     else
    1999           0 :                         pImp->m_eError = ERRCODE_IO_GENERAL;
    2000             :                 }
    2001           0 :                 catch ( const ::com::sun::star::uno::Exception& )
    2002             :                 {
    2003           0 :                     pImp->m_eError = ERRCODE_IO_GENERAL;
    2004             :                 }
    2005             : 
    2006             :                 // do not switch from temporary file in case of nonfile protocol
    2007           0 :             }
    2008             :         }
    2009             : 
    2010         836 :         if ( ( !pImp->m_eError || (pImp->m_eError & ERRCODE_WARNING_MASK) ) && !pImp->pTempFile )
    2011             :         {
    2012             :             // without a TempFile the physical and logical name should be the same after successful transfer
    2013             :               ::utl::LocalFileHelper::ConvertURLToPhysicalName(
    2014         836 :                   GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), pImp->m_aName );
    2015         836 :             pImp->m_bSalvageMode = false;
    2016         836 :         }
    2017         837 :     }
    2018             : }
    2019             : 
    2020             : 
    2021         819 : void SfxMedium::DoInternalBackup_Impl( const ::ucbhelper::Content& aOriginalContent,
    2022             :                                        const OUString& aPrefix,
    2023             :                                        const OUString& aExtension,
    2024             :                                        const OUString& aDestDir )
    2025             : {
    2026         819 :     if ( !pImp->m_aBackupURL.isEmpty() )
    2027         819 :         return; // the backup was done already
    2028             : 
    2029         819 :     ::utl::TempFile aTransactTemp( aPrefix, true, &aExtension, &aDestDir );
    2030             : 
    2031        1638 :     INetURLObject aBackObj( aTransactTemp.GetURL() );
    2032        1638 :     OUString aBackupName = aBackObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
    2033             : 
    2034        1638 :     Reference < ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
    2035        1638 :     ::ucbhelper::Content aBackupCont;
    2036         819 :     if( ::ucbhelper::Content::create( aDestDir, xDummyEnv, comphelper::getProcessComponentContext(), aBackupCont ) )
    2037             :     {
    2038             :         try
    2039             :         {
    2040         819 :             OUString sMimeType = pImp->getFilterMimeType();
    2041        1638 :             if( aBackupCont.transferContent( aOriginalContent,
    2042             :                                             ::ucbhelper::InsertOperation_COPY,
    2043             :                                             aBackupName,
    2044             :                                             NameClash::OVERWRITE,
    2045        1638 :                                             sMimeType ) )
    2046             :             {
    2047         819 :                 pImp->m_aBackupURL = aBackObj.GetMainURL( INetURLObject::NO_DECODE );
    2048         819 :                 pImp->m_bRemoveBackup = true;
    2049         819 :             }
    2050             :         }
    2051           0 :         catch( const Exception& )
    2052             :         {}
    2053             :     }
    2054             : 
    2055         819 :     if ( pImp->m_aBackupURL.isEmpty() )
    2056         819 :         aTransactTemp.EnableKillingFile();
    2057             : }
    2058             : 
    2059             : 
    2060         819 : void SfxMedium::DoInternalBackup_Impl( const ::ucbhelper::Content& aOriginalContent )
    2061             : {
    2062         819 :     if ( !pImp->m_aBackupURL.isEmpty() )
    2063         819 :         return; // the backup was done already
    2064             : 
    2065         819 :     OUString aFileName =  GetURLObject().getName( INetURLObject::LAST_SEGMENT,
    2066             :                                                         true,
    2067         819 :                                                         INetURLObject::NO_DECODE );
    2068             : 
    2069         819 :     sal_Int32 nPrefixLen = aFileName.lastIndexOf( '.' );
    2070        1638 :     OUString aPrefix = ( nPrefixLen == -1 ) ? aFileName : aFileName.copy( 0, nPrefixLen );
    2071        1638 :     OUString aExtension = ( nPrefixLen == -1 ) ? OUString() : aFileName.copy( nPrefixLen );
    2072        1638 :     OUString aBakDir = SvtPathOptions().GetBackupPath();
    2073             : 
    2074             :     // create content for the parent folder ( = backup folder )
    2075        1638 :     ::ucbhelper::Content  aContent;
    2076        1638 :     Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
    2077         819 :     if( ::utl::UCBContentHelper::ensureFolder(comphelper::getProcessComponentContext(), xEnv, aBakDir, aContent) )
    2078         819 :         DoInternalBackup_Impl( aOriginalContent, aPrefix, aExtension, aBakDir );
    2079             : 
    2080         819 :     if ( pImp->m_aBackupURL.isEmpty() )
    2081             :     {
    2082             :         // the copiing to the backup catalog failed ( for example because
    2083             :         // of using an encrypted partition as target catalog )
    2084             :         // since the user did not specify to make backup explicitly
    2085             :         // office should try to make backup in another place,
    2086             :         // target catalog does not look bad for this case ( and looks
    2087             :         // to be the only way for encrypted partitions )
    2088             : 
    2089           0 :         INetURLObject aDest = GetURLObject();
    2090           0 :         if ( aDest.removeSegment() )
    2091           0 :             DoInternalBackup_Impl( aOriginalContent, aPrefix, aExtension, aDest.GetMainURL( INetURLObject::NO_DECODE ) );
    2092         819 :     }
    2093             : }
    2094             : 
    2095             : 
    2096             : 
    2097           0 : void SfxMedium::DoBackup_Impl()
    2098             : {
    2099             :     // source file name is the logical name of this medium
    2100           0 :     INetURLObject aSource( GetURLObject() );
    2101             : 
    2102             :     // there is nothing to backup in case source file does not exist
    2103           0 :     if ( !::utl::UCBContentHelper::IsDocument( aSource.GetMainURL( INetURLObject::NO_DECODE ) ) )
    2104           0 :         return;
    2105             : 
    2106           0 :     bool        bSuccess = false;
    2107             : 
    2108             :     // get path for backups
    2109           0 :     OUString aBakDir = SvtPathOptions().GetBackupPath();
    2110           0 :     if( !aBakDir.isEmpty() )
    2111             :     {
    2112             :         // create content for the parent folder ( = backup folder )
    2113           0 :         ::ucbhelper::Content  aContent;
    2114           0 :         Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
    2115           0 :         if( ::utl::UCBContentHelper::ensureFolder(comphelper::getProcessComponentContext(), xEnv, aBakDir, aContent) )
    2116             :         {
    2117             :             // save as ".bak" file
    2118           0 :             INetURLObject aDest( aBakDir );
    2119           0 :             aDest.insertName( aSource.getName() );
    2120           0 :             aDest.setExtension( "bak" );
    2121           0 :             OUString aFileName = aDest.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
    2122             : 
    2123             :             // create a content for the source file
    2124           0 :             ::ucbhelper::Content aSourceContent;
    2125           0 :             if ( ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, comphelper::getProcessComponentContext(), aSourceContent ) )
    2126             :             {
    2127             :                 try
    2128             :                 {
    2129             :                     // do the transfer ( copy source file to backup dir )
    2130           0 :                     OUString sMimeType = pImp->getFilterMimeType();
    2131             :                     bSuccess = aContent.transferContent( aSourceContent,
    2132             :                                                         ::ucbhelper::InsertOperation_COPY,
    2133             :                                                         aFileName,
    2134             :                                                         NameClash::OVERWRITE,
    2135           0 :                                                         sMimeType );
    2136           0 :                     if( bSuccess )
    2137             :                     {
    2138           0 :                         pImp->m_aBackupURL = aDest.GetMainURL( INetURLObject::NO_DECODE );
    2139           0 :                         pImp->m_bRemoveBackup = false;
    2140           0 :                     }
    2141             :                 }
    2142           0 :                 catch ( const ::com::sun::star::uno::Exception& )
    2143             :                 {
    2144             :                 }
    2145           0 :             }
    2146           0 :         }
    2147             :     }
    2148             : 
    2149           0 :     if ( !bSuccess )
    2150             :     {
    2151           0 :         pImp->m_eError = ERRCODE_SFX_CANTCREATEBACKUP;
    2152           0 :     }
    2153             : }
    2154             : 
    2155             : 
    2156       14218 : void SfxMedium::ClearBackup_Impl()
    2157             : {
    2158       14218 :     if( pImp->m_bRemoveBackup )
    2159             :     {
    2160             :         // currently a document is always stored in a new medium,
    2161             :         // thus if a backup can not be removed the backup URL should not be cleaned
    2162         819 :         if ( !pImp->m_aBackupURL.isEmpty() )
    2163             :         {
    2164         819 :             if ( ::utl::UCBContentHelper::Kill( pImp->m_aBackupURL ) )
    2165             :             {
    2166         819 :                 pImp->m_bRemoveBackup = false;
    2167         819 :                 pImp->m_aBackupURL.clear();
    2168             :             }
    2169             :             else
    2170             :             {
    2171             : 
    2172             :                 SAL_WARN( "sfx.doc", "Couldn't remove backup file!");
    2173             :             }
    2174             :         }
    2175             :     }
    2176             :     else
    2177       13399 :         pImp->m_aBackupURL.clear();
    2178       14218 : }
    2179             : 
    2180             : 
    2181          29 : void SfxMedium::GetLockingStream_Impl()
    2182             : {
    2183          87 :     if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
    2184          87 :       && !pImp->m_xLockingStream.is() )
    2185             :     {
    2186          26 :         SFX_ITEMSET_ARG( pImp->m_pSet, pWriteStreamItem, SfxUnoAnyItem, SID_STREAM, false);
    2187          26 :         if ( pWriteStreamItem )
    2188          22 :             pWriteStreamItem->GetValue() >>= pImp->m_xLockingStream;
    2189             : 
    2190          26 :         if ( !pImp->m_xLockingStream.is() )
    2191             :         {
    2192             :             // open the original document
    2193           4 :             uno::Sequence< beans::PropertyValue > xProps;
    2194           4 :             TransformItems( SID_OPENDOC, *GetItemSet(), xProps );
    2195           8 :             utl::MediaDescriptor aMedium( xProps );
    2196             : 
    2197           4 :             aMedium.addInputStreamOwnLock();
    2198             : 
    2199           8 :             uno::Reference< io::XInputStream > xInputStream;
    2200           4 :             aMedium[utl::MediaDescriptor::PROP_STREAM()] >>= pImp->m_xLockingStream;
    2201           4 :             aMedium[utl::MediaDescriptor::PROP_INPUTSTREAM()] >>= xInputStream;
    2202             : 
    2203           4 :             if ( !pImp->pTempFile && pImp->m_aName.isEmpty() )
    2204             :             {
    2205             :                 // the medium is still based on the original file, it makes sense to initialize the streams
    2206           0 :                 if ( pImp->m_xLockingStream.is() )
    2207           0 :                     pImp->xStream = pImp->m_xLockingStream;
    2208             : 
    2209           0 :                 if ( xInputStream.is() )
    2210           0 :                     pImp->xInputStream = xInputStream;
    2211             : 
    2212           0 :                 if ( !pImp->xInputStream.is() && pImp->xStream.is() )
    2213           0 :                     pImp->xInputStream = pImp->xStream->getInputStream();
    2214           4 :             }
    2215             :         }
    2216             :     }
    2217          29 : }
    2218             : 
    2219             : 
    2220       15249 : void SfxMedium::GetMedium_Impl()
    2221             : {
    2222       15249 :     if ( !pImp->m_pInStream )
    2223             :     {
    2224       12286 :         pImp->bDownloadDone = false;
    2225       12286 :         Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = GetInteractionHandler();
    2226             : 
    2227             :         //TODO/MBA: need support for SID_STREAM
    2228       12286 :         SFX_ITEMSET_ARG( pImp->m_pSet, pWriteStreamItem, SfxUnoAnyItem, SID_STREAM, false);
    2229       12286 :         SFX_ITEMSET_ARG( pImp->m_pSet, pInStreamItem, SfxUnoAnyItem, SID_INPUTSTREAM, false);
    2230       12286 :         if ( pWriteStreamItem )
    2231             :         {
    2232          22 :             pWriteStreamItem->GetValue() >>= pImp->xStream;
    2233             : 
    2234          22 :             if ( pInStreamItem )
    2235          22 :                 pInStreamItem->GetValue() >>= pImp->xInputStream;
    2236             : 
    2237          22 :             if ( !pImp->xInputStream.is() && pImp->xStream.is() )
    2238           0 :                 pImp->xInputStream = pImp->xStream->getInputStream();
    2239             :         }
    2240       12264 :         else if ( pInStreamItem )
    2241             :         {
    2242        2827 :             pInStreamItem->GetValue() >>= pImp->xInputStream;
    2243             :         }
    2244             :         else
    2245             :         {
    2246        9437 :             uno::Sequence < beans::PropertyValue > xProps;
    2247       18874 :             OUString aFileName;
    2248        9437 :             if (!pImp->m_aName.isEmpty())
    2249             :             {
    2250        4434 :                 if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->m_aName, aFileName ) )
    2251             :                 {
    2252             :                     SAL_WARN( "sfx.doc", "Physical name not convertible!");
    2253             :                 }
    2254             :             }
    2255             :             else
    2256        5003 :                 aFileName = GetName();
    2257             : 
    2258             :             // in case the temporary file exists the streams should be initialized from it,
    2259             :             // but the original MediaDescriptor should not be changed
    2260        9437 :             bool bFromTempFile = ( pImp->pTempFile != NULL );
    2261             : 
    2262        9437 :             if ( !bFromTempFile )
    2263             :             {
    2264        6584 :                 GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, aFileName ) );
    2265        6584 :                 if( !(pImp->m_nStorOpenMode & StreamMode::WRITE) )
    2266        1535 :                     GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
    2267        6584 :                 if (xInteractionHandler.is())
    2268          15 :                     GetItemSet()->Put( SfxUnoAnyItem( SID_INTERACTIONHANDLER, makeAny(xInteractionHandler) ) );
    2269             :             }
    2270             : 
    2271        9437 :             if ( pImp->m_xInputStreamToLoadFrom.is() )
    2272             :             {
    2273        4994 :                 pImp->xInputStream = pImp->m_xInputStreamToLoadFrom;
    2274        4994 :                 pImp->xInputStream->skipBytes(0);
    2275        4994 :                 if (pImp->m_bInputStreamIsReadOnly)
    2276        4994 :                     GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
    2277             :             }
    2278             :             else
    2279             :             {
    2280        4443 :                 TransformItems( SID_OPENDOC, *GetItemSet(), xProps );
    2281        4443 :                 utl::MediaDescriptor aMedium( xProps );
    2282             : 
    2283        4443 :                 if ( pImp->m_xLockingStream.is() && !bFromTempFile )
    2284             :                 {
    2285             :                     // the medium is not based on the temporary file, so the original stream can be used
    2286           0 :                     pImp->xStream = pImp->m_xLockingStream;
    2287             :                 }
    2288             :                 else
    2289             :                 {
    2290        4443 :                     if ( bFromTempFile )
    2291             :                     {
    2292        2853 :                         aMedium[utl::MediaDescriptor::PROP_URL()] <<= OUString( aFileName );
    2293        2853 :                         aMedium.erase( utl::MediaDescriptor::PROP_READONLY() );
    2294        2853 :                         aMedium.addInputStream();
    2295             :                     }
    2296        1590 :                     else if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
    2297             :                     {
    2298             :                         // use the special locking approach only for file URLs
    2299        1581 :                         aMedium.addInputStreamOwnLock();
    2300             :                     }
    2301             :                     else
    2302           9 :                         aMedium.addInputStream();
    2303             : 
    2304             :                     // the ReadOnly property set in aMedium is ignored
    2305             :                     // the check is done in LockOrigFileOnDemand() for file and non-file URLs
    2306             : 
    2307             :                     //TODO/MBA: what happens if property is not there?!
    2308        4443 :                     aMedium[utl::MediaDescriptor::PROP_STREAM()] >>= pImp->xStream;
    2309        4443 :                     aMedium[utl::MediaDescriptor::PROP_INPUTSTREAM()] >>= pImp->xInputStream;
    2310             :                 }
    2311             : 
    2312        4443 :                 GetContent();
    2313        4443 :                 if ( !pImp->xInputStream.is() && pImp->xStream.is() )
    2314           0 :                     pImp->xInputStream = pImp->xStream->getInputStream();
    2315             :             }
    2316             : 
    2317        9437 :             if ( !bFromTempFile )
    2318             :             {
    2319             :                 //TODO/MBA: need support for SID_STREAM
    2320        6584 :                 if ( pImp->xStream.is() )
    2321           5 :                     GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM, makeAny( pImp->xStream ) ) );
    2322             : 
    2323        6584 :                 GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, makeAny( pImp->xInputStream ) ) );
    2324        9437 :             }
    2325             :         }
    2326             : 
    2327             :         //TODO/MBA: ErrorHandling - how to transport error from MediaDescriptor
    2328       12286 :         if ( !GetError() && !pImp->xStream.is() && !pImp->xInputStream.is() )
    2329         372 :             SetError( ERRCODE_IO_ACCESSDENIED, OUString( OSL_LOG_PREFIX  ) );
    2330             : 
    2331       12286 :         if ( !GetError() )
    2332             :         {
    2333       11550 :             if ( pImp->xStream.is() )
    2334        2874 :                 pImp->m_pInStream = utl::UcbStreamHelper::CreateStream( pImp->xStream );
    2335        8676 :             else if ( pImp->xInputStream.is() )
    2336        8676 :                 pImp->m_pInStream = utl::UcbStreamHelper::CreateStream( pImp->xInputStream );
    2337             :         }
    2338             : 
    2339       12286 :         pImp->bDownloadDone = true;
    2340       12286 :         pImp->aDoneLink.ClearPendingCall();
    2341       12286 :         sal_uIntPtr nError = GetError();
    2342       12286 :         pImp->aDoneLink.Call( reinterpret_cast<void*>(nError) );
    2343             :     }
    2344       15249 : }
    2345             : 
    2346        1857 : bool SfxMedium::IsRemote() const
    2347             : {
    2348        1857 :     return pImp->m_bRemote;
    2349             : }
    2350             : 
    2351        2491 : void SfxMedium::SetUpdatePickList(bool bVal)
    2352             : {
    2353        2491 :     pImp->bUpdatePickList = bVal;
    2354        2491 : }
    2355             : 
    2356        3195 : bool SfxMedium::IsUpdatePickList() const
    2357             : {
    2358        3195 :     return pImp->bUpdatePickList;
    2359             : }
    2360             : 
    2361           2 : void SfxMedium::SetLongName(const OUString &rName)
    2362             : {
    2363           2 :     pImp->m_aLongName = rName;
    2364           2 : }
    2365             : 
    2366           2 : const OUString& SfxMedium::GetLongName() const
    2367             : {
    2368           2 :     return pImp->m_aLongName;
    2369             : }
    2370             : 
    2371         543 : void SfxMedium::SetDoneLink( const Link<>& rLink )
    2372             : {
    2373         543 :     pImp->aDoneLink = rLink;
    2374         543 : }
    2375             : 
    2376         535 : void SfxMedium::Download( const Link<>& aLink )
    2377             : {
    2378         535 :     SetDoneLink( aLink );
    2379         535 :     GetInStream();
    2380         535 :     if ( pImp->m_pInStream && !aLink.IsSet() )
    2381             :     {
    2382        1034 :         while( !pImp->bDownloadDone )
    2383           0 :             Application::Yield();
    2384             :     }
    2385         535 : }
    2386             : 
    2387             : 
    2388       12469 : void SfxMedium::Init_Impl()
    2389             : /*  [Description]
    2390             :     Includes a valid:: sun:: com:: star:: util:: URL (If a file name was
    2391             :     previously in there) in the logical name and if available sets the
    2392             :     physical name as the file name.
    2393             :  */
    2394             : 
    2395             : {
    2396       12469 :     Reference< XOutputStream > rOutStream;
    2397             : 
    2398             :     // TODO/LATER: handle lifetime of storages
    2399       12469 :     pImp->bDisposeStorage = false;
    2400             : 
    2401       12469 :     SFX_ITEMSET_ARG( pImp->m_pSet, pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, false);
    2402       12469 :     if ( pSalvageItem && pSalvageItem->GetValue().isEmpty() )
    2403             :     {
    2404           0 :         pSalvageItem = NULL;
    2405           0 :         pImp->m_pSet->ClearItem( SID_DOC_SALVAGE );
    2406             :     }
    2407             : 
    2408       12469 :     if (!pImp->m_aLogicName.isEmpty())
    2409             :     {
    2410        4882 :         INetURLObject aUrl( pImp->m_aLogicName );
    2411        4882 :         INetProtocol eProt = aUrl.GetProtocol();
    2412        4882 :         if ( eProt == INetProtocol::NotValid )
    2413             :         {
    2414             :             SAL_WARN( "sfx.doc", "Unknown protocol!" );
    2415             :         }
    2416             :         else
    2417             :         {
    2418        4882 :             if ( aUrl.HasMark() )
    2419             :             {
    2420           0 :                 pImp->m_aLogicName = aUrl.GetURLNoMark( INetURLObject::NO_DECODE );
    2421           0 :                 GetItemSet()->Put( SfxStringItem( SID_JUMPMARK, aUrl.GetMark() ) );
    2422             :             }
    2423             : 
    2424             :             // try to convert the URL into a physical name - but never change a physical name
    2425             :             // physical name may be set if the logical name is changed after construction
    2426        4882 :             if ( pImp->m_aName.isEmpty() )
    2427        4882 :                 ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), pImp->m_aName );
    2428             :             else
    2429             :             {
    2430             :                 DBG_ASSERT( pSalvageItem, "Suspicious change of logical name!" );
    2431             :             }
    2432        4882 :         }
    2433             :     }
    2434             : 
    2435       12469 :     if ( pSalvageItem && !pSalvageItem->GetValue().isEmpty() )
    2436             :     {
    2437           0 :         pImp->m_aLogicName = pSalvageItem->GetValue();
    2438           0 :         DELETEZ( pImp->m_pURLObj );
    2439           0 :         pImp->m_bSalvageMode = true;
    2440             :     }
    2441             : 
    2442             :     // in case output stream is by mistake here
    2443             :     // clear the reference
    2444       12469 :     SFX_ITEMSET_ARG( pImp->m_pSet, pOutStreamItem, SfxUnoAnyItem, SID_OUTPUTSTREAM, false);
    2445       37405 :     if( pOutStreamItem
    2446       24940 :      && ( !( pOutStreamItem->GetValue() >>= rOutStream )
    2447           2 :           || !pImp->m_aLogicName.startsWith("private:stream")) )
    2448             :     {
    2449           0 :         pImp->m_pSet->ClearItem( SID_OUTPUTSTREAM );
    2450             :         SAL_WARN( "sfx.doc", "Unexpected Output stream parameter!\n" );
    2451             :     }
    2452             : 
    2453       12469 :     if (!pImp->m_aLogicName.isEmpty())
    2454             :     {
    2455             :         // if the logic name is set it should be set in MediaDescriptor as well
    2456        4882 :         SFX_ITEMSET_ARG( pImp->m_pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, false );
    2457        4882 :         if ( !pFileNameItem )
    2458             :         {
    2459             :             // let the ItemSet be created if necessary
    2460             :             GetItemSet()->Put(
    2461             :                 SfxStringItem(
    2462        1685 :                     SID_FILE_NAME, INetURLObject( pImp->m_aLogicName ).GetMainURL( INetURLObject::NO_DECODE ) ) );
    2463             :         }
    2464             :     }
    2465             : 
    2466       12469 :     SetIsRemote_Impl();
    2467             : 
    2468       24938 :     osl::DirectoryItem item;
    2469       12469 :     if (osl::DirectoryItem::get(GetName(), item) == osl::FileBase::E_None) {
    2470        4477 :         osl::FileStatus stat(osl_FileStatus_Mask_Attributes);
    2471        8954 :         if (item.getFileStatus(stat) == osl::FileBase::E_None
    2472        4477 :             && stat.isValid(osl_FileStatus_Mask_Attributes))
    2473             :         {
    2474        4477 :             if ((stat.getAttributes() & osl_File_Attribute_ReadOnly) != 0) {
    2475           0 :                 pImp->m_bOriginallyReadOnly = true;
    2476             :             }
    2477        4477 :         }
    2478       12469 :     }
    2479       12469 : }
    2480             : 
    2481             : 
    2482        6344 : SfxMedium::SfxMedium() : pImp(new SfxMedium_Impl(this))
    2483             : {
    2484        6344 :     Init_Impl();
    2485        6344 : }
    2486             : 
    2487             : 
    2488             : 
    2489        5247 : void SfxMedium::UseInteractionHandler( bool bUse )
    2490             : {
    2491        5247 :     pImp->bAllowDefaultIntHdl = bUse;
    2492        5247 : }
    2493             : 
    2494             : 
    2495             : 
    2496             : ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >
    2497       22486 : SfxMedium::GetInteractionHandler()
    2498             : {
    2499             :     // if interaction isn't allowed explicitly ... return empty reference!
    2500       22486 :     if ( !pImp->bUseInteractionHandler )
    2501          11 :         return ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >();
    2502             : 
    2503             :     // search a possible existing handler inside cached item set
    2504       22475 :     if ( pImp->m_pSet )
    2505             :     {
    2506       17481 :         ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > xHandler;
    2507       17481 :         SFX_ITEMSET_ARG( pImp->m_pSet, pHandler, SfxUnoAnyItem, SID_INTERACTIONHANDLER, false);
    2508       17481 :         if ( pHandler && (pHandler->GetValue() >>= xHandler) && xHandler.is() )
    2509       14291 :             return xHandler;
    2510             :     }
    2511             : 
    2512             :     // if default interaction isn't allowed explicitly ... return empty reference!
    2513        8184 :     if ( !pImp->bAllowDefaultIntHdl )
    2514        8180 :         return ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >();
    2515             : 
    2516             :     // otherwise return cached default handler ... if it exist.
    2517           4 :     if ( pImp->xInteraction.is() )
    2518           0 :         return pImp->xInteraction;
    2519             : 
    2520             :     // create default handler and cache it!
    2521           4 :     Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    2522             :     pImp->xInteraction.set(
    2523           4 :         task::InteractionHandler::createWithParent(xContext, 0), UNO_QUERY_THROW );
    2524           4 :     return pImp->xInteraction;
    2525             : }
    2526             : 
    2527             : 
    2528             : 
    2529        4697 : void SfxMedium::SetFilter( const SfxFilter* pFilterP, bool /*bResetOrig*/ )
    2530             : {
    2531        4697 :     pImp->m_pFilter = pFilterP;
    2532        4697 : }
    2533             : 
    2534    75562109 : const SfxFilter* SfxMedium::GetFilter() const
    2535             : {
    2536    75562109 :     return pImp->m_pFilter;
    2537             : }
    2538             : 
    2539             : 
    2540             : 
    2541        9536 : const SfxFilter* SfxMedium::GetOrigFilter( bool bNotCurrent ) const
    2542             : {
    2543        9536 :     return ( pImp->pOrigFilter || bNotCurrent ) ? pImp->pOrigFilter : pImp->m_pFilter;
    2544             : }
    2545             : 
    2546             : 
    2547             : 
    2548           0 : sal_uInt32 SfxMedium::CreatePasswordToModifyHash( const OUString& aPasswd, bool bWriter )
    2549             : {
    2550           0 :     sal_uInt32 nHash = 0;
    2551             : 
    2552           0 :     if ( !aPasswd.isEmpty() )
    2553             :     {
    2554           0 :         if ( bWriter )
    2555             :         {
    2556           0 :             nHash = ::comphelper::DocPasswordHelper::GetWordHashAsUINT32( aPasswd );
    2557             :         }
    2558             :         else
    2559             :         {
    2560           0 :             rtl_TextEncoding nEncoding = osl_getThreadTextEncoding();
    2561           0 :             nHash = ::comphelper::DocPasswordHelper::GetXLHashAsUINT16( aPasswd, nEncoding );
    2562             :         }
    2563             :     }
    2564             : 
    2565           0 :     return nHash;
    2566             : }
    2567             : 
    2568             : 
    2569             : 
    2570       12361 : void SfxMedium::Close()
    2571             : {
    2572       12361 :     if ( pImp->xStorage.is() )
    2573             :     {
    2574        1215 :         CloseStorage();
    2575             :     }
    2576             : 
    2577       12361 :     CloseStreams_Impl();
    2578             : 
    2579       12361 :     UnlockFile( false );
    2580       12361 : }
    2581             : 
    2582         833 : void SfxMedium::CloseAndRelease()
    2583             : {
    2584         833 :     if ( pImp->xStorage.is() )
    2585             :     {
    2586           2 :         CloseStorage();
    2587             :     }
    2588             : 
    2589         833 :     CloseAndReleaseStreams_Impl();
    2590             : 
    2591         833 :     UnlockFile( true );
    2592         833 : }
    2593             : 
    2594       13194 : void SfxMedium::UnlockFile( bool bReleaseLockStream )
    2595             : {
    2596             : #if !HAVE_FEATURE_MULTIUSER_ENVIRONMENT
    2597             :     (void) bReleaseLockStream;
    2598             : #else
    2599       13194 :     if ( pImp->m_xLockingStream.is() )
    2600             :     {
    2601          23 :         if ( bReleaseLockStream )
    2602             :         {
    2603             :             try
    2604             :             {
    2605           0 :                 uno::Reference< io::XInputStream > xInStream = pImp->m_xLockingStream->getInputStream();
    2606           0 :                 uno::Reference< io::XOutputStream > xOutStream = pImp->m_xLockingStream->getOutputStream();
    2607           0 :                 if ( xInStream.is() )
    2608           0 :                     xInStream->closeInput();
    2609           0 :                 if ( xOutStream.is() )
    2610           0 :                     xOutStream->closeOutput();
    2611             :             }
    2612           0 :             catch( const uno::Exception& )
    2613             :             {}
    2614             :         }
    2615             : 
    2616          23 :         pImp->m_xLockingStream.clear();
    2617             :     }
    2618             : 
    2619       13194 :     if ( pImp->m_bLocked )
    2620             :     {
    2621             :         try
    2622             :         {
    2623          31 :             pImp->m_bLocked = false;
    2624          31 :             ::svt::DocumentLockFile aLockFile( pImp->m_aLogicName );
    2625             :             // TODO/LATER: A warning could be shown in case the file is not the own one
    2626          31 :             aLockFile.RemoveFile();
    2627             :         }
    2628           0 :         catch( const uno::Exception& )
    2629             :         {}
    2630             :     }
    2631             : #endif
    2632       13194 : }
    2633             : 
    2634        5137 : void SfxMedium::CloseAndReleaseStreams_Impl()
    2635             : {
    2636        5137 :     CloseZipStorage_Impl();
    2637             : 
    2638        5137 :     uno::Reference< io::XInputStream > xInToClose = pImp->xInputStream;
    2639       10274 :     uno::Reference< io::XOutputStream > xOutToClose;
    2640        5137 :     if ( pImp->xStream.is() )
    2641             :     {
    2642        2643 :         xOutToClose = pImp->xStream->getOutputStream();
    2643             : 
    2644             :         // if the locking stream is closed here the related member should be cleaned
    2645        2643 :         if ( pImp->xStream == pImp->m_xLockingStream )
    2646           2 :             pImp->m_xLockingStream.clear();
    2647             :     }
    2648             : 
    2649             :     // The probably exsisting SvStream wrappers should be closed first
    2650        5137 :     CloseStreams_Impl();
    2651             : 
    2652             :     // in case of salvage mode the storage is based on the streams
    2653        5137 :     if ( !pImp->m_bSalvageMode )
    2654             :     {
    2655             :         try
    2656             :         {
    2657        5137 :             if ( xInToClose.is() )
    2658        2725 :                 xInToClose->closeInput();
    2659        5137 :             if ( xOutToClose.is() )
    2660        2643 :                 xOutToClose->closeOutput();
    2661             :         }
    2662           0 :         catch ( const uno::Exception& )
    2663             :         {
    2664             :         }
    2665        5137 :     }
    2666        5137 : }
    2667             : 
    2668             : 
    2669       18336 : void SfxMedium::CloseStreams_Impl()
    2670             : {
    2671       18336 :     CloseInStream_Impl();
    2672       18336 :     CloseOutStream_Impl();
    2673             : 
    2674       18336 :     if ( pImp->m_pSet )
    2675       18054 :         pImp->m_pSet->ClearItem( SID_CONTENT );
    2676             : 
    2677       18336 :     pImp->aContent = ::ucbhelper::Content();
    2678       18336 : }
    2679             : 
    2680             : 
    2681             : 
    2682       12469 : void SfxMedium::SetIsRemote_Impl()
    2683             : {
    2684       12469 :     INetURLObject aObj( GetName() );
    2685       12469 :     switch( aObj.GetProtocol() )
    2686             :     {
    2687             :         case INetProtocol::Ftp:
    2688             :         case INetProtocol::Http:
    2689             :         case INetProtocol::Https:
    2690           8 :             pImp->m_bRemote = true;
    2691           8 :         break;
    2692             :         default:
    2693       12461 :             pImp->m_bRemote = GetName().startsWith("private:msgid");
    2694       12461 :             break;
    2695             :     }
    2696             : 
    2697             :     // As files that are written to the remote transmission must also be able
    2698             :     // to be read.
    2699       12469 :     if (pImp->m_bRemote)
    2700           8 :         pImp->m_nStorOpenMode |= StreamMode::READ;
    2701       12469 : }
    2702             : 
    2703             : 
    2704             : 
    2705          49 : void SfxMedium::SetName( const OUString& aNameP, bool bSetOrigURL )
    2706             : {
    2707          49 :     if (pImp->aOrigURL.isEmpty())
    2708          49 :         pImp->aOrigURL = pImp->m_aLogicName;
    2709          49 :     if( bSetOrigURL )
    2710          49 :         pImp->aOrigURL = aNameP;
    2711          49 :     pImp->m_aLogicName = aNameP;
    2712          49 :     DELETEZ( pImp->m_pURLObj );
    2713          49 :     pImp->aContent = ::ucbhelper::Content();
    2714          49 :     Init_Impl();
    2715          49 : }
    2716             : 
    2717             : 
    2718       16797 : const OUString& SfxMedium::GetOrigURL() const
    2719             : {
    2720       16797 :     return pImp->aOrigURL.isEmpty() ? pImp->m_aLogicName : pImp->aOrigURL;
    2721             : }
    2722             : 
    2723             : 
    2724             : 
    2725           0 : void SfxMedium::SetPhysicalName_Impl( const OUString& rNameP )
    2726             : {
    2727           0 :     if ( rNameP != pImp->m_aName )
    2728             :     {
    2729           0 :         if( pImp->pTempFile )
    2730             :         {
    2731           0 :             delete pImp->pTempFile;
    2732           0 :             pImp->pTempFile = NULL;
    2733             :         }
    2734             : 
    2735           0 :         if ( !pImp->m_aName.isEmpty() || !rNameP.isEmpty() )
    2736           0 :             pImp->aContent = ::ucbhelper::Content();
    2737             : 
    2738           0 :         pImp->m_aName = rNameP;
    2739           0 :         pImp->m_bTriedStorage = false;
    2740           0 :         pImp->bIsStorage = false;
    2741             :     }
    2742           0 : }
    2743             : 
    2744             : 
    2745             : 
    2746         561 : void SfxMedium::ReOpen()
    2747             : {
    2748         561 :     bool bUseInteractionHandler = pImp->bUseInteractionHandler;
    2749         561 :     pImp->bUseInteractionHandler = false;
    2750         561 :     GetMedium_Impl();
    2751         561 :     pImp->bUseInteractionHandler = bUseInteractionHandler;
    2752         561 : }
    2753             : 
    2754             : 
    2755             : 
    2756           0 : void SfxMedium::CompleteReOpen()
    2757             : {
    2758             :     // do not use temporary file for reopen and in case of success throw the temporary file away
    2759           0 :     bool bUseInteractionHandler = pImp->bUseInteractionHandler;
    2760           0 :     pImp->bUseInteractionHandler = false;
    2761             : 
    2762           0 :     ::utl::TempFile* pTmpFile = NULL;
    2763           0 :     if ( pImp->pTempFile )
    2764             :     {
    2765           0 :         pTmpFile = pImp->pTempFile;
    2766           0 :         pImp->pTempFile = NULL;
    2767           0 :         pImp->m_aName.clear();
    2768             :     }
    2769             : 
    2770           0 :     GetMedium_Impl();
    2771             : 
    2772           0 :     if ( GetError() )
    2773             :     {
    2774           0 :         if ( pImp->pTempFile )
    2775             :         {
    2776           0 :             pImp->pTempFile->EnableKillingFile( true );
    2777           0 :             delete pImp->pTempFile;
    2778             :         }
    2779           0 :         pImp->pTempFile = pTmpFile;
    2780           0 :         if ( pImp->pTempFile )
    2781           0 :             pImp->m_aName = pImp->pTempFile->GetFileName();
    2782             :     }
    2783           0 :     else if (pTmpFile)
    2784             :     {
    2785           0 :         pTmpFile->EnableKillingFile( true );
    2786           0 :         delete pTmpFile;
    2787             : 
    2788             :     }
    2789             : 
    2790           0 :     pImp->bUseInteractionHandler = bUseInteractionHandler;
    2791           0 : }
    2792             : 
    2793        1866 : SfxMedium::SfxMedium(const OUString &rName, StreamMode nOpenMode, const SfxFilter *pFlt, SfxItemSet *pInSet) :
    2794        1866 :     pImp(new SfxMedium_Impl(this))
    2795             : {
    2796        1866 :     pImp->m_pSet = pInSet;
    2797        1866 :     pImp->m_pFilter = pFlt;
    2798        1866 :     pImp->m_aLogicName = rName;
    2799        1866 :     pImp->m_nStorOpenMode = nOpenMode;
    2800        1866 :     Init_Impl();
    2801        1866 : }
    2802             : 
    2803         522 : SfxMedium::SfxMedium(const OUString &rName, const OUString &rReferer, StreamMode nOpenMode, const SfxFilter *pFlt, SfxItemSet *pInSet) :
    2804         522 :     pImp(new SfxMedium_Impl(this))
    2805             : {
    2806         522 :     pImp->m_pSet = pInSet;
    2807         522 :     SfxItemSet * s = GetItemSet();
    2808         522 :     if (s->GetItem(SID_REFERER) == 0) {
    2809         522 :         s->Put(SfxStringItem(SID_REFERER, rReferer));
    2810             :     }
    2811         522 :     pImp->m_pFilter = pFlt;
    2812         522 :     pImp->m_aLogicName = rName;
    2813         522 :     pImp->m_nStorOpenMode = nOpenMode;
    2814         522 :     Init_Impl();
    2815         522 : }
    2816             : 
    2817        2495 : SfxMedium::SfxMedium( const uno::Sequence<beans::PropertyValue>& aArgs ) :
    2818        2495 :     pImp(new SfxMedium_Impl(this))
    2819             : {
    2820        2495 :     SfxAllItemSet *pParams = new SfxAllItemSet( SfxGetpApp()->GetPool() );
    2821        2495 :     pImp->m_pSet = pParams;
    2822        2495 :     TransformParameters( SID_OPENDOC, aArgs, *pParams );
    2823             : 
    2824        4990 :     OUString aFilterProvider, aFilterName;
    2825             :     {
    2826        2495 :         const SfxPoolItem* pItem = NULL;
    2827        2495 :         if (pImp->m_pSet->HasItem(SID_FILTER_PROVIDER, &pItem))
    2828           0 :             aFilterProvider = static_cast<const SfxStringItem*>(pItem)->GetValue();
    2829             : 
    2830        2495 :         if (pImp->m_pSet->HasItem(SID_FILTER_NAME, &pItem))
    2831        2491 :             aFilterName = static_cast<const SfxStringItem*>(pItem)->GetValue();
    2832             :     }
    2833             : 
    2834        2495 :     if (aFilterProvider.isEmpty())
    2835             :     {
    2836             :         // This is a conventional filter type.
    2837        2495 :         pImp->m_pFilter = SfxGetpApp()->GetFilterMatcher().GetFilter4FilterName( aFilterName );
    2838             :     }
    2839             :     else
    2840             :     {
    2841             :         // This filter is from an external provider such as orcus.
    2842           0 :         pImp->m_pCustomFilter.reset(new SfxFilter(aFilterProvider, aFilterName));
    2843           0 :         pImp->m_pFilter = pImp->m_pCustomFilter.get();
    2844             :     }
    2845             : 
    2846        2495 :     SFX_ITEMSET_ARG( pImp->m_pSet, pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, false );
    2847        2495 :     if( pSalvageItem )
    2848             :     {
    2849             :         // QUESTION: there is some treatment of Salvage in Init_Impl; align!
    2850           0 :         if ( !pSalvageItem->GetValue().isEmpty() )
    2851             :         {
    2852             :             // if an URL is provided in SalvageItem that means that the FileName refers to a temporary file
    2853             :             // that must be copied here
    2854             : 
    2855           0 :             SFX_ITEMSET_ARG( pImp->m_pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, false );
    2856           0 :             if (!pFileNameItem) throw uno::RuntimeException();
    2857           0 :             OUString aNewTempFileURL = SfxMedium::CreateTempCopyWithExt( pFileNameItem->GetValue() );
    2858           0 :             if ( !aNewTempFileURL.isEmpty() )
    2859             :             {
    2860           0 :                 pImp->m_pSet->Put( SfxStringItem( SID_FILE_NAME, aNewTempFileURL ) );
    2861           0 :                 pImp->m_pSet->ClearItem( SID_INPUTSTREAM );
    2862           0 :                 pImp->m_pSet->ClearItem( SID_STREAM );
    2863           0 :                 pImp->m_pSet->ClearItem( SID_CONTENT );
    2864             :             }
    2865             :             else
    2866             :             {
    2867             :                 SAL_WARN( "sfx.doc", "Can not create a new temporary file for crash recovery!\n" );
    2868           0 :             }
    2869             :         }
    2870             :     }
    2871             : 
    2872        2495 :     bool readOnly = false;
    2873        2495 :     SFX_ITEMSET_ARG( pImp->m_pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, false );
    2874        2495 :     if ( pReadOnlyItem && pReadOnlyItem->GetValue() )
    2875          11 :         readOnly = true;
    2876             : 
    2877        2495 :     SFX_ITEMSET_ARG( pImp->m_pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, false );
    2878        2495 :     if (!pFileNameItem) throw uno::RuntimeException();
    2879        2495 :     pImp->m_aLogicName = pFileNameItem->GetValue();
    2880        2495 :     pImp->m_nStorOpenMode = readOnly ? SFX_STREAM_READONLY : SFX_STREAM_READWRITE;
    2881        4990 :     Init_Impl();
    2882        2495 : }
    2883             : 
    2884             : 
    2885             : 
    2886             : 
    2887        1142 : SfxMedium::SfxMedium( const uno::Reference < embed::XStorage >& rStor, const OUString& rBaseURL, const SfxItemSet* p ) :
    2888        1142 :     pImp(new SfxMedium_Impl(this))
    2889             : {
    2890        1142 :     OUString aType = SfxFilter::GetTypeFromStorage(rStor);
    2891        1142 :     pImp->m_pFilter = SfxGetpApp()->GetFilterMatcher().GetFilter4EA( aType );
    2892             :     DBG_ASSERT( pImp->m_pFilter, "No Filter for storage found!" );
    2893             : 
    2894        1142 :     Init_Impl();
    2895        1142 :     pImp->xStorage = rStor;
    2896        1142 :     pImp->bDisposeStorage = false;
    2897             : 
    2898             :     // always take BaseURL first, could be overwritten by ItemSet
    2899        1142 :     GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL, rBaseURL ) );
    2900        1142 :     if ( p )
    2901         572 :         GetItemSet()->Put( *p );
    2902        1142 : }
    2903             : 
    2904             : 
    2905             : 
    2906           2 : SfxMedium::SfxMedium( const uno::Reference < embed::XStorage >& rStor, const OUString& rBaseURL, const OUString &rTypeName, const SfxItemSet* p ) :
    2907           2 :     pImp(new SfxMedium_Impl(this))
    2908             : {
    2909           2 :     pImp->m_pFilter = SfxGetpApp()->GetFilterMatcher().GetFilter4EA( rTypeName );
    2910             :     DBG_ASSERT( pImp->m_pFilter, "No Filter for storage found!" );
    2911             : 
    2912           2 :     Init_Impl();
    2913           2 :     pImp->xStorage = rStor;
    2914           2 :     pImp->bDisposeStorage = false;
    2915             : 
    2916             :     // always take BaseURL first, could be overwritten by ItemSet
    2917           2 :     GetItemSet()->Put( SfxStringItem( SID_DOC_BASEURL, rBaseURL ) );
    2918           2 :     if ( p )
    2919           0 :         GetItemSet()->Put( *p );
    2920           2 : }
    2921             : 
    2922             : 
    2923             : 
    2924       30338 : SfxMedium::~SfxMedium()
    2925             : {
    2926             :     // if there is a requirement to clean the backup this is the last possibility to do it
    2927       12352 :     ClearBackup_Impl();
    2928             : 
    2929       12352 :     Close();
    2930             : 
    2931       12352 :     if( pImp->bIsTemp && !pImp->m_aName.isEmpty() )
    2932             :     {
    2933           1 :         OUString aTemp;
    2934           1 :         if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->m_aName, aTemp ))
    2935             :         {
    2936             :             SAL_WARN( "sfx.doc", "Physical name not convertible!");
    2937             :         }
    2938             : 
    2939           1 :         if ( !::utl::UCBContentHelper::Kill( aTemp ) )
    2940             :         {
    2941             :             SAL_WARN( "sfx.doc", "Couldn't remove temporary file!");
    2942           1 :         }
    2943             :     }
    2944             : 
    2945       12352 :     delete pImp;
    2946       17986 : }
    2947             : 
    2948      126649 : const OUString& SfxMedium::GetName() const
    2949             : {
    2950      126649 :     return pImp->m_aLogicName;
    2951             : }
    2952             : 
    2953      150476 : const INetURLObject& SfxMedium::GetURLObject() const
    2954             : {
    2955      150476 :     if (!pImp->m_pURLObj)
    2956             :     {
    2957       10640 :         pImp->m_pURLObj = new INetURLObject( pImp->m_aLogicName );
    2958       10640 :         pImp->m_pURLObj->SetMark("");
    2959             :     }
    2960             : 
    2961      150476 :     return *pImp->m_pURLObj;
    2962             : }
    2963             : 
    2964           0 : void SfxMedium::SetExpired_Impl( const DateTime& rDateTime )
    2965             : {
    2966           0 :     pImp->aExpireTime = rDateTime;
    2967           0 : }
    2968             : 
    2969             : 
    2970           0 : bool SfxMedium::IsExpired() const
    2971             : {
    2972           0 :     return pImp->aExpireTime.IsValidAndGregorian() && pImp->aExpireTime < DateTime( DateTime::SYSTEM );
    2973             : }
    2974             : 
    2975             : 
    2976           1 : void SfxMedium::ForceSynchronStream_Impl( bool bForce )
    2977             : {
    2978           1 :     if( pImp->m_pInStream )
    2979             :     {
    2980           1 :         SvLockBytes* pBytes = pImp->m_pInStream->GetLockBytes();
    2981           1 :         if( pBytes )
    2982           1 :             pBytes->SetSynchronMode( bForce );
    2983             :     }
    2984           1 : }
    2985             : 
    2986             : 
    2987           0 : SfxFrame* SfxMedium::GetLoadTargetFrame() const
    2988             : {
    2989           0 :     return pImp->wLoadTargetFrame;
    2990             : }
    2991             : 
    2992        5005 : void SfxMedium::setStreamToLoadFrom(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream, bool bIsReadOnly )
    2993             : {
    2994        5005 :     pImp->m_xInputStreamToLoadFrom = xInputStream;
    2995        5005 :     pImp->m_bInputStreamIsReadOnly = bIsReadOnly;
    2996        5005 : }
    2997             : 
    2998           0 : void SfxMedium::SetLoadTargetFrame(SfxFrame* pFrame )
    2999             : {
    3000           0 :     pImp->wLoadTargetFrame = pFrame;
    3001           0 : }
    3002             : 
    3003             : 
    3004           4 : void SfxMedium::SetStorage_Impl( const uno::Reference < embed::XStorage >& rStor )
    3005             : {
    3006           4 :     pImp->xStorage = rStor;
    3007           4 : }
    3008             : 
    3009             : 
    3010      435811 : SfxItemSet* SfxMedium::GetItemSet() const
    3011             : {
    3012             :     // this method *must* return an ItemSet, returning NULL can cause crashes
    3013      435811 :     if (!pImp->m_pSet)
    3014        9024 :         pImp->m_pSet = new SfxAllItemSet( SfxGetpApp()->GetPool() );
    3015      435811 :     return pImp->m_pSet;
    3016             : }
    3017             : 
    3018             : 
    3019        2964 : SvKeyValueIterator* SfxMedium::GetHeaderAttributes_Impl()
    3020             : {
    3021        2964 :     if( !pImp->xAttributes.Is() )
    3022             :     {
    3023        2964 :         pImp->xAttributes = SvKeyValueIteratorRef( new SvKeyValueIterator );
    3024             : 
    3025        2964 :         if ( GetContent().is() )
    3026             :         {
    3027             :             try
    3028             :             {
    3029        2949 :                 Any aAny = pImp->aContent.getPropertyValue("MediaType");
    3030        5898 :                 OUString aContentType;
    3031        2949 :                 aAny >>= aContentType;
    3032             : 
    3033        5898 :                 pImp->xAttributes->Append( SvKeyValue( OUString("content-type"), aContentType ) );
    3034             :             }
    3035           0 :             catch ( const ::com::sun::star::uno::Exception& )
    3036             :             {
    3037             :             }
    3038             :         }
    3039             :     }
    3040             : 
    3041        2964 :     return pImp->xAttributes;
    3042             : }
    3043             : 
    3044         669 : ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >  SfxMedium::GetInputStream()
    3045             : {
    3046         669 :     if ( !pImp->xInputStream.is() )
    3047         390 :         GetMedium_Impl();
    3048         669 :     return pImp->xInputStream;
    3049             : }
    3050             : 
    3051        2471 : const uno::Sequence < util::RevisionTag >& SfxMedium::GetVersionList( bool _bNoReload )
    3052             : {
    3053             :     // if the medium has no name, then this medium should represent a new document and can have no version info
    3054        9884 :     if ( ( !_bNoReload || !pImp->m_bVersionsAlreadyLoaded ) && !pImp->aVersions.getLength() &&
    3055       12355 :          ( !pImp->m_aName.isEmpty() || !pImp->m_aLogicName.isEmpty() ) && GetStorage().is() )
    3056             :     {
    3057             :         uno::Reference < document::XDocumentRevisionListPersistence > xReader =
    3058        2471 :                 document::DocumentRevisionListPersistence::create( comphelper::getProcessComponentContext() );
    3059             :         try
    3060             :         {
    3061        2471 :             pImp->aVersions = xReader->load( GetStorage() );
    3062             :         }
    3063           0 :         catch ( const uno::Exception& )
    3064             :         {
    3065        2471 :         }
    3066             :     }
    3067             : 
    3068        2471 :     if ( !pImp->m_bVersionsAlreadyLoaded )
    3069        2334 :         pImp->m_bVersionsAlreadyLoaded = true;
    3070             : 
    3071        2471 :     return pImp->aVersions;
    3072             : }
    3073             : 
    3074           0 : uno::Sequence < util::RevisionTag > SfxMedium::GetVersionList( const uno::Reference < embed::XStorage >& xStorage )
    3075             : {
    3076             :     uno::Reference < document::XDocumentRevisionListPersistence > xReader =
    3077           0 :         document::DocumentRevisionListPersistence::create( comphelper::getProcessComponentContext() );
    3078             :     try
    3079             :     {
    3080           0 :         return xReader->load( xStorage );
    3081             :     }
    3082           0 :     catch ( const uno::Exception& )
    3083             :     {
    3084             :     }
    3085             : 
    3086           0 :     return uno::Sequence < util::RevisionTag >();
    3087             : }
    3088             : 
    3089           0 : sal_uInt16 SfxMedium::AddVersion_Impl( util::RevisionTag& rRevision )
    3090             : {
    3091           0 :     if ( GetStorage().is() )
    3092             :     {
    3093             :         // To determine a unique name for the stream
    3094           0 :         std::vector<sal_uInt32> aLongs;
    3095           0 :         sal_Int32 nLength = pImp->aVersions.getLength();
    3096           0 :         for ( sal_Int32 m=0; m<nLength; m++ )
    3097             :         {
    3098           0 :             sal_uInt32 nVer = static_cast<sal_uInt32>( pImp->aVersions[m].Identifier.copy(7).toInt32());
    3099             :             size_t n;
    3100           0 :             for ( n=0; n<aLongs.size(); ++n )
    3101           0 :                 if ( nVer<aLongs[n] )
    3102           0 :                     break;
    3103             : 
    3104           0 :             aLongs.insert( aLongs.begin()+n, nVer );
    3105             :         }
    3106             : 
    3107             :         sal_uInt16 nKey;
    3108           0 :         for ( nKey=0; nKey<aLongs.size(); ++nKey )
    3109           0 :             if ( aLongs[nKey] > ( sal_uIntPtr ) nKey+1 )
    3110           0 :                 break;
    3111             : 
    3112           0 :         OUString aRevName = "Version" + OUString::number( nKey + 1 );
    3113           0 :         pImp->aVersions.realloc( nLength+1 );
    3114           0 :         rRevision.Identifier = aRevName;
    3115           0 :         pImp->aVersions[nLength] = rRevision;
    3116           0 :         return nKey;
    3117             :     }
    3118             : 
    3119           0 :     return 0;
    3120             : }
    3121             : 
    3122           0 : bool SfxMedium::RemoveVersion_Impl( const OUString& rName )
    3123             : {
    3124           0 :     if ( !pImp->aVersions.getLength() )
    3125           0 :         return false;
    3126             : 
    3127           0 :     sal_Int32 nLength = pImp->aVersions.getLength();
    3128           0 :     for ( sal_Int32 n=0; n<nLength; n++ )
    3129             :     {
    3130           0 :         if ( pImp->aVersions[n].Identifier == rName )
    3131             :         {
    3132           0 :             for ( sal_Int32 m=n; m<nLength-1; m++ )
    3133           0 :                 pImp->aVersions[m] = pImp->aVersions[m+1];
    3134           0 :             pImp->aVersions.realloc(nLength-1);
    3135           0 :             return true;
    3136             :         }
    3137             :     }
    3138             : 
    3139           0 :     return false;
    3140             : }
    3141             : 
    3142         831 : bool SfxMedium::TransferVersionList_Impl( SfxMedium& rMedium )
    3143             : {
    3144         831 :     if ( rMedium.pImp->aVersions.getLength() )
    3145             :     {
    3146           1 :         pImp->aVersions = rMedium.pImp->aVersions;
    3147           1 :         return true;
    3148             :     }
    3149             : 
    3150         830 :     return false;
    3151             : }
    3152             : 
    3153         101 : bool SfxMedium::SaveVersionList_Impl( bool /*bUseXML*/ )
    3154             : {
    3155         101 :     if ( GetStorage().is() )
    3156             :     {
    3157         101 :         if ( !pImp->aVersions.getLength() )
    3158         202 :             return true;
    3159             : 
    3160             :         uno::Reference < document::XDocumentRevisionListPersistence > xWriter =
    3161           0 :                  document::DocumentRevisionListPersistence::create( comphelper::getProcessComponentContext() );
    3162             :         try
    3163             :         {
    3164           0 :             xWriter->store( GetStorage(), pImp->aVersions );
    3165           0 :             return true;
    3166             :         }
    3167           0 :         catch ( const uno::Exception& )
    3168             :         {
    3169           0 :         }
    3170             :     }
    3171             : 
    3172           0 :     return false;
    3173             : }
    3174             : 
    3175       23131 : bool SfxMedium::IsReadOnly() const
    3176             : {
    3177             :     // a) ReadOnly filter can't produce read/write contents!
    3178       23131 :     bool bReadOnly = pImp->m_pFilter && (pImp->m_pFilter->GetFilterFlags() & SfxFilterFlags::OPENREADONLY);
    3179             : 
    3180             :     // b) if filter allow read/write contents .. check open mode of the storage
    3181       23131 :     if (!bReadOnly)
    3182       23131 :         bReadOnly = !( GetOpenMode() & StreamMode::WRITE );
    3183             : 
    3184             :     // c) the API can force the readonly state!
    3185       23131 :     if (!bReadOnly)
    3186             :     {
    3187       21375 :         SFX_ITEMSET_ARG( GetItemSet(), pItem, SfxBoolItem, SID_DOC_READONLY, false);
    3188       21375 :         if (pItem)
    3189          45 :             bReadOnly = pItem->GetValue();
    3190             :     }
    3191             : 
    3192       23131 :     return bReadOnly;
    3193             : }
    3194             : 
    3195           0 : bool SfxMedium::IsOriginallyReadOnly() const
    3196             : {
    3197           0 :     return pImp->m_bOriginallyReadOnly;
    3198             : }
    3199             : 
    3200             : 
    3201        2731 : bool SfxMedium::SetWritableForUserOnly( const OUString& aURL )
    3202             : {
    3203             :     // UCB does not allow to allow write access only for the user,
    3204             :     // use osl API
    3205        2731 :     bool bResult = false;
    3206             : 
    3207        2731 :     ::osl::DirectoryItem aDirItem;
    3208        2731 :     if ( ::osl::DirectoryItem::get( aURL, aDirItem ) == ::osl::FileBase::E_None )
    3209             :     {
    3210        2731 :         ::osl::FileStatus aFileStatus( osl_FileStatus_Mask_Attributes );
    3211        5462 :         if ( aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None
    3212        2731 :           && aFileStatus.isValid( osl_FileStatus_Mask_Attributes ) )
    3213             :         {
    3214        2731 :             sal_uInt64 nAttributes = aFileStatus.getAttributes();
    3215             : 
    3216             :             nAttributes &= ~(osl_File_Attribute_OwnWrite |
    3217             :                              osl_File_Attribute_GrpWrite |
    3218             :                              osl_File_Attribute_OthWrite |
    3219        2731 :                              osl_File_Attribute_ReadOnly);
    3220             :             nAttributes |=  (osl_File_Attribute_OwnWrite |
    3221        2731 :                              osl_File_Attribute_OwnRead);
    3222             : 
    3223        2731 :             bResult = ( osl::File::setAttributes( aURL, nAttributes ) == ::osl::FileBase::E_None );
    3224        2731 :         }
    3225             :     }
    3226             : 
    3227        2731 :     return bResult;
    3228             : }
    3229             : 
    3230             : 
    3231       13657 : void SfxMedium::CreateTempFile( bool bReplace )
    3232             : {
    3233       13657 :     if ( pImp->pTempFile )
    3234             :     {
    3235        5231 :         if ( !bReplace )
    3236       10460 :             return;
    3237             : 
    3238           1 :         DELETEZ( pImp->pTempFile );
    3239           1 :         pImp->m_aName.clear();
    3240             :     }
    3241             : 
    3242        8427 :     pImp->pTempFile = new ::utl::TempFile();
    3243        8427 :     pImp->pTempFile->EnableKillingFile( true );
    3244        8427 :     pImp->m_aName = pImp->pTempFile->GetFileName();
    3245        8427 :     OUString aTmpURL = pImp->pTempFile->GetURL();
    3246        8427 :     if ( pImp->m_aName.isEmpty() || aTmpURL.isEmpty() )
    3247             :     {
    3248           0 :         SetError( ERRCODE_IO_CANTWRITE, OUString( OSL_LOG_PREFIX  ) );
    3249           0 :         return;
    3250             :     }
    3251             : 
    3252        8427 :     if ( !(pImp->m_nStorOpenMode & StreamMode::TRUNC) )
    3253             :     {
    3254        7780 :         bool bTransferSuccess = false;
    3255             : 
    3256       31120 :         if ( GetContent().is()
    3257       15560 :           && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
    3258       33859 :           && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) )
    3259             :         {
    3260             :             // if there is already such a document, we should copy it
    3261             :             // if it is a file system use OS copy process
    3262             :             try
    3263             :             {
    3264        2733 :                 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
    3265        5466 :                 INetURLObject aTmpURLObj( aTmpURL );
    3266             :                 OUString aFileName = aTmpURLObj.getName( INetURLObject::LAST_SEGMENT,
    3267             :                                                                 true,
    3268        5466 :                                                                 INetURLObject::DECODE_WITH_CHARSET );
    3269        2733 :                 if ( !aFileName.isEmpty() && aTmpURLObj.removeSegment() )
    3270             :                 {
    3271        2733 :                     ::ucbhelper::Content aTargetContent( aTmpURLObj.GetMainURL( INetURLObject::NO_DECODE ), xComEnv, comphelper::getProcessComponentContext() );
    3272        5466 :                     OUString sMimeType = pImp->getFilterMimeType();
    3273        2735 :                     if ( aTargetContent.transferContent( pImp->aContent, ::ucbhelper::InsertOperation_COPY, aFileName, NameClash::OVERWRITE, sMimeType ) )
    3274             :                     {
    3275        2731 :                         SetWritableForUserOnly( aTmpURL );
    3276        2731 :                         bTransferSuccess = true;
    3277        2733 :                     }
    3278        2733 :                 }
    3279             :             }
    3280           2 :             catch( const uno::Exception& )
    3281             :             {}
    3282             : 
    3283        2733 :             if ( bTransferSuccess )
    3284             :             {
    3285        2731 :                 CloseOutStream();
    3286        2731 :                 CloseInStream();
    3287             :             }
    3288             :         }
    3289             : 
    3290        7780 :         if ( !bTransferSuccess && pImp->m_pInStream )
    3291             :         {
    3292             :             // the case when there is no URL-access available or this is a remote protocoll
    3293             :             // but there is an input stream
    3294        5041 :             GetOutStream();
    3295        5041 :             if ( pImp->m_pOutStream )
    3296             :             {
    3297        5041 :                 char        *pBuf = new char [8192];
    3298        5041 :                 sal_uInt32   nErr = ERRCODE_NONE;
    3299             : 
    3300        5041 :                 pImp->m_pInStream->Seek(0);
    3301        5041 :                 pImp->m_pOutStream->Seek(0);
    3302             : 
    3303      103135 :                 while( !pImp->m_pInStream->IsEof() && nErr == ERRCODE_NONE )
    3304             :                 {
    3305       93053 :                     sal_uInt32 nRead = pImp->m_pInStream->Read( pBuf, 8192 );
    3306       93053 :                     nErr = pImp->m_pInStream->GetError();
    3307       93053 :                     pImp->m_pOutStream->Write( pBuf, nRead );
    3308             :                 }
    3309             : 
    3310        5041 :                 bTransferSuccess = true;
    3311        5041 :                 delete[] pBuf;
    3312        5041 :                 CloseInStream();
    3313             :             }
    3314        5041 :             CloseOutStream_Impl();
    3315             :         }
    3316             :         else
    3317             :         {
    3318             :             // Quite strange design, but currently it is expected that in this case no transfer happens
    3319             :             // TODO/LATER: get rid of this inconsistent part of the call design
    3320        2739 :             bTransferSuccess = true;
    3321        2739 :             CloseInStream();
    3322             :         }
    3323             : 
    3324        7780 :         if ( !bTransferSuccess )
    3325             :         {
    3326           0 :             SetError( ERRCODE_IO_CANTWRITE, OUString( OSL_LOG_PREFIX  ) );
    3327           0 :             return;
    3328             :         }
    3329             :     }
    3330             : 
    3331        8427 :     CloseStorage();
    3332             : }
    3333             : 
    3334             : 
    3335         235 : void SfxMedium::CreateTempFileNoCopy()
    3336             : {
    3337             :     // this call always replaces the existing temporary file
    3338         235 :     if ( pImp->pTempFile )
    3339          47 :         delete pImp->pTempFile;
    3340             : 
    3341         235 :     pImp->pTempFile = new ::utl::TempFile();
    3342         235 :     pImp->pTempFile->EnableKillingFile( true );
    3343         235 :     pImp->m_aName = pImp->pTempFile->GetFileName();
    3344         235 :     if ( pImp->m_aName.isEmpty() )
    3345             :     {
    3346           0 :         SetError( ERRCODE_IO_CANTWRITE, OUString( OSL_LOG_PREFIX  ) );
    3347         235 :         return;
    3348             :     }
    3349             : 
    3350         235 :     CloseOutStream_Impl();
    3351         235 :     CloseStorage();
    3352             : }
    3353             : 
    3354           0 : bool SfxMedium::SignContents_Impl( bool bScriptingContent, const OUString& aODFVersion, bool bHasValidDocumentSignature )
    3355             : {
    3356           0 :     bool bChanges = false;
    3357             : 
    3358             :     // the medium should be closed to be able to sign, the caller is responsible to close it
    3359           0 :     if ( !IsOpen() && !GetError() )
    3360             :     {
    3361             :         // The component should know if there was a valid document signature, since
    3362             :         // it should show a warning in this case
    3363             :         uno::Reference< security::XDocumentDigitalSignatures > xSigner(
    3364             :             security::DocumentDigitalSignatures::createWithVersionAndValidSignature(
    3365           0 :                 comphelper::getProcessComponentContext(), aODFVersion, bHasValidDocumentSignature ) );
    3366             : 
    3367           0 :         uno::Reference< embed::XStorage > xWriteableZipStor;
    3368           0 :         if ( !IsReadOnly() )
    3369             :         {
    3370             :             // we can reuse the temporary file if there is one already
    3371           0 :             CreateTempFile( false );
    3372           0 :             GetMedium_Impl();
    3373             : 
    3374             :             try
    3375             :             {
    3376           0 :                 if ( !pImp->xStream.is() )
    3377           0 :                     throw uno::RuntimeException();
    3378             : 
    3379           0 :                 xWriteableZipStor = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream );
    3380           0 :                 if ( !xWriteableZipStor.is() )
    3381           0 :                     throw uno::RuntimeException();
    3382             : 
    3383           0 :                 uno::Reference< embed::XStorage > xMetaInf = xWriteableZipStor->openStorageElement(
    3384             :                                                 OUString( "META-INF"  ),
    3385           0 :                                                 embed::ElementModes::READWRITE );
    3386           0 :                 if ( !xMetaInf.is() )
    3387           0 :                     throw uno::RuntimeException();
    3388             : 
    3389           0 :                 if ( bScriptingContent )
    3390             :                 {
    3391             :                     // If the signature has already the document signature it will be removed
    3392             :                     // after the scripting signature is inserted.
    3393             :                     uno::Reference< io::XStream > xStream(
    3394           0 :                         xMetaInf->openStreamElement( xSigner->getScriptingContentSignatureDefaultStreamName(),
    3395           0 :                                                      embed::ElementModes::READWRITE ),
    3396           0 :                         uno::UNO_SET_THROW );
    3397             : 
    3398           0 :                     if ( xSigner->signScriptingContent( GetZipStorageToSign_Impl(), xStream ) )
    3399             :                     {
    3400             :                         // remove the document signature if any
    3401           0 :                         OUString aDocSigName = xSigner->getDocumentContentSignatureDefaultStreamName();
    3402           0 :                         if ( !aDocSigName.isEmpty() && xMetaInf->hasByName( aDocSigName ) )
    3403           0 :                             xMetaInf->removeElement( aDocSigName );
    3404             : 
    3405           0 :                         uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW );
    3406           0 :                         xTransact->commit();
    3407           0 :                         xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW );
    3408           0 :                         xTransact->commit();
    3409             : 
    3410             :                         // the temporary file has been written, commit it to the original file
    3411           0 :                         Commit();
    3412           0 :                         bChanges = true;
    3413           0 :                     }
    3414             :                 }
    3415             :                 else
    3416             :                 {
    3417             :                      uno::Reference< io::XStream > xStream(
    3418           0 :                         xMetaInf->openStreamElement( xSigner->getDocumentContentSignatureDefaultStreamName(),
    3419           0 :                                                      embed::ElementModes::READWRITE ),
    3420           0 :                         uno::UNO_SET_THROW );
    3421             : 
    3422           0 :                     if ( xSigner->signDocumentContent( GetZipStorageToSign_Impl(), xStream ) )
    3423             :                     {
    3424           0 :                         uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW );
    3425           0 :                         xTransact->commit();
    3426           0 :                         xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW );
    3427           0 :                         xTransact->commit();
    3428             : 
    3429             :                         // the temporary file has been written, commit it to the original file
    3430           0 :                         Commit();
    3431           0 :                         bChanges = true;
    3432           0 :                     }
    3433           0 :                 }
    3434             :             }
    3435           0 :             catch ( const uno::Exception& )
    3436             :             {
    3437             :                 SAL_WARN( "sfx.doc", "Couldn't use signing functionality!\n" );
    3438             :             }
    3439             : 
    3440           0 :             CloseAndRelease();
    3441             :         }
    3442             :         else
    3443             :         {
    3444             :             try
    3445             :             {
    3446           0 :                 if ( bScriptingContent )
    3447           0 :                     xSigner->showScriptingContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() );
    3448             :                 else
    3449           0 :                     xSigner->showDocumentContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() );
    3450             :             }
    3451           0 :             catch( const uno::Exception& )
    3452             :             {
    3453             :                 SAL_WARN( "sfx.doc", "Couldn't use signing functionality!\n" );
    3454             :             }
    3455             :         }
    3456             : 
    3457           0 :         ResetError();
    3458             :     }
    3459             : 
    3460           0 :     return bChanges;
    3461             : }
    3462             : 
    3463             : 
    3464         609 : SignatureState SfxMedium::GetCachedSignatureState_Impl()
    3465             : {
    3466         609 :     return pImp->m_nSignatureState;
    3467             : }
    3468             : 
    3469             : 
    3470         609 : void SfxMedium::SetCachedSignatureState_Impl( SignatureState nState )
    3471             : {
    3472         609 :     pImp->m_nSignatureState = nState;
    3473         609 : }
    3474             : 
    3475        5373 : bool SfxMedium::HasStorage_Impl() const
    3476             : {
    3477        5373 :     return pImp->xStorage.is();
    3478             : }
    3479             : 
    3480           0 : bool SfxMedium::IsOpen() const
    3481             : {
    3482           0 :     return pImp->m_pInStream || pImp->m_pOutStream || pImp->xStorage.is();
    3483             : }
    3484             : 
    3485           0 : OUString SfxMedium::CreateTempCopyWithExt( const OUString& aURL )
    3486             : {
    3487           0 :     OUString aResult;
    3488             : 
    3489           0 :     if ( !aURL.isEmpty() )
    3490             :     {
    3491           0 :         sal_Int32 nPrefixLen = aURL.lastIndexOf( '.' );
    3492           0 :         OUString aExt = ( nPrefixLen == -1 ) ? OUString() :  aURL.copy( nPrefixLen );
    3493             : 
    3494           0 :         OUString aNewTempFileURL = ::utl::TempFile( OUString(), true, &aExt ).GetURL();
    3495           0 :         if ( !aNewTempFileURL.isEmpty() )
    3496             :         {
    3497           0 :             INetURLObject aSource( aURL );
    3498           0 :             INetURLObject aDest( aNewTempFileURL );
    3499             :             OUString aFileName = aDest.getName( INetURLObject::LAST_SEGMENT,
    3500             :                                                         true,
    3501           0 :                                                         INetURLObject::DECODE_WITH_CHARSET );
    3502           0 :             if ( !aFileName.isEmpty() && aDest.removeSegment() )
    3503             :             {
    3504             :                 try
    3505             :                 {
    3506           0 :                     uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
    3507           0 :                     ::ucbhelper::Content aTargetContent( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv, comphelper::getProcessComponentContext() );
    3508           0 :                     ::ucbhelper::Content aSourceContent( aSource.GetMainURL( INetURLObject::NO_DECODE ), xComEnv, comphelper::getProcessComponentContext() );
    3509           0 :                     if ( aTargetContent.transferContent( aSourceContent,
    3510             :                                                         ::ucbhelper::InsertOperation_COPY,
    3511             :                                                         aFileName,
    3512           0 :                                                         NameClash::OVERWRITE ) )
    3513             :                     {
    3514             :                         // Success
    3515           0 :                         aResult = aNewTempFileURL;
    3516           0 :                     }
    3517             :                 }
    3518           0 :                 catch( const uno::Exception& )
    3519             :                 {}
    3520           0 :             }
    3521           0 :         }
    3522             :     }
    3523             : 
    3524           0 :     return aResult;
    3525             : }
    3526             : 
    3527           0 : bool SfxMedium::CallApproveHandler(const uno::Reference< task::XInteractionHandler >& xHandler, const uno::Any& rRequest, bool bAllowAbort)
    3528             : {
    3529           0 :     bool bResult = false;
    3530             : 
    3531           0 :     if ( xHandler.is() )
    3532             :     {
    3533             :         try
    3534             :         {
    3535           0 :             uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( bAllowAbort ? 2 : 1 );
    3536             : 
    3537           0 :             ::rtl::Reference< ::comphelper::OInteractionApprove > pApprove( new ::comphelper::OInteractionApprove );
    3538           0 :             aContinuations[ 0 ] = pApprove.get();
    3539             : 
    3540           0 :             if ( bAllowAbort )
    3541             :             {
    3542           0 :                 ::rtl::Reference< ::comphelper::OInteractionAbort > pAbort( new ::comphelper::OInteractionAbort );
    3543           0 :                 aContinuations[ 1 ] = pAbort.get();
    3544             :             }
    3545             : 
    3546           0 :             xHandler->handle(::framework::InteractionRequest::CreateRequest(rRequest, aContinuations));
    3547           0 :             bResult = pApprove->wasSelected();
    3548             :         }
    3549           0 :         catch( const Exception& )
    3550             :         {
    3551             :         }
    3552             :     }
    3553             : 
    3554           0 :     return bResult;
    3555             : }
    3556             : 
    3557           0 : OUString SfxMedium::SwitchDocumentToTempFile()
    3558             : {
    3559             :     // the method returns empty string in case of failure
    3560           0 :     OUString aResult;
    3561           0 :     OUString aOrigURL = pImp->m_aLogicName;
    3562             : 
    3563           0 :     if ( !aOrigURL.isEmpty() )
    3564             :     {
    3565           0 :         sal_Int32 nPrefixLen = aOrigURL.lastIndexOf( '.' );
    3566             :         OUString const aExt = (nPrefixLen == -1)
    3567             :                                 ? OUString()
    3568           0 :                                 : aOrigURL.copy(nPrefixLen);
    3569           0 :         OUString aNewURL = ::utl::TempFile( OUString(), true, &aExt ).GetURL();
    3570             : 
    3571             :         // TODO/LATER: In future the aLogicName should be set to shared folder URL
    3572             :         //             and a temporary file should be created. Transport_Impl should be impossible then.
    3573           0 :         if ( !aNewURL.isEmpty() )
    3574             :         {
    3575           0 :             uno::Reference< embed::XStorage > xStorage = GetStorage();
    3576           0 :             uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY );
    3577             : 
    3578           0 :             if ( xOptStorage.is() )
    3579             :             {
    3580             :                 // TODO/LATER: reuse the pImp->pTempFile if it already exists
    3581           0 :                 CanDisposeStorage_Impl( false );
    3582           0 :                 Close();
    3583           0 :                 SetPhysicalName_Impl( OUString() );
    3584           0 :                 SetName( aNewURL );
    3585             : 
    3586             :                 // remove the readonly state
    3587           0 :                 bool bWasReadonly = false;
    3588           0 :                 pImp->m_nStorOpenMode = SFX_STREAM_READWRITE;
    3589           0 :                 SFX_ITEMSET_ARG( pImp->m_pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, false );
    3590           0 :                 if ( pReadOnlyItem && pReadOnlyItem->GetValue() )
    3591           0 :                     bWasReadonly = true;
    3592           0 :                 GetItemSet()->ClearItem( SID_DOC_READONLY );
    3593             : 
    3594           0 :                 GetMedium_Impl();
    3595           0 :                 LockOrigFileOnDemand( false, false );
    3596           0 :                 CreateTempFile( true );
    3597           0 :                 GetMedium_Impl();
    3598             : 
    3599           0 :                 if ( pImp->xStream.is() )
    3600             :                 {
    3601             :                     try
    3602             :                     {
    3603           0 :                         xOptStorage->writeAndAttachToStream( pImp->xStream );
    3604           0 :                         pImp->xStorage = xStorage;
    3605           0 :                         aResult = aNewURL;
    3606             :                     }
    3607           0 :                     catch( const uno::Exception& )
    3608             :                     {}
    3609             :                 }
    3610             : 
    3611           0 :                 if ( aResult.isEmpty() )
    3612             :                 {
    3613           0 :                     Close();
    3614           0 :                     SetPhysicalName_Impl( OUString() );
    3615           0 :                     SetName( aOrigURL );
    3616           0 :                     if ( bWasReadonly )
    3617             :                     {
    3618             :                         // set the readonly state back
    3619           0 :                         pImp->m_nStorOpenMode = SFX_STREAM_READONLY;
    3620           0 :                         GetItemSet()->Put( SfxBoolItem(SID_DOC_READONLY, true));
    3621             :                     }
    3622           0 :                     GetMedium_Impl();
    3623           0 :                     pImp->xStorage = xStorage;
    3624             :                 }
    3625           0 :             }
    3626           0 :         }
    3627             :     }
    3628             : 
    3629           0 :     return aResult;
    3630             : }
    3631             : 
    3632           0 : bool SfxMedium::SwitchDocumentToFile( const OUString& aURL )
    3633             : {
    3634             :     // the method is only for storage based documents
    3635           0 :     bool bResult = false;
    3636           0 :     OUString aOrigURL = pImp->m_aLogicName;
    3637             : 
    3638           0 :     if ( !aURL.isEmpty() && !aOrigURL.isEmpty() )
    3639             :     {
    3640           0 :         uno::Reference< embed::XStorage > xStorage = GetStorage();
    3641           0 :         uno::Reference< embed::XOptimizedStorage > xOptStorage( xStorage, uno::UNO_QUERY );
    3642             : 
    3643           0 :         if ( xOptStorage.is() )
    3644             :         {
    3645             :             // TODO/LATER: reuse the pImp->pTempFile if it already exists
    3646           0 :             CanDisposeStorage_Impl( false );
    3647           0 :             Close();
    3648           0 :             SetPhysicalName_Impl( OUString() );
    3649           0 :             SetName( aURL );
    3650             : 
    3651             :             // open the temporary file based document
    3652           0 :             GetMedium_Impl();
    3653           0 :             LockOrigFileOnDemand( false, false );
    3654           0 :             CreateTempFile( true );
    3655           0 :             GetMedium_Impl();
    3656             : 
    3657           0 :             if ( pImp->xStream.is() )
    3658             :             {
    3659             :                 try
    3660             :                 {
    3661           0 :                     uno::Reference< io::XTruncate > xTruncate( pImp->xStream, uno::UNO_QUERY_THROW );
    3662           0 :                     if ( xTruncate.is() )
    3663           0 :                         xTruncate->truncate();
    3664             : 
    3665           0 :                     xOptStorage->writeAndAttachToStream( pImp->xStream );
    3666           0 :                     pImp->xStorage = xStorage;
    3667           0 :                     bResult = true;
    3668             :                 }
    3669           0 :                 catch( const uno::Exception& )
    3670             :                 {}
    3671             :             }
    3672             : 
    3673           0 :             if ( !bResult )
    3674             :             {
    3675           0 :                 Close();
    3676           0 :                 SetPhysicalName_Impl( OUString() );
    3677           0 :                 SetName( aOrigURL );
    3678           0 :                 GetMedium_Impl();
    3679           0 :                 pImp->xStorage = xStorage;
    3680             :             }
    3681           0 :         }
    3682             :     }
    3683             : 
    3684           0 :     return bResult;
    3685             : }
    3686             : 
    3687           6 : void SfxMedium::SetInCheckIn( bool bInCheckIn )
    3688             : {
    3689           6 :     pImp->m_bInCheckIn = bInCheckIn;
    3690           6 : }
    3691             : 
    3692         105 : bool SfxMedium::IsInCheckIn( )
    3693             : {
    3694         105 :     return pImp->m_bInCheckIn;
    3695             : }
    3696             : 
    3697             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11