Utils: Fix file saver for delete locked files

If we can not delete a file via the ReplaceFile operation, because we ca
not get the DELETE access right we still can try to replace it contents.

Task-number: QTCREATORBUG-7668
Change-Id: I8804133a0e118518307f33976b821d5b2fdc9b8d
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
David Schulz
2018-09-26 09:49:02 +02:00
parent 4d7f825deb
commit 8d609692b3

View File

@@ -128,13 +128,25 @@ bool SaveFile::commit()
fileName().toStdWString().data(), fileName().toStdWString().data(),
nullptr, REPLACEFILE_IGNORE_MERGE_ERRORS, nullptr, nullptr); nullptr, REPLACEFILE_IGNORE_MERGE_ERRORS, nullptr, nullptr);
if (!result) { if (!result) {
const DWORD replaceErrorCode = GetLastError(); DWORD replaceErrorCode = GetLastError();
QString errorStr; QString errorStr;
if (!QFile::exists(finalFileName)) { if (!QFile::exists(finalFileName)) {
// Replace failed because finalFileName does not exist, try rename. // Replace failed because finalFileName does not exist, try rename.
if (!(result = rename(finalFileName))) if (!(result = rename(finalFileName)))
errorStr = errorString(); errorStr = errorString();
} else { } else {
if (replaceErrorCode == ERROR_UNABLE_TO_REMOVE_REPLACED) {
// If we do not get the rights to remove the original final file we still might try
// to replace the file contents
result = MoveFileEx(fileName().toStdWString().data(),
finalFileName.toStdWString().data(),
MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
| MOVEFILE_WRITE_THROUGH);
if (!result)
replaceErrorCode = GetLastError();
}
if (!result) {
wchar_t messageBuffer[256]; wchar_t messageBuffer[256];
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, replaceErrorCode, nullptr, replaceErrorCode,
@@ -142,6 +154,7 @@ bool SaveFile::commit()
messageBuffer, sizeof(messageBuffer), nullptr); messageBuffer, sizeof(messageBuffer), nullptr);
errorStr = QString::fromWCharArray(messageBuffer); errorStr = QString::fromWCharArray(messageBuffer);
} }
}
if (!result) { if (!result) {
remove(); remove();
setErrorString(errorStr); setErrorString(errorStr);