xref: /AOO41X/main/sal/osl/w32/file.cxx (revision 87d2adbc9cadf14644c3679b041b9226f7630199)
1*87d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*87d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*87d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*87d2adbcSAndrew Rist  * distributed with this work for additional information
6*87d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*87d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*87d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
9*87d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*87d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*87d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*87d2adbcSAndrew Rist  * software distributed under the License is distributed on an
15*87d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*87d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*87d2adbcSAndrew Rist  * specific language governing permissions and limitations
18*87d2adbcSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*87d2adbcSAndrew Rist  *************************************************************/
21*87d2adbcSAndrew Rist 
22*87d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sal.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #define UNICODE
28cdf0e10cSrcweir #define _UNICODE
29cdf0e10cSrcweir #define _WIN32_WINNT 0x0500
30cdf0e10cSrcweir #include "systools/win32/uwinapi.h"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "osl/file.hxx"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include "file_url.h"
35cdf0e10cSrcweir #include "file_error.h"
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include "osl/diagnose.h"
38cdf0e10cSrcweir #include "rtl/alloc.h"
39cdf0e10cSrcweir #include "rtl/byteseq.h"
40cdf0e10cSrcweir #include "rtl/ustring.hxx"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <stdio.h>
43cdf0e10cSrcweir #include <tchar.h>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #ifdef __MINGW32__
46cdf0e10cSrcweir #include <wchar.h>
47cdf0e10cSrcweir #include <ctype.h>
48cdf0e10cSrcweir #endif
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #include <algorithm>
51cdf0e10cSrcweir #include <limits>
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #ifdef max /* conflict w/ std::numeric_limits<T>::max() */
54cdf0e10cSrcweir #undef max
55cdf0e10cSrcweir #endif
56cdf0e10cSrcweir #ifdef min
57cdf0e10cSrcweir #undef min
58cdf0e10cSrcweir #endif
59cdf0e10cSrcweir 
60cdf0e10cSrcweir //##################################################################
61cdf0e10cSrcweir // File handle implementation
62cdf0e10cSrcweir //##################################################################
63cdf0e10cSrcweir struct FileHandle_Impl
64cdf0e10cSrcweir {
65cdf0e10cSrcweir     CRITICAL_SECTION m_mutex;
66cdf0e10cSrcweir     HANDLE           m_hFile;
67cdf0e10cSrcweir 
68cdf0e10cSrcweir 	/** State
69cdf0e10cSrcweir 	 */
70cdf0e10cSrcweir 	enum StateBits
71cdf0e10cSrcweir 	{
72cdf0e10cSrcweir 		STATE_SEEKABLE  = 1, /* open() sets, iff regular file */
73cdf0e10cSrcweir 		STATE_READABLE  = 2, /* open() sets, read() requires */
74cdf0e10cSrcweir 		STATE_WRITEABLE = 4, /* open() sets, write() requires */
75cdf0e10cSrcweir 		STATE_MODIFIED  = 8  /* write() sets, flush() resets */
76cdf0e10cSrcweir 	};
77cdf0e10cSrcweir 	int          m_state;
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 	sal_uInt64   m_size;    /* file size */
80cdf0e10cSrcweir 	LONGLONG     m_offset;  /* physical offset from begin of file */
81cdf0e10cSrcweir 	LONGLONG     m_filepos; /* logical offset from begin of file */
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 	LONGLONG     m_bufptr;  /* buffer offset from begin of file */
84cdf0e10cSrcweir 	SIZE_T       m_buflen;  /* buffer filled [0, m_bufsiz - 1] */
85cdf0e10cSrcweir 
86cdf0e10cSrcweir 	SIZE_T       m_bufsiz;
87cdf0e10cSrcweir 	sal_uInt8 *  m_buffer;
88cdf0e10cSrcweir 
89cdf0e10cSrcweir 	explicit FileHandle_Impl (HANDLE hFile);
90cdf0e10cSrcweir 	~FileHandle_Impl();
91cdf0e10cSrcweir 
92cdf0e10cSrcweir 	static void*  operator new(size_t n);
93cdf0e10cSrcweir 	static void   operator delete(void * p, size_t);
94cdf0e10cSrcweir 	static SIZE_T getpagesize();
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 	sal_uInt64    getPos() const;
97cdf0e10cSrcweir 	oslFileError  setPos (sal_uInt64 uPos);
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 	sal_uInt64    getSize() const;
100cdf0e10cSrcweir 	oslFileError  setSize (sal_uInt64 uPos);
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	oslFileError readAt (
103cdf0e10cSrcweir 		LONGLONG     nOffset,
104cdf0e10cSrcweir 		void *       pBuffer,
105cdf0e10cSrcweir 		DWORD        nBytesRequested,
106cdf0e10cSrcweir 		sal_uInt64 * pBytesRead);
107cdf0e10cSrcweir 
108cdf0e10cSrcweir 	oslFileError writeAt (
109cdf0e10cSrcweir 		LONGLONG     nOffset,
110cdf0e10cSrcweir 		void const * pBuffer,
111cdf0e10cSrcweir 		DWORD        nBytesToWrite,
112cdf0e10cSrcweir 		sal_uInt64 * pBytesWritten);
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 	oslFileError readFileAt (
115cdf0e10cSrcweir 		LONGLONG     nOffset,
116cdf0e10cSrcweir 		void *       pBuffer,
117cdf0e10cSrcweir 		sal_uInt64   uBytesRequested,
118cdf0e10cSrcweir 		sal_uInt64 * pBytesRead);
119cdf0e10cSrcweir 
120cdf0e10cSrcweir 	oslFileError writeFileAt (
121cdf0e10cSrcweir 		LONGLONG     nOffset,
122cdf0e10cSrcweir 		void const * pBuffer,
123cdf0e10cSrcweir 		sal_uInt64   uBytesToWrite,
124cdf0e10cSrcweir 		sal_uInt64 * pBytesWritten);
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 	oslFileError readLineAt (
127cdf0e10cSrcweir 		LONGLONG        nOffset,
128cdf0e10cSrcweir 		sal_Sequence ** ppSequence,
129cdf0e10cSrcweir 		sal_uInt64 *    pBytesRead);
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 	oslFileError writeSequence_Impl (
132cdf0e10cSrcweir 		sal_Sequence ** ppSequence,
133cdf0e10cSrcweir 		SIZE_T *        pnOffset,
134cdf0e10cSrcweir 		const void *    pBuffer,
135cdf0e10cSrcweir 		SIZE_T          nBytes);
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 	oslFileError syncFile();
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 	/** Buffer cache / allocator.
140cdf0e10cSrcweir 	 */
141cdf0e10cSrcweir 	class Allocator
142cdf0e10cSrcweir 	{
143cdf0e10cSrcweir 		rtl_cache_type * m_cache;
144cdf0e10cSrcweir 		SIZE_T           m_bufsiz;
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 		Allocator (Allocator const &);
147cdf0e10cSrcweir 		Allocator & operator= (Allocator const &);
148cdf0e10cSrcweir 
149cdf0e10cSrcweir 	public:
150cdf0e10cSrcweir 		static Allocator & get();
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 		void allocate (sal_uInt8 ** ppBuffer, SIZE_T * pnSize);
153cdf0e10cSrcweir 		void deallocate (sal_uInt8 * pBuffer);
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 	protected:
156cdf0e10cSrcweir 		Allocator();
157cdf0e10cSrcweir 		~Allocator();
158cdf0e10cSrcweir 	};
159cdf0e10cSrcweir 
160cdf0e10cSrcweir     /** Guard.
161cdf0e10cSrcweir      */
162cdf0e10cSrcweir     class Guard
163cdf0e10cSrcweir     {
164cdf0e10cSrcweir         LPCRITICAL_SECTION m_mutex;
165cdf0e10cSrcweir 
166cdf0e10cSrcweir     public:
167cdf0e10cSrcweir         explicit Guard(LPCRITICAL_SECTION pMutex);
168cdf0e10cSrcweir         ~Guard();
169cdf0e10cSrcweir     };
170cdf0e10cSrcweir };
171cdf0e10cSrcweir 
172cdf0e10cSrcweir FileHandle_Impl::Allocator &
get()173cdf0e10cSrcweir FileHandle_Impl::Allocator::get()
174cdf0e10cSrcweir {
175cdf0e10cSrcweir 	static Allocator g_aBufferAllocator;
176cdf0e10cSrcweir 	return g_aBufferAllocator;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir 
Allocator()179cdf0e10cSrcweir FileHandle_Impl::Allocator::Allocator()
180cdf0e10cSrcweir 	: m_cache  (0),
181cdf0e10cSrcweir 	  m_bufsiz (0)
182cdf0e10cSrcweir {
183cdf0e10cSrcweir 	SIZE_T const pagesize = FileHandle_Impl::getpagesize();
184cdf0e10cSrcweir 	m_cache = rtl_cache_create (
185cdf0e10cSrcweir 		"osl_file_buffer_cache", pagesize, 0, 0, 0, 0, 0, 0, 0);
186cdf0e10cSrcweir 	if (0 != m_cache)
187cdf0e10cSrcweir 		m_bufsiz = pagesize;
188cdf0e10cSrcweir }
189cdf0e10cSrcweir 
~Allocator()190cdf0e10cSrcweir FileHandle_Impl::Allocator::~Allocator()
191cdf0e10cSrcweir {
192cdf0e10cSrcweir 	rtl_cache_destroy(m_cache), m_cache = 0;
193cdf0e10cSrcweir }
194cdf0e10cSrcweir 
allocate(sal_uInt8 ** ppBuffer,SIZE_T * pnSize)195cdf0e10cSrcweir void FileHandle_Impl::Allocator::allocate (sal_uInt8 ** ppBuffer, SIZE_T * pnSize)
196cdf0e10cSrcweir {
197cdf0e10cSrcweir 	OSL_PRECOND((0 != ppBuffer) && (0 != pnSize), "FileHandle_Impl::Allocator::allocate(): contract violation");
198cdf0e10cSrcweir 	*ppBuffer = static_cast< sal_uInt8* >(rtl_cache_alloc(m_cache)), *pnSize = m_bufsiz;
199cdf0e10cSrcweir }
200cdf0e10cSrcweir 
deallocate(sal_uInt8 * pBuffer)201cdf0e10cSrcweir void FileHandle_Impl::Allocator::deallocate (sal_uInt8 * pBuffer)
202cdf0e10cSrcweir {
203cdf0e10cSrcweir 	if (0 != pBuffer)
204cdf0e10cSrcweir 		rtl_cache_free (m_cache, pBuffer);
205cdf0e10cSrcweir }
206cdf0e10cSrcweir 
Guard(LPCRITICAL_SECTION pMutex)207cdf0e10cSrcweir FileHandle_Impl::Guard::Guard(LPCRITICAL_SECTION pMutex)
208cdf0e10cSrcweir     : m_mutex (pMutex)
209cdf0e10cSrcweir {
210cdf0e10cSrcweir     OSL_PRECOND (m_mutex != 0, "FileHandle_Impl::Guard::Guard(): null pointer.");
211cdf0e10cSrcweir     ::EnterCriticalSection (m_mutex);
212cdf0e10cSrcweir }
~Guard()213cdf0e10cSrcweir FileHandle_Impl::Guard::~Guard()
214cdf0e10cSrcweir {
215cdf0e10cSrcweir     OSL_PRECOND (m_mutex != 0, "FileHandle_Impl::Guard::~Guard(): null pointer.");
216cdf0e10cSrcweir     ::LeaveCriticalSection (m_mutex);
217cdf0e10cSrcweir }
218cdf0e10cSrcweir 
FileHandle_Impl(HANDLE hFile)219cdf0e10cSrcweir FileHandle_Impl::FileHandle_Impl(HANDLE hFile)
220cdf0e10cSrcweir 	: m_hFile   (hFile),
221cdf0e10cSrcweir 	  m_state   (STATE_READABLE | STATE_WRITEABLE),
222cdf0e10cSrcweir 	  m_size    (0),
223cdf0e10cSrcweir 	  m_offset  (0),
224cdf0e10cSrcweir 	  m_filepos (0),
225cdf0e10cSrcweir 	  m_bufptr  (-1),
226cdf0e10cSrcweir 	  m_buflen  (0),
227cdf0e10cSrcweir 	  m_bufsiz  (0),
228cdf0e10cSrcweir 	  m_buffer  (0)
229cdf0e10cSrcweir {
230cdf0e10cSrcweir     ::InitializeCriticalSection (&m_mutex);
231cdf0e10cSrcweir 	Allocator::get().allocate (&m_buffer, &m_bufsiz);
232cdf0e10cSrcweir 	if (m_buffer != 0)
233cdf0e10cSrcweir 		memset (m_buffer, 0, m_bufsiz);
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
~FileHandle_Impl()236cdf0e10cSrcweir FileHandle_Impl::~FileHandle_Impl()
237cdf0e10cSrcweir {
238cdf0e10cSrcweir 	Allocator::get().deallocate (m_buffer), m_buffer = 0;
239cdf0e10cSrcweir     ::DeleteCriticalSection (&m_mutex);
240cdf0e10cSrcweir }
241cdf0e10cSrcweir 
operator new(size_t n)242cdf0e10cSrcweir void * FileHandle_Impl::operator new(size_t n)
243cdf0e10cSrcweir {
244cdf0e10cSrcweir 	return rtl_allocateMemory(n);
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
operator delete(void * p,size_t)247cdf0e10cSrcweir void FileHandle_Impl::operator delete(void * p, size_t)
248cdf0e10cSrcweir {
249cdf0e10cSrcweir 	rtl_freeMemory(p);
250cdf0e10cSrcweir }
251cdf0e10cSrcweir 
getpagesize()252cdf0e10cSrcweir SIZE_T FileHandle_Impl::getpagesize()
253cdf0e10cSrcweir {
254cdf0e10cSrcweir 	SYSTEM_INFO info;
255cdf0e10cSrcweir 	::GetSystemInfo (&info);
256cdf0e10cSrcweir 	return sal::static_int_cast< SIZE_T >(info.dwPageSize);
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
getPos() const259cdf0e10cSrcweir sal_uInt64 FileHandle_Impl::getPos() const
260cdf0e10cSrcweir {
261cdf0e10cSrcweir 	return sal::static_int_cast< sal_uInt64 >(m_filepos);
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
setPos(sal_uInt64 uPos)264cdf0e10cSrcweir oslFileError FileHandle_Impl::setPos (sal_uInt64 uPos)
265cdf0e10cSrcweir {
266cdf0e10cSrcweir 	m_filepos = sal::static_int_cast< LONGLONG >(uPos);
267cdf0e10cSrcweir 	return osl_File_E_None;
268cdf0e10cSrcweir }
269cdf0e10cSrcweir 
getSize() const270cdf0e10cSrcweir sal_uInt64 FileHandle_Impl::getSize() const
271cdf0e10cSrcweir {
272cdf0e10cSrcweir 	LONGLONG bufend = std::max((LONGLONG)(0), m_bufptr) + m_buflen;
273cdf0e10cSrcweir 	return std::max(m_size, sal::static_int_cast< sal_uInt64 >(bufend));
274cdf0e10cSrcweir }
275cdf0e10cSrcweir 
setSize(sal_uInt64 uSize)276cdf0e10cSrcweir oslFileError FileHandle_Impl::setSize (sal_uInt64 uSize)
277cdf0e10cSrcweir {
278cdf0e10cSrcweir 	LARGE_INTEGER nDstPos; nDstPos.QuadPart = sal::static_int_cast< LONGLONG >(uSize);
279cdf0e10cSrcweir 	if (!::SetFilePointerEx(m_hFile, nDstPos, 0, FILE_BEGIN))
280cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 	if (!::SetEndOfFile(m_hFile))
283cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
284cdf0e10cSrcweir 	m_size = uSize;
285cdf0e10cSrcweir 
286cdf0e10cSrcweir 	nDstPos.QuadPart = m_offset;
287cdf0e10cSrcweir 	if (!::SetFilePointerEx(m_hFile, nDstPos, 0, FILE_BEGIN))
288cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
289cdf0e10cSrcweir 
290cdf0e10cSrcweir 	return osl_File_E_None;
291cdf0e10cSrcweir }
292cdf0e10cSrcweir 
readAt(LONGLONG nOffset,void * pBuffer,DWORD nBytesRequested,sal_uInt64 * pBytesRead)293cdf0e10cSrcweir oslFileError FileHandle_Impl::readAt (
294cdf0e10cSrcweir 	LONGLONG     nOffset,
295cdf0e10cSrcweir 	void *       pBuffer,
296cdf0e10cSrcweir 	DWORD        nBytesRequested,
297cdf0e10cSrcweir 	sal_uInt64 * pBytesRead)
298cdf0e10cSrcweir {
299cdf0e10cSrcweir 	OSL_PRECOND(m_state & STATE_SEEKABLE, "FileHandle_Impl::readAt(): not seekable");
300cdf0e10cSrcweir 	if (!(m_state & STATE_SEEKABLE))
301cdf0e10cSrcweir 		return osl_File_E_SPIPE;
302cdf0e10cSrcweir 
303cdf0e10cSrcweir 	OSL_PRECOND(m_state & STATE_READABLE, "FileHandle_Impl::readAt(): not readable");
304cdf0e10cSrcweir 	if (!(m_state & STATE_READABLE))
305cdf0e10cSrcweir 		return osl_File_E_BADF;
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 	if (nOffset != m_offset)
308cdf0e10cSrcweir 	{
309cdf0e10cSrcweir 		LARGE_INTEGER liOffset; liOffset.QuadPart = nOffset;
310cdf0e10cSrcweir 		if (!::SetFilePointerEx(m_hFile, liOffset, 0, FILE_BEGIN))
311cdf0e10cSrcweir 			return oslTranslateFileError( GetLastError() );
312cdf0e10cSrcweir 		m_offset = nOffset;
313cdf0e10cSrcweir 	}
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 	DWORD dwDone = 0;
316cdf0e10cSrcweir 	if (!::ReadFile(m_hFile, pBuffer, nBytesRequested, &dwDone, 0))
317cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
318cdf0e10cSrcweir 	m_offset += dwDone;
319cdf0e10cSrcweir 
320cdf0e10cSrcweir 	*pBytesRead = dwDone;
321cdf0e10cSrcweir 	return osl_File_E_None;
322cdf0e10cSrcweir }
323cdf0e10cSrcweir 
writeAt(LONGLONG nOffset,void const * pBuffer,DWORD nBytesToWrite,sal_uInt64 * pBytesWritten)324cdf0e10cSrcweir oslFileError FileHandle_Impl::writeAt (
325cdf0e10cSrcweir 	LONGLONG     nOffset,
326cdf0e10cSrcweir 	void const * pBuffer,
327cdf0e10cSrcweir 	DWORD        nBytesToWrite,
328cdf0e10cSrcweir 	sal_uInt64 * pBytesWritten)
329cdf0e10cSrcweir {
330cdf0e10cSrcweir 	OSL_PRECOND(m_state & STATE_SEEKABLE, "FileHandle_Impl::writeAt(): not seekable");
331cdf0e10cSrcweir 	if (!(m_state & STATE_SEEKABLE))
332cdf0e10cSrcweir 		return osl_File_E_SPIPE;
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 	OSL_PRECOND(m_state & STATE_WRITEABLE, "FileHandle_Impl::writeAt(): not writeable");
335cdf0e10cSrcweir 	if (!(m_state & STATE_WRITEABLE))
336cdf0e10cSrcweir 		return osl_File_E_BADF;
337cdf0e10cSrcweir 
338cdf0e10cSrcweir 	if (nOffset != m_offset)
339cdf0e10cSrcweir 	{
340cdf0e10cSrcweir 		LARGE_INTEGER liOffset; liOffset.QuadPart = nOffset;
341cdf0e10cSrcweir 		if (!::SetFilePointerEx (m_hFile, liOffset, 0, FILE_BEGIN))
342cdf0e10cSrcweir 			return oslTranslateFileError( GetLastError() );
343cdf0e10cSrcweir 		m_offset = nOffset;
344cdf0e10cSrcweir 	}
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 	DWORD dwDone = 0;
347cdf0e10cSrcweir 	if (!::WriteFile(m_hFile, pBuffer, nBytesToWrite, &dwDone, 0))
348cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
349cdf0e10cSrcweir 	m_offset += dwDone;
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 	m_size = std::max(m_size, sal::static_int_cast< sal_uInt64 >(m_offset));
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 	*pBytesWritten = dwDone;
354cdf0e10cSrcweir 	return osl_File_E_None;
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
readFileAt(LONGLONG nOffset,void * pBuffer,sal_uInt64 uBytesRequested,sal_uInt64 * pBytesRead)357cdf0e10cSrcweir oslFileError FileHandle_Impl::readFileAt (
358cdf0e10cSrcweir 	LONGLONG     nOffset,
359cdf0e10cSrcweir 	void *       pBuffer,
360cdf0e10cSrcweir 	sal_uInt64   uBytesRequested,
361cdf0e10cSrcweir 	sal_uInt64 * pBytesRead)
362cdf0e10cSrcweir {
363cdf0e10cSrcweir 	static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max();
364cdf0e10cSrcweir 	if (g_limit_dword < uBytesRequested)
365cdf0e10cSrcweir 		return osl_File_E_OVERFLOW;
366cdf0e10cSrcweir 	DWORD nBytesRequested = sal::static_int_cast< DWORD >(uBytesRequested);
367cdf0e10cSrcweir 
368cdf0e10cSrcweir 	if (0 == (m_state & STATE_SEEKABLE))
369cdf0e10cSrcweir 	{
370cdf0e10cSrcweir 		// not seekable (pipe)
371cdf0e10cSrcweir 		DWORD dwDone = 0;
372cdf0e10cSrcweir 		if (!::ReadFile(m_hFile, pBuffer, nBytesRequested, &dwDone, 0))
373cdf0e10cSrcweir 			return oslTranslateFileError( GetLastError() );
374cdf0e10cSrcweir 		*pBytesRead = dwDone;
375cdf0e10cSrcweir 		return osl_File_E_None;
376cdf0e10cSrcweir 	}
377cdf0e10cSrcweir 	else if (0 == m_buffer)
378cdf0e10cSrcweir 	{
379cdf0e10cSrcweir 		// not buffered
380cdf0e10cSrcweir 		return readAt (nOffset, pBuffer, nBytesRequested, pBytesRead);
381cdf0e10cSrcweir 	}
382cdf0e10cSrcweir 	else
383cdf0e10cSrcweir 	{
384cdf0e10cSrcweir 		sal_uInt8 * buffer = static_cast< sal_uInt8* >(pBuffer);
385cdf0e10cSrcweir 		for (*pBytesRead = 0; nBytesRequested > 0; )
386cdf0e10cSrcweir 		{
387cdf0e10cSrcweir 			LONGLONG const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
388cdf0e10cSrcweir 			SIZE_T   const bufpos = (nOffset % m_bufsiz);
389cdf0e10cSrcweir 
390cdf0e10cSrcweir 			if (bufptr != m_bufptr)
391cdf0e10cSrcweir 			{
392cdf0e10cSrcweir 				// flush current buffer
393cdf0e10cSrcweir 				oslFileError result = syncFile();
394cdf0e10cSrcweir 				if (result != osl_File_E_None)
395cdf0e10cSrcweir 					return (result);
396cdf0e10cSrcweir                 m_bufptr = -1, m_buflen = 0;
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 				if (nBytesRequested >= m_bufsiz)
399cdf0e10cSrcweir 				{
400cdf0e10cSrcweir 					// buffer too small, read through from file
401cdf0e10cSrcweir 					sal_uInt64 uDone = 0;
402cdf0e10cSrcweir 					result = readAt (nOffset, &(buffer[*pBytesRead]), nBytesRequested, &uDone);
403cdf0e10cSrcweir 					if (result != osl_File_E_None)
404cdf0e10cSrcweir 						return (result);
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 					nBytesRequested -= sal::static_int_cast< DWORD >(uDone), *pBytesRead += uDone;
407cdf0e10cSrcweir 					return osl_File_E_None;
408cdf0e10cSrcweir 				}
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 				// update buffer (pointer)
411cdf0e10cSrcweir 				sal_uInt64 uDone = 0;
412cdf0e10cSrcweir 				result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
413cdf0e10cSrcweir 				if (result != osl_File_E_None)
414cdf0e10cSrcweir 					return (result);
415cdf0e10cSrcweir 				m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone);
416cdf0e10cSrcweir 			}
417cdf0e10cSrcweir 			if (bufpos >= m_buflen)
418cdf0e10cSrcweir 			{
419cdf0e10cSrcweir 				// end of file
420cdf0e10cSrcweir 				return osl_File_E_None;
421cdf0e10cSrcweir 			}
422cdf0e10cSrcweir 
423cdf0e10cSrcweir 			SIZE_T const bytes = std::min(m_buflen - bufpos, nBytesRequested);
424cdf0e10cSrcweir 			memcpy (&(buffer[*pBytesRead]), &(m_buffer[bufpos]), bytes);
425cdf0e10cSrcweir 			nBytesRequested -= bytes, *pBytesRead += bytes, nOffset += bytes;
426cdf0e10cSrcweir 		}
427cdf0e10cSrcweir 		return osl_File_E_None;
428cdf0e10cSrcweir 	}
429cdf0e10cSrcweir }
430cdf0e10cSrcweir 
writeFileAt(LONGLONG nOffset,void const * pBuffer,sal_uInt64 uBytesToWrite,sal_uInt64 * pBytesWritten)431cdf0e10cSrcweir oslFileError FileHandle_Impl::writeFileAt (
432cdf0e10cSrcweir 	LONGLONG     nOffset,
433cdf0e10cSrcweir 	void const * pBuffer,
434cdf0e10cSrcweir 	sal_uInt64   uBytesToWrite,
435cdf0e10cSrcweir 	sal_uInt64 * pBytesWritten)
436cdf0e10cSrcweir {
437cdf0e10cSrcweir 	static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max();
438cdf0e10cSrcweir 	if (g_limit_dword < uBytesToWrite)
439cdf0e10cSrcweir 		return osl_File_E_OVERFLOW;
440cdf0e10cSrcweir 	DWORD nBytesToWrite = sal::static_int_cast< DWORD >(uBytesToWrite);
441cdf0e10cSrcweir 
442cdf0e10cSrcweir 	if (0 == (m_state & STATE_SEEKABLE))
443cdf0e10cSrcweir 	{
444cdf0e10cSrcweir 		// not seekable (pipe)
445cdf0e10cSrcweir 		DWORD dwDone = 0;
446cdf0e10cSrcweir 		if (!::WriteFile(m_hFile, pBuffer, nBytesToWrite, &dwDone, 0))
447cdf0e10cSrcweir 			return oslTranslateFileError( GetLastError() );
448cdf0e10cSrcweir 		*pBytesWritten = dwDone;
449cdf0e10cSrcweir 		return osl_File_E_None;
450cdf0e10cSrcweir 	}
451cdf0e10cSrcweir 	else if (0 == m_buffer)
452cdf0e10cSrcweir 	{
453cdf0e10cSrcweir 		// not buffered
454cdf0e10cSrcweir 		return writeAt(nOffset, pBuffer, nBytesToWrite, pBytesWritten);
455cdf0e10cSrcweir 	}
456cdf0e10cSrcweir 	else
457cdf0e10cSrcweir 	{
458cdf0e10cSrcweir 		sal_uInt8 const * buffer = static_cast< sal_uInt8 const* >(pBuffer);
459cdf0e10cSrcweir 		for (*pBytesWritten = 0; nBytesToWrite > 0; )
460cdf0e10cSrcweir 		{
461cdf0e10cSrcweir 			LONGLONG const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
462cdf0e10cSrcweir 			SIZE_T   const bufpos = (nOffset % m_bufsiz);
463cdf0e10cSrcweir 			if (bufptr != m_bufptr)
464cdf0e10cSrcweir 			{
465cdf0e10cSrcweir 				// flush current buffer
466cdf0e10cSrcweir 				oslFileError result = syncFile();
467cdf0e10cSrcweir 				if (result != osl_File_E_None)
468cdf0e10cSrcweir 					return (result);
469cdf0e10cSrcweir                 m_bufptr = -1, m_buflen = 0;
470cdf0e10cSrcweir 
471cdf0e10cSrcweir 				if (nBytesToWrite >= m_bufsiz)
472cdf0e10cSrcweir 				{
473cdf0e10cSrcweir 					// buffer too small, write through to file
474cdf0e10cSrcweir 					sal_uInt64 uDone = 0;
475cdf0e10cSrcweir 					result = writeAt (nOffset, &(buffer[*pBytesWritten]), nBytesToWrite, &uDone);
476cdf0e10cSrcweir 					if (result != osl_File_E_None)
477cdf0e10cSrcweir 						return (result);
478cdf0e10cSrcweir 					if (uDone != nBytesToWrite)
479cdf0e10cSrcweir 						return osl_File_E_IO;
480cdf0e10cSrcweir 
481cdf0e10cSrcweir 					nBytesToWrite -= sal::static_int_cast< DWORD >(uDone), *pBytesWritten += uDone;
482cdf0e10cSrcweir 					return osl_File_E_None;
483cdf0e10cSrcweir 				}
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 				// update buffer (pointer)
486cdf0e10cSrcweir 				sal_uInt64 uDone = 0;
487cdf0e10cSrcweir 				result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
488cdf0e10cSrcweir 				if (result != osl_File_E_None)
489cdf0e10cSrcweir 					return (result);
490cdf0e10cSrcweir 				m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone);
491cdf0e10cSrcweir 			}
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 			SIZE_T const bytes = std::min(m_bufsiz - bufpos, nBytesToWrite);
494cdf0e10cSrcweir 			memcpy (&(m_buffer[bufpos]), &(buffer[*pBytesWritten]), bytes);
495cdf0e10cSrcweir 			nBytesToWrite -= bytes, *pBytesWritten += bytes, nOffset += bytes;
496cdf0e10cSrcweir 
497cdf0e10cSrcweir 			m_buflen = std::max(m_buflen, bufpos + bytes);
498cdf0e10cSrcweir 			m_state |= STATE_MODIFIED;
499cdf0e10cSrcweir 		}
500cdf0e10cSrcweir 		return osl_File_E_None;
501cdf0e10cSrcweir 	}
502cdf0e10cSrcweir }
503cdf0e10cSrcweir 
readLineAt(LONGLONG nOffset,sal_Sequence ** ppSequence,sal_uInt64 * pBytesRead)504cdf0e10cSrcweir oslFileError FileHandle_Impl::readLineAt (
505cdf0e10cSrcweir     LONGLONG        nOffset,
506cdf0e10cSrcweir     sal_Sequence ** ppSequence,
507cdf0e10cSrcweir     sal_uInt64 *    pBytesRead)
508cdf0e10cSrcweir {
509cdf0e10cSrcweir     oslFileError result = osl_File_E_None;
510cdf0e10cSrcweir 
511cdf0e10cSrcweir     LONGLONG bufptr = (nOffset / m_bufsiz) * m_bufsiz;
512cdf0e10cSrcweir     if (bufptr != m_bufptr)
513cdf0e10cSrcweir     {
514cdf0e10cSrcweir         /* flush current buffer */
515cdf0e10cSrcweir         result = syncFile();
516cdf0e10cSrcweir         if (result != osl_File_E_None)
517cdf0e10cSrcweir             return (result);
518cdf0e10cSrcweir 
519cdf0e10cSrcweir         /* update buffer (pointer) */
520cdf0e10cSrcweir         sal_uInt64 uDone = 0;
521cdf0e10cSrcweir         result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
522cdf0e10cSrcweir         if (result != osl_File_E_None)
523cdf0e10cSrcweir             return (result);
524cdf0e10cSrcweir 
525cdf0e10cSrcweir         m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone);
526cdf0e10cSrcweir     }
527cdf0e10cSrcweir 
528cdf0e10cSrcweir     static int const LINE_STATE_BEGIN = 0;
529cdf0e10cSrcweir     static int const LINE_STATE_CR    = 1;
530cdf0e10cSrcweir     static int const LINE_STATE_LF    = 2;
531cdf0e10cSrcweir 
532cdf0e10cSrcweir     SIZE_T bufpos = sal::static_int_cast< SIZE_T >(nOffset - m_bufptr), curpos = bufpos, dstpos = 0;
533cdf0e10cSrcweir     int    state  = (bufpos >= m_buflen) ? LINE_STATE_LF : LINE_STATE_BEGIN;
534cdf0e10cSrcweir 
535cdf0e10cSrcweir     for ( ; state != LINE_STATE_LF; )
536cdf0e10cSrcweir     {
537cdf0e10cSrcweir         if (curpos >= m_buflen)
538cdf0e10cSrcweir         {
539cdf0e10cSrcweir             /* buffer examined */
540cdf0e10cSrcweir             if (0 < (curpos - bufpos))
541cdf0e10cSrcweir             {
542cdf0e10cSrcweir                 /* flush buffer to sequence */
543cdf0e10cSrcweir                 result = writeSequence_Impl (
544cdf0e10cSrcweir                     ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos);
545cdf0e10cSrcweir                 if (result != osl_File_E_None)
546cdf0e10cSrcweir                     return (result);
547cdf0e10cSrcweir                 *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
548cdf0e10cSrcweir             }
549cdf0e10cSrcweir 
550cdf0e10cSrcweir             bufptr = nOffset / m_bufsiz * m_bufsiz;
551cdf0e10cSrcweir             if (bufptr != m_bufptr)
552cdf0e10cSrcweir             {
553cdf0e10cSrcweir                 /* update buffer (pointer) */
554cdf0e10cSrcweir                 sal_uInt64 uDone = 0;
555cdf0e10cSrcweir                 result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
556cdf0e10cSrcweir                 if (result != osl_File_E_None)
557cdf0e10cSrcweir                     return (result);
558cdf0e10cSrcweir                 m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone);
559cdf0e10cSrcweir             }
560cdf0e10cSrcweir 
561cdf0e10cSrcweir             bufpos = sal::static_int_cast< SIZE_T >(nOffset - m_bufptr), curpos = bufpos;
562cdf0e10cSrcweir             if (bufpos >= m_buflen)
563cdf0e10cSrcweir                 break;
564cdf0e10cSrcweir         }
565cdf0e10cSrcweir         switch (state)
566cdf0e10cSrcweir         {
567cdf0e10cSrcweir         case LINE_STATE_CR:
568cdf0e10cSrcweir             state = LINE_STATE_LF;
569cdf0e10cSrcweir             switch (m_buffer[curpos])
570cdf0e10cSrcweir             {
571cdf0e10cSrcweir             case 0x0A: /* CRLF */
572cdf0e10cSrcweir                 /* eat current char */
573cdf0e10cSrcweir                 curpos++;
574cdf0e10cSrcweir                 break;
575cdf0e10cSrcweir             default: /* single CR */
576cdf0e10cSrcweir                 /* keep current char */
577cdf0e10cSrcweir                 break;
578cdf0e10cSrcweir             }
579cdf0e10cSrcweir             break;
580cdf0e10cSrcweir         default:
581cdf0e10cSrcweir             /* determine next state */
582cdf0e10cSrcweir             switch (m_buffer[curpos])
583cdf0e10cSrcweir             {
584cdf0e10cSrcweir             case 0x0A: /* single LF */
585cdf0e10cSrcweir                 state = LINE_STATE_LF;
586cdf0e10cSrcweir                 break;
587cdf0e10cSrcweir             case 0x0D: /* CR */
588cdf0e10cSrcweir                 state = LINE_STATE_CR;
589cdf0e10cSrcweir                 break;
590cdf0e10cSrcweir             default: /* advance to next char */
591cdf0e10cSrcweir                 curpos++;
592cdf0e10cSrcweir                 break;
593cdf0e10cSrcweir             }
594cdf0e10cSrcweir             if (state != LINE_STATE_BEGIN)
595cdf0e10cSrcweir             {
596cdf0e10cSrcweir                 /* store (and eat) the newline char */
597cdf0e10cSrcweir                 m_buffer[curpos] = 0x0A, curpos++;
598cdf0e10cSrcweir 
599cdf0e10cSrcweir                 /* flush buffer to sequence */
600cdf0e10cSrcweir                 result = writeSequence_Impl (
601cdf0e10cSrcweir                     ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos - 1);
602cdf0e10cSrcweir                 if (result != osl_File_E_None)
603cdf0e10cSrcweir                     return (result);
604cdf0e10cSrcweir                 *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
605cdf0e10cSrcweir             }
606cdf0e10cSrcweir             break;
607cdf0e10cSrcweir         }
608cdf0e10cSrcweir     }
609cdf0e10cSrcweir 
610cdf0e10cSrcweir     result = writeSequence_Impl (ppSequence, &dstpos, 0, 0);
611cdf0e10cSrcweir     if (result != osl_File_E_None)
612cdf0e10cSrcweir         return (result);
613cdf0e10cSrcweir     if (0 < dstpos)
614cdf0e10cSrcweir         return osl_File_E_None;
615cdf0e10cSrcweir     if (bufpos >= m_buflen)
616cdf0e10cSrcweir         return osl_File_E_AGAIN;
617cdf0e10cSrcweir     return osl_File_E_None;
618cdf0e10cSrcweir }
619cdf0e10cSrcweir 
writeSequence_Impl(sal_Sequence ** ppSequence,SIZE_T * pnOffset,const void * pBuffer,SIZE_T nBytes)620cdf0e10cSrcweir oslFileError FileHandle_Impl::writeSequence_Impl (
621cdf0e10cSrcweir     sal_Sequence ** ppSequence,
622cdf0e10cSrcweir     SIZE_T *        pnOffset,
623cdf0e10cSrcweir     const void *    pBuffer,
624cdf0e10cSrcweir     SIZE_T          nBytes)
625cdf0e10cSrcweir {
626cdf0e10cSrcweir     sal_Int32 nElements = *pnOffset + nBytes;
627cdf0e10cSrcweir     if (!*ppSequence)
628cdf0e10cSrcweir     {
629cdf0e10cSrcweir         /* construct sequence */
630cdf0e10cSrcweir         rtl_byte_sequence_constructNoDefault(ppSequence, nElements);
631cdf0e10cSrcweir     }
632cdf0e10cSrcweir     else if (nElements != (*ppSequence)->nElements)
633cdf0e10cSrcweir     {
634cdf0e10cSrcweir         /* resize sequence */
635cdf0e10cSrcweir         rtl_byte_sequence_realloc(ppSequence, nElements);
636cdf0e10cSrcweir     }
637cdf0e10cSrcweir     if (*ppSequence != 0)
638cdf0e10cSrcweir     {
639cdf0e10cSrcweir         /* fill sequence */
640cdf0e10cSrcweir         memcpy(&((*ppSequence)->elements[*pnOffset]), pBuffer, nBytes), *pnOffset += nBytes;
641cdf0e10cSrcweir     }
642cdf0e10cSrcweir     return (*ppSequence != 0) ? osl_File_E_None : osl_File_E_NOMEM;
643cdf0e10cSrcweir }
644cdf0e10cSrcweir 
syncFile()645cdf0e10cSrcweir oslFileError FileHandle_Impl::syncFile()
646cdf0e10cSrcweir {
647cdf0e10cSrcweir 	oslFileError result = osl_File_E_None;
648cdf0e10cSrcweir 	if (m_state & STATE_MODIFIED)
649cdf0e10cSrcweir 	{
650cdf0e10cSrcweir 		sal_uInt64 uDone = 0;
651cdf0e10cSrcweir 		result = writeAt (m_bufptr, m_buffer, m_buflen, &uDone);
652cdf0e10cSrcweir 		if (result != osl_File_E_None)
653cdf0e10cSrcweir 			return (result);
654cdf0e10cSrcweir 		if (uDone != m_buflen)
655cdf0e10cSrcweir 			return osl_File_E_IO;
656cdf0e10cSrcweir 		m_state &= ~STATE_MODIFIED;
657cdf0e10cSrcweir 	}
658cdf0e10cSrcweir 	return (result);
659cdf0e10cSrcweir }
660cdf0e10cSrcweir 
661cdf0e10cSrcweir //##################################################################
662cdf0e10cSrcweir // File I/O functions
663cdf0e10cSrcweir //##################################################################
664cdf0e10cSrcweir 
665cdf0e10cSrcweir extern "C" oslFileHandle
osl_createFileHandleFromOSHandle(HANDLE hFile,sal_uInt32 uFlags)666cdf0e10cSrcweir SAL_CALL osl_createFileHandleFromOSHandle (
667cdf0e10cSrcweir 	HANDLE     hFile,
668cdf0e10cSrcweir 	sal_uInt32 uFlags)
669cdf0e10cSrcweir {
670cdf0e10cSrcweir 	if ( !IsValidHandle(hFile) )
671cdf0e10cSrcweir 		return 0; // EINVAL
672cdf0e10cSrcweir 
673cdf0e10cSrcweir 	FileHandle_Impl * pImpl = new FileHandle_Impl(hFile);
674cdf0e10cSrcweir 	if (pImpl == 0)
675cdf0e10cSrcweir 	{
676cdf0e10cSrcweir 		// cleanup and fail
677cdf0e10cSrcweir 		(void) ::CloseHandle(hFile);
678cdf0e10cSrcweir 		return 0; // ENOMEM
679cdf0e10cSrcweir 	}
680cdf0e10cSrcweir 
681cdf0e10cSrcweir 	/* check for regular file */
682cdf0e10cSrcweir 	if (FILE_TYPE_DISK == GetFileType(hFile))
683cdf0e10cSrcweir 	{
684cdf0e10cSrcweir 		/* mark seekable */
685cdf0e10cSrcweir 		pImpl->m_state |= FileHandle_Impl::STATE_SEEKABLE;
686cdf0e10cSrcweir 
687cdf0e10cSrcweir 		/* init current size */
688cdf0e10cSrcweir 		LARGE_INTEGER uSize = { 0, 0 };
689cdf0e10cSrcweir 		(void) ::GetFileSizeEx(hFile, &uSize);
690cdf0e10cSrcweir 		pImpl->m_size = (sal::static_int_cast<sal_uInt64>(uSize.HighPart) << 32) + uSize.LowPart;
691cdf0e10cSrcweir 	}
692cdf0e10cSrcweir 
693cdf0e10cSrcweir 	if (!(uFlags & osl_File_OpenFlag_Read))
694cdf0e10cSrcweir 		pImpl->m_state &= ~FileHandle_Impl::STATE_READABLE;
695cdf0e10cSrcweir 	if (!(uFlags & osl_File_OpenFlag_Write))
696cdf0e10cSrcweir 		pImpl->m_state &= ~FileHandle_Impl::STATE_WRITEABLE;
697cdf0e10cSrcweir 
698cdf0e10cSrcweir 	OSL_POSTCOND(
699cdf0e10cSrcweir 		(uFlags & osl_File_OpenFlag_Read) || (uFlags & osl_File_OpenFlag_Write),
700cdf0e10cSrcweir 		"osl_createFileHandleFromOSHandle(): missing read/write access flags");
701cdf0e10cSrcweir 	return (oslFileHandle)(pImpl);
702cdf0e10cSrcweir }
703cdf0e10cSrcweir 
704cdf0e10cSrcweir //#############################################
705cdf0e10cSrcweir oslFileError
osl_openFile(rtl_uString * strPath,oslFileHandle * pHandle,sal_uInt32 uFlags)706cdf0e10cSrcweir SAL_CALL osl_openFile(
707cdf0e10cSrcweir     rtl_uString *   strPath,
708cdf0e10cSrcweir 	oslFileHandle * pHandle,
709cdf0e10cSrcweir 	sal_uInt32      uFlags )
710cdf0e10cSrcweir {
711cdf0e10cSrcweir 	rtl_uString * strSysPath = 0;
712cdf0e10cSrcweir 	oslFileError result = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
713cdf0e10cSrcweir 	if (result != osl_File_E_None)
714cdf0e10cSrcweir 		return (result);
715cdf0e10cSrcweir 
716cdf0e10cSrcweir 	DWORD dwAccess = GENERIC_READ, dwShare = FILE_SHARE_READ, dwCreation = 0, dwAttributes = 0;
717cdf0e10cSrcweir 
718cdf0e10cSrcweir 	if ( uFlags & osl_File_OpenFlag_Write )
719cdf0e10cSrcweir 		dwAccess |= GENERIC_WRITE;
720cdf0e10cSrcweir 	else
721cdf0e10cSrcweir 		dwShare  |= FILE_SHARE_WRITE;
722cdf0e10cSrcweir 
723cdf0e10cSrcweir 	if ( uFlags & osl_File_OpenFlag_NoLock )
724cdf0e10cSrcweir 		dwShare  |= FILE_SHARE_WRITE;
725cdf0e10cSrcweir 
726cdf0e10cSrcweir 	if ( uFlags & osl_File_OpenFlag_Create )
727cdf0e10cSrcweir 		dwCreation |= CREATE_NEW;
728cdf0e10cSrcweir 	else
729cdf0e10cSrcweir 		dwCreation |= OPEN_EXISTING;
730cdf0e10cSrcweir 
731cdf0e10cSrcweir 	HANDLE hFile = CreateFileW(
732cdf0e10cSrcweir 		reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )),
733cdf0e10cSrcweir 		dwAccess, dwShare, NULL, dwCreation, dwAttributes, NULL );
734cdf0e10cSrcweir 
735cdf0e10cSrcweir 	// @@@ ERROR HANDLING @@@
736cdf0e10cSrcweir 	if ( !IsValidHandle( hFile ) )
737cdf0e10cSrcweir 		result = oslTranslateFileError( GetLastError() );
738cdf0e10cSrcweir 
739cdf0e10cSrcweir 	*pHandle = osl_createFileHandleFromOSHandle (hFile, uFlags | osl_File_OpenFlag_Read);
740cdf0e10cSrcweir 
741cdf0e10cSrcweir 	rtl_uString_release( strSysPath );
742cdf0e10cSrcweir 	return (result);
743cdf0e10cSrcweir }
744cdf0e10cSrcweir 
745cdf0e10cSrcweir //#############################################
746cdf0e10cSrcweir oslFileError
osl_syncFile(oslFileHandle Handle)747cdf0e10cSrcweir SAL_CALL osl_syncFile(oslFileHandle Handle)
748cdf0e10cSrcweir {
749cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
750cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile))
751cdf0e10cSrcweir 		return osl_File_E_INVAL;
752cdf0e10cSrcweir 
753cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
754cdf0e10cSrcweir 
755cdf0e10cSrcweir 	oslFileError result = pImpl->syncFile();
756cdf0e10cSrcweir 	if (result != osl_File_E_None)
757cdf0e10cSrcweir 		return result;
758cdf0e10cSrcweir 
759cdf0e10cSrcweir     if (!FlushFileBuffers(pImpl->m_hFile))
760cdf0e10cSrcweir         return oslTranslateFileError(GetLastError());
761cdf0e10cSrcweir 
762cdf0e10cSrcweir     return osl_File_E_None;
763cdf0e10cSrcweir }
764cdf0e10cSrcweir 
765cdf0e10cSrcweir //#############################################
766cdf0e10cSrcweir oslFileError
osl_closeFile(oslFileHandle Handle)767cdf0e10cSrcweir SAL_CALL osl_closeFile(oslFileHandle Handle)
768cdf0e10cSrcweir {
769cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
770cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile))
771cdf0e10cSrcweir 		return osl_File_E_INVAL;
772cdf0e10cSrcweir 
773cdf0e10cSrcweir     ::EnterCriticalSection (&(pImpl->m_mutex));
774cdf0e10cSrcweir 
775cdf0e10cSrcweir 	oslFileError result = pImpl->syncFile();
776cdf0e10cSrcweir 	if (result != osl_File_E_None)
777cdf0e10cSrcweir 	{
778cdf0e10cSrcweir 		/* ignore double failure */
779cdf0e10cSrcweir 		(void)::CloseHandle(pImpl->m_hFile);
780cdf0e10cSrcweir 	}
781cdf0e10cSrcweir 	else if (!::CloseHandle(pImpl->m_hFile))
782cdf0e10cSrcweir 	{
783cdf0e10cSrcweir 		/* translate error code */
784cdf0e10cSrcweir 		result = oslTranslateFileError( GetLastError() );
785cdf0e10cSrcweir 	}
786cdf0e10cSrcweir 
787cdf0e10cSrcweir     ::LeaveCriticalSection (&(pImpl->m_mutex));
788cdf0e10cSrcweir 	delete pImpl;
789cdf0e10cSrcweir 	return (result);
790cdf0e10cSrcweir }
791cdf0e10cSrcweir 
792cdf0e10cSrcweir //#############################################
793cdf0e10cSrcweir oslFileError
osl_mapFile(oslFileHandle Handle,void ** ppAddr,sal_uInt64 uLength,sal_uInt64 uOffset,sal_uInt32 uFlags)794cdf0e10cSrcweir SAL_CALL osl_mapFile(
795cdf0e10cSrcweir 	oslFileHandle Handle,
796cdf0e10cSrcweir 	void**        ppAddr,
797cdf0e10cSrcweir 	sal_uInt64    uLength,
798cdf0e10cSrcweir 	sal_uInt64    uOffset,
799cdf0e10cSrcweir 	sal_uInt32    uFlags)
800cdf0e10cSrcweir {
801cdf0e10cSrcweir 	struct FileMapping
802cdf0e10cSrcweir 	{
803cdf0e10cSrcweir 		HANDLE m_handle;
804cdf0e10cSrcweir 
805cdf0e10cSrcweir 		explicit FileMapping (HANDLE hMap)
806cdf0e10cSrcweir 			: m_handle (hMap)
807cdf0e10cSrcweir 		{}
808cdf0e10cSrcweir 
809cdf0e10cSrcweir 		~FileMapping()
810cdf0e10cSrcweir 		{
811cdf0e10cSrcweir 			(void)::CloseHandle(m_handle);
812cdf0e10cSrcweir 		}
813cdf0e10cSrcweir 	};
814cdf0e10cSrcweir 
815cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
816cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == ppAddr))
817cdf0e10cSrcweir 		return osl_File_E_INVAL;
818cdf0e10cSrcweir 	*ppAddr = 0;
819cdf0e10cSrcweir 
820cdf0e10cSrcweir 	static SIZE_T const nLimit = std::numeric_limits< SIZE_T >::max();
821cdf0e10cSrcweir 	if (uLength > nLimit)
822cdf0e10cSrcweir 		return osl_File_E_OVERFLOW;
823cdf0e10cSrcweir 	SIZE_T const nLength = sal::static_int_cast< SIZE_T >(uLength);
824cdf0e10cSrcweir 
825cdf0e10cSrcweir 	OSVERSIONINFO osinfo;
826cdf0e10cSrcweir 	osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
827cdf0e10cSrcweir 	(void)::GetVersionEx(&osinfo);
828cdf0e10cSrcweir 
829cdf0e10cSrcweir 	if (VER_PLATFORM_WIN32_NT != osinfo.dwPlatformId)
830cdf0e10cSrcweir 		return osl_File_E_NOSYS; // Unsupported
831cdf0e10cSrcweir 
832cdf0e10cSrcweir 	FileMapping aMap( ::CreateFileMapping (pImpl->m_hFile, NULL, SEC_COMMIT | PAGE_READONLY, 0, 0, NULL) );
833cdf0e10cSrcweir 	if (!IsValidHandle(aMap.m_handle))
834cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
835cdf0e10cSrcweir 
836cdf0e10cSrcweir 	DWORD const dwOffsetHi = sal::static_int_cast<DWORD>(uOffset >> 32);
837cdf0e10cSrcweir 	DWORD const dwOffsetLo = sal::static_int_cast<DWORD>(uOffset & 0xFFFFFFFF);
838cdf0e10cSrcweir 
839cdf0e10cSrcweir 	*ppAddr = ::MapViewOfFile( aMap.m_handle, FILE_MAP_READ, dwOffsetHi, dwOffsetLo, nLength );
840cdf0e10cSrcweir 	if (0 == *ppAddr)
841cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
842cdf0e10cSrcweir 
843cdf0e10cSrcweir 	if (uFlags & osl_File_MapFlag_RandomAccess)
844cdf0e10cSrcweir 	{
845cdf0e10cSrcweir 		// Determine memory pagesize.
846cdf0e10cSrcweir 		SYSTEM_INFO info;
847cdf0e10cSrcweir 		::GetSystemInfo( &info );
848cdf0e10cSrcweir 		DWORD const dwPageSize = info.dwPageSize;
849cdf0e10cSrcweir 
850cdf0e10cSrcweir 		/*
851cdf0e10cSrcweir 		 * Pagein, touching first byte of each memory page.
852cdf0e10cSrcweir 		 * Note: volatile disables optimizing the loop away.
853cdf0e10cSrcweir 		 */
854cdf0e10cSrcweir 		BYTE * pData (reinterpret_cast<BYTE*>(*ppAddr));
855cdf0e10cSrcweir 		SIZE_T nSize (nLength);
856cdf0e10cSrcweir 
857cdf0e10cSrcweir 		volatile BYTE c = 0;
858cdf0e10cSrcweir 		while (nSize > dwPageSize)
859cdf0e10cSrcweir 		{
860cdf0e10cSrcweir 			c ^= pData[0];
861cdf0e10cSrcweir 			pData += dwPageSize;
862cdf0e10cSrcweir 			nSize -= dwPageSize;
863cdf0e10cSrcweir 		}
864cdf0e10cSrcweir 		if (nSize > 0)
865cdf0e10cSrcweir 		{
866cdf0e10cSrcweir 			c ^= pData[0];
867cdf0e10cSrcweir 			pData += nSize;
868cdf0e10cSrcweir 			nSize -= nSize;
869cdf0e10cSrcweir 		}
870cdf0e10cSrcweir 	}
871cdf0e10cSrcweir 	return osl_File_E_None;
872cdf0e10cSrcweir }
873cdf0e10cSrcweir 
874cdf0e10cSrcweir //#############################################
875cdf0e10cSrcweir oslFileError
osl_unmapFile(void * pAddr,sal_uInt64)876cdf0e10cSrcweir SAL_CALL osl_unmapFile(void* pAddr, sal_uInt64 /* uLength */)
877cdf0e10cSrcweir {
878cdf0e10cSrcweir 	if (0 == pAddr)
879cdf0e10cSrcweir 		return osl_File_E_INVAL;
880cdf0e10cSrcweir 
881cdf0e10cSrcweir 	if (!::UnmapViewOfFile (pAddr))
882cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
883cdf0e10cSrcweir 
884cdf0e10cSrcweir 	return osl_File_E_None;
885cdf0e10cSrcweir }
886cdf0e10cSrcweir 
887cdf0e10cSrcweir //#############################################
888cdf0e10cSrcweir oslFileError
osl_readLine(oslFileHandle Handle,sal_Sequence ** ppSequence)889cdf0e10cSrcweir SAL_CALL osl_readLine(
890cdf0e10cSrcweir 	oslFileHandle   Handle,
891cdf0e10cSrcweir 	sal_Sequence ** ppSequence)
892cdf0e10cSrcweir {
893cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
894cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == ppSequence))
895cdf0e10cSrcweir 		return osl_File_E_INVAL;
896cdf0e10cSrcweir 	sal_uInt64 uBytesRead = 0;
897cdf0e10cSrcweir 
898cdf0e10cSrcweir 	// read at current filepos; filepos += uBytesRead;
899cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
900cdf0e10cSrcweir 	oslFileError result = pImpl->readLineAt (
901cdf0e10cSrcweir 		pImpl->m_filepos, ppSequence, &uBytesRead);
902cdf0e10cSrcweir 	if (result == osl_File_E_None)
903cdf0e10cSrcweir 		pImpl->m_filepos += uBytesRead;
904cdf0e10cSrcweir 	return (result);
905cdf0e10cSrcweir }
906cdf0e10cSrcweir 
907cdf0e10cSrcweir //#############################################
908cdf0e10cSrcweir oslFileError
osl_readFile(oslFileHandle Handle,void * pBuffer,sal_uInt64 uBytesRequested,sal_uInt64 * pBytesRead)909cdf0e10cSrcweir SAL_CALL osl_readFile(
910cdf0e10cSrcweir     oslFileHandle Handle,
911cdf0e10cSrcweir     void *        pBuffer,
912cdf0e10cSrcweir     sal_uInt64    uBytesRequested,
913cdf0e10cSrcweir     sal_uInt64 *  pBytesRead)
914cdf0e10cSrcweir {
915cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
916cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesRead))
917cdf0e10cSrcweir 		return osl_File_E_INVAL;
918cdf0e10cSrcweir 
919cdf0e10cSrcweir 	// read at current filepos; filepos += *pBytesRead;
920cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
921cdf0e10cSrcweir 	oslFileError result = pImpl->readFileAt (
922cdf0e10cSrcweir 		pImpl->m_filepos, pBuffer, uBytesRequested, pBytesRead);
923cdf0e10cSrcweir 	if (result == osl_File_E_None)
924cdf0e10cSrcweir 		pImpl->m_filepos += *pBytesRead;
925cdf0e10cSrcweir 	return (result);
926cdf0e10cSrcweir }
927cdf0e10cSrcweir 
928cdf0e10cSrcweir //#############################################
929cdf0e10cSrcweir oslFileError
osl_writeFile(oslFileHandle Handle,const void * pBuffer,sal_uInt64 uBytesToWrite,sal_uInt64 * pBytesWritten)930cdf0e10cSrcweir SAL_CALL osl_writeFile(
931cdf0e10cSrcweir     oslFileHandle Handle,
932cdf0e10cSrcweir     const void *  pBuffer,
933cdf0e10cSrcweir     sal_uInt64    uBytesToWrite,
934cdf0e10cSrcweir     sal_uInt64 *  pBytesWritten )
935cdf0e10cSrcweir {
936cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
937cdf0e10cSrcweir 
938cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesWritten))
939cdf0e10cSrcweir 		return osl_File_E_INVAL;
940cdf0e10cSrcweir 
941cdf0e10cSrcweir 	// write at current filepos; filepos += *pBytesWritten;
942cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
943cdf0e10cSrcweir 	oslFileError result = pImpl->writeFileAt (
944cdf0e10cSrcweir 		pImpl->m_filepos, pBuffer, uBytesToWrite, pBytesWritten);
945cdf0e10cSrcweir 	if (result == osl_File_E_None)
946cdf0e10cSrcweir 		pImpl->m_filepos += *pBytesWritten;
947cdf0e10cSrcweir 	return (result);
948cdf0e10cSrcweir }
949cdf0e10cSrcweir 
950cdf0e10cSrcweir //#############################################
951cdf0e10cSrcweir oslFileError
osl_readFileAt(oslFileHandle Handle,sal_uInt64 uOffset,void * pBuffer,sal_uInt64 uBytesRequested,sal_uInt64 * pBytesRead)952cdf0e10cSrcweir SAL_CALL osl_readFileAt(
953cdf0e10cSrcweir 	oslFileHandle Handle,
954cdf0e10cSrcweir 	sal_uInt64    uOffset,
955cdf0e10cSrcweir 	void*         pBuffer,
956cdf0e10cSrcweir 	sal_uInt64    uBytesRequested,
957cdf0e10cSrcweir 	sal_uInt64*   pBytesRead)
958cdf0e10cSrcweir {
959cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
960cdf0e10cSrcweir 
961cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesRead))
962cdf0e10cSrcweir 		return osl_File_E_INVAL;
963cdf0e10cSrcweir 	if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
964cdf0e10cSrcweir 		return osl_File_E_SPIPE;
965cdf0e10cSrcweir 
966cdf0e10cSrcweir 	static sal_uInt64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max();
967cdf0e10cSrcweir 	if (g_limit_longlong < uOffset)
968cdf0e10cSrcweir 		return osl_File_E_OVERFLOW;
969cdf0e10cSrcweir 	LONGLONG const nOffset = sal::static_int_cast< LONGLONG >(uOffset);
970cdf0e10cSrcweir 
971cdf0e10cSrcweir 	// read at specified fileptr
972cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
973cdf0e10cSrcweir 	return pImpl->readFileAt (nOffset, pBuffer, uBytesRequested, pBytesRead);
974cdf0e10cSrcweir }
975cdf0e10cSrcweir 
976cdf0e10cSrcweir //#############################################
977cdf0e10cSrcweir oslFileError
osl_writeFileAt(oslFileHandle Handle,sal_uInt64 uOffset,const void * pBuffer,sal_uInt64 uBytesToWrite,sal_uInt64 * pBytesWritten)978cdf0e10cSrcweir SAL_CALL osl_writeFileAt(
979cdf0e10cSrcweir 	oslFileHandle Handle,
980cdf0e10cSrcweir 	sal_uInt64    uOffset,
981cdf0e10cSrcweir 	const void*   pBuffer,
982cdf0e10cSrcweir 	sal_uInt64    uBytesToWrite,
983cdf0e10cSrcweir 	sal_uInt64*   pBytesWritten)
984cdf0e10cSrcweir {
985cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
986cdf0e10cSrcweir 
987cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesWritten))
988cdf0e10cSrcweir 		return osl_File_E_INVAL;
989cdf0e10cSrcweir 	if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
990cdf0e10cSrcweir 		return osl_File_E_SPIPE;
991cdf0e10cSrcweir 
992cdf0e10cSrcweir 	static sal_uInt64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max();
993cdf0e10cSrcweir 	if (g_limit_longlong < uOffset)
994cdf0e10cSrcweir 		return osl_File_E_OVERFLOW;
995cdf0e10cSrcweir 	LONGLONG const nOffset = sal::static_int_cast< LONGLONG >(uOffset);
996cdf0e10cSrcweir 
997cdf0e10cSrcweir 	// write at specified fileptr
998cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
999cdf0e10cSrcweir 	return pImpl->writeFileAt (nOffset, pBuffer, uBytesToWrite, pBytesWritten);
1000cdf0e10cSrcweir }
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir //#############################################
1003cdf0e10cSrcweir oslFileError
osl_isEndOfFile(oslFileHandle Handle,sal_Bool * pIsEOF)1004cdf0e10cSrcweir SAL_CALL osl_isEndOfFile (oslFileHandle Handle, sal_Bool *pIsEOF)
1005cdf0e10cSrcweir {
1006cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
1007cdf0e10cSrcweir 
1008cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pIsEOF))
1009cdf0e10cSrcweir 		return osl_File_E_INVAL;
1010cdf0e10cSrcweir 
1011cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
1012cdf0e10cSrcweir 	*pIsEOF = (pImpl->getPos() == pImpl->getSize());
1013cdf0e10cSrcweir 	return osl_File_E_None;
1014cdf0e10cSrcweir }
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir //#############################################
1017cdf0e10cSrcweir oslFileError
osl_getFilePos(oslFileHandle Handle,sal_uInt64 * pPos)1018cdf0e10cSrcweir SAL_CALL osl_getFilePos(oslFileHandle Handle, sal_uInt64 *pPos)
1019cdf0e10cSrcweir {
1020cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
1021cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pPos))
1022cdf0e10cSrcweir 		return osl_File_E_INVAL;
1023cdf0e10cSrcweir 
1024cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
1025cdf0e10cSrcweir 	*pPos = pImpl->getPos();
1026cdf0e10cSrcweir 	return osl_File_E_None;
1027cdf0e10cSrcweir }
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir //#############################################
1030cdf0e10cSrcweir oslFileError
osl_setFilePos(oslFileHandle Handle,sal_uInt32 uHow,sal_Int64 uOffset)1031cdf0e10cSrcweir SAL_CALL osl_setFilePos(oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uOffset)
1032cdf0e10cSrcweir {
1033cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
1034cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile))
1035cdf0e10cSrcweir 		return osl_File_E_INVAL;
1036cdf0e10cSrcweir 
1037cdf0e10cSrcweir 	static sal_Int64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max();
1038cdf0e10cSrcweir 	if (g_limit_longlong < uOffset)
1039cdf0e10cSrcweir 		return osl_File_E_OVERFLOW;
1040cdf0e10cSrcweir 	LONGLONG nPos = 0, nOffset = sal::static_int_cast< LONGLONG >(uOffset);
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
1043cdf0e10cSrcweir 	switch (uHow)
1044cdf0e10cSrcweir 	{
1045cdf0e10cSrcweir 		case osl_Pos_Absolut:
1046cdf0e10cSrcweir 			if (0 > nOffset)
1047cdf0e10cSrcweir 				return osl_File_E_INVAL;
1048cdf0e10cSrcweir 			break;
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir 		case osl_Pos_Current:
1051cdf0e10cSrcweir 			nPos = sal::static_int_cast< LONGLONG >(pImpl->getPos());
1052cdf0e10cSrcweir 			if ((0 > nOffset) && (-1*nOffset > nPos))
1053cdf0e10cSrcweir 				return osl_File_E_INVAL;
1054cdf0e10cSrcweir 			if (g_limit_longlong < nPos + nOffset)
1055cdf0e10cSrcweir 				return osl_File_E_OVERFLOW;
1056cdf0e10cSrcweir 			break;
1057cdf0e10cSrcweir 
1058cdf0e10cSrcweir 		case osl_Pos_End:
1059cdf0e10cSrcweir 			nPos = sal::static_int_cast< LONGLONG >(pImpl->getSize());
1060cdf0e10cSrcweir 			if ((0 > nOffset) && (-1*nOffset > nPos))
1061cdf0e10cSrcweir 				return osl_File_E_INVAL;
1062cdf0e10cSrcweir 			if (g_limit_longlong < nPos + nOffset)
1063cdf0e10cSrcweir 				return osl_File_E_OVERFLOW;
1064cdf0e10cSrcweir 			break;
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir 		default:
1067cdf0e10cSrcweir 			return osl_File_E_INVAL;
1068cdf0e10cSrcweir 	}
1069cdf0e10cSrcweir 
1070cdf0e10cSrcweir 	return pImpl->setPos (nPos + nOffset);
1071cdf0e10cSrcweir }
1072cdf0e10cSrcweir 
1073cdf0e10cSrcweir //#############################################
1074cdf0e10cSrcweir oslFileError
osl_getFileSize(oslFileHandle Handle,sal_uInt64 * pSize)1075cdf0e10cSrcweir SAL_CALL osl_getFileSize (oslFileHandle Handle, sal_uInt64 *pSize)
1076cdf0e10cSrcweir {
1077cdf0e10cSrcweir     FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
1078cdf0e10cSrcweir 
1079cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pSize))
1080cdf0e10cSrcweir 		return osl_File_E_INVAL;
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
1083cdf0e10cSrcweir     *pSize = pImpl->getSize();
1084cdf0e10cSrcweir     return osl_File_E_None;
1085cdf0e10cSrcweir }
1086cdf0e10cSrcweir 
1087cdf0e10cSrcweir //#############################################
1088cdf0e10cSrcweir oslFileError
osl_setFileSize(oslFileHandle Handle,sal_uInt64 uSize)1089cdf0e10cSrcweir SAL_CALL osl_setFileSize (oslFileHandle Handle, sal_uInt64 uSize)
1090cdf0e10cSrcweir {
1091cdf0e10cSrcweir 	FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
1092cdf0e10cSrcweir 
1093cdf0e10cSrcweir 	if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile))
1094cdf0e10cSrcweir 		return osl_File_E_INVAL;
1095cdf0e10cSrcweir 	if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
1096cdf0e10cSrcweir 		return osl_File_E_BADF;
1097cdf0e10cSrcweir 
1098cdf0e10cSrcweir 	static sal_uInt64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max();
1099cdf0e10cSrcweir 	if (g_limit_longlong < uSize)
1100cdf0e10cSrcweir 		return osl_File_E_OVERFLOW;
1101cdf0e10cSrcweir 
1102cdf0e10cSrcweir     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
1103cdf0e10cSrcweir 	oslFileError result = pImpl->syncFile();
1104cdf0e10cSrcweir 	if (result != osl_File_E_None)
1105cdf0e10cSrcweir 		return (result);
1106cdf0e10cSrcweir     pImpl->m_bufptr = -1, pImpl->m_buflen = 0;
1107cdf0e10cSrcweir 
1108cdf0e10cSrcweir     return pImpl->setSize (uSize);
1109cdf0e10cSrcweir }
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir //##################################################################
1112cdf0e10cSrcweir // File handling functions
1113cdf0e10cSrcweir //##################################################################
1114cdf0e10cSrcweir 
1115cdf0e10cSrcweir //#############################################
osl_removeFile(rtl_uString * strPath)1116cdf0e10cSrcweir oslFileError SAL_CALL osl_removeFile( rtl_uString* strPath )
1117cdf0e10cSrcweir {
1118cdf0e10cSrcweir 	rtl_uString	*strSysPath = NULL;
1119cdf0e10cSrcweir 	oslFileError	error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
1120cdf0e10cSrcweir 
1121cdf0e10cSrcweir 	if ( osl_File_E_None == error )
1122cdf0e10cSrcweir 	{
1123cdf0e10cSrcweir 		if ( DeleteFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )) ) )
1124cdf0e10cSrcweir 			error = osl_File_E_None;
1125cdf0e10cSrcweir 		else
1126cdf0e10cSrcweir 			error = oslTranslateFileError( GetLastError() );
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir 		rtl_uString_release( strSysPath );
1129cdf0e10cSrcweir 	}
1130cdf0e10cSrcweir 	return error;
1131cdf0e10cSrcweir }
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir //#############################################
1134cdf0e10cSrcweir #define osl_File_CopyRecursive	0x0001
1135cdf0e10cSrcweir #define osl_File_CopyOverwrite	0x0002
1136cdf0e10cSrcweir 
osl_copyFile(rtl_uString * strPath,rtl_uString * strDestPath)1137cdf0e10cSrcweir oslFileError SAL_CALL osl_copyFile( rtl_uString* strPath, rtl_uString *strDestPath )
1138cdf0e10cSrcweir {
1139cdf0e10cSrcweir 	rtl_uString	*strSysPath = NULL, *strSysDestPath = NULL;
1140cdf0e10cSrcweir 	oslFileError	error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
1141cdf0e10cSrcweir 
1142cdf0e10cSrcweir 	if ( osl_File_E_None == error )
1143cdf0e10cSrcweir 		error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False );
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir 	if ( osl_File_E_None == error )
1146cdf0e10cSrcweir 	{
1147cdf0e10cSrcweir 		LPCTSTR src = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath ));
1148cdf0e10cSrcweir         LPCTSTR dst = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath ));
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir 		if ( CopyFile( src, dst, FALSE ) )
1151cdf0e10cSrcweir 			error = osl_File_E_None;
1152cdf0e10cSrcweir 		else
1153cdf0e10cSrcweir 			error = oslTranslateFileError( GetLastError() );
1154cdf0e10cSrcweir 	}
1155cdf0e10cSrcweir 
1156cdf0e10cSrcweir 	if ( strSysPath )
1157cdf0e10cSrcweir 		rtl_uString_release( strSysPath );
1158cdf0e10cSrcweir 	if ( strSysDestPath )
1159cdf0e10cSrcweir 		rtl_uString_release( strSysDestPath );
1160cdf0e10cSrcweir 
1161cdf0e10cSrcweir 	return error;
1162cdf0e10cSrcweir }
1163cdf0e10cSrcweir 
1164cdf0e10cSrcweir //#############################################
osl_moveFile(rtl_uString * strPath,rtl_uString * strDestPath)1165cdf0e10cSrcweir oslFileError SAL_CALL osl_moveFile( rtl_uString* strPath, rtl_uString *strDestPath )
1166cdf0e10cSrcweir {
1167cdf0e10cSrcweir 	rtl_uString	*strSysPath = NULL, *strSysDestPath = NULL;
1168cdf0e10cSrcweir 	oslFileError	error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
1169cdf0e10cSrcweir 
1170cdf0e10cSrcweir 	if ( osl_File_E_None == error )
1171cdf0e10cSrcweir 		error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False );
1172cdf0e10cSrcweir 
1173cdf0e10cSrcweir 	if ( osl_File_E_None == error )
1174cdf0e10cSrcweir 	{
1175cdf0e10cSrcweir         LPCTSTR src = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath ));
1176cdf0e10cSrcweir         LPCTSTR dst = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath ));
1177cdf0e10cSrcweir 
1178cdf0e10cSrcweir 		if ( MoveFileEx( src, dst, MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING ) )
1179cdf0e10cSrcweir 			error = osl_File_E_None;
1180cdf0e10cSrcweir 		else
1181cdf0e10cSrcweir 			error = oslTranslateFileError( GetLastError() );
1182cdf0e10cSrcweir 	}
1183cdf0e10cSrcweir 
1184cdf0e10cSrcweir 	if ( strSysPath )
1185cdf0e10cSrcweir 		rtl_uString_release( strSysPath );
1186cdf0e10cSrcweir 	if ( strSysDestPath )
1187cdf0e10cSrcweir 		rtl_uString_release( strSysDestPath );
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir 	return error;
1190cdf0e10cSrcweir }
1191