1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sot/storinfo.hxx>
22 #include <osl/file.hxx>
23 #include <unotools/tempfile.hxx>
24 #include <tools/stream.hxx>
25 #include <tools/debug.hxx>
27 #include "sot/stg.hxx"
28 #include "stgelem.hxx"
29 #include "stgcache.hxx"
30 #include "stgstrms.hxx"
35 static long nTmpCount
= 0;
37 // The internal open mode is STREAM_READ | STREAM_TRUNC, which is silly
38 // by itself. It inhibits the checking of sharing modes and is used
39 // during CopyTo() and MoveTo() for opening a stream in read mode
40 // although it may be open in DENYALL mode
42 #define INTERNAL_MODE ( STREAM_READ | STREAM_TRUNC )
44 ///////////////////////// class StorageBase //////////////////////////////
46 TYPEINIT0( StorageBase
);
47 TYPEINIT1( BaseStorageStream
, StorageBase
);
48 TYPEINIT1( BaseStorage
, StorageBase
);
50 StorageBase::StorageBase()
51 : m_bAutoCommit( false )
53 m_nMode
= STREAM_READ
;
54 m_nError
= SVSTREAM_OK
;
57 StorageBase::~StorageBase()
61 // The following three methods are declared as const, since they
62 // may be called from within a const method.
64 sal_uLong
StorageBase::GetError() const
66 sal_uLong n
= m_nError
;
67 ((StorageBase
*) this)->m_nError
= SVSTREAM_OK
;
71 void StorageBase::SetError( sal_uLong n
) const
74 ((StorageBase
*) this)->m_nError
= n
;
77 void StorageBase::ResetError() const
79 ((StorageBase
*) this)->m_nError
= SVSTREAM_OK
;
82 // Retrieve the underlying SvStream for info purposes
84 const SvStream
* OLEStorageBase::GetSvStream_Impl() const
86 return pIo
? pIo
->GetStrm() : NULL
;
89 OLEStorageBase::OLEStorageBase( StgIo
* p
, StgDirEntry
* pe
, StreamMode
& nMode
)
90 : nStreamMode( nMode
), pIo( p
), pEntry( pe
)
98 OLEStorageBase::~OLEStorageBase()
102 DBG_ASSERT( pEntry
->nRefCnt
, "RefCount unter 0" );
103 if( !--pEntry
->nRefCnt
)
105 if( pEntry
->bZombie
)
115 if( pIo
&& !pIo
->DecRef() )
122 // Validate the instance for I/O
124 bool OLEStorageBase::Validate_Impl( bool bWrite
) const
130 && ( !bWrite
|| !pEntry
->bDirect
|| ( nStreamMode
& STREAM_WRITE
) ) )
135 bool OLEStorageBase::ValidateMode_Impl( StreamMode m
, StgDirEntry
* p
) const
137 if( m
== INTERNAL_MODE
)
139 sal_uInt16 nCurMode
= ( p
&& p
->nRefCnt
) ? p
->nMode
: 0xFFFF;
140 if( ( m
& 3 ) == STREAM_READ
)
142 // only SHARE_DENYWRITE or SHARE_DENYALL allowed
143 if( ( ( m
& STREAM_SHARE_DENYWRITE
)
144 && ( nCurMode
& STREAM_SHARE_DENYWRITE
) )
145 || ( ( m
& STREAM_SHARE_DENYALL
)
146 && ( nCurMode
& STREAM_SHARE_DENYALL
) ) )
151 // only SHARE_DENYALL allowed
152 // storages open in r/o mode are OK, since only
153 // the commit may fail
154 if( ( m
& STREAM_SHARE_DENYALL
)
155 && ( nCurMode
& STREAM_SHARE_DENYALL
) )
162 //////////////////////// class StorageStream /////////////////////////////
164 TYPEINIT1( StorageStream
, BaseStorageStream
);
166 StorageStream::StorageStream( StgIo
* p
, StgDirEntry
* q
, StreamMode m
)
167 : OLEStorageBase( p
, q
, m_nMode
), nPos( 0L )
169 // The dir entry may be 0; this means that the stream is invalid.
172 if( q
->nRefCnt
== 1 )
179 m
&= ~STREAM_READWRITE
;
183 StorageStream::~StorageStream()
185 // Do an auto-commit if the entry is open in direct mode
188 if( pEntry
&& pEntry
->nRefCnt
&& pEntry
->bDirect
&& (m_nMode
& STREAM_WRITE
) )
192 bool StorageStream::Equals( const BaseStorageStream
& rStream
) const
194 const StorageStream
* pOther
= PTR_CAST( StorageStream
, &rStream
);
195 return pOther
&& ( pOther
->pEntry
== pEntry
);
198 sal_uLong
StorageStream::Read( void* pData
, sal_uLong nSize
)
202 pEntry
->Seek( nPos
);
203 nSize
= pEntry
->Read( pData
, (sal_Int32
) nSize
);
204 pIo
->MoveError( *this );
212 sal_uLong
StorageStream::Write( const void* pData
, sal_uLong nSize
)
214 if( Validate( true ) )
216 pEntry
->Seek( nPos
);
217 nSize
= pEntry
->Write( pData
, (sal_Int32
) nSize
);
218 pIo
->MoveError( *this );
226 sal_uLong
StorageStream::Seek( sal_uLong n
)
229 return nPos
= pEntry
->Seek( n
);
234 void StorageStream::Flush()
236 // Flushing means committing, since streams are never transacted
240 bool StorageStream::SetSize( sal_uLong nNewSize
)
242 if( Validate( true ) )
244 bool b
= pEntry
->SetSize( (sal_Int32
) nNewSize
);
245 pIo
->MoveError( *this );
252 sal_uLong
StorageStream::GetSize() const
255 return pEntry
->GetSize();
259 bool StorageStream::Commit()
263 if( !( m_nMode
& STREAM_WRITE
) )
265 SetError( SVSTREAM_ACCESS_DENIED
);
271 pIo
->MoveError( *this );
276 bool StorageStream::Revert()
278 bool bResult
= false;
283 pIo
->MoveError( *this );
290 bool StorageStream::CopyTo( BaseStorageStream
* pDest
)
292 if( !Validate() || !pDest
|| !pDest
->Validate( true ) || Equals( *pDest
) )
294 pEntry
->Copy( *pDest
);
296 pIo
->MoveError( *this );
297 SetError( pDest
->GetError() );
298 return Good() && pDest
->Good();
301 const SvStream
* StorageStream::GetSvStream() const
303 return GetSvStream_Impl();
306 bool StorageStream::Validate( bool bValidate
) const
308 bool bRet
= Validate_Impl( bValidate
);
310 SetError( SVSTREAM_ACCESS_DENIED
);
314 bool StorageStream::ValidateMode( StreamMode nMode
) const
316 bool bRet
= ValidateMode_Impl( nMode
, NULL
);
318 SetError( SVSTREAM_ACCESS_DENIED
);
322 ///////////////////////// class SvStorageInfo //////////////////////////////
324 SvStorageInfo::SvStorageInfo( const StgDirEntry
& rE
)
326 rE
.aEntry
.GetName( aName
);
327 bStorage
= rE
.aEntry
.GetType() == STG_STORAGE
;
328 bStream
= rE
.aEntry
.GetType() == STG_STREAM
;
329 nSize
= bStorage
? 0 : rE
.aEntry
.GetSize();
332 /////////////////////////// class Storage ////////////////////////////////
334 bool Storage::IsStorageFile( const OUString
& rFileName
)
337 if( aIo
.Open( rFileName
, STREAM_STD_READ
) )
342 bool Storage::IsStorageFile( SvStream
* pStream
)
349 sal_uLong nPos
= pStream
->Tell();
350 bRet
= ( aHdr
.Load( *pStream
) && aHdr
.Check() );
352 // It's not a stream error if it is too small for a OLE storage header
353 if ( pStream
->GetErrorCode() == ERRCODE_IO_CANTSEEK
)
354 pStream
->ResetError();
355 pStream
->Seek( nPos
);
361 // Open the storage file. If writing is permitted and the file is not
362 // a storage file, initialize it.
364 TYPEINIT1( Storage
, BaseStorage
);
366 Storage::Storage( const OUString
& rFile
, StreamMode m
, bool bDirect
)
367 : OLEStorageBase( new StgIo
, NULL
, m_nMode
)
368 , aName( rFile
), bIsRoot( false )
371 if( aName
.isEmpty() )
373 // no name = temporary name!
374 aName
= utl::TempFile::CreateTempName();
377 // the root storage creates the I/O system
379 if( pIo
->Open( aName
, m
) )
381 Init( ( m
& ( STREAM_TRUNC
| STREAM_NOCREATE
) ) == STREAM_TRUNC
);
384 pEntry
->bDirect
= bDirect
;
386 pEntry
->bTemp
= bTemp
;
391 pIo
->MoveError( *this );
396 // Create a storage on a given stream.
398 Storage::Storage( SvStream
& r
, bool bDirect
)
399 : OLEStorageBase( new StgIo
, NULL
, m_nMode
)
402 m_nMode
= STREAM_READ
;
404 m_nMode
= STREAM_READ
| STREAM_WRITE
;
405 if( r
.GetError() == SVSTREAM_OK
)
407 pIo
->SetStrm( &r
, false );
408 sal_uLong nSize
= r
.Seek( STREAM_SEEK_TO_END
);
410 // Initializing is OK if the stream is empty
414 pEntry
->bDirect
= bDirect
;
415 pEntry
->nMode
= m_nMode
;
417 pIo
->MoveError( *this );
421 SetError( r
.GetError() );
427 Storage::Storage( UCBStorageStream
& rStrm
, bool bDirect
)
428 : OLEStorageBase( new StgIo
, NULL
, m_nMode
), bIsRoot( false )
430 m_nMode
= STREAM_READ
;
432 if ( rStrm
.GetError() != SVSTREAM_OK
)
434 SetError( rStrm
.GetError() );
439 SvStream
* pStream
= rStrm
.GetModifySvStream();
442 OSL_FAIL( "UCBStorageStream can not provide SvStream implementation!\n" );
443 SetError( SVSTREAM_GENERALERROR
);
448 if( pStream
->IsWritable() )
449 m_nMode
= STREAM_READ
| STREAM_WRITE
;
451 pIo
->SetStrm( &rStrm
);
453 sal_uLong nSize
= pStream
->Seek( STREAM_SEEK_TO_END
);
455 // Initializing is OK if the stream is empty
459 pEntry
->bDirect
= bDirect
;
460 pEntry
->nMode
= m_nMode
;
463 pIo
->MoveError( *this );
467 // Perform common code for both ctors above.
469 void Storage::Init( bool bCreate
)
472 bool bHdrLoaded
= false;
475 OSL_ENSURE( pIo
, "The pointer may not be empty at this point!" );
476 if( pIo
->Good() && pIo
->GetStrm() )
478 sal_uLong nSize
= pIo
->GetStrm()->Seek( STREAM_SEEK_TO_END
);
479 pIo
->GetStrm()->Seek( 0L );
482 bHdrLoaded
= pIo
->Load();
483 if( !bHdrLoaded
&& !bCreate
)
485 // File is not a storage and not empty; do not destroy!
486 SetError( SVSTREAM_FILEFORMAT_ERROR
);
491 // file is a storage, empty or should be overwritten
493 // we have to set up the data structures, since
497 if( pIo
->Good() && pIo
->pTOC
)
499 pEntry
= pIo
->pTOC
->GetRoot();
506 Storage::Storage( StgIo
* p
, StgDirEntry
* q
, StreamMode m
)
507 : OLEStorageBase( p
, q
, m_nMode
), bIsRoot( false )
510 q
->aEntry
.GetName( aName
);
512 m
&= ~STREAM_READWRITE
;
514 if( q
&& q
->nRefCnt
== 1 )
520 // Invalidate all open substorages
525 // Do an auto-commit if the entry is open in direct mode
526 if( pEntry
->nRefCnt
&& pEntry
->bDirect
&& (m_nMode
& STREAM_WRITE
) )
528 if( pEntry
->nRefCnt
== 1 )
529 pEntry
->Invalidate();
531 // close the stream is root storage
534 // remove the file if temporary root storage
535 if( bIsRoot
&& pEntry
&& pEntry
->bTemp
)
537 osl::File::remove( GetName() );
541 const OUString
& Storage::GetName() const
543 if( !bIsRoot
&& Validate() )
544 pEntry
->aEntry
.GetName( ((Storage
*) this)->aName
);
548 // Fill in the info list for this storage
550 void Storage::FillInfoList( SvStorageInfoList
* pList
) const
552 if( Validate() && pList
)
554 StgIterator
aIter( *pEntry
);
555 StgDirEntry
* p
= aIter
.First();
560 SvStorageInfo
aInfo( *p
);
561 pList
->push_back( aInfo
);
568 // Open or create a substorage
570 BaseStorage
* Storage::OpenUCBStorage( const OUString
& rName
, StreamMode m
, bool bDirect
)
572 OSL_FAIL("Not supported!");
573 return OpenStorage( rName
, m
, bDirect
);
576 BaseStorage
* Storage::OpenOLEStorage( const OUString
& rName
, StreamMode m
, bool bDirect
)
578 return OpenStorage( rName
, m
, bDirect
);
581 BaseStorage
* Storage::OpenStorage( const OUString
& rName
, StreamMode m
, bool bDirect
)
583 if( !Validate() || !ValidateMode( m
) )
584 return new Storage( pIo
, NULL
, m
);
585 if( bDirect
&& !pEntry
->bDirect
)
588 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
591 if( !( m
& STREAM_NOCREATE
) )
594 // create a new storage
595 OUString aNewName
= rName
;
596 if( aNewName
.isEmpty() )
598 aNewName
= "Temp Stg " + OUString::number( ++nTmpCount
);
601 p
= pIo
->pTOC
->Create( *pEntry
, aNewName
, STG_STORAGE
);
606 pIo
->SetError( ( m
& STREAM_WRITE
)
607 ? SVSTREAM_CANNOT_MAKE
: SVSTREAM_FILE_NOT_FOUND
);
609 else if( !ValidateMode( m
, p
) )
611 if( p
&& p
->aEntry
.GetType() != STG_STORAGE
)
613 pIo
->SetError( SVSTREAM_FILE_NOT_FOUND
);
617 // Either direct or transacted mode is supported
618 if( p
&& pEntry
->nRefCnt
== 1 )
619 p
->bDirect
= bDirect
;
621 // Dont check direct conflict if opening readonly
622 if( p
&& (m
& STREAM_WRITE
))
624 if( p
->bDirect
!= bDirect
)
625 SetError( SVSTREAM_ACCESS_DENIED
);
627 Storage
* pStg
= new Storage( pIo
, p
, m
);
628 pIo
->MoveError( *pStg
);
629 if( m
& STREAM_WRITE
) pStg
->m_bAutoCommit
= true;
635 BaseStorageStream
* Storage::OpenStream( const OUString
& rName
, StreamMode m
, bool,
642 DBG_ASSERT(!pB
, "Encryption not supported");
644 if( !Validate() || !ValidateMode( m
) )
645 return new StorageStream( pIo
, NULL
, m
);
646 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
650 if( !( m
& STREAM_NOCREATE
) )
652 // create a new stream
653 // make a name if the stream is temporary (has no name)
654 OUString
aNewName( rName
);
655 if( aNewName
.isEmpty() )
657 aNewName
= "Temp Strm " + OUString::number( ++nTmpCount
);
660 p
= pIo
->pTOC
->Create( *pEntry
, aNewName
, STG_STREAM
);
663 pIo
->SetError( ( m
& STREAM_WRITE
)
664 ? SVSTREAM_CANNOT_MAKE
: SVSTREAM_FILE_NOT_FOUND
);
666 else if( !ValidateMode( m
, p
) )
668 if( p
&& p
->aEntry
.GetType() != STG_STREAM
)
670 pIo
->SetError( SVSTREAM_FILE_NOT_FOUND
);
676 p
->bDirect
= pEntry
->bDirect
;
678 StorageStream
* pStm
= new StorageStream( pIo
, p
, m
);
679 if( p
&& !p
->bDirect
)
680 pStm
->SetAutoCommit( true );
681 pIo
->MoveError( *pStm
);
685 // Delete a stream or substorage by setting the temp bit.
687 bool Storage::Remove( const OUString
& rName
)
689 if( !Validate( true ) )
691 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
694 p
->Invalidate( true );
699 SetError( SVSTREAM_FILE_NOT_FOUND
);
704 // Rename a storage element
706 bool Storage::Rename( const OUString
& rOld
, const OUString
& rNew
)
708 if( Validate( true ) )
710 bool b
= pIo
->pTOC
->Rename( *pEntry
, rOld
, rNew
);
711 pIo
->MoveError( *this );
720 bool Storage::CopyTo( const OUString
& rElem
, BaseStorage
* pDest
, const OUString
& rNew
)
722 if( !Validate() || !pDest
|| !pDest
->Validate( true ) )
724 StgDirEntry
* pElem
= pIo
->pTOC
->Find( *pEntry
, rElem
);
727 if( pElem
->aEntry
.GetType() == STG_STORAGE
)
729 // copy the entire storage
730 BaseStorage
* p1
= OpenStorage( rElem
, INTERNAL_MODE
);
731 BaseStorage
* p2
= pDest
->OpenOLEStorage( rNew
, STREAM_WRITE
| STREAM_SHARE_DENYALL
, pEntry
->bDirect
);
735 sal_uLong nTmpErr
= p2
->GetError();
738 p2
->SetClassId( p1
->GetClassId() );
740 SetError( p1
->GetError() );
742 nTmpErr
= p2
->GetError();
746 pDest
->SetError( nTmpErr
);
749 pDest
->SetError( nTmpErr
);
754 return Good() && pDest
->Good();
759 BaseStorageStream
* p1
= OpenStream( rElem
, INTERNAL_MODE
);
760 BaseStorageStream
* p2
= pDest
->OpenStream( rNew
, STREAM_WRITE
| STREAM_SHARE_DENYALL
, pEntry
->bDirect
);
764 sal_uLong nTmpErr
= p2
->GetError();
768 SetError( p1
->GetError() );
770 nTmpErr
= p2
->GetError();
774 pDest
->SetError( nTmpErr
);
777 pDest
->SetError( nTmpErr
);
782 return Good() && pDest
->Good();
785 SetError( SVSTREAM_FILE_NOT_FOUND
);
789 bool Storage::CopyTo( BaseStorage
* pDest
) const
791 if( !Validate() || !pDest
|| !pDest
->Validate( true ) || Equals( *pDest
) )
793 SetError( SVSTREAM_ACCESS_DENIED
);
796 Storage
* pThis
= (Storage
*) this;
797 pDest
->SetClassId( GetClassId() );
799 SvStorageInfoList aList
;
800 FillInfoList( &aList
);
802 for( size_t i
= 0; i
< aList
.size() && bRes
; i
++ )
804 SvStorageInfo
& rInfo
= aList
[ i
];
805 bRes
= pThis
->CopyTo( rInfo
.GetName(), pDest
, rInfo
.GetName() );
808 SetError( pDest
->GetError() );
809 return Good() && pDest
->Good();
814 bool Storage::MoveTo( const OUString
& rElem
, BaseStorage
* pODest
, const OUString
& rNew
)
816 if( !Validate() || !pODest
|| !pODest
->Validate( true ) || Equals( *pODest
) )
818 SetError( SVSTREAM_ACCESS_DENIED
);
822 StgDirEntry
* pElem
= pIo
->pTOC
->Find( *pEntry
, rElem
);
825 // Simplest case: both storages share the same file
827 Storage
*pOther
= PTR_CAST( Storage
, pODest
);
828 if( pOther
&& pIo
== pOther
->pIo
&& rElem
== rNew
)
830 Storage
*p
= (Storage
*) pODest
;
832 // both storages are conventional storages, use implementation dependent code
833 if( !pElem
->IsContained( pDest
->pEntry
) )
836 SetError( SVSTREAM_ACCESS_DENIED
);
839 bRes
= pIo
->pTOC
->Move( *pEntry
, *pDest
->pEntry
, rNew
);
842 pIo
->MoveError( *this );
843 pDest
->pIo
->MoveError( *pDest
);
844 sal_uLong nErr
= GetError();
846 nErr
= pDest
->GetError();
848 pDest
->SetError( nErr
);
853 bRes
= CopyTo( rElem
, pODest
, rNew
);
855 bRes
= Remove( rElem
);
858 SetError( pIo
->GetError() );
861 SetError( SVSTREAM_FILE_NOT_FOUND
);
865 bool Storage::IsStorage( const OUString
& rName
) const
869 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
871 return p
->aEntry
.GetType() == STG_STORAGE
;
876 bool Storage::IsStream( const OUString
& rName
) const
880 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
882 return p
->aEntry
.GetType() == STG_STREAM
;
887 bool Storage::IsContained( const OUString
& rName
) const
890 return pIo
->pTOC
->Find( *pEntry
, rName
) != NULL
;
895 // Commit all sub-elements within this storage. If this is
896 // the root, commit the FAT, the TOC and the header as well.
898 bool Storage::Commit()
903 if( !( m_nMode
& STREAM_WRITE
) )
905 SetError( SVSTREAM_ACCESS_DENIED
);
910 // Also commit the sub-streams and Storages
911 StgIterator
aIter( *pEntry
);
912 for( StgDirEntry
* p
= aIter
.First(); p
&& bRes
; p
= aIter
.Next() )
914 if( bRes
&& bIsRoot
)
916 bRes
= pEntry
->Commit();
918 bRes
= pIo
->CommitAll();
920 pIo
->MoveError( *this );
925 bool Storage::Revert()
930 ///////////////////////////// OLE Support ////////////////////////////////
932 // Set the storage type
934 void Storage::SetClass( const SvGlobalName
& rClass
,
935 sal_uLong nOriginalClipFormat
,
936 const OUString
& rUserTypeName
)
938 if( Validate( true ) )
940 // set the class name in the root entry
941 pEntry
->aEntry
.SetClassId( (const ClsId
&) rClass
.GetCLSID() );
943 // then create the streams
944 StgCompObjStream
aCompObj( *this, true );
945 aCompObj
.GetClsId() = (const ClsId
&) rClass
.GetCLSID();
946 aCompObj
.GetCbFormat() = nOriginalClipFormat
;
947 aCompObj
.GetUserName() = rUserTypeName
;
948 if( !aCompObj
.Store() )
949 SetError( aCompObj
.GetError() );
952 StgOleStream
aOle(*this, true);
954 SetError( aOle
.GetError() );
958 SetError( SVSTREAM_ACCESS_DENIED
);
961 void Storage::SetConvertClass( const SvGlobalName
& rConvertClass
,
962 sal_uLong nOriginalClipFormat
,
963 const OUString
& rUserTypeName
)
965 if( Validate( true ) )
967 SetClass( rConvertClass
, nOriginalClipFormat
, rUserTypeName
);
968 // plus the convert flag:
969 StgOleStream
aOle( *this, true );
970 aOle
.GetFlags() |= 4;
972 SetError( aOle
.GetError() );
976 SvGlobalName
Storage::GetClassName()
978 StgCompObjStream
aCompObj( *this, false );
979 if( aCompObj
.Load() )
980 return SvGlobalName( (const CLSID
&) aCompObj
.GetClsId() );
984 return SvGlobalName( (const CLSID
&) pEntry
->aEntry
.GetClassId() );
986 return SvGlobalName();
989 sal_uLong
Storage::GetFormat()
991 StgCompObjStream
aCompObj( *this, false );
992 if( aCompObj
.Load() )
993 return aCompObj
.GetCbFormat();
998 OUString
Storage::GetUserName()
1000 StgCompObjStream
aCompObj( *this, false );
1001 if( aCompObj
.Load() )
1002 return aCompObj
.GetUserName();
1007 bool Storage::ShouldConvert()
1009 StgOleStream
aOle( *this, false );
1011 return ( aOle
.GetFlags() & 4 ) != 0;
1019 bool Storage::ValidateFAT()
1021 Link aLink
= StgIo::GetErrorLink();
1022 ErrCode nErr
= pIo
->ValidateFATs();
1023 StgIo::SetErrorLink( aLink
);
1024 return nErr
== ERRCODE_NONE
;
1027 void Storage::SetDirty()
1033 void Storage::SetClassId( const ClsId
& rId
)
1036 pEntry
->aEntry
.SetClassId( rId
);
1039 const ClsId
& Storage::GetClassId() const
1042 return pEntry
->aEntry
.GetClassId();
1044 static ClsId aDummyId
= {0,0,0,0,0,0,0,0,0,0,0};
1048 const SvStream
* Storage::GetSvStream() const
1050 return GetSvStream_Impl();
1053 bool Storage::Validate( bool bValidate
) const
1055 bool bRet
= Validate_Impl( bValidate
);
1057 SetError( SVSTREAM_ACCESS_DENIED
);
1061 bool Storage::ValidateMode( StreamMode nMode
) const
1063 bool bRet
= ValidateMode_Impl( nMode
);
1065 SetError( SVSTREAM_ACCESS_DENIED
);
1069 bool Storage::ValidateMode( StreamMode nMode
, StgDirEntry
* p
) const
1071 bool bRet
= ValidateMode_Impl( nMode
, p
);
1073 SetError( SVSTREAM_ACCESS_DENIED
);
1077 bool Storage::Equals( const BaseStorage
& rStorage
) const
1079 const Storage
* pOther
= PTR_CAST( Storage
, &rStorage
);
1080 return pOther
&& ( pOther
->pEntry
== pEntry
);
1084 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */