/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#define UNICODE
#define _UNICODE
#define _WIN32_WINNT_0x0500
#include "systools/win32/uwinapi.h"

#include "osl/file.h"

#include "file_url.h"
#include "file_error.h"

#include "path_helper.hxx"

#include "osl/diagnose.h"
#include "osl/time.h"
#include "rtl/alloc.h"
#include "rtl/ustring.hxx"

#include <tchar.h>
#ifdef __MINGW32__
#include <ctype.h>
#endif 

//#####################################################
#define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0])))

static const wchar_t UNC_PREFIX[] = L"\\\\";
static const wchar_t BACKSLASH = '\\';
static const wchar_t SLASH = '/';

//#####################################################
extern "C" BOOL TimeValueToFileTime(const TimeValue *cpTimeVal, FILETIME *pFTime)
{
	SYSTEMTIME	BaseSysTime;
	FILETIME	BaseFileTime;
	FILETIME	FTime;
	__int64		localTime;
	BOOL		fSuccess = FALSE;

	BaseSysTime.wYear         = 1970;
	BaseSysTime.wMonth        = 1;
    BaseSysTime.wDayOfWeek    = 0;
    BaseSysTime.wDay          = 1;
    BaseSysTime.wHour         = 0;
    BaseSysTime.wMinute       = 0;
    BaseSysTime.wSecond       = 0;
    BaseSysTime.wMilliseconds = 0;

	if (cpTimeVal==NULL)
		return fSuccess;

	if ( SystemTimeToFileTime(&BaseSysTime, &BaseFileTime) )
	{
		__int64 timeValue;
		localTime=cpTimeVal->Seconds*(__int64)10000000+cpTimeVal->Nanosec/100;
		*(__int64 *)&FTime=localTime;
		fSuccess = 0 <= (timeValue= *((__int64 *)&BaseFileTime) + *((__int64 *) &FTime));
		if (fSuccess)
			*(__int64 *)pFTime=timeValue;
	}
	return fSuccess;
}

//#####################################################
extern "C" BOOL FileTimeToTimeValue(const FILETIME *cpFTime, TimeValue *pTimeVal)
{
	SYSTEMTIME	BaseSysTime;
	FILETIME	BaseFileTime;
	BOOL		fSuccess = FALSE;	/* Assume failure */

	BaseSysTime.wYear         = 1970;
	BaseSysTime.wMonth        = 1;
    BaseSysTime.wDayOfWeek    = 0;
    BaseSysTime.wDay          = 1;
    BaseSysTime.wHour         = 0;
    BaseSysTime.wMinute       = 0;
    BaseSysTime.wSecond       = 0;
    BaseSysTime.wMilliseconds = 0;

	if ( SystemTimeToFileTime(&BaseSysTime, &BaseFileTime) )
	{
		__int64		Value;

		fSuccess = 0 <= (Value = *((__int64 *)cpFTime) - *((__int64 *)&BaseFileTime));

		if ( fSuccess )
		{
			pTimeVal->Seconds  = (unsigned long) (Value / 10000000L);
			pTimeVal->Nanosec  = (unsigned long)((Value % 10000000L) * 100);
		}
	}
	return fSuccess;
}

//#####################################################
namespace /* private */
{       
    //#####################################################
	struct Component
    {       
        Component() : 
            begin_(0), end_(0)
        {}

        bool isPresent() const
        { return (static_cast<sal_IntPtr>(end_ - begin_) > 0); }        
        
        const sal_Unicode* begin_;
        const sal_Unicode* end_;
    };
                    
    //#####################################################
    struct UNCComponents
    {                        
        Component server_;
        Component share_;
        Component resource_;
    };
    
    //#####################################################
    inline bool is_UNC_path(const sal_Unicode* path)
    { return (0 == wcsncmp(UNC_PREFIX, reinterpret_cast<LPCWSTR>(path), ELEMENTS_OF_ARRAY(UNC_PREFIX) - 1)); }   
    
    //#####################################################
    inline bool is_UNC_path(const rtl::OUString& path)
    { return is_UNC_path(path.getStr()); }
    
    //#####################################################
    void parse_UNC_path(const sal_Unicode* path, UNCComponents* puncc)
    {                
        OSL_PRECOND(is_UNC_path(path), "Precondition violated: No UNC path");
        OSL_PRECOND(rtl_ustr_indexOfChar(path, SLASH) == -1, "Path must not contain slashes");
                        
        const sal_Unicode* pend = path + rtl_ustr_getLength(path);
        const sal_Unicode* ppos = path + 2;
                
        puncc->server_.begin_ = ppos;                                    
        while ((ppos < pend) && (*ppos != BACKSLASH))
            ppos++;
        
        puncc->server_.end_ = ppos;
        
        if (BACKSLASH == *ppos)    
        {                                                
            puncc->share_.begin_ = ++ppos;                                
            while ((ppos < pend) && (*ppos != BACKSLASH))
                ppos++;
                
            puncc->share_.end_ = ppos;
                                        
            if (BACKSLASH == *ppos)
            {                                                                                                                                                                               
                puncc->resource_.begin_ = ++ppos;                                                        
                while (ppos < pend)
                    ppos++;
                
                puncc->resource_.end_ = ppos;
            }                                 
        }     
        
        OSL_POSTCOND(puncc->server_.isPresent() && puncc->share_.isPresent(), \
        "Postcondition violated: Invalid UNC path detected");   
    }
    
    //#####################################################
    void parse_UNC_path(const rtl::OUString& path, UNCComponents* puncc)
    { parse_UNC_path(path.getStr(), puncc); }
    
                                   
    //#####################################################
    bool has_path_parent(const sal_Unicode* path)
    {                
		// Has the given path a parent or are we already there, 
		// e.g. 'c:\' or '\\server\share\'?

        bool has_parent = false;
        if (is_UNC_path(path))
        {
            UNCComponents unc_comp;
            parse_UNC_path(path, &unc_comp);                        
            has_parent = unc_comp.resource_.isPresent();
        }
        else 
        {
            has_parent = !osl::systemPathIsLogicalDrivePattern(path);
        }
        return has_parent;
    }
    
    //#####################################################
    inline bool has_path_parent(const rtl::OUString& path)
    { return has_path_parent(path.getStr()); }
    
} // end namespace private 

//#####################################################
// volume handling functions
//#####################################################

//#####################################################
oslFileError SAL_CALL osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
{
	if ( Handle )
		return osl_File_E_None;
	else
		return osl_File_E_INVAL;
}

//#####################################################
oslFileError SAL_CALL osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
{
	if ( Handle )
		return osl_File_E_None;
	else
		return osl_File_E_INVAL;
}

//#####################################################
oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
{
	if ( Handle )
	{
		rtl_uString_acquire( (rtl_uString *)Handle );
		return osl_File_E_None;
	}
	else
		return osl_File_E_INVAL;
}

//#####################################################
oslFileError SAL_CALL osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
{
	if ( Handle )
	{
		rtl_uString_release( (rtl_uString *)Handle );
		return osl_File_E_None;
	}
	else
		return osl_File_E_INVAL;
}

//#####################################################
oslFileError SAL_CALL osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
{
	if ( Handle && pstrPath )
	{
		rtl_uString_assign( pstrPath, (rtl_uString *)Handle );
		return osl_File_E_None;
	}
	else
		return osl_File_E_INVAL;
}

//##################################################################
// directory handling functions
//##################################################################

#define DIRECTORYITEM_DRIVE		0
#define DIRECTORYITEM_FILE		1
#define DIRECTORYITEM_SERVER	2

struct DirectoryItem_Impl
{
	UINT uType;
	union {
		WIN32_FIND_DATA	FindData;
		TCHAR			cDriveString[MAX_PATH];
	};
    rtl_uString*    m_pFullPath;
	BOOL			bFullPathNormalized;
	int				nRefCount;
};

//#####################################################

#define	DIRECTORYTYPE_LOCALROOT	    0
#define	DIRECTORYTYPE_NETROOT		1
#define	DIRECTORYTYPE_NETRESORCE	2
#define	DIRECTORYTYPE_FILESYSTEM	3

struct Directory_Impl
{
	UINT uType;
	union {
		HANDLE	hDirectory;
		HANDLE	hEnumDrives;
	};
    rtl_uString*    m_pDirectoryPath;
};

//##################################################### 

typedef struct tagDRIVEENUM
{
	LPCTSTR	lpIdent;
	TCHAR	cBuffer[/*('Z' - 'A' + 1) * sizeof("A:\\") + 1*/256];
	LPCTSTR	lpCurrent;
} DRIVEENUM, * PDRIVEENUM, FAR * LPDRIVEENUM;

//##################################################### 

static HANDLE WINAPI OpenLogicalDrivesEnum(void)
{
	LPDRIVEENUM	pEnum = (LPDRIVEENUM)HeapAlloc( GetProcessHeap(), 0, sizeof(DRIVEENUM) );
	if ( pEnum )
	{
		DWORD dwNumCopied = GetLogicalDriveStrings( (sizeof(pEnum->cBuffer) - 1) / sizeof(TCHAR), pEnum->cBuffer );

		if ( dwNumCopied && dwNumCopied < sizeof(pEnum->cBuffer) / sizeof(TCHAR) )
		{
			pEnum->lpCurrent = pEnum->cBuffer;
			pEnum->lpIdent = L"tagDRIVEENUM";
		}
		else
		{
			HeapFree( GetProcessHeap(), 0, pEnum );
			pEnum = NULL;
		}
	}
	return pEnum ? (HANDLE)pEnum : INVALID_HANDLE_VALUE;
}

//##################################################### 
static BOOL WINAPI EnumLogicalDrives(HANDLE hEnum, LPTSTR lpBuffer)
{
	BOOL		fSuccess = FALSE;
	LPDRIVEENUM	pEnum = (LPDRIVEENUM)hEnum;

	if ( pEnum )
	{
		int	nLen = _tcslen( pEnum->lpCurrent );

		if ( nLen )
		{
			CopyMemory( lpBuffer, pEnum->lpCurrent, (nLen + 1) * sizeof(TCHAR) );
			pEnum->lpCurrent += nLen + 1;
			fSuccess = TRUE;
		}
		else
			SetLastError( ERROR_NO_MORE_FILES );
	}
	else
		SetLastError( ERROR_INVALID_HANDLE );

	return fSuccess;
}

//##################################################### 
static BOOL WINAPI CloseLogicalDrivesEnum(HANDLE hEnum)
{
	BOOL		fSuccess = FALSE;
	LPDRIVEENUM	pEnum = (LPDRIVEENUM)hEnum;

	if ( pEnum )
	{
		HeapFree( GetProcessHeap(), 0, pEnum );
		fSuccess = TRUE;
	}
	else
		SetLastError( ERROR_INVALID_HANDLE );

	return fSuccess;
}

//#####################################################
typedef struct tagDIRECTORY
{
	HANDLE          hFind;
	WIN32_FIND_DATA aFirstData;
} DIRECTORY, *PDIRECTORY, FAR *LPDIRECTORY;

//#####################################################
static HANDLE WINAPI OpenDirectory( rtl_uString* pPath)
{
	LPDIRECTORY	pDirectory = NULL;

	if ( pPath )
	{
        sal_uInt32 nLen = rtl_uString_getLength( pPath );
        if ( nLen )
        {
            TCHAR* pSuffix = 0;
            sal_uInt32 nSuffLen = 0;

            if ( pPath->buffer[nLen - 1] != L'\\' )
            {
                pSuffix = L"\\*.*";
                nSuffLen = 4;
            }
            else
            {
                pSuffix = L"*.*";
                nSuffLen = 3;
            }

            TCHAR* szFileMask = reinterpret_cast< TCHAR* >( rtl_allocateMemory( sizeof( TCHAR ) * ( nLen + nSuffLen + 1 ) ) );

		    _tcscpy( szFileMask, reinterpret_cast<LPCTSTR>( rtl_uString_getStr( pPath ) ) );
            _tcscat( szFileMask, pSuffix );

            pDirectory = (LPDIRECTORY)HeapAlloc(GetProcessHeap(), 0, sizeof(DIRECTORY));
            pDirectory->hFind = FindFirstFile(szFileMask, &pDirectory->aFirstData);

            if (!IsValidHandle(pDirectory->hFind))		
            {
                if ( GetLastError() != ERROR_NO_MORE_FILES )
                {
                    HeapFree(GetProcessHeap(), 0, pDirectory);
                    pDirectory = NULL;
                }
            }

            rtl_freeMemory(szFileMask);  // #119939#, memory leak
        }
	}

	return (HANDLE)pDirectory;
}

//#####################################################
BOOL WINAPI EnumDirectory(HANDLE hDirectory, LPWIN32_FIND_DATA pFindData)
{
	BOOL		fSuccess = FALSE;
	LPDIRECTORY	pDirectory = (LPDIRECTORY)hDirectory;

	if ( pDirectory )
	{
		BOOL	fValid;

		do
		{
			if ( pDirectory->aFirstData.cFileName[0] )
			{
				*pFindData = pDirectory->aFirstData;
				fSuccess = TRUE;
				pDirectory->aFirstData.cFileName[0] = 0;
			}
			else if ( IsValidHandle( pDirectory->hFind ) )
				fSuccess = FindNextFile( pDirectory->hFind, pFindData );
			else
			{
				fSuccess = FALSE;
				SetLastError( ERROR_NO_MORE_FILES );
			}

			fValid = fSuccess && _tcscmp( TEXT("."), pFindData->cFileName ) != 0 && _tcscmp( TEXT(".."), pFindData->cFileName ) != 0;

		} while( fSuccess && !fValid );
	}
	else
		SetLastError( ERROR_INVALID_HANDLE );

	return fSuccess;
}

//#####################################################
static BOOL WINAPI CloseDirectory(HANDLE hDirectory)
{
	BOOL		fSuccess = FALSE;
	LPDIRECTORY	pDirectory = (LPDIRECTORY)hDirectory;

	if (pDirectory)
	{
		if (IsValidHandle(pDirectory->hFind))
			fSuccess = FindClose(pDirectory->hFind);

		fSuccess = HeapFree(GetProcessHeap(), 0, pDirectory) && fSuccess;
	}
	else
		SetLastError(ERROR_INVALID_HANDLE);

	return fSuccess;
}

//#####################################################
static oslFileError osl_openLocalRoot(
    rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
{
    rtl_uString		*strSysPath = NULL;
    oslFileError	error;
	    
    if ( !pDirectory )
        return osl_File_E_INVAL;

    *pDirectory = NULL;

    error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysPath, sal_False );
    if ( osl_File_E_None == error )
    {
        Directory_Impl	*pDirImpl;

        pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory( sizeof(Directory_Impl)));
        ZeroMemory( pDirImpl, sizeof(Directory_Impl) );
        rtl_uString_newFromString( &pDirImpl->m_pDirectoryPath, strSysPath );

        /* Append backslash if necessary */

        /* @@@ToDo
           use function ensure backslash
        */
        sal_uInt32 nLen = rtl_uString_getLength( pDirImpl->m_pDirectoryPath );
        if ( nLen && pDirImpl->m_pDirectoryPath->buffer[nLen - 1] != L'\\' )
        {
            rtl_uString* pCurDir = 0;
            rtl_uString* pBackSlash = 0;

            rtl_uString_assign( &pCurDir, pDirImpl->m_pDirectoryPath );
            rtl_uString_newFromAscii( &pBackSlash, "\\" );
            rtl_uString_newConcat( &pDirImpl->m_pDirectoryPath, pCurDir, pBackSlash );
            rtl_uString_release( pBackSlash );
            rtl_uString_release( pCurDir );
        }

        pDirImpl->uType = DIRECTORYTYPE_LOCALROOT;
        pDirImpl->hEnumDrives = OpenLogicalDrivesEnum();

        /* @@@ToDo
           Use IsValidHandle(...)
        */
        if ( pDirImpl->hEnumDrives != INVALID_HANDLE_VALUE )
        {
            *pDirectory = (oslDirectory)pDirImpl;
            error = osl_File_E_None;
        }
        else
        {
            if ( pDirImpl )
            {
                if ( pDirImpl->m_pDirectoryPath )
                {
                    rtl_uString_release( pDirImpl->m_pDirectoryPath );
                    pDirImpl->m_pDirectoryPath = 0;
                }

                rtl_freeMemory(pDirImpl);
                pDirImpl = 0;
            }

            error = oslTranslateFileError( GetLastError() );
        }

        rtl_uString_release( strSysPath );
    }
    return error;
}

//#####################################################
static oslFileError SAL_CALL osl_openFileDirectory(
	rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
{
	oslFileError error = osl_File_E_None;
	    
	if ( !pDirectory )
		return osl_File_E_INVAL;
	*pDirectory = NULL;

	Directory_Impl *pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl)));
    ZeroMemory( pDirImpl, sizeof(Directory_Impl) );
    rtl_uString_newFromString( &pDirImpl->m_pDirectoryPath, strDirectoryPath );

	/* Append backslash if necessary */

	/* @@@ToDo
	   use function ensure backslash
	*/
    sal_uInt32 nLen = rtl_uString_getLength( pDirImpl->m_pDirectoryPath );
    if ( nLen && pDirImpl->m_pDirectoryPath->buffer[nLen - 1] != L'\\' )
    {
        rtl_uString* pCurDir = 0;
        rtl_uString* pBackSlash = 0;

        rtl_uString_assign( &pCurDir, pDirImpl->m_pDirectoryPath );
        rtl_uString_newFromAscii( &pBackSlash, "\\" );
        rtl_uString_newConcat( &pDirImpl->m_pDirectoryPath, pCurDir, pBackSlash );
        rtl_uString_release( pBackSlash );
        rtl_uString_release( pCurDir );
    }


	pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM;
	pDirImpl->hDirectory = OpenDirectory( pDirImpl->m_pDirectoryPath );

	if ( !pDirImpl->hDirectory )
	{
		error = oslTranslateFileError( GetLastError() );

        if ( pDirImpl->m_pDirectoryPath )
        {
            rtl_uString_release( pDirImpl->m_pDirectoryPath );
            pDirImpl->m_pDirectoryPath = 0;
        }

		rtl_freeMemory(pDirImpl), pDirImpl = 0;
	}

	*pDirectory = (oslDirectory)(pDirImpl);
	return error;
}

//#####################################################
static oslFileError SAL_CALL osl_openNetworkServer(
	rtl_uString *strSysDirPath, oslDirectory *pDirectory)
{
	NETRESOURCEW	aNetResource;
	HANDLE			hEnum;
	DWORD			dwError;

	ZeroMemory( &aNetResource, sizeof(aNetResource) );

	aNetResource.lpRemoteName = reinterpret_cast<LPWSTR>(strSysDirPath->buffer);

	dwError = WNetOpenEnumW( 
		RESOURCE_GLOBALNET, 
		RESOURCETYPE_DISK, 
		RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER, 
		&aNetResource, 
		&hEnum );

	if ( ERROR_SUCCESS == dwError )
	{
		Directory_Impl	*pDirImpl;

		pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl)));
        ZeroMemory( pDirImpl, sizeof(Directory_Impl) );
		pDirImpl->uType = DIRECTORYTYPE_NETROOT;
		pDirImpl->hDirectory = hEnum;	
		*pDirectory = (oslDirectory)pDirImpl;
	}
	return oslTranslateFileError( dwError );
}

//#############################################
static DWORD create_dir_with_callback(
    rtl_uString * dir_path,
    oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc, 
    void* pData)
{
	// Create the specified directory and call the 
	// user specified callback function. On success
	// the function returns ERROR_SUCCESS else a Win32 error code.

    BOOL bCreated = FALSE;

    bCreated = CreateDirectoryW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( dir_path )), NULL );

    if ( bCreated )
    {
        if (aDirectoryCreationCallbackFunc)
        {
            rtl::OUString url;
            _osl_getFileURLFromSystemPath(dir_path, &(url.pData));
            aDirectoryCreationCallbackFunc(pData, url.pData);
        }
        return ERROR_SUCCESS;
    }
    return GetLastError();
}

//#############################################
static int path_make_parent(sal_Unicode* path)
{    
    /*  Cut off the last part of the given path to 
    get the parent only, e.g. 'c:\dir\subdir' -> 
    'c:\dir' or '\\share\sub\dir' -> '\\share\sub'
    @return The position where the path has been cut 
    off (this is the posistion of the last backslash).
    If there are no more parents 0 will be returned, 
    e.g. 'c:\' or '\\Share' have no more parents */        

	OSL_PRECOND(rtl_ustr_indexOfChar(path, SLASH) == -1, "Path must not contain slashes");
	OSL_PRECOND(has_path_parent(path), "Path must have a parent");                
                    
	sal_Unicode* pos_last_backslash = path + rtl_ustr_lastIndexOfChar(path, BACKSLASH);
	*pos_last_backslash = 0; 
	return (pos_last_backslash - path);        
}
    
//#############################################
static DWORD create_dir_recursively_(
    rtl_uString * dir_path,
    oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc, 
    void* pData)
{
    OSL_PRECOND(
		rtl_ustr_lastIndexOfChar_WithLength(dir_path->buffer, dir_path->length, BACKSLASH) != dir_path->length,
		"Path must not end with a backslash");
        
    DWORD w32_error = create_dir_with_callback(
        dir_path, aDirectoryCreationCallbackFunc, pData);
    if (w32_error == ERROR_SUCCESS)
        return ERROR_SUCCESS;   
                                
    if ((w32_error != ERROR_PATH_NOT_FOUND) || !has_path_parent(dir_path->buffer))
        return w32_error;

    int pos = path_make_parent(dir_path->buffer); // dir_path->buffer[pos] = 0, restore below
                            
    w32_error = create_dir_recursively_(
        dir_path, aDirectoryCreationCallbackFunc, pData);

    dir_path->buffer[pos] = BACKSLASH; // restore

    if (ERROR_SUCCESS != w32_error)
        return w32_error;

    return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
}

//#############################################
oslFileError SAL_CALL osl_createDirectoryPath(
    rtl_uString* aDirectoryUrl, 
    oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc, 
    void* pData)
{   
    if (aDirectoryUrl == NULL)
        return osl_File_E_INVAL;
        
    rtl::OUString sys_path;         
    oslFileError osl_error = 
        _osl_getSystemPathFromFileURL(aDirectoryUrl, &sys_path.pData, sal_False);        
    
    if (osl_error != osl_File_E_None)
        return osl_error;
                                                                
    osl::systemPathRemoveSeparator(sys_path);
    
    // const_cast because sys_path is a local copy
    // which we want to modify inplace instead of 
    // coyp it into another buffer on the heap again
    return oslTranslateFileError(create_dir_recursively_(
        sys_path.pData, aDirectoryCreationCallbackFunc, pData));                     
}

//#####################################################
oslFileError SAL_CALL osl_createDirectory(rtl_uString* strPath)
{
	rtl_uString	*strSysPath = NULL;
	oslFileError	error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );

	if ( osl_File_E_None == error )
	{
        BOOL bCreated = FALSE;

        bCreated = CreateDirectoryW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )), NULL );
		
        if ( !bCreated )
		{
            /*@@@ToDo
              The following case is a hack because the ucb or the webtop had some 
              problems with the error code that CreateDirectory returns in
              case the path is only a logical drive, should be removed!
            */			

			const sal_Unicode	*pBuffer = rtl_uString_getStr( strSysPath );
			sal_Int32			nLen = rtl_uString_getLength( strSysPath );

			if (
				( ( pBuffer[0] >= 'A' && pBuffer[0] <= 'Z' ) ||
				  ( pBuffer[0] >= 'a' && pBuffer[0] <= 'z' ) ) &&
				pBuffer[1] == ':' && ( nLen ==2 || ( nLen == 3 && pBuffer[2] == '\\' ) )
				)
				SetLastError( ERROR_ALREADY_EXISTS );

			error = oslTranslateFileError( GetLastError() );
		}

		rtl_uString_release( strSysPath );
	}
	return error;
}

//#####################################################
oslFileError SAL_CALL osl_removeDirectory(rtl_uString* strPath)
{
	rtl_uString	*strSysPath = NULL;
	oslFileError	error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False );

	if ( osl_File_E_None == error )
	{
		if ( RemoveDirectory( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )) ) )
			error = osl_File_E_None;
		else
			error = oslTranslateFileError( GetLastError() );

		rtl_uString_release( strSysPath );
	}
	return error;
}

//#####################################################
oslFileError SAL_CALL osl_openDirectory(rtl_uString *strDirectoryPath, oslDirectory *pDirectory)
{
	oslFileError	error;			

	if ( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase( strDirectoryPath->buffer, "file:///" ) )
		error = osl_openLocalRoot( strDirectoryPath, pDirectory );
	else
	{
		rtl_uString	*strSysDirectoryPath = NULL;
		DWORD		dwPathType;

		error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysDirectoryPath, sal_False );

		if ( osl_File_E_None != error )
				return error;

		dwPathType = IsValidFilePath( strSysDirectoryPath, NULL, VALIDATEPATH_NORMAL, NULL );

		if ( dwPathType & PATHTYPE_IS_SERVER )
		{
			error = osl_openNetworkServer( strSysDirectoryPath, pDirectory );
		}
		else
			error = osl_openFileDirectory( strSysDirectoryPath, pDirectory );

		rtl_uString_release( strSysDirectoryPath );
	}
	return error;
}

//#####################################################
static oslFileError SAL_CALL osl_getNextNetResource( 
	oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
{
	Directory_Impl		*pDirImpl = (Directory_Impl *)Directory;
	DirectoryItem_Impl	*pItemImpl = NULL;
	BYTE				buffer[16384];
	LPNETRESOURCEW		lpNetResource = (LPNETRESOURCEW)buffer;
	DWORD				dwError, dwCount, dwBufSize;

	uHint = uHint; /* to get no warning */        	    

	if ( !pItem )
		return osl_File_E_INVAL;
	*pItem = NULL;

	if ( !pDirImpl )
		return osl_File_E_INVAL;

	dwCount = 1;
	dwBufSize = sizeof(buffer);
	dwError = WNetEnumResource( pDirImpl->hDirectory, &dwCount, lpNetResource, &dwBufSize );

	switch ( dwError )
	{
	    case NO_ERROR:
	    case ERROR_MORE_DATA:
		{
			pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
			if ( !pItemImpl )
				return osl_File_E_NOMEM;

			ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
			pItemImpl->uType = DIRECTORYITEM_DRIVE;
			osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );

			wcscpy( pItemImpl->cDriveString, lpNetResource->lpRemoteName );

			*pItem = pItemImpl;
		}
		return osl_File_E_None;
	    case ERROR_NO_MORE_ITEMS:
		    return osl_File_E_NOENT;
	    default:
		    return oslTranslateFileError( dwError );
	}
}

//##################################################### 
static oslFileError SAL_CALL osl_getNextDrive( 
	oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint )
{
	Directory_Impl		*pDirImpl = (Directory_Impl *)Directory;
	DirectoryItem_Impl	*pItemImpl = NULL;
	BOOL				fSuccess;

	uHint = uHint; /* avoid warnings */
        	    
	if ( !pItem )
		return osl_File_E_INVAL;
	*pItem = NULL;

	if ( !pDirImpl )
		return osl_File_E_INVAL;

	pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
	if ( !pItemImpl )
		return osl_File_E_NOMEM;

	ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
	pItemImpl->uType = DIRECTORYITEM_DRIVE;
	osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
	fSuccess = EnumLogicalDrives( pDirImpl->hEnumDrives, pItemImpl->cDriveString );

	if ( fSuccess )
	{
		*pItem = pItemImpl;
		return osl_File_E_None;
	}
	else
	{
        if ( pItemImpl->m_pFullPath )
        {
            rtl_uString_release( pItemImpl->m_pFullPath );
            pItemImpl->m_pFullPath = 0;
        }

		rtl_freeMemory( pItemImpl );
		return oslTranslateFileError( GetLastError() );
	}
}

//##################################################### 
static oslFileError SAL_CALL osl_getNextFileItem( 
	oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint)
{
	Directory_Impl		*pDirImpl = (Directory_Impl *)Directory;
	DirectoryItem_Impl	*pItemImpl = NULL;
	BOOL				fFound;

	uHint = uHint; /* avoid warnings */
        	    
	if ( !pItem )
		return osl_File_E_INVAL;
	*pItem = NULL;

	if ( !pDirImpl )
		return osl_File_E_INVAL;

	pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));
	if ( !pItemImpl )
		return osl_File_E_NOMEM;

	memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) );
	fFound = EnumDirectory( pDirImpl->hDirectory, &pItemImpl->FindData );

	if ( fFound )
	{
		pItemImpl->uType = DIRECTORYITEM_FILE;
		pItemImpl->nRefCount = 1;

        rtl_uString* pTmpFileName = 0;
        rtl_uString_newFromStr( &pTmpFileName,  reinterpret_cast<const sal_Unicode *>(pItemImpl->FindData.cFileName) );
        rtl_uString_newConcat( &pItemImpl->m_pFullPath, pDirImpl->m_pDirectoryPath, pTmpFileName );
        rtl_uString_release( pTmpFileName );

		pItemImpl->bFullPathNormalized = FALSE;
		*pItem = (oslDirectoryItem)pItemImpl;
		return osl_File_E_None;
	}
	else
	{
        if ( pItemImpl->m_pFullPath )
        {
            rtl_uString_release( pItemImpl->m_pFullPath );
            pItemImpl->m_pFullPath = 0;
        }

		rtl_freeMemory( pItemImpl );
		return oslTranslateFileError( GetLastError() );
	}
}

//##################################################### 
oslFileError SAL_CALL osl_getNextDirectoryItem(
	oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint)
{
	Directory_Impl		*pDirImpl = (Directory_Impl *)Directory;
	
	/* Assume failure */

	if ( !pItem )
		return osl_File_E_INVAL;
	*pItem = NULL;

	if ( !pDirImpl )
		return osl_File_E_INVAL;

	switch ( pDirImpl->uType )
	{
	case DIRECTORYTYPE_LOCALROOT:
		return osl_getNextDrive( Directory, pItem, uHint );
	case DIRECTORYTYPE_NETROOT:
		return osl_getNextNetResource( Directory, pItem, uHint );
	case DIRECTORYTYPE_FILESYSTEM:
		return osl_getNextFileItem( Directory, pItem, uHint );
	default:
		return osl_File_E_INVAL;
	}
}

//#####################################################
oslFileError SAL_CALL osl_closeDirectory(oslDirectory Directory)
{
	Directory_Impl	*pDirImpl = (Directory_Impl *)Directory;
	oslFileError	eError = osl_File_E_INVAL;

	if ( pDirImpl )
	{
		switch ( pDirImpl->uType )
		{
		case DIRECTORYTYPE_FILESYSTEM:
			eError = CloseDirectory( pDirImpl->hDirectory ) ? osl_File_E_None : oslTranslateFileError( GetLastError() );
			break;
		case DIRECTORYTYPE_LOCALROOT:
			eError = CloseLogicalDrivesEnum( pDirImpl->hEnumDrives ) ? osl_File_E_None : oslTranslateFileError( GetLastError() );
			break;
		case DIRECTORYTYPE_NETROOT:
		    {
		        DWORD err = WNetCloseEnum(pDirImpl->hDirectory);
			    eError = (err == NO_ERROR) ? osl_File_E_None : oslTranslateFileError(err);
			}
			break;
		default:
			OSL_ENSURE( 0, "Invalid directory type" );
			break;
		}

        if ( pDirImpl->m_pDirectoryPath )
        {
            rtl_uString_release( pDirImpl->m_pDirectoryPath );
            pDirImpl->m_pDirectoryPath = 0;
        }

		rtl_freeMemory(pDirImpl);
	}	
	return eError;
}

//#####################################################
/* Different types of paths */
typedef enum _PATHTYPE
{
	PATHTYPE_SYNTAXERROR = 0,
	PATHTYPE_NETROOT,
	PATHTYPE_NETSERVER,
	PATHTYPE_VOLUME,
	PATHTYPE_FILE
} PATHTYPE;

oslFileError SAL_CALL osl_getDirectoryItem(rtl_uString *strFilePath, oslDirectoryItem *pItem)
{
	oslFileError	error = osl_File_E_None;
	rtl_uString*	strSysFilePath = NULL;
	PATHTYPE		type = PATHTYPE_FILE;
	DWORD			dwPathType;

	/* Assume failure */

	if ( !pItem )
		return osl_File_E_INVAL;

	*pItem = NULL;


	error = _osl_getSystemPathFromFileURL( strFilePath, &strSysFilePath, sal_False );

	if ( osl_File_E_None != error )
			return error;

	dwPathType = IsValidFilePath( strSysFilePath, NULL, VALIDATEPATH_NORMAL, NULL );

	if ( dwPathType & PATHTYPE_IS_VOLUME )
		type = PATHTYPE_VOLUME;
	else if ( dwPathType & PATHTYPE_IS_SERVER )
		type = PATHTYPE_NETSERVER;
	else
		type = PATHTYPE_FILE;

	switch ( type )
	{
	case PATHTYPE_NETSERVER:
		{
			DirectoryItem_Impl*	pItemImpl = 
			    reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));

			if ( !pItemImpl )
				error = osl_File_E_NOMEM;

			if ( osl_File_E_None == error )
			{
				ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
				pItemImpl->uType = DIRECTORYITEM_SERVER;

				osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );
                rtl_uString_newFromString( &pItemImpl->m_pFullPath, strSysFilePath );

				// Assign a title anyway
				{
					int iSrc = 2;
					int	iDst = 0;

					while( iSrc < strSysFilePath->length && strSysFilePath->buffer[iSrc] && strSysFilePath->buffer[iSrc] != '\\' )
					{
						pItemImpl->FindData.cFileName[iDst++] = strSysFilePath->buffer[iSrc++];
					}
				}

				*pItem = pItemImpl;
			}
		}
		break;
	case PATHTYPE_VOLUME:
		{
			DirectoryItem_Impl*	pItemImpl = 
			    reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));

			if ( !pItemImpl )
				error = osl_File_E_NOMEM;

			if ( osl_File_E_None == error )
			{
				ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
				pItemImpl->uType = DIRECTORYITEM_DRIVE;

				osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );

				_tcscpy( pItemImpl->cDriveString, reinterpret_cast<LPCTSTR>(strSysFilePath->buffer) );
				pItemImpl->cDriveString[0] = _toupper( pItemImpl->cDriveString[0] );

				if ( pItemImpl->cDriveString[_tcslen(pItemImpl->cDriveString) - 1] != '\\' )
					_tcscat( pItemImpl->cDriveString, TEXT( "\\" ) );

				*pItem = pItemImpl;
			}
		}
		break;
    case PATHTYPE_SYNTAXERROR:
    case PATHTYPE_NETROOT:
	case PATHTYPE_FILE:
		{
			HANDLE				hFind;
			WIN32_FIND_DATA		aFindData;

			if ( strSysFilePath->length > 0 && strSysFilePath->buffer[strSysFilePath->length - 1] == '\\' )
				rtl_uString_newFromStr_WithLength( &strSysFilePath, strSysFilePath->buffer, strSysFilePath->length - 1 );

			hFind = FindFirstFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysFilePath)), &aFindData );

			if ( hFind != INVALID_HANDLE_VALUE )
			{
				DirectoryItem_Impl	*pItemImpl = 
				    reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl)));

				ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) );
				osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl );

				CopyMemory( &pItemImpl->FindData, &aFindData, sizeof(WIN32_FIND_DATA) );
                rtl_uString_newFromString( &pItemImpl->m_pFullPath, strSysFilePath );

				// MT: This costs 600ms startup time on fast v60x!
				// GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) );

				pItemImpl->uType = DIRECTORYITEM_FILE;
				*pItem = pItemImpl;
				FindClose( hFind );
			}
			else
				error = oslTranslateFileError( GetLastError() );
		}
		break;
	}

	if ( strSysFilePath )
		rtl_uString_release( strSysFilePath );

	return error;
}

//#####################################################
oslFileError SAL_CALL osl_acquireDirectoryItem( oslDirectoryItem Item )
{
	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;

	if ( !pItemImpl )
		return osl_File_E_INVAL;

	pItemImpl->nRefCount++;
	return osl_File_E_None;
}

//#####################################################
oslFileError SAL_CALL osl_releaseDirectoryItem( oslDirectoryItem Item )
{
	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;

	if ( !pItemImpl )
		return osl_File_E_INVAL;

	if ( ! --pItemImpl->nRefCount )
    {
        if ( pItemImpl->m_pFullPath )
        {
            rtl_uString_release( pItemImpl->m_pFullPath );
            pItemImpl->m_pFullPath = 0;
        }

		rtl_freeMemory( pItemImpl );
    }

	return osl_File_E_None;
}

//#####################################################
// volume / file info handling functions
//#####################################################

//#####################################################
static inline bool is_floppy_A_present()
{ return (GetLogicalDrives() & 1); }
    
//#####################################################
static inline bool is_floppy_B_present()
{ return (GetLogicalDrives() & 2); }
    
//#####################################################
bool is_floppy_volume_mount_point(const rtl::OUString& path)
{                   
    // determines if a volume mount point shows to a floppy
    // disk by comparing the unique volume names           
    static const LPCWSTR FLOPPY_A = L"A:\\";
    static const LPCWSTR FLOPPY_B = L"B:\\";

	rtl::OUString p(path);
	osl::systemPathEnsureSeparator(p);
        
	TCHAR vn[51];
	if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR>(p.getStr()), vn, ELEMENTS_OF_ARRAY(vn)))
	{       
		TCHAR vnfloppy[51];
		if (is_floppy_A_present() && 
			GetVolumeNameForVolumeMountPoint(FLOPPY_A, vnfloppy, ELEMENTS_OF_ARRAY(vnfloppy)) &&
			(0 == wcscmp(vn, vnfloppy)))
			return true;
                    
		if (is_floppy_B_present() &&
			GetVolumeNameForVolumeMountPoint(FLOPPY_B, vnfloppy, ELEMENTS_OF_ARRAY(vnfloppy)) &&
			(0 == wcscmp(vn, vnfloppy)))
			return true;
	}
	return false;
}
    
//################################################
static bool is_floppy_drive(const rtl::OUString& path)
{
	static const LPCWSTR FLOPPY_DRV_LETTERS = TEXT("AaBb"); 

    // we must take into account that even a floppy 
    // drive may be mounted to a directory so checking
    // for the drive letter alone is not sufficient
    // we must compare the unique volume name with 
    // that of the available floppy disks
 
	const sal_Unicode* pszPath = path.getStr();
	return ((wcschr(FLOPPY_DRV_LETTERS, pszPath[0]) && (L':' == pszPath[1])) || is_floppy_volume_mount_point(path));
}
    
//#####################################################
static bool is_volume_mount_point(const rtl::OUString& path)
{
	rtl::OUString p(path);        
	osl::systemPathRemoveSeparator(p);
            
	bool  is_volume_root = false;
        
	if (!is_floppy_drive(p))
	{
		DWORD fattr = GetFileAttributes(reinterpret_cast<LPCTSTR>(p.getStr()));
            
		if ((INVALID_FILE_ATTRIBUTES != fattr) && 
			(FILE_ATTRIBUTE_REPARSE_POINT & fattr))
		{
			WIN32_FIND_DATA find_data;
			HANDLE h_find = FindFirstFile(reinterpret_cast<LPCTSTR>(p.getStr()), &find_data);    
                           
			if (IsValidHandle(h_find) &&
				(FILE_ATTRIBUTE_REPARSE_POINT & find_data.dwFileAttributes) && 
				(IO_REPARSE_TAG_MOUNT_POINT == find_data.dwReserved0))
			{            
				is_volume_root = true;
			}        
			if (IsValidHandle(h_find))
				FindClose(h_find);
		}
	}
	return is_volume_root;
}

//#############################################
static UINT get_volume_mount_point_drive_type(const rtl::OUString& path)
{
	if (0 == path.getLength())
		return GetDriveType(NULL);
        
	rtl::OUString p(path);
	osl::systemPathEnsureSeparator(p);
        
	TCHAR vn[51];  
	if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR>(p.getStr()), vn, ELEMENTS_OF_ARRAY(vn)))
		return GetDriveType(vn);
        
	return DRIVE_NO_ROOT_DIR;  
}

//#############################################
static inline bool is_drivetype_request(sal_uInt32 field_mask)
{
	return (field_mask & osl_VolumeInfo_Mask_Attributes);
}

//#############################################
static oslFileError osl_get_drive_type(
	const rtl::OUString& path, oslVolumeInfo* pInfo)
{
	// GetDriveType fails on empty volume mount points
	// see Knowledge Base Q244089
	UINT drive_type;
	if (is_volume_mount_point(path))
		drive_type = get_volume_mount_point_drive_type(path);
	else
		drive_type = GetDriveType(reinterpret_cast<LPCTSTR>(path.getStr()));
    	
	if (DRIVE_NO_ROOT_DIR == drive_type)
		return oslTranslateFileError(ERROR_INVALID_DRIVE);
    		    
	pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;		

	switch (drive_type)
	{
		case DRIVE_CDROM:
			pInfo->uAttributes |= osl_Volume_Attribute_CompactDisc | osl_Volume_Attribute_Removeable;
			break;
		case DRIVE_REMOVABLE:
			pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
			if (is_floppy_drive(path))
				pInfo->uAttributes |= osl_Volume_Attribute_FloppyDisk;
			break;
		case DRIVE_FIXED:
			pInfo->uAttributes |= osl_Volume_Attribute_FixedDisk;
			break;
		case DRIVE_RAMDISK:
			pInfo->uAttributes |= osl_Volume_Attribute_RAMDisk;
			break;
		case DRIVE_REMOTE:
			pInfo->uAttributes |= osl_Volume_Attribute_Remote;
			break;
		case DRIVE_UNKNOWN:
			pInfo->uAttributes = 0;
			break;		
		default:
			pInfo->uValidFields &= ~osl_VolumeInfo_Mask_Attributes;
			pInfo->uAttributes = 0;
			break;
	}
	return osl_File_E_None;    
}

//#############################################
static inline bool is_volume_space_info_request(sal_uInt32 field_mask)
{
	return (field_mask & 
			(osl_VolumeInfo_Mask_TotalSpace | 
			 osl_VolumeInfo_Mask_UsedSpace  | 
			 osl_VolumeInfo_Mask_FreeSpace));
}
    
//#############################################
static void get_volume_space_information(
	const rtl::OUString& path, oslVolumeInfo *pInfo)
{
	BOOL ret = GetDiskFreeSpaceEx(
		reinterpret_cast<LPCTSTR>(path.getStr()), 
		(PULARGE_INTEGER)&(pInfo->uFreeSpace),
		(PULARGE_INTEGER)&(pInfo->uTotalSpace),
		NULL);
            
	if (ret)
	{			    			    
		pInfo->uUsedSpace    = pInfo->uTotalSpace - pInfo->uFreeSpace;
		pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace | 
			osl_VolumeInfo_Mask_UsedSpace | 
			osl_VolumeInfo_Mask_FreeSpace;
	}
}
    
//#############################################
static inline bool is_filesystem_attributes_request(sal_uInt32 field_mask)
{
	return (field_mask & 
			(osl_VolumeInfo_Mask_MaxNameLength | 
			 osl_VolumeInfo_Mask_MaxPathLength | 
			 osl_VolumeInfo_Mask_FileSystemName | 
			 osl_VolumeInfo_Mask_FileSystemCaseHandling));
}
    
//#############################################
static oslFileError get_filesystem_attributes(
	const rtl::OUString& path, sal_uInt32 field_mask, oslVolumeInfo* pInfo)
{
	pInfo->uAttributes = 0;
        
	// osl_get_drive_type must be called first because
	// this function resets osl_VolumeInfo_Mask_Attributes
	// on failure
	if (is_drivetype_request(field_mask))
	{
		oslFileError osl_error = osl_get_drive_type(path, pInfo);
        if (osl_File_E_None != osl_error)
			return osl_error;
	}
	if (is_filesystem_attributes_request(field_mask))
	{
        /* the following two parameters can not be longer than MAX_PATH+1 */
		WCHAR vn[MAX_PATH+1];
		WCHAR fsn[MAX_PATH+1];

		DWORD serial;
		DWORD mcl;
		DWORD flags;
        	
		LPCTSTR pszPath = reinterpret_cast<LPCTSTR>(path.getStr());
		if (GetVolumeInformation(pszPath, vn, MAX_PATH+1, &serial, &mcl, &flags, fsn, MAX_PATH+1))
		{		
            // Currently sal does not use this value, instead MAX_PATH is used
			pInfo->uValidFields   |= osl_VolumeInfo_Mask_MaxNameLength;
			pInfo->uMaxNameLength  = mcl;
        	
            // Should the uMaxPathLength be set to 32767, "\\?\" prefix allowes it
			pInfo->uValidFields   |= osl_VolumeInfo_Mask_MaxPathLength;
			pInfo->uMaxPathLength  = MAX_PATH;

			pInfo->uValidFields   |= osl_VolumeInfo_Mask_FileSystemName;
			rtl_uString_newFromStr(&pInfo->ustrFileSystemName, reinterpret_cast<const sal_Unicode*>(fsn));
        		
			// volumes (even NTFS) will always be considered case
			// insensitive because the Win32 API is not able to
			// deal with case sensitive volumes see M$ Knowledge Base
			// article 100625 that's why we never set the attribute
			// osl_Volume_Attribute_Case_Sensitive
        		
			if (flags & FS_CASE_IS_PRESERVED)
				pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
		            
			pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
		}
	}
	return osl_File_E_None;
}
    
//#####################################################
static bool path_get_parent(rtl::OUString& path)
{   
	OSL_PRECOND(path.lastIndexOf(SLASH) == -1, "Path must not have slashes");
        
	if (!has_path_parent(path))
	{
		sal_Int32 i = path.lastIndexOf(BACKSLASH);                        
		if (-1 < i)
		{
			path = rtl::OUString(path.getStr(), i);
			return true;                    
		}
	}
	return false;
}
    
//##################################################### 
static void path_travel_to_volume_root(const rtl::OUString& system_path, rtl::OUString& volume_root)
{
	rtl::OUString sys_path(system_path);
        
	while(!is_volume_mount_point(sys_path) && path_get_parent(sys_path))
		/**/;
        
	volume_root = sys_path;
	osl::systemPathEnsureSeparator(volume_root);                            
}

//#############################################
oslFileError SAL_CALL osl_getVolumeInformation( 
    rtl_uString *ustrURL, oslVolumeInfo *pInfo, sal_uInt32 uFieldMask )
{			
	if (!pInfo)
		return osl_File_E_INVAL;

    rtl::OUString system_path;		
	oslFileError error = _osl_getSystemPathFromFileURL(ustrURL, &system_path.pData, sal_False);
    
    if (osl_File_E_None != error)
        return error;
    
    rtl::OUString volume_root;
    path_travel_to_volume_root(system_path, volume_root);        
    			
	pInfo->uValidFields = 0;
    
    if ((error = get_filesystem_attributes(volume_root, uFieldMask, pInfo)) != osl_File_E_None)
        return error;
            	
	if (is_volume_space_info_request(uFieldMask)) 
	    get_volume_space_information(volume_root, pInfo);
	    	    
	if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
	{
		pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
		osl_getFileURLFromSystemPath(volume_root.pData, (rtl_uString**)&pInfo->pDeviceHandle);
	}
    
	return osl_File_E_None;
}

//##################################################### 
static oslFileError SAL_CALL osl_getDriveInfo(
	oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask)
{
	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
	TCHAR				cDrive[3] = TEXT("A:");
	TCHAR				cRoot[4] = TEXT("A:\\");

	if ( !pItemImpl )
		return osl_File_E_INVAL;

	pStatus->uValidFields = 0;

	cDrive[0] = pItemImpl->cDriveString[0];
	cRoot[0] = pItemImpl->cDriveString[0];

	if ( uFieldMask & osl_FileStatus_Mask_FileName )
	{
		if ( pItemImpl->cDriveString[0] == '\\' && pItemImpl->cDriveString[1] == '\\' )
		{
			LPCWSTR	lpFirstBkSlash = wcschr( &pItemImpl->cDriveString[2], '\\' );

			if ( lpFirstBkSlash && lpFirstBkSlash[1] )
			{
				LPCWSTR	lpLastBkSlash = wcschr( &lpFirstBkSlash[1], '\\' );

				if ( lpLastBkSlash )
					rtl_uString_newFromStr_WithLength( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(&lpFirstBkSlash[1]), lpLastBkSlash - lpFirstBkSlash - 1 );
				else
					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(&lpFirstBkSlash[1]) );
				pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
			}
		}
		else switch ( GetDriveType( cRoot ) )
		{
		    case DRIVE_REMOTE:
			{
				TCHAR szBuffer[1024];
				DWORD const dwBufsizeConst = ELEMENTS_OF_ARRAY(szBuffer);
				DWORD dwBufsize = dwBufsizeConst;

				DWORD dwResult = WNetGetConnection( cDrive, szBuffer, &dwBufsize );
				if ( NO_ERROR == dwResult )
				{
					TCHAR szFileName[dwBufsizeConst + 16];

					swprintf( szFileName, L"%s [%s]", cDrive, szBuffer );
					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(szFileName) );
				}
				else
					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cDrive) );
			}
			pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
			break;
		    case DRIVE_FIXED:
			{
				TCHAR szVolumeNameBuffer[1024];
				DWORD const dwBufsizeConst = ELEMENTS_OF_ARRAY(szVolumeNameBuffer);

				if ( GetVolumeInformation( cRoot, szVolumeNameBuffer, dwBufsizeConst, NULL, NULL, NULL, NULL, 0 ) )
				{
					TCHAR	szFileName[dwBufsizeConst + 16];

					swprintf( szFileName, L"%s [%s]", cDrive, szVolumeNameBuffer );
					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(szFileName) );
				}
				else
					rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cDrive) );
			}
			pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
			break;
		    case DRIVE_CDROM:
		    case DRIVE_REMOVABLE:
			    pStatus->uValidFields |= osl_FileStatus_Mask_FileName;
			    rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(cRoot) );
			    break;
		    case DRIVE_UNKNOWN:
		    default:
			    break;
		}
	}

	pStatus->eType = osl_File_Type_Volume;
	pStatus->uValidFields |= osl_FileStatus_Mask_Type;

	if ( uFieldMask & osl_FileStatus_Mask_FileURL )
	{
		rtl_uString	*ustrSystemPath = NULL;

		rtl_uString_newFromStr( &ustrSystemPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->cDriveString) );
		osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL );
		rtl_uString_release( ustrSystemPath );
		pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
	}
	return osl_File_E_None;
}

//##################################################### 
static oslFileError SAL_CALL osl_getServerInfo( 
	oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask )
{
	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;
	if ( !pItemImpl )
		return osl_File_E_INVAL;

	pStatus->uValidFields = 0;

	//	pStatus->uValidFields |= osl_FileStatus_Mask_FileName;

	//	if ( _tcscmp( pItemImpl->FindData.cFileName, TEXT(".") ) == 0 )
	//		rtl_uString_newFromAscii( &pStatus->ustrFileName, "/" );
	//	else
	//		rtl_uString_newFromStr( &pStatus->ustrFileName, pItemImpl->FindData.cFileName );

	pStatus->eType = osl_File_Type_Directory;
	pStatus->uValidFields |= osl_FileStatus_Mask_Type;

	if ( uFieldMask & osl_FileStatus_Mask_FileURL )
	{
		osl_getFileURLFromSystemPath( pItemImpl->m_pFullPath, &pStatus->ustrFileURL );
		pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
	}
	return osl_File_E_None;
}

//#############################################
oslFileError SAL_CALL osl_getFileStatus( 
    oslDirectoryItem Item, 
    oslFileStatus *pStatus, 
    sal_uInt32 uFieldMask )
{
	DirectoryItem_Impl	*pItemImpl = (DirectoryItem_Impl *)Item;

	if ( !pItemImpl )
		return osl_File_E_INVAL;

	switch ( pItemImpl->uType  )
	{
	case DIRECTORYITEM_DRIVE:
		return osl_getDriveInfo( Item, pStatus, uFieldMask );
	case DIRECTORYITEM_SERVER:
		return osl_getServerInfo( Item, pStatus, uFieldMask );
	default:
		break;
	}

	if ( uFieldMask & osl_FileStatus_Mask_Validate )
	{
		HANDLE	hFind = FindFirstFile( reinterpret_cast<LPCTSTR>( rtl_uString_getStr( pItemImpl->m_pFullPath ) ), &pItemImpl->FindData );

		if ( hFind != INVALID_HANDLE_VALUE )
			FindClose( hFind );
		else
			return oslTranslateFileError( GetLastError() );

		uFieldMask &= ~	osl_FileStatus_Mask_Validate;
	}

	/* If no fields to retrieve left ignore pStatus */
	if ( !uFieldMask )
		return osl_File_E_None;

	/* Otherwise, this must be a valid pointer */
	if ( !pStatus )
		return osl_File_E_INVAL;

	if ( pStatus->uStructSize != sizeof(oslFileStatus) )
		return osl_File_E_INVAL;

	pStatus->uValidFields = 0;

	/* File time stamps */

	if ( (uFieldMask & osl_FileStatus_Mask_ModifyTime) &&
		FileTimeToTimeValue( &pItemImpl->FindData.ftLastWriteTime, &pStatus->aModifyTime ) )
		pStatus->uValidFields |= osl_FileStatus_Mask_ModifyTime;

	if ( (uFieldMask & osl_FileStatus_Mask_AccessTime) &&
		FileTimeToTimeValue( &pItemImpl->FindData.ftLastAccessTime, &pStatus->aAccessTime ) )
		pStatus->uValidFields |= osl_FileStatus_Mask_AccessTime;

	if ( (uFieldMask & osl_FileStatus_Mask_CreationTime) &&
		FileTimeToTimeValue( &pItemImpl->FindData.ftCreationTime, &pStatus->aCreationTime ) )
		pStatus->uValidFields |= osl_FileStatus_Mask_CreationTime;

	/* Most of the fields are already set, regardless of requiered fields */

	rtl_uString_newFromStr( &pStatus->ustrFileName, reinterpret_cast<const sal_Unicode*>(pItemImpl->FindData.cFileName) );
	pStatus->uValidFields |= osl_FileStatus_Mask_FileName;

    if ((FILE_ATTRIBUTE_REPARSE_POINT & pItemImpl->FindData.dwFileAttributes) &&
        (IO_REPARSE_TAG_MOUNT_POINT == pItemImpl->FindData.dwReserved0))
        pStatus->eType = osl_File_Type_Volume;
    else if (pItemImpl->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        pStatus->eType = osl_File_Type_Directory;
    else    
	    pStatus->eType = osl_File_Type_Regular;
	    
	pStatus->uValidFields |= osl_FileStatus_Mask_Type;

	pStatus->uAttributes = pItemImpl->FindData.dwFileAttributes;
	pStatus->uValidFields |= osl_FileStatus_Mask_Attributes;

	pStatus->uFileSize = (sal_uInt64)pItemImpl->FindData.nFileSizeLow + ((sal_uInt64)pItemImpl->FindData.nFileSizeHigh << 32);
	pStatus->uValidFields |= osl_FileStatus_Mask_FileSize;

	if ( uFieldMask & osl_FileStatus_Mask_LinkTargetURL )
	{
		osl_getFileURLFromSystemPath( pItemImpl->m_pFullPath, &pStatus->ustrLinkTargetURL );

		pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL;
	}

	if ( uFieldMask & osl_FileStatus_Mask_FileURL )
	{
		if ( !pItemImpl->bFullPathNormalized )
		{
            sal_uInt32 nLen = rtl_uString_getLength( pItemImpl->m_pFullPath );
            ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
            sal_uInt32 nNewLen = GetCaseCorrectPathName( reinterpret_cast<LPCTSTR>( rtl_uString_getStr( pItemImpl->m_pFullPath ) ),
                                                      ::osl::mingw_reinterpret_cast<LPTSTR>( aBuffer ),
                                                      aBuffer.getBufSizeInSymbols(),
                                                      sal_True );

            if ( nNewLen )
            {
                rtl_uString_newFromStr( &pItemImpl->m_pFullPath, aBuffer );
                pItemImpl->bFullPathNormalized = TRUE;
            }
		}

		osl_getFileURLFromSystemPath( pItemImpl->m_pFullPath, &pStatus->ustrFileURL );
		pStatus->uValidFields |= osl_FileStatus_Mask_FileURL;
	}

	return osl_File_E_None;
}

//#####################################################
// file attributes handling functions
//#####################################################

//#############################################
oslFileError SAL_CALL osl_setFileAttributes( 
    rtl_uString *ustrFileURL, 
    sal_uInt64 uAttributes )
{
	oslFileError	error;
	rtl_uString		*ustrSysPath = NULL;
	DWORD			dwFileAttributes;
	BOOL			fSuccess;

	// Converts the normalized path into a systempath
	error = _osl_getSystemPathFromFileURL( ustrFileURL, &ustrSysPath, sal_False );

	if ( osl_File_E_None != error )
		return error;

	dwFileAttributes = GetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)) );

	if ( (DWORD)-1 != dwFileAttributes )
	{
		dwFileAttributes &= ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN);

		if ( uAttributes & osl_File_Attribute_ReadOnly )
			dwFileAttributes |= FILE_ATTRIBUTE_READONLY;

		if ( uAttributes & osl_File_Attribute_Hidden )
			dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;

		fSuccess = SetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)), dwFileAttributes );
	}
	else
		fSuccess = FALSE;

	if ( !fSuccess )
		error = oslTranslateFileError( GetLastError() );

	rtl_uString_release( ustrSysPath );

	return error;
}

//##################################################### 
oslFileError SAL_CALL osl_setFileTime(
    rtl_uString *filePath, 
    const TimeValue *aCreationTime, 
    const TimeValue *aLastAccessTime, 
    const TimeValue *aLastWriteTime)
{
	oslFileError error;
	rtl_uString *sysPath=NULL;
	FILETIME *lpCreationTime=NULL;
	FILETIME *lpLastAccessTime=NULL;
	FILETIME *lpLastWriteTime=NULL;
	FILETIME ftCreationTime;
	FILETIME ftLastAccessTime;
	FILETIME ftLastWriteTime;
	HANDLE hFile;
	BOOL fSuccess;


	error=_osl_getSystemPathFromFileURL(filePath, &sysPath, sal_False);

	if (error==osl_File_E_INVAL)
		return error;

	hFile=CreateFileW(reinterpret_cast<LPCWSTR>(rtl_uString_getStr(sysPath)), GENERIC_WRITE, 0, NULL , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	rtl_uString_release(sysPath);

	if (hFile==INVALID_HANDLE_VALUE)
		return osl_File_E_NOENT;

	if (TimeValueToFileTime(aCreationTime, &ftCreationTime))
		lpCreationTime=&ftCreationTime;

	if (TimeValueToFileTime(aLastAccessTime, &ftLastAccessTime))
		lpLastAccessTime=&ftLastAccessTime;

	if (TimeValueToFileTime(aLastWriteTime, &ftLastWriteTime))
		lpLastWriteTime=&ftLastWriteTime;

	fSuccess=SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime);

	CloseHandle(hFile);

	if (!fSuccess)
		return osl_File_E_INVAL;
	else
		return osl_File_E_None;
}
