Exemple #1
0
        internal ComInvokeBinder(
                CallInfo callInfo, 
                DynamicMetaObject[] args,
                bool[] isByRef,
                BindingRestrictions restrictions, 
                Expression method, 
                Expression dispatch, 
                ComMethodDesc methodDesc
                )
        {
            Debug.Assert(callInfo != null, "arguments");
            Debug.Assert(args != null, "args");
            Debug.Assert(isByRef != null, "isByRef");
            Debug.Assert(method != null, "method");
            Debug.Assert(dispatch != null, "dispatch");

            Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(ComMethodDesc), method.Type), "method");
            Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(IDispatch), dispatch.Type), "dispatch");

            _method = method;
            _dispatch = dispatch;
            _methodDesc = methodDesc;

            _callInfo = callInfo;
            _args = args;
            _isByRef = isByRef;
            _restrictions = restrictions;

            // Set Instance to some value so that CallBinderHelper has the right number of parameters to work with
            _instance = dispatch;
        }
        private DynamicMetaObject BindComInvoke(DynamicMetaObject[] args, ComMethodDesc method, CallInfo callInfo, bool[] isByRef,
            List<ParameterExpression> temps, List<Expression> initTemps)
        {
            DynamicMetaObject invoke = new ComInvokeBinder(
                callInfo,
                args,
                isByRef,
                IDispatchRestriction(),
                Expression.Constant(method),
                Expression.Property(
                    Helpers.Convert(Expression, typeof(IDispatchComObject)),
                    typeof(IDispatchComObject).GetProperty("DispatchObject")
                ),
                method
            ).Invoke();

            if ((temps != null) && (temps.Any()))
            {
                Expression invokeExpression = invoke.Expression;
                Expression call = Expression.Block(invokeExpression.Type, temps, initTemps.Append(invokeExpression));
                invoke = new DynamicMetaObject(call, invoke.Restrictions);
            }

            return invoke;
        }
 private DynamicMetaObject BindComInvoke(DynamicMetaObject[] args, ComMethodDesc method, CallInfo callInfo, bool[] isByRef) {
     return new ComInvokeBinder(
         callInfo,
         args,
         isByRef,
         IDispatchRestriction(),
         Expression.Constant(method),
         Expression.Property(
             Helpers.Convert(Expression, typeof(IDispatchComObject)),
             typeof(IDispatchComObject).GetProperty("DispatchObject")
         ),
         method
     ).Invoke();
 }
Exemple #4
0
 private DynamicMetaObject BindComInvoke(DynamicMetaObject[] args, ComMethodDesc method, CallInfo callInfo, bool[] isByRef)
 {
     return(new ComInvokeBinder(
                callInfo,
                args,
                isByRef,
                IDispatchRestriction(),
                Expression.Constant(method),
                Expression.Property(
                    Helpers.Convert(Expression, typeof(IDispatchComObject)),
                    typeof(IDispatchComObject).GetProperty("DispatchObject")
                    ),
                method
                ).Invoke());
 }
        private DynamicMetaObject BindComInvoke(ComMethodDesc method, DynamicMetaObject[] indexes, CallInfo callInfo, bool[] isByRef) {
            var callable = Expression;
            var dispCall = Helpers.Convert(callable, typeof(DispCallable));

            return new ComInvokeBinder(
                callInfo,
                indexes,
                isByRef,
                DispCallableRestrictions(),
                Expression.Constant(method),
                Expression.Property(
                    dispCall,
                    typeof(DispCallable).GetProperty("DispatchObject")
                ),
                method
            ).Invoke();
        }
Exemple #6
0
        private bool SlowTryGetSetItem(out ComMethodDesc value)
        {
            EnsureScanDefinedMethods();

            ComMethodDesc methodDesc = _comTypeDesc.SetItem;

            // Without type information, we really don't know whether or not we have a property setter.
            if (methodDesc == null)
            {
                string name = "[PROPERTYPUT, DISPID(0)]";

                _comTypeDesc.EnsureSetItem(new ComMethodDesc(name, ComDispIds.DISPID_VALUE, ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT));
                methodDesc = _comTypeDesc.SetItem;
            }

            value = methodDesc;
            return(true);
        }
Exemple #7
0
        private DynamicMetaObject BindComInvoke(ComMethodDesc method, DynamicMetaObject[] indexes, CallInfo callInfo, bool[] isByRef)
        {
            var callable = Expression;
            var dispCall = Helpers.Convert(callable, typeof(DispCallable));

            return(new ComInvokeBinder(
                       callInfo,
                       indexes,
                       isByRef,
                       DispCallableRestrictions(),
                       Expression.Constant(method),
                       Expression.Property(
                           dispCall,
                           typeof(DispCallable).GetProperty("DispatchObject")
                           ),
                       method
                       ).Invoke());
        }
Exemple #8
0
        internal bool TryGetPropertySetterExplicit(string name, out ComMethodDesc method, Type limitType, bool holdsNull)
        {
            EnsureScanDefinedMethods();

            int dispId;
            int hresult = GetIDsOfNames(_dispatchObject, name, out dispId);

            if (hresult == ComHresults.S_OK)
            {
                // we do not know whether we have put or putref here
                // and we will not guess and pretend we found both.
                ComMethodDesc put = new ComMethodDesc(name, dispId, ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT);
                _comTypeDesc.AddPut(name, put);

                ComMethodDesc putref = new ComMethodDesc(name, dispId, ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF);
                _comTypeDesc.AddPutRef(name, putref);

                if (ComBinderHelpers.PreferPut(limitType, holdsNull))
                {
                    method = put;
                }
                else
                {
                    method = putref;
                }
                return(true);
            }
            else if (hresult == ComHresults.DISP_E_UNKNOWNNAME)
            {
                method = null;
                return(false);
            }
            else
            {
                throw Error.CouldNotGetDispId(name, string.Format(CultureInfo.InvariantCulture, "0x{1:X})", hresult));
            }
        }
Exemple #9
0
        internal bool TryGetMemberMethodExplicit(string name, out ComMethodDesc method)
        {
            EnsureScanDefinedMethods();

            int dispId;
            int hresult = GetIDsOfNames(_dispatchObject, name, out dispId);

            if (hresult == ComHresults.S_OK)
            {
                ComMethodDesc cmd = new ComMethodDesc(name, dispId, ComTypes.INVOKEKIND.INVOKE_FUNC);
                _comTypeDesc.AddFunc(name, cmd);
                method = cmd;
                return(true);
            }
            else if (hresult == ComHresults.DISP_E_UNKNOWNNAME)
            {
                method = null;
                return(false);
            }
            else
            {
                throw Error.CouldNotGetDispId(name, string.Format(CultureInfo.InvariantCulture, "0x{1:X})", hresult));
            }
        }
Exemple #10
0
        internal bool TryGetMemberMethodExplicit(string name, out ComMethodDesc method) {
            EnsureScanDefinedMethods();

            int dispId;
            int hresult = GetIDsOfNames(_dispatchObject, name, out dispId);

            if (hresult == ComHresults.S_OK) {
                ComMethodDesc cmd = new ComMethodDesc(name, dispId, ComTypes.INVOKEKIND.INVOKE_FUNC);
                _comTypeDesc.AddFunc(name, cmd);
                method = cmd;
                return true;
            } else if (hresult == ComHresults.DISP_E_UNKNOWNNAME) {
                method = null;
                return false;
            } else {
                throw Error.CouldNotGetDispId(name, string.Format(CultureInfo.InvariantCulture, "0x{1:X})", hresult));
            }
        }
Exemple #11
0
 internal void EnsureSetItem(ComMethodDesc candidate)
 {
     Interlocked.CompareExchange(ref _setItem, candidate, null);
 }
        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);
            }
        }
Exemple #13
0
 public static DispCallable CreateDispCallable(IDispatchComObject dispatch, ComMethodDesc method)
 {
     return(new DispCallable(dispatch, method.Name, method.DispId));
 }
Exemple #14
0
 internal void EnsureSetItem(ComMethodDesc candidate) {
     Interlocked.CompareExchange(ref _setItem, candidate, null);
 }
Exemple #15
0
 internal void AddPutRef(string name, ComMethodDesc method) {
     name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
     lock (_putRefs) {
         _putRefs[name] = method;
     }
 }
Exemple #16
0
 internal bool TryGetPutRef(string name, out ComMethodDesc method) {
     name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
     if (_putRefs.ContainsKey(name)) {
         method = _putRefs[name] as ComMethodDesc;
         return true;
     }
     method = null;
     return false;
 }
Exemple #17
0
 public static DispCallable CreateDispCallable(IDispatchComObject dispatch, ComMethodDesc method) {
     return new DispCallable(dispatch, method.Name, method.DispId);
 }
Exemple #18
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);
            }
        }
Exemple #19
0
        private DynamicMetaObject BindGetMember(ComMethodDesc method, bool canReturnCallables)
        {
            if (method.IsDataMember)
            {
                if (method.ParamCount == 0)
                {
                    return BindComInvoke(DynamicMetaObject.EmptyMetaObjects, method, new CallInfo(0), Utils.EmptyArray<bool>(), null, null);
                }
            }

            // ComGetMemberBinder does not expect callables. Try to call always.
            if (!canReturnCallables)
            {
                return BindComInvoke(DynamicMetaObject.EmptyMetaObjects, method, new CallInfo(0), Utils.EmptyArray<bool>(), null, null);
            }

            return new DynamicMetaObject(
                Expression.Call(
                    typeof(ComRuntimeHelpers).GetMethod("CreateDispCallable"),
                    Helpers.Convert(Expression, typeof(IDispatchComObject)),
                    Expression.Constant(method)
                ),
                IDispatchRestriction()
            );
        }
Exemple #20
0
 internal bool TryGetMemberMethod(string name, out ComMethodDesc method) {
     EnsureScanDefinedMethods();
     return _comTypeDesc.TryGetFunc(name, out method);
 }
Exemple #21
0
        private bool SlowTryGetSetItem(out ComMethodDesc value) {
            EnsureScanDefinedMethods();

            ComMethodDesc methodDesc = _comTypeDesc.SetItem;

            // Without type information, we really don't know whether or not we have a property setter.
            if (methodDesc == null) {
                string name = "[PROPERTYPUT, DISPID(0)]";

                _comTypeDesc.EnsureSetItem(new ComMethodDesc(name, ComDispIds.DISPID_VALUE, ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT));
                methodDesc = _comTypeDesc.SetItem;
            }

            value = methodDesc;
            return true;
        }
Exemple #22
0
        internal bool TryGetSetItem(out ComMethodDesc value) {
            ComMethodDesc methodDesc = _comTypeDesc.SetItem;
            if (methodDesc != null) {
                value = methodDesc;
                return true;
            }

            return SlowTryGetSetItem(out value);
        }
Exemple #23
0
 internal bool TryGetMemberMethod(string name, out ComMethodDesc method)
 {
     EnsureScanDefinedMethods();
     return(_comTypeDesc.TryGetFunc(name, out method));
 }
Exemple #24
0
        internal bool TryGetPropertySetterExplicit(string name, out ComMethodDesc method, Type limitType, bool holdsNull) {
            EnsureScanDefinedMethods();

            int dispId;
            int hresult = GetIDsOfNames(_dispatchObject, name, out dispId);

            if (hresult == ComHresults.S_OK) {
                // we do not know whether we have put or putref here
                // and we will not guess and pretend we found both.
                ComMethodDesc put = new ComMethodDesc(name, dispId, ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT);
                _comTypeDesc.AddPut(name, put);

                ComMethodDesc putref = new ComMethodDesc(name, dispId, ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF);
                _comTypeDesc.AddPutRef(name, putref);

                if (ComBinderHelpers.PreferPut(limitType, holdsNull)) {
                    method = put;
                } else {
                    method = putref;
                }
                return true;
            } else if (hresult == ComHresults.DISP_E_UNKNOWNNAME) {
                method = null;
                return false;
            } else {
                throw Error.CouldNotGetDispId(name, string.Format(CultureInfo.InvariantCulture, "0x{1:X})", hresult));
            }
        }
Exemple #25
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);
            }
        }
Exemple #26
0
        internal bool TryGetPropertySetter(string name, out ComMethodDesc method, Type limitType, bool holdsNull) {
            EnsureScanDefinedMethods();

            if (ComBinderHelpers.PreferPut(limitType, holdsNull)) {
                return _comTypeDesc.TryGetPut(name, out method) ||
                    _comTypeDesc.TryGetPutRef(name, out method);
            } else {
                return _comTypeDesc.TryGetPutRef(name, out method) ||
                    _comTypeDesc.TryGetPut(name, out method);
            }
        }
        private DynamicMetaObject BindComInvoke(ComMethodDesc method, DynamicMetaObject[] indexes, CallInfo callInfo, bool[] isByRef,
            List<ParameterExpression> temps, List<Expression> initTemps)
        {
            var callable = Expression;
            var dispCall = Helpers.Convert(callable, typeof(DispCallable));

            DynamicMetaObject invoke = new ComInvokeBinder(
                callInfo,
                indexes,
                isByRef,
                DispCallableRestrictions(),
                Expression.Constant(method),
                Expression.Property(
                    dispCall,
                    typeof(DispCallable).GetProperty("DispatchObject")
                ),
                method
            ).Invoke();

            if ((temps != null) && (temps.Any()))
            {
                Expression invokeExpression = invoke.Expression;
                Expression call = Expression.Block(invokeExpression.Type, temps, initTemps.Append(invokeExpression));
                invoke = new DynamicMetaObject(call, invoke.Restrictions);
            }

            return invoke;
        }
Exemple #28
0
        // this helper prepares arguments for COM binding by transforming ByVal StongBox arguments
        // into ByRef expressions that represent the argument's Value fields.
        internal static bool[] ProcessArgumentsForCom(ComMethodDesc method, ref DynamicMetaObject[] args,
            List<ParameterExpression> temps, List<Expression> initTemps)
        {
            Debug.Assert(args != null);

            DynamicMetaObject[] newArgs = new DynamicMetaObject[args.Length];
            bool[] isByRefArg = new bool[args.Length];

            for (int i = 0; i < args.Length; i++)
            {
                DynamicMetaObject curArgument = args[i];

                // set new arg infos to their original values or set default ones
                // we will do this fixup early so that we can assume we always have
                // arginfos in COM binder.

                if (IsByRef(curArgument))
                {
                    newArgs[i] = curArgument;
                    isByRefArg[i] = true;
                }
                else
                {
                    if (IsPSReferenceArg(curArgument))
                    {
                        var restrictions = curArgument.Restrictions.Merge(
                            GetTypeRestrictionForDynamicMetaObject(curArgument)
                        );

                        // we have restricted this argument to LimitType so we can convert and conversion will be trivial cast.
                        Expression boxedValueAccessor = Expression.Property(
                            Helpers.Convert(
                                curArgument.Expression,
                                curArgument.LimitType
                            ),
                            curArgument.LimitType.GetProperty("Value")
                        );

                        PSReference value = curArgument.Value as PSReference;
                        object boxedValue = value != null ? value.Value : null;

                        newArgs[i] = new DynamicMetaObject(
                            boxedValueAccessor,
                            restrictions,
                            boxedValue
                        );

                        isByRefArg[i] = true;
                    }
                    else
                    {
                        if ((method.ParameterInformation != null) && (i < method.ParameterInformation.Length))
                        {
                            newArgs[i] = new DynamicMetaObject(curArgument.CastOrConvertMethodArgument(
                                method.ParameterInformation[i].parameterType,
                                i.ToString(CultureInfo.InvariantCulture),
                                method.Name,
                                temps,
                                initTemps), curArgument.Restrictions);
                        }
                        else
                        {
                            newArgs[i] = curArgument;
                        }

                        isByRefArg[i] = false;
                    }
                }
            }

            args = newArgs;
            return isByRefArg;
        }