diff options
Diffstat (limited to 'sal/osl/w32/file_dirvol.cxx')
-rw-r--r-- | sal/osl/w32/file_dirvol.cxx | 217 |
1 files changed, 155 insertions, 62 deletions
diff --git a/sal/osl/w32/file_dirvol.cxx b/sal/osl/w32/file_dirvol.cxx index d74f78fb30e2..734824d63e57 100644 --- a/sal/osl/w32/file_dirvol.cxx +++ b/sal/osl/w32/file_dirvol.cxx @@ -34,6 +34,7 @@ #include "file_url.h" #include "file_error.h" + #include "path_helper.hxx" #include "osl/diagnose.h" @@ -291,7 +292,7 @@ struct DirectoryItem_Impl WIN32_FIND_DATA FindData; TCHAR cDriveString[MAX_PATH]; }; - TCHAR szFullPath[MAX_PATH]; + rtl_uString* m_pFullPath; BOOL bFullPathNormalized; int nRefCount; }; @@ -310,7 +311,7 @@ struct Directory_Impl HANDLE hDirectory; HANDLE hEnumDrives; }; - TCHAR szDirectoryPath[MAX_PATH]; + rtl_uString* m_pDirectoryPath; }; //##################################################### @@ -395,34 +396,48 @@ typedef struct tagDIRECTORY } DIRECTORY, *PDIRECTORY, FAR *LPDIRECTORY; //##################################################### -static HANDLE WINAPI OpenDirectory(LPCTSTR lpszPath) +static HANDLE WINAPI OpenDirectory( rtl_uString* pPath) { - LPDIRECTORY pDirectory = (LPDIRECTORY)HeapAlloc(GetProcessHeap(), 0, sizeof(DIRECTORY)); + LPDIRECTORY pDirectory = NULL; - if (pDirectory) + if ( pPath ) { - TCHAR szFileMask[MAX_PATH]; - int nLen; + 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; + } - _tcscpy( szFileMask, lpszPath ); - nLen = _tcslen( szFileMask ); + TCHAR* szFileMask = reinterpret_cast< TCHAR* >( rtl_allocateMemory( sizeof( TCHAR ) * ( nLen + nSuffLen + 1 ) ) ); - if (nLen && szFileMask[nLen-1] != '\\') - _tcscat(szFileMask, TEXT("\\*.*")); - else - _tcscat(szFileMask, TEXT("*.*")); + _tcscpy( szFileMask, reinterpret_cast<LPCTSTR>( rtl_uString_getStr( pPath ) ) ); + _tcscat( szFileMask, pSuffix ); - pDirectory->hFind = FindFirstFile(szFileMask, &pDirectory->aFirstData); + pDirectory = (LPDIRECTORY)HeapAlloc(GetProcessHeap(), 0, sizeof(DIRECTORY)); + pDirectory->hFind = FindFirstFile(szFileMask, &pDirectory->aFirstData); - if (!IsValidHandle(pDirectory->hFind)) - { - if ( GetLastError() != ERROR_NO_MORE_FILES ) + if (!IsValidHandle(pDirectory->hFind)) { - HeapFree(GetProcessHeap(), 0, pDirectory); - pDirectory = NULL; + if ( GetLastError() != ERROR_NO_MORE_FILES ) + { + HeapFree(GetProcessHeap(), 0, pDirectory); + pDirectory = NULL; + } } } } + return (HANDLE)pDirectory; } @@ -499,15 +514,26 @@ static oslFileError osl_openLocalRoot( Directory_Impl *pDirImpl; pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory( sizeof(Directory_Impl))); - _tcscpy( pDirImpl->szDirectoryPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysPath)) ); + ZeroMemory( pDirImpl, sizeof(Directory_Impl) ); + rtl_uString_newFromString( &pDirImpl->m_pDirectoryPath, strSysPath ); /* Append backslash if neccessary */ /* @@@ToDo use function ensure backslash */ - if ( pDirImpl->szDirectoryPath[_tcslen(pDirImpl->szDirectoryPath) - 1] != L'\\' ) - _tcscat( pDirImpl->szDirectoryPath, L"\\" ); + 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_newFromStr( &pBackSlash, L"\\" ); + rtl_uString_newConcat( &pDirImpl->m_pDirectoryPath, pCurDir, pBackSlash ); + rtl_uString_release( pBackSlash ); + rtl_uString_release( pCurDir ); + } pDirImpl->uType = DIRECTORYTYPE_LOCALROOT; pDirImpl->hEnumDrives = OpenLogicalDrivesEnum(); @@ -523,7 +549,16 @@ static oslFileError osl_openLocalRoot( 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() ); } @@ -544,23 +579,41 @@ static oslFileError SAL_CALL osl_openFileDirectory( *pDirectory = NULL; Directory_Impl *pDirImpl = reinterpret_cast<Directory_Impl*>(rtl_allocateMemory(sizeof(Directory_Impl))); - _tcscpy( pDirImpl->szDirectoryPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strDirectoryPath)) ); + ZeroMemory( pDirImpl, sizeof(Directory_Impl) ); + rtl_uString_newFromString( &pDirImpl->m_pDirectoryPath, strDirectoryPath ); /* Append backslash if neccessary */ /* @@@ToDo use function ensure backslash */ - if ( pDirImpl->szDirectoryPath[_tcslen(pDirImpl->szDirectoryPath) - 1] != L'\\' ) - _tcscat( pDirImpl->szDirectoryPath, L"\\" ); + 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_newFromStr( &pBackSlash, L"\\" ); + rtl_uString_newConcat( &pDirImpl->m_pDirectoryPath, pCurDir, pBackSlash ); + rtl_uString_release( pBackSlash ); + rtl_uString_release( pCurDir ); + } + pDirImpl->uType = DIRECTORYTYPE_FILESYSTEM; - pDirImpl->hDirectory = OpenDirectory( pDirImpl->szDirectoryPath ); + 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; } @@ -592,6 +645,7 @@ static oslFileError SAL_CALL osl_openNetworkServer( 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; @@ -609,7 +663,11 @@ static DWORD create_dir_with_callback( // user specified callback function. On success // the function returns ERROR_SUCCESS else a Win32 error code. - if (CreateDirectory(reinterpret_cast<LPCTSTR>(dir_path->buffer), NULL)) + BOOL bCreated = FALSE; + + bCreated = CreateDirectoryW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( dir_path )), NULL ); + + if ( bCreated ) { if (aDirectoryCreationCallbackFunc) { @@ -705,15 +763,18 @@ oslFileError SAL_CALL osl_createDirectory(rtl_uString* strPath) if ( osl_File_E_None == error ) { - if ( CreateDirectoryW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strSysPath )), NULL ) ) - 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 + 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 ); @@ -862,6 +923,12 @@ static oslFileError SAL_CALL osl_getNextDrive( } else { + if ( pItemImpl->m_pFullPath ) + { + rtl_uString_release( pItemImpl->m_pFullPath ); + pItemImpl->m_pFullPath = 0; + } + rtl_freeMemory( pItemImpl ); return oslTranslateFileError( GetLastError() ); } @@ -895,14 +962,24 @@ static oslFileError SAL_CALL osl_getNextFileItem( { pItemImpl->uType = DIRECTORYITEM_FILE; pItemImpl->nRefCount = 1; - _tcscpy( pItemImpl->szFullPath, pDirImpl->szDirectoryPath ); - _tcscat( pItemImpl->szFullPath, pItemImpl->FindData.cFileName ); + + rtl_uString* pTmpFileName = 0; + rtl_uString_newFromStr( &pTmpFileName, 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() ); } @@ -963,6 +1040,12 @@ oslFileError SAL_CALL osl_closeDirectory(oslDirectory Directory) break; } + if ( pDirImpl->m_pDirectoryPath ) + { + rtl_uString_release( pDirImpl->m_pDirectoryPath ); + pDirImpl->m_pDirectoryPath = 0; + } + rtl_freeMemory(pDirImpl); } return eError; @@ -1024,8 +1107,7 @@ oslFileError SAL_CALL osl_getDirectoryItem(rtl_uString *strFilePath, oslDirector pItemImpl->uType = DIRECTORYITEM_SERVER; osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl ); - - _tcscpy( pItemImpl->szFullPath, reinterpret_cast<LPCTSTR>(strSysFilePath->buffer) ); + rtl_uString_newFromString( &pItemImpl->m_pFullPath, strSysFilePath ); // Assign a title anyway { @@ -1088,7 +1170,7 @@ oslFileError SAL_CALL osl_getDirectoryItem(rtl_uString *strFilePath, oslDirector osl_acquireDirectoryItem( (oslDirectoryItem)pItemImpl ); CopyMemory( &pItemImpl->FindData, &aFindData, sizeof(WIN32_FIND_DATA) ); - _tcscpy( pItemImpl->szFullPath, reinterpret_cast<LPCTSTR>(rtl_uString_getStr(strSysFilePath)) ); + rtl_uString_newFromString( &pItemImpl->m_pFullPath, strSysFilePath ); // MT: This costs 600ms startup time on fast v60x! // GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) ); @@ -1130,7 +1212,16 @@ oslFileError SAL_CALL osl_releaseDirectoryItem( oslDirectoryItem Item ) 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; } @@ -1344,18 +1435,22 @@ static oslFileError get_filesystem_attributes( } if (is_filesystem_attributes_request(field_mask)) { - WCHAR vn[MAX_PATH]; - WCHAR fsn[MAX_PATH]; + /* 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, &serial, &mcl, &flags, fsn, MAX_PATH)) + 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; @@ -1558,11 +1653,7 @@ static oslFileError SAL_CALL osl_getServerInfo( if ( uFieldMask & osl_FileStatus_Mask_FileURL ) { - rtl_uString *ustrSystemPath = NULL; - - rtl_uString_newFromStr( &ustrSystemPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) ); - osl_getFileURLFromSystemPath( ustrSystemPath, &pStatus->ustrFileURL ); - rtl_uString_release( ustrSystemPath ); + osl_getFileURLFromSystemPath( pItemImpl->m_pFullPath, &pStatus->ustrFileURL ); pStatus->uValidFields |= osl_FileStatus_Mask_FileURL; } return osl_File_E_None; @@ -1591,7 +1682,7 @@ oslFileError SAL_CALL osl_getFileStatus( if ( uFieldMask & osl_FileStatus_Mask_Validate ) { - HANDLE hFind = FindFirstFile( pItemImpl->szFullPath, &pItemImpl->FindData ); + HANDLE hFind = FindFirstFile( reinterpret_cast<LPCTSTR>( rtl_uString_getStr( pItemImpl->m_pFullPath ) ), &pItemImpl->FindData ); if ( hFind != INVALID_HANDLE_VALUE ) FindClose( hFind ); @@ -1651,28 +1742,30 @@ oslFileError SAL_CALL osl_getFileStatus( 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 ); + osl_getFileURLFromSystemPath( pItemImpl->m_pFullPath, &pStatus->ustrLinkTargetURL ); pStatus->uValidFields |= osl_FileStatus_Mask_LinkTargetURL; } if ( uFieldMask & osl_FileStatus_Mask_FileURL ) { - rtl_uString *ustrFullPath = NULL; - - if ( !pItemImpl->bFullPathNormalized ) { - GetCaseCorrectPathName( pItemImpl->szFullPath, pItemImpl->szFullPath, sizeof(pItemImpl->szFullPath) ); - pItemImpl->bFullPathNormalized = TRUE; + 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 ) ), + aBuffer, + aBuffer.getBufSizeInSymbols(), + sal_True ); + + if ( nNewLen ) + { + rtl_uString_newFromStr( &pItemImpl->m_pFullPath, aBuffer ); + pItemImpl->bFullPathNormalized = TRUE; + } } - rtl_uString_newFromStr( &ustrFullPath, reinterpret_cast<const sal_Unicode*>(pItemImpl->szFullPath) ); - osl_getFileURLFromSystemPath( ustrFullPath, &pStatus->ustrFileURL ); - rtl_uString_release( ustrFullPath ); + + osl_getFileURLFromSystemPath( pItemImpl->m_pFullPath, &pStatus->ustrFileURL ); pStatus->uValidFields |= osl_FileStatus_Mask_FileURL; } |