Ejemplo n.º 1
0
        /// <summary>
        /// Allows you to change the service config
        /// </summary>
        /// <param name="serviceDefinition">Service definition instance with all paramaters</param>
        public void ChangeConfig(IWin32ServiceDefinition serviceDefinition)
        {
            //Change the config
            ChangeConfig
            (
                serviceDefinition.DisplayName,
                serviceDefinition.StartType,
                serviceDefinition.CanInteractWithDesktop,
                serviceDefinition.LoadOrderGroup,
                serviceDefinition.ErrorControl,
                serviceDefinition.Credentials,
                serviceDefinition.DependOnService,
                serviceDefinition.DependOnGroup
            );

            //Set the description
            ChangeDescription(serviceDefinition.Description);

            //Set delayed start
            ChangeDelayedStart(serviceDefinition.DelayedStart);

            //Change failure actions
            ChangeFailureActions(serviceDefinition.FailureActions);

            //Set the failure actions on non crash failures
            ChangeFailureActionsOnNonCrashFailures(serviceDefinition.FailureActionsOnNonCrashFailures);
        }
        /// <summary>
        /// Creates a new service and return his handle
        /// </summary>
        /// <param name="serviceDefinition">The services definitions</param>
        /// <returns>A ServiceHandle instance</returns>
        public ServiceHandle CreateService(IWin32ServiceDefinition serviceDefinition)
        {
            IntPtr passwordHandle = IntPtr.Zero;

            if (!ValidServiceName(serviceDefinition.ServiceName))
            {
                throw new ArgumentException("The given service name is not a valid name.");
            }

            //Create the service type
            var serviceType = Advapi32.ServiceType.Win32OwnProcess; //DM only supports Win32OwnProcess

            if (Equals(serviceDefinition.Credentials, ServiceCredentials.LocalSystem) && serviceDefinition.CanInteractWithDesktop)
            {
                serviceType |= Advapi32.ServiceType.InteractivProcess;
            }

            //The credentials can't be null
            if (serviceDefinition.Credentials == null)
            {
                throw new ArgumentNullException(nameof(serviceDefinition.Credentials));
            }


            ServiceHandle serviceHandle;

            try
            {
                //Only call marshal if a password is set (SecureString != null), otherwise leave IntPtr.Zero
                if (serviceDefinition.Credentials.Password != null)
                {
                    passwordHandle = Marshal.SecureStringToGlobalAllocUnicode(serviceDefinition.Credentials.Password);
                }

                serviceHandle = Advapi32.CreateService
                                (
                    this,
                    serviceDefinition.ServiceName,
                    serviceDefinition.DisplayName,
                    Advapi32.ServiceAccessRights.AllAccess,
                    serviceType,
                    serviceDefinition.StartType,
                    serviceDefinition.ErrorControl,
                    DmServiceExe,
                    serviceDefinition.LoadOrderGroup,
                    tagId: 0, //Tags are only evaluated for driver services that have SERVICE_BOOT_START or SERVICE_SYSTEM_START start types.
                    Advapi32.ConvertDependenciesArraysToWin32String(serviceDefinition.DependOnService, serviceDefinition.DependOnGroup),
                    serviceDefinition.Credentials.Username,
                    passwordHandle
                                );

                if (serviceHandle.IsInvalid)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                if (passwordHandle != IntPtr.Zero)
                {
                    Marshal.ZeroFreeGlobalAllocUnicode(passwordHandle);
                }
            }


            //Set the description
            if (!string.IsNullOrWhiteSpace(serviceDefinition.Description))
            {
                serviceHandle.ChangeDescription(serviceDefinition.Description);
            }

            //Set delayed start
            if (serviceDefinition.DelayedStart)
            {
                serviceHandle.ChangeDelayedStart(serviceDefinition.DelayedStart);
            }

            //Change failure actions
            if (!serviceDefinition.FailureActions.Equals(Advapi32.ServiceFailureActions.Default))
            {
                serviceHandle.ChangeFailureActions(serviceDefinition.FailureActions);
            }

            //Set the failure actions on non crash failures
            if (serviceDefinition.FailureActionsOnNonCrashFailures)
            {
                serviceHandle.ChangeFailureActionsOnNonCrashFailures(serviceDefinition.FailureActionsOnNonCrashFailures);
            }

            return(serviceHandle);
        }