Ejemplo n.º 1
0
        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;
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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));
            }
        }
Ejemplo n.º 6
0
        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;
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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));
        }