1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
29 /************************************************************************
32 * Fix osl_getCanonicalName
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 ***********************************************************************/
43 #define INCL_DOSDEVIOCTL // OS2 device definitions
46 #include <rtl/alloc.h>
48 #include "osl/file.hxx"
51 #include <sal/types.h>
52 #include <osl/thread.h>
53 #include <osl/diagnose.h>
54 #include "file_error_transl.h"
61 #include "file_path_helper.hxx"
62 #include "uunxapi.hxx"
76 #if OSL_DEBUG_LEVEL > 1
77 extern void debug_ustring(rtl_uString
*);
82 # define PERROR( a, b ) perror( a ); fprintf( stderr, b )
84 # define PERROR( a, b )
87 extern "C" oslFileHandle
osl_createFileHandleFromFD( int fd
);
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 */
140 #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
142 //#####################################################
143 oslFileError
MapError(APIRET dwError
)
145 for (int i
= 0; i
< ELEMENTS_OF_ARRAY(errtable
); ++i
)
147 if (dwError
== errtable
[i
].oscode
)
148 return static_cast<oslFileError
>(errtable
[i
].errnocode
);
150 return osl_File_E_INVAL
;
153 /******************************************************************************
157 *****************************************************************************/
159 static const char * pFileLockEnvVar
= (char *) -1;
162 /******************************************************************************
164 * C-String Function Declarations
166 *****************************************************************************/
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
);
177 /******************************************************************************
179 * Static Module Utility Function Declarations
181 *****************************************************************************/
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
);
190 /******************************************************************************
192 * Non-Static Utility Function Declarations
194 *****************************************************************************/
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
);
200 /******************************************************************************
202 * 'removeable device' aka floppy functions
204 *****************************************************************************/
206 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
);
207 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
);
208 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
);
210 #ifdef DEBUG_OSL_FILE
211 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl
* hFloppy
);
214 /**********************************************
216 * enumerate available drives
217 *********************************************/
218 static oslFileError
_osl_openLocalRoot( rtl_uString
*strDirectoryPath
, oslDirectory
*pDirectory
)
220 rtl_uString
*ustrSystemPath
= NULL
;
224 return osl_File_E_INVAL
;
228 error
= osl_getSystemPathFromFileURL_Ex( strDirectoryPath
, &ustrSystemPath
, sal_False
);
230 if ( osl_File_E_None
== error
)
232 /* create and initialize impl structure */
233 DirectoryImpl
* pDirImpl
= (DirectoryImpl
*) rtl_allocateMemory( sizeof(DirectoryImpl
) );
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;
245 // determine number of floppy-drives
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;
256 *pDirectory
= (oslDirectory
) pDirImpl
;
257 return osl_File_E_None
;
261 errno
= osl_File_E_NOMEM
;
266 rtl_uString_release( ustrSystemPath
);
270 /**********************************************
272 *********************************************/
273 static oslFileError SAL_CALL
_osl_getNextDrive(
274 oslDirectory Directory
, oslDirectoryItem
*pItem
, sal_uInt32 uHint
)
276 DirectoryImpl
*pDirImpl
= (DirectoryImpl
*)Directory
;
277 DirectoryItem_Impl
*pItemImpl
= NULL
;
278 rtl_uString
* ustrDrive
= NULL
;
282 uHint
= uHint
; /* avoid warnings */
285 return osl_File_E_INVAL
;
290 return osl_File_E_INVAL
;
292 while( pDirImpl
->ulNextDrive
<= 26)
294 // exit if bit==1 -> drive found
295 if (pDirImpl
->ulDriveMap
& pDirImpl
->ulNextDriveMask
) {
297 /* convert file name to unicode */
298 buffer
[0] = '@' + pDirImpl
->ulNextDrive
;
302 pItemImpl
= (DirectoryItem_Impl
*) rtl_allocateMemory(sizeof(DirectoryItem_Impl
));
304 return osl_File_E_NOMEM
;
306 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
307 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
308 pItemImpl
->nRefCount
= 1;
310 rtl_string2UString( &pItemImpl
->ustrDrive
, buffer
, 3,
311 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
312 OSL_ASSERT(pItemImpl
->ustrDrive
!= 0);
314 /* use drive as directory item */
315 *pItem
= (oslDirectoryItem
) pItemImpl
;
317 // scan next bit position
318 pDirImpl
->ulNextDrive
++;
319 pDirImpl
->ulNextDriveMask
<<= 1;
321 if (*pItem
) // item assigned, return now.
322 return osl_File_E_None
;
326 return osl_File_E_NOENT
;
329 /**********************************************
332 * readdir wrapper, filters out "." and ".."
334 *********************************************/
336 static struct dirent
* _osl_readdir_impl_(DIR* pdir
, sal_Bool bFilterLocalAndParentDir
)
338 struct dirent
* pdirent
;
340 while ((pdirent
= readdir(pdir
)) != NULL
)
342 if (bFilterLocalAndParentDir
&&
343 ((0 == strcmp(pdirent
->d_name
, ".")) || (0 == strcmp(pdirent
->d_name
, ".."))))
352 /*******************************************************************
354 ******************************************************************/
356 oslFileError SAL_CALL
osl_openDirectory(rtl_uString
* ustrDirectoryURL
, oslDirectory
* pDirectory
)
358 rtl_uString
* ustrSystemPath
= NULL
;
363 OSL_ASSERT(ustrDirectoryURL
&& (ustrDirectoryURL
->length
> 0));
364 OSL_ASSERT(pDirectory
);
366 if (0 == ustrDirectoryURL
->length
)
367 return osl_File_E_INVAL
;
369 if ( 0 == rtl_ustr_compareIgnoreAsciiCase( ustrDirectoryURL
->buffer
, (const sal_Unicode
*)L
"file:///" ) )
370 return _osl_openLocalRoot( ustrDirectoryURL
, pDirectory
);
372 /* convert file URL to system path */
373 eRet
= osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL
, &ustrSystemPath
, sal_False
);
375 if( osl_File_E_None
!= eRet
)
378 osl_systemPathRemoveSeparator(ustrSystemPath
);
380 /* convert unicode path to text */
381 if ( UnicodeToText( path
, PATH_MAX
, ustrSystemPath
->buffer
, ustrSystemPath
->length
) )
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] == ':')
388 DIR *pdir
= opendir( path
);
392 /* create and initialize impl structure */
393 DirectoryImpl
* pDirImpl
= (DirectoryImpl
*) rtl_allocateMemory( sizeof(DirectoryImpl
) );
397 pDirImpl
->uType
= DIRECTORYTYPE_FILESYSTEM
;
398 pDirImpl
->pDirStruct
= pdir
;
399 pDirImpl
->ustrPath
= ustrSystemPath
;
401 *pDirectory
= (oslDirectory
) pDirImpl
;
402 return osl_File_E_None
;
411 /* should be removed by optimizer in product version */
412 PERROR( "osl_openDirectory", path
);
415 rtl_uString_release( ustrSystemPath
);
417 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
421 /****************************************************************************
422 * osl_getNextDirectoryItem
423 ***************************************************************************/
425 oslFileError SAL_CALL
osl_getNextDirectoryItem(oslDirectory Directory
, oslDirectoryItem
* pItem
, sal_uInt32 uHint
)
427 DirectoryImpl
* pDirImpl
= (DirectoryImpl
*)Directory
;
428 DirectoryItem_Impl
*pItemImpl
= NULL
;
429 rtl_uString
* ustrFileName
= NULL
;
430 rtl_uString
* ustrFilePath
= NULL
;
431 struct dirent
* pEntry
;
433 OSL_ASSERT(Directory
);
436 if ((NULL
== Directory
) || (NULL
== pItem
))
437 return osl_File_E_INVAL
;
439 if ( pDirImpl
->uType
== DIRECTORYTYPE_LOCALROOT
)
440 return _osl_getNextDrive( Directory
, pItem
, uHint
);
442 pEntry
= _osl_readdir_impl_(pDirImpl
->pDirStruct
, sal_True
);
445 return osl_File_E_NOENT
;
447 pItemImpl
= (DirectoryItem_Impl
*) rtl_allocateMemory(sizeof(DirectoryItem_Impl
));
449 return osl_File_E_NOMEM
;
451 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
452 pItemImpl
->uType
= DIRECTORYITEM_FILE
;
453 pItemImpl
->nRefCount
= 1;
454 pItemImpl
->d_attr
= pEntry
->d_attr
;
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);
461 osl_systemPathMakeAbsolutePath(pDirImpl
->ustrPath
, ustrFileName
, &pItemImpl
->ustrFilePath
);
462 rtl_uString_release( ustrFileName
);
464 *pItem
= (oslDirectoryItem
)pItemImpl
;
465 return osl_File_E_None
;
468 /****************************************************************************/
469 /* osl_closeDirectory */
470 /****************************************************************************/
472 oslFileError SAL_CALL
osl_closeDirectory( oslDirectory Directory
)
474 DirectoryImpl
* pDirImpl
= (DirectoryImpl
*) Directory
;
475 oslFileError err
= osl_File_E_None
;
477 OSL_ASSERT( Directory
);
479 if( NULL
== pDirImpl
)
480 return osl_File_E_INVAL
;
482 switch ( pDirImpl
->uType
)
484 case DIRECTORYTYPE_FILESYSTEM
:
485 if( closedir( pDirImpl
->pDirStruct
) )
486 err
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
488 case DIRECTORYTYPE_LOCALROOT
:
489 err
= osl_File_E_None
;
492 case DIRECTORYTYPE_NETROOT
:
494 DWORD err
= WNetCloseEnum(pDirImpl
->hDirectory
);
495 eError
= (err
== NO_ERROR
) ? osl_File_E_None
: MapError(err
);
500 OSL_ENSURE( 0, "Invalid directory type" );
504 /* cleanup members */
505 rtl_uString_release( pDirImpl
->ustrPath
);
507 rtl_freeMemory( pDirImpl
);
512 /****************************************************************************/
513 /* osl_getDirectoryItem */
514 /****************************************************************************/
516 oslFileError SAL_CALL
osl_getDirectoryItem( rtl_uString
* ustrFileURL
, oslDirectoryItem
* pItem
)
518 rtl_uString
* strSysFilePath
= NULL
;
519 oslFileError error
= osl_File_E_INVAL
;
521 PATHTYPE type
= PATHTYPE_FILE
;
523 OSL_ASSERT(ustrFileURL
);
528 return osl_File_E_INVAL
;
531 if (0 == ustrFileURL
->length
|| NULL
== pItem
)
532 return osl_File_E_INVAL
;
534 error
= osl_getSystemPathFromFileURL_Ex(ustrFileURL
, &strSysFilePath
, sal_False
);
536 if (osl_File_E_None
!= error
)
539 dwPathType
= IsValidFilePath( strSysFilePath
->buffer
, NULL
, VALIDATEPATH_NORMAL
);
541 if ( dwPathType
& PATHTYPE_IS_VOLUME
)
542 type
= PATHTYPE_VOLUME
;
543 else if ( dwPathType
& PATHTYPE_IS_SERVER
)
544 type
= PATHTYPE_NETSERVER
;
546 type
= PATHTYPE_FILE
;
550 case PATHTYPE_NETSERVER
:
552 DirectoryItem_Impl
* pItemImpl
=
553 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
556 error
= osl_File_E_NOMEM
;
558 if ( osl_File_E_None
== error
)
560 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
561 pItemImpl
->uType
= DIRECTORYITEM_SERVER
;
562 pItemImpl
->nRefCount
= 1;
563 rtl_uString_assign( &pItemImpl
->ustrFilePath
, strSysFilePath
);
569 case PATHTYPE_VOLUME
:
571 DirectoryItem_Impl
* pItemImpl
=
572 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
575 error
= osl_File_E_NOMEM
;
577 if ( osl_File_E_None
== error
)
579 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
580 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
581 pItemImpl
->nRefCount
= 1;
582 rtl_uString_assign( &pItemImpl
->ustrDrive
, strSysFilePath
);
584 if ( pItemImpl
->ustrDrive
->buffer
[pItemImpl
->ustrDrive
->length
-1] != sal_Unicode('\\') )
585 rtl_uString_newConcat( &pItemImpl
->ustrDrive
,
586 pItemImpl
->ustrDrive
, rtl::OUString::createFromAscii( "\\" ).pData
);
595 if ( strSysFilePath
->length
> 0 && strSysFilePath
->buffer
[strSysFilePath
->length
- 1] == '\\' )
596 rtl_uString_newFromStr_WithLength( &strSysFilePath
, strSysFilePath
->buffer
, strSysFilePath
->length
- 1 );
598 if (0 == access_u(strSysFilePath
, F_OK
))
600 DirectoryItem_Impl
*pItemImpl
=
601 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
603 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
604 pItemImpl
->uType
= DIRECTORYITEM_FILE
;
605 pItemImpl
->nRefCount
= 1;
606 rtl_uString_assign( &pItemImpl
->ustrFilePath
, strSysFilePath
);
611 error
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
616 if ( strSysFilePath
)
617 rtl_uString_release( strSysFilePath
);
622 /****************************************************************************/
623 /* osl_acquireDirectoryItem */
624 /****************************************************************************/
626 oslFileError
osl_acquireDirectoryItem( oslDirectoryItem Item
)
629 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
632 return osl_File_E_INVAL
;
634 pItemImpl
->nRefCount
++;
635 return osl_File_E_None
;
638 /****************************************************************************/
639 /* osl_releaseDirectoryItem */
640 /****************************************************************************/
642 oslFileError
osl_releaseDirectoryItem( oslDirectoryItem Item
)
645 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
648 return osl_File_E_INVAL
;
650 if ( ! --pItemImpl
->nRefCount
)
652 if (pItemImpl
->ustrFilePath
)
653 rtl_uString_release( pItemImpl
->ustrFilePath
);
654 if (pItemImpl
->ustrDrive
)
655 rtl_uString_release( pItemImpl
->ustrDrive
);
656 rtl_freeMemory( pItemImpl
);
658 return osl_File_E_None
;
661 /****************************************************************************
662 * osl_createFileHandleFromFD
663 ***************************************************************************/
665 oslFileHandle
osl_createFileHandleFromFD( int fd
)
667 oslFileHandleImpl
* pHandleImpl
= NULL
;
671 pHandleImpl
= (oslFileHandleImpl
*) rtl_allocateMemory( sizeof(oslFileHandleImpl
) );
675 pHandleImpl
->ustrFilePath
= NULL
;
676 rtl_uString_new( &pHandleImpl
->ustrFilePath
);
677 pHandleImpl
->fd
= fd
;
679 /* FIXME: should detect whether the file has been locked */
680 pHandleImpl
->bLocked
= sal_True
;
684 return (oslFileHandle
)pHandleImpl
;
687 /****************************************************************************
689 ***************************************************************************/
691 oslFileError
osl_openFile( rtl_uString
* ustrFileURL
, oslFileHandle
* pHandle
, sal_uInt32 uFlags
)
693 oslFileHandleImpl
* pHandleImpl
= NULL
;
695 rtl_uString
* ustrFilePath
= NULL
;
697 char buffer
[PATH_MAX
];
699 int mode
= S_IRUSR
| S_IRGRP
| S_IROTH
;
700 int flags
= O_RDONLY
;
704 /* locking the complete file */
706 aflock
.l_whence
= SEEK_SET
;
710 OSL_ASSERT( ustrFileURL
);
711 OSL_ASSERT( pHandle
);
713 if( ( 0 == ustrFileURL
->length
) )
714 return osl_File_E_INVAL
;
716 /* convert file URL to system path */
717 eRet
= osl_getSystemPathFromFileURL( ustrFileURL
, &ustrFilePath
);
719 if( osl_File_E_None
!= eRet
)
722 osl_systemPathRemoveSeparator(ustrFilePath
);
724 /* convert unicode path to text */
725 if( UnicodeToText( buffer
, PATH_MAX
, ustrFilePath
->buffer
, ustrFilePath
->length
) )
727 /* we do not open devices or such here */
728 if( !( uFlags
& osl_File_OpenFlag_Create
) )
730 struct stat aFileStat
;
732 if( 0 > stat( buffer
, &aFileStat
) )
734 PERROR( "osl_openFile", buffer
);
735 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
738 else if( !S_ISREG( aFileStat
.st_mode
) )
740 eRet
= osl_File_E_INVAL
;
744 if( osl_File_E_None
== eRet
)
750 if ( uFlags
& osl_File_OpenFlag_Write
)
752 mode
|= S_IWUSR
| S_IWGRP
| S_IWOTH
;
754 aflock
.l_type
= F_WRLCK
;
757 if ( uFlags
& osl_File_OpenFlag_Create
)
759 mode
|= S_IWUSR
| S_IWGRP
| S_IWOTH
;
760 flags
= O_CREAT
| O_EXCL
| O_RDWR
;
764 fd
= open( buffer
, flags
| O_BINARY
, mode
);
767 sal_Bool bNeedsLock
= ( ( uFlags
& osl_File_OpenFlag_NoLock
) == 0 );
768 sal_Bool bLocked
= sal_False
;
771 /* check if file lock is enabled and clear l_type member of flock otherwise */
772 if( (char *) -1 == pFileLockEnvVar
)
774 /* FIXME: this is not MT safe */
775 pFileLockEnvVar
= getenv("SAL_ENABLE_FILE_LOCKING");
777 if( NULL
== pFileLockEnvVar
)
778 pFileLockEnvVar
= getenv("STAR_ENABLE_FILE_LOCKING");
781 if( NULL
== pFileLockEnvVar
)
784 /* lock the file if flock.l_type is set */
785 bLocked
= ( F_WRLCK
!= aflock
.l_type
|| -1 != fcntl( fd
, F_SETLK
, &aflock
) );
788 if ( !bNeedsLock
|| bLocked
)
790 /* allocate memory for impl structure */
791 pHandleImpl
= (oslFileHandleImpl
*) rtl_allocateMemory( sizeof(oslFileHandleImpl
) );
794 pHandleImpl
->ustrFilePath
= ustrFilePath
;
795 pHandleImpl
->fd
= fd
;
796 pHandleImpl
->bLocked
= bLocked
;
798 *pHandle
= (oslFileHandle
) pHandleImpl
;
800 return osl_File_E_None
;
811 PERROR( "osl_openFile", buffer
);
812 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
816 eRet
= osl_File_E_INVAL
;
818 rtl_uString_release( ustrFilePath
);
822 /****************************************************************************/
824 /****************************************************************************/
826 oslFileError
osl_closeFile( oslFileHandle Handle
)
828 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*) Handle
;
829 oslFileError eRet
= osl_File_E_INVAL
;
831 OSL_ASSERT( Handle
);
835 rtl_uString_release( pHandleImpl
->ustrFilePath
);
837 /* release file lock if locking is enabled */
838 if( pFileLockEnvVar
)
842 aflock
.l_type
= F_UNLCK
;
843 aflock
.l_whence
= SEEK_SET
;
847 if ( pHandleImpl
->bLocked
)
849 /* FIXME: check if file is really locked ? */
851 /* release the file share lock on this file */
852 if( -1 == fcntl( pHandleImpl
->fd
, F_SETLK
, &aflock
) )
853 PERROR( "osl_closeFile", "unlock failed" );
857 if( 0 > close( pHandleImpl
->fd
) )
859 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
862 eRet
= osl_File_E_None
;
864 rtl_freeMemory( pHandleImpl
);
870 /****************************************************************************/
871 /* osl_isEndOfFile */
872 /****************************************************************************/
874 oslFileError SAL_CALL
osl_isEndOfFile( oslFileHandle Handle
, sal_Bool
*pIsEOF
)
876 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*) Handle
;
877 oslFileError eRet
= osl_File_E_INVAL
;
881 long curPos
= lseek( pHandleImpl
->fd
, 0, SEEK_CUR
);
885 long endPos
= lseek( pHandleImpl
->fd
, 0, SEEK_END
);
889 *pIsEOF
= ( curPos
== endPos
);
890 curPos
= lseek( pHandleImpl
->fd
, curPos
, SEEK_SET
);
893 eRet
= osl_File_E_None
;
895 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
898 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
901 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
908 /****************************************************************************/
910 /****************************************************************************/
912 oslFileError
osl_moveFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
914 char srcPath
[PATH_MAX
];
915 char destPath
[PATH_MAX
];
919 OSL_ASSERT( ustrFileURL
);
920 OSL_ASSERT( ustrDestURL
);
922 /* convert source url to system path */
923 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
924 if( eRet
!= osl_File_E_None
)
927 /* convert destination url to system path */
928 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
929 if( eRet
!= osl_File_E_None
)
932 //YD 01/05/06 rename() can overwrite existing files.
933 rc
= DosDelete( (PCSZ
)destPath
);
934 rc
= DosMove( (PCSZ
)srcPath
, (PCSZ
)destPath
);
936 eRet
= osl_File_E_None
;
938 eRet
= MapError( rc
);
943 /****************************************************************************/
945 /****************************************************************************/
947 #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
949 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
)
952 sal_Char pszTmpDestFile
[PATH_MAX
];
953 size_t size_tmp_dest_buff
= sizeof(pszTmpDestFile
);
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.
959 memset(pszTmpDestFile
, 0, size_tmp_dest_buff
);
961 if ( DestFileExists
)
963 strncpy(pszTmpDestFile
, pszDestFileName
, size_tmp_dest_buff
- 1);
965 if ((strlen(pszTmpDestFile
) + strlen(TMP_DEST_FILE_EXTENSION
)) >= size_tmp_dest_buff
)
966 return osl_File_E_NAMETOOLONG
;
968 strncat(pszTmpDestFile
, TMP_DEST_FILE_EXTENSION
, strlen(TMP_DEST_FILE_EXTENSION
));
970 /* FIXME: what if pszTmpDestFile already exists? */
971 /* with getcanonical??? */
972 nRet
=rename(pszDestFileName
,pszTmpDestFile
);
975 /* mfe: should be S_ISREG */
976 if ( !S_ISLNK(nMode
) )
978 /* copy SourceFile to DestFile */
979 nRet
= oslDoCopyFile(pszSourceFileName
,pszDestFileName
,nSourceSize
, nMode
);
981 /* mfe: OK redundant at the moment */
982 else if ( S_ISLNK(nMode
) )
984 nRet
= oslDoCopyLink(pszSourceFileName
,pszDestFileName
);
988 /* mfe: what to do here? */
992 if ( nRet
> 0 && DestFileExists
== 1 )
994 unlink(pszDestFileName
);
995 rename(pszTmpDestFile
,pszDestFileName
);
1000 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1003 if ( DestFileExists
== 1 )
1005 unlink(pszTmpDestFile
);
1008 return osl_File_E_None
;
1011 /*****************************************
1012 * oslChangeFileModes
1013 ****************************************/
1015 static oslFileError
oslChangeFileModes( const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
)
1018 struct utimbuf aTimeBuffer
;
1020 nRet
= chmod(pszFileName
,nMode
);
1024 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1027 aTimeBuffer
.actime
=nAcTime
;
1028 aTimeBuffer
.modtime
=nModTime
;
1029 nRet
=utime(pszFileName
,&aTimeBuffer
);
1033 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1036 if ( nUID
!= getuid() )
1041 nRet
=chown(pszFileName
,nUID
,nGID
);
1046 /* mfe: do not return an error here! */
1047 /* return oslTranslateFileError(nRet);*/
1050 return osl_File_E_None
;
1053 /*****************************************
1055 ****************************************/
1057 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
)
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
];
1065 pszLinkContent
[0] = '\0';
1067 nRet
= readlink(pszSourceFileName
,pszLinkContent
,PATH_MAX
);
1075 pszLinkContent
[ nRet
] = 0;
1077 nRet
= symlink(pszLinkContent
,pszDestFileName
);
1088 /*****************************************
1090 ****************************************/
1092 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
)
1097 void* pSourceFile
=0;
1100 SourceFileFD
=open(pszSourceFileName
,O_RDONLY
| O_BINARY
);
1101 if ( SourceFileFD
< 0 )
1107 DestFileFD
=open(pszDestFileName
, O_WRONLY
| O_CREAT
| O_BINARY
, mode
);
1108 if ( DestFileFD
< 0 )
1111 close(SourceFileFD
);
1115 /* HACK: because memory mapping fails on various
1116 platforms if the size of the source file is 0 byte */
1117 if (0 == nSourceSize
)
1119 close(SourceFileFD
);
1124 while( (nRet
= read(SourceFileFD
, buffer
, sizeof(buffer
))) !=0 )
1126 nRet
= write( DestFileFD
, buffer
, nRet
);
1129 close(SourceFileFD
);
1135 static oslFileError
osl_psz_copyFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
1143 struct stat aFileStat
;
1144 oslFileError tErr
=osl_File_E_invalidError
;
1145 size_t nSourceSize
=0;
1146 int DestFileExists
=1;
1148 /* mfe: does the source file really exists? */
1149 nRet
= lstat(pszPath
,&aFileStat
);
1154 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1157 /* mfe: we do only copy files here! */
1158 if ( S_ISDIR(aFileStat
.st_mode
) )
1160 return osl_File_E_ISDIR
;
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
;
1170 nRet
= stat(pszDestPath
,&aFileStat
);
1175 if ( nRet
== ENOENT
)
1179 /* return oslTranslateFileError(nRet);*/
1182 /* mfe: the destination file must not be a directory! */
1183 if ( nRet
== 0 && S_ISDIR(aFileStat
.st_mode
) )
1185 return osl_File_E_ISDIR
;
1189 /* mfe: file does not exists or is no dir */
1192 tErr
= oslDoCopy(pszPath
,pszDestPath
,nMode
,nSourceSize
,DestFileExists
);
1194 if ( tErr
!= osl_File_E_None
)
1200 * mfe: ignore return code
1201 * since only the success of the copy is
1204 oslChangeFileModes(pszDestPath
,nMode
,nAcTime
,nModTime
,nUID
,nGID
);
1209 oslFileError
osl_copyFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
1211 char srcPath
[PATH_MAX
];
1212 char destPath
[PATH_MAX
];
1216 OSL_ASSERT( ustrFileURL
);
1217 OSL_ASSERT( ustrDestURL
);
1219 /* convert source url to system path */
1220 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
1221 if( eRet
!= osl_File_E_None
)
1224 /* convert destination url to system path */
1225 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
1226 if( eRet
!= osl_File_E_None
)
1229 return osl_psz_copyFile( srcPath
, destPath
);
1232 /****************************************************************************/
1233 /* osl_removeFile */
1234 /****************************************************************************/
1236 oslFileError
osl_removeFile( rtl_uString
* ustrFileURL
)
1238 char path
[PATH_MAX
];
1242 OSL_ASSERT( ustrFileURL
);
1244 /* convert file url to system path */
1245 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
1246 if( eRet
!= osl_File_E_None
)
1249 rc
= DosDelete( (PCSZ
)path
);
1251 eRet
= osl_File_E_None
;
1253 eRet
= MapError( rc
);
1258 /****************************************************************************/
1259 /* osl_getVolumeInformation */
1260 /****************************************************************************/
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
1266 typedef struct drivecmd
1268 BYTE cmd
; // 0=unlock 1=lock 2=eject
1269 BYTE drv
; // 0=A, 1=B 2=C ...
1270 } DRIVECMD
; // end of struct "drivecmd"
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
1289 typedef struct drivebpb
1291 TXFS_EBPB ebpb
; // extended BPB
1295 USHORT attributes
; // device attributes
1296 BYTE fill
[6]; // documented for IOCtl
1297 } DRIVEBPB
; // end of struct "drivebpb"
1306 /*****************************************************************************/
1307 // Get number of cdrom readers
1308 /*****************************************************************************/
1309 BOOL
GetCDInfo( CDInfo
* pCDInfo
)
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
);
1326 pCDInfo
->usFirst
= 0;
1327 pCDInfo
->usCount
= 0;
1331 /*****************************************************************************/
1332 // Determine if unit is a cdrom or not
1333 /*****************************************************************************/
1334 BOOL
DriveIsCDROM(UINT uiDrive
, CDInfo
*pCDInfo
)
1336 return (uiDrive
>= pCDInfo
->usFirst
)
1337 && (uiDrive
< (pCDInfo
->usFirst
+ pCDInfo
->usCount
));
1340 /*****************************************************************************/
1341 // Determine attached fstype, e.g. HPFS for specified drive
1342 /*****************************************************************************/
1343 BOOL TxFsType
// RET FS type resolved
1345 char *drive
, // IN Drive specification
1346 char *fstype
, // OUT Attached FS type
1347 char *details
// OUT details (UNC) or NULL
1351 FSQBUFFER2
*fsinfo
; // Attached FS info
1352 ULONG fsdlen
= 2048; // Fs info data length
1354 strcpy(fstype
, "none");
1357 strcpy(details
, "");
1359 if ((fsinfo
= (FSQBUFFER2
*)calloc(1, fsdlen
)) != NULL
)
1361 if (DosQFSAttach((PCSZ
)drive
, 0, 1, fsinfo
, &fsdlen
) == NO_ERROR
)
1363 strcpy(fstype
, (char*) fsinfo
->szName
+ fsinfo
->cbName
+1);
1364 if (details
&& (fsinfo
->cbFSAData
!= 0))
1366 strcpy( details
, (char*) fsinfo
->szName
+ fsinfo
->cbName
+
1367 fsinfo
->cbFSDName
+2);
1375 /*---------------------------------------------------------------------------*/
1378 /*****************************************************************************/
1379 // Determine if a driveletter represents a removable medium/device
1380 /*****************************************************************************/
1381 BOOL TxFsIsRemovable
// RET drive is removable
1383 char *drive
// IN Driveletter to test
1393 DosError( FERR_DISABLEHARDERR
); // avoid 'not ready' popups
1395 ParmLen
= sizeof(IOCtl
);
1396 IOCtl
.cmd
= TXFSDC_BLOCKR
;
1397 IOCtl
.drv
= toupper(drive
[0]) - 'A';
1398 DataLen
= sizeof(NoRem
);
1400 if (DosDevIOCtl((HFILE
) -1, IOCTL_DISK
,
1402 &IOCtl
, ParmLen
, &ParmLen
,
1403 &NoRem
, DataLen
, &DataLen
) == NO_ERROR
)
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
);
1412 if (DosDevIOCtl((HFILE
) -1, IOCTL_DISK
,
1413 DSK_GETDEVICEPARAMS
,
1414 &IOCtl
, ParmLen
, &ParmLen
,
1415 &RemAt
, DataLen
, &DataLen
) == NO_ERROR
)
1418 if (RemAt
.attributes
& TXFSBPB_REMOVABLE
)
1420 rc
= TRUE
; // removable, probably USB
1426 rc
= TRUE
; // removable block device
1429 DosError( FERR_ENABLEHARDERR
); // enable criterror handler
1431 } // end 'TxFsIsRemovable'
1432 /*---------------------------------------------------------------------------*/
1434 static oslFileError
get_drive_type(const char* path
, oslVolumeInfo
* pInfo
)
1436 char Drive_Letter
= toupper( *path
);
1439 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1441 // check for floppy A/B
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
;
1451 // query system for CD drives
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
;
1459 if (TxFsIsRemovable( (char*)path
))
1460 pInfo
->uAttributes
|= osl_Volume_Attribute_Removeable
;
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
;
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
;
1479 pInfo
->uAttributes
|= osl_Volume_Attribute_FixedDisk
;
1481 return osl_File_E_None
;
1484 //#############################################
1485 inline bool is_volume_space_info_request(sal_uInt32 field_mask
)
1487 return (field_mask
&
1488 (osl_VolumeInfo_Mask_TotalSpace
|
1489 osl_VolumeInfo_Mask_UsedSpace
|
1490 osl_VolumeInfo_Mask_FreeSpace
));
1493 //#############################################
1494 static void get_volume_space_information(const char* path
, oslVolumeInfo
*pInfo
)
1496 FSALLOCATE aFSInfoBuf
;
1497 ULONG nDriveNumber
= toupper( *path
) - 'A' + 1;
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
);
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
;
1518 //#############################################
1519 inline bool is_filesystem_attributes_request(sal_uInt32 field_mask
)
1521 return (field_mask
&
1522 (osl_VolumeInfo_Mask_MaxNameLength
|
1523 osl_VolumeInfo_Mask_MaxPathLength
|
1524 osl_VolumeInfo_Mask_FileSystemName
|
1525 osl_VolumeInfo_Mask_FileSystemCaseHandling
));
1528 //#############################################
1529 inline bool is_drivetype_request(sal_uInt32 field_mask
)
1531 return (field_mask
& osl_VolumeInfo_Mask_Attributes
);
1534 typedef struct _FSQBUFFER_
1540 //#############################################
1541 static oslFileError
get_filesystem_attributes(const char* path
, sal_uInt32 field_mask
, oslVolumeInfo
* pInfo
)
1543 pInfo
->uAttributes
= 0;
1545 oslFileError osl_error
= osl_File_E_None
;
1547 // osl_get_drive_type must be called first because
1548 // this function resets osl_VolumeInfo_Mask_Attributes
1550 if (is_drivetype_request(field_mask
))
1551 osl_error
= get_drive_type(path
, pInfo
);
1553 if ((osl_File_E_None
== osl_error
) && is_filesystem_attributes_request(field_mask
))
1559 nBufLen
= sizeof( aBuf
);
1560 // disable error popups
1561 DosError(FERR_DISABLEHARDERR
);
1562 nRet
= DosQueryFSAttach( (PCSZ
)path
, 0, FSAIL_QUERYNAME
, (_FSQBUFFER2
*) &aBuf
, &nBufLen
);
1565 char *pType
= (char*)(aBuf
.aBuf
.szName
+ aBuf
.aBuf
.cbName
+ 1);
1566 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxNameLength
;
1567 pInfo
->uMaxNameLength
= _MAX_FNAME
;
1569 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxPathLength
;
1570 pInfo
->uMaxPathLength
= _MAX_PATH
;
1572 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FileSystemName
;
1573 rtl_uString_newFromAscii(&pInfo
->ustrFileSystemName
, pType
);
1575 // case is preserved always except for FAT
1576 if (strcmp( pType
, "FAT" ))
1577 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Is_Preserved
;
1579 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1581 // enable error popups
1582 DosError(FERR_ENABLEHARDERR
);
1587 oslFileError SAL_CALL
osl_getVolumeInformation( rtl_uString
* ustrDirectoryURL
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
1589 char volume_root
[PATH_MAX
];
1592 OSL_ASSERT( ustrDirectoryURL
);
1593 OSL_ASSERT( pInfo
);
1595 /* convert directory url to system path */
1596 error
= FileURLToPath( volume_root
, PATH_MAX
, ustrDirectoryURL
);
1597 if( error
!= osl_File_E_None
)
1601 return osl_File_E_INVAL
;
1603 pInfo
->uValidFields
= 0;
1605 if ((error
= get_filesystem_attributes(volume_root
, uFieldMask
, pInfo
)) != osl_File_E_None
)
1608 if (is_volume_space_info_request(uFieldMask
))
1609 get_volume_space_information(volume_root
, pInfo
);
1611 if (uFieldMask
& osl_VolumeInfo_Mask_DeviceHandle
)
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
);
1620 return osl_File_E_None
;
1623 /****************************************************************************/
1624 /* osl_getFileStatus */
1625 /****************************************************************************/
1626 static oslFileError
_osl_getDriveInfo(
1627 oslDirectoryItem Item
, oslFileStatus
*pStatus
, sal_uInt32 uFieldMask
)
1629 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
1630 sal_Unicode cDrive
[3];
1631 sal_Unicode cRoot
[4];
1634 return osl_File_E_INVAL
;
1636 pStatus
->uValidFields
= 0;
1638 cDrive
[0] = pItemImpl
->ustrDrive
->buffer
[0];
1639 cDrive
[1] = (sal_Unicode
)':';
1641 cRoot
[0] = pItemImpl
->ustrDrive
->buffer
[0];
1642 cRoot
[1] = (sal_Unicode
)':';
1645 if ( uFieldMask
& osl_FileStatus_Mask_FileName
)
1647 if ( pItemImpl
->ustrDrive
->buffer
[0] == '\\' &&
1648 pItemImpl
->ustrDrive
->buffer
[1] == '\\' )
1650 LPCWSTR lpFirstBkSlash
= wcschr( (const wchar_t*)&pItemImpl
->ustrDrive
->buffer
[2], '\\' );
1652 if ( lpFirstBkSlash
&& lpFirstBkSlash
[1] )
1654 LPCWSTR lpLastBkSlash
= wcschr( (const wchar_t*)&lpFirstBkSlash
[1], '\\' );
1656 if ( lpLastBkSlash
)
1657 rtl_uString_newFromStr_WithLength( &pStatus
->ustrFileName
, (sal_Unicode
*)&lpFirstBkSlash
[1], lpLastBkSlash
- lpFirstBkSlash
- 1 );
1659 rtl_uString_newFromStr( &pStatus
->ustrFileName
, (sal_Unicode
*)&lpFirstBkSlash
[1] );
1660 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1666 ULONG ulFSInfoLevel
= FSIL_VOLSER
;
1668 char szFileName
[ _MAX_PATH
];
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
);
1685 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1689 pStatus
->eType
= osl_File_Type_Volume
;
1690 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
1692 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
1694 rtl_uString
*ustrSystemPath
= NULL
;
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
;
1702 return osl_File_E_None
;
1705 oslFileError SAL_CALL
osl_getFileStatus(
1706 oslDirectoryItem Item
,
1707 oslFileStatus
*pStatus
,
1708 sal_uInt32 uFieldMask
)
1710 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
1711 struct stat file_stat
;
1714 return osl_File_E_INVAL
;
1716 if ( pItemImpl
->uType
== DIRECTORYITEM_DRIVE
)
1717 return _osl_getDriveInfo( Item
, pStatus
, uFieldMask
);
1719 osl::lstat(pItemImpl
->ustrFilePath
, file_stat
);
1720 if ( uFieldMask
& osl_FileStatus_Mask_Validate
)
1722 uFieldMask
&= ~ osl_FileStatus_Mask_Validate
;
1725 /* If no fields to retrieve left ignore pStatus */
1727 return osl_File_E_None
;
1729 /* Otherwise, this must be a valid pointer */
1731 return osl_File_E_INVAL
;
1733 if ( pStatus
->uStructSize
!= sizeof(oslFileStatus
) )
1734 return osl_File_E_INVAL
;
1736 pStatus
->uValidFields
= 0;
1738 /* File time stamps */
1740 if ( (uFieldMask
& osl_FileStatus_Mask_ModifyTime
))
1742 pStatus
->aModifyTime
.Seconds
= file_stat
.st_mtime
;
1743 pStatus
->aModifyTime
.Nanosec
= 0;
1744 pStatus
->uValidFields
|= osl_FileStatus_Mask_ModifyTime
;
1747 if ( (uFieldMask
& osl_FileStatus_Mask_AccessTime
))
1749 pStatus
->aAccessTime
.Seconds
= file_stat
.st_atime
;
1750 pStatus
->aAccessTime
.Nanosec
= 0;
1751 pStatus
->uValidFields
|= osl_FileStatus_Mask_AccessTime
;
1754 if ( (uFieldMask
& osl_FileStatus_Mask_CreationTime
))
1756 pStatus
->aAccessTime
.Seconds
= file_stat
.st_birthtime
;
1757 pStatus
->aAccessTime
.Nanosec
= 0;
1758 pStatus
->uValidFields
|= osl_FileStatus_Mask_CreationTime
;
1761 /* Most of the fields are already set, regardless of requiered fields */
1763 osl_systemPathGetFileNameOrLastDirectoryPart(pItemImpl
->ustrFilePath
, &pStatus
->ustrFileName
);
1764 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
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
;
1779 pStatus
->eType
= osl_File_Type_Unknown
;
1781 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
1783 pStatus
->uAttributes
= pItemImpl
->d_attr
;
1784 pStatus
->uValidFields
|= osl_FileStatus_Mask_Attributes
;
1786 pStatus
->uFileSize
= file_stat
.st_size
;
1787 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileSize
;
1789 if ( uFieldMask
& osl_FileStatus_Mask_LinkTargetURL
)
1791 rtl_uString
*ustrFullPath
= NULL
;
1793 rtl_uString_newFromStr( &ustrFullPath
, rtl_uString_getStr(pItemImpl
->ustrFilePath
) );
1794 osl_getFileURLFromSystemPath( ustrFullPath
, &pStatus
->ustrLinkTargetURL
);
1795 rtl_uString_release( ustrFullPath
);
1797 pStatus
->uValidFields
|= osl_FileStatus_Mask_LinkTargetURL
;
1800 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
1802 rtl_uString
*ustrFullPath
= NULL
;
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
;
1810 return osl_File_E_None
;
1813 /****************************************************************************/
1814 /* osl_createDirectory */
1815 /****************************************************************************/
1817 oslFileError
osl_createDirectory( rtl_uString
* ustrDirectoryURL
)
1819 char path
[PATH_MAX
];
1823 OSL_ASSERT( ustrDirectoryURL
);
1825 /* convert directory url to system path */
1826 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
1827 if( eRet
!= osl_File_E_None
)
1830 rc
= DosCreateDir( (PCSZ
)path
, NULL
);
1831 if (rc
== ERROR_ACCESS_DENIED
)
1832 rc
=ERROR_FILE_EXISTS
;
1835 eRet
= osl_File_E_None
;
1837 eRet
= MapError( rc
);
1842 /****************************************************************************/
1843 /* osl_removeDirectory */
1844 /****************************************************************************/
1846 oslFileError
osl_removeDirectory( rtl_uString
* ustrDirectoryURL
)
1848 char path
[PATH_MAX
];
1852 OSL_ASSERT( ustrDirectoryURL
);
1854 /* convert directory url to system path */
1855 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
1856 if( eRet
!= osl_File_E_None
)
1859 rc
= DosDeleteDir( (PCSZ
)path
);
1861 eRet
= osl_File_E_None
;
1863 eRet
= MapError( rc
);
1868 //#############################################
1869 int path_make_parent(sal_Unicode
* path
)
1871 int i
= rtl_ustr_lastIndexOfChar(path
, '/');
1882 //#############################################
1883 int create_dir_with_callback(
1884 sal_Unicode
* directory_path
,
1885 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1888 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
1890 if (osl::mkdir(directory_path
, mode
) == 0)
1892 if (aDirectoryCreationCallbackFunc
)
1895 osl::FileBase::getFileURLFromSystemPath(directory_path
, url
);
1896 aDirectoryCreationCallbackFunc(pData
, url
.pData
);
1903 //#############################################
1904 oslFileError
create_dir_recursively_(
1905 sal_Unicode
* dir_path
,
1906 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
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");
1912 int native_err
= create_dir_with_callback(
1913 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1915 if (native_err
== 0)
1916 return osl_File_E_None
;
1918 if (native_err
!= ENOENT
)
1919 return oslTranslateFileError(OSL_FET_ERROR
, native_err
);
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
1925 int pos
= path_make_parent(dir_path
);
1927 oslFileError osl_error
= create_dir_recursively_(
1928 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1930 if (osl_File_E_None
!= osl_error
)
1933 dir_path
[pos
] = '/';
1935 return create_dir_recursively_(dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1938 //#######################################
1939 oslFileError SAL_CALL
osl_createDirectoryPath(
1940 rtl_uString
* aDirectoryUrl
,
1941 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1944 if (aDirectoryUrl
== NULL
)
1945 return osl_File_E_INVAL
;
1947 rtl::OUString sys_path
;
1948 oslFileError osl_error
= osl_getSystemPathFromFileURL_Ex(
1949 aDirectoryUrl
, &sys_path
.pData
, sal_False
);
1951 if (osl_error
!= osl_File_E_None
)
1954 osl::systemPathRemoveSeparator(sys_path
);
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
);
1961 /****************************************************************************/
1962 /* osl_getCanonicalName */
1963 /****************************************************************************/
1965 oslFileError
osl_getCanonicalName( rtl_uString
* ustrFileURL
, rtl_uString
** pustrValidURL
)
1967 OSL_ENSURE(sal_False
, "osl_getCanonicalName not implemented");
1969 rtl_uString_newFromString(pustrValidURL
, ustrFileURL
);
1970 return osl_File_E_None
;
1974 /****************************************************************************/
1975 /* osl_setFileAttributes */
1976 /****************************************************************************/
1978 oslFileError
osl_setFileAttributes( rtl_uString
* ustrFileURL
, sal_uInt64 uAttributes
)
1980 char path
[PATH_MAX
];
1982 FILESTATUS3 fsts3ConfigInfo
;
1983 ULONG ulBufSize
= sizeof(FILESTATUS3
);
1984 APIRET rc
= NO_ERROR
;
1986 OSL_ASSERT( ustrFileURL
);
1988 /* convert file url to system path */
1989 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
1990 if( eRet
!= osl_File_E_None
)
1993 /* query current attributes */
1994 rc
= DosQueryPathInfo( (PCSZ
)path
, FIL_STANDARD
, &fsts3ConfigInfo
, ulBufSize
);
1996 return MapError( rc
);
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
;
2005 /* write new attributes */
2006 rc
= DosSetPathInfo( (PCSZ
)path
, FIL_STANDARD
, &fsts3ConfigInfo
, ulBufSize
, 0);
2008 return MapError( rc
);
2011 return osl_File_E_None
;
2014 /****************************************************************************/
2015 /* osl_setFileTime */
2016 /****************************************************************************/
2018 oslFileError
osl_setFileTime( rtl_uString
* ustrFileURL
, const TimeValue
* pCreationTime
,
2019 const TimeValue
* pLastAccessTime
, const TimeValue
* pLastWriteTime
)
2021 char path
[PATH_MAX
];
2024 OSL_ASSERT( ustrFileURL
);
2026 /* convert file url to system path */
2027 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
2028 if( eRet
!= osl_File_E_None
)
2031 return osl_psz_setFileTime( path
, pCreationTime
, pLastAccessTime
, pLastWriteTime
);
2034 /******************************************************************************
2036 * Exported Module Functions
2037 * (independent of C or Unicode Strings)
2039 *****************************************************************************/
2042 /*******************************************
2044 ********************************************/
2046 oslFileError
osl_readFile(oslFileHandle Handle
, void* pBuffer
, sal_uInt64 uBytesRequested
, sal_uInt64
* pBytesRead
)
2049 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*)Handle
;
2051 if ((0 == pHandleImpl
) || (pHandleImpl
->fd
< 0) || (0 == pBuffer
) || (0 == pBytesRead
))
2052 return osl_File_E_INVAL
;
2054 nBytes
= read(pHandleImpl
->fd
, pBuffer
, uBytesRequested
);
2057 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
2059 *pBytesRead
= nBytes
;
2060 return osl_File_E_None
;
2063 /*******************************************
2065 ********************************************/
2067 oslFileError
osl_writeFile(oslFileHandle Handle
, const void* pBuffer
, sal_uInt64 uBytesToWrite
, sal_uInt64
* pBytesWritten
)
2070 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*)Handle
;
2072 OSL_ASSERT(pHandleImpl
);
2073 OSL_ASSERT(pBuffer
);
2074 OSL_ASSERT(pBytesWritten
);
2076 if ((0 == pHandleImpl
) || (0 == pBuffer
) || (0 == pBytesWritten
))
2077 return osl_File_E_INVAL
;
2079 OSL_ASSERT(pHandleImpl
->fd
>= 0);
2081 if (pHandleImpl
->fd
< 0)
2082 return osl_File_E_INVAL
;
2084 nBytes
= write(pHandleImpl
->fd
, pBuffer
, uBytesToWrite
);
2087 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
2089 *pBytesWritten
= nBytes
;
2090 return osl_File_E_None
;
2093 /*******************************************
2095 ********************************************/
2097 oslFileError
osl_setFilePos( oslFileHandle Handle
, sal_uInt32 uHow
, sal_Int64 uPos
)
2099 oslFileHandleImpl
* pHandleImpl
=0;
2103 pHandleImpl
= (oslFileHandleImpl
*) Handle
;
2104 if ( pHandleImpl
== 0 )
2106 return osl_File_E_INVAL
;
2109 if ( pHandleImpl
->fd
< 0 )
2111 return osl_File_E_INVAL
;
2114 /* FIXME mfe: setFilePos: Do we have any runtime function to determine LONG_MAX? */
2115 if ( uPos
> LONG_MAX
)
2117 return osl_File_E_OVERFLOW
;
2120 nOffset
=(off_t
)uPos
;
2124 case osl_Pos_Absolut
:
2125 nOffset
= lseek(pHandleImpl
->fd
,nOffset
,SEEK_SET
);
2128 case osl_Pos_Current
:
2129 nOffset
= lseek(pHandleImpl
->fd
,nOffset
,SEEK_CUR
);
2133 nOffset
= lseek(pHandleImpl
->fd
,nOffset
,SEEK_END
);
2137 return osl_File_E_INVAL
;
2143 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2146 return osl_File_E_None
;
2149 /************************************************
2151 ***********************************************/
2153 oslFileError
osl_getFilePos( oslFileHandle Handle
, sal_uInt64
* pPos
)
2155 oslFileHandleImpl
* pHandleImpl
=0;
2159 pHandleImpl
= (oslFileHandleImpl
*) Handle
;
2160 if ( pHandleImpl
== 0 || pPos
== 0)
2162 return osl_File_E_INVAL
;
2165 if ( pHandleImpl
->fd
< 0 )
2167 return osl_File_E_INVAL
;
2170 nOffset
= lseek(pHandleImpl
->fd
,0,SEEK_CUR
);
2178 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2183 return osl_File_E_None
;
2186 /****************************************************************************
2188 ****************************************************************************/
2190 oslFileError
osl_getFileSize( oslFileHandle Handle
, sal_uInt64
* pSize
)
2192 oslFileHandleImpl
* pHandleImpl
=(oslFileHandleImpl
*) Handle
;
2193 if (pHandleImpl
== 0)
2194 return osl_File_E_INVAL
;
2196 struct stat file_stat
;
2197 if (fstat(pHandleImpl
->fd
, &file_stat
) == -1)
2198 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
2200 *pSize
= file_stat
.st_size
;
2201 return osl_File_E_None
;
2204 /************************************************
2206 ***********************************************/
2208 oslFileError
osl_setFileSize( oslFileHandle Handle
, sal_uInt64 uSize
)
2210 oslFileHandleImpl
* pHandleImpl
=0;
2213 pHandleImpl
= (oslFileHandleImpl
*) Handle
;
2214 if ( pHandleImpl
== 0 )
2216 return osl_File_E_INVAL
;
2219 if ( pHandleImpl
->fd
< 0 )
2221 return osl_File_E_INVAL
;
2224 /* FIXME: mfe: setFileSize: Do we have any runtime function to determine LONG_MAX? */
2225 if ( uSize
> LONG_MAX
)
2227 return osl_File_E_OVERFLOW
;
2230 nOffset
= (off_t
)uSize
;
2231 if (ftruncate (pHandleImpl
->fd
, nOffset
) < 0)
2233 /* Failure. Try fallback algorithm */
2234 oslFileError result
;
2238 /* Save original result */
2239 result
= oslTranslateFileError (OSL_FET_ERROR
, errno
);
2240 PERROR("ftruncate", "Try osl_setFileSize [fallback]\n");
2242 /* Check against current size. Fail upon 'shrink' */
2243 if (fstat (pHandleImpl
->fd
, &aStat
) < 0)
2245 PERROR("ftruncate: fstat", "Out osl_setFileSize [error]\n");
2248 if ((0 <= nOffset
) && (nOffset
<= aStat
.st_size
))
2250 /* Failure upon 'shrink'. Return original result */
2254 /* Save current position */
2255 nCurPos
= (off_t
)lseek (pHandleImpl
->fd
, (off_t
)0, SEEK_CUR
);
2256 if (nCurPos
== (off_t
)(-1))
2258 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2262 /* Try 'expand' via 'lseek()' and 'write()' */
2263 if (lseek (pHandleImpl
->fd
, (off_t
)(nOffset
- 1), SEEK_SET
) < 0)
2265 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2268 if (write (pHandleImpl
->fd
, (char*)"", (size_t)1) < 0)
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)
2274 #ifdef DEBUG_OSL_FILE
2275 perror("ftruncate: lseek");
2276 #endif /* DEBUG_OSL_FILE */
2281 /* Success. Restore saved position */
2282 if (lseek (pHandleImpl
->fd
, (off_t
)nCurPos
, SEEK_SET
) < 0)
2284 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]");
2289 return (osl_File_E_None
);
2292 /*###############################################*/
2293 oslFileError SAL_CALL
osl_syncFile(oslFileHandle Handle
)
2295 oslFileHandleImpl
* handle_impl
= (oslFileHandleImpl
*)Handle
;
2297 if (handle_impl
== 0)
2298 return osl_File_E_INVAL
;
2300 if (fsync(handle_impl
->fd
) == -1)
2301 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
2303 return osl_File_E_None
;
2306 /******************************************************************************
2308 * C-String Versions of Exported Module Functions
2310 *****************************************************************************/
2312 #ifdef HAVE_STATFS_H
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)
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 */
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))
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)
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 */
2357 # define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
2359 #else /* no statfs available */
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 */
2370 static oslFileError
osl_psz_getVolumeInformation (
2371 const sal_Char
* pszDirectory
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
2373 __OSL_STATFS_STRUCT sfs
;
2376 return osl_File_E_INVAL
;
2378 __OSL_STATFS_INIT(sfs
);
2380 pInfo
->uValidFields
= 0;
2381 pInfo
->uAttributes
= 0;
2383 if ((__OSL_STATFS(pszDirectory
, &sfs
)) < 0)
2385 oslFileError result
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
2389 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
2390 if (uFieldMask
& osl_VolumeInfo_Mask_Attributes
)
2392 if (__OSL_STATFS_ISREMOTE(sfs
))
2393 pInfo
->uAttributes
|= osl_Volume_Attribute_Remote
;
2395 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
2398 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemCaseHandling
)
2400 if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs
))
2401 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Sensitive
;
2403 if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs
))
2404 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Is_Preserved
;
2406 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
2409 pInfo
->uTotalSpace
= 0;
2410 pInfo
->uFreeSpace
= 0;
2411 pInfo
->uUsedSpace
= 0;
2413 #if defined(__OSL_STATFS_BLKSIZ)
2415 if ((uFieldMask
& osl_VolumeInfo_Mask_TotalSpace
) ||
2416 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
2418 pInfo
->uTotalSpace
= __OSL_STATFS_BLKSIZ(sfs
);
2419 pInfo
->uTotalSpace
*= (sal_uInt64
)(sfs
.f_blocks
);
2420 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_TotalSpace
;
2423 if ((uFieldMask
& osl_VolumeInfo_Mask_FreeSpace
) ||
2424 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
2426 pInfo
->uFreeSpace
= __OSL_STATFS_BLKSIZ(sfs
);
2429 pInfo
->uFreeSpace
*= (sal_uInt64
)(sfs
.f_bfree
);
2431 pInfo
->uFreeSpace
*= (sal_uInt64
)(sfs
.f_bavail
);
2433 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FreeSpace
;
2436 #endif /* __OSL_STATFS_BLKSIZ */
2438 if ((pInfo
->uValidFields
& osl_VolumeInfo_Mask_TotalSpace
) &&
2439 (pInfo
->uValidFields
& osl_VolumeInfo_Mask_FreeSpace
))
2441 pInfo
->uUsedSpace
= pInfo
->uTotalSpace
- pInfo
->uFreeSpace
;
2442 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_UsedSpace
;
2445 pInfo
->uMaxNameLength
= 0;
2446 if (uFieldMask
& osl_VolumeInfo_Mask_MaxNameLength
)
2448 long nLen
= pathconf(pszDirectory
, _PC_NAME_MAX
);
2451 pInfo
->uMaxNameLength
= (sal_uInt32
)nLen
;
2452 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxNameLength
;
2456 pInfo
->uMaxPathLength
= 0;
2457 if (uFieldMask
& osl_VolumeInfo_Mask_MaxPathLength
)
2459 long nLen
= pathconf (pszDirectory
, _PC_PATH_MAX
);
2462 pInfo
->uMaxPathLength
= (sal_uInt32
)nLen
;
2463 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxPathLength
;
2467 #if defined(__OSL_STATFS_TYPENAME)
2469 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemName
)
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);
2479 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FileSystemName
;
2482 #endif /* __OSL_STATFS_TYPENAME */
2484 if (uFieldMask
& osl_VolumeInfo_Mask_DeviceHandle
)
2486 /* FIXME: check also entries in mntent for the device
2487 and fill it with correct values */
2489 *pInfo
->pDeviceHandle
= osl_isFloppyDrive(pszDirectory
);
2491 if (*pInfo
->pDeviceHandle
)
2493 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_DeviceHandle
;
2494 pInfo
->uAttributes
|= osl_Volume_Attribute_Removeable
;
2495 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
2498 return osl_File_E_None
;
2501 /******************************************
2502 * osl_psz_setFileTime
2503 *****************************************/
2505 static oslFileError
osl_psz_setFileTime( const sal_Char
* pszFilePath
,
2506 const TimeValue
* /*pCreationTime*/,
2507 const TimeValue
* pLastAccessTime
,
2508 const TimeValue
* pLastWriteTime
)
2511 struct utimbuf aTimeBuffer
;
2512 struct stat aFileStat
;
2513 #ifdef DEBUG_OSL_FILE
2517 nRet
= lstat(pszFilePath
,&aFileStat
);
2522 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
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
));
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
));
2540 if ( pLastAccessTime
!= 0 )
2542 aTimeBuffer
.actime
=pLastAccessTime
->Seconds
;
2546 aTimeBuffer
.actime
=aFileStat
.st_atime
;
2549 if ( pLastWriteTime
!= 0 )
2551 aTimeBuffer
.modtime
=pLastWriteTime
->Seconds
;
2555 aTimeBuffer
.modtime
=aFileStat
.st_mtime
;
2558 /* mfe: Creation time not used here! */
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
));
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
));
2575 nRet
=utime(pszFilePath
,&aTimeBuffer
);
2579 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2582 return osl_File_E_None
;
2586 /*****************************************
2587 * osl_psz_removeFile
2588 ****************************************/
2590 static oslFileError
osl_psz_removeFile( const sal_Char
* pszPath
)
2595 nRet
= stat(pszPath
,&aStat
);
2599 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2602 if ( S_ISDIR(aStat
.st_mode
) )
2604 return osl_File_E_ISDIR
;
2607 nRet
= unlink(pszPath
);
2611 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2614 return osl_File_E_None
;
2618 /*****************************************
2619 * osl_psz_createDirectory
2620 ****************************************/
2622 static oslFileError
osl_psz_createDirectory( const sal_Char
* pszPath
)
2625 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
2627 nRet
= mkdir(pszPath
,mode
);
2632 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2635 return osl_File_E_None
;
2638 /*****************************************
2639 * osl_psz_removeDirectory
2640 ****************************************/
2642 static oslFileError
osl_psz_removeDirectory( const sal_Char
* pszPath
)
2646 nRet
= rmdir(pszPath
);
2651 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2654 return osl_File_E_None
;
2657 /*****************************************
2659 ****************************************/
2661 static oslFileError
oslDoMoveFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
2663 oslFileError tErr
=osl_File_E_invalidError
;
2665 tErr
= osl_psz_moveFile(pszPath
,pszDestPath
);
2666 if ( tErr
== osl_File_E_None
)
2671 if ( tErr
!= osl_File_E_XDEV
)
2676 tErr
=osl_psz_copyFile(pszPath
,pszDestPath
);
2678 if ( tErr
!= osl_File_E_None
)
2680 oslFileError tErrRemove
;
2681 tErrRemove
=osl_psz_removeFile(pszDestPath
);
2685 tErr
=osl_psz_removeFile(pszPath
);
2690 /*****************************************
2692 ****************************************/
2694 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
2699 nRet
= rename(pszPath
,pszDestPath
);
2704 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2707 return osl_File_E_None
;
2710 /*****************************************
2712 ****************************************/
2714 static oslFileError
osl_psz_copyFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
2722 struct stat aFileStat
;
2723 oslFileError tErr
=osl_File_E_invalidError
;
2724 size_t nSourceSize
=0;
2725 int DestFileExists
=1;
2727 /* mfe: does the source file really exists? */
2728 nRet
= lstat(pszPath
,&aFileStat
);
2733 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2736 /* mfe: we do only copy files here! */
2737 if ( S_ISDIR(aFileStat
.st_mode
) )
2739 return osl_File_E_ISDIR
;
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
;
2749 nRet
= stat(pszDestPath
,&aFileStat
);
2754 if ( nRet
== ENOENT
)
2758 /* return oslTranslateFileError(nRet);*/
2761 /* mfe: the destination file must not be a directory! */
2762 if ( nRet
== 0 && S_ISDIR(aFileStat
.st_mode
) )
2764 return osl_File_E_ISDIR
;
2768 /* mfe: file does not exists or is no dir */
2771 tErr
= oslDoCopy(pszPath
,pszDestPath
,nMode
,nSourceSize
,DestFileExists
);
2773 if ( tErr
!= osl_File_E_None
)
2779 * mfe: ignore return code
2780 * since only the success of the copy is
2783 oslChangeFileModes(pszDestPath
,nMode
,nAcTime
,nModTime
,nUID
,nGID
);
2789 /******************************************************************************
2793 *****************************************************************************/
2796 /*****************************************
2797 * oslMakeUStrFromPsz
2798 ****************************************/
2800 rtl_uString
* oslMakeUStrFromPsz(const sal_Char
* pszStr
, rtl_uString
** ustrValid
)
2805 rtl_str_getLength( pszStr
),
2806 osl_getThreadTextEncoding(),
2807 OUSTRING_TO_OSTRING_CVTFLAGS
);
2808 OSL_ASSERT(*ustrValid
!= 0);
2813 /*****************************************************************************
2815 * converting unicode to text manually saves us the penalty of a temporary
2816 * rtl_String object.
2817 ****************************************************************************/
2819 int UnicodeToText( char * buffer
, size_t bufLen
, const sal_Unicode
* uniText
, sal_Int32 uniTextLen
)
2821 rtl_UnicodeToTextConverter hConverter
;
2823 sal_Size nSrcChars
, nDestBytes
;
2825 /* stolen from rtl/string.c */
2826 hConverter
= rtl_createUnicodeToTextConverter( osl_getThreadTextEncoding() );
2828 nDestBytes
= rtl_convertUnicodeToText( hConverter
, 0, uniText
, uniTextLen
,
2830 OUSTRING_TO_OSTRING_CVTFLAGS
| RTL_UNICODETOTEXT_FLAGS_FLUSH
,
2831 &nInfo
, &nSrcChars
);
2833 rtl_destroyUnicodeToTextConverter( hConverter
);
2835 if( nInfo
& RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
)
2841 /* ensure trailing '\0' */
2842 buffer
[nDestBytes
] = '\0';
2847 /*****************************************************************************
2851 The text to convert.
2853 @param text_buffer_size
2854 The number of characters.
2859 @param unic_text_buffer_size
2860 The size in characters of the unicode buffer.
2862 ****************************************************************************/
2866 size_t text_buffer_size
,
2867 sal_Unicode
* unic_text
,
2868 sal_Int32 unic_text_buffer_size
)
2870 rtl_TextToUnicodeConverter hConverter
;
2873 sal_Size nDestBytes
;
2875 /* stolen from rtl/string.c */
2876 hConverter
= rtl_createTextToUnicodeConverter(osl_getThreadTextEncoding());
2878 nDestBytes
= rtl_convertTextToUnicode(hConverter
,
2880 text
, text_buffer_size
,
2881 unic_text
, unic_text_buffer_size
,
2882 OSTRING_TO_OUSTRING_CVTFLAGS
| RTL_TEXTTOUNICODE_FLAGS_FLUSH
,
2883 &nInfo
, &nSrcChars
);
2885 rtl_destroyTextToUnicodeConverter(hConverter
);
2887 if (nInfo
& RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL
)
2893 /* ensure trailing '\0' */
2894 unic_text
[nDestBytes
] = '\0';
2899 /******************************************************************************
2901 * GENERIC FLOPPY FUNCTIONS
2903 *****************************************************************************/
2906 /*****************************************
2907 * osl_unmountVolumeDevice
2908 ****************************************/
2910 oslFileError
osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle
)
2912 oslFileError tErr
= osl_File_E_NOSYS
;
2914 tErr
= osl_unmountFloppy(Handle
);
2916 /* Perhaps current working directory is set to mount point */
2920 sal_Char
*pszHomeDir
= getenv("HOME");
2922 if ( pszHomeDir
&& strlen( pszHomeDir
) && 0 == chdir( pszHomeDir
) )
2926 tErr
= osl_unmountFloppy(Handle
);
2928 OSL_ENSURE( tErr
, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
2935 /*****************************************
2936 * osl_automountVolumeDevice
2937 ****************************************/
2939 oslFileError
osl_automountVolumeDevice( oslVolumeDeviceHandle Handle
)
2941 oslFileError tErr
= osl_File_E_NOSYS
;
2943 tErr
= osl_mountFloppy(Handle
);
2948 /*****************************************
2949 * osl_getVolumeDeviceMountPath
2950 ****************************************/
2952 oslFileError
osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle
, rtl_uString
**pstrPath
)
2954 oslVolumeDeviceHandleImpl
* pItem
= (oslVolumeDeviceHandleImpl
*) Handle
;
2955 sal_Char Buffer
[PATH_MAX
];
2959 if ( pItem
== 0 || pstrPath
== 0 )
2961 return osl_File_E_INVAL
;
2964 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
2966 return osl_File_E_INVAL
;
2969 #ifdef DEBUG_OSL_FILE
2970 fprintf(stderr
,"Handle is:\n");
2971 osl_printFloppyHandle(pItem
);
2974 snprintf(Buffer
, sizeof(Buffer
), "file://%s", pItem
->pszMountPoint
);
2976 #ifdef DEBUG_OSL_FILE
2977 fprintf(stderr
,"Mount Point is: '%s'\n",Buffer
);
2980 oslMakeUStrFromPsz(Buffer
, pstrPath
);
2982 return osl_File_E_None
;
2985 /*****************************************
2986 * osl_acquireVolumeDeviceHandle
2987 ****************************************/
2989 oslFileError SAL_CALL
osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
2991 oslVolumeDeviceHandleImpl
* pItem
=(oslVolumeDeviceHandleImpl
*) Handle
;
2995 return osl_File_E_INVAL
;
2998 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3000 return osl_File_E_INVAL
;
3005 return osl_File_E_None
;
3008 /*****************************************
3009 * osl_releaseVolumeDeviceHandle
3010 ****************************************/
3012 oslFileError
osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
3014 oslVolumeDeviceHandleImpl
* pItem
=(oslVolumeDeviceHandleImpl
*) Handle
;
3018 return osl_File_E_INVAL
;
3021 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3023 return osl_File_E_INVAL
;
3028 if ( pItem
->RefCount
== 0 )
3030 rtl_freeMemory(pItem
);
3033 return osl_File_E_None
;
3036 /*****************************************
3037 * osl_newVolumeDeviceHandleImpl
3038 ****************************************/
3040 static oslVolumeDeviceHandleImpl
* osl_newVolumeDeviceHandleImpl()
3042 oslVolumeDeviceHandleImpl
* pHandle
;
3043 const size_t nSizeOfHandle
= sizeof(oslVolumeDeviceHandleImpl
);
3045 pHandle
= (oslVolumeDeviceHandleImpl
*) rtl_allocateMemory (nSizeOfHandle
);
3046 if (pHandle
!= NULL
)
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;
3060 /*****************************************
3061 * osl_freeVolumeDeviceHandleImpl
3062 ****************************************/
3064 static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl
* pHandle
)
3066 if (pHandle
!= NULL
)
3067 rtl_freeMemory (pHandle
);
3071 /******************************************************************************
3073 * OS/2 FLOPPY FUNCTIONS
3075 *****************************************************************************/
3078 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
)
3083 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
3085 return osl_File_E_BUSY
;
3088 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
3090 return osl_File_E_BUSY
;
3093 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
3098 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
)
3104 #ifdef DEBUG_OSL_FILE
3105 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl
* pItem
)
3109 fprintf(stderr
,"NULL Handle\n");
3112 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3114 #ifdef TRACE_OSL_FILE
3115 fprintf(stderr
,"Invalid Handle]\n");
3121 fprintf(stderr
,"MountPoint : '%s'\n",pItem
->pszMountPoint
);
3122 fprintf(stderr
,"FilePath : '%s'\n",pItem
->pszFilePath
);
3123 fprintf(stderr
,"Device : '%s'\n",pItem
->pszDevice
);