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