LibreOffice Module sot (master) 1
stg.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
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>
26
27#include <sot/stg.hxx>
28#include <utility>
29#include "stgelem.hxx"
30#include "stgdir.hxx"
31#include "stgio.hxx"
32#include "stgole.hxx"
33
35
36// The internal open mode is StreamMode::READ | StreamMode::TRUNC, which is silly
37// by itself. It inhibits the checking of sharing modes and is used
38// during CopyTo() and MoveTo() for opening a stream in read mode
39// although it may be open in DENYALL mode
40
41#define INTERNAL_MODE ( StreamMode::READ | StreamMode::TRUNC )
42
44
45
47 : m_bAutoCommit( false )
48{
49 m_nMode = StreamMode::READ;
51}
52
54{
55}
56
57// The following three methods are declared as const, since they
58// may be called from within a const method.
59
61{
62 const ErrCode n = m_nError;
64 return n;
65}
66
68{
69 if( !m_nError )
70 m_nError = n;
71}
72
74{
76}
77
79 : nStreamMode( nMode ), pIo( p ), pEntry( pe )
80{
81 if ( p )
82 p->IncRef();
83 if( pe )
84 pe->m_nRefCnt++;
85}
86
88{
89 if( pEntry )
90 {
91 DBG_ASSERT( pEntry->m_nRefCnt, "RefCount under 0" );
92 if( !--pEntry->m_nRefCnt )
93 {
94 if( pEntry->m_bZombie )
95 delete pEntry;
96 else
97 pEntry->Close();
98 }
99
100 pEntry = nullptr;
101 }
102
103
104 if( pIo && !pIo->DecRef() )
105 {
106 delete pIo;
107 pIo = nullptr;
108 }
109}
110
111// Validate the instance for I/O
112
113bool OLEStorageBase::Validate_Impl( bool bWrite ) const
114{
115 return pIo
116 && pIo->m_pTOC
117 && pEntry
118 && !pEntry->m_bInvalid
119 && ( !bWrite || !pEntry->m_bDirect || ( nStreamMode & StreamMode::WRITE ) );
120}
121
123{
124 if( m == INTERNAL_MODE )
125 return true;
126 StreamMode nCurMode = ( p && p->m_nRefCnt ) ? p->m_nMode : StreamMode::SHARE_DENYALL;
127 if( ( m & StreamMode::READWRITE ) == StreamMode::READ )
128 {
129 // only SHARE_DENYWRITE or SHARE_DENYALL allowed
130 if( ( ( m & StreamMode::SHARE_DENYWRITE )
131 && ( nCurMode & StreamMode::SHARE_DENYWRITE ) )
132 || ( ( m & StreamMode::SHARE_DENYALL )
133 && ( nCurMode & StreamMode::SHARE_DENYALL ) ) )
134 return true;
135 }
136 else
137 {
138 // only SHARE_DENYALL allowed
139 // storages open in r/o mode are OK, since only
140 // the commit may fail
141 if( ( m & StreamMode::SHARE_DENYALL )
142 && ( nCurMode & StreamMode::SHARE_DENYALL ) )
143 return true;
144 }
145 return false;
146}
147
148
150
151
153 : OLEStorageBase( p, q, m_nMode ), nPos( 0 )
154{
155 // The dir entry may be 0; this means that the stream is invalid.
156 if( q && p )
157 {
158 if( q->m_nRefCnt == 1 )
159 {
160 q->m_nMode = m;
161 q->OpenStream( *p );
162 }
163 }
164 else
165 m &= ~StreamMode::READWRITE;
166 m_nMode = m;
167}
168
170{
171 // Do an auto-commit if the entry is open in direct mode
172 if( m_bAutoCommit )
173 Commit();
174 if( pEntry && pEntry->m_nRefCnt && pEntry->m_bDirect && (m_nMode & StreamMode::WRITE) )
175 pEntry->Commit();
176}
177
178bool StorageStream::Equals( const BaseStorageStream& rStream ) const
179{
180 const StorageStream* pOther = dynamic_cast<const StorageStream*>( &rStream );
181 return pOther && ( pOther->pEntry == pEntry );
182}
183
184sal_Int32 StorageStream::Read( void* pData, sal_Int32 nSize )
185{
186 if( Validate() )
187 {
188 pEntry->Seek( nPos );
189 nSize = pEntry->Read( pData, nSize );
190 pIo->MoveError( *this );
191 nPos += nSize;
192 }
193 else
194 nSize = 0;
195 return nSize;
196}
197
198sal_Int32 StorageStream::Write( const void* pData, sal_Int32 nSize )
199{
200 if( Validate( true ) )
201 {
202 pEntry->Seek( nPos );
203 nSize = pEntry->Write( pData, nSize );
204 pIo->MoveError( *this );
205 nPos += nSize;
206 }
207 else
208 nSize = 0;
209 return nSize;
210}
211
212sal_uInt64 StorageStream::Seek( sal_uInt64 n )
213{
214 if( Validate() )
215 {
216 nPos = pEntry->Seek( n );
217 return nPos;
218 }
219 else
220 return n;
221}
222
224{
225 // Flushing means committing, since streams are never transacted
226 Commit();
227}
228
229bool StorageStream::SetSize( sal_uInt64 nNewSize )
230{
231 if( Validate( true ) )
232 {
233 bool b = pEntry->SetSize( nNewSize );
234 pIo->MoveError( *this );
235 return b;
236 }
237 else
238 return false;
239}
240
241sal_uInt64 StorageStream::GetSize() const
242{
243 if( Validate() )
244 return pEntry->GetSize();
245 return 0;
246}
247
249{
250 if( !Validate() )
251 return false;
252 if( !( m_nMode & StreamMode::WRITE ) )
253 {
255 return false;
256 }
257 else
258 {
259 pEntry->Commit();
260 pIo->MoveError( *this );
261 return Good();
262 }
263}
264
266{
267 if( !Validate() || !pDest || !pDest->Validate( true ) || Equals( *pDest ) )
268 return;
269 pEntry->Copy( *pDest );
270 pDest->Commit();
271 pIo->MoveError( *this );
272 SetError( pDest->GetError() );
273}
274
275bool StorageStream::Validate( bool bValidate ) const
276{
277 bool bRet = Validate_Impl( bValidate );
278 if ( !bRet )
280 return bRet;
281}
282
284{
285 bool bRet = ValidateMode_Impl( nMode );
286 if ( !bRet )
288 return bRet;
289}
290
292
294{
295 rE.m_aEntry.GetName( aName );
298 nSize = bStorage ? 0 : rE.m_aEntry.GetSize();
299}
300
302
303bool Storage::IsStorageFile( const OUString & rFileName )
304{
305 StgIo aIo;
306 if( aIo.Open( rFileName, StreamMode::STD_READ ) )
307 return aIo.Load();
308 return false;
309}
310
311bool Storage::IsStorageFile( SvStream* pStream )
312{
313 bool bRet = false;
314
315 if ( pStream )
316 {
317 StgHeader aHdr;
318 sal_uInt64 nPos = pStream->Tell();
319 bRet = ( aHdr.Load( *pStream ) && aHdr.Check() );
320
321 // It's not a stream error if it is too small for an OLE storage header
322 if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK )
323 pStream->ResetError();
324 pStream->Seek( nPos );
325 }
326
327 return bRet;
328}
329
330// Open the storage file. If writing is permitted and the file is not
331// a storage file, initialize it.
332
333
334Storage::Storage( OUString aFile, StreamMode m, bool bDirect )
335 : OLEStorageBase( new StgIo, nullptr, m_nMode )
336 , aName(std::move( aFile )), bIsRoot( false )
337{
338 bool bTemp = false;
339 if( aName.isEmpty() )
340 {
341 // no name = temporary name!
343 bTemp = true;
344 }
345 // the root storage creates the I/O system
346 m_nMode = m;
347 if( pIo->Open( aName, m ) )
348 {
349 Init( ( m & ( StreamMode::TRUNC | StreamMode::NOCREATE ) ) == StreamMode::TRUNC );
350 if( pEntry )
351 {
352 pEntry->m_bDirect = bDirect;
353 pEntry->m_nMode = m;
354 pEntry->m_bTemp = bTemp;
355 }
356 }
357 else
358 {
359 pIo->MoveError( *this );
360 pEntry = nullptr;
361 }
362}
363
364// Create a storage on a given stream.
365
366Storage::Storage( SvStream& r, bool bDirect )
367 : OLEStorageBase( new StgIo, nullptr, m_nMode )
368 , bIsRoot( false )
369{
370 m_nMode = StreamMode::READ;
371 if( r.IsWritable() )
372 m_nMode = StreamMode::READ | StreamMode::WRITE;
373 if( r.GetError() == ERRCODE_NONE )
374 {
375 pIo->SetStrm( &r, false );
376 sal_uInt64 nSize = r.TellEnd();
377 r.Seek( 0 );
378 // Initializing is OK if the stream is empty
379 Init( nSize == 0 );
380 if( pEntry )
381 {
382 pEntry->m_bDirect = bDirect;
383 pEntry->m_nMode = m_nMode;
384 }
385 pIo->MoveError( *this );
386 }
387 else
388 {
389 SetError( r.GetError() );
390 pEntry = nullptr;
391 }
392}
393
394
395Storage::Storage( UCBStorageStream& rStrm, bool bDirect )
396 : OLEStorageBase( new StgIo, nullptr, m_nMode ), bIsRoot( false )
397{
398 m_nMode = StreamMode::READ;
399
400 if ( rStrm.GetError() != ERRCODE_NONE )
401 {
403 pEntry = nullptr;
404 return;
405 }
406
407 SvStream* pStream = rStrm.GetModifySvStream();
408 if ( !pStream )
409 {
410 OSL_FAIL( "UCBStorageStream can not provide SvStream implementation!" );
411 SetError( SVSTREAM_GENERALERROR );
412 pEntry = nullptr;
413 return;
414 }
415
416 if( pStream->IsWritable() )
417 m_nMode = StreamMode::READ | StreamMode::WRITE;
418
419 pIo->SetStrm( &rStrm );
420
421 sal_uInt64 nSize = pStream->TellEnd();
422 pStream->Seek( 0 );
423 // Initializing is OK if the stream is empty
424 Init( nSize == 0 );
425 if( pEntry )
426 {
427 pEntry->m_bDirect = bDirect;
428 pEntry->m_nMode = m_nMode;
429 }
430
431 pIo->MoveError( *this );
432}
433
434
435// Perform common code for both ctors above.
436
437void Storage::Init( bool bCreate )
438{
439 pEntry = nullptr;
440 bool bHdrLoaded = false;
441 bIsRoot = true;
442
443 OSL_ENSURE( pIo, "The pointer may not be empty at this point!" );
444 if( pIo->Good() && pIo->GetStrm() )
445 {
446 sal_uInt64 nSize = pIo->GetStrm()->TellEnd();
447 pIo->GetStrm()->Seek( 0 );
448 if( nSize )
449 {
450 bHdrLoaded = pIo->Load();
451 if( !bHdrLoaded && !bCreate )
452 {
453 // File is not a storage and not empty; do not destroy!
454 SetError( SVSTREAM_FILEFORMAT_ERROR );
455 return;
456 }
457 }
458 }
459 // file is a storage, empty or should be overwritten
460 pIo->ResetError();
461 // we have to set up the data structures, since
462 // the file is empty
463 if( !bHdrLoaded )
464 pIo->Init();
465 if( pIo->Good() && pIo->m_pTOC )
466 {
467 pEntry = pIo->m_pTOC->GetRoot();
468 pEntry->m_nRefCnt++;
469 }
470}
471
472// Internal ctor
473
474Storage::Storage( StgIo* p, StgDirEntry* q, StreamMode m )
475 : OLEStorageBase( p, q, m_nMode ), bIsRoot( false )
476{
477 if( q )
478 q->m_aEntry.GetName( aName );
479 else
480 m &= ~StreamMode::READWRITE;
481 m_nMode = m;
482 if( q && q->m_nRefCnt == 1 )
483 q->m_nMode = m;
484}
485
486Storage::~Storage()
487{
488 // Invalidate all open substorages
489 if( m_bAutoCommit )
490 Commit();
491 if( pEntry )
492 {
493 // Do an auto-commit if the entry is open in direct mode
494 if( pEntry->m_nRefCnt && pEntry->m_bDirect && (m_nMode & StreamMode::WRITE) )
495 Commit();
496 if( pEntry->m_nRefCnt == 1 )
497 pEntry->Invalidate(false);
498 }
499 // close the stream is root storage
500 if( bIsRoot )
501 pIo->Close();
502 // remove the file if temporary root storage
503 if( bIsRoot && pEntry && pEntry->m_bTemp )
504 {
505 osl::File::remove( GetName() );
506 }
507}
508
509const OUString& Storage::GetName() const
510{
511 if( !bIsRoot && Validate() )
512 pEntry->m_aEntry.GetName( const_cast<Storage*>(this)->aName );
513 return aName;
514}
515
516// Fill in the info list for this storage
517
518void Storage::FillInfoList( SvStorageInfoList* pList ) const
519{
520 if( !(Validate() && pList) )
521 return;
522
523 StgIterator aIter( *pEntry );
524 StgDirEntry* p = aIter.First();
525 while( p )
526 {
527 if( !p->m_bInvalid )
528 {
529 SvStorageInfo aInfo( *p );
530 pList->push_back( aInfo );
531 }
532 p = aIter.Next();
533 }
534}
535
536// Open or create a substorage
537
538BaseStorage* Storage::OpenUCBStorage( const OUString& rName, StreamMode m, bool bDirect )
539{
540 OSL_FAIL("Not supported!");
541 return OpenStorage( rName, m, bDirect );
542}
543
544BaseStorage* Storage::OpenOLEStorage( const OUString& rName, StreamMode m, bool bDirect )
545{
546 return OpenStorage( rName, m, bDirect );
547}
548
549BaseStorage* Storage::OpenStorage( const OUString& rName, StreamMode m, bool bDirect )
550{
551 if( !Validate() || !ValidateMode( m ) )
552 return new Storage( pIo, nullptr, m );
553 if( bDirect && !pEntry->m_bDirect )
554 bDirect = false;
555
556 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
557 if( !p )
558 {
559 if( !( m & StreamMode::NOCREATE ) )
560 {
561 bool bTemp = false;
562 // create a new storage
563 OUString aNewName = rName;
564 if( aNewName.isEmpty() )
565 {
566 aNewName = "Temp Stg " + OUString::number( ++nTmpCount );
567 bTemp = true;
568 }
569 p = pIo->m_pTOC->Create( *pEntry, aNewName, STG_STORAGE );
570 if( p )
571 p->m_bTemp = bTemp;
572 }
573 if( !p )
574 pIo->SetError( ( m & StreamMode::WRITE )
575 ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
576 }
577 else if( !ValidateMode( m, p ) )
578 p = nullptr;
579 if( p && p->m_aEntry.GetType() != STG_STORAGE )
580 {
581 pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
582 // coverity[overwrite_var] - ownership is not here, but with StgDirStrm
583 p = nullptr;
584 }
585
586 // Either direct or transacted mode is supported
587 if( p && pEntry->m_nRefCnt == 1 )
588 p->m_bDirect = bDirect;
589
590 // Don't check direct conflict if opening readonly
591 if( p && (m & StreamMode::WRITE ))
592 {
593 if( p->m_bDirect != bDirect )
594 SetError( SVSTREAM_ACCESS_DENIED );
595 }
596 Storage* pStg = new Storage( pIo, p, m );
597 pIo->MoveError( *pStg );
598 if( m & StreamMode::WRITE ) pStg->m_bAutoCommit = true;
599 return pStg;
600}
601
602// Open a stream
603
604BaseStorageStream* Storage::OpenStream( const OUString& rName, StreamMode m, bool )
605{
606 if( !Validate() || !ValidateMode( m ) )
607 return new StorageStream( pIo, nullptr, m );
608 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
609 bool bTemp = false;
610 if( !p )
611 {
612 if( !( m & StreamMode::NOCREATE ) )
613 {
614 // create a new stream
615 // make a name if the stream is temporary (has no name)
616 OUString aNewName( rName );
617 if( aNewName.isEmpty() )
618 {
619 aNewName = "Temp Strm " + OUString::number( ++nTmpCount );
620 bTemp = true;
621 }
622 p = pIo->m_pTOC->Create( *pEntry, aNewName, STG_STREAM );
623 }
624 if( !p )
625 pIo->SetError( ( m & StreamMode::WRITE )
626 ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
627 }
628 else if( !ValidateMode( m, p ) )
629 p = nullptr;
630 // coverity[Resource leak : FALSE] - "Create" method is called with STG_STREAM line 620,
631 // so we won't enter into this "if" block here.
632 if( p && p->m_aEntry.GetType() != STG_STREAM )
633 {
634 pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
635 p = nullptr;
636 }
637 if( p )
638 {
639 p->m_bTemp = bTemp;
640 p->m_bDirect = pEntry->m_bDirect;
641 }
642 StorageStream* pStm = new StorageStream( pIo, p, m );
643 if( p && !p->m_bDirect )
644 pStm->SetAutoCommit( true );
645 pIo->MoveError( *pStm );
646 return pStm;
647}
648
649// Delete a stream or substorage by setting the temp bit.
650
651void Storage::Remove( const OUString& rName )
652{
653 if( !Validate( true ) )
654 return;
655 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
656 if( p )
657 {
658 p->Invalidate( true );
659 }
660 else
661 {
662 SetError( SVSTREAM_FILE_NOT_FOUND );
663 }
664}
665
666// Copy one element
667
668bool Storage::CopyTo( const OUString& rElem, BaseStorage* pDest, const OUString& rNew )
669{
670 if( !Validate() || !pDest || !pDest->Validate( true ) )
671 return false;
672 StgDirEntry* pElem = StgDirStrm::Find( *pEntry, rElem );
673 if( pElem )
674 {
675 if( pElem->m_aEntry.GetType() == STG_STORAGE )
676 {
677 // copy the entire storage
678 tools::SvRef<BaseStorage> p1 = OpenStorage( rElem, INTERNAL_MODE );
679 tools::SvRef<BaseStorage> p2 = pDest->OpenOLEStorage( rNew, StreamMode::WRITE | StreamMode::SHARE_DENYALL, pEntry->m_bDirect );
680
681 if ( p2 )
682 {
683 ErrCode nTmpErr = p2->GetError();
684 if( !nTmpErr )
685 {
686 p2->SetClassId( p1->GetClassId() );
687 p1->CopyTo( p2.get() );
688 SetError( p1->GetError() );
689
690 nTmpErr = p2->GetError();
691 if( !nTmpErr )
692 p2->Commit();
693 else
694 pDest->SetError( nTmpErr );
695 }
696 else
697 pDest->SetError( nTmpErr );
698 }
699
700 return Good() && pDest->Good();
701 }
702 else
703 {
704 // stream copy
705 tools::SvRef<BaseStorageStream> p1 = OpenStream( rElem, INTERNAL_MODE );
706 tools::SvRef<BaseStorageStream> p2 = pDest->OpenStream( rNew, StreamMode::WRITE | StreamMode::SHARE_DENYALL, pEntry->m_bDirect );
707
708 if ( p2 )
709 {
710 ErrCode nTmpErr = p2->GetError();
711 if( !nTmpErr )
712 {
713 p1->CopyTo( p2.get() );
714 SetError( p1->GetError() );
715
716 nTmpErr = p2->GetError();
717 if( !nTmpErr )
718 p2->Commit();
719 else
720 pDest->SetError( nTmpErr );
721 }
722 else
723 pDest->SetError( nTmpErr );
724 }
725
726 return Good() && pDest->Good();
727 }
728 }
729 SetError( SVSTREAM_FILE_NOT_FOUND );
730 return false;
731}
732
733bool Storage::CopyTo( BaseStorage* pDest ) const
734{
735 if( !Validate() || !pDest || !pDest->Validate( true ) || Equals( *pDest ) )
736 {
737 SetError( SVSTREAM_ACCESS_DENIED );
738 return false;
739 }
740 Storage* pThis = const_cast<Storage*>(this);
741 pDest->SetClassId( GetClassId() );
742 pDest->SetDirty();
743 SvStorageInfoList aList;
744 FillInfoList( &aList );
745 bool bRes = true;
746 for( size_t i = 0; i < aList.size() && bRes; i++ )
747 {
748 SvStorageInfo& rInfo = aList[ i ];
749 bRes = pThis->CopyTo( rInfo.GetName(), pDest, rInfo.GetName() );
750 }
751 if( !bRes )
752 SetError( pDest->GetError() );
753 return Good() && pDest->Good();
754}
755
756bool Storage::IsStorage( const OUString& rName ) const
757{
758 if( Validate() )
759 {
760 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
761 if( p )
762 return p->m_aEntry.GetType() == STG_STORAGE;
763 }
764 return false;
765}
766
767bool Storage::IsStream( const OUString& rName ) const
768{
769 if( Validate() )
770 {
771 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
772 if( p )
773 return p->m_aEntry.GetType() == STG_STREAM;
774 }
775 return false;
776}
777
778bool Storage::IsContained( const OUString& rName ) const
779{
780 if( Validate() )
781 return StgDirStrm::Find( *pEntry, rName ) != nullptr;
782 else
783 return false;
784}
785
786// Commit all sub-elements within this storage. If this is
787// the root, commit the FAT, the TOC and the header as well.
788
789bool Storage::Commit()
790{
791 bool bRes = true;
792 if( !Validate() )
793 return false;
794 if( !( m_nMode & StreamMode::WRITE ) )
795 {
796 SetError( SVSTREAM_ACCESS_DENIED );
797 return false;
798 }
799 else
800 {
801 // Also commit the sub-streams and Storages
802 StgIterator aIter( *pEntry );
803 for( StgDirEntry* p = aIter.First(); p && bRes; p = aIter.Next() )
804 bRes = p->Commit();
805 if( bRes && bIsRoot )
806 {
807 bRes = pEntry->Commit();
808 if( bRes )
809 bRes = pIo->CommitAll();
810 }
811 pIo->MoveError( *this );
812 }
813 return bRes;
814}
815
816bool Storage::Revert()
817{
818 return true;
819}
820
822
823// Set the storage type
824
825void Storage::SetClass( const SvGlobalName & rClass,
826 SotClipboardFormatId nOriginalClipFormat,
827 const OUString & rUserTypeName )
828{
829 if( Validate( true ) )
830 {
831 // set the class name in the root entry
832 pEntry->m_aEntry.SetClassId( rClass.GetCLSID() );
833 pEntry->SetDirty();
834 // then create the streams
835 StgCompObjStream aCompObj( *this, true );
836 aCompObj.GetClsId() = rClass.GetCLSID();
837 aCompObj.GetCbFormat() = nOriginalClipFormat;
838 aCompObj.GetUserName() = rUserTypeName;
839 if( !aCompObj.Store() )
840 SetError( aCompObj.GetError() );
841 else
842 {
843 StgOleStream aOle(*this);
844 if( !aOle.Store() )
845 SetError( aOle.GetError() );
846 }
847 }
848 else
849 SetError( SVSTREAM_ACCESS_DENIED );
850}
851
852SvGlobalName Storage::GetClassName()
853{
854 StgCompObjStream aCompObj( *this, false );
855 if( aCompObj.Load() )
856 return SvGlobalName( aCompObj.GetClsId() );
857 pIo->ResetError();
858
859 if ( pEntry )
860 return SvGlobalName( pEntry->m_aEntry.GetClassId() );
861
862 return SvGlobalName();
863}
864
865SotClipboardFormatId Storage::GetFormat()
866{
867 StgCompObjStream aCompObj( *this, false );
868 if( aCompObj.Load() )
869 return aCompObj.GetCbFormat();
870 pIo->ResetError();
872}
873
874OUString Storage::GetUserName()
875{
876 StgCompObjStream aCompObj( *this, false );
877 if( aCompObj.Load() )
878 return aCompObj.GetUserName();
879 pIo->ResetError();
880 return OUString();
881}
882
883bool Storage::ValidateFAT()
884{
885 FatError nErr = pIo->ValidateFATs();
886 return nErr == FatError::Ok;
887}
888
889void Storage::SetDirty()
890{
891 if ( pEntry )
892 pEntry->SetDirty();
893}
894
895void Storage::SetClassId( const ClsId& rId )
896{
897 if ( pEntry )
898 pEntry->m_aEntry.SetClassId( rId );
899}
900
901const ClsId& Storage::GetClassId() const
902{
903 if ( pEntry )
904 return pEntry->m_aEntry.GetClassId();
905
906 static const ClsId aDummyId = {0,0,0,{0,0,0,0,0,0,0,0}};
907 return aDummyId;
908}
909
910bool Storage::Validate( bool bValidate ) const
911{
912 bool bRet = Validate_Impl( bValidate );
913 if ( !bRet )
914 SetError( SVSTREAM_ACCESS_DENIED );
915 return bRet;
916}
917
918bool Storage::ValidateMode( StreamMode nMode ) const
919{
920 bool bRet = ValidateMode_Impl( nMode );
921 if ( !bRet )
922 SetError( SVSTREAM_ACCESS_DENIED );
923 return bRet;
924}
925
926bool Storage::ValidateMode( StreamMode nMode, StgDirEntry const * p ) const
927{
928 bool bRet = ValidateMode_Impl( nMode, p );
929 if ( !bRet )
930 SetError( SVSTREAM_ACCESS_DENIED );
931 return bRet;
932}
933
934bool Storage::Equals( const BaseStorage& rStorage ) const
935{
936 const Storage* pOther = dynamic_cast<const Storage*>( &rStorage );
937 return pOther && ( pOther->pEntry == pEntry );
938}
939
940/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool Commit()=0
virtual BaseStorageStream * OpenStream(const OUString &rEleName, StreamMode=StreamMode::STD_READWRITE, bool bDirect=true)=0
virtual BaseStorage * OpenOLEStorage(const OUString &rEleName, StreamMode=StreamMode::STD_READWRITE, bool bDirect=false)=0
virtual void SetDirty()=0
virtual void SetClassId(const ClsId &)=0
StreamMode & nStreamMode
Definition: stg.hxx:116
StgDirEntry * pEntry
Definition: stg.hxx:118
OLEStorageBase(StgIo *, StgDirEntry *, StreamMode &)
Definition: stg.cxx:78
bool Validate_Impl(bool) const
Definition: stg.cxx:113
StgIo * pIo
Definition: stg.hxx:117
static bool ValidateMode_Impl(StreamMode, StgDirEntry const *p=nullptr)
Definition: stg.cxx:122
~OLEStorageBase()
Definition: stg.cxx:87
bool Open(const OUString &rName, StreamMode)
Definition: stgcache.cxx:274
sal_uInt16 DecRef()
Definition: stgcache.hxx:66
void MoveError(StorageBase const &)
Definition: stgcache.cxx:413
bool m_bInvalid
Definition: stgdir.hxx:59
sal_Int32 m_nRefCnt
Definition: stgdir.hxx:54
bool m_bDirect
Definition: stgdir.hxx:57
void Copy(BaseStorageStream &)
Definition: stgdir.cxx:491
bool m_bZombie
Definition: stgdir.hxx:58
StreamMode m_nMode
Definition: stgdir.hxx:55
sal_Int32 Write(const void *, sal_Int32)
Definition: stgdir.cxx:455
void Close()
Definition: stgdir.cxx:278
StgEntry m_aEntry
Definition: stgdir.hxx:53
bool SetSize(sal_Int32)
Definition: stgdir.cxx:301
sal_Int32 Read(void *, sal_Int32)
Definition: stgdir.cxx:432
bool Commit()
Definition: stgdir.cxx:518
sal_Int32 GetSize() const
Definition: stgdir.cxx:288
sal_Int32 Seek(sal_Int32)
Definition: stgdir.cxx:387
void OpenStream(StgIo &)
Definition: stgdir.cxx:256
static StgDirEntry * Find(StgDirEntry &, const OUString &)
Definition: stgdir.cxx:884
sal_Int32 GetSize() const
Definition: stgelem.hxx:130
void GetName(OUString &rName) const
Definition: stgelem.cxx:365
StgEntryType GetType() const
Definition: stgelem.hxx:127
bool Check()
Definition: stgelem.cxx:194
bool Load(StgIo &)
Definition: stgelem.cxx:112
Definition: stgio.hxx:42
bool Load()
Definition: stgio.cxx:55
StgDirStrm * m_pTOC
Definition: stgio.hxx:50
StreamMode m_nMode
Definition: stg.hxx:41
bool m_bAutoCommit
Definition: stg.hxx:42
void SetError(ErrCode) const
Definition: stg.cxx:67
ErrCode m_nError
Definition: stg.hxx:40
bool Good() const
Definition: stg.hxx:51
StorageBase()
Definition: stg.cxx:46
virtual bool Validate(bool=false) const =0
void ResetError() const
Definition: stg.cxx:73
virtual ~StorageBase() override
Definition: stg.cxx:53
ErrCode GetError() const
Definition: stg.cxx:60
void SetAutoCommit(bool bSet)
Definition: stg.hxx:53
virtual void Flush() override
Definition: stg.cxx:223
virtual bool ValidateMode(StreamMode) const override
Definition: stg.cxx:283
virtual bool Commit() final override
Definition: stg.cxx:248
virtual sal_uInt64 GetSize() const override
Definition: stg.cxx:241
virtual sal_Int32 Read(void *pData, sal_Int32 nSize) override
Definition: stg.cxx:184
virtual ~StorageStream() override
Definition: stg.cxx:169
sal_uInt64 nPos
Definition: stg.hxx:128
virtual bool Equals(const BaseStorageStream &rStream) const override
Definition: stg.cxx:178
virtual void CopyTo(BaseStorageStream *pDestStm) override
Definition: stg.cxx:265
virtual bool Validate(bool=false) const override
Definition: stg.cxx:275
StorageStream(StgIo *, StgDirEntry *, StreamMode)
Definition: stg.cxx:152
virtual sal_Int32 Write(const void *pData, sal_Int32 nSize) override
Definition: stg.cxx:198
virtual bool SetSize(sal_uInt64 nNewSize) override
Definition: stg.cxx:229
virtual sal_uInt64 Seek(sal_uInt64 nPos) override
Definition: stg.cxx:212
const SvGUID & GetCLSID() const
OUString aName
Definition: storinfo.hxx:35
const OUString & GetName() const
Definition: storinfo.hxx:50
SvStorageInfo(const StgDirEntry &)
Definition: stg.cxx:293
sal_uInt64 nSize
Definition: storinfo.hxx:36
virtual void ResetError()
bool IsWritable() const
sal_uInt64 Tell() const
virtual sal_uInt64 TellEnd()
sal_uInt64 Seek(sal_uInt64 nPos)
ErrCode GetError() const
ErrCode const & GetErrorCode() const
T * get() const
void Init()
#define DBG_ASSERT(sCon, aError)
virtual OUString GetName() const override
#define SVSTREAM_ACCESS_DENIED
#define ERRCODE_IO_CANTSEEK
#define ERRCODE_NONE
SotClipboardFormatId
Definition: formats.hxx:28
OUString aName
void * p
sal_Int64 n
sal_uInt16 nPos
std::unique_ptr< sal_Int32[]> pData
int i
void SvStream & rStrm
m
long Long
OUString CreateTempName()
#define INTERNAL_MODE
Definition: stg.cxx:41
static tools::Long nTmpCount
Definition: stg.cxx:34
@ STG_STORAGE
Definition: stgelem.hxx:87
@ STG_STREAM
Definition: stgelem.hxx:88
FatError
Definition: stgio.hxx:31
std::vector< SvStorageInfo > SvStorageInfoList
Definition: storinfo.hxx:56
StreamMode
int SetError()