示例#1
0
        /// <summary>
        /// Attempts to stop a service
        /// Waits for timeout period for the service to stop
        /// Logs result and returns.
        /// </summary>
        /// <param name="serviceName"></param>
        private static void StopService(string serviceName)
        {
            AppAssert.Assert(null != serviceName, "Null service name passed!");

            SetupLogger.LogInfo("ServiceConfigurationHandler.StopService: Stop the service {0}", serviceName);

            try
            {
                //InspectHelper.StopService(serviceName);
                using (ServiceController serviceController = new ServiceController(serviceName))
                {
                    // Check if the service is stopped or paused
                    if (serviceController.Status == ServiceControllerStatus.Stopped)
                    {
                        // Service is stopped, log and return
                        return;
                    }
                    serviceController.Stop();
                    serviceController.WaitForStatus(ServiceControllerStatus.Stopped, ServiceStopTimeout);
                }
            }
            catch (Exception e)
            {
                SetupLogger.LogException(e);
                throw new Exception(String.Format("Cannot stop the {0} service", serviceName));
            }
        }
示例#2
0
        /// <summary>
        /// Sets the failure actions for the specified service
        /// </summary>
        /// <param name="serviceName"></param>
        /// <param name="sfa"></param>
        internal static void SetFailureActions(string serviceName, ref NativeMethods.SERVICE_FAILURE_ACTIONS sfa)
        {
            AppAssert.Assert(null != serviceName, "Null service name passed!");

            IntPtr lockHandle = NativeMethods.NullIntPtr;
            IntPtr scmHandle  = NativeMethods.NullIntPtr;
            IntPtr svcHandle  = NativeMethods.NullIntPtr;

            try
            {
                scmHandle = ServiceConfigurationHandler.GetSCMHandle();

                //lock the database
                lockHandle = RepeatLockServiceDatabase(scmHandle);
                if (NativeMethods.NullIntPtr.Equals(lockHandle))
                {
                    SetupLogger.LogError("BackEnd.Configure: Got back NULL service handle!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Setup was unable to configure service {0}", serviceName));
                }

                svcHandle = NativeMethods.OpenService(
                    scmHandle,
                    serviceName,
                    NativeMethods.SERVICE_CHANGE_CONFIG | NativeMethods.SERVICE_START);//since we set restart as a failure option, the handle should have SERVICE_START rights
                if (NativeMethods.NullIntPtr.Equals(svcHandle))
                {
                    //throw exception here
                    SetupLogger.LogInfo("BackEnd.Configure: Got back NULL service handle!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Setup was unable to configure service {0}", serviceName));
                }

                SetupLogger.LogInfo("BackEnd.Configure: Successfully opened {0} service", serviceName);

                bool success = NativeMethods.ChangeServiceConfig2(svcHandle, NativeMethods.SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa);
                if (!success)
                {
                    SetupLogger.LogInfo("BackEnd.Configure: Couldn't modify service description!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Setup was unable to configure service {0}", serviceName));
                }
            }
            finally
            {
                if (!NativeMethods.NullIntPtr.Equals(lockHandle))
                {
                    NativeMethods.UnlockServiceDatabase(lockHandle);
                }
                if (!NativeMethods.NullIntPtr.Equals(svcHandle))
                {
                    NativeMethods.CloseServiceHandle(svcHandle);
                }
                if (!NativeMethods.NullIntPtr.Equals(scmHandle))
                {
                    NativeMethods.CloseServiceHandle(scmHandle);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Check installed products with Upgrade code
        /// </summary>
        /// <param name="upgradeCode"></param>
        /// <param name="foundAtleastOneVersion"></param>
        /// <param name="maxInstalledVersion"></param>
        /// <returns></returns>
        public static List <string> CheckProductByUpgradeCode(String upgradeCode, ref Version maxInstalledVersion)
        {
            //initializations
            List <string> result       = new List <string>();
            string        productCode  = String.Empty;
            UInt32        error        = 0;//for holding return values from native APIs
            StringBuilder queryVersion = new StringBuilder(SetupConstants.MaximumVersionStringLength);
            UInt32        bufferLength = (UInt32)queryVersion.Capacity;

            int           index = 0;
            UInt32        enumRelatedProdResult = 0;
            StringBuilder productCodeBuffer     = new StringBuilder(SetupConstants.MaximumUpgradeCodeLength);

            enumRelatedProdResult = CMP.Setup.Helpers.NativeMethods.MsiEnumRelatedProducts(upgradeCode, 0, index, productCodeBuffer);

            while (CMP.Setup.Helpers.NativeMethods.ERROR_SUCCESS == enumRelatedProdResult)
            {
                bufferLength = SetupConstants.MaximumVersionStringLength;
                error        = CMP.Setup.Helpers.NativeMethods.MsiGetProductInfo(productCodeBuffer.ToString(),
                                                                                 CMP.Setup.Helpers.NativeMethods.INSTALLPROPERTY_VERSIONSTRING,
                                                                                 queryVersion,
                                                                                 ref bufferLength);
                if (0 == error)
                {
                    // success
                    SetupLogger.LogInfo("CheckProductByUpgradeCode : found product with upgrade code {0} with version {1}", upgradeCode, queryVersion.ToString());
                    Version obtainedVersion = new Version(queryVersion.ToString());
                    SetupLogger.LogInfo("CheckProductByUpgradeCode: Installed Version {0}", queryVersion.ToString());
                    int res = obtainedVersion.CompareTo(maxInstalledVersion);
                    AppAssert.Assert(res != 0, "Cannot get two related products with same version! Something must be bad with your code");
                    if (res > 0)
                    {
                        maxInstalledVersion = obtainedVersion;
                    }

                    productCode = productCodeBuffer.ToString();
                    if (!result.Contains(productCode))
                    {
                        result.Add(productCode);
                    }
                }
                else
                {
                    //failed
                    SetupLogger.LogError("CheckProductByUpgradeCode : MsiGetProductInfo failed. Msi Error is {0}", error);
                }
                index++;
                enumRelatedProdResult = CMP.Setup.Helpers.NativeMethods.MsiEnumRelatedProducts(upgradeCode, 0, index, productCodeBuffer);
            }//end of while

            return(result);
        }
示例#4
0
        /// <summary>
        /// Restarts a particular service
        /// The method times out if service does not reach "Running" status within the timeout period.
        /// </summary>
        /// <param name="serviceName">name of service to start</param>
        /// <exception cref="ServiceConfigurationException">when  service could not be started</exception>
        public void RestartService(String serviceName)
        {
            AppAssert.Assert(null != serviceName, "Null service name passed!");

            SetupLogger.LogInfo("ServiceConfigurationHandler.RestartService: Start the service {0}", serviceName);

            try
            {
                this.StartService(serviceName);
            }
            catch (Exception serviceNotFoundException)
            {
                SetupLogger.LogInfo("ServiceConfigurationHandler.StartService: Start the service, exception {0}", serviceNotFoundException);
                throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
            }
        }
示例#5
0
        /// <summary>
        /// Check to see whether the domain account and its password are valid
        /// </summary>
        private static bool CheckDomainAccountValid()
        {
            string       domainName = SetupInputs.Instance.FindItem(SetupInputTags.CmpServiceDomainTag);
            string       userName   = SetupInputs.Instance.FindItem(SetupInputTags.CmpServiceUserNameTag);
            SecureString password   = SetupInputs.Instance.FindItem(SetupInputTags.CmpServiceUserPasswordTag);

            if (UserAccountHelper.ValidateCredentials(userName, domainName, password))
            {
                return(true);
            }
            else
            {
                //throw SetupExceptionFactory.NewBackEndErrorException(ErrorCode.InvalidDomainAccount);
                SetupLogger.LogError("CheckDomainAccountValid(): Invalid domain account");
                return(false);
            }
        }
示例#6
0
        /// <summary>
        /// Attempts to delete the service
        /// Does nothing if the service doesn't exist
        /// Throws exception only if the delete actually failed
        /// </summary>
        /// <param name="hSCManager"></param>
        /// <param name="svcName"></param>
        private static void DeleteService(IntPtr hSCManager, string svcName)
        {
            AppAssert.Assert(NativeMethods.NullIntPtr != hSCManager, "Invalid SC Manager handle!");
            AppAssert.Assert(null != svcName, "Null service name passed!");

            IntPtr hSvc = NativeMethods.NullIntPtr;

            try
            {
                hSvc = NativeMethods.OpenService(hSCManager, svcName, NativeMethods.DELETE);
                if (NativeMethods.NullIntPtr.Equals(hSvc))
                {
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    if (
                        ((NativeMethods.ERROR_SERVICE_DOES_NOT_EXIST != lastWin32Error) &&
                         (NativeMethods.ERROR_SERVICE_MARKED_FOR_DELETE != lastWin32Error))
                        )
                    {
                        throw new Exception(String.Format("Cannot connect to the service.\nService name: {0}", svcName));
                    }
                    else
                    {
                        //no exception if the service doesn't exist.
                        return;
                    }
                }

                //got a handle to the service... let's try to delete it.
                bool deleteSvcReturn = NativeMethods.DeleteService(hSvc);
                if (!deleteSvcReturn)
                {
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    SetupLogger.LogInfo("Couldn't delete service: Doing get last error: {0}.", lastWin32Error);
                    throw new Exception(String.Format("Setup could not delete service {0}", svcName));
                }
            }
            finally
            {
                if (!NativeMethods.NullIntPtr.Equals(hSvc))
                {
                    NativeMethods.CloseServiceHandle(hSvc);
                }
                SetupLogger.LogInfo("ServiceConfigurationHandler.DeleteService: Doing get last error after closing service handle: {0}", Marshal.GetLastWin32Error());
            }
        }
示例#7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="upgradeCode"></param>
        /// <param name="recordVMMDifferentVersionInstalled">If it is true, record that a different version of vNext feature is installed if there is one.</param>
        /// <returns></returns>
        public static bool CheckProductByUpgradeCode(String upgradeCode, bool recordVMMDifferentVersionInstalled)
        {
            bool    foundAtleastOne = false;                   //flag to check if a valid version is found
            Version maxInstalled    = new Version(0, 0, 0, 0); //set to VERSION_MIN initially

            List <string> productCodes = SystemStateDetection.CheckProductByUpgradeCode(upgradeCode, ref maxInstalled);

            foundAtleastOne = productCodes != null && productCodes.Count > 0;
            if (recordVMMDifferentVersionInstalled &&
                foundAtleastOne &&
                maxInstalled.CompareTo(System.Reflection.Assembly.GetEntryAssembly().GetName().Version) < 0) // only deal with upgrade with version before current verion; In Update Rollup, this version has to set to RTM version if SetupVM.exe is to be patched.
            {
                // Upgrade not supported
                SetupLogger.LogInfo("Incompatible version of VMM has been detected.");
                PropertyBagDictionary.Instance.SafeAdd(PropertyBagConstants.VMMUnsupportedVersionInstalled, "1");
            }

            return(foundAtleastOne);
        }
示例#8
0
        private static string CreateNativeStringArray(string[] strArray)
        {
            char nullChar = (char)0;//Unicode NULL character. 16 bit zero

            if (null == strArray)
            {
                return(null);
            }
            System.Text.StringBuilder retString = new System.Text.StringBuilder();
            foreach (string str in strArray)
            {
                retString.Append(str);
                retString.Append(nullChar);
            }
            retString.Append(nullChar);

            SetupLogger.LogInfo("ServiceConfigurationHandler.CreateNativeStringArray: String created is {0}", retString.ToString());
            return(retString.ToString());
        }
示例#9
0
        /// <summary>
        /// This method opens the Service control manager handle with rights to create service and the standard rights.
        /// </summary>
        /// <returns>Handle to SCM</returns>
        public static IntPtr GetSCMHandle()
        {
            IntPtr hSCMgr = NativeMethods.OpenSCManager
                                (null,
                                null,
                                NativeMethods.SC_MANAGER_LOCK |
                                NativeMethods.SC_MANAGER_CREATE_SERVICE |
                                NativeMethods.STANDARD_RIGHTS_REQUIRED
                                );

            if (NativeMethods.NullIntPtr.Equals(hSCMgr))
            {
                int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                throw new Exception("Cannot connect to the Service Control Manager (SCM).");
            }

            SetupLogger.LogInfo("BackEnd.Configure: Doing get last error after obtaining SCM handle: {0}", System.Runtime.InteropServices.Marshal.GetLastWin32Error());
            return(hSCMgr);
        }
示例#10
0
 public void Dispose()
 {
     if (this.windowsImpersonationContext != null)
     {
         // Revert the user context to the windows user represented by this object
         this.windowsImpersonationContext.Undo();
     }
     if (!CMP.Setup.Helpers.NativeMethods.NullIntPtr.Equals(this.tokenHandle))
     {
         CMP.Setup.Helpers.UnsafeNativeMethods.CloseHandle(this.tokenHandle);
     }
     if (!CMP.Setup.Helpers.NativeMethods.NullIntPtr.Equals(this.processHandle))
     {
         CMP.Setup.Helpers.UnsafeNativeMethods.CloseHandle(this.processHandle);
         if (!RevertToSelf())
         {
             int winError = Marshal.GetLastWin32Error();
             throw new Exception("The remote SQL Server administrator credentials provided are not valid");
         }
     }
     SetupLogger.LogInfo("Out of Impersonation");
 }
示例#11
0
        public static IntPtr RepeatLockServiceDatabase(IntPtr scmHandle)
        {
            const int NumOfTries = 10;
            const int SleepTimeInMilliSeconds = 2000;
            IntPtr    lockHandle = NativeMethods.NullIntPtr;

            for (int num = 0; num < NumOfTries; num++)
            {
                lockHandle = NativeMethods.LockServiceDatabase(scmHandle);

                if (!NativeMethods.NullIntPtr.Equals(lockHandle))
                {
                    return(lockHandle);
                }

                SetupLogger.LogInfo(
                    "RepeatLockServiceDatabase: sleep {0} seconds before trying to lock again...",
                    SleepTimeInMilliSeconds / 1000);

                System.Threading.Thread.Sleep(SleepTimeInMilliSeconds);
            }

            return(NativeMethods.NullIntPtr);
        }
示例#12
0
        public static void CheckInstalledComponents()
        {
            // Check if CMP Service is installed
            if (CheckProductByUpgradeCode(SetupConstants.GetUpgradeCode(SetupFeatures.Server), true))
            {
                SetupLogger.LogInfo("CheckInstalledComponents: CMP server found");
                PropertyBagDictionary.Instance.SafeAdd(PropertyBagConstants.ServerVersion, "1");
                SetupInputs.Instance.EditItem(SetupInputTags.BinaryInstallLocationTag, SetupConstants.GetServerInstallPath());
            }

            // Check if Tenant Extension is installed
            if (CheckProductByUpgradeCode(SetupConstants.GetUpgradeCode(SetupFeatures.TenantExtension), true))
            {
                SetupLogger.LogInfo("CheckInstalledComponents: Tenant extension found");
                PropertyBagDictionary.Instance.SafeAdd(PropertyBagConstants.TenantExtensionVersion, "1");
                SetupInputs.Instance.EditItem(SetupInputTags.BinaryInstallLocationTag, SetupConstants.GetTenantExtensionInstallPath());
            }

            // Check if Extension Common Components are installed
            if (CheckProductByUpgradeCode(SetupConstants.GetUpgradeCode(SetupFeatures.ExtensionCommon), true))
            {
                SetupLogger.LogInfo("CheckInstalledComponents: Extension common components found");
                PropertyBagDictionary.Instance.SafeAdd(PropertyBagConstants.ExtensionCommonVersion, "1");
                SetupInputs.Instance.EditItem(SetupInputTags.BinaryInstallLocationTag, SetupConstants.GetExtensionCommonInstallPath());
            }

            // Determine if the VMM WebPortal msi is already installed.
            if (CheckProductByUpgradeCode(SetupConstants.GetUpgradeCode(SetupFeatures.AdminExtension), true))
            {
                SetupLogger.LogInfo("CheckInstalledComponents: Admin extension found");
                PropertyBagDictionary.Instance.SafeAdd(PropertyBagConstants.AdminExtensionVersion, "1");
                SetupInputs.Instance.EditItem(SetupInputTags.BinaryInstallLocationTag, SetupConstants.GetAdminExtensionInstallPath());
            }

            return;
        }
示例#13
0
        /// <summary>
        /// Create the engine service and start it
        /// </summary>
        public static void ConfigureCMPWorkerService(ServiceConfigurationHandler serviceConfigurationHandler)
        {
            AppAssert.AssertNotNull(serviceConfigurationHandler, "serviceConfigurationHandler");

            string installPath = SetupConstants.GetServerInstallPath();

            //attempt to remove services first.
            //this will ignore errors of service does not exist and service marked for deletion
            //If service is marked for deletion, then exception will be thrown at create time as
            //we will be unable to create the service.
            //reason:
            //1. Keeps the code path of Install and Repair same
            //2. Handles corner case of service already existing in Install mode
            //3. Repairs the configuration of the service if broken

            IntPtr hSCManager = NativeMethods.NullIntPtr;
            IntPtr password   = NativeMethods.NullIntPtr;

            try
            {
                hSCManager = ServiceConfigurationHandler.GetSCMHandle();

                //TODO: Handle rollback if exception is thrown
                ServiceConfigurationHandler.StopAndRemoveService(hSCManager, SetupConstants.EngineServiceName);

                //construct paths to service binaries
                string servicePathEngine = PathHelper.QuoteString(installPath + @"MSIT\CmpWorkerService\" + SetupConstants.EngineServiceBinary);
                SetupLogger.LogInfo("BackEnd.Configure: Engine Service path is : {0}", servicePathEngine);

                //Get account
                string userAccountName   = null;
                bool   runasLocalAccount = SetupInputs.Instance.FindItem(SetupInputTags.CmpServiceLocalAccountTag);
                if (!runasLocalAccount)
                {
                    userAccountName = UserAccountHelper.GetVmmServiceDomainAccount();
                    password        = Marshal.SecureStringToGlobalAllocUnicode(SetupInputs.Instance.FindItem(SetupInputTags.CmpServiceUserPasswordTag));
                }

                //create engine service
                ServiceConfigurationHandler.CreateService(
                    hSCManager,
                    SetupConstants.EngineServiceName,
                    Resources.EngineServiceDisplayName,
                    Resources.EngineServiceDescription,
                    servicePathEngine,
                    null,   // dependent services
                    userAccountName,
                    password: password,
                    autoStart: true,
                    interactive: false);

                //set failure actions for VMMService
                NativeMethods.SERVICE_FAILURE_ACTIONS sfa = new NativeMethods.SERVICE_FAILURE_ACTIONS();
                NativeMethods.SC_ACTION[]             sca = new NativeMethods.SC_ACTION[SetupConstants.ServiceActionsCount + 1];
                for (int i = 0; i < SetupConstants.ServiceActionsCount; i++)
                {
                    sca[i].Delay = SetupConstants.ServiceRestartDelay;
                    sca[i].Type  = NativeMethods.SC_ACTION_TYPE.SC_ACTION_RESTART;
                }
                sca[SetupConstants.ServiceActionsCount].Delay = 0;
                sca[SetupConstants.ServiceActionsCount].Type  = NativeMethods.SC_ACTION_TYPE.SC_ACTION_NONE;

                IntPtr unmanagedStructArray = NativeMethods.NullIntPtr;
                try
                {
                    unmanagedStructArray = GetUnmanagedStructArray(sca);

                    sfa.sc_Action     = unmanagedStructArray;
                    sfa.cActions      = SetupConstants.ServiceActionsCount + 1;
                    sfa.dwResetPeriod = SetupConstants.ServiceResetPeriod;
                    sfa.lpCommand     = null;
                    sfa.lpRebootMsg   = null;

                    //set service failure actions for engine service
                    ServiceConfigurationHandler.SetFailureActions(SetupConstants.EngineServiceName, ref sfa);

                    //ConfigurationProgressEvent(this, new EventArgs());
                }
                finally
                {
                    if (NativeMethods.NullIntPtr != unmanagedStructArray)
                    {
                        Marshal.FreeHGlobal(unmanagedStructArray);
                    }
                }
            }
            finally
            {
                if (!NativeMethods.NullIntPtr.Equals(hSCManager))
                {
                    NativeMethods.CloseServiceHandle(hSCManager);
                }
                if (!NativeMethods.NullIntPtr.Equals(password))
                {
                    Marshal.ZeroFreeGlobalAllocUnicode(password);
                }
            }
        }
示例#14
0
        /// <summary>
        /// Starts a particular service
        /// The method times out if service does not reach "Running" status within the timeout period.
        /// </summary>
        /// <param name="serviceName">name of service to start</param>
        /// <param name="machineName">name of computer on which the service resides</param>
        /// <exception cref="ServiceConfigurationException">when  service could not be started</exception>
        public void StartService(String serviceName, String machineName)
        {
            AppAssert.Assert(null != serviceName, "Null service name passed!");

            SetupLogger.LogInfo("StartService: Start the service {0}", serviceName);
            //ConfigurationMessageEvent(this, new ConfigurationMessageEventArgs(String.Format(Resources.StartingService, serviceName)));
            try
            {
                AppAssert.AssertNotNull(serviceName, "serviceName");

                ServiceController serviceController = null;

                try
                {
                    SetupLogger.LogInfo("Starting service" + serviceName);

                    if (machineName == null)
                    {
                        serviceController = new ServiceController(serviceName); // local host
                    }
                    else
                    {
                        serviceController = new ServiceController(serviceName, machineName);
                    }

                    SetupLogger.LogInfo("StartService: Service {0} status = {1}", serviceName, serviceController.Status);

                    //
                    // Query configurations (credentials and start mode) of service
                    //
                    ServiceConfig serviceConfig = GetServiceConfig(serviceName, machineName);

                    //
                    // Check if the service is disabled or manual and stopped
                    //
                    if (serviceConfig.StartMode == ServiceStartMode.Disabled ||
                        (serviceConfig.StartMode == ServiceStartMode.Manual &&
                         serviceController.Status == ServiceControllerStatus.Stopped))
                    {
                        SetupLogger.LogInfo(
                            "StartService : service is disabled or manual and not running");

                        throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
                    }

                    // Check if the service is stopped or paused
                    if (serviceController.Status == ServiceControllerStatus.Running)
                    {
                        // Service is running, log and return

                        SetupLogger.LogInfo("StartService: Service running, check if needs to be restarted");

                        return;
                    }
                    if (serviceController.Status == ServiceControllerStatus.Stopped)
                    {
                        // Service stopped, Start the service

                        SetupLogger.LogInfo("StartService: Service stopped, Start the service");
                        serviceController.Start();
                    }
                    else if (serviceController.Status == ServiceControllerStatus.Paused)
                    {
                        // Service paused, Resume the service

                        SetupLogger.LogInfo("StartService: Service paused, Resume the service");
                        serviceController.Continue();
                    }

                    SetupLogger.LogInfo("StartService: Wait for service to start (timeout = {0})", SetupConstants.ServiceStartTimeout);
                    serviceController.WaitForStatus(ServiceControllerStatus.Running, SetupConstants.ServiceStartTimeout);
                }
                catch (System.ComponentModel.Win32Exception win32Exception)
                {
                    // The native service API failed
                    SetupLogger.LogError("StartService: Couldn't start service! Throwing exception: {0}", win32Exception.ToString());
                    throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
                }
                catch (InvalidOperationException invalidOperationException)
                {
                    // The service can not be started
                    SetupLogger.LogError("StartService: Couldn't start service! Throwing exception: {0}", invalidOperationException.ToString());
                    throw;
                }
                catch (System.ServiceProcess.TimeoutException timeoutException)
                {
                    // There was a timeout
                    SetupLogger.LogError("StartService: Couldn't start service! Throwing exception: {0}", timeoutException.ToString());
                    throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
                }
                finally
                {
                    if (serviceController != null)
                    {
                        serviceController.Close();
                    }
                }
            }
            catch (Exception serviceNotFoundException)
            {
                SetupLogger.LogInfo("ServiceConfigurationHandler.StartService: Start the service, exception {0}", serviceNotFoundException);
                throw new Exception(String.Format("Cannot start the service. Service name: {0}", serviceName));
            }
        }
示例#15
0
        public static ServiceConfig GetServiceConfig(String serviceName, String machineName)
        {
            if (serviceName == null)
            {
                SetupLogger.LogInfo("InspectConfigs.GetServiceConfig : Service name parametr is null");

                throw new Exception("Service name is null");
            }

            ServiceConfig serviceConfig = new ServiceConfig();

            NativeMethods.QUERY_SERVICE_CONFIGW serviceConfigQueryResult = new NativeMethods.QUERY_SERVICE_CONFIGW();

            IntPtr schSCManager = new IntPtr(0);
            IntPtr schService   = new IntPtr(0);

            int result = 0;

            UInt32 dwBytesNeeded = 0;

            try
            {
                //
                // Open handle to Service control manager
                //

                schSCManager = NativeMethods.OpenSCManager(
                    machineName, // null for local machine
                    null,        // ServicesActive database
                    NativeMethods.SC_MANAGER_CONNECT);

                if (NativeMethods.NullIntPtr.Equals(schSCManager))
                {
                    //
                    // Could not open service database
                    //

                    result = Marshal.GetLastWin32Error();
                    SetupLogger.LogError("GetServiceConfig : Unknown error while connecting to OpenSCManager");

                    throw new Exception("Cannot connect to service manager");
                }

                //
                // Open handle to the service
                //

                schService = NativeMethods.OpenService(
                    schSCManager,                        // SCManager database
                    serviceName,                         // name of service
                    NativeMethods.SERVICE_QUERY_CONFIG); // need QUERY access

                if (NativeMethods.NullIntPtr.Equals(schService))
                {
                    //
                    // Could not open service
                    //

                    result = Marshal.GetLastWin32Error();

                    switch (result)
                    {
                    case NativeMethods.ERROR_SERVICE_DOES_NOT_EXIST:
                    {
                        SetupLogger.LogInfo("GetServiceConfig : Service not found, ERROR_SERVICE_DOES_NOT_EXIST");

                        throw new Exception(String.Format("OpenService returned error ERROR_SERVICE_DOES_NOT_EXIST (Service not found) for service {0}", serviceName));
                    }

                    default:
                    {
                        SetupLogger.LogError("GetServiceConfig : Unknown error while connecting to Service");

                        throw new Exception("GetServiceConfig : Unknown error while connecting to Service");
                    }
                    }
                }

                //
                // Get the configuration information (Query SCM)
                //

                UInt32 size        = (UInt32)Marshal.SizeOf(serviceConfigQueryResult);
                bool   queryResult = NativeMethods.QueryServiceConfig(
                    schService,
                    ref serviceConfigQueryResult,
                    size,
                    ref dwBytesNeeded);

                if (queryResult == false)
                {
                    //
                    // Query to SCM for service configuration failed
                    //

                    result = Marshal.GetLastWin32Error();

                    SetupLogger.LogError("InspectConfigs.GetServiceConfig : Unknown error while querying service configuration information");

                    throw new Exception(String.Format("Error getting the service configuration for service {0}", serviceName));
                }

                //
                // Set service credentials parameter in output structure ServiceConfig
                //

                serviceConfig.ServiceCredentials = Marshal.PtrToStringAuto(serviceConfigQueryResult.lpServiceStartName);

                //
                // Set start mode parameter in output structure ServiceConfig
                //

                if (serviceConfigQueryResult.dwStartType == NativeMethods.SERVICE_AUTO_START)
                {
                    //
                    // Service AUTO start
                    //

                    serviceConfig.StartMode = ServiceStartMode.Automatic;
                }
                else if (serviceConfigQueryResult.dwStartType == NativeMethods.SERVICE_DISABLED)
                {
                    //
                    // Service disabled (can not be started)
                    //

                    serviceConfig.StartMode = ServiceStartMode.Disabled;
                }
                else
                {
                    //
                    // The .NET enumeration does not define SERVICE_BOOT_START and SERVICE_SYSTEM_START
                    // Hence we set it to manual. Service needs to be started manually
                    //

                    serviceConfig.StartMode = ServiceStartMode.Manual;
                }
            }
            finally
            {
                // cleanup
                if (!NativeMethods.NullIntPtr.Equals(schService))
                {
                    NativeMethods.CloseServiceHandle(schService);
                }

                if (!NativeMethods.NullIntPtr.Equals(schSCManager))
                {
                    NativeMethods.CloseServiceHandle(schSCManager);
                }
            }


            return(serviceConfig);
        }
示例#16
0
        /// <summary>
        /// This method calls into native code for creating a service.
        /// The service is created with the following standard parameters:
        /// WIN32_OWN_PROCESS, ERROR_NORMAL, No dependencies
        /// The handle of the service obtained is closed and not returned
        /// </summary>
        /// <param name="hSCManager">Handle to SCM with create service rights</param>
        /// <param name="svcName">Name of service to create</param>
        /// <param name="displayName">Localized display name of the service</param>
        /// <param name="svcDescription">Description of the service</param>
        /// <param name="binaryPath">Path to the binary</param>
        /// <param name="dependenciesArray">Array of dependencies</param>
        /// <param name="serviceStartName">The user account under which the service will run</param>
        /// <param name="password">Password for the user account</param>
        /// <param name="autoStart">Should the service be AutoStart on booting the machine</param>
        /// <param name="interactive">Allow service to interact with desktop or not</param>
        public static void CreateService(IntPtr hSCManager,
                                         string svcName,
                                         string displayName,
                                         string svcDescription,
                                         string binaryPath,
                                         string[] dependenciesArray,
                                         string serviceStartName,
                                         IntPtr password,
                                         bool autoStart,
                                         bool interactive)
        {
            IntPtr hService = NativeMethods.NullIntPtr;

            try
            {
                AppAssert.Assert(null != svcName, "Null service name passed!");
                AppAssert.Assert(null != binaryPath, "Null binary path passed!");

                string dependenciesString = CreateNativeStringArray(dependenciesArray);

                int svcType = NativeMethods.SERVICE_WIN32_OWN_PROCESS;
                if (interactive)
                {
                    svcType = NativeMethods.SERVICE_WIN32_OWN_PROCESS | NativeMethods.SERVICE_INTERACTIVE_PROCESS;
                }

                int svcStartType = NativeMethods.SERVICE_DEMAND_START;
                if (autoStart)
                {
                    svcStartType = NativeMethods.SERVICE_AUTO_START;
                }

                if (!NativeMethods.NullIntPtr.Equals(password))
                //if we are using a password we need to gr  ant logon as service permissions to this user.
                {
                    try
                    {
                        NativeMethods.SetRight(serviceStartName, "SeServiceLogonRight", true);
                        NativeMethods.SetRight(serviceStartName, "SeAssignPrimaryTokenPrivilege", true);
                    }
                    catch (Exception exp)
                    {
                        SetupLogger.LogError("Failed to grant user ( " + serviceStartName +
                                             " ) logon as service permissions. Error: " + exp.Message);
                    }
                }

                hService = NativeMethods.CreateService(
                    hSCManager,
                    svcName,
                    displayName,
                    NativeMethods.SERVICE_CHANGE_CONFIG,
                    svcType,
                    svcStartType,
                    NativeMethods.SERVICE_ERROR_NORMAL,
                    binaryPath,
                    null,                     //load order group
                    NativeMethods.NullIntPtr, //[out] tagId
                    dependenciesString,
                    serviceStartName,         //Username
                    password
                    );

                if (NativeMethods.NullIntPtr.Equals(hService))
                {
                    SetupLogger.LogInfo("BackEnd.Configure: Got back NULL service handle!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Cannot create service {0}", svcName));
                }

                NativeMethods.SERVICE_DESCRIPTION svcDesc = new NativeMethods.SERVICE_DESCRIPTION();
                svcDesc.lpDescription = svcDescription;
                bool success = NativeMethods.ChangeServiceConfig2(hService, NativeMethods.SERVICE_CONFIG_DESCRIPTION,
                                                                  ref svcDesc);

                if (!success)
                {
                    SetupLogger.LogInfo("BackEnd.Configure: Couldn't modify service description!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Cannot create service {0}", svcName));
                }

                // Set service SID type. This is required for any service that has a firewall rule targeted for that specific service.
                NativeMethods.SERVICE_SID_INFO svcSidType = new NativeMethods.SERVICE_SID_INFO();
                svcSidType.serviceSidType = NativeMethods.SERVICE_SID_TYPE.SERVICE_SID_TYPE_UNRESTRICTED;
                success = NativeMethods.ChangeServiceConfig2(hService, NativeMethods.SERVICE_CONFIG_SERVICE_SID_INFO,
                                                             ref svcSidType);

                if (!success)
                {
                    SetupLogger.LogInfo("BackEnd.Configure: Couldn't modify service SID type!");
                    int lastWin32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    throw new Exception(String.Format("Cannot create service {0}", svcName));
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                if (NativeMethods.NullIntPtr != hService)
                {
                    NativeMethods.CloseServiceHandle(hService);
                }
            }
        }
示例#17
0
 private void Configuration_ConfigurationMessageEvent(Object sender, ConfigurationMessageEventArgs e)
 {
     SetupLogger.LogInfo("ServiceConfigurationHandler : Configure message event : {0}", e.Message);
 }
示例#18
0
 private void Configuration_ConfigurationProgressEvent(Object sender, EventArgs e)
 {
     SetupLogger.LogInfo("ServiceConfigurationHandler : Configure progress event");
 }
示例#19
0
        private void Impersonate(string userName, string domain, InputParameter pwd)
        {
            string userAccountName = String.Format(SetupConstants.UserAccountTemplate, domain, userName);

            SetupLogger.LogInfo("We are going to impersonate as {0}.", userAccountName);


            const int LOGON32_PROVIDER_DEFAULT  = 0;
            const int LOGON32_LOGON_INTERACTIVE = 2;

            this.tokenHandle = CMP.Setup.Helpers.NativeMethods.NullIntPtr;

            IntPtr password = IntPtr.Zero;

            try
            {
                if (pwd != null)
                {
                    password = Marshal.SecureStringToGlobalAllocUnicode(pwd);
                }

                logonSuccessful = CMP.Setup.Helpers.UnsafeNativeMethods.LogonUser(
                    userName, domain, password,
                    LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref this.tokenHandle);

                // LogonUser() if successful will return a non-zero value else it will return a 0
                if (logonSuccessful)
                {
                    WindowsIdentity windowsIdentity = new WindowsIdentity(this.tokenHandle);
                    this.windowsImpersonationContext = windowsIdentity.Impersonate();
                }
                else
                {
                    // LogonUser has failed so GetLastWin32Error() and throw an exception
                    int winError = Marshal.GetLastWin32Error();
                    throw new Exception("The remote SQL Server administrator credentials provided are not valid");
                }
            }
            catch (ArgumentException)
            {
                throw new Exception("The remote SQL Server administrator credentials provided are not valid");
            }
            catch (SecurityException)
            {
                // Constructor WindowsIdentity(this.tokenHandle) can throw this exception
                // This can mean either The caller does not have the correct permissions OR A Win32 error occured

                // WindowsIdentity.Impersonate() can also throw this exception
                // This can mean that A Win32 error occured
                throw new Exception("The remote SQL Server administrator credentials provided are not valid");
            }
            catch (InvalidOperationException)
            {
                // WindowsIdentity.Impersonate() can throw this exception
                // This can mean that An anonymous identity attempted to perform an impersonation
                throw new Exception("The remote SQL Server administrator credentials provided are not valid");
            }
            finally
            {
                if (IntPtr.Zero != password)
                {
                    Marshal.ZeroFreeGlobalAllocUnicode(password);
                }
            }
        }