Esempio n. 1
0
 internal ComTypeDesc(ITypeInfo typeInfo)
 {
     if (typeInfo != null)
     {
         ComRuntimeHelpers.GetInfoFromType(typeInfo, out _typeName, out _documentation);
     }
 }
Esempio n. 2
0
        private static ComTypes.ITypeInfo GetCoClassTypeInfo(object rcw, ComTypes.ITypeInfo typeInfo)
        {
            Debug.Assert(typeInfo != null);

            IProvideClassInfo provideClassInfo = rcw as IProvideClassInfo;

            if (provideClassInfo != null)
            {
                IntPtr typeInfoPtr = IntPtr.Zero;
                try {
                    provideClassInfo.GetClassInfo(out typeInfoPtr);
                    if (typeInfoPtr != IntPtr.Zero)
                    {
                        return(Marshal.GetObjectForIUnknown(typeInfoPtr) as ComTypes.ITypeInfo);
                    }
                } finally {
                    if (typeInfoPtr != IntPtr.Zero)
                    {
                        Marshal.Release(typeInfoPtr);
                    }
                }
            }

            // retrieving class information through IPCI has failed -
            // we can try scanning the typelib to find the coclass

            ComTypes.ITypeLib typeLib;
            int typeInfoIndex;

            typeInfo.GetContainingTypeLib(out typeLib, out typeInfoIndex);
            string typeName = ComRuntimeHelpers.GetNameOfType(typeInfo);

            ComTypeLibDesc   typeLibDesc = ComTypeLibDesc.GetFromTypeLib(typeLib);
            ComTypeClassDesc coclassDesc = typeLibDesc.GetCoClassForInterface(typeName);

            if (coclassDesc == null)
            {
                return(null);
            }

            ComTypes.ITypeInfo typeInfoCoClass;
            Guid coclassGuid = coclassDesc.Guid;

            typeLib.GetTypeInfoOfGuid(ref coclassGuid, out typeInfoCoClass);
            return(typeInfoCoClass);
        }
Esempio n. 3
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 (_CachedTypeLibDesc) {
                if (_CachedTypeLibDesc.TryGetValue(typeLibAttr.guid, out typeLibDesc))
                {
                    return(typeLibDesc);
                }
            }

            typeLibDesc = new ComTypeLibDesc();

            typeLibDesc._typeLibName = ComRuntimeHelpers.GetNameOfLib(typeLib);

            int countTypes = typeLib.GetTypeInfoCount();

            for (int i = 0; i < countTypes; i++)
            {
                ComTypes.TYPEKIND typeKind;
                typeLib.GetTypeInfoType(i, out typeKind);

                ComTypes.ITypeInfo typeInfo;
                if (typeKind == ComTypes.TYPEKIND.TKIND_COCLASS)
                {
                    typeLib.GetTypeInfo(i, out typeInfo);
                    ComTypeClassDesc classDesc = new ComTypeClassDesc(typeInfo);
                    typeLibDesc._classes.AddLast(classDesc);
                }
                else if (typeKind == ComTypes.TYPEKIND.TKIND_ENUM)
                {
                    typeLib.GetTypeInfo(i, out typeInfo);
                    ComTypeEnumDesc enumDesc = new ComTypeEnumDesc(typeInfo);
                    typeLibDesc._enums.Add(enumDesc.TypeName, enumDesc);
                }
            }

            // cached the typelib using the guid as the dictionary key
            lock (_CachedTypeLibDesc) {
                _CachedTypeLibDesc.Add(typeLibAttr.guid, typeLibDesc);
            }

            return(typeLibDesc);
        }
Esempio n. 4
0
        private static void ScanSourceInterface(ComTypes.ITypeInfo sourceTypeInfo, ref Dictionary <string, ComEventDesc> events)
        {
            ComTypes.TYPEATTR sourceTypeAttribute = ComRuntimeHelpers.GetTypeAttrForTypeInfo(sourceTypeInfo);

            for (int index = 0; index < sourceTypeAttribute.cFuncs; index++)
            {
                IntPtr funcDescHandleToRelease = IntPtr.Zero;

                try {
                    ComTypes.FUNCDESC funcDesc;
                    GetFuncDescForDescIndex(sourceTypeInfo, index, out funcDesc, out funcDescHandleToRelease);

                    // we are not interested in hidden or restricted functions for now.
                    if ((funcDesc.wFuncFlags & (int)ComTypes.FUNCFLAGS.FUNCFLAG_FHIDDEN) != 0)
                    {
                        continue;
                    }
                    if ((funcDesc.wFuncFlags & (int)ComTypes.FUNCFLAGS.FUNCFLAG_FRESTRICTED) != 0)
                    {
                        continue;
                    }

                    string name = ComRuntimeHelpers.GetNameOfMethod(sourceTypeInfo, funcDesc.memid);

                    // Sometimes coclass has multiple source interfaces. Usually this is caused by
                    // adding new events and putting them on new interfaces while keeping the
                    // old interfaces around. This may cause name collisioning which we are
                    // resolving by keeping only the first event with the same name.
                    if (events.ContainsKey(name) == false)
                    {
                        ComEventDesc eventDesc = new ComEventDesc();
                        eventDesc.dispid    = funcDesc.memid;
                        eventDesc.sourceIID = sourceTypeAttribute.guid;
                        events.Add(name, eventDesc);
                    }
                } finally {
                    if (funcDescHandleToRelease != IntPtr.Zero)
                    {
                        sourceTypeInfo.ReleaseFuncDesc(funcDescHandleToRelease);
                    }
                }
            }
        }
Esempio n. 5
0
        private LinkedList <string> _sourceItfs; // source interfaces supported by this coclass

        internal ComTypeClassDesc(ComTypes.ITypeInfo typeInfo) :
            base(typeInfo)
        {
            ComTypes.TYPEATTR typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo);
            Guid = typeAttr.guid;

            for (int i = 0; i < typeAttr.cImplTypes; i++)
            {
                int hRefType;
                typeInfo.GetRefTypeOfImplType(i, out hRefType);
                ComTypes.ITypeInfo currentTypeInfo;
                typeInfo.GetRefTypeInfo(hRefType, out currentTypeInfo);

                ComTypes.IMPLTYPEFLAGS implTypeFlags;
                typeInfo.GetImplTypeFlags(i, out implTypeFlags);

                bool isSourceItf = (implTypeFlags & ComTypes.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0;
                AddInterface(currentTypeInfo, isSourceItf);
            }
        }
Esempio n. 6
0
        private void AddInterface(ComTypes.ITypeInfo itfTypeInfo, bool isSourceItf)
        {
            string itfName = ComRuntimeHelpers.GetNameOfType(itfTypeInfo);

            if (isSourceItf)
            {
                if (_sourceItfs == null)
                {
                    _sourceItfs = new LinkedList <string>();
                }
                _sourceItfs.AddLast(itfName);
            }
            else
            {
                if (_itfs == null)
                {
                    _itfs = new LinkedList <string>();
                }
                _itfs.AddLast(itfName);
            }
        }
Esempio n. 7
0
 internal static ComTypeDesc FromITypeInfo(ComTypes.ITypeInfo typeInfo)
 {
     ComTypes.TYPEATTR typeAttr;
     typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo);
     if (typeAttr.typekind == ComTypes.TYPEKIND.TKIND_COCLASS)
     {
         return(new ComTypeClassDesc(typeInfo));
     }
     else if (typeAttr.typekind == ComTypes.TYPEKIND.TKIND_ENUM)
     {
         return(new ComTypeEnumDesc(typeInfo));
     }
     else if ((typeAttr.typekind == ComTypes.TYPEKIND.TKIND_DISPATCH) ||
              (typeAttr.typekind == ComTypes.TYPEKIND.TKIND_INTERFACE))
     {
         ComTypeDesc typeDesc = new ComTypeDesc(typeInfo);
         return(typeDesc);
     }
     else
     {
         throw Error.UnsupportedEnumType();
     }
 }
Esempio n. 8
0
        private void EnsureScanDefinedMethods()
        {
            if (_comTypeDesc != null && _comTypeDesc.Funcs != null)
            {
                return;
            }

            ComTypes.ITypeInfo typeInfo = ComRuntimeHelpers.GetITypeInfoFromIDispatch(_dispatchObject, true);
            if (typeInfo == null)
            {
                _comTypeDesc = ComTypeDesc.CreateEmptyTypeDesc();
                return;
            }

            ComTypes.TYPEATTR typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo);

            if (_comTypeDesc == null)
            {
                lock (_CacheComTypeDesc) {
                    if (_CacheComTypeDesc.TryGetValue(typeAttr.guid, out _comTypeDesc) == true &&
                        _comTypeDesc.Funcs != null)
                    {
                        return;
                    }
                }
            }

            ComTypeDesc typeDesc = ComTypeDesc.FromITypeInfo(typeInfo);

            ComMethodDesc getItem = null;
            ComMethodDesc setItem = null;
            Dictionary <string, ComMethodDesc> funcs   = new Dictionary <string, ComMethodDesc>(typeAttr.cFuncs);
            Dictionary <string, ComMethodDesc> puts    = new Dictionary <string, ComMethodDesc>();
            Dictionary <string, ComMethodDesc> putrefs = new Dictionary <string, ComMethodDesc>();
            Set <int> usedDispIds = new Set <int>();

            for (int definedFuncIndex = 0; definedFuncIndex < typeAttr.cFuncs; definedFuncIndex++)
            {
                IntPtr funcDescHandleToRelease = IntPtr.Zero;

                try {
                    ComTypes.FUNCDESC funcDesc;
                    GetFuncDescForDescIndex(typeInfo, definedFuncIndex, out funcDesc, out funcDescHandleToRelease);

                    if ((funcDesc.wFuncFlags & (int)ComTypes.FUNCFLAGS.FUNCFLAG_FRESTRICTED) != 0)
                    {
                        // This function is not meant for the script user to use.
                        continue;
                    }

                    ComMethodDesc method = new ComMethodDesc(typeInfo, funcDesc);

                    if ((funcDesc.invkind & ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT) != 0)
                    {
                        puts.Add(method.Name, method);
                        continue;
                    }
                    if ((funcDesc.invkind & ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF) != 0)
                    {
                        putrefs.Add(method.Name, method);
                        continue;
                    }

                    usedDispIds.Add(funcDesc.memid);

                    if (funcDesc.memid == ComDispIds.DISPID_NEWENUM)
                    {
                        funcs.Add("GetEnumerator", method);
                        continue;
                    }

                    funcs.Add(method.Name, method);

                    // for the special dispId == 0, we need to store the method descriptor
                    // for the Do(GetItem) binder.
                    if (funcDesc.memid == ComDispIds.DISPID_VALUE)
                    {
                        getItem = method;
                    }
                } finally {
                    if (funcDescHandleToRelease != IntPtr.Zero)
                    {
                        typeInfo.ReleaseFuncDesc(funcDescHandleToRelease);
                    }
                }
            }

            ProcessPut(funcs, puts, usedDispIds, ref setItem);
            ProcessPut(funcs, putrefs, usedDispIds, ref setItem);

            lock (_CacheComTypeDesc) {
                ComTypeDesc cachedTypeDesc;
                if (_CacheComTypeDesc.TryGetValue(typeAttr.guid, out cachedTypeDesc))
                {
                    _comTypeDesc = cachedTypeDesc;
                }
                else
                {
                    _comTypeDesc = typeDesc;
                    _CacheComTypeDesc.Add(typeAttr.guid, _comTypeDesc);
                }
                _comTypeDesc.Funcs   = funcs;
                _comTypeDesc.Puts    = puts;
                _comTypeDesc.PutRefs = putrefs;
                _comTypeDesc.GetItem = getItem;
                _comTypeDesc.SetItem = setItem;
            }
        }
Esempio n. 9
0
        private void EnsureScanDefinedEvents()
        {
            // _comTypeDesc.Events is null if we have not yet attempted
            // to scan the object for events.
            if (_comTypeDesc != null && _comTypeDesc.Events != null)
            {
                return;
            }

            // check type info in the type descriptions cache
            ComTypes.ITypeInfo typeInfo = ComRuntimeHelpers.GetITypeInfoFromIDispatch(_dispatchObject, true);
            if (typeInfo == null)
            {
                _comTypeDesc = ComTypeDesc.CreateEmptyTypeDesc();
                return;
            }

            ComTypes.TYPEATTR typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo);

            if (_comTypeDesc == null)
            {
                lock (_CacheComTypeDesc) {
                    if (_CacheComTypeDesc.TryGetValue(typeAttr.guid, out _comTypeDesc) == true &&
                        _comTypeDesc.Events != null)
                    {
                        return;
                    }
                }
            }

            ComTypeDesc typeDesc = ComTypeDesc.FromITypeInfo(typeInfo);

            ComTypes.ITypeInfo classTypeInfo         = null;
            Dictionary <string, ComEventDesc> events = null;

            var cpc = RuntimeCallableWrapper as ComTypes.IConnectionPointContainer;

            if (cpc == null)
            {
                // No ICPC - this object does not support events
                events = ComTypeDesc.EmptyEvents;
            }
            else if ((classTypeInfo = GetCoClassTypeInfo(this.RuntimeCallableWrapper, typeInfo)) == null)
            {
                // no class info found - this object may support events
                // but we could not discover those
                Debug.Assert(false, "object support IConnectionPoint but no class info found");
                events = ComTypeDesc.EmptyEvents;
            }
            else
            {
                events = new Dictionary <string, ComEventDesc>();

                ComTypes.TYPEATTR classTypeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(classTypeInfo);
                for (int i = 0; i < classTypeAttr.cImplTypes; i++)
                {
                    int hRefType;
                    classTypeInfo.GetRefTypeOfImplType(i, out hRefType);

                    ComTypes.ITypeInfo interfaceTypeInfo;
                    classTypeInfo.GetRefTypeInfo(hRefType, out interfaceTypeInfo);

                    ComTypes.IMPLTYPEFLAGS flags;
                    classTypeInfo.GetImplTypeFlags(i, out flags);
                    if ((flags & ComTypes.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0)
                    {
                        ScanSourceInterface(interfaceTypeInfo, ref events);
                    }
                }

                if (events.Count == 0)
                {
                    events = ComTypeDesc.EmptyEvents;
                }
            }

            lock (_CacheComTypeDesc) {
                ComTypeDesc cachedTypeDesc;
                if (_CacheComTypeDesc.TryGetValue(typeAttr.guid, out cachedTypeDesc))
                {
                    _comTypeDesc = cachedTypeDesc;
                }
                else
                {
                    _comTypeDesc = typeDesc;
                    _CacheComTypeDesc.Add(typeAttr.guid, _comTypeDesc);
                }
                _comTypeDesc.Events = events;
            }
        }