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