1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sal.hxx"
36 #define _WIN32_WINNT 0x0500
37 #include "systools\win32\uwinapi.h"
39 #include "path_helper.hxx"
41 #include "sal/types.h"
43 #include "osl/file.hxx"
44 #include "osl/diagnose.h"
45 #include "rtl/ustring.hxx"
46 #include "rtl/alloc.h"
47 #include "rtl/tencinfo.h"
48 #include "osl/thread.h"
49 #include "osl/mutex.h"
50 #include "rtl/byteseq.h"
52 //#include <rtl/logfile.h>
55 #define WIN32_LEAN_AND_MEAN
68 #ifdef max /* conflict w/ std::numeric_limits<T>::max() */
72 //#####################################################
74 //#####################################################
76 extern "C" oslMutex g_CurrentDirectoryMutex
; /* Initialized in dllentry.c */
77 oslMutex g_CurrentDirectoryMutex
;
79 //#####################################################
80 extern "C" BOOL
TimeValueToFileTime(const TimeValue
*cpTimeVal
, FILETIME
*pFTime
)
82 SYSTEMTIME BaseSysTime
;
83 FILETIME BaseFileTime
;
86 BOOL fSuccess
= FALSE
;
88 BaseSysTime
.wYear
= 1970;
89 BaseSysTime
.wMonth
= 1;
90 BaseSysTime
.wDayOfWeek
= 0;
92 BaseSysTime
.wHour
= 0;
93 BaseSysTime
.wMinute
= 0;
94 BaseSysTime
.wSecond
= 0;
95 BaseSysTime
.wMilliseconds
= 0;
100 if ( SystemTimeToFileTime(&BaseSysTime
, &BaseFileTime
) )
103 localTime
=cpTimeVal
->Seconds
*(__int64
)10000000+cpTimeVal
->Nanosec
/100;
104 *(__int64
*)&FTime
=localTime
;
105 fSuccess
= 0 <= (timeValue
= *((__int64
*)&BaseFileTime
) + *((__int64
*) &FTime
));
107 *(__int64
*)pFTime
=timeValue
;
112 //#####################################################
113 extern "C" BOOL
FileTimeToTimeValue(const FILETIME
*cpFTime
, TimeValue
*pTimeVal
)
115 SYSTEMTIME BaseSysTime
;
116 FILETIME BaseFileTime
;
117 BOOL fSuccess
= FALSE
; /* Assume failure */
119 BaseSysTime
.wYear
= 1970;
120 BaseSysTime
.wMonth
= 1;
121 BaseSysTime
.wDayOfWeek
= 0;
122 BaseSysTime
.wDay
= 1;
123 BaseSysTime
.wHour
= 0;
124 BaseSysTime
.wMinute
= 0;
125 BaseSysTime
.wSecond
= 0;
126 BaseSysTime
.wMilliseconds
= 0;
128 if ( SystemTimeToFileTime(&BaseSysTime
, &BaseFileTime
) )
132 fSuccess
= 0 <= (Value
= *((__int64
*)cpFTime
) - *((__int64
*)&BaseFileTime
));
136 pTimeVal
->Seconds
= (unsigned long) (Value
/ 10000000L);
137 pTimeVal
->Nanosec
= (unsigned long)((Value
% 10000000L) * 100);
143 //#####################################################
144 extern "C" oslFileHandle SAL_CALL
osl_createFileHandleFromOSHandle(HANDLE hFile
)
146 if ( IsValidHandle(hFile
) )
147 return (oslFileHandle
)hFile
;
152 //#####################################################
154 //#####################################################
159 #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
161 // Allocate n number of t's on the stack return a pointer to it in p
163 #define STACK_ALLOC(p, t, n) (p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));
165 #define STACK_ALLOC(p, t, n) __try {(p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));} \
166 __except(EXCEPTION_EXECUTE_HANDLER) {(p) = NULL;}
169 #if OSL_DEBUG_LEVEL > 0
170 #define OSL_ENSURE_FILE( cond, msg, file ) ( (cond) ? (void)0 : _osl_warnFile( msg, file ) )
172 #define OSL_ENSURE_FILE( cond, msg, file ) ((void)0)
175 #define PATHTYPE_ERROR 0
176 #define PATHTYPE_RELATIVE 1
177 #define PATHTYPE_ABSOLUTE_UNC 2
178 #define PATHTYPE_ABSOLUTE_LOCAL 3
179 #define PATHTYPE_MASK_TYPE 0xFF
180 #define PATHTYPE_IS_VOLUME 0x0100
181 #define PATHTYPE_IS_SERVER 0x0200
183 #define VALIDATEPATH_NORMAL 0x0000
184 #define VALIDATEPATH_ALLOW_WILDCARDS 0x0001
185 #define VALIDATEPATH_ALLOW_ELLIPSE 0x0002
186 #define VALIDATEPATH_ALLOW_RELATIVE 0x0004
187 #define VALIDATEPATH_ALLOW_UNC 0x0008
188 #define VALIDATEPATH_ALLOW_INVALID_SPACE_AND_PERIOD 0x0010
190 #define WSTR_SYSTEM_ROOT_PATH L"\\\\.\\"
196 WIN32_FIND_DATA FindData
;
197 TCHAR cDriveString
[MAX_PATH
];
199 TCHAR szFullPath
[MAX_PATH
];
200 BOOL bFullPathNormalized
;
204 #define DIRECTORYTYPE_LOCALROOT 0
205 #define DIRECTORYTYPE_NETROOT 1
206 #define DIRECTORYTYPE_NETRESORCE 2
207 #define DIRECTORYTYPE_FILESYSTEM 3
209 #define DIRECTORYITEM_DRIVE 0
210 #define DIRECTORYITEM_FILE 1
211 #define DIRECTORYITEM_SERVER 2
219 TCHAR szDirectoryPath
[MAX_PATH
];
222 /* Different types of paths */
223 typedef enum _PATHTYPE
225 PATHTYPE_SYNTAXERROR
= 0,
233 namespace /* private */
236 void _osl_warnFile(const char*, rtl_uString
*);
237 oslFileError SAL_CALL
_osl_getFileURLFromSystemPath(rtl_uString
* , rtl_uString
**);
238 DWORD WINAPI
IsValidFilePath(rtl_uString
*, LPCTSTR
*, DWORD
, rtl_uString
**);
239 HANDLE WINAPI
OpenLogicalDrivesEnum(void);
240 BOOL WINAPI
EnumLogicalDrives(HANDLE
, LPTSTR
);
241 BOOL WINAPI
CloseLogicalDrivesEnum(HANDLE
);
242 HANDLE WINAPI
OpenDirectory(LPCTSTR
);
243 BOOL WINAPI
CloseDirectory(HANDLE
);
244 BOOL WINAPI
EnumDirectory(HANDLE
, LPWIN32_FIND_DATA
);
245 DWORD WINAPI
GetCaseCorrectPathName(LPCTSTR
, LPTSTR
, DWORD
);
246 oslFileError SAL_CALL
_osl_getSystemPathFromFileURL(rtl_uString
*, rtl_uString
**, sal_Bool
);
248 /* OS error to errno values mapping table */
250 unsigned long oscode
; /* OS return value */
251 int errnocode
; /* System V error code */
254 struct errentry errtable
[] = {
255 { ERROR_SUCCESS
, osl_File_E_None
}, /* 0 */
256 { ERROR_INVALID_FUNCTION
, osl_File_E_INVAL
}, /* 1 */
257 { ERROR_FILE_NOT_FOUND
, osl_File_E_NOENT
}, /* 2 */
258 { ERROR_PATH_NOT_FOUND
, osl_File_E_NOENT
}, /* 3 */
259 { ERROR_TOO_MANY_OPEN_FILES
, osl_File_E_MFILE
}, /* 4 */
260 { ERROR_ACCESS_DENIED
, osl_File_E_ACCES
}, /* 5 */
261 { ERROR_INVALID_HANDLE
, osl_File_E_BADF
}, /* 6 */
262 { ERROR_ARENA_TRASHED
, osl_File_E_NOMEM
}, /* 7 */
263 { ERROR_NOT_ENOUGH_MEMORY
, osl_File_E_NOMEM
}, /* 8 */
264 { ERROR_INVALID_BLOCK
, osl_File_E_NOMEM
}, /* 9 */
265 { ERROR_BAD_ENVIRONMENT
, osl_File_E_2BIG
}, /* 10 */
266 { ERROR_BAD_FORMAT
, osl_File_E_NOEXEC
}, /* 11 */
267 { ERROR_INVALID_ACCESS
, osl_File_E_INVAL
}, /* 12 */
268 { ERROR_INVALID_DATA
, osl_File_E_INVAL
}, /* 13 */
269 { ERROR_INVALID_DRIVE
, osl_File_E_NOENT
}, /* 15 */
270 { ERROR_CURRENT_DIRECTORY
, osl_File_E_ACCES
}, /* 16 */
271 { ERROR_NOT_SAME_DEVICE
, osl_File_E_XDEV
}, /* 17 */
272 { ERROR_NO_MORE_FILES
, osl_File_E_NOENT
}, /* 18 */
273 { ERROR_NOT_READY
, osl_File_E_NOTREADY
}, /* 21 */
274 { ERROR_LOCK_VIOLATION
, osl_File_E_ACCES
}, /* 33 */
275 { ERROR_BAD_NETPATH
, osl_File_E_NOENT
}, /* 53 */
276 { ERROR_NETWORK_ACCESS_DENIED
, osl_File_E_ACCES
}, /* 65 */
277 { ERROR_BAD_NET_NAME
, osl_File_E_NOENT
}, /* 67 */
278 { ERROR_FILE_EXISTS
, osl_File_E_EXIST
}, /* 80 */
279 { ERROR_CANNOT_MAKE
, osl_File_E_ACCES
}, /* 82 */
280 { ERROR_FAIL_I24
, osl_File_E_ACCES
}, /* 83 */
281 { ERROR_INVALID_PARAMETER
, osl_File_E_INVAL
}, /* 87 */
282 { ERROR_NO_PROC_SLOTS
, osl_File_E_AGAIN
}, /* 89 */
283 { ERROR_DRIVE_LOCKED
, osl_File_E_ACCES
}, /* 108 */
284 { ERROR_BROKEN_PIPE
, osl_File_E_PIPE
}, /* 109 */
285 { ERROR_DISK_FULL
, osl_File_E_NOSPC
}, /* 112 */
286 { ERROR_INVALID_TARGET_HANDLE
, osl_File_E_BADF
}, /* 114 */
287 { ERROR_INVALID_HANDLE
, osl_File_E_INVAL
}, /* 124 */
288 { ERROR_WAIT_NO_CHILDREN
, osl_File_E_CHILD
}, /* 128 */
289 { ERROR_CHILD_NOT_COMPLETE
, osl_File_E_CHILD
}, /* 129 */
290 { ERROR_DIRECT_ACCESS_HANDLE
, osl_File_E_BADF
}, /* 130 */
291 { ERROR_NEGATIVE_SEEK
, osl_File_E_INVAL
}, /* 131 */
292 { ERROR_SEEK_ON_DEVICE
, osl_File_E_ACCES
}, /* 132 */
293 { ERROR_DIR_NOT_EMPTY
, osl_File_E_NOTEMPTY
}, /* 145 */
294 { ERROR_NOT_LOCKED
, osl_File_E_ACCES
}, /* 158 */
295 { ERROR_BAD_PATHNAME
, osl_File_E_NOENT
}, /* 161 */
296 { ERROR_MAX_THRDS_REACHED
, osl_File_E_AGAIN
}, /* 164 */
297 { ERROR_LOCK_FAILED
, osl_File_E_ACCES
}, /* 167 */
298 { ERROR_ALREADY_EXISTS
, osl_File_E_EXIST
}, /* 183 */
299 { ERROR_FILENAME_EXCED_RANGE
, osl_File_E_NOENT
}, /* 206 */
300 { ERROR_NESTING_NOT_ALLOWED
, osl_File_E_AGAIN
}, /* 215 */
301 { ERROR_DIRECTORY
, osl_File_E_NOENT
}, /* 267 */
302 { ERROR_NOT_ENOUGH_QUOTA
, osl_File_E_NOMEM
}, /* 1816 */
303 { ERROR_UNEXP_NET_ERR
, osl_File_E_NETWORK
} /* 59 */
306 /* The following two constants must be the minimum and maximum
307 values in the (contiguous) range of osl_File_E_xec Failure errors. */
308 #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
309 #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
311 /* These are the low and high value in the range of errors that are
313 #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
314 #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
316 //#####################################################
317 oslFileError
MapError(DWORD dwError
)
319 for (int i
= 0; i
< ELEMENTS_OF_ARRAY(errtable
); ++i
)
321 if (dwError
== errtable
[i
].oscode
)
322 return static_cast<oslFileError
>(errtable
[i
].errnocode
);
325 /* The error code wasn't in the table. We check for a range of
326 osl_File_E_ACCES errors or exec failure errors (ENOEXEC).
327 Otherwise osl_File_E_INVAL is returned. */
328 if ( dwError
>= MIN_EACCES_RANGE
&& dwError
<= MAX_EACCES_RANGE
)
329 return osl_File_E_ACCES
;
330 else if ( dwError
>= MIN_EXEC_ERROR
&& dwError
<= MAX_EXEC_ERROR
)
331 return osl_File_E_NOEXEC
;
333 return osl_File_E_INVAL
;
336 //#####################################################
337 oslFileError SAL_CALL
osl_openLocalRoot(
338 rtl_uString
*strDirectoryPath
, oslDirectory
*pDirectory
)
340 rtl_uString
*strSysPath
= NULL
;
344 return osl_File_E_INVAL
;
348 error
= _osl_getSystemPathFromFileURL( strDirectoryPath
, &strSysPath
, sal_False
);
350 if ( osl_File_E_None
== error
)
352 Directory_Impl
*pDirImpl
;
354 pDirImpl
= reinterpret_cast<Directory_Impl
*>(rtl_allocateMemory( sizeof(Directory_Impl
)));
355 _tcscpy( pDirImpl
->szDirectoryPath
, reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(strSysPath
)) );
357 /* Append backslash if neccessary */
360 use function ensure backslash
362 if ( pDirImpl
->szDirectoryPath
[_tcslen(pDirImpl
->szDirectoryPath
) - 1] != L
'\\' )
363 _tcscat( pDirImpl
->szDirectoryPath
, L
"\\" );
365 pDirImpl
->uType
= DIRECTORYTYPE_LOCALROOT
;
366 pDirImpl
->hEnumDrives
= OpenLogicalDrivesEnum();
369 Use IsValidHandle(...)
371 if ( pDirImpl
->hEnumDrives
!= INVALID_HANDLE_VALUE
)
373 *pDirectory
= (oslDirectory
)pDirImpl
;
374 error
= osl_File_E_None
;
379 rtl_freeMemory(pDirImpl
);
381 error
= MapError( GetLastError() );
384 rtl_uString_release( strSysPath
);
389 //#####################################################
390 oslFileError SAL_CALL
osl_openFileDirectory(
391 rtl_uString
*strDirectoryPath
, oslDirectory
*pDirectory
)
393 // MT: Done in osl_openDirectory!
394 // rtl_uString *strSysPath = NULL;
397 //MT: Not done in osl_openNetworkServer, why here?
399 return osl_File_E_INVAL
;
403 // MT: Done in osl_openDirectory!
404 // error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysPath, sal_False );
405 // if ( osl_File_E_None == error )
407 Directory_Impl
*pDirImpl
;
409 pDirImpl
= reinterpret_cast<Directory_Impl
*>(rtl_allocateMemory(sizeof(Directory_Impl
)));
410 _tcscpy( pDirImpl
->szDirectoryPath
, reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(strDirectoryPath
)) );
412 /* Append backslash if neccessary */
415 use function ensure backslash
417 if ( pDirImpl
->szDirectoryPath
[_tcslen(pDirImpl
->szDirectoryPath
) - 1] != L
'\\' )
418 _tcscat( pDirImpl
->szDirectoryPath
, L
"\\" );
420 // GetCaseCorrectPathName( pDirImpl->szDirectoryPath, pDirImpl->szDirectoryPath, sizeof(pDirImpl->szDirectoryPath) );
422 pDirImpl
->uType
= DIRECTORYTYPE_FILESYSTEM
;
423 pDirImpl
->hDirectory
= OpenDirectory( pDirImpl
->szDirectoryPath
);
425 if ( pDirImpl
->hDirectory
)
427 *pDirectory
= (oslDirectory
)pDirImpl
;
428 error
= osl_File_E_None
;
433 rtl_freeMemory(pDirImpl
);
435 error
= MapError( GetLastError() );
438 // rtl_uString_release( strSysPath );
443 typedef struct tagDIRECTORY
446 WIN32_FIND_DATA aFirstData
;
447 } DIRECTORY
, *PDIRECTORY
, FAR
*LPDIRECTORY
;
449 //#####################################################
450 HANDLE WINAPI
OpenDirectory(LPCTSTR lpszPath
)
452 LPDIRECTORY pDirectory
= (LPDIRECTORY
)HeapAlloc(GetProcessHeap(), 0, sizeof(DIRECTORY
));
456 TCHAR szFileMask
[MAX_PATH
];
459 _tcscpy( szFileMask
, lpszPath
);
460 nLen
= _tcslen( szFileMask
);
462 if (nLen
&& szFileMask
[nLen
-1] != '\\')
463 _tcscat(szFileMask
, TEXT("\\*.*"));
465 _tcscat(szFileMask
, TEXT("*.*"));
467 pDirectory
->hFind
= FindFirstFile(szFileMask
, &pDirectory
->aFirstData
);
469 if (!IsValidHandle(pDirectory
->hFind
))
471 if ( GetLastError() != ERROR_NO_MORE_FILES
)
473 HeapFree(GetProcessHeap(), 0, pDirectory
);
478 return (HANDLE
)pDirectory
;
481 //#####################################################
482 BOOL WINAPI
CloseDirectory(HANDLE hDirectory
)
484 BOOL fSuccess
= FALSE
;
485 LPDIRECTORY pDirectory
= (LPDIRECTORY
)hDirectory
;
489 if (IsValidHandle(pDirectory
->hFind
))
490 fSuccess
= FindClose(pDirectory
->hFind
);
492 fSuccess
= HeapFree(GetProcessHeap(), 0, pDirectory
) && fSuccess
;
495 SetLastError(ERROR_INVALID_HANDLE
);
500 //#####################################################
501 BOOL WINAPI
EnumDirectory(HANDLE hDirectory
, LPWIN32_FIND_DATA pFindData
)
503 BOOL fSuccess
= FALSE
;
504 LPDIRECTORY pDirectory
= (LPDIRECTORY
)hDirectory
;
512 if ( pDirectory
->aFirstData
.cFileName
[0] )
514 *pFindData
= pDirectory
->aFirstData
;
516 pDirectory
->aFirstData
.cFileName
[0] = 0;
518 else if ( IsValidHandle( pDirectory
->hFind
) )
519 fSuccess
= FindNextFile( pDirectory
->hFind
, pFindData
);
523 SetLastError( ERROR_NO_MORE_FILES
);
526 fValid
= fSuccess
&& _tcscmp( TEXT("."), pFindData
->cFileName
) != 0 && _tcscmp( TEXT(".."), pFindData
->cFileName
) != 0;
528 } while( fSuccess
&& !fValid
);
531 SetLastError( ERROR_INVALID_HANDLE
);
536 //#####################################################
537 oslFileError SAL_CALL
osl_openNetworkServer(rtl_uString
*strSysDirPath
, oslDirectory
*pDirectory
)
539 NETRESOURCEW aNetResource
;
543 ZeroMemory( &aNetResource
, sizeof(aNetResource
) );
545 aNetResource
.lpRemoteName
= reinterpret_cast<LPWSTR
>(strSysDirPath
->buffer
);
547 dwError
= WNetOpenEnumW(
550 RESOURCEUSAGE_CONNECTABLE
| RESOURCEUSAGE_CONTAINER
,
554 if ( ERROR_SUCCESS
== dwError
)
556 Directory_Impl
*pDirImpl
;
558 pDirImpl
= reinterpret_cast<Directory_Impl
*>(rtl_allocateMemory(sizeof(Directory_Impl
)));
559 pDirImpl
->uType
= DIRECTORYTYPE_NETROOT
;
560 pDirImpl
->hDirectory
= hEnum
;
561 *pDirectory
= (oslDirectory
)pDirImpl
;
563 return MapError( dwError
);
566 //#####################################################
567 oslFileError SAL_CALL
osl_getNextNetResource(
568 oslDirectory Directory
,
569 oslDirectoryItem
*pItem
,
572 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
573 DirectoryItem_Impl
*pItemImpl
= NULL
;
575 LPNETRESOURCEW lpNetResource
= (LPNETRESOURCEW
)buffer
;
576 DWORD dwError
, dwCount
, dwBufSize
;
578 uHint
= uHint
; /* to get no warning */
581 return osl_File_E_INVAL
;
586 return osl_File_E_INVAL
;
589 dwBufSize
= sizeof(buffer
);
590 dwError
= WNetEnumResource( pDirImpl
->hDirectory
, &dwCount
, lpNetResource
, &dwBufSize
);
595 case ERROR_MORE_DATA
:
597 pItemImpl
= reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
599 return osl_File_E_NOMEM
;
601 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
602 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
603 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
605 wcscpy( pItemImpl
->cDriveString
, lpNetResource
->lpRemoteName
);
609 return osl_File_E_None
;
610 case ERROR_NO_MORE_ITEMS
:
611 return osl_File_E_NOENT
;
613 return MapError( dwError
);
617 //#####################################################
618 oslFileError SAL_CALL
osl_getNextDrive(
619 oslDirectory Directory
, oslDirectoryItem
*pItem
, sal_uInt32 uHint
)
621 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
622 DirectoryItem_Impl
*pItemImpl
= NULL
;
625 uHint
= uHint
; /* avoid warnings */
628 return osl_File_E_INVAL
;
633 return osl_File_E_INVAL
;
635 pItemImpl
= reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
637 return osl_File_E_NOMEM
;
640 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
641 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
642 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
643 fSuccess
= EnumLogicalDrives( pDirImpl
->hEnumDrives
, pItemImpl
->cDriveString
);
648 return osl_File_E_None
;
652 rtl_freeMemory( pItemImpl
);
653 return MapError( GetLastError() );
657 //#####################################################
658 oslFileError SAL_CALL
osl_getNextFileItem(
659 oslDirectory Directory
, oslDirectoryItem
*pItem
, sal_uInt32 uHint
)
661 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
662 DirectoryItem_Impl
*pItemImpl
= NULL
;
665 uHint
= uHint
; /* avoid warnings */
668 return osl_File_E_INVAL
;
673 return osl_File_E_INVAL
;
675 pItemImpl
= reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
677 return osl_File_E_NOMEM
;
679 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
680 fFound
= EnumDirectory( pDirImpl
->hDirectory
, &pItemImpl
->FindData
);
684 pItemImpl
->uType
= DIRECTORYITEM_FILE
;
685 pItemImpl
->nRefCount
= 1;
686 _tcscpy( pItemImpl
->szFullPath
, pDirImpl
->szDirectoryPath
);
687 _tcscat( pItemImpl
->szFullPath
, pItemImpl
->FindData
.cFileName
);
688 pItemImpl
->bFullPathNormalized
= FALSE
;
689 *pItem
= (oslDirectoryItem
)pItemImpl
;
690 return osl_File_E_None
;
694 rtl_freeMemory( pItemImpl
);
695 return MapError( GetLastError() );
699 //#####################################################
700 oslFileError SAL_CALL
osl_getDriveInfo(
701 oslDirectoryItem Item
, oslFileStatus
*pStatus
, sal_uInt32 uFieldMask
)
703 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
704 TCHAR cDrive
[3] = TEXT("A:");
705 TCHAR cRoot
[4] = TEXT("A:\\");
708 return osl_File_E_INVAL
;
710 pStatus
->uValidFields
= 0;
712 cDrive
[0] = pItemImpl
->cDriveString
[0];
713 cRoot
[0] = pItemImpl
->cDriveString
[0];
715 if ( uFieldMask
& osl_FileStatus_Mask_FileName
)
717 if ( pItemImpl
->cDriveString
[0] == '\\' &&
718 pItemImpl
->cDriveString
[1] == '\\' )
720 LPCWSTR lpFirstBkSlash
= wcschr( &pItemImpl
->cDriveString
[2], '\\' );
722 if ( lpFirstBkSlash
&& lpFirstBkSlash
[1] )
724 LPCWSTR lpLastBkSlash
= wcschr( &lpFirstBkSlash
[1], '\\' );
727 rtl_uString_newFromStr_WithLength( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(&lpFirstBkSlash
[1]), lpLastBkSlash
- lpFirstBkSlash
- 1 );
729 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(&lpFirstBkSlash
[1]) );
730 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
733 else switch ( GetDriveType( cRoot
) )
737 TCHAR szBuffer
[1024];
738 DWORD dwBufsize
= ELEMENTS_OF_ARRAY(szBuffer
);
739 DWORD dwResult
= WNetGetConnection( cDrive
, szBuffer
, &dwBufsize
);
741 if ( NO_ERROR
== dwResult
)
743 TCHAR szFileName
[ELEMENTS_OF_ARRAY(szBuffer
) + 16];
745 swprintf( szFileName
, L
"%s [%s]", cDrive
, szBuffer
);
746 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(szFileName
) );
749 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(cDrive
) );
751 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
755 TCHAR szVolumeNameBuffer
[1024];
757 if ( GetVolumeInformation( cRoot
, szVolumeNameBuffer
, ELEMENTS_OF_ARRAY(szVolumeNameBuffer
), NULL
, NULL
, NULL
, NULL
, 0 ) )
759 TCHAR szFileName
[ELEMENTS_OF_ARRAY(szVolumeNameBuffer
) + 16];
761 swprintf( szFileName
, L
"%s [%s]", cDrive
, szVolumeNameBuffer
);
762 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(szFileName
) );
765 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(cDrive
) );
767 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
770 case DRIVE_REMOVABLE
:
771 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
772 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(cRoot
) );
780 pStatus
->eType
= osl_File_Type_Volume
;
781 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
783 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
785 rtl_uString
*ustrSystemPath
= NULL
;
787 rtl_uString_newFromStr( &ustrSystemPath
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->cDriveString
) );
788 osl_getFileURLFromSystemPath( ustrSystemPath
, &pStatus
->ustrFileURL
);
789 rtl_uString_release( ustrSystemPath
);
790 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileURL
;
792 return osl_File_E_None
;
795 //#####################################################
796 oslFileError SAL_CALL
osl_getServerInfo(
797 oslDirectoryItem Item
, oslFileStatus
*pStatus
, sal_uInt32 uFieldMask
)
799 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
802 return osl_File_E_INVAL
;
804 pStatus
->uValidFields
= 0;
806 // pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
808 // if ( _tcscmp( pItemImpl->FindData.cFileName, TEXT(".") ) == 0 )
809 // rtl_uString_newFromAscii( &pStatus->ustrFileName, "/" );
811 // rtl_uString_newFromStr( &pStatus->ustrFileName, pItemImpl->FindData.cFileName );
813 pStatus
->eType
= osl_File_Type_Directory
;
814 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
816 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
818 rtl_uString
*ustrSystemPath
= NULL
;
820 rtl_uString_newFromStr( &ustrSystemPath
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->szFullPath
) );
821 osl_getFileURLFromSystemPath( ustrSystemPath
, &pStatus
->ustrFileURL
);
822 rtl_uString_release( ustrSystemPath
);
823 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileURL
;
825 return osl_File_E_None
;
828 typedef struct tagDRIVEENUM
{
830 TCHAR cBuffer
[/*('Z' - 'A' + 1) * sizeof("A:\\") + 1*/256];
832 } DRIVEENUM
, * PDRIVEENUM
, FAR
* LPDRIVEENUM
;
834 //#####################################################
835 HANDLE WINAPI
OpenLogicalDrivesEnum(void)
837 LPDRIVEENUM pEnum
= NULL
;
839 pEnum
= (LPDRIVEENUM
)HeapAlloc( GetProcessHeap(), 0, sizeof(DRIVEENUM
) );
843 DWORD dwNumCopied
= GetLogicalDriveStrings( (sizeof(pEnum
->cBuffer
) - 1) / sizeof(TCHAR
), pEnum
->cBuffer
);
845 if ( dwNumCopied
&& dwNumCopied
< sizeof(pEnum
->cBuffer
) / sizeof(TCHAR
) )
847 pEnum
->lpCurrent
= pEnum
->cBuffer
;
848 pEnum
->lpIdent
= L
"tagDRIVEENUM";
852 HeapFree( GetProcessHeap(), 0, pEnum
);
856 return pEnum
? (HANDLE
)pEnum
: INVALID_HANDLE_VALUE
;
859 //#####################################################
860 BOOL WINAPI
EnumLogicalDrives(HANDLE hEnum
, LPTSTR lpBuffer
)
862 BOOL fSuccess
= FALSE
;
863 LPDRIVEENUM pEnum
= (LPDRIVEENUM
)hEnum
;
867 int nLen
= _tcslen( pEnum
->lpCurrent
);
871 CopyMemory( lpBuffer
, pEnum
->lpCurrent
, (nLen
+ 1) * sizeof(TCHAR
) );
872 pEnum
->lpCurrent
+= nLen
+ 1;
876 SetLastError( ERROR_NO_MORE_FILES
);
879 SetLastError( ERROR_INVALID_HANDLE
);
884 //#####################################################
885 BOOL WINAPI
CloseLogicalDrivesEnum(HANDLE hEnum
)
887 BOOL fSuccess
= FALSE
;
888 LPDRIVEENUM pEnum
= (LPDRIVEENUM
)hEnum
;
892 HeapFree( GetProcessHeap(), 0, pEnum
);
896 SetLastError( ERROR_INVALID_HANDLE
);
901 //#####################################################
902 //Undocumented in SHELL32.DLL ordinal 35
903 BOOL WINAPI
PathRemoveFileSpec(LPTSTR lpPath
)
905 BOOL fSuccess
= FALSE
; // Assume failure
906 LPTSTR lpLastBkSlash
= _tcsrchr( lpPath
, '\\' );
907 LPTSTR lpLastSlash
= _tcsrchr( lpPath
, '/' );
908 LPTSTR lpLastDelimiter
= lpLastSlash
> lpLastBkSlash
? lpLastSlash
: lpLastBkSlash
;
910 if ( lpLastDelimiter
)
912 if ( 0 == *(lpLastDelimiter
+ 1) )
914 if ( lpLastDelimiter
> lpPath
&& *(lpLastDelimiter
- 1) != ':' )
916 *lpLastDelimiter
= 0;
922 *(++lpLastDelimiter
) = 0;
929 //#####################################################
930 // Undocumented in SHELL32.DLL ordinal 32
931 LPTSTR WINAPI
PathAddBackslash(LPTSTR lpPath
)
933 LPTSTR lpEndPath
= NULL
;
937 int nLen
= _tcslen(lpPath
);
939 if ( !nLen
|| lpPath
[nLen
-1] != '\\' && lpPath
[nLen
-1] != '/' && nLen
< MAX_PATH
- 1 )
941 lpEndPath
= lpPath
+ nLen
;
950 //#####################################################
951 // Same as GetLongPathName but also 95/NT4
952 DWORD WINAPI
GetCaseCorrectPathNameEx(
953 LPCTSTR lpszShortPath
, // file name
954 LPTSTR lpszLongPath
, // path buffer
955 DWORD cchBuffer
, // size of path buffer
959 // log file doesn't work, because initialization of rtl log init() calls this method...
960 // RTL_LOGFILE_TRACE1( "SAL: GetCaseCorrectPathNameEx: %s (Skip:%n)", lpszShortPath,nSkipLevels );
962 TCHAR szPath
[MAX_PATH
];
965 cchBuffer
= cchBuffer
; /* avoid warnings */
967 _tcscpy( szPath
, lpszShortPath
);
969 fSuccess
= PathRemoveFileSpec( szPath
);
973 int nLen
= _tcslen( szPath
);
974 LPCTSTR lpszFileSpec
= lpszShortPath
+ nLen
;
977 if ( 0 == _tcscmp( lpszFileSpec
, TEXT("..") ) )
983 0 == _tcscmp( lpszFileSpec
, TEXT(".") ) ||
984 0 == _tcscmp( lpszFileSpec
, TEXT("\\") ) ||
985 0 == _tcscmp( lpszFileSpec
, TEXT("/") )
990 else if ( nSkipLevels
)
998 GetCaseCorrectPathNameEx( szPath
, szPath
, MAX_PATH
, nSkipLevels
);
1000 PathAddBackslash( szPath
);
1002 /* Analyze parent if not only a trailing backslash was cutted but a real file spec */
1005 WIN32_FIND_DATA aFindFileData
;
1006 HANDLE hFind
= FindFirstFile( lpszShortPath
, &aFindFileData
);
1008 if ( IsValidHandle(hFind
) )
1010 _tcscat( szPath
, aFindFileData
.cFileName
[0] ? aFindFileData
.cFileName
: aFindFileData
.cAlternateFileName
);
1020 /* File specification can't be removed therefore the short path is either a drive
1021 or a network share. If still levels to skip are left, the path specification
1022 tries to travel below the file system root */
1029 _tcscpy( lpszLongPath
, szPath
);
1031 return _tcslen( lpszLongPath
);
1036 inline size_t wcstoupper( LPWSTR lpStr
)
1038 size_t nLen
= wcslen( lpStr
);
1040 for ( LPWSTR p
= lpStr
; p
< lpStr
+ nLen
; p
++ )
1050 //#####################################################
1051 DWORD WINAPI
GetCaseCorrectPathName(
1052 LPCTSTR lpszShortPath
, // file name
1053 LPTSTR lpszLongPath
, // path buffer
1054 DWORD cchBuffer
// size of path buffer
1058 /* Special handling for "\\.\" as system root */
1059 if ( lpszShortPath
&& 0 == wcscmp( lpszShortPath
, WSTR_SYSTEM_ROOT_PATH
) )
1061 if ( cchBuffer
>= ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH
) )
1063 wcscpy( lpszLongPath
, WSTR_SYSTEM_ROOT_PATH
);
1064 return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH
) - 1;
1067 return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH
);
1071 DWORD nSrcLen
= wcslen( lpszShortPath
);
1073 if ( cchBuffer
> nSrcLen
)
1075 wcscpy( lpszLongPath
, lpszShortPath
);
1076 wcstoupper( lpszLongPath
);
1086 /* Special handling for "\\.\" as system root */
1087 if ( lpszShortPath
&& 0 == wcscmp( lpszShortPath
, WSTR_SYSTEM_ROOT_PATH
) )
1089 if ( cchBuffer
>= ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH
) )
1091 wcscpy( lpszLongPath
, WSTR_SYSTEM_ROOT_PATH
);
1092 return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH
) - 1;
1095 return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH
) - 1;
1098 return GetCaseCorrectPathNameEx( lpszShortPath
, lpszLongPath
, cchBuffer
, 0 );
1103 //#####################################################
1104 #define CHARSET_SEPARATOR TEXT("\\/")
1106 BOOL WINAPI
IsValidFilePathComponent(
1107 LPCTSTR lpComponent
, LPCTSTR
*lppComponentEnd
, DWORD dwFlags
)
1109 LPCTSTR lpComponentEnd
= NULL
;
1110 LPCTSTR lpCurrent
= lpComponent
;
1111 BOOL fValid
= TRUE
; /* Assume success */
1114 /* Path component length must not exceed MAX_PATH */
1116 while ( !lpComponentEnd
&& lpCurrent
&& lpCurrent
- lpComponent
< MAX_PATH
)
1118 switch ( *lpCurrent
)
1120 /* Both backslash and slash determine the end of a path component */
1126 /* Component must not end with '.' or blank and can't be empty */
1129 if ( dwFlags
& VALIDATEPATH_ALLOW_ELLIPSE
)
1131 if ( (dwFlags
& VALIDATEPATH_ALLOW_INVALID_SPACE_AND_PERIOD
) ||
1132 1 == lpCurrent
- lpComponent
)
1134 /* Either do allow periods anywhere, or current directory */
1135 lpComponentEnd
= lpCurrent
;
1138 else if ( 2 == lpCurrent
- lpComponent
&& '.' == *lpComponent
)
1140 /* Parent directory is O.K. */
1141 lpComponentEnd
= lpCurrent
;
1147 if ( dwFlags
& VALIDATEPATH_ALLOW_INVALID_SPACE_AND_PERIOD
)
1148 lpComponentEnd
= lpCurrent
;
1151 lpComponentEnd
= lpCurrent
- 1;
1156 lpComponentEnd
= lpCurrent
;
1160 /* '?' and '*' are valid wildcards but not valid file name characters */
1163 if ( dwFlags
& VALIDATEPATH_ALLOW_WILDCARDS
)
1165 /* The following characters are reserved */
1171 lpComponentEnd
= lpCurrent
;
1175 /* Characters below ASCII 32 are not allowed */
1176 if ( *lpCurrent
< ' ' )
1178 lpComponentEnd
= lpCurrent
;
1183 cLast
= *lpCurrent
++;
1186 /* If we don't reached the end of the component the length of the component was to long
1187 ( See condition of while loop ) */
1188 if ( !lpComponentEnd
)
1191 lpComponentEnd
= lpCurrent
;
1194 /* Test wether the component specifies a device name what is not allowed */
1197 // This is very expensive. A lot of calls to _tcsicmp.
1198 // in SRC6870m71 67.000 calls of this method while empty office start result into more than 1.500.00 calls of _tcsicmp!
1199 // Possible optimizations
1200 // - Array should be const static
1201 // - Sorted array, use binary search
1202 // - More intelligent check for com1-9, lpt1-9
1203 // Maybe make szComponent upper case, don't search case intensitive
1204 // 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.
1208 LPCTSTR alpDeviceNames[] =
1235 TCHAR szComponent[MAX_PATH];
1236 int nComponentLength;
1240 // A device name with an extension is also invalid
1241 lpDot = _tcschr( lpComponent, '.' );
1243 if ( !lpDot || lpDot > lpComponentEnd )
1244 nComponentLength = lpComponentEnd - lpComponent;
1246 nComponentLength = lpDot - lpComponent;
1248 _tcsncpy( szComponent, lpComponent, nComponentLength );
1249 szComponent[nComponentLength] = 0;
1251 for ( i = 0; i < sizeof( alpDeviceNames ) / sizeof(LPCTSTR); i++ )
1253 if ( 0 == _tcsicmp( szComponent, alpDeviceNames[i] ) )
1255 lpComponentEnd = lpComponent;
1265 // Empty components are not allowed
1266 if ( lpComponentEnd
- lpComponent
< 1 )
1269 // If we reached the end of the string NULL is returned
1270 else if ( !*lpComponentEnd
)
1271 lpComponentEnd
= NULL
;
1275 if ( lppComponentEnd
)
1276 *lppComponentEnd
= lpComponentEnd
;
1281 //#####################################################
1282 DWORD WINAPI
IsValidFilePath(rtl_uString
*path
, LPCTSTR
*lppError
, DWORD dwFlags
, rtl_uString
**corrected
)
1284 LPCTSTR lpszPath
= reinterpret_cast< LPCTSTR
>(path
->buffer
);
1285 LPCTSTR lpComponent
;
1287 DWORD dwPathType
= PATHTYPE_ERROR
;
1289 if ( dwFlags
& VALIDATEPATH_ALLOW_RELATIVE
)
1290 dwFlags
|= VALIDATEPATH_ALLOW_ELLIPSE
;
1295 lpComponent
= lpszPath
;
1298 /* Test for UNC path notation */
1299 if ( 2 == _tcsspn( lpszPath
, CHARSET_SEPARATOR
) )
1301 /* Place the pointer behind the leading to backslashes */
1303 lpComponent
= lpszPath
+ 2;
1305 fValid
= IsValidFilePathComponent( lpComponent
, &lpComponent
, VALIDATEPATH_ALLOW_ELLIPSE
);
1307 /* So far we have a valid servername. Now let's see if we also have a network resource */
1309 dwPathType
= PATHTYPE_ABSOLUTE_UNC
;
1313 if ( lpComponent
&& !*++lpComponent
)
1319 /* We only have a Server specification what is invalid */
1321 lpComponent
= lpszPath
;
1324 dwPathType
|= PATHTYPE_IS_SERVER
;
1329 /* Now test the network resource */
1331 fValid
= IsValidFilePathComponent( lpComponent
, &lpComponent
, 0 );
1333 /* If we now reached the end of the path, everything is O.K. */
1336 if ( fValid
&& (!lpComponent
|| lpComponent
&& !*++lpComponent
) )
1339 dwPathType
|= PATHTYPE_IS_VOLUME
;
1345 /* Local path verification. Must start with <drive>: */
1346 else if ( _istalpha( lpszPath
[0] ) && ':' == lpszPath
[1] )
1348 /* Place pointer behind correct drive specification */
1350 lpComponent
= lpszPath
+ 2;
1352 if ( 1 == _tcsspn( lpComponent
, CHARSET_SEPARATOR
) )
1354 else if ( *lpComponent
)
1357 dwPathType
= PATHTYPE_ABSOLUTE_LOCAL
;
1359 /* Now we are behind the backslash or it was a simple drive without backslash */
1361 if ( fValid
&& !*lpComponent
)
1364 dwPathType
|= PATHTYPE_IS_VOLUME
;
1368 /* Can be a relative path */
1369 else if ( dwFlags
& VALIDATEPATH_ALLOW_RELATIVE
)
1371 lpComponent
= lpszPath
;
1373 /* Relative path can start with a backslash */
1375 if ( 1 == _tcsspn( lpComponent
, CHARSET_SEPARATOR
) )
1378 if ( !*lpComponent
)
1382 dwPathType
= PATHTYPE_RELATIVE
;
1385 /* Anything else is an error */
1389 lpComponent
= lpszPath
;
1392 /* Now validate each component of the path */
1393 while ( fValid
&& lpComponent
)
1395 // Correct path by merging consecutive slashes:
1396 if (*lpComponent
== '\\' && corrected
!= NULL
) {
1397 sal_Int32 i
= lpComponent
- lpszPath
;
1398 rtl_uString_newReplaceStrAt(corrected
, path
, i
, 1, NULL
);
1399 //TODO: handle out-of-memory
1400 lpszPath
= reinterpret_cast< LPCTSTR
>((*corrected
)->buffer
);
1401 lpComponent
= lpszPath
+ i
;
1404 fValid
= IsValidFilePathComponent( lpComponent
, &lpComponent
, dwFlags
| VALIDATEPATH_ALLOW_INVALID_SPACE_AND_PERIOD
);
1406 if ( fValid
&& lpComponent
)
1410 /* If the string behind the backslash is empty, we've done */
1412 if ( !*lpComponent
)
1417 if ( fValid
&& _tcslen( lpszPath
) >= MAX_PATH
)
1420 lpComponent
= lpszPath
+ MAX_PATH
;
1424 *lppError
= lpComponent
;
1426 return fValid
? dwPathType
: PATHTYPE_ERROR
;
1429 //#####################################################
1430 bool is_floppy_drive(const rtl::OUString
& path
);
1432 //#####################################################
1439 bool isPresent() const
1440 { return (static_cast<sal_Int32
>(end_
- begin_
) > 0); }
1442 const sal_Unicode
* begin_
;
1443 const sal_Unicode
* end_
;
1446 //#####################################################
1447 struct UNCComponents
1451 Component resource_
;
1454 //#####################################################
1455 const wchar_t UNC_PREFIX
[] = L
"\\\\";
1456 const wchar_t BACKSLASH
= '\\';
1457 const wchar_t SLASH
= '/';
1459 bool is_UNC_path(const sal_Unicode
* path
)
1460 { return (0 == wcsncmp(UNC_PREFIX
, reinterpret_cast<LPCWSTR
>(path
), ELEMENTS_OF_ARRAY(UNC_PREFIX
) - 1)); }
1462 //#####################################################
1463 bool is_UNC_path(const rtl::OUString
& path
)
1464 { return is_UNC_path(path
.getStr()); }
1466 //#####################################################
1467 void parse_UNC_path(const sal_Unicode
* path
, UNCComponents
* puncc
)
1469 OSL_PRECOND(is_UNC_path(path
), "Precondition violated: No UNC path");
1470 OSL_PRECOND(rtl_ustr_indexOfChar(path
, SLASH
) != -1, "Path must not contain slashes");
1472 const sal_Unicode
* pend
= path
+ rtl_ustr_getLength(path
);
1473 const sal_Unicode
* ppos
= path
+ 2;
1475 puncc
->server_
.begin_
= ppos
;
1476 while ((ppos
< pend
) && (*ppos
!= BACKSLASH
))
1479 puncc
->server_
.end_
= ppos
;
1481 if (BACKSLASH
== *ppos
)
1483 puncc
->share_
.begin_
= ++ppos
;
1484 while ((ppos
< pend
) && (*ppos
!= BACKSLASH
))
1487 puncc
->share_
.end_
= ppos
;
1489 if (BACKSLASH
== *ppos
)
1491 puncc
->resource_
.begin_
= ++ppos
;
1495 puncc
->resource_
.end_
= ppos
;
1499 OSL_POSTCOND(puncc
->server_
.isPresent() && puncc
->share_
.isPresent(), \
1500 "Postcondition violated: Invalid UNC path detected");
1503 //#####################################################
1504 void parse_UNC_path(const rtl::OUString
& path
, UNCComponents
* puncc
)
1505 { parse_UNC_path(path
.getStr(), puncc
); }
1507 //#####################################################
1508 bool is_volume_mount_point(const rtl::OUString
& path
)
1510 rtl::OUString
p(path
);
1511 osl::systemPathRemoveSeparator(p
);
1513 bool is_volume_root
= false;
1515 if (!is_floppy_drive(p
))
1517 DWORD fattr
= GetFileAttributes(reinterpret_cast<LPCTSTR
>(p
.getStr()));
1519 if ((INVALID_FILE_ATTRIBUTES
!= fattr
) &&
1520 (FILE_ATTRIBUTE_REPARSE_POINT
& fattr
))
1522 WIN32_FIND_DATA find_data
;
1523 HANDLE h_find
= FindFirstFile(reinterpret_cast<LPCTSTR
>(p
.getStr()), &find_data
);
1525 if (IsValidHandle(h_find
) &&
1526 (FILE_ATTRIBUTE_REPARSE_POINT
& find_data
.dwFileAttributes
) &&
1527 (IO_REPARSE_TAG_MOUNT_POINT
== find_data
.dwReserved0
))
1529 is_volume_root
= true;
1531 if (IsValidHandle(h_find
))
1535 return is_volume_root
;
1538 //#####################################################
1539 // Has the given path a parent or are we already there,
1540 // e.g. 'c:\' or '\\server\share\'?
1541 bool has_path_parent(const sal_Unicode
* path
)
1543 bool has_parent
= false;
1545 if (is_UNC_path(path
))
1547 UNCComponents unc_comp
;
1548 parse_UNC_path(path
, &unc_comp
);
1549 has_parent
= unc_comp
.resource_
.isPresent();
1553 has_parent
= !osl::systemPathIsLogicalDrivePattern(path
);
1558 //#####################################################
1559 // @see bool has_path_parent(const sal_Unicode* path)
1560 bool has_path_parent(const rtl::OUString
& path
)
1561 { return has_path_parent(path
.getStr()); }
1563 //#####################################################
1564 bool path_get_parent(rtl::OUString
& path
)
1566 OSL_PRECOND(path
.lastIndexOf(SLASH
) == -1, "Path must not have slashes");
1568 if (!has_path_parent(path
))
1570 sal_Int32 i
= path
.lastIndexOf(BACKSLASH
);
1573 path
= rtl::OUString(path
.getStr(), i
);
1580 //#############################################
1581 /* Cut off the last part of the given path to
1582 get the parent only, e.g. 'c:\dir\subdir' ->
1583 'c:\dir' or '\\share\sub\dir' -> '\\share\sub'
1584 @return The position where the path has been cut
1585 off (this is the posistion of the last backslash).
1586 If there are no more parents 0 will be returned,
1587 e.g. 'c:\' or '\\Share' have no more parents */
1588 int path_make_parent(sal_Unicode
* path
)
1590 OSL_PRECOND(rtl_ustr_indexOfChar(path
, SLASH
) != -1, "Path must not contain slashes");
1591 OSL_PRECOND(has_path_parent(path
), "Path must have a parent");
1593 sal_Unicode
* pos_last_backslash
= path
+ rtl_ustr_lastIndexOfChar(path
, BACKSLASH
);
1594 *pos_last_backslash
= 0;
1595 return (pos_last_backslash
- path
);
1598 //#####################################################
1599 void path_travel_to_volume_root(const rtl::OUString
& system_path
, rtl::OUString
& volume_root
)
1601 rtl::OUString
sys_path(system_path
);
1603 while(!is_volume_mount_point(sys_path
) && path_get_parent(sys_path
))
1606 volume_root
= sys_path
;
1607 osl_systemPathEnsureSeparator(&volume_root
.pData
);
1610 //#####################################################
1611 inline bool is_floppy_A_present()
1612 { return (GetLogicalDrives() & 1); }
1614 //#####################################################
1615 inline bool is_floppy_B_present()
1616 { return (GetLogicalDrives() & 2); }
1618 //#####################################################
1619 // determines if a volume mount point shows to a floppy
1620 // disk by comparing the unique volume names
1621 const LPWSTR FLOPPY_A
= L
"A:\\";
1622 const LPWSTR FLOPPY_B
= L
"B:\\";
1624 bool is_floppy_volume_mount_point(const rtl::OUString
& path
)
1626 rtl::OUString
p(path
);
1627 osl_systemPathEnsureSeparator(&p
.pData
);
1630 if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR
>(p
.getStr()), vn
, ELEMENTS_OF_ARRAY(vn
)))
1633 if (is_floppy_A_present() &&
1634 GetVolumeNameForVolumeMountPoint(FLOPPY_A
, vnfloppy
, ELEMENTS_OF_ARRAY(vnfloppy
)) &&
1635 (0 == wcscmp(vn
, vnfloppy
)))
1638 if (is_floppy_B_present() &&
1639 GetVolumeNameForVolumeMountPoint(FLOPPY_B
, vnfloppy
, ELEMENTS_OF_ARRAY(vnfloppy
)) &&
1640 (0 == wcscmp(vn
, vnfloppy
)))
1646 //################################################
1647 // we must take into account that even a floppy
1648 // drive may be mounted to a directory so checking
1649 // for the drive letter alone is not sufficient
1650 // we must compare the unique volume name with
1651 // that of the available floppy disks
1652 LPCWSTR FLOPPY_DRV_LETTERS
= TEXT("AaBb");
1654 bool is_floppy_drive(const rtl::OUString
& path
)
1656 const sal_Unicode
* pf
= path
.getStr();
1657 const sal_Unicode
* ps
= path
.getStr() + 1;
1658 return ((wcschr(FLOPPY_DRV_LETTERS
, *pf
) && (L
':' == *ps
)) ||
1659 is_floppy_volume_mount_point(path
));
1662 //#############################################
1663 UINT
get_volume_mount_point_drive_type(const rtl::OUString
& path
)
1665 if (0 == path
.getLength())
1666 return GetDriveType(NULL
);
1668 rtl::OUString
p(path
);
1669 osl_systemPathEnsureSeparator(&p
.pData
);
1672 if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR
>(p
.getStr()), vn
, ELEMENTS_OF_ARRAY(vn
)))
1673 return GetDriveType(vn
);
1675 return DRIVE_NO_ROOT_DIR
;
1678 //#############################################
1679 oslFileError
osl_get_drive_type(const rtl::OUString
& path
, oslVolumeInfo
* pInfo
)
1681 // GetDriveType fails on empty volume mount points
1682 // see Knowledge Base Q244089
1684 if (is_volume_mount_point(path
))
1685 drive_type
= get_volume_mount_point_drive_type(path
);
1687 drive_type
= GetDriveType(reinterpret_cast<LPCTSTR
>(path
.getStr()));
1689 if (DRIVE_NO_ROOT_DIR
== drive_type
)
1690 return MapError(ERROR_INVALID_DRIVE
);
1692 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1697 pInfo
->uAttributes
|= osl_Volume_Attribute_CompactDisc
| osl_Volume_Attribute_Removeable
;
1699 case DRIVE_REMOVABLE
:
1700 pInfo
->uAttributes
|= osl_Volume_Attribute_Removeable
;
1701 if (is_floppy_drive(path
))
1702 pInfo
->uAttributes
|= osl_Volume_Attribute_FloppyDisk
;
1705 pInfo
->uAttributes
|= osl_Volume_Attribute_FixedDisk
;
1708 pInfo
->uAttributes
|= osl_Volume_Attribute_RAMDisk
;
1711 pInfo
->uAttributes
|= osl_Volume_Attribute_Remote
;
1714 pInfo
->uAttributes
= 0;
1717 pInfo
->uValidFields
&= ~osl_VolumeInfo_Mask_Attributes
;
1718 pInfo
->uAttributes
= 0;
1721 return osl_File_E_None
;
1724 //#############################################
1725 inline bool is_volume_space_info_request(sal_uInt32 field_mask
)
1727 return (field_mask
&
1728 (osl_VolumeInfo_Mask_TotalSpace
|
1729 osl_VolumeInfo_Mask_UsedSpace
|
1730 osl_VolumeInfo_Mask_FreeSpace
));
1733 //#############################################
1734 void get_volume_space_information(const rtl::OUString
& path
, oslVolumeInfo
*pInfo
)
1736 BOOL ret
= GetDiskFreeSpaceEx(
1737 reinterpret_cast<LPCTSTR
>(path
.getStr()),
1738 (PULARGE_INTEGER
)&pInfo
->uFreeSpace
,
1739 (PULARGE_INTEGER
)&pInfo
->uTotalSpace
,
1744 pInfo
->uUsedSpace
= pInfo
->uTotalSpace
- pInfo
->uFreeSpace
;
1745 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_TotalSpace
|
1746 osl_VolumeInfo_Mask_UsedSpace
|
1747 osl_VolumeInfo_Mask_FreeSpace
;
1751 //#############################################
1752 inline bool is_filesystem_attributes_request(sal_uInt32 field_mask
)
1754 return (field_mask
&
1755 (osl_VolumeInfo_Mask_MaxNameLength
|
1756 osl_VolumeInfo_Mask_MaxPathLength
|
1757 osl_VolumeInfo_Mask_FileSystemName
|
1758 osl_VolumeInfo_Mask_FileSystemCaseHandling
));
1761 //#############################################
1762 inline bool is_drivetype_request(sal_uInt32 field_mask
)
1764 return (field_mask
& osl_VolumeInfo_Mask_Attributes
);
1767 //#############################################
1768 oslFileError
get_filesystem_attributes(const rtl::OUString
& path
, sal_uInt32 field_mask
, oslVolumeInfo
* pInfo
)
1770 pInfo
->uAttributes
= 0;
1772 oslFileError osl_error
= osl_File_E_None
;
1774 // osl_get_drive_type must be called first because
1775 // this function resets osl_VolumeInfo_Mask_Attributes
1777 if (is_drivetype_request(field_mask
))
1778 osl_error
= osl_get_drive_type(path
, pInfo
);
1780 if ((osl_File_E_None
== osl_error
) && is_filesystem_attributes_request(field_mask
))
1783 WCHAR fsn
[MAX_PATH
];
1788 if (GetVolumeInformation(reinterpret_cast<LPCTSTR
>(path
.getStr()), vn
, MAX_PATH
, &serial
, &mcl
, &flags
, fsn
, MAX_PATH
))
1790 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxNameLength
;
1791 pInfo
->uMaxNameLength
= mcl
;
1793 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxPathLength
;
1794 pInfo
->uMaxPathLength
= MAX_PATH
;
1796 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FileSystemName
;
1797 rtl_uString_newFromStr(&pInfo
->ustrFileSystemName
, reinterpret_cast<const sal_Unicode
*>(fsn
));
1799 // volumes (even NTFS) will always be considered case
1800 // insensitive because the Win32 API is not able to
1801 // deal with case sensitive volumes see M$ Knowledge Base
1802 // article 100625 that's why we never set the attribute
1803 // osl_Volume_Attribute_Case_Sensitive
1805 if (flags
& FS_CASE_IS_PRESERVED
)
1806 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Is_Preserved
;
1808 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1814 //#############################################
1815 // Create the specified directory and call the
1816 // user specified callback function. On success
1817 // the function returns ERROR_SUCCESS else a
1818 // Win32 error code.
1819 DWORD
create_dir_with_callback(
1820 sal_Unicode
* dir_path
,
1821 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1824 if (CreateDirectory(reinterpret_cast<LPCTSTR
>(dir_path
), NULL
))
1826 if (aDirectoryCreationCallbackFunc
)
1829 FileBase::getFileURLFromSystemPath(dir_path
, url
);
1830 aDirectoryCreationCallbackFunc(pData
, url
.pData
);
1832 return ERROR_SUCCESS
;
1834 return GetLastError();
1837 //#############################################
1838 DWORD
create_dir_recursively_(
1839 sal_Unicode
* dir_path
,
1840 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1843 OSL_PRECOND(rtl_ustr_getLength(dir_path
) > 0 && (rtl_ustr_lastIndexOfChar(dir_path
, BACKSLASH
) != rtl_ustr_getLength(dir_path
) - 1), \
1844 "Path must not end with a backslash");
1846 DWORD w32_error
= create_dir_with_callback(
1847 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1849 if (w32_error
== ERROR_SUCCESS
)
1850 return ERROR_SUCCESS
;
1852 if ((w32_error
!= ERROR_PATH_NOT_FOUND
) || !has_path_parent(dir_path
))
1855 int pos
= path_make_parent(dir_path
);
1857 w32_error
= create_dir_recursively_(
1858 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1860 if (ERROR_SUCCESS
!= w32_error
)
1863 dir_path
[pos
] = BACKSLASH
;
1865 return create_dir_recursively_(
1866 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1869 //#####################################################
1871 //#####################################################
1874 //#####################################################
1875 oslFileError
osl_setup_base_directory_impl_(
1876 rtl_uString
* pustrDirectoryURL
,
1877 rtl_uString
** ppustr_base_dir
)
1879 rtl_uString
* dir_url
= 0;
1880 rtl_uString
* dir
= 0;
1881 oslFileError error
= osl_File_E_None
;
1883 if (pustrDirectoryURL
)
1884 rtl_uString_assign(&dir_url
, pustrDirectoryURL
);
1886 error
= osl_getTempDirURL(&dir_url
);
1888 if (osl_File_E_None
== error
)
1890 error
= _osl_getSystemPathFromFileURL(dir_url
, &dir
, sal_False
);
1891 rtl_uString_release(dir_url
);
1894 if (osl_File_E_None
== error
)
1896 rtl_uString_assign(ppustr_base_dir
, dir
);
1897 rtl_uString_release(dir
);
1903 //#####################################################
1904 oslFileError
osl_setup_createTempFile_impl_(
1905 rtl_uString
* pustrDirectoryURL
,
1906 oslFileHandle
* pHandle
,
1907 rtl_uString
** ppustrTempFileURL
,
1908 rtl_uString
** ppustr_base_dir
,
1909 sal_Bool
* b_delete_on_close
)
1911 oslFileError osl_error
;
1913 OSL_PRECOND(((0 != pHandle
) || (0 != ppustrTempFileURL
)), "Invalid parameter!");
1915 if ((0 == pHandle
) && (0 == ppustrTempFileURL
))
1917 osl_error
= osl_File_E_INVAL
;
1921 osl_error
= osl_setup_base_directory_impl_(
1922 pustrDirectoryURL
, ppustr_base_dir
);
1924 *b_delete_on_close
= (sal_Bool
)(0 == ppustrTempFileURL
);
1930 //#####################################################
1931 oslFileError
osl_win32_GetTempFileName_impl_(
1932 rtl_uString
* base_directory
, LPWSTR temp_file_name
)
1934 oslFileError osl_error
= osl_File_E_None
;
1936 if (0 == GetTempFileNameW(
1937 reinterpret_cast<LPCWSTR
>(rtl_uString_getStr(base_directory
)),
1942 osl_error
= MapError(GetLastError());
1948 //#####################################################
1949 sal_Bool
osl_win32_CreateFile_impl_(
1950 LPCWSTR file_name
, sal_Bool b_delete_on_close
, oslFileHandle
* p_handle
)
1952 DWORD flags
= FILE_ATTRIBUTE_NORMAL
;
1955 OSL_ASSERT(p_handle
);
1957 if (b_delete_on_close
)
1958 flags
|= FILE_FLAG_DELETE_ON_CLOSE
;
1960 hFile
= CreateFileW(
1962 GENERIC_READ
| GENERIC_WRITE
,
1969 if (IsValidHandle(hFile
))
1970 *p_handle
= (oslFileHandle
)hFile
;
1972 return (sal_Bool
)IsValidHandle(hFile
);
1975 //#############################################
1976 oslFileError
osl_createTempFile_impl_(
1977 rtl_uString
* base_directory
,
1979 sal_Bool b_delete_on_close
,
1980 oslFileHandle
* pHandle
,
1981 rtl_uString
** ppustrTempFileURL
)
1983 oslFileError osl_error
;
1987 osl_error
= osl_win32_GetTempFileName_impl_(base_directory
, tmp_name
);
1989 /* if file could not be opened try again */
1991 if ((osl_File_E_None
!= osl_error
) || (0 == pHandle
) ||
1992 osl_win32_CreateFile_impl_(tmp_name
, b_delete_on_close
, pHandle
))
1995 } while(1); // try until success
1997 if ((osl_File_E_None
== osl_error
) && !b_delete_on_close
)
1999 rtl_uString
* pustr
= 0;
2000 rtl_uString_newFromStr(&pustr
, reinterpret_cast<const sal_Unicode
*>(tmp_name
));
2001 osl_getFileURLFromSystemPath(pustr
, ppustrTempFileURL
);
2002 rtl_uString_release(pustr
);
2008 //#####################################################
2010 //#####################################################
2013 //#############################################
2014 sal_Bool
_osl_decodeURL( rtl_String
* strUTF8
, rtl_uString
** pstrDecodedURL
)
2017 const sal_Char
*pSrcEnd
;
2018 const sal_Char
*pSrc
;
2021 sal_Bool bValidEncoded
= sal_True
; /* Assume success */
2023 /* The resulting decoded string length is shorter or equal to the source length */
2025 nSrcLen
= rtl_string_getLength(strUTF8
);
2026 pBuffer
= reinterpret_cast<sal_Char
*>(rtl_allocateMemory(nSrcLen
+ 1));
2029 pSrc
= rtl_string_getStr(strUTF8
);
2030 pSrcEnd
= pSrc
+ nSrcLen
;
2032 /* Now decode the URL what should result in an UTF8 string */
2033 while ( bValidEncoded
&& pSrc
< pSrcEnd
)
2043 aToken
[0] = *pSrc
++;
2044 aToken
[1] = *pSrc
++;
2047 aChar
= (sal_Char
)strtoul( aToken
, NULL
, 16 );
2049 /* The chars are path delimiters and must not be encoded */
2051 if ( 0 == aChar
|| '\\' == aChar
|| '/' == aChar
|| ':' == aChar
)
2052 bValidEncoded
= sal_False
;
2065 if ( bValidEncoded
) {
2066 rtl_string2UString( pstrDecodedURL
, pBuffer
, rtl_str_getLength(pBuffer
), RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
2067 OSL_ASSERT(*pstrDecodedURL
!= 0);
2070 rtl_freeMemory( pBuffer
);
2072 return bValidEncoded
;
2075 //#############################################
2076 void _osl_encodeURL( rtl_uString
*strURL
, rtl_String
**pstrEncodedURL
)
2078 /* Encode non ascii characters within the URL */
2080 rtl_String
*strUTF8
= NULL
;
2081 sal_Char
*pszEncodedURL
;
2082 const sal_Char
*pURLScan
;
2084 sal_Int32 nURLScanLen
;
2085 sal_Int32 nURLScanCount
;
2087 rtl_uString2String( &strUTF8
, rtl_uString_getStr( strURL
), rtl_uString_getLength( strURL
), RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
2089 pszEncodedURL
= (sal_Char
*) rtl_allocateMemory( (rtl_string_getLength( strUTF8
) * 3 + 1) * sizeof(sal_Char
) );
2091 pURLDest
= pszEncodedURL
;
2092 pURLScan
= rtl_string_getStr( strUTF8
);
2093 nURLScanLen
= rtl_string_getLength( strUTF8
);
2096 while ( nURLScanCount
< nURLScanLen
)
2098 sal_Char cCurrent
= *pURLScan
;
2103 if (!( ( cCurrent
>= 'a' && cCurrent
<= 'z' ) || ( cCurrent
>= 'A' && cCurrent
<= 'Z' ) || ( cCurrent
>= '0' && cCurrent
<= '9' ) ) )
2105 sprintf( pURLDest
, "%%%02X", (unsigned char)cCurrent
);
2128 *pURLDest
++ = cCurrent
;
2141 rtl_string_release( strUTF8
);
2142 rtl_string_newFromStr( pstrEncodedURL
, pszEncodedURL
);
2143 rtl_freeMemory( pszEncodedURL
);
2146 //#############################################
2147 oslFileError SAL_CALL
_osl_getSystemPathFromFileURL( rtl_uString
*strURL
, rtl_uString
**pustrPath
, sal_Bool bAllowRelative
)
2149 rtl_String
*strUTF8
= NULL
;
2150 rtl_uString
*strDecodedURL
= NULL
;
2151 rtl_uString
*strTempPath
= NULL
;
2152 const sal_Unicode
*pDecodedURL
;
2153 sal_uInt32 nDecodedLen
;
2154 sal_Bool bValidEncoded
;
2155 oslFileError nError
= osl_File_E_INVAL
; /* Assume failure */
2157 /* If someone hasn't encoded the complete URL we convert it to UTF8 now to prevent from
2158 having a mixed encoded URL later */
2160 rtl_uString2String( &strUTF8
, rtl_uString_getStr( strURL
), rtl_uString_getLength( strURL
), RTL_TEXTENCODING_UTF8
, OUSTRING_TO_OSTRING_CVTFLAGS
);
2162 /* If the length of strUTF8 and strURL differs it indicates that the URL was not correct encoded */
2165 strUTF8
->length
== strURL
->length
||
2166 0 != rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( strURL
->buffer
, strURL
->length
, "file:\\\\", 7 )
2167 ,"osl_getSystemPathFromFileURL: \"%s\" is not encoded !!!", strURL
);
2169 bValidEncoded
= _osl_decodeURL( strUTF8
, &strDecodedURL
);
2171 /* Release the encoded UTF8 string */
2173 rtl_string_release( strUTF8
);
2176 if ( bValidEncoded
)
2178 /* Replace backslashes and pipes */
2180 rtl_uString_newReplace( &strDecodedURL
, strDecodedURL
, '/', '\\' );
2181 rtl_uString_newReplace( &strDecodedURL
, strDecodedURL
, '|', ':' );
2183 pDecodedURL
= rtl_uString_getStr( strDecodedURL
);
2184 nDecodedLen
= rtl_uString_getLength( strDecodedURL
);
2186 /* Must start with "file://" */
2188 if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL
, nDecodedLen
, "file:\\\\", 7 ) )
2192 if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL
, nDecodedLen
, "file:\\\\\\", 8 ) )
2195 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL
, nDecodedLen
, "file:\\\\localhost\\", 17 ) ||
2196 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL
, nDecodedLen
, "file:\\\\127.0.0.1\\", 17 )
2202 /* Indicates local root */
2203 if ( nDecodedLen
== nSkip
)
2204 rtl_uString_newFromStr_WithLength( &strTempPath
, reinterpret_cast<const sal_Unicode
*>(WSTR_SYSTEM_ROOT_PATH
), ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH
) - 1 );
2206 rtl_uString_newFromStr_WithLength( &strTempPath
, pDecodedURL
+ nSkip
, nDecodedLen
- nSkip
);
2208 if ( IsValidFilePath( strTempPath
, NULL
, VALIDATEPATH_ALLOW_ELLIPSE
, &strTempPath
) )
2209 nError
= osl_File_E_None
;
2211 else if ( bAllowRelative
) /* This maybe a relative file URL */
2213 rtl_uString_assign( &strTempPath
, strDecodedURL
);
2215 if ( IsValidFilePath( strTempPath
, NULL
, VALIDATEPATH_ALLOW_RELATIVE
| VALIDATEPATH_ALLOW_ELLIPSE
, &strTempPath
) )
2216 nError
= osl_File_E_None
;
2220 OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not an absolute FileURL !!!", strURL );
2225 if ( strDecodedURL
)
2226 rtl_uString_release( strDecodedURL
);
2228 if ( osl_File_E_None
== nError
)
2229 rtl_uString_assign( pustrPath
, strTempPath
);
2232 rtl_uString_release( strTempPath
);
2235 OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not a FileURL !!!", strURL );
2241 //#############################################
2242 oslFileError SAL_CALL
_osl_getFileURLFromSystemPath( rtl_uString
* strPath
, rtl_uString
** pstrURL
)
2244 oslFileError nError
= osl_File_E_INVAL
; /* Assume failure */
2245 rtl_uString
*strTempURL
= NULL
;
2246 DWORD dwPathType
= PATHTYPE_ERROR
;
2249 dwPathType
= IsValidFilePath(strPath
, NULL
, VALIDATEPATH_ALLOW_RELATIVE
, NULL
);
2253 rtl_uString
*strTempPath
= NULL
;
2255 /* Replace backslashes */
2257 rtl_uString_newReplace( &strTempPath
, strPath
, '\\', '/' );
2259 switch ( dwPathType
& PATHTYPE_MASK_TYPE
)
2261 case PATHTYPE_RELATIVE
:
2262 rtl_uString_assign( &strTempURL
, strTempPath
);
2263 nError
= osl_File_E_None
;
2265 case PATHTYPE_ABSOLUTE_UNC
:
2266 rtl_uString_newFromAscii( &strTempURL
, "file:" );
2267 rtl_uString_newConcat( &strTempURL
, strTempURL
, strTempPath
);
2268 nError
= osl_File_E_None
;
2270 case PATHTYPE_ABSOLUTE_LOCAL
:
2271 rtl_uString_newFromAscii( &strTempURL
, "file:///" );
2272 rtl_uString_newConcat( &strTempURL
, strTempURL
, strTempPath
);
2273 nError
= osl_File_E_None
;
2279 /* Release temp path */
2281 rtl_uString_release( strTempPath
);
2284 if ( osl_File_E_None
== nError
)
2286 rtl_String
*strEncodedURL
= NULL
;
2288 /* Encode the URL */
2290 _osl_encodeURL( strTempURL
, &strEncodedURL
);
2292 /* Provide URL via unicode string */
2294 rtl_string2UString( pstrURL
, rtl_string_getStr(strEncodedURL
), rtl_string_getLength(strEncodedURL
), RTL_TEXTENCODING_ASCII_US
, OUSTRING_TO_OSTRING_CVTFLAGS
);
2295 OSL_ASSERT(*pstrURL
!= 0);
2296 rtl_string_release( strEncodedURL
);
2299 /* Release temp URL */
2302 rtl_uString_release( strTempURL
);
2305 OSL_ENSURE_FILE( !nError, "osl_getFileURLFromSystemPath: \"%s\" is not a systemPath !!!", strPath );
2311 #if OSL_DEBUG_LEVEL > 0
2313 //#####################################################
2314 void _osl_warnFile( const char *message
, rtl_uString
*ustrFile
)
2316 char szBuffer
[2048];
2320 rtl_String
*strFile
= NULL
;
2322 rtl_uString2String( &strFile
, rtl_uString_getStr( ustrFile
), rtl_uString_getLength( ustrFile
), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
);
2323 snprintf( szBuffer
, sizeof(szBuffer
), message
, strFile
->buffer
);
2324 rtl_string_release( strFile
);
2328 OSL_ENSURE( 0, message
);
2331 #endif // OSL_DEBUG_LEVEL > 0
2333 } // end namespace private
2336 //#####################################################
2338 //#####################################################
2341 //#############################################
2342 oslFileError SAL_CALL
osl_getVolumeInformation(
2343 rtl_uString
*ustrURL
, oslVolumeInfo
*pInfo
, sal_uInt32 uFieldMask
)
2346 return osl_File_E_INVAL
;
2348 rtl::OUString system_path
;
2349 oslFileError error
= _osl_getSystemPathFromFileURL(ustrURL
, &system_path
.pData
, sal_False
);
2351 if (osl_File_E_None
!= error
)
2354 rtl::OUString volume_root
;
2355 path_travel_to_volume_root(system_path
, volume_root
);
2357 pInfo
->uValidFields
= 0;
2359 if ((error
= get_filesystem_attributes(volume_root
, uFieldMask
, pInfo
)) != osl_File_E_None
)
2362 if (is_volume_space_info_request(uFieldMask
))
2363 get_volume_space_information(volume_root
, pInfo
);
2365 if (uFieldMask
& osl_VolumeInfo_Mask_DeviceHandle
)
2367 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_DeviceHandle
;
2368 osl_getFileURLFromSystemPath(volume_root
.pData
, (rtl_uString
**)&pInfo
->pDeviceHandle
);
2371 return osl_File_E_None
;
2375 //#############################################
2376 oslFileError SAL_CALL
osl_createDirectoryPath(
2377 rtl_uString
* aDirectoryUrl
,
2378 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
2381 if (aDirectoryUrl
== NULL
)
2382 return osl_File_E_INVAL
;
2384 rtl::OUString sys_path
;
2385 oslFileError osl_error
=
2386 _osl_getSystemPathFromFileURL(aDirectoryUrl
, &sys_path
.pData
, sal_False
);
2388 if (osl_error
!= osl_File_E_None
)
2391 systemPathRemoveSeparator(sys_path
);
2393 // const_cast because sys_path is a local copy
2394 // which we want to modify inplace instead of
2395 // coyp it into another buffer on the heap again
2396 return MapError(create_dir_recursively_(
2397 sys_path
.pData
->buffer
, aDirectoryCreationCallbackFunc
, pData
));
2400 //#############################################
2401 oslFileError SAL_CALL
osl_createTempFile(
2402 rtl_uString
* pustrDirectoryURL
,
2403 oslFileHandle
* pHandle
,
2404 rtl_uString
** ppustrTempFileURL
)
2406 rtl_uString
* base_directory
= 0;
2408 sal_Bool b_delete_on_close
;
2409 oslFileError osl_error
;
2411 osl_error
= osl_setup_createTempFile_impl_(
2416 &b_delete_on_close
);
2418 if (osl_File_E_None
!= osl_error
)
2421 /* allocate enough space on the stack */
2422 STACK_ALLOC(tmp_name
, WCHAR
, (rtl_uString_getLength(base_directory
) + MAX_PATH
));
2426 osl_createTempFile_impl_(
2433 else // stack alloc failed
2435 osl_error
= osl_File_E_NOMEM
;
2439 rtl_uString_release(base_directory
);
2444 //#############################################
2445 oslFileError SAL_CALL
osl_getTempDirURL(rtl_uString
** pustrTempDir
)
2447 WCHAR szBuffer
[MAX_PATH
];
2448 LPWSTR lpBuffer
= szBuffer
;
2449 DWORD nBufferLength
= ELEMENTS_OF_ARRAY(szBuffer
) - 1;
2456 nLength
= GetTempPathW( ELEMENTS_OF_ARRAY(szBuffer
), lpBuffer
);
2457 if ( nLength
> nBufferLength
)
2460 lpBuffer
= reinterpret_cast<WCHAR
*>(alloca( sizeof(WCHAR
) * nLength
));
2461 nBufferLength
= nLength
- 1;
2463 } while ( nLength
> nBufferLength
);
2467 rtl_uString
*ustrTempPath
= NULL
;
2469 if ( '\\' == lpBuffer
[nLength
-1] )
2470 lpBuffer
[nLength
-1] = 0;
2472 rtl_uString_newFromStr( &ustrTempPath
, reinterpret_cast<const sal_Unicode
*>(lpBuffer
) );
2474 error
= osl_getFileURLFromSystemPath( ustrTempPath
, pustrTempDir
);
2476 rtl_uString_release( ustrTempPath
);
2479 error
= MapError( GetLastError() );
2484 //##################################################################
2485 // File handling functions
2486 //##################################################################
2489 //#############################################
2490 oslFileError SAL_CALL
osl_openFile(
2491 rtl_uString
*strPath
, oslFileHandle
*pHandle
, sal_uInt32 uFlags
)
2493 rtl_uString
*strSysPath
= NULL
;
2494 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
2496 if ( osl_File_E_None
== error
)
2498 DWORD dwAccess
= 0, dwShare
= FILE_SHARE_READ
, dwCreation
= 0, dwAttributes
= 0;
2501 if ( uFlags
& osl_File_OpenFlag_Read
)
2502 dwAccess
|= GENERIC_READ
;
2504 if ( uFlags
& osl_File_OpenFlag_Write
)
2505 dwAccess
|= GENERIC_WRITE
;
2507 dwShare
|= FILE_SHARE_WRITE
;
2509 if ( uFlags
& osl_File_OpenFlag_NoLock
)
2510 dwShare
|= FILE_SHARE_WRITE
;
2512 if ( uFlags
& osl_File_OpenFlag_Create
)
2513 dwCreation
|= CREATE_NEW
;
2515 dwCreation
|= OPEN_EXISTING
;
2517 hFile
= CreateFileW( reinterpret_cast<LPCWSTR
>(rtl_uString_getStr( strSysPath
)), dwAccess
, dwShare
, NULL
, dwCreation
, dwAttributes
, NULL
);
2519 *pHandle
= osl_createFileHandleFromOSHandle( hFile
);
2521 if ( !IsValidHandle( hFile
) )
2522 error
= MapError( GetLastError() );
2524 rtl_uString_release( strSysPath
);
2530 //#############################################
2531 oslFileError SAL_CALL
osl_syncFile(oslFileHandle Handle
)
2533 if (!IsValidHandle((HANDLE
)Handle
))
2534 return osl_File_E_INVAL
;
2536 if (!FlushFileBuffers((HANDLE
)Handle
))
2537 return MapError(GetLastError());
2539 return osl_File_E_None
;
2542 //#############################################
2543 oslFileError SAL_CALL
osl_closeFile(oslFileHandle Handle
)
2546 HANDLE hFile
= (HANDLE
)Handle
;
2548 if ( IsValidHandle(hFile
) )
2549 error
= CloseHandle( hFile
) ? osl_File_E_None
: MapError( GetLastError() );
2551 error
= osl_File_E_INVAL
;
2556 //#############################################
2557 oslFileError SAL_CALL
osl_isEndOfFile(oslFileHandle Handle
, sal_Bool
*pIsEOF
)
2559 oslFileError error
= osl_File_E_INVAL
;
2560 HANDLE hFile
= (HANDLE
)Handle
;
2562 if ( IsValidHandle(hFile
) )
2564 LONG lDistanceToMove
, lDistanceToMoveHigh
;
2567 /* Return value INVALID_SET_FILE_POINTER is no error indication and LastError could
2568 be set from previous IO call */
2570 SetLastError( NOERROR
);
2572 lDistanceToMoveHigh
= 0;
2573 lDistanceToMove
= SetFilePointer( hFile
, 0, &lDistanceToMoveHigh
, FILE_CURRENT
);
2575 error
= MapError( GetLastError() );
2577 if ( osl_File_E_None
== error
)
2579 nCurPos
= (sal_uInt64
)lDistanceToMove
+ ((sal_uInt64
)lDistanceToMoveHigh
<< 32);
2581 lDistanceToMoveHigh
= 0;
2582 lDistanceToMove
= SetFilePointer( hFile
, 0, &lDistanceToMoveHigh
, FILE_END
);
2584 error
= MapError( GetLastError() );
2586 if ( osl_File_E_None
== error
)
2588 sal_uInt64 nEndPos
= (sal_uInt64
)lDistanceToMove
+ ((sal_uInt64
)lDistanceToMoveHigh
<< 32);
2590 *pIsEOF
= (sal_Bool
)(nEndPos
== nCurPos
);
2592 lDistanceToMoveHigh
= (LONG
)(nCurPos
>> 32);
2593 SetFilePointer( hFile
, (LONG
)(nCurPos
& 0xFFFFFFFF), &lDistanceToMoveHigh
, FILE_BEGIN
);
2595 error
= MapError( GetLastError() );
2602 //#############################################
2603 oslFileError SAL_CALL
osl_setFilePos(oslFileHandle Handle
, sal_uInt32 uHow
, sal_Int64 uPos
)
2605 HANDLE hFile
= (HANDLE
)Handle
;
2606 if (!IsValidHandle(hFile
))
2607 return osl_File_E_INVAL
;
2609 DWORD dwMoveMethod
= 0;
2612 case osl_Pos_Current
:
2613 dwMoveMethod
= FILE_CURRENT
;
2616 dwMoveMethod
= FILE_END
;
2618 case osl_Pos_Absolut
:
2620 dwMoveMethod
= FILE_BEGIN
;
2624 LONG nOffsetLo
= sal::static_int_cast
<LONG
>(uPos
& 0xFFFFFFFF);
2625 LONG nOffsetHi
= sal::static_int_cast
<LONG
>(uPos
>> 32);
2628 DWORD dwPosLo
= SetFilePointer( hFile
, nOffsetLo
, &nOffsetHi
, dwMoveMethod
);
2629 if (INVALID_SET_FILE_POINTER
== dwPosLo
)
2631 DWORD dwError
= GetLastError();
2632 if (NO_ERROR
!= dwError
)
2633 return MapError( dwError
);
2635 return osl_File_E_None
;
2638 //#############################################
2639 oslFileError SAL_CALL
osl_getFilePos(oslFileHandle Handle
, sal_uInt64
*pPos
)
2642 HANDLE hFile
= (HANDLE
)Handle
;
2644 if ( IsValidHandle(hFile
) )
2646 LONG lDistanceToMove
, lDistanceToMoveHigh
;
2648 /* Return value INVALID_SET_FILE_POINTER is no error indication and LastError could
2649 be set from previous IO call */
2651 SetLastError( NOERROR
);
2653 lDistanceToMoveHigh
= 0;
2654 lDistanceToMove
= SetFilePointer( hFile
, 0, &lDistanceToMoveHigh
, FILE_CURRENT
);
2656 error
= MapError( GetLastError() );
2658 if ( osl_File_E_None
== error
)
2659 *pPos
= (sal_uInt64
)lDistanceToMove
+ ((sal_uInt64
)lDistanceToMoveHigh
<< 32);
2662 error
= osl_File_E_INVAL
;
2667 //#############################################
2668 oslFileError SAL_CALL
osl_getFileSize(oslFileHandle Handle
, sal_uInt64
*pSize
)
2670 HANDLE hFile
= (HANDLE
)Handle
;
2671 if ( !IsValidHandle(hFile
) )
2672 return osl_File_E_INVAL
;
2674 DWORD nSize
= GetFileSize(hFile
, NULL
);
2675 if (nSize
== INVALID_FILE_SIZE
)
2677 DWORD nError
= GetLastError();
2678 if (nError
!= NO_ERROR
)
2679 return MapError(nError
);
2682 *pSize
= (sal_uInt64
)(nSize
);
2683 return osl_File_E_None
;
2686 oslFileError SAL_CALL
osl_setFileSize(oslFileHandle Handle
, sal_uInt64 uSize
)
2688 oslFileError error
= osl_setFilePos( Handle
, osl_Pos_Absolut
, uSize
);
2689 if ( osl_File_E_None
== error
)
2691 if ( !SetEndOfFile( (HANDLE
)Handle
) )
2692 error
= MapError( osl_File_E_None
);
2698 //#############################################
2699 oslFileError SAL_CALL
osl_mapFile(
2700 oslFileHandle Handle
,
2710 explicit FileMapping (HANDLE hMap
)
2716 (void)::CloseHandle(m_handle
);
2720 HANDLE hFile
= (HANDLE
)(Handle
);
2721 if (!IsValidHandle(hFile
) || (0 == ppAddr
))
2722 return osl_File_E_INVAL
;
2725 static SIZE_T
const nLimit
= std::numeric_limits
< SIZE_T
>::max();
2726 if (uLength
> nLimit
)
2727 return osl_File_E_OVERFLOW
;
2728 SIZE_T
const nLength
= sal::static_int_cast
< SIZE_T
>(uLength
);
2730 OSVERSIONINFO osinfo
;
2731 osinfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
2732 (void)::GetVersionEx(&osinfo
);
2734 if (VER_PLATFORM_WIN32_NT
!= osinfo
.dwPlatformId
)
2735 return osl_File_E_NOSYS
; // Unsupported
2737 FileMapping
aMap( ::CreateFileMapping (hFile
, NULL
, SEC_COMMIT
| PAGE_READONLY
, 0, 0, NULL
) );
2738 if (!IsValidHandle(aMap
.m_handle
))
2739 return MapError( GetLastError() );
2741 DWORD
const dwOffsetHi
= sal::static_int_cast
<DWORD
>(uOffset
>> 32);
2742 DWORD
const dwOffsetLo
= sal::static_int_cast
<DWORD
>(uOffset
& 0xFFFFFFFF);
2744 *ppAddr
= ::MapViewOfFile( aMap
.m_handle
, FILE_MAP_READ
, dwOffsetHi
, dwOffsetLo
, nLength
);
2746 return MapError( GetLastError() );
2748 if (uFlags
& osl_File_MapFlag_RandomAccess
)
2750 // Determine memory pagesize.
2752 ::GetSystemInfo( &info
);
2753 DWORD
const dwPageSize
= info
.dwPageSize
;
2756 * Pagein, touching first byte of each memory page.
2757 * Note: volatile disables optimizing the loop away.
2759 BYTE
* pData (reinterpret_cast<BYTE
*>(*ppAddr
));
2760 SIZE_T
nSize (nLength
);
2762 volatile BYTE c
= 0;
2763 while (nSize
> dwPageSize
)
2766 pData
+= dwPageSize
;
2767 nSize
-= dwPageSize
;
2776 return osl_File_E_None
;
2779 //#############################################
2780 oslFileError SAL_CALL
osl_unmapFile(void* pAddr
, sal_uInt64
/* uLength */)
2783 return osl_File_E_INVAL
;
2785 if (!::UnmapViewOfFile (pAddr
))
2786 return MapError( GetLastError() );
2788 return osl_File_E_None
;
2791 //#############################################
2792 oslFileError SAL_CALL
osl_readFile(
2793 oslFileHandle Handle
,
2795 sal_uInt64 uBytesRequested
,
2796 sal_uInt64
*pBytesRead
)
2799 HANDLE hFile
= (HANDLE
)Handle
;
2801 if ( IsValidHandle(hFile
) )
2803 DWORD dwBytesToRead
= (DWORD
)uBytesRequested
;
2806 if ( ReadFile( hFile
, pBuffer
, dwBytesToRead
, &dwBytesRead
, NULL
) )
2808 *pBytesRead
= (sal_uInt64
)dwBytesRead
;
2809 error
= osl_File_E_None
;
2812 error
= MapError( GetLastError() );
2815 error
= osl_File_E_INVAL
;
2820 //#############################################
2821 oslFileError SAL_CALL
osl_writeFile(
2822 oslFileHandle Handle
,
2823 const void *pBuffer
,
2824 sal_uInt64 uBytesToWrite
,
2825 sal_uInt64
*pBytesWritten
)
2828 HANDLE hFile
= (HANDLE
)Handle
;
2830 if ( IsValidHandle(hFile
) )
2832 DWORD dwBytesToWrite
= (DWORD
)uBytesToWrite
;
2833 DWORD dwBytesWritten
;
2835 if ( WriteFile( hFile
, pBuffer
, dwBytesToWrite
, &dwBytesWritten
, NULL
) )
2837 *pBytesWritten
= (sal_uInt64
)dwBytesWritten
;
2838 error
= osl_File_E_None
;
2841 error
= MapError( GetLastError() );
2844 error
= osl_File_E_INVAL
;
2849 //#############################################
2850 oslFileError SAL_CALL
osl_readFileAt(
2851 oslFileHandle Handle
,
2854 sal_uInt64 uBytesRequested
,
2855 sal_uInt64
* pBytesRead
)
2857 HANDLE hFile
= (HANDLE
)(Handle
);
2858 if (!IsValidHandle(hFile
) || (0 == pBuffer
))
2859 return osl_File_E_INVAL
;
2861 static sal_uInt64
const g_limit_dword
= std::numeric_limits
< DWORD
>::max();
2862 if (g_limit_dword
< uBytesRequested
)
2863 return osl_File_E_OVERFLOW
;
2864 DWORD
const dwBytes
= sal::static_int_cast
< DWORD
>(uBytesRequested
);
2866 if (0 == pBytesRead
)
2867 return osl_File_E_INVAL
;
2870 oslFileError error
= osl_setFilePos(Handle
, osl_Pos_Absolut
, uOffset
);
2871 if (osl_File_E_None
!= error
)
2875 if (!::ReadFile(hFile
, pBuffer
, dwBytes
, &dwDone
, NULL
))
2876 return MapError( GetLastError() );
2878 *pBytesRead
= dwDone
;
2879 return osl_File_E_None
;
2882 //#############################################
2883 oslFileError SAL_CALL
osl_writeFileAt(
2884 oslFileHandle Handle
,
2886 const void* pBuffer
,
2887 sal_uInt64 uBytesToWrite
,
2888 sal_uInt64
* pBytesWritten
)
2890 HANDLE hFile
= (HANDLE
)(Handle
);
2891 if (!IsValidHandle(hFile
) || (0 == pBuffer
))
2892 return osl_File_E_INVAL
;
2894 static sal_uInt64
const g_limit_dword
= std::numeric_limits
< DWORD
>::max();
2895 if (g_limit_dword
< uBytesToWrite
)
2896 return osl_File_E_OVERFLOW
;
2897 DWORD
const dwBytes
= sal::static_int_cast
< DWORD
>(uBytesToWrite
);
2899 if (0 == pBytesWritten
)
2900 return osl_File_E_INVAL
;
2903 oslFileError error
= osl_setFilePos(Handle
, osl_Pos_Absolut
, uOffset
);
2904 if (osl_File_E_None
!= error
)
2908 if (!::WriteFile(hFile
, pBuffer
, dwBytes
, &dwDone
, NULL
))
2909 return MapError( GetLastError() );
2911 *pBytesWritten
= dwDone
;
2912 return osl_File_E_None
;
2915 //#############################################
2916 oslFileError SAL_CALL
osl_removeFile( rtl_uString
* strPath
)
2918 rtl_uString
*strSysPath
= NULL
;
2919 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
2921 if ( osl_File_E_None
== error
)
2923 if ( DeleteFile( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysPath
)) ) )
2924 error
= osl_File_E_None
;
2926 error
= MapError( GetLastError() );
2928 rtl_uString_release( strSysPath
);
2933 //#############################################
2934 #define osl_File_CopyRecursive 0x0001
2935 #define osl_File_CopyOverwrite 0x0002
2937 oslFileError SAL_CALL
osl_copyFile( rtl_uString
* strPath
, rtl_uString
*strDestPath
)
2939 rtl_uString
*strSysPath
= NULL
, *strSysDestPath
= NULL
;
2940 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
2942 if ( osl_File_E_None
== error
)
2943 error
= _osl_getSystemPathFromFileURL( strDestPath
, &strSysDestPath
, sal_False
);
2945 if ( osl_File_E_None
== error
)
2947 if ( CopyFile( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysPath
)), reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysDestPath
)), FALSE
) )
2948 error
= osl_File_E_None
;
2950 error
= MapError( GetLastError() );
2954 rtl_uString_release( strSysPath
);
2955 if ( strSysDestPath
)
2956 rtl_uString_release( strSysDestPath
);
2961 //#############################################
2962 oslFileError SAL_CALL
osl_moveFile( rtl_uString
* strPath
, rtl_uString
*strDestPath
)
2964 rtl_uString
*strSysPath
= NULL
, *strSysDestPath
= NULL
;
2965 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
2967 if ( osl_File_E_None
== error
)
2968 error
= _osl_getSystemPathFromFileURL( strDestPath
, &strSysDestPath
, sal_False
);
2970 if ( osl_File_E_None
== error
)
2972 if ( MoveFileEx( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysPath
)), reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysDestPath
)), MOVEFILE_COPY_ALLOWED
| MOVEFILE_WRITE_THROUGH
| MOVEFILE_REPLACE_EXISTING
) )
2973 error
= osl_File_E_None
;
2975 error
= MapError( GetLastError() );
2979 rtl_uString_release( strSysPath
);
2980 if ( strSysDestPath
)
2981 rtl_uString_release( strSysDestPath
);
2986 //#############################################
2987 oslFileError SAL_CALL
osl_setFileAttributes(
2988 rtl_uString
*ustrFileURL
,
2989 sal_uInt64 uAttributes
)
2992 rtl_uString
*ustrSysPath
= NULL
;
2993 DWORD dwFileAttributes
;
2996 // Converts the normalized path into a systempath
2997 error
= _osl_getSystemPathFromFileURL( ustrFileURL
, &ustrSysPath
, sal_False
);
2999 if ( osl_File_E_None
!= error
)
3002 dwFileAttributes
= GetFileAttributes( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(ustrSysPath
)) );
3004 if ( (DWORD
)-1 != dwFileAttributes
)
3006 dwFileAttributes
&= ~(FILE_ATTRIBUTE_READONLY
| FILE_ATTRIBUTE_HIDDEN
);
3008 if ( uAttributes
& osl_File_Attribute_ReadOnly
)
3009 dwFileAttributes
|= FILE_ATTRIBUTE_READONLY
;
3011 if ( uAttributes
& osl_File_Attribute_Hidden
)
3012 dwFileAttributes
|= FILE_ATTRIBUTE_HIDDEN
;
3014 fSuccess
= SetFileAttributes( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(ustrSysPath
)), dwFileAttributes
);
3020 error
= MapError( GetLastError() );
3022 rtl_uString_release( ustrSysPath
);
3027 //#####################################################
3028 oslFileError SAL_CALL
osl_setFileTime(
3029 rtl_uString
*filePath
,
3030 const TimeValue
*aCreationTime
,
3031 const TimeValue
*aLastAccessTime
,
3032 const TimeValue
*aLastWriteTime
)
3035 rtl_uString
*sysPath
=NULL
;
3036 FILETIME
*lpCreationTime
=NULL
;
3037 FILETIME
*lpLastAccessTime
=NULL
;
3038 FILETIME
*lpLastWriteTime
=NULL
;
3039 FILETIME ftCreationTime
;
3040 FILETIME ftLastAccessTime
;
3041 FILETIME ftLastWriteTime
;
3046 error
=_osl_getSystemPathFromFileURL(filePath
, &sysPath
, sal_False
);
3048 if (error
==osl_File_E_INVAL
)
3051 hFile
=CreateFileW(reinterpret_cast<LPCWSTR
>(rtl_uString_getStr(sysPath
)), GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
3052 rtl_uString_release(sysPath
);
3054 if (hFile
==INVALID_HANDLE_VALUE
)
3055 return osl_File_E_NOENT
;
3057 if (TimeValueToFileTime(aCreationTime
, &ftCreationTime
))
3058 lpCreationTime
=&ftCreationTime
;
3060 if (TimeValueToFileTime(aLastAccessTime
, &ftLastAccessTime
))
3061 lpLastAccessTime
=&ftLastAccessTime
;
3063 if (TimeValueToFileTime(aLastWriteTime
, &ftLastWriteTime
))
3064 lpLastWriteTime
=&ftLastWriteTime
;
3066 fSuccess
=SetFileTime(hFile
, lpCreationTime
, lpLastAccessTime
, lpLastWriteTime
);
3071 return osl_File_E_INVAL
;
3073 return osl_File_E_None
;
3076 //#####################################################
3077 oslFileError SAL_CALL
osl_getFileStatus(
3078 oslDirectoryItem Item
,
3079 oslFileStatus
*pStatus
,
3080 sal_uInt32 uFieldMask
)
3082 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
3085 return osl_File_E_INVAL
;
3087 switch ( pItemImpl
->uType
)
3089 case DIRECTORYITEM_DRIVE
:
3090 return osl_getDriveInfo( Item
, pStatus
, uFieldMask
);
3091 case DIRECTORYITEM_SERVER
:
3092 return osl_getServerInfo( Item
, pStatus
, uFieldMask
);
3097 if ( uFieldMask
& osl_FileStatus_Mask_Validate
)
3099 HANDLE hFind
= FindFirstFile( pItemImpl
->szFullPath
, &pItemImpl
->FindData
);
3101 if ( hFind
!= INVALID_HANDLE_VALUE
)
3104 return MapError( GetLastError() );
3106 uFieldMask
&= ~ osl_FileStatus_Mask_Validate
;
3109 /* If no fields to retrieve left ignore pStatus */
3111 return osl_File_E_None
;
3113 /* Otherwise, this must be a valid pointer */
3115 return osl_File_E_INVAL
;
3117 if ( pStatus
->uStructSize
!= sizeof(oslFileStatus
) )
3118 return osl_File_E_INVAL
;
3120 pStatus
->uValidFields
= 0;
3122 /* File time stamps */
3124 if ( (uFieldMask
& osl_FileStatus_Mask_ModifyTime
) &&
3125 FileTimeToTimeValue( &pItemImpl
->FindData
.ftLastWriteTime
, &pStatus
->aModifyTime
) )
3126 pStatus
->uValidFields
|= osl_FileStatus_Mask_ModifyTime
;
3128 if ( (uFieldMask
& osl_FileStatus_Mask_AccessTime
) &&
3129 FileTimeToTimeValue( &pItemImpl
->FindData
.ftLastAccessTime
, &pStatus
->aAccessTime
) )
3130 pStatus
->uValidFields
|= osl_FileStatus_Mask_AccessTime
;
3132 if ( (uFieldMask
& osl_FileStatus_Mask_CreationTime
) &&
3133 FileTimeToTimeValue( &pItemImpl
->FindData
.ftCreationTime
, &pStatus
->aCreationTime
) )
3134 pStatus
->uValidFields
|= osl_FileStatus_Mask_CreationTime
;
3136 /* Most of the fields are already set, regardless of requiered fields */
3138 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->FindData
.cFileName
) );
3139 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
3141 if ((FILE_ATTRIBUTE_REPARSE_POINT
& pItemImpl
->FindData
.dwFileAttributes
) &&
3142 (IO_REPARSE_TAG_MOUNT_POINT
== pItemImpl
->FindData
.dwReserved0
))
3143 pStatus
->eType
= osl_File_Type_Volume
;
3144 else if (pItemImpl
->FindData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
3145 pStatus
->eType
= osl_File_Type_Directory
;
3147 pStatus
->eType
= osl_File_Type_Regular
;
3149 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
3151 pStatus
->uAttributes
= pItemImpl
->FindData
.dwFileAttributes
;
3152 pStatus
->uValidFields
|= osl_FileStatus_Mask_Attributes
;
3154 pStatus
->uFileSize
= (sal_uInt64
)pItemImpl
->FindData
.nFileSizeLow
+ ((sal_uInt64
)pItemImpl
->FindData
.nFileSizeHigh
<< 32);
3155 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileSize
;
3157 if ( uFieldMask
& osl_FileStatus_Mask_LinkTargetURL
)
3159 rtl_uString
*ustrFullPath
= NULL
;
3161 rtl_uString_newFromStr( &ustrFullPath
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->szFullPath
) );
3162 osl_getFileURLFromSystemPath( ustrFullPath
, &pStatus
->ustrLinkTargetURL
);
3163 rtl_uString_release( ustrFullPath
);
3165 pStatus
->uValidFields
|= osl_FileStatus_Mask_LinkTargetURL
;
3168 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
3170 rtl_uString
*ustrFullPath
= NULL
;
3173 if ( !pItemImpl
->bFullPathNormalized
)
3175 GetCaseCorrectPathName( pItemImpl
->szFullPath
, pItemImpl
->szFullPath
, sizeof(pItemImpl
->szFullPath
) );
3176 pItemImpl
->bFullPathNormalized
= TRUE
;
3178 rtl_uString_newFromStr( &ustrFullPath
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->szFullPath
) );
3179 osl_getFileURLFromSystemPath( ustrFullPath
, &pStatus
->ustrFileURL
);
3180 rtl_uString_release( ustrFullPath
);
3181 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileURL
;
3184 return osl_File_E_None
;
3187 //##################################################################
3188 // directory handling functions
3189 //##################################################################
3192 //#####################################################
3193 oslFileError SAL_CALL
osl_createDirectory(rtl_uString
* strPath
)
3195 rtl_uString
*strSysPath
= NULL
;
3196 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
3198 if ( osl_File_E_None
== error
)
3200 if ( CreateDirectoryW( reinterpret_cast<LPCWSTR
>(rtl_uString_getStr( strSysPath
)), NULL
) )
3201 error
= osl_File_E_None
;
3203 The else case is a hack because the ucb or the webtop had some
3204 problems with the error code that CreateDirectory returns in
3205 case the path is only a logical drive, should be removed!
3209 const sal_Unicode
*pBuffer
= rtl_uString_getStr( strSysPath
);
3210 sal_Int32 nLen
= rtl_uString_getLength( strSysPath
);
3213 ( pBuffer
[0] >= 'A' && pBuffer
[0] <= 'Z' ||
3214 pBuffer
[0] >= 'a' && pBuffer
[0] <= 'z' ) &&
3215 pBuffer
[1] == ':' && ( nLen
==2 || nLen
== 3 && pBuffer
[2] == '\\' )
3217 SetLastError( ERROR_ALREADY_EXISTS
);
3219 error
= MapError( GetLastError() );
3222 rtl_uString_release( strSysPath
);
3227 //#####################################################
3228 oslFileError SAL_CALL
osl_removeDirectory(rtl_uString
* strPath
)
3230 rtl_uString
*strSysPath
= NULL
;
3231 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
3233 if ( osl_File_E_None
== error
)
3235 if ( RemoveDirectory( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysPath
)) ) )
3236 error
= osl_File_E_None
;
3238 error
= MapError( GetLastError() );
3240 rtl_uString_release( strSysPath
);
3245 //#####################################################
3246 oslFileError SAL_CALL
osl_openDirectory(rtl_uString
*strDirectoryPath
, oslDirectory
*pDirectory
)
3250 if ( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase( strDirectoryPath
->buffer
, "file:///" ) )
3251 error
= osl_openLocalRoot( strDirectoryPath
, pDirectory
);
3254 rtl_uString
*strSysDirectoryPath
= NULL
;
3255 // WCHAR szCorrectedPathName[MAX_PATH];
3258 error
= _osl_getSystemPathFromFileURL( strDirectoryPath
, &strSysDirectoryPath
, sal_False
);
3260 if ( osl_File_E_None
!= error
)
3265 if ( GetCaseCorrectPathName( strSysDirectoryPath->buffer, szCorrectedPathName, MAX_PATH ) )
3267 rtl_uString_newFromStr( &strSysDirectoryPath, szCorrectedPathName );
3271 dwPathType
= IsValidFilePath( strSysDirectoryPath
, NULL
, VALIDATEPATH_NORMAL
, NULL
);
3273 if ( dwPathType
& PATHTYPE_IS_SERVER
)
3275 error
= osl_openNetworkServer( strSysDirectoryPath
, pDirectory
);
3278 error
= osl_openFileDirectory( strSysDirectoryPath
, pDirectory
);
3280 rtl_uString_release( strSysDirectoryPath
);
3285 //#####################################################
3286 oslFileError SAL_CALL
osl_getNextDirectoryItem(oslDirectory Directory
, oslDirectoryItem
*pItem
, sal_uInt32 uHint
)
3288 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
3290 /* Assume failure */
3293 return osl_File_E_INVAL
;
3298 return osl_File_E_INVAL
;
3300 switch ( pDirImpl
->uType
)
3302 case DIRECTORYTYPE_LOCALROOT
:
3303 return osl_getNextDrive( Directory
, pItem
, uHint
);
3304 case DIRECTORYTYPE_NETROOT
:
3305 return osl_getNextNetResource( Directory
, pItem
, uHint
);
3306 case DIRECTORYTYPE_FILESYSTEM
:
3307 return osl_getNextFileItem( Directory
, pItem
, uHint
);
3309 return osl_File_E_INVAL
;
3313 //#####################################################
3314 oslFileError SAL_CALL
osl_closeDirectory(oslDirectory Directory
)
3316 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
3317 oslFileError eError
= osl_File_E_INVAL
;
3321 switch ( pDirImpl
->uType
)
3323 case DIRECTORYTYPE_FILESYSTEM
:
3324 eError
= CloseDirectory( pDirImpl
->hDirectory
) ? osl_File_E_None
: MapError( GetLastError() );
3326 case DIRECTORYTYPE_LOCALROOT
:
3327 eError
= CloseLogicalDrivesEnum( pDirImpl
->hEnumDrives
) ? osl_File_E_None
: MapError( GetLastError() );
3329 case DIRECTORYTYPE_NETROOT
:
3331 DWORD err
= WNetCloseEnum(pDirImpl
->hDirectory
);
3332 eError
= (err
== NO_ERROR
) ? osl_File_E_None
: MapError(err
);
3336 OSL_ENSURE( 0, "Invalid directory type" );
3340 rtl_freeMemory(pDirImpl
);
3345 //#####################################################
3346 oslFileError SAL_CALL
osl_getDirectoryItem(rtl_uString
*strFilePath
, oslDirectoryItem
*pItem
)
3348 oslFileError error
= osl_File_E_None
;
3349 rtl_uString
* strSysFilePath
= NULL
;
3350 PATHTYPE type
= PATHTYPE_FILE
;
3352 // TCHAR szCorrectedPathName[MAX_PATH];
3354 /* Assume failure */
3357 return osl_File_E_INVAL
;
3362 error
= _osl_getSystemPathFromFileURL( strFilePath
, &strSysFilePath
, sal_False
);
3364 if ( osl_File_E_None
!= error
)
3367 // MT: I can't imagine a case where this is good for!
3369 if ( GetCaseCorrectPathName( strSysFilePath->buffer, szCorrectedPathName, MAX_PATH ) )
3371 rtl_uString_newFromStr( &strSysFilePath, szCorrectedPathName );
3375 dwPathType
= IsValidFilePath( strSysFilePath
, NULL
, VALIDATEPATH_NORMAL
, NULL
);
3377 if ( dwPathType
& PATHTYPE_IS_VOLUME
)
3378 type
= PATHTYPE_VOLUME
;
3379 else if ( dwPathType
& PATHTYPE_IS_SERVER
)
3380 type
= PATHTYPE_NETSERVER
;
3382 type
= PATHTYPE_FILE
;
3386 case PATHTYPE_NETSERVER
:
3388 DirectoryItem_Impl
* pItemImpl
=
3389 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
3392 error
= osl_File_E_NOMEM
;
3394 if ( osl_File_E_None
== error
)
3396 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
3397 pItemImpl
->uType
= DIRECTORYITEM_SERVER
;
3399 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
3401 _tcscpy( pItemImpl
->szFullPath
, reinterpret_cast<LPCTSTR
>(strSysFilePath
->buffer
) );
3403 // Assign a title anyway
3408 while( iSrc
< strSysFilePath
->length
&& strSysFilePath
->buffer
[iSrc
] && strSysFilePath
->buffer
[iSrc
] != '\\' )
3410 pItemImpl
->FindData
.cFileName
[iDst
++] = strSysFilePath
->buffer
[iSrc
++];
3418 case PATHTYPE_VOLUME
:
3420 DirectoryItem_Impl
* pItemImpl
=
3421 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
3424 error
= osl_File_E_NOMEM
;
3426 if ( osl_File_E_None
== error
)
3428 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
3429 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
3431 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
3433 _tcscpy( pItemImpl
->cDriveString
, reinterpret_cast<LPCTSTR
>(strSysFilePath
->buffer
) );
3434 pItemImpl
->cDriveString
[0] = _toupper( pItemImpl
->cDriveString
[0] );
3436 if ( pItemImpl
->cDriveString
[_tcslen(pItemImpl
->cDriveString
) - 1] != '\\' )
3437 _tcscat( pItemImpl
->cDriveString
, TEXT( "\\" ) );
3443 case PATHTYPE_SYNTAXERROR
:
3444 case PATHTYPE_NETROOT
:
3448 WIN32_FIND_DATA aFindData
;
3450 if ( strSysFilePath
->length
> 0 && strSysFilePath
->buffer
[strSysFilePath
->length
- 1] == '\\' )
3451 rtl_uString_newFromStr_WithLength( &strSysFilePath
, strSysFilePath
->buffer
, strSysFilePath
->length
- 1 );
3453 hFind
= FindFirstFile( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(strSysFilePath
)), &aFindData
);
3455 if ( hFind
!= INVALID_HANDLE_VALUE
)
3457 DirectoryItem_Impl
*pItemImpl
=
3458 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
3460 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
3461 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
3463 CopyMemory( &pItemImpl
->FindData
, &aFindData
, sizeof(WIN32_FIND_DATA
) );
3464 _tcscpy( pItemImpl
->szFullPath
, reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(strSysFilePath
)) );
3466 // MT: This costs 600ms startup time on fast v60x!
3467 // GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) );
3469 pItemImpl
->uType
= DIRECTORYITEM_FILE
;
3474 error
= MapError( GetLastError() );
3479 if ( strSysFilePath
)
3480 rtl_uString_release( strSysFilePath
);
3485 //#####################################################
3486 oslFileError SAL_CALL
osl_acquireDirectoryItem( oslDirectoryItem Item
)
3488 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
3491 return osl_File_E_INVAL
;
3493 pItemImpl
->nRefCount
++;
3494 return osl_File_E_None
;
3497 //#####################################################
3498 oslFileError SAL_CALL
osl_releaseDirectoryItem( oslDirectoryItem Item
)
3500 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
3503 return osl_File_E_INVAL
;
3505 if ( ! --pItemImpl
->nRefCount
)
3506 rtl_freeMemory( pItemImpl
);
3507 return osl_File_E_None
;
3510 //#####################################################
3511 oslFileError SAL_CALL
osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle
)
3514 return osl_File_E_None
;
3516 return osl_File_E_INVAL
;
3519 //#####################################################
3520 oslFileError SAL_CALL
osl_automountVolumeDevice( oslVolumeDeviceHandle Handle
)
3523 return osl_File_E_None
;
3525 return osl_File_E_INVAL
;
3528 //#####################################################
3529 oslFileError SAL_CALL
osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
3533 rtl_uString_acquire( (rtl_uString
*)Handle
);
3534 return osl_File_E_None
;
3537 return osl_File_E_INVAL
;
3540 //#####################################################
3541 oslFileError SAL_CALL
osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
3545 rtl_uString_release( (rtl_uString
*)Handle
);
3546 return osl_File_E_None
;
3549 return osl_File_E_INVAL
;
3552 //#####################################################
3553 oslFileError SAL_CALL
osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle
, rtl_uString
**pstrPath
)
3555 if ( Handle
&& pstrPath
)
3557 rtl_uString_assign( pstrPath
, (rtl_uString
*)Handle
);
3558 return osl_File_E_None
;
3561 return osl_File_E_INVAL
;
3565 //##################################################################
3566 // FileURL functions
3567 //##################################################################
3570 //#####################################################
3571 oslFileError SAL_CALL
osl_getFileURLFromSystemPath(
3572 rtl_uString
* ustrPath
, rtl_uString
** pustrURL
)
3574 return _osl_getFileURLFromSystemPath( ustrPath
, pustrURL
);
3577 //#####################################################
3578 oslFileError SAL_CALL
osl_getSystemPathFromFileURL(
3579 rtl_uString
*ustrURL
, rtl_uString
**pustrPath
)
3581 return _osl_getSystemPathFromFileURL( ustrURL
, pustrPath
, sal_True
);
3584 //#####################################################
3585 oslFileError SAL_CALL
osl_searchFileURL(
3586 rtl_uString
*ustrFileName
,
3587 rtl_uString
*ustrSystemSearchPath
,
3588 rtl_uString
**pustrPath
)
3590 rtl_uString
*ustrUNCPath
= NULL
;
3591 rtl_uString
*ustrSysPath
= NULL
;
3594 /* First try to interpret the file name as an URL even a relative one */
3595 error
= _osl_getSystemPathFromFileURL( ustrFileName
, &ustrUNCPath
, sal_True
);
3597 /* So far we either have an UNC path or something invalid
3598 Now create a system path */
3599 if ( osl_File_E_None
== error
)
3600 error
= _osl_getSystemPathFromFileURL( ustrUNCPath
, &ustrSysPath
, sal_True
);
3602 if ( osl_File_E_None
== error
)
3604 DWORD nBufferLength
;
3606 LPTSTR lpBuffer
= NULL
;
3607 LPTSTR lpszFilePart
;
3609 /* Repeat calling SearchPath ...
3610 Start with MAX_PATH for the buffer. In most cases this
3611 will be enough and does not force the loop to runtwice */
3612 dwResult
= MAX_PATH
;
3616 /* If search path is empty use a NULL pointer instead according to MSDN documentation of SearchPath */
3617 LPCTSTR lpszSearchPath
= ustrSystemSearchPath
&& ustrSystemSearchPath
->length
? reinterpret_cast<LPCTSTR
>(ustrSystemSearchPath
->buffer
) : NULL
;
3618 LPCTSTR lpszSearchFile
= reinterpret_cast<LPCTSTR
>(ustrSysPath
->buffer
);
3620 /* Allocate space for buffer according to previous returned count of required chars */
3621 /* +1 is not neccessary if we follow MSDN documentation but for robustness we do so */
3622 nBufferLength
= dwResult
+ 1;
3623 lpBuffer
= lpBuffer
?
3624 reinterpret_cast<LPTSTR
>(rtl_reallocateMemory(lpBuffer
, nBufferLength
* sizeof(TCHAR
))) :
3625 reinterpret_cast<LPTSTR
>(rtl_allocateMemory(nBufferLength
* sizeof(TCHAR
)));
3627 dwResult
= SearchPath( lpszSearchPath
, lpszSearchFile
, NULL
, nBufferLength
, lpBuffer
, &lpszFilePart
);
3628 } while ( dwResult
&& dwResult
>= nBufferLength
);
3630 /* ... until an error occures or buffer is large enough.
3631 dwResult == nBufferLength can not happen according to documentation but lets be robust ;-) */
3635 rtl_uString_newFromStr( &ustrSysPath
, reinterpret_cast<const sal_Unicode
*>(lpBuffer
) );
3636 error
= osl_getFileURLFromSystemPath( ustrSysPath
, pustrPath
);
3640 WIN32_FIND_DATA aFindFileData
;
3643 /* Somthing went wrong, perhaps the path was absolute */
3644 error
= MapError( GetLastError() );
3646 hFind
= FindFirstFile( reinterpret_cast<LPCTSTR
>(ustrSysPath
->buffer
), &aFindFileData
);
3648 if ( IsValidHandle(hFind
) )
3650 error
= osl_getFileURLFromSystemPath( ustrSysPath
, pustrPath
);
3655 rtl_freeMemory( lpBuffer
);
3659 rtl_uString_release( ustrSysPath
);
3662 rtl_uString_release( ustrUNCPath
);
3667 //#####################################################
3669 oslFileError SAL_CALL
osl_getAbsoluteFileURL( rtl_uString
* ustrBaseURL
, rtl_uString
* ustrRelativeURL
, rtl_uString
** pustrAbsoluteURL
)
3671 oslFileError eError
;
3672 rtl_uString
*ustrRelSysPath
= NULL
;
3673 rtl_uString
*ustrBaseSysPath
= NULL
;
3675 if ( ustrBaseURL
&& ustrBaseURL
->length
)
3677 eError
= _osl_getSystemPathFromFileURL( ustrBaseURL
, &ustrBaseSysPath
, sal_False
);
3678 OSL_ENSURE( osl_File_E_None
== eError
, "osl_getAbsoluteFileURL called with relative or invalid base URL" );
3680 eError
= _osl_getSystemPathFromFileURL( ustrRelativeURL
, &ustrRelSysPath
, sal_True
);
3684 eError
= _osl_getSystemPathFromFileURL( ustrRelativeURL
, &ustrRelSysPath
, sal_False
);
3685 OSL_ENSURE( osl_File_E_None
== eError
, "osl_getAbsoluteFileURL called with empty base URL and/or invalid relative URL" );
3690 TCHAR szBuffer
[MAX_PATH
];
3691 TCHAR szCurrentDir
[MAX_PATH
];
3692 LPTSTR lpFilePart
= NULL
;
3696 Bad, bad hack, this only works if the base path
3697 really exists which is not necessary according
3699 The whole FileURL implementation should be merged
3700 with the rtl/uri class.
3702 if ( ustrBaseSysPath
)
3704 osl_acquireMutex( g_CurrentDirectoryMutex
);
3706 GetCurrentDirectory( MAX_PATH
, szCurrentDir
);
3707 SetCurrentDirectory( reinterpret_cast<LPCTSTR
>(ustrBaseSysPath
->buffer
) );
3710 dwResult
= GetFullPathName( reinterpret_cast<LPCTSTR
>(ustrRelSysPath
->buffer
), MAX_PATH
, szBuffer
, &lpFilePart
);
3712 if ( ustrBaseSysPath
)
3714 SetCurrentDirectory( szCurrentDir
);
3716 osl_releaseMutex( g_CurrentDirectoryMutex
);
3721 if ( dwResult
>= MAX_PATH
)
3722 eError
= osl_File_E_INVAL
;
3725 rtl_uString
*ustrAbsSysPath
= NULL
;
3727 rtl_uString_newFromStr( &ustrAbsSysPath
, reinterpret_cast<const sal_Unicode
*>(szBuffer
) );
3729 eError
= osl_getFileURLFromSystemPath( ustrAbsSysPath
, pustrAbsoluteURL
);
3731 if ( ustrAbsSysPath
)
3732 rtl_uString_release( ustrAbsSysPath
);
3736 eError
= MapError( GetLastError() );
3739 if ( ustrBaseSysPath
)
3740 rtl_uString_release( ustrBaseSysPath
);
3742 if ( ustrRelSysPath
)
3743 rtl_uString_release( ustrRelSysPath
);
3748 //#####################################################
3749 oslFileError SAL_CALL
osl_getCanonicalName( rtl_uString
*strRequested
, rtl_uString
**strValid
)
3751 rtl_uString_newFromString(strValid
, strRequested
);
3752 return osl_File_E_None
;