Example #1
0
        internal static COM.FUNCDESC GetFuncDesc(COM.ITypeInfo typeinfo, int index)
        {
            IntPtr pFuncDesc;

            typeinfo.GetFuncDesc(index, out pFuncDesc);
            COM.FUNCDESC funcdesc = Marshal.PtrToStructure <COM.FUNCDESC>(pFuncDesc);
            typeinfo.ReleaseFuncDesc(pFuncDesc);
            return(funcdesc);
        }
Example #2
0
        private static IEnumerable <ComTypes.FUNCDESC> GetFuncDescs(ComTypes.ITypeInfo typeInfo, ComTypes.TYPEATTR typeAttr)
        {
            for (var iFunc = 0; iFunc < typeAttr.cFuncs; iFunc++)
            {
                IntPtr pFuncDesc;
                typeInfo.GetFuncDesc(iFunc, out pFuncDesc);
                var funcDesc = (ComTypes.FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(ComTypes.FUNCDESC));
                yield return(funcDesc);

                typeInfo.ReleaseFuncDesc(pFuncDesc);
            }
        }
Example #3
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);
                    name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);

                    // 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 collisions 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);
                    }
                }
            }
        }
Example #4
0
        /// <summary>
        /// Converts a MethodBase[] into a MethodInformation[]
        /// </summary>
        /// <returns>the ComMethodInformation[] corresponding to methods</returns>
        internal static ComMethodInformation[] GetMethodInformationArray(COM.ITypeInfo typeInfo, Collection <int> methods, bool skipLastParameters)
        {
            int methodCount = methods.Count;
            int count       = 0;

            ComMethodInformation[] returnValue = new ComMethodInformation[methodCount];

            foreach (int index in methods)
            {
                IntPtr pFuncDesc;
                typeInfo.GetFuncDesc(index, out pFuncDesc);
                COM.FUNCDESC funcdesc = ClrFacade.PtrToStructure <COM.FUNCDESC>(pFuncDesc);
                returnValue[count++] = ComUtil.GetMethodInformation(funcdesc, skipLastParameters);
                typeInfo.ReleaseFuncDesc(pFuncDesc);
            }
            return(returnValue);
        }
Example #5
0
        internal string GetDefinition()
        {
            IntPtr pFuncDesc = IntPtr.Zero;

            try
            {
                _typeInfo.GetFuncDesc(GetFuncDescIndex(), out pFuncDesc);
                COM.FUNCDESC funcdesc = Marshal.PtrToStructure <COM.FUNCDESC>(pFuncDesc);

                return(ComUtil.GetMethodSignatureFromFuncDesc(_typeInfo, funcdesc, !IsGettable));
            }
            finally
            {
                if (pFuncDesc != IntPtr.Zero)
                {
                    _typeInfo.ReleaseFuncDesc(pFuncDesc);
                }
            }
        }
Example #6
0
        /// <summary>
        /// Returns the different method overloads signatures.
        /// </summary>
        /// <returns></returns>
        internal Collection <string> MethodDefinitions()
        {
            Collection <string> result = new Collection <string>();

            foreach (int index in _methods)
            {
                IntPtr pFuncDesc;

                _typeInfo.GetFuncDesc(index, out pFuncDesc);
                COM.FUNCDESC funcdesc = Marshal.PtrToStructure <COM.FUNCDESC>(pFuncDesc);

                string signature = ComUtil.GetMethodSignatureFromFuncDesc(_typeInfo, funcdesc, false);
                result.Add(signature);

                _typeInfo.ReleaseFuncDesc(pFuncDesc);
            }

            return(result);
        }
Example #7
0
        private void EnsureScanDefinedMethods()
        {
            if (_comTypeDesc != null && _comTypeDesc.Funcs != null)
            {
                return;
            }

            //
            // Demand Full Trust to proceed with the operation.
            //

            new PermissionSet(PermissionState.Unrestricted).Demand();

            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, typeAttr);

            ComMethodDesc getItem = null;
            ComMethodDesc setItem = null;
            Hashtable     funcs   = new Hashtable(typeAttr.cFuncs);
            Hashtable     puts    = new Hashtable();
            Hashtable     putrefs = new Hashtable();

            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);
                    string        name   = method.Name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);

                    if ((funcDesc.invkind & ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT) != 0)
                    {
                        puts.Add(name, method);

                        // for the special dispId == 0, we need to store
                        // the method descriptor for the Do(SetItem) binder.
                        if (method.DispId == ComDispIds.DISPID_VALUE && setItem == null)
                        {
                            setItem = method;
                        }
                        continue;
                    }
                    if ((funcDesc.invkind & ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF) != 0)
                    {
                        putrefs.Add(name, method);
                        // for the special dispId == 0, we need to store
                        // the method descriptor for the Do(SetItem) binder.
                        if (method.DispId == ComDispIds.DISPID_VALUE && setItem == null)
                        {
                            setItem = method;
                        }
                        continue;
                    }

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

                    funcs.Add(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);
                    }
                }
            }

            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.EnsureGetItem(getItem);
                _comTypeDesc.EnsureSetItem(setItem);
            }
        }
Example #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 (s_cacheComTypeDesc)
                {
                    if (s_cacheComTypeDesc.TryGetValue(typeAttr.guid, out _comTypeDesc) == true &&
                        _comTypeDesc.Funcs != null)
                    {
                        return;
                    }
                }
            }

            if (typeAttr.typekind == ComTypes.TYPEKIND.TKIND_INTERFACE)
            {
                // We have typeinfo for custom interface. Get typeinfo for Dispatch interface.
                typeInfo = ComTypeInfo.GetDispatchTypeInfoFromCustomInterfaceTypeInfo(typeInfo);
                typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo);
            }

            if (typeAttr.typekind == ComTypes.TYPEKIND.TKIND_COCLASS)
            {
                // We have typeinfo for the COClass.  Find the default interface and get typeinfo for default interface.
                typeInfo = ComTypeInfo.GetDispatchTypeInfoFromCoClassTypeInfo(typeInfo);
                typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo);
            }

            ComTypeDesc typeDesc = ComTypeDesc.FromITypeInfo(typeInfo, typeAttr);

            ComMethodDesc getItem = null;
            ComMethodDesc setItem = null;
            Hashtable     funcs   = new Hashtable(typeAttr.cFuncs);
            Hashtable     puts    = new Hashtable();
            Hashtable     putrefs = new Hashtable();

            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);
                    string        name   = method.Name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);

                    if ((funcDesc.invkind & ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT) != 0)
                    {
                        // If there is a getter for this put, use that ReturnType as the
                        // PropertyType.
                        if (funcs.ContainsKey(name))
                        {
                            method.InputType = ((ComMethodDesc)funcs[name]).ReturnType;
                        }

                        puts.Add(name, method);

                        // for the special dispId == 0, we need to store
                        // the method descriptor for the Do(SetItem) binder.
                        if (method.DispId == ComDispIds.DISPID_VALUE && setItem == null)
                        {
                            setItem = method;
                        }

                        continue;
                    }

                    if ((funcDesc.invkind & ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF) != 0)
                    {
                        // If there is a getter for this put, use that ReturnType as the
                        // PropertyType.
                        if (funcs.ContainsKey(name))
                        {
                            method.InputType = ((ComMethodDesc)funcs[name]).ReturnType;
                        }

                        putrefs.Add(name, method);
                        // for the special dispId == 0, we need to store
                        // the method descriptor for the Do(SetItem) binder.
                        if (method.DispId == ComDispIds.DISPID_VALUE && setItem == null)
                        {
                            setItem = method;
                        }

                        continue;
                    }

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

                    // If there is a setter for this put, update the InputType from our
                    // ReturnType.
                    if (puts.ContainsKey(name))
                    {
                        ((ComMethodDesc)puts[name]).InputType = method.ReturnType;
                    }

                    if (putrefs.ContainsKey(name))
                    {
                        ((ComMethodDesc)putrefs[name]).InputType = method.ReturnType;
                    }

                    funcs.Add(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);
                    }
                }
            }

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

                _comTypeDesc.Funcs   = funcs;
                _comTypeDesc.Puts    = puts;
                _comTypeDesc.PutRefs = putrefs;
                _comTypeDesc.EnsureGetItem(getItem);
                _comTypeDesc.EnsureSetItem(setItem);
            }
        }
Example #9
0
        /// <summary>
        /// Creates an entity support list for a proxy
        /// </summary>
        /// <param name="factory">core to perform searching</param>
        /// <param name="comProxy">proxy to analyze</param>
        /// <returns>supported methods and properties as name/kind dictionary</returns>
        /// <exception cref="COMException">Throws generaly if any exception occurs. See inner exception(s) for details</exception>
        internal Dictionary <string, string> GetSupportedEntities(Core factory, object comProxy)
        {
            try
            {
                Guid parentLibraryGuid = CoreFactoryExtensions.GetParentLibraryGuid(factory, comProxy);
                if (Guid.Empty == parentLibraryGuid)
                {
                    return(null);
                }

                string className = TypeDescriptor.GetClassName(comProxy);
                string key       = (parentLibraryGuid.ToString() + className).ToLower();

                Dictionary <string, string> supportList = null;
                if (factory.EntitiesListCache.TryGetValue(key, out supportList))
                {
                    return(supportList);
                }

                supportList = new Dictionary <string, string>();
                IDispatch dispatch = comProxy as IDispatch;
                if (null == dispatch)
                {
                    throw new COMException("Unable to cast underlying proxy to IDispatch.");
                }

                COMTypes.ITypeInfo typeInfo = dispatch.GetTypeInfo(0, 0);
                if (null == typeInfo)
                {
                    throw new COMException("GetTypeInfo returns null.");
                }

                IntPtr typeAttrPointer = IntPtr.Zero;
                typeInfo.GetTypeAttr(out typeAttrPointer);

                COMTypes.TYPEATTR typeAttr = (COMTypes.TYPEATTR)Marshal.PtrToStructure(typeAttrPointer, typeof(COMTypes.TYPEATTR));
                for (int i = 0; i < typeAttr.cFuncs; i++)
                {
                    string            strName, strDocString, strHelpFile;
                    int               dwHelpContext;
                    IntPtr            funcDescPointer = IntPtr.Zero;
                    COMTypes.FUNCDESC funcDesc;
                    typeInfo.GetFuncDesc(i, out funcDescPointer);
                    funcDesc = (COMTypes.FUNCDESC)Marshal.PtrToStructure(funcDescPointer, typeof(COMTypes.FUNCDESC));

                    switch (funcDesc.invkind)
                    {
                    case COMTypes.INVOKEKIND.INVOKE_PROPERTYGET:
                    case COMTypes.INVOKEKIND.INVOKE_PROPERTYPUT:
                    case COMTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF:
                    {
                        typeInfo.GetDocumentation(funcDesc.memid, out strName, out strDocString, out dwHelpContext, out strHelpFile);
                        string outValue = "";
                        bool   exists   = supportList.TryGetValue("Property-" + strName, out outValue);
                        if (!exists)
                        {
                            supportList.Add("Property-" + strName, strDocString);
                        }
                        break;
                    }

                    case COMTypes.INVOKEKIND.INVOKE_FUNC:
                    {
                        typeInfo.GetDocumentation(funcDesc.memid, out strName, out strDocString, out dwHelpContext, out strHelpFile);
                        string outValue = "";
                        bool   exists   = supportList.TryGetValue("Method-" + strName, out outValue);
                        if (!exists)
                        {
                            supportList.Add("Method-" + strName, strDocString);
                        }
                        break;
                    }
                    }

                    typeInfo.ReleaseFuncDesc(funcDescPointer);
                }

                typeInfo.ReleaseTypeAttr(typeAttrPointer);
                Marshal.ReleaseComObject(typeInfo);

                factory.EntitiesListCache.Add(key, supportList);

                return(supportList);
            }
            catch (Exception exception)
            {
                throw new COMException("An unexpected error occurs.", exception);
            }
        }
Example #10
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;
            }
        }