예제 #1
0
        // 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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        public static void CheckThrowException(int hresult, ref ExcepInfo excepInfo, ComMethodDesc method, object[] args, uint argErr)
        {
            if (ComHresults.IsSuccess(hresult))
            {
                return;
            }
            Exception parameterException = null;

            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.
                parameterException = Error.DispBadParamCount(method.Name, args.Length - 1);
                ThrowWrappedInvocationException(method, parameterException);
                break;

            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(method.Name);

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

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

            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:
                // The index within rgvarg of the first parameter with the incorrect
                // type is returned in the puArgErr parameter.
                //
                // But: Arguments are stored in pDispParams->rgvarg in reverse order, so the first
                // parameter is the one with the highest index in the array
                // https://msdn.microsoft.com/library/aa912367.aspx
                argErr = ((uint)args.Length) - argErr - 2;

                // One or more of the arguments could not be coerced.

                Type destinationType = null;
                if (argErr >= method.ParameterInformation.Length)
                {
                    destinationType = method.InputType;
                }
                else
                {
                    destinationType = method.ParameterInformation[argErr].parameterType;
                }

                object originalValue = args[argErr + 1];

                // If this is a put, use the InputType and the last argument
                if (method.IsPropertyPut || method.IsPropertyPutRef)
                {
                    destinationType = method.InputType;
                    originalValue   = args[args.Length - 1];
                }

                string originalValueString = originalValue.ToString();
                string originalTypeName    = Microsoft.PowerShell.ToStringCodeMethods.Type(originalValue.GetType(), true);

                // ByRef arguments should be displayed in the error message as a PSReference
                if (destinationType == typeof(object) && method.ParameterInformation[argErr].isByRef)
                {
                    destinationType = typeof(PSReference);
                }

                string destinationTypeName = Microsoft.PowerShell.ToStringCodeMethods.Type(destinationType, true);

                parameterException = Error.DispTypeMismatch(method.Name, originalValueString, originalTypeName, destinationTypeName);
                ThrowWrappedInvocationException(method, parameterException);
                break;

            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(method.Name);
            }

            Marshal.ThrowExceptionForHR(hresult);
        }
예제 #4
0
        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;
        }
예제 #5
0
        public static void CheckThrowException(int hresult, ref ExcepInfo excepInfo, ComMethodDesc method, object[] args, uint argErr)
        {
            if (Utils.Succeeded(hresult))
            {
                return;
            }

            Exception parameterException = null;

            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.

                    parameterException = Error.DispBadParamCount(method.Name, args.Length - 1);
                    ThrowWrappedInvocationException(method, parameterException);
                    break;

                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(method.Name);

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

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

                case ComHresults.DISP_E_PARAMNOTFOUND:
                    break;

                case ComHresults.DISP_E_TYPEMISMATCH:
                    // The index within rgvarg of the first parameter with the incorrect
                    // type is returned in the puArgErr parameter.
                    //
                    // But: Arguments are stored in pDispParams->rgvarg in reverse order, so the first
                    // parameter is the one with the highest index in the array
                    // http://msdn.microsoft.com/en-us/library/aa912367.aspx
                    argErr = ((uint)args.Length) - argErr - 2;


                    // One or more of the arguments could not be coerced.

                    Type destinationType = null;
                    if (argErr >= method.ParameterInformation.Length)
                    {
                        destinationType = method.InputType;
                    }
                    else
                    {
                        destinationType = method.ParameterInformation[argErr].parameterType;
                    }
                    object originalValue = args[argErr + 1];

                    // If this is a put, use the InputType and the last argument
                    if (method.IsPropertyPut || method.IsPropertyPutRef)
                    {
                        destinationType = method.InputType;
                        originalValue = args[args.Length - 1];
                    }

                    string originalValueString = originalValue.ToString();
                    string originalTypeName = Microsoft.PowerShell.ToStringCodeMethods.Type(originalValue.GetType(), true);

                    // ByRef arguments should be displayed in the error message as a PSReference
                    if (destinationType == typeof(Object) && method.ParameterInformation[argErr].isByRef)
                    {
                        destinationType = typeof(PSReference);
                    }

                    string destinationTypeName = Microsoft.PowerShell.ToStringCodeMethods.Type(destinationType, true);

                    parameterException = Error.DispTypeMismatch(method.Name, originalValueString, originalTypeName, destinationTypeName);
                    ThrowWrappedInvocationException(method, parameterException);
                    break;

                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(method.Name);
            }

            Marshal.ThrowExceptionForHR(hresult);
        }