The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting \ ComRedirectionProxy

  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. // File: RedirectionProxy.cs
  16. using System;
  17. using System.Runtime.InteropServices;
  18. using System.Runtime.Remoting.Messaging;
  19. using System.Runtime.Remoting.Proxies;
  20. namespace System.Runtime.Remoting
  21. {
  22.    
  23.     internal class RedirectionProxy : MarshalByRefObject, IMessageSink
  24.     {
  25.         private MarshalByRefObject _proxy;
  26.         private RealProxy _realProxy;
  27.         private Type _serverType;
  28.         private WellKnownObjectMode _objectMode;
  29.        
  30.         internal RedirectionProxy(MarshalByRefObject proxy, Type serverType)
  31.         {
  32.             _proxy = proxy;
  33.             _realProxy = RemotingServices.GetRealProxy(_proxy);
  34.             _serverType = serverType;
  35.             _objectMode = WellKnownObjectMode.Singleton;
  36.         }
  37.         // RedirectionProxy
  38.        
  39.         public WellKnownObjectMode ObjectMode {
  40.             set { _objectMode = value; }
  41.         }
  42.         // ObjectMode
  43.         public virtual IMessage SyncProcessMessage(IMessage msg)
  44.         {
  45.             IMessage replyMsg = null;
  46.            
  47.             try {
  48.                 msg.Properties["__Uri"] = _realProxy.IdentityObject.URI;
  49.                
  50.                 if (_objectMode == WellKnownObjectMode.Singleton) {
  51.                     replyMsg = _realProxy.Invoke(msg);
  52.                 }
  53.                 else {
  54.                     // This is a single call object, so we need to create
  55.                     // a new instance.
  56.                     MarshalByRefObject obj = (MarshalByRefObject)Activator.CreateInstance(_serverType, true);
  57.                     BCLDebug.Assert(RemotingServices.IsTransparentProxy(obj), "expecting a proxy");
  58.                    
  59.                     RealProxy rp = RemotingServices.GetRealProxy(obj);
  60.                     replyMsg = rp.Invoke(msg);
  61.                 }
  62.             }
  63.             catch (Exception e) {
  64.                 replyMsg = new ReturnMessage(e, msg as IMethodCallMessage);
  65.             }
  66.            
  67.             return replyMsg;
  68.         }
  69.         // SyncProcessMessage
  70.        
  71.         public virtual IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
  72.         {
  73.            
  74.             IMessage replyMsg = null;
  75.            
  76.             replyMsg = SyncProcessMessage(msg);
  77.            
  78.             if (replySink != null)
  79.                 replySink.SyncProcessMessage(replyMsg);
  80.            
  81.             return null;
  82.         }
  83.         // AsyncProcessMessage
  84.         public IMessageSink NextSink {
  85.             get { return null; }
  86.         }
  87.        
  88.     }
  89.     // class RedirectionProxy
  90.    
  91.    
  92.     // This is only to be used for wellknown Singleton COM objects.
  93.     internal class ComRedirectionProxy : MarshalByRefObject, IMessageSink
  94.     {
  95.         private MarshalByRefObject _comObject;
  96.         private Type _serverType;
  97.        
  98.         internal ComRedirectionProxy(MarshalByRefObject comObject, Type serverType)
  99.         {
  100.             BCLDebug.Assert(serverType.IsCOMObject, "This must be a COM object type.");
  101.            
  102.             _comObject = comObject;
  103.             _serverType = serverType;
  104.         }
  105.         // ComRedirectionProxy
  106.        
  107.         public virtual IMessage SyncProcessMessage(IMessage msg)
  108.         {
  109.             IMethodCallMessage mcmReqMsg = (IMethodCallMessage)msg;
  110.             IMethodReturnMessage replyMsg = null;
  111.            
  112.             replyMsg = RemotingServices.ExecuteMessage(_comObject, mcmReqMsg);
  113.            
  114.             if (replyMsg != null) {
  115.                 // If an "RPC server not available" (HRESULT=0x800706BA) COM
  116.                 // exception is thrown, we will try to recreate the object once.
  117.                 const int RPC_S_SERVER_UNAVAILABLE = unchecked((int)2147944122u);
  118.                 const int RPC_S_CALL_FAILED_DNE = unchecked((int)2147944127u);
  119.                 COMException comException = replyMsg.Exception as COMException;
  120.                 if ((comException != null) && ((comException._HResult == RPC_S_SERVER_UNAVAILABLE) || (comException._HResult == RPC_S_CALL_FAILED_DNE))) {
  121.                     _comObject = (MarshalByRefObject)Activator.CreateInstance(_serverType, true);
  122.                    
  123.                     replyMsg = RemotingServices.ExecuteMessage(_comObject, mcmReqMsg);
  124.                 }
  125.             }
  126.            
  127.             return replyMsg;
  128.         }
  129.         // SyncProcessMessage
  130.        
  131.         public virtual IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
  132.         {
  133.            
  134.             IMessage replyMsg = null;
  135.            
  136.             replyMsg = SyncProcessMessage(msg);
  137.            
  138.             if (replySink != null)
  139.                 replySink.SyncProcessMessage(replyMsg);
  140.            
  141.             return null;
  142.         }
  143.         // AsyncProcessMessage
  144.         public IMessageSink NextSink {
  145.             get { return null; }
  146.         }
  147.        
  148.     }
  149.     // class ComRedirectionProxy
  150.    
  151. }
  152. // namespace System.Runtime.Remoting

Developer Fusion