/// <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)); } }
/// <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); } } }
/// <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); }
/// <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)); } }
/// <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); } }
/// <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()); } }
/// <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); }
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()); }
/// <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); }
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"); }
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); }
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; }
/// <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); } } }
/// <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)); } }
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); }
/// <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); } } }
private void Configuration_ConfigurationMessageEvent(Object sender, ConfigurationMessageEventArgs e) { SetupLogger.LogInfo("ServiceConfigurationHandler : Configure message event : {0}", e.Message); }
private void Configuration_ConfigurationProgressEvent(Object sender, EventArgs e) { SetupLogger.LogInfo("ServiceConfigurationHandler : Configure progress event"); }
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); } } }