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>
This commit is contained in:
parent
37d6fd60a8
commit
776a969bfd
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user