LCOV - code coverage report
Current view: top level - sot/source/sdstor - stg.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 400 571 70.1 %
Date: 2015-06-13 12:38:46 Functions: 62 93 66.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11