fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / tools / source / stream / strmwnt.cxx
blob13d1ea118782ef4ac9693c70fb7f5d302573db2a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 // TODO: StreamMode <-> AllocateMemory
22 #include <string.h>
23 #include <limits.h>
25 #ifdef WNT
26 #include <windows.h>
27 #endif
29 #include <tools/stream.hxx>
31 // class FileBase
32 #include <osl/file.hxx>
33 using namespace osl;
35 class StreamData
37 public:
38 HANDLE hFile;
40 StreamData()
42 hFile = 0;
46 static sal_uIntPtr GetSvError( DWORD nWntError )
48 static struct { DWORD wnt; sal_uIntPtr sv; } errArr[] =
50 { ERROR_SUCCESS, SVSTREAM_OK },
51 { ERROR_ACCESS_DENIED, SVSTREAM_ACCESS_DENIED },
52 { ERROR_ACCOUNT_DISABLED, SVSTREAM_ACCESS_DENIED },
53 { ERROR_ACCOUNT_EXPIRED, SVSTREAM_ACCESS_DENIED },
54 { ERROR_ACCOUNT_RESTRICTION, SVSTREAM_ACCESS_DENIED },
55 { ERROR_ATOMIC_LOCKS_NOT_SUPPORTED, SVSTREAM_INVALID_PARAMETER },
56 { ERROR_BAD_PATHNAME, SVSTREAM_PATH_NOT_FOUND },
57 // Filename too long
58 { ERROR_BUFFER_OVERFLOW, SVSTREAM_INVALID_PARAMETER },
59 { ERROR_DIRECTORY, SVSTREAM_INVALID_PARAMETER },
60 { ERROR_DRIVE_LOCKED, SVSTREAM_LOCKING_VIOLATION },
61 { ERROR_FILE_NOT_FOUND, SVSTREAM_FILE_NOT_FOUND },
62 { ERROR_FILENAME_EXCED_RANGE, SVSTREAM_INVALID_PARAMETER },
63 { ERROR_INVALID_ACCESS, SVSTREAM_INVALID_ACCESS },
64 { ERROR_INVALID_DRIVE, SVSTREAM_PATH_NOT_FOUND },
65 { ERROR_INVALID_HANDLE, SVSTREAM_INVALID_HANDLE },
66 { ERROR_INVALID_NAME, SVSTREAM_PATH_NOT_FOUND },
67 { ERROR_INVALID_PARAMETER, SVSTREAM_INVALID_PARAMETER },
68 { ERROR_IS_SUBST_PATH, SVSTREAM_INVALID_PARAMETER },
69 { ERROR_IS_SUBST_TARGET, SVSTREAM_INVALID_PARAMETER },
70 { ERROR_LOCK_FAILED, SVSTREAM_LOCKING_VIOLATION },
71 { ERROR_LOCK_VIOLATION, SVSTREAM_LOCKING_VIOLATION },
72 { ERROR_NEGATIVE_SEEK, SVSTREAM_SEEK_ERROR },
73 { ERROR_PATH_NOT_FOUND, SVSTREAM_PATH_NOT_FOUND },
74 { ERROR_READ_FAULT, SVSTREAM_READ_ERROR },
75 { ERROR_SEEK, SVSTREAM_SEEK_ERROR },
76 { ERROR_SEEK_ON_DEVICE, SVSTREAM_SEEK_ERROR },
77 { ERROR_SHARING_BUFFER_EXCEEDED,SVSTREAM_SHARE_BUFF_EXCEEDED },
78 { ERROR_SHARING_PAUSED, SVSTREAM_SHARING_VIOLATION },
79 { ERROR_SHARING_VIOLATION, SVSTREAM_SHARING_VIOLATION },
80 { ERROR_TOO_MANY_OPEN_FILES, SVSTREAM_TOO_MANY_OPEN_FILES },
81 { ERROR_WRITE_FAULT, SVSTREAM_WRITE_ERROR },
82 { ERROR_WRITE_PROTECT, SVSTREAM_ACCESS_DENIED },
83 { ERROR_DISK_FULL, SVSTREAM_DISK_FULL },
85 { (DWORD)0xFFFFFFFF, SVSTREAM_GENERALERROR }
88 sal_uIntPtr nRetVal = SVSTREAM_GENERALERROR; // default error
89 int i=0;
92 if( errArr[i].wnt == nWntError )
94 nRetVal = errArr[i].sv;
95 break;
97 i++;
98 } while( errArr[i].wnt != (DWORD)0xFFFFFFFF );
99 return nRetVal;
102 SvFileStream::SvFileStream( const String& rFileName, StreamMode nMode )
104 bIsOpen = sal_False;
105 nLockCounter = 0;
106 bIsWritable = sal_False;
107 pInstanceData = new StreamData;
109 SetBufferSize( 8192 );
110 // convert URL to SystemPath, if necessary
111 OUString aFileName, aNormPath;
113 if ( FileBase::getSystemPathFromFileURL( rFileName, aFileName ) != FileBase::E_None )
114 aFileName = rFileName;
115 Open( aFileName, nMode );
118 SvFileStream::SvFileStream()
120 bIsOpen = sal_False;
121 nLockCounter = 0;
122 bIsWritable = sal_False;
123 pInstanceData = new StreamData;
125 SetBufferSize( 8192 );
128 SvFileStream::~SvFileStream()
130 Close();
131 if (pInstanceData)
132 delete pInstanceData;
135 sal_uInt16 SvFileStream::IsA() const
137 return ID_FILESTREAM;
140 /// Does not check for EOF, makes isEof callable
141 sal_uIntPtr SvFileStream::GetData( void* pData, sal_uIntPtr nSize )
143 DWORD nCount = 0;
144 if( IsOpen() )
146 bool bResult = ReadFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL);
147 if( !bResult )
149 sal_uIntPtr nTestError = GetLastError();
150 SetError(::GetSvError( nTestError ) );
153 return (DWORD)nCount;
156 sal_uIntPtr SvFileStream::PutData( const void* pData, sal_uIntPtr nSize )
158 DWORD nCount = 0;
159 if( IsOpen() )
161 if(!WriteFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL))
162 SetError(::GetSvError( GetLastError() ) );
164 return nCount;
167 sal_uIntPtr SvFileStream::SeekPos( sal_uIntPtr nPos )
169 DWORD nNewPos = 0;
170 if( IsOpen() )
172 if( nPos != STREAM_SEEK_TO_END )
173 // 64-Bit files are not supported
174 nNewPos=SetFilePointer(pInstanceData->hFile,nPos,NULL,FILE_BEGIN);
175 else
176 nNewPos=SetFilePointer(pInstanceData->hFile,0L,NULL,FILE_END);
178 if( nNewPos == 0xFFFFFFFF )
180 SetError(::GetSvError( GetLastError() ) );
181 nNewPos = 0L;
184 else
185 SetError( SVSTREAM_GENERALERROR );
186 return (sal_uIntPtr)nNewPos;
189 void SvFileStream::FlushData()
191 if( IsOpen() )
193 if( !FlushFileBuffers(pInstanceData->hFile) )
194 SetError(::GetSvError(GetLastError()));
198 sal_Bool SvFileStream::LockRange( sal_uIntPtr nByteOffset, sal_uIntPtr nBytes )
200 bool bRetVal = false;
201 if( IsOpen() )
203 bRetVal = ::LockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L );
204 if( !bRetVal )
205 SetError(::GetSvError(GetLastError()));
207 return bRetVal;
210 sal_Bool SvFileStream::UnlockRange( sal_uIntPtr nByteOffset, sal_uIntPtr nBytes )
212 bool bRetVal = false;
213 if( IsOpen() )
215 bRetVal = ::UnlockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L );
216 if( !bRetVal )
217 SetError(::GetSvError(GetLastError()));
219 return bRetVal;
222 sal_Bool SvFileStream::LockFile()
224 sal_Bool bRetVal = sal_False;
225 if( !nLockCounter )
227 if( LockRange( 0L, LONG_MAX ) )
229 nLockCounter = 1;
230 bRetVal = sal_True;
233 else
235 nLockCounter++;
236 bRetVal = sal_True;
238 return bRetVal;
241 sal_Bool SvFileStream::UnlockFile()
243 sal_Bool bRetVal = sal_False;
244 if( nLockCounter > 0)
246 if( nLockCounter == 1)
248 if( UnlockRange( 0L, LONG_MAX ) )
250 nLockCounter = 0;
251 bRetVal = sal_True;
254 else
256 nLockCounter--;
257 bRetVal = sal_True;
260 return bRetVal;
264 NOCREATE TRUNC NT-Action
265 ----------------------------------------------
266 0 (Create) 0 OPEN_ALWAYS
267 0 (Create) 1 CREATE_ALWAYS
268 1 0 OPEN_EXISTING
269 1 1 TRUNCATE_EXISTING
271 void SvFileStream::Open( const String& rFilename, StreamMode nMode )
273 String aParsedFilename(rFilename);
275 SetLastError( ERROR_SUCCESS );
276 Close();
277 SvStream::ClearBuffer();
279 eStreamMode = nMode;
280 eStreamMode &= ~STREAM_TRUNC; // don't truncate on reopen
282 aFilename = aParsedFilename;
283 OString aFileNameA(OUStringToOString(aFilename, osl_getThreadTextEncoding()));
284 SetLastError( ERROR_SUCCESS ); // might be changed by Redirector
286 DWORD nOpenAction;
287 DWORD nShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
288 DWORD nAccessMode = 0L;
289 UINT nOldErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX );
291 if( nMode & STREAM_SHARE_DENYREAD)
292 nShareMode &= ~FILE_SHARE_READ;
294 if( nMode & STREAM_SHARE_DENYWRITE)
295 nShareMode &= ~FILE_SHARE_WRITE;
297 if( nMode & STREAM_SHARE_DENYALL)
298 nShareMode = 0;
300 if( (nMode & STREAM_READ) )
301 nAccessMode |= GENERIC_READ;
302 if( (nMode & STREAM_WRITE) )
303 nAccessMode |= GENERIC_WRITE;
305 if( nAccessMode == GENERIC_READ ) // ReadOnly ?
306 nMode |= STREAM_NOCREATE; // Don't create if readonly
308 // Assignment based on true/false table above
309 if( !(nMode & STREAM_NOCREATE) )
311 if( nMode & STREAM_TRUNC )
312 nOpenAction = CREATE_ALWAYS;
313 else
314 nOpenAction = OPEN_ALWAYS;
316 else
318 if( nMode & STREAM_TRUNC )
319 nOpenAction = TRUNCATE_EXISTING;
320 else
321 nOpenAction = OPEN_EXISTING;
324 pInstanceData->hFile = CreateFile(
325 aFileNameA.getStr(),
326 nAccessMode,
327 nShareMode,
328 (LPSECURITY_ATTRIBUTES)NULL,
329 nOpenAction,
330 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
331 (HANDLE) NULL
334 if( pInstanceData->hFile!=INVALID_HANDLE_VALUE && (
335 // Did Create Always overwrite a file?
336 GetLastError() == ERROR_ALREADY_EXISTS ||
337 // Did Create Always open a new file?
338 GetLastError() == ERROR_FILE_NOT_FOUND ))
340 // If so, no error
341 if( nOpenAction == OPEN_ALWAYS || nOpenAction == CREATE_ALWAYS )
342 SetLastError( ERROR_SUCCESS );
345 // Otherwise, determine if we're allowed to read
346 if( (pInstanceData->hFile==INVALID_HANDLE_VALUE) &&
347 (nAccessMode & GENERIC_WRITE))
349 sal_uIntPtr nErr = ::GetSvError( GetLastError() );
350 if(nErr==SVSTREAM_ACCESS_DENIED || nErr==SVSTREAM_SHARING_VIOLATION)
352 nMode &= (~STREAM_WRITE);
353 nAccessMode = GENERIC_READ;
354 // OV, 28.1.97: Win32 sets file to length 0
355 // if Openaction is CREATE_ALWAYS
356 nOpenAction = OPEN_EXISTING;
357 SetLastError( ERROR_SUCCESS );
358 pInstanceData->hFile = CreateFile(
359 aFileNameA.getStr(),
360 GENERIC_READ,
361 nShareMode,
362 (LPSECURITY_ATTRIBUTES)NULL,
363 nOpenAction,
364 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
365 (HANDLE) NULL
367 if( GetLastError() == ERROR_ALREADY_EXISTS )
368 SetLastError( ERROR_SUCCESS );
372 if( GetLastError() != ERROR_SUCCESS )
374 bIsOpen = sal_False;
375 SetError(::GetSvError( GetLastError() ) );
377 else
379 bIsOpen = sal_True;
380 // pInstanceData->bIsEof = sal_False;
381 if( nAccessMode & GENERIC_WRITE )
382 bIsWritable = sal_True;
384 SetErrorMode( nOldErrorMode );
387 void SvFileStream::Close()
389 if( IsOpen() )
391 if( nLockCounter )
393 nLockCounter = 1;
394 UnlockFile();
396 Flush();
397 CloseHandle( pInstanceData->hFile );
399 bIsOpen = sal_False;
400 nLockCounter= 0;
401 bIsWritable = sal_False;
402 SvStream::ClearBuffer();
403 SvStream::ClearError();
406 /// Reset filepointer to beginning of file
407 void SvFileStream::ResetError()
409 SvStream::ClearError();
412 void SvFileStream::SetSize( sal_uIntPtr nSize )
415 if( IsOpen() )
417 int bError = sal_False;
418 HANDLE hFile = pInstanceData->hFile;
419 sal_uIntPtr nOld = SetFilePointer( hFile, 0L, NULL, FILE_CURRENT );
420 if( nOld != 0xffffffff )
422 if( SetFilePointer(hFile,nSize,NULL,FILE_BEGIN ) != 0xffffffff)
424 bool bSucc = SetEndOfFile( hFile );
425 if( !bSucc )
426 bError = sal_True;
428 if( SetFilePointer( hFile,nOld,NULL,FILE_BEGIN ) == 0xffffffff)
429 bError = sal_True;
431 if( bError )
432 SetError(::GetSvError( GetLastError() ) );
436 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */