summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@qt.io>2021-04-12 14:56:18 +0200
committerKarsten Heimrich <karsten.heimrich@qt.io>2021-05-12 14:53:12 +0200
commit776a969bfd426a697ce95481ab7989f9bb351552 (patch)
treef11e65c3829ed5e9a4d516f9728b07840dcc50bb /src
parent37d6fd60a800a0956b41870aca338a30e0bd5768 (diff)
Implement QFileSystemEngine::createLink() on MS-Win
Fixes: QTBUG-74271 Change-Id: I9e414dd16546f65e85b5a1a6c70c40dfa4284a6f Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp38
-rw-r--r--src/corelib/io/qfsfileengine.cpp5
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp48
3 files changed, 42 insertions, 49 deletions
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 6fa6ec2dc2..6c4418a83b 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -1313,12 +1313,40 @@ QFileSystemEntry QFileSystemEngine::currentPath()
//static
bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
- Q_ASSERT(false);
- Q_UNUSED(source);
- Q_UNUSED(target);
- Q_UNUSED(error);
+ bool ret = false;
+ IShellLink *psl = nullptr;
+ HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void **>(&psl));
- return false; // TODO implement; - code needs to be moved from qfsfileengine_win.cpp
+ bool neededCoInit = false;
+ if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
+ neededCoInit = true;
+ CoInitialize(nullptr);
+ hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void **>(&psl));
+ }
+
+ if (SUCCEEDED(hres)) {
+ const auto name = QDir::toNativeSeparators(source.filePath());
+ const auto pathName = QDir::toNativeSeparators(source.path());
+ if (SUCCEEDED(psl->SetPath(reinterpret_cast<const wchar_t *>(name.utf16())))
+ && SUCCEEDED(psl->SetWorkingDirectory(reinterpret_cast<const wchar_t *>(pathName.utf16())))) {
+ IPersistFile *ppf = nullptr;
+ if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void **>(&ppf)))) {
+ ret = SUCCEEDED(ppf->Save(reinterpret_cast<const wchar_t *>(target.filePath().utf16()), TRUE));
+ ppf->Release();
+ }
+ }
+ psl->Release();
+ }
+
+ if (!ret)
+ error = QSystemError(::GetLastError(), QSystemError::NativeError);
+
+ if (neededCoInit)
+ CoUninitialize();
+
+ return ret;
}
//static
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 1a1a9076c7..cef5a1f3e7 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -981,7 +981,10 @@ QString QFSFileEngine::tempPath()
Creates a link from the file currently specified by fileName() to
\a newName. What a link is depends on the underlying filesystem
(be it a shortcut on Windows or a symbolic link on Unix). Returns
- true if successful; otherwise returns \c false.
+ \c true if successful; otherwise returns \c false.
+
+ \note On Windows \a newName is expected to end with .lnk as the filename
+ extension.
*/
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 84ba42f55a..fad9f5e48b 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -494,52 +494,14 @@ bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) cons
return metaData.exists();
}
-
+// ### assume that they add .lnk to newName
bool QFSFileEngine::link(const QString &newName)
{
- bool ret = false;
-
- QString linkName = newName;
- //### assume that they add .lnk
-
- IShellLink *psl;
- bool neededCoInit = false;
-
- HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink,
- reinterpret_cast<void **>(&psl));
-
- if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
- neededCoInit = true;
- CoInitialize(nullptr);
- hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink,
- reinterpret_cast<void **>(&psl));
- }
-
- if (SUCCEEDED(hres)) {
- const QString nativeAbsoluteName = fileName(AbsoluteName).replace(QLatin1Char('/'), QLatin1Char('\\'));
- hres = psl->SetPath(reinterpret_cast<const wchar_t *>(nativeAbsoluteName.utf16()));
- if (SUCCEEDED(hres)) {
- const QString nativeAbsolutePathName = fileName(AbsolutePathName).replace(QLatin1Char('/'), QLatin1Char('\\'));
- hres = psl->SetWorkingDirectory(reinterpret_cast<const wchar_t *>(nativeAbsolutePathName.utf16()));
- if (SUCCEEDED(hres)) {
- IPersistFile *ppf;
- hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void **>(&ppf));
- if (SUCCEEDED(hres)) {
- hres = ppf->Save(reinterpret_cast<const wchar_t *>(linkName.utf16()), TRUE);
- if (SUCCEEDED(hres))
- ret = true;
- ppf->Release();
- }
- }
- }
- psl->Release();
- }
+ QSystemError error;
+ bool ret = QFileSystemEngine::createLink(QFileSystemEntry(fileName(AbsoluteName)),
+ QFileSystemEntry(newName), error);
if (!ret)
- setError(QFile::RenameError, qt_error_string());
-
- if (neededCoInit)
- CoUninitialize();
-
+ setError(QFile::RenameError, error.toString());
return ret;
}