Update ooo320-m1
[ooovba.git] / tools / source / stream / strmwnt.cxx
blob56da0e8cd89b2a49624184d95c205fb8811f871f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: strmwnt.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // no include "precompiled_tools.hxx" because this file is included in strmsys.cxx
34 Todo: StreamMode <-> AllocateMemory
37 #include <string.h>
38 #include <limits.h>
40 #include <tools/svwin.h>
42 #include <tools/debug.hxx>
43 #include <tools/fsys.hxx>
44 #include <tools/stream.hxx>
46 // class FileBase
47 #include <osl/file.hxx>
48 using namespace osl;
50 // -----------------------------------------------------------------------
52 // --------------
53 // - StreamData -
54 // --------------
56 class StreamData
58 public:
59 HANDLE hFile;
61 StreamData()
63 hFile = 0;
67 // -----------------------------------------------------------------------
69 static ULONG GetSvError( DWORD nWntError )
71 static struct { DWORD wnt; ULONG sv; } errArr[] =
73 { ERROR_SUCCESS, SVSTREAM_OK },
74 { ERROR_ACCESS_DENIED, SVSTREAM_ACCESS_DENIED },
75 { ERROR_ACCOUNT_DISABLED, SVSTREAM_ACCESS_DENIED },
76 { ERROR_ACCOUNT_EXPIRED, SVSTREAM_ACCESS_DENIED },
77 { ERROR_ACCOUNT_RESTRICTION, SVSTREAM_ACCESS_DENIED },
78 { ERROR_ATOMIC_LOCKS_NOT_SUPPORTED, SVSTREAM_INVALID_PARAMETER },
79 { ERROR_BAD_PATHNAME, SVSTREAM_PATH_NOT_FOUND },
80 // Filename too long
81 { ERROR_BUFFER_OVERFLOW, SVSTREAM_INVALID_PARAMETER },
82 { ERROR_DIRECTORY, SVSTREAM_INVALID_PARAMETER },
83 { ERROR_DRIVE_LOCKED, SVSTREAM_LOCKING_VIOLATION },
84 { ERROR_FILE_NOT_FOUND, SVSTREAM_FILE_NOT_FOUND },
85 { ERROR_FILENAME_EXCED_RANGE, SVSTREAM_INVALID_PARAMETER },
86 { ERROR_INVALID_ACCESS, SVSTREAM_INVALID_ACCESS },
87 { ERROR_INVALID_DRIVE, SVSTREAM_PATH_NOT_FOUND },
88 { ERROR_INVALID_HANDLE, SVSTREAM_INVALID_HANDLE },
89 { ERROR_INVALID_NAME, SVSTREAM_PATH_NOT_FOUND },
90 { ERROR_INVALID_PARAMETER, SVSTREAM_INVALID_PARAMETER },
91 { ERROR_IS_SUBST_PATH, SVSTREAM_INVALID_PARAMETER },
92 { ERROR_IS_SUBST_TARGET, SVSTREAM_INVALID_PARAMETER },
93 { ERROR_LOCK_FAILED, SVSTREAM_LOCKING_VIOLATION },
94 { ERROR_LOCK_VIOLATION, SVSTREAM_LOCKING_VIOLATION },
95 { ERROR_NEGATIVE_SEEK, SVSTREAM_SEEK_ERROR },
96 { ERROR_PATH_NOT_FOUND, SVSTREAM_PATH_NOT_FOUND },
97 { ERROR_READ_FAULT, SVSTREAM_READ_ERROR },
98 { ERROR_SEEK, SVSTREAM_SEEK_ERROR },
99 { ERROR_SEEK_ON_DEVICE, SVSTREAM_SEEK_ERROR },
100 { ERROR_SHARING_BUFFER_EXCEEDED,SVSTREAM_SHARE_BUFF_EXCEEDED },
101 { ERROR_SHARING_PAUSED, SVSTREAM_SHARING_VIOLATION },
102 { ERROR_SHARING_VIOLATION, SVSTREAM_SHARING_VIOLATION },
103 { ERROR_TOO_MANY_OPEN_FILES, SVSTREAM_TOO_MANY_OPEN_FILES },
104 { ERROR_WRITE_FAULT, SVSTREAM_WRITE_ERROR },
105 { ERROR_WRITE_PROTECT, SVSTREAM_ACCESS_DENIED },
106 { ERROR_DISK_FULL, SVSTREAM_DISK_FULL },
108 { (DWORD)0xFFFFFFFF, SVSTREAM_GENERALERROR }
111 ULONG nRetVal = SVSTREAM_GENERALERROR; // Standardfehler
112 int i=0;
115 if( errArr[i].wnt == nWntError )
117 nRetVal = errArr[i].sv;
118 break;
120 i++;
121 } while( errArr[i].wnt != (DWORD)0xFFFFFFFF );
122 return nRetVal;
125 /*************************************************************************
127 |* SvFileStream::SvFileStream()
129 |* Beschreibung STREAM.SDW
130 |* Ersterstellung OV 17.06.94
131 |* Letzte Aenderung TPF 15.07.98
133 *************************************************************************/
135 SvFileStream::SvFileStream( const String& rFileName, StreamMode nMode )
137 bIsOpen = FALSE;
138 nLockCounter = 0;
139 bIsWritable = FALSE;
140 pInstanceData = new StreamData;
142 SetBufferSize( 8192 );
143 // convert URL to SystemPath, if necessary
144 ::rtl::OUString aFileName, aNormPath;
146 if ( FileBase::getSystemPathFromFileURL( rFileName, aFileName ) != FileBase::E_None )
147 aFileName = rFileName;
148 Open( aFileName, nMode );
151 /*************************************************************************
153 |* SvFileStream::SvFileStream()
155 |* Beschreibung STREAM.SDW
156 |* Ersterstellung OV 22.11.94
157 |* Letzte Aenderung TPF 15.07.98
159 *************************************************************************/
161 SvFileStream::SvFileStream()
163 bIsOpen = FALSE;
164 nLockCounter = 0;
165 bIsWritable = FALSE;
166 pInstanceData = new StreamData;
168 SetBufferSize( 8192 );
171 /*************************************************************************
173 |* SvFileStream::~SvFileStream()
175 |* Beschreibung STREAM.SDW
176 |* Ersterstellung OV 14.06.94
177 |* Letzte Aenderung OV 14.06.94
179 *************************************************************************/
181 SvFileStream::~SvFileStream()
183 Close();
184 if (pInstanceData)
185 delete pInstanceData;
188 /*************************************************************************
190 |* SvFileStream::GetFileHandle()
192 |* Beschreibung STREAM.SDW
193 |* Ersterstellung OV 14.06.94
194 |* Letzte Aenderung OV 14.06.94
196 *************************************************************************/
198 ULONG SvFileStream::GetFileHandle() const
200 return (ULONG)pInstanceData->hFile;
203 /*************************************************************************
205 |* SvFileStream::IsA()
207 |* Beschreibung STREAM.SDW
208 |* Ersterstellung OV 14.06.94
209 |* Letzte Aenderung OV 14.06.94
211 *************************************************************************/
213 USHORT SvFileStream::IsA() const
215 return ID_FILESTREAM;
218 /*************************************************************************
220 |* SvFileStream::GetData()
222 |* Beschreibung STREAM.SDW, Prueft nicht Eof; IsEof danach rufbar
223 |* Ersterstellung OV 15.06.94
224 |* Letzte Aenderung TPF 15.07.98
226 *************************************************************************/
228 ULONG SvFileStream::GetData( void* pData, ULONG nSize )
230 DWORD nCount = 0;
231 if( IsOpen() )
233 bool bResult = ReadFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL);
234 if( !bResult )
236 ULONG nTestError = GetLastError();
237 SetError(::GetSvError( nTestError ) );
240 return (DWORD)nCount;
243 /*************************************************************************
245 |* SvFileStream::PutData()
247 |* Beschreibung STREAM.SDW
248 |* Ersterstellung OV 15.06.94
249 |* Letzte Aenderung TPF 15.07.98
251 *************************************************************************/
253 ULONG SvFileStream::PutData( const void* pData, ULONG nSize )
255 DWORD nCount = 0;
256 if( IsOpen() )
258 if(!WriteFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL))
259 SetError(::GetSvError( GetLastError() ) );
261 return nCount;
264 /*************************************************************************
266 |* SvFileStream::SeekPos()
268 |* Beschreibung STREAM.SDW
269 |* Ersterstellung OV 15.06.94
270 |* Letzte Aenderung TPF 15.07.98
272 *************************************************************************/
274 ULONG SvFileStream::SeekPos( ULONG nPos )
276 DWORD nNewPos = 0;
277 if( IsOpen() )
279 if( nPos != STREAM_SEEK_TO_END )
280 // 64-Bit files werden nicht unterstuetzt
281 nNewPos=SetFilePointer(pInstanceData->hFile,nPos,NULL,FILE_BEGIN);
282 else
283 nNewPos=SetFilePointer(pInstanceData->hFile,0L,NULL,FILE_END);
285 if( nNewPos == 0xFFFFFFFF )
287 SetError(::GetSvError( GetLastError() ) );
288 nNewPos = 0L;
291 else
292 SetError( SVSTREAM_GENERALERROR );
293 return (ULONG)nNewPos;
296 /*************************************************************************
298 |* SvFileStream::Tell()
300 |* Beschreibung STREAM.SDW
301 |* Ersterstellung OV 15.06.94
302 |* Letzte Aenderung OV 15.06.94
304 *************************************************************************/
306 ULONG SvFileStream::Tell()
308 ULONG nPos = 0L;
310 if( IsOpen() )
312 DWORD nPos;
313 nPos = SetFilePointer(pInstanceData->hFile,0L,NULL,FILE_CURRENT);
314 if( nPos = 0xFFFFFFFF )
316 SetError( ::GetSvError( GetLastError() ) );
317 nPos = 0L;
320 return nPos;
324 /*************************************************************************
326 |* SvFileStream::FlushData()
328 |* Beschreibung STREAM.SDW
329 |* Ersterstellung OV 15.06.94
330 |* Letzte Aenderung TPF 15.07.98
332 *************************************************************************/
334 void SvFileStream::FlushData()
336 if( IsOpen() )
338 if( !FlushFileBuffers(pInstanceData->hFile) )
339 SetError(::GetSvError(GetLastError()));
343 /*************************************************************************
345 |* SvFileStream::LockRange()
347 |* Beschreibung STREAM.SDW
348 |* Ersterstellung OV 15.06.94
349 |* Letzte Aenderung TPF 15.07.98
351 *************************************************************************/
353 BOOL SvFileStream::LockRange( ULONG nByteOffset, ULONG nBytes )
355 bool bRetVal = false;
356 if( IsOpen() )
358 bRetVal = ::LockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L );
359 if( !bRetVal )
360 SetError(::GetSvError(GetLastError()));
362 return bRetVal;
365 /*************************************************************************
367 |* SvFileStream::UnlockRange()
369 |* Beschreibung STREAM.SDW
370 |* Ersterstellung OV 15.06.94
371 |* Letzte Aenderung TPF 15.07.98
373 *************************************************************************/
375 BOOL SvFileStream::UnlockRange( ULONG nByteOffset, ULONG nBytes )
377 bool bRetVal = false;
378 if( IsOpen() )
380 bRetVal = ::UnlockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L );
381 if( !bRetVal )
382 SetError(::GetSvError(GetLastError()));
384 return bRetVal;
387 /*************************************************************************
389 |* SvFileStream::LockFile()
391 |* Beschreibung STREAM.SDW
392 |* Ersterstellung OV 15.06.94
393 |* Letzte Aenderung OV 15.06.94
395 *************************************************************************/
397 BOOL SvFileStream::LockFile()
399 BOOL bRetVal = FALSE;
400 if( !nLockCounter )
402 if( LockRange( 0L, LONG_MAX ) )
404 nLockCounter = 1;
405 bRetVal = TRUE;
408 else
410 nLockCounter++;
411 bRetVal = TRUE;
413 return bRetVal;
416 /*************************************************************************
418 |* SvFileStream::UnlockFile()
420 |* Beschreibung STREAM.SDW
421 |* Ersterstellung OV 15.06.94
422 |* Letzte Aenderung OV 15.06.94
424 *************************************************************************/
426 BOOL SvFileStream::UnlockFile()
428 BOOL bRetVal = FALSE;
429 if( nLockCounter > 0)
431 if( nLockCounter == 1)
433 if( UnlockRange( 0L, LONG_MAX ) )
435 nLockCounter = 0;
436 bRetVal = TRUE;
439 else
441 nLockCounter--;
442 bRetVal = TRUE;
445 return bRetVal;
449 /*************************************************************************
451 |* SvFileStream::Open()
453 |* Beschreibung STREAM.SDW
454 |* Ersterstellung OV 15.06.94
455 |* Letzte Aenderung TPF 15.07.98
457 *************************************************************************/
459 NOCREATE TRUNC NT-Action
460 ----------------------------------------------
461 0 (Create) 0 OPEN_ALWAYS
462 0 (Create) 1 CREATE_ALWAYS
463 1 0 OPEN_EXISTING
464 1 1 TRUNCATE_EXISTING
467 void SvFileStream::Open( const String& rFilename, StreamMode nMode )
469 String aParsedFilename(rFilename);
471 SetLastError( ERROR_SUCCESS );
472 Close();
473 SvStream::ClearBuffer();
475 eStreamMode = nMode;
476 eStreamMode &= ~STREAM_TRUNC; // beim ReOpen nicht cutten
478 // !!! NoOp: Ansonsten ToAbs() verwendern
479 // !!! DirEntry aDirEntry( rFilename );
480 // !!! aFilename = aDirEntry.GetFull();
481 aFilename = aParsedFilename;
482 #ifdef BOOTSTRAP
483 ByteString aFileNameA( aFilename, gsl_getSystemTextEncoding());
484 #else
485 ByteString aFileNameA( aFilename, osl_getThreadTextEncoding());
486 FSysRedirector::DoRedirect( aFilename );
487 #endif
488 SetLastError( ERROR_SUCCESS ); // ggf. durch Redirector geaendert!
491 #ifdef DBG_UTIL
492 String aTraceStr( "SvFileStream::Open(): " );
493 aTraceStr += aFilename;
494 DBG_TRACE( aTraceStr );
495 #endif
498 DWORD nOpenAction;
499 DWORD nShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
500 DWORD nAccessMode = 0L;
501 UINT nOldErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX );
503 if( nMode & STREAM_SHARE_DENYREAD)
504 nShareMode &= ~FILE_SHARE_READ;
506 if( nMode & STREAM_SHARE_DENYWRITE)
507 nShareMode &= ~FILE_SHARE_WRITE;
509 if( nMode & STREAM_SHARE_DENYALL)
510 nShareMode = 0;
512 if( (nMode & STREAM_READ) )
513 nAccessMode |= GENERIC_READ;
514 if( (nMode & STREAM_WRITE) )
515 nAccessMode |= GENERIC_WRITE;
517 if( nAccessMode == GENERIC_READ ) // ReadOnly ?
518 nMode |= STREAM_NOCREATE; // wenn ja, nicht erzeugen
520 // Zuordnung siehe obige Wahrheitstafel
521 if( !(nMode & STREAM_NOCREATE) )
523 if( nMode & STREAM_TRUNC )
524 nOpenAction = CREATE_ALWAYS;
525 else
526 nOpenAction = OPEN_ALWAYS;
528 else
530 if( nMode & STREAM_TRUNC )
531 nOpenAction = TRUNCATE_EXISTING;
532 else
533 nOpenAction = OPEN_EXISTING;
536 pInstanceData->hFile = CreateFile(
537 aFileNameA.GetBuffer(),
538 nAccessMode,
539 nShareMode,
540 (LPSECURITY_ATTRIBUTES)NULL,
541 nOpenAction,
542 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
543 (HANDLE) NULL
546 if( pInstanceData->hFile!=INVALID_HANDLE_VALUE && (
547 // Hat Create Always eine existierende Datei ueberschrieben ?
548 GetLastError() == ERROR_ALREADY_EXISTS ||
549 // Hat Open Always eine neue Datei angelegt ?
550 GetLastError() == ERROR_FILE_NOT_FOUND ))
552 // wenn ja, dann alles OK
553 if( nOpenAction == OPEN_ALWAYS || nOpenAction == CREATE_ALWAYS )
554 SetLastError( ERROR_SUCCESS );
557 // Bei Fehler pruefen, ob wir lesen duerfen
558 if( (pInstanceData->hFile==INVALID_HANDLE_VALUE) &&
559 (nAccessMode & GENERIC_WRITE))
561 ULONG nErr = ::GetSvError( GetLastError() );
562 if(nErr==SVSTREAM_ACCESS_DENIED || nErr==SVSTREAM_SHARING_VIOLATION)
564 nMode &= (~STREAM_WRITE);
565 nAccessMode = GENERIC_READ;
566 // OV, 28.1.97: Win32 setzt die Datei auf 0-Laenge, wenn
567 // die Openaction CREATE_ALWAYS ist!!!!
568 nOpenAction = OPEN_EXISTING;
569 SetLastError( ERROR_SUCCESS );
570 pInstanceData->hFile = CreateFile(
571 aFileNameA.GetBuffer(),
572 GENERIC_READ,
573 nShareMode,
574 (LPSECURITY_ATTRIBUTES)NULL,
575 nOpenAction,
576 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
577 (HANDLE) NULL
579 if( GetLastError() == ERROR_ALREADY_EXISTS )
580 SetLastError( ERROR_SUCCESS );
584 if( GetLastError() != ERROR_SUCCESS )
586 bIsOpen = FALSE;
587 SetError(::GetSvError( GetLastError() ) );
589 else
591 bIsOpen = TRUE;
592 // pInstanceData->bIsEof = FALSE;
593 if( nAccessMode & GENERIC_WRITE )
594 bIsWritable = TRUE;
596 SetErrorMode( nOldErrorMode );
599 /*************************************************************************
601 |* SvFileStream::ReOpen()
603 |* Beschreibung STREAM.SDW
604 |* Ersterstellung OV 15.06.94
605 |* Letzte Aenderung OV 15.06.94
607 *************************************************************************/
609 void SvFileStream::ReOpen()
611 if( !bIsOpen && aFilename.Len() )
612 Open( aFilename, eStreamMode );
615 /*************************************************************************
617 |* SvFileStream::Close()
619 |* Beschreibung STREAM.SDW
620 |* Ersterstellung OV 15.06.94
621 |* Letzte Aenderung TPF 15.07.98
623 *************************************************************************/
625 void SvFileStream::Close()
627 if( IsOpen() )
629 if( nLockCounter )
631 nLockCounter = 1;
632 UnlockFile();
634 Flush();
635 CloseHandle( pInstanceData->hFile );
637 bIsOpen = FALSE;
638 nLockCounter= 0;
639 bIsWritable = FALSE;
640 SvStream::ClearBuffer();
641 SvStream::ClearError();
644 /*************************************************************************
646 |* SvFileStream::ResetError()
648 |* Beschreibung STREAM.SDW; Setzt Filepointer auf Dateianfang
649 |* Ersterstellung OV 15.06.94
650 |* Letzte Aenderung OV 15.06.94
652 *************************************************************************/
654 void SvFileStream::ResetError()
656 SvStream::ClearError();
659 /*************************************************************************
661 |* SvFileStream::SetSize()
663 |* Beschreibung STREAM.SDW
664 |* Ersterstellung OV 19.10.95
665 |* Letzte Aenderung TPF 15.07.98
667 *************************************************************************/
669 void SvFileStream::SetSize( ULONG nSize )
672 if( IsOpen() )
674 int bError = FALSE;
675 HANDLE hFile = pInstanceData->hFile;
676 ULONG nOld = SetFilePointer( hFile, 0L, NULL, FILE_CURRENT );
677 if( nOld != 0xffffffff )
679 if( SetFilePointer(hFile,nSize,NULL,FILE_BEGIN ) != 0xffffffff)
681 bool bSucc = SetEndOfFile( hFile );
682 if( !bSucc )
683 bError = TRUE;
685 if( SetFilePointer( hFile,nOld,NULL,FILE_BEGIN ) == 0xffffffff)
686 bError = TRUE;
688 if( bError )
689 SetError(::GetSvError( GetLastError() ) );