From 971cecf343777894cec5144da11d16ef97d0db31 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Thu, 12 Sep 2019 01:09:40 -0400 Subject: split spawnBinaryProcess() into spawn, no changes --- src/mainwindow.cpp | 2 +- src/organizercore.cpp | 286 ++-------------------------------------------- src/spawn.cpp | 310 +++++++++++++++++++++++++++++++++++++++++++++++++- src/spawn.h | 18 +++ 4 files changed, 338 insertions(+), 278 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 054262e9..6737e330 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -6434,7 +6434,7 @@ void MainWindow::on_bossButton_clicked() return; } - HANDLE loot = startBinary(QFileInfo(qApp->applicationDirPath() + "/loot/lootcli.exe"), + HANDLE loot = spawn::startBinary(QFileInfo(qApp->applicationDirPath() + "/loot/lootcli.exe"), parameters.join(" "), qApp->applicationDirPath() + "/loot", true, diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 91e16716..9403b47d 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -135,34 +135,6 @@ static DWORD getProcessParentID(DWORD pid) return res; } -static void startSteam(QWidget *widget) -{ - QSettings steamSettings("HKEY_CURRENT_USER\\Software\\Valve\\Steam", - QSettings::NativeFormat); - QString exe = steamSettings.value("SteamExe", "").toString(); - if (!exe.isEmpty()) { - exe = QString("\"%1\"").arg(exe); - // See if username and password supplied. If so, pass them into steam. - QStringList args; - QString username; - QString password; - if (Settings::instance().steam().login(username, password)) { - args << "-login"; - args << username; - if (password != "") { - args << password; - } - } - if (!QProcess::startDetached(exe, args)) { - reportError(QObject::tr("Failed to start \"%1\"").arg(exe)); - } else { - QMessageBox::information( - widget, QObject::tr("Waiting"), - QObject::tr("Please press OK once you're logged into steam.")); - } - } -} - template QStringList toStringList(InputIterator current, InputIterator end) { @@ -173,86 +145,6 @@ QStringList toStringList(InputIterator current, InputIterator end) return result; } -bool checkService() -{ - SC_HANDLE serviceManagerHandle = NULL; - SC_HANDLE serviceHandle = NULL; - LPSERVICE_STATUS_PROCESS serviceStatus = NULL; - LPQUERY_SERVICE_CONFIG serviceConfig = NULL; - bool serviceRunning = true; - - DWORD bytesNeeded; - - try { - serviceManagerHandle = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); - if (!serviceManagerHandle) { - log::warn("failed to open service manager (query status) (error {})", GetLastError()); - throw 1; - } - - serviceHandle = OpenService(serviceManagerHandle, L"EventLog", SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); - if (!serviceHandle) { - log::warn("failed to open EventLog service (query status) (error {})", GetLastError()); - throw 2; - } - - if (QueryServiceConfig(serviceHandle, NULL, 0, &bytesNeeded) - || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { - log::warn("failed to get size of service config (error {})", GetLastError()); - throw 3; - } - - DWORD serviceConfigSize = bytesNeeded; - serviceConfig = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, serviceConfigSize); - if (!QueryServiceConfig(serviceHandle, serviceConfig, serviceConfigSize, &bytesNeeded)) { - log::warn("failed to query service config (error {})", GetLastError()); - throw 4; - } - - if (serviceConfig->dwStartType == SERVICE_DISABLED) { - log::error("Windows Event Log service is disabled!"); - serviceRunning = false; - } - - if (QueryServiceStatusEx(serviceHandle, SC_STATUS_PROCESS_INFO, NULL, 0, &bytesNeeded) - || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { - log::warn("failed to get size of service status (error {})", GetLastError()); - throw 5; - } - - DWORD serviceStatusSize = bytesNeeded; - serviceStatus = (LPSERVICE_STATUS_PROCESS)LocalAlloc(LMEM_FIXED, serviceStatusSize); - if (!QueryServiceStatusEx(serviceHandle, SC_STATUS_PROCESS_INFO, (LPBYTE)serviceStatus, serviceStatusSize, &bytesNeeded)) { - log::warn("failed to query service status (error {})", GetLastError()); - throw 6; - } - - if (serviceStatus->dwCurrentState != SERVICE_RUNNING) { - log::error("Windows Event Log service is not running"); - serviceRunning = false; - } - } - catch (int e) { - UNUSED_VAR(e); - serviceRunning = false; - } - - if (serviceStatus) { - LocalFree(serviceStatus); - } - if (serviceConfig) { - LocalFree(serviceConfig); - } - if (serviceHandle) { - CloseServiceHandle(serviceHandle); - } - if (serviceManagerHandle) { - CloseServiceHandle(serviceManagerHandle); - } - - return serviceRunning; -} - OrganizerCore::OrganizerCore(Settings &settings) : m_UserInterface(nullptr) @@ -361,67 +253,6 @@ void OrganizerCore::storeSettings() } } -bool OrganizerCore::testForSteam(bool *found, bool *access) -{ - HANDLE hProcessSnap; - HANDLE hProcess; - PROCESSENTRY32 pe32; - DWORD lastError; - - if (found == nullptr || access == nullptr) { - return false; - } - - // Take a snapshot of all processes in the system. - hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hProcessSnap == INVALID_HANDLE_VALUE) { - lastError = GetLastError(); - log::error("unable to get snapshot of processes (error {})", lastError); - return false; - } - - // Retrieve information about the first process, - // and exit if unsuccessful - pe32.dwSize = sizeof(PROCESSENTRY32); - if (!Process32First(hProcessSnap, &pe32)) { - lastError = GetLastError(); - log::error("unable to get first process (error {})", lastError); - CloseHandle(hProcessSnap); - return false; - } - - *found = false; - *access = true; - - // Now walk the snapshot of processes, and - // display information about each process in turn - do { - if ((_tcsicmp(pe32.szExeFile, L"Steam.exe") == 0) || - (_tcsicmp(pe32.szExeFile, L"SteamService.exe") == 0)) { - - *found = true; - - // Try to open the process to determine if MO has the proper access - hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, - FALSE, pe32.th32ProcessID); - if (hProcess == NULL) { - lastError = GetLastError(); - if (lastError == ERROR_ACCESS_DENIED) { - *access = false; - } - } else { - CloseHandle(hProcess); - } - break; - } - -} while(Process32Next(hProcessSnap, &pe32)); - -CloseHandle(hProcessSnap); -return true; - -} - void OrganizerCore::updateExecutablesList() { if (m_PluginContainer == nullptr) { @@ -1453,93 +1284,18 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, { prepareStart(); - if (!binary.exists()) { - reportError( - tr("Executable not found: %1").arg(qUtf8Printable(binary.absoluteFilePath()))); - return INVALID_HANDLE_VALUE; - } - - if (!steamAppID.isEmpty()) { - ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(steamAppID).c_str()); - } else { - ::SetEnvironmentVariableW(L"SteamAPPId", - ToWString(m_Settings.steam().appID()).c_str()); - } - QWidget *window = qApp->activeWindow(); if ((window != nullptr) && (!window->isVisible())) { window = nullptr; } - // This could possibly be extracted somewhere else but it's probably for when - // we have more than one provider of game registration. - if ((QFileInfo( - managedGame()->gameDirectory().absoluteFilePath("steam_api.dll")) - .exists() - || QFileInfo(managedGame()->gameDirectory().absoluteFilePath( - "steam_api64.dll")) - .exists()) - && (m_Settings.game().loadMechanismType() == LoadMechanism::LOAD_MODORGANIZER)) { - - bool steamFound = true; - bool steamAccess = true; - if (!testForSteam(&steamFound, &steamAccess)) { - log::error("unable to determine state of Steam"); - } - - if (!steamFound) { - QDialogButtonBox::StandardButton result; - result = QuestionBoxMemory::query(window, "steamQuery", binary.fileName(), - tr("Start Steam?"), - tr("Steam is required to be running already to correctly start the game. " - "Should MO try to start steam now?"), - QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel); - if (result == QDialogButtonBox::Yes) { - startSteam(window); - - // double-check that Steam is started and MO has access - steamFound = true; - steamAccess = true; - if (!testForSteam(&steamFound, &steamAccess)) { - log::error("unable to determine state of Steam"); - } else if (!steamFound) { - log::error("could not find Steam"); - } - } else if (result == QDialogButtonBox::Cancel) { - return INVALID_HANDLE_VALUE; - } - } + if (!spawn::checkBinary(binary)) { + return INVALID_HANDLE_VALUE; + } - if (!steamAccess) { - QDialogButtonBox::StandardButton result; - result = QuestionBoxMemory::query(window, "steamAdminQuery", binary.fileName(), - tr("Steam: Access Denied"), - tr("MO was denied access to the Steam process. This normally indicates that " - "Steam is being run as administrator while MO is not. This can cause issues " - "launching the game. It is recommended to not run Steam as administrator unless " - "absolutely necessary.\n\n" - "Restart MO as administrator?"), - QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel); - if (result == QDialogButtonBox::Yes) { - WCHAR cwd[MAX_PATH]; - if (!GetCurrentDirectory(MAX_PATH, cwd)) { - log::error("unable to get current directory (error {})", GetLastError()); - cwd[0] = L'\0'; - } - if (!Helper::adminLaunch( - qApp->applicationDirPath().toStdWString(), - qApp->applicationFilePath().toStdWString(), - std::wstring(cwd))) { - log::error("unable to relaunch MO as admin"); - return INVALID_HANDLE_VALUE; - } - qApp->exit(0); - return INVALID_HANDLE_VALUE; - } else if (result == QDialogButtonBox::Cancel) { - return INVALID_HANDLE_VALUE; - } - } + if (!spawn::checkSteam(window, managedGame()->gameDirectory(), binary, steamAppID, m_Settings)) { + return INVALID_HANDLE_VALUE; } while (m_DirectoryUpdate) { @@ -1566,32 +1322,12 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, return INVALID_HANDLE_VALUE; } - // Check if the Windows Event Logging service is running. For some reason, this seems to be - // critical to the successful running of usvfs. - if (!checkService()) { - if (QuestionBoxMemory::query(window, QString("eventLogService"), binary.fileName(), - tr("Windows Event Log Error"), - tr("The Windows Event Log service is disabled and/or not running. This prevents" - " USVFS from running properly. Your mods may not be working in the executable" - " that you are launching. Note that you may have to restart MO and/or your PC" - " after the service is fixed.\n\nContinue launching %1?").arg(binary.fileName()), - QDialogButtonBox::Yes | QDialogButtonBox::No) == QDialogButtonBox::No) { - return INVALID_HANDLE_VALUE; - } + if (!spawn::checkEnvironment(window, binary)) { + return INVALID_HANDLE_VALUE; } - for (auto exec : settings().executablesBlacklist().split(";")) { - if (exec.compare(binary.fileName(), Qt::CaseInsensitive) == 0) { - if (QuestionBoxMemory::query(window, QString("blacklistedExecutable"), binary.fileName(), - tr("Blacklisted Executable"), - tr("The executable you are attempted to launch is blacklisted in the virtual file" - " system. This will likely prevent the executable, and any executables that are" - " launched by this one, from seeing any mods. This could extend to INI files, save" - " games and any other virtualized files.\n\nContinue launching %1?").arg(binary.fileName()), - QDialogButtonBox::Yes | QDialogButtonBox::No) == QDialogButtonBox::No) { - return INVALID_HANDLE_VALUE; - } - } + if (!spawn::checkBlacklist(window, m_Settings, binary)) { + return INVALID_HANDLE_VALUE; } QString modsPath = settings().paths().mods(); @@ -1628,11 +1364,11 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, log::debug("Spawning proxyed process <{}>", cmdline); - return startBinary(QFileInfo(QCoreApplication::applicationFilePath()), + return spawn::startBinary(QFileInfo(QCoreApplication::applicationFilePath()), cmdline, QCoreApplication::applicationDirPath(), true); } else { log::debug("Spawning direct process <{}, {}, {}>", binPath, arguments, cwdPath); - return startBinary(binary, arguments, currentDirectory, true); + return spawn::startBinary(binary, arguments, currentDirectory, true); } } else { log::debug("start of \"{}\" canceled by plugin", binary.absoluteFilePath()); diff --git a/src/spawn.cpp b/src/spawn.cpp index 614bc92f..4376e5bf 100644 --- a/src/spawn.cpp +++ b/src/spawn.cpp @@ -24,6 +24,7 @@ along with Mod Organizer. If not, see . #include "env.h" #include "envwindows.h" #include "envsecurity.h" +#include "settings.h" #include #include #include @@ -41,6 +42,10 @@ along with Mod Organizer. If not, see . using namespace MOBase; using namespace MOShared; +namespace spawn +{ + +// details namespace { @@ -320,8 +325,6 @@ bool confirmRestartAsAdmin(const SpawnParameters& sp) return (r == QMessageBox::Yes); } -} // namespace - void startBinaryAdmin(const SpawnParameters& sp) { if (!confirmRestartAsAdmin(sp)) { @@ -344,6 +347,307 @@ void startBinaryAdmin(const SpawnParameters& sp) } } +} // namespace + + +bool checkBinary(const QFileInfo& binary) +{ + if (!binary.exists()) { + reportError( + QObject::tr("Executable not found: %1") + .arg(qUtf8Printable(binary.absoluteFilePath()))); + + return false; + } + + return true; +} + +bool testForSteam(bool *found, bool *access) +{ + HANDLE hProcessSnap; + HANDLE hProcess; + PROCESSENTRY32 pe32; + DWORD lastError; + + if (found == nullptr || access == nullptr) { + return false; + } + + // Take a snapshot of all processes in the system. + hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hProcessSnap == INVALID_HANDLE_VALUE) { + lastError = GetLastError(); + log::error("unable to get snapshot of processes (error {})", lastError); + return false; + } + + // Retrieve information about the first process, + // and exit if unsuccessful + pe32.dwSize = sizeof(PROCESSENTRY32); + if (!Process32First(hProcessSnap, &pe32)) { + lastError = GetLastError(); + log::error("unable to get first process (error {})", lastError); + CloseHandle(hProcessSnap); + return false; + } + + *found = false; + *access = true; + + // Now walk the snapshot of processes, and + // display information about each process in turn + do { + if ((_tcsicmp(pe32.szExeFile, L"Steam.exe") == 0) || + (_tcsicmp(pe32.szExeFile, L"SteamService.exe") == 0)) { + + *found = true; + + // Try to open the process to determine if MO has the proper access + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + FALSE, pe32.th32ProcessID); + if (hProcess == NULL) { + lastError = GetLastError(); + if (lastError == ERROR_ACCESS_DENIED) { + *access = false; + } + } else { + CloseHandle(hProcess); + } + break; + } + + } while(Process32Next(hProcessSnap, &pe32)); + + CloseHandle(hProcessSnap); + return true; +} + +void startSteam(QWidget *widget) +{ + QSettings steamSettings("HKEY_CURRENT_USER\\Software\\Valve\\Steam", + QSettings::NativeFormat); + QString exe = steamSettings.value("SteamExe", "").toString(); + if (!exe.isEmpty()) { + exe = QString("\"%1\"").arg(exe); + // See if username and password supplied. If so, pass them into steam. + QStringList args; + QString username; + QString password; + if (Settings::instance().steam().login(username, password)) { + args << "-login"; + args << username; + if (password != "") { + args << password; + } + } + if (!QProcess::startDetached(exe, args)) { + reportError(QObject::tr("Failed to start \"%1\"").arg(exe)); + } else { + QMessageBox::information( + widget, QObject::tr("Waiting"), + QObject::tr("Please press OK once you're logged into steam.")); + } + } +} + +bool checkSteam( + QWidget* parent, const QDir& gameDirectory, + const QFileInfo &binary, const QString &steamAppID, const Settings& settings) +{ + if (!steamAppID.isEmpty()) { + ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(steamAppID).c_str()); + } else { + ::SetEnvironmentVariableW(L"SteamAPPId", + ToWString(settings.steam().appID()).c_str()); + } + + if ((QFileInfo(gameDirectory.absoluteFilePath("steam_api.dll")).exists() || + QFileInfo(gameDirectory.absoluteFilePath("steam_api64.dll")).exists()) + && (settings.game().loadMechanismType() == LoadMechanism::LOAD_MODORGANIZER)) { + + bool steamFound = true; + bool steamAccess = true; + if (!testForSteam(&steamFound, &steamAccess)) { + log::error("unable to determine state of Steam"); + } + + if (!steamFound) { + QDialogButtonBox::StandardButton result; + result = QuestionBoxMemory::query(parent, "steamQuery", binary.fileName(), + QObject::tr("Start Steam?"), + QObject::tr("Steam is required to be running already to correctly start the game. " + "Should MO try to start steam now?"), + QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel); + if (result == QDialogButtonBox::Yes) { + startSteam(parent); + + // double-check that Steam is started and MO has access + steamFound = true; + steamAccess = true; + if (!testForSteam(&steamFound, &steamAccess)) { + log::error("unable to determine state of Steam"); + } else if (!steamFound) { + log::error("could not find Steam"); + } + + } else if (result == QDialogButtonBox::Cancel) { + return false; + } + } + + if (!steamAccess) { + QDialogButtonBox::StandardButton result; + result = QuestionBoxMemory::query(parent, "steamAdminQuery", binary.fileName(), + QObject::tr("Steam: Access Denied"), + QObject::tr("MO was denied access to the Steam process. This normally indicates that " + "Steam is being run as administrator while MO is not. This can cause issues " + "launching the game. It is recommended to not run Steam as administrator unless " + "absolutely necessary.\n\n" + "Restart MO as administrator?"), + QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel); + if (result == QDialogButtonBox::Yes) { + WCHAR cwd[MAX_PATH]; + if (!GetCurrentDirectory(MAX_PATH, cwd)) { + log::error("unable to get current directory (error {})", GetLastError()); + cwd[0] = L'\0'; + } + if (!Helper::adminLaunch( + qApp->applicationDirPath().toStdWString(), + qApp->applicationFilePath().toStdWString(), + std::wstring(cwd))) { + log::error("unable to relaunch MO as admin"); + return false; + } + qApp->exit(0); + return false; + } else if (result == QDialogButtonBox::Cancel) { + return false; + } + } + } + + return true; +} + +bool checkService() +{ + SC_HANDLE serviceManagerHandle = NULL; + SC_HANDLE serviceHandle = NULL; + LPSERVICE_STATUS_PROCESS serviceStatus = NULL; + LPQUERY_SERVICE_CONFIG serviceConfig = NULL; + bool serviceRunning = true; + + DWORD bytesNeeded; + + try { + serviceManagerHandle = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); + if (!serviceManagerHandle) { + log::warn("failed to open service manager (query status) (error {})", GetLastError()); + throw 1; + } + + serviceHandle = OpenService(serviceManagerHandle, L"EventLog", SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); + if (!serviceHandle) { + log::warn("failed to open EventLog service (query status) (error {})", GetLastError()); + throw 2; + } + + if (QueryServiceConfig(serviceHandle, NULL, 0, &bytesNeeded) + || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { + log::warn("failed to get size of service config (error {})", GetLastError()); + throw 3; + } + + DWORD serviceConfigSize = bytesNeeded; + serviceConfig = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, serviceConfigSize); + if (!QueryServiceConfig(serviceHandle, serviceConfig, serviceConfigSize, &bytesNeeded)) { + log::warn("failed to query service config (error {})", GetLastError()); + throw 4; + } + + if (serviceConfig->dwStartType == SERVICE_DISABLED) { + log::error("Windows Event Log service is disabled!"); + serviceRunning = false; + } + + if (QueryServiceStatusEx(serviceHandle, SC_STATUS_PROCESS_INFO, NULL, 0, &bytesNeeded) + || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { + log::warn("failed to get size of service status (error {})", GetLastError()); + throw 5; + } + + DWORD serviceStatusSize = bytesNeeded; + serviceStatus = (LPSERVICE_STATUS_PROCESS)LocalAlloc(LMEM_FIXED, serviceStatusSize); + if (!QueryServiceStatusEx(serviceHandle, SC_STATUS_PROCESS_INFO, (LPBYTE)serviceStatus, serviceStatusSize, &bytesNeeded)) { + log::warn("failed to query service status (error {})", GetLastError()); + throw 6; + } + + if (serviceStatus->dwCurrentState != SERVICE_RUNNING) { + log::error("Windows Event Log service is not running"); + serviceRunning = false; + } + } + catch (int) { + serviceRunning = false; + } + + if (serviceStatus) { + LocalFree(serviceStatus); + } + if (serviceConfig) { + LocalFree(serviceConfig); + } + if (serviceHandle) { + CloseServiceHandle(serviceHandle); + } + if (serviceManagerHandle) { + CloseServiceHandle(serviceManagerHandle); + } + + return serviceRunning; +} + +bool checkEnvironment(QWidget* parent, const QFileInfo& binary) +{ + // Check if the Windows Event Logging service is running. For some reason, this seems to be + // critical to the successful running of usvfs. + if (!checkService()) { + if (QuestionBoxMemory::query(parent, QString("eventLogService"), binary.fileName(), + QObject::tr("Windows Event Log Error"), + QObject::tr("The Windows Event Log service is disabled and/or not running. This prevents" + " USVFS from running properly. Your mods may not be working in the executable" + " that you are launching. Note that you may have to restart MO and/or your PC" + " after the service is fixed.\n\nContinue launching %1?").arg(binary.fileName()), + QDialogButtonBox::Yes | QDialogButtonBox::No) == QDialogButtonBox::No) { + return false; + } + } + + return true; +} + +bool checkBlacklist(QWidget* parent, const Settings& settings, const QFileInfo& binary) +{ + for (auto exec : settings.executablesBlacklist().split(";")) { + if (exec.compare(binary.fileName(), Qt::CaseInsensitive) == 0) { + if (QuestionBoxMemory::query(parent, QString("blacklistedExecutable"), binary.fileName(), + QObject::tr("Blacklisted Executable"), + QObject::tr("The executable you are attempted to launch is blacklisted in the virtual file" + " system. This will likely prevent the executable, and any executables that are" + " launched by this one, from seeing any mods. This could extend to INI files, save" + " games and any other virtualized files.\n\nContinue launching %1?").arg(binary.fileName()), + QDialogButtonBox::Yes | QDialogButtonBox::No) == QDialogButtonBox::No) { + return false; + } + } + } + + return true; +} + + HANDLE startBinary( const QFileInfo &binary, const QString &arguments, const QDir ¤tDirectory, bool hooked, HANDLE stdOut, HANDLE stdErr) @@ -382,3 +686,5 @@ HANDLE startBinary( } } } + +} // namespace \ No newline at end of file diff --git a/src/spawn.h b/src/spawn.h index 9a2dbfbd..9a5afb4a 100644 --- a/src/spawn.h +++ b/src/spawn.h @@ -26,6 +26,22 @@ along with Mod Organizer. If not, see . #include #include +class Settings; + +namespace spawn +{ + +bool checkBinary(const QFileInfo& binary); + +bool checkSteam( + QWidget* parent, const QDir& gameDirectory, + const QFileInfo &binary, const QString &steamAppID, const Settings& settings); + +bool checkEnvironment(QWidget* parent, const QFileInfo& binary); + +bool checkBlacklist( + QWidget* parent, const Settings& settings, const QFileInfo& binary); + /** * @brief spawn a binary with Mod Organizer injected * @@ -45,5 +61,7 @@ HANDLE startBinary(const QFileInfo &binary, const QString &arguments, const QDir ¤tDirectory, bool hooked, HANDLE stdOut = INVALID_HANDLE_VALUE, HANDLE stdErr = INVALID_HANDLE_VALUE); +} // namespace + #endif // SPAWN_H -- cgit v1.3.1