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

Generated by: LCOV version 1.10