1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: strmwnt.cxx,v $
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
40 #include <tools/svwin.h>
42 #include <tools/debug.hxx>
43 #include <tools/fsys.hxx>
44 #include <tools/stream.hxx>
47 #include <osl/file.hxx>
50 // -----------------------------------------------------------------------
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
},
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
115 if( errArr
[i
].wnt
== nWntError
)
117 nRetVal
= errArr
[i
].sv
;
121 } while( errArr
[i
].wnt
!= (DWORD
)0xFFFFFFFF );
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
)
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()
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()
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
)
233 bool bResult
= ReadFile(pInstanceData
->hFile
,(LPVOID
)pData
,nSize
,&nCount
,NULL
);
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
)
258 if(!WriteFile(pInstanceData
->hFile
,(LPVOID
)pData
,nSize
,&nCount
,NULL
))
259 SetError(::GetSvError( GetLastError() ) );
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
)
279 if( nPos
!= STREAM_SEEK_TO_END
)
280 // 64-Bit files werden nicht unterstuetzt
281 nNewPos
=SetFilePointer(pInstanceData
->hFile
,nPos
,NULL
,FILE_BEGIN
);
283 nNewPos
=SetFilePointer(pInstanceData
->hFile
,0L,NULL
,FILE_END
);
285 if( nNewPos
== 0xFFFFFFFF )
287 SetError(::GetSvError( GetLastError() ) );
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()
313 nPos = SetFilePointer(pInstanceData->hFile,0L,NULL,FILE_CURRENT);
314 if( nPos = 0xFFFFFFFF )
316 SetError( ::GetSvError( GetLastError() ) );
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()
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;
358 bRetVal
= ::LockFile(pInstanceData
->hFile
,nByteOffset
,0L,nBytes
,0L );
360 SetError(::GetSvError(GetLastError()));
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;
380 bRetVal
= ::UnlockFile(pInstanceData
->hFile
,nByteOffset
,0L,nBytes
,0L );
382 SetError(::GetSvError(GetLastError()));
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
;
402 if( LockRange( 0L, LONG_MAX
) )
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
) )
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
464 1 1 TRUNCATE_EXISTING
467 void SvFileStream::Open( const String
& rFilename
, StreamMode nMode
)
469 String
aParsedFilename(rFilename
);
471 SetLastError( ERROR_SUCCESS
);
473 SvStream::ClearBuffer();
476 eStreamMode
&= ~STREAM_TRUNC
; // beim ReOpen nicht cutten
478 // !!! NoOp: Ansonsten ToAbs() verwendern
479 // !!! DirEntry aDirEntry( rFilename );
480 // !!! aFilename = aDirEntry.GetFull();
481 aFilename
= aParsedFilename
;
483 ByteString
aFileNameA( aFilename
, gsl_getSystemTextEncoding());
485 ByteString
aFileNameA( aFilename
, osl_getThreadTextEncoding());
486 FSysRedirector::DoRedirect( aFilename
);
488 SetLastError( ERROR_SUCCESS
); // ggf. durch Redirector geaendert!
492 String aTraceStr( "SvFileStream::Open(): " );
493 aTraceStr += aFilename;
494 DBG_TRACE( aTraceStr );
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
)
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
;
526 nOpenAction
= OPEN_ALWAYS
;
530 if( nMode
& STREAM_TRUNC
)
531 nOpenAction
= TRUNCATE_EXISTING
;
533 nOpenAction
= OPEN_EXISTING
;
536 pInstanceData
->hFile
= CreateFile(
537 aFileNameA
.GetBuffer(),
540 (LPSECURITY_ATTRIBUTES
)NULL
,
542 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_RANDOM_ACCESS
,
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(),
574 (LPSECURITY_ATTRIBUTES
)NULL
,
576 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_RANDOM_ACCESS
,
579 if( GetLastError() == ERROR_ALREADY_EXISTS
)
580 SetLastError( ERROR_SUCCESS
);
584 if( GetLastError() != ERROR_SUCCESS
)
587 SetError(::GetSvError( GetLastError() ) );
592 // pInstanceData->bIsEof = FALSE;
593 if( nAccessMode
& GENERIC_WRITE
)
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()
635 CloseHandle( pInstanceData
->hFile
);
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
)
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
);
685 if( SetFilePointer( hFile
,nOld
,NULL
,FILE_BEGIN
) == 0xffffffff)
689 SetError(::GetSvError( GetLastError() ) );