diff options
| author | Brian Munro <brian.alexander.munro@gmail.com> | 2018-03-05 11:35:58 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-03-05 11:35:58 +0200 |
| commit | c7e1d9738f06c6c6e7c9b41cdd8d35062d7c06b6 (patch) | |
| tree | c9c92380fcc82a64df8956face14e22bc3d2b4f7 /src/spawn.cpp | |
| parent | 7dfe0c9a8feae35ba7554493eea4fdb4e33a64d3 (diff) | |
| parent | a540a542a47fe75d0d0e4594158422aef4340b3a (diff) | |
Merge pull request #252 from LePresidente/new_vfs_library
Update master to latest stable code.
Diffstat (limited to 'src/spawn.cpp')
| -rw-r--r-- | src/spawn.cpp | 92 |
1 files changed, 30 insertions, 62 deletions
diff --git a/src/spawn.cpp b/src/spawn.cpp index 49e89a8b..ac8ccf30 100644 --- a/src/spawn.cpp +++ b/src/spawn.cpp @@ -22,7 +22,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "report.h"
#include "utility.h"
#include <report.h>
-#include <inject.h>
+#include <usvfs.h>
+#include <Shellapi.h>
#include <appconfig.h>
#include <windows_error.h>
@@ -39,7 +40,8 @@ using namespace MOShared; static const int BUFSIZE = 4096;
-static bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, bool suspended,
+static bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory,
+ bool suspended, bool hooked,
HANDLE stdOut, HANDLE stdErr,
HANDLE& processHandle, HANDLE& threadHandle)
{
@@ -57,7 +59,7 @@ static bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, b si.dwFlags |= STARTF_USESTDHANDLES;
}
si.cb = sizeof(si);
- int length = wcslen(binary) + wcslen(arguments) + 4;
+ size_t length = wcslen(binary) + wcslen(arguments) + 4;
wchar_t *commandLine = nullptr;
if (arguments[0] != L'\0') {
commandLine = new wchar_t[length];
@@ -87,15 +89,28 @@ static bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, b }
PROCESS_INFORMATION pi;
- BOOL success = ::CreateProcess(nullptr,
- commandLine,
- nullptr, nullptr, // no special process or thread attributes
- inheritHandles, // inherit handles if we plan to use stdout or stderr reroute
- CREATE_BREAKAWAY_FROM_JOB | (suspended ? CREATE_SUSPENDED : 0), // create suspended so I have time to inject the DLL
- nullptr, // same environment as parent
- currentDirectory, // current directory
- &si, &pi // startup and process information
- );
+ BOOL success = FALSE;
+ if (hooked) {
+ success = ::CreateProcessHooked(nullptr,
+ commandLine,
+ nullptr, nullptr, // no special process or thread attributes
+ inheritHandles, // inherit handles if we plan to use stdout or stderr reroute
+ CREATE_BREAKAWAY_FROM_JOB,
+ nullptr, // same environment as parent
+ currentDirectory, // current directory
+ &si, &pi // startup and process information
+ );
+ } else {
+ success = ::CreateProcess(nullptr,
+ commandLine,
+ nullptr, nullptr, // no special process or thread attributes
+ inheritHandles, // inherit handles if we plan to use stdout or stderr reroute
+ CREATE_BREAKAWAY_FROM_JOB,
+ nullptr, // same environment as parent
+ currentDirectory, // current directory
+ &si, &pi // startup and process information
+ );
+ }
::SetEnvironmentVariable(TEXT("PATH"), oldPath.get());
@@ -113,33 +128,18 @@ static bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, b HANDLE startBinary(const QFileInfo &binary,
const QString &arguments,
- const QString& profileName,
- int logLevel,
const QDir ¤tDirectory,
bool hooked,
HANDLE stdOut,
HANDLE stdErr)
{
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo;
-
- ::QueryInformationJobObject(nullptr, JobObjectExtendedLimitInformation, &jobInfo, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION), nullptr);
- jobInfo.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_BREAKAWAY_OK;
-
- HANDLE jobObject = ::CreateJobObject(nullptr, nullptr);
-
- if (jobObject == nullptr) {
- qWarning("failed to create job object: %lu", ::GetLastError());
- } else {
- ::SetInformationJobObject(jobObject, JobObjectExtendedLimitInformation, &jobInfo, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
- }
-
HANDLE processHandle, threadHandle;
std::wstring binaryName = ToWString(QDir::toNativeSeparators(binary.absoluteFilePath()));
std::wstring currentDirectoryName = ToWString(QDir::toNativeSeparators(currentDirectory.absolutePath()));
try {
- if (!spawn(binaryName.c_str(), ToWString(arguments).c_str(), currentDirectoryName.c_str(), true,
- stdOut, stdErr, processHandle, threadHandle)) {
+ if (!spawn(binaryName.c_str(), ToWString(arguments).c_str(), currentDirectoryName.c_str(),
+ true, hooked, stdOut, stdErr, processHandle, threadHandle)) {
reportError(QObject::tr("failed to spawn \"%1\"").arg(binary.fileName()));
return INVALID_HANDLE_VALUE;
}
@@ -168,38 +168,6 @@ HANDLE startBinary(const QFileInfo &binary, }
}
- if (hooked) {
- try {
- QFileInfo dllInfo(QApplication::applicationDirPath() + "/" + ToQString(AppConfig::hookDLLName()));
- if (!dllInfo.exists()) {
- reportError(QObject::tr("\"%1\" doesn't exist").arg(dllInfo.fileName()));
- return INVALID_HANDLE_VALUE;
- }
- injectDLL(processHandle, threadHandle,
- QDir::toNativeSeparators(dllInfo.canonicalFilePath()).toLocal8Bit().constData(),
- ToWString(profileName).c_str(), logLevel);
- } catch (const windows_error& e) {
- reportError(QObject::tr("failed to inject dll into \"%1\": %2").arg(binary.fileName()).arg(e.what()));
- ::TerminateProcess(processHandle, 1);
- return INVALID_HANDLE_VALUE;
- }
-#ifdef _DEBUG
- reportError("ready?");
-#endif // DEBUG
- }
-
- if (::AssignProcessToJobObject(jobObject, processHandle) == 0) {
- qWarning("failed to assign to job object: %lu", ::GetLastError());
- ::CloseHandle(jobObject);
- jobObject = processHandle;
- } else {
- ::CloseHandle(processHandle);
- }
-
- if (::ResumeThread(threadHandle) == (DWORD)-1) {
- reportError(QObject::tr("failed to run \"%1\"").arg(binary.fileName()));
- return INVALID_HANDLE_VALUE;
- }
::CloseHandle(threadHandle);
- return jobObject;
+ return processHandle;
}
|
