File: System\Management\ManagementScope.cs
Web Access
Project: src\src\runtime\src\libraries\System.Management\src\System.Management.csproj (System.Management)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.Win32;

namespace System.Management
{
    internal static class CompatSwitches
    {
        internal const string DotNetVersion = "v4.0.30319";
        private const string RegKeyLocation = @"SOFTWARE\Microsoft\.NETFramework\" + DotNetVersion;

        private static readonly object s_syncLock = new object();
        private static int s_allowManagementObjectQI;

        private const string c_WMIDisableCOMSecurity = "WMIDisableCOMSecurity";

        public static bool AllowIManagementObjectQI
        {
            get
            {
                if (s_allowManagementObjectQI == 0)
                {
                    lock (s_syncLock)
                    {
                        if (s_allowManagementObjectQI == 0)
                        {
                            s_allowManagementObjectQI = GetSwitchValueFromRegistry() ? 1 : -1;
                        }
                    }
                }

                return s_allowManagementObjectQI == 1 ? true : false;
            }
        }

        private static bool GetSwitchValueFromRegistry()
        {
            RegistryKey s_switchesRegKey = null;
            try
            {
                s_switchesRegKey = Registry.LocalMachine.OpenSubKey(RegKeyLocation);

                if (s_switchesRegKey == null)
                {
                    return false;
                }

                return ((int)s_switchesRegKey.GetValue(c_WMIDisableCOMSecurity, -1 /* default */) == 1);
            }

            // ignore exceptions so that we don't crash the process if we can't read the switch value
            catch (Exception e)
            {
                if (e is StackOverflowException ||
                    e is OutOfMemoryException ||
                    e is System.Threading.ThreadAbortException ||
                    e is AccessViolationException)
                    throw;
            }
            finally
            {
                // dispose of the key
                s_switchesRegKey?.Dispose();
            }

            // if for any reason we cannot retrieve the value of the switch from the Registry,
            // fallback to 'false' which is the secure behavior
            return false;
        }
    }

    internal static class WmiNetUtilsHelper
    {
        internal delegate int ResetSecurity(IntPtr hToken);
        internal delegate int SetSecurity([In][Out] ref bool pNeedtoReset, [In][Out] ref IntPtr pHandle);
        internal delegate int BlessIWbemServices([MarshalAs(UnmanagedType.Interface)] IWbemServices pIUnknown,
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                        IntPtr password,
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority,
                                                                        int impersonationLevel,
                                                                        int authenticationLevel);
        internal delegate int BlessIWbemServicesObject([MarshalAs(UnmanagedType.IUnknown)] object pIUnknown,
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                        IntPtr password,
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority,
                                                                        int impersonationLevel,
                                                                        int authenticationLevel);

        internal delegate int GetPropertyHandle(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszPropertyName, [Out] out int pType, [Out] out int plHandle);
        internal delegate int WritePropertyValue(int vFunc, IntPtr pWbemClassObject, [In] int lHandle, [In] int lNumBytes, [In][MarshalAs(UnmanagedType.LPWStr)] string str);
        internal delegate int GetQualifierSet(int vFunc, IntPtr pWbemClassObject, [Out] out IntPtr ppQualSet);
        internal delegate int Get(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName, [In] int lFlags, [In][Out] ref object pVal, [In][Out] ref int pType, [In][Out] ref int plFlavor);
        internal delegate int Put(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName, [In] int lFlags, [In] ref object pVal, [In] int Type);
        internal delegate int Delete(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName);
        internal delegate int GetNames(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszQualifierName, [In] int lFlags, [In] ref object pQualifierVal, [Out][MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]  out string[] pNames);
        internal delegate int BeginEnumeration(int vFunc, IntPtr pWbemClassObject, [In] int lEnumFlags);
        internal delegate int Next(int vFunc, IntPtr pWbemClassObject, [In] int lFlags, [In][Out][MarshalAs(UnmanagedType.BStr)]  ref string strName, [In][Out] ref object pVal, [In][Out] ref int pType, [In][Out] ref int plFlavor);
        internal delegate int EndEnumeration(int vFunc, IntPtr pWbemClassObject);
        internal delegate int GetPropertyQualifierSet(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszProperty, [Out] out IntPtr ppQualSet);
        internal delegate int Clone(int vFunc, IntPtr pWbemClassObject, [Out] out IntPtr ppCopy);
        internal delegate int GetObjectText(int vFunc, IntPtr pWbemClassObject, [In] int lFlags, [Out][MarshalAs(UnmanagedType.BStr)]  out string pstrObjectText);
        internal delegate int SpawnDerivedClass(int vFunc, IntPtr pWbemClassObject, [In] int lFlags, [Out] out IntPtr ppNewClass);
        internal delegate int SpawnInstance(int vFunc, IntPtr pWbemClassObject, [In] int lFlags, [Out] out IntPtr ppNewInstance);
        internal delegate int CompareTo(int vFunc, IntPtr pWbemClassObject, [In] int lFlags, [In] IntPtr pCompareTo);
        internal delegate int GetPropertyOrigin(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName, [Out][MarshalAs(UnmanagedType.BStr)]  out string pstrClassName);
        internal delegate int InheritsFrom(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string strAncestor);
        internal delegate int GetMethod(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName, [In] int lFlags, [Out]out IntPtr ppInSignature, [Out] out IntPtr ppOutSignature);
        internal delegate int PutMethod(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName, [In] int lFlags, [In] IntPtr pInSignature, [In] IntPtr pOutSignature);
        internal delegate int DeleteMethod(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName);
        internal delegate int BeginMethodEnumeration(int vFunc, IntPtr pWbemClassObject, [In] int lEnumFlags);
        internal delegate int NextMethod(int vFunc, IntPtr pWbemClassObject, [In] int lFlags, [Out][MarshalAs(UnmanagedType.BStr)] out string pstrName, [Out] out IntPtr ppInSignature, [Out] out IntPtr ppOutSignature);
        internal delegate int EndMethodEnumeration(int vFunc, IntPtr pWbemClassObject);
        internal delegate int GetMethodQualifierSet(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszMethod, [Out] out IntPtr ppQualSet);
        internal delegate int GetMethodOrigin(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszMethodName, [Out][MarshalAs(UnmanagedType.BStr)]  out string pstrClassName);
        internal delegate int QualifierSet_Get(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName, [In] int lFlags, [In][Out] ref object pVal, [In][Out] ref int plFlavor);
        internal delegate int QualifierSet_Put(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName, [In] ref object pVal, [In] int lFlavor);
        internal delegate int QualifierSet_Delete(int vFunc, IntPtr pWbemClassObject, [In][MarshalAs(UnmanagedType.LPWStr)]  string wszName);
        internal delegate int QualifierSet_GetNames(int vFunc, IntPtr pWbemClassObject, [In] int lFlags, [Out][MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]  out string[] pNames);
        internal delegate int QualifierSet_BeginEnumeration(int vFunc, IntPtr pWbemClassObject, [In] int lFlags);
        internal delegate int QualifierSet_Next(int vFunc, IntPtr pWbemClassObject, [In] int lFlags, [Out][MarshalAs(UnmanagedType.BStr)]  out string pstrName, [Out] out object pVal, [Out] out int plFlavor);
        internal delegate int QualifierSet_EndEnumeration(int vFunc, IntPtr pWbemClassObject);
        internal delegate int GetCurrentApartmentType(int vFunc, IntPtr pComThreadingInfo, [Out] out APTTYPE aptType);
        internal delegate void VerifyClientKey();
        internal delegate int GetDemultiplexedStub([In, MarshalAs(UnmanagedType.IUnknown)]object pIUnknown, [In]bool isLocal, [Out, MarshalAs(UnmanagedType.IUnknown)]out object ppIUnknown);
        internal delegate int CreateInstanceEnumWmi([In][MarshalAs(UnmanagedType.BStr)]  string strFilter,
                                                                                           [In] int lFlags,
                                                                                           [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext pCtx,
                                                                                           [Out][MarshalAs(UnmanagedType.Interface)]  out IEnumWbemClassObject ppEnum,
                                                                                           [In] int impLevel,
                                                                                           [In] int authnLevel,
                                                                                           [In] [MarshalAs(UnmanagedType.Interface)] IWbemServices pCurrentNamespace,
                                                                                           [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                                           [In]IntPtr strPassword,
                                                                                           [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority
                                                                                           );
        internal delegate int CreateClassEnumWmi([In][MarshalAs(UnmanagedType.BStr)]  string strSuperclass,
                                                                                       [In] int lFlags,
                                                                                       [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext pCtx,
                                                                                       [Out][MarshalAs(UnmanagedType.Interface)]  out IEnumWbemClassObject ppEnum,
                                                                                       [In] int impLevel,
                                                                                       [In] int authnLevel,
                                                                                       [In] [MarshalAs(UnmanagedType.Interface)] IWbemServices pCurrentNamespace,
                                                                                       [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                                       [In]IntPtr strPassword,
                                                                                       [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority
                                                                                       );
        internal delegate int ExecQueryWmi([In][MarshalAs(UnmanagedType.BStr)]  string strQueryLanguage,
                                                                           [In][MarshalAs(UnmanagedType.BStr)]  string strQuery,
                                                                           [In] int lFlags,
                                                                           [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext pCtx,
                                                                           [Out][MarshalAs(UnmanagedType.Interface)]  out IEnumWbemClassObject ppEnum,
                                                                           [In] int impLevel,
                                                                           [In] int authnLevel,
                                                                           [In] [MarshalAs(UnmanagedType.Interface)] IWbemServices pCurrentNamespace,
                                                                           [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                           [In]IntPtr strPassword,
                                                                           [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority
                                                                           );
        internal delegate int ExecNotificationQueryWmi([In][MarshalAs(UnmanagedType.BStr)]  string strQueryLanguage,
                                                                                                [In][MarshalAs(UnmanagedType.BStr)]  string strQuery,
                                                                                                [In] int lFlags,
                                                                                                [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext pCtx,
                                                                                                [Out][MarshalAs(UnmanagedType.Interface)]  out IEnumWbemClassObject ppEnum,
                                                                                                [In] int impLevel,
                                                                                                [In] int authnLevel,
                                                                                                [In] [MarshalAs(UnmanagedType.Interface)] IWbemServices pCurrentNamespace,
                                                                                                [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                                                [In]IntPtr strPassword,
                                                                                                [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority
                                                                                                );
        internal delegate int PutInstanceWmi([In] IntPtr pInst,
                                                                            [In] int lFlags,
                                                                            [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext pCtx,
                                                                            [In] IntPtr ppCallResult,
                                                                            [In] int impLevel,
                                                                            [In] int authnLevel,
                                                                            [In] [MarshalAs(UnmanagedType.Interface)] IWbemServices pCurrentNamespace,
                                                                            [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                            [In]IntPtr strPassword,
                                                                            [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority
                                                                            );
        internal delegate int PutClassWmi([In] IntPtr pObject,
                                                                        [In] int lFlags,
                                                                        [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext pCtx,
                                                                        [In] IntPtr ppCallResult,
                                                                        [In] int impLevel,
                                                                        [In] int authnLevel,
                                                                        [In] [MarshalAs(UnmanagedType.Interface)] IWbemServices pCurrentNamespace,
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                        [In]IntPtr strPassword,
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority
                                                                        );
        internal delegate int CloneEnumWbemClassObject(
                                                                [Out][MarshalAs(UnmanagedType.Interface)]  out IEnumWbemClassObject ppEnum,
                                                                [In] int impLevel,
                                                                [In] int authnLevel,
                                                                [In] [MarshalAs(UnmanagedType.Interface)] IEnumWbemClassObject pCurrentEnumWbemClassObject,
                                                                [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                [In]IntPtr strPassword,
                                                                [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority
                                                                );
        internal delegate int ConnectServerWmi(
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strNetworkResource,
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strUser,
                                                                        [In]  IntPtr strPassword,
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strLocale,
                                                                        [In] int lSecurityFlags,
                                                                        [In][MarshalAs(UnmanagedType.BStr)]  string strAuthority,
                                                                        [In][MarshalAs(UnmanagedType.Interface)]  IWbemContext pCtx,
                                                                        [Out][MarshalAs(UnmanagedType.Interface)]  out IWbemServices ppNamespace,
                                                                        int impersonationLevel,
                                                                        int authenticationLevel);

        internal delegate IntPtr GetErrorInfo();

        internal delegate int Initialize([In]bool AllowIManagementObjectQI);




        // 'Apartment Type' returned by IComThreadingInfo::GetCurrentApartmentType()
        internal enum APTTYPE
        {
            APTTYPE_CURRENT = -1,
            APTTYPE_STA = 0,
            APTTYPE_MTA = 1,
            APTTYPE_NA = 2,
            APTTYPE_MAINSTA = 3
        }
        internal static ResetSecurity ResetSecurity_f;
        internal static SetSecurity SetSecurity_f;
        internal static BlessIWbemServices BlessIWbemServices_f;
        internal static BlessIWbemServicesObject BlessIWbemServicesObject_f;
        internal static GetPropertyHandle GetPropertyHandle_f27;
        internal static WritePropertyValue WritePropertyValue_f28;
        internal static GetQualifierSet GetQualifierSet_f;
        internal static Get Get_f;
        internal static Put Put_f;
        internal static Delete Delete_f;
        internal static GetNames GetNames_f;
        internal static BeginEnumeration BeginEnumeration_f;
        internal static Next Next_f;
        internal static EndEnumeration EndEnumeration_f;
        internal static GetPropertyQualifierSet GetPropertyQualifierSet_f;
        internal static Clone Clone_f;
        internal static GetObjectText GetObjectText_f;
        internal static SpawnDerivedClass SpawnDerivedClass_f;
        internal static SpawnInstance SpawnInstance_f;
        internal static CompareTo CompareTo_f;
        internal static GetPropertyOrigin GetPropertyOrigin_f;
        internal static InheritsFrom InheritsFrom_f;
        internal static GetMethod GetMethod_f;
        internal static PutMethod PutMethod_f;
        internal static DeleteMethod DeleteMethod_f;
        internal static BeginMethodEnumeration BeginMethodEnumeration_f;
        internal static NextMethod NextMethod_f;
        internal static EndMethodEnumeration EndMethodEnumeration_f;
        internal static GetMethodQualifierSet GetMethodQualifierSet_f;
        internal static GetMethodOrigin GetMethodOrigin_f;
        internal static QualifierSet_Get QualifierGet_f;
        internal static QualifierSet_Put QualifierPut_f;
        internal static QualifierSet_Delete QualifierDelete_f;
        internal static QualifierSet_GetNames QualifierGetNames_f;
        internal static QualifierSet_BeginEnumeration QualifierBeginEnumeration_f;
        internal static QualifierSet_Next QualifierNext_f;
        internal static QualifierSet_EndEnumeration QualifierEndEnumeration_f;
        internal static GetCurrentApartmentType GetCurrentApartmentType_f;
        internal static VerifyClientKey VerifyClientKey_f;
        internal static Clone Clone_f12;
        internal static GetDemultiplexedStub GetDemultiplexedStub_f;
        internal static CreateInstanceEnumWmi CreateInstanceEnumWmi_f;
        internal static CreateClassEnumWmi CreateClassEnumWmi_f;
        internal static ExecQueryWmi ExecQueryWmi_f;
        internal static ExecNotificationQueryWmi ExecNotificationQueryWmi_f;
        internal static PutInstanceWmi PutInstanceWmi_f;
        internal static PutClassWmi PutClassWmi_f;
        internal static CloneEnumWbemClassObject CloneEnumWbemClassObject_f;
        internal static ConnectServerWmi ConnectServerWmi_f;
        internal static GetErrorInfo GetErrorInfo_f;
        internal static Initialize Initialize_f;

        static WmiNetUtilsHelper()
        {
            RegistryKey netFrameworkSubKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework\");
            string netFrameworkInstallRoot = (string)netFrameworkSubKey?.GetValue(RuntimeInformation.ProcessArchitecture == Architecture.Arm64 ?
                "InstallRootArm64" :
                "InstallRoot");

            if (netFrameworkInstallRoot == null)
            {
                // In some Windows versions, like Nano Server, the .NET Framework is not installed by default.
                // It is possible that general failure to access the registry get to this code branch but it is
                // very unlikely.
                // Load PNSE delegates. This way it will throw PNSE when methods are used not when type is loaded.
                LoadPlatformNotSupportedDelegates(SR.PlatformNotSupported_FullFrameworkRequired);
                return;
            }

            string wminet_utilsPath = Path.Combine(
                netFrameworkInstallRoot,
                CompatSwitches.DotNetVersion, // The same value is hard coded on Environment.Version and quirks for WMI
                "wminet_utils.dll");

            IntPtr hModule = Interop.Kernel32.LoadLibrary(wminet_utilsPath);
            if (hModule == IntPtr.Zero)
            {
                // This is unlikely, so having the TypeInitializationException wrapping it is fine.
                throw new Win32Exception(Marshal.GetLastPInvokeError(), SR.Format(SR.LoadLibraryFailed, wminet_utilsPath));
            }

            if (LoadDelegate(ref ResetSecurity_f, hModule, "ResetSecurity") &&
                LoadDelegate(ref SetSecurity_f, hModule, "SetSecurity") &&
                LoadDelegate(ref BlessIWbemServices_f, hModule, "BlessIWbemServices") &&
                LoadDelegate(ref BlessIWbemServicesObject_f, hModule, "BlessIWbemServicesObject") &&
                LoadDelegate(ref GetPropertyHandle_f27, hModule, "GetPropertyHandle") &&
                LoadDelegate(ref WritePropertyValue_f28, hModule, "WritePropertyValue") &&
                LoadDelegate(ref Clone_f12, hModule, "Clone") &&
                LoadDelegate(ref VerifyClientKey_f, hModule, "VerifyClientKey") &&
                LoadDelegate(ref GetQualifierSet_f, hModule, "GetQualifierSet") &&
                LoadDelegate(ref Get_f, hModule, "Get") &&
                LoadDelegate(ref Put_f, hModule, "Put") &&
                LoadDelegate(ref Delete_f, hModule, "Delete") &&
                LoadDelegate(ref GetNames_f, hModule, "GetNames") &&
                LoadDelegate(ref BeginEnumeration_f, hModule, "BeginEnumeration") &&
                LoadDelegate(ref Next_f, hModule, "Next") &&
                LoadDelegate(ref EndEnumeration_f, hModule, "EndEnumeration") &&
                LoadDelegate(ref GetPropertyQualifierSet_f, hModule, "GetPropertyQualifierSet") &&
                LoadDelegate(ref Clone_f, hModule, "Clone") &&
                LoadDelegate(ref GetObjectText_f, hModule, "GetObjectText") &&
                LoadDelegate(ref SpawnDerivedClass_f, hModule, "SpawnDerivedClass") &&
                LoadDelegate(ref SpawnInstance_f, hModule, "SpawnInstance") &&
                LoadDelegate(ref CompareTo_f, hModule, "CompareTo") &&
                LoadDelegate(ref GetPropertyOrigin_f, hModule, "GetPropertyOrigin") &&
                LoadDelegate(ref InheritsFrom_f, hModule, "InheritsFrom") &&
                LoadDelegate(ref GetMethod_f, hModule, "GetMethod") &&
                LoadDelegate(ref PutMethod_f, hModule, "PutMethod") &&
                LoadDelegate(ref DeleteMethod_f, hModule, "DeleteMethod") &&
                LoadDelegate(ref BeginMethodEnumeration_f, hModule, "BeginMethodEnumeration") &&
                LoadDelegate(ref NextMethod_f, hModule, "NextMethod") &&
                LoadDelegate(ref EndMethodEnumeration_f, hModule, "EndMethodEnumeration") &&
                LoadDelegate(ref GetMethodQualifierSet_f, hModule, "GetMethodQualifierSet") &&
                LoadDelegate(ref GetMethodOrigin_f, hModule, "GetMethodOrigin") &&
                LoadDelegate(ref QualifierGet_f, hModule, "QualifierSet_Get") &&
                LoadDelegate(ref QualifierPut_f, hModule, "QualifierSet_Put") &&
                LoadDelegate(ref QualifierDelete_f, hModule, "QualifierSet_Delete") &&
                LoadDelegate(ref QualifierGetNames_f, hModule, "QualifierSet_GetNames") &&
                LoadDelegate(ref QualifierBeginEnumeration_f, hModule, "QualifierSet_BeginEnumeration") &&
                LoadDelegate(ref QualifierNext_f, hModule, "QualifierSet_Next") &&
                LoadDelegate(ref QualifierEndEnumeration_f, hModule, "QualifierSet_EndEnumeration") &&
                LoadDelegate(ref GetCurrentApartmentType_f, hModule, "GetCurrentApartmentType") &&
                LoadDelegate(ref GetDemultiplexedStub_f, hModule, "GetDemultiplexedStub") &&
                LoadDelegate(ref CreateInstanceEnumWmi_f, hModule, "CreateInstanceEnumWmi") &&
                LoadDelegate(ref CreateClassEnumWmi_f, hModule, "CreateClassEnumWmi") &&
                LoadDelegate(ref ExecQueryWmi_f, hModule, "ExecQueryWmi") &&
                LoadDelegate(ref ExecNotificationQueryWmi_f, hModule, "ExecNotificationQueryWmi") &&
                LoadDelegate(ref PutInstanceWmi_f, hModule, "PutInstanceWmi") &&
                LoadDelegate(ref PutClassWmi_f, hModule, "PutClassWmi") &&
                LoadDelegate(ref CloneEnumWbemClassObject_f, hModule, "CloneEnumWbemClassObject") &&
                LoadDelegate(ref ConnectServerWmi_f, hModule, "ConnectServerWmi") &&
                LoadDelegate(ref GetErrorInfo_f, hModule, "GetErrorInfo") &&
                LoadDelegate(ref Initialize_f, hModule, "Initialize"))
            {
                // All required delegates were loaded.
                Initialize_f(CompatSwitches.AllowIManagementObjectQI);
            }
            else
            {
                LoadPlatformNotSupportedDelegates(SR.Format(SR.PlatformNotSupported_FrameworkUpdatedRequired, wminet_utilsPath));
            }
        }
        private static bool LoadDelegate<TDelegate>(ref TDelegate delegate_f, IntPtr hModule, string procName) where TDelegate : class
        {
            IntPtr procAddr = Interop.Kernel32.GetProcAddress(hModule, procName);
            return procAddr != IntPtr.Zero &&
                (delegate_f = Marshal.GetDelegateForFunctionPointer<TDelegate>(procAddr)) != null;
        }

        private static void LoadPlatformNotSupportedDelegates(string exceptionMessage)
        {
            ResetSecurity_f = (_) => throw new PlatformNotSupportedException(exceptionMessage);
            SetSecurity_f = (ref bool _, ref IntPtr __) => throw new PlatformNotSupportedException(exceptionMessage);
            BlessIWbemServices_f = (_, __, ___, ____, _____, ______) => throw new PlatformNotSupportedException(exceptionMessage);
            BlessIWbemServicesObject_f = (_, __, ___, ____, _____, ______) => throw new PlatformNotSupportedException(exceptionMessage);
            GetPropertyHandle_f27 = (int _, IntPtr __, string ___, out int ____, out int _____) => throw new PlatformNotSupportedException(exceptionMessage);
            WritePropertyValue_f28 = (_, __, ___, ____, _____) => throw new PlatformNotSupportedException(exceptionMessage);
            Clone_f12 = (int _, IntPtr __, out IntPtr ___) => throw new PlatformNotSupportedException(exceptionMessage);
            VerifyClientKey_f = () => throw new PlatformNotSupportedException(exceptionMessage);
            GetQualifierSet_f = (int _, IntPtr __, out IntPtr ___) => throw new PlatformNotSupportedException(exceptionMessage);
            Get_f = (int _, IntPtr __, string ___, int ____, ref object _____, ref int ______, ref int _______) => throw new PlatformNotSupportedException(exceptionMessage);
            Put_f = (int _, IntPtr __, string ___, int ____, ref object _____, int ______) => throw new PlatformNotSupportedException(exceptionMessage);
            Delete_f = (_, __, ___) => throw new PlatformNotSupportedException(exceptionMessage);
            GetNames_f = (int _, IntPtr __, string ___, int ____, ref object _____, out string[] ______) => throw new PlatformNotSupportedException(exceptionMessage);
            BeginEnumeration_f = (_, __, ___) => throw new PlatformNotSupportedException(exceptionMessage);
            Next_f = (int _, IntPtr __, int ___, ref string ____, ref object _____, ref int ______, ref int _______) => throw new PlatformNotSupportedException(exceptionMessage);
            EndEnumeration_f = (_, __) => throw new PlatformNotSupportedException(exceptionMessage);
            GetPropertyQualifierSet_f = (int _, IntPtr __, string ___, out IntPtr ____) => throw new PlatformNotSupportedException(exceptionMessage);
            Clone_f = (int _, IntPtr __, out IntPtr ___) => throw new PlatformNotSupportedException(exceptionMessage);
            GetObjectText_f = (int _, IntPtr __, int ___, out string ____) => throw new PlatformNotSupportedException(exceptionMessage);
            SpawnDerivedClass_f = (int _, IntPtr __, int ___, out IntPtr ____) => throw new PlatformNotSupportedException(exceptionMessage);
            SpawnInstance_f = (int _, IntPtr __, int ___, out IntPtr ____) => throw new PlatformNotSupportedException(exceptionMessage);
            CompareTo_f = (_, __, ___, ____) => throw new PlatformNotSupportedException(exceptionMessage);
            GetPropertyOrigin_f = (int _, IntPtr __, string ___, out string ____) => throw new PlatformNotSupportedException(exceptionMessage);
            InheritsFrom_f = (int _, IntPtr __, string ___) => throw new PlatformNotSupportedException(exceptionMessage);
            GetMethod_f = (int _, IntPtr __, string ___, int ____, out IntPtr _____, out IntPtr ______) => throw new PlatformNotSupportedException(exceptionMessage);
            PutMethod_f = (_, __, ___, ____, _____, ______) => throw new PlatformNotSupportedException(exceptionMessage);
            DeleteMethod_f = (_, __, ___) => throw new PlatformNotSupportedException(exceptionMessage);
            BeginMethodEnumeration_f = (_, __, ___) => throw new PlatformNotSupportedException(exceptionMessage);
            NextMethod_f = (int _, IntPtr __, int ___, out string ____, out IntPtr _____, out IntPtr ______) => throw new PlatformNotSupportedException(exceptionMessage);
            EndMethodEnumeration_f = (_, __) => throw new PlatformNotSupportedException(exceptionMessage);
            GetMethodQualifierSet_f = (int _, IntPtr __, string ___, out IntPtr ____) => throw new PlatformNotSupportedException(exceptionMessage);
            GetMethodOrigin_f = (int _, IntPtr __, string ___, out string ____) => throw new PlatformNotSupportedException(exceptionMessage);
            QualifierGet_f = (int _, IntPtr __, string ___, int ____, ref object _____, ref int ______) => throw new PlatformNotSupportedException(exceptionMessage);
            QualifierPut_f = (int _, IntPtr __, string ___, ref object ____, int _____) => throw new PlatformNotSupportedException(exceptionMessage);
            QualifierDelete_f = (_, __, ___) => throw new PlatformNotSupportedException(exceptionMessage);
            QualifierGetNames_f = (int _, IntPtr __, int ___, out string[] ____) => throw new PlatformNotSupportedException(exceptionMessage);
            QualifierBeginEnumeration_f = (_, __, ___) => throw new PlatformNotSupportedException(exceptionMessage);
            QualifierNext_f = (int _, IntPtr __, int ___, out string ____, out object _____, out int ______) => throw new PlatformNotSupportedException(exceptionMessage);
            QualifierEndEnumeration_f = (_, __) => throw new PlatformNotSupportedException(exceptionMessage);
            GetCurrentApartmentType_f = (int _, IntPtr __, out APTTYPE ___) => throw new PlatformNotSupportedException(exceptionMessage);
            GetDemultiplexedStub_f = (object _, bool __, out object ___) => throw new PlatformNotSupportedException(exceptionMessage);
            CreateInstanceEnumWmi_f = (string _, int __, IWbemContext ___, out IEnumWbemClassObject ____, int _____, int ______, IWbemServices _______, string ________, IntPtr _________, string __________) => throw new PlatformNotSupportedException(exceptionMessage);
            CreateClassEnumWmi_f = (string _, int __, IWbemContext ___, out IEnumWbemClassObject ____, int _____, int ______, IWbemServices _______, string ________, IntPtr _________, string __________) => throw new PlatformNotSupportedException(exceptionMessage);
            ExecQueryWmi_f = (string _, string __, int ___, IWbemContext ____, out IEnumWbemClassObject _____, int ______, int _______, IWbemServices ________, string _________, IntPtr __________, string ___________) => throw new PlatformNotSupportedException(exceptionMessage);
            ExecNotificationQueryWmi_f = (string _, string __, int ___, IWbemContext ____, out IEnumWbemClassObject _____, int ______, int _______, IWbemServices ________, string _________, IntPtr __________, string ___________) => throw new PlatformNotSupportedException(exceptionMessage);
            PutInstanceWmi_f = (_, __, ___, ____, _____, ______, _______, ________, _________, __________) => throw new PlatformNotSupportedException(exceptionMessage);
            PutClassWmi_f = (_, __, ___, ____, _____, ______, _______, ________, _________, __________) => throw new PlatformNotSupportedException(exceptionMessage);
            CloneEnumWbemClassObject_f = (out IEnumWbemClassObject _, int __, int ____, IEnumWbemClassObject _____, string ______, IntPtr _______, string ________) => throw new PlatformNotSupportedException(exceptionMessage);
            ConnectServerWmi_f = (string _, string __, IntPtr ___, string ____, int _____, string ______, IWbemContext _______, out IWbemServices ________, int _________, int __________) => throw new PlatformNotSupportedException(exceptionMessage);
            GetErrorInfo_f = () => throw new PlatformNotSupportedException(exceptionMessage);
            Initialize_f = (_) => throw new PlatformNotSupportedException(exceptionMessage);
        }
    }

    /// <summary>
    ///    <para>Represents a scope for management operations. In v1.0 the scope defines the WMI namespace in which management operations are performed.</para>
    /// </summary>
    /// <example>
    ///    <code lang='C#'>using System;
    /// using System.Management;
    ///
    /// // This sample demonstrates how to connect to root/default namespace
    /// // using ManagmentScope object.
    /// class Sample_ManagementScope
    /// {
    ///     public static int Main(string[] args)
    ///     {
    ///         ManagementScope scope = new ManagementScope("root\\default");
    ///         scope.Connect();
    ///         ManagementClass newClass = new ManagementClass(
    ///             scope,
    ///             new ManagementPath(),
    ///             null);
    ///         return 0;
    ///     }
    /// }
    ///    </code>
    ///    <code lang='VB'>Imports System
    /// Imports System.Management
    ///
    /// ' This sample demonstrates how to connect to root/default namespace
    /// ' using ManagmentScope object.
    /// Class Sample_ManagementScope
    ///     Overloads Public Shared Function Main(args() As String) As Integer
    ///         Dim scope As New ManagementScope("root\default")
    ///         scope.Connect()
    ///         Dim newClass As New ManagementClass(scope, _
    ///             New ManagementPath(), _
    ///             Nothing)
    ///         Return 0
    ///     End Function
    /// End Class
    ///    </code>
    /// </example>
    [TypeConverter(typeof(ManagementScopeConverter))]
    public class ManagementScope : ICloneable
    {
        private ManagementPath validatedPath;
        private IWbemServices wbemServices;
        private ConnectionOptions options;
        internal event IdentifierChangedEventHandler IdentifierChanged;
        internal bool IsDefaulted; //used to tell whether the current scope has been created from the default
        //scope or not - this information is used to tell whether it can be overridden
        //when a new path is set or not.

        //Fires IdentifierChanged event
        private void FireIdentifierChanged()
        {
            IdentifierChanged?.Invoke(this, null);
        }

        //Called when IdentifierChanged() event fires
        private void HandleIdentifierChange(object sender,
            IdentifierChangedEventArgs args)
        {
            // Since our object has changed we had better signal to ourself that
            // an connection needs to be established
            wbemServices = null;

            //Something inside ManagementScope changed, we need to fire an event
            //to the parent object
            FireIdentifierChanged();
        }

        // Private path property accessor which performs minimal validation on the
        // namespace path. IWbemPath cannot differentiate between a class or a name-
        // space if path separators are not present in the path.  Therefore, IWbemPath
        // will allow a namespace of "rootBeer" vs "root".  Since it is established
        // that the scope path is indeed a namespace path, we perform this validation.
        private ManagementPath prvpath
        {
            get
            {
                return validatedPath;
            }
            set
            {
                if (value != null)
                {
                    string pathValue = value.Path;
                    if (!ManagementPath.IsValidNamespaceSyntax(pathValue))
                        ManagementException.ThrowWithExtendedInfo((ManagementStatus)tag_WBEMSTATUS.WBEM_E_INVALID_NAMESPACE);
                }

                validatedPath = value;
            }
        }

        internal IWbemServices GetIWbemServices()
        {
            IWbemServices localCopy = wbemServices;
            //IWbemServices is always created in MTA context. Only if call is made through non MTA context we need to use IWbemServices in right context.
            // Lets start by assuming that we'll return the RCW that we already have. When WMINet_Utils.dll wraps the real COM proxy, credentials don't get
            // lost when the CLR marshals the wrapped object to a different COM apartment. The wrap was added to prevent marshalling of IManagedObject from native
            // to managed code.

            if (CompatSwitches.AllowIManagementObjectQI)
            {
                // Get an IUnknown for this apartment
                IntPtr pUnk = Marshal.GetIUnknownForObject(wbemServices);

                // Get an 'IUnknown RCW' for this apartment
                object unknown = Marshal.GetObjectForIUnknown(pUnk);

                // Release the ref count on the IUnknwon
                Marshal.Release(pUnk);

                // See if we are in the same apartment as where the original IWbemServices lived
                // If we are in a different apartment, give the caller an RCW generated just for their
                // apartment, and set the proxy blanket appropriately
                if (!object.ReferenceEquals(unknown, wbemServices))
                {
                    // We need to set the proxy blanket on 'unknown' or else the QI for IWbemServices may
                    // fail if we are running under a local user account.  The QI has to be done by
                    // someone who is a member of the 'Everyone' group on the target machine, or DCOM
                    // won't let the call through.
                    SecurityHandler securityHandler = GetSecurityHandler();
                    securityHandler.SecureIUnknown(unknown);

                    // Now, we can QI and secure the IWbemServices
                    localCopy = (IWbemServices)unknown;

                    // We still need to bless the IWbemServices in this apartment
                    securityHandler.Secure(localCopy);
                }
            }

            return localCopy; // STRANGE: Why does it still work if I return 'wbemServices'?
        }

        /// <summary>
        /// <para> Gets or sets a value indicating whether the <see cref='System.Management.ManagementScope'/> is currently bound to a
        ///    WMI server and namespace.</para>
        /// </summary>
        /// <value>
        /// <para><see langword='true'/> if a connection is alive (bound
        ///    to a server and namespace); otherwise, <see langword='false'/>.</para>
        /// </value>
        /// <remarks>
        ///    <para> A scope is disconnected after creation until someone
        ///       explicitly calls <see cref='System.Management.ManagementScope.Connect'/>(), or uses the scope for any
        ///       operation that requires a live connection. Also, the scope is
        ///       disconnected from the previous connection whenever the identifying properties of the scope are
        ///       changed.</para>
        /// </remarks>
        public bool IsConnected
        {
            get
            {
                return (null != wbemServices);
            }
        }

        //Internal constructor
        internal ManagementScope(ManagementPath path, IWbemServices wbemServices,
            ConnectionOptions options)
        {
            if (null != path)
                this.Path = path;

            if (null != options)
            {
                this.Options = options;
            }

            // We set this.wbemServices after setting Path and Options
            // because the latter operations can cause wbemServices to be NULLed.
            this.wbemServices = wbemServices;
        }

        internal ManagementScope(ManagementPath path, ManagementScope scope)
            : this(path, scope?.options) { }

        internal static ManagementScope _Clone(ManagementScope scope)
        {
            return ManagementScope._Clone(scope, null);
        }

        internal static ManagementScope _Clone(ManagementScope scope, IdentifierChangedEventHandler handler)
        {
            ManagementScope scopeTmp = new ManagementScope(null, null, null);

            // Wire up change handler chain. Use supplied handler, if specified;
            // otherwise, default to that of the scope argument.
            if (handler != null)
                scopeTmp.IdentifierChanged = handler;
            else if (scope != null)
                scopeTmp.IdentifierChanged = new IdentifierChangedEventHandler(scope.HandleIdentifierChange);

            // Set scope path.
            if (scope == null)
            {
                // No path specified. Default.
                scopeTmp.prvpath = ManagementPath._Clone(ManagementPath.DefaultPath, new IdentifierChangedEventHandler(scopeTmp.HandleIdentifierChange));
                scopeTmp.IsDefaulted = true;

                scopeTmp.wbemServices = null;
                scopeTmp.options = null;
            }
            else
            {
                if (scope.prvpath == null)
                {
                    // No path specified. Default.
                    scopeTmp.prvpath = ManagementPath._Clone(ManagementPath.DefaultPath, new IdentifierChangedEventHandler(scopeTmp.HandleIdentifierChange));
                    scopeTmp.IsDefaulted = true;
                }
                else
                {
                    // Use scope-supplied path.
                    scopeTmp.prvpath = ManagementPath._Clone(scope.prvpath, new IdentifierChangedEventHandler(scopeTmp.HandleIdentifierChange));
                    scopeTmp.IsDefaulted = scope.IsDefaulted;
                }

                scopeTmp.wbemServices = scope.wbemServices;
                if (scope.options != null)
                    scopeTmp.options = ConnectionOptions._Clone(scope.options, new IdentifierChangedEventHandler(scopeTmp.HandleIdentifierChange));
            }

            return scopeTmp;
        }

        //Default constructor
        /// <overload>
        ///    Initializes a new instance
        ///    of the <see cref='System.Management.ManagementScope'/> class.
        /// </overload>
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.ManagementScope'/> class, with default values. This is the
        ///    default constructor.</para>
        /// </summary>
        /// <remarks>
        ///    <para> If the object doesn't have any
        ///       properties set before connection, it will be initialized with default values
        ///       (for example, the local machine and the root\cimv2 namespace).</para>
        /// </remarks>
        /// <example>
        ///    <code lang='C#'>ManagementScope s = new ManagementScope();
        ///    </code>
        ///    <code lang='VB'>Dim s As New ManagementScope()
        ///    </code>
        /// </example>
        public ManagementScope() :
            this(new ManagementPath(ManagementPath.DefaultPath.Path))
        {
            //Flag that this scope uses the default path
            IsDefaulted = true;
        }

        //Parameterized constructors
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.ManagementScope'/> class representing
        ///    the specified scope path.</para>
        /// </summary>
        /// <param name='path'>A <see cref='System.Management.ManagementPath'/> containing the path to a server and namespace for the <see cref='System.Management.ManagementScope'/>.</param>
        /// <example>
        ///    <code lang='C#'>ManagementScope s = new ManagementScope(new ManagementPath("\\\\MyServer\\root\\default"));
        ///    </code>
        ///    <code lang='VB'>Dim p As New ManagementPath("\\MyServer\root\default")
        /// Dim s As New ManagementScope(p)
        ///    </code>
        /// </example>
        public ManagementScope(ManagementPath path) : this(path, (ConnectionOptions)null) { }

        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.ManagementScope'/> class representing the specified scope
        ///    path.</para>
        /// </summary>
        /// <param name='path'>The server and namespace path for the <see cref='System.Management.ManagementScope'/>.</param>
        /// <example>
        ///    <code lang='C#'>ManagementScope s = new ManagementScope("\\\\MyServer\\root\\default");
        ///    </code>
        ///    <code lang='VB'>Dim s As New ManagementScope("\\MyServer\root\default")
        ///    </code>
        /// </example>
        public ManagementScope(string path) : this(new ManagementPath(path), (ConnectionOptions)null) { }
        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.ManagementScope'/> class representing the specified scope path,
        ///    with the specified options.</para>
        /// </summary>
        /// <param name='path'>The server and namespace for the <see cref='System.Management.ManagementScope'/>.</param>
        /// <param name=' options'>A <see cref='System.Management.ConnectionOptions'/> containing options for the connection.</param>
        /// <example>
        ///    <code lang='C#'>ConnectionOptions opt = new ConnectionOptions();
        /// opt.Username = "Me";
        /// opt.Password = "MyPassword";
        /// ManagementScope s = new ManagementScope("\\\\MyServer\\root\\default", opt);
        ///    </code>
        ///    <code lang='VB'>Dim opt As New ConnectionOptions()
        /// opt.Username = "Me"
        /// opt.Password = "MyPassword"
        /// Dim s As New ManagementScope("\\MyServer\root\default", opt);
        ///    </code>
        /// </example>
        public ManagementScope(string path, ConnectionOptions options) : this(new ManagementPath(path), options) { }

        /// <summary>
        /// <para>Initializes a new instance of the <see cref='System.Management.ManagementScope'/> class representing the specified scope path,
        ///    with the specified options.</para>
        /// </summary>
        /// <param name='path'>A <see cref='System.Management.ManagementPath'/> containing the path to the server and namespace for the <see cref='System.Management.ManagementScope'/>.</param>
        /// <param name=' options'>The <see cref='System.Management.ConnectionOptions'/> containing options for the connection.</param>
        /// <example>
        ///    <code lang='C#'>ConnectionOptions opt = new ConnectionOptions();
        /// opt.Username = "Me";
        /// opt.Password = "MyPassword";
        ///
        /// ManagementPath p = new ManagementPath("\\\\MyServer\\root\\default");
        /// ManagementScope = new ManagementScope(p, opt);
        ///    </code>
        ///    <code lang='VB'>Dim opt As New ConnectionOptions()
        /// opt.UserName = "Me"
        /// opt.Password = "MyPassword"
        ///
        /// Dim p As New ManagementPath("\\MyServer\root\default")
        /// Dim s As New ManagementScope(p, opt)
        ///    </code>
        /// </example>
        public ManagementScope(ManagementPath path, ConnectionOptions options)
        {
            if (null != path)
                this.prvpath = ManagementPath._Clone(path, new IdentifierChangedEventHandler(HandleIdentifierChange));
            else
                this.prvpath = ManagementPath._Clone(null);

            if (null != options)
            {
                this.options = ConnectionOptions._Clone(options, new IdentifierChangedEventHandler(HandleIdentifierChange));
            }
            else
                this.options = null;

            IsDefaulted = false; //assume that this scope is not initialized by the default path
        }

        /// <summary>
        ///    <para> Gets or sets options for making the WMI connection.</para>
        /// </summary>
        /// <value>
        /// <para>The valid <see cref='System.Management.ConnectionOptions'/>
        /// containing options for the WMI connection.</para>
        /// </value>
        /// <example>
        ///    <code lang='C#'>//This constructor creates a scope object with default options
        /// ManagementScope s = new ManagementScope("root\\MyApp");
        ///
        /// //Change default connection options -
        /// //In this example, set the system privileges to enabled for operations that require system privileges.
        /// s.Options.EnablePrivileges = true;
        ///    </code>
        ///    <code lang='VB'>'This constructor creates a scope object with default options
        /// Dim s As New ManagementScope("root\\MyApp")
        ///
        /// 'Change default connection options -
        /// 'In this example, set the system privileges to enabled for operations that require system privileges.
        /// s.Options.EnablePrivileges = True
        ///    </code>
        /// </example>
        public ConnectionOptions Options
        {
            get
            {
                return options ??= ConnectionOptions._Clone(null, new IdentifierChangedEventHandler(HandleIdentifierChange));
            }
            set
            {
                if (null != value)
                {
                    if (null != options)
                        options.IdentifierChanged -= new IdentifierChangedEventHandler(HandleIdentifierChange);

                    options = ConnectionOptions._Clone((ConnectionOptions)value, new IdentifierChangedEventHandler(HandleIdentifierChange));

                    //the options property has changed so act like we fired the event
                    HandleIdentifierChange(this, null);
                }
                else
                    throw new ArgumentNullException(nameof(value));
            }
        }

        /// <summary>
        /// <para>Gets or sets the path for the <see cref='System.Management.ManagementScope'/>.</para>
        /// </summary>
        /// <value>
        /// <para> A <see cref='System.Management.ManagementPath'/> containing
        ///    the path to a server and namespace.</para>
        /// </value>
        /// <example>
        ///    <code lang='C#'>ManagementScope s = new ManagementScope();
        /// s.Path = new ManagementPath("root\\MyApp");
        ///    </code>
        ///    <code lang='VB'>Dim s As New ManagementScope()
        /// s.Path = New ManagementPath("root\MyApp")
        ///    </code>
        /// </example>
        public ManagementPath Path
        {
            get
            {
                return prvpath ??= ManagementPath._Clone(null);
            }
            set
            {
                if (null != value)
                {
                    if (null != prvpath)
                        prvpath.IdentifierChanged -= new IdentifierChangedEventHandler(HandleIdentifierChange);

                    IsDefaulted = false; //someone is specifically setting the scope path so it's not defaulted any more

                    prvpath = ManagementPath._Clone((ManagementPath)value, new IdentifierChangedEventHandler(HandleIdentifierChange));

                    //the path property has changed so act like we fired the event
                    HandleIdentifierChange(this, null);
                }
                else
                    throw new ArgumentNullException(nameof(value));
            }
        }

        /// <summary>
        ///    <para>Returns a copy of the object.</para>
        /// </summary>
        /// <returns>
        /// <para>A new copy of the <see cref='System.Management.ManagementScope'/>.</para>
        /// </returns>
        public ManagementScope Clone()
        {
            return ManagementScope._Clone(this);
        }

        /// <summary>
        ///    <para>Clone a copy of this object.</para>
        /// </summary>
        /// <returns>
        ///    A new copy of this object.
        ///    object.
        /// </returns>
        object ICloneable.Clone()
        {
            return Clone();
        }

        /// <summary>
        /// <para>Connects this <see cref='System.Management.ManagementScope'/> to the actual WMI
        ///    scope.</para>
        /// </summary>
        /// <remarks>
        ///    <para>This method is called implicitly when the
        ///       scope is used in an operation that requires it to be connected. Calling it
        ///       explicitly allows the user to control the time of connection.</para>
        /// </remarks>
        /// <example>
        ///    <code lang='C#'>ManagementScope s = new ManagementScope("root\\MyApp");
        ///
        /// //Explicit call to connect the scope object to the WMI namespace
        /// s.Connect();
        ///
        /// //The following doesn't do any implicit scope connections because s is already connected.
        /// ManagementObject o = new ManagementObject(s, "Win32_LogicalDisk='C:'", null);
        ///    </code>
        ///    <code lang='VB'>Dim s As New ManagementScope("root\\MyApp")
        ///
        /// 'Explicit call to connect the scope object to the WMI namespace
        /// s.Connect()
        ///
        /// 'The following doesn't do any implicit scope connections because s is already connected.
        /// Dim o As New ManagementObject(s, "Win32_LogicalDisk=""C:""", null)
        ///    </code>
        /// </example>
        public void Connect()
        {
            Initialize();
        }

        internal void Initialize()
        {
            //If the path is not set yet we can't do it
            if (null == prvpath)
                throw new InvalidOperationException();


            /*
             * If we're not connected yet, this is the time to do it... We lock
             * the state to prevent 2 threads simultaneously doing the same
             * connection. To avoid taking the lock unnecessarily we examine
             * isConnected first
             */
            if (!IsConnected)
            {
                lock (this)
                {
                    if (!IsConnected)
                    {
                        // The locator cannot be marshalled across apartments, so we must create the locator
                        // and get the IWbemServices from an MTA thread
                        if (!MTAHelper.IsNoContextMTA())
                        {
                            //
                            // Ensure we are able to trap exceptions from worker thread.
                            //
                            ThreadDispatch disp = new ThreadDispatch(new ThreadDispatch.ThreadWorkerMethodWithParam(InitializeGuts));
                            disp.Parameter = this;
                            disp.Start();
                        }
                        else
                            InitializeGuts(this);
                    }
                }
            }
        }

        private void InitializeGuts(object o)
        {
            ManagementScope threadParam = (ManagementScope)o;

            if (null == threadParam.options)
            {
                threadParam.Options = new ConnectionOptions();
            }

            string nsPath = threadParam.prvpath.GetNamespacePath((int)tag_WBEM_GET_TEXT_FLAGS.WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY);

            // If no namespace specified, fill in the default one
            if ((null == nsPath) || (0 == nsPath.Length))
            {
                // NB: we use a special method to set the namespace
                // path here as we do NOT want to trigger an
                // IdentifierChanged event as a result of this set

                nsPath = threadParam.prvpath.SetNamespacePath(ManagementPath.DefaultPath.Path, out _);
            }

            int status = (int)ManagementStatus.NoError;
            threadParam.wbemServices = null;

            //If we're on XP or higher, always use the "max_wait" flag to avoid hanging
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {

                if (((Environment.OSVersion.Version.Major == 5) && (Environment.OSVersion.Version.Minor >= 1)) || (Environment.OSVersion.Version.Major >= 6))
                {
                    threadParam.options.Flags |= (int)tag_WBEM_CONNECT_OPTIONS.WBEM_FLAG_CONNECT_USE_MAX_WAIT;
                }
            }

            try
            {
                status = GetSecuredConnectHandler().ConnectNSecureIWbemServices(nsPath, ref threadParam.wbemServices);
            }
            catch (COMException e)
            {
                ManagementException.ThrowWithExtendedInfo(e);
            }

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

        internal SecurityHandler GetSecurityHandler()
        {
            return new SecurityHandler(this);
        }
        internal SecuredConnectHandler GetSecuredConnectHandler()
        {
            return new SecuredConnectHandler(this);
        }
        internal SecuredIEnumWbemClassObjectHandler GetSecuredIEnumWbemClassObjectHandler(IEnumWbemClassObject pEnumWbemClassObject)
        {
            return new SecuredIEnumWbemClassObjectHandler(this, pEnumWbemClassObject);
        }
        internal SecuredIWbemServicesHandler GetSecuredIWbemServicesHandler(IWbemServices pWbemServiecs)
        {
            return new SecuredIWbemServicesHandler(this, pWbemServiecs);
        }

    }//ManagementScope

    internal sealed class SecuredIEnumWbemClassObjectHandler
    {
        private readonly IEnumWbemClassObject pEnumWbemClassObjectsecurityHelper;
        private readonly ManagementScope scope;
        internal SecuredIEnumWbemClassObjectHandler(ManagementScope theScope, IEnumWbemClassObject pEnumWbemClassObject)
        {
            this.scope = theScope;
            pEnumWbemClassObjectsecurityHelper = pEnumWbemClassObject;
        }
        internal int Reset_()
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pEnumWbemClassObjectsecurityHelper.Reset_();
            return status;
        }
        internal int Next_(int lTimeout, uint uCount, IWbemClassObject_DoNotMarshal[] ppOutParams, ref uint puReturned)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pEnumWbemClassObjectsecurityHelper.Next_(lTimeout, uCount, ppOutParams, out puReturned);
            return status;
        }
        internal int NextAsync_(uint uCount, IWbemObjectSink pSink)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pEnumWbemClassObjectsecurityHelper.NextAsync_(uCount, pSink);
            return status;
        }
        internal int Clone_(ref IEnumWbemClassObject ppEnum)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            if (null != scope)
            {
                IntPtr password = scope.Options.GetPassword();
                status = WmiNetUtilsHelper.CloneEnumWbemClassObject_f(
                    out ppEnum,
                    (int)scope.Options.Authentication,
                    (int)scope.Options.Impersonation,
                    pEnumWbemClassObjectsecurityHelper,
                    scope.Options.Username,
                    password,
                    scope.Options.Authority);
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
            }
            return status;
        }
        internal int Skip_(int lTimeout, uint nCount)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pEnumWbemClassObjectsecurityHelper.Skip_(lTimeout, nCount);
            return status;
        }
    }


    internal sealed class SecuredConnectHandler
    {
        private readonly ManagementScope scope;

        internal SecuredConnectHandler(ManagementScope theScope)
        {
            this.scope = theScope;
        }
        internal int ConnectNSecureIWbemServices(string path, ref IWbemServices pServices)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            if (null != scope)
            {
                bool needToReset = false;
                IntPtr handle = IntPtr.Zero;

                try
                {
                    if (scope.Options.EnablePrivileges && !CompatSwitches.AllowIManagementObjectQI)
                    {
                        WmiNetUtilsHelper.SetSecurity_f(ref needToReset, ref handle);
                    }

                    IntPtr password = scope.Options.GetPassword();
                    status = WmiNetUtilsHelper.ConnectServerWmi_f(
                        path,
                        scope.Options.Username,
                        password,
                        scope.Options.Locale,
                        scope.Options.Flags,
                        scope.Options.Authority,
                        scope.Options.GetContext(),
                        out pServices,
                        (int)scope.Options.Impersonation,
                        (int)scope.Options.Authentication);
                    System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
                }
                finally
                {
                    if (needToReset)
                    {
                        needToReset = false;
                        WmiNetUtilsHelper.ResetSecurity_f(handle);
                    }
                }
            }
            return status;
        }
    }

    internal sealed class SecuredIWbemServicesHandler
    {
        private readonly IWbemServices pWbemServiecsSecurityHelper;
        private readonly ManagementScope scope;
        internal SecuredIWbemServicesHandler(ManagementScope theScope, IWbemServices pWbemServiecs)
        {
            this.scope = theScope;
            pWbemServiecsSecurityHelper = pWbemServiecs;
        }
        internal int OpenNamespace_(string strNamespace, int lFlags, ref IWbemServices ppWorkingNamespace, IntPtr ppCallResult)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_NOT_SUPPORTED;
            //This should go through WMINET_utils layer and ppWorkingNamespace should be secured. See implementation of CreateInstanceEnum method.
            return status;
        }

        internal int CancelAsyncCall_(IWbemObjectSink pSink)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.CancelAsyncCall_(pSink);
            return status;
        }
        internal int QueryObjectSink_(int lFlags, ref IWbemObjectSink ppResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.QueryObjectSink_(lFlags, out ppResponseHandler);
            return status;
        }
        internal int GetObject_(string strObjectPath, int lFlags, IWbemContext pCtx, ref IWbemClassObjectFreeThreaded ppObject, IntPtr ppCallResult)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.GetObject_(strObjectPath, lFlags, pCtx, out ppObject, ppCallResult);
            return status;
        }

        internal int GetObjectAsync_(string strObjectPath, int lFlags, IWbemContext pCtx, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.GetObjectAsync_(strObjectPath, lFlags, pCtx, pResponseHandler);
            return status;
        }
        internal int PutClass_(IWbemClassObjectFreeThreaded pObject, int lFlags, IWbemContext pCtx, IntPtr ppCallResult)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            if (null != scope)
            {
                IntPtr password = scope.Options.GetPassword();
                status = WmiNetUtilsHelper.PutClassWmi_f(pObject,
                    lFlags,
                    pCtx,
                    ppCallResult,
                    (int)scope.Options.Authentication,
                    (int)scope.Options.Impersonation,
                    pWbemServiecsSecurityHelper,
                    scope.Options.Username,
                    password,
                    scope.Options.Authority);
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
            }
            return status;
        }
        internal int PutClassAsync_(IWbemClassObjectFreeThreaded pObject, int lFlags, IWbemContext pCtx, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.PutClassAsync_(pObject, lFlags, pCtx, pResponseHandler);
            return status;
        }
        internal int DeleteClass_(string strClass, int lFlags, IWbemContext pCtx, IntPtr ppCallResult)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.DeleteClass_(strClass, lFlags, pCtx, ppCallResult);
            return status;
        }
        internal int DeleteClassAsync_(string strClass, int lFlags, IWbemContext pCtx, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.DeleteClassAsync_(strClass, lFlags, pCtx, pResponseHandler);
            return status;
        }
        internal int CreateClassEnum_(string strSuperClass, int lFlags, IWbemContext pCtx, ref IEnumWbemClassObject ppEnum)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            if (null != scope)
            {
                IntPtr password = scope.Options.GetPassword();
                status = WmiNetUtilsHelper.CreateClassEnumWmi_f(strSuperClass,
                    lFlags,
                    pCtx,
                    out ppEnum,
                    (int)scope.Options.Authentication,
                    (int)scope.Options.Impersonation,
                    pWbemServiecsSecurityHelper,
                    scope.Options.Username,
                    password,
                    scope.Options.Authority);
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
            }
            return status;
        }
        internal int CreateClassEnumAsync_(string strSuperClass, int lFlags, IWbemContext pCtx, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.CreateClassEnumAsync_(strSuperClass, lFlags, pCtx, pResponseHandler);
            return status;
        }
        internal int PutInstance_(IWbemClassObjectFreeThreaded pInst, int lFlags, IWbemContext pCtx, IntPtr ppCallResult)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            if (null != scope)
            {
                IntPtr password = scope.Options.GetPassword();
                status = WmiNetUtilsHelper.PutInstanceWmi_f(pInst,
                    lFlags,
                    pCtx,
                    ppCallResult,
                    (int)scope.Options.Authentication,
                    (int)scope.Options.Impersonation,
                    pWbemServiecsSecurityHelper,
                    scope.Options.Username,
                    password,
                    scope.Options.Authority);
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
            }
            return status;
        }
        internal int PutInstanceAsync_(IWbemClassObjectFreeThreaded pInst, int lFlags, IWbemContext pCtx, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.PutInstanceAsync_(pInst, lFlags, pCtx, pResponseHandler);
            return status;
        }
        internal int DeleteInstance_(string strObjectPath, int lFlags, IWbemContext pCtx, IntPtr ppCallResult)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.DeleteInstance_(strObjectPath, lFlags, pCtx, ppCallResult);
            return status;
        }
        internal int DeleteInstanceAsync_(string strObjectPath, int lFlags, IWbemContext pCtx, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.DeleteInstanceAsync_(strObjectPath, lFlags, pCtx, pResponseHandler);
            return status;
        }

        internal int CreateInstanceEnum_(string strFilter, int lFlags, IWbemContext pCtx, ref IEnumWbemClassObject ppEnum)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            if (null != scope)
            {
                IntPtr password = scope.Options.GetPassword();
                status = WmiNetUtilsHelper.CreateInstanceEnumWmi_f(strFilter,
                    lFlags,
                    pCtx,
                    out ppEnum,
                    (int)scope.Options.Authentication,
                    (int)scope.Options.Impersonation,
                    pWbemServiecsSecurityHelper,
                    scope.Options.Username,
                    password,
                    scope.Options.Authority);
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
            }
            return status;
        }
        internal int CreateInstanceEnumAsync_(string strFilter, int lFlags, IWbemContext pCtx, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.CreateInstanceEnumAsync_(strFilter, lFlags, pCtx, pResponseHandler);
            return status;
        }
        internal int ExecQuery_(string strQueryLanguage, string strQuery, int lFlags, IWbemContext pCtx, ref IEnumWbemClassObject ppEnum)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            if (null != scope)
            {
                IntPtr password = scope.Options.GetPassword();
                status = WmiNetUtilsHelper.ExecQueryWmi_f(strQueryLanguage,
                    strQuery,
                    lFlags,
                    pCtx,
                    out ppEnum,
                    (int)scope.Options.Authentication,
                    (int)scope.Options.Impersonation,
                    pWbemServiecsSecurityHelper,
                    scope.Options.Username,
                    password,
                    scope.Options.Authority);
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
            }
            return status;
        }
        internal int ExecQueryAsync_(string strQueryLanguage, string strQuery, int lFlags, IWbemContext pCtx, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.ExecQueryAsync_(strQueryLanguage, strQuery, lFlags, pCtx, pResponseHandler);
            return status;
        }
        internal int ExecNotificationQuery_(string strQueryLanguage, string strQuery, int lFlags, IWbemContext pCtx, ref IEnumWbemClassObject ppEnum)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            if (null != scope)
            {
                IntPtr password = scope.Options.GetPassword();
                status = WmiNetUtilsHelper.ExecNotificationQueryWmi_f(strQueryLanguage,
                    strQuery,
                    lFlags,
                    pCtx,
                    out ppEnum,
                    (int)scope.Options.Authentication,
                    (int)scope.Options.Impersonation,
                    pWbemServiecsSecurityHelper,
                    scope.Options.Username,
                    password,
                    scope.Options.Authority);
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
            }
            return status;
        }
        internal int ExecNotificationQueryAsync_(string strQueryLanguage, string strQuery, int lFlags, IWbemContext pCtx, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.ExecNotificationQueryAsync_(strQueryLanguage, strQuery, lFlags, pCtx, pResponseHandler);
            return status;
        }
        internal int ExecMethod_(string strObjectPath, string strMethodName, int lFlags, IWbemContext pCtx, IWbemClassObjectFreeThreaded pInParams, ref IWbemClassObjectFreeThreaded ppOutParams, IntPtr ppCallResult)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.ExecMethod_(strObjectPath, strMethodName, lFlags, pCtx, pInParams, out ppOutParams, ppCallResult);
            return status;
        }
        internal int ExecMethodAsync_(string strObjectPath, string strMethodName, int lFlags, IWbemContext pCtx, IWbemClassObjectFreeThreaded pInParams, IWbemObjectSink pResponseHandler)
        {
            int status = (int)tag_WBEMSTATUS.WBEM_E_FAILED;
            status = pWbemServiecsSecurityHelper.ExecMethodAsync_(strObjectPath, strMethodName, lFlags, pCtx, pInParams, pResponseHandler);
            return status;
        }
    }


    internal sealed class SecurityHandler
    {
        private bool needToReset;
        private readonly IntPtr handle;
        private readonly ManagementScope scope;

        internal SecurityHandler(ManagementScope theScope)
        {
            this.scope = theScope;
            if (null != scope)
            {
                if (scope.Options.EnablePrivileges)
                {
                    WmiNetUtilsHelper.SetSecurity_f(ref needToReset, ref handle);
                }
            }
        }

        internal void Reset()
        {
            if (needToReset)
            {
                needToReset = false;

                if (null != scope)
                {
                    WmiNetUtilsHelper.ResetSecurity_f(handle);
                }
            }

        }


        internal void Secure(IWbemServices services)
        {
            if (null != scope)
            {
                IntPtr password = scope.Options.GetPassword();
                int status = WmiNetUtilsHelper.BlessIWbemServices_f
                    (
                    services,
                    scope.Options.Username,
                    password,
                    scope.Options.Authority,
                    (int)scope.Options.Impersonation,
                    (int)scope.Options.Authentication
                    );
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
                if (status < 0)
                {
                    Marshal.ThrowExceptionForHR(status, WmiNetUtilsHelper.GetErrorInfo_f());
                }
            }
        }

        internal void SecureIUnknown(object unknown)
        {
            // We use a hack to call BlessIWbemServices with an IUnknown instead of an IWbemServices
            // In VNext, we should really change the implementation of WMINet_Utils.dll so that it has
            // a method which explicitly takes an IUnknown.  We rely on the fact that the implementation
            // of BlessIWbemServices actually casts the first parameter to IUnknown before blessing
            if (null != scope)
            {
                IntPtr password = scope.Options.GetPassword();
                int status = WmiNetUtilsHelper.BlessIWbemServicesObject_f
                    (
                    unknown,
                    scope.Options.Username,
                    password,
                    scope.Options.Authority,
                    (int)scope.Options.Impersonation,
                    (int)scope.Options.Authentication
                    );
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(password);
                if (status < 0)
                {
                    Marshal.ThrowExceptionForHR(status, WmiNetUtilsHelper.GetErrorInfo_f());
                }
            }
        }


    } //SecurityHandler


    /// <summary>
    /// Converts a String to a ManagementScope
    /// </summary>
    internal sealed class ManagementScopeConverter : ExpandableObjectConverter
    {

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

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

        /// <summary>
        ///      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 destination type, this will
        ///      throw a NotSupportedException.
        /// </summary>
        /// <param name='context'>An ITypeDescriptorContext that provides a format context.</param>
        /// <param name='culture'>A CultureInfo object. If a null reference (Nothing in Visual Basic) is passed, the current culture is assumed.</param>
        /// <param name='value'>The Object to convert.</param>
        /// <param name='destinationType'>The Type to convert the value parameter to.</param>
        /// <returns>An Object that represents the converted value.</returns>
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {

            ArgumentNullException.ThrowIfNull(destinationType);

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