ManagementObjectCollection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Wmi / managed / System / Management / ManagementObjectCollection.cs / 1305376 / ManagementObjectCollection.cs

                            using System; 
using System.Collections;
using System.Runtime.InteropServices;
using WbemClient_v1;
using System.ComponentModel; 

namespace System.Management 
{ 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    ///  
    ///     Represents different collections of management objects
    ///       retrieved through WMI. The objects in this collection are of -derived types, including  and 
    ///       .
    ///     The collection can be the result of a WMI 
    ///       query executed through a  object, or an enumeration of
    ///       management objects of a specified type retrieved through a  representing that type. 
    ///       In addition, this can be a collection of management objects related in a specified 
    ///       way to a specific management object - in this case the collection would
    ///       be retrieved through a method such as . 
    /// The collection can be walked using the  and objects in it can be inspected or
    ///    manipulated for various management tasks.
    /// 
    ///  
    ///    using System;
    /// using System.Management; 
    /// 
    /// // This example demonstrates how to enumerate instances of a ManagementClass object.
    /// class Sample_ManagementObjectCollection 
    /// {
    ///     public static int Main(string[] args) {
    ///         ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk");
    ///         ManagementObjectCollection disks = diskClass.GetInstances(); 
    ///         foreach (ManagementObject disk in disks) {
    ///             Console.WriteLine("Disk = " + disk["deviceid"]); 
    ///         } 
    ///         return 0;
    ///     } 
    /// }
    ///    
    ///    Imports System
    /// Imports System.Management 
    ///
    /// ' This example demonstrates how to enumerate instances of a ManagementClass object. 
    /// Class Sample_ManagementObjectCollection 
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    ///         Dim diskClass As New ManagementClass("Win32_LogicalDisk") 
    ///         Dim disks As ManagementObjectCollection = diskClass.GetInstances()
    ///         Dim disk As ManagementObject
    ///         For Each disk In disks
    ///             Console.WriteLine("Disk = " & disk("deviceid").ToString()) 
    ///         Next disk
    ///         Return 0 
    ///     End Function 
    /// End Class
    ///     
    /// 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    public class ManagementObjectCollection : ICollection, IEnumerable, IDisposable
    { 
        private static readonly string name = typeof(ManagementObjectCollection).FullName;
 
        //fields 
        internal ManagementScope scope;
        internal EnumerationOptions options; 
        private IEnumWbemClassObject enumWbem; //holds WMI enumerator for this collection
        private bool isDisposed = false;

        //internal IWbemServices GetIWbemServices () { 
        //  return scope.GetIWbemServices ();
        //} 
 
        //internal ConnectionOptions Connection {
        //  get { return scope.Connection; } 
        //}

        //Constructor
        internal ManagementObjectCollection( 
            ManagementScope scope,
            EnumerationOptions options, 
            IEnumWbemClassObject enumWbem) 
        {
            if (null != options) 
                this.options = (EnumerationOptions) options.Clone();
            else
                this.options = new EnumerationOptions ();
 
            if (null != scope)
                this.scope = (ManagementScope)scope.Clone (); 
            else 
                this.scope = ManagementScope._Clone(null);
 
            this.enumWbem = enumWbem;
        }

        ///  
        /// Disposes of resources the object is holding. This is the destructor for the object.
        ///  
        ~ManagementObjectCollection () 
        {
            Dispose ( false ); 
        }

        /// 
        /// Releases resources associated with this object. After this 
        /// method has been called, an attempt to use this object will
        /// result in an ObjectDisposedException being thrown. 
        ///  
        public void Dispose ()
        { 
            if (!isDisposed)
            {
                Dispose ( true ) ;
            } 
        }
 
        private void Dispose ( bool disposing ) 
        {
            if ( disposing ) 
            {
                GC.SuppressFinalize (this);
                isDisposed = true;
            } 
            Marshal.ReleaseComObject (enumWbem);
        } 
 

        // 
        //ICollection properties & methods
        //

        ///  
        ///    Represents the number of objects in the collection.
        ///  
        ///  
        ///    The number of objects in the collection.
        ///  
        /// 
        ///    This property is very expensive - it requires that
        ///    all members of the collection be enumerated.
        ///  
        public int Count
        { 
            get 
            {
                if (isDisposed) 
                    throw new ObjectDisposedException(name);


                // 
                // [Whidbey RAID (marioh) : 27063]
                // See bug for more detailed comment. We can not use foreach since it 
                // _always_ calls Dispose on the collection invalidating the IEnumWbemClassObject 
                // pointers.
                // We fi this by doing a manual walk of the collection. 
                //
                int count = 0;

                IEnumerator enumCol = this.GetEnumerator ( ) ; 
                while ( enumCol.MoveNext() == true )
                { 
                    count++ ; 
                }
                return count ; 
            }
        }

        ///  
        ///    Represents whether the object is synchronized.
        ///  
        ///  
        /// , if the object is synchronized;
        ///    otherwise, . 
        /// 
        public bool IsSynchronized
        {
            get 
            {
                if (isDisposed) 
                    throw new ObjectDisposedException(name); 

                return false; 
            }
        }

        ///  
        ///    Represents the object to be used for synchronization.
        ///  
        ///  
        ///     The object to be used for synchronization.
        ///  
        public Object SyncRoot
        {
            get
            { 
                if (isDisposed)
                    throw new ObjectDisposedException(name); 
 
                return this;
            } 
        }

        /// 
        ///    Copies the collection to an array. 
        /// 
        ///  
        ///     Copies the collection to an array. 
        /// 
        /// An array to copy to.  
        /// The index to start from. 
        public void CopyTo (Array array, Int32 index)
        {
            if (isDisposed) 
                throw new ObjectDisposedException(name);
 
            if (null == array) 
                throw new ArgumentNullException ("array");
 
            if ((index < array.GetLowerBound (0)) || (index > array.GetUpperBound(0)))
                throw new ArgumentOutOfRangeException ("index");

            // Since we don't know the size until we've enumerated 
            // we'll have to dump the objects in a list first then
            // try to copy them in. 
 
            int capacity = array.Length - index;
            int numObjects = 0; 
            ArrayList arrList = new ArrayList ();

            ManagementObjectEnumerator en = this.GetEnumerator();
            ManagementBaseObject obj; 

            while (en.MoveNext()) 
            { 
                obj = en.Current;
 
                arrList.Add(obj);
                numObjects++;

                if (numObjects > capacity) 
                    throw new ArgumentException (null, "index");
            } 
 
            // If we get here we are OK. Now copy the list to the array
            arrList.CopyTo (array, index); 

            return;
        }
 
        /// 
        /// Copies the items in the collection to a  
        /// array. 
        /// 
        /// The target array. 
        /// The index to start from.
        public void CopyTo (ManagementBaseObject[] objectCollection, Int32 index)
        {
            CopyTo ((Array)objectCollection, index); 
        }
 
        // 
        //IEnumerable methods
        // 

        //****************************************
        //GetEnumerator
        //**************************************** 
        /// 
        ///    Returns the enumerator for the collection. If the collection was retrieved from an operation that 
        /// specified the EnumerationOptions.Rewindable = false only one iteration through this enumerator is allowed. 
        /// Note that this applies to using the Count property of the collection as well since an iteration over the collection
        /// is required. Due to this, code using the Count property should never specify EnumerationOptions.Rewindable = false. 
        /// 
        /// 
        /// 
        ///    An that can be used to iterate through the 
        ///    collection.
        ///  
        public ManagementObjectEnumerator GetEnumerator() 
        {
            if (isDisposed) 
                throw new ObjectDisposedException(name);


            // 
            // [Everett SP1 (marioh) : 149274]
            // The crux of the problem with this bug is that we we do not clone the enumerator 
            // if its the first enumerator. If it is the first enumerator we pass the reference 
            // to the enumerator implementation rather than a clone. If the enumerator is used
            // from within a foreach statement in the client code, the foreach statement will 
            // dec the ref count on the reference which also happens to be the reference to the
            // original enumerator causing subsequent uses of the collection to fail.
            // The fix is to always clone the enumerator (assuming its a rewindable enumerator)
            // to avoid invalidating the collection. 
            //
            // If its a forward only enumerator we simply pass back the original enumerator (i.e. 
            // not cloned) and if it gets disposed we end up throwing the next time its used. Essentially, 
            // the enumerator becomes the collection.
            // 

            // Unless this is the first enumerator, we have
            // to clone. This may throw if we are non-rewindable.
            if ( this.options.Rewindable == true ) 
            {
                IEnumWbemClassObject enumWbemClone = null; 
                int status = (int)ManagementStatus.NoError; 

                try 
                {
                    status = scope.GetSecuredIEnumWbemClassObjectHandler(enumWbem ).Clone_( ref enumWbemClone);

                    if ((status & 0x80000000) == 0) 
                    {
                        //since the original enumerator might not be reset, we need 
                        //to reset the new one. 
                        status = scope.GetSecuredIEnumWbemClassObjectHandler(enumWbemClone ).Reset_( );
                    } 
                }
                catch (COMException e)
                {
                    ManagementException.ThrowWithExtendedInfo (e); 
                }
 
                if ((status & 0xfffff000) == 0x80041000) 
                {
                    // 
                    ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                }
                else if ((status & 0x80000000) != 0)
                { 
                    //
                    Marshal.ThrowExceptionForHR(status); 
                } 
                return new ManagementObjectEnumerator (this, enumWbemClone);
            } 
            else
            {
                //
                // Notice that we use the original enumerator and hence enum position is retained. 
                // For example, if the client code manually walked half the collection and then
                // used a foreach statement, the foreach statement would continue from where the 
                // manual walk ended. 
                //
                return new ManagementObjectEnumerator(this, enumWbem); 
            }
        }

 
        /// 
        ///  
        ///    Returns an enumerator that can iterate through a collection. 
        /// 
        ///  
        ///    An  that can be used to iterate
        ///    through the collection.
        /// 
        IEnumerator IEnumerable.GetEnumerator() 
        {
            return GetEnumerator (); 
        } 

 

        //
        // ManagementObjectCollection methods
        // 

        //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 
        ///  
        ///    Represents the enumerator on the collection.
        ///  
        /// 
        ///    using System;
        /// using System.Management;
        /// 
        /// // This example demonstrates how to enumerate all logical disks
        /// // using the ManagementObjectEnumerator object. 
        /// class Sample_ManagementObjectEnumerator 
        /// {
        ///     public static int Main(string[] args) { 
        ///         ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk");
        ///         ManagementObjectCollection disks = diskClass.GetInstances();
        ///         ManagementObjectCollection.ManagementObjectEnumerator disksEnumerator =
        ///             disks.GetEnumerator(); 
        ///         while(disksEnumerator.MoveNext()) {
        ///             ManagementObject disk = (ManagementObject)disksEnumerator.Current; 
        ///            Console.WriteLine("Disk found: " + disk["deviceid"]); 
        ///         }
        ///         return 0; 
        ///     }
        /// }
        ///    
        ///    Imports System 
        ///       Imports System.Management
        ///       ' This sample demonstrates how to enumerate all logical disks 
        ///       ' using ManagementObjectEnumerator object. 
        ///       Class Sample_ManagementObjectEnumerator
        ///       Overloads Public Shared Function Main(args() As String) As Integer 
        ///       Dim diskClass As New ManagementClass("Win32_LogicalDisk")
        ///       Dim disks As ManagementObjectCollection = diskClass.GetInstances()
        ///       Dim disksEnumerator As _
        ///       ManagementObjectCollection.ManagementObjectEnumerator = _ 
        ///       disks.GetEnumerator()
        ///       While disksEnumerator.MoveNext() 
        ///       Dim disk As ManagementObject = _ 
        ///       CType(disksEnumerator.Current, ManagementObject)
        ///       Console.WriteLine("Disk found: " & disk("deviceid")) 
        ///       End While
        ///       Return 0
        ///       End Function
        ///       End Class 
        ///    
        ///  
        //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 
        public class ManagementObjectEnumerator : IEnumerator, IDisposable
        { 
            private static readonly string name = typeof(ManagementObjectEnumerator).FullName;
            private IEnumWbemClassObject enumWbem;
            private ManagementObjectCollection collectionObject;
            private uint cachedCount; //says how many objects are in the enumeration cache (when using BlockSize option) 
            private int cacheIndex; //used to walk the enumeration cache
            private IWbemClassObjectFreeThreaded[] cachedObjects; //points to objects currently available in enumeration cache 
            private bool atEndOfCollection; 
            private bool isDisposed = false;
 
            //constructor
            internal ManagementObjectEnumerator(
                ManagementObjectCollection collectionObject,
                IEnumWbemClassObject enumWbem) 
            {
                this.enumWbem = enumWbem; 
                this.collectionObject = collectionObject; 
                cachedObjects = new IWbemClassObjectFreeThreaded[collectionObject.options.BlockSize];
                cachedCount = 0; 
                cacheIndex = -1; // Reset position
                atEndOfCollection = false;
            }
 

            ///  
            /// Disposes of resources the object is holding. This is the destructor for the object. 
            /// 
            ~ManagementObjectEnumerator () 
            {
                Dispose ();
            }
 

            ///  
            /// Releases resources associated with this object. After this 
            /// method has been called, an attempt to use this object will
            /// result in an ObjectDisposedException being thrown. 
            /// 
            public void Dispose ()
            {
                if (!isDisposed) 
                {
                    if (null != enumWbem) 
                    { 
                        Marshal.ReleaseComObject (enumWbem);
                        enumWbem = null; 
                    }

                    cachedObjects = null;
 
                    // DO NOT dispose of collectionObject.  It is merely a reference - its lifetime
                    // exceeds that of this object.  If collectionObject.Dispose was to be done here, 
                    // a reference count would be needed. 
                    //
                    collectionObject = null; 

                    isDisposed = true;

                    GC.SuppressFinalize (this); 
                }
            } 
 

            ///  
            /// Gets the current  that this enumerator points
            ///    to.
            /// 
            ///  
            ///    The current object in the enumeration.
            ///  
            public ManagementBaseObject Current 
            {
                get 
                {
                    if (isDisposed)
                        throw new ObjectDisposedException(name);
 
                    if (cacheIndex < 0)
                        throw new InvalidOperationException(); 
 
                    return ManagementBaseObject.GetBaseObject (cachedObjects[cacheIndex],
                        collectionObject.scope); 
                }
            }

            ///  
            /// 
            ///    Returns the current object in the enumeration. 
            ///  
            /// 
            ///    The current object in the enumeration. 
            /// 
            object IEnumerator.Current
            {
                get 
                {
                    return Current; 
                } 
            }
 
            //****************************************
            //MoveNext
            //****************************************
            ///  
            ///    Indicates whether the enumerator has moved to
            ///    the next object in the enumeration. 
            ///  
            /// 
            /// , if the enumerator was 
            ///    successfully advanced to the next element;  if the enumerator has
            ///    passed the end of the collection.
            /// 
            public bool MoveNext () 
            {
                if (isDisposed) 
                    throw new ObjectDisposedException(name); 

                //If there are no more objects in the collection return false 
                if (atEndOfCollection)
                    return false;

                //Look for the next object 
                cacheIndex++;
 
                if ((cachedCount - cacheIndex) == 0) //cache is empty - need to get more objects 
                {
 
                    //If the timeout is set to infinite, need to use the WMI infinite constant
                    int timeout = (collectionObject.options.Timeout.Ticks == Int64.MaxValue) ?
                        (int)tag_WBEM_TIMEOUT_TYPE.WBEM_INFINITE : (int)collectionObject.options.Timeout.TotalMilliseconds;
 
                    //Get the next [BLockSize] objects within the specified timeout
                    // 
 
                    SecurityHandler securityHandler = collectionObject.scope.GetSecurityHandler();
 
                    //Because Interop doesn't support custom marshalling for arrays, we have to use
                    //the "DoNotMarshal" objects in the interop and then convert to the "FreeThreaded"
                    //counterparts afterwards.
                    IWbemClassObject_DoNotMarshal[] tempArray = new IWbemClassObject_DoNotMarshal[collectionObject.options.BlockSize]; 

                    int status = collectionObject.scope.GetSecuredIEnumWbemClassObjectHandler(enumWbem ).Next_(timeout, (uint)collectionObject.options.BlockSize,tempArray, ref cachedCount); 
 
                    securityHandler.Reset();
 
                    if (status >= 0)
                    {
                        //Convert results and put them in cache.
 
                        for (int i = 0; i < cachedCount; i++)
                        { 
                            cachedObjects[i] = new IWbemClassObjectFreeThreaded 
                                                (
                                                    Marshal.GetIUnknownForObject(tempArray[i]) 
                                                );
                        }
                    }
 
                    if (status < 0)
                    { 
                        if ((status & 0xfffff000) == 0x80041000) 
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                        else 
                            Marshal.ThrowExceptionForHR(status);
                    }
                    else
                    { 
                        //If there was a timeout and no object can be returned we throw a timeout exception...
                        // - 
                        if ((status == (int)tag_WBEMSTATUS.WBEM_S_TIMEDOUT) && (cachedCount == 0)) 
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
 
                        //If not timeout and no objects were returned - we're at the end of the collection
                        if ((status == (int)tag_WBEMSTATUS.WBEM_S_FALSE) && (cachedCount == 0))
                        {
                            atEndOfCollection = true; 
                            cacheIndex--; //back to last object
 
                            /* This call to Dispose is being removed as per discussion with URT people and the newly supported 
                             * Dispose() call in the foreach implementation itself.
                             * 
                             *                              //Release the COM object (so that the user doesn't have to)
                                                            Dispose();
                            */
                            return false; 
                        }
                    } 
 
                    cacheIndex = 0;
                } 

                return true;
            }
 
            //****************************************
            //Reset 
            //**************************************** 
            /// 
            ///    Resets the enumerator to the beginning of the collection. 
            /// 
            public void Reset ()
            {
                if (isDisposed) 
                    throw new ObjectDisposedException(name);
 
                //If the collection is not rewindable you can't do this 
                if (!collectionObject.options.Rewindable)
                    throw new InvalidOperationException(); 
                else
                {
                    //Reset the WMI enumerator
                    SecurityHandler securityHandler = collectionObject.scope.GetSecurityHandler(); 
                    int status = (int)ManagementStatus.NoError;
 
                    try 
                    {
                        status = collectionObject.scope.GetSecuredIEnumWbemClassObjectHandler(enumWbem).Reset_(); 
                    }
                    catch (COMException e)
                    {
                        // 
                        ManagementException.ThrowWithExtendedInfo (e);
                    } 
                    finally 
                    {
                        securityHandler.Reset (); 
                    }

                    if ((status & 0xfffff000) == 0x80041000)
                    { 
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                    } 
                    else if ((status & 0x80000000) != 0) 
                    {
                        Marshal.ThrowExceptionForHR(status); 
                    }

                    //Flush the current enumeration cache
                    for (int i=(cacheIndex >= 0 ? cacheIndex : 0); i 
    ///     Represents different collections of management objects
    ///       retrieved through WMI. The objects in this collection are of -derived types, including  and 
    ///       .
    ///     The collection can be the result of a WMI 
    ///       query executed through a  object, or an enumeration of
    ///       management objects of a specified type retrieved through a  representing that type. 
    ///       In addition, this can be a collection of management objects related in a specified 
    ///       way to a specific management object - in this case the collection would
    ///       be retrieved through a method such as . 
    /// The collection can be walked using the  and objects in it can be inspected or
    ///    manipulated for various management tasks.
    /// 
    ///  
    ///    using System;
    /// using System.Management; 
    /// 
    /// // This example demonstrates how to enumerate instances of a ManagementClass object.
    /// class Sample_ManagementObjectCollection 
    /// {
    ///     public static int Main(string[] args) {
    ///         ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk");
    ///         ManagementObjectCollection disks = diskClass.GetInstances(); 
    ///         foreach (ManagementObject disk in disks) {
    ///             Console.WriteLine("Disk = " + disk["deviceid"]); 
    ///         } 
    ///         return 0;
    ///     } 
    /// }
    ///    
    ///    Imports System
    /// Imports System.Management 
    ///
    /// ' This example demonstrates how to enumerate instances of a ManagementClass object. 
    /// Class Sample_ManagementObjectCollection 
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    ///         Dim diskClass As New ManagementClass("Win32_LogicalDisk") 
    ///         Dim disks As ManagementObjectCollection = diskClass.GetInstances()
    ///         Dim disk As ManagementObject
    ///         For Each disk In disks
    ///             Console.WriteLine("Disk = " & disk("deviceid").ToString()) 
    ///         Next disk
    ///         Return 0 
    ///     End Function 
    /// End Class
    ///     
    /// 
    //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC//
    public class ManagementObjectCollection : ICollection, IEnumerable, IDisposable
    { 
        private static readonly string name = typeof(ManagementObjectCollection).FullName;
 
        //fields 
        internal ManagementScope scope;
        internal EnumerationOptions options; 
        private IEnumWbemClassObject enumWbem; //holds WMI enumerator for this collection
        private bool isDisposed = false;

        //internal IWbemServices GetIWbemServices () { 
        //  return scope.GetIWbemServices ();
        //} 
 
        //internal ConnectionOptions Connection {
        //  get { return scope.Connection; } 
        //}

        //Constructor
        internal ManagementObjectCollection( 
            ManagementScope scope,
            EnumerationOptions options, 
            IEnumWbemClassObject enumWbem) 
        {
            if (null != options) 
                this.options = (EnumerationOptions) options.Clone();
            else
                this.options = new EnumerationOptions ();
 
            if (null != scope)
                this.scope = (ManagementScope)scope.Clone (); 
            else 
                this.scope = ManagementScope._Clone(null);
 
            this.enumWbem = enumWbem;
        }

        ///  
        /// Disposes of resources the object is holding. This is the destructor for the object.
        ///  
        ~ManagementObjectCollection () 
        {
            Dispose ( false ); 
        }

        /// 
        /// Releases resources associated with this object. After this 
        /// method has been called, an attempt to use this object will
        /// result in an ObjectDisposedException being thrown. 
        ///  
        public void Dispose ()
        { 
            if (!isDisposed)
            {
                Dispose ( true ) ;
            } 
        }
 
        private void Dispose ( bool disposing ) 
        {
            if ( disposing ) 
            {
                GC.SuppressFinalize (this);
                isDisposed = true;
            } 
            Marshal.ReleaseComObject (enumWbem);
        } 
 

        // 
        //ICollection properties & methods
        //

        ///  
        ///    Represents the number of objects in the collection.
        ///  
        ///  
        ///    The number of objects in the collection.
        ///  
        /// 
        ///    This property is very expensive - it requires that
        ///    all members of the collection be enumerated.
        ///  
        public int Count
        { 
            get 
            {
                if (isDisposed) 
                    throw new ObjectDisposedException(name);


                // 
                // [Whidbey RAID (marioh) : 27063]
                // See bug for more detailed comment. We can not use foreach since it 
                // _always_ calls Dispose on the collection invalidating the IEnumWbemClassObject 
                // pointers.
                // We fi this by doing a manual walk of the collection. 
                //
                int count = 0;

                IEnumerator enumCol = this.GetEnumerator ( ) ; 
                while ( enumCol.MoveNext() == true )
                { 
                    count++ ; 
                }
                return count ; 
            }
        }

        ///  
        ///    Represents whether the object is synchronized.
        ///  
        ///  
        /// , if the object is synchronized;
        ///    otherwise, . 
        /// 
        public bool IsSynchronized
        {
            get 
            {
                if (isDisposed) 
                    throw new ObjectDisposedException(name); 

                return false; 
            }
        }

        ///  
        ///    Represents the object to be used for synchronization.
        ///  
        ///  
        ///     The object to be used for synchronization.
        ///  
        public Object SyncRoot
        {
            get
            { 
                if (isDisposed)
                    throw new ObjectDisposedException(name); 
 
                return this;
            } 
        }

        /// 
        ///    Copies the collection to an array. 
        /// 
        ///  
        ///     Copies the collection to an array. 
        /// 
        /// An array to copy to.  
        /// The index to start from. 
        public void CopyTo (Array array, Int32 index)
        {
            if (isDisposed) 
                throw new ObjectDisposedException(name);
 
            if (null == array) 
                throw new ArgumentNullException ("array");
 
            if ((index < array.GetLowerBound (0)) || (index > array.GetUpperBound(0)))
                throw new ArgumentOutOfRangeException ("index");

            // Since we don't know the size until we've enumerated 
            // we'll have to dump the objects in a list first then
            // try to copy them in. 
 
            int capacity = array.Length - index;
            int numObjects = 0; 
            ArrayList arrList = new ArrayList ();

            ManagementObjectEnumerator en = this.GetEnumerator();
            ManagementBaseObject obj; 

            while (en.MoveNext()) 
            { 
                obj = en.Current;
 
                arrList.Add(obj);
                numObjects++;

                if (numObjects > capacity) 
                    throw new ArgumentException (null, "index");
            } 
 
            // If we get here we are OK. Now copy the list to the array
            arrList.CopyTo (array, index); 

            return;
        }
 
        /// 
        /// Copies the items in the collection to a  
        /// array. 
        /// 
        /// The target array. 
        /// The index to start from.
        public void CopyTo (ManagementBaseObject[] objectCollection, Int32 index)
        {
            CopyTo ((Array)objectCollection, index); 
        }
 
        // 
        //IEnumerable methods
        // 

        //****************************************
        //GetEnumerator
        //**************************************** 
        /// 
        ///    Returns the enumerator for the collection. If the collection was retrieved from an operation that 
        /// specified the EnumerationOptions.Rewindable = false only one iteration through this enumerator is allowed. 
        /// Note that this applies to using the Count property of the collection as well since an iteration over the collection
        /// is required. Due to this, code using the Count property should never specify EnumerationOptions.Rewindable = false. 
        /// 
        /// 
        /// 
        ///    An that can be used to iterate through the 
        ///    collection.
        ///  
        public ManagementObjectEnumerator GetEnumerator() 
        {
            if (isDisposed) 
                throw new ObjectDisposedException(name);


            // 
            // [Everett SP1 (marioh) : 149274]
            // The crux of the problem with this bug is that we we do not clone the enumerator 
            // if its the first enumerator. If it is the first enumerator we pass the reference 
            // to the enumerator implementation rather than a clone. If the enumerator is used
            // from within a foreach statement in the client code, the foreach statement will 
            // dec the ref count on the reference which also happens to be the reference to the
            // original enumerator causing subsequent uses of the collection to fail.
            // The fix is to always clone the enumerator (assuming its a rewindable enumerator)
            // to avoid invalidating the collection. 
            //
            // If its a forward only enumerator we simply pass back the original enumerator (i.e. 
            // not cloned) and if it gets disposed we end up throwing the next time its used. Essentially, 
            // the enumerator becomes the collection.
            // 

            // Unless this is the first enumerator, we have
            // to clone. This may throw if we are non-rewindable.
            if ( this.options.Rewindable == true ) 
            {
                IEnumWbemClassObject enumWbemClone = null; 
                int status = (int)ManagementStatus.NoError; 

                try 
                {
                    status = scope.GetSecuredIEnumWbemClassObjectHandler(enumWbem ).Clone_( ref enumWbemClone);

                    if ((status & 0x80000000) == 0) 
                    {
                        //since the original enumerator might not be reset, we need 
                        //to reset the new one. 
                        status = scope.GetSecuredIEnumWbemClassObjectHandler(enumWbemClone ).Reset_( );
                    } 
                }
                catch (COMException e)
                {
                    ManagementException.ThrowWithExtendedInfo (e); 
                }
 
                if ((status & 0xfffff000) == 0x80041000) 
                {
                    // 
                    ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                }
                else if ((status & 0x80000000) != 0)
                { 
                    //
                    Marshal.ThrowExceptionForHR(status); 
                } 
                return new ManagementObjectEnumerator (this, enumWbemClone);
            } 
            else
            {
                //
                // Notice that we use the original enumerator and hence enum position is retained. 
                // For example, if the client code manually walked half the collection and then
                // used a foreach statement, the foreach statement would continue from where the 
                // manual walk ended. 
                //
                return new ManagementObjectEnumerator(this, enumWbem); 
            }
        }

 
        /// 
        ///  
        ///    Returns an enumerator that can iterate through a collection. 
        /// 
        ///  
        ///    An  that can be used to iterate
        ///    through the collection.
        /// 
        IEnumerator IEnumerable.GetEnumerator() 
        {
            return GetEnumerator (); 
        } 

 

        //
        // ManagementObjectCollection methods
        // 

        //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 
        ///  
        ///    Represents the enumerator on the collection.
        ///  
        /// 
        ///    using System;
        /// using System.Management;
        /// 
        /// // This example demonstrates how to enumerate all logical disks
        /// // using the ManagementObjectEnumerator object. 
        /// class Sample_ManagementObjectEnumerator 
        /// {
        ///     public static int Main(string[] args) { 
        ///         ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk");
        ///         ManagementObjectCollection disks = diskClass.GetInstances();
        ///         ManagementObjectCollection.ManagementObjectEnumerator disksEnumerator =
        ///             disks.GetEnumerator(); 
        ///         while(disksEnumerator.MoveNext()) {
        ///             ManagementObject disk = (ManagementObject)disksEnumerator.Current; 
        ///            Console.WriteLine("Disk found: " + disk["deviceid"]); 
        ///         }
        ///         return 0; 
        ///     }
        /// }
        ///    
        ///    Imports System 
        ///       Imports System.Management
        ///       ' This sample demonstrates how to enumerate all logical disks 
        ///       ' using ManagementObjectEnumerator object. 
        ///       Class Sample_ManagementObjectEnumerator
        ///       Overloads Public Shared Function Main(args() As String) As Integer 
        ///       Dim diskClass As New ManagementClass("Win32_LogicalDisk")
        ///       Dim disks As ManagementObjectCollection = diskClass.GetInstances()
        ///       Dim disksEnumerator As _
        ///       ManagementObjectCollection.ManagementObjectEnumerator = _ 
        ///       disks.GetEnumerator()
        ///       While disksEnumerator.MoveNext() 
        ///       Dim disk As ManagementObject = _ 
        ///       CType(disksEnumerator.Current, ManagementObject)
        ///       Console.WriteLine("Disk found: " & disk("deviceid")) 
        ///       End While
        ///       Return 0
        ///       End Function
        ///       End Class 
        ///    
        ///  
        //CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 
        public class ManagementObjectEnumerator : IEnumerator, IDisposable
        { 
            private static readonly string name = typeof(ManagementObjectEnumerator).FullName;
            private IEnumWbemClassObject enumWbem;
            private ManagementObjectCollection collectionObject;
            private uint cachedCount; //says how many objects are in the enumeration cache (when using BlockSize option) 
            private int cacheIndex; //used to walk the enumeration cache
            private IWbemClassObjectFreeThreaded[] cachedObjects; //points to objects currently available in enumeration cache 
            private bool atEndOfCollection; 
            private bool isDisposed = false;
 
            //constructor
            internal ManagementObjectEnumerator(
                ManagementObjectCollection collectionObject,
                IEnumWbemClassObject enumWbem) 
            {
                this.enumWbem = enumWbem; 
                this.collectionObject = collectionObject; 
                cachedObjects = new IWbemClassObjectFreeThreaded[collectionObject.options.BlockSize];
                cachedCount = 0; 
                cacheIndex = -1; // Reset position
                atEndOfCollection = false;
            }
 

            ///  
            /// Disposes of resources the object is holding. This is the destructor for the object. 
            /// 
            ~ManagementObjectEnumerator () 
            {
                Dispose ();
            }
 

            ///  
            /// Releases resources associated with this object. After this 
            /// method has been called, an attempt to use this object will
            /// result in an ObjectDisposedException being thrown. 
            /// 
            public void Dispose ()
            {
                if (!isDisposed) 
                {
                    if (null != enumWbem) 
                    { 
                        Marshal.ReleaseComObject (enumWbem);
                        enumWbem = null; 
                    }

                    cachedObjects = null;
 
                    // DO NOT dispose of collectionObject.  It is merely a reference - its lifetime
                    // exceeds that of this object.  If collectionObject.Dispose was to be done here, 
                    // a reference count would be needed. 
                    //
                    collectionObject = null; 

                    isDisposed = true;

                    GC.SuppressFinalize (this); 
                }
            } 
 

            ///  
            /// Gets the current  that this enumerator points
            ///    to.
            /// 
            ///  
            ///    The current object in the enumeration.
            ///  
            public ManagementBaseObject Current 
            {
                get 
                {
                    if (isDisposed)
                        throw new ObjectDisposedException(name);
 
                    if (cacheIndex < 0)
                        throw new InvalidOperationException(); 
 
                    return ManagementBaseObject.GetBaseObject (cachedObjects[cacheIndex],
                        collectionObject.scope); 
                }
            }

            ///  
            /// 
            ///    Returns the current object in the enumeration. 
            ///  
            /// 
            ///    The current object in the enumeration. 
            /// 
            object IEnumerator.Current
            {
                get 
                {
                    return Current; 
                } 
            }
 
            //****************************************
            //MoveNext
            //****************************************
            ///  
            ///    Indicates whether the enumerator has moved to
            ///    the next object in the enumeration. 
            ///  
            /// 
            /// , if the enumerator was 
            ///    successfully advanced to the next element;  if the enumerator has
            ///    passed the end of the collection.
            /// 
            public bool MoveNext () 
            {
                if (isDisposed) 
                    throw new ObjectDisposedException(name); 

                //If there are no more objects in the collection return false 
                if (atEndOfCollection)
                    return false;

                //Look for the next object 
                cacheIndex++;
 
                if ((cachedCount - cacheIndex) == 0) //cache is empty - need to get more objects 
                {
 
                    //If the timeout is set to infinite, need to use the WMI infinite constant
                    int timeout = (collectionObject.options.Timeout.Ticks == Int64.MaxValue) ?
                        (int)tag_WBEM_TIMEOUT_TYPE.WBEM_INFINITE : (int)collectionObject.options.Timeout.TotalMilliseconds;
 
                    //Get the next [BLockSize] objects within the specified timeout
                    // 
 
                    SecurityHandler securityHandler = collectionObject.scope.GetSecurityHandler();
 
                    //Because Interop doesn't support custom marshalling for arrays, we have to use
                    //the "DoNotMarshal" objects in the interop and then convert to the "FreeThreaded"
                    //counterparts afterwards.
                    IWbemClassObject_DoNotMarshal[] tempArray = new IWbemClassObject_DoNotMarshal[collectionObject.options.BlockSize]; 

                    int status = collectionObject.scope.GetSecuredIEnumWbemClassObjectHandler(enumWbem ).Next_(timeout, (uint)collectionObject.options.BlockSize,tempArray, ref cachedCount); 
 
                    securityHandler.Reset();
 
                    if (status >= 0)
                    {
                        //Convert results and put them in cache.
 
                        for (int i = 0; i < cachedCount; i++)
                        { 
                            cachedObjects[i] = new IWbemClassObjectFreeThreaded 
                                                (
                                                    Marshal.GetIUnknownForObject(tempArray[i]) 
                                                );
                        }
                    }
 
                    if (status < 0)
                    { 
                        if ((status & 0xfffff000) == 0x80041000) 
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                        else 
                            Marshal.ThrowExceptionForHR(status);
                    }
                    else
                    { 
                        //If there was a timeout and no object can be returned we throw a timeout exception...
                        // - 
                        if ((status == (int)tag_WBEMSTATUS.WBEM_S_TIMEDOUT) && (cachedCount == 0)) 
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
 
                        //If not timeout and no objects were returned - we're at the end of the collection
                        if ((status == (int)tag_WBEMSTATUS.WBEM_S_FALSE) && (cachedCount == 0))
                        {
                            atEndOfCollection = true; 
                            cacheIndex--; //back to last object
 
                            /* This call to Dispose is being removed as per discussion with URT people and the newly supported 
                             * Dispose() call in the foreach implementation itself.
                             * 
                             *                              //Release the COM object (so that the user doesn't have to)
                                                            Dispose();
                            */
                            return false; 
                        }
                    } 
 
                    cacheIndex = 0;
                } 

                return true;
            }
 
            //****************************************
            //Reset 
            //**************************************** 
            /// 
            ///    Resets the enumerator to the beginning of the collection. 
            /// 
            public void Reset ()
            {
                if (isDisposed) 
                    throw new ObjectDisposedException(name);
 
                //If the collection is not rewindable you can't do this 
                if (!collectionObject.options.Rewindable)
                    throw new InvalidOperationException(); 
                else
                {
                    //Reset the WMI enumerator
                    SecurityHandler securityHandler = collectionObject.scope.GetSecurityHandler(); 
                    int status = (int)ManagementStatus.NoError;
 
                    try 
                    {
                        status = collectionObject.scope.GetSecuredIEnumWbemClassObjectHandler(enumWbem).Reset_(); 
                    }
                    catch (COMException e)
                    {
                        // 
                        ManagementException.ThrowWithExtendedInfo (e);
                    } 
                    finally 
                    {
                        securityHandler.Reset (); 
                    }

                    if ((status & 0xfffff000) == 0x80041000)
                    { 
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                    } 
                    else if ((status & 0x80000000) != 0) 
                    {
                        Marshal.ThrowExceptionForHR(status); 
                    }

                    //Flush the current enumeration cache
                    for (int i=(cacheIndex >= 0 ? cacheIndex : 0); i

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK