The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting.Messaging \ MRMWrapperDictionary

  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. **
  17. ** File:    Message.cs
  18. **
  19. **
  20. ** Purpose: Defines the message object created by the transparent
  21. **          proxy and used by the message sinks
  22. **
  23. **
  24. ===========================================================*/
  25. namespace System.Runtime.Remoting.Messaging
  26. {
  27.     using System;
  28.     using System.Collections;
  29.     using System.Threading;
  30.     using System.Runtime.InteropServices;
  31.     using System.Runtime.Remoting;
  32.     using System.Runtime.Remoting.Activation;
  33.     using System.Runtime.Remoting.Contexts;
  34.     using System.Runtime.Remoting.Channels;
  35.     using System.Runtime.Remoting.Metadata;
  36.     using System.Runtime.Remoting.Metadata.W3cXsd2001;
  37.     using System.Runtime.Remoting.Proxies;
  38.     using System.Runtime.Serialization;
  39.     using System.Runtime.Serialization.Formatters;
  40.     using System.Runtime.Serialization.Formatters.Binary;
  41.     using System.Reflection;
  42.     using System.Text;
  43.     using System.Runtime.CompilerServices;
  44.     using System.Security.Permissions;
  45.     using System.Globalization;
  46.    
  47.     //+=======================================================================
  48.     //
  49.     // Synopsis: Message is used to represent call and is created by the
  50.     // Transparent proxy
  51.     //
  52.     //-=======================================================================
  53.     [Serializable()]
  54.     internal class Message : IMethodCallMessage, IInternalMessage, ISerializable
  55.     {
  56.        
  57.         // *** NOTE ***
  58.         // Keep these in sync with the flags in Message.h
  59.         // flags
  60.         internal const int Sync = 0;
  61.         // Synchronous call
  62.         internal const int BeginAsync = 1;
  63.         // Async Begin call
  64.         internal const int EndAsync = 2;
  65.         // Async End call
  66.         internal const int Ctor = 4;
  67.         // The call is a .Ctor
  68.         internal const int OneWay = 8;
  69.         // One way call
  70.         internal const int CallMask = 15;
  71.         // Mask for call type bits
  72.         internal const int FixedArgs = 16;
  73.         // Fixed number of arguments call
  74.         internal const int VarArgs = 32;
  75.         // Variable number of arguments call
  76.         //
  77.         // Changing the type or position of these fields requires making changes
  78.         // to the corresponding unmanaged class and to mscorlib.h
  79.         //
  80.        
  81.         // Private data members
  82.         private string _MethodName;
  83.         // Method name
  84.         private Type[] _MethodSignature;
  85.         // Array of parameter types
  86.         private MethodBase _MethodBase;
  87.         // Reflection method object
  88.         private object _properties;
  89.         // hash table for properities
  90.         private string _URI;
  91.         // target object URI
  92.         private string _typeName;
  93.         private Exception _Fault;
  94.         // null if no fault
  95.         private Identity _ID;
  96.         // identity cached during Invoke
  97.         private ServerIdentity _srvID;
  98.         // server Identity cached during Invoke
  99.         private ArgMapper _argMapper;
  100.         private LogicalCallContext _callContext;
  101.        
  102.         private IntPtr _frame;
  103.         // ptr to the call frame
  104.         private IntPtr _methodDesc;
  105.         // ptr to the internal method descriptor
  106.         private IntPtr _metaSigHolder;
  107.         // Pointer to the MetaSig structure
  108.         private IntPtr _delegateMD;
  109.         // ptr to the internal method descriptor for the delegate
  110.         private IntPtr _governingType;
  111.         // ptr to the internal type handle for the type calling the method
  112.         private int _flags;
  113.         // internal flags
  114.         private bool _initDone;
  115.         // called the native init routine
  116.        
  117.         static internal string CallContextKey = "__CallContext";
  118.         static internal string UriKey = "__Uri";
  119.        
  120.        
  121.         public virtual Exception GetFault()
  122.         {
  123.             return _Fault;
  124.         }
  125.         public virtual void SetFault(Exception e)
  126.         {
  127.             _Fault = e;
  128.         }
  129.        
  130.         internal virtual void SetOneWay()
  131.         {
  132.             _flags |= Message.OneWay;
  133.         }
  134.         public virtual int GetCallType()
  135.         {
  136.             // We should call init only if neccessary
  137.             InitIfNecessary();
  138.             return _flags;
  139.         }
  140.        
  141.         internal IntPtr GetFramePtr()
  142.         {
  143.             return _frame;
  144.         }
  145.        
  146.        
  147.        
  148.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  149.         public extern void GetAsyncBeginInfo(out AsyncCallback acbd, out object state);
  150.        
  151.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  152.         public extern object GetThisPtr();
  153.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  154.         public extern IAsyncResult GetAsyncResult();
  155.        
  156.         public void Init()
  157.         {
  158.             // This method no longer does any meaninfull work, however it is
  159.             // publicly exposed so we cannot get rid of it.
  160.         }
  161.        
  162.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  163.         public extern object GetReturnValue();
  164.         //
  165.         // Constructor
  166.         // This should be internal. The message object is
  167.         // allocated and deallocated via a pool to enable
  168.         // reuse.
  169.         //
  170.         internal Message()
  171.         {
  172.         }
  173.        
  174.         // NOTE: This method is called multiple times as we reuse the
  175.         // message object. Make sure that you reset any fields that you
  176.         // add to the message object to the default values. This will
  177.         // ensure that the reused message object starts with the correct
  178.         // values.
  179.         internal void InitFields(MessageData msgData)
  180.         {
  181.             _frame = msgData.pFrame;
  182.             _delegateMD = msgData.pDelegateMD;
  183.             _methodDesc = msgData.pMethodDesc;
  184.             _flags = msgData.iFlags;
  185.             _initDone = true;
  186.             _metaSigHolder = msgData.pSig;
  187.             _governingType = msgData.thGoverningType;
  188.            
  189.             _MethodName = null;
  190.             _MethodSignature = null;
  191.             _MethodBase = null;
  192.             _URI = null;
  193.             _Fault = null;
  194.             _ID = null;
  195.             _srvID = null;
  196.             _callContext = null;
  197.            
  198.             if (_properties != null) {
  199.                 // A dictionary object already exists. This case occurs
  200.                 // when we reuse the message object. Just remove all the
  201.                 // entries from the dictionary object and reuse it.
  202.                 ((IDictionary)_properties).Clear();
  203.             }
  204.            
  205.         }
  206.        
  207.         private void InitIfNecessary()
  208.         {
  209.             if (!_initDone) {
  210.                 // We assume that Init is an idempotent operation
  211.                 Init();
  212.                 _initDone = true;
  213.             }
  214.         }
  215.        
  216.        
  217.         //-------------------------------------------------------------------
  218.         // IInternalMessage
  219.         //-------------------------------------------------------------------
  220.         ServerIdentity IInternalMessage.ServerIdentityObject {
  221.             get { return _srvID; }
  222.             set { _srvID = value; }
  223.         }
  224.        
  225.         Identity IInternalMessage.IdentityObject {
  226.             get { return _ID; }
  227.             set { _ID = value; }
  228.         }
  229.        
  230.         void IInternalMessage.SetURI(string URI)
  231.         {
  232.             _URI = URI;
  233.         }
  234.        
  235.         void IInternalMessage.SetCallContext(LogicalCallContext callContext)
  236.         {
  237.             _callContext = callContext;
  238.         }
  239.        
  240.         bool IInternalMessage.HasProperties()
  241.         {
  242.             return _properties != null;
  243.         }
  244.        
  245.         //-------------------------------------------------------------------
  246.         // IMessage
  247.         //-------------------------------------------------------------------
  248.         public IDictionary Properties {
  249.             get {
  250.                 if (_properties == null) {
  251.                     Interlocked.CompareExchange(ref _properties, new MCMDictionary(this, null), null);
  252.                 }
  253.                 return (IDictionary)_properties;
  254.             }
  255.         }
  256.        
  257.         //-------------------------------------------------------------------
  258.         // IMethodCallMessage
  259.         //-------------------------------------------------------------------
  260.        
  261.         public string Uri {
  262.             get { return _URI; }
  263.            
  264.             set { _URI = value; }
  265.         }
  266.        
  267.         public bool HasVarArgs {
  268.             get {
  269.                 // When this method is called for the first time, we
  270.                 // obtain the answer from a native call and set the flags
  271.                 if ((0 == (_flags & Message.FixedArgs)) && (0 == (_flags & Message.VarArgs))) {
  272.                     if (!InternalHasVarArgs()) {
  273.                         _flags |= Message.FixedArgs;
  274.                     }
  275.                     else {
  276.                         _flags |= Message.VarArgs;
  277.                     }
  278.                 }
  279.                 return (1 == (_flags & Message.VarArgs));
  280.             }
  281.         }
  282.        
  283.        
  284.         public int ArgCount {
  285.             get { return InternalGetArgCount(); }
  286.         }
  287.        
  288.         public object GetArg(int argNum)
  289.         {
  290.             return InternalGetArg(argNum);
  291.         }
  292.        
  293.         public string GetArgName(int index)
  294.         {
  295.             if (index >= ArgCount) {
  296.                 throw new ArgumentOutOfRangeException("index");
  297.             }
  298.            
  299.             RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(GetMethodBase());
  300.            
  301.             ParameterInfo[] pi = methodCache.Parameters;
  302.            
  303.             if (index < pi.Length) {
  304.                 return pi[index].Name;
  305.             }
  306.             else {
  307.                 return "VarArg" + (index - pi.Length);
  308.             }
  309.         }
  310.        
  311.         public object[] Args {
  312.             get { return InternalGetArgs(); }
  313.         }
  314.        
  315.         public int InArgCount {
  316.             get {
  317.                 if (_argMapper == null)
  318.                     _argMapper = new ArgMapper(this, false);
  319.                 return _argMapper.ArgCount;
  320.             }
  321.         }
  322.        
  323.         public object GetInArg(int argNum)
  324.         {
  325.             if (_argMapper == null)
  326.                 _argMapper = new ArgMapper(this, false);
  327.             return _argMapper.GetArg(argNum);
  328.         }
  329.        
  330.         public string GetInArgName(int index)
  331.         {
  332.             if (_argMapper == null)
  333.                 _argMapper = new ArgMapper(this, false);
  334.             return _argMapper.GetArgName(index);
  335.         }
  336.        
  337.         public object[] InArgs {
  338.             get {
  339.                 if (_argMapper == null)
  340.                     _argMapper = new ArgMapper(this, false);
  341.                 return _argMapper.Args;
  342.             }
  343.         }
  344.        
  345.         private void UpdateNames()
  346.         {
  347.             RemotingMethodCachedData methCache = InternalRemotingServices.GetReflectionCachedData(GetMethodBase());
  348.             _typeName = methCache.TypeAndAssemblyName;
  349.             _MethodName = methCache.MethodName;
  350.         }
  351.        
  352.         public string MethodName {
  353.             get {
  354.                 if (null == _MethodName)
  355.                     UpdateNames();
  356.                 return _MethodName;
  357.             }
  358.         }
  359.        
  360.         public string TypeName {
  361.             get {
  362.                 if (_typeName == null)
  363.                     UpdateNames();
  364.                 return _typeName;
  365.             }
  366.         }
  367.        
  368.         public object MethodSignature {
  369.             get {
  370.                 if (null == _MethodSignature)
  371.                     _MethodSignature = GenerateMethodSignature(GetMethodBase());
  372.                
  373.                 return _MethodSignature;
  374.             }
  375.         }
  376.        
  377.         public LogicalCallContext LogicalCallContext {
  378.             get { return GetLogicalCallContext(); }
  379.         }
  380.        
  381.         public MethodBase MethodBase {
  382.             get { return GetMethodBase(); }
  383.         }
  384.        
  385.        
  386.         //
  387.         // ISerializable
  388.         //
  389.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
  390.         public void GetObjectData(SerializationInfo info, StreamingContext context)
  391.         {
  392.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_Method"));
  393.         }
  394.        
  395.         internal MethodBase GetMethodBase()
  396.         {
  397.             if (null == _MethodBase) {
  398.                 unsafe {
  399.                     RuntimeMethodHandle mh = new RuntimeMethodHandle((void*)_methodDesc);
  400.                     RuntimeTypeHandle th = new RuntimeTypeHandle((void*)_governingType);
  401.                     _MethodBase = RuntimeType.GetMethodBase(th, mh);
  402.                 }
  403.             }
  404.             return _MethodBase;
  405.         }
  406.        
  407.         internal LogicalCallContext SetLogicalCallContext(LogicalCallContext callCtx)
  408.         {
  409.             LogicalCallContext oldCtx = _callContext;
  410.             _callContext = callCtx;
  411.            
  412.             return oldCtx;
  413.         }
  414.        
  415.         internal LogicalCallContext GetLogicalCallContext()
  416.         {
  417.             if (_callContext == null)
  418.                 _callContext = new LogicalCallContext();
  419.             return _callContext;
  420.         }
  421.        
  422.        
  423.         // Internal helper to create method signature
  424.         static internal Type[] GenerateMethodSignature(MethodBase mb)
  425.         {
  426.             RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(mb);
  427.            
  428.             ParameterInfo[] paramArray = methodCache.Parameters;
  429.             Type[] methodSig = new Type[paramArray.Length];
  430.             for (int i = 0; i < paramArray.Length; i++) {
  431.                 methodSig[i] = paramArray[i].ParameterType;
  432.             }
  433.            
  434.             return methodSig;
  435.         }
  436.         // GenerateMethodSignature
  437.         //
  438.         // The following two routines are used by StackBuilderSink to check
  439.         // the consistency of arguments.
  440.         //
  441.         // Check that all the arguments are of the type
  442.         // specified by the parameter list.
  443.         //
  444.         static internal object[] CoerceArgs(IMethodMessage m)
  445.         {
  446.             MethodBase mb = m.MethodBase;
  447.             BCLDebug.Assert(mb != null, "null method base passed to CoerceArgs");
  448.            
  449.             RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(mb);
  450.            
  451.             return CoerceArgs(m, methodCache.Parameters);
  452.         }
  453.         // CoerceArgs
  454.         static internal object[] CoerceArgs(IMethodMessage m, ParameterInfo[] pi)
  455.         {
  456.             return CoerceArgs(m.MethodBase, m.Args, pi);
  457.         }
  458.         // CoerceArgs
  459.         static internal object[] CoerceArgs(MethodBase mb, object[] args, ParameterInfo[] pi)
  460.         {
  461.             if (pi == null) {
  462.                 throw new ArgumentNullException("pi");
  463.             }
  464.            
  465.             if (pi.Length != args.Length) {
  466.                 throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_ArgMismatch"), mb.DeclaringType.FullName, mb.Name, args.Length, pi.Length));
  467.             }
  468.            
  469.             for (int i = 0; i < pi.Length; i++) {
  470.                 ParameterInfo currentPi = pi[i];
  471.                 Type pt = currentPi.ParameterType;
  472.                 object oArg = args[i];
  473.                 if (oArg != null) {
  474.                     args[i] = CoerceArg(oArg, pt);
  475.                 }
  476.                 else {
  477.                     if (pt.IsByRef) {
  478.                         Type paramType = pt.GetElementType();
  479.                         if (paramType.IsValueType) {
  480.                             // nullables can be null,
  481.                             if (currentPi.IsOut) {
  482.                                 // we need to fill in the blanks for value types if they are null
  483.                                 args[i] = Activator.CreateInstance(paramType, true);
  484.                             }
  485.                             else {
  486.                                 if (!(paramType.IsGenericType && paramType.GetGenericTypeDefinition() == typeof(Nullable<>))) {
  487.                                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_MissingArgValue"), paramType.FullName, i));
  488.                                 }
  489.                             }
  490.                         }
  491.                     }
  492.                     else {
  493.                         if (pt.IsValueType) {
  494.                             // nullables can be null,
  495.                             if (!(pt.IsGenericType && pt.GetGenericTypeDefinition() == typeof(Nullable<>))) {
  496.                                 // A null value was passed as a value type parameter.
  497.                                 throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_MissingArgValue"), pt.FullName, i));
  498.                             }
  499.                         }
  500.                     }
  501.                 }
  502.             }
  503.            
  504.             return args;
  505.         }
  506.         // CoerceArgs
  507.        
  508.         static internal object CoerceArg(object value, Type pt)
  509.         {
  510.             object ret = null;
  511.            
  512.             if (null != value) {
  513.                 Exception inner = null;
  514.                 try {
  515.                     if (pt.IsByRef) {
  516.                         pt = pt.GetElementType();
  517.                     }
  518.                    
  519.                     if (pt.IsInstanceOfType(value)) {
  520.                         ret = value;
  521.                     }
  522.                     else {
  523.                         ret = Convert.ChangeType(value, pt, CultureInfo.InvariantCulture);
  524.                     }
  525.                 }
  526.                 catch (Exception e) {
  527.                     // Quietly swallow all exceptions. We will throw
  528.                     // a more meaningful exception below.
  529.                     inner = e;
  530.                 }
  531.                
  532.                 // If the coercion failed then throw an exception
  533.                 if (null == ret) {
  534.                     // NOTE: Do not call value.ToString() on proxies as
  535.                     // it results in loading the type and loss of refinement
  536.                     // optimization or denial of service attacks by loading
  537.                     // a lot of types in the server.
  538.                     string valueName = null;
  539.                     if (RemotingServices.IsTransparentProxy(value)) {
  540.                         valueName = typeof(MarshalByRefObject).ToString();
  541.                     }
  542.                     else {
  543.                         valueName = value.ToString();
  544.                     }
  545.                    
  546.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_CoercionFailed"), valueName, pt), inner);
  547.                 }
  548.             }
  549.            
  550.             return ret;
  551.         }
  552.         //end of CoerceArg
  553.         static internal object SoapCoerceArg(object value, Type pt, Hashtable keyToNamespaceTable)
  554.         {
  555.             object ret = null;
  556.            
  557.             if (value != null) {
  558.                 try {
  559.                     if (pt.IsByRef) {
  560.                         pt = pt.GetElementType();
  561.                     }
  562.                    
  563.                     if (pt.IsInstanceOfType(value)) {
  564.                         ret = value;
  565.                     }
  566.                     else {
  567.                         string strValue = value as string;
  568.                         if (strValue != null) {
  569.                             if (pt == typeof(double)) {
  570.                                 if (strValue == "INF")
  571.                                     ret = Double.PositiveInfinity;
  572.                                 else if (strValue == "-INF")
  573.                                     ret = Double.NegativeInfinity;
  574.                                 else
  575.                                     ret = Double.Parse(strValue, CultureInfo.InvariantCulture);
  576.                             }
  577.                             else if (pt == typeof(float)) {
  578.                                 if (strValue == "INF")
  579.                                     ret = Single.PositiveInfinity;
  580.                                 else if (strValue == "-INF")
  581.                                     ret = Single.NegativeInfinity;
  582.                                 else
  583.                                     ret = Single.Parse(strValue, CultureInfo.InvariantCulture);
  584.                             }
  585.                             else if (SoapType.typeofISoapXsd.IsAssignableFrom(pt)) {
  586.                                 if (pt == SoapType.typeofSoapTime)
  587.                                     ret = SoapTime.Parse(strValue);
  588.                                 else if (pt == SoapType.typeofSoapDate)
  589.                                     ret = SoapDate.Parse(strValue);
  590.                                 else if (pt == SoapType.typeofSoapYearMonth)
  591.                                     ret = SoapYearMonth.Parse(strValue);
  592.                                 else if (pt == SoapType.typeofSoapYear)
  593.                                     ret = SoapYear.Parse(strValue);
  594.                                 else if (pt == SoapType.typeofSoapMonthDay)
  595.                                     ret = SoapMonthDay.Parse(strValue);
  596.                                 else if (pt == SoapType.typeofSoapDay)
  597.                                     ret = SoapDay.Parse(strValue);
  598.                                 else if (pt == SoapType.typeofSoapMonth)
  599.                                     ret = SoapMonth.Parse(strValue);
  600.                                 else if (pt == SoapType.typeofSoapHexBinary)
  601.                                     ret = SoapHexBinary.Parse(strValue);
  602.                                 else if (pt == SoapType.typeofSoapBase64Binary)
  603.                                     ret = SoapBase64Binary.Parse(strValue);
  604.                                 else if (pt == SoapType.typeofSoapInteger)
  605.                                     ret = SoapInteger.Parse(strValue);
  606.                                 else if (pt == SoapType.typeofSoapPositiveInteger)
  607.                                     ret = SoapPositiveInteger.Parse(strValue);
  608.                                 else if (pt == SoapType.typeofSoapNonPositiveInteger)
  609.                                     ret = SoapNonPositiveInteger.Parse(strValue);
  610.                                 else if (pt == SoapType.typeofSoapNonNegativeInteger)
  611.                                     ret = SoapNonNegativeInteger.Parse(strValue);
  612.                                 else if (pt == SoapType.typeofSoapNegativeInteger)
  613.                                     ret = SoapNegativeInteger.Parse(strValue);
  614.                                 else if (pt == SoapType.typeofSoapAnyUri)
  615.                                     ret = SoapAnyUri.Parse(strValue);
  616.                                 else if (pt == SoapType.typeofSoapQName) {
  617.                                     ret = SoapQName.Parse(strValue);
  618.                                     SoapQName soapQName = (SoapQName)ret;
  619.                                     if (soapQName.Key.Length == 0)
  620.                                         soapQName.Namespace = (string)keyToNamespaceTable["xmlns"];
  621.                                     else
  622.                                         soapQName.Namespace = (string)keyToNamespaceTable["xmlns" + ":" + soapQName.Key];
  623.                                 }
  624.                                 else if (pt == SoapType.typeofSoapNotation)
  625.                                     ret = SoapNotation.Parse(strValue);
  626.                                 else if (pt == SoapType.typeofSoapNormalizedString)
  627.                                     ret = SoapNormalizedString.Parse(strValue);
  628.                                 else if (pt == SoapType.typeofSoapToken)
  629.                                     ret = SoapToken.Parse(strValue);
  630.                                 else if (pt == SoapType.typeofSoapLanguage)
  631.                                     ret = SoapLanguage.Parse(strValue);
  632.                                 else if (pt == SoapType.typeofSoapName)
  633.                                     ret = SoapName.Parse(strValue);
  634.                                 else if (pt == SoapType.typeofSoapIdrefs)
  635.                                     ret = SoapIdrefs.Parse(strValue);
  636.                                 else if (pt == SoapType.typeofSoapEntities)
  637.                                     ret = SoapEntities.Parse(strValue);
  638.                                 else if (pt == SoapType.typeofSoapNmtoken)
  639.                                     ret = SoapNmtoken.Parse(strValue);
  640.                                 else if (pt == SoapType.typeofSoapNmtokens)
  641.                                     ret = SoapNmtokens.Parse(strValue);
  642.                                 else if (pt == SoapType.typeofSoapNcName)
  643.                                     ret = SoapNcName.Parse(strValue);
  644.                                 else if (pt == SoapType.typeofSoapId)
  645.                                     ret = SoapId.Parse(strValue);
  646.                                 else if (pt == SoapType.typeofSoapIdref)
  647.                                     ret = SoapIdref.Parse(strValue);
  648.                                 else if (pt == SoapType.typeofSoapEntity)
  649.                                     ret = SoapEntity.Parse(strValue);
  650.                             }
  651.                             else if (pt == typeof(bool)) {
  652.                                 if (strValue == "1" || strValue == "true")
  653.                                     ret = (bool)true;
  654.                                 else if (strValue == "0" || strValue == "false")
  655.                                     ret = (bool)false;
  656.                                 else {
  657.                                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_CoercionFailed"), strValue, pt));
  658.                                 }
  659.                             }
  660.                             else if (pt == typeof(DateTime))
  661.                                 ret = SoapDateTime.Parse(strValue);
  662.                             else if (pt.IsPrimitive)
  663.                                 ret = Convert.ChangeType(value, pt, CultureInfo.InvariantCulture);
  664.                             else if (pt == typeof(TimeSpan))
  665.                                 ret = SoapDuration.Parse(strValue);
  666.                             else if (pt == typeof(char))
  667.                                 ret = strValue[0];
  668.                             else
  669.                                
  670.                                 ret = Convert.ChangeType(value, pt, CultureInfo.InvariantCulture);
  671.                             //Should this just throw an exception
  672.                         }
  673.                         else
  674.                             ret = Convert.ChangeType(value, pt, CultureInfo.InvariantCulture);
  675.                     }
  676.                 }
  677.                 catch (Exception) {
  678.                     // Quietly swallow all exceptions. We will throw
  679.                     // a more meaningful exception below.
  680.                 }
  681.                
  682.                 // If the coercion failed then throw an exception
  683.                 if (null == ret) {
  684.                     // NOTE: Do not call value.ToString() on proxies as
  685.                     // it results in loading the type and loss of refinement
  686.                     // optimization or denial of service attacks by loading
  687.                     // a lot of types in the server.
  688.                     string valueName = null;
  689.                     if (RemotingServices.IsTransparentProxy(value)) {
  690.                         valueName = typeof(MarshalByRefObject).ToString();
  691.                     }
  692.                     else {
  693.                         valueName = value.ToString();
  694.                     }
  695.                    
  696.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_CoercionFailed"), valueName, pt));
  697.                 }
  698.             }
  699.            
  700.             return ret;
  701.         }
  702.         //end of SoapCoerceArg
  703.        
  704.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  705.         internal extern bool InternalHasVarArgs();
  706.        
  707.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  708.         internal extern int InternalGetArgCount();
  709.        
  710.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  711.         private extern object InternalGetArg(int argNum);
  712.        
  713.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  714.         private extern object[] InternalGetArgs();
  715.        
  716.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  717.         public extern void PropagateOutParameters(object[] OutArgs, object retVal);
  718.        
  719.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  720.         public extern bool Dispatch(object target, bool fExecuteInContext);
  721.        
  722.         //
  723.         //
  724.         [System.Diagnostics.Conditional("_REMOTING_DEBUG")]
  725.         public static void DebugOut(string s)
  726.         {
  727.             BCLDebug.Trace("REMOTE", "RMTING: Thrd " + Thread.CurrentThread.GetHashCode() + " : " + s);
  728.             OutToUnmanagedDebugger("\nRMTING: Thrd " + Thread.CurrentThread.GetHashCode() + " : " + s);
  729.         }
  730.        
  731.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  732.         static internal extern void OutToUnmanagedDebugger(string s);
  733.        
  734.         static internal LogicalCallContext PropagateCallContextFromMessageToThread(IMessage msg)
  735.         {
  736.             return CallContext.SetLogicalCallContext((LogicalCallContext)msg.Properties[Message.CallContextKey]);
  737.         }
  738.        
  739.         static internal void PropagateCallContextFromThreadToMessage(IMessage msg)
  740.         {
  741.             LogicalCallContext callCtx = CallContext.GetLogicalCallContext();
  742.            
  743.             msg.Properties[Message.CallContextKey] = callCtx;
  744.         }
  745.        
  746.         static internal void PropagateCallContextFromThreadToMessage(IMessage msg, LogicalCallContext oldcctx)
  747.         {
  748.             // First do the common work
  749.             PropagateCallContextFromThreadToMessage(msg);
  750.            
  751.             // restore the old call context on the thread
  752.             CallContext.SetLogicalCallContext(oldcctx);
  753.         }
  754.     }
  755.    
  756.     //+================================================================================
  757.     //
  758.     // Synopsis: Return message for constructors
  759.     //
  760.     //-================================================================================
  761.     internal class ConstructorReturnMessage : ReturnMessage, IConstructionReturnMessage
  762.     {
  763.        
  764.         private const int Intercept = 1;
  765.        
  766.         private MarshalByRefObject _o;
  767.         private int _iFlags;
  768.        
  769.        
  770.         public ConstructorReturnMessage(MarshalByRefObject o, object[] outArgs, int outArgsCount, LogicalCallContext callCtx, IConstructionCallMessage ccm) : base(o, outArgs, outArgsCount, callCtx, ccm)
  771.         {
  772.             _o = o;
  773.             _iFlags = Intercept;
  774.         }
  775.        
  776.         public ConstructorReturnMessage(Exception e, IConstructionCallMessage ccm) : base(e, ccm)
  777.         {
  778.         }
  779.        
  780.         public override object ReturnValue {
  781.             get {
  782.                 if (_iFlags == Intercept) {
  783.                     return RemotingServices.MarshalInternal(_o, null, null);
  784.                 }
  785.                 else {
  786.                     return base.ReturnValue;
  787.                 }
  788.             }
  789.         }
  790.        
  791.        
  792.         public override IDictionary Properties {
  793.             get {
  794.                 if (_properties == null) {
  795.                     object properties = new CRMDictionary(this, new Hashtable());
  796.                     Interlocked.CompareExchange(ref _properties, properties, null);
  797.                 }
  798.                 return (IDictionary)_properties;
  799.             }
  800.         }
  801.        
  802.         internal object GetObject()
  803.         {
  804.             return _o;
  805.         }
  806.     }
  807.    
  808.     //+========================================================================
  809.     //
  810.     // Synopsis: client side implementation of activation message
  811.     //
  812.     //-========================================================================
  813.     internal class ConstructorCallMessage : IConstructionCallMessage
  814.     {
  815.        
  816.         // data
  817.        
  818.         private object[] _callSiteActivationAttributes;
  819.         private object[] _womGlobalAttributes;
  820.         private object[] _typeAttributes;
  821.        
  822.         // The activation type isn't serialized because we want to
  823.         // re-resolve the activation type name on the other side
  824.         // based on _activationTypeName.
  825.         [NonSerialized()]
  826.         private Type _activationType;
  827.        
  828.         private string _activationTypeName;
  829.        
  830.         private IList _contextProperties;
  831.         private int _iFlags;
  832.         private Message _message;
  833.         private object _properties;
  834.         private ArgMapper _argMapper;
  835.         private IActivator _activator;
  836.        
  837.         // flags
  838.         private const int CCM_ACTIVATEINCONTEXT = 1;
  839.        
  840.         private ConstructorCallMessage()
  841.         {
  842.             // Default constructor
  843.         }
  844.        
  845.         internal ConstructorCallMessage(object[] callSiteActivationAttributes, object[] womAttr, object[] typeAttr, Type serverType)
  846.         {
  847.             _activationType = serverType;
  848.             _activationTypeName = RemotingServices.GetDefaultQualifiedTypeName(_activationType);
  849.             _callSiteActivationAttributes = callSiteActivationAttributes;
  850.             _womGlobalAttributes = womAttr;
  851.             _typeAttributes = typeAttr;
  852.         }
  853.        
  854.         public object GetThisPtr()
  855.         {
  856.             if (_message != null) {
  857.                 return _message.GetThisPtr();
  858.             }
  859.             else {
  860.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  861.             }
  862.         }
  863.        
  864.         public object[] CallSiteActivationAttributes {
  865.             get { return _callSiteActivationAttributes; }
  866.         }
  867.        
  868.        
  869.         internal object[] GetWOMAttributes()
  870.         {
  871.             return _womGlobalAttributes;
  872.         }
  873.        
  874.         internal object[] GetTypeAttributes()
  875.         {
  876.             return _typeAttributes;
  877.         }
  878.        
  879.         public Type ActivationType {
  880.             get {
  881.                 if ((_activationType == null) && (_activationTypeName != null))
  882.                     _activationType = RemotingServices.InternalGetTypeFromQualifiedTypeName(_activationTypeName, false);
  883.                
  884.                 return _activationType;
  885.             }
  886.         }
  887.        
  888.         public string ActivationTypeName {
  889.             get { return _activationTypeName; }
  890.         }
  891.        
  892.         public IList ContextProperties {
  893.             get {
  894.                 if (_contextProperties == null) {
  895.                     _contextProperties = new ArrayList();
  896.                 }
  897.                 return _contextProperties;
  898.             }
  899.         }
  900.        
  901.         public string Uri {
  902.             get {
  903.                 if (_message != null) {
  904.                     return _message.Uri;
  905.                 }
  906.                 else {
  907.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  908.                 }
  909.             }
  910.            
  911.             set {
  912.                 if (_message != null) {
  913.                     _message.Uri = value;
  914.                 }
  915.                 else {
  916.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  917.                 }
  918.             }
  919.         }
  920.        
  921.        
  922.         public string MethodName {
  923.             get {
  924.                 if (_message != null) {
  925.                     return _message.MethodName;
  926.                 }
  927.                 else {
  928.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  929.                 }
  930.             }
  931.         }
  932.        
  933.         public string TypeName {
  934.             get {
  935.                 if (_message != null) {
  936.                     return _message.TypeName;
  937.                 }
  938.                 else {
  939.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  940.                 }
  941.             }
  942.         }
  943.        
  944.         public object MethodSignature {
  945.             get {
  946.                 if (_message != null) {
  947.                     return _message.MethodSignature;
  948.                 }
  949.                 else {
  950.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  951.                 }
  952.             }
  953.         }
  954.         // MethodSignature
  955.         public MethodBase MethodBase {
  956.             get {
  957.                 if (_message != null) {
  958.                     return _message.MethodBase;
  959.                 }
  960.                 else {
  961.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  962.                 }
  963.             }
  964.         }
  965.         // MethodBase
  966.        
  967.         /// <internalonly/>
  968.         public int InArgCount {
  969.             get {
  970.                 if (_argMapper == null)
  971.                     _argMapper = new ArgMapper(this, false);
  972.                 return _argMapper.ArgCount;
  973.             }
  974.         }
  975.        
  976.         public object GetInArg(int argNum)
  977.         {
  978.             if (_argMapper == null)
  979.                 _argMapper = new ArgMapper(this, false);
  980.             return _argMapper.GetArg(argNum);
  981.         }
  982.        
  983.         /// <internalonly/>
  984.         public string GetInArgName(int index)
  985.         {
  986.             if (_argMapper == null)
  987.                 _argMapper = new ArgMapper(this, false);
  988.             return _argMapper.GetArgName(index);
  989.         }
  990.         public object[] InArgs {
  991.             get {
  992.                 if (_argMapper == null)
  993.                     _argMapper = new ArgMapper(this, false);
  994.                 return _argMapper.Args;
  995.             }
  996.         }
  997.        
  998.         public int ArgCount {
  999.             get {
  1000.                 if (_message != null) {
  1001.                     return _message.ArgCount;
  1002.                 }
  1003.                 else {
  1004.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1005.                 }
  1006.             }
  1007.         }
  1008.        
  1009.         public object GetArg(int argNum)
  1010.         {
  1011.             if (_message != null) {
  1012.                 return _message.GetArg(argNum);
  1013.             }
  1014.             else {
  1015.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1016.             }
  1017.         }
  1018.        
  1019.         public string GetArgName(int index)
  1020.         {
  1021.             if (_message != null) {
  1022.                 return _message.GetArgName(index);
  1023.             }
  1024.             else {
  1025.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1026.             }
  1027.         }
  1028.        
  1029.         public bool HasVarArgs {
  1030.             get {
  1031.                 if (_message != null) {
  1032.                     return _message.HasVarArgs;
  1033.                 }
  1034.                 else {
  1035.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1036.                 }
  1037.             }
  1038.         }
  1039.        
  1040.         public object[] Args {
  1041.             get {
  1042.                 if (_message != null) {
  1043.                     return _message.Args;
  1044.                 }
  1045.                 else {
  1046.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1047.                 }
  1048.             }
  1049.         }
  1050.        
  1051.         public IDictionary Properties {
  1052.             get {
  1053.                 if (_properties == null) {
  1054.                     object properties = new CCMDictionary(this, new Hashtable());
  1055.                     Interlocked.CompareExchange(ref _properties, properties, null);
  1056.                 }
  1057.                 return (IDictionary)_properties;
  1058.             }
  1059.         }
  1060.        
  1061.         public IActivator Activator {
  1062.             get { return _activator; }
  1063.             set { _activator = value; }
  1064.         }
  1065.        
  1066.         public LogicalCallContext LogicalCallContext {
  1067.             get { return GetLogicalCallContext(); }
  1068.         }
  1069.        
  1070.        
  1071.         internal bool ActivateInContext {
  1072.             get { return ((_iFlags & CCM_ACTIVATEINCONTEXT) != 0); }
  1073.             set { _iFlags = value ? (_iFlags | CCM_ACTIVATEINCONTEXT) : (_iFlags & ~CCM_ACTIVATEINCONTEXT); }
  1074.         }
  1075.        
  1076.         internal void SetFrame(MessageData msgData)
  1077.         {
  1078.             BCLDebug.Assert(_message == null, "Can't set frame twice on ConstructorCallMessage");
  1079.             _message = new Message();
  1080.             _message.InitFields(msgData);
  1081.         }
  1082.        
  1083.         internal LogicalCallContext GetLogicalCallContext()
  1084.         {
  1085.             if (_message != null) {
  1086.                 return _message.GetLogicalCallContext();
  1087.             }
  1088.             else {
  1089.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1090.             }
  1091.         }
  1092.        
  1093.         internal LogicalCallContext SetLogicalCallContext(LogicalCallContext ctx)
  1094.         {
  1095.             if (_message != null) {
  1096.                 return _message.SetLogicalCallContext(ctx);
  1097.             }
  1098.             else {
  1099.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1100.             }
  1101.            
  1102.         }
  1103.        
  1104.         internal Message GetMessage()
  1105.         {
  1106.             return _message;
  1107.         }
  1108.     }
  1109.    
  1110.     //+========================================================================
  1111.     //
  1112.     // Synopsis: Specialization of MessageDictionary for
  1113.     // ConstructorCallMessage objects
  1114.     //
  1115.     //-========================================================================
  1116.    
  1117.     internal class CCMDictionary : MessageDictionary
  1118.     {
  1119.         public static string[] CCMkeys = {"__Uri", "__MethodName", "__MethodSignature", "__TypeName", "__Args", "__CallContext", "__CallSiteActivationAttributes", "__ActivationType", "__ContextProperties", "__Activator",
  1120.             //0
  1121.             //1
  1122.             //2
  1123.             //3
  1124.             //4
  1125.             //5
  1126.             //6
  1127.             //7
  1128.             //8
  1129.             //9
  1130.         "__ActivationTypeName"};
  1131.         //10
  1132.         internal IConstructionCallMessage _ccmsg;
  1133.         // back pointer to message object
  1134.        
  1135.         public CCMDictionary(IConstructionCallMessage msg, IDictionary idict) : base(CCMkeys, idict)
  1136.         {
  1137.             _ccmsg = msg;
  1138.         }
  1139.        
  1140.         internal override object GetMessageValue(int i)
  1141.         {
  1142.             switch (i) {
  1143.                 case 0:
  1144.                     return _ccmsg.Uri;
  1145.                 case 1:
  1146.                     return _ccmsg.MethodName;
  1147.                 case 2:
  1148.                     return _ccmsg.MethodSignature;
  1149.                 case 3:
  1150.                     return _ccmsg.TypeName;
  1151.                 case 4:
  1152.                     return _ccmsg.Args;
  1153.                 case 5:
  1154.                     return FetchLogicalCallContext();
  1155.                 case 6:
  1156.                     return _ccmsg.CallSiteActivationAttributes;
  1157.                 case 7:
  1158.                     // This it to keep us from serializing the requested server type
  1159.                     return null;
  1160.                 case 8:
  1161.                     return _ccmsg.ContextProperties;
  1162.                 case 9:
  1163.                     return _ccmsg.Activator;
  1164.                 case 10:
  1165.                     return _ccmsg.ActivationTypeName;
  1166.             }
  1167.             // We should not get here!
  1168.             throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  1169.         }
  1170.        
  1171.         private LogicalCallContext FetchLogicalCallContext()
  1172.         {
  1173.             ConstructorCallMessage ccm = _ccmsg as ConstructorCallMessage;
  1174.             if (null != ccm) {
  1175.                 return ccm.GetLogicalCallContext();
  1176.             }
  1177.             else if (_ccmsg is ConstructionCall) {
  1178.                 // This is the case where the message got serialized
  1179.                 // and deserialized
  1180.                 return ((MethodCall)_ccmsg).GetLogicalCallContext();
  1181.             }
  1182.             else {
  1183.                 throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1184.             }
  1185.         }
  1186.        
  1187.         internal override void SetSpecialKey(int keyNum, object value)
  1188.         {
  1189.             switch (keyNum) {
  1190.                 case 0:
  1191.                     ((ConstructorCallMessage)_ccmsg).Uri = (string)value;
  1192.                     break;
  1193.                 case 1:
  1194.                     ((ConstructorCallMessage)_ccmsg).SetLogicalCallContext((LogicalCallContext)value);
  1195.                     break;
  1196.                 default:
  1197.                     // We should not get here!
  1198.                     throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  1199.                     break;
  1200.             }
  1201.         }
  1202.     }
  1203.    
  1204.    
  1205.     //+========================================================================
  1206.     //
  1207.     // Synopsis: Specialization of MessageDictionary for ConstructorCallMessage objects
  1208.     //
  1209.     //-========================================================================
  1210.    
  1211.     internal class CRMDictionary : MessageDictionary
  1212.     {
  1213.         public static string[] CRMkeysFault = {"__Uri", "__MethodName", "__MethodSignature", "__TypeName", "__CallContext"};
  1214.         public static string[] CRMkeysNoFault = {"__Uri", "__MethodName", "__MethodSignature", "__TypeName", "__Return", "__OutArgs", "__CallContext"};
  1215.         internal IConstructionReturnMessage _crmsg;
  1216.         internal bool fault;
  1217.        
  1218.         public CRMDictionary(IConstructionReturnMessage msg, IDictionary idict) : base((msg.Exception != null) ? CRMkeysFault : CRMkeysNoFault, idict)
  1219.         {
  1220.             fault = (msg.Exception != null);
  1221.             _crmsg = msg;
  1222.         }
  1223.        
  1224.         internal override object GetMessageValue(int i)
  1225.         {
  1226.             switch (i) {
  1227.                 case 0:
  1228.                     return _crmsg.Uri;
  1229.                 case 1:
  1230.                     return _crmsg.MethodName;
  1231.                 case 2:
  1232.                     return _crmsg.MethodSignature;
  1233.                 case 3:
  1234.                     return _crmsg.TypeName;
  1235.                 case 4:
  1236.                     return fault ? FetchLogicalCallContext() : _crmsg.ReturnValue;
  1237.                 case 5:
  1238.                     return _crmsg.Args;
  1239.                 case 6:
  1240.                     return FetchLogicalCallContext();
  1241.             }
  1242.             throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  1243.         }
  1244.        
  1245.         private LogicalCallContext FetchLogicalCallContext()
  1246.         {
  1247.             ReturnMessage retMsg = _crmsg as ReturnMessage;
  1248.             if (null != retMsg) {
  1249.                 return retMsg.GetLogicalCallContext();
  1250.             }
  1251.             else {
  1252.                 MethodResponse mr = _crmsg as MethodResponse;
  1253.                 if (null != mr) {
  1254.                     return mr.GetLogicalCallContext();
  1255.                 }
  1256.                 else {
  1257.                     throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1258.                 }
  1259.             }
  1260.         }
  1261.        
  1262.         internal override void SetSpecialKey(int keyNum, object value)
  1263.         {
  1264.             // NOTE: we use this for Uri & CallContext only ...
  1265.            
  1266.             ReturnMessage rm = _crmsg as ReturnMessage;
  1267.             MethodResponse mr = _crmsg as MethodResponse;
  1268.             switch (keyNum) {
  1269.                 case 0:
  1270.                     if (null != rm) {
  1271.                         rm.Uri = (string)value;
  1272.                     }
  1273.                     else {
  1274.                        
  1275.                         if (null != mr) {
  1276.                             mr.Uri = (string)value;
  1277.                         }
  1278.                         else {
  1279.                             throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1280.                         }
  1281.                     }
  1282.                     break;
  1283.                 case 1:
  1284.                     if (null != rm) {
  1285.                         rm.SetLogicalCallContext((LogicalCallContext)value);
  1286.                     }
  1287.                     else {
  1288.                        
  1289.                         if (null != mr) {
  1290.                             mr.SetLogicalCallContext((LogicalCallContext)value);
  1291.                         }
  1292.                         else {
  1293.                             throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1294.                         }
  1295.                     }
  1296.                     break;
  1297.                 default:
  1298.                     throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  1299.                     break;
  1300.             }
  1301.         }
  1302.     }
  1303.    
  1304.     //+================================================================================
  1305.     //
  1306.     // Synopsis: Specialization of MessageDictionary for MethodCallMessage
  1307.     //
  1308.     //-========================================================================
  1309.    
  1310.     internal class MCMDictionary : MessageDictionary
  1311.     {
  1312.         public static string[] MCMkeys = {"__Uri", "__MethodName", "__MethodSignature", "__TypeName", "__Args", "__CallContext"};
  1313.        
  1314.         internal IMethodCallMessage _mcmsg;
  1315.         // back pointer to message object
  1316.        
  1317.         public MCMDictionary(IMethodCallMessage msg, IDictionary idict) : base(MCMkeys, idict)
  1318.         {
  1319.             _mcmsg = msg;
  1320.         }
  1321.        
  1322.         internal override object GetMessageValue(int i)
  1323.         {
  1324.             switch (i) {
  1325.                 case 0:
  1326.                     return _mcmsg.Uri;
  1327.                 case 1:
  1328.                     return _mcmsg.MethodName;
  1329.                 case 2:
  1330.                     return _mcmsg.MethodSignature;
  1331.                 case 3:
  1332.                     return _mcmsg.TypeName;
  1333.                 case 4:
  1334.                     return _mcmsg.Args;
  1335.                 case 5:
  1336.                     return FetchLogicalCallContext();
  1337.             }
  1338.            
  1339.             // Shouldn't get here.
  1340.             throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  1341.         }
  1342.        
  1343.         private LogicalCallContext FetchLogicalCallContext()
  1344.         {
  1345.             Message msg = _mcmsg as Message;
  1346.             if (null != msg) {
  1347.                 return msg.GetLogicalCallContext();
  1348.             }
  1349.             else {
  1350.                 MethodCall mc = _mcmsg as MethodCall;
  1351.                 if (null != mc) {
  1352.                     return mc.GetLogicalCallContext();
  1353.                 }
  1354.                 else {
  1355.                     throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1356.                 }
  1357.             }
  1358.         }
  1359.        
  1360.         internal override void SetSpecialKey(int keyNum, object value)
  1361.         {
  1362.             Message msg = _mcmsg as Message;
  1363.             MethodCall mc = _mcmsg as MethodCall;
  1364.             switch (keyNum) {
  1365.                 case 0:
  1366.                     if (null != msg) {
  1367.                         msg.Uri = (string)value;
  1368.                     }
  1369.                     else if (null != mc) {
  1370.                         mc.Uri = (string)value;
  1371.                     }
  1372.                     else {
  1373.                         throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1374.                     }
  1375.                     break;
  1376.                 case 1:
  1377.                    
  1378.                     if (null != msg) {
  1379.                         msg.SetLogicalCallContext((LogicalCallContext)value);
  1380.                     }
  1381.                     else {
  1382.                         throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1383.                     }
  1384.                     break;
  1385.                 default:
  1386.                     // Shouldn't get here.
  1387.                     throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  1388.                     break;
  1389.             }
  1390.         }
  1391.     }
  1392.    
  1393.     //+================================================================================
  1394.     //
  1395.     // Synopsis: Specialization of MessageDictionary for MethodReturnMessage objects
  1396.     //
  1397.     //-================================================================================
  1398.     internal class MRMDictionary : MessageDictionary
  1399.     {
  1400.         public static string[] MCMkeysFault = {"__CallContext"};
  1401.         public static string[] MCMkeysNoFault = {"__Uri", "__MethodName", "__MethodSignature", "__TypeName", "__Return", "__OutArgs", "__CallContext"};
  1402.        
  1403.         internal IMethodReturnMessage _mrmsg;
  1404.         internal bool fault;
  1405.        
  1406.         public MRMDictionary(IMethodReturnMessage msg, IDictionary idict) : base((msg.Exception != null) ? MCMkeysFault : MCMkeysNoFault, idict)
  1407.         {
  1408.             fault = (msg.Exception != null);
  1409.             _mrmsg = msg;
  1410.         }
  1411.        
  1412.         internal override object GetMessageValue(int i)
  1413.         {
  1414.             switch (i) {
  1415.                 case 0:
  1416.                     if (fault)
  1417.                         return FetchLogicalCallContext();
  1418.                     else
  1419.                         return _mrmsg.Uri;
  1420.                     break;
  1421.                 case 1:
  1422.                     return _mrmsg.MethodName;
  1423.                 case 2:
  1424.                     return _mrmsg.MethodSignature;
  1425.                 case 3:
  1426.                     return _mrmsg.TypeName;
  1427.                 case 4:
  1428.                     if (fault) {
  1429.                         return _mrmsg.Exception;
  1430.                     }
  1431.                     else {
  1432.                         return _mrmsg.ReturnValue;
  1433.                     }
  1434.                     break;
  1435.                 case 5:
  1436.                     return _mrmsg.Args;
  1437.                 case 6:
  1438.                     return FetchLogicalCallContext();
  1439.             }
  1440.             // Shouldn't get here.
  1441.             throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  1442.         }
  1443.        
  1444.         private LogicalCallContext FetchLogicalCallContext()
  1445.         {
  1446.             ReturnMessage rm = _mrmsg as ReturnMessage;
  1447.             if (null != rm) {
  1448.                 return rm.GetLogicalCallContext();
  1449.             }
  1450.             else {
  1451.                 MethodResponse mr = _mrmsg as MethodResponse;
  1452.                 if (null != mr) {
  1453.                     return mr.GetLogicalCallContext();
  1454.                 }
  1455.                 else {
  1456.                     StackBasedReturnMessage srm = _mrmsg as StackBasedReturnMessage;
  1457.                     if (null != srm) {
  1458.                         return srm.GetLogicalCallContext();
  1459.                     }
  1460.                     else {
  1461.                         throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1462.                     }
  1463.                 }
  1464.             }
  1465.         }
  1466.        
  1467.         internal override void SetSpecialKey(int keyNum, object value)
  1468.         {
  1469.             // 0 == Uri
  1470.             // 1 == CallContext
  1471.             // NOTE : we use this for Uri & CallContext only ...
  1472.             ReturnMessage rm = _mrmsg as ReturnMessage;
  1473.             MethodResponse mr = _mrmsg as MethodResponse;
  1474.            
  1475.             switch (keyNum) {
  1476.                 case 0:
  1477.                     if (null != rm) {
  1478.                         rm.Uri = (string)value;
  1479.                     }
  1480.                     else {
  1481.                         if (null != mr) {
  1482.                             mr.Uri = (string)value;
  1483.                         }
  1484.                         else {
  1485.                             throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1486.                         }
  1487.                     }
  1488.                     break;
  1489.                 case 1:
  1490.                     if (null != rm) {
  1491.                         rm.SetLogicalCallContext((LogicalCallContext)value);
  1492.                     }
  1493.                     else {
  1494.                        
  1495.                         if (null != mr) {
  1496.                             mr.SetLogicalCallContext((LogicalCallContext)value);
  1497.                         }
  1498.                         else {
  1499.                             throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadType"));
  1500.                         }
  1501.                     }
  1502.                     break;
  1503.                 default:
  1504.                     // Shouldn't get here.
  1505.                     throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  1506.                     break;
  1507.             }
  1508.         }
  1509.        
  1510.     }
  1511.    
  1512.     //+================================================================================
  1513.     //
  1514.     // Synopsis: Abstract class to help present a dictionary view of an object
  1515.     //
  1516.     //-================================================================================
  1517.     internal abstract class MessageDictionary : IDictionary
  1518.     {
  1519.         internal string[] _keys;
  1520.         internal IDictionary _dict;
  1521.        
  1522.         internal MessageDictionary(string[] keys, IDictionary idict)
  1523.         {
  1524.             _keys = keys;
  1525.             _dict = idict;
  1526.         }
  1527.        
  1528.         internal bool HasUserData()
  1529.         {
  1530.             // used by message smuggler to determine if there is any custom user
  1531.             // data in the dictionary
  1532.             if ((_dict != null) && (_dict.Count > 0))
  1533.                 return true;
  1534.             else
  1535.                 return false;
  1536.         }
  1537.        
  1538.         // used by message smuggler, so that it doesn't have to iterate
  1539.         // through special keys
  1540.         internal IDictionary InternalDictionary {
  1541.             get { return _dict; }
  1542.         }
  1543.        
  1544.        
  1545.         internal abstract object GetMessageValue(int i);
  1546.        
  1547.         internal abstract void SetSpecialKey(int keyNum, object value);
  1548.        
  1549.         public virtual bool IsReadOnly {
  1550.             get { return false; }
  1551.         }
  1552.         public virtual bool IsSynchronized {
  1553.             get { return false; }
  1554.         }
  1555.         public virtual bool IsFixedSize {
  1556.             get { return false; }
  1557.         }
  1558.        
  1559.         public virtual object SyncRoot {
  1560.             get { return this; }
  1561.         }
  1562.        
  1563.        
  1564.         public virtual bool Contains(object key)
  1565.         {
  1566.             if (ContainsSpecialKey(key)) {
  1567.                 return true;
  1568.             }
  1569.             else if (_dict != null) {
  1570.                 return _dict.Contains(key);
  1571.             }
  1572.             return false;
  1573.         }
  1574.        
  1575.         protected virtual bool ContainsSpecialKey(object key)
  1576.         {
  1577.             if (!(key is string)) {
  1578.                 return false;
  1579.             }
  1580.             string skey = (string)key;
  1581.             for (int i = 0; i < _keys.Length; i++) {
  1582.                 if (skey.Equals(_keys[i])) {
  1583.                     return true;
  1584.                 }
  1585.             }
  1586.             return false;
  1587.         }
  1588.        
  1589.         public virtual void CopyTo(Array array, int index)
  1590.         {
  1591.             for (int i = 0; i < _keys.Length; i++) {
  1592.                 array.SetValue(GetMessageValue(i), index + i);
  1593.             }
  1594.            
  1595.             if (_dict != null) {
  1596.                 _dict.CopyTo(array, index + _keys.Length);
  1597.             }
  1598.         }
  1599.        
  1600.         public virtual object this[object key]
  1601.         {
  1602.             get {
  1603.                 string skey = key as string;
  1604.                 if (null != skey) {
  1605.                     for (int i = 0; i < _keys.Length; i++) {
  1606.                         if (skey.Equals(_keys[i])) {
  1607.                             return GetMessageValue(i);
  1608.                         }
  1609.                     }
  1610.                     if (_dict != null) {
  1611.                         return _dict[key];
  1612.                     }
  1613.                 }
  1614.                 return null;
  1615.             }
  1616.             set {
  1617.                 if (ContainsSpecialKey(key)) {
  1618.                     if (key.Equals(Message.UriKey)) {
  1619.                         SetSpecialKey(0, value);
  1620.                     }
  1621.                     else if (key.Equals(Message.CallContextKey)) {
  1622.                         SetSpecialKey(1, value);
  1623.                     }
  1624.                     else {
  1625.                         throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKey"));
  1626.                     }
  1627.                 }
  1628.                 else {
  1629.                     if (_dict == null) {
  1630.                         _dict = new Hashtable();
  1631.                     }
  1632.                     _dict[key] = value;
  1633.                 }
  1634.                
  1635.             }
  1636.         }
  1637.        
  1638.         IDictionaryEnumerator IDictionary.GetEnumerator()
  1639.         {
  1640.             return new MessageDictionaryEnumerator(this, _dict);
  1641.         }
  1642.        
  1643.         IEnumerator IEnumerable.GetEnumerator()
  1644.         {
  1645.             throw new NotSupportedException();
  1646.         }
  1647.        
  1648.        
  1649.         public virtual void Add(object key, object value)
  1650.         {
  1651.             if (ContainsSpecialKey(key)) {
  1652.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKey"));
  1653.             }
  1654.             else {
  1655.                 if (_dict == null) {
  1656.                     // no need to interlock, message object not guaranteed to
  1657.                     // be thread-safe.
  1658.                     _dict = new Hashtable();
  1659.                 }
  1660.                 _dict.Add(key, value);
  1661.             }
  1662.         }
  1663.        
  1664.         public virtual void Clear()
  1665.         {
  1666.             // Remove all the entries from the hash table
  1667.             if (null != _dict) {
  1668.                 _dict.Clear();
  1669.             }
  1670.         }
  1671.        
  1672.         public virtual void Remove(object key)
  1673.         {
  1674.             if (ContainsSpecialKey(key) || (_dict == null)) {
  1675.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKey"));
  1676.             }
  1677.             else {
  1678.                 _dict.Remove(key);
  1679.             }
  1680.         }
  1681.        
  1682.         public virtual ICollection Keys {
  1683.             get {
  1684.                
  1685.                 int len = _keys.Length;
  1686.                 ICollection c = (_dict != null) ? _dict.Keys : null;
  1687.                 if (c != null) {
  1688.                     len += c.Count;
  1689.                 }
  1690.                
  1691.                 ArrayList l = new ArrayList(len);
  1692.                 for (int i = 0; i < _keys.Length; i++) {
  1693.                     l.Add(_keys[i]);
  1694.                 }
  1695.                
  1696.                 if (c != null) {
  1697.                     l.AddRange(c);
  1698.                 }
  1699.                
  1700.                 return l;
  1701.             }
  1702.         }
  1703.        
  1704.         public virtual ICollection Values {
  1705.             get {
  1706.                 int len = _keys.Length;
  1707.                 ICollection c = (_dict != null) ? _dict.Keys : null;
  1708.                 if (c != null) {
  1709.                     len += c.Count;
  1710.                 }
  1711.                
  1712.                 ArrayList l = new ArrayList(len);
  1713.                
  1714.                 for (int i = 0; i < _keys.Length; i++) {
  1715.                     l.Add(GetMessageValue(i));
  1716.                 }
  1717.                
  1718.                 if (c != null) {
  1719.                     l.AddRange(c);
  1720.                 }
  1721.                 return l;
  1722.             }
  1723.         }
  1724.        
  1725.         public virtual int Count {
  1726.             get {
  1727.                 if (_dict != null) {
  1728.                     return _dict.Count + _keys.Length;
  1729.                 }
  1730.                 else {
  1731.                     return _keys.Length;
  1732.                 }
  1733.             }
  1734.         }
  1735.        
  1736.     }
  1737.    
  1738.     //+================================================================================
  1739.     //
  1740.     // Synopsis: Dictionary enumerator for helper class
  1741.     //
  1742.     //-================================================================================
  1743.     internal class MessageDictionaryEnumerator : IDictionaryEnumerator
  1744.     {
  1745.         private int i = -1;
  1746.         private IDictionaryEnumerator _enumHash;
  1747.         private MessageDictionary _md;
  1748.        
  1749.        
  1750.         public MessageDictionaryEnumerator(MessageDictionary md, IDictionary hashtable)
  1751.         {
  1752.             _md = md;
  1753.             if (hashtable != null) {
  1754.                 _enumHash = hashtable.GetEnumerator();
  1755.             }
  1756.             else {
  1757.                 _enumHash = null;
  1758.             }
  1759.         }
  1760.         // Returns the key of the current element of the enumeration. The returned
  1761.         // value is undefined before the first call to GetNext and following
  1762.         // a call to GetNext that returned false. Multiple calls to
  1763.         // GetKey with no intervening calls to GetNext will return
  1764.         // the same object.
  1765.         //
  1766.         public object Key {
  1767.             get {
  1768.                 Message.DebugOut("MessageDE::GetKey i = " + i + "\n");
  1769.                 if (i < 0) {
  1770.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1771.                 }
  1772.                 if (i < _md._keys.Length) {
  1773.                     return _md._keys[i];
  1774.                 }
  1775.                 else {
  1776.                     BCLDebug.Assert(_enumHash != null, "_enumHash != null");
  1777.                     return _enumHash.Key;
  1778.                 }
  1779.             }
  1780.         }
  1781.        
  1782.         // Returns the value of the current element of the enumeration. The
  1783.         // returned value is undefined before the first call to GetNext and
  1784.         // following a call to GetNext that returned false. Multiple calls
  1785.         // to GetValue with no intervening calls to GetNext will
  1786.         // return the same object.
  1787.         //
  1788.         public object Value {
  1789.             get {
  1790.                 if (i < 0) {
  1791.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1792.                 }
  1793.                
  1794.                 if (i < _md._keys.Length) {
  1795.                     return _md.GetMessageValue(i);
  1796.                 }
  1797.                 else {
  1798.                     BCLDebug.Assert(_enumHash != null, "_enumHash != null");
  1799.                     return _enumHash.Value;
  1800.                 }
  1801.             }
  1802.         }
  1803.        
  1804.         // Advances the enumerator to the next element of the enumeration and
  1805.         // returns a boolean indicating whether an element is available. Upon
  1806.         // creation, an enumerator is conceptually positioned before the first
  1807.         // element of the enumeration, and the first call to GetNext brings
  1808.         // the first element of the enumeration into view.
  1809.         //
  1810.         public bool MoveNext()
  1811.         {
  1812.             if (i == -2) {
  1813.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  1814.             }
  1815.             i++;
  1816.             if (i < _md._keys.Length) {
  1817.                 return true;
  1818.             }
  1819.             else {
  1820.                 if (_enumHash != null && _enumHash.MoveNext()) {
  1821.                     return true;
  1822.                 }
  1823.                 else {
  1824.                     i = -2;
  1825.                     return false;
  1826.                 }
  1827.             }
  1828.         }
  1829.        
  1830.         // Returns the current element of the enumeration. The returned value is
  1831.         // undefined before the first call to MoveNext and following a call
  1832.         // to MoveNext that returned false. Multiple calls to
  1833.         // Current with no intervening calls to MoveNext will return
  1834.         // the same object.
  1835.         //
  1836.         public object Current {
  1837.             get { return Entry; }
  1838.         }
  1839.        
  1840.         public DictionaryEntry Entry {
  1841.             get { return new DictionaryEntry(Key, Value); }
  1842.         }
  1843.        
  1844.         // Resets the enumerator, positioning it before the first element. If an
  1845.         // Enumerator doesn't support Reset, a NotSupportedException is
  1846.         // thrown.
  1847.         public void Reset()
  1848.         {
  1849.             i = -1;
  1850.             if (_enumHash != null) {
  1851.                 _enumHash.Reset();
  1852.             }
  1853.         }
  1854.     }
  1855.    
  1856.     //+================================================================================
  1857.     //
  1858.     // Synopsis: Message for return from a stack blit call
  1859.     //
  1860.     //-================================================================================
  1861.     internal class StackBasedReturnMessage : IMethodReturnMessage, IInternalMessage
  1862.     {
  1863.         Message _m;
  1864.         Hashtable _h;
  1865.         MRMDictionary _d;
  1866.         ArgMapper _argMapper;
  1867.        
  1868.         internal StackBasedReturnMessage()
  1869.         {
  1870.         }
  1871.        
  1872.         // NOTE: This method is called multiple times as we reuse the
  1873.         // message object. Make sure that you reset any fields that you
  1874.         // add to the message object to the default values. This will
  1875.         // ensure that the reused message object starts with the correct
  1876.         // values.
  1877.         internal void InitFields(Message m)
  1878.         {
  1879.             _m = m;
  1880.             if (null != _h) {
  1881.                 // Remove all the hashtable entries
  1882.                 _h.Clear();
  1883.             }
  1884.             if (null != _d) {
  1885.                 // Remove all the dictionary entries
  1886.                 _d.Clear();
  1887.             }
  1888.         }
  1889.        
  1890.         public string Uri {
  1891.             get { return _m.Uri; }
  1892.         }
  1893.         public string MethodName {
  1894.             get { return _m.MethodName; }
  1895.         }
  1896.         public string TypeName {
  1897.             get { return _m.TypeName; }
  1898.         }
  1899.         public object MethodSignature {
  1900.             get { return _m.MethodSignature; }
  1901.         }
  1902.         public MethodBase MethodBase {
  1903.             get { return _m.MethodBase; }
  1904.         }
  1905.         public bool HasVarArgs {
  1906.             get { return _m.HasVarArgs; }
  1907.         }
  1908.        
  1909.         public int ArgCount {
  1910.             get { return _m.ArgCount; }
  1911.         }
  1912.         public object GetArg(int argNum)
  1913.         {
  1914.             return _m.GetArg(argNum);
  1915.         }
  1916.         public string GetArgName(int index)
  1917.         {
  1918.             return _m.GetArgName(index);
  1919.         }
  1920.         public object[] Args {
  1921.             get { return _m.Args; }
  1922.         }
  1923.         public LogicalCallContext LogicalCallContext {
  1924.             get { return _m.GetLogicalCallContext(); }
  1925.         }
  1926.        
  1927.         internal LogicalCallContext GetLogicalCallContext()
  1928.         {
  1929.             return _m.GetLogicalCallContext();
  1930.         }
  1931.         internal LogicalCallContext SetLogicalCallContext(LogicalCallContext callCtx)
  1932.         {
  1933.             return _m.SetLogicalCallContext(callCtx);
  1934.         }
  1935.        
  1936.         public int OutArgCount {
  1937.             get {
  1938.                 if (_argMapper == null)
  1939.                     _argMapper = new ArgMapper(this, true);
  1940.                 return _argMapper.ArgCount;
  1941.             }
  1942.         }
  1943.        
  1944.         public object GetOutArg(int argNum)
  1945.         {
  1946.             if (_argMapper == null)
  1947.                 _argMapper = new ArgMapper(this, true);
  1948.             return _argMapper.GetArg(argNum);
  1949.         }
  1950.        
  1951.         public string GetOutArgName(int index)
  1952.         {
  1953.             if (_argMapper == null)
  1954.                 _argMapper = new ArgMapper(this, true);
  1955.             return _argMapper.GetArgName(index);
  1956.         }
  1957.         public object[] OutArgs {
  1958.             get {
  1959.                 if (_argMapper == null)
  1960.                     _argMapper = new ArgMapper(this, true);
  1961.                 return _argMapper.Args;
  1962.             }
  1963.         }
  1964.        
  1965.         public Exception Exception {
  1966.             get { return null; }
  1967.         }
  1968.         public object ReturnValue {
  1969.             get { return _m.GetReturnValue(); }
  1970.         }
  1971.        
  1972.         public IDictionary Properties {
  1973.             get {
  1974.                 lock (this) {
  1975.                     if (_h == null) {
  1976.                         _h = new Hashtable();
  1977.                     }
  1978.                     if (_d == null) {
  1979.                         _d = new MRMDictionary(this, _h);
  1980.                     }
  1981.                     return _d;
  1982.                 }
  1983.             }
  1984.         }
  1985.        
  1986.         //
  1987.         // IInternalMessage
  1988.         //
  1989.        
  1990.         ServerIdentity IInternalMessage.ServerIdentityObject {
  1991.             get { return null; }
  1992.             set { }
  1993.         }
  1994.        
  1995.         Identity IInternalMessage.IdentityObject {
  1996.             get { return null; }
  1997.             set { }
  1998.         }
  1999.        
  2000.         void IInternalMessage.SetURI(string val)
  2001.         {
  2002.             _m.Uri = val;
  2003.         }
  2004.        
  2005.         void IInternalMessage.SetCallContext(LogicalCallContext newCallContext)
  2006.         {
  2007.             _m.SetLogicalCallContext(newCallContext);
  2008.         }
  2009.        
  2010.         bool IInternalMessage.HasProperties()
  2011.         {
  2012.             return _h != null;
  2013.         }
  2014.     }
  2015.     // class StackBasedReturnMessage
  2016.    
  2017.     //+================================================================================
  2018.     //
  2019.     // Synopsis: Message for return from a stack builder sink call
  2020.     //
  2021.     //-================================================================================
  2022.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  2023.     [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  2024.     [System.Runtime.InteropServices.ComVisible(true)]
  2025.     public class ReturnMessage : IMethodReturnMessage
  2026.     {
  2027.         internal object _ret;
  2028.         internal object _properties;
  2029.         internal string _URI;
  2030.         internal Exception _e;
  2031.         internal object[] _outArgs;
  2032.         internal int _outArgsCount;
  2033.         internal string _methodName;
  2034.         internal string _typeName;
  2035.         internal Type[] _methodSignature;
  2036.         internal bool _hasVarArgs;
  2037.         internal LogicalCallContext _callContext;
  2038.         internal ArgMapper _argMapper;
  2039.         internal MethodBase _methodBase;
  2040.        
  2041.         public ReturnMessage(object ret, object[] outArgs, int outArgsCount, LogicalCallContext callCtx, IMethodCallMessage mcm)
  2042.         {
  2043.             _ret = ret;
  2044.             _outArgs = outArgs;
  2045.             _outArgsCount = outArgsCount;
  2046.            
  2047.             if (callCtx != null)
  2048.                 _callContext = callCtx;
  2049.             else
  2050.                 _callContext = CallContext.GetLogicalCallContext();
  2051.            
  2052.             if (mcm != null) {
  2053.                 _URI = mcm.Uri;
  2054.                 _methodName = mcm.MethodName;
  2055.                 _methodSignature = null;
  2056.                 _typeName = mcm.TypeName;
  2057.                 _hasVarArgs = mcm.HasVarArgs;
  2058.                 _methodBase = mcm.MethodBase;
  2059.             }
  2060.         }
  2061.        
  2062.         public ReturnMessage(Exception e, IMethodCallMessage mcm)
  2063.         {
  2064.             _e = IsCustomErrorEnabled() ? new RemotingException(Environment.GetResourceString("Remoting_InternalError")) : e;
  2065.             _callContext = CallContext.GetLogicalCallContext();
  2066.             if (mcm != null) {
  2067.                 _URI = mcm.Uri;
  2068.                 _methodName = mcm.MethodName;
  2069.                 _methodSignature = null;
  2070.                 _typeName = mcm.TypeName;
  2071.                 _hasVarArgs = mcm.HasVarArgs;
  2072.                 _methodBase = mcm.MethodBase;
  2073.             }
  2074.         }
  2075.        
  2076.         public string Uri {
  2077.             get { return _URI; }
  2078.             set { _URI = value; }
  2079.         }
  2080.         public string MethodName {
  2081.             get { return _methodName; }
  2082.         }
  2083.         public string TypeName {
  2084.             get { return _typeName; }
  2085.         }
  2086.         public object MethodSignature {
  2087.             get {
  2088.                 if ((_methodSignature == null) && (_methodBase != null))
  2089.                     _methodSignature = Message.GenerateMethodSignature(_methodBase);
  2090.                
  2091.                 return _methodSignature;
  2092.             }
  2093.         }
  2094.        
  2095.         public MethodBase MethodBase {
  2096.             get { return _methodBase; }
  2097.         }
  2098.        
  2099.         public bool HasVarArgs {
  2100.             get { return _hasVarArgs; }
  2101.         }
  2102.        
  2103.        
  2104.         public int ArgCount {
  2105.             get {
  2106.                 if (_outArgs == null) {
  2107.                     return _outArgsCount;
  2108.                 }
  2109.                 else {
  2110.                     return _outArgs.Length;
  2111.                 }
  2112.             }
  2113.         }
  2114.        
  2115.         public object GetArg(int argNum)
  2116.         {
  2117.             if (_outArgs == null) {
  2118.                 if ((argNum < 0) || (argNum >= _outArgsCount)) {
  2119.                     throw new ArgumentOutOfRangeException("argNum");
  2120.                 }
  2121.                 return null;
  2122.             }
  2123.             else {
  2124.                 if ((argNum < 0) || (argNum >= _outArgs.Length)) {
  2125.                     throw new ArgumentOutOfRangeException("argNum");
  2126.                 }
  2127.                 return _outArgs[argNum];
  2128.             }
  2129.            
  2130.         }
  2131.        
  2132.         public string GetArgName(int index)
  2133.         {
  2134.            
  2135.             if (_outArgs == null) {
  2136.                 if ((index < 0) || (index >= _outArgsCount)) {
  2137.                     throw new ArgumentOutOfRangeException("index");
  2138.                 }
  2139.             }
  2140.             else {
  2141.                 if ((index < 0) || (index >= _outArgs.Length)) {
  2142.                     throw new ArgumentOutOfRangeException("index");
  2143.                 }
  2144.             }
  2145.            
  2146.             if (_methodBase != null) {
  2147.                 RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(_methodBase);
  2148.                 return methodCache.Parameters[index].Name;
  2149.             }
  2150.             else
  2151.                 return "__param" + index;
  2152.         }
  2153.        
  2154.         public object[] Args {
  2155.             get {
  2156.                 if (_outArgs == null) {
  2157.                     return new object[_outArgsCount];
  2158.                 }
  2159.                 return _outArgs;
  2160.             }
  2161.         }
  2162.        
  2163.         public int OutArgCount {
  2164.             get {
  2165.                 if (_argMapper == null)
  2166.                     _argMapper = new ArgMapper(this, true);
  2167.                 return _argMapper.ArgCount;
  2168.             }
  2169.         }
  2170.        
  2171.         public object GetOutArg(int argNum)
  2172.         {
  2173.             if (_argMapper == null)
  2174.                 _argMapper = new ArgMapper(this, true);
  2175.             return _argMapper.GetArg(argNum);
  2176.         }
  2177.        
  2178.         public string GetOutArgName(int index)
  2179.         {
  2180.             if (_argMapper == null)
  2181.                 _argMapper = new ArgMapper(this, true);
  2182.             return _argMapper.GetArgName(index);
  2183.         }
  2184.         public object[] OutArgs {
  2185.             get {
  2186.                 if (_argMapper == null)
  2187.                     _argMapper = new ArgMapper(this, true);
  2188.                 return _argMapper.Args;
  2189.             }
  2190.         }
  2191.        
  2192.         public Exception Exception {
  2193.             get { return _e; }
  2194.         }
  2195.         public virtual object ReturnValue {
  2196.             get { return _ret; }
  2197.         }
  2198.        
  2199.         public virtual IDictionary Properties {
  2200.             get {
  2201.                 if (_properties == null) {
  2202.                     _properties = new MRMDictionary(this, null);
  2203.                 }
  2204.                 return (MRMDictionary)_properties;
  2205.             }
  2206.         }
  2207.        
  2208.         public LogicalCallContext LogicalCallContext {
  2209.             get { return GetLogicalCallContext(); }
  2210.         }
  2211.        
  2212.        
  2213.         internal LogicalCallContext GetLogicalCallContext()
  2214.         {
  2215.             if (_callContext == null)
  2216.                 _callContext = new LogicalCallContext();
  2217.             return _callContext;
  2218.         }
  2219.        
  2220.         internal LogicalCallContext SetLogicalCallContext(LogicalCallContext ctx)
  2221.         {
  2222.             LogicalCallContext old = _callContext;
  2223.             _callContext = ctx;
  2224.             return old;
  2225.         }
  2226.        
  2227.         // used to determine if the properties dictionary has already been created
  2228.         internal bool HasProperties()
  2229.         {
  2230.             return _properties != null;
  2231.         }
  2232.         static internal bool IsCustomErrorEnabled()
  2233.         {
  2234.             object oIsCustomErrorEnabled = CallContext.GetData("__CustomErrorsEnabled");
  2235.             // The server side will always have this CallContext item set. If it is not set then
  2236.             // it means this is the client side. In that case customError is false.
  2237.             return (oIsCustomErrorEnabled == null) ? false : (bool)oIsCustomErrorEnabled;
  2238.         }
  2239.        
  2240.     }
  2241.     // class ReturnMessage
  2242.     //+================================================================================
  2243.     //
  2244.     // Synopsis: Message used for deserialization of a method call
  2245.     //
  2246.     //-================================================================================
  2247.     /// <internalonly/>
  2248.     [Serializable(), CLSCompliant(false)]
  2249.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  2250.     [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  2251.     [System.Runtime.InteropServices.ComVisible(true)]
  2252.     public class MethodCall : IMethodCallMessage, ISerializable, IInternalMessage, ISerializationRootObject
  2253.     {
  2254.        
  2255.         private const BindingFlags LookupAll = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
  2256.         private const BindingFlags LookupPublic = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
  2257.        
  2258.         // data
  2259.         private string uri;
  2260.         private string methodName;
  2261.         private MethodBase MI;
  2262.         private string typeName;
  2263.         private object[] args;
  2264.         private Type[] instArgs;
  2265.         private LogicalCallContext callContext;
  2266.         private Type[] methodSignature;
  2267.         /// <internalonly/>
  2268.         protected IDictionary ExternalProperties = null;
  2269.         /// <internalonly/>
  2270.         protected IDictionary InternalProperties = null;
  2271.        
  2272.         private ServerIdentity srvID;
  2273.         private Identity identity;
  2274.         private bool fSoap;
  2275.         private bool fVarArgs = false;
  2276.         private ArgMapper argMapper;
  2277.        
  2278.         //
  2279.         // MethodCall -- SOAP uses this constructor
  2280.         //
  2281.        
  2282.         /// <internalonly/>
  2283.         public MethodCall(Header[] h1)
  2284.         {
  2285.             Message.DebugOut("MethodCall ctor IN headers: " + (h1 == null ? "<null>" : h1.ToString()) + "\n");
  2286.            
  2287.             Init();
  2288.            
  2289.             fSoap = true;
  2290.             FillHeaders(h1);
  2291.            
  2292.             ResolveMethod();
  2293.            
  2294.             Message.DebugOut("MethodCall ctor OUT\n");
  2295.         }
  2296.        
  2297.         //
  2298.         // MethodCall -- this constructor is used for copying an existing message
  2299.         //
  2300.        
  2301.         public MethodCall(IMessage msg)
  2302.         {
  2303.             if (msg == null)
  2304.                 throw new ArgumentNullException("msg");
  2305.            
  2306.             Init();
  2307.            
  2308.             IDictionaryEnumerator de = msg.Properties.GetEnumerator();
  2309.             while (de.MoveNext()) {
  2310.                 FillHeader(de.Key.ToString(), de.Value);
  2311.             }
  2312.            
  2313.             IMethodCallMessage mcm = msg as IMethodCallMessage;
  2314.             if (mcm != null)
  2315.                
  2316.                 MI = mcm.MethodBase;
  2317.            
  2318.             ResolveMethod();
  2319.         }
  2320.        
  2321.         internal MethodCall(SerializationInfo info, StreamingContext context)
  2322.         {
  2323.             if (info == null)
  2324.                 throw new ArgumentNullException("info");
  2325.             Init();
  2326.            
  2327.             SetObjectData(info, context);
  2328.         }
  2329.        
  2330.        
  2331.         internal MethodCall(SmuggledMethodCallMessage smuggledMsg, ArrayList deserializedArgs)
  2332.         {
  2333.             uri = smuggledMsg.Uri;
  2334.             typeName = smuggledMsg.TypeName;
  2335.             methodName = smuggledMsg.MethodName;
  2336.             methodSignature = (Type[])smuggledMsg.GetMethodSignature(deserializedArgs);
  2337.             args = smuggledMsg.GetArgs(deserializedArgs);
  2338.             instArgs = smuggledMsg.GetInstantiation(deserializedArgs);
  2339.             callContext = smuggledMsg.GetCallContext(deserializedArgs);
  2340.            
  2341.             ResolveMethod();
  2342.            
  2343.             if (smuggledMsg.MessagePropertyCount > 0)
  2344.                 smuggledMsg.PopulateMessageProperties(Properties, deserializedArgs);
  2345.         }
  2346.        
  2347.         internal MethodCall(object handlerObject, BinaryMethodCallMessage smuggledMsg)
  2348.         {
  2349.             if (handlerObject != null) {
  2350.                 uri = handlerObject as string;
  2351.                 if (uri == null) {
  2352.                     // This must be the tranparent proxy
  2353.                     MarshalByRefObject mbr = handlerObject as MarshalByRefObject;
  2354.                     if (mbr != null) {
  2355.                         bool fServer;
  2356.                         srvID = MarshalByRefObject.GetIdentity(mbr, out fServer) as ServerIdentity;
  2357.                         uri = srvID.URI;
  2358.                     }
  2359.                 }
  2360.             }
  2361.            
  2362.             typeName = smuggledMsg.TypeName;
  2363.             methodName = smuggledMsg.MethodName;
  2364.             methodSignature = (Type[])smuggledMsg.MethodSignature;
  2365.             args = smuggledMsg.Args;
  2366.             instArgs = smuggledMsg.InstantiationArgs;
  2367.             callContext = smuggledMsg.LogicalCallContext;
  2368.            
  2369.             ResolveMethod();
  2370.            
  2371.             if (smuggledMsg.HasProperties)
  2372.                 smuggledMsg.PopulateMessageProperties(Properties);
  2373.         }
  2374.        
  2375.        
  2376.        
  2377.         //
  2378.         // ISerializationRootObject
  2379.         //
  2380.         /// <internalonly/>
  2381.         public void RootSetObjectData(SerializationInfo info, StreamingContext ctx)
  2382.         {
  2383.             SetObjectData(info, ctx);
  2384.         }
  2385.        
  2386.         //
  2387.         // SetObjectData -- the class can also be initialized in part or in whole by serialization
  2388.         // in the SOAP case, both the constructor and SetObjectData init the object, in the non-SOAP
  2389.         // case, just SetObjectData is called
  2390.         //
  2391.        
  2392.         internal void SetObjectData(SerializationInfo info, StreamingContext context)
  2393.         {
  2394.             if (info == null)
  2395.                 throw new ArgumentNullException("info");
  2396.            
  2397.             if (fSoap) {
  2398.                 SetObjectFromSoapData(info);
  2399.             }
  2400.             else {
  2401.                 SerializationInfoEnumerator siEnum = info.GetEnumerator();
  2402.                 while (siEnum.MoveNext()) {
  2403.                     FillHeader(siEnum.Name, siEnum.Value);
  2404.                 }
  2405.                 if ((context.State == StreamingContextStates.Remoting) && (context.Context != null)) {
  2406.                     Header[] h = context.Context as Header[];
  2407.                     if (null != h) {
  2408.                         for (int i = 0; i < h.Length; i++)
  2409.                             FillHeader(h[i].Name, h[i].Value);
  2410.                     }
  2411.                 }
  2412.             }
  2413.         }
  2414.         // SetObjectData
  2415.         //
  2416.         // ResolveMethod
  2417.         //
  2418.        
  2419.         internal Type ResolveType()
  2420.         {
  2421.             // resolve type
  2422.             Type t = null;
  2423.            
  2424.             if (srvID == null)
  2425.                 srvID = IdentityHolder.CasualResolveIdentity(uri) as ServerIdentity;
  2426.            
  2427.             if (srvID != null) {
  2428.                 Type serverType = srvID.GetLastCalledType(typeName);
  2429.                 if (serverType != null)
  2430.                     return serverType;
  2431.                 int startIndex = 0;
  2432.                 // start of type name
  2433.                 // check to see if type name starts with "clr:"
  2434.                 if (String.CompareOrdinal(typeName, 0, "clr:", 0, 4) == 0) {
  2435.                     // type starts just past "clr:"
  2436.                     startIndex = 4;
  2437.                 }
  2438.                
  2439.                 // find end of full type name
  2440.                 int index = typeName.IndexOf(',', startIndex);
  2441.                 if (index == -1)
  2442.                     index = typeName.Length;
  2443.                
  2444.                 serverType = srvID.ServerType;
  2445.                 t = Type.ResolveTypeRelativeTo(typeName, startIndex, index - startIndex, serverType);
  2446.             }
  2447.            
  2448.             if (t == null) {
  2449.                 // fall back to Type.GetType() in case someone isn't using
  2450.                 // our convention for the TypeName
  2451.                 t = RemotingServices.InternalGetTypeFromQualifiedTypeName(typeName);
  2452.             }
  2453.             if (srvID != null)
  2454.                 srvID.SetLastCalledType(typeName, t);
  2455.             return t;
  2456.         }
  2457.         // ResolveType
  2458.        
  2459.         /// <internalonly/>
  2460.         public void ResolveMethod()
  2461.         {
  2462.             ResolveMethod(true);
  2463.         }
  2464.        
  2465.         internal void ResolveMethod(bool bThrowIfNotResolved)
  2466.         {
  2467.             if ((MI == null) && (methodName != null)) {
  2468.                 BCLDebug.Trace("REMOTE", "TypeName: " + (typeName == null ? "<null>" : typeName) + "\n");
  2469.                
  2470.                 // resolve type
  2471.                 RuntimeType t = ResolveType() as RuntimeType;
  2472.                
  2473.                 BCLDebug.Trace("REMOTE", "Type: " + (t == null ? "<null>" : t.ToString()) + "\n");
  2474.                 if (methodName.Equals(".ctor"))
  2475.                     return;
  2476.                 if (t == null) {
  2477.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"), typeName));
  2478.                 }
  2479.                
  2480.                 // Note: we reflect on non-public members here .. we do
  2481.                 // block incoming remote calls and allow only specific methods
  2482.                 // that we use for implementation of certain features (eg.
  2483.                 // for remote field access)
  2484.                
  2485.                 // ***********************************************************
  2486.                 // Note: For the common (non-overloaded method, urt-to-urt) case
  2487.                 // methodSignature is null.
  2488.                 // If the call is from a urt client to an overloaded method,
  2489.                 // methodSignature is non-null. We could have a non-null
  2490.                 // methodSignature if the call is from a non-urt client for
  2491.                 // which we have to do special work if the method is overloaded
  2492.                 // (in the try-catch below).
  2493.                 // ***********************************************************
  2494.                 if (null != methodSignature) {
  2495.                     // We might still get an AmbiguousMatchException here if
  2496.                     // there are multiple methods with the same name and
  2497.                     // signature distinguished only by their arity (reflection
  2498.                     // doesn't currently provide a way to filter on this in a
  2499.                     // GetMethod call). This should be reasonably rare, so
  2500.                     // handle the common case efficiently and back off to a
  2501.                     // slower algorithm only if necessary.
  2502.                     try {
  2503.                         MI = t.GetMethod(methodName, MethodCall.LookupAll, null, CallingConventions.Any, methodSignature, null);
  2504.                     }
  2505.                     catch (AmbiguousMatchException) {
  2506.                         // Make a list of all the methods with the right name.
  2507.                         MemberInfo[] methods = t.FindMembers(MemberTypes.Method, MethodCall.LookupAll, Type.FilterName, methodName);
  2508.                        
  2509.                         int arity = instArgs == null ? 0 : instArgs.Length;
  2510.                         int candidates = 0;
  2511.                         for (int i = 0; i < methods.Length; i++) {
  2512.                             MethodInfo mi = (MethodInfo)methods[i];
  2513.                             int miArity = mi.IsGenericMethod ? mi.GetGenericArguments().Length : 0;
  2514.                             if (miArity == arity) {
  2515.                                 // Got a candidate, compress it back to the
  2516.                                 // start of the array if necessary.
  2517.                                 if (i > candidates)
  2518.                                     methods[candidates] = methods[i];
  2519.                                 candidates++;
  2520.                             }
  2521.                         }
  2522.                         MethodInfo[] matches = new MethodInfo[candidates];
  2523.                         for (int i = 0; i < candidates; i++)
  2524.                             matches[i] = (MethodInfo)methods[i];
  2525.                        
  2526.                         // Use the default binder to select the right overload
  2527.                         // based on signature.
  2528.                         MI = Type.DefaultBinder.SelectMethod(MethodCall.LookupAll, matches, methodSignature, null);
  2529.                     }
  2530.                    
  2531.                     if (instArgs != null && instArgs.Length > 0)
  2532.                         MI = ((MethodInfo)MI).MakeGenericMethod(instArgs);
  2533.                    
  2534.                     BCLDebug.Trace("REMOTE", "Method resolved w/sig ", MI == null ? "<null>" : "<not null>");
  2535.                 }
  2536.                 else {
  2537.                    
  2538.                     // Check the cache to see if you find the methodbase (unless
  2539.                     // the method has an instantiation, in which case the method
  2540.                     // name is not a unique key).
  2541.                     RemotingTypeCachedData typeCache = null;
  2542.                     if (instArgs == null) {
  2543.                         typeCache = InternalRemotingServices.GetReflectionCachedData(t);
  2544.                         MI = typeCache.GetLastCalledMethod(methodName);
  2545.                         if (MI != null)
  2546.                             return;
  2547.                     }
  2548.                    
  2549.                    
  2550.                     BCLDebug.Assert(!methodName.Equals(".ctor"), "unexpected method type");
  2551.                    
  2552.                     bool bOverloaded = false;
  2553.                    
  2554.                     try {
  2555.                         MI = t.GetMethod(methodName, MethodCall.LookupAll);
  2556.                        
  2557.                         if (instArgs != null && instArgs.Length > 0)
  2558.                             MI = ((MethodInfo)MI).MakeGenericMethod(instArgs);
  2559.                        
  2560.                         BCLDebug.Trace("REMOTE", "Method resolved w/name ", MI == null ? "<null>" : methodName);
  2561.                         BCLDebug.Trace("REMOTE", "sig not filled in!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  2562.                     }
  2563.                     catch (AmbiguousMatchException) {
  2564.                         // This is the case when no methodSignature was found
  2565.                         // but the method is overloaded ..
  2566.                         // (possibly because a non-URT client called us)
  2567.                         bOverloaded = true;
  2568.                         ResolveOverloadedMethod(t);
  2569.                     }
  2570.                     //catch
  2571.                     // In the non-URT call, overloaded case, don't cache the MI
  2572.                     // Avoid caching generic methods -- their names aren't a unique key.
  2573.                     if (MI != null && !bOverloaded && typeCache != null)
  2574.                         typeCache.SetLastCalledMethod(methodName, MI);
  2575.                 }
  2576.                
  2577.                 if (MI == null && bThrowIfNotResolved) {
  2578.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_MethodMissing"), methodName, typeName));
  2579.                 }
  2580.             }
  2581.         }
  2582.        
  2583.         // Helper that gets called when we attempt to resolve a method
  2584.         // without an accompanying methodSignature ... current thinking is
  2585.         // that we should make a good faith attempt by matching argument
  2586.         // counts
  2587.        
  2588.         void ResolveOverloadedMethod(RuntimeType t)
  2589.         {
  2590.             // args is null the first call from soap because we havem't passed the arguments yet.
  2591.             if (args == null)
  2592.                 return;
  2593.            
  2594.             MemberInfo[] canidates = t.GetMember(methodName, MemberTypes.Method, MethodCall.LookupPublic);
  2595.            
  2596.             int canidatesCount = canidates.Length;
  2597.            
  2598.             if (canidatesCount == 1) {
  2599.                 MI = canidates[0] as MethodBase;
  2600.                 return;
  2601.             }
  2602.            
  2603.             if (canidatesCount == 0)
  2604.                 return;
  2605.            
  2606.             int argCount = args.Length;
  2607.             MethodBase match = null;
  2608.            
  2609.             // We will let resolve succeed if exactly one of the overloaded methods matches in terms of argCount
  2610.             for (int i = 0; i < canidatesCount; i++) {
  2611.                 MethodBase canidate = canidates[i] as MethodBase;
  2612.                 if (canidate.GetParameters().Length == argCount) {
  2613.                     if (match != null)
  2614.                         throw new RemotingException(Environment.GetResourceString("Remoting_AmbiguousMethod"));
  2615.                    
  2616.                     match = canidate;
  2617.                 }
  2618.             }
  2619.            
  2620.             if (match != null)
  2621.                 MI = match;
  2622.         }
  2623.        
  2624.         void ResolveOverloadedMethod(RuntimeType t, string methodName, ArrayList argNames, ArrayList argValues)
  2625.         {
  2626.             MemberInfo[] canidates = t.GetMember(methodName, MemberTypes.Method, MethodCall.LookupPublic);
  2627.            
  2628.             int canidatesCount = canidates.Length;
  2629.            
  2630.             if (canidatesCount == 1) {
  2631.                 MI = canidates[0] as MethodBase;
  2632.                 return;
  2633.             }
  2634.            
  2635.            
  2636.             if (canidatesCount == 0)
  2637.                 return;
  2638.            
  2639.             int argCount = args.Length;
  2640.             MethodBase match = null;
  2641.            
  2642.             for (int i = 0; i < canidatesCount; i++) {
  2643.                 MethodBase canidate = canidates[i] as MethodBase;
  2644.                
  2645.                 ParameterInfo[] parameters = canidate.GetParameters();
  2646.                
  2647.                 if (parameters.Length == argValues.Count) {
  2648.                     for (int j = 0; j < parameters.Length; j++) {
  2649.                         Type parameterType = parameters[j].ParameterType;
  2650.                        
  2651.                         if (parameterType.IsByRef)
  2652.                             parameterType = parameterType.GetElementType();
  2653.                        
  2654.                         if (parameterType != argValues[j].GetType()) {
  2655.                             match = canidate;
  2656.                             break;
  2657.                         }
  2658.                        
  2659.                     }
  2660.                    
  2661.                     if (match != null)
  2662.                         break;
  2663.                 }
  2664.                
  2665.                 if (match == null)
  2666.                     throw new RemotingException(Environment.GetResourceString("Remoting_AmbiguousMethod"));
  2667.             }
  2668.            
  2669.             if (match != null)
  2670.                 MI = match;
  2671.         }
  2672.        
  2673.         //
  2674.         // GetObjectData -- not implemented
  2675.         //
  2676.        
  2677.         /// <internalonly/>
  2678.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
  2679.         public void GetObjectData(SerializationInfo info, StreamingContext context)
  2680.         {
  2681.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_Method"));
  2682.         }
  2683.        
  2684.         //
  2685.         // SetObjectFromSoapData -- parses soap format for serialization data
  2686.         //
  2687.        
  2688.         internal void SetObjectFromSoapData(SerializationInfo info)
  2689.         {
  2690.             // resolve method
  2691.             methodName = info.GetString("__methodName");
  2692.             ArrayList paramNames = (ArrayList)info.GetValue("__paramNameList", typeof(ArrayList));
  2693.            
  2694.             Hashtable keyToNamespaceTable = (Hashtable)info.GetValue("__keyToNamespaceTable", typeof(Hashtable));
  2695.            
  2696.             if (MI == null) {
  2697.                 // This is the case where
  2698.                 // 1) there is no signature in the header,
  2699.                 // 2) there is an overloaded method which can not be resolved by a difference in the number of parameters.
  2700.                 //
  2701.                 // The methodbase can be found only if the parameters from soap have type information
  2702.                 ArrayList argValues = new ArrayList();
  2703.                 ArrayList argNames = paramNames;
  2704.                 // SerializationInfoEnumerator siEnum1 = info.GetEnumerator();
  2705.                 for (int i = 0; i < argNames.Count; i++) {
  2706.                     argValues.Add(info.GetValue((string)argNames[i], typeof(object)));
  2707.                 }
  2708.                
  2709.                 //ambiguous member, try to find methodBase using actual argment types (if available)
  2710.                 RuntimeType t = ResolveType() as RuntimeType;
  2711.                 if (t == null) {
  2712.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"), typeName));
  2713.                 }
  2714.                
  2715.                 ResolveOverloadedMethod(t, methodName, argNames, argValues);
  2716.                
  2717.                 if (MI == null) {
  2718.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_MethodMissing"), methodName, typeName));
  2719.                 }
  2720.             }
  2721.             //ResolveMethod();
  2722.            
  2723.            
  2724.             //BCLDebug.Assert(null != MI, "null != MI");
  2725.            
  2726.             // get method parameters and parameter maps
  2727.             RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
  2728.             ParameterInfo[] pinfos = methodCache.Parameters;
  2729.             int[] marshalRequestArgMap = methodCache.MarshalRequestArgMap;
  2730.             int[] outOnlyArgMap = methodCache.OutOnlyArgMap;
  2731.            
  2732.             // check to see if parameters are in-order
  2733.             object fUnordered = (null == InternalProperties ? null : InternalProperties["__UnorderedParams"]);
  2734.            
  2735.             // Create an array for arguments
  2736.             args = new object[pinfos.Length];
  2737.            
  2738.             //SerializationInfoEnumerator siEnum = info.GetEnumerator();
  2739.            
  2740.             // Fill up the argument array
  2741.             if (fUnordered != null && (fUnordered is bool) && (true == (bool)fUnordered)) {
  2742.                 string memberName;
  2743.                
  2744.                 for (int i = 0; i < paramNames.Count; i++) {
  2745.                     memberName = (string)paramNames[i];
  2746.                     Message.DebugOut("MethodCall::PopulateData members[i].Name: " + memberName + " substring:>>" + memberName.Substring(7) + "<<\n");
  2747.                    
  2748.                     int position = -1;
  2749.                     for (int j = 0; j < pinfos.Length; j++) {
  2750.                         if (memberName.Equals(pinfos[j].Name)) {
  2751.                             position = pinfos[j].Position;
  2752.                             break;
  2753.                         }
  2754.                     }
  2755.                    
  2756.                     if (position == -1) {
  2757.                         if (!memberName.StartsWith("__param", StringComparison.Ordinal)) {
  2758.                             throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadSerialization"));
  2759.                         }
  2760.                         position = Int32.Parse(memberName.Substring(7), CultureInfo.InvariantCulture);
  2761.                     }
  2762.                     if (position >= args.Length) {
  2763.                         throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadSerialization"));
  2764.                     }
  2765.                     args[position] = Message.SoapCoerceArg(info.GetValue(memberName, typeof(object)), pinfos[position].ParameterType, keyToNamespaceTable);
  2766.                 }
  2767.             }
  2768.             else {
  2769.                 for (int i = 0; i < paramNames.Count; i++) {
  2770.                     string memberName = (string)paramNames[i];
  2771.                     args[marshalRequestArgMap[i]] = Message.SoapCoerceArg(info.GetValue(memberName, typeof(object)), pinfos[marshalRequestArgMap[i]].ParameterType, keyToNamespaceTable);
  2772.                 }
  2773.                
  2774.                 // We need to have a dummy object in the array for out parameters
  2775.                 // that have value types.
  2776.                 foreach (int outArg in outOnlyArgMap) {
  2777.                     Type type = pinfos[outArg].ParameterType.GetElementType();
  2778.                     if (type.IsValueType)
  2779.                         args[outArg] = Activator.CreateInstance(type, true);
  2780.                 }
  2781.             }
  2782.         }
  2783.         // SetObjectFromSoapData
  2784.         //
  2785.         // Init -- constructor helper for for default behavior
  2786.         //
  2787.        
  2788.         /// <internalonly/>
  2789.         public virtual void Init()
  2790.         {
  2791.         }
  2792.        
  2793.         //
  2794.         // IMethodCallMessage
  2795.         //
  2796.        
  2797.         /// <internalonly/>
  2798.         public int ArgCount {
  2799.             get { return (args == null) ? 0 : args.Length; }
  2800.         }
  2801.        
  2802.         /// <internalonly/>
  2803.         public object GetArg(int argNum)
  2804.         {
  2805.             return args[argNum];
  2806.         }
  2807.        
  2808.         /// <internalonly/>
  2809.         public string GetArgName(int index)
  2810.         {
  2811.             ResolveMethod();
  2812.            
  2813.             RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
  2814.             return methodCache.Parameters[index].Name;
  2815.         }
  2816.        
  2817.         /// <internalonly/>
  2818.         public object[] Args {
  2819.             get { return args; }
  2820.         }
  2821.        
  2822.        
  2823.         /// <internalonly/>
  2824.         public int InArgCount {
  2825.             get {
  2826.                 if (argMapper == null)
  2827.                     argMapper = new ArgMapper(this, false);
  2828.                 return argMapper.ArgCount;
  2829.             }
  2830.         }
  2831.        
  2832.         /// <internalonly/>
  2833.         public object GetInArg(int argNum)
  2834.         {
  2835.             if (argMapper == null)
  2836.                 argMapper = new ArgMapper(this, false);
  2837.             return argMapper.GetArg(argNum);
  2838.         }
  2839.        
  2840.         /// <internalonly/>
  2841.         public string GetInArgName(int index)
  2842.         {
  2843.             if (argMapper == null)
  2844.                 argMapper = new ArgMapper(this, false);
  2845.             return argMapper.GetArgName(index);
  2846.         }
  2847.         /// <internalonly/>
  2848.         public object[] InArgs {
  2849.             get {
  2850.                 if (argMapper == null)
  2851.                     argMapper = new ArgMapper(this, false);
  2852.                 return argMapper.Args;
  2853.             }
  2854.         }
  2855.        
  2856.         /// <internalonly/>
  2857.         public string MethodName {
  2858.             get { return methodName; }
  2859.         }
  2860.         /// <internalonly/>
  2861.         public string TypeName {
  2862.             get { return typeName; }
  2863.         }
  2864.         /// <internalonly/>
  2865.         public object MethodSignature {
  2866.             get {
  2867.                 if (methodSignature != null)
  2868.                     return methodSignature;
  2869.                 else if (MI != null)
  2870.                     methodSignature = Message.GenerateMethodSignature(this.MethodBase);
  2871.                
  2872.                 return null;
  2873.             }
  2874.         }
  2875.        
  2876.         /// <internalonly/>
  2877.         public MethodBase MethodBase {
  2878.             get {
  2879.                 if (MI == null)
  2880.                     MI = RemotingServices.InternalGetMethodBaseFromMethodMessage(this);
  2881.                 return MI;
  2882.             }
  2883.         }
  2884.        
  2885.         /// <internalonly/>
  2886.         public string Uri {
  2887.             get { return uri; }
  2888.             set { uri = value; }
  2889.         }
  2890.        
  2891.         /// <internalonly/>
  2892.         public bool HasVarArgs {
  2893.             get { return fVarArgs; }
  2894.         }
  2895.        
  2896.         /// <internalonly/>
  2897.         public virtual IDictionary Properties {
  2898.             get {
  2899.                 lock (this) {
  2900.                     if (InternalProperties == null) {
  2901.                         InternalProperties = new Hashtable();
  2902.                     }
  2903.                     if (ExternalProperties == null) {
  2904.                         ExternalProperties = new MCMDictionary(this, InternalProperties);
  2905.                     }
  2906.                     return ExternalProperties;
  2907.                 }
  2908.             }
  2909.         }
  2910.        
  2911.         /// <internalonly/>
  2912.         public LogicalCallContext LogicalCallContext {
  2913.             get { return GetLogicalCallContext(); }
  2914.         }
  2915.         internal LogicalCallContext GetLogicalCallContext()
  2916.         {
  2917.             if (callContext == null)
  2918.                 callContext = new LogicalCallContext();
  2919.             return callContext;
  2920.         }
  2921.        
  2922.         internal LogicalCallContext SetLogicalCallContext(LogicalCallContext ctx)
  2923.         {
  2924.             LogicalCallContext old = callContext;
  2925.             callContext = ctx;
  2926.             return old;
  2927.         }
  2928.        
  2929.         //
  2930.         // IInternalMessage
  2931.         //
  2932.        
  2933.         /// <internalonly/>
  2934.         ServerIdentity IInternalMessage.ServerIdentityObject {
  2935.             get { return srvID; }
  2936.             set { srvID = value; }
  2937.         }
  2938.        
  2939.         /// <internalonly/>
  2940.         Identity IInternalMessage.IdentityObject {
  2941.             get { return identity; }
  2942.             set { identity = value; }
  2943.         }
  2944.        
  2945.         /// <internalonly/>
  2946.         void IInternalMessage.SetURI(string val)
  2947.         {
  2948.             uri = val;
  2949.         }
  2950.        
  2951.         /// <internalonly/>
  2952.         void IInternalMessage.SetCallContext(LogicalCallContext newCallContext)
  2953.         {
  2954.             callContext = newCallContext;
  2955.         }
  2956.        
  2957.         /// <internalonly/>
  2958.         bool IInternalMessage.HasProperties()
  2959.         {
  2960.             return (ExternalProperties != null) || (InternalProperties != null);
  2961.         }
  2962.        
  2963.         //
  2964.         // helper functions
  2965.         //
  2966.        
  2967.         internal void FillHeaders(Header[] h)
  2968.         {
  2969.             FillHeaders(h, false);
  2970.         }
  2971.        
  2972.         private void FillHeaders(Header[] h, bool bFromHeaderHandler)
  2973.         {
  2974.             if (h == null)
  2975.                 return;
  2976.            
  2977.             if (bFromHeaderHandler && fSoap) {
  2978.                 // Handle the case of headers coming off the wire in SOAP.
  2979.                
  2980.                 // look for message properties
  2981.                 int co;
  2982.                 for (co = 0; co < h.Length; co++) {
  2983.                     Header header = h[co];
  2984.                     if (header.HeaderNamespace == "http://schemas.microsoft.com/clr/soap/messageProperties") {
  2985.                         // add property to the message
  2986.                         FillHeader(header.Name, header.Value);
  2987.                     }
  2988.                     else {
  2989.                         // add header to the message as a header
  2990.                         string name = LogicalCallContext.GetPropertyKeyForHeader(header);
  2991.                         FillHeader(name, header);
  2992.                     }
  2993.                 }
  2994.             }
  2995.             else {
  2996.                 int i;
  2997.                 for (i = 0; i < h.Length; i++) {
  2998.                     FillHeader(h[i].Name, h[i].Value);
  2999.                 }
  3000.             }
  3001.         }
  3002.        
  3003.         internal virtual bool FillSpecialHeader(string key, object value)
  3004.         {
  3005.             if (key == null) {
  3006.                 //skip
  3007.             }
  3008.             else if (key.Equals("__Uri")) {
  3009.                 uri = (string)value;
  3010.             }
  3011.             else if (key.Equals("__MethodName")) {
  3012.                 methodName = (string)value;
  3013.             }
  3014.             else if (key.Equals("__MethodSignature")) {
  3015.                 methodSignature = (Type[])value;
  3016.             }
  3017.             else if (key.Equals("__TypeName")) {
  3018.                 typeName = (string)value;
  3019.             }
  3020.             else if (key.Equals("__Args")) {
  3021.                 args = (object[])value;
  3022.             }
  3023.             else if (key.Equals("__CallContext")) {
  3024.                 // if the value is a string, then its the LogicalCallId
  3025.                 if (value is string) {
  3026.                     callContext = new LogicalCallContext();
  3027.                     callContext.RemotingData.LogicalCallID = (string)value;
  3028.                 }
  3029.                 else
  3030.                     callContext = (LogicalCallContext)value;
  3031.             }
  3032.             else {
  3033.                 return false;
  3034.             }
  3035.             return true;
  3036.         }
  3037.         internal void FillHeader(string key, object value)
  3038.         {
  3039.             Message.DebugOut("MethodCall::FillHeader: key:" + key + "\n");
  3040.            
  3041.             if (!FillSpecialHeader(key, value)) {
  3042.                 if (InternalProperties == null) {
  3043.                     InternalProperties = new Hashtable();
  3044.                 }
  3045.                 InternalProperties[key] = value;
  3046.             }
  3047.            
  3048.         }
  3049.        
  3050.         /// <internalonly/>
  3051.         public virtual object HeaderHandler(Header[] h)
  3052.         {
  3053.             SerializationMonkey m = (SerializationMonkey)FormatterServices.GetUninitializedObject(typeof(SerializationMonkey));
  3054.             Header[] newHeaders = null;
  3055.             if (h != null && h.Length > 0 && h[0].Name == "__methodName") {
  3056.                 methodName = (string)h[0].Value;
  3057.                 if (h.Length > 1) {
  3058.                     newHeaders = new Header[h.Length - 1];
  3059.                     Array.Copy(h, 1, newHeaders, 0, h.Length - 1);
  3060.                 }
  3061.                 else
  3062.                     newHeaders = null;
  3063.             }
  3064.             else
  3065.                 newHeaders = h;
  3066.            
  3067.             FillHeaders(newHeaders, true);
  3068.             ResolveMethod(false);
  3069.             m._obj = this;
  3070.             if (MI != null) {
  3071.                 ArgMapper argm = new ArgMapper(MI, false);
  3072.                 m.fieldNames = argm.ArgNames;
  3073.                 m.fieldTypes = argm.ArgTypes;
  3074.             }
  3075.             return m;
  3076.         }
  3077.     }
  3078.    
  3079.    
  3080.     //+================================================================================
  3081.     //
  3082.     // Synopsis: Message used for deserialization of a construction call
  3083.     //
  3084.     //-================================================================================
  3085.     /// <internalonly/>
  3086.     [Serializable(), CLSCompliant(false)]
  3087.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  3088.     [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  3089.     [System.Runtime.InteropServices.ComVisible(true)]
  3090.     public class ConstructionCall : MethodCall, IConstructionCallMessage
  3091.     {
  3092.        
  3093.         //
  3094.         // data
  3095.         //
  3096.        
  3097.         internal Type _activationType;
  3098.         internal string _activationTypeName;
  3099.         internal IList _contextProperties;
  3100.         internal object[] _callSiteActivationAttributes;
  3101.         internal IActivator _activator;
  3102.        
  3103. /*
  3104.         [NonSerialized()]
  3105.         internal Object      _fakeThisPtr;    // used for proxyattribute::CI
  3106.         */       
  3107.        
  3108.         //
  3109.         // construction
  3110.         //
  3111.        
  3112.         /// <internalonly/>
  3113.         public ConstructionCall(Header[] headers) : base(headers)
  3114.         {
  3115.         }
  3116.        
  3117.         /// <internalonly/>
  3118.         public ConstructionCall(IMessage m) : base(m)
  3119.         {
  3120.         }
  3121.         internal ConstructionCall(SerializationInfo info, StreamingContext context) : base(info, context)
  3122.         {
  3123.         }
  3124.        
  3125.        
  3126.         //
  3127.         // Function: FillSpecialHeader
  3128.         //
  3129.         // Synopsis: this is the only specialization we need to
  3130.         // make things go in the right place
  3131.         //
  3132.         //
  3133.         internal override bool FillSpecialHeader(string key, object value)
  3134.         {
  3135.             if (key == null) {
  3136.                 //skip
  3137.             }
  3138.             else if (key.Equals("__ActivationType")) {
  3139.                 BCLDebug.Assert(value == null, "Phoney type in CCM");
  3140.                 _activationType = null;
  3141.             }
  3142.             else if (key.Equals("__ContextProperties")) {
  3143.                 _contextProperties = (IList)value;
  3144.             }
  3145.             else if (key.Equals("__CallSiteActivationAttributes")) {
  3146.                 _callSiteActivationAttributes = (object[])value;
  3147.             }
  3148.             else if (key.Equals("__Activator")) {
  3149.                 _activator = (IActivator)value;
  3150.             }
  3151.             else if (key.Equals("__ActivationTypeName")) {
  3152.                 _activationTypeName = (string)value;
  3153.             }
  3154.             else {
  3155.                 return base.FillSpecialHeader(key, value);
  3156.             }
  3157.             return true;
  3158.            
  3159.         }
  3160.        
  3161.        
  3162.         //
  3163.         // IConstructionCallMessage
  3164.         //
  3165.        
  3166.         /// <internalonly/>
  3167.         public object[] CallSiteActivationAttributes {
  3168.             get { return _callSiteActivationAttributes; }
  3169.         }
  3170.        
  3171.        
  3172.         /// <internalonly/>
  3173.         public Type ActivationType {
  3174.             get {
  3175.                 if ((_activationType == null) && (_activationTypeName != null))
  3176.                     _activationType = RemotingServices.InternalGetTypeFromQualifiedTypeName(_activationTypeName, false);
  3177.                
  3178.                 return _activationType;
  3179.             }
  3180.         }
  3181.        
  3182.         /// <internalonly/>
  3183.         public string ActivationTypeName {
  3184.             get { return _activationTypeName; }
  3185.         }
  3186.        
  3187.         /// <internalonly/>
  3188.         public IList ContextProperties {
  3189.             get {
  3190.                 if (_contextProperties == null) {
  3191.                     _contextProperties = new ArrayList();
  3192.                 }
  3193.                 return _contextProperties;
  3194.             }
  3195.         }
  3196.        
  3197.         /// <internalonly/>
  3198.         public override IDictionary Properties {
  3199.             get {
  3200.                 lock (this) {
  3201.                     if (InternalProperties == null) {
  3202.                         InternalProperties = new Hashtable();
  3203.                     }
  3204.                     if (ExternalProperties == null) {
  3205.                         ExternalProperties = new CCMDictionary(this, InternalProperties);
  3206.                     }
  3207.                     return ExternalProperties;
  3208.                 }
  3209.             }
  3210.         }
  3211.        
  3212.        
  3213.         // IConstructionCallMessage::Activator
  3214.         /// <internalonly/>
  3215.         public IActivator Activator {
  3216.             get { return _activator; }
  3217.             set { _activator = value; }
  3218.         }
  3219.        
  3220.     }
  3221.     //+================================================================================
  3222.     //
  3223.     // Synopsis: Message used for deserialization of a method response
  3224.     //
  3225.     //-================================================================================
  3226.     /// <internalonly/>
  3227.     [Serializable(), CLSCompliant(false)]
  3228.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  3229.     [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  3230.     [System.Runtime.InteropServices.ComVisible(true)]
  3231.     public class MethodResponse : IMethodReturnMessage, ISerializable, ISerializationRootObject, IInternalMessage
  3232.     {
  3233.         private MethodBase MI;
  3234.         private string methodName;
  3235.         private Type[] methodSignature;
  3236.         private string uri;
  3237.         private string typeName;
  3238.         private object retVal;
  3239.         private Exception fault;
  3240.         private object[] outArgs;
  3241.         private LogicalCallContext callContext;
  3242.         /// <internalonly/>
  3243.         protected IDictionary InternalProperties;
  3244.         /// <internalonly/>
  3245.         protected IDictionary ExternalProperties;
  3246.        
  3247.         private int argCount;
  3248.         private bool fSoap;
  3249.         private ArgMapper argMapper;
  3250.         private RemotingMethodCachedData _methodCache;
  3251.        
  3252.         // Constructor -- this constructor is called only in the SOAP Scenario
  3253.        
  3254.        
  3255.         /// <internalonly/>
  3256.         public MethodResponse(Header[] h1, IMethodCallMessage mcm)
  3257.         {
  3258.             if (mcm == null)
  3259.                 throw new ArgumentNullException("mcm");
  3260.            
  3261.             Message msg = mcm as Message;
  3262.             if (null != msg) {
  3263.                 MI = (MethodBase)msg.GetMethodBase();
  3264.             }
  3265.             else {
  3266.                 MI = (MethodBase)mcm.MethodBase;
  3267.             }
  3268.             if (MI == null) {
  3269.                 throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_MethodMissing"), mcm.MethodName, mcm.TypeName));
  3270.             }
  3271.            
  3272.             _methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
  3273.            
  3274.             argCount = _methodCache.Parameters.Length;
  3275.             fSoap = true;
  3276.             FillHeaders(h1);
  3277.         }
  3278.        
  3279.        
  3280.         internal MethodResponse(IMethodCallMessage msg, SmuggledMethodReturnMessage smuggledMrm, ArrayList deserializedArgs)
  3281.         {
  3282.             MI = (MethodBase)msg.MethodBase;
  3283.             _methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
  3284.            
  3285.             methodName = msg.MethodName;
  3286.             uri = msg.Uri;
  3287.             typeName = msg.TypeName;
  3288.            
  3289.             if (_methodCache.IsOverloaded())
  3290.                 methodSignature = (Type[])msg.MethodSignature;
  3291.            
  3292.             retVal = smuggledMrm.GetReturnValue(deserializedArgs);
  3293.             outArgs = smuggledMrm.GetArgs(deserializedArgs);
  3294.             fault = smuggledMrm.GetException(deserializedArgs);
  3295.            
  3296.             callContext = smuggledMrm.GetCallContext(deserializedArgs);
  3297.            
  3298.             if (smuggledMrm.MessagePropertyCount > 0)
  3299.                 smuggledMrm.PopulateMessageProperties(Properties, deserializedArgs);
  3300.            
  3301.             argCount = _methodCache.Parameters.Length;
  3302.             fSoap = false;
  3303.         }
  3304.        
  3305.         internal MethodResponse(IMethodCallMessage msg, object handlerObject, BinaryMethodReturnMessage smuggledMrm)
  3306.         {
  3307.            
  3308.             if (msg != null) {
  3309.                 MI = (MethodBase)msg.MethodBase;
  3310.                 _methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
  3311.                
  3312.                 methodName = msg.MethodName;
  3313.                 uri = msg.Uri;
  3314.                 typeName = msg.TypeName;
  3315.                
  3316.                 if (_methodCache.IsOverloaded())
  3317.                     methodSignature = (Type[])msg.MethodSignature;
  3318.                
  3319.                 argCount = _methodCache.Parameters.Length;
  3320.                
  3321.             }
  3322.            
  3323.             retVal = smuggledMrm.ReturnValue;
  3324.             outArgs = smuggledMrm.Args;
  3325.             fault = smuggledMrm.Exception;
  3326.            
  3327.             callContext = smuggledMrm.LogicalCallContext;
  3328.            
  3329.             if (smuggledMrm.HasProperties)
  3330.                 smuggledMrm.PopulateMessageProperties(Properties);
  3331.            
  3332.             fSoap = false;
  3333.         }
  3334.        
  3335.        
  3336.        
  3337.         //
  3338.         // SetObjectData -- this can be called with the object in two possible states. 1. the object
  3339.         // is servicing a SOAP response in which it will have been half initialized by the constructor,
  3340.         // or 2. the object is uninitailized and serialization is passing in the contents.
  3341.         //
  3342.         internal MethodResponse(SerializationInfo info, StreamingContext context)
  3343.         {
  3344.             if (info == null)
  3345.                 throw new ArgumentNullException("info");
  3346.             SetObjectData(info, context);
  3347.         }
  3348.        
  3349.        
  3350.         /// <internalonly/>
  3351.         public virtual object HeaderHandler(Header[] h)
  3352.         {
  3353.             SerializationMonkey m = (SerializationMonkey)FormatterServices.GetUninitializedObject(typeof(SerializationMonkey));
  3354.            
  3355.             Header[] newHeaders = null;
  3356.             if (h != null && h.Length > 0 && h[0].Name == "__methodName") {
  3357.                 if (h.Length > 1) {
  3358.                     newHeaders = new Header[h.Length - 1];
  3359.                     Array.Copy(h, 1, newHeaders, 0, h.Length - 1);
  3360.                 }
  3361.                 else
  3362.                     newHeaders = null;
  3363.             }
  3364.             else
  3365.                 newHeaders = h;
  3366.            
  3367.             Type retType = null;
  3368.             MethodInfo mi = MI as MethodInfo;
  3369.             if (mi != null) {
  3370.                 retType = mi.ReturnType;
  3371.             }
  3372.            
  3373.             ParameterInfo[] pinfos = _methodCache.Parameters;
  3374.            
  3375.             // Calculate length
  3376.             int outParamsCount = _methodCache.MarshalResponseArgMap.Length;
  3377.             if (!((retType == null) || (retType == typeof(void))))
  3378.                 outParamsCount++;
  3379.            
  3380.             Type[] paramTypes = new Type[outParamsCount];
  3381.             string[] paramNames = new string[outParamsCount];
  3382.             int paramTypesIndex = 0;
  3383.             if (!((retType == null) || (retType == typeof(void)))) {
  3384.                 paramTypes[paramTypesIndex++] = retType;
  3385.             }
  3386.            
  3387.             foreach (int i in _methodCache.MarshalResponseArgMap) {
  3388.                 paramNames[paramTypesIndex] = pinfos[i].Name;
  3389.                 if (pinfos[i].ParameterType.IsByRef)
  3390.                     paramTypes[paramTypesIndex++] = pinfos[i].ParameterType.GetElementType();
  3391.                 else
  3392.                     paramTypes[paramTypesIndex++] = pinfos[i].ParameterType;
  3393.             }
  3394.            
  3395.             ((IFieldInfo)m).FieldTypes = paramTypes;
  3396.             ((IFieldInfo)m).FieldNames = paramNames;
  3397.             FillHeaders(newHeaders, true);
  3398.             m._obj = this;
  3399.             return m;
  3400.         }
  3401.        
  3402.         //
  3403.         // ISerializationRootObject
  3404.         //
  3405.         /// <internalonly/>
  3406.         public void RootSetObjectData(SerializationInfo info, StreamingContext ctx)
  3407.         {
  3408.             SetObjectData(info, ctx);
  3409.         }
  3410.        
  3411.         internal void SetObjectData(SerializationInfo info, StreamingContext ctx)
  3412.         {
  3413.             if (info == null)
  3414.                 throw new ArgumentNullException("info");
  3415.            
  3416.             if (fSoap) {
  3417.                 SetObjectFromSoapData(info);
  3418.             }
  3419.             else {
  3420.                 SerializationInfoEnumerator e = info.GetEnumerator();
  3421.                 bool ret = false;
  3422.                 bool excep = false;
  3423.                
  3424.                 while (e.MoveNext()) {
  3425.                     if (e.Name.Equals("__return")) {
  3426.                         ret = true;
  3427.                         break;
  3428.                     }
  3429.                     if (e.Name.Equals("__fault")) {
  3430.                         excep = true;
  3431.                         fault = (Exception)e.Value;
  3432.                         break;
  3433.                     }
  3434.                    
  3435.                     FillHeader(e.Name, e.Value);
  3436.                 }
  3437.                 if ((excep) && (ret)) {
  3438.                     throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadSerialization"));
  3439.                 }
  3440.             }
  3441.         }
  3442.         //
  3443.         // ISerializable
  3444.         //
  3445.        
  3446.         //
  3447.         // GetObjectData -- not implemented
  3448.         //
  3449.        
  3450.         /// <internalonly/>
  3451.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
  3452.         public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
  3453.         {
  3454.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_Method"));
  3455.         }
  3456.        
  3457.         //
  3458.         // SetObjectFromSoapData -- assumes SOAP format and populates the arguments array
  3459.         //
  3460.        
  3461.         internal void SetObjectFromSoapData(SerializationInfo info)
  3462.         {
  3463.             //SerializationInfoEnumerator e = info.GetEnumerator();
  3464.            
  3465.             Hashtable keyToNamespaceTable = (Hashtable)info.GetValue("__keyToNamespaceTable", typeof(Hashtable));
  3466.             ArrayList paramNames = (ArrayList)info.GetValue("__paramNameList", typeof(ArrayList));
  3467.             SoapFault soapFault = (SoapFault)info.GetValue("__fault", typeof(SoapFault));
  3468.            
  3469.             if (soapFault != null) {
  3470.                 ServerFault serverFault = soapFault.Detail as ServerFault;
  3471.                 if (null != serverFault) {
  3472.                     // Server Fault information
  3473.                     if (serverFault.Exception != null)
  3474.                         fault = serverFault.Exception;
  3475.                     else {
  3476.                         Type exceptionType = Type.GetType(serverFault.ExceptionType, false, false);
  3477.                         if (exceptionType == null) {
  3478.                             // Exception type cannot be resolved, use a ServerException
  3479.                             StringBuilder sb = new StringBuilder();
  3480.                             sb.Append("\nException Type: ");
  3481.                             sb.Append(serverFault.ExceptionType);
  3482.                             sb.Append("\n");
  3483.                             sb.Append("Exception Message: ");
  3484.                             sb.Append(serverFault.ExceptionMessage);
  3485.                             sb.Append("\n");
  3486.                             sb.Append(serverFault.StackTrace);
  3487.                             fault = new ServerException(sb.ToString());
  3488.                         }
  3489.                         else {
  3490.                             // Exception type can be resolved, throw the exception
  3491.                             object[] args = {serverFault.ExceptionMessage};
  3492.                             fault = (Exception)Activator.CreateInstance(exceptionType, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, args, null, null);
  3493.                         }
  3494.                     }
  3495.                 }
  3496.                 else if ((soapFault.Detail != null) && (soapFault.Detail.GetType() == typeof(string)) && (!(((string)soapFault.Detail).Length == 0))) {
  3497.                     fault = new ServerException((string)soapFault.Detail);
  3498.                 }
  3499.                 else {
  3500.                     fault = new ServerException(soapFault.FaultString);
  3501.                 }
  3502.                
  3503.                 return;
  3504.             }
  3505.            
  3506.             MethodInfo mi = MI as MethodInfo;
  3507.             int paramNameIndex = 0;
  3508.             if (mi != null) {
  3509.                 Type retType = mi.ReturnType;
  3510.                 if (retType != typeof(void)) {
  3511.                     paramNameIndex++;
  3512.                     object returnValue = info.GetValue((string)paramNames[0], typeof(object));
  3513.                     if (returnValue is string)
  3514.                         retVal = Message.SoapCoerceArg(returnValue, retType, keyToNamespaceTable);
  3515.                     else
  3516.                         retVal = returnValue;
  3517.                 }
  3518.             }
  3519.            
  3520.             // populate the args array
  3521.             ParameterInfo[] pinfos = _methodCache.Parameters;
  3522.            
  3523.             object fUnordered = (InternalProperties == null) ? null : InternalProperties["__UnorderedParams"];
  3524.             if (fUnordered != null && (fUnordered is bool) && (true == (bool)fUnordered)) {
  3525.                 // Unordered
  3526.                 for (int i = paramNameIndex; i < paramNames.Count; i++) {
  3527.                     string memberName = (string)paramNames[i];
  3528.                    
  3529.                     // check for the parameter name
  3530.                    
  3531.                     int position = -1;
  3532.                     for (int j = 0; j < pinfos.Length; j++) {
  3533.                         if (memberName.Equals(pinfos[j].Name)) {
  3534.                             position = pinfos[j].Position;
  3535.                         }
  3536.                     }
  3537.                    
  3538.                     // no name so check for well known name
  3539.                    
  3540.                     if (position == -1) {
  3541.                         if (!memberName.StartsWith("__param", StringComparison.Ordinal)) {
  3542.                             throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadSerialization"));
  3543.                         }
  3544.                         position = Int32.Parse(memberName.Substring(7), CultureInfo.InvariantCulture);
  3545.                     }
  3546.                    
  3547.                     // if still not resolved then throw
  3548.                    
  3549.                     if (position >= argCount) {
  3550.                         throw new RemotingException(Environment.GetResourceString("Remoting_Message_BadSerialization"));
  3551.                     }
  3552.                    
  3553.                     // store the arg in the parameter array
  3554.                    
  3555.                     if (outArgs == null) {
  3556.                         outArgs = new object[argCount];
  3557.                     }
  3558.                     outArgs[position] = Message.SoapCoerceArg(info.GetValue(memberName, typeof(object)), pinfos[position].ParameterType, keyToNamespaceTable);
  3559.                 }
  3560.             }
  3561.             else {
  3562.                 // ordered
  3563.                 if (argMapper == null)
  3564.                     argMapper = new ArgMapper(this, true);
  3565.                 for (int j = paramNameIndex; j < paramNames.Count; j++) {
  3566.                     string memberName = (string)paramNames[j];
  3567.                     if (outArgs == null) {
  3568.                         outArgs = new object[argCount];
  3569.                     }
  3570.                    
  3571.                     int position = argMapper.Map[j - paramNameIndex];
  3572.                     outArgs[position] = Message.SoapCoerceArg(info.GetValue(memberName, typeof(object)), pinfos[position].ParameterType, keyToNamespaceTable);
  3573.                 }
  3574.             }
  3575.         }
  3576.         // SetObjectFromSoapData
  3577.        
  3578.        
  3579.         internal LogicalCallContext GetLogicalCallContext()
  3580.         {
  3581.             if (callContext == null)
  3582.                 callContext = new LogicalCallContext();
  3583.             return callContext;
  3584.         }
  3585.        
  3586.         internal LogicalCallContext SetLogicalCallContext(LogicalCallContext ctx)
  3587.         {
  3588.             LogicalCallContext old = callContext;
  3589.             callContext = ctx;
  3590.             return old;
  3591.         }
  3592.        
  3593.         //
  3594.         // IMethodReturnMessage
  3595.         //
  3596.        
  3597.         /// <internalonly/>
  3598.         public string Uri {
  3599.             get { return uri; }
  3600.             set { uri = value; }
  3601.         }
  3602.         /// <internalonly/>
  3603.         public string MethodName {
  3604.             get { return methodName; }
  3605.         }
  3606.         /// <internalonly/>
  3607.         public string TypeName {
  3608.             get { return typeName; }
  3609.         }
  3610.         /// <internalonly/>
  3611.         public object MethodSignature {
  3612.             get { return methodSignature; }
  3613.         }
  3614.         /// <internalonly/>
  3615.         public MethodBase MethodBase {
  3616.             get { return MI; }
  3617.         }
  3618.        
  3619.        
  3620.         /// <internalonly/>
  3621.         public bool HasVarArgs {
  3622. // Var args nyi..
  3623.             get { return false; }
  3624.         }
  3625.        
  3626.         /// <internalonly/>
  3627.         public int ArgCount {
  3628.             get {
  3629.                 if (outArgs == null)
  3630.                     return 0;
  3631.                 else
  3632.                     return outArgs.Length;
  3633.             }
  3634.         }
  3635.         /// <internalonly/>
  3636.         public object GetArg(int argNum)
  3637.         {
  3638.             return outArgs[argNum];
  3639.         }
  3640.         /// <internalonly/>
  3641.         public string GetArgName(int index)
  3642.         {
  3643.             if (MI != null) {
  3644.                 RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
  3645.                 ParameterInfo[] paramInfo = methodCache.Parameters;
  3646.                 if (index < 0 || index >= paramInfo.Length)
  3647.                     throw new ArgumentOutOfRangeException("index");
  3648.                
  3649.                 return methodCache.Parameters[index].Name;
  3650.             }
  3651.             else
  3652.                 return "__param" + index;
  3653.         }
  3654.         /// <internalonly/>
  3655.         public object[] Args {
  3656.             get { return outArgs; }
  3657.         }
  3658.        
  3659.         /// <internalonly/>
  3660.         public int OutArgCount {
  3661.             get {
  3662.                 if (argMapper == null)
  3663.                     argMapper = new ArgMapper(this, true);
  3664.                 return argMapper.ArgCount;
  3665.             }
  3666.         }
  3667.        
  3668.         /// <internalonly/>
  3669.         public object GetOutArg(int argNum)
  3670.         {
  3671.             if (argMapper == null)
  3672.                 argMapper = new ArgMapper(this, true);
  3673.             return argMapper.GetArg(argNum);
  3674.         }
  3675.        
  3676.         /// <internalonly/>
  3677.         public string GetOutArgName(int index)
  3678.         {
  3679.             if (argMapper == null)
  3680.                 argMapper = new ArgMapper(this, true);
  3681.             return argMapper.GetArgName(index);
  3682.         }
  3683.         /// <internalonly/>
  3684.         public object[] OutArgs {
  3685.             get {
  3686.                 if (argMapper == null)
  3687.                     argMapper = new ArgMapper(this, true);
  3688.                 return argMapper.Args;
  3689.             }
  3690.         }
  3691.        
  3692.         /// <internalonly/>
  3693.         public Exception Exception {
  3694.             get { return fault; }
  3695.         }
  3696.         /// <internalonly/>
  3697.         public object ReturnValue {
  3698.             get { return retVal; }
  3699.         }
  3700.        
  3701.        
  3702.         /// <internalonly/>
  3703.         public virtual IDictionary Properties {
  3704.             get {
  3705.                 lock (this) {
  3706.                     if (InternalProperties == null) {
  3707.                         InternalProperties = new Hashtable();
  3708.                     }
  3709.                     if (ExternalProperties == null) {
  3710.                         ExternalProperties = new MRMDictionary(this, InternalProperties);
  3711.                     }
  3712.                     return ExternalProperties;
  3713.                 }
  3714.             }
  3715.         }
  3716.        
  3717.         /// <internalonly/>
  3718.         public LogicalCallContext LogicalCallContext {
  3719.             get { return GetLogicalCallContext(); }
  3720.         }
  3721.        
  3722.         //
  3723.         // helpers
  3724.         //
  3725.         internal void FillHeaders(Header[] h)
  3726.         {
  3727.             FillHeaders(h, false);
  3728.         }
  3729.         // FillHeaders
  3730.        
  3731.         private void FillHeaders(Header[] h, bool bFromHeaderHandler)
  3732.         {
  3733.             if (h == null)
  3734.                 return;
  3735.            
  3736.             if (bFromHeaderHandler && fSoap) {
  3737.                 // Handle the case of headers coming off the wire in SOAP.
  3738.                
  3739.                 // look for message properties
  3740.                 int co;
  3741.                 for (co = 0; co < h.Length; co++) {
  3742.                     Header header = h[co];
  3743.                     if (header.HeaderNamespace == "http://schemas.microsoft.com/clr/soap/messageProperties") {
  3744.                         // add property to the message
  3745.                         FillHeader(header.Name, header.Value);
  3746.                     }
  3747.                     else {
  3748.                         // add header to the message as a header
  3749.                         string name = LogicalCallContext.GetPropertyKeyForHeader(header);
  3750.                         FillHeader(name, header);
  3751.                     }
  3752.                 }
  3753.             }
  3754.             else {
  3755.                 for (int i = 0; i < h.Length; i++) {
  3756.                     FillHeader(h[i].Name, h[i].Value);
  3757.                 }
  3758.             }
  3759.         }
  3760.         // FillHeaders
  3761.        
  3762.         internal void FillHeader(string name, object value)
  3763.         {
  3764.             Message.DebugOut("MethodCall::FillHeaders: name: " + (name == null ? "NULL" : name) + "\n");
  3765.             Message.DebugOut("MethodCall::FillHeaders: Value.GetClass: " + (value == null ? "NULL" : value.GetType().FullName) + "\n");
  3766.             Message.DebugOut("MethodCall::FillHeaders: Value.ToString: " + (value == null ? "NULL" : value.ToString()) + "\n");
  3767.            
  3768.             if (name.Equals("__MethodName")) {
  3769.                 methodName = (string)value;
  3770.             }
  3771.             else if (name.Equals("__Uri")) {
  3772.                 uri = (string)value;
  3773.             }
  3774.             else if (name.Equals("__MethodSignature")) {
  3775.                 methodSignature = (Type[])value;
  3776.             }
  3777.             else if (name.Equals("__TypeName")) {
  3778.                 typeName = (string)value;
  3779.             }
  3780.             else if (name.Equals("__OutArgs")) {
  3781.                 outArgs = (object[])value;
  3782.             }
  3783.             else if (name.Equals("__CallContext")) {
  3784.                 // if the value is a string, then its the LogicalCallId
  3785.                 if (value is string) {
  3786.                     callContext = new LogicalCallContext();
  3787.                     callContext.RemotingData.LogicalCallID = (string)value;
  3788.                 }
  3789.                 else
  3790.                     callContext = (LogicalCallContext)value;
  3791.             }
  3792.             else if (name.Equals("__Return")) {
  3793.                 retVal = value;
  3794.             }
  3795.             else {
  3796.                 if (InternalProperties == null) {
  3797.                     InternalProperties = new Hashtable();
  3798.                 }
  3799.                 InternalProperties[name] = value;
  3800.             }
  3801.         }
  3802.        
  3803.         //
  3804.         // IInternalMessage
  3805.         //
  3806.        
  3807.         /// <internalonly/>
  3808.         ServerIdentity IInternalMessage.ServerIdentityObject {
  3809.             get { return null; }
  3810.             set { }
  3811.         }
  3812.        
  3813.         /// <internalonly/>
  3814.         Identity IInternalMessage.IdentityObject {
  3815.             get { return null; }
  3816.             set { }
  3817.         }
  3818.        
  3819.         /// <internalonly/>
  3820.         void IInternalMessage.SetURI(string val)
  3821.         {
  3822.             uri = val;
  3823.         }
  3824.        
  3825.         /// <internalonly/>
  3826.         void IInternalMessage.SetCallContext(LogicalCallContext newCallContext)
  3827.         {
  3828.             callContext = newCallContext;
  3829.         }
  3830.        
  3831.         /// <internalonly/>
  3832.         bool IInternalMessage.HasProperties()
  3833.         {
  3834.             return (ExternalProperties != null) || (InternalProperties != null);
  3835.         }
  3836.        
  3837.     }
  3838.     // class MethodResponse
  3839.     internal interface ISerializationRootObject
  3840.     {
  3841.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  3842.         void RootSetObjectData(SerializationInfo info, StreamingContext ctx);
  3843.     }
  3844.    
  3845.     [Serializable()]
  3846.     internal class SerializationMonkey : ISerializable, IFieldInfo
  3847.     {
  3848.         internal ISerializationRootObject _obj;
  3849.         internal string[] fieldNames = null;
  3850.         internal Type[] fieldTypes = null;
  3851.        
  3852.         internal SerializationMonkey(SerializationInfo info, StreamingContext ctx)
  3853.         {
  3854.             _obj.RootSetObjectData(info, ctx);
  3855.         }
  3856.        
  3857.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
  3858.         public void GetObjectData(SerializationInfo info, StreamingContext context)
  3859.         {
  3860.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_Method"));
  3861.         }
  3862.        
  3863.         public string[] FieldNames {
  3864.             get { return fieldNames; }
  3865.             set { fieldNames = value; }
  3866.         }
  3867.        
  3868.         public Type[] FieldTypes {
  3869.             get { return fieldTypes; }
  3870.             set { fieldTypes = value; }
  3871.         }
  3872.        
  3873.        
  3874.     }
  3875.    
  3876.     //+================================================================================
  3877.     //
  3878.     // Synopsis: Message used for deserialization of a method construction
  3879.     //
  3880.     //-================================================================================
  3881.     /// <internalonly/>
  3882.     [Serializable(), CLSCompliant(false)]
  3883.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  3884.     [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  3885.     [System.Runtime.InteropServices.ComVisible(true)]
  3886.     public class ConstructionResponse : MethodResponse, IConstructionReturnMessage
  3887.     {
  3888.         /// <internalonly/>
  3889.         public ConstructionResponse(Header[] h, IMethodCallMessage mcm) : base(h, mcm)
  3890.         {
  3891.         }
  3892.         internal ConstructionResponse(SerializationInfo info, StreamingContext context) : base(info, context)
  3893.         {
  3894.         }
  3895.        
  3896.         /// <internalonly/>
  3897.         public override IDictionary Properties {
  3898.             get {
  3899.                 lock (this) {
  3900.                     if (InternalProperties == null) {
  3901.                         InternalProperties = new Hashtable();
  3902.                     }
  3903.                     if (ExternalProperties == null) {
  3904.                         ExternalProperties = new CRMDictionary(this, InternalProperties);
  3905.                     }
  3906.                     return ExternalProperties;
  3907.                 }
  3908.             }
  3909.         }
  3910.     }
  3911.    
  3912.     // This is a special message used for helping someone make a transition
  3913.     // into a Context (or AppDomain) and back out. This is intended as a replacement
  3914.     // of the callBack object mechanism which is expensive since it involves
  3915.     // 2 round trips (one to get the callback object) and one to make the call
  3916.     // on it. Furthermore the callBack object scheme in cross domain cases would
  3917.     // involve unnecessary marshal/unmarshal-s of vari'ous callBack objects.
  3918.     //
  3919.     // We implement IInternalMessage and do our own magic when various
  3920.     // infrastructure sinks ask for serverID etc. Bottomline intent is to make
  3921.     // everything look like a complete remote call with all the entailing transitions
  3922.     // and executing some delegate in another context (or appdomain) without
  3923.     // actually having a proxy to call "Invoke" on or a server object to "Dispatch"
  3924.     // on.
  3925.     [Serializable()]
  3926.     internal class TransitionCall : IMessage, IInternalMessage, IMessageSink, ISerializable
  3927.     {
  3928.         IDictionary _props;
  3929.         // For IMessage::GetDictionary
  3930.         IntPtr _sourceCtxID;
  3931.         // Where the request emerged
  3932.         IntPtr _targetCtxID;
  3933.         // Where the request should execute
  3934.         int _targetDomainID;
  3935.         // Non zero if we are going to another domain
  3936.         ServerIdentity _srvID;
  3937.         // Created serverID
  3938.         Identity _ID;
  3939.         // Created ID
  3940.         CrossContextDelegate _delegate;
  3941.         // The delegate to execute for the cross context case
  3942.         IntPtr _eeData;
  3943.         // Used for DoCallbackInEE
  3944.         // The _delegate should really be on an agile object otherwise
  3945.         // the whole point of doing a callBack is moot. However, even if it
  3946.         // is not, remoting and serialization together will ensure that
  3947.         // everything happens as expected and there is no smuggling.
  3948.        
  3949.         internal TransitionCall(IntPtr targetCtxID, CrossContextDelegate deleg)
  3950.         {
  3951.             BCLDebug.Assert(targetCtxID != IntPtr.Zero, "bad target ctx for call back");
  3952.             _sourceCtxID = Thread.CurrentContext.InternalContextID;
  3953.             _targetCtxID = targetCtxID;
  3954.             _delegate = deleg;
  3955.             _targetDomainID = 0;
  3956.             _eeData = IntPtr.Zero;
  3957.            
  3958.             // We are going to another context in the same app domain
  3959.             _srvID = new ServerIdentity(null, Thread.GetContextInternal(_targetCtxID));
  3960.             _ID = _srvID;
  3961.             _ID.RaceSetChannelSink(CrossContextChannel.MessageSink);
  3962.             _srvID.RaceSetServerObjectChain(this);
  3963.            
  3964.             //DBG Console.WriteLine("### TransitionCall ctor: " + Int32.Format(_sourceCtxID,"x") + ":" + Int32.Format(_targetCtxID,"x"));
  3965.         }
  3966.         // TransitionCall
  3967.        
  3968.         // This constructor should be used for cross appdomain case.
  3969.         internal TransitionCall(IntPtr targetCtxID, IntPtr eeData, int targetDomainID)
  3970.         {
  3971.             BCLDebug.Assert(targetCtxID != IntPtr.Zero, "bad target ctx for call back");
  3972.             BCLDebug.Assert(targetDomainID != 0, "bad target ctx for call back");
  3973.            
  3974.             _sourceCtxID = Thread.CurrentContext.InternalContextID;
  3975.             _targetCtxID = targetCtxID;
  3976.             _delegate = null;
  3977.             _targetDomainID = targetDomainID;
  3978.             _eeData = eeData;
  3979.            
  3980.            
  3981.             // In the cross domain case, the client side just has a base Identity
  3982.             // and the server domain has the Server identity. We fault in the latter
  3983.             // when requested later.
  3984.            
  3985.             // We are going to a context in another app domain
  3986.             _srvID = null;
  3987.             _ID = new Identity("TransitionCallURI", null);
  3988.            
  3989.             // Create the data needed for the channel sink creation
  3990.             CrossAppDomainData data = new CrossAppDomainData(_targetCtxID, _targetDomainID, Identity.ProcessGuid);
  3991.             string unUsed;
  3992.                 //uri
  3993.                 //channelData
  3994.             IMessageSink channelSink = CrossAppDomainChannel.AppDomainChannel.CreateMessageSink(null, data, out unUsed);
  3995.             //out objURI
  3996.             BCLDebug.Assert(channelSink != null, "X-domain transition failure");
  3997.             _ID.RaceSetChannelSink(channelSink);
  3998.         }
  3999.         // TransitionCall
  4000.        
  4001.         internal TransitionCall(SerializationInfo info, StreamingContext context)
  4002.         {
  4003.             if (info == null || (context.State != StreamingContextStates.CrossAppDomain)) {
  4004.                 throw new ArgumentNullException("info");
  4005.             }
  4006.            
  4007.             _props = (IDictionary)info.GetValue("props", typeof(IDictionary));
  4008.             _delegate = (CrossContextDelegate)info.GetValue("delegate", typeof(CrossContextDelegate));
  4009.             _sourceCtxID = (IntPtr)info.GetValue("sourceCtxID", typeof(IntPtr));
  4010.             _targetCtxID = (IntPtr)info.GetValue("targetCtxID", typeof(IntPtr));
  4011.             _eeData = (IntPtr)info.GetValue("eeData", typeof(IntPtr));
  4012.            
  4013.             _targetDomainID = info.GetInt32("targetDomainID");
  4014.             BCLDebug.Assert(_targetDomainID != 0, "target domain should be non-zero");
  4015.         }
  4016.        
  4017.         //IMessage::GetProperties
  4018.         public IDictionary Properties {
  4019.             get {
  4020.                 if (_props == null) {
  4021.                     lock (this) {
  4022.                         if (_props == null) {
  4023.                             _props = new Hashtable();
  4024.                         }
  4025.                     }
  4026.                 }
  4027.                 return _props;
  4028.             }
  4029.         }
  4030.        
  4031.         //IInternalMessage::ServerIdentityObject
  4032.         ServerIdentity IInternalMessage.ServerIdentityObject {
  4033.             get {
  4034.                 if ((_targetDomainID != 0) && _srvID == null) {
  4035.                     // We should now be in the target context! (We should not be
  4036.                     // attempting to get the server identity in the client domain).
  4037.                     BCLDebug.Assert(Thread.CurrentContext.InternalContextID == _targetCtxID, "ServerID requested in wrong appDomain!");
  4038.                     lock (this) {
  4039.                         /*DBG Console.WriteLine("### Get SrvID: thrdCtxID== " + Int32.Format(Thread.CurrentContext.InternalContextID,"x"));
  4040.                         Console.WriteLine("### Get SrvID: _targetCtxID" + Int32.Format(_targetCtxID,"x")); DBG*/                       
  4041.                        
  4042.                         // NOTE: if we don't have a managed context object
  4043.                         // corresponding to the targetCtxID ... we just use
  4044.                         // the default context for the AppDomain. This could
  4045.                         // be a problem if by some means we could have
  4046.                         // a non-default target VM context without a managed
  4047.                         // context object associated with it.
  4048. Context ctx = Thread.GetContextInternal(_targetCtxID);
  4049.                         if (ctx == null) {
  4050.                             ctx = Context.DefaultContext;
  4051.                         }
  4052.                         BCLDebug.Assert(ctx != null, "Null target context unexpected!");
  4053.                         _srvID = new ServerIdentity(null, Thread.GetContextInternal(_targetCtxID));
  4054.                        
  4055.                         _srvID.RaceSetServerObjectChain(this);
  4056.                     }
  4057.                 }
  4058.                 return _srvID;
  4059.             }
  4060.             set {
  4061.                 throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  4062.             }
  4063.         }
  4064.        
  4065.         //IInternalMessage::IdentityObject
  4066.         Identity IInternalMessage.IdentityObject {
  4067.             get { return _ID; }
  4068.             set {
  4069.                 throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  4070.             }
  4071.         }
  4072.        
  4073.         //IInternalMessage::SetURI
  4074.         void IInternalMessage.SetURI(string uri)
  4075.         {
  4076.             throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  4077.         }
  4078.        
  4079.        
  4080.         void IInternalMessage.SetCallContext(LogicalCallContext callContext)
  4081.         {
  4082.             throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  4083.         }
  4084.        
  4085.         bool IInternalMessage.HasProperties()
  4086.         {
  4087.             throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  4088.         }
  4089.        
  4090.        
  4091.         //IMessage::SyncProcessMessage
  4092.         public IMessage SyncProcessMessage(IMessage msg)
  4093.         {
  4094.             BCLDebug.Assert(Thread.CurrentContext.InternalContextID == _targetCtxID, "Transition message routed to wrong context");
  4095.            
  4096.             try {
  4097.                 LogicalCallContext oldcctx = Message.PropagateCallContextFromMessageToThread(msg);
  4098.                 if (_delegate != null) {
  4099.                     _delegate();
  4100.                 }
  4101.                 else {
  4102.                     // This is the cross appdomain case, so we need to construct
  4103.                     // the delegate and call on it.
  4104.                         /*fromEE*/                    CallBackHelper cb = new CallBackHelper(_eeData, true, _targetDomainID);
  4105.                     CrossContextDelegate ctxDel = new CrossContextDelegate(cb.Func);
  4106.                     ctxDel();
  4107.                 }
  4108.                 Message.PropagateCallContextFromThreadToMessage(msg, oldcctx);
  4109.             }
  4110.            
  4111.             catch (Exception e) {
  4112.                 ReturnMessage retMsg = new ReturnMessage(e, new ErrorMessage());
  4113.                 retMsg.SetLogicalCallContext((LogicalCallContext)msg.Properties[Message.CallContextKey]);
  4114.                 return retMsg;
  4115.             }
  4116.            
  4117.             return this;
  4118.         }
  4119.        
  4120.         //IMessage::AsyncProcessMessage
  4121.         public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
  4122.         {
  4123.             IMessage retMsg = SyncProcessMessage(msg);
  4124.             replySink.SyncProcessMessage(retMsg);
  4125.             return null;
  4126.         }
  4127.        
  4128.         //IMessage::GetNextSink()
  4129.         public IMessageSink NextSink {
  4130.             get { return null; }
  4131.         }
  4132.        
  4133.         //ISerializable::GetObjectData
  4134.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
  4135.         public void GetObjectData(SerializationInfo info, StreamingContext context)
  4136.         {
  4137.             if (info == null || (context.State != StreamingContextStates.CrossAppDomain)) {
  4138.                 throw new ArgumentNullException("info");
  4139.             }
  4140.             info.AddValue("props", _props, typeof(IDictionary));
  4141.             info.AddValue("delegate", _delegate, typeof(CrossContextDelegate));
  4142.             info.AddValue("sourceCtxID", _sourceCtxID);
  4143.             info.AddValue("targetCtxID", _targetCtxID);
  4144.             info.AddValue("targetDomainID", _targetDomainID);
  4145.             info.AddValue("eeData", _eeData);
  4146.         }
  4147.        
  4148.     }
  4149.     // class TransitionCall
  4150.     internal class ArgMapper
  4151.     {
  4152.         int[] _map;
  4153.         IMethodMessage _mm;
  4154.         RemotingMethodCachedData _methodCachedData;
  4155.        
  4156.         internal ArgMapper(IMethodMessage mm, bool fOut)
  4157.         {
  4158.             _mm = mm;
  4159.             MethodBase mb = (MethodBase)_mm.MethodBase;
  4160.             _methodCachedData = InternalRemotingServices.GetReflectionCachedData(mb);
  4161.            
  4162.             if (fOut)
  4163.                 _map = _methodCachedData.MarshalResponseArgMap;
  4164.             else
  4165.                 _map = _methodCachedData.MarshalRequestArgMap;
  4166.         }
  4167.         // ArgMapper
  4168.         internal ArgMapper(MethodBase mb, bool fOut)
  4169.         {
  4170.             _methodCachedData = InternalRemotingServices.GetReflectionCachedData(mb);
  4171.            
  4172.             if (fOut)
  4173.                 _map = _methodCachedData.MarshalResponseArgMap;
  4174.             else
  4175.                 _map = _methodCachedData.MarshalRequestArgMap;
  4176.         }
  4177.         // ArgMapper
  4178.        
  4179.         internal int[] Map {
  4180.             get { return _map; }
  4181.         }
  4182.        
  4183.         internal int ArgCount {
  4184.             get {
  4185.                 if (_map == null) {
  4186.                     return 0;
  4187.                 }
  4188.                 else {
  4189.                     return _map.Length;
  4190.                 }
  4191.             }
  4192.         }
  4193.        
  4194.         internal object GetArg(int argNum)
  4195.         {
  4196.            
  4197.             if (_map == null || argNum < 0 || argNum >= _map.Length) {
  4198.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  4199.             }
  4200.             else {
  4201.                 return _mm.GetArg(_map[argNum]);
  4202.             }
  4203.         }
  4204.        
  4205.         internal string GetArgName(int argNum)
  4206.         {
  4207.             if (_map == null || argNum < 0 || argNum >= _map.Length) {
  4208.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InternalState"));
  4209.             }
  4210.             else {
  4211.                 return _mm.GetArgName(_map[argNum]);
  4212.             }
  4213.         }
  4214.        
  4215.         internal object[] Args {
  4216.             get {
  4217.                 if (_map == null) {
  4218.                     return null;
  4219.                 }
  4220.                 else {
  4221.                     object[] ret = new object[_map.Length];
  4222.                     for (int i = 0; i < _map.Length; i++) {
  4223.                         ret[i] = _mm.GetArg(_map[i]);
  4224.                     }
  4225.                     return ret;
  4226.                 }
  4227.             }
  4228.         }
  4229.        
  4230.         internal Type[] ArgTypes {
  4231.             get {
  4232.                 Type[] ret = null;
  4233.                 if (_map != null) {
  4234.                     ParameterInfo[] pi = _methodCachedData.Parameters;
  4235.                     ret = new Type[_map.Length];
  4236.                     for (int i = 0; i < _map.Length; i++) {
  4237.                         ret[i] = pi[_map[i]].ParameterType;
  4238.                     }
  4239.                 }
  4240.                 return ret;
  4241.             }
  4242.         }
  4243.        
  4244.         internal string[] ArgNames {
  4245.             get {
  4246.                 string[] ret = null;
  4247.                 if (_map != null) {
  4248.                     ParameterInfo[] pi = _methodCachedData.Parameters;
  4249.                     ret = new string[_map.Length];
  4250.                     for (int i = 0; i < _map.Length; i++) {
  4251.                         ret[i] = pi[_map[i]].Name;
  4252.                     }
  4253.                 }
  4254.                 return ret;
  4255.             }
  4256.         }
  4257.        
  4258.        
  4259.         //
  4260.         // Helper functions for getting argument maps
  4261.         //
  4262.        
  4263.         static internal void GetParameterMaps(ParameterInfo[] parameters, out int[] inRefArgMap, out int[] outRefArgMap, out int[] outOnlyArgMap, out int[] nonRefOutArgMap, out int[] marshalRequestMap, out int[] marshalResponseMap)
  4264.         {
  4265.             int co;
  4266.            
  4267.             int inRefCount = 0;
  4268.             int outRefCount = 0;
  4269.             int outOnlyCount = 0;
  4270.             int nonRefOutCount = 0;
  4271.            
  4272.             int marshalRequestCount = 0;
  4273.             int marshalResponseCount = 0;
  4274.             int[] tempMarshalRequestMap = new int[parameters.Length];
  4275.             int[] tempMarshalResponseMap = new int[parameters.Length];
  4276.            
  4277.             // count instances of each type of parameter
  4278.             co = 0;
  4279.             foreach (ParameterInfo param in parameters) {
  4280.                 bool bIsIn = param.IsIn;
  4281.                 // [In]
  4282.                 bool bIsOut = param.IsOut;
  4283.                 // [Out] note: out int a === [Out] ref int b
  4284.                 bool bIsByRef = param.ParameterType.IsByRef;
  4285.                 // (ref or normal)
  4286.                 if (!bIsByRef) {
  4287.                     // it's a normal parameter (always passed in)
  4288.                     inRefCount++;
  4289.                     if (bIsOut)
  4290.                         nonRefOutCount++;
  4291.                 }
  4292.                 else if (bIsOut) {
  4293.                     outRefCount++;
  4294.                     outOnlyCount++;
  4295.                 }
  4296.                 else {
  4297.                     inRefCount++;
  4298.                    
  4299.                     outRefCount++;
  4300.                 }
  4301.                
  4302.                 // create maps for marshaling
  4303.                 bool bMarshalIn = false;
  4304.                 bool bMarshalOut = false;
  4305.                 if (bIsByRef) {
  4306.                     if (bIsIn == bIsOut) {
  4307.                         // "ref int a" or "[In, Out] ref int a"
  4308.                         bMarshalIn = true;
  4309.                         bMarshalOut = true;
  4310.                     }
  4311.                     else {
  4312.                         // "[In] ref int a" or "out int a"
  4313.                         bMarshalIn = bIsIn;
  4314.                         bMarshalOut = bIsOut;
  4315.                     }
  4316.                 }
  4317.                 else {
  4318.                     // "int a" or "[In, Out] a"
  4319.                     bMarshalIn = true;
  4320.                     bMarshalOut = bIsOut;
  4321.                 }
  4322.                
  4323.                
  4324.                 if (bMarshalIn)
  4325.                     tempMarshalRequestMap[marshalRequestCount++] = co;
  4326.                
  4327.                 if (bMarshalOut)
  4328.                     tempMarshalResponseMap[marshalResponseCount++] = co;
  4329.                
  4330.                 co++;
  4331.                 // parameter index
  4332.             }
  4333.             // foreach (ParameterInfo param in parameters)
  4334.             inRefArgMap = new int[inRefCount];
  4335.             outRefArgMap = new int[outRefCount];
  4336.             outOnlyArgMap = new int[outOnlyCount];
  4337.             nonRefOutArgMap = new int[nonRefOutCount];
  4338.            
  4339.             inRefCount = 0;
  4340.             outRefCount = 0;
  4341.             outOnlyCount = 0;
  4342.             nonRefOutCount = 0;
  4343.            
  4344.             // build up parameter maps
  4345.             for (co = 0; co < parameters.Length; co++) {
  4346.                 ParameterInfo param = parameters[co];
  4347.                
  4348.                 bool bIsOut = param.IsOut;
  4349.                 // [Out] note: out int a === [Out] ref int b
  4350.                 bool bIsByRef = param.ParameterType.IsByRef;
  4351.                 // (ref or normal)
  4352.                 if (!bIsByRef) {
  4353.                     // it's an in parameter
  4354.                     inRefArgMap[inRefCount++] = co;
  4355.                     if (bIsOut)
  4356.                         nonRefOutArgMap[nonRefOutCount++] = co;
  4357.                 }
  4358.                 else if (bIsOut) {
  4359.                     outRefArgMap[outRefCount++] = co;
  4360.                     outOnlyArgMap[outOnlyCount++] = co;
  4361.                 }
  4362.                 else {
  4363.                     inRefArgMap[inRefCount++] = co;
  4364.                    
  4365.                     outRefArgMap[outRefCount++] = co;
  4366.                 }
  4367.             }
  4368.            
  4369.             // copy over marshal maps
  4370.             marshalRequestMap = new int[marshalRequestCount];
  4371.             Array.Copy(tempMarshalRequestMap, marshalRequestMap, marshalRequestCount);
  4372.            
  4373.             marshalResponseMap = new int[marshalResponseCount];
  4374.             Array.Copy(tempMarshalResponseMap, marshalResponseMap, marshalResponseCount);
  4375.            
  4376.         }
  4377.         // GetParameterMaps
  4378.         //
  4379.         // Helper methods for expanding and contracting argument lists
  4380.         // when translating from async methods to sync methods and back.
  4381.         //
  4382.        
  4383.         static internal object[] ExpandAsyncEndArgsToSyncArgs(RemotingMethodCachedData syncMethod, object[] asyncEndArgs)
  4384.         {
  4385.             // This is when we have a list of args associated with EndFoo(), and
  4386.             // we want to size it to a list of args associated with Foo();
  4387.            
  4388.             object[] args = new object[syncMethod.Parameters.Length];
  4389.            
  4390.             int[] outRefArgMap = syncMethod.OutRefArgMap;
  4391.            
  4392.             for (int co = 0; co < outRefArgMap.Length; co++) {
  4393.                 args[outRefArgMap[co]] = asyncEndArgs[co];
  4394.             }
  4395.            
  4396.             return args;
  4397.         }
  4398.         // ExpandAsyncEndArgsToSyncArgs
  4399.     }
  4400.     // class ArgMapper
  4401.     internal class ErrorMessage : IMethodCallMessage
  4402.     {
  4403.        
  4404.         // IMessage
  4405.         public IDictionary Properties {
  4406.             get { return null; }
  4407.         }
  4408.        
  4409.         // IMethodMessage
  4410.         public string Uri {
  4411.             get { return m_URI; }
  4412.         }
  4413.         public string MethodName {
  4414.             get { return m_MethodName; }
  4415.         }
  4416.         public string TypeName {
  4417.             get { return m_TypeName; }
  4418.         }
  4419.         public object MethodSignature {
  4420.             get { return m_MethodSignature; }
  4421.         }
  4422.         public MethodBase MethodBase {
  4423.             get { return null; }
  4424.         }
  4425.        
  4426.         public int ArgCount {
  4427.             get { return m_ArgCount; }
  4428.         }
  4429.         public string GetArgName(int index)
  4430.         {
  4431.             return m_ArgName;
  4432.         }
  4433.         public object GetArg(int argNum)
  4434.         {
  4435.             return null;
  4436.         }
  4437.         public object[] Args {
  4438.             get { return null; }
  4439.         }
  4440.        
  4441.         public bool HasVarArgs {
  4442.             get { return false; }
  4443.         }
  4444.        
  4445.        
  4446.         // IMethodCallMessage
  4447.         public int InArgCount {
  4448.             get { return m_ArgCount; }
  4449.         }
  4450.         public string GetInArgName(int index)
  4451.         {
  4452.             return null;
  4453.         }
  4454.         public object GetInArg(int argNum)
  4455.         {
  4456.             return null;
  4457.         }
  4458.         public object[] InArgs {
  4459.             get { return null; }
  4460.         }
  4461.         public LogicalCallContext LogicalCallContext {
  4462.             get { return null; }
  4463.         }
  4464.        
  4465.         string m_URI = "Exception";
  4466.         string m_MethodName = "Unknown";
  4467.         string m_TypeName = "Unknown";
  4468.         object m_MethodSignature = null;
  4469.         int m_ArgCount = 0;
  4470.         string m_ArgName = "Unknown";
  4471.     }
  4472.    
  4473.    
  4474.    
  4475.     //+================================================================================
  4476.     //
  4477.     // Synopsis: Message wrapper used as base class for all exposed message wrappers.
  4478.     // This is needed so that we can extract the identity object from a custom message.
  4479.     //
  4480.     //-================================================================================
  4481.     /// <internalonly/>
  4482.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  4483.     [System.Runtime.InteropServices.ComVisible(true)]
  4484.     public class InternalMessageWrapper
  4485.     {
  4486.         /// <internalonly/>
  4487.         protected IMessage WrappedMessage;
  4488.        
  4489.         /// <internalonly/>
  4490.         public InternalMessageWrapper(IMessage msg)
  4491.         {
  4492.             WrappedMessage = msg;
  4493.         }
  4494.         // InternalMessageWrapper
  4495.         internal object GetIdentityObject()
  4496.         {
  4497.             IInternalMessage iim = WrappedMessage as IInternalMessage;
  4498.             if (null != iim) {
  4499.                 return iim.IdentityObject;
  4500.             }
  4501.             else {
  4502.                 InternalMessageWrapper imw = WrappedMessage as InternalMessageWrapper;
  4503.                 if (null != imw) {
  4504.                     return imw.GetIdentityObject();
  4505.                 }
  4506.                 else {
  4507.                     return null;
  4508.                 }
  4509.             }
  4510.         }
  4511.         // GetIdentityObject
  4512.         internal object GetServerIdentityObject()
  4513.         {
  4514.             IInternalMessage iim = WrappedMessage as IInternalMessage;
  4515.             if (null != iim) {
  4516.                 return iim.ServerIdentityObject;
  4517.             }
  4518.             else {
  4519.                 InternalMessageWrapper imw = WrappedMessage as InternalMessageWrapper;
  4520.                 if (null != imw) {
  4521.                     return imw.GetServerIdentityObject();
  4522.                 }
  4523.                 else {
  4524.                     return null;
  4525.                 }
  4526.             }
  4527.         }
  4528.         // GetServerIdentityObject
  4529.     }
  4530.     // class InternalMessageWrapper
  4531.    
  4532.    
  4533.     //+================================================================================
  4534.     //
  4535.     // Synopsis: Message wrapper used for creating custom method call messages.
  4536.     //
  4537.     //-================================================================================
  4538.     /// <internalonly/>
  4539.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  4540.     [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  4541.     [System.Runtime.InteropServices.ComVisible(true)]
  4542.     public class MethodCallMessageWrapper : InternalMessageWrapper, IMethodCallMessage
  4543.     {
  4544.         // we need to overload the dictionary to delegate special values to this class
  4545.         private class MCMWrapperDictionary : Hashtable
  4546.         {
  4547.             private IMethodCallMessage _mcmsg;
  4548.             // pointer to this message object
  4549.             private IDictionary _idict;
  4550.             // point to contained message's dictionary
  4551.             public MCMWrapperDictionary(IMethodCallMessage msg, IDictionary idict)
  4552.             {
  4553.                 _mcmsg = msg;
  4554.                 _idict = idict;
  4555.             }
  4556.            
  4557.             public override object this[object key]
  4558.             {
  4559.                 get {
  4560.                     string strKey = key as string;
  4561.                     if (null != strKey) {
  4562.                         switch (strKey) {
  4563.                             case "__Uri":
  4564.                                 return _mcmsg.Uri;
  4565.                             case "__MethodName":
  4566.                                 return _mcmsg.MethodName;
  4567.                             case "__MethodSignature":
  4568.                                 return _mcmsg.MethodSignature;
  4569.                             case "__TypeName":
  4570.                                 return _mcmsg.TypeName;
  4571.                             case "__Args":
  4572.                                 return _mcmsg.Args;
  4573.                         }
  4574.                     }
  4575.                     return _idict[key];
  4576.                 }
  4577.                 set {
  4578.                     string strKey = key as string;
  4579.                     if (null != strKey) {
  4580.                         switch (strKey) {
  4581.                             case "__MethodName":
  4582.                             case "__MethodSignature":
  4583.                             case "__TypeName":
  4584.                             case "__Args":
  4585.                                 throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  4586.                                 break;
  4587.                         }
  4588.                         _idict[key] = value;
  4589.                     }
  4590.                 }
  4591.             }
  4592.         }
  4593.         // class MCMWrapperDictionary
  4594.        
  4595.         IMethodCallMessage _msg;
  4596.         IDictionary _properties;
  4597.         ArgMapper _argMapper = null;
  4598.         object[] _args;
  4599.        
  4600.        
  4601.         /// <internalonly/>
  4602.         public MethodCallMessageWrapper(IMethodCallMessage msg) : base(msg)
  4603.         {
  4604.             _msg = msg;
  4605.             _args = _msg.Args;
  4606.         }
  4607.         // MethodCallMessageWrapper
  4608.        
  4609.         // IMethodMessage implementation
  4610.        
  4611.         /// <internalonly/>
  4612.         public virtual string Uri {
  4613.             get { return _msg.Uri; }
  4614.             set { _msg.Properties[Message.UriKey] = value; }
  4615.         }
  4616.        
  4617.         /// <internalonly/>
  4618.         public virtual string MethodName {
  4619.             get { return _msg.MethodName; }
  4620.         }
  4621.         /// <internalonly/>
  4622.         public virtual string TypeName {
  4623.             get { return _msg.TypeName; }
  4624.         }
  4625.         /// <internalonly/>
  4626.         public virtual object MethodSignature {
  4627.             get { return _msg.MethodSignature; }
  4628.         }
  4629.         /// <internalonly/>
  4630.         public virtual LogicalCallContext LogicalCallContext {
  4631.             get { return _msg.LogicalCallContext; }
  4632.         }
  4633.         /// <internalonly/>
  4634.         public virtual MethodBase MethodBase {
  4635.             get { return _msg.MethodBase; }
  4636.         }
  4637.        
  4638.         /// <internalonly/>
  4639.         public virtual int ArgCount {
  4640.             get {
  4641.                 if (_args != null)
  4642.                     return _args.Length;
  4643.                 else
  4644.                     return 0;
  4645.             }
  4646.         }
  4647.         /// <internalonly/>
  4648.         public virtual string GetArgName(int index)
  4649.         {
  4650.             return _msg.GetArgName(index);
  4651.         }
  4652.         /// <internalonly/>
  4653.         public virtual object GetArg(int argNum)
  4654.         {
  4655.             return _args[argNum];
  4656.         }
  4657.         /// <internalonly/>
  4658.         public virtual object[] Args {
  4659.             get { return _args; }
  4660.             set { _args = value; }
  4661.         }
  4662.        
  4663.         /// <internalonly/>
  4664.         public virtual bool HasVarArgs {
  4665.             get { return _msg.HasVarArgs; }
  4666.         }
  4667.        
  4668.         // end of IMethodMessage implementation
  4669.        
  4670.        
  4671.         // IMethodCallMessage implementation
  4672.         // (We cannot simply delegate to the internal message
  4673.         // since we override the definition of Args and create our own array
  4674.         // which can be modified.)
  4675.         /// <internalonly/>
  4676.         public virtual int InArgCount {
  4677.             get {
  4678.                 if (_argMapper == null)
  4679.                     _argMapper = new ArgMapper(this, false);
  4680.                 return _argMapper.ArgCount;
  4681.             }
  4682.         }
  4683.         // InArgCount
  4684.         /// <internalonly/>
  4685.         public virtual object GetInArg(int argNum)
  4686.         {
  4687.             if (_argMapper == null)
  4688.                 _argMapper = new ArgMapper(this, false);
  4689.             return _argMapper.GetArg(argNum);
  4690.         }
  4691.         // GetInArg
  4692.         /// <internalonly/>
  4693.         public virtual string GetInArgName(int index)
  4694.         {
  4695.             if (_argMapper == null)
  4696.                 _argMapper = new ArgMapper(this, false);
  4697.             return _argMapper.GetArgName(index);
  4698.         }
  4699.         // GetInArgName
  4700.         /// <internalonly/>
  4701.         public virtual object[] InArgs {
  4702.             get {
  4703.                 if (_argMapper == null)
  4704.                     _argMapper = new ArgMapper(this, false);
  4705.                 return _argMapper.Args;
  4706.             }
  4707.         }
  4708.         // InArgs
  4709.         // end of IMethodCallMessage implementation
  4710.        
  4711.        
  4712.         /// <internalonly/>
  4713.         public virtual IDictionary Properties {
  4714.             get {
  4715.                 if (_properties == null)
  4716.                     _properties = new MCMWrapperDictionary(this, _msg.Properties);
  4717.                 return _properties;
  4718.             }
  4719.         }
  4720.        
  4721.     }
  4722.     // class MethodCallMessageWrapper
  4723.    
  4724.    
  4725.     //+================================================================================
  4726.     //
  4727.     // Synopsis: Message wrapper used for creating custom method return messages.
  4728.     //
  4729.     //-================================================================================
  4730.     /// <internalonly/>
  4731.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  4732.     [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  4733.     [System.Runtime.InteropServices.ComVisible(true)]
  4734.     public class MethodReturnMessageWrapper : InternalMessageWrapper, IMethodReturnMessage
  4735.     {
  4736.         // we need to overload the dictionary to delegate special values to this class
  4737.         private class MRMWrapperDictionary : Hashtable
  4738.         {
  4739.             private IMethodReturnMessage _mrmsg;
  4740.             // pointer to this message object
  4741.             private IDictionary _idict;
  4742.             // point to contained message's dictionary
  4743.             public MRMWrapperDictionary(IMethodReturnMessage msg, IDictionary idict)
  4744.             {
  4745.                 _mrmsg = msg;
  4746.                 _idict = idict;
  4747.             }
  4748.            
  4749.             public override object this[object key]
  4750.             {
  4751.                 get {
  4752.                     string strKey = key as string;
  4753.                     if (null != strKey) {
  4754.                         switch (strKey) {
  4755.                             case "__Uri":
  4756.                                 return _mrmsg.Uri;
  4757.                             case "__MethodName":
  4758.                                 return _mrmsg.MethodName;
  4759.                             case "__MethodSignature":
  4760.                                 return _mrmsg.MethodSignature;
  4761.                             case "__TypeName":
  4762.                                 return _mrmsg.TypeName;
  4763.                             case "__Return":
  4764.                                 return _mrmsg.ReturnValue;
  4765.                             case "__OutArgs":
  4766.                                 return _mrmsg.OutArgs;
  4767.                         }
  4768.                     }
  4769.                     return _idict[key];
  4770.                 }
  4771.                 set {
  4772.                     string strKey = key as string;
  4773.                     if (null != strKey) {
  4774.                         switch (strKey) {
  4775.                             case "__MethodName":
  4776.                             case "__MethodSignature":
  4777.                             case "__TypeName":
  4778.                             case "__Return":
  4779.                             case "__OutArgs":
  4780.                                 throw new RemotingException(Environment.GetResourceString("Remoting_Default"));
  4781.                                 break;
  4782.                         }
  4783.                         _idict[key] = value;
  4784.                     }
  4785.                 }
  4786.             }
  4787.         }
  4788.         // class MCMWrapperDictionary
  4789.        
  4790.         IMethodReturnMessage _msg;
  4791.         IDictionary _properties;
  4792.         ArgMapper _argMapper = null;
  4793.         object[] _args = null;
  4794.         object _returnValue = null;
  4795.         Exception _exception = null;
  4796.        
  4797.        
  4798.         /// <internalonly/>
  4799.         public MethodReturnMessageWrapper(IMethodReturnMessage msg) : base(msg)
  4800.         {
  4801.             _msg = msg;
  4802.             _args = _msg.Args;
  4803.             _returnValue = _msg.ReturnValue;
  4804.             // be careful if you decide to lazily assign _returnValue
  4805.             // since the return value might actually be null
  4806.             _exception = _msg.Exception;
  4807.             // (same thing as above goes for _exception)
  4808.         }
  4809.         // MethodReturnMessageWrapper
  4810.        
  4811.         // IMethodMessage implementation
  4812.        
  4813.         /// <internalonly/>
  4814.         public string Uri {
  4815.             get { return _msg.Uri; }
  4816.            
  4817.             set { _msg.Properties[Message.UriKey] = value; }
  4818.         }
  4819.        
  4820.         /// <internalonly/>
  4821.         public virtual string MethodName {
  4822.             get { return _msg.MethodName; }
  4823.         }
  4824.         /// <internalonly/>
  4825.         public virtual string TypeName {
  4826.             get { return _msg.TypeName; }
  4827.         }
  4828.         /// <internalonly/>
  4829.         public virtual object MethodSignature {
  4830.             get { return _msg.MethodSignature; }
  4831.         }
  4832.         /// <internalonly/>
  4833.         public virtual LogicalCallContext LogicalCallContext {
  4834.             get { return _msg.LogicalCallContext; }
  4835.         }
  4836.         /// <internalonly/>
  4837.         public virtual MethodBase MethodBase {
  4838.             get { return _msg.MethodBase; }
  4839.         }
  4840.        
  4841.         /// <internalonly/>
  4842.         public virtual int ArgCount {
  4843.             get {
  4844.                 if (_args != null)
  4845.                     return _args.Length;
  4846.                 else
  4847.                     return 0;
  4848.             }
  4849.         }
  4850.        
  4851.         /// <internalonly/>
  4852.         public virtual string GetArgName(int index)
  4853.         {
  4854.             return _msg.GetArgName(index);
  4855.         }
  4856.         /// <internalonly/>
  4857.         public virtual object GetArg(int argNum)
  4858.         {
  4859.             return _args[argNum];
  4860.         }
  4861.         /// <internalonly/>
  4862.         public virtual object[] Args {
  4863.             get { return _args; }
  4864.             set { _args = value; }
  4865.         }
  4866.        
  4867.         /// <internalonly/>
  4868.         public virtual bool HasVarArgs {
  4869.             get { return _msg.HasVarArgs; }
  4870.         }
  4871.        
  4872.         // end of IMethodMessage implementation
  4873.        
  4874.        
  4875.         // IMethodReturnMessage implementation
  4876.         // (We cannot simply delegate to the internal message
  4877.         // since we override the definition of Args and create our own array
  4878.         // which can be modified.)
  4879.         /// <internalonly/>
  4880.         public virtual int OutArgCount {
  4881.             get {
  4882.                 if (_argMapper == null)
  4883.                     _argMapper = new ArgMapper(this, true);
  4884.                 return _argMapper.ArgCount;
  4885.             }
  4886.         }
  4887.        
  4888.         /// <internalonly/>
  4889.         public virtual object GetOutArg(int argNum)
  4890.         {
  4891.             if (_argMapper == null)
  4892.                 _argMapper = new ArgMapper(this, true);
  4893.             return _argMapper.GetArg(argNum);
  4894.         }
  4895.        
  4896.         /// <internalonly/>
  4897.         public virtual string GetOutArgName(int index)
  4898.         {
  4899.             if (_argMapper == null)
  4900.                 _argMapper = new ArgMapper(this, true);
  4901.             return _argMapper.GetArgName(index);
  4902.         }
  4903.        
  4904.         /// <internalonly/>
  4905.         public virtual object[] OutArgs {
  4906.             get {
  4907.                 if (_argMapper == null)
  4908.                     _argMapper = new ArgMapper(this, true);
  4909.                 return _argMapper.Args;
  4910.             }
  4911.         }
  4912.        
  4913.         /// <internalonly/>
  4914.         public virtual Exception Exception {
  4915.             get { return _exception; }
  4916.             set { _exception = value; }
  4917.         }
  4918.        
  4919.         /// <internalonly/>
  4920.         public virtual object ReturnValue {
  4921.             get { return _returnValue; }
  4922.             set { _returnValue = value; }
  4923.         }
  4924.        
  4925.         // end of IMethodReturnMessage implementation
  4926.        
  4927.         // IMessage
  4928.         /// <internalonly/>
  4929.         public virtual IDictionary Properties {
  4930.             get {
  4931.                 if (_properties == null)
  4932.                     _properties = new MRMWrapperDictionary(this, _msg.Properties);
  4933.                 return _properties;
  4934.             }
  4935.         }
  4936.        
  4937.        
  4938.     }
  4939.     // class MethodReturnMessageWrapper
  4940. }
  4941. // namespace Remoting

Developer Fusion