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_url.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 ************************************************************************/
54 #include <osl/security.h>
56 #include <osl/diagnose.h>
57 #include <rtl/ustring.hxx>
58 #include <rtl/ustrbuf.h>
61 #include <osl/thread.h>
63 #include <osl/file.hxx>
64 #include <osl/mutex.h>
65 #include <osl/process.h>
66 #include "file_error_transl.h"
71 #include "file_path_helper.hxx"
73 #ifndef _OSL_UUNXAPI_HXX_
74 #include "uunxapi.hxx"
80 /***************************************************
84 This file contains the part that handles File URLs.
86 File URLs as scheme specific notion of URIs
87 (RFC2396) may be handled platform independend, but
88 will not in osl which is considered wrong.
89 Future version of osl should handle File URLs this
90 way. In rtl/uri there is already an URI parser etc.
91 so this code should be consolidated.
93 **************************************************/
95 oslMutex g_CurrentDirectoryMutex
;
98 /***************************************************
100 **************************************************/
102 void _osl_warnFile(const char*, rtl_uString
*);
103 rtl_uString
* oslMakeUStrFromPsz(const sal_Char
* pszStr
,rtl_uString
** uStr
);
105 extern "C" int UnicodeToText(char *, size_t, const sal_Unicode
*, sal_Int32
);
106 extern "C" int TextToUnicode(const char* text
, size_t text_buffer_size
, sal_Unicode
* unic_text
, sal_Int32 unic_text_buffer_size
);
108 /***************************************************
109 * namespace directives
110 **************************************************/
114 /******************************************************************************
116 * Exported Module Functions
118 *****************************************************************************/
120 /* a slightly modified version of Pchar in rtl/source/uri.c */
121 const sal_Bool uriCharClass
[128] =
123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Pchar but without encoding slashes */
124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
125 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* !"#$%&'()*+,-./ */
126 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, /* 0123456789:;<=>? */
127 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ABCDEFGHIJKLMNO */
128 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* PQRSTUVWXYZ[\]^_ */
129 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* `abcdefghijklmno */
130 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 /* pqrstuvwxyz{|}~ */
134 /* check for top wrong usage strings */
136 static sal_Bool findWrongUsage( const sal_Unicode *path, sal_Int32 len )
138 rtl_uString *pTmp = NULL;
141 rtl_uString_newFromStr_WithLength( &pTmp, path, len );
143 rtl_ustr_toAsciiLowerCase_WithLength( pTmp->buffer, pTmp->length );
145 bRet = ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "ftp://", 6 ) ) ||
146 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "http://", 7 ) ) ||
147 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "vnd.sun.star", 12 ) ) ||
148 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "private:", 8 ) ) ||
149 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "slot:", 5) );
151 rtl_uString_release( pTmp );
157 /****************************************************************************/
158 /* osl_getFileURLFromSystemPath */
159 /****************************************************************************/
161 BOOL WINAPI
IsValidFilePathComponent(
162 LPCTSTR lpComponent
, LPCTSTR
*lppComponentEnd
, DWORD dwFlags
)
164 LPCTSTR lpComponentEnd
= NULL
;
165 LPCTSTR lpCurrent
= lpComponent
;
166 BOOL fValid
= TRUE
; /* Assume success */
169 /* Path component length must not exceed MAX_PATH */
171 while ( !lpComponentEnd
&& lpCurrent
&& lpCurrent
- lpComponent
< _MAX_PATH
)
173 switch ( *lpCurrent
)
175 /* Both backslash and slash determine the end of a path component */
181 /* Component must not end with '.' or blank and can't be empty */
184 if ( dwFlags
& VALIDATEPATH_ALLOW_ELLIPSE
)
186 if ( 1 == lpCurrent
- lpComponent
)
188 /* Current directory is O.K. */
189 lpComponentEnd
= lpCurrent
;
192 else if ( 2 == lpCurrent
- lpComponent
&& '.' == *lpComponent
)
194 /* Parent directory is O.K. */
195 lpComponentEnd
= lpCurrent
;
201 lpComponentEnd
= lpCurrent
- 1;
205 lpComponentEnd
= lpCurrent
;
209 /* '?' and '*' are valid wildcards but not valid file name characters */
212 if ( dwFlags
& VALIDATEPATH_ALLOW_WILDCARDS
)
214 /* The following characters are reserved */
220 lpComponentEnd
= lpCurrent
;
224 /* Characters below ASCII 32 are not allowed */
225 if ( *lpCurrent
< ' ' )
227 lpComponentEnd
= lpCurrent
;
232 cLast
= *lpCurrent
++;
235 /* If we don't reached the end of the component the length of the component was to long
236 ( See condition of while loop ) */
237 if ( !lpComponentEnd
)
240 lpComponentEnd
= lpCurrent
;
243 /* Test wether the component specifies a device name what is not allowed */
246 // This is very expensive. A lot of calls to _tcsicmp.
247 // in SRC6870m71 67.000 calls of this method while empty office start result into more than 1.500.00 calls of _tcsicmp!
248 // Possible optimizations
249 // - Array should be const static
250 // - Sorted array, use binary search
251 // - More intelligent check for com1-9, lpt1-9
252 // Maybe make szComponent upper case, don't search case intensitive
253 // Talked to HRO: Could be removed. Shouldn't be used in OOo, and if used for something like a filename, it will lead to an error anyway.
257 LPCTSTR alpDeviceNames[] =
284 TCHAR szComponent[MAX_PATH];
285 int nComponentLength;
289 // A device name with an extension is also invalid
290 lpDot = _tcschr( lpComponent, '.' );
292 if ( !lpDot || lpDot > lpComponentEnd )
293 nComponentLength = lpComponentEnd - lpComponent;
295 nComponentLength = lpDot - lpComponent;
297 _tcsncpy( szComponent, lpComponent, nComponentLength );
298 szComponent[nComponentLength] = 0;
300 for ( i = 0; i < sizeof( alpDeviceNames ) / sizeof(LPCTSTR); i++ )
302 if ( 0 == _tcsicmp( szComponent, alpDeviceNames[i] ) )
304 lpComponentEnd = lpComponent;
314 // Empty components are not allowed
315 if ( lpComponentEnd
- lpComponent
< 1 )
318 // If we reached the end of the string NULL is returned
319 else if ( !*lpComponentEnd
)
320 lpComponentEnd
= NULL
;
324 if ( lppComponentEnd
)
325 *lppComponentEnd
= lpComponentEnd
;
330 //#####################################################
331 DWORD WINAPI
IsValidFilePath(LPCTSTR lpszPath
, LPCTSTR
*lppError
, DWORD dwFlags
)
335 DWORD dwPathType
= PATHTYPE_ERROR
;
337 if ( dwFlags
& VALIDATEPATH_ALLOW_RELATIVE
)
338 dwFlags
|= VALIDATEPATH_ALLOW_ELLIPSE
;
343 lpComponent
= lpszPath
;
346 /* Test for UNC path notation */
347 if ( 2 == _tcsspn( lpszPath
, CHARSET_SEPARATOR
) )
349 /* Place the pointer behind the leading to backslashes */
351 lpComponent
= lpszPath
+ 2;
353 fValid
= IsValidFilePathComponent( lpComponent
, &lpComponent
, VALIDATEPATH_ALLOW_ELLIPSE
);
355 /* So far we have a valid servername. Now let's see if we also have a network resource */
357 dwPathType
= PATHTYPE_ABSOLUTE_UNC
;
361 if ( lpComponent
&& !*++lpComponent
)
367 /* We only have a Server specification what is invalid */
369 lpComponent
= lpszPath
;
372 dwPathType
|= PATHTYPE_IS_SERVER
;
377 /* Now test the network resource */
379 fValid
= IsValidFilePathComponent( lpComponent
, &lpComponent
, 0 );
381 /* If we now reached the end of the path, everything is O.K. */
384 if ( fValid
&& (!lpComponent
|| lpComponent
&& !*++lpComponent
) )
387 dwPathType
|= PATHTYPE_IS_VOLUME
;
393 /* Local path verification. Must start with <drive>: */
394 else if ( _istalpha( lpszPath
[0] ) && ':' == lpszPath
[1] )
396 /* Place pointer behind correct drive specification */
398 lpComponent
= lpszPath
+ 2;
400 if ( 1 == _tcsspn( lpComponent
, CHARSET_SEPARATOR
) )
402 else if ( *lpComponent
)
405 dwPathType
= PATHTYPE_ABSOLUTE_LOCAL
;
407 /* Now we are behind the backslash or it was a simple drive without backslash */
409 if ( fValid
&& !*lpComponent
)
412 dwPathType
|= PATHTYPE_IS_VOLUME
;
416 /* Can be a relative path */
417 else if ( dwFlags
& VALIDATEPATH_ALLOW_RELATIVE
)
419 lpComponent
= lpszPath
;
421 /* Relative path can start with a backslash */
423 if ( 1 == _tcsspn( lpComponent
, CHARSET_SEPARATOR
) )
430 dwPathType
= PATHTYPE_RELATIVE
;
433 /* Anything else is an error */
437 lpComponent
= lpszPath
;
440 /* Now validate each component of the path */
441 while ( fValid
&& lpComponent
)
443 fValid
= IsValidFilePathComponent( lpComponent
, &lpComponent
, dwFlags
);
445 if ( fValid
&& lpComponent
)
449 /* If the string behind the backslash is empty, we've done */
456 if ( fValid
&& _tcslen( lpszPath
) >= _MAX_PATH
)
459 lpComponent
= lpszPath
+ _MAX_PATH
;
463 *lppError
= lpComponent
;
465 return fValid
? dwPathType
: PATHTYPE_ERROR
;
468 sal_Bool
_osl_decodeURL( rtl_String
* strUTF8
, rtl_uString
** pstrDecodedURL
)
471 const sal_Char
*pSrcEnd
;
472 const sal_Char
*pSrc
;
475 sal_Bool bValidEncoded
= sal_True
; /* Assume success */
477 /* The resulting decoded string length is shorter or equal to the source length */
479 nSrcLen
= rtl_string_getLength(strUTF8
);
480 pBuffer
= reinterpret_cast<sal_Char
*>(rtl_allocateMemory(nSrcLen
+ 1));
483 pSrc
= rtl_string_getStr(strUTF8
);
484 pSrcEnd
= pSrc
+ nSrcLen
;
486 /* Now decode the URL what should result in an UTF8 string */
487 while ( bValidEncoded
&& pSrc
< pSrcEnd
)
501 aChar
= (sal_Char
)strtoul( aToken
, NULL
, 16 );
503 /* The chars are path delimiters and must not be encoded */
505 if ( 0 == aChar
|| '\\' == aChar
|| '/' == aChar
|| ':' == aChar
)
506 bValidEncoded
= sal_False
;
519 if ( bValidEncoded
) {
520 rtl_string2UString( pstrDecodedURL
, pBuffer
, rtl_str_getLength(pBuffer
), RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
521 OSL_ASSERT(*pstrDecodedURL
!= 0);
524 rtl_freeMemory( pBuffer
);
526 return bValidEncoded
;
529 //#############################################
530 void _osl_encodeURL( rtl_uString
*strURL
, rtl_String
**pstrEncodedURL
)
532 /* Encode non ascii characters within the URL */
534 rtl_String
*strUTF8
= NULL
;
535 sal_Char
*pszEncodedURL
;
536 const sal_Char
*pURLScan
;
538 sal_Int32 nURLScanLen
;
539 sal_Int32 nURLScanCount
;
541 rtl_uString2String( &strUTF8
, rtl_uString_getStr( strURL
), rtl_uString_getLength( strURL
), RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
543 pszEncodedURL
= (sal_Char
*) rtl_allocateMemory( (rtl_string_getLength( strUTF8
) * 3 + 1) * sizeof(sal_Char
) );
545 pURLDest
= pszEncodedURL
;
546 pURLScan
= rtl_string_getStr( strUTF8
);
547 nURLScanLen
= rtl_string_getLength( strUTF8
);
550 while ( nURLScanCount
< nURLScanLen
)
552 sal_Char cCurrent
= *pURLScan
;
557 if (!( ( cCurrent
>= 'a' && cCurrent
<= 'z' ) || ( cCurrent
>= 'A' && cCurrent
<= 'Z' ) || ( cCurrent
>= '0' && cCurrent
<= '9' ) ) )
559 sprintf( pURLDest
, "%%%02X", (unsigned char)cCurrent
);
582 *pURLDest
++ = cCurrent
;
595 rtl_string_release( strUTF8
);
596 rtl_string_newFromStr( pstrEncodedURL
, pszEncodedURL
);
597 rtl_freeMemory( pszEncodedURL
);
600 //#############################################
601 oslFileError SAL_CALL
_osl_getFileURLFromSystemPath( rtl_uString
* strPath
, rtl_uString
** pstrURL
)
603 oslFileError nError
= osl_File_E_INVAL
; /* Assume failure */
604 rtl_uString
*strTempURL
= NULL
;
605 DWORD dwPathType
= PATHTYPE_ERROR
;
608 dwPathType
= IsValidFilePath(strPath
->buffer
, NULL
, VALIDATEPATH_ALLOW_RELATIVE
);
612 rtl_uString
*strTempPath
= NULL
;
614 /* Replace backslashes */
616 rtl_uString_newReplace( &strTempPath
, strPath
, '\\', '/' );
618 switch ( dwPathType
& PATHTYPE_MASK_TYPE
)
620 case PATHTYPE_RELATIVE
:
621 rtl_uString_assign( &strTempURL
, strTempPath
);
622 nError
= osl_File_E_None
;
624 case PATHTYPE_ABSOLUTE_UNC
:
625 rtl_uString_newFromAscii( &strTempURL
, "file:" );
626 rtl_uString_newConcat( &strTempURL
, strTempURL
, strTempPath
);
627 nError
= osl_File_E_None
;
629 case PATHTYPE_ABSOLUTE_LOCAL
:
630 rtl_uString_newFromAscii( &strTempURL
, "file:///" );
631 rtl_uString_newConcat( &strTempURL
, strTempURL
, strTempPath
);
632 nError
= osl_File_E_None
;
638 /* Release temp path */
640 rtl_uString_release( strTempPath
);
643 if ( osl_File_E_None
== nError
)
645 rtl_String
*strEncodedURL
= NULL
;
649 _osl_encodeURL( strTempURL
, &strEncodedURL
);
651 /* Provide URL via unicode string */
653 rtl_string2UString( pstrURL
, rtl_string_getStr(strEncodedURL
), rtl_string_getLength(strEncodedURL
), RTL_TEXTENCODING_ASCII_US
, OUSTRING_TO_OSTRING_CVTFLAGS
);
654 OSL_ASSERT(*pstrURL
!= 0);
655 rtl_string_release( strEncodedURL
);
658 /* Release temp URL */
661 rtl_uString_release( strTempURL
);
664 OSL_ENSURE_FILE( !nError, "osl_getFileURLFromSystemPath: \"%s\" is not a systemPath !!!", strPath );
670 oslFileError SAL_CALL
osl_getFileURLFromSystemPath( rtl_uString
*ustrSystemPath
, rtl_uString
**pustrFileURL
)
672 return _osl_getFileURLFromSystemPath( ustrSystemPath
, pustrFileURL
);
674 static const sal_Unicode pDoubleSlash
[2] = { '/', '/' };
676 rtl_uString
*pTmp
= NULL
;
679 if( 0 == ustrSystemPath
->length
)
680 return osl_File_E_INVAL
;
682 /* YD convert '\' to '/' */
683 rtl_ustr_replaceChar( ustrSystemPath
->buffer
, '\\', '/' );
685 /* temporary hack: if already file url, return ustrSystemPath */
686 if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( ustrSystemPath
->buffer
, ustrSystemPath
->length
,"file:", 5 ) )
689 if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( ustrSystemPath->buffer, ustrSystemPath->length,"file://", 7 ) )
691 OSL_ENSURE( 0, "osl_getFileURLFromSystemPath: input is already file URL" );
692 rtl_uString_assign( pustrFileURL, ustrSystemPath );
696 rtl_uString *pTmp2 = NULL;
698 OSL_ENSURE( 0, "osl_getFileURLFromSystemPath: input is wrong file URL" );
699 rtl_uString_newFromStr_WithLength( pustrFileURL, ustrSystemPath->buffer + 5, ustrSystemPath->length - 5 );
700 rtl_uString_newFromAscii( &pTmp2, "file://" );
701 rtl_uString_newConcat( pustrFileURL, *pustrFileURL, pTmp2 );
702 rtl_uString_release( pTmp2 );
704 return osl_File_E_None;
706 return osl_File_E_INVAL
;
710 /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */
711 if( (sal_Unicode
) '~' == ustrSystemPath
->buffer
[0] )
713 /* check if another user is specified */
714 if( ( 1 == ustrSystemPath
->length
) || ( (sal_Unicode
)'/' == ustrSystemPath
->buffer
[1] ) )
716 /* osl_getHomeDir returns file URL */
717 osl_getHomeDir( osl_getCurrentSecurity(), &pTmp
);
719 /* remove "file://" prefix */
720 rtl_uString_newFromStr_WithLength( &pTmp
, pTmp
->buffer
+ 7, pTmp
->length
- 7 );
722 /* replace '~' in original string */
723 rtl_uString_newReplaceStrAt( &pTmp
, ustrSystemPath
, 0, 1, pTmp
);
728 /* FIXME: replace ~user with users home directory */
729 return osl_File_E_INVAL
;
733 /* check if initial string contains double instances of '/' */
734 nIndex
= rtl_ustr_indexOfStr_WithLength( ustrSystemPath
->buffer
, ustrSystemPath
->length
, pDoubleSlash
, 2 );
738 sal_Int32 nDeleted
= 0;
740 /* if pTmp is not already allocated, copy ustrSystemPath for modification */
742 rtl_uString_newFromString( &pTmp
, ustrSystemPath
);
744 /* adapt index to pTmp */
745 nIndex
+= pTmp
->length
- ustrSystemPath
->length
;
747 /* remove all occurances of '//' */
748 for( nSrcIndex
= nIndex
+ 1; nSrcIndex
< pTmp
->length
; nSrcIndex
++ )
750 if( ((sal_Unicode
) '/' == pTmp
->buffer
[nSrcIndex
]) && ((sal_Unicode
) '/' == pTmp
->buffer
[nIndex
]) )
753 pTmp
->buffer
[++nIndex
] = pTmp
->buffer
[nSrcIndex
];
756 /* adjust length member */
757 pTmp
->length
-= nDeleted
;
761 rtl_uString_assign( &pTmp
, ustrSystemPath
);
763 /* temporary check for top 5 wrong usage strings (which are valid but unlikly filenames) */
765 OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) );
768 /* file URLs must be URI encoded */
769 rtl_uriEncode( pTmp
, uriCharClass
, rtl_UriEncodeIgnoreEscapes
, RTL_TEXTENCODING_UTF8
, pustrFileURL
);
771 rtl_uString_release( pTmp
);
773 /* absolute urls should start with 'file://' */
774 if( (sal_Unicode
)'/' == (*pustrFileURL
)->buffer
[0] )
776 rtl_uString
*pProtocol
= NULL
;
778 rtl_uString_newFromAscii( &pProtocol
, "file://" );
779 rtl_uString_newConcat( pustrFileURL
, pProtocol
, *pustrFileURL
);
780 rtl_uString_release( pProtocol
);
783 return osl_File_E_None
;
787 //#############################################
788 oslFileError SAL_CALL
_osl_getSystemPathFromFileURL( rtl_uString
*strURL
, rtl_uString
**pustrPath
, sal_Bool bAllowRelative
)
790 rtl_String
*strUTF8
= NULL
;
791 rtl_uString
*strDecodedURL
= NULL
;
792 rtl_uString
*strTempPath
= NULL
;
793 const sal_Unicode
*pDecodedURL
;
794 sal_uInt32 nDecodedLen
;
795 sal_Bool bValidEncoded
;
796 oslFileError nError
= osl_File_E_INVAL
; /* Assume failure */
798 /* If someone hasn't encoded the complete URL we convert it to UTF8 now to prevent from
799 having a mixed encoded URL later */
801 rtl_uString2String( &strUTF8
, rtl_uString_getStr( strURL
), rtl_uString_getLength( strURL
), RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
803 /* If the length of strUTF8 and strURL differs it indicates that the URL was not correct encoded */
806 strUTF8
->length
== strURL
->length
||
807 0 != rtl_ustr_ascii_shortenedCompare_WithLength( strURL
->buffer
, strURL
->length
, "file:\\\\", 7 )
808 ,"osl_getSystemPathFromFileURL: \"%s\" is not encoded !!!", strURL
);
810 bValidEncoded
= _osl_decodeURL( strUTF8
, &strDecodedURL
);
812 /* Release the encoded UTF8 string */
814 rtl_string_release( strUTF8
);
819 /* Replace backslashes and pipes */
821 rtl_uString_newReplace( &strDecodedURL
, strDecodedURL
, '/', '\\' );
822 rtl_uString_newReplace( &strDecodedURL
, strDecodedURL
, '|', ':' );
824 pDecodedURL
= rtl_uString_getStr( strDecodedURL
);
825 nDecodedLen
= rtl_uString_getLength( strDecodedURL
);
827 /* Must start with "file://" */
829 if ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pDecodedURL
, nDecodedLen
, "file:\\\\", 7 ) )
833 if ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pDecodedURL
, nDecodedLen
, "file:\\\\\\", 8 ) )
836 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pDecodedURL
, nDecodedLen
, "file:\\\\localhost\\", 17 ) ||
837 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pDecodedURL
, nDecodedLen
, "file:\\\\127.0.0.1\\", 17 )
843 /* Indicates local root */
844 if ( nDecodedLen
== nSkip
)
845 rtl_uString_newFromStr_WithLength( &strTempPath
, (const sal_Unicode
*)WSTR_SYSTEM_ROOT_PATH
, ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH
) - 1 );
847 rtl_uString_newFromStr_WithLength( &strTempPath
, pDecodedURL
+ nSkip
, nDecodedLen
- nSkip
);
849 if ( IsValidFilePath( strTempPath
->buffer
, NULL
, VALIDATEPATH_ALLOW_ELLIPSE
) )
850 nError
= osl_File_E_None
;
852 else if ( bAllowRelative
) /* This maybe a relative file URL */
854 rtl_uString_assign( &strTempPath
, strDecodedURL
);
856 if ( IsValidFilePath( strTempPath
->buffer
, NULL
, VALIDATEPATH_ALLOW_RELATIVE
| VALIDATEPATH_ALLOW_ELLIPSE
) )
857 nError
= osl_File_E_None
;
861 OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not an absolute FileURL !!!", strURL );
867 rtl_uString_release( strDecodedURL
);
869 if ( osl_File_E_None
== nError
)
870 rtl_uString_assign( pustrPath
, strTempPath
);
873 rtl_uString_release( strTempPath
);
876 OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not a FileURL !!!", strURL );
882 /****************************************************************************/
883 /* osl_getSystemPathFromFileURL */
884 /****************************************************************************/
886 oslFileError SAL_CALL
osl_getSystemPathFromFileURL( rtl_uString
*ustrFileURL
, rtl_uString
**pustrSystemPath
)
888 return _osl_getSystemPathFromFileURL( ustrFileURL
, pustrSystemPath
, sal_True
);
890 sal_Int32 nIndex
= 0;
891 rtl_uString
* pTmp
= NULL
;
893 sal_Unicode encodedSlash
[3] = { '%', '2', 'F' };
895 /* temporary hack: if already system path, return ustrFileURL */
897 if( (sal_Unicode) '/' == ustrFileURL->buffer[0] )
899 OSL_ENSURE( 0, "osl_getSystemPathFromFileURL: input is already system path" );
900 rtl_uString_assign( pustrSystemPath, ustrFileURL );
901 return osl_File_E_None;
905 /* a valid file url may not start with '/' */
906 if( ( 0 == ustrFileURL
->length
) || ( (sal_Unicode
) '/' == ustrFileURL
->buffer
[0] ) )
908 return osl_File_E_INVAL
;
911 /* search for encoded slashes (%2F) and decode every single token if we find one */
912 if( -1 != rtl_ustr_indexOfStr_WithLength( ustrFileURL
->buffer
, ustrFileURL
->length
, encodedSlash
, 3 ) )
914 rtl_uString
* ustrPathToken
= NULL
;
915 sal_Int32 nOffset
= 7;
921 /* break url down in '/' devided tokens tokens */
922 nIndex
= rtl_ustr_indexOfChar_WithLength( ustrFileURL
->buffer
+ nOffset
, ustrFileURL
->length
- nOffset
, (sal_Unicode
) '/' );
924 /* copy token to new string */
925 rtl_uString_newFromStr_WithLength( &ustrPathToken
, ustrFileURL
->buffer
+ nOffset
,
926 -1 == nIndex
? ustrFileURL
->length
- nOffset
: nIndex
++ );
929 rtl_uriDecode( ustrPathToken
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
, &pTmp
);
931 /* the result should not contain any '/' */
932 if( -1 != rtl_ustr_indexOfChar_WithLength( pTmp
->buffer
, pTmp
->length
, (sal_Unicode
) '/' ) )
934 rtl_uString_release( pTmp
);
935 rtl_uString_release( ustrPathToken
);
937 return osl_File_E_INVAL
;
940 } while( -1 != nIndex
);
942 /* release temporary string and restore index variable */
943 rtl_uString_release( ustrPathToken
);
947 /* protocol and server should not be encoded, so decode the whole string */
948 rtl_uriDecode( ustrFileURL
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
, &pTmp
);
950 /* check if file protocol specified */
951 /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */
952 if( 7 <= pTmp
->length
)
954 rtl_uString
* pProtocol
= NULL
;
955 rtl_uString_newFromStr_WithLength( &pProtocol
, pTmp
->buffer
, 7 );
957 /* protocol is case insensitive */
958 rtl_ustr_toAsciiLowerCase_WithLength( pProtocol
->buffer
, pProtocol
->length
);
960 if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pProtocol
->buffer
, pProtocol
->length
,"file://", 7 ) )
963 rtl_uString_release( pProtocol
);
966 /* skip "localhost" or "127.0.0.1" if "file://" is specified */
967 /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */
968 if( nIndex
&& ( 10 <= pTmp
->length
- nIndex
) )
970 rtl_uString
* pServer
= NULL
;
971 rtl_uString_newFromStr_WithLength( &pServer
, pTmp
->buffer
+ nIndex
, 10 );
973 /* server is case insensitive */
974 rtl_ustr_toAsciiLowerCase_WithLength( pServer
->buffer
, pServer
->length
);
976 if( ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer
->buffer
, pServer
->length
,"localhost/", 10 ) ) ||
977 ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer
->buffer
, pServer
->length
,"127.0.0.1/", 10 ) ) )
979 /* don't exclude the '/' */
983 rtl_uString_release( pServer
);
987 rtl_uString_newFromStr_WithLength( &pTmp
, pTmp
->buffer
+ nIndex
, pTmp
->length
- nIndex
);
989 /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */
990 if( (sal_Unicode
) '~' == pTmp
->buffer
[0] )
992 /* check if another user is specified */
993 if( ( 1 == pTmp
->length
) || ( (sal_Unicode
)'/' == pTmp
->buffer
[1] ) )
995 rtl_uString
*pTmp2
= NULL
;
997 /* osl_getHomeDir returns file URL */
998 osl_getHomeDir( osl_getCurrentSecurity(), &pTmp2
);
1000 /* remove "file://" prefix */
1001 rtl_uString_newFromStr_WithLength( &pTmp2
, pTmp2
->buffer
+ 7, pTmp2
->length
- 7 );
1003 /* replace '~' in original string */
1004 rtl_uString_newReplaceStrAt( &pTmp
, pTmp
, 0, 1, pTmp2
);
1005 rtl_uString_release( pTmp2
);
1010 /* FIXME: replace ~user with users home directory */
1011 return osl_File_E_INVAL
;
1015 /* temporary check for top 5 wrong usage strings (which are valid but unlikly filenames) */
1017 OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) );
1020 *pustrSystemPath
= pTmp
;
1021 return osl_File_E_None
;
1026 /****************************************************************************
1027 * osl_getSystemPathFromFileURL_Ex - helper function
1028 * clients may specify if they want to accept relative
1030 ****************************************************************************/
1032 oslFileError
osl_getSystemPathFromFileURL_Ex(
1033 rtl_uString
*ustrFileURL
, rtl_uString
**pustrSystemPath
, sal_Bool bAllowRelative
)
1035 return _osl_getSystemPathFromFileURL( ustrFileURL
, pustrSystemPath
, bAllowRelative
);
1037 rtl_uString
* temp
= 0;
1038 oslFileError osl_error
= osl_getSystemPathFromFileURL(ustrFileURL
, &temp
);
1040 if (osl_File_E_None
== osl_error
)
1043 || (UNICHAR_SLASH
== temp
->buffer
[0])
1044 || (UNICHAR_COLON
== temp
->buffer
[1] && UNICHAR_SLASH
== temp
->buffer
[2]))
1046 *pustrSystemPath
= temp
;
1050 rtl_uString_release(temp
);
1051 osl_error
= osl_File_E_INVAL
;
1059 namespace /* private */
1064 /******************************************************
1065 * Helper function, return a pinter to the final '\0'
1067 ******************************************************/
1069 sal_Unicode
* ustrtoend(sal_Unicode
* pStr
)
1071 return (pStr
+ rtl_ustr_getLength(pStr
));
1074 /*********************************************
1076 ********************************************/
1077 sal_Unicode
* ustrcpy(const sal_Unicode
* s
, sal_Unicode
* d
)
1079 const sal_Unicode
* sc
= s
;
1080 sal_Unicode
* dc
= d
;
1082 while ((*dc
++ = *sc
++))
1088 /*********************************************
1090 ********************************************/
1092 sal_Unicode
* ustrncpy(const sal_Unicode
* s
, sal_Unicode
* d
, unsigned int n
)
1094 const sal_Unicode
* sc
= s
;
1095 sal_Unicode
* dc
= d
;
1107 /*********************************************
1109 ********************************************/
1111 sal_Unicode
* ustrchrcat(const sal_Unicode chr
, sal_Unicode
* d
)
1113 sal_Unicode
* p
= ustrtoend(d
);
1119 /*********************************************
1121 ********************************************/
1123 sal_Unicode
* ustrcat(const sal_Unicode
* s
, sal_Unicode
* d
)
1125 sal_Unicode
* dc
= ustrtoend(d
);
1130 /******************************************************
1132 ******************************************************/
1134 bool _islastchr(sal_Unicode
* pStr
, sal_Unicode Chr
)
1136 sal_Unicode
* p
= ustrtoend(pStr
);
1142 /******************************************************
1143 * Ensure that the given string has the specified last
1144 * character if necessary append it
1145 ******************************************************/
1147 sal_Unicode
* _strensurelast(sal_Unicode
* pStr
, sal_Unicode Chr
)
1149 if (!_islastchr(pStr
, Chr
))
1150 ustrchrcat(Chr
, pStr
);
1154 /******************************************************
1155 * Remove the last part of a path, a path that has
1156 * only a '/' or no '/' at all will be returned
1158 ******************************************************/
1160 sal_Unicode
* _rmlastpathtoken(sal_Unicode
* aPath
)
1162 /* we always may skip -2 because we
1163 may at least stand on a '/' but
1164 either there is no other character
1165 before this '/' or it's another
1166 character than the '/'
1168 sal_Unicode
* p
= ustrtoend(aPath
) - 2;
1170 // move back to the next path separator
1171 // or to the start of the string
1172 while ((p
> aPath
) && (*p
!= UNICHAR_SLASH
))
1177 if (UNICHAR_SLASH
== *p
)
1191 /******************************************************
1193 ******************************************************/
1195 oslFileError
_osl_resolvepath(
1196 /*inout*/ sal_Unicode
* path
,
1197 /*inout*/ sal_Unicode
* current_pos
,
1198 /*in */ sal_Unicode
* sentinel
,
1199 /*inout*/ bool* failed
)
1201 oslFileError ferr
= osl_File_E_None
;
1205 char unresolved_path
[PATH_MAX
];
1206 if (!UnicodeToText(unresolved_path
, sizeof(unresolved_path
), path
, rtl_ustr_getLength(path
)))
1207 return oslTranslateFileError(OSL_FET_ERROR
, ENAMETOOLONG
);
1209 char resolved_path
[PATH_MAX
];
1210 if (realpath(unresolved_path
, resolved_path
))
1212 if (!TextToUnicode(resolved_path
, strlen(resolved_path
), path
, PATH_MAX
))
1213 return oslTranslateFileError(OSL_FET_ERROR
, ENAMETOOLONG
);
1215 current_pos
= ustrtoend(path
) - 1;
1219 if (EACCES
== errno
|| ENOTDIR
== errno
|| ENOENT
== errno
)
1222 ferr
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
1229 /******************************************************
1230 * Works even with non existing paths. The resulting
1231 * path must not exceed PATH_MAX else
1232 * osl_File_E_NAMETOOLONG is the result
1233 ******************************************************/
1235 oslFileError
osl_getAbsoluteFileURL_impl_(const rtl::OUString
& unresolved_path
, rtl::OUString
& resolved_path
)
1237 // the given unresolved path must not exceed PATH_MAX
1238 if (unresolved_path
.getLength() >= (PATH_MAX
- 2))
1239 return oslTranslateFileError(OSL_FET_ERROR
, ENAMETOOLONG
);
1241 sal_Unicode path_resolved_so_far
[PATH_MAX
];
1242 const sal_Unicode
* punresolved
= unresolved_path
.getStr();
1243 sal_Unicode
* presolvedsf
= path_resolved_so_far
;
1245 // reserve space for leading '/' and trailing '\0'
1246 // do not exceed this limit
1247 sal_Unicode
* sentinel
= path_resolved_so_far
+ PATH_MAX
- 2;
1249 // if realpath fails with error ENOTDIR, EACCES or ENOENT
1250 // we will not call it again, because _osl_realpath should also
1251 // work with non existing directories etc.
1252 bool realpath_failed
= false;
1255 path_resolved_so_far
[0] = '\0';
1257 while (*punresolved
!= '\0')
1259 // ignore '/.' , skip one part back when '/..'
1261 if ((UNICHAR_DOT
== *punresolved
) && (UNICHAR_SLASH
== *presolvedsf
))
1263 if ('\0' == *(punresolved
+ 1))
1268 else if (UNICHAR_SLASH
== *(punresolved
+ 1))
1273 else if ((UNICHAR_DOT
== *(punresolved
+ 1)) && ('\0' == *(punresolved
+ 2) || (UNICHAR_SLASH
== *(punresolved
+ 2))))
1275 _rmlastpathtoken(path_resolved_so_far
);
1277 presolvedsf
= ustrtoend(path_resolved_so_far
) - 1;
1279 if (UNICHAR_SLASH
== *(punresolved
+ 2))
1286 else // a file or directory name may start with '.'
1288 if ((presolvedsf
= ustrtoend(path_resolved_so_far
)) > sentinel
)
1289 return oslTranslateFileError(OSL_FET_ERROR
, ENAMETOOLONG
);
1291 ustrchrcat(*punresolved
++, path_resolved_so_far
);
1293 if ('\0' == *punresolved
&& !realpath_failed
)
1295 ferr
= _osl_resolvepath(
1296 path_resolved_so_far
,
1301 if (osl_File_E_None
!= ferr
)
1306 else if (UNICHAR_SLASH
== *punresolved
)
1308 if ((presolvedsf
= ustrtoend(path_resolved_so_far
)) > sentinel
)
1309 return oslTranslateFileError(OSL_FET_ERROR
, ENAMETOOLONG
);
1311 ustrchrcat(*punresolved
++, path_resolved_so_far
);
1313 if (!realpath_failed
)
1315 ferr
= _osl_resolvepath(
1316 path_resolved_so_far
,
1321 if (osl_File_E_None
!= ferr
)
1324 if (!_islastchr(path_resolved_so_far
, UNICHAR_SLASH
))
1326 if ((presolvedsf
= ustrtoend(path_resolved_so_far
)) > sentinel
)
1327 return oslTranslateFileError(OSL_FET_ERROR
, ENAMETOOLONG
);
1329 ustrchrcat(UNICHAR_SLASH
, path_resolved_so_far
);
1333 else // any other character
1335 if ((presolvedsf
= ustrtoend(path_resolved_so_far
)) > sentinel
)
1336 return oslTranslateFileError(OSL_FET_ERROR
, ENAMETOOLONG
);
1338 ustrchrcat(*punresolved
++, path_resolved_so_far
);
1340 if ('\0' == *punresolved
&& !realpath_failed
)
1342 ferr
= _osl_resolvepath(
1343 path_resolved_so_far
,
1348 if (osl_File_E_None
!= ferr
)
1354 sal_Int32 len
= rtl_ustr_getLength(path_resolved_so_far
);
1356 OSL_ASSERT(len
< PATH_MAX
);
1358 resolved_path
= rtl::OUString(path_resolved_so_far
, len
);
1360 return osl_File_E_None
;
1365 } // end namespace private
1367 #if OSL_DEBUG_LEVEL > 0
1369 //#####################################################
1370 void _osl_warnFile( const char *message
, rtl_uString
*ustrFile
)
1372 char szBuffer
[2048];
1376 rtl_String
*strFile
= NULL
;
1378 rtl_uString2String( &strFile
, rtl_uString_getStr( ustrFile
), rtl_uString_getLength( ustrFile
), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
);
1379 snprintf( szBuffer
, sizeof(szBuffer
), message
, strFile
->buffer
);
1380 rtl_string_release( strFile
);
1384 OSL_ENSURE( 0, message
);
1387 #endif // OSL_DEBUG_LEVEL > 0
1389 /******************************************************
1390 * osl_getAbsoluteFileURL
1391 ******************************************************/
1393 //oslFileError osl_getAbsoluteFileURL(rtl_uString* ustrBaseDirURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL)
1394 oslFileError SAL_CALL
osl_getAbsoluteFileURL( rtl_uString
* ustrBaseURL
, rtl_uString
* ustrRelativeURL
, rtl_uString
** pustrAbsoluteURL
)
1396 oslFileError eError
;
1397 rtl_uString
*ustrRelSysPath
= NULL
;
1398 rtl_uString
*ustrBaseSysPath
= NULL
;
1400 if ( ustrBaseURL
&& ustrBaseURL
->length
)
1402 eError
= _osl_getSystemPathFromFileURL( ustrBaseURL
, &ustrBaseSysPath
, sal_False
);
1403 OSL_ENSURE( osl_File_E_None
== eError
, "osl_getAbsoluteFileURL called with relative or invalid base URL" );
1405 eError
= _osl_getSystemPathFromFileURL( ustrRelativeURL
, &ustrRelSysPath
, sal_True
);
1409 eError
= _osl_getSystemPathFromFileURL( ustrRelativeURL
, &ustrRelSysPath
, sal_False
);
1410 OSL_ENSURE( osl_File_E_None
== eError
, "osl_getAbsoluteFileURL called with empty base URL and/or invalid relative URL" );
1415 CHAR szBuffer
[_MAX_PATH
];
1416 CHAR szRelSysPath
[_MAX_PATH
];
1417 CHAR szCurrentDir
[_MAX_PATH
];
1423 Bad, bad hack, this only works if the base path
1424 really exists which is not necessary according
1426 The whole FileURL implementation should be merged
1427 with the rtl/uri class.
1429 if ( ustrBaseSysPath
)
1431 CHAR szBaseSysPath
[_MAX_PATH
];
1433 if (!g_CurrentDirectoryMutex
)
1434 g_CurrentDirectoryMutex
= osl_createMutex();
1436 osl_acquireMutex( g_CurrentDirectoryMutex
);
1438 cwd
= getcwd( szCurrentDir
, sizeof(szCurrentDir
) );
1439 UnicodeToText( szBaseSysPath
, sizeof(szBaseSysPath
), ustrBaseSysPath
->buffer
, ustrBaseSysPath
->length
);
1440 rc
= chdir( szBaseSysPath
);
1443 UnicodeToText( szRelSysPath
, sizeof(szRelSysPath
), ustrRelSysPath
->buffer
, ustrRelSysPath
->length
);
1444 result
= !_abspath( szBuffer
, szRelSysPath
, sizeof(szBuffer
));
1446 if ( ustrBaseSysPath
)
1448 rc
= chdir( szCurrentDir
);
1450 osl_releaseMutex( g_CurrentDirectoryMutex
);
1455 rtl_uString
*ustrAbsSysPath
= NULL
;
1457 oslMakeUStrFromPsz( szBuffer
, &ustrAbsSysPath
);
1459 eError
= osl_getFileURLFromSystemPath( ustrAbsSysPath
, pustrAbsoluteURL
);
1461 if ( ustrAbsSysPath
)
1462 rtl_uString_release( ustrAbsSysPath
);
1465 eError
= osl_File_E_INVAL
;
1468 if ( ustrBaseSysPath
)
1469 rtl_uString_release( ustrBaseSysPath
);
1471 if ( ustrRelSysPath
)
1472 rtl_uString_release( ustrRelSysPath
);
1477 rtl::OUString unresolved_path
;
1479 rc
= FileBase::getSystemPathFromFileURL(rtl::OUString(ustrRelativeURL
), unresolved_path
);
1481 if(FileBase::E_None
!= rc
)
1482 return oslFileError(rc
);
1484 if (systemPathIsRelativePath(unresolved_path
))
1486 rtl::OUString base_path
;
1487 rc
= (FileBase::RC
) osl_getSystemPathFromFileURL_Ex(ustrBaseDirURL
, &base_path
.pData
, sal_False
);
1489 if (FileBase::E_None
!= rc
)
1490 return oslFileError(rc
);
1492 rtl::OUString abs_path
;
1493 systemPathMakeAbsolutePath(base_path
, unresolved_path
, abs_path
);
1495 unresolved_path
= abs_path
;
1498 rtl::OUString resolved_path
;
1499 rc
= (FileBase::RC
) osl_getAbsoluteFileURL_impl_(unresolved_path
, resolved_path
);
1501 if (FileBase::E_None
== rc
)
1503 rc
= (FileBase::RC
) osl_getFileURLFromSystemPath(resolved_path
.pData
, pustrAbsoluteURL
);
1504 OSL_ASSERT(FileBase::E_None
== rc
);
1507 return oslFileError(rc
);
1512 namespace /* private */
1515 /*********************************************
1516 No separate error code if unicode to text
1517 conversion or getenv fails because for the
1518 caller there is no difference why a file
1519 could not be found in $PATH
1520 ********************************************/
1522 bool find_in_PATH(const rtl::OUString
& file_path
, rtl::OUString
& result
)
1524 bool bfound
= false;
1525 rtl::OUString path
= rtl::OUString::createFromAscii("PATH");
1526 rtl::OUString env_path
;
1528 if (osl_Process_E_None
== osl_getEnvironment(path
.pData
, &env_path
.pData
))
1529 bfound
= osl::searchPath(file_path
, env_path
, result
);
1534 /*********************************************
1535 No separate error code if unicode to text
1536 conversion or getcwd fails because for the
1537 caller there is no difference why a file
1538 could not be found in CDW
1539 ********************************************/
1541 bool find_in_CWD(const rtl::OUString
& file_path
, rtl::OUString
& result
)
1543 bool bfound
= false;
1544 rtl::OUString cwd_url
;
1546 if (osl_Process_E_None
== osl_getProcessWorkingDir(&cwd_url
.pData
))
1549 FileBase::getSystemPathFromFileURL(cwd_url
, cwd
);
1550 bfound
= osl::searchPath(file_path
, cwd
, result
);
1555 /*********************************************
1557 ********************************************/
1559 bool find_in_searchPath(const rtl::OUString
& file_path
, rtl_uString
* search_path
, rtl::OUString
& result
)
1561 return (search_path
&& osl::searchPath(file_path
, rtl::OUString(search_path
), result
));
1564 } // end namespace private
1567 /****************************************************************************
1569 ***************************************************************************/
1571 oslFileError
osl_searchFileURL(rtl_uString
* ustrFilePath
, rtl_uString
* ustrSearchPath
, rtl_uString
** pustrURL
)
1573 OSL_PRECOND(ustrFilePath
&& pustrURL
, "osl_searchFileURL: invalid parameter");
1576 rtl::OUString file_path
;
1578 // try to interpret search path as file url else assume it's a system path list
1579 rc
= FileBase::getSystemPathFromFileURL(rtl::OUString(ustrFilePath
), file_path
);
1580 if ((FileBase::E_None
!= rc
) && (FileBase::E_INVAL
== rc
))
1581 file_path
= ustrFilePath
;
1582 else if (FileBase::E_None
!= rc
)
1583 return oslFileError(rc
);
1585 bool bfound
= false;
1586 rtl::OUString result
;
1588 if (find_in_searchPath(file_path
, ustrSearchPath
, result
) ||
1589 find_in_PATH(file_path
, result
) ||
1590 find_in_CWD(file_path
, result
))
1592 rtl::OUString resolved
;
1594 if (osl::realpath(result
, resolved
))
1596 #if OSL_DEBUG_LEVEL > 0
1597 oslFileError osl_error
=
1599 osl_getFileURLFromSystemPath(resolved
.pData
, pustrURL
);
1600 OSL_ASSERT(osl_File_E_None
== osl_error
);
1604 return bfound
? osl_File_E_None
: osl_File_E_NOENT
;
1608 /****************************************************************************
1610 ***************************************************************************/
1612 oslFileError
FileURLToPath(char * buffer
, size_t bufLen
, rtl_uString
* ustrFileURL
)
1614 rtl_uString
* ustrSystemPath
= NULL
;
1615 oslFileError osl_error
= osl_getSystemPathFromFileURL(ustrFileURL
, &ustrSystemPath
);
1617 if(osl_File_E_None
!= osl_error
)
1620 osl_systemPathRemoveSeparator(ustrSystemPath
);
1622 /* convert unicode path to text */
1623 if(!UnicodeToText( buffer
, bufLen
, ustrSystemPath
->buffer
, ustrSystemPath
->length
))
1624 osl_error
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
1626 rtl_uString_release(ustrSystemPath
);