/********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ #if !SILVERLIGHT // ComObject using System.Runtime.InteropServices.ComTypes; using System.Text; using Marshal = System.Runtime.InteropServices.Marshal; using VarEnum = System.Runtime.InteropServices.VarEnum; namespace System.Management.Automation.ComInterop { /// /// The parameter description of a method defined in a type library /// internal class ComParamDesc { # region private fields private readonly VarEnum _vt; private readonly string _name; # endregion # region ctor /// /// Creates a representation for the parameter of a COM method /// internal ComParamDesc(ref ELEMDESC elemDesc, string name) { // Ensure _defaultValue is set to DBNull.Value regardless of whether or not the // default value is extracted from the parameter description. Failure to do so // yields a runtime exception in the ToString() function. DefaultValue = DBNull.Value; if (!String.IsNullOrEmpty(name)) { // This is a parameter, not a return value IsOut = (elemDesc.desc.paramdesc.wParamFlags & PARAMFLAG.PARAMFLAG_FOUT) != 0; IsOptional = (elemDesc.desc.paramdesc.wParamFlags & PARAMFLAG.PARAMFLAG_FOPT) != 0; // TODO: The PARAMDESCEX struct has a memory issue that needs to be resolved. For now, we ignore it. //_defaultValue = PARAMDESCEX.GetDefaultValue(ref elemDesc.desc.paramdesc); } _name = name; _vt = (VarEnum)elemDesc.tdesc.vt; TYPEDESC typeDesc = elemDesc.tdesc; while (true) { if (_vt == VarEnum.VT_PTR) { ByReference = true; } else if (_vt == VarEnum.VT_ARRAY) { IsArray = true; } else { break; } TYPEDESC childTypeDesc = (TYPEDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(TYPEDESC)); _vt = (VarEnum)childTypeDesc.vt; typeDesc = childTypeDesc; } VarEnum vtWithoutByref = _vt; if ((_vt & VarEnum.VT_BYREF) != 0) { vtWithoutByref = (_vt & ~VarEnum.VT_BYREF); ByReference = true; } ParameterType = VarEnumSelector.GetTypeForVarEnum(vtWithoutByref); } /// /// Creates a representation for the return value of a COM method /// TODO: Return values should be represented by a different type /// internal ComParamDesc(ref ELEMDESC elemDesc) : this(ref elemDesc, String.Empty) { } public override string ToString() { StringBuilder result = new StringBuilder(); if (IsOptional) { result.Append("[Optional] "); } if (IsOut) { result.Append("[out]"); } result.Append(ParameterType.Name); if (IsArray) { result.Append("[]"); } if (ByReference) { result.Append("&"); } result.Append(" "); result.Append(_name); if (DefaultValue != DBNull.Value) { result.Append("="); result.Append(DefaultValue.ToString()); } return result.ToString(); } # endregion # region properties public bool IsOut { get; } public bool IsOptional { get; } public bool ByReference { get; } public bool IsArray { get; } public Type ParameterType { get; } /// /// DBNull.Value if there is no default value /// internal object DefaultValue { get; } # endregion } } #endif