diff options
-rw-r--r-- | include/osl/file.h | 31 | ||||
-rw-r--r-- | include/osl/file.hxx | 33 | ||||
-rw-r--r-- | sal/osl/unx/file_misc.cxx | 5 | ||||
-rw-r--r-- | sal/osl/w32/file.cxx | 34 | ||||
-rw-r--r-- | sal/util/sal.map | 5 | ||||
-rw-r--r-- | sfx2/source/doc/docfile.cxx | 3 |
6 files changed, 110 insertions, 1 deletions
diff --git a/include/osl/file.h b/include/osl/file.h index 133b93de0c93..cf0bbfb9495d 100644 --- a/include/osl/file.h +++ b/include/osl/file.h @@ -1634,6 +1634,37 @@ SAL_DLLPUBLIC oslFileError SAL_CALL osl_createTempFile( oslFileHandle* pHandle, rtl_uString** ppustrTempFileURL); +/** Move a file to a new destination or rename it, taking old file's identity (if exists). + + Moves or renames a file, replacing an existing file if exist. If the old file existed, + moved file's metadata, e.g. creation time (on FSes which keep files' creation time) or + ACLs, are set to old one's (to keep the old file's identity) - currently this is only + implemented on Windows; on other platforms, this is equivalent to osl_moveFile. + + @param[in] pustrSourceFileURL + Full qualified URL of the source file. + + @param[in] pustrDestFileURL + Full qualified URL of the destination file. + + @retval osl_File_E_None on success + @retval osl_File_E_INVAL the format of the parameters was not valid + @retval osl_File_E_NOMEM not enough memory for allocating structures + @retval osl_File_E_ACCES permission denied + @retval osl_File_E_PERM operation not permitted + @retval osl_File_E_NAMETOOLONG file name too long + @retval osl_File_E_NOENT no such file + @retval osl_File_E_ROFS read-only file system + @retval osl_File_E_BUSY if the implementation internally requires resources that are + (temporarily) unavailable + + @see osl_moveFile() + + @since LibreOffice 6.2 +*/ +SAL_DLLPUBLIC oslFileError SAL_CALL osl_replaceFile(rtl_uString* pustrSourceFileURL, + rtl_uString* pustrDestFileURL); + #ifdef __cplusplus } #endif diff --git a/include/osl/file.hxx b/include/osl/file.hxx index a154aa4f27bc..855398db4038 100644 --- a/include/osl/file.hxx +++ b/include/osl/file.hxx @@ -1298,6 +1298,39 @@ public: return static_cast< RC >( osl_moveFile( ustrSourceFileURL.pData, ustrDestFileURL.pData ) ); } + /** Move a file to a new destination or rename it, taking old file's identity (if exists). + + Moves or renames a file, replacing an existing file if exist. If the old file existed, + moved file's metadata, e.g. creation time (on FSes which keep files' creation time) or + ACLs, are set to old one's (to keep the old file's identity) - currently this is only + implemented on Windows; on other platforms, this is equivalent to osl_moveFile. + + @param[in] ustrSourceFileURL + Full qualified URL of the source file. + + @param[in] ustrDestFileURL + Full qualified URL of the destination file. + + @retval E_None on success + @retval E_INVAL the format of the parameters was not valid + @retval E_NOMEM not enough memory for allocating structures + @retval E_ACCES permission denied + @retval E_PERM operation not permitted + @retval E_NAMETOOLONG file name too long + @retval E_NOENT no such file + @retval E_ROFS read-only file system + @retval E_BUSY device or resource busy + + @see move() + + @since LibreOffice 6.2 + */ + static RC replace(const ::rtl::OUString& ustrSourceFileURL, + const ::rtl::OUString& ustrDestFileURL) + { + return static_cast<RC>(osl_replaceFile(ustrSourceFileURL.pData, ustrDestFileURL.pData)); + } + /** Remove a regular file. @param[in] ustrFileURL diff --git a/sal/osl/unx/file_misc.cxx b/sal/osl/unx/file_misc.cxx index 873bec3cb988..8ae8c74062ee 100644 --- a/sal/osl/unx/file_misc.cxx +++ b/sal/osl/unx/file_misc.cxx @@ -604,6 +604,11 @@ oslFileError SAL_CALL osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrD return oslDoMoveFile( srcPath, destPath ); } +oslFileError SAL_CALL osl_replaceFile(rtl_uString* ustrFileURL, rtl_uString* ustrDestURL) +{ + return osl_moveFile(ustrFileURL, ustrDestURL); +} + oslFileError SAL_CALL osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL ) { char srcPath[PATH_MAX]; diff --git a/sal/osl/w32/file.cxx b/sal/osl/w32/file.cxx index c8b001e9847d..a5e6c640b8ed 100644 --- a/sal/osl/w32/file.cxx +++ b/sal/osl/w32/file.cxx @@ -1099,4 +1099,38 @@ oslFileError SAL_CALL osl_moveFile(rtl_uString* strPath, rtl_uString *strDestPat return error; } +oslFileError SAL_CALL osl_replaceFile(rtl_uString* strPath, rtl_uString* strDestPath) +{ + rtl_uString *strSysPath = nullptr, *strSysDestPath = nullptr; + oslFileError error = osl_getSystemPathFromFileURL_(strPath, &strSysPath, false); + + if (error == osl_File_E_None) + error = osl_getSystemPathFromFileURL_(strDestPath, &strSysDestPath, false); + + if (error == osl_File_E_None) + { + LPCWSTR src = o3tl::toW(rtl_uString_getStr(strSysPath)); + LPCWSTR dst = o3tl::toW(rtl_uString_getStr(strSysDestPath)); + + if (!ReplaceFileW(dst, src, nullptr, + REPLACEFILE_WRITE_THROUGH | REPLACEFILE_IGNORE_MERGE_ERRORS + | REPLACEFILE_IGNORE_ACL_ERRORS, + nullptr, nullptr)) + { + DWORD dwError = GetLastError(); + if (dwError == ERROR_FILE_NOT_FOUND) // no strDestPath file? + error = osl_moveFile(strPath, strDestPath); + else + error = oslTranslateFileError(dwError); + } + } + + if (strSysPath) + rtl_uString_release(strSysPath); + if (strSysDestPath) + rtl_uString_release(strSysDestPath); + + return error; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/util/sal.map b/sal/util/sal.map index 07150ab0340d..9292d50ca423 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -700,6 +700,11 @@ LIBO_UDK_5.3 { # symbols available in >= LibO 5.3 rtl_uString_newReplaceFirstUtf16LUtf16L; } LIBO_UDK_5.2; +LIBO_UDK_6.2 { # symbols available in >= LibO 6.2 + global: + osl_replaceFile; +} LIBO_UDK_5.3; + PRIVATE_1.0 { global: osl_detail_ObjectRegistry_storeAddresses; diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 8da6f3a6e7b8..4cebc868e2bd 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -1845,7 +1845,8 @@ void SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource, OUString aDestMainURL = aDest.GetMainURL(INetURLObject::DecodeMechanism::NONE); sal_uInt64 nAttributes = GetDefaultFileAttributes(aDestMainURL); - if (IsFileMovable(aDestMainURL) && osl::File::move(aSourceMainURL, aDestMainURL) == osl::FileBase::E_None) + if (IsFileMovable(aDestMainURL) + && osl::File::replace(aSourceMainURL, aDestMainURL) == osl::FileBase::E_None) { if (nAttributes) // Adjust attributes, source might be created with |