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