1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // no include "precompiled_tools.hxx" because this file is included in strmsys.cxx 29 30 /* 31 Todo: StreamMode <-> AllocateMemory 32 */ 33 34 #include <string.h> 35 #include <limits.h> 36 37 #include <tools/svwin.h> 38 39 #include <tools/debug.hxx> 40 #include <tools/fsys.hxx> 41 #include <tools/stream.hxx> 42 43 // class FileBase 44 #include <osl/file.hxx> 45 using namespace osl; 46 47 // ----------------------------------------------------------------------- 48 49 // -------------- 50 // - StreamData - 51 // -------------- 52 53 class StreamData 54 { 55 public: 56 HANDLE hFile; 57 58 StreamData() 59 { 60 hFile = 0; 61 } 62 }; 63 64 // ----------------------------------------------------------------------- 65 66 static sal_uIntPtr GetSvError( DWORD nWntError ) 67 { 68 static struct { DWORD wnt; sal_uIntPtr sv; } errArr[] = 69 { 70 { ERROR_SUCCESS, SVSTREAM_OK }, 71 { ERROR_ACCESS_DENIED, SVSTREAM_ACCESS_DENIED }, 72 { ERROR_ACCOUNT_DISABLED, SVSTREAM_ACCESS_DENIED }, 73 { ERROR_ACCOUNT_EXPIRED, SVSTREAM_ACCESS_DENIED }, 74 { ERROR_ACCOUNT_RESTRICTION, SVSTREAM_ACCESS_DENIED }, 75 { ERROR_ATOMIC_LOCKS_NOT_SUPPORTED, SVSTREAM_INVALID_PARAMETER }, 76 { ERROR_BAD_PATHNAME, SVSTREAM_PATH_NOT_FOUND }, 77 // Filename too long 78 { ERROR_BUFFER_OVERFLOW, SVSTREAM_INVALID_PARAMETER }, 79 { ERROR_DIRECTORY, SVSTREAM_INVALID_PARAMETER }, 80 { ERROR_DRIVE_LOCKED, SVSTREAM_LOCKING_VIOLATION }, 81 { ERROR_FILE_NOT_FOUND, SVSTREAM_FILE_NOT_FOUND }, 82 { ERROR_FILENAME_EXCED_RANGE, SVSTREAM_INVALID_PARAMETER }, 83 { ERROR_INVALID_ACCESS, SVSTREAM_INVALID_ACCESS }, 84 { ERROR_INVALID_DRIVE, SVSTREAM_PATH_NOT_FOUND }, 85 { ERROR_INVALID_HANDLE, SVSTREAM_INVALID_HANDLE }, 86 { ERROR_INVALID_NAME, SVSTREAM_PATH_NOT_FOUND }, 87 { ERROR_INVALID_PARAMETER, SVSTREAM_INVALID_PARAMETER }, 88 { ERROR_IS_SUBST_PATH, SVSTREAM_INVALID_PARAMETER }, 89 { ERROR_IS_SUBST_TARGET, SVSTREAM_INVALID_PARAMETER }, 90 { ERROR_LOCK_FAILED, SVSTREAM_LOCKING_VIOLATION }, 91 { ERROR_LOCK_VIOLATION, SVSTREAM_LOCKING_VIOLATION }, 92 { ERROR_NEGATIVE_SEEK, SVSTREAM_SEEK_ERROR }, 93 { ERROR_PATH_NOT_FOUND, SVSTREAM_PATH_NOT_FOUND }, 94 { ERROR_READ_FAULT, SVSTREAM_READ_ERROR }, 95 { ERROR_SEEK, SVSTREAM_SEEK_ERROR }, 96 { ERROR_SEEK_ON_DEVICE, SVSTREAM_SEEK_ERROR }, 97 { ERROR_SHARING_BUFFER_EXCEEDED,SVSTREAM_SHARE_BUFF_EXCEEDED }, 98 { ERROR_SHARING_PAUSED, SVSTREAM_SHARING_VIOLATION }, 99 { ERROR_SHARING_VIOLATION, SVSTREAM_SHARING_VIOLATION }, 100 { ERROR_TOO_MANY_OPEN_FILES, SVSTREAM_TOO_MANY_OPEN_FILES }, 101 { ERROR_WRITE_FAULT, SVSTREAM_WRITE_ERROR }, 102 { ERROR_WRITE_PROTECT, SVSTREAM_ACCESS_DENIED }, 103 { ERROR_DISK_FULL, SVSTREAM_DISK_FULL }, 104 105 { (DWORD)0xFFFFFFFF, SVSTREAM_GENERALERROR } 106 }; 107 108 sal_uIntPtr nRetVal = SVSTREAM_GENERALERROR; // Standardfehler 109 int i=0; 110 do 111 { 112 if( errArr[i].wnt == nWntError ) 113 { 114 nRetVal = errArr[i].sv; 115 break; 116 } 117 i++; 118 } while( errArr[i].wnt != (DWORD)0xFFFFFFFF ); 119 return nRetVal; 120 } 121 122 /************************************************************************* 123 |* 124 |* SvFileStream::SvFileStream() 125 |* 126 |* Beschreibung STREAM.SDW 127 |* Ersterstellung OV 17.06.94 128 |* Letzte Aenderung TPF 15.07.98 129 |* 130 *************************************************************************/ 131 132 SvFileStream::SvFileStream( const String& rFileName, StreamMode nMode ) 133 { 134 bIsOpen = sal_False; 135 nLockCounter = 0; 136 bIsWritable = sal_False; 137 pInstanceData = new StreamData; 138 139 SetBufferSize( 8192 ); 140 // convert URL to SystemPath, if necessary 141 ::rtl::OUString aFileName, aNormPath; 142 143 if ( FileBase::getSystemPathFromFileURL( rFileName, aFileName ) != FileBase::E_None ) 144 aFileName = rFileName; 145 Open( aFileName, nMode ); 146 } 147 148 /************************************************************************* 149 |* 150 |* SvFileStream::SvFileStream() 151 |* 152 |* Beschreibung STREAM.SDW 153 |* Ersterstellung OV 22.11.94 154 |* Letzte Aenderung TPF 15.07.98 155 |* 156 *************************************************************************/ 157 158 SvFileStream::SvFileStream() 159 { 160 bIsOpen = sal_False; 161 nLockCounter = 0; 162 bIsWritable = sal_False; 163 pInstanceData = new StreamData; 164 165 SetBufferSize( 8192 ); 166 } 167 168 /************************************************************************* 169 |* 170 |* SvFileStream::~SvFileStream() 171 |* 172 |* Beschreibung STREAM.SDW 173 |* Ersterstellung OV 14.06.94 174 |* Letzte Aenderung OV 14.06.94 175 |* 176 *************************************************************************/ 177 178 SvFileStream::~SvFileStream() 179 { 180 Close(); 181 if (pInstanceData) 182 delete pInstanceData; 183 } 184 185 /************************************************************************* 186 |* 187 |* SvFileStream::GetFileHandle() 188 |* 189 |* Beschreibung STREAM.SDW 190 |* Ersterstellung OV 14.06.94 191 |* Letzte Aenderung OV 14.06.94 192 |* 193 *************************************************************************/ 194 195 sal_uIntPtr SvFileStream::GetFileHandle() const 196 { 197 return (sal_uIntPtr)pInstanceData->hFile; 198 } 199 200 /************************************************************************* 201 |* 202 |* SvFileStream::IsA() 203 |* 204 |* Beschreibung STREAM.SDW 205 |* Ersterstellung OV 14.06.94 206 |* Letzte Aenderung OV 14.06.94 207 |* 208 *************************************************************************/ 209 210 sal_uInt16 SvFileStream::IsA() const 211 { 212 return ID_FILESTREAM; 213 } 214 215 /************************************************************************* 216 |* 217 |* SvFileStream::GetData() 218 |* 219 |* Beschreibung STREAM.SDW, Prueft nicht Eof; IsEof danach rufbar 220 |* Ersterstellung OV 15.06.94 221 |* Letzte Aenderung TPF 15.07.98 222 |* 223 *************************************************************************/ 224 225 sal_uIntPtr SvFileStream::GetData( void* pData, sal_uIntPtr nSize ) 226 { 227 DWORD nCount = 0; 228 if( IsOpen() ) 229 { 230 bool bResult = ReadFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL); 231 if( !bResult ) 232 { 233 sal_uIntPtr nTestError = GetLastError(); 234 SetError(::GetSvError( nTestError ) ); 235 } 236 } 237 return (DWORD)nCount; 238 } 239 240 /************************************************************************* 241 |* 242 |* SvFileStream::PutData() 243 |* 244 |* Beschreibung STREAM.SDW 245 |* Ersterstellung OV 15.06.94 246 |* Letzte Aenderung TPF 15.07.98 247 |* 248 *************************************************************************/ 249 250 sal_uIntPtr SvFileStream::PutData( const void* pData, sal_uIntPtr nSize ) 251 { 252 DWORD nCount = 0; 253 if( IsOpen() ) 254 { 255 if(!WriteFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL)) 256 SetError(::GetSvError( GetLastError() ) ); 257 } 258 return nCount; 259 } 260 261 /************************************************************************* 262 |* 263 |* SvFileStream::SeekPos() 264 |* 265 |* Beschreibung STREAM.SDW 266 |* Ersterstellung OV 15.06.94 267 |* Letzte Aenderung TPF 15.07.98 268 |* 269 *************************************************************************/ 270 271 sal_uIntPtr SvFileStream::SeekPos( sal_uIntPtr nPos ) 272 { 273 DWORD nNewPos = 0; 274 if( IsOpen() ) 275 { 276 if( nPos != STREAM_SEEK_TO_END ) 277 // 64-Bit files werden nicht unterstuetzt 278 nNewPos=SetFilePointer(pInstanceData->hFile,nPos,NULL,FILE_BEGIN); 279 else 280 nNewPos=SetFilePointer(pInstanceData->hFile,0L,NULL,FILE_END); 281 282 if( nNewPos == 0xFFFFFFFF ) 283 { 284 SetError(::GetSvError( GetLastError() ) ); 285 nNewPos = 0L; 286 } 287 } 288 else 289 SetError( SVSTREAM_GENERALERROR ); 290 return (sal_uIntPtr)nNewPos; 291 } 292 293 /************************************************************************* 294 |* 295 |* SvFileStream::Tell() 296 |* 297 |* Beschreibung STREAM.SDW 298 |* Ersterstellung OV 15.06.94 299 |* Letzte Aenderung OV 15.06.94 300 |* 301 *************************************************************************/ 302 /* 303 sal_uIntPtr SvFileStream::Tell() 304 { 305 sal_uIntPtr nPos = 0L; 306 307 if( IsOpen() ) 308 { 309 DWORD nPos; 310 nPos = SetFilePointer(pInstanceData->hFile,0L,NULL,FILE_CURRENT); 311 if( nPos = 0xFFFFFFFF ) 312 { 313 SetError( ::GetSvError( GetLastError() ) ); 314 nPos = 0L; 315 } 316 } 317 return nPos; 318 } 319 */ 320 321 /************************************************************************* 322 |* 323 |* SvFileStream::FlushData() 324 |* 325 |* Beschreibung STREAM.SDW 326 |* Ersterstellung OV 15.06.94 327 |* Letzte Aenderung TPF 15.07.98 328 |* 329 *************************************************************************/ 330 331 void SvFileStream::FlushData() 332 { 333 if( IsOpen() ) 334 { 335 if( !FlushFileBuffers(pInstanceData->hFile) ) 336 SetError(::GetSvError(GetLastError())); 337 } 338 } 339 340 /************************************************************************* 341 |* 342 |* SvFileStream::LockRange() 343 |* 344 |* Beschreibung STREAM.SDW 345 |* Ersterstellung OV 15.06.94 346 |* Letzte Aenderung TPF 15.07.98 347 |* 348 *************************************************************************/ 349 350 sal_Bool SvFileStream::LockRange( sal_uIntPtr nByteOffset, sal_uIntPtr nBytes ) 351 { 352 bool bRetVal = false; 353 if( IsOpen() ) 354 { 355 bRetVal = ::LockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L ); 356 if( !bRetVal ) 357 SetError(::GetSvError(GetLastError())); 358 } 359 return bRetVal; 360 } 361 362 /************************************************************************* 363 |* 364 |* SvFileStream::UnlockRange() 365 |* 366 |* Beschreibung STREAM.SDW 367 |* Ersterstellung OV 15.06.94 368 |* Letzte Aenderung TPF 15.07.98 369 |* 370 *************************************************************************/ 371 372 sal_Bool SvFileStream::UnlockRange( sal_uIntPtr nByteOffset, sal_uIntPtr nBytes ) 373 { 374 bool bRetVal = false; 375 if( IsOpen() ) 376 { 377 bRetVal = ::UnlockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L ); 378 if( !bRetVal ) 379 SetError(::GetSvError(GetLastError())); 380 } 381 return bRetVal; 382 } 383 384 /************************************************************************* 385 |* 386 |* SvFileStream::LockFile() 387 |* 388 |* Beschreibung STREAM.SDW 389 |* Ersterstellung OV 15.06.94 390 |* Letzte Aenderung OV 15.06.94 391 |* 392 *************************************************************************/ 393 394 sal_Bool SvFileStream::LockFile() 395 { 396 sal_Bool bRetVal = sal_False; 397 if( !nLockCounter ) 398 { 399 if( LockRange( 0L, LONG_MAX ) ) 400 { 401 nLockCounter = 1; 402 bRetVal = sal_True; 403 } 404 } 405 else 406 { 407 nLockCounter++; 408 bRetVal = sal_True; 409 } 410 return bRetVal; 411 } 412 413 /************************************************************************* 414 |* 415 |* SvFileStream::UnlockFile() 416 |* 417 |* Beschreibung STREAM.SDW 418 |* Ersterstellung OV 15.06.94 419 |* Letzte Aenderung OV 15.06.94 420 |* 421 *************************************************************************/ 422 423 sal_Bool SvFileStream::UnlockFile() 424 { 425 sal_Bool bRetVal = sal_False; 426 if( nLockCounter > 0) 427 { 428 if( nLockCounter == 1) 429 { 430 if( UnlockRange( 0L, LONG_MAX ) ) 431 { 432 nLockCounter = 0; 433 bRetVal = sal_True; 434 } 435 } 436 else 437 { 438 nLockCounter--; 439 bRetVal = sal_True; 440 } 441 } 442 return bRetVal; 443 } 444 445 446 /************************************************************************* 447 |* 448 |* SvFileStream::Open() 449 |* 450 |* Beschreibung STREAM.SDW 451 |* Ersterstellung OV 15.06.94 452 |* Letzte Aenderung TPF 15.07.98 453 |* 454 *************************************************************************/ 455 /* 456 NOCREATE TRUNC NT-Action 457 ---------------------------------------------- 458 0 (Create) 0 OPEN_ALWAYS 459 0 (Create) 1 CREATE_ALWAYS 460 1 0 OPEN_EXISTING 461 1 1 TRUNCATE_EXISTING 462 */ 463 464 void SvFileStream::Open( const String& rFilename, StreamMode nMode ) 465 { 466 String aParsedFilename(rFilename); 467 468 SetLastError( ERROR_SUCCESS ); 469 Close(); 470 SvStream::ClearBuffer(); 471 472 eStreamMode = nMode; 473 eStreamMode &= ~STREAM_TRUNC; // beim ReOpen nicht cutten 474 475 // !!! NoOp: Ansonsten ToAbs() verwendern 476 // !!! DirEntry aDirEntry( rFilename ); 477 // !!! aFilename = aDirEntry.GetFull(); 478 aFilename = aParsedFilename; 479 #ifdef BOOTSTRAP 480 ByteString aFileNameA( aFilename, gsl_getSystemTextEncoding()); 481 #else 482 ByteString aFileNameA( aFilename, osl_getThreadTextEncoding()); 483 FSysRedirector::DoRedirect( aFilename ); 484 #endif 485 SetLastError( ERROR_SUCCESS ); // ggf. durch Redirector geaendert! 486 487 /* 488 #ifdef DBG_UTIL 489 String aTraceStr( "SvFileStream::Open(): " ); 490 aTraceStr += aFilename; 491 DBG_TRACE( aTraceStr ); 492 #endif 493 */ 494 495 DWORD nOpenAction; 496 DWORD nShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 497 DWORD nAccessMode = 0L; 498 UINT nOldErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX ); 499 500 if( nMode & STREAM_SHARE_DENYREAD) 501 nShareMode &= ~FILE_SHARE_READ; 502 503 if( nMode & STREAM_SHARE_DENYWRITE) 504 nShareMode &= ~FILE_SHARE_WRITE; 505 506 if( nMode & STREAM_SHARE_DENYALL) 507 nShareMode = 0; 508 509 if( (nMode & STREAM_READ) ) 510 nAccessMode |= GENERIC_READ; 511 if( (nMode & STREAM_WRITE) ) 512 nAccessMode |= GENERIC_WRITE; 513 514 if( nAccessMode == GENERIC_READ ) // ReadOnly ? 515 nMode |= STREAM_NOCREATE; // wenn ja, nicht erzeugen 516 517 // Zuordnung siehe obige Wahrheitstafel 518 if( !(nMode & STREAM_NOCREATE) ) 519 { 520 if( nMode & STREAM_TRUNC ) 521 nOpenAction = CREATE_ALWAYS; 522 else 523 nOpenAction = OPEN_ALWAYS; 524 } 525 else 526 { 527 if( nMode & STREAM_TRUNC ) 528 nOpenAction = TRUNCATE_EXISTING; 529 else 530 nOpenAction = OPEN_EXISTING; 531 } 532 533 pInstanceData->hFile = CreateFile( 534 aFileNameA.GetBuffer(), 535 nAccessMode, 536 nShareMode, 537 (LPSECURITY_ATTRIBUTES)NULL, 538 nOpenAction, 539 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 540 (HANDLE) NULL 541 ); 542 543 if( pInstanceData->hFile!=INVALID_HANDLE_VALUE && ( 544 // Hat Create Always eine existierende Datei ueberschrieben ? 545 GetLastError() == ERROR_ALREADY_EXISTS || 546 // Hat Open Always eine neue Datei angelegt ? 547 GetLastError() == ERROR_FILE_NOT_FOUND )) 548 { 549 // wenn ja, dann alles OK 550 if( nOpenAction == OPEN_ALWAYS || nOpenAction == CREATE_ALWAYS ) 551 SetLastError( ERROR_SUCCESS ); 552 } 553 554 // Bei Fehler pruefen, ob wir lesen duerfen 555 if( (pInstanceData->hFile==INVALID_HANDLE_VALUE) && 556 (nAccessMode & GENERIC_WRITE)) 557 { 558 sal_uIntPtr nErr = ::GetSvError( GetLastError() ); 559 if(nErr==SVSTREAM_ACCESS_DENIED || nErr==SVSTREAM_SHARING_VIOLATION) 560 { 561 nMode &= (~STREAM_WRITE); 562 nAccessMode = GENERIC_READ; 563 // OV, 28.1.97: Win32 setzt die Datei auf 0-Laenge, wenn 564 // die Openaction CREATE_ALWAYS ist!!!! 565 nOpenAction = OPEN_EXISTING; 566 SetLastError( ERROR_SUCCESS ); 567 pInstanceData->hFile = CreateFile( 568 aFileNameA.GetBuffer(), 569 GENERIC_READ, 570 nShareMode, 571 (LPSECURITY_ATTRIBUTES)NULL, 572 nOpenAction, 573 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 574 (HANDLE) NULL 575 ); 576 if( GetLastError() == ERROR_ALREADY_EXISTS ) 577 SetLastError( ERROR_SUCCESS ); 578 } 579 } 580 581 if( GetLastError() != ERROR_SUCCESS ) 582 { 583 bIsOpen = sal_False; 584 SetError(::GetSvError( GetLastError() ) ); 585 } 586 else 587 { 588 bIsOpen = sal_True; 589 // pInstanceData->bIsEof = sal_False; 590 if( nAccessMode & GENERIC_WRITE ) 591 bIsWritable = sal_True; 592 } 593 SetErrorMode( nOldErrorMode ); 594 } 595 596 /************************************************************************* 597 |* 598 |* SvFileStream::ReOpen() 599 |* 600 |* Beschreibung STREAM.SDW 601 |* Ersterstellung OV 15.06.94 602 |* Letzte Aenderung OV 15.06.94 603 |* 604 *************************************************************************/ 605 606 void SvFileStream::ReOpen() 607 { 608 if( !bIsOpen && aFilename.Len() ) 609 Open( aFilename, eStreamMode ); 610 } 611 612 /************************************************************************* 613 |* 614 |* SvFileStream::Close() 615 |* 616 |* Beschreibung STREAM.SDW 617 |* Ersterstellung OV 15.06.94 618 |* Letzte Aenderung TPF 15.07.98 619 |* 620 *************************************************************************/ 621 622 void SvFileStream::Close() 623 { 624 if( IsOpen() ) 625 { 626 if( nLockCounter ) 627 { 628 nLockCounter = 1; 629 UnlockFile(); 630 } 631 Flush(); 632 CloseHandle( pInstanceData->hFile ); 633 } 634 bIsOpen = sal_False; 635 nLockCounter= 0; 636 bIsWritable = sal_False; 637 SvStream::ClearBuffer(); 638 SvStream::ClearError(); 639 } 640 641 /************************************************************************* 642 |* 643 |* SvFileStream::ResetError() 644 |* 645 |* Beschreibung STREAM.SDW; Setzt Filepointer auf Dateianfang 646 |* Ersterstellung OV 15.06.94 647 |* Letzte Aenderung OV 15.06.94 648 |* 649 *************************************************************************/ 650 651 void SvFileStream::ResetError() 652 { 653 SvStream::ClearError(); 654 } 655 656 /************************************************************************* 657 |* 658 |* SvFileStream::SetSize() 659 |* 660 |* Beschreibung STREAM.SDW 661 |* Ersterstellung OV 19.10.95 662 |* Letzte Aenderung TPF 15.07.98 663 |* 664 *************************************************************************/ 665 666 void SvFileStream::SetSize( sal_uIntPtr nSize ) 667 { 668 669 if( IsOpen() ) 670 { 671 int bError = sal_False; 672 HANDLE hFile = pInstanceData->hFile; 673 sal_uIntPtr nOld = SetFilePointer( hFile, 0L, NULL, FILE_CURRENT ); 674 if( nOld != 0xffffffff ) 675 { 676 if( SetFilePointer(hFile,nSize,NULL,FILE_BEGIN ) != 0xffffffff) 677 { 678 bool bSucc = SetEndOfFile( hFile ); 679 if( !bSucc ) 680 bError = sal_True; 681 } 682 if( SetFilePointer( hFile,nOld,NULL,FILE_BEGIN ) == 0xffffffff) 683 bError = sal_True; 684 } 685 if( bError ) 686 SetError(::GetSvError( GetLastError() ) ); 687 } 688 } 689 690