summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2018-09-07 17:11:48 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2018-09-27 16:43:48 +0200
commitc9343988204ee3e9889f3cc833adbbaca83e53e6 (patch)
treebe94bfad127deb256a55e957b3a82268e3ef97b9 /sal
parentbfd2393ca7247aae1b09e661610a5f750b6e06fa (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.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 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;