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 ************************************************************************/
33 #define _WIN32_WINNT_0x0500
34 #include "systools/win32/uwinapi.h"
39 #include "file_error.h"
40 #include "path_helper.hxx"
42 #include "osl/diagnose.h"
44 #include "rtl/alloc.h"
45 #include "rtl/ustring.hxx"
49 //#####################################################
50 #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
52 static const wchar_t UNC_PREFIX
[] = L
"\\\\";
53 static const wchar_t BACKSLASH
= '\\';
54 static const wchar_t SLASH
= '/';
56 //#####################################################
57 extern "C" BOOL
TimeValueToFileTime(const TimeValue
*cpTimeVal
, FILETIME
*pFTime
)
59 SYSTEMTIME BaseSysTime
;
60 FILETIME BaseFileTime
;
63 BOOL fSuccess
= FALSE
;
65 BaseSysTime
.wYear
= 1970;
66 BaseSysTime
.wMonth
= 1;
67 BaseSysTime
.wDayOfWeek
= 0;
69 BaseSysTime
.wHour
= 0;
70 BaseSysTime
.wMinute
= 0;
71 BaseSysTime
.wSecond
= 0;
72 BaseSysTime
.wMilliseconds
= 0;
77 if ( SystemTimeToFileTime(&BaseSysTime
, &BaseFileTime
) )
80 localTime
=cpTimeVal
->Seconds
*(__int64
)10000000+cpTimeVal
->Nanosec
/100;
81 *(__int64
*)&FTime
=localTime
;
82 fSuccess
= 0 <= (timeValue
= *((__int64
*)&BaseFileTime
) + *((__int64
*) &FTime
));
84 *(__int64
*)pFTime
=timeValue
;
89 //#####################################################
90 extern "C" BOOL
FileTimeToTimeValue(const FILETIME
*cpFTime
, TimeValue
*pTimeVal
)
92 SYSTEMTIME BaseSysTime
;
93 FILETIME BaseFileTime
;
94 BOOL fSuccess
= FALSE
; /* Assume failure */
96 BaseSysTime
.wYear
= 1970;
97 BaseSysTime
.wMonth
= 1;
98 BaseSysTime
.wDayOfWeek
= 0;
100 BaseSysTime
.wHour
= 0;
101 BaseSysTime
.wMinute
= 0;
102 BaseSysTime
.wSecond
= 0;
103 BaseSysTime
.wMilliseconds
= 0;
105 if ( SystemTimeToFileTime(&BaseSysTime
, &BaseFileTime
) )
109 fSuccess
= 0 <= (Value
= *((__int64
*)cpFTime
) - *((__int64
*)&BaseFileTime
));
113 pTimeVal
->Seconds
= (unsigned long) (Value
/ 10000000L);
114 pTimeVal
->Nanosec
= (unsigned long)((Value
% 10000000L) * 100);
120 //#####################################################
121 namespace /* private */
123 //#####################################################
130 bool isPresent() const
131 { return (static_cast<sal_IntPtr
>(end_
- begin_
) > 0); }
133 const sal_Unicode
* begin_
;
134 const sal_Unicode
* end_
;
137 //#####################################################
145 //#####################################################
146 inline bool is_UNC_path(const sal_Unicode
* path
)
147 { return (0 == wcsncmp(UNC_PREFIX
, reinterpret_cast<LPCWSTR
>(path
), ELEMENTS_OF_ARRAY(UNC_PREFIX
) - 1)); }
149 //#####################################################
150 inline bool is_UNC_path(const rtl::OUString
& path
)
151 { return is_UNC_path(path
.getStr()); }
153 //#####################################################
154 void parse_UNC_path(const sal_Unicode
* path
, UNCComponents
* puncc
)
156 OSL_PRECOND(is_UNC_path(path
), "Precondition violated: No UNC path");
157 OSL_PRECOND(rtl_ustr_indexOfChar(path
, SLASH
) != -1, "Path must not contain slashes");
159 const sal_Unicode
* pend
= path
+ rtl_ustr_getLength(path
);
160 const sal_Unicode
* ppos
= path
+ 2;
162 puncc
->server_
.begin_
= ppos
;
163 while ((ppos
< pend
) && (*ppos
!= BACKSLASH
))
166 puncc
->server_
.end_
= ppos
;
168 if (BACKSLASH
== *ppos
)
170 puncc
->share_
.begin_
= ++ppos
;
171 while ((ppos
< pend
) && (*ppos
!= BACKSLASH
))
174 puncc
->share_
.end_
= ppos
;
176 if (BACKSLASH
== *ppos
)
178 puncc
->resource_
.begin_
= ++ppos
;
182 puncc
->resource_
.end_
= ppos
;
186 OSL_POSTCOND(puncc
->server_
.isPresent() && puncc
->share_
.isPresent(), \
187 "Postcondition violated: Invalid UNC path detected");
190 //#####################################################
191 void parse_UNC_path(const rtl::OUString
& path
, UNCComponents
* puncc
)
192 { parse_UNC_path(path
.getStr(), puncc
); }
195 //#####################################################
196 bool has_path_parent(const sal_Unicode
* path
)
198 // Has the given path a parent or are we already there,
199 // e.g. 'c:\' or '\\server\share\'?
201 bool has_parent
= false;
202 if (is_UNC_path(path
))
204 UNCComponents unc_comp
;
205 parse_UNC_path(path
, &unc_comp
);
206 has_parent
= unc_comp
.resource_
.isPresent();
210 has_parent
= !osl::systemPathIsLogicalDrivePattern(path
);
215 //#####################################################
216 inline bool has_path_parent(const rtl::OUString
& path
)
217 { return has_path_parent(path
.getStr()); }
219 } // end namespace private
221 //#####################################################
222 // volume handling functions
223 //#####################################################
225 //#####################################################
226 oslFileError SAL_CALL
osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle
)
229 return osl_File_E_None
;
231 return osl_File_E_INVAL
;
234 //#####################################################
235 oslFileError SAL_CALL
osl_automountVolumeDevice( oslVolumeDeviceHandle Handle
)
238 return osl_File_E_None
;
240 return osl_File_E_INVAL
;
243 //#####################################################
244 oslFileError SAL_CALL
osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
248 rtl_uString_acquire( (rtl_uString
*)Handle
);
249 return osl_File_E_None
;
252 return osl_File_E_INVAL
;
255 //#####################################################
256 oslFileError SAL_CALL
osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
260 rtl_uString_release( (rtl_uString
*)Handle
);
261 return osl_File_E_None
;
264 return osl_File_E_INVAL
;
267 //#####################################################
268 oslFileError SAL_CALL
osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle
, rtl_uString
**pstrPath
)
270 if ( Handle
&& pstrPath
)
272 rtl_uString_assign( pstrPath
, (rtl_uString
*)Handle
);
273 return osl_File_E_None
;
276 return osl_File_E_INVAL
;
279 //##################################################################
280 // directory handling functions
281 //##################################################################
283 #define DIRECTORYITEM_DRIVE 0
284 #define DIRECTORYITEM_FILE 1
285 #define DIRECTORYITEM_SERVER 2
287 struct DirectoryItem_Impl
291 WIN32_FIND_DATA FindData
;
292 TCHAR cDriveString
[MAX_PATH
];
294 TCHAR szFullPath
[MAX_PATH
];
295 BOOL bFullPathNormalized
;
299 //#####################################################
301 #define DIRECTORYTYPE_LOCALROOT 0
302 #define DIRECTORYTYPE_NETROOT 1
303 #define DIRECTORYTYPE_NETRESORCE 2
304 #define DIRECTORYTYPE_FILESYSTEM 3
306 struct Directory_Impl
313 TCHAR szDirectoryPath
[MAX_PATH
];
316 //#####################################################
318 typedef struct tagDRIVEENUM
321 TCHAR cBuffer
[/*('Z' - 'A' + 1) * sizeof("A:\\") + 1*/256];
323 } DRIVEENUM
, * PDRIVEENUM
, FAR
* LPDRIVEENUM
;
325 //#####################################################
327 static HANDLE WINAPI
OpenLogicalDrivesEnum(void)
329 LPDRIVEENUM pEnum
= (LPDRIVEENUM
)HeapAlloc( GetProcessHeap(), 0, sizeof(DRIVEENUM
) );
332 DWORD dwNumCopied
= GetLogicalDriveStrings( (sizeof(pEnum
->cBuffer
) - 1) / sizeof(TCHAR
), pEnum
->cBuffer
);
334 if ( dwNumCopied
&& dwNumCopied
< sizeof(pEnum
->cBuffer
) / sizeof(TCHAR
) )
336 pEnum
->lpCurrent
= pEnum
->cBuffer
;
337 pEnum
->lpIdent
= L
"tagDRIVEENUM";
341 HeapFree( GetProcessHeap(), 0, pEnum
);
345 return pEnum
? (HANDLE
)pEnum
: INVALID_HANDLE_VALUE
;
348 //#####################################################
349 static BOOL WINAPI
EnumLogicalDrives(HANDLE hEnum
, LPTSTR lpBuffer
)
351 BOOL fSuccess
= FALSE
;
352 LPDRIVEENUM pEnum
= (LPDRIVEENUM
)hEnum
;
356 int nLen
= _tcslen( pEnum
->lpCurrent
);
360 CopyMemory( lpBuffer
, pEnum
->lpCurrent
, (nLen
+ 1) * sizeof(TCHAR
) );
361 pEnum
->lpCurrent
+= nLen
+ 1;
365 SetLastError( ERROR_NO_MORE_FILES
);
368 SetLastError( ERROR_INVALID_HANDLE
);
373 //#####################################################
374 static BOOL WINAPI
CloseLogicalDrivesEnum(HANDLE hEnum
)
376 BOOL fSuccess
= FALSE
;
377 LPDRIVEENUM pEnum
= (LPDRIVEENUM
)hEnum
;
381 HeapFree( GetProcessHeap(), 0, pEnum
);
385 SetLastError( ERROR_INVALID_HANDLE
);
390 //#####################################################
391 typedef struct tagDIRECTORY
394 WIN32_FIND_DATA aFirstData
;
395 } DIRECTORY
, *PDIRECTORY
, FAR
*LPDIRECTORY
;
397 //#####################################################
398 static HANDLE WINAPI
OpenDirectory(LPCTSTR lpszPath
)
400 LPDIRECTORY pDirectory
= (LPDIRECTORY
)HeapAlloc(GetProcessHeap(), 0, sizeof(DIRECTORY
));
404 TCHAR szFileMask
[MAX_PATH
];
407 _tcscpy( szFileMask
, lpszPath
);
408 nLen
= _tcslen( szFileMask
);
410 if (nLen
&& szFileMask
[nLen
-1] != '\\')
411 _tcscat(szFileMask
, TEXT("\\*.*"));
413 _tcscat(szFileMask
, TEXT("*.*"));
415 pDirectory
->hFind
= FindFirstFile(szFileMask
, &pDirectory
->aFirstData
);
417 if (!IsValidHandle(pDirectory
->hFind
))
419 if ( GetLastError() != ERROR_NO_MORE_FILES
)
421 HeapFree(GetProcessHeap(), 0, pDirectory
);
426 return (HANDLE
)pDirectory
;
429 //#####################################################
430 BOOL WINAPI
EnumDirectory(HANDLE hDirectory
, LPWIN32_FIND_DATA pFindData
)
432 BOOL fSuccess
= FALSE
;
433 LPDIRECTORY pDirectory
= (LPDIRECTORY
)hDirectory
;
441 if ( pDirectory
->aFirstData
.cFileName
[0] )
443 *pFindData
= pDirectory
->aFirstData
;
445 pDirectory
->aFirstData
.cFileName
[0] = 0;
447 else if ( IsValidHandle( pDirectory
->hFind
) )
448 fSuccess
= FindNextFile( pDirectory
->hFind
, pFindData
);
452 SetLastError( ERROR_NO_MORE_FILES
);
455 fValid
= fSuccess
&& _tcscmp( TEXT("."), pFindData
->cFileName
) != 0 && _tcscmp( TEXT(".."), pFindData
->cFileName
) != 0;
457 } while( fSuccess
&& !fValid
);
460 SetLastError( ERROR_INVALID_HANDLE
);
465 //#####################################################
466 static BOOL WINAPI
CloseDirectory(HANDLE hDirectory
)
468 BOOL fSuccess
= FALSE
;
469 LPDIRECTORY pDirectory
= (LPDIRECTORY
)hDirectory
;
473 if (IsValidHandle(pDirectory
->hFind
))
474 fSuccess
= FindClose(pDirectory
->hFind
);
476 fSuccess
= HeapFree(GetProcessHeap(), 0, pDirectory
) && fSuccess
;
479 SetLastError(ERROR_INVALID_HANDLE
);
484 //#####################################################
485 static oslFileError
osl_openLocalRoot(
486 rtl_uString
*strDirectoryPath
, oslDirectory
*pDirectory
)
488 rtl_uString
*strSysPath
= NULL
;
492 return osl_File_E_INVAL
;
496 error
= _osl_getSystemPathFromFileURL( strDirectoryPath
, &strSysPath
, sal_False
);
497 if ( osl_File_E_None
== error
)
499 Directory_Impl
*pDirImpl
;
501 pDirImpl
= reinterpret_cast<Directory_Impl
*>(rtl_allocateMemory( sizeof(Directory_Impl
)));
502 _tcscpy( pDirImpl
->szDirectoryPath
, reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(strSysPath
)) );
504 /* Append backslash if neccessary */
507 use function ensure backslash
509 if ( pDirImpl
->szDirectoryPath
[_tcslen(pDirImpl
->szDirectoryPath
) - 1] != L
'\\' )
510 _tcscat( pDirImpl
->szDirectoryPath
, L
"\\" );
512 pDirImpl
->uType
= DIRECTORYTYPE_LOCALROOT
;
513 pDirImpl
->hEnumDrives
= OpenLogicalDrivesEnum();
516 Use IsValidHandle(...)
518 if ( pDirImpl
->hEnumDrives
!= INVALID_HANDLE_VALUE
)
520 *pDirectory
= (oslDirectory
)pDirImpl
;
521 error
= osl_File_E_None
;
526 rtl_freeMemory(pDirImpl
);
528 error
= oslTranslateFileError( GetLastError() );
531 rtl_uString_release( strSysPath
);
536 //#####################################################
537 static oslFileError SAL_CALL
osl_openFileDirectory(
538 rtl_uString
*strDirectoryPath
, oslDirectory
*pDirectory
)
540 oslFileError error
= osl_File_E_None
;
543 return osl_File_E_INVAL
;
546 Directory_Impl
*pDirImpl
= reinterpret_cast<Directory_Impl
*>(rtl_allocateMemory(sizeof(Directory_Impl
)));
547 _tcscpy( pDirImpl
->szDirectoryPath
, reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(strDirectoryPath
)) );
549 /* Append backslash if neccessary */
552 use function ensure backslash
554 if ( pDirImpl
->szDirectoryPath
[_tcslen(pDirImpl
->szDirectoryPath
) - 1] != L
'\\' )
555 _tcscat( pDirImpl
->szDirectoryPath
, L
"\\" );
557 pDirImpl
->uType
= DIRECTORYTYPE_FILESYSTEM
;
558 pDirImpl
->hDirectory
= OpenDirectory( pDirImpl
->szDirectoryPath
);
560 if ( !pDirImpl
->hDirectory
)
562 error
= oslTranslateFileError( GetLastError() );
564 rtl_freeMemory(pDirImpl
), pDirImpl
= 0;
567 *pDirectory
= (oslDirectory
)(pDirImpl
);
571 //#####################################################
572 static oslFileError SAL_CALL
osl_openNetworkServer(
573 rtl_uString
*strSysDirPath
, oslDirectory
*pDirectory
)
575 NETRESOURCEW aNetResource
;
579 ZeroMemory( &aNetResource
, sizeof(aNetResource
) );
581 aNetResource
.lpRemoteName
= reinterpret_cast<LPWSTR
>(strSysDirPath
->buffer
);
583 dwError
= WNetOpenEnumW(
586 RESOURCEUSAGE_CONNECTABLE
| RESOURCEUSAGE_CONTAINER
,
590 if ( ERROR_SUCCESS
== dwError
)
592 Directory_Impl
*pDirImpl
;
594 pDirImpl
= reinterpret_cast<Directory_Impl
*>(rtl_allocateMemory(sizeof(Directory_Impl
)));
595 pDirImpl
->uType
= DIRECTORYTYPE_NETROOT
;
596 pDirImpl
->hDirectory
= hEnum
;
597 *pDirectory
= (oslDirectory
)pDirImpl
;
599 return oslTranslateFileError( dwError
);
602 //#############################################
603 static DWORD
create_dir_with_callback(
604 rtl_uString
* dir_path
,
605 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
608 // Create the specified directory and call the
609 // user specified callback function. On success
610 // the function returns ERROR_SUCCESS else a Win32 error code.
612 if (CreateDirectory(reinterpret_cast<LPCTSTR
>(dir_path
->buffer
), NULL
))
614 if (aDirectoryCreationCallbackFunc
)
617 _osl_getFileURLFromSystemPath(dir_path
, &(url
.pData
));
618 aDirectoryCreationCallbackFunc(pData
, url
.pData
);
620 return ERROR_SUCCESS
;
622 return GetLastError();
625 //#############################################
626 static int path_make_parent(sal_Unicode
* path
)
628 /* Cut off the last part of the given path to
629 get the parent only, e.g. 'c:\dir\subdir' ->
630 'c:\dir' or '\\share\sub\dir' -> '\\share\sub'
631 @return The position where the path has been cut
632 off (this is the posistion of the last backslash).
633 If there are no more parents 0 will be returned,
634 e.g. 'c:\' or '\\Share' have no more parents */
636 OSL_PRECOND(rtl_ustr_indexOfChar(path
, SLASH
) != -1, "Path must not contain slashes");
637 OSL_PRECOND(has_path_parent(path
), "Path must have a parent");
639 sal_Unicode
* pos_last_backslash
= path
+ rtl_ustr_lastIndexOfChar(path
, BACKSLASH
);
640 *pos_last_backslash
= 0;
641 return (pos_last_backslash
- path
);
644 //#############################################
645 static DWORD
create_dir_recursively_(
646 rtl_uString
* dir_path
,
647 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
651 rtl_ustr_lastIndexOfChar_WithLength(dir_path
->buffer
, dir_path
->length
, BACKSLASH
) != dir_path
->length
,
652 "Path must not end with a backslash");
654 DWORD w32_error
= create_dir_with_callback(
655 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
656 if (w32_error
== ERROR_SUCCESS
)
657 return ERROR_SUCCESS
;
659 if ((w32_error
!= ERROR_PATH_NOT_FOUND
) || !has_path_parent(dir_path
->buffer
))
662 int pos
= path_make_parent(dir_path
->buffer
); // dir_path->buffer[pos] = 0, restore below
664 w32_error
= create_dir_recursively_(
665 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
667 dir_path
->buffer
[pos
] = BACKSLASH
; // restore
669 if (ERROR_SUCCESS
!= w32_error
)
672 return create_dir_recursively_(dir_path
, aDirectoryCreationCallbackFunc
, pData
);
675 //#############################################
676 oslFileError SAL_CALL
osl_createDirectoryPath(
677 rtl_uString
* aDirectoryUrl
,
678 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
681 if (aDirectoryUrl
== NULL
)
682 return osl_File_E_INVAL
;
684 rtl::OUString sys_path
;
685 oslFileError osl_error
=
686 _osl_getSystemPathFromFileURL(aDirectoryUrl
, &sys_path
.pData
, sal_False
);
688 if (osl_error
!= osl_File_E_None
)
691 osl::systemPathRemoveSeparator(sys_path
);
693 // const_cast because sys_path is a local copy
694 // which we want to modify inplace instead of
695 // coyp it into another buffer on the heap again
696 return oslTranslateFileError(create_dir_recursively_(
697 sys_path
.pData
, aDirectoryCreationCallbackFunc
, pData
));
700 //#####################################################
701 oslFileError SAL_CALL
osl_createDirectory(rtl_uString
* strPath
)
703 rtl_uString
*strSysPath
= NULL
;
704 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
706 if ( osl_File_E_None
== error
)
708 if ( CreateDirectoryW( reinterpret_cast<LPCWSTR
>(rtl_uString_getStr( strSysPath
)), NULL
) )
709 error
= osl_File_E_None
;
711 The else case is a hack because the ucb or the webtop had some
712 problems with the error code that CreateDirectory returns in
713 case the path is only a logical drive, should be removed!
717 const sal_Unicode
*pBuffer
= rtl_uString_getStr( strSysPath
);
718 sal_Int32 nLen
= rtl_uString_getLength( strSysPath
);
721 ( pBuffer
[0] >= 'A' && pBuffer
[0] <= 'Z' ||
722 pBuffer
[0] >= 'a' && pBuffer
[0] <= 'z' ) &&
723 pBuffer
[1] == ':' && ( nLen
==2 || nLen
== 3 && pBuffer
[2] == '\\' )
725 SetLastError( ERROR_ALREADY_EXISTS
);
727 error
= oslTranslateFileError( GetLastError() );
730 rtl_uString_release( strSysPath
);
735 //#####################################################
736 oslFileError SAL_CALL
osl_removeDirectory(rtl_uString
* strPath
)
738 rtl_uString
*strSysPath
= NULL
;
739 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
741 if ( osl_File_E_None
== error
)
743 if ( RemoveDirectory( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysPath
)) ) )
744 error
= osl_File_E_None
;
746 error
= oslTranslateFileError( GetLastError() );
748 rtl_uString_release( strSysPath
);
753 //#####################################################
754 oslFileError SAL_CALL
osl_openDirectory(rtl_uString
*strDirectoryPath
, oslDirectory
*pDirectory
)
758 if ( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase( strDirectoryPath
->buffer
, "file:///" ) )
759 error
= osl_openLocalRoot( strDirectoryPath
, pDirectory
);
762 rtl_uString
*strSysDirectoryPath
= NULL
;
765 error
= _osl_getSystemPathFromFileURL( strDirectoryPath
, &strSysDirectoryPath
, sal_False
);
767 if ( osl_File_E_None
!= error
)
770 dwPathType
= IsValidFilePath( strSysDirectoryPath
, NULL
, VALIDATEPATH_NORMAL
, NULL
);
772 if ( dwPathType
& PATHTYPE_IS_SERVER
)
774 error
= osl_openNetworkServer( strSysDirectoryPath
, pDirectory
);
777 error
= osl_openFileDirectory( strSysDirectoryPath
, pDirectory
);
779 rtl_uString_release( strSysDirectoryPath
);
784 //#####################################################
785 static oslFileError SAL_CALL
osl_getNextNetResource(
786 oslDirectory Directory
, oslDirectoryItem
*pItem
, sal_uInt32 uHint
)
788 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
789 DirectoryItem_Impl
*pItemImpl
= NULL
;
791 LPNETRESOURCEW lpNetResource
= (LPNETRESOURCEW
)buffer
;
792 DWORD dwError
, dwCount
, dwBufSize
;
794 uHint
= uHint
; /* to get no warning */
797 return osl_File_E_INVAL
;
801 return osl_File_E_INVAL
;
804 dwBufSize
= sizeof(buffer
);
805 dwError
= WNetEnumResource( pDirImpl
->hDirectory
, &dwCount
, lpNetResource
, &dwBufSize
);
810 case ERROR_MORE_DATA
:
812 pItemImpl
= reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
814 return osl_File_E_NOMEM
;
816 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
817 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
818 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
820 wcscpy( pItemImpl
->cDriveString
, lpNetResource
->lpRemoteName
);
824 return osl_File_E_None
;
825 case ERROR_NO_MORE_ITEMS
:
826 return osl_File_E_NOENT
;
828 return oslTranslateFileError( dwError
);
832 //#####################################################
833 static oslFileError SAL_CALL
osl_getNextDrive(
834 oslDirectory Directory
, oslDirectoryItem
*pItem
, sal_uInt32 uHint
)
836 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
837 DirectoryItem_Impl
*pItemImpl
= NULL
;
840 uHint
= uHint
; /* avoid warnings */
843 return osl_File_E_INVAL
;
847 return osl_File_E_INVAL
;
849 pItemImpl
= reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
851 return osl_File_E_NOMEM
;
853 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
854 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
855 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
856 fSuccess
= EnumLogicalDrives( pDirImpl
->hEnumDrives
, pItemImpl
->cDriveString
);
861 return osl_File_E_None
;
865 rtl_freeMemory( pItemImpl
);
866 return oslTranslateFileError( GetLastError() );
870 //#####################################################
871 static oslFileError SAL_CALL
osl_getNextFileItem(
872 oslDirectory Directory
, oslDirectoryItem
*pItem
, sal_uInt32 uHint
)
874 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
875 DirectoryItem_Impl
*pItemImpl
= NULL
;
878 uHint
= uHint
; /* avoid warnings */
881 return osl_File_E_INVAL
;
885 return osl_File_E_INVAL
;
887 pItemImpl
= reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
889 return osl_File_E_NOMEM
;
891 memset( pItemImpl
, 0, sizeof(DirectoryItem_Impl
) );
892 fFound
= EnumDirectory( pDirImpl
->hDirectory
, &pItemImpl
->FindData
);
896 pItemImpl
->uType
= DIRECTORYITEM_FILE
;
897 pItemImpl
->nRefCount
= 1;
898 _tcscpy( pItemImpl
->szFullPath
, pDirImpl
->szDirectoryPath
);
899 _tcscat( pItemImpl
->szFullPath
, pItemImpl
->FindData
.cFileName
);
900 pItemImpl
->bFullPathNormalized
= FALSE
;
901 *pItem
= (oslDirectoryItem
)pItemImpl
;
902 return osl_File_E_None
;
906 rtl_freeMemory( pItemImpl
);
907 return oslTranslateFileError( GetLastError() );
911 //#####################################################
912 oslFileError SAL_CALL
osl_getNextDirectoryItem(
913 oslDirectory Directory
, oslDirectoryItem
*pItem
, sal_uInt32 uHint
)
915 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
920 return osl_File_E_INVAL
;
924 return osl_File_E_INVAL
;
926 switch ( pDirImpl
->uType
)
928 case DIRECTORYTYPE_LOCALROOT
:
929 return osl_getNextDrive( Directory
, pItem
, uHint
);
930 case DIRECTORYTYPE_NETROOT
:
931 return osl_getNextNetResource( Directory
, pItem
, uHint
);
932 case DIRECTORYTYPE_FILESYSTEM
:
933 return osl_getNextFileItem( Directory
, pItem
, uHint
);
935 return osl_File_E_INVAL
;
939 //#####################################################
940 oslFileError SAL_CALL
osl_closeDirectory(oslDirectory Directory
)
942 Directory_Impl
*pDirImpl
= (Directory_Impl
*)Directory
;
943 oslFileError eError
= osl_File_E_INVAL
;
947 switch ( pDirImpl
->uType
)
949 case DIRECTORYTYPE_FILESYSTEM
:
950 eError
= CloseDirectory( pDirImpl
->hDirectory
) ? osl_File_E_None
: oslTranslateFileError( GetLastError() );
952 case DIRECTORYTYPE_LOCALROOT
:
953 eError
= CloseLogicalDrivesEnum( pDirImpl
->hEnumDrives
) ? osl_File_E_None
: oslTranslateFileError( GetLastError() );
955 case DIRECTORYTYPE_NETROOT
:
957 DWORD err
= WNetCloseEnum(pDirImpl
->hDirectory
);
958 eError
= (err
== NO_ERROR
) ? osl_File_E_None
: oslTranslateFileError(err
);
962 OSL_ENSURE( 0, "Invalid directory type" );
966 rtl_freeMemory(pDirImpl
);
971 //#####################################################
972 /* Different types of paths */
973 typedef enum _PATHTYPE
975 PATHTYPE_SYNTAXERROR
= 0,
982 oslFileError SAL_CALL
osl_getDirectoryItem(rtl_uString
*strFilePath
, oslDirectoryItem
*pItem
)
984 oslFileError error
= osl_File_E_None
;
985 rtl_uString
* strSysFilePath
= NULL
;
986 PATHTYPE type
= PATHTYPE_FILE
;
992 return osl_File_E_INVAL
;
997 error
= _osl_getSystemPathFromFileURL( strFilePath
, &strSysFilePath
, sal_False
);
999 if ( osl_File_E_None
!= error
)
1002 dwPathType
= IsValidFilePath( strSysFilePath
, NULL
, VALIDATEPATH_NORMAL
, NULL
);
1004 if ( dwPathType
& PATHTYPE_IS_VOLUME
)
1005 type
= PATHTYPE_VOLUME
;
1006 else if ( dwPathType
& PATHTYPE_IS_SERVER
)
1007 type
= PATHTYPE_NETSERVER
;
1009 type
= PATHTYPE_FILE
;
1013 case PATHTYPE_NETSERVER
:
1015 DirectoryItem_Impl
* pItemImpl
=
1016 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
1019 error
= osl_File_E_NOMEM
;
1021 if ( osl_File_E_None
== error
)
1023 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
1024 pItemImpl
->uType
= DIRECTORYITEM_SERVER
;
1026 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
1028 _tcscpy( pItemImpl
->szFullPath
, reinterpret_cast<LPCTSTR
>(strSysFilePath
->buffer
) );
1030 // Assign a title anyway
1035 while( iSrc
< strSysFilePath
->length
&& strSysFilePath
->buffer
[iSrc
] && strSysFilePath
->buffer
[iSrc
] != '\\' )
1037 pItemImpl
->FindData
.cFileName
[iDst
++] = strSysFilePath
->buffer
[iSrc
++];
1045 case PATHTYPE_VOLUME
:
1047 DirectoryItem_Impl
* pItemImpl
=
1048 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
1051 error
= osl_File_E_NOMEM
;
1053 if ( osl_File_E_None
== error
)
1055 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
1056 pItemImpl
->uType
= DIRECTORYITEM_DRIVE
;
1058 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
1060 _tcscpy( pItemImpl
->cDriveString
, reinterpret_cast<LPCTSTR
>(strSysFilePath
->buffer
) );
1061 pItemImpl
->cDriveString
[0] = _toupper( pItemImpl
->cDriveString
[0] );
1063 if ( pItemImpl
->cDriveString
[_tcslen(pItemImpl
->cDriveString
) - 1] != '\\' )
1064 _tcscat( pItemImpl
->cDriveString
, TEXT( "\\" ) );
1070 case PATHTYPE_SYNTAXERROR
:
1071 case PATHTYPE_NETROOT
:
1075 WIN32_FIND_DATA aFindData
;
1077 if ( strSysFilePath
->length
> 0 && strSysFilePath
->buffer
[strSysFilePath
->length
- 1] == '\\' )
1078 rtl_uString_newFromStr_WithLength( &strSysFilePath
, strSysFilePath
->buffer
, strSysFilePath
->length
- 1 );
1080 hFind
= FindFirstFile( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(strSysFilePath
)), &aFindData
);
1082 if ( hFind
!= INVALID_HANDLE_VALUE
)
1084 DirectoryItem_Impl
*pItemImpl
=
1085 reinterpret_cast<DirectoryItem_Impl
*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl
)));
1087 ZeroMemory( pItemImpl
, sizeof(DirectoryItem_Impl
) );
1088 osl_acquireDirectoryItem( (oslDirectoryItem
)pItemImpl
);
1090 CopyMemory( &pItemImpl
->FindData
, &aFindData
, sizeof(WIN32_FIND_DATA
) );
1091 _tcscpy( pItemImpl
->szFullPath
, reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(strSysFilePath
)) );
1093 // MT: This costs 600ms startup time on fast v60x!
1094 // GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) );
1096 pItemImpl
->uType
= DIRECTORYITEM_FILE
;
1101 error
= oslTranslateFileError( GetLastError() );
1106 if ( strSysFilePath
)
1107 rtl_uString_release( strSysFilePath
);
1112 //#####################################################
1113 oslFileError SAL_CALL
osl_acquireDirectoryItem( oslDirectoryItem Item
)
1115 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
1118 return osl_File_E_INVAL
;
1120 pItemImpl
->nRefCount
++;
1121 return osl_File_E_None
;
1124 //#####################################################
1125 oslFileError SAL_CALL
osl_releaseDirectoryItem( oslDirectoryItem Item
)
1127 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
1130 return osl_File_E_INVAL
;
1132 if ( ! --pItemImpl
->nRefCount
)
1133 rtl_freeMemory( pItemImpl
);
1134 return osl_File_E_None
;
1137 //#####################################################
1138 // volume / file info handling functions
1139 //#####################################################
1141 //#####################################################
1142 static inline bool is_floppy_A_present()
1143 { return (GetLogicalDrives() & 1); }
1145 //#####################################################
1146 static inline bool is_floppy_B_present()
1147 { return (GetLogicalDrives() & 2); }
1149 //#####################################################
1150 bool is_floppy_volume_mount_point(const rtl::OUString
& path
)
1152 // determines if a volume mount point shows to a floppy
1153 // disk by comparing the unique volume names
1154 static const LPWSTR FLOPPY_A
= L
"A:\\";
1155 static const LPWSTR FLOPPY_B
= L
"B:\\";
1157 rtl::OUString
p(path
);
1158 osl::systemPathEnsureSeparator(p
);
1161 if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR
>(p
.getStr()), vn
, ELEMENTS_OF_ARRAY(vn
)))
1164 if (is_floppy_A_present() &&
1165 GetVolumeNameForVolumeMountPoint(FLOPPY_A
, vnfloppy
, ELEMENTS_OF_ARRAY(vnfloppy
)) &&
1166 (0 == wcscmp(vn
, vnfloppy
)))
1169 if (is_floppy_B_present() &&
1170 GetVolumeNameForVolumeMountPoint(FLOPPY_B
, vnfloppy
, ELEMENTS_OF_ARRAY(vnfloppy
)) &&
1171 (0 == wcscmp(vn
, vnfloppy
)))
1177 //################################################
1178 static bool is_floppy_drive(const rtl::OUString
& path
)
1180 static const LPWSTR FLOPPY_DRV_LETTERS
= TEXT("AaBb");
1182 // we must take into account that even a floppy
1183 // drive may be mounted to a directory so checking
1184 // for the drive letter alone is not sufficient
1185 // we must compare the unique volume name with
1186 // that of the available floppy disks
1188 const sal_Unicode
* pszPath
= path
.getStr();
1189 return ((wcschr(FLOPPY_DRV_LETTERS
, pszPath
[0]) && (L
':' == pszPath
[1])) || is_floppy_volume_mount_point(path
));
1192 //#####################################################
1193 static bool is_volume_mount_point(const rtl::OUString
& path
)
1195 rtl::OUString
p(path
);
1196 osl::systemPathRemoveSeparator(p
);
1198 bool is_volume_root
= false;
1200 if (!is_floppy_drive(p
))
1202 DWORD fattr
= GetFileAttributes(reinterpret_cast<LPCTSTR
>(p
.getStr()));
1204 if ((INVALID_FILE_ATTRIBUTES
!= fattr
) &&
1205 (FILE_ATTRIBUTE_REPARSE_POINT
& fattr
))
1207 WIN32_FIND_DATA find_data
;
1208 HANDLE h_find
= FindFirstFile(reinterpret_cast<LPCTSTR
>(p
.getStr()), &find_data
);
1210 if (IsValidHandle(h_find
) &&
1211 (FILE_ATTRIBUTE_REPARSE_POINT
& find_data
.dwFileAttributes
) &&
1212 (IO_REPARSE_TAG_MOUNT_POINT
== find_data
.dwReserved0
))
1214 is_volume_root
= true;
1216 if (IsValidHandle(h_find
))
1220 return is_volume_root
;
1223 //#############################################
1224 static UINT
get_volume_mount_point_drive_type(const rtl::OUString
& path
)
1226 if (0 == path
.getLength())
1227 return GetDriveType(NULL
);
1229 rtl::OUString
p(path
);
1230 osl::systemPathEnsureSeparator(p
);
1233 if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR
>(p
.getStr()), vn
, ELEMENTS_OF_ARRAY(vn
)))
1234 return GetDriveType(vn
);
1236 return DRIVE_NO_ROOT_DIR
;
1239 //#############################################
1240 static inline bool is_drivetype_request(sal_uInt32 field_mask
)
1242 return (field_mask
& osl_VolumeInfo_Mask_Attributes
);
1245 //#############################################
1246 static oslFileError
osl_get_drive_type(
1247 const rtl::OUString
& path
, oslVolumeInfo
* pInfo
)
1249 // GetDriveType fails on empty volume mount points
1250 // see Knowledge Base Q244089
1252 if (is_volume_mount_point(path
))
1253 drive_type
= get_volume_mount_point_drive_type(path
);
1255 drive_type
= GetDriveType(reinterpret_cast<LPCTSTR
>(path
.getStr()));
1257 if (DRIVE_NO_ROOT_DIR
== drive_type
)
1258 return oslTranslateFileError(ERROR_INVALID_DRIVE
);
1260 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1265 pInfo
->uAttributes
|= osl_Volume_Attribute_CompactDisc
| osl_Volume_Attribute_Removeable
;
1267 case DRIVE_REMOVABLE
:
1268 pInfo
->uAttributes
|= osl_Volume_Attribute_Removeable
;
1269 if (is_floppy_drive(path
))
1270 pInfo
->uAttributes
|= osl_Volume_Attribute_FloppyDisk
;
1273 pInfo
->uAttributes
|= osl_Volume_Attribute_FixedDisk
;
1276 pInfo
->uAttributes
|= osl_Volume_Attribute_RAMDisk
;
1279 pInfo
->uAttributes
|= osl_Volume_Attribute_Remote
;
1282 pInfo
->uAttributes
= 0;
1285 pInfo
->uValidFields
&= ~osl_VolumeInfo_Mask_Attributes
;
1286 pInfo
->uAttributes
= 0;
1289 return osl_File_E_None
;
1292 //#############################################
1293 static inline bool is_volume_space_info_request(sal_uInt32 field_mask
)
1295 return (field_mask
&
1296 (osl_VolumeInfo_Mask_TotalSpace
|
1297 osl_VolumeInfo_Mask_UsedSpace
|
1298 osl_VolumeInfo_Mask_FreeSpace
));
1301 //#############################################
1302 static void get_volume_space_information(
1303 const rtl::OUString
& path
, oslVolumeInfo
*pInfo
)
1305 BOOL ret
= GetDiskFreeSpaceEx(
1306 reinterpret_cast<LPCTSTR
>(path
.getStr()),
1307 (PULARGE_INTEGER
)&(pInfo
->uFreeSpace
),
1308 (PULARGE_INTEGER
)&(pInfo
->uTotalSpace
),
1313 pInfo
->uUsedSpace
= pInfo
->uTotalSpace
- pInfo
->uFreeSpace
;
1314 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_TotalSpace
|
1315 osl_VolumeInfo_Mask_UsedSpace
|
1316 osl_VolumeInfo_Mask_FreeSpace
;
1320 //#############################################
1321 static inline bool is_filesystem_attributes_request(sal_uInt32 field_mask
)
1323 return (field_mask
&
1324 (osl_VolumeInfo_Mask_MaxNameLength
|
1325 osl_VolumeInfo_Mask_MaxPathLength
|
1326 osl_VolumeInfo_Mask_FileSystemName
|
1327 osl_VolumeInfo_Mask_FileSystemCaseHandling
));
1330 //#############################################
1331 static oslFileError
get_filesystem_attributes(
1332 const rtl::OUString
& path
, sal_uInt32 field_mask
, oslVolumeInfo
* pInfo
)
1334 pInfo
->uAttributes
= 0;
1336 // osl_get_drive_type must be called first because
1337 // this function resets osl_VolumeInfo_Mask_Attributes
1339 if (is_drivetype_request(field_mask
))
1341 oslFileError osl_error
= osl_get_drive_type(path
, pInfo
);
1342 if (osl_File_E_None
!= osl_error
)
1345 if (is_filesystem_attributes_request(field_mask
))
1348 WCHAR fsn
[MAX_PATH
];
1353 LPCTSTR pszPath
= reinterpret_cast<LPCTSTR
>(path
.getStr());
1354 if (GetVolumeInformation(pszPath
, vn
, MAX_PATH
, &serial
, &mcl
, &flags
, fsn
, MAX_PATH
))
1356 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxNameLength
;
1357 pInfo
->uMaxNameLength
= mcl
;
1359 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxPathLength
;
1360 pInfo
->uMaxPathLength
= MAX_PATH
;
1362 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FileSystemName
;
1363 rtl_uString_newFromStr(&pInfo
->ustrFileSystemName
, reinterpret_cast<const sal_Unicode
*>(fsn
));
1365 // volumes (even NTFS) will always be considered case
1366 // insensitive because the Win32 API is not able to
1367 // deal with case sensitive volumes see M$ Knowledge Base
1368 // article 100625 that's why we never set the attribute
1369 // osl_Volume_Attribute_Case_Sensitive
1371 if (flags
& FS_CASE_IS_PRESERVED
)
1372 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Is_Preserved
;
1374 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1377 return osl_File_E_None
;
1380 //#####################################################
1381 static bool path_get_parent(rtl::OUString
& path
)
1383 OSL_PRECOND(path
.lastIndexOf(SLASH
) == -1, "Path must not have slashes");
1385 if (!has_path_parent(path
))
1387 sal_Int32 i
= path
.lastIndexOf(BACKSLASH
);
1390 path
= rtl::OUString(path
.getStr(), i
);
1397 //#####################################################
1398 static void path_travel_to_volume_root(const rtl::OUString
& system_path
, rtl::OUString
& volume_root
)
1400 rtl::OUString
sys_path(system_path
);
1402 while(!is_volume_mount_point(sys_path
) && path_get_parent(sys_path
))
1405 volume_root
= sys_path
;
1406 osl::systemPathEnsureSeparator(volume_root
);
1409 //#############################################
1410 oslFileError SAL_CALL
osl_getVolumeInformation(
1411 rtl_uString
*ustrURL
, oslVolumeInfo
*pInfo
, sal_uInt32 uFieldMask
)
1414 return osl_File_E_INVAL
;
1416 rtl::OUString system_path
;
1417 oslFileError error
= _osl_getSystemPathFromFileURL(ustrURL
, &system_path
.pData
, sal_False
);
1419 if (osl_File_E_None
!= error
)
1422 rtl::OUString volume_root
;
1423 path_travel_to_volume_root(system_path
, volume_root
);
1425 pInfo
->uValidFields
= 0;
1427 if ((error
= get_filesystem_attributes(volume_root
, uFieldMask
, pInfo
)) != osl_File_E_None
)
1430 if (is_volume_space_info_request(uFieldMask
))
1431 get_volume_space_information(volume_root
, pInfo
);
1433 if (uFieldMask
& osl_VolumeInfo_Mask_DeviceHandle
)
1435 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_DeviceHandle
;
1436 osl_getFileURLFromSystemPath(volume_root
.pData
, (rtl_uString
**)&pInfo
->pDeviceHandle
);
1439 return osl_File_E_None
;
1442 //#####################################################
1443 static oslFileError SAL_CALL
osl_getDriveInfo(
1444 oslDirectoryItem Item
, oslFileStatus
*pStatus
, sal_uInt32 uFieldMask
)
1446 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
1447 TCHAR cDrive
[3] = TEXT("A:");
1448 TCHAR cRoot
[4] = TEXT("A:\\");
1451 return osl_File_E_INVAL
;
1453 pStatus
->uValidFields
= 0;
1455 cDrive
[0] = pItemImpl
->cDriveString
[0];
1456 cRoot
[0] = pItemImpl
->cDriveString
[0];
1458 if ( uFieldMask
& osl_FileStatus_Mask_FileName
)
1460 if ( pItemImpl
->cDriveString
[0] == '\\' && pItemImpl
->cDriveString
[1] == '\\' )
1462 LPCWSTR lpFirstBkSlash
= wcschr( &pItemImpl
->cDriveString
[2], '\\' );
1464 if ( lpFirstBkSlash
&& lpFirstBkSlash
[1] )
1466 LPCWSTR lpLastBkSlash
= wcschr( &lpFirstBkSlash
[1], '\\' );
1468 if ( lpLastBkSlash
)
1469 rtl_uString_newFromStr_WithLength( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(&lpFirstBkSlash
[1]), lpLastBkSlash
- lpFirstBkSlash
- 1 );
1471 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(&lpFirstBkSlash
[1]) );
1472 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1475 else switch ( GetDriveType( cRoot
) )
1479 TCHAR szBuffer
[1024];
1480 DWORD
const dwBufsizeConst
= ELEMENTS_OF_ARRAY(szBuffer
);
1481 DWORD dwBufsize
= dwBufsizeConst
;
1483 DWORD dwResult
= WNetGetConnection( cDrive
, szBuffer
, &dwBufsize
);
1484 if ( NO_ERROR
== dwResult
)
1486 TCHAR szFileName
[dwBufsizeConst
+ 16];
1488 swprintf( szFileName
, L
"%s [%s]", cDrive
, szBuffer
);
1489 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(szFileName
) );
1492 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(cDrive
) );
1494 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1498 TCHAR szVolumeNameBuffer
[1024];
1499 DWORD
const dwBufsizeConst
= ELEMENTS_OF_ARRAY(szVolumeNameBuffer
);
1501 if ( GetVolumeInformation( cRoot
, szVolumeNameBuffer
, dwBufsizeConst
, NULL
, NULL
, NULL
, NULL
, 0 ) )
1503 TCHAR szFileName
[dwBufsizeConst
+ 16];
1505 swprintf( szFileName
, L
"%s [%s]", cDrive
, szVolumeNameBuffer
);
1506 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(szFileName
) );
1509 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(cDrive
) );
1511 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1514 case DRIVE_REMOVABLE
:
1515 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1516 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(cRoot
) );
1524 pStatus
->eType
= osl_File_Type_Volume
;
1525 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
1527 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
1529 rtl_uString
*ustrSystemPath
= NULL
;
1531 rtl_uString_newFromStr( &ustrSystemPath
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->cDriveString
) );
1532 osl_getFileURLFromSystemPath( ustrSystemPath
, &pStatus
->ustrFileURL
);
1533 rtl_uString_release( ustrSystemPath
);
1534 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileURL
;
1536 return osl_File_E_None
;
1539 //#####################################################
1540 static oslFileError SAL_CALL
osl_getServerInfo(
1541 oslDirectoryItem Item
, oslFileStatus
*pStatus
, sal_uInt32 uFieldMask
)
1543 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
1545 return osl_File_E_INVAL
;
1547 pStatus
->uValidFields
= 0;
1549 // pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1551 // if ( _tcscmp( pItemImpl->FindData.cFileName, TEXT(".") ) == 0 )
1552 // rtl_uString_newFromAscii( &pStatus->ustrFileName, "/" );
1554 // rtl_uString_newFromStr( &pStatus->ustrFileName, pItemImpl->FindData.cFileName );
1556 pStatus
->eType
= osl_File_Type_Directory
;
1557 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
1559 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
1561 rtl_uString
*ustrSystemPath
= NULL
;
1563 rtl_uString_newFromStr( &ustrSystemPath
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->szFullPath
) );
1564 osl_getFileURLFromSystemPath( ustrSystemPath
, &pStatus
->ustrFileURL
);
1565 rtl_uString_release( ustrSystemPath
);
1566 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileURL
;
1568 return osl_File_E_None
;
1571 //#############################################
1572 oslFileError SAL_CALL
osl_getFileStatus(
1573 oslDirectoryItem Item
,
1574 oslFileStatus
*pStatus
,
1575 sal_uInt32 uFieldMask
)
1577 DirectoryItem_Impl
*pItemImpl
= (DirectoryItem_Impl
*)Item
;
1580 return osl_File_E_INVAL
;
1582 switch ( pItemImpl
->uType
)
1584 case DIRECTORYITEM_DRIVE
:
1585 return osl_getDriveInfo( Item
, pStatus
, uFieldMask
);
1586 case DIRECTORYITEM_SERVER
:
1587 return osl_getServerInfo( Item
, pStatus
, uFieldMask
);
1592 if ( uFieldMask
& osl_FileStatus_Mask_Validate
)
1594 HANDLE hFind
= FindFirstFile( pItemImpl
->szFullPath
, &pItemImpl
->FindData
);
1596 if ( hFind
!= INVALID_HANDLE_VALUE
)
1599 return oslTranslateFileError( GetLastError() );
1601 uFieldMask
&= ~ osl_FileStatus_Mask_Validate
;
1604 /* If no fields to retrieve left ignore pStatus */
1606 return osl_File_E_None
;
1608 /* Otherwise, this must be a valid pointer */
1610 return osl_File_E_INVAL
;
1612 if ( pStatus
->uStructSize
!= sizeof(oslFileStatus
) )
1613 return osl_File_E_INVAL
;
1615 pStatus
->uValidFields
= 0;
1617 /* File time stamps */
1619 if ( (uFieldMask
& osl_FileStatus_Mask_ModifyTime
) &&
1620 FileTimeToTimeValue( &pItemImpl
->FindData
.ftLastWriteTime
, &pStatus
->aModifyTime
) )
1621 pStatus
->uValidFields
|= osl_FileStatus_Mask_ModifyTime
;
1623 if ( (uFieldMask
& osl_FileStatus_Mask_AccessTime
) &&
1624 FileTimeToTimeValue( &pItemImpl
->FindData
.ftLastAccessTime
, &pStatus
->aAccessTime
) )
1625 pStatus
->uValidFields
|= osl_FileStatus_Mask_AccessTime
;
1627 if ( (uFieldMask
& osl_FileStatus_Mask_CreationTime
) &&
1628 FileTimeToTimeValue( &pItemImpl
->FindData
.ftCreationTime
, &pStatus
->aCreationTime
) )
1629 pStatus
->uValidFields
|= osl_FileStatus_Mask_CreationTime
;
1631 /* Most of the fields are already set, regardless of requiered fields */
1633 rtl_uString_newFromStr( &pStatus
->ustrFileName
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->FindData
.cFileName
) );
1634 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileName
;
1636 if ((FILE_ATTRIBUTE_REPARSE_POINT
& pItemImpl
->FindData
.dwFileAttributes
) &&
1637 (IO_REPARSE_TAG_MOUNT_POINT
== pItemImpl
->FindData
.dwReserved0
))
1638 pStatus
->eType
= osl_File_Type_Volume
;
1639 else if (pItemImpl
->FindData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1640 pStatus
->eType
= osl_File_Type_Directory
;
1642 pStatus
->eType
= osl_File_Type_Regular
;
1644 pStatus
->uValidFields
|= osl_FileStatus_Mask_Type
;
1646 pStatus
->uAttributes
= pItemImpl
->FindData
.dwFileAttributes
;
1647 pStatus
->uValidFields
|= osl_FileStatus_Mask_Attributes
;
1649 pStatus
->uFileSize
= (sal_uInt64
)pItemImpl
->FindData
.nFileSizeLow
+ ((sal_uInt64
)pItemImpl
->FindData
.nFileSizeHigh
<< 32);
1650 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileSize
;
1652 if ( uFieldMask
& osl_FileStatus_Mask_LinkTargetURL
)
1654 rtl_uString
*ustrFullPath
= NULL
;
1656 rtl_uString_newFromStr( &ustrFullPath
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->szFullPath
) );
1657 osl_getFileURLFromSystemPath( ustrFullPath
, &pStatus
->ustrLinkTargetURL
);
1658 rtl_uString_release( ustrFullPath
);
1660 pStatus
->uValidFields
|= osl_FileStatus_Mask_LinkTargetURL
;
1663 if ( uFieldMask
& osl_FileStatus_Mask_FileURL
)
1665 rtl_uString
*ustrFullPath
= NULL
;
1668 if ( !pItemImpl
->bFullPathNormalized
)
1670 GetCaseCorrectPathName( pItemImpl
->szFullPath
, pItemImpl
->szFullPath
, sizeof(pItemImpl
->szFullPath
) );
1671 pItemImpl
->bFullPathNormalized
= TRUE
;
1673 rtl_uString_newFromStr( &ustrFullPath
, reinterpret_cast<const sal_Unicode
*>(pItemImpl
->szFullPath
) );
1674 osl_getFileURLFromSystemPath( ustrFullPath
, &pStatus
->ustrFileURL
);
1675 rtl_uString_release( ustrFullPath
);
1676 pStatus
->uValidFields
|= osl_FileStatus_Mask_FileURL
;
1679 return osl_File_E_None
;
1682 //#####################################################
1683 // file attributes handling functions
1684 //#####################################################
1686 //#############################################
1687 oslFileError SAL_CALL
osl_setFileAttributes(
1688 rtl_uString
*ustrFileURL
,
1689 sal_uInt64 uAttributes
)
1692 rtl_uString
*ustrSysPath
= NULL
;
1693 DWORD dwFileAttributes
;
1696 // Converts the normalized path into a systempath
1697 error
= _osl_getSystemPathFromFileURL( ustrFileURL
, &ustrSysPath
, sal_False
);
1699 if ( osl_File_E_None
!= error
)
1702 dwFileAttributes
= GetFileAttributes( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(ustrSysPath
)) );
1704 if ( (DWORD
)-1 != dwFileAttributes
)
1706 dwFileAttributes
&= ~(FILE_ATTRIBUTE_READONLY
| FILE_ATTRIBUTE_HIDDEN
);
1708 if ( uAttributes
& osl_File_Attribute_ReadOnly
)
1709 dwFileAttributes
|= FILE_ATTRIBUTE_READONLY
;
1711 if ( uAttributes
& osl_File_Attribute_Hidden
)
1712 dwFileAttributes
|= FILE_ATTRIBUTE_HIDDEN
;
1714 fSuccess
= SetFileAttributes( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr(ustrSysPath
)), dwFileAttributes
);
1720 error
= oslTranslateFileError( GetLastError() );
1722 rtl_uString_release( ustrSysPath
);
1727 //#####################################################
1728 oslFileError SAL_CALL
osl_setFileTime(
1729 rtl_uString
*filePath
,
1730 const TimeValue
*aCreationTime
,
1731 const TimeValue
*aLastAccessTime
,
1732 const TimeValue
*aLastWriteTime
)
1735 rtl_uString
*sysPath
=NULL
;
1736 FILETIME
*lpCreationTime
=NULL
;
1737 FILETIME
*lpLastAccessTime
=NULL
;
1738 FILETIME
*lpLastWriteTime
=NULL
;
1739 FILETIME ftCreationTime
;
1740 FILETIME ftLastAccessTime
;
1741 FILETIME ftLastWriteTime
;
1746 error
=_osl_getSystemPathFromFileURL(filePath
, &sysPath
, sal_False
);
1748 if (error
==osl_File_E_INVAL
)
1751 hFile
=CreateFileW(reinterpret_cast<LPCWSTR
>(rtl_uString_getStr(sysPath
)), GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1752 rtl_uString_release(sysPath
);
1754 if (hFile
==INVALID_HANDLE_VALUE
)
1755 return osl_File_E_NOENT
;
1757 if (TimeValueToFileTime(aCreationTime
, &ftCreationTime
))
1758 lpCreationTime
=&ftCreationTime
;
1760 if (TimeValueToFileTime(aLastAccessTime
, &ftLastAccessTime
))
1761 lpLastAccessTime
=&ftLastAccessTime
;
1763 if (TimeValueToFileTime(aLastWriteTime
, &ftLastWriteTime
))
1764 lpLastWriteTime
=&ftLastWriteTime
;
1766 fSuccess
=SetFileTime(hFile
, lpCreationTime
, lpLastAccessTime
, lpLastWriteTime
);
1771 return osl_File_E_INVAL
;
1773 return osl_File_E_None
;