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