The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting.Channels \ CrossAppDomainData

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. //
  16. // Remoting Infrastructure Sink for making calls across context
  17. // boundaries.
  18. //
  19. namespace System.Runtime.Remoting.Channels
  20. {
  21.     using System;
  22.     using System.Collections;
  23.     using System.IO;
  24.     using System.Runtime.InteropServices;
  25.     using System.Runtime.Remoting;
  26.     using System.Runtime.Remoting.Messaging;
  27.     using System.Runtime.Remoting.Contexts;
  28.     using System.Runtime.Serialization;
  29.     using System.Runtime.Serialization.Formatters.Binary;
  30.     using System.Security;
  31.     using System.Security.Permissions;
  32.     using System.Security.Policy;
  33.     using System.Security.Principal;
  34.     using System.Text;
  35.     using System.Threading;
  36.     using System.Runtime.ConstrainedExecution;
  37.    
  38.    
  39.    
  40.     [Serializable()]
  41.     internal class CrossAppDomainChannel : IChannel, IChannelSender, IChannelReceiver
  42.     {
  43.         private const string _channelName = "XAPPDMN";
  44.         private const string _channelURI = "XAPPDMN_URI";
  45.        
  46.        
  47.         private static CrossAppDomainChannel gAppDomainChannel {
  48.             get { return Thread.GetDomain().RemotingData.ChannelServicesData.xadmessageSink; }
  49.             set { Thread.GetDomain().RemotingData.ChannelServicesData.xadmessageSink = value; }
  50.         }
  51.         private static object staticSyncObject = new object();
  52.         private static PermissionSet s_fullTrust = new PermissionSet(PermissionState.Unrestricted);
  53.        
  54.         static internal CrossAppDomainChannel AppDomainChannel {
  55.             get {
  56.                 if (gAppDomainChannel == null) {
  57.                     CrossAppDomainChannel tmpChnl = new CrossAppDomainChannel();
  58.                    
  59.                     lock (staticSyncObject) {
  60.                         if (gAppDomainChannel == null) {
  61.                             gAppDomainChannel = tmpChnl;
  62.                         }
  63.                     }
  64.                 }
  65.                 return gAppDomainChannel;
  66.                
  67.             }
  68.         }
  69.        
  70.         static internal void RegisterChannel()
  71.         {
  72.             CrossAppDomainChannel adc = CrossAppDomainChannel.AppDomainChannel;
  73.                 /*ensureSecurity*/            ChannelServices.RegisterChannelInternal((IChannel)adc, false);
  74.         }
  75.        
  76.         //
  77.         // IChannel Methods
  78.         //
  79.         public virtual string ChannelName {
  80.             get { return _channelName; }
  81.         }
  82.        
  83.         public virtual string ChannelURI {
  84.             get { return _channelURI; }
  85.         }
  86.        
  87.         public virtual int ChannelPriority {
  88.             get { return 100; }
  89.         }
  90.        
  91.         public string Parse(string url, out string objectURI)
  92.         {
  93.             objectURI = url;
  94.             return null;
  95.         }
  96.        
  97.         public virtual object ChannelData {
  98.             get { return new CrossAppDomainData(Context.DefaultContext.InternalContextID, Thread.GetDomain().GetId(), Identity.ProcessGuid); }
  99.         }
  100.        
  101.        
  102.         public virtual IMessageSink CreateMessageSink(string url, object data, out string objectURI)
  103.         {
  104.             // Set the out parameters
  105.             objectURI = null;
  106.             IMessageSink sink = null;
  107.            
  108.             if ((null != url) && (data == null)) {
  109.                 if (url.StartsWith(_channelName, StringComparison.Ordinal)) {
  110.                     throw new RemotingException(Environment.GetResourceString("Remoting_AppDomains_NYI"));
  111.                 }
  112.             }
  113.             else {
  114.                 Message.DebugOut("XAPPDOMAIN::Creating sink for data \n");
  115.                 CrossAppDomainData xadData = data as CrossAppDomainData;
  116.                 if (null != xadData) {
  117.                     if (xadData.ProcessGuid.Equals(Identity.ProcessGuid)) {
  118.                         sink = CrossAppDomainSink.FindOrCreateSink(xadData);
  119.                     }
  120.                 }
  121.             }
  122.             return sink;
  123.         }
  124.        
  125.         public virtual string[] GetUrlsForUri(string objectURI)
  126.         {
  127.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_Method"));
  128.         }
  129.        
  130.         public virtual void StartListening(object data)
  131.         {
  132.            
  133.         }
  134.        
  135.         public virtual void StopListening(object data)
  136.         {
  137.            
  138.         }
  139.     }
  140.    
  141.     [Serializable()]
  142.     internal class CrossAppDomainData
  143.     {
  144.         object _ContextID = 0;
  145.         // This is for backward compatibility
  146.         int _DomainID;
  147.         // server appDomain ID
  148.         string _processGuid;
  149.         // idGuid for the process (shared static)
  150.         internal virtual IntPtr ContextID {
  151.             get {
  152.                 #if WIN32
  153.                 return new IntPtr((int)_ContextID);
  154.                 #else
  155.                 return new IntPtr((long)_ContextID);
  156.                 #endif
  157.             }
  158.         }
  159.         internal virtual int DomainID {
  160.             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  161.             get { return _DomainID; }
  162.         }
  163.        
  164.         internal virtual string ProcessGuid {
  165.             get { return _processGuid; }
  166.         }
  167.        
  168.         internal CrossAppDomainData(IntPtr ctxId, int domainID, string processGuid)
  169.         {
  170.             _DomainID = domainID;
  171.             _processGuid = processGuid;
  172.             #if WIN32
  173.             _ContextID = ctxId.ToInt32();
  174.             #else
  175.             _ContextID = ctxId.ToInt64();
  176.             // This would have never worked anyway
  177.             #endif
  178.         }
  179.        
  180.         internal bool IsFromThisProcess()
  181.         {
  182.             return Identity.ProcessGuid.Equals(_processGuid);
  183.         }
  184.        
  185.         internal bool IsFromThisAppDomain()
  186.         {
  187.             return IsFromThisProcess() && (Thread.GetDomain().GetId() == _DomainID);
  188.         }
  189.     }
  190.     // Implements the Message Sink provided by the X-AppDomain channel.
  191.     // We try to use one instance of the sink to make calls to all remote
  192.     // objects in another AppDomain from one AppDomain.
  193.     internal class CrossAppDomainSink : InternalSink, IMessageSink
  194.     {
  195.         internal const int GROW_BY = 8;
  196.         static internal int[] _sinkKeys;
  197.         static internal CrossAppDomainSink[] _sinks;
  198.        
  199.         internal const string LCC_DATA_KEY = "__xADCall";
  200.        
  201.         private static object staticSyncObject = new object();
  202.         private static InternalCrossContextDelegate s_xctxDel = new InternalCrossContextDelegate(DoTransitionDispatchCallback);
  203.        
  204.         // each sink stores the default ContextID of the server side domain
  205.         // and the domain ID for the domain
  206.         internal CrossAppDomainData _xadData;
  207.        
  208.         internal CrossAppDomainSink(CrossAppDomainData xadData)
  209.         {
  210.             //
  211.             // WARNING: xadData.ContextID may not be valid at this point. Because
  212.             // CrossAppDomainData._ContextID is an IntPtr and IntPtrs are
  213.             // value types, the deserializer has to wait until the very
  214.             // end of deserialization to fixup value types. However, when
  215.             // we unmarshal objects, we need to setup the x-AD sink and
  216.             // initialize it with this data. Fortunately, that data won't
  217.             // be consumed until deserialization is complete, so we just
  218.             // need to take care not to read _ContextID in the constructor.
  219.             // The xadData object ref will be finalized by the time we need
  220.             // to consume its contents and everything should work properly.
  221.             //
  222.             _xadData = xadData;
  223.         }
  224.        
  225.         // Note: this should be called from within a synch-block
  226.         static internal void GrowArrays(int oldSize)
  227.         {
  228.             if (_sinks == null) {
  229.                 _sinks = new CrossAppDomainSink[GROW_BY];
  230.                 _sinkKeys = new int[GROW_BY];
  231.             }
  232.             else {
  233.                 CrossAppDomainSink[] tmpSinks = new CrossAppDomainSink[_sinks.Length + GROW_BY];
  234.                 int[] tmpKeys = new int[_sinkKeys.Length + GROW_BY];
  235.                 Array.Copy(_sinks, tmpSinks, _sinks.Length);
  236.                 Array.Copy(_sinkKeys, tmpKeys, _sinkKeys.Length);
  237.                 _sinks = tmpSinks;
  238.                 _sinkKeys = tmpKeys;
  239.             }
  240.         }
  241.         static internal CrossAppDomainSink FindOrCreateSink(CrossAppDomainData xadData)
  242.         {
  243.             //
  244.             // WARNING: Do not read any value type member of xadData in this method!!
  245.             // xadData is not completely deserialized at this point. See
  246.             // warning in CrossAppDomainSink::.ctor above
  247.             //
  248.             lock (staticSyncObject) {
  249.                 // Note: keep this in sync with DomainUnloaded below
  250.                 int key = xadData.DomainID;
  251.                 if (_sinks == null) {
  252.                     GrowArrays(0);
  253.                 }
  254.                 int i = 0;
  255.                 while (_sinks[i] != null) {
  256.                     if (_sinkKeys[i] == key) {
  257.                         return _sinks[i];
  258.                     }
  259.                     i++;
  260.                     if (i == _sinks.Length) {
  261.                         // could not find a sink, also need to Grow the array.
  262.                         GrowArrays(i);
  263.                         break;
  264.                     }
  265.                 }
  266.                 // At this point we need to create a new sink and cache
  267.                 // it at location "i"
  268.                 _sinks[i] = new CrossAppDomainSink(xadData);
  269.                 _sinkKeys[i] = key;
  270.                 return _sinks[i];
  271.             }
  272.         }
  273.        
  274.         static internal void DomainUnloaded(Int32 domainID)
  275.         {
  276.             int key = domainID;
  277.             lock (staticSyncObject) {
  278.                 if (_sinks == null) {
  279.                     return;
  280.                 }
  281.                 // Note: keep this in sync with FindOrCreateSink
  282.                 int i = 0;
  283.                 int remove = -1;
  284.                 while (_sinks[i] != null) {
  285.                     if (_sinkKeys[i] == key) {
  286.                         BCLDebug.Assert(remove == -1, "multiple sinks?");
  287.                         remove = i;
  288.                     }
  289.                     i++;
  290.                     if (i == _sinks.Length) {
  291.                         break;
  292.                     }
  293.                 }
  294.                
  295.                 if (remove == -1)
  296.                     //hasn't been initialized yet
  297.                     return;
  298.                
  299.                 // The sink to remove is at index 'remove'
  300.                 // We will move the last non-null entry to this location
  301.                
  302.                 BCLDebug.Assert(remove != -1, "Bad domainId for unload?");
  303.                 _sinkKeys[remove] = _sinkKeys[i - 1];
  304.                 _sinks[remove] = _sinks[i - 1];
  305.                 _sinkKeys[i - 1] = 0;
  306.                 _sinks[i - 1] = null;
  307.             }
  308.            
  309.         }
  310.        
  311.        
  312.         static internal byte[] DoDispatch(byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm, out SmuggledMethodReturnMessage smuggledMrm)
  313.         {
  314.             //*********************** DE-SERIALIZE REQ-MSG ********************
  315.            
  316.             IMessage desReqMsg = null;
  317.            
  318.             if (smuggledMcm != null) {
  319.                 ArrayList deserializedArgs = smuggledMcm.FixupForNewAppDomain();
  320.                 desReqMsg = new MethodCall(smuggledMcm, deserializedArgs);
  321.             }
  322.             else {
  323.                 MemoryStream reqStm = new MemoryStream(reqStmBuff);
  324.                 desReqMsg = CrossAppDomainSerializer.DeserializeMessage(reqStm);
  325.             }
  326.            
  327.             LogicalCallContext lcc = CallContext.GetLogicalCallContext();
  328.             lcc.SetData(LCC_DATA_KEY, true);
  329.             // now we can delegate to the DispatchMessage to do the rest
  330.            
  331.             IMessage retMsg = ChannelServices.SyncDispatchMessage(desReqMsg);
  332.             lcc.FreeNamedDataSlot(LCC_DATA_KEY);
  333.            
  334.             smuggledMrm = SmuggledMethodReturnMessage.SmuggleIfPossible(retMsg);
  335.             if (smuggledMrm != null) {
  336.                 return null;
  337.             }
  338.             else {
  339.                 if (retMsg != null) {
  340.                     // Null out the principal since we won't use it on the other side.
  341.                     // This is handled inside of SmuggleIfPossible for method call
  342.                     // messages.
  343.                     LogicalCallContext callCtx = (LogicalCallContext)retMsg.Properties[Message.CallContextKey];
  344.                     if (callCtx != null) {
  345.                         if (callCtx.Principal != null)
  346.                             callCtx.Principal = null;
  347.                     }
  348.                    
  349.                     return CrossAppDomainSerializer.SerializeMessage(retMsg).GetBuffer();
  350.                 }
  351.                
  352.                 //*********************** SERIALIZE RET-MSG ********************
  353.                 return null;
  354.             }
  355.         }
  356.         // DoDispatch
  357.         static internal object DoTransitionDispatchCallback(object[] args)
  358.         {
  359.             byte[] reqStmBuff = (byte[])args[0];
  360.             SmuggledMethodCallMessage smuggledMcm = (SmuggledMethodCallMessage)args[1];
  361.             SmuggledMethodReturnMessage smuggledMrm = null;
  362.             byte[] retBuff = null;
  363.            
  364.             try {
  365.                 Message.DebugOut("#### : changed to Server Domain :: " + (Thread.CurrentContext.InternalContextID).ToString("X"));
  366.                
  367.                 retBuff = DoDispatch(reqStmBuff, smuggledMcm, out smuggledMrm);
  368.             }
  369.             catch (Exception e) {
  370.                 // This will catch exceptions thrown by the infrastructure,
  371.                 // Serialization/Deserialization etc
  372.                 // Those thrown by the server are already taken care of
  373.                 // and encoded in the retMsg .. so we don't come here for
  374.                 // that case.
  375.                
  376.                 // We are in another appDomain, so we can't simply throw
  377.                 // the exception object across. The following marshals it
  378.                 // into a serialized return message.
  379.                 IMessage retMsg = new ReturnMessage(e, new ErrorMessage());
  380.                 //*********************** SERIALIZE RET-MSG ******************
  381.                 retBuff = CrossAppDomainSerializer.SerializeMessage(retMsg).GetBuffer();
  382.                 retMsg = null;
  383.             }
  384.            
  385.             args[2] = smuggledMrm;
  386.            
  387.             return retBuff;
  388.         }
  389.        
  390.         internal byte[] DoTransitionDispatch(byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm, out SmuggledMethodReturnMessage smuggledMrm)
  391.         {
  392.             byte[] retBuff = null;
  393.            
  394.             object[] args = new object[] {reqStmBuff, smuggledMcm, null};
  395.            
  396.             retBuff = (byte[])Thread.CurrentThread.InternalCrossContextCallback(null, _xadData.ContextID, _xadData.DomainID, s_xctxDel, args);
  397.            
  398.             Message.DebugOut("#### : changed back to Client Domain " + (Thread.CurrentContext.InternalContextID).ToString("X"));
  399.            
  400.             smuggledMrm = (SmuggledMethodReturnMessage)args[2];
  401.            
  402.             // System.Diagnostics.Debugger.Break();
  403.             return retBuff;
  404.         }
  405.         // DoTransitionDispatch
  406.         public virtual IMessage SyncProcessMessage(IMessage reqMsg)
  407.         {
  408.             Message.DebugOut("\n::::::::::::::::::::::::: CrossAppDomain Channel: Sync call starting");
  409.             IMessage errMsg = InternalSink.ValidateMessage(reqMsg);
  410.             if (errMsg != null) {
  411.                 return errMsg;
  412.             }
  413.            
  414.            
  415.             // currentPrincipal is used to save the current principal. It should be
  416.             // restored on the reply message.
  417.             IPrincipal currentPrincipal = null;
  418.            
  419.            
  420.             IMessage desRetMsg = null;
  421.            
  422.             try {
  423.                 IMethodCallMessage mcmReqMsg = reqMsg as IMethodCallMessage;
  424.                 if (mcmReqMsg != null) {
  425.                     LogicalCallContext lcc = mcmReqMsg.LogicalCallContext;
  426.                     if (lcc != null) {
  427.                         // Special case Principal since if might not be serializable
  428.                         currentPrincipal = lcc.RemovePrincipalIfNotSerializable();
  429.                     }
  430.                 }
  431.                
  432.                 MemoryStream reqStm = null;
  433.                 SmuggledMethodCallMessage smuggledMcm = SmuggledMethodCallMessage.SmuggleIfPossible(reqMsg);
  434.                
  435.                 if (smuggledMcm == null) {
  436.                    
  437.                     //*********************** SERIALIZE REQ-MSG ****************
  438.                     // Deserialization of objects requires permissions that users
  439.                     // of remoting are not guaranteed to possess. Since remoting
  440.                     // can guarantee that it's users can't abuse deserialization
  441.                     // (since it won't allow them to pass in raw blobs of
  442.                     // serialized data), it should assert the permissions
  443.                     // necessary before calling the deserialization code. This
  444.                     // will terminate the security stackwalk caused when
  445.                     // serialization checks for the correct permissions at the
  446.                     // remoting stack frame so the check won't continue on to
  447.                     // the user and fail.
  448.                     // We will hold off from doing this for x-process channels
  449.                     // until the big picture of distributed security is finalized.
  450.                    
  451.                     reqStm = CrossAppDomainSerializer.SerializeMessage(reqMsg);
  452.                 }
  453.                
  454.                 // Retrieve calling caller context here, where it is safe from the view
  455.                 // of app domain checking code
  456.                 LogicalCallContext oldCallCtx = CallContext.SetLogicalCallContext(null);
  457.                
  458.                 // Call helper method here, to avoid confusion with stack frames & app domains
  459.                 MemoryStream retStm = null;
  460.                 byte[] responseBytes = null;
  461.                 SmuggledMethodReturnMessage smuggledMrm;
  462.                
  463.                 try {
  464.                     if (smuggledMcm != null)
  465.                         responseBytes = DoTransitionDispatch(null, smuggledMcm, out smuggledMrm);
  466.                     else
  467.                         responseBytes = DoTransitionDispatch(reqStm.GetBuffer(), null, out smuggledMrm);
  468.                 }
  469.                 finally {
  470.                     CallContext.SetLogicalCallContext(oldCallCtx);
  471.                 }
  472.                
  473.                 if (smuggledMrm != null) {
  474.                     ArrayList deserializedArgs = smuggledMrm.FixupForNewAppDomain();
  475.                     desRetMsg = new MethodResponse((IMethodCallMessage)reqMsg, smuggledMrm, deserializedArgs);
  476.                 }
  477.                 else {
  478.                     if (responseBytes != null) {
  479.                         retStm = new MemoryStream(responseBytes);
  480.                        
  481.                         Message.DebugOut("::::::::::::::::::::::::::: CrossAppDomain Channel: Sync call returning!!\n");
  482.                         //*********************** DESERIALIZE RET-MSG **************
  483.                         desRetMsg = CrossAppDomainSerializer.DeserializeMessage(retStm, reqMsg as IMethodCallMessage);
  484.                     }
  485.                 }
  486.             }
  487.             catch (Exception e) {
  488.                 Message.DebugOut("Arrgh.. XAppDomainSink::throwing exception " + e + "\n");
  489.                 try {
  490.                     desRetMsg = new ReturnMessage(e, (reqMsg as IMethodCallMessage));
  491.                 }
  492.                 catch (Exception) {
  493.                     // Fatal Error .. can't do much here
  494.                 }
  495.             }
  496.            
  497.             // restore the principal if necessary.
  498.             if (currentPrincipal != null) {
  499.                 IMethodReturnMessage mrmRetMsg = desRetMsg as IMethodReturnMessage;
  500.                 if (mrmRetMsg != null) {
  501.                     LogicalCallContext lcc = mrmRetMsg.LogicalCallContext;
  502.                     lcc.Principal = currentPrincipal;
  503.                 }
  504.             }
  505.            
  506.             return desRetMsg;
  507.         }
  508.        
  509.         public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink)
  510.         {
  511.             // This is the case where we take care of returning the calling
  512.             // thread asap by using the ThreadPool for completing the call.
  513.            
  514.             // we use a more elaborate WorkItem and delegate the work to the thread pool
  515.                 /* nextSink */            ADAsyncWorkItem workItem = new ADAsyncWorkItem(reqMsg, (IMessageSink)this, replySink);
  516.            
  517.             WaitCallback threadFunc = new WaitCallback(workItem.FinishAsyncWork);
  518.             ThreadPool.QueueUserWorkItem(threadFunc);
  519.            
  520.             return null;
  521.         }
  522.        
  523.         public IMessageSink NextSink {
  524. // We are a terminating sink for this chain
  525.             get { return null; }
  526.         }
  527.        
  528.     }
  529.    
  530. /* package */   
  531.     internal class ADAsyncWorkItem
  532.     {
  533.         // the replySink passed in to us in AsyncProcessMsg
  534.         private IMessageSink _replySink;
  535.        
  536.         // the nextSink we have to call
  537.         private IMessageSink _nextSink;
  538.        
  539.         private LogicalCallContext _callCtx;
  540.        
  541.         // the request msg passed in
  542.         private IMessage _reqMsg;
  543.        
  544.         internal ADAsyncWorkItem(IMessage reqMsg, IMessageSink nextSink, IMessageSink replySink)
  545.         {
  546.             _reqMsg = reqMsg;
  547.             _nextSink = nextSink;
  548.             _replySink = replySink;
  549.             _callCtx = CallContext.GetLogicalCallContext();
  550.         }
  551.        
  552. /* package */       
  553.         internal virtual void FinishAsyncWork(object stateIgnored)
  554.         {
  555.             // install the call context that the calling thread actually had onto
  556.             // the threadPool thread.
  557.             LogicalCallContext threadPoolCallCtx = CallContext.SetLogicalCallContext(_callCtx);
  558.            
  559.             IMessage retMsg = _nextSink.SyncProcessMessage(_reqMsg);
  560.            
  561.             // send the reply back to the replySink we were provided with
  562.             // note: replySink may be null for one-way calls.
  563.             if (_replySink != null) {
  564.                 _replySink.SyncProcessMessage(retMsg);
  565.             }
  566.             CallContext.SetLogicalCallContext(threadPoolCallCtx);
  567.         }
  568.     }
  569.    
  570.    
  571.     static internal class CrossAppDomainSerializer
  572.     {
  573.         static internal MemoryStream SerializeMessage(IMessage msg)
  574.         {
  575.             MemoryStream stm = new MemoryStream();
  576.             RemotingSurrogateSelector ss = new RemotingSurrogateSelector();
  577.             BinaryFormatter fmt = new BinaryFormatter();
  578.             fmt.SurrogateSelector = ss;
  579.             fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
  580.                 /* No Security check */            fmt.Serialize(stm, msg, null, false);
  581.            
  582.             // Reset the stream so that Deserialize happens correctly
  583.             stm.Position = 0;
  584.            
  585.             return stm;
  586.         }
  587.        
  588.        
  589.         static internal MemoryStream SerializeMessageParts(ArrayList argsToSerialize)
  590.         {
  591.             MemoryStream stm = new MemoryStream();
  592.            
  593.             BinaryFormatter fmt = new BinaryFormatter();
  594.             RemotingSurrogateSelector ss = new RemotingSurrogateSelector();
  595.             fmt.SurrogateSelector = ss;
  596.             fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
  597.                 /* No Security check */            fmt.Serialize(stm, argsToSerialize, null, false);
  598.            
  599.             stm.Position = 0;
  600.             return stm;
  601.         }
  602.         // SerializeMessageParts
  603.         // called from MessageSmuggler classes
  604.         static internal void SerializeObject(object obj, MemoryStream stm)
  605.         {
  606.             BinaryFormatter fmt = new BinaryFormatter();
  607.             RemotingSurrogateSelector ss = new RemotingSurrogateSelector();
  608.             fmt.SurrogateSelector = ss;
  609.             fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
  610.                 /* No Security check */            fmt.Serialize(stm, obj, null, false);
  611.         }
  612.         // SerializeMessageParts
  613.         // called from MessageSmuggler classes
  614.         static internal MemoryStream SerializeObject(object obj)
  615.         {
  616.             MemoryStream stm = new MemoryStream();
  617.            
  618.             SerializeObject(obj, stm);
  619.            
  620.             stm.Position = 0;
  621.             return stm;
  622.         }
  623.         // SerializeMessageParts
  624.        
  625.         static internal IMessage DeserializeMessage(MemoryStream stm)
  626.         {
  627.             return DeserializeMessage(stm, null);
  628.         }
  629.        
  630.         static internal IMessage DeserializeMessage(MemoryStream stm, IMethodCallMessage reqMsg)
  631.         {
  632.             if (stm == null)
  633.                 throw new ArgumentNullException("stm");
  634.            
  635.             stm.Position = 0;
  636.             BinaryFormatter fmt = new BinaryFormatter();
  637.             fmt.SurrogateSelector = null;
  638.             fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
  639.            
  640.                 /* No Security check */                /*isCrossAppDomain*/            return (IMessage)fmt.Deserialize(stm, null, false, true, reqMsg);
  641.         }
  642.        
  643.        
  644.         static internal ArrayList DeserializeMessageParts(MemoryStream stm)
  645.         {
  646.             return (ArrayList)DeserializeObject(stm);
  647.            
  648.         }
  649.         // DeserializeMessageParts
  650.        
  651.         static internal object DeserializeObject(MemoryStream stm)
  652.         {
  653.             stm.Position = 0;
  654.            
  655.             BinaryFormatter fmt = new BinaryFormatter();
  656.             fmt.Context = new StreamingContext(StreamingContextStates.CrossAppDomain);
  657.                 /* No Security check */                /*isCrossAppDomain*/            return fmt.Deserialize(stm, null, false, true, null);
  658.         }
  659.         // DeserializeMessageParts
  660.     }
  661.    
  662. }

Developer Fusion