Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
ciminstancetypeadapter.cs401 linesDownload Raw Back to other
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections.Generic;6using System.Collections.ObjectModel;7using System.Globalization;8using System.Management.Automation;9using System.Reflection;10 11using Microsoft.Management.Infrastructure;12 13using Dbg = System.Management.Automation.Diagnostics;14 15namespace Microsoft.PowerShell.Cim16{17    /// <summary>18    /// Adapter that deals with CimInstance objects.19    /// </summary>20    /// <remarks>21    /// Implementing the PropertyOnlyAdapter for the time being as CimInstanceTypeAdapter currently22    /// supports only properties. If method support is needed in future, this should derive from23    /// Adapter class.24    /// </remarks>25    public sealed class CimInstanceAdapter : PSPropertyAdapter26    {27        private static PSAdaptedProperty GetCimPropertyAdapter(CimProperty property, object baseObject, string propertyName)28        {29            PSAdaptedProperty propertyToAdd = new(propertyName, property);30            propertyToAdd.baseObject = baseObject;31            // propertyToAdd.adapter = this;32            return propertyToAdd;33        }34 35        private static PSAdaptedProperty GetCimPropertyAdapter(CimProperty property, object baseObject)36        {37            try38            {39                string propertyName = property.Name;40                return GetCimPropertyAdapter(property, baseObject, propertyName);41            }42            catch (CimException)43            {44                // ignore "Name" property access failures and move on.45                return null;46            }47        }48 49        private static PSAdaptedProperty GetPSComputerNameAdapter(CimInstance cimInstance)50        {51            PSAdaptedProperty psComputerNameProperty = new(RemotingConstants.ComputerNameNoteProperty, cimInstance);52            psComputerNameProperty.baseObject = cimInstance;53            // psComputerNameProperty.adapter = this;54            return psComputerNameProperty;55        }56 57        /// <summary>58        /// </summary>59        /// <param name="baseObject"></param>60        /// <returns></returns>61        public override System.Collections.ObjectModel.Collection<PSAdaptedProperty> GetProperties(object baseObject)62        {63            // baseObject should never be null64            if (baseObject is not CimInstance cimInstance)65            {66                string msg = string.Format(CultureInfo.InvariantCulture,67                    CimInstanceTypeAdapterResources.BaseObjectNotCimInstance,68                    "baseObject",69                    typeof(CimInstance).ToString());70                throw new PSInvalidOperationException(msg);71            }72 73            Collection<PSAdaptedProperty> result = new();74 75            if (cimInstance.CimInstanceProperties != null)76            {77                foreach (CimProperty property in cimInstance.CimInstanceProperties)78                {79                    PSAdaptedProperty propertyToAdd = GetCimPropertyAdapter(property, baseObject);80                    if (propertyToAdd != null)81                    {82                        result.Add(propertyToAdd);83                    }84                }85            }86 87            PSAdaptedProperty psComputerNameProperty = GetPSComputerNameAdapter(cimInstance);88            if (psComputerNameProperty != null)89            {90                result.Add(psComputerNameProperty);91            }92 93            return result;94        }95 96        /// <summary>97        /// </summary>98        /// <param name="baseObject"></param>99        /// <param name="propertyName"></param>100        /// <returns></returns>101        public override PSAdaptedProperty GetProperty(object baseObject, string propertyName)102        {103            if (propertyName == null)104            {105                throw new PSArgumentNullException(nameof(propertyName));106            }107 108            // baseObject should never be null109            if (baseObject is not CimInstance cimInstance)110            {111                string msg = string.Format(CultureInfo.InvariantCulture,112                    CimInstanceTypeAdapterResources.BaseObjectNotCimInstance,113                    "baseObject",114                    typeof(CimInstance).ToString());115                throw new PSInvalidOperationException(msg);116            }117 118            CimProperty cimProperty = cimInstance.CimInstanceProperties[propertyName];119            if (cimProperty != null)120            {121                PSAdaptedProperty prop = GetCimPropertyAdapter(cimProperty, baseObject, propertyName);122                return prop;123            }124 125            if (propertyName.Equals(RemotingConstants.ComputerNameNoteProperty, StringComparison.OrdinalIgnoreCase))126            {127                PSAdaptedProperty prop = GetPSComputerNameAdapter(cimInstance);128                return prop;129            }130 131            return null;132        }133 134        /// <inheritdoc/>135        public override PSAdaptedProperty GetFirstPropertyOrDefault(object baseObject, MemberNamePredicate predicate)136        {137            if (predicate == null)138            {139                throw new PSArgumentNullException(nameof(predicate));140            }141 142            // baseObject should never be null143            if (baseObject is not CimInstance cimInstance)144            {145                string msg = string.Format(146                    CultureInfo.InvariantCulture,147                    CimInstanceTypeAdapterResources.BaseObjectNotCimInstance,148                    "baseObject",149                    typeof(CimInstance).ToString());150                throw new PSInvalidOperationException(msg);151            }152 153            if (predicate(RemotingConstants.ComputerNameNoteProperty))154            {155                PSAdaptedProperty prop = GetPSComputerNameAdapter(cimInstance);156                return prop;157            }158 159            foreach (CimProperty cimProperty in cimInstance.CimInstanceProperties)160            {161                if (cimProperty != null && predicate(cimProperty.Name))162                {163                    PSAdaptedProperty prop = GetCimPropertyAdapter(cimProperty, baseObject, cimProperty.Name);164                    return prop;165                }166            }167 168            return null;169        }170 171        internal static string CimTypeToTypeNameDisplayString(CimType cimType)172        {173            switch (cimType)174            {175                case CimType.DateTime:176                case CimType.Instance:177                case CimType.Reference:178                case CimType.DateTimeArray:179                case CimType.InstanceArray:180                case CimType.ReferenceArray:181                    return "CimInstance#" + cimType.ToString();182 183                default:184                    return ToStringCodeMethods.Type(185                        CimConverter.GetDotNetType(cimType));186            }187        }188 189        /// <summary>190        /// </summary>191        /// <param name="adaptedProperty"></param>192        /// <returns></returns>193        public override string GetPropertyTypeName(PSAdaptedProperty adaptedProperty)194        {195            ArgumentNullException.ThrowIfNull(adaptedProperty);196 197            if (adaptedProperty.Tag is CimProperty cimProperty)198            {199                return CimTypeToTypeNameDisplayString(cimProperty.CimType);200            }201 202            if (adaptedProperty.Name.Equals(RemotingConstants.ComputerNameNoteProperty, StringComparison.OrdinalIgnoreCase))203            {204                return ToStringCodeMethods.Type(typeof(string));205            }206 207            throw new ArgumentNullException(nameof(adaptedProperty));208        }209 210        /// <summary>211        /// </summary>212        /// <param name="adaptedProperty"></param>213        /// <returns></returns>214        public override object GetPropertyValue(PSAdaptedProperty adaptedProperty)215        {216            ArgumentNullException.ThrowIfNull(adaptedProperty);217 218            if (adaptedProperty.Tag is CimProperty cimProperty)219            {220                return cimProperty.Value;221            }222 223            if (adaptedProperty.Name.Equals(RemotingConstants.ComputerNameNoteProperty, StringComparison.OrdinalIgnoreCase))224            {225                CimInstance cimInstance = (CimInstance)adaptedProperty.Tag;226                return cimInstance.GetCimSessionComputerName();227            }228 229            throw new ArgumentNullException(nameof(adaptedProperty));230        }231 232        private static void AddTypeNameHierarchy(IList<string> typeNamesWithNamespace, IList<string> typeNamesWithoutNamespace, string namespaceName, string className)233        {234            if (!string.IsNullOrEmpty(namespaceName))235            {236                string fullTypeName = string.Create(CultureInfo.InvariantCulture, $"Microsoft.Management.Infrastructure.CimInstance#{namespaceName}/{className}");237                typeNamesWithNamespace.Add(fullTypeName);238            }239 240            typeNamesWithoutNamespace.Add(string.Create(CultureInfo.InvariantCulture, $"Microsoft.Management.Infrastructure.CimInstance#{className}"));241        }242 243        private static List<CimClass> GetInheritanceChain(CimInstance cimInstance)244        {245            List<CimClass> inheritanceChain = new();246            CimClass cimClass = cimInstance.CimClass;247            Dbg.Assert(cimClass != null, "CimInstance should always have ClassDecl");248            while (cimClass != null)249            {250                inheritanceChain.Add(cimClass);251                try252                {253                    cimClass = cimClass.CimSuperClass;254                }255                catch (CimException)256                {257                    break;258                }259            }260 261            return inheritanceChain;262        }263 264        /// <summary>265        /// </summary>266        /// <param name="baseObject"></param>267        /// <returns></returns>268        public override Collection<string> GetTypeNameHierarchy(object baseObject)269        {270            if (baseObject is not CimInstance cimInstance)271            {272                throw new ArgumentNullException(nameof(baseObject));273            }274 275            var typeNamesWithNamespace = new List<string>();276            var typeNamesWithoutNamespace = new List<string>();277 278            IList<CimClass> inheritanceChain = GetInheritanceChain(cimInstance);279            if ((inheritanceChain == null) || (inheritanceChain.Count == 0))280            {281                AddTypeNameHierarchy(282                    typeNamesWithNamespace,283                    typeNamesWithoutNamespace,284                    cimInstance.CimSystemProperties.Namespace,285                    cimInstance.CimSystemProperties.ClassName);286            }287            else288            {289                foreach (CimClass cimClass in inheritanceChain)290                {291                    AddTypeNameHierarchy(292                        typeNamesWithNamespace,293                        typeNamesWithoutNamespace,294                        cimClass.CimSystemProperties.Namespace,295                        cimClass.CimSystemProperties.ClassName);296                    cimClass.Dispose();297                }298            }299 300            var result = new List<string>();301            result.AddRange(typeNamesWithNamespace);302            result.AddRange(typeNamesWithoutNamespace);303 304            if (baseObject != null)305            {306                for (Type type = baseObject.GetType(); type != null; type = type.BaseType)307                {308                    result.Add(type.FullName);309                }310            }311 312            return new Collection<string>(result);313        }314 315        /// <summary>316        /// </summary>317        /// <param name="adaptedProperty"></param>318        /// <returns></returns>319        public override bool IsGettable(PSAdaptedProperty adaptedProperty)320        {321            /* I was explicitly asked to only use MI_FLAG_READONLY for now322            // based on DSP0004, version 2.6.0, section "5.5.3.41 Read" (page 85, lines 2881-2884)323            bool readQualifierValue = this.GetPropertyQualifierValue(adaptedProperty, "Read", defaultValue: true);324            return readQualifierValue;325            */326            return true;327        }328 329        /// <summary>330        /// </summary>331        /// <param name="adaptedProperty"></param>332        /// <returns></returns>333        public override bool IsSettable(PSAdaptedProperty adaptedProperty)334        {335            /* I was explicitly asked to only use MI_FLAG_READONLY for now336            // based on DSP0004, version 2.6.0, section "5.5.3.55 Write" (pages 89-90, lines 3056-3061)337            bool writeQualifierValue = this.GetPropertyQualifierValue(adaptedProperty, "Write", defaultValue: false);338            return writeQualifierValue;339            */340 341            if (adaptedProperty == null)342            {343                return false;344            }345 346            if (adaptedProperty.Tag is not CimProperty cimProperty)347            {348                return false;349            }350 351            bool isReadOnly = ((cimProperty.Flags & CimFlags.ReadOnly) == CimFlags.ReadOnly);352            bool isSettable = !isReadOnly;353            return isSettable;354        }355 356        /// <summary>357        /// </summary>358        /// <param name="adaptedProperty"></param>359        /// <param name="value"></param>360        public override void SetPropertyValue(PSAdaptedProperty adaptedProperty, object value)361        {362            ArgumentNullException.ThrowIfNull(adaptedProperty);363 364            if (!IsSettable(adaptedProperty))365            {366                throw new SetValueException("ReadOnlyCIMProperty",367                        null,368                        CimInstanceTypeAdapterResources.ReadOnlyCIMProperty,369                        adaptedProperty.Name);370            }371 372            CimProperty cimProperty = adaptedProperty.Tag as CimProperty;373            object valueToSet = value;374            if (valueToSet != null)375            {376                // Convert only if value is not null377                Type paramType;378                switch (cimProperty.CimType)379                {380                    case CimType.DateTime:381                        paramType = typeof(object);382                        break;383                    case CimType.DateTimeArray:384                        paramType = typeof(object[]);385                        break;386                    default:387                        paramType = CimConverter.GetDotNetType(cimProperty.CimType);388                        Dbg.Assert(paramType != null, "'default' case should only be used for well-defined CimType->DotNetType conversions");389                        break;390                }391 392                valueToSet = Adapter.PropertySetAndMethodArgumentConvertTo(393                    value, paramType, CultureInfo.InvariantCulture);394            }395 396            cimProperty.Value = valueToSet;397            return;398        }399    }400}401