void ITypeInfo.AddressOfMember(int memid, INVOKEKIND invKind, out IntPtr ppv)
 {
     Before($"{nameof(memid)}: {memid}, {nameof(invKind)}: {invKind}");
     _wrapper.AddressOfMember(memid, invKind, out var t);
     After($"{nameof(ppv)}: {t}");
     ppv = t;
 }
        void ITypeInfo.GetDllEntry(int memid, INVOKEKIND invKind, IntPtr pBstrDllName, IntPtr pBstrName, IntPtr pwOrdinal)
        {
            Before($"{nameof(memid)}: {memid}, {nameof(invKind)}: {invKind}, {nameof(pBstrDllName)}: {pBstrDllName}, {nameof(pBstrName)}: {pBstrName}, {nameof(pwOrdinal)}: {pwOrdinal}");
            var result = _inner.GetDllEntry(memid, invKind, pBstrDllName, pBstrName, pwOrdinal);

            After($"{nameof(result)}: {result}");
        }
Example #3
0
        internal ComMethodDesc(ITypeInfo typeInfo, FUNCDESC funcDesc)
            : this(funcDesc.memid) {

            _hasTypeInfo = true;
            InvokeKind = funcDesc.invkind;

            int cNames;
            string[] rgNames = new string[1 + funcDesc.cParams];
            typeInfo.GetNames(_memid, rgNames, rgNames.Length, out cNames);
            if (IsPropertyPut && rgNames[rgNames.Length - 1] == null) {
                rgNames[rgNames.Length - 1] = "value";
                cNames++;
            }
            Debug.Assert(cNames == rgNames.Length);
            _name = rgNames[0];

            _parameters = new ComParamDesc[funcDesc.cParams];

            int offset = 0;
            for (int i = 0; i < funcDesc.cParams; i++) {
                ELEMDESC elemDesc = (ELEMDESC)Marshal.PtrToStructure(
                    new IntPtr(funcDesc.lprgelemdescParam.ToInt64() + offset),
                    typeof(ELEMDESC));

                _parameters[i] = new ComParamDesc(ref elemDesc, rgNames[1 + i]);

                offset += Marshal.SizeOf(typeof(ELEMDESC));
            }
        }
Example #4
0
        internal ComMethodDesc(ITypeInfo typeInfo, FUNCDESC funcDesc)
            : this(funcDesc.memid)
        {
            _hasTypeInfo = true;
            InvokeKind   = funcDesc.invkind;

            int cNames;

            string[] rgNames = new string[1 + funcDesc.cParams];
            typeInfo.GetNames(_memid, rgNames, rgNames.Length, out cNames);
            if (IsPropertyPut && rgNames[rgNames.Length - 1] == null)
            {
                rgNames[rgNames.Length - 1] = "value";
                cNames++;
            }
            Debug.Assert(cNames == rgNames.Length);
            _name = rgNames[0];

            _parameters = new ComParamDesc[funcDesc.cParams];

            int offset = 0;

            for (int i = 0; i < funcDesc.cParams; i++)
            {
                ELEMDESC elemDesc = (ELEMDESC)Marshal.PtrToStructure(
                    new IntPtr(funcDesc.lprgelemdescParam.ToInt64() + offset),
                    typeof(ELEMDESC));

                _parameters[i] = new ComParamDesc(ref elemDesc, rgNames[1 + i]);

                offset += Marshal.SizeOf(typeof(ELEMDESC));
            }
        }
Example #5
0
        internal ComMethodDesc(ITypeInfo typeInfo, FUNCDESC funcDesc)
            : this(funcDesc.memid)
        {
            InvokeKind = funcDesc.invkind;

            int cNames;

            string[] rgNames = new string[1 + funcDesc.cParams];
            typeInfo.GetNames(DispId, rgNames, rgNames.Length, out cNames);

            bool skipLast = false;

            if (IsPropertyPut && rgNames[rgNames.Length - 1] == null)
            {
                rgNames[rgNames.Length - 1] = "value";
                cNames++;
                skipLast = true;
            }
            Debug.Assert(cNames == rgNames.Length);
            _name = rgNames[0];

            ParamCount = funcDesc.cParams;

            ReturnType           = ComUtil.GetTypeFromTypeDesc(funcDesc.elemdescFunc.tdesc);
            ParameterInformation = ComUtil.GetParameterInformation(funcDesc, skipLast);
        }
        private int AddressOfMember(int memid, INVOKEKIND invKind, IntPtr ppv)
        {
            Before($"{nameof(memid)}: {memid}, {nameof(invKind)}: {invKind}, {nameof(ppv)}: {ppv}");
            var result = _wrapper.AddressOfMember(memid, invKind, ppv);

            After($"{nameof(result)}: {result}");
            return(result);
        }
Example #7
0
 public int GetDllEntry(int memid, INVOKEKIND invKind, ref IntPtr pBstrDllName, ref IntPtr pBstrName, ref ushort pwOrdinal)
 {
     if (m_GetDllEntryFunc == null)
     {
         var fp = GetFunctionPointer(13);
         m_GetDllEntryFunc = (GetDllEntryFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(GetDllEntryFunc));
     }
     return(m_GetDllEntryFunc(m_ptr, memid, invKind, ref pBstrDllName, ref pBstrName, ref pwOrdinal));
 }
Example #8
0
 public int DeleteFuncDescByMemId(int memid, INVOKEKIND invKind)
 {
     if (m_DeleteFuncDescByMemIdFunc == null)
     {
         var fp = GetFunctionPointer(27);
         m_DeleteFuncDescByMemIdFunc = (DeleteFuncDescByMemIdFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(DeleteFuncDescByMemIdFunc));
     }
     return(m_DeleteFuncDescByMemIdFunc(m_ptr, memid, invKind));
 }
Example #9
0
 public int AddressOfMember(int memid, INVOKEKIND invKind, ref IntPtr ppv)
 {
     if (m_AddressOfMemberFunc == null)
     {
         var fp = GetFunctionPointer(15);
         m_AddressOfMemberFunc = (AddressOfMemberFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(AddressOfMemberFunc));
     }
     return(m_AddressOfMemberFunc(m_ptr, memid, invKind, ref ppv));
 }
Example #10
0
 public int GetFuncIndexOfMemId(int memid, INVOKEKIND invKind, ref uint pFuncIndex)
 {
     if (m_GetFuncIndexOfMemIdFunc == null)
     {
         var fp = GetFunctionPointer(24);
         m_GetFuncIndexOfMemIdFunc = (GetFuncIndexOfMemIdFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(GetFuncIndexOfMemIdFunc));
     }
     return(m_GetFuncIndexOfMemIdFunc(m_ptr, memid, invKind, ref pFuncIndex));
 }
    void ComWrappersImpl.IDispatch.Invoke(
        int dispIdMember,
        ref Guid riid,
        int lcid,
        INVOKEKIND wFlags,
        ref DISPPARAMS pDispParams,
        IntPtr VarResult,
        IntPtr pExcepInfo,
        IntPtr puArgErr)
    {
        MemberInfo?memberInfo;

        if (!this.dispIdToMemberInfo.TryGetValue(dispIdMember, out memberInfo))
        {
            throw new COMException(null, DISP_E_UNKNOWNNAME);
        }

        BindingFlags invokeFlags = BindingFlags.Public | BindingFlags.Instance;

        if (wFlags.HasFlag(INVOKEKIND.INVOKE_FUNC) &&
            memberInfo.MemberType == MemberTypes.Method)
        {
            invokeFlags |= BindingFlags.InvokeMethod;
        }
        else
        {
            throw new NotImplementedException("Operation not implemented.");
        }

        // Use reflection to dispatch to the indicated function.
        // Note that this is exactly what the internal implementation of IDispatch does so there
        // isn't a lot of difference in cost.
        var result = this.objType.InvokeMember(
            memberInfo.Name,
            invokeFlags,
            null,
            this.obj,
            MarshalArguments(ref pDispParams));

        if (result != null)
        {
            // Lots of special cases should be addressed here.
            //  * Arrays, IEnumerable
            //  * IDispatch/IUnknown instances
            //  * .NET object could be wrapped by ComWrappers
            //  * .NET objects that are already COM objects can be safely passed on
            //  * etc
            Marshal.GetNativeVariantForObject(result, VarResult);
        }
    }
Example #12
0
        internal ComMethodDesc(ITypeInfo typeInfo, FUNCDESC funcDesc)
            : this(funcDesc.memid)
        {
            _invokeKind = funcDesc.invkind;

            string[] rgNames = new string[1 + funcDesc.cParams];
            typeInfo.GetNames(DispId, rgNames, rgNames.Length, out int cNames);
            if (IsPropertyPut && rgNames[rgNames.Length - 1] == null)
            {
                rgNames[rgNames.Length - 1] = "value";
                cNames++;
            }
            Debug.Assert(cNames == rgNames.Length);
            Name = rgNames[0];

            ParamCount = funcDesc.cParams;
        }
Example #13
0
        internal ComMethodDesc(ITypeInfo typeInfo, FUNCDESC funcDesc)
            : this(funcDesc.memid) {

            InvokeKind = funcDesc.invkind;

            int cNames;
            string[] rgNames = new string[1 + funcDesc.cParams];
            typeInfo.GetNames(_memid, rgNames, rgNames.Length, out cNames);
            if (IsPropertyPut && rgNames[rgNames.Length - 1] == null) {
                rgNames[rgNames.Length - 1] = "value";
                cNames++;
            }
            Debug.Assert(cNames == rgNames.Length);
            _name = rgNames[0];

            _paramCnt = funcDesc.cParams;
        }
Example #14
0
        public DispatchMember(string name, int dispid, INVOKEKIND invokeKind)
            : this(name, dispid)
        {
            if (invokeKind.HasFlag(INVOKEKIND.INVOKE_FUNC))
            {
                DispatchFlags |= DispatchFlags.Method;
            }

            if (invokeKind.HasFlag(INVOKEKIND.INVOKE_PROPERTYGET))
            {
                DispatchFlags |= DispatchFlags.PropertyGet;
            }

            if (invokeKind.HasFlag(INVOKEKIND.INVOKE_PROPERTYPUT))
            {
                DispatchFlags |= DispatchFlags.PropertyPut;
            }

            if (invokeKind.HasFlag(INVOKEKIND.INVOKE_PROPERTYPUTREF))
            {
                DispatchFlags |= DispatchFlags.PropertyPutRef;
            }
        }
Example #15
0
        internal ComMethodDesc(ITypeInfo typeInfo, FUNCDESC funcDesc)
            : this(funcDesc.memid)
        {
            InvokeKind = funcDesc.invkind;

            int cNames;
            string[] rgNames = new string[1 + funcDesc.cParams];
            typeInfo.GetNames(DispId, rgNames, rgNames.Length, out cNames);

            bool skipLast = false;
            if (IsPropertyPut && rgNames[rgNames.Length - 1] == null)
            {
                rgNames[rgNames.Length - 1] = "value";
                cNames++;
                skipLast = true;
            }
            Debug.Assert(cNames == rgNames.Length);
            _name = rgNames[0];

            ParamCount = funcDesc.cParams;

            ReturnType = ComUtil.GetTypeFromTypeDesc(funcDesc.elemdescFunc.tdesc);
            ParameterInformation = ComUtil.GetParameterInformation(funcDesc, skipLast);
        }
 int ITypeInfoWrapper.AddressOfMember(int memid, INVOKEKIND invKind, IntPtr ppv)
 {
     return(AddressOfMember(memid, invKind, ppv));
 }
Example #17
0
 public unsafe int RemoteGetDllEntry(int memid, INVOKEKIND invKind, uint refPtrFlags, char** pBstrDllName, char** pBstrName, ushort* pwOrdinal)
 {
     ITypeInfo_vtbl** @this = (ITypeInfo_vtbl**)reference;
     ITypeInfo_vtbl* vtbl = *@this;
     if (vtbl == null)
         throw new InvalidComObjectException();
     Delegate genericDelegate = Marshal.GetDelegateForFunctionPointer(vtbl->method_13, typeof(delegate_13));
     delegate_13 method = (delegate_13)genericDelegate;
     return method(@this, memid, invKind, refPtrFlags, pBstrDllName, pBstrName, pwOrdinal);
 }
Example #18
0
 internal ComMethodDesc(string name, int dispId, INVOKEKIND invkind)
     : this(name, dispId)
 {
     InvokeKind = invkind;
 }
Example #19
0
 public int AddressOfMember([NativeTypeName("MEMBERID")] int memid, INVOKEKIND invKind, [NativeTypeName("PVOID *")] void **ppv)
 {
     return(((delegate * unmanaged <ITypeInfo *, int, INVOKEKIND, void **, int>)(lpVtbl[15]))((ITypeInfo *)Unsafe.AsPointer(ref this), memid, invKind, ppv));
 }
Example #20
0
 internal ComMethodDesc(string name, int dispId, INVOKEKIND invkind)
     : this(name, dispId)
 {
     InvokeKind = invkind;
 }
Example #21
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);
            }
        }
Example #22
0
 public int GetDllEntry([NativeTypeName("MEMBERID")] int memid, INVOKEKIND invKind, [NativeTypeName("BSTR *")] ushort **pBstrDllName, [NativeTypeName("BSTR *")] ushort **pBstrName, [NativeTypeName("WORD *")] ushort *pwOrdinal)
 {
     return(((delegate * unmanaged <ITypeInfo *, int, INVOKEKIND, ushort **, ushort **, ushort *, int>)(lpVtbl[13]))((ITypeInfo *)Unsafe.AsPointer(ref this), memid, invKind, pBstrDllName, pBstrName, pwOrdinal));
 }
Example #23
0
 public void GetDllEntry(int memid, INVOKEKIND invKind, IntPtr pBstrDllName, IntPtr pBstrName, IntPtr pwOrdinal)
 {
     throw new Exception("The method or operation is not implemented.");
 }
 public int DeleteFuncDescByMemId([NativeTypeName("MEMBERID")] int memid, INVOKEKIND invKind)
 {
     return(((delegate * stdcall <ICreateTypeInfo2 *, int, INVOKEKIND, int>)(lpVtbl[27]))((ICreateTypeInfo2 *)Unsafe.AsPointer(ref this), memid, invKind));
 }
Example #25
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);
            }
        }
Example #26
0
 public void AddressOfMember(int memid, INVOKEKIND invKind, out IntPtr ppv)
 {
     throw new Exception("The method or operation is not implemented.");
 }
        unsafe void NativeMethods.IDispatch.Invoke(int dispid, ref Guid riid, int lcid, INVOKEKIND wFlags, ref DISPPARAMS pDispParams, IntPtr pvarResult, IntPtr pExcepInfo, IntPtr puArgErr)
        {
            ComEventsMethod comEventsMethod = this.FindMethod(dispid);

            if (comEventsMethod == null)
            {
                return;
            }
            object[] array  = new object[pDispParams.cArgs];
            int[]    array2 = new int[pDispParams.cArgs];
            bool[]   array3 = new bool[pDispParams.cArgs];
            Variant *ptr    = (Variant *)((void *)pDispParams.rgvarg);
            int *    ptr2   = (int *)((void *)pDispParams.rgdispidNamedArgs);
            int      i;
            int      num;

            for (i = 0; i < pDispParams.cNamedArgs; i++)
            {
                num = ptr2[i];
                Variant *variant = ComEventsSink.GetVariant(ptr + i);
                array[num]  = variant->ToObject();
                array3[num] = true;
                if (variant->IsByRef)
                {
                    array2[num] = i;
                }
                else
                {
                    array2[num] = -1;
                }
            }
            num = 0;
            while (i < pDispParams.cArgs)
            {
                while (array3[num])
                {
                    num++;
                }
                Variant *variant2 = ComEventsSink.GetVariant(ptr + (pDispParams.cArgs - 1 - i));
                array[num] = variant2->ToObject();
                if (variant2->IsByRef)
                {
                    array2[num] = pDispParams.cArgs - 1 - i;
                }
                else
                {
                    array2[num] = -1;
                }
                num++;
                i++;
            }
            object obj = comEventsMethod.Invoke(array);

            if (pvarResult != IntPtr.Zero)
            {
                Marshal.GetNativeVariantForObject(obj, pvarResult);
            }
            for (i = 0; i < pDispParams.cArgs; i++)
            {
                int num2 = array2[i];
                if (num2 != -1)
                {
                    ComEventsSink.GetVariant(ptr + num2)->CopyFromIndirect(array[i]);
                }
            }
        }
Example #28
0
 public HRESULT GetFuncIndexOfMemId([NativeTypeName("MEMBERID")] int memid, INVOKEKIND invKind, uint *pFuncIndex)
 {
     return(((delegate * unmanaged <ITypeInfo2 *, int, INVOKEKIND, uint *, int>)(lpVtbl[24]))((ITypeInfo2 *)Unsafe.AsPointer(ref this), memid, invKind, pFuncIndex));
 }
Example #29
0
 public int GetFuncIndexOfMemId([NativeTypeName("MEMBERID")] int memid, INVOKEKIND invKind, [NativeTypeName("UINT *")] uint *pFuncIndex)
 {
     return(((delegate * stdcall <ITypeInfo2 *, int, INVOKEKIND, uint *, int>)(lpVtbl[24]))((ITypeInfo2 *)Unsafe.AsPointer(ref this), memid, invKind, pFuncIndex));
 }
Example #30
0
 public void AddressOfMember(int memid, INVOKEKIND invKind, out IntPtr ppv)
 {
     throw new Exception("The method or operation is not implemented.");
 }
Example #31
0
 public void GetDllEntry(int memid, INVOKEKIND invKind, IntPtr pBstrDllName, IntPtr pBstrName, IntPtr pwOrdinal)
 {
     throw new Exception("The method or operation is not implemented.");
 }