aboutsummaryrefslogtreecommitdiff
path: root/zenutil/zenserverprocess.cpp
diff options
context:
space:
mode:
authorMartin Ridgers <[email protected]>2021-11-16 14:37:00 +0100
committerMartin Ridgers <[email protected]>2021-11-16 14:39:21 +0100
commit1d3944bd37603b94c809bf32761721b85d342e51 (patch)
treee57c9039ad2877ca70d6ca014d9f2935db99e499 /zenutil/zenserverprocess.cpp
parentzen::CreateProc() variant that can launch processes unelevated (diff)
downloadzen-1d3944bd37603b94c809bf32761721b85d342e51.tar.xz
zen-1d3944bd37603b94c809bf32761721b85d342e51.zip
Changed SpawnServer() over to use zen::CreateProc()
Diffstat (limited to 'zenutil/zenserverprocess.cpp')
-rw-r--r--zenutil/zenserverprocess.cpp105
1 files changed, 23 insertions, 82 deletions
diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp
index 8dd93b32e..43e266b50 100644
--- a/zenutil/zenserverprocess.cpp
+++ b/zenutil/zenserverprocess.cpp
@@ -15,7 +15,6 @@
#if ZEN_PLATFORM_WINDOWS
# include <atlbase.h>
-# include <shellapi.h>
# include <zencore/windows.h>
#else
# include <sys/mman.h>
@@ -453,12 +452,8 @@ ZenServerInstance::Shutdown()
void
ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerArgs)
{
-#if ZEN_PLATFORM_WINDOWS
ZEN_ASSERT(!m_Process.IsValid()); // Only spawn once
- const std::filesystem::path BaseDir = m_Env.ProgramBaseDir();
- const std::filesystem::path Executable = BaseDir / "zenserver.exe";
-
const int MyPid = zen::GetCurrentProcessId();
const int ChildId = ++ChildIdCounter;
@@ -471,10 +466,8 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr
ExtendableStringBuilder<32> LogId;
LogId << "Zen" << ChildId;
- ExtendableWideStringBuilder<512> CommandLine;
- CommandLine << "\"";
- CommandLine.Append(Executable.c_str());
- CommandLine << "\"";
+ ExtendableStringBuilder<512> CommandLine;
+ CommandLine << "zenserver" ZEN_EXE_SUFFIX_LITERAL; // see CreateProc() call for actual binary path
const bool IsTest = m_Env.IsTestEnvironment();
@@ -504,7 +497,7 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr
if (!m_TestDir.empty())
{
CommandLine << " --data-dir ";
- CommandLine << m_TestDir.c_str();
+ PathToUtf8(m_TestDir.c_str(), CommandLine);
}
if (m_MeshEnabled)
@@ -521,93 +514,41 @@ ZenServerInstance::SpawnServer(int BasePort, std::string_view AdditionalServerAr
ZEN_DEBUG("Spawning server '{}'", LogId);
- PROCESS_INFORMATION ProcessInfo{};
- STARTUPINFO StartupInfo{.cb = sizeof(STARTUPINFO)};
-
- DWORD CreationFlags = 0;
-
+ uint32_t CreationFlags = 0;
if (!IsTest)
{
- CreationFlags |= CREATE_NEW_CONSOLE;
+ CreationFlags |= CreateProcOptions::Flag_NewConsole;
}
- HANDLE hProcess = NULL;
-
+ const std::filesystem::path BaseDir = m_Env.ProgramBaseDir();
+ const std::filesystem::path Executable = BaseDir / "zenserver" ZEN_EXE_SUFFIX_LITERAL;
+ CreateProcOptions CreateOptions = {
+ .WorkingDirectory = &CurrentDirectory,
+ .Flags = CreationFlags,
+ };
+ CreateProcResult ChildPid = CreateProc(Executable, CommandLine.ToView(), CreateOptions);
+#if ZEN_PLATFORM_WINDOWS
+ if (!ChildPid && ::GetLastError() == ERROR_ELEVATION_REQUIRED)
{
- const bool InheritHandles = false;
- void* Environment = nullptr;
- LPSECURITY_ATTRIBUTES ProcessAttributes = nullptr;
- LPSECURITY_ATTRIBUTES ThreadAttributes = nullptr;
-
- BOOL Success = CreateProcessW(Executable.c_str(),
- (LPWSTR)CommandLine.c_str(),
- ProcessAttributes,
- ThreadAttributes,
- InheritHandles,
- CreationFlags,
- Environment,
- CurrentDirectory.c_str(),
- &StartupInfo,
- &ProcessInfo);
-
- if (Success)
- {
- hProcess = ProcessInfo.hProcess;
- CloseHandle(ProcessInfo.hThread);
- }
- else
- {
- DWORD WinError = ::GetLastError();
-
- if (WinError == ERROR_ELEVATION_REQUIRED)
- {
- // Try launching elevated process
-
- ZEN_DEBUG("Regular spawn failed - spawning elevated server");
-
- SHELLEXECUTEINFO ShellExecuteInfo;
- ZeroMemory(&ShellExecuteInfo, sizeof(ShellExecuteInfo));
- ShellExecuteInfo.cbSize = sizeof(ShellExecuteInfo);
- ShellExecuteInfo.fMask = SEE_MASK_UNICODE | SEE_MASK_NOCLOSEPROCESS;
- ShellExecuteInfo.lpFile = Executable.c_str();
- ShellExecuteInfo.lpVerb = TEXT("runas");
- ShellExecuteInfo.nShow = SW_SHOW;
- ShellExecuteInfo.lpParameters = CommandLine.c_str();
-
- if (::ShellExecuteEx(&ShellExecuteInfo))
- {
- WinError = NO_ERROR;
-
- hProcess = ShellExecuteInfo.hProcess;
- }
- }
-
- if (WinError != NO_ERROR)
- {
- std::error_code err(WinError, std::system_category());
-
- ZEN_ERROR("Server spawn failed: {}", err.message());
+ ZEN_DEBUG("Regular spawn failed - spawning elevated server");
+ CreateOptions.Flags |= CreateProcOptions::Flag_Elevated;
+ ChildPid = CreateProc(Executable, CommandLine.ToView(), CreateOptions);
+ }
+#endif
- throw std::system_error(err, "failed to create server process");
- }
- }
+ if (!ChildPid)
+ {
+ ThrowLastError("Server spawn failed");
}
ZEN_DEBUG("Server '{}' spawned OK", LogId);
if (IsTest)
{
- m_Process.Initialize(hProcess);
- }
- else
- {
- CloseHandle(hProcess);
+ m_Process.Initialize(ChildPid);
}
m_ReadyEvent = std::move(ChildEvent);
-#else
- ZEN_UNUSED(BasePort, AdditionalServerArgs);
-#endif // ZEN_PLATFORM_WINDOWS
}
void