//---------------------------------------------------------------------------- // // Copyright © 2009-2014, Intel Corporation. All rights reserved. // // File: LogicLayer.cs // //---------------------------------------------------------------------------- using System; using UCT.Forms; using UCT.Utils; using System.Text; using System.Timers; using System.Windows.Forms; using System.Collections.Generic; using System.Threading; namespace UCT { /// /// The main class - hold the logic behind the operations /// public class LogicLayer : IUserConsentFlow, IDisposable { #region - Dictionaries - // OptInService Functions Statuses Dictionary StatusCodes = new Dictionary() { {0, "Success"}, {1, "Internal error"}, {2, "Invalid state"}, {3, "Operation is blocked"}, {2066, "Invalid credentials"} }; // Power state change return values Dictionary PowerStatusCode = new Dictionary() { {0, "succuess"}, {1, "Operation is not supported"}, {2, "Unknown or unspecified error"}, {3, "Operation cannot be completed within timeout period"}, {4, "Operation failed"}, {5, "Invalid parameter"}, {6, "In use"}, {4099, "Invalid power transition"}, {4096, "Reserved"} }; #endregion #region - Consts - // Hold the time (in minutes) required for detecting if sprite is supported private const int SPRITE_SUPPORTED_TIMEOUT = 15; #endregion #region - Private Members - // The GUI instance private UserInterface _UI; // The target system instance private TargetSystem _targetSystem; // Indicates if 15 seconds has elapsed when establishing if sprite is supported. private bool _timeHadElapsed = false; // Indicate if Sprite is suppported on the remote system private bool _spriteIsSupported = false; // Indicates if power operation was successful private bool _powerOperationSucceed = false; // Indicates if the previous optInState was 'in-session'. private bool _isLastStateInSession; // Reflects the result of the graceful shutdown private bool _gracfulResult = false; // Indicate whether the user cancel the progress bar private bool _userCancel; // Holds the optInState after connection was established. // This is used for the code timer settings. private int _firstStateUpdateAfterConnect = 0; // Indicate whether the opt in state was changed private bool _statusChanged = false; // Indicate whether to reboot after shutdown or just log off private bool _rebootAfterShutdown; // Power operations timers private System.Timers.Timer _timer, _timerBoot, _timerGraceful; int _spriteCounter = 0, _bootCounter = 0; // Hold the system power state private PowerState _powerState; #endregion #region - Timer Events - /// /// Timer that running when executing graceful shutdown /// /// /// void timerGraceful_Elapsed(object sender, ElapsedEventArgs e) { _timerGraceful.Enabled = false; if (_rebootAfterShutdown) { WriteLog(LogLevel.BASIC, string.Format(Properties.Resources.EXECUTE_GRACEFUL_RESET_MESSAGE, Configuration.BasicSettings.GetInstance().AmtHost), LogInteraction.Information); } else { WriteLog(LogLevel.BASIC, string.Format(Properties.Resources.EXECUTE_GRACEFUL_SHUTDOWN_MESSAGE, Configuration.BasicSettings.GetInstance().AmtHost), LogInteraction.Information); } if (_targetSystem.PerfomGracefulShutDown(_rebootAfterShutdown)) { _gracfulResult = true; _UI.stopProgress = true; _timerGraceful.Stop(); _timerGraceful.Close(); } else { _UI.stopProgress = true; _gracfulResult = false; _timerGraceful.Stop(); _timerGraceful.Close(); } } /// /// Timer that running when detecting if sprite is supported /// /// /// private void OnShortTimedEvent(object source, ElapsedEventArgs e) { if (_spriteCounter < SPRITE_SUPPORTED_TIMEOUT) { _spriteCounter++; OptInState state = _targetSystem.GetOptInState(); if (state == OptInState.Displayed) { WriteLog(LogLevel.DETAILED, string.Format(Properties.Resources.GETTING_OPT_IN_STATE_MESSAGE, state.ToString()), LogInteraction.FWOperation); // Disable the timers _spriteIsSupported = true; _UI.stopProgress = true; _timer.Stop(); _timer.Close(); } } else { _timeHadElapsed = true; _UI.stopProgress = true; _timer.Stop(); _timer.Close(); } } /// /// Timer that running when performing AMT reboot /// /// /// void timerBoot_Elapsed(object sender, ElapsedEventArgs e) { _bootCounter++; // Check if time had elapsed, or state was changed to the desired one. if ((_bootCounter >= SPRITE_SUPPORTED_TIMEOUT) || (_targetSystem.GetPowerState() == _powerState)) { _UI.stopProgress = true; _timerBoot.Stop(); _timerBoot.Close(); } } public uint GetOptInTimeOut() { return _targetSystem.UctOperation.GetOptInTimeout(); } public bool CheckOptInTimeoutSupport() { return (_targetSystem.UctOperation.CheckOptInTimeoutSupport()); } public bool Check3DisplaysSupport() { return (_targetSystem.UctOperation.CheckThirdScreenSupport()); } public bool CheckLinkProtectionSupport() { return (_targetSystem.WirelessOperation.CheckLinkProtectionSupport()); } public void SetOptInTimeOut(uint time) { try { UpdateGUIMessages(LogLevel.BASIC, "Settings the Opt-In timeout to: " + time + "seconds", LogInteraction.UserOperation, "Setting the Opt-In timeout to: " + time + " seconds"); _targetSystem.SetOptInTimeout(time); _UI.DisplayStatusBar("Opt-In timeout was set successfully"); } catch (UCTException ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, "Failed to set the Opt-In timeout"); _UI.DisplayMessage("Set Opt-In timeout failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } catch (Exception ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, "Failed to set the Opt-In timeout"); _UI.DisplayMessage("Set Opt-In timeout failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } } #endregion #region - Constructors and Design pattern methods - /// /// Constructor /// public LogicLayer() { _timer = new System.Timers.Timer(); _timerBoot = new System.Timers.Timer(); _timerGraceful = new System.Timers.Timer(); _timerBoot.Elapsed += new ElapsedEventHandler(timerBoot_Elapsed); _timerGraceful.Elapsed += new ElapsedEventHandler(timerGraceful_Elapsed); _timer.Elapsed += new ElapsedEventHandler(OnShortTimedEvent); _timerBoot.Interval = 1000; _timer.Interval = 1000; // Set the Interval to 1 second _isLastStateInSession = false; } /// /// Register the GUI layer /// /// public void RegisterUI(UserInterface ui) { _UI = ui; } /// /// Register the target system layer /// /// public void RegisterTargetSystem(TargetSystem trs) { _targetSystem = trs; } #endregion #region - Methods - #region - Main Methods Flow - /// /// Canceling user consent /// /// public void CancelConsent() { try { // Writing relevant messages to log and status bar UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.CANCELING_USER_CONSENT_LOG_MESSAGE, LogInteraction.UserOperation, Properties.Resources.CANCELING_USER_CONSENT_STATUS_BAR_MESSAGE); // Check if cancel is allowed: i.e. if there is no Redirection of KVM open session. OptInState oiState = _targetSystem.GetOptInState(); if (oiState == OptInState.InSession) { _UI.DisplayMessage(Properties.Resources.CANCEL_USER_CONSENT_IN_SESSION_MESSAGE, Properties.Resources.CANCEL_USER_CONSENT_PROGRESS_BAR_MESSAGE, MessageType.ERROR); UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.CANCEL_USER_CONSNET_IN_SESSION_ERROR_MESSAGE, LogInteraction.Error, "Cancel opertion failed"); return; } if (oiState == OptInState.NotStarted) { UpdateGUIMessages(LogLevel.DETAILED, "Invoking cancel consent is not required since the User Consent state is already 'NotStarted'", LogInteraction.Information, "Cancel opertion completed successfully"); return; } CancelUserConsentProcess(); } catch (UCTException ex) { _UI.changeMouse(Cursors.Default); _UI.DisplayMessage(string.Format(Properties.Resources.OPERATION_FAILED_ERROR_MESSAGE, ex.Message), Properties.Resources.OPERATION_FAILED, MessageType.ERROR); UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error, Properties.Resources.CANCEL_USER_CONSENT_FAILURE); } catch (Exception ex) { _UI.changeMouse(Cursors.Default); _UI.DisplayMessage(ex.Message, Properties.Resources.OPERATION_FAILED, MessageType.ERROR); UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error, Properties.Resources.CANCEL_USER_CONSENT_FAILURE); } } /// /// Canceling the user consent (include just the FW call, without the state checking) /// private void CancelUserConsentProcess() { _UI.changeMouse(Cursors.WaitCursor); // Performing the cancel operation uint res = _targetSystem.CancelConsent(); _UI.changeMouse(Cursors.Default); if (res != 0) { _UI.DisplayMessage("Cancel consent operation failed with error code: " + res + " - " + StatusCodes[res], Properties.Resources.CANCEL_USER_CONSENT_FAILURE, MessageType.ERROR); UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.CANCEL_USER_CONSENT_FAILURE_ERROR_CODE, res), LogInteraction.Error, "Cancel operation failed"); } else { _UI.DisplayStatusBar("Cancel operation completed successfully"); } } /// /// Start user consent flow /// public void StartConsent() { try { _UI.changeMouse(Cursors.WaitCursor); RunFullFlow(); _UI.changeMouse(Cursors.Default); } catch (UCTException ex) { _UI.changeMouse(Cursors.Default); _UI.DisplayMessage(string.Format(Properties.Resources.OPERATION_FAILED_ERROR_MESSAGE, ex.Message), Properties.Resources.OPERATION_FAILED, MessageType.ERROR); UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, Properties.Resources.STARTING_CONSNET_FAILED); } catch (Exception ex) { _UI.changeMouse(Cursors.Default); _UI.DisplayMessage(Properties.Resources.UNKNOWN_ERROR, Properties.Resources.OPERATION_FAILED, MessageType.ERROR); UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, Properties.Resources.STARTING_CONSNET_FAILED); } } /// /// Sent the OptIn code /// /// public void SendCode(uint code) { try { UpdateGUIMessages(LogLevel.BASIC, "Sending the optInCode", LogInteraction.UserOperation, "Sending the consent code..."); uint res = _targetSystem.SendCode(code); if (res != 0) { UpdateGUIMessages(LogLevel.BASIC, "Send User Consent code failed with error code: " + res, LogInteraction.FWOperation, "Send consent code operation failed"); _UI.DisplayMessage("Send Code operation failed with error code: " + res + ", " + StatusCodes[res], "Operation Failed", MessageType.ERROR); return; } else { UpdateGUIMessages(LogLevel.BASIC, "Code was sent successfully, consent was obtained", LogInteraction.FWOperation, "Code was sent successfully, consent was obtained"); _UI.DisplayMessage("Code was submitted successfully, consent was obtained.\nOperations that require consent can be performed.", "", MessageType.INFO); } } catch (UCTException ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, "Failed to send the consent code"); _UI.DisplayMessage("Send consent code failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } catch (Exception ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error, "Failed to send the consent code"); _UI.DisplayMessage("Send consent code failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } } #endregion #region - Boot Methods - /// /// This method try to reboot the system, first gracefully (via OS), if failed - try AMT shutdown /// private void RebootSystem(LinkInterface linkInterface) { // Perform graceful shutdown just if the user ask for if (Properties.Settings.Default.USE_GRACFUL_SHUTDOWN_BEFORE_AMT_REBOOT) { if (!PerformGracefulShutdown()) return; // If we are connected over wireless interface, we must set the link preference to // ME before reboot the system (otherwise, connection will lost), but because that graceful shutdown // is a WinAPI command in order this command to success the link must be 'Host'. // So we first send the graceful shutdown command and then start the loop of SetLinkPrefernce if (linkInterface == LinkInterface.Wireless) _targetSystem.StartLinkPreferenceThread(true); // If the graceful operation failed - ask user if to reboot with AMT. if (!_gracfulResult) { UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.GRACEFUL_SHUTDOWN_FAILED, LogInteraction.Error, "Graceful reboot operation failed"); if (_UI.DisplayMessage(Properties.Resources.GRACEFUL_SHUTDOWN_MESSAGE_BOX_MESSAGE, Properties.Resources.OPERATION_FAILED, MessageType.QUESTION) == DialogResult.Yes) { // Perform AMT Shutdown if (!PerformAMTShutDown(PowerState.MasterBusReset)) return; } } else { UpdateGUIMessages(LogLevel.DETAILED, "Graceful reboot operation completed successfully", LogInteraction.FWOperation, "Graceful reboot operation completed successfully"); } } else { // Reboot when interface is wireless required set link preference to ME before executing the operation. if (linkInterface == LinkInterface.Wireless) _targetSystem.StartLinkPreferenceThread(true); // Perform AMT Shutdown if (!PerformAMTShutDown(PowerState.MasterBusReset)) return; } } /// /// Execute graceful shutdown on the target system /// /// Indicate if the progress bar has 'Cancel' option, this button is used for cancel /// the consent flow (e.g. reset the opt in state to NotStarted) /// true - continue the flow, false - abort the flow public bool PerformGracefulShutdown(bool hasCancel, bool hasSkip, bool hasReboot) { try { // Indicate whether we need reboot after or not. _rebootAfterShutdown = hasReboot; // Update status bar and log if (hasReboot) UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.GRACEFUL_REBOOT_LOG_MESSAGE, LogInteraction.UserOperation, Properties.Resources.GRACEFUL_REBOOT_STATUS_BAR_MESSAGE); else UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.GRACEFUL_SHUTDOWN_LOG_MESSAGE, LogInteraction.UserOperation, Properties.Resources.GRACEFUL_SHUTDOWN_STATUS_BAR_MESSAGE); // Reset all the progress bar properties to their default values _UI.stopProgress = _gracfulResult = false; // Start the graceful shutdown timer _timerGraceful.Start(); DialogResult dResult; if (hasReboot) dResult = _UI.RunProgressBar(Properties.Resources.GRACEFUL_REBOOT_PROGRESS_BAR, Properties.Resources.GRACEFUL_REBOOT_HEADER, hasCancel, hasSkip); else dResult = _UI.RunProgressBar(Properties.Resources.GRACEFUL_SHUTDOWN_PROGRESS_BAR, Properties.Resources.GRACEFUL_SHUTDOWN_HEADER, hasCancel, hasSkip); if (dResult != DialogResult.Cancel) { _timerGraceful.Stop(); _timerGraceful.Enabled = false; UpdateGUIMessages(LogLevel.BASIC, "Reboot operation was canceled by the user", LogInteraction.UserOperation, "Power operation was aborted"); _UI.stopProgress = true; // Choosing 'Cancel' in the progress bar will cancel the flow (Skip - for stop the flow at this point) if (dResult == DialogResult.Ignore) { CancelUserConsentProcess(); return false; } _UI.RefreshScreen(); } if (!_gracfulResult) { _UI.DisplayStatusBar(hasReboot ? "Graceful reset failed" : "Graceful shutdown failed"); } else { // Indicate the grageful shutdown succeed if (hasReboot) UpdateGUIMessages(LogLevel.BASIC, "Graceful reset completed successfully", LogInteraction.Information, "Graceful reset completed successfully"); else UpdateGUIMessages(LogLevel.BASIC, "Graceful shutdown completed successfully", LogInteraction.Information, "Graceful shutdown completed successfully"); } return true; } catch (UCTException ex) { if (hasReboot) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error, "Graceful reset failed"); _UI.DisplayMessage("Graceful reset failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } else { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error, "Graceful shutdown failed"); _UI.DisplayMessage("Graceful shutdown failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } } catch (Exception ex) { if (hasReboot) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error, "Graceful reset failed"); _UI.DisplayMessage("Graceful reset failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } else { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error, "Graceful shutdown failed"); _UI.DisplayMessage("Graceful shutdown failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } } return false; } /// /// Execute AMT shutdown on the target system /// /// Indicate if the progress bar has 'Cancel' option, this button is used for cancel /// the consent flow (e.g. reset the opt in state to NotStarted) /// true - continue the flow, false - abort the flow public bool PerformAMTShutDown(PowerState state, bool hasCancel, bool hasSkip) { try { // Update status bar and log UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.PERFORMING_POWER_OPERATION_LOG, state.ToString()), LogInteraction.UserOperation, Properties.Resources.PERFORMING_POWER_OPERATION_STATUS_BAR); // Reset all parameters to default values _powerOperationSucceed = false; _bootCounter = 0; _powerState = state; DialogResult dResult = DialogResult.Cancel; Thread _thread = new Thread(new ThreadStart(()=>{ UserInterface _UI1 = new UserInterface(); // Display a progress bar until power state is changed, or 15 seconds had elapsed. _timerBoot.Start(); _UI1.stopProgress = false; dResult = _UI1.RunProgressBar("Performing power operation on the remote system...", "Power Operation in progress", false, false); })); //end _thread.Start(); // Execute the power operation WriteLog(LogLevel.DETAILED, "AMT_AssociatedPoweManagerService.ChnagePowerState was executed", LogInteraction.FWOperation); uint res = _targetSystem.ChangePowerState(state); _powerOperationSucceed = res == 0 ? true : false; _thread.Abort(); if (dResult != DialogResult.Cancel) { _timerBoot.Stop(); _timerBoot.Enabled = false; _UI.stopProgress = true; UpdateGUIMessages(LogLevel.BASIC, "Power operation was canceled by the user", LogInteraction.UserOperation, "Power operation was aborted"); // Choosing 'Cancel' in the progress bar will cancel the flow (Skip - for stop the flow at this point) if (dResult == DialogResult.Ignore) { CancelUserConsentProcess(); return false; } } // Check if power operation failed if (_powerOperationSucceed) { UpdateGUIMessages(LogLevel.BASIC, "Power Operation: " + state.ToString() + " completed successfully", LogInteraction.FWOperation, "Power operation completed successfully"); } else { _UI.DisplayMessage("Power Operation failed with error code: " + res + ", " + (PowerStatusCode.ContainsKey(res) ? PowerStatusCode[res] : PowerStatusCode[2]), "Power Operation Failed", MessageType.ERROR); } } catch (UCTException ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error, "Graceful shutdown failed"); _UI.DisplayMessage("Power operation failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } catch (Exception ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error, "Graceful shutdown failed"); _UI.DisplayMessage("Power operation failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } _UI.RefreshScreen(); return true; } #endregion #region - Utils Methods /// /// Change the connection address (used when changing the host name via the combo box) /// /// internal bool ChangeConnectionAddress() { try { // Update log and status bar UpdateGUIMessages(LogLevel.BASIC, "Connecting to: " + Configuration.GetInstance().Basic.AmtHost, LogInteraction.UserOperation, "Connecting to the remote system..."); // Try to establish connection if (Configuration.GetInstance().InitWSManClient() != UCT.ConnectionStatus.Connected) return false; if (CertificateUtils.ValidateCertificate()) { SetDefaultValues(); return true; } return false; } // Connection failed catch (Exception e) { // Update log and status bar UpdateGUIMessages(LogLevel.BASIC, "Exception was thrown: " + e.Message, LogInteraction.Error, "Failed to connect to the remote system"); _targetSystem.StartPolling(false); SetApplicationToUnknown(); _UI.DisplayMessage(e.Message, "Failed to connect to the remote system", MessageType.ERROR); _UI.connectionState = ConnectionState.DISCONNECTED; _UI.ChangeGuiToDisconnect(ConnectionState.DISCONNECTED); _UI.RefreshScreen(); } return false; } /// /// Set the application to its default values /// public void SetDefaultValues() { try { _targetSystem.SetDefaultOptInState(); _targetSystem.SetDefaultPowerState(); _isLastStateInSession = false; _targetSystem.StartPolling(true); _firstStateUpdateAfterConnect = 0; UpdateGUIMessages(LogLevel.BASIC, "Successfully Connected to: " + Configuration.GetInstance().Basic.AmtHost, LogInteraction.Connection, "Connected to the remote system"); _UI.connectionState = ConnectionState.CONNECTED; _UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED); } catch (Exception ex) { WriteLog(LogLevel.DETAILED, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.Error); } } /// /// Get the statistics tab information /// /// public Dictionary GetStatisticsParams() { WriteLog(LogLevel.BASIC, "Getting connection parameters", LogInteraction.FWOperation); return _targetSystem.GetConnectionParameters(); } /// /// Open the log file (in notepad) /// public void ViewLog() { try { LogManager.GetInstance().ViewLogFile(); } catch (UCTException e) { _UI.DisplayMessage(e.Message, "Failed to open the Log", MessageType.ERROR); } } /// /// Write a line to the log /// /// /// /// public void WriteLog(LogLevel level, string message, LogInteraction interaction) { try { // Adding the operation details to the log file StringBuilder line = LogManager.WriteOperation(level, message, interaction); if (line.ToString() != String.Empty) { // Adding the operation details to the log viewer _UI.WriteToLog(line.ToString(), interaction); } } catch (Exception) { } } /// /// Update the GUI - write the current operation to the log and status bar /// /// /// /// /// private void UpdateGUIMessages(LogLevel logLevel, string logMessage, LogInteraction logInteraction, string statusbarMessage) { WriteLog(logLevel, logMessage, logInteraction); _UI.DisplayStatusBar(statusbarMessage); } /// /// Check if meanwhile, the consent state changed to disconnect /// /// private bool EnsureRelevantState() { if (_targetSystem.GetOptInState() == OptInState.Displayed) { _UI.DisplayMessage("This operation is not necessary since the consent state already changed to display.\nOperation aborted", "Information", MessageType.INFO); return false; } return true; } #endregion #region - Polling Methods - /// /// This is the main function - once the opt in state property is changed, this method is called /// /// public void UpdateOptInState(OptInState state) { try { _UI.SetOptInState(state); // The first state is not 'NotStarted' - the timer should be disable (Display warning?) if (_firstStateUpdateAfterConnect++ == 0 && (state == OptInState.Received || state == OptInState.Displayed || state == OptInState.Requested)) { // The first machine state is Display/Recieve/Requested _UI.SetTimerState(TimerStatus.DISABLE); _UI.ChangeTimerNote("The Timer cannot be set at this state"); } else { switch (state) { case OptInState.Unknown: { _UI.SetTimerState(TimerStatus.DISABLE); _UI.ChangeTimerNote(string.Empty); break; } case OptInState.NotStarted: { _UI.SetTimerState(TimerStatus.DISABLE); _UI.ChangeTimerNote("Timer is activated once the consent code is recieved"); break; } case OptInState.Requested: { _UI.ChangeTimerNote("Consent code expiration timeout started"); break; } case OptInState.Displayed: { _UI.ChangeTimerNote("Consent code expiration timeout started"); break; } case OptInState.InSession: { // Time is not running but its value is 15 _UI.SetTimerState(TimerStatus.FREEZE); _UI.ChangeTimerNote("Timer is reset when a session is opened"); break; } case OptInState.Received: { // If the previous state was "InSession" - timer is start for the beginning _UI.SetTimerState(TimerStatus.RUN); _UI.ChangeTimerNote(string.Empty); break; } } } switch (state) { case OptInState.Unknown: SetApplicationToUnknown(); break; case OptInState.InSession: SetApplicationToInSession(); break; case OptInState.NotStarted: SetApplicationToNotStarted(); break; case OptInState.Requested: SetApplicationToRequested(); break; case OptInState.Displayed: SetApplicationToDisplayed(); break; case OptInState.Received: SetApplicationToRecieved(); break; } // Update this value to indicate if last state was in-session. this is used to setup the code timer. _isLastStateInSession = (state == OptInState.InSession) ? true : false; } catch (UCTException ex) { _UI.SetPowerState(PowerState.Unknown); _UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR); WriteLog(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.FWOperation); } catch (Exception ex) { WriteLog(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.FWOperation); _UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR); } } /// /// Set the tool to 'Unknown' state /// public void SetApplicationToUnknown() { if (!_statusChanged) { _UI.DisplayStatusBar("Not Connected"); WriteLog(LogLevel.BASIC, "Connection to: " + Configuration.BasicSettings.GetInstance().AmtHost + " was lost", LogInteraction.Error); // Stop the polling properties _targetSystem.StartPolling(false); // Change statistics to 'Not - Available' _UI.InitStatisticsTab(false); // Changed the connection icon indication _UI.ChangeConnectionIcon(false); // Disable tab operations _UI.InitOperationTab(false); // Disable start / cancel buttons _UI.ChangeMainButtonsStatus(false); // Disable advance tab _UI.InitAdvancedTab(false); // Change the power state label _UI.ChangePowerStateLabel(false); // Stop the timer _UI.SetTimerState(TimerStatus.DISABLE); // Change the GUI to indicate disconnection _UI.ChangeGuiToDisconnect(ConnectionState.DISCONNECTED); _UI.SetConnectioDetailsToUnknown(false); _statusChanged = true; } } /// /// Set the tool to 'Not Started' state /// private void SetApplicationToNotStarted() { WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'Not Started'", LogInteraction.FWOperation); // Enable the main button _UI.SetStartCancelButtonState(true); // Enable start / cancel buttons _UI.ChangeMainButtonsStatus(true); // Start the polling properties _targetSystem.StartPolling(true); // Update statistics _UI.InitStatisticsTab(true); // Changed the connection icon indication _UI.ChangeConnectionIcon(true); // Disable tab operations _UI.InitOperationTab(false); // Enable advance tab _UI.InitAdvancedTab(true); // Change the GUI controls to indicate connection _UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED); // Stop the link preference polling _targetSystem.StartLinkPreferenceThread(false); _statusChanged = false; } /// /// Set the tool to 'Displayed' state /// private void SetApplicationToDisplayed() { WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'Requested'", LogInteraction.FWOperation); // Start polling _targetSystem.StartPolling(true); // Set the main button to 'Cancel' _UI.SetStartCancelButtonState(false); // Update statistics _UI.InitStatisticsTab(true); // Init operation tab _UI.InitOperationTab(true); // Move the focus to the code control _UI.MoveFocousToCodeFrame(); // Changed the connection icon indication _UI.ChangeConnectionIcon(true); // Enable start / cancel buttons _UI.ChangeMainButtonsStatus(true); // Enable advance tab _UI.InitAdvancedTab(true); // Change the GUI to indicate connection _UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED); _statusChanged = false; } /// /// Set the tool to 'Requested' state /// private void SetApplicationToRequested() { WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'Requested'", LogInteraction.FWOperation); // Start (continue...) the polling _targetSystem.StartPolling(true); // Change the main button to cancel _UI.SetStartCancelButtonState(false); // Update statistics _UI.InitStatisticsTab(true); // Changed the connection icon indication _UI.ChangeConnectionIcon(true); // Disable tab operations _UI.InitOperationTab(false); // Enable start / cancel buttons _UI.ChangeMainButtonsStatus(true); // Enable advance tab _UI.InitAdvancedTab(true); // Change the GUI to indiacte connection _UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED); _statusChanged = false; } /// /// Set the tool to 'Recieved' state /// private void SetApplicationToRecieved() { WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'Received'", LogInteraction.FWOperation); // Start the polling _targetSystem.StartPolling(true); // Set the main button to cancel _UI.SetStartCancelButtonState(false); // Update statistics _UI.InitStatisticsTab(true); // Changed the connection icon indication _UI.ChangeConnectionIcon(true); // Disable tab operations _UI.ChangeSendCodeStatus(false); // Enable start / cancel buttons _UI.ChangeMainButtonsStatus(true); // Enable advanced tab _UI.InitAdvancedTab(true); // Change the GUI to indicate connection _UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED); _statusChanged = false; } /// /// Set the tool to 'In Session' state /// private void SetApplicationToInSession() { WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'In-Session'", LogInteraction.FWOperation); // Start (continue...) the polling _targetSystem.StartPolling(true); // Set the main button to enable _UI.SetStartCancelButtonState(false); // Update statistics _UI.InitStatisticsTab(true); // Changed the connection icon indication _UI.ChangeConnectionIcon(true); // Disable tab operation - BUT NOT THE CLOCK _UI.ChangeSendCodeStatus(false); // Enable start / cancel buttons _UI.ChangeMainButtonsStatus(true); // Enable advance tab _UI.InitAdvancedTab(true); // Change the GUI to indicate connection _UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED); _statusChanged = false; } /// /// Update the power state label /// /// public void UpdatePowerState(PowerState ps) { try { _UI.SetPowerState(ps); // Update the power state combo-box _UI.FillOperationOptions(ps); } catch (UCTException ex) { _UI.SetPowerState(PowerState.Unknown); _UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR); WriteLog(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.FWOperation); } catch (Exception ex) { _UI.SetPowerState(PowerState.Unknown); _UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR); WriteLog(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.FWOperation); } } public OptInState CheckOptInState() { return _targetSystem.GetOptInState(); } #endregion #region - Target system method - #region - Wireless Methods - /// /// Set the link preference /// /// /// internal void SetLinkPreference(LinkControl link, uint timeout) { try { UpdateGUIMessages(LogLevel.BASIC, string.Format("Setting the link preference to: {0} {1}", link, (link == LinkControl.ME) ? " for " + timeout + " seconds" : string.Empty), LogInteraction.UserOperation, "Setting the link preference to " + link + "..."); uint res = _targetSystem.SetLinkPreference(link, timeout); if (res != 0) { UpdateGUIMessages(LogLevel.BASIC, "SetLinkPreference failed with error code: " + res, LogInteraction.Error, "Failed to set the link preference"); } else { _UI.DisplayStatusBar("Link preference was set successfully"); _targetSystem.WirelessOperation.GetWirelessLinkState(this); } } catch (UCTException ex) { _UI.DisplayMessage("Setting the link preference failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, "Failed to set the link preference"); } catch (Exception ex) { _UI.DisplayMessage(String.Format(Properties.Resources.EXCEPTION_WAS_THROWN, ex.Message), "Operation Failed", MessageType.ERROR); UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, "Failed to set the link preference"); } } /// /// Update the wireless details (link control, lan id ect.) /// /// /// internal void UpdateWirelessDetails(LinkControl linkControl, LinkControl linkPreference) { try { _UI.SetWirelessDetails(linkControl, linkPreference); } catch (UCTException ex) { _UI.SetPowerState(PowerState.Unknown); _UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR); WriteLog(LogLevel.DETAILED, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error); } catch (Exception ex) { _UI.SetPowerState(PowerState.Unknown); WriteLog(LogLevel.DETAILED, String.Format(Properties.Resources.EXCEPTION_WAS_THROWN, ex.Message), LogInteraction.Error); } } #endregion /// /// Set the default screens /// /// public void ChangeDefaultScreen(DefaultScreen screen) { try { UpdateGUIMessages(LogLevel.BASIC, "Settings the default monitor to: " + Utilities.GetEnumDescription(screen), LogInteraction.UserOperation, "Setting the default screen to: " + Utilities.GetEnumDescription(screen)); _targetSystem.SetDefaultMonitor(screen); _UI.DisplayStatusBar("Default screen was set successfully"); } catch (UCTException ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, "Failed to set the default screen"); _UI.DisplayMessage("Set default monitor failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } catch (Exception ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, "Failed to set the default screen"); _UI.DisplayMessage("Set default monitor failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } } /// /// Switch screens /// public void SetDefaultMonitor() { try { _targetSystem.SetDefaultMonitor(); _UI.DisplayStatusBar("Set default monitor completed successfully"); } catch (UCTException ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, "Failed to set the default monitor"); _UI.DisplayMessage("Set default monitor failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } catch (Exception ex) { UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite), LogInteraction.Error, "Failed to set the default monitor"); _UI.DisplayMessage("Set default monitor failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR); } } #endregion #endregion #region IUserConsentFlow Members public bool CheckIfConsentIsRequired() { if (_targetSystem.GetOptInPolicy() == OptInPolicy.NONE) { _UI.DisplayMessage(Properties.Resources.USER_CONSENT_NOT_REQUIRED, Properties.Resources.OPERATION_FAILED, MessageType.INFO); UpdateGUIMessages(LogLevel.DETAILED, Properties.Resources.USER_CONSNET_LOG_NOT_REQUIRED, LogInteraction.Information, "Consent is not required for any operation"); return false; } return true; } public bool CheckIfConsentAlreadyObtain() { // Get the User Consent state OptInState state = _targetSystem.GetOptInState(); // If state is In-Session - indicate the user and exit the flow if (state == OptInState.InSession) { _UI.DisplayMessage(Properties.Resources.USER_CONSENT_OPEN_SESSION, Properties.Resources.OPERATION_FAILED, MessageType.INFO); UpdateGUIMessages(LogLevel.DETAILED, "Consent was already obtained - a KVM or Redirection session is open", LogInteraction.Information, "Consent was already obtained"); return true; } // If state is Recieved - indicate the user that consent was already obtained and exit the flow if (state == OptInState.Received) { _UI.DisplayMessage(Properties.Resources.USER_CONSENT_ALREADY_OBTAINED, Properties.Resources.OPERATION_FAILED, MessageType.INFO); UpdateGUIMessages(LogLevel.DETAILED, Properties.Resources.USER_CONSENT_ALREADY_OBTAINED_LOG, LogInteraction.Information, "Consent was already obtained"); return true; } // Any other state (except "Not Started") - reset the flow using cancel operation if (state != OptInState.NotStarted) { UpdateGUIMessages(LogLevel.BASIC, "Reseting the User Consent state in order to start the consent process", LogInteraction.Information, Properties.Resources.RESETING_USER_CONSENT); // Cancel the consent flow uint result = _targetSystem.CancelConsent(); if (result != 0) { UpdateGUIMessages(LogLevel.DETAILED, string.Format(Properties.Resources.CANCEL_USER_CONSENT_FAILURE_ERROR_CODE, result), LogInteraction.Error, "Failed to reset the consent state"); } } return false; } public void PerformSxFlow() { if (!StartUserConsentProcess()) return; // Ask the user if he want the tool to reboot the system if (_UI.DisplayMessage("The target system is in Sx power state.\nA boot is needed in order to display the consent form.\nWould you like to boot the system?", Properties.Resources.BOOTING_SYSTEM_MESSAGE, MessageType.QUESTION) == DialogResult.Yes) { _UI.RefreshScreen(); // Check if meanwhile the state changed to display if (!EnsureRelevantState()) return; _UI.RefreshScreen(); // Perform power operation (graceful and force) PerformAMTShutDown(PowerState.On); } else { //Check if meanwhile the machine state changed to 'Display' (= the user woke up the machine) if (_targetSystem.GetOptInState() != OptInState.Displayed) { _UI.DisplayMessage("In order to complete the consent process, please turn-on the target system.\nYou can ask the user to perform it localy, or use the advanced tab operations to perform it remotely. ", "Information Message", MessageType.INFO); UpdateGUIMessages(LogLevel.DETAILED, "Power operation was aborted", LogInteraction.UserOperation, "Power operation was aborted."); } } } public bool StartUserConsentProcess() { // Start the consent process uint result = _targetSystem.StartConsent(); if (result != 0) { _UI.DisplayMessage("Start consent operation failed with error code: " + result + " - " + StatusCodes[result], Properties.Resources.STARTING_CONSNET_FAILED, MessageType.ERROR); UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.STARTING_USER_CONSENT_FAILED_ERROR_CODE, result.ToString()), LogInteraction.Error, "Start consent operation failed"); return false; } return true; } public void DetectingIfSpriteIsSupported() { UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.DETECTING_SPRITE_LOG_MESSAGE, LogInteraction.FWOperation, Properties.Resources.DETECTING_SPRITE_MESSAGE + "..."); _timer.Start(); _UI.stopProgress = false; _UI.RefreshScreen(); // Detecting if sprite is supported, that may take up to 15 seconds. // A timer is set to indicate this time had elapsed. DialogResult dialogResult = _UI.RunProgressBar(Properties.Resources.DETECTING_SPRITE_MESSAGE + " (may take up to 15 sec.)", Properties.Resources.DETECTING_SPRITE_MESSAGE, true, false); if (dialogResult != DialogResult.Cancel) { _timer.Stop(); _UI.stopProgress = _timer.Enabled = false; _UI.RefreshScreen(); // If user choose 'Skip' or 'cancel' at the Sprite detection progress bar - just stop the detection // the button of 'Skip' removed , so the 'cancel' behave as the 'skip' if (dialogResult == DialogResult.Abort || dialogResult == DialogResult.Ignore) { _userCancel = true; UpdateGUIMessages(LogLevel.DETAILED, "Detection if sprite is supported was caceled", LogInteraction.UserOperation, "Detection if sprite is supported was caceled"); return; } } if (!_timeHadElapsed) _userCancel = true; _UI.RefreshScreen(); while ((!_timeHadElapsed) && (!_spriteIsSupported) && (!_userCancel)) ; } public void ExecuteWirelessFlow() { // Check if AMT's wireless link is passive. // If true returned - indicate that control link = ME, just perform reboot if (!_targetSystem.CheckAMTWirelessLink()) { // Get the wireless profiles state WirelessProfilesState wirelessState = _targetSystem.GetWirelessProfilesState(); // Wireless profiles does not exist - indicate the user and stop the flow if (wirelessState == WirelessProfilesState.None) { if (_UI.DisplayWarningMessage("The target system does not have wireless profiles, flow cannot be executed.", "Wireless Flow Aborted", MessageBoxButtons.OK) == DialogResult.OK) { _UI.RefreshScreen(); CancelUserConsentProcess(); } UpdateGUIMessages(LogLevel.BASIC, "No wireless profile defined, Wireless flow aborted", LogInteraction.Error, "Wireless flow aborted"); return; } // Check if there is SSID match between AMT's profiles and host profile if (!_targetSystem.CheckConnectionBetweenProfiles()) { // The target system include only IT profiles, flow cannot be executed if (wirelessState == WirelessProfilesState.ITProfiles) { _UI.DisplayWarningMessage("The target system does not have user profiles defined, flow cannot be executed.", "Wireless Flow Aborted", MessageBoxButtons.OK); UpdateGUIMessages(LogLevel.BASIC, "No wireless profile defined, Wireless flow aborted", LogInteraction.Error, "Wireless flow aborted"); return; } // No match between profiles - indicate the user about the risk if (_UI.DisplayMessage("LANID doesn't match SSID and only user profiles exist, hence the flow may fail.\nDo you wish to continue?", "Wireless Flow", MessageType.QUESTION) == DialogResult.No) { // User don't want to continue the flow - abort UpdateGUIMessages(LogLevel.BASIC, "Wireless profile does not match, Wireless flow aborted", LogInteraction.Error, "Wireless flow aborted"); // Cancel the flow CancelUserConsentProcess(); return; } } DialogResult dResult; uint protectionLevel = _targetSystem.GetLinkProtectionLevel(); if (protectionLevel == 0) // Override { if ((dResult = _UI.DisplayWarningMessage("The Intel AMT system must be rebooted to display a user consent code.\n" + "To remain connected via a wireless connection during reboot,\n" + "link protection must be restored " + "\nSelect one of the following options:\n" + "Yes – Restore the link protection and reboot the system.\n" + "No – Restore the link protection and do NOT reboot the system.\n" + "Cancel – Cancel the user consent process (make no changes).", "Wireless Flow Notification", MessageBoxButtons.YesNoCancel)) == DialogResult.Cancel) { _UI.RefreshScreen(); // User choose to cancel the flow - exits the flow at this point, not setting the link preference and not boot UpdateGUIMessages(LogLevel.BASIC, "Consent flow was canceled by the user", LogInteraction.UserOperation, "Consent flow was canceled"); CancelUserConsentProcess(); return; } // Check if meanwhile the state changed to display if (!EnsureRelevantState()) return; _targetSystem.RestoreLinkProtection(); // No- indicates the user don't want to reboot the system, // so we just restored the link protection (for the case the user will use the discrete operation to reboot) if (dResult == DialogResult.No) { return; } else // Reboot the syetem { RebootSystem(LinkInterface.Wireless); } } else // None { // Notify the user about the link preference if ((dResult = _UI.DisplayWarningMessage("The Intel AMT system must be rebooted to display a user consent code.\n" + "To remain connected via a wireless connection during reboot,\n" + "control of network connections on the system must be passed to the Intel AMT Manageability Engine " + "(by changing the 'Link Preference' of the Intel AMT system to 'ME').\n" + "\nSelect one of the following options:\n" + "Yes – Set the link preference to ME and reboot the system.\n" + "No – Set the link preference to ME and do NOT reboot the system.\n" + "Cancel – Cancel the user consent process (make no changes).", "Wireless Flow Notification", MessageBoxButtons.YesNoCancel)) == DialogResult.Cancel) { _UI.RefreshScreen(); // User choose to cancel the flow - exits the flow at this point, not setting the link preference and not boot UpdateGUIMessages(LogLevel.BASIC, "Consent flow was canceled by the user", LogInteraction.UserOperation, "Consent flow was canceled"); CancelUserConsentProcess(); return; } // Check if meanwhile the state changed to display if (!EnsureRelevantState()) return; // No indicates the user don't want to reboot the system, // so we just set the link preference (for the case the user will use the discrete operation to reboot) if (dResult == DialogResult.No) { _targetSystem.StartLinkPreferenceThread(true); return; } RebootSystem(LinkInterface.Wireless); } } else // Reboot the syetem { if (_UI.DisplayMessage(Properties.Resources.SPRITE_NOT_AVAILIBLE_MESSAGE_BOX_MESSAGE, Properties.Resources.QUESTION_HEADER, MessageType.QUESTION) == DialogResult.Yes) { // Check if meanwhile the state changed to display if (!EnsureRelevantState()) return; RebootSystem(LinkInterface.Wireless); } } } public void ExecuteNonSpriteFlow() { // Check the system power state - because it needs to be s0 for this flow to continue. if (_targetSystem.GetPowerState() != PowerState.On) { UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.POWER_ON_MESSAGE, LogInteraction.Information, Properties.Resources.POWER_ON_MESSAGE); _UI.RefreshScreen(); if (_UI.DisplayMessage(Properties.Resources.POWER_ON_MESSAGE_BOX_MESSAGE + "\n\nNote that if you choose 'No', in order to complete the consent process, you have to boot the target system." + "\nYou can ask the user to perform it localy, or use the advanced tab operations to perform it remotely.", Properties.Resources.BOOTING_SYSTEM_MESSAGE, MessageType.QUESTION) == DialogResult.Yes) { // Check if meanwhile the state changed to display if (!EnsureRelevantState()) return; // Power on the system PerformAMTShutDown(PowerState.On); } } // System is on and needs to be re-booted else { // First try graceful shutdown - via OS, if failed try AMT reboot. if (_UI.DisplayMessage(Properties.Resources.SPRITE_NOT_AVAILIBLE_MESSAGE_BOX_MESSAGE, Properties.Resources.QUESTION_HEADER, MessageType.QUESTION) == DialogResult.Yes) { // Check if meanwhile the state changed to display if (!EnsureRelevantState()) return; RebootSystem(LinkInterface.Wired); } UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.MEBx_USER_CONSENT_MESSAGE, LogInteraction.Information, Properties.Resources.MEBx_USER_CONSENT_MESSAGE); } } public void RunFullFlow() { bool wasSxFlow = false; // Reseting all arguments to default _timeHadElapsed = _spriteIsSupported = _userCancel = false; _spriteCounter = 0; // Update log and status bar UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.STARTING_USER_CONSENT_LOG_MESSAGE, LogInteraction.UserOperation, Properties.Resources.STARTING_USER_CONSENT_PROGRESS_BAR_MESSAGE); // 1) Check if consent is required if (!CheckIfConsentIsRequired()) return; // 2) Check if consent was already obtained if (CheckIfConsentAlreadyObtain()) return; // 3) Check the system power state if (_targetSystem.GetPowerState() != PowerState.On) { PerformSxFlow(); wasSxFlow = true; } // 4) Start the consent process if(!wasSxFlow) if (!StartUserConsentProcess()) return; // 5) Detecting if sprite is supported DetectingIfSpriteIsSupported(); if (_userCancel == true) { if (_targetSystem.GetOptInState() == OptInState.Displayed) { UpdateGUIMessages(LogLevel.DETAILED, Properties.Resources.ASK_OPTIN_CODE_MESSAGE, LogInteraction.Information, Properties.Resources.ASK_OPTIN_CODE_MESSAGE); } return; } // 6) Check if sprite is not supported - if so, executing the non-sprite flow: // A reboot is needed to display form from MEbx. // But before, there is a need to check the connection interface, if the connection is over wireless // a SetLinkPreference command must be sent in order to for keep the connection. // For the case that the user press "Skip" but the state already changed to display, // we asking here again what the OptIn state is. if (_targetSystem.GetOptInState() != OptInState.Displayed) { if (_spriteIsSupported == false) { // Check if the connection is over wireless and the FW version is earlier than 8.1 (in later versions, the ling preference is automaticly taken care of) if (Configuration.InterfaceSettings.GetInstance().LinkInterface == LinkInterface.Wireless && !CheckLinkProtectionSupport()) { ExecuteWirelessFlow(); } else { ExecuteNonSpriteFlow(); } } } else { UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.ASK_OPTIN_CODE_MESSAGE, LogInteraction.Information, Properties.Resources.ASK_OPTIN_CODE_MESSAGE); } } public bool PerformGracefulShutdown() { return PerformGracefulShutdown(true, true, true); } public bool PerformAMTShutDown(PowerState state) { return PerformAMTShutDown(state, true, true); } public void SetGUIToConnect() { UpdateGUIMessages(LogLevel.BASIC, "Successfully Connected to: " + Configuration.GetInstance().Basic.AmtHost, LogInteraction.Connection, "Connected to the remote system"); } #endregion #region IDisposable Members public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (disposing) { _timerBoot.Elapsed -= new ElapsedEventHandler(timerBoot_Elapsed); _timerGraceful.Elapsed -= new ElapsedEventHandler(timerGraceful_Elapsed); _timer.Elapsed -= new ElapsedEventHandler(OnShortTimedEvent); _timer.Dispose(); _timerBoot.Dispose(); _timerGraceful.Dispose(); } } #endregion internal PowerState GetPowerState() { return _targetSystem.GetPowerState(); } } }