[System.Security.SecurityCritical] // auto-generated private void PrivateInvoke(ref MessageData msgData, int type) { IMessage reqMsg = null; CallType callType = (CallType)type; IMessage retMsg = null; int msgFlags = -1; // Used only for Construction case RemotingProxy rp = null; // Create a message object based on the type of call if(CallType.MethodCall == callType) { Message msg = new Message(); msg.InitFields(msgData); reqMsg = msg; msgFlags = msg.GetCallType(); } else if (CallType.ConstructorCall == (CallType)callType) { // We use msgFlags to handle CallContext around // the virtual call to Invoke() msgFlags = Message.Sync; rp = this as RemotingProxy; ConstructorCallMessage ctorMsg = null; bool bIsWellKnown = false; if(!IsRemotingProxy()) { // Create a new constructor call message // < ctorMsg = new ConstructorCallMessage(null, null, null, (RuntimeType)GetProxiedType()); } else { // Extract the constructor message set in the first step of activation. ctorMsg = rp.ConstructorMessage; // If the proxy is a wellknown client proxy, we don't // need to run the c'tor. Identity id = rp.IdentityObject; if (id != null) bIsWellKnown = id.IsWellKnown(); } if ((null == ctorMsg) || bIsWellKnown) { // This is also used to short-circuit the activation path // when we have a well known proxy that has already been // initialized (there's a race condition if we don't do this). // // This is a special case, where we have a remoting proxy // but the constructormessage hasn't been setup. // so let us just bail out.. // this is currently used by ServicedComponent's for cross appdomain // pooling: <EMAIL>Microsoft</EMAIL> // ctorMsg = new ConstructorCallMessage(null, null, null, (RuntimeType)GetProxiedType()); // Set the constructor frame info in the CCM ctorMsg.SetFrame(msgData); reqMsg = ctorMsg; // If this was the default ctor, check that default .ctor was called. if (bIsWellKnown) { Contract.Assert(rp!=null, "RemotingProxy expected here!"); // Clear any cached ctorMsg on the RemotingProxy rp.ConstructorMessage = null; // We did execute a Connect. Throw if the client // code is also trying to use a non-default constructor at // the same time. if (ctorMsg.ArgCount != 0) { throw new RemotingException( Environment.GetResourceString( "Remoting_Activation_WellKnownCTOR")); } } // Create a constructor return message retMsg = new ConstructorReturnMessage((MarshalByRefObject)GetTransparentProxy(), null, 0, null, ctorMsg); } else { // Set the constructor frame info in the CCM ctorMsg.SetFrame(msgData); reqMsg = ctorMsg; } } else { Contract.Assert(false, "Unknown call type"); } // Make sure that outgoing remote calls are counted. ChannelServices.IncrementRemoteCalls(); // For non-remoting proxies, EndAsync should not call Invoke() // because the proxy cannot support Async and the call has already // finished executing in BeginAsync if (!IsRemotingProxy() && ((msgFlags&Message.EndAsync)==Message.EndAsync)) { Message msg = reqMsg as Message; retMsg = EndInvokeHelper(msg, true); Contract.Assert(null != retMsg, "null != retMsg"); } // Invoke Contract.Assert(null != reqMsg, "null != reqMsg"); if (null == retMsg) { // NOTE: there are cases where we setup a return message // and we don't want the activation call to go through // refer to the note above for ServicedComponents and Cross Appdomain // pooling LogicalCallContext cctx = null; Thread currentThread = Thread.CurrentThread; // Pick up or clone the call context from the thread // and install it in the reqMsg as appropriate cctx = currentThread.GetMutableExecutionContext().LogicalCallContext; SetCallContextInMessage(reqMsg, msgFlags, cctx); // Add the outgoing "Header"'s to the message. cctx.PropagateOutgoingHeadersToMessage(reqMsg); retMsg = Invoke(reqMsg); // Get the call context returned and set it on the thread ReturnCallContextToThread(currentThread, retMsg, msgFlags, cctx); // Pull response "Header"'s out of the message Thread.CurrentThread.GetMutableExecutionContext().LogicalCallContext.PropagateIncomingHeadersToCallContext(retMsg); } if (!IsRemotingProxy() && ((msgFlags&Message.BeginAsync) == Message.BeginAsync)) { // This was a begin-async on a non-Remoting Proxy. For V-1 they // cannot support Async and end up doing a Sync call. We need // to fill up here to make the call look like async to // the caller. // Create the async result to return Message msg = reqMsg as Message; AsyncResult ar = new AsyncResult(msg); // Tell the async result that the call has actually completed // so it can hold on to the return message. ar.SyncProcessMessage(retMsg); // create a returnMessage to propagate just the asyncResult back // to the caller's stack. retMsg = new ReturnMessage(ar, null, 0, null/*cctx*/, msg); } // Propagate out parameters HandleReturnMessage(reqMsg, retMsg); // For constructor calls do some extra bookkeeping if(CallType.ConstructorCall == callType) { // NOTE: It is the responsiblity of the callee to propagate // the out parameters // Everything went well, we are ready to return // a proxy to the caller // Extract the return value MarshalByRefObject retObj = null; IConstructionReturnMessage ctorRetMsg = retMsg as IConstructionReturnMessage; if(null == ctorRetMsg) { throw new RemotingException( Environment.GetResourceString("Remoting_Proxy_BadReturnTypeForActivation")); } ConstructorReturnMessage crm = ctorRetMsg as ConstructorReturnMessage; if (null != crm) { // If return message is of type ConstructorReturnMessage // this is an in-appDomain activation. So no unmarshaling // needed. retObj = (MarshalByRefObject)crm.GetObject(); if (retObj == null) { throw new RemotingException( Environment.GetResourceString("Remoting_Activation_NullReturnValue")); } } else { // Fetch the objRef out of the returned message and unmarshal it retObj = (MarshalByRefObject)RemotingServices.InternalUnmarshal( (ObjRef)ctorRetMsg.ReturnValue, GetTransparentProxy(), true /*fRefine*/); if (retObj == null) { throw new RemotingException( Environment.GetResourceString("Remoting_Activation_NullFromInternalUnmarshal")); } } if (retObj != (MarshalByRefObject)GetTransparentProxy()) { throw new RemotingException( Environment.GetResourceString( "Remoting_Activation_InconsistentState")); } if (IsRemotingProxy()) { // Clear any cached ctorMsg on the RemotingProxy rp.ConstructorMessage = null; } } }
private static void Invoke(object NotUsed, ref MessageData msgData) { Message reqMcmMsg = new Message(); reqMcmMsg.InitFields(msgData); Delegate thisPtr = reqMcmMsg.GetThisPtr() as Delegate; if (thisPtr == null) { throw new RemotingException(Environment.GetResourceString("Remoting_Default")); } RemotingProxy realProxy = (RemotingProxy) RemotingServices.GetRealProxy(thisPtr.Target); if (realProxy != null) { realProxy.InternalInvoke(reqMcmMsg, true, reqMcmMsg.GetCallType()); } else { int callType = reqMcmMsg.GetCallType(); switch (callType) { case 1: case 9: { reqMcmMsg.Properties[Message.CallContextKey] = CallContext.GetLogicalCallContext().Clone(); AsyncResult retVal = new AsyncResult(reqMcmMsg); AgileAsyncWorkerItem state = new AgileAsyncWorkerItem(reqMcmMsg, ((callType & 8) != 0) ? null : retVal, thisPtr.Target); ThreadPool.QueueUserWorkItem(new WaitCallback(AgileAsyncWorkerItem.ThreadPoolCallBack), state); if ((callType & 8) != 0) { retVal.SyncProcessMessage(null); } reqMcmMsg.PropagateOutParameters(null, retVal); break; } case 2: RealProxy.EndInvokeHelper(reqMcmMsg, false); return; case 10: break; default: return; } } }
// Invoke for case where call is in the same context as the server object // (This special static method is used for AsyncDelegate-s ... this is called // directly from the EE) private static void Invoke(Object NotUsed, ref MessageData msgData) { Message m = new Message(); m.InitFields(msgData); Object thisPtr = m.GetThisPtr(); Delegate d; if ((d = thisPtr as Delegate) != null) { RemotingProxy rp = (RemotingProxy) RemotingServices.GetRealProxy(d.Target); if (rp != null) { rp.InternalInvoke(m, true, m.GetCallType()); } else { int callType = m.GetCallType(); AsyncResult ar; switch (callType) { case Message.BeginAsync: case Message.BeginAsync | Message.OneWay: // pick up call context from the thread m.Properties[Message.CallContextKey] = CallContext.GetLogicalCallContext().Clone(); ar = new AsyncResult(m); AgileAsyncWorkerItem workItem = new AgileAsyncWorkerItem( m, ((callType & Message.OneWay) != 0) ? null : ar, d.Target); ThreadPool.QueueUserWorkItem( new WaitCallback( AgileAsyncWorkerItem.ThreadPoolCallBack), workItem); if ((callType & Message.OneWay) != 0) { ar.SyncProcessMessage(null); } m.PropagateOutParameters(null, ar); break; case (Message.EndAsync | Message.OneWay): return; case Message.EndAsync: // This will also merge back the call context // onto the thread that called EndAsync RealProxy.EndInvokeHelper(m, false); break; default: BCLDebug.Assert( false, "Should never be here. Sync delegate code for agile object ended up in remoting"); break; } } } else { // Static invoke called with incorrect this pointer ... throw new RemotingException( Environment.GetResourceString( "Remoting_Default")); } }
private void PrivateInvoke(ref MessageData msgData, int type) { IMessage reqMsg = null; CallType type2 = (CallType) type; IMessage retMsg = null; int msgFlags = -1; RemotingProxy proxy = null; if (CallType.MethodCall == type2) { Message message3 = new Message(); message3.InitFields(msgData); reqMsg = message3; msgFlags = message3.GetCallType(); } else if (CallType.ConstructorCall == type2) { msgFlags = 0; proxy = this as RemotingProxy; ConstructorCallMessage ccm = null; bool flag = false; if (!this.IsRemotingProxy()) { ccm = new ConstructorCallMessage(null, null, null, (RuntimeType) this.GetProxiedType()); } else { ccm = proxy.ConstructorMessage; Identity identityObject = proxy.IdentityObject; if (identityObject != null) { flag = identityObject.IsWellKnown(); } } if ((ccm == null) || flag) { ccm = new ConstructorCallMessage(null, null, null, (RuntimeType) this.GetProxiedType()); ccm.SetFrame(msgData); reqMsg = ccm; if (flag) { proxy.ConstructorMessage = null; if (ccm.ArgCount != 0) { throw new RemotingException(Environment.GetResourceString("Remoting_Activation_WellKnownCTOR")); } } retMsg = new ConstructorReturnMessage((MarshalByRefObject) this.GetTransparentProxy(), null, 0, null, ccm); } else { ccm.SetFrame(msgData); reqMsg = ccm; } } ChannelServices.IncrementRemoteCalls(); if (!this.IsRemotingProxy() && ((msgFlags & 2) == 2)) { Message message5 = reqMsg as Message; retMsg = EndInvokeHelper(message5, true); } if (retMsg == null) { LogicalCallContext cctx = null; Thread currentThread = Thread.CurrentThread; cctx = currentThread.GetLogicalCallContext(); this.SetCallContextInMessage(reqMsg, msgFlags, cctx); cctx.PropagateOutgoingHeadersToMessage(reqMsg); retMsg = this.Invoke(reqMsg); this.ReturnCallContextToThread(currentThread, retMsg, msgFlags, cctx); CallContext.GetLogicalCallContext().PropagateIncomingHeadersToCallContext(retMsg); } if (!this.IsRemotingProxy() && ((msgFlags & 1) == 1)) { Message m = reqMsg as Message; AsyncResult ret = new AsyncResult(m); ret.SyncProcessMessage(retMsg); retMsg = new ReturnMessage(ret, null, 0, null, m); } HandleReturnMessage(reqMsg, retMsg); if (CallType.ConstructorCall == type2) { MarshalByRefObject obj2 = null; IConstructionReturnMessage message7 = retMsg as IConstructionReturnMessage; if (message7 == null) { throw new RemotingException(Environment.GetResourceString("Remoting_Proxy_BadReturnTypeForActivation")); } ConstructorReturnMessage message8 = message7 as ConstructorReturnMessage; if (message8 != null) { obj2 = (MarshalByRefObject) message8.GetObject(); if (obj2 == null) { throw new RemotingException(Environment.GetResourceString("Remoting_Activation_NullReturnValue")); } } else { obj2 = (MarshalByRefObject) RemotingServices.InternalUnmarshal((ObjRef) message7.ReturnValue, this.GetTransparentProxy(), true); if (obj2 == null) { throw new RemotingException(Environment.GetResourceString("Remoting_Activation_NullFromInternalUnmarshal")); } } if (obj2 != ((MarshalByRefObject) this.GetTransparentProxy())) { throw new RemotingException(Environment.GetResourceString("Remoting_Activation_InconsistentState")); } if (this.IsRemotingProxy()) { proxy.ConstructorMessage = null; } } }