xref: /aoo42x/main/sot/source/sdstor/storage.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_sot.hxx"
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
32 #include <com/sun/star/embed/XStorage.hpp>
33 #include <com/sun/star/embed/ElementModes.hpp>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 
36 #include <rtl/digest.h>
37 #include <osl/file.hxx>
38 #include <sot/stg.hxx>
39 #include <sot/storinfo.hxx>
40 #include <sot/storage.hxx>
41 #include <sot/formats.hxx>
42 #include <sot/exchange.hxx>
43 #include <unotools/ucbstreamhelper.hxx>
44 #ifndef _TOOLS_FSYS_HXX
45 #include <tools/fsys.hxx>
46 #endif
47 #include <tools/cachestr.hxx>
48 #include <tools/debug.hxx>
49 #include <tools/urlobj.hxx>
50 #include <unotools/localfilehelper.hxx>
51 #include <unotools/ucbhelper.hxx>
52 #include <comphelper/processfactory.hxx>
53 
54 #include "unostorageholder.hxx"
55 
56 using namespace ::com::sun::star;
57 
58 /************** class SotStorageStream ***********************************/
59 class SotStorageStreamFactory : public SotFactory
60 {
61 public:
62  		TYPEINFO();
63 		SotStorageStreamFactory( const SvGlobalName & rName,
64 					  		const String & rClassName,
65 					  		CreateInstanceType pCreateFuncP )
66 			: SotFactory( rName, rClassName, pCreateFuncP )
67 		{}
68 };
69 TYPEINIT1(SotStorageStreamFactory,SotFactory);
70 
71 
72 SO2_IMPL_BASIC_CLASS1_DLL(SotStorageStream,SotStorageStreamFactory,SotObject,
73 						SvGlobalName( 0xd7deb420, 0xf902, 0x11d0,
74 							0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
75 SO2_IMPL_INVARIANT(SotStorageStream)
76 
77 
78 void SotStorageStream::TestMemberObjRef( sal_Bool /*bFree*/ )
79 {
80 }
81 
82 #ifdef TEST_INVARIANT
83 void SotStorageStream::TestMemberInvariant( sal_Bool /*bPrint*/ )
84 {
85 }
86 #endif
87 
88 /************************************************************************
89 |*    SotStorageStream::SotStorageStream()
90 |*
91 |*    Beschreibung
92 *************************************************************************/
93 SvLockBytesRef MakeLockBytes_Impl( const String & rName, StreamMode nMode )
94 {
95 	SvLockBytesRef xLB;
96 	if( rName.Len() )
97 	{
98 		SvStream * pFileStm = new SvFileStream( rName, nMode );
99 		xLB = new SvLockBytes( pFileStm, sal_True );
100 	}
101 	else
102 	{
103 		SvStream * pCacheStm = new SvCacheStream();
104 		xLB = new SvLockBytes( pCacheStm, sal_True );
105 	}
106 	return xLB;
107 }
108 
109 SotStorageStream::SotStorageStream( const String & rName, StreamMode nMode,
110                                   StorageMode
111                                   #ifdef DBG_UTIL
112                                   nStorageMode
113                                   #endif
114                                   )
115 	: SvStream( MakeLockBytes_Impl( rName, nMode ) )
116     , pOwnStm( NULL )
117 {
118 	if( nMode & STREAM_WRITE )
119     	bIsWritable = sal_True;
120 	else
121     	bIsWritable = sal_False;
122 
123     DBG_ASSERT( !nStorageMode,"StorageModes ignored" );
124 }
125 
126 SotStorageStream::SotStorageStream( BaseStorageStream * pStm )
127 {
128 	if( pStm )
129 	{
130 		if( STREAM_WRITE & pStm->GetMode() )
131     		bIsWritable = sal_True;
132 		else
133     		bIsWritable = sal_False;
134 
135 		pOwnStm = pStm;
136     	SetError( pStm->GetError() );
137     	pStm->ResetError();
138 	}
139 	else
140 	{
141 		pOwnStm = NULL;
142     	bIsWritable = sal_True;
143 		SetError( SVSTREAM_INVALID_PARAMETER );
144 	}
145 }
146 
147 SotStorageStream::SotStorageStream()
148 	: pOwnStm( NULL )
149 {
150 	// ??? wenn Init virtuell ist, entsprechen setzen
151     bIsWritable = sal_True;
152 }
153 
154 /************************************************************************
155 |*    SotStorageStream::~SotStorageStream()
156 |*
157 |*    Beschreibung
158 *************************************************************************/
159 SotStorageStream::~SotStorageStream()
160 {
161     Flush(); //SetBufferSize(0);
162     delete pOwnStm;
163 }
164 
165 /*************************************************************************
166 |*    SotStorageStream::SyncSvStream()
167 |*
168 |*    Beschreibung: Der SvStream wird auf den Zustand des Standard-Streams
169 |*	  				gesetzt. Der Puffer des SvStreams wird weggeworfen.
170 *************************************************************************/
171 void SotStorageStream::SyncSvStream()
172 {
173 	sal_uLong nPos = 0;
174     if( pOwnStm )
175 	{
176         pOwnStm->Flush();
177 		nPos = pOwnStm->Tell();
178         SetError( pOwnStm->GetError() );
179 		SvStream::SyncSvStream( nPos );
180     }
181 }
182 
183 /*************************************************************************
184 |*    SotStorageStream::ResetError()
185 |*
186 |*    Beschreibung
187 *************************************************************************/
188 void SotStorageStream::ResetError()
189 {
190     SvStream::ResetError();
191 	if( pOwnStm )
192          pOwnStm->ResetError();
193 }
194 
195 /*************************************************************************
196 |*    SotStorageStream::GetData()
197 |*
198 |*    Beschreibung
199 *************************************************************************/
200 sal_uLong SotStorageStream::GetData( void* pData, sal_uLong nSize )
201 {
202     sal_uLong nRet = 0;
203 
204     if( pOwnStm )
205 	{
206         nRet = pOwnStm->Read( pData, nSize );
207         SetError( pOwnStm->GetError() );
208     }
209 	else
210 		nRet = SvStream::GetData( (sal_Char *)pData, nSize );
211     return nRet;
212 }
213 
214 /*************************************************************************
215 |*    SotStorageStream::PutData()
216 |*
217 |*    Beschreibung
218 *************************************************************************/
219 sal_uLong SotStorageStream::PutData( const void* pData, sal_uLong nSize )
220 {
221     sal_uLong nRet = 0;
222 
223     if( pOwnStm )
224 	{
225         nRet = pOwnStm->Write( pData, nSize );
226         SetError( pOwnStm->GetError() );
227     }
228 	else
229 		nRet = SvStream::PutData( (sal_Char *)pData, nSize );
230     return nRet;
231 }
232 
233 /*************************************************************************
234 |*    SotStorageStream::SeekPos()
235 |*
236 |*    Beschreibung
237 *************************************************************************/
238 sal_uLong SotStorageStream::SeekPos( sal_uLong nPos )
239 {
240     sal_uLong nRet = 0;
241 
242     if( pOwnStm )
243 	{
244         nRet = pOwnStm->Seek( nPos );
245         SetError( pOwnStm->GetError() );
246 	}
247 	else
248 		nRet = SvStream::SeekPos( nPos );
249     return nRet;
250 }
251 
252 /*************************************************************************
253 |*    SotStorageStream::Flush()
254 |*
255 |*    Beschreibung
256 *************************************************************************/
257 void SotStorageStream::FlushData()
258 {
259     if( pOwnStm )
260 	{
261         pOwnStm->Flush();
262         SetError( pOwnStm->GetError() );
263     }
264 	else
265 		SvStream::FlushData();
266 }
267 
268 /*************************************************************************
269 |*    SotStorageStream::SetSize()
270 |*
271 |*    Beschreibung
272 *************************************************************************/
273 void SotStorageStream::SetSize( sal_uLong nNewSize )
274 {
275     sal_uLong   nPos = Tell();
276     if( pOwnStm )
277     {
278         pOwnStm->SetSize( nNewSize );
279         SetError( pOwnStm->GetError() );
280     }
281     else
282 		SvStream::SetSize( nNewSize );
283 
284     if( nNewSize < nPos )
285         // ans Ende setzen
286         Seek( nNewSize );
287 
288     //return GetError() == SVSTREAM_OK;
289 }
290 
291 /*************************************************************************
292 |*
293 |*    SotStorageStream::GetSize()
294 |*
295 |*    Beschreibung
296 |*
297 *************************************************************************/
298 sal_uInt32 SotStorageStream::GetSize() const
299 {
300     sal_uLong nPos = Tell();
301     ((SotStorageStream *)this)->Seek( STREAM_SEEK_TO_END );
302     sal_uLong nSize = Tell();
303     ((SotStorageStream *)this)->Seek( nPos );
304     return nSize;
305 }
306 
307 /*************************************************************************
308 |*    SotStorageStream::CopyTo()
309 |*
310 |*    Beschreibung
311 *************************************************************************/
312 sal_Bool SotStorageStream::CopyTo( SotStorageStream * pDestStm )
313 {
314     Flush(); // alle Daten schreiben
315     pDestStm->ClearBuffer();
316 	if( !pOwnStm || !pDestStm->pOwnStm )
317     { // Wenn Ole2 oder nicht nur eigene StorageStreams
318 
319         sal_uLong nPos = Tell();    // Position merken
320 		Seek( 0L );
321         pDestStm->SetSize( 0 ); // Ziel-Stream leeren
322 
323         void * pMem = new sal_uInt8[ 8192 ];
324         sal_uLong  nRead;
325         while( 0 != (nRead = Read( pMem, 8192 )) )
326         {
327             if( nRead != pDestStm->Write( pMem, nRead ) )
328             {
329                 SetError( SVSTREAM_GENERALERROR );
330                 break;
331             }
332         }
333         delete [] static_cast<sal_uInt8*>(pMem);
334         // Position setzen
335         pDestStm->Seek( nPos );
336         Seek( nPos );
337     }
338     else
339     {
340         /*
341         // Kopieren
342         nErr = pObjI->CopyTo( pDestStm->pObjI, uSize, NULL, &uWrite );
343         if( SUCCEEDED( nErr ) )
344         {
345             // Ziel-Streamzeiger steht hinter den Daten
346             // SvSeek abgleichen
347             pDestStm->Seek( uWrite.LowPart );
348         }
349         else if( GetScode( nErr ) == E_NOTIMPL )
350         { // Eines Tages werden alle MS... ?!#
351         */
352         pOwnStm->CopyTo( pDestStm->pOwnStm );
353         SetError( pOwnStm->GetError() );
354     }
355     return GetError() == SVSTREAM_OK;
356 }
357 
358 /*************************************************************************
359 |*    SotStorageStream::Commit()
360 |*    SotStorageStream::Revert()
361 |*
362 |*    Beschreibung
363 *************************************************************************/
364 sal_Bool SotStorageStream::Commit()
365 {
366     if( pOwnStm )
367 	{
368 		pOwnStm->Flush();
369 		if( pOwnStm->GetError() == SVSTREAM_OK )
370 			pOwnStm->Commit();
371         SetError( pOwnStm->GetError() );
372     }
373     return GetError() == SVSTREAM_OK;
374 }
375 
376 sal_Bool SotStorageStream::Revert()
377 {
378     if( !pOwnStm )
379     {
380         pOwnStm->Revert();
381         SetError( pOwnStm->GetError() );
382     }
383     return GetError() == SVSTREAM_OK;
384 }
385 
386 sal_Bool SotStorageStream::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue )
387 {
388     UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm );
389     if ( pStg )
390     {
391         return pStg->SetProperty( rName, rValue );
392     }
393     else
394     {
395         DBG_ERROR("Not implemented!");
396         return sal_False;
397     }
398 }
399 
400 sal_Bool SotStorageStream::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue )
401 {
402     UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm );
403     if ( pStg )
404     {
405         return pStg->GetProperty( rName, rValue );
406     }
407 	else
408     {
409         DBG_ERROR("Not implemented!");
410         return sal_False;
411     }
412 }
413 
414 ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SotStorageStream::GetXInputStream() const
415 {
416     UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm );
417     if ( pStg )
418     {
419         return pStg->GetXInputStream();
420     }
421     else
422     {
423         DBG_ERROR("Not implemented!");
424         return ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >();
425     }
426 }
427 
428 
429 
430 /************** class SotStorage ******************************************
431 *************************************************************************/
432 class SotStorageFactory : public SotFactory
433 {
434 public:
435  		TYPEINFO();
436 		SotStorageFactory( const SvGlobalName & rName,
437 					  		const String & rClassName,
438 					  		CreateInstanceType pCreateFuncP )
439 			: SotFactory( rName, rClassName, pCreateFuncP )
440 		{}
441 };
442 TYPEINIT1(SotStorageFactory,SotFactory);
443 
444 
445 SO2_IMPL_BASIC_CLASS1_DLL(SotStorage,SotStorageFactory,SotObject,
446 						SvGlobalName( 0x980ce7e0, 0xf905, 0x11d0,
447 							0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
448 SO2_IMPL_INVARIANT(SotStorage)
449 
450 
451 /************************************************************************
452 |*
453 |*    SotStorage::Tes*()
454 |*
455 |*    Beschreibung
456 *************************************************************************/
457 void SotStorage::TestMemberObjRef( sal_Bool /*bFree*/ )
458 {
459 }
460 
461 #ifdef TEST_INVARIANT
462 void SotStorage::TestMemberInvariant( sal_Bool /*bPrint*/ )
463 {
464 }
465 #endif
466 
467 /************************************************************************
468 |*
469 |*    SotStorage::SotStorage()
470 |*
471 |*    Beschreibung      Es muss ein I... Objekt an SvObject uebergeben
472 |*                      werden, da es sonst selbst ein IUnknown anlegt und
473 |*                      festlegt, dass alle weiteren I... Objekte mit
474 |*                      delete zerstoert werden (Owner() == sal_True).
475 |*                      Es werden aber nur IStorage Objekte benutzt und nicht
476 |*                      selbst implementiert, deshalb wird so getan, als ob
477 |*                      das IStorage Objekt von aussen kam und es wird mit
478 |*                      Release() freigegeben.
479 |*                      Die CreateStorage Methoden werden benoetigt, um
480 |*                      ein IStorage Objekt vor dem Aufruf von SvObject
481 |*                      zu erzeugen (Own, !Own automatik).
482 |*                      Hat CreateStorage ein Objekt erzeugt, dann wurde
483 |*                      der RefCounter schon um 1 erhoet.
484 |*                      Die Uebergabe erfolgt in pStorageCTor. Die Variable
485 |*                      ist NULL, wenn es nicht geklappt hat.
486 |*    Ersterstellung    MM 23.06.94
487 |*    Letzte Aenderung  MM 23.06.94
488 |*
489 *************************************************************************/
490 #define INIT_SotStorage()            		\
491 	: m_pOwnStg( NULL )                       \
492     , m_pStorStm( NULL )                      \
493     , m_nError( SVSTREAM_OK )         		\
494 	, m_bIsRoot( sal_False )              		\
495     , m_bDelStm( sal_False )						\
496     , m_nVersion( SOFFICE_FILEFORMAT_CURRENT )
497 
498 SotStorage::SotStorage()
499     INIT_SotStorage()
500 {
501     // ??? What's this ???
502 }
503 
504 #define ERASEMASK  ( STREAM_TRUNC | STREAM_WRITE | STREAM_SHARE_DENYALL )
505 #include <com/sun/star/uno/Reference.h>
506 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
507 #include <ucbhelper/content.hxx>
508 
509 SotStorage::SotStorage( const ::ucbhelper::Content& rContent, const String & rName, StreamMode nMode, StorageMode nStorageMode )
510     INIT_SotStorage()
511 {
512     m_aName = rName; // Namen merken
513 	m_pOwnStg = new UCBStorage( rContent, m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
514 
515 	SetError( m_pOwnStg->GetError() );
516 
517     if ( IsOLEStorage() )
518         m_nVersion = SOFFICE_FILEFORMAT_50;
519 
520     SignAsRoot( m_pOwnStg->IsRoot() );
521 }
522 
523 SotStorage::SotStorage( const String & rName, StreamMode nMode, StorageMode nStorageMode )
524     INIT_SotStorage()
525 {
526     m_aName = rName; // Namen merken
527     CreateStorage( sal_True, nMode, nStorageMode );
528     if ( IsOLEStorage() )
529         m_nVersion = SOFFICE_FILEFORMAT_50;
530 }
531 
532 void SotStorage::CreateStorage( sal_Bool bForceUCBStorage, StreamMode nMode, StorageMode nStorageMode  )
533 {
534 	DBG_ASSERT( !m_pStorStm && !m_pOwnStg, "Use only in ctor!" );
535     if( m_aName.Len() )
536 	{
537         // named storage
538         if( ( ( nMode & ERASEMASK ) == ERASEMASK ) )
539             ::utl::UCBContentHelper::Kill( m_aName );
540 
541         INetURLObject aObj( m_aName );
542         if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
543         {
544             String aURL;
545             ::utl::LocalFileHelper::ConvertPhysicalNameToURL( m_aName, aURL );
546             aObj.SetURL( aURL );
547 			m_aName = aObj.GetMainURL( INetURLObject::NO_DECODE );
548         }
549 
550         // a new unpacked storage should be created
551         if ( nStorageMode == STORAGE_CREATE_UNPACKED )
552         {
553             // don't open stream readwrite, content provider may not support this !
554             String aURL = UCBStorage::CreateLinkFile( m_aName );
555             if ( aURL.Len() )
556             {
557                 ::ucbhelper::Content aContent( aURL, ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XCommandEnvironment >() );
558                 m_pOwnStg = new UCBStorage( aContent, aURL, nMode, sal_False );
559             }
560             else
561             {
562                 m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
563                 SetError( ERRCODE_IO_NOTSUPPORTED );
564             }
565         }
566         else
567         {
568             // check the stream
569             m_pStorStm = ::utl::UcbStreamHelper::CreateStream( m_aName, nMode );
570             if ( m_pStorStm && m_pStorStm->GetError() )
571                 DELETEZ( m_pStorStm );
572 
573             if ( m_pStorStm )
574             {
575                 // try as UCBStorage, next try as OLEStorage
576                 sal_Bool bIsUCBStorage = UCBStorage::IsStorageFile( m_pStorStm );
577                 if ( !bIsUCBStorage && bForceUCBStorage )
578                     // if UCBStorage has priority, it should not be used only if it is really an OLEStorage
579                     bIsUCBStorage = !Storage::IsStorageFile( m_pStorStm );
580 
581                 if ( bIsUCBStorage )
582                 {
583                     if ( UCBStorage::GetLinkedFile( *m_pStorStm ).Len() )
584                     {
585                         // detect special unpacked storages
586                         m_pOwnStg = new UCBStorage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
587                         m_bDelStm = sal_True;
588                     }
589                     else
590                     {
591                         // detect special disk spanned storages
592                         if ( UCBStorage::IsDiskSpannedFile( m_pStorStm ) )
593                             nMode |= STORAGE_DISKSPANNED_MODE;
594 
595                         // UCBStorage always works directly on the UCB content, so discard the stream first
596                         DELETEZ( m_pStorStm );
597                         m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
598                     }
599                 }
600                 else
601                 {
602                     // OLEStorage can be opened with a stream
603                     m_pOwnStg = new Storage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
604                     m_bDelStm = sal_True;
605                 }
606             }
607             else if ( bForceUCBStorage )
608             {
609                 m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
610                 SetError( ERRCODE_IO_NOTSUPPORTED );
611             }
612             else
613             {
614                 m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
615                 SetError( ERRCODE_IO_NOTSUPPORTED );
616             }
617         }
618     }
619     else
620     {
621         // temporary storage
622         if ( bForceUCBStorage )
623         	m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
624         else
625             m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
626 		m_aName = m_pOwnStg->GetName();
627     }
628 
629 	SetError( m_pOwnStg->GetError() );
630 
631     SignAsRoot( m_pOwnStg->IsRoot() );
632 }
633 
634 SotStorage::SotStorage( sal_Bool bUCBStorage, const String & rName, StreamMode nMode, StorageMode nStorageMode )
635     INIT_SotStorage()
636 {
637     m_aName = rName;
638 	CreateStorage( bUCBStorage, nMode, nStorageMode );
639     if ( IsOLEStorage() )
640         m_nVersion = SOFFICE_FILEFORMAT_50;
641 }
642 
643 SotStorage::SotStorage( BaseStorage * pStor )
644     INIT_SotStorage()
645 {
646     if ( pStor )
647     {
648         m_aName = pStor->GetName(); // Namen merken
649         SignAsRoot( pStor->IsRoot() );
650         SetError( pStor->GetError() );
651     }
652 
653     m_pOwnStg = pStor;
654     sal_uLong nErr = m_pOwnStg ? m_pOwnStg->GetError() : SVSTREAM_CANNOT_MAKE;
655 	SetError( nErr );
656     if ( IsOLEStorage() )
657         m_nVersion = SOFFICE_FILEFORMAT_50;
658 }
659 
660 SotStorage::SotStorage( sal_Bool bUCBStorage, SvStream & rStm )
661     INIT_SotStorage()
662 {
663     SetError( rStm.GetError() );
664 
665     // try as UCBStorage, next try as OLEStorage
666     if ( UCBStorage::IsStorageFile( &rStm ) || bUCBStorage )
667         m_pOwnStg = new UCBStorage( rStm, sal_False );
668     else
669         m_pOwnStg = new Storage( rStm, sal_False );
670 
671 	SetError( m_pOwnStg->GetError() );
672 
673     if ( IsOLEStorage() )
674         m_nVersion = SOFFICE_FILEFORMAT_50;
675 
676     SignAsRoot( m_pOwnStg->IsRoot() );
677 }
678 
679 SotStorage::SotStorage( SvStream & rStm )
680     INIT_SotStorage()
681 {
682     SetError( rStm.GetError() );
683 
684     // try as UCBStorage, next try as OLEStorage
685     if ( UCBStorage::IsStorageFile( &rStm ) )
686         m_pOwnStg = new UCBStorage( rStm, sal_False );
687     else
688         m_pOwnStg = new Storage( rStm, sal_False );
689 
690 	SetError( m_pOwnStg->GetError() );
691 
692     if ( IsOLEStorage() )
693         m_nVersion = SOFFICE_FILEFORMAT_50;
694 
695     SignAsRoot( m_pOwnStg->IsRoot() );
696 }
697 
698 SotStorage::SotStorage( SvStream * pStm, sal_Bool bDelete )
699     INIT_SotStorage()
700 {
701     SetError( pStm->GetError() );
702 
703     // try as UCBStorage, next try as OLEStorage
704     if ( UCBStorage::IsStorageFile( pStm ) )
705         m_pOwnStg = new UCBStorage( *pStm, sal_False );
706     else
707         m_pOwnStg = new Storage( *pStm, sal_False );
708 
709 	SetError( m_pOwnStg->GetError() );
710 
711 	m_pStorStm = pStm;
712 	m_bDelStm = bDelete;
713     if ( IsOLEStorage() )
714         m_nVersion = SOFFICE_FILEFORMAT_50;
715 
716     SignAsRoot( m_pOwnStg->IsRoot() );
717 }
718 
719 /*************************************************************************
720 |*    SotStorage::~SotStorage()
721 |*
722 |*    Beschreibung
723 *************************************************************************/
724 SotStorage::~SotStorage()
725 {
726     delete m_pOwnStg;
727     if( m_bDelStm )
728         delete m_pStorStm;
729 }
730 
731 /*************************************************************************
732 |*    SotStorage::RemoveUNOStorageHolder()
733 |*
734 |*    Beschreibung
735 *************************************************************************/
736 void SotStorage::RemoveUNOStorageHolder( UNOStorageHolder* pHolder )
737 {
738     UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
739     if ( pStg )
740     {
741         pStg->GetUNOStorageHolderList()->remove( pHolder );
742 		pHolder->release();
743     }
744     else
745     {
746         DBG_ERROR("Not implemented!");
747     }
748 }
749 
750 /*************************************************************************
751 |*    SotStorage::GetUNOAPIDuplicate()
752 |*
753 |*    Beschreibung
754 *************************************************************************/
755 uno::Reference< embed::XStorage > SotStorage::GetUNOAPIDuplicate( const String& rEleName, sal_Int32 nUNOStorageMode )
756 {
757 	// after we create a duplicate we will register wrapper
758 	// for storage messages, the wrapper will control the real storage
759 	// the real storage will be able to ask the duplicate to dispose if it's parent is disposed
760 
761 	uno::Reference< embed::XStorage > xResult;
762 
763     UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
764     if ( !pStg )
765 		return xResult;
766 
767 	UNOStorageHolderList* pUNOStorageHolderList = pStg->GetUNOStorageHolderList();
768 	if ( !pUNOStorageHolderList )
769 		return xResult;
770 
771 	for ( UNOStorageHolderList::iterator aIter = pUNOStorageHolderList->begin();
772 		  aIter != pUNOStorageHolderList->end(); aIter++ )
773 		if ( (*aIter) && (*aIter)->GetStorageName().Equals( rEleName ) )
774 		{
775 			// the storage is already in use
776 			return xResult;
777 		}
778 
779 	if ( IsStream( rEleName ) )
780 		return xResult;
781 
782 	if ( GetError() == ERRCODE_NONE )
783 	{
784 		StreamMode nMode = ( ( nUNOStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ) ?
785 									STREAM_WRITE : ( STREAM_READ | STREAM_NOCREATE );
786 		if ( nUNOStorageMode & embed::ElementModes::NOCREATE )
787 			nMode |= STREAM_NOCREATE;
788 
789 		sal_Bool bStorageReady = !IsStorage( rEleName );
790 		SotStorageRef pChildStorage = OpenUCBStorage( rEleName, nMode, STORAGE_TRANSACTED );
791 		if ( pChildStorage->GetError() == ERRCODE_NONE && pChildStorage->m_pOwnStg )
792 		{
793 			::utl::TempFile* pTempFile = new ::utl::TempFile();
794 			if ( pTempFile->GetURL().Len() )
795 			{
796 					if ( !bStorageReady )
797 					{
798    						UCBStorage* pChildUCBStg = PTR_CAST( UCBStorage, pChildStorage->m_pOwnStg );
799 						if ( pChildUCBStg )
800 						{
801 							UCBStorage* pTempStorage = new UCBStorage( pTempFile->GetURL(), STREAM_WRITE, sal_False, sal_True );
802 							if ( pTempStorage )
803 							{
804 								pChildUCBStg->CopyTo( pTempStorage );
805 
806 								// CopyTo does not transport unknown media type
807 								// just workaround it
808 								uno::Any aMediaType;
809 
810 								if ( pChildUCBStg->GetProperty(
811 													::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ) )
812 									pTempStorage->SetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType );
813 
814 								bStorageReady = !pChildUCBStg->GetError() && !pTempStorage->GetError()
815 											&& pTempStorage->Commit();
816 
817 								delete ((BaseStorage*)pTempStorage);
818 								pTempStorage = NULL;
819 							}
820 						}
821 
822 						OSL_ENSURE( bStorageReady, "Problem on storage copy!\n" );
823 					}
824 
825 					if ( bStorageReady )
826 					{
827 						try {
828 							uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
829 									::comphelper::getProcessServiceFactory()->createInstance(
830                                 		::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
831 									uno::UNO_QUERY );
832 
833 							OSL_ENSURE( xStorageFactory.is(), "Can't create storage factory!\n" );
834 							if ( xStorageFactory.is() )
835 							{
836 								uno::Sequence< uno::Any > aArg( 2 );
837 								aArg[0] <<= ::rtl::OUString( pTempFile->GetURL() );
838 								aArg[1] <<= nUNOStorageMode;
839 								uno::Reference< embed::XStorage > xDuplStorage(
840 													xStorageFactory->createInstanceWithArguments( aArg ),
841 													uno::UNO_QUERY );
842 
843 								OSL_ENSURE( xDuplStorage.is(), "Can't open storage!\n" );
844 								if ( xDuplStorage.is() )
845 								{
846 									UNOStorageHolder* pHolder =
847 											new UNOStorageHolder( *this, *pChildStorage, xDuplStorage, pTempFile );
848 									pHolder->acquire();
849                                     pTempFile = NULL;
850 									pUNOStorageHolderList->push_back( pHolder );
851 									xResult = xDuplStorage;
852 								}
853 							}
854 						}
855 						catch( uno::Exception& e )
856 						{
857                                                     (void)e;
858                                                     OSL_ENSURE( sal_False, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ) );
859 						}
860 					}
861 			}
862 
863             if ( pTempFile != NULL )
864                 delete pTempFile;
865 		}
866 		else
867 			SetError( pChildStorage->GetError() );
868 	}
869 
870 	return xResult;
871 }
872 
873 /*************************************************************************
874 |*    SotStorage::CreateMemoryStream()
875 |*
876 |*    Beschreibung
877 *************************************************************************/
878 SvMemoryStream * SotStorage::CreateMemoryStream()
879 {
880     SvMemoryStream * pStm = NULL;
881 	pStm = new SvMemoryStream( 0x8000, 0x8000 );
882     SotStorageRef aStg = new SotStorage( *pStm );
883     if( CopyTo( aStg ) )
884         aStg->Commit();
885     else
886     {
887         aStg.Clear(); // Storage vorher freigeben
888         delete pStm;
889 		pStm = NULL;
890     }
891     return pStm;
892 }
893 
894 /*************************************************************************
895 |*    SotStorage::GetStorage()
896 |*
897 |*    Beschreibung
898 *************************************************************************/
899 sal_Bool SotStorage::IsStorageFile( const String & rFileName )
900 {
901 	String aName( rFileName );
902     INetURLObject aObj( aName );
903     if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
904     {
905         String aURL;
906         ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL );
907         aObj.SetURL( aURL );
908 		aName = aObj.GetMainURL( INetURLObject::NO_DECODE );
909     }
910 
911 	SvStream * pStm = ::utl::UcbStreamHelper::CreateStream( aName, STREAM_STD_READ );
912     sal_Bool bRet = SotStorage::IsStorageFile( pStm );
913 	delete pStm;
914 	return bRet;
915 }
916 
917 sal_Bool SotStorage::IsStorageFile( SvStream* pStream )
918 {
919     /** code for new storages must come first! **/
920     if ( pStream )
921     {
922         long nPos = pStream->Tell();
923         sal_Bool bRet = UCBStorage::IsStorageFile( pStream );
924 		if ( !bRet )
925 			bRet = Storage::IsStorageFile( pStream );
926         pStream->Seek( nPos );
927         return bRet;
928     }
929     else
930         return sal_False;
931 }
932 /*************************************************************************
933 |*    SotStorage::GetStorage()
934 |*
935 |*    Beschreibung
936 *************************************************************************/
937 const String & SotStorage::GetName() const
938 {
939 	if( !m_aName.Len() )
940 	{
941     	DBG_ASSERT( Owner(), "must be owner" );
942 		if( m_pOwnStg )
943     		((SotStorage *)this)->m_aName = m_pOwnStg->GetName();
944 	}
945 	return m_aName;
946 }
947 
948 void SotStorage::SetName( const String& rName )
949 {
950     // This method is necessary because most storages will not be opened with a FileName, but an external stream instead
951     // This stream is a stream opened by a UCP and so aName is only used as a transport for all client code of the SotStorage
952     // class that depends on the fact that a root storage has a name
953     DBG_ASSERT( !GetName().Len(), "SetName() must not be called when the storage already has a name!" );
954     m_aName = rName;
955 }
956 
957 /*************************************************************************
958 |*    SotStorage::ResetError()
959 |*
960 |*    Beschreibung
961 *************************************************************************/
962 void SotStorage::ResetError()
963 {
964     m_nError = SVSTREAM_OK;
965     if( m_pOwnStg )
966 		m_pOwnStg->ResetError();
967 }
968 
969 /*************************************************************************
970 |*    SotStorage::SetClass()
971 |*    SotStorage::SetConvertClass()
972 |*
973 |*    Beschreibung
974 *************************************************************************/
975 void SotStorage::SetClass( const SvGlobalName & rName,
976                           sal_uLong nOriginalClipFormat,
977                           const String & rUserTypeName )
978 {
979     DBG_ASSERT( Owner(), "must be owner" );
980 	if( m_pOwnStg )
981 	    m_pOwnStg->SetClass( rName, nOriginalClipFormat, rUserTypeName );
982 	else
983 		SetError( SVSTREAM_GENERALERROR );
984 }
985 
986 void SotStorage::SetConvertClass( const SvGlobalName & rName,
987                                  sal_uLong nOriginalClipFormat,
988                                  const String & rUserTypeName )
989 {
990     DBG_ASSERT( Owner(), "must be owner" );
991 	if( m_pOwnStg )
992 	    m_pOwnStg->SetConvertClass( rName, nOriginalClipFormat, rUserTypeName );
993 	else
994 		SetError( SVSTREAM_GENERALERROR );
995 }
996 
997 /*************************************************************************
998 |*    SotStorage::GetClassName()
999 |*    SotStorage::GetFormat()
1000 |*    SotStorage::GetUserName()
1001 |*    SotStorage::ShouldConvert()
1002 |*
1003 |*    Beschreibung
1004 *************************************************************************/
1005 SvGlobalName SotStorage::GetClassName()
1006 {
1007     SvGlobalName aGN;
1008     DBG_ASSERT( Owner(), "must be owner" );
1009 	if( m_pOwnStg )
1010 		aGN = m_pOwnStg->GetClassName();
1011 	else
1012 		SetError( SVSTREAM_GENERALERROR );
1013     return aGN;
1014 }
1015 
1016 sal_uLong SotStorage::GetFormat()
1017 {
1018     sal_uLong nFormat = 0;
1019     DBG_ASSERT( Owner(), "must be owner" );
1020 	if( m_pOwnStg )
1021 		nFormat = m_pOwnStg->GetFormat();
1022 	else
1023 		SetError( SVSTREAM_GENERALERROR );
1024     return nFormat;
1025 }
1026 
1027 String SotStorage::GetUserName()
1028 {
1029     String aName;
1030     DBG_ASSERT( Owner(), "must be owner" );
1031 	if( m_pOwnStg )
1032 		aName = m_pOwnStg->GetUserName();
1033 	else
1034 		SetError( SVSTREAM_GENERALERROR );
1035     return aName;
1036 }
1037 
1038 sal_Bool SotStorage::ShouldConvert()
1039 {
1040     DBG_ASSERT( Owner(), "must be owner" );
1041 	if( m_pOwnStg )
1042 		return m_pOwnStg->ShouldConvert();
1043 	else
1044 		SetError( SVSTREAM_GENERALERROR );
1045 	return sal_False;
1046 }
1047 
1048 /*************************************************************************
1049 |*    SotStorage::FillInfoList()
1050 |*
1051 |*    Beschreibung
1052 *************************************************************************/
1053 void SotStorage::FillInfoList( SvStorageInfoList * pFillList ) const
1054 {
1055     DBG_ASSERT( Owner(), "must be owner" );
1056 	if( m_pOwnStg )
1057 		m_pOwnStg->FillInfoList( pFillList );
1058 }
1059 
1060 /*************************************************************************
1061 |*    SotStorage::CopyTo()
1062 |*
1063 |*    Beschreibung
1064 *************************************************************************/
1065 sal_Bool SotStorage::CopyTo( SotStorage * pDestStg )
1066 {
1067     DBG_ASSERT( Owner(), "must be owner" );
1068     DBG_ASSERT( pDestStg->Owner(), "must be owner" );
1069 	if( m_pOwnStg && pDestStg->m_pOwnStg )
1070 	{
1071 		m_pOwnStg->CopyTo( pDestStg->m_pOwnStg );
1072 		SetError( m_pOwnStg->GetError() );
1073 		pDestStg->m_aKey = m_aKey;
1074 		pDestStg->m_nVersion = m_nVersion;
1075 	}
1076 	else
1077 		SetError( SVSTREAM_GENERALERROR );
1078     return SVSTREAM_OK == GetError();
1079 }
1080 
1081 /*************************************************************************
1082 |*    SotStorage::Commit()
1083 |*
1084 |*    Beschreibung
1085 *************************************************************************/
1086 sal_Bool SotStorage::Commit()
1087 {
1088     DBG_ASSERT( Owner(), "must be owner" );
1089 	if( m_pOwnStg )
1090 	{
1091 		if( !m_pOwnStg->Commit() )
1092 			SetError( m_pOwnStg->GetError() );
1093 	}
1094 	else
1095 		SetError( SVSTREAM_GENERALERROR );
1096     return SVSTREAM_OK == GetError();
1097 }
1098 
1099 /*************************************************************************
1100 |*    SotStorage::Revert()
1101 |*
1102 |*    Beschreibung
1103 *************************************************************************/
1104 sal_Bool SotStorage::Revert()
1105 {
1106     DBG_ASSERT( Owner(), "must be owner" );
1107 	if( m_pOwnStg )
1108 	{
1109 		if( !m_pOwnStg->Revert() )
1110 			SetError( m_pOwnStg->GetError() );
1111 	}
1112 	else
1113 		SetError( SVSTREAM_GENERALERROR );
1114     return SVSTREAM_OK == GetError();
1115 }
1116 
1117 /*************************************************************************
1118 |*    SotStorage::OpenStream()
1119 |*
1120 |*    Beschreibung
1121 *************************************************************************/
1122 SotStorageStream * SotStorage::OpenEncryptedSotStream( const String & rEleName, const ByteString& rKey,
1123 										     StreamMode nMode,
1124 											 StorageMode nStorageMode )
1125 {
1126     DBG_ASSERT( !nStorageMode, "StorageModes ignored" );
1127     SotStorageStream * pStm = NULL;
1128     DBG_ASSERT( Owner(), "must be owner" );
1129 	if( m_pOwnStg )
1130 	{
1131 		// volle Ole-Patches einschalten
1132 		// egal was kommt, nur exclusiv gestattet
1133 		nMode |= STREAM_SHARE_DENYALL;
1134 		ErrCode nE = m_pOwnStg->GetError();
1135         BaseStorageStream* p = m_pOwnStg->OpenStream( rEleName, nMode,
1136                             (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True, &rKey );
1137 		pStm = new SotStorageStream( p );
1138 
1139 		if( !nE )
1140 			m_pOwnStg->ResetError(); // kein Fehler setzen
1141 		if( nMode & STREAM_TRUNC )
1142 			pStm->SetSize( 0 );
1143 	}
1144 	else
1145 		SetError( SVSTREAM_GENERALERROR );
1146     return pStm;
1147 }
1148 
1149 SotStorageStream * SotStorage::OpenSotStream( const String & rEleName,
1150 										     StreamMode nMode,
1151 											 StorageMode nStorageMode )
1152 {
1153     DBG_ASSERT( !nStorageMode, "StorageModes ignored" );
1154     SotStorageStream * pStm = NULL;
1155     DBG_ASSERT( Owner(), "must be owner" );
1156 	if( m_pOwnStg )
1157 	{
1158 		// volle Ole-Patches einschalten
1159 		// egal was kommt, nur exclusiv gestattet
1160 		nMode |= STREAM_SHARE_DENYALL;
1161 		ErrCode nE = m_pOwnStg->GetError();
1162         BaseStorageStream * p = m_pOwnStg->OpenStream( rEleName, nMode,
1163 							(nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
1164 		pStm = new SotStorageStream( p );
1165 
1166 		if( !nE )
1167 			m_pOwnStg->ResetError(); // kein Fehler setzen
1168 		if( nMode & STREAM_TRUNC )
1169 			pStm->SetSize( 0 );
1170 	}
1171 	else
1172 		SetError( SVSTREAM_GENERALERROR );
1173     return pStm;
1174 }
1175 
1176 /*************************************************************************
1177 |*    SotStorage::OpenStorage()
1178 |*
1179 |*    Beschreibung
1180 *************************************************************************/
1181 SotStorage * SotStorage::OpenSotStorage( const String & rEleName,
1182 										StreamMode nMode,
1183 										StorageMode nStorageMode )
1184 {
1185     SotStorage * pStor = NULL;
1186     DBG_ASSERT( Owner(), "must be owner" );
1187 	if( m_pOwnStg )
1188 	{
1189 		nMode |= STREAM_SHARE_DENYALL;
1190 		ErrCode nE = m_pOwnStg->GetError();
1191         BaseStorage * p = m_pOwnStg->OpenStorage( rEleName, nMode,
1192 						(nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
1193 		if( p )
1194 		{
1195 			pStor = new SotStorage( p );
1196 			if( !nE )
1197 				m_pOwnStg->ResetError(); // kein Fehler setzen
1198 
1199 		    return pStor;
1200 		}
1201 	}
1202 
1203 	SetError( SVSTREAM_GENERALERROR );
1204 
1205     return NULL;
1206 }
1207 
1208 SotStorage * SotStorage::OpenUCBStorage( const String & rEleName,
1209 										StreamMode nMode,
1210 										StorageMode nStorageMode )
1211 {
1212     SotStorage * pStor = NULL;
1213     DBG_ASSERT( Owner(), "must be owner" );
1214 	if( m_pOwnStg )
1215 	{
1216 		nMode |= STREAM_SHARE_DENYALL;
1217 		ErrCode nE = m_pOwnStg->GetError();
1218         BaseStorage * p = m_pOwnStg->OpenUCBStorage( rEleName, nMode,
1219 						(nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
1220 		pStor = new SotStorage( p );
1221 		if( !nE )
1222 			m_pOwnStg->ResetError(); // kein Fehler setzen
1223 	}
1224 	else
1225 		SetError( SVSTREAM_GENERALERROR );
1226     return pStor;
1227 }
1228 
1229 SotStorage * SotStorage::OpenOLEStorage( const String & rEleName,
1230 										StreamMode nMode,
1231 										StorageMode nStorageMode )
1232 {
1233     SotStorage * pStor = NULL;
1234     DBG_ASSERT( Owner(), "must be owner" );
1235 	if( m_pOwnStg )
1236 	{
1237 		nMode |= STREAM_SHARE_DENYALL;
1238 		ErrCode nE = m_pOwnStg->GetError();
1239         BaseStorage * p = m_pOwnStg->OpenOLEStorage( rEleName, nMode,
1240 						(nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True );
1241 		pStor = new SotStorage( p );
1242 		if( !nE )
1243 			m_pOwnStg->ResetError(); // kein Fehler setzen
1244 	}
1245 	else
1246 		SetError( SVSTREAM_GENERALERROR );
1247     return pStor;
1248 }
1249 
1250 /*************************************************************************
1251 |*    SotStorage::IsStream()
1252 |*    SotStorage::IsStorage()
1253 |*    SotStorage::IsContained()
1254 |*
1255 |*    Beschreibung
1256 *************************************************************************/
1257 sal_Bool SotStorage::IsStorage( const String & rEleName ) const
1258 {
1259     DBG_ASSERT( Owner(), "must be owner" );
1260     // ein bisschen schneller
1261 	if( m_pOwnStg )
1262 		return m_pOwnStg->IsStorage( rEleName );
1263 	return sal_False;
1264 }
1265 
1266 sal_Bool SotStorage::IsStream( const String & rEleName ) const
1267 {
1268     DBG_ASSERT( Owner(), "must be owner" );
1269     // ein bisschen schneller
1270 	if( m_pOwnStg )
1271 		return m_pOwnStg->IsStream( rEleName );
1272 	return sal_False;
1273 }
1274 
1275 sal_Bool SotStorage::IsContained( const String & rEleName ) const
1276 {
1277     DBG_ASSERT( Owner(), "must be owner" );
1278     // ein bisschen schneller
1279 	if( m_pOwnStg )
1280 		return m_pOwnStg->IsContained( rEleName );
1281 	return sal_False;
1282 }
1283 
1284 /*************************************************************************
1285 |*    SotStorage::Remove()
1286 |*
1287 |*    Beschreibung
1288 *************************************************************************/
1289 sal_Bool SotStorage::Remove( const String & rEleName )
1290 {
1291     DBG_ASSERT( Owner(), "must be owner" );
1292 	if( m_pOwnStg )
1293 	{
1294 		m_pOwnStg->Remove( rEleName );
1295 		SetError( m_pOwnStg->GetError() );
1296 	}
1297 	else
1298 		SetError( SVSTREAM_GENERALERROR );
1299     return SVSTREAM_OK == GetError();
1300 }
1301 
1302 /*************************************************************************
1303 |*    SotStorage::Rename()
1304 |*
1305 |*    Beschreibung
1306 *************************************************************************/
1307 sal_Bool SotStorage::Rename( const String & rEleName, const String & rNewName )
1308 {
1309     DBG_ASSERT( Owner(), "must be owner" );
1310 	if( m_pOwnStg )
1311 	{
1312 		m_pOwnStg->Rename( rEleName, rNewName );
1313 		SetError( m_pOwnStg->GetError() );
1314 	}
1315 	else
1316 		SetError( SVSTREAM_GENERALERROR );
1317     return SVSTREAM_OK == GetError();
1318 }
1319 
1320 /*************************************************************************
1321 |*    SotStorage::CopyTo()
1322 |*
1323 |*    Beschreibung
1324 *************************************************************************/
1325 sal_Bool SotStorage::CopyTo( const String & rEleName,
1326                         SotStorage * pNewSt, const String & rNewName )
1327 {
1328     DBG_ASSERT( Owner(), "must be owner" );
1329     DBG_ASSERT( pNewSt->Owner(), "must be owner" );
1330 	if( m_pOwnStg )
1331 	{
1332 		m_pOwnStg->CopyTo( rEleName, pNewSt->m_pOwnStg, rNewName );
1333 		SetError( m_pOwnStg->GetError() );
1334 		SetError( pNewSt->GetError() );
1335 	}
1336 	else
1337 		SetError( SVSTREAM_GENERALERROR );
1338     return SVSTREAM_OK == GetError();
1339 }
1340 
1341 /*************************************************************************
1342 |*    SotStorage::MoveTo()
1343 |*
1344 |*    Beschreibung
1345 *************************************************************************/
1346 sal_Bool SotStorage::MoveTo( const String & rEleName,
1347                         SotStorage * pNewSt, const String & rNewName )
1348 {
1349     DBG_ASSERT( Owner(), "must be owner" );
1350     DBG_ASSERT( pNewSt->Owner(), "must be owner" );
1351 	if( m_pOwnStg )
1352 	{
1353 		m_pOwnStg->MoveTo( rEleName, pNewSt->m_pOwnStg, rNewName );
1354 		SetError( m_pOwnStg->GetError() );
1355 		SetError( pNewSt->GetError() );
1356 	}
1357 	else
1358 		SetError( SVSTREAM_GENERALERROR );
1359     return SVSTREAM_OK == GetError();
1360 }
1361 
1362 const SvStream* SotStorage::GetSvStream()
1363 {
1364 	const SvStream* pResult = 0;
1365     DBG_ASSERT( Owner(), "must be owner" );
1366     if( m_pOwnStg )
1367 		pResult = m_pOwnStg->GetSvStream();
1368 	return pResult;
1369 }
1370 
1371 SvStream* SotStorage::GetTargetSvStream() const
1372 {
1373 	SvStream* pResult = 0;
1374     DBG_ASSERT( Owner(), "must be owner" );
1375     if( m_pOwnStg )
1376 		pResult = (SvStream*)(m_pOwnStg->GetSvStream());
1377 	return pResult;
1378 }
1379 
1380 
1381 sal_Bool SotStorage::Validate()
1382 {
1383 	DBG_ASSERT( m_bIsRoot, "Validate nur an Rootstorage" );
1384 	if( m_pOwnStg )
1385 		return m_pOwnStg->ValidateFAT();
1386 	else
1387 		return sal_True;
1388 }
1389 
1390 sal_Bool SotStorage::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue )
1391 {
1392     UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
1393     if ( pStg )
1394     {
1395         return pStg->SetProperty( rName, rValue );
1396     }
1397     else
1398     {
1399         DBG_WARNING("W1:Not implemented!");
1400         return sal_False;
1401     }
1402 }
1403 
1404 sal_Bool SotStorage::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue )
1405 {
1406     UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
1407     if ( pStg )
1408     {
1409         return pStg->GetProperty( rName, rValue );
1410     }
1411     else if ( rName.CompareToAscii("MediaType") == COMPARE_EQUAL )
1412 	{
1413 		String aStr = SotExchange::GetFormatMimeType( GetFormat() );
1414 		sal_uInt16 nPos = aStr.Search(';');
1415 		if ( nPos != STRING_NOTFOUND )
1416 			aStr = aStr.Copy( 0, nPos );
1417 		rValue <<= (::rtl::OUString) aStr;
1418 		return sal_True;
1419 	}
1420     else
1421     {
1422         DBG_WARNING("W1:Not implemented!");
1423         return sal_False;
1424     }
1425 }
1426 
1427 sal_Bool SotStorage::GetProperty( const String& rEleName, const String& rName, ::com::sun::star::uno::Any& rValue )
1428 {
1429     UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
1430     if ( pStg )
1431     {
1432         return pStg->GetProperty( rEleName, rName, rValue );
1433     }
1434     else
1435     {
1436         DBG_WARNING("W1:Not implemented!");
1437         return sal_False;
1438     }
1439 }
1440 
1441 sal_Bool SotStorage::IsOLEStorage() const
1442 {
1443     UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
1444 	return !pStg;
1445 }
1446 
1447 sal_Bool SotStorage::IsOLEStorage( const String & rFileName )
1448 {
1449     return Storage::IsStorageFile( rFileName );
1450 }
1451 
1452 sal_Bool SotStorage::IsOLEStorage( SvStream* pStream )
1453 {
1454     return Storage::IsStorageFile( pStream );
1455 }
1456 
1457 void SotStorage::SetKey( const ByteString& rKey )
1458 {
1459     m_aKey = rKey;
1460     if ( !IsOLEStorage() )
1461     {
1462         sal_uInt8 aBuffer[RTL_DIGEST_LENGTH_SHA1];
1463         rtlDigestError nError = rtl_digest_SHA1( m_aKey.GetBuffer(), m_aKey.Len(), aBuffer, RTL_DIGEST_LENGTH_SHA1 );
1464         if ( nError == rtl_Digest_E_None )
1465         {
1466             sal_uInt8* pBuffer = aBuffer;
1467             ::com::sun::star::uno::Sequence < sal_Int8 > aSequ( (sal_Int8*) pBuffer, RTL_DIGEST_LENGTH_SHA1 );
1468             ::com::sun::star::uno::Any aAny;
1469             aAny <<= aSequ;
1470             SetProperty( ::rtl::OUString::createFromAscii("EncryptionKey"), aAny );
1471         }
1472     }
1473 }
1474 
1475 SotStorage* SotStorage::OpenOLEStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage,
1476                                     const String& rEleName, StreamMode nMode )
1477 {
1478     sal_Int32 nEleMode = embed::ElementModes::SEEKABLEREAD;
1479     if ( nMode & STREAM_WRITE )
1480         nEleMode |= embed::ElementModes::WRITE;
1481     if ( nMode & STREAM_TRUNC )
1482         nEleMode |= embed::ElementModes::TRUNCATE;
1483     if ( nMode & STREAM_NOCREATE )
1484         nEleMode |= embed::ElementModes::NOCREATE;
1485 
1486     SvStream* pStream = NULL;
1487     try
1488     {
1489         uno::Reference < io::XStream > xStream = xStorage->openStreamElement( rEleName, nEleMode );
1490 
1491 		// TODO/LATER: should it be done this way?
1492     	if ( nMode & STREAM_WRITE )
1493 		{
1494 			uno::Reference < beans::XPropertySet > xStreamProps( xStream, uno::UNO_QUERY_THROW );
1495 			xStreamProps->setPropertyValue(
1496 						::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1497 						uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) );
1498 		}
1499 
1500        	pStream = utl::UcbStreamHelper::CreateStream( xStream );
1501     }
1502     catch ( uno::Exception& )
1503     {
1504         //TODO/LATER: ErrorHandling
1505         pStream = new SvMemoryStream;
1506         pStream->SetError( ERRCODE_IO_GENERAL );
1507     }
1508 
1509     return new SotStorage( pStream, sal_True );
1510 }
1511 
1512 sal_Int32 SotStorage::GetFormatID( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage )
1513 {
1514     uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );
1515     if ( !xProps.is() )
1516         return 0;
1517 
1518     ::rtl::OUString aMediaType;
1519     xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType;
1520     if ( aMediaType.getLength() )
1521     {
1522         ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
1523         aDataFlavor.MimeType = aMediaType;
1524         return SotExchange::GetFormat( aDataFlavor );
1525     }
1526 
1527     return 0;
1528 }
1529 
1530 sal_Int32 SotStorage::GetVersion( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage )
1531 {
1532 	sal_Int32 nSotFormatID = SotStorage::GetFormatID( xStorage );
1533 	switch( nSotFormatID )
1534 	{
1535 		case SOT_FORMATSTR_ID_STARWRITER_8:
1536 		case SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE:
1537 		case SOT_FORMATSTR_ID_STARWRITERWEB_8:
1538 		case SOT_FORMATSTR_ID_STARWRITERGLOB_8:
1539 		case SOT_FORMATSTR_ID_STARDRAW_8:
1540 		case SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE:
1541 		case SOT_FORMATSTR_ID_STARIMPRESS_8:
1542 		case SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE:
1543 		case SOT_FORMATSTR_ID_STARCALC_8:
1544 		case SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE:
1545 		case SOT_FORMATSTR_ID_STARCHART_8:
1546 		case SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE:
1547 		case SOT_FORMATSTR_ID_STARMATH_8:
1548 		case SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE:
1549 			return SOFFICE_FILEFORMAT_8;
1550 		case SOT_FORMATSTR_ID_STARWRITER_60:
1551 		case SOT_FORMATSTR_ID_STARWRITERWEB_60:
1552 		case SOT_FORMATSTR_ID_STARWRITERGLOB_60:
1553 		case SOT_FORMATSTR_ID_STARDRAW_60:
1554 		case SOT_FORMATSTR_ID_STARIMPRESS_60:
1555 		case SOT_FORMATSTR_ID_STARCALC_60:
1556 		case SOT_FORMATSTR_ID_STARCHART_60:
1557 		case SOT_FORMATSTR_ID_STARMATH_60:
1558 			return SOFFICE_FILEFORMAT_60;
1559 	}
1560 
1561 	return 0;
1562 }
1563 
1564