private static System.Type GetValueTypeFromTypeDesc(System.Windows.Forms.NativeMethods.tagTYPEDESC typeDesc, UnsafeNativeMethods.ITypeInfo typeInfo, object[] typeData, StructCache structCache) { IntPtr unionMember; int hr = 0; switch (((System.Windows.Forms.NativeMethods.tagVT)typeDesc.vt)) { case System.Windows.Forms.NativeMethods.tagVT.VT_DISPATCH: case System.Windows.Forms.NativeMethods.tagVT.VT_UNKNOWN: typeData[0] = GetGuidForTypeInfo(typeInfo, structCache, null); return(VTToType((System.Windows.Forms.NativeMethods.tagVT)typeDesc.vt)); case System.Windows.Forms.NativeMethods.tagVT.VT_PTR: { System.Windows.Forms.NativeMethods.tagTYPEDESC data = (System.Windows.Forms.NativeMethods.tagTYPEDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEDESC)); try { try { UnsafeNativeMethods.PtrToStructure(typeDesc.unionMember, data); } catch { data = new System.Windows.Forms.NativeMethods.tagTYPEDESC { unionMember = (IntPtr)Marshal.ReadInt32(typeDesc.unionMember), vt = Marshal.ReadInt16(typeDesc.unionMember, 4) }; } if (data.vt == 12) { return(VTToType((System.Windows.Forms.NativeMethods.tagVT)data.vt)); } unionMember = data.unionMember; } finally { structCache.ReleaseStruct(data); } break; } case System.Windows.Forms.NativeMethods.tagVT.VT_USERDEFINED: unionMember = typeDesc.unionMember; break; default: return(VTToType((System.Windows.Forms.NativeMethods.tagVT)typeDesc.vt)); } UnsafeNativeMethods.ITypeInfo pTypeInfo = null; hr = typeInfo.GetRefTypeInfo(unionMember, ref pTypeInfo); if (!System.Windows.Forms.NativeMethods.Succeeded(hr)) { throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetRefTypeInfoFailed", new object[] { hr }), hr); } try { if (pTypeInfo != null) { IntPtr zero = IntPtr.Zero; hr = pTypeInfo.GetTypeAttr(ref zero); if (!System.Windows.Forms.NativeMethods.Succeeded(hr)) { throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { hr }), hr); } System.Windows.Forms.NativeMethods.tagTYPEATTR gtypeattr = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR)); UnsafeNativeMethods.PtrToStructure(zero, gtypeattr); try { Guid g = gtypeattr.guid; if (!Guid.Empty.Equals(g)) { typeData[0] = g; } switch (gtypeattr.typekind) { case 0: return(ProcessTypeInfoEnum(pTypeInfo, structCache)); case 3: case 5: return(VTToType(System.Windows.Forms.NativeMethods.tagVT.VT_UNKNOWN)); case 4: return(VTToType(System.Windows.Forms.NativeMethods.tagVT.VT_DISPATCH)); case 6: return(GetValueTypeFromTypeDesc(gtypeattr.Get_tdescAlias(), pTypeInfo, typeData, structCache)); } return(null); } finally { pTypeInfo.ReleaseTypeAttr(zero); structCache.ReleaseStruct(gtypeattr); } } } finally { pTypeInfo = null; } return(null); }