ManagementPath.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 / ManagementPath.cs / 1305376 / ManagementPath.cs

                            using System; 
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design; 
using System.Runtime.InteropServices;
using WbemUtilities_v1; 
using WbemClient_v1; 
using System.Globalization;
using System.Reflection; 
using System.ComponentModel.Design.Serialization;

namespace System.Management
{ 
    /// 
    ///    Provides a wrapper for parsing and building paths to WMI objects. 
    ///  
    /// 
    ///    using System; 
    /// using System.Management;
    ///
    /// // This sample displays all properties in a ManagementPath object.
    /// 
    /// class Sample_ManagementPath
    /// { 
    ///     public static int Main(string[] args) { 
    ///         ManagementPath path = new ManagementPath( "\\\\MyServer\\MyNamespace:Win32_logicaldisk='c:'");
    /// 
    ///         // Results of full path parsing
    ///         Console.WriteLine("Path: " + path.Path);
    ///         Console.WriteLine("RelativePath: " + path.RelativePath);
    ///         Console.WriteLine("Server: " + path.Server); 
    ///         Console.WriteLine("NamespacePath: " + path.NamespacePath);
    ///         Console.WriteLine("ClassName: " + path.ClassName); 
    ///         Console.WriteLine("IsClass: " + path.IsClass); 
    ///         Console.WriteLine("IsInstance: " + path.IsInstance);
    ///         Console.WriteLine("IsSingleton: " + path.IsSingleton); 
    ///
    ///         // Change a portion of the full path
    ///         path.Server = "AnotherServer";
    ///         Console.WriteLine("New Path: " + path.Path); 
    ///         return 0;
    ///    } 
    /// } 
    ///    
    ///    Imports System 
    /// Imports System.Management
    ///
    /// 'This sample displays all properties in a ManagementPath object.
    /// Class Sample_ManagementPath Overloads 
    ///     Public Shared Function Main(args() As String) As Integer
    ///         Dim path As _ New 
    ///         ManagementPath("\\MyServer\MyNamespace:Win32_LogicalDisk='c:'") 
    ///
    ///         ' Results of full path parsing 
    ///         Console.WriteLine("Path: " & path.Path)
    ///         Console.WriteLine("RelativePath: " & path.RelativePath)
    ///         Console.WriteLine("Server: " & path.Server)
    ///         Console.WriteLine("NamespacePath: " & path.NamespacePath) 
    ///         Console.WriteLine("ClassName: " & path.ClassName)
    ///         Console.WriteLine("IsClass: " & path.IsClass) 
    ///         Console.WriteLine("IsInstance: " & path.IsInstance) 
    ///         Console.WriteLine("IsSingleton: " & path.IsSingleton)
    /// 
    ///         ' Change a portion of the full path
    ///         path.Server= "AnotherServer"
    ///         Console.WriteLine("New Path: " & path.Path)
    ///         Return 0 
    ///     End Function
    /// End Class 
    ///     
    /// 
    [TypeConverter(typeof(ManagementPathConverter ))] 
    public class ManagementPath : ICloneable
    {
        private static ManagementPath defaultPath = new ManagementPath("//./root/cimv2");
 
        //Used to minimize the cases in which new wbemPath (WMI object path parser) objects need to be constructed
        //This is done for performance reasons. 
        private bool   isWbemPathShared = false; 

        internal event IdentifierChangedEventHandler IdentifierChanged; 

        //Fires IdentifierChanged event
        private void FireIdentifierChanged()
        { 
            if (IdentifierChanged != null)
                IdentifierChanged(this, null); 
        } 

        //internal factory 
        /// 
        /// Internal static "factory" method for making a new ManagementPath
        /// from the system property of a WMI object
        ///  
        /// The WMI object whose __PATH property will
        /// be used to supply the returned object 
        internal static string GetManagementPath ( 
            IWbemClassObjectFreeThreaded wbemObject)
        { 
            string path = null;
            int status  = (int)ManagementStatus.Failed;

            if (null != wbemObject) 
            {
                int dummy1 = 0, dummy2 = 0; 
                object val = null; 
                status = wbemObject.Get_ ("__PATH", 0, ref val, ref dummy1, ref dummy2);
                if ((status < 0) || (val == System.DBNull.Value)) 
                {
                    //try to get the relpath instead
                    status = wbemObject.Get_ ("__RELPATH", 0, ref val, ref dummy1, ref dummy2);
                    if (status < 0) 
                    {
                        if ((status & 0xfffff000) == 0x80041000) 
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                        else
                            Marshal.ThrowExceptionForHR(status); 
                    }
                }

                if (System.DBNull.Value == val) 
                    path = null;
                else 
                    path = (string)val; 
            }
 
            return path;
        }

        //Used internally to check whether a string passed in as a namespace is indeed syntactically correct 
        //for a namespace (e.g. either has "\" or "/" in it or is the special case of "root")
        //This doesn't check for the existance of that namespace, nor does it guarrantee correctness. 
        internal static bool IsValidNamespaceSyntax(string nsPath) 
        {
            if (nsPath.Length != 0) 
            {
                // Any path separators present?
                char[] pathSeparators = { '\\', '/' };
                if (nsPath.IndexOfAny(pathSeparators) == -1) 
                {
                    // No separators.  The only valid path is "root". 
                    if (String.Compare("root", nsPath, StringComparison.OrdinalIgnoreCase) != 0) 
                        return false;
                } 
            }

            return true;
        } 

 
        internal static ManagementPath _Clone(ManagementPath path) 
        {
            return ManagementPath._Clone(path, null); 
        }

        internal static ManagementPath _Clone(ManagementPath path, IdentifierChangedEventHandler handler)
        { 
            ManagementPath pathTmp = new ManagementPath();
 
            // Wire up change handler chain. Use supplied handler, if specified; 
            // otherwise, default to that of the path argument.
            if (handler != null) 
                pathTmp.IdentifierChanged = handler;

            // Assign ManagementPath IWbemPath to this.wmiPath.
            // Optimization for performance : As long as the path is only read, we share this interface. 
            // On the first write, a private copy will be needed;
            // isWbemPathShared signals ManagementPath to create such a copy at write-time. 
            if (path != null && path.wmiPath != null) 
            {
                pathTmp.wmiPath = path.wmiPath; 
                pathTmp.isWbemPathShared = path.isWbemPathShared = true;
            }

            return pathTmp; 
        }
 
        ///  
        ///    Initializes a new instance
        ///    of the  class. 
        /// 
        /// 
        ///  Initializes a new instance of the  class that is empty. This is the default constructor.
        ///  
        public ManagementPath () : this ((string) null) {}
 
        ///  
        /// Initializes a new instance of the  class for the given path.
        ///  
        ///  The object path. 
        public ManagementPath(string path)
        {
            if ((null != path) && (0 < path.Length)) 
                wmiPath = CreateWbemPath(path);
        } 
 
        /// 
        ///    Returns the full object path as the string representation. 
        /// 
        /// 
        ///    A string containing the full object
        ///    path represented by this object. This value is equivalent to the value of the 
        ///  property.
        ///  
        public override string ToString () 
        {
            return this.Path; 
        }

        /// 
        /// Returns a copy of the . 
        /// 
        ///  
        ///    The cloned object. 
        /// 
        public ManagementPath Clone () 
        {
            return new ManagementPath (Path);
        }
 
        /// 
        /// Standard Clone returns a copy of this ManagementPath as a generic "Object" type 
        ///  
        /// 
        ///    The cloned object. 
        /// 
        object ICloneable.Clone ()
        {
            return Clone (); 
        }
 
        ///  
        ///    Gets or sets the default scope path used when no scope is specified.
        ///       The default scope is /-/ \\.\root\cimv2, and can be changed by setting this property. 
        /// 
        /// 
        ///    By default the scope value is /-/ \\.\root\cimv2, or a different scope path if
        ///       the default was changed. 
        /// 
        public static ManagementPath DefaultPath 
        { 
            get { return ManagementPath.defaultPath; }
            set { ManagementPath.defaultPath = value; } 
        }

        //private members
        private IWbemPath       wmiPath; 

        private IWbemPath CreateWbemPath(string path) 
        { 
            IWbemPath wbemPath = (IWbemPath)MTAHelper.CreateInMTA(typeof(WbemDefPath));//new WbemDefPath();
            SetWbemPath(wbemPath, path); 
            return wbemPath;
        }

        private void SetWbemPath(string path) 
        {
            // Test/utilize isWbemPathShared *only* on public + internal members! 
            if (wmiPath == null) 
                wmiPath = CreateWbemPath(path);
            else 
                SetWbemPath(wmiPath, path);
        }

        private static void SetWbemPath(IWbemPath wbemPath, string path) 
        {
            if (null != wbemPath) 
            { 
                uint flags = (uint) tag_WBEM_PATH_CREATE_FLAG.WBEMPATH_CREATE_ACCEPT_ALL;
 
                //For now we have to special-case the "root" namespace -
                //  this is because in the case of "root", the path parser cannot tell whether
                //  this is a namespace name or a class name
                // 
                if (String.Compare(path, "root", StringComparison.OrdinalIgnoreCase) == 0)
                    flags = flags | (uint) tag_WBEM_PATH_CREATE_FLAG.WBEMPATH_TREAT_SINGLE_IDENT_AS_NS; 
 
                int status = wbemPath.SetText_(flags, path);
 
                if (status < 0)
                {
                    if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                    else
                        Marshal.ThrowExceptionForHR(status); 
                } 
            }
        } 

        private string GetWbemPath()
        {
            return GetWbemPath(this.wmiPath); 
        }
 
        private static string GetWbemPath(IWbemPath wbemPath) 
        {
            String pathStr = String.Empty; 

            if (null != wbemPath)
            {
                // 

 
 

 
                int flags = (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_SERVER_TOO;
                uint nCount = 0;

                int status = (int)ManagementStatus.NoError; 

                status = wbemPath.GetNamespaceCount_(out nCount); 
 
                if (status >= 0)
                { 
                    if (0 == nCount)
                        flags = (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_RELATIVE_ONLY;

                    // Get the space we need to reserve 
                    uint bufLen = 0;
 
                    status = wbemPath.GetText_(flags, ref bufLen, null); 

                    if (status >= 0 && 0 < bufLen) 
                    {
                        pathStr = new String ('0', (int) bufLen-1);
                        status = wbemPath.GetText_(flags, ref bufLen, pathStr);
                    } 
                }
 
                if (status < 0) 
                {
                    if (status == (int)tag_WBEMSTATUS.WBEM_E_INVALID_PARAMETER) 
                    {
                        // Interpret as unspecified - return ""
                    }
 
                    else if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                    else 
                        Marshal.ThrowExceptionForHR(status);
                } 
            }

            return pathStr;
        } 

        private void ClearKeys (bool setAsSingleton) 
        { 
            // Test/utilize isWbemPathShared *only* on public + internal members!
            int status = (int)ManagementStatus.NoError; 

            try
            {
                if (null != wmiPath) 
                {
                    IWbemPathKeyList keyList = null; 
                    status = wmiPath.GetKeyList_(out keyList); 

                    if (null != keyList) 
                    {
                        status = keyList.RemoveAllKeys_(0);
                        if ((status & 0x80000000) == 0)
                        { 
                            sbyte bSingleton = (setAsSingleton) ? (sbyte)(-1) : (sbyte)0;
                            status = keyList.MakeSingleton_(bSingleton); 
                            FireIdentifierChanged ();       // 
                        }
                    } 
                }
            }
            catch (COMException e)
            { 
                ManagementException.ThrowWithExtendedInfo(e);
            } 
 
            if ((status & 0xfffff000) == 0x80041000)
            { 
                ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
            }
            else if ((status & 0x80000000) != 0)
            { 
                Marshal.ThrowExceptionForHR(status);
            } 
        } 

        internal bool IsEmpty 
        {
            get
            {
                return (Path.Length == 0 ) ; 
            }
        } 
 

        // 
        // Methods
        //

        ///  
        ///     Sets the path as a new class path. This means that the path must have
        ///       a class name but not key values. 
        ///  
        public void SetAsClass ()
        { 
            if (IsClass || IsInstance)
            {
                // Check if this IWbemPath is shared among multiple managed objects.
                // With this write, it will have to maintain its own copy. 
                if (isWbemPathShared)
                { 
                    wmiPath = CreateWbemPath(this.GetWbemPath()); 
                    isWbemPathShared = false;
                } 

                ClearKeys (false);
            }
            else 
                throw new ManagementException (ManagementStatus.InvalidOperation, null, null);
        } 
 
        /// 
        ///     Sets the path as a new singleton object path. This means that it is a path to an instance but 
        ///       there are no key values.
        /// 
        public void SetAsSingleton ()
        { 
            if (IsClass || IsInstance)
            { 
                // Check if this IWbemPath is shared among multiple managed objects. 
                // With this write, it will have to maintain its own copy.
                if (isWbemPathShared) 
                {
                    wmiPath = CreateWbemPath(this.GetWbemPath());
                    isWbemPathShared = false;
                } 

                ClearKeys (true); 
            } 
            else
                throw new ManagementException (ManagementStatus.InvalidOperation, null, null); 
        }

        //
        // Properties 
        //
 
        ///  
        ///     Gets or sets the string representation of the full path in the object.
        ///  
        /// 
        ///    A string containing the full path
        ///       represented in this object.
        ///  
        [RefreshProperties(RefreshProperties.All)]
        public string Path 
        { 
            get
            { 
                return this.GetWbemPath();
            }
            set
            { 
                try
                { 
                    // Before overwriting, check it's OK 
                    // Note, we've never done such validation, should we?
                    // 
                    // Check if this IWbemPath is shared among multiple managed objects.
                    // With this write, it will have to maintain its own copy.
                    if (isWbemPathShared)
                    { 
                        wmiPath = CreateWbemPath(this.GetWbemPath());
                        isWbemPathShared = false; 
                    } 

                    this.SetWbemPath(value); 
                }
                catch
                {
                    throw new ArgumentOutOfRangeException ("value"); 
                }
                FireIdentifierChanged(); 
            } 
        }
 
        /// 
        ///     Gets or sets the relative path: class name and keys only.
        /// 
        ///  
        ///    A string containing the relative
        ///    path (not including the server and namespace portions) represented in this 
        ///    object. 
        /// 
        [RefreshProperties(RefreshProperties.All)] 
        public string RelativePath
        {
            get
            { 
                String pathStr = String.Empty;
 
                if (null != wmiPath) 
                {
                    // Get the space we need to reserve 
                    uint bufLen = 0;
                    int status = wmiPath.GetText_(
                        (int) tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_RELATIVE_ONLY,
                        ref bufLen, 
                        null);
 
                    if (status >= 0 && 0 < bufLen) 
                    {
                        pathStr = new String ('0', (int) bufLen-1); 
                        status = wmiPath.GetText_(
                            (int) tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_RELATIVE_ONLY,
                            ref bufLen,
                            pathStr); 
                    }
 
                    if (status < 0) 
                    {
                        if (status == (int)tag_WBEMSTATUS.WBEM_E_INVALID_PARAMETER) 
                        {
                            // Interpret as unspecified - return ""
                        }
                        else if ((status & 0xfffff000) == 0x80041000) 
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                        else 
                            Marshal.ThrowExceptionForHR(status); 
                    }
                } 

                return pathStr;
            }
 
            set
            { 
                try 
                {
                    // No need for isWbemPathShared here since internal SetRelativePath 
                    // always creates a new copy.
                    SetRelativePath (value);
                }
                catch (COMException) 
                {
                    throw new ArgumentOutOfRangeException ("value"); 
                } 
                FireIdentifierChanged();
            } 
        }

        internal void SetRelativePath (string relPath)
        { 
            // No need for isWbemPathShared here since internal SetRelativePath
            // always creates a new copy. 
            ManagementPath newPath = new ManagementPath (relPath); 
            newPath.NamespacePath = this.GetNamespacePath((int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY);
            newPath.Server = this.Server; 
            wmiPath = newPath.wmiPath;
        }

        //Used to update the relative path when the user changes any key properties 
        internal void UpdateRelativePath(string relPath)
        { 
            if (relPath == null) 
                return;
 
            //Get the server & namespace part from the existing path, and concatenate the given relPath.
            //NOTE : we need to do this because IWbemPath doesn't have a function to set the relative path alone...
            string newPath = String.Empty;
            string nsPath = this.GetNamespacePath((int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY); 

            if (nsPath.Length>0 ) 
                newPath = String.Concat(nsPath, ":", relPath); 
            else
                newPath = relPath; 

            // Check if this IWbemPath is shared among multiple managed objects.
            // With this write, it will have to maintain its own copy.
            if (isWbemPathShared) 
            {
                wmiPath = CreateWbemPath(this.GetWbemPath()); 
                isWbemPathShared = false; 
            }
 
            this.SetWbemPath(newPath);
        }

 
        /// 
        ///    Gets or sets the server part of the path. 
        ///  
        /// 
        ///    A string containing the server name 
        ///    from the path represented in this object.
        /// 
        [RefreshProperties(RefreshProperties.All)]
        public string Server 
        {
            get 
            { 
                String pathStr = String.Empty;
 
                if (null != wmiPath)
                {

                    uint uLen = 0; 
                    int status = wmiPath.GetServer_(ref uLen, null);
 
                    if (status >= 0 && 0 < uLen) 
                    {
                        pathStr = new String ('0', (int) uLen-1); 
                        status = wmiPath.GetServer_(ref uLen, pathStr);
                    }

                    if (status < 0) 
                    {
                        if (status == (int)tag_WBEMSTATUS.WBEM_E_NOT_AVAILABLE) 
                        { 
                            // Interpret as unspecified - return ""
                        } 
                        else if ((status & 0xfffff000) == 0x80041000)
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                        else
                            Marshal.ThrowExceptionForHR(status); 
                    }
                } 
 
                return pathStr;
            } 
            set
            {
                String oldValue = Server;
 
                // Only set if changed
                if (0 != String.Compare(oldValue,value,StringComparison.OrdinalIgnoreCase)) 
                { 
                    if (null == wmiPath)
                        wmiPath = (IWbemPath)MTAHelper.CreateInMTA(typeof(WbemDefPath));//new WbemDefPath (); 
                    else if (isWbemPathShared)
                    {
                        // Check if this IWbemPath is shared among multiple managed objects.
                        // With this write, it will have to maintain its own copy. 
                        wmiPath = CreateWbemPath(this.GetWbemPath());
                        isWbemPathShared = false; 
                    } 

                    int status = wmiPath.SetServer_(value); 

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

        internal string SetNamespacePath(string nsPath, out bool bChange) 
        { 
            int         status = (int)ManagementStatus.NoError;
            string      nsOrg = null; 
            string      nsNew = null;
            IWbemPath   wmiPathTmp = null;
            bChange = false;
 
            Debug.Assert(nsPath != null);
 
            //Do some validation on the path to make sure it is a valid namespace path (at least syntactically) 
            if (!IsValidNamespaceSyntax(nsPath))
                ManagementException.ThrowWithExtendedInfo((ManagementStatus)tag_WBEMSTATUS.WBEM_E_INVALID_NAMESPACE); 

            wmiPathTmp = CreateWbemPath(nsPath);
            if (wmiPath == null)
                wmiPath = this.CreateWbemPath(""); 
            else if (isWbemPathShared)
            { 
                // Check if this IWbemPath is shared among multiple managed objects. 
                // With this write, it will have to maintain its own copy.
                wmiPath = CreateWbemPath(this.GetWbemPath()); 
                isWbemPathShared = false;
            }

            nsOrg = GetNamespacePath(wmiPath, 
                (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_NAMESPACE_ONLY);
            nsNew = GetNamespacePath(wmiPathTmp, 
                (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_NAMESPACE_ONLY); 

            if (String.Compare(nsOrg, nsNew, StringComparison.OrdinalIgnoreCase) != 0) 
            {
                wmiPath.RemoveAllNamespaces_();                                 // Out with the old... Ignore status code.

                // Add the new ones in 
                bChange = true;                                                 // Now dirty from above.
                uint nCount = 0; 
                status = wmiPathTmp.GetNamespaceCount_(out nCount); 

                if (status >= 0) 
                {
                    for (uint i = 0; i < nCount; i++)
                    {
                        uint uLen = 0; 
                        status = wmiPathTmp.GetNamespaceAt_(i, ref uLen, null);
 
                        if (status >= 0) 
                        {
                            string nSpace = new String('0', (int) uLen-1); 
                            status = wmiPathTmp.GetNamespaceAt_(i, ref uLen, nSpace);
                            if (status >= 0)
                            {
                                status = wmiPath.SetNamespaceAt_(i, nSpace); 

                                if (status < 0) 
                                    break; 
                            }
                            else 
                                break;
                        }
                        else
                            break; 
                    }
                } 
            } 
            else {;}    // Continue on. Could have different server name, same ns specified.
 
            //
            // Update Server property if specified in the namespace.
            // eg: "\\MyServer\root\cimv2".
            // 
            if (status >= 0 && nsPath.Length > 1 &&
                (nsPath[0] == '\\' && nsPath[1] == '\\' || 
                nsPath[0] == '/'  && nsPath[1] == '/')) 
            {
                uint uLen = 0; 
                status = wmiPathTmp.GetServer_(ref uLen, null);

                if (status >= 0 && uLen > 0)
                { 
                    string serverNew = new String ('0', (int) uLen-1);
                    status = wmiPathTmp.GetServer_(ref uLen, serverNew); 
 
                    if (status >= 0)
                    { 
                        // Compare server name on this object, if specified, to the caller's.
                        //     Update this object if different or unspecified.
                        uLen = 0;
                        status = wmiPath.GetServer_(ref uLen, null);            // NB: Cannot use property get since it may throw. 

                        if (status >= 0) 
                        { 
                            string serverOrg = new String('0', (int)uLen-1);
                            status = wmiPath.GetServer_(ref uLen, serverOrg); 

                            if (status >= 0 && String.Compare(serverOrg, serverNew, StringComparison.OrdinalIgnoreCase) != 0)
                                status = wmiPath.SetServer_(serverNew);
                        } 
                        else if (status == (int)tag_WBEMSTATUS.WBEM_E_NOT_AVAILABLE)
                        { 
                            status = wmiPath.SetServer_(serverNew); 
                            if (status >= 0)
                                bChange = true; 
                        }
                    }
                }
                else if (status == (int)tag_WBEMSTATUS.WBEM_E_NOT_AVAILABLE)    // No caller-supplied server name; 
                    status = (int)ManagementStatus.NoError;                     // Ignore error.
            } 
 
            if (status < 0)
            { 
                if ((status & 0xfffff000) == 0x80041000)
                    ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                else
                    Marshal.ThrowExceptionForHR(status); 
            }
 
            return nsNew; 
        }
 
        internal string GetNamespacePath(int flags)
        {
            return GetNamespacePath(wmiPath, flags);
        } 

        internal static string GetNamespacePath(IWbemPath wbemPath, int flags) 
        { 
            string pathStr = String.Empty;
 
            if (null != wbemPath)
            {
                //
 

 
 

                uint nCount = 0; 
                int status = (int)ManagementStatus.NoError;

                status = wbemPath.GetNamespaceCount_(out nCount);
 
                if (status >= 0 && nCount > 0)
                { 
                    // Get the space we need to reserve 
                    uint bufLen = 0;
                    status = wbemPath.GetText_(flags, ref bufLen, null); 

                    if (status >= 0 && bufLen > 0)
                    {
                        pathStr = new String ('0', (int) bufLen-1); 
                        status = wbemPath.GetText_(flags, ref bufLen, pathStr);
                    } 
                } 

                if (status < 0) 
                {
                    if (status == (int)tag_WBEMSTATUS.WBEM_E_INVALID_PARAMETER)
                    {
                        // Interpret as unspecified - return "" 
                    }
                    else if ((status & 0xfffff000) == 0x80041000) 
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                    else
                        Marshal.ThrowExceptionForHR(status); 
                }
            }

            return pathStr; 
        }
 
        ///  
        ///    Gets or sets the namespace part of the path. Note that this does not include
        ///       the server name, which can be retrieved separately. 
        /// 
        /// 
        ///    A string containing the namespace
        ///    portion of the path represented in this object. 
        /// 
        [RefreshProperties(RefreshProperties.All)] 
        public string NamespacePath 
        {
            get 
            {
                return GetNamespacePath((int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_NAMESPACE_ONLY);
            }
            set 
            {
                bool bChange = false; 
 
                try
                { 
                    // isWbemPathShared handled in internal SetNamespacePath.
                    SetNamespacePath(value, out bChange);
                }
                catch (COMException) 
                {
                    throw new ArgumentOutOfRangeException ("value"); 
                } 

                if (bChange) 
                    FireIdentifierChanged();
            }
        }
 
        /// 
        ///    Gets or sets the class portion of the path. 
        ///  
        /// 
        ///    A string containing the name of the 
        ///    class.
        /// 
        [RefreshProperties(RefreshProperties.All)]
        public string ClassName 
        {
            get 
            { 
                return internalClassName;
            } 
            set
            {
                String oldValue = ClassName;
 
                // Only set if changed
                if (0 != String.Compare(oldValue,value,StringComparison.OrdinalIgnoreCase)) 
                { 
                    // isWbemPathShared handled in internal className property accessor.
                    internalClassName = value; 
                    FireIdentifierChanged();
                }
            }
        } 

        internal string internalClassName 
        { 
            get
            { 
                String pathStr = String.Empty;
                int status = (int)ManagementStatus.NoError;

                if (null != wmiPath) 
                {
                    uint bufLen = 0; 
                    status = wmiPath.GetClassName_(ref bufLen, null); 

                    if (status >= 0 && 0 < bufLen) 
                    {
                        pathStr = new String ('0', (int) bufLen-1);
                        status = wmiPath.GetClassName_(ref bufLen, pathStr);
 
                        if (status < 0)
                            pathStr = String.Empty; 
                    } 
                }
 
                return pathStr;
            }
            set
            { 
                int status = (int)ManagementStatus.NoError;
 
                if (wmiPath == null) 
                    wmiPath = (IWbemPath)MTAHelper.CreateInMTA(typeof(WbemDefPath));//new WbemDefPath();
                else if (isWbemPathShared) 
                {
                    // Check if this IWbemPath is shared among multiple managed objects.
                    // With this write, it will have to maintain its own copy.
                    wmiPath = CreateWbemPath(this.GetWbemPath()); 
                    isWbemPathShared = false;
                } 
 
                try
                { 
                    status = wmiPath.SetClassName_(value);
                }
                catch (COMException)
                {       // 
                    throw new ArgumentOutOfRangeException ("value");
                } 
 
                if (status < 0)
                { 
                    if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                    else
                        Marshal.ThrowExceptionForHR(status); 
                }
            } 
        } 

        ///  
        ///    Gets or sets a value indicating whether this is a class path.
        /// 
        /// 
        ///  if this is a class path; otherwise, 
        /// .
        ///  
        public bool IsClass 
        {
            get 
            {
                if (null == wmiPath)
                    return false;
 
                ulong uInfo = 0;
                int status = wmiPath.GetInfo_(0, out uInfo); 
 
                if (status < 0)
                { 
                    if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                    else
                        Marshal.ThrowExceptionForHR(status); 
                }
 
                return (0 != (uInfo & (ulong)tag_WBEM_PATH_STATUS_FLAG.WBEMPATH_INFO_IS_CLASS_REF)); 
            }
        } 

        /// 
        ///    Gets or sets a value indicating whether this is an instance path.
        ///  
        /// 
        ///  if this is an instance path; otherwise, 
        /// . 
        /// 
        public bool IsInstance 
        {
            get
            {
                if (null == wmiPath) 
                    return false;
 
                ulong uInfo = 0; 
                int status = wmiPath.GetInfo_(0, out uInfo);
 
                if (status < 0)
                {
                    if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                    else
                        Marshal.ThrowExceptionForHR(status); 
                } 

                return (0 != (uInfo & (ulong)tag_WBEM_PATH_STATUS_FLAG.WBEMPATH_INFO_IS_INST_REF)); 
            }
        }

        ///  
        ///    Gets or sets a value indicating whether this is a singleton instance path.
        ///  
        ///  
        ///  if this is a singleton instance path; otherwise,
        /// . 
        /// 
        public bool IsSingleton
        {
            get 
            {
                if (null == wmiPath) 
                    return false; 

                ulong uInfo = 0; 
                int status = wmiPath.GetInfo_(0, out uInfo);

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

                return (0 != (uInfo & (ulong)tag_WBEM_PATH_STATUS_FLAG.WBEMPATH_INFO_IS_SINGLETON));
            }
        } 
    }
 
    ///  
    /// Converts a String to a ManagementPath
    ///  
    class ManagementPathConverter : ExpandableObjectConverter
    {

        ///  
        /// Determines if this converter can convert an object in the given source type to the native type of the converter.
        ///  
        /// An ITypeDescriptorContext that provides a format context. 
        /// A Type that represents the type you wish to convert from.
        ///  
        ///    true if this converter can perform the conversion; otherwise, false.
        /// 
        public override Boolean CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        { 
            if ((sourceType == typeof(ManagementPath)))
            { 
                return true; 
            }
            return base.CanConvertFrom(context,sourceType); 
        }

        /// 
        /// Gets a value indicating whether this converter can convert an object to the given destination type using the context. 
        /// 
        /// An ITypeDescriptorContext that provides a format context. 
        /// A Type that represents the type you wish to convert to. 
        /// 
        ///    true if this converter can perform the conversion; otherwise, false. 
        /// 
        public override Boolean CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if ((destinationType == typeof(InstanceDescriptor))) 
            {
                return true; 
            } 
            return base.CanConvertTo(context,destinationType);
        } 

        /// 
        ///      Converts the given object to another type.  The most common types to convert
        ///      are to and from a string object.  The default implementation will make a call 
        ///      to ToString on the object if the object is valid and if the destination
        ///      type is string.  If this cannot convert to the desitnation type, this will 
        ///      throw a NotSupportedException. 
        /// 
        /// An ITypeDescriptorContext that provides a format context. 
        /// A CultureInfo object. If a null reference (Nothing in Visual Basic) is passed, the current culture is assumed.
        /// The Object to convert.
        /// The Type to convert the value parameter to.
        /// An Object that represents the converted value. 
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        { 
 
            if (destinationType == null)
            { 
                throw new ArgumentNullException("destinationType");
            }

            if (value is ManagementPath && destinationType == typeof(InstanceDescriptor)) 
            {
                ManagementPath obj = ((ManagementPath)(value)); 
                ConstructorInfo ctor = typeof(ManagementPath).GetConstructor(new Type[] {typeof(System.String)}); 
                if (ctor != null)
                { 
                    return new InstanceDescriptor(ctor, new object[] {obj.Path});
                }
            }
            return base.ConvertTo(context,culture,value,destinationType); 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design; 
using System.Runtime.InteropServices;
using WbemUtilities_v1; 
using WbemClient_v1; 
using System.Globalization;
using System.Reflection; 
using System.ComponentModel.Design.Serialization;

namespace System.Management
{ 
    /// 
    ///    Provides a wrapper for parsing and building paths to WMI objects. 
    ///  
    /// 
    ///    using System; 
    /// using System.Management;
    ///
    /// // This sample displays all properties in a ManagementPath object.
    /// 
    /// class Sample_ManagementPath
    /// { 
    ///     public static int Main(string[] args) { 
    ///         ManagementPath path = new ManagementPath( "\\\\MyServer\\MyNamespace:Win32_logicaldisk='c:'");
    /// 
    ///         // Results of full path parsing
    ///         Console.WriteLine("Path: " + path.Path);
    ///         Console.WriteLine("RelativePath: " + path.RelativePath);
    ///         Console.WriteLine("Server: " + path.Server); 
    ///         Console.WriteLine("NamespacePath: " + path.NamespacePath);
    ///         Console.WriteLine("ClassName: " + path.ClassName); 
    ///         Console.WriteLine("IsClass: " + path.IsClass); 
    ///         Console.WriteLine("IsInstance: " + path.IsInstance);
    ///         Console.WriteLine("IsSingleton: " + path.IsSingleton); 
    ///
    ///         // Change a portion of the full path
    ///         path.Server = "AnotherServer";
    ///         Console.WriteLine("New Path: " + path.Path); 
    ///         return 0;
    ///    } 
    /// } 
    ///    
    ///    Imports System 
    /// Imports System.Management
    ///
    /// 'This sample displays all properties in a ManagementPath object.
    /// Class Sample_ManagementPath Overloads 
    ///     Public Shared Function Main(args() As String) As Integer
    ///         Dim path As _ New 
    ///         ManagementPath("\\MyServer\MyNamespace:Win32_LogicalDisk='c:'") 
    ///
    ///         ' Results of full path parsing 
    ///         Console.WriteLine("Path: " & path.Path)
    ///         Console.WriteLine("RelativePath: " & path.RelativePath)
    ///         Console.WriteLine("Server: " & path.Server)
    ///         Console.WriteLine("NamespacePath: " & path.NamespacePath) 
    ///         Console.WriteLine("ClassName: " & path.ClassName)
    ///         Console.WriteLine("IsClass: " & path.IsClass) 
    ///         Console.WriteLine("IsInstance: " & path.IsInstance) 
    ///         Console.WriteLine("IsSingleton: " & path.IsSingleton)
    /// 
    ///         ' Change a portion of the full path
    ///         path.Server= "AnotherServer"
    ///         Console.WriteLine("New Path: " & path.Path)
    ///         Return 0 
    ///     End Function
    /// End Class 
    ///     
    /// 
    [TypeConverter(typeof(ManagementPathConverter ))] 
    public class ManagementPath : ICloneable
    {
        private static ManagementPath defaultPath = new ManagementPath("//./root/cimv2");
 
        //Used to minimize the cases in which new wbemPath (WMI object path parser) objects need to be constructed
        //This is done for performance reasons. 
        private bool   isWbemPathShared = false; 

        internal event IdentifierChangedEventHandler IdentifierChanged; 

        //Fires IdentifierChanged event
        private void FireIdentifierChanged()
        { 
            if (IdentifierChanged != null)
                IdentifierChanged(this, null); 
        } 

        //internal factory 
        /// 
        /// Internal static "factory" method for making a new ManagementPath
        /// from the system property of a WMI object
        ///  
        /// The WMI object whose __PATH property will
        /// be used to supply the returned object 
        internal static string GetManagementPath ( 
            IWbemClassObjectFreeThreaded wbemObject)
        { 
            string path = null;
            int status  = (int)ManagementStatus.Failed;

            if (null != wbemObject) 
            {
                int dummy1 = 0, dummy2 = 0; 
                object val = null; 
                status = wbemObject.Get_ ("__PATH", 0, ref val, ref dummy1, ref dummy2);
                if ((status < 0) || (val == System.DBNull.Value)) 
                {
                    //try to get the relpath instead
                    status = wbemObject.Get_ ("__RELPATH", 0, ref val, ref dummy1, ref dummy2);
                    if (status < 0) 
                    {
                        if ((status & 0xfffff000) == 0x80041000) 
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                        else
                            Marshal.ThrowExceptionForHR(status); 
                    }
                }

                if (System.DBNull.Value == val) 
                    path = null;
                else 
                    path = (string)val; 
            }
 
            return path;
        }

        //Used internally to check whether a string passed in as a namespace is indeed syntactically correct 
        //for a namespace (e.g. either has "\" or "/" in it or is the special case of "root")
        //This doesn't check for the existance of that namespace, nor does it guarrantee correctness. 
        internal static bool IsValidNamespaceSyntax(string nsPath) 
        {
            if (nsPath.Length != 0) 
            {
                // Any path separators present?
                char[] pathSeparators = { '\\', '/' };
                if (nsPath.IndexOfAny(pathSeparators) == -1) 
                {
                    // No separators.  The only valid path is "root". 
                    if (String.Compare("root", nsPath, StringComparison.OrdinalIgnoreCase) != 0) 
                        return false;
                } 
            }

            return true;
        } 

 
        internal static ManagementPath _Clone(ManagementPath path) 
        {
            return ManagementPath._Clone(path, null); 
        }

        internal static ManagementPath _Clone(ManagementPath path, IdentifierChangedEventHandler handler)
        { 
            ManagementPath pathTmp = new ManagementPath();
 
            // Wire up change handler chain. Use supplied handler, if specified; 
            // otherwise, default to that of the path argument.
            if (handler != null) 
                pathTmp.IdentifierChanged = handler;

            // Assign ManagementPath IWbemPath to this.wmiPath.
            // Optimization for performance : As long as the path is only read, we share this interface. 
            // On the first write, a private copy will be needed;
            // isWbemPathShared signals ManagementPath to create such a copy at write-time. 
            if (path != null && path.wmiPath != null) 
            {
                pathTmp.wmiPath = path.wmiPath; 
                pathTmp.isWbemPathShared = path.isWbemPathShared = true;
            }

            return pathTmp; 
        }
 
        ///  
        ///    Initializes a new instance
        ///    of the  class. 
        /// 
        /// 
        ///  Initializes a new instance of the  class that is empty. This is the default constructor.
        ///  
        public ManagementPath () : this ((string) null) {}
 
        ///  
        /// Initializes a new instance of the  class for the given path.
        ///  
        ///  The object path. 
        public ManagementPath(string path)
        {
            if ((null != path) && (0 < path.Length)) 
                wmiPath = CreateWbemPath(path);
        } 
 
        /// 
        ///    Returns the full object path as the string representation. 
        /// 
        /// 
        ///    A string containing the full object
        ///    path represented by this object. This value is equivalent to the value of the 
        ///  property.
        ///  
        public override string ToString () 
        {
            return this.Path; 
        }

        /// 
        /// Returns a copy of the . 
        /// 
        ///  
        ///    The cloned object. 
        /// 
        public ManagementPath Clone () 
        {
            return new ManagementPath (Path);
        }
 
        /// 
        /// Standard Clone returns a copy of this ManagementPath as a generic "Object" type 
        ///  
        /// 
        ///    The cloned object. 
        /// 
        object ICloneable.Clone ()
        {
            return Clone (); 
        }
 
        ///  
        ///    Gets or sets the default scope path used when no scope is specified.
        ///       The default scope is /-/ \\.\root\cimv2, and can be changed by setting this property. 
        /// 
        /// 
        ///    By default the scope value is /-/ \\.\root\cimv2, or a different scope path if
        ///       the default was changed. 
        /// 
        public static ManagementPath DefaultPath 
        { 
            get { return ManagementPath.defaultPath; }
            set { ManagementPath.defaultPath = value; } 
        }

        //private members
        private IWbemPath       wmiPath; 

        private IWbemPath CreateWbemPath(string path) 
        { 
            IWbemPath wbemPath = (IWbemPath)MTAHelper.CreateInMTA(typeof(WbemDefPath));//new WbemDefPath();
            SetWbemPath(wbemPath, path); 
            return wbemPath;
        }

        private void SetWbemPath(string path) 
        {
            // Test/utilize isWbemPathShared *only* on public + internal members! 
            if (wmiPath == null) 
                wmiPath = CreateWbemPath(path);
            else 
                SetWbemPath(wmiPath, path);
        }

        private static void SetWbemPath(IWbemPath wbemPath, string path) 
        {
            if (null != wbemPath) 
            { 
                uint flags = (uint) tag_WBEM_PATH_CREATE_FLAG.WBEMPATH_CREATE_ACCEPT_ALL;
 
                //For now we have to special-case the "root" namespace -
                //  this is because in the case of "root", the path parser cannot tell whether
                //  this is a namespace name or a class name
                // 
                if (String.Compare(path, "root", StringComparison.OrdinalIgnoreCase) == 0)
                    flags = flags | (uint) tag_WBEM_PATH_CREATE_FLAG.WBEMPATH_TREAT_SINGLE_IDENT_AS_NS; 
 
                int status = wbemPath.SetText_(flags, path);
 
                if (status < 0)
                {
                    if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                    else
                        Marshal.ThrowExceptionForHR(status); 
                } 
            }
        } 

        private string GetWbemPath()
        {
            return GetWbemPath(this.wmiPath); 
        }
 
        private static string GetWbemPath(IWbemPath wbemPath) 
        {
            String pathStr = String.Empty; 

            if (null != wbemPath)
            {
                // 

 
 

 
                int flags = (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_SERVER_TOO;
                uint nCount = 0;

                int status = (int)ManagementStatus.NoError; 

                status = wbemPath.GetNamespaceCount_(out nCount); 
 
                if (status >= 0)
                { 
                    if (0 == nCount)
                        flags = (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_RELATIVE_ONLY;

                    // Get the space we need to reserve 
                    uint bufLen = 0;
 
                    status = wbemPath.GetText_(flags, ref bufLen, null); 

                    if (status >= 0 && 0 < bufLen) 
                    {
                        pathStr = new String ('0', (int) bufLen-1);
                        status = wbemPath.GetText_(flags, ref bufLen, pathStr);
                    } 
                }
 
                if (status < 0) 
                {
                    if (status == (int)tag_WBEMSTATUS.WBEM_E_INVALID_PARAMETER) 
                    {
                        // Interpret as unspecified - return ""
                    }
 
                    else if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                    else 
                        Marshal.ThrowExceptionForHR(status);
                } 
            }

            return pathStr;
        } 

        private void ClearKeys (bool setAsSingleton) 
        { 
            // Test/utilize isWbemPathShared *only* on public + internal members!
            int status = (int)ManagementStatus.NoError; 

            try
            {
                if (null != wmiPath) 
                {
                    IWbemPathKeyList keyList = null; 
                    status = wmiPath.GetKeyList_(out keyList); 

                    if (null != keyList) 
                    {
                        status = keyList.RemoveAllKeys_(0);
                        if ((status & 0x80000000) == 0)
                        { 
                            sbyte bSingleton = (setAsSingleton) ? (sbyte)(-1) : (sbyte)0;
                            status = keyList.MakeSingleton_(bSingleton); 
                            FireIdentifierChanged ();       // 
                        }
                    } 
                }
            }
            catch (COMException e)
            { 
                ManagementException.ThrowWithExtendedInfo(e);
            } 
 
            if ((status & 0xfffff000) == 0x80041000)
            { 
                ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
            }
            else if ((status & 0x80000000) != 0)
            { 
                Marshal.ThrowExceptionForHR(status);
            } 
        } 

        internal bool IsEmpty 
        {
            get
            {
                return (Path.Length == 0 ) ; 
            }
        } 
 

        // 
        // Methods
        //

        ///  
        ///     Sets the path as a new class path. This means that the path must have
        ///       a class name but not key values. 
        ///  
        public void SetAsClass ()
        { 
            if (IsClass || IsInstance)
            {
                // Check if this IWbemPath is shared among multiple managed objects.
                // With this write, it will have to maintain its own copy. 
                if (isWbemPathShared)
                { 
                    wmiPath = CreateWbemPath(this.GetWbemPath()); 
                    isWbemPathShared = false;
                } 

                ClearKeys (false);
            }
            else 
                throw new ManagementException (ManagementStatus.InvalidOperation, null, null);
        } 
 
        /// 
        ///     Sets the path as a new singleton object path. This means that it is a path to an instance but 
        ///       there are no key values.
        /// 
        public void SetAsSingleton ()
        { 
            if (IsClass || IsInstance)
            { 
                // Check if this IWbemPath is shared among multiple managed objects. 
                // With this write, it will have to maintain its own copy.
                if (isWbemPathShared) 
                {
                    wmiPath = CreateWbemPath(this.GetWbemPath());
                    isWbemPathShared = false;
                } 

                ClearKeys (true); 
            } 
            else
                throw new ManagementException (ManagementStatus.InvalidOperation, null, null); 
        }

        //
        // Properties 
        //
 
        ///  
        ///     Gets or sets the string representation of the full path in the object.
        ///  
        /// 
        ///    A string containing the full path
        ///       represented in this object.
        ///  
        [RefreshProperties(RefreshProperties.All)]
        public string Path 
        { 
            get
            { 
                return this.GetWbemPath();
            }
            set
            { 
                try
                { 
                    // Before overwriting, check it's OK 
                    // Note, we've never done such validation, should we?
                    // 
                    // Check if this IWbemPath is shared among multiple managed objects.
                    // With this write, it will have to maintain its own copy.
                    if (isWbemPathShared)
                    { 
                        wmiPath = CreateWbemPath(this.GetWbemPath());
                        isWbemPathShared = false; 
                    } 

                    this.SetWbemPath(value); 
                }
                catch
                {
                    throw new ArgumentOutOfRangeException ("value"); 
                }
                FireIdentifierChanged(); 
            } 
        }
 
        /// 
        ///     Gets or sets the relative path: class name and keys only.
        /// 
        ///  
        ///    A string containing the relative
        ///    path (not including the server and namespace portions) represented in this 
        ///    object. 
        /// 
        [RefreshProperties(RefreshProperties.All)] 
        public string RelativePath
        {
            get
            { 
                String pathStr = String.Empty;
 
                if (null != wmiPath) 
                {
                    // Get the space we need to reserve 
                    uint bufLen = 0;
                    int status = wmiPath.GetText_(
                        (int) tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_RELATIVE_ONLY,
                        ref bufLen, 
                        null);
 
                    if (status >= 0 && 0 < bufLen) 
                    {
                        pathStr = new String ('0', (int) bufLen-1); 
                        status = wmiPath.GetText_(
                            (int) tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_RELATIVE_ONLY,
                            ref bufLen,
                            pathStr); 
                    }
 
                    if (status < 0) 
                    {
                        if (status == (int)tag_WBEMSTATUS.WBEM_E_INVALID_PARAMETER) 
                        {
                            // Interpret as unspecified - return ""
                        }
                        else if ((status & 0xfffff000) == 0x80041000) 
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                        else 
                            Marshal.ThrowExceptionForHR(status); 
                    }
                } 

                return pathStr;
            }
 
            set
            { 
                try 
                {
                    // No need for isWbemPathShared here since internal SetRelativePath 
                    // always creates a new copy.
                    SetRelativePath (value);
                }
                catch (COMException) 
                {
                    throw new ArgumentOutOfRangeException ("value"); 
                } 
                FireIdentifierChanged();
            } 
        }

        internal void SetRelativePath (string relPath)
        { 
            // No need for isWbemPathShared here since internal SetRelativePath
            // always creates a new copy. 
            ManagementPath newPath = new ManagementPath (relPath); 
            newPath.NamespacePath = this.GetNamespacePath((int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY);
            newPath.Server = this.Server; 
            wmiPath = newPath.wmiPath;
        }

        //Used to update the relative path when the user changes any key properties 
        internal void UpdateRelativePath(string relPath)
        { 
            if (relPath == null) 
                return;
 
            //Get the server & namespace part from the existing path, and concatenate the given relPath.
            //NOTE : we need to do this because IWbemPath doesn't have a function to set the relative path alone...
            string newPath = String.Empty;
            string nsPath = this.GetNamespacePath((int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY); 

            if (nsPath.Length>0 ) 
                newPath = String.Concat(nsPath, ":", relPath); 
            else
                newPath = relPath; 

            // Check if this IWbemPath is shared among multiple managed objects.
            // With this write, it will have to maintain its own copy.
            if (isWbemPathShared) 
            {
                wmiPath = CreateWbemPath(this.GetWbemPath()); 
                isWbemPathShared = false; 
            }
 
            this.SetWbemPath(newPath);
        }

 
        /// 
        ///    Gets or sets the server part of the path. 
        ///  
        /// 
        ///    A string containing the server name 
        ///    from the path represented in this object.
        /// 
        [RefreshProperties(RefreshProperties.All)]
        public string Server 
        {
            get 
            { 
                String pathStr = String.Empty;
 
                if (null != wmiPath)
                {

                    uint uLen = 0; 
                    int status = wmiPath.GetServer_(ref uLen, null);
 
                    if (status >= 0 && 0 < uLen) 
                    {
                        pathStr = new String ('0', (int) uLen-1); 
                        status = wmiPath.GetServer_(ref uLen, pathStr);
                    }

                    if (status < 0) 
                    {
                        if (status == (int)tag_WBEMSTATUS.WBEM_E_NOT_AVAILABLE) 
                        { 
                            // Interpret as unspecified - return ""
                        } 
                        else if ((status & 0xfffff000) == 0x80041000)
                            ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                        else
                            Marshal.ThrowExceptionForHR(status); 
                    }
                } 
 
                return pathStr;
            } 
            set
            {
                String oldValue = Server;
 
                // Only set if changed
                if (0 != String.Compare(oldValue,value,StringComparison.OrdinalIgnoreCase)) 
                { 
                    if (null == wmiPath)
                        wmiPath = (IWbemPath)MTAHelper.CreateInMTA(typeof(WbemDefPath));//new WbemDefPath (); 
                    else if (isWbemPathShared)
                    {
                        // Check if this IWbemPath is shared among multiple managed objects.
                        // With this write, it will have to maintain its own copy. 
                        wmiPath = CreateWbemPath(this.GetWbemPath());
                        isWbemPathShared = false; 
                    } 

                    int status = wmiPath.SetServer_(value); 

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

        internal string SetNamespacePath(string nsPath, out bool bChange) 
        { 
            int         status = (int)ManagementStatus.NoError;
            string      nsOrg = null; 
            string      nsNew = null;
            IWbemPath   wmiPathTmp = null;
            bChange = false;
 
            Debug.Assert(nsPath != null);
 
            //Do some validation on the path to make sure it is a valid namespace path (at least syntactically) 
            if (!IsValidNamespaceSyntax(nsPath))
                ManagementException.ThrowWithExtendedInfo((ManagementStatus)tag_WBEMSTATUS.WBEM_E_INVALID_NAMESPACE); 

            wmiPathTmp = CreateWbemPath(nsPath);
            if (wmiPath == null)
                wmiPath = this.CreateWbemPath(""); 
            else if (isWbemPathShared)
            { 
                // Check if this IWbemPath is shared among multiple managed objects. 
                // With this write, it will have to maintain its own copy.
                wmiPath = CreateWbemPath(this.GetWbemPath()); 
                isWbemPathShared = false;
            }

            nsOrg = GetNamespacePath(wmiPath, 
                (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_NAMESPACE_ONLY);
            nsNew = GetNamespacePath(wmiPathTmp, 
                (int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_NAMESPACE_ONLY); 

            if (String.Compare(nsOrg, nsNew, StringComparison.OrdinalIgnoreCase) != 0) 
            {
                wmiPath.RemoveAllNamespaces_();                                 // Out with the old... Ignore status code.

                // Add the new ones in 
                bChange = true;                                                 // Now dirty from above.
                uint nCount = 0; 
                status = wmiPathTmp.GetNamespaceCount_(out nCount); 

                if (status >= 0) 
                {
                    for (uint i = 0; i < nCount; i++)
                    {
                        uint uLen = 0; 
                        status = wmiPathTmp.GetNamespaceAt_(i, ref uLen, null);
 
                        if (status >= 0) 
                        {
                            string nSpace = new String('0', (int) uLen-1); 
                            status = wmiPathTmp.GetNamespaceAt_(i, ref uLen, nSpace);
                            if (status >= 0)
                            {
                                status = wmiPath.SetNamespaceAt_(i, nSpace); 

                                if (status < 0) 
                                    break; 
                            }
                            else 
                                break;
                        }
                        else
                            break; 
                    }
                } 
            } 
            else {;}    // Continue on. Could have different server name, same ns specified.
 
            //
            // Update Server property if specified in the namespace.
            // eg: "\\MyServer\root\cimv2".
            // 
            if (status >= 0 && nsPath.Length > 1 &&
                (nsPath[0] == '\\' && nsPath[1] == '\\' || 
                nsPath[0] == '/'  && nsPath[1] == '/')) 
            {
                uint uLen = 0; 
                status = wmiPathTmp.GetServer_(ref uLen, null);

                if (status >= 0 && uLen > 0)
                { 
                    string serverNew = new String ('0', (int) uLen-1);
                    status = wmiPathTmp.GetServer_(ref uLen, serverNew); 
 
                    if (status >= 0)
                    { 
                        // Compare server name on this object, if specified, to the caller's.
                        //     Update this object if different or unspecified.
                        uLen = 0;
                        status = wmiPath.GetServer_(ref uLen, null);            // NB: Cannot use property get since it may throw. 

                        if (status >= 0) 
                        { 
                            string serverOrg = new String('0', (int)uLen-1);
                            status = wmiPath.GetServer_(ref uLen, serverOrg); 

                            if (status >= 0 && String.Compare(serverOrg, serverNew, StringComparison.OrdinalIgnoreCase) != 0)
                                status = wmiPath.SetServer_(serverNew);
                        } 
                        else if (status == (int)tag_WBEMSTATUS.WBEM_E_NOT_AVAILABLE)
                        { 
                            status = wmiPath.SetServer_(serverNew); 
                            if (status >= 0)
                                bChange = true; 
                        }
                    }
                }
                else if (status == (int)tag_WBEMSTATUS.WBEM_E_NOT_AVAILABLE)    // No caller-supplied server name; 
                    status = (int)ManagementStatus.NoError;                     // Ignore error.
            } 
 
            if (status < 0)
            { 
                if ((status & 0xfffff000) == 0x80041000)
                    ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                else
                    Marshal.ThrowExceptionForHR(status); 
            }
 
            return nsNew; 
        }
 
        internal string GetNamespacePath(int flags)
        {
            return GetNamespacePath(wmiPath, flags);
        } 

        internal static string GetNamespacePath(IWbemPath wbemPath, int flags) 
        { 
            string pathStr = String.Empty;
 
            if (null != wbemPath)
            {
                //
 

 
 

                uint nCount = 0; 
                int status = (int)ManagementStatus.NoError;

                status = wbemPath.GetNamespaceCount_(out nCount);
 
                if (status >= 0 && nCount > 0)
                { 
                    // Get the space we need to reserve 
                    uint bufLen = 0;
                    status = wbemPath.GetText_(flags, ref bufLen, null); 

                    if (status >= 0 && bufLen > 0)
                    {
                        pathStr = new String ('0', (int) bufLen-1); 
                        status = wbemPath.GetText_(flags, ref bufLen, pathStr);
                    } 
                } 

                if (status < 0) 
                {
                    if (status == (int)tag_WBEMSTATUS.WBEM_E_INVALID_PARAMETER)
                    {
                        // Interpret as unspecified - return "" 
                    }
                    else if ((status & 0xfffff000) == 0x80041000) 
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                    else
                        Marshal.ThrowExceptionForHR(status); 
                }
            }

            return pathStr; 
        }
 
        ///  
        ///    Gets or sets the namespace part of the path. Note that this does not include
        ///       the server name, which can be retrieved separately. 
        /// 
        /// 
        ///    A string containing the namespace
        ///    portion of the path represented in this object. 
        /// 
        [RefreshProperties(RefreshProperties.All)] 
        public string NamespacePath 
        {
            get 
            {
                return GetNamespacePath((int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_NAMESPACE_ONLY);
            }
            set 
            {
                bool bChange = false; 
 
                try
                { 
                    // isWbemPathShared handled in internal SetNamespacePath.
                    SetNamespacePath(value, out bChange);
                }
                catch (COMException) 
                {
                    throw new ArgumentOutOfRangeException ("value"); 
                } 

                if (bChange) 
                    FireIdentifierChanged();
            }
        }
 
        /// 
        ///    Gets or sets the class portion of the path. 
        ///  
        /// 
        ///    A string containing the name of the 
        ///    class.
        /// 
        [RefreshProperties(RefreshProperties.All)]
        public string ClassName 
        {
            get 
            { 
                return internalClassName;
            } 
            set
            {
                String oldValue = ClassName;
 
                // Only set if changed
                if (0 != String.Compare(oldValue,value,StringComparison.OrdinalIgnoreCase)) 
                { 
                    // isWbemPathShared handled in internal className property accessor.
                    internalClassName = value; 
                    FireIdentifierChanged();
                }
            }
        } 

        internal string internalClassName 
        { 
            get
            { 
                String pathStr = String.Empty;
                int status = (int)ManagementStatus.NoError;

                if (null != wmiPath) 
                {
                    uint bufLen = 0; 
                    status = wmiPath.GetClassName_(ref bufLen, null); 

                    if (status >= 0 && 0 < bufLen) 
                    {
                        pathStr = new String ('0', (int) bufLen-1);
                        status = wmiPath.GetClassName_(ref bufLen, pathStr);
 
                        if (status < 0)
                            pathStr = String.Empty; 
                    } 
                }
 
                return pathStr;
            }
            set
            { 
                int status = (int)ManagementStatus.NoError;
 
                if (wmiPath == null) 
                    wmiPath = (IWbemPath)MTAHelper.CreateInMTA(typeof(WbemDefPath));//new WbemDefPath();
                else if (isWbemPathShared) 
                {
                    // Check if this IWbemPath is shared among multiple managed objects.
                    // With this write, it will have to maintain its own copy.
                    wmiPath = CreateWbemPath(this.GetWbemPath()); 
                    isWbemPathShared = false;
                } 
 
                try
                { 
                    status = wmiPath.SetClassName_(value);
                }
                catch (COMException)
                {       // 
                    throw new ArgumentOutOfRangeException ("value");
                } 
 
                if (status < 0)
                { 
                    if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                    else
                        Marshal.ThrowExceptionForHR(status); 
                }
            } 
        } 

        ///  
        ///    Gets or sets a value indicating whether this is a class path.
        /// 
        /// 
        ///  if this is a class path; otherwise, 
        /// .
        ///  
        public bool IsClass 
        {
            get 
            {
                if (null == wmiPath)
                    return false;
 
                ulong uInfo = 0;
                int status = wmiPath.GetInfo_(0, out uInfo); 
 
                if (status < 0)
                { 
                    if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status);
                    else
                        Marshal.ThrowExceptionForHR(status); 
                }
 
                return (0 != (uInfo & (ulong)tag_WBEM_PATH_STATUS_FLAG.WBEMPATH_INFO_IS_CLASS_REF)); 
            }
        } 

        /// 
        ///    Gets or sets a value indicating whether this is an instance path.
        ///  
        /// 
        ///  if this is an instance path; otherwise, 
        /// . 
        /// 
        public bool IsInstance 
        {
            get
            {
                if (null == wmiPath) 
                    return false;
 
                ulong uInfo = 0; 
                int status = wmiPath.GetInfo_(0, out uInfo);
 
                if (status < 0)
                {
                    if ((status & 0xfffff000) == 0x80041000)
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)status); 
                    else
                        Marshal.ThrowExceptionForHR(status); 
                } 

                return (0 != (uInfo & (ulong)tag_WBEM_PATH_STATUS_FLAG.WBEMPATH_INFO_IS_INST_REF)); 
            }
        }

        ///  
        ///    Gets or sets a value indicating whether this is a singleton instance path.
        ///  
        ///  
        ///  if this is a singleton instance path; otherwise,
        /// . 
        /// 
        public bool IsSingleton
        {
            get 
            {
                if (null == wmiPath) 
                    return false; 

                ulong uInfo = 0; 
                int status = wmiPath.GetInfo_(0, out uInfo);

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

                return (0 != (uInfo & (ulong)tag_WBEM_PATH_STATUS_FLAG.WBEMPATH_INFO_IS_SINGLETON));
            }
        } 
    }
 
    ///  
    /// Converts a String to a ManagementPath
    ///  
    class ManagementPathConverter : ExpandableObjectConverter
    {

        ///  
        /// Determines if this converter can convert an object in the given source type to the native type of the converter.
        ///  
        /// An ITypeDescriptorContext that provides a format context. 
        /// A Type that represents the type you wish to convert from.
        ///  
        ///    true if this converter can perform the conversion; otherwise, false.
        /// 
        public override Boolean CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        { 
            if ((sourceType == typeof(ManagementPath)))
            { 
                return true; 
            }
            return base.CanConvertFrom(context,sourceType); 
        }

        /// 
        /// Gets a value indicating whether this converter can convert an object to the given destination type using the context. 
        /// 
        /// An ITypeDescriptorContext that provides a format context. 
        /// A Type that represents the type you wish to convert to. 
        /// 
        ///    true if this converter can perform the conversion; otherwise, false. 
        /// 
        public override Boolean CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if ((destinationType == typeof(InstanceDescriptor))) 
            {
                return true; 
            } 
            return base.CanConvertTo(context,destinationType);
        } 

        /// 
        ///      Converts the given object to another type.  The most common types to convert
        ///      are to and from a string object.  The default implementation will make a call 
        ///      to ToString on the object if the object is valid and if the destination
        ///      type is string.  If this cannot convert to the desitnation type, this will 
        ///      throw a NotSupportedException. 
        /// 
        /// An ITypeDescriptorContext that provides a format context. 
        /// A CultureInfo object. If a null reference (Nothing in Visual Basic) is passed, the current culture is assumed.
        /// The Object to convert.
        /// The Type to convert the value parameter to.
        /// An Object that represents the converted value. 
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        { 
 
            if (destinationType == null)
            { 
                throw new ArgumentNullException("destinationType");
            }

            if (value is ManagementPath && destinationType == typeof(InstanceDescriptor)) 
            {
                ManagementPath obj = ((ManagementPath)(value)); 
                ConstructorInfo ctor = typeof(ManagementPath).GetConstructor(new Type[] {typeof(System.String)}); 
                if (ctor != null)
                { 
                    return new InstanceDescriptor(ctor, new object[] {obj.Path});
                }
            }
            return base.ConvertTo(context,culture,value,destinationType); 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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