xref: /aoo4110/main/sal/osl/os2/file.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski 
25*b1cdbd2cSJim Jagielski /************************************************************************
26*b1cdbd2cSJim Jagielski  *   ToDo
27*b1cdbd2cSJim Jagielski  *
28*b1cdbd2cSJim Jagielski  *   Fix osl_getCanonicalName
29*b1cdbd2cSJim Jagielski  *
30*b1cdbd2cSJim Jagielski  *   - Fix: check for corresponding struct sizes in exported functions
31*b1cdbd2cSJim Jagielski  *   - check size/use of oslDirectory
32*b1cdbd2cSJim Jagielski  *   - check size/use of oslDirectoryItem
33*b1cdbd2cSJim Jagielski  *   - check size/use of oslFileStatus
34*b1cdbd2cSJim Jagielski  *   - check size/use of oslVolumeDeviceHandle
35*b1cdbd2cSJim Jagielski  *   - check size/use of oslVolumeInfo
36*b1cdbd2cSJim Jagielski  *   - check size/use of oslFileHandle
37*b1cdbd2cSJim Jagielski  ***********************************************************************/
38*b1cdbd2cSJim Jagielski 
39*b1cdbd2cSJim Jagielski #define INCL_DOSDEVIOCTL                        // OS2 device definitions
40*b1cdbd2cSJim Jagielski 
41*b1cdbd2cSJim Jagielski #include "system.h"
42*b1cdbd2cSJim Jagielski #include <rtl/alloc.h>
43*b1cdbd2cSJim Jagielski 
44*b1cdbd2cSJim Jagielski #include "osl/file.hxx"
45*b1cdbd2cSJim Jagielski 
46*b1cdbd2cSJim Jagielski 
47*b1cdbd2cSJim Jagielski #include <sal/types.h>
48*b1cdbd2cSJim Jagielski #include <osl/thread.h>
49*b1cdbd2cSJim Jagielski #include <osl/diagnose.h>
50*b1cdbd2cSJim Jagielski #include "file_error_transl.h"
51*b1cdbd2cSJim Jagielski #include <osl/time.h>
52*b1cdbd2cSJim Jagielski 
53*b1cdbd2cSJim Jagielski #ifndef _FILE_URL_H_
54*b1cdbd2cSJim Jagielski #include "file_url.h"
55*b1cdbd2cSJim Jagielski #endif
56*b1cdbd2cSJim Jagielski 
57*b1cdbd2cSJim Jagielski #include "file_path_helper.hxx"
58*b1cdbd2cSJim Jagielski #include "uunxapi.hxx"
59*b1cdbd2cSJim Jagielski 
60*b1cdbd2cSJim Jagielski #ifndef	_STRING_H_
61*b1cdbd2cSJim Jagielski #include <string.h>
62*b1cdbd2cSJim Jagielski #endif
63*b1cdbd2cSJim Jagielski 
64*b1cdbd2cSJim Jagielski #ifndef	_CTYPE_H_
65*b1cdbd2cSJim Jagielski #include <ctype.h>
66*b1cdbd2cSJim Jagielski #endif
67*b1cdbd2cSJim Jagielski 
68*b1cdbd2cSJim Jagielski #ifndef	_WCHAR_H_
69*b1cdbd2cSJim Jagielski #include <wchar.h>
70*b1cdbd2cSJim Jagielski #endif
71*b1cdbd2cSJim Jagielski 
72*b1cdbd2cSJim Jagielski #include <algorithm>
73*b1cdbd2cSJim Jagielski 
74*b1cdbd2cSJim Jagielski #include <limits>
75*b1cdbd2cSJim Jagielski #include <sys/mman.h>
76*b1cdbd2cSJim Jagielski 
77*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 1
78*b1cdbd2cSJim Jagielski 	extern void debug_ustring(rtl_uString*);
79*b1cdbd2cSJim Jagielski #endif
80*b1cdbd2cSJim Jagielski 
81*b1cdbd2cSJim Jagielski 
82*b1cdbd2cSJim Jagielski #ifdef DEBUG_OSL_FILE
83*b1cdbd2cSJim Jagielski #	define PERROR( a, b ) perror( a ); fprintf( stderr, b )
84*b1cdbd2cSJim Jagielski #else
85*b1cdbd2cSJim Jagielski #	define PERROR( a, b )
86*b1cdbd2cSJim Jagielski #endif
87*b1cdbd2cSJim Jagielski 
88*b1cdbd2cSJim Jagielski extern "C" oslFileHandle osl_createFileHandleFromFD( int fd );
89*b1cdbd2cSJim Jagielski 
90*b1cdbd2cSJim Jagielski     struct errentry errtable[] = {
91*b1cdbd2cSJim Jagielski         {  NO_ERROR,			 osl_File_E_None     },  /* 0 */
92*b1cdbd2cSJim Jagielski         {  ERROR_INVALID_FUNCTION,       osl_File_E_INVAL    },  /* 1 */
93*b1cdbd2cSJim Jagielski         {  ERROR_FILE_NOT_FOUND,         osl_File_E_NOENT    },  /* 2 */
94*b1cdbd2cSJim Jagielski         {  ERROR_PATH_NOT_FOUND,         osl_File_E_NOENT    },  /* 3 */
95*b1cdbd2cSJim Jagielski         {  ERROR_TOO_MANY_OPEN_FILES,    osl_File_E_MFILE    },  /* 4 */
96*b1cdbd2cSJim Jagielski         {  ERROR_ACCESS_DENIED,          osl_File_E_ACCES    },  /* 5 */
97*b1cdbd2cSJim Jagielski         {  ERROR_INVALID_HANDLE,         osl_File_E_BADF     },  /* 6 */
98*b1cdbd2cSJim Jagielski         {  ERROR_ARENA_TRASHED,          osl_File_E_NOMEM    },  /* 7 */
99*b1cdbd2cSJim Jagielski         {  ERROR_NOT_ENOUGH_MEMORY,      osl_File_E_NOMEM    },  /* 8 */
100*b1cdbd2cSJim Jagielski         {  ERROR_INVALID_BLOCK,          osl_File_E_NOMEM    },  /* 9 */
101*b1cdbd2cSJim Jagielski         {  ERROR_BAD_ENVIRONMENT,        osl_File_E_2BIG     },  /* 10 */
102*b1cdbd2cSJim Jagielski         {  ERROR_BAD_FORMAT,             osl_File_E_NOEXEC   },  /* 11 */
103*b1cdbd2cSJim Jagielski         {  ERROR_INVALID_ACCESS,         osl_File_E_INVAL    },  /* 12 */
104*b1cdbd2cSJim Jagielski         {  ERROR_INVALID_DATA,           osl_File_E_INVAL    },  /* 13 */
105*b1cdbd2cSJim Jagielski         {  ERROR_INVALID_DRIVE,          osl_File_E_NOENT    },  /* 15 */
106*b1cdbd2cSJim Jagielski         {  ERROR_CURRENT_DIRECTORY,      osl_File_E_ACCES    },  /* 16 */
107*b1cdbd2cSJim Jagielski         {  ERROR_NOT_SAME_DEVICE,        osl_File_E_XDEV     },  /* 17 */
108*b1cdbd2cSJim Jagielski         {  ERROR_NO_MORE_FILES,          osl_File_E_NOENT    },  /* 18 */
109*b1cdbd2cSJim Jagielski         {  ERROR_NOT_READY,              osl_File_E_NOTREADY },  /* 21 */
110*b1cdbd2cSJim Jagielski         {  ERROR_LOCK_VIOLATION,         osl_File_E_ACCES    },  /* 33 */
111*b1cdbd2cSJim Jagielski         {  ERROR_BAD_NETPATH,            osl_File_E_NOENT    },  /* 53 */
112*b1cdbd2cSJim Jagielski         {  ERROR_NETWORK_ACCESS_DENIED,  osl_File_E_ACCES    },  /* 65 */
113*b1cdbd2cSJim Jagielski         {  ERROR_BAD_NET_NAME,           osl_File_E_NOENT    },  /* 67 */
114*b1cdbd2cSJim Jagielski         {  ERROR_FILE_EXISTS,            osl_File_E_EXIST    },  /* 80 */
115*b1cdbd2cSJim Jagielski         {  ERROR_CANNOT_MAKE,            osl_File_E_ACCES    },  /* 82 */
116*b1cdbd2cSJim Jagielski         {  ERROR_FAIL_I24,               osl_File_E_ACCES    },  /* 83 */
117*b1cdbd2cSJim Jagielski         {  ERROR_INVALID_PARAMETER,      osl_File_E_INVAL    },  /* 87 */
118*b1cdbd2cSJim Jagielski         {  ERROR_NO_PROC_SLOTS,          osl_File_E_AGAIN    },  /* 89 */
119*b1cdbd2cSJim Jagielski         {  ERROR_DRIVE_LOCKED,           osl_File_E_ACCES    },  /* 108 */
120*b1cdbd2cSJim Jagielski         {  ERROR_BROKEN_PIPE,            osl_File_E_PIPE     },  /* 109 */
121*b1cdbd2cSJim Jagielski         {  ERROR_DISK_FULL,              osl_File_E_NOSPC    },  /* 112 */
122*b1cdbd2cSJim Jagielski         {  ERROR_INVALID_TARGET_HANDLE,  osl_File_E_BADF     },  /* 114 */
123*b1cdbd2cSJim Jagielski         {  ERROR_INVALID_HANDLE,         osl_File_E_INVAL    },  /* 124 */
124*b1cdbd2cSJim Jagielski         {  ERROR_WAIT_NO_CHILDREN,       osl_File_E_CHILD    },  /* 128 */
125*b1cdbd2cSJim Jagielski         {  ERROR_CHILD_NOT_COMPLETE,     osl_File_E_CHILD    },  /* 129 */
126*b1cdbd2cSJim Jagielski         {  ERROR_DIRECT_ACCESS_HANDLE,   osl_File_E_BADF     },  /* 130 */
127*b1cdbd2cSJim Jagielski         {  ERROR_NEGATIVE_SEEK,          osl_File_E_INVAL    },  /* 131 */
128*b1cdbd2cSJim Jagielski         {  ERROR_SEEK_ON_DEVICE,         osl_File_E_ACCES    },  /* 132 */
129*b1cdbd2cSJim Jagielski         {  ERROR_DIR_NOT_EMPTY,          osl_File_E_NOTEMPTY },  /* 145 */
130*b1cdbd2cSJim Jagielski         {  ERROR_NOT_LOCKED,             osl_File_E_ACCES    },  /* 158 */
131*b1cdbd2cSJim Jagielski         {  ERROR_BAD_PATHNAME,           osl_File_E_NOENT    },  /* 161 */
132*b1cdbd2cSJim Jagielski         {  ERROR_MAX_THRDS_REACHED,      osl_File_E_AGAIN    },  /* 164 */
133*b1cdbd2cSJim Jagielski         {  ERROR_LOCK_FAILED,            osl_File_E_ACCES    },  /* 167 */
134*b1cdbd2cSJim Jagielski         {  ERROR_ALREADY_EXISTS,         osl_File_E_EXIST    },  /* 183 */
135*b1cdbd2cSJim Jagielski         {  ERROR_FILENAME_EXCED_RANGE,   osl_File_E_NOENT    },  /* 206 */
136*b1cdbd2cSJim Jagielski         {  ERROR_NESTING_NOT_ALLOWED,    osl_File_E_AGAIN    },  /* 215 */
137*b1cdbd2cSJim Jagielski         {  ERROR_DIRECTORY,              osl_File_E_NOENT    },  /* 267 */
138*b1cdbd2cSJim Jagielski         //{  ERROR_NOT_ENOUGH_QUOTA,       osl_File_E_NOMEM    }    /* 1816 */
139*b1cdbd2cSJim Jagielski     };
140*b1cdbd2cSJim Jagielski 
141*b1cdbd2cSJim Jagielski     #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
142*b1cdbd2cSJim Jagielski 
143*b1cdbd2cSJim Jagielski     //#####################################################
MapError(APIRET dwError)144*b1cdbd2cSJim Jagielski     oslFileError MapError(APIRET dwError)
145*b1cdbd2cSJim Jagielski     {
146*b1cdbd2cSJim Jagielski         for (int i = 0; i < ELEMENTS_OF_ARRAY(errtable); ++i )
147*b1cdbd2cSJim Jagielski 	    {
148*b1cdbd2cSJim Jagielski 		    if (dwError == errtable[i].oscode)
149*b1cdbd2cSJim Jagielski 			    return static_cast<oslFileError>(errtable[i].errnocode);
150*b1cdbd2cSJim Jagielski         }
151*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
152*b1cdbd2cSJim Jagielski     }
153*b1cdbd2cSJim Jagielski 
154*b1cdbd2cSJim Jagielski #ifdef DEBUG_OSL_FILE
155*b1cdbd2cSJim Jagielski #   define OSL_FILE_TRACE 0 ? (void)(0) : osl_trace
156*b1cdbd2cSJim Jagielski #	define PERROR( a, b ) perror( a ); fprintf( stderr, b )
157*b1cdbd2cSJim Jagielski #else
158*b1cdbd2cSJim Jagielski #   define OSL_FILE_TRACE 1 ? (void)(0) : osl_trace
159*b1cdbd2cSJim Jagielski #	define PERROR( a, b )
160*b1cdbd2cSJim Jagielski #endif
161*b1cdbd2cSJim Jagielski 
162*b1cdbd2cSJim Jagielski //##################################################################
163*b1cdbd2cSJim Jagielski // File handle implementation
164*b1cdbd2cSJim Jagielski //##################################################################
165*b1cdbd2cSJim Jagielski struct FileHandle_Impl
166*b1cdbd2cSJim Jagielski {
167*b1cdbd2cSJim Jagielski     rtl_String * m_strFilePath; /* holds native file path */
168*b1cdbd2cSJim Jagielski     int          m_fd;
169*b1cdbd2cSJim Jagielski 
170*b1cdbd2cSJim Jagielski     /** State
171*b1cdbd2cSJim Jagielski      */
172*b1cdbd2cSJim Jagielski     enum StateBits
173*b1cdbd2cSJim Jagielski     {
174*b1cdbd2cSJim Jagielski         STATE_SEEKABLE  = 1, /* default */
175*b1cdbd2cSJim Jagielski         STATE_READABLE  = 2, /* default */
176*b1cdbd2cSJim Jagielski         STATE_WRITEABLE = 4, /* open() sets, write() requires, else osl_File_E_BADF */
177*b1cdbd2cSJim Jagielski         STATE_MODIFIED  = 8  /* write() sets, flush() resets  */
178*b1cdbd2cSJim Jagielski     };
179*b1cdbd2cSJim Jagielski     int          m_state;
180*b1cdbd2cSJim Jagielski 
181*b1cdbd2cSJim Jagielski 	sal_uInt64   m_size;    /* file size */
182*b1cdbd2cSJim Jagielski 	off_t     m_offset;  /* physical offset from begin of file */
183*b1cdbd2cSJim Jagielski 	//off_t     m_filepos; /* logical offset from begin of file */
184*b1cdbd2cSJim Jagielski     off_t        m_fileptr; /* logical offset from begin of file */
185*b1cdbd2cSJim Jagielski 
186*b1cdbd2cSJim Jagielski 	off_t     m_bufptr;  /* buffer offset from begin of file */
187*b1cdbd2cSJim Jagielski 	size_t       m_buflen;  /* buffer filled [0, m_bufsiz - 1] */
188*b1cdbd2cSJim Jagielski 
189*b1cdbd2cSJim Jagielski 	size_t       m_bufsiz;
190*b1cdbd2cSJim Jagielski 	sal_uInt8 *  m_buffer;
191*b1cdbd2cSJim Jagielski 
192*b1cdbd2cSJim Jagielski     explicit FileHandle_Impl (int fd, char const * path = "<anon>");
193*b1cdbd2cSJim Jagielski 	~FileHandle_Impl();
194*b1cdbd2cSJim Jagielski 
195*b1cdbd2cSJim Jagielski 	static void*  operator new(size_t n);
196*b1cdbd2cSJim Jagielski 	static void   operator delete(void * p, size_t);
197*b1cdbd2cSJim Jagielski 	static size_t getpagesize();
198*b1cdbd2cSJim Jagielski 
199*b1cdbd2cSJim Jagielski 	sal_uInt64    getPos() const;
200*b1cdbd2cSJim Jagielski 	oslFileError  setPos (sal_uInt64 uPos);
201*b1cdbd2cSJim Jagielski 
202*b1cdbd2cSJim Jagielski 	sal_uInt64    getSize() const;
203*b1cdbd2cSJim Jagielski 	oslFileError  setSize (sal_uInt64 uPos);
204*b1cdbd2cSJim Jagielski 
205*b1cdbd2cSJim Jagielski     oslFileError readAt (
206*b1cdbd2cSJim Jagielski         off_t        nOffset,
207*b1cdbd2cSJim Jagielski         void *       pBuffer,
208*b1cdbd2cSJim Jagielski         size_t       nBytesRequested,
209*b1cdbd2cSJim Jagielski         sal_uInt64 * pBytesRead);
210*b1cdbd2cSJim Jagielski 
211*b1cdbd2cSJim Jagielski     oslFileError writeAt (
212*b1cdbd2cSJim Jagielski         off_t        nOffset,
213*b1cdbd2cSJim Jagielski         void const * pBuffer,
214*b1cdbd2cSJim Jagielski         size_t       nBytesToWrite,
215*b1cdbd2cSJim Jagielski         sal_uInt64 * pBytesWritten);
216*b1cdbd2cSJim Jagielski 
217*b1cdbd2cSJim Jagielski 	oslFileError readFileAt (
218*b1cdbd2cSJim Jagielski 		off_t        nOffset,
219*b1cdbd2cSJim Jagielski 		void *       pBuffer,
220*b1cdbd2cSJim Jagielski 		size_t       nBytesRequested,
221*b1cdbd2cSJim Jagielski 		sal_uInt64 * pBytesRead);
222*b1cdbd2cSJim Jagielski 
223*b1cdbd2cSJim Jagielski 	oslFileError writeFileAt (
224*b1cdbd2cSJim Jagielski 		off_t        nOffset,
225*b1cdbd2cSJim Jagielski 		void const * pBuffer,
226*b1cdbd2cSJim Jagielski 		size_t       nBytesToWrite,
227*b1cdbd2cSJim Jagielski 		sal_uInt64 * pBytesWritten);
228*b1cdbd2cSJim Jagielski 
229*b1cdbd2cSJim Jagielski 	oslFileError readLineAt (
230*b1cdbd2cSJim Jagielski 		LONGLONG        nOffset,
231*b1cdbd2cSJim Jagielski 		sal_Sequence ** ppSequence,
232*b1cdbd2cSJim Jagielski 		sal_uInt64 *    pBytesRead);
233*b1cdbd2cSJim Jagielski 
234*b1cdbd2cSJim Jagielski 	oslFileError writeSequence_Impl (
235*b1cdbd2cSJim Jagielski 		sal_Sequence ** ppSequence,
236*b1cdbd2cSJim Jagielski 		size_t *        pnOffset,
237*b1cdbd2cSJim Jagielski 		const void *    pBuffer,
238*b1cdbd2cSJim Jagielski 		size_t          nBytes);
239*b1cdbd2cSJim Jagielski 
240*b1cdbd2cSJim Jagielski 	oslFileError syncFile();
241*b1cdbd2cSJim Jagielski 
242*b1cdbd2cSJim Jagielski 	/** Buffer cache / allocator.
243*b1cdbd2cSJim Jagielski 	 */
244*b1cdbd2cSJim Jagielski 	class Allocator
245*b1cdbd2cSJim Jagielski 	{
246*b1cdbd2cSJim Jagielski 		rtl_cache_type * m_cache;
247*b1cdbd2cSJim Jagielski 		size_t           m_bufsiz;
248*b1cdbd2cSJim Jagielski 
249*b1cdbd2cSJim Jagielski 		Allocator (Allocator const &);
250*b1cdbd2cSJim Jagielski 		Allocator & operator= (Allocator const &);
251*b1cdbd2cSJim Jagielski 
252*b1cdbd2cSJim Jagielski 	public:
253*b1cdbd2cSJim Jagielski 		static Allocator & get();
254*b1cdbd2cSJim Jagielski 
255*b1cdbd2cSJim Jagielski 		void allocate (sal_uInt8 ** ppBuffer, size_t * pnSize);
256*b1cdbd2cSJim Jagielski 		void deallocate (sal_uInt8 * pBuffer);
257*b1cdbd2cSJim Jagielski 
258*b1cdbd2cSJim Jagielski 	protected:
259*b1cdbd2cSJim Jagielski 		Allocator();
260*b1cdbd2cSJim Jagielski 		~Allocator();
261*b1cdbd2cSJim Jagielski 	};
262*b1cdbd2cSJim Jagielski };
263*b1cdbd2cSJim Jagielski 
264*b1cdbd2cSJim Jagielski FileHandle_Impl::Allocator &
get()265*b1cdbd2cSJim Jagielski FileHandle_Impl::Allocator::get()
266*b1cdbd2cSJim Jagielski {
267*b1cdbd2cSJim Jagielski 	static Allocator g_aBufferAllocator;
268*b1cdbd2cSJim Jagielski 	return g_aBufferAllocator;
269*b1cdbd2cSJim Jagielski }
270*b1cdbd2cSJim Jagielski 
Allocator()271*b1cdbd2cSJim Jagielski FileHandle_Impl::Allocator::Allocator()
272*b1cdbd2cSJim Jagielski 	: m_cache  (0),
273*b1cdbd2cSJim Jagielski 	  m_bufsiz (0)
274*b1cdbd2cSJim Jagielski {
275*b1cdbd2cSJim Jagielski 	size_t const pagesize = FileHandle_Impl::getpagesize();
276*b1cdbd2cSJim Jagielski 	m_cache = rtl_cache_create (
277*b1cdbd2cSJim Jagielski 		"osl_file_buffer_cache", pagesize, 0, 0, 0, 0, 0, 0, 0);
278*b1cdbd2cSJim Jagielski 	if (0 != m_cache)
279*b1cdbd2cSJim Jagielski 		m_bufsiz = pagesize;
280*b1cdbd2cSJim Jagielski }
281*b1cdbd2cSJim Jagielski 
~Allocator()282*b1cdbd2cSJim Jagielski FileHandle_Impl::Allocator::~Allocator()
283*b1cdbd2cSJim Jagielski {
284*b1cdbd2cSJim Jagielski 	rtl_cache_destroy(m_cache), m_cache = 0;
285*b1cdbd2cSJim Jagielski }
286*b1cdbd2cSJim Jagielski 
allocate(sal_uInt8 ** ppBuffer,size_t * pnSize)287*b1cdbd2cSJim Jagielski void FileHandle_Impl::Allocator::allocate (sal_uInt8 ** ppBuffer, size_t * pnSize)
288*b1cdbd2cSJim Jagielski {
289*b1cdbd2cSJim Jagielski 	OSL_PRECOND((0 != ppBuffer) && (0 != pnSize), "FileHandle_Impl::Allocator::allocate(): contract violation");
290*b1cdbd2cSJim Jagielski 	*ppBuffer = static_cast< sal_uInt8* >(rtl_cache_alloc(m_cache)), *pnSize = m_bufsiz;
291*b1cdbd2cSJim Jagielski }
292*b1cdbd2cSJim Jagielski 
deallocate(sal_uInt8 * pBuffer)293*b1cdbd2cSJim Jagielski void FileHandle_Impl::Allocator::deallocate (sal_uInt8 * pBuffer)
294*b1cdbd2cSJim Jagielski {
295*b1cdbd2cSJim Jagielski 	if (0 != pBuffer)
296*b1cdbd2cSJim Jagielski 		rtl_cache_free (m_cache, pBuffer);
297*b1cdbd2cSJim Jagielski }
298*b1cdbd2cSJim Jagielski 
FileHandle_Impl(int fd,char const * path)299*b1cdbd2cSJim Jagielski FileHandle_Impl::FileHandle_Impl (int fd, char const * path)
300*b1cdbd2cSJim Jagielski     : m_strFilePath (0),
301*b1cdbd2cSJim Jagielski       m_fd      (fd),
302*b1cdbd2cSJim Jagielski       m_state   (STATE_SEEKABLE | STATE_READABLE),
303*b1cdbd2cSJim Jagielski       m_size    (0),
304*b1cdbd2cSJim Jagielski 	  m_offset  (0),
305*b1cdbd2cSJim Jagielski       m_fileptr (0),
306*b1cdbd2cSJim Jagielski       m_bufptr  (-1),
307*b1cdbd2cSJim Jagielski       m_buflen  (0),
308*b1cdbd2cSJim Jagielski       m_bufsiz  (0),
309*b1cdbd2cSJim Jagielski       m_buffer  (0)
310*b1cdbd2cSJim Jagielski {
311*b1cdbd2cSJim Jagielski     rtl_string_newFromStr (&m_strFilePath, path);
312*b1cdbd2cSJim Jagielski 	Allocator::get().allocate (&m_buffer, &m_bufsiz);
313*b1cdbd2cSJim Jagielski 	if (m_buffer != 0)
314*b1cdbd2cSJim Jagielski 		memset (m_buffer, 0, m_bufsiz);
315*b1cdbd2cSJim Jagielski }
316*b1cdbd2cSJim Jagielski 
~FileHandle_Impl()317*b1cdbd2cSJim Jagielski FileHandle_Impl::~FileHandle_Impl()
318*b1cdbd2cSJim Jagielski {
319*b1cdbd2cSJim Jagielski 	Allocator::get().deallocate (m_buffer), m_buffer = 0;
320*b1cdbd2cSJim Jagielski     rtl_string_release (m_strFilePath), m_strFilePath = 0;
321*b1cdbd2cSJim Jagielski }
322*b1cdbd2cSJim Jagielski 
operator new(size_t n)323*b1cdbd2cSJim Jagielski void * FileHandle_Impl::operator new(size_t n)
324*b1cdbd2cSJim Jagielski {
325*b1cdbd2cSJim Jagielski 	return rtl_allocateMemory(n);
326*b1cdbd2cSJim Jagielski }
327*b1cdbd2cSJim Jagielski 
operator delete(void * p,size_t)328*b1cdbd2cSJim Jagielski void FileHandle_Impl::operator delete(void * p, size_t)
329*b1cdbd2cSJim Jagielski {
330*b1cdbd2cSJim Jagielski 	rtl_freeMemory(p);
331*b1cdbd2cSJim Jagielski }
332*b1cdbd2cSJim Jagielski 
getpagesize()333*b1cdbd2cSJim Jagielski size_t FileHandle_Impl::getpagesize()
334*b1cdbd2cSJim Jagielski {
335*b1cdbd2cSJim Jagielski 	ULONG ulPageSize;
336*b1cdbd2cSJim Jagielski 	DosQuerySysInfo(QSV_PAGE_SIZE, QSV_PAGE_SIZE, &ulPageSize, sizeof(ULONG));
337*b1cdbd2cSJim Jagielski 	return sal::static_int_cast< size_t >(ulPageSize);
338*b1cdbd2cSJim Jagielski }
339*b1cdbd2cSJim Jagielski 
getPos() const340*b1cdbd2cSJim Jagielski sal_uInt64 FileHandle_Impl::getPos() const
341*b1cdbd2cSJim Jagielski {
342*b1cdbd2cSJim Jagielski 	return sal::static_int_cast< sal_uInt64 >(m_fileptr);
343*b1cdbd2cSJim Jagielski }
344*b1cdbd2cSJim Jagielski 
setPos(sal_uInt64 uPos)345*b1cdbd2cSJim Jagielski oslFileError FileHandle_Impl::setPos (sal_uInt64 uPos)
346*b1cdbd2cSJim Jagielski {
347*b1cdbd2cSJim Jagielski 	m_fileptr = sal::static_int_cast< LONGLONG >(uPos);
348*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
349*b1cdbd2cSJim Jagielski }
350*b1cdbd2cSJim Jagielski 
getSize() const351*b1cdbd2cSJim Jagielski sal_uInt64 FileHandle_Impl::getSize() const
352*b1cdbd2cSJim Jagielski {
353*b1cdbd2cSJim Jagielski 	LONGLONG bufend = std::max((LONGLONG)(0), m_bufptr) + m_buflen;
354*b1cdbd2cSJim Jagielski 	return std::max(m_size, sal::static_int_cast< sal_uInt64 >(bufend));
355*b1cdbd2cSJim Jagielski }
356*b1cdbd2cSJim Jagielski 
setSize(sal_uInt64 uSize)357*b1cdbd2cSJim Jagielski oslFileError FileHandle_Impl::setSize (sal_uInt64 uSize)
358*b1cdbd2cSJim Jagielski {
359*b1cdbd2cSJim Jagielski 	off_t const nSize = sal::static_int_cast< off_t >(uSize);
360*b1cdbd2cSJim Jagielski 	if (-1 == ftruncate (m_fd, nSize))
361*b1cdbd2cSJim Jagielski 	{
362*b1cdbd2cSJim Jagielski 		/* Failure. Save original result. Try fallback algorithm */
363*b1cdbd2cSJim Jagielski 		oslFileError result = oslTranslateFileError (OSL_FET_ERROR, errno);
364*b1cdbd2cSJim Jagielski 
365*b1cdbd2cSJim Jagielski 		/* Check against current size. Fail upon 'shrink' */
366*b1cdbd2cSJim Jagielski 		if (uSize <= getSize())
367*b1cdbd2cSJim Jagielski 		{
368*b1cdbd2cSJim Jagielski 			/* Failure upon 'shrink'. Return original result */
369*b1cdbd2cSJim Jagielski 			return (result);
370*b1cdbd2cSJim Jagielski 		}
371*b1cdbd2cSJim Jagielski 
372*b1cdbd2cSJim Jagielski 		/* Save current position */
373*b1cdbd2cSJim Jagielski 		off_t const nCurPos = (off_t)lseek (m_fd, (off_t)0, SEEK_CUR);
374*b1cdbd2cSJim Jagielski 		if (nCurPos == (off_t)(-1))
375*b1cdbd2cSJim Jagielski 			return (result);
376*b1cdbd2cSJim Jagielski 
377*b1cdbd2cSJim Jagielski 		/* Try 'expand' via 'lseek()' and 'write()' */
378*b1cdbd2cSJim Jagielski 		if (-1 == lseek (m_fd, (off_t)(nSize - 1), SEEK_SET))
379*b1cdbd2cSJim Jagielski 			return (result);
380*b1cdbd2cSJim Jagielski 
381*b1cdbd2cSJim Jagielski 		if (-1 == write (m_fd, (char*)"", (size_t)1))
382*b1cdbd2cSJim Jagielski 		{
383*b1cdbd2cSJim Jagielski 			/* Failure. Restore saved position */
384*b1cdbd2cSJim Jagielski 			(void) lseek (m_fd, (off_t)(nCurPos), SEEK_SET);
385*b1cdbd2cSJim Jagielski 			return (result);
386*b1cdbd2cSJim Jagielski 		}
387*b1cdbd2cSJim Jagielski 
388*b1cdbd2cSJim Jagielski 		/* Success. Restore saved position */
389*b1cdbd2cSJim Jagielski 		if (-1 == lseek (m_fd, (off_t)nCurPos, SEEK_SET))
390*b1cdbd2cSJim Jagielski 			return (result);
391*b1cdbd2cSJim Jagielski 	}
392*b1cdbd2cSJim Jagielski 
393*b1cdbd2cSJim Jagielski 	OSL_FILE_TRACE("osl_setFileSize(%d, %lld) => %ld", m_fd, getSize(), nSize);
394*b1cdbd2cSJim Jagielski 	m_size = sal::static_int_cast< sal_uInt64 >(nSize);
395*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
396*b1cdbd2cSJim Jagielski }
397*b1cdbd2cSJim Jagielski 
readAt(off_t nOffset,void * pBuffer,size_t nBytesRequested,sal_uInt64 * pBytesRead)398*b1cdbd2cSJim Jagielski oslFileError FileHandle_Impl::readAt (
399*b1cdbd2cSJim Jagielski     off_t        nOffset,
400*b1cdbd2cSJim Jagielski     void *       pBuffer,
401*b1cdbd2cSJim Jagielski     size_t       nBytesRequested,
402*b1cdbd2cSJim Jagielski     sal_uInt64 * pBytesRead)
403*b1cdbd2cSJim Jagielski {
404*b1cdbd2cSJim Jagielski     OSL_PRECOND((m_state & STATE_SEEKABLE), "FileHandle_Impl::readAt(): not seekable");
405*b1cdbd2cSJim Jagielski     if (!(m_state & STATE_SEEKABLE))
406*b1cdbd2cSJim Jagielski         return osl_File_E_SPIPE;
407*b1cdbd2cSJim Jagielski 
408*b1cdbd2cSJim Jagielski     OSL_PRECOND((m_state & STATE_READABLE), "FileHandle_Impl::readAt(): not readable");
409*b1cdbd2cSJim Jagielski     if (!(m_state & STATE_READABLE))
410*b1cdbd2cSJim Jagielski         return osl_File_E_BADF;
411*b1cdbd2cSJim Jagielski 
412*b1cdbd2cSJim Jagielski     if (nOffset != m_offset)
413*b1cdbd2cSJim Jagielski 	{
414*b1cdbd2cSJim Jagielski 		if (-1 == ::lseek (m_fd, nOffset, SEEK_SET))
415*b1cdbd2cSJim Jagielski 			return oslTranslateFileError (OSL_FET_ERROR, errno);
416*b1cdbd2cSJim Jagielski 		m_offset = nOffset;
417*b1cdbd2cSJim Jagielski 	}
418*b1cdbd2cSJim Jagielski 
419*b1cdbd2cSJim Jagielski     ssize_t nBytes = ::read (m_fd, pBuffer, nBytesRequested);
420*b1cdbd2cSJim Jagielski     if (-1 == nBytes)
421*b1cdbd2cSJim Jagielski         return oslTranslateFileError (OSL_FET_ERROR, errno);
422*b1cdbd2cSJim Jagielski 	m_offset += nBytes;
423*b1cdbd2cSJim Jagielski 
424*b1cdbd2cSJim Jagielski     OSL_FILE_TRACE("FileHandle_Impl::readAt(%d, %lld, %ld)", m_fd, nOffset, nBytes);
425*b1cdbd2cSJim Jagielski     *pBytesRead = nBytes;
426*b1cdbd2cSJim Jagielski     return osl_File_E_None;
427*b1cdbd2cSJim Jagielski }
428*b1cdbd2cSJim Jagielski 
writeAt(off_t nOffset,void const * pBuffer,size_t nBytesToWrite,sal_uInt64 * pBytesWritten)429*b1cdbd2cSJim Jagielski oslFileError FileHandle_Impl::writeAt (
430*b1cdbd2cSJim Jagielski     off_t        nOffset,
431*b1cdbd2cSJim Jagielski     void const * pBuffer,
432*b1cdbd2cSJim Jagielski     size_t       nBytesToWrite,
433*b1cdbd2cSJim Jagielski     sal_uInt64 * pBytesWritten)
434*b1cdbd2cSJim Jagielski {
435*b1cdbd2cSJim Jagielski     OSL_PRECOND((m_state & STATE_SEEKABLE), "FileHandle_Impl::writeAt(): not seekable");
436*b1cdbd2cSJim Jagielski     if (!(m_state & STATE_SEEKABLE))
437*b1cdbd2cSJim Jagielski         return osl_File_E_SPIPE;
438*b1cdbd2cSJim Jagielski 
439*b1cdbd2cSJim Jagielski     OSL_PRECOND((m_state & STATE_WRITEABLE), "FileHandle_Impl::writeAt(): not writeable");
440*b1cdbd2cSJim Jagielski     if (!(m_state & STATE_WRITEABLE))
441*b1cdbd2cSJim Jagielski         return osl_File_E_BADF;
442*b1cdbd2cSJim Jagielski 
443*b1cdbd2cSJim Jagielski     if (nOffset != m_offset)
444*b1cdbd2cSJim Jagielski 	{
445*b1cdbd2cSJim Jagielski 		if (-1 == ::lseek (m_fd, nOffset, SEEK_SET))
446*b1cdbd2cSJim Jagielski 			return oslTranslateFileError (OSL_FET_ERROR, errno);
447*b1cdbd2cSJim Jagielski 		m_offset = nOffset;
448*b1cdbd2cSJim Jagielski 	}
449*b1cdbd2cSJim Jagielski 
450*b1cdbd2cSJim Jagielski     ssize_t nBytes = ::write (m_fd, pBuffer, nBytesToWrite);
451*b1cdbd2cSJim Jagielski     if (-1 == nBytes)
452*b1cdbd2cSJim Jagielski         return oslTranslateFileError (OSL_FET_ERROR, errno);
453*b1cdbd2cSJim Jagielski 	m_offset += nBytes;
454*b1cdbd2cSJim Jagielski 
455*b1cdbd2cSJim Jagielski     OSL_FILE_TRACE("FileHandle_Impl::writeAt(%d, %lld, %ld)", m_fd, nOffset, nBytes);
456*b1cdbd2cSJim Jagielski     m_size = std::max (m_size, sal::static_int_cast< sal_uInt64 >(nOffset + nBytes));
457*b1cdbd2cSJim Jagielski 
458*b1cdbd2cSJim Jagielski     *pBytesWritten = nBytes;
459*b1cdbd2cSJim Jagielski     return osl_File_E_None;
460*b1cdbd2cSJim Jagielski }
461*b1cdbd2cSJim Jagielski 
readFileAt(off_t nOffset,void * pBuffer,size_t nBytesRequested,sal_uInt64 * pBytesRead)462*b1cdbd2cSJim Jagielski oslFileError FileHandle_Impl::readFileAt (
463*b1cdbd2cSJim Jagielski     off_t        nOffset,
464*b1cdbd2cSJim Jagielski     void *       pBuffer,
465*b1cdbd2cSJim Jagielski     size_t       nBytesRequested,
466*b1cdbd2cSJim Jagielski     sal_uInt64 * pBytesRead)
467*b1cdbd2cSJim Jagielski {
468*b1cdbd2cSJim Jagielski     if (0 == (m_state & STATE_SEEKABLE))
469*b1cdbd2cSJim Jagielski     {
470*b1cdbd2cSJim Jagielski         // not seekable (pipe)
471*b1cdbd2cSJim Jagielski         ssize_t nBytes = ::read (m_fd, pBuffer, nBytesRequested);
472*b1cdbd2cSJim Jagielski         if (-1 == nBytes)
473*b1cdbd2cSJim Jagielski             return oslTranslateFileError (OSL_FET_ERROR, errno);
474*b1cdbd2cSJim Jagielski         *pBytesRead = nBytes;
475*b1cdbd2cSJim Jagielski         return osl_File_E_None;
476*b1cdbd2cSJim Jagielski     }
477*b1cdbd2cSJim Jagielski     else if (0 == m_buffer)
478*b1cdbd2cSJim Jagielski     {
479*b1cdbd2cSJim Jagielski         // not buffered
480*b1cdbd2cSJim Jagielski         return readAt (nOffset, pBuffer, nBytesRequested, pBytesRead);
481*b1cdbd2cSJim Jagielski     }
482*b1cdbd2cSJim Jagielski     else
483*b1cdbd2cSJim Jagielski     {
484*b1cdbd2cSJim Jagielski         sal_uInt8 * buffer = static_cast<sal_uInt8*>(pBuffer);
485*b1cdbd2cSJim Jagielski         for (*pBytesRead = 0; nBytesRequested > 0; )
486*b1cdbd2cSJim Jagielski         {
487*b1cdbd2cSJim Jagielski             off_t  const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
488*b1cdbd2cSJim Jagielski             size_t const bufpos = (nOffset % m_bufsiz);
489*b1cdbd2cSJim Jagielski 
490*b1cdbd2cSJim Jagielski             if (bufptr != m_bufptr)
491*b1cdbd2cSJim Jagielski             {
492*b1cdbd2cSJim Jagielski                 // flush current buffer
493*b1cdbd2cSJim Jagielski                 oslFileError result = syncFile();
494*b1cdbd2cSJim Jagielski                 if (result != osl_File_E_None)
495*b1cdbd2cSJim Jagielski                     return (result);
496*b1cdbd2cSJim Jagielski 
497*b1cdbd2cSJim Jagielski                 if (nBytesRequested >= m_bufsiz)
498*b1cdbd2cSJim Jagielski                 {
499*b1cdbd2cSJim Jagielski                     // buffer too small, read through from file
500*b1cdbd2cSJim Jagielski                     sal_uInt64 uDone = 0;
501*b1cdbd2cSJim Jagielski                     result = readAt (nOffset, &(buffer[*pBytesRead]), nBytesRequested, &uDone);
502*b1cdbd2cSJim Jagielski                     if (result != osl_File_E_None)
503*b1cdbd2cSJim Jagielski                         return (result);
504*b1cdbd2cSJim Jagielski 
505*b1cdbd2cSJim Jagielski                     nBytesRequested -= uDone, *pBytesRead += uDone;
506*b1cdbd2cSJim Jagielski                     return osl_File_E_None;
507*b1cdbd2cSJim Jagielski                 }
508*b1cdbd2cSJim Jagielski 
509*b1cdbd2cSJim Jagielski                 // update buffer (pointer)
510*b1cdbd2cSJim Jagielski                 sal_uInt64 uDone = 0;
511*b1cdbd2cSJim Jagielski                 result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
512*b1cdbd2cSJim Jagielski                 if (result != osl_File_E_None)
513*b1cdbd2cSJim Jagielski                     return (result);
514*b1cdbd2cSJim Jagielski                 m_bufptr = bufptr, m_buflen = uDone;
515*b1cdbd2cSJim Jagielski             }
516*b1cdbd2cSJim Jagielski             if (bufpos >= m_buflen)
517*b1cdbd2cSJim Jagielski             {
518*b1cdbd2cSJim Jagielski                 // end of file
519*b1cdbd2cSJim Jagielski                 return osl_File_E_None;
520*b1cdbd2cSJim Jagielski             }
521*b1cdbd2cSJim Jagielski 
522*b1cdbd2cSJim Jagielski             size_t const bytes = std::min (m_buflen - bufpos, nBytesRequested);
523*b1cdbd2cSJim Jagielski             OSL_FILE_TRACE("FileHandle_Impl::readFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes);
524*b1cdbd2cSJim Jagielski 
525*b1cdbd2cSJim Jagielski             memcpy (&(buffer[*pBytesRead]), &(m_buffer[bufpos]), bytes);
526*b1cdbd2cSJim Jagielski             nBytesRequested -= bytes, *pBytesRead += bytes, nOffset += bytes;
527*b1cdbd2cSJim Jagielski         }
528*b1cdbd2cSJim Jagielski         return osl_File_E_None;
529*b1cdbd2cSJim Jagielski     }
530*b1cdbd2cSJim Jagielski }
531*b1cdbd2cSJim Jagielski 
writeFileAt(off_t nOffset,void const * pBuffer,size_t nBytesToWrite,sal_uInt64 * pBytesWritten)532*b1cdbd2cSJim Jagielski oslFileError FileHandle_Impl::writeFileAt (
533*b1cdbd2cSJim Jagielski     off_t        nOffset,
534*b1cdbd2cSJim Jagielski     void const * pBuffer,
535*b1cdbd2cSJim Jagielski     size_t       nBytesToWrite,
536*b1cdbd2cSJim Jagielski     sal_uInt64 * pBytesWritten)
537*b1cdbd2cSJim Jagielski {
538*b1cdbd2cSJim Jagielski     if (0 == (m_state & STATE_SEEKABLE))
539*b1cdbd2cSJim Jagielski     {
540*b1cdbd2cSJim Jagielski         // not seekable (pipe)
541*b1cdbd2cSJim Jagielski         ssize_t nBytes = ::write (m_fd, pBuffer, nBytesToWrite);
542*b1cdbd2cSJim Jagielski         if (-1 == nBytes)
543*b1cdbd2cSJim Jagielski             return oslTranslateFileError (OSL_FET_ERROR, errno);
544*b1cdbd2cSJim Jagielski         *pBytesWritten = nBytes;
545*b1cdbd2cSJim Jagielski         return osl_File_E_None;
546*b1cdbd2cSJim Jagielski     }
547*b1cdbd2cSJim Jagielski     else if (0 == m_buffer)
548*b1cdbd2cSJim Jagielski     {
549*b1cdbd2cSJim Jagielski         // not buffered
550*b1cdbd2cSJim Jagielski         return writeAt (nOffset, pBuffer, nBytesToWrite, pBytesWritten);
551*b1cdbd2cSJim Jagielski     }
552*b1cdbd2cSJim Jagielski     else
553*b1cdbd2cSJim Jagielski     {
554*b1cdbd2cSJim Jagielski         sal_uInt8 const * buffer = static_cast<sal_uInt8 const *>(pBuffer);
555*b1cdbd2cSJim Jagielski         for (*pBytesWritten = 0; nBytesToWrite > 0; )
556*b1cdbd2cSJim Jagielski         {
557*b1cdbd2cSJim Jagielski             off_t  const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
558*b1cdbd2cSJim Jagielski             size_t const bufpos = (nOffset % m_bufsiz);
559*b1cdbd2cSJim Jagielski             if (bufptr != m_bufptr)
560*b1cdbd2cSJim Jagielski             {
561*b1cdbd2cSJim Jagielski                 // flush current buffer
562*b1cdbd2cSJim Jagielski                 oslFileError result = syncFile();
563*b1cdbd2cSJim Jagielski                 if (result != osl_File_E_None)
564*b1cdbd2cSJim Jagielski                     return (result);
565*b1cdbd2cSJim Jagielski 
566*b1cdbd2cSJim Jagielski                 if (nBytesToWrite >= m_bufsiz)
567*b1cdbd2cSJim Jagielski                 {
568*b1cdbd2cSJim Jagielski                     // buffer to small, write through to file
569*b1cdbd2cSJim Jagielski                     sal_uInt64 uDone = 0;
570*b1cdbd2cSJim Jagielski                     result = writeAt (nOffset, &(buffer[*pBytesWritten]), nBytesToWrite, &uDone);
571*b1cdbd2cSJim Jagielski                     if (result != osl_File_E_None)
572*b1cdbd2cSJim Jagielski                         return (result);
573*b1cdbd2cSJim Jagielski                     if (uDone != nBytesToWrite)
574*b1cdbd2cSJim Jagielski                         return osl_File_E_IO;
575*b1cdbd2cSJim Jagielski 
576*b1cdbd2cSJim Jagielski                     nBytesToWrite -= uDone, *pBytesWritten += uDone;
577*b1cdbd2cSJim Jagielski                     return osl_File_E_None;
578*b1cdbd2cSJim Jagielski                 }
579*b1cdbd2cSJim Jagielski 
580*b1cdbd2cSJim Jagielski                 // update buffer (pointer)
581*b1cdbd2cSJim Jagielski                 sal_uInt64 uDone = 0;
582*b1cdbd2cSJim Jagielski                 result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
583*b1cdbd2cSJim Jagielski                 if (result != osl_File_E_None)
584*b1cdbd2cSJim Jagielski                     return (result);
585*b1cdbd2cSJim Jagielski                 m_bufptr = bufptr, m_buflen = uDone;
586*b1cdbd2cSJim Jagielski             }
587*b1cdbd2cSJim Jagielski 
588*b1cdbd2cSJim Jagielski             size_t const bytes = std::min (m_bufsiz - bufpos, nBytesToWrite);
589*b1cdbd2cSJim Jagielski             OSL_FILE_TRACE("FileHandle_Impl::writeFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes);
590*b1cdbd2cSJim Jagielski 
591*b1cdbd2cSJim Jagielski             memcpy (&(m_buffer[bufpos]), &(buffer[*pBytesWritten]), bytes);
592*b1cdbd2cSJim Jagielski             nBytesToWrite -= bytes, *pBytesWritten += bytes, nOffset += bytes;
593*b1cdbd2cSJim Jagielski 
594*b1cdbd2cSJim Jagielski             m_buflen = std::max(m_buflen, bufpos + bytes);
595*b1cdbd2cSJim Jagielski             m_state |= STATE_MODIFIED;
596*b1cdbd2cSJim Jagielski         }
597*b1cdbd2cSJim Jagielski         return osl_File_E_None;
598*b1cdbd2cSJim Jagielski     }
599*b1cdbd2cSJim Jagielski }
600*b1cdbd2cSJim Jagielski 
readLineAt(LONGLONG nOffset,sal_Sequence ** ppSequence,sal_uInt64 * pBytesRead)601*b1cdbd2cSJim Jagielski oslFileError FileHandle_Impl::readLineAt (
602*b1cdbd2cSJim Jagielski     LONGLONG        nOffset,
603*b1cdbd2cSJim Jagielski     sal_Sequence ** ppSequence,
604*b1cdbd2cSJim Jagielski     sal_uInt64 *    pBytesRead)
605*b1cdbd2cSJim Jagielski {
606*b1cdbd2cSJim Jagielski     oslFileError result = osl_File_E_None;
607*b1cdbd2cSJim Jagielski 
608*b1cdbd2cSJim Jagielski     LONGLONG bufptr = (nOffset / m_bufsiz) * m_bufsiz;
609*b1cdbd2cSJim Jagielski     if (bufptr != m_bufptr)
610*b1cdbd2cSJim Jagielski     {
611*b1cdbd2cSJim Jagielski         /* flush current buffer */
612*b1cdbd2cSJim Jagielski         result = syncFile();
613*b1cdbd2cSJim Jagielski         if (result != osl_File_E_None)
614*b1cdbd2cSJim Jagielski             return (result);
615*b1cdbd2cSJim Jagielski 
616*b1cdbd2cSJim Jagielski         /* update buffer (pointer) */
617*b1cdbd2cSJim Jagielski         sal_uInt64 uDone = 0;
618*b1cdbd2cSJim Jagielski         result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
619*b1cdbd2cSJim Jagielski         if (result != osl_File_E_None)
620*b1cdbd2cSJim Jagielski             return (result);
621*b1cdbd2cSJim Jagielski 
622*b1cdbd2cSJim Jagielski         m_bufptr = bufptr, m_buflen = sal::static_int_cast< size_t >(uDone);
623*b1cdbd2cSJim Jagielski     }
624*b1cdbd2cSJim Jagielski 
625*b1cdbd2cSJim Jagielski     static int const LINE_STATE_BEGIN = 0;
626*b1cdbd2cSJim Jagielski     static int const LINE_STATE_CR    = 1;
627*b1cdbd2cSJim Jagielski     static int const LINE_STATE_LF    = 2;
628*b1cdbd2cSJim Jagielski 
629*b1cdbd2cSJim Jagielski     size_t bufpos = sal::static_int_cast< size_t >(nOffset - m_bufptr), curpos = bufpos, dstpos = 0;
630*b1cdbd2cSJim Jagielski     int    state  = (bufpos >= m_buflen) ? LINE_STATE_LF : LINE_STATE_BEGIN;
631*b1cdbd2cSJim Jagielski 
632*b1cdbd2cSJim Jagielski     for ( ; state != LINE_STATE_LF; )
633*b1cdbd2cSJim Jagielski     {
634*b1cdbd2cSJim Jagielski         if (curpos >= m_buflen)
635*b1cdbd2cSJim Jagielski         {
636*b1cdbd2cSJim Jagielski             /* buffer examined */
637*b1cdbd2cSJim Jagielski             if (0 < (curpos - bufpos))
638*b1cdbd2cSJim Jagielski             {
639*b1cdbd2cSJim Jagielski                 /* flush buffer to sequence */
640*b1cdbd2cSJim Jagielski                 result = writeSequence_Impl (
641*b1cdbd2cSJim Jagielski                     ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos);
642*b1cdbd2cSJim Jagielski                 if (result != osl_File_E_None)
643*b1cdbd2cSJim Jagielski                     return (result);
644*b1cdbd2cSJim Jagielski                 *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
645*b1cdbd2cSJim Jagielski             }
646*b1cdbd2cSJim Jagielski 
647*b1cdbd2cSJim Jagielski             bufptr = nOffset / m_bufsiz * m_bufsiz;
648*b1cdbd2cSJim Jagielski             if (bufptr != m_bufptr)
649*b1cdbd2cSJim Jagielski             {
650*b1cdbd2cSJim Jagielski                 /* update buffer (pointer) */
651*b1cdbd2cSJim Jagielski                 sal_uInt64 uDone = 0;
652*b1cdbd2cSJim Jagielski                 result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
653*b1cdbd2cSJim Jagielski                 if (result != osl_File_E_None)
654*b1cdbd2cSJim Jagielski                     return (result);
655*b1cdbd2cSJim Jagielski                 m_bufptr = bufptr, m_buflen = sal::static_int_cast< size_t >(uDone);
656*b1cdbd2cSJim Jagielski             }
657*b1cdbd2cSJim Jagielski 
658*b1cdbd2cSJim Jagielski             bufpos = sal::static_int_cast< size_t >(nOffset - m_bufptr), curpos = bufpos;
659*b1cdbd2cSJim Jagielski             if (bufpos >= m_buflen)
660*b1cdbd2cSJim Jagielski                 break;
661*b1cdbd2cSJim Jagielski         }
662*b1cdbd2cSJim Jagielski         switch (state)
663*b1cdbd2cSJim Jagielski         {
664*b1cdbd2cSJim Jagielski         case LINE_STATE_CR:
665*b1cdbd2cSJim Jagielski             state = LINE_STATE_LF;
666*b1cdbd2cSJim Jagielski             switch (m_buffer[curpos])
667*b1cdbd2cSJim Jagielski             {
668*b1cdbd2cSJim Jagielski             case 0x0A: /* CRLF */
669*b1cdbd2cSJim Jagielski                 /* eat current char */
670*b1cdbd2cSJim Jagielski                 curpos++;
671*b1cdbd2cSJim Jagielski                 break;
672*b1cdbd2cSJim Jagielski             default: /* single CR */
673*b1cdbd2cSJim Jagielski                 /* keep current char */
674*b1cdbd2cSJim Jagielski                 break;
675*b1cdbd2cSJim Jagielski             }
676*b1cdbd2cSJim Jagielski             break;
677*b1cdbd2cSJim Jagielski         default:
678*b1cdbd2cSJim Jagielski             /* determine next state */
679*b1cdbd2cSJim Jagielski             switch (m_buffer[curpos])
680*b1cdbd2cSJim Jagielski             {
681*b1cdbd2cSJim Jagielski             case 0x0A: /* single LF */
682*b1cdbd2cSJim Jagielski                 state = LINE_STATE_LF;
683*b1cdbd2cSJim Jagielski                 break;
684*b1cdbd2cSJim Jagielski             case 0x0D: /* CR */
685*b1cdbd2cSJim Jagielski                 state = LINE_STATE_CR;
686*b1cdbd2cSJim Jagielski                 break;
687*b1cdbd2cSJim Jagielski             default: /* advance to next char */
688*b1cdbd2cSJim Jagielski                 curpos++;
689*b1cdbd2cSJim Jagielski                 break;
690*b1cdbd2cSJim Jagielski             }
691*b1cdbd2cSJim Jagielski             if (state != LINE_STATE_BEGIN)
692*b1cdbd2cSJim Jagielski             {
693*b1cdbd2cSJim Jagielski                 /* store (and eat) the newline char */
694*b1cdbd2cSJim Jagielski                 m_buffer[curpos] = 0x0A, curpos++;
695*b1cdbd2cSJim Jagielski 
696*b1cdbd2cSJim Jagielski                 /* flush buffer to sequence */
697*b1cdbd2cSJim Jagielski                 result = writeSequence_Impl (
698*b1cdbd2cSJim Jagielski                     ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos - 1);
699*b1cdbd2cSJim Jagielski                 if (result != osl_File_E_None)
700*b1cdbd2cSJim Jagielski                     return (result);
701*b1cdbd2cSJim Jagielski                 *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
702*b1cdbd2cSJim Jagielski             }
703*b1cdbd2cSJim Jagielski             break;
704*b1cdbd2cSJim Jagielski         }
705*b1cdbd2cSJim Jagielski     }
706*b1cdbd2cSJim Jagielski 
707*b1cdbd2cSJim Jagielski     result = writeSequence_Impl (ppSequence, &dstpos, 0, 0);
708*b1cdbd2cSJim Jagielski     if (result != osl_File_E_None)
709*b1cdbd2cSJim Jagielski         return (result);
710*b1cdbd2cSJim Jagielski     if (0 < dstpos)
711*b1cdbd2cSJim Jagielski         return osl_File_E_None;
712*b1cdbd2cSJim Jagielski     if (bufpos >= m_buflen)
713*b1cdbd2cSJim Jagielski         return osl_File_E_AGAIN;
714*b1cdbd2cSJim Jagielski     return osl_File_E_None;
715*b1cdbd2cSJim Jagielski }
716*b1cdbd2cSJim Jagielski 
writeSequence_Impl(sal_Sequence ** ppSequence,size_t * pnOffset,const void * pBuffer,size_t nBytes)717*b1cdbd2cSJim Jagielski oslFileError FileHandle_Impl::writeSequence_Impl (
718*b1cdbd2cSJim Jagielski     sal_Sequence ** ppSequence,
719*b1cdbd2cSJim Jagielski     size_t *        pnOffset,
720*b1cdbd2cSJim Jagielski     const void *    pBuffer,
721*b1cdbd2cSJim Jagielski     size_t          nBytes)
722*b1cdbd2cSJim Jagielski {
723*b1cdbd2cSJim Jagielski     sal_Int32 nElements = *pnOffset + nBytes;
724*b1cdbd2cSJim Jagielski     if (!*ppSequence)
725*b1cdbd2cSJim Jagielski     {
726*b1cdbd2cSJim Jagielski         /* construct sequence */
727*b1cdbd2cSJim Jagielski         rtl_byte_sequence_constructNoDefault(ppSequence, nElements);
728*b1cdbd2cSJim Jagielski     }
729*b1cdbd2cSJim Jagielski     else if (nElements != (*ppSequence)->nElements)
730*b1cdbd2cSJim Jagielski     {
731*b1cdbd2cSJim Jagielski         /* resize sequence */
732*b1cdbd2cSJim Jagielski         rtl_byte_sequence_realloc(ppSequence, nElements);
733*b1cdbd2cSJim Jagielski     }
734*b1cdbd2cSJim Jagielski     if (*ppSequence != 0)
735*b1cdbd2cSJim Jagielski     {
736*b1cdbd2cSJim Jagielski         /* fill sequence */
737*b1cdbd2cSJim Jagielski         memcpy(&((*ppSequence)->elements[*pnOffset]), pBuffer, nBytes), *pnOffset += nBytes;
738*b1cdbd2cSJim Jagielski     }
739*b1cdbd2cSJim Jagielski     return (*ppSequence != 0) ? osl_File_E_None : osl_File_E_NOMEM;
740*b1cdbd2cSJim Jagielski }
741*b1cdbd2cSJim Jagielski 
syncFile()742*b1cdbd2cSJim Jagielski oslFileError FileHandle_Impl::syncFile()
743*b1cdbd2cSJim Jagielski {
744*b1cdbd2cSJim Jagielski 	oslFileError result = osl_File_E_None;
745*b1cdbd2cSJim Jagielski 	if (m_state & STATE_MODIFIED)
746*b1cdbd2cSJim Jagielski 	{
747*b1cdbd2cSJim Jagielski 		sal_uInt64 uDone = 0;
748*b1cdbd2cSJim Jagielski 		result = writeAt (m_bufptr, m_buffer, m_buflen, &uDone);
749*b1cdbd2cSJim Jagielski 		if (result != osl_File_E_None)
750*b1cdbd2cSJim Jagielski 			return (result);
751*b1cdbd2cSJim Jagielski 		if (uDone != m_buflen)
752*b1cdbd2cSJim Jagielski 			return osl_File_E_IO;
753*b1cdbd2cSJim Jagielski 		m_state &= ~STATE_MODIFIED;
754*b1cdbd2cSJim Jagielski 	}
755*b1cdbd2cSJim Jagielski 	return (result);
756*b1cdbd2cSJim Jagielski }
757*b1cdbd2cSJim Jagielski 
758*b1cdbd2cSJim Jagielski 
759*b1cdbd2cSJim Jagielski /******************************************************************************
760*b1cdbd2cSJim Jagielski  *
761*b1cdbd2cSJim Jagielski  *                  static members
762*b1cdbd2cSJim Jagielski  *
763*b1cdbd2cSJim Jagielski  *****************************************************************************/
764*b1cdbd2cSJim Jagielski 
765*b1cdbd2cSJim Jagielski static const char * pFileLockEnvVar = (char *) -1;
766*b1cdbd2cSJim Jagielski 
767*b1cdbd2cSJim Jagielski 
768*b1cdbd2cSJim Jagielski /******************************************************************************
769*b1cdbd2cSJim Jagielski  *
770*b1cdbd2cSJim Jagielski  *                  C-String Function Declarations
771*b1cdbd2cSJim Jagielski  *
772*b1cdbd2cSJim Jagielski  *****************************************************************************/
773*b1cdbd2cSJim Jagielski 
774*b1cdbd2cSJim Jagielski static oslFileError osl_psz_getVolumeInformation(const sal_Char* , oslVolumeInfo* pInfo, sal_uInt32 uFieldMask);
775*b1cdbd2cSJim Jagielski static oslFileError osl_psz_removeFile(const sal_Char* pszPath);
776*b1cdbd2cSJim Jagielski static oslFileError osl_psz_createDirectory(const sal_Char* pszPath);
777*b1cdbd2cSJim Jagielski static oslFileError osl_psz_removeDirectory(const sal_Char* pszPath);
778*b1cdbd2cSJim Jagielski static oslFileError osl_psz_copyFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
779*b1cdbd2cSJim Jagielski static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
780*b1cdbd2cSJim Jagielski static oslFileError osl_psz_setFileTime(const sal_Char* strFilePath, const TimeValue* pCreationTime, const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime);
781*b1cdbd2cSJim Jagielski 
782*b1cdbd2cSJim Jagielski 
783*b1cdbd2cSJim Jagielski /******************************************************************************
784*b1cdbd2cSJim Jagielski  *
785*b1cdbd2cSJim Jagielski  *                  Static Module Utility Function Declarations
786*b1cdbd2cSJim Jagielski  *
787*b1cdbd2cSJim Jagielski  *****************************************************************************/
788*b1cdbd2cSJim Jagielski 
789*b1cdbd2cSJim Jagielski static oslFileError  oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists);
790*b1cdbd2cSJim Jagielski static oslFileError  oslChangeFileModes(const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID);
791*b1cdbd2cSJim Jagielski static int           oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName);
792*b1cdbd2cSJim Jagielski static int           oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode);
793*b1cdbd2cSJim Jagielski static oslFileError  oslDoMoveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
794*b1cdbd2cSJim Jagielski rtl_uString*  oslMakeUStrFromPsz(const sal_Char* pszStr,rtl_uString** uStr);
795*b1cdbd2cSJim Jagielski 
796*b1cdbd2cSJim Jagielski /******************************************************************************
797*b1cdbd2cSJim Jagielski  *
798*b1cdbd2cSJim Jagielski  *                  Non-Static Utility Function Declarations
799*b1cdbd2cSJim Jagielski  *
800*b1cdbd2cSJim Jagielski  *****************************************************************************/
801*b1cdbd2cSJim Jagielski 
802*b1cdbd2cSJim Jagielski extern "C" int UnicodeToText( char *, size_t, const sal_Unicode *, sal_Int32 );
803*b1cdbd2cSJim Jagielski extern "C" int TextToUnicode(
804*b1cdbd2cSJim Jagielski     const char* text, size_t text_buffer_size,	sal_Unicode* unic_text, sal_Int32 unic_text_buffer_size);
805*b1cdbd2cSJim Jagielski 
806*b1cdbd2cSJim Jagielski /******************************************************************************
807*b1cdbd2cSJim Jagielski  *
808*b1cdbd2cSJim Jagielski  *                  'removeable device' aka floppy functions
809*b1cdbd2cSJim Jagielski  *
810*b1cdbd2cSJim Jagielski  *****************************************************************************/
811*b1cdbd2cSJim Jagielski 
812*b1cdbd2cSJim Jagielski static oslVolumeDeviceHandle  osl_isFloppyDrive(const sal_Char* pszPath);
813*b1cdbd2cSJim Jagielski static oslFileError   osl_mountFloppy(oslVolumeDeviceHandle hFloppy);
814*b1cdbd2cSJim Jagielski static oslFileError   osl_unmountFloppy(oslVolumeDeviceHandle hFloppy);
815*b1cdbd2cSJim Jagielski 
816*b1cdbd2cSJim Jagielski #ifdef DEBUG_OSL_FILE
817*b1cdbd2cSJim Jagielski static void           osl_printFloppyHandle(oslVolumeDeviceHandleImpl* hFloppy);
818*b1cdbd2cSJim Jagielski #endif
819*b1cdbd2cSJim Jagielski 
820*b1cdbd2cSJim Jagielski /**********************************************
821*b1cdbd2cSJim Jagielski  * _osl_openLocalRoot
822*b1cdbd2cSJim Jagielski  * enumerate available drives
823*b1cdbd2cSJim Jagielski  *********************************************/
_osl_openLocalRoot(rtl_uString * strDirectoryPath,oslDirectory * pDirectory)824*b1cdbd2cSJim Jagielski static oslFileError _osl_openLocalRoot( rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
825*b1cdbd2cSJim Jagielski {
826*b1cdbd2cSJim Jagielski 	rtl_uString		*ustrSystemPath = NULL;
827*b1cdbd2cSJim Jagielski 	oslFileError	error;
828*b1cdbd2cSJim Jagielski 
829*b1cdbd2cSJim Jagielski 	if ( !pDirectory )
830*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
831*b1cdbd2cSJim Jagielski 
832*b1cdbd2cSJim Jagielski 	*pDirectory = NULL;
833*b1cdbd2cSJim Jagielski 
834*b1cdbd2cSJim Jagielski 	error = osl_getSystemPathFromFileURL_Ex( strDirectoryPath, &ustrSystemPath, sal_False );
835*b1cdbd2cSJim Jagielski 
836*b1cdbd2cSJim Jagielski 	if ( osl_File_E_None == error )
837*b1cdbd2cSJim Jagielski 	{
838*b1cdbd2cSJim Jagielski 		/* create and initialize impl structure */
839*b1cdbd2cSJim Jagielski 		DirectoryImpl* pDirImpl = (DirectoryImpl*) rtl_allocateMemory( sizeof(DirectoryImpl) );
840*b1cdbd2cSJim Jagielski 		if( pDirImpl )
841*b1cdbd2cSJim Jagielski 		{
842*b1cdbd2cSJim Jagielski 			ULONG   ulDriveNum;
843*b1cdbd2cSJim Jagielski 			APIRET  rc;
844*b1cdbd2cSJim Jagielski 			pDirImpl->uType = DIRECTORYTYPE_LOCALROOT;
845*b1cdbd2cSJim Jagielski 			pDirImpl->ustrPath = ustrSystemPath;
846*b1cdbd2cSJim Jagielski 			rc = DosQueryCurrentDisk (&ulDriveNum, &pDirImpl->ulDriveMap);
847*b1cdbd2cSJim Jagielski 			pDirImpl->pDirStruct = 0;
848*b1cdbd2cSJim Jagielski 			pDirImpl->ulNextDrive = 1;
849*b1cdbd2cSJim Jagielski 			pDirImpl->ulNextDriveMask = 1;
850*b1cdbd2cSJim Jagielski 
851*b1cdbd2cSJim Jagielski 			// determine number of floppy-drives
852*b1cdbd2cSJim Jagielski 			BYTE nFloppies;
853*b1cdbd2cSJim Jagielski 			rc = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
854*b1cdbd2cSJim Jagielski 			if (nFloppies == 0) {
855*b1cdbd2cSJim Jagielski 				// if no floppies, start with 3rd drive (C:)
856*b1cdbd2cSJim Jagielski 				pDirImpl->ulNextDrive = 3;
857*b1cdbd2cSJim Jagielski 				pDirImpl->ulNextDriveMask <<= 2;
858*b1cdbd2cSJim Jagielski 			} else if (nFloppies == 1) {
859*b1cdbd2cSJim Jagielski 				// mask drive B (second bit) in this case
860*b1cdbd2cSJim Jagielski 				pDirImpl->ulDriveMap &= ~0x02;
861*b1cdbd2cSJim Jagielski 			}
862*b1cdbd2cSJim Jagielski 			*pDirectory = (oslDirectory) pDirImpl;
863*b1cdbd2cSJim Jagielski 			return osl_File_E_None;
864*b1cdbd2cSJim Jagielski 		}
865*b1cdbd2cSJim Jagielski 		else
866*b1cdbd2cSJim Jagielski 		{
867*b1cdbd2cSJim Jagielski 			errno = osl_File_E_NOMEM;
868*b1cdbd2cSJim Jagielski 		}
869*b1cdbd2cSJim Jagielski 
870*b1cdbd2cSJim Jagielski 	}
871*b1cdbd2cSJim Jagielski 
872*b1cdbd2cSJim Jagielski     rtl_uString_release( ustrSystemPath );
873*b1cdbd2cSJim Jagielski 	return error;
874*b1cdbd2cSJim Jagielski }
875*b1cdbd2cSJim Jagielski 
876*b1cdbd2cSJim Jagielski /**********************************************
877*b1cdbd2cSJim Jagielski  * _osl_getNextDrive
878*b1cdbd2cSJim Jagielski  *********************************************/
_osl_getNextDrive(oslDirectory Directory,oslDirectoryItem * pItem,sal_uInt32 uHint)879*b1cdbd2cSJim Jagielski static oslFileError SAL_CALL _osl_getNextDrive(
880*b1cdbd2cSJim Jagielski 	oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
881*b1cdbd2cSJim Jagielski {
882*b1cdbd2cSJim Jagielski 	DirectoryImpl	*pDirImpl = (DirectoryImpl *)Directory;
883*b1cdbd2cSJim Jagielski 	DirectoryItem_Impl	*pItemImpl = NULL;
884*b1cdbd2cSJim Jagielski     rtl_uString			* ustrDrive = NULL;
885*b1cdbd2cSJim Jagielski 	BOOL				fSuccess;
886*b1cdbd2cSJim Jagielski 	char				buffer[3];
887*b1cdbd2cSJim Jagielski 
888*b1cdbd2cSJim Jagielski 	uHint = uHint; /* avoid warnings */
889*b1cdbd2cSJim Jagielski 
890*b1cdbd2cSJim Jagielski 	if ( !pItem )
891*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
892*b1cdbd2cSJim Jagielski 
893*b1cdbd2cSJim Jagielski 	*pItem = NULL;
894*b1cdbd2cSJim Jagielski 
895*b1cdbd2cSJim Jagielski 	if ( !pDirImpl )
896*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
897*b1cdbd2cSJim Jagielski 
898*b1cdbd2cSJim Jagielski 	while( pDirImpl->ulNextDrive <= 26)
899*b1cdbd2cSJim Jagielski 	{
900*b1cdbd2cSJim Jagielski 		// exit if  bit==1 -> drive found
901*b1cdbd2cSJim Jagielski 		if (pDirImpl->ulDriveMap & pDirImpl->ulNextDriveMask) {
902*b1cdbd2cSJim Jagielski 
903*b1cdbd2cSJim Jagielski 			/* convert file name to unicode */
904*b1cdbd2cSJim Jagielski 			buffer[0] = '@' + pDirImpl->ulNextDrive;
905*b1cdbd2cSJim Jagielski 			buffer[1] = ':';
906*b1cdbd2cSJim Jagielski 			buffer[2] = 0;
907*b1cdbd2cSJim Jagielski 
908*b1cdbd2cSJim Jagielski 			pItemImpl = (DirectoryItem_Impl*) rtl_allocateMemory(sizeof(DirectoryItem_Impl));
909*b1cdbd2cSJim Jagielski 			if ( !pItemImpl )
910*b1cdbd2cSJim Jagielski 				return osl_File_E_NOMEM;
911*b1cdbd2cSJim Jagielski 
912*b1cdbd2cSJim Jagielski 			memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
913*b1cdbd2cSJim Jagielski 			pItemImpl->uType = DIRECTORYITEM_DRIVE;
914*b1cdbd2cSJim Jagielski 			pItemImpl->nRefCount = 1;
915*b1cdbd2cSJim Jagielski 
916*b1cdbd2cSJim Jagielski 			rtl_string2UString( &pItemImpl->ustrDrive, buffer, 3,
917*b1cdbd2cSJim Jagielski 				osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
918*b1cdbd2cSJim Jagielski 			OSL_ASSERT(pItemImpl->ustrDrive != 0);
919*b1cdbd2cSJim Jagielski 
920*b1cdbd2cSJim Jagielski 			/* use drive as directory item */
921*b1cdbd2cSJim Jagielski 			*pItem = (oslDirectoryItem) pItemImpl;
922*b1cdbd2cSJim Jagielski 		}
923*b1cdbd2cSJim Jagielski 		// scan next bit position
924*b1cdbd2cSJim Jagielski 		pDirImpl->ulNextDrive++;
925*b1cdbd2cSJim Jagielski 		pDirImpl->ulNextDriveMask <<= 1;
926*b1cdbd2cSJim Jagielski 
927*b1cdbd2cSJim Jagielski 		if (*pItem)	// item assigned, return now.
928*b1cdbd2cSJim Jagielski 			return osl_File_E_None;
929*b1cdbd2cSJim Jagielski 	}
930*b1cdbd2cSJim Jagielski 
931*b1cdbd2cSJim Jagielski 	// no more items
932*b1cdbd2cSJim Jagielski 	return osl_File_E_NOENT;
933*b1cdbd2cSJim Jagielski }
934*b1cdbd2cSJim Jagielski 
935*b1cdbd2cSJim Jagielski /**********************************************
936*b1cdbd2cSJim Jagielski  * _osl_readdir_impl_
937*b1cdbd2cSJim Jagielski  *
938*b1cdbd2cSJim Jagielski  * readdir wrapper, filters out "." and ".."
939*b1cdbd2cSJim Jagielski  * on request
940*b1cdbd2cSJim Jagielski  *********************************************/
941*b1cdbd2cSJim Jagielski 
_osl_readdir_impl_(DIR * pdir,sal_Bool bFilterLocalAndParentDir)942*b1cdbd2cSJim Jagielski static struct dirent* _osl_readdir_impl_(DIR* pdir, sal_Bool bFilterLocalAndParentDir)
943*b1cdbd2cSJim Jagielski {
944*b1cdbd2cSJim Jagielski 	struct dirent* pdirent;
945*b1cdbd2cSJim Jagielski 
946*b1cdbd2cSJim Jagielski 	while ((pdirent = readdir(pdir)) != NULL)
947*b1cdbd2cSJim Jagielski 	{
948*b1cdbd2cSJim Jagielski 		if (bFilterLocalAndParentDir &&
949*b1cdbd2cSJim Jagielski 			((0 == strcmp(pdirent->d_name, ".")) || (0 == strcmp(pdirent->d_name, ".."))))
950*b1cdbd2cSJim Jagielski 			continue;
951*b1cdbd2cSJim Jagielski 		else
952*b1cdbd2cSJim Jagielski 			break;
953*b1cdbd2cSJim Jagielski 	}
954*b1cdbd2cSJim Jagielski 
955*b1cdbd2cSJim Jagielski 	return pdirent;
956*b1cdbd2cSJim Jagielski }
957*b1cdbd2cSJim Jagielski 
958*b1cdbd2cSJim Jagielski /*******************************************************************
959*b1cdbd2cSJim Jagielski  *	osl_openDirectory
960*b1cdbd2cSJim Jagielski  ******************************************************************/
961*b1cdbd2cSJim Jagielski 
osl_openDirectory(rtl_uString * ustrDirectoryURL,oslDirectory * pDirectory)962*b1cdbd2cSJim Jagielski oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory)
963*b1cdbd2cSJim Jagielski {
964*b1cdbd2cSJim Jagielski     rtl_uString* ustrSystemPath = NULL;
965*b1cdbd2cSJim Jagielski     oslFileError eRet;
966*b1cdbd2cSJim Jagielski 
967*b1cdbd2cSJim Jagielski     char path[PATH_MAX];
968*b1cdbd2cSJim Jagielski 
969*b1cdbd2cSJim Jagielski     OSL_ASSERT(ustrDirectoryURL && (ustrDirectoryURL->length > 0));
970*b1cdbd2cSJim Jagielski     OSL_ASSERT(pDirectory);
971*b1cdbd2cSJim Jagielski 
972*b1cdbd2cSJim Jagielski     if (0 == ustrDirectoryURL->length )
973*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
974*b1cdbd2cSJim Jagielski 
975*b1cdbd2cSJim Jagielski 	if ( 0 == rtl_ustr_compareIgnoreAsciiCase( ustrDirectoryURL->buffer, (const sal_Unicode*)L"file:///" ) )
976*b1cdbd2cSJim Jagielski 		return _osl_openLocalRoot( ustrDirectoryURL, pDirectory );
977*b1cdbd2cSJim Jagielski 
978*b1cdbd2cSJim Jagielski     /* convert file URL to system path */
979*b1cdbd2cSJim Jagielski     eRet = osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL, &ustrSystemPath, sal_False);
980*b1cdbd2cSJim Jagielski 
981*b1cdbd2cSJim Jagielski 	if( osl_File_E_None != eRet )
982*b1cdbd2cSJim Jagielski         return eRet;
983*b1cdbd2cSJim Jagielski 
984*b1cdbd2cSJim Jagielski 	osl_systemPathRemoveSeparator(ustrSystemPath);
985*b1cdbd2cSJim Jagielski 
986*b1cdbd2cSJim Jagielski     /* convert unicode path to text */
987*b1cdbd2cSJim Jagielski     if ( UnicodeToText( path, PATH_MAX, ustrSystemPath->buffer, ustrSystemPath->length ) )
988*b1cdbd2cSJim Jagielski     {
989*b1cdbd2cSJim Jagielski 		// if only the drive is specified (x:), add a \ (x:\) otherwise current
990*b1cdbd2cSJim Jagielski 		// directory is browsed instead of root.
991*b1cdbd2cSJim Jagielski 		if (strlen( path) == 2 && path[1] == ':')
992*b1cdbd2cSJim Jagielski 			strcat( path, "\\");
993*b1cdbd2cSJim Jagielski         /* open directory */
994*b1cdbd2cSJim Jagielski         DIR *pdir = opendir( path );
995*b1cdbd2cSJim Jagielski 
996*b1cdbd2cSJim Jagielski         if( pdir )
997*b1cdbd2cSJim Jagielski         {
998*b1cdbd2cSJim Jagielski             /* create and initialize impl structure */
999*b1cdbd2cSJim Jagielski             DirectoryImpl* pDirImpl = (DirectoryImpl*) rtl_allocateMemory( sizeof(DirectoryImpl) );
1000*b1cdbd2cSJim Jagielski 
1001*b1cdbd2cSJim Jagielski             if( pDirImpl )
1002*b1cdbd2cSJim Jagielski             {
1003*b1cdbd2cSJim Jagielski 				pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM;
1004*b1cdbd2cSJim Jagielski                 pDirImpl->pDirStruct = pdir;
1005*b1cdbd2cSJim Jagielski                 pDirImpl->ustrPath = ustrSystemPath;
1006*b1cdbd2cSJim Jagielski 
1007*b1cdbd2cSJim Jagielski                 *pDirectory = (oslDirectory) pDirImpl;
1008*b1cdbd2cSJim Jagielski                 return osl_File_E_None;
1009*b1cdbd2cSJim Jagielski             }
1010*b1cdbd2cSJim Jagielski             else
1011*b1cdbd2cSJim Jagielski             {
1012*b1cdbd2cSJim Jagielski                 errno = ENOMEM;
1013*b1cdbd2cSJim Jagielski                 closedir( pdir );
1014*b1cdbd2cSJim Jagielski             }
1015*b1cdbd2cSJim Jagielski         }
1016*b1cdbd2cSJim Jagielski         else
1017*b1cdbd2cSJim Jagielski             /* should be removed by optimizer in product version */
1018*b1cdbd2cSJim Jagielski             PERROR( "osl_openDirectory", path );
1019*b1cdbd2cSJim Jagielski     }
1020*b1cdbd2cSJim Jagielski 
1021*b1cdbd2cSJim Jagielski     rtl_uString_release( ustrSystemPath );
1022*b1cdbd2cSJim Jagielski 
1023*b1cdbd2cSJim Jagielski     return oslTranslateFileError(OSL_FET_ERROR, errno);
1024*b1cdbd2cSJim Jagielski }
1025*b1cdbd2cSJim Jagielski 
1026*b1cdbd2cSJim Jagielski 
1027*b1cdbd2cSJim Jagielski /****************************************************************************
1028*b1cdbd2cSJim Jagielski  *	osl_getNextDirectoryItem
1029*b1cdbd2cSJim Jagielski  ***************************************************************************/
1030*b1cdbd2cSJim Jagielski 
osl_getNextDirectoryItem(oslDirectory Directory,oslDirectoryItem * pItem,sal_uInt32 uHint)1031*b1cdbd2cSJim Jagielski oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory Directory, oslDirectoryItem* pItem, sal_uInt32 uHint)
1032*b1cdbd2cSJim Jagielski {
1033*b1cdbd2cSJim Jagielski     DirectoryImpl* pDirImpl     = (DirectoryImpl*)Directory;
1034*b1cdbd2cSJim Jagielski 	DirectoryItem_Impl	*pItemImpl = NULL;
1035*b1cdbd2cSJim Jagielski     rtl_uString*      ustrFileName = NULL;
1036*b1cdbd2cSJim Jagielski     rtl_uString*      ustrFilePath = NULL;
1037*b1cdbd2cSJim Jagielski     struct dirent*    pEntry;
1038*b1cdbd2cSJim Jagielski 
1039*b1cdbd2cSJim Jagielski     OSL_ASSERT(Directory);
1040*b1cdbd2cSJim Jagielski     OSL_ASSERT(pItem);
1041*b1cdbd2cSJim Jagielski 
1042*b1cdbd2cSJim Jagielski     if ((NULL == Directory) || (NULL == pItem))
1043*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1044*b1cdbd2cSJim Jagielski 
1045*b1cdbd2cSJim Jagielski 	if ( pDirImpl->uType == DIRECTORYTYPE_LOCALROOT)
1046*b1cdbd2cSJim Jagielski 		return _osl_getNextDrive( Directory, pItem, uHint );
1047*b1cdbd2cSJim Jagielski 
1048*b1cdbd2cSJim Jagielski     pEntry = _osl_readdir_impl_(pDirImpl->pDirStruct, sal_True);
1049*b1cdbd2cSJim Jagielski 
1050*b1cdbd2cSJim Jagielski     if (NULL == pEntry)
1051*b1cdbd2cSJim Jagielski         return osl_File_E_NOENT;
1052*b1cdbd2cSJim Jagielski 
1053*b1cdbd2cSJim Jagielski 	pItemImpl = (DirectoryItem_Impl*) rtl_allocateMemory(sizeof(DirectoryItem_Impl));
1054*b1cdbd2cSJim Jagielski 	if ( !pItemImpl )
1055*b1cdbd2cSJim Jagielski 		return osl_File_E_NOMEM;
1056*b1cdbd2cSJim Jagielski 
1057*b1cdbd2cSJim Jagielski 	memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
1058*b1cdbd2cSJim Jagielski 	pItemImpl->uType = DIRECTORYITEM_FILE;
1059*b1cdbd2cSJim Jagielski 	pItemImpl->nRefCount = 1;
1060*b1cdbd2cSJim Jagielski 	pItemImpl->d_attr = pEntry->d_attr;
1061*b1cdbd2cSJim Jagielski 
1062*b1cdbd2cSJim Jagielski     /* convert file name to unicode */
1063*b1cdbd2cSJim Jagielski     rtl_string2UString( &ustrFileName, pEntry->d_name, strlen( pEntry->d_name ),
1064*b1cdbd2cSJim Jagielski         osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
1065*b1cdbd2cSJim Jagielski     OSL_ASSERT(ustrFileName != 0);
1066*b1cdbd2cSJim Jagielski 
1067*b1cdbd2cSJim Jagielski 	osl_systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName, &pItemImpl->ustrFilePath);
1068*b1cdbd2cSJim Jagielski     rtl_uString_release( ustrFileName );
1069*b1cdbd2cSJim Jagielski 
1070*b1cdbd2cSJim Jagielski 	*pItem = (oslDirectoryItem)pItemImpl;
1071*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
1072*b1cdbd2cSJim Jagielski }
1073*b1cdbd2cSJim Jagielski 
1074*b1cdbd2cSJim Jagielski /****************************************************************************/
1075*b1cdbd2cSJim Jagielski /*	osl_closeDirectory */
1076*b1cdbd2cSJim Jagielski /****************************************************************************/
1077*b1cdbd2cSJim Jagielski 
osl_closeDirectory(oslDirectory Directory)1078*b1cdbd2cSJim Jagielski oslFileError SAL_CALL osl_closeDirectory( oslDirectory Directory )
1079*b1cdbd2cSJim Jagielski {
1080*b1cdbd2cSJim Jagielski     DirectoryImpl* pDirImpl = (DirectoryImpl*) Directory;
1081*b1cdbd2cSJim Jagielski     oslFileError err = osl_File_E_None;
1082*b1cdbd2cSJim Jagielski 
1083*b1cdbd2cSJim Jagielski     OSL_ASSERT( Directory );
1084*b1cdbd2cSJim Jagielski 
1085*b1cdbd2cSJim Jagielski     if( NULL == pDirImpl )
1086*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1087*b1cdbd2cSJim Jagielski 
1088*b1cdbd2cSJim Jagielski 	switch ( pDirImpl->uType )
1089*b1cdbd2cSJim Jagielski 	{
1090*b1cdbd2cSJim Jagielski 	case DIRECTORYTYPE_FILESYSTEM:
1091*b1cdbd2cSJim Jagielski 		if( closedir( pDirImpl->pDirStruct ) )
1092*b1cdbd2cSJim Jagielski 			err = oslTranslateFileError(OSL_FET_ERROR, errno);
1093*b1cdbd2cSJim Jagielski 		break;
1094*b1cdbd2cSJim Jagielski 	case DIRECTORYTYPE_LOCALROOT:
1095*b1cdbd2cSJim Jagielski 		err = osl_File_E_None;
1096*b1cdbd2cSJim Jagielski 		break;
1097*b1cdbd2cSJim Jagielski #if 0
1098*b1cdbd2cSJim Jagielski 	case DIRECTORYTYPE_NETROOT:
1099*b1cdbd2cSJim Jagielski 		{
1100*b1cdbd2cSJim Jagielski 			DWORD err = WNetCloseEnum(pDirImpl->hDirectory);
1101*b1cdbd2cSJim Jagielski 			eError = (err == NO_ERROR) ? osl_File_E_None : MapError(err);
1102*b1cdbd2cSJim Jagielski 		}
1103*b1cdbd2cSJim Jagielski 		break;
1104*b1cdbd2cSJim Jagielski #endif
1105*b1cdbd2cSJim Jagielski 	default:
1106*b1cdbd2cSJim Jagielski 		OSL_ENSURE( 0, "Invalid directory type" );
1107*b1cdbd2cSJim Jagielski 		break;
1108*b1cdbd2cSJim Jagielski 	}
1109*b1cdbd2cSJim Jagielski 
1110*b1cdbd2cSJim Jagielski     /* cleanup members */
1111*b1cdbd2cSJim Jagielski     rtl_uString_release( pDirImpl->ustrPath );
1112*b1cdbd2cSJim Jagielski 
1113*b1cdbd2cSJim Jagielski     rtl_freeMemory( pDirImpl );
1114*b1cdbd2cSJim Jagielski 
1115*b1cdbd2cSJim Jagielski     return err;
1116*b1cdbd2cSJim Jagielski }
1117*b1cdbd2cSJim Jagielski 
1118*b1cdbd2cSJim Jagielski /****************************************************************************/
1119*b1cdbd2cSJim Jagielski /*	osl_getDirectoryItem */
1120*b1cdbd2cSJim Jagielski /****************************************************************************/
1121*b1cdbd2cSJim Jagielski 
osl_getDirectoryItem(rtl_uString * ustrFileURL,oslDirectoryItem * pItem)1122*b1cdbd2cSJim Jagielski oslFileError SAL_CALL osl_getDirectoryItem( rtl_uString* ustrFileURL, oslDirectoryItem* pItem )
1123*b1cdbd2cSJim Jagielski {
1124*b1cdbd2cSJim Jagielski     rtl_uString* 	strSysFilePath = NULL;
1125*b1cdbd2cSJim Jagielski     oslFileError 	error      = osl_File_E_INVAL;
1126*b1cdbd2cSJim Jagielski 	ULONG			dwPathType;
1127*b1cdbd2cSJim Jagielski 	PATHTYPE		type = PATHTYPE_FILE;
1128*b1cdbd2cSJim Jagielski 
1129*b1cdbd2cSJim Jagielski     OSL_ASSERT(ustrFileURL);
1130*b1cdbd2cSJim Jagielski     OSL_ASSERT(pItem);
1131*b1cdbd2cSJim Jagielski 
1132*b1cdbd2cSJim Jagielski 	/* Assume failure */
1133*b1cdbd2cSJim Jagielski 	if ( !pItem )
1134*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
1135*b1cdbd2cSJim Jagielski 	*pItem = NULL;
1136*b1cdbd2cSJim Jagielski 
1137*b1cdbd2cSJim Jagielski     if (0 == ustrFileURL->length || NULL == pItem)
1138*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1139*b1cdbd2cSJim Jagielski 
1140*b1cdbd2cSJim Jagielski     error = osl_getSystemPathFromFileURL_Ex(ustrFileURL, &strSysFilePath, sal_False);
1141*b1cdbd2cSJim Jagielski 
1142*b1cdbd2cSJim Jagielski     if (osl_File_E_None != error)
1143*b1cdbd2cSJim Jagielski         return error;
1144*b1cdbd2cSJim Jagielski 
1145*b1cdbd2cSJim Jagielski 	dwPathType = IsValidFilePath( strSysFilePath->buffer, NULL, VALIDATEPATH_NORMAL );
1146*b1cdbd2cSJim Jagielski 
1147*b1cdbd2cSJim Jagielski 	if ( dwPathType & PATHTYPE_IS_VOLUME )
1148*b1cdbd2cSJim Jagielski 		type = PATHTYPE_VOLUME;
1149*b1cdbd2cSJim Jagielski 	else if ( dwPathType & PATHTYPE_IS_SERVER )
1150*b1cdbd2cSJim Jagielski 		type = PATHTYPE_NETSERVER;
1151*b1cdbd2cSJim Jagielski 	else
1152*b1cdbd2cSJim Jagielski 		type = PATHTYPE_FILE;
1153*b1cdbd2cSJim Jagielski 
1154*b1cdbd2cSJim Jagielski 	switch ( type )
1155*b1cdbd2cSJim Jagielski 	{
1156*b1cdbd2cSJim Jagielski 	case PATHTYPE_NETSERVER:
1157*b1cdbd2cSJim Jagielski 		{
1158*b1cdbd2cSJim Jagielski 			DirectoryItem_Impl*	pItemImpl =
1159*b1cdbd2cSJim Jagielski 			    reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
1160*b1cdbd2cSJim Jagielski 
1161*b1cdbd2cSJim Jagielski 			if ( !pItemImpl )
1162*b1cdbd2cSJim Jagielski 				error = osl_File_E_NOMEM;
1163*b1cdbd2cSJim Jagielski 
1164*b1cdbd2cSJim Jagielski 			if ( osl_File_E_None == error )
1165*b1cdbd2cSJim Jagielski 			{
1166*b1cdbd2cSJim Jagielski 				memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
1167*b1cdbd2cSJim Jagielski 				pItemImpl->uType = DIRECTORYITEM_SERVER;
1168*b1cdbd2cSJim Jagielski 				pItemImpl->nRefCount = 1;
1169*b1cdbd2cSJim Jagielski 				rtl_uString_assign( &pItemImpl->ustrFilePath, strSysFilePath );
1170*b1cdbd2cSJim Jagielski 
1171*b1cdbd2cSJim Jagielski 				*pItem = pItemImpl;
1172*b1cdbd2cSJim Jagielski 			}
1173*b1cdbd2cSJim Jagielski 		}
1174*b1cdbd2cSJim Jagielski 		break;
1175*b1cdbd2cSJim Jagielski 	case PATHTYPE_VOLUME:
1176*b1cdbd2cSJim Jagielski 		{
1177*b1cdbd2cSJim Jagielski 			DirectoryItem_Impl*	pItemImpl =
1178*b1cdbd2cSJim Jagielski 			    reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
1179*b1cdbd2cSJim Jagielski 
1180*b1cdbd2cSJim Jagielski 			if ( !pItemImpl )
1181*b1cdbd2cSJim Jagielski 				error = osl_File_E_NOMEM;
1182*b1cdbd2cSJim Jagielski 
1183*b1cdbd2cSJim Jagielski 			if ( osl_File_E_None == error )
1184*b1cdbd2cSJim Jagielski 			{
1185*b1cdbd2cSJim Jagielski 				memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
1186*b1cdbd2cSJim Jagielski 				pItemImpl->uType = DIRECTORYITEM_DRIVE;
1187*b1cdbd2cSJim Jagielski 				pItemImpl->nRefCount = 1;
1188*b1cdbd2cSJim Jagielski 				rtl_uString_assign( &pItemImpl->ustrDrive, strSysFilePath );
1189*b1cdbd2cSJim Jagielski 
1190*b1cdbd2cSJim Jagielski 				if ( pItemImpl->ustrDrive->buffer[pItemImpl->ustrDrive->length-1] != sal_Unicode('\\') )
1191*b1cdbd2cSJim Jagielski 					rtl_uString_newConcat( &pItemImpl->ustrDrive,
1192*b1cdbd2cSJim Jagielski 											pItemImpl->ustrDrive, rtl::OUString::createFromAscii( "\\" ).pData);
1193*b1cdbd2cSJim Jagielski 
1194*b1cdbd2cSJim Jagielski 				*pItem = pItemImpl;
1195*b1cdbd2cSJim Jagielski 			}
1196*b1cdbd2cSJim Jagielski 		}
1197*b1cdbd2cSJim Jagielski 		break;
1198*b1cdbd2cSJim Jagielski 	default:
1199*b1cdbd2cSJim Jagielski 	case PATHTYPE_FILE:
1200*b1cdbd2cSJim Jagielski 		{
1201*b1cdbd2cSJim Jagielski 			if ( strSysFilePath->length > 0 && strSysFilePath->buffer[strSysFilePath->length - 1] == '\\' )
1202*b1cdbd2cSJim Jagielski 				rtl_uString_newFromStr_WithLength( &strSysFilePath, strSysFilePath->buffer, strSysFilePath->length - 1 );
1203*b1cdbd2cSJim Jagielski 
1204*b1cdbd2cSJim Jagielski 			if (0 == access_u(strSysFilePath, F_OK))
1205*b1cdbd2cSJim Jagielski 			{
1206*b1cdbd2cSJim Jagielski 				DirectoryItem_Impl	*pItemImpl =
1207*b1cdbd2cSJim Jagielski 				    reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
1208*b1cdbd2cSJim Jagielski 
1209*b1cdbd2cSJim Jagielski 				memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
1210*b1cdbd2cSJim Jagielski 				pItemImpl->uType = DIRECTORYITEM_FILE;
1211*b1cdbd2cSJim Jagielski 				pItemImpl->nRefCount = 1;
1212*b1cdbd2cSJim Jagielski 				rtl_uString_assign( &pItemImpl->ustrFilePath, strSysFilePath );
1213*b1cdbd2cSJim Jagielski 
1214*b1cdbd2cSJim Jagielski 				*pItem = pItemImpl;
1215*b1cdbd2cSJim Jagielski 			}
1216*b1cdbd2cSJim Jagielski 			else
1217*b1cdbd2cSJim Jagielski 				error = oslTranslateFileError(OSL_FET_ERROR, errno);
1218*b1cdbd2cSJim Jagielski 		}
1219*b1cdbd2cSJim Jagielski 		break;
1220*b1cdbd2cSJim Jagielski 	}
1221*b1cdbd2cSJim Jagielski 
1222*b1cdbd2cSJim Jagielski 	if ( strSysFilePath )
1223*b1cdbd2cSJim Jagielski 		rtl_uString_release( strSysFilePath );
1224*b1cdbd2cSJim Jagielski 
1225*b1cdbd2cSJim Jagielski 	return error;
1226*b1cdbd2cSJim Jagielski }
1227*b1cdbd2cSJim Jagielski 
1228*b1cdbd2cSJim Jagielski /****************************************************************************/
1229*b1cdbd2cSJim Jagielski /*	osl_acquireDirectoryItem */
1230*b1cdbd2cSJim Jagielski /****************************************************************************/
1231*b1cdbd2cSJim Jagielski 
osl_acquireDirectoryItem(oslDirectoryItem Item)1232*b1cdbd2cSJim Jagielski oslFileError osl_acquireDirectoryItem( oslDirectoryItem Item )
1233*b1cdbd2cSJim Jagielski {
1234*b1cdbd2cSJim Jagielski     OSL_ASSERT( Item );
1235*b1cdbd2cSJim Jagielski 	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
1236*b1cdbd2cSJim Jagielski 
1237*b1cdbd2cSJim Jagielski 	if ( !pItemImpl )
1238*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
1239*b1cdbd2cSJim Jagielski 
1240*b1cdbd2cSJim Jagielski 	pItemImpl->nRefCount++;
1241*b1cdbd2cSJim Jagielski     return osl_File_E_None;
1242*b1cdbd2cSJim Jagielski }
1243*b1cdbd2cSJim Jagielski 
1244*b1cdbd2cSJim Jagielski /****************************************************************************/
1245*b1cdbd2cSJim Jagielski /*	osl_releaseDirectoryItem */
1246*b1cdbd2cSJim Jagielski /****************************************************************************/
1247*b1cdbd2cSJim Jagielski 
osl_releaseDirectoryItem(oslDirectoryItem Item)1248*b1cdbd2cSJim Jagielski oslFileError osl_releaseDirectoryItem( oslDirectoryItem Item )
1249*b1cdbd2cSJim Jagielski {
1250*b1cdbd2cSJim Jagielski     OSL_ASSERT( Item );
1251*b1cdbd2cSJim Jagielski 	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
1252*b1cdbd2cSJim Jagielski 
1253*b1cdbd2cSJim Jagielski 	if ( !pItemImpl )
1254*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
1255*b1cdbd2cSJim Jagielski 
1256*b1cdbd2cSJim Jagielski 	if ( ! --pItemImpl->nRefCount )
1257*b1cdbd2cSJim Jagielski 	{
1258*b1cdbd2cSJim Jagielski 		if (pItemImpl->ustrFilePath)
1259*b1cdbd2cSJim Jagielski 			rtl_uString_release( pItemImpl->ustrFilePath );
1260*b1cdbd2cSJim Jagielski 		if (pItemImpl->ustrDrive)
1261*b1cdbd2cSJim Jagielski 			rtl_uString_release( pItemImpl->ustrDrive );
1262*b1cdbd2cSJim Jagielski 		rtl_freeMemory( pItemImpl );
1263*b1cdbd2cSJim Jagielski 	}
1264*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
1265*b1cdbd2cSJim Jagielski }
1266*b1cdbd2cSJim Jagielski 
1267*b1cdbd2cSJim Jagielski /****************************************************************************
1268*b1cdbd2cSJim Jagielski  *	osl_createFileHandleFromFD
1269*b1cdbd2cSJim Jagielski  ***************************************************************************/
osl_createFileHandleFromFD(int fd)1270*b1cdbd2cSJim Jagielski extern "C" oslFileHandle osl_createFileHandleFromFD( int fd )
1271*b1cdbd2cSJim Jagielski {
1272*b1cdbd2cSJim Jagielski     if (-1 == fd)
1273*b1cdbd2cSJim Jagielski         return 0; // EINVAL
1274*b1cdbd2cSJim Jagielski 
1275*b1cdbd2cSJim Jagielski     struct stat aFileStat;
1276*b1cdbd2cSJim Jagielski     if (-1 == fstat (fd, &aFileStat))
1277*b1cdbd2cSJim Jagielski         return 0; // EBADF
1278*b1cdbd2cSJim Jagielski 
1279*b1cdbd2cSJim Jagielski 	FileHandle_Impl * pImpl = new FileHandle_Impl (fd);
1280*b1cdbd2cSJim Jagielski     if (0 == pImpl)
1281*b1cdbd2cSJim Jagielski         return 0; // ENOMEM
1282*b1cdbd2cSJim Jagielski 
1283*b1cdbd2cSJim Jagielski     // assume writeable
1284*b1cdbd2cSJim Jagielski     pImpl->m_state |= FileHandle_Impl::STATE_WRITEABLE;
1285*b1cdbd2cSJim Jagielski     if (!S_ISREG(aFileStat.st_mode))
1286*b1cdbd2cSJim Jagielski     {
1287*b1cdbd2cSJim Jagielski         /* not a regular file, mark not seekable */
1288*b1cdbd2cSJim Jagielski         pImpl->m_state &= ~FileHandle_Impl::STATE_SEEKABLE;
1289*b1cdbd2cSJim Jagielski     }
1290*b1cdbd2cSJim Jagielski     else
1291*b1cdbd2cSJim Jagielski     {
1292*b1cdbd2cSJim Jagielski         /* regular file, init current size */
1293*b1cdbd2cSJim Jagielski         pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size);
1294*b1cdbd2cSJim Jagielski     }
1295*b1cdbd2cSJim Jagielski 
1296*b1cdbd2cSJim Jagielski     OSL_FILE_TRACE("osl_createFileHandleFromFD(%d, writeable) => %s",
1297*b1cdbd2cSJim Jagielski                    pImpl->m_fd, rtl_string_getStr(pImpl->m_strFilePath));
1298*b1cdbd2cSJim Jagielski 	return (oslFileHandle)(pImpl);
1299*b1cdbd2cSJim Jagielski }
1300*b1cdbd2cSJim Jagielski 
1301*b1cdbd2cSJim Jagielski /*******************************************************************
1302*b1cdbd2cSJim Jagielski  * osl_file_adjustLockFlags
1303*b1cdbd2cSJim Jagielski  ******************************************************************/
osl_file_adjustLockFlags(const char * path,int flags)1304*b1cdbd2cSJim Jagielski static int osl_file_adjustLockFlags (const char * path, int flags)
1305*b1cdbd2cSJim Jagielski {
1306*b1cdbd2cSJim Jagielski #ifdef MACOSX
1307*b1cdbd2cSJim Jagielski     /*
1308*b1cdbd2cSJim Jagielski      * The AFP implementation of MacOS X 10.4 treats O_EXLOCK in a way
1309*b1cdbd2cSJim Jagielski      * that makes it impossible for OOo to create a backup copy of the
1310*b1cdbd2cSJim Jagielski      * file it keeps opened. OTOH O_SHLOCK for AFP behaves as desired by
1311*b1cdbd2cSJim Jagielski      * the OOo file handling, so we need to check the path of the file
1312*b1cdbd2cSJim Jagielski      * for the filesystem name.
1313*b1cdbd2cSJim Jagielski      */
1314*b1cdbd2cSJim Jagielski     struct statfs s;
1315*b1cdbd2cSJim Jagielski     if( 0 <= statfs( path, &s ) )
1316*b1cdbd2cSJim Jagielski     {
1317*b1cdbd2cSJim Jagielski         if( 0 == strncmp("afpfs", s.f_fstypename, 5) )
1318*b1cdbd2cSJim Jagielski         {
1319*b1cdbd2cSJim Jagielski             flags &= ~O_EXLOCK;
1320*b1cdbd2cSJim Jagielski             flags |=  O_SHLOCK;
1321*b1cdbd2cSJim Jagielski         }
1322*b1cdbd2cSJim Jagielski         else
1323*b1cdbd2cSJim Jagielski         {
1324*b1cdbd2cSJim Jagielski             /* Needed flags to allow opening a webdav file */
1325*b1cdbd2cSJim Jagielski             flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK);
1326*b1cdbd2cSJim Jagielski 		}
1327*b1cdbd2cSJim Jagielski     }
1328*b1cdbd2cSJim Jagielski #endif /* MACOSX */
1329*b1cdbd2cSJim Jagielski 
1330*b1cdbd2cSJim Jagielski     (void) path;
1331*b1cdbd2cSJim Jagielski     return flags;
1332*b1cdbd2cSJim Jagielski }
1333*b1cdbd2cSJim Jagielski 
1334*b1cdbd2cSJim Jagielski /****************************************************************************
1335*b1cdbd2cSJim Jagielski  *	osl_file_queryLocking
1336*b1cdbd2cSJim Jagielski  ***************************************************************************/
1337*b1cdbd2cSJim Jagielski struct Locking_Impl
1338*b1cdbd2cSJim Jagielski {
1339*b1cdbd2cSJim Jagielski     int m_enabled;
Locking_ImplLocking_Impl1340*b1cdbd2cSJim Jagielski     Locking_Impl() : m_enabled(0)
1341*b1cdbd2cSJim Jagielski     {
1342*b1cdbd2cSJim Jagielski #ifndef HAVE_O_EXLOCK
1343*b1cdbd2cSJim Jagielski         m_enabled = ((getenv("SAL_ENABLE_FILE_LOCKING") != 0) || (getenv("STAR_ENABLE_FILE_LOCKING") != 0));
1344*b1cdbd2cSJim Jagielski #endif /* HAVE_O_EXLOCK */
1345*b1cdbd2cSJim Jagielski     }
1346*b1cdbd2cSJim Jagielski };
osl_file_queryLocking(sal_uInt32 uFlags)1347*b1cdbd2cSJim Jagielski static int osl_file_queryLocking (sal_uInt32 uFlags)
1348*b1cdbd2cSJim Jagielski {
1349*b1cdbd2cSJim Jagielski     if (!(uFlags & osl_File_OpenFlag_NoLock))
1350*b1cdbd2cSJim Jagielski     {
1351*b1cdbd2cSJim Jagielski         if ((uFlags & osl_File_OpenFlag_Write) || (uFlags & osl_File_OpenFlag_Create))
1352*b1cdbd2cSJim Jagielski         {
1353*b1cdbd2cSJim Jagielski             static Locking_Impl g_locking;
1354*b1cdbd2cSJim Jagielski             return (g_locking.m_enabled != 0);
1355*b1cdbd2cSJim Jagielski         }
1356*b1cdbd2cSJim Jagielski     }
1357*b1cdbd2cSJim Jagielski     return 0;
1358*b1cdbd2cSJim Jagielski }
1359*b1cdbd2cSJim Jagielski 
1360*b1cdbd2cSJim Jagielski /****************************************************************************
1361*b1cdbd2cSJim Jagielski  *	osl_openFile
1362*b1cdbd2cSJim Jagielski  ***************************************************************************/
1363*b1cdbd2cSJim Jagielski #ifdef HAVE_O_EXLOCK
1364*b1cdbd2cSJim Jagielski #define OPEN_WRITE_FLAGS ( O_RDWR | O_EXLOCK | O_NONBLOCK )
1365*b1cdbd2cSJim Jagielski #define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR | O_EXLOCK | O_NONBLOCK )
1366*b1cdbd2cSJim Jagielski #else
1367*b1cdbd2cSJim Jagielski #define OPEN_WRITE_FLAGS ( O_RDWR )
1368*b1cdbd2cSJim Jagielski #define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR )
1369*b1cdbd2cSJim Jagielski #endif
1370*b1cdbd2cSJim Jagielski 
1371*b1cdbd2cSJim Jagielski oslFileError
osl_openFile(rtl_uString * ustrFileURL,oslFileHandle * pHandle,sal_uInt32 uFlags)1372*b1cdbd2cSJim Jagielski SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
1373*b1cdbd2cSJim Jagielski {
1374*b1cdbd2cSJim Jagielski     oslFileError eRet;
1375*b1cdbd2cSJim Jagielski 
1376*b1cdbd2cSJim Jagielski     if ((ustrFileURL == 0) || (ustrFileURL->length == 0) || (pHandle == 0))
1377*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1378*b1cdbd2cSJim Jagielski 
1379*b1cdbd2cSJim Jagielski     /* convert file URL to system path */
1380*b1cdbd2cSJim Jagielski     char buffer[PATH_MAX];
1381*b1cdbd2cSJim Jagielski     eRet = FileURLToPath (buffer, sizeof(buffer), ustrFileURL);
1382*b1cdbd2cSJim Jagielski     if (eRet != osl_File_E_None)
1383*b1cdbd2cSJim Jagielski         return eRet;
1384*b1cdbd2cSJim Jagielski #ifdef MACOSX
1385*b1cdbd2cSJim Jagielski     if (macxp_resolveAlias (buffer, sizeof(buffer)) != 0)
1386*b1cdbd2cSJim Jagielski         return oslTranslateFileError (OSL_FET_ERROR, errno);
1387*b1cdbd2cSJim Jagielski #endif /* MACOSX */
1388*b1cdbd2cSJim Jagielski 
1389*b1cdbd2cSJim Jagielski     /* set mode and flags */
1390*b1cdbd2cSJim Jagielski     int mode  = S_IRUSR | S_IRGRP | S_IROTH;
1391*b1cdbd2cSJim Jagielski     int flags = O_RDONLY;
1392*b1cdbd2cSJim Jagielski     if (uFlags & osl_File_OpenFlag_Write)
1393*b1cdbd2cSJim Jagielski     {
1394*b1cdbd2cSJim Jagielski         mode |= S_IWUSR | S_IWGRP | S_IWOTH;
1395*b1cdbd2cSJim Jagielski         flags = OPEN_WRITE_FLAGS;
1396*b1cdbd2cSJim Jagielski     }
1397*b1cdbd2cSJim Jagielski     if (uFlags & osl_File_OpenFlag_Create)
1398*b1cdbd2cSJim Jagielski     {
1399*b1cdbd2cSJim Jagielski         mode |= S_IWUSR | S_IWGRP | S_IWOTH;
1400*b1cdbd2cSJim Jagielski         flags = OPEN_CREATE_FLAGS;
1401*b1cdbd2cSJim Jagielski     }
1402*b1cdbd2cSJim Jagielski     if (uFlags & osl_File_OpenFlag_NoLock)
1403*b1cdbd2cSJim Jagielski     {
1404*b1cdbd2cSJim Jagielski #ifdef HAVE_O_EXLOCK
1405*b1cdbd2cSJim Jagielski         flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK);
1406*b1cdbd2cSJim Jagielski #endif /* HAVE_O_EXLOCK */
1407*b1cdbd2cSJim Jagielski     }
1408*b1cdbd2cSJim Jagielski     else
1409*b1cdbd2cSJim Jagielski     {
1410*b1cdbd2cSJim Jagielski         flags = osl_file_adjustLockFlags (buffer, flags);
1411*b1cdbd2cSJim Jagielski     }
1412*b1cdbd2cSJim Jagielski 
1413*b1cdbd2cSJim Jagielski     /* open the file */
1414*b1cdbd2cSJim Jagielski     int fd = open( buffer, flags | O_BINARY, mode );
1415*b1cdbd2cSJim Jagielski     if (-1 == fd)
1416*b1cdbd2cSJim Jagielski         return oslTranslateFileError (OSL_FET_ERROR, errno);
1417*b1cdbd2cSJim Jagielski 
1418*b1cdbd2cSJim Jagielski     /* reset O_NONBLOCK flag */
1419*b1cdbd2cSJim Jagielski     if (flags & O_NONBLOCK)
1420*b1cdbd2cSJim Jagielski     {
1421*b1cdbd2cSJim Jagielski         int f = fcntl (fd, F_GETFL, 0);
1422*b1cdbd2cSJim Jagielski         if (-1 == f)
1423*b1cdbd2cSJim Jagielski         {
1424*b1cdbd2cSJim Jagielski             eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1425*b1cdbd2cSJim Jagielski             (void) close(fd);
1426*b1cdbd2cSJim Jagielski             return eRet;
1427*b1cdbd2cSJim Jagielski         }
1428*b1cdbd2cSJim Jagielski         if (-1 == fcntl (fd, F_SETFL, (f & ~O_NONBLOCK)))
1429*b1cdbd2cSJim Jagielski         {
1430*b1cdbd2cSJim Jagielski             eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1431*b1cdbd2cSJim Jagielski             (void) close(fd);
1432*b1cdbd2cSJim Jagielski             return eRet;
1433*b1cdbd2cSJim Jagielski         }
1434*b1cdbd2cSJim Jagielski     }
1435*b1cdbd2cSJim Jagielski 
1436*b1cdbd2cSJim Jagielski     /* get file status (mode, size) */
1437*b1cdbd2cSJim Jagielski     struct stat aFileStat;
1438*b1cdbd2cSJim Jagielski     if (-1 == fstat (fd, &aFileStat))
1439*b1cdbd2cSJim Jagielski     {
1440*b1cdbd2cSJim Jagielski         eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1441*b1cdbd2cSJim Jagielski         (void) close(fd);
1442*b1cdbd2cSJim Jagielski         return eRet;
1443*b1cdbd2cSJim Jagielski     }
1444*b1cdbd2cSJim Jagielski     if (!S_ISREG(aFileStat.st_mode))
1445*b1cdbd2cSJim Jagielski     {
1446*b1cdbd2cSJim Jagielski         /* we only open regular files here */
1447*b1cdbd2cSJim Jagielski         (void) close(fd);
1448*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1449*b1cdbd2cSJim Jagielski     }
1450*b1cdbd2cSJim Jagielski 
1451*b1cdbd2cSJim Jagielski     if (osl_file_queryLocking (uFlags))
1452*b1cdbd2cSJim Jagielski     {
1453*b1cdbd2cSJim Jagielski #ifdef MACOSX
1454*b1cdbd2cSJim Jagielski         if (-1 == flock (fd, LOCK_EX | LOCK_NB))
1455*b1cdbd2cSJim Jagielski         {
1456*b1cdbd2cSJim Jagielski             /* Mac OSX returns ENOTSUP for webdav drives. We should try read lock */
1457*b1cdbd2cSJim Jagielski             if ((errno != ENOTSUP) || ((-1 == flock (fd, LOCK_SH | LOCK_NB)) && (errno != ENOTSUP)))
1458*b1cdbd2cSJim Jagielski             {
1459*b1cdbd2cSJim Jagielski                 eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1460*b1cdbd2cSJim Jagielski                 (void) close(fd);
1461*b1cdbd2cSJim Jagielski                 return eRet;
1462*b1cdbd2cSJim Jagielski             }
1463*b1cdbd2cSJim Jagielski         }
1464*b1cdbd2cSJim Jagielski #else   /* F_SETLK */
1465*b1cdbd2cSJim Jagielski         {
1466*b1cdbd2cSJim Jagielski             struct flock aflock;
1467*b1cdbd2cSJim Jagielski 
1468*b1cdbd2cSJim Jagielski             aflock.l_type = F_WRLCK;
1469*b1cdbd2cSJim Jagielski             aflock.l_whence = SEEK_SET;
1470*b1cdbd2cSJim Jagielski             aflock.l_start = 0;
1471*b1cdbd2cSJim Jagielski             aflock.l_len = 0;
1472*b1cdbd2cSJim Jagielski 
1473*b1cdbd2cSJim Jagielski             if (-1 == fcntl (fd, F_SETLK, &aflock))
1474*b1cdbd2cSJim Jagielski             {
1475*b1cdbd2cSJim Jagielski                 eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1476*b1cdbd2cSJim Jagielski                 (void) close(fd);
1477*b1cdbd2cSJim Jagielski                 return eRet;
1478*b1cdbd2cSJim Jagielski             }
1479*b1cdbd2cSJim Jagielski         }
1480*b1cdbd2cSJim Jagielski #endif  /* F_SETLK */
1481*b1cdbd2cSJim Jagielski     }
1482*b1cdbd2cSJim Jagielski 
1483*b1cdbd2cSJim Jagielski     /* allocate memory for impl structure */
1484*b1cdbd2cSJim Jagielski     FileHandle_Impl * pImpl = new FileHandle_Impl (fd, buffer);
1485*b1cdbd2cSJim Jagielski     if (!pImpl)
1486*b1cdbd2cSJim Jagielski     {
1487*b1cdbd2cSJim Jagielski         eRet = oslTranslateFileError (OSL_FET_ERROR, ENOMEM);
1488*b1cdbd2cSJim Jagielski         (void) close(fd);
1489*b1cdbd2cSJim Jagielski         return eRet;
1490*b1cdbd2cSJim Jagielski     }
1491*b1cdbd2cSJim Jagielski     if (flags & O_RDWR)
1492*b1cdbd2cSJim Jagielski         pImpl->m_state |= FileHandle_Impl::STATE_WRITEABLE;
1493*b1cdbd2cSJim Jagielski     pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size);
1494*b1cdbd2cSJim Jagielski 
1495*b1cdbd2cSJim Jagielski     OSL_TRACE("osl_openFile(%d, %s) => %s", pImpl->m_fd,
1496*b1cdbd2cSJim Jagielski               flags & O_RDWR ? "writeable":"readonly",
1497*b1cdbd2cSJim Jagielski               rtl_string_getStr(pImpl->m_strFilePath));
1498*b1cdbd2cSJim Jagielski 
1499*b1cdbd2cSJim Jagielski     *pHandle = (oslFileHandle)(pImpl);
1500*b1cdbd2cSJim Jagielski     return osl_File_E_None;
1501*b1cdbd2cSJim Jagielski }
1502*b1cdbd2cSJim Jagielski 
1503*b1cdbd2cSJim Jagielski /****************************************************************************/
1504*b1cdbd2cSJim Jagielski /*	osl_closeFile */
1505*b1cdbd2cSJim Jagielski /****************************************************************************/
1506*b1cdbd2cSJim Jagielski oslFileError
osl_closeFile(oslFileHandle Handle)1507*b1cdbd2cSJim Jagielski SAL_CALL osl_closeFile( oslFileHandle Handle )
1508*b1cdbd2cSJim Jagielski {
1509*b1cdbd2cSJim Jagielski     FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1510*b1cdbd2cSJim Jagielski 
1511*b1cdbd2cSJim Jagielski     if ((pImpl == 0) || (pImpl->m_fd < 0))
1512*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1513*b1cdbd2cSJim Jagielski 
1514*b1cdbd2cSJim Jagielski     /* close(2) implicitly (and unconditionally) unlocks */
1515*b1cdbd2cSJim Jagielski     OSL_TRACE("osl_closeFile(%d) => %s", pImpl->m_fd, rtl_string_getStr(pImpl->m_strFilePath));
1516*b1cdbd2cSJim Jagielski     oslFileError result = pImpl->syncFile();
1517*b1cdbd2cSJim Jagielski     if (result != osl_File_E_None)
1518*b1cdbd2cSJim Jagielski     {
1519*b1cdbd2cSJim Jagielski         /* close, ignoring double failure */
1520*b1cdbd2cSJim Jagielski         (void) close (pImpl->m_fd);
1521*b1cdbd2cSJim Jagielski     }
1522*b1cdbd2cSJim Jagielski     else if (-1 == close (pImpl->m_fd))
1523*b1cdbd2cSJim Jagielski     {
1524*b1cdbd2cSJim Jagielski         /* translate error code */
1525*b1cdbd2cSJim Jagielski         result = oslTranslateFileError (OSL_FET_ERROR, errno);
1526*b1cdbd2cSJim Jagielski     }
1527*b1cdbd2cSJim Jagielski 
1528*b1cdbd2cSJim Jagielski     delete pImpl;
1529*b1cdbd2cSJim Jagielski     return (result);
1530*b1cdbd2cSJim Jagielski }
1531*b1cdbd2cSJim Jagielski 
1532*b1cdbd2cSJim Jagielski /************************************************
1533*b1cdbd2cSJim Jagielski  * osl_syncFile
1534*b1cdbd2cSJim Jagielski  ***********************************************/
1535*b1cdbd2cSJim Jagielski oslFileError
osl_syncFile(oslFileHandle Handle)1536*b1cdbd2cSJim Jagielski SAL_CALL osl_syncFile(oslFileHandle Handle)
1537*b1cdbd2cSJim Jagielski {
1538*b1cdbd2cSJim Jagielski     FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1539*b1cdbd2cSJim Jagielski 
1540*b1cdbd2cSJim Jagielski     if ((0 == pImpl) || (-1 == pImpl->m_fd))
1541*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1542*b1cdbd2cSJim Jagielski 
1543*b1cdbd2cSJim Jagielski     OSL_FILE_TRACE("osl_syncFile(%d)", pImpl->m_fd);
1544*b1cdbd2cSJim Jagielski     oslFileError result = pImpl->syncFile();
1545*b1cdbd2cSJim Jagielski     if (result != osl_File_E_None)
1546*b1cdbd2cSJim Jagielski         return (result);
1547*b1cdbd2cSJim Jagielski     if (-1 == fsync (pImpl->m_fd))
1548*b1cdbd2cSJim Jagielski         return oslTranslateFileError (OSL_FET_ERROR, errno);
1549*b1cdbd2cSJim Jagielski 
1550*b1cdbd2cSJim Jagielski     return osl_File_E_None;
1551*b1cdbd2cSJim Jagielski }
1552*b1cdbd2cSJim Jagielski 
1553*b1cdbd2cSJim Jagielski /*******************************************
1554*b1cdbd2cSJim Jagielski     osl_mapFile
1555*b1cdbd2cSJim Jagielski ********************************************/
1556*b1cdbd2cSJim Jagielski oslFileError
osl_mapFile(oslFileHandle Handle,void ** ppAddr,sal_uInt64 uLength,sal_uInt64 uOffset,sal_uInt32 uFlags)1557*b1cdbd2cSJim Jagielski SAL_CALL osl_mapFile (
1558*b1cdbd2cSJim Jagielski 	oslFileHandle Handle,
1559*b1cdbd2cSJim Jagielski 	void**        ppAddr,
1560*b1cdbd2cSJim Jagielski 	sal_uInt64    uLength,
1561*b1cdbd2cSJim Jagielski 	sal_uInt64    uOffset,
1562*b1cdbd2cSJim Jagielski 	sal_uInt32    uFlags
1563*b1cdbd2cSJim Jagielski )
1564*b1cdbd2cSJim Jagielski {
1565*b1cdbd2cSJim Jagielski 	FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1566*b1cdbd2cSJim Jagielski 
1567*b1cdbd2cSJim Jagielski 	if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppAddr))
1568*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
1569*b1cdbd2cSJim Jagielski 	*ppAddr = 0;
1570*b1cdbd2cSJim Jagielski 
1571*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_size_t = std::numeric_limits< size_t >::max();
1572*b1cdbd2cSJim Jagielski 	if (g_limit_size_t < uLength)
1573*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1574*b1cdbd2cSJim Jagielski 	size_t const nLength = sal::static_int_cast< size_t >(uLength);
1575*b1cdbd2cSJim Jagielski 
1576*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1577*b1cdbd2cSJim Jagielski 	if (g_limit_off_t < uOffset)
1578*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1579*b1cdbd2cSJim Jagielski 	off_t const nOffset = sal::static_int_cast< off_t >(uOffset);
1580*b1cdbd2cSJim Jagielski 
1581*b1cdbd2cSJim Jagielski #ifdef SAL_OS2 // YD mmap does not support shared
1582*b1cdbd2cSJim Jagielski 	void* p = mmap(NULL, nLength, PROT_READ, MAP_PRIVATE, pImpl->m_fd, nOffset);
1583*b1cdbd2cSJim Jagielski #else
1584*b1cdbd2cSJim Jagielski 	void* p = mmap(NULL, nLength, PROT_READ, MAP_SHARED, pImpl->m_fd, nOffset);
1585*b1cdbd2cSJim Jagielski #endif
1586*b1cdbd2cSJim Jagielski 	if (MAP_FAILED == p)
1587*b1cdbd2cSJim Jagielski 		return oslTranslateFileError(OSL_FET_ERROR, errno);
1588*b1cdbd2cSJim Jagielski 	*ppAddr = p;
1589*b1cdbd2cSJim Jagielski 
1590*b1cdbd2cSJim Jagielski 	if (uFlags & osl_File_MapFlag_RandomAccess)
1591*b1cdbd2cSJim Jagielski 	{
1592*b1cdbd2cSJim Jagielski 		// Determine memory pagesize.
1593*b1cdbd2cSJim Jagielski 		size_t const nPageSize = FileHandle_Impl::getpagesize();
1594*b1cdbd2cSJim Jagielski 		if (size_t(-1) != nPageSize)
1595*b1cdbd2cSJim Jagielski 		{
1596*b1cdbd2cSJim Jagielski 			/*
1597*b1cdbd2cSJim Jagielski 			 * Pagein, touching first byte of every memory page.
1598*b1cdbd2cSJim Jagielski 			 * Note: volatile disables optimizing the loop away.
1599*b1cdbd2cSJim Jagielski 			 */
1600*b1cdbd2cSJim Jagielski 			sal_uInt8 * pData (reinterpret_cast<sal_uInt8*>(*ppAddr));
1601*b1cdbd2cSJim Jagielski 			size_t      nSize (nLength);
1602*b1cdbd2cSJim Jagielski 
1603*b1cdbd2cSJim Jagielski 			volatile sal_uInt8 c = 0;
1604*b1cdbd2cSJim Jagielski 			while (nSize > nPageSize)
1605*b1cdbd2cSJim Jagielski 			{
1606*b1cdbd2cSJim Jagielski 				c ^= pData[0];
1607*b1cdbd2cSJim Jagielski 				pData += nPageSize;
1608*b1cdbd2cSJim Jagielski 				nSize -= nPageSize;
1609*b1cdbd2cSJim Jagielski 			}
1610*b1cdbd2cSJim Jagielski 			if (nSize > 0)
1611*b1cdbd2cSJim Jagielski 			{
1612*b1cdbd2cSJim Jagielski 				c^= pData[0];
1613*b1cdbd2cSJim Jagielski 				pData += nSize;
1614*b1cdbd2cSJim Jagielski 				nSize -= nSize;
1615*b1cdbd2cSJim Jagielski 			}
1616*b1cdbd2cSJim Jagielski 		}
1617*b1cdbd2cSJim Jagielski 	}
1618*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
1619*b1cdbd2cSJim Jagielski }
1620*b1cdbd2cSJim Jagielski 
1621*b1cdbd2cSJim Jagielski /*******************************************
1622*b1cdbd2cSJim Jagielski     osl_unmapFile
1623*b1cdbd2cSJim Jagielski ********************************************/
1624*b1cdbd2cSJim Jagielski oslFileError
osl_unmapFile(void * pAddr,sal_uInt64 uLength)1625*b1cdbd2cSJim Jagielski SAL_CALL osl_unmapFile (void* pAddr, sal_uInt64 uLength)
1626*b1cdbd2cSJim Jagielski {
1627*b1cdbd2cSJim Jagielski 	if (0 == pAddr)
1628*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
1629*b1cdbd2cSJim Jagielski 
1630*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_size_t = std::numeric_limits< size_t >::max();
1631*b1cdbd2cSJim Jagielski 	if (g_limit_size_t < uLength)
1632*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1633*b1cdbd2cSJim Jagielski 	size_t const nLength = sal::static_int_cast< size_t >(uLength);
1634*b1cdbd2cSJim Jagielski 
1635*b1cdbd2cSJim Jagielski 	if (-1 == munmap(static_cast<char*>(pAddr), nLength))
1636*b1cdbd2cSJim Jagielski 		return oslTranslateFileError(OSL_FET_ERROR, errno);
1637*b1cdbd2cSJim Jagielski 
1638*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
1639*b1cdbd2cSJim Jagielski }
1640*b1cdbd2cSJim Jagielski 
1641*b1cdbd2cSJim Jagielski /*******************************************
1642*b1cdbd2cSJim Jagielski     osl_readLine
1643*b1cdbd2cSJim Jagielski ********************************************/
1644*b1cdbd2cSJim Jagielski oslFileError
osl_readLine(oslFileHandle Handle,sal_Sequence ** ppSequence)1645*b1cdbd2cSJim Jagielski SAL_CALL osl_readLine (
1646*b1cdbd2cSJim Jagielski     oslFileHandle   Handle,
1647*b1cdbd2cSJim Jagielski     sal_Sequence ** ppSequence)
1648*b1cdbd2cSJim Jagielski {
1649*b1cdbd2cSJim Jagielski     FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
1650*b1cdbd2cSJim Jagielski 
1651*b1cdbd2cSJim Jagielski     if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppSequence))
1652*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1653*b1cdbd2cSJim Jagielski     sal_uInt64 uBytesRead = 0;
1654*b1cdbd2cSJim Jagielski 
1655*b1cdbd2cSJim Jagielski     // read at current fileptr; fileptr += uBytesRead;
1656*b1cdbd2cSJim Jagielski     oslFileError result = pImpl->readLineAt (
1657*b1cdbd2cSJim Jagielski         pImpl->m_fileptr, ppSequence, &uBytesRead);
1658*b1cdbd2cSJim Jagielski     if (result == osl_File_E_None)
1659*b1cdbd2cSJim Jagielski         pImpl->m_fileptr += uBytesRead;
1660*b1cdbd2cSJim Jagielski     return (result);
1661*b1cdbd2cSJim Jagielski }
1662*b1cdbd2cSJim Jagielski 
1663*b1cdbd2cSJim Jagielski /*******************************************
1664*b1cdbd2cSJim Jagielski     osl_readFile
1665*b1cdbd2cSJim Jagielski ********************************************/
1666*b1cdbd2cSJim Jagielski oslFileError
osl_readFile(oslFileHandle Handle,void * pBuffer,sal_uInt64 uBytesRequested,sal_uInt64 * pBytesRead)1667*b1cdbd2cSJim Jagielski SAL_CALL osl_readFile (
1668*b1cdbd2cSJim Jagielski     oslFileHandle Handle,
1669*b1cdbd2cSJim Jagielski     void *        pBuffer,
1670*b1cdbd2cSJim Jagielski     sal_uInt64    uBytesRequested,
1671*b1cdbd2cSJim Jagielski     sal_uInt64 *  pBytesRead)
1672*b1cdbd2cSJim Jagielski {
1673*b1cdbd2cSJim Jagielski     FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1674*b1cdbd2cSJim Jagielski 
1675*b1cdbd2cSJim Jagielski     if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead))
1676*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1677*b1cdbd2cSJim Jagielski 
1678*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
1679*b1cdbd2cSJim Jagielski 	if (g_limit_ssize_t < uBytesRequested)
1680*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1681*b1cdbd2cSJim Jagielski 	size_t const nBytesRequested = sal::static_int_cast< size_t >(uBytesRequested);
1682*b1cdbd2cSJim Jagielski 
1683*b1cdbd2cSJim Jagielski     // read at current fileptr; fileptr += *pBytesRead;
1684*b1cdbd2cSJim Jagielski     oslFileError result = pImpl->readFileAt (
1685*b1cdbd2cSJim Jagielski         pImpl->m_fileptr, pBuffer, nBytesRequested, pBytesRead);
1686*b1cdbd2cSJim Jagielski     if (result == osl_File_E_None)
1687*b1cdbd2cSJim Jagielski         pImpl->m_fileptr += *pBytesRead;
1688*b1cdbd2cSJim Jagielski     return (result);
1689*b1cdbd2cSJim Jagielski }
1690*b1cdbd2cSJim Jagielski 
1691*b1cdbd2cSJim Jagielski /*******************************************
1692*b1cdbd2cSJim Jagielski     osl_writeFile
1693*b1cdbd2cSJim Jagielski ********************************************/
1694*b1cdbd2cSJim Jagielski oslFileError
osl_writeFile(oslFileHandle Handle,const void * pBuffer,sal_uInt64 uBytesToWrite,sal_uInt64 * pBytesWritten)1695*b1cdbd2cSJim Jagielski SAL_CALL osl_writeFile (
1696*b1cdbd2cSJim Jagielski     oslFileHandle Handle,
1697*b1cdbd2cSJim Jagielski     const void *  pBuffer,
1698*b1cdbd2cSJim Jagielski     sal_uInt64    uBytesToWrite,
1699*b1cdbd2cSJim Jagielski     sal_uInt64 *  pBytesWritten)
1700*b1cdbd2cSJim Jagielski {
1701*b1cdbd2cSJim Jagielski     FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1702*b1cdbd2cSJim Jagielski 
1703*b1cdbd2cSJim Jagielski     if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesWritten))
1704*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1705*b1cdbd2cSJim Jagielski     if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
1706*b1cdbd2cSJim Jagielski         return osl_File_E_BADF;
1707*b1cdbd2cSJim Jagielski 
1708*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
1709*b1cdbd2cSJim Jagielski 	if (g_limit_ssize_t < uBytesToWrite)
1710*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1711*b1cdbd2cSJim Jagielski 	size_t const nBytesToWrite = sal::static_int_cast< size_t >(uBytesToWrite);
1712*b1cdbd2cSJim Jagielski 
1713*b1cdbd2cSJim Jagielski     // write at current fileptr; fileptr += *pBytesWritten;
1714*b1cdbd2cSJim Jagielski     oslFileError result = pImpl->writeFileAt (
1715*b1cdbd2cSJim Jagielski         pImpl->m_fileptr, pBuffer, nBytesToWrite, pBytesWritten);
1716*b1cdbd2cSJim Jagielski     if (result == osl_File_E_None)
1717*b1cdbd2cSJim Jagielski         pImpl->m_fileptr += *pBytesWritten;
1718*b1cdbd2cSJim Jagielski     return (result);
1719*b1cdbd2cSJim Jagielski }
1720*b1cdbd2cSJim Jagielski 
1721*b1cdbd2cSJim Jagielski /*******************************************
1722*b1cdbd2cSJim Jagielski     osl_readFileAt
1723*b1cdbd2cSJim Jagielski ********************************************/
1724*b1cdbd2cSJim Jagielski oslFileError
osl_readFileAt(oslFileHandle Handle,sal_uInt64 uOffset,void * pBuffer,sal_uInt64 uBytesRequested,sal_uInt64 * pBytesRead)1725*b1cdbd2cSJim Jagielski SAL_CALL osl_readFileAt (
1726*b1cdbd2cSJim Jagielski 	oslFileHandle Handle,
1727*b1cdbd2cSJim Jagielski 	sal_uInt64    uOffset,
1728*b1cdbd2cSJim Jagielski 	void*         pBuffer,
1729*b1cdbd2cSJim Jagielski 	sal_uInt64    uBytesRequested,
1730*b1cdbd2cSJim Jagielski 	sal_uInt64*   pBytesRead)
1731*b1cdbd2cSJim Jagielski {
1732*b1cdbd2cSJim Jagielski 	FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1733*b1cdbd2cSJim Jagielski 
1734*b1cdbd2cSJim Jagielski 	if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead))
1735*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
1736*b1cdbd2cSJim Jagielski     if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
1737*b1cdbd2cSJim Jagielski         return osl_File_E_SPIPE;
1738*b1cdbd2cSJim Jagielski 
1739*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1740*b1cdbd2cSJim Jagielski 	if (g_limit_off_t < uOffset)
1741*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1742*b1cdbd2cSJim Jagielski 	off_t const nOffset = sal::static_int_cast< off_t >(uOffset);
1743*b1cdbd2cSJim Jagielski 
1744*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
1745*b1cdbd2cSJim Jagielski 	if (g_limit_ssize_t < uBytesRequested)
1746*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1747*b1cdbd2cSJim Jagielski 	size_t const nBytesRequested = sal::static_int_cast< size_t >(uBytesRequested);
1748*b1cdbd2cSJim Jagielski 
1749*b1cdbd2cSJim Jagielski     // read at specified fileptr
1750*b1cdbd2cSJim Jagielski     return pImpl->readFileAt (nOffset, pBuffer, nBytesRequested, pBytesRead);
1751*b1cdbd2cSJim Jagielski }
1752*b1cdbd2cSJim Jagielski 
1753*b1cdbd2cSJim Jagielski /*******************************************
1754*b1cdbd2cSJim Jagielski     osl_writeFileAt
1755*b1cdbd2cSJim Jagielski ********************************************/
1756*b1cdbd2cSJim Jagielski oslFileError
osl_writeFileAt(oslFileHandle Handle,sal_uInt64 uOffset,const void * pBuffer,sal_uInt64 uBytesToWrite,sal_uInt64 * pBytesWritten)1757*b1cdbd2cSJim Jagielski SAL_CALL osl_writeFileAt (
1758*b1cdbd2cSJim Jagielski 	oslFileHandle Handle,
1759*b1cdbd2cSJim Jagielski 	sal_uInt64    uOffset,
1760*b1cdbd2cSJim Jagielski 	const void*   pBuffer,
1761*b1cdbd2cSJim Jagielski 	sal_uInt64    uBytesToWrite,
1762*b1cdbd2cSJim Jagielski 	sal_uInt64*   pBytesWritten)
1763*b1cdbd2cSJim Jagielski {
1764*b1cdbd2cSJim Jagielski 	FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1765*b1cdbd2cSJim Jagielski 
1766*b1cdbd2cSJim Jagielski 	if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesWritten))
1767*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
1768*b1cdbd2cSJim Jagielski     if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
1769*b1cdbd2cSJim Jagielski         return osl_File_E_SPIPE;
1770*b1cdbd2cSJim Jagielski     if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
1771*b1cdbd2cSJim Jagielski         return osl_File_E_BADF;
1772*b1cdbd2cSJim Jagielski 
1773*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1774*b1cdbd2cSJim Jagielski 	if (g_limit_off_t < uOffset)
1775*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1776*b1cdbd2cSJim Jagielski 	off_t const nOffset = sal::static_int_cast< off_t >(uOffset);
1777*b1cdbd2cSJim Jagielski 
1778*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
1779*b1cdbd2cSJim Jagielski 	if (g_limit_ssize_t < uBytesToWrite)
1780*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1781*b1cdbd2cSJim Jagielski 	size_t const nBytesToWrite = sal::static_int_cast< size_t >(uBytesToWrite);
1782*b1cdbd2cSJim Jagielski 
1783*b1cdbd2cSJim Jagielski     // write at specified fileptr
1784*b1cdbd2cSJim Jagielski     return pImpl->writeFileAt (nOffset, pBuffer, nBytesToWrite, pBytesWritten);
1785*b1cdbd2cSJim Jagielski }
1786*b1cdbd2cSJim Jagielski 
1787*b1cdbd2cSJim Jagielski /****************************************************************************/
1788*b1cdbd2cSJim Jagielski /*	osl_isEndOfFile */
1789*b1cdbd2cSJim Jagielski /****************************************************************************/
1790*b1cdbd2cSJim Jagielski oslFileError
osl_isEndOfFile(oslFileHandle Handle,sal_Bool * pIsEOF)1791*b1cdbd2cSJim Jagielski SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF )
1792*b1cdbd2cSJim Jagielski {
1793*b1cdbd2cSJim Jagielski     FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1794*b1cdbd2cSJim Jagielski 
1795*b1cdbd2cSJim Jagielski     if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pIsEOF))
1796*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1797*b1cdbd2cSJim Jagielski 
1798*b1cdbd2cSJim Jagielski     *pIsEOF = (pImpl->getPos() == pImpl->getSize());
1799*b1cdbd2cSJim Jagielski     return osl_File_E_None;
1800*b1cdbd2cSJim Jagielski }
1801*b1cdbd2cSJim Jagielski 
1802*b1cdbd2cSJim Jagielski /************************************************
1803*b1cdbd2cSJim Jagielski  * osl_getFilePos
1804*b1cdbd2cSJim Jagielski  ***********************************************/
1805*b1cdbd2cSJim Jagielski oslFileError
osl_getFilePos(oslFileHandle Handle,sal_uInt64 * pPos)1806*b1cdbd2cSJim Jagielski SAL_CALL osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
1807*b1cdbd2cSJim Jagielski {
1808*b1cdbd2cSJim Jagielski     FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1809*b1cdbd2cSJim Jagielski 
1810*b1cdbd2cSJim Jagielski     if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pPos))
1811*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1812*b1cdbd2cSJim Jagielski 
1813*b1cdbd2cSJim Jagielski     *pPos = pImpl->getPos();
1814*b1cdbd2cSJim Jagielski     return osl_File_E_None;
1815*b1cdbd2cSJim Jagielski }
1816*b1cdbd2cSJim Jagielski 
1817*b1cdbd2cSJim Jagielski /*******************************************
1818*b1cdbd2cSJim Jagielski     osl_setFilePos
1819*b1cdbd2cSJim Jagielski ********************************************/
1820*b1cdbd2cSJim Jagielski oslFileError
osl_setFilePos(oslFileHandle Handle,sal_uInt32 uHow,sal_Int64 uOffset)1821*b1cdbd2cSJim Jagielski SAL_CALL osl_setFilePos (oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uOffset)
1822*b1cdbd2cSJim Jagielski {
1823*b1cdbd2cSJim Jagielski     FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1824*b1cdbd2cSJim Jagielski 
1825*b1cdbd2cSJim Jagielski     if ((0 == pImpl) || (-1 == pImpl->m_fd))
1826*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1827*b1cdbd2cSJim Jagielski 
1828*b1cdbd2cSJim Jagielski 	static sal_Int64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1829*b1cdbd2cSJim Jagielski 	if (g_limit_off_t < uOffset)
1830*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1831*b1cdbd2cSJim Jagielski 	off_t nPos = 0, nOffset = sal::static_int_cast< off_t >(uOffset);
1832*b1cdbd2cSJim Jagielski 
1833*b1cdbd2cSJim Jagielski     switch(uHow)
1834*b1cdbd2cSJim Jagielski     {
1835*b1cdbd2cSJim Jagielski         case osl_Pos_Absolut:
1836*b1cdbd2cSJim Jagielski             if (0 > nOffset)
1837*b1cdbd2cSJim Jagielski                 return osl_File_E_INVAL;
1838*b1cdbd2cSJim Jagielski             break;
1839*b1cdbd2cSJim Jagielski 
1840*b1cdbd2cSJim Jagielski         case osl_Pos_Current:
1841*b1cdbd2cSJim Jagielski             nPos = sal::static_int_cast< off_t >(pImpl->getPos());
1842*b1cdbd2cSJim Jagielski             if ((0 > nOffset) && (-1*nOffset > nPos))
1843*b1cdbd2cSJim Jagielski                 return osl_File_E_INVAL;
1844*b1cdbd2cSJim Jagielski             if (g_limit_off_t < nPos + nOffset)
1845*b1cdbd2cSJim Jagielski                 return osl_File_E_OVERFLOW;
1846*b1cdbd2cSJim Jagielski             break;
1847*b1cdbd2cSJim Jagielski 
1848*b1cdbd2cSJim Jagielski         case osl_Pos_End:
1849*b1cdbd2cSJim Jagielski             nPos = sal::static_int_cast< off_t >(pImpl->getSize());
1850*b1cdbd2cSJim Jagielski             if ((0 > nOffset) && (-1*nOffset > nPos))
1851*b1cdbd2cSJim Jagielski                 return osl_File_E_INVAL;
1852*b1cdbd2cSJim Jagielski             if (g_limit_off_t < nPos + nOffset)
1853*b1cdbd2cSJim Jagielski                 return osl_File_E_OVERFLOW;
1854*b1cdbd2cSJim Jagielski             break;
1855*b1cdbd2cSJim Jagielski 
1856*b1cdbd2cSJim Jagielski         default:
1857*b1cdbd2cSJim Jagielski             return osl_File_E_INVAL;
1858*b1cdbd2cSJim Jagielski     }
1859*b1cdbd2cSJim Jagielski 
1860*b1cdbd2cSJim Jagielski     return pImpl->setPos (nPos + nOffset);
1861*b1cdbd2cSJim Jagielski }
1862*b1cdbd2cSJim Jagielski 
1863*b1cdbd2cSJim Jagielski /****************************************************************************
1864*b1cdbd2cSJim Jagielski  *	osl_getFileSize
1865*b1cdbd2cSJim Jagielski  ****************************************************************************/
1866*b1cdbd2cSJim Jagielski oslFileError
osl_getFileSize(oslFileHandle Handle,sal_uInt64 * pSize)1867*b1cdbd2cSJim Jagielski SAL_CALL osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize )
1868*b1cdbd2cSJim Jagielski {
1869*b1cdbd2cSJim Jagielski     FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1870*b1cdbd2cSJim Jagielski 
1871*b1cdbd2cSJim Jagielski     if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pSize))
1872*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1873*b1cdbd2cSJim Jagielski 
1874*b1cdbd2cSJim Jagielski     *pSize = pImpl->getSize();
1875*b1cdbd2cSJim Jagielski     return osl_File_E_None;
1876*b1cdbd2cSJim Jagielski }
1877*b1cdbd2cSJim Jagielski 
1878*b1cdbd2cSJim Jagielski /************************************************
1879*b1cdbd2cSJim Jagielski  * osl_setFileSize
1880*b1cdbd2cSJim Jagielski  ***********************************************/
1881*b1cdbd2cSJim Jagielski oslFileError
osl_setFileSize(oslFileHandle Handle,sal_uInt64 uSize)1882*b1cdbd2cSJim Jagielski SAL_CALL osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
1883*b1cdbd2cSJim Jagielski {
1884*b1cdbd2cSJim Jagielski     FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1885*b1cdbd2cSJim Jagielski 
1886*b1cdbd2cSJim Jagielski     if ((0 == pImpl) || (-1 == pImpl->m_fd))
1887*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
1888*b1cdbd2cSJim Jagielski     if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
1889*b1cdbd2cSJim Jagielski         return osl_File_E_BADF;
1890*b1cdbd2cSJim Jagielski 
1891*b1cdbd2cSJim Jagielski 	static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1892*b1cdbd2cSJim Jagielski 	if (g_limit_off_t < uSize)
1893*b1cdbd2cSJim Jagielski 		return osl_File_E_OVERFLOW;
1894*b1cdbd2cSJim Jagielski 
1895*b1cdbd2cSJim Jagielski     oslFileError result = pImpl->syncFile();
1896*b1cdbd2cSJim Jagielski     if (result != osl_File_E_None)
1897*b1cdbd2cSJim Jagielski         return (result);
1898*b1cdbd2cSJim Jagielski     pImpl->m_bufptr = -1, pImpl->m_buflen = 0;
1899*b1cdbd2cSJim Jagielski 
1900*b1cdbd2cSJim Jagielski     return pImpl->setSize (uSize);
1901*b1cdbd2cSJim Jagielski }
1902*b1cdbd2cSJim Jagielski 
1903*b1cdbd2cSJim Jagielski /****************************************************************************/
1904*b1cdbd2cSJim Jagielski /*	osl_moveFile */
1905*b1cdbd2cSJim Jagielski /****************************************************************************/
1906*b1cdbd2cSJim Jagielski 
osl_moveFile(rtl_uString * ustrFileURL,rtl_uString * ustrDestURL)1907*b1cdbd2cSJim Jagielski oslFileError osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
1908*b1cdbd2cSJim Jagielski {
1909*b1cdbd2cSJim Jagielski     char srcPath[PATH_MAX];
1910*b1cdbd2cSJim Jagielski     char destPath[PATH_MAX];
1911*b1cdbd2cSJim Jagielski     oslFileError eRet;
1912*b1cdbd2cSJim Jagielski     APIRET rc;
1913*b1cdbd2cSJim Jagielski 
1914*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrFileURL );
1915*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrDestURL );
1916*b1cdbd2cSJim Jagielski 
1917*b1cdbd2cSJim Jagielski     /* convert source url to system path */
1918*b1cdbd2cSJim Jagielski     eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
1919*b1cdbd2cSJim Jagielski     if( eRet != osl_File_E_None )
1920*b1cdbd2cSJim Jagielski         return eRet;
1921*b1cdbd2cSJim Jagielski 
1922*b1cdbd2cSJim Jagielski     /* convert destination url to system path */
1923*b1cdbd2cSJim Jagielski     eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
1924*b1cdbd2cSJim Jagielski     if( eRet != osl_File_E_None )
1925*b1cdbd2cSJim Jagielski         return eRet;
1926*b1cdbd2cSJim Jagielski 
1927*b1cdbd2cSJim Jagielski     //YD 01/05/06 rename() can overwrite existing files.
1928*b1cdbd2cSJim Jagielski     rc = DosDelete( (PCSZ)destPath);
1929*b1cdbd2cSJim Jagielski     rc = DosMove( (PCSZ)srcPath, (PCSZ)destPath);
1930*b1cdbd2cSJim Jagielski     if (!rc)
1931*b1cdbd2cSJim Jagielski         eRet = osl_File_E_None;
1932*b1cdbd2cSJim Jagielski     else
1933*b1cdbd2cSJim Jagielski         eRet = MapError( rc);
1934*b1cdbd2cSJim Jagielski 
1935*b1cdbd2cSJim Jagielski     return eRet;
1936*b1cdbd2cSJim Jagielski }
1937*b1cdbd2cSJim Jagielski 
1938*b1cdbd2cSJim Jagielski /****************************************************************************/
1939*b1cdbd2cSJim Jagielski /*	osl_copyFile */
1940*b1cdbd2cSJim Jagielski /****************************************************************************/
1941*b1cdbd2cSJim Jagielski 
1942*b1cdbd2cSJim Jagielski #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
1943*b1cdbd2cSJim Jagielski 
oslDoCopy(const sal_Char * pszSourceFileName,const sal_Char * pszDestFileName,mode_t nMode,size_t nSourceSize,int DestFileExists)1944*b1cdbd2cSJim Jagielski static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists)
1945*b1cdbd2cSJim Jagielski {
1946*b1cdbd2cSJim Jagielski     int      nRet=0;
1947*b1cdbd2cSJim Jagielski     sal_Char pszTmpDestFile[PATH_MAX];
1948*b1cdbd2cSJim Jagielski 	size_t   size_tmp_dest_buff = sizeof(pszTmpDestFile);
1949*b1cdbd2cSJim Jagielski 
1950*b1cdbd2cSJim Jagielski 	/* Quick fix for #106048, the whole copy file function seems
1951*b1cdbd2cSJim Jagielski 	   to be erroneous anyway and needs to be rewritten.
1952*b1cdbd2cSJim Jagielski 	   Besides osl_copyFile	is currently not used from OO/SO code.
1953*b1cdbd2cSJim Jagielski 	*/
1954*b1cdbd2cSJim Jagielski 	memset(pszTmpDestFile, 0, size_tmp_dest_buff);
1955*b1cdbd2cSJim Jagielski 
1956*b1cdbd2cSJim Jagielski     if ( DestFileExists )
1957*b1cdbd2cSJim Jagielski     {
1958*b1cdbd2cSJim Jagielski 		strncpy(pszTmpDestFile, pszDestFileName, size_tmp_dest_buff - 1);
1959*b1cdbd2cSJim Jagielski 
1960*b1cdbd2cSJim Jagielski 		if ((strlen(pszTmpDestFile) + strlen(TMP_DEST_FILE_EXTENSION)) >= size_tmp_dest_buff)
1961*b1cdbd2cSJim Jagielski 			return osl_File_E_NAMETOOLONG;
1962*b1cdbd2cSJim Jagielski 
1963*b1cdbd2cSJim Jagielski 		strncat(pszTmpDestFile, TMP_DEST_FILE_EXTENSION, strlen(TMP_DEST_FILE_EXTENSION));
1964*b1cdbd2cSJim Jagielski 
1965*b1cdbd2cSJim Jagielski         /* FIXME: what if pszTmpDestFile already exists? */
1966*b1cdbd2cSJim Jagielski         /*        with getcanonical??? */
1967*b1cdbd2cSJim Jagielski         nRet=rename(pszDestFileName,pszTmpDestFile);
1968*b1cdbd2cSJim Jagielski     }
1969*b1cdbd2cSJim Jagielski 
1970*b1cdbd2cSJim Jagielski     /* mfe: should be S_ISREG */
1971*b1cdbd2cSJim Jagielski     if ( !S_ISLNK(nMode) )
1972*b1cdbd2cSJim Jagielski     {
1973*b1cdbd2cSJim Jagielski         /* copy SourceFile to DestFile */
1974*b1cdbd2cSJim Jagielski         nRet = oslDoCopyFile(pszSourceFileName,pszDestFileName,nSourceSize, nMode);
1975*b1cdbd2cSJim Jagielski     }
1976*b1cdbd2cSJim Jagielski     /* mfe: OK redundant at the moment */
1977*b1cdbd2cSJim Jagielski     else if ( S_ISLNK(nMode) )
1978*b1cdbd2cSJim Jagielski     {
1979*b1cdbd2cSJim Jagielski         nRet = oslDoCopyLink(pszSourceFileName,pszDestFileName);
1980*b1cdbd2cSJim Jagielski     }
1981*b1cdbd2cSJim Jagielski     else
1982*b1cdbd2cSJim Jagielski     {
1983*b1cdbd2cSJim Jagielski         /* mfe: what to do here? */
1984*b1cdbd2cSJim Jagielski         nRet=ENOSYS;
1985*b1cdbd2cSJim Jagielski     }
1986*b1cdbd2cSJim Jagielski 
1987*b1cdbd2cSJim Jagielski     if ( nRet > 0 && DestFileExists == 1 )
1988*b1cdbd2cSJim Jagielski     {
1989*b1cdbd2cSJim Jagielski         unlink(pszDestFileName);
1990*b1cdbd2cSJim Jagielski         rename(pszTmpDestFile,pszDestFileName);
1991*b1cdbd2cSJim Jagielski     }
1992*b1cdbd2cSJim Jagielski 
1993*b1cdbd2cSJim Jagielski     if ( nRet > 0 )
1994*b1cdbd2cSJim Jagielski     {
1995*b1cdbd2cSJim Jagielski         return oslTranslateFileError(OSL_FET_ERROR, nRet);
1996*b1cdbd2cSJim Jagielski     }
1997*b1cdbd2cSJim Jagielski 
1998*b1cdbd2cSJim Jagielski     if ( DestFileExists == 1 )
1999*b1cdbd2cSJim Jagielski     {
2000*b1cdbd2cSJim Jagielski         unlink(pszTmpDestFile);
2001*b1cdbd2cSJim Jagielski     }
2002*b1cdbd2cSJim Jagielski 
2003*b1cdbd2cSJim Jagielski     return osl_File_E_None;
2004*b1cdbd2cSJim Jagielski }
2005*b1cdbd2cSJim Jagielski 
2006*b1cdbd2cSJim Jagielski /*****************************************
2007*b1cdbd2cSJim Jagielski  * oslChangeFileModes
2008*b1cdbd2cSJim Jagielski  ****************************************/
2009*b1cdbd2cSJim Jagielski 
oslChangeFileModes(const sal_Char * pszFileName,mode_t nMode,time_t nAcTime,time_t nModTime,uid_t nUID,gid_t nGID)2010*b1cdbd2cSJim Jagielski static oslFileError oslChangeFileModes( const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID)
2011*b1cdbd2cSJim Jagielski {
2012*b1cdbd2cSJim Jagielski     int nRet=0;
2013*b1cdbd2cSJim Jagielski     struct utimbuf aTimeBuffer;
2014*b1cdbd2cSJim Jagielski 
2015*b1cdbd2cSJim Jagielski     nRet = chmod(pszFileName,nMode);
2016*b1cdbd2cSJim Jagielski     if ( nRet < 0 )
2017*b1cdbd2cSJim Jagielski     {
2018*b1cdbd2cSJim Jagielski         nRet=errno;
2019*b1cdbd2cSJim Jagielski         return oslTranslateFileError(OSL_FET_ERROR, nRet);
2020*b1cdbd2cSJim Jagielski     }
2021*b1cdbd2cSJim Jagielski 
2022*b1cdbd2cSJim Jagielski     aTimeBuffer.actime=nAcTime;
2023*b1cdbd2cSJim Jagielski     aTimeBuffer.modtime=nModTime;
2024*b1cdbd2cSJim Jagielski     nRet=utime(pszFileName,&aTimeBuffer);
2025*b1cdbd2cSJim Jagielski     if ( nRet < 0 )
2026*b1cdbd2cSJim Jagielski     {
2027*b1cdbd2cSJim Jagielski         nRet=errno;
2028*b1cdbd2cSJim Jagielski         return oslTranslateFileError(OSL_FET_ERROR, nRet);
2029*b1cdbd2cSJim Jagielski     }
2030*b1cdbd2cSJim Jagielski 
2031*b1cdbd2cSJim Jagielski     if ( nUID != getuid() )
2032*b1cdbd2cSJim Jagielski     {
2033*b1cdbd2cSJim Jagielski         nUID=getuid();
2034*b1cdbd2cSJim Jagielski     }
2035*b1cdbd2cSJim Jagielski 
2036*b1cdbd2cSJim Jagielski     nRet=chown(pszFileName,nUID,nGID);
2037*b1cdbd2cSJim Jagielski     if ( nRet < 0 )
2038*b1cdbd2cSJim Jagielski     {
2039*b1cdbd2cSJim Jagielski         nRet=errno;
2040*b1cdbd2cSJim Jagielski 
2041*b1cdbd2cSJim Jagielski         /* mfe: do not return an error here! */
2042*b1cdbd2cSJim Jagielski         /* return oslTranslateFileError(nRet);*/
2043*b1cdbd2cSJim Jagielski     }
2044*b1cdbd2cSJim Jagielski 
2045*b1cdbd2cSJim Jagielski     return osl_File_E_None;
2046*b1cdbd2cSJim Jagielski }
2047*b1cdbd2cSJim Jagielski 
2048*b1cdbd2cSJim Jagielski /*****************************************
2049*b1cdbd2cSJim Jagielski  * oslDoCopyLink
2050*b1cdbd2cSJim Jagielski  ****************************************/
2051*b1cdbd2cSJim Jagielski 
oslDoCopyLink(const sal_Char * pszSourceFileName,const sal_Char * pszDestFileName)2052*b1cdbd2cSJim Jagielski static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName)
2053*b1cdbd2cSJim Jagielski {
2054*b1cdbd2cSJim Jagielski     int nRet=0;
2055*b1cdbd2cSJim Jagielski 
2056*b1cdbd2cSJim Jagielski     /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
2057*b1cdbd2cSJim Jagielski     /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
2058*b1cdbd2cSJim Jagielski     sal_Char pszLinkContent[PATH_MAX];
2059*b1cdbd2cSJim Jagielski 
2060*b1cdbd2cSJim Jagielski     pszLinkContent[0] = '\0';
2061*b1cdbd2cSJim Jagielski 
2062*b1cdbd2cSJim Jagielski     nRet = readlink(pszSourceFileName,pszLinkContent,PATH_MAX);
2063*b1cdbd2cSJim Jagielski 
2064*b1cdbd2cSJim Jagielski     if ( nRet < 0 )
2065*b1cdbd2cSJim Jagielski     {
2066*b1cdbd2cSJim Jagielski         nRet=errno;
2067*b1cdbd2cSJim Jagielski         return nRet;
2068*b1cdbd2cSJim Jagielski     }
2069*b1cdbd2cSJim Jagielski 	else
2070*b1cdbd2cSJim Jagielski 		pszLinkContent[ nRet ] = 0;
2071*b1cdbd2cSJim Jagielski 
2072*b1cdbd2cSJim Jagielski     nRet = symlink(pszLinkContent,pszDestFileName);
2073*b1cdbd2cSJim Jagielski 
2074*b1cdbd2cSJim Jagielski     if ( nRet < 0 )
2075*b1cdbd2cSJim Jagielski     {
2076*b1cdbd2cSJim Jagielski         nRet=errno;
2077*b1cdbd2cSJim Jagielski         return nRet;
2078*b1cdbd2cSJim Jagielski     }
2079*b1cdbd2cSJim Jagielski 
2080*b1cdbd2cSJim Jagielski     return 0;
2081*b1cdbd2cSJim Jagielski }
2082*b1cdbd2cSJim Jagielski 
2083*b1cdbd2cSJim Jagielski /*****************************************
2084*b1cdbd2cSJim Jagielski  * oslDoCopyFile
2085*b1cdbd2cSJim Jagielski  ****************************************/
2086*b1cdbd2cSJim Jagielski 
oslDoCopyFile(const sal_Char * pszSourceFileName,const sal_Char * pszDestFileName,size_t nSourceSize,mode_t mode)2087*b1cdbd2cSJim Jagielski static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode)
2088*b1cdbd2cSJim Jagielski {
2089*b1cdbd2cSJim Jagielski     int SourceFileFD=0;
2090*b1cdbd2cSJim Jagielski     int DestFileFD=0;
2091*b1cdbd2cSJim Jagielski     int nRet=0;
2092*b1cdbd2cSJim Jagielski     void* pSourceFile=0;
2093*b1cdbd2cSJim Jagielski 	char	buffer[ 4096];
2094*b1cdbd2cSJim Jagielski 
2095*b1cdbd2cSJim Jagielski     SourceFileFD=open(pszSourceFileName,O_RDONLY | O_BINARY);
2096*b1cdbd2cSJim Jagielski     if ( SourceFileFD < 0 )
2097*b1cdbd2cSJim Jagielski     {
2098*b1cdbd2cSJim Jagielski         nRet=errno;
2099*b1cdbd2cSJim Jagielski         return nRet;
2100*b1cdbd2cSJim Jagielski     }
2101*b1cdbd2cSJim Jagielski 
2102*b1cdbd2cSJim Jagielski     DestFileFD=open(pszDestFileName, O_WRONLY | O_CREAT | O_BINARY, mode);
2103*b1cdbd2cSJim Jagielski     if ( DestFileFD < 0 )
2104*b1cdbd2cSJim Jagielski     {
2105*b1cdbd2cSJim Jagielski         nRet=errno;
2106*b1cdbd2cSJim Jagielski         close(SourceFileFD);
2107*b1cdbd2cSJim Jagielski         return nRet;
2108*b1cdbd2cSJim Jagielski     }
2109*b1cdbd2cSJim Jagielski 
2110*b1cdbd2cSJim Jagielski 	/* HACK: because memory mapping fails on various
2111*b1cdbd2cSJim Jagielski 	   platforms if the size of the source file is  0 byte */
2112*b1cdbd2cSJim Jagielski 	if (0 == nSourceSize)
2113*b1cdbd2cSJim Jagielski 	{
2114*b1cdbd2cSJim Jagielski 		close(SourceFileFD);
2115*b1cdbd2cSJim Jagielski 		close(DestFileFD);
2116*b1cdbd2cSJim Jagielski 		return 0;
2117*b1cdbd2cSJim Jagielski 	}
2118*b1cdbd2cSJim Jagielski 
2119*b1cdbd2cSJim Jagielski 	while( (nRet = read(SourceFileFD, buffer, sizeof(buffer))) !=0 )
2120*b1cdbd2cSJim Jagielski 	{
2121*b1cdbd2cSJim Jagielski 		nRet = write( DestFileFD, buffer, nRet);
2122*b1cdbd2cSJim Jagielski 	}
2123*b1cdbd2cSJim Jagielski 
2124*b1cdbd2cSJim Jagielski     close(SourceFileFD);
2125*b1cdbd2cSJim Jagielski     close(DestFileFD);
2126*b1cdbd2cSJim Jagielski 
2127*b1cdbd2cSJim Jagielski     return nRet;
2128*b1cdbd2cSJim Jagielski }
2129*b1cdbd2cSJim Jagielski 
osl_psz_copyFile(const sal_Char * pszPath,const sal_Char * pszDestPath)2130*b1cdbd2cSJim Jagielski static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
2131*b1cdbd2cSJim Jagielski {
2132*b1cdbd2cSJim Jagielski     time_t nAcTime=0;
2133*b1cdbd2cSJim Jagielski     time_t nModTime=0;
2134*b1cdbd2cSJim Jagielski     uid_t nUID=0;
2135*b1cdbd2cSJim Jagielski     gid_t nGID=0;
2136*b1cdbd2cSJim Jagielski     int nRet=0;
2137*b1cdbd2cSJim Jagielski     mode_t nMode=0;
2138*b1cdbd2cSJim Jagielski     struct stat aFileStat;
2139*b1cdbd2cSJim Jagielski     oslFileError tErr=osl_File_E_invalidError;
2140*b1cdbd2cSJim Jagielski     size_t nSourceSize=0;
2141*b1cdbd2cSJim Jagielski     int DestFileExists=1;
2142*b1cdbd2cSJim Jagielski 
2143*b1cdbd2cSJim Jagielski     /* mfe: does the source file really exists? */
2144*b1cdbd2cSJim Jagielski     nRet = lstat(pszPath,&aFileStat);
2145*b1cdbd2cSJim Jagielski 
2146*b1cdbd2cSJim Jagielski     if ( nRet < 0 )
2147*b1cdbd2cSJim Jagielski     {
2148*b1cdbd2cSJim Jagielski         nRet=errno;
2149*b1cdbd2cSJim Jagielski         return oslTranslateFileError(OSL_FET_ERROR, nRet);
2150*b1cdbd2cSJim Jagielski     }
2151*b1cdbd2cSJim Jagielski 
2152*b1cdbd2cSJim Jagielski     /* mfe: we do only copy files here! */
2153*b1cdbd2cSJim Jagielski     if ( S_ISDIR(aFileStat.st_mode) )
2154*b1cdbd2cSJim Jagielski     {
2155*b1cdbd2cSJim Jagielski         return osl_File_E_ISDIR;
2156*b1cdbd2cSJim Jagielski     }
2157*b1cdbd2cSJim Jagielski 
2158*b1cdbd2cSJim Jagielski     nSourceSize=(size_t)aFileStat.st_size;
2159*b1cdbd2cSJim Jagielski     nMode=aFileStat.st_mode;
2160*b1cdbd2cSJim Jagielski     nAcTime=aFileStat.st_atime;
2161*b1cdbd2cSJim Jagielski     nModTime=aFileStat.st_mtime;
2162*b1cdbd2cSJim Jagielski     nUID=aFileStat.st_uid;
2163*b1cdbd2cSJim Jagielski     nGID=aFileStat.st_gid;
2164*b1cdbd2cSJim Jagielski 
2165*b1cdbd2cSJim Jagielski     nRet = stat(pszDestPath,&aFileStat);
2166*b1cdbd2cSJim Jagielski     if ( nRet < 0 )
2167*b1cdbd2cSJim Jagielski     {
2168*b1cdbd2cSJim Jagielski         nRet=errno;
2169*b1cdbd2cSJim Jagielski 
2170*b1cdbd2cSJim Jagielski         if ( nRet == ENOENT )
2171*b1cdbd2cSJim Jagielski         {
2172*b1cdbd2cSJim Jagielski             DestFileExists=0;
2173*b1cdbd2cSJim Jagielski         }
2174*b1cdbd2cSJim Jagielski /*        return oslTranslateFileError(nRet);*/
2175*b1cdbd2cSJim Jagielski     }
2176*b1cdbd2cSJim Jagielski 
2177*b1cdbd2cSJim Jagielski     /* mfe: the destination file must not be a directory! */
2178*b1cdbd2cSJim Jagielski     if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
2179*b1cdbd2cSJim Jagielski     {
2180*b1cdbd2cSJim Jagielski         return osl_File_E_ISDIR;
2181*b1cdbd2cSJim Jagielski     }
2182*b1cdbd2cSJim Jagielski     else
2183*b1cdbd2cSJim Jagielski     {
2184*b1cdbd2cSJim Jagielski         /* mfe: file does not exists or is no dir */
2185*b1cdbd2cSJim Jagielski     }
2186*b1cdbd2cSJim Jagielski 
2187*b1cdbd2cSJim Jagielski     tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
2188*b1cdbd2cSJim Jagielski 
2189*b1cdbd2cSJim Jagielski     if ( tErr != osl_File_E_None )
2190*b1cdbd2cSJim Jagielski     {
2191*b1cdbd2cSJim Jagielski         return tErr;
2192*b1cdbd2cSJim Jagielski     }
2193*b1cdbd2cSJim Jagielski 
2194*b1cdbd2cSJim Jagielski     /*
2195*b1cdbd2cSJim Jagielski      *   mfe: ignore return code
2196*b1cdbd2cSJim Jagielski      *        since only  the success of the copy is
2197*b1cdbd2cSJim Jagielski      *        important
2198*b1cdbd2cSJim Jagielski      */
2199*b1cdbd2cSJim Jagielski     oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
2200*b1cdbd2cSJim Jagielski 
2201*b1cdbd2cSJim Jagielski     return tErr;
2202*b1cdbd2cSJim Jagielski }
2203*b1cdbd2cSJim Jagielski 
osl_copyFile(rtl_uString * ustrFileURL,rtl_uString * ustrDestURL)2204*b1cdbd2cSJim Jagielski oslFileError osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
2205*b1cdbd2cSJim Jagielski {
2206*b1cdbd2cSJim Jagielski     char srcPath[PATH_MAX];
2207*b1cdbd2cSJim Jagielski     char destPath[PATH_MAX];
2208*b1cdbd2cSJim Jagielski     oslFileError eRet;
2209*b1cdbd2cSJim Jagielski     APIRET rc;
2210*b1cdbd2cSJim Jagielski 
2211*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrFileURL );
2212*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrDestURL );
2213*b1cdbd2cSJim Jagielski 
2214*b1cdbd2cSJim Jagielski     /* convert source url to system path */
2215*b1cdbd2cSJim Jagielski     eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
2216*b1cdbd2cSJim Jagielski     if( eRet != osl_File_E_None )
2217*b1cdbd2cSJim Jagielski         return eRet;
2218*b1cdbd2cSJim Jagielski 
2219*b1cdbd2cSJim Jagielski     /* convert destination url to system path */
2220*b1cdbd2cSJim Jagielski     eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
2221*b1cdbd2cSJim Jagielski     if( eRet != osl_File_E_None )
2222*b1cdbd2cSJim Jagielski         return eRet;
2223*b1cdbd2cSJim Jagielski 
2224*b1cdbd2cSJim Jagielski     return osl_psz_copyFile( srcPath, destPath );
2225*b1cdbd2cSJim Jagielski }
2226*b1cdbd2cSJim Jagielski 
2227*b1cdbd2cSJim Jagielski /****************************************************************************/
2228*b1cdbd2cSJim Jagielski /*	osl_removeFile */
2229*b1cdbd2cSJim Jagielski /****************************************************************************/
2230*b1cdbd2cSJim Jagielski 
osl_removeFile(rtl_uString * ustrFileURL)2231*b1cdbd2cSJim Jagielski oslFileError osl_removeFile( rtl_uString* ustrFileURL )
2232*b1cdbd2cSJim Jagielski {
2233*b1cdbd2cSJim Jagielski     char path[PATH_MAX];
2234*b1cdbd2cSJim Jagielski     oslFileError eRet;
2235*b1cdbd2cSJim Jagielski     APIRET rc;
2236*b1cdbd2cSJim Jagielski 
2237*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrFileURL );
2238*b1cdbd2cSJim Jagielski 
2239*b1cdbd2cSJim Jagielski     /* convert file url to system path */
2240*b1cdbd2cSJim Jagielski     eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
2241*b1cdbd2cSJim Jagielski     if( eRet != osl_File_E_None )
2242*b1cdbd2cSJim Jagielski         return eRet;
2243*b1cdbd2cSJim Jagielski 
2244*b1cdbd2cSJim Jagielski     rc = DosDelete( (PCSZ)path);
2245*b1cdbd2cSJim Jagielski     if (!rc)
2246*b1cdbd2cSJim Jagielski         eRet = osl_File_E_None;
2247*b1cdbd2cSJim Jagielski     else
2248*b1cdbd2cSJim Jagielski         eRet = MapError( rc);
2249*b1cdbd2cSJim Jagielski 
2250*b1cdbd2cSJim Jagielski     return eRet;
2251*b1cdbd2cSJim Jagielski }
2252*b1cdbd2cSJim Jagielski 
2253*b1cdbd2cSJim Jagielski /****************************************************************************/
2254*b1cdbd2cSJim Jagielski /*	osl_getVolumeInformation */
2255*b1cdbd2cSJim Jagielski /****************************************************************************/
2256*b1cdbd2cSJim Jagielski 
2257*b1cdbd2cSJim Jagielski #define TXFSDC_BLOCKR         0x00              // block device removable
2258*b1cdbd2cSJim Jagielski #define TXFSDC_GETBPB         0x00              // get device bpb info
2259*b1cdbd2cSJim Jagielski #define TXFSBPB_REMOVABLE     0x08              // BPB attribute for removable
2260*b1cdbd2cSJim Jagielski 
2261*b1cdbd2cSJim Jagielski typedef struct drivecmd
2262*b1cdbd2cSJim Jagielski {
2263*b1cdbd2cSJim Jagielski    BYTE                cmd;                     // 0=unlock 1=lock 2=eject
2264*b1cdbd2cSJim Jagielski    BYTE                drv;                     // 0=A, 1=B 2=C ...
2265*b1cdbd2cSJim Jagielski } DRIVECMD;                                     // end of struct "drivecmd"
2266*b1cdbd2cSJim Jagielski 
2267*b1cdbd2cSJim Jagielski #pragma pack(push, 1)                           // byte packing
2268*b1cdbd2cSJim Jagielski typedef struct txfs_ebpb                        // ext. boot parameter block
2269*b1cdbd2cSJim Jagielski {                                               // at offset 0x0b in bootsector
2270*b1cdbd2cSJim Jagielski    USHORT              SectSize;                // 0B bytes per sector
2271*b1cdbd2cSJim Jagielski    BYTE                ClustSize;               // 0D sectors per cluster
2272*b1cdbd2cSJim Jagielski    USHORT              FatOffset;               // 0E sectors to 1st FAT
2273*b1cdbd2cSJim Jagielski    BYTE                NrOfFats;                // 10 nr of FATS     (FAT only)
2274*b1cdbd2cSJim Jagielski    USHORT              RootEntries;             // 11 Max entries \ (FAT only)
2275*b1cdbd2cSJim Jagielski    USHORT              Sectors;                 // 13 nr of sectors if <  64K
2276*b1cdbd2cSJim Jagielski    BYTE                MediaType;               // 15 mediatype (F8 for HD)
2277*b1cdbd2cSJim Jagielski    USHORT              FatSectors;              // 16 sectors/FAT (FAT only)
2278*b1cdbd2cSJim Jagielski    USHORT              LogGeoSect;              // 18 sectors/Track
2279*b1cdbd2cSJim Jagielski    USHORT              LogGeoHead;              // 1a nr of heads
2280*b1cdbd2cSJim Jagielski    ULONG               HiddenSectors;           // 1c sector-offset from MBR/EBR
2281*b1cdbd2cSJim Jagielski    ULONG               BigSectors;              // 20 nr of sectors if >= 64K
2282*b1cdbd2cSJim Jagielski } TXFS_EBPB;                                    // last byte is at offset 0x23
2283*b1cdbd2cSJim Jagielski 
2284*b1cdbd2cSJim Jagielski typedef struct drivebpb
2285*b1cdbd2cSJim Jagielski {
2286*b1cdbd2cSJim Jagielski    TXFS_EBPB           ebpb;                    // extended BPB
2287*b1cdbd2cSJim Jagielski    BYTE                reserved[6];
2288*b1cdbd2cSJim Jagielski    USHORT              cyls;
2289*b1cdbd2cSJim Jagielski    BYTE                type;
2290*b1cdbd2cSJim Jagielski    USHORT              attributes;              // device attributes
2291*b1cdbd2cSJim Jagielski    BYTE                fill[6];                 // documented for IOCtl
2292*b1cdbd2cSJim Jagielski } DRIVEBPB;                                     // end of struct "drivebpb"
2293*b1cdbd2cSJim Jagielski 
2294*b1cdbd2cSJim Jagielski struct CDInfo {
2295*b1cdbd2cSJim Jagielski     USHORT usCount;
2296*b1cdbd2cSJim Jagielski     USHORT usFirst;
2297*b1cdbd2cSJim Jagielski };
2298*b1cdbd2cSJim Jagielski 
2299*b1cdbd2cSJim Jagielski #pragma pack(pop)
2300*b1cdbd2cSJim Jagielski 
2301*b1cdbd2cSJim Jagielski /*****************************************************************************/
2302*b1cdbd2cSJim Jagielski // Get number of cdrom readers
2303*b1cdbd2cSJim Jagielski /*****************************************************************************/
GetCDInfo(CDInfo * pCDInfo)2304*b1cdbd2cSJim Jagielski BOOL GetCDInfo( CDInfo * pCDInfo )
2305*b1cdbd2cSJim Jagielski {
2306*b1cdbd2cSJim Jagielski     HFILE hFileCD;
2307*b1cdbd2cSJim Jagielski     ULONG ulAction;
2308*b1cdbd2cSJim Jagielski 
2309*b1cdbd2cSJim Jagielski     if( NO_ERROR == DosOpen( (PCSZ)"\\DEV\\CD-ROM2$",
2310*b1cdbd2cSJim Jagielski                             &hFileCD, &ulAction, 0, FILE_NORMAL,
2311*b1cdbd2cSJim Jagielski                             OPEN_ACTION_OPEN_IF_EXISTS,
2312*b1cdbd2cSJim Jagielski                             OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL )) {
2313*b1cdbd2cSJim Jagielski         ULONG  ulDataSize = sizeof(CDInfo);
2314*b1cdbd2cSJim Jagielski         APIRET rc = DosDevIOCtl( hFileCD, 0x82, 0x60, NULL, 0,
2315*b1cdbd2cSJim Jagielski                                  NULL, (PVOID)pCDInfo, ulDataSize, &ulDataSize);
2316*b1cdbd2cSJim Jagielski         DosClose( hFileCD);
2317*b1cdbd2cSJim Jagielski         if(rc == NO_ERROR)
2318*b1cdbd2cSJim Jagielski             return TRUE;
2319*b1cdbd2cSJim Jagielski     }
2320*b1cdbd2cSJim Jagielski 	// failed
2321*b1cdbd2cSJim Jagielski     pCDInfo->usFirst = 0;
2322*b1cdbd2cSJim Jagielski     pCDInfo->usCount = 0;
2323*b1cdbd2cSJim Jagielski     return FALSE;
2324*b1cdbd2cSJim Jagielski }
2325*b1cdbd2cSJim Jagielski 
2326*b1cdbd2cSJim Jagielski /*****************************************************************************/
2327*b1cdbd2cSJim Jagielski // Determine if unit is a cdrom or not
2328*b1cdbd2cSJim Jagielski /*****************************************************************************/
DriveIsCDROM(UINT uiDrive,CDInfo * pCDInfo)2329*b1cdbd2cSJim Jagielski BOOL DriveIsCDROM(UINT uiDrive, CDInfo *pCDInfo)
2330*b1cdbd2cSJim Jagielski {
2331*b1cdbd2cSJim Jagielski 	return (uiDrive >= pCDInfo->usFirst)
2332*b1cdbd2cSJim Jagielski 			&& (uiDrive < (pCDInfo->usFirst + pCDInfo->usCount));
2333*b1cdbd2cSJim Jagielski }
2334*b1cdbd2cSJim Jagielski 
2335*b1cdbd2cSJim Jagielski /*****************************************************************************/
2336*b1cdbd2cSJim Jagielski // Determine attached fstype, e.g. HPFS for specified drive
2337*b1cdbd2cSJim Jagielski /*****************************************************************************/
TxFsType(char * drive,char * fstype,char * details)2338*b1cdbd2cSJim Jagielski BOOL TxFsType                                   // RET   FS type resolved
2339*b1cdbd2cSJim Jagielski (
2340*b1cdbd2cSJim Jagielski    char               *drive,                   // IN    Drive specification
2341*b1cdbd2cSJim Jagielski    char               *fstype,                  // OUT   Attached FS type
2342*b1cdbd2cSJim Jagielski    char               *details                  // OUT   details (UNC) or NULL
2343*b1cdbd2cSJim Jagielski )
2344*b1cdbd2cSJim Jagielski {
2345*b1cdbd2cSJim Jagielski    BOOL                rc = FALSE;
2346*b1cdbd2cSJim Jagielski    FSQBUFFER2         *fsinfo;                     // Attached FS info
2347*b1cdbd2cSJim Jagielski    ULONG               fsdlen = 2048;              // Fs info data length
2348*b1cdbd2cSJim Jagielski 
2349*b1cdbd2cSJim Jagielski    strcpy(fstype, "none");
2350*b1cdbd2cSJim Jagielski    if (details)
2351*b1cdbd2cSJim Jagielski    {
2352*b1cdbd2cSJim Jagielski       strcpy(details, "");
2353*b1cdbd2cSJim Jagielski    }
2354*b1cdbd2cSJim Jagielski    if ((fsinfo = (FSQBUFFER2*)calloc(1, fsdlen)) != NULL)
2355*b1cdbd2cSJim Jagielski    {
2356*b1cdbd2cSJim Jagielski       if (DosQFSAttach((PCSZ)drive, 0, 1, fsinfo, &fsdlen) == NO_ERROR)
2357*b1cdbd2cSJim Jagielski       {
2358*b1cdbd2cSJim Jagielski          strcpy(fstype, (char*) fsinfo->szName + fsinfo->cbName +1);
2359*b1cdbd2cSJim Jagielski          if (details && (fsinfo->cbFSAData != 0))
2360*b1cdbd2cSJim Jagielski          {
2361*b1cdbd2cSJim Jagielski             strcpy( details, (char*) fsinfo->szName + fsinfo->cbName +
2362*b1cdbd2cSJim Jagielski                                               fsinfo->cbFSDName +2);
2363*b1cdbd2cSJim Jagielski          }
2364*b1cdbd2cSJim Jagielski          rc = TRUE;
2365*b1cdbd2cSJim Jagielski       }
2366*b1cdbd2cSJim Jagielski       free(fsinfo);
2367*b1cdbd2cSJim Jagielski    }
2368*b1cdbd2cSJim Jagielski    return (rc);
2369*b1cdbd2cSJim Jagielski }                                               // end 'TxFsType'
2370*b1cdbd2cSJim Jagielski /*---------------------------------------------------------------------------*/
2371*b1cdbd2cSJim Jagielski 
2372*b1cdbd2cSJim Jagielski 
2373*b1cdbd2cSJim Jagielski /*****************************************************************************/
2374*b1cdbd2cSJim Jagielski // Determine if a driveletter represents a removable medium/device
2375*b1cdbd2cSJim Jagielski /*****************************************************************************/
TxFsIsRemovable(char * drive)2376*b1cdbd2cSJim Jagielski BOOL TxFsIsRemovable                            // RET   drive is removable
2377*b1cdbd2cSJim Jagielski (
2378*b1cdbd2cSJim Jagielski    char               *drive                    // IN    Driveletter to test
2379*b1cdbd2cSJim Jagielski )
2380*b1cdbd2cSJim Jagielski {
2381*b1cdbd2cSJim Jagielski    BOOL                rc = FALSE;
2382*b1cdbd2cSJim Jagielski    DRIVECMD            IOCtl;
2383*b1cdbd2cSJim Jagielski    DRIVEBPB            RemAt;
2384*b1cdbd2cSJim Jagielski    ULONG               DataLen;
2385*b1cdbd2cSJim Jagielski    ULONG               ParmLen;
2386*b1cdbd2cSJim Jagielski    BYTE                NoRem;
2387*b1cdbd2cSJim Jagielski 
2388*b1cdbd2cSJim Jagielski    DosError( FERR_DISABLEHARDERR);              // avoid 'not ready' popups
2389*b1cdbd2cSJim Jagielski 
2390*b1cdbd2cSJim Jagielski    ParmLen   = sizeof(IOCtl);
2391*b1cdbd2cSJim Jagielski    IOCtl.cmd = TXFSDC_BLOCKR;
2392*b1cdbd2cSJim Jagielski    IOCtl.drv = toupper(drive[0]) - 'A';
2393*b1cdbd2cSJim Jagielski    DataLen   = sizeof(NoRem);
2394*b1cdbd2cSJim Jagielski 
2395*b1cdbd2cSJim Jagielski    if (DosDevIOCtl((HFILE) -1, IOCTL_DISK,
2396*b1cdbd2cSJim Jagielski                                DSK_BLOCKREMOVABLE,
2397*b1cdbd2cSJim Jagielski                                &IOCtl, ParmLen, &ParmLen,
2398*b1cdbd2cSJim Jagielski                                &NoRem, DataLen, &DataLen) == NO_ERROR)
2399*b1cdbd2cSJim Jagielski    {
2400*b1cdbd2cSJim Jagielski       if (NoRem)                                // non-removable sofar, check
2401*b1cdbd2cSJim Jagielski       {                                         // BPB as well (USB devices)
2402*b1cdbd2cSJim Jagielski          ParmLen   = sizeof(IOCtl);
2403*b1cdbd2cSJim Jagielski          IOCtl.cmd = TXFSDC_GETBPB;
2404*b1cdbd2cSJim Jagielski          IOCtl.drv = toupper(drive[0]) - 'A';
2405*b1cdbd2cSJim Jagielski          DataLen   = sizeof(RemAt);
2406*b1cdbd2cSJim Jagielski 
2407*b1cdbd2cSJim Jagielski          if (DosDevIOCtl((HFILE) -1, IOCTL_DISK,
2408*b1cdbd2cSJim Jagielski                                      DSK_GETDEVICEPARAMS,
2409*b1cdbd2cSJim Jagielski                                      &IOCtl, ParmLen, &ParmLen,
2410*b1cdbd2cSJim Jagielski                                      &RemAt, DataLen, &DataLen) == NO_ERROR)
2411*b1cdbd2cSJim Jagielski 
2412*b1cdbd2cSJim Jagielski          {
2413*b1cdbd2cSJim Jagielski             if (RemAt.attributes & TXFSBPB_REMOVABLE)
2414*b1cdbd2cSJim Jagielski             {
2415*b1cdbd2cSJim Jagielski                rc = TRUE;                       // removable, probably USB
2416*b1cdbd2cSJim Jagielski             }
2417*b1cdbd2cSJim Jagielski          }
2418*b1cdbd2cSJim Jagielski       }
2419*b1cdbd2cSJim Jagielski       else
2420*b1cdbd2cSJim Jagielski       {
2421*b1cdbd2cSJim Jagielski          rc = TRUE;                             // removable block device
2422*b1cdbd2cSJim Jagielski       }
2423*b1cdbd2cSJim Jagielski    }
2424*b1cdbd2cSJim Jagielski    DosError( FERR_ENABLEHARDERR);               // enable criterror handler
2425*b1cdbd2cSJim Jagielski    return (rc);
2426*b1cdbd2cSJim Jagielski }                                               // end 'TxFsIsRemovable'
2427*b1cdbd2cSJim Jagielski /*---------------------------------------------------------------------------*/
2428*b1cdbd2cSJim Jagielski 
get_drive_type(const char * path,oslVolumeInfo * pInfo)2429*b1cdbd2cSJim Jagielski static oslFileError get_drive_type(const char* path, oslVolumeInfo* pInfo)
2430*b1cdbd2cSJim Jagielski {
2431*b1cdbd2cSJim Jagielski 	char		Drive_Letter = toupper( *path);
2432*b1cdbd2cSJim Jagielski 	char		fstype[ 64];
2433*b1cdbd2cSJim Jagielski 
2434*b1cdbd2cSJim Jagielski 	pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2435*b1cdbd2cSJim Jagielski 
2436*b1cdbd2cSJim Jagielski 	// check for floppy A/B
2437*b1cdbd2cSJim Jagielski     BYTE 	nFloppies;
2438*b1cdbd2cSJim Jagielski 	APIRET	rc;
2439*b1cdbd2cSJim Jagielski     rc = DosDevConfig( (void*) &nFloppies, DEVINFO_FLOPPY );
2440*b1cdbd2cSJim Jagielski 	if ((Drive_Letter - 'A') < nFloppies) {
2441*b1cdbd2cSJim Jagielski 		pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
2442*b1cdbd2cSJim Jagielski 		pInfo->uAttributes |= osl_Volume_Attribute_FloppyDisk;
2443*b1cdbd2cSJim Jagielski 		return osl_File_E_None;
2444*b1cdbd2cSJim Jagielski 	}
2445*b1cdbd2cSJim Jagielski 
2446*b1cdbd2cSJim Jagielski 	// query system for CD drives
2447*b1cdbd2cSJim Jagielski 	CDInfo cdInfo;
2448*b1cdbd2cSJim Jagielski 	GetCDInfo(&cdInfo);
2449*b1cdbd2cSJim Jagielski 
2450*b1cdbd2cSJim Jagielski 	// query if drive is a CDROM
2451*b1cdbd2cSJim Jagielski 	if (DriveIsCDROM( Drive_Letter - 'A', &cdInfo))
2452*b1cdbd2cSJim Jagielski 		pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
2453*b1cdbd2cSJim Jagielski 
2454*b1cdbd2cSJim Jagielski 	if (TxFsIsRemovable( (char*)path))
2455*b1cdbd2cSJim Jagielski 		pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
2456*b1cdbd2cSJim Jagielski 
2457*b1cdbd2cSJim Jagielski 	if (TxFsType( (char*)path, fstype, NULL) == FALSE) {
2458*b1cdbd2cSJim Jagielski 		// query failed, assume fixed disk
2459*b1cdbd2cSJim Jagielski 		pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
2460*b1cdbd2cSJim Jagielski 		return osl_File_E_None;
2461*b1cdbd2cSJim Jagielski 	}
2462*b1cdbd2cSJim Jagielski 
2463*b1cdbd2cSJim Jagielski 	//- Note, connected Win-NT drives use the REAL FS-name like NTFS!
2464*b1cdbd2cSJim Jagielski 	if ((strncasecmp( fstype, "LAN", 3) == 0) 			//- OS/2 LAN drives
2465*b1cdbd2cSJim Jagielski 		|| (strncasecmp( fstype, "NDFS", 4) == 0)  	//- NetDrive
2466*b1cdbd2cSJim Jagielski 		|| (strncasecmp( fstype, "REMOTE", 5) == 0)  )  //- NT disconnected
2467*b1cdbd2cSJim Jagielski 		pInfo->uAttributes |= osl_Volume_Attribute_Remote;
2468*b1cdbd2cSJim Jagielski 	else if (strncasecmp( fstype, "RAMFS", 5) == 0)
2469*b1cdbd2cSJim Jagielski 		pInfo->uAttributes |= osl_Volume_Attribute_RAMDisk;
2470*b1cdbd2cSJim Jagielski 	else if ((strncasecmp( fstype, "CD",  2) == 0)	 	// OS2:CDFS, DOS/WIN:CDROM
2471*b1cdbd2cSJim Jagielski 		|| (strncasecmp( fstype, "UDF", 3) == 0)   ) 	// OS2:UDF DVD's
2472*b1cdbd2cSJim Jagielski 		pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
2473*b1cdbd2cSJim Jagielski 	else
2474*b1cdbd2cSJim Jagielski 		pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
2475*b1cdbd2cSJim Jagielski 
2476*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
2477*b1cdbd2cSJim Jagielski }
2478*b1cdbd2cSJim Jagielski 
2479*b1cdbd2cSJim Jagielski //#############################################
is_volume_space_info_request(sal_uInt32 field_mask)2480*b1cdbd2cSJim Jagielski inline bool is_volume_space_info_request(sal_uInt32 field_mask)
2481*b1cdbd2cSJim Jagielski {
2482*b1cdbd2cSJim Jagielski 	return (field_mask &
2483*b1cdbd2cSJim Jagielski 			(osl_VolumeInfo_Mask_TotalSpace |
2484*b1cdbd2cSJim Jagielski 			 osl_VolumeInfo_Mask_UsedSpace  |
2485*b1cdbd2cSJim Jagielski 			 osl_VolumeInfo_Mask_FreeSpace));
2486*b1cdbd2cSJim Jagielski }
2487*b1cdbd2cSJim Jagielski 
2488*b1cdbd2cSJim Jagielski //#############################################
get_volume_space_information(const char * path,oslVolumeInfo * pInfo)2489*b1cdbd2cSJim Jagielski static void get_volume_space_information(const char* path, oslVolumeInfo *pInfo)
2490*b1cdbd2cSJim Jagielski {
2491*b1cdbd2cSJim Jagielski     FSALLOCATE aFSInfoBuf;
2492*b1cdbd2cSJim Jagielski     ULONG nDriveNumber = toupper( *path) - 'A' + 1;
2493*b1cdbd2cSJim Jagielski 
2494*b1cdbd2cSJim Jagielski 	// disable error popups
2495*b1cdbd2cSJim Jagielski 	DosError(FERR_DISABLEHARDERR);
2496*b1cdbd2cSJim Jagielski     APIRET rc = DosQueryFSInfo( nDriveNumber, FSIL_ALLOC,
2497*b1cdbd2cSJim Jagielski                                 &aFSInfoBuf, sizeof(aFSInfoBuf) );
2498*b1cdbd2cSJim Jagielski 	// enable error popups
2499*b1cdbd2cSJim Jagielski 	DosError(FERR_ENABLEHARDERR);
2500*b1cdbd2cSJim Jagielski 	if (!rc)
2501*b1cdbd2cSJim Jagielski 	{
2502*b1cdbd2cSJim Jagielski 		uint64_t aBytesPerCluster( uint64_t(aFSInfoBuf.cbSector) *
2503*b1cdbd2cSJim Jagielski 								 uint64_t(aFSInfoBuf.cSectorUnit) );
2504*b1cdbd2cSJim Jagielski 		pInfo->uFreeSpace = aBytesPerCluster * uint64_t(aFSInfoBuf.cUnitAvail);
2505*b1cdbd2cSJim Jagielski 		pInfo->uTotalSpace = aBytesPerCluster * uint64_t(aFSInfoBuf.cUnit);
2506*b1cdbd2cSJim Jagielski 		pInfo->uUsedSpace    = pInfo->uTotalSpace - pInfo->uFreeSpace;
2507*b1cdbd2cSJim Jagielski 		pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace |
2508*b1cdbd2cSJim Jagielski 							   osl_VolumeInfo_Mask_UsedSpace |
2509*b1cdbd2cSJim Jagielski 							   osl_VolumeInfo_Mask_FreeSpace;
2510*b1cdbd2cSJim Jagielski 	}
2511*b1cdbd2cSJim Jagielski }
2512*b1cdbd2cSJim Jagielski 
2513*b1cdbd2cSJim Jagielski //#############################################
is_filesystem_attributes_request(sal_uInt32 field_mask)2514*b1cdbd2cSJim Jagielski inline bool is_filesystem_attributes_request(sal_uInt32 field_mask)
2515*b1cdbd2cSJim Jagielski {
2516*b1cdbd2cSJim Jagielski 	return (field_mask &
2517*b1cdbd2cSJim Jagielski 			(osl_VolumeInfo_Mask_MaxNameLength |
2518*b1cdbd2cSJim Jagielski 			 osl_VolumeInfo_Mask_MaxPathLength |
2519*b1cdbd2cSJim Jagielski 			 osl_VolumeInfo_Mask_FileSystemName |
2520*b1cdbd2cSJim Jagielski 			 osl_VolumeInfo_Mask_FileSystemCaseHandling));
2521*b1cdbd2cSJim Jagielski }
2522*b1cdbd2cSJim Jagielski 
2523*b1cdbd2cSJim Jagielski //#############################################
is_drivetype_request(sal_uInt32 field_mask)2524*b1cdbd2cSJim Jagielski inline bool is_drivetype_request(sal_uInt32 field_mask)
2525*b1cdbd2cSJim Jagielski {
2526*b1cdbd2cSJim Jagielski 	return (field_mask & osl_VolumeInfo_Mask_Attributes);
2527*b1cdbd2cSJim Jagielski }
2528*b1cdbd2cSJim Jagielski 
2529*b1cdbd2cSJim Jagielski typedef struct _FSQBUFFER_
2530*b1cdbd2cSJim Jagielski {
2531*b1cdbd2cSJim Jagielski     FSQBUFFER2  aBuf;
2532*b1cdbd2cSJim Jagielski     UCHAR       sBuf[64];
2533*b1cdbd2cSJim Jagielski } FSQBUFFER_;
2534*b1cdbd2cSJim Jagielski 
2535*b1cdbd2cSJim Jagielski //#############################################
get_filesystem_attributes(const char * path,sal_uInt32 field_mask,oslVolumeInfo * pInfo)2536*b1cdbd2cSJim Jagielski static oslFileError get_filesystem_attributes(const char* path, sal_uInt32 field_mask, oslVolumeInfo* pInfo)
2537*b1cdbd2cSJim Jagielski {
2538*b1cdbd2cSJim Jagielski 	pInfo->uAttributes = 0;
2539*b1cdbd2cSJim Jagielski 
2540*b1cdbd2cSJim Jagielski 	oslFileError osl_error = osl_File_E_None;
2541*b1cdbd2cSJim Jagielski 
2542*b1cdbd2cSJim Jagielski 	// osl_get_drive_type must be called first because
2543*b1cdbd2cSJim Jagielski 	// this function resets osl_VolumeInfo_Mask_Attributes
2544*b1cdbd2cSJim Jagielski 	// on failure
2545*b1cdbd2cSJim Jagielski 	if (is_drivetype_request(field_mask))
2546*b1cdbd2cSJim Jagielski 		osl_error = get_drive_type(path, pInfo);
2547*b1cdbd2cSJim Jagielski 
2548*b1cdbd2cSJim Jagielski 	if ((osl_File_E_None == osl_error) && is_filesystem_attributes_request(field_mask))
2549*b1cdbd2cSJim Jagielski 	{
2550*b1cdbd2cSJim Jagielski 		FSQBUFFER_	aBuf;
2551*b1cdbd2cSJim Jagielski 		ULONG       nBufLen;
2552*b1cdbd2cSJim Jagielski 		APIRET      nRet;
2553*b1cdbd2cSJim Jagielski 
2554*b1cdbd2cSJim Jagielski         nBufLen = sizeof( aBuf );
2555*b1cdbd2cSJim Jagielski 		// disable error popups
2556*b1cdbd2cSJim Jagielski 		DosError(FERR_DISABLEHARDERR);
2557*b1cdbd2cSJim Jagielski         nRet = DosQueryFSAttach( (PCSZ)path, 0, FSAIL_QUERYNAME, (_FSQBUFFER2*) &aBuf, &nBufLen );
2558*b1cdbd2cSJim Jagielski         if ( !nRet )
2559*b1cdbd2cSJim Jagielski         {
2560*b1cdbd2cSJim Jagielski             char *pType = (char*)(aBuf.aBuf.szName + aBuf.aBuf.cbName + 1);
2561*b1cdbd2cSJim Jagielski 			pInfo->uValidFields   |= osl_VolumeInfo_Mask_MaxNameLength;
2562*b1cdbd2cSJim Jagielski 			pInfo->uMaxNameLength  = _MAX_FNAME;
2563*b1cdbd2cSJim Jagielski 
2564*b1cdbd2cSJim Jagielski 			pInfo->uValidFields   |= osl_VolumeInfo_Mask_MaxPathLength;
2565*b1cdbd2cSJim Jagielski 			pInfo->uMaxPathLength  = _MAX_PATH;
2566*b1cdbd2cSJim Jagielski 
2567*b1cdbd2cSJim Jagielski 			pInfo->uValidFields   |= osl_VolumeInfo_Mask_FileSystemName;
2568*b1cdbd2cSJim Jagielski 			rtl_uString_newFromAscii(&pInfo->ustrFileSystemName, pType);
2569*b1cdbd2cSJim Jagielski 
2570*b1cdbd2cSJim Jagielski 			// case is preserved always except for FAT
2571*b1cdbd2cSJim Jagielski 			if (strcmp( pType, "FAT" ))
2572*b1cdbd2cSJim Jagielski 				pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
2573*b1cdbd2cSJim Jagielski 
2574*b1cdbd2cSJim Jagielski 			pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2575*b1cdbd2cSJim Jagielski 		}
2576*b1cdbd2cSJim Jagielski 		// enable error popups
2577*b1cdbd2cSJim Jagielski 		DosError(FERR_ENABLEHARDERR);
2578*b1cdbd2cSJim Jagielski 	}
2579*b1cdbd2cSJim Jagielski 	return osl_error;
2580*b1cdbd2cSJim Jagielski }
2581*b1cdbd2cSJim Jagielski 
osl_getVolumeInformation(rtl_uString * ustrDirectoryURL,oslVolumeInfo * pInfo,sal_uInt32 uFieldMask)2582*b1cdbd2cSJim Jagielski oslFileError SAL_CALL osl_getVolumeInformation( rtl_uString* ustrDirectoryURL, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask )
2583*b1cdbd2cSJim Jagielski {
2584*b1cdbd2cSJim Jagielski     char volume_root[PATH_MAX];
2585*b1cdbd2cSJim Jagielski     oslFileError error;
2586*b1cdbd2cSJim Jagielski 
2587*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrDirectoryURL );
2588*b1cdbd2cSJim Jagielski     OSL_ASSERT( pInfo );
2589*b1cdbd2cSJim Jagielski 
2590*b1cdbd2cSJim Jagielski     /* convert directory url to system path */
2591*b1cdbd2cSJim Jagielski     error = FileURLToPath( volume_root, PATH_MAX, ustrDirectoryURL );
2592*b1cdbd2cSJim Jagielski     if( error != osl_File_E_None )
2593*b1cdbd2cSJim Jagielski         return error;
2594*b1cdbd2cSJim Jagielski 
2595*b1cdbd2cSJim Jagielski 	if (!pInfo)
2596*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
2597*b1cdbd2cSJim Jagielski 
2598*b1cdbd2cSJim Jagielski 	pInfo->uValidFields = 0;
2599*b1cdbd2cSJim Jagielski 
2600*b1cdbd2cSJim Jagielski     if ((error = get_filesystem_attributes(volume_root, uFieldMask, pInfo)) != osl_File_E_None)
2601*b1cdbd2cSJim Jagielski         return error;
2602*b1cdbd2cSJim Jagielski 
2603*b1cdbd2cSJim Jagielski 	if (is_volume_space_info_request(uFieldMask))
2604*b1cdbd2cSJim Jagielski 	    get_volume_space_information(volume_root, pInfo);
2605*b1cdbd2cSJim Jagielski 
2606*b1cdbd2cSJim Jagielski 	if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
2607*b1cdbd2cSJim Jagielski 	{
2608*b1cdbd2cSJim Jagielski 		pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
2609*b1cdbd2cSJim Jagielski 		rtl_uString* uVolumeRoot;
2610*b1cdbd2cSJim Jagielski 		rtl_uString_newFromAscii( &uVolumeRoot, volume_root);
2611*b1cdbd2cSJim Jagielski 		osl_getFileURLFromSystemPath( uVolumeRoot, (rtl_uString**)&pInfo->pDeviceHandle);
2612*b1cdbd2cSJim Jagielski 		rtl_uString_release( uVolumeRoot);
2613*b1cdbd2cSJim Jagielski 	}
2614*b1cdbd2cSJim Jagielski 
2615*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
2616*b1cdbd2cSJim Jagielski }
2617*b1cdbd2cSJim Jagielski 
2618*b1cdbd2cSJim Jagielski /****************************************************************************/
2619*b1cdbd2cSJim Jagielski /*	osl_getFileStatus */
2620*b1cdbd2cSJim Jagielski /****************************************************************************/
_osl_getDriveInfo(oslDirectoryItem Item,oslFileStatus * pStatus,sal_uInt32 uFieldMask)2621*b1cdbd2cSJim Jagielski static oslFileError _osl_getDriveInfo(
2622*b1cdbd2cSJim Jagielski 	oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask)
2623*b1cdbd2cSJim Jagielski {
2624*b1cdbd2cSJim Jagielski 	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
2625*b1cdbd2cSJim Jagielski 	sal_Unicode			cDrive[3];
2626*b1cdbd2cSJim Jagielski 	sal_Unicode			cRoot[4];
2627*b1cdbd2cSJim Jagielski 
2628*b1cdbd2cSJim Jagielski 	if ( !pItemImpl )
2629*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
2630*b1cdbd2cSJim Jagielski 
2631*b1cdbd2cSJim Jagielski 	pStatus->uValidFields = 0;
2632*b1cdbd2cSJim Jagielski 
2633*b1cdbd2cSJim Jagielski 	cDrive[0] = pItemImpl->ustrDrive->buffer[0];
2634*b1cdbd2cSJim Jagielski 	cDrive[1] = (sal_Unicode)':';
2635*b1cdbd2cSJim Jagielski 	cDrive[2] = 0;
2636*b1cdbd2cSJim Jagielski 	cRoot[0] = pItemImpl->ustrDrive->buffer[0];
2637*b1cdbd2cSJim Jagielski 	cRoot[1] = (sal_Unicode)':';
2638*b1cdbd2cSJim Jagielski 	cRoot[2] = 0;
2639*b1cdbd2cSJim Jagielski 
2640*b1cdbd2cSJim Jagielski 	if ( uFieldMask & osl_FileStatus_Mask_FileName )
2641*b1cdbd2cSJim Jagielski 	{
2642*b1cdbd2cSJim Jagielski 		if ( pItemImpl->ustrDrive->buffer[0] == '\\' &&
2643*b1cdbd2cSJim Jagielski 			pItemImpl->ustrDrive->buffer[1] == '\\' )
2644*b1cdbd2cSJim Jagielski 		{
2645*b1cdbd2cSJim Jagielski 			LPCWSTR	lpFirstBkSlash = wcschr( (const wchar_t*)&pItemImpl->ustrDrive->buffer[2], '\\' );
2646*b1cdbd2cSJim Jagielski 
2647*b1cdbd2cSJim Jagielski 			if ( lpFirstBkSlash && lpFirstBkSlash[1] )
2648*b1cdbd2cSJim Jagielski 			{
2649*b1cdbd2cSJim Jagielski 				LPCWSTR	lpLastBkSlash = wcschr( (const wchar_t*)&lpFirstBkSlash[1], '\\' );
2650*b1cdbd2cSJim Jagielski 
2651*b1cdbd2cSJim Jagielski 				if ( lpLastBkSlash )
2652*b1cdbd2cSJim Jagielski 					rtl_uString_newFromStr_WithLength( &pStatus->ustrFileName, (sal_Unicode*)&lpFirstBkSlash[1], lpLastBkSlash - lpFirstBkSlash - 1 );
2653*b1cdbd2cSJim Jagielski 				else
2654*b1cdbd2cSJim Jagielski 					rtl_uString_newFromStr( &pStatus->ustrFileName, (sal_Unicode*)&lpFirstBkSlash[1] );
2655*b1cdbd2cSJim Jagielski 				pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
2656*b1cdbd2cSJim Jagielski 			}
2657*b1cdbd2cSJim Jagielski 		}
2658*b1cdbd2cSJim Jagielski 		else
2659*b1cdbd2cSJim Jagielski 		{
2660*b1cdbd2cSJim Jagielski 			FSINFO	aFSInfoBuf;
2661*b1cdbd2cSJim Jagielski 			ULONG   ulFSInfoLevel = FSIL_VOLSER;
2662*b1cdbd2cSJim Jagielski 			ULONG   nDriveNumber;
2663*b1cdbd2cSJim Jagielski 			char	szFileName[ _MAX_PATH];
2664*b1cdbd2cSJim Jagielski 
2665*b1cdbd2cSJim Jagielski 			nDriveNumber = toupper(*cDrive) - 'A' + 1;
2666*b1cdbd2cSJim Jagielski 			memset( &aFSInfoBuf, 0, sizeof(FSINFO) );
2667*b1cdbd2cSJim Jagielski 			// disable error popups
2668*b1cdbd2cSJim Jagielski 			DosError(FERR_DISABLEHARDERR);
2669*b1cdbd2cSJim Jagielski 			APIRET rc = DosQueryFSInfo( nDriveNumber, ulFSInfoLevel, &aFSInfoBuf, sizeof(FSINFO) );
2670*b1cdbd2cSJim Jagielski 			// enable error popups
2671*b1cdbd2cSJim Jagielski 			DosError(FERR_ENABLEHARDERR);
2672*b1cdbd2cSJim Jagielski 			memset( szFileName, 0, sizeof( szFileName));
2673*b1cdbd2cSJim Jagielski 			*szFileName = toupper(*cDrive);
2674*b1cdbd2cSJim Jagielski 			strcat( szFileName, ": [");
2675*b1cdbd2cSJim Jagielski 			if ( !rc || aFSInfoBuf.vol.cch)
2676*b1cdbd2cSJim Jagielski 				strncat( szFileName, aFSInfoBuf.vol.szVolLabel, aFSInfoBuf.vol.cch);
2677*b1cdbd2cSJim Jagielski 			strcat( szFileName, "]");
2678*b1cdbd2cSJim Jagielski 			rtl_uString_newFromAscii( &pStatus->ustrFileName, szFileName );
2679*b1cdbd2cSJim Jagielski 
2680*b1cdbd2cSJim Jagielski 			pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
2681*b1cdbd2cSJim Jagielski 		}
2682*b1cdbd2cSJim Jagielski 	}
2683*b1cdbd2cSJim Jagielski 
2684*b1cdbd2cSJim Jagielski 	pStatus->eType = osl_File_Type_Volume;
2685*b1cdbd2cSJim Jagielski 	pStatus->uValidFields |= osl_FileStatus_Mask_Type;
2686*b1cdbd2cSJim Jagielski 
2687*b1cdbd2cSJim Jagielski 	if ( uFieldMask & osl_FileStatus_Mask_FileURL )
2688*b1cdbd2cSJim Jagielski 	{
2689*b1cdbd2cSJim Jagielski 		rtl_uString	*ustrSystemPath = NULL;
2690*b1cdbd2cSJim Jagielski 
2691*b1cdbd2cSJim Jagielski 		rtl_uString_newFromStr( &ustrSystemPath, pItemImpl->ustrDrive->buffer );
2692*b1cdbd2cSJim Jagielski 		osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
2693*b1cdbd2cSJim Jagielski 		rtl_uString_release( ustrSystemPath );
2694*b1cdbd2cSJim Jagielski 		pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
2695*b1cdbd2cSJim Jagielski 	}
2696*b1cdbd2cSJim Jagielski 
2697*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
2698*b1cdbd2cSJim Jagielski }
2699*b1cdbd2cSJim Jagielski 
osl_getFileStatus(oslDirectoryItem Item,oslFileStatus * pStatus,sal_uInt32 uFieldMask)2700*b1cdbd2cSJim Jagielski oslFileError SAL_CALL osl_getFileStatus(
2701*b1cdbd2cSJim Jagielski     oslDirectoryItem Item,
2702*b1cdbd2cSJim Jagielski     oslFileStatus *pStatus,
2703*b1cdbd2cSJim Jagielski     sal_uInt32 uFieldMask )
2704*b1cdbd2cSJim Jagielski {
2705*b1cdbd2cSJim Jagielski 	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
2706*b1cdbd2cSJim Jagielski 	struct stat file_stat;
2707*b1cdbd2cSJim Jagielski 
2708*b1cdbd2cSJim Jagielski 	if ( !pItemImpl )
2709*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
2710*b1cdbd2cSJim Jagielski 
2711*b1cdbd2cSJim Jagielski 	if ( pItemImpl->uType == DIRECTORYITEM_DRIVE)
2712*b1cdbd2cSJim Jagielski 		return _osl_getDriveInfo( Item, pStatus, uFieldMask );
2713*b1cdbd2cSJim Jagielski 
2714*b1cdbd2cSJim Jagielski 	osl::lstat(pItemImpl->ustrFilePath, file_stat);
2715*b1cdbd2cSJim Jagielski 	if ( uFieldMask & osl_FileStatus_Mask_Validate )
2716*b1cdbd2cSJim Jagielski 	{
2717*b1cdbd2cSJim Jagielski 		uFieldMask &= ~	osl_FileStatus_Mask_Validate;
2718*b1cdbd2cSJim Jagielski 	}
2719*b1cdbd2cSJim Jagielski 
2720*b1cdbd2cSJim Jagielski 	/* If no fields to retrieve left ignore pStatus */
2721*b1cdbd2cSJim Jagielski 	if ( !uFieldMask )
2722*b1cdbd2cSJim Jagielski 		return osl_File_E_None;
2723*b1cdbd2cSJim Jagielski 
2724*b1cdbd2cSJim Jagielski 	/* Otherwise, this must be a valid pointer */
2725*b1cdbd2cSJim Jagielski 	if ( !pStatus )
2726*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
2727*b1cdbd2cSJim Jagielski 
2728*b1cdbd2cSJim Jagielski 	if ( pStatus->uStructSize != sizeof(oslFileStatus) )
2729*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
2730*b1cdbd2cSJim Jagielski 
2731*b1cdbd2cSJim Jagielski 	pStatus->uValidFields = 0;
2732*b1cdbd2cSJim Jagielski 
2733*b1cdbd2cSJim Jagielski 	/* File time stamps */
2734*b1cdbd2cSJim Jagielski 
2735*b1cdbd2cSJim Jagielski 	if ( (uFieldMask & osl_FileStatus_Mask_ModifyTime))
2736*b1cdbd2cSJim Jagielski 	{
2737*b1cdbd2cSJim Jagielski 	    pStatus->aModifyTime.Seconds  = file_stat.st_mtime;
2738*b1cdbd2cSJim Jagielski     	pStatus->aModifyTime.Nanosec  = 0;
2739*b1cdbd2cSJim Jagielski 		pStatus->uValidFields |= osl_FileStatus_Mask_ModifyTime;
2740*b1cdbd2cSJim Jagielski 	}
2741*b1cdbd2cSJim Jagielski 
2742*b1cdbd2cSJim Jagielski 	if ( (uFieldMask & osl_FileStatus_Mask_AccessTime))
2743*b1cdbd2cSJim Jagielski 	{
2744*b1cdbd2cSJim Jagielski 		pStatus->aAccessTime.Seconds  = file_stat.st_atime;
2745*b1cdbd2cSJim Jagielski     	pStatus->aAccessTime.Nanosec  = 0;
2746*b1cdbd2cSJim Jagielski 		pStatus->uValidFields |= osl_FileStatus_Mask_AccessTime;
2747*b1cdbd2cSJim Jagielski 	}
2748*b1cdbd2cSJim Jagielski 
2749*b1cdbd2cSJim Jagielski 	if ( (uFieldMask & osl_FileStatus_Mask_CreationTime))
2750*b1cdbd2cSJim Jagielski 	{
2751*b1cdbd2cSJim Jagielski 		pStatus->aAccessTime.Seconds  = file_stat.st_birthtime;
2752*b1cdbd2cSJim Jagielski     	pStatus->aAccessTime.Nanosec  = 0;
2753*b1cdbd2cSJim Jagielski 		pStatus->uValidFields |= osl_FileStatus_Mask_CreationTime;
2754*b1cdbd2cSJim Jagielski 	}
2755*b1cdbd2cSJim Jagielski 
2756*b1cdbd2cSJim Jagielski 	/* Most of the fields are already set, regardless of requiered fields */
2757*b1cdbd2cSJim Jagielski 
2758*b1cdbd2cSJim Jagielski 	osl_systemPathGetFileNameOrLastDirectoryPart(pItemImpl->ustrFilePath, &pStatus->ustrFileName);
2759*b1cdbd2cSJim Jagielski 	pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
2760*b1cdbd2cSJim Jagielski 
2761*b1cdbd2cSJim Jagielski 	if (S_ISLNK(file_stat.st_mode))
2762*b1cdbd2cSJim Jagielski 	   pStatus->eType = osl_File_Type_Link;
2763*b1cdbd2cSJim Jagielski 	else if (S_ISDIR(file_stat.st_mode))
2764*b1cdbd2cSJim Jagielski 	   pStatus->eType = osl_File_Type_Directory;
2765*b1cdbd2cSJim Jagielski 	else if (S_ISREG(file_stat.st_mode))
2766*b1cdbd2cSJim Jagielski 	   pStatus->eType = osl_File_Type_Regular;
2767*b1cdbd2cSJim Jagielski 	else if (S_ISFIFO(file_stat.st_mode))
2768*b1cdbd2cSJim Jagielski 	   pStatus->eType = osl_File_Type_Fifo;
2769*b1cdbd2cSJim Jagielski 	else if (S_ISSOCK(file_stat.st_mode))
2770*b1cdbd2cSJim Jagielski 	   pStatus->eType = osl_File_Type_Socket;
2771*b1cdbd2cSJim Jagielski 	else if (S_ISCHR(file_stat.st_mode) || S_ISBLK(file_stat.st_mode))
2772*b1cdbd2cSJim Jagielski 	   pStatus->eType = osl_File_Type_Special;
2773*b1cdbd2cSJim Jagielski 	else
2774*b1cdbd2cSJim Jagielski 	   pStatus->eType = osl_File_Type_Unknown;
2775*b1cdbd2cSJim Jagielski 
2776*b1cdbd2cSJim Jagielski 	pStatus->uValidFields |= osl_FileStatus_Mask_Type;
2777*b1cdbd2cSJim Jagielski 
2778*b1cdbd2cSJim Jagielski 	pStatus->uAttributes = pItemImpl->d_attr;
2779*b1cdbd2cSJim Jagielski 	pStatus->uValidFields |= osl_FileStatus_Mask_Attributes;
2780*b1cdbd2cSJim Jagielski 
2781*b1cdbd2cSJim Jagielski 	pStatus->uFileSize = file_stat.st_size;
2782*b1cdbd2cSJim Jagielski 	pStatus->uValidFields |= osl_FileStatus_Mask_FileSize;
2783*b1cdbd2cSJim Jagielski 
2784*b1cdbd2cSJim Jagielski 	if ( uFieldMask & osl_FileStatus_Mask_LinkTargetURL )
2785*b1cdbd2cSJim Jagielski 	{
2786*b1cdbd2cSJim Jagielski 		rtl_uString	*ustrFullPath = NULL;
2787*b1cdbd2cSJim Jagielski 
2788*b1cdbd2cSJim Jagielski 		rtl_uString_newFromStr( &ustrFullPath, rtl_uString_getStr(pItemImpl->ustrFilePath) );
2789*b1cdbd2cSJim Jagielski 		osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrLinkTargetURL );
2790*b1cdbd2cSJim Jagielski 		rtl_uString_release( ustrFullPath );
2791*b1cdbd2cSJim Jagielski 
2792*b1cdbd2cSJim Jagielski 		pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL;
2793*b1cdbd2cSJim Jagielski 	}
2794*b1cdbd2cSJim Jagielski 
2795*b1cdbd2cSJim Jagielski 	if ( uFieldMask & osl_FileStatus_Mask_FileURL )
2796*b1cdbd2cSJim Jagielski 	{
2797*b1cdbd2cSJim Jagielski 		rtl_uString	*ustrFullPath = NULL;
2798*b1cdbd2cSJim Jagielski 
2799*b1cdbd2cSJim Jagielski 		rtl_uString_newFromStr( &ustrFullPath, rtl_uString_getStr(pItemImpl->ustrFilePath) );
2800*b1cdbd2cSJim Jagielski 		osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrFileURL );
2801*b1cdbd2cSJim Jagielski 		rtl_uString_release( ustrFullPath );
2802*b1cdbd2cSJim Jagielski 		pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
2803*b1cdbd2cSJim Jagielski 	}
2804*b1cdbd2cSJim Jagielski 
2805*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
2806*b1cdbd2cSJim Jagielski }
2807*b1cdbd2cSJim Jagielski 
2808*b1cdbd2cSJim Jagielski /****************************************************************************/
2809*b1cdbd2cSJim Jagielski /*	osl_createDirectory */
2810*b1cdbd2cSJim Jagielski /****************************************************************************/
2811*b1cdbd2cSJim Jagielski 
osl_createDirectory(rtl_uString * ustrDirectoryURL)2812*b1cdbd2cSJim Jagielski oslFileError osl_createDirectory( rtl_uString* ustrDirectoryURL )
2813*b1cdbd2cSJim Jagielski {
2814*b1cdbd2cSJim Jagielski     char path[PATH_MAX];
2815*b1cdbd2cSJim Jagielski     oslFileError eRet;
2816*b1cdbd2cSJim Jagielski 	APIRET rc;
2817*b1cdbd2cSJim Jagielski 
2818*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrDirectoryURL );
2819*b1cdbd2cSJim Jagielski 
2820*b1cdbd2cSJim Jagielski     /* convert directory url to system path */
2821*b1cdbd2cSJim Jagielski     eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
2822*b1cdbd2cSJim Jagielski     if( eRet != osl_File_E_None )
2823*b1cdbd2cSJim Jagielski         return eRet;
2824*b1cdbd2cSJim Jagielski 
2825*b1cdbd2cSJim Jagielski     rc = DosCreateDir( (PCSZ)path, NULL);
2826*b1cdbd2cSJim Jagielski     if (rc == ERROR_ACCESS_DENIED)
2827*b1cdbd2cSJim Jagielski        rc=ERROR_FILE_EXISTS;
2828*b1cdbd2cSJim Jagielski 
2829*b1cdbd2cSJim Jagielski     if (!rc)
2830*b1cdbd2cSJim Jagielski         eRet = osl_File_E_None;
2831*b1cdbd2cSJim Jagielski     else
2832*b1cdbd2cSJim Jagielski         eRet = MapError( rc);
2833*b1cdbd2cSJim Jagielski 
2834*b1cdbd2cSJim Jagielski     return eRet;
2835*b1cdbd2cSJim Jagielski }
2836*b1cdbd2cSJim Jagielski 
2837*b1cdbd2cSJim Jagielski /****************************************************************************/
2838*b1cdbd2cSJim Jagielski /*	osl_removeDirectory */
2839*b1cdbd2cSJim Jagielski /****************************************************************************/
2840*b1cdbd2cSJim Jagielski 
osl_removeDirectory(rtl_uString * ustrDirectoryURL)2841*b1cdbd2cSJim Jagielski oslFileError osl_removeDirectory( rtl_uString* ustrDirectoryURL )
2842*b1cdbd2cSJim Jagielski {
2843*b1cdbd2cSJim Jagielski     char path[PATH_MAX];
2844*b1cdbd2cSJim Jagielski     oslFileError eRet;
2845*b1cdbd2cSJim Jagielski 	APIRET rc;
2846*b1cdbd2cSJim Jagielski 
2847*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrDirectoryURL );
2848*b1cdbd2cSJim Jagielski 
2849*b1cdbd2cSJim Jagielski     /* convert directory url to system path */
2850*b1cdbd2cSJim Jagielski     eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
2851*b1cdbd2cSJim Jagielski     if( eRet != osl_File_E_None )
2852*b1cdbd2cSJim Jagielski         return eRet;
2853*b1cdbd2cSJim Jagielski 
2854*b1cdbd2cSJim Jagielski     rc = DosDeleteDir( (PCSZ)path);
2855*b1cdbd2cSJim Jagielski     if (!rc)
2856*b1cdbd2cSJim Jagielski         eRet = osl_File_E_None;
2857*b1cdbd2cSJim Jagielski     else
2858*b1cdbd2cSJim Jagielski         eRet = MapError( rc);
2859*b1cdbd2cSJim Jagielski 
2860*b1cdbd2cSJim Jagielski     return eRet;
2861*b1cdbd2cSJim Jagielski }
2862*b1cdbd2cSJim Jagielski 
2863*b1cdbd2cSJim Jagielski //#############################################
path_make_parent(sal_Unicode * path)2864*b1cdbd2cSJim Jagielski int path_make_parent(sal_Unicode* path)
2865*b1cdbd2cSJim Jagielski {
2866*b1cdbd2cSJim Jagielski 	int i = rtl_ustr_lastIndexOfChar(path, '/');
2867*b1cdbd2cSJim Jagielski 	if (i == -1)
2868*b1cdbd2cSJim Jagielski 		i = rtl_ustr_lastIndexOfChar(path, '\\');
2869*b1cdbd2cSJim Jagielski 
2870*b1cdbd2cSJim Jagielski 	if (i > 0)
2871*b1cdbd2cSJim Jagielski 	{
2872*b1cdbd2cSJim Jagielski 		*(path + i) = 0;
2873*b1cdbd2cSJim Jagielski 		return i;
2874*b1cdbd2cSJim Jagielski 	}
2875*b1cdbd2cSJim Jagielski 	else
2876*b1cdbd2cSJim Jagielski 		return 0;
2877*b1cdbd2cSJim Jagielski }
2878*b1cdbd2cSJim Jagielski 
2879*b1cdbd2cSJim Jagielski //#############################################
create_dir_with_callback(sal_Unicode * directory_path,oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,void * pData)2880*b1cdbd2cSJim Jagielski int create_dir_with_callback(
2881*b1cdbd2cSJim Jagielski 	sal_Unicode* directory_path,
2882*b1cdbd2cSJim Jagielski     oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
2883*b1cdbd2cSJim Jagielski     void* pData)
2884*b1cdbd2cSJim Jagielski {
2885*b1cdbd2cSJim Jagielski 	int mode = S_IRWXU | S_IRWXG | S_IRWXO;
2886*b1cdbd2cSJim Jagielski 
2887*b1cdbd2cSJim Jagielski 	if (osl::mkdir(directory_path, mode) == 0)
2888*b1cdbd2cSJim Jagielski     {
2889*b1cdbd2cSJim Jagielski     	if (aDirectoryCreationCallbackFunc)
2890*b1cdbd2cSJim Jagielski         {
2891*b1cdbd2cSJim Jagielski         	rtl::OUString url;
2892*b1cdbd2cSJim Jagielski             osl::FileBase::getFileURLFromSystemPath(directory_path, url);
2893*b1cdbd2cSJim Jagielski             aDirectoryCreationCallbackFunc(pData, url.pData);
2894*b1cdbd2cSJim Jagielski         }
2895*b1cdbd2cSJim Jagielski         return 0;
2896*b1cdbd2cSJim Jagielski     }
2897*b1cdbd2cSJim Jagielski     return errno;
2898*b1cdbd2cSJim Jagielski }
2899*b1cdbd2cSJim Jagielski 
2900*b1cdbd2cSJim Jagielski //#############################################
create_dir_recursively_(sal_Unicode * dir_path,oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,void * pData)2901*b1cdbd2cSJim Jagielski oslFileError create_dir_recursively_(
2902*b1cdbd2cSJim Jagielski 	sal_Unicode* dir_path,
2903*b1cdbd2cSJim Jagielski     oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
2904*b1cdbd2cSJim Jagielski     void* pData)
2905*b1cdbd2cSJim Jagielski {
2906*b1cdbd2cSJim Jagielski 	OSL_PRECOND((rtl_ustr_getLength(dir_path) > 0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/'))), \
2907*b1cdbd2cSJim Jagielski 	"Path must not end with a slash");
2908*b1cdbd2cSJim Jagielski 
2909*b1cdbd2cSJim Jagielski 	int native_err = create_dir_with_callback(
2910*b1cdbd2cSJim Jagielski     	dir_path, aDirectoryCreationCallbackFunc, pData);
2911*b1cdbd2cSJim Jagielski 
2912*b1cdbd2cSJim Jagielski 	if (native_err == 0)
2913*b1cdbd2cSJim Jagielski         return osl_File_E_None;
2914*b1cdbd2cSJim Jagielski 
2915*b1cdbd2cSJim Jagielski     if (native_err != ENOENT)
2916*b1cdbd2cSJim Jagielski     	return oslTranslateFileError(OSL_FET_ERROR, native_err);
2917*b1cdbd2cSJim Jagielski 
2918*b1cdbd2cSJim Jagielski 	// we step back until '/a_dir' at maximum because
2919*b1cdbd2cSJim Jagielski 	// we should get an error unequal ENOENT when
2920*b1cdbd2cSJim Jagielski 	// we try to create 'a_dir' at '/' and would so
2921*b1cdbd2cSJim Jagielski 	// return before
2922*b1cdbd2cSJim Jagielski 	int pos = path_make_parent(dir_path);
2923*b1cdbd2cSJim Jagielski 
2924*b1cdbd2cSJim Jagielski     oslFileError osl_error = create_dir_recursively_(
2925*b1cdbd2cSJim Jagielski     	dir_path, aDirectoryCreationCallbackFunc, pData);
2926*b1cdbd2cSJim Jagielski 
2927*b1cdbd2cSJim Jagielski     if (osl_File_E_None != osl_error)
2928*b1cdbd2cSJim Jagielski     	return osl_error;
2929*b1cdbd2cSJim Jagielski 
2930*b1cdbd2cSJim Jagielski    	dir_path[pos] = '/';
2931*b1cdbd2cSJim Jagielski 
2932*b1cdbd2cSJim Jagielski     return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
2933*b1cdbd2cSJim Jagielski }
2934*b1cdbd2cSJim Jagielski 
2935*b1cdbd2cSJim Jagielski //#######################################
osl_createDirectoryPath(rtl_uString * aDirectoryUrl,oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,void * pData)2936*b1cdbd2cSJim Jagielski oslFileError SAL_CALL osl_createDirectoryPath(
2937*b1cdbd2cSJim Jagielski 	rtl_uString* aDirectoryUrl,
2938*b1cdbd2cSJim Jagielski     oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
2939*b1cdbd2cSJim Jagielski     void* pData)
2940*b1cdbd2cSJim Jagielski {
2941*b1cdbd2cSJim Jagielski     if (aDirectoryUrl == NULL)
2942*b1cdbd2cSJim Jagielski         return osl_File_E_INVAL;
2943*b1cdbd2cSJim Jagielski 
2944*b1cdbd2cSJim Jagielski     rtl::OUString sys_path;
2945*b1cdbd2cSJim Jagielski     oslFileError osl_error = osl_getSystemPathFromFileURL_Ex(
2946*b1cdbd2cSJim Jagielski         aDirectoryUrl, &sys_path.pData, sal_False);
2947*b1cdbd2cSJim Jagielski 
2948*b1cdbd2cSJim Jagielski     if (osl_error != osl_File_E_None)
2949*b1cdbd2cSJim Jagielski         return osl_error;
2950*b1cdbd2cSJim Jagielski 
2951*b1cdbd2cSJim Jagielski     osl::systemPathRemoveSeparator(sys_path);
2952*b1cdbd2cSJim Jagielski 
2953*b1cdbd2cSJim Jagielski     // const_cast because sys_path is a local copy which we want to modify inplace instead of
2954*b1cdbd2cSJim Jagielski     // coyp it into another buffer on the heap again
2955*b1cdbd2cSJim Jagielski 	return create_dir_recursively_(sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData);
2956*b1cdbd2cSJim Jagielski }
2957*b1cdbd2cSJim Jagielski 
2958*b1cdbd2cSJim Jagielski /****************************************************************************/
2959*b1cdbd2cSJim Jagielski /*	osl_getCanonicalName */
2960*b1cdbd2cSJim Jagielski /****************************************************************************/
2961*b1cdbd2cSJim Jagielski 
osl_getCanonicalName(rtl_uString * ustrFileURL,rtl_uString ** pustrValidURL)2962*b1cdbd2cSJim Jagielski oslFileError osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uString** pustrValidURL )
2963*b1cdbd2cSJim Jagielski {
2964*b1cdbd2cSJim Jagielski 	OSL_ENSURE(sal_False, "osl_getCanonicalName not implemented");
2965*b1cdbd2cSJim Jagielski 
2966*b1cdbd2cSJim Jagielski 	rtl_uString_newFromString(pustrValidURL, ustrFileURL);
2967*b1cdbd2cSJim Jagielski 	return osl_File_E_None;
2968*b1cdbd2cSJim Jagielski }
2969*b1cdbd2cSJim Jagielski 
2970*b1cdbd2cSJim Jagielski 
2971*b1cdbd2cSJim Jagielski /****************************************************************************/
2972*b1cdbd2cSJim Jagielski /*	osl_setFileAttributes */
2973*b1cdbd2cSJim Jagielski /****************************************************************************/
2974*b1cdbd2cSJim Jagielski 
osl_setFileAttributes(rtl_uString * ustrFileURL,sal_uInt64 uAttributes)2975*b1cdbd2cSJim Jagielski oslFileError osl_setFileAttributes( rtl_uString* ustrFileURL, sal_uInt64 uAttributes )
2976*b1cdbd2cSJim Jagielski {
2977*b1cdbd2cSJim Jagielski     char         path[PATH_MAX];
2978*b1cdbd2cSJim Jagielski     oslFileError eRet;
2979*b1cdbd2cSJim Jagielski     FILESTATUS3  fsts3ConfigInfo;
2980*b1cdbd2cSJim Jagielski     ULONG        ulBufSize     = sizeof(FILESTATUS3);
2981*b1cdbd2cSJim Jagielski     APIRET       rc            = NO_ERROR;
2982*b1cdbd2cSJim Jagielski 
2983*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrFileURL );
2984*b1cdbd2cSJim Jagielski 
2985*b1cdbd2cSJim Jagielski     /* convert file url to system path */
2986*b1cdbd2cSJim Jagielski     eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
2987*b1cdbd2cSJim Jagielski     if( eRet != osl_File_E_None )
2988*b1cdbd2cSJim Jagielski         return eRet;
2989*b1cdbd2cSJim Jagielski 
2990*b1cdbd2cSJim Jagielski     /* query current attributes */
2991*b1cdbd2cSJim Jagielski     rc = DosQueryPathInfo( (PCSZ)path, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize);
2992*b1cdbd2cSJim Jagielski     if (rc != NO_ERROR)
2993*b1cdbd2cSJim Jagielski         return MapError( rc);
2994*b1cdbd2cSJim Jagielski 
2995*b1cdbd2cSJim Jagielski     /* set/reset readonly/hidden (see w32\file.cxx) */
2996*b1cdbd2cSJim Jagielski     fsts3ConfigInfo.attrFile &= ~(FILE_READONLY | FILE_HIDDEN);
2997*b1cdbd2cSJim Jagielski     if ( uAttributes & osl_File_Attribute_ReadOnly )
2998*b1cdbd2cSJim Jagielski         fsts3ConfigInfo.attrFile |= FILE_READONLY;
2999*b1cdbd2cSJim Jagielski     if ( uAttributes & osl_File_Attribute_Hidden )
3000*b1cdbd2cSJim Jagielski         fsts3ConfigInfo.attrFile |= FILE_HIDDEN;
3001*b1cdbd2cSJim Jagielski 
3002*b1cdbd2cSJim Jagielski     /* write new attributes */
3003*b1cdbd2cSJim Jagielski     rc = DosSetPathInfo( (PCSZ)path, FIL_STANDARD, &fsts3ConfigInfo, ulBufSize, 0);
3004*b1cdbd2cSJim Jagielski     if (rc != NO_ERROR)
3005*b1cdbd2cSJim Jagielski         return MapError( rc);
3006*b1cdbd2cSJim Jagielski 
3007*b1cdbd2cSJim Jagielski     /* everything ok */
3008*b1cdbd2cSJim Jagielski     return osl_File_E_None;
3009*b1cdbd2cSJim Jagielski }
3010*b1cdbd2cSJim Jagielski 
3011*b1cdbd2cSJim Jagielski /****************************************************************************/
3012*b1cdbd2cSJim Jagielski /*	osl_setFileTime */
3013*b1cdbd2cSJim Jagielski /****************************************************************************/
3014*b1cdbd2cSJim Jagielski 
osl_setFileTime(rtl_uString * ustrFileURL,const TimeValue * pCreationTime,const TimeValue * pLastAccessTime,const TimeValue * pLastWriteTime)3015*b1cdbd2cSJim Jagielski oslFileError osl_setFileTime( rtl_uString* ustrFileURL, const TimeValue* pCreationTime,
3016*b1cdbd2cSJim Jagielski                               const TimeValue* pLastAccessTime, const TimeValue* pLastWriteTime )
3017*b1cdbd2cSJim Jagielski {
3018*b1cdbd2cSJim Jagielski     char path[PATH_MAX];
3019*b1cdbd2cSJim Jagielski     oslFileError eRet;
3020*b1cdbd2cSJim Jagielski 
3021*b1cdbd2cSJim Jagielski     OSL_ASSERT( ustrFileURL );
3022*b1cdbd2cSJim Jagielski 
3023*b1cdbd2cSJim Jagielski     /* convert file url to system path */
3024*b1cdbd2cSJim Jagielski     eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
3025*b1cdbd2cSJim Jagielski     if( eRet != osl_File_E_None )
3026*b1cdbd2cSJim Jagielski         return eRet;
3027*b1cdbd2cSJim Jagielski 
3028*b1cdbd2cSJim Jagielski     return osl_psz_setFileTime( path, pCreationTime, pLastAccessTime, pLastWriteTime );
3029*b1cdbd2cSJim Jagielski }
3030*b1cdbd2cSJim Jagielski 
3031*b1cdbd2cSJim Jagielski /******************************************************************************
3032*b1cdbd2cSJim Jagielski  *
3033*b1cdbd2cSJim Jagielski  *                  Exported Module Functions
3034*b1cdbd2cSJim Jagielski  *             (independent of C or Unicode Strings)
3035*b1cdbd2cSJim Jagielski  *
3036*b1cdbd2cSJim Jagielski  *****************************************************************************/
3037*b1cdbd2cSJim Jagielski 
3038*b1cdbd2cSJim Jagielski 
3039*b1cdbd2cSJim Jagielski 
3040*b1cdbd2cSJim Jagielski /******************************************************************************
3041*b1cdbd2cSJim Jagielski  *
3042*b1cdbd2cSJim Jagielski  *                  C-String Versions of Exported Module Functions
3043*b1cdbd2cSJim Jagielski  *
3044*b1cdbd2cSJim Jagielski  *****************************************************************************/
3045*b1cdbd2cSJim Jagielski 
3046*b1cdbd2cSJim Jagielski 
3047*b1cdbd2cSJim Jagielski /******************************************
3048*b1cdbd2cSJim Jagielski  * osl_psz_setFileTime
3049*b1cdbd2cSJim Jagielski  *****************************************/
3050*b1cdbd2cSJim Jagielski 
osl_psz_setFileTime(const sal_Char * pszFilePath,const TimeValue *,const TimeValue * pLastAccessTime,const TimeValue * pLastWriteTime)3051*b1cdbd2cSJim Jagielski static oslFileError osl_psz_setFileTime( const sal_Char* pszFilePath,
3052*b1cdbd2cSJim Jagielski                                   const TimeValue* /*pCreationTime*/,
3053*b1cdbd2cSJim Jagielski                                   const TimeValue* pLastAccessTime,
3054*b1cdbd2cSJim Jagielski                                   const TimeValue* pLastWriteTime )
3055*b1cdbd2cSJim Jagielski {
3056*b1cdbd2cSJim Jagielski     int nRet=0;
3057*b1cdbd2cSJim Jagielski     struct utimbuf aTimeBuffer;
3058*b1cdbd2cSJim Jagielski     struct stat aFileStat;
3059*b1cdbd2cSJim Jagielski #ifdef DEBUG_OSL_FILE
3060*b1cdbd2cSJim Jagielski     struct tm* pTM=0;
3061*b1cdbd2cSJim Jagielski #endif
3062*b1cdbd2cSJim Jagielski 
3063*b1cdbd2cSJim Jagielski     nRet = lstat(pszFilePath,&aFileStat);
3064*b1cdbd2cSJim Jagielski 
3065*b1cdbd2cSJim Jagielski     if ( nRet < 0 )
3066*b1cdbd2cSJim Jagielski     {
3067*b1cdbd2cSJim Jagielski         nRet=errno;
3068*b1cdbd2cSJim Jagielski         return oslTranslateFileError(OSL_FET_ERROR, nRet);
3069*b1cdbd2cSJim Jagielski     }
3070*b1cdbd2cSJim Jagielski 
3071*b1cdbd2cSJim Jagielski #ifdef DEBUG_OSL_FILE
3072*b1cdbd2cSJim Jagielski     fprintf(stderr,"File Times are (in localtime):\n");
3073*b1cdbd2cSJim Jagielski     pTM=localtime(&aFileStat.st_ctime);
3074*b1cdbd2cSJim Jagielski     fprintf(stderr,"CreationTime is '%s'\n",asctime(pTM));
3075*b1cdbd2cSJim Jagielski     pTM=localtime(&aFileStat.st_atime);
3076*b1cdbd2cSJim Jagielski     fprintf(stderr,"AccessTime   is '%s'\n",asctime(pTM));
3077*b1cdbd2cSJim Jagielski     pTM=localtime(&aFileStat.st_mtime);
3078*b1cdbd2cSJim Jagielski     fprintf(stderr,"Modification is '%s'\n",asctime(pTM));
3079*b1cdbd2cSJim Jagielski 
3080*b1cdbd2cSJim Jagielski     fprintf(stderr,"File Times are (in UTC):\n");
3081*b1cdbd2cSJim Jagielski     fprintf(stderr,"CreationTime is '%s'\n",ctime(&aFileStat.st_ctime));
3082*b1cdbd2cSJim Jagielski     fprintf(stderr,"AccessTime   is '%s'\n",ctime(&aTimeBuffer.actime));
3083*b1cdbd2cSJim Jagielski     fprintf(stderr,"Modification is '%s'\n",ctime(&aTimeBuffer.modtime));
3084*b1cdbd2cSJim Jagielski #endif
3085*b1cdbd2cSJim Jagielski 
3086*b1cdbd2cSJim Jagielski     if ( pLastAccessTime != 0 )
3087*b1cdbd2cSJim Jagielski     {
3088*b1cdbd2cSJim Jagielski         aTimeBuffer.actime=pLastAccessTime->Seconds;
3089*b1cdbd2cSJim Jagielski     }
3090*b1cdbd2cSJim Jagielski     else
3091*b1cdbd2cSJim Jagielski     {
3092*b1cdbd2cSJim Jagielski         aTimeBuffer.actime=aFileStat.st_atime;
3093*b1cdbd2cSJim Jagielski     }
3094*b1cdbd2cSJim Jagielski 
3095*b1cdbd2cSJim Jagielski     if ( pLastWriteTime != 0 )
3096*b1cdbd2cSJim Jagielski     {
3097*b1cdbd2cSJim Jagielski         aTimeBuffer.modtime=pLastWriteTime->Seconds;
3098*b1cdbd2cSJim Jagielski     }
3099*b1cdbd2cSJim Jagielski     else
3100*b1cdbd2cSJim Jagielski     {
3101*b1cdbd2cSJim Jagielski         aTimeBuffer.modtime=aFileStat.st_mtime;
3102*b1cdbd2cSJim Jagielski     }
3103*b1cdbd2cSJim Jagielski 
3104*b1cdbd2cSJim Jagielski     /* mfe: Creation time not used here! */
3105*b1cdbd2cSJim Jagielski 
3106*b1cdbd2cSJim Jagielski #ifdef DEBUG_OSL_FILE
3107*b1cdbd2cSJim Jagielski     fprintf(stderr,"File Times are (in localtime):\n");
3108*b1cdbd2cSJim Jagielski     pTM=localtime(&aFileStat.st_ctime);
3109*b1cdbd2cSJim Jagielski     fprintf(stderr,"CreationTime now '%s'\n",asctime(pTM));
3110*b1cdbd2cSJim Jagielski     pTM=localtime(&aTimeBuffer.actime);
3111*b1cdbd2cSJim Jagielski     fprintf(stderr,"AccessTime   now '%s'\n",asctime(pTM));
3112*b1cdbd2cSJim Jagielski     pTM=localtime(&aTimeBuffer.modtime);
3113*b1cdbd2cSJim Jagielski     fprintf(stderr,"Modification now '%s'\n",asctime(pTM));
3114*b1cdbd2cSJim Jagielski 
3115*b1cdbd2cSJim Jagielski     fprintf(stderr,"File Times are (in UTC):\n");
3116*b1cdbd2cSJim Jagielski     fprintf(stderr,"CreationTime now '%s'\n",ctime(&aFileStat.st_ctime));
3117*b1cdbd2cSJim Jagielski     fprintf(stderr,"AccessTime   now '%s'\n",ctime(&aTimeBuffer.actime));
3118*b1cdbd2cSJim Jagielski     fprintf(stderr,"Modification now '%s'\n",ctime(&aTimeBuffer.modtime));
3119*b1cdbd2cSJim Jagielski #endif
3120*b1cdbd2cSJim Jagielski 
3121*b1cdbd2cSJim Jagielski     nRet=utime(pszFilePath,&aTimeBuffer);
3122*b1cdbd2cSJim Jagielski     if ( nRet < 0 )
3123*b1cdbd2cSJim Jagielski     {
3124*b1cdbd2cSJim Jagielski         nRet=errno;
3125*b1cdbd2cSJim Jagielski         return oslTranslateFileError(OSL_FET_ERROR, nRet);
3126*b1cdbd2cSJim Jagielski     }
3127*b1cdbd2cSJim Jagielski 
3128*b1cdbd2cSJim Jagielski     return osl_File_E_None;
3129*b1cdbd2cSJim Jagielski }
3130*b1cdbd2cSJim Jagielski 
3131*b1cdbd2cSJim Jagielski 
3132*b1cdbd2cSJim Jagielski /******************************************************************************
3133*b1cdbd2cSJim Jagielski  *
3134*b1cdbd2cSJim Jagielski  *                  Utility Functions
3135*b1cdbd2cSJim Jagielski  *
3136*b1cdbd2cSJim Jagielski  *****************************************************************************/
3137*b1cdbd2cSJim Jagielski 
3138*b1cdbd2cSJim Jagielski 
3139*b1cdbd2cSJim Jagielski /*****************************************
3140*b1cdbd2cSJim Jagielski  * oslMakeUStrFromPsz
3141*b1cdbd2cSJim Jagielski  ****************************************/
3142*b1cdbd2cSJim Jagielski 
oslMakeUStrFromPsz(const sal_Char * pszStr,rtl_uString ** ustrValid)3143*b1cdbd2cSJim Jagielski rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr, rtl_uString** ustrValid)
3144*b1cdbd2cSJim Jagielski {
3145*b1cdbd2cSJim Jagielski     rtl_string2UString(
3146*b1cdbd2cSJim Jagielski         ustrValid,
3147*b1cdbd2cSJim Jagielski         pszStr,
3148*b1cdbd2cSJim Jagielski         rtl_str_getLength( pszStr ),
3149*b1cdbd2cSJim Jagielski         osl_getThreadTextEncoding(),
3150*b1cdbd2cSJim Jagielski         OUSTRING_TO_OSTRING_CVTFLAGS );
3151*b1cdbd2cSJim Jagielski     OSL_ASSERT(*ustrValid != 0);
3152*b1cdbd2cSJim Jagielski 
3153*b1cdbd2cSJim Jagielski     return *ustrValid;
3154*b1cdbd2cSJim Jagielski }
3155*b1cdbd2cSJim Jagielski 
3156*b1cdbd2cSJim Jagielski /*****************************************************************************
3157*b1cdbd2cSJim Jagielski  * UnicodeToText
3158*b1cdbd2cSJim Jagielski  * converting unicode to text manually saves us the penalty of a temporary
3159*b1cdbd2cSJim Jagielski  * rtl_String object.
3160*b1cdbd2cSJim Jagielski  ****************************************************************************/
3161*b1cdbd2cSJim Jagielski 
UnicodeToText(char * buffer,size_t bufLen,const sal_Unicode * uniText,sal_Int32 uniTextLen)3162*b1cdbd2cSJim Jagielski int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen )
3163*b1cdbd2cSJim Jagielski {
3164*b1cdbd2cSJim Jagielski     rtl_UnicodeToTextConverter hConverter;
3165*b1cdbd2cSJim Jagielski     sal_uInt32   nInfo;
3166*b1cdbd2cSJim Jagielski     sal_Size   nSrcChars, nDestBytes;
3167*b1cdbd2cSJim Jagielski 
3168*b1cdbd2cSJim Jagielski     /* stolen from rtl/string.c */
3169*b1cdbd2cSJim Jagielski     hConverter = rtl_createUnicodeToTextConverter( osl_getThreadTextEncoding() );
3170*b1cdbd2cSJim Jagielski 
3171*b1cdbd2cSJim Jagielski 	nDestBytes = rtl_convertUnicodeToText( hConverter, 0, uniText, uniTextLen,
3172*b1cdbd2cSJim Jagielski                                            buffer, bufLen,
3173*b1cdbd2cSJim Jagielski                                            OUSTRING_TO_OSTRING_CVTFLAGS | RTL_UNICODETOTEXT_FLAGS_FLUSH,
3174*b1cdbd2cSJim Jagielski                                            &nInfo, &nSrcChars );
3175*b1cdbd2cSJim Jagielski 
3176*b1cdbd2cSJim Jagielski     rtl_destroyUnicodeToTextConverter( hConverter );
3177*b1cdbd2cSJim Jagielski 
3178*b1cdbd2cSJim Jagielski     if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
3179*b1cdbd2cSJim Jagielski     {
3180*b1cdbd2cSJim Jagielski         errno = EOVERFLOW;
3181*b1cdbd2cSJim Jagielski         return 0;
3182*b1cdbd2cSJim Jagielski     }
3183*b1cdbd2cSJim Jagielski 
3184*b1cdbd2cSJim Jagielski     /* ensure trailing '\0' */
3185*b1cdbd2cSJim Jagielski     buffer[nDestBytes] = '\0';
3186*b1cdbd2cSJim Jagielski 
3187*b1cdbd2cSJim Jagielski     return nDestBytes;
3188*b1cdbd2cSJim Jagielski }
3189*b1cdbd2cSJim Jagielski 
3190*b1cdbd2cSJim Jagielski /*****************************************************************************
3191*b1cdbd2cSJim Jagielski    TextToUnicode
3192*b1cdbd2cSJim Jagielski 
3193*b1cdbd2cSJim Jagielski    @param text
3194*b1cdbd2cSJim Jagielski           The text to convert.
3195*b1cdbd2cSJim Jagielski 
3196*b1cdbd2cSJim Jagielski    @param text_buffer_size
3197*b1cdbd2cSJim Jagielski           The number of characters.
3198*b1cdbd2cSJim Jagielski 
3199*b1cdbd2cSJim Jagielski    @param unic_text
3200*b1cdbd2cSJim Jagielski           The unicode buffer.
3201*b1cdbd2cSJim Jagielski 
3202*b1cdbd2cSJim Jagielski    @param unic_text_buffer_size
3203*b1cdbd2cSJim Jagielski    		  The size in characters of the unicode buffer.
3204*b1cdbd2cSJim Jagielski 
3205*b1cdbd2cSJim Jagielski  ****************************************************************************/
3206*b1cdbd2cSJim Jagielski 
TextToUnicode(const char * text,size_t text_buffer_size,sal_Unicode * unic_text,sal_Int32 unic_text_buffer_size)3207*b1cdbd2cSJim Jagielski int TextToUnicode(
3208*b1cdbd2cSJim Jagielski 	const char*  text,
3209*b1cdbd2cSJim Jagielski 	size_t       text_buffer_size,
3210*b1cdbd2cSJim Jagielski 	sal_Unicode* unic_text,
3211*b1cdbd2cSJim Jagielski 	sal_Int32    unic_text_buffer_size)
3212*b1cdbd2cSJim Jagielski {
3213*b1cdbd2cSJim Jagielski     rtl_TextToUnicodeConverter hConverter;
3214*b1cdbd2cSJim Jagielski     sal_uInt32 nInfo;
3215*b1cdbd2cSJim Jagielski     sal_Size nSrcChars;
3216*b1cdbd2cSJim Jagielski     sal_Size nDestBytes;
3217*b1cdbd2cSJim Jagielski 
3218*b1cdbd2cSJim Jagielski     /* stolen from rtl/string.c */
3219*b1cdbd2cSJim Jagielski     hConverter = rtl_createTextToUnicodeConverter(osl_getThreadTextEncoding());
3220*b1cdbd2cSJim Jagielski 
3221*b1cdbd2cSJim Jagielski 	nDestBytes = rtl_convertTextToUnicode(hConverter,
3222*b1cdbd2cSJim Jagielski 										  0,
3223*b1cdbd2cSJim Jagielski 										  text,  text_buffer_size,
3224*b1cdbd2cSJim Jagielski                                           unic_text, unic_text_buffer_size,
3225*b1cdbd2cSJim Jagielski                                           OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_FLUSH,
3226*b1cdbd2cSJim Jagielski                                           &nInfo, &nSrcChars);
3227*b1cdbd2cSJim Jagielski 
3228*b1cdbd2cSJim Jagielski     rtl_destroyTextToUnicodeConverter(hConverter);
3229*b1cdbd2cSJim Jagielski 
3230*b1cdbd2cSJim Jagielski     if (nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
3231*b1cdbd2cSJim Jagielski     {
3232*b1cdbd2cSJim Jagielski         errno = EOVERFLOW;
3233*b1cdbd2cSJim Jagielski         return 0;
3234*b1cdbd2cSJim Jagielski     }
3235*b1cdbd2cSJim Jagielski 
3236*b1cdbd2cSJim Jagielski     /* ensure trailing '\0' */
3237*b1cdbd2cSJim Jagielski     unic_text[nDestBytes] = '\0';
3238*b1cdbd2cSJim Jagielski 
3239*b1cdbd2cSJim Jagielski     return nDestBytes;
3240*b1cdbd2cSJim Jagielski }
3241*b1cdbd2cSJim Jagielski 
3242*b1cdbd2cSJim Jagielski /******************************************************************************
3243*b1cdbd2cSJim Jagielski  *
3244*b1cdbd2cSJim Jagielski  *                  GENERIC FLOPPY FUNCTIONS
3245*b1cdbd2cSJim Jagielski  *
3246*b1cdbd2cSJim Jagielski  *****************************************************************************/
3247*b1cdbd2cSJim Jagielski 
3248*b1cdbd2cSJim Jagielski /*****************************************
3249*b1cdbd2cSJim Jagielski  * osl_unmountVolumeDevice
3250*b1cdbd2cSJim Jagielski  ****************************************/
osl_unmountVolumeDevice(oslVolumeDeviceHandle Handle)3251*b1cdbd2cSJim Jagielski oslFileError osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
3252*b1cdbd2cSJim Jagielski {
3253*b1cdbd2cSJim Jagielski 	if ( Handle )
3254*b1cdbd2cSJim Jagielski 		return osl_File_E_None;
3255*b1cdbd2cSJim Jagielski 	else
3256*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
3257*b1cdbd2cSJim Jagielski }
3258*b1cdbd2cSJim Jagielski 
3259*b1cdbd2cSJim Jagielski /*****************************************
3260*b1cdbd2cSJim Jagielski  * osl_automountVolumeDevice
3261*b1cdbd2cSJim Jagielski  ****************************************/
osl_automountVolumeDevice(oslVolumeDeviceHandle Handle)3262*b1cdbd2cSJim Jagielski oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
3263*b1cdbd2cSJim Jagielski {
3264*b1cdbd2cSJim Jagielski 	if ( Handle )
3265*b1cdbd2cSJim Jagielski 		return osl_File_E_None;
3266*b1cdbd2cSJim Jagielski 	else
3267*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
3268*b1cdbd2cSJim Jagielski }
3269*b1cdbd2cSJim Jagielski 
3270*b1cdbd2cSJim Jagielski /*****************************************
3271*b1cdbd2cSJim Jagielski  * osl_getVolumeDeviceMountPath
3272*b1cdbd2cSJim Jagielski  ****************************************/
osl_getVolumeDeviceMountPath(oslVolumeDeviceHandle Handle,rtl_uString ** pstrPath)3273*b1cdbd2cSJim Jagielski oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
3274*b1cdbd2cSJim Jagielski {
3275*b1cdbd2cSJim Jagielski 	if ( Handle && pstrPath )
3276*b1cdbd2cSJim Jagielski 	{
3277*b1cdbd2cSJim Jagielski 		rtl_uString_assign( pstrPath, (rtl_uString *)Handle );
3278*b1cdbd2cSJim Jagielski 		return osl_File_E_None;
3279*b1cdbd2cSJim Jagielski 	}
3280*b1cdbd2cSJim Jagielski 	else
3281*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
3282*b1cdbd2cSJim Jagielski }
3283*b1cdbd2cSJim Jagielski 
3284*b1cdbd2cSJim Jagielski /*****************************************
3285*b1cdbd2cSJim Jagielski  * osl_acquireVolumeDeviceHandle
3286*b1cdbd2cSJim Jagielski  ****************************************/
3287*b1cdbd2cSJim Jagielski 
osl_acquireVolumeDeviceHandle(oslVolumeDeviceHandle Handle)3288*b1cdbd2cSJim Jagielski oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
3289*b1cdbd2cSJim Jagielski {
3290*b1cdbd2cSJim Jagielski 	if ( Handle )
3291*b1cdbd2cSJim Jagielski 	{
3292*b1cdbd2cSJim Jagielski 		rtl_uString_acquire( (rtl_uString *)Handle );
3293*b1cdbd2cSJim Jagielski 		return osl_File_E_None;
3294*b1cdbd2cSJim Jagielski 	}
3295*b1cdbd2cSJim Jagielski 	else
3296*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
3297*b1cdbd2cSJim Jagielski }
3298*b1cdbd2cSJim Jagielski 
3299*b1cdbd2cSJim Jagielski /*****************************************
3300*b1cdbd2cSJim Jagielski  * osl_releaseVolumeDeviceHandle
3301*b1cdbd2cSJim Jagielski  ****************************************/
3302*b1cdbd2cSJim Jagielski 
osl_releaseVolumeDeviceHandle(oslVolumeDeviceHandle Handle)3303*b1cdbd2cSJim Jagielski oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
3304*b1cdbd2cSJim Jagielski {
3305*b1cdbd2cSJim Jagielski 	if ( Handle )
3306*b1cdbd2cSJim Jagielski 	{
3307*b1cdbd2cSJim Jagielski 		rtl_uString_release( (rtl_uString *)Handle );
3308*b1cdbd2cSJim Jagielski 		return osl_File_E_None;
3309*b1cdbd2cSJim Jagielski 	}
3310*b1cdbd2cSJim Jagielski 	else
3311*b1cdbd2cSJim Jagielski 		return osl_File_E_INVAL;
3312*b1cdbd2cSJim Jagielski }
3313*b1cdbd2cSJim Jagielski 
3314*b1cdbd2cSJim Jagielski /******************************************************************************
3315*b1cdbd2cSJim Jagielski  *
3316*b1cdbd2cSJim Jagielski  *                  OS/2 FLOPPY FUNCTIONS
3317*b1cdbd2cSJim Jagielski  *
3318*b1cdbd2cSJim Jagielski  *****************************************************************************/
osl_isFloppyDrive(const sal_Char * pszPath)3319*b1cdbd2cSJim Jagielski static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
3320*b1cdbd2cSJim Jagielski {
3321*b1cdbd2cSJim Jagielski     return NULL;
3322*b1cdbd2cSJim Jagielski }
3323*b1cdbd2cSJim Jagielski 
3324