void ComTypes.ITypeLib.GetTypeInfoType(int index, out ComTypes.TYPEKIND pTKind) { // initialize out parameters pTKind = default; using (var typeKindPtr = AddressableVariables.Create <ComTypes.TYPEKIND>()) { var hr = _this_Internal.GetTypeInfoType(index, typeKindPtr.Address); if (ComHelper.HRESULT_FAILED(hr)) { HandleBadHRESULT(hr); } pTKind = typeKindPtr.Value; } }
internal static ComTypeLibDesc GetFromTypeLib(ComTypes.ITypeLib typeLib) { // check whether we have already loaded this type library ComTypes.TYPELIBATTR typeLibAttr = ComRuntimeHelpers.GetTypeAttrForTypeLib(typeLib); ComTypeLibDesc typeLibDesc; lock (s_cachedTypeLibDesc) { if (s_cachedTypeLibDesc.TryGetValue(typeLibAttr.guid, out typeLibDesc)) { return(typeLibDesc); } } typeLibDesc = new ComTypeLibDesc { Name = ComRuntimeHelpers.GetNameOfLib(typeLib), _typeLibAttributes = typeLibAttr }; int countTypes = typeLib.GetTypeInfoCount(); for (int i = 0; i < countTypes; i++) { typeLib.GetTypeInfoType(i, out ComTypes.TYPEKIND typeKind); typeLib.GetTypeInfo(i, out ComTypes.ITypeInfo typeInfo); if (typeKind == ComTypes.TYPEKIND.TKIND_COCLASS) { ComTypeClassDesc classDesc = new ComTypeClassDesc(typeInfo, typeLibDesc); typeLibDesc._classes.AddLast(classDesc); } else if (typeKind == ComTypes.TYPEKIND.TKIND_ENUM) { ComTypeEnumDesc enumDesc = new ComTypeEnumDesc(typeInfo, typeLibDesc); typeLibDesc._enums.Add(enumDesc.TypeName, enumDesc); } else if (typeKind == ComTypes.TYPEKIND.TKIND_ALIAS) { ComTypes.TYPEATTR typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo); if (typeAttr.tdescAlias.vt == (short)VarEnum.VT_USERDEFINED) { ComRuntimeHelpers.GetInfoFromType(typeInfo, out string aliasName, out _); typeInfo.GetRefTypeInfo(typeAttr.tdescAlias.lpValue.ToInt32(), out ComTypes.ITypeInfo referencedTypeInfo); ComTypes.TYPEATTR referencedTypeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(referencedTypeInfo); ComTypes.TYPEKIND referencedTypeKind = referencedTypeAttr.typekind; if (referencedTypeKind == ComTypes.TYPEKIND.TKIND_ENUM) { ComTypeEnumDesc enumDesc = new ComTypeEnumDesc(referencedTypeInfo, typeLibDesc); typeLibDesc._enums.Add(aliasName, enumDesc); } } } } // cached the typelib using the guid as the dictionary key lock (s_cachedTypeLibDesc) { s_cachedTypeLibDesc.Add(typeLibAttr.guid, typeLibDesc); } return(typeLibDesc); }
public static Type GetTypeOrTypeInfo(this object value) { var type = value.GetType(); IDispatch dispatch = null; Type typeInfo = null; TYPEKIND typeInfoKind = 0; TYPEFLAGS typeInfoFlags = 0; if (type.IsUnknownCOMObject()) { // This appears to be a generic COM object with no specific type information. // Attempt to acquire COM type information via IDispatch or IProvideClassInfo. dispatch = value as IDispatch; if (dispatch != null) { uint count; if (RawCOMHelpers.HResult.Succeeded(dispatch.GetTypeInfoCount(out count)) && (count > 0)) { ITypeInfo tempTypeInfo; if (RawCOMHelpers.HResult.Succeeded(dispatch.GetTypeInfo(0, 0, out tempTypeInfo))) { typeInfo = GetTypeForTypeInfo(tempTypeInfo); typeInfoKind = GetTypeInfoKind(tempTypeInfo); typeInfoFlags = GetTypeInfoFlags(tempTypeInfo); } } } if (typeInfo == null) { var provideClassInfo = value as IProvideClassInfo; if (provideClassInfo != null) { ITypeInfo tempTypeInfo; if (RawCOMHelpers.HResult.Succeeded(provideClassInfo.GetClassInfo(out tempTypeInfo))) { typeInfo = GetTypeForTypeInfo(tempTypeInfo); typeInfoKind = GetTypeInfoKind(tempTypeInfo); typeInfoFlags = GetTypeInfoFlags(tempTypeInfo); } } } } if (typeInfo != null) { // If the COM type is a dispatch-only interface, use it. Such interfaces typically // aren't exposed via QueryInterface(), so there's no way to validate them anyway. if ((dispatch != null) && (typeInfoKind == TYPEKIND.TKIND_DISPATCH) && typeInfoFlags.HasFlag(TYPEFLAGS.TYPEFLAG_FDISPATCHABLE) && !typeInfoFlags.HasFlag(TYPEFLAGS.TYPEFLAG_FDUAL)) { return(typeInfo); } // COM type information acquired in this manner may not actually be valid for the // original object. In some cases the original object implements a base interface. if (typeInfo.IsInstanceOfType(value)) { return(typeInfo); } foreach (var interfaceType in typeInfo.GetInterfaces()) { if (interfaceType.IsInstanceOfType(value)) { return(interfaceType); } } } return(type); }
private DeclarationType GetDeclarationType(string memberName, FUNCDESC funcDesc, VarEnum funcValueType, TYPEKIND typekind, IMPLTYPEFLAGS parentImplTypeFlags) { DeclarationType memberType; if (funcDesc.invkind.HasFlag(INVOKEKIND.INVOKE_PROPERTYGET)) { memberType = DeclarationType.PropertyGet; } else if (funcDesc.invkind.HasFlag(INVOKEKIND.INVOKE_PROPERTYPUT)) { memberType = DeclarationType.PropertyLet; } else if (funcDesc.invkind.HasFlag(INVOKEKIND.INVOKE_PROPERTYPUTREF)) { memberType = DeclarationType.PropertySet; } else if ((parentImplTypeFlags.HasFlag(IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) || ((FUNCFLAGS)funcDesc.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FSOURCE))) { memberType = DeclarationType.Event; } else if (funcValueType == VarEnum.VT_VOID) { memberType = DeclarationType.Procedure; } else { memberType = DeclarationType.Function; } return(memberType); }
private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND typeKind, ITypeInfo info, IMPLTYPEFLAGS parentImplFlags, QualifiedModuleName typeQualifiedModuleName, Declaration moduleDeclaration, out string[] memberNames) { if (memberDescriptor.callconv != CALLCONV.CC_STDCALL) { memberNames = new string[] { }; return(null); } memberNames = new string[255]; int namesArrayLength; info.GetNames(memberDescriptor.memid, memberNames, 255, out namesArrayLength); var memberName = memberNames[0]; var funcValueType = (VarEnum)memberDescriptor.elemdescFunc.tdesc.vt; var memberDeclarationType = GetDeclarationType(memberName, memberDescriptor, funcValueType, typeKind, parentImplFlags); if (((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FRESTRICTED) && IgnoredInterfaceMembers.Contains(memberName)) // Ignore IDispatch and IUnknown members - quick-and-dirty for beta { return(null); } var asTypeName = new ComParameter(string.Empty, false); if (memberDeclarationType != DeclarationType.Procedure) { asTypeName = GetParameterInfo(memberDescriptor.elemdescFunc.tdesc, info); } var attributes = new Attributes(); if (memberName == "_NewEnum" && ((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FNONBROWSABLE)) { attributes.AddEnumeratorMemberAttribute(memberName); } else if (memberDescriptor.memid == 0) { attributes.AddDefaultMemberAttribute(memberName); } else if (((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FHIDDEN)) { attributes.AddHiddenMemberAttribute(memberName); } switch (memberDeclarationType) { case DeclarationType.Procedure: return(new SubroutineDeclaration( new QualifiedMemberName(typeQualifiedModuleName, memberName), moduleDeclaration, moduleDeclaration, asTypeName.Name, Accessibility.Global, null, Selection.Home, true, null, attributes)); case DeclarationType.Function: return(new FunctionDeclaration( new QualifiedMemberName(typeQualifiedModuleName, memberName), moduleDeclaration, moduleDeclaration, asTypeName.Name, null, null, Accessibility.Global, null, Selection.Home, asTypeName.IsArray, true, null, attributes)); case DeclarationType.PropertyGet: return(new PropertyGetDeclaration( new QualifiedMemberName(typeQualifiedModuleName, memberName), moduleDeclaration, moduleDeclaration, asTypeName.Name, null, null, Accessibility.Global, null, Selection.Home, asTypeName.IsArray, true, null, attributes)); case DeclarationType.PropertySet: return(new PropertySetDeclaration( new QualifiedMemberName(typeQualifiedModuleName, memberName), moduleDeclaration, moduleDeclaration, asTypeName.Name, Accessibility.Global, null, Selection.Home, true, null, attributes)); case DeclarationType.PropertyLet: return(new PropertyLetDeclaration( new QualifiedMemberName(typeQualifiedModuleName, memberName), moduleDeclaration, moduleDeclaration, asTypeName.Name, Accessibility.Global, null, Selection.Home, true, null, attributes)); default: return(new Declaration( new QualifiedMemberName(typeQualifiedModuleName, memberName), moduleDeclaration, moduleDeclaration, asTypeName.Name, null, false, false, Accessibility.Global, memberDeclarationType, null, Selection.Home, false, null, true, null, attributes)); } }
public static void ParseTypeLib(string filePath) { string fileNameOnly = Path.GetFileNameWithoutExtension(filePath); ITypeLib typeLib = LoadTypeLib(filePath); int count = typeLib.GetTypeInfoCount(); Console.WriteLine($"typeLib count is {count}"); IntPtr ipLibAtt = IntPtr.Zero; typeLib.GetLibAttr(out ipLibAtt); var typeLibAttr = (System.Runtime.InteropServices.ComTypes.TYPELIBATTR) Marshal.PtrToStructure(ipLibAtt, typeof(System.Runtime.InteropServices.ComTypes.TYPELIBATTR)); Guid tlbId = typeLibAttr.guid; for (int i = 0; i < count; i++) { ITypeInfo typeInfo = null; typeLib.GetTypeInfo(i, out typeInfo); //figure out what guids, typekind, and names of the thing we're dealing with IntPtr ipTypeAttr = IntPtr.Zero; typeInfo.GetTypeAttr(out ipTypeAttr); //unmarshal the pointer into a structure into something we can read var typeattr = (System.Runtime.InteropServices.ComTypes.TYPEATTR) Marshal.PtrToStructure(ipTypeAttr, typeof(System.Runtime.InteropServices.ComTypes.TYPEATTR)); System.Runtime.InteropServices.ComTypes.TYPEKIND typeKind = typeattr.typekind; Guid typeId = typeattr.guid; //get the name of the type string strName, strDocString, strHelpFile; int dwHelpContext; typeLib.GetDocumentation(i, out strName, out strDocString, out dwHelpContext, out strHelpFile); if (typeKind == System.Runtime.InteropServices.ComTypes.TYPEKIND.TKIND_COCLASS) { string xmlComClassFormat = "<comClass clsid=\"{0}\" tlbid=\"{1}\" description=\"{2}\" progid=\"{3}.{4}\"></comClass>"; string comClassXml = String.Format(xmlComClassFormat, typeId.ToString("B").ToUpper(), tlbId.ToString("B").ToUpper(), strDocString, fileNameOnly, strName ); Console.WriteLine(comClassXml); } else if (typeKind == System.Runtime.InteropServices.ComTypes.TYPEKIND.TKIND_INTERFACE) { string xmlProxyStubFormat = "<comInterfaceExternalProxyStub name=\"{0}\" iid=\"{1}\" tlbid=\"{2}\" proxyStubClsid32=\"{3}\"></comInterfaceExternalProxyStub>"; string proxyStubXml = String.Format(xmlProxyStubFormat, strName, typeId.ToString("B").ToUpper(), tlbId.ToString("B").ToUpper(), "{00020424-0000-0000-C000-000000000046}" ); Console.WriteLine(proxyStubXml); } } return; }
private DeclarationType GetDeclarationType(FUNCDESC funcDesc, VarEnum funcValueType, TYPEKIND typekind) { DeclarationType memberType; if (funcDesc.invkind.HasFlag(INVOKEKIND.INVOKE_PROPERTYGET)) { memberType = DeclarationType.PropertyGet; } else if (funcDesc.invkind.HasFlag(INVOKEKIND.INVOKE_PROPERTYPUT)) { memberType = DeclarationType.PropertyLet; } else if (funcDesc.invkind.HasFlag(INVOKEKIND.INVOKE_PROPERTYPUTREF)) { memberType = DeclarationType.PropertySet; } else if (funcValueType == VarEnum.VT_VOID) { memberType = DeclarationType.Procedure; } else if (funcDesc.funckind == FUNCKIND.FUNC_PUREVIRTUAL && typekind == TYPEKIND.TKIND_COCLASS) { memberType = DeclarationType.Event; } else { memberType = DeclarationType.Function; } return(memberType); }
private Declaration CreateMemberDeclaration(out FUNCDESC memberDescriptor, TYPEKIND typeKind, ITypeInfo info, int memberIndex, QualifiedModuleName typeQualifiedModuleName, Declaration moduleDeclaration, out string[] memberNames) { IntPtr memberDescriptorPointer; info.GetFuncDesc(memberIndex, out memberDescriptorPointer); memberDescriptor = (FUNCDESC)Marshal.PtrToStructure(memberDescriptorPointer, typeof(FUNCDESC)); if (memberDescriptor.callconv != CALLCONV.CC_STDCALL) { memberDescriptor = new FUNCDESC(); memberNames = new string[] {}; return(null); } memberNames = new string[255]; int namesArrayLength; info.GetNames(memberDescriptor.memid, memberNames, 255, out namesArrayLength); var memberName = memberNames[0]; var funcValueType = (VarEnum)memberDescriptor.elemdescFunc.tdesc.vt; var memberDeclarationType = GetDeclarationType(memberDescriptor, funcValueType, typeKind); var asTypeName = string.Empty; if (memberDeclarationType != DeclarationType.Procedure && !TypeNames.TryGetValue(funcValueType, out asTypeName)) { if (funcValueType == VarEnum.VT_PTR) { try { var asTypeDesc = (TYPEDESC)Marshal.PtrToStructure(memberDescriptor.elemdescFunc.tdesc.lpValue, typeof(TYPEDESC)); asTypeName = GetTypeName(asTypeDesc, info); } catch { asTypeName = funcValueType.ToString(); //TypeNames[VarEnum.VT_VARIANT]; } } else { asTypeName = funcValueType.ToString(); //TypeNames[VarEnum.VT_VARIANT]; } } var attributes = new Attributes(); if (memberName == "_NewEnum" && ((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FNONBROWSABLE)) { attributes.AddEnumeratorMemberAttribute(memberName); } else if (memberDescriptor.memid == 0) { attributes.AddDefaultMemberAttribute(memberName); //Debug.WriteLine("Default member found: {0}.{1} ({2} / {3})", moduleDeclaration.IdentifierName, memberName, memberDeclarationType, (VarEnum)memberDescriptor.elemdescFunc.tdesc.vt); } else if (((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FHIDDEN)) { attributes.AddHiddenMemberAttribute(memberName); } return(new Declaration(new QualifiedMemberName(typeQualifiedModuleName, memberName), moduleDeclaration, moduleDeclaration, asTypeName, false, false, Accessibility.Global, memberDeclarationType, null, Selection.Home, true, null, attributes)); }