xref: /aoo41x/main/sal/osl/w32/file_dirvol.cxx (revision 1102d251)
187d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
387d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
487d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
587d2adbcSAndrew Rist  * distributed with this work for additional information
687d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
787d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
887d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
987d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
1087d2adbcSAndrew Rist  *
1187d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1287d2adbcSAndrew Rist  *
1387d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1487d2adbcSAndrew Rist  * software distributed under the License is distributed on an
1587d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1687d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
1787d2adbcSAndrew Rist  * specific language governing permissions and limitations
1887d2adbcSAndrew Rist  * under the License.
1987d2adbcSAndrew Rist  *
2087d2adbcSAndrew Rist  *************************************************************/
2187d2adbcSAndrew Rist 
2287d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #define UNICODE
25cdf0e10cSrcweir #define _UNICODE
26cdf0e10cSrcweir #define _WIN32_WINNT_0x0500
27cdf0e10cSrcweir #include "systools/win32/uwinapi.h"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "osl/file.h"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "file_url.h"
32cdf0e10cSrcweir #include "file_error.h"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include "path_helper.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include "osl/diagnose.h"
37cdf0e10cSrcweir #include "osl/time.h"
38cdf0e10cSrcweir #include "rtl/alloc.h"
39cdf0e10cSrcweir #include "rtl/ustring.hxx"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include <tchar.h>
42cdf0e10cSrcweir #ifdef __MINGW32__
43cdf0e10cSrcweir #include <ctype.h>
44cdf0e10cSrcweir #endif
45cdf0e10cSrcweir 
46cdf0e10cSrcweir //#####################################################
47cdf0e10cSrcweir #define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))
48cdf0e10cSrcweir 
49cdf0e10cSrcweir static const wchar_t UNC_PREFIX[] = L"\\\\";
50cdf0e10cSrcweir static const wchar_t BACKSLASH = '\\';
51cdf0e10cSrcweir static const wchar_t SLASH = '/';
52cdf0e10cSrcweir 
53cdf0e10cSrcweir //#####################################################
TimeValueToFileTime(const TimeValue * cpTimeVal,FILETIME * pFTime)54cdf0e10cSrcweir extern "C" BOOL TimeValueToFileTime(const TimeValue *cpTimeVal, FILETIME *pFTime)
55cdf0e10cSrcweir {
56cdf0e10cSrcweir 	SYSTEMTIME	BaseSysTime;
57cdf0e10cSrcweir 	FILETIME	BaseFileTime;
58cdf0e10cSrcweir 	FILETIME	FTime;
59cdf0e10cSrcweir 	__int64		localTime;
60cdf0e10cSrcweir 	BOOL		fSuccess = FALSE;
61cdf0e10cSrcweir 
62cdf0e10cSrcweir 	BaseSysTime.wYear         = 1970;
63cdf0e10cSrcweir 	BaseSysTime.wMonth        = 1;
64cdf0e10cSrcweir     BaseSysTime.wDayOfWeek    = 0;
65cdf0e10cSrcweir     BaseSysTime.wDay          = 1;
66cdf0e10cSrcweir     BaseSysTime.wHour         = 0;
67cdf0e10cSrcweir     BaseSysTime.wMinute       = 0;
68cdf0e10cSrcweir     BaseSysTime.wSecond       = 0;
69cdf0e10cSrcweir     BaseSysTime.wMilliseconds = 0;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 	if (cpTimeVal==NULL)
72cdf0e10cSrcweir 		return fSuccess;
73cdf0e10cSrcweir 
74cdf0e10cSrcweir 	if ( SystemTimeToFileTime(&BaseSysTime, &BaseFileTime) )
75cdf0e10cSrcweir 	{
76cdf0e10cSrcweir 		__int64 timeValue;
77cdf0e10cSrcweir 		localTime=cpTimeVal->Seconds*(__int64)10000000+cpTimeVal->Nanosec/100;
78cdf0e10cSrcweir 		*(__int64 *)&FTime=localTime;
79cdf0e10cSrcweir 		fSuccess = 0 <= (timeValue= *((__int64 *)&BaseFileTime) + *((__int64 *) &FTime));
80cdf0e10cSrcweir 		if (fSuccess)
81cdf0e10cSrcweir 			*(__int64 *)pFTime=timeValue;
82cdf0e10cSrcweir 	}
83cdf0e10cSrcweir 	return fSuccess;
84cdf0e10cSrcweir }
85cdf0e10cSrcweir 
86cdf0e10cSrcweir //#####################################################
FileTimeToTimeValue(const FILETIME * cpFTime,TimeValue * pTimeVal)87cdf0e10cSrcweir extern "C" BOOL FileTimeToTimeValue(const FILETIME *cpFTime, TimeValue *pTimeVal)
88cdf0e10cSrcweir {
89cdf0e10cSrcweir 	SYSTEMTIME	BaseSysTime;
90cdf0e10cSrcweir 	FILETIME	BaseFileTime;
91cdf0e10cSrcweir 	BOOL		fSuccess = FALSE;	/* Assume failure */
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 	BaseSysTime.wYear         = 1970;
94cdf0e10cSrcweir 	BaseSysTime.wMonth        = 1;
95cdf0e10cSrcweir     BaseSysTime.wDayOfWeek    = 0;
96cdf0e10cSrcweir     BaseSysTime.wDay          = 1;
97cdf0e10cSrcweir     BaseSysTime.wHour         = 0;
98cdf0e10cSrcweir     BaseSysTime.wMinute       = 0;
99cdf0e10cSrcweir     BaseSysTime.wSecond       = 0;
100cdf0e10cSrcweir     BaseSysTime.wMilliseconds = 0;
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	if ( SystemTimeToFileTime(&BaseSysTime, &BaseFileTime) )
103cdf0e10cSrcweir 	{
104cdf0e10cSrcweir 		__int64		Value;
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 		fSuccess = 0 <= (Value = *((__int64 *)cpFTime) - *((__int64 *)&BaseFileTime));
107cdf0e10cSrcweir 
108cdf0e10cSrcweir 		if ( fSuccess )
109cdf0e10cSrcweir 		{
110cdf0e10cSrcweir 			pTimeVal->Seconds  = (unsigned long) (Value / 10000000L);
111cdf0e10cSrcweir 			pTimeVal->Nanosec  = (unsigned long)((Value % 10000000L) * 100);
112cdf0e10cSrcweir 		}
113cdf0e10cSrcweir 	}
114cdf0e10cSrcweir 	return fSuccess;
115cdf0e10cSrcweir }
116cdf0e10cSrcweir 
117cdf0e10cSrcweir //#####################################################
118cdf0e10cSrcweir namespace /* private */
119cdf0e10cSrcweir {
120cdf0e10cSrcweir     //#####################################################
121cdf0e10cSrcweir 	struct Component
122cdf0e10cSrcweir     {
Component__anon34d11c5d0111::Component123cdf0e10cSrcweir         Component() :
124cdf0e10cSrcweir             begin_(0), end_(0)
125cdf0e10cSrcweir         {}
126cdf0e10cSrcweir 
isPresent__anon34d11c5d0111::Component127cdf0e10cSrcweir         bool isPresent() const
128cdf0e10cSrcweir         { return (static_cast<sal_IntPtr>(end_ - begin_) > 0); }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir         const sal_Unicode* begin_;
131cdf0e10cSrcweir         const sal_Unicode* end_;
132cdf0e10cSrcweir     };
133cdf0e10cSrcweir 
134cdf0e10cSrcweir     //#####################################################
135cdf0e10cSrcweir     struct UNCComponents
136cdf0e10cSrcweir     {
137cdf0e10cSrcweir         Component server_;
138cdf0e10cSrcweir         Component share_;
139cdf0e10cSrcweir         Component resource_;
140cdf0e10cSrcweir     };
141cdf0e10cSrcweir 
142cdf0e10cSrcweir     //#####################################################
is_UNC_path(const sal_Unicode * path)143cdf0e10cSrcweir     inline bool is_UNC_path(const sal_Unicode* path)
144cdf0e10cSrcweir     { return (0 == wcsncmp(UNC_PREFIX, reinterpret_cast<LPCWSTR>(path), ELEMENTS_OF_ARRAY(UNC_PREFIX) - 1)); }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir     //#####################################################
is_UNC_path(const rtl::OUString & path)147cdf0e10cSrcweir     inline bool is_UNC_path(const rtl::OUString& path)
148cdf0e10cSrcweir     { return is_UNC_path(path.getStr()); }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir     //#####################################################
parse_UNC_path(const sal_Unicode * path,UNCComponents * puncc)151cdf0e10cSrcweir     void parse_UNC_path(const sal_Unicode* path, UNCComponents* puncc)
152cdf0e10cSrcweir     {
153cdf0e10cSrcweir         OSL_PRECOND(is_UNC_path(path), "Precondition violated: No UNC path");
154cdf0e10cSrcweir         OSL_PRECOND(rtl_ustr_indexOfChar(path, SLASH) == -1, "Path must not contain slashes");
155cdf0e10cSrcweir 
156cdf0e10cSrcweir         const sal_Unicode* pend = path + rtl_ustr_getLength(path);
157cdf0e10cSrcweir         const sal_Unicode* ppos = path + 2;
158cdf0e10cSrcweir 
159cdf0e10cSrcweir         puncc->server_.begin_ = ppos;
160cdf0e10cSrcweir         while ((ppos < pend) && (*ppos != BACKSLASH))
161cdf0e10cSrcweir             ppos++;
162cdf0e10cSrcweir 
163cdf0e10cSrcweir         puncc->server_.end_ = ppos;
164cdf0e10cSrcweir 
165cdf0e10cSrcweir         if (BACKSLASH == *ppos)
166cdf0e10cSrcweir         {
167cdf0e10cSrcweir             puncc->share_.begin_ = ++ppos;
168cdf0e10cSrcweir             while ((ppos < pend) && (*ppos != BACKSLASH))
169cdf0e10cSrcweir                 ppos++;
170cdf0e10cSrcweir 
171cdf0e10cSrcweir             puncc->share_.end_ = ppos;
172cdf0e10cSrcweir 
173cdf0e10cSrcweir             if (BACKSLASH == *ppos)
174cdf0e10cSrcweir             {
175cdf0e10cSrcweir                 puncc->resource_.begin_ = ++ppos;
176cdf0e10cSrcweir                 while (ppos < pend)
177cdf0e10cSrcweir                     ppos++;
178cdf0e10cSrcweir 
179cdf0e10cSrcweir                 puncc->resource_.end_ = ppos;
180cdf0e10cSrcweir             }
181cdf0e10cSrcweir         }
182cdf0e10cSrcweir 
183cdf0e10cSrcweir         OSL_POSTCOND(puncc->server_.isPresent() && puncc->share_.isPresent(), \
184cdf0e10cSrcweir         "Postcondition violated: Invalid UNC path detected");
185cdf0e10cSrcweir     }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir     //#####################################################
parse_UNC_path(const rtl::OUString & path,UNCComponents * puncc)188cdf0e10cSrcweir     void parse_UNC_path(const rtl::OUString& path, UNCComponents* puncc)
189cdf0e10cSrcweir     { parse_UNC_path(path.getStr(), puncc); }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 
192cdf0e10cSrcweir     //#####################################################
has_path_parent(const sal_Unicode * path)193cdf0e10cSrcweir     bool has_path_parent(const sal_Unicode* path)
194cdf0e10cSrcweir     {
195cdf0e10cSrcweir 		// Has the given path a parent or are we already there,
196cdf0e10cSrcweir 		// e.g. 'c:\' or '\\server\share\'?
197cdf0e10cSrcweir 
198cdf0e10cSrcweir         bool has_parent = false;
199cdf0e10cSrcweir         if (is_UNC_path(path))
200cdf0e10cSrcweir         {
201cdf0e10cSrcweir             UNCComponents unc_comp;
202cdf0e10cSrcweir             parse_UNC_path(path, &unc_comp);
203cdf0e10cSrcweir             has_parent = unc_comp.resource_.isPresent();
204cdf0e10cSrcweir         }
205cdf0e10cSrcweir         else
206cdf0e10cSrcweir         {
207cdf0e10cSrcweir             has_parent = !osl::systemPathIsLogicalDrivePattern(path);
208cdf0e10cSrcweir         }
209cdf0e10cSrcweir         return has_parent;
210cdf0e10cSrcweir     }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir     //#####################################################
has_path_parent(const rtl::OUString & path)213cdf0e10cSrcweir     inline bool has_path_parent(const rtl::OUString& path)
214cdf0e10cSrcweir     { return has_path_parent(path.getStr()); }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir } // end namespace private
217cdf0e10cSrcweir 
218cdf0e10cSrcweir //#####################################################
219cdf0e10cSrcweir // volume handling functions
220cdf0e10cSrcweir //#####################################################
221cdf0e10cSrcweir 
222cdf0e10cSrcweir //#####################################################
osl_unmountVolumeDevice(oslVolumeDeviceHandle Handle)223cdf0e10cSrcweir oslFileError SAL_CALL osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
224cdf0e10cSrcweir {
225cdf0e10cSrcweir 	if ( Handle )
226cdf0e10cSrcweir 		return osl_File_E_None;
227cdf0e10cSrcweir 	else
228cdf0e10cSrcweir 		return osl_File_E_INVAL;
229cdf0e10cSrcweir }
230cdf0e10cSrcweir 
231cdf0e10cSrcweir //#####################################################
osl_automountVolumeDevice(oslVolumeDeviceHandle Handle)232cdf0e10cSrcweir oslFileError SAL_CALL osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
233cdf0e10cSrcweir {
234cdf0e10cSrcweir 	if ( Handle )
235cdf0e10cSrcweir 		return osl_File_E_None;
236cdf0e10cSrcweir 	else
237cdf0e10cSrcweir 		return osl_File_E_INVAL;
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir //#####################################################
osl_acquireVolumeDeviceHandle(oslVolumeDeviceHandle Handle)241cdf0e10cSrcweir oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
242cdf0e10cSrcweir {
243cdf0e10cSrcweir 	if ( Handle )
244cdf0e10cSrcweir 	{
245cdf0e10cSrcweir 		rtl_uString_acquire( (rtl_uString *)Handle );
246cdf0e10cSrcweir 		return osl_File_E_None;
247cdf0e10cSrcweir 	}
248cdf0e10cSrcweir 	else
249cdf0e10cSrcweir 		return osl_File_E_INVAL;
250cdf0e10cSrcweir }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir //#####################################################
osl_releaseVolumeDeviceHandle(oslVolumeDeviceHandle Handle)253cdf0e10cSrcweir oslFileError SAL_CALL osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
254cdf0e10cSrcweir {
255cdf0e10cSrcweir 	if ( Handle )
256cdf0e10cSrcweir 	{
257cdf0e10cSrcweir 		rtl_uString_release( (rtl_uString *)Handle );
258cdf0e10cSrcweir 		return osl_File_E_None;
259cdf0e10cSrcweir 	}
260cdf0e10cSrcweir 	else
261cdf0e10cSrcweir 		return osl_File_E_INVAL;
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir //#####################################################
osl_getVolumeDeviceMountPath(oslVolumeDeviceHandle Handle,rtl_uString ** pstrPath)265cdf0e10cSrcweir oslFileError SAL_CALL osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
266cdf0e10cSrcweir {
267cdf0e10cSrcweir 	if ( Handle && pstrPath )
268cdf0e10cSrcweir 	{
269cdf0e10cSrcweir 		rtl_uString_assign( pstrPath, (rtl_uString *)Handle );
270cdf0e10cSrcweir 		return osl_File_E_None;
271cdf0e10cSrcweir 	}
272cdf0e10cSrcweir 	else
273cdf0e10cSrcweir 		return osl_File_E_INVAL;
274cdf0e10cSrcweir }
275cdf0e10cSrcweir 
276cdf0e10cSrcweir //##################################################################
277cdf0e10cSrcweir // directory handling functions
278cdf0e10cSrcweir //##################################################################
279cdf0e10cSrcweir 
280cdf0e10cSrcweir #define DIRECTORYITEM_DRIVE		0
281cdf0e10cSrcweir #define DIRECTORYITEM_FILE		1
282cdf0e10cSrcweir #define DIRECTORYITEM_SERVER	2
283cdf0e10cSrcweir 
284cdf0e10cSrcweir struct DirectoryItem_Impl
285cdf0e10cSrcweir {
286cdf0e10cSrcweir 	UINT uType;
287cdf0e10cSrcweir 	union {
288cdf0e10cSrcweir 		WIN32_FIND_DATA	FindData;
289cdf0e10cSrcweir 		TCHAR			cDriveString[MAX_PATH];
290cdf0e10cSrcweir 	};
291cdf0e10cSrcweir     rtl_uString*    m_pFullPath;
292cdf0e10cSrcweir 	BOOL			bFullPathNormalized;
293cdf0e10cSrcweir 	int				nRefCount;
294cdf0e10cSrcweir };
295cdf0e10cSrcweir 
296cdf0e10cSrcweir //#####################################################
297cdf0e10cSrcweir 
298cdf0e10cSrcweir #define	DIRECTORYTYPE_LOCALROOT	    0
299cdf0e10cSrcweir #define	DIRECTORYTYPE_NETROOT		1
300cdf0e10cSrcweir #define	DIRECTORYTYPE_NETRESORCE	2
301cdf0e10cSrcweir #define	DIRECTORYTYPE_FILESYSTEM	3
302cdf0e10cSrcweir 
303cdf0e10cSrcweir struct Directory_Impl
304cdf0e10cSrcweir {
305cdf0e10cSrcweir 	UINT uType;
306cdf0e10cSrcweir 	union {
307cdf0e10cSrcweir 		HANDLE	hDirectory;
308cdf0e10cSrcweir 		HANDLE	hEnumDrives;
309cdf0e10cSrcweir 	};
310cdf0e10cSrcweir     rtl_uString*    m_pDirectoryPath;
311cdf0e10cSrcweir };
312cdf0e10cSrcweir 
313cdf0e10cSrcweir //#####################################################
314cdf0e10cSrcweir 
315cdf0e10cSrcweir typedef struct tagDRIVEENUM
316cdf0e10cSrcweir {
317cdf0e10cSrcweir 	LPCTSTR	lpIdent;
318cdf0e10cSrcweir 	TCHAR	cBuffer[/*('Z' - 'A' + 1) * sizeof("A:\\") + 1*/256];
319cdf0e10cSrcweir 	LPCTSTR	lpCurrent;
320cdf0e10cSrcweir } DRIVEENUM, * PDRIVEENUM, FAR * LPDRIVEENUM;
321cdf0e10cSrcweir 
322cdf0e10cSrcweir //#####################################################
323cdf0e10cSrcweir 
OpenLogicalDrivesEnum(void)324cdf0e10cSrcweir static HANDLE WINAPI OpenLogicalDrivesEnum(void)
325cdf0e10cSrcweir {
326cdf0e10cSrcweir 	LPDRIVEENUM	pEnum = (LPDRIVEENUM)HeapAlloc( GetProcessHeap(), 0, sizeof(DRIVEENUM) );
327cdf0e10cSrcweir 	if ( pEnum )
328cdf0e10cSrcweir 	{
329cdf0e10cSrcweir 		DWORD dwNumCopied = GetLogicalDriveStrings( (sizeof(pEnum->cBuffer) - 1) / sizeof(TCHAR), pEnum->cBuffer );
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 		if ( dwNumCopied && dwNumCopied < sizeof(pEnum->cBuffer) / sizeof(TCHAR) )
332cdf0e10cSrcweir 		{
333cdf0e10cSrcweir 			pEnum->lpCurrent = pEnum->cBuffer;
334cdf0e10cSrcweir 			pEnum->lpIdent = L"tagDRIVEENUM";
335cdf0e10cSrcweir 		}
336cdf0e10cSrcweir 		else
337cdf0e10cSrcweir 		{
338cdf0e10cSrcweir 			HeapFree( GetProcessHeap(), 0, pEnum );
339cdf0e10cSrcweir 			pEnum = NULL;
340cdf0e10cSrcweir 		}
341cdf0e10cSrcweir 	}
342cdf0e10cSrcweir 	return pEnum ? (HANDLE)pEnum : INVALID_HANDLE_VALUE;
343cdf0e10cSrcweir }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir //#####################################################
EnumLogicalDrives(HANDLE hEnum,LPTSTR lpBuffer)346cdf0e10cSrcweir static BOOL WINAPI EnumLogicalDrives(HANDLE hEnum, LPTSTR lpBuffer)
347cdf0e10cSrcweir {
348cdf0e10cSrcweir 	BOOL		fSuccess = FALSE;
349cdf0e10cSrcweir 	LPDRIVEENUM	pEnum = (LPDRIVEENUM)hEnum;
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 	if ( pEnum )
352cdf0e10cSrcweir 	{
353cdf0e10cSrcweir 		int	nLen = _tcslen( pEnum->lpCurrent );
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 		if ( nLen )
356cdf0e10cSrcweir 		{
357cdf0e10cSrcweir 			CopyMemory( lpBuffer, pEnum->lpCurrent, (nLen + 1) * sizeof(TCHAR) );
358cdf0e10cSrcweir 			pEnum->lpCurrent += nLen + 1;
359cdf0e10cSrcweir 			fSuccess = TRUE;
360cdf0e10cSrcweir 		}
361cdf0e10cSrcweir 		else
362cdf0e10cSrcweir 			SetLastError( ERROR_NO_MORE_FILES );
363cdf0e10cSrcweir 	}
364cdf0e10cSrcweir 	else
365cdf0e10cSrcweir 		SetLastError( ERROR_INVALID_HANDLE );
366cdf0e10cSrcweir 
367cdf0e10cSrcweir 	return fSuccess;
368cdf0e10cSrcweir }
369cdf0e10cSrcweir 
370cdf0e10cSrcweir //#####################################################
CloseLogicalDrivesEnum(HANDLE hEnum)371cdf0e10cSrcweir static BOOL WINAPI CloseLogicalDrivesEnum(HANDLE hEnum)
372cdf0e10cSrcweir {
373cdf0e10cSrcweir 	BOOL		fSuccess = FALSE;
374cdf0e10cSrcweir 	LPDRIVEENUM	pEnum = (LPDRIVEENUM)hEnum;
375cdf0e10cSrcweir 
376cdf0e10cSrcweir 	if ( pEnum )
377cdf0e10cSrcweir 	{
378cdf0e10cSrcweir 		HeapFree( GetProcessHeap(), 0, pEnum );
379cdf0e10cSrcweir 		fSuccess = TRUE;
380cdf0e10cSrcweir 	}
381cdf0e10cSrcweir 	else
382cdf0e10cSrcweir 		SetLastError( ERROR_INVALID_HANDLE );
383cdf0e10cSrcweir 
384cdf0e10cSrcweir 	return fSuccess;
385cdf0e10cSrcweir }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir //#####################################################
388cdf0e10cSrcweir typedef struct tagDIRECTORY
389cdf0e10cSrcweir {
390cdf0e10cSrcweir 	HANDLE          hFind;
391cdf0e10cSrcweir 	WIN32_FIND_DATA aFirstData;
392cdf0e10cSrcweir } DIRECTORY, *PDIRECTORY, FAR *LPDIRECTORY;
393cdf0e10cSrcweir 
394cdf0e10cSrcweir //#####################################################
OpenDirectory(rtl_uString * pPath)395cdf0e10cSrcweir static HANDLE WINAPI OpenDirectory( rtl_uString* pPath)
396cdf0e10cSrcweir {
397cdf0e10cSrcweir 	LPDIRECTORY	pDirectory = NULL;
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 	if ( pPath )
400cdf0e10cSrcweir 	{
401cdf0e10cSrcweir         sal_uInt32 nLen = rtl_uString_getLength( pPath );
402cdf0e10cSrcweir         if ( nLen )
403cdf0e10cSrcweir         {
404cdf0e10cSrcweir             TCHAR* pSuffix = 0;
405cdf0e10cSrcweir             sal_uInt32 nSuffLen = 0;
406cdf0e10cSrcweir 
407cdf0e10cSrcweir             if ( pPath->buffer[nLen - 1] != L'\\' )
408cdf0e10cSrcweir             {
409cdf0e10cSrcweir                 pSuffix = L"\\*.*";
410cdf0e10cSrcweir                 nSuffLen = 4;
411cdf0e10cSrcweir             }
412cdf0e10cSrcweir             else
413cdf0e10cSrcweir             {
414cdf0e10cSrcweir                 pSuffix = L"*.*";
415cdf0e10cSrcweir                 nSuffLen = 3;
416cdf0e10cSrcweir             }
417cdf0e10cSrcweir 
418cdf0e10cSrcweir             TCHAR* szFileMask = reinterpret_cast< TCHAR* >( rtl_allocateMemory( sizeof( TCHAR ) * ( nLen + nSuffLen + 1 ) ) );
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 		    _tcscpy( szFileMask, reinterpret_cast<LPCTSTR>( rtl_uString_getStr( pPath ) ) );
421cdf0e10cSrcweir             _tcscat( szFileMask, pSuffix );
422cdf0e10cSrcweir 
423cdf0e10cSrcweir             pDirectory = (LPDIRECTORY)HeapAlloc(GetProcessHeap(), 0, sizeof(DIRECTORY));
424cdf0e10cSrcweir             pDirectory->hFind = FindFirstFile(szFileMask, &pDirectory->aFirstData);
425cdf0e10cSrcweir 
426cdf0e10cSrcweir             if (!IsValidHandle(pDirectory->hFind))
427cdf0e10cSrcweir             {
428cdf0e10cSrcweir                 if ( GetLastError() != ERROR_NO_MORE_FILES )
429cdf0e10cSrcweir                 {
430cdf0e10cSrcweir                     HeapFree(GetProcessHeap(), 0, pDirectory);
431cdf0e10cSrcweir                     pDirectory = NULL;
432cdf0e10cSrcweir                 }
433cdf0e10cSrcweir             }
434*1102d251SJian Fang Zhang 
435*1102d251SJian Fang Zhang             rtl_freeMemory(szFileMask);  // #119939#, memory leak
436cdf0e10cSrcweir         }
437cdf0e10cSrcweir 	}
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 	return (HANDLE)pDirectory;
440cdf0e10cSrcweir }
441cdf0e10cSrcweir 
442cdf0e10cSrcweir //#####################################################
EnumDirectory(HANDLE hDirectory,LPWIN32_FIND_DATA pFindData)443cdf0e10cSrcweir BOOL WINAPI EnumDirectory(HANDLE hDirectory, LPWIN32_FIND_DATA pFindData)
444cdf0e10cSrcweir {
445cdf0e10cSrcweir 	BOOL		fSuccess = FALSE;
446cdf0e10cSrcweir 	LPDIRECTORY	pDirectory = (LPDIRECTORY)hDirectory;
447cdf0e10cSrcweir 
448cdf0e10cSrcweir 	if ( pDirectory )
449cdf0e10cSrcweir 	{
450cdf0e10cSrcweir 		BOOL	fValid;
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 		do
453cdf0e10cSrcweir 		{
454cdf0e10cSrcweir 			if ( pDirectory->aFirstData.cFileName[0] )
455cdf0e10cSrcweir 			{
456cdf0e10cSrcweir 				*pFindData = pDirectory->aFirstData;
457cdf0e10cSrcweir 				fSuccess = TRUE;
458cdf0e10cSrcweir 				pDirectory->aFirstData.cFileName[0] = 0;
459cdf0e10cSrcweir 			}
460cdf0e10cSrcweir 			else if ( IsValidHandle( pDirectory->hFind ) )
461cdf0e10cSrcweir 				fSuccess = FindNextFile( pDirectory->hFind, pFindData );
462cdf0e10cSrcweir 			else
463cdf0e10cSrcweir 			{
464cdf0e10cSrcweir 				fSuccess = FALSE;
465cdf0e10cSrcweir 				SetLastError( ERROR_NO_MORE_FILES );
466cdf0e10cSrcweir 			}
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 			fValid = fSuccess && _tcscmp( TEXT("."), pFindData->cFileName ) != 0 && _tcscmp( TEXT(".."), pFindData->cFileName ) != 0;
469cdf0e10cSrcweir 
470cdf0e10cSrcweir 		} while( fSuccess && !fValid );
471cdf0e10cSrcweir 	}
472cdf0e10cSrcweir 	else
473cdf0e10cSrcweir 		SetLastError( ERROR_INVALID_HANDLE );
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 	return fSuccess;
476cdf0e10cSrcweir }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir //#####################################################
CloseDirectory(HANDLE hDirectory)479cdf0e10cSrcweir static BOOL WINAPI CloseDirectory(HANDLE hDirectory)
480cdf0e10cSrcweir {
481cdf0e10cSrcweir 	BOOL		fSuccess = FALSE;
482cdf0e10cSrcweir 	LPDIRECTORY	pDirectory = (LPDIRECTORY)hDirectory;
483cdf0e10cSrcweir 
484cdf0e10cSrcweir 	if (pDirectory)
485cdf0e10cSrcweir 	{
486cdf0e10cSrcweir 		if (IsValidHandle(pDirectory->hFind))
487cdf0e10cSrcweir 			fSuccess = FindClose(pDirectory->hFind);
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 		fSuccess = HeapFree(GetProcessHeap(), 0, pDirectory) && fSuccess;
490cdf0e10cSrcweir 	}
491cdf0e10cSrcweir 	else
492cdf0e10cSrcweir 		SetLastError(ERROR_INVALID_HANDLE);
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 	return fSuccess;
495cdf0e10cSrcweir }
496cdf0e10cSrcweir 
497cdf0e10cSrcweir //#####################################################
osl_openLocalRoot(rtl_uString * strDirectoryPath,oslDirectory * pDirectory)498cdf0e10cSrcweir static oslFileError osl_openLocalRoot(
499cdf0e10cSrcweir     rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
500cdf0e10cSrcweir {
501cdf0e10cSrcweir     rtl_uString		*strSysPath = NULL;
502cdf0e10cSrcweir     oslFileError	error;
503cdf0e10cSrcweir 
504cdf0e10cSrcweir     if ( !pDirectory )
505cdf0e10cSrcweir         return osl_File_E_INVAL;
506cdf0e10cSrcweir 
507cdf0e10cSrcweir     *pDirectory = NULL;
508cdf0e10cSrcweir 
509cdf0e10cSrcweir     error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysPath, sal_False );
510cdf0e10cSrcweir     if ( osl_File_E_None == error )
511cdf0e10cSrcweir     {
512cdf0e10cSrcweir         Directory_Impl	*pDirImpl;
513cdf0e10cSrcweir 
514cdf0e10cSrcweir         pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory( sizeof(Directory_Impl)));
515cdf0e10cSrcweir         ZeroMemory( pDirImpl, sizeof(Directory_Impl) );
516cdf0e10cSrcweir         rtl_uString_newFromString( &pDirImpl->m_pDirectoryPath, strSysPath );
517cdf0e10cSrcweir 
518cdf0e10cSrcweir         /* Append backslash if neccessary */
519cdf0e10cSrcweir 
520cdf0e10cSrcweir         /* @@@ToDo
521cdf0e10cSrcweir            use function ensure backslash
522cdf0e10cSrcweir         */
523cdf0e10cSrcweir         sal_uInt32 nLen = rtl_uString_getLength( pDirImpl->m_pDirectoryPath );
524cdf0e10cSrcweir         if ( nLen && pDirImpl->m_pDirectoryPath->buffer[nLen - 1] != L'\\' )
525cdf0e10cSrcweir         {
526cdf0e10cSrcweir             rtl_uString* pCurDir = 0;
527cdf0e10cSrcweir             rtl_uString* pBackSlash = 0;
528cdf0e10cSrcweir 
529cdf0e10cSrcweir             rtl_uString_assign( &pCurDir, pDirImpl->m_pDirectoryPath );
530cdf0e10cSrcweir             rtl_uString_newFromAscii( &pBackSlash, "\\" );
531cdf0e10cSrcweir             rtl_uString_newConcat( &pDirImpl->m_pDirectoryPath, pCurDir, pBackSlash );
532cdf0e10cSrcweir             rtl_uString_release( pBackSlash );
533cdf0e10cSrcweir             rtl_uString_release( pCurDir );
534cdf0e10cSrcweir         }
535cdf0e10cSrcweir 
536cdf0e10cSrcweir         pDirImpl->uType = DIRECTORYTYPE_LOCALROOT;
537cdf0e10cSrcweir         pDirImpl->hEnumDrives = OpenLogicalDrivesEnum();
538cdf0e10cSrcweir 
539cdf0e10cSrcweir         /* @@@ToDo
540cdf0e10cSrcweir            Use IsValidHandle(...)
541cdf0e10cSrcweir         */
542cdf0e10cSrcweir         if ( pDirImpl->hEnumDrives != INVALID_HANDLE_VALUE )
543cdf0e10cSrcweir         {
544cdf0e10cSrcweir             *pDirectory = (oslDirectory)pDirImpl;
545cdf0e10cSrcweir             error = osl_File_E_None;
546cdf0e10cSrcweir         }
547cdf0e10cSrcweir         else
548cdf0e10cSrcweir         {
549cdf0e10cSrcweir             if ( pDirImpl )
550cdf0e10cSrcweir             {
551cdf0e10cSrcweir                 if ( pDirImpl->m_pDirectoryPath )
552cdf0e10cSrcweir                 {
553cdf0e10cSrcweir                     rtl_uString_release( pDirImpl->m_pDirectoryPath );
554cdf0e10cSrcweir                     pDirImpl->m_pDirectoryPath = 0;
555cdf0e10cSrcweir                 }
556cdf0e10cSrcweir 
557cdf0e10cSrcweir                 rtl_freeMemory(pDirImpl);
558cdf0e10cSrcweir                 pDirImpl = 0;
559cdf0e10cSrcweir             }
560cdf0e10cSrcweir 
561cdf0e10cSrcweir             error = oslTranslateFileError( GetLastError() );
562cdf0e10cSrcweir         }
563cdf0e10cSrcweir 
564cdf0e10cSrcweir         rtl_uString_release( strSysPath );
565cdf0e10cSrcweir     }
566cdf0e10cSrcweir     return error;
567cdf0e10cSrcweir }
568cdf0e10cSrcweir 
569cdf0e10cSrcweir //#####################################################
osl_openFileDirectory(rtl_uString * strDirectoryPath,oslDirectory * pDirectory)570cdf0e10cSrcweir static oslFileError SAL_CALL osl_openFileDirectory(
571cdf0e10cSrcweir 	rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
572cdf0e10cSrcweir {
573cdf0e10cSrcweir 	oslFileError error = osl_File_E_None;
574cdf0e10cSrcweir 
575cdf0e10cSrcweir 	if ( !pDirectory )
576cdf0e10cSrcweir 		return osl_File_E_INVAL;
577cdf0e10cSrcweir 	*pDirectory = NULL;
578cdf0e10cSrcweir 
579cdf0e10cSrcweir 	Directory_Impl *pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl)));
580cdf0e10cSrcweir     ZeroMemory( pDirImpl, sizeof(Directory_Impl) );
581cdf0e10cSrcweir     rtl_uString_newFromString( &pDirImpl->m_pDirectoryPath, strDirectoryPath );
582cdf0e10cSrcweir 
583cdf0e10cSrcweir 	/* Append backslash if neccessary */
584cdf0e10cSrcweir 
585cdf0e10cSrcweir 	/* @@@ToDo
586cdf0e10cSrcweir 	   use function ensure backslash
587cdf0e10cSrcweir 	*/
588cdf0e10cSrcweir     sal_uInt32 nLen = rtl_uString_getLength( pDirImpl->m_pDirectoryPath );
589cdf0e10cSrcweir     if ( nLen && pDirImpl->m_pDirectoryPath->buffer[nLen - 1] != L'\\' )
590cdf0e10cSrcweir     {
591cdf0e10cSrcweir         rtl_uString* pCurDir = 0;
592cdf0e10cSrcweir         rtl_uString* pBackSlash = 0;
593cdf0e10cSrcweir 
594cdf0e10cSrcweir         rtl_uString_assign( &pCurDir, pDirImpl->m_pDirectoryPath );
595cdf0e10cSrcweir         rtl_uString_newFromAscii( &pBackSlash, "\\" );
596cdf0e10cSrcweir         rtl_uString_newConcat( &pDirImpl->m_pDirectoryPath, pCurDir, pBackSlash );
597cdf0e10cSrcweir         rtl_uString_release( pBackSlash );
598cdf0e10cSrcweir         rtl_uString_release( pCurDir );
599cdf0e10cSrcweir     }
600cdf0e10cSrcweir 
601cdf0e10cSrcweir 
602cdf0e10cSrcweir 	pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM;
603cdf0e10cSrcweir 	pDirImpl->hDirectory = OpenDirectory( pDirImpl->m_pDirectoryPath );
604cdf0e10cSrcweir 
605cdf0e10cSrcweir 	if ( !pDirImpl->hDirectory )
606cdf0e10cSrcweir 	{
607cdf0e10cSrcweir 		error = oslTranslateFileError( GetLastError() );
608cdf0e10cSrcweir 
609cdf0e10cSrcweir         if ( pDirImpl->m_pDirectoryPath )
610cdf0e10cSrcweir         {
611cdf0e10cSrcweir             rtl_uString_release( pDirImpl->m_pDirectoryPath );
612cdf0e10cSrcweir             pDirImpl->m_pDirectoryPath = 0;
613cdf0e10cSrcweir         }
614cdf0e10cSrcweir 
615cdf0e10cSrcweir 		rtl_freeMemory(pDirImpl), pDirImpl = 0;
616cdf0e10cSrcweir 	}
617cdf0e10cSrcweir 
618cdf0e10cSrcweir 	*pDirectory = (oslDirectory)(pDirImpl);
619cdf0e10cSrcweir 	return error;
620cdf0e10cSrcweir }
621cdf0e10cSrcweir 
622cdf0e10cSrcweir //#####################################################
osl_openNetworkServer(rtl_uString * strSysDirPath,oslDirectory * pDirectory)623cdf0e10cSrcweir static oslFileError SAL_CALL osl_openNetworkServer(
624cdf0e10cSrcweir 	rtl_uString *strSysDirPath, oslDirectory *pDirectory)
625cdf0e10cSrcweir {
626cdf0e10cSrcweir 	NETRESOURCEW	aNetResource;
627cdf0e10cSrcweir 	HANDLE			hEnum;
628cdf0e10cSrcweir 	DWORD			dwError;
629cdf0e10cSrcweir 
630cdf0e10cSrcweir 	ZeroMemory( &aNetResource, sizeof(aNetResource) );
631cdf0e10cSrcweir 
632cdf0e10cSrcweir 	aNetResource.lpRemoteName = reinterpret_cast<LPWSTR>(strSysDirPath->buffer);
633cdf0e10cSrcweir 
634cdf0e10cSrcweir 	dwError = WNetOpenEnumW(
635cdf0e10cSrcweir 		RESOURCE_GLOBALNET,
636cdf0e10cSrcweir 		RESOURCETYPE_DISK,
637cdf0e10cSrcweir 		RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER,
638cdf0e10cSrcweir 		&aNetResource,
639cdf0e10cSrcweir 		&hEnum );
640cdf0e10cSrcweir 
641cdf0e10cSrcweir 	if ( ERROR_SUCCESS == dwError )
642cdf0e10cSrcweir 	{
643cdf0e10cSrcweir 		Directory_Impl	*pDirImpl;
644cdf0e10cSrcweir 
645cdf0e10cSrcweir 		pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl)));
646cdf0e10cSrcweir         ZeroMemory( pDirImpl, sizeof(Directory_Impl) );
647cdf0e10cSrcweir 		pDirImpl->uType = DIRECTORYTYPE_NETROOT;
648cdf0e10cSrcweir 		pDirImpl->hDirectory = hEnum;
649cdf0e10cSrcweir 		*pDirectory = (oslDirectory)pDirImpl;
650cdf0e10cSrcweir 	}
651cdf0e10cSrcweir 	return oslTranslateFileError( dwError );
652cdf0e10cSrcweir }
653cdf0e10cSrcweir 
654cdf0e10cSrcweir //#############################################
create_dir_with_callback(rtl_uString * dir_path,oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,void * pData)655cdf0e10cSrcweir static DWORD create_dir_with_callback(
656cdf0e10cSrcweir     rtl_uString * dir_path,
657cdf0e10cSrcweir     oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
658cdf0e10cSrcweir     void* pData)
659cdf0e10cSrcweir {
660cdf0e10cSrcweir 	// Create the specified directory and call the
661cdf0e10cSrcweir 	// user specified callback function. On success
662cdf0e10cSrcweir 	// the function returns ERROR_SUCCESS else a Win32 error code.
663cdf0e10cSrcweir 
664cdf0e10cSrcweir     BOOL bCreated = FALSE;
665cdf0e10cSrcweir 
666cdf0e10cSrcweir     bCreated = CreateDirectoryW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( dir_path )), NULL );
667cdf0e10cSrcweir 
668cdf0e10cSrcweir     if ( bCreated )
669cdf0e10cSrcweir     {
670cdf0e10cSrcweir         if (aDirectoryCreationCallbackFunc)
671cdf0e10cSrcweir         {
672cdf0e10cSrcweir             rtl::OUString url;
673cdf0e10cSrcweir             _osl_getFileURLFromSystemPath(dir_path, &(url.pData));
674cdf0e10cSrcweir             aDirectoryCreationCallbackFunc(pData, url.pData);
675cdf0e10cSrcweir         }
676cdf0e10cSrcweir         return ERROR_SUCCESS;
677cdf0e10cSrcweir     }
678cdf0e10cSrcweir     return GetLastError();
679cdf0e10cSrcweir }
680cdf0e10cSrcweir 
681cdf0e10cSrcweir //#############################################
path_make_parent(sal_Unicode * path)682cdf0e10cSrcweir static int path_make_parent(sal_Unicode* path)
683cdf0e10cSrcweir {
684cdf0e10cSrcweir     /*  Cut off the last part of the given path to
685cdf0e10cSrcweir     get the parent only, e.g. 'c:\dir\subdir' ->
686cdf0e10cSrcweir     'c:\dir' or '\\share\sub\dir' -> '\\share\sub'
687cdf0e10cSrcweir     @return The position where the path has been cut
688cdf0e10cSrcweir     off (this is the posistion of the last backslash).
689cdf0e10cSrcweir     If there are no more parents 0 will be returned,
690cdf0e10cSrcweir     e.g. 'c:\' or '\\Share' have no more parents */
691cdf0e10cSrcweir 
692cdf0e10cSrcweir 	OSL_PRECOND(rtl_ustr_indexOfChar(path, SLASH) == -1, "Path must not contain slashes");
693cdf0e10cSrcweir 	OSL_PRECOND(has_path_parent(path), "Path must have a parent");
694cdf0e10cSrcweir 
695cdf0e10cSrcweir 	sal_Unicode* pos_last_backslash = path + rtl_ustr_lastIndexOfChar(path, BACKSLASH);
696cdf0e10cSrcweir 	*pos_last_backslash = 0;
697cdf0e10cSrcweir 	return (pos_last_backslash - path);
698cdf0e10cSrcweir }
699cdf0e10cSrcweir 
700cdf0e10cSrcweir //#############################################
create_dir_recursively_(rtl_uString * dir_path,oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,void * pData)701cdf0e10cSrcweir static DWORD create_dir_recursively_(
702cdf0e10cSrcweir     rtl_uString * dir_path,
703cdf0e10cSrcweir     oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
704cdf0e10cSrcweir     void* pData)
705cdf0e10cSrcweir {
706cdf0e10cSrcweir     OSL_PRECOND(
707cdf0e10cSrcweir 		rtl_ustr_lastIndexOfChar_WithLength(dir_path->buffer, dir_path->length, BACKSLASH) != dir_path->length,
708cdf0e10cSrcweir 		"Path must not end with a backslash");
709cdf0e10cSrcweir 
710cdf0e10cSrcweir     DWORD w32_error = create_dir_with_callback(
711cdf0e10cSrcweir         dir_path, aDirectoryCreationCallbackFunc, pData);
712cdf0e10cSrcweir     if (w32_error == ERROR_SUCCESS)
713cdf0e10cSrcweir         return ERROR_SUCCESS;
714cdf0e10cSrcweir 
715cdf0e10cSrcweir     if ((w32_error != ERROR_PATH_NOT_FOUND) || !has_path_parent(dir_path->buffer))
716cdf0e10cSrcweir         return w32_error;
717cdf0e10cSrcweir 
718cdf0e10cSrcweir     int pos = path_make_parent(dir_path->buffer); // dir_path->buffer[pos] = 0, restore below
719cdf0e10cSrcweir 
720cdf0e10cSrcweir     w32_error = create_dir_recursively_(
721cdf0e10cSrcweir         dir_path, aDirectoryCreationCallbackFunc, pData);
722cdf0e10cSrcweir 
723cdf0e10cSrcweir     dir_path->buffer[pos] = BACKSLASH; // restore
724cdf0e10cSrcweir 
725cdf0e10cSrcweir     if (ERROR_SUCCESS != w32_error)
726cdf0e10cSrcweir         return w32_error;
727cdf0e10cSrcweir 
728cdf0e10cSrcweir     return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
729cdf0e10cSrcweir }
730cdf0e10cSrcweir 
731cdf0e10cSrcweir //#############################################
osl_createDirectoryPath(rtl_uString * aDirectoryUrl,oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,void * pData)732cdf0e10cSrcweir oslFileError SAL_CALL osl_createDirectoryPath(
733cdf0e10cSrcweir     rtl_uString* aDirectoryUrl,
734cdf0e10cSrcweir     oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
735cdf0e10cSrcweir     void* pData)
736cdf0e10cSrcweir {
737cdf0e10cSrcweir     if (aDirectoryUrl == NULL)
738cdf0e10cSrcweir         return osl_File_E_INVAL;
739cdf0e10cSrcweir 
740cdf0e10cSrcweir     rtl::OUString sys_path;
741cdf0e10cSrcweir     oslFileError osl_error =
742cdf0e10cSrcweir         _osl_getSystemPathFromFileURL(aDirectoryUrl, &sys_path.pData, sal_False);
743cdf0e10cSrcweir 
744cdf0e10cSrcweir     if (osl_error != osl_File_E_None)
745cdf0e10cSrcweir         return osl_error;
746cdf0e10cSrcweir 
747cdf0e10cSrcweir     osl::systemPathRemoveSeparator(sys_path);
748cdf0e10cSrcweir 
749cdf0e10cSrcweir     // const_cast because sys_path is a local copy
750cdf0e10cSrcweir     // which we want to modify inplace instead of
751cdf0e10cSrcweir     // coyp it into another buffer on the heap again
752cdf0e10cSrcweir     return oslTranslateFileError(create_dir_recursively_(
753cdf0e10cSrcweir         sys_path.pData, aDirectoryCreationCallbackFunc, pData));
754cdf0e10cSrcweir }
755cdf0e10cSrcweir 
756cdf0e10cSrcweir //#####################################################
osl_createDirectory(rtl_uString * strPath)757cdf0e10cSrcweir oslFileError SAL_CALL osl_createDirectory(rtl_uString* strPath)
758cdf0e10cSrcweir {
759cdf0e10cSrcweir 	rtl_uString	*strSysPath = NULL;
760cdf0e10cSrcweir 	oslFileError	error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
761cdf0e10cSrcweir 
762cdf0e10cSrcweir 	if ( osl_File_E_None == error )
763cdf0e10cSrcweir 	{
764cdf0e10cSrcweir         BOOL bCreated = FALSE;
765cdf0e10cSrcweir 
766cdf0e10cSrcweir         bCreated = CreateDirectoryW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )), NULL );
767cdf0e10cSrcweir 
768cdf0e10cSrcweir         if ( !bCreated )
769cdf0e10cSrcweir 		{
770cdf0e10cSrcweir             /*@@@ToDo
771cdf0e10cSrcweir               The following case is a hack because the ucb or the webtop had some
772cdf0e10cSrcweir               problems with the error code that CreateDirectory returns in
773cdf0e10cSrcweir               case the path is only a logical drive, should be removed!
774cdf0e10cSrcweir             */
775cdf0e10cSrcweir 
776cdf0e10cSrcweir 			const sal_Unicode	*pBuffer = rtl_uString_getStr( strSysPath );
777cdf0e10cSrcweir 			sal_Int32			nLen = rtl_uString_getLength( strSysPath );
778cdf0e10cSrcweir 
779cdf0e10cSrcweir 			if (
780cdf0e10cSrcweir 				( ( pBuffer[0] >= 'A' && pBuffer[0] <= 'Z' ) ||
781cdf0e10cSrcweir 				  ( pBuffer[0] >= 'a' && pBuffer[0] <= 'z' ) ) &&
782cdf0e10cSrcweir 				pBuffer[1] == ':' && ( nLen ==2 || ( nLen == 3 && pBuffer[2] == '\\' ) )
783cdf0e10cSrcweir 				)
784cdf0e10cSrcweir 				SetLastError( ERROR_ALREADY_EXISTS );
785cdf0e10cSrcweir 
786cdf0e10cSrcweir 			error = oslTranslateFileError( GetLastError() );
787cdf0e10cSrcweir 		}
788cdf0e10cSrcweir 
789cdf0e10cSrcweir 		rtl_uString_release( strSysPath );
790cdf0e10cSrcweir 	}
791cdf0e10cSrcweir 	return error;
792cdf0e10cSrcweir }
793cdf0e10cSrcweir 
794cdf0e10cSrcweir //#####################################################
osl_removeDirectory(rtl_uString * strPath)795cdf0e10cSrcweir oslFileError SAL_CALL osl_removeDirectory(rtl_uString* strPath)
796cdf0e10cSrcweir {
797cdf0e10cSrcweir 	rtl_uString	*strSysPath = NULL;
798cdf0e10cSrcweir 	oslFileError	error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );
799cdf0e10cSrcweir 
800cdf0e10cSrcweir 	if ( osl_File_E_None == error )
801cdf0e10cSrcweir 	{
802cdf0e10cSrcweir 		if ( RemoveDirectory( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )) ) )
803cdf0e10cSrcweir 			error = osl_File_E_None;
804cdf0e10cSrcweir 		else
805cdf0e10cSrcweir 			error = oslTranslateFileError( GetLastError() );
806cdf0e10cSrcweir 
807cdf0e10cSrcweir 		rtl_uString_release( strSysPath );
808cdf0e10cSrcweir 	}
809cdf0e10cSrcweir 	return error;
810cdf0e10cSrcweir }
811cdf0e10cSrcweir 
812cdf0e10cSrcweir //#####################################################
osl_openDirectory(rtl_uString * strDirectoryPath,oslDirectory * pDirectory)813cdf0e10cSrcweir oslFileError SAL_CALL osl_openDirectory(rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
814cdf0e10cSrcweir {
815cdf0e10cSrcweir 	oslFileError	error;
816cdf0e10cSrcweir 
817cdf0e10cSrcweir 	if ( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase( strDirectoryPath->buffer, "file:///" ) )
818cdf0e10cSrcweir 		error = osl_openLocalRoot( strDirectoryPath, pDirectory );
819cdf0e10cSrcweir 	else
820cdf0e10cSrcweir 	{
821cdf0e10cSrcweir 		rtl_uString	*strSysDirectoryPath = NULL;
822cdf0e10cSrcweir 		DWORD		dwPathType;
823cdf0e10cSrcweir 
824cdf0e10cSrcweir 		error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysDirectoryPath, sal_False );
825cdf0e10cSrcweir 
826cdf0e10cSrcweir 		if ( osl_File_E_None != error )
827cdf0e10cSrcweir 				return error;
828cdf0e10cSrcweir 
829cdf0e10cSrcweir 		dwPathType = IsValidFilePath( strSysDirectoryPath, NULL, VALIDATEPATH_NORMAL, NULL );
830cdf0e10cSrcweir 
831cdf0e10cSrcweir 		if ( dwPathType & PATHTYPE_IS_SERVER )
832cdf0e10cSrcweir 		{
833cdf0e10cSrcweir 			error = osl_openNetworkServer( strSysDirectoryPath, pDirectory );
834cdf0e10cSrcweir 		}
835cdf0e10cSrcweir 		else
836cdf0e10cSrcweir 			error = osl_openFileDirectory( strSysDirectoryPath, pDirectory );
837cdf0e10cSrcweir 
838cdf0e10cSrcweir 		rtl_uString_release( strSysDirectoryPath );
839cdf0e10cSrcweir 	}
840cdf0e10cSrcweir 	return error;
841cdf0e10cSrcweir }
842cdf0e10cSrcweir 
843cdf0e10cSrcweir //#####################################################
osl_getNextNetResource(oslDirectory Directory,oslDirectoryItem * pItem,sal_uInt32 uHint)844cdf0e10cSrcweir static oslFileError SAL_CALL osl_getNextNetResource(
845cdf0e10cSrcweir 	oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
846cdf0e10cSrcweir {
847cdf0e10cSrcweir 	Directory_Impl		*pDirImpl = (Directory_Impl *)Directory;
848cdf0e10cSrcweir 	DirectoryItem_Impl	*pItemImpl = NULL;
849cdf0e10cSrcweir 	BYTE				buffer[16384];
850cdf0e10cSrcweir 	LPNETRESOURCEW		lpNetResource = (LPNETRESOURCEW)buffer;
851cdf0e10cSrcweir 	DWORD				dwError, dwCount, dwBufSize;
852cdf0e10cSrcweir 
853cdf0e10cSrcweir 	uHint = uHint; /* to get no warning */
854cdf0e10cSrcweir 
855cdf0e10cSrcweir 	if ( !pItem )
856cdf0e10cSrcweir 		return osl_File_E_INVAL;
857cdf0e10cSrcweir 	*pItem = NULL;
858cdf0e10cSrcweir 
859cdf0e10cSrcweir 	if ( !pDirImpl )
860cdf0e10cSrcweir 		return osl_File_E_INVAL;
861cdf0e10cSrcweir 
862cdf0e10cSrcweir 	dwCount = 1;
863cdf0e10cSrcweir 	dwBufSize = sizeof(buffer);
864cdf0e10cSrcweir 	dwError = WNetEnumResource( pDirImpl->hDirectory, &dwCount, lpNetResource, &dwBufSize );
865cdf0e10cSrcweir 
866cdf0e10cSrcweir 	switch ( dwError )
867cdf0e10cSrcweir 	{
868cdf0e10cSrcweir 	    case NO_ERROR:
869cdf0e10cSrcweir 	    case ERROR_MORE_DATA:
870cdf0e10cSrcweir 		{
871cdf0e10cSrcweir 			pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
872cdf0e10cSrcweir 			if ( !pItemImpl )
873cdf0e10cSrcweir 				return osl_File_E_NOMEM;
874cdf0e10cSrcweir 
875cdf0e10cSrcweir 			ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
876cdf0e10cSrcweir 			pItemImpl->uType = DIRECTORYITEM_DRIVE;
877cdf0e10cSrcweir 			osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
878cdf0e10cSrcweir 
879cdf0e10cSrcweir 			wcscpy( pItemImpl->cDriveString, lpNetResource->lpRemoteName );
880cdf0e10cSrcweir 
881cdf0e10cSrcweir 			*pItem = pItemImpl;
882cdf0e10cSrcweir 		}
883cdf0e10cSrcweir 		return osl_File_E_None;
884cdf0e10cSrcweir 	    case ERROR_NO_MORE_ITEMS:
885cdf0e10cSrcweir 		    return osl_File_E_NOENT;
886cdf0e10cSrcweir 	    default:
887cdf0e10cSrcweir 		    return oslTranslateFileError( dwError );
888cdf0e10cSrcweir 	}
889cdf0e10cSrcweir }
890cdf0e10cSrcweir 
891cdf0e10cSrcweir //#####################################################
osl_getNextDrive(oslDirectory Directory,oslDirectoryItem * pItem,sal_uInt32 uHint)892cdf0e10cSrcweir static oslFileError SAL_CALL osl_getNextDrive(
893cdf0e10cSrcweir 	oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
894cdf0e10cSrcweir {
895cdf0e10cSrcweir 	Directory_Impl		*pDirImpl = (Directory_Impl *)Directory;
896cdf0e10cSrcweir 	DirectoryItem_Impl	*pItemImpl = NULL;
897cdf0e10cSrcweir 	BOOL				fSuccess;
898cdf0e10cSrcweir 
899cdf0e10cSrcweir 	uHint = uHint; /* avoid warnings */
900cdf0e10cSrcweir 
901cdf0e10cSrcweir 	if ( !pItem )
902cdf0e10cSrcweir 		return osl_File_E_INVAL;
903cdf0e10cSrcweir 	*pItem = NULL;
904cdf0e10cSrcweir 
905cdf0e10cSrcweir 	if ( !pDirImpl )
906cdf0e10cSrcweir 		return osl_File_E_INVAL;
907cdf0e10cSrcweir 
908cdf0e10cSrcweir 	pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
909cdf0e10cSrcweir 	if ( !pItemImpl )
910cdf0e10cSrcweir 		return osl_File_E_NOMEM;
911cdf0e10cSrcweir 
912cdf0e10cSrcweir 	ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
913cdf0e10cSrcweir 	pItemImpl->uType = DIRECTORYITEM_DRIVE;
914cdf0e10cSrcweir 	osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
915cdf0e10cSrcweir 	fSuccess = EnumLogicalDrives( pDirImpl->hEnumDrives, pItemImpl->cDriveString );
916cdf0e10cSrcweir 
917cdf0e10cSrcweir 	if ( fSuccess )
918cdf0e10cSrcweir 	{
919cdf0e10cSrcweir 		*pItem = pItemImpl;
920cdf0e10cSrcweir 		return osl_File_E_None;
921cdf0e10cSrcweir 	}
922cdf0e10cSrcweir 	else
923cdf0e10cSrcweir 	{
924cdf0e10cSrcweir         if ( pItemImpl->m_pFullPath )
925cdf0e10cSrcweir         {
926cdf0e10cSrcweir             rtl_uString_release( pItemImpl->m_pFullPath );
927cdf0e10cSrcweir             pItemImpl->m_pFullPath = 0;
928cdf0e10cSrcweir         }
929cdf0e10cSrcweir 
930cdf0e10cSrcweir 		rtl_freeMemory( pItemImpl );
931cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
932cdf0e10cSrcweir 	}
933cdf0e10cSrcweir }
934cdf0e10cSrcweir 
935cdf0e10cSrcweir //#####################################################
osl_getNextFileItem(oslDirectory Directory,oslDirectoryItem * pItem,sal_uInt32 uHint)936cdf0e10cSrcweir static oslFileError SAL_CALL osl_getNextFileItem(
937cdf0e10cSrcweir 	oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint)
938cdf0e10cSrcweir {
939cdf0e10cSrcweir 	Directory_Impl		*pDirImpl = (Directory_Impl *)Directory;
940cdf0e10cSrcweir 	DirectoryItem_Impl	*pItemImpl = NULL;
941cdf0e10cSrcweir 	BOOL				fFound;
942cdf0e10cSrcweir 
943cdf0e10cSrcweir 	uHint = uHint; /* avoid warnings */
944cdf0e10cSrcweir 
945cdf0e10cSrcweir 	if ( !pItem )
946cdf0e10cSrcweir 		return osl_File_E_INVAL;
947cdf0e10cSrcweir 	*pItem = NULL;
948cdf0e10cSrcweir 
949cdf0e10cSrcweir 	if ( !pDirImpl )
950cdf0e10cSrcweir 		return osl_File_E_INVAL;
951cdf0e10cSrcweir 
952cdf0e10cSrcweir 	pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
953cdf0e10cSrcweir 	if ( !pItemImpl )
954cdf0e10cSrcweir 		return osl_File_E_NOMEM;
955cdf0e10cSrcweir 
956cdf0e10cSrcweir 	memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
957cdf0e10cSrcweir 	fFound = EnumDirectory( pDirImpl->hDirectory, &pItemImpl->FindData );
958cdf0e10cSrcweir 
959cdf0e10cSrcweir 	if ( fFound )
960cdf0e10cSrcweir 	{
961cdf0e10cSrcweir 		pItemImpl->uType = DIRECTORYITEM_FILE;
962cdf0e10cSrcweir 		pItemImpl->nRefCount = 1;
963cdf0e10cSrcweir 
964cdf0e10cSrcweir         rtl_uString* pTmpFileName = 0;
965cdf0e10cSrcweir         rtl_uString_newFromStr( &pTmpFileName,  reinterpret_cast<const sal_Unicode *>(pItemImpl->FindData.cFileName) );
966cdf0e10cSrcweir         rtl_uString_newConcat( &pItemImpl->m_pFullPath, pDirImpl->m_pDirectoryPath, pTmpFileName );
967cdf0e10cSrcweir         rtl_uString_release( pTmpFileName );
968cdf0e10cSrcweir 
969cdf0e10cSrcweir 		pItemImpl->bFullPathNormalized = FALSE;
970cdf0e10cSrcweir 		*pItem = (oslDirectoryItem)pItemImpl;
971cdf0e10cSrcweir 		return osl_File_E_None;
972cdf0e10cSrcweir 	}
973cdf0e10cSrcweir 	else
974cdf0e10cSrcweir 	{
975cdf0e10cSrcweir         if ( pItemImpl->m_pFullPath )
976cdf0e10cSrcweir         {
977cdf0e10cSrcweir             rtl_uString_release( pItemImpl->m_pFullPath );
978cdf0e10cSrcweir             pItemImpl->m_pFullPath = 0;
979cdf0e10cSrcweir         }
980cdf0e10cSrcweir 
981cdf0e10cSrcweir 		rtl_freeMemory( pItemImpl );
982cdf0e10cSrcweir 		return oslTranslateFileError( GetLastError() );
983cdf0e10cSrcweir 	}
984cdf0e10cSrcweir }
985cdf0e10cSrcweir 
986cdf0e10cSrcweir //#####################################################
osl_getNextDirectoryItem(oslDirectory Directory,oslDirectoryItem * pItem,sal_uInt32 uHint)987cdf0e10cSrcweir oslFileError SAL_CALL osl_getNextDirectoryItem(
988cdf0e10cSrcweir 	oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint)
989cdf0e10cSrcweir {
990cdf0e10cSrcweir 	Directory_Impl		*pDirImpl = (Directory_Impl *)Directory;
991cdf0e10cSrcweir 
992cdf0e10cSrcweir 	/* Assume failure */
993cdf0e10cSrcweir 
994cdf0e10cSrcweir 	if ( !pItem )
995cdf0e10cSrcweir 		return osl_File_E_INVAL;
996cdf0e10cSrcweir 	*pItem = NULL;
997cdf0e10cSrcweir 
998cdf0e10cSrcweir 	if ( !pDirImpl )
999cdf0e10cSrcweir 		return osl_File_E_INVAL;
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir 	switch ( pDirImpl->uType )
1002cdf0e10cSrcweir 	{
1003cdf0e10cSrcweir 	case DIRECTORYTYPE_LOCALROOT:
1004cdf0e10cSrcweir 		return osl_getNextDrive( Directory, pItem, uHint );
1005cdf0e10cSrcweir 	case DIRECTORYTYPE_NETROOT:
1006cdf0e10cSrcweir 		return osl_getNextNetResource( Directory, pItem, uHint );
1007cdf0e10cSrcweir 	case DIRECTORYTYPE_FILESYSTEM:
1008cdf0e10cSrcweir 		return osl_getNextFileItem( Directory, pItem, uHint );
1009cdf0e10cSrcweir 	default:
1010cdf0e10cSrcweir 		return osl_File_E_INVAL;
1011cdf0e10cSrcweir 	}
1012cdf0e10cSrcweir }
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir //#####################################################
osl_closeDirectory(oslDirectory Directory)1015cdf0e10cSrcweir oslFileError SAL_CALL osl_closeDirectory(oslDirectory Directory)
1016cdf0e10cSrcweir {
1017cdf0e10cSrcweir 	Directory_Impl	*pDirImpl = (Directory_Impl *)Directory;
1018cdf0e10cSrcweir 	oslFileError	eError = osl_File_E_INVAL;
1019cdf0e10cSrcweir 
1020cdf0e10cSrcweir 	if ( pDirImpl )
1021cdf0e10cSrcweir 	{
1022cdf0e10cSrcweir 		switch ( pDirImpl->uType )
1023cdf0e10cSrcweir 		{
1024cdf0e10cSrcweir 		case DIRECTORYTYPE_FILESYSTEM:
1025cdf0e10cSrcweir 			eError = CloseDirectory( pDirImpl->hDirectory ) ? osl_File_E_None : oslTranslateFileError( GetLastError() );
1026cdf0e10cSrcweir 			break;
1027cdf0e10cSrcweir 		case DIRECTORYTYPE_LOCALROOT:
1028cdf0e10cSrcweir 			eError = CloseLogicalDrivesEnum( pDirImpl->hEnumDrives ) ? osl_File_E_None : oslTranslateFileError( GetLastError() );
1029cdf0e10cSrcweir 			break;
1030cdf0e10cSrcweir 		case DIRECTORYTYPE_NETROOT:
1031cdf0e10cSrcweir 		    {
1032cdf0e10cSrcweir 		        DWORD err = WNetCloseEnum(pDirImpl->hDirectory);
1033cdf0e10cSrcweir 			    eError = (err == NO_ERROR) ? osl_File_E_None : oslTranslateFileError(err);
1034cdf0e10cSrcweir 			}
1035cdf0e10cSrcweir 			break;
1036cdf0e10cSrcweir 		default:
1037cdf0e10cSrcweir 			OSL_ENSURE( 0, "Invalid directory type" );
1038cdf0e10cSrcweir 			break;
1039cdf0e10cSrcweir 		}
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir         if ( pDirImpl->m_pDirectoryPath )
1042cdf0e10cSrcweir         {
1043cdf0e10cSrcweir             rtl_uString_release( pDirImpl->m_pDirectoryPath );
1044cdf0e10cSrcweir             pDirImpl->m_pDirectoryPath = 0;
1045cdf0e10cSrcweir         }
1046cdf0e10cSrcweir 
1047cdf0e10cSrcweir 		rtl_freeMemory(pDirImpl);
1048cdf0e10cSrcweir 	}
1049cdf0e10cSrcweir 	return eError;
1050cdf0e10cSrcweir }
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir //#####################################################
1053cdf0e10cSrcweir /* Different types of paths */
1054cdf0e10cSrcweir typedef enum _PATHTYPE
1055cdf0e10cSrcweir {
1056cdf0e10cSrcweir 	PATHTYPE_SYNTAXERROR = 0,
1057cdf0e10cSrcweir 	PATHTYPE_NETROOT,
1058cdf0e10cSrcweir 	PATHTYPE_NETSERVER,
1059cdf0e10cSrcweir 	PATHTYPE_VOLUME,
1060cdf0e10cSrcweir 	PATHTYPE_FILE
1061cdf0e10cSrcweir } PATHTYPE;
1062cdf0e10cSrcweir 
osl_getDirectoryItem(rtl_uString * strFilePath,oslDirectoryItem * pItem)1063cdf0e10cSrcweir oslFileError SAL_CALL osl_getDirectoryItem(rtl_uString *strFilePath, oslDirectoryItem *pItem)
1064cdf0e10cSrcweir {
1065cdf0e10cSrcweir 	oslFileError	error = osl_File_E_None;
1066cdf0e10cSrcweir 	rtl_uString*	strSysFilePath = NULL;
1067cdf0e10cSrcweir 	PATHTYPE		type = PATHTYPE_FILE;
1068cdf0e10cSrcweir 	DWORD			dwPathType;
1069cdf0e10cSrcweir 
1070cdf0e10cSrcweir 	/* Assume failure */
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir 	if ( !pItem )
1073cdf0e10cSrcweir 		return osl_File_E_INVAL;
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir 	*pItem = NULL;
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir 
1078cdf0e10cSrcweir 	error = _osl_getSystemPathFromFileURL( strFilePath, &strSysFilePath, sal_False );
1079cdf0e10cSrcweir 
1080cdf0e10cSrcweir 	if ( osl_File_E_None != error )
1081cdf0e10cSrcweir 			return error;
1082cdf0e10cSrcweir 
1083cdf0e10cSrcweir 	dwPathType = IsValidFilePath( strSysFilePath, NULL, VALIDATEPATH_NORMAL, NULL );
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir 	if ( dwPathType & PATHTYPE_IS_VOLUME )
1086cdf0e10cSrcweir 		type = PATHTYPE_VOLUME;
1087cdf0e10cSrcweir 	else if ( dwPathType & PATHTYPE_IS_SERVER )
1088cdf0e10cSrcweir 		type = PATHTYPE_NETSERVER;
1089cdf0e10cSrcweir 	else
1090cdf0e10cSrcweir 		type = PATHTYPE_FILE;
1091cdf0e10cSrcweir 
1092cdf0e10cSrcweir 	switch ( type )
1093cdf0e10cSrcweir 	{
1094cdf0e10cSrcweir 	case PATHTYPE_NETSERVER:
1095cdf0e10cSrcweir 		{
1096cdf0e10cSrcweir 			DirectoryItem_Impl*	pItemImpl =
1097cdf0e10cSrcweir 			    reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir 			if ( !pItemImpl )
1100cdf0e10cSrcweir 				error = osl_File_E_NOMEM;
1101cdf0e10cSrcweir 
1102cdf0e10cSrcweir 			if ( osl_File_E_None == error )
1103cdf0e10cSrcweir 			{
1104cdf0e10cSrcweir 				ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
1105cdf0e10cSrcweir 				pItemImpl->uType = DIRECTORYITEM_SERVER;
1106cdf0e10cSrcweir 
1107cdf0e10cSrcweir 				osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
1108cdf0e10cSrcweir                 rtl_uString_newFromString( &pItemImpl->m_pFullPath, strSysFilePath );
1109cdf0e10cSrcweir 
1110cdf0e10cSrcweir 				// Assign a title anyway
1111cdf0e10cSrcweir 				{
1112cdf0e10cSrcweir 					int iSrc = 2;
1113cdf0e10cSrcweir 					int	iDst = 0;
1114cdf0e10cSrcweir 
1115cdf0e10cSrcweir 					while( iSrc < strSysFilePath->length && strSysFilePath->buffer[iSrc] && strSysFilePath->buffer[iSrc] != '\\' )
1116cdf0e10cSrcweir 					{
1117cdf0e10cSrcweir 						pItemImpl->FindData.cFileName[iDst++] = strSysFilePath->buffer[iSrc++];
1118cdf0e10cSrcweir 					}
1119cdf0e10cSrcweir 				}
1120cdf0e10cSrcweir 
1121cdf0e10cSrcweir 				*pItem = pItemImpl;
1122cdf0e10cSrcweir 			}
1123cdf0e10cSrcweir 		}
1124cdf0e10cSrcweir 		break;
1125cdf0e10cSrcweir 	case PATHTYPE_VOLUME:
1126cdf0e10cSrcweir 		{
1127cdf0e10cSrcweir 			DirectoryItem_Impl*	pItemImpl =
1128cdf0e10cSrcweir 			    reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir 			if ( !pItemImpl )
1131cdf0e10cSrcweir 				error = osl_File_E_NOMEM;
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir 			if ( osl_File_E_None == error )
1134cdf0e10cSrcweir 			{
1135cdf0e10cSrcweir 				ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
1136cdf0e10cSrcweir 				pItemImpl->uType = DIRECTORYITEM_DRIVE;
1137cdf0e10cSrcweir 
1138cdf0e10cSrcweir 				osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
1139cdf0e10cSrcweir 
1140cdf0e10cSrcweir 				_tcscpy( pItemImpl->cDriveString, reinterpret_cast<LPCTSTR>(strSysFilePath->buffer) );
1141cdf0e10cSrcweir 				pItemImpl->cDriveString[0] = _toupper( pItemImpl->cDriveString[0] );
1142cdf0e10cSrcweir 
1143cdf0e10cSrcweir 				if ( pItemImpl->cDriveString[_tcslen(pItemImpl->cDriveString) - 1] != '\\' )
1144cdf0e10cSrcweir 					_tcscat( pItemImpl->cDriveString, TEXT( "\\" ) );
1145cdf0e10cSrcweir 
1146cdf0e10cSrcweir 				*pItem = pItemImpl;
1147cdf0e10cSrcweir 			}
1148cdf0e10cSrcweir 		}
1149cdf0e10cSrcweir 		break;
1150cdf0e10cSrcweir     case PATHTYPE_SYNTAXERROR:
1151cdf0e10cSrcweir     case PATHTYPE_NETROOT:
1152cdf0e10cSrcweir 	case PATHTYPE_FILE:
1153cdf0e10cSrcweir 		{
1154cdf0e10cSrcweir 			HANDLE				hFind;
1155cdf0e10cSrcweir 			WIN32_FIND_DATA		aFindData;
1156cdf0e10cSrcweir 
1157cdf0e10cSrcweir 			if ( strSysFilePath->length > 0 && strSysFilePath->buffer[strSysFilePath->length - 1] == '\\' )
1158cdf0e10cSrcweir 				rtl_uString_newFromStr_WithLength( &strSysFilePath, strSysFilePath->buffer, strSysFilePath->length - 1 );
1159cdf0e10cSrcweir 
1160cdf0e10cSrcweir 			hFind = FindFirstFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysFilePath)), &aFindData );
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir 			if ( hFind != INVALID_HANDLE_VALUE )
1163cdf0e10cSrcweir 			{
1164cdf0e10cSrcweir 				DirectoryItem_Impl	*pItemImpl =
1165cdf0e10cSrcweir 				    reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir 				ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
1168cdf0e10cSrcweir 				osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
1169cdf0e10cSrcweir 
1170cdf0e10cSrcweir 				CopyMemory( &pItemImpl->FindData, &aFindData, sizeof(WIN32_FIND_DATA) );
1171cdf0e10cSrcweir                 rtl_uString_newFromString( &pItemImpl->m_pFullPath, strSysFilePath );
1172cdf0e10cSrcweir 
1173cdf0e10cSrcweir 				// MT: This costs 600ms startup time on fast v60x!
1174cdf0e10cSrcweir 				// GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) );
1175cdf0e10cSrcweir 
1176cdf0e10cSrcweir 				pItemImpl->uType = DIRECTORYITEM_FILE;
1177cdf0e10cSrcweir 				*pItem = pItemImpl;
1178cdf0e10cSrcweir 				FindClose( hFind );
1179cdf0e10cSrcweir 			}
1180cdf0e10cSrcweir 			else
1181cdf0e10cSrcweir 				error = oslTranslateFileError( GetLastError() );
1182cdf0e10cSrcweir 		}
1183cdf0e10cSrcweir 		break;
1184cdf0e10cSrcweir 	}
1185cdf0e10cSrcweir 
1186cdf0e10cSrcweir 	if ( strSysFilePath )
1187cdf0e10cSrcweir 		rtl_uString_release( strSysFilePath );
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir 	return error;
1190cdf0e10cSrcweir }
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir //#####################################################
osl_acquireDirectoryItem(oslDirectoryItem Item)1193cdf0e10cSrcweir oslFileError SAL_CALL osl_acquireDirectoryItem( oslDirectoryItem Item )
1194cdf0e10cSrcweir {
1195cdf0e10cSrcweir 	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
1196cdf0e10cSrcweir 
1197cdf0e10cSrcweir 	if ( !pItemImpl )
1198cdf0e10cSrcweir 		return osl_File_E_INVAL;
1199cdf0e10cSrcweir 
1200cdf0e10cSrcweir 	pItemImpl->nRefCount++;
1201cdf0e10cSrcweir 	return osl_File_E_None;
1202cdf0e10cSrcweir }
1203cdf0e10cSrcweir 
1204cdf0e10cSrcweir //#####################################################
osl_releaseDirectoryItem(oslDirectoryItem Item)1205cdf0e10cSrcweir oslFileError SAL_CALL osl_releaseDirectoryItem( oslDirectoryItem Item )
1206cdf0e10cSrcweir {
1207cdf0e10cSrcweir 	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
1208cdf0e10cSrcweir 
1209cdf0e10cSrcweir 	if ( !pItemImpl )
1210cdf0e10cSrcweir 		return osl_File_E_INVAL;
1211cdf0e10cSrcweir 
1212cdf0e10cSrcweir 	if ( ! --pItemImpl->nRefCount )
1213cdf0e10cSrcweir     {
1214cdf0e10cSrcweir         if ( pItemImpl->m_pFullPath )
1215cdf0e10cSrcweir         {
1216cdf0e10cSrcweir             rtl_uString_release( pItemImpl->m_pFullPath );
1217cdf0e10cSrcweir             pItemImpl->m_pFullPath = 0;
1218cdf0e10cSrcweir         }
1219cdf0e10cSrcweir 
1220cdf0e10cSrcweir 		rtl_freeMemory( pItemImpl );
1221cdf0e10cSrcweir     }
1222cdf0e10cSrcweir 
1223cdf0e10cSrcweir 	return osl_File_E_None;
1224cdf0e10cSrcweir }
1225cdf0e10cSrcweir 
1226cdf0e10cSrcweir //#####################################################
1227cdf0e10cSrcweir // volume / file info handling functions
1228cdf0e10cSrcweir //#####################################################
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir //#####################################################
is_floppy_A_present()1231cdf0e10cSrcweir static inline bool is_floppy_A_present()
1232cdf0e10cSrcweir { return (GetLogicalDrives() & 1); }
1233cdf0e10cSrcweir 
1234cdf0e10cSrcweir //#####################################################
is_floppy_B_present()1235cdf0e10cSrcweir static inline bool is_floppy_B_present()
1236cdf0e10cSrcweir { return (GetLogicalDrives() & 2); }
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir //#####################################################
is_floppy_volume_mount_point(const rtl::OUString & path)1239cdf0e10cSrcweir bool is_floppy_volume_mount_point(const rtl::OUString& path)
1240cdf0e10cSrcweir {
1241cdf0e10cSrcweir     // determines if a volume mount point shows to a floppy
1242cdf0e10cSrcweir     // disk by comparing the unique volume names
1243cdf0e10cSrcweir     static const LPCWSTR FLOPPY_A = L"A:\\";
1244cdf0e10cSrcweir     static const LPCWSTR FLOPPY_B = L"B:\\";
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir 	rtl::OUString p(path);
1247cdf0e10cSrcweir 	osl::systemPathEnsureSeparator(p);
1248cdf0e10cSrcweir 
1249cdf0e10cSrcweir 	TCHAR vn[51];
1250cdf0e10cSrcweir 	if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR>(p.getStr()), vn, ELEMENTS_OF_ARRAY(vn)))
1251cdf0e10cSrcweir 	{
1252cdf0e10cSrcweir 		TCHAR vnfloppy[51];
1253cdf0e10cSrcweir 		if (is_floppy_A_present() &&
1254cdf0e10cSrcweir 			GetVolumeNameForVolumeMountPoint(FLOPPY_A, vnfloppy, ELEMENTS_OF_ARRAY(vnfloppy)) &&
1255cdf0e10cSrcweir 			(0 == wcscmp(vn, vnfloppy)))
1256cdf0e10cSrcweir 			return true;
1257cdf0e10cSrcweir 
1258cdf0e10cSrcweir 		if (is_floppy_B_present() &&
1259cdf0e10cSrcweir 			GetVolumeNameForVolumeMountPoint(FLOPPY_B, vnfloppy, ELEMENTS_OF_ARRAY(vnfloppy)) &&
1260cdf0e10cSrcweir 			(0 == wcscmp(vn, vnfloppy)))
1261cdf0e10cSrcweir 			return true;
1262cdf0e10cSrcweir 	}
1263cdf0e10cSrcweir 	return false;
1264cdf0e10cSrcweir }
1265cdf0e10cSrcweir 
1266cdf0e10cSrcweir //################################################
is_floppy_drive(const rtl::OUString & path)1267cdf0e10cSrcweir static bool is_floppy_drive(const rtl::OUString& path)
1268cdf0e10cSrcweir {
1269cdf0e10cSrcweir 	static const LPCWSTR FLOPPY_DRV_LETTERS = TEXT("AaBb");
1270cdf0e10cSrcweir 
1271cdf0e10cSrcweir     // we must take into account that even a floppy
1272cdf0e10cSrcweir     // drive may be mounted to a directory so checking
1273cdf0e10cSrcweir     // for the drive letter alone is not sufficient
1274cdf0e10cSrcweir     // we must compare the unique volume name with
1275cdf0e10cSrcweir     // that of the available floppy disks
1276cdf0e10cSrcweir 
1277cdf0e10cSrcweir 	const sal_Unicode* pszPath = path.getStr();
1278cdf0e10cSrcweir 	return ((wcschr(FLOPPY_DRV_LETTERS, pszPath[0]) && (L':' == pszPath[1])) || is_floppy_volume_mount_point(path));
1279cdf0e10cSrcweir }
1280cdf0e10cSrcweir 
1281cdf0e10cSrcweir //#####################################################
is_volume_mount_point(const rtl::OUString & path)1282cdf0e10cSrcweir static bool is_volume_mount_point(const rtl::OUString& path)
1283cdf0e10cSrcweir {
1284cdf0e10cSrcweir 	rtl::OUString p(path);
1285cdf0e10cSrcweir 	osl::systemPathRemoveSeparator(p);
1286cdf0e10cSrcweir 
1287cdf0e10cSrcweir 	bool  is_volume_root = false;
1288cdf0e10cSrcweir 
1289cdf0e10cSrcweir 	if (!is_floppy_drive(p))
1290cdf0e10cSrcweir 	{
1291cdf0e10cSrcweir 		DWORD fattr = GetFileAttributes(reinterpret_cast<LPCTSTR>(p.getStr()));
1292cdf0e10cSrcweir 
1293cdf0e10cSrcweir 		if ((INVALID_FILE_ATTRIBUTES != fattr) &&
1294cdf0e10cSrcweir 			(FILE_ATTRIBUTE_REPARSE_POINT & fattr))
1295cdf0e10cSrcweir 		{
1296cdf0e10cSrcweir 			WIN32_FIND_DATA find_data;
1297cdf0e10cSrcweir 			HANDLE h_find = FindFirstFile(reinterpret_cast<LPCTSTR>(p.getStr()), &find_data);
1298cdf0e10cSrcweir 
1299cdf0e10cSrcweir 			if (IsValidHandle(h_find) &&
1300cdf0e10cSrcweir 				(FILE_ATTRIBUTE_REPARSE_POINT & find_data.dwFileAttributes) &&
1301cdf0e10cSrcweir 				(IO_REPARSE_TAG_MOUNT_POINT == find_data.dwReserved0))
1302cdf0e10cSrcweir 			{
1303cdf0e10cSrcweir 				is_volume_root = true;
1304cdf0e10cSrcweir 			}
1305cdf0e10cSrcweir 			if (IsValidHandle(h_find))
1306cdf0e10cSrcweir 				FindClose(h_find);
1307cdf0e10cSrcweir 		}
1308cdf0e10cSrcweir 	}
1309cdf0e10cSrcweir 	return is_volume_root;
1310cdf0e10cSrcweir }
1311cdf0e10cSrcweir 
1312cdf0e10cSrcweir //#############################################
get_volume_mount_point_drive_type(const rtl::OUString & path)1313cdf0e10cSrcweir static UINT get_volume_mount_point_drive_type(const rtl::OUString& path)
1314cdf0e10cSrcweir {
1315cdf0e10cSrcweir 	if (0 == path.getLength())
1316cdf0e10cSrcweir 		return GetDriveType(NULL);
1317cdf0e10cSrcweir 
1318cdf0e10cSrcweir 	rtl::OUString p(path);
1319cdf0e10cSrcweir 	osl::systemPathEnsureSeparator(p);
1320cdf0e10cSrcweir 
1321cdf0e10cSrcweir 	TCHAR vn[51];
1322cdf0e10cSrcweir 	if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR>(p.getStr()), vn, ELEMENTS_OF_ARRAY(vn)))
1323cdf0e10cSrcweir 		return GetDriveType(vn);
1324cdf0e10cSrcweir 
1325cdf0e10cSrcweir 	return DRIVE_NO_ROOT_DIR;
1326cdf0e10cSrcweir }
1327cdf0e10cSrcweir 
1328cdf0e10cSrcweir //#############################################
is_drivetype_request(sal_uInt32 field_mask)1329cdf0e10cSrcweir static inline bool is_drivetype_request(sal_uInt32 field_mask)
1330cdf0e10cSrcweir {
1331cdf0e10cSrcweir 	return (field_mask & osl_VolumeInfo_Mask_Attributes);
1332cdf0e10cSrcweir }
1333cdf0e10cSrcweir 
1334cdf0e10cSrcweir //#############################################
osl_get_drive_type(const rtl::OUString & path,oslVolumeInfo * pInfo)1335cdf0e10cSrcweir static oslFileError osl_get_drive_type(
1336cdf0e10cSrcweir 	const rtl::OUString& path, oslVolumeInfo* pInfo)
1337cdf0e10cSrcweir {
1338cdf0e10cSrcweir 	// GetDriveType fails on empty volume mount points
1339cdf0e10cSrcweir 	// see Knowledge Base Q244089
1340cdf0e10cSrcweir 	UINT drive_type;
1341cdf0e10cSrcweir 	if (is_volume_mount_point(path))
1342cdf0e10cSrcweir 		drive_type = get_volume_mount_point_drive_type(path);
1343cdf0e10cSrcweir 	else
1344cdf0e10cSrcweir 		drive_type = GetDriveType(reinterpret_cast<LPCTSTR>(path.getStr()));
1345cdf0e10cSrcweir 
1346cdf0e10cSrcweir 	if (DRIVE_NO_ROOT_DIR == drive_type)
1347cdf0e10cSrcweir 		return oslTranslateFileError(ERROR_INVALID_DRIVE);
1348cdf0e10cSrcweir 
1349cdf0e10cSrcweir 	pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
1350cdf0e10cSrcweir 
1351cdf0e10cSrcweir 	switch (drive_type)
1352cdf0e10cSrcweir 	{
1353cdf0e10cSrcweir 		case DRIVE_CDROM:
1354cdf0e10cSrcweir 			pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
1355cdf0e10cSrcweir 			break;
1356cdf0e10cSrcweir 		case DRIVE_REMOVABLE:
1357cdf0e10cSrcweir 			pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
1358cdf0e10cSrcweir 			if (is_floppy_drive(path))
1359cdf0e10cSrcweir 				pInfo->uAttributes |= osl_Volume_Attribute_FloppyDisk;
1360cdf0e10cSrcweir 			break;
1361cdf0e10cSrcweir 		case DRIVE_FIXED:
1362cdf0e10cSrcweir 			pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
1363cdf0e10cSrcweir 			break;
1364cdf0e10cSrcweir 		case DRIVE_RAMDISK:
1365cdf0e10cSrcweir 			pInfo->uAttributes |= osl_Volume_Attribute_RAMDisk;
1366cdf0e10cSrcweir 			break;
1367cdf0e10cSrcweir 		case DRIVE_REMOTE:
1368cdf0e10cSrcweir 			pInfo->uAttributes |= osl_Volume_Attribute_Remote;
1369cdf0e10cSrcweir 			break;
1370cdf0e10cSrcweir 		case DRIVE_UNKNOWN:
1371cdf0e10cSrcweir 			pInfo->uAttributes = 0;
1372cdf0e10cSrcweir 			break;
1373cdf0e10cSrcweir 		default:
1374cdf0e10cSrcweir 			pInfo->uValidFields &= ~osl_VolumeInfo_Mask_Attributes;
1375cdf0e10cSrcweir 			pInfo->uAttributes = 0;
1376cdf0e10cSrcweir 			break;
1377cdf0e10cSrcweir 	}
1378cdf0e10cSrcweir 	return osl_File_E_None;
1379cdf0e10cSrcweir }
1380cdf0e10cSrcweir 
1381cdf0e10cSrcweir //#############################################
is_volume_space_info_request(sal_uInt32 field_mask)1382cdf0e10cSrcweir static inline bool is_volume_space_info_request(sal_uInt32 field_mask)
1383cdf0e10cSrcweir {
1384cdf0e10cSrcweir 	return (field_mask &
1385cdf0e10cSrcweir 			(osl_VolumeInfo_Mask_TotalSpace |
1386cdf0e10cSrcweir 			 osl_VolumeInfo_Mask_UsedSpace  |
1387cdf0e10cSrcweir 			 osl_VolumeInfo_Mask_FreeSpace));
1388cdf0e10cSrcweir }
1389cdf0e10cSrcweir 
1390cdf0e10cSrcweir //#############################################
get_volume_space_information(const rtl::OUString & path,oslVolumeInfo * pInfo)1391cdf0e10cSrcweir static void get_volume_space_information(
1392cdf0e10cSrcweir 	const rtl::OUString& path, oslVolumeInfo *pInfo)
1393cdf0e10cSrcweir {
1394cdf0e10cSrcweir 	BOOL ret = GetDiskFreeSpaceEx(
1395cdf0e10cSrcweir 		reinterpret_cast<LPCTSTR>(path.getStr()),
1396cdf0e10cSrcweir 		(PULARGE_INTEGER)&(pInfo->uFreeSpace),
1397cdf0e10cSrcweir 		(PULARGE_INTEGER)&(pInfo->uTotalSpace),
1398cdf0e10cSrcweir 		NULL);
1399cdf0e10cSrcweir 
1400cdf0e10cSrcweir 	if (ret)
1401cdf0e10cSrcweir 	{
1402cdf0e10cSrcweir 		pInfo->uUsedSpace    = pInfo->uTotalSpace - pInfo->uFreeSpace;
1403cdf0e10cSrcweir 		pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace |
1404cdf0e10cSrcweir 			osl_VolumeInfo_Mask_UsedSpace |
1405cdf0e10cSrcweir 			osl_VolumeInfo_Mask_FreeSpace;
1406cdf0e10cSrcweir 	}
1407cdf0e10cSrcweir }
1408cdf0e10cSrcweir 
1409cdf0e10cSrcweir //#############################################
is_filesystem_attributes_request(sal_uInt32 field_mask)1410cdf0e10cSrcweir static inline bool is_filesystem_attributes_request(sal_uInt32 field_mask)
1411cdf0e10cSrcweir {
1412cdf0e10cSrcweir 	return (field_mask &
1413cdf0e10cSrcweir 			(osl_VolumeInfo_Mask_MaxNameLength |
1414cdf0e10cSrcweir 			 osl_VolumeInfo_Mask_MaxPathLength |
1415cdf0e10cSrcweir 			 osl_VolumeInfo_Mask_FileSystemName |
1416cdf0e10cSrcweir 			 osl_VolumeInfo_Mask_FileSystemCaseHandling));
1417cdf0e10cSrcweir }
1418cdf0e10cSrcweir 
1419cdf0e10cSrcweir //#############################################
get_filesystem_attributes(const rtl::OUString & path,sal_uInt32 field_mask,oslVolumeInfo * pInfo)1420cdf0e10cSrcweir static oslFileError get_filesystem_attributes(
1421cdf0e10cSrcweir 	const rtl::OUString& path, sal_uInt32 field_mask, oslVolumeInfo* pInfo)
1422cdf0e10cSrcweir {
1423cdf0e10cSrcweir 	pInfo->uAttributes = 0;
1424cdf0e10cSrcweir 
1425cdf0e10cSrcweir 	// osl_get_drive_type must be called first because
1426cdf0e10cSrcweir 	// this function resets osl_VolumeInfo_Mask_Attributes
1427cdf0e10cSrcweir 	// on failure
1428cdf0e10cSrcweir 	if (is_drivetype_request(field_mask))
1429cdf0e10cSrcweir 	{
1430cdf0e10cSrcweir 		oslFileError osl_error = osl_get_drive_type(path, pInfo);
1431cdf0e10cSrcweir         if (osl_File_E_None != osl_error)
1432cdf0e10cSrcweir 			return osl_error;
1433cdf0e10cSrcweir 	}
1434cdf0e10cSrcweir 	if (is_filesystem_attributes_request(field_mask))
1435cdf0e10cSrcweir 	{
1436cdf0e10cSrcweir         /* the following two parameters can not be longer than MAX_PATH+1 */
1437cdf0e10cSrcweir 		WCHAR vn[MAX_PATH+1];
1438cdf0e10cSrcweir 		WCHAR fsn[MAX_PATH+1];
1439cdf0e10cSrcweir 
1440cdf0e10cSrcweir 		DWORD serial;
1441cdf0e10cSrcweir 		DWORD mcl;
1442cdf0e10cSrcweir 		DWORD flags;
1443cdf0e10cSrcweir 
1444cdf0e10cSrcweir 		LPCTSTR pszPath = reinterpret_cast<LPCTSTR>(path.getStr());
1445cdf0e10cSrcweir 		if (GetVolumeInformation(pszPath, vn, MAX_PATH+1, &serial, &mcl, &flags, fsn, MAX_PATH+1))
1446cdf0e10cSrcweir 		{
1447cdf0e10cSrcweir             // Currently sal does not use this value, instead MAX_PATH is used
1448cdf0e10cSrcweir 			pInfo->uValidFields   |= osl_VolumeInfo_Mask_MaxNameLength;
1449cdf0e10cSrcweir 			pInfo->uMaxNameLength  = mcl;
1450cdf0e10cSrcweir 
1451cdf0e10cSrcweir             // Should the uMaxPathLength be set to 32767, "\\?\" prefix allowes it
1452cdf0e10cSrcweir 			pInfo->uValidFields   |= osl_VolumeInfo_Mask_MaxPathLength;
1453cdf0e10cSrcweir 			pInfo->uMaxPathLength  = MAX_PATH;
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir 			pInfo->uValidFields   |= osl_VolumeInfo_Mask_FileSystemName;
1456cdf0e10cSrcweir 			rtl_uString_newFromStr(&pInfo->ustrFileSystemName, reinterpret_cast<const sal_Unicode*>(fsn));
1457cdf0e10cSrcweir 
1458cdf0e10cSrcweir 			// volumes (even NTFS) will always be considered case
1459cdf0e10cSrcweir 			// insensitive because the Win32 API is not able to
1460cdf0e10cSrcweir 			// deal with case sensitive volumes see M$ Knowledge Base
1461cdf0e10cSrcweir 			// article 100625 that's why we never set the attribute
1462cdf0e10cSrcweir 			// osl_Volume_Attribute_Case_Sensitive
1463cdf0e10cSrcweir 
1464cdf0e10cSrcweir 			if (flags & FS_CASE_IS_PRESERVED)
1465cdf0e10cSrcweir 				pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
1466cdf0e10cSrcweir 
1467cdf0e10cSrcweir 			pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
1468cdf0e10cSrcweir 		}
1469cdf0e10cSrcweir 	}
1470cdf0e10cSrcweir 	return osl_File_E_None;
1471cdf0e10cSrcweir }
1472cdf0e10cSrcweir 
1473cdf0e10cSrcweir //#####################################################
path_get_parent(rtl::OUString & path)1474cdf0e10cSrcweir static bool path_get_parent(rtl::OUString& path)
1475cdf0e10cSrcweir {
1476cdf0e10cSrcweir 	OSL_PRECOND(path.lastIndexOf(SLASH) == -1, "Path must not have slashes");
1477cdf0e10cSrcweir 
1478cdf0e10cSrcweir 	if (!has_path_parent(path))
1479cdf0e10cSrcweir 	{
1480cdf0e10cSrcweir 		sal_Int32 i = path.lastIndexOf(BACKSLASH);
1481cdf0e10cSrcweir 		if (-1 < i)
1482cdf0e10cSrcweir 		{
1483cdf0e10cSrcweir 			path = rtl::OUString(path.getStr(), i);
1484cdf0e10cSrcweir 			return true;
1485cdf0e10cSrcweir 		}
1486cdf0e10cSrcweir 	}
1487cdf0e10cSrcweir 	return false;
1488cdf0e10cSrcweir }
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir //#####################################################
path_travel_to_volume_root(const rtl::OUString & system_path,rtl::OUString & volume_root)1491cdf0e10cSrcweir static void path_travel_to_volume_root(const rtl::OUString& system_path, rtl::OUString& volume_root)
1492cdf0e10cSrcweir {
1493cdf0e10cSrcweir 	rtl::OUString sys_path(system_path);
1494cdf0e10cSrcweir 
1495cdf0e10cSrcweir 	while(!is_volume_mount_point(sys_path) && path_get_parent(sys_path))
1496cdf0e10cSrcweir 		/**/;
1497cdf0e10cSrcweir 
1498cdf0e10cSrcweir 	volume_root = sys_path;
1499cdf0e10cSrcweir 	osl::systemPathEnsureSeparator(volume_root);
1500cdf0e10cSrcweir }
1501cdf0e10cSrcweir 
1502cdf0e10cSrcweir //#############################################
osl_getVolumeInformation(rtl_uString * ustrURL,oslVolumeInfo * pInfo,sal_uInt32 uFieldMask)1503cdf0e10cSrcweir oslFileError SAL_CALL osl_getVolumeInformation(
1504cdf0e10cSrcweir     rtl_uString *ustrURL, oslVolumeInfo *pInfo, sal_uInt32 uFieldMask )
1505cdf0e10cSrcweir {
1506cdf0e10cSrcweir 	if (!pInfo)
1507cdf0e10cSrcweir 		return osl_File_E_INVAL;
1508cdf0e10cSrcweir 
1509cdf0e10cSrcweir     rtl::OUString system_path;
1510cdf0e10cSrcweir 	oslFileError error = _osl_getSystemPathFromFileURL(ustrURL, &system_path.pData, sal_False);
1511cdf0e10cSrcweir 
1512cdf0e10cSrcweir     if (osl_File_E_None != error)
1513cdf0e10cSrcweir         return error;
1514cdf0e10cSrcweir 
1515cdf0e10cSrcweir     rtl::OUString volume_root;
1516cdf0e10cSrcweir     path_travel_to_volume_root(system_path, volume_root);
1517cdf0e10cSrcweir 
1518cdf0e10cSrcweir 	pInfo->uValidFields = 0;
1519cdf0e10cSrcweir 
1520cdf0e10cSrcweir     if ((error = get_filesystem_attributes(volume_root, uFieldMask, pInfo)) != osl_File_E_None)
1521cdf0e10cSrcweir         return error;
1522cdf0e10cSrcweir 
1523cdf0e10cSrcweir 	if (is_volume_space_info_request(uFieldMask))
1524cdf0e10cSrcweir 	    get_volume_space_information(volume_root, pInfo);
1525cdf0e10cSrcweir 
1526cdf0e10cSrcweir 	if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
1527cdf0e10cSrcweir 	{
1528cdf0e10cSrcweir 		pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
1529cdf0e10cSrcweir 		osl_getFileURLFromSystemPath(volume_root.pData, (rtl_uString**)&pInfo->pDeviceHandle);
1530cdf0e10cSrcweir 	}
1531cdf0e10cSrcweir 
1532cdf0e10cSrcweir 	return osl_File_E_None;
1533cdf0e10cSrcweir }
1534cdf0e10cSrcweir 
1535cdf0e10cSrcweir //#####################################################
osl_getDriveInfo(oslDirectoryItem Item,oslFileStatus * pStatus,sal_uInt32 uFieldMask)1536cdf0e10cSrcweir static oslFileError SAL_CALL osl_getDriveInfo(
1537cdf0e10cSrcweir 	oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask)
1538cdf0e10cSrcweir {
1539cdf0e10cSrcweir 	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
1540cdf0e10cSrcweir 	TCHAR				cDrive[3] = TEXT("A:");
1541cdf0e10cSrcweir 	TCHAR				cRoot[4] = TEXT("A:\\");
1542cdf0e10cSrcweir 
1543cdf0e10cSrcweir 	if ( !pItemImpl )
1544cdf0e10cSrcweir 		return osl_File_E_INVAL;
1545cdf0e10cSrcweir 
1546cdf0e10cSrcweir 	pStatus->uValidFields = 0;
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir 	cDrive[0] = pItemImpl->cDriveString[0];
1549cdf0e10cSrcweir 	cRoot[0] = pItemImpl->cDriveString[0];
1550cdf0e10cSrcweir 
1551cdf0e10cSrcweir 	if ( uFieldMask & osl_FileStatus_Mask_FileName )
1552cdf0e10cSrcweir 	{
1553cdf0e10cSrcweir 		if ( pItemImpl->cDriveString[0] == '\\' && pItemImpl->cDriveString[1] == '\\' )
1554cdf0e10cSrcweir 		{
1555cdf0e10cSrcweir 			LPCWSTR	lpFirstBkSlash = wcschr( &pItemImpl->cDriveString[2], '\\' );
1556cdf0e10cSrcweir 
1557cdf0e10cSrcweir 			if ( lpFirstBkSlash && lpFirstBkSlash[1] )
1558cdf0e10cSrcweir 			{
1559cdf0e10cSrcweir 				LPCWSTR	lpLastBkSlash = wcschr( &lpFirstBkSlash[1], '\\' );
1560cdf0e10cSrcweir 
1561cdf0e10cSrcweir 				if ( lpLastBkSlash )
1562cdf0e10cSrcweir 					rtl_uString_newFromStr_WithLength( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(&lpFirstBkSlash[1]), lpLastBkSlash - lpFirstBkSlash - 1 );
1563cdf0e10cSrcweir 				else
1564cdf0e10cSrcweir 					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(&lpFirstBkSlash[1]) );
1565cdf0e10cSrcweir 				pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1566cdf0e10cSrcweir 			}
1567cdf0e10cSrcweir 		}
1568cdf0e10cSrcweir 		else switch ( GetDriveType( cRoot ) )
1569cdf0e10cSrcweir 		{
1570cdf0e10cSrcweir 		    case DRIVE_REMOTE:
1571cdf0e10cSrcweir 			{
1572cdf0e10cSrcweir 				TCHAR szBuffer[1024];
1573cdf0e10cSrcweir 				DWORD const dwBufsizeConst = ELEMENTS_OF_ARRAY(szBuffer);
1574cdf0e10cSrcweir 				DWORD dwBufsize = dwBufsizeConst;
1575cdf0e10cSrcweir 
1576cdf0e10cSrcweir 				DWORD dwResult = WNetGetConnection( cDrive, szBuffer, &dwBufsize );
1577cdf0e10cSrcweir 				if ( NO_ERROR == dwResult )
1578cdf0e10cSrcweir 				{
1579cdf0e10cSrcweir 					TCHAR szFileName[dwBufsizeConst + 16];
1580cdf0e10cSrcweir 
1581cdf0e10cSrcweir 					swprintf( szFileName, L"%s [%s]", cDrive, szBuffer );
1582cdf0e10cSrcweir 					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(szFileName) );
1583cdf0e10cSrcweir 				}
1584cdf0e10cSrcweir 				else
1585cdf0e10cSrcweir 					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cDrive) );
1586cdf0e10cSrcweir 			}
1587cdf0e10cSrcweir 			pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1588cdf0e10cSrcweir 			break;
1589cdf0e10cSrcweir 		    case DRIVE_FIXED:
1590cdf0e10cSrcweir 			{
1591cdf0e10cSrcweir 				TCHAR szVolumeNameBuffer[1024];
1592cdf0e10cSrcweir 				DWORD const dwBufsizeConst = ELEMENTS_OF_ARRAY(szVolumeNameBuffer);
1593cdf0e10cSrcweir 
1594cdf0e10cSrcweir 				if ( GetVolumeInformation( cRoot, szVolumeNameBuffer, dwBufsizeConst, NULL, NULL, NULL, NULL, 0 ) )
1595cdf0e10cSrcweir 				{
1596cdf0e10cSrcweir 					TCHAR	szFileName[dwBufsizeConst + 16];
1597cdf0e10cSrcweir 
1598cdf0e10cSrcweir 					swprintf( szFileName, L"%s [%s]", cDrive, szVolumeNameBuffer );
1599cdf0e10cSrcweir 					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(szFileName) );
1600cdf0e10cSrcweir 				}
1601cdf0e10cSrcweir 				else
1602cdf0e10cSrcweir 					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cDrive) );
1603cdf0e10cSrcweir 			}
1604cdf0e10cSrcweir 			pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1605cdf0e10cSrcweir 			break;
1606cdf0e10cSrcweir 		    case DRIVE_CDROM:
1607cdf0e10cSrcweir 		    case DRIVE_REMOVABLE:
1608cdf0e10cSrcweir 			    pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1609cdf0e10cSrcweir 			    rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cRoot) );
1610cdf0e10cSrcweir 			    break;
1611cdf0e10cSrcweir 		    case DRIVE_UNKNOWN:
1612cdf0e10cSrcweir 		    default:
1613cdf0e10cSrcweir 			    break;
1614cdf0e10cSrcweir 		}
1615cdf0e10cSrcweir 	}
1616cdf0e10cSrcweir 
1617cdf0e10cSrcweir 	pStatus->eType = osl_File_Type_Volume;
1618cdf0e10cSrcweir 	pStatus->uValidFields |= osl_FileStatus_Mask_Type;
1619cdf0e10cSrcweir 
1620cdf0e10cSrcweir 	if ( uFieldMask & osl_FileStatus_Mask_FileURL )
1621cdf0e10cSrcweir 	{
1622cdf0e10cSrcweir 		rtl_uString	*ustrSystemPath = NULL;
1623cdf0e10cSrcweir 
1624cdf0e10cSrcweir 		rtl_uString_newFromStr( &ustrSystemPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->cDriveString) );
1625cdf0e10cSrcweir 		osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
1626cdf0e10cSrcweir 		rtl_uString_release( ustrSystemPath );
1627cdf0e10cSrcweir 		pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
1628cdf0e10cSrcweir 	}
1629cdf0e10cSrcweir 	return osl_File_E_None;
1630cdf0e10cSrcweir }
1631cdf0e10cSrcweir 
1632cdf0e10cSrcweir //#####################################################
osl_getServerInfo(oslDirectoryItem Item,oslFileStatus * pStatus,sal_uInt32 uFieldMask)1633cdf0e10cSrcweir static oslFileError SAL_CALL osl_getServerInfo(
1634cdf0e10cSrcweir 	oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask )
1635cdf0e10cSrcweir {
1636cdf0e10cSrcweir 	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
1637cdf0e10cSrcweir 	if ( !pItemImpl )
1638cdf0e10cSrcweir 		return osl_File_E_INVAL;
1639cdf0e10cSrcweir 
1640cdf0e10cSrcweir 	pStatus->uValidFields = 0;
1641cdf0e10cSrcweir 
1642cdf0e10cSrcweir 	//	pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1643cdf0e10cSrcweir 
1644cdf0e10cSrcweir 	//	if ( _tcscmp( pItemImpl->FindData.cFileName, TEXT(".") ) == 0 )
1645cdf0e10cSrcweir 	//		rtl_uString_newFromAscii( &pStatus->ustrFileName, "/" );
1646cdf0e10cSrcweir 	//	else
1647cdf0e10cSrcweir 	//		rtl_uString_newFromStr( &pStatus->ustrFileName, pItemImpl->FindData.cFileName );
1648cdf0e10cSrcweir 
1649cdf0e10cSrcweir 	pStatus->eType = osl_File_Type_Directory;
1650cdf0e10cSrcweir 	pStatus->uValidFields |= osl_FileStatus_Mask_Type;
1651cdf0e10cSrcweir 
1652cdf0e10cSrcweir 	if ( uFieldMask & osl_FileStatus_Mask_FileURL )
1653cdf0e10cSrcweir 	{
1654cdf0e10cSrcweir 		osl_getFileURLFromSystemPath( pItemImpl->m_pFullPath, &pStatus->ustrFileURL );
1655cdf0e10cSrcweir 		pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
1656cdf0e10cSrcweir 	}
1657cdf0e10cSrcweir 	return osl_File_E_None;
1658cdf0e10cSrcweir }
1659cdf0e10cSrcweir 
1660cdf0e10cSrcweir //#############################################
osl_getFileStatus(oslDirectoryItem Item,oslFileStatus * pStatus,sal_uInt32 uFieldMask)1661cdf0e10cSrcweir oslFileError SAL_CALL osl_getFileStatus(
1662cdf0e10cSrcweir     oslDirectoryItem Item,
1663cdf0e10cSrcweir     oslFileStatus *pStatus,
1664cdf0e10cSrcweir     sal_uInt32 uFieldMask )
1665cdf0e10cSrcweir {
1666cdf0e10cSrcweir 	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
1667cdf0e10cSrcweir 
1668cdf0e10cSrcweir 	if ( !pItemImpl )
1669cdf0e10cSrcweir 		return osl_File_E_INVAL;
1670cdf0e10cSrcweir 
1671cdf0e10cSrcweir 	switch ( pItemImpl->uType  )
1672cdf0e10cSrcweir 	{
1673cdf0e10cSrcweir 	case DIRECTORYITEM_DRIVE:
1674cdf0e10cSrcweir 		return osl_getDriveInfo( Item, pStatus, uFieldMask );
1675cdf0e10cSrcweir 	case DIRECTORYITEM_SERVER:
1676cdf0e10cSrcweir 		return osl_getServerInfo( Item, pStatus, uFieldMask );
1677cdf0e10cSrcweir 	default:
1678cdf0e10cSrcweir 		break;
1679cdf0e10cSrcweir 	}
1680cdf0e10cSrcweir 
1681cdf0e10cSrcweir 	if ( uFieldMask & osl_FileStatus_Mask_Validate )
1682cdf0e10cSrcweir 	{
1683cdf0e10cSrcweir 		HANDLE	hFind = FindFirstFile( reinterpret_cast<LPCTSTR>( rtl_uString_getStr( pItemImpl->m_pFullPath ) ), &pItemImpl->FindData );
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir 		if ( hFind != INVALID_HANDLE_VALUE )
1686cdf0e10cSrcweir 			FindClose( hFind );
1687cdf0e10cSrcweir 		else
1688cdf0e10cSrcweir 			return oslTranslateFileError( GetLastError() );
1689cdf0e10cSrcweir 
1690cdf0e10cSrcweir 		uFieldMask &= ~	osl_FileStatus_Mask_Validate;
1691cdf0e10cSrcweir 	}
1692cdf0e10cSrcweir 
1693cdf0e10cSrcweir 	/* If no fields to retrieve left ignore pStatus */
1694cdf0e10cSrcweir 	if ( !uFieldMask )
1695cdf0e10cSrcweir 		return osl_File_E_None;
1696cdf0e10cSrcweir 
1697cdf0e10cSrcweir 	/* Otherwise, this must be a valid pointer */
1698cdf0e10cSrcweir 	if ( !pStatus )
1699cdf0e10cSrcweir 		return osl_File_E_INVAL;
1700cdf0e10cSrcweir 
1701cdf0e10cSrcweir 	if ( pStatus->uStructSize != sizeof(oslFileStatus) )
1702cdf0e10cSrcweir 		return osl_File_E_INVAL;
1703cdf0e10cSrcweir 
1704cdf0e10cSrcweir 	pStatus->uValidFields = 0;
1705cdf0e10cSrcweir 
1706cdf0e10cSrcweir 	/* File time stamps */
1707cdf0e10cSrcweir 
1708cdf0e10cSrcweir 	if ( (uFieldMask & osl_FileStatus_Mask_ModifyTime) &&
1709cdf0e10cSrcweir 		FileTimeToTimeValue( &pItemImpl->FindData.ftLastWriteTime, &pStatus->aModifyTime ) )
1710cdf0e10cSrcweir 		pStatus->uValidFields |= osl_FileStatus_Mask_ModifyTime;
1711cdf0e10cSrcweir 
1712cdf0e10cSrcweir 	if ( (uFieldMask & osl_FileStatus_Mask_AccessTime) &&
1713cdf0e10cSrcweir 		FileTimeToTimeValue( &pItemImpl->FindData.ftLastAccessTime, &pStatus->aAccessTime ) )
1714cdf0e10cSrcweir 		pStatus->uValidFields |= osl_FileStatus_Mask_AccessTime;
1715cdf0e10cSrcweir 
1716cdf0e10cSrcweir 	if ( (uFieldMask & osl_FileStatus_Mask_CreationTime) &&
1717cdf0e10cSrcweir 		FileTimeToTimeValue( &pItemImpl->FindData.ftCreationTime, &pStatus->aCreationTime ) )
1718cdf0e10cSrcweir 		pStatus->uValidFields |= osl_FileStatus_Mask_CreationTime;
1719cdf0e10cSrcweir 
1720cdf0e10cSrcweir 	/* Most of the fields are already set, regardless of requiered fields */
1721cdf0e10cSrcweir 
1722cdf0e10cSrcweir 	rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(pItemImpl->FindData.cFileName) );
1723cdf0e10cSrcweir 	pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
1724cdf0e10cSrcweir 
1725cdf0e10cSrcweir     if ((FILE_ATTRIBUTE_REPARSE_POINT & pItemImpl->FindData.dwFileAttributes) &&
1726cdf0e10cSrcweir         (IO_REPARSE_TAG_MOUNT_POINT == pItemImpl->FindData.dwReserved0))
1727cdf0e10cSrcweir         pStatus->eType = osl_File_Type_Volume;
1728cdf0e10cSrcweir     else if (pItemImpl->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1729cdf0e10cSrcweir         pStatus->eType = osl_File_Type_Directory;
1730cdf0e10cSrcweir     else
1731cdf0e10cSrcweir 	    pStatus->eType = osl_File_Type_Regular;
1732cdf0e10cSrcweir 
1733cdf0e10cSrcweir 	pStatus->uValidFields |= osl_FileStatus_Mask_Type;
1734cdf0e10cSrcweir 
1735cdf0e10cSrcweir 	pStatus->uAttributes = pItemImpl->FindData.dwFileAttributes;
1736cdf0e10cSrcweir 	pStatus->uValidFields |= osl_FileStatus_Mask_Attributes;
1737cdf0e10cSrcweir 
1738cdf0e10cSrcweir 	pStatus->uFileSize = (sal_uInt64)pItemImpl->FindData.nFileSizeLow + ((sal_uInt64)pItemImpl->FindData.nFileSizeHigh << 32);
1739cdf0e10cSrcweir 	pStatus->uValidFields |= osl_FileStatus_Mask_FileSize;
1740cdf0e10cSrcweir 
1741cdf0e10cSrcweir 	if ( uFieldMask & osl_FileStatus_Mask_LinkTargetURL )
1742cdf0e10cSrcweir 	{
1743cdf0e10cSrcweir 		osl_getFileURLFromSystemPath( pItemImpl->m_pFullPath, &pStatus->ustrLinkTargetURL );
1744cdf0e10cSrcweir 
1745cdf0e10cSrcweir 		pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL;
1746cdf0e10cSrcweir 	}
1747cdf0e10cSrcweir 
1748cdf0e10cSrcweir 	if ( uFieldMask & osl_FileStatus_Mask_FileURL )
1749cdf0e10cSrcweir 	{
1750cdf0e10cSrcweir 		if ( !pItemImpl->bFullPathNormalized )
1751cdf0e10cSrcweir 		{
1752cdf0e10cSrcweir             sal_uInt32 nLen = rtl_uString_getLength( pItemImpl->m_pFullPath );
1753cdf0e10cSrcweir             ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
1754cdf0e10cSrcweir             sal_uInt32 nNewLen = GetCaseCorrectPathName( reinterpret_cast<LPCTSTR>( rtl_uString_getStr( pItemImpl->m_pFullPath ) ),
1755cdf0e10cSrcweir                                                       ::osl::mingw_reinterpret_cast<LPTSTR>( aBuffer ),
1756cdf0e10cSrcweir                                                       aBuffer.getBufSizeInSymbols(),
1757cdf0e10cSrcweir                                                       sal_True );
1758cdf0e10cSrcweir 
1759cdf0e10cSrcweir             if ( nNewLen )
1760cdf0e10cSrcweir             {
1761cdf0e10cSrcweir                 rtl_uString_newFromStr( &pItemImpl->m_pFullPath, aBuffer );
1762cdf0e10cSrcweir                 pItemImpl->bFullPathNormalized = TRUE;
1763cdf0e10cSrcweir             }
1764cdf0e10cSrcweir 		}
1765cdf0e10cSrcweir 
1766cdf0e10cSrcweir 		osl_getFileURLFromSystemPath( pItemImpl->m_pFullPath, &pStatus->ustrFileURL );
1767cdf0e10cSrcweir 		pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
1768cdf0e10cSrcweir 	}
1769cdf0e10cSrcweir 
1770cdf0e10cSrcweir 	return osl_File_E_None;
1771cdf0e10cSrcweir }
1772cdf0e10cSrcweir 
1773cdf0e10cSrcweir //#####################################################
1774cdf0e10cSrcweir // file attributes handling functions
1775cdf0e10cSrcweir //#####################################################
1776cdf0e10cSrcweir 
1777cdf0e10cSrcweir //#############################################
osl_setFileAttributes(rtl_uString * ustrFileURL,sal_uInt64 uAttributes)1778cdf0e10cSrcweir oslFileError SAL_CALL osl_setFileAttributes(
1779cdf0e10cSrcweir     rtl_uString *ustrFileURL,
1780cdf0e10cSrcweir     sal_uInt64 uAttributes )
1781cdf0e10cSrcweir {
1782cdf0e10cSrcweir 	oslFileError	error;
1783cdf0e10cSrcweir 	rtl_uString		*ustrSysPath = NULL;
1784cdf0e10cSrcweir 	DWORD			dwFileAttributes;
1785cdf0e10cSrcweir 	BOOL			fSuccess;
1786cdf0e10cSrcweir 
1787cdf0e10cSrcweir 	// Converts the normalized path into a systempath
1788cdf0e10cSrcweir 	error = _osl_getSystemPathFromFileURL( ustrFileURL, &ustrSysPath, sal_False );
1789cdf0e10cSrcweir 
1790cdf0e10cSrcweir 	if ( osl_File_E_None != error )
1791cdf0e10cSrcweir 		return error;
1792cdf0e10cSrcweir 
1793cdf0e10cSrcweir 	dwFileAttributes = GetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)) );
1794cdf0e10cSrcweir 
1795cdf0e10cSrcweir 	if ( (DWORD)-1 != dwFileAttributes )
1796cdf0e10cSrcweir 	{
1797cdf0e10cSrcweir 		dwFileAttributes &= ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN);
1798cdf0e10cSrcweir 
1799cdf0e10cSrcweir 		if ( uAttributes & osl_File_Attribute_ReadOnly )
1800cdf0e10cSrcweir 			dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
1801cdf0e10cSrcweir 
1802cdf0e10cSrcweir 		if ( uAttributes & osl_File_Attribute_Hidden )
1803cdf0e10cSrcweir 			dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1804cdf0e10cSrcweir 
1805cdf0e10cSrcweir 		fSuccess = SetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)), dwFileAttributes );
1806cdf0e10cSrcweir 	}
1807cdf0e10cSrcweir 	else
1808cdf0e10cSrcweir 		fSuccess = FALSE;
1809cdf0e10cSrcweir 
1810cdf0e10cSrcweir 	if ( !fSuccess )
1811cdf0e10cSrcweir 		error = oslTranslateFileError( GetLastError() );
1812cdf0e10cSrcweir 
1813cdf0e10cSrcweir 	rtl_uString_release( ustrSysPath );
1814cdf0e10cSrcweir 
1815cdf0e10cSrcweir 	return error;
1816cdf0e10cSrcweir }
1817cdf0e10cSrcweir 
1818cdf0e10cSrcweir //#####################################################
osl_setFileTime(rtl_uString * filePath,const TimeValue * aCreationTime,const TimeValue * aLastAccessTime,const TimeValue * aLastWriteTime)1819cdf0e10cSrcweir oslFileError SAL_CALL osl_setFileTime(
1820cdf0e10cSrcweir     rtl_uString *filePath,
1821cdf0e10cSrcweir     const TimeValue *aCreationTime,
1822cdf0e10cSrcweir     const TimeValue *aLastAccessTime,
1823cdf0e10cSrcweir     const TimeValue *aLastWriteTime)
1824cdf0e10cSrcweir {
1825cdf0e10cSrcweir 	oslFileError error;
1826cdf0e10cSrcweir 	rtl_uString *sysPath=NULL;
1827cdf0e10cSrcweir 	FILETIME *lpCreationTime=NULL;
1828cdf0e10cSrcweir 	FILETIME *lpLastAccessTime=NULL;
1829cdf0e10cSrcweir 	FILETIME *lpLastWriteTime=NULL;
1830cdf0e10cSrcweir 	FILETIME ftCreationTime;
1831cdf0e10cSrcweir 	FILETIME ftLastAccessTime;
1832cdf0e10cSrcweir 	FILETIME ftLastWriteTime;
1833cdf0e10cSrcweir 	HANDLE hFile;
1834cdf0e10cSrcweir 	BOOL fSuccess;
1835cdf0e10cSrcweir 
1836cdf0e10cSrcweir 
1837cdf0e10cSrcweir 	error=_osl_getSystemPathFromFileURL(filePath, &sysPath, sal_False);
1838cdf0e10cSrcweir 
1839cdf0e10cSrcweir 	if (error==osl_File_E_INVAL)
1840cdf0e10cSrcweir 		return error;
1841cdf0e10cSrcweir 
1842cdf0e10cSrcweir 	hFile=CreateFileW(reinterpret_cast<LPCWSTR>(rtl_uString_getStr(sysPath)), GENERIC_WRITE, 0, NULL , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1843cdf0e10cSrcweir 	rtl_uString_release(sysPath);
1844cdf0e10cSrcweir 
1845cdf0e10cSrcweir 	if (hFile==INVALID_HANDLE_VALUE)
1846cdf0e10cSrcweir 		return osl_File_E_NOENT;
1847cdf0e10cSrcweir 
1848cdf0e10cSrcweir 	if (TimeValueToFileTime(aCreationTime, &ftCreationTime))
1849cdf0e10cSrcweir 		lpCreationTime=&ftCreationTime;
1850cdf0e10cSrcweir 
1851cdf0e10cSrcweir 	if (TimeValueToFileTime(aLastAccessTime, &ftLastAccessTime))
1852cdf0e10cSrcweir 		lpLastAccessTime=&ftLastAccessTime;
1853cdf0e10cSrcweir 
1854cdf0e10cSrcweir 	if (TimeValueToFileTime(aLastWriteTime, &ftLastWriteTime))
1855cdf0e10cSrcweir 		lpLastWriteTime=&ftLastWriteTime;
1856cdf0e10cSrcweir 
1857cdf0e10cSrcweir 	fSuccess=SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
1858cdf0e10cSrcweir 
1859cdf0e10cSrcweir 	CloseHandle(hFile);
1860cdf0e10cSrcweir 
1861cdf0e10cSrcweir 	if (!fSuccess)
1862cdf0e10cSrcweir 		return osl_File_E_INVAL;
1863cdf0e10cSrcweir 	else
1864cdf0e10cSrcweir 		return osl_File_E_None;
1865cdf0e10cSrcweir }
1866