diff options
| author | Dan Engelbrecht <[email protected]> | 2025-01-10 10:11:04 +0100 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2025-01-10 10:11:04 +0100 |
| commit | 9c101d0bdd3c3ada0d263dd57116931af9bcad88 (patch) | |
| tree | f7bc41a96338902323d076fdb0225cac2e428ac0 /src/zenutil/service.cpp | |
| parent | get home folder (diff) | |
| download | zen-9c101d0bdd3c3ada0d263dd57116931af9bcad88.tar.xz zen-9c101d0bdd3c3ada0d263dd57116931af9bcad88.zip | |
remove ServiceLevel
Diffstat (limited to 'src/zenutil/service.cpp')
| -rw-r--r-- | src/zenutil/service.cpp | 370 |
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 {}; } |