// This method is intended for use through reflection and should not be used directly
        public static unsafe int IDispatchInvoke(
            IntPtr dispatchPointer,
            int memberDispId,
            ComTypes.INVOKEKIND flags,
            ref ComTypes.DISPPARAMS dispParams,
            out Variant result,
            out ExcepInfo excepInfo,
            out uint argErr)
        {
            Guid IID_NULL = default;

            fixed(ComTypes.DISPPARAMS *pDispParams = &dispParams)
            fixed(Variant * pResult      = &result)
            fixed(ExcepInfo * pExcepInfo = &excepInfo)
            fixed(uint *pArgErr          = &argErr)
            {
                var pfnIDispatchInvoke = (delegate * stdcall <IntPtr, int, Guid *, int, ushort, ComTypes.DISPPARAMS *, Variant *, ExcepInfo *, uint *, int>)
                                             (*(*(void ***)dispatchPointer + 6 /* IDispatch.Invoke slot */));

                int hresult = pfnIDispatchInvoke(dispatchPointer,
                                                 memberDispId, &IID_NULL, 0, (ushort)flags, pDispParams, pResult, pExcepInfo, pArgErr);

                if (hresult == ComHresults.DISP_E_MEMBERNOTFOUND &&
                    (flags & ComTypes.INVOKEKIND.INVOKE_FUNC) != 0 &&
                    (flags & (ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT | ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF)) == 0)
                {
                    // Re-invoke with no result argument to accomodate Word
                    hresult = pfnIDispatchInvoke(dispatchPointer,
                                                 memberDispId, &IID_NULL, 0, (ushort)ComTypes.INVOKEKIND.INVOKE_FUNC, pDispParams, null, pExcepInfo, pArgErr);
                }

                return(hresult);
            }
        }
Beispiel #2
0
        // This method is intended for use through reflection and should not be used directly
        public static int IDispatchInvoke(
            IntPtr dispatchPointer,
            int memberDispId,
            ComTypes.INVOKEKIND flags,
            ref ComTypes.DISPPARAMS dispParams,
            out Variant result,
            out ExcepInfo excepInfo,
            out uint argErr)
        {
            int hresult = s_iDispatchInvoke(
                dispatchPointer,
                memberDispId,
                flags,
                ref dispParams,
                out result,
                out excepInfo,
                out argErr
                );

            if (hresult == ComHresults.DISP_E_MEMBERNOTFOUND &&
                (flags & ComTypes.INVOKEKIND.INVOKE_FUNC) != 0 &&
                (flags & (ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT | ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF)) == 0)
            {
                // Re-invoke with no result argument to accomodate Word
                hresult = _IDispatchInvokeNoResult(
                    dispatchPointer,
                    memberDispId,
                    ComTypes.INVOKEKIND.INVOKE_FUNC,
                    ref dispParams,
                    out result,
                    out excepInfo,
                    out argErr);
            }
            return(hresult);
        }
        public static void CheckThrowException(int hresult, ref ExcepInfo excepInfo, uint argErr, string message)
        {
            if (ComHresults.IsSuccess(hresult))
            {
                return;
            }

            switch (hresult)
            {
            case ComHresults.DISP_E_BADPARAMCOUNT:
                // The number of elements provided to DISPPARAMS is different from the number of arguments
                // accepted by the method or property.
                throw Error.DispBadParamCount(message);

            case ComHresults.DISP_E_BADVARTYPE:
                //One of the arguments in rgvarg is not a valid variant type.
                break;

            case ComHresults.DISP_E_EXCEPTION:
                // The application needs to raise an exception. In this case, the structure passed in pExcepInfo
                // should be filled in.
                throw excepInfo.GetException();

            case ComHresults.DISP_E_MEMBERNOTFOUND:
                // The requested member does not exist, or the call to Invoke tried to set the value of a
                // read-only property.
                throw Error.DispMemberNotFound(message);

            case ComHresults.DISP_E_NONAMEDARGS:
                // This implementation of IDispatch does not support named arguments.
                throw Error.DispNoNamedArgs(message);

            case ComHresults.DISP_E_OVERFLOW:
                // One of the arguments in rgvarg could not be coerced to the specified type.
                throw Error.DispOverflow(message);

            case ComHresults.DISP_E_PARAMNOTFOUND:
                // One of the parameter DISPIDs does not correspond to a parameter on the method. In this case,
                // puArgErr should be set to the first argument that contains the error.
                break;

            case ComHresults.DISP_E_TYPEMISMATCH:
                // One or more of the arguments could not be coerced. The index within rgvarg of the first
                // parameter with the incorrect type is returned in the puArgErr parameter.
                throw Error.DispTypeMismatch(argErr, message);

            case ComHresults.DISP_E_UNKNOWNINTERFACE:
                // The interface identifier passed in riid is not IID_NULL.
                break;

            case ComHresults.DISP_E_UNKNOWNLCID:
                // The member being invoked interprets string arguments according to the LCID, and the
                // LCID is not recognized.
                break;

            case ComHresults.DISP_E_PARAMNOTOPTIONAL:
                // A required parameter was omitted.
                throw Error.DispParamNotOptional(message);
            }

            Marshal.ThrowExceptionForHR(hresult);
        }