diff options
author | Karsten Heimrich <karsten.heimrich@qt.io> | 2021-04-12 14:56:18 +0200 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@qt.io> | 2021-05-12 14:53:12 +0200 |
commit | 776a969bfd426a697ce95481ab7989f9bb351552 (patch) | |
tree | f11e65c3829ed5e9a4d516f9728b07840dcc50bb /src/corelib/io | |
parent | 37d6fd60a800a0956b41870aca338a30e0bd5768 (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/corelib/io')
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 38 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine.cpp | 5 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_win.cpp | 48 |
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; } |