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