1317 lines
47 KiB
C#
1317 lines
47 KiB
C#
//----------------------------------------------------------------------------
|
||
//
|
||
// Copyright © 2009-2014, Intel Corporation. All rights reserved.
|
||
//
|
||
// File: TargetSystem.cs
|
||
//
|
||
//----------------------------------------------------------------------------
|
||
|
||
using System;
|
||
using UCT.Utils;
|
||
using System.Threading;
|
||
using System.ComponentModel;
|
||
using System.Collections.Generic;
|
||
using System.Runtime.InteropServices;
|
||
using Intel.Management.Wsman;
|
||
|
||
namespace UCT
|
||
{
|
||
#region - Enums -
|
||
|
||
/// <summary>
|
||
/// Indicate the wireless profile state.
|
||
/// Wireless has IT profiles or / and User profiles.
|
||
/// If user has no user profiles wireless flow cannot continue
|
||
/// </summary>
|
||
public enum WirelessProfilesState
|
||
{
|
||
/// <summary>
|
||
/// No profiles at all
|
||
/// </summary>
|
||
None,
|
||
|
||
/// <summary>
|
||
/// Just IT Profiles
|
||
/// </summary>
|
||
ITProfiles,
|
||
|
||
/// <summary>
|
||
/// Just user profiles
|
||
/// </summary>
|
||
UserProfiles,
|
||
|
||
/// <summary>
|
||
/// Both user and IT profiles
|
||
/// </summary>
|
||
BothITAndUserProfiles
|
||
}
|
||
|
||
/// <summary>
|
||
/// Link interface Wired/Wireless
|
||
/// </summary>
|
||
public enum LinkInterface
|
||
{
|
||
/// <summary>
|
||
/// no link interface detected
|
||
/// </summary>
|
||
None = 0,
|
||
/// <summary>
|
||
/// wired link interface
|
||
/// </summary>
|
||
Wired,
|
||
/// <summary>
|
||
/// wireless link interface
|
||
/// </summary>
|
||
Wireless
|
||
};
|
||
|
||
/// <summary>
|
||
/// Link control
|
||
/// </summary>
|
||
public enum LinkControl
|
||
{
|
||
/// <summary>
|
||
/// no link control detected
|
||
/// </summary>
|
||
None,
|
||
/// <summary>
|
||
/// ME control
|
||
/// </summary>
|
||
ME = 1,
|
||
/// <summary>
|
||
/// Host control
|
||
/// </summary>
|
||
Host = 2
|
||
};
|
||
|
||
public enum TimerStatus
|
||
{
|
||
/// <summary>
|
||
/// The timer is diable (00:00)
|
||
/// </summary>
|
||
DISABLE,
|
||
|
||
/// <summary>
|
||
/// The timer is freeze (stand on 14:59)
|
||
/// </summary>
|
||
FREEZE,
|
||
|
||
/// <summary>
|
||
/// Timer should start running
|
||
/// </summary>
|
||
RUN
|
||
}
|
||
|
||
public enum PowerState
|
||
{
|
||
[Description("Unknown")]
|
||
Unknown = 0,
|
||
|
||
[Description("Unknown")]
|
||
Other = 1,
|
||
|
||
[Description("On")]
|
||
On,
|
||
|
||
[Description("Sleep")]
|
||
LightSleep,
|
||
|
||
[Description("Sleep")]
|
||
DeepSleep,
|
||
|
||
[Description("Power Cycle")]
|
||
SoftPowerCycle,
|
||
|
||
[Description("Off")]
|
||
HardOff,
|
||
|
||
[Description("Hibernate")]
|
||
Hibernate,
|
||
|
||
[Description("Off")]
|
||
SoftOff,
|
||
|
||
[Description("Power Cycle")]
|
||
HardPowerCycle,
|
||
|
||
[Description("Reset")]
|
||
MasterBusReset,
|
||
|
||
[Description("Diagnostic Interrupt")]
|
||
DiagnosticInterrupt,
|
||
|
||
[Description("GracefulOff")]
|
||
GracefulOff,
|
||
|
||
[Description("GracefulReset")]
|
||
GracefulReset = 14
|
||
};
|
||
|
||
public enum DefaultScreen
|
||
{
|
||
[Description("PrimaryScreen")]
|
||
PrimaryScreen,
|
||
|
||
[Description("SecondaryScreen")]
|
||
SecondaryScreen,
|
||
|
||
[Description("ThirdScreen")]
|
||
ThirdScreen,
|
||
|
||
[Description("FourthScreen")]
|
||
FourthScreen,
|
||
|
||
[Description("FifthScreen")]
|
||
FifthScreen,
|
||
|
||
[Description("SixthScreen")]
|
||
SixthScreen,
|
||
};
|
||
|
||
public enum OptInPolicy : uint
|
||
{
|
||
NONE,
|
||
KVM,
|
||
ALL = UInt32.MaxValue
|
||
};
|
||
|
||
/// <summary>
|
||
/// Indicates the state of OptIn (User Consent)
|
||
/// </summary>
|
||
public enum OptInState : uint
|
||
{
|
||
[Description("Not Started")]
|
||
NotStarted,
|
||
|
||
/// <summary>
|
||
/// A console has required an optIn code, but it was not displayed to the user yet
|
||
/// </summary>
|
||
[Description("Requested")]
|
||
Requested,
|
||
|
||
/// <summary>
|
||
/// The optIn code was displayed to the user
|
||
/// </summary>
|
||
[Description("Displayed")]
|
||
Displayed,
|
||
|
||
/// <summary>
|
||
/// optIn code was successfully entered by the IT
|
||
/// </summary>
|
||
[Description("Received")]
|
||
Received,
|
||
|
||
/// <summary>
|
||
/// The console has an open session
|
||
/// </summary>
|
||
[Description("In Session")]
|
||
InSession,
|
||
|
||
/// <summary>
|
||
/// The optInState is unknown
|
||
/// </summary>
|
||
[Description("Unknown")]
|
||
Unknown
|
||
};
|
||
|
||
public enum MessageType
|
||
{
|
||
GENERAL,
|
||
INFO,
|
||
WARNING,
|
||
ERROR,
|
||
QUESTION
|
||
}
|
||
|
||
public enum EnabledState : ushort
|
||
{
|
||
[Description("Unknown")]
|
||
Unknown,
|
||
[Description("Other")]
|
||
Other,
|
||
[Description("Enabled")]
|
||
Enabled,
|
||
[Description("Disabled")]
|
||
Disabled,
|
||
[Description("Shutting Down")]
|
||
ShuttingDown,
|
||
[Description("Not Applicable")]
|
||
NotApplicable,
|
||
[Description("Enabled But Offline")]
|
||
EnabledButOffline,
|
||
[Description("In Test")]
|
||
InTest,
|
||
[Description("Deferred")]
|
||
Deferred,
|
||
[Description("Quiesce")]
|
||
Quiesce,
|
||
[Description("Starting")]
|
||
Starting,
|
||
[Description("Reserved")]
|
||
Reserved
|
||
};
|
||
|
||
/// <summary>
|
||
/// WS-Mangement status codes
|
||
/// </summary>
|
||
public enum WSMAN_KVM_STATUS_CODE
|
||
{
|
||
/// <summary>
|
||
/// the operation succeeded
|
||
/// </summary>
|
||
[Description("success")]
|
||
OK = 0,
|
||
/// <summary>
|
||
/// KVM Disabled in the MEBX
|
||
/// </summary>
|
||
[Description("KVM is Disabled in the MEBx")]
|
||
KVM_DISABLED_IN_MEBX,
|
||
/// <summary>
|
||
/// Failed to perform requested state change
|
||
/// </summary>
|
||
[Description("Failed to perform requested state change")]
|
||
KVM_REQUEST_STATE_CHANGE_FAILED,
|
||
/// <summary>
|
||
/// KVM general error
|
||
/// </summary>
|
||
[Description("KVM internal error")]
|
||
KVM_ERROR
|
||
};
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// Describe the target AMT system
|
||
/// </summary>
|
||
public class TargetSystem : IDisposable
|
||
{
|
||
#region - Extern Methods -
|
||
|
||
[DllImport("AdvAPI32.dll")]
|
||
private static extern bool InitiateSystemShutdown(string lpMachineName,
|
||
string lpMessage,
|
||
int dwTimeout,
|
||
bool bForceAppsClosed,
|
||
bool bRebootAfterShutdown);
|
||
#endregion
|
||
|
||
#region - Consts -
|
||
|
||
private const uint LinkTimeoutSeconds = 30;
|
||
private const string SupportOpInTimeOut = "6.2.0";
|
||
private const string Support3Displays = "8.0";
|
||
private const string SupportLinkProtection = "8.1.0";
|
||
#endregion
|
||
|
||
#region - Members -
|
||
|
||
private WsmanConnection _wsmanConnection;
|
||
private bool _requested = true;
|
||
private LogicLayer _logicLayer;
|
||
public ManualResetEvent _manualResetEvent = new ManualResetEvent(true);
|
||
public PowerOperations PowerOperation { set; get; }
|
||
public UCTOperations UctOperation { set; get; }
|
||
public WirelessOperations WirelessOperation { set; get; }
|
||
|
||
#endregion
|
||
|
||
#region - Constructor -
|
||
|
||
public TargetSystem(LogicLayer logicLayer)
|
||
{
|
||
_wsmanConnection = Configuration._wsmanConnection;
|
||
PowerOperation = new PowerOperations(this);
|
||
UctOperation = new UCTOperations(this);
|
||
WirelessOperation = new WirelessOperations(this);
|
||
_logicLayer = logicLayer;
|
||
UctOperation.OptInChangedEvent += new StateChanged_D(this.OptInChangedEvent);
|
||
PowerOperation.PowerStateChangedEvent += new PowerStateChanged_D(this.PowerStateChangedEvent);
|
||
WirelessOperation.WirelessLinkChangedEvent += new WirelessLinkChanged_D(_wirelessOperation_WirelessLinkChangedEvent);
|
||
PowerOperation.StartThread();
|
||
UctOperation.StartThread();
|
||
|
||
if (Configuration.InterfaceSettings.GetInstance().LinkInterface == LinkInterface.Wireless)
|
||
WirelessOperation.StartThread();
|
||
}
|
||
|
||
void _wirelessOperation_WirelessLinkChangedEvent()
|
||
{
|
||
_logicLayer.UpdateWirelessDetails(WirelessOperation.LinkControl, WirelessOperation.LinkPreference);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region - Methods -
|
||
|
||
#region - Public Functions -
|
||
|
||
public Dictionary<string, string> GetConnectionParameters()
|
||
{
|
||
try
|
||
{
|
||
_wsmanConnection = Configuration._wsmanConnection;
|
||
Dictionary<string, string> connectionParams = Merge<string, string>(PowerOperation.GetPowerParameters(), UctOperation.GetUCTParameters());
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Getting system properties.", LogInteraction.FWOperation);
|
||
|
||
// Add FW Version
|
||
IManagedReference softwareIdentityRef = _wsmanConnection.NewReference("SELECT * FROM CIM_SoftwareIdentity WHERE InstanceID='AMT FW Core Version'");
|
||
IManagedInstance softwareIdentityInstance = softwareIdentityRef.Get();
|
||
connectionParams.Add("CodeVersion", softwareIdentityInstance.GetProperty("VersionString").ToString());
|
||
|
||
// Add build number
|
||
softwareIdentityRef = _wsmanConnection.NewReference("SELECT * FROM CIM_SoftwareIdentity WHERE InstanceID='Build Number'");
|
||
softwareIdentityInstance = softwareIdentityRef.Get();
|
||
connectionParams.Add("VersionString", softwareIdentityInstance.GetProperty("VersionString").ToString());
|
||
|
||
// Add AMT host name property
|
||
IManagedReference generalSettingsRef = _wsmanConnection.NewReference("AMT_GeneralSettings");
|
||
IManagedInstance generalSettingsInstance = generalSettingsRef.Get();
|
||
|
||
connectionParams.Add("HostName", generalSettingsInstance.GetProperty("HostName").ToString());
|
||
|
||
return connectionParams;
|
||
}
|
||
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
public void PowerStateChangedEvent()
|
||
{
|
||
_logicLayer.UpdatePowerState(PowerOperation.PowerState);
|
||
}
|
||
|
||
public void OptInChangedEvent()
|
||
{
|
||
_logicLayer.UpdateOptInState(UctOperation.OptInState);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region - Private Functions -
|
||
|
||
private static Dictionary<TKEY, TValue> Merge<TKEY, TValue>(params Dictionary<TKEY, TValue>[] dictionaries)
|
||
{
|
||
Dictionary<TKEY, TValue> result = new Dictionary<TKEY, TValue>();
|
||
|
||
foreach (Dictionary<TKEY, TValue> dictionary in dictionaries)
|
||
|
||
foreach (KeyValuePair<TKEY, TValue> pair in dictionary)
|
||
|
||
result[pair.Key] = pair.Value;
|
||
|
||
return result;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region - Logic Functions -
|
||
|
||
/// <summary>
|
||
/// Set the OptIn state to its default value
|
||
/// </summary>
|
||
internal void SetDefaultOptInState()
|
||
{
|
||
if (null != UctOperation)
|
||
{
|
||
UctOperation.OptInState = OptInState.Unknown;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the power state to its default value
|
||
/// </summary>
|
||
internal void SetDefaultPowerState()
|
||
{
|
||
if (null != UctOperation)
|
||
PowerOperation.PowerState = PowerState.Unknown;
|
||
}
|
||
|
||
internal OptInPolicy GetOptInPolicy()
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED,
|
||
"Invoke IPS_OptInService.Get( OptInRequired property )", LogInteraction.FWOperation);
|
||
return (OptInPolicy)UctOperation.GetOptInPolicy();
|
||
|
||
}
|
||
|
||
internal OptInState GetOptInState()
|
||
{
|
||
return (OptInState)UctOperation.OptInState;
|
||
}
|
||
|
||
internal uint StartConsent()
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke IPS_OptInService.StartOptIn", LogInteraction.FWOperation);
|
||
return UctOperation.StartOptIn();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal uint SendCode(uint code)
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke IPS_OptInService.SendOptInCode( code = " + code + " )", LogInteraction.FWOperation);
|
||
|
||
return UctOperation.SendCode(code);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
|
||
}
|
||
|
||
internal uint CancelConsent()
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke IPS_OptInService.CancelOptIn", LogInteraction.FWOperation);
|
||
return UctOperation.CancelOptIn();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal void SetDefaultMonitor()
|
||
{
|
||
try
|
||
{
|
||
UctOperation.ChangeDefaultScreen();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal void SetDefaultMonitor(DefaultScreen screen)
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED,
|
||
"Invoke IPS_SecIOService.Put( DefaultScreen = " + Utilities.GetEnumDescription(screen) + " )", LogInteraction.FWOperation);
|
||
UctOperation.SetNewScreen((Byte)(screen));
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal void SetDefaultTimeout(ushort minutes)
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED,
|
||
"Invoke IPS_OptInService.Put( OptInDisplayTimeout = " + minutes.ToString() + " )", LogInteraction.FWOperation);
|
||
UctOperation.SetDefaultTimeout(minutes * 60);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal PowerState GetPowerState()
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED,
|
||
"Invoke CIM_PowerManagementService.Get()", LogInteraction.FWOperation);
|
||
|
||
return PowerOperation.PowerState;
|
||
}
|
||
|
||
internal uint ChangePowerState(PowerState powerState)
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED,
|
||
"Invoke CIM_PowerManagementService.RequestPowerStateChange( state = " + Utilities.GetEnumDescription(powerState) + " )", LogInteraction.FWOperation);
|
||
return PowerOperation.ChangePowerState(powerState);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal void SetOptInTimeout(uint time)
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED,
|
||
"Invoke IPS_OptInService.Put( OptInCodeTimeout = " + time + " )", LogInteraction.FWOperation);
|
||
UctOperation.SetOptInTimeout(time);
|
||
}
|
||
|
||
internal bool PerfomGracefulShutDown(bool reboot)
|
||
{
|
||
try
|
||
{
|
||
return PowerOperation.GreacfulShutDown(reboot);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.Message);
|
||
}
|
||
}
|
||
|
||
internal void StartPolling(bool connected)
|
||
{
|
||
UctOperation.connected = WirelessOperation.connected = PowerOperation.connected = connected;
|
||
|
||
if (connected && Configuration.InterfaceSettings.GetInstance().LinkInterface == LinkInterface.Wireless)
|
||
{
|
||
WirelessOperation.InitWirelessService();
|
||
WirelessOperation.StartThread();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region - Wireless Functions -
|
||
|
||
internal uint SetLinkPreference(LinkControl link, uint timeout)
|
||
{
|
||
try
|
||
{
|
||
return WirelessOperation.SetLinkPreference(link, timeout);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal bool CheckAMTWirelessLink()
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke AMT_EthernetPortSettings.Get( LinkControl property )", LogInteraction.FWOperation);
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke AMT_EthernetPortSettings.Get( LinkPreference property )", LogInteraction.FWOperation);
|
||
return WirelessOperation.CheckAMTWirelessLink();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal bool CheckConnectionBetweenProfiles()
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke CIM_WiFiEndpoint.Get( LANID property )", LogInteraction.FWOperation);
|
||
return WirelessOperation.CheckConnectionBetweenProfiles();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal WirelessProfilesState GetWirelessProfilesState()
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke CIM_WiFiEndpointSettings.Enumerate()", LogInteraction.FWOperation);
|
||
return WirelessOperation.GetWirelessProfilesState();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
internal uint GetLinkProtectionLevel()
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke AMT_EthernetPortSettings.Get()", LogInteraction.FWOperation);
|
||
return WirelessOperation.GetLinkProtectionLevel();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
throw new UCTException(e.InnerException.Message);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Start polling the optIn state and set re-set the link preference
|
||
/// </summary>
|
||
public void StartLinkPreferenceThread(bool start)
|
||
{
|
||
_requested = start;
|
||
if (start)
|
||
ThreadPool.QueueUserWorkItem(new WaitCallback(this.SetLinkPreference));
|
||
}
|
||
|
||
/// <summary>
|
||
/// Polling the machine state in order to check if SetLinkPreference is still needed
|
||
/// </summary>
|
||
/// <param name="stateinfo"></param>
|
||
private void SetLinkPreference(object stateInfo)
|
||
{
|
||
while (_requested)
|
||
{
|
||
if (UctOperation.OptInState == OptInState.Requested)
|
||
{
|
||
try
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke AMT_EthernetPortSettings.SetLinkPreference()", LogInteraction.FWOperation);
|
||
WirelessOperation.SetLinkPreference(LinkControl.ME, LinkTimeoutSeconds);
|
||
Thread.Sleep(20000);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
_requested = false;
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, e.Message, e.TargetSite.ToString()), LogInteraction.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_requested = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
internal uint RestoreLinkProtection()
|
||
{
|
||
_logicLayer.WriteLog(LogLevel.DETAILED, "Invoke AMT_EthernetPortSettings.RestoreLinkProtection()", LogInteraction.FWOperation);
|
||
return WirelessOperation.RestoreLinkProtection();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region - Inner Classes -
|
||
|
||
/// <summary>
|
||
/// Describe various power operations
|
||
/// </summary>
|
||
public class PowerOperations
|
||
{
|
||
#region MEMBERS
|
||
|
||
public event PowerStateChanged_D PowerStateChangedEvent;
|
||
public TargetSystem _parent;
|
||
public PowerState PowerState { set; get; }
|
||
public bool connected { set; private get; }
|
||
private IManagedReference associatedPowerManagementServiceRef;
|
||
private Mutex _powerMutex;
|
||
private IWsmanConnection _wsmanConnection;
|
||
private IManagedInstance associatedPowerManagementServiceInstance;
|
||
|
||
#endregion
|
||
|
||
#region CONSTRUCTOR
|
||
|
||
public PowerOperations(TargetSystem targetSystem)
|
||
{
|
||
_parent = targetSystem;
|
||
connected = true;
|
||
|
||
_wsmanConnection = Configuration._wsmanConnection;
|
||
associatedPowerManagementServiceRef = _wsmanConnection.NewReference("CIM_AssociatedPowerManagementService");
|
||
associatedPowerManagementServiceInstance = associatedPowerManagementServiceRef.Get();
|
||
|
||
_powerMutex = new Mutex();
|
||
PowerState = PowerState.Unknown;
|
||
}
|
||
|
||
public void StartThread()
|
||
{
|
||
ThreadPool.QueueUserWorkItem(new WaitCallback(this.GetPowerState));
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region METHODS
|
||
|
||
/// <summary>
|
||
/// Polling the power state
|
||
/// </summary>
|
||
/// <param name="stateinfo"></param>
|
||
public void GetPowerState(Object stateinfo)
|
||
{
|
||
uint counter = 0;
|
||
while (true)
|
||
{
|
||
if (connected)
|
||
{
|
||
_powerMutex.WaitOne();
|
||
try
|
||
{
|
||
_parent._manualResetEvent.WaitOne();
|
||
IManagedReference powerManagementServiceRef = _wsmanConnection.NewReference("CIM_AssociatedPowerManagementService");
|
||
associatedPowerManagementServiceInstance = powerManagementServiceRef.Get();
|
||
counter = (counter == 0) ? counter : counter--;
|
||
|
||
string realPowerStateStr = associatedPowerManagementServiceInstance.GetProperty("PowerState").ToString();
|
||
uint realPowerStateUint = Convert.ToUInt32(realPowerStateStr);
|
||
PowerState realPowerState = (PowerState)(realPowerStateUint);
|
||
|
||
if (PowerState != realPowerState)
|
||
{
|
||
PowerState s = realPowerState;
|
||
PowerState = s;
|
||
if (PowerStateChangedEvent != null)
|
||
{
|
||
PowerStateChangedEvent();
|
||
}
|
||
}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
if (++counter == 3)
|
||
{
|
||
PowerState = PowerState.Unknown;
|
||
counter = 0;
|
||
}
|
||
}
|
||
_powerMutex.ReleaseMutex();
|
||
|
||
Thread.Sleep(500);
|
||
}
|
||
Thread.Sleep(500);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Changing the machine power state (AMT force shutdown)
|
||
/// </summary>
|
||
/// <param name="state"></param>
|
||
public uint ChangePowerState(PowerState state)
|
||
{
|
||
IManagedReference powerManagementServiceRef = _wsmanConnection.NewReference("SELECT * FROM CIM_PowerManagementService WHERE Name='Intel(r) AMT Power Management Service'");
|
||
IManagedInstance powerManagementServiceInstance = powerManagementServiceRef.Get();
|
||
|
||
IManagedReference computerSystemRef = _wsmanConnection.NewReference("SELECT * FROM CIM_ComputerSystem WHERE Name='ManagedSystem'");
|
||
powerManagementServiceInstance = powerManagementServiceRef.CreateMethodInput("RequestPowerStateChange");
|
||
powerManagementServiceInstance.SetProperty("PowerState", (Convert.ToUInt32(state)).ToString());
|
||
powerManagementServiceInstance.SetProperty("ManagedElement", computerSystemRef);
|
||
|
||
powerManagementServiceInstance = powerManagementServiceRef.InvokeMethod(powerManagementServiceInstance);
|
||
uint response = uint.Parse(powerManagementServiceInstance.GetProperty("ReturnValue").ToString());
|
||
_parent._manualResetEvent.Reset();
|
||
Thread.Sleep(20000);
|
||
_parent._manualResetEvent.Set();
|
||
return response;
|
||
}
|
||
|
||
/// <summary>
|
||
/// ShutDown the machine gracefully
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool GreacfulShutDown(bool reboot)
|
||
{
|
||
LogManager.WriteOperation(LogLevel.DETAILED, "Attempting graceful shutdown", LogInteraction.FWOperation);
|
||
|
||
PowerState desired = reboot ? PowerState.GracefulReset : PowerState.GracefulOff;
|
||
uint result = ChangePowerState(desired);
|
||
|
||
return result == 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Return the advanced UserConsent properties
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public Dictionary<string, string> GetPowerParameters()
|
||
{
|
||
Dictionary<string, string> powerParams = new Dictionary<string, string>();
|
||
powerParams.Add("PowerState", Utilities.GetEnumDescription(((PowerState)(Convert.ToUInt32(associatedPowerManagementServiceInstance.GetProperty("PowerState").ToString())))));
|
||
return powerParams;
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
/// <summary>
|
||
/// Describe various user consent operations
|
||
/// </summary>
|
||
public class UCTOperations
|
||
{
|
||
#region MEMBERS
|
||
|
||
public event StateChanged_D OptInChangedEvent;
|
||
public bool connected { set; private get; }
|
||
public OptInState OptInState { set; get; }
|
||
public TargetSystem _parent;
|
||
private IWsmanConnection _wsmanConnection;
|
||
private IManagedReference optInServiceRef;
|
||
private IManagedReference secIOServiceRef;
|
||
private IManagedInstance optInServiceInstance;
|
||
private IManagedInstance secIOServiceInstance;
|
||
private Mutex _optInMutex;
|
||
|
||
#endregion
|
||
|
||
#region CONSTRUCTORS
|
||
|
||
public UCTOperations(TargetSystem targetSystem)
|
||
{
|
||
_parent = targetSystem;
|
||
connected = true;
|
||
|
||
_wsmanConnection = Configuration._wsmanConnection;
|
||
|
||
secIOServiceRef = _wsmanConnection.NewReference("SELECT * FROM IPS_SecIOService WHERE Name='SecIO'");
|
||
secIOServiceInstance = secIOServiceRef.Get();
|
||
|
||
optInServiceRef = _wsmanConnection.NewReference("SELECT * FROM IPS_OptInService WHERE Name='Intel(r) AMT OptIn Service'");
|
||
optInServiceInstance = optInServiceRef.Get();
|
||
|
||
OptInState = OptInState.Unknown;
|
||
_optInMutex = new Mutex();
|
||
}
|
||
|
||
public void StartThread()
|
||
{
|
||
ThreadPool.QueueUserWorkItem(new WaitCallback(this.GetOptInState));
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region METHODS
|
||
|
||
public uint CancelOptIn()
|
||
{
|
||
optInServiceInstance = optInServiceRef.CreateMethodInput("CancelOptIn");
|
||
optInServiceInstance = optInServiceRef.InvokeMethod(optInServiceInstance);
|
||
return uint.Parse(optInServiceInstance.GetProperty("ReturnValue").ToString());
|
||
}
|
||
|
||
public uint StartOptIn()
|
||
{
|
||
optInServiceInstance = optInServiceRef.CreateMethodInput("StartOptIn");
|
||
optInServiceInstance = optInServiceRef.InvokeMethod(optInServiceInstance);
|
||
return uint.Parse(optInServiceInstance.GetProperty("ReturnValue").ToString());
|
||
}
|
||
|
||
public void ChangeDefaultScreen(byte currentScreen)
|
||
{
|
||
byte newScreen;
|
||
if (Utilities.CompareVersions(GetCoreVersion(), "8.0") < 0)
|
||
{
|
||
newScreen = (currentScreen == (byte)DefaultScreen.PrimaryScreen) ? (byte)DefaultScreen.SecondaryScreen : (byte)DefaultScreen.PrimaryScreen;
|
||
}
|
||
else
|
||
{
|
||
newScreen = (byte)((currentScreen + 1) % GetNumberOfScreens());
|
||
}
|
||
SetNewScreen(newScreen);
|
||
}
|
||
|
||
public void SetNewScreen(byte newScreen)
|
||
{
|
||
secIOServiceInstance.SetProperty("DefaultScreen", newScreen.ToString());
|
||
secIOServiceRef.Put(secIOServiceInstance);
|
||
}
|
||
|
||
public uint SendCode(uint code)
|
||
{
|
||
optInServiceInstance = optInServiceRef.CreateMethodInput("SendOptInCode");
|
||
optInServiceInstance.SetProperty("OptInCode", code.ToString());
|
||
optInServiceInstance = optInServiceRef.InvokeMethod(optInServiceInstance);
|
||
return uint.Parse(optInServiceInstance.GetProperty("ReturnValue").ToString());
|
||
}
|
||
|
||
public Dictionary<string, string> GetUCTParameters()
|
||
{
|
||
optInServiceInstance = optInServiceRef.Get();
|
||
secIOServiceInstance = secIOServiceRef.Get();
|
||
|
||
Dictionary<string, string> UCTParams = new Dictionary<string, string>();
|
||
|
||
UCTParams.Add("DisplayTimeout", optInServiceInstance.GetProperty("OptInDisplayTimeout").ToString());
|
||
UCTParams.Add("CodeTimeout", optInServiceInstance.GetProperty("OptInCodeTimeout").ToString());
|
||
UCTParams.Add("OptInPolicy", Utilities.GetEnumDescription((OptInPolicy)(Convert.ToUInt32(optInServiceInstance.GetProperty("OptInRequired").ToString()))));
|
||
UCTParams.Add("OptInState", Utilities.GetEnumDescription((OptInState)(Convert.ToUInt32(optInServiceInstance.GetProperty("OptInState").ToString()))));
|
||
UCTParams.Add("DefaultMonitor", Utilities.GetEnumDescription((DefaultScreen)(Convert.ToUInt32(secIOServiceInstance.GetProperty("DefaultScreen").ToString()))));
|
||
|
||
return UCTParams;
|
||
}
|
||
|
||
public void GetOptInState(Object stateinfo)
|
||
{
|
||
uint counter = 0;
|
||
while (true)
|
||
{
|
||
if (connected)
|
||
{
|
||
_optInMutex.WaitOne();
|
||
try
|
||
{
|
||
_parent._manualResetEvent.WaitOne();
|
||
optInServiceInstance = optInServiceRef.Get();
|
||
counter = (counter == 0) ? counter : counter--;
|
||
|
||
if (OptInState != (OptInState)(Convert.ToUInt32(optInServiceInstance.GetProperty("OptInState").ToString())))
|
||
{
|
||
OptInState = (OptInState)Convert.ToUInt32(optInServiceInstance.GetProperty("OptInState").ToString());
|
||
if (OptInChangedEvent != null)
|
||
{
|
||
OptInChangedEvent();
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
if (++counter == 3 || ex.Message == "Unable to connect to the remote server")
|
||
{
|
||
OptInState = OptInState.Unknown;
|
||
counter = 0;
|
||
if (OptInChangedEvent != null)
|
||
{
|
||
OptInChangedEvent();
|
||
}
|
||
}
|
||
}
|
||
|
||
_optInMutex.ReleaseMutex();
|
||
|
||
Thread.Sleep(500);
|
||
}
|
||
Thread.Sleep(500);
|
||
}
|
||
}
|
||
|
||
public uint GetOptInState()
|
||
{
|
||
return Convert.ToUInt32(optInServiceInstance.GetProperty("OptInState").ToString());
|
||
}
|
||
|
||
public uint GetOptInPolicy()
|
||
{
|
||
return Convert.ToUInt32(optInServiceInstance.GetProperty("OptInRequired").ToString());
|
||
}
|
||
|
||
public uint GetOptInTimeout()
|
||
{
|
||
optInServiceInstance = optInServiceRef.Get();
|
||
return Convert.ToUInt32(optInServiceInstance.GetProperty("OptInCodeTimeout").ToString());
|
||
}
|
||
|
||
public bool CheckOptInTimeoutSupport()
|
||
{
|
||
return Utilities.CompareVersions(GetCoreVersion(), SupportOpInTimeOut) >= 0;
|
||
}
|
||
|
||
public bool CheckThirdScreenSupport()
|
||
{
|
||
return Utilities.CompareVersions(GetCoreVersion(), Support3Displays) >= 0;
|
||
}
|
||
|
||
internal void SetOptInTimeout(uint time)
|
||
{
|
||
optInServiceInstance.SetProperty("OptInCodeTimeout", time.ToString());
|
||
optInServiceRef.Put(optInServiceInstance);
|
||
}
|
||
|
||
internal void ChangeDefaultScreen()
|
||
{
|
||
DefaultScreen currentScreen = (DefaultScreen)Convert.ToUInt32(secIOServiceInstance.GetProperty("DefaultScreen").ToString());
|
||
ChangeDefaultScreen((Byte)currentScreen);
|
||
}
|
||
|
||
internal void SetDefaultTimeout(int minutes)
|
||
{
|
||
optInServiceInstance.SetProperty("OptInDisplayTimeout", (uint)minutes);
|
||
optInServiceRef.Put(optInServiceInstance);
|
||
}
|
||
|
||
private string GetCoreVersion()
|
||
{
|
||
IManagedReference softwareIdentityRef =
|
||
_wsmanConnection.NewReference("SELECT * FROM CIM_SoftwareIdentity WHERE InstanceID='AMT FW Core Version'");
|
||
IManagedInstance softwareIdentityInstance = softwareIdentityRef.Get();
|
||
return softwareIdentityInstance.GetProperty("VersionString").ToString();
|
||
}
|
||
|
||
private int GetNumberOfScreens()
|
||
{
|
||
IWsmanItem numberOfScreens= secIOServiceInstance.GetProperty("NumberOfScreens");
|
||
if (numberOfScreens.IsNull)// this property is available only in AMT Release 8.0 HF1 and later.
|
||
{
|
||
return Utilities.CompareVersions(GetCoreVersion(),"8.0" )< 0 ? 2 : 3;
|
||
}
|
||
return Int32.Parse(numberOfScreens.ToString());
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
/// <summary>
|
||
/// Describe the wireless operation
|
||
/// (used to set the link preference when the connection interface is wireless and
|
||
/// machine does not support sprite)
|
||
/// </summary>
|
||
public class WirelessOperations
|
||
{
|
||
#region Consts
|
||
|
||
private const string InstanceIDUser = "WiFi Endpoint User Settings";
|
||
|
||
#endregion
|
||
|
||
#region Members
|
||
|
||
public event WirelessLinkChanged_D WirelessLinkChangedEvent;
|
||
public TargetSystem _parent;
|
||
public bool connected { set; private get; }
|
||
public LinkControl LinkControl { private set; get; }
|
||
public LinkControl LinkPreference { private set; get; }
|
||
|
||
private Mutex _wirelessMutex;
|
||
IWsmanConnection _wsmanConnection;
|
||
IManagedInstance _ethernetPortService;
|
||
IManagedReference _ethernetPortEPR;
|
||
private bool _changed = false;
|
||
|
||
#endregion
|
||
|
||
#region Constructors
|
||
|
||
public WirelessOperations(TargetSystem targetSystem)
|
||
{
|
||
_parent = targetSystem;
|
||
_wsmanConnection = Configuration._wsmanConnection;
|
||
_wirelessMutex = new Mutex();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Methods
|
||
|
||
public bool InitWirelessService()
|
||
{
|
||
if (Configuration.InterfaceSettings.GetInstance().LinkInterface == LinkInterface.Wireless)
|
||
{
|
||
_ethernetPortEPR = Configuration.InterfaceSettings.GetInstance().EthernetPortServiceEPR;
|
||
_ethernetPortService = _ethernetPortEPR.Get();
|
||
|
||
LinkPreference = LinkControl.None;
|
||
LinkControl = LinkControl.None;
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
public void StartThread()
|
||
{
|
||
ThreadPool.QueueUserWorkItem(new WaitCallback(GetWirelessLinkState));
|
||
}
|
||
|
||
/// <summary>
|
||
/// Check if AMT’s wireless link is active or passive
|
||
/// </summary>
|
||
/// <returns>true - wireless link is active, false - the link is passive</returns>
|
||
public bool CheckAMTWirelessLink()
|
||
{
|
||
// If LinkProtection is supported and wasn't overrieded, no need to notify the user about LinkPreference, the switch between the links will be automatically.
|
||
if (CheckLinkProtectionSupport())
|
||
return true;
|
||
_ethernetPortService = _ethernetPortEPR.Get();
|
||
return (LinkControl)Convert.ToUInt32(_ethernetPortService.GetProperty("LinkControl").ToString()) == LinkControl.ME &&
|
||
(LinkControl)Convert.ToUInt32(_ethernetPortService.GetProperty("LinkPreference").ToString()) == LinkControl.ME;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Check if AMT is connected to one of its defined profiles
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool CheckConnectionBetweenProfiles()
|
||
{
|
||
return !String.IsNullOrEmpty(Configuration.InterfaceSettings.GetInstance().LanID);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the Link Preference
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public uint SetLinkPreference(LinkControl link, UInt32 timeout)
|
||
{
|
||
_ethernetPortService = _ethernetPortEPR.CreateMethodInput("SetLinkPreference");
|
||
_ethernetPortService.SetProperty("LinkPreference", (Convert.ToUInt16(link)).ToString());
|
||
_ethernetPortService.SetProperty("Timeout", timeout.ToString());
|
||
_ethernetPortService = _ethernetPortEPR.InvokeMethod(_ethernetPortService);
|
||
return Convert.ToUInt32(_ethernetPortService.GetProperty("ReturnValue").ToString());
|
||
}
|
||
|
||
/// <summary>
|
||
/// Return the wireless profiles state
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public WirelessProfilesState GetWirelessProfilesState()
|
||
{
|
||
// Count the number of user and admin profiles instances
|
||
int AdminProfiles = 0, UserProfiles = 0;
|
||
|
||
IManagedReference wiFiEndpointSettingsRef = _wsmanConnection.NewReference("CIM_WiFiEndpointSettings");
|
||
IWsmanEnumeration wiFiEndpointSettingsCollection = wiFiEndpointSettingsRef.Enumerate("http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter", null);
|
||
|
||
// No profiles exist.
|
||
if(!wiFiEndpointSettingsCollection.HasNext)
|
||
return WirelessProfilesState.None;
|
||
|
||
// Go over the instances and count the user and admin instances
|
||
foreach (IWsmanItem wiFiEndpointSettingsItem in wiFiEndpointSettingsCollection)
|
||
{
|
||
IManagedInstance wiFiEndpointSettingsObject = wiFiEndpointSettingsItem.Object;
|
||
// The difference between user profiles and admin profiles is that the user profiles
|
||
// don't have SSID property. (name is the only property the user profiles has)
|
||
string instanceID = wiFiEndpointSettingsObject.GetProperty("InstanceID").ToString();
|
||
if (instanceID.Contains(InstanceIDUser))
|
||
UserProfiles++;
|
||
else AdminProfiles++;
|
||
}
|
||
// No admin profiles - indicate there are only user profiles
|
||
if (AdminProfiles == 0)
|
||
return WirelessProfilesState.UserProfiles;
|
||
// No user profiles - indicate there are only admin profiles
|
||
return UserProfiles == 0 ? WirelessProfilesState.ITProfiles : WirelessProfilesState.BothITAndUserProfiles;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Polling the wireless properties
|
||
/// </summary>
|
||
/// <param name="stateinfo"></param>
|
||
public void GetWirelessLinkState(Object stateinfo)
|
||
{
|
||
uint counter = 0;
|
||
while (true)
|
||
{
|
||
_changed = false;
|
||
if (connected)
|
||
{
|
||
_wirelessMutex.WaitOne();
|
||
try
|
||
{
|
||
_parent._manualResetEvent.WaitOne();
|
||
_ethernetPortService = _ethernetPortEPR.Get();
|
||
counter = (counter == 0) ? counter : counter--;
|
||
|
||
if (LinkControl != (LinkControl)Convert.ToUInt32(_ethernetPortService.GetProperty("LinkControl").ToString()))
|
||
{
|
||
LinkControl = (LinkControl)Convert.ToUInt32(_ethernetPortService.GetProperty("LinkControl").ToString());
|
||
_changed = true;
|
||
|
||
}
|
||
if (LinkPreference != (LinkControl)Convert.ToUInt32(_ethernetPortService.GetProperty("LinkPreference").ToString()))
|
||
{
|
||
LinkPreference = (LinkControl)Convert.ToUInt32(_ethernetPortService.GetProperty("LinkPreference").ToString());
|
||
_changed = true;
|
||
}
|
||
if (_changed)
|
||
{
|
||
if (WirelessLinkChangedEvent != null)
|
||
{
|
||
WirelessLinkChangedEvent();
|
||
}
|
||
}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
if (++counter == 3)
|
||
{
|
||
LinkControl = LinkControl.None;
|
||
LinkPreference = LinkControl.None;
|
||
counter = 0;
|
||
}
|
||
}
|
||
_wirelessMutex.ReleaseMutex();
|
||
}
|
||
Thread.Sleep(80000);
|
||
}
|
||
}
|
||
|
||
internal bool CheckLinkProtectionSupport()
|
||
{
|
||
if (Utilities.CompareVersions(SupportLinkProtection, GetCoreVersion()) > 0)// version earlier than 8.1
|
||
return false;
|
||
uint linkProtectionLevel = GetLinkProtectionLevel();
|
||
if (linkProtectionLevel != 2)// Not Passive.
|
||
return false;
|
||
return true;
|
||
}
|
||
|
||
internal uint GetLinkProtectionLevel()
|
||
{
|
||
const string NOT_EXIST_EXCEPTION = "No route can be determined to reach the destination role defined by the WSAddressing To.";
|
||
const string ETHERNET_PORT_INSTANCE_ID = "Intel(r) AMT Ethernet Port Settings 1";
|
||
if (Utilities.CompareVersions(SupportLinkProtection, GetCoreVersion()) > 0)// version earlier than 8.1
|
||
return 1;// none
|
||
if(_ethernetPortEPR == null)
|
||
_ethernetPortEPR =
|
||
_wsmanConnection.NewReference("SELECT * FROM AMT_EthernetPortSettings WHERE InstanceID='" + ETHERNET_PORT_INSTANCE_ID + "'");
|
||
try
|
||
{
|
||
_ethernetPortService = _ethernetPortEPR.Get();
|
||
if (_ethernetPortService == null)
|
||
return 1;// Wired connection, return 1 (none).
|
||
IWsmanItem linkProtectionLevel = _ethernetPortService.GetProperty("WLANLinkProtectionLevel");
|
||
return uint.Parse(linkProtectionLevel.ToString());//override, none or passive
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
if(ex.Message.Contains(NOT_EXIST_EXCEPTION))
|
||
return 1;// Wired connection, return 1 (none).
|
||
throw;
|
||
}
|
||
|
||
}
|
||
|
||
internal uint RestoreLinkProtection()
|
||
{
|
||
_ethernetPortService = _ethernetPortEPR.CreateMethodInput("RestoreLinkProtection");
|
||
_ethernetPortService = _ethernetPortEPR.InvokeMethod(_ethernetPortService);
|
||
return Convert.ToUInt32(_ethernetPortService.GetProperty("ReturnValue").ToString());
|
||
}
|
||
#endregion
|
||
|
||
#region Private Methods
|
||
|
||
private string GetCoreVersion()
|
||
{
|
||
IManagedReference softwareIdentityRef =
|
||
_wsmanConnection.NewReference("SELECT * FROM CIM_SoftwareIdentity WHERE InstanceID='AMT FW Core Version'");
|
||
IManagedInstance softwareIdentityInstance = softwareIdentityRef.Get();
|
||
return softwareIdentityInstance.GetProperty("VersionString").ToString();
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region IDisposable Members
|
||
|
||
public void Dispose()
|
||
{
|
||
Dispose(true);
|
||
GC.SuppressFinalize(this);
|
||
}
|
||
|
||
private void Dispose(bool disposing)
|
||
{
|
||
if (disposing)
|
||
{
|
||
UctOperation.OptInChangedEvent -= new StateChanged_D(this.OptInChangedEvent);
|
||
PowerOperation.PowerStateChangedEvent -= new PowerStateChanged_D(this.PowerStateChangedEvent);
|
||
WirelessOperation.WirelessLinkChangedEvent -= new WirelessLinkChanged_D(_wirelessOperation_WirelessLinkChangedEvent);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
}
|
||
} |