aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/service.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-01-10 10:11:04 +0100
committerDan Engelbrecht <[email protected]>2025-01-10 10:11:04 +0100
commit9c101d0bdd3c3ada0d263dd57116931af9bcad88 (patch)
treef7bc41a96338902323d076fdb0225cac2e428ac0 /src/zenutil/service.cpp
parentget home folder (diff)
downloadzen-9c101d0bdd3c3ada0d263dd57116931af9bcad88.tar.xz
zen-9c101d0bdd3c3ada0d263dd57116931af9bcad88.zip
remove ServiceLevel
Diffstat (limited to 'src/zenutil/service.cpp')
-rw-r--r--src/zenutil/service.cpp370
1 files changed, 21 insertions, 349 deletions
diff --git a/src/zenutil/service.cpp b/src/zenutil/service.cpp
index 60db75f00..34d7c2eb6 100644
--- a/src/zenutil/service.cpp
+++ b/src/zenutil/service.cpp
@@ -16,7 +16,7 @@
# include <unistd.h>
# include <sys/stat.h>
-#include <xpc/xpc.h>
+# include <xpc/xpc.h>
#endif
namespace zen {
@@ -63,7 +63,7 @@ namespace {
return false;
}
-#endif // ZEN_PLATFORM_WINDOWS
+#endif // ZEN_PLATFORM_WINDOWS
#if ZEN_PLATFORM_MAC
std::vector<std::string_view> SplitArguments(std::string_view Arguments)
@@ -245,45 +245,6 @@ namespace {
#endif // ZEN_PLATFORM_MAC
} // namespace
-
-std::string_view
-ToString(ServiceLevel Level)
-{
- switch (Level)
- {
- case ServiceLevel::CurrentUser:
- return "Current User"sv;
- case ServiceLevel::AllUsers:
- return "All Users"sv;
- case ServiceLevel::SystemService:
- return "System Service"sv;
- default:
- ZEN_ASSERT(false);
- return ""sv;
- }
-}
-
-std::optional<ServiceLevel>
-FromString(const std::string& Level)
-{
- if (StrCaseCompare(Level.c_str(), std::string(ToString(ServiceLevel::CurrentUser)).c_str()) == 0 ||
- StrCaseCompare(Level.c_str(), "CurrentUser") == 0)
- {
- return ServiceLevel::CurrentUser;
- }
- if (StrCaseCompare(Level.c_str(), std::string(ToString(ServiceLevel::AllUsers)).c_str()) == 0 ||
- StrCaseCompare(Level.c_str(), "AllUsers") == 0)
- {
- return ServiceLevel::AllUsers;
- }
- if (StrCaseCompare(Level.c_str(), std::string(ToString(ServiceLevel::SystemService)).c_str()) == 0 ||
- StrCaseCompare(Level.c_str(), "SystemService") == 0)
- {
- return ServiceLevel::SystemService;
- }
- return {};
-}
-
std::string_view
ToString(ServiceStatus Status)
{
@@ -314,36 +275,7 @@ ToString(ServiceStatus Status)
#if ZEN_PLATFORM_WINDOWS
std::error_code
-InstallRunService(std::string_view ServiceName, const ServiceSpec& Spec)
-{
- HKEY RegKey = NULL;
- if (LSTATUS Status = RegOpenKey(Spec.ServiceLevel == ServiceLevel::AllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
- L"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
- &RegKey);
- Status == ERROR_SUCCESS)
- {
- auto _ = MakeGuard([&]() { RegCloseKey(RegKey); });
- std::wstring PathIncludingArgs = Spec.ExecutablePath.wstring();
- if (!Spec.CommandLineOptions.empty())
- {
- PathIncludingArgs += (L" " + Utf8ToWide(Spec.CommandLineOptions));
- }
- if (Status = RegSetValueEx(RegKey,
- Utf8ToWide(ServiceName).c_str(),
- 0,
- REG_SZ,
- (BYTE*)PathIncludingArgs.c_str(),
- DWORD((PathIncludingArgs.length() * 2) + 1));
- Status == ERROR_SUCCESS)
- {
- return {};
- }
- }
- return MakeErrorCodeFromLastError();
-}
-
-std::error_code
-InstallSystemService(std::string_view ServiceName, const ServiceSpec& Spec)
+InstallService(std::string_view ServiceName, const ServiceSpec& Spec)
{
// Get a handle to the SCM database.
@@ -412,40 +344,7 @@ InstallSystemService(std::string_view ServiceName, const ServiceSpec& Spec)
}
std::error_code
-InstallService(std::string_view ServiceName, const ServiceSpec& Spec)
-{
- if (Spec.ServiceLevel == ServiceLevel::SystemService)
- {
- return InstallSystemService(ServiceName, Spec);
- }
- return InstallRunService(ServiceName, Spec);
-}
-
-std::error_code
-UninstallRunService(bool AllUsers, std::string_view ServiceName)
-{
- HKEY RegKey = NULL;
- if (LSTATUS Status =
- RegOpenKey(AllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", &RegKey);
- Status == ERROR_SUCCESS)
- {
- auto _ = MakeGuard([&]() { RegCloseKey(RegKey); });
- TCHAR Value[4096];
- DWORD Type;
- DWORD Size = sizeof(Value);
- if (ERROR_SUCCESS == RegQueryValueEx(RegKey, Utf8ToWide(ServiceName).c_str(), 0, &Type, (BYTE*)Value, &Size))
- {
- if (Status = RegDeleteValue(RegKey, Utf8ToWide(ServiceName).c_str()); Status == ERROR_SUCCESS)
- {
- return std::error_code{};
- }
- }
- }
- return MakeErrorCodeFromLastError();
-}
-
-std::error_code
-UninstallSystemService(std::string_view ServiceName)
+UninstallService(std::string_view ServiceName)
{
// Get a handle to the SCM database.
SC_HANDLE schSCManager = OpenSCManager(NULL, // local computer
@@ -490,57 +389,7 @@ UninstallSystemService(std::string_view ServiceName)
}
std::error_code
-UninstallService(std::string_view ServiceName, ServiceLevel Level)
-{
- switch (Level)
- {
- case ServiceLevel::CurrentUser:
- return UninstallRunService(/*AllUsers*/ false, ServiceName);
- case ServiceLevel::AllUsers:
- return UninstallRunService(/*AllUsers*/ true, ServiceName);
- case ServiceLevel::SystemService:
- return UninstallSystemService(ServiceName);
- default:
- ZEN_ASSERT(false);
- return {};
- }
-}
-
-bool
-QueryRunServiceStatus(bool AllUsers, std::string_view ServiceName, ServiceInfo& OutInfo)
-{
- HKEY RegKey = NULL;
- if (ERROR_SUCCESS ==
- RegOpenKey(AllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", &RegKey))
- {
- auto _ = MakeGuard([&]() { RegCloseKey(RegKey); });
- TCHAR Value[4096];
- DWORD Type;
- DWORD Size = sizeof(Value);
- if (ERROR_SUCCESS == RegQueryValueEx(RegKey, Utf8ToWide(ServiceName).c_str(), 0, &Type, (BYTE*)Value, &Size))
- {
- OutInfo.Spec.ServiceLevel = AllUsers ? ServiceLevel::AllUsers : ServiceLevel::CurrentUser;
- std::wstring PathIncludingArgs(Value);
-
- (void)SplitExecutableAndArgs(PathIncludingArgs, OutInfo.Spec.ExecutablePath, OutInfo.Spec.CommandLineOptions);
-
- OutInfo.Spec.DisplayName = ServiceName;
- OutInfo.Spec.Description = "";
- OutInfo.Status = ServiceStatus::Stopped;
- ProcessHandle Process;
- std::error_code Ec = FindProcess(OutInfo.Spec.ExecutablePath, Process);
- if (!Ec)
- {
- OutInfo.Status = ServiceStatus::Running;
- }
- return true;
- }
- }
- return false;
-}
-
-std::error_code
-QuerySystemServiceStatus(std::string_view ServiceName, ServiceInfo& OutInfo)
+QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo)
{
// Get a handle to the SCM database.
SC_HANDLE schSCManager = OpenSCManager(NULL, // local computer
@@ -646,54 +495,7 @@ QuerySystemServiceStatus(std::string_view ServiceName, ServiceInfo& OutInfo)
}
std::error_code
-QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo)
-{
- if (QueryRunServiceStatus(/*AllUsers*/ false, ServiceName, OutInfo))
- {
- return {};
- }
- if (QueryRunServiceStatus(/*AllUsers*/ true, ServiceName, OutInfo))
- {
- return {};
- }
- return QuerySystemServiceStatus(ServiceName, OutInfo);
-}
-
-std::error_code
-StartRunService(bool AllUsers, std::string_view ServiceName)
-{
- HKEY RegKey = NULL;
- if (ERROR_SUCCESS ==
- RegOpenKey(AllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", &RegKey))
- {
- auto _ = MakeGuard([&]() { RegCloseKey(RegKey); });
- TCHAR Value[4096];
- DWORD Type;
- DWORD Size = sizeof(Value);
- if (ERROR_SUCCESS == RegQueryValueEx(RegKey, Utf8ToWide(ServiceName).c_str(), 0, &Type, (BYTE*)Value, &Size))
- {
- std::wstring PathIncludingArgs(Value);
-
- std::filesystem::path ExecutablePath;
- std::string CommandLineOptions;
- if (SplitExecutableAndArgs(PathIncludingArgs, ExecutablePath, CommandLineOptions))
- {
- ProcessHandle Proc;
- Proc.Initialize(CreateProc(ExecutablePath, WideToUtf8(PathIncludingArgs), {.Flags = CreateProcOptions::Flag_NoConsole}));
- if (Proc.IsValid())
- {
- return {};
- }
- MakeErrorCode(ERROR_PATH_NOT_FOUND);
- }
- MakeErrorCode(ERROR_INVALID_PARAMETER);
- }
- }
- return MakeErrorCodeFromLastError();
-}
-
-std::error_code
-StartSystemService(std::string_view ServiceName)
+StartService(std::string_view ServiceName)
{
// Get a handle to the SCM database.
SC_HANDLE schSCManager = OpenSCManager(NULL, // local computer
@@ -733,100 +535,7 @@ StartSystemService(std::string_view ServiceName)
}
std::error_code
-StartService(std::string_view ServiceName, ServiceLevel Level)
-{
- switch (Level)
- {
- case ServiceLevel::CurrentUser:
- return StartRunService(/*AllUsers*/ false, ServiceName);
- case ServiceLevel::AllUsers:
- return StartRunService(/*AllUsers*/ true, ServiceName);
- case ServiceLevel::SystemService:
- return StartSystemService(ServiceName);
- default:
- ZEN_ASSERT(false);
- return {};
- }
-}
-
-std::error_code
-SendSignalToProcess(DWORD dwProcessId, DWORD dwCtrlEvent)
-{
- std::error_code Ec = {};
- DWORD ConsoleId = GetCurrentProcessId();
- // Leave current console if it exists
- // (otherwise AttachConsole will return ERROR_ACCESS_DENIED)
- bool ConsoleDetached = FreeConsole() != FALSE;
-
- if (AttachConsole(dwProcessId) != FALSE)
- {
- // Add a fake Ctrl-C handler for avoid instant kill is this console
- // WARNING: do not revert it or current program will be also killed
- SetConsoleCtrlHandler(nullptr, true);
- if (GenerateConsoleCtrlEvent(dwCtrlEvent, 0) == FALSE)
- {
- Ec = MakeErrorCodeFromLastError();
- }
- FreeConsole();
- }
- else
- {
- Ec = MakeErrorCodeFromLastError();
- }
-
- if (ConsoleDetached)
- {
- // Create a new console if previous was deleted by OS
- if (AttachConsole(ConsoleId) == FALSE)
- {
- int errorCode = GetLastError();
- if (errorCode == 31) // 31=ERROR_GEN_FAILURE
- {
- AllocConsole();
- }
- }
- }
- return Ec;
-}
-
-std::error_code
-StopRunService(bool AllUsers, std::string_view ServiceName)
-{
- HKEY RegKey = NULL;
- if (ERROR_SUCCESS ==
- RegOpenKey(AllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", &RegKey))
- {
- auto _ = MakeGuard([&]() { RegCloseKey(RegKey); });
- TCHAR Value[4096];
- DWORD Type;
- DWORD Size = sizeof(Value);
- if (ERROR_SUCCESS == RegQueryValueEx(RegKey, Utf8ToWide(ServiceName).c_str(), 0, &Type, (BYTE*)Value, &Size))
- {
- std::wstring PathIncludingArgs(Value);
-
- std::filesystem::path ExecutablePath;
- std::string CommandLineOptions;
- if (SplitExecutableAndArgs(PathIncludingArgs, ExecutablePath, CommandLineOptions))
- {
- ProcessHandle Proc;
- std::error_code Ec = FindProcess(ExecutablePath, Proc);
- if (Ec)
- {
- return Ec;
- }
- else
- {
- return SendSignalToProcess(Proc.Pid(), CTRL_C_EVENT);
- }
- }
- return MakeErrorCode(ERROR_INVALID_PARAMETER);
- }
- }
- return MakeErrorCodeFromLastError();
-}
-
-std::error_code
-StopSystemService(std::string_view ServiceName)
+StopService(std::string_view ServiceName)
{
// Get a handle to the SCM database.
SC_HANDLE schSCManager = OpenSCManager(NULL, // local computer
@@ -865,23 +574,6 @@ StopSystemService(std::string_view ServiceName)
return {};
}
-std::error_code
-StopService(std::string_view ServiceName, ServiceLevel Level)
-{
- switch (Level)
- {
- case ServiceLevel::CurrentUser:
- return StopRunService(/*AllUsers*/ false, ServiceName);
- case ServiceLevel::AllUsers:
- return StopRunService(/*AllUsers*/ true, ServiceName);
- case ServiceLevel::SystemService:
- return StopSystemService(ServiceName);
- default:
- ZEN_ASSERT(false);
- return {};
- }
-}
-
#else
# if 0
@@ -930,22 +622,6 @@ static int CopyFile(std::filesystem::path source, std::filesystem::path dest)
}
# endif
-std::filesystem::path GetDaemonBasePath(ServiceLevel Level)
-{
- switch(Level)
- {
- case ServiceLevel::CurrentUser:
- return GetUserHomeFolder() / "Library/LaunchAgents";
- case ServiceLevel::AllUsers:
- return "/Library/LaunchAgents";
- case ServiceLevel::SystemService:
- return "/Library/LaunchDaemon";
- default:
- ZEN_ASSERT(false);
- return {};
- }
-}
-
std::error_code
InstallService(std::string_view ServiceName, const ServiceSpec& Spec)
{
@@ -956,17 +632,16 @@ InstallService(std::string_view ServiceName, const ServiceSpec& Spec)
// {
// return MakeErrorCodeFromLastError();
// }
-
+
// System: /Library/LaunchDaemons
// All users: /Library/LaunchAgents
// Current user: ~/Library/LaunchAgents
-
std::string DaemonName = fmt::format("com.epicgames.unreal.{}", ServiceName);
std::string PList =
BuildPlist(ServiceName, Spec.ExecutablePath, Spec.CommandLineOptions, DaemonName, Spec.DisplayName, Spec.Description, true);
- std::filesystem::path PListFolder = GetDaemonBasePath(Spec.ServiceLevel);
+ std::filesystem::path PListFolder = "/Library/LaunchDaemon";
std::filesystem::path PListPath = PListFolder / (DaemonName + ".plist");
ZEN_INFO("Writing launchd plist to {}", PListPath.string());
@@ -974,24 +649,21 @@ InstallService(std::string_view ServiceName, const ServiceSpec& Spec)
{
zen::WriteFile(PListPath, IoBuffer(IoBuffer::Wrap, PList.data(), PList.size()));
}
- catch(const std::system_error& Ex)
+ catch (const std::system_error& Ex)
{
return MakeErrorCode(Ex.code().value());
}
-
- if (Spec.ServiceLevel != ServiceLevel::CurrentUser) // ???? Correct?
+
+ ZEN_INFO("Changing permissions to 600 for {}", PListPath.string());
+ if (chmod(PListPath.string().c_str(), 0600) == -1)
{
- ZEN_INFO("Changing permissions to 600 for {}", PListPath.string());
- if (chmod(PListPath.string().c_str(), 0600) == -1)
- {
- return MakeErrorCodeFromLastError();
- }
+ return MakeErrorCodeFromLastError();
}
return {};
}
std::error_code
-UninstallService(std::string_view ServiceName, ServiceLevel Level)
+UninstallService(std::string_view ServiceName)
{
ZEN_UNUSED(Level);
@@ -1016,9 +688,9 @@ std::error_code
QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo)
{
ZEN_UNUSED(ServiceName, OutInfo);
-// ZEN_NOT_IMPLEMENTED("QueryInstalledService");
- //std::filesystem::path PListFolder = GetDaemonBasePath(Spec.ServiceLevel);
- //sudo launchctl list
+ // ZEN_NOT_IMPLEMENTED("QueryInstalledService");
+ // std::filesystem::path PListFolder = "/Library/LaunchDaemon";
+ // sudo launchctl list
OutInfo.Status = ServiceStatus::NotInstalled;
@@ -1026,7 +698,7 @@ QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo)
}
std::error_code
-StartService(std::string_view ServiceName, ServiceLevel Level)
+StartService(std::string_view ServiceName)
{
ZEN_UNUSED(ServiceName, Level);
ZEN_NOT_IMPLEMENTED("StartService");
@@ -1035,11 +707,11 @@ StartService(std::string_view ServiceName, ServiceLevel Level)
}
std::error_code
-StopService(std::string_view ServiceName, ServiceLevel Level)
+StopService(std::string_view ServiceName)
{
ZEN_UNUSED(ServiceName, Level);
ZEN_NOT_IMPLEMENTED("StopService");
- // sudo launchctl bootout system /Library/LaunchDaemon/com.epicgames.unreal.ZenServer.plist
+ // sudo launchctl bootout system /Library/LaunchDaemon/com.epicgames.unreal.ZenServer.plist
return {};
}