aboutsummaryrefslogtreecommitdiff
path: root/launcher/FileSystem.cpp
diff options
context:
space:
mode:
authorSefa Eyeoglu <contact@scrumplex.net>2022-12-14 23:22:27 +0100
committerSefa Eyeoglu <contact@scrumplex.net>2022-12-14 23:22:27 +0100
commit849b92665e0762a38a7e17403015e2b037318aec (patch)
tree2fbeac111297727aa6613aacc08e80dcec5c3724 /launcher/FileSystem.cpp
parentfdbd8d9d2b2e04cd68fd800882309b40c05aba2c (diff)
parentd193ed9eebb392b259edb88a227dce4cee773df6 (diff)
downloadPrismLauncher-849b92665e0762a38a7e17403015e2b037318aec.tar.gz
PrismLauncher-849b92665e0762a38a7e17403015e2b037318aec.tar.bz2
PrismLauncher-849b92665e0762a38a7e17403015e2b037318aec.zip
Merge branch 'develop' into remove-updater
Diffstat (limited to 'launcher/FileSystem.cpp')
-rw-r--r--launcher/FileSystem.cpp187
1 files changed, 161 insertions, 26 deletions
diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp
index 0c6527b1..3e8e10a5 100644
--- a/launcher/FileSystem.cpp
+++ b/launcher/FileSystem.cpp
@@ -49,6 +49,7 @@
#include "StringUtils.h"
#if defined Q_OS_WIN32
+#define WIN32_LEAN_AND_MEAN
#include <objbase.h>
#include <objidl.h>
#include <shlguid.h>
@@ -188,6 +189,8 @@ bool copy::operator()(const QString& offset, bool dryRun)
qDebug() << "Source file:" << src_path;
qDebug() << "Destination file:" << dst_path;
}
+ m_copied++;
+ emit fileCopied(relative_dst_path);
};
// We can't use copy_opts::recursive because we need to take into account the
@@ -341,12 +344,35 @@ QString getDesktopDir()
}
// Cross-platform Shortcut creation
-bool createShortCut(QString location, QString dest, QStringList args, QString name, QString icon)
+bool createShortcut(QString destination, QString target, QStringList args, QString name, QString icon)
{
-#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
- location = PathCombine(location, name + ".desktop");
+#if defined(Q_OS_MACOS)
+ destination += ".command";
- QFile f(location);
+ QFile f(destination);
+ f.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream stream(&f);
+
+ QString argstring;
+ if (!args.empty())
+ argstring = " \"" + args.join("\" \"") + "\"";
+
+ stream << "#!/bin/bash"
+ << "\n";
+ stream << "\""
+ << target
+ << "\" "
+ << argstring
+ << "\n";
+
+ stream.flush();
+ f.close();
+
+ f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther);
+
+ return true;
+#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
+ QFile f(destination);
f.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream stream(&f);
@@ -358,10 +384,12 @@ bool createShortCut(QString location, QString dest, QStringList args, QString na
<< "\n";
stream << "Type=Application"
<< "\n";
- stream << "TryExec=" << dest.toLocal8Bit() << "\n";
- stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
+ stream << "Exec=\"" << target.toLocal8Bit() << "\"" << argstring.toLocal8Bit() << "\n";
stream << "Name=" << name.toLocal8Bit() << "\n";
- stream << "Icon=" << icon.toLocal8Bit() << "\n";
+ if (!icon.isEmpty())
+ {
+ stream << "Icon=" << icon.toLocal8Bit() << "\n";
+ }
stream.flush();
f.close();
@@ -369,25 +397,132 @@ bool createShortCut(QString location, QString dest, QStringList args, QString na
f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther);
return true;
-#elif defined Q_OS_WIN
- // TODO: Fix
- // QFile file(PathCombine(location, name + ".lnk"));
- // WCHAR *file_w;
- // WCHAR *dest_w;
- // WCHAR *args_w;
- // file.fileName().toWCharArray(file_w);
- // dest.toWCharArray(dest_w);
-
- // QString argStr;
- // for (int i = 0; i < args.count(); i++)
- // {
- // argStr.append(args[i]);
- // argStr.append(" ");
- // }
- // argStr.toWCharArray(args_w);
-
- // return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
- return false;
+#elif defined(Q_OS_WIN)
+ QFileInfo targetInfo(target);
+
+ if (!targetInfo.exists())
+ {
+ qWarning() << "Target file does not exist!";
+ return false;
+ }
+
+ target = targetInfo.absoluteFilePath();
+
+ if (target.length() >= MAX_PATH)
+ {
+ qWarning() << "Target file path is too long!";
+ return false;
+ }
+
+ if (!icon.isEmpty() && icon.length() >= MAX_PATH)
+ {
+ qWarning() << "Icon path is too long!";
+ return false;
+ }
+
+ destination += ".lnk";
+
+ if (destination.length() >= MAX_PATH)
+ {
+ qWarning() << "Destination path is too long!";
+ return false;
+ }
+
+ QString argStr;
+ int argCount = args.count();
+ for (int i = 0; i < argCount; i++)
+ {
+ if (args[i].contains(' '))
+ {
+ argStr.append('"').append(args[i]).append('"');
+ }
+ else
+ {
+ argStr.append(args[i]);
+ }
+
+ if (i < argCount - 1)
+ {
+ argStr.append(" ");
+ }
+ }
+
+ if (argStr.length() >= MAX_PATH)
+ {
+ qWarning() << "Arguments string is too long!";
+ return false;
+ }
+
+ HRESULT hres;
+
+ // ...yes, you need to initialize the entire COM stack just to make a shortcut
+ hres = CoInitialize(nullptr);
+ if (FAILED(hres))
+ {
+ qWarning() << "Failed to initialize COM!";
+ return false;
+ }
+
+ WCHAR wsz[MAX_PATH];
+
+ IShellLink* psl;
+
+ // create an IShellLink instance - this stores the shortcut's attributes
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
+ if (SUCCEEDED(hres))
+ {
+ wmemset(wsz, 0, MAX_PATH);
+ target.toWCharArray(wsz);
+ psl->SetPath(wsz);
+
+ wmemset(wsz, 0, MAX_PATH);
+ argStr.toWCharArray(wsz);
+ psl->SetArguments(wsz);
+
+ wmemset(wsz, 0, MAX_PATH);
+ targetInfo.absolutePath().toWCharArray(wsz);
+ psl->SetWorkingDirectory(wsz); // "Starts in" attribute
+
+ if (!icon.isEmpty())
+ {
+ wmemset(wsz, 0, MAX_PATH);
+ icon.toWCharArray(wsz);
+ psl->SetIconLocation(wsz, 0);
+ }
+
+ // query an IPersistFile interface from our IShellLink instance
+ // this is the interface that will actually let us save the shortcut to disk!
+ IPersistFile* ppf;
+ hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
+ if (SUCCEEDED(hres))
+ {
+ wmemset(wsz, 0, MAX_PATH);
+ destination.toWCharArray(wsz);
+ hres = ppf->Save(wsz, TRUE);
+ if (FAILED(hres))
+ {
+ qWarning() << "IPresistFile->Save() failed";
+ qWarning() << "hres = " << hres;
+ }
+ ppf->Release();
+ }
+ else
+ {
+ qWarning() << "Failed to query IPersistFile interface from IShellLink instance";
+ qWarning() << "hres = " << hres;
+ }
+ psl->Release();
+ }
+ else
+ {
+ qWarning() << "Failed to create IShellLink instance";
+ qWarning() << "hres = " << hres;
+ }
+
+ // go away COM, nobody likes you
+ CoUninitialize();
+
+ return SUCCEEDED(hres);
#else
qWarning("Desktop Shortcuts not supported on your platform!");
return false;