xref: /aoo41x/main/sal/osl/w32/file_url.cxx (revision 87d2adbc)
1*87d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*87d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*87d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*87d2adbcSAndrew Rist  * distributed with this work for additional information
6*87d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*87d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*87d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
9*87d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*87d2adbcSAndrew Rist  *
11*87d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*87d2adbcSAndrew Rist  *
13*87d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*87d2adbcSAndrew Rist  * software distributed under the License is distributed on an
15*87d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*87d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*87d2adbcSAndrew Rist  * specific language governing permissions and limitations
18*87d2adbcSAndrew Rist  * under the License.
19*87d2adbcSAndrew Rist  *
20*87d2adbcSAndrew Rist  *************************************************************/
21*87d2adbcSAndrew Rist 
22*87d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #define UNICODE
25cdf0e10cSrcweir #define _UNICODE
26cdf0e10cSrcweir #define _WIN32_WINNT_0x0500
27cdf0e10cSrcweir #include "systools/win32/uwinapi.h"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "file_url.h"
30cdf0e10cSrcweir #include "file_error.h"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "rtl/alloc.h"
33cdf0e10cSrcweir #include "osl/diagnose.h"
34cdf0e10cSrcweir #include "osl/file.h"
35cdf0e10cSrcweir #include "osl/mutex.h"
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include "path_helper.hxx"
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #include <stdio.h>
40cdf0e10cSrcweir #include <tchar.h>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
43cdf0e10cSrcweir #define OSL_ENSURE_FILE( cond, msg, file ) ( (cond) ?  (void)0 : _osl_warnFile( msg, file ) )
44cdf0e10cSrcweir #else
45cdf0e10cSrcweir #define OSL_ENSURE_FILE( cond, msg, file ) ((void)0)
46cdf0e10cSrcweir #endif
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #define WSTR_SYSTEM_ROOT_PATH				L"\\\\.\\"
51cdf0e10cSrcweir #define WSTR_LONG_PATH_PREFIX				L"\\\\?\\"
52cdf0e10cSrcweir #define WSTR_LONG_PATH_PREFIX_UNC			L"\\\\?\\UNC\\"
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 
55cdf0e10cSrcweir //##################################################################
56cdf0e10cSrcweir // FileURL functions
57cdf0e10cSrcweir //##################################################################
58cdf0e10cSrcweir 
59cdf0e10cSrcweir extern "C" oslMutex g_CurrentDirectoryMutex; /* Initialized in dllentry.c */
60cdf0e10cSrcweir oslMutex g_CurrentDirectoryMutex = 0;
61cdf0e10cSrcweir 
62cdf0e10cSrcweir //#####################################################
IsValidFilePathComponent(LPCTSTR lpComponent,LPCTSTR * lppComponentEnd,DWORD dwFlags)63cdf0e10cSrcweir static BOOL IsValidFilePathComponent(
64cdf0e10cSrcweir     LPCTSTR lpComponent, LPCTSTR *lppComponentEnd, DWORD dwFlags)
65cdf0e10cSrcweir {
66cdf0e10cSrcweir 	    LPCTSTR	lpComponentEnd = NULL;
67cdf0e10cSrcweir 	    LPCTSTR	lpCurrent = lpComponent;
68cdf0e10cSrcweir 	    BOOL	fValid = TRUE;	/* Assume success */
69cdf0e10cSrcweir 	    TCHAR	cLast = 0;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 	    /* Path component length must not exceed MAX_PATH even if long path with "\\?\" prefix is used */
72cdf0e10cSrcweir 
73cdf0e10cSrcweir 	    while ( !lpComponentEnd && lpCurrent && lpCurrent - lpComponent < MAX_PATH )
74cdf0e10cSrcweir 	    {
75cdf0e10cSrcweir 		    switch ( *lpCurrent )
76cdf0e10cSrcweir 		    {
77cdf0e10cSrcweir 			    /* Both backslash and slash determine the end of a path component */
78cdf0e10cSrcweir 		    case '\0':
79cdf0e10cSrcweir 		    case '/':
80cdf0e10cSrcweir 		    case '\\':
81cdf0e10cSrcweir 			    switch ( cLast )
82cdf0e10cSrcweir 			    {
83cdf0e10cSrcweir 				    /* Component must not end with '.' or blank and can't be empty */
84cdf0e10cSrcweir 
85cdf0e10cSrcweir 			    case '.':
86cdf0e10cSrcweir 				    if ( dwFlags & VALIDATEPATH_ALLOW_ELLIPSE )
87cdf0e10cSrcweir 				    {
88cdf0e10cSrcweir 					    if ( 1 == lpCurrent - lpComponent )
89cdf0e10cSrcweir 					    {
90cdf0e10cSrcweir 						    /* Current directory is O.K. */
91cdf0e10cSrcweir 						    lpComponentEnd = lpCurrent;
92cdf0e10cSrcweir 						    break;
93cdf0e10cSrcweir 					    }
94cdf0e10cSrcweir 					    else if ( 2 == lpCurrent - lpComponent && '.' == *lpComponent )
95cdf0e10cSrcweir 					    {
96cdf0e10cSrcweir 						    /* Parent directory is O.K. */
97cdf0e10cSrcweir 						    lpComponentEnd = lpCurrent;
98cdf0e10cSrcweir 						    break;
99cdf0e10cSrcweir 					    }
100cdf0e10cSrcweir 				    }
101cdf0e10cSrcweir 			    case 0:
102cdf0e10cSrcweir 			    case ' ':
103cdf0e10cSrcweir 				    lpComponentEnd = lpCurrent - 1;
104cdf0e10cSrcweir 				    fValid = FALSE;
105cdf0e10cSrcweir 				    break;
106cdf0e10cSrcweir 			    default:
107cdf0e10cSrcweir 				    lpComponentEnd = lpCurrent;
108cdf0e10cSrcweir 				    break;
109cdf0e10cSrcweir 			    }
110cdf0e10cSrcweir 			    break;
111cdf0e10cSrcweir 			    /* '?' and '*' are valid wildcards but not valid file name characters */
112cdf0e10cSrcweir 		    case '?':
113cdf0e10cSrcweir 		    case '*':
114cdf0e10cSrcweir 			    if ( dwFlags & VALIDATEPATH_ALLOW_WILDCARDS )
115cdf0e10cSrcweir 				    break;
116cdf0e10cSrcweir 			    /* The following characters are reserved */
117cdf0e10cSrcweir 		    case '<':
118cdf0e10cSrcweir 		    case '>':
119cdf0e10cSrcweir 		    case '\"':
120cdf0e10cSrcweir 		    case '|':
121cdf0e10cSrcweir 		    case ':':
122cdf0e10cSrcweir 			    lpComponentEnd = lpCurrent;
123cdf0e10cSrcweir 			    fValid = FALSE;
124cdf0e10cSrcweir 			    break;
125cdf0e10cSrcweir 		    default:
126cdf0e10cSrcweir 			    /* Characters below ASCII 32 are not allowed */
127cdf0e10cSrcweir 			    if ( *lpCurrent < ' ' )
128cdf0e10cSrcweir 			    {
129cdf0e10cSrcweir 				    lpComponentEnd = lpCurrent;
130cdf0e10cSrcweir 				    fValid = FALSE;
131cdf0e10cSrcweir 			    }
132cdf0e10cSrcweir 			    break;
133cdf0e10cSrcweir 		    }
134cdf0e10cSrcweir 		    cLast = *lpCurrent++;
135cdf0e10cSrcweir 	    }
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 	    /*	If we don't reached the end of the component the length of the component was to long
138cdf0e10cSrcweir 		    ( See condition of while loop ) */
139cdf0e10cSrcweir 	    if ( !lpComponentEnd )
140cdf0e10cSrcweir 	    {
141cdf0e10cSrcweir 		    fValid = FALSE;
142cdf0e10cSrcweir 		    lpComponentEnd = lpCurrent;
143cdf0e10cSrcweir 	    }
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 		/* Test wether the component specifies a device name what is not allowed */
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 		// MT: PERFORMANCE:
148cdf0e10cSrcweir 		// This is very expensive. A lot of calls to _tcsicmp.
149cdf0e10cSrcweir 		// in SRC6870m71 67.000 calls of this method while empty office start result into more than 1.500.00 calls of _tcsicmp!
150cdf0e10cSrcweir 		// Possible optimizations
151cdf0e10cSrcweir 		// - Array should be const static
152cdf0e10cSrcweir 		// - Sorted array, use binary search
153cdf0e10cSrcweir 		// - More intelligent check for com1-9, lpt1-9
154cdf0e10cSrcweir 		// Maybe make szComponent upper case, don't search case intensitive
155cdf0e10cSrcweir 		// 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.
156cdf0e10cSrcweir 		/*
157cdf0e10cSrcweir 	    if ( fValid )
158cdf0e10cSrcweir 	    {
159cdf0e10cSrcweir 		    LPCTSTR	alpDeviceNames[] =
160cdf0e10cSrcweir 		    {
161cdf0e10cSrcweir 			    TEXT("CON"),
162cdf0e10cSrcweir 			    TEXT("PRN"),
163cdf0e10cSrcweir 			    TEXT("AUX"),
164cdf0e10cSrcweir 			    TEXT("CLOCK$"),
165cdf0e10cSrcweir 			    TEXT("NUL"),
166cdf0e10cSrcweir 			    TEXT("LPT1"),
167cdf0e10cSrcweir 			    TEXT("LPT2"),
168cdf0e10cSrcweir 			    TEXT("LPT3"),
169cdf0e10cSrcweir 			    TEXT("LPT4"),
170cdf0e10cSrcweir 			    TEXT("LPT5"),
171cdf0e10cSrcweir 			    TEXT("LPT6"),
172cdf0e10cSrcweir 			    TEXT("LPT7"),
173cdf0e10cSrcweir 			    TEXT("LPT8"),
174cdf0e10cSrcweir 			    TEXT("LPT9"),
175cdf0e10cSrcweir 			    TEXT("COM1"),
176cdf0e10cSrcweir 			    TEXT("COM2"),
177cdf0e10cSrcweir 			    TEXT("COM3"),
178cdf0e10cSrcweir 			    TEXT("COM4"),
179cdf0e10cSrcweir 			    TEXT("COM5"),
180cdf0e10cSrcweir 			    TEXT("COM6"),
181cdf0e10cSrcweir 			    TEXT("COM7"),
182cdf0e10cSrcweir 			    TEXT("COM8"),
183cdf0e10cSrcweir 			    TEXT("COM9")
184cdf0e10cSrcweir 		    };
185cdf0e10cSrcweir 
186cdf0e10cSrcweir 		    TCHAR	szComponent[MAX_PATH];
187cdf0e10cSrcweir 		    int		nComponentLength;
188cdf0e10cSrcweir 		    LPCTSTR	lpDot;
189cdf0e10cSrcweir 		    int		i;
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 		    // A device name with an extension is also invalid
192cdf0e10cSrcweir 		    lpDot = _tcschr( lpComponent, '.' );
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 		    if ( !lpDot || lpDot > lpComponentEnd )
195cdf0e10cSrcweir 			    nComponentLength = lpComponentEnd - lpComponent;
196cdf0e10cSrcweir 		    else
197cdf0e10cSrcweir 			    nComponentLength = lpDot - lpComponent;
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 		    _tcsncpy( szComponent, lpComponent, nComponentLength );
200cdf0e10cSrcweir 		    szComponent[nComponentLength] = 0;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 		    for ( i = 0; i < sizeof( alpDeviceNames ) / sizeof(LPCTSTR); i++ )
203cdf0e10cSrcweir 		    {
204cdf0e10cSrcweir 			    if ( 0 == _tcsicmp( szComponent, alpDeviceNames[i] ) )
205cdf0e10cSrcweir 			    {
206cdf0e10cSrcweir 				    lpComponentEnd = lpComponent;
207cdf0e10cSrcweir 				    fValid = FALSE;
208cdf0e10cSrcweir 				    break;
209cdf0e10cSrcweir 			    }
210cdf0e10cSrcweir 		    }
211cdf0e10cSrcweir 	    }
212cdf0e10cSrcweir 	    */
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 		if ( fValid )
215cdf0e10cSrcweir 		{
216cdf0e10cSrcweir 			// Empty components are not allowed
217cdf0e10cSrcweir 			if ( lpComponentEnd - lpComponent < 1 )
218cdf0e10cSrcweir 				fValid = FALSE;
219cdf0e10cSrcweir 
220cdf0e10cSrcweir 			// If we reached the end of the string NULL is returned
221cdf0e10cSrcweir 			else if ( !*lpComponentEnd )
222cdf0e10cSrcweir 				lpComponentEnd = NULL;
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 		}
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 	    if ( lppComponentEnd )
227cdf0e10cSrcweir 		    *lppComponentEnd = lpComponentEnd;
228cdf0e10cSrcweir 
229cdf0e10cSrcweir 	    return fValid;
230cdf0e10cSrcweir }
231cdf0e10cSrcweir 
232cdf0e10cSrcweir //#####################################################
233cdf0e10cSrcweir #define	CHARSET_SEPARATOR TEXT("\\/")
234cdf0e10cSrcweir 
IsValidFilePath(rtl_uString * path,LPCTSTR * lppError,DWORD dwFlags,rtl_uString ** corrected)235cdf0e10cSrcweir DWORD IsValidFilePath(rtl_uString *path, LPCTSTR *lppError, DWORD dwFlags, rtl_uString **corrected)
236cdf0e10cSrcweir {
237cdf0e10cSrcweir         LPCTSTR lpszPath = reinterpret_cast< LPCTSTR >(path->buffer);
238cdf0e10cSrcweir 	    LPCTSTR	lpComponent = lpszPath;
239cdf0e10cSrcweir 	    BOOL	fValid = TRUE;
240cdf0e10cSrcweir 	    DWORD	dwPathType = PATHTYPE_ERROR;
241cdf0e10cSrcweir         sal_Int32 nLength = rtl_uString_getLength( path );
242cdf0e10cSrcweir 
243cdf0e10cSrcweir 	    if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE )
244cdf0e10cSrcweir 		    dwFlags |= VALIDATEPATH_ALLOW_ELLIPSE;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 	    if ( !lpszPath )
247cdf0e10cSrcweir 		    fValid = FALSE;
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 	    DWORD	dwCandidatPathType = PATHTYPE_ERROR;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir         if ( 0 == rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( path->buffer, nLength, reinterpret_cast<const sal_Unicode *>(WSTR_LONG_PATH_PREFIX_UNC), ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX_UNC) - 1, ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX_UNC) - 1 ) )
252cdf0e10cSrcweir         {
253cdf0e10cSrcweir             /* This is long path in UNC notation */
254cdf0e10cSrcweir             lpComponent = lpszPath + ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX_UNC) - 1;
255cdf0e10cSrcweir             dwCandidatPathType = PATHTYPE_ABSOLUTE_UNC | PATHTYPE_IS_LONGPATH;
256cdf0e10cSrcweir         }
257cdf0e10cSrcweir         else if ( 0 == rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( path->buffer, nLength, reinterpret_cast<const sal_Unicode *>(WSTR_LONG_PATH_PREFIX), ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1, ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1 ) )
258cdf0e10cSrcweir         {
259cdf0e10cSrcweir             /* This is long path */
260cdf0e10cSrcweir             lpComponent = lpszPath + ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1;
261cdf0e10cSrcweir 
262cdf0e10cSrcweir             if ( _istalpha( lpComponent[0] ) && ':' == lpComponent[1] )
263cdf0e10cSrcweir             {
264cdf0e10cSrcweir                 lpComponent += 2;
265cdf0e10cSrcweir                 dwCandidatPathType = PATHTYPE_ABSOLUTE_LOCAL | PATHTYPE_IS_LONGPATH;
266cdf0e10cSrcweir             }
267cdf0e10cSrcweir         }
268cdf0e10cSrcweir 	    else if ( 2 == _tcsspn( lpszPath, CHARSET_SEPARATOR ) )
269cdf0e10cSrcweir         {
270cdf0e10cSrcweir             /* The UNC path notation */
271cdf0e10cSrcweir             lpComponent = lpszPath + 2;
272cdf0e10cSrcweir             dwCandidatPathType = PATHTYPE_ABSOLUTE_UNC;
273cdf0e10cSrcweir         }
274cdf0e10cSrcweir 	    else if ( _istalpha( lpszPath[0] ) && ':' == lpszPath[1] )
275cdf0e10cSrcweir         {
276cdf0e10cSrcweir             /* Local path verification. Must start with <drive>: */
277cdf0e10cSrcweir 		    lpComponent = lpszPath + 2;
278cdf0e10cSrcweir             dwCandidatPathType = PATHTYPE_ABSOLUTE_LOCAL;
279cdf0e10cSrcweir         }
280cdf0e10cSrcweir 
281cdf0e10cSrcweir 	    if ( ( dwCandidatPathType & PATHTYPE_MASK_TYPE ) == PATHTYPE_ABSOLUTE_UNC )
282cdf0e10cSrcweir 	    {
283cdf0e10cSrcweir 		    fValid = IsValidFilePathComponent( lpComponent, &lpComponent, VALIDATEPATH_ALLOW_ELLIPSE );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 		    /* So far we have a valid servername. Now let's see if we also have a network resource */
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 		    dwPathType = dwCandidatPathType;
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 		    if ( fValid )
290cdf0e10cSrcweir 		    {
291cdf0e10cSrcweir 			    if ( lpComponent &&	 !*++lpComponent )
292cdf0e10cSrcweir 				    lpComponent = NULL;
293cdf0e10cSrcweir 
294cdf0e10cSrcweir 			    if ( !lpComponent )
295cdf0e10cSrcweir 			    {
296cdf0e10cSrcweir     #if 0
297cdf0e10cSrcweir 				    /* We only have a Server specification what is invalid */
298cdf0e10cSrcweir 
299cdf0e10cSrcweir 				    lpComponent = lpszPath;
300cdf0e10cSrcweir 				    fValid = FALSE;
301cdf0e10cSrcweir     #else
302cdf0e10cSrcweir 				    dwPathType |= PATHTYPE_IS_SERVER;
303cdf0e10cSrcweir     #endif
304cdf0e10cSrcweir 			    }
305cdf0e10cSrcweir 			    else
306cdf0e10cSrcweir 			    {
307cdf0e10cSrcweir 				    /* Now test the network resource */
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 				    fValid = IsValidFilePathComponent( lpComponent, &lpComponent, 0 );
310cdf0e10cSrcweir 
311cdf0e10cSrcweir 				    /* If we now reached the end of the path, everything is O.K. */
312cdf0e10cSrcweir 
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 				    if ( fValid && (!lpComponent || lpComponent && !*++lpComponent ) )
315cdf0e10cSrcweir 				    {
316cdf0e10cSrcweir 					    lpComponent = NULL;
317cdf0e10cSrcweir 					    dwPathType |= PATHTYPE_IS_VOLUME;
318cdf0e10cSrcweir 				    }
319cdf0e10cSrcweir 			    }
320cdf0e10cSrcweir 		    }
321cdf0e10cSrcweir 	    }
322cdf0e10cSrcweir 	    else if (  ( dwCandidatPathType & PATHTYPE_MASK_TYPE ) == PATHTYPE_ABSOLUTE_LOCAL )
323cdf0e10cSrcweir 	    {
324cdf0e10cSrcweir 		    if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) )
325cdf0e10cSrcweir 			    lpComponent++;
326cdf0e10cSrcweir 		    else if ( *lpComponent )
327cdf0e10cSrcweir 			    fValid = FALSE;
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 		    dwPathType = dwCandidatPathType;
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 		    /* Now we are behind the backslash or it was a simple drive without backslash */
332cdf0e10cSrcweir 
333cdf0e10cSrcweir 		    if ( fValid && !*lpComponent )
334cdf0e10cSrcweir 		    {
335cdf0e10cSrcweir 			    lpComponent = NULL;
336cdf0e10cSrcweir 			    dwPathType |= PATHTYPE_IS_VOLUME;
337cdf0e10cSrcweir 		    }
338cdf0e10cSrcweir 	    }
339cdf0e10cSrcweir 	    else if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE )
340cdf0e10cSrcweir 	    {
341cdf0e10cSrcweir             /* Can be a relative path */
342cdf0e10cSrcweir 		    lpComponent = lpszPath;
343cdf0e10cSrcweir 
344cdf0e10cSrcweir 		    /* Relative path can start with a backslash */
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 		    if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) )
347cdf0e10cSrcweir 		    {
348cdf0e10cSrcweir 			    lpComponent++;
349cdf0e10cSrcweir 			    if ( !*lpComponent )
350cdf0e10cSrcweir 				    lpComponent = NULL;
351cdf0e10cSrcweir 		    }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 		    dwPathType = PATHTYPE_RELATIVE;
354cdf0e10cSrcweir 	    }
355cdf0e10cSrcweir 	    else
356cdf0e10cSrcweir 	    {
357cdf0e10cSrcweir             /* Anything else is an error */
358cdf0e10cSrcweir 		    fValid = FALSE;
359cdf0e10cSrcweir 		    lpComponent = lpszPath;
360cdf0e10cSrcweir 	    }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 	    /* Now validate each component of the path */
363cdf0e10cSrcweir 	    while ( fValid && lpComponent )
364cdf0e10cSrcweir 	    {
365cdf0e10cSrcweir             // Correct path by merging consecutive slashes:
366cdf0e10cSrcweir             if (*lpComponent == '\\' && corrected != NULL) {
367cdf0e10cSrcweir                 sal_Int32 i = lpComponent - lpszPath;
368cdf0e10cSrcweir                 rtl_uString_newReplaceStrAt(corrected, path, i, 1, NULL);
369cdf0e10cSrcweir                     //TODO: handle out-of-memory
370cdf0e10cSrcweir                 lpszPath = reinterpret_cast< LPCTSTR >((*corrected)->buffer);
371cdf0e10cSrcweir                 lpComponent = lpszPath + i;
372cdf0e10cSrcweir             }
373cdf0e10cSrcweir 
374cdf0e10cSrcweir 		    fValid = IsValidFilePathComponent( lpComponent, &lpComponent, dwFlags );
375cdf0e10cSrcweir 
376cdf0e10cSrcweir 		    if ( fValid && lpComponent )
377cdf0e10cSrcweir 		    {
378cdf0e10cSrcweir 			    lpComponent++;
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 			    /* If the string behind the backslash is empty, we've done */
381cdf0e10cSrcweir 
382cdf0e10cSrcweir 			    if ( !*lpComponent )
383cdf0e10cSrcweir 				    lpComponent = NULL;
384cdf0e10cSrcweir 		    }
385cdf0e10cSrcweir 	    }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir         /* The path can be longer than MAX_PATH only in case it has the longpath prefix */
388cdf0e10cSrcweir 	    if ( fValid && !( dwPathType &  PATHTYPE_IS_LONGPATH ) && _tcslen( lpszPath ) >= MAX_PATH )
389cdf0e10cSrcweir 	    {
390cdf0e10cSrcweir 		    fValid = FALSE;
391cdf0e10cSrcweir 		    lpComponent = lpszPath + MAX_PATH;
392cdf0e10cSrcweir 	    }
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 	    if ( lppError )
395cdf0e10cSrcweir 		    *lppError = lpComponent;
396cdf0e10cSrcweir 
397cdf0e10cSrcweir 	    return fValid ? dwPathType : PATHTYPE_ERROR;
398cdf0e10cSrcweir }
399cdf0e10cSrcweir 
400cdf0e10cSrcweir //#####################################################
PathRemoveFileSpec(LPTSTR lpPath,LPTSTR lpFileName,sal_Int32 nFileBufLen)401cdf0e10cSrcweir static sal_Int32 PathRemoveFileSpec(LPTSTR lpPath, LPTSTR lpFileName, sal_Int32 nFileBufLen )
402cdf0e10cSrcweir {
403cdf0e10cSrcweir     sal_Int32 nRemoved = 0;
404cdf0e10cSrcweir 
405cdf0e10cSrcweir     if ( nFileBufLen )
406cdf0e10cSrcweir     {
407cdf0e10cSrcweir         lpFileName[0] = 0;
408cdf0e10cSrcweir         LPTSTR	lpLastBkSlash = _tcsrchr( lpPath, '\\' );
409cdf0e10cSrcweir         LPTSTR	lpLastSlash = _tcsrchr( lpPath, '/' );
410cdf0e10cSrcweir         LPTSTR	lpLastDelimiter = lpLastSlash > lpLastBkSlash ? lpLastSlash : lpLastBkSlash;
411cdf0e10cSrcweir 
412cdf0e10cSrcweir         if ( lpLastDelimiter )
413cdf0e10cSrcweir         {
414cdf0e10cSrcweir                 sal_Int32 nDelLen = _tcslen( lpLastDelimiter );
415cdf0e10cSrcweir                 if ( 1 == nDelLen )
416cdf0e10cSrcweir                 {
417cdf0e10cSrcweir                     if ( lpLastDelimiter > lpPath && *(lpLastDelimiter - 1) != ':' )
418cdf0e10cSrcweir                     {
419cdf0e10cSrcweir                         *lpLastDelimiter = 0;
420cdf0e10cSrcweir                         *lpFileName = 0;
421cdf0e10cSrcweir                         nRemoved = nDelLen;
422cdf0e10cSrcweir                     }
423cdf0e10cSrcweir                 }
424cdf0e10cSrcweir                 else if ( nDelLen && nDelLen - 1 < nFileBufLen )
425cdf0e10cSrcweir                 {
426cdf0e10cSrcweir                     _tcscpy( lpFileName, lpLastDelimiter + 1 );
427cdf0e10cSrcweir                     *(++lpLastDelimiter) = 0;
428cdf0e10cSrcweir                     nRemoved = nDelLen - 1;
429cdf0e10cSrcweir                 }
430cdf0e10cSrcweir         }
431cdf0e10cSrcweir     }
432cdf0e10cSrcweir 
433cdf0e10cSrcweir     return nRemoved;
434cdf0e10cSrcweir }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir //#####################################################
437cdf0e10cSrcweir // Undocumented in SHELL32.DLL ordinal 32
PathAddBackslash(LPTSTR lpPath,sal_Int32 nBufLen)438cdf0e10cSrcweir static LPTSTR PathAddBackslash(LPTSTR lpPath, sal_Int32 nBufLen)
439cdf0e10cSrcweir {
440cdf0e10cSrcweir     LPTSTR	lpEndPath = NULL;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir     if ( lpPath )
443cdf0e10cSrcweir     {
444cdf0e10cSrcweir 		    int		nLen = _tcslen(lpPath);
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 		    if ( !nLen || lpPath[nLen-1] != '\\' && lpPath[nLen-1] != '/' && nLen < nBufLen - 1 )
447cdf0e10cSrcweir 		    {
448cdf0e10cSrcweir 			    lpEndPath = lpPath + nLen;
449cdf0e10cSrcweir 			    *lpEndPath++ = '\\';
450cdf0e10cSrcweir 			    *lpEndPath = 0;
451cdf0e10cSrcweir 		    }
452cdf0e10cSrcweir     }
453cdf0e10cSrcweir     return lpEndPath;
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir //#####################################################
457cdf0e10cSrcweir // Same as GetLongPathName but also 95/NT4
GetCaseCorrectPathNameEx(LPTSTR lpszPath,DWORD cchBuffer,DWORD nSkipLevels,BOOL bCheckExistence)458cdf0e10cSrcweir static DWORD GetCaseCorrectPathNameEx(
459cdf0e10cSrcweir     LPTSTR	lpszPath,	// path buffer to convert
460cdf0e10cSrcweir     DWORD	cchBuffer,		// size of path buffer
461cdf0e10cSrcweir     DWORD	nSkipLevels,
462cdf0e10cSrcweir     BOOL bCheckExistence )
463cdf0e10cSrcweir {
464cdf0e10cSrcweir         ::osl::LongPathBuffer< WCHAR > szFile( MAX_PATH + 1 );
465cdf0e10cSrcweir 	    sal_Int32 nRemoved = PathRemoveFileSpec( lpszPath, szFile, MAX_PATH + 1 );
466cdf0e10cSrcweir         sal_Int32 nLastStepRemoved = nRemoved;
467cdf0e10cSrcweir         while ( nLastStepRemoved && szFile[0] == 0 )
468cdf0e10cSrcweir         {
469cdf0e10cSrcweir             // remove separators
470cdf0e10cSrcweir 	        nLastStepRemoved = PathRemoveFileSpec( lpszPath, szFile, MAX_PATH + 1 );
471cdf0e10cSrcweir             nRemoved += nLastStepRemoved;
472cdf0e10cSrcweir         }
473cdf0e10cSrcweir 
474cdf0e10cSrcweir 	    if ( nRemoved )
475cdf0e10cSrcweir 	    {
476cdf0e10cSrcweir             BOOL bSkipThis = FALSE;
477cdf0e10cSrcweir 
478cdf0e10cSrcweir 		    if ( 0 == _tcscmp( szFile, TEXT("..") ) )
479cdf0e10cSrcweir 		    {
480cdf0e10cSrcweir 			    bSkipThis = TRUE;
481cdf0e10cSrcweir 			    nSkipLevels += 1;
482cdf0e10cSrcweir 		    }
483cdf0e10cSrcweir             else if ( 0 == _tcscmp( szFile, TEXT(".") ) )
484cdf0e10cSrcweir             {
485cdf0e10cSrcweir 			    bSkipThis = TRUE;
486cdf0e10cSrcweir             }
487cdf0e10cSrcweir 		    else if ( nSkipLevels )
488cdf0e10cSrcweir 		    {
489cdf0e10cSrcweir 			    bSkipThis = TRUE;
490cdf0e10cSrcweir 			    nSkipLevels--;
491cdf0e10cSrcweir 		    }
492cdf0e10cSrcweir 		    else
493cdf0e10cSrcweir 			    bSkipThis = FALSE;
494cdf0e10cSrcweir 
495cdf0e10cSrcweir 		    GetCaseCorrectPathNameEx( lpszPath, cchBuffer, nSkipLevels, bCheckExistence );
496cdf0e10cSrcweir 
497cdf0e10cSrcweir 		    PathAddBackslash( lpszPath, cchBuffer );
498cdf0e10cSrcweir 
499cdf0e10cSrcweir 		    /* Analyze parent if not only a trailing backslash was cutted but a real file spec */
500cdf0e10cSrcweir 		    if ( !bSkipThis )
501cdf0e10cSrcweir 		    {
502cdf0e10cSrcweir                 if ( bCheckExistence )
503cdf0e10cSrcweir                 {
504cdf0e10cSrcweir                     ::osl::LongPathBuffer< WCHAR > aShortPath( MAX_LONG_PATH );
505cdf0e10cSrcweir                     _tcscpy( aShortPath, lpszPath );
506cdf0e10cSrcweir                     _tcscat( aShortPath, szFile );
507cdf0e10cSrcweir 
508cdf0e10cSrcweir                     WIN32_FIND_DATA	aFindFileData;
509cdf0e10cSrcweir                     HANDLE	hFind = FindFirstFile( aShortPath, &aFindFileData );
510cdf0e10cSrcweir 
511cdf0e10cSrcweir                     if ( IsValidHandle(hFind) )
512cdf0e10cSrcweir                     {
513cdf0e10cSrcweir                         _tcscat( lpszPath, aFindFileData.cFileName[0] ? aFindFileData.cFileName : aFindFileData.cAlternateFileName );
514cdf0e10cSrcweir 
515cdf0e10cSrcweir                         FindClose( hFind );
516cdf0e10cSrcweir                     }
517cdf0e10cSrcweir                     else
518cdf0e10cSrcweir                         lpszPath[0] = 0;
519cdf0e10cSrcweir                 }
520cdf0e10cSrcweir                 else
521cdf0e10cSrcweir                 {
522cdf0e10cSrcweir                     /* add the segment name back */
523cdf0e10cSrcweir                     _tcscat( lpszPath, szFile );
524cdf0e10cSrcweir                 }
525cdf0e10cSrcweir 		    }
526cdf0e10cSrcweir 	    }
527cdf0e10cSrcweir 	    else
528cdf0e10cSrcweir 	    {
529cdf0e10cSrcweir 		    /* File specification can't be removed therefore the short path is either a drive
530cdf0e10cSrcweir 			   or a network share. If still levels to skip are left, the path specification
531cdf0e10cSrcweir 			   tries to travel below the file system root */
532cdf0e10cSrcweir 		    if ( nSkipLevels )
533cdf0e10cSrcweir                     lpszPath[0] = 0;
534cdf0e10cSrcweir             else
535cdf0e10cSrcweir                 _tcsupr( lpszPath );
536cdf0e10cSrcweir 	    }
537cdf0e10cSrcweir 
538cdf0e10cSrcweir 	    return _tcslen( lpszPath );
539cdf0e10cSrcweir }
540cdf0e10cSrcweir 
541cdf0e10cSrcweir //#####################################################
542cdf0e10cSrcweir #define WSTR_SYSTEM_ROOT_PATH				L"\\\\.\\"
543cdf0e10cSrcweir 
GetCaseCorrectPathName(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD cchBuffer,BOOL bCheckExistence)544cdf0e10cSrcweir DWORD GetCaseCorrectPathName(
545cdf0e10cSrcweir     LPCTSTR	lpszShortPath,	// file name
546cdf0e10cSrcweir     LPTSTR	lpszLongPath,	// path buffer
547cdf0e10cSrcweir     DWORD	cchBuffer,		// size of path buffer
548cdf0e10cSrcweir     BOOL bCheckExistence
549cdf0e10cSrcweir )
550cdf0e10cSrcweir {
551cdf0e10cSrcweir     /* Special handling for "\\.\" as system root */
552cdf0e10cSrcweir     if ( lpszShortPath && 0 == wcscmp( lpszShortPath, WSTR_SYSTEM_ROOT_PATH ) )
553cdf0e10cSrcweir     {
554cdf0e10cSrcweir         if ( cchBuffer >= ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) )
555cdf0e10cSrcweir         {
556cdf0e10cSrcweir             wcscpy( lpszLongPath, WSTR_SYSTEM_ROOT_PATH );
557cdf0e10cSrcweir             return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1;
558cdf0e10cSrcweir         }
559cdf0e10cSrcweir         else
560cdf0e10cSrcweir         {
561cdf0e10cSrcweir             return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1;
562cdf0e10cSrcweir         }
563cdf0e10cSrcweir     }
564cdf0e10cSrcweir     else if ( lpszShortPath )
565cdf0e10cSrcweir     {
566cdf0e10cSrcweir         if ( _tcslen( lpszShortPath ) <= cchBuffer )
567cdf0e10cSrcweir         {
568cdf0e10cSrcweir             _tcscpy( lpszLongPath, lpszShortPath );
569cdf0e10cSrcweir             return GetCaseCorrectPathNameEx( lpszLongPath, cchBuffer, 0, bCheckExistence );
570cdf0e10cSrcweir         }
571cdf0e10cSrcweir     }
572cdf0e10cSrcweir 
573cdf0e10cSrcweir     return 0;
574cdf0e10cSrcweir }
575cdf0e10cSrcweir 
576cdf0e10cSrcweir 
577cdf0e10cSrcweir //#############################################
_osl_decodeURL(rtl_String * strUTF8,rtl_uString ** pstrDecodedURL)578cdf0e10cSrcweir static sal_Bool _osl_decodeURL( rtl_String* strUTF8, rtl_uString** pstrDecodedURL )
579cdf0e10cSrcweir {
580cdf0e10cSrcweir     sal_Char		*pBuffer;
581cdf0e10cSrcweir     const sal_Char	*pSrcEnd;
582cdf0e10cSrcweir     const sal_Char	*pSrc;
583cdf0e10cSrcweir     sal_Char		*pDest;
584cdf0e10cSrcweir     sal_Int32		nSrcLen;
585cdf0e10cSrcweir     sal_Bool		bValidEncoded = sal_True;	/* Assume success */
586cdf0e10cSrcweir 
587cdf0e10cSrcweir     /* The resulting decoded string length is shorter or equal to the source length */
588cdf0e10cSrcweir 
589cdf0e10cSrcweir     nSrcLen = rtl_string_getLength(strUTF8);
590cdf0e10cSrcweir     pBuffer = reinterpret_cast<sal_Char*>(rtl_allocateMemory(nSrcLen + 1));
591cdf0e10cSrcweir 
592cdf0e10cSrcweir     pDest = pBuffer;
593cdf0e10cSrcweir     pSrc = rtl_string_getStr(strUTF8);
594cdf0e10cSrcweir     pSrcEnd = pSrc + nSrcLen;
595cdf0e10cSrcweir 
596cdf0e10cSrcweir     /* Now decode the URL what should result in an UTF8 string */
597cdf0e10cSrcweir     while ( bValidEncoded && pSrc < pSrcEnd )
598cdf0e10cSrcweir     {
599cdf0e10cSrcweir         switch ( *pSrc )
600cdf0e10cSrcweir         {
601cdf0e10cSrcweir         case '%':
602cdf0e10cSrcweir             {
603cdf0e10cSrcweir                 sal_Char	aToken[3];
604cdf0e10cSrcweir                 sal_Char	aChar;
605cdf0e10cSrcweir 
606cdf0e10cSrcweir                 pSrc++;
607cdf0e10cSrcweir                 aToken[0] = *pSrc++;
608cdf0e10cSrcweir                 aToken[1] = *pSrc++;
609cdf0e10cSrcweir                 aToken[2] = 0;
610cdf0e10cSrcweir 
611cdf0e10cSrcweir                 aChar = (sal_Char)strtoul( aToken, NULL, 16 );
612cdf0e10cSrcweir 
613cdf0e10cSrcweir                 /* The chars are path delimiters and must not be encoded */
614cdf0e10cSrcweir 
615cdf0e10cSrcweir                 if ( 0 == aChar || '\\' == aChar || '/' == aChar || ':' == aChar )
616cdf0e10cSrcweir                     bValidEncoded = sal_False;
617cdf0e10cSrcweir                 else
618cdf0e10cSrcweir                     *pDest++ = aChar;
619cdf0e10cSrcweir             }
620cdf0e10cSrcweir             break;
621cdf0e10cSrcweir         default:
622cdf0e10cSrcweir             *pDest++ = *pSrc++;
623cdf0e10cSrcweir             break;
624cdf0e10cSrcweir         }
625cdf0e10cSrcweir     }
626cdf0e10cSrcweir 
627cdf0e10cSrcweir     *pDest++ = 0;
628cdf0e10cSrcweir 
629cdf0e10cSrcweir     if ( bValidEncoded )
630cdf0e10cSrcweir     {
631cdf0e10cSrcweir         rtl_string2UString( pstrDecodedURL, pBuffer, rtl_str_getLength(pBuffer), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
632cdf0e10cSrcweir         OSL_ASSERT(*pstrDecodedURL != 0);
633cdf0e10cSrcweir     }
634cdf0e10cSrcweir 
635cdf0e10cSrcweir     rtl_freeMemory( pBuffer );
636cdf0e10cSrcweir 
637cdf0e10cSrcweir     return bValidEncoded;
638cdf0e10cSrcweir }
639cdf0e10cSrcweir 
640cdf0e10cSrcweir //#############################################
_osl_encodeURL(rtl_uString * strURL,rtl_String ** pstrEncodedURL)641cdf0e10cSrcweir static void _osl_encodeURL( rtl_uString *strURL, rtl_String **pstrEncodedURL )
642cdf0e10cSrcweir {
643cdf0e10cSrcweir     /* Encode non ascii characters within the URL */
644cdf0e10cSrcweir 
645cdf0e10cSrcweir     rtl_String		*strUTF8 = NULL;
646cdf0e10cSrcweir     sal_Char		*pszEncodedURL;
647cdf0e10cSrcweir     const sal_Char	*pURLScan;
648cdf0e10cSrcweir     sal_Char		*pURLDest;
649cdf0e10cSrcweir     sal_Int32		nURLScanLen;
650cdf0e10cSrcweir     sal_Int32		nURLScanCount;
651cdf0e10cSrcweir 
652cdf0e10cSrcweir     rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
653cdf0e10cSrcweir 
654cdf0e10cSrcweir     pszEncodedURL = (sal_Char*) rtl_allocateMemory( (rtl_string_getLength( strUTF8 ) * 3 + 1)  * sizeof(sal_Char) );
655cdf0e10cSrcweir 
656cdf0e10cSrcweir     pURLDest = pszEncodedURL;
657cdf0e10cSrcweir     pURLScan = rtl_string_getStr( strUTF8 );
658cdf0e10cSrcweir     nURLScanLen = rtl_string_getLength( strUTF8 );
659cdf0e10cSrcweir     nURLScanCount = 0;
660cdf0e10cSrcweir 
661cdf0e10cSrcweir     while ( nURLScanCount < nURLScanLen )
662cdf0e10cSrcweir     {
663cdf0e10cSrcweir         sal_Char cCurrent = *pURLScan;
664cdf0e10cSrcweir         switch ( cCurrent )
665cdf0e10cSrcweir         {
666cdf0e10cSrcweir         default:
667cdf0e10cSrcweir             if (!( ( cCurrent >= 'a' && cCurrent <= 'z' ) || ( cCurrent >= 'A' && cCurrent <= 'Z' ) || ( cCurrent >= '0' && cCurrent <= '9' ) ) )
668cdf0e10cSrcweir             {
669cdf0e10cSrcweir                 sprintf( pURLDest, "%%%02X", (unsigned char)cCurrent );
670cdf0e10cSrcweir                 pURLDest += 3;
671cdf0e10cSrcweir                 break;
672cdf0e10cSrcweir             }
673cdf0e10cSrcweir         case '!':
674cdf0e10cSrcweir         case '\'':
675cdf0e10cSrcweir         case '(':
676cdf0e10cSrcweir         case ')':
677cdf0e10cSrcweir         case '*':
678cdf0e10cSrcweir         case '-':
679cdf0e10cSrcweir         case '.':
680cdf0e10cSrcweir         case '_':
681cdf0e10cSrcweir         case '~':
682cdf0e10cSrcweir         case '$':
683cdf0e10cSrcweir         case '&':
684cdf0e10cSrcweir         case '+':
685cdf0e10cSrcweir         case ',':
686cdf0e10cSrcweir         case '=':
687cdf0e10cSrcweir         case '@':
688cdf0e10cSrcweir         case ':':
689cdf0e10cSrcweir         case '/':
690cdf0e10cSrcweir         case '\\':
691cdf0e10cSrcweir         case '|':
692cdf0e10cSrcweir             *pURLDest++ = cCurrent;
693cdf0e10cSrcweir             break;
694cdf0e10cSrcweir         case 0:
695cdf0e10cSrcweir             break;
696cdf0e10cSrcweir         }
697cdf0e10cSrcweir 
698cdf0e10cSrcweir         pURLScan++;
699cdf0e10cSrcweir         nURLScanCount++;
700cdf0e10cSrcweir     }
701cdf0e10cSrcweir 
702cdf0e10cSrcweir     *pURLDest = 0;
703cdf0e10cSrcweir 
704cdf0e10cSrcweir     rtl_string_release( strUTF8 );
705cdf0e10cSrcweir     rtl_string_newFromStr( pstrEncodedURL, pszEncodedURL );
706cdf0e10cSrcweir     rtl_freeMemory( pszEncodedURL );
707cdf0e10cSrcweir }
708cdf0e10cSrcweir 
709cdf0e10cSrcweir //#############################################
710cdf0e10cSrcweir 
_osl_getSystemPathFromFileURL(rtl_uString * strURL,rtl_uString ** pustrPath,sal_Bool bAllowRelative)711cdf0e10cSrcweir oslFileError _osl_getSystemPathFromFileURL( rtl_uString *strURL, rtl_uString **pustrPath, sal_Bool bAllowRelative )
712cdf0e10cSrcweir {
713cdf0e10cSrcweir     rtl_String			*strUTF8 = NULL;
714cdf0e10cSrcweir     rtl_uString			*strDecodedURL = NULL;
715cdf0e10cSrcweir     rtl_uString			*strTempPath = NULL;
716cdf0e10cSrcweir     const sal_Unicode	*pDecodedURL;
717cdf0e10cSrcweir     sal_uInt32			nDecodedLen;
718cdf0e10cSrcweir     sal_Bool			bValidEncoded;
719cdf0e10cSrcweir     oslFileError		nError = osl_File_E_INVAL;	/* Assume failure */
720cdf0e10cSrcweir 
721cdf0e10cSrcweir     /*  If someone hasn't encoded the complete URL we convert it to UTF8 now to prevent from
722cdf0e10cSrcweir         having a mixed encoded URL later */
723cdf0e10cSrcweir 
724cdf0e10cSrcweir     rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
725cdf0e10cSrcweir 
726cdf0e10cSrcweir     /* If the length of strUTF8 and strURL differs it indicates that the URL was not correct encoded */
727cdf0e10cSrcweir 
728cdf0e10cSrcweir     OSL_ENSURE_FILE(
729cdf0e10cSrcweir         strUTF8->length == strURL->length ||
730cdf0e10cSrcweir         0 != rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( strURL->buffer, strURL->length, "file:\\\\", 7 )
731cdf0e10cSrcweir         ,"osl_getSystemPathFromFileURL: \"%s\" is not encoded !!!", strURL );
732cdf0e10cSrcweir 
733cdf0e10cSrcweir     bValidEncoded = _osl_decodeURL( strUTF8, &strDecodedURL );
734cdf0e10cSrcweir 
735cdf0e10cSrcweir     /* Release the encoded UTF8 string */
736cdf0e10cSrcweir     rtl_string_release( strUTF8 );
737cdf0e10cSrcweir 
738cdf0e10cSrcweir     if ( bValidEncoded )
739cdf0e10cSrcweir     {
740cdf0e10cSrcweir         /* Replace backslashes and pipes */
741cdf0e10cSrcweir 
742cdf0e10cSrcweir         rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '/', '\\' );
743cdf0e10cSrcweir         rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '|', ':' );
744cdf0e10cSrcweir 
745cdf0e10cSrcweir         pDecodedURL = rtl_uString_getStr( strDecodedURL );
746cdf0e10cSrcweir         nDecodedLen = rtl_uString_getLength( strDecodedURL );
747cdf0e10cSrcweir 
748cdf0e10cSrcweir         /* Must start with "file://" */
749cdf0e10cSrcweir         if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\", 7 ) )
750cdf0e10cSrcweir         {
751cdf0e10cSrcweir             sal_uInt32	nSkip;
752cdf0e10cSrcweir 
753cdf0e10cSrcweir             if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\\\", 8 ) )
754cdf0e10cSrcweir                 nSkip = 8;
755cdf0e10cSrcweir             else if (
756cdf0e10cSrcweir                 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\localhost\\", 17 ) ||
757cdf0e10cSrcweir                 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\127.0.0.1\\", 17 )
758cdf0e10cSrcweir                       )
759cdf0e10cSrcweir                 nSkip = 17;
760cdf0e10cSrcweir             else
761cdf0e10cSrcweir                 nSkip = 5;
762cdf0e10cSrcweir 
763cdf0e10cSrcweir             /* Indicates local root */
764cdf0e10cSrcweir             if ( nDecodedLen == nSkip )
765cdf0e10cSrcweir                 rtl_uString_newFromStr_WithLength( &strTempPath, reinterpret_cast<const sal_Unicode*>(WSTR_SYSTEM_ROOT_PATH), ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1 );
766cdf0e10cSrcweir             else
767cdf0e10cSrcweir             {
768cdf0e10cSrcweir                 /* do not separate the directory and file case, so the maximal path lengs without prefix is MAX_PATH-12 */
769cdf0e10cSrcweir                 if ( nDecodedLen - nSkip <= MAX_PATH - 12 )
770cdf0e10cSrcweir                 {
771cdf0e10cSrcweir                     rtl_uString_newFromStr_WithLength( &strTempPath, pDecodedURL + nSkip, nDecodedLen - nSkip );
772cdf0e10cSrcweir                 }
773cdf0e10cSrcweir                 else
774cdf0e10cSrcweir                 {
775cdf0e10cSrcweir                     ::osl::LongPathBuffer< sal_Unicode > aBuf( MAX_LONG_PATH );
776cdf0e10cSrcweir                     sal_uInt32 nNewLen = GetCaseCorrectPathName( reinterpret_cast<LPCTSTR>(pDecodedURL + nSkip),
777cdf0e10cSrcweir                                                                  ::osl::mingw_reinterpret_cast<LPTSTR>(aBuf),
778cdf0e10cSrcweir                                                                  aBuf.getBufSizeInSymbols(),
779cdf0e10cSrcweir                                                                  sal_False );
780cdf0e10cSrcweir 
781cdf0e10cSrcweir                     if ( nNewLen <= MAX_PATH - 12
782cdf0e10cSrcweir                       || 0 == rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL + nSkip, nDecodedLen - nSkip, reinterpret_cast<const sal_Unicode*>(WSTR_SYSTEM_ROOT_PATH), ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1, ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1 )
783cdf0e10cSrcweir                       || 0 == rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL + nSkip, nDecodedLen - nSkip, reinterpret_cast<const sal_Unicode*>(WSTR_LONG_PATH_PREFIX), ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1, ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1 ) )
784cdf0e10cSrcweir                     {
785cdf0e10cSrcweir                         rtl_uString_newFromStr_WithLength( &strTempPath, aBuf, nNewLen );
786cdf0e10cSrcweir                     }
787cdf0e10cSrcweir                     else if ( pDecodedURL[nSkip] == (sal_Unicode)'\\' && pDecodedURL[nSkip+1] == (sal_Unicode)'\\' )
788cdf0e10cSrcweir                     {
789cdf0e10cSrcweir                         /* it should be an UNC path, use the according prefix */
790cdf0e10cSrcweir                         rtl_uString *strSuffix = NULL;
791cdf0e10cSrcweir                         rtl_uString *strPrefix = NULL;
792cdf0e10cSrcweir                         rtl_uString_newFromStr_WithLength( &strPrefix, reinterpret_cast<const sal_Unicode*>(WSTR_LONG_PATH_PREFIX_UNC), ELEMENTS_OF_ARRAY( WSTR_LONG_PATH_PREFIX_UNC ) - 1 );
793cdf0e10cSrcweir                         rtl_uString_newFromStr_WithLength( &strSuffix, aBuf + 2, nNewLen - 2 );
794cdf0e10cSrcweir 
795cdf0e10cSrcweir                         rtl_uString_newConcat( &strTempPath, strPrefix, strSuffix );
796cdf0e10cSrcweir 
797cdf0e10cSrcweir                         rtl_uString_release( strPrefix );
798cdf0e10cSrcweir                         rtl_uString_release( strSuffix );
799cdf0e10cSrcweir                     }
800cdf0e10cSrcweir                     else
801cdf0e10cSrcweir                     {
802cdf0e10cSrcweir                         rtl_uString *strSuffix = NULL;
803cdf0e10cSrcweir                         rtl_uString *strPrefix = NULL;
804cdf0e10cSrcweir                         rtl_uString_newFromStr_WithLength( &strPrefix, reinterpret_cast<const sal_Unicode*>(WSTR_LONG_PATH_PREFIX), ELEMENTS_OF_ARRAY( WSTR_LONG_PATH_PREFIX ) - 1 );
805cdf0e10cSrcweir                         rtl_uString_newFromStr_WithLength( &strSuffix, aBuf, nNewLen );
806cdf0e10cSrcweir 
807cdf0e10cSrcweir                         rtl_uString_newConcat( &strTempPath, strPrefix, strSuffix );
808cdf0e10cSrcweir 
809cdf0e10cSrcweir                         rtl_uString_release( strPrefix );
810cdf0e10cSrcweir                         rtl_uString_release( strSuffix );
811cdf0e10cSrcweir                     }
812cdf0e10cSrcweir                 }
813cdf0e10cSrcweir             }
814cdf0e10cSrcweir 
815cdf0e10cSrcweir             if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) )
816cdf0e10cSrcweir                 nError = osl_File_E_None;
817cdf0e10cSrcweir         }
818cdf0e10cSrcweir         else if ( bAllowRelative )	/* This maybe a relative file URL */
819cdf0e10cSrcweir         {
820cdf0e10cSrcweir             /* In future the relative path could be converted to absolute if it is too long */
821cdf0e10cSrcweir             rtl_uString_assign( &strTempPath, strDecodedURL );
822cdf0e10cSrcweir 
823cdf0e10cSrcweir             if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_RELATIVE | VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) )
824cdf0e10cSrcweir                 nError = osl_File_E_None;
825cdf0e10cSrcweir         }
826cdf0e10cSrcweir         /*
827cdf0e10cSrcweir           else
828cdf0e10cSrcweir           OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not an absolute FileURL !!!", strURL );
829cdf0e10cSrcweir         */
830cdf0e10cSrcweir 
831cdf0e10cSrcweir     }
832cdf0e10cSrcweir 
833cdf0e10cSrcweir     if ( strDecodedURL )
834cdf0e10cSrcweir         rtl_uString_release( strDecodedURL );
835cdf0e10cSrcweir 
836cdf0e10cSrcweir     if ( osl_File_E_None == nError )
837cdf0e10cSrcweir         rtl_uString_assign( pustrPath, strTempPath );
838cdf0e10cSrcweir 
839cdf0e10cSrcweir     if ( strTempPath )
840cdf0e10cSrcweir         rtl_uString_release( strTempPath );
841cdf0e10cSrcweir 
842cdf0e10cSrcweir     /*
843cdf0e10cSrcweir       OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not a FileURL !!!", strURL );
844cdf0e10cSrcweir     */
845cdf0e10cSrcweir 
846cdf0e10cSrcweir     return nError;
847cdf0e10cSrcweir }
848cdf0e10cSrcweir 
849cdf0e10cSrcweir //#############################################
_osl_getFileURLFromSystemPath(rtl_uString * strPath,rtl_uString ** pstrURL)850cdf0e10cSrcweir oslFileError _osl_getFileURLFromSystemPath( rtl_uString* strPath, rtl_uString** pstrURL )
851cdf0e10cSrcweir {
852cdf0e10cSrcweir     oslFileError nError = osl_File_E_INVAL; /* Assume failure */
853cdf0e10cSrcweir     rtl_uString	*strTempURL = NULL;
854cdf0e10cSrcweir     DWORD dwPathType = PATHTYPE_ERROR;
855cdf0e10cSrcweir 
856cdf0e10cSrcweir     if (strPath)
857cdf0e10cSrcweir         dwPathType = IsValidFilePath(strPath, NULL, VALIDATEPATH_ALLOW_RELATIVE, NULL);
858cdf0e10cSrcweir 
859cdf0e10cSrcweir     if (dwPathType)
860cdf0e10cSrcweir     {
861cdf0e10cSrcweir         rtl_uString	*strTempPath = NULL;
862cdf0e10cSrcweir 
863cdf0e10cSrcweir         if ( dwPathType & PATHTYPE_IS_LONGPATH )
864cdf0e10cSrcweir         {
865cdf0e10cSrcweir             rtl_uString *strBuffer = NULL;
866cdf0e10cSrcweir             sal_uInt32 nIgnore = 0;
867cdf0e10cSrcweir             sal_uInt32 nLength = 0;
868cdf0e10cSrcweir 
869cdf0e10cSrcweir             /* the path has the longpath prefix, lets remove it */
870cdf0e10cSrcweir             switch ( dwPathType & PATHTYPE_MASK_TYPE )
871cdf0e10cSrcweir             {
872cdf0e10cSrcweir                 case PATHTYPE_ABSOLUTE_UNC:
873cdf0e10cSrcweir                     nIgnore = ELEMENTS_OF_ARRAY( WSTR_LONG_PATH_PREFIX_UNC ) - 1;
874cdf0e10cSrcweir                     OSL_ENSURE( nIgnore == 8, "Unexpected long path UNC prefix!" );
875cdf0e10cSrcweir 
876cdf0e10cSrcweir                     /* generate the normal UNC path */
877cdf0e10cSrcweir                     nLength = rtl_uString_getLength( strPath );
878cdf0e10cSrcweir                     rtl_uString_newFromStr_WithLength( &strBuffer, strPath->buffer + nIgnore - 2, nLength - nIgnore + 2 );
879cdf0e10cSrcweir                     strBuffer->buffer[0] = '\\';
880cdf0e10cSrcweir 
881cdf0e10cSrcweir                     rtl_uString_newReplace( &strTempPath, strBuffer, '\\', '/' );
882cdf0e10cSrcweir                     rtl_uString_release( strBuffer );
883cdf0e10cSrcweir                     break;
884cdf0e10cSrcweir 
885cdf0e10cSrcweir                 case PATHTYPE_ABSOLUTE_LOCAL:
886cdf0e10cSrcweir                     nIgnore = ELEMENTS_OF_ARRAY( WSTR_LONG_PATH_PREFIX ) - 1;
887cdf0e10cSrcweir                     OSL_ENSURE( nIgnore == 4, "Unexpected long path prefix!" );
888cdf0e10cSrcweir 
889cdf0e10cSrcweir                     /* generate the normal path */
890cdf0e10cSrcweir                     nLength = rtl_uString_getLength( strPath );
891cdf0e10cSrcweir                     rtl_uString_newFromStr_WithLength( &strBuffer, strPath->buffer + nIgnore, nLength - nIgnore );
892cdf0e10cSrcweir 
893cdf0e10cSrcweir                     rtl_uString_newReplace( &strTempPath, strBuffer, '\\', '/' );
894cdf0e10cSrcweir                     rtl_uString_release( strBuffer );
895cdf0e10cSrcweir                     break;
896cdf0e10cSrcweir 
897cdf0e10cSrcweir                 default:
898cdf0e10cSrcweir                     OSL_ASSERT( "Unexpected long path format!" );
899cdf0e10cSrcweir                     rtl_uString_newReplace( &strTempPath, strPath, '\\', '/' );
900cdf0e10cSrcweir                     break;
901cdf0e10cSrcweir             }
902cdf0e10cSrcweir         }
903cdf0e10cSrcweir         else
904cdf0e10cSrcweir         {
905cdf0e10cSrcweir             /* Replace backslashes */
906cdf0e10cSrcweir             rtl_uString_newReplace( &strTempPath, strPath, '\\', '/' );
907cdf0e10cSrcweir         }
908cdf0e10cSrcweir 
909cdf0e10cSrcweir         switch ( dwPathType & PATHTYPE_MASK_TYPE )
910cdf0e10cSrcweir         {
911cdf0e10cSrcweir         case PATHTYPE_RELATIVE:
912cdf0e10cSrcweir             rtl_uString_assign( &strTempURL, strTempPath );
913cdf0e10cSrcweir             nError = osl_File_E_None;
914cdf0e10cSrcweir             break;
915cdf0e10cSrcweir         case PATHTYPE_ABSOLUTE_UNC:
916cdf0e10cSrcweir             rtl_uString_newFromAscii( &strTempURL, "file:" );
917cdf0e10cSrcweir             rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath );
918cdf0e10cSrcweir             nError = osl_File_E_None;
919cdf0e10cSrcweir             break;
920cdf0e10cSrcweir         case PATHTYPE_ABSOLUTE_LOCAL:
921cdf0e10cSrcweir             rtl_uString_newFromAscii( &strTempURL, "file:///" );
922cdf0e10cSrcweir             rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath );
923cdf0e10cSrcweir             nError = osl_File_E_None;
924cdf0e10cSrcweir             break;
925cdf0e10cSrcweir         default:
926cdf0e10cSrcweir             break;
927cdf0e10cSrcweir         }
928cdf0e10cSrcweir 
929cdf0e10cSrcweir         /* Release temp path */
930cdf0e10cSrcweir         rtl_uString_release( strTempPath );
931cdf0e10cSrcweir     }
932cdf0e10cSrcweir 
933cdf0e10cSrcweir     if ( osl_File_E_None == nError )
934cdf0e10cSrcweir     {
935cdf0e10cSrcweir         rtl_String	*strEncodedURL = NULL;
936cdf0e10cSrcweir 
937cdf0e10cSrcweir         /* Encode the URL */
938cdf0e10cSrcweir         _osl_encodeURL( strTempURL, &strEncodedURL );
939cdf0e10cSrcweir 
940cdf0e10cSrcweir         /* Provide URL via unicode string */
941cdf0e10cSrcweir         rtl_string2UString( pstrURL, rtl_string_getStr(strEncodedURL), rtl_string_getLength(strEncodedURL), RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS );
942cdf0e10cSrcweir         OSL_ASSERT(*pstrURL != 0);
943cdf0e10cSrcweir         rtl_string_release( strEncodedURL );
944cdf0e10cSrcweir     }
945cdf0e10cSrcweir 
946cdf0e10cSrcweir     /* Release temp URL */
947cdf0e10cSrcweir     if ( strTempURL )
948cdf0e10cSrcweir         rtl_uString_release( strTempURL );
949cdf0e10cSrcweir 
950cdf0e10cSrcweir     /*
951cdf0e10cSrcweir       OSL_ENSURE_FILE( !nError, "osl_getFileURLFromSystemPath: \"%s\" is not a systemPath !!!", strPath );
952cdf0e10cSrcweir     */
953cdf0e10cSrcweir     return nError;
954cdf0e10cSrcweir }
955cdf0e10cSrcweir 
956cdf0e10cSrcweir //#####################################################
osl_getFileURLFromSystemPath(rtl_uString * ustrPath,rtl_uString ** pustrURL)957cdf0e10cSrcweir oslFileError SAL_CALL osl_getFileURLFromSystemPath(
958cdf0e10cSrcweir     rtl_uString* ustrPath, rtl_uString** pustrURL )
959cdf0e10cSrcweir {
960cdf0e10cSrcweir 	return _osl_getFileURLFromSystemPath( ustrPath, pustrURL );
961cdf0e10cSrcweir }
962cdf0e10cSrcweir 
963cdf0e10cSrcweir //#####################################################
osl_getSystemPathFromFileURL(rtl_uString * ustrURL,rtl_uString ** pustrPath)964cdf0e10cSrcweir oslFileError SAL_CALL osl_getSystemPathFromFileURL(
965cdf0e10cSrcweir     rtl_uString *ustrURL, rtl_uString **pustrPath)
966cdf0e10cSrcweir {
967cdf0e10cSrcweir 	return _osl_getSystemPathFromFileURL( ustrURL, pustrPath, sal_True );
968cdf0e10cSrcweir }
969cdf0e10cSrcweir 
970cdf0e10cSrcweir //#####################################################
osl_searchFileURL(rtl_uString * ustrFileName,rtl_uString * ustrSystemSearchPath,rtl_uString ** pustrPath)971cdf0e10cSrcweir oslFileError SAL_CALL osl_searchFileURL(
972cdf0e10cSrcweir     rtl_uString *ustrFileName,
973cdf0e10cSrcweir     rtl_uString *ustrSystemSearchPath,
974cdf0e10cSrcweir     rtl_uString **pustrPath)
975cdf0e10cSrcweir {
976cdf0e10cSrcweir 	rtl_uString		*ustrUNCPath = NULL;
977cdf0e10cSrcweir 	rtl_uString		*ustrSysPath = NULL;
978cdf0e10cSrcweir 	oslFileError	error;
979cdf0e10cSrcweir 
980cdf0e10cSrcweir 	/* First try to interpret the file name as an URL even a relative one */
981cdf0e10cSrcweir 	error = _osl_getSystemPathFromFileURL( ustrFileName, &ustrUNCPath, sal_True );
982cdf0e10cSrcweir 
983cdf0e10cSrcweir 	/* So far we either have an UNC path or something invalid
984cdf0e10cSrcweir 	   Now create a system path */
985cdf0e10cSrcweir 	if ( osl_File_E_None == error )
986cdf0e10cSrcweir 		error = _osl_getSystemPathFromFileURL( ustrUNCPath, &ustrSysPath, sal_True );
987cdf0e10cSrcweir 
988cdf0e10cSrcweir 	if ( osl_File_E_None == error )
989cdf0e10cSrcweir 	{
990cdf0e10cSrcweir 		DWORD	nBufferLength;
991cdf0e10cSrcweir 		DWORD	dwResult;
992cdf0e10cSrcweir 		LPTSTR	lpBuffer = NULL;
993cdf0e10cSrcweir 		LPTSTR	lpszFilePart;
994cdf0e10cSrcweir 
995cdf0e10cSrcweir 		/* Repeat calling SearchPath ...
996cdf0e10cSrcweir 		   Start with MAX_PATH for the buffer. In most cases this
997cdf0e10cSrcweir 		   will be enough and does not force the loop to runtwice */
998cdf0e10cSrcweir 		dwResult = MAX_PATH;
999cdf0e10cSrcweir 
1000cdf0e10cSrcweir 		do
1001cdf0e10cSrcweir 		{
1002cdf0e10cSrcweir 			/* If search path is empty use a NULL pointer instead according to MSDN documentation of SearchPath */
1003cdf0e10cSrcweir 			LPCTSTR	lpszSearchPath = ustrSystemSearchPath && ustrSystemSearchPath->length ? reinterpret_cast<LPCTSTR>(ustrSystemSearchPath->buffer) : NULL;
1004cdf0e10cSrcweir 			LPCTSTR	lpszSearchFile = reinterpret_cast<LPCTSTR>(ustrSysPath->buffer);
1005cdf0e10cSrcweir 
1006cdf0e10cSrcweir 			/* Allocate space for buffer according to previous returned count of required chars */
1007cdf0e10cSrcweir 			/* +1 is not neccessary if we follow MSDN documentation but for robustness we do so */
1008cdf0e10cSrcweir 			nBufferLength = dwResult + 1;
1009cdf0e10cSrcweir 			lpBuffer = lpBuffer ?
1010cdf0e10cSrcweir 			    reinterpret_cast<LPTSTR>(rtl_reallocateMemory(lpBuffer, nBufferLength * sizeof(TCHAR))) :
1011cdf0e10cSrcweir 			    reinterpret_cast<LPTSTR>(rtl_allocateMemory(nBufferLength * sizeof(TCHAR)));
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir 			dwResult = SearchPath( lpszSearchPath, lpszSearchFile, NULL, nBufferLength, lpBuffer, &lpszFilePart );
1014cdf0e10cSrcweir 		} while ( dwResult && dwResult >= nBufferLength );
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir 		/*	... until an error occures or buffer is large enough.
1017cdf0e10cSrcweir 			dwResult == nBufferLength can not happen according to documentation but lets be robust ;-) */
1018cdf0e10cSrcweir 
1019cdf0e10cSrcweir 		if ( dwResult )
1020cdf0e10cSrcweir 		{
1021cdf0e10cSrcweir 			rtl_uString_newFromStr( &ustrSysPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) );
1022cdf0e10cSrcweir 			error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath );
1023cdf0e10cSrcweir 		}
1024cdf0e10cSrcweir 		else
1025cdf0e10cSrcweir 		{
1026cdf0e10cSrcweir 			WIN32_FIND_DATA	aFindFileData;
1027cdf0e10cSrcweir 			HANDLE	hFind;
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir 			/* Somthing went wrong, perhaps the path was absolute */
1030cdf0e10cSrcweir 			error = oslTranslateFileError( GetLastError() );
1031cdf0e10cSrcweir 
1032cdf0e10cSrcweir 			hFind = FindFirstFile( reinterpret_cast<LPCTSTR>(ustrSysPath->buffer), &aFindFileData );
1033cdf0e10cSrcweir 
1034cdf0e10cSrcweir 			if ( IsValidHandle(hFind) )
1035cdf0e10cSrcweir 			{
1036cdf0e10cSrcweir 				error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath );
1037cdf0e10cSrcweir 				FindClose( hFind );
1038cdf0e10cSrcweir 			}
1039cdf0e10cSrcweir 		}
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir 		rtl_freeMemory( lpBuffer );
1042cdf0e10cSrcweir 	}
1043cdf0e10cSrcweir 
1044cdf0e10cSrcweir 	if ( ustrSysPath )
1045cdf0e10cSrcweir 		rtl_uString_release( ustrSysPath );
1046cdf0e10cSrcweir 
1047cdf0e10cSrcweir 	if ( ustrUNCPath )
1048cdf0e10cSrcweir 		rtl_uString_release( ustrUNCPath );
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir 	return error;
1051cdf0e10cSrcweir }
1052cdf0e10cSrcweir 
1053cdf0e10cSrcweir //#####################################################
1054cdf0e10cSrcweir 
osl_getAbsoluteFileURL(rtl_uString * ustrBaseURL,rtl_uString * ustrRelativeURL,rtl_uString ** pustrAbsoluteURL)1055cdf0e10cSrcweir oslFileError SAL_CALL osl_getAbsoluteFileURL( rtl_uString* ustrBaseURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL )
1056cdf0e10cSrcweir {
1057cdf0e10cSrcweir 	oslFileError	eError;
1058cdf0e10cSrcweir 	rtl_uString		*ustrRelSysPath = NULL;
1059cdf0e10cSrcweir 	rtl_uString		*ustrBaseSysPath = NULL;
1060cdf0e10cSrcweir 
1061cdf0e10cSrcweir 	if ( ustrBaseURL && ustrBaseURL->length )
1062cdf0e10cSrcweir 	{
1063cdf0e10cSrcweir 		eError = _osl_getSystemPathFromFileURL( ustrBaseURL, &ustrBaseSysPath, sal_False );
1064cdf0e10cSrcweir 		OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with relative or invalid base URL" );
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir 		eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_True );
1067cdf0e10cSrcweir 	}
1068cdf0e10cSrcweir 	else
1069cdf0e10cSrcweir 	{
1070cdf0e10cSrcweir 		eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_False );
1071cdf0e10cSrcweir 		OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with empty base URL and/or invalid relative URL" );
1072cdf0e10cSrcweir 	}
1073cdf0e10cSrcweir 
1074cdf0e10cSrcweir 	if ( !eError )
1075cdf0e10cSrcweir 	{
1076cdf0e10cSrcweir         ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
1077cdf0e10cSrcweir         ::osl::LongPathBuffer< sal_Unicode > aCurrentDir( MAX_LONG_PATH );
1078cdf0e10cSrcweir 		LPTSTR	lpFilePart = NULL;
1079cdf0e10cSrcweir 		DWORD	dwResult;
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir /*@@@ToDo
1082cdf0e10cSrcweir   Bad, bad hack, this only works if the base path
1083cdf0e10cSrcweir   really exists which is not necessary according
1084cdf0e10cSrcweir   to RFC2396
1085cdf0e10cSrcweir   The whole FileURL implementation should be merged
1086cdf0e10cSrcweir   with the rtl/uri class.
1087cdf0e10cSrcweir */
1088cdf0e10cSrcweir 		if ( ustrBaseSysPath )
1089cdf0e10cSrcweir 		{
1090cdf0e10cSrcweir 			osl_acquireMutex( g_CurrentDirectoryMutex );
1091cdf0e10cSrcweir 
1092cdf0e10cSrcweir 			GetCurrentDirectoryW( aCurrentDir.getBufSizeInSymbols(), ::osl::mingw_reinterpret_cast<LPWSTR>(aCurrentDir) );
1093cdf0e10cSrcweir 			SetCurrentDirectoryW( reinterpret_cast<LPCWSTR>(ustrBaseSysPath->buffer) );
1094cdf0e10cSrcweir 		}
1095cdf0e10cSrcweir 
1096cdf0e10cSrcweir 		dwResult = GetFullPathNameW( reinterpret_cast<LPCWSTR>(ustrRelSysPath->buffer), aBuffer.getBufSizeInSymbols(), ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer), &lpFilePart );
1097cdf0e10cSrcweir 
1098cdf0e10cSrcweir 		if ( ustrBaseSysPath )
1099cdf0e10cSrcweir 		{
1100cdf0e10cSrcweir 			SetCurrentDirectoryW( ::osl::mingw_reinterpret_cast<LPCWSTR>(aCurrentDir) );
1101cdf0e10cSrcweir 
1102cdf0e10cSrcweir 			osl_releaseMutex( g_CurrentDirectoryMutex );
1103cdf0e10cSrcweir 		}
1104cdf0e10cSrcweir 
1105cdf0e10cSrcweir 		if ( dwResult )
1106cdf0e10cSrcweir 		{
1107cdf0e10cSrcweir 			if ( dwResult >= aBuffer.getBufSizeInSymbols() )
1108cdf0e10cSrcweir 				eError = osl_File_E_INVAL;
1109cdf0e10cSrcweir 			else
1110cdf0e10cSrcweir 			{
1111cdf0e10cSrcweir 				rtl_uString	*ustrAbsSysPath = NULL;
1112cdf0e10cSrcweir 
1113cdf0e10cSrcweir 				rtl_uString_newFromStr( &ustrAbsSysPath, aBuffer );
1114cdf0e10cSrcweir 
1115cdf0e10cSrcweir 				eError = osl_getFileURLFromSystemPath( ustrAbsSysPath, pustrAbsoluteURL );
1116cdf0e10cSrcweir 
1117cdf0e10cSrcweir 				if ( ustrAbsSysPath )
1118cdf0e10cSrcweir 					rtl_uString_release( ustrAbsSysPath );
1119cdf0e10cSrcweir 			}
1120cdf0e10cSrcweir 		}
1121cdf0e10cSrcweir 		else
1122cdf0e10cSrcweir 			eError = oslTranslateFileError( GetLastError() );
1123cdf0e10cSrcweir 	}
1124cdf0e10cSrcweir 
1125cdf0e10cSrcweir 	if ( ustrBaseSysPath )
1126cdf0e10cSrcweir 		rtl_uString_release( ustrBaseSysPath );
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir 	if ( ustrRelSysPath )
1129cdf0e10cSrcweir 		rtl_uString_release( ustrRelSysPath );
1130cdf0e10cSrcweir 
1131cdf0e10cSrcweir 	return	eError;
1132cdf0e10cSrcweir }
1133cdf0e10cSrcweir 
1134cdf0e10cSrcweir //#####################################################
osl_getCanonicalName(rtl_uString * strRequested,rtl_uString ** strValid)1135cdf0e10cSrcweir oslFileError SAL_CALL osl_getCanonicalName( rtl_uString *strRequested, rtl_uString **strValid )
1136cdf0e10cSrcweir {
1137cdf0e10cSrcweir 	rtl_uString_newFromString(strValid, strRequested);
1138cdf0e10cSrcweir 	return osl_File_E_None;
1139cdf0e10cSrcweir }
1140