summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp132
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp3
2 files changed, 69 insertions, 66 deletions
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 71a0e36693..36d43e9cb7 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -1546,73 +1546,79 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source,
// we need the "display name" of the file, so can't use nativeFilePath
const QString sourcePath = QDir::toNativeSeparators(source.filePath());
+ /*
+ Windows 7 insists on showing confirmation dialogs and ignores the respective
+ flags set on IFileOperation. Fall back to SHFileOperation, even if it doesn't
+ give us the new location of the file.
+ */
+ if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) {
# if defined(__IFileOperation_INTERFACE_DEFINED__)
- CoInitialize(NULL);
- IFileOperation *pfo = nullptr;
- IShellItem *deleteItem = nullptr;
- FileOperationProgressSink *sink = nullptr;
- HRESULT hres = E_FAIL;
-
- auto coUninitialize = qScopeGuard([&](){
- if (sink)
- sink->Release();
- if (deleteItem)
- deleteItem->Release();
- if (pfo)
- pfo->Release();
- CoUninitialize();
+ CoInitialize(NULL);
+ IFileOperation *pfo = nullptr;
+ IShellItem *deleteItem = nullptr;
+ FileOperationProgressSink *sink = nullptr;
+ HRESULT hres = E_FAIL;
+
+ auto coUninitialize = qScopeGuard([&](){
+ if (sink)
+ sink->Release();
+ if (deleteItem)
+ deleteItem->Release();
+ if (pfo)
+ pfo->Release();
+ CoUninitialize();
+ if (!SUCCEEDED(hres))
+ error = QSystemError(hres, QSystemError::NativeError);
+ });
+
+ hres = CoCreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pfo));
+ if (!pfo)
+ return false;
+ pfo->SetOperationFlags(FOF_ALLOWUNDO | FOFX_RECYCLEONDELETE | FOF_NOCONFIRMATION
+ | FOF_SILENT | FOF_NOERRORUI);
+ hres = SHCreateItemFromParsingName(reinterpret_cast<const wchar_t*>(sourcePath.utf16()),
+ nullptr, IID_PPV_ARGS(&deleteItem));
+ if (!deleteItem)
+ return false;
+ sink = new FileOperationProgressSink;
+ hres = pfo->DeleteItem(deleteItem, static_cast<IFileOperationProgressSink*>(sink));
+ if (!SUCCEEDED(hres))
+ return false;
+ hres = pfo->PerformOperations();
if (!SUCCEEDED(hres))
- error = QSystemError(hres, QSystemError::NativeError);
- });
+ return false;
+ newLocation = QFileSystemEntry(sink->targetPath);
- hres = CoCreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pfo));
- if (!pfo)
- return false;
- pfo->SetOperationFlags(FOF_ALLOWUNDO | FOFX_RECYCLEONDELETE | FOF_NOCONFIRMATION
- | FOF_SILENT | FOF_NOERRORUI);
- hres = SHCreateItemFromParsingName(reinterpret_cast<const wchar_t*>(sourcePath.utf16()),
- nullptr, IID_PPV_ARGS(&deleteItem));
- if (!deleteItem)
- return false;
- sink = new FileOperationProgressSink;
- hres = pfo->DeleteItem(deleteItem, static_cast<IFileOperationProgressSink*>(sink));
- if (!SUCCEEDED(hres))
- return false;
- hres = pfo->PerformOperations();
- if (!SUCCEEDED(hres))
- return false;
- newLocation = QFileSystemEntry(sink->targetPath);
-
-# else // no IFileOperation in SDK (mingw, likely) - fall back to SHFileOperation
-
- // double null termination needed, so can't use QString::utf16
- QVarLengthArray<wchar_t, MAX_PATH + 1> winFile(sourcePath.length() + 2);
- sourcePath.toWCharArray(winFile.data());
- winFile[sourcePath.length()] = wchar_t{};
- winFile[sourcePath.length() + 1] = wchar_t{};
-
- SHFILEOPSTRUCTW operation;
- operation.hwnd = nullptr;
- operation.wFunc = FO_DELETE;
- operation.pFrom = winFile.constData();
- operation.pTo = nullptr;
- operation.fFlags = FOF_ALLOWUNDO | FOF_NO_UI;
- operation.fAnyOperationsAborted = FALSE;
- operation.hNameMappings = nullptr;
- operation.lpszProgressTitle = nullptr;
-
- int result = SHFileOperation(&operation);
- if (result != 0) {
- error = QSystemError(result, QSystemError::NativeError);
- return false;
+# endif // no IFileOperation in SDK (mingw, likely) - fall back to SHFileOperation
+ } else {
+ // double null termination needed, so can't use QString::utf16
+ QVarLengthArray<wchar_t, MAX_PATH + 1> winFile(sourcePath.length() + 2);
+ sourcePath.toWCharArray(winFile.data());
+ winFile[sourcePath.length()] = wchar_t{};
+ winFile[sourcePath.length() + 1] = wchar_t{};
+
+ SHFILEOPSTRUCTW operation;
+ operation.hwnd = nullptr;
+ operation.wFunc = FO_DELETE;
+ operation.pFrom = winFile.constData();
+ operation.pTo = nullptr;
+ operation.fFlags = FOF_ALLOWUNDO | FOF_NO_UI;
+ operation.fAnyOperationsAborted = FALSE;
+ operation.hNameMappings = nullptr;
+ operation.lpszProgressTitle = nullptr;
+
+ int result = SHFileOperation(&operation);
+ if (result != 0) {
+ error = QSystemError(result, QSystemError::NativeError);
+ return false;
+ }
+ /*
+ This implementation doesn't let us know where the file ended up, even if
+ we would specify FOF_WANTMAPPINGHANDLE | FOF_RENAMEONCOLLISION, as
+ FOF_RENAMEONCOLLISION has no effect unless files are moved, copied, or renamed.
+ */
+ Q_UNUSED(newLocation);
}
- /*
- This implementation doesn't let us know where the file ended up, even if
- we would specify FOF_WANTMAPPINGHANDLE | FOF_RENAMEONCOLLISION, as
- FOF_RENAMEONCOLLISION has no effect unless files are moved, copied, or renamed.
- */
- Q_UNUSED(newLocation);
-# endif // IFileOperation fallback
return true;
#else // Q_OS_WINRT
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index b065e1f10f..350bff0652 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -3681,9 +3681,6 @@ void tst_QFile::moveToTrash_data()
QTest::addColumn<bool>("create");
QTest::addColumn<bool>("result");
- if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::Windows7)
- QSKIP("Windows 7 insists on showing a confirmation dialog", SkipAll);
-
// success cases
{
QTemporaryFile temp;