xref: /aoo41x/main/sot/source/sdstor/stg.cxx (revision 297a844a)
1046d9d1fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3046d9d1fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4046d9d1fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5046d9d1fSAndrew Rist  * distributed with this work for additional information
6046d9d1fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7046d9d1fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8046d9d1fSAndrew Rist  * "License"); you may not use this file except in compliance
9046d9d1fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10046d9d1fSAndrew Rist  *
11046d9d1fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12046d9d1fSAndrew Rist  *
13046d9d1fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14046d9d1fSAndrew Rist  * software distributed under the License is distributed on an
15046d9d1fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16046d9d1fSAndrew Rist  * KIND, either express or implied.  See the License for the
17046d9d1fSAndrew Rist  * specific language governing permissions and limitations
18046d9d1fSAndrew Rist  * under the License.
19046d9d1fSAndrew Rist  *
20046d9d1fSAndrew Rist  *************************************************************/
21046d9d1fSAndrew Rist 
22046d9d1fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sot.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <sot/storinfo.hxx>
28cdf0e10cSrcweir #include <osl/file.hxx>
29cdf0e10cSrcweir #include <tools/tempfile.hxx>
30cdf0e10cSrcweir #include <tools/ownlist.hxx>
31cdf0e10cSrcweir #include <tools/string.hxx>
32cdf0e10cSrcweir #ifndef _TOOLS_FSYS_HXX
33cdf0e10cSrcweir #include <tools/fsys.hxx>
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir #ifndef _TOOLS_STREAM_HXX
36cdf0e10cSrcweir #include <tools/stream.hxx>
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir #include <tools/pstm.hxx>
39cdf0e10cSrcweir #include <tools/debug.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include "sot/stg.hxx"
42cdf0e10cSrcweir #include "stgelem.hxx"
43cdf0e10cSrcweir #include "stgcache.hxx"
44cdf0e10cSrcweir #include "stgstrms.hxx"
45cdf0e10cSrcweir #include "stgdir.hxx"
46cdf0e10cSrcweir #include "stgio.hxx"
47cdf0e10cSrcweir #include "stgole.hxx"
48cdf0e10cSrcweir 
49cdf0e10cSrcweir static long nTmpCount = 0;
50cdf0e10cSrcweir 
51cdf0e10cSrcweir // The internal open mode is STREAM_READ | STREAM_TRUNC, which is silly
52cdf0e10cSrcweir // by itself. It inhibits the checking of sharing modes and is used
53cdf0e10cSrcweir // during CopyTo() and MoveTo() for opening a stream in read mode
54cdf0e10cSrcweir // although it may be open in DENYALL mode
55cdf0e10cSrcweir 
56cdf0e10cSrcweir #define INTERNAL_MODE ( STREAM_READ | STREAM_TRUNC )
57cdf0e10cSrcweir 
58cdf0e10cSrcweir ///////////////////////// class StorageBase //////////////////////////////
59cdf0e10cSrcweir 
60cdf0e10cSrcweir TYPEINIT0( StorageBase );
61cdf0e10cSrcweir TYPEINIT1( BaseStorageStream, StorageBase );
62cdf0e10cSrcweir TYPEINIT1( BaseStorage, StorageBase );
63cdf0e10cSrcweir 
StorageBase()64cdf0e10cSrcweir StorageBase::StorageBase()
65cdf0e10cSrcweir     : m_bAutoCommit( sal_False )
66cdf0e10cSrcweir {
67cdf0e10cSrcweir 	m_nMode  = STREAM_READ;
68cdf0e10cSrcweir 	m_nError = SVSTREAM_OK;
69cdf0e10cSrcweir }
70cdf0e10cSrcweir 
~StorageBase()71cdf0e10cSrcweir StorageBase::~StorageBase()
72cdf0e10cSrcweir {
73cdf0e10cSrcweir }
74cdf0e10cSrcweir 
75cdf0e10cSrcweir // The following three methods are declared as const, since they
76cdf0e10cSrcweir // may be called from within a const method.
77cdf0e10cSrcweir 
GetError() const78cdf0e10cSrcweir sal_uLong StorageBase::GetError() const
79cdf0e10cSrcweir {
80cdf0e10cSrcweir 	sal_uLong n = m_nError;
81cdf0e10cSrcweir 	((StorageBase*) this)->m_nError = SVSTREAM_OK;
82cdf0e10cSrcweir 	return n;
83cdf0e10cSrcweir }
84cdf0e10cSrcweir 
SetError(sal_uLong n) const85cdf0e10cSrcweir void StorageBase::SetError( sal_uLong n ) const
86cdf0e10cSrcweir {
87cdf0e10cSrcweir     if( !m_nError )
88cdf0e10cSrcweir 		((StorageBase*) this)->m_nError = n;
89cdf0e10cSrcweir }
90cdf0e10cSrcweir 
ResetError() const91cdf0e10cSrcweir void StorageBase::ResetError() const
92cdf0e10cSrcweir {
93cdf0e10cSrcweir 	((StorageBase*) this)->m_nError = SVSTREAM_OK;
94cdf0e10cSrcweir }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir // Retrieve the underlying SvStream for info purposes
97cdf0e10cSrcweir 
GetSvStream_Impl() const98cdf0e10cSrcweir const SvStream* OLEStorageBase::GetSvStream_Impl() const
99cdf0e10cSrcweir {
100cdf0e10cSrcweir 	return pIo ? pIo->GetStrm() : NULL;
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
OLEStorageBase(StgIo * p,StgDirEntry * pe,StreamMode & nMode)103cdf0e10cSrcweir OLEStorageBase::OLEStorageBase( StgIo* p, StgDirEntry* pe, StreamMode& nMode )
104cdf0e10cSrcweir     : nStreamMode( nMode ), pIo( p ), pEntry( pe )
105cdf0e10cSrcweir {
106*297a844aSArmin Le Grand     if ( p )
107*297a844aSArmin Le Grand         p->IncRef();
108cdf0e10cSrcweir 	if( pe )
109cdf0e10cSrcweir 		pe->nRefCnt++;
110cdf0e10cSrcweir }
111cdf0e10cSrcweir 
~OLEStorageBase()112cdf0e10cSrcweir OLEStorageBase::~OLEStorageBase()
113cdf0e10cSrcweir {
114cdf0e10cSrcweir 	if( pEntry )
115cdf0e10cSrcweir 	{
116cdf0e10cSrcweir 		DBG_ASSERT( pEntry->nRefCnt, "RefCount unter 0" );
117cdf0e10cSrcweir 		if( !--pEntry->nRefCnt )
118cdf0e10cSrcweir 		{
119cdf0e10cSrcweir 			if( pEntry->bZombie )
120cdf0e10cSrcweir 				delete pEntry;
121cdf0e10cSrcweir 			else
122cdf0e10cSrcweir 				pEntry->Close();
123cdf0e10cSrcweir 		}
124*297a844aSArmin Le Grand 
125*297a844aSArmin Le Grand         pEntry = NULL;
126cdf0e10cSrcweir 	}
127cdf0e10cSrcweir 
128cdf0e10cSrcweir 
129*297a844aSArmin Le Grand 	if( pIo && !pIo->DecRef() )
130*297a844aSArmin Le Grand     {
131cdf0e10cSrcweir 		delete pIo;
132*297a844aSArmin Le Grand         pIo = NULL;
133*297a844aSArmin Le Grand     }
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir // Validate the instance for I/O
137cdf0e10cSrcweir 
Validate_Impl(sal_Bool bWrite) const138cdf0e10cSrcweir sal_Bool OLEStorageBase::Validate_Impl( sal_Bool bWrite ) const
139cdf0e10cSrcweir {
140*297a844aSArmin Le Grand     if( pIo
141*297a844aSArmin Le Grand         && pIo->pTOC
142*297a844aSArmin Le Grand         && pEntry
143cdf0e10cSrcweir 		&& !pEntry->bInvalid
144cdf0e10cSrcweir         &&  ( !bWrite || !pEntry->bDirect || ( nStreamMode & STREAM_WRITE ) ) )
145*297a844aSArmin Le Grand             return sal_True;
146cdf0e10cSrcweir 	return sal_False;
147cdf0e10cSrcweir }
148cdf0e10cSrcweir 
ValidateMode_Impl(StreamMode m,StgDirEntry * p) const149cdf0e10cSrcweir sal_Bool OLEStorageBase::ValidateMode_Impl( StreamMode m, StgDirEntry* p ) const
150cdf0e10cSrcweir {
151cdf0e10cSrcweir 	if( m == INTERNAL_MODE )
152cdf0e10cSrcweir 		return sal_True;
153cdf0e10cSrcweir 	sal_uInt16 nCurMode = ( p && p->nRefCnt ) ? p->nMode : 0xFFFF;
154cdf0e10cSrcweir 	if( ( m & 3 ) == STREAM_READ )
155cdf0e10cSrcweir 	{
156cdf0e10cSrcweir 		// only SHARE_DENYWRITE or SHARE_DENYALL allowed
157cdf0e10cSrcweir 		if( ( ( m & STREAM_SHARE_DENYWRITE )
158cdf0e10cSrcweir 		   && ( nCurMode & STREAM_SHARE_DENYWRITE ) )
159cdf0e10cSrcweir 		 || ( ( m & STREAM_SHARE_DENYALL )
160cdf0e10cSrcweir 		   && ( nCurMode & STREAM_SHARE_DENYALL ) ) )
161cdf0e10cSrcweir 			return sal_True;
162cdf0e10cSrcweir 	}
163cdf0e10cSrcweir 	else
164cdf0e10cSrcweir 	{
165cdf0e10cSrcweir 		// only SHARE_DENYALL allowed
166cdf0e10cSrcweir 		// storages open in r/o mode are OK, since only
167cdf0e10cSrcweir 		// the commit may fail
168cdf0e10cSrcweir 		if( ( m & STREAM_SHARE_DENYALL )
169cdf0e10cSrcweir 		 && ( nCurMode & STREAM_SHARE_DENYALL ) )
170cdf0e10cSrcweir 			return sal_True;
171cdf0e10cSrcweir 	}
172cdf0e10cSrcweir 	return sal_False;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 
176cdf0e10cSrcweir //////////////////////// class StorageStream /////////////////////////////
177cdf0e10cSrcweir 
178cdf0e10cSrcweir TYPEINIT1( StorageStream, BaseStorageStream );
179cdf0e10cSrcweir 
StorageStream(StgIo * p,StgDirEntry * q,StreamMode m)180cdf0e10cSrcweir StorageStream::StorageStream( StgIo* p, StgDirEntry* q, StreamMode m )
181cdf0e10cSrcweir              : OLEStorageBase( p, q, m_nMode ), nPos( 0L )
182cdf0e10cSrcweir {
183cdf0e10cSrcweir     // The dir entry may be 0; this means that the stream is invalid.
184*297a844aSArmin Le Grand     if( q && p )
185cdf0e10cSrcweir 	{
186cdf0e10cSrcweir 		if( q->nRefCnt == 1 )
187cdf0e10cSrcweir 		{
188cdf0e10cSrcweir 			q->nMode = m;
189cdf0e10cSrcweir 			q->OpenStream( *p );
190cdf0e10cSrcweir 		}
191cdf0e10cSrcweir 	}
192cdf0e10cSrcweir     else
193cdf0e10cSrcweir         m &= ~STREAM_READWRITE;
194cdf0e10cSrcweir 	m_nMode = m;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
~StorageStream()197cdf0e10cSrcweir StorageStream::~StorageStream()
198cdf0e10cSrcweir {
199cdf0e10cSrcweir 	// Do an auto-commit if the entry is open in direct mode
200cdf0e10cSrcweir 	if( m_bAutoCommit )
201cdf0e10cSrcweir 		Commit();
202cdf0e10cSrcweir 	if( pEntry && pEntry->nRefCnt && pEntry->bDirect && (m_nMode & STREAM_WRITE) )
203cdf0e10cSrcweir 		pEntry->Commit();
204cdf0e10cSrcweir }
205cdf0e10cSrcweir 
Equals(const BaseStorageStream & rStream) const206cdf0e10cSrcweir sal_Bool StorageStream::Equals( const BaseStorageStream& rStream ) const
207cdf0e10cSrcweir {
208cdf0e10cSrcweir     const StorageStream* pOther = PTR_CAST( StorageStream, &rStream );
209cdf0e10cSrcweir     return pOther && ( pOther->pEntry == pEntry );
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
Read(void * pData,sal_uLong nSize)212cdf0e10cSrcweir sal_uLong StorageStream::Read( void* pData, sal_uLong nSize )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir 	if( Validate() )
215cdf0e10cSrcweir 	{
216cdf0e10cSrcweir 		pEntry->Seek( nPos );
217cdf0e10cSrcweir 		nSize = pEntry->Read( pData, (sal_Int32) nSize );
218cdf0e10cSrcweir 		pIo->MoveError( *this );
219cdf0e10cSrcweir 		nPos += nSize;
220cdf0e10cSrcweir 	}
221cdf0e10cSrcweir 	else
222cdf0e10cSrcweir 		nSize = 0L;
223cdf0e10cSrcweir 	return nSize;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir 
Write(const void * pData,sal_uLong nSize)226cdf0e10cSrcweir sal_uLong StorageStream::Write( const void* pData, sal_uLong nSize )
227cdf0e10cSrcweir {
228cdf0e10cSrcweir 	if( Validate( sal_True ) )
229cdf0e10cSrcweir 	{
230cdf0e10cSrcweir 		pEntry->Seek( nPos );
231cdf0e10cSrcweir 		nSize = pEntry->Write( pData, (sal_Int32) nSize );
232cdf0e10cSrcweir 		pIo->MoveError( *this );
233cdf0e10cSrcweir 		nPos += nSize;
234cdf0e10cSrcweir 	}
235cdf0e10cSrcweir 	else
236cdf0e10cSrcweir 		nSize = 0L;
237cdf0e10cSrcweir 	return nSize;
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
Seek(sal_uLong n)240cdf0e10cSrcweir sal_uLong StorageStream::Seek( sal_uLong n )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir 	if( Validate() )
243cdf0e10cSrcweir 		return nPos = pEntry->Seek( n );
244cdf0e10cSrcweir 	else
245cdf0e10cSrcweir 		return n;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
Flush()248cdf0e10cSrcweir void StorageStream::Flush()
249cdf0e10cSrcweir {
250cdf0e10cSrcweir 	// Flushing means committing, since streams are never transacted
251cdf0e10cSrcweir 	Commit();
252cdf0e10cSrcweir }
253cdf0e10cSrcweir 
SetSize(sal_uLong nNewSize)254cdf0e10cSrcweir sal_Bool StorageStream::SetSize( sal_uLong nNewSize )
255cdf0e10cSrcweir {
256cdf0e10cSrcweir     if( Validate( sal_True ) )
257cdf0e10cSrcweir 	{
258cdf0e10cSrcweir 		sal_Bool b = pEntry->SetSize( (sal_Int32) nNewSize );
259cdf0e10cSrcweir 		pIo->MoveError( *this );
260cdf0e10cSrcweir 		return b;
261cdf0e10cSrcweir 	}
262cdf0e10cSrcweir 	else
263cdf0e10cSrcweir 		return sal_False;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
Commit()266cdf0e10cSrcweir sal_Bool StorageStream::Commit()
267cdf0e10cSrcweir {
268cdf0e10cSrcweir 	if( !Validate() )
269cdf0e10cSrcweir 		return sal_False;
270cdf0e10cSrcweir 	if( !( m_nMode & STREAM_WRITE ) )
271cdf0e10cSrcweir 	{
272cdf0e10cSrcweir 		SetError( SVSTREAM_ACCESS_DENIED );
273cdf0e10cSrcweir 		return sal_False;
274cdf0e10cSrcweir 	}
275cdf0e10cSrcweir 	else
276cdf0e10cSrcweir     {
277cdf0e10cSrcweir 		pEntry->Commit();
278cdf0e10cSrcweir 		pIo->MoveError( *this );
279cdf0e10cSrcweir 		return Good();
280cdf0e10cSrcweir     }
281cdf0e10cSrcweir }
282cdf0e10cSrcweir 
Revert()283cdf0e10cSrcweir sal_Bool StorageStream::Revert()
284cdf0e10cSrcweir {
285*297a844aSArmin Le Grand     sal_Bool bResult = sal_False;
286*297a844aSArmin Le Grand 
287*297a844aSArmin Le Grand     if ( Validate() )
288*297a844aSArmin Le Grand     {
289*297a844aSArmin Le Grand         pEntry->Revert();
290*297a844aSArmin Le Grand         pIo->MoveError( *this );
291*297a844aSArmin Le Grand         bResult = Good();
292*297a844aSArmin Le Grand     }
293*297a844aSArmin Le Grand 
294*297a844aSArmin Le Grand     return bResult;
295cdf0e10cSrcweir }
296cdf0e10cSrcweir 
CopyTo(BaseStorageStream * pDest)297cdf0e10cSrcweir sal_Bool StorageStream::CopyTo( BaseStorageStream* pDest )
298cdf0e10cSrcweir {
299*297a844aSArmin Le Grand     if( !Validate() || !pDest || !pDest->Validate( sal_True ) || Equals( *pDest ) )
300cdf0e10cSrcweir 		return sal_False;
301cdf0e10cSrcweir     pEntry->Copy( *pDest );
302cdf0e10cSrcweir 	pDest->Commit();
303cdf0e10cSrcweir 	pIo->MoveError( *this );
304cdf0e10cSrcweir 	SetError( pDest->GetError() );
305cdf0e10cSrcweir 	return sal_Bool( Good() && pDest->Good() );
306cdf0e10cSrcweir }
307cdf0e10cSrcweir 
GetSvStream() const308cdf0e10cSrcweir const SvStream* StorageStream::GetSvStream() const
309cdf0e10cSrcweir {
310cdf0e10cSrcweir     return GetSvStream_Impl();
311cdf0e10cSrcweir }
312cdf0e10cSrcweir 
Validate(sal_Bool bValidate) const313cdf0e10cSrcweir sal_Bool StorageStream::Validate( sal_Bool bValidate ) const
314cdf0e10cSrcweir {
315cdf0e10cSrcweir     sal_Bool bRet = Validate_Impl( bValidate );
316cdf0e10cSrcweir     if ( !bRet )
317cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
318cdf0e10cSrcweir     return bRet;
319cdf0e10cSrcweir }
320cdf0e10cSrcweir 
ValidateMode(StreamMode nMode) const321cdf0e10cSrcweir sal_Bool StorageStream::ValidateMode( StreamMode nMode ) const
322cdf0e10cSrcweir {
323cdf0e10cSrcweir     sal_Bool bRet = ValidateMode_Impl( nMode, NULL );
324cdf0e10cSrcweir     if ( !bRet )
325cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
326cdf0e10cSrcweir     return bRet;
327cdf0e10cSrcweir }
328cdf0e10cSrcweir 
ValidateMode(StreamMode nMode,StgDirEntry * p) const329cdf0e10cSrcweir sal_Bool StorageStream::ValidateMode( StreamMode nMode, StgDirEntry* p ) const
330cdf0e10cSrcweir {
331cdf0e10cSrcweir     sal_Bool bRet = ValidateMode_Impl( nMode, p );
332cdf0e10cSrcweir     if ( !bRet )
333cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
334cdf0e10cSrcweir     return bRet;
335cdf0e10cSrcweir }
336cdf0e10cSrcweir 
337cdf0e10cSrcweir ///////////////////////// class SvStorageInfo //////////////////////////////
338cdf0e10cSrcweir 
SvStorageInfo(const StgDirEntry & rE)339cdf0e10cSrcweir SvStorageInfo::SvStorageInfo( const StgDirEntry& rE )
340cdf0e10cSrcweir {
341cdf0e10cSrcweir     rE.aEntry.GetName( aName );
342cdf0e10cSrcweir     bStorage = sal_Bool( rE.aEntry.GetType() == STG_STORAGE );
343cdf0e10cSrcweir     bStream  = sal_Bool( rE.aEntry.GetType() == STG_STREAM );
344cdf0e10cSrcweir     nSize    = bStorage ? 0 : rE.aEntry.GetSize();
345cdf0e10cSrcweir }
346cdf0e10cSrcweir 
347cdf0e10cSrcweir /////////////////////////// class Storage ////////////////////////////////
348cdf0e10cSrcweir 
IsStorageFile(const String & rFileName)349cdf0e10cSrcweir sal_Bool Storage::IsStorageFile( const String & rFileName )
350cdf0e10cSrcweir {
351cdf0e10cSrcweir     StgIo aIo;
352cdf0e10cSrcweir     if( aIo.Open( rFileName, STREAM_STD_READ ) )
353cdf0e10cSrcweir     	return aIo.Load();
354cdf0e10cSrcweir     return sal_False;
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
IsStorageFile(SvStream * pStream)357cdf0e10cSrcweir sal_Bool Storage::IsStorageFile( SvStream* pStream )
358cdf0e10cSrcweir {
359*297a844aSArmin Le Grand     sal_Bool bRet = sal_False;
360*297a844aSArmin Le Grand 
361*297a844aSArmin Le Grand     if ( pStream )
362*297a844aSArmin Le Grand     {
363*297a844aSArmin Le Grand         StgHeader aHdr;
364*297a844aSArmin Le Grand         sal_uLong nPos = pStream->Tell();
365*297a844aSArmin Le Grand         bRet = ( aHdr.Load( *pStream ) && aHdr.Check() );
366*297a844aSArmin Le Grand 
367*297a844aSArmin Le Grand         // It's not a stream error if it is too small for a OLE storage header
368*297a844aSArmin Le Grand         if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK )
369*297a844aSArmin Le Grand             pStream->ResetError();
370*297a844aSArmin Le Grand         pStream->Seek( nPos );
371*297a844aSArmin Le Grand     }
372cdf0e10cSrcweir 
373cdf0e10cSrcweir     return bRet;
374cdf0e10cSrcweir }
375cdf0e10cSrcweir 
376cdf0e10cSrcweir // Open the storage file. If writing is permitted and the file is not
377cdf0e10cSrcweir // a storage file, initialize it.
378cdf0e10cSrcweir 
379cdf0e10cSrcweir TYPEINIT1( Storage, BaseStorage );
380cdf0e10cSrcweir 
Storage(const String & rFile,StreamMode m,sal_Bool bDirect)381cdf0e10cSrcweir Storage::Storage( const String& rFile, StreamMode m, sal_Bool bDirect )
382cdf0e10cSrcweir        : OLEStorageBase( new StgIo, NULL, m_nMode ), aName( rFile ), bIsRoot( sal_False )
383cdf0e10cSrcweir {
384cdf0e10cSrcweir 	sal_Bool bTemp = sal_False;
385cdf0e10cSrcweir 	if( !aName.Len() )
386cdf0e10cSrcweir 	{
387cdf0e10cSrcweir 		// no name = temporary name!
388cdf0e10cSrcweir 		aName = TempFile::CreateTempName();
389cdf0e10cSrcweir 		bTemp = sal_True;
390cdf0e10cSrcweir 	}
391cdf0e10cSrcweir 	// the root storage creates the I/O system
392cdf0e10cSrcweir     m_nMode = m;
393cdf0e10cSrcweir     if( pIo->Open( aName, m ) )
394cdf0e10cSrcweir 	{
395cdf0e10cSrcweir 		Init( sal_Bool( ( m & ( STREAM_TRUNC | STREAM_NOCREATE ) ) == STREAM_TRUNC ) );
396cdf0e10cSrcweir 		if( pEntry )
397cdf0e10cSrcweir 		{
398cdf0e10cSrcweir 			pEntry->bDirect = bDirect;
399cdf0e10cSrcweir 			pEntry->nMode = m;
400cdf0e10cSrcweir 			pEntry->bTemp = bTemp;
401cdf0e10cSrcweir 		}
402cdf0e10cSrcweir 	}
403cdf0e10cSrcweir 	else
404cdf0e10cSrcweir 	{
405cdf0e10cSrcweir 		pIo->MoveError( *this );
406cdf0e10cSrcweir 		pEntry = NULL;
407cdf0e10cSrcweir 	}
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir // Create a storage on a given stream.
411cdf0e10cSrcweir 
Storage(SvStream & r,sal_Bool bDirect)412cdf0e10cSrcweir Storage::Storage( SvStream& r, sal_Bool bDirect )
413cdf0e10cSrcweir        : OLEStorageBase( new StgIo, NULL, m_nMode ), bIsRoot( sal_False )
414cdf0e10cSrcweir {
415cdf0e10cSrcweir 	m_nMode = STREAM_READ;
416cdf0e10cSrcweir 	if( r.IsWritable() )
417cdf0e10cSrcweir 		m_nMode = STREAM_READ | STREAM_WRITE;
418cdf0e10cSrcweir 	if( r.GetError() == SVSTREAM_OK )
419cdf0e10cSrcweir 	{
420cdf0e10cSrcweir 		pIo->SetStrm( &r, sal_False );
421cdf0e10cSrcweir 		sal_uLong nSize = r.Seek( STREAM_SEEK_TO_END );
422cdf0e10cSrcweir 		r.Seek( 0L );
423cdf0e10cSrcweir 		// Initializing is OK if the stream is empty
424cdf0e10cSrcweir 		Init( sal_Bool( nSize == 0 ) );
425cdf0e10cSrcweir 		if( pEntry )
426cdf0e10cSrcweir 		{
427cdf0e10cSrcweir 			pEntry->bDirect = bDirect;
428cdf0e10cSrcweir 			pEntry->nMode = m_nMode;
429cdf0e10cSrcweir 		}
430cdf0e10cSrcweir 		pIo->MoveError( *this );
431cdf0e10cSrcweir 	}
432cdf0e10cSrcweir 	else
433cdf0e10cSrcweir 	{
434cdf0e10cSrcweir 		SetError( r.GetError() );
435cdf0e10cSrcweir 		pEntry = NULL;
436cdf0e10cSrcweir 	}
437cdf0e10cSrcweir }
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 
Storage(UCBStorageStream & rStrm,sal_Bool bDirect)440cdf0e10cSrcweir Storage::Storage( UCBStorageStream& rStrm, sal_Bool bDirect )
441cdf0e10cSrcweir        : OLEStorageBase( new StgIo, NULL, m_nMode ), bIsRoot( sal_False )
442cdf0e10cSrcweir {
443cdf0e10cSrcweir 	m_nMode = STREAM_READ;
444cdf0e10cSrcweir 
445cdf0e10cSrcweir 	if ( rStrm.GetError() != SVSTREAM_OK )
446cdf0e10cSrcweir 	{
447cdf0e10cSrcweir 		SetError( rStrm.GetError() );
448cdf0e10cSrcweir 		pEntry = NULL;
449cdf0e10cSrcweir 		return;
450cdf0e10cSrcweir 	}
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 	SvStream* pStream = rStrm.GetModifySvStream();
453cdf0e10cSrcweir 	if ( !pStream )
454cdf0e10cSrcweir 	{
455cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "UCBStorageStream can not provide SvStream implementation!\n" );
456cdf0e10cSrcweir 		SetError( SVSTREAM_GENERALERROR );
457cdf0e10cSrcweir 		pEntry = NULL;
458cdf0e10cSrcweir 		return;
459cdf0e10cSrcweir 	}
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 	if( pStream->IsWritable() )
462cdf0e10cSrcweir 		m_nMode = STREAM_READ | STREAM_WRITE;
463cdf0e10cSrcweir 
464cdf0e10cSrcweir 	pIo->SetStrm( &rStrm );
465cdf0e10cSrcweir 
466cdf0e10cSrcweir 	sal_uLong nSize = pStream->Seek( STREAM_SEEK_TO_END );
467cdf0e10cSrcweir 	pStream->Seek( 0L );
468cdf0e10cSrcweir 	// Initializing is OK if the stream is empty
469cdf0e10cSrcweir 	Init( sal_Bool( nSize == 0 ) );
470cdf0e10cSrcweir 	if( pEntry )
471cdf0e10cSrcweir 	{
472cdf0e10cSrcweir 		pEntry->bDirect = bDirect;
473cdf0e10cSrcweir 		pEntry->nMode = m_nMode;
474cdf0e10cSrcweir 	}
475cdf0e10cSrcweir 
476cdf0e10cSrcweir 	pIo->MoveError( *this );
477cdf0e10cSrcweir }
478cdf0e10cSrcweir 
479cdf0e10cSrcweir 
480cdf0e10cSrcweir // Perform common code for both ctors above.
481cdf0e10cSrcweir 
Init(sal_Bool bCreate)482cdf0e10cSrcweir void Storage::Init( sal_Bool bCreate )
483cdf0e10cSrcweir {
484cdf0e10cSrcweir 	pEntry = NULL;
485cdf0e10cSrcweir 	sal_Bool bHdrLoaded = sal_False;
486cdf0e10cSrcweir     bIsRoot = sal_True;
487*297a844aSArmin Le Grand 
488*297a844aSArmin Le Grand     OSL_ENSURE( pIo, "The pointer may not be empty at this point!" );
489*297a844aSArmin Le Grand 	if( pIo->Good() && pIo->GetStrm() )
490cdf0e10cSrcweir 	{
491cdf0e10cSrcweir 		sal_uLong nSize = pIo->GetStrm()->Seek( STREAM_SEEK_TO_END );
492cdf0e10cSrcweir 		pIo->GetStrm()->Seek( 0L );
493cdf0e10cSrcweir 		if( nSize )
494cdf0e10cSrcweir 		{
495cdf0e10cSrcweir 			bHdrLoaded = pIo->Load();
496cdf0e10cSrcweir 			if( !bHdrLoaded && !bCreate  )
497cdf0e10cSrcweir 			{
498cdf0e10cSrcweir 				// File is not a storage and not empty; do not destroy!
499cdf0e10cSrcweir 				SetError( SVSTREAM_FILEFORMAT_ERROR );
500cdf0e10cSrcweir 				return;
501cdf0e10cSrcweir 			}
502cdf0e10cSrcweir 		}
503cdf0e10cSrcweir 	}
504cdf0e10cSrcweir     // file is a storage, empty or should be overwritten
505cdf0e10cSrcweir 	pIo->ResetError();
506cdf0e10cSrcweir 	// we have to set up the data structures, since
507cdf0e10cSrcweir 	// the file is empty
508cdf0e10cSrcweir 	if( !bHdrLoaded )
509cdf0e10cSrcweir 		pIo->Init();
510*297a844aSArmin Le Grand     if( pIo->Good() && pIo->pTOC )
511cdf0e10cSrcweir 	{
512cdf0e10cSrcweir         pEntry = pIo->pTOC->GetRoot();
513cdf0e10cSrcweir 		pEntry->nRefCnt++;
514cdf0e10cSrcweir 	}
515cdf0e10cSrcweir }
516cdf0e10cSrcweir 
517cdf0e10cSrcweir // Internal ctor
518cdf0e10cSrcweir 
Storage(StgIo * p,StgDirEntry * q,StreamMode m)519cdf0e10cSrcweir Storage::Storage( StgIo* p, StgDirEntry* q, StreamMode m )
520cdf0e10cSrcweir        : OLEStorageBase( p, q, m_nMode ), bIsRoot( sal_False )
521cdf0e10cSrcweir {
522cdf0e10cSrcweir 	if( q )
523cdf0e10cSrcweir 		q->aEntry.GetName( aName );
524cdf0e10cSrcweir 	else
525cdf0e10cSrcweir         m &= ~STREAM_READWRITE;
526cdf0e10cSrcweir 	m_nMode   = m;
527cdf0e10cSrcweir 	if( q && q->nRefCnt == 1 )
528cdf0e10cSrcweir 		q->nMode = m;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir 
~Storage()531cdf0e10cSrcweir Storage::~Storage()
532cdf0e10cSrcweir {
533cdf0e10cSrcweir 	// Invalidate all open substorages
534cdf0e10cSrcweir 	if( m_bAutoCommit )
535cdf0e10cSrcweir 		Commit();
536cdf0e10cSrcweir 	if( pEntry )
537cdf0e10cSrcweir 	{
538cdf0e10cSrcweir 		// Do an auto-commit if the entry is open in direct mode
539cdf0e10cSrcweir 		if( pEntry->nRefCnt && pEntry->bDirect && (m_nMode & STREAM_WRITE) )
540cdf0e10cSrcweir 			Commit();
541cdf0e10cSrcweir 		if( pEntry->nRefCnt == 1 )
542cdf0e10cSrcweir 			pEntry->Invalidate();
543cdf0e10cSrcweir 	}
544cdf0e10cSrcweir 	// close the stream is root storage
545cdf0e10cSrcweir     if( bIsRoot )
546cdf0e10cSrcweir         pIo->Close();
547cdf0e10cSrcweir 	// remove the file if temporary root storage
548cdf0e10cSrcweir 	if( bIsRoot && pEntry && pEntry->bTemp )
549cdf0e10cSrcweir 	{
550cdf0e10cSrcweir 		osl::File::remove( GetName() );
551cdf0e10cSrcweir 	}
552cdf0e10cSrcweir }
553cdf0e10cSrcweir 
GetName() const554cdf0e10cSrcweir const String& Storage::GetName() const
555cdf0e10cSrcweir {
556cdf0e10cSrcweir 	if( !bIsRoot && Validate() )
557cdf0e10cSrcweir 		pEntry->aEntry.GetName( ((Storage*) this)->aName );
558cdf0e10cSrcweir 	return aName;
559cdf0e10cSrcweir }
560cdf0e10cSrcweir 
561cdf0e10cSrcweir // Fill in the info list for this storage
562cdf0e10cSrcweir 
FillInfoList(SvStorageInfoList * pList) const563cdf0e10cSrcweir void Storage::FillInfoList( SvStorageInfoList* pList ) const
564cdf0e10cSrcweir {
565*297a844aSArmin Le Grand 	if( Validate() && pList )
566cdf0e10cSrcweir     {
567cdf0e10cSrcweir         StgIterator aIter( *pEntry );
568cdf0e10cSrcweir         StgDirEntry* p = aIter.First();
569cdf0e10cSrcweir         while( p )
570cdf0e10cSrcweir         {
571cdf0e10cSrcweir             if( !p->bInvalid )
572cdf0e10cSrcweir 			{
573cdf0e10cSrcweir 				SvStorageInfo aInfo( *p );
574cdf0e10cSrcweir 				pList->Append( aInfo );
575cdf0e10cSrcweir 			}
576cdf0e10cSrcweir 			p = aIter.Next();
577cdf0e10cSrcweir         }
578cdf0e10cSrcweir     }
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir // Open or create a substorage
582cdf0e10cSrcweir 
OpenUCBStorage(const String & rName,StreamMode m,sal_Bool bDirect)583cdf0e10cSrcweir BaseStorage* Storage::OpenUCBStorage( const String& rName, StreamMode m, sal_Bool bDirect )
584cdf0e10cSrcweir {
585cdf0e10cSrcweir 	DBG_ERROR("Not supported!");
586cdf0e10cSrcweir /*
587cdf0e10cSrcweir 	BaseStorage* pStorage = new Storage( pIo, NULL, m );
588cdf0e10cSrcweir 	SetError( ERRCODE_IO_NOTSUPPORTED );
589cdf0e10cSrcweir 	return pStorage;
590cdf0e10cSrcweir  */
591cdf0e10cSrcweir     return OpenStorage( rName, m, bDirect );
592cdf0e10cSrcweir }
593cdf0e10cSrcweir 
OpenOLEStorage(const String & rName,StreamMode m,sal_Bool bDirect)594cdf0e10cSrcweir BaseStorage* Storage::OpenOLEStorage( const String& rName, StreamMode m, sal_Bool bDirect )
595cdf0e10cSrcweir {
596cdf0e10cSrcweir     return OpenStorage( rName, m, bDirect );
597cdf0e10cSrcweir }
598cdf0e10cSrcweir 
OpenStorage(const String & rName,StreamMode m,sal_Bool bDirect)599cdf0e10cSrcweir BaseStorage* Storage::OpenStorage( const String& rName, StreamMode m, sal_Bool bDirect )
600cdf0e10cSrcweir {
601cdf0e10cSrcweir     if( !Validate() || !ValidateMode( m ) )
602cdf0e10cSrcweir         return new Storage( pIo, NULL, m );
603cdf0e10cSrcweir 	sal_Bool bSetAutoCommit = sal_False;
604cdf0e10cSrcweir 	if( bDirect && !pEntry->bDirect )
605cdf0e10cSrcweir 	{
606cdf0e10cSrcweir 		bSetAutoCommit = sal_True;
607cdf0e10cSrcweir 		bDirect = sal_False;
608cdf0e10cSrcweir 	}
609cdf0e10cSrcweir 
610cdf0e10cSrcweir     StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
611cdf0e10cSrcweir     if( !p )
612cdf0e10cSrcweir     {
613cdf0e10cSrcweir         if( !( m & STREAM_NOCREATE ) )
614cdf0e10cSrcweir         {
615cdf0e10cSrcweir 			sal_Bool bTemp = sal_False;
616cdf0e10cSrcweir 			// create a new storage
617cdf0e10cSrcweir 			String aNewName = rName;
618cdf0e10cSrcweir 			if( !aNewName.Len() )
619cdf0e10cSrcweir 			{
620cdf0e10cSrcweir 				aNewName.AssignAscii( "Temp Stg " );
621cdf0e10cSrcweir 				aNewName.Append( String::CreateFromInt32( ++nTmpCount ) );
622cdf0e10cSrcweir 				bTemp = sal_True;
623cdf0e10cSrcweir 			}
624cdf0e10cSrcweir             p = pIo->pTOC->Create( *pEntry, aNewName, STG_STORAGE );
625cdf0e10cSrcweir             if( p )
626cdf0e10cSrcweir 				p->bTemp = bTemp;
627cdf0e10cSrcweir         }
628cdf0e10cSrcweir         if( !p )
629cdf0e10cSrcweir             pIo->SetError( ( m & STREAM_WRITE )
630cdf0e10cSrcweir 					         ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
631cdf0e10cSrcweir     }
632cdf0e10cSrcweir 	else if( !ValidateMode( m, p ) )
633cdf0e10cSrcweir 		p = NULL;
634cdf0e10cSrcweir     if( p && p->aEntry.GetType() != STG_STORAGE )
635cdf0e10cSrcweir     {
636cdf0e10cSrcweir         pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
637cdf0e10cSrcweir         p = NULL;
638cdf0e10cSrcweir     }
639cdf0e10cSrcweir 
640cdf0e10cSrcweir 	// Either direct or transacted mode is supported
641cdf0e10cSrcweir 	if( p && pEntry->nRefCnt == 1 )
642cdf0e10cSrcweir 		p->bDirect = bDirect;
643cdf0e10cSrcweir 
644cdf0e10cSrcweir 	// Dont check direct conflict if opening readonly
645cdf0e10cSrcweir 	if( p && (m & STREAM_WRITE ))
646cdf0e10cSrcweir 	{
647cdf0e10cSrcweir 		if( p->bDirect != bDirect )
648cdf0e10cSrcweir 			SetError( SVSTREAM_ACCESS_DENIED );
649cdf0e10cSrcweir 	}
650cdf0e10cSrcweir 	Storage* pStg = new Storage( pIo, p, m );
651cdf0e10cSrcweir 	pIo->MoveError( *pStg );
652cdf0e10cSrcweir 	if( m & STREAM_WRITE ) pStg->m_bAutoCommit = sal_True;
653cdf0e10cSrcweir 	return pStg;
654cdf0e10cSrcweir }
655cdf0e10cSrcweir 
656cdf0e10cSrcweir // Open a stream
657cdf0e10cSrcweir 
OpenStream(const String & rName,StreamMode m,sal_Bool,const ByteString * pB)658cdf0e10cSrcweir BaseStorageStream* Storage::OpenStream( const String& rName, StreamMode m, sal_Bool,
659cdf0e10cSrcweir const ByteString*
660cdf0e10cSrcweir #ifdef DBG_UTIL
661cdf0e10cSrcweir pB
662cdf0e10cSrcweir #endif
663cdf0e10cSrcweir )
664cdf0e10cSrcweir {
665cdf0e10cSrcweir     DBG_ASSERT(!pB, "Encryption not supported");
666cdf0e10cSrcweir 
667cdf0e10cSrcweir     if( !Validate() || !ValidateMode( m ) )
668cdf0e10cSrcweir         return new StorageStream( pIo, NULL, m );
669cdf0e10cSrcweir 	StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
670cdf0e10cSrcweir 	sal_Bool bTemp = sal_False;
671cdf0e10cSrcweir 	if( !p )
672cdf0e10cSrcweir     {
673cdf0e10cSrcweir         if( !( m & STREAM_NOCREATE ) )
674cdf0e10cSrcweir         {
675cdf0e10cSrcweir             // create a new stream
676cdf0e10cSrcweir 			// make a name if the stream is temporary (has no name)
677cdf0e10cSrcweir 			String aNewName( rName );
678cdf0e10cSrcweir 			if( !aNewName.Len() )
679cdf0e10cSrcweir 			{
680cdf0e10cSrcweir 				aNewName.AssignAscii( "Temp Strm " );
681cdf0e10cSrcweir 				aNewName.Append( String::CreateFromInt32( ++nTmpCount ) );
682cdf0e10cSrcweir 				bTemp = sal_True;
683cdf0e10cSrcweir 			}
684cdf0e10cSrcweir             p = pIo->pTOC->Create( *pEntry, aNewName, STG_STREAM );
685cdf0e10cSrcweir 		}
686cdf0e10cSrcweir         if( !p )
687cdf0e10cSrcweir             pIo->SetError( ( m & STREAM_WRITE )
688cdf0e10cSrcweir 						   ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
689cdf0e10cSrcweir     }
690cdf0e10cSrcweir 	else if( !ValidateMode( m, p ) )
691cdf0e10cSrcweir 		p = NULL;
692cdf0e10cSrcweir     if( p && p->aEntry.GetType() != STG_STREAM )
693cdf0e10cSrcweir     {
694cdf0e10cSrcweir         pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
695cdf0e10cSrcweir         p = NULL;
696cdf0e10cSrcweir     }
697cdf0e10cSrcweir 	if( p )
698cdf0e10cSrcweir 	{
699cdf0e10cSrcweir 		p->bTemp = bTemp;
700cdf0e10cSrcweir 		p->bDirect = pEntry->bDirect;
701cdf0e10cSrcweir 	}
702cdf0e10cSrcweir     StorageStream* pStm = new StorageStream( pIo, p, m );
703cdf0e10cSrcweir 	if( p && !p->bDirect )
704cdf0e10cSrcweir 		pStm->SetAutoCommit( sal_True );
705cdf0e10cSrcweir 	pIo->MoveError( *pStm );
706cdf0e10cSrcweir 	return pStm;
707cdf0e10cSrcweir }
708cdf0e10cSrcweir 
709cdf0e10cSrcweir // Delete a stream or substorage by setting the temp bit.
710cdf0e10cSrcweir 
Remove(const String & rName)711cdf0e10cSrcweir sal_Bool Storage::Remove( const String& rName )
712cdf0e10cSrcweir {
713cdf0e10cSrcweir 	if( !Validate( sal_True ) )
714cdf0e10cSrcweir         return sal_False;
715cdf0e10cSrcweir     StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
716cdf0e10cSrcweir 	if( p )
717cdf0e10cSrcweir 	{
718cdf0e10cSrcweir 		p->Invalidate( sal_True );
719cdf0e10cSrcweir 		return sal_True;
720cdf0e10cSrcweir 	}
721cdf0e10cSrcweir     else
722cdf0e10cSrcweir 	{
723cdf0e10cSrcweir         SetError( SVSTREAM_FILE_NOT_FOUND );
724cdf0e10cSrcweir 	    return sal_False;
725cdf0e10cSrcweir 	}
726cdf0e10cSrcweir }
727cdf0e10cSrcweir 
728cdf0e10cSrcweir // Rename a storage element
729cdf0e10cSrcweir 
Rename(const String & rOld,const String & rNew)730cdf0e10cSrcweir sal_Bool Storage::Rename( const String& rOld, const String& rNew )
731cdf0e10cSrcweir {
732cdf0e10cSrcweir 	if( Validate( sal_True ) )
733cdf0e10cSrcweir 	{
734cdf0e10cSrcweir 	    sal_Bool b = pIo->pTOC->Rename( *pEntry, rOld, rNew );
735cdf0e10cSrcweir 		pIo->MoveError( *this );
736cdf0e10cSrcweir 		return b;
737cdf0e10cSrcweir 	}
738cdf0e10cSrcweir 	else
739cdf0e10cSrcweir 		return sal_False;
740cdf0e10cSrcweir }
741cdf0e10cSrcweir 
742cdf0e10cSrcweir // Copy one element
743cdf0e10cSrcweir 
CopyTo(const String & rElem,BaseStorage * pDest,const String & rNew)744cdf0e10cSrcweir sal_Bool Storage::CopyTo( const String& rElem, BaseStorage* pDest, const String& rNew )
745cdf0e10cSrcweir {
746cdf0e10cSrcweir     if( !Validate() || !pDest || !pDest->Validate( sal_True ) )
747cdf0e10cSrcweir         return sal_False;
748cdf0e10cSrcweir 	StgDirEntry* pElem = pIo->pTOC->Find( *pEntry, rElem );
749cdf0e10cSrcweir     if( pElem )
750cdf0e10cSrcweir     {
751cdf0e10cSrcweir 		/*
752cdf0e10cSrcweir 		this lines are misterious !!! MM
753cdf0e10cSrcweir         if( !pElem->IsContained( pDest->pEntry ) )
754cdf0e10cSrcweir         {
755cdf0e10cSrcweir             SetError( SVSTREAM_ACCESS_DENIED );
756cdf0e10cSrcweir             return sal_False;
757cdf0e10cSrcweir         }
758cdf0e10cSrcweir 		*/
759cdf0e10cSrcweir         if( pElem->aEntry.GetType() == STG_STORAGE )
760cdf0e10cSrcweir         {
761cdf0e10cSrcweir             // copy the entire storage
762cdf0e10cSrcweir             BaseStorage* p1 = OpenStorage( rElem, INTERNAL_MODE );
763cdf0e10cSrcweir             BaseStorage* p2 = pDest->OpenOLEStorage( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
764cdf0e10cSrcweir 
765*297a844aSArmin Le Grand             if ( p2 )
766*297a844aSArmin Le Grand             {
767*297a844aSArmin Le Grand                 sal_uLong nTmpErr = p2->GetError();
768*297a844aSArmin Le Grand                 if( !nTmpErr )
769*297a844aSArmin Le Grand                 {
770*297a844aSArmin Le Grand                     p2->SetClassId( p1->GetClassId() );
771*297a844aSArmin Le Grand                     p1->CopyTo( p2 );
772*297a844aSArmin Le Grand                     SetError( p1->GetError() );
773*297a844aSArmin Le Grand 
774*297a844aSArmin Le Grand                     nTmpErr = p2->GetError();
775*297a844aSArmin Le Grand                     if( !nTmpErr )
776*297a844aSArmin Le Grand                         p2->Commit();
777*297a844aSArmin Le Grand                     else
778*297a844aSArmin Le Grand                         pDest->SetError( nTmpErr );
779*297a844aSArmin Le Grand                 }
780*297a844aSArmin Le Grand                 else
781*297a844aSArmin Le Grand                     pDest->SetError( nTmpErr );
782*297a844aSArmin Le Grand             }
783cdf0e10cSrcweir 
784cdf0e10cSrcweir 			delete p1;
785cdf0e10cSrcweir 			delete p2;
786cdf0e10cSrcweir             return sal_Bool( Good() && pDest->Good() );
787cdf0e10cSrcweir         }
788cdf0e10cSrcweir         else
789cdf0e10cSrcweir         {
790cdf0e10cSrcweir             // stream copy
791cdf0e10cSrcweir             BaseStorageStream* p1 = OpenStream( rElem, INTERNAL_MODE );
792cdf0e10cSrcweir             BaseStorageStream* p2 = pDest->OpenStream( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
793cdf0e10cSrcweir 
794*297a844aSArmin Le Grand             if ( p2 )
795*297a844aSArmin Le Grand             {
796*297a844aSArmin Le Grand                 sal_uLong nTmpErr = p2->GetError();
797*297a844aSArmin Le Grand                 if( !nTmpErr )
798*297a844aSArmin Le Grand                 {
799*297a844aSArmin Le Grand                     p1->CopyTo( p2 );
800*297a844aSArmin Le Grand                     SetError( p1->GetError() );
801*297a844aSArmin Le Grand 
802*297a844aSArmin Le Grand                     nTmpErr = p2->GetError();
803*297a844aSArmin Le Grand                     if( !nTmpErr )
804*297a844aSArmin Le Grand                         p2->Commit();
805*297a844aSArmin Le Grand                     else
806*297a844aSArmin Le Grand                         pDest->SetError( nTmpErr );
807*297a844aSArmin Le Grand                 }
808*297a844aSArmin Le Grand                 else
809*297a844aSArmin Le Grand                     pDest->SetError( nTmpErr );
810*297a844aSArmin Le Grand             }
811cdf0e10cSrcweir 
812cdf0e10cSrcweir 			delete p1;
813cdf0e10cSrcweir 			delete p2;
814cdf0e10cSrcweir             return sal_Bool( Good() && pDest->Good() );
815cdf0e10cSrcweir         }
816cdf0e10cSrcweir     }
817cdf0e10cSrcweir     SetError( SVSTREAM_FILE_NOT_FOUND );
818cdf0e10cSrcweir     return sal_False;
819cdf0e10cSrcweir }
820cdf0e10cSrcweir 
CopyTo(BaseStorage * pDest) const821cdf0e10cSrcweir sal_Bool Storage::CopyTo( BaseStorage* pDest ) const
822cdf0e10cSrcweir {
823cdf0e10cSrcweir     if( !Validate() || !pDest || !pDest->Validate( sal_True ) || Equals( *pDest ) )
824cdf0e10cSrcweir     {
825cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
826cdf0e10cSrcweir         return sal_False;
827cdf0e10cSrcweir     }
828cdf0e10cSrcweir     Storage* pThis = (Storage*) this;
829cdf0e10cSrcweir 	/*
830cdf0e10cSrcweir     if( !pThis->pEntry->IsContained( pDest->pEntry ) )
831cdf0e10cSrcweir     {
832cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
833cdf0e10cSrcweir         return sal_False;
834cdf0e10cSrcweir     }
835cdf0e10cSrcweir 	*/
836cdf0e10cSrcweir     pDest->SetClassId( GetClassId() );
837cdf0e10cSrcweir     pDest->SetDirty();
838cdf0e10cSrcweir     SvStorageInfoList aList;
839cdf0e10cSrcweir     FillInfoList( &aList );
840cdf0e10cSrcweir 	sal_Bool bRes = sal_True;
841cdf0e10cSrcweir     for( sal_uInt16 i = 0; i < aList.Count() && bRes; i++ )
842cdf0e10cSrcweir     {
843cdf0e10cSrcweir         SvStorageInfo& rInfo = aList.GetObject( i );
844cdf0e10cSrcweir         bRes = pThis->CopyTo( rInfo.GetName(), pDest, rInfo.GetName() );
845cdf0e10cSrcweir     }
846cdf0e10cSrcweir 	if( !bRes )
847cdf0e10cSrcweir 		SetError( pDest->GetError() );
848cdf0e10cSrcweir     return sal_Bool( Good() && pDest->Good() );
849cdf0e10cSrcweir }
850cdf0e10cSrcweir 
851cdf0e10cSrcweir // Move one element
852cdf0e10cSrcweir 
MoveTo(const String & rElem,BaseStorage * pODest,const String & rNew)853cdf0e10cSrcweir sal_Bool Storage::MoveTo( const String& rElem, BaseStorage* pODest, const String& rNew )
854cdf0e10cSrcweir {
855cdf0e10cSrcweir     if( !Validate() || !pODest || !pODest->Validate( sal_True ) || Equals( *pODest ) )
856cdf0e10cSrcweir     {
857cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
858cdf0e10cSrcweir         return sal_False;
859cdf0e10cSrcweir     }
860cdf0e10cSrcweir 
861cdf0e10cSrcweir     StgDirEntry* pElem = pIo->pTOC->Find( *pEntry, rElem );
862cdf0e10cSrcweir     if( pElem )
863cdf0e10cSrcweir     {
864cdf0e10cSrcweir         // Simplest case: both storages share the same file
865cdf0e10cSrcweir 		sal_Bool bRes;
866cdf0e10cSrcweir         Storage *pOther = PTR_CAST( Storage, pODest );
867cdf0e10cSrcweir         if( pOther && pIo == pOther->pIo && rElem == rNew )
868cdf0e10cSrcweir         {
869cdf0e10cSrcweir             Storage *p = (Storage*) pODest;
870cdf0e10cSrcweir             Storage *pDest = p;
871cdf0e10cSrcweir             // both storages are conventional storages, use implementation dependent code
872cdf0e10cSrcweir             if( !pElem->IsContained( pDest->pEntry ) )
873cdf0e10cSrcweir             {
874cdf0e10cSrcweir 				// cyclic move
875cdf0e10cSrcweir 				SetError( SVSTREAM_ACCESS_DENIED );
876cdf0e10cSrcweir                 return sal_False;
877cdf0e10cSrcweir             }
878cdf0e10cSrcweir 			bRes = pIo->pTOC->Move( *pEntry, *pDest->pEntry, rNew );
879cdf0e10cSrcweir 			if( !bRes )
880cdf0e10cSrcweir 			{
881cdf0e10cSrcweir 				pIo->MoveError( *this );
882cdf0e10cSrcweir 				pDest->pIo->MoveError( *pDest );
883cdf0e10cSrcweir 				sal_uLong nErr = GetError();
884cdf0e10cSrcweir 				if( !nErr )
885cdf0e10cSrcweir 					nErr = pDest->GetError();
886cdf0e10cSrcweir 				SetError( nErr );
887cdf0e10cSrcweir 				pDest->SetError( nErr );
888cdf0e10cSrcweir 			}
889cdf0e10cSrcweir 		}
890cdf0e10cSrcweir         else
891cdf0e10cSrcweir         {
892cdf0e10cSrcweir 			bRes = CopyTo( rElem, pODest, rNew );
893cdf0e10cSrcweir 			if( bRes )
894cdf0e10cSrcweir 				bRes = Remove( rElem );
895cdf0e10cSrcweir 		}
896cdf0e10cSrcweir 		if( !bRes )
897cdf0e10cSrcweir 			SetError( pIo->GetError() );
898cdf0e10cSrcweir 		return bRes;
899cdf0e10cSrcweir     }
900cdf0e10cSrcweir     SetError( SVSTREAM_FILE_NOT_FOUND );
901cdf0e10cSrcweir     return sal_False;
902cdf0e10cSrcweir }
903cdf0e10cSrcweir 
IsStorage(const String & rName) const904cdf0e10cSrcweir sal_Bool Storage::IsStorage( const String& rName ) const
905cdf0e10cSrcweir {
906cdf0e10cSrcweir     if( Validate() )
907cdf0e10cSrcweir     {
908cdf0e10cSrcweir         StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
909cdf0e10cSrcweir         if( p )
910cdf0e10cSrcweir             return sal_Bool( p->aEntry.GetType() == STG_STORAGE );
911cdf0e10cSrcweir     }
912cdf0e10cSrcweir     return sal_False;
913cdf0e10cSrcweir }
914cdf0e10cSrcweir 
IsStream(const String & rName) const915cdf0e10cSrcweir sal_Bool Storage::IsStream( const String& rName ) const
916cdf0e10cSrcweir {
917cdf0e10cSrcweir     if( Validate() )
918cdf0e10cSrcweir     {
919cdf0e10cSrcweir         StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
920cdf0e10cSrcweir         if( p )
921cdf0e10cSrcweir             return sal_Bool( p->aEntry.GetType() == STG_STREAM );
922cdf0e10cSrcweir     }
923cdf0e10cSrcweir     return sal_False;
924cdf0e10cSrcweir }
925cdf0e10cSrcweir 
IsContained(const String & rName) const926cdf0e10cSrcweir sal_Bool Storage::IsContained( const String& rName ) const
927cdf0e10cSrcweir {
928cdf0e10cSrcweir     if( Validate() )
929cdf0e10cSrcweir         return sal_Bool( pIo->pTOC->Find( *pEntry, rName ) != NULL );
930cdf0e10cSrcweir     else
931cdf0e10cSrcweir         return sal_False;
932cdf0e10cSrcweir }
933cdf0e10cSrcweir 
934cdf0e10cSrcweir // Commit all sub-elements within this storage. If this is
935cdf0e10cSrcweir // the root, commit the FAT, the TOC and the header as well.
936cdf0e10cSrcweir 
Commit()937cdf0e10cSrcweir sal_Bool Storage::Commit()
938cdf0e10cSrcweir {
939cdf0e10cSrcweir 	sal_Bool bRes = sal_True;
940cdf0e10cSrcweir 	if( !Validate() )
941cdf0e10cSrcweir 		return sal_False;
942cdf0e10cSrcweir 	if( !( m_nMode & STREAM_WRITE ) )
943cdf0e10cSrcweir 	{
944cdf0e10cSrcweir 		SetError( SVSTREAM_ACCESS_DENIED );
945cdf0e10cSrcweir 		return sal_False;
946cdf0e10cSrcweir 	}
947cdf0e10cSrcweir 	else
948cdf0e10cSrcweir 	{
949cdf0e10cSrcweir 		// Also commit the sub-streams and Storages
950cdf0e10cSrcweir 		StgIterator aIter( *pEntry );
951cdf0e10cSrcweir 		for( StgDirEntry* p = aIter.First(); p && bRes; p = aIter.Next() )
952cdf0e10cSrcweir 			bRes = p->Commit();
953cdf0e10cSrcweir 		if( bRes && bIsRoot )
954cdf0e10cSrcweir 		{
955cdf0e10cSrcweir 			bRes = pEntry->Commit();
956cdf0e10cSrcweir 			if( bRes )
957cdf0e10cSrcweir 				bRes = pIo->CommitAll();
958cdf0e10cSrcweir 		}
959cdf0e10cSrcweir 		pIo->MoveError( *this );
960cdf0e10cSrcweir 	}
961cdf0e10cSrcweir 	return bRes;
962cdf0e10cSrcweir }
963cdf0e10cSrcweir 
Revert()964cdf0e10cSrcweir sal_Bool Storage::Revert()
965cdf0e10cSrcweir {
966cdf0e10cSrcweir 	return sal_True;
967cdf0e10cSrcweir }
968cdf0e10cSrcweir 
969cdf0e10cSrcweir ///////////////////////////// OLE Support ////////////////////////////////
970cdf0e10cSrcweir 
971cdf0e10cSrcweir // Set the storage type
972cdf0e10cSrcweir 
SetClass(const SvGlobalName & rClass,sal_uLong nOriginalClipFormat,const String & rUserTypeName)973cdf0e10cSrcweir void Storage::SetClass( const SvGlobalName & rClass,
974cdf0e10cSrcweir                                 sal_uLong nOriginalClipFormat,
975cdf0e10cSrcweir                                 const String & rUserTypeName )
976cdf0e10cSrcweir {
977cdf0e10cSrcweir 	if( Validate( sal_True ) )
978cdf0e10cSrcweir 	{
979cdf0e10cSrcweir 		// set the class name in the root entry
980cdf0e10cSrcweir 		pEntry->aEntry.SetClassId( (const ClsId&) rClass.GetCLSID() );
981cdf0e10cSrcweir 		pEntry->SetDirty();
982cdf0e10cSrcweir 		// then create the streams
983cdf0e10cSrcweir 		StgCompObjStream aCompObj( *this, sal_True );
984cdf0e10cSrcweir 		aCompObj.GetClsId() = (const ClsId&) rClass.GetCLSID();
985cdf0e10cSrcweir 		aCompObj.GetCbFormat() = nOriginalClipFormat;
986cdf0e10cSrcweir 		aCompObj.GetUserName() = rUserTypeName;
987cdf0e10cSrcweir 		if( !aCompObj.Store() )
988cdf0e10cSrcweir 			SetError( aCompObj.GetError() );
989cdf0e10cSrcweir 		else
990cdf0e10cSrcweir 		{
991cdf0e10cSrcweir 			StgOleStream aOle( *this, STREAM_WRITE );
992cdf0e10cSrcweir 			if( !aOle.Store() )
993cdf0e10cSrcweir 				SetError( aOle.GetError() );
994cdf0e10cSrcweir 		}
995cdf0e10cSrcweir 	}
996cdf0e10cSrcweir 	else
997cdf0e10cSrcweir 		SetError( SVSTREAM_ACCESS_DENIED );
998cdf0e10cSrcweir }
999cdf0e10cSrcweir 
SetConvertClass(const SvGlobalName & rConvertClass,sal_uLong nOriginalClipFormat,const String & rUserTypeName)1000cdf0e10cSrcweir void Storage::SetConvertClass( const SvGlobalName & rConvertClass,
1001cdf0e10cSrcweir                                        sal_uLong nOriginalClipFormat,
1002cdf0e10cSrcweir                                        const String & rUserTypeName )
1003cdf0e10cSrcweir {
1004cdf0e10cSrcweir 	if( Validate( sal_True ) )
1005cdf0e10cSrcweir 	{
1006cdf0e10cSrcweir 		SetClass( rConvertClass, nOriginalClipFormat, rUserTypeName );
1007cdf0e10cSrcweir 		// plus the convert flag:
1008cdf0e10cSrcweir 		StgOleStream aOle( *this, sal_True );
1009cdf0e10cSrcweir 		aOle.GetFlags() |= 4;
1010cdf0e10cSrcweir 		if( !aOle.Store() )
1011cdf0e10cSrcweir 			SetError( aOle.GetError() );
1012cdf0e10cSrcweir 	}
1013cdf0e10cSrcweir }
1014cdf0e10cSrcweir 
GetClassName()1015cdf0e10cSrcweir SvGlobalName Storage::GetClassName()
1016cdf0e10cSrcweir {
1017cdf0e10cSrcweir 	StgCompObjStream aCompObj( *this, sal_False );
1018cdf0e10cSrcweir 	if( aCompObj.Load() )
1019cdf0e10cSrcweir 		return SvGlobalName( (const CLSID&) aCompObj.GetClsId() );
1020cdf0e10cSrcweir 	pIo->ResetError();
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir 	if ( pEntry )
1023cdf0e10cSrcweir 		return SvGlobalName( (const CLSID&) pEntry->aEntry.GetClassId() );
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir 	return SvGlobalName();
1026cdf0e10cSrcweir }
1027cdf0e10cSrcweir 
GetFormat()1028cdf0e10cSrcweir sal_uLong Storage::GetFormat()
1029cdf0e10cSrcweir {
1030cdf0e10cSrcweir 	StgCompObjStream aCompObj( *this, sal_False );
1031cdf0e10cSrcweir 	if( aCompObj.Load() )
1032cdf0e10cSrcweir 		return aCompObj.GetCbFormat();
1033cdf0e10cSrcweir 	pIo->ResetError();
1034cdf0e10cSrcweir 	return 0;
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir 
GetUserName()1037cdf0e10cSrcweir String Storage::GetUserName()
1038cdf0e10cSrcweir {
1039cdf0e10cSrcweir 	StgCompObjStream aCompObj( *this, sal_False );
1040cdf0e10cSrcweir 	if( aCompObj.Load() )
1041cdf0e10cSrcweir 		return aCompObj.GetUserName();
1042cdf0e10cSrcweir 	pIo->ResetError();
1043cdf0e10cSrcweir 	return String();
1044cdf0e10cSrcweir }
1045cdf0e10cSrcweir 
ShouldConvert()1046cdf0e10cSrcweir sal_Bool Storage::ShouldConvert()
1047cdf0e10cSrcweir {
1048cdf0e10cSrcweir 	StgOleStream aOle( *this, sal_False );
1049cdf0e10cSrcweir 	if( aOle.Load() )
1050cdf0e10cSrcweir 		return sal_Bool( ( aOle.GetFlags() & 4 ) != 0 );
1051cdf0e10cSrcweir 	else
1052cdf0e10cSrcweir 	{
1053cdf0e10cSrcweir 		pIo->ResetError();
1054cdf0e10cSrcweir 		return sal_False;
1055cdf0e10cSrcweir 	}
1056cdf0e10cSrcweir }
1057cdf0e10cSrcweir 
ValidateFAT()1058cdf0e10cSrcweir sal_Bool Storage::ValidateFAT()
1059cdf0e10cSrcweir {
1060cdf0e10cSrcweir 	Link aLink = StgIo::GetErrorLink();
1061cdf0e10cSrcweir 	ErrCode nErr = pIo->ValidateFATs();
1062cdf0e10cSrcweir 	StgIo::SetErrorLink( aLink );
1063cdf0e10cSrcweir 	return nErr == ERRCODE_NONE;
1064cdf0e10cSrcweir }
1065cdf0e10cSrcweir 
SetDirty()1066cdf0e10cSrcweir void Storage::SetDirty()
1067cdf0e10cSrcweir {
1068*297a844aSArmin Le Grand     if ( pEntry )
1069*297a844aSArmin Le Grand         pEntry->SetDirty();
1070cdf0e10cSrcweir }
1071cdf0e10cSrcweir 
SetClassId(const ClsId & rId)1072cdf0e10cSrcweir void Storage::SetClassId( const ClsId& rId )
1073cdf0e10cSrcweir {
1074*297a844aSArmin Le Grand     if ( pEntry )
1075*297a844aSArmin Le Grand         pEntry->aEntry.SetClassId( rId );
1076cdf0e10cSrcweir }
1077cdf0e10cSrcweir 
GetClassId() const1078cdf0e10cSrcweir const ClsId& Storage::GetClassId() const
1079cdf0e10cSrcweir {
1080*297a844aSArmin Le Grand     if ( pEntry )
1081*297a844aSArmin Le Grand         return pEntry->aEntry.GetClassId();
1082*297a844aSArmin Le Grand 
1083*297a844aSArmin Le Grand     static ClsId aDummyId = {0,0,0,0,0,0,0,0,0,0,0};
1084*297a844aSArmin Le Grand     return aDummyId;
1085cdf0e10cSrcweir }
1086cdf0e10cSrcweir 
GetSvStream() const1087cdf0e10cSrcweir const SvStream* Storage::GetSvStream() const
1088cdf0e10cSrcweir {
1089cdf0e10cSrcweir     return GetSvStream_Impl();
1090cdf0e10cSrcweir }
1091cdf0e10cSrcweir 
Validate(sal_Bool bValidate) const1092cdf0e10cSrcweir sal_Bool Storage::Validate( sal_Bool bValidate ) const
1093cdf0e10cSrcweir {
1094cdf0e10cSrcweir     sal_Bool bRet = Validate_Impl( bValidate );
1095cdf0e10cSrcweir     if ( !bRet )
1096cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
1097cdf0e10cSrcweir     return bRet;
1098cdf0e10cSrcweir }
1099cdf0e10cSrcweir 
ValidateMode(StreamMode nMode) const1100cdf0e10cSrcweir sal_Bool Storage::ValidateMode( StreamMode nMode ) const
1101cdf0e10cSrcweir {
1102cdf0e10cSrcweir     sal_Bool bRet = ValidateMode_Impl( nMode );
1103cdf0e10cSrcweir     if ( !bRet )
1104cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
1105cdf0e10cSrcweir     return bRet;
1106cdf0e10cSrcweir }
1107cdf0e10cSrcweir 
ValidateMode(StreamMode nMode,StgDirEntry * p) const1108cdf0e10cSrcweir sal_Bool Storage::ValidateMode( StreamMode nMode, StgDirEntry* p ) const
1109cdf0e10cSrcweir {
1110cdf0e10cSrcweir     sal_Bool bRet = ValidateMode_Impl( nMode, p );
1111cdf0e10cSrcweir     if ( !bRet )
1112cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
1113cdf0e10cSrcweir     return bRet;
1114cdf0e10cSrcweir }
1115cdf0e10cSrcweir 
Equals(const BaseStorage & rStorage) const1116cdf0e10cSrcweir sal_Bool Storage::Equals( const BaseStorage& rStorage ) const
1117cdf0e10cSrcweir {
1118cdf0e10cSrcweir     const Storage* pOther = PTR_CAST( Storage, &rStorage );
1119cdf0e10cSrcweir     return pOther && ( pOther->pEntry == pEntry );
1120cdf0e10cSrcweir }
1121cdf0e10cSrcweir 
1122cdf0e10cSrcweir 
1123