diff options
| author | Martin Ridgers <[email protected]> | 2021-11-16 14:37:00 +0100 |
|---|---|---|
| committer | Martin Ridgers <[email protected]> | 2021-11-16 14:39:21 +0100 |
| commit | 1d3944bd37603b94c809bf32761721b85d342e51 (patch) | |
| tree | e57c9039ad2877ca70d6ca014d9f2935db99e499 /zenutil/zenserverprocess.cpp | |
| parent | zen::CreateProc() variant that can launch processes unelevated (diff) | |
| download | zen-1d3944bd37603b94c809bf32761721b85d342e51.tar.xz zen-1d3944bd37603b94c809bf32761721b85d342e51.zip | |
Changed SpawnServer() over to use zen::CreateProc()
Diffstat (limited to 'zenutil/zenserverprocess.cpp')
| -rw-r--r-- | zenutil/zenserverprocess.cpp | 105 |
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 |