aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--launcher/CMakeLists.txt9
-rw-r--r--launcher/DesktopServices.cpp2
-rw-r--r--launcher/FileSystem.cpp140
-rw-r--r--launcher/FileSystem.h57
-rw-r--r--launcher/StringUtils.cpp15
-rw-r--r--launcher/StringUtils.h2
-rw-r--r--launcher/filelink/FileLink.cpp106
-rw-r--r--launcher/filelink/FileLink.h15
-rw-r--r--tests/FileSystem_test.cpp181
9 files changed, 437 insertions, 90 deletions
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 18d4ce0b..dd62893c 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -562,6 +562,13 @@ set(ATLAUNCHER_SOURCES
set(LINKEXE_SOURCES
filelink/FileLink.h
filelink/FileLink.cpp
+ FileSystem.h
+ FileSystem.cpp
+ Exception.h
+ StringUtils.h
+ StringUtils.cpp
+ DesktopServices.h
+ DesktopServices.cpp
)
######## Logging categories ########
@@ -1126,8 +1133,6 @@ if(WIN32)
Qt${QT_VERSION_MAJOR}::Xml
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Concurrent
- Qt${QT_VERSION_MAJOR}::Gui
- Qt${QT_VERSION_MAJOR}::Widgets
${Launcher_QT_LIBS}
)
diff --git a/launcher/DesktopServices.cpp b/launcher/DesktopServices.cpp
index 302eaf96..69770e99 100644
--- a/launcher/DesktopServices.cpp
+++ b/launcher/DesktopServices.cpp
@@ -37,7 +37,7 @@
#include <QDesktopServices>
#include <QProcess>
#include <QDebug>
-#include "Application.h"
+//#include "Application.h"
/**
* This shouldn't exist, but until QTBUG-9328 and other unreported bugs are fixed, it needs to be a thing.
diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp
index ec4af98c..9e51f932 100644
--- a/launcher/FileSystem.cpp
+++ b/launcher/FileSystem.cpp
@@ -36,6 +36,8 @@
#include "FileSystem.h"
+#include "BuildConfig.h"
+
#include <QDebug>
#include <QDir>
#include <QDirIterator>
@@ -45,6 +47,7 @@
#include <QStandardPaths>
#include <QTextStream>
#include <QUrl>
+#include <QtNetwork>
#include "DesktopServices.h"
#include "StringUtils.h"
@@ -61,6 +64,11 @@
#include <windows.h>
#include <winnls.h>
#include <string>
+//for ShellExecute
+#include <shlobj.h>
+//#include <shlwapi.h>
+#include <objbase.h>
+#include <Shellapi.h>
#else
#include <utime.h>
#endif
@@ -218,19 +226,29 @@ bool copy::operator()(const QString& offset, bool dryRun)
}
+bool create_link::operator()(const QString& offset, bool dryRun)
+{
+
+ for (auto pair : m_path_pairs) {
+ if (!make_link(pair.src, pair.dst, offset, dryRun)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
/**
* @brief links a directory and it's contents from src to dest
* @param offset subdirectory form src to link to dest
* @return if there was an error during the attempt to link
*/
-bool create_link::operator()(const QString& offset, bool dryRun)
+bool create_link::make_link(const QString& srcPath, const QString& dstPath, const QString& offset, bool dryRun)
{
m_linked = 0; // reset counter
- auto src = PathCombine(m_src.absolutePath(), offset);
- auto dst = PathCombine(m_dst.absolutePath(), offset);
-
- std::error_code err;
+ auto src = PathCombine(QDir(srcPath).absolutePath(), offset);
+ auto dst = PathCombine(QDir(dstPath).absolutePath(), offset);
// you can't hard link a directory so make sure if we deal with a directory we do so recursively
if (m_useHardLinks)
@@ -248,26 +266,25 @@ bool create_link::operator()(const QString& offset, bool dryRun)
if (m_useHardLinks) {
if (m_debug)
qDebug() << "making hard link:" << src_path << "to" << dst_path;
- fs::create_hard_link(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), err);
+ fs::create_hard_link(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), m_os_err);
} else if (fs::is_directory(StringUtils::toStdString(src_path))) {
if (m_debug)
qDebug() << "making directory_symlink:" << src_path << "to" << dst_path;
- fs::create_directory_symlink(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), err);
+ fs::create_directory_symlink(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), m_os_err);
} else {
if (m_debug)
qDebug() << "making symlink:" << src_path << "to" << dst_path;
- fs::create_symlink(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), err);
+ fs::create_symlink(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), m_os_err);
}
}
- if (err) {
- qWarning() << "Failed to link files:" << QString::fromStdString(err.message());
+ if (m_os_err) {
+ qWarning() << "Failed to link files:" << QString::fromStdString(m_os_err.message());
qDebug() << "Source file:" << src_path;
qDebug() << "Destination file:" << dst_path;
- qDebug() << "Error catagory:" << err.category().name();
- qDebug() << "Error code:" << err.value();
- m_last_os_err = err.value();
- emit linkFailed(src_path, dst_path, err);
+ qDebug() << "Error catagory:" << m_os_err.category().name();
+ qDebug() << "Error code:" << m_os_err.value();
+ emit linkFailed(src_path, dst_path, m_os_err);
} else {
m_linked++;
emit fileLinked(relative_dst_path);
@@ -290,10 +307,103 @@ bool create_link::operator()(const QString& offset, bool dryRun)
auto relative_path = src_dir.relativeFilePath(src_path);
link_file(src_path, relative_path);
+ if (m_os_err) return false;
}
}
- return err.value() == 0;
+ return m_os_err.value() == 0;
+}
+
+bool create_link::runPrivlaged(const QString& offset)
+{
+
+ QString serverName = BuildConfig.LAUNCHER_APP_BINARY_NAME + "_filelink_server" + StringUtils::getRandomAlphaNumeric(8);
+
+ connect(&m_linkServer, &QLocalServer::newConnection, this, [&](){
+
+ qDebug() << "Client connected, sending out pairs";
+ // construct block of data to send
+ QByteArray block;
+ QDataStream out(&block, QIODevice::WriteOnly);
+ out.setVersion(QDataStream::Qt_5_15); // choose correct version better?
+
+ qint32 blocksize = quint32(sizeof(quint32));
+ for (auto pair : m_path_pairs) {
+ blocksize += quint32(pair.src.size());
+ blocksize += quint32(pair.dst.size());
+ }
+ qDebug() << "About to write block of size:" << blocksize;
+ out << blocksize;
+
+ out << quint32(m_path_pairs.length());
+ for (auto pair : m_path_pairs) {
+ out << pair.src;
+ out << pair.dst;
+ }
+
+ QLocalSocket *clientConnection = m_linkServer.nextPendingConnection();
+ connect(clientConnection, &QLocalSocket::disconnected,
+ clientConnection, &QLocalSocket::deleteLater);
+
+ qint64 byteswritten = clientConnection->write(block);
+ bool bytesflushed = clientConnection->flush();
+ qDebug() << "block flushed" << byteswritten << bytesflushed;
+ //clientConnection->disconnectFromServer();
+ });
+
+ qDebug() << "Listening on pipe" << serverName;
+ if (!m_linkServer.listen(serverName)) {
+ qDebug() << "Unable to start local pipe server on" << serverName << ":" << m_linkServer.errorString();
+ return false;
+ }
+
+ ExternalLinkFileProcess *linkFileProcess = new ExternalLinkFileProcess(serverName, this);
+ connect(linkFileProcess, &ExternalLinkFileProcess::processExited, this, [&](){
+ emit finishedPrivlaged();
+ });
+ connect(linkFileProcess, &ExternalLinkFileProcess::finished, linkFileProcess, &QObject::deleteLater);
+
+ linkFileProcess->start();
+
+ // linkFileProcess->wait();
+
+ return true;
+}
+
+
+void ExternalLinkFileProcess::runLinkFile() {
+ QString fileLinkExe = PathCombine(QCoreApplication::instance()->applicationDirPath(), BuildConfig.LAUNCHER_APP_BINARY_NAME + "_filelink");
+ QString params = "-s " + m_server;
+
+#if defined Q_OS_WIN32
+ SHELLEXECUTEINFO ShExecInfo;
+ HRESULT hr;
+
+ fileLinkExe = fileLinkExe + ".exe";
+
+ qDebug() << "Running: runas" << fileLinkExe << params;
+
+ LPCWSTR programNameWin = (const wchar_t*) fileLinkExe.utf16();
+ LPCWSTR paramsWin = (const wchar_t*) params.utf16();
+
+ // https://learn.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-shellexecuteinfoa
+ ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
+ ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
+ ShExecInfo.hwnd = NULL; // Optional. A handle to the owner window, used to display and position any UI that the system might produce while executing this function.
+ ShExecInfo.lpVerb = L"runas"; // elevate to admin, show UAC
+ ShExecInfo.lpFile = programNameWin;
+ ShExecInfo.lpParameters = paramsWin;
+ ShExecInfo.lpDirectory = NULL;
+ ShExecInfo.nShow = SW_NORMAL;
+ ShExecInfo.hInstApp = NULL;
+
+ ShellExecuteEx(&ShExecInfo);
+
+ WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
+ CloseHandle(ShExecInfo.hProcess);
+#endif
+
+ qDebug() << "Process exited";
}
bool move(const QString& source, const QString& dest)
diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h
index 98f55f96..b15d1685 100644
--- a/launcher/FileSystem.h
+++ b/launcher/FileSystem.h
@@ -39,9 +39,13 @@
#include "Exception.h"
#include "pathmatcher/IPathMatcher.h"
+#include <system_error>
+
#include <QDir>
#include <QFlags>
#include <QObject>
+#include <QThread>
+#include <QLocalServer>
namespace FS {
@@ -124,16 +128,45 @@ class copy : public QObject {
int m_copied;
};
+struct LinkPair {
+ QString src;
+ QString dst;
+};
+
+class ExternalLinkFileProcess : public QThread
+{
+ Q_OBJECT
+ public:
+ ExternalLinkFileProcess(QString server, QObject* parent = nullptr) : QThread(parent), m_server(server) {}
+
+ void run() override {
+ runLinkFile();
+ emit processExited();
+ }
+
+ signals:
+ void processExited();
+
+ private:
+ void runLinkFile();
+
+ QString m_server;
+};
+
/**
- * @brief Copies a directory and it's contents from src to dest
+ * @brief links (a file / a directory and it's contents) from src to dest
*/
class create_link : public QObject {
Q_OBJECT
public:
+ create_link(const QList<LinkPair> path_pairs, QObject* parent = nullptr) : QObject(parent)
+ {
+ m_path_pairs.append(path_pairs);
+ }
create_link(const QString& src, const QString& dst, QObject* parent = nullptr) : QObject(parent)
{
- m_src.setPath(src);
- m_dst.setPath(dst);
+ LinkPair pair = {src, dst};
+ m_path_pairs.append(pair);
}
create_link& useHardLinks(const bool useHard)
{
@@ -161,31 +194,39 @@ class create_link : public QObject {
return *this;
}
- int getLastOSError() {
- return m_last_os_err;
+ std::error_code getOSError() {
+ return m_os_err;
}
bool operator()(bool dryRun = false) { return operator()(QString(), dryRun); }
+ bool runPrivlaged() { return runPrivlaged(QString()); }
+ bool runPrivlaged(const QString& offset);
+
int totalLinked() { return m_linked; }
signals:
void fileLinked(const QString& relativeName);
void linkFailed(const QString& srcName, const QString& dstName, std::error_code err);
+ void finishedPrivlaged();
private:
bool operator()(const QString& offset, bool dryRun = false);
+ bool make_link(const QString& src_path, const QString& dst_path, const QString& offset, bool dryRun);
private:
bool m_useHardLinks = false;
const IPathMatcher* m_matcher = nullptr;
bool m_whitelist = false;
bool m_recursive = true;
- QDir m_src;
- QDir m_dst;
+
+ QList<LinkPair> m_path_pairs;
+
int m_linked;
bool m_debug = false;
- int m_last_os_err = 0;
+ std::error_code m_os_err;
+
+ QLocalServer m_linkServer;
};
/**
diff --git a/launcher/StringUtils.cpp b/launcher/StringUtils.cpp
index 0f3c3669..93a44d4c 100644
--- a/launcher/StringUtils.cpp
+++ b/launcher/StringUtils.cpp
@@ -1,5 +1,7 @@
#include "StringUtils.h"
+#include <QRandomGenerator>
+
/// If you're wondering where these came from exactly, then know you're not the only one =D
/// TAKEN FROM Qt, because it doesn't expose it intelligently
@@ -74,3 +76,16 @@ int StringUtils::naturalCompare(const QString& s1, const QString& s2, Qt::CaseSe
// The two strings are the same (02 == 2) so fall back to the normal sort
return QString::compare(s1, s2, cs);
}
+
+QString StringUtils::getRandomAlphaNumeric(const int length)
+{
+ const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ QString randomString;
+ for(int i=0; i < length; ++i)
+ {
+ int index = QRandomGenerator::global()->bounded(0, possibleCharacters.length());
+ QChar nextChar = possibleCharacters.at(index);
+ randomString.append(nextChar);
+ }
+ return randomString;
+}
diff --git a/launcher/StringUtils.h b/launcher/StringUtils.h
index 1799605b..1ba19555 100644
--- a/launcher/StringUtils.h
+++ b/launcher/StringUtils.h
@@ -29,4 +29,6 @@ inline QString fromStdString(string s)
#endif
int naturalCompare(const QString& s1, const QString& s2, Qt::CaseSensitivity cs);
+
+QString getRandomAlphaNumeric(const int length);
} // namespace StringUtils
diff --git a/launcher/filelink/FileLink.cpp b/launcher/filelink/FileLink.cpp
index 9b5589ab..78486507 100644
--- a/launcher/filelink/FileLink.cpp
+++ b/launcher/filelink/FileLink.cpp
@@ -31,8 +31,6 @@
#include <QDebug>
-
-#include <FileSystem.h>
#include <DesktopServices.h>
#include <sys.h>
@@ -48,7 +46,7 @@
-FileLinkApp::FileLinkApp(int &argc, char **argv) : QCoreApplication(argc, argv)
+FileLinkApp::FileLinkApp(int &argc, char **argv) : QCoreApplication(argc, argv), socket(new QLocalSocket(this))
{
#if defined Q_OS_WIN32
// attach the parent console
@@ -81,18 +79,116 @@ FileLinkApp::FileLinkApp(int &argc, char **argv) : QCoreApplication(argc, argv)
// Commandline parsing
QCommandLineParser parser;
- parser.setApplicationDescription(QObject::tr("a batch MKLINK program for windows to be useed with prismlauncher"));
+ parser.setApplicationDescription(QObject::tr("a batch MKLINK program for windows to be used with prismlauncher"));
parser.addOptions({
-
+ {{"s", "server"}, "Join the specified server on launch", "pipe name"}
});
parser.addHelpOption();
parser.addVersionOption();
parser.process(arguments());
+ QString serverToJoin = parser.value("server");
+
qDebug() << "link program launched";
+ if (!serverToJoin.isEmpty()) {
+ qDebug() << "joining server" << serverToJoin;
+ joinServer(serverToJoin);
+ } else {
+ qDebug() << "no server to join";
+ exit();
+ }
+
+}
+
+void FileLinkApp::joinServer(QString server)
+{
+
+ blockSize = 0;
+
+ in.setDevice(&socket);
+ in.setVersion(QDataStream::Qt_5_15);
+
+ connect(&socket, &QLocalSocket::connected, this, [&](){
+ qDebug() << "connected to server";
+ });
+
+ connect(&socket, &QLocalSocket::readyRead, this, &FileLinkApp::readPathPairs);
+
+ connect(&socket, &QLocalSocket::errorOccurred, this, [&](QLocalSocket::LocalSocketError socketError){
+ switch (socketError) {
+ case QLocalSocket::ServerNotFoundError:
+ qDebug() << tr("The host was not found. Please make sure "
+ "that the server is running and that the "
+ "server name is correct.");
+ break;
+ case QLocalSocket::ConnectionRefusedError:
+ qDebug() << tr("The connection was refused by the peer. "
+ "Make sure the server is running, "
+ "and check that the server name "
+ "is correct.");
+ break;
+ case QLocalSocket::PeerClosedError:
+ break;
+ default:
+ qDebug() << tr("The following error occurred: %1.").arg(socket.errorString());
+ }
+ });
+
+ connect(&socket, &QLocalSocket::disconnected, this, [&](){
+ qDebug() << "dissconnected from server";
+ });
+
+ socket.connectToServer(server);
+
+
+}
+
+void FileLinkApp::runLink()
+{
+ qDebug() << "creating link";
+ FS::create_link lnk(m_path_pairs);
+ lnk.debug(true);
+ if (!lnk()) {
+ qDebug() << "Link Failed!" << lnk.getOSError().value() << lnk.getOSError().message().c_str();
+ }
+ //exit();
+ qDebug() << "done, should exit";
+}
+
+void FileLinkApp::readPathPairs()
+{
+ m_path_pairs.clear();
+ qDebug() << "Reading path pairs from server";
+ qDebug() << "bytes avalible" << socket.bytesAvailable();
+ if (blockSize == 0) {
+ // Relies on the fact that QDataStream serializes a quint32 into
+ // sizeof(quint32) bytes
+ if (socket.bytesAvailable() < (int)sizeof(quint32))
+ return;
+ qDebug() << "reading block size";
+ in >> blockSize;
+ }
+ qDebug() << "blocksize is" << blockSize;
+ qDebug() << "bytes avalible" << socket.bytesAvailable();
+ if (socket.bytesAvailable() < blockSize || in.atEnd())
+ return;
+
+ quint32 numPairs;
+ in >> numPairs;
+ qDebug() << "numPairs" << numPairs;
+
+ for(int i = 0; i < numPairs; i++) {
+ FS::LinkPair pair;
+ in >> pair.src;
+ in >> pair.dst;
+ qDebug() << "link" << pair.src << "to" << pair.dst;
+ m_path_pairs.append(pair);
+ }
+
+ runLink();
}
diff --git a/launcher/filelink/FileLink.h b/launcher/filelink/FileLink.h
index 253d1394..5d0ba123 100644
--- a/launcher/filelink/FileLink.h
+++ b/launcher/filelink/FileLink.h
@@ -32,6 +32,11 @@
#include <QDateTime>
#include <QUrl>
#include <QDateTime>
+#include <QDataStream>
+#include <QLocalSocket>
+
+#define PRISM_EXTERNAL_EXE
+#include "FileSystem.h"
class FileLinkApp : public QCoreApplication
{
@@ -43,7 +48,17 @@ public:
virtual ~FileLinkApp();
private:
+
+ void joinServer(QString server);
+ void readPathPairs();
+ void runLink();
+
QDateTime m_startTime;
+ QLocalSocket socket;
+ QDataStream in;
+ quint32 blockSize;
+
+ QList<FS::LinkPair> m_path_pairs;
#if defined Q_OS_WIN32
// used on Windows to attach the standard IO streams
diff --git a/tests/FileSystem_test.cpp b/tests/FileSystem_test.cpp
index 395ca5c0..be0a4be0 100644
--- a/tests/FileSystem_test.cpp
+++ b/tests/FileSystem_test.cpp
@@ -2,6 +2,8 @@
#include <QTemporaryDir>
#include <QStandardPaths>
+#include <tasks/Task.h>
+
#include <FileSystem.h>
#include <StringUtils.h>
@@ -26,6 +28,66 @@ namespace fs = ghc::filesystem;
#include <pathmatcher/RegexpMatcher.h>
+
+
+class LinkTask : public Task {
+ Q_OBJECT
+
+ friend class FileSystemTest;
+
+ LinkTask(QString src, QString dst)
+ {
+ m_lnk = new FS::create_link(src, dst, this);
+ m_lnk->debug(true);
+ }
+
+ void matcher(const IPathMatcher *filter)
+ {
+ m_lnk->matcher(filter);
+ }
+
+ void linkRecursively(bool recursive)
+ {
+ m_lnk->linkRecursively(recursive);
+ m_linkRecursive = recursive;
+ }
+
+ void whitelist(bool b)
+ {
+ m_lnk->whitelist(b);
+ }
+
+ private:
+ void executeTask() override
+ {
+ if(!(*m_lnk)()){
+#if defined Q_OS_WIN32
+ if (!m_useHard) {
+ qDebug() << "EXPECTED: Link failure, Windows requires permissions for symlinks";
+
+ qDebug() << "atempting to run with privelage";
+ connect(m_lnk, &FS::create_link::finishedPrivlaged, this, [&](){
+ emitSucceeded();
+ });
+ m_lnk->runPrivlaged();
+ } else {
+ qDebug() << "Link Failed!" << m_lnk->getOSError().value() << m_lnk->getOSError().message().c_str();
+ }
+#else
+ qDebug() << "Link Failed!" << m_lnk->getOSError().value() << m_lnk->getOSError().message().c_str();
+#endif
+ } else {
+ emitSucceeded();
+ }
+
+ };
+
+ FS::create_link *m_lnk;
+ bool m_useHard = false;
+ bool m_linkRecursive = true;
+};
+
+
class FileSystemTest : public QObject
{
Q_OBJECT
@@ -273,7 +335,7 @@ slots:
void test_link()
{
QString folder = QFINDTESTDATA("testdata/FileSystem/test_folder");
- auto f = [&folder]()
+ auto f = [&folder, this]()
{
QTemporaryDir tempDir;
tempDir.setAutoRemove(true);
@@ -282,17 +344,17 @@ slots:
QDir target_dir(FS::PathCombine(tempDir.path(), "test_folder"));
qDebug() << tempDir.path();
qDebug() << target_dir.path();
- FS::create_link lnk(folder, target_dir.path());
- lnk.linkRecursively(false);
- lnk.debug(true);
- if(!lnk()){
-#if defined Q_OS_WIN32
- qDebug() << "EXPECTED: Link failure, Windows requires permissions for symlinks";
- QVERIFY(lnk.getLastOSError() == 1314);
- return;
-#endif
- qDebug() << "Link Failed!" << lnk.getLastOSError();
- }
+
+ LinkTask lnk_tsk(folder, target_dir.path());
+ lnk_tsk.linkRecursively(false);
+ QObject::connect(&lnk_tsk, &Task::finished, [&]{
+ QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been.");
+ });
+ lnk_tsk.start();
+
+ QVERIFY2(QTest::qWaitFor([&]() {
+ return lnk_tsk.isFinished();
+ }, 100000), "Task didn't finish as it should.");
for(auto entry: target_dir.entryList())
{
@@ -337,7 +399,7 @@ slots:
lnk.useHardLinks(true);
lnk.debug(true);
if(!lnk()){
- qDebug() << "Link Failed!" << lnk.getLastOSError();
+ qDebug() << "Link Failed!" << lnk.getOSError().value() << lnk.getOSError().message().c_str();
}
for(auto entry: target_dir.entryList())
@@ -385,18 +447,19 @@ slots:
QDir target_dir(FS::PathCombine(tempDir.path(), "test_folder"));
qDebug() << tempDir.path();
qDebug() << target_dir.path();
- FS::create_link lnk(folder, target_dir.path());
- lnk.matcher(new RegexpMatcher("[.]?mcmeta"));
- lnk.linkRecursively(true);
- lnk.debug(true);
- if(!lnk()){
-#if defined Q_OS_WIN32
- qDebug() << "EXPECTED: Link failure, Windows requires permissions for symlinks";
- QVERIFY(lnk.getLastOSError() == 1314);
- return;
-#endif
- qDebug() << "Link Failed!" << lnk.getLastOSError();
- }
+
+ LinkTask lnk_tsk(folder, target_dir.path());
+ lnk_tsk.matcher(new RegexpMatcher("[.]?mcmeta"));
+ lnk_tsk.linkRecursively(true);
+ QObject::connect(&lnk_tsk, &Task::finished, [&]{
+ QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been.");
+ });
+ lnk_tsk.start();
+
+ QVERIFY2(QTest::qWaitFor([&]() {
+ return lnk_tsk.isFinished();
+ }, 100000), "Task didn't finish as it should.");
+
for(auto entry: target_dir.entryList())
{
@@ -435,19 +498,19 @@ slots:
QDir target_dir(FS::PathCombine(tempDir.path(), "test_folder"));
qDebug() << tempDir.path();
qDebug() << target_dir.path();
- FS::create_link lnk(folder, target_dir.path());
- lnk.matcher(new RegexpMatcher("[.]?mcmeta"));
- lnk.whitelist(true);
- lnk.linkRecursively(true);
- lnk.debug(true);
- if(!lnk()){
-#if defined Q_OS_WIN32
- qDebug() << "EXPECTED: Link failure, Windows requires permissions for symlinks";
- QVERIFY(lnk.getLastOSError() == 1314);
- return;
-#endif
- qDebug() << "Link Failed!" << lnk.getLastOSError();
- }
+
+ LinkTask lnk_tsk(folder, target_dir.path());
+ lnk_tsk.matcher(new RegexpMatcher("[.]?mcmeta"));
+ lnk_tsk.linkRecursively(true);
+ lnk_tsk.whitelist(true);
+ QObject::connect(&lnk_tsk, &Task::finished, [&]{
+ QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been.");
+ });
+ lnk_tsk.start();
+
+ QVERIFY2(QTest::qWaitFor([&]() {
+ return lnk_tsk.isFinished();
+ }, 100000), "Task didn't finish as it should.");
for(auto entry: target_dir.entryList())
{
@@ -486,17 +549,17 @@ slots:
QDir target_dir(FS::PathCombine(tempDir.path(), "test_folder"));
qDebug() << tempDir.path();
qDebug() << target_dir.path();
- FS::create_link lnk(folder, target_dir.path());
- lnk.linkRecursively(true);
- lnk.debug(true);
- if(!lnk()){
-#if defined Q_OS_WIN32
- qDebug() << "EXPECTED: Link failure, Windows requires permissions for symlinks";
- QVERIFY(lnk.getLastOSError() == 1314);
- return;
-#endif
- qDebug() << "Link Failed!" << lnk.getLastOSError();
- }
+
+ LinkTask lnk_tsk(folder, target_dir.path());
+ lnk_tsk.linkRecursively(true);
+ QObject::connect(&lnk_tsk, &Task::finished, [&]{
+ QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been.");
+ });
+ lnk_tsk.start();
+
+ QVERIFY2(QTest::qWaitFor([&]() {
+ return lnk_tsk.isFinished();
+ }, 100000), "Task didn't finish as it should.");
auto filter = QDir::Filter::Files | QDir::Filter::Dirs | QDir::Filter::Hidden;
@@ -538,16 +601,16 @@ slots:
QDir target_dir(FS::PathCombine(tempDir.path(), "pack.mcmeta"));
qDebug() << tempDir.path();
qDebug() << target_dir.path();
- FS::create_link lnk(file, target_dir.filePath("pack.mcmeta"));
- lnk.debug(true);
- if(!lnk()){
-#if defined Q_OS_WIN32
- qDebug() << "EXPECTED: Link failure, Windows requires permissions for symlinks";
- QVERIFY(lnk.getLastOSError() == 1314);
- return;
-#endif
- qDebug() << "Link Failed!" << lnk.getLastOSError();
- }
+
+ LinkTask lnk_tsk(file, target_dir.filePath("pack.mcmeta"));
+ QObject::connect(&lnk_tsk, &Task::finished, [&]{
+ QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been.");
+ });
+ lnk_tsk.start();
+
+ QVERIFY2(QTest::qWaitFor([&]() {
+ return lnk_tsk.isFinished();
+ }, 100000), "Task didn't finish as it should.");
auto filter = QDir::Filter::Files;