summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2018-09-07 17:11:48 +0300
committerStephan Bergmann <sbergman@redhat.com>2018-09-27 23:20:32 +0200
commit4f28521bf96d4a5fedad3c85171baba412abbb0e (patch)
treea5e16b6ef56288ca3e130306e35304cd782374b4 /sal
parent3ab472e718ea590a5c0dba572cf91e79ab916562 (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 (cherry picked from commit c9343988204ee3e9889f3cc833adbbaca83e53e6) Reviewed-on: https://gerrit.libreoffice.org/61041
Diffstat (limited to 'sal')
-rw-r--r--sal/osl/unx/file_misc.cxx5
-rw-r--r--sal/osl/w32/file.cxx34
-rw-r--r--sal/util/sal.map5
3 files changed, 44 insertions, 0 deletions
diff --git a/sal/osl/unx/file_misc.cxx b/sal/osl/unx/file_misc.cxx
index 7e3386cfa4e5..8126a4db23d0 100644
--- a/sal/osl/unx/file_misc.cxx
+++ b/sal/osl/unx/file_misc.cxx
@@ -603,6 +603,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 aed1b315bb9e..b3f68ea94e32 100644
--- a/sal/osl/w32/file.cxx
+++ b/sal/osl/w32/file.cxx
@@ -1156,4 +1156,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 86ad07525ee6..e5c8cdb58fc5 100644
--- a/sal/util/sal.map
+++ b/sal/util/sal.map
@@ -707,6 +707,11 @@ LIBO_UDK_5.3 { # symbols available in >= LibO 5.3
rtl_uString_newReplaceFirstUtf16LUtf16L;
} LIBO_UDK_5.2;
+LIBO_UDK_6.1 { # symbols available in >= LibO 6.1
+ global:
+ osl_replaceFile;
+} LIBO_UDK_5.3;
+
PRIVATE_1.0 {
global:
osl_detail_ObjectRegistry_storeAddresses;