internal ComTypeDefInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) : base(typeLib, typeKind, index) { TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); _infoType = "TypeDef"; if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("TypeDefInfo: " + _name); } _varComType = TypeLibUtil.TYPEDESCToString(typeLib, _typeInfo, typeAttr.tdescAlias, TypeLibUtil.COMTYPE); _varClrType = TypeLibUtil.TYPEDESCToString(typeLib, _typeInfo, typeAttr.tdescAlias, !TypeLibUtil.COMTYPE); _typeInfo.ReleaseTypeAttr(typeAttrPtr); // Add to the typelibrary for resolution typeLib.TypeDefHash.Add(_name, this); }
public static TYPEKIND_VBE ToTypeKindVbe(this TYPEKIND typeKind) { switch (typeKind) { case TYPEKIND.TKIND_ALIAS: return(TYPEKIND_VBE.TKIND_ALIAS); case TYPEKIND.TKIND_UNION: return(TYPEKIND_VBE.TKIND_UNION); case TYPEKIND.TKIND_COCLASS: return(TYPEKIND_VBE.TKIND_COCLASS); case TYPEKIND.TKIND_DISPATCH: return(TYPEKIND_VBE.TKIND_DISPATCH); case TYPEKIND.TKIND_ENUM: return(TYPEKIND_VBE.TKIND_ENUM); case TYPEKIND.TKIND_INTERFACE: return(TYPEKIND_VBE.TKIND_INTERFACE); case TYPEKIND.TKIND_MODULE: return(TYPEKIND_VBE.TKIND_MODULE); case TYPEKIND.TKIND_RECORD: return(TYPEKIND_VBE.TKIND_RECORD); case TYPEKIND.TKIND_MAX: return(TYPEKIND_VBE.TKIND_VBACLASS); default: throw new NotSupportedException(typeKind.ToString()); } }
internal ComTypeDefInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) : base(typeLib, typeKind, index) { TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); _infoType = "TypeDef"; if (TraceUtil.If(this, TraceLevel.Verbose)) Trace.WriteLine("TypeDefInfo: " + _name); _varComType = TypeLibUtil.TYPEDESCToString(typeLib, _typeInfo, typeAttr.tdescAlias, TypeLibUtil.COMTYPE); _varClrType = TypeLibUtil.TYPEDESCToString(typeLib, _typeInfo, typeAttr.tdescAlias, !TypeLibUtil.COMTYPE); _typeInfo.ReleaseTypeAttr(typeAttrPtr); // Add to the typelibrary for resolution typeLib.TypeDefHash.Add(_name, this); }
protected void SetupTypeLibInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { if (_hasTypeLibInfo) { return; } base.Setup(typeLib, typeKind, index, typeInfo, guid); TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); _cImplTypes = typeAttr.cImplTypes; _typeFlags = typeAttr.wTypeFlags; _typeInfo.ReleaseTypeAttr(typeAttrPtr); _hasTypeLibInfo = true; }
// Get or create a interface info for the specified interface internal static ComInterfaceInfo GetInterfaceInfo (TypeLibrary typeLib, TYPEKIND typeKind, int index) { UCOMITypeInfo typeInfo; Guid guid; typeLib.ITypeLib.GetTypeInfo(index, out typeInfo); guid = GuidFromTypeInfo(typeInfo); // Use the TypeLibrary lock to prevent deadlocks lock (typeof(TypeLibrary)) { // Never heard of it, get the defining type library ComInterfaceInfo intInfo = (ComInterfaceInfo)_interfacesByGuid[guid]; if (intInfo == null) { // Add the interface to the table before we call // setup because setup will try to create the // inherited interfaces, and it should find // this one (otherwise it will stack overflow) intInfo = new ComInterfaceInfo(); _interfacesByGuid.Add(guid, intInfo); intInfo.Setup(typeLib, typeKind, index); } return(intInfo); } }
void ITypeLib.GetTypeInfoType(int index, out TYPEKIND pTKind) { Before($"{nameof(index)}: {index}"); _wrapper.GetTypeInfoType(index, out var t); After($"{nameof(pTKind)}: {t}"); pTKind = t; }
internal virtual void Setup(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { _typeLib = typeLib; _iTypeLib = typeLib.ITypeLib; if (typeInfo != null) { _typeInfo = typeInfo; } else { _iTypeLib.GetTypeInfo(index, out _typeInfo); } if (!guid.Equals(Guid.Empty)) { InitGuid(guid); } else { InitGuid(GuidFromTypeInfo(_typeInfo)); } _typeKind = typeKind; _presInfo = PresentationMap.GetInfo(_typeKind); GetDocumentation(index); if (TraceUtil.If(this, TraceLevel.Info)) { Trace.WriteLine(this, "Basic: " + typeKind + " " + this); } }
public TypeInfoMatchTarget(TypeLib typeLib, TypeInfo typeInfo, TYPEKIND typeKind) { m_typeLib = typeLib; m_typeInfo = typeInfo; m_typeKind = typeKind; m_typeString = TypeLibUtility.TypeKind2String(m_typeKind); m_guid = typeInfo.GetTypeAttr().Guid; }
// Used for subclassses that are classes, objects and interfaces // Where the type library information is known internal BasicInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) : this() { Setup(typeLib, typeKind, index, typeInfo, guid); }
public int CreateTypeInfo(IntPtr szName, TYPEKIND tkind, ref IntPtr ppCTInfo) { if (m_CreateTypeInfoFunc == null) { var fp = GetFunctionPointer(3); m_CreateTypeInfoFunc = (CreateTypeInfoFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(CreateTypeInfoFunc)); } return(m_CreateTypeInfoFunc(m_ptr, szName, tkind, ref ppCTInfo)); }
public int GetTypeInfoType(uint index, ref TYPEKIND pTKind) { if (m_GetTypeInfoTypeFunc == null) { var fp = GetFunctionPointer(5); m_GetTypeInfoTypeFunc = (GetTypeInfoTypeFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(GetTypeInfoTypeFunc)); } return(m_GetTypeInfoTypeFunc(m_ptr, index, ref pTKind)); }
public int GetTypeKind(ref TYPEKIND pTypeKind) { if (m_GetTypeKindFunc == null) { var fp = GetFunctionPointer(22); m_GetTypeKindFunc = (GetTypeKindFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(GetTypeKindFunc)); } return(m_GetTypeKindFunc(m_ptr, ref pTypeKind)); }
public TypeInfoMatchTarget(TypeLib typeLib, TypeInfo typeInfo, TYPEKIND typeKind) { if (typeInfo == null) throw new ArgumentNullException(nameof(typeInfo)); m_typeLib = typeLib; m_typeInfo = typeInfo; m_typeKind = typeKind; m_typeString = TypeLibUtility.TypeKind2String(m_typeKind); m_guid = typeInfo.GetTypeAttr().Guid; }
internal static ComMemberInfo MakeComMemberInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index, bool dispatch, bool dual) { IntPtr funcDescPtr; FUNCDESC funcDesc; ComMemberInfo comMemberInfo = null; typeInfo.GetFuncDesc(index, out funcDescPtr); funcDesc = (FUNCDESC)Marshal.PtrToStructure(funcDescPtr, typeof(FUNCDESC)); // from http://www.opengroup.org/onlinepubs/009899899/toc.htm // Table 25-43: MEMBERID Format // // Bits Value // 0 - 15 Offset. Any value is permissible. // 16 - 21 The nesting level of this type information // in the inheritance hierarchy. For example: // interface mydisp : IDispatch. // The nesting level of IUnknown() is 0, // IDispatch is 1, and MyDisp is 2. // 22 - 25 Reserved. Must be zero. // 26 - 28 Value of the DISPID. // 29 TRUE if this is the member ID for a FUNCDESC; otherwise FALSE. // 30 - 31 Must be 01. // For a dispatch interface, show only those members that are // part of the user's definition, which is bits 16-17 == 2 // (as above); also only if this is a MEMBERID format (bit 30 on) // (some members just use the low order bits and the rest // are empty); also show any negative member Id. if (!dispatch || // ((Int16)funcDesc.memid < 0) || (funcDesc.memid & 0xFFFF) < 0 || (funcDesc.memid & 0x40000000) == 0 || (funcDesc.memid & 0x30000) == 0x20000) { comMemberInfo = new ComMemberInfo(parent, typeKind, typeInfo, index, dispatch, funcDesc); } else { if (TraceUtil.If(null, TraceLevel.Verbose)) { Trace.WriteLine("MemberInfo: SKIPPING index: " + index + " memid: 0x" + funcDesc.memid.ToString("X")); } } typeInfo.ReleaseFuncDesc(funcDescPtr); return(comMemberInfo); }
// Constuctor when creating from withing a typelib protected ComClassInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { Init(); SetupTypeLibInfo(typeLib, typeKind, index, typeInfo, guid); _classesByCLSID.Add(_guid, this); }
internal static TreeNode GetTypeLibNode(TypeLib tlb, DisplayLevel displayLevel) { string typeLibName = tlb.GetDocumentation(); TreeNode root = new TreeNode(typeLibName); root.Tag = tlb; int nCount = tlb.GetTypeInfoCount(); for (int n = 0; n < nCount; ++n) { TypeInfo type = tlb.GetTypeInfo(n); //string typeTypeName = type.GetDocumentation(); //NativeType2String.AddNativeUserDefinedType(typeTypeName); // For dual interfaces, it has a "funky" TKIND_DISPATCH|TKIND_DUAL interface with a parter of TKIND_INTERFACE|TKIND_DUAL interface // The first one is pretty bad and has duplicated all the interface members of its parent, which is not we want // We want the second v-table interface // So, if we indeed has seen this kind of interface, prefer its partner // However, we should not blindly get the partner because those two interfaces partners with each other // So we need to first test to see if the interface is both dispatch & dual, and then get its partner interface using (TypeAttr attr = type.GetTypeAttr()) { if (attr.IsDual && attr.IsDispatch) { TypeInfo typeReferencedType = type.GetRefTypeNoComThrow(); if (typeReferencedType != null) { type = typeReferencedType; } } } TreeNode typeInfoNode = new TreeNode(); TypeInfoMatchTarget typeInfoMatchTarget = null; root.Nodes.Add(typeInfoNode); using (TypeAttr attr = type.GetTypeAttr()) { TYPEKIND kind = attr.typekind; typeInfoMatchTarget = new TypeInfoMatchTarget(tlb, type, kind); if (displayLevel == DisplayLevel.All) { ProcessFunctions(type, typeInfoNode); ProcessFields(type, typeInfoNode); } } typeInfoNode.Text = typeInfoMatchTarget.Name + ": " + typeInfoMatchTarget.Type; typeInfoNode.Tag = typeInfoMatchTarget; SetTlbTreeNodeImage(typeInfoNode); } return(root); }
internal static ComMemberInfo MakeComMemberInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index, bool dispatch, bool dual) { IntPtr funcDescPtr; FUNCDESC funcDesc; ComMemberInfo comMemberInfo = null; typeInfo.GetFuncDesc(index, out funcDescPtr); funcDesc = (FUNCDESC)Marshal.PtrToStructure(funcDescPtr, typeof(FUNCDESC)); // from http://www.opengroup.org/onlinepubs/009899899/toc.htm // Table 25-43: MEMBERID Format // // Bits Value // 0 - 15 Offset. Any value is permissible. // 16 - 21 The nesting level of this type information // in the inheritance hierarchy. For example: // interface mydisp : IDispatch. // The nesting level of IUnknown() is 0, // IDispatch is 1, and MyDisp is 2. // 22 - 25 Reserved. Must be zero. // 26 - 28 Value of the DISPID. // 29 TRUE if this is the member ID for a FUNCDESC; otherwise FALSE. // 30 - 31 Must be 01. // For a dispatch interface, show only those members that are // part of the user's definition, which is bits 16-17 == 2 // (as above); also only if this is a MEMBERID format (bit 30 on) // (some members just use the low order bits and the rest // are empty); also show any negative member Id. if (!dispatch || // ((Int16)funcDesc.memid < 0) || (funcDesc.memid & 0xFFFF) < 0 || (funcDesc.memid & 0x40000000) == 0 || (funcDesc.memid & 0x30000) == 0x20000) { comMemberInfo = new ComMemberInfo(parent, typeKind, typeInfo, index, dispatch, funcDesc); } else { if (TraceUtil.If(null, TraceLevel.Verbose)) { Trace.WriteLine("MemberInfo: SKIPPING index: " + index + " memid: 0x" + funcDesc.memid.ToString("X")); } } typeInfo.ReleaseFuncDesc(funcDescPtr); return comMemberInfo; }
internal ComStructInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) : base(typeLib, typeKind, index) { switch (typeKind) { case TYPEKIND.TKIND_ENUM: _infoType = "Enum"; break; case TYPEKIND.TKIND_MODULE: _infoType = "Module"; break; case TYPEKIND.TKIND_RECORD: _infoType = "Struct"; break; case TYPEKIND.TKIND_UNION: _infoType = "Union"; break; } TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); for (int i = 0; i < typeAttr.cVars; i++) { ComVariableInfo mi = new ComVariableInfo(this, _typeKind, _typeInfo, i); _members.Add(mi); } _typeInfo.ReleaseTypeAttr(typeAttrPtr); if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("Struct: " + _name); } }
internal ComStructInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) : base(typeLib, typeKind, index) { switch (typeKind) { case TYPEKIND.TKIND_ENUM: _infoType = "Enum"; break; case TYPEKIND.TKIND_MODULE: _infoType = "Module"; break; case TYPEKIND.TKIND_RECORD: _infoType = "Struct"; break; case TYPEKIND.TKIND_UNION: _infoType = "Union"; break; } TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); for (int i = 0; i < typeAttr.cVars; i++) { ComVariableInfo mi = new ComVariableInfo(this, _typeKind, _typeInfo, i); _members.Add(mi); } _typeInfo.ReleaseTypeAttr(typeAttrPtr); if (TraceUtil.If(this, TraceLevel.Verbose)) Trace.WriteLine("Struct: " + _name); }
// Returns a ComClassInfo for the requested class // Used for creating from within a typelib internal static ComClassInfo GetClassInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) { UCOMITypeInfo typeInfo; typeLib.ITypeLib.GetTypeInfo(index, out typeInfo); Guid guid = GuidFromTypeInfo(typeInfo); ComClassInfo clsInfo = (ComClassInfo)_classesByCLSID[guid]; if (clsInfo != null) { // Add the type lib information if we have seen this // class before clsInfo.SetupTypeLibInfo(typeLib, typeKind, index, null, Guid.Empty); return(clsInfo); } return(new ComClassInfo(typeLib, typeKind, index, typeInfo, guid)); }
protected void SetupTypeLibInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { if (_hasTypeLibInfo) return; base.Setup(typeLib, typeKind, index, typeInfo, guid); TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); _cImplTypes = typeAttr.cImplTypes; _typeFlags = typeAttr.wTypeFlags; _typeInfo.ReleaseTypeAttr(typeAttrPtr); _hasTypeLibInfo = true; }
// Get or create a interface info for the specified interface internal static ComInterfaceInfo GetInterfaceInfo (TypeLibrary typeLib, TYPEKIND typeKind, int index) { UCOMITypeInfo typeInfo; Guid guid; typeLib.ITypeLib.GetTypeInfo(index, out typeInfo); guid = GuidFromTypeInfo(typeInfo); // Use the TypeLibrary lock to prevent deadlocks lock (typeof(TypeLibrary)) { // Never heard of it, get the defining type library ComInterfaceInfo intInfo = (ComInterfaceInfo)_interfacesByGuid[guid]; if (intInfo == null) { // Add the interface to the table before we call // setup because setup will try to create the // inherited interfaces, and it should find // this one (otherwise it will stack overflow) intInfo = new ComInterfaceInfo(); _interfacesByGuid.Add(guid, intInfo); intInfo.Setup(typeLib, typeKind, index); } return intInfo; } }
// Constructor from creating withing a typelib internal override void Setup(TypeLibrary typeLib, TYPEKIND typeKind, int index) { base.Setup(typeLib, typeKind, index); Init(); _container = typeLib; TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); if (typeKind == TYPEKIND.TKIND_DISPATCH) { _infoType = "Dispatch Interface"; _dispatch = true; } else { _infoType = "Interface"; } if ((typeAttr.wTypeFlags & TYPEFLAGS.TYPEFLAG_FDUAL) != 0) { _infoType = "Dual Interface"; _dispatch = true; _dual = true; } // Members for (int i = 0; i < typeAttr.cFuncs; i++) { // Some members for a dispatch interface are not added // because they are the inherited members from the // IDispatch interface ComMemberInfo mi = ComMemberInfo. MakeComMemberInfo(this, typeKind, _typeInfo, i, _dispatch, _dual); if (mi != null) { _members.Add(mi); _memberNames.Add(mi.NameKey, mi); } } // Inherited interfaces for (int i = 0; i < typeAttr.cImplTypes; i++) { int href; int refTypeIndex; UCOMITypeInfo refTypeInfo; UCOMITypeLib refITypeLib; TypeLibrary refTypeLib; try { _typeInfo.GetRefTypeOfImplType(i, out href); _typeInfo.GetRefTypeInfo(href, out refTypeInfo); refTypeInfo.GetContainingTypeLib(out refITypeLib, out refTypeIndex); refTypeLib = TypeLibrary.GetTypeLib(refITypeLib); ComInterfaceInfo mi = ComInterfaceInfo.GetInterfaceInfo(refTypeLib, typeAttr.typekind, refTypeIndex); if (TraceUtil.If(this, TraceLevel.Verbose)) Trace.WriteLine(" inherit: " + mi); _members.Add(mi); _parentCount += 1 + mi.ParentCount; // Don't set the typelib on the member as multiple // typelibs may refer to the same interface mi._container = this; } catch (Exception ex) { ErrorDialog.Show (ex, "Warning - this error was detected when attempting " + "to find an ancestor of the interface " + _name + ". This is normal in the case where the type " + "library containing that interface " + "is not available. " + "In other situations this might be a bug and " + "should be reported.", "Warning - Cannot Access Inherited Interface", MessageBoxIcon.Warning); } } if (_dual) { _printName = (String)_name.Clone(); _printName += " (Dual)"; } else { _printName = _name; } _typeInfo.ReleaseTypeAttr(typeAttrPtr); }
/// <summary> /// Use a custom type kind /// </summary> /// <param name="typeKind"></param> public MockTypeInfo(TYPEKIND typeKind) : this() { _typeAttributes.typekind = typeKind; }
public AssemblyBuilder DoProcess( Object typeLib, string asmFilename, TypeLibImporterFlags flags, ITypeLibImporterNotifySink notifySink, byte[] publicKey, StrongNameKeyPair keyPair, string asmNamespace, Version asmVersion, bool isVersion2, bool isPreserveSig, bool isRemoveEnumPrefix) { m_resolver = notifySink; TypeLib tlb = new TypeLib((ITypeLib)typeLib); if (asmNamespace == null) { asmNamespace = tlb.GetDocumentation(); string fileName = System.IO.Path.GetFileNameWithoutExtension(asmFilename); if (fileName != asmNamespace) { asmNamespace = fileName; } // // Support for GUID_ManagedName (for namespace) // string customManagedNamespace = tlb.GetCustData(CustomAttributeGuids.GUID_ManagedName) as string; if (customManagedNamespace != null) { customManagedNamespace = customManagedNamespace.Trim(); if (customManagedNamespace.ToUpper().EndsWith(".DLL")) { customManagedNamespace = customManagedNamespace.Substring(0, customManagedNamespace.Length - 4); } else if (customManagedNamespace.ToUpper().EndsWith(".EXE")) { customManagedNamespace = customManagedNamespace.Substring(0, customManagedNamespace.Length - 4); } asmNamespace = customManagedNamespace; } } // // Check for GUID_ExportedFromComPlus // object value = tlb.GetCustData(CustomAttributeGuids.GUID_ExportedFromComPlus); if (value != null) { // Make this a critical failure, instead of returning null which will be ignored. throw new TlbImpGeneralException(Resource.FormatString("Err_CircularImport", asmNamespace), ErrorCode.Err_CircularImport); } string strModuleName = asmFilename; if (asmFilename.Contains("\\")) { int nIndex; for (nIndex = strModuleName.Length; strModuleName[nIndex - 1] != '\\'; --nIndex) { ; } strModuleName = strModuleName.Substring(nIndex); } // If the version information was not specified, then retrieve it from the typelib. if (asmVersion == null) { using (TypeLibAttr attr = tlb.GetLibAttr()) { asmVersion = new Version(attr.wMajorVerNum, attr.wMinorVerNum, 0, 0); } } // Assembly name should not have .DLL // while module name must contain the .DLL string strAsmName = String.Copy(strModuleName); if (strAsmName.EndsWith(".DLL", StringComparison.InvariantCultureIgnoreCase)) { strAsmName = strAsmName.Substring(0, strAsmName.Length - 4); } AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = strAsmName; assemblyName.SetPublicKey(publicKey); assemblyName.Version = asmVersion; assemblyName.KeyPair = keyPair; m_assemblyBuilder = CreateAssemblyBuilder(assemblyName, tlb, flags); m_moduleBuilder = CreateModuleBuilder(m_assemblyBuilder, strModuleName); // Add a listener for the reflection load only resolve events. AppDomain currentDomain = Thread.GetDomain(); ResolveEventHandler asmResolveHandler = new ResolveEventHandler(ReflectionOnlyResolveAsmEvent); currentDomain.ReflectionOnlyAssemblyResolve += asmResolveHandler; ConverterSettings settings; settings.m_isGenerateClassInterfaces = true; settings.m_namespace = asmNamespace; settings.m_flags = flags; settings.m_isVersion2 = isVersion2; settings.m_isPreserveSig = isPreserveSig; settings.m_isRemoveEnumPrefix = isRemoveEnumPrefix; m_converterInfo = new ConverterInfo(m_moduleBuilder, tlb, m_resolver, settings); // // Generate class interfaces // NOTE: // We have to create class interface ahead of time because of the need to convert default interfaces to // class interfafces. However, this creates another problem that the event interface is always named first // before the other interfaces, because we need to create the type builder for the event interface first // so that we can create a class interface that implement it. But in the previous version of TlbImp, // it doesn't have to do that because it can directly create a typeref with the class interface name, // without actually creating anything like the TypeBuilder. The result is that the name would be different // with interop assemblies generated by old tlbimp in this case. // Given the nature of reflection API, this cannot be easily workarounded unless we switch to metadata APIs. // I believe this is acceptable because this only happens when: // 1. People decide to migrate newer .NET framework // 2. The event interface name conflicts with a normal interface // // In this case the problem can be easily fixed with a global refactoring, so I wouldn't worry about that // if (m_converterInfo.GenerateClassInterfaces) { CreateClassInterfaces(); } // // Generate the remaining types except coclass // Because during creating coclass, we require every type, including all the referenced type to be created // This is a restriction of reflection API that when you override a method in parent interface, the method info // is needed so the type must be already created and loaded // List <TypeInfo> coclassList = new List <TypeInfo>(); int nCount = tlb.GetTypeInfoCount(); for (int n = 0; n < nCount; ++n) { TypeInfo type = null; try { type = tlb.GetTypeInfo(n); string strType = type.GetDocumentation(); TypeInfo typeToProcess; TypeAttr attrToProcess; using (TypeAttr attr = type.GetTypeAttr()) { TYPEKIND kind = attr.typekind; if (kind == TYPEKIND.TKIND_ALIAS) { ConvCommon.ResolveAlias(type, attr.tdescAlias, out typeToProcess, out attrToProcess); if (attrToProcess.typekind == TYPEKIND.TKIND_ALIAS) { continue; } else { // We need to duplicate the definition of the user defined type in the name of the alias kind = attrToProcess.typekind; typeToProcess = type; attrToProcess = attr; } } else { typeToProcess = type; attrToProcess = attr; } switch (kind) { // Process coclass later because of reflection API requirements case TYPEKIND.TKIND_COCLASS: coclassList.Add(typeToProcess); break; case TYPEKIND.TKIND_ENUM: m_converterInfo.GetEnum(typeToProcess, attrToProcess); break; case TYPEKIND.TKIND_DISPATCH: case TYPEKIND.TKIND_INTERFACE: m_converterInfo.GetInterface(typeToProcess, attrToProcess); break; case TYPEKIND.TKIND_MODULE: m_converterInfo.GetModule(typeToProcess, attrToProcess); break; case TYPEKIND.TKIND_RECORD: m_converterInfo.GetStruct(typeToProcess, attrToProcess); break; case TYPEKIND.TKIND_UNION: m_converterInfo.GetUnion(typeToProcess, attrToProcess); break; } m_converterInfo.ReportEvent( MessageCode.Msg_TypeInfoImported, Resource.FormatString("Msg_TypeInfoImported", typeToProcess.GetDocumentation())); } } catch (ReflectionTypeLoadException) { throw; // Fatal failure. Throw } catch (TlbImpResolveRefFailWrapperException) { throw; // Fatal failure. Throw } catch (TlbImpGeneralException) { throw; // Fatal failure. Throw } catch (TypeLoadException) { throw; // TypeLoadException is critical. Throw. } catch (Exception) { } } // Process coclass after processing all the other types foreach (TypeInfo type in coclassList) { using (TypeAttr attr = type.GetTypeAttr()) { try { m_converterInfo.GetCoClass(type, attr); } catch (ReflectionTypeLoadException) { throw; // Fatal failure. Throw } catch (TlbImpResolveRefFailWrapperException) { throw; // Fatal failure. Throw } catch (TlbImpGeneralException) { throw; // Fatal failure. Throw } catch (TypeLoadException) { throw; // TypeLoadException is critical. Throw. } catch (Exception) { } } } // // Build an array of EventItfInfo & generate event provider / event sink helpers // Event.TCEAdapterGenerator eventAdapterGenerator = new Event.TCEAdapterGenerator(); List <Event.EventItfInfo> eventItfList = new List <Event.EventItfInfo>(); foreach (IConvBase symbol in m_converterInfo.GetAllConvBase) { IConvInterface convInterface = symbol as IConvInterface; if (convInterface != null) { if (convInterface.EventInterface != null) { Debug.Assert(convInterface.EventInterface is ConvEventInterfaceLocal); ConvEventInterfaceLocal local = convInterface.EventInterface as ConvEventInterfaceLocal; Type eventInterfaceType = convInterface.EventInterface.ManagedType; // Build EventItfInfo and add to the list Type sourceInterfaceType = convInterface.ManagedType; string sourceInterfaceName = sourceInterfaceType.FullName; Event.EventItfInfo eventItfInfo = new Event.EventItfInfo( eventInterfaceType.FullName, sourceInterfaceName, local.EventProviderName, eventInterfaceType, convInterface.ManagedType); eventItfList.Add(eventItfInfo); } } } eventAdapterGenerator.Process(m_moduleBuilder, eventItfList); return(m_assemblyBuilder); }
private void _Convert() { VarEnum vt = (VarEnum)m_typeDesc.vt; // Strip out VT_PTR while (vt == VarEnum.VT_PTR) { m_typeDesc = m_typeDesc.lptdesc; vt = (VarEnum)m_typeDesc.vt; m_nativeIndirections++; } // Strip out VT_BYREF if ((vt & VarEnum.VT_BYREF) != 0) { vt &= ~VarEnum.VT_BYREF; m_nativeIndirections++; } // // Find the corresponding type and save it in result and store the custom attribute in m_attribute // Type result = null; m_attribute = null; switch (vt) { case VarEnum.VT_HRESULT: result = typeof(int); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.Error); SetUnmanagedType(UnmanagedType.Error); break; case VarEnum.VT_VOID: result = typeof(void); break; case VarEnum.VT_UINT: result = typeof(uint); break; case VarEnum.VT_INT: result = typeof(int); break; case VarEnum.VT_UI1: result = typeof(byte); break; case VarEnum.VT_UI2: result = typeof(ushort); break; case VarEnum.VT_UI4: result = typeof(uint); break; case VarEnum.VT_UI8: result = typeof(ulong); break; case VarEnum.VT_I1: result = typeof(sbyte); break; case VarEnum.VT_I2: result = typeof(short); break; case VarEnum.VT_I4: result = typeof(int); break; case VarEnum.VT_I8: result = typeof(long); break; case VarEnum.VT_R4: result = typeof(float); break; case VarEnum.VT_R8: result = typeof(double); break; case VarEnum.VT_ERROR: result = typeof(int); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.Error); SetUnmanagedType(UnmanagedType.Error); break; case VarEnum.VT_BSTR: result = typeof(string); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.BStr); SetUnmanagedType(UnmanagedType.BStr); // BSTR => string is special as BSTR are actually OLECHAR*, so we should add one indirection m_nativeIndirections++; break; case VarEnum.VT_DISPATCH: if (m_convertingNewEnumMember) { // When we are creating a new enum member, convert IDispatch to IEnumVariant TryUseCustomMarshaler(WellKnownGuids.IID_IEnumVARIANT, out result); } else { result = typeof(object); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.IDispatch); SetUnmanagedType(UnmanagedType.IDispatch); } // VT_DISPATCH => IDispatch * m_nativeIndirections++; break; case VarEnum.VT_UNKNOWN: if (m_convertingNewEnumMember) { // When we are creating a new enum member, convert IUnknown to IEnumVariant TryUseCustomMarshaler(WellKnownGuids.IID_IEnumVARIANT, out result); } else { result = typeof(object); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.IUnknown); SetUnmanagedType(UnmanagedType.IUnknown); } // VT_UNKNOWN => IUnknown * m_nativeIndirections++; break; case VarEnum.VT_LPSTR: result = typeof(string); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.LPStr); SetUnmanagedType(UnmanagedType.LPStr); m_nativeIndirections++; break; case VarEnum.VT_LPWSTR: result = typeof(string); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.LPWStr); SetUnmanagedType(UnmanagedType.LPWStr); m_nativeIndirections++; break; case VarEnum.VT_PTR: Debug.Assert(false, "Should not get here"); break; case VarEnum.VT_SAFEARRAY: { TypeDesc arrayDesc = m_typeDesc.lpadesc.tdescElem; VarEnum arrayVt = (VarEnum)arrayDesc.vt; Type userDefinedType = null; TypeConverter elemTypeConverter = new TypeConverter(m_info, m_typeInfo, arrayDesc, ConversionType.Element); Type elemType = elemTypeConverter.ConvertedType; // Determine the right VT for MarshalAs attribute bool pointerArray = false; if (arrayVt == VarEnum.VT_PTR) { arrayDesc = arrayDesc.lptdesc; arrayVt = (VarEnum)arrayDesc.vt; pointerArray = true; // We don't support marshalling pointers in array except UserType* & void* if (arrayVt != VarEnum.VT_USERDEFINED && arrayVt != VarEnum.VT_VOID) { arrayVt = VarEnum.VT_INT; m_conversionLoss = true; } } // // Emit UserDefinedSubType if necessary // if (arrayVt == VarEnum.VT_USERDEFINED) { if (elemType.IsEnum) { if (pointerArray) { arrayVt = VarEnum.VT_INT; m_conversionLoss = true; } else { // For enums, using VT_RECORD is better than VT_I4 // Within the runtime, if you specify VT_I4 for enums in SafeArray, we treat it the same way as VT_RECORD // Reflection API also accepts VT_RECORD instead of VT_I4 arrayVt = VarEnum.VT_RECORD; } } else if (elemType.IsValueType) { if (pointerArray) { arrayVt = VarEnum.VT_INT; m_conversionLoss = true; } else { arrayVt = VarEnum.VT_RECORD; } } else if (elemType.IsInterface) { if (pointerArray) { // decide VT_UNKNOWN / VT_DISPATCH if (InterfaceSupportsDispatch(elemType)) { arrayVt = VarEnum.VT_DISPATCH; } else { arrayVt = VarEnum.VT_UNKNOWN; } } else { arrayVt = VarEnum.VT_INT; m_conversionLoss = true; } } else if (elemType == typeof(object) && !elemTypeConverter.UseDefaultMarshal && (elemTypeConverter.UnmanagedType == UnmanagedType.IUnknown)) { // Special case for object that doesn't have default interface and will be marshalled as IUnknown arrayVt = VarEnum.VT_UNKNOWN; } userDefinedType = elemType; } m_conversionLoss |= elemTypeConverter.IsConversionLoss; // Transform to System.Array if /sysarray is set and not vararg if (((m_info.Settings.m_flags & TypeLibImporterFlags.SafeArrayAsSystemArray) != 0) && m_conversionType != ConversionType.VarArgParameter) { result = typeof(System.Array); } else { result = elemType.MakeArrayType(); // Don't need SafeArrayUserDefinedSubType for non System.Array case userDefinedType = null; } // TlbImp doesn't have this check for vt == VT_RECORD/VT_UNKNOWN/VT_DISPATCH therefore // it will emit SafeArrayUserDefinedSubType even it is not necessary/not valid // TlbImp2 will take this into account if ((userDefinedType != null) && (arrayVt == VarEnum.VT_RECORD || arrayVt == VarEnum.VT_UNKNOWN || arrayVt == VarEnum.VT_DISPATCH)) { // The name of the type would be full name in TlbImp2 m_attribute = CustomAttributeHelper.GetBuilderForMarshalAsSafeArrayAndUserDefinedSubType(arrayVt, userDefinedType); } else { // Use I4 for enums when SafeArrayUserDefinedSubType is not specified if (elemType.IsEnum && arrayVt == VarEnum.VT_RECORD) { arrayVt = VarEnum.VT_I4; } m_attribute = CustomAttributeHelper.GetBuilderForMarshalAsSafeArray(arrayVt); } SetUnmanagedType(UnmanagedType.SafeArray); // SafeArray <=> array is special because SafeArray is similar to Element* m_nativeIndirections++; break; } case VarEnum.VT_RECORD: case VarEnum.VT_USERDEFINED: { // Handle structs, interfaces, enums, and unions // Support for aliasing TypeInfo realType; TypeAttr realAttr; ConvCommon.ResolveAlias(m_typeInfo, m_typeDesc, out realType, out realAttr); // Alias for a built-in type? if (realAttr.typekind == TYPEKIND.TKIND_ALIAS) { // Recurse to convert the built-in type TypeConverter builtinType = new TypeConverter(m_info, realType, realAttr.tdescAlias, m_conversionType); result = builtinType.ConvertedType; m_attribute = builtinType.m_attribute; } else { // Otherwise, we must have a non-aliased type, and it is a user defined type // We should use the TypeInfo that this TypeDesc refers to realType = m_typeDesc.GetUserDefinedTypeInfo(m_typeInfo); TYPEKIND typeKind = realAttr.typekind; using (realAttr = realType.GetTypeAttr()) { TypeLib typeLib = realType.GetContainingTypeLib(); // Convert StdOle2.Guid to System.Guid if (_IsStdOleGuid(realType)) { result = typeof(Guid); m_attribute = null; ResetUnmanagedType(); } else if (realAttr.Guid == WellKnownGuids.IID_IUnknown) { // Occasional goto makes sense // If VT_USERDEFINE *, and the VT_USERDEFINE is actually a VT_UNKNOWN => IUnknown *, we need to decrease the m_nativeIndirections // to compensate for the m_nativeIndirections++ in VT_UNKNOWN m_nativeIndirections--; goto case VarEnum.VT_UNKNOWN; } else if (realAttr.Guid == WellKnownGuids.IID_IDispatch) { // Occasional goto makes sense // See the IID_IUnknown case for why we need to -- m_nativeIndirections--; goto case VarEnum.VT_DISPATCH; } else { // Need to use CustomMarshaler? Type customMarshalerResultType; if (TryUseCustomMarshaler(realAttr.Guid, out customMarshalerResultType)) { result = customMarshalerResultType; } else { IConvBase ret = m_info.GetTypeRef(ConvCommon.TypeKindToConvType(typeKind), realType); if (m_conversionType == ConversionType.Field) { // Too bad. Reflection API requires that the field type must be created before creating // the struct/union type // Only process indirection = 0 case because > 1 case will be converted to IntPtr // Otherwise it will leads to a infinite recursion, if you consider the following scenario: // struct A // { // struct B // { // struct A *a; // } b; // } if (ret is ConvUnionLocal && m_nativeIndirections == 0) { ConvUnionLocal convUnion = ret as ConvUnionLocal; convUnion.Create(); } else if (ret is ConvStructLocal && m_nativeIndirections == 0) { ConvStructLocal convStruct = ret as ConvStructLocal; convStruct.Create(); } else if (ret is ConvEnumLocal && m_nativeIndirections == 0) { ConvEnumLocal convEnum = ret as ConvEnumLocal; convEnum.Create(); } } result = ret.ManagedType; // Don't reply on result.IsInterface as we have some weird scenarios like refering to a exported type lib // which has interfaces that are class interfaces and have the same name as a class. // For example, manage class M has a class interface _M, and their managed name are both M if (ret.ConvType == ConvType.Interface || ret.ConvType == ConvType.EventInterface || ret.ConvType == ConvType.ClassInterface) { m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.Interface); SetUnmanagedType(UnmanagedType.Interface); } if (ret.ConvType == ConvType.CoClass) { // We need to convert CoClass to default interface (could be converted to class interface if it is exclusive) in signatures Debug.Assert(ret is IConvCoClass); IConvCoClass convCoClass = ret as IConvCoClass; if (convCoClass.DefaultInterface != null) { // Use the default interface result = convCoClass.DefaultInterface.ManagedType; m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.Interface); SetUnmanagedType(UnmanagedType.Interface); } else { // The coclass has no default interface (source interface excluded) // Marshal it as IUnknown result = typeof(object); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.IUnknown); SetUnmanagedType(UnmanagedType.IUnknown); } } } } } } } break; case VarEnum.VT_VARIANT: result = typeof(object); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.Struct); SetUnmanagedType(UnmanagedType.Struct); // object is special that it will be marshaled to VARIANT // because we'll think object as having one indirection, now we are one indirection less, // so we need add 1 to m_indirections m_nativeIndirections++; break; case VarEnum.VT_CY: result = typeof(System.Decimal); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.Currency); SetUnmanagedType(UnmanagedType.Currency); break; case VarEnum.VT_DATE: result = typeof(System.DateTime); break; case VarEnum.VT_DECIMAL: result = typeof(System.Decimal); break; case VarEnum.VT_CARRAY: { TypeDesc elemTypeDesc = m_typeDesc.lptdesc; TypeConverter elemTypeConverter = new TypeConverter(m_info, m_typeInfo, elemTypeDesc, ConversionType.Element); Type elemType = elemTypeConverter.ConvertedType; result = elemType.MakeArrayType(); m_conversionLoss |= elemTypeConverter.IsConversionLoss; uint elements = 1; SAFEARRAYBOUND[] bounds = m_typeDesc.lpadesc.Bounds; foreach (SAFEARRAYBOUND bound in bounds) { elements *= bound.cElements; } // SizeConst can only hold Int32.MaxValue if (elements <= Int32.MaxValue) { UnmanagedType arrayType; if (m_conversionType == ConversionType.Field) { arrayType = UnmanagedType.ByValArray; } else { arrayType = UnmanagedType.LPArray; } if (elemTypeConverter.UseDefaultMarshal) { m_attribute = CustomAttributeHelper.GetBuilderForMarshalAsConstArray(arrayType, (int)elements); } else { if (elemTypeConverter.UnmanagedType == UnmanagedType.BStr || elemTypeConverter.UnmanagedType == UnmanagedType.LPStr || elemTypeConverter.UnmanagedType == UnmanagedType.LPWStr) { m_attribute = CustomAttributeHelper.GetBuilderForMarshalAsConstArray(arrayType, (int)elements, elemTypeConverter.UnmanagedType); } else { m_attribute = CustomAttributeHelper.GetBuilderForMarshalAsConstArray(arrayType, (int)elements); } } SetUnmanagedType(arrayType); } else { m_nativeIndirections = 0; result = typeof(IntPtr); m_attribute = null; ResetUnmanagedType(); m_conversionLoss = true; } } break; case VarEnum.VT_BOOL: // For VT_BOOL in fields, use short if v2 switch is not specified. if (m_conversionType == ConversionType.Field) { if (m_info.Settings.m_isVersion2) { result = typeof(bool); m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.VariantBool); } else { result = typeof(short); } } else { result = typeof(bool); } break; default: m_info.ReportEvent( WarningCode.Wrn_BadVtType, Resource.FormatString("Wrn_BadVtType", (int)vt, m_typeInfo.GetDocumentation())); result = typeof(IntPtr); m_conversionLoss = true; break; } // // String -> StringBuilder special case // if (result == typeof(string)) { if (_IsParamOut() && m_nativeIndirections == 1 && (m_conversionType == ConversionType.Parameter || m_conversionType == ConversionType.VarArgParameter)) { // [out] or [in, out] LPSTR/LPWSTR scenario if (vt != VarEnum.VT_BSTR) { // String is immutable and cannot be [out]/[in, out]. We can convert to StringBuilder result = typeof(StringBuilder); } else // VT_BSTR { // VT_BSTR is also immutable. So conversion loss here m_conversionLoss = true; result = typeof(IntPtr); m_attribute = null; m_nativeIndirections = 0; ResetUnmanagedType(); } } } // Special rule for void* => IntPtr if (result == typeof(void)) { result = typeof(IntPtr); switch (m_conversionType) { case ConversionType.Element: m_nativeIndirections = 0; break; case ConversionType.Field: m_nativeIndirections = 0; break; default: if (m_nativeIndirections > 1) { m_nativeIndirections = 1; } else { m_nativeIndirections = 0; } break; } } // // Process indirection // if (m_nativeIndirections > 0) { if (result.IsValueType) { switch (m_conversionType) { case ConversionType.VarArgParameter: case ConversionType.Parameter: // Decimal/Guid can support extra level of indirection using LpStruct in parameters // LpStruct has no effect in other places and for other types // Only use LpStruct for scenarios like GUID ** // This is different from old TlbImp. Old TlbImp will use IntPtr if ((result == typeof(Decimal) || result == typeof(Guid)) && m_nativeIndirections == 2) { m_nativeIndirections--; m_attribute = CustomAttributeHelper.GetBuilderForMarshalAs(UnmanagedType.LPStruct); ResetUnmanagedType(); SetUnmanagedType(UnmanagedType.LPStruct); } if (m_nativeIndirections >= 2) { m_conversionLoss = true; result = typeof(IntPtr); m_attribute = null; ResetUnmanagedType(); } else if (m_nativeIndirections > 0) { result = result.MakeByRefType(); } break; case ConversionType.Field: m_conversionLoss = true; result = typeof(IntPtr); m_attribute = null; ResetUnmanagedType(); break; case ConversionType.ParamRetVal: m_nativeIndirections--; goto case ConversionType.ReturnValue; // Fall through to ConversionType.ReturnValue case ConversionType.ReturnValue: if (m_nativeIndirections >= 1) { m_conversionLoss = true; result = typeof(IntPtr); m_attribute = null; ResetUnmanagedType(); } break; case ConversionType.Element: m_conversionLoss = true; result = typeof(IntPtr); m_attribute = null; ResetUnmanagedType(); break; } } else { switch (m_conversionType) { case ConversionType.Field: // ** => IntPtr, ConversionLoss if (m_nativeIndirections > 1) { result = typeof(IntPtr); m_conversionLoss = true; m_attribute = null; ResetUnmanagedType(); } break; case ConversionType.VarArgParameter: case ConversionType.Parameter: if (m_nativeIndirections > 2) { result = typeof(IntPtr); m_conversionLoss = true; m_attribute = null; ResetUnmanagedType(); } else if (m_nativeIndirections == 2) { result = result.MakeByRefType(); } break; case ConversionType.ParamRetVal: m_nativeIndirections--; goto case ConversionType.ReturnValue; // Fall through to ConversionType.ReturnValue case ConversionType.ReturnValue: if (m_nativeIndirections > 1) { result = typeof(IntPtr); m_conversionLoss = true; m_attribute = null; ResetUnmanagedType(); } break; case ConversionType.Element: if (m_nativeIndirections > 1) { m_conversionLoss = true; result = typeof(IntPtr); m_attribute = null; ResetUnmanagedType(); } break; } } } m_convertedType = result; }
internal ComMemberInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index, bool dispatch, FUNCDESC funcDesc) : base(typeInfo) { int actLen; String[] memberNames = new String[100]; _typeInfo.GetNames(funcDesc.memid, memberNames, memberNames.Length, out actLen); _memberId = funcDesc.memid; // the high order part of the memberId is flags // for a dispatch interface if (dispatch) { _memberId &= 0xffff; // Make sure we get a 16 bit integer so that negative // DISPIDs show up correctly _memberId = (Int16)_memberId; } String docString; // Note, use the original unmasked memberId _typeInfo.GetDocumentation(funcDesc.memid, out _name, out docString, out _helpContext, out _helpFile); // Set using property so that nulls are checked DocString = docString; _parameters = new ArrayList(); _typeLib = parent.TypeLib; _index = index; _container = parent; _printName = _name; _nameKey = (String)_name; // Add the DISPID to the dispatch interfaces if (dispatch) { _dispatch = true; _printName += " - " + _memberId; } if (TraceUtil.If(this, TraceLevel.Verbose)) Trace.WriteLine("MemberInfo: " + _name); _type = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, funcDesc.elemdescFunc.tdesc, TypeLibUtil.COMTYPE); if (funcDesc.invkind == INVOKEKIND.INVOKE_FUNC) { _infoType = "Function"; _property = false; if (funcDesc.cParams > 0) { AddParams(funcDesc, memberNames, funcDesc.cParams); } } else { if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYGET) { _printName += " (get)"; _nameKey += NAMEKEY_GET; } else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUT) { _printName += " (put)"; _nameKey += NAMEKEY_SET; } else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUTREF) { _printName += " (put ref)"; _nameKey += NAMEKEY_SETREF; } _infoType = "Property"; _property = true; } _flagsString = FlagsString((FUNCFLAGS)funcDesc.wFuncFlags); if (_property) { _presInfo = PresentationMap. GetInfo(PresentationMap.COM_PROPERTY); } else { _presInfo = PresentationMap. GetInfo(PresentationMap.COM_METHOD); } }
internal ComVariableInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index) : base(typeInfo) { IntPtr varDescPtr; CORRECT_VARDESC varDesc; _typeKind = typeKind; _typeLib = parent.TypeLib; _container = parent; _index = index; _typeInfo.GetVarDesc(_index, out varDescPtr); varDesc = (CORRECT_VARDESC) Marshal.PtrToStructure(varDescPtr, typeof(CORRECT_VARDESC)); int actLen; String[] memberNames = new String[100]; _typeInfo.GetNames(varDesc.memid, memberNames, memberNames.Length, out actLen); Name = memberNames[0]; if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("VariableInfo: " + _name); } if (_typeKind == TYPEKIND.TKIND_ENUM) { _infoType = "Constant"; try { Object value = Marshal.GetObjectForNativeVariant (varDesc.u.lpvarValue); _enumValue = value.ToString(); } catch (Exception ex) { _enumValue = "Unknown variant: 0x" + varDesc.u.lpvarValue.ToInt32().ToString("X"); TraceUtil.WriteLineWarning(this, "Exception reading enum value: " + ex); } } else { _infoType = "Variable"; } TYPEDESC typeDesc = varDesc.elemdescVar.tdesc; _varType = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, typeDesc, TypeLibUtil.COMTYPE); _typeInfo.ReleaseVarDesc(varDescPtr); _presInfo = PresentationMap. GetInfo(PresentationMap.COM_VARIABLE); }
public unsafe int GetTypeInfoType(uint index, TYPEKIND* pTKind) { ITypeLib_vtbl** @this = (ITypeLib_vtbl**)reference; ITypeLib_vtbl* vtbl = *@this; if (vtbl == null) throw new InvalidComObjectException(); Delegate genericDelegate = Marshal.GetDelegateForFunctionPointer(vtbl->method_5, typeof(delegate_5)); delegate_5 method = (delegate_5)genericDelegate; return method(@this, index, pTKind); }
internal virtual void Setup(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { _typeLib = typeLib; _iTypeLib = typeLib.ITypeLib; if (typeInfo != null) _typeInfo = typeInfo; else _iTypeLib.GetTypeInfo(index, out _typeInfo); if (!guid.Equals(Guid.Empty)) InitGuid(guid); else InitGuid(GuidFromTypeInfo(_typeInfo)); _typeKind = typeKind; _presInfo = PresentationMap.GetInfo(_typeKind); GetDocumentation(index); if (TraceUtil.If(this, TraceLevel.Info)) Trace.WriteLine(this, "Basic: " + typeKind + " " + this); }
// Constructor from creating withing a typelib internal override void Setup(TypeLibrary typeLib, TYPEKIND typeKind, int index) { base.Setup(typeLib, typeKind, index); Init(); _container = typeLib; TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); if (typeKind == TYPEKIND.TKIND_DISPATCH) { _infoType = "Dispatch Interface"; _dispatch = true; } else { _infoType = "Interface"; } if ((typeAttr.wTypeFlags & TYPEFLAGS.TYPEFLAG_FDUAL) != 0) { _infoType = "Dual Interface"; _dispatch = true; _dual = true; } // Members for (int i = 0; i < typeAttr.cFuncs; i++) { // Some members for a dispatch interface are not added // because they are the inherited members from the // IDispatch interface ComMemberInfo mi = ComMemberInfo. MakeComMemberInfo(this, typeKind, _typeInfo, i, _dispatch, _dual); if (mi != null) { _members.Add(mi); _memberNames.Add(mi.NameKey, mi); } } // Inherited interfaces for (int i = 0; i < typeAttr.cImplTypes; i++) { int href; int refTypeIndex; UCOMITypeInfo refTypeInfo; UCOMITypeLib refITypeLib; TypeLibrary refTypeLib; try { _typeInfo.GetRefTypeOfImplType(i, out href); _typeInfo.GetRefTypeInfo(href, out refTypeInfo); refTypeInfo.GetContainingTypeLib(out refITypeLib, out refTypeIndex); refTypeLib = TypeLibrary.GetTypeLib(refITypeLib); ComInterfaceInfo mi = ComInterfaceInfo.GetInterfaceInfo(refTypeLib, typeAttr.typekind, refTypeIndex); if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine(" inherit: " + mi); } _members.Add(mi); _parentCount += 1 + mi.ParentCount; // Don't set the typelib on the member as multiple // typelibs may refer to the same interface mi._container = this; } catch (Exception ex) { ErrorDialog.Show (ex, "Warning - this error was detected when attempting " + "to find an ancestor of the interface " + _name + ". This is normal in the case where the type " + "library containing that interface " + "is not available. " + "In other situations this might be a bug and " + "should be reported.", "Warning - Cannot Access Inherited Interface", MessageBoxIcon.Warning); } } if (_dual) { _printName = (String)_name.Clone(); _printName += " (Dual)"; } else { _printName = _name; } _typeInfo.ReleaseTypeAttr(typeAttrPtr); }
public int CreateTypeInfo([NativeTypeName("LPOLESTR")] ushort *szName, TYPEKIND tkind, ICreateTypeInfo **ppCTInfo) { return(((delegate * unmanaged <ICreateTypeLib2 *, ushort *, TYPEKIND, ICreateTypeInfo **, int>)(lpVtbl[3]))((ICreateTypeLib2 *)Unsafe.AsPointer(ref this), szName, tkind, ppCTInfo)); }
// Returns a ComClassInfo for the requested class // Used for creating from within a typelib internal static ComClassInfo GetClassInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) { UCOMITypeInfo typeInfo; typeLib.ITypeLib.GetTypeInfo(index, out typeInfo); Guid guid = GuidFromTypeInfo(typeInfo); ComClassInfo clsInfo = (ComClassInfo)_classesByCLSID[guid]; if (clsInfo != null) { // Add the type lib information if we have seen this // class before clsInfo.SetupTypeLibInfo(typeLib, typeKind, index, null, Guid.Empty); return clsInfo; } return new ComClassInfo(typeLib, typeKind, index, typeInfo, guid); }
internal ComMemberInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index, bool dispatch, FUNCDESC funcDesc) : base(typeInfo) { int actLen; String[] memberNames = new String[100]; _typeInfo.GetNames(funcDesc.memid, memberNames, memberNames.Length, out actLen); _memberId = funcDesc.memid; // the high order part of the memberId is flags // for a dispatch interface if (dispatch) { _memberId &= 0xffff; // Make sure we get a 16 bit integer so that negative // DISPIDs show up correctly _memberId = (Int16)_memberId; } String docString; // Note, use the original unmasked memberId _typeInfo.GetDocumentation(funcDesc.memid, out _name, out docString, out _helpContext, out _helpFile); // Set using property so that nulls are checked DocString = docString; _parameters = new ArrayList(); _typeLib = parent.TypeLib; _index = index; _container = parent; _printName = _name; _nameKey = (String)_name; // Add the DISPID to the dispatch interfaces if (dispatch) { _dispatch = true; _printName += " - " + _memberId; } if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("MemberInfo: " + _name); } _type = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, funcDesc.elemdescFunc.tdesc, TypeLibUtil.COMTYPE); if (funcDesc.invkind == INVOKEKIND.INVOKE_FUNC) { _infoType = "Function"; _property = false; if (funcDesc.cParams > 0) { AddParams(funcDesc, memberNames, funcDesc.cParams); } } else { if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYGET) { _printName += " (get)"; _nameKey += NAMEKEY_GET; } else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUT) { _printName += " (put)"; _nameKey += NAMEKEY_SET; } else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUTREF) { _printName += " (put ref)"; _nameKey += NAMEKEY_SETREF; } _infoType = "Property"; _property = true; } _flagsString = FlagsString((FUNCFLAGS)funcDesc.wFuncFlags); if (_property) { _presInfo = PresentationMap. GetInfo(PresentationMap.COM_PROPERTY); } else { _presInfo = PresentationMap. GetInfo(PresentationMap.COM_METHOD); } }
internal ComVariableInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index) : base(typeInfo) { IntPtr varDescPtr; CORRECT_VARDESC varDesc; _typeKind = typeKind; _typeLib = parent.TypeLib; _container = parent; _index = index; _typeInfo.GetVarDesc(_index, out varDescPtr); varDesc = (CORRECT_VARDESC) Marshal.PtrToStructure(varDescPtr, typeof(CORRECT_VARDESC)); int actLen; String[] memberNames = new String[100]; _typeInfo.GetNames(varDesc.memid, memberNames, memberNames.Length, out actLen); Name = memberNames[0]; if (TraceUtil.If(this, TraceLevel.Verbose)) Trace.WriteLine("VariableInfo: " + _name); if (_typeKind == TYPEKIND.TKIND_ENUM) { _infoType = "Constant"; try { Object value = Marshal.GetObjectForNativeVariant (varDesc.u.lpvarValue); _enumValue = value.ToString(); } catch (Exception ex) { _enumValue = "Unknown variant: 0x" + varDesc.u.lpvarValue.ToInt32().ToString("X"); TraceUtil.WriteLineWarning(this, "Exception reading enum value: " + ex); } } else { _infoType = "Variable"; } TYPEDESC typeDesc = varDesc.elemdescVar.tdesc; _varType = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, typeDesc, TypeLibUtil.COMTYPE); _typeInfo.ReleaseVarDesc(varDescPtr); _presInfo = PresentationMap. GetInfo(PresentationMap.COM_VARIABLE); }
// Used for subclassses that are classes, objects and interfaces // Where the type library information is known internal BasicInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) : this() { Setup(typeLib, typeKind, index, null, Guid.Empty); }
internal virtual void Setup(TypeLibrary typeLib, TYPEKIND typeKind, int index) { Setup(typeLib, typeKind, index, null, Guid.Empty); }
public void GetTypeInfoType(int index, out TYPEKIND pTKind) { throw new Exception("The method or operation is not implemented."); }