diff options
| author | Dan Engelbrecht <[email protected]> | 2024-08-28 14:40:03 +0200 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2025-01-08 10:01:23 +0100 |
| commit | 54ffc9b9ad7d3d8d32e4de00980d66d4a31f3c09 (patch) | |
| tree | 457c7c404bdbe7486e37bd8c699ed5716c7513e0 /src/zenutil/service.cpp | |
| parent | clang format (diff) | |
| download | zen-54ffc9b9ad7d3d8d32e4de00980d66d4a31f3c09.tar.xz zen-54ffc9b9ad7d3d8d32e4de00980d66d4a31f3c09.zip | |
Add ServiceSpec struct
Diffstat (limited to 'src/zenutil/service.cpp')
| -rw-r--r-- | src/zenutil/service.cpp | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/src/zenutil/service.cpp b/src/zenutil/service.cpp index 637974c13..870a47df5 100644 --- a/src/zenutil/service.cpp +++ b/src/zenutil/service.cpp @@ -219,11 +219,7 @@ ToString(ServiceStatus Status) #if ZEN_PLATFORM_WINDOWS std::error_code -InstallService(const std::filesystem::path& ExecutablePath, - std::string_view CommandLineOptions, - std::string_view ServiceName, - std::string_view ServiceDisplayName, - std::string_view ServiceDescription) +InstallService(std::string_view ServiceName, const ServiceSpec& Spec) { // Get a handle to the SCM database. @@ -244,14 +240,14 @@ InstallService(const std::filesystem::path& ExecutablePath, Utf8ToWide(ServiceName, Name); ExtendableWideStringBuilder<128> DisplayName; - Utf8ToWide(ServiceDisplayName, DisplayName); + Utf8ToWide(Spec.DisplayName, DisplayName); ExtendableWideStringBuilder<128> Path; - Path.Append(ExecutablePath.c_str()); - if (!CommandLineOptions.empty()) + Path.Append(Spec.ExecutablePath.c_str()); + if (!Spec.CommandLineOptions.empty()) { Path.AppendAscii(" "); - Utf8ToWide(CommandLineOptions, Path); + Utf8ToWide(Spec.CommandLineOptions, Path); } SC_HANDLE schService = CreateService(schSCManager, // SCM database @@ -273,10 +269,10 @@ InstallService(const std::filesystem::path& ExecutablePath, return MakeErrorCodeFromLastError(); } - if (!ServiceDescription.empty()) + if (!Spec.Description.empty()) { ExtendableWideStringBuilder<128> DescriptionBuilder; - Utf8ToWide(ServiceDescription, DescriptionBuilder); + Utf8ToWide(Spec.Description, DescriptionBuilder); SERVICE_DESCRIPTION Description; Description.lpDescription = const_cast<wchar_t*>(DescriptionBuilder.c_str()); @@ -380,8 +376,38 @@ QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo) return MakeErrorCodeFromLastError(); } - OutInfo.ExecutablePath = std::filesystem::path(ServiceConfig->lpBinaryPathName); - OutInfo.DisplayName = WideToUtf8(ServiceConfig->lpDisplayName); + std::wstring BinaryWithArguments(ServiceConfig->lpBinaryPathName); + if (BinaryWithArguments.size()) + { + if (BinaryWithArguments[0] == '"') + { + std::wstring::size_type ExecutableEnd = BinaryWithArguments.find('"', 1); + if (ExecutableEnd == std::wstring::npos) + { + OutInfo.Spec.ExecutablePath = BinaryWithArguments; + } + else + { + OutInfo.Spec.ExecutablePath = BinaryWithArguments.substr(0, ExecutableEnd + 1); + OutInfo.Spec.CommandLineOptions = + WideToUtf8(BinaryWithArguments.substr(ExecutableEnd + 1 + BinaryWithArguments[ExecutableEnd + 1] == ' ' ? 1 : 0)); + } + } + else + { + std::wstring::size_type ExecutableEnd = BinaryWithArguments.find(' ', 1); + if (ExecutableEnd == std::wstring::npos) + { + OutInfo.Spec.ExecutablePath = BinaryWithArguments; + } + else + { + OutInfo.Spec.ExecutablePath = BinaryWithArguments.substr(0, ExecutableEnd); + OutInfo.Spec.CommandLineOptions = WideToUtf8(BinaryWithArguments.substr(ExecutableEnd + 1)); + } + } + } + OutInfo.Spec.DisplayName = WideToUtf8(ServiceConfig->lpDisplayName); SERVICE_STATUS ServiceStatus; if (!::QueryServiceStatus(schService, &ServiceStatus)) @@ -435,7 +461,7 @@ QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo) SERVICE_DESCRIPTION* Description = (SERVICE_DESCRIPTION*)Buffer.data(); if (Description->lpDescription != NULL) { - OutInfo.Description = WideToUtf8(std::wstring(Description->lpDescription)); + OutInfo.Spec.Description = WideToUtf8(std::wstring(Description->lpDescription)); } return {}; @@ -522,20 +548,16 @@ StopService(std::string_view ServiceName) } #else std::error_code -InstallService(const std::filesystem::path& ExecutablePath, - std::string_view CommandLineOptions, - std::string_view ServiceName, - std::string_view ServiceDisplayName, - std::string_view ServiceDescription) +InstallService(std::string_view ServiceName, const ServiceSpec& Spec) { - std::filesystem::path SymLink = std::filesystem::path("/usr/local/libexec") / ExecutablePath.filename(); - ZEN_INFO("Attempting synlink from {} to {}", ExecutablePath.string(), SymLink.string()); - if (symlink(ExecutablePath.c_str(), SymLink.c_str()) == -1) + std::filesystem::path SymLink = std::filesystem::path("/usr/local/libexec") / Spec.ExecutablePath.filename(); + ZEN_INFO("Attempting symlink from {} to {}", Spec.ExecutablePath.string(), SymLink.string()); + if (symlink(Spec.ExecutablePath.c_str(), SymLink.c_str()) == -1) { return MakeErrorCodeFromLastError(); } - std::string DaemonName = fmt::format("com.epicgames.unreal.{}", ServiceName); - std::string PList = BuildPlist(ExecutablePath, CommandLineOptions, DaemonName, ServiceDisplayName, ServiceDescription, true); + std::string DaemonName = fmt::format("com.epicgames.unreal.{}", ServiceName); + std::string PList = BuildPlist(Spec.ExecutablePath, Spec.CommandLineOptions, DaemonName, Spec.DisplayName, Spec.Description, true); std::filesystem::path PListPath = std::filesystem::path("/Library/LaunchDaemons") / (DaemonName + ".plist"); ZEN_INFO("Writing launchd plist to {}", PListPath.string()); zen::WriteFile(PListPath, IoBuffer(IoBuffer::Wrap, PList.data(), PList.size())); @@ -556,9 +578,9 @@ UninstallService(std::string_view ServiceName) } std::error_code -QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutStatus) +QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo) { - ZEN_UNUSED(ServiceName, OutStatus); + ZEN_UNUSED(ServiceName, OutInfo); ZEN_NOT_IMPLEMENTED("QueryInstalledService"); return {}; } |