1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Microsoft Public License. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Microsoft Public License, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Microsoft Public License.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
15 using System; using Microsoft;
18 #if !SILVERLIGHT // ComObject
21 using System.Linq.Expressions;
23 using Microsoft.Linq.Expressions;
25 using System.Runtime.CompilerServices;
27 using Microsoft.Runtime.CompilerServices;
30 using System.Security;
31 using System.Security.Permissions;
34 namespace System.Dynamic {
36 namespace Microsoft.Scripting {
38 internal sealed class BoundDispEvent : DynamicObject {
40 private Guid _sourceIid;
43 internal BoundDispEvent(object rcw, Guid sourceIid, int dispid) {
45 _sourceIid = sourceIid;
50 /// Provides the implementation of performing AddAssign and SubtractAssign binary operations.
52 /// <param name="binder">The binder provided by the call site.</param>
53 /// <param name="handler">The handler for the operation.</param>
54 /// <param name="result">The result of the operation.</param>
55 /// <returns>true if the operation is complete, false if the call site should determine behavior.</returns>
56 public override bool TryBinaryOperation(BinaryOperationBinder binder, object handler, out object result) {
57 if (binder.Operation == ExpressionType.AddAssign) {
58 result = InPlaceAdd(handler);
62 if (binder.Operation == ExpressionType.SubtractAssign) {
63 result = InPlaceSubtract(handler);
71 private static void VerifyHandler(object handler) {
72 if (handler is Delegate && handler.GetType() != typeof(Delegate)) {
76 if (handler is IDynamicMetaObjectProvider) {
80 throw Error.UnsupportedHandlerType();
84 /// Adds a handler to an event.
86 /// <param name="handler">The handler to be added.</param>
87 /// <returns>The original event with handler added.</returns>
89 [SecurityCritical, SecurityTreatAsSafe]
91 [SecuritySafeCritical]
93 private object InPlaceAdd(object handler) {
94 ContractUtils.RequiresNotNull(handler, "handler");
95 VerifyHandler(handler);
98 // Demand Full Trust to proceed with the operation.
101 new PermissionSet(PermissionState.Unrestricted).Demand();
103 ComEventSink comEventSink = ComEventSink.FromRuntimeCallableWrapper(_rcw, _sourceIid, true);
104 comEventSink.AddHandler(_dispid, handler);
109 /// Removes handler from the event.
111 /// <param name="handler">The handler to be removed.</param>
112 /// <returns>The original event with handler removed.</returns>
113 #if MICROSOFT_DYNAMIC
114 [SecurityCritical, SecurityTreatAsSafe]
116 [SecuritySafeCritical]
118 private object InPlaceSubtract(object handler) {
119 ContractUtils.RequiresNotNull(handler, "handler");
120 VerifyHandler(handler);
123 // Demand Full Trust to proceed with the operation.
126 new PermissionSet(PermissionState.Unrestricted).Demand();
128 ComEventSink comEventSink = ComEventSink.FromRuntimeCallableWrapper(_rcw, _sourceIid, false);
129 if (comEventSink != null) {
130 comEventSink.RemoveHandler(_dispid, handler);