internal static extern bool EnumServicesStatusEx(
     SafeServiceHandle databaseHandle,
     int infolevel,
     int serviceType,
     int serviceState,
     IntPtr status,
     int size,
     out int bytesNeeded,
     out int servicesReturned,
     ref int resumeHandle,
     string?group);
Пример #2
0
        /// Disconnects this object from the service and frees any allocated resources.
        protected virtual void Dispose(bool disposing)
        {
            if (_serviceManagerHandle != null)
            {
                _serviceManagerHandle.Dispose();
                _serviceManagerHandle = null;
            }

            _statusGenerated = false;
            _type            = Interop.mincore.ServiceTypeOptions.SERVICE_TYPE_ALL;
            _disposed        = true;
        }
Пример #3
0
        /// <summary>
        /// Starts a service in the machine specified.
        /// </summary>
        public void Start(string[] args)
        {
            ArgumentNullException.ThrowIfNull(args);

            using SafeServiceHandle serviceHandle = GetServiceHandle(Interop.Advapi32.ServiceOptions.SERVICE_START);
            IntPtr[] argPtrs = new IntPtr[args.Length];
            int      i       = 0;

            try
            {
                for (i = 0; i < args.Length; i++)
                {
                    if (args[i] == null)
                    {
                        throw new ArgumentNullException($"{nameof(args)}[{i}]", SR.ArgsCantBeNull);
                    }

                    argPtrs[i] = Marshal.StringToHGlobalUni(args[i]);
                }
            }
            catch
            {
                for (int j = 0; j < i; j++)
                {
                    Marshal.FreeHGlobal(argPtrs[i]);
                }
                throw;
            }

            GCHandle argPtrsHandle = default;

            try
            {
                argPtrsHandle = GCHandle.Alloc(argPtrs, GCHandleType.Pinned);
                bool result = Interop.Advapi32.StartService(serviceHandle, args.Length, argPtrsHandle.AddrOfPinnedObject());
                if (!result)
                {
                    Exception inner = new Win32Exception();
                    throw new InvalidOperationException(SR.Format(SR.CannotStart, ServiceName, _machineName), inner);
                }
            }
            finally
            {
                for (i = 0; i < args.Length; i++)
                {
                    Marshal.FreeHGlobal(argPtrs[i]);
                }
                if (argPtrsHandle.IsAllocated)
                {
                    argPtrsHandle.Free();
                }
            }
        }
Пример #4
0
 public static extern bool ChangeServiceConfig(
     SafeServiceHandle hService,
     ServiceType dwServiceType,
     ServiceStartType dwStartType,
     ServiceErrorControl dwErrorControl,
     string lpBinaryPathName,
     string lpLoadOrderGroup,
     int lpdwTagId,
     string lpDependencies,
     string lpServiceStartName,
     string lpPassword,
     string lpDisplayName);
Пример #5
0
        /// <summary>
        /// Closes the handle to the service manager, but does not
        /// mark the class as disposed.
        /// </summary>
        /// <remarks>
        /// Violates design guidelines by not matching Dispose() -- matches .NET Framework
        /// </remarks>
        public void Close()
        {
            if (_serviceManagerHandle != null)
            {
                _serviceManagerHandle.Dispose();
                _serviceManagerHandle = null;
            }

            _statusGenerated      = false;
            _startTypeInitialized = false;
            _type = Interop.Advapi32.ServiceTypeOptions.SERVICE_TYPE_ALL;
        }
Пример #6
0
        static SecurityDescriptor GetServiceSecurityDescriptor(SafeServiceHandle handle)
        {
            int required = 0;

            byte[] sd = new byte[8192];
            if (!QueryServiceObjectSecurity(handle, SecurityInformation.AllBasic, sd, sd.Length, out required))
            {
                throw new Win32Exception();
            }

            return(new SecurityDescriptor(sd));
        }
Пример #7
0
        /// <summary>
        /// Opens a handle for the current service. The handle must be Dispose()'d.
        /// </summary>
        /// <param name="desiredAccess">Access level to pass to OpenService()</param>
        /// <returns></returns>
        private SafeServiceHandle GetServiceHandle(int desiredAccess)
        {
            GetDataBaseHandleWithConnectAccess();

            var serviceHandle = new SafeServiceHandle(Interop.Advapi32.OpenService(_serviceManagerHandle, ServiceName, desiredAccess));
            if (serviceHandle.IsInvalid)
            {
                Exception inner = new Win32Exception(Marshal.GetLastWin32Error());
                throw new InvalidOperationException(SR.Format(SR.OpenService, ServiceName, _machineName), inner);
            }

            return serviceHandle;
        }
 internal static extern bool ChangeServiceConfigW(
     /* _In_      SC_HANDLE */ [In] SafeServiceHandle hService,
     /* _In_      DWORD     */ [In] ServiceType dwServiceType,
     /* _In_      DWORD     */ [In] ServiceStartType dwStartType,
     /* _In_      DWORD     */ [In] ServiceErrorControl dwErrorControl,
     /* _In_opt_  LPCTSTR   */ [In] string lpBinaryPathName,
     /* _In_opt_  LPCTSTR   */ [In] string lpLoadOrderGroup,
     /* _Out_opt_ LPDWORD   */ [In][Out] IntPtr lpdwTagId,
     /* _In_opt_  LPCTSTR   */ [In] string lpDependencies,
     /* _In_opt_  LPCTSTR   */ [In] string lpServiceStartName,
     /* _In_opt_  LPCTSTR   */ [In] string lpPassword,
     /* _In_opt_  LPCTSTR   */ [In] string lpDisplayName
     );
Пример #9
0
        /// <summary>The SetServiceObjectSecurity function sets the security descriptor of a service object.</summary>
        /// <param name="hService">
        ///     A handle to the service. This handle is returned by the <see cref="OpenService" /> or
        ///     <see cref="CreateService(SafeServiceHandle,string,string,ACCESS_MASK,ServiceType,ServiceStartType,ServiceErrorControl,string,string,int, string,string,string)" /> function. The access required for this handle depends on the security information
        ///     specified in the <paramref name="dwSecurityInformation" /> parameter.
        /// </param>
        /// <param name="dwSecurityInformation">
        ///     Specifies the components of the security descriptor to set. This parameter can be a
        ///     combination of the following values : <see cref="SECURITY_INFORMATION.DACL_SECURITY_INFORMATION" />,
        ///     <see cref="SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION" />,
        ///     <see cref="SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION" />,
        ///     <see cref="SECURITY_INFORMATION.SACL_SECURITY_INFORMATION" />. Note that flags not handled by
        ///     SetServiceObjectSecurity will be silently ignored.
        /// </param>
        /// <param name="lpSecurityDescriptor">The new security information.</param>
        public static void SetServiceObjectSecurity(
            SafeServiceHandle hService,
            SECURITY_INFORMATION dwSecurityInformation,
            RawSecurityDescriptor lpSecurityDescriptor)
        {
            var binaryForm = new byte[lpSecurityDescriptor.BinaryLength];

            lpSecurityDescriptor.GetBinaryForm(binaryForm, 0);
            if (!SetServiceObjectSecurity(hService, dwSecurityInformation, binaryForm))
            {
                throw new Win32Exception();
            }
        }
Пример #10
0
        private void GetDataBaseHandleWithConnectAccess()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            // get a handle to SCM with connect access and store it in serviceManagerHandle field.
            if (_serviceManagerHandle == null)
            {
                _serviceManagerHandle = new SafeServiceHandle(GetDataBaseHandleWithAccess(_machineName, Interop.mincore.ServiceControllerOptions.SC_MANAGER_CONNECT));
            }
        }
Пример #11
0
        /// Disconnects this object from the service and frees any allocated resources.
        protected override void Dispose(bool disposing)
        {
            if (_serviceManagerHandle != null)
            {
                _serviceManagerHandle.Dispose();
                _serviceManagerHandle = null;
            }

            _statusGenerated      = false;
            _startTypeInitialized = false;
            _type     = Interop.Advapi32.ServiceTypeOptions.SERVICE_TYPE_ALL;
            _disposed = true;
        }
Пример #12
0
        private static SafeServiceHandle GetDataBaseHandleWithAccess(string machineName, int serviceControlManagerAccess)
        {
            var databaseHandle = new SafeServiceHandle();

            Marshal.InitHandle(databaseHandle, machineName.Equals(DefaultMachineName) || machineName.Length == 0 ?
                               Interop.Advapi32.OpenSCManager(null, null, serviceControlManagerAccess) :
                               Interop.Advapi32.OpenSCManager(machineName, null, serviceControlManagerAccess));

            if (databaseHandle.IsInvalid)
            {
                Exception inner = new Win32Exception();
                databaseHandle.Dispose();
                throw new InvalidOperationException(SR.Format(SR.OpenSC, machineName), inner);
            }

            return(databaseHandle);
        }
        /// <summary>
        /// Open an instance of the SCM.
        /// </summary>
        /// <param name="machine_name">The machine name for the SCM.</param>
        /// <param name="database_name">The database name. Specify SERVICES_ACTIVE_DATABASE or SERVICES_FAILED_DATABASE.
        /// If null then SERVICES_ACTIVE_DATABASE is used.</param>
        /// <param name="desired_access">The desired access for the SCM connection.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The SCM instance.</returns>
        public static NtResult <ServiceControlManager> Open(string machine_name, string database_name,
                                                            ServiceControlManagerAccessRights desired_access, bool throw_on_error)
        {
            if (machine_name == string.Empty)
            {
                machine_name = null;
            }
            if (database_name == string.Empty)
            {
                database_name = null;
            }
            SafeServiceHandle scm = Win32NativeMethods.OpenSCManager(machine_name, database_name, desired_access);

            if (!scm.IsInvalid)
            {
                return(new ServiceControlManager(scm, machine_name, desired_access).CreateResult());
            }
            return(Win32Utils.CreateResultFromDosError <ServiceControlManager>(throw_on_error));
        }
Пример #14
0
        private static SafeServiceHandle GetDataBaseHandleWithAccess(string machineName, int serviceControlManagerAccess)
        {
            SafeServiceHandle? databaseHandle;
            if (machineName.Equals(DefaultMachineName) || machineName.Length == 0)
            {
                databaseHandle = new SafeServiceHandle(Interop.Advapi32.OpenSCManager(null, null, serviceControlManagerAccess));
            }
            else
            {
                databaseHandle = new SafeServiceHandle(Interop.Advapi32.OpenSCManager(machineName, null, serviceControlManagerAccess));
            }

            if (databaseHandle.IsInvalid)
            {
                Exception inner = new Win32Exception(Marshal.GetLastWin32Error());
                throw new InvalidOperationException(SR.Format(SR.OpenSC, machineName), inner);
            }

            return databaseHandle;
        }
        private void DeleteService()
        {
            using (var serviceManagerHandle = new SafeServiceHandle(Interop.Advapi32.OpenSCManager(null, null, Interop.Advapi32.ServiceControllerOptions.SC_MANAGER_ALL)))
            {
                if (serviceManagerHandle.IsInvalid)
                {
                    throw new Win32Exception("Could not open SCM");
                }

                using (var serviceHandle = new SafeServiceHandle(Interop.Advapi32.OpenService(serviceManagerHandle, ServiceName, Interop.Advapi32.ServiceOptions.STANDARD_RIGHTS_DELETE)))
                {
                    if (serviceHandle.IsInvalid)
                    {
                        throw new Win32Exception($"Could not find service '{ServiceName}'");
                    }

                    if (!Interop.Advapi32.DeleteService(serviceHandle))
                    {
                        throw new Win32Exception($"Could not delete service '{ServiceName}'");
                    }
                }
            }
        }
Пример #16
0
		public SafeServiceHandle OpenService(SafeServiceHandle hSCManager, string lpServiceName, ServiceAccess dwDesiredAccess)
			=> OpenService(hSCManager, lpServiceName, dwDesiredAccess);
 public static extern bool ChangeServiceConfig2(SafeServiceHandle serviceHandle, uint infoLevel, ref SERVICE_DELAYED_AUTOSTART_INFO serviceDesc);
Пример #18
0
 public static extern bool FailureActionsOnNonCrashFailures(
     SafeServiceHandle hService,
     int dwInfoLevel,
     [MarshalAs(UnmanagedType.Struct)]
     ref SERVICE_FAILURE_ACTIONS_FLAG lpInfo);
 internal static extern unsafe bool GetServiceDisplayName(SafeServiceHandle SCMHandle, string serviceName, char *displayName, ref int displayNameLength);
Пример #20
0
 internal extern static IntPtr OpenService(SafeServiceHandle databaseHandle, string serviceName, int access);
Пример #21
0
 public static extern bool DeleteService(SafeServiceHandle serviceHandle);
Пример #22
0
        static void Main(string[] args)
        {
            bool show_help = false;

            int  pid             = Process.GetCurrentProcess().Id;
            bool show_write_only = false;
            bool print_sddl      = false;
            bool dump_triggers   = false;
            bool dump_scm        = false;
            ServiceAccessRights service_rights = 0;
            bool quiet          = false;
            bool map_to_generic = false;

            try
            {
                OptionSet opts = new OptionSet()
                {
                    { "sddl", "Print full SDDL security descriptors", v => print_sddl = v != null },
                    { "p|pid=", "Specify a PID of a process to impersonate when checking", v => pid = int.Parse(v.Trim()) },
                    { "w", "Show only write permissions granted", v => show_write_only = v != null },
                    { "k=", String.Format("Filter on a specific right [{0}]",
                                          String.Join(",", Enum.GetNames(typeof(ServiceAccessRights)))),
                      v => service_rights |= ParseRight <ServiceAccessRights>(v) },
                    { "t", "Dump trigger information for services", v => dump_triggers = v != null },
                    { "scm", "Dump SCM security information", v => dump_scm = v != null },
                    { "g", "Map access mask to generic rights.", v => map_to_generic = v != null },
                    { "q", "Don't print our errors", v => quiet = v != null },
                    { "h|help", "show this message and exit", v => show_help = v != null },
                };

                List <string> service_names = opts.Parse(args);

                if (show_help)
                {
                    ShowHelp(opts);
                }
                else
                {
                    if (service_names.Count == 0)
                    {
                        service_names.AddRange(ServiceController.GetServices().Select(s => s.ServiceName));
                    }

                    using (NtToken token = NtToken.OpenProcessToken(pid))
                    {
                        using (SafeServiceHandle scm = OpenSCManager(null, null,
                                                                     ServiceControlManagerAccessRights.Connect | ServiceControlManagerAccessRights.ReadControl))
                        {
                            if (dump_scm)
                            {
                                SecurityDescriptor sd             = GetServiceSecurityDescriptor(scm);
                                AccessMask         granted_access = GetGrantedAccess(sd, token, AccessMask.Empty,
                                                                                     GetSCMGenericMapping());

                                Console.WriteLine("SCM Granted Access: {0:X08} {1}",
                                                  granted_access, GrantedAccessToString(granted_access, true, map_to_generic));
                                if (print_sddl)
                                {
                                    Console.WriteLine("SCM SDDL: {0}", sd.ToSddl());
                                }
                            }

                            foreach (string name in service_names)
                            {
                                try
                                {
                                    DumpService(scm, name, token, service_rights,
                                                show_write_only, print_sddl, dump_triggers,
                                                map_to_generic);
                                }
                                catch (Exception ex)
                                {
                                    if (!quiet)
                                    {
                                        Console.Error.WriteLine("Error querying service: {0} - {1}", name, ex.Message);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
            }
        }
 internal static extern bool StartService(SafeServiceHandle hSCManager, int dwNumServiceArgs, string[] lpServiceArgVectors);
 internal static extern bool QueryServiceStatusEx(SafeServiceHandle hService, int InfoLevel, [Out] byte[] pBuffer, int cbBufSize, out int pcbBytesNeeded);
 internal static extern bool QueryServiceStatus(SafeServiceHandle hService, out SERVICE_STATUS_PROCESS status);
 internal static extern bool QueryServiceConfig(SafeServiceHandle hService, [Out] byte[] pServiceConfig, int cbBufSize, out int pcbBytesNeeded);
        public unsafe void Install()
        {
            string username = Username;
            string password = Password;

            if (ServiceCommandLine == null)
            {
                string processName    = Process.GetCurrentProcess().MainModule.FileName;
                string entryPointName = System.Reflection.Assembly.GetEntryAssembly().Location;
                string arguments      = ServiceName;

                // if process and entry point aren't the same then we are running hosted so pass
                // in the entrypoint as the first argument
                if (!string.Equals(processName, entryPointName, StringComparison.OrdinalIgnoreCase))
                {
                    arguments = $"\"{entryPointName}\" {arguments}";
                }

                ServiceCommandLine = $"\"{processName}\" {arguments}";
            }

            // Build servicesDependedOn string
            string servicesDependedOn = null;

            if (ServicesDependedOn.Length > 0)
            {
                StringBuilder buff = new StringBuilder();
                for (int i = 0; i < ServicesDependedOn.Length; ++i)
                {
                    //The servicesDependedOn need to be separated by a null
                    buff.Append(ServicesDependedOn[i]);
                    buff.Append('\0');
                }
                // an extra null at the end indicates end of list.
                buff.Append('\0');

                servicesDependedOn = buff.ToString();
            }

            // Open the service manager
            using (var serviceManagerHandle = new SafeServiceHandle(Interop.Advapi32.OpenSCManager(null, null, Interop.Advapi32.ServiceControllerOptions.SC_MANAGER_ALL)))
            {
                if (serviceManagerHandle.IsInvalid)
                {
                    throw new InvalidOperationException("Cannot open Service Control Manager");
                }

                // Install the service
                using (var serviceHandle = new SafeServiceHandle(Interop.Advapi32.CreateService(serviceManagerHandle, ServiceName,
                                                                                                DisplayName, Interop.Advapi32.ServiceAccessOptions.ACCESS_TYPE_ALL, Interop.Advapi32.ServiceTypeOptions.SERVICE_TYPE_WIN32_OWN_PROCESS,
                                                                                                (int)StartType, Interop.Advapi32.ServiceStartErrorModes.ERROR_CONTROL_NORMAL,
                                                                                                ServiceCommandLine, null, IntPtr.Zero, servicesDependedOn, username, password)))
                {
                    if (serviceHandle.IsInvalid)
                    {
                        throw new Win32Exception("Cannot create service");
                    }

                    // A local variable in an unsafe method is already fixed -- so we don't need a "fixed { }" blocks to protect
                    // across the p/invoke calls below.

                    if (Description.Length != 0)
                    {
                        Interop.Advapi32.SERVICE_DESCRIPTION serviceDesc = new Interop.Advapi32.SERVICE_DESCRIPTION();
                        serviceDesc.description = Marshal.StringToHGlobalUni(Description);
                        bool success = Interop.Advapi32.ChangeServiceConfig2(serviceHandle, Interop.Advapi32.ServiceConfigOptions.SERVICE_CONFIG_DESCRIPTION, ref serviceDesc);
                        Marshal.FreeHGlobal(serviceDesc.description);
                        if (!success)
                        {
                            throw new Win32Exception("Cannot set description");
                        }
                    }

                    // Start the service after creating it
                    using (ServiceController svc = new ServiceController(ServiceName))
                    {
                        if (svc.Status != ServiceControllerStatus.Running)
                        {
                            svc.Start();
                            if (!ServiceName.StartsWith("PropagateExceptionFromOnStart"))
                            {
                                svc.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(120));
                            }
                        }
                    }
                }
            }
        }
Пример #28
0
		public bool ChangeServiceConfig2(SafeServiceHandle hService, ServiceInfoLevel dwInfoLevel, IntPtr lpInfo)
			=> ChangeServiceConfig2(hService, dwInfoLevel, lpInfo);
Пример #29
0
		public bool DeleteService(SafeServiceHandle hService)
			=> DeleteService(hService);
Пример #30
0
		public bool StartService(SafeServiceHandle hService, int dwNumServiceArgs, string lpServiceArgVectors)
			=> StartService(hService, dwNumServiceArgs, lpServiceArgVectors);
Пример #31
0
        static void DumpTriggers(SafeServiceHandle service)
        {
            using (var buf = new SafeStructureInOutBuffer <SERVICE_TRIGGER_INFO>(8192, false))
            {
                int required = 0;
                if (!QueryServiceConfig2(service, SERVICE_CONFIG_TRIGGER_INFO, buf, 8192, out required))
                {
                    return;
                }

                SERVICE_TRIGGER_INFO trigger_info = buf.Result;
                if (trigger_info.cTriggers == 0)
                {
                    return;
                }

                SERVICE_TRIGGER[] trigger_arr;
                using (SafeHGlobalBuffer triggers = new SafeHGlobalBuffer(trigger_info.pTriggers, trigger_info.cTriggers * Marshal.SizeOf(typeof(SERVICE_TRIGGER)), false))
                {
                    trigger_arr = new SERVICE_TRIGGER[trigger_info.cTriggers];
                    triggers.ReadArray(0, trigger_arr, 0, trigger_arr.Length);
                }
                for (int i = 0; i < trigger_arr.Length; ++i)
                {
                    SERVICE_TRIGGER trigger = trigger_arr[i];
                    Console.WriteLine("Trigger: {0} - Type: {1} - Action: {2}", i, trigger.dwTriggerType, trigger.dwAction);
                    switch (trigger.dwTriggerType)
                    {
                    case ServiceTriggerType.Custom:
                        Console.WriteLine("Subtype: [ETW UUID] {0:B}", trigger.GetSubType());
                        break;

                    case ServiceTriggerType.DeviceInterfaceArrival:
                        Console.WriteLine("Subtype: [Interface Class GUID] {0:B}", trigger.GetSubType());
                        break;

                    case ServiceTriggerType.GroupPolicy:
                    {
                        Guid sub_type = trigger.GetSubType();
                        if (sub_type == MACHINE_POLICY_PRESENT_GUID)
                        {
                            Console.WriteLine("Subtype: [Machine Policy Present]");
                        }
                        else if (sub_type == USER_POLICY_PRESENT_GUID)
                        {
                            Console.WriteLine("Subtype: [User Policy Present]");
                        }
                        else
                        {
                            Console.WriteLine("Subtype: [Unknown Group Policy] {0:B}", sub_type);
                        }
                    }
                    break;

                    case ServiceTriggerType.NetworkEndpoint:
                    {
                        Guid sub_type = trigger.GetSubType();
                        if (sub_type == RPC_INTERFACE_EVENT_GUID)
                        {
                            Console.WriteLine("Subtype: [RPC Interface]");
                        }
                        else if (sub_type == NAMED_PIPE_EVENT_GUID)
                        {
                            Console.WriteLine("Subtype: [Named Pipe]");
                        }
                        else
                        {
                            Console.WriteLine("Subtype: [Unknown Network Endpoint] {0:B}", sub_type);
                        }
                    }
                    break;

                    case ServiceTriggerType.DomainJoin:
                    {
                        Guid sub_type = trigger.GetSubType();
                        if (sub_type == DOMAIN_JOIN_GUID)
                        {
                            Console.WriteLine("Subtype: [Domain Join]");
                        }
                        else if (sub_type == DOMAIN_LEAVE_GUID)
                        {
                            Console.WriteLine("Subtype: [Domain Leave]");
                        }
                        else
                        {
                            Console.WriteLine("Subtype: [Unknown Domain Join] {0:B}", sub_type);
                        }
                    }
                    break;

                    case ServiceTriggerType.IPAddressAvailability:
                    {
                        Guid sub_type = trigger.GetSubType();
                        if (sub_type == NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID)
                        {
                            Console.WriteLine("Subtype: [First IP Address Available]");
                        }
                        else if (sub_type == NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID)
                        {
                            Console.WriteLine("Subtype: [Last IP Address Available]");
                        }
                        else
                        {
                            Console.WriteLine("Subtype: [Unknown IP Address Availability] {0:B}", sub_type);
                        }
                    }
                    break;
                    }

                    if (trigger.pDataItems != IntPtr.Zero && trigger.cDataItems > 0)
                    {
                        DumpCustomData(trigger);
                    }
                }
            }
        }
Пример #32
0
        /// <summary>
        ///     Retrieves a copy of the security descriptor associated with a service object. You can also use the
        ///     GetNamedSecurityInfo function to retrieve a security descriptor.
        /// </summary>
        /// <param name="hService">
        ///     A handle to the service control manager or the service. Handles to the service control manager
        ///     are returned by the <see cref="OpenSCManager" /> function, and handles to a service are returned by either the
        ///     <see cref="OpenService" /> or <see cref="CreateService(SafeServiceHandle,string,string,ACCESS_MASK,ServiceType,ServiceStartType,ServiceErrorControl,string,string,int, string,string,string)" /> function. The handle must have the READ_CONTROL access
        ///     right.
        /// </param>
        /// <param name="dwSecurityInformation">
        ///     A set of bit flags that indicate the type of security information to retrieve. This
        ///     parameter can be a combination of the <see cref="SECURITY_INFORMATION" /> flags, with the exception that this
        ///     function does not support the <see cref="SECURITY_INFORMATION.LABEL_SECURITY_INFORMATION" /> value.
        /// </param>
        /// <returns>
        ///     A copy of the security descriptor of the specified service object. The calling process must have the
        ///     appropriate access to view the specified aspects of the security descriptor of the object.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="hService" /> is NULL.</exception>
        /// <exception cref="Win32Exception">If the call to the native method fails fails.</exception>
        public static RawSecurityDescriptor QueryServiceObjectSecurity(SafeServiceHandle hService, SECURITY_INFORMATION dwSecurityInformation)
        {
            if (hService == null)
            {
                throw new ArgumentNullException(nameof(hService));
            }

            var securityDescriptor = new byte[0];
            int bufSizeNeeded;
            QueryServiceObjectSecurity(hService, dwSecurityInformation, securityDescriptor, 0, out bufSizeNeeded);

            var lastError = GetLastError();
            if (lastError != Win32ErrorCode.ERROR_INSUFFICIENT_BUFFER)
            {
                throw new Win32Exception(lastError);
            }

            securityDescriptor = new byte[bufSizeNeeded];
            var success = QueryServiceObjectSecurity(hService, dwSecurityInformation, securityDescriptor, bufSizeNeeded, out bufSizeNeeded);

            if (!success)
            {
                throw new Win32Exception();
            }

            return new RawSecurityDescriptor(securityDescriptor, 0);
        }
 public static extern bool ChangeServiceConfig2(
     SafeServiceHandle hService,
     int dwInfoLevel,
     ref SERVICE_PRESHUTDOWN_INFO lpInfo);
Пример #34
0
 internal static extern bool StartService(SafeServiceHandle serviceHandle, int argNum, IntPtr argPtrs);
 public ServiceConfig(SafeServiceHandle handle) {
     _handle = handle;
 }
Пример #36
0
 public static extern bool ChangeServiceConfig2(SafeServiceHandle hService, ServiceInfoLevel dwInfoLevel, IntPtr lpInfo);
 public ServiceManager() {
     _handle = NativeMethods.OpenSCManager(null, null, NativeMethods.SCM_ACCESS.SC_MANAGER_ENUMERATE_SERVICE);
     if (_handle.IsInvalid) {
         Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
     }
 }
Пример #38
0
 public static extern bool ChangeServiceFailureActions(
     SafeServiceHandle hService,
     int dwInfoLevel,
     [MarshalAs(UnmanagedType.Struct)]
     ref SERVICE_FAILURE_ACTIONS lpInfo);
 private ServiceControlManager(SafeServiceHandle handle, string machine_name, ServiceControlManagerAccessRights granted_access)
 {
     _handle         = handle;
     _machine_name   = machine_name;
     _granted_access = granted_access;
 }
Пример #40
0
 public static extern bool SetServiceObjectSecurity(
     SafeServiceHandle hService,
     SECURITY_INFORMATION dwSecurityInformation,
     byte[] lpSecurityDescriptor);
 internal static extern SafeServiceHandle OpenService(SafeServiceHandle hSCManager, string lpServiceName, int dwDesiredAccess);
Пример #42
0
 public static unsafe extern bool ChangeServiceConfig2(SafeServiceHandle hService, ServiceInfoLevel dwInfoLevel, void* lpInfo);
 public static extern IntPtr CreateService(SafeServiceHandle databaseHandle, string serviceName, string displayName, int access, int serviceType,
                                           int startType, int errorControl, string binaryPath, string loadOrderGroup, IntPtr pTagId, string dependencies,
                                           string servicesStartName, string password);
Пример #44
0
 public static extern SafeServiceHandle CreateService(SafeServiceHandle hSCManager, string lpServiceName, string lpDisplayName, ServiceAccess dwDesiredAccess, ServiceType dwServiceType, ServiceStartType dwStartType, ServiceErrorControl dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, int lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword);
Пример #45
0
 /// <summary>The SetServiceObjectSecurity function sets the security descriptor of a service object.</summary>
 /// <param name="hService">
 ///     A handle to the service. This handle is returned by the <see cref="OpenService" /> or
 ///     <see cref="CreateService(SafeServiceHandle,string,string,ACCESS_MASK,ServiceType,ServiceStartType,ServiceErrorControl,string,string,int, string,string,string)" /> function. The access required for this handle depends on the security information
 ///     specified in the <paramref name="dwSecurityInformation" /> parameter.
 /// </param>
 /// <param name="dwSecurityInformation">
 ///     Specifies the components of the security descriptor to set. This parameter can be a
 ///     combination of the following values : <see cref="SECURITY_INFORMATION.DACL_SECURITY_INFORMATION" />,
 ///     <see cref="SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION" />,
 ///     <see cref="SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION" />,
 ///     <see cref="SECURITY_INFORMATION.SACL_SECURITY_INFORMATION" />. Note that flags not handled by
 ///     SetServiceObjectSecurity will be silently ignored.
 /// </param>
 /// <param name="lpSecurityDescriptor">The new security information.</param>
 public static void SetServiceObjectSecurity(
     SafeServiceHandle hService,
     SECURITY_INFORMATION dwSecurityInformation,
     RawSecurityDescriptor lpSecurityDescriptor)
 {
     var binaryForm = new byte[lpSecurityDescriptor.BinaryLength];
     lpSecurityDescriptor.GetBinaryForm(binaryForm, 0);
     if (!SetServiceObjectSecurity(hService, dwSecurityInformation, binaryForm))
     {
         throw new Win32Exception();
     }
 }
Пример #46
0
 public static extern SafeServiceHandle OpenService(SafeServiceHandle hSCManager, string lpServiceName, ServiceAccess dwDesiredAccess);
Пример #47
0
 public static extern bool ChangeServiceConfig(
     SafeServiceHandle hService,
     ServiceType dwServiceType,
     ServiceStartType dwStartType,
     ServiceErrorControl dwErrorControl,
     string lpBinaryPathName,
     string lpLoadOrderGroup,
     int lpdwTagId,
     string lpDependencies,
     string lpServiceStartName,
     string lpPassword,
     string lpDisplayName);
Пример #48
0
 public static extern bool QueryServiceObjectSecurity(
     SafeServiceHandle hService,
     SECURITY_INFORMATION dwSecurityInformation,
     byte[] lpSecurityDescriptor,
     int cbBufSize,
     out int pcbBytesNeeded);
Пример #49
0
 public static extern bool ControlService(SafeServiceHandle hService, ServiceControl dwControl, ref SERVICE_STATUS lpServiceStatus);
Пример #50
0
 public static extern bool EnumServicesStatus(
     SafeServiceHandle hSCManager,
     ServiceType dwServiceType,
     ServiceStateQuery dwServiceState,
     IntPtr lpServices,
     int cbBufSize,
     ref int pcbBytesNeeded,
     ref int lpServicesReturned,
     ref int lpResumeHandle);
Пример #51
0
 public static extern bool DeleteService(SafeServiceHandle hService);
Пример #52
0
 public static partial bool DeleteService(SafeServiceHandle serviceHandle);
Пример #53
0
 public static extern bool StartService(SafeServiceHandle hService, int dwNumServiceArgs, string lpServiceArgVectors);
Пример #54
0
        /// <summary>
        /// Creates a service object and adds it to service control manager database o the local computer.
        /// </summary>
        /// <param name="lpBinaryPathName">
        /// The fully qualified path to the service binary file. If the path contains a space, it must be quoted so that it is correctly interpreted.
        /// For example, "d:\\my share\\myservice.exe" should be specified as "\"d:\\my share\\myservice.exe\"".
        /// The path can also include arguments for an auto-start service.
        /// For example, "d:\\myshare\\myservice.exe arg1 arg2".
        /// These arguments are passed to the service entry point (typically the main function).
        /// </param>
        /// <param name="lpServiceName">
        /// The name of the service to install. The maximum string length is 256 characters.
        /// The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive.
        /// Forward-slash (/) and backslash (\) are not valid service name characters.
        /// </param>
        /// <param name="lpDisplayName">
        /// The display name to be used by user interface programs to identify the service.
        /// This string has a maximum length of 256 characters. The name is case-preserved in the service control manager.
        /// Display name comparisons are always case-insensitive.
        /// </param>
        /// <param name="lpDescription">
        /// The description of the service. If this member is NULL, the description remains unchanged.
        /// If this value is an empty string (""), the current description is deleted.
        /// The service description must not exceed the size of a registry value of type REG_SZ.
        /// </param>
        /// <param name="lpServiceStartName">
        /// The name of the account under which the service should run.
        /// Use an account name in the form DomainName\UserName. The service process will be logged on as this user.
        /// If the account belongs to the built-in domain, you can specify .\UserName.
        /// </param>
        /// <param name="lpPassword">
        /// The password to the account name specified by the lpServiceStartName parameter.
        /// Specify an empty string if the account has no password or if the service runs in the LocalService, NetworkService, or LocalSystem account.
        /// If the account name specified by the <paramref name="lpServiceStartName"/> parameter is the name of a managed service account or virtual account name, the lpPassword parameter must be NULL.
        /// </param>
        /// <exception cref="Win32Exception">If the method fails, returning the calling thread's last-error code value.</exception>
        /// <exception cref="ArgumentException"><paramref name="lpServiceName" /> or <paramref name="lpBinaryPathName"/> are NULL or empty string.</exception>
        public static unsafe void CreateService(string lpBinaryPathName, string lpServiceName, string lpDisplayName, string lpDescription, string lpServiceStartName, string lpPassword)
        {
            if (string.IsNullOrEmpty(lpBinaryPathName))
            {
                throw new ArgumentException("Binary path name must not be null nor empty", nameof(lpBinaryPathName));
            }

            if (string.IsNullOrEmpty(lpServiceName))
            {
                throw new ArgumentException("Service name must not be null nor empty", nameof(lpServiceName));
            }

            using (SafeServiceHandle scmHandle = OpenSCManager(null, null, ServiceManagerAccess.SC_MANAGER_CREATE_SERVICE))
            {
                if (scmHandle.IsInvalid)
                {
                    throw new Win32Exception();
                }

                SafeServiceHandle svcHandle = CreateService(
                    scmHandle,
                    lpServiceName,
                    lpDisplayName,
                    ServiceAccess.SERVICE_ALL_ACCESS,
                    ServiceType.SERVICE_WIN32_OWN_PROCESS,
                    ServiceStartType.SERVICE_DEMAND_START,
                    ServiceErrorControl.SERVICE_ERROR_NORMAL,
                    lpBinaryPathName,
                    null,
                    0,
                    null,
                    lpServiceStartName,
                    lpPassword);

                using (svcHandle)
                {
                    if (svcHandle.IsInvalid)
                    {
                        throw new Win32Exception();
                    }

                    var descriptionStruct = new ServiceDescription
                    {
                        lpDescription = lpDescription
                    };

#if NETSTANDARD1_3_ORLATER
                    fixed(void *lpInfo = new byte[Marshal.SizeOf <ServiceDescription>()])
#else
                    fixed(void *lpInfo = new byte[Marshal.SizeOf(typeof(ServiceDescription))])
#endif
                    {
                        Marshal.StructureToPtr(descriptionStruct, new IntPtr(lpInfo), false);
                        if (!ChangeServiceConfig2(svcHandle, ServiceInfoLevel.SERVICE_CONFIG_DESCRIPTION, lpInfo))
                        {
                            throw new Win32Exception();
                        }

#if NETSTANDARD1_3_ORLATER
                        Marshal.DestroyStructure <ServiceDescription>(new IntPtr(lpInfo));
#else
                        Marshal.DestroyStructure(new IntPtr(lpInfo), typeof(ServiceDescription));
#endif
                    }
                }
            }
        }
Пример #55
0
 public static extern bool QueryServiceStatus(SafeServiceHandle hService, ref SERVICE_STATUS dwServiceStatus);
Пример #56
0
 static extern SafeServiceHandle OpenService(
     SafeServiceHandle hSCManager,
     string lpServiceName,
     ServiceAccessRights dwDesiredAccess
     );
Пример #57
0
 internal static unsafe partial bool ControlService(SafeServiceHandle serviceHandle, int control, SERVICE_STATUS *pStatus);
Пример #58
0
 static extern bool QueryServiceObjectSecurity(SafeServiceHandle hService,
                                               SecurityInformation dwSecurityInformation,
                                               [Out] byte[] lpSecurityDescriptor,
                                               int cbBufSize,
                                               out int pcbBytesNeeded);