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