File: managementoptions.cs
Project: ndp\fx\src\wmi\managed\System\Management\System.Management.csproj (System.Management)
using System;
using System.Diagnostics;
using System.Text;
using System.Collections;
using System.ComponentModel;
using System.Security;
 
using System.Security.Cryptography;
using WbemClient_v1;
 
 
namespace System.Management
{
    /// <summary>
    ///    <para>Describes the authentication level to be used to connect to WMI. This is used for the COM connection to WMI.</para>
    /// </summary>
    public enum AuthenticationLevel 
    { 
        /// <summary>
        ///    <para>The default COM authentication level. WMI uses the default Windows Authentication setting.</para>
        /// </summary>
        Default=0, 
        /// <summary>
        ///    <para> No COM authentication.</para>
        /// </summary>
        None=1, 
        /// <summary>
        ///    <para> Connect-level COM authentication.</para>
        /// </summary>
        Connect=2, 
        /// <summary>
        ///    <para> Call-level COM authentication.</para>
        /// </summary>
        Call=3, 
        /// <summary>
        ///    <para> Packet-level COM authentication.</para>
        /// </summary>
        Packet=4,
        /// <summary>
        ///    <para>Packet Integrity-level COM authentication.</para>
        /// </summary>
        PacketIntegrity=5,
        /// <summary>
        ///    <para>Packet Privacy-level COM authentication.</para>
        /// </summary>
        PacketPrivacy=6,
        /// <summary>
        ///    <para>The default COM authentication level. WMI uses the default Windows Authentication setting.</para>
        /// </summary>
        Unchanged=-1
    }
 
    /// <summary>
    ///    <para>Describes the impersonation level to be used to connect to WMI.</para>
    /// </summary>
    public enum ImpersonationLevel 
    { 
        /// <summary>
        ///    <para>Default impersonation.</para>
        /// </summary>
        Default=0,
        /// <summary>
        ///    <para> Anonymous COM impersonation level that hides the 
        ///       identity of the caller. Calls to WMI may fail
        ///       with this impersonation level.</para>
        /// </summary>
        Anonymous=1, 
        /// <summary>
        ///    <para> Identify-level COM impersonation level that allows objects 
        ///       to query the credentials of the caller. Calls to
        ///       WMI may fail with this impersonation level.</para>
        /// </summary>
        Identify=2, 
        /// <summary>
        ///    <para> Impersonate-level COM impersonation level that allows 
        ///       objects to use the credentials of the caller. This is the recommended impersonation level for WMI calls.</para>
        /// </summary>
        Impersonate=3, 
        /// <summary>
        ///    <para> Delegate-level COM impersonation level that allows objects
        ///       to permit other objects to use the credentials of the caller. This
        ///       level, which will work with WMI calls but may constitute an unnecessary
        ///       security risk, is supported only under Windows 2000.</para>
        /// </summary>
        Delegate=4 
    }
    
    /// <summary>
    ///    <para>Describes the possible effects of saving an object to WMI when 
    ///       using <see cref='System.Management.ManagementObject.Put'/>.</para>
    /// </summary>
    public enum PutType 
    { 
        /// <summary>
        ///    <para> Invalid Type </para>
        /// </summary>
        None = 0,
        /// <summary>
        ///    <para> Updates an existing object
        ///       only; does not create a new object.</para>
        /// </summary>
        UpdateOnly=1, 
        /// <summary>
        ///    <para> Creates an object only;
        ///       does not update an existing object.</para>
        /// </summary>
        CreateOnly=2, 
        /// <summary>
        ///    <para> Saves the object, whether
        ///       updating an existing object or creating a new object.</para>
        /// </summary>
        UpdateOrCreate=3 
    }
 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//    
    /// <summary>
    ///    <para> 
    ///       Provides an abstract base class for all Options objects.</para>
    ///    <para>Options objects are used to customize different management operations. </para>
    ///    <para>Use one of the Options classes derived from this class, as 
    ///       indicated by the signature of the operation being performed.</para>
    /// </summary>
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    [TypeConverter(typeof(ExpandableObjectConverter))]
    abstract public class ManagementOptions : ICloneable
    {
        /// <summary>
        ///    <para> Specifies an infinite timeout.</para>
        /// </summary>
        public static readonly TimeSpan InfiniteTimeout = TimeSpan.MaxValue;
 
        internal int flags;
        internal ManagementNamedValueCollection context;
        internal TimeSpan timeout;
 
        //Used when any public property on this object is changed, to signal
        //to the containing object that it needs to be refreshed.
        internal event IdentifierChangedEventHandler IdentifierChanged;
 
        //Fires IdentifierChanged event
        internal void FireIdentifierChanged()
        {
            if (IdentifierChanged != null)
                IdentifierChanged(this, null);
        }
 
        //Called when IdentifierChanged() event fires
        internal void HandleIdentifierChange(object sender,
                            IdentifierChangedEventArgs args)
        {
            //Something inside ManagementOptions changed, we need to fire an event
            //to the parent object
            FireIdentifierChanged();
        }
        
        internal int Flags {
            get { return flags; }
            set { flags = value; }
        }
 
        /// <summary>
        ///    <para> Gets or sets a WMI context object. This is a
        ///       name-value pairs list to be passed through to a WMI provider that supports
        ///       context information for customized operation.</para>
        /// </summary>
        /// <value>
        ///    <para>A name-value pairs list to be passed through to a WMI provider that
        ///       supports context information for customized operation.</para>
        /// </value>
        public ManagementNamedValueCollection Context 
        {
            get
            {
                if (context == null)
                    return context = new ManagementNamedValueCollection();
                else
                    return context;
            }
            set
            {
                ManagementNamedValueCollection oldContext = context;
 
                if (null != value)
                    context = (ManagementNamedValueCollection) value.Clone();
                else
                    context = new ManagementNamedValueCollection ();
 
                if (null != oldContext)
                    oldContext.IdentifierChanged -= new IdentifierChangedEventHandler(HandleIdentifierChange);
 
                //register for change events in this object
                context.IdentifierChanged += new IdentifierChangedEventHandler(HandleIdentifierChange);
 
                //the context property has changed so act like we fired the event
                HandleIdentifierChange(this,null);
            }
        }
 
        /// <summary>
        ///    <para>Gets or sets the timeout to apply to the operation. 
        ///       Note that for operations that return collections, this timeout applies to the
        ///       enumeration through the resulting collection, not the operation itself
        ///       (the <see cref='System.Management.EnumerationOptions.ReturnImmediately'/>
        ///       property is used for the latter).</para>
        ///    This property is used to indicate that the operation should be performed semisynchronously.
        /// </summary>
        /// <value>
        /// <para>The default value for this property is <see cref='System.Management.ManagementOptions.InfiniteTimeout'/> 
        /// , which means the operation will block.
        /// The value specified must be positive.</para>
        /// </value>
        public TimeSpan Timeout 
        {
            get 
            { return timeout; }
            set 
            { 
                //Timespan allows for negative values, but we want to make sure it's positive here...
                if (value.Ticks < 0)
                    throw new ArgumentOutOfRangeException("value");
 
                timeout = value;
                FireIdentifierChanged();
            }
        }
 
 
        internal ManagementOptions() : this(null, InfiniteTimeout) {}
        internal ManagementOptions(ManagementNamedValueCollection context, TimeSpan timeout) : this(context, timeout, 0) {}
        internal ManagementOptions(ManagementNamedValueCollection context, TimeSpan timeout, int flags)
        {
            this.flags = flags;
            if (context != null)
                this.Context = context;
            else
                this.context = null;
            this.Timeout = timeout;
        }
 
 
        internal IWbemContext GetContext () {
            if (context != null)
                return context.GetContext();
            else
                return null;
        }
        
        // We do not expose this publicly; instead the flag is set automatically
        // when making an async call if we detect that someone has requested to
        // listen for status messages.
        internal bool SendStatus 
        {
            get 
            { return (((Flags & (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_SEND_STATUS) != 0) ? true : false); }
            set 
            {
                Flags = (value == false) ? (Flags & (int)~tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_SEND_STATUS) : 
                    (Flags | (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_SEND_STATUS);
            }
        }
 
        /// <summary>
        ///    <para> Returns a copy of the object.</para>
        /// </summary>
        /// <returns>
        ///    <para>The cloned object.</para>
        /// </returns>
        public abstract object Clone();
    }
 
 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//    
    /// <summary>
    ///    <para>Provides a base class for query and enumeration-related options
    ///       objects.</para>
    ///    <para>Use this class to customize enumeration of management 
    ///       objects, traverse management object relationships, or query for
    ///       management objects.</para>
    /// </summary>
    /// <example>
    ///    <code lang='C#'>using System;
    /// using System.Management;
    /// 
    /// // This example demonstrates how to enumerate all top-level WMI classes
    /// // and subclasses in root/cimv2 namespace.
    /// class Sample_EnumerationOptions
    /// {
    ///     public static int Main(string[] args) {
    ///         ManagementClass newClass = new ManagementClass();
    ///         EnumerationOptions options = new EnumerationOptions();
    ///         options.EnumerateDeep = false;
    ///         foreach(ManagementObject o in newClass.GetSubclasses(options)) {
    ///             Console.WriteLine(o["__Class"]);
    ///         }
    ///         return 0;
    ///     }
    /// }
    ///    </code>
    ///    <code lang='VB'>Imports System
    /// Imports System.Management
    /// 
    /// ' This example demonstrates how to enumerate all top-level WMI classes
    /// ' and subclasses in root/cimv2 namespace.
    /// Class Sample_EnumerationOptions
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    ///         Dim newClass As New ManagementClass()
    ///         Dim options As New EnumerationOptions()
    ///         options.EnumerateDeep = False
    ///         Dim o As ManagementObject
    ///         For Each o In newClass.GetSubclasses(options)
    ///             Console.WriteLine(o("__Class"))
    ///         Next o
    ///         Return 0
    ///     End Function
    /// End Class
    ///    </code>
    /// </example>
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    public class EnumerationOptions : ManagementOptions
    {
        private int blockSize;
 
        /// <summary>
        ///    <para>Gets or sets a value indicating whether the invoked operation should be 
        ///       performed in a synchronous or semisynchronous fashion. If this property is set
        ///       to <see langword='true'/>, the enumeration is invoked and the call returns immediately. The actual
        ///       retrieval of the results will occur when the resulting collection is walked.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if the invoked operation should 
        ///    be performed in a synchronous or semisynchronous fashion; otherwise,
        /// <see langword='false'/>. The default value is <see langword='true'/>.</para>
        /// </value>
        public bool ReturnImmediately 
        {
            get { return (((Flags & (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_RETURN_IMMEDIATELY) != 0) ? true : false); }
            set {
                Flags = (value == false) ? (Flags & (int)~tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_RETURN_IMMEDIATELY) : 
                            (Flags | (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_RETURN_IMMEDIATELY);
            }
        }
 
        /// <summary>
        ///    <para> Gets or sets the block size
        ///       for block operations. When enumerating through a collection, WMI will return results in
        ///       groups of the specified size.</para>
        /// </summary>
        /// <value>
        ///    <para>The default value is 1.</para>
        /// </value>
        public int BlockSize 
        {
            get { return blockSize; }
            set { 
                //Unfortunately BlockSize was defined as int, but valid values are only  > 0
                if (value <= 0)
                    throw new ArgumentOutOfRangeException("value");
 
                blockSize = value;
            }
        }
 
        /// <summary>
        ///    <para>Gets or sets a value indicating whether the collection is assumed to be 
        ///       rewindable. If <see langword='true'/>, the objects in the
        ///       collection will be kept available for multiple enumerations. If
        ///    <see langword='false'/>, the collection
        ///       can only be enumerated one time.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if the collection is assumed to 
        ///    be rewindable; otherwise, <see langword='false'/>. The default value is
        /// <see langword='true'/>.</para>
        /// </value>
        /// <remarks>
        ///    <para>A rewindable collection is more costly in memory
        ///       consumption as all the objects need to be kept available at the same time.
        ///       In a collection defined as non-rewindable, the objects are discarded after being returned
        ///       in the enumeration.</para>
        /// </remarks>
        public bool Rewindable 
        {
            get { return (((Flags & (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_FORWARD_ONLY) != 0) ? false : true); }
            set { 
                Flags = (value == true) ? (Flags & (int)~tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_FORWARD_ONLY) : 
                                            (Flags | (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_FORWARD_ONLY);
            }
        }    
 
        /// <summary>
        ///    <para> Gets or sets a value indicating whether the objects returned from
        ///       WMI should contain amended information. Typically, amended information is localizable
        ///       information attached to the WMI object, such as object and property
        ///       descriptions.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if the objects returned from WMI 
        ///    should contain amended information; otherwise, <see langword='false'/>. The
        ///    default value is <see langword='false'/>.</para>
        /// </value>
        /// <remarks>
        ///    <para>If descriptions and other amended information are not of 
        ///       interest, setting this property to <see langword='false'/>
        ///       is more
        ///       efficient.</para>
        /// </remarks>
        public bool UseAmendedQualifiers 
        {
            get { return (((Flags & (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_USE_AMENDED_QUALIFIERS) != 0) ? true : false); }
            set { 
                Flags = (value == true) ? (Flags | (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_USE_AMENDED_QUALIFIERS) :
                                            (Flags & (int)~tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_USE_AMENDED_QUALIFIERS); 
            }
        }
 
        /// <summary>
        ///    <para>Gets or sets a value indicating whether to the objects returned should have
        ///       locatable information in them. This ensures that the system properties, such as
        ///    <see langword='__PATH'/>, <see langword='__RELPATH'/>, and 
        ///    <see langword='__SERVER'/>, are non-NULL. This flag can only be used in queries,
        ///       and is ignored in enumerations.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if WMI 
        ///    should ensure all returned objects have valid paths; otherwise,
        /// <see langword='false'/>. The default value is <see langword='false'/>.</para>
        /// </value>
        public bool EnsureLocatable 
        {
            get 
            { return (((Flags & (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_ENSURE_LOCATABLE) != 0) ? true : false); }
            set 
            { Flags = (value == true) ? (Flags | (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_ENSURE_LOCATABLE) :
                      (Flags & (int)~tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_ENSURE_LOCATABLE) ; }
        }
 
 
        /// <summary>
        ///    <para>Gets or sets a value indicating whether the query should return a
        ///       prototype of the result set instead of the actual results. This flag is used for
        ///       prototyping.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if the 
        ///    query should return a prototype of the result set instead of the actual results;
        ///    otherwise, <see langword='false'/>. The default value is
        /// <see langword='false'/>.</para>
        /// </value>
        public bool PrototypeOnly 
        {
            get 
            { return (((Flags & (int)tag_WBEM_QUERY_FLAG_TYPE.WBEM_FLAG_PROTOTYPE) != 0) ? true : false); }
            set 
            { Flags = (value == true) ? (Flags | (int)tag_WBEM_QUERY_FLAG_TYPE.WBEM_FLAG_PROTOTYPE) :
                      (Flags & (int)~tag_WBEM_QUERY_FLAG_TYPE.WBEM_FLAG_PROTOTYPE) ; }
        }
 
        /// <summary>
        ///    <para> Gets or sets a value indicating whether direct access to the WMI provider is requested for the specified class,
        ///       without any regard to its base class or derived classes.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if only 
        ///    objects of the specified class should be received, without regard to derivation
        ///    or inheritance; otherwise, <see langword='false'/>. The default value is
        /// <see langword='false'/>. </para>
        /// </value>
        public bool DirectRead 
        {
            get 
            { return (((Flags & (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_DIRECT_READ) != 0) ? true : false); }
            set 
            { Flags = (value == true) ? (Flags | (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_DIRECT_READ) :
                      (Flags & (int)~tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_DIRECT_READ) ; }
        }
 
        
        /// <summary>
        ///    <para> Gets or sets a value indicating whether recursive enumeration is requested 
        ///       into all classes derived from the specified base class. If
        ///    <see langword='false'/>, only immediate derived
        ///       class members are returned.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if recursive enumeration is requested 
        ///    into all classes derived from the specified base class; otherwise,
        /// <see langword='false'/>. The default value is <see langword='false'/>.</para>
        /// </value>
        public bool EnumerateDeep 
        {
            get 
            { return (((Flags & (int)tag_WBEM_QUERY_FLAG_TYPE.WBEM_FLAG_SHALLOW) != 0) ? false : true); }
            set 
            { Flags = (value == false) ? (Flags | (int)tag_WBEM_QUERY_FLAG_TYPE.WBEM_FLAG_SHALLOW) :
                      (Flags & (int)~tag_WBEM_QUERY_FLAG_TYPE.WBEM_FLAG_SHALLOW); }
        }
 
        
        //default constructor
        /// <overload>
        ///    Initializes a new instance
        ///    of the <see cref='System.Management.EnumerationOptions'/> class.
        /// </overload>
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.EnumerationOptions'/>
        /// class with default values (see the individual property descriptions
        /// for what the default values are). This is the default constructor. </para>
        /// </summary>
        public EnumerationOptions() : this (null, InfiniteTimeout, 1, true, true, false, false, false, false, false) {}
        
 
        
        //Constructor that specifies flags as individual values - we need to set the flags acordingly !
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.EnumerationOptions'/> class to be used for queries or enumerations, 
        ///    allowing the user to specify values for the different options.</para>
        /// </summary>
        /// <param name='context'>The options context object containing provider-specific information that can be passed through to the provider.</param>
        /// <param name=' timeout'>The timeout value for enumerating through the results.</param>
        /// <param name=' blockSize'>The number of items to retrieve at one time from WMI.</param>
        /// <param name=' rewindable'><see langword='true'/> to specify whether the result set is rewindable (=allows multiple traversal or one-time); otherwise, <see langword='false'/>.</param>
        /// <param name=' returnImmediatley'><see langword='true'/> to specify whether the operation should return immediately (semi-sync) or block until all results are available; otherwise, <see langword='false'/> .</param>
        /// <param name=' useAmendedQualifiers'><see langword='true'/> to specify whether the returned objects should contain amended (locale-aware) qualifiers; otherwise, <see langword='false'/> .</param>
        /// <param name=' ensureLocatable'><see langword='true'/> to specify to WMI that it should ensure all returned objects have valid paths; otherwise, <see langword='false'/> .</param>
        /// <param name=' prototypeOnly'><see langword='true'/> to return a prototype of the result set instead of the actual results; otherwise, <see langword='false'/> .</param>
        /// <param name=' directRead'><see langword='true'/> to to retrieve objects of only the specified class only or from derived classes as well; otherwise, <see langword='false'/> .</param>
        /// <param name=' enumerateDeep'><see langword='true'/> to specify recursive enumeration in subclasses; otherwise, <see langword='false'/> .</param>
        public EnumerationOptions(
            ManagementNamedValueCollection context, 
            TimeSpan timeout, 
            int blockSize,
            bool rewindable,
            bool returnImmediatley,
            bool useAmendedQualifiers,
            bool ensureLocatable,
            bool prototypeOnly,
            bool directRead,
            bool enumerateDeep) : base(context, timeout)
        {
            BlockSize = blockSize;
            Rewindable = rewindable;
            ReturnImmediately = returnImmediatley;
            UseAmendedQualifiers = useAmendedQualifiers;
            EnsureLocatable = ensureLocatable;
            PrototypeOnly = prototypeOnly;
            DirectRead = directRead;
            EnumerateDeep = enumerateDeep;
        }
 
        /// <summary>
        ///    <para> Returns a copy of the object.</para>
        /// </summary>
        /// <returns>
        ///    <para>The cloned object.</para>
        /// </returns>
        public override object Clone ()
        {
            ManagementNamedValueCollection newContext = null;
 
            if (null != Context)
                newContext = (ManagementNamedValueCollection)Context.Clone();
 
            return new EnumerationOptions (newContext, Timeout, blockSize, Rewindable,
                            ReturnImmediately, UseAmendedQualifiers, EnsureLocatable, PrototypeOnly, DirectRead, EnumerateDeep);
        }
        
    }//EnumerationOptions
 
 
 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//    
    /// <summary>
    ///    <para> Specifies options for management event watching.</para>
    ///    <para>Use this class to customize subscriptions for watching management events. </para>
    /// </summary>
    /// <example>
    ///    <code lang='C#'>using System; 
    /// using System.Management; 
    /// 
    /// // This example demonstrates how to listen to an event using ManagementEventWatcher object. 
    /// class Sample_EventWatcherOptions 
    /// { 
    ///     public static int Main(string[] args) {
    ///         ManagementClass newClass = new ManagementClass(); 
    ///         newClass["__CLASS"] = "TestDeletionClass"; 
    ///         newClass.Put(); 
    ///         
    ///         EventWatcherOptions options = new EventWatcherOptions(); 
    ///         ManagementEventWatcher watcher = new ManagementEventWatcher(null, 
    ///                                                                     new WqlEventQuery("__classdeletionevent"), 
    ///                                                                     options); 
    ///         MyHandler handler = new MyHandler(); 
    ///         watcher.EventArrived += new EventArrivedEventHandler(handler.Arrived); 
    ///         watcher.Start(); 
    /// 
    ///         // Delete class to trigger event
    ///         newClass.Delete(); 
    /// 
    ///         //For the purpose of this example, we will wait
    ///         // two seconds before main thread terminates.
    ///         System.Threading.Thread.Sleep(2000); 
    /// 
    ///         watcher.Stop(); 
    /// 
    ///         return 0;
    ///     } 
    /// 
    ///     public class MyHandler
    ///     {
    ///        public void Arrived(object sender, EventArrivedEventArgs e) {
    ///            Console.WriteLine("Class Deleted= " +
    ///                ((ManagementBaseObject)e.NewEvent["TargetClass"])["__CLASS"]);
    ///        } 
    ///     }
    /// }
    ///    </code>
    ///    <code lang='VB'>Imports System
    /// Imports System.Management
    /// 
    /// ' This example demonstrates how to listen to an event using the ManagementEventWatcher object. 
    /// Class Sample_EventWatcherOptions
    ///     Public Shared Sub Main() 
    ///         Dim newClass As New ManagementClass() 
    ///         newClass("__CLASS") = "TestDeletionClass"
    ///         newClass.Put()
    ///     
    ///         Dim options As _
    ///             New EventWatcherOptions()
    ///         Dim watcher As New ManagementEventWatcher( _
    ///             Nothing, _
    ///             New WqlEventQuery("__classdeletionevent"), _
    ///             options)
    ///         Dim handler As New MyHandler()
    ///         AddHandler watcher.EventArrived, AddressOf handler.Arrived
    ///         watcher.Start()
    ///       
    ///         ' Delete class to trigger event
    ///         newClass.Delete()
    ///       
    ///         ' For the purpose of this example, we will wait
    ///         ' two seconds before main thread terminates.
    ///         System.Threading.Thread.Sleep(2000)
    ///         watcher.Stop()
    ///     End Sub
    ///      
    ///     Public Class MyHandler
    ///         Public Sub Arrived(sender As Object, e As EventArrivedEventArgs)
    ///             Console.WriteLine("Class Deleted = " &amp; _
    ///                 CType(e.NewEvent("TargetClass"), ManagementBaseObject)("__CLASS"))
    ///         End Sub
    ///     End Class
    /// End Class
    ///    </code>
    /// </example>
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    public class EventWatcherOptions : ManagementOptions
    {
        private int blockSize = 1;
        
        /// <summary>
        ///    <para>Gets or sets the block size for block operations. When waiting for events, this
        ///       value specifies how many events to wait for before returning.</para>
        /// </summary>
        /// <value>
        ///    <para>The default value is 1.</para>
        /// </value>
        public int BlockSize 
        {
            get { return blockSize; }
            set 
            { 
                blockSize = value; 
                FireIdentifierChanged ();
            }
 
        }
 
        /// <overload>
        /// <para>Initializes a new instance of the <see cref='System.Management.EventWatcherOptions'/> class. </para>
        /// </overload>
        /// <summary>
        /// <para> Initializes a new instance of the <see cref='System.Management.EventWatcherOptions'/> class for event watching, using default values.
        ///    This is the default constructor.</para>
        /// </summary>
        public EventWatcherOptions() 
            : this (null, InfiniteTimeout, 1) {}
 
        /// <summary>
        /// <para> Initializes a new instance of the <see cref='System.Management.EventWatcherOptions'/> class with the given
        ///    values.</para>
        /// </summary>
        /// <param name='context'>The options context object containing provider-specific information to be passed through to the provider. </param>
        /// <param name=' timeout'>The timeout to wait for the next events.</param>
        /// <param name=' blockSize'>The number of events to wait for in each block.</param>
        public EventWatcherOptions(ManagementNamedValueCollection context, TimeSpan timeout, int blockSize) 
            : base(context, timeout) 
        {
            Flags = (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_RETURN_IMMEDIATELY|(int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_FORWARD_ONLY;
            BlockSize = blockSize;
        }
 
        /// <summary>
        ///    <para> Returns a copy of the object.</para>
        /// </summary>
        /// <returns>
        ///    The cloned object.
        /// </returns>
        public override object Clone () 
        {
            ManagementNamedValueCollection newContext = null;
 
            if (null != Context)
                newContext = (ManagementNamedValueCollection)Context.Clone();
 
            return new EventWatcherOptions (newContext, Timeout, blockSize);
        }
    }//EventWatcherOptions
 
 
 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//    
    /// <summary>
    ///    <para> Specifies options for getting a management object.</para>
    ///    Use this class to customize retrieval of a management object.
    /// </summary>
    /// <example>
    ///    <code lang='C#'>using System;
    /// using System.Management;
    /// 
    /// // This example demonstrates how to set a timeout value and list
    /// // all amended qualifiers in a ManagementClass object.
    /// class Sample_ObjectGetOptions
    /// {
    ///     public static int Main(string[] args) {
    ///         // Request amended qualifiers
    ///         ObjectGetOptions options =
    ///             new ObjectGetOptions(null, new TimeSpan(0,0,0,5), true);
    ///         ManagementClass diskClass =
    ///             new ManagementClass("root/cimv2", "Win32_Process", options);
    ///         foreach(QualifierData qualifier in diskClass.Qualifiers) {
    ///             Console.WriteLine(qualifier.Name + ":" + qualifier.Value);
    ///         }
    ///         return 0;
    ///     }
    /// }
    ///    </code>
    ///    <code lang='VB'>Imports System
    /// Imports System.Management
    /// 
    /// ' This example demonstrates how to set a timeout value and list
    /// ' all amended qualifiers in a ManagementClass object.
    /// Class Sample_ObjectGetOptions
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    ///         ' Request amended qualifiers
    ///         Dim options As _
    ///             New ObjectGetOptions(Nothing, New TimeSpan(0, 0, 0, 5), True)
    ///         Dim diskClass As New ManagementClass( _
    ///             "root/cimv2", _
    ///             "Win32_Process", _
    ///             options)
    ///         Dim qualifier As QualifierData
    ///         For Each qualifier In diskClass.Qualifiers
    ///             Console.WriteLine(qualifier.Name &amp; ":" &amp; qualifier.Value)
    ///         Next qualifier
    ///         Return 0
    ///     End Function
    /// End Class
    ///    </code>
    /// </example>
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    public class ObjectGetOptions : ManagementOptions
    {
        internal static ObjectGetOptions _Clone(ObjectGetOptions options)
        {
            return ObjectGetOptions._Clone(options, null);
        }
 
        internal static ObjectGetOptions _Clone(ObjectGetOptions options, IdentifierChangedEventHandler handler)
        {
            ObjectGetOptions optionsTmp;
            
            if (options != null)
                optionsTmp = new ObjectGetOptions(options.context, options.timeout, options.UseAmendedQualifiers);
            else
                optionsTmp = new ObjectGetOptions();
 
            // Wire up change handler chain. Use supplied handler, if specified;
            // otherwise, default to that of the path argument.
            if (handler != null)
                optionsTmp.IdentifierChanged += handler;
            else if (options != null)
                optionsTmp.IdentifierChanged += new IdentifierChangedEventHandler(options.HandleIdentifierChange);
 
            return optionsTmp;
        }
 
        /// <summary>
        ///    <para> Gets or sets a value indicating whether the objects returned from WMI should
        ///       contain amended information. Typically, amended information is localizable information
        ///       attached to the WMI object, such as object and property descriptions.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if the objects returned from WMI 
        ///    should contain amended information; otherwise, <see langword='false'/>. The
        ///    default value is <see langword='false'/>.</para>
        /// </value>
        public bool UseAmendedQualifiers 
        {
            get { return (((Flags & (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_USE_AMENDED_QUALIFIERS) != 0) ? true : false); }
            set { 
                Flags = (value == true) ? (Flags | (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_USE_AMENDED_QUALIFIERS) :
                                            (Flags & (int)~tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_USE_AMENDED_QUALIFIERS); 
                FireIdentifierChanged();
            }
        }
 
        /// <overload>
        /// <para>Initializes a new instance of the <see cref='System.Management.ObjectGetOptions'/> class.</para>
        /// </overload>
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.ObjectGetOptions'/> class for getting a WMI object, using
        ///    default values. This is the default constructor.</para>
        /// </summary>
        public ObjectGetOptions() : this(null, InfiniteTimeout, false) {}
 
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.ObjectGetOptions'/> class for getting a WMI object, using the
        ///    specified provider-specific context.</para>
        /// </summary>
        /// <param name='context'>A provider-specific, named-value pairs context object to be passed through to the provider.</param>
        public ObjectGetOptions(ManagementNamedValueCollection context) : this(context, InfiniteTimeout, false) {}
 
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.ObjectGetOptions'/> class for getting a WMI object,
        ///    using the given options values.</para>
        /// </summary>
        /// <param name='context'>A provider-specific, named-value pairs context object to be passed through to the provider.</param>
        /// <param name=' timeout'>The length of time to let the operation perform before it times out. The default is <see cref='System.Management.ManagementOptions.InfiniteTimeout'/> .</param>
        /// <param name=' useAmendedQualifiers'><see langword='true'/> if the returned objects should contain amended (locale-aware) qualifiers; otherwise, <see langword='false'/>. </param>
        public ObjectGetOptions(ManagementNamedValueCollection context, TimeSpan timeout, bool useAmendedQualifiers) : base(context, timeout)
        {
            UseAmendedQualifiers = useAmendedQualifiers;
        }
 
        /// <summary>
        ///    <para> Returns a copy of the object.</para>
        /// </summary>
        /// <returns>
        ///    <para>The cloned object.</para>
        /// </returns>
        public override object Clone () 
        {
            ManagementNamedValueCollection newContext = null;
 
            if (null != Context)
                newContext = (ManagementNamedValueCollection)Context.Clone();
 
            return new ObjectGetOptions (newContext, Timeout, UseAmendedQualifiers);
        }
    }
 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//    
    /// <summary>
    ///    <para> Specifies options for committing management
    ///       object changes.</para>
    ///    <para>Use this class to customize how values are saved to a management object.</para>
    /// </summary>
    /// <example>
    ///    <code lang='C#'>using System; 
    /// using System.Management; 
    /// 
    /// // This example demonstrates how to specify a PutOptions using 
    /// // PutOptions object when saving a ManagementClass object to 
    /// // the WMI respository. 
    /// class Sample_PutOptions 
    /// {
    ///     public static int Main(string[] args) { 
    ///         ManagementClass newClass = new ManagementClass("root/default",
    ///                                                        String.Empty,
    ///                                                        null); 
    ///         newClass["__Class"] = "class999xc";
    /// 
    ///         PutOptions options = new PutOptions(); 
    ///         options.Type = PutType.UpdateOnly;
    /// 
    ///         try
    ///         {
    ///             newClass.Put(options); //will fail if the class doesn't already exist
    ///         }
    ///         catch (ManagementException e)
    ///         {
    ///             Console.WriteLine("Couldn't update class: " + e.ErrorCode);
    ///         }
    ///         return 0;
    ///     }
    /// }
    ///    </code>
    ///    <code lang='VB'>Imports System
    /// Imports System.Management
    /// 
    /// ' This example demonstrates how to specify a PutOptions using
    /// ' PutOptions object when saving a ManagementClass object to
    /// ' WMI respository.
    /// Class Sample_PutOptions
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    ///         Dim newClass As New ManagementClass( _
    ///            "root/default", _
    ///            String.Empty, _
    ///            Nothing)
    ///         newClass("__Class") = "class999xc"
    /// 
    ///         Dim options As New PutOptions()
    ///         options.Type = PutType.UpdateOnly 'will fail if the class doesn't already exist
    /// 
    ///         Try
    ///             newClass.Put(options)
    ///         Catch e As ManagementException
    ///             Console.WriteLine("Couldn't update class: " &amp; e.ErrorCode)
    ///         End Try
    ///         Return 0
    ///     End Function
    /// End Class
    ///    </code>
    /// </example>
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    public class PutOptions : ManagementOptions
    {
 
        /// <summary>
        ///    <para> Gets or sets a value indicating whether the objects returned from WMI should
        ///       contain amended information. Typically, amended information is localizable information
        ///       attached to the WMI object, such as object and property descriptions.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if the objects returned from WMI 
        ///    should contain amended information; otherwise, <see langword='false'/>. The
        ///    default value is <see langword='false'/>.</para>
        /// </value>
        public bool UseAmendedQualifiers 
        {
            get { return (((Flags & (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_USE_AMENDED_QUALIFIERS) != 0) ? true : false); }
            set { Flags = (value == true) ? (Flags | (int)tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_USE_AMENDED_QUALIFIERS) :
                                            (Flags & (int)~tag_WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_USE_AMENDED_QUALIFIERS); }
        }
 
        /// <summary>
        ///    <para>Gets or sets the type of commit to be performed for the object.</para>
        /// </summary>
        /// <value>
        /// <para>The default value is <see cref='System.Management.PutType.UpdateOrCreate'/>.</para>
        /// </value>
        public PutType Type 
        {
            get { return (((Flags & (int)tag_WBEM_CHANGE_FLAG_TYPE.WBEM_FLAG_UPDATE_ONLY) != 0) ? PutType.UpdateOnly :
                          ((Flags & (int)tag_WBEM_CHANGE_FLAG_TYPE.WBEM_FLAG_CREATE_ONLY) != 0) ? PutType.CreateOnly : 
                                                                                PutType.UpdateOrCreate);
            }
            set { 
                switch (value)
                {
                    case PutType.UpdateOnly : Flags |= (int)tag_WBEM_CHANGE_FLAG_TYPE.WBEM_FLAG_UPDATE_ONLY; break;
                    case PutType.CreateOnly : Flags |= (int)tag_WBEM_CHANGE_FLAG_TYPE.WBEM_FLAG_CREATE_ONLY; break;
                    case PutType.UpdateOrCreate : Flags |= (int)tag_WBEM_CHANGE_FLAG_TYPE.WBEM_FLAG_CREATE_OR_UPDATE; break;
                    default : throw new ArgumentException(null, "Type");
                }
            }
        }
 
        /// <overload>
        /// <para> Initializes a new instance of the <see cref='System.Management.PutOptions'/> class.</para>
        /// </overload>
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.PutOptions'/> class for put operations, using default values.
        ///    This is the default constructor.</para>
        /// </summary>
        public PutOptions() : this(null, InfiniteTimeout, false, PutType.UpdateOrCreate) {}
 
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.PutOptions'/> class for committing a WMI object, using the
        ///    specified provider-specific context.</para>
        /// </summary>
        /// <param name='context'>A provider-specific, named-value pairs context object to be passed through to the provider.</param>
        public PutOptions(ManagementNamedValueCollection context) : this(context, InfiniteTimeout, false, PutType.UpdateOrCreate) {}
 
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.PutOptions'/> class for committing a WMI object, using
        ///    the specified option values.</para>
        /// </summary>
        /// <param name='context'>A provider-specific, named-value pairs object to be passed through to the provider. </param>
        /// <param name=' timeout'>The length of time to let the operation perform before it times out. The default is <see cref='System.Management.ManagementOptions.InfiniteTimeout'/> .</param>
        /// <param name=' useAmendedQualifiers'><see langword='true'/> if the returned objects should contain amended (locale-aware) qualifiers; otherwise, <see langword='false'/>. </param>
        /// <param name=' putType'> The type of commit to be performed (update or create).</param>
        public PutOptions(ManagementNamedValueCollection context, TimeSpan timeout, bool useAmendedQualifiers, PutType putType) : base(context, timeout)
        {
            UseAmendedQualifiers = useAmendedQualifiers;
            Type = putType;
        }
 
        /// <summary>
        ///    <para> Returns a copy of the object.</para>
        /// </summary>
        /// <returns>
        ///    <para>The cloned object.</para>
        /// </returns>
        public override object Clone () 
        {
            ManagementNamedValueCollection newContext = null;
 
            if (null != Context)
                newContext = (ManagementNamedValueCollection)Context.Clone();
 
            return new PutOptions (newContext, Timeout, UseAmendedQualifiers, Type);
        }
    }
 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//    
    /// <summary>
    ///    <para> Specifies options for deleting a management
    ///       object.</para>
    /// </summary>
    /// <example>
    ///    <code lang='C#'>using System;
    /// using System.Management;
    /// 
    /// // This example demonstrates how to specify a timeout value
    /// // when deleting a ManagementClass object.
    /// class Sample_DeleteOptions
    /// {
    ///     public static int Main(string[] args) {
    ///         ManagementClass newClass = new ManagementClass();
    ///         newClass["__CLASS"] = "ClassToDelete";
    ///         newClass.Put();
    ///    
    ///         // Set deletion options: delete operation timeout value
    ///         DeleteOptions opt = new DeleteOptions(null, new TimeSpan(0,0,0,5));
    ///         
    ///         ManagementClass dummyClassToDelete =
    ///             new ManagementClass("ClassToDelete");
    ///         dummyClassToDelete.Delete(opt);
    /// 
    ///         return 0;
    ///     }
    /// }
    ///    </code>
    ///    <code lang='VB'>Imports System
    /// Imports System.Management
    /// 
    /// ' This sample demonstrates how to specify a timeout value
    /// ' when deleting a ManagementClass object.
    /// Class Sample_DeleteOptions
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    ///         Dim newClass As New ManagementClass()
    ///         newClass("__CLASS") = "ClassToDelete"
    ///         newClass.Put()
    /// 
    ///         ' Set deletion options: delete operation timeout value
    ///         Dim opt As New DeleteOptions(Nothing, New TimeSpan(0, 0, 0, 5))
    ///         
    ///         Dim dummyClassToDelete As New ManagementClass("ClassToDelete")
    ///         dummyClassToDelete.Delete(opt)
    ///         Return 0
    ///     End Function
    /// End Class
    ///    </code>
    /// </example>
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    public class DeleteOptions : ManagementOptions
    {
        /// <overload>
        /// <para>Initializes a new instance of the <see cref='System.Management.DeleteOptions'/> class.</para>
        /// </overload>
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.DeleteOptions'/> class for the delete operation, using default values.
        ///    This is the default constructor.</para>
        /// </summary>
        public DeleteOptions() : base () {}
 
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.DeleteOptions'/> class for a delete operation, using
        ///    the specified values.</para>
        /// </summary>
        /// <param name='context'>A provider-specific, named-value pairs object to be passed through to the provider. </param>
        /// <param name='timeout'>The length of time to let the operation perform before it times out. The default value is <see cref='System.Management.ManagementOptions.InfiniteTimeout'/> . Setting this parameter will invoke the operation semisynchronously.</param>
        public DeleteOptions(ManagementNamedValueCollection context, TimeSpan timeout) : base(context, timeout) {}
 
        /// <summary>
        ///    <para> Returns a copy of the object.</para>
        /// </summary>
        /// <returns>
        ///    <para>A cloned object.</para>
        /// </returns>
        public override object Clone () 
        {
            ManagementNamedValueCollection newContext = null;
 
            if (null != Context)
                newContext = (ManagementNamedValueCollection)Context.Clone();
 
            return new DeleteOptions (newContext, Timeout);
        }
    }
 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//    
    /// <summary>
    ///    <para> Specifies options for invoking a management method.</para>
    ///    <para>Use this class to customize the execution of a method on a management 
    ///       object.</para>
    /// </summary>
    /// <example>
    ///    <code lang='C#'>using System; 
    /// using System.Management; 
    /// 
    /// // This example demonstrates how to stop a system service. 
    /// class Sample_InvokeMethodOptions 
    /// { 
    ///     public static int Main(string[] args) {
    ///         ManagementObject service = 
    ///             new ManagementObject("win32_service=\"winmgmt\"");
    ///         InvokeMethodOptions options = new InvokeMethodOptions();
    ///         options.Timeout = new TimeSpan(0,0,0,5); 
    /// 
    ///         ManagementBaseObject outParams = service.InvokeMethod("StopService", null, options);
    /// 
    ///         Console.WriteLine("Return Status = " + outParams["ReturnValue"]);
    /// 
    ///         return 0;
    ///     }
    /// }
    ///    </code>
    ///    <code lang='VB'>Imports System
    /// Imports System.Management
    /// 
    /// ' This sample demonstrates how to stop a system service.
    /// Class Sample_InvokeMethodOptions
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    ///         Dim service As New ManagementObject("win32_service=""winmgmt""")
    ///         Dim options As New InvokeMethodOptions()
    ///         options.Timeout = New TimeSpan(0, 0, 0, 5)
    ///         
    ///         Dim outParams As ManagementBaseObject = service.InvokeMethod( _
    ///             "StopService", _
    ///             Nothing, _
    ///             options)
    /// 
    ///         Console.WriteLine("Return Status = " &amp; _
    ///             outParams("ReturnValue").ToString())
    ///       
    ///         Return 0
    ///     End Function
    /// End Class
    ///    </code>
    /// </example>
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    public class InvokeMethodOptions : ManagementOptions
    {
        /// <overload>
        /// <para>Initializes a new instance of the <see cref='System.Management.InvokeMethodOptions'/> class.</para>
        /// </overload>
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.InvokeMethodOptions'/> class for the <see cref='System.Management.ManagementObject.InvokeMethod'/> operation, using default values.
        ///    This is the default constructor.</para>
        /// </summary>
        public InvokeMethodOptions() : base () {}
 
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.InvokeMethodOptions'/> class for an invoke operation using 
        ///    the specified values.</para>
        /// </summary>
        /// <param name=' context'>A provider-specific, named-value pairs object to be passed through to the provider. </param>
        /// <param name='timeout'>The length of time to let the operation perform before it times out. The default value is <see cref='System.Management.ManagementOptions.InfiniteTimeout'/> . Setting this parameter will invoke the operation semisynchronously.</param>
        public InvokeMethodOptions(ManagementNamedValueCollection context, TimeSpan timeout) : base(context, timeout) {}
 
        /// <summary>
        ///    <para> Returns a copy of the object.</para>
        /// </summary>
        /// <returns>
        ///    <para>The cloned object.</para>
        /// </returns>
        public override object Clone () 
        {
            ManagementNamedValueCollection newContext = null;
 
            if (null != Context)
                newContext = (ManagementNamedValueCollection)Context.Clone();
 
            return new InvokeMethodOptions (newContext, Timeout);
        }
    }
 
 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//    
    /// <summary>
    ///    <para> Specifies all settings required to make a WMI connection.</para>
    ///    <para>Use this class to customize a connection to WMI made via a 
    ///       ManagementScope object.</para>
    /// </summary>
    /// <example>
    ///    <code lang='C#'>using System;
    /// using System.Management;
    /// 
    /// // This example demonstrates how to connect to remote machine
    /// // using supplied credentials.
    /// class Sample_ConnectionOptions
    /// {
    ///     public static int Main(string[] args) {
    ///         ConnectionOptions options = new ConnectionOptions();
    ///         options.Username = "domain\\username";
    ///         options.Password = "password";
    ///         ManagementScope scope = new ManagementScope(
    ///             "\\\\servername\\root\\cimv2",
    ///             options);
    ///         try {
    ///             scope.Connect();
    ///             ManagementObject disk = new ManagementObject(
    ///                 scope,
    ///                 new ManagementPath("Win32_logicaldisk='c:'"),
    ///                 null);
    ///             disk.Get();
    ///         }
    ///         catch (Exception e) {
    ///             Console.WriteLine("Failed to connect: " + e.Message);
    ///         }
    ///         return 0;
    ///     }
    /// }
    ///    </code>
    ///    <code lang='VB'>Imports System
    /// Imports System.Management
    /// 
    /// ' This example demonstrates how to connect to remote machine
    /// ' using supplied credentials.
    /// Class Sample_ConnectionOptions
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    ///         Dim options As New ConnectionOptions()
    ///         options.Username = "domain\username"
    ///         options.Password = "password"
    ///         Dim scope As New ManagementScope("\\servername\root\cimv2", options)
    ///         Try
    ///             scope.Connect()
    ///             Dim disk As New ManagementObject(scope, _
    ///                 New ManagementPath("Win32_logicaldisk='c:'"), Nothing)
    ///             disk.Get()
    ///         Catch e As UnauthorizedAccessException
    ///             Console.WriteLine(("Failed to connect: " + e.Message))
    ///         End Try
    ///         Return 0
    ///     End Function
    /// End Class
    ///    </code>
    /// </example>
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    public class ConnectionOptions : ManagementOptions
    {
 
        internal const string DEFAULTLOCALE = null;
        internal const string DEFAULTAUTHORITY = null;
        internal const ImpersonationLevel DEFAULTIMPERSONATION = ImpersonationLevel.Impersonate;
        internal const AuthenticationLevel DEFAULTAUTHENTICATION = AuthenticationLevel.Unchanged;
        internal const bool DEFAULTENABLEPRIVILEGES = false;
 
        //Fields
        private string locale;
        private string username;
        private SecureString securePassword = null;
        private string authority;
        private ImpersonationLevel impersonation;
        private AuthenticationLevel authentication;
        private bool enablePrivileges;
        
 
        //
        //Properties
        //
 
        /// <summary>
        ///    <para>Gets or sets the locale to be used for the connection operation.</para>
        /// </summary>
        /// <value>
        ///    <para>The default value is DEFAULTLOCALE.</para>
        /// </value>
        public string Locale 
        {
            get { return (null != locale) ? locale : String.Empty; } 
            set { 
                if (locale != value)
                {
                    locale = value; 
                    FireIdentifierChanged();
                }
            } 
        }
 
        /// <summary>
        ///    <para>Gets or sets the user name to be used for the connection operation.</para>
        /// </summary>
        /// <value>
        ///    <para>Null if the connection will use the currently logged-on user; otherwise, a string representing the user name. The default value is null.</para>
        /// </value>
        /// <remarks>
        ///    <para>If the user name is from a domain other than the current 
        ///       domain, the string may contain the domain name and user name, separated by a backslash:</para>
        ///    <c>
        ///       <para>string username = "EnterDomainHere\\EnterUsernameHere";</para>
        ///    </c>
        /// </remarks>
        public string Username 
        {
            get { return username; } 
            set {
                if (username != value)
                {
                    username = value; 
                    FireIdentifierChanged();
                }
            } 
        }
 
        /// <summary>
        ///    <para>Sets the password for the specified user. The value can be set, but not retrieved.</para>
        /// </summary>
        /// <value>
        ///    <para> The default value is null. If the user name is also
        ///       null, the credentials used will be those of the currently logged-on user.</para>
        /// </value>
        /// <remarks>
        ///    <para> A blank string ("") specifies a valid
        ///       zero-length password.</para>
        /// </remarks>
        public string Password 
        { 
            set {
                if( value != null)
                {
                    if (securePassword == null)
                    {
                        securePassword = new SecureString();
                        for( int i=0; i <value.Length;i++)
                        {
                            securePassword.AppendChar(value[i]);
                        }
                    }
                    else
                    {
                        SecureString tempStr = new SecureString();
                        for( int i=0; i <value.Length;i++)
                        {
                            tempStr.AppendChar(value[i]);
                        }
                        securePassword.Clear();
                        securePassword = tempStr.Copy();
                        FireIdentifierChanged();
                         tempStr.Dispose();
                    }
                }
                else
                {
                    if (securePassword != null)
                    {
                        securePassword.Dispose();
                        securePassword = null;
                        FireIdentifierChanged();
                    }
                }
            }
        }
        /// <summary>
        ///    <para>Sets the secure password for the specified user. The value can be set, but not retrieved.</para>
        /// </summary>
        /// <value>
        ///    <para> The default value is null. If the user name is also
        ///       null, the credentials used will be those of the currently logged-on user.</para>
        /// </value>
        /// <remarks>
        ///    <para> A blank securestring ("") specifies a valid
        ///       zero-length password.</para>
        /// </remarks>
        public SecureString SecurePassword
        {
            set{
                if( value != null)
                {
                    if( securePassword == null)
                    {
                        securePassword = value.Copy();
                    }
                    else
                    {
                        securePassword.Clear();
                        securePassword = value.Copy();
                        FireIdentifierChanged();
                    }
                }
                else
                {
                    if (securePassword != null)
                    {
                        securePassword.Dispose();
                        securePassword = null;
                        FireIdentifierChanged();
                    }
                }
            }
        }
 
        /// <summary>
        ///    <para>Gets or sets the authority to be used to authenticate the specified user.</para>
        /// </summary>
        /// <value>
        ///    <para>If not null, this property can contain the name of the
        ///       Windows NT/Windows 2000 domain in which to obtain the user to
        ///       authenticate.</para>
        /// </value>
        /// <remarks>
        ///    <para> 
        ///       The property must be passed
        ///       as follows: If it begins with the string "Kerberos:", Kerberos
        ///       authentication will be used and this property should contain a Kerberos principal name. For
        ///       example, Kerberos:&lt;principal name&gt;.</para>
        ///    <para>If the property value begins with the string "NTLMDOMAIN:", NTLM 
        ///       authentication will be used and the property should contain a NTLM domain name.
        ///       For example, NTLMDOMAIN:&lt;domain name&gt;. </para>
        ///    <para>If the property is null, NTLM authentication will be used and the NTLM domain 
        ///       of the current user will be used.</para>
        /// </remarks>
        public string Authority 
        {
            get { return (null != authority) ? authority : String.Empty; } 
            set {
                if (authority != value)
                {
                    authority = value; 
                    FireIdentifierChanged();
                }
            } 
        }
 
        /// <summary>
        ///    <para>Gets or sets the COM impersonation level to be used for operations in this connection.</para>
        /// </summary>
        /// <value>
        ///    <para>The COM impersonation level to be used for operations in 
        ///       this connection. The default value is <see cref='System.Management.ImpersonationLevel.Impersonate' qualify='true'/>, which indicates that the WMI provider can
        ///       impersonate the client when performing the requested operations in this connection.</para>
        /// </value>
        /// <remarks>
        /// <para>The <see cref='System.Management.ImpersonationLevel.Impersonate' qualify='true'/> setting is advantageous when the provider is 
        ///    a trusted application or service. It eliminates the need for the provider to
        ///    perform client identity and access checks for the requested operations. However,
        ///    note that if for some reason the provider cannot be trusted, allowing it to
        ///    impersonate the client may constitute a security threat. In such cases, it is
        ///    recommended that this property be set by the client to a lower value, such as
        /// <see cref='System.Management.ImpersonationLevel. Identify' qualify='true'/>. Note that this may cause failure of the 
        ///    provider to perform the requested operations, for lack of sufficient permissions
        ///    or inability to perform access checks.</para>
        /// </remarks>
        public ImpersonationLevel Impersonation 
        {
            get { return impersonation; } 
            set { 
                if (impersonation != value)
                {
                    impersonation = value; 
                    FireIdentifierChanged();
                }
            } 
        }
 
        /// <summary>
        ///    <para>Gets or sets the COM authentication level to be used for operations in this connection.</para>
        /// </summary>
        /// <value>
        ///    <para>The COM authentication level to be used for operations 
        ///       in this connection. The default value is <see cref='System.Management.AuthenticationLevel.Unchanged' qualify='true'/>, which indicates that the
        ///       client will use the authentication level requested by the server, according to
        ///       the standard DCOM negotiation process.</para>
        /// </value>
        /// <remarks>
        ///    <para>On Windows 2000 and below, the WMI service will request 
        ///       Connect level authentication, while on Windows XP and higher it will request
        ///       Packet level authentication. If the client requires a specific authentication
        ///       setting, this property can be used to control the authentication level on this
        ///       particular connection. For example, the property can be set to <see cref='System.Management.AuthenticationLevel.PacketPrivacy' qualify='true'/>
        ///       if the
        ///       client requires all communication to be encrypted.</para>
        /// </remarks>
        public AuthenticationLevel Authentication 
        {
            get { return authentication; } 
            set {
                if (authentication != value)
                {
                    authentication = value; 
                    FireIdentifierChanged();
                }
            } 
        }
 
        /// <summary>
        ///    <para>Gets or sets a value indicating whether user privileges need to be enabled for 
        ///       the connection operation. This property should only be used when the operation
        ///       performed requires a certain user privilege to be enabled
        ///       (for example, a machine reboot).</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if user privileges need to be 
        ///    enabled for the connection operation; otherwise, <see langword='false'/>. The
        ///    default value is <see langword='false'/>.</para>
        /// </value>
        public bool EnablePrivileges 
        {
            get { return enablePrivileges; } 
            set {
                if (enablePrivileges != value)
                {
                    enablePrivileges = value; 
                    FireIdentifierChanged();
                }
            } 
        }
 
        //
        //Constructors
        //
 
        //default
        /// <overload>
        /// <para>Initializes a new instance of the <see cref='System.Management.ConnectionOptions'/> class.</para>
        /// </overload>
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.ConnectionOptions'/> class for the connection operation, using default values. This is the 
        ///    default constructor.</para>
        /// </summary>
        public ConnectionOptions () :
            this (DEFAULTLOCALE, null, (string)null, DEFAULTAUTHORITY,
                    DEFAULTIMPERSONATION, DEFAULTAUTHENTICATION,
                    DEFAULTENABLEPRIVILEGES, null, InfiniteTimeout) {}
 
        
        //parameterized
        /// <summary>
        /// <para> Initializes a new instance of the <see cref='System.Management.ConnectionOptions'/> class to be used for a WMI
        ///    connection, using the specified values.</para>
        /// </summary>
        /// <param name='locale'>The locale to be used for the connection.</param>
        /// <param name=' username'>The user name to be used for the connection. If null, the credentials of the currently logged-on user are used.</param>
        /// <param name=' password'>The password for the given user name. If the user name is also null, the credentials used will be those of the currently logged-on user.</param>
        /// <param name=' authority'><para>The authority to be used to authenticate the specified user.</para></param>
        /// <param name=' impersonation'>The COM impersonation level to be used for the connection.</param>
        /// <param name=' authentication'>The COM authentication level to be used for the connection.</param>
        /// <param name=' enablePrivileges'><see langword='true'/>to enable special user privileges; otherwise, <see langword='false'/> . This parameter should only be used when performing an operation that requires special Windows NT user privileges.</param>
        /// <param name=' context'>A provider-specific, named value pairs object to be passed through to the provider.</param>
        /// <param name=' timeout'>Reserved for future use.</param>
        public ConnectionOptions (string locale,
                string username, string password, string authority,
                ImpersonationLevel impersonation, AuthenticationLevel authentication,
                bool enablePrivileges,
                ManagementNamedValueCollection context, TimeSpan timeout) : base (context, timeout)
        {
            if (locale != null) 
                this.locale = locale;
 
            this.username = username;
            this.enablePrivileges = enablePrivileges;
 
            if (password != null)
            {
                this.securePassword = new SecureString();
                for( int i=0; i <password.Length;i++)
                {
                    securePassword.AppendChar(password[i]);
                }
            }
 
            if (authority != null) 
                this.authority = authority;
 
            if (impersonation != 0)
                this.impersonation = impersonation;
 
            if (authentication != 0)
                this.authentication = authentication;
        }
        //parameterized
        /// <summary>
        /// <para> Initializes a new instance of the <see cref='System.Management.ConnectionOptions'/> class to be used for a WMI
        ///    connection, using the specified values.</para>
        /// </summary>
        /// <param name='locale'>The locale to be used for the connection.</param>
        /// <param name=' username'>The user name to be used for the connection. If null, the credentials of the currently logged-on user are used.</param>
        /// <param name=' securepassword'>The secure password for the given user name. If the user name is also null, the credentials used will be those of the currently logged-on user.</param>
        /// <param name=' authority'><para>The authority to be used to authenticate the specified user.</para></param>
        /// <param name=' impersonation'>The COM impersonation level to be used for the connection.</param>
        /// <param name=' authentication'>The COM authentication level to be used for the connection.</param>
        /// <param name=' enablePrivileges'><see langword='true'/>to enable special user privileges; otherwise, <see langword='false'/> . This parameter should only be used when performing an operation that requires special Windows NT user privileges.</param>
        /// <param name=' context'>A provider-specific, named value pairs object to be passed through to the provider.</param>
        /// <param name=' timeout'>Reserved for future use.</param>
        public ConnectionOptions (string locale,
                string username, SecureString password, string authority,
                ImpersonationLevel impersonation, AuthenticationLevel authentication,
                bool enablePrivileges,
                ManagementNamedValueCollection context, TimeSpan timeout) : base (context, timeout)
        {
            if (locale != null) 
                this.locale = locale;
 
            this.username = username;
            this.enablePrivileges = enablePrivileges;
 
            if (password != null)
            {
                this.securePassword = password.Copy();
            }
 
            if (authority != null) 
                this.authority = authority;
 
            if (impersonation != 0)
                this.impersonation = impersonation;
 
            if (authentication != 0)
                this.authentication = authentication;
        }
 
        /// <summary>
        ///    <para> Returns a copy of the object.</para>
        /// </summary>
        /// <returns>
        ///    <para>The cloned object.</para>
        /// </returns>
        public override object Clone ()
        {
            ManagementNamedValueCollection newContext = null;
 
            if (null != Context)
                newContext = (ManagementNamedValueCollection)Context.Clone();
            return new ConnectionOptions (locale, username, GetSecurePassword (),
                    authority, impersonation, authentication, enablePrivileges, newContext, Timeout);
        }
 
        //
        //Methods
        //
 
        internal IntPtr GetPassword()
        {
            if (securePassword != null)
            {
                try{
                    return System.Runtime.InteropServices.Marshal.SecureStringToBSTR(securePassword);
                }
                catch(OutOfMemoryException)
                {
                    return IntPtr.Zero;
                }
            }
            else
                return IntPtr.Zero;
        }
         internal SecureString GetSecurePassword()
        {
            if (securePassword != null)
                return securePassword.Copy();
            else
                return null;
        }
 
        internal ConnectionOptions(ManagementNamedValueCollection context, TimeSpan timeout, int flags) : base(context, timeout, flags) {}
 
        internal ConnectionOptions(ManagementNamedValueCollection context) : base(context, InfiniteTimeout) {}
 
        internal static ConnectionOptions _Clone(ConnectionOptions options)
        {
            return ConnectionOptions._Clone(options, null);
        }
 
        internal static ConnectionOptions _Clone(ConnectionOptions options, IdentifierChangedEventHandler handler)
        {
            ConnectionOptions optionsTmp;
 
            if (options != null)
            {
                optionsTmp = new ConnectionOptions(options.Context, options.Timeout, options.Flags);
 
                optionsTmp.locale = options.locale;
 
                optionsTmp.username = options.username;
                optionsTmp.enablePrivileges = options.enablePrivileges;
 
                if (options.securePassword != null)
                {
                    optionsTmp.securePassword = options.securePassword.Copy();
                }
                else
                    optionsTmp.securePassword = null;
 
                if (options.authority != null) 
                    optionsTmp.authority = options.authority;
 
                if (options.impersonation != 0)
                    optionsTmp.impersonation = options.impersonation;
 
                if (options.authentication != 0)
                    optionsTmp.authentication = options.authentication;
            }
            else
                optionsTmp = new ConnectionOptions();
 
            // Wire up change handler chain. Use supplied handler, if specified;
            // otherwise, default to that of the path argument.
            if (handler != null)
                optionsTmp.IdentifierChanged += handler;
            else if (options != null)
                optionsTmp.IdentifierChanged += new IdentifierChangedEventHandler(options.HandleIdentifierChange);
 
            return optionsTmp;
        }
 
    }//ConnectionOptions
}