diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index aaf3d1f5fb..7705f1ab95 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -231,7 +231,8 @@ bool QSaveFile::open(OpenMode mode)
d->finalFileName = existingFile.filePath();
}
- d->fileEngine = new QTemporaryFileEngine(QTemporaryFileEngine::Win32NonShared);
+ d->fileEngine = new QTemporaryFileEngine(QTemporaryFileEngine::Win32NonShared
+ | QTemporaryFileEngine::Win32OpenForDelete);
// if the target file exists, we'll copy its permissions below,
// but until then, let's ensure the temporary file is not accessible
// to a third party
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 4712e65a41..75136b0059 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -37,6 +37,9 @@
**
****************************************************************************/
+#define WINVER 0x0600
+#define _WIN32_WINNT 0x0600
+
#include "qtemporaryfile.h"
#ifndef QT_NO_TEMPORARYFILE
@@ -46,6 +49,11 @@
#include "private/qfile_p.h"
#include "private/qsystemerror_p.h"
+#ifdef Q_OS_WIN
+#include "qbytearray.h"
+#include "qt_windows.h"
+#endif
+
#if !defined(Q_OS_WIN)
#include "private/qcore_unix_p.h" // overrides QT_OPEN
#include <errno.h>
@@ -153,15 +161,18 @@ static bool createFileFromTemplate(NativeFileHandle &file,
Q_UNUSED(mode);
const DWORD shareMode = (flags & QTemporaryFileEngine::Win32NonShared)
? 0u : (FILE_SHARE_READ | FILE_SHARE_WRITE);
+ const DWORD desiredAccess = GENERIC_READ | GENERIC_WRITE | (flags
+ & QTemporaryFileEngine::Win32OpenForDelete)
+ ? DELETE : 0u;
# ifndef Q_OS_WINRT
file = CreateFile((const wchar_t *)path.constData(),
- GENERIC_READ | GENERIC_WRITE,
+ desiredAccess,
shareMode, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
# else // !Q_OS_WINRT
file = CreateFile2((const wchar_t *)path.constData(),
- GENERIC_READ | GENERIC_WRITE,
+ desiredAccess,
shareMode, CREATE_NEW,
NULL);
# endif // Q_OS_WINRT
@@ -393,6 +404,25 @@ bool QTemporaryFileEngine::rename(const QString &newName)
bool QTemporaryFileEngine::renameOverwrite(const QString &newName)
{
+#ifdef Q_OS_WIN
+ Q_D(const QFSFileEngine);
+ if (flags & QTemporaryFileEngine::Win32OpenForDelete && d->fileHandle != INVALID_HANDLE_VALUE) {
+ QString newPath = QFileSystemEntry(newName).nativeFilePath();
+ QByteArray fileRenameInfoData(sizeof(FILE_RENAME_INFO) + newPath.size() * sizeof(wchar_t), '\0');
+ FILE_RENAME_INFO &fileRenameInfo = *((FILE_RENAME_INFO *)fileRenameInfoData.data());
+ fileRenameInfo.ReplaceIfExists = TRUE;
+ fileRenameInfo.RootDirectory = nullptr;
+ fileRenameInfo.FileNameLength = newPath.size();
+ newPath.toWCharArray(fileRenameInfo.FileName);
+ bool ret = ::SetFileInformationByHandle(d->fileHandle, FileRenameInfo, &fileRenameInfo, fileRenameInfoData.size());
+ //bool ret = ::MoveFileEx((wchar_t*)d->fileEntry.nativeFilePath().utf16(),
+ // (wchar_t*)QFileSystemEntry(newName).nativeFilePath().utf16(),
+ // MOVEFILE_REPLACE_EXISTING) != 0;
+ if (!ret)
+ setError(QFile::RenameError, QSystemError(::GetLastError(), QSystemError::NativeError).toString());
+ return ret;
+ }
+#endif
QFSFileEngine::close();
return QFSFileEngine::renameOverwrite(newName);
}
diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h
index b0fab3a255..d347369707 100644
--- a/src/corelib/io/qtemporaryfile_p.h
+++ b/src/corelib/io/qtemporaryfile_p.h
@@ -85,7 +85,7 @@ class QTemporaryFileEngine : public QFSFileEngine
{
Q_DECLARE_PRIVATE(QFSFileEngine)
public:
- enum Flags { Win32NonShared = 0x1 };
+ enum Flags { Win32NonShared = 0x1, Win32OpenForDelete = 0x2 };
explicit QTemporaryFileEngine(int _flags = 0) : flags(_flags) {}