Exemple #1
0
        public void CreateWrapperOfType_GenericHasNoWrapperWithInterfaces_ReturnsExpected()
        {
            var    comObject = new ComImportObject();
            object wrapper   = Marshal.CreateWrapperOfType <ComImportObject, HasNonCOMInterfaces>(comObject);

            Assert.Same(wrapper, Marshal.GetComObjectData(comObject, typeof(HasNonCOMInterfaces)));
        }
        public static ComEventSinksContainer FromRuntimeCallableWrapper(object rcw, bool createIfNotFound)
        {
            // !!! Marshal.Get/SetComObjectData has a LinkDemand for UnmanagedCode which will turn into
            // a full demand. We need to avoid this by making this method SecurityCritical
            object data = Marshal.GetComObjectData(rcw, _ComObjectEventSinksKey);

            if (data != null || createIfNotFound == false)
            {
                return((ComEventSinksContainer)data);
            }

            lock (_ComObjectEventSinksKey) {
                data = Marshal.GetComObjectData(rcw, _ComObjectEventSinksKey);
                if (data != null)
                {
                    return((ComEventSinksContainer)data);
                }

                ComEventSinksContainer comEventSinks = new ComEventSinksContainer();
                if (!Marshal.SetComObjectData(rcw, _ComObjectEventSinksKey, comEventSinks))
                {
                    throw Error.SetComObjectDataFailed();
                }

                return(comEventSinks);
            }
        }
Exemple #3
0
        /// <summary>
        /// Gets a <see cref="ComObject"/> that wraps the runtime-callable-wrapper, or creates one if none currently exists.
        /// </summary>
        /// <returns></returns>
        public static ComObject ObjectToComObject(object rcw)
        {
            Debug.Assert(ComBinder.IsComObject(rcw));

            object data = Marshal.GetComObjectData(rcw, s_comObjectInfoKey);

            if (data != null)
            {
                return((ComObject)data);
            }

            lock (s_comObjectInfoKey)
            {
                data = Marshal.GetComObjectData(rcw, s_comObjectInfoKey);
                if (data != null)
                {
                    return((ComObject)data);
                }

                ComObject comObjectInfo = CreateComObject(rcw);
                if (!Marshal.SetComObjectData(rcw, s_comObjectInfoKey, comObjectInfo))
                {
                    throw Error.SetComObjectDataFailed();
                }

                return(comObjectInfo);
            }
        }
Exemple #4
0
        public void CreateWrapperOfType_NonGenericHasNoWrapper_ReturnsExpected()
        {
            var    comObject = new ComImportObject();
            object wrapper   = Marshal.CreateWrapperOfType(comObject, typeof(WrapperComImportObject));

            Assert.Same(wrapper, Marshal.GetComObjectData(comObject, typeof(WrapperComImportObject)));
        }
Exemple #5
0
        public static ComEventSinksContainer FromRuntimeCallableWrapper(object rcw, bool createIfNotFound)
        {
            object data = Marshal.GetComObjectData(rcw, s_comObjectEventSinksKey);

            if (data != null || !createIfNotFound)
            {
                return((ComEventSinksContainer)data);
            }

            lock (s_comObjectEventSinksKey)
            {
                data = Marshal.GetComObjectData(rcw, s_comObjectEventSinksKey);
                if (data != null)
                {
                    return((ComEventSinksContainer)data);
                }

                ComEventSinksContainer comEventSinks = new ComEventSinksContainer();
                if (!Marshal.SetComObjectData(rcw, s_comObjectEventSinksKey, comEventSinks))
                {
                    throw Error.SetComObjectDataFailed();
                }

                return(comEventSinks);
            }
        }
Exemple #6
0
        public static ComObject ObjectToComObject(object rcw)
        {
            Debug.Assert(ComObject.IsComObject(rcw));

            // Marshal.Get/SetComObjectData has a LinkDemand for UnmanagedCode which will turn into
            // a full demand. We could avoid this by making this method SecurityCritical
            object data = Marshal.GetComObjectData(rcw, _ComObjectInfoKey);

            if (data != null)
            {
                return((ComObject)data);
            }

            lock (_ComObjectInfoKey) {
                data = Marshal.GetComObjectData(rcw, _ComObjectInfoKey);
                if (data != null)
                {
                    return((ComObject)data);
                }

                ComObject comObjectInfo = CreateComObject(rcw);
                if (!Marshal.SetComObjectData(rcw, _ComObjectInfoKey, comObjectInfo))
                {
                    throw Error.SetComObjectDataFailed();
                }

                return(comObjectInfo);
            }
        }
Exemple #7
0
 /// <summary>
 /// Gets the name of the default COM interface for this object.
 /// </summary>
 /// <remarks>
 /// Uses the COM ITypeInfo interface to get the information. Does not throw.
 /// </remarks>
 /// <param name="obj"></param>
 /// <returns>The name of the interface; null on any exception</returns>
 ///
 internal static string GetDefaultCOMInterfaceName(object obj)
 {
     try {
         string intfName = (string)Marshal.GetComObjectData(obj, "NETLinkCOMInterface");
         if (intfName == null)
         {
             UCOMIDispatch iDisp = GetIDispatch(obj);
             UCOMITypeInfo iTypeInfo = GetITypeInfo(obj, iDisp);
             string        typeLibName, docStr, helpFile;
             int           helpContext;
             iTypeInfo.GetDocumentation(-1, out intfName, out docStr, out helpContext, out helpFile);
             UCOMITypeLib iTypeLib;
             int          index;
             iTypeInfo.GetContainingTypeLib(out iTypeLib, out index);
             iTypeLib.GetDocumentation(-1, out typeLibName, out docStr, out helpContext, out helpFile);
             intfName = typeLibName + "." + intfName;
             Marshal.SetComObjectData(obj, "NETLinkCOMInterface", intfName);
             // Not strictly necessary to release here, but better to force it now than rely on GC to do it later.
             // Cannot release iDisp or iTypeInfo, as they might be cached in the object.
             Marshal.ReleaseComObject(iTypeLib);
         }
         return(intfName);
     } catch (Exception) {
         return(null);
     }
 }
        public void GetComObjectData_ValidObject_ReturnsExpected()
        {
            var comObject = new ComImportObject();

            Assert.Null(Marshal.GetComObjectData(comObject, "key"));

            Marshal.SetComObjectData(comObject, "key", 1);
            Assert.Equal(1, Marshal.GetComObjectData(comObject, "key"));
            Assert.Null(Marshal.GetComObjectData(comObject, "noSuchKey"));
        }
Exemple #9
0
        // Allows exceptions to be thrown.
        private static UCOMITypeInfo GetITypeInfo(object obj, UCOMIDispatch iDisp)
        {
            UCOMITypeInfo iTypeInfo = (UCOMITypeInfo)Marshal.GetComObjectData(obj, "NETLinkITypeInfo");

            if (iTypeInfo == null)
            {
                iDisp.GetTypeInfo(0, GetUserDefaultLCID(), out iTypeInfo);
                Marshal.SetComObjectData(obj, "NETLinkITypeInfo", iTypeInfo);
            }
            return(iTypeInfo);
        }
Exemple #10
0
        public void GetComObjectData_NetFramework_ReturnsExpected()
        {
            Type   type      = Type.GetTypeFromCLSID(new Guid("927971f5-0939-11d1-8be1-00c04fd8d503"));
            object comObject = Activator.CreateInstance(type);

            Assert.Null(Marshal.GetComObjectData(comObject, "key"));

            Marshal.SetComObjectData(comObject, "key", 1);
            Assert.Equal(1, Marshal.GetComObjectData(comObject, "key"));
            Assert.Null(Marshal.GetComObjectData(comObject, "noSuchKey"));
        }
Exemple #11
0
        public void SetComObjectData_NonNullValue_Sucesss()
        {
            var comObject = new ComImportObject();

            Assert.True(Marshal.SetComObjectData(comObject, "key", 1));
            Assert.Equal(1, Marshal.GetComObjectData(comObject, "key"));

            Assert.False(Marshal.SetComObjectData(comObject, "key", 2));
            Assert.Equal(1, Marshal.GetComObjectData(comObject, "key"));

            Assert.True(Marshal.SetComObjectData(comObject, "otherKey", 2));
            Assert.Equal(2, Marshal.GetComObjectData(comObject, "otherKey"));
        }
Exemple #12
0
        public static TView GetOrCreateManagedViewFromComData <T, TView>(object comObject, Func <T, TView> createCallback)
        {
            object key = typeof(TView);

            if (Marshal.GetComObjectData(comObject, key) is TView managedView)
            {
                return(managedView);
            }

            managedView = createCallback((T)comObject);
            if (!Marshal.SetComObjectData(comObject, key, managedView))
            {
                managedView = (TView)Marshal.GetComObjectData(comObject, key);
            }
            return(managedView);
        }
Exemple #13
0
        /// <summary>
        /// Like Marshal.ReleaseCOMObject, but also frees IDispatch and ITypeInfo objects held in the object's cache.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns>The new COM refcount.</returns>
        ///
        internal static int releaseCOMObject(object obj)
        {
            int newRefCount = Marshal.ReleaseComObject(obj);

            if (newRefCount == 0)
            {
                UCOMITypeInfo iTypeInfo = (UCOMITypeInfo)Marshal.GetComObjectData(obj, "NETLinkITypeInfo");
                if (iTypeInfo != null)
                {
                    Marshal.ReleaseComObject(iTypeInfo);
                }
                UCOMIDispatch iDisp = (UCOMIDispatch)Marshal.GetComObjectData(obj, "NETLinkIDispatch");
                if (iDisp != null)
                {
                    Marshal.ReleaseComObject(iDisp);
                }
            }
            return(newRefCount);
        }
Exemple #14
0
        // Returns -1 on failure. Does not throw.
        private static int GetMemberDispID(object obj, UCOMIDispatch iDisp, ref string memberName)
        {
            object val = Marshal.GetComObjectData(obj, "NETLinkDispID" + memberName);

            if (val != null)
            {
                // We also need to extract the modified (U --> _ converted) name.
                memberName = (string)Marshal.GetComObjectData(obj, "NETLinkModifiedName" + memberName);
                return((int)val);
            }
            else
            {
                int      memberDispId;
                int      defaultLCID     = GetUserDefaultLCID();
                string[] substrs         = memberName.Split('U');
                int      numCombinations = (int)Math.Pow(2, substrs.Length - 1);
                for (int i = 0; i < numCombinations; i++)
                {
                    string modifiedName = substrs[0];
                    // Use bit ops to take i and pick 0 -> U, 1 -> _ for replacement.
                    for (int j = 1; j < substrs.Length; j++)
                    {
                        modifiedName += ((((i >> (j - 1)) & 1) == 0) ? "U" : "_") + substrs[j];
                    }
                    try {
                        iDisp.GetIDsOfNames(ref IID_NULL, new string[] { modifiedName }, 1, defaultLCID, out memberDispId);
                    } catch (Exception) {
                        // Try next combination.
                        continue;
                    }
                    // If we get here, name was found, and is held in the variable modifiedName. Cache the correct dispID
                    // for the unaltered name as it arrives from M, cache the modified name, and then set the ref
                    // parameter memberName to correct name.
                    Marshal.SetComObjectData(obj, "NETLinkDispID" + memberName, memberDispId);
                    Marshal.SetComObjectData(obj, "NETLinkModifiedName" + memberName, modifiedName);
                    memberName = modifiedName;
                    return(memberDispId);
                }
                // Name not found by GetIDsOfNames().
                return(-1);
            }
        }
Exemple #15
0
        private HandlerList GetComHandlerList(object instance)
        {
            HandlerList hl = (HandlerList)Marshal.GetComObjectData(instance, this);

            if (hl == null)
            {
                lock (_staticTarget) {
                    hl = (HandlerList)Marshal.GetComObjectData(instance, this);
                    if (hl == null)
                    {
                        hl = new ComHandlerList();
                        if (!Marshal.SetComObjectData(instance, this, hl))
                        {
                            throw new COMException("Failed to set COM Object Data");
                        }
                    }
                }
            }

            return(hl);
        }
Exemple #16
0
        /// <summary>
        /// Gets parameter information for the given member.
        /// </summary>
        /// <remarks>
        /// Uses the COM ITypeInfo interface to get the information. Does not throw. If it returns false then the out params
        /// will not hold useful information.
        /// </remarks>
        /// <param name="obj"></param>
        /// <param name="memberName"></param>
        /// <param name="callType"></param>
        /// <param name="isBeingCalledWithZeroArgs"></param>
        /// <param name="paramTypes"></param>
        /// <param name="paramFlags"></param>
        /// <param name="endsWithParamArray"></param>
        /// <returns>true if the name refers to a valid member or if no type information is available</returns>
        ///
        internal static bool GetMemberInfo(object obj, ref string memberName, int callType, bool isBeingCalledWithZeroArgs,
                                           out Type[] paramTypes, out PARAMFLAG[] paramFlags, out bool endsWithParamArray)
        {
            // There are some early returns in this method, so we initialize the out params right away. To the caller, if these values
            // come back null it means that the information could not be determined.
            paramTypes         = null;
            paramFlags         = null;
            endsWithParamArray = false;

            int defaultLCID = GetUserDefaultLCID();

            try {
                // Throws in this outer try cause true to be returned. They mean "type info could not be obtained, so the member is not
                // known to be invalid."

                UCOMIDispatch iDisp        = GetIDispatch(obj);
                int           memberDispId = GetMemberDispID(obj, iDisp, ref memberName);
                if (memberDispId == -1)
                {
                    // Name not found by GetIDsOfNames.
                    return(false);
                }

                // If no args are being passed, then we can skip all the machinations below about type info.
                if (isBeingCalledWithZeroArgs)
                {
                    return(true);
                }

                UCOMITypeInfo iTypeInfo = GetITypeInfo(obj, iDisp);
                IntPtr        pFuncDesc;

                // Check to see if the func index for this member name is already cached from a previous call.
                FuncIndexHolder fih = (FuncIndexHolder)Marshal.GetComObjectData(obj, "NETLinkFuncIndex" + memberName);
                if (fih == null)
                {
                    // This will be populated below.
                    fih = new FuncIndexHolder();
                    Marshal.SetComObjectData(obj, "NETLinkFuncIndex" + memberName, fih);
                }
                int funcIndex = -1;
                if (callType == Install.CALLTYPE_FIELD_OR_SIMPLE_PROP_GET)
                {
                    if (fih.funcIndexForCALLTYPE_FIELD_OR_SIMPLE_PROP_GET != -1)
                    {
                        funcIndex = fih.funcIndexForCALLTYPE_FIELD_OR_SIMPLE_PROP_GET;
                    }
                }
                else if (callType == Install.CALLTYPE_FIELD_OR_SIMPLE_PROP_SET || callType == Install.CALLTYPE_PARAM_PROP_SET)
                {
                    if (fih.funcIndexForCALLTYPE_FIELD_OR_ANY_PROP_SET != -1)
                    {
                        funcIndex = fih.funcIndexForCALLTYPE_FIELD_OR_ANY_PROP_SET;
                    }
                }
                else if (callType == Install.CALLTYPE_METHOD || callType == Install.CALLTYPE_PARAM_PROP_GET)
                {
                    // COM objects are treated by M code as if they all have indexers, so calls like obj[1] will
                    // come in as CALLTYPE_PARAM_PROP_GET with a property name of Item. We can just treat these like
                    // method calls.
                    if (fih.funcIndexForCALLTYPE_METHOD != -1)
                    {
                        funcIndex = fih.funcIndexForCALLTYPE_METHOD;
                    }
                }

                // Did not have the func index for this call type cached.
                if (funcIndex == -1)
                {
                    IntPtr pTypeAttr;
                    iTypeInfo.GetTypeAttr(out pTypeAttr);
                    TYPEATTR typeAttr = (TYPEATTR)Marshal.PtrToStructure(pTypeAttr, typeof(TYPEATTR));
                    int      numFuncs = typeAttr.cFuncs;
                    iTypeInfo.ReleaseTypeAttr(pTypeAttr);
                    bool foundDispId = false;
                    for (int thisIndex = 0; thisIndex < numFuncs; thisIndex++)
                    {
                        // Be aware that GetFuncDesc() can (I think) throw a cryptic "Element not found" exception,
                        // such as for a hidden property like (Excel) _Application.ActiveDialog.
                        iTypeInfo.GetFuncDesc(thisIndex, out pFuncDesc);
                        FUNCDESC   funcDesc     = (FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(FUNCDESC));
                        int        thisMemberId = funcDesc.memid;
                        INVOKEKIND invokeKind   = funcDesc.invkind;
                        iTypeInfo.ReleaseFuncDesc(pFuncDesc);
                        if (thisMemberId == memberDispId)
                        {
                            foundDispId = true;
                            // Verify that it is a member of the correct call type.
                            if (callType == Install.CALLTYPE_FIELD_OR_SIMPLE_PROP_GET && invokeKind == INVOKEKIND.INVOKE_PROPERTYGET)
                            {
                                fih.funcIndexForCALLTYPE_FIELD_OR_SIMPLE_PROP_GET = thisIndex;
                                funcIndex = thisIndex;
                                break;
                            }
                            else if ((callType == Install.CALLTYPE_FIELD_OR_SIMPLE_PROP_SET || callType == Install.CALLTYPE_PARAM_PROP_SET) &&
                                     (invokeKind == INVOKEKIND.INVOKE_PROPERTYPUT || invokeKind == INVOKEKIND.INVOKE_PROPERTYPUTREF))
                            {
                                fih.funcIndexForCALLTYPE_FIELD_OR_ANY_PROP_SET = thisIndex;
                                funcIndex = thisIndex;
                                break;
                            }
                            else if ((callType == Install.CALLTYPE_METHOD && (invokeKind == INVOKEKIND.INVOKE_FUNC || invokeKind == INVOKEKIND.INVOKE_PROPERTYGET)) ||
                                     (callType == Install.CALLTYPE_PARAM_PROP_GET && invokeKind == INVOKEKIND.INVOKE_PROPERTYGET))
                            {
                                // Parameterized prop gets, not sets, look like CALLTYPE_METHOD. Also, as discussed in an earlier comment,
                                // indexer notation calls (obj[1]) are supported for all COM objects and come in as CALLTYPE_PARAM_PROP_GET.
                                fih.funcIndexForCALLTYPE_METHOD = thisIndex;
                                funcIndex = thisIndex;
                                break;
                            }
                        }
                    }
                    if (funcIndex == -1)
                    {
                        // We didn't find the member in our search. This can happen in two ways. First, the member might
                        // exist but not be the right call type. For this case we want to return false. Second, we didn't
                        // even find the dispid. This can happen in unusual cases I don't understan An example of this
                        // is the IWebBrowser2 interface obtained by CreateCOMObject["InternetExplorer.Application"].
                        // For this case we want to return true, as if there was no type info at all available, so the
                        // call can still proceed.
                        return(!foundDispId);
                    }
                }

                // If we get to here, we have a valid funcIndex and memberDispId, and the member is of the correct variety
                // that corresponds to how it was called (e.g., it's a method and it was called as such). All that
                // remains is to get the parameter types.

                iTypeInfo.GetFuncDesc(funcIndex, out pFuncDesc);
                try {
                    FUNCDESC funcDesc = (FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(FUNCDESC));
                    Debug.Assert(funcDesc.memid == memberDispId);
                    int paramCount = funcDesc.cParams;
                    // Functions that end with a VB-style ParamArray (a variable-length argument sequence) have -1 for the
                    // cParamsOpt member. It is convenient to treat them specially, hence the 'endsWithParamArray' variable
                    // (which is an out param for this method). The special treatment involves leaving the ParamArray arg off
                    // the list of paramFlags and paramTypes. We just pretend there is one less arg to the function but
                    // record that it ends with a ParamArray. We always know the type of this arg anyway: ByRef Variant[].
                    // To the caller, though, the individual args are sent as a sequence, not packed into an array.
                    endsWithParamArray = funcDesc.cParamsOpt == -1;
                    if (endsWithParamArray)
                    {
                        paramCount--;
                    }
                    paramTypes = new Type[paramCount];
                    paramFlags = new PARAMFLAG[paramCount];
                    IntPtr pElemDescArray = funcDesc.lprgelemdescParam;
                    for (int paramIndex = 0; paramIndex < paramCount; paramIndex++)
                    {
                        ELEMDESC elemDesc = (ELEMDESC)Marshal.PtrToStructure((IntPtr)(pElemDescArray.ToInt64() +
                                                                                      paramIndex * Marshal.SizeOf(typeof(ELEMDESC))), typeof(ELEMDESC));
                        TYPEDESC typeDesc = elemDesc.tdesc;
                        paramFlags[paramIndex] = elemDesc.desc.paramdesc.wParamFlags;
                        // I think I should never see a retval param here. They have been automatically converted to return types.
                        Debug.Assert((paramFlags[paramIndex] & PARAMFLAG.PARAMFLAG_FRETVAL) == 0);
                        VarEnum variantType = (VarEnum)typeDesc.vt;
                        bool    isArray     = variantType == VarEnum.VT_SAFEARRAY;
                        bool    isPtr       = variantType == VarEnum.VT_PTR;
                        bool    isOut       = (paramFlags[paramIndex] & PARAMFLAG.PARAMFLAG_FOUT) != 0;
                        // VB array params will have isPtr and !isArray, because they are always ByRef (thus ptrs).
                        // In general (always?), out params will be VT_PTR.
                        if (isArray || isPtr)
                        {
                            IntPtr   pElementTypeDesc = typeDesc.lpValue;
                            TYPEDESC elementTypeDesc  = (TYPEDESC)Marshal.PtrToStructure(pElementTypeDesc, typeof(TYPEDESC));
                            variantType = (VarEnum)elementTypeDesc.vt;
                            // If the arg was a ptr to an array (e.g., as in VB objects), do it again to get the element type.
                            if (variantType == VarEnum.VT_SAFEARRAY)
                            {
                                isArray          = true;
                                pElementTypeDesc = elementTypeDesc.lpValue;
                                elementTypeDesc  = (TYPEDESC)Marshal.PtrToStructure(pElementTypeDesc, typeof(TYPEDESC));
                                variantType      = (VarEnum)elementTypeDesc.vt;
                            }
                        }
                        paramTypes[paramIndex] = managedTypeForVariantType(variantType, isArray, isPtr, isOut);
                    }
                } finally {
                    iTypeInfo.ReleaseFuncDesc(pFuncDesc);
                }
                return(true);
            } catch (Exception) {
                return(true);
            }
        }
Exemple #17
0
        /// <summary>
        /// Determines whether the name belongs to a COM property on the given raw COM object.
        /// </summary>
        /// <remarks>
        /// Looks up type information using the COM ITypeInfo interface.
        /// Caches the result in the object's built-in COM data area so that subsequent queries for the same name are fast.
        /// </remarks>
        /// <param name="obj"></param>
        /// <param name="memberName"></param>
        /// <returns>false if no type information is available, or for any error condition.</returns>
        ///
        internal static bool IsCOMProp(object obj, string memberName)
        {
            if (Utils.IsMono)
            {
                return(false);
            }

            // The memberName can be changed by the call to GetMemberDispID below (U to _ conversion), but we want
            // to cache the isComProp value for the unmodified member name, so we save it.
            string unmodifiedMemberName = memberName;
            object cachedValue          = Marshal.GetComObjectData(obj, "NETLinkIsCOMProp" + unmodifiedMemberName);

            if (cachedValue != null)
            {
                return((bool)cachedValue);
            }
            else
            {
                UCOMIDispatch iDisp;
                UCOMITypeInfo iTypeInfo;
                try {
                    iDisp     = GetIDispatch(obj);
                    iTypeInfo = GetITypeInfo(obj, iDisp);
                } catch (Exception) {
                    Marshal.SetComObjectData(obj, "NETLinkIsCOMProp" + unmodifiedMemberName, false);
                    return(false);
                }
                // GetMemberDispID() does not throw on failure--it returns -1.
                int memberDispId = GetMemberDispID(obj, iDisp, ref memberName);
                if (memberDispId == -1)
                {
                    Marshal.SetComObjectData(obj, "NETLinkIsCOMProp" + unmodifiedMemberName, false);
                    return(false);
                }

                // We have successfully passed GetIDsOfNames() and GetITypeInfo(), so we know that type info is available and that
                // the name is a member of the dispatch interface. The name may also have been modified to reflect U to _ conversion.

                // Previous versions of this method acquired an ITypeInfo2 from the ITypeInfo and called GetFuncIndexOfMemId() to get
                // a function index suitable for GetFuncDesc(). There were problems with that technique, in that the index returned
                // sometimes (not always) needed to have 7 added to it. Because we cache the T/F result from this method anyway,
                // we now just exhaustively call GetFuncDesc() on all the members, looking for one with the right memberDispId.
                // Then we can check its func info to see if it is a property with no args.
                bool   result = false;
                IntPtr pTypeAttr;
                iTypeInfo.GetTypeAttr(out pTypeAttr);
                TYPEATTR typeAttr = (TYPEATTR)Marshal.PtrToStructure(pTypeAttr, typeof(TYPEATTR));
                int      numFuncs = typeAttr.cFuncs;
                iTypeInfo.ReleaseTypeAttr(pTypeAttr);
                for (int i = 0; i < numFuncs; i++)
                {
                    IntPtr pFuncDesc;
                    iTypeInfo.GetFuncDesc(i, out pFuncDesc);
                    FUNCDESC   funcDesc     = (FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(FUNCDESC));
                    int        thisMemberID = funcDesc.memid;
                    INVOKEKIND invokeKind   = funcDesc.invkind;
                    int        numParams    = funcDesc.cParams;
                    iTypeInfo.ReleaseFuncDesc(pFuncDesc);
                    if (thisMemberID == memberDispId)
                    {
                        result = invokeKind == INVOKEKIND.INVOKE_PROPERTYGET && numParams == 0;
                        break;
                    }
                }
                Marshal.SetComObjectData(obj, "NETLinkIsCOMProp" + unmodifiedMemberName, result);
                return(result);
            }
        }
Exemple #18
0
 public static ComEventsInfo?Find(object rcw)
 {
     return((ComEventsInfo?)Marshal.GetComObjectData(rcw, typeof(ComEventsInfo)));
 }
Exemple #19
0
 public void GetComObjectData_NonComObjectObj_ThrowsArgumentNullException()
 {
     AssertExtensions.Throws <ArgumentException>("obj", () => Marshal.GetComObjectData(1, 2));
 }
Exemple #20
0
 public void GetComObjectData_NullKey_ThrowsArgumentNullException()
 {
     AssertExtensions.Throws <ArgumentNullException>("key", () => Marshal.GetComObjectData(new object(), null));
 }
Exemple #21
0
 public void GetComObjectData_NullObj_ThrowsArgumentNullException()
 {
     AssertExtensions.Throws <ArgumentNullException>("obj", () => Marshal.GetComObjectData(null, new object()));
 }
Exemple #22
0
 public void GetComObjectData_NetCore_ThrowsPlatformNotSupportedException()
 {
     Assert.Throws <PlatformNotSupportedException>(() => Marshal.GetComObjectData(null, null));
 }
 public void GetComObjectData_ThrowsNotSupportedException()
 {
     Assert.Throws <NotSupportedException>(() => Marshal.GetComObjectData("key", "value"));
 }