1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 /************************************************************************
35 * Fix osl_getCanonicalName
37 * - Fix: check for corresponding struct sizes in exported functions
38 * - check size/use of oslDirectory
39 * - check size/use of oslDirectoryItem
40 * - check size/use of oslFileStatus
41 * - check size/use of oslVolumeDeviceHandle
42 * - check size/use of oslVolumeInfo
43 * - check size/use of oslFileHandle
44 ***********************************************************************/
46 #define INCL_DOSDEVIOCTL // OS2 device definitions
49 #include <rtl/alloc.h>
51 #include "osl/file.hxx"
54 #include <sal/types.h>
55 #include <osl/thread.h>
56 #include <osl/diagnose.h>
57 #include "file_error_transl.h"
64 #include "file_path_helper.hxx"
65 #include "uunxapi.hxx"
79 #if OSL_DEBUG_LEVEL > 1
80 extern void debug_ustring(rtl_uString
*);
85 # define PERROR( a, b ) perror( a ); fprintf( stderr, b )
87 # define PERROR( a, b )
90 extern "C" oslFileHandle
osl_createFileHandleFromFD( int fd
);
92 struct errentry errtable
[] = {
93 { NO_ERROR
, osl_File_E_None
}, /* 0 */
94 { ERROR_INVALID_FUNCTION
, osl_File_E_INVAL
}, /* 1 */
95 { ERROR_FILE_NOT_FOUND
, osl_File_E_NOENT
}, /* 2 */
96 { ERROR_PATH_NOT_FOUND
, osl_File_E_NOENT
}, /* 3 */
97 { ERROR_TOO_MANY_OPEN_FILES
, osl_File_E_MFILE
}, /* 4 */
98 { ERROR_ACCESS_DENIED
, osl_File_E_ACCES
}, /* 5 */
99 { ERROR_INVALID_HANDLE
, osl_File_E_BADF
}, /* 6 */
100 { ERROR_ARENA_TRASHED
, osl_File_E_NOMEM
}, /* 7 */
101 { ERROR_NOT_ENOUGH_MEMORY
, osl_File_E_NOMEM
}, /* 8 */
102 { ERROR_INVALID_BLOCK
, osl_File_E_NOMEM
}, /* 9 */
103 { ERROR_BAD_ENVIRONMENT
, osl_File_E_2BIG
}, /* 10 */
104 { ERROR_BAD_FORMAT
, osl_File_E_NOEXEC
}, /* 11 */
105 { ERROR_INVALID_ACCESS
, osl_File_E_INVAL
}, /* 12 */
106 { ERROR_INVALID_DATA
, osl_File_E_INVAL
}, /* 13 */
107 { ERROR_INVALID_DRIVE
, osl_File_E_NOENT
}, /* 15 */
108 { ERROR_CURRENT_DIRECTORY
, osl_File_E_ACCES
}, /* 16 */
109 { ERROR_NOT_SAME_DEVICE
, osl_File_E_XDEV
}, /* 17 */
110 { ERROR_NO_MORE_FILES
, osl_File_E_NOENT
}, /* 18 */
111 { ERROR_NOT_READY
, osl_File_E_NOTREADY
}, /* 21 */
112 { ERROR_LOCK_VIOLATION
, osl_File_E_ACCES
}, /* 33 */
113 { ERROR_BAD_NETPATH
, osl_File_E_NOENT
}, /* 53 */
114 { ERROR_NETWORK_ACCESS_DENIED
, osl_File_E_ACCES
}, /* 65 */
115 { ERROR_BAD_NET_NAME
, osl_File_E_NOENT
}, /* 67 */
116 { ERROR_FILE_EXISTS
, osl_File_E_EXIST
}, /* 80 */
117 { ERROR_CANNOT_MAKE
, osl_File_E_ACCES
}, /* 82 */
118 { ERROR_FAIL_I24
, osl_File_E_ACCES
}, /* 83 */
119 { ERROR_INVALID_PARAMETER
, osl_File_E_INVAL
}, /* 87 */
120 { ERROR_NO_PROC_SLOTS
, osl_File_E_AGAIN
}, /* 89 */
121 { ERROR_DRIVE_LOCKED
, osl_File_E_ACCES
}, /* 108 */
122 { ERROR_BROKEN_PIPE
, osl_File_E_PIPE
}, /* 109 */
123 { ERROR_DISK_FULL
, osl_File_E_NOSPC
}, /* 112 */
124 { ERROR_INVALID_TARGET_HANDLE
, osl_File_E_BADF
}, /* 114 */
125 { ERROR_INVALID_HANDLE
, osl_File_E_INVAL
}, /* 124 */
126 { ERROR_WAIT_NO_CHILDREN
, osl_File_E_CHILD
}, /* 128 */
127 { ERROR_CHILD_NOT_COMPLETE
, osl_File_E_CHILD
}, /* 129 */
128 { ERROR_DIRECT_ACCESS_HANDLE
, osl_File_E_BADF
}, /* 130 */
129 { ERROR_NEGATIVE_SEEK
, osl_File_E_INVAL
}, /* 131 */
130 { ERROR_SEEK_ON_DEVICE
, osl_File_E_ACCES
}, /* 132 */
131 { ERROR_DIR_NOT_EMPTY
, osl_File_E_NOTEMPTY
}, /* 145 */
132 { ERROR_NOT_LOCKED
, osl_File_E_ACCES
}, /* 158 */
133 { ERROR_BAD_PATHNAME
, osl_File_E_NOENT
}, /* 161 */
134 { ERROR_MAX_THRDS_REACHED
, osl_File_E_AGAIN
}, /* 164 */
135 { ERROR_LOCK_FAILED
, osl_File_E_ACCES
}, /* 167 */
136 { ERROR_ALREADY_EXISTS
, osl_File_E_EXIST
}, /* 183 */
137 { ERROR_FILENAME_EXCED_RANGE
, osl_File_E_NOENT
}, /* 206 */
138 { ERROR_NESTING_NOT_ALLOWED
, osl_File_E_AGAIN
}, /* 215 */
139 { ERROR_DIRECTORY
, osl_File_E_NOENT
}, /* 267 */
140 //{ ERROR_NOT_ENOUGH_QUOTA, osl_File_E_NOMEM } /* 1816 */
143 #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
145 //#####################################################
146 oslFileError
MapError(APIRET dwError
)
148 for (int i
= 0; i
< ELEMENTS_OF_ARRAY(errtable
); ++i
)
150 if (dwError
== errtable
[i
].oscode
)
151 return static_cast<oslFileError
>(errtable
[i
].errnocode
);
153 return osl_File_E_INVAL
;
156 /******************************************************************************
160 *****************************************************************************/
162 static const char * pFileLockEnvVar
= (char *) -1;
165 /******************************************************************************
167 * C-String Function Declarations
169 *****************************************************************************/
171 static oslFileError
osl_psz_getVolumeInformation(const sal_Char
* , oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
);
172 static oslFileError
osl_psz_removeFile(const sal_Char
* pszPath
);
173 static oslFileError
osl_psz_createDirectory(const sal_Char
* pszPath
);
174 static oslFileError
osl_psz_removeDirectory(const sal_Char
* pszPath
);
175 static oslFileError
osl_psz_copyFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
176 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
177 static oslFileError
osl_psz_setFileTime(const sal_Char
* strFilePath
, const TimeValue
* pCreationTime
, const TimeValue
* pLastAccessTime
, const TimeValue
* pLastWriteTime
);
180 /******************************************************************************
182 * Static Module Utility Function Declarations
184 *****************************************************************************/
186 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
);
187 static oslFileError
oslChangeFileModes(const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
);
188 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
);
189 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
);
190 static oslFileError
oslDoMoveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
191 rtl_uString
* oslMakeUStrFromPsz(const sal_Char
* pszStr
,rtl_uString
** uStr
);
193 /******************************************************************************
195 * Non-Static Utility Function Declarations
197 *****************************************************************************/
199 extern "C" int UnicodeToText( char *, size_t, const sal_Unicode
*, sal_Int32
);
200 extern "C" int TextToUnicode(
201 const char* text
, size_t text_buffer_size
, sal_Unicode
* unic_text
, sal_Int32 unic_text_buffer_size
);
203 /******************************************************************************
205 * 'removeable device' aka floppy functions
207 *****************************************************************************/
209 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
);
210 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
);
211 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
);
213 #ifdef DEBUG_OSL_FILE
214 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl
* hFloppy
);
217 /**********************************************
219 * enumerate available drives
220 *********************************************/
221 static oslFileError
_osl_openLocalRoot( rtl_uString
*strDirectoryPath
, oslDirectory
*pDirectory
)
223 rtl_uString
*ustrSystemPath
= NULL
;
227 return osl_File_E_INVAL
;
231 error
= osl_getSystemPathFromFileURL_Ex( strDirectoryPath
, &ustrSystemPath
, sal_False
);
233 if ( osl_File_E_None
== error
)
235 /* create and initialize impl structure */
236 DirectoryImpl
* pDirImpl
= (DirectoryImpl
*) rtl_allocateMemory( sizeof(DirectoryImpl
) );
241 pDirImpl
->uType
= DIRECTORYTYPE_LOCALROOT
;
242 pDirImpl
->ustrPath
= ustrSystemPath
;
243 rc
= DosQueryCurrentDisk (&ulDriveNum
, &pDirImpl
->ulDriveMap
);
244 pDirImpl
->pDirStruct
= 0;
245 pDirImpl
->ulNextDrive
= 1;
246 pDirImpl
->ulNextDriveMask
= 1;
248 // determine number of floppy-drives
250 rc
= DosDevConfig( (void*) &nFloppies
, DEVINFO_FLOPPY
);
251 if (nFloppies
== 0) {
252 // if no floppies, start with 3rd drive (C:)
253 pDirImpl
->ulNextDrive
= 3;
254 pDirImpl
->ulNextDriveMask
<<= 2;
255 } else if (nFloppies
== 1) {
256 // mask drive B (second bit) in this case
257 pDirImpl
->ulDriveMap
&= ~0x02;
259 *pDirectory
= (oslDirectory
) pDirImpl
;
260 return osl_File_E_None
;
264 errno
= osl_File_E_NOMEM
;
269 rtl_uString_release( ustrSystemPath
);
273 /**********************************************
275 *********************************************/
276 static oslFileError SAL_CALL
_osl_getNextDrive(
277 oslDirectory Directory
, oslDirectoryItem
*pItem
, sal_uInt32 uHint
)
279 DirectoryImpl
*pDirImpl
= (DirectoryImpl
*)Directory
;
280 DirectoryItem_Impl
*pItemImpl
= NULL
;
281 rtl_uString
* ustrDrive
= NULL
;
285 uHint
= uHint
; /* avoid warnings */
288 return osl_File_E_INVAL
;
293 return osl_File_E_INVAL
;
295 while( pDirImpl
->ulNextDrive
<= 26)
297 // exit if bit==1 -> drive found
298 if (pDirImpl
->ulDriveMap
& pDirImpl
->ulNextDriveMask
) {
300 /* convert file name to unicode */
301 buffer
[0] = '@' + pDirImpl
->ulNextDrive
;
305 pItemImpl
= (DirectoryItem_Impl
*) rtl_allocateMemory(sizeof(DirectoryItem_Impl
));
307 return osl_File_E_NOMEM
;
309 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
310 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
311 pItemImpl
->nRefCount
= 1;
313 rtl_string2UString( &pItemImpl
->ustrDrive
, buffer
, 3,
314 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
315 OSL_ASSERT(pItemImpl
->ustrDrive
!= 0);
317 /* use drive as directory item */
318 *pItem
= (oslDirectoryItem
) pItemImpl
;
320 // scan next bit position
321 pDirImpl
->ulNextDrive
++;
322 pDirImpl
->ulNextDriveMask
<<= 1;
324 if (*pItem
) // item assigned, return now.
325 return osl_File_E_None
;
329 return osl_File_E_NOENT
;
332 /**********************************************
335 * readdir wrapper, filters out "." and ".."
337 *********************************************/
339 static struct dirent
* _osl_readdir_impl_(DIR* pdir
, sal_Bool bFilterLocalAndParentDir
)
341 struct dirent
* pdirent
;
343 while ((pdirent
= readdir(pdir
)) != NULL
)
345 if (bFilterLocalAndParentDir
&&
346 ((0 == strcmp(pdirent
->d_name
, ".")) || (0 == strcmp(pdirent
->d_name
, ".."))))
355 /*******************************************************************
357 ******************************************************************/
359 oslFileError SAL_CALL
osl_openDirectory(rtl_uString
* ustrDirectoryURL
, oslDirectory
* pDirectory
)
361 rtl_uString
* ustrSystemPath
= NULL
;
366 OSL_ASSERT(ustrDirectoryURL
&& (ustrDirectoryURL
->length
> 0));
367 OSL_ASSERT(pDirectory
);
369 if (0 == ustrDirectoryURL
->length
)
370 return osl_File_E_INVAL
;
372 if ( 0 == rtl_ustr_compareIgnoreAsciiCase( ustrDirectoryURL
->buffer
, (const sal_Unicode
*)L
"file:///" ) )
373 return _osl_openLocalRoot( ustrDirectoryURL
, pDirectory
);
375 /* convert file URL to system path */
376 eRet
= osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL
, &ustrSystemPath
, sal_False
);
378 if( osl_File_E_None
!= eRet
)
381 osl_systemPathRemoveSeparator(ustrSystemPath
);
383 /* convert unicode path to text */
384 if ( UnicodeToText( path
, PATH_MAX
, ustrSystemPath
->buffer
, ustrSystemPath
->length
) )
386 // if only the drive is specified (x:), add a \ (x:\) otherwise current
387 // directory is browsed instead of root.
388 if (strlen( path
) == 2 && path
[1] == ':')
391 DIR *pdir
= opendir( path
);
395 /* create and initialize impl structure */
396 DirectoryImpl
* pDirImpl
= (DirectoryImpl
*) rtl_allocateMemory( sizeof(DirectoryImpl
) );
400 pDirImpl
->uType
= DIRECTORYTYPE_FILESYSTEM
;
401 pDirImpl
->pDirStruct
= pdir
;
402 pDirImpl
->ustrPath
= ustrSystemPath
;
404 *pDirectory
= (oslDirectory
) pDirImpl
;
405 return osl_File_E_None
;
414 /* should be removed by optimizer in product version */
415 PERROR( "osl_openDirectory", path
);
418 rtl_uString_release( ustrSystemPath
);
420 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
424 /****************************************************************************
425 * osl_getNextDirectoryItem
426 ***************************************************************************/
428 oslFileError SAL_CALL
osl_getNextDirectoryItem(oslDirectory Directory
, oslDirectoryItem
* pItem
, sal_uInt32 uHint
)
430 DirectoryImpl
* pDirImpl
= (DirectoryImpl
*)Directory
;
431 DirectoryItem_Impl
*pItemImpl
= NULL
;
432 rtl_uString
* ustrFileName
= NULL
;
433 rtl_uString
* ustrFilePath
= NULL
;
434 struct dirent
* pEntry
;
436 OSL_ASSERT(Directory
);
439 if ((NULL
== Directory
) || (NULL
== pItem
))
440 return osl_File_E_INVAL
;
442 if ( pDirImpl
->uType
== DIRECTORYTYPE_LOCALROOT
)
443 return _osl_getNextDrive( Directory
, pItem
, uHint
);
445 pEntry
= _osl_readdir_impl_(pDirImpl
->pDirStruct
, sal_True
);
448 return osl_File_E_NOENT
;
450 pItemImpl
= (DirectoryItem_Impl
*) rtl_allocateMemory(sizeof(DirectoryItem_Impl
));
452 return osl_File_E_NOMEM
;
454 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
455 pItemImpl
->uType
= DIRECTORYITEM_FILE
;
456 pItemImpl
->nRefCount
= 1;
457 pItemImpl
->d_attr
= pEntry
->d_attr
;
459 /* convert file name to unicode */
460 rtl_string2UString( &ustrFileName
, pEntry
->d_name
, strlen( pEntry
->d_name
),
461 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
462 OSL_ASSERT(ustrFileName
!= 0);
464 osl_systemPathMakeAbsolutePath(pDirImpl
->ustrPath
, ustrFileName
, &pItemImpl
->ustrFilePath
);
465 rtl_uString_release( ustrFileName
);
467 *pItem
= (oslDirectoryItem
)pItemImpl
;
468 return osl_File_E_None
;
471 /****************************************************************************/
472 /* osl_closeDirectory */
473 /****************************************************************************/
475 oslFileError SAL_CALL
osl_closeDirectory( oslDirectory Directory
)
477 DirectoryImpl
* pDirImpl
= (DirectoryImpl
*) Directory
;
478 oslFileError err
= osl_File_E_None
;
480 OSL_ASSERT( Directory
);
482 if( NULL
== pDirImpl
)
483 return osl_File_E_INVAL
;
485 switch ( pDirImpl
->uType
)
487 case DIRECTORYTYPE_FILESYSTEM
:
488 if( closedir( pDirImpl
->pDirStruct
) )
489 err
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
491 case DIRECTORYTYPE_LOCALROOT
:
492 err
= osl_File_E_None
;
495 case DIRECTORYTYPE_NETROOT
:
497 DWORD err
= WNetCloseEnum(pDirImpl
->hDirectory
);
498 eError
= (err
== NO_ERROR
) ? osl_File_E_None
: MapError(err
);
503 OSL_ENSURE( 0, "Invalid directory type" );
507 /* cleanup members */
508 rtl_uString_release( pDirImpl
->ustrPath
);
510 rtl_freeMemory( pDirImpl
);
515 /****************************************************************************/
516 /* osl_getDirectoryItem */
517 /****************************************************************************/
519 oslFileError SAL_CALL
osl_getDirectoryItem( rtl_uString
* ustrFileURL
, oslDirectoryItem
* pItem
)
521 rtl_uString
* strSysFilePath
= NULL
;
522 oslFileError error
= osl_File_E_INVAL
;
524 PATHTYPE type
= PATHTYPE_FILE
;
526 OSL_ASSERT(ustrFileURL
);
531 return osl_File_E_INVAL
;
534 if (0 == ustrFileURL
->length
|| NULL
== pItem
)
535 return osl_File_E_INVAL
;
537 error
= osl_getSystemPathFromFileURL_Ex(ustrFileURL
, &strSysFilePath
, sal_False
);
539 if (osl_File_E_None
!= error
)
542 dwPathType
= IsValidFilePath( strSysFilePath
->buffer
, NULL
, VALIDATEPATH_NORMAL
);
544 if ( dwPathType
& PATHTYPE_IS_VOLUME
)
545 type
= PATHTYPE_VOLUME
;
546 else if ( dwPathType
& PATHTYPE_IS_SERVER
)
547 type
= PATHTYPE_NETSERVER
;
549 type
= PATHTYPE_FILE
;
553 case PATHTYPE_NETSERVER
:
555 DirectoryItem_Impl
* pItemImpl
=
556 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
559 error
= osl_File_E_NOMEM
;
561 if ( osl_File_E_None
== error
)
563 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
564 pItemImpl
->uType
= DIRECTORYITEM_SERVER
;
565 pItemImpl
->nRefCount
= 1;
566 rtl_uString_assign( &pItemImpl
->ustrFilePath
, strSysFilePath
);
572 case PATHTYPE_VOLUME
:
574 DirectoryItem_Impl
* pItemImpl
=
575 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
578 error
= osl_File_E_NOMEM
;
580 if ( osl_File_E_None
== error
)
582 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
583 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
584 pItemImpl
->nRefCount
= 1;
585 rtl_uString_assign( &pItemImpl
->ustrDrive
, strSysFilePath
);
587 if ( pItemImpl
->ustrDrive
->buffer
[pItemImpl
->ustrDrive
->length
-1] != sal_Unicode('\\') )
588 rtl_uString_newConcat( &pItemImpl
->ustrDrive
,
589 pItemImpl
->ustrDrive
, rtl::OUString::createFromAscii( "\\" ).pData
);
598 if ( strSysFilePath
->length
> 0 && strSysFilePath
->buffer
[strSysFilePath
->length
- 1] == '\\' )
599 rtl_uString_newFromStr_WithLength( &strSysFilePath
, strSysFilePath
->buffer
, strSysFilePath
->length
- 1 );
601 if (0 == access_u(strSysFilePath
, F_OK
))
603 DirectoryItem_Impl
*pItemImpl
=
604 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
606 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
607 pItemImpl
->uType
= DIRECTORYITEM_FILE
;
608 pItemImpl
->nRefCount
= 1;
609 rtl_uString_assign( &pItemImpl
->ustrFilePath
, strSysFilePath
);
614 error
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
619 if ( strSysFilePath
)
620 rtl_uString_release( strSysFilePath
);
625 /****************************************************************************/
626 /* osl_acquireDirectoryItem */
627 /****************************************************************************/
629 oslFileError
osl_acquireDirectoryItem( oslDirectoryItem Item
)
632 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
635 return osl_File_E_INVAL
;
637 pItemImpl
->nRefCount
++;
638 return osl_File_E_None
;
641 /****************************************************************************/
642 /* osl_releaseDirectoryItem */
643 /****************************************************************************/
645 oslFileError
osl_releaseDirectoryItem( oslDirectoryItem Item
)
648 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
651 return osl_File_E_INVAL
;
653 if ( ! --pItemImpl
->nRefCount
)
655 if (pItemImpl
->ustrFilePath
)
656 rtl_uString_release( pItemImpl
->ustrFilePath
);
657 if (pItemImpl
->ustrDrive
)
658 rtl_uString_release( pItemImpl
->ustrDrive
);
659 rtl_freeMemory( pItemImpl
);
661 return osl_File_E_None
;
664 /****************************************************************************
665 * osl_createFileHandleFromFD
666 ***************************************************************************/
668 oslFileHandle
osl_createFileHandleFromFD( int fd
)
670 oslFileHandleImpl
* pHandleImpl
= NULL
;
674 pHandleImpl
= (oslFileHandleImpl
*) rtl_allocateMemory( sizeof(oslFileHandleImpl
) );
678 pHandleImpl
->ustrFilePath
= NULL
;
679 rtl_uString_new( &pHandleImpl
->ustrFilePath
);
680 pHandleImpl
->fd
= fd
;
682 /* FIXME: should detect whether the file has been locked */
683 pHandleImpl
->bLocked
= sal_True
;
687 return (oslFileHandle
)pHandleImpl
;
690 /****************************************************************************
692 ***************************************************************************/
694 oslFileError
osl_openFile( rtl_uString
* ustrFileURL
, oslFileHandle
* pHandle
, sal_uInt32 uFlags
)
696 oslFileHandleImpl
* pHandleImpl
= NULL
;
698 rtl_uString
* ustrFilePath
= NULL
;
700 char buffer
[PATH_MAX
];
702 int mode
= S_IRUSR
| S_IRGRP
| S_IROTH
;
703 int flags
= O_RDONLY
;
707 /* locking the complete file */
709 aflock
.l_whence
= SEEK_SET
;
713 OSL_ASSERT( ustrFileURL
);
714 OSL_ASSERT( pHandle
);
716 if( ( 0 == ustrFileURL
->length
) )
717 return osl_File_E_INVAL
;
719 /* convert file URL to system path */
720 eRet
= osl_getSystemPathFromFileURL( ustrFileURL
, &ustrFilePath
);
722 if( osl_File_E_None
!= eRet
)
725 osl_systemPathRemoveSeparator(ustrFilePath
);
727 /* convert unicode path to text */
728 if( UnicodeToText( buffer
, PATH_MAX
, ustrFilePath
->buffer
, ustrFilePath
->length
) )
730 /* we do not open devices or such here */
731 if( !( uFlags
& osl_File_OpenFlag_Create
) )
733 struct stat aFileStat
;
735 if( 0 > stat( buffer
, &aFileStat
) )
737 PERROR( "osl_openFile", buffer
);
738 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
741 else if( !S_ISREG( aFileStat
.st_mode
) )
743 eRet
= osl_File_E_INVAL
;
747 if( osl_File_E_None
== eRet
)
753 if ( uFlags
& osl_File_OpenFlag_Write
)
755 mode
|= S_IWUSR
| S_IWGRP
| S_IWOTH
;
757 aflock
.l_type
= F_WRLCK
;
760 if ( uFlags
& osl_File_OpenFlag_Create
)
762 mode
|= S_IWUSR
| S_IWGRP
| S_IWOTH
;
763 flags
= O_CREAT
| O_EXCL
| O_RDWR
;
767 fd
= open( buffer
, flags
| O_BINARY
, mode
);
770 sal_Bool bNeedsLock
= ( ( uFlags
& osl_File_OpenFlag_NoLock
) == 0 );
771 sal_Bool bLocked
= sal_False
;
774 /* check if file lock is enabled and clear l_type member of flock otherwise */
775 if( (char *) -1 == pFileLockEnvVar
)
777 /* FIXME: this is not MT safe */
778 pFileLockEnvVar
= getenv("SAL_ENABLE_FILE_LOCKING");
780 if( NULL
== pFileLockEnvVar
)
781 pFileLockEnvVar
= getenv("STAR_ENABLE_FILE_LOCKING");
784 if( NULL
== pFileLockEnvVar
)
787 /* lock the file if flock.l_type is set */
788 bLocked
= ( F_WRLCK
!= aflock
.l_type
|| -1 != fcntl( fd
, F_SETLK
, &aflock
) );
791 if ( !bNeedsLock
|| bLocked
)
793 /* allocate memory for impl structure */
794 pHandleImpl
= (oslFileHandleImpl
*) rtl_allocateMemory( sizeof(oslFileHandleImpl
) );
797 pHandleImpl
->ustrFilePath
= ustrFilePath
;
798 pHandleImpl
->fd
= fd
;
799 pHandleImpl
->bLocked
= bLocked
;
801 *pHandle
= (oslFileHandle
) pHandleImpl
;
803 return osl_File_E_None
;
814 PERROR( "osl_openFile", buffer
);
815 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
819 eRet
= osl_File_E_INVAL
;
821 rtl_uString_release( ustrFilePath
);
825 /****************************************************************************/
827 /****************************************************************************/
829 oslFileError
osl_closeFile( oslFileHandle Handle
)
831 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*) Handle
;
832 oslFileError eRet
= osl_File_E_INVAL
;
834 OSL_ASSERT( Handle
);
838 rtl_uString_release( pHandleImpl
->ustrFilePath
);
840 /* release file lock if locking is enabled */
841 if( pFileLockEnvVar
)
845 aflock
.l_type
= F_UNLCK
;
846 aflock
.l_whence
= SEEK_SET
;
850 if ( pHandleImpl
->bLocked
)
852 /* FIXME: check if file is really locked ? */
854 /* release the file share lock on this file */
855 if( -1 == fcntl( pHandleImpl
->fd
, F_SETLK
, &aflock
) )
856 PERROR( "osl_closeFile", "unlock failed" );
860 if( 0 > close( pHandleImpl
->fd
) )
862 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
865 eRet
= osl_File_E_None
;
867 rtl_freeMemory( pHandleImpl
);
873 /****************************************************************************/
874 /* osl_isEndOfFile */
875 /****************************************************************************/
877 oslFileError SAL_CALL
osl_isEndOfFile( oslFileHandle Handle
, sal_Bool
*pIsEOF
)
879 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*) Handle
;
880 oslFileError eRet
= osl_File_E_INVAL
;
884 long curPos
= lseek( pHandleImpl
->fd
, 0, SEEK_CUR
);
888 long endPos
= lseek( pHandleImpl
->fd
, 0, SEEK_END
);
892 *pIsEOF
= ( curPos
== endPos
);
893 curPos
= lseek( pHandleImpl
->fd
, curPos
, SEEK_SET
);
896 eRet
= osl_File_E_None
;
898 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
901 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
904 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
911 /****************************************************************************/
913 /****************************************************************************/
915 oslFileError
osl_moveFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
917 char srcPath
[PATH_MAX
];
918 char destPath
[PATH_MAX
];
922 OSL_ASSERT( ustrFileURL
);
923 OSL_ASSERT( ustrDestURL
);
925 /* convert source url to system path */
926 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
927 if( eRet
!= osl_File_E_None
)
930 /* convert destination url to system path */
931 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
932 if( eRet
!= osl_File_E_None
)
935 //YD 01/05/06 rename() can overwrite existing files.
936 rc
= DosDelete( (PCSZ
)destPath
);
937 rc
= DosMove( (PCSZ
)srcPath
, (PCSZ
)destPath
);
939 eRet
= osl_File_E_None
;
941 eRet
= MapError( rc
);
946 /****************************************************************************/
948 /****************************************************************************/
950 #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
952 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
)
955 sal_Char pszTmpDestFile
[PATH_MAX
];
956 size_t size_tmp_dest_buff
= sizeof(pszTmpDestFile
);
958 /* Quick fix for #106048, the whole copy file function seems
959 to be erroneous anyway and needs to be rewritten.
960 Besides osl_copyFile is currently not used from OO/SO code.
962 memset(pszTmpDestFile
, 0, size_tmp_dest_buff
);
964 if ( DestFileExists
)
966 strncpy(pszTmpDestFile
, pszDestFileName
, size_tmp_dest_buff
- 1);
968 if ((strlen(pszTmpDestFile
) + strlen(TMP_DEST_FILE_EXTENSION
)) >= size_tmp_dest_buff
)
969 return osl_File_E_NAMETOOLONG
;
971 strncat(pszTmpDestFile
, TMP_DEST_FILE_EXTENSION
, strlen(TMP_DEST_FILE_EXTENSION
));
973 /* FIXME: what if pszTmpDestFile already exists? */
974 /* with getcanonical??? */
975 nRet
=rename(pszDestFileName
,pszTmpDestFile
);
978 /* mfe: should be S_ISREG */
979 if ( !S_ISLNK(nMode
) )
981 /* copy SourceFile to DestFile */
982 nRet
= oslDoCopyFile(pszSourceFileName
,pszDestFileName
,nSourceSize
, nMode
);
984 /* mfe: OK redundant at the moment */
985 else if ( S_ISLNK(nMode
) )
987 nRet
= oslDoCopyLink(pszSourceFileName
,pszDestFileName
);
991 /* mfe: what to do here? */
995 if ( nRet
> 0 && DestFileExists
== 1 )
997 unlink(pszDestFileName
);
998 rename(pszTmpDestFile
,pszDestFileName
);
1003 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1006 if ( DestFileExists
== 1 )
1008 unlink(pszTmpDestFile
);
1011 return osl_File_E_None
;
1014 /*****************************************
1015 * oslChangeFileModes
1016 ****************************************/
1018 static oslFileError
oslChangeFileModes( const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
)
1021 struct utimbuf aTimeBuffer
;
1023 nRet
= chmod(pszFileName
,nMode
);
1027 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1030 aTimeBuffer
.actime
=nAcTime
;
1031 aTimeBuffer
.modtime
=nModTime
;
1032 nRet
=utime(pszFileName
,&aTimeBuffer
);
1036 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1039 if ( nUID
!= getuid() )
1044 nRet
=chown(pszFileName
,nUID
,nGID
);
1049 /* mfe: do not return an error here! */
1050 /* return oslTranslateFileError(nRet);*/
1053 return osl_File_E_None
;
1056 /*****************************************
1058 ****************************************/
1060 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
)
1064 /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
1065 /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
1066 sal_Char pszLinkContent
[PATH_MAX
];
1068 pszLinkContent
[0] = '\0';
1070 nRet
= readlink(pszSourceFileName
,pszLinkContent
,PATH_MAX
);
1078 pszLinkContent
[ nRet
] = 0;
1080 nRet
= symlink(pszLinkContent
,pszDestFileName
);
1091 /*****************************************
1093 ****************************************/
1095 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
)
1100 void* pSourceFile
=0;
1103 SourceFileFD
=open(pszSourceFileName
,O_RDONLY
| O_BINARY
);
1104 if ( SourceFileFD
< 0 )
1110 DestFileFD
=open(pszDestFileName
, O_WRONLY
| O_CREAT
| O_BINARY
, mode
);
1111 if ( DestFileFD
< 0 )
1114 close(SourceFileFD
);
1118 /* HACK: because memory mapping fails on various
1119 platforms if the size of the source file is 0 byte */
1120 if (0 == nSourceSize
)
1122 close(SourceFileFD
);
1127 while( (nRet
= read(SourceFileFD
, buffer
, sizeof(buffer
))) !=0 )
1129 nRet
= write( DestFileFD
, buffer
, nRet
);
1132 close(SourceFileFD
);
1138 static oslFileError
osl_psz_copyFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
1146 struct stat aFileStat
;
1147 oslFileError tErr
=osl_File_E_invalidError
;
1148 size_t nSourceSize
=0;
1149 int DestFileExists
=1;
1151 /* mfe: does the source file really exists? */
1152 nRet
= lstat(pszPath
,&aFileStat
);
1157 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1160 /* mfe: we do only copy files here! */
1161 if ( S_ISDIR(aFileStat
.st_mode
) )
1163 return osl_File_E_ISDIR
;
1166 nSourceSize
=(size_t)aFileStat
.st_size
;
1167 nMode
=aFileStat
.st_mode
;
1168 nAcTime
=aFileStat
.st_atime
;
1169 nModTime
=aFileStat
.st_mtime
;
1170 nUID
=aFileStat
.st_uid
;
1171 nGID
=aFileStat
.st_gid
;
1173 nRet
= stat(pszDestPath
,&aFileStat
);
1178 if ( nRet
== ENOENT
)
1182 /* return oslTranslateFileError(nRet);*/
1185 /* mfe: the destination file must not be a directory! */
1186 if ( nRet
== 0 && S_ISDIR(aFileStat
.st_mode
) )
1188 return osl_File_E_ISDIR
;
1192 /* mfe: file does not exists or is no dir */
1195 tErr
= oslDoCopy(pszPath
,pszDestPath
,nMode
,nSourceSize
,DestFileExists
);
1197 if ( tErr
!= osl_File_E_None
)
1203 * mfe: ignore return code
1204 * since only the success of the copy is
1207 oslChangeFileModes(pszDestPath
,nMode
,nAcTime
,nModTime
,nUID
,nGID
);
1212 oslFileError
osl_copyFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
1214 char srcPath
[PATH_MAX
];
1215 char destPath
[PATH_MAX
];
1219 OSL_ASSERT( ustrFileURL
);
1220 OSL_ASSERT( ustrDestURL
);
1222 /* convert source url to system path */
1223 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
1224 if( eRet
!= osl_File_E_None
)
1227 /* convert destination url to system path */
1228 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
1229 if( eRet
!= osl_File_E_None
)
1232 return osl_psz_copyFile( srcPath
, destPath
);
1235 /****************************************************************************/
1236 /* osl_removeFile */
1237 /****************************************************************************/
1239 oslFileError
osl_removeFile( rtl_uString
* ustrFileURL
)
1241 char path
[PATH_MAX
];
1245 OSL_ASSERT( ustrFileURL
);
1247 /* convert file url to system path */
1248 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
1249 if( eRet
!= osl_File_E_None
)
1252 rc
= DosDelete( (PCSZ
)path
);
1254 eRet
= osl_File_E_None
;
1256 eRet
= MapError( rc
);
1261 /****************************************************************************/
1262 /* osl_getVolumeInformation */
1263 /****************************************************************************/
1265 #define TXFSDC_BLOCKR 0x00 // block device removable
1266 #define TXFSDC_GETBPB 0x00 // get device bpb info
1267 #define TXFSBPB_REMOVABLE 0x08 // BPB attribute for removable
1269 typedef struct drivecmd
1271 BYTE cmd
; // 0=unlock 1=lock 2=eject
1272 BYTE drv
; // 0=A, 1=B 2=C ...
1273 } DRIVECMD
; // end of struct "drivecmd"
1275 #pragma pack(push, 1) // byte packing
1276 typedef struct txfs_ebpb
// ext. boot parameter block
1277 { // at offset 0x0b in bootsector
1278 USHORT SectSize
; // 0B bytes per sector
1279 BYTE ClustSize
; // 0D sectors per cluster
1280 USHORT FatOffset
; // 0E sectors to 1st FAT
1281 BYTE NrOfFats
; // 10 nr of FATS (FAT only)
1282 USHORT RootEntries
; // 11 Max entries \ (FAT only)
1283 USHORT Sectors
; // 13 nr of sectors if < 64K
1284 BYTE MediaType
; // 15 mediatype (F8 for HD)
1285 USHORT FatSectors
; // 16 sectors/FAT (FAT only)
1286 USHORT LogGeoSect
; // 18 sectors/Track
1287 USHORT LogGeoHead
; // 1a nr of heads
1288 ULONG HiddenSectors
; // 1c sector-offset from MBR/EBR
1289 ULONG BigSectors
; // 20 nr of sectors if >= 64K
1290 } TXFS_EBPB
; // last byte is at offset 0x23
1292 typedef struct drivebpb
1294 TXFS_EBPB ebpb
; // extended BPB
1298 USHORT attributes
; // device attributes
1299 BYTE fill
[6]; // documented for IOCtl
1300 } DRIVEBPB
; // end of struct "drivebpb"
1309 /*****************************************************************************/
1310 // Get number of cdrom readers
1311 /*****************************************************************************/
1312 BOOL
GetCDInfo( CDInfo
* pCDInfo
)
1317 if( NO_ERROR
== DosOpen( (PCSZ
)"\\DEV\\CD-ROM2$",
1318 &hFileCD
, &ulAction
, 0, FILE_NORMAL
,
1319 OPEN_ACTION_OPEN_IF_EXISTS
,
1320 OPEN_SHARE_DENYNONE
| OPEN_ACCESS_READONLY
, NULL
)) {
1321 ULONG ulDataSize
= sizeof(CDInfo
);
1322 APIRET rc
= DosDevIOCtl( hFileCD
, 0x82, 0x60, NULL
, 0,
1323 NULL
, (PVOID
)pCDInfo
, ulDataSize
, &ulDataSize
);
1329 pCDInfo
->usFirst
= 0;
1330 pCDInfo
->usCount
= 0;
1334 /*****************************************************************************/
1335 // Determine if unit is a cdrom or not
1336 /*****************************************************************************/
1337 BOOL
DriveIsCDROM(UINT uiDrive
, CDInfo
*pCDInfo
)
1339 return (uiDrive
>= pCDInfo
->usFirst
)
1340 && (uiDrive
< (pCDInfo
->usFirst
+ pCDInfo
->usCount
));
1343 /*****************************************************************************/
1344 // Determine attached fstype, e.g. HPFS for specified drive
1345 /*****************************************************************************/
1346 BOOL TxFsType
// RET FS type resolved
1348 char *drive
, // IN Drive specification
1349 char *fstype
, // OUT Attached FS type
1350 char *details
// OUT details (UNC) or NULL
1354 FSQBUFFER2
*fsinfo
; // Attached FS info
1355 ULONG fsdlen
= 2048; // Fs info data length
1357 strcpy(fstype
, "none");
1360 strcpy(details
, "");
1362 if ((fsinfo
= (FSQBUFFER2
*)calloc(1, fsdlen
)) != NULL
)
1364 if (DosQFSAttach((PCSZ
)drive
, 0, 1, fsinfo
, &fsdlen
) == NO_ERROR
)
1366 strcpy(fstype
, (char*) fsinfo
->szName
+ fsinfo
->cbName
+1);
1367 if (details
&& (fsinfo
->cbFSAData
!= 0))
1369 strcpy( details
, (char*) fsinfo
->szName
+ fsinfo
->cbName
+
1370 fsinfo
->cbFSDName
+2);
1378 /*---------------------------------------------------------------------------*/
1381 /*****************************************************************************/
1382 // Determine if a driveletter represents a removable medium/device
1383 /*****************************************************************************/
1384 BOOL TxFsIsRemovable
// RET drive is removable
1386 char *drive
// IN Driveletter to test
1396 DosError( FERR_DISABLEHARDERR
); // avoid 'not ready' popups
1398 ParmLen
= sizeof(IOCtl
);
1399 IOCtl
.cmd
= TXFSDC_BLOCKR
;
1400 IOCtl
.drv
= toupper(drive
[0]) - 'A';
1401 DataLen
= sizeof(NoRem
);
1403 if (DosDevIOCtl((HFILE
) -1, IOCTL_DISK
,
1405 &IOCtl
, ParmLen
, &ParmLen
,
1406 &NoRem
, DataLen
, &DataLen
) == NO_ERROR
)
1408 if (NoRem
) // non-removable sofar, check
1409 { // BPB as well (USB devices)
1410 ParmLen
= sizeof(IOCtl
);
1411 IOCtl
.cmd
= TXFSDC_GETBPB
;
1412 IOCtl
.drv
= toupper(drive
[0]) - 'A';
1413 DataLen
= sizeof(RemAt
);
1415 if (DosDevIOCtl((HFILE
) -1, IOCTL_DISK
,
1416 DSK_GETDEVICEPARAMS
,
1417 &IOCtl
, ParmLen
, &ParmLen
,
1418 &RemAt
, DataLen
, &DataLen
) == NO_ERROR
)
1421 if (RemAt
.attributes
& TXFSBPB_REMOVABLE
)
1423 rc
= TRUE
; // removable, probably USB
1429 rc
= TRUE
; // removable block device
1432 DosError( FERR_ENABLEHARDERR
); // enable criterror handler
1434 } // end 'TxFsIsRemovable'
1435 /*---------------------------------------------------------------------------*/
1437 static oslFileError
get_drive_type(const char* path
, oslVolumeInfo
* pInfo
)
1439 char Drive_Letter
= toupper( *path
);
1442 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1444 // check for floppy A/B
1447 rc
= DosDevConfig( (void*) &nFloppies
, DEVINFO_FLOPPY
);
1448 if ((Drive_Letter
- 'A') < nFloppies
) {
1449 pInfo
->uAttributes
|= osl_Volume_Attribute_Removeable
;
1450 pInfo
->uAttributes
|= osl_Volume_Attribute_FloppyDisk
;
1451 return osl_File_E_None
;
1454 // query system for CD drives
1458 // query if drive is a CDROM
1459 if (DriveIsCDROM( Drive_Letter
- 'A', &cdInfo
))
1460 pInfo
->uAttributes
|= osl_Volume_Attribute_CompactDisc
| osl_Volume_Attribute_Removeable
;
1462 if (TxFsIsRemovable( (char*)path
))
1463 pInfo
->uAttributes
|= osl_Volume_Attribute_Removeable
;
1465 if (TxFsType( (char*)path
, fstype
, NULL
) == FALSE
) {
1466 // query failed, assume fixed disk
1467 pInfo
->uAttributes
|= osl_Volume_Attribute_FixedDisk
;
1468 return osl_File_E_None
;
1471 //- Note, connected Win-NT drives use the REAL FS-name like NTFS!
1472 if ((strncasecmp( fstype
, "LAN", 3) == 0) //- OS/2 LAN drives
1473 || (strncasecmp( fstype
, "NDFS", 4) == 0) //- NetDrive
1474 || (strncasecmp( fstype
, "REMOTE", 5) == 0) ) //- NT disconnected
1475 pInfo
->uAttributes
|= osl_Volume_Attribute_Remote
;
1476 else if (strncasecmp( fstype
, "RAMFS", 5) == 0)
1477 pInfo
->uAttributes
|= osl_Volume_Attribute_RAMDisk
;
1478 else if ((strncasecmp( fstype
, "CD", 2) == 0) // OS2:CDFS, DOS/WIN:CDROM
1479 || (strncasecmp( fstype
, "UDF", 3) == 0) ) // OS2:UDF DVD's
1480 pInfo
->uAttributes
|= osl_Volume_Attribute_CompactDisc
| osl_Volume_Attribute_Removeable
;
1482 pInfo
->uAttributes
|= osl_Volume_Attribute_FixedDisk
;
1484 return osl_File_E_None
;
1487 //#############################################
1488 inline bool is_volume_space_info_request(sal_uInt32 field_mask
)
1490 return (field_mask
&
1491 (osl_VolumeInfo_Mask_TotalSpace
|
1492 osl_VolumeInfo_Mask_UsedSpace
|
1493 osl_VolumeInfo_Mask_FreeSpace
));
1496 //#############################################
1497 static void get_volume_space_information(const char* path
, oslVolumeInfo
*pInfo
)
1499 FSALLOCATE aFSInfoBuf
;
1500 ULONG nDriveNumber
= toupper( *path
) - 'A' + 1;
1502 // disable error popups
1503 DosError(FERR_DISABLEHARDERR
);
1504 APIRET rc
= DosQueryFSInfo( nDriveNumber
, FSIL_ALLOC
,
1505 &aFSInfoBuf
, sizeof(aFSInfoBuf
) );
1506 // enable error popups
1507 DosError(FERR_ENABLEHARDERR
);
1510 uint64_t aBytesPerCluster( uint64_t(aFSInfoBuf
.cbSector
) *
1511 uint64_t(aFSInfoBuf
.cSectorUnit
) );
1512 pInfo
->uFreeSpace
= aBytesPerCluster
* uint64_t(aFSInfoBuf
.cUnitAvail
);
1513 pInfo
->uTotalSpace
= aBytesPerCluster
* uint64_t(aFSInfoBuf
.cUnit
);
1514 pInfo
->uUsedSpace
= pInfo
->uTotalSpace
- pInfo
->uFreeSpace
;
1515 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_TotalSpace
|
1516 osl_VolumeInfo_Mask_UsedSpace
|
1517 osl_VolumeInfo_Mask_FreeSpace
;
1521 //#############################################
1522 inline bool is_filesystem_attributes_request(sal_uInt32 field_mask
)
1524 return (field_mask
&
1525 (osl_VolumeInfo_Mask_MaxNameLength
|
1526 osl_VolumeInfo_Mask_MaxPathLength
|
1527 osl_VolumeInfo_Mask_FileSystemName
|
1528 osl_VolumeInfo_Mask_FileSystemCaseHandling
));
1531 //#############################################
1532 inline bool is_drivetype_request(sal_uInt32 field_mask
)
1534 return (field_mask
& osl_VolumeInfo_Mask_Attributes
);
1537 typedef struct _FSQBUFFER_
1543 //#############################################
1544 static oslFileError
get_filesystem_attributes(const char* path
, sal_uInt32 field_mask
, oslVolumeInfo
* pInfo
)
1546 pInfo
->uAttributes
= 0;
1548 oslFileError osl_error
= osl_File_E_None
;
1550 // osl_get_drive_type must be called first because
1551 // this function resets osl_VolumeInfo_Mask_Attributes
1553 if (is_drivetype_request(field_mask
))
1554 osl_error
= get_drive_type(path
, pInfo
);
1556 if ((osl_File_E_None
== osl_error
) && is_filesystem_attributes_request(field_mask
))
1562 nBufLen
= sizeof( aBuf
);
1563 // disable error popups
1564 DosError(FERR_DISABLEHARDERR
);
1565 nRet
= DosQueryFSAttach( (PCSZ
)path
, 0, FSAIL_QUERYNAME
, (_FSQBUFFER2
*) &aBuf
, &nBufLen
);
1568 char *pType
= (char*)(aBuf
.aBuf
.szName
+ aBuf
.aBuf
.cbName
+ 1);
1569 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxNameLength
;
1570 pInfo
->uMaxNameLength
= _MAX_FNAME
;
1572 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxPathLength
;
1573 pInfo
->uMaxPathLength
= _MAX_PATH
;
1575 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FileSystemName
;
1576 rtl_uString_newFromAscii(&pInfo
->ustrFileSystemName
, pType
);
1578 // case is preserved always except for FAT
1579 if (strcmp( pType
, "FAT" ))
1580 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Is_Preserved
;
1582 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1584 // enable error popups
1585 DosError(FERR_ENABLEHARDERR
);
1590 oslFileError SAL_CALL
osl_getVolumeInformation( rtl_uString
* ustrDirectoryURL
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
1592 char volume_root
[PATH_MAX
];
1595 OSL_ASSERT( ustrDirectoryURL
);
1596 OSL_ASSERT( pInfo
);
1598 /* convert directory url to system path */
1599 error
= FileURLToPath( volume_root
, PATH_MAX
, ustrDirectoryURL
);
1600 if( error
!= osl_File_E_None
)
1604 return osl_File_E_INVAL
;
1606 pInfo
->uValidFields
= 0;
1608 if ((error
= get_filesystem_attributes(volume_root
, uFieldMask
, pInfo
)) != osl_File_E_None
)
1611 if (is_volume_space_info_request(uFieldMask
))
1612 get_volume_space_information(volume_root
, pInfo
);
1614 if (uFieldMask
& osl_VolumeInfo_Mask_DeviceHandle
)
1616 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_DeviceHandle
;
1617 rtl_uString
* uVolumeRoot
;
1618 rtl_uString_newFromAscii( &uVolumeRoot
, volume_root
);
1619 osl_getFileURLFromSystemPath( uVolumeRoot
, (rtl_uString
**)&pInfo
->pDeviceHandle
);
1620 rtl_uString_release( uVolumeRoot
);
1623 return osl_File_E_None
;
1626 /****************************************************************************/
1627 /* osl_getFileStatus */
1628 /****************************************************************************/
1629 static oslFileError
_osl_getDriveInfo(
1630 oslDirectoryItem Item
, oslFileStatus
*pStatus
, sal_uInt32 uFieldMask
)
1632 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
1633 sal_Unicode cDrive
[3];
1634 sal_Unicode cRoot
[4];
1637 return osl_File_E_INVAL
;
1639 pStatus
->uValidFields
= 0;
1641 cDrive
[0] = pItemImpl
->ustrDrive
->buffer
[0];
1642 cDrive
[1] = (sal_Unicode
)':';
1644 cRoot
[0] = pItemImpl
->ustrDrive
->buffer
[0];
1645 cRoot
[1] = (sal_Unicode
)':';
1648 if ( uFieldMask
& osl_FileStatus_Mask_FileName
)
1650 if ( pItemImpl
->ustrDrive
->buffer
[0] == '\\' &&
1651 pItemImpl
->ustrDrive
->buffer
[1] == '\\' )
1653 LPCWSTR lpFirstBkSlash
= wcschr( (const wchar_t*)&pItemImpl
->ustrDrive
->buffer
[2], '\\' );
1655 if ( lpFirstBkSlash
&& lpFirstBkSlash
[1] )
1657 LPCWSTR lpLastBkSlash
= wcschr( (const wchar_t*)&lpFirstBkSlash
[1], '\\' );
1659 if ( lpLastBkSlash
)
1660 rtl_uString_newFromStr_WithLength( &pStatus
->ustrFileName
, (sal_Unicode
*)&lpFirstBkSlash
[1], lpLastBkSlash
- lpFirstBkSlash
- 1 );
1662 rtl_uString_newFromStr( &pStatus
->ustrFileName
, (sal_Unicode
*)&lpFirstBkSlash
[1] );
1663 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1669 ULONG ulFSInfoLevel
= FSIL_VOLSER
;
1671 char szFileName
[ _MAX_PATH
];
1673 nDriveNumber
= toupper(*cDrive
) - 'A' + 1;
1674 memset( &aFSInfoBuf
, 0, sizeof(FSINFO
) );
1675 // disable error popups
1676 DosError(FERR_DISABLEHARDERR
);
1677 APIRET rc
= DosQueryFSInfo( nDriveNumber
, ulFSInfoLevel
, &aFSInfoBuf
, sizeof(FSINFO
) );
1678 // enable error popups
1679 DosError(FERR_ENABLEHARDERR
);
1680 memset( szFileName
, 0, sizeof( szFileName
));
1681 *szFileName
= toupper(*cDrive
);
1682 strcat( szFileName
, ": [");
1683 if ( !rc
|| aFSInfoBuf
.vol
.cch
)
1684 strncat( szFileName
, aFSInfoBuf
.vol
.szVolLabel
, aFSInfoBuf
.vol
.cch
);
1685 strcat( szFileName
, "]");
1686 rtl_uString_newFromAscii( &pStatus
->ustrFileName
, szFileName
);
1688 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1692 pStatus
->eType
= osl_File_Type_Volume
;
1693 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
1695 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
1697 rtl_uString
*ustrSystemPath
= NULL
;
1699 rtl_uString_newFromStr( &ustrSystemPath
, pItemImpl
->ustrDrive
->buffer
);
1700 osl_getFileURLFromSystemPath( ustrSystemPath
, &pStatus
->ustrFileURL
);
1701 rtl_uString_release( ustrSystemPath
);
1702 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileURL
;
1705 return osl_File_E_None
;
1708 oslFileError SAL_CALL
osl_getFileStatus(
1709 oslDirectoryItem Item
,
1710 oslFileStatus
*pStatus
,
1711 sal_uInt32 uFieldMask
)
1713 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
1714 struct stat file_stat
;
1717 return osl_File_E_INVAL
;
1719 if ( pItemImpl
->uType
== DIRECTORYITEM_DRIVE
)
1720 return _osl_getDriveInfo( Item
, pStatus
, uFieldMask
);
1722 osl::lstat(pItemImpl
->ustrFilePath
, file_stat
);
1723 if ( uFieldMask
& osl_FileStatus_Mask_Validate
)
1725 uFieldMask
&= ~ osl_FileStatus_Mask_Validate
;
1728 /* If no fields to retrieve left ignore pStatus */
1730 return osl_File_E_None
;
1732 /* Otherwise, this must be a valid pointer */
1734 return osl_File_E_INVAL
;
1736 if ( pStatus
->uStructSize
!= sizeof(oslFileStatus
) )
1737 return osl_File_E_INVAL
;
1739 pStatus
->uValidFields
= 0;
1741 /* File time stamps */
1743 if ( (uFieldMask
& osl_FileStatus_Mask_ModifyTime
))
1745 pStatus
->aModifyTime
.Seconds
= file_stat
.st_mtime
;
1746 pStatus
->aModifyTime
.Nanosec
= 0;
1747 pStatus
->uValidFields
|= osl_FileStatus_Mask_ModifyTime
;
1750 if ( (uFieldMask
& osl_FileStatus_Mask_AccessTime
))
1752 pStatus
->aAccessTime
.Seconds
= file_stat
.st_atime
;
1753 pStatus
->aAccessTime
.Nanosec
= 0;
1754 pStatus
->uValidFields
|= osl_FileStatus_Mask_AccessTime
;
1757 if ( (uFieldMask
& osl_FileStatus_Mask_CreationTime
))
1759 pStatus
->aAccessTime
.Seconds
= file_stat
.st_birthtime
;
1760 pStatus
->aAccessTime
.Nanosec
= 0;
1761 pStatus
->uValidFields
|= osl_FileStatus_Mask_CreationTime
;
1764 /* Most of the fields are already set, regardless of requiered fields */
1766 osl_systemPathGetFileNameOrLastDirectoryPart(pItemImpl
->ustrFilePath
, &pStatus
->ustrFileName
);
1767 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1769 if (S_ISLNK(file_stat
.st_mode
))
1770 pStatus
->eType
= osl_File_Type_Link
;
1771 else if (S_ISDIR(file_stat
.st_mode
))
1772 pStatus
->eType
= osl_File_Type_Directory
;
1773 else if (S_ISREG(file_stat
.st_mode
))
1774 pStatus
->eType
= osl_File_Type_Regular
;
1775 else if (S_ISFIFO(file_stat
.st_mode
))
1776 pStatus
->eType
= osl_File_Type_Fifo
;
1777 else if (S_ISSOCK(file_stat
.st_mode
))
1778 pStatus
->eType
= osl_File_Type_Socket
;
1779 else if (S_ISCHR(file_stat
.st_mode
) || S_ISBLK(file_stat
.st_mode
))
1780 pStatus
->eType
= osl_File_Type_Special
;
1782 pStatus
->eType
= osl_File_Type_Unknown
;
1784 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
1786 pStatus
->uAttributes
= pItemImpl
->d_attr
;
1787 pStatus
->uValidFields
|= osl_FileStatus_Mask_Attributes
;
1789 pStatus
->uFileSize
= file_stat
.st_size
;
1790 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileSize
;
1792 if ( uFieldMask
& osl_FileStatus_Mask_LinkTargetURL
)
1794 rtl_uString
*ustrFullPath
= NULL
;
1796 rtl_uString_newFromStr( &ustrFullPath
, rtl_uString_getStr(pItemImpl
->ustrFilePath
) );
1797 osl_getFileURLFromSystemPath( ustrFullPath
, &pStatus
->ustrLinkTargetURL
);
1798 rtl_uString_release( ustrFullPath
);
1800 pStatus
->uValidFields
|= osl_FileStatus_Mask_LinkTargetURL
;
1803 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
1805 rtl_uString
*ustrFullPath
= NULL
;
1807 rtl_uString_newFromStr( &ustrFullPath
, rtl_uString_getStr(pItemImpl
->ustrFilePath
) );
1808 osl_getFileURLFromSystemPath( ustrFullPath
, &pStatus
->ustrFileURL
);
1809 rtl_uString_release( ustrFullPath
);
1810 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileURL
;
1813 return osl_File_E_None
;
1816 /****************************************************************************/
1817 /* osl_createDirectory */
1818 /****************************************************************************/
1820 oslFileError
osl_createDirectory( rtl_uString
* ustrDirectoryURL
)
1822 char path
[PATH_MAX
];
1826 OSL_ASSERT( ustrDirectoryURL
);
1828 /* convert directory url to system path */
1829 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
1830 if( eRet
!= osl_File_E_None
)
1833 rc
= DosCreateDir( (PCSZ
)path
, NULL
);
1834 if (rc
== ERROR_ACCESS_DENIED
)
1835 rc
=ERROR_FILE_EXISTS
;
1838 eRet
= osl_File_E_None
;
1840 eRet
= MapError( rc
);
1845 /****************************************************************************/
1846 /* osl_removeDirectory */
1847 /****************************************************************************/
1849 oslFileError
osl_removeDirectory( rtl_uString
* ustrDirectoryURL
)
1851 char path
[PATH_MAX
];
1855 OSL_ASSERT( ustrDirectoryURL
);
1857 /* convert directory url to system path */
1858 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
1859 if( eRet
!= osl_File_E_None
)
1862 rc
= DosDeleteDir( (PCSZ
)path
);
1864 eRet
= osl_File_E_None
;
1866 eRet
= MapError( rc
);
1871 //#############################################
1872 int path_make_parent(sal_Unicode
* path
)
1874 int i
= rtl_ustr_lastIndexOfChar(path
, '/');
1885 //#############################################
1886 int create_dir_with_callback(
1887 sal_Unicode
* directory_path
,
1888 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1891 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
1893 if (osl::mkdir(directory_path
, mode
) == 0)
1895 if (aDirectoryCreationCallbackFunc
)
1898 osl::FileBase::getFileURLFromSystemPath(directory_path
, url
);
1899 aDirectoryCreationCallbackFunc(pData
, url
.pData
);
1906 //#############################################
1907 oslFileError
create_dir_recursively_(
1908 sal_Unicode
* dir_path
,
1909 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1912 OSL_PRECOND((rtl_ustr_getLength(dir_path
) > 0) && ((dir_path
+ (rtl_ustr_getLength(dir_path
) - 1)) != (dir_path
+ rtl_ustr_lastIndexOfChar(dir_path
, '/'))), \
1913 "Path must not end with a slash");
1915 int native_err
= create_dir_with_callback(
1916 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1918 if (native_err
== 0)
1919 return osl_File_E_None
;
1921 if (native_err
!= ENOENT
)
1922 return oslTranslateFileError(OSL_FET_ERROR
, native_err
);
1924 // we step back until '/a_dir' at maximum because
1925 // we should get an error unequal ENOENT when
1926 // we try to create 'a_dir' at '/' and would so
1928 int pos
= path_make_parent(dir_path
);
1930 oslFileError osl_error
= create_dir_recursively_(
1931 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1933 if (osl_File_E_None
!= osl_error
)
1936 dir_path
[pos
] = '/';
1938 return create_dir_recursively_(dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1941 //#######################################
1942 oslFileError SAL_CALL
osl_createDirectoryPath(
1943 rtl_uString
* aDirectoryUrl
,
1944 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1947 if (aDirectoryUrl
== NULL
)
1948 return osl_File_E_INVAL
;
1950 rtl::OUString sys_path
;
1951 oslFileError osl_error
= osl_getSystemPathFromFileURL_Ex(
1952 aDirectoryUrl
, &sys_path
.pData
, sal_False
);
1954 if (osl_error
!= osl_File_E_None
)
1957 osl::systemPathRemoveSeparator(sys_path
);
1959 // const_cast because sys_path is a local copy which we want to modify inplace instead of
1960 // coyp it into another buffer on the heap again
1961 return create_dir_recursively_(sys_path
.pData
->buffer
, aDirectoryCreationCallbackFunc
, pData
);
1964 /****************************************************************************/
1965 /* osl_getCanonicalName */
1966 /****************************************************************************/
1968 oslFileError
osl_getCanonicalName( rtl_uString
* ustrFileURL
, rtl_uString
** pustrValidURL
)
1970 OSL_ENSURE(sal_False
, "osl_getCanonicalName not implemented");
1972 rtl_uString_newFromString(pustrValidURL
, ustrFileURL
);
1973 return osl_File_E_None
;
1977 /****************************************************************************/
1978 /* osl_setFileAttributes */
1979 /****************************************************************************/
1981 oslFileError
osl_setFileAttributes( rtl_uString
* ustrFileURL
, sal_uInt64 uAttributes
)
1983 char path
[PATH_MAX
];
1985 FILESTATUS3 fsts3ConfigInfo
;
1986 ULONG ulBufSize
= sizeof(FILESTATUS3
);
1987 APIRET rc
= NO_ERROR
;
1989 OSL_ASSERT( ustrFileURL
);
1991 /* convert file url to system path */
1992 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
1993 if( eRet
!= osl_File_E_None
)
1996 /* query current attributes */
1997 rc
= DosQueryPathInfo( (PCSZ
)path
, FIL_STANDARD
, &fsts3ConfigInfo
, ulBufSize
);
1999 return MapError( rc
);
2001 /* set/reset readonly/hidden (see w32\file.cxx) */
2002 fsts3ConfigInfo
.attrFile
&= ~(FILE_READONLY
| FILE_HIDDEN
);
2003 if ( uAttributes
& osl_File_Attribute_ReadOnly
)
2004 fsts3ConfigInfo
.attrFile
|= FILE_READONLY
;
2005 if ( uAttributes
& osl_File_Attribute_Hidden
)
2006 fsts3ConfigInfo
.attrFile
|= FILE_HIDDEN
;
2008 /* write new attributes */
2009 rc
= DosSetPathInfo( (PCSZ
)path
, FIL_STANDARD
, &fsts3ConfigInfo
, ulBufSize
, 0);
2011 return MapError( rc
);
2014 return osl_File_E_None
;
2017 /****************************************************************************/
2018 /* osl_setFileTime */
2019 /****************************************************************************/
2021 oslFileError
osl_setFileTime( rtl_uString
* ustrFileURL
, const TimeValue
* pCreationTime
,
2022 const TimeValue
* pLastAccessTime
, const TimeValue
* pLastWriteTime
)
2024 char path
[PATH_MAX
];
2027 OSL_ASSERT( ustrFileURL
);
2029 /* convert file url to system path */
2030 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
2031 if( eRet
!= osl_File_E_None
)
2034 return osl_psz_setFileTime( path
, pCreationTime
, pLastAccessTime
, pLastWriteTime
);
2037 /******************************************************************************
2039 * Exported Module Functions
2040 * (independent of C or Unicode Strings)
2042 *****************************************************************************/
2045 /*******************************************
2047 ********************************************/
2049 oslFileError
osl_readFile(oslFileHandle Handle
, void* pBuffer
, sal_uInt64 uBytesRequested
, sal_uInt64
* pBytesRead
)
2052 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*)Handle
;
2054 if ((0 == pHandleImpl
) || (pHandleImpl
->fd
< 0) || (0 == pBuffer
) || (0 == pBytesRead
))
2055 return osl_File_E_INVAL
;
2057 nBytes
= read(pHandleImpl
->fd
, pBuffer
, uBytesRequested
);
2060 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
2062 *pBytesRead
= nBytes
;
2063 return osl_File_E_None
;
2066 /*******************************************
2068 ********************************************/
2070 oslFileError
osl_writeFile(oslFileHandle Handle
, const void* pBuffer
, sal_uInt64 uBytesToWrite
, sal_uInt64
* pBytesWritten
)
2073 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*)Handle
;
2075 OSL_ASSERT(pHandleImpl
);
2076 OSL_ASSERT(pBuffer
);
2077 OSL_ASSERT(pBytesWritten
);
2079 if ((0 == pHandleImpl
) || (0 == pBuffer
) || (0 == pBytesWritten
))
2080 return osl_File_E_INVAL
;
2082 OSL_ASSERT(pHandleImpl
->fd
>= 0);
2084 if (pHandleImpl
->fd
< 0)
2085 return osl_File_E_INVAL
;
2087 nBytes
= write(pHandleImpl
->fd
, pBuffer
, uBytesToWrite
);
2090 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
2092 *pBytesWritten
= nBytes
;
2093 return osl_File_E_None
;
2096 /*******************************************
2098 ********************************************/
2100 oslFileError
osl_setFilePos( oslFileHandle Handle
, sal_uInt32 uHow
, sal_Int64 uPos
)
2102 oslFileHandleImpl
* pHandleImpl
=0;
2106 pHandleImpl
= (oslFileHandleImpl
*) Handle
;
2107 if ( pHandleImpl
== 0 )
2109 return osl_File_E_INVAL
;
2112 if ( pHandleImpl
->fd
< 0 )
2114 return osl_File_E_INVAL
;
2117 /* FIXME mfe: setFilePos: Do we have any runtime function to determine LONG_MAX? */
2118 if ( uPos
> LONG_MAX
)
2120 return osl_File_E_OVERFLOW
;
2123 nOffset
=(off_t
)uPos
;
2127 case osl_Pos_Absolut
:
2128 nOffset
= lseek(pHandleImpl
->fd
,nOffset
,SEEK_SET
);
2131 case osl_Pos_Current
:
2132 nOffset
= lseek(pHandleImpl
->fd
,nOffset
,SEEK_CUR
);
2136 nOffset
= lseek(pHandleImpl
->fd
,nOffset
,SEEK_END
);
2140 return osl_File_E_INVAL
;
2146 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2149 return osl_File_E_None
;
2152 /************************************************
2154 ***********************************************/
2156 oslFileError
osl_getFilePos( oslFileHandle Handle
, sal_uInt64
* pPos
)
2158 oslFileHandleImpl
* pHandleImpl
=0;
2162 pHandleImpl
= (oslFileHandleImpl
*) Handle
;
2163 if ( pHandleImpl
== 0 || pPos
== 0)
2165 return osl_File_E_INVAL
;
2168 if ( pHandleImpl
->fd
< 0 )
2170 return osl_File_E_INVAL
;
2173 nOffset
= lseek(pHandleImpl
->fd
,0,SEEK_CUR
);
2181 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2186 return osl_File_E_None
;
2189 /****************************************************************************
2191 ****************************************************************************/
2193 oslFileError
osl_getFileSize( oslFileHandle Handle
, sal_uInt64
* pSize
)
2195 oslFileHandleImpl
* pHandleImpl
=(oslFileHandleImpl
*) Handle
;
2196 if (pHandleImpl
== 0)
2197 return osl_File_E_INVAL
;
2199 struct stat file_stat
;
2200 if (fstat(pHandleImpl
->fd
, &file_stat
) == -1)
2201 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
2203 *pSize
= file_stat
.st_size
;
2204 return osl_File_E_None
;
2207 /************************************************
2209 ***********************************************/
2211 oslFileError
osl_setFileSize( oslFileHandle Handle
, sal_uInt64 uSize
)
2213 oslFileHandleImpl
* pHandleImpl
=0;
2216 pHandleImpl
= (oslFileHandleImpl
*) Handle
;
2217 if ( pHandleImpl
== 0 )
2219 return osl_File_E_INVAL
;
2222 if ( pHandleImpl
->fd
< 0 )
2224 return osl_File_E_INVAL
;
2227 /* FIXME: mfe: setFileSize: Do we have any runtime function to determine LONG_MAX? */
2228 if ( uSize
> LONG_MAX
)
2230 return osl_File_E_OVERFLOW
;
2233 nOffset
= (off_t
)uSize
;
2234 if (ftruncate (pHandleImpl
->fd
, nOffset
) < 0)
2236 /* Failure. Try fallback algorithm */
2237 oslFileError result
;
2241 /* Save original result */
2242 result
= oslTranslateFileError (OSL_FET_ERROR
, errno
);
2243 PERROR("ftruncate", "Try osl_setFileSize [fallback]\n");
2245 /* Check against current size. Fail upon 'shrink' */
2246 if (fstat (pHandleImpl
->fd
, &aStat
) < 0)
2248 PERROR("ftruncate: fstat", "Out osl_setFileSize [error]\n");
2251 if ((0 <= nOffset
) && (nOffset
<= aStat
.st_size
))
2253 /* Failure upon 'shrink'. Return original result */
2257 /* Save current position */
2258 nCurPos
= (off_t
)lseek (pHandleImpl
->fd
, (off_t
)0, SEEK_CUR
);
2259 if (nCurPos
== (off_t
)(-1))
2261 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2265 /* Try 'expand' via 'lseek()' and 'write()' */
2266 if (lseek (pHandleImpl
->fd
, (off_t
)(nOffset
- 1), SEEK_SET
) < 0)
2268 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2271 if (write (pHandleImpl
->fd
, (char*)"", (size_t)1) < 0)
2273 /* Failure. Restore saved position */
2274 PERROR("ftruncate: write", "Out osl_setFileSize [error]\n");
2275 if (lseek (pHandleImpl
->fd
, (off_t
)nCurPos
, SEEK_SET
) < 0)
2277 #ifdef DEBUG_OSL_FILE
2278 perror("ftruncate: lseek");
2279 #endif /* DEBUG_OSL_FILE */
2284 /* Success. Restore saved position */
2285 if (lseek (pHandleImpl
->fd
, (off_t
)nCurPos
, SEEK_SET
) < 0)
2287 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]");
2292 return (osl_File_E_None
);
2295 /*###############################################*/
2296 oslFileError SAL_CALL
osl_syncFile(oslFileHandle Handle
)
2298 oslFileHandleImpl
* handle_impl
= (oslFileHandleImpl
*)Handle
;
2300 if (handle_impl
== 0)
2301 return osl_File_E_INVAL
;
2303 if (fsync(handle_impl
->fd
) == -1)
2304 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
2306 return osl_File_E_None
;
2309 /******************************************************************************
2311 * C-String Versions of Exported Module Functions
2313 *****************************************************************************/
2315 #ifdef HAVE_STATFS_H
2317 #if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
2318 # define __OSL_STATFS_STRUCT struct statfs
2319 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
2320 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
2321 # define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
2322 # define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
2324 /* always return true if queried for the properties of
2325 the file system. If you think this is wrong under any
2326 of the target platforms fix it!!!! */
2327 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2328 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2329 #endif /* FREEBSD || NETBSD */
2332 # define __OSL_NFS_SUPER_MAGIC 0x6969
2333 # define __OSL_SMB_SUPER_MAGIC 0x517B
2334 # define __OSL_MSDOS_SUPER_MAGIC 0x4d44
2335 # define __OSL_NTFS_SUPER_MAGIC 0x5346544e
2336 # define __OSL_STATFS_STRUCT struct statfs
2337 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
2338 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
2339 # define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
2340 # define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
2341 # define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
2342 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
2343 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
2346 #if defined(SOLARIS) || defined(IRIX)
2347 # define __OSL_STATFS_STRUCT struct statvfs
2348 # define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
2349 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
2350 # define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
2351 # define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
2353 /* always return true if queried for the properties of
2354 the file system. If you think this is wrong under any
2355 of the target platforms fix it!!!! */
2356 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2357 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2358 #endif /* SOLARIS || IRIX*/
2360 # define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
2362 #else /* no statfs available */
2364 # define __OSL_STATFS_STRUCT struct dummy {int i;}
2365 # define __OSL_STATFS_INIT(a) ((void)0)
2366 # define __OSL_STATFS(dir, sfs) (1)
2367 # define __OSL_STATFS_ISREMOTE(sfs) (0)
2368 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2369 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2370 #endif /* HAVE_STATFS_H */
2373 static oslFileError
osl_psz_getVolumeInformation (
2374 const sal_Char
* pszDirectory
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
2376 __OSL_STATFS_STRUCT sfs
;
2379 return osl_File_E_INVAL
;
2381 __OSL_STATFS_INIT(sfs
);
2383 pInfo
->uValidFields
= 0;
2384 pInfo
->uAttributes
= 0;
2386 if ((__OSL_STATFS(pszDirectory
, &sfs
)) < 0)
2388 oslFileError result
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
2392 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
2393 if (uFieldMask
& osl_VolumeInfo_Mask_Attributes
)
2395 if (__OSL_STATFS_ISREMOTE(sfs
))
2396 pInfo
->uAttributes
|= osl_Volume_Attribute_Remote
;
2398 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
2401 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemCaseHandling
)
2403 if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs
))
2404 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Sensitive
;
2406 if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs
))
2407 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Is_Preserved
;
2409 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
2412 pInfo
->uTotalSpace
= 0;
2413 pInfo
->uFreeSpace
= 0;
2414 pInfo
->uUsedSpace
= 0;
2416 #if defined(__OSL_STATFS_BLKSIZ)
2418 if ((uFieldMask
& osl_VolumeInfo_Mask_TotalSpace
) ||
2419 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
2421 pInfo
->uTotalSpace
= __OSL_STATFS_BLKSIZ(sfs
);
2422 pInfo
->uTotalSpace
*= (sal_uInt64
)(sfs
.f_blocks
);
2423 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_TotalSpace
;
2426 if ((uFieldMask
& osl_VolumeInfo_Mask_FreeSpace
) ||
2427 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
2429 pInfo
->uFreeSpace
= __OSL_STATFS_BLKSIZ(sfs
);
2432 pInfo
->uFreeSpace
*= (sal_uInt64
)(sfs
.f_bfree
);
2434 pInfo
->uFreeSpace
*= (sal_uInt64
)(sfs
.f_bavail
);
2436 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FreeSpace
;
2439 #endif /* __OSL_STATFS_BLKSIZ */
2441 if ((pInfo
->uValidFields
& osl_VolumeInfo_Mask_TotalSpace
) &&
2442 (pInfo
->uValidFields
& osl_VolumeInfo_Mask_FreeSpace
))
2444 pInfo
->uUsedSpace
= pInfo
->uTotalSpace
- pInfo
->uFreeSpace
;
2445 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_UsedSpace
;
2448 pInfo
->uMaxNameLength
= 0;
2449 if (uFieldMask
& osl_VolumeInfo_Mask_MaxNameLength
)
2451 long nLen
= pathconf(pszDirectory
, _PC_NAME_MAX
);
2454 pInfo
->uMaxNameLength
= (sal_uInt32
)nLen
;
2455 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxNameLength
;
2459 pInfo
->uMaxPathLength
= 0;
2460 if (uFieldMask
& osl_VolumeInfo_Mask_MaxPathLength
)
2462 long nLen
= pathconf (pszDirectory
, _PC_PATH_MAX
);
2465 pInfo
->uMaxPathLength
= (sal_uInt32
)nLen
;
2466 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxPathLength
;
2470 #if defined(__OSL_STATFS_TYPENAME)
2472 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemName
)
2475 &(pInfo
->ustrFileSystemName
),
2476 __OSL_STATFS_TYPENAME(sfs
),
2477 rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs
)),
2478 osl_getThreadTextEncoding(),
2479 OUSTRING_TO_OSTRING_CVTFLAGS
);
2480 OSL_ASSERT(pInfo
->ustrFileSystemName
!= 0);
2482 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FileSystemName
;
2485 #endif /* __OSL_STATFS_TYPENAME */
2487 if (uFieldMask
& osl_VolumeInfo_Mask_DeviceHandle
)
2489 /* FIXME: check also entries in mntent for the device
2490 and fill it with correct values */
2492 *pInfo
->pDeviceHandle
= osl_isFloppyDrive(pszDirectory
);
2494 if (*pInfo
->pDeviceHandle
)
2496 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_DeviceHandle
;
2497 pInfo
->uAttributes
|= osl_Volume_Attribute_Removeable
;
2498 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
2501 return osl_File_E_None
;
2504 /******************************************
2505 * osl_psz_setFileTime
2506 *****************************************/
2508 static oslFileError
osl_psz_setFileTime( const sal_Char
* pszFilePath
,
2509 const TimeValue
* /*pCreationTime*/,
2510 const TimeValue
* pLastAccessTime
,
2511 const TimeValue
* pLastWriteTime
)
2514 struct utimbuf aTimeBuffer
;
2515 struct stat aFileStat
;
2516 #ifdef DEBUG_OSL_FILE
2520 nRet
= lstat(pszFilePath
,&aFileStat
);
2525 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2528 #ifdef DEBUG_OSL_FILE
2529 fprintf(stderr
,"File Times are (in localtime):\n");
2530 pTM
=localtime(&aFileStat
.st_ctime
);
2531 fprintf(stderr
,"CreationTime is '%s'\n",asctime(pTM
));
2532 pTM
=localtime(&aFileStat
.st_atime
);
2533 fprintf(stderr
,"AccessTime is '%s'\n",asctime(pTM
));
2534 pTM
=localtime(&aFileStat
.st_mtime
);
2535 fprintf(stderr
,"Modification is '%s'\n",asctime(pTM
));
2537 fprintf(stderr
,"File Times are (in UTC):\n");
2538 fprintf(stderr
,"CreationTime is '%s'\n",ctime(&aFileStat
.st_ctime
));
2539 fprintf(stderr
,"AccessTime is '%s'\n",ctime(&aTimeBuffer
.actime
));
2540 fprintf(stderr
,"Modification is '%s'\n",ctime(&aTimeBuffer
.modtime
));
2543 if ( pLastAccessTime
!= 0 )
2545 aTimeBuffer
.actime
=pLastAccessTime
->Seconds
;
2549 aTimeBuffer
.actime
=aFileStat
.st_atime
;
2552 if ( pLastWriteTime
!= 0 )
2554 aTimeBuffer
.modtime
=pLastWriteTime
->Seconds
;
2558 aTimeBuffer
.modtime
=aFileStat
.st_mtime
;
2561 /* mfe: Creation time not used here! */
2563 #ifdef DEBUG_OSL_FILE
2564 fprintf(stderr
,"File Times are (in localtime):\n");
2565 pTM
=localtime(&aFileStat
.st_ctime
);
2566 fprintf(stderr
,"CreationTime now '%s'\n",asctime(pTM
));
2567 pTM
=localtime(&aTimeBuffer
.actime
);
2568 fprintf(stderr
,"AccessTime now '%s'\n",asctime(pTM
));
2569 pTM
=localtime(&aTimeBuffer
.modtime
);
2570 fprintf(stderr
,"Modification now '%s'\n",asctime(pTM
));
2572 fprintf(stderr
,"File Times are (in UTC):\n");
2573 fprintf(stderr
,"CreationTime now '%s'\n",ctime(&aFileStat
.st_ctime
));
2574 fprintf(stderr
,"AccessTime now '%s'\n",ctime(&aTimeBuffer
.actime
));
2575 fprintf(stderr
,"Modification now '%s'\n",ctime(&aTimeBuffer
.modtime
));
2578 nRet
=utime(pszFilePath
,&aTimeBuffer
);
2582 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2585 return osl_File_E_None
;
2589 /*****************************************
2590 * osl_psz_removeFile
2591 ****************************************/
2593 static oslFileError
osl_psz_removeFile( const sal_Char
* pszPath
)
2598 nRet
= stat(pszPath
,&aStat
);
2602 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2605 if ( S_ISDIR(aStat
.st_mode
) )
2607 return osl_File_E_ISDIR
;
2610 nRet
= unlink(pszPath
);
2614 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2617 return osl_File_E_None
;
2621 /*****************************************
2622 * osl_psz_createDirectory
2623 ****************************************/
2625 static oslFileError
osl_psz_createDirectory( const sal_Char
* pszPath
)
2628 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
2630 nRet
= mkdir(pszPath
,mode
);
2635 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2638 return osl_File_E_None
;
2641 /*****************************************
2642 * osl_psz_removeDirectory
2643 ****************************************/
2645 static oslFileError
osl_psz_removeDirectory( const sal_Char
* pszPath
)
2649 nRet
= rmdir(pszPath
);
2654 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2657 return osl_File_E_None
;
2660 /*****************************************
2662 ****************************************/
2664 static oslFileError
oslDoMoveFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
2666 oslFileError tErr
=osl_File_E_invalidError
;
2668 tErr
= osl_psz_moveFile(pszPath
,pszDestPath
);
2669 if ( tErr
== osl_File_E_None
)
2674 if ( tErr
!= osl_File_E_XDEV
)
2679 tErr
=osl_psz_copyFile(pszPath
,pszDestPath
);
2681 if ( tErr
!= osl_File_E_None
)
2683 oslFileError tErrRemove
;
2684 tErrRemove
=osl_psz_removeFile(pszDestPath
);
2688 tErr
=osl_psz_removeFile(pszPath
);
2693 /*****************************************
2695 ****************************************/
2697 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
2702 nRet
= rename(pszPath
,pszDestPath
);
2707 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2710 return osl_File_E_None
;
2713 /*****************************************
2715 ****************************************/
2717 static oslFileError
osl_psz_copyFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
2725 struct stat aFileStat
;
2726 oslFileError tErr
=osl_File_E_invalidError
;
2727 size_t nSourceSize
=0;
2728 int DestFileExists
=1;
2730 /* mfe: does the source file really exists? */
2731 nRet
= lstat(pszPath
,&aFileStat
);
2736 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2739 /* mfe: we do only copy files here! */
2740 if ( S_ISDIR(aFileStat
.st_mode
) )
2742 return osl_File_E_ISDIR
;
2745 nSourceSize
=(size_t)aFileStat
.st_size
;
2746 nMode
=aFileStat
.st_mode
;
2747 nAcTime
=aFileStat
.st_atime
;
2748 nModTime
=aFileStat
.st_mtime
;
2749 nUID
=aFileStat
.st_uid
;
2750 nGID
=aFileStat
.st_gid
;
2752 nRet
= stat(pszDestPath
,&aFileStat
);
2757 if ( nRet
== ENOENT
)
2761 /* return oslTranslateFileError(nRet);*/
2764 /* mfe: the destination file must not be a directory! */
2765 if ( nRet
== 0 && S_ISDIR(aFileStat
.st_mode
) )
2767 return osl_File_E_ISDIR
;
2771 /* mfe: file does not exists or is no dir */
2774 tErr
= oslDoCopy(pszPath
,pszDestPath
,nMode
,nSourceSize
,DestFileExists
);
2776 if ( tErr
!= osl_File_E_None
)
2782 * mfe: ignore return code
2783 * since only the success of the copy is
2786 oslChangeFileModes(pszDestPath
,nMode
,nAcTime
,nModTime
,nUID
,nGID
);
2792 /******************************************************************************
2796 *****************************************************************************/
2799 /*****************************************
2800 * oslMakeUStrFromPsz
2801 ****************************************/
2803 rtl_uString
* oslMakeUStrFromPsz(const sal_Char
* pszStr
, rtl_uString
** ustrValid
)
2808 rtl_str_getLength( pszStr
),
2809 osl_getThreadTextEncoding(),
2810 OUSTRING_TO_OSTRING_CVTFLAGS
);
2811 OSL_ASSERT(*ustrValid
!= 0);
2816 /*****************************************************************************
2818 * converting unicode to text manually saves us the penalty of a temporary
2819 * rtl_String object.
2820 ****************************************************************************/
2822 int UnicodeToText( char * buffer
, size_t bufLen
, const sal_Unicode
* uniText
, sal_Int32 uniTextLen
)
2824 rtl_UnicodeToTextConverter hConverter
;
2826 sal_Size nSrcChars
, nDestBytes
;
2828 /* stolen from rtl/string.c */
2829 hConverter
= rtl_createUnicodeToTextConverter( osl_getThreadTextEncoding() );
2831 nDestBytes
= rtl_convertUnicodeToText( hConverter
, 0, uniText
, uniTextLen
,
2833 OUSTRING_TO_OSTRING_CVTFLAGS
| RTL_UNICODETOTEXT_FLAGS_FLUSH
,
2834 &nInfo
, &nSrcChars
);
2836 rtl_destroyUnicodeToTextConverter( hConverter
);
2838 if( nInfo
& RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
)
2844 /* ensure trailing '\0' */
2845 buffer
[nDestBytes
] = '\0';
2850 /*****************************************************************************
2854 The text to convert.
2856 @param text_buffer_size
2857 The number of characters.
2862 @param unic_text_buffer_size
2863 The size in characters of the unicode buffer.
2865 ****************************************************************************/
2869 size_t text_buffer_size
,
2870 sal_Unicode
* unic_text
,
2871 sal_Int32 unic_text_buffer_size
)
2873 rtl_TextToUnicodeConverter hConverter
;
2876 sal_Size nDestBytes
;
2878 /* stolen from rtl/string.c */
2879 hConverter
= rtl_createTextToUnicodeConverter(osl_getThreadTextEncoding());
2881 nDestBytes
= rtl_convertTextToUnicode(hConverter
,
2883 text
, text_buffer_size
,
2884 unic_text
, unic_text_buffer_size
,
2885 OSTRING_TO_OUSTRING_CVTFLAGS
| RTL_TEXTTOUNICODE_FLAGS_FLUSH
,
2886 &nInfo
, &nSrcChars
);
2888 rtl_destroyTextToUnicodeConverter(hConverter
);
2890 if (nInfo
& RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL
)
2896 /* ensure trailing '\0' */
2897 unic_text
[nDestBytes
] = '\0';
2902 /******************************************************************************
2904 * GENERIC FLOPPY FUNCTIONS
2906 *****************************************************************************/
2909 /*****************************************
2910 * osl_unmountVolumeDevice
2911 ****************************************/
2913 oslFileError
osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle
)
2915 oslFileError tErr
= osl_File_E_NOSYS
;
2917 tErr
= osl_unmountFloppy(Handle
);
2919 /* Perhaps current working directory is set to mount point */
2923 sal_Char
*pszHomeDir
= getenv("HOME");
2925 if ( pszHomeDir
&& strlen( pszHomeDir
) && 0 == chdir( pszHomeDir
) )
2929 tErr
= osl_unmountFloppy(Handle
);
2931 OSL_ENSURE( tErr
, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
2938 /*****************************************
2939 * osl_automountVolumeDevice
2940 ****************************************/
2942 oslFileError
osl_automountVolumeDevice( oslVolumeDeviceHandle Handle
)
2944 oslFileError tErr
= osl_File_E_NOSYS
;
2946 tErr
= osl_mountFloppy(Handle
);
2951 /*****************************************
2952 * osl_getVolumeDeviceMountPath
2953 ****************************************/
2955 oslFileError
osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle
, rtl_uString
**pstrPath
)
2957 oslVolumeDeviceHandleImpl
* pItem
= (oslVolumeDeviceHandleImpl
*) Handle
;
2958 sal_Char Buffer
[PATH_MAX
];
2962 if ( pItem
== 0 || pstrPath
== 0 )
2964 return osl_File_E_INVAL
;
2967 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
2969 return osl_File_E_INVAL
;
2972 #ifdef DEBUG_OSL_FILE
2973 fprintf(stderr
,"Handle is:\n");
2974 osl_printFloppyHandle(pItem
);
2977 snprintf(Buffer
, sizeof(Buffer
), "file://%s", pItem
->pszMountPoint
);
2979 #ifdef DEBUG_OSL_FILE
2980 fprintf(stderr
,"Mount Point is: '%s'\n",Buffer
);
2983 oslMakeUStrFromPsz(Buffer
, pstrPath
);
2985 return osl_File_E_None
;
2988 /*****************************************
2989 * osl_acquireVolumeDeviceHandle
2990 ****************************************/
2992 oslFileError SAL_CALL
osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
2994 oslVolumeDeviceHandleImpl
* pItem
=(oslVolumeDeviceHandleImpl
*) Handle
;
2998 return osl_File_E_INVAL
;
3001 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3003 return osl_File_E_INVAL
;
3008 return osl_File_E_None
;
3011 /*****************************************
3012 * osl_releaseVolumeDeviceHandle
3013 ****************************************/
3015 oslFileError
osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
3017 oslVolumeDeviceHandleImpl
* pItem
=(oslVolumeDeviceHandleImpl
*) Handle
;
3021 return osl_File_E_INVAL
;
3024 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3026 return osl_File_E_INVAL
;
3031 if ( pItem
->RefCount
== 0 )
3033 rtl_freeMemory(pItem
);
3036 return osl_File_E_None
;
3039 /*****************************************
3040 * osl_newVolumeDeviceHandleImpl
3041 ****************************************/
3043 static oslVolumeDeviceHandleImpl
* osl_newVolumeDeviceHandleImpl()
3045 oslVolumeDeviceHandleImpl
* pHandle
;
3046 const size_t nSizeOfHandle
= sizeof(oslVolumeDeviceHandleImpl
);
3048 pHandle
= (oslVolumeDeviceHandleImpl
*) rtl_allocateMemory (nSizeOfHandle
);
3049 if (pHandle
!= NULL
)
3051 pHandle
->ident
[0] = 'O';
3052 pHandle
->ident
[1] = 'V';
3053 pHandle
->ident
[2] = 'D';
3054 pHandle
->ident
[3] = 'H';
3055 pHandle
->pszMountPoint
[0] = '\0';
3056 pHandle
->pszFilePath
[0] = '\0';
3057 pHandle
->pszDevice
[0] = '\0';
3058 pHandle
->RefCount
= 1;
3063 /*****************************************
3064 * osl_freeVolumeDeviceHandleImpl
3065 ****************************************/
3067 static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl
* pHandle
)
3069 if (pHandle
!= NULL
)
3070 rtl_freeMemory (pHandle
);
3074 /******************************************************************************
3076 * OS/2 FLOPPY FUNCTIONS
3078 *****************************************************************************/
3081 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
)
3086 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
3088 return osl_File_E_BUSY
;
3091 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
3093 return osl_File_E_BUSY
;
3096 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
3101 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
)
3107 #ifdef DEBUG_OSL_FILE
3108 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl
* pItem
)
3112 fprintf(stderr
,"NULL Handle\n");
3115 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3117 #ifdef TRACE_OSL_FILE
3118 fprintf(stderr
,"Invalid Handle]\n");
3124 fprintf(stderr
,"MountPoint : '%s'\n",pItem
->pszMountPoint
);
3125 fprintf(stderr
,"FilePath : '%s'\n",pItem
->pszFilePath
);
3126 fprintf(stderr
,"Device : '%s'\n",pItem
->pszDevice
);