diff options
Diffstat (limited to 'sal/osl/w32')
36 files changed, 4753 insertions, 3737 deletions
diff --git a/sal/osl/w32/MAKEFILE.MK b/sal/osl/w32/MAKEFILE.MK index e6a338543..474904884 100644 --- a/sal/osl/w32/MAKEFILE.MK +++ b/sal/osl/w32/MAKEFILE.MK @@ -2,14 +2,10 @@ # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # -# Copyright 2008 by Sun Microsystems, Inc. +# Copyright 2000, 2010 Oracle and/or its affiliates. # # OpenOffice.org - a multi-platform office productivity suite # -# $RCSfile: MAKEFILE.MK,v $ -# -# $Revision: 1.16 $ -# # This file is part of OpenOffice.org. # # OpenOffice.org is free software: you can redistribute it and/or modify @@ -78,6 +74,10 @@ SLOFILES= $(SLO)$/conditn.obj \ $(SLO)$/pipe.obj \ $(SLO)$/util.obj \ $(SLO)$/file.obj\ + $(SLO)$/file_dirvol.obj\ + $(SLO)$/file_error.obj\ + $(SLO)$/file_url.obj\ + $(SLO)$/tempfile.obj\ $(SLO)$/path_helper.obj\ $(SLO)$/procimpl.obj \ $(SLO)$/salinit.obj @@ -101,6 +101,10 @@ OBJFILES= $(OBJ)$/conditn.obj \ $(OBJ)$/pipe.obj \ $(OBJ)$/util.obj \ $(OBJ)$/file.obj\ + $(OBJ)$/file_dirvol.obj\ + $(OBJ)$/file_error.obj\ + $(OBJ)$/file_url.obj\ + $(OBJ)$/tempfile.obj\ $(OBJ)$/path_helper.obj\ $(OBJ)$/procimpl.obj \ $(OBJ)$/salinit.obj diff --git a/sal/osl/w32/conditn.c b/sal/osl/w32/conditn.c index 854c35984..9a637935b 100644 --- a/sal/osl/w32/conditn.c +++ b/sal/osl/w32/conditn.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: conditn.c,v $ - * $Revision: 1.8 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -107,8 +104,7 @@ oslConditionResult SAL_CALL osl_waitCondition(oslCondition Condition, while ( 1 ) { /* Only wake up if a SendMessage call to the threads message loop is detected */ - - switch( MsgWaitForMultipleObjects( 1, &(HANDLE)Condition, FALSE, timeout, QS_SENDMESSAGE ) ) + switch( MsgWaitForMultipleObjects( 1, (HANDLE *)(&Condition), FALSE, timeout, QS_SENDMESSAGE ) ) { case WAIT_OBJECT_0 + 1: { diff --git a/sal/osl/w32/diagnose.c b/sal/osl/w32/diagnose.c index 0983e2c9a..129f579c4 100644 --- a/sal/osl/w32/diagnose.c +++ b/sal/osl/w32/diagnose.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: diagnose.c,v $ - * $Revision: 1.14 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -73,6 +70,7 @@ void SAL_CALL osl_breakDebug(void) void SAL_CALL osl_trace(const sal_Char* lpszFormat, ...) { va_list args; + int written = 0; va_start(args, lpszFormat); @@ -89,8 +87,11 @@ void SAL_CALL osl_trace(const sal_Char* lpszFormat, ...) if ( IsDebuggerPresent() ) { sal_Char szMessage[512]; - szMessage[sizeof(szMessage)-1] = 0; - _vsnprintf( szMessage, sizeof(szMessage) -1, lpszFormat, args ); + written = _vsnprintf( szMessage, sizeof(szMessage) - 2, lpszFormat, args ); + if ( written == -1 ) + written = sizeof(szMessage) - 2; + szMessage[ written++ ] = '\n'; + szMessage[ written ] = 0; OutputDebugString( szMessage ); } diff --git a/sal/osl/w32/dllentry.c b/sal/osl/w32/dllentry.c index a81dfc32a..3c1d1195d 100644 --- a/sal/osl/w32/dllentry.c +++ b/sal/osl/w32/dllentry.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: dllentry.c,v $ - * $Revision: 1.34 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -255,7 +252,7 @@ void do_cleanup( void ) */ -#ifdef PRODUCT +#ifndef DBG_UTIL __try #endif { @@ -267,7 +264,7 @@ void do_cleanup( void ) rtl_cache_fini(); rtl_arena_fini(); } -#ifdef PRODUCT +#ifndef DBG_UTIL __except( EXCEPTION_EXECUTE_HANDLER ) { } diff --git a/sal/osl/w32/file.cxx b/sal/osl/w32/file.cxx index b7eb4d52b..bed2f39cc 100644 --- a/sal/osl/w32/file.cxx +++ b/sal/osl/w32/file.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: file.cxx,v $ - * $Revision: 1.19 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -34,26 +31,19 @@ #define UNICODE #define _UNICODE #define _WIN32_WINNT 0x0500 -#include "systools\win32\uwinapi.h" +#include "systools/win32/uwinapi.h" -#include "path_helper.hxx" +#include "osl/file.hxx" -#include "sal/types.h" +#include "file_url.h" +#include "file_error.h" -#include "osl/file.hxx" #include "osl/diagnose.h" -#include "rtl/ustring.hxx" #include "rtl/alloc.h" -#include "rtl/tencinfo.h" -#include "osl/thread.h" -#include "osl/mutex.h" #include "rtl/byteseq.h" -#include "osl/time.h" -//#include <rtl/logfile.h> -#include <stdio.h> +#include "rtl/ustring.hxx" -#define WIN32_LEAN_AND_MEAN -#include <windows.h> +#include <stdio.h> #include <tchar.h> #ifdef __MINGW32__ @@ -61,2635 +51,751 @@ #include <ctype.h> #endif -#include <malloc.h> #include <algorithm> #include <limits> #ifdef max /* conflict w/ std::numeric_limits<T>::max() */ #undef max #endif - -//##################################################### -// BEGIN global -//##################################################### - -extern "C" oslMutex g_CurrentDirectoryMutex; /* Initialized in dllentry.c */ -oslMutex g_CurrentDirectoryMutex; - -//##################################################### -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; -} - -//##################################################### -extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle(HANDLE hFile) -{ - if ( IsValidHandle(hFile) ) - return (oslFileHandle)hFile; - else - return NULL; -} - -//##################################################### -// End global -//##################################################### - - -using namespace osl; - -#define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0]))) - -// Allocate n number of t's on the stack return a pointer to it in p -#ifdef __MINGW32__ -#define STACK_ALLOC(p, t, n) (p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t))); -#else -#define STACK_ALLOC(p, t, n) __try {(p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));} \ - __except(EXCEPTION_EXECUTE_HANDLER) {(p) = NULL;} -#endif - -#if OSL_DEBUG_LEVEL > 0 -#define OSL_ENSURE_FILE( cond, msg, file ) ( (cond) ? (void)0 : _osl_warnFile( msg, file ) ) -#else -#define OSL_ENSURE_FILE( cond, msg, file ) ((void)0) +#ifdef min +#undef min #endif - -#define PATHTYPE_ERROR 0 -#define PATHTYPE_RELATIVE 1 -#define PATHTYPE_ABSOLUTE_UNC 2 -#define PATHTYPE_ABSOLUTE_LOCAL 3 -#define PATHTYPE_MASK_TYPE 0xFF -#define PATHTYPE_IS_VOLUME 0x0100 -#define PATHTYPE_IS_SERVER 0x0200 - -#define VALIDATEPATH_NORMAL 0x0000 -#define VALIDATEPATH_ALLOW_WILDCARDS 0x0001 -#define VALIDATEPATH_ALLOW_ELLIPSE 0x0002 -#define VALIDATEPATH_ALLOW_RELATIVE 0x0004 -#define VALIDATEPATH_ALLOW_UNC 0x0008 - -#define WSTR_SYSTEM_ROOT_PATH L"\\\\.\\" - -typedef struct { - UINT uType; - - union { - WIN32_FIND_DATA FindData; - TCHAR cDriveString[MAX_PATH]; - }; - TCHAR szFullPath[MAX_PATH]; - BOOL bFullPathNormalized; - int nRefCount; -}DirectoryItem_Impl; - -#define DIRECTORYTYPE_LOCALROOT 0 -#define DIRECTORYTYPE_NETROOT 1 -#define DIRECTORYTYPE_NETRESORCE 2 -#define DIRECTORYTYPE_FILESYSTEM 3 - -#define DIRECTORYITEM_DRIVE 0 -#define DIRECTORYITEM_FILE 1 -#define DIRECTORYITEM_SERVER 2 - -typedef struct { - UINT uType; - union { - HANDLE hDirectory; - HANDLE hEnumDrives; - }; - TCHAR szDirectoryPath[MAX_PATH]; -} Directory_Impl; -/* Different types of paths */ -typedef enum _PATHTYPE +//################################################################## +// File handle implementation +//################################################################## +struct FileHandle_Impl { - PATHTYPE_SYNTAXERROR = 0, - PATHTYPE_NETROOT, - PATHTYPE_NETSERVER, - PATHTYPE_VOLUME, - PATHTYPE_FILE -} PATHTYPE; - - -namespace /* private */ -{ - // forward - void _osl_warnFile(const char*, rtl_uString*); - oslFileError SAL_CALL _osl_getFileURLFromSystemPath(rtl_uString* , rtl_uString**); - DWORD WINAPI IsValidFilePath(rtl_uString*, LPCTSTR*, DWORD, rtl_uString**); - HANDLE WINAPI OpenLogicalDrivesEnum(void); - BOOL WINAPI EnumLogicalDrives(HANDLE, LPTSTR); - BOOL WINAPI CloseLogicalDrivesEnum(HANDLE); - HANDLE WINAPI OpenDirectory(LPCTSTR); - BOOL WINAPI CloseDirectory(HANDLE); - BOOL WINAPI EnumDirectory(HANDLE, LPWIN32_FIND_DATA); - DWORD WINAPI GetCaseCorrectPathName(LPCTSTR, LPTSTR, DWORD); - oslFileError SAL_CALL _osl_getSystemPathFromFileURL(rtl_uString*, rtl_uString**, sal_Bool); - - /* OS error to errno values mapping table */ - struct errentry { - unsigned long oscode; /* OS return value */ - int errnocode; /* System V error code */ - }; - - struct errentry errtable[] = { - { ERROR_SUCCESS, osl_File_E_None }, /* 0 */ - { ERROR_INVALID_FUNCTION, osl_File_E_INVAL }, /* 1 */ - { ERROR_FILE_NOT_FOUND, osl_File_E_NOENT }, /* 2 */ - { ERROR_PATH_NOT_FOUND, osl_File_E_NOENT }, /* 3 */ - { ERROR_TOO_MANY_OPEN_FILES, osl_File_E_MFILE }, /* 4 */ - { ERROR_ACCESS_DENIED, osl_File_E_ACCES }, /* 5 */ - { ERROR_INVALID_HANDLE, osl_File_E_BADF }, /* 6 */ - { ERROR_ARENA_TRASHED, osl_File_E_NOMEM }, /* 7 */ - { ERROR_NOT_ENOUGH_MEMORY, osl_File_E_NOMEM }, /* 8 */ - { ERROR_INVALID_BLOCK, osl_File_E_NOMEM }, /* 9 */ - { ERROR_BAD_ENVIRONMENT, osl_File_E_2BIG }, /* 10 */ - { ERROR_BAD_FORMAT, osl_File_E_NOEXEC }, /* 11 */ - { ERROR_INVALID_ACCESS, osl_File_E_INVAL }, /* 12 */ - { ERROR_INVALID_DATA, osl_File_E_INVAL }, /* 13 */ - { ERROR_INVALID_DRIVE, osl_File_E_NOENT }, /* 15 */ - { ERROR_CURRENT_DIRECTORY, osl_File_E_ACCES }, /* 16 */ - { ERROR_NOT_SAME_DEVICE, osl_File_E_XDEV }, /* 17 */ - { ERROR_NO_MORE_FILES, osl_File_E_NOENT }, /* 18 */ - { ERROR_NOT_READY, osl_File_E_NOTREADY }, /* 21 */ - { ERROR_LOCK_VIOLATION, osl_File_E_ACCES }, /* 33 */ - { ERROR_BAD_NETPATH, osl_File_E_NOENT }, /* 53 */ - { ERROR_NETWORK_ACCESS_DENIED, osl_File_E_ACCES }, /* 65 */ - { ERROR_BAD_NET_NAME, osl_File_E_NOENT }, /* 67 */ - { ERROR_FILE_EXISTS, osl_File_E_EXIST }, /* 80 */ - { ERROR_CANNOT_MAKE, osl_File_E_ACCES }, /* 82 */ - { ERROR_FAIL_I24, osl_File_E_ACCES }, /* 83 */ - { ERROR_INVALID_PARAMETER, osl_File_E_INVAL }, /* 87 */ - { ERROR_NO_PROC_SLOTS, osl_File_E_AGAIN }, /* 89 */ - { ERROR_DRIVE_LOCKED, osl_File_E_ACCES }, /* 108 */ - { ERROR_BROKEN_PIPE, osl_File_E_PIPE }, /* 109 */ - { ERROR_DISK_FULL, osl_File_E_NOSPC }, /* 112 */ - { ERROR_INVALID_TARGET_HANDLE, osl_File_E_BADF }, /* 114 */ - { ERROR_INVALID_HANDLE, osl_File_E_INVAL }, /* 124 */ - { ERROR_WAIT_NO_CHILDREN, osl_File_E_CHILD }, /* 128 */ - { ERROR_CHILD_NOT_COMPLETE, osl_File_E_CHILD }, /* 129 */ - { ERROR_DIRECT_ACCESS_HANDLE, osl_File_E_BADF }, /* 130 */ - { ERROR_NEGATIVE_SEEK, osl_File_E_INVAL }, /* 131 */ - { ERROR_SEEK_ON_DEVICE, osl_File_E_ACCES }, /* 132 */ - { ERROR_DIR_NOT_EMPTY, osl_File_E_NOTEMPTY }, /* 145 */ - { ERROR_NOT_LOCKED, osl_File_E_ACCES }, /* 158 */ - { ERROR_BAD_PATHNAME, osl_File_E_NOENT }, /* 161 */ - { ERROR_MAX_THRDS_REACHED, osl_File_E_AGAIN }, /* 164 */ - { ERROR_LOCK_FAILED, osl_File_E_ACCES }, /* 167 */ - { ERROR_ALREADY_EXISTS, osl_File_E_EXIST }, /* 183 */ - { ERROR_FILENAME_EXCED_RANGE, osl_File_E_NOENT }, /* 206 */ - { ERROR_NESTING_NOT_ALLOWED, osl_File_E_AGAIN }, /* 215 */ - { ERROR_DIRECTORY, osl_File_E_NOENT }, /* 267 */ - { ERROR_NOT_ENOUGH_QUOTA, osl_File_E_NOMEM }, /* 1816 */ - { ERROR_UNEXP_NET_ERR, osl_File_E_NETWORK } /* 59 */ - }; - - /* The following two constants must be the minimum and maximum - values in the (contiguous) range of osl_File_E_xec Failure errors. */ - #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG - #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN - - /* These are the low and high value in the range of errors that are - access violations */ - #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT - #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED - - //##################################################### - oslFileError MapError(DWORD dwError) - { - for (int i = 0; i < ELEMENTS_OF_ARRAY(errtable); ++i ) - { - if (dwError == errtable[i].oscode) - return static_cast<oslFileError>(errtable[i].errnocode); - } + CRITICAL_SECTION m_mutex; + HANDLE m_hFile; - /* The error code wasn't in the table. We check for a range of - osl_File_E_ACCES errors or exec failure errors (ENOEXEC). - Otherwise osl_File_E_INVAL is returned. */ - if ( dwError >= MIN_EACCES_RANGE && dwError <= MAX_EACCES_RANGE) - return osl_File_E_ACCES; - else if ( dwError >= MIN_EXEC_ERROR && dwError <= MAX_EXEC_ERROR) - return osl_File_E_NOEXEC; - else - return osl_File_E_INVAL; - } - - //##################################################### - oslFileError SAL_CALL osl_openLocalRoot( - rtl_uString *strDirectoryPath, oslDirectory *pDirectory) + /** State + */ + enum StateBits { - 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))); - _tcscpy( pDirImpl->szDirectoryPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysPath)) ); - - /* Append backslash if neccessary */ - - /* @@@ToDo - use function ensure backslash - */ - if ( pDirImpl->szDirectoryPath[_tcslen(pDirImpl->szDirectoryPath) - 1] != L'\\' ) - _tcscat( pDirImpl->szDirectoryPath, L"\\" ); + STATE_SEEKABLE = 1, /* open() sets, iff regular file */ + STATE_READABLE = 2, /* open() sets, read() requires */ + STATE_WRITEABLE = 4, /* open() sets, write() requires */ + STATE_MODIFIED = 8 /* write() sets, flush() resets */ + }; + int m_state; - pDirImpl->uType = DIRECTORYTYPE_LOCALROOT; - pDirImpl->hEnumDrives = OpenLogicalDrivesEnum(); + sal_uInt64 m_size; /* file size */ + LONGLONG m_offset; /* physical offset from begin of file */ + LONGLONG m_filepos; /* logical offset from begin of file */ - /* @@@ToDo - Use IsValidHandle(...) - */ - if ( pDirImpl->hEnumDrives != INVALID_HANDLE_VALUE ) - { - *pDirectory = (oslDirectory)pDirImpl; - error = osl_File_E_None; - } - else - { - if ( pDirImpl ) - rtl_freeMemory(pDirImpl); + LONGLONG m_bufptr; /* buffer offset from begin of file */ + SIZE_T m_buflen; /* buffer filled [0, m_bufsiz - 1] */ - error = MapError( GetLastError() ); - } + SIZE_T m_bufsiz; + sal_uInt8 * m_buffer; - rtl_uString_release( strSysPath ); - } - return error; - } + explicit FileHandle_Impl (HANDLE hFile); + ~FileHandle_Impl(); - //##################################################### - oslFileError SAL_CALL osl_openFileDirectory( - rtl_uString *strDirectoryPath, oslDirectory *pDirectory) - { - // MT: Done in osl_openDirectory! -// rtl_uString *strSysPath = NULL; - oslFileError error; - - //MT: Not done in osl_openNetworkServer, why here? - if ( !pDirectory ) - return osl_File_E_INVAL; + static void* operator new(size_t n); + static void operator delete(void * p, size_t); + static SIZE_T getpagesize(); - *pDirectory = NULL; + sal_uInt64 getPos() const; + oslFileError setPos (sal_uInt64 uPos); - // MT: Done in osl_openDirectory! -// error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysPath, sal_False ); -// if ( osl_File_E_None == error ) - { - Directory_Impl *pDirImpl; + sal_uInt64 getSize() const; + oslFileError setSize (sal_uInt64 uPos); - pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl))); - _tcscpy( pDirImpl->szDirectoryPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strDirectoryPath)) ); + oslFileError readAt ( + LONGLONG nOffset, + void * pBuffer, + DWORD nBytesRequested, + sal_uInt64 * pBytesRead); - /* Append backslash if neccessary */ + oslFileError writeAt ( + LONGLONG nOffset, + void const * pBuffer, + DWORD nBytesToWrite, + sal_uInt64 * pBytesWritten); - /* @@@ToDo - use function ensure backslash - */ - if ( pDirImpl->szDirectoryPath[_tcslen(pDirImpl->szDirectoryPath) - 1] != L'\\' ) - _tcscat( pDirImpl->szDirectoryPath, L"\\" ); - // MT: ??? - // GetCaseCorrectPathName( pDirImpl->szDirectoryPath, pDirImpl->szDirectoryPath, sizeof(pDirImpl->szDirectoryPath) ); + oslFileError readFileAt ( + LONGLONG nOffset, + void * pBuffer, + sal_uInt64 uBytesRequested, + sal_uInt64 * pBytesRead); - pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM; - pDirImpl->hDirectory = OpenDirectory( pDirImpl->szDirectoryPath ); + oslFileError writeFileAt ( + LONGLONG nOffset, + void const * pBuffer, + sal_uInt64 uBytesToWrite, + sal_uInt64 * pBytesWritten); - if ( pDirImpl->hDirectory ) - { - *pDirectory = (oslDirectory)pDirImpl; - error = osl_File_E_None; - } - else - { - if ( pDirImpl ) - rtl_freeMemory(pDirImpl); + oslFileError readLineAt ( + LONGLONG nOffset, + sal_Sequence ** ppSequence, + sal_uInt64 * pBytesRead); - error = MapError( GetLastError() ); - } + oslFileError writeSequence_Impl ( + sal_Sequence ** ppSequence, + SIZE_T * pnOffset, + const void * pBuffer, + SIZE_T nBytes); -// rtl_uString_release( strSysPath ); - } - return error; - } + oslFileError syncFile(); - typedef struct tagDIRECTORY + /** Buffer cache / allocator. + */ + class Allocator { - HANDLE hFind; - WIN32_FIND_DATA aFirstData; - } DIRECTORY, *PDIRECTORY, FAR *LPDIRECTORY; - - //##################################################### - HANDLE WINAPI OpenDirectory(LPCTSTR lpszPath) - { - LPDIRECTORY pDirectory = (LPDIRECTORY)HeapAlloc(GetProcessHeap(), 0, sizeof(DIRECTORY)); - - if (pDirectory) - { - TCHAR szFileMask[MAX_PATH]; - int nLen; - - _tcscpy( szFileMask, lpszPath ); - nLen = _tcslen( szFileMask ); - - if (nLen && szFileMask[nLen-1] != '\\') - _tcscat(szFileMask, TEXT("\\*.*")); - else - _tcscat(szFileMask, TEXT("*.*")); + rtl_cache_type * m_cache; + SIZE_T m_bufsiz; - pDirectory->hFind = FindFirstFile(szFileMask, &pDirectory->aFirstData); + Allocator (Allocator const &); + Allocator & operator= (Allocator const &); - if (!IsValidHandle(pDirectory->hFind)) - { - if ( GetLastError() != ERROR_NO_MORE_FILES ) - { - HeapFree(GetProcessHeap(), 0, pDirectory); - pDirectory = NULL; - } - } - } - return (HANDLE)pDirectory; - } + public: + static Allocator & get(); - //##################################################### - BOOL WINAPI CloseDirectory(HANDLE hDirectory) - { - BOOL fSuccess = FALSE; - LPDIRECTORY pDirectory = (LPDIRECTORY)hDirectory; + void allocate (sal_uInt8 ** ppBuffer, SIZE_T * pnSize); + void deallocate (sal_uInt8 * pBuffer); - if (pDirectory) - { - if (IsValidHandle(pDirectory->hFind)) - fSuccess = FindClose(pDirectory->hFind); - - fSuccess = HeapFree(GetProcessHeap(), 0, pDirectory) && fSuccess; - } - else - SetLastError(ERROR_INVALID_HANDLE); - - return fSuccess; - } + protected: + Allocator(); + ~Allocator(); + }; - //##################################################### - BOOL WINAPI EnumDirectory(HANDLE hDirectory, LPWIN32_FIND_DATA pFindData) + /** Guard. + */ + class Guard { - BOOL fSuccess = FALSE; - LPDIRECTORY pDirectory = (LPDIRECTORY)hDirectory; + LPCRITICAL_SECTION m_mutex; - if ( pDirectory ) - { - BOOL fValid; + public: + explicit Guard(LPCRITICAL_SECTION pMutex); + ~Guard(); + }; +}; - 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 ); - } +FileHandle_Impl::Allocator & +FileHandle_Impl::Allocator::get() +{ + static Allocator g_aBufferAllocator; + return g_aBufferAllocator; +} - fValid = fSuccess && _tcscmp( TEXT("."), pFindData->cFileName ) != 0 && _tcscmp( TEXT(".."), pFindData->cFileName ) != 0; +FileHandle_Impl::Allocator::Allocator() + : m_cache (0), + m_bufsiz (0) +{ + SIZE_T const pagesize = FileHandle_Impl::getpagesize(); + m_cache = rtl_cache_create ( + "osl_file_buffer_cache", pagesize, 0, 0, 0, 0, 0, 0, 0); + if (0 != m_cache) + m_bufsiz = pagesize; +} - } while( fSuccess && !fValid ); - } - else - SetLastError( ERROR_INVALID_HANDLE ); +FileHandle_Impl::Allocator::~Allocator() +{ + rtl_cache_destroy(m_cache), m_cache = 0; +} - return fSuccess; - } +void FileHandle_Impl::Allocator::allocate (sal_uInt8 ** ppBuffer, SIZE_T * pnSize) +{ + OSL_PRECOND((0 != ppBuffer) && (0 != pnSize), "FileHandle_Impl::Allocator::allocate(): contract violation"); + *ppBuffer = static_cast< sal_uInt8* >(rtl_cache_alloc(m_cache)), *pnSize = m_bufsiz; +} - //##################################################### - oslFileError SAL_CALL osl_openNetworkServer(rtl_uString *strSysDirPath, oslDirectory *pDirectory) - { - NETRESOURCEW aNetResource; - HANDLE hEnum; - DWORD dwError; +void FileHandle_Impl::Allocator::deallocate (sal_uInt8 * pBuffer) +{ + if (0 != pBuffer) + rtl_cache_free (m_cache, pBuffer); +} - ZeroMemory( &aNetResource, sizeof(aNetResource) ); +FileHandle_Impl::Guard::Guard(LPCRITICAL_SECTION pMutex) + : m_mutex (pMutex) +{ + OSL_PRECOND (m_mutex != 0, "FileHandle_Impl::Guard::Guard(): null pointer."); + ::EnterCriticalSection (m_mutex); +} +FileHandle_Impl::Guard::~Guard() +{ + OSL_PRECOND (m_mutex != 0, "FileHandle_Impl::Guard::~Guard(): null pointer."); + ::LeaveCriticalSection (m_mutex); +} - aNetResource.lpRemoteName = reinterpret_cast<LPWSTR>(strSysDirPath->buffer); +FileHandle_Impl::FileHandle_Impl(HANDLE hFile) + : m_hFile (hFile), + m_state (STATE_READABLE | STATE_WRITEABLE), + m_size (0), + m_offset (0), + m_filepos (0), + m_bufptr (-1), + m_buflen (0), + m_bufsiz (0), + m_buffer (0) +{ + ::InitializeCriticalSection (&m_mutex); + Allocator::get().allocate (&m_buffer, &m_bufsiz); + if (m_buffer != 0) + memset (m_buffer, 0, m_bufsiz); +} - dwError = WNetOpenEnumW( - RESOURCE_GLOBALNET, - RESOURCETYPE_DISK, - RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER, - &aNetResource, - &hEnum ); +FileHandle_Impl::~FileHandle_Impl() +{ + Allocator::get().deallocate (m_buffer), m_buffer = 0; + ::DeleteCriticalSection (&m_mutex); +} - if ( ERROR_SUCCESS == dwError ) - { - Directory_Impl *pDirImpl; +void * FileHandle_Impl::operator new(size_t n) +{ + return rtl_allocateMemory(n); +} - pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl))); - pDirImpl->uType = DIRECTORYTYPE_NETROOT; - pDirImpl->hDirectory = hEnum; - *pDirectory = (oslDirectory)pDirImpl; - } - return MapError( dwError ); - } +void FileHandle_Impl::operator delete(void * p, size_t) +{ + rtl_freeMemory(p); +} - //##################################################### - 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; +SIZE_T FileHandle_Impl::getpagesize() +{ + SYSTEM_INFO info; + ::GetSystemInfo (&info); + return sal::static_int_cast< SIZE_T >(info.dwPageSize); +} - uHint = uHint; /* to get no warning */ +sal_uInt64 FileHandle_Impl::getPos() const +{ + return sal::static_int_cast< sal_uInt64 >(m_filepos); +} - if ( !pItem ) - return osl_File_E_INVAL; +oslFileError FileHandle_Impl::setPos (sal_uInt64 uPos) +{ + m_filepos = sal::static_int_cast< LONGLONG >(uPos); + return osl_File_E_None; +} - *pItem = NULL; +sal_uInt64 FileHandle_Impl::getSize() const +{ + LONGLONG bufend = std::max((LONGLONG)(0), m_bufptr) + m_buflen; + return std::max(m_size, sal::static_int_cast< sal_uInt64 >(bufend)); +} - if ( !pDirImpl ) - return osl_File_E_INVAL; +oslFileError FileHandle_Impl::setSize (sal_uInt64 uSize) +{ + LARGE_INTEGER nDstPos; nDstPos.QuadPart = sal::static_int_cast< LONGLONG >(uSize); + if (!::SetFilePointerEx(m_hFile, nDstPos, 0, FILE_BEGIN)) + return oslTranslateFileError( GetLastError() ); - dwCount = 1; - dwBufSize = sizeof(buffer); - dwError = WNetEnumResource( pDirImpl->hDirectory, &dwCount, lpNetResource, &dwBufSize ); + if (!::SetEndOfFile(m_hFile)) + return oslTranslateFileError( GetLastError() ); + m_size = uSize; - 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; + nDstPos.QuadPart = m_offset; + if (!::SetFilePointerEx(m_hFile, nDstPos, 0, FILE_BEGIN)) + return oslTranslateFileError( GetLastError() ); - ZeroMemory( pItemImpl, sizeof(DirectoryItem_Impl) ); - pItemImpl->uType = DIRECTORYITEM_DRIVE; - osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl ); + return osl_File_E_None; +} - wcscpy( pItemImpl->cDriveString, lpNetResource->lpRemoteName ); +oslFileError FileHandle_Impl::readAt ( + LONGLONG nOffset, + void * pBuffer, + DWORD nBytesRequested, + sal_uInt64 * pBytesRead) +{ + OSL_PRECOND(m_state & STATE_SEEKABLE, "FileHandle_Impl::readAt(): not seekable"); + if (!(m_state & STATE_SEEKABLE)) + return osl_File_E_SPIPE; - *pItem = pItemImpl; - } - return osl_File_E_None; - case ERROR_NO_MORE_ITEMS: - return osl_File_E_NOENT; - default: - return MapError( dwError ); - } - } + OSL_PRECOND(m_state & STATE_READABLE, "FileHandle_Impl::readAt(): not readable"); + if (!(m_state & STATE_READABLE)) + return osl_File_E_BADF; - //##################################################### - oslFileError SAL_CALL osl_getNextDrive( - oslDirectory Directory, oslDirectoryItem *pItem, sal_uInt32 uHint ) + if (nOffset != m_offset) { - 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 - { - rtl_freeMemory( pItemImpl ); - return MapError( GetLastError() ); - } + LARGE_INTEGER liOffset; liOffset.QuadPart = nOffset; + if (!::SetFilePointerEx(m_hFile, liOffset, 0, FILE_BEGIN)) + return oslTranslateFileError( GetLastError() ); + m_offset = nOffset; } - //##################################################### - 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; + DWORD dwDone = 0; + if (!::ReadFile(m_hFile, pBuffer, nBytesRequested, &dwDone, 0)) + return oslTranslateFileError( GetLastError() ); + m_offset += dwDone; - pItemImpl = reinterpret_cast<DirectoryItem_Impl*>(rtl_allocateMemory(sizeof(DirectoryItem_Impl))); - if ( !pItemImpl ) - return osl_File_E_NOMEM; + *pBytesRead = dwDone; + return osl_File_E_None; +} - memset( pItemImpl, 0, sizeof(DirectoryItem_Impl) ); - fFound = EnumDirectory( pDirImpl->hDirectory, &pItemImpl->FindData ); +oslFileError FileHandle_Impl::writeAt ( + LONGLONG nOffset, + void const * pBuffer, + DWORD nBytesToWrite, + sal_uInt64 * pBytesWritten) +{ + OSL_PRECOND(m_state & STATE_SEEKABLE, "FileHandle_Impl::writeAt(): not seekable"); + if (!(m_state & STATE_SEEKABLE)) + return osl_File_E_SPIPE; - if ( fFound ) - { - pItemImpl->uType = DIRECTORYITEM_FILE; - pItemImpl->nRefCount = 1; - _tcscpy( pItemImpl->szFullPath, pDirImpl->szDirectoryPath ); - _tcscat( pItemImpl->szFullPath, pItemImpl->FindData.cFileName ); - pItemImpl->bFullPathNormalized = FALSE; - *pItem = (oslDirectoryItem)pItemImpl; - return osl_File_E_None; - } - else - { - rtl_freeMemory( pItemImpl ); - return MapError( GetLastError() ); - } - } + OSL_PRECOND(m_state & STATE_WRITEABLE, "FileHandle_Impl::writeAt(): not writeable"); + if (!(m_state & STATE_WRITEABLE)) + return osl_File_E_BADF; - //##################################################### - oslFileError SAL_CALL osl_getDriveInfo( - oslDirectoryItem Item, oslFileStatus *pStatus, sal_uInt32 uFieldMask) + if (nOffset != m_offset) { - 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 dwBufsize = ELEMENTS_OF_ARRAY(szBuffer); - DWORD dwResult = WNetGetConnection( cDrive, szBuffer, &dwBufsize ); - - if ( NO_ERROR == dwResult ) - { - TCHAR szFileName[ELEMENTS_OF_ARRAY(szBuffer) + 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]; - - if ( GetVolumeInformation( cRoot, szVolumeNameBuffer, ELEMENTS_OF_ARRAY(szVolumeNameBuffer), NULL, NULL, NULL, NULL, 0 ) ) - { - TCHAR szFileName[ELEMENTS_OF_ARRAY(szVolumeNameBuffer) + 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; + LARGE_INTEGER liOffset; liOffset.QuadPart = nOffset; + if (!::SetFilePointerEx (m_hFile, liOffset, 0, FILE_BEGIN)) + return oslTranslateFileError( GetLastError() ); + m_offset = nOffset; } + + DWORD dwDone = 0; + if (!::WriteFile(m_hFile, pBuffer, nBytesToWrite, &dwDone, 0)) + return oslTranslateFileError( GetLastError() ); + m_offset += dwDone; - //##################################################### - 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 ); + m_size = std::max(m_size, sal::static_int_cast< sal_uInt64 >(m_offset)); - pStatus->eType = osl_File_Type_Directory; - pStatus->uValidFields |= osl_FileStatus_Mask_Type; + *pBytesWritten = dwDone; + return osl_File_E_None; +} - if ( uFieldMask & osl_FileStatus_Mask_FileURL ) - { - rtl_uString *ustrSystemPath = NULL; +oslFileError FileHandle_Impl::readFileAt ( + LONGLONG nOffset, + void * pBuffer, + sal_uInt64 uBytesRequested, + sal_uInt64 * pBytesRead) +{ + static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max(); + if (g_limit_dword < uBytesRequested) + return osl_File_E_OVERFLOW; + DWORD nBytesRequested = sal::static_int_cast< DWORD >(uBytesRequested); - rtl_uString_newFromStr( &ustrSystemPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) ); - osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL ); - rtl_uString_release( ustrSystemPath ); - pStatus->uValidFields |= osl_FileStatus_Mask_FileURL; - } + if (0 == (m_state & STATE_SEEKABLE)) + { + // not seekable (pipe) + DWORD dwDone = 0; + if (!::ReadFile(m_hFile, pBuffer, nBytesRequested, &dwDone, 0)) + return oslTranslateFileError( GetLastError() ); + *pBytesRead = dwDone; return osl_File_E_None; } - - typedef struct tagDRIVEENUM { - LPCTSTR lpIdent; - TCHAR cBuffer[/*('Z' - 'A' + 1) * sizeof("A:\\") + 1*/256]; - LPCTSTR lpCurrent; - } DRIVEENUM, * PDRIVEENUM, FAR * LPDRIVEENUM; - - //##################################################### - HANDLE WINAPI OpenLogicalDrivesEnum(void) + else if (0 == m_buffer) { - LPDRIVEENUM pEnum = NULL; - - 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; + // not buffered + return readAt (nOffset, pBuffer, nBytesRequested, pBytesRead); } - - //##################################################### - BOOL WINAPI EnumLogicalDrives(HANDLE hEnum, LPTSTR lpBuffer) + else { - BOOL fSuccess = FALSE; - LPDRIVEENUM pEnum = (LPDRIVEENUM)hEnum; - - if ( pEnum ) + sal_uInt8 * buffer = static_cast< sal_uInt8* >(pBuffer); + for (*pBytesRead = 0; nBytesRequested > 0; ) { - int nLen = _tcslen( pEnum->lpCurrent ); + LONGLONG const bufptr = (nOffset / m_bufsiz) * m_bufsiz; + SIZE_T const bufpos = (nOffset % m_bufsiz); - if ( nLen ) + if (bufptr != m_bufptr) { - 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; - } - - //##################################################### - BOOL WINAPI CloseLogicalDrivesEnum(HANDLE hEnum) - { - BOOL fSuccess = FALSE; - LPDRIVEENUM pEnum = (LPDRIVEENUM)hEnum; + // flush current buffer + oslFileError result = syncFile(); + if (result != osl_File_E_None) + return (result); + m_bufptr = -1, m_buflen = 0; - if ( pEnum ) - { - HeapFree( GetProcessHeap(), 0, pEnum ); - fSuccess = TRUE; - } - else - SetLastError( ERROR_INVALID_HANDLE ); - - return fSuccess; - } - - //##################################################### - //Undocumented in SHELL32.DLL ordinal 35 - BOOL WINAPI PathRemoveFileSpec(LPTSTR lpPath) - { - BOOL fSuccess = FALSE; // Assume failure - LPTSTR lpLastBkSlash = _tcsrchr( lpPath, '\\' ); - LPTSTR lpLastSlash = _tcsrchr( lpPath, '/' ); - LPTSTR lpLastDelimiter = lpLastSlash > lpLastBkSlash ? lpLastSlash : lpLastBkSlash; - - if ( lpLastDelimiter ) - { - if ( 0 == *(lpLastDelimiter + 1) ) - { - if ( lpLastDelimiter > lpPath && *(lpLastDelimiter - 1) != ':' ) + if (nBytesRequested >= m_bufsiz) { - *lpLastDelimiter = 0; - fSuccess = TRUE; + // buffer too small, read through from file + sal_uInt64 uDone = 0; + result = readAt (nOffset, &(buffer[*pBytesRead]), nBytesRequested, &uDone); + if (result != osl_File_E_None) + return (result); + + nBytesRequested -= sal::static_int_cast< DWORD >(uDone), *pBytesRead += uDone; + return osl_File_E_None; } - } - else - { - *(++lpLastDelimiter) = 0; - fSuccess = TRUE; - } - } - return fSuccess; - } - - //##################################################### - // Undocumented in SHELL32.DLL ordinal 32 - LPTSTR WINAPI PathAddBackslash(LPTSTR lpPath) - { - LPTSTR lpEndPath = NULL; - - if ( lpPath ) - { - int nLen = _tcslen(lpPath); - if ( !nLen || lpPath[nLen-1] != '\\' && lpPath[nLen-1] != '/' && nLen < MAX_PATH - 1 ) - { - lpEndPath = lpPath + nLen; - *lpEndPath++ = '\\'; - *lpEndPath = 0; + // update buffer (pointer) + sal_uInt64 uDone = 0; + result = readAt (bufptr, m_buffer, m_bufsiz, &uDone); + if (result != osl_File_E_None) + return (result); + m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone); } - } - return lpEndPath; - } - -#if 1 - //##################################################### - // Same as GetLongPathName but also 95/NT4 - DWORD WINAPI GetCaseCorrectPathNameEx( - LPCTSTR lpszShortPath, // file name - LPTSTR lpszLongPath, // path buffer - DWORD cchBuffer, // size of path buffer - DWORD nSkipLevels - ) - { -// log file doesn't work, because initialization of rtl log init() calls this method... -// RTL_LOGFILE_TRACE1( "SAL: GetCaseCorrectPathNameEx: %s (Skip:%n)", lpszShortPath,nSkipLevels ); - - TCHAR szPath[MAX_PATH]; - BOOL fSuccess; - - cchBuffer = cchBuffer; /* avoid warnings */ - - _tcscpy( szPath, lpszShortPath ); - - fSuccess = PathRemoveFileSpec( szPath ); - - if ( fSuccess ) - { - int nLen = _tcslen( szPath ); - LPCTSTR lpszFileSpec = lpszShortPath + nLen; - BOOL bSkipThis; - - if ( 0 == _tcscmp( lpszFileSpec, TEXT("..") ) ) - { - bSkipThis = TRUE; - nSkipLevels += 1; - } - else if ( - 0 == _tcscmp( lpszFileSpec, TEXT(".") ) || - 0 == _tcscmp( lpszFileSpec, TEXT("\\") ) || - 0 == _tcscmp( lpszFileSpec, TEXT("/") ) - ) + if (bufpos >= m_buflen) { - bSkipThis = TRUE; + // end of file + return osl_File_E_None; } - else if ( nSkipLevels ) - { - bSkipThis = TRUE; - nSkipLevels--; - } - else - bSkipThis = FALSE; - - GetCaseCorrectPathNameEx( szPath, szPath, MAX_PATH, nSkipLevels ); - - PathAddBackslash( szPath ); - - /* Analyze parent if not only a trailing backslash was cutted but a real file spec */ - if ( !bSkipThis ) - { - WIN32_FIND_DATA aFindFileData; - HANDLE hFind = FindFirstFile( lpszShortPath, &aFindFileData ); - - if ( IsValidHandle(hFind) ) - { - _tcscat( szPath, aFindFileData.cFileName[0] ? aFindFileData.cFileName : aFindFileData.cAlternateFileName ); - - FindClose( hFind ); - } - else - return 0; - } - } - else - { - /* File specification can't be removed therefore the short path is either a drive - or a network share. If still levels to skip are left, the path specification - tries to travel below the file system root */ - if ( nSkipLevels ) - return 0; - - _tcsupr( szPath ); - } - - _tcscpy( lpszLongPath, szPath ); - - return _tcslen( lpszLongPath ); - } -#endif - -#if 0 - inline size_t wcstoupper( LPWSTR lpStr ) - { - size_t nLen = wcslen( lpStr ); - for ( LPWSTR p = lpStr; p < lpStr + nLen; p++ ) - { - *p = towupper(*p); + SIZE_T const bytes = std::min(m_buflen - bufpos, nBytesRequested); + memcpy (&(buffer[*pBytesRead]), &(m_buffer[bufpos]), bytes); + nBytesRequested -= bytes, *pBytesRead += bytes, nOffset += bytes; } - - return nLen; + return osl_File_E_None; } +} -#endif +oslFileError FileHandle_Impl::writeFileAt ( + LONGLONG nOffset, + void const * pBuffer, + sal_uInt64 uBytesToWrite, + sal_uInt64 * pBytesWritten) +{ + static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max(); + if (g_limit_dword < uBytesToWrite) + return osl_File_E_OVERFLOW; + DWORD nBytesToWrite = sal::static_int_cast< DWORD >(uBytesToWrite); - //##################################################### - DWORD WINAPI GetCaseCorrectPathName( - LPCTSTR lpszShortPath, // file name - LPTSTR lpszLongPath, // path buffer - DWORD cchBuffer // size of path buffer - ) -#if 0 + if (0 == (m_state & STATE_SEEKABLE)) { - /* Special handling for "\\.\" as system root */ - if ( lpszShortPath && 0 == wcscmp( lpszShortPath, WSTR_SYSTEM_ROOT_PATH ) ) - { - if ( cchBuffer >= ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) ) - { - wcscpy( lpszLongPath, WSTR_SYSTEM_ROOT_PATH ); - return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1; - } - else - return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH); - } - else - { - DWORD nSrcLen = wcslen( lpszShortPath ); - - if ( cchBuffer > nSrcLen ) - { - wcscpy( lpszLongPath, lpszShortPath ); - wcstoupper( lpszLongPath ); - } - else - nSrcLen++; - - return nSrcLen; - } + // not seekable (pipe) + DWORD dwDone = 0; + if (!::WriteFile(m_hFile, pBuffer, nBytesToWrite, &dwDone, 0)) + return oslTranslateFileError( GetLastError() ); + *pBytesWritten = dwDone; + return osl_File_E_None; } -#else + else if (0 == m_buffer) { - /* Special handling for "\\.\" as system root */ - if ( lpszShortPath && 0 == wcscmp( lpszShortPath, WSTR_SYSTEM_ROOT_PATH ) ) - { - if ( cchBuffer >= ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) ) - { - wcscpy( lpszLongPath, WSTR_SYSTEM_ROOT_PATH ); - return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1; - } - else - return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1; - } - else - return GetCaseCorrectPathNameEx( lpszShortPath, lpszLongPath, cchBuffer, 0 ); + // not buffered + return writeAt(nOffset, pBuffer, nBytesToWrite, pBytesWritten); } - -#endif - - //##################################################### - #define CHARSET_SEPARATOR TEXT("\\/") - - BOOL WINAPI IsValidFilePathComponent( - LPCTSTR lpComponent, LPCTSTR *lppComponentEnd, DWORD dwFlags) + else { - LPCTSTR lpComponentEnd = NULL; - LPCTSTR lpCurrent = lpComponent; - BOOL fValid = TRUE; /* Assume success */ - TCHAR cLast = 0; - - /* Path component length must not exceed MAX_PATH */ - - while ( !lpComponentEnd && lpCurrent && lpCurrent - lpComponent < MAX_PATH ) - { - switch ( *lpCurrent ) - { - /* Both backslash and slash determine the end of a path component */ - case '\0': - case '/': - case '\\': - switch ( cLast ) - { - /* Component must not end with '.' or blank and can't be empty */ - - case '.': - if ( dwFlags & VALIDATEPATH_ALLOW_ELLIPSE ) - { - if ( 1 == lpCurrent - lpComponent ) - { - /* Current directory is O.K. */ - lpComponentEnd = lpCurrent; - break; - } - else if ( 2 == lpCurrent - lpComponent && '.' == *lpComponent ) - { - /* Parent directory is O.K. */ - lpComponentEnd = lpCurrent; - break; - } - } - case 0: - case ' ': - lpComponentEnd = lpCurrent - 1; - fValid = FALSE; - break; - default: - lpComponentEnd = lpCurrent; - break; - } - break; - /* '?' and '*' are valid wildcards but not valid file name characters */ - case '?': - case '*': - if ( dwFlags & VALIDATEPATH_ALLOW_WILDCARDS ) - break; - /* The following characters are reserved */ - case '<': - case '>': - case '\"': - case '|': - case ':': - lpComponentEnd = lpCurrent; - fValid = FALSE; - break; - default: - /* Characters below ASCII 32 are not allowed */ - if ( *lpCurrent < ' ' ) - { - lpComponentEnd = lpCurrent; - fValid = FALSE; - } - break; - } - cLast = *lpCurrent++; - } - - /* If we don't reached the end of the component the length of the component was to long - ( See condition of while loop ) */ - if ( !lpComponentEnd ) + sal_uInt8 const * buffer = static_cast< sal_uInt8 const* >(pBuffer); + for (*pBytesWritten = 0; nBytesToWrite > 0; ) { - fValid = FALSE; - lpComponentEnd = lpCurrent; - } - - /* Test wether the component specifies a device name what is not allowed */ - - // MT: PERFORMANCE: - // This is very expensive. A lot of calls to _tcsicmp. - // in SRC6870m71 67.000 calls of this method while empty office start result into more than 1.500.00 calls of _tcsicmp! - // Possible optimizations - // - Array should be const static - // - Sorted array, use binary search - // - More intelligent check for com1-9, lpt1-9 - // Maybe make szComponent upper case, don't search case intensitive - // Talked to HRO: Could be removed. Shouldn't be used in OOo, and if used for something like a filename, it will lead to an error anyway. - /* - if ( fValid ) - { - LPCTSTR alpDeviceNames[] = + LONGLONG const bufptr = (nOffset / m_bufsiz) * m_bufsiz; + SIZE_T const bufpos = (nOffset % m_bufsiz); + if (bufptr != m_bufptr) { - TEXT("CON"), - TEXT("PRN"), - TEXT("AUX"), - TEXT("CLOCK$"), - TEXT("NUL"), - TEXT("LPT1"), - TEXT("LPT2"), - TEXT("LPT3"), - TEXT("LPT4"), - TEXT("LPT5"), - TEXT("LPT6"), - TEXT("LPT7"), - TEXT("LPT8"), - TEXT("LPT9"), - TEXT("COM1"), - TEXT("COM2"), - TEXT("COM3"), - TEXT("COM4"), - TEXT("COM5"), - TEXT("COM6"), - TEXT("COM7"), - TEXT("COM8"), - TEXT("COM9") - }; - - TCHAR szComponent[MAX_PATH]; - int nComponentLength; - LPCTSTR lpDot; - int i; - - // A device name with an extension is also invalid - lpDot = _tcschr( lpComponent, '.' ); - - if ( !lpDot || lpDot > lpComponentEnd ) - nComponentLength = lpComponentEnd - lpComponent; - else - nComponentLength = lpDot - lpComponent; - - _tcsncpy( szComponent, lpComponent, nComponentLength ); - szComponent[nComponentLength] = 0; - - for ( i = 0; i < sizeof( alpDeviceNames ) / sizeof(LPCTSTR); i++ ) - { - if ( 0 == _tcsicmp( szComponent, alpDeviceNames[i] ) ) - { - lpComponentEnd = lpComponent; - fValid = FALSE; - break; - } - } - } - */ - - if ( fValid ) - { - // Empty components are not allowed - if ( lpComponentEnd - lpComponent < 1 ) - fValid = FALSE; - - // If we reached the end of the string NULL is returned - else if ( !*lpComponentEnd ) - lpComponentEnd = NULL; - - } - - if ( lppComponentEnd ) - *lppComponentEnd = lpComponentEnd; - - return fValid; - } - - //##################################################### - DWORD WINAPI IsValidFilePath(rtl_uString *path, LPCTSTR *lppError, DWORD dwFlags, rtl_uString **corrected) - { - LPCTSTR lpszPath = reinterpret_cast< LPCTSTR >(path->buffer); - LPCTSTR lpComponent; - BOOL fValid = TRUE; - DWORD dwPathType = PATHTYPE_ERROR; - - if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE ) - dwFlags |= VALIDATEPATH_ALLOW_ELLIPSE; - - if ( !lpszPath ) - { - fValid = FALSE; - lpComponent = lpszPath; - } - - /* Test for UNC path notation */ - if ( 2 == _tcsspn( lpszPath, CHARSET_SEPARATOR ) ) - { - /* Place the pointer behind the leading to backslashes */ - - lpComponent = lpszPath + 2; - - fValid = IsValidFilePathComponent( lpComponent, &lpComponent, VALIDATEPATH_ALLOW_ELLIPSE ); + // flush current buffer + oslFileError result = syncFile(); + if (result != osl_File_E_None) + return (result); + m_bufptr = -1, m_buflen = 0; - /* So far we have a valid servername. Now let's see if we also have a network resource */ - - dwPathType = PATHTYPE_ABSOLUTE_UNC; - - if ( fValid ) - { - if ( lpComponent && !*++lpComponent ) - lpComponent = NULL; - - if ( !lpComponent ) - { - #if 0 - /* We only have a Server specification what is invalid */ - - lpComponent = lpszPath; - fValid = FALSE; - #else - dwPathType |= PATHTYPE_IS_SERVER; - #endif - } - else + if (nBytesToWrite >= m_bufsiz) { - /* Now test the network resource */ - - fValid = IsValidFilePathComponent( lpComponent, &lpComponent, 0 ); - - /* If we now reached the end of the path, everything is O.K. */ - - - if ( fValid && (!lpComponent || lpComponent && !*++lpComponent ) ) - { - lpComponent = NULL; - dwPathType |= PATHTYPE_IS_VOLUME; - } + // buffer too small, write through to file + sal_uInt64 uDone = 0; + result = writeAt (nOffset, &(buffer[*pBytesWritten]), nBytesToWrite, &uDone); + if (result != osl_File_E_None) + return (result); + if (uDone != nBytesToWrite) + return osl_File_E_IO; + + nBytesToWrite -= sal::static_int_cast< DWORD >(uDone), *pBytesWritten += uDone; + return osl_File_E_None; } - } - } - - /* Local path verification. Must start with <drive>: */ - else if ( _istalpha( lpszPath[0] ) && ':' == lpszPath[1] ) - { - /* Place pointer behind correct drive specification */ - - lpComponent = lpszPath + 2; - - if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) ) - lpComponent++; - else if ( *lpComponent ) - fValid = FALSE; - - dwPathType = PATHTYPE_ABSOLUTE_LOCAL; - - /* Now we are behind the backslash or it was a simple drive without backslash */ - - if ( fValid && !*lpComponent ) - { - lpComponent = NULL; - dwPathType |= PATHTYPE_IS_VOLUME; - } - } - - /* Can be a relative path */ - else if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE ) - { - lpComponent = lpszPath; - - /* Relative path can start with a backslash */ - if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) ) - { - lpComponent++; - if ( !*lpComponent ) - lpComponent = NULL; + // update buffer (pointer) + sal_uInt64 uDone = 0; + result = readAt (bufptr, m_buffer, m_bufsiz, &uDone); + if (result != osl_File_E_None) + return (result); + m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone); } - dwPathType = PATHTYPE_RELATIVE; - } + SIZE_T const bytes = std::min(m_bufsiz - bufpos, nBytesToWrite); + memcpy (&(m_buffer[bufpos]), &(buffer[*pBytesWritten]), bytes); + nBytesToWrite -= bytes, *pBytesWritten += bytes, nOffset += bytes; - /* Anything else is an error */ - else - { - fValid = FALSE; - lpComponent = lpszPath; - } - - /* Now validate each component of the path */ - while ( fValid && lpComponent ) - { - // Correct path by merging consecutive slashes: - if (*lpComponent == '\\' && corrected != NULL) { - sal_Int32 i = lpComponent - lpszPath; - rtl_uString_newReplaceStrAt(corrected, path, i, 1, NULL); - //TODO: handle out-of-memory - lpszPath = reinterpret_cast< LPCTSTR >((*corrected)->buffer); - lpComponent = lpszPath + i; - } - - fValid = IsValidFilePathComponent( lpComponent, &lpComponent, dwFlags ); - - if ( fValid && lpComponent ) - { - lpComponent++; - - /* If the string behind the backslash is empty, we've done */ - - if ( !*lpComponent ) - lpComponent = NULL; - } + m_buflen = std::max(m_buflen, bufpos + bytes); + m_state |= STATE_MODIFIED; } - - if ( fValid && _tcslen( lpszPath ) >= MAX_PATH ) - { - fValid = FALSE; - lpComponent = lpszPath + MAX_PATH; - } - - if ( lppError ) - *lppError = lpComponent; - - return fValid ? dwPathType : PATHTYPE_ERROR; + return osl_File_E_None; } +} - //##################################################### - bool is_floppy_drive(const rtl::OUString& path); - - //##################################################### - struct Component - { - Component() : - begin_(0), end_(0) - {} - - bool isPresent() const - { return (static_cast<sal_Int32>(end_ - begin_) > 0); } - - const sal_Unicode* begin_; - const sal_Unicode* end_; - }; - - //##################################################### - struct UNCComponents - { - Component server_; - Component share_; - Component resource_; - }; - - //##################################################### - const wchar_t UNC_PREFIX[] = L"\\\\"; - const wchar_t BACKSLASH = '\\'; - const wchar_t SLASH = '/'; - - bool is_UNC_path(const sal_Unicode* path) - { return (0 == wcsncmp(UNC_PREFIX, reinterpret_cast<LPCWSTR>(path), ELEMENTS_OF_ARRAY(UNC_PREFIX) - 1)); } - - //##################################################### - 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 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; - } - - //##################################################### - // Has the given path a parent or are we already there, - // e.g. 'c:\' or '\\server\share\'? - bool has_path_parent(const sal_Unicode* path) - { - 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; - } - - //##################################################### - // @see bool has_path_parent(const sal_Unicode* path) - bool has_path_parent(const rtl::OUString& path) - { return has_path_parent(path.getStr()); } - - //##################################################### - 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; - } - - //############################################# - /* 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 */ - int path_make_parent(sal_Unicode* path) - { - 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); - } - - //##################################################### - 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.pData); - } - - //##################################################### - inline bool is_floppy_A_present() - { return (GetLogicalDrives() & 1); } - - //##################################################### - inline bool is_floppy_B_present() - { return (GetLogicalDrives() & 2); } - - //##################################################### - // determines if a volume mount point shows to a floppy - // disk by comparing the unique volume names - const LPWSTR FLOPPY_A = L"A:\\"; - const LPWSTR FLOPPY_B = L"B:\\"; - - bool is_floppy_volume_mount_point(const rtl::OUString& path) - { - rtl::OUString p(path); - osl_systemPathEnsureSeparator(&p.pData); - - 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; - } - - //################################################ - // 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 - LPCWSTR FLOPPY_DRV_LETTERS = TEXT("AaBb"); - - bool is_floppy_drive(const rtl::OUString& path) - { - const sal_Unicode* pf = path.getStr(); - const sal_Unicode* ps = path.getStr() + 1; - return ((wcschr(FLOPPY_DRV_LETTERS, *pf) && (L':' == *ps)) || - is_floppy_volume_mount_point(path)); - } - - //############################################# - 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.pData); - - TCHAR vn[51]; - if (GetVolumeNameForVolumeMountPoint(reinterpret_cast<LPCTSTR>(p.getStr()), vn, ELEMENTS_OF_ARRAY(vn))) - return GetDriveType(vn); - - return DRIVE_NO_ROOT_DIR; - } - - //############################################# - 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 MapError(ERROR_INVALID_DRIVE); - - pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes; +oslFileError FileHandle_Impl::readLineAt ( + LONGLONG nOffset, + sal_Sequence ** ppSequence, + sal_uInt64 * pBytesRead) +{ + oslFileError result = osl_File_E_None; - 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; - } - - //############################################# - 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)); - } - - //############################################# - 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; - } - } - - //############################################# - 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)); - } - - //############################################# - inline bool is_drivetype_request(sal_uInt32 field_mask) - { - return (field_mask & osl_VolumeInfo_Mask_Attributes); - } - - //############################################# - oslFileError get_filesystem_attributes(const rtl::OUString& path, sal_uInt32 field_mask, oslVolumeInfo* pInfo) - { - pInfo->uAttributes = 0; - - oslFileError osl_error = osl_File_E_None; - - // osl_get_drive_type must be called first because - // this function resets osl_VolumeInfo_Mask_Attributes - // on failure - if (is_drivetype_request(field_mask)) - osl_error = osl_get_drive_type(path, pInfo); - - if ((osl_File_E_None == osl_error) && is_filesystem_attributes_request(field_mask)) - { - WCHAR vn[MAX_PATH]; - WCHAR fsn[MAX_PATH]; - DWORD serial; - DWORD mcl; - DWORD flags; - - if (GetVolumeInformation(reinterpret_cast<LPCTSTR>(path.getStr()), vn, MAX_PATH, &serial, &mcl, &flags, fsn, MAX_PATH)) - { - pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength; - pInfo->uMaxNameLength = mcl; - - 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_error; - } - - //############################################# - // Create the specified directory and call the - // user specified callback function. On success - // the function returns ERROR_SUCCESS else a - // Win32 error code. - DWORD create_dir_with_callback( - sal_Unicode* dir_path, - oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc, - void* pData) + LONGLONG bufptr = (nOffset / m_bufsiz) * m_bufsiz; + if (bufptr != m_bufptr) { - if (CreateDirectory(reinterpret_cast<LPCTSTR>(dir_path), NULL)) - { - if (aDirectoryCreationCallbackFunc) - { - rtl::OUString url; - FileBase::getFileURLFromSystemPath(dir_path, url); - aDirectoryCreationCallbackFunc(pData, url.pData); - } - return ERROR_SUCCESS; - } - return GetLastError(); - } + /* flush current buffer */ + result = syncFile(); + if (result != osl_File_E_None) + return (result); - //############################################# - DWORD create_dir_recursively_( - sal_Unicode* dir_path, - oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc, - void* pData) - { - OSL_PRECOND(rtl_ustr_getLength(dir_path) > 0 && (rtl_ustr_lastIndexOfChar(dir_path, BACKSLASH) != rtl_ustr_getLength(dir_path) - 1), \ - "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)) - return w32_error; - - int pos = path_make_parent(dir_path); - - w32_error = create_dir_recursively_( - dir_path, aDirectoryCreationCallbackFunc, pData); - - if (ERROR_SUCCESS != w32_error) - return w32_error; - - dir_path[pos] = BACKSLASH; - - return create_dir_recursively_( - dir_path, aDirectoryCreationCallbackFunc, pData); - } - - //##################################################### - // Temp file - //##################################################### - - - //##################################################### - oslFileError osl_setup_base_directory_impl_( - rtl_uString* pustrDirectoryURL, - rtl_uString** ppustr_base_dir) - { - rtl_uString* dir_url = 0; - rtl_uString* dir = 0; - oslFileError error = osl_File_E_None; - - if (pustrDirectoryURL) - rtl_uString_assign(&dir_url, pustrDirectoryURL); - else - error = osl_getTempDirURL(&dir_url); + /* update buffer (pointer) */ + sal_uInt64 uDone = 0; + result = readAt (bufptr, m_buffer, m_bufsiz, &uDone); + if (result != osl_File_E_None) + return (result); - if (osl_File_E_None == error) - { - error = _osl_getSystemPathFromFileURL(dir_url, &dir, sal_False); - rtl_uString_release(dir_url); - } - - if (osl_File_E_None == error ) - { - rtl_uString_assign(ppustr_base_dir, dir); - rtl_uString_release(dir); - } - - return error; - } - - //##################################################### - oslFileError osl_setup_createTempFile_impl_( - rtl_uString* pustrDirectoryURL, - oslFileHandle* pHandle, - rtl_uString** ppustrTempFileURL, - rtl_uString** ppustr_base_dir, - sal_Bool* b_delete_on_close) - { - oslFileError osl_error; - - OSL_PRECOND(((0 != pHandle) || (0 != ppustrTempFileURL)), "Invalid parameter!"); - - if ((0 == pHandle) && (0 == ppustrTempFileURL)) - { - osl_error = osl_File_E_INVAL; - } - else - { - osl_error = osl_setup_base_directory_impl_( - pustrDirectoryURL, ppustr_base_dir); - - *b_delete_on_close = (sal_Bool)(0 == ppustrTempFileURL); - } - - return osl_error; + m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone); } - //##################################################### - oslFileError osl_win32_GetTempFileName_impl_( - rtl_uString* base_directory, LPWSTR temp_file_name) - { - oslFileError osl_error = osl_File_E_None; - - if (0 == GetTempFileNameW( - reinterpret_cast<LPCWSTR>(rtl_uString_getStr(base_directory)), - L"", - 0, - temp_file_name)) - { - osl_error = MapError(GetLastError()); - } - - return osl_error; - } - - //##################################################### - sal_Bool osl_win32_CreateFile_impl_( - LPCWSTR file_name, sal_Bool b_delete_on_close, oslFileHandle* p_handle) - { - DWORD flags = FILE_ATTRIBUTE_NORMAL; - HANDLE hFile; - - OSL_ASSERT(p_handle); - - if (b_delete_on_close) - flags |= FILE_FLAG_DELETE_ON_CLOSE; - - hFile = CreateFileW( - file_name, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - TRUNCATE_EXISTING, - flags, - NULL); - - if (IsValidHandle(hFile)) - *p_handle = (oslFileHandle)hFile; - - return (sal_Bool)IsValidHandle(hFile); - } + static int const LINE_STATE_BEGIN = 0; + static int const LINE_STATE_CR = 1; + static int const LINE_STATE_LF = 2; - //############################################# - oslFileError osl_createTempFile_impl_( - rtl_uString* base_directory, - LPWSTR tmp_name, - sal_Bool b_delete_on_close, - oslFileHandle* pHandle, - rtl_uString** ppustrTempFileURL) - { - oslFileError osl_error; - - do - { - osl_error = osl_win32_GetTempFileName_impl_(base_directory, tmp_name); - - /* if file could not be opened try again */ - - if ((osl_File_E_None != osl_error) || (0 == pHandle) || - osl_win32_CreateFile_impl_(tmp_name, b_delete_on_close, pHandle)) - break; - - } while(1); // try until success - - if ((osl_File_E_None == osl_error) && !b_delete_on_close) - { - rtl_uString* pustr = 0; - rtl_uString_newFromStr(&pustr, reinterpret_cast<const sal_Unicode*>(tmp_name)); - osl_getFileURLFromSystemPath(pustr, ppustrTempFileURL); - rtl_uString_release(pustr); - } - - return osl_error; - } - - //##################################################### - // End Temp file - //##################################################### + SIZE_T bufpos = sal::static_int_cast< SIZE_T >(nOffset - m_bufptr), curpos = bufpos, dstpos = 0; + int state = (bufpos >= m_buflen) ? LINE_STATE_LF : LINE_STATE_BEGIN; - - //############################################# - sal_Bool _osl_decodeURL( rtl_String* strUTF8, rtl_uString** pstrDecodedURL ) + for ( ; state != LINE_STATE_LF; ) { - sal_Char *pBuffer; - const sal_Char *pSrcEnd; - const sal_Char *pSrc; - sal_Char *pDest; - sal_Int32 nSrcLen; - sal_Bool bValidEncoded = sal_True; /* Assume success */ - - /* The resulting decoded string length is shorter or equal to the source length */ - - nSrcLen = rtl_string_getLength(strUTF8); - pBuffer = reinterpret_cast<sal_Char*>(rtl_allocateMemory(nSrcLen + 1)); - - pDest = pBuffer; - pSrc = rtl_string_getStr(strUTF8); - pSrcEnd = pSrc + nSrcLen; - - /* Now decode the URL what should result in an UTF8 string */ - while ( bValidEncoded && pSrc < pSrcEnd ) + if (curpos >= m_buflen) { - switch ( *pSrc ) + /* buffer examined */ + if (0 < (curpos - bufpos)) { - case '%': - { - sal_Char aToken[3]; - sal_Char aChar; - - pSrc++; - aToken[0] = *pSrc++; - aToken[1] = *pSrc++; - aToken[2] = 0; - - aChar = (sal_Char)strtoul( aToken, NULL, 16 ); - - /* The chars are path delimiters and must not be encoded */ - - if ( 0 == aChar || '\\' == aChar || '/' == aChar || ':' == aChar ) - bValidEncoded = sal_False; - else - *pDest++ = aChar; - } - break; - default: - *pDest++ = *pSrc++; - break; + /* flush buffer to sequence */ + result = writeSequence_Impl ( + ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos); + if (result != osl_File_E_None) + return (result); + *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos; } - } - - *pDest++ = 0; - - if ( bValidEncoded ) { - rtl_string2UString( pstrDecodedURL, pBuffer, rtl_str_getLength(pBuffer), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS ); - OSL_ASSERT(*pstrDecodedURL != 0); - } - - rtl_freeMemory( pBuffer ); - return bValidEncoded; - } - - //############################################# - void _osl_encodeURL( rtl_uString *strURL, rtl_String **pstrEncodedURL ) - { - /* Encode non ascii characters within the URL */ - - rtl_String *strUTF8 = NULL; - sal_Char *pszEncodedURL; - const sal_Char *pURLScan; - sal_Char *pURLDest; - sal_Int32 nURLScanLen; - sal_Int32 nURLScanCount; - - rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS ); - - pszEncodedURL = (sal_Char*) rtl_allocateMemory( (rtl_string_getLength( strUTF8 ) * 3 + 1) * sizeof(sal_Char) ); - - pURLDest = pszEncodedURL; - pURLScan = rtl_string_getStr( strUTF8 ); - nURLScanLen = rtl_string_getLength( strUTF8 ); - nURLScanCount = 0; - - while ( nURLScanCount < nURLScanLen ) - { - sal_Char cCurrent = *pURLScan; - - switch ( cCurrent ) + bufptr = nOffset / m_bufsiz * m_bufsiz; + if (bufptr != m_bufptr) { - default: - if (!( ( cCurrent >= 'a' && cCurrent <= 'z' ) || ( cCurrent >= 'A' && cCurrent <= 'Z' ) || ( cCurrent >= '0' && cCurrent <= '9' ) ) ) - { - sprintf( pURLDest, "%%%02X", (unsigned char)cCurrent ); - pURLDest += 3; - break; - } - case '!': - case '\'': - case '(': - case ')': - case '*': - case '-': - case '.': - case '_': - case '~': - case '$': - case '&': - case '+': - case ',': - case '=': - case '@': - case ':': - case '/': - case '\\': - case '|': - *pURLDest++ = cCurrent; - break; - case 0: - break; + /* update buffer (pointer) */ + sal_uInt64 uDone = 0; + result = readAt (bufptr, m_buffer, m_bufsiz, &uDone); + if (result != osl_File_E_None) + return (result); + m_bufptr = bufptr, m_buflen = sal::static_int_cast< SIZE_T >(uDone); } - pURLScan++; - nURLScanCount++; + bufpos = sal::static_int_cast< SIZE_T >(nOffset - m_bufptr), curpos = bufpos; + if (bufpos >= m_buflen) + break; } - - - *pURLDest = 0; - - rtl_string_release( strUTF8 ); - rtl_string_newFromStr( pstrEncodedURL, pszEncodedURL ); - rtl_freeMemory( pszEncodedURL ); - } - - //############################################# - oslFileError SAL_CALL _osl_getSystemPathFromFileURL( rtl_uString *strURL, rtl_uString **pustrPath, sal_Bool bAllowRelative ) - { - rtl_String *strUTF8 = NULL; - rtl_uString *strDecodedURL = NULL; - rtl_uString *strTempPath = NULL; - const sal_Unicode *pDecodedURL; - sal_uInt32 nDecodedLen; - sal_Bool bValidEncoded; - oslFileError nError = osl_File_E_INVAL; /* Assume failure */ - - /* If someone hasn't encoded the complete URL we convert it to UTF8 now to prevent from - having a mixed encoded URL later */ - - rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS ); - - /* If the length of strUTF8 and strURL differs it indicates that the URL was not correct encoded */ - - OSL_ENSURE_FILE( - strUTF8->length == strURL->length || - 0 != rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( strURL->buffer, strURL->length, "file:\\\\", 7 ) - ,"osl_getSystemPathFromFileURL: \"%s\" is not encoded !!!", strURL ); - - bValidEncoded = _osl_decodeURL( strUTF8, &strDecodedURL ); - - /* Release the encoded UTF8 string */ - - rtl_string_release( strUTF8 ); - - - if ( bValidEncoded ) + switch (state) { - /* Replace backslashes and pipes */ - - rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '/', '\\' ); - rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '|', ':' ); - - pDecodedURL = rtl_uString_getStr( strDecodedURL ); - nDecodedLen = rtl_uString_getLength( strDecodedURL ); - - /* Must start with "file://" */ - - if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\", 7 ) ) - { - sal_uInt32 nSkip; - - if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\\\", 8 ) ) - nSkip = 8; - else if ( - 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\localhost\\", 17 ) || - 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\127.0.0.1\\", 17 ) - ) - nSkip = 17; - else - nSkip = 5; - - /* Indicates local root */ - if ( nDecodedLen == nSkip ) - rtl_uString_newFromStr_WithLength( &strTempPath, reinterpret_cast<const sal_Unicode*>(WSTR_SYSTEM_ROOT_PATH), ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1 ); - else - rtl_uString_newFromStr_WithLength( &strTempPath, pDecodedURL + nSkip, nDecodedLen - nSkip ); - - if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) ) - nError = osl_File_E_None; - } - else if ( bAllowRelative ) /* This maybe a relative file URL */ + case LINE_STATE_CR: + state = LINE_STATE_LF; + switch (m_buffer[curpos]) { - rtl_uString_assign( &strTempPath, strDecodedURL ); - - if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_RELATIVE | VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) ) - nError = osl_File_E_None; + case 0x0A: /* CRLF */ + /* eat current char */ + curpos++; + break; + default: /* single CR */ + /* keep current char */ + break; } - /* - else - OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not an absolute FileURL !!!", strURL ); - */ - - } - - if ( strDecodedURL ) - rtl_uString_release( strDecodedURL ); - - if ( osl_File_E_None == nError ) - rtl_uString_assign( pustrPath, strTempPath ); - - if ( strTempPath ) - rtl_uString_release( strTempPath ); - - /* - OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not a FileURL !!!", strURL ); - */ - - return nError; - } - - //############################################# - oslFileError SAL_CALL _osl_getFileURLFromSystemPath( rtl_uString* strPath, rtl_uString** pstrURL ) - { - oslFileError nError = osl_File_E_INVAL; /* Assume failure */ - rtl_uString *strTempURL = NULL; - DWORD dwPathType = PATHTYPE_ERROR; - - if (strPath) - dwPathType = IsValidFilePath(strPath, NULL, VALIDATEPATH_ALLOW_RELATIVE, NULL); - - if (dwPathType) - { - rtl_uString *strTempPath = NULL; - - /* Replace backslashes */ - - rtl_uString_newReplace( &strTempPath, strPath, '\\', '/' ); - - switch ( dwPathType & PATHTYPE_MASK_TYPE ) + break; + default: + /* determine next state */ + switch (m_buffer[curpos]) { - case PATHTYPE_RELATIVE: - rtl_uString_assign( &strTempURL, strTempPath ); - nError = osl_File_E_None; - break; - case PATHTYPE_ABSOLUTE_UNC: - rtl_uString_newFromAscii( &strTempURL, "file:" ); - rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath ); - nError = osl_File_E_None; + case 0x0A: /* single LF */ + state = LINE_STATE_LF; break; - case PATHTYPE_ABSOLUTE_LOCAL: - rtl_uString_newFromAscii( &strTempURL, "file:///" ); - rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath ); - nError = osl_File_E_None; + case 0x0D: /* CR */ + state = LINE_STATE_CR; break; - default: + default: /* advance to next char */ + curpos++; break; } - - /* Release temp path */ - - rtl_uString_release( strTempPath ); - } - - if ( osl_File_E_None == nError ) - { - rtl_String *strEncodedURL = NULL; - - /* Encode the URL */ - - _osl_encodeURL( strTempURL, &strEncodedURL ); - - /* Provide URL via unicode string */ - - rtl_string2UString( pstrURL, rtl_string_getStr(strEncodedURL), rtl_string_getLength(strEncodedURL), RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS ); - OSL_ASSERT(*pstrURL != 0); - rtl_string_release( strEncodedURL ); - } - - /* Release temp URL */ - - if ( strTempURL ) - rtl_uString_release( strTempURL ); - - /* - OSL_ENSURE_FILE( !nError, "osl_getFileURLFromSystemPath: \"%s\" is not a systemPath !!!", strPath ); - */ - - return nError; - } - -#if OSL_DEBUG_LEVEL > 0 - - //##################################################### - void _osl_warnFile( const char *message, rtl_uString *ustrFile ) - { - char szBuffer[2048]; - - if (ustrFile) - { - rtl_String *strFile = NULL; - - rtl_uString2String( &strFile, rtl_uString_getStr( ustrFile ), rtl_uString_getLength( ustrFile ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS ); - snprintf( szBuffer, sizeof(szBuffer), message, strFile->buffer ); - rtl_string_release( strFile ); - - message = szBuffer; + if (state != LINE_STATE_BEGIN) + { + /* store (and eat) the newline char */ + m_buffer[curpos] = 0x0A, curpos++; + + /* flush buffer to sequence */ + result = writeSequence_Impl ( + ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos - 1); + if (result != osl_File_E_None) + return (result); + *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos; + } + break; } - OSL_ENSURE( 0, message ); } -#endif // OSL_DEBUG_LEVEL > 0 - -} // end namespace private - - -//##################################################### -// Exported OSL API -//##################################################### - - -//############################################# -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); - } - + result = writeSequence_Impl (ppSequence, &dstpos, 0, 0); + if (result != osl_File_E_None) + return (result); + if (0 < dstpos) + return osl_File_E_None; + if (bufpos >= m_buflen) + return osl_File_E_AGAIN; return osl_File_E_None; } - -//############################################# -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; - - 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 MapError(create_dir_recursively_( - sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData)); -} - -//############################################# -oslFileError SAL_CALL osl_createTempFile( - rtl_uString* pustrDirectoryURL, - oslFileHandle* pHandle, - rtl_uString** ppustrTempFileURL) +oslFileError FileHandle_Impl::writeSequence_Impl ( + sal_Sequence ** ppSequence, + SIZE_T * pnOffset, + const void * pBuffer, + SIZE_T nBytes) { - rtl_uString* base_directory = 0; - LPWSTR tmp_name; - sal_Bool b_delete_on_close; - oslFileError osl_error; - - osl_error = osl_setup_createTempFile_impl_( - pustrDirectoryURL, - pHandle, - ppustrTempFileURL, - &base_directory, - &b_delete_on_close); - - if (osl_File_E_None != osl_error) - return osl_error; - - /* allocate enough space on the stack */ - STACK_ALLOC(tmp_name, WCHAR, (rtl_uString_getLength(base_directory) + MAX_PATH)); - - if (tmp_name) + sal_Int32 nElements = *pnOffset + nBytes; + if (!*ppSequence) { - osl_createTempFile_impl_( - base_directory, - tmp_name, - b_delete_on_close, - pHandle, - ppustrTempFileURL); + /* construct sequence */ + rtl_byte_sequence_constructNoDefault(ppSequence, nElements); } - else // stack alloc failed + else if (nElements != (*ppSequence)->nElements) { - osl_error = osl_File_E_NOMEM; + /* resize sequence */ + rtl_byte_sequence_realloc(ppSequence, nElements); } - - if (base_directory) - rtl_uString_release(base_directory); - - return osl_error; -} - -//############################################# -oslFileError SAL_CALL osl_getTempDirURL(rtl_uString** pustrTempDir) -{ - WCHAR szBuffer[MAX_PATH]; - LPWSTR lpBuffer = szBuffer; - DWORD nBufferLength = ELEMENTS_OF_ARRAY(szBuffer) - 1; - - DWORD nLength; - oslFileError error; - - do - { - nLength = GetTempPathW( ELEMENTS_OF_ARRAY(szBuffer), lpBuffer ); - if ( nLength > nBufferLength ) - { - nLength++; - lpBuffer = reinterpret_cast<WCHAR*>(alloca( sizeof(WCHAR) * nLength )); - nBufferLength = nLength - 1; - } - } while ( nLength > nBufferLength ); - - if ( nLength ) + if (*ppSequence != 0) { - rtl_uString *ustrTempPath = NULL; - - if ( '\\' == lpBuffer[nLength-1] ) - lpBuffer[nLength-1] = 0; - - rtl_uString_newFromStr( &ustrTempPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) ); - - error = osl_getFileURLFromSystemPath( ustrTempPath, pustrTempDir ); - - rtl_uString_release( ustrTempPath ); + /* fill sequence */ + memcpy(&((*ppSequence)->elements[*pnOffset]), pBuffer, nBytes), *pnOffset += nBytes; } - else - error = MapError( GetLastError() ); - - return error; + return (*ppSequence != 0) ? osl_File_E_None : osl_File_E_NOMEM; } +oslFileError FileHandle_Impl::syncFile() +{ + oslFileError result = osl_File_E_None; + if (m_state & STATE_MODIFIED) + { + sal_uInt64 uDone = 0; + result = writeAt (m_bufptr, m_buffer, m_buflen, &uDone); + if (result != osl_File_E_None) + return (result); + if (uDone != m_buflen) + return osl_File_E_IO; + m_state &= ~STATE_MODIFIED; + } + return (result); +} + //################################################################## -// File handling functions +// File I/O functions //################################################################## - - -//############################################# -oslFileError SAL_CALL osl_openFile( - rtl_uString *strPath, oslFileHandle *pHandle, sal_uInt32 uFlags ) + +extern "C" oslFileHandle +SAL_CALL osl_createFileHandleFromOSHandle ( + HANDLE hFile, + sal_uInt32 uFlags) { - rtl_uString *strSysPath = NULL; - oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False ); + if ( !IsValidHandle(hFile) ) + return 0; // EINVAL - if ( osl_File_E_None == error ) + FileHandle_Impl * pImpl = new FileHandle_Impl(hFile); + if (pImpl == 0) { - DWORD dwAccess = 0, dwShare = FILE_SHARE_READ, dwCreation = 0, dwAttributes = 0; - HANDLE hFile; - - if ( uFlags & osl_File_OpenFlag_Read ) - dwAccess |= GENERIC_READ; - - if ( uFlags & osl_File_OpenFlag_Write ) - dwAccess |= GENERIC_WRITE; - else - dwShare |= FILE_SHARE_WRITE; - - if ( uFlags & osl_File_OpenFlag_NoLock ) - dwShare |= FILE_SHARE_WRITE; - - if ( uFlags & osl_File_OpenFlag_Create ) - dwCreation |= CREATE_NEW; - else - dwCreation |= OPEN_EXISTING; - - hFile = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )), dwAccess, dwShare, NULL, dwCreation, dwAttributes, NULL ); - - *pHandle = osl_createFileHandleFromOSHandle( hFile ); - - if ( !IsValidHandle( hFile ) ) - error = MapError( GetLastError() ); - - rtl_uString_release( strSysPath ); + // cleanup and fail + (void) ::CloseHandle(hFile); + return 0; // ENOMEM } - return error; -} - -//############################################# -oslFileError SAL_CALL osl_syncFile(oslFileHandle Handle) -{ - if (!IsValidHandle((HANDLE)Handle)) - return osl_File_E_INVAL; - - if (!FlushFileBuffers((HANDLE)Handle)) - return MapError(GetLastError()); - - return osl_File_E_None; -} + /* check for regular file */ + if (FILE_TYPE_DISK == GetFileType(hFile)) + { + /* mark seekable */ + pImpl->m_state |= FileHandle_Impl::STATE_SEEKABLE; -//############################################# -oslFileError SAL_CALL osl_closeFile(oslFileHandle Handle) -{ - oslFileError error; - HANDLE hFile = (HANDLE)Handle; + /* init current size */ + LARGE_INTEGER uSize = { 0, 0 }; + (void) ::GetFileSizeEx(hFile, &uSize); + pImpl->m_size = (sal::static_int_cast<sal_uInt64>(uSize.HighPart) << 32) + uSize.LowPart; + } - if ( IsValidHandle(hFile) ) - error = CloseHandle( hFile ) ? osl_File_E_None : MapError( GetLastError() ); - else - error = osl_File_E_INVAL; + if (!(uFlags & osl_File_OpenFlag_Read)) + pImpl->m_state &= ~FileHandle_Impl::STATE_READABLE; + if (!(uFlags & osl_File_OpenFlag_Write)) + pImpl->m_state &= ~FileHandle_Impl::STATE_WRITEABLE; - return error; + OSL_POSTCOND( + (uFlags & osl_File_OpenFlag_Read) || (uFlags & osl_File_OpenFlag_Write), + "osl_createFileHandleFromOSHandle(): missing read/write access flags"); + return (oslFileHandle)(pImpl); } //############################################# -oslFileError SAL_CALL osl_isEndOfFile(oslFileHandle Handle, sal_Bool *pIsEOF) +oslFileError +SAL_CALL osl_openFile( + rtl_uString * strPath, + oslFileHandle * pHandle, + sal_uInt32 uFlags ) { - oslFileError error = osl_File_E_INVAL; - HANDLE hFile = (HANDLE)Handle; - - if ( IsValidHandle(hFile) ) - { - LONG lDistanceToMove, lDistanceToMoveHigh; - sal_uInt64 nCurPos; - - /* Return value INVALID_SET_FILE_POINTER is no error indication and LastError could - be set from previous IO call */ - - SetLastError( NOERROR ); + rtl_uString * strSysPath = 0; + oslFileError result = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False ); + if (result != osl_File_E_None) + return (result); - lDistanceToMoveHigh = 0; - lDistanceToMove = SetFilePointer( hFile, 0, &lDistanceToMoveHigh, FILE_CURRENT ); + DWORD dwAccess = GENERIC_READ, dwShare = FILE_SHARE_READ, dwCreation = 0, dwAttributes = 0; - error = MapError( GetLastError() ); - - if ( osl_File_E_None == error ) - { - nCurPos = (sal_uInt64)lDistanceToMove + ((sal_uInt64)lDistanceToMoveHigh << 32); + if ( uFlags & osl_File_OpenFlag_Write ) + dwAccess |= GENERIC_WRITE; + else + dwShare |= FILE_SHARE_WRITE; - lDistanceToMoveHigh = 0; - lDistanceToMove = SetFilePointer( hFile, 0, &lDistanceToMoveHigh, FILE_END ); + if ( uFlags & osl_File_OpenFlag_NoLock ) + dwShare |= FILE_SHARE_WRITE; - error = MapError( GetLastError() ); + if ( uFlags & osl_File_OpenFlag_Create ) + dwCreation |= CREATE_NEW; + else + dwCreation |= OPEN_EXISTING; - if ( osl_File_E_None == error ) - { - sal_uInt64 nEndPos = (sal_uInt64)lDistanceToMove + ((sal_uInt64)lDistanceToMoveHigh << 32); + HANDLE hFile = CreateFileW( + reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )), + dwAccess, dwShare, NULL, dwCreation, dwAttributes, NULL ); - *pIsEOF = (sal_Bool)(nEndPos == nCurPos); + // @@@ ERROR HANDLING @@@ + if ( !IsValidHandle( hFile ) ) + result = oslTranslateFileError( GetLastError() ); - lDistanceToMoveHigh = (LONG)(nCurPos >> 32); - SetFilePointer( hFile, (LONG)(nCurPos & 0xFFFFFFFF), &lDistanceToMoveHigh, FILE_BEGIN ); + *pHandle = osl_createFileHandleFromOSHandle (hFile, uFlags | osl_File_OpenFlag_Read); - error = MapError( GetLastError() ); - } - } - } - return error; + rtl_uString_release( strSysPath ); + return (result); } //############################################# -oslFileError SAL_CALL osl_setFilePos(oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos) +oslFileError +SAL_CALL osl_syncFile(oslFileHandle Handle) { - HANDLE hFile = (HANDLE)Handle; - if (!IsValidHandle(hFile)) + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile)) return osl_File_E_INVAL; - DWORD dwMoveMethod = 0; - switch ( uHow ) - { - case osl_Pos_Current: - dwMoveMethod = FILE_CURRENT; - break; - case osl_Pos_End: - dwMoveMethod = FILE_END; - break; - case osl_Pos_Absolut: - default: - dwMoveMethod = FILE_BEGIN; - break; - } + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); - LONG nOffsetLo = sal::static_int_cast<LONG>(uPos & 0xFFFFFFFF); - LONG nOffsetHi = sal::static_int_cast<LONG>(uPos >> 32); + oslFileError result = pImpl->syncFile(); + if (result != osl_File_E_None) + return result; - SetLastError(0); - DWORD dwPosLo = SetFilePointer( hFile, nOffsetLo, &nOffsetHi, dwMoveMethod ); - if (INVALID_SET_FILE_POINTER == dwPosLo) - { - DWORD dwError = GetLastError(); - if (NO_ERROR != dwError) - return MapError( dwError ); - } + if (!FlushFileBuffers(pImpl->m_hFile)) + return oslTranslateFileError(GetLastError()); + return osl_File_E_None; } //############################################# -oslFileError SAL_CALL osl_getFilePos(oslFileHandle Handle, sal_uInt64 *pPos) +oslFileError +SAL_CALL osl_closeFile(oslFileHandle Handle) { - oslFileError error; - HANDLE hFile = (HANDLE)Handle; - - if ( IsValidHandle(hFile) ) - { - LONG lDistanceToMove, lDistanceToMoveHigh; - - /* Return value INVALID_SET_FILE_POINTER is no error indication and LastError could - be set from previous IO call */ - - SetLastError( NOERROR ); - - lDistanceToMoveHigh = 0; - lDistanceToMove = SetFilePointer( hFile, 0, &lDistanceToMoveHigh, FILE_CURRENT ); - - error = MapError( GetLastError() ); - - if ( osl_File_E_None == error ) - *pPos = (sal_uInt64)lDistanceToMove + ((sal_uInt64)lDistanceToMoveHigh << 32); - } - else - error = osl_File_E_INVAL; - - return error; -} - -//############################################# -oslFileError SAL_CALL osl_getFileSize(oslFileHandle Handle, sal_uInt64 *pSize) -{ - HANDLE hFile = (HANDLE)Handle; - if ( !IsValidHandle(hFile) ) + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile)) return osl_File_E_INVAL; - DWORD nSize = GetFileSize(hFile, NULL); - if (nSize == INVALID_FILE_SIZE) + ::EnterCriticalSection (&(pImpl->m_mutex)); + + oslFileError result = pImpl->syncFile(); + if (result != osl_File_E_None) { - DWORD nError = GetLastError(); - if (nError != NO_ERROR) - return MapError(nError); + /* ignore double failure */ + (void)::CloseHandle(pImpl->m_hFile); } - - *pSize = (sal_uInt64)(nSize); - return osl_File_E_None; -} - -oslFileError SAL_CALL osl_setFileSize(oslFileHandle Handle, sal_uInt64 uSize) -{ - oslFileError error = osl_setFilePos( Handle, osl_Pos_Absolut, uSize ); - if ( osl_File_E_None == error ) + else if (!::CloseHandle(pImpl->m_hFile)) { - if ( !SetEndOfFile( (HANDLE)Handle ) ) - error = MapError( osl_File_E_None ); + /* translate error code */ + result = oslTranslateFileError( GetLastError() ); } - return error; + ::LeaveCriticalSection (&(pImpl->m_mutex)); + delete pImpl; + return (result); } //############################################# -oslFileError SAL_CALL osl_mapFile( +oslFileError +SAL_CALL osl_mapFile( oslFileHandle Handle, void** ppAddr, sal_uInt64 uLength, @@ -2710,8 +816,8 @@ oslFileError SAL_CALL osl_mapFile( } }; - HANDLE hFile = (HANDLE)(Handle); - if (!IsValidHandle(hFile) || (0 == ppAddr)) + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == ppAddr)) return osl_File_E_INVAL; *ppAddr = 0; @@ -2727,16 +833,16 @@ oslFileError SAL_CALL osl_mapFile( if (VER_PLATFORM_WIN32_NT != osinfo.dwPlatformId) return osl_File_E_NOSYS; // Unsupported - FileMapping aMap( ::CreateFileMapping (hFile, NULL, SEC_COMMIT | PAGE_READONLY, 0, 0, NULL) ); + FileMapping aMap( ::CreateFileMapping (pImpl->m_hFile, NULL, SEC_COMMIT | PAGE_READONLY, 0, 0, NULL) ); if (!IsValidHandle(aMap.m_handle)) - return MapError( GetLastError() ); + return oslTranslateFileError( GetLastError() ); DWORD const dwOffsetHi = sal::static_int_cast<DWORD>(uOffset >> 32); DWORD const dwOffsetLo = sal::static_int_cast<DWORD>(uOffset & 0xFFFFFFFF); *ppAddr = ::MapViewOfFile( aMap.m_handle, FILE_MAP_READ, dwOffsetHi, dwOffsetLo, nLength ); if (0 == *ppAddr) - return MapError( GetLastError() ); + return oslTranslateFileError( GetLastError() ); if (uFlags & osl_File_MapFlag_RandomAccess) { @@ -2770,977 +876,319 @@ oslFileError SAL_CALL osl_mapFile( } //############################################# -oslFileError SAL_CALL osl_unmapFile(void* pAddr, sal_uInt64 /* uLength */) +oslFileError +SAL_CALL osl_unmapFile(void* pAddr, sal_uInt64 /* uLength */) { if (0 == pAddr) return osl_File_E_INVAL; if (!::UnmapViewOfFile (pAddr)) - return MapError( GetLastError() ); + return oslTranslateFileError( GetLastError() ); return osl_File_E_None; } //############################################# -oslFileError SAL_CALL osl_readFile( - oslFileHandle Handle, - void *pBuffer, - sal_uInt64 uBytesRequested, - sal_uInt64 *pBytesRead ) +oslFileError +SAL_CALL osl_readLine( + oslFileHandle Handle, + sal_Sequence ** ppSequence) { - oslFileError error; - HANDLE hFile = (HANDLE)Handle; - - if ( IsValidHandle(hFile) ) - { - DWORD dwBytesToRead = (DWORD)uBytesRequested; - DWORD dwBytesRead; + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == ppSequence)) + return osl_File_E_INVAL; + sal_uInt64 uBytesRead = 0; + + // read at current filepos; filepos += uBytesRead; + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + oslFileError result = pImpl->readLineAt ( + pImpl->m_filepos, ppSequence, &uBytesRead); + if (result == osl_File_E_None) + pImpl->m_filepos += uBytesRead; + return (result); +} - if ( ReadFile( hFile, pBuffer, dwBytesToRead, &dwBytesRead, NULL ) ) - { - *pBytesRead = (sal_uInt64)dwBytesRead; - error = osl_File_E_None; - } - else - error = MapError( GetLastError() ); - } - else - error = osl_File_E_INVAL; +//############################################# +oslFileError +SAL_CALL osl_readFile( + oslFileHandle Handle, + void * pBuffer, + sal_uInt64 uBytesRequested, + sal_uInt64 * pBytesRead) +{ + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesRead)) + return osl_File_E_INVAL; - return error; + // read at current filepos; filepos += *pBytesRead; + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + oslFileError result = pImpl->readFileAt ( + pImpl->m_filepos, pBuffer, uBytesRequested, pBytesRead); + if (result == osl_File_E_None) + pImpl->m_filepos += *pBytesRead; + return (result); } //############################################# -oslFileError SAL_CALL osl_writeFile( +oslFileError +SAL_CALL osl_writeFile( oslFileHandle Handle, - const void *pBuffer, - sal_uInt64 uBytesToWrite, - sal_uInt64 *pBytesWritten ) + const void * pBuffer, + sal_uInt64 uBytesToWrite, + sal_uInt64 * pBytesWritten ) { - oslFileError error; - HANDLE hFile = (HANDLE)Handle; - - if ( IsValidHandle(hFile) ) - { - DWORD dwBytesToWrite = (DWORD)uBytesToWrite; - DWORD dwBytesWritten; + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); - if ( WriteFile( hFile, pBuffer, dwBytesToWrite, &dwBytesWritten, NULL ) ) - { - *pBytesWritten = (sal_uInt64)dwBytesWritten; - error = osl_File_E_None; - } - else - error = MapError( GetLastError() ); - } - else - error = osl_File_E_INVAL; + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesWritten)) + return osl_File_E_INVAL; - return error; + // write at current filepos; filepos += *pBytesWritten; + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + oslFileError result = pImpl->writeFileAt ( + pImpl->m_filepos, pBuffer, uBytesToWrite, pBytesWritten); + if (result == osl_File_E_None) + pImpl->m_filepos += *pBytesWritten; + return (result); } //############################################# -oslFileError SAL_CALL osl_readFileAt( +oslFileError +SAL_CALL osl_readFileAt( oslFileHandle Handle, sal_uInt64 uOffset, void* pBuffer, sal_uInt64 uBytesRequested, sal_uInt64* pBytesRead) { - HANDLE hFile = (HANDLE)(Handle); - if (!IsValidHandle(hFile) || (0 == pBuffer)) - return osl_File_E_INVAL; - - static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max(); - if (g_limit_dword < uBytesRequested) - return osl_File_E_OVERFLOW; - DWORD const dwBytes = sal::static_int_cast< DWORD >(uBytesRequested); + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); - if (0 == pBytesRead) + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesRead)) return osl_File_E_INVAL; - *pBytesRead = 0; + if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE)) + return osl_File_E_SPIPE; - oslFileError error = osl_setFilePos(Handle, osl_Pos_Absolut, uOffset); - if (osl_File_E_None != error) - return error; - - DWORD dwDone = 0; - if (!::ReadFile(hFile, pBuffer, dwBytes, &dwDone, NULL)) - return MapError( GetLastError() ); + static sal_uInt64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max(); + if (g_limit_longlong < uOffset) + return osl_File_E_OVERFLOW; + LONGLONG const nOffset = sal::static_int_cast< LONGLONG >(uOffset); - *pBytesRead = dwDone; - return osl_File_E_None; + // read at specified fileptr + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + return pImpl->readFileAt (nOffset, pBuffer, uBytesRequested, pBytesRead); } //############################################# -oslFileError SAL_CALL osl_writeFileAt( +oslFileError +SAL_CALL osl_writeFileAt( oslFileHandle Handle, sal_uInt64 uOffset, const void* pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64* pBytesWritten) { - HANDLE hFile = (HANDLE)(Handle); - if (!IsValidHandle(hFile) || (0 == pBuffer)) - return osl_File_E_INVAL; - - static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max(); - if (g_limit_dword < uBytesToWrite) - return osl_File_E_OVERFLOW; - DWORD const dwBytes = sal::static_int_cast< DWORD >(uBytesToWrite); + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); - if (0 == pBytesWritten) + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pBuffer) || (0 == pBytesWritten)) return osl_File_E_INVAL; - *pBytesWritten = 0; + if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE)) + return osl_File_E_SPIPE; - oslFileError error = osl_setFilePos(Handle, osl_Pos_Absolut, uOffset); - if (osl_File_E_None != error) - return error; - - DWORD dwDone = 0; - if (!::WriteFile(hFile, pBuffer, dwBytes, &dwDone, NULL)) - return MapError( GetLastError() ); - - *pBytesWritten = dwDone; - return osl_File_E_None; -} - -//############################################# -oslFileError SAL_CALL osl_removeFile( rtl_uString* strPath ) -{ - rtl_uString *strSysPath = NULL; - oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False ); - - if ( osl_File_E_None == error ) - { - if ( DeleteFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )) ) ) - error = osl_File_E_None; - else - error = MapError( GetLastError() ); + static sal_uInt64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max(); + if (g_limit_longlong < uOffset) + return osl_File_E_OVERFLOW; + LONGLONG const nOffset = sal::static_int_cast< LONGLONG >(uOffset); - rtl_uString_release( strSysPath ); - } - return error; + // write at specified fileptr + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + return pImpl->writeFileAt (nOffset, pBuffer, uBytesToWrite, pBytesWritten); } //############################################# -#define osl_File_CopyRecursive 0x0001 -#define osl_File_CopyOverwrite 0x0002 - -oslFileError SAL_CALL osl_copyFile( rtl_uString* strPath, rtl_uString *strDestPath ) +oslFileError +SAL_CALL osl_isEndOfFile (oslFileHandle Handle, sal_Bool *pIsEOF) { - rtl_uString *strSysPath = NULL, *strSysDestPath = NULL; - oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False ); + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); - if ( osl_File_E_None == error ) - error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False ); - - if ( osl_File_E_None == error ) - { - if ( CopyFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )), reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath )), FALSE ) ) - error = osl_File_E_None; - else - error = MapError( GetLastError() ); - } - - if ( strSysPath ) - rtl_uString_release( strSysPath ); - if ( strSysDestPath ) - rtl_uString_release( strSysDestPath ); + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pIsEOF)) + return osl_File_E_INVAL; - return error; + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + *pIsEOF = (pImpl->getPos() == pImpl->getSize()); + return osl_File_E_None; } //############################################# -oslFileError SAL_CALL osl_moveFile( rtl_uString* strPath, rtl_uString *strDestPath ) +oslFileError +SAL_CALL osl_getFilePos(oslFileHandle Handle, sal_uInt64 *pPos) { - rtl_uString *strSysPath = NULL, *strSysDestPath = NULL; - oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False ); - - if ( osl_File_E_None == error ) - error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False ); - - if ( osl_File_E_None == error ) - { - if ( MoveFileEx( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )), reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING ) ) - error = osl_File_E_None; - else - error = MapError( GetLastError() ); - } - - if ( strSysPath ) - rtl_uString_release( strSysPath ); - if ( strSysDestPath ) - rtl_uString_release( strSysDestPath ); + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pPos)) + return osl_File_E_INVAL; - return error; + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + *pPos = pImpl->getPos(); + return osl_File_E_None; } //############################################# -oslFileError SAL_CALL osl_setFileAttributes( - rtl_uString *ustrFileURL, - sal_uInt64 uAttributes ) +oslFileError +SAL_CALL osl_setFilePos(oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uOffset) { - 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; + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile)) + return osl_File_E_INVAL; - dwFileAttributes = GetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)) ); + static sal_Int64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max(); + if (g_limit_longlong < uOffset) + return osl_File_E_OVERFLOW; + LONGLONG nPos = 0, nOffset = sal::static_int_cast< LONGLONG >(uOffset); - if ( (DWORD)-1 != dwFileAttributes ) + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + switch (uHow) { - dwFileAttributes &= ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN); + case osl_Pos_Absolut: + if (0 > nOffset) + return osl_File_E_INVAL; + break; - if ( uAttributes & osl_File_Attribute_ReadOnly ) - dwFileAttributes |= FILE_ATTRIBUTE_READONLY; + case osl_Pos_Current: + nPos = sal::static_int_cast< LONGLONG >(pImpl->getPos()); + if ((0 > nOffset) && (-1*nOffset > nPos)) + return osl_File_E_INVAL; + if (g_limit_longlong < nPos + nOffset) + return osl_File_E_OVERFLOW; + break; - if ( uAttributes & osl_File_Attribute_Hidden ) - dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN; + case osl_Pos_End: + nPos = sal::static_int_cast< LONGLONG >(pImpl->getSize()); + if ((0 > nOffset) && (-1*nOffset > nPos)) + return osl_File_E_INVAL; + if (g_limit_longlong < nPos + nOffset) + return osl_File_E_OVERFLOW; + break; - fSuccess = SetFileAttributes( reinterpret_cast<LPCTSTR>(rtl_uString_getStr(ustrSysPath)), dwFileAttributes ); + default: + return osl_File_E_INVAL; } - else - fSuccess = FALSE; - - if ( !fSuccess ) - error = MapError( GetLastError() ); - rtl_uString_release( ustrSysPath ); - - return error; + return pImpl->setPos (nPos + nOffset); } -//##################################################### -oslFileError SAL_CALL osl_setFileTime( - rtl_uString *filePath, - const TimeValue *aCreationTime, - const TimeValue *aLastAccessTime, - const TimeValue *aLastWriteTime) +//############################################# +oslFileError +SAL_CALL osl_getFileSize (oslFileHandle Handle, sal_uInt64 *pSize) { - 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; + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); - 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) + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile) || (0 == pSize)) return osl_File_E_INVAL; - else - return osl_File_E_None; + + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + *pSize = pImpl->getSize(); + return osl_File_E_None; } -//##################################################### -oslFileError SAL_CALL osl_getFileStatus( - oslDirectoryItem Item, - oslFileStatus *pStatus, - sal_uInt32 uFieldMask ) +//############################################# +oslFileError +SAL_CALL osl_setFileSize (oslFileHandle Handle, sal_uInt64 uSize) { - 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( pItemImpl->szFullPath, &pItemImpl->FindData ); + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); - if ( hFind != INVALID_HANDLE_VALUE ) - FindClose( hFind ); - else - return MapError( 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) ) + if ((0 == pImpl) || !IsValidHandle(pImpl->m_hFile)) return osl_File_E_INVAL; + if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE)) + return osl_File_E_BADF; - 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 ) - { - rtl_uString *ustrFullPath = NULL; - - rtl_uString_newFromStr( &ustrFullPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) ); - osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrLinkTargetURL ); - rtl_uString_release( ustrFullPath ); - - pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL; - } - - if ( uFieldMask & osl_FileStatus_Mask_FileURL ) - { - rtl_uString *ustrFullPath = NULL; + static sal_uInt64 const g_limit_longlong = std::numeric_limits< LONGLONG >::max(); + if (g_limit_longlong < uSize) + return osl_File_E_OVERFLOW; + FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); + oslFileError result = pImpl->syncFile(); + if (result != osl_File_E_None) + return (result); + pImpl->m_bufptr = -1, pImpl->m_buflen = 0; - if ( !pItemImpl->bFullPathNormalized ) - { - GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) ); - pItemImpl->bFullPathNormalized = TRUE; - } - rtl_uString_newFromStr( &ustrFullPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) ); - osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrFileURL ); - rtl_uString_release( ustrFullPath ); - pStatus->uValidFields |= osl_FileStatus_Mask_FileURL; - } - - return osl_File_E_None; + return pImpl->setSize (uSize); } //################################################################## -// directory handling functions +// File handling functions //################################################################## - - -//##################################################### -oslFileError SAL_CALL osl_createDirectory(rtl_uString* strPath) + +//############################################# +oslFileError SAL_CALL osl_removeFile( rtl_uString* strPath ) { rtl_uString *strSysPath = NULL; oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False ); if ( osl_File_E_None == error ) { - if ( CreateDirectoryW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )), NULL ) ) + if ( DeleteFile( reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )) ) ) error = osl_File_E_None; -/*@@@ToDo - The else 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! -*/ else - { - 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 = MapError( GetLastError() ); - } + error = oslTranslateFileError( GetLastError() ); rtl_uString_release( strSysPath ); } return error; } -//##################################################### -oslFileError SAL_CALL osl_removeDirectory(rtl_uString* strPath) +//############################################# +#define osl_File_CopyRecursive 0x0001 +#define osl_File_CopyOverwrite 0x0002 + +oslFileError SAL_CALL osl_copyFile( rtl_uString* strPath, rtl_uString *strDestPath ) { - rtl_uString *strSysPath = NULL; + rtl_uString *strSysPath = NULL, *strSysDestPath = 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 = MapError( GetLastError() ); - - rtl_uString_release( strSysPath ); - } - return error; -} - -//##################################################### -oslFileError SAL_CALL osl_openDirectory(rtl_uString *strDirectoryPath, oslDirectory *pDirectory) -{ - oslFileError error; + error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False ); - if ( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase( strDirectoryPath->buffer, "file:///" ) ) - error = osl_openLocalRoot( strDirectoryPath, pDirectory ); - else + if ( osl_File_E_None == error ) { - rtl_uString *strSysDirectoryPath = NULL; -// WCHAR szCorrectedPathName[MAX_PATH]; - DWORD dwPathType; + LPCTSTR src = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )); + LPCTSTR dst = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath )); - error = _osl_getSystemPathFromFileURL( strDirectoryPath, &strSysDirectoryPath, sal_False ); - - if ( osl_File_E_None != error ) - return error; - - // MT Perform05 - /* - if ( GetCaseCorrectPathName( strSysDirectoryPath->buffer, szCorrectedPathName, MAX_PATH ) ) - { - rtl_uString_newFromStr( &strSysDirectoryPath, szCorrectedPathName ); - } - */ - - dwPathType = IsValidFilePath( strSysDirectoryPath, NULL, VALIDATEPATH_NORMAL, NULL ); - - if ( dwPathType & PATHTYPE_IS_SERVER ) - { - error = osl_openNetworkServer( strSysDirectoryPath, pDirectory ); - } + if ( CopyFile( src, dst, FALSE ) ) + error = osl_File_E_None; else - error = osl_openFileDirectory( strSysDirectoryPath, pDirectory ); - - rtl_uString_release( strSysDirectoryPath ); - } - return error; -} - -//##################################################### -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 : MapError( GetLastError() ); - break; - case DIRECTORYTYPE_LOCALROOT: - eError = CloseLogicalDrivesEnum( pDirImpl->hEnumDrives ) ? osl_File_E_None : MapError( GetLastError() ); - break; - case DIRECTORYTYPE_NETROOT: - { - DWORD err = WNetCloseEnum(pDirImpl->hDirectory); - eError = (err == NO_ERROR) ? osl_File_E_None : MapError(err); - } - break; - default: - OSL_ENSURE( 0, "Invalid directory type" ); - break; - } - - rtl_freeMemory(pDirImpl); - } - return eError; -} - -//##################################################### -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; -// TCHAR szCorrectedPathName[MAX_PATH]; - - /* 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; - - // MT: I can't imagine a case where this is good for! - /* - if ( GetCaseCorrectPathName( strSysFilePath->buffer, szCorrectedPathName, MAX_PATH ) ) - { - rtl_uString_newFromStr( &strSysFilePath, szCorrectedPathName ); + error = oslTranslateFileError( GetLastError() ); } - */ - - 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 ); - - _tcscpy( pItemImpl->szFullPath, reinterpret_cast<LPCTSTR>(strSysFilePath->buffer) ); - - // 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) ); - _tcscpy( pItemImpl->szFullPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(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 = MapError( GetLastError() ); - } - break; - } - - if ( strSysFilePath ) - rtl_uString_release( strSysFilePath ); + if ( strSysPath ) + rtl_uString_release( strSysPath ); + if ( strSysDestPath ) + rtl_uString_release( strSysDestPath ); 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 ) - rtl_freeMemory( pItemImpl ); - return osl_File_E_None; -} - -//##################################################### -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; -} - - -//################################################################## -// FileURL functions -//################################################################## - - -//##################################################### -oslFileError SAL_CALL osl_getFileURLFromSystemPath( - rtl_uString* ustrPath, rtl_uString** pustrURL ) -{ - return _osl_getFileURLFromSystemPath( ustrPath, pustrURL ); -} - -//##################################################### -oslFileError SAL_CALL osl_getSystemPathFromFileURL( - rtl_uString *ustrURL, rtl_uString **pustrPath) -{ - return _osl_getSystemPathFromFileURL( ustrURL, pustrPath, sal_True ); -} - -//##################################################### -oslFileError SAL_CALL osl_searchFileURL( - rtl_uString *ustrFileName, - rtl_uString *ustrSystemSearchPath, - rtl_uString **pustrPath) +//############################################# +oslFileError SAL_CALL osl_moveFile( rtl_uString* strPath, rtl_uString *strDestPath ) { - rtl_uString *ustrUNCPath = NULL; - rtl_uString *ustrSysPath = NULL; - oslFileError error; - - /* First try to interpret the file name as an URL even a relative one */ - error = _osl_getSystemPathFromFileURL( ustrFileName, &ustrUNCPath, sal_True ); + rtl_uString *strSysPath = NULL, *strSysDestPath = NULL; + oslFileError error = _osl_getSystemPathFromFileURL( strPath, &strSysPath, sal_False ); - /* So far we either have an UNC path or something invalid - Now create a system path */ if ( osl_File_E_None == error ) - error = _osl_getSystemPathFromFileURL( ustrUNCPath, &ustrSysPath, sal_True ); + error = _osl_getSystemPathFromFileURL( strDestPath, &strSysDestPath, sal_False ); if ( osl_File_E_None == error ) { - DWORD nBufferLength; - DWORD dwResult; - LPTSTR lpBuffer = NULL; - LPTSTR lpszFilePart; - - /* Repeat calling SearchPath ... - Start with MAX_PATH for the buffer. In most cases this - will be enough and does not force the loop to runtwice */ - dwResult = MAX_PATH; - - do - { - /* If search path is empty use a NULL pointer instead according to MSDN documentation of SearchPath */ - LPCTSTR lpszSearchPath = ustrSystemSearchPath && ustrSystemSearchPath->length ? reinterpret_cast<LPCTSTR>(ustrSystemSearchPath->buffer) : NULL; - LPCTSTR lpszSearchFile = reinterpret_cast<LPCTSTR>(ustrSysPath->buffer); - - /* Allocate space for buffer according to previous returned count of required chars */ - /* +1 is not neccessary if we follow MSDN documentation but for robustness we do so */ - nBufferLength = dwResult + 1; - lpBuffer = lpBuffer ? - reinterpret_cast<LPTSTR>(rtl_reallocateMemory(lpBuffer, nBufferLength * sizeof(TCHAR))) : - reinterpret_cast<LPTSTR>(rtl_allocateMemory(nBufferLength * sizeof(TCHAR))); + LPCTSTR src = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysPath )); + LPCTSTR dst = reinterpret_cast<LPCTSTR>(rtl_uString_getStr( strSysDestPath )); - dwResult = SearchPath( lpszSearchPath, lpszSearchFile, NULL, nBufferLength, lpBuffer, &lpszFilePart ); - } while ( dwResult && dwResult >= nBufferLength ); - - /* ... until an error occures or buffer is large enough. - dwResult == nBufferLength can not happen according to documentation but lets be robust ;-) */ - - if ( dwResult ) - { - rtl_uString_newFromStr( &ustrSysPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) ); - error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath ); - } + if ( MoveFileEx( src, dst, MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING ) ) + error = osl_File_E_None; else - { - WIN32_FIND_DATA aFindFileData; - HANDLE hFind; - - /* Somthing went wrong, perhaps the path was absolute */ - error = MapError( GetLastError() ); - - hFind = FindFirstFile( reinterpret_cast<LPCTSTR>(ustrSysPath->buffer), &aFindFileData ); - - if ( IsValidHandle(hFind) ) - { - error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath ); - FindClose( hFind ); - } - } - - rtl_freeMemory( lpBuffer ); + error = oslTranslateFileError( GetLastError() ); } - - if ( ustrSysPath ) - rtl_uString_release( ustrSysPath ); - if ( ustrUNCPath ) - rtl_uString_release( ustrUNCPath ); + if ( strSysPath ) + rtl_uString_release( strSysPath ); + if ( strSysDestPath ) + rtl_uString_release( strSysDestPath ); return error; } - -//##################################################### - -oslFileError SAL_CALL osl_getAbsoluteFileURL( rtl_uString* ustrBaseURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL ) -{ - oslFileError eError; - rtl_uString *ustrRelSysPath = NULL; - rtl_uString *ustrBaseSysPath = NULL; - - if ( ustrBaseURL && ustrBaseURL->length ) - { - eError = _osl_getSystemPathFromFileURL( ustrBaseURL, &ustrBaseSysPath, sal_False ); - OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with relative or invalid base URL" ); - - eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_True ); - } - else - { - eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_False ); - OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with empty base URL and/or invalid relative URL" ); - } - - if ( !eError ) - { - TCHAR szBuffer[MAX_PATH]; - TCHAR szCurrentDir[MAX_PATH]; - LPTSTR lpFilePart = NULL; - DWORD dwResult; - -/*@@@ToDo - Bad, bad hack, this only works if the base path - really exists which is not necessary according - to RFC2396 - The whole FileURL implementation should be merged - with the rtl/uri class. -*/ - if ( ustrBaseSysPath ) - { - osl_acquireMutex( g_CurrentDirectoryMutex ); - - GetCurrentDirectory( MAX_PATH, szCurrentDir ); - SetCurrentDirectory( reinterpret_cast<LPCTSTR>(ustrBaseSysPath->buffer) ); - } - - dwResult = GetFullPathName( reinterpret_cast<LPCTSTR>(ustrRelSysPath->buffer), MAX_PATH, szBuffer, &lpFilePart ); - - if ( ustrBaseSysPath ) - { - SetCurrentDirectory( szCurrentDir ); - - osl_releaseMutex( g_CurrentDirectoryMutex ); - } - - if ( dwResult ) - { - if ( dwResult >= MAX_PATH ) - eError = osl_File_E_INVAL; - else - { - rtl_uString *ustrAbsSysPath = NULL; - - rtl_uString_newFromStr( &ustrAbsSysPath, reinterpret_cast<const sal_Unicode*>(szBuffer) ); - - eError = osl_getFileURLFromSystemPath( ustrAbsSysPath, pustrAbsoluteURL ); - - if ( ustrAbsSysPath ) - rtl_uString_release( ustrAbsSysPath ); - } - } - else - eError = MapError( GetLastError() ); - } - - if ( ustrBaseSysPath ) - rtl_uString_release( ustrBaseSysPath ); - - if ( ustrRelSysPath ) - rtl_uString_release( ustrRelSysPath ); - - return eError; -} - -//##################################################### -oslFileError SAL_CALL osl_getCanonicalName( rtl_uString *strRequested, rtl_uString **strValid ) -{ - rtl_uString_newFromString(strValid, strRequested); - return osl_File_E_None; -} diff --git a/sal/osl/w32/file_dirvol.cxx b/sal/osl/w32/file_dirvol.cxx new file mode 100644 index 000000000..c307a634c --- /dev/null +++ b/sal/osl/w32/file_dirvol.cxx @@ -0,0 +1,1867 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 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; + } + } + } + } + + 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 neccessary */ + + /* @@@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 neccessary */ + + /* @@@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; +} diff --git a/sal/osl/w32/file_error.c b/sal/osl/w32/file_error.c new file mode 100644 index 000000000..790255145 --- /dev/null +++ b/sal/osl/w32/file_error.c @@ -0,0 +1,151 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define UNICODE +#define _UNICODE +#define _WIN32_WINNT_0x0500 +#include "systools/win32/uwinapi.h" + +#include "file_error.h" + +#include "osl/diagnose.h" +#include "osl/thread.h" + +/* OS error to oslFileError values mapping table */ +struct osl_file_error_entry +{ + unsigned long oscode; /* OS return value */ + int errnocode; /* oslFileError code */ +}; + +static const struct osl_file_error_entry errtable[] = { + { ERROR_SUCCESS, osl_File_E_None }, /* 0 */ + { ERROR_INVALID_FUNCTION, osl_File_E_INVAL }, /* 1 */ + { ERROR_FILE_NOT_FOUND, osl_File_E_NOENT }, /* 2 */ + { ERROR_PATH_NOT_FOUND, osl_File_E_NOENT }, /* 3 */ + { ERROR_TOO_MANY_OPEN_FILES, osl_File_E_MFILE }, /* 4 */ + { ERROR_ACCESS_DENIED, osl_File_E_ACCES }, /* 5 */ + { ERROR_INVALID_HANDLE, osl_File_E_BADF }, /* 6 */ + { ERROR_ARENA_TRASHED, osl_File_E_NOMEM }, /* 7 */ + { ERROR_NOT_ENOUGH_MEMORY, osl_File_E_NOMEM }, /* 8 */ + { ERROR_INVALID_BLOCK, osl_File_E_NOMEM }, /* 9 */ + { ERROR_BAD_ENVIRONMENT, osl_File_E_2BIG }, /* 10 */ + { ERROR_BAD_FORMAT, osl_File_E_NOEXEC }, /* 11 */ + { ERROR_INVALID_ACCESS, osl_File_E_INVAL }, /* 12 */ + { ERROR_INVALID_DATA, osl_File_E_INVAL }, /* 13 */ + { ERROR_INVALID_DRIVE, osl_File_E_NOENT }, /* 15 */ + { ERROR_CURRENT_DIRECTORY, osl_File_E_ACCES }, /* 16 */ + { ERROR_NOT_SAME_DEVICE, osl_File_E_XDEV }, /* 17 */ + { ERROR_NO_MORE_FILES, osl_File_E_NOENT }, /* 18 */ + { ERROR_NOT_READY, osl_File_E_NOTREADY }, /* 21 */ + { ERROR_LOCK_VIOLATION, osl_File_E_ACCES }, /* 33 */ + { ERROR_BAD_NETPATH, osl_File_E_NOENT }, /* 53 */ + { ERROR_NETWORK_ACCESS_DENIED, osl_File_E_ACCES }, /* 65 */ + { ERROR_BAD_NET_NAME, osl_File_E_NOENT }, /* 67 */ + { ERROR_FILE_EXISTS, osl_File_E_EXIST }, /* 80 */ + { ERROR_CANNOT_MAKE, osl_File_E_ACCES }, /* 82 */ + { ERROR_FAIL_I24, osl_File_E_ACCES }, /* 83 */ + { ERROR_INVALID_PARAMETER, osl_File_E_INVAL }, /* 87 */ + { ERROR_NO_PROC_SLOTS, osl_File_E_AGAIN }, /* 89 */ + { ERROR_DRIVE_LOCKED, osl_File_E_ACCES }, /* 108 */ + { ERROR_BROKEN_PIPE, osl_File_E_PIPE }, /* 109 */ + { ERROR_DISK_FULL, osl_File_E_NOSPC }, /* 112 */ + { ERROR_INVALID_TARGET_HANDLE, osl_File_E_BADF }, /* 114 */ + { ERROR_INVALID_HANDLE, osl_File_E_INVAL }, /* 124 */ + { ERROR_WAIT_NO_CHILDREN, osl_File_E_CHILD }, /* 128 */ + { ERROR_CHILD_NOT_COMPLETE, osl_File_E_CHILD }, /* 129 */ + { ERROR_DIRECT_ACCESS_HANDLE, osl_File_E_BADF }, /* 130 */ + { ERROR_NEGATIVE_SEEK, osl_File_E_INVAL }, /* 131 */ + { ERROR_SEEK_ON_DEVICE, osl_File_E_ACCES }, /* 132 */ + { ERROR_DIR_NOT_EMPTY, osl_File_E_NOTEMPTY }, /* 145 */ + { ERROR_NOT_LOCKED, osl_File_E_ACCES }, /* 158 */ + { ERROR_BAD_PATHNAME, osl_File_E_NOENT }, /* 161 */ + { ERROR_MAX_THRDS_REACHED, osl_File_E_AGAIN }, /* 164 */ + { ERROR_LOCK_FAILED, osl_File_E_ACCES }, /* 167 */ + { ERROR_ALREADY_EXISTS, osl_File_E_EXIST }, /* 183 */ + { ERROR_FILENAME_EXCED_RANGE, osl_File_E_NOENT }, /* 206 */ + { ERROR_NESTING_NOT_ALLOWED, osl_File_E_AGAIN }, /* 215 */ + { ERROR_DIRECTORY, osl_File_E_NOENT }, /* 267 */ + { ERROR_NOT_ENOUGH_QUOTA, osl_File_E_NOMEM }, /* 1816 */ + { ERROR_UNEXP_NET_ERR, osl_File_E_NETWORK } /* 59 */ +}; + +/* The following two constants must be the minimum and maximum + values in the (contiguous) range of osl_File_E_xec Failure errors. +*/ +#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG +#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN + +/* These are the low and high value in the range of errors that are + access violations +*/ +#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT +#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED + +oslFileError oslTranslateFileError (/*DWORD*/ unsigned long dwError) +{ + static const int n = sizeof(errtable)/sizeof(errtable[0]); + + int i; + for (i = 0; i < n; ++i ) + { + if (dwError == errtable[i].oscode) + return (oslFileError)(errtable[i].errnocode); + } + + /* The error code wasn't in the table. We check for a range of + osl_File_E_ACCES errors or exec failure errors (ENOEXEC). + Otherwise osl_File_E_INVAL is returned. + */ + if ( (dwError >= MIN_EACCES_RANGE) && (dwError <= MAX_EACCES_RANGE) ) + return osl_File_E_ACCES; + else if ( (dwError >= MIN_EXEC_ERROR) && (dwError <= MAX_EXEC_ERROR) ) + return osl_File_E_NOEXEC; + else + return osl_File_E_INVAL; +} + +//##################################################### +#if OSL_DEBUG_LEVEL > 0 +void _osl_warnFile( const char *message, rtl_uString *ustrFile ) +{ + char szBuffer[2048]; + + if (ustrFile) + { + rtl_String *strFile = NULL; + + rtl_uString2String( &strFile, rtl_uString_getStr( ustrFile ), rtl_uString_getLength( ustrFile ), + osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS ); + snprintf( szBuffer, sizeof(szBuffer), message, strFile->buffer ); + rtl_string_release( strFile ); + + message = szBuffer; + } + OSL_ENSURE( 0, message ); +} +#endif /* OSL_DEBUG_LEVEL */ diff --git a/sal/osl/w32/file_error.h b/sal/osl/w32/file_error.h new file mode 100644 index 000000000..be4d75cdb --- /dev/null +++ b/sal/osl/w32/file_error.h @@ -0,0 +1,51 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_OSL_FILE_ERROR_H +#define INCLUDED_OSL_FILE_ERROR_H + +#include "osl/file.h" +#include "rtl/ustring.h" + +#ifdef __cplusplus +extern "C" { +#endif + +oslFileError oslTranslateFileError (/*DWORD*/ unsigned long dwError); + +#if OSL_DEBUG_LEVEL > 0 +void _osl_warnFile (const char * message, rtl_uString * ustrFile); +#define OSL_ENSURE_FILE( cond, msg, file ) ( (cond) ? (void)0 : _osl_warnFile( msg, file ) ) +#else +#define OSL_ENSURE_FILE( cond, msg, file ) ((void)0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDED_OSL_FILE_ERROR_H */ diff --git a/sal/osl/w32/file_url.cxx b/sal/osl/w32/file_url.cxx new file mode 100644 index 000000000..246874a42 --- /dev/null +++ b/sal/osl/w32/file_url.cxx @@ -0,0 +1,1143 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define UNICODE +#define _UNICODE +#define _WIN32_WINNT_0x0500 +#include "systools/win32/uwinapi.h" + +#include "file_url.h" +#include "file_error.h" + +#include "rtl/alloc.h" +#include "osl/diagnose.h" +#include "osl/file.h" +#include "osl/mutex.h" + +#include "path_helper.hxx" + +#include <stdio.h> +#include <tchar.h> + +#if OSL_DEBUG_LEVEL > 0 +#define OSL_ENSURE_FILE( cond, msg, file ) ( (cond) ? (void)0 : _osl_warnFile( msg, file ) ) +#else +#define OSL_ENSURE_FILE( cond, msg, file ) ((void)0) +#endif + +#define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0]))) + +#define WSTR_SYSTEM_ROOT_PATH L"\\\\.\\" +#define WSTR_LONG_PATH_PREFIX L"\\\\?\\" +#define WSTR_LONG_PATH_PREFIX_UNC L"\\\\?\\UNC\\" + + +//################################################################## +// FileURL functions +//################################################################## + +extern "C" oslMutex g_CurrentDirectoryMutex; /* Initialized in dllentry.c */ +oslMutex g_CurrentDirectoryMutex = 0; + +//##################################################### +static BOOL IsValidFilePathComponent( + LPCTSTR lpComponent, LPCTSTR *lppComponentEnd, DWORD dwFlags) +{ + LPCTSTR lpComponentEnd = NULL; + LPCTSTR lpCurrent = lpComponent; + BOOL fValid = TRUE; /* Assume success */ + TCHAR cLast = 0; + + /* Path component length must not exceed MAX_PATH even if long path with "\\?\" prefix is used */ + + while ( !lpComponentEnd && lpCurrent && lpCurrent - lpComponent < MAX_PATH ) + { + switch ( *lpCurrent ) + { + /* Both backslash and slash determine the end of a path component */ + case '\0': + case '/': + case '\\': + switch ( cLast ) + { + /* Component must not end with '.' or blank and can't be empty */ + + case '.': + if ( dwFlags & VALIDATEPATH_ALLOW_ELLIPSE ) + { + if ( 1 == lpCurrent - lpComponent ) + { + /* Current directory is O.K. */ + lpComponentEnd = lpCurrent; + break; + } + else if ( 2 == lpCurrent - lpComponent && '.' == *lpComponent ) + { + /* Parent directory is O.K. */ + lpComponentEnd = lpCurrent; + break; + } + } + case 0: + case ' ': + lpComponentEnd = lpCurrent - 1; + fValid = FALSE; + break; + default: + lpComponentEnd = lpCurrent; + break; + } + break; + /* '?' and '*' are valid wildcards but not valid file name characters */ + case '?': + case '*': + if ( dwFlags & VALIDATEPATH_ALLOW_WILDCARDS ) + break; + /* The following characters are reserved */ + case '<': + case '>': + case '\"': + case '|': + case ':': + lpComponentEnd = lpCurrent; + fValid = FALSE; + break; + default: + /* Characters below ASCII 32 are not allowed */ + if ( *lpCurrent < ' ' ) + { + lpComponentEnd = lpCurrent; + fValid = FALSE; + } + break; + } + cLast = *lpCurrent++; + } + + /* If we don't reached the end of the component the length of the component was to long + ( See condition of while loop ) */ + if ( !lpComponentEnd ) + { + fValid = FALSE; + lpComponentEnd = lpCurrent; + } + + /* Test wether the component specifies a device name what is not allowed */ + + // MT: PERFORMANCE: + // This is very expensive. A lot of calls to _tcsicmp. + // in SRC6870m71 67.000 calls of this method while empty office start result into more than 1.500.00 calls of _tcsicmp! + // Possible optimizations + // - Array should be const static + // - Sorted array, use binary search + // - More intelligent check for com1-9, lpt1-9 + // Maybe make szComponent upper case, don't search case intensitive + // Talked to HRO: Could be removed. Shouldn't be used in OOo, and if used for something like a filename, it will lead to an error anyway. + /* + if ( fValid ) + { + LPCTSTR alpDeviceNames[] = + { + TEXT("CON"), + TEXT("PRN"), + TEXT("AUX"), + TEXT("CLOCK$"), + TEXT("NUL"), + TEXT("LPT1"), + TEXT("LPT2"), + TEXT("LPT3"), + TEXT("LPT4"), + TEXT("LPT5"), + TEXT("LPT6"), + TEXT("LPT7"), + TEXT("LPT8"), + TEXT("LPT9"), + TEXT("COM1"), + TEXT("COM2"), + TEXT("COM3"), + TEXT("COM4"), + TEXT("COM5"), + TEXT("COM6"), + TEXT("COM7"), + TEXT("COM8"), + TEXT("COM9") + }; + + TCHAR szComponent[MAX_PATH]; + int nComponentLength; + LPCTSTR lpDot; + int i; + + // A device name with an extension is also invalid + lpDot = _tcschr( lpComponent, '.' ); + + if ( !lpDot || lpDot > lpComponentEnd ) + nComponentLength = lpComponentEnd - lpComponent; + else + nComponentLength = lpDot - lpComponent; + + _tcsncpy( szComponent, lpComponent, nComponentLength ); + szComponent[nComponentLength] = 0; + + for ( i = 0; i < sizeof( alpDeviceNames ) / sizeof(LPCTSTR); i++ ) + { + if ( 0 == _tcsicmp( szComponent, alpDeviceNames[i] ) ) + { + lpComponentEnd = lpComponent; + fValid = FALSE; + break; + } + } + } + */ + + if ( fValid ) + { + // Empty components are not allowed + if ( lpComponentEnd - lpComponent < 1 ) + fValid = FALSE; + + // If we reached the end of the string NULL is returned + else if ( !*lpComponentEnd ) + lpComponentEnd = NULL; + + } + + if ( lppComponentEnd ) + *lppComponentEnd = lpComponentEnd; + + return fValid; +} + +//##################################################### +#define CHARSET_SEPARATOR TEXT("\\/") + +DWORD IsValidFilePath(rtl_uString *path, LPCTSTR *lppError, DWORD dwFlags, rtl_uString **corrected) +{ + LPCTSTR lpszPath = reinterpret_cast< LPCTSTR >(path->buffer); + LPCTSTR lpComponent = lpszPath; + BOOL fValid = TRUE; + DWORD dwPathType = PATHTYPE_ERROR; + sal_Int32 nLength = rtl_uString_getLength( path ); + + if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE ) + dwFlags |= VALIDATEPATH_ALLOW_ELLIPSE; + + if ( !lpszPath ) + fValid = FALSE; + + DWORD dwCandidatPathType = PATHTYPE_ERROR; + + if ( 0 == rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( path->buffer, nLength, reinterpret_cast<const sal_Unicode *>(WSTR_LONG_PATH_PREFIX_UNC), ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX_UNC) - 1, ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX_UNC) - 1 ) ) + { + /* This is long path in UNC notation */ + lpComponent = lpszPath + ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX_UNC) - 1; + dwCandidatPathType = PATHTYPE_ABSOLUTE_UNC | PATHTYPE_IS_LONGPATH; + } + else if ( 0 == rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( path->buffer, nLength, reinterpret_cast<const sal_Unicode *>(WSTR_LONG_PATH_PREFIX), ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1, ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1 ) ) + { + /* This is long path */ + lpComponent = lpszPath + ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1; + + if ( _istalpha( lpComponent[0] ) && ':' == lpComponent[1] ) + { + lpComponent += 2; + dwCandidatPathType = PATHTYPE_ABSOLUTE_LOCAL | PATHTYPE_IS_LONGPATH; + } + } + else if ( 2 == _tcsspn( lpszPath, CHARSET_SEPARATOR ) ) + { + /* The UNC path notation */ + lpComponent = lpszPath + 2; + dwCandidatPathType = PATHTYPE_ABSOLUTE_UNC; + } + else if ( _istalpha( lpszPath[0] ) && ':' == lpszPath[1] ) + { + /* Local path verification. Must start with <drive>: */ + lpComponent = lpszPath + 2; + dwCandidatPathType = PATHTYPE_ABSOLUTE_LOCAL; + } + + if ( ( dwCandidatPathType & PATHTYPE_MASK_TYPE ) == PATHTYPE_ABSOLUTE_UNC ) + { + fValid = IsValidFilePathComponent( lpComponent, &lpComponent, VALIDATEPATH_ALLOW_ELLIPSE ); + + /* So far we have a valid servername. Now let's see if we also have a network resource */ + + dwPathType = dwCandidatPathType; + + if ( fValid ) + { + if ( lpComponent && !*++lpComponent ) + lpComponent = NULL; + + if ( !lpComponent ) + { + #if 0 + /* We only have a Server specification what is invalid */ + + lpComponent = lpszPath; + fValid = FALSE; + #else + dwPathType |= PATHTYPE_IS_SERVER; + #endif + } + else + { + /* Now test the network resource */ + + fValid = IsValidFilePathComponent( lpComponent, &lpComponent, 0 ); + + /* If we now reached the end of the path, everything is O.K. */ + + + if ( fValid && (!lpComponent || lpComponent && !*++lpComponent ) ) + { + lpComponent = NULL; + dwPathType |= PATHTYPE_IS_VOLUME; + } + } + } + } + else if ( ( dwCandidatPathType & PATHTYPE_MASK_TYPE ) == PATHTYPE_ABSOLUTE_LOCAL ) + { + if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) ) + lpComponent++; + else if ( *lpComponent ) + fValid = FALSE; + + dwPathType = dwCandidatPathType; + + /* Now we are behind the backslash or it was a simple drive without backslash */ + + if ( fValid && !*lpComponent ) + { + lpComponent = NULL; + dwPathType |= PATHTYPE_IS_VOLUME; + } + } + else if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE ) + { + /* Can be a relative path */ + lpComponent = lpszPath; + + /* Relative path can start with a backslash */ + + if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) ) + { + lpComponent++; + if ( !*lpComponent ) + lpComponent = NULL; + } + + dwPathType = PATHTYPE_RELATIVE; + } + else + { + /* Anything else is an error */ + fValid = FALSE; + lpComponent = lpszPath; + } + + /* Now validate each component of the path */ + while ( fValid && lpComponent ) + { + // Correct path by merging consecutive slashes: + if (*lpComponent == '\\' && corrected != NULL) { + sal_Int32 i = lpComponent - lpszPath; + rtl_uString_newReplaceStrAt(corrected, path, i, 1, NULL); + //TODO: handle out-of-memory + lpszPath = reinterpret_cast< LPCTSTR >((*corrected)->buffer); + lpComponent = lpszPath + i; + } + + fValid = IsValidFilePathComponent( lpComponent, &lpComponent, dwFlags ); + + if ( fValid && lpComponent ) + { + lpComponent++; + + /* If the string behind the backslash is empty, we've done */ + + if ( !*lpComponent ) + lpComponent = NULL; + } + } + + /* The path can be longer than MAX_PATH only in case it has the longpath prefix */ + if ( fValid && !( dwPathType & PATHTYPE_IS_LONGPATH ) && _tcslen( lpszPath ) >= MAX_PATH ) + { + fValid = FALSE; + lpComponent = lpszPath + MAX_PATH; + } + + if ( lppError ) + *lppError = lpComponent; + + return fValid ? dwPathType : PATHTYPE_ERROR; +} + +//##################################################### +static sal_Int32 PathRemoveFileSpec(LPTSTR lpPath, LPTSTR lpFileName, sal_Int32 nFileBufLen ) +{ + sal_Int32 nRemoved = 0; + + if ( nFileBufLen ) + { + lpFileName[0] = 0; + LPTSTR lpLastBkSlash = _tcsrchr( lpPath, '\\' ); + LPTSTR lpLastSlash = _tcsrchr( lpPath, '/' ); + LPTSTR lpLastDelimiter = lpLastSlash > lpLastBkSlash ? lpLastSlash : lpLastBkSlash; + + if ( lpLastDelimiter ) + { + sal_Int32 nDelLen = _tcslen( lpLastDelimiter ); + if ( 1 == nDelLen ) + { + if ( lpLastDelimiter > lpPath && *(lpLastDelimiter - 1) != ':' ) + { + *lpLastDelimiter = 0; + *lpFileName = 0; + nRemoved = nDelLen; + } + } + else if ( nDelLen && nDelLen - 1 < nFileBufLen ) + { + _tcscpy( lpFileName, lpLastDelimiter + 1 ); + *(++lpLastDelimiter) = 0; + nRemoved = nDelLen - 1; + } + } + } + + return nRemoved; +} + +//##################################################### +// Undocumented in SHELL32.DLL ordinal 32 +static LPTSTR PathAddBackslash(LPTSTR lpPath, sal_Int32 nBufLen) +{ + LPTSTR lpEndPath = NULL; + + if ( lpPath ) + { + int nLen = _tcslen(lpPath); + + if ( !nLen || lpPath[nLen-1] != '\\' && lpPath[nLen-1] != '/' && nLen < nBufLen - 1 ) + { + lpEndPath = lpPath + nLen; + *lpEndPath++ = '\\'; + *lpEndPath = 0; + } + } + return lpEndPath; +} + +//##################################################### +// Same as GetLongPathName but also 95/NT4 +static DWORD GetCaseCorrectPathNameEx( + LPTSTR lpszPath, // path buffer to convert + DWORD cchBuffer, // size of path buffer + DWORD nSkipLevels, + BOOL bCheckExistence ) +{ + ::osl::LongPathBuffer< WCHAR > szFile( MAX_PATH + 1 ); + sal_Int32 nRemoved = PathRemoveFileSpec( lpszPath, szFile, MAX_PATH + 1 ); + sal_Int32 nLastStepRemoved = nRemoved; + while ( nLastStepRemoved && szFile[0] == 0 ) + { + // remove separators + nLastStepRemoved = PathRemoveFileSpec( lpszPath, szFile, MAX_PATH + 1 ); + nRemoved += nLastStepRemoved; + } + + if ( nRemoved ) + { + BOOL bSkipThis = FALSE; + + if ( 0 == _tcscmp( szFile, TEXT("..") ) ) + { + bSkipThis = TRUE; + nSkipLevels += 1; + } + else if ( 0 == _tcscmp( szFile, TEXT(".") ) ) + { + bSkipThis = TRUE; + } + else if ( nSkipLevels ) + { + bSkipThis = TRUE; + nSkipLevels--; + } + else + bSkipThis = FALSE; + + GetCaseCorrectPathNameEx( lpszPath, cchBuffer, nSkipLevels, bCheckExistence ); + + PathAddBackslash( lpszPath, cchBuffer ); + + /* Analyze parent if not only a trailing backslash was cutted but a real file spec */ + if ( !bSkipThis ) + { + if ( bCheckExistence ) + { + ::osl::LongPathBuffer< WCHAR > aShortPath( MAX_LONG_PATH ); + _tcscpy( aShortPath, lpszPath ); + _tcscat( aShortPath, szFile ); + + WIN32_FIND_DATA aFindFileData; + HANDLE hFind = FindFirstFile( aShortPath, &aFindFileData ); + + if ( IsValidHandle(hFind) ) + { + _tcscat( lpszPath, aFindFileData.cFileName[0] ? aFindFileData.cFileName : aFindFileData.cAlternateFileName ); + + FindClose( hFind ); + } + else + lpszPath[0] = 0; + } + else + { + /* add the segment name back */ + _tcscat( lpszPath, szFile ); + } + } + } + else + { + /* File specification can't be removed therefore the short path is either a drive + or a network share. If still levels to skip are left, the path specification + tries to travel below the file system root */ + if ( nSkipLevels ) + lpszPath[0] = 0; + else + _tcsupr( lpszPath ); + } + + return _tcslen( lpszPath ); +} + +//##################################################### +#define WSTR_SYSTEM_ROOT_PATH L"\\\\.\\" + +DWORD GetCaseCorrectPathName( + LPCTSTR lpszShortPath, // file name + LPTSTR lpszLongPath, // path buffer + DWORD cchBuffer, // size of path buffer + BOOL bCheckExistence +) +{ + /* Special handling for "\\.\" as system root */ + if ( lpszShortPath && 0 == wcscmp( lpszShortPath, WSTR_SYSTEM_ROOT_PATH ) ) + { + if ( cchBuffer >= ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) ) + { + wcscpy( lpszLongPath, WSTR_SYSTEM_ROOT_PATH ); + return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1; + } + else + { + return ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1; + } + } + else if ( lpszShortPath ) + { + if ( _tcslen( lpszShortPath ) <= cchBuffer ) + { + _tcscpy( lpszLongPath, lpszShortPath ); + return GetCaseCorrectPathNameEx( lpszLongPath, cchBuffer, 0, bCheckExistence ); + } + } + + return 0; +} + + +//############################################# +static sal_Bool _osl_decodeURL( rtl_String* strUTF8, rtl_uString** pstrDecodedURL ) +{ + sal_Char *pBuffer; + const sal_Char *pSrcEnd; + const sal_Char *pSrc; + sal_Char *pDest; + sal_Int32 nSrcLen; + sal_Bool bValidEncoded = sal_True; /* Assume success */ + + /* The resulting decoded string length is shorter or equal to the source length */ + + nSrcLen = rtl_string_getLength(strUTF8); + pBuffer = reinterpret_cast<sal_Char*>(rtl_allocateMemory(nSrcLen + 1)); + + pDest = pBuffer; + pSrc = rtl_string_getStr(strUTF8); + pSrcEnd = pSrc + nSrcLen; + + /* Now decode the URL what should result in an UTF8 string */ + while ( bValidEncoded && pSrc < pSrcEnd ) + { + switch ( *pSrc ) + { + case '%': + { + sal_Char aToken[3]; + sal_Char aChar; + + pSrc++; + aToken[0] = *pSrc++; + aToken[1] = *pSrc++; + aToken[2] = 0; + + aChar = (sal_Char)strtoul( aToken, NULL, 16 ); + + /* The chars are path delimiters and must not be encoded */ + + if ( 0 == aChar || '\\' == aChar || '/' == aChar || ':' == aChar ) + bValidEncoded = sal_False; + else + *pDest++ = aChar; + } + break; + default: + *pDest++ = *pSrc++; + break; + } + } + + *pDest++ = 0; + + if ( bValidEncoded ) + { + rtl_string2UString( pstrDecodedURL, pBuffer, rtl_str_getLength(pBuffer), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS ); + OSL_ASSERT(*pstrDecodedURL != 0); + } + + rtl_freeMemory( pBuffer ); + + return bValidEncoded; +} + +//############################################# +static void _osl_encodeURL( rtl_uString *strURL, rtl_String **pstrEncodedURL ) +{ + /* Encode non ascii characters within the URL */ + + rtl_String *strUTF8 = NULL; + sal_Char *pszEncodedURL; + const sal_Char *pURLScan; + sal_Char *pURLDest; + sal_Int32 nURLScanLen; + sal_Int32 nURLScanCount; + + rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS ); + + pszEncodedURL = (sal_Char*) rtl_allocateMemory( (rtl_string_getLength( strUTF8 ) * 3 + 1) * sizeof(sal_Char) ); + + pURLDest = pszEncodedURL; + pURLScan = rtl_string_getStr( strUTF8 ); + nURLScanLen = rtl_string_getLength( strUTF8 ); + nURLScanCount = 0; + + while ( nURLScanCount < nURLScanLen ) + { + sal_Char cCurrent = *pURLScan; + switch ( cCurrent ) + { + default: + if (!( ( cCurrent >= 'a' && cCurrent <= 'z' ) || ( cCurrent >= 'A' && cCurrent <= 'Z' ) || ( cCurrent >= '0' && cCurrent <= '9' ) ) ) + { + sprintf( pURLDest, "%%%02X", (unsigned char)cCurrent ); + pURLDest += 3; + break; + } + case '!': + case '\'': + case '(': + case ')': + case '*': + case '-': + case '.': + case '_': + case '~': + case '$': + case '&': + case '+': + case ',': + case '=': + case '@': + case ':': + case '/': + case '\\': + case '|': + *pURLDest++ = cCurrent; + break; + case 0: + break; + } + + pURLScan++; + nURLScanCount++; + } + + *pURLDest = 0; + + rtl_string_release( strUTF8 ); + rtl_string_newFromStr( pstrEncodedURL, pszEncodedURL ); + rtl_freeMemory( pszEncodedURL ); +} + +//############################################# + +oslFileError _osl_getSystemPathFromFileURL( rtl_uString *strURL, rtl_uString **pustrPath, sal_Bool bAllowRelative ) +{ + rtl_String *strUTF8 = NULL; + rtl_uString *strDecodedURL = NULL; + rtl_uString *strTempPath = NULL; + const sal_Unicode *pDecodedURL; + sal_uInt32 nDecodedLen; + sal_Bool bValidEncoded; + oslFileError nError = osl_File_E_INVAL; /* Assume failure */ + + /* If someone hasn't encoded the complete URL we convert it to UTF8 now to prevent from + having a mixed encoded URL later */ + + rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS ); + + /* If the length of strUTF8 and strURL differs it indicates that the URL was not correct encoded */ + + OSL_ENSURE_FILE( + strUTF8->length == strURL->length || + 0 != rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( strURL->buffer, strURL->length, "file:\\\\", 7 ) + ,"osl_getSystemPathFromFileURL: \"%s\" is not encoded !!!", strURL ); + + bValidEncoded = _osl_decodeURL( strUTF8, &strDecodedURL ); + + /* Release the encoded UTF8 string */ + rtl_string_release( strUTF8 ); + + if ( bValidEncoded ) + { + /* Replace backslashes and pipes */ + + rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '/', '\\' ); + rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '|', ':' ); + + pDecodedURL = rtl_uString_getStr( strDecodedURL ); + nDecodedLen = rtl_uString_getLength( strDecodedURL ); + + /* Must start with "file://" */ + if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\", 7 ) ) + { + sal_uInt32 nSkip; + + if ( 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\\\", 8 ) ) + nSkip = 8; + else if ( + 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\localhost\\", 17 ) || + 0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL, nDecodedLen, "file:\\\\127.0.0.1\\", 17 ) + ) + nSkip = 17; + else + nSkip = 5; + + /* Indicates local root */ + if ( nDecodedLen == nSkip ) + rtl_uString_newFromStr_WithLength( &strTempPath, reinterpret_cast<const sal_Unicode*>(WSTR_SYSTEM_ROOT_PATH), ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1 ); + else + { + /* do not separate the directory and file case, so the maximal path lengs without prefix is MAX_PATH-12 */ + if ( nDecodedLen - nSkip <= MAX_PATH - 12 ) + { + rtl_uString_newFromStr_WithLength( &strTempPath, pDecodedURL + nSkip, nDecodedLen - nSkip ); + } + else + { + ::osl::LongPathBuffer< sal_Unicode > aBuf( MAX_LONG_PATH ); + sal_uInt32 nNewLen = GetCaseCorrectPathName( reinterpret_cast<LPCTSTR>(pDecodedURL + nSkip), + ::osl::mingw_reinterpret_cast<LPTSTR>(aBuf), + aBuf.getBufSizeInSymbols(), + sal_False ); + + if ( nNewLen <= MAX_PATH - 12 + || 0 == rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL + nSkip, nDecodedLen - nSkip, reinterpret_cast<const sal_Unicode*>(WSTR_SYSTEM_ROOT_PATH), ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1, ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1 ) + || 0 == rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pDecodedURL + nSkip, nDecodedLen - nSkip, reinterpret_cast<const sal_Unicode*>(WSTR_LONG_PATH_PREFIX), ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1, ELEMENTS_OF_ARRAY(WSTR_LONG_PATH_PREFIX) - 1 ) ) + { + rtl_uString_newFromStr_WithLength( &strTempPath, aBuf, nNewLen ); + } + else if ( pDecodedURL[nSkip] == (sal_Unicode)'\\' && pDecodedURL[nSkip+1] == (sal_Unicode)'\\' ) + { + /* it should be an UNC path, use the according prefix */ + rtl_uString *strSuffix = NULL; + rtl_uString *strPrefix = NULL; + rtl_uString_newFromStr_WithLength( &strPrefix, reinterpret_cast<const sal_Unicode*>(WSTR_LONG_PATH_PREFIX_UNC), ELEMENTS_OF_ARRAY( WSTR_LONG_PATH_PREFIX_UNC ) - 1 ); + rtl_uString_newFromStr_WithLength( &strSuffix, aBuf + 2, nNewLen - 2 ); + + rtl_uString_newConcat( &strTempPath, strPrefix, strSuffix ); + + rtl_uString_release( strPrefix ); + rtl_uString_release( strSuffix ); + } + else + { + rtl_uString *strSuffix = NULL; + rtl_uString *strPrefix = NULL; + rtl_uString_newFromStr_WithLength( &strPrefix, reinterpret_cast<const sal_Unicode*>(WSTR_LONG_PATH_PREFIX), ELEMENTS_OF_ARRAY( WSTR_LONG_PATH_PREFIX ) - 1 ); + rtl_uString_newFromStr_WithLength( &strSuffix, aBuf, nNewLen ); + + rtl_uString_newConcat( &strTempPath, strPrefix, strSuffix ); + + rtl_uString_release( strPrefix ); + rtl_uString_release( strSuffix ); + } + } + } + + if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) ) + nError = osl_File_E_None; + } + else if ( bAllowRelative ) /* This maybe a relative file URL */ + { + /* In future the relative path could be converted to absolute if it is too long */ + rtl_uString_assign( &strTempPath, strDecodedURL ); + + if ( IsValidFilePath( strTempPath, NULL, VALIDATEPATH_ALLOW_RELATIVE | VALIDATEPATH_ALLOW_ELLIPSE, &strTempPath ) ) + nError = osl_File_E_None; + } + /* + else + OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not an absolute FileURL !!!", strURL ); + */ + + } + + if ( strDecodedURL ) + rtl_uString_release( strDecodedURL ); + + if ( osl_File_E_None == nError ) + rtl_uString_assign( pustrPath, strTempPath ); + + if ( strTempPath ) + rtl_uString_release( strTempPath ); + + /* + OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not a FileURL !!!", strURL ); + */ + + return nError; +} + +//############################################# +oslFileError _osl_getFileURLFromSystemPath( rtl_uString* strPath, rtl_uString** pstrURL ) +{ + oslFileError nError = osl_File_E_INVAL; /* Assume failure */ + rtl_uString *strTempURL = NULL; + DWORD dwPathType = PATHTYPE_ERROR; + + if (strPath) + dwPathType = IsValidFilePath(strPath, NULL, VALIDATEPATH_ALLOW_RELATIVE, NULL); + + if (dwPathType) + { + rtl_uString *strTempPath = NULL; + + if ( dwPathType & PATHTYPE_IS_LONGPATH ) + { + rtl_uString *strBuffer = NULL; + sal_uInt32 nIgnore = 0; + sal_uInt32 nLength = 0; + + /* the path has the longpath prefix, lets remove it */ + switch ( dwPathType & PATHTYPE_MASK_TYPE ) + { + case PATHTYPE_ABSOLUTE_UNC: + nIgnore = ELEMENTS_OF_ARRAY( WSTR_LONG_PATH_PREFIX_UNC ) - 1; + OSL_ENSURE( nIgnore == 8, "Unexpected long path UNC prefix!" ); + + /* generate the normal UNC path */ + nLength = rtl_uString_getLength( strPath ); + rtl_uString_newFromStr_WithLength( &strBuffer, strPath->buffer + nIgnore - 2, nLength - nIgnore + 2 ); + strBuffer->buffer[0] = '\\'; + + rtl_uString_newReplace( &strTempPath, strBuffer, '\\', '/' ); + rtl_uString_release( strBuffer ); + break; + + case PATHTYPE_ABSOLUTE_LOCAL: + nIgnore = ELEMENTS_OF_ARRAY( WSTR_LONG_PATH_PREFIX ) - 1; + OSL_ENSURE( nIgnore == 4, "Unexpected long path prefix!" ); + + /* generate the normal path */ + nLength = rtl_uString_getLength( strPath ); + rtl_uString_newFromStr_WithLength( &strBuffer, strPath->buffer + nIgnore, nLength - nIgnore ); + + rtl_uString_newReplace( &strTempPath, strBuffer, '\\', '/' ); + rtl_uString_release( strBuffer ); + break; + + default: + OSL_ASSERT( "Unexpected long path format!" ); + rtl_uString_newReplace( &strTempPath, strPath, '\\', '/' ); + break; + } + } + else + { + /* Replace backslashes */ + rtl_uString_newReplace( &strTempPath, strPath, '\\', '/' ); + } + + switch ( dwPathType & PATHTYPE_MASK_TYPE ) + { + case PATHTYPE_RELATIVE: + rtl_uString_assign( &strTempURL, strTempPath ); + nError = osl_File_E_None; + break; + case PATHTYPE_ABSOLUTE_UNC: + rtl_uString_newFromAscii( &strTempURL, "file:" ); + rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath ); + nError = osl_File_E_None; + break; + case PATHTYPE_ABSOLUTE_LOCAL: + rtl_uString_newFromAscii( &strTempURL, "file:///" ); + rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath ); + nError = osl_File_E_None; + break; + default: + break; + } + + /* Release temp path */ + rtl_uString_release( strTempPath ); + } + + if ( osl_File_E_None == nError ) + { + rtl_String *strEncodedURL = NULL; + + /* Encode the URL */ + _osl_encodeURL( strTempURL, &strEncodedURL ); + + /* Provide URL via unicode string */ + rtl_string2UString( pstrURL, rtl_string_getStr(strEncodedURL), rtl_string_getLength(strEncodedURL), RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS ); + OSL_ASSERT(*pstrURL != 0); + rtl_string_release( strEncodedURL ); + } + + /* Release temp URL */ + if ( strTempURL ) + rtl_uString_release( strTempURL ); + + /* + OSL_ENSURE_FILE( !nError, "osl_getFileURLFromSystemPath: \"%s\" is not a systemPath !!!", strPath ); + */ + return nError; +} + +//##################################################### +oslFileError SAL_CALL osl_getFileURLFromSystemPath( + rtl_uString* ustrPath, rtl_uString** pustrURL ) +{ + return _osl_getFileURLFromSystemPath( ustrPath, pustrURL ); +} + +//##################################################### +oslFileError SAL_CALL osl_getSystemPathFromFileURL( + rtl_uString *ustrURL, rtl_uString **pustrPath) +{ + return _osl_getSystemPathFromFileURL( ustrURL, pustrPath, sal_True ); +} + +//##################################################### +oslFileError SAL_CALL osl_searchFileURL( + rtl_uString *ustrFileName, + rtl_uString *ustrSystemSearchPath, + rtl_uString **pustrPath) +{ + rtl_uString *ustrUNCPath = NULL; + rtl_uString *ustrSysPath = NULL; + oslFileError error; + + /* First try to interpret the file name as an URL even a relative one */ + error = _osl_getSystemPathFromFileURL( ustrFileName, &ustrUNCPath, sal_True ); + + /* So far we either have an UNC path or something invalid + Now create a system path */ + if ( osl_File_E_None == error ) + error = _osl_getSystemPathFromFileURL( ustrUNCPath, &ustrSysPath, sal_True ); + + if ( osl_File_E_None == error ) + { + DWORD nBufferLength; + DWORD dwResult; + LPTSTR lpBuffer = NULL; + LPTSTR lpszFilePart; + + /* Repeat calling SearchPath ... + Start with MAX_PATH for the buffer. In most cases this + will be enough and does not force the loop to runtwice */ + dwResult = MAX_PATH; + + do + { + /* If search path is empty use a NULL pointer instead according to MSDN documentation of SearchPath */ + LPCTSTR lpszSearchPath = ustrSystemSearchPath && ustrSystemSearchPath->length ? reinterpret_cast<LPCTSTR>(ustrSystemSearchPath->buffer) : NULL; + LPCTSTR lpszSearchFile = reinterpret_cast<LPCTSTR>(ustrSysPath->buffer); + + /* Allocate space for buffer according to previous returned count of required chars */ + /* +1 is not neccessary if we follow MSDN documentation but for robustness we do so */ + nBufferLength = dwResult + 1; + lpBuffer = lpBuffer ? + reinterpret_cast<LPTSTR>(rtl_reallocateMemory(lpBuffer, nBufferLength * sizeof(TCHAR))) : + reinterpret_cast<LPTSTR>(rtl_allocateMemory(nBufferLength * sizeof(TCHAR))); + + dwResult = SearchPath( lpszSearchPath, lpszSearchFile, NULL, nBufferLength, lpBuffer, &lpszFilePart ); + } while ( dwResult && dwResult >= nBufferLength ); + + /* ... until an error occures or buffer is large enough. + dwResult == nBufferLength can not happen according to documentation but lets be robust ;-) */ + + if ( dwResult ) + { + rtl_uString_newFromStr( &ustrSysPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) ); + error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath ); + } + else + { + WIN32_FIND_DATA aFindFileData; + HANDLE hFind; + + /* Somthing went wrong, perhaps the path was absolute */ + error = oslTranslateFileError( GetLastError() ); + + hFind = FindFirstFile( reinterpret_cast<LPCTSTR>(ustrSysPath->buffer), &aFindFileData ); + + if ( IsValidHandle(hFind) ) + { + error = osl_getFileURLFromSystemPath( ustrSysPath, pustrPath ); + FindClose( hFind ); + } + } + + rtl_freeMemory( lpBuffer ); + } + + if ( ustrSysPath ) + rtl_uString_release( ustrSysPath ); + + if ( ustrUNCPath ) + rtl_uString_release( ustrUNCPath ); + + return error; +} + +//##################################################### + +oslFileError SAL_CALL osl_getAbsoluteFileURL( rtl_uString* ustrBaseURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL ) +{ + oslFileError eError; + rtl_uString *ustrRelSysPath = NULL; + rtl_uString *ustrBaseSysPath = NULL; + + if ( ustrBaseURL && ustrBaseURL->length ) + { + eError = _osl_getSystemPathFromFileURL( ustrBaseURL, &ustrBaseSysPath, sal_False ); + OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with relative or invalid base URL" ); + + eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_True ); + } + else + { + eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_False ); + OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with empty base URL and/or invalid relative URL" ); + } + + if ( !eError ) + { + ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH ); + ::osl::LongPathBuffer< sal_Unicode > aCurrentDir( MAX_LONG_PATH ); + LPTSTR lpFilePart = NULL; + DWORD dwResult; + +/*@@@ToDo + Bad, bad hack, this only works if the base path + really exists which is not necessary according + to RFC2396 + The whole FileURL implementation should be merged + with the rtl/uri class. +*/ + if ( ustrBaseSysPath ) + { + osl_acquireMutex( g_CurrentDirectoryMutex ); + + GetCurrentDirectoryW( aCurrentDir.getBufSizeInSymbols(), ::osl::mingw_reinterpret_cast<LPWSTR>(aCurrentDir) ); + SetCurrentDirectoryW( reinterpret_cast<LPCWSTR>(ustrBaseSysPath->buffer) ); + } + + dwResult = GetFullPathNameW( reinterpret_cast<LPCWSTR>(ustrRelSysPath->buffer), aBuffer.getBufSizeInSymbols(), ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer), &lpFilePart ); + + if ( ustrBaseSysPath ) + { + SetCurrentDirectoryW( ::osl::mingw_reinterpret_cast<LPCWSTR>(aCurrentDir) ); + + osl_releaseMutex( g_CurrentDirectoryMutex ); + } + + if ( dwResult ) + { + if ( dwResult >= aBuffer.getBufSizeInSymbols() ) + eError = osl_File_E_INVAL; + else + { + rtl_uString *ustrAbsSysPath = NULL; + + rtl_uString_newFromStr( &ustrAbsSysPath, aBuffer ); + + eError = osl_getFileURLFromSystemPath( ustrAbsSysPath, pustrAbsoluteURL ); + + if ( ustrAbsSysPath ) + rtl_uString_release( ustrAbsSysPath ); + } + } + else + eError = oslTranslateFileError( GetLastError() ); + } + + if ( ustrBaseSysPath ) + rtl_uString_release( ustrBaseSysPath ); + + if ( ustrRelSysPath ) + rtl_uString_release( ustrRelSysPath ); + + return eError; +} + +//##################################################### +oslFileError SAL_CALL osl_getCanonicalName( rtl_uString *strRequested, rtl_uString **strValid ) +{ + rtl_uString_newFromString(strValid, strRequested); + return osl_File_E_None; +} diff --git a/sal/osl/w32/file_url.h b/sal/osl/w32/file_url.h new file mode 100644 index 000000000..8af4b8a59 --- /dev/null +++ b/sal/osl/w32/file_url.h @@ -0,0 +1,96 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_OSL_FILE_URL_H +#define INCLUDED_OSL_FILE_URL_H + +#include "sal/types.h" +#include "rtl/ustring.h" +#include "osl/file.h" + +#ifdef _MSC_VER +#pragma warning(push,1) +#endif + +#define WINDOWS_LEAN_AND_MEAN +#include <windows.h> + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define PATHTYPE_ERROR 0 +#define PATHTYPE_RELATIVE 1 +#define PATHTYPE_ABSOLUTE_UNC 2 +#define PATHTYPE_ABSOLUTE_LOCAL 3 +#define PATHTYPE_MASK_TYPE 0xFF +#define PATHTYPE_IS_VOLUME 0x0100 +#define PATHTYPE_IS_SERVER 0x0200 +#define PATHTYPE_IS_LONGPATH 0x0400 + +#define VALIDATEPATH_NORMAL 0x0000 +#define VALIDATEPATH_ALLOW_WILDCARDS 0x0001 +#define VALIDATEPATH_ALLOW_ELLIPSE 0x0002 +#define VALIDATEPATH_ALLOW_RELATIVE 0x0004 +#define VALIDATEPATH_ALLOW_UNC 0x0008 + +#define MAX_LONG_PATH 32767 + +DWORD IsValidFilePath ( + rtl_uString * path, + LPCTSTR * lppError, + DWORD dwFlags, + rtl_uString ** corrected +); + +DWORD GetCaseCorrectPathName ( + LPCTSTR lpszShortPath, // file name + LPTSTR lpszLongPath, // path buffer + DWORD cchBuffer, // size of path buffer + BOOL bCheckExistence +); + +oslFileError _osl_getSystemPathFromFileURL ( + rtl_uString * strURL, + rtl_uString ** pustrPath, + sal_Bool bAllowRelative +); + +oslFileError _osl_getFileURLFromSystemPath ( + rtl_uString * strPath, + rtl_uString ** pstrURL +); + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDED_OSL_FILE_URL_H */ diff --git a/sal/osl/w32/interlck.c b/sal/osl/w32/interlck.c index 02ec29dca..b53bd4156 100644 --- a/sal/osl/w32/interlck.c +++ b/sal/osl/w32/interlck.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: interlck.c,v $ - * $Revision: 1.7 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/libutil.c b/sal/osl/w32/libutil.c index 8352529d6..4271bb4bb 100644 --- a/sal/osl/w32/libutil.c +++ b/sal/osl/w32/libutil.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: libutil.c,v $ - * $Revision: 1.6 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/module.c b/sal/osl/w32/module.cxx index f09ae5773..be5a5b47a 100644 --- a/sal/osl/w32/module.c +++ b/sal/osl/w32/module.cxx @@ -1,42 +1,42 @@ /************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: module.c,v $ - * $Revision: 1.25 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +************************************************************************/ #include "system.h" #include <tlhelp32.h> +#include "file_url.h" +#include "path_helper.hxx" + #include <osl/module.h> #include <osl/diagnose.h> #include <osl/thread.h> #include <osl/file.h> #include <rtl/logfile.h> + /* under WIN32, we use the void* oslModule as a WIN32 HANDLE (which is also a 32-bit value) @@ -64,9 +64,9 @@ oslModule SAL_CALL osl_loadModule(rtl_uString *strModuleName, sal_Int32 nRtldMod if ( osl_File_E_None != nError ) rtl_uString_assign(&Module, strModuleName); - hInstance = LoadLibraryW(Module->buffer); + hInstance = LoadLibraryW(reinterpret_cast<LPCWSTR>(Module->buffer)); if (hInstance == NULL) - hInstance = LoadLibraryExW(Module->buffer, NULL, + hInstance = LoadLibraryExW(reinterpret_cast<LPCWSTR>(Module->buffer), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (hInstance <= (HINSTANCE)HINSTANCE_ERROR) @@ -88,7 +88,7 @@ oslModule SAL_CALL osl_loadModule(rtl_uString *strModuleName, sal_Int32 nRtldMod sal_Bool SAL_CALL osl_getModuleHandle(rtl_uString *pModuleName, oslModule *pResult) { - HINSTANCE hInstance = GetModuleHandleW(pModuleName->buffer); + HINSTANCE hInstance = GetModuleHandleW(reinterpret_cast<LPCWSTR>(pModuleName->buffer)); if( hInstance ) { *pResult = (oslModule) hInstance; @@ -312,22 +312,22 @@ static sal_Bool SAL_CALL _osl_addressGetModuleURL_NT4( void *pv, rtl_uString **p if ( lpfnSymInitialize && lpfnSymCleanup && lpfnSymGetModuleInfo ) { IMAGEHLP_MODULE ModuleInfo; - CHAR szModuleFileName[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aModuleFileName( MAX_LONG_PATH ); LPSTR lpSearchPath = NULL; - if ( GetModuleFileNameA( NULL, szModuleFileName, sizeof(szModuleFileName) ) ) + if ( GetModuleFileNameA( NULL, aModuleFileName, aModuleFileName.getBufSizeInSymbols() ) ) { - char *pLastBkSlash = strrchr( szModuleFileName, '\\' ); + char *pLastBkSlash = strrchr( aModuleFileName, '\\' ); if ( pLastBkSlash && - pLastBkSlash > szModuleFileName + pLastBkSlash > (sal_Char*)aModuleFileName && *(pLastBkSlash - 1) != ':' && *(pLastBkSlash - 1) != '\\' ) { *pLastBkSlash = 0; - lpSearchPath = szModuleFileName; + lpSearchPath = aModuleFileName; } } @@ -426,12 +426,12 @@ static sal_Bool SAL_CALL _osl_addressGetModuleURL_NT( void *pv, rtl_uString **pu if ( (BYTE *)pv >= (BYTE *)modinfo.lpBaseOfDll && (BYTE *)pv < (BYTE *)modinfo.lpBaseOfDll + modinfo.SizeOfImage ) { - WCHAR szBuffer[MAX_PATH]; + ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH ); rtl_uString *ustrSysPath = NULL; - GetModuleFileNameW( lpModules[iModule], szBuffer, bufsizeof(szBuffer) ); + GetModuleFileNameW( lpModules[iModule], ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer), aBuffer.getBufSizeInSymbols() ); - rtl_uString_newFromStr( &ustrSysPath, szBuffer ); + rtl_uString_newFromStr( &ustrSysPath, aBuffer ); osl_getFileURLFromSystemPath( ustrSysPath, pustrURL ); rtl_uString_release( ustrSysPath ); diff --git a/sal/osl/w32/mutex.c b/sal/osl/w32/mutex.c index 82f4e2bcf..dbb568d01 100644 --- a/sal/osl/w32/mutex.c +++ b/sal/osl/w32/mutex.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: mutex.c,v $ - * $Revision: 1.6 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/nlsupport.c b/sal/osl/w32/nlsupport.c index d932f2f0e..3519177ed 100644 --- a/sal/osl/w32/nlsupport.c +++ b/sal/osl/w32/nlsupport.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: nlsupport.c,v $ - * $Revision: 1.12 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/path_helper.cxx b/sal/osl/w32/path_helper.cxx index 4a54a3ad3..dd78f9604 100644 --- a/sal/osl/w32/path_helper.cxx +++ b/sal/osl/w32/path_helper.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: path_helper.cxx,v $ - * $Revision: 1.6 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/path_helper.h b/sal/osl/w32/path_helper.h index 968458142..df40758e9 100644 --- a/sal/osl/w32/path_helper.h +++ b/sal/osl/w32/path_helper.h @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: path_helper.h,v $ - * $Revision: 1.5 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/path_helper.hxx b/sal/osl/w32/path_helper.hxx index 69ffdb2c5..690129245 100644 --- a/sal/osl/w32/path_helper.hxx +++ b/sal/osl/w32/path_helper.hxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: path_helper.hxx,v $ - * $Revision: 1.6 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -37,6 +34,7 @@ #include "path_helper.h" #include <rtl/ustring.hxx> +#include <rtl/allocator.hxx> namespace osl { @@ -72,7 +70,49 @@ inline bool systemPathIsLogicalDrivePattern(/*in*/ const rtl::OUString& path) { return osl_systemPathIsLogicalDrivePattern(path.pData); } - + +/******************************************************************* + LongPathBuffer + ******************************************************************/ +template< class T > +class LongPathBuffer +{ + T* m_pBuffer; + sal_uInt32 m_nCharNum; + + LongPathBuffer(); + LongPathBuffer( const LongPathBuffer& ); + LongPathBuffer& operator=( const LongPathBuffer& ); + +public: + LongPathBuffer( sal_uInt32 nCharNum ) + : m_pBuffer( reinterpret_cast<T*>( rtl_allocateMemory( nCharNum * sizeof( T ) ) ) ) + , m_nCharNum( nCharNum ) + { + OSL_ENSURE( m_pBuffer, "Can not allocate the buffer!" ); + } + + ~LongPathBuffer() + { + if ( m_pBuffer ) + rtl_freeMemory( m_pBuffer ); + m_pBuffer = 0; + } + + sal_uInt32 getBufSizeInSymbols() + { + return m_nCharNum; + } + + operator T* () + { + return m_pBuffer; + } + +}; + + template< class U, class T > U mingw_reinterpret_cast(LongPathBuffer<T>& a) { return reinterpret_cast<U>(static_cast<T*>(a)); } + } // end namespace osl #endif diff --git a/sal/osl/w32/pipe.c b/sal/osl/w32/pipe.c index fbc4e1923..ab8421b61 100644 --- a/sal/osl/w32/pipe.c +++ b/sal/osl/w32/pipe.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: pipe.c,v $ - * $Revision: 1.20 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -632,7 +629,7 @@ oslPipeError SAL_CALL osl_getLastPipeError(oslPipe pPipe) pPipe->m_Error = osl_Pipe_E_None; } else - Error = osl_Pipe_E_None; + Error = osl_Pipe_E_NotFound; return (Error); } diff --git a/sal/osl/w32/pipeimpl.cxx b/sal/osl/w32/pipeimpl.cxx index 9ea65f522..b5ecafd86 100644 --- a/sal/osl/w32/pipeimpl.cxx +++ b/sal/osl/w32/pipeimpl.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: pipeimpl.cxx,v $ - * $Revision: 1.4 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/process.c b/sal/osl/w32/process.cxx index cd61d9369..e107abea0 100644 --- a/sal/osl/w32/process.c +++ b/sal/osl/w32/process.cxx @@ -1,32 +1,29 @@ /************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: process.c,v $ - * $Revision: 1.35 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +************************************************************************/ #define UNICODE #include "system.h" @@ -46,6 +43,8 @@ #include "procimpl.h" #include "sockimpl.h" +#include "file_url.h" +#include "path_helper.hxx" #include <rtl/ustrbuf.h> #include <rtl/alloc.h> @@ -75,7 +74,7 @@ oslProcess SAL_CALL osl_getProcess(oslProcessIdentifier Ident) if (hProcess) { - pProcImpl = rtl_allocateMemory(sizeof(oslProcessImpl)); + pProcImpl = reinterpret_cast< oslProcessImpl*>( rtl_allocateMemory(sizeof(oslProcessImpl)) ); pProcImpl->m_hProcess = hProcess; pProcImpl->m_IdProcess = Ident; } @@ -219,19 +218,19 @@ oslProcessError SAL_CALL osl_joinProcessWithTimeout(oslProcess Process, const Ti * ***************************************************************************/ -oslProcessError SAL_CALL osl_bootstrap_getExecutableFile_Impl ( +extern "C" oslProcessError SAL_CALL osl_bootstrap_getExecutableFile_Impl ( rtl_uString ** ppFileURL ) SAL_THROW_EXTERN_C() { oslProcessError result = osl_Process_E_NotFound; - TCHAR buffer[MAX_PATH]; - DWORD buflen; + ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH ); + DWORD buflen = 0; - if ((buflen = GetModuleFileNameW (0, buffer, MAX_PATH)) > 0) + if ((buflen = GetModuleFileNameW (0, ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer), aBuffer.getBufSizeInSymbols())) > 0) { rtl_uString * pAbsPath = 0; - rtl_uString_newFromStr_WithLength (&(pAbsPath), buffer, buflen); + rtl_uString_newFromStr_WithLength (&(pAbsPath), aBuffer, buflen); if (pAbsPath) { /* Convert from path to url. */ @@ -280,21 +279,21 @@ static rtl_uString ** osl_createCommandArgs_Impl (int argc, char ** argv) for (i = 0; i < nArgs; i++) { /* Convert to unicode */ - rtl_uString_newFromStr( &(ppArgs[i]), wargv[i] ); + rtl_uString_newFromStr( &(ppArgs[i]), reinterpret_cast<const sal_Unicode*>(wargv[i]) ); } if (ppArgs[0] != 0) { /* Ensure absolute path */ - DWORD dwResult; - TCHAR szBuffer[MAX_PATH]; + ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH ); + DWORD dwResult = 0; dwResult = SearchPath ( - 0, ppArgs[0]->buffer, L".exe", MAX_PATH, szBuffer, 0); - if ((0 < dwResult) && (dwResult < MAX_PATH)) + 0, reinterpret_cast<LPCWSTR>(ppArgs[0]->buffer), L".exe", aBuffer.getBufSizeInSymbols(), ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer), 0); + if ((0 < dwResult) && (dwResult < aBuffer.getBufSizeInSymbols())) { /* Replace argv[0] with it's absolute path */ rtl_uString_newFromStr_WithLength( - &(ppArgs[0]), szBuffer, dwResult); + &(ppArgs[0]), aBuffer, dwResult); } } if (ppArgs[0] != 0) @@ -323,6 +322,7 @@ oslProcessError SAL_CALL osl_getExecutableFile( rtl_uString **ppustrFile ) oslProcessError result = osl_Process_E_NotFound; osl_acquireMutex (*osl_getGlobalMutex()); + OSL_ASSERT(g_command_args.m_nCount > 0); if (g_command_args.m_nCount > 0) { /* CommandArgs set. Obtain arv[0]. */ @@ -341,6 +341,7 @@ sal_uInt32 SAL_CALL osl_getCommandArgCount(void) sal_uInt32 result = 0; osl_acquireMutex (*osl_getGlobalMutex()); + OSL_ASSERT(g_command_args.m_nCount > 0); if (g_command_args.m_nCount > 0) { /* We're not counting argv[0] here. */ @@ -358,6 +359,7 @@ oslProcessError SAL_CALL osl_getCommandArg( sal_uInt32 nArg, rtl_uString **strCo oslProcessError result = osl_Process_E_NotFound; osl_acquireMutex (*osl_getGlobalMutex()); + OSL_ASSERT(g_command_args.m_nCount > 0); if (g_command_args.m_nCount > (nArg + 1)) { /* We're not counting argv[0] here. */ @@ -373,6 +375,7 @@ oslProcessError SAL_CALL osl_getCommandArg( sal_uInt32 nArg, rtl_uString **strCo void SAL_CALL osl_setCommandArgs (int argc, char ** argv) { + OSL_ASSERT(argc > 0); osl_acquireMutex (*osl_getGlobalMutex()); if (g_command_args.m_nCount == 0) { @@ -402,9 +405,9 @@ oslProcessError SAL_CALL osl_getEnvironment(rtl_uString *ustrVar, rtl_uString ** { WCHAR buff[ENV_BUFFER_SIZE]; - if (GetEnvironmentVariableW(ustrVar->buffer, buff, ENV_BUFFER_SIZE) > 0) + if (GetEnvironmentVariableW(reinterpret_cast<LPCWSTR>(ustrVar->buffer), buff, ENV_BUFFER_SIZE) > 0) { - rtl_uString_newFromStr(ustrValue, buff); + rtl_uString_newFromStr(ustrValue, reinterpret_cast<const sal_Unicode*>(buff)); return osl_Process_E_None; } return osl_Process_E_Unknown; @@ -414,24 +417,24 @@ oslProcessError SAL_CALL osl_getEnvironment(rtl_uString *ustrVar, rtl_uString ** * Current Working Directory. ***************************************************************************/ -extern oslMutex g_CurrentDirectoryMutex; +extern "C" oslMutex g_CurrentDirectoryMutex; oslProcessError SAL_CALL osl_getProcessWorkingDir( rtl_uString **pustrWorkingDir ) { - TCHAR szBuffer[MAX_PATH]; - DWORD dwLen; + ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH ); + DWORD dwLen = 0; osl_acquireMutex( g_CurrentDirectoryMutex ); - dwLen = GetCurrentDirectory( sizeof(szBuffer) / sizeof(TCHAR), szBuffer ); + dwLen = GetCurrentDirectory( aBuffer.getBufSizeInSymbols(), ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer) ); osl_releaseMutex( g_CurrentDirectoryMutex ); - if ( dwLen ) + if ( dwLen && dwLen < aBuffer.getBufSizeInSymbols() ) { oslFileError eError; rtl_uString *ustrTemp = NULL;; - rtl_uString_newFromStr_WithLength( &ustrTemp, szBuffer, dwLen ); + rtl_uString_newFromStr_WithLength( &ustrTemp, aBuffer, dwLen ); eError = osl_getFileURLFromSystemPath( ustrTemp, pustrWorkingDir ); rtl_uString_release( ustrTemp ); @@ -449,7 +452,7 @@ oslProcessError SAL_CALL osl_getProcessWorkingDir( rtl_uString **pustrWorkingDir * Process Locale. ***************************************************************************/ -extern void _imp_getProcessLocale( rtl_Locale ** ppLocale ); +extern "C" void _imp_getProcessLocale( rtl_Locale ** ppLocale ); static rtl_Locale * g_theProcessLocale = NULL; diff --git a/sal/osl/w32/procimpl.cxx b/sal/osl/w32/procimpl.cxx index 3aaea44fd..a2e645426 100644 --- a/sal/osl/w32/procimpl.cxx +++ b/sal/osl/w32/procimpl.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: procimpl.cxx,v $ - * $Revision: 1.10 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -59,7 +56,7 @@ #include <string> //################################################# -extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle( HANDLE hFile ); +extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle( HANDLE hFile, sal_uInt32 uFlags ); //################################################# const sal_Unicode NAME_VALUE_SEPARATOR = TEXT('='); @@ -172,8 +169,7 @@ namespace /* private */ { rtl::OUString env_var = rtl::OUString(env_vars[i]); - if ((env_var.getLength() == 0) || - (env_var.indexOf(NAME_VALUE_SEPARATOR) == -1)) + if (env_var.getLength() == 0) return false; iterator_pair_t iter_pair = std::equal_range( @@ -182,10 +178,17 @@ namespace /* private */ env_var, less_environment_variable()); - if (iter_pair.first != iter_pair.second) // found - *iter_pair.first = env_var; - else // not found - merged_env->insert(iter_pair.first, env_var); + if (env_var.indexOf(NAME_VALUE_SEPARATOR) == -1) + { + merged_env->erase(iter_pair.first, iter_pair.second); + } + else + { + if (iter_pair.first != iter_pair.second) // found + *iter_pair.first = env_var; + else // not found + merged_env->insert(iter_pair.first, env_var); + } } return true; } @@ -201,9 +204,9 @@ namespace /* private */ if (!create_merged_environment(environment_vars, n_environment_vars, &merged_env)) return false; - // reserve enough space for the '\0'-separated environment strings and + // allocate enough space for the '\0'-separated environment strings and // a final '\0' - environment.reserve(calc_sum_of_string_lengths(merged_env) + 1); + environment.resize(calc_sum_of_string_lengths(merged_env) + 1); string_container_const_iterator_t iter = merged_env.begin(); string_container_const_iterator_t iter_end = merged_env.end(); @@ -576,13 +579,13 @@ oslProcessError SAL_CALL osl_executeProcess_WithRedirectedIO( WaitForSingleObject(pProcImpl->m_hProcess, INFINITE); if (pProcessInputWrite) - *pProcessInputWrite = osl_createFileHandleFromOSHandle(hInputWrite); + *pProcessInputWrite = osl_createFileHandleFromOSHandle(hInputWrite, osl_File_OpenFlag_Write); if (pProcessOutputRead) - *pProcessOutputRead = osl_createFileHandleFromOSHandle(hOutputRead); + *pProcessOutputRead = osl_createFileHandleFromOSHandle(hOutputRead, osl_File_OpenFlag_Read); if (pProcessErrorRead) - *pProcessErrorRead = osl_createFileHandleFromOSHandle(hErrorRead); + *pProcessErrorRead = osl_createFileHandleFromOSHandle(hErrorRead, osl_File_OpenFlag_Read); return osl_Process_E_None; } diff --git a/sal/osl/w32/procimpl.h b/sal/osl/w32/procimpl.h index 629909e33..a174f6968 100644 --- a/sal/osl/w32/procimpl.h +++ b/sal/osl/w32/procimpl.h @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: procimpl.h,v $ - * $Revision: 1.4 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/profile.c b/sal/osl/w32/profile.cxx index 0457fbf3c..0bda059dc 100644 --- a/sal/osl/w32/profile.c +++ b/sal/osl/w32/profile.cxx @@ -1,42 +1,44 @@ /************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: profile.c,v $ - * $Revision: 1.17 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +************************************************************************/ #include "system.h" +#include "file_url.h" +#include "path_helper.hxx" + #include <osl/diagnose.h> #include <osl/profile.h> #include <osl/process.h> #include <osl/file.h> #include <osl/util.h> #include <rtl/alloc.h> +#include <algorithm> +using std::min; +static inline void copy_ustr_n( void *dest, const void *source, size_t length ) { rtl_copyMemory(dest, source, length*sizeof(sal_Unicode)); } #define LINES_INI 32 #define LINES_ADD 10 @@ -502,10 +504,10 @@ sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile, } else { - CHAR szFileName[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH ); - WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL); - GetPrivateProfileString(pszSection, pszEntry, pszDefault, pszString, MaxLen, szFileName); + WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL); + GetPrivateProfileString(pszSection, pszEntry, pszDefault, pszString, MaxLen, aFileName); } releaseProfile(pProfile); @@ -683,10 +685,10 @@ sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile, } else { - CHAR szFileName[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH ); - WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL); - WritePrivateProfileString(pszSection, pszEntry, pszString, szFileName); + WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL); + WritePrivateProfileString(pszSection, pszEntry, pszString, aFileName); } bRet = releaseProfile(pProfile); @@ -794,10 +796,10 @@ sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile, } else { - CHAR szFileName[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH ); - WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL); - WritePrivateProfileString(pszSection, pszEntry, NULL, szFileName); + WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL); + WritePrivateProfileString(pszSection, pszEntry, NULL, aFileName); } bRet = releaseProfile(pProfile); @@ -868,10 +870,10 @@ sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_C } else { - CHAR szFileName[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH ); - WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL); - n = GetPrivateProfileString(pszSection, NULL, NULL, pszBuffer, MaxLen, szFileName); + WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL); + n = GetPrivateProfileString(pszSection, NULL, NULL, pszBuffer, MaxLen, aFileName); } releaseProfile(pProfile); @@ -887,9 +889,9 @@ sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_C sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName) { sal_Bool bFailed; - sal_Unicode wcsFile[MAX_PATH]; - sal_Unicode wcsPath[MAX_PATH]; - sal_uInt32 nFileLen; + ::osl::LongPathBuffer< sal_Unicode > aFile( MAX_LONG_PATH ); + ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH ); + sal_uInt32 nFileLen = 0; sal_uInt32 nPathLen = 0; rtl_uString * strTmp = NULL; @@ -898,19 +900,19 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, /* build file name */ if (strName && strName->length) { - if(strName->length >= MAX_PATH) + if( ::sal::static_int_cast< sal_uInt32 >( strName->length ) >= aFile.getBufSizeInSymbols() ) return sal_False; - wcscpy(wcsFile, strName->buffer); + copy_ustr_n( aFile, strName->buffer, strName->length+1); nFileLen = strName->length; - if (rtl_ustr_indexOfChar( wcsFile, L'.' ) == -1) + if (rtl_ustr_indexOfChar( aFile, L'.' ) == -1) { - if (nFileLen + wcslen(STR_INI_EXTENSION) >= MAX_PATH) + if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols()) return sal_False; /* add default extension */ - wcscpy(wcsFile + nFileLen, STR_INI_EXTENSION); + copy_ustr_n( aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1 ); nFileLen += wcslen(STR_INI_EXTENSION); } } @@ -937,22 +939,22 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'.' )) != -1 ) nLen -= 4; - if ((nFileLen = nLen - nOffset) >= MAX_PATH) + if ((nFileLen = nLen - nOffset) >= aFile.getBufSizeInSymbols()) return sal_False; - wcsncpy(wcsFile, pProgName + nOffset, nFileLen); + copy_ustr_n(aFile, pProgName + nOffset, nFileLen); - if (nFileLen + wcslen(STR_INI_EXTENSION) >= MAX_PATH) + if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols()) return sal_False; /* add default extension */ - wcscpy(wcsFile + nFileLen, STR_INI_EXTENSION); + copy_ustr_n(aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1); nFileLen += wcslen(STR_INI_EXTENSION); rtl_uString_release( strProgName ); } - if (wcsFile[0] == 0) + if (aFile[0] == 0) return sal_False; /* build directory path */ @@ -972,10 +974,10 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, if (bFailed) return (sal_False); - if (strHome->length >= MAX_PATH) + if ( ::sal::static_int_cast< sal_uInt32 >( strHome->length ) >= aPath.getBufSizeInSymbols()) return sal_False; - wcscpy( wcsPath, strHome->buffer); + copy_ustr_n( aPath, strHome->buffer, strHome->length+1); nPathLen = strHome->length; if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)) @@ -983,10 +985,10 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, pPath += RTL_CONSTASCII_LENGTH(STR_INI_METAHOME); nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME); - if (nLen + nPathLen >= MAX_PATH) + if (nLen + nPathLen >= aPath.getBufSizeInSymbols()) return sal_False; - wcscpy(wcsPath + nPathLen, pPath); + copy_ustr_n(aPath + nPathLen, pPath, nLen+1); nPathLen += nLen; } @@ -1004,10 +1006,10 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, if (bFailed) return (sal_False); - if (strConfig->length >= MAX_PATH) + if ( ::sal::static_int_cast< sal_uInt32 >( strConfig->length ) >= aPath.getBufSizeInSymbols()) return sal_False; - wcscpy( wcsPath, strConfig->buffer); + copy_ustr_n( aPath, strConfig->buffer, strConfig->length+1 ); nPathLen = strConfig->length; if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METACFG)) @@ -1015,10 +1017,10 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, pPath += RTL_CONSTASCII_LENGTH(STR_INI_METACFG); nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METACFG); - if (nLen + nPathLen >= MAX_PATH) + if (nLen + nPathLen >= aPath.getBufSizeInSymbols()) return sal_False; - wcscpy(wcsPath + nPathLen, pPath); + copy_ustr_n(aPath + nPathLen, pPath, nLen+1); nPathLen += nLen; } @@ -1028,7 +1030,7 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METASYS), STR_INI_METASYS) == 0) && ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METASYS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METASYS)] == '/'))) { - if (((nPathLen = GetWindowsDirectoryW(wcsPath, MAX_PATH)) == 0) || (nPathLen >= MAX_PATH)) + if (((nPathLen = GetWindowsDirectoryW(::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols())) == 0) || (nPathLen >= aPath.getBufSizeInSymbols())) return (sal_False); if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METASYS)) @@ -1036,10 +1038,10 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, pPath += RTL_CONSTASCII_LENGTH(STR_INI_METASYS); nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METASYS); - if (nLen + nPathLen >= MAX_PATH) + if (nLen + nPathLen >= aPath.getBufSizeInSymbols()) return sal_False; - wcscpy(wcsPath + nPathLen, pPath); + copy_ustr_n(aPath + nPathLen, pPath, nLen+1); nPathLen += nLen; } } @@ -1048,16 +1050,16 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAINS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '/') || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '"') ) ) { - if (! lookupProfile(pPath + RTL_CONSTASCII_LENGTH(STR_INI_METAINS), wcsFile, wcsPath)) + if (! lookupProfile(pPath + RTL_CONSTASCII_LENGTH(STR_INI_METAINS), aFile, aPath)) return (sal_False); - nPathLen = wcslen(wcsPath); + nPathLen = rtl_ustr_getLength(aPath); } - else if(nLen < MAX_PATH) + else if( ::sal::static_int_cast< sal_uInt32 >( nLen ) < aPath.getBufSizeInSymbols()) { - wcscpy(wcsPath, pPath); - nPathLen = wcslen(wcsPath); + copy_ustr_n(aPath, pPath, nLen+1); + nPathLen = rtl_ustr_getLength(aPath); } else return sal_False; @@ -1071,28 +1073,28 @@ sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, osl_freeSecurityHandle(security); if (bFailed) return (sal_False); - if (strConfigDir->length >= MAX_PATH) + if ( ::sal::static_int_cast< sal_uInt32 >( strConfigDir->length ) >= aPath.getBufSizeInSymbols() ) return sal_False; - wcscpy(wcsPath, strConfigDir->buffer); + copy_ustr_n(aPath, strConfigDir->buffer, strConfigDir->length+1); nPathLen = strConfigDir->length; } - if (nPathLen && (wcsPath[nPathLen - 1] != L'/') && (wcsPath[nPathLen - 1] != L'\\')) + if (nPathLen && (aPath[nPathLen - 1] != L'/') && (aPath[nPathLen - 1] != L'\\')) { - wcsPath[nPathLen++] = L'\\'; - wcsPath[nPathLen] = 0; + aPath[nPathLen++] = L'\\'; + aPath[nPathLen] = 0; } - if (nPathLen + nFileLen >= MAX_PATH) + if (nPathLen + nFileLen >= aPath.getBufSizeInSymbols()) return sal_False; /* append file name */ - wcscpy(wcsPath + nPathLen, wcsFile); + copy_ustr_n(aPath + nPathLen, aFile, nFileLen+1); nPathLen += nFileLen; /* copy filename */ - rtl_uString_newFromStr_WithLength(&strTmp, wcsPath, nPathLen); + rtl_uString_newFromStr_WithLength(&strTmp, aPath, nPathLen); nError = osl_getFileURLFromSystemPath(strTmp, strProfileName); rtl_uString_release(strTmp); @@ -1140,10 +1142,10 @@ sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuff } else { - CHAR szFileName[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH ); - WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL); - n = GetPrivateProfileSectionNames(pszBuffer, MaxLen, szFileName); + WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL); + n = GetPrivateProfileSectionNames(pszBuffer, MaxLen, aFileName); } releaseProfile(pProfile); @@ -1154,35 +1156,6 @@ sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuff - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /*****************************************************************************/ /* Static Module Functions */ /*****************************************************************************/ @@ -1287,7 +1260,7 @@ static sal_Bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode) static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags ) { - osl_TFile* pFile = calloc(1, sizeof(osl_TFile)); + osl_TFile* pFile = reinterpret_cast< osl_TFile*>( calloc( 1, sizeof(osl_TFile) ) ); sal_Bool bWriteable = sal_False; /* if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE | osl_Profile_READWRITE ) )*/ @@ -1306,7 +1279,7 @@ static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption Profi OSL_TRACE("opening '%s' read only\n",pszFilename); #endif - pFile->m_Handle = CreateFileW( rtl_uString_getStr( strFileName ), GENERIC_READ, + pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -1319,7 +1292,7 @@ static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption Profi OSL_TRACE("opening '%s' read/write\n",pszFilename); #endif - if ((pFile->m_Handle = CreateFileW( rtl_uString_getStr( strFileName ), GENERIC_READ | GENERIC_WRITE, + if ((pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) @@ -2163,13 +2136,13 @@ static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile) /* unlink bak */ - DeleteFileW( rtl_uString_getStr( ustrBakFile ) ); + DeleteFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )) ); /* rename ini bak */ - MoveFileExW( rtl_uString_getStr( ustrIniFile ), rtl_uString_getStr( ustrBakFile ), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH ); + MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH ); /* rename tmp ini */ - MoveFileExW( rtl_uString_getStr( ustrTmpFile ), rtl_uString_getStr( ustrIniFile ), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH ); + MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrTmpFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH ); return bRet; } @@ -2226,7 +2199,7 @@ static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable) - if ((pProfile = osl_openProfile(NULL, PFlags)) != NULL ) + if ( ( pProfile = (osl_TProfileImpl*)osl_openProfile( NULL, PFlags ) ) != NULL ) { pProfile->m_Flags |= FLG_AUTOOPEN; } @@ -2333,7 +2306,8 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str sal_Char Buffer[4096] = ""; sal_Char Product[132] = ""; - WCHAR wcsPath[MAX_PATH] = L""; + ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH ); + aPath[0] = 0; DWORD dwPathLen = 0; if (*strPath == L'"') @@ -2345,7 +2319,7 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str while ((strPath[i] != L'"') && (strPath[i] != L'\0')) i++; - WideCharToMultiByte(CP_ACP,0, strPath, i, Product, sizeof(Product), NULL, NULL); + WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strPath), i, Product, sizeof(Product), NULL, NULL); Product[i] = '\0'; strPath += i; @@ -2367,7 +2341,7 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str rtl_uString * strSVFallback = NULL; rtl_uString * strSVLocation = NULL; rtl_uString * strSVName = NULL; - sal_Char Dir[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aDir( MAX_LONG_PATH ); oslProfile hProfile; rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK); @@ -2393,11 +2367,11 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str && (stricmp(Product, pChr) < 0)) { osl_readProfileString( - hProfile, SVERSION_SECTION, pChr, Dir, - sizeof(Dir), ""); + hProfile, SVERSION_SECTION, pChr, aDir, + aDir.getBufSizeInSymbols(), ""); /* check for existence of path */ - if (access(Dir, 0) >= 0) + if (access(aDir, 0) >= 0) strcpy(Product, pChr); } } @@ -2428,11 +2402,11 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str && (stricmp(Product, pChr) < 0)) { osl_readProfileString( - hProfile, SVERSION_SECTION, pChr, Dir, - sizeof(Dir), ""); + hProfile, SVERSION_SECTION, pChr, aDir, + aDir.getBufSizeInSymbols(), ""); /* check for existence of path */ - if (access(Dir, 0) >= 0) + if (access(aDir, 0) >= 0) strcpy(Product, pChr); } } @@ -2472,31 +2446,31 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str ((nEnd = rtl_ustr_indexOfChar(pCommandArg + nStart + 1, L']')) != -1)) { dwPathLen = nEnd; - wcsncpy(wcsPath, pCommandArg + nStart + 1, dwPathLen ); - wcsPath[dwPathLen] = 0; + copy_ustr_n(aPath, pCommandArg + nStart + 1, dwPathLen); + aPath[dwPathLen] = 0; /* build full path */ - if ((wcsPath[dwPathLen - 1] != L'/') && (wcsPath[dwPathLen - 1] != L'\\')) + if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\')) { - wcscpy(wcsPath + dwPathLen++, L"/"); + copy_ustr_n(aPath + dwPathLen++, L"/", 2); } if (*strPath) { - wcscpy(wcsPath + dwPathLen, strPath); - dwPathLen += wcslen(strPath); + copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1); + dwPathLen += rtl_ustr_getLength(strPath); } else { - CHAR szPath[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH ); int n; - if ((n = WideCharToMultiByte(CP_ACP,0, wcsPath, -1, szPath, MAX_PATH, NULL, NULL)) > 0) + if ((n = WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL)) > 0) { - strcpy(szPath + n, SVERSION_USER); - if (access(szPath, 0) >= 0) + strcpy(aTmpPath + n, SVERSION_USER); + if (access(aTmpPath, 0) >= 0) { - dwPathLen += MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, wcsPath + dwPathLen, MAX_PATH - dwPathLen ); + dwPathLen += MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + dwPathLen), aPath.getBufSizeInSymbols() - dwPathLen ); } } } @@ -2536,22 +2510,22 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str } else { - wcsncpy(wcsPath, strExecutable->buffer, nPos ); - wcsPath[nPos] = 0; + copy_ustr_n(aPath, strExecutable->buffer, nPos); + aPath[nPos] = 0; dwPathLen = nPos; } } else { - wcsncpy(wcsPath, strExecutable->buffer, nPos ); + copy_ustr_n(aPath, strExecutable->buffer, nPos); dwPathLen = nPos; - wcsPath[dwPathLen] = 0; + aPath[dwPathLen] = 0; } /* if we have no product identification use the executable file name */ if (*Product == 0) { - WideCharToMultiByte(CP_ACP,0, strExecutable->buffer + nPos + 1, -1, Product, sizeof(Product), NULL, NULL); + WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strExecutable->buffer + nPos + 1), -1, Product, sizeof(Product), NULL, NULL); /* remove extension */ if ((pChr = strrchr(Product, '.')) != NULL) @@ -2561,30 +2535,30 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str rtl_uString_release(strExecutable); /* remember last subdir */ - nPos = rtl_ustr_lastIndexOfChar(wcsPath, L'\\'); + nPos = rtl_ustr_lastIndexOfChar(aPath, L'\\'); - wcscpy(wcsPath + dwPathLen++, L"\\"); + copy_ustr_n(aPath + dwPathLen++, L"\\", 2); if (*strPath) { - wcscpy(wcsPath + dwPathLen, strPath); - dwPathLen += wcslen(strPath); + copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1); + dwPathLen += rtl_ustr_getLength(strPath); } { - CHAR szPath[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH ); - WideCharToMultiByte(CP_ACP,0, wcsPath, -1, szPath, MAX_PATH, NULL, NULL); + WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL); /* if file not exists, remove any specified subdirectories like "bin" or "program" */ - if (((access(szPath, 0) < 0) && (nPos != -1)) || (*strPath == 0)) + if (((access(aTmpPath, 0) < 0) && (nPos != -1)) || (*strPath == 0)) { static sal_Char *SubDirs[] = SVERSION_DIRS; int i = 0; - pStr = szPath + nPos; + pStr = aTmpPath + nPos; for (i = 0; i < (sizeof(SubDirs) / sizeof(SubDirs[0])); i++) if (strnicmp(pStr + 1, SubDirs[i], strlen(SubDirs[i])) == 0) @@ -2592,19 +2566,19 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str if ( *strPath == 0) { strcpy(pStr + 1,SVERSION_USER); - if ( access(szPath, 0) < 0 ) + if ( access(aTmpPath, 0) < 0 ) { *(pStr+1)='\0'; } else { - dwPathLen = nPos + MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, wcsPath + nPos + 1, MAX_PATH - (nPos + 1) ); + dwPathLen = nPos + MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + nPos + 1), aPath.getBufSizeInSymbols() - (nPos + 1) ); } } else { - wcscpy(wcsPath + nPos + 1, strPath); - dwPathLen = nPos + 1 + wcslen(strPath); + copy_ustr_n(aPath + nPos + 1, strPath, rtl_ustr_getLength(strPath)+1); + dwPathLen = nPos + 1 + rtl_ustr_getLength(strPath); } break; @@ -2612,20 +2586,20 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str } } - if ((wcsPath[dwPathLen - 1] != L'/') && (wcsPath[dwPathLen - 1] != L'\\')) + if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\')) { - wcsPath[dwPathLen++] = L'\\'; - wcsPath[dwPathLen] = 0; + aPath[dwPathLen++] = L'\\'; + aPath[dwPathLen] = 0; } - wcscpy(wcsPath + dwPathLen, strFile); + copy_ustr_n(aPath + dwPathLen, strFile, rtl_ustr_getLength(strFile)+1); { - CHAR szPath[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH ); - WideCharToMultiByte(CP_ACP,0, wcsPath, -1, szPath, MAX_PATH, NULL, NULL); + WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL); - if ((access(szPath, 0) < 0) && (strlen(Product) > 0)) + if ((access(aTmpPath, 0) < 0) && (strlen(Product) > 0)) { rtl_uString * strSVFallback = NULL; rtl_uString * strSVProfile = NULL; @@ -2674,38 +2648,38 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str if (strlen(Buffer) > 0) { dwPathLen = MultiByteToWideChar( - CP_ACP, 0, Buffer, -1, wcsPath, MAX_PATH ); + CP_ACP, 0, Buffer, -1, ::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols() ); dwPathLen -=1; /* build full path */ - if ((wcsPath[dwPathLen - 1] != L'/') - && (wcsPath[dwPathLen - 1] != L'\\')) + if ((aPath[dwPathLen - 1] != L'/') + && (aPath[dwPathLen - 1] != L'\\')) { - wcscpy(wcsPath + dwPathLen++, L"\\"); + copy_ustr_n(aPath + dwPathLen++, L"\\", 2); } if (*strPath) { - wcscpy(wcsPath + dwPathLen, strPath); - dwPathLen += wcslen(strPath); + copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1); + dwPathLen += rtl_ustr_getLength(strPath); } else { - CHAR szPath[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH ); int n; if ((n = WideCharToMultiByte( - CP_ACP,0, wcsPath, -1, szPath, - MAX_PATH, NULL, NULL)) + CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, + aTmpPath.getBufSizeInSymbols(), NULL, NULL)) > 0) { - strcpy(szPath + n, SVERSION_USER); - if (access(szPath, 0) >= 0) + strcpy(aTmpPath + n, SVERSION_USER); + if (access(aTmpPath, 0) >= 0) { dwPathLen += MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, - wcsPath + dwPathLen, - MAX_PATH - dwPathLen ); + reinterpret_cast<LPWSTR>(aPath + dwPathLen), + aPath.getBufSizeInSymbols() - dwPathLen ); } } } @@ -2721,11 +2695,11 @@ static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *str } } - wcsPath[dwPathLen] = 0; + aPath[dwPathLen] = 0; } /* copy filename */ - wcscpy(strProfile, wcsPath); + copy_ustr_n(strProfile, aPath, dwPathLen+1); return sal_True; } diff --git a/sal/osl/w32/salinit.cxx b/sal/osl/w32/salinit.cxx index 992601321..43b7b8a16 100644 --- a/sal/osl/w32/salinit.cxx +++ b/sal/osl/w32/salinit.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: salinit.cxx,v $ - * $Revision: 1.3 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -43,6 +40,26 @@ extern "C" { void SAL_CALL sal_detail_initialize(int argc, char ** argv) { + // SetProcessDEPPolicy(PROCESS_DEP_ENABLE); + // SetDllDirectoryW(L""); + // SetSearchPathMode( + // BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT); + HMODULE h = GetModuleHandleW(L"kernel32.dll"); + if (h != 0) { + FARPROC p = GetProcAddress(h, "SetProcessDEPPolicy"); + if (p != 0) { + reinterpret_cast< BOOL (WINAPI *)(DWORD) >(p)(0x00000001); + } + p = GetProcAddress(h, "SetDllDirectoryW"); + if (p != 0) { + reinterpret_cast< BOOL (WINAPI *)(LPCWSTR) >(p)(L""); + } + p = GetProcAddress(h, "SetSearchPathMode"); + if (p != 0) { + reinterpret_cast< BOOL (WINAPI *)(DWORD) >(p)(0x8001); + } + } + WSADATA wsaData; int error; WORD wVersionRequested; diff --git a/sal/osl/w32/secimpl.h b/sal/osl/w32/secimpl.h index ab77362ea..ef437ca62 100644 --- a/sal/osl/w32/secimpl.h +++ b/sal/osl/w32/secimpl.h @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: secimpl.h,v $ - * $Revision: 1.4 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/security.c b/sal/osl/w32/security.c index adf1b988a..4d9ee324e 100644 --- a/sal/osl/w32/security.c +++ b/sal/osl/w32/security.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: security.c,v $ - * $Revision: 1.14 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/semaphor.c b/sal/osl/w32/semaphor.c index 643fac90c..44bcac70a 100644 --- a/sal/osl/w32/semaphor.c +++ b/sal/osl/w32/semaphor.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: semaphor.c,v $ - * $Revision: 1.6 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/signal.c b/sal/osl/w32/signal.cxx index 0a4ecc344..3869d13ac 100644 --- a/sal/osl/w32/signal.c +++ b/sal/osl/w32/signal.cxx @@ -1,37 +1,37 @@ /************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: signal.c,v $ - * $Revision: 1.12 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +************************************************************************/ /* system headers */ #include "system.h" #include <tchar.h> +#include "file_url.h" +#include "path_helper.hxx" + #include <osl/diagnose.h> #include <osl/mutex.h> #include <osl/signal.h> @@ -115,7 +115,7 @@ static BOOL ReportCrash( LPEXCEPTION_POINTERS lpEP ) BOOL fSuccess = FALSE; BOOL fAutoReport = FALSE; TCHAR szBuffer[1024]; - TCHAR szPath[MAX_PATH]; + ::osl::LongPathBuffer< sal_Char > aPath( MAX_LONG_PATH ); LPTSTR lpFilePart; PROCESS_INFORMATION ProcessInfo; STARTUPINFO StartupInfo; @@ -167,11 +167,11 @@ static BOOL ReportCrash( LPEXCEPTION_POINTERS lpEP ) value_len = quote - value; } - lpVariable = _alloca( variable_len + 1 ); + lpVariable = reinterpret_cast< CHAR* >( _alloca( variable_len + 1 ) ); memcpy( lpVariable, variable, variable_len ); lpVariable[variable_len] = 0; - lpValue = _alloca( value_len + 1); + lpValue = reinterpret_cast< CHAR* >( _alloca( value_len + 1) ); memcpy( lpValue, value, value_len ); lpValue[value_len] = 0; @@ -180,7 +180,7 @@ static BOOL ReportCrash( LPEXCEPTION_POINTERS lpEP ) } } - if ( SearchPath( NULL, TEXT("crashrep.exe"), NULL, MAX_PATH, szPath, &lpFilePart ) ) + if ( SearchPath( NULL, TEXT( "crashrep.exe" ), NULL, aPath.getBufSizeInSymbols(), aPath, &lpFilePart ) ) { ZeroMemory( &StartupInfo, sizeof(StartupInfo) ); StartupInfo.cb = sizeof(StartupInfo.cb); @@ -188,7 +188,7 @@ static BOOL ReportCrash( LPEXCEPTION_POINTERS lpEP ) sntprintf( szBuffer, elementsof(szBuffer), _T("%s -p %u -excp 0x%p -t %u%s"), - szPath, + aPath, GetCurrentProcessId(), lpEP, GetCurrentThreadId(), @@ -317,6 +317,8 @@ static long WINAPI SignalHandlerFunction(LPEXCEPTION_POINTERS lpEP) SetErrorMode(SEM_NOGPFAULTERRORBOX); exit(255); break; + default: + break; } return (EXCEPTION_CONTINUE_EXECUTION); @@ -334,7 +336,7 @@ oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, if (! bInitSignal) bInitSignal = InitSignal(); - pHandler = calloc(1, sizeof(oslSignalHandlerImpl)); + pHandler = reinterpret_cast< oslSignalHandlerImpl* >( calloc( 1, sizeof(oslSignalHandlerImpl) ) ); if (pHandler != NULL) { diff --git a/sal/osl/w32/socket.cxx b/sal/osl/w32/socket.cxx index e91a6d000..c71da4e40 100644 --- a/sal/osl/w32/socket.cxx +++ b/sal/osl/w32/socket.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: socket.cxx,v $ - * $Revision: 1.14 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/sockimpl.h b/sal/osl/w32/sockimpl.h index 5a2a8c341..d2e68da75 100644 --- a/sal/osl/w32/sockimpl.h +++ b/sal/osl/w32/sockimpl.h @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: sockimpl.h,v $ - * $Revision: 1.5 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/system.h b/sal/osl/w32/system.h index 6732e3e66..2bb432394 100644 --- a/sal/osl/w32/system.h +++ b/sal/osl/w32/system.h @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: system.h,v $ - * $Revision: 1.11 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -108,10 +105,22 @@ #endif // #ifdef GCC #ifdef _DLL_ + +#ifdef __cplusplus + extern "C" DWORD g_dwPlatformId; +#else extern DWORD g_dwPlatformId; +#endif // #ifdef __cplusplus + #define IS_NT (g_dwPlatformId == VER_PLATFORM_WIN32_NT) #else + +#ifdef __cplusplus + extern "C" DWORD GetPlatformId(void); +#else extern DWORD GetPlatformId(void); +#endif // #ifdef __cplusplus + #define IS_NT (GetPlatformId() == VER_PLATFORM_WIN32_NT) #endif // #ifdef _DLL_ diff --git a/sal/osl/w32/tempfile.cxx b/sal/osl/w32/tempfile.cxx new file mode 100644 index 000000000..63a5d9a61 --- /dev/null +++ b/sal/osl/w32/tempfile.cxx @@ -0,0 +1,274 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define UNICODE +#define _UNICODE +#define _WIN32_WINNT_0x0500 +#include "systools/win32/uwinapi.h" + +#include "osl/file.h" + +#include "file_error.h" +#include "file_url.h" +#include "path_helper.hxx" + +#include "osl/diagnose.h" + +#include <malloc.h> +#include <tchar.h> + +//##################################################### +#define ELEMENTS_OF_ARRAY(arr) (sizeof(arr)/(sizeof((arr)[0]))) + +// Allocate n number of t's on the stack return a pointer to it in p +#ifdef __MINGW32__ +#define STACK_ALLOC(p, t, n) (p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t))); +#else +#define STACK_ALLOC(p, t, n) __try {(p) = reinterpret_cast<t*>(_alloca((n)*sizeof(t)));} \ + __except(EXCEPTION_EXECUTE_HANDLER) {(p) = 0;} +#endif + +extern "C" oslFileHandle SAL_CALL osl_createFileHandleFromOSHandle(HANDLE hFile, sal_uInt32 uFlags); + +//##################################################### +// Temp file functions +//##################################################### + +static oslFileError osl_setup_base_directory_impl_( + rtl_uString* pustrDirectoryURL, + rtl_uString** ppustr_base_dir) +{ + rtl_uString* dir_url = 0; + rtl_uString* dir = 0; + oslFileError error = osl_File_E_None; + + if (pustrDirectoryURL) + rtl_uString_assign(&dir_url, pustrDirectoryURL); + else + error = osl_getTempDirURL(&dir_url); + + if (osl_File_E_None == error) + { + error = _osl_getSystemPathFromFileURL(dir_url, &dir, sal_False); + rtl_uString_release(dir_url); + } + + if (osl_File_E_None == error ) + { + rtl_uString_assign(ppustr_base_dir, dir); + rtl_uString_release(dir); + } + + return error; +} + +//##################################################### +static oslFileError osl_setup_createTempFile_impl_( + rtl_uString* pustrDirectoryURL, + oslFileHandle* pHandle, + rtl_uString** ppustrTempFileURL, + rtl_uString** ppustr_base_dir, + sal_Bool* b_delete_on_close) +{ + oslFileError osl_error; + + OSL_PRECOND(((0 != pHandle) || (0 != ppustrTempFileURL)), "Invalid parameter!"); + + if ((0 == pHandle) && (0 == ppustrTempFileURL)) + { + osl_error = osl_File_E_INVAL; + } + else + { + osl_error = osl_setup_base_directory_impl_( + pustrDirectoryURL, ppustr_base_dir); + + *b_delete_on_close = (sal_Bool)(0 == ppustrTempFileURL); + } + + return osl_error; +} + +//##################################################### +static oslFileError osl_win32_GetTempFileName_impl_( + rtl_uString* base_directory, LPWSTR temp_file_name) +{ + oslFileError osl_error = osl_File_E_None; + + if (0 == GetTempFileNameW( + reinterpret_cast<LPCWSTR>(rtl_uString_getStr(base_directory)), + L"", + 0, + temp_file_name)) + { + osl_error = oslTranslateFileError(GetLastError()); + } + + return osl_error; +} + +//##################################################### +static sal_Bool osl_win32_CreateFile_impl_( + LPCWSTR file_name, sal_Bool b_delete_on_close, oslFileHandle* p_handle) +{ + DWORD flags = FILE_ATTRIBUTE_NORMAL; + HANDLE hFile; + + OSL_ASSERT(p_handle); + + if (b_delete_on_close) + flags |= FILE_FLAG_DELETE_ON_CLOSE; + + hFile = CreateFileW( + file_name, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + TRUNCATE_EXISTING, + flags, + NULL); + + // @@@ ERROR HANDLING @@@ + if (IsValidHandle(hFile)) + *p_handle = osl_createFileHandleFromOSHandle(hFile, osl_File_OpenFlag_Read | osl_File_OpenFlag_Write); + + return (sal_Bool)IsValidHandle(hFile); +} + +//############################################# +static oslFileError osl_createTempFile_impl_( + rtl_uString* base_directory, + LPWSTR tmp_name, + sal_Bool b_delete_on_close, + oslFileHandle* pHandle, + rtl_uString** ppustrTempFileURL) +{ + oslFileError osl_error; + + do + { + osl_error = osl_win32_GetTempFileName_impl_(base_directory, tmp_name); + + /* if file could not be opened try again */ + + if ((osl_File_E_None != osl_error) || (0 == pHandle) || + osl_win32_CreateFile_impl_(tmp_name, b_delete_on_close, pHandle)) + break; + + } while(1); // try until success + + if ((osl_File_E_None == osl_error) && !b_delete_on_close) + { + rtl_uString* pustr = 0; + rtl_uString_newFromStr(&pustr, reinterpret_cast<const sal_Unicode*>(tmp_name)); + osl_getFileURLFromSystemPath(pustr, ppustrTempFileURL); + rtl_uString_release(pustr); + } + + return osl_error; +} + +//############################################# +oslFileError SAL_CALL osl_createTempFile( + rtl_uString* pustrDirectoryURL, + oslFileHandle* pHandle, + rtl_uString** ppustrTempFileURL) +{ + rtl_uString* base_directory = 0; + LPWSTR tmp_name; + sal_Bool b_delete_on_close; + oslFileError osl_error; + + osl_error = osl_setup_createTempFile_impl_( + pustrDirectoryURL, + pHandle, + ppustrTempFileURL, + &base_directory, + &b_delete_on_close); + + if (osl_File_E_None != osl_error) + return osl_error; + + /* allocate enough space on the stack, the file name can not be longer than MAX_PATH */ + STACK_ALLOC(tmp_name, WCHAR, (rtl_uString_getLength(base_directory) + MAX_PATH)); + + if (tmp_name) + { + osl_createTempFile_impl_( + base_directory, + tmp_name, + b_delete_on_close, + pHandle, + ppustrTempFileURL); + } + else // stack alloc failed + { + osl_error = osl_File_E_NOMEM; + } + + if (base_directory) + rtl_uString_release(base_directory); + + return osl_error; +} + +//############################################# +oslFileError SAL_CALL osl_getTempDirURL(rtl_uString** pustrTempDir) +{ + ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH ); + LPWSTR lpBuffer = ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer); + DWORD nBufferLength = aBuffer.getBufSizeInSymbols() - 1; + + DWORD nLength; + oslFileError error; + + nLength = GetTempPathW( aBuffer.getBufSizeInSymbols(), lpBuffer ); + + if ( nLength > nBufferLength ) + { + // the provided path has invalid length + error = osl_File_E_NOENT; + } + else if ( nLength ) + { + rtl_uString *ustrTempPath = NULL; + + if ( '\\' == lpBuffer[nLength-1] ) + lpBuffer[nLength-1] = 0; + + rtl_uString_newFromStr( &ustrTempPath, reinterpret_cast<const sal_Unicode*>(lpBuffer) ); + + error = osl_getFileURLFromSystemPath( ustrTempPath, pustrTempDir ); + + rtl_uString_release( ustrTempPath ); + } + else + error = oslTranslateFileError( GetLastError() ); + + return error; +} + diff --git a/sal/osl/w32/thread.c b/sal/osl/w32/thread.c index ea6909220..90ff0d2dc 100644 --- a/sal/osl/w32/thread.c +++ b/sal/osl/w32/thread.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: thread.c,v $ - * $Revision: 1.20 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/time.c b/sal/osl/w32/time.c index b6626fdfb..273d785bf 100644 --- a/sal/osl/w32/time.c +++ b/sal/osl/w32/time.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: time.c,v $ - * $Revision: 1.6 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/sal/osl/w32/util.c b/sal/osl/w32/util.c index a2e1fe1f7..b72572fff 100644 --- a/sal/osl/w32/util.c +++ b/sal/osl/w32/util.c @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: util.c,v $ - * $Revision: 1.5 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -32,15 +29,6 @@ -extern sal_Bool osl_getEtherAddr(sal_Char* pszAddr, sal_uInt16 BufferSize) -{ - /* avoid warnings */ - pszAddr = pszAddr; - BufferSize = BufferSize; - - return sal_False; -} - extern sal_Bool SAL_CALL osl_getEthernetAddress( sal_uInt8 *pAddr ) { pAddr = pAddr; /* avoid warnings */ |