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

Generated by: LCOV version 1.10