/// <summary> /// Get the security descriptor of the SCM. /// </summary> /// <returns></returns> public static SecurityDescriptor GetScmSecurityDescriptor() { using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect | ServiceControlManagerAccessRights.ReadControl)) { return(GetServiceSecurityDescriptor(scm, "scm")); } }
/// <summary> /// Create a new service. /// </summary> /// <param name="name">The name of the service.</param> /// <param name="display_name">The display name for the service.</param> /// <param name="service_type">The service type.</param> /// <param name="start_type">The service start type.</param> /// <param name="error_control">Error control.</param> /// <param name="binary_path_name">Path to the service executable.</param> /// <param name="load_order_group">Load group order.</param> /// <param name="dependencies">List of service dependencies.</param> /// <param name="service_start_name">The username for the service.</param> /// <param name="password">Password for the username if needed.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The registered service information.</returns> public static NtResult <RunningService> CreateService( string name, string display_name, ServiceType service_type, ServiceStartType start_type, ServiceErrorControl error_control, string binary_path_name, string load_order_group, IEnumerable <string> dependencies, string service_start_name, SecureString password, bool throw_on_error) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException($"'{nameof(name)}' cannot be null or empty", nameof(name)); } if (string.IsNullOrEmpty(binary_path_name)) { throw new ArgumentException($"'{nameof(binary_path_name)}' cannot be null or empty", nameof(binary_path_name)); } using (var scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect | ServiceControlManagerAccessRights.CreateService)) { if (scm.IsInvalid) { return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <RunningService>(throw_on_error)); } IntPtr pwd = password != null?Marshal.SecureStringToBSTR(password) : IntPtr.Zero; try { using (var service = Win32NativeMethods.CreateService(scm, name, display_name, ServiceAccessRights.MaximumAllowed, service_type, start_type, error_control, binary_path_name, load_order_group, null, dependencies.ToMultiString(), string.IsNullOrEmpty(service_start_name) ? null : service_start_name, pwd)) { if (service.IsInvalid) { return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <RunningService>(throw_on_error)); } return(new RunningService(name, display_name ?? string.Empty, QueryStatus(service)).CreateResult()); } } finally { if (pwd != IntPtr.Zero) { Marshal.FreeBSTR(pwd); } } } }
/// <summary> /// Get the PID of a running service. /// </summary> /// <param name="name">The name of the service.</param> /// <returns>Returns the PID of the running service, or 0 if not running.</returns> /// <exception cref="SafeWin32Exception">Thrown on error.</exception> public static int GetServiceProcessId(string name) { using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect)) { if (scm.IsInvalid) { throw new SafeWin32Exception(); } return(GetServiceProcessId(scm, name)); } }
/// <summary> /// Get the information about a service. /// </summary> /// <param name="name">The name of the service.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The service information.</returns> public static NtResult <ServiceInformation> GetServiceInformation(string name, bool throw_on_error) { using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect)) { if (scm.IsInvalid) { return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <ServiceInformation>(throw_on_error)); } return(GetServiceSecurityInformation(scm, name, DEFAULT_SECURITY_INFORMATION, throw_on_error)); } }
/// <summary> /// Get the information about a service. /// </summary> /// <param name="name">The name of the service.</param> /// <returns>The servicec information.</returns> public static ServiceInformation GetServiceInformation(string name) { using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect | ServiceControlManagerAccessRights.ReadControl)) { if (scm.IsInvalid) { throw new SafeWin32Exception(); } return(GetServiceSecurityInformation(scm, name)); } }
/// <summary> /// Get the security descriptor of the SCM. /// </summary> /// <param name="security_information">Parts of the security descriptor to return.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The SCM security descriptor.</returns> public static NtResult <SecurityDescriptor> GetScmSecurityDescriptor(SecurityInformation security_information, bool throw_on_error) { var desired_access = NtSecurity.QuerySecurityAccessMask(security_information).ToSpecificAccess <ServiceControlManagerAccessRights>(); using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect | desired_access)) { if (scm.IsInvalid) { return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <SecurityDescriptor>(throw_on_error)); } return(GetServiceSecurityDescriptor(scm, "scm", security_information, throw_on_error)); } }
/// <summary> /// Set the SCM security descriptor. /// </summary> /// <param name="security_descriptor">The security descriptor to set.</param> /// <param name="security_information">The parts of the security descriptor to set.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The NT status code.</returns> public static NtStatus SetScmSecurityDescriptor(SecurityDescriptor security_descriptor, SecurityInformation security_information, bool throw_on_error) { var desired_access = NtSecurity.SetSecurityAccessMask(security_information).ToSpecificAccess <ServiceControlManagerAccessRights>(); using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect | desired_access)) { if (scm.IsInvalid) { return(Win32Utils.GetLastWin32Error().ToNtException(throw_on_error)); } return(SetServiceSecurityDescriptor(scm, security_information, security_descriptor, throw_on_error)); } }
/// <summary> /// Get a list of registered services. /// </summary> /// <returns>A list of running services with process IDs.</returns> private static IEnumerable <RunningService> GetServices(SERVICE_STATE service_state) { using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect | ServiceControlManagerAccessRights.EnumerateService)) { if (scm.IsInvalid) { throw new SafeWin32Exception(); } ServiceType service_types = ServiceType.Win32OwnProcess | ServiceType.Win32ShareProcess; if (!NtObjectUtils.IsWindows81OrLess) { service_types |= ServiceType.UserService; } const int Length = 32 * 1024; using (var buffer = new SafeHGlobalBuffer(Length)) { int resume_handle = 0; while (true) { bool ret = Win32NativeMethods.EnumServicesStatusEx(scm, SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, service_types, service_state, buffer, buffer.Length, out int bytes_needed, out int services_returned, ref resume_handle, null); Win32Error error = Win32Utils.GetLastWin32Error(); if (!ret && error != Win32Error.ERROR_MORE_DATA) { throw new SafeWin32Exception(error); } ENUM_SERVICE_STATUS_PROCESS[] services = new ENUM_SERVICE_STATUS_PROCESS[services_returned]; buffer.ReadArray(0, services, 0, services_returned); foreach (var service in services) { yield return(new RunningService(service)); } if (ret) { break; } } } } }
private static NtResult <SafeServiceHandle> OpenService(string name, ServiceAccessRights desired_access, bool throw_on_error) { using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect)) { if (scm.IsInvalid) { return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <SafeServiceHandle>(throw_on_error)); } using (var service = Win32NativeMethods.OpenService(scm, name, desired_access)) { if (service.IsInvalid) { return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <SafeServiceHandle>(throw_on_error)); } return(service.Detach().CreateResult()); } } }
/// <summary> /// Get a running service by name. /// </summary> /// <param name="name">The name of the service.</param> /// <returns>The running service.</returns> /// <remarks>This will return active and non-active services as well as drivers.</remarks> public static RunningService GetService(string name) { using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect)) { if (scm.IsInvalid) { throw new SafeWin32Exception(); } using (var service = Win32NativeMethods.OpenService(scm, name, ServiceAccessRights.QueryConfig | ServiceAccessRights.QueryStatus)) { if (service.IsInvalid) { throw new SafeWin32Exception(); } return(new RunningService(name, GetServiceDisplayName(service), QueryStatus(service))); } } }
/// <summary> /// Get the PIDs of a list of running service. /// </summary> /// <param name="names">The names of the services.</param> /// <returns>Returns the PID of the running service, or 0 if not running.</returns> /// <exception cref="SafeWin32Exception">Thrown on error.</exception> public static IDictionary <string, int> GetServiceProcessIds(IEnumerable <string> names) { Dictionary <string, int> result = new Dictionary <string, int>(StringComparer.OrdinalIgnoreCase); using (SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect)) { if (scm.IsInvalid) { throw new SafeWin32Exception(); } foreach (var name in names) { if (!result.ContainsKey(name)) { result[name] = GetServiceProcessId(scm, name); } } } return(result); }