diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2018-09-07 17:11:48 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2018-09-27 16:43:48 +0200 |
commit | c9343988204ee3e9889f3cc833adbbaca83e53e6 (patch) | |
tree | be94bfad127deb256a55e957b3a82268e3ef97b9 /sal | |
parent | bfd2393ca7247aae1b09e661610a5f750b6e06fa (diff) |
tdf#119238: keep replaced file's identity when renaming docfile
Regression from 2157a3536f97ff5ae7c82611a801fef7e3708983
sfx2 store: try rename before copying
Rename is cheaper then copying the content over manually, so try that
first.
On Windows, we need to keep the file's dentity, including metadata (e.g.,
creation time, which is kept in FS). WinAPI has ReplaceFileW specifically
for this, and it keeps ACLs of the original file, and otherwise makes the
changed file not a separate entry, but updated old file from system's PoV.
Eventually, we could try to restructure creating backup copies (e.g., for
documents when configured so) to take advantage of this function being able
to do that.
Change-Id: I6001a2a3af5e10bc010f5ef129f4bb6f83ee1581
Reviewed-on: https://gerrit.libreoffice.org/60163
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Tested-by: Jenkins
Diffstat (limited to 'sal')
-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 |
3 files changed, 44 insertions, 0 deletions
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; |