1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: stg.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sot.hxx"
34 #include <storinfo.hxx>
35 #include <osl/file.hxx>
36 #include <tools/tempfile.hxx>
37 #include <tools/ownlist.hxx>
38 #include <tools/string.hxx>
39 #ifndef _TOOLS_FSYS_HXX
40 #include <tools/fsys.hxx>
42 #ifndef _TOOLS_STREAM_HXX
43 #include <tools/stream.hxx>
45 #include <tools/pstm.hxx>
46 #include <tools/debug.hxx>
49 #include "stgelem.hxx"
50 #include "stgcache.hxx"
51 #include "stgstrms.hxx"
56 static long nTmpCount
= 0;
58 // The internal open mode is STREAM_READ | STREAM_TRUNC, which is silly
59 // by itself. It inhibits the checking of sharing modes and is used
60 // during CopyTo() and MoveTo() for opening a stream in read mode
61 // although it may be open in DENYALL mode
63 #define INTERNAL_MODE ( STREAM_READ | STREAM_TRUNC )
65 ///////////////////////// class StorageBase //////////////////////////////
67 TYPEINIT0( StorageBase
);
68 TYPEINIT1( BaseStorageStream
, StorageBase
);
69 TYPEINIT1( BaseStorage
, StorageBase
);
71 StorageBase::StorageBase()
72 : m_bAutoCommit( FALSE
)
74 m_nMode
= STREAM_READ
;
75 m_nError
= SVSTREAM_OK
;
78 StorageBase::~StorageBase()
82 // The following three methods are declared as const, since they
83 // may be called from within a const method.
85 ULONG
StorageBase::GetError() const
88 ((StorageBase
*) this)->m_nError
= SVSTREAM_OK
;
92 void StorageBase::SetError( ULONG n
) const
95 ((StorageBase
*) this)->m_nError
= n
;
98 void StorageBase::ResetError() const
100 ((StorageBase
*) this)->m_nError
= SVSTREAM_OK
;
103 // Retrieve the underlying SvStream for info purposes
105 const SvStream
* OLEStorageBase::GetSvStream_Impl() const
107 return pIo
? pIo
->GetStrm() : NULL
;
110 OLEStorageBase::OLEStorageBase( StgIo
* p
, StgDirEntry
* pe
, StreamMode
& nMode
)
111 : nStreamMode( nMode
), pIo( p
), pEntry( pe
)
118 OLEStorageBase::~OLEStorageBase()
122 DBG_ASSERT( pEntry
->nRefCnt
, "RefCount unter 0" );
123 if( !--pEntry
->nRefCnt
)
125 if( pEntry
->bZombie
)
137 // Validate the instance for I/O
139 BOOL
OLEStorageBase::Validate_Impl( BOOL bWrite
) const
143 && ( !bWrite
|| !pEntry
->bDirect
|| ( nStreamMode
& STREAM_WRITE
) ) )
148 BOOL
OLEStorageBase::ValidateMode_Impl( StreamMode m
, StgDirEntry
* p
) const
150 if( m
== INTERNAL_MODE
)
152 USHORT nCurMode
= ( p
&& p
->nRefCnt
) ? p
->nMode
: 0xFFFF;
153 if( ( m
& 3 ) == STREAM_READ
)
155 // only SHARE_DENYWRITE or SHARE_DENYALL allowed
156 if( ( ( m
& STREAM_SHARE_DENYWRITE
)
157 && ( nCurMode
& STREAM_SHARE_DENYWRITE
) )
158 || ( ( m
& STREAM_SHARE_DENYALL
)
159 && ( nCurMode
& STREAM_SHARE_DENYALL
) ) )
164 // only SHARE_DENYALL allowed
165 // storages open in r/o mode are OK, since only
166 // the commit may fail
167 if( ( m
& STREAM_SHARE_DENYALL
)
168 && ( nCurMode
& STREAM_SHARE_DENYALL
) )
175 //////////////////////// class StorageStream /////////////////////////////
177 TYPEINIT1( StorageStream
, BaseStorageStream
);
179 StorageStream::StorageStream( StgIo
* p
, StgDirEntry
* q
, StreamMode m
)
180 : OLEStorageBase( p
, q
, m_nMode
), nPos( 0L )
182 // The dir entry may be 0; this means that the stream is invalid.
185 if( q
->nRefCnt
== 1 )
192 m
&= ~STREAM_READWRITE
;
196 StorageStream::~StorageStream()
198 // Do an auto-commit if the entry is open in direct mode
201 if( pEntry
&& pEntry
->nRefCnt
&& pEntry
->bDirect
&& (m_nMode
& STREAM_WRITE
) )
205 BOOL
StorageStream::Equals( const BaseStorageStream
& rStream
) const
207 const StorageStream
* pOther
= PTR_CAST( StorageStream
, &rStream
);
208 return pOther
&& ( pOther
->pEntry
== pEntry
);
211 ULONG
StorageStream::Read( void* pData
, ULONG nSize
)
215 pEntry
->Seek( nPos
);
216 nSize
= pEntry
->Read( pData
, (INT32
) nSize
);
217 pIo
->MoveError( *this );
225 ULONG
StorageStream::Write( const void* pData
, ULONG nSize
)
227 if( Validate( TRUE
) )
229 pEntry
->Seek( nPos
);
230 nSize
= pEntry
->Write( pData
, (INT32
) nSize
);
231 pIo
->MoveError( *this );
239 ULONG
StorageStream::Seek( ULONG n
)
242 return nPos
= pEntry
->Seek( n
);
247 void StorageStream::Flush()
249 // Flushing means committing, since streams are never transacted
253 BOOL
StorageStream::SetSize( ULONG nNewSize
)
255 if( Validate( TRUE
) )
257 BOOL b
= pEntry
->SetSize( (INT32
) nNewSize
);
258 pIo
->MoveError( *this );
265 BOOL
StorageStream::Commit()
269 if( !( m_nMode
& STREAM_WRITE
) )
271 SetError( SVSTREAM_ACCESS_DENIED
);
277 pIo
->MoveError( *this );
282 BOOL
StorageStream::Revert()
285 pIo
->MoveError( *this );
289 BOOL
StorageStream::CopyTo( BaseStorageStream
* pDest
)
291 if( !Validate() || !pDest
->Validate( TRUE
) || Equals( *pDest
) )
293 pEntry
->Copy( *pDest
);
295 pIo
->MoveError( *this );
296 SetError( pDest
->GetError() );
297 return BOOL( Good() && pDest
->Good() );
300 const SvStream
* StorageStream::GetSvStream() const
302 return GetSvStream_Impl();
305 BOOL
StorageStream::Validate( BOOL bValidate
) const
307 BOOL bRet
= Validate_Impl( bValidate
);
309 SetError( SVSTREAM_ACCESS_DENIED
);
313 BOOL
StorageStream::ValidateMode( StreamMode nMode
) const
315 BOOL bRet
= ValidateMode_Impl( nMode
, NULL
);
317 SetError( SVSTREAM_ACCESS_DENIED
);
321 BOOL
StorageStream::ValidateMode( StreamMode nMode
, StgDirEntry
* p
) const
323 BOOL bRet
= ValidateMode_Impl( nMode
, p
);
325 SetError( SVSTREAM_ACCESS_DENIED
);
329 ///////////////////////// class SvStorageInfo //////////////////////////////
331 SvStorageInfo::SvStorageInfo( const StgDirEntry
& rE
)
333 rE
.aEntry
.GetName( aName
);
334 bStorage
= BOOL( rE
.aEntry
.GetType() == STG_STORAGE
);
335 bStream
= BOOL( rE
.aEntry
.GetType() == STG_STREAM
);
336 nSize
= bStorage
? 0 : rE
.aEntry
.GetSize();
339 /////////////////////////// class Storage ////////////////////////////////
341 BOOL
Storage::IsStorageFile( const String
& rFileName
)
344 if( aIo
.Open( rFileName
, STREAM_STD_READ
) )
349 BOOL
Storage::IsStorageFile( SvStream
* pStream
)
352 ULONG nPos
= pStream
->Tell();
353 BOOL bRet
= ( aHdr
.Load( *pStream
) && aHdr
.Check() );
355 // It's not a stream error if it is too small for a OLE storage header
356 if ( pStream
->GetErrorCode() == ERRCODE_IO_CANTSEEK
)
357 pStream
->ResetError();
358 pStream
->Seek( nPos
);
362 // Open the storage file. If writing is permitted and the file is not
363 // a storage file, initialize it.
365 TYPEINIT1( Storage
, BaseStorage
);
367 Storage::Storage( const String
& rFile
, StreamMode m
, BOOL bDirect
)
368 : OLEStorageBase( new StgIo
, NULL
, m_nMode
), aName( rFile
), bIsRoot( FALSE
)
373 // no name = temporary name!
374 aName
= TempFile::CreateTempName();
377 // the root storage creates the I/O system
379 if( pIo
->Open( aName
, m
) )
381 Init( BOOL( ( 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
), bIsRoot( FALSE
)
401 m_nMode
= STREAM_READ
;
403 m_nMode
= STREAM_READ
| STREAM_WRITE
;
404 if( r
.GetError() == SVSTREAM_OK
)
406 pIo
->SetStrm( &r
, FALSE
);
407 ULONG nSize
= r
.Seek( STREAM_SEEK_TO_END
);
409 // Initializing is OK if the stream is empty
410 Init( BOOL( nSize
== 0 ) );
413 pEntry
->bDirect
= bDirect
;
414 pEntry
->nMode
= m_nMode
;
416 pIo
->MoveError( *this );
420 SetError( r
.GetError() );
426 Storage::Storage( UCBStorageStream
& rStrm
, BOOL bDirect
)
427 : OLEStorageBase( new StgIo
, NULL
, m_nMode
), bIsRoot( FALSE
)
429 m_nMode
= STREAM_READ
;
431 if ( rStrm
.GetError() != SVSTREAM_OK
)
433 SetError( rStrm
.GetError() );
438 SvStream
* pStream
= rStrm
.GetModifySvStream();
441 OSL_ENSURE( FALSE
, "UCBStorageStream can not provide SvStream implementation!\n" );
442 SetError( SVSTREAM_GENERALERROR
);
447 if( pStream
->IsWritable() )
448 m_nMode
= STREAM_READ
| STREAM_WRITE
;
450 pIo
->SetStrm( &rStrm
);
452 ULONG nSize
= pStream
->Seek( STREAM_SEEK_TO_END
);
454 // Initializing is OK if the stream is empty
455 Init( BOOL( nSize
== 0 ) );
458 pEntry
->bDirect
= bDirect
;
459 pEntry
->nMode
= m_nMode
;
462 pIo
->MoveError( *this );
466 // Perform common code for both ctors above.
468 void Storage::Init( BOOL bCreate
)
471 BOOL bHdrLoaded
= FALSE
;
475 ULONG nSize
= pIo
->GetStrm()->Seek( STREAM_SEEK_TO_END
);
476 pIo
->GetStrm()->Seek( 0L );
479 bHdrLoaded
= pIo
->Load();
480 if( !bHdrLoaded
&& !bCreate
)
482 // File is not a storage and not empty; do not destroy!
483 SetError( SVSTREAM_FILEFORMAT_ERROR
);
488 // file is a storage, empty or should be overwritten
490 // we have to set up the data structures, since
496 pEntry
= pIo
->pTOC
->GetRoot();
503 Storage::Storage( StgIo
* p
, StgDirEntry
* q
, StreamMode m
)
504 : OLEStorageBase( p
, q
, m_nMode
), bIsRoot( FALSE
)
507 q
->aEntry
.GetName( aName
);
509 m
&= ~STREAM_READWRITE
;
511 if( q
&& q
->nRefCnt
== 1 )
517 // Invalidate all open substorages
522 // Do an auto-commit if the entry is open in direct mode
523 if( pEntry
->nRefCnt
&& pEntry
->bDirect
&& (m_nMode
& STREAM_WRITE
) )
525 if( pEntry
->nRefCnt
== 1 )
526 pEntry
->Invalidate();
528 // close the stream is root storage
531 // remove the file if temporary root storage
532 if( bIsRoot
&& pEntry
&& pEntry
->bTemp
)
534 osl::File::remove( GetName() );
538 const String
& Storage::GetName() const
540 if( !bIsRoot
&& Validate() )
541 pEntry
->aEntry
.GetName( ((Storage
*) this)->aName
);
545 // Fill in the info list for this storage
547 void Storage::FillInfoList( SvStorageInfoList
* pList
) const
551 StgIterator
aIter( *pEntry
);
552 StgDirEntry
* p
= aIter
.First();
557 SvStorageInfo
aInfo( *p
);
558 pList
->Append( aInfo
);
565 // Open or create a substorage
567 BaseStorage
* Storage::OpenUCBStorage( const String
& rName
, StreamMode m
, BOOL bDirect
)
569 DBG_ERROR("Not supported!");
571 BaseStorage* pStorage = new Storage( pIo, NULL, m );
572 SetError( ERRCODE_IO_NOTSUPPORTED );
575 return OpenStorage( rName
, m
, bDirect
);
578 BaseStorage
* Storage::OpenOLEStorage( const String
& rName
, StreamMode m
, BOOL bDirect
)
580 return OpenStorage( rName
, m
, bDirect
);
583 BaseStorage
* Storage::OpenStorage( const String
& rName
, StreamMode m
, BOOL bDirect
)
585 if( !Validate() || !ValidateMode( m
) )
586 return new Storage( pIo
, NULL
, m
);
587 BOOL bSetAutoCommit
= FALSE
;
588 if( bDirect
&& !pEntry
->bDirect
)
590 bSetAutoCommit
= TRUE
;
594 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
597 if( !( m
& STREAM_NOCREATE
) )
600 // create a new storage
601 String aNewName
= rName
;
602 if( !aNewName
.Len() )
604 aNewName
.AssignAscii( "Temp Stg " );
605 aNewName
.Append( String::CreateFromInt32( ++nTmpCount
) );
608 p
= pIo
->pTOC
->Create( *pEntry
, aNewName
, STG_STORAGE
);
613 pIo
->SetError( ( m
& STREAM_WRITE
)
614 ? SVSTREAM_CANNOT_MAKE
: SVSTREAM_FILE_NOT_FOUND
);
616 else if( !ValidateMode( m
, p
) )
618 if( p
&& p
->aEntry
.GetType() != STG_STORAGE
)
620 pIo
->SetError( SVSTREAM_FILE_NOT_FOUND
);
624 // Either direct or transacted mode is supported
625 if( p
&& pEntry
->nRefCnt
== 1 )
626 p
->bDirect
= bDirect
;
628 // Dont check direct conflict if opening readonly
629 if( p
&& (m
& STREAM_WRITE
))
631 if( p
->bDirect
!= bDirect
)
632 SetError( SVSTREAM_ACCESS_DENIED
);
634 Storage
* pStg
= new Storage( pIo
, p
, m
);
635 pIo
->MoveError( *pStg
);
636 if( m
& STREAM_WRITE
) pStg
->m_bAutoCommit
= TRUE
;
642 BaseStorageStream
* Storage::OpenStream( const String
& rName
, StreamMode m
, BOOL
,
649 DBG_ASSERT(!pB
, "Encryption not supported");
651 if( !Validate() || !ValidateMode( m
) )
652 return new StorageStream( pIo
, NULL
, m
);
653 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
657 if( !( m
& STREAM_NOCREATE
) )
659 // create a new stream
660 // make a name if the stream is temporary (has no name)
661 String
aNewName( rName
);
662 if( !aNewName
.Len() )
664 aNewName
.AssignAscii( "Temp Strm " );
665 aNewName
.Append( String::CreateFromInt32( ++nTmpCount
) );
668 p
= pIo
->pTOC
->Create( *pEntry
, aNewName
, STG_STREAM
);
671 pIo
->SetError( ( m
& STREAM_WRITE
)
672 ? SVSTREAM_CANNOT_MAKE
: SVSTREAM_FILE_NOT_FOUND
);
674 else if( !ValidateMode( m
, p
) )
676 if( p
&& p
->aEntry
.GetType() != STG_STREAM
)
678 pIo
->SetError( SVSTREAM_FILE_NOT_FOUND
);
684 p
->bDirect
= pEntry
->bDirect
;
686 StorageStream
* pStm
= new StorageStream( pIo
, p
, m
);
687 if( p
&& !p
->bDirect
)
688 pStm
->SetAutoCommit( TRUE
);
689 pIo
->MoveError( *pStm
);
693 // Delete a stream or substorage by setting the temp bit.
695 BOOL
Storage::Remove( const String
& rName
)
697 if( !Validate( TRUE
) )
699 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
702 p
->Invalidate( TRUE
);
707 SetError( SVSTREAM_FILE_NOT_FOUND
);
712 // Rename a storage element
714 BOOL
Storage::Rename( const String
& rOld
, const String
& rNew
)
716 if( Validate( TRUE
) )
718 BOOL b
= pIo
->pTOC
->Rename( *pEntry
, rOld
, rNew
);
719 pIo
->MoveError( *this );
728 BOOL
Storage::CopyTo( const String
& rElem
, BaseStorage
* pDest
, const String
& rNew
)
730 if( !Validate() || !pDest
|| !pDest
->Validate( TRUE
) )
732 StgDirEntry
* pElem
= pIo
->pTOC
->Find( *pEntry
, rElem
);
736 this lines are misterious !!! MM
737 if( !pElem->IsContained( pDest->pEntry ) )
739 SetError( SVSTREAM_ACCESS_DENIED );
743 if( pElem
->aEntry
.GetType() == STG_STORAGE
)
745 // copy the entire storage
746 BaseStorage
* p1
= OpenStorage( rElem
, INTERNAL_MODE
);
747 BaseStorage
* p2
= pDest
->OpenOLEStorage( rNew
, STREAM_WRITE
| STREAM_SHARE_DENYALL
, pEntry
->bDirect
);
749 ULONG nTmpErr
= p2
->GetError();
752 p2
->SetClassId( p1
->GetClassId() );
754 SetError( p1
->GetError() );
756 nTmpErr
= p2
->GetError();
760 pDest
->SetError( nTmpErr
);
763 pDest
->SetError( nTmpErr
);
767 return BOOL( Good() && pDest
->Good() );
772 BaseStorageStream
* p1
= OpenStream( rElem
, INTERNAL_MODE
);
773 BaseStorageStream
* p2
= pDest
->OpenStream( rNew
, STREAM_WRITE
| STREAM_SHARE_DENYALL
, pEntry
->bDirect
);
775 ULONG nTmpErr
= p2
->GetError();
779 SetError( p1
->GetError() );
781 nTmpErr
= p2
->GetError();
785 pDest
->SetError( nTmpErr
);
788 pDest
->SetError( nTmpErr
);
792 return BOOL( Good() && pDest
->Good() );
795 SetError( SVSTREAM_FILE_NOT_FOUND
);
799 BOOL
Storage::CopyTo( BaseStorage
* pDest
) const
801 if( !Validate() || !pDest
|| !pDest
->Validate( TRUE
) || Equals( *pDest
) )
803 SetError( SVSTREAM_ACCESS_DENIED
);
806 Storage
* pThis
= (Storage
*) this;
808 if( !pThis->pEntry->IsContained( pDest->pEntry ) )
810 SetError( SVSTREAM_ACCESS_DENIED );
814 pDest
->SetClassId( GetClassId() );
816 SvStorageInfoList aList
;
817 FillInfoList( &aList
);
819 for( USHORT i
= 0; i
< aList
.Count() && bRes
; i
++ )
821 SvStorageInfo
& rInfo
= aList
.GetObject( i
);
822 bRes
= pThis
->CopyTo( rInfo
.GetName(), pDest
, rInfo
.GetName() );
825 SetError( pDest
->GetError() );
826 return BOOL( Good() && pDest
->Good() );
831 BOOL
Storage::MoveTo( const String
& rElem
, BaseStorage
* pODest
, const String
& rNew
)
833 if( !Validate() || !pODest
|| !pODest
->Validate( TRUE
) || Equals( *pODest
) )
835 SetError( SVSTREAM_ACCESS_DENIED
);
839 StgDirEntry
* pElem
= pIo
->pTOC
->Find( *pEntry
, rElem
);
842 // Simplest case: both storages share the same file
844 Storage
*pOther
= PTR_CAST( Storage
, pODest
);
845 if( pOther
&& pIo
== pOther
->pIo
&& rElem
== rNew
)
847 Storage
*p
= (Storage
*) pODest
;
849 // both storages are conventional storages, use implementation dependent code
850 if( !pElem
->IsContained( pDest
->pEntry
) )
853 SetError( SVSTREAM_ACCESS_DENIED
);
856 bRes
= pIo
->pTOC
->Move( *pEntry
, *pDest
->pEntry
, rNew
);
859 pIo
->MoveError( *this );
860 pDest
->pIo
->MoveError( *pDest
);
861 ULONG nErr
= GetError();
863 nErr
= pDest
->GetError();
865 pDest
->SetError( nErr
);
870 bRes
= CopyTo( rElem
, pODest
, rNew
);
872 bRes
= Remove( rElem
);
875 SetError( pIo
->GetError() );
878 SetError( SVSTREAM_FILE_NOT_FOUND
);
882 BOOL
Storage::IsStorage( const String
& rName
) const
886 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
888 return BOOL( p
->aEntry
.GetType() == STG_STORAGE
);
893 BOOL
Storage::IsStream( const String
& rName
) const
897 StgDirEntry
* p
= pIo
->pTOC
->Find( *pEntry
, rName
);
899 return BOOL( p
->aEntry
.GetType() == STG_STREAM
);
904 BOOL
Storage::IsContained( const String
& rName
) const
907 return BOOL( pIo
->pTOC
->Find( *pEntry
, rName
) != NULL
);
912 // Commit all sub-elements within this storage. If this is
913 // the root, commit the FAT, the TOC and the header as well.
915 BOOL
Storage::Commit()
920 if( !( m_nMode
& STREAM_WRITE
) )
922 SetError( SVSTREAM_ACCESS_DENIED
);
927 // Also commit the sub-streams and Storages
928 StgIterator
aIter( *pEntry
);
929 for( StgDirEntry
* p
= aIter
.First(); p
&& bRes
; p
= aIter
.Next() )
931 if( bRes
&& bIsRoot
)
933 bRes
= pEntry
->Commit();
935 bRes
= pIo
->CommitAll();
937 pIo
->MoveError( *this );
942 BOOL
Storage::Revert()
947 ///////////////////////////// OLE Support ////////////////////////////////
949 // Set the storage type
951 void Storage::SetClass( const SvGlobalName
& rClass
,
952 ULONG nOriginalClipFormat
,
953 const String
& rUserTypeName
)
955 if( Validate( TRUE
) )
957 // set the class name in the root entry
958 pEntry
->aEntry
.SetClassId( (const ClsId
&) rClass
.GetCLSID() );
960 // then create the streams
961 StgCompObjStream
aCompObj( *this, TRUE
);
962 aCompObj
.GetClsId() = (const ClsId
&) rClass
.GetCLSID();
963 aCompObj
.GetCbFormat() = nOriginalClipFormat
;
964 aCompObj
.GetUserName() = rUserTypeName
;
965 if( !aCompObj
.Store() )
966 SetError( aCompObj
.GetError() );
969 StgOleStream
aOle( *this, STREAM_WRITE
);
971 SetError( aOle
.GetError() );
975 SetError( SVSTREAM_ACCESS_DENIED
);
978 void Storage::SetConvertClass( const SvGlobalName
& rConvertClass
,
979 ULONG nOriginalClipFormat
,
980 const String
& rUserTypeName
)
982 if( Validate( TRUE
) )
984 SetClass( rConvertClass
, nOriginalClipFormat
, rUserTypeName
);
985 // plus the convert flag:
986 StgOleStream
aOle( *this, TRUE
);
987 aOle
.GetFlags() |= 4;
989 SetError( aOle
.GetError() );
993 SvGlobalName
Storage::GetClassName()
995 StgCompObjStream
aCompObj( *this, FALSE
);
996 if( aCompObj
.Load() )
997 return SvGlobalName( (const CLSID
&) aCompObj
.GetClsId() );
1001 return SvGlobalName( (const CLSID
&) pEntry
->aEntry
.GetClassId() );
1003 return SvGlobalName();
1006 ULONG
Storage::GetFormat()
1008 StgCompObjStream
aCompObj( *this, FALSE
);
1009 if( aCompObj
.Load() )
1010 return aCompObj
.GetCbFormat();
1015 String
Storage::GetUserName()
1017 StgCompObjStream
aCompObj( *this, FALSE
);
1018 if( aCompObj
.Load() )
1019 return aCompObj
.GetUserName();
1024 BOOL
Storage::ShouldConvert()
1026 StgOleStream
aOle( *this, FALSE
);
1028 return BOOL( ( aOle
.GetFlags() & 4 ) != 0 );
1036 BOOL
Storage::ValidateFAT()
1038 Link aLink
= StgIo::GetErrorLink();
1039 ErrCode nErr
= pIo
->ValidateFATs();
1040 StgIo::SetErrorLink( aLink
);
1041 return nErr
== ERRCODE_NONE
;
1044 void Storage::SetDirty()
1049 void Storage::SetClassId( const ClsId
& rId
)
1051 pEntry
->aEntry
.SetClassId( rId
);
1054 const ClsId
& Storage::GetClassId() const
1056 return pEntry
->aEntry
.GetClassId();
1059 const SvStream
* Storage::GetSvStream() const
1061 return GetSvStream_Impl();
1064 BOOL
Storage::Validate( BOOL bValidate
) const
1066 BOOL bRet
= Validate_Impl( bValidate
);
1068 SetError( SVSTREAM_ACCESS_DENIED
);
1072 BOOL
Storage::ValidateMode( StreamMode nMode
) const
1074 BOOL bRet
= ValidateMode_Impl( nMode
);
1076 SetError( SVSTREAM_ACCESS_DENIED
);
1080 BOOL
Storage::ValidateMode( StreamMode nMode
, StgDirEntry
* p
) const
1082 BOOL bRet
= ValidateMode_Impl( nMode
, p
);
1084 SetError( SVSTREAM_ACCESS_DENIED
);
1088 BOOL
Storage::Equals( const BaseStorage
& rStorage
) const
1090 const Storage
* pOther
= PTR_CAST( Storage
, &rStorage
);
1091 return pOther
&& ( pOther
->pEntry
== pEntry
);