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