xref: /trunk/main/sot/source/sdstor/storage.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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