We need you! We're working hard on the next version of Developer Fusion -
Let us know what you think we should be up to!
- namespace System.Runtime.Remoting.Channels
- {
- using System;
- using System.Collections;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Runtime.Remoting;
- using System.Runtime.Remoting.Messaging;
- using System.Runtime.Remoting.Contexts;
- using System.Runtime.Serialization;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Security;
- using System.Security.Permissions;
- using System.Security.Policy;
- using System.Security.Principal;
- using System.Text;
- using System.Threading;
- using System.Runtime.ConstrainedExecution;
-
-
-
- [Serializable()]
- internal class CrossAppDomainChannel : IChannel, IChannelSender, IChannelReceiver
- {
- private const string _channelName = "XAPPDMN";
- private const string _channelURI = "XAPPDMN_URI";
-
-
- private static CrossAppDomainChannel gAppDomainChannel {
- get { return Thread.GetDomain().RemotingData.ChannelServicesData.xadmessageSink; }
- set { Thread.GetDomain().RemotingData.ChannelServicesData.xadmessageSink = value; }
- }
- private static object staticSyncObject = new object();
- private static PermissionSet s_fullTrust = new PermissionSet(PermissionState.Unrestricted);
-
- static internal CrossAppDomainChannel AppDomainChannel {
- get {
- if (gAppDomainChannel == null) {
- CrossAppDomainChannel tmpChnl = new CrossAppDomainChannel();
-
- lock (staticSyncObject) {
- if (gAppDomainChannel == null) {
- gAppDomainChannel = tmpChnl;
- }
- }
- }
- return gAppDomainChannel;
-
- }
- }
-
- static internal void RegisterChannel()
- {
- CrossAppDomainChannel adc = CrossAppDomainChannel.AppDomainChannel;
- ChannelServices.RegisterChannelInternal((IChannel)adc, false);
- }
-
-
-
-
- public virtual string ChannelName {
- get { return _channelName; }
- }
-
- public virtual string ChannelURI {
- get { return _channelURI; }
- }
-
- public virtual int ChannelPriority {
- get { return 100; }
- }
-
- public string Parse(string url, out string objectURI)
- {
- objectURI = url;
- return null;
- }
-
- public virtual object ChannelData {
- get { return new CrossAppDomainData(Context.DefaultContext.InternalContextID, Thread.GetDomain().GetId(), Identity.ProcessGuid); }
- }
-
-
- public virtual IMessageSink CreateMessageSink(string url, object data, out string objectURI)
- {
-
- objectURI = null;
- IMessageSink sink = null;
-
- if ((null != url) && (data == null)) {
- if (url.StartsWith(_channelName, StringComparison.Ordinal)) {
- throw new RemotingException(Environment.GetResourceString("Remoting_AppDomains_NYI"));
- }
- }
- else {
- Message.DebugOut("XAPPDOMAIN::Creating sink for data \n");
- CrossAppDomainData xadData = data as CrossAppDomainData;
- if (null != xadData) {
- if (xadData.ProcessGuid.Equals(Identity.ProcessGuid)) {
- sink = CrossAppDomainSink.FindOrCreateSink(xadData);
- }
- }
- }
- return sink;
- }
-
- public virtual string[] GetUrlsForUri(string objectURI)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_Method"));
- }
-
- public virtual void StartListening(object data)
- {
-
- }
-
- public virtual void StopListening(object data)
- {
-
- }
- }
-
- [Serializable()]
- internal class CrossAppDomainData
- {
- object _ContextID = 0;
-
- int _DomainID;
-
- string _processGuid;
-
- internal virtual IntPtr ContextID {
- get {
- #if WIN32
- return new IntPtr((int)_ContextID);
- #else
- return new IntPtr((long)_ContextID);
- #endif
- }
- }
- internal virtual int DomainID {
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- get { return _DomainID; }
- }
-
- internal virtual string ProcessGuid {
- get { return _processGuid; }
- }
-
- internal CrossAppDomainData(IntPtr ctxId, int domainID, string processGuid)
- {
- _DomainID = domainID;
- _processGuid = processGuid;
- #if WIN32
- _ContextID = ctxId.ToInt32();
- #else
- _ContextID = ctxId.ToInt64();
-
- #endif
- }
-
- internal bool IsFromThisProcess()
- {
- return Identity.ProcessGuid.Equals(_processGuid);
- }
-
- internal bool IsFromThisAppDomain()
- {
- return IsFromThisProcess() && (Thread.GetDomain().GetId() == _DomainID);
- }
- }
-
-
-
- internal class CrossAppDomainSink : InternalSink, IMessageSink
- {
- internal const int GROW_BY = 8;
- static internal int[] _sinkKeys;
- static internal CrossAppDomainSink[] _sinks;
-
- internal const string LCC_DATA_KEY = "__xADCall";
-
- private static object staticSyncObject = new object();
- private static InternalCrossContextDelegate s_xctxDel = new InternalCrossContextDelegate(DoTransitionDispatchCallback);
-
-
-
- internal CrossAppDomainData _xadData;
-
- internal CrossAppDomainSink(CrossAppDomainData xadData)
- {
-
-
-
-
-
-
-
-
-
-
-
-
- _xadData = xadData;
- }
-
-
- static internal void GrowArrays(int oldSize)
- {
- if (_sinks == null) {
- _sinks = new CrossAppDomainSink[GROW_BY];
- _sinkKeys = new int[GROW_BY];
- }
- else {
- CrossAppDomainSink[] tmpSinks = new CrossAppDomainSink[_sinks.Length + GROW_BY];
- int[] tmpKeys = new int[_sinkKeys.Length + GROW_BY];
- Array.Copy(_sinks, tmpSinks, _sinks.Length);
- Array.Copy(_sinkKeys, tmpKeys, _sinkKeys.Length);
- _sinks = tmpSinks;
- _sinkKeys = tmpKeys;
- }
- }
- static internal CrossAppDomainSink FindOrCreateSink(CrossAppDomainData xadData)
- {
-
-
-
-
-
- lock (staticSyncObject) {
-
- int key = xadData.DomainID;
- if (_sinks == null) {
- GrowArrays(0);
- }
- int i = 0;
- while (_sinks[i] != null) {
- if (_sinkKeys[i] == key) {
- return _sinks[i];
- }
- i++;
- if (i == _sinks.Length) {
-
- GrowArrays(i);
- break;
- }
- }
-
-
- _sinks[i] = new CrossAppDomainSink(xadData);
- _sinkKeys[i] = key;
- return _sinks[i];
- }
- }
-
- static internal void DomainUnloaded(Int32 domainID)
- {
- int key = domainID;
- lock (staticSyncObject) {
- if (_sinks == null) {
- return;
- }
-
- int i = 0;
- int remove = -1;
- while (_sinks[i] != null) {
- if (_sinkKeys[i] == key) {
- BCLDebug.Assert(remove == -1, "multiple sinks?");
- remove = i;
- }
- i++;
- if (i == _sinks.Length) {
- break;
- }
- }
-
- if (remove == -1)
-
- return;
-
-
-
-
- BCLDebug.Assert(remove != -1, "Bad domainId for unload?");
- _sinkKeys[remove] = _sinkKeys[i - 1];
- _sinks[remove] = _sinks[i - 1];
- _sinkKeys[i - 1] = 0;
- _sinks[i - 1] = null;
- }
-
- }
-
-
- static internal byte[] DoDispatch(byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm, out SmuggledMethodReturnMessage smuggledMrm)
- {
-
-
- IMessage desReqMsg = null;
-
- if (smuggledMcm != null) {
- ArrayList deserializedArgs = smuggledMcm.FixupForNewAppDomain();
- desReqMsg = new MethodCall(smuggledMcm, deserializedArgs);
- }
- else {
- MemoryStream reqStm = new MemoryStream(reqStmBuff);
- desReqMsg = CrossAppDomainSerializer.DeserializeMessage(reqStm);
- }
-
- LogicalCallContext lcc = CallContext.GetLogicalCallContext();
- lcc.SetData(LCC_DATA_KEY, true);
-
-
- IMessage retMsg = ChannelServices.SyncDispatchMessage(desReqMsg);
- lcc.FreeNamedDataSlot(LCC_DATA_KEY);
-
- smuggledMrm = SmuggledMethodReturnMessage.SmuggleIfPossible(retMsg);
- if (smuggledMrm != null) {
- return null;
- }
- else {
- if (retMsg != null) {
-
-
-
- LogicalCallContext callCtx = (LogicalCallContext)retMsg.Properties[Message.CallContextKey];
- if (callCtx != null) {
- if (callCtx.Principal != null)
- callCtx.Principal = null;
- }
-
- return CrossAppDomainSerializer.SerializeMessage(retMsg).GetBuffer();
- }
-
-
- return null;
- }
- }
-
- static internal object DoTransitionDispatchCallback(object[] args)
- {
- byte[] reqStmBuff = (byte[])args[0];
- SmuggledMethodCallMessage smuggledMcm = (SmuggledMethodCallMessage)args[1];
- SmuggledMethodReturnMessage smuggledMrm = null;
- byte[] retBuff = null;
-
- try {
- Message.DebugOut("#### : changed to Server Domain :: " + (Thread.CurrentContext.InternalContextID).ToString("X"));
-
- retBuff = DoDispatch(reqStmBuff, smuggledMcm, out smuggledMrm);
- }
- catch (Exception e) {
-
-
-
-
-
-
-
-
-
- IMessage retMsg = new ReturnMessage(e, new ErrorMessage());
-
- retBuff = CrossAppDomainSerializer.SerializeMessage(retMsg).GetBuffer();
- retMsg = null;
- }
-
- args[2] = smuggledMrm;
-
- return retBuff;
- }
-
- internal byte[] DoTransitionDispatch(byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm, out SmuggledMethodReturnMessage smuggledMrm)
- {
- byte[] retBuff = null;
-
- object[] args = new object[] {reqStmBuff, smuggledMcm, null};
-
- retBuff = (byte[])Thread.CurrentThread.InternalCrossContextCallback(null, _xadData.ContextID, _xadData.DomainID, s_xctxDel, args);
-
- Message.DebugOut("#### : changed back to Client Domain " + (Thread.CurrentContext.InternalContextID).ToString("X"));
-
- smuggledMrm = (SmuggledMethodReturnMessage)args[2];
-
-
- return retBuff;
- }
-
- public virtual IMessage SyncProcessMessage(IMessage reqMsg)
- {
- Message.DebugOut("\n::::::::::::::::::::::::: CrossAppDomain Channel: Sync call starting");
- IMessage errMsg = InternalSink.ValidateMessage(reqMsg);
- if (errMsg != null) {
- return errMsg;
- }
-
-
-
-
- IPrincipal currentPrincipal = null;
-
-
- IMessage desRetMsg = null;
-
- try {
- IMethodCallMessage mcmReqMsg = reqMsg as IMethodCallMessage;
- if (mcmReqMsg != null) {
- LogicalCallContext lcc = mcmReqMsg.LogicalCallContext;
- if (lcc != null) {
-
- currentPrincipal = lcc.RemovePrincipalIfNotSerializable();
- }
- }
-
- MemoryStream reqStm = null;
- SmuggledMethodCallMessage smuggledMcm = SmuggledMethodCallMessage.SmuggleIfPossible(reqMsg);
-
- if (smuggledMcm == null) {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- reqStm = CrossAppDomainSerializer.SerializeMessage(reqMsg);
- }
-
-
-
- LogicalCallContext oldCallCtx = CallContext.SetLogicalCallContext(null);
-
-
- MemoryStream retStm = null;
- byte[] responseBytes = null;
- SmuggledMethodReturnMessage smuggledMrm;
-
- try {
- if (smuggledMcm != null)
- responseBytes = DoTransitionDispatch(null, smuggledMcm, out smuggledMrm);
- else
- responseBytes = DoTransitionDispatch(reqStm.GetBuffer(), null, out smuggledMrm);
- }
- finally {
- CallContext.SetLogicalCallContext(oldCallCtx);
- }
-
- if (smuggledMrm != null) {
- ArrayList deserializedArgs = smuggledMrm.FixupForNewAppDomain();
- desRetMsg = new MethodResponse((IMethodCallMessage)reqMsg, smuggledMrm, deserializedArgs);
- }
- else {
- if (responseBytes != null) {
- retStm = new MemoryStream(responseBytes);
-
- Message.DebugOut("::::::::::::::::::::::::::: CrossAppDomain Channel: Sync call returning!!\n");
-
- desRetMsg = CrossAppDomainSerializer.DeserializeMessage(retStm, reqMsg as IMethodCallMessage);
- }
- }
- }
- catch (Exception e) {
- Message.DebugOut("Arrgh.. XAppDomainSink::throwing exception " + e + "\n");
- try {
- desRetMsg = new ReturnMessage(e, (reqMsg as IMethodCallMessage));
- }
- catch (Exception) {
-
- }
- }
-
-
- if (currentPrincipal != null) {
- IMethodReturnMessage mrmRetMsg = desRetMsg as IMethodReturnMessage;
- if (mrmRetMsg != null) {
- LogicalCallContext lcc = mrmRetMsg.LogicalCallContext;
- lcc.Principal = currentPrincipal;
- }
- }
-
- return desRetMsg;
- }
-
- public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink)
- {
-
-
-
-
- ADAsyncWorkItem workItem = new ADAsyncWorkItem(reqMsg, (IMessageSink)this, replySink);
-
- WaitCallback threadFunc = new WaitCallback(workItem.FinishAsyncWork);
- ThreadPool.QueueUserWorkItem(threadFunc);
-
- return null;
- }
-
- public IMessageSink NextSink {
- get { return null; }
- }
-
- }
-
-
- internal class ADAsyncWorkItem
- {
-
- private IMessageSink _replySink;
-
-
- private IMessageSink _nextSink;
-
- private LogicalCallContext _callCtx;
-
-
- private IMessage _reqMsg;
-
- internal ADAsyncWorkItem(IMessage reqMsg, IMessageSink nextSink, IMessageSink replySink)
- {
- _reqMsg = reqMsg;
- _nextSink = nextSink;
- _replySink = replySink;
- _callCtx = CallContext.GetLogicalCallContext();
- }
-
-
- internal virtual void FinishAsyncWork(object stateIgnored)
- {
-
-
- LogicalCallContext threadPoolCallCtx = CallContext.SetLogicalCallContext(_callCtx);
-
- IMessage retMsg = _nextSink.SyncProcessMessage(_reqMsg);
-
-
-
- if (_replySink != null) {
- _replySink.SyncProcessMessage(retMsg);
- }
- CallContext.SetLogicalCallContext(threadPoolCallCtx);
- }
- }
-
-
- static internal class CrossAppDomainSerializer
- {
- static internal MemoryStream SerializeMessage(IMessage msg)
- {
- MemoryStream stm = new MemoryStream();
- RemotingSurrogateSelector ss = new RemotingSurrogateSelector();
- BinaryFormatter fmt = new BinaryFormatter();
- fmt.SurrogateSelector = ss;
- fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
- fmt.Serialize(stm, msg, null, false);
-
-
- stm.Position = 0;
-
- return stm;
- }
-
-
- static internal MemoryStream SerializeMessageParts(ArrayList argsToSerialize)
- {
- MemoryStream stm = new MemoryStream();
-
- BinaryFormatter fmt = new BinaryFormatter();
- RemotingSurrogateSelector ss = new RemotingSurrogateSelector();
- fmt.SurrogateSelector = ss;
- fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
- fmt.Serialize(stm, argsToSerialize, null, false);
-
- stm.Position = 0;
- return stm;
- }
-
-
- static internal void SerializeObject(object obj, MemoryStream stm)
- {
- BinaryFormatter fmt = new BinaryFormatter();
- RemotingSurrogateSelector ss = new RemotingSurrogateSelector();
- fmt.SurrogateSelector = ss;
- fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
- fmt.Serialize(stm, obj, null, false);
- }
-
-
- static internal MemoryStream SerializeObject(object obj)
- {
- MemoryStream stm = new MemoryStream();
-
- SerializeObject(obj, stm);
-
- stm.Position = 0;
- return stm;
- }
-
-
- static internal IMessage DeserializeMessage(MemoryStream stm)
- {
- return DeserializeMessage(stm, null);
- }
-
- static internal IMessage DeserializeMessage(MemoryStream stm, IMethodCallMessage reqMsg)
- {
- if (stm == null)
- throw new ArgumentNullException("stm");
-
- stm.Position = 0;
- BinaryFormatter fmt = new BinaryFormatter();
- fmt.SurrogateSelector = null;
- fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
-
- return (IMessage)fmt.Deserialize(stm, null, false, true, reqMsg);
- }
-
-
- static internal ArrayList DeserializeMessageParts(MemoryStream stm)
- {
- return (ArrayList)DeserializeObject(stm);
-
- }
-
-
- static internal object DeserializeObject(MemoryStream stm)
- {
- stm.Position = 0;
-
- BinaryFormatter fmt = new BinaryFormatter();
- fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
- return fmt.Deserialize(stm, null, false, true, null);
- }
-
- }
-
- }