Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Runtime / Remoting / Message.cs / 1 / Message.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** File: Message.cs
**
**
** Purpose: Defines the message object created by the transparent
** proxy and used by the message sinks
**
**
===========================================================*/
namespace System.Runtime.Remoting.Messaging {
using System;
using System.Collections;
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Metadata;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using System.Text;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using System.Globalization;
//+=======================================================================
//
// Synopsis: Message is used to represent call and is created by the
// Transparent proxy
//
//-=======================================================================
[Serializable()]
internal class Message : IMethodCallMessage, IInternalMessage, ISerializable
{
// *** NOTE ***
// Keep these in sync with the flags in Message.h
// flags
internal const int Sync = 0; // Synchronous call
internal const int BeginAsync = 1; // Async Begin call
internal const int EndAsync = 2; // Async End call
internal const int Ctor = 4; // The call is a .Ctor
internal const int OneWay = 8; // One way call
internal const int CallMask = 15; // Mask for call type bits
internal const int FixedArgs = 16; // Fixed number of arguments call
internal const int VarArgs = 32; // Variable number of arguments call
//
// Changing the type or position of these fields requires making changes
// to the corresponding unmanaged class and to mscorlib.h
//
// Private data members
private String _MethodName; // Method name
private Type[] _MethodSignature; // Array of parameter types
private MethodBase _MethodBase; // Reflection method object
private Object _properties; // hash table for properities
private String _URI; // target object URI
private String _typeName;
private Exception _Fault; // null if no fault
private Identity _ID; // identity cached during Invoke
private ServerIdentity _srvID; // server Identity cached during Invoke
private ArgMapper _argMapper;
private LogicalCallContext _callContext;
private IntPtr _frame; // ptr to the call frame
private IntPtr _methodDesc; // ptr to the internal method descriptor
private IntPtr _metaSigHolder; // Pointer to the MetaSig structure
private IntPtr _delegateMD; // ptr to the internal method descriptor for the delegate
private IntPtr _governingType; // ptr to the internal type handle for the type calling the method
private int _flags; // internal flags
private bool _initDone; // called the native init routine
internal static String CallContextKey = "__CallContext";
internal static String UriKey = "__Uri";
public virtual Exception GetFault() {return _Fault;}
public virtual void SetFault(Exception e) {_Fault = e;}
internal virtual void SetOneWay() { _flags |= Message.OneWay;}
public virtual int GetCallType()
{
// We should call init only if neccessary
InitIfNecessary();
return _flags;
}
internal IntPtr GetFramePtr() { return _frame;}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void GetAsyncBeginInfo(out AsyncCallback acbd,
out Object state);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Object GetThisPtr();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern IAsyncResult GetAsyncResult();
public void Init()
{
// This method no longer does any meaninfull work, however it is
// publicly exposed so we cannot get rid of it.
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Object GetReturnValue();
//
// Constructor
// This should be internal. The message object is
// allocated and deallocated via a pool to enable
// reuse.
//
internal Message()
{
}
// NOTE: This method is called multiple times as we reuse the
// message object. Make sure that you reset any fields that you
// add to the message object to the default values. This will
// ensure that the reused message object starts with the correct
// values.
internal void InitFields(MessageData msgData)
{
_frame = msgData.pFrame;
_delegateMD = msgData.pDelegateMD;
_methodDesc = msgData.pMethodDesc;
_flags = msgData.iFlags;
_initDone = true;
_metaSigHolder = msgData.pSig;
_governingType = msgData.thGoverningType;
_MethodName = null;
_MethodSignature = null;
_MethodBase = null;
_URI = null;
_Fault = null;
_ID = null;
_srvID = null;
_callContext = null;
if (_properties != null)
{
// A dictionary object already exists. This case occurs
// when we reuse the message object. Just remove all the
// entries from the dictionary object and reuse it.
((IDictionary)_properties).Clear();
}
}
private void InitIfNecessary()
{
if (!_initDone)
{
// We assume that Init is an idempotent operation
Init();
_initDone = true;
}
}
//-------------------------------------------------------------------
// IInternalMessage
//--------------------------------------------------------------------
ServerIdentity IInternalMessage.ServerIdentityObject
{
get { return _srvID;}
set {_srvID = value;}
}
Identity IInternalMessage.IdentityObject
{
get { return _ID;}
set { _ID = value;}
}
void IInternalMessage.SetURI(String URI)
{
_URI = URI;
}
void IInternalMessage.SetCallContext(LogicalCallContext callContext)
{
_callContext = callContext;
}
bool IInternalMessage.HasProperties()
{
return _properties != null;
}
//-------------------------------------------------------------------
// IMessage
//--------------------------------------------------------------------
public IDictionary Properties
{
get
{
if (_properties == null)
{
Interlocked.CompareExchange(ref _properties,
new MCMDictionary(this, null),
null);
}
return (IDictionary)_properties;
}
}
//--------------------------------------------------------------------
// IMethodCallMessage
//-------------------------------------------------------------------
public String Uri
{
get { return _URI;}
set { _URI = value; }
}
public bool HasVarArgs
{
get
{
// When this method is called for the first time, we
// obtain the answer from a native call and set the flags
if((0 == (_flags & Message.FixedArgs)) &&
(0 == (_flags & Message.VarArgs)))
{
if(!InternalHasVarArgs())
{
_flags |= Message.FixedArgs;
}
else
{
_flags |= Message.VarArgs;
}
}
return (1 == (_flags & Message.VarArgs));
}
}
public int ArgCount
{
get { return InternalGetArgCount();}
}
public Object GetArg(int argNum)
{
return InternalGetArg(argNum);
}
public String GetArgName(int index)
{
if (index >= ArgCount)
{
throw new ArgumentOutOfRangeException("index");
}
RemotingMethodCachedData methodCache =
InternalRemotingServices.GetReflectionCachedData(GetMethodBase());
ParameterInfo[] pi = methodCache.Parameters;
if (index < pi.Length)
{
return pi[index].Name;
}
else
{
return "VarArg" + (index - pi.Length);
}
}
public Object[] Args
{
get
{
return InternalGetArgs();
}
}
public int InArgCount
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.ArgCount;
}
}
public Object GetInArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.GetArg(argNum);
}
public String GetInArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.GetArgName(index);
}
public Object[] InArgs
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.Args;
}
}
private void UpdateNames()
{
RemotingMethodCachedData methCache =
InternalRemotingServices.GetReflectionCachedData(GetMethodBase());
_typeName = methCache.TypeAndAssemblyName;
_MethodName = methCache.MethodName;
}
public String MethodName
{
get
{
if(null == _MethodName)
UpdateNames();
return _MethodName;
}
}
public String TypeName
{
get
{
if (_typeName == null)
UpdateNames();
return _typeName;
}
}
public Object MethodSignature
{
get
{
if(null == _MethodSignature)
_MethodSignature = GenerateMethodSignature(GetMethodBase());
return _MethodSignature;
}
}
public LogicalCallContext LogicalCallContext
{
get
{
return GetLogicalCallContext();
}
}
public MethodBase MethodBase
{
get
{
return GetMethodBase();
}
}
//
// ISerializable
//
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(
Environment.GetResourceString("NotSupported_Method"));
}
internal MethodBase GetMethodBase()
{
if(null == _MethodBase)
{
unsafe
{
RuntimeMethodHandle mh = new RuntimeMethodHandle((void*)_methodDesc);
RuntimeTypeHandle th = new RuntimeTypeHandle((void*)_governingType);
_MethodBase = RuntimeType.GetMethodBase(th, mh);
}
}
return _MethodBase;
}
internal LogicalCallContext SetLogicalCallContext(
LogicalCallContext callCtx)
{
LogicalCallContext oldCtx = _callContext;
_callContext = callCtx;
return oldCtx;
}
internal LogicalCallContext GetLogicalCallContext()
{
if (_callContext == null)
_callContext = new LogicalCallContext();
return _callContext;
}
// Internal helper to create method signature
internal static Type[] GenerateMethodSignature(MethodBase mb)
{
RemotingMethodCachedData methodCache =
InternalRemotingServices.GetReflectionCachedData(mb);
ParameterInfo[] paramArray = methodCache.Parameters;
Type[] methodSig = new Type[paramArray.Length];
for(int i = 0; i < paramArray.Length; i++)
{
methodSig[i] = paramArray[i].ParameterType;
}
return methodSig;
} // GenerateMethodSignature
//
// The following two routines are used by StackBuilderSink to check
// the consistency of arguments.
//
// Check that all the arguments are of the type
// specified by the parameter list.
//
internal static Object[] CoerceArgs(IMethodMessage m)
{
MethodBase mb = m.MethodBase;
BCLDebug.Assert(mb != null, "null method base passed to CoerceArgs");
RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(mb);
return CoerceArgs(m, methodCache.Parameters);
} // CoerceArgs
internal static Object[] CoerceArgs(IMethodMessage m, ParameterInfo[] pi)
{
return CoerceArgs(m.MethodBase, m.Args, pi);
} // CoerceArgs
internal static Object[] CoerceArgs(MethodBase mb, Object[] args, ParameterInfo[] pi)
{
if (pi == null)
{
throw new ArgumentNullException("pi");
}
if (pi.Length != args.Length)
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_Message_ArgMismatch"),
mb.DeclaringType.FullName, mb.Name,
args.Length, pi.Length));
}
for (int i=0; i < pi.Length; i++)
{
ParameterInfo currentPi = pi[i];
Type pt = currentPi.ParameterType;
Object oArg = args[i];
if (oArg != null)
{
args[i] = CoerceArg(oArg, pt);
}
else
{
if (pt.IsByRef)
{
Type paramType = pt.GetElementType();
if (paramType.IsValueType)
{
// nullables can be null,
if (currentPi.IsOut)
{
// we need to fill in the blanks for value types if they are null
args[i] = Activator.CreateInstance(paramType, true);
}
else
{
if (!(paramType.IsGenericType && paramType.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_MissingArgValue"),
paramType.FullName, i));
}
}
}
}
else
{
if (pt.IsValueType)
{
// nullables can be null,
if (!(pt.IsGenericType && pt.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
// A null value was passed as a value type parameter.
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Message_MissingArgValue"),
pt.FullName, i));
}
}
}
}
}
return args;
} // CoerceArgs
internal static Object CoerceArg(Object value, Type pt)
{
Object ret = null;
if(null != value)
{
Exception inner = null;
try
{
if (pt.IsByRef)
{
pt = pt.GetElementType();
}
if (pt.IsInstanceOfType(value))
{
ret = value;
}
else
{
ret = Convert.ChangeType(value, pt, CultureInfo.InvariantCulture);
}
}
catch(Exception e)
{
// Quietly ignore all exceptions. We will throw
// a more meaningful exception below.
inner = e;
}
// If the coercion failed then throw an exception
if(null == ret)
{
// NOTE: Do not call value.ToString() on proxies as
// it results in loading the type and loss of refinement
// optimization or denial of service attacks by loading
// a lot of types in the server.
String valueName = null;
if(RemotingServices.IsTransparentProxy(value))
{
valueName = typeof(MarshalByRefObject).ToString();
}
else
{
valueName = value.ToString();
}
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_Message_CoercionFailed"), valueName, pt), inner);
}
}
return ret;
} //end of CoerceArg
internal static Object SoapCoerceArg(Object value, Type pt, Hashtable keyToNamespaceTable)
{
Object ret = null;
if (value != null)
{
try
{
if (pt.IsByRef)
{
pt = pt.GetElementType();
}
if (pt.IsInstanceOfType(value))
{
ret = value;
}
else
{
String strValue = value as String;
if (strValue != null)
{
if (pt == typeof(Double))
{
if (strValue == "INF")
ret = Double.PositiveInfinity;
else if (strValue == "-INF")
ret = Double.NegativeInfinity;
else
ret = Double.Parse(strValue, CultureInfo.InvariantCulture);
}
else if (pt == typeof(Single))
{
if (strValue == "INF")
ret = Single.PositiveInfinity;
else if (strValue == "-INF")
ret = Single.NegativeInfinity;
else
ret = Single.Parse(strValue, CultureInfo.InvariantCulture);
}
else if (SoapType.typeofISoapXsd.IsAssignableFrom(pt))
{
if (pt == SoapType.typeofSoapTime)
ret = SoapTime.Parse(strValue);
else if (pt == SoapType.typeofSoapDate)
ret = SoapDate.Parse(strValue);
else if (pt == SoapType.typeofSoapYearMonth)
ret = SoapYearMonth.Parse(strValue);
else if (pt == SoapType.typeofSoapYear)
ret = SoapYear.Parse(strValue);
else if (pt == SoapType.typeofSoapMonthDay)
ret = SoapMonthDay.Parse(strValue);
else if (pt == SoapType.typeofSoapDay)
ret = SoapDay.Parse(strValue);
else if (pt == SoapType.typeofSoapMonth)
ret = SoapMonth.Parse(strValue);
else if (pt == SoapType.typeofSoapHexBinary)
ret = SoapHexBinary.Parse(strValue);
else if (pt == SoapType.typeofSoapBase64Binary)
ret = SoapBase64Binary.Parse(strValue);
else if (pt == SoapType.typeofSoapInteger)
ret = SoapInteger.Parse(strValue);
else if (pt == SoapType.typeofSoapPositiveInteger)
ret = SoapPositiveInteger.Parse(strValue);
else if (pt == SoapType.typeofSoapNonPositiveInteger)
ret = SoapNonPositiveInteger.Parse(strValue);
else if (pt == SoapType.typeofSoapNonNegativeInteger)
ret = SoapNonNegativeInteger.Parse(strValue);
else if (pt == SoapType.typeofSoapNegativeInteger)
ret = SoapNegativeInteger.Parse(strValue);
else if (pt == SoapType.typeofSoapAnyUri)
ret = SoapAnyUri.Parse(strValue);
else if (pt == SoapType.typeofSoapQName)
{
ret = SoapQName.Parse(strValue);
SoapQName soapQName = (SoapQName)ret;
if (soapQName.Key.Length == 0)
soapQName.Namespace = (String)keyToNamespaceTable["xmlns"];
else
soapQName.Namespace = (String)keyToNamespaceTable["xmlns"+":"+soapQName.Key];
}
else if (pt == SoapType.typeofSoapNotation)
ret = SoapNotation.Parse(strValue);
else if (pt == SoapType.typeofSoapNormalizedString)
ret = SoapNormalizedString.Parse(strValue);
else if (pt == SoapType.typeofSoapToken)
ret = SoapToken.Parse(strValue);
else if (pt == SoapType.typeofSoapLanguage)
ret = SoapLanguage.Parse(strValue);
else if (pt == SoapType.typeofSoapName)
ret = SoapName.Parse(strValue);
else if (pt == SoapType.typeofSoapIdrefs)
ret = SoapIdrefs.Parse(strValue);
else if (pt == SoapType.typeofSoapEntities)
ret = SoapEntities.Parse(strValue);
else if (pt == SoapType.typeofSoapNmtoken)
ret = SoapNmtoken.Parse(strValue);
else if (pt == SoapType.typeofSoapNmtokens)
ret = SoapNmtokens.Parse(strValue);
else if (pt == SoapType.typeofSoapNcName)
ret = SoapNcName.Parse(strValue);
else if (pt == SoapType.typeofSoapId)
ret = SoapId.Parse(strValue);
else if (pt == SoapType.typeofSoapIdref)
ret = SoapIdref.Parse(strValue);
else if (pt == SoapType.typeofSoapEntity)
ret = SoapEntity.Parse(strValue);
}
else if (pt == typeof(Boolean))
{
if (strValue == "1" || strValue == "true")
ret = (bool)true;
else if (strValue == "0" || strValue =="false")
ret = (bool)false;
else
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_Message_CoercionFailed"), strValue, pt));
}
}
else if (pt == typeof(DateTime))
ret = SoapDateTime.Parse(strValue);
else if (pt.IsPrimitive)
ret = Convert.ChangeType(value, pt, CultureInfo.InvariantCulture);
else if (pt == typeof(TimeSpan))
ret = SoapDuration.Parse(strValue);
else if (pt == typeof(Char))
ret = strValue[0];
else
ret = Convert.ChangeType(value, pt, CultureInfo.InvariantCulture); //Should this just throw an exception
}
else
ret = Convert.ChangeType(value, pt, CultureInfo.InvariantCulture);
}
}
catch(Exception )
{
// Quietly ignore all exceptions. We will throw
// a more meaningful exception below.
}
// If the coercion failed then throw an exception
if(null == ret)
{
// NOTE: Do not call value.ToString() on proxies as
// it results in loading the type and loss of refinement
// optimization or denial of service attacks by loading
// a lot of types in the server.
String valueName = null;
if(RemotingServices.IsTransparentProxy(value))
{
valueName = typeof(MarshalByRefObject).ToString();
}
else
{
valueName = value.ToString();
}
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_Message_CoercionFailed"), valueName, pt));
}
}
return ret;
}//end of SoapCoerceArg
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern bool InternalHasVarArgs();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern int InternalGetArgCount();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object InternalGetArg(int argNum);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object[] InternalGetArgs();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void PropagateOutParameters(Object[] OutArgs, Object retVal);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern bool Dispatch(Object target, bool fExecuteInContext);
//
// <
[System.Diagnostics.Conditional("_REMOTING_DEBUG")]
public static void DebugOut(String s)
{
BCLDebug.Trace(
"REMOTE", "RMTING: Thrd "
+ Thread.CurrentThread.GetHashCode()
+ " : " + s);
OutToUnmanagedDebugger(
"\nRMTING: Thrd "
+ Thread.CurrentThread.GetHashCode()
+ " : " + s);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static void OutToUnmanagedDebugger(String s);
internal static LogicalCallContext PropagateCallContextFromMessageToThread(IMessage msg)
{
return CallContext.SetLogicalCallContext(
(LogicalCallContext) msg.Properties[Message.CallContextKey]);
}
internal static void PropagateCallContextFromThreadToMessage(IMessage msg)
{
LogicalCallContext callCtx = CallContext.GetLogicalCallContext();
msg.Properties[Message.CallContextKey] = callCtx;
}
internal static void PropagateCallContextFromThreadToMessage(IMessage msg, LogicalCallContext oldcctx)
{
// First do the common work
PropagateCallContextFromThreadToMessage(msg);
// restore the old call context on the thread
CallContext.SetLogicalCallContext(oldcctx);
}
}
//+================================================================================
//
// Synopsis: Return message for constructors
//
//-===============================================================================
internal class ConstructorReturnMessage : ReturnMessage, IConstructionReturnMessage
{
private const int Intercept = 0x1;
private MarshalByRefObject _o;
private int _iFlags;
public ConstructorReturnMessage(MarshalByRefObject o, Object[] outArgs, int outArgsCount,
LogicalCallContext callCtx, IConstructionCallMessage ccm)
: base(o, outArgs, outArgsCount, callCtx, ccm)
{
_o = o;
_iFlags = Intercept;
}
public ConstructorReturnMessage(Exception e, IConstructionCallMessage ccm)
: base(e, ccm)
{
}
public override Object ReturnValue
{
get
{
if (_iFlags == Intercept)
{
return RemotingServices.MarshalInternal(_o,null,null);
}
else
{
return base.ReturnValue;
}
}
}
public override IDictionary Properties
{
get
{
if (_properties == null)
{
Object properties = new CRMDictionary(this, new Hashtable());
Interlocked.CompareExchange(ref _properties, properties, null);
}
return(IDictionary) _properties;
}
}
internal Object GetObject()
{
return _o;
}
}
//+=======================================================================
//
// Synopsis: client side implementation of activation message
//
//-=======================================================================
internal class ConstructorCallMessage : IConstructionCallMessage
{
// data
private Object[] _callSiteActivationAttributes;
private Object[] _womGlobalAttributes;
private Object[] _typeAttributes;
// The activation type isn't serialized because we want to
// re-resolve the activation type name on the other side
// based on _activationTypeName.
[NonSerialized()]
private Type _activationType;
private String _activationTypeName;
private IList _contextProperties;
private int _iFlags;
private Message _message;
private Object _properties;
private ArgMapper _argMapper;
private IActivator _activator;
// flags
private const int CCM_ACTIVATEINCONTEXT = 0x01;
private ConstructorCallMessage()
{
// Default constructor
}
internal ConstructorCallMessage(Object[] callSiteActivationAttributes,
Object[]womAttr, Object[] typeAttr, Type serverType)
{
_activationType = serverType;
_activationTypeName = RemotingServices.GetDefaultQualifiedTypeName(_activationType);
_callSiteActivationAttributes = callSiteActivationAttributes;
_womGlobalAttributes = womAttr;
_typeAttributes = typeAttr;
}
public Object GetThisPtr()
{
if (_message != null)
{
return _message.GetThisPtr();
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
public Object[] CallSiteActivationAttributes
{
get
{
return _callSiteActivationAttributes;
}
}
internal Object[] GetWOMAttributes()
{
return _womGlobalAttributes;
}
internal Object[] GetTypeAttributes()
{
return _typeAttributes;
}
public Type ActivationType
{
get
{
if ((_activationType == null) && (_activationTypeName != null))
_activationType = RemotingServices.InternalGetTypeFromQualifiedTypeName(_activationTypeName, false);
return _activationType;
}
}
public String ActivationTypeName
{
get
{
return _activationTypeName;
}
}
public IList ContextProperties
{
get
{
if (_contextProperties == null)
{
_contextProperties = new ArrayList();
}
return _contextProperties;
}
}
public String Uri
{
get
{
if (_message != null)
{
return _message.Uri;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
set
{
if (_message != null)
{
_message.Uri = value;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public String MethodName
{
get
{
if (_message != null)
{
return _message.MethodName;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public String TypeName
{
get
{
if (_message != null)
{
return _message.TypeName;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public Object MethodSignature
{
get
{
if (_message != null)
{
return _message.MethodSignature;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
} // MethodSignature
public MethodBase MethodBase
{
get
{
if (_message != null)
{
return _message.MethodBase;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
} // MethodBase
///
public int InArgCount
{
get
{
if (_argMapper == null)
_argMapper = new ArgMapper(this, false);
return _argMapper.ArgCount;
}
}
public Object GetInArg(int argNum)
{
if (_argMapper == null)
_argMapper = new ArgMapper(this, false);
return _argMapper.GetArg(argNum);
}
///
public String GetInArgName(int index)
{
if (_argMapper == null)
_argMapper = new ArgMapper(this, false);
return _argMapper.GetArgName(index);
}
public Object[] InArgs
{
get
{
if (_argMapper == null)
_argMapper = new ArgMapper(this, false);
return _argMapper.Args;
}
}
public int ArgCount
{
get
{
if (_message != null)
{
return _message.ArgCount;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public Object GetArg(int argNum)
{
if (_message != null)
{
return _message.GetArg(argNum);
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
public String GetArgName(int index)
{
if (_message != null)
{
return _message.GetArgName(index);
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
public bool HasVarArgs
{
get
{
if (_message != null)
{
return _message.HasVarArgs;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public Object[] Args
{
get
{
if (_message != null)
{
return _message.Args;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public IDictionary Properties
{
get
{
if (_properties == null)
{
Object properties = new CCMDictionary(this, new Hashtable());
Interlocked.CompareExchange(ref _properties, properties, null);
}
return(IDictionary) _properties;
}
}
public IActivator Activator
{
get { return _activator; }
set { _activator = value; }
}
public LogicalCallContext LogicalCallContext
{
get
{
return GetLogicalCallContext();
}
}
internal bool ActivateInContext
{
get { return((_iFlags & CCM_ACTIVATEINCONTEXT) != 0);}
set { _iFlags = value ? (_iFlags | CCM_ACTIVATEINCONTEXT) : (_iFlags & ~CCM_ACTIVATEINCONTEXT);}
}
internal void SetFrame(MessageData msgData)
{
BCLDebug.Assert(_message == null, "Can't set frame twice on ConstructorCallMessage");
_message = new Message();
_message.InitFields(msgData);
}
internal LogicalCallContext GetLogicalCallContext()
{
if (_message != null)
{
return _message.GetLogicalCallContext();
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
internal LogicalCallContext SetLogicalCallContext(LogicalCallContext ctx)
{
if (_message != null)
{
return _message.SetLogicalCallContext(ctx);
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
internal Message GetMessage()
{
return _message;
}
}
//+========================================================================
//
// Synopsis: Specialization of MessageDictionary for
// ConstructorCallMessage objects
//
//-=======================================================================
internal class CCMDictionary : MessageDictionary
{
public static String[] CCMkeys = {
"__Uri", //0
"__MethodName", //1
"__MethodSignature", //2
"__TypeName", //3
"__Args", //4
"__CallContext", //5
"__CallSiteActivationAttributes", //6
"__ActivationType", //7
"__ContextProperties", //8
"__Activator", //9
"__ActivationTypeName"}; //10
internal IConstructionCallMessage _ccmsg; // back pointer to message object
public CCMDictionary(IConstructionCallMessage msg, IDictionary idict)
: base(CCMkeys, idict)
{
_ccmsg = msg;
}
internal override Object GetMessageValue(int i)
{
switch (i)
{
case 0:
return _ccmsg.Uri;
case 1:
return _ccmsg.MethodName;
case 2:
return _ccmsg.MethodSignature;
case 3:
return _ccmsg.TypeName;
case 4:
return _ccmsg.Args;
case 5:
return FetchLogicalCallContext();
case 6:
return _ccmsg.CallSiteActivationAttributes;
case 7:
// This it to keep us from serializing the requested server type
return null;
case 8:
return _ccmsg.ContextProperties;
case 9:
return _ccmsg.Activator;
case 10:
return _ccmsg.ActivationTypeName;
}
// We should not get here!
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
private LogicalCallContext FetchLogicalCallContext()
{
ConstructorCallMessage ccm = _ccmsg as ConstructorCallMessage;
if (null != ccm)
{
return ccm.GetLogicalCallContext();
}
else if (_ccmsg is ConstructionCall)
{
// This is the case where the message got serialized
// and deserialized
return((MethodCall)_ccmsg).GetLogicalCallContext();
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
}
internal override void SetSpecialKey(int keyNum, Object value)
{
switch (keyNum)
{
case 0:
((ConstructorCallMessage)_ccmsg).Uri = (String)value;
break;
case 1:
((ConstructorCallMessage)_ccmsg).SetLogicalCallContext(
(LogicalCallContext)value);
break;
default:
// We should not get here!
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
}
}
//+========================================================================
//
// Synopsis: Specialization of MessageDictionary for ConstructorCallMessage objects
//
//-========================================================================
internal class CRMDictionary : MessageDictionary
{
public static String[] CRMkeysFault = {
"__Uri",
"__MethodName",
"__MethodSignature",
"__TypeName",
"__CallContext"};
public static String[] CRMkeysNoFault = {
"__Uri",
"__MethodName",
"__MethodSignature",
"__TypeName",
"__Return",
"__OutArgs",
"__CallContext"};
internal IConstructionReturnMessage _crmsg;
internal bool fault;
public CRMDictionary(IConstructionReturnMessage msg, IDictionary idict)
: base( (msg.Exception!=null)? CRMkeysFault : CRMkeysNoFault, idict)
{
fault = (msg.Exception != null) ;
_crmsg = msg;
}
internal override Object GetMessageValue(int i)
{
switch (i)
{
case 0:
return _crmsg.Uri;
case 1:
return _crmsg.MethodName;
case 2:
return _crmsg.MethodSignature;
case 3:
return _crmsg.TypeName;
case 4:
return fault ? FetchLogicalCallContext() : _crmsg.ReturnValue;
case 5:
return _crmsg.Args;
case 6:
return FetchLogicalCallContext();
}
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
private LogicalCallContext FetchLogicalCallContext()
{
ReturnMessage retMsg = _crmsg as ReturnMessage;
if (null != retMsg)
{
return retMsg.GetLogicalCallContext();
}
else
{
MethodResponse mr = _crmsg as MethodResponse;
if (null != mr)
{
return mr.GetLogicalCallContext();
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
}
}
internal override void SetSpecialKey(int keyNum, Object value)
{
// NOTE: we use this for Uri & CallContext only ...
ReturnMessage rm = _crmsg as ReturnMessage;
MethodResponse mr = _crmsg as MethodResponse;
switch(keyNum)
{
case 0:
if (null != rm)
{
rm.Uri = (String)value;
}
else
{
if (null != mr)
{
mr.Uri = (String)value;
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
}
break;
case 1:
if (null != rm)
{
rm.SetLogicalCallContext((LogicalCallContext)value);
}
else
{
if (null != mr)
{
mr.SetLogicalCallContext((LogicalCallContext)value);
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
}
break;
default:
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
}
}
//+===============================================================================
//
// Synopsis: Specialization of MessageDictionary for MethodCallMessage
//
//-========================================================================
internal class MCMDictionary : MessageDictionary
{
public static String[] MCMkeys = {
"__Uri",
"__MethodName",
"__MethodSignature",
"__TypeName",
"__Args",
"__CallContext"};
internal IMethodCallMessage _mcmsg; // back pointer to message object
public MCMDictionary(IMethodCallMessage msg, IDictionary idict)
: base(MCMkeys, idict)
{
_mcmsg = msg;
}
internal override Object GetMessageValue(int i)
{
switch (i)
{
case 0:
return _mcmsg.Uri;
case 1:
return _mcmsg.MethodName;
case 2:
return _mcmsg.MethodSignature;
case 3:
return _mcmsg.TypeName;
case 4:
return _mcmsg.Args;
case 5:
return FetchLogicalCallContext();
}
// Shouldn't get here.
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
private LogicalCallContext FetchLogicalCallContext()
{
Message msg = _mcmsg as Message;
if (null != msg)
{
return msg.GetLogicalCallContext();
}
else
{
MethodCall mc = _mcmsg as MethodCall;
if (null != mc)
{
return mc.GetLogicalCallContext();
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
}
}
internal override void SetSpecialKey(int keyNum, Object value)
{
Message msg = _mcmsg as Message;
MethodCall mc = _mcmsg as MethodCall;
switch (keyNum)
{
case 0:
if(null != msg)
{
msg.Uri = (String)value;
}
else if (null != mc)
{
mc.Uri = (String)value;
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
break;
case 1:
if(null != msg)
{
msg.SetLogicalCallContext((LogicalCallContext)value);
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
break;
default:
// Shouldn't get here.
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
}
}
//+===============================================================================
//
// Synopsis: Specialization of MessageDictionary for MethodReturnMessage objects
//
//-===============================================================================
internal class MRMDictionary : MessageDictionary
{
public static String[] MCMkeysFault = {"__CallContext"};
public static String[] MCMkeysNoFault = {
"__Uri",
"__MethodName",
"__MethodSignature",
"__TypeName",
"__Return",
"__OutArgs",
"__CallContext"};
internal IMethodReturnMessage _mrmsg;
internal bool fault;
public MRMDictionary(IMethodReturnMessage msg, IDictionary idict)
: base((msg.Exception != null) ? MCMkeysFault : MCMkeysNoFault, idict)
{
fault = (msg.Exception != null) ;
_mrmsg = msg;
}
internal override Object GetMessageValue(int i)
{
switch (i)
{
case 0:
if (fault)
return FetchLogicalCallContext();
else
return _mrmsg.Uri;
case 1:
return _mrmsg.MethodName;
case 2:
return _mrmsg.MethodSignature;
case 3:
return _mrmsg.TypeName;
case 4:
if (fault)
{
return _mrmsg.Exception;
}
else
{
return _mrmsg.ReturnValue;
}
case 5:
return _mrmsg.Args;
case 6:
return FetchLogicalCallContext();
}
// Shouldn't get here.
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
private LogicalCallContext FetchLogicalCallContext()
{
ReturnMessage rm = _mrmsg as ReturnMessage;
if (null != rm)
{
return rm.GetLogicalCallContext();
}
else
{
MethodResponse mr = _mrmsg as MethodResponse;
if (null != mr)
{
return mr.GetLogicalCallContext();
}
else
{
StackBasedReturnMessage srm = _mrmsg as StackBasedReturnMessage;
if (null != srm)
{
return srm.GetLogicalCallContext();
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
}
}
}
internal override void SetSpecialKey(int keyNum, Object value)
{
// 0 == Uri
// 1 == CallContext
// NOTE : we use this for Uri & CallContext only ...
ReturnMessage rm = _mrmsg as ReturnMessage;
MethodResponse mr = _mrmsg as MethodResponse;
switch (keyNum)
{
case 0:
if (null != rm)
{
rm.Uri = (String)value;
}
else
{
if (null != mr)
{
mr.Uri = (String)value;
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
}
break;
case 1:
if (null != rm)
{
rm.SetLogicalCallContext((LogicalCallContext)value);
}
else
{
if (null != mr)
{
mr.SetLogicalCallContext((LogicalCallContext)value);
}
else
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadType"));
}
}
break;
default:
// Shouldn't get here.
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
}
}
//+===============================================================================
//
// Synopsis: Abstract class to help present a dictionary view of an object
//
//-================================================================================
internal abstract class MessageDictionary : IDictionary
{
internal String[] _keys;
internal IDictionary _dict;
internal MessageDictionary(String[] keys, IDictionary idict)
{
_keys = keys;
_dict = idict;
}
internal bool HasUserData()
{
// used by message smuggler to determine if there is any custom user
// data in the dictionary
if ((_dict != null) && (_dict.Count > 0))
return true;
else
return false;
}
// used by message smuggler, so that it doesn't have to iterate
// through special keys
internal IDictionary InternalDictionary
{
get { return _dict; }
}
internal abstract Object GetMessageValue(int i);
internal abstract void SetSpecialKey(int keyNum, Object value);
public virtual bool IsReadOnly { get { return false; } }
public virtual bool IsSynchronized { get { return false; } }
public virtual bool IsFixedSize { get { return false; } }
public virtual Object SyncRoot { get { return this; } }
public virtual bool Contains(Object key)
{
if (ContainsSpecialKey(key))
{
return true;
}
else if (_dict != null)
{
return _dict.Contains(key);
}
return false;
}
protected virtual bool ContainsSpecialKey(Object key)
{
if (!(key is System.String))
{
return false;
}
String skey = (String) key;
for (int i = 0 ; i < _keys.Length; i++)
{
if (skey.Equals(_keys[i]))
{
return true;
}
}
return false;
}
public virtual void CopyTo(Array array, int index)
{
for (int i=0; i<_keys.Length; i++)
{
array.SetValue(GetMessageValue(i), index+i);
}
if (_dict != null)
{
_dict.CopyTo(array, index+_keys.Length);
}
}
public virtual Object this[Object key]
{
get
{
System.String skey = key as System.String;
if (null != skey)
{
for (int i=0; i<_keys.Length; i++)
{
if (skey.Equals(_keys[i]))
{
return GetMessageValue(i);
}
}
if (_dict != null)
{
return _dict[key];
}
}
return null;
}
set
{
if (ContainsSpecialKey(key))
{
if (key.Equals(Message.UriKey))
{
SetSpecialKey(0,value);
}
else if (key.Equals(Message.CallContextKey))
{
SetSpecialKey(1,value);
}
else
{
throw new ArgumentException(
Environment.GetResourceString(
"Argument_InvalidKey"));
}
}
else
{
if (_dict == null)
{
_dict = new Hashtable();
}
_dict[key] = value;
}
}
}
IDictionaryEnumerator IDictionary.GetEnumerator()
{
return new MessageDictionaryEnumerator(this, _dict);
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotSupportedException();
}
public virtual void Add(Object key, Object value)
{
if (ContainsSpecialKey(key))
{
throw new ArgumentException(
Environment.GetResourceString(
"Argument_InvalidKey"));
}
else
{
if (_dict == null)
{
// no need to interlock, message object not guaranteed to
// be thread-safe.
_dict = new Hashtable();
}
_dict.Add(key, value);
}
}
public virtual void Clear()
{
// Remove all the entries from the hash table
if (null != _dict)
{
_dict.Clear();
}
}
public virtual void Remove(Object key)
{
if (ContainsSpecialKey(key) || (_dict == null))
{
throw new ArgumentException(
Environment.GetResourceString(
"Argument_InvalidKey"));
}
else
{
_dict.Remove(key);
}
}
public virtual ICollection Keys
{
get
{
int len = _keys.Length;
ICollection c = (_dict != null) ? _dict.Keys : null;
if (c != null)
{
len += c.Count;
}
ArrayList l = new ArrayList(len);
for (int i = 0; i<_keys.Length; i++)
{
l.Add(_keys[i]);
}
if (c != null)
{
l.AddRange(c);
}
return l;
}
}
public virtual ICollection Values
{
get
{
int len = _keys.Length;
ICollection c = (_dict != null) ? _dict.Keys : null;
if (c != null)
{
len += c.Count;
}
ArrayList l = new ArrayList(len);
for (int i = 0; i<_keys.Length; i++)
{
l.Add(GetMessageValue(i));
}
if (c != null)
{
l.AddRange(c);
}
return l;
}
}
public virtual int Count
{
get
{
if (_dict != null)
{
return _dict.Count+_keys.Length;
}
else
{
return _keys.Length;
}
}
}
}
//+===============================================================================
//
// Synopsis: Dictionary enumerator for helper class
//
//-================================================================================
internal class MessageDictionaryEnumerator : IDictionaryEnumerator
{
private int i=-1;
private IDictionaryEnumerator _enumHash;
private MessageDictionary _md;
public MessageDictionaryEnumerator(MessageDictionary md, IDictionary hashtable)
{
_md = md;
if (hashtable != null)
{
_enumHash = hashtable.GetEnumerator();
}
else
{
_enumHash = null;
}
}
// Returns the key of the current element of the enumeration. The returned
// value is undefined before the first call to GetNext and following
// a call to GetNext that returned false. Multiple calls to
// GetKey with no intervening calls to GetNext will return
// the same object.
//
public Object Key {
get {
Message.DebugOut("MessageDE::GetKey i = " + i + "\n");
if (i < 0)
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
if (i < _md._keys.Length)
{
return _md._keys[i];
}
else
{
BCLDebug.Assert(_enumHash != null,"_enumHash != null");
return _enumHash.Key;
}
}
}
// Returns the value of the current element of the enumeration. The
// returned value is undefined before the first call to GetNext and
// following a call to GetNext that returned false. Multiple calls
// to GetValue with no intervening calls to GetNext will
// return the same object.
//
public Object Value {
get {
if (i < 0)
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
if (i < _md._keys.Length)
{
return _md.GetMessageValue(i);
}
else
{
BCLDebug.Assert(_enumHash != null,"_enumHash != null");
return _enumHash.Value;
}
}
}
// Advances the enumerator to the next element of the enumeration and
// returns a boolean indicating whether an element is available. Upon
// creation, an enumerator is conceptually positioned before the first
// element of the enumeration, and the first call to GetNext brings
// the first element of the enumeration into view.
//
public bool MoveNext()
{
if (i == -2)
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
i++;
if (i < _md._keys.Length)
{
return true;
}
else
{
if (_enumHash != null && _enumHash.MoveNext())
{
return true;
}
else
{
i = -2;
return false;
}
}
}
// Returns the current element of the enumeration. The returned value is
// undefined before the first call to MoveNext and following a call
// to MoveNext that returned false. Multiple calls to
// Current with no intervening calls to MoveNext will return
// the same object.
//
public Object Current {
get {
return Entry;
}
}
public DictionaryEntry Entry {
get {
return new DictionaryEntry(Key, Value);
}
}
// Resets the enumerator, positioning it before the first element. If an
// Enumerator doesn't support Reset, a NotSupportedException is
// thrown.
public void Reset()
{
i = -1;
if (_enumHash != null)
{
_enumHash.Reset();
}
}
}
//+================================================================================
//
// Synopsis: Message for return from a stack blit call
//
//-===============================================================================
internal class StackBasedReturnMessage : IMethodReturnMessage, IInternalMessage
{
Message _m;
Hashtable _h;
MRMDictionary _d;
ArgMapper _argMapper;
internal StackBasedReturnMessage() {}
// NOTE: This method is called multiple times as we reuse the
// message object. Make sure that you reset any fields that you
// add to the message object to the default values. This will
// ensure that the reused message object starts with the correct
// values.
internal void InitFields(Message m)
{
_m = m;
if (null != _h)
{
// Remove all the hashtable entries
_h.Clear();
}
if (null != _d)
{
// Remove all the dictionary entries
_d.Clear();
}
}
public String Uri { get {return _m.Uri;}}
public String MethodName { get {return _m.MethodName;}}
public String TypeName { get {return _m.TypeName;}}
public Object MethodSignature { get {return _m.MethodSignature;}}
public MethodBase MethodBase { get {return _m.MethodBase;}}
public bool HasVarArgs { get {return _m.HasVarArgs;}}
public int ArgCount { get {return _m.ArgCount;}}
public Object GetArg(int argNum) {return _m.GetArg(argNum);}
public String GetArgName(int index) {return _m.GetArgName(index);}
public Object[] Args { get {return _m.Args;}}
public LogicalCallContext LogicalCallContext { get { return _m.GetLogicalCallContext(); } }
internal LogicalCallContext GetLogicalCallContext() {return _m.GetLogicalCallContext();}
internal LogicalCallContext SetLogicalCallContext(LogicalCallContext callCtx)
{
return _m.SetLogicalCallContext(callCtx);
}
public int OutArgCount
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.ArgCount;
}
}
public Object GetOutArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArg(argNum);
}
public String GetOutArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArgName(index);
}
public Object[] OutArgs
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.Args;
}
}
public Exception Exception { get {return null;}}
public Object ReturnValue { get {return _m.GetReturnValue();}}
public IDictionary Properties
{
get
{
lock(this)
{
if (_h == null)
{
_h = new Hashtable();
}
if (_d == null)
{
_d = new MRMDictionary(this, _h);
}
return _d;
}
}
}
//
// IInternalMessage
//
ServerIdentity IInternalMessage.ServerIdentityObject
{
get { return null; }
set {}
}
Identity IInternalMessage.IdentityObject
{
get { return null;}
set {}
}
void IInternalMessage.SetURI(String val)
{
_m.Uri = val;
}
void IInternalMessage.SetCallContext(LogicalCallContext newCallContext)
{
_m.SetLogicalCallContext(newCallContext);
}
bool IInternalMessage.HasProperties()
{
return _h != null;
}
} // class StackBasedReturnMessage
//+================================================================================
//
// Synopsis: Message for return from a stack builder sink call
//
//-===============================================================================
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[System.Runtime.InteropServices.ComVisible(true)]
public class ReturnMessage : IMethodReturnMessage
{
internal Object _ret;
internal Object _properties;
internal String _URI;
internal Exception _e;
internal Object[] _outArgs;
internal int _outArgsCount;
internal String _methodName;
internal String _typeName;
internal Type[] _methodSignature;
internal bool _hasVarArgs;
internal LogicalCallContext _callContext;
internal ArgMapper _argMapper;
internal MethodBase _methodBase;
public ReturnMessage(Object ret, Object[] outArgs, int outArgsCount, LogicalCallContext callCtx,
IMethodCallMessage mcm)
{
_ret = ret;
_outArgs = outArgs;
_outArgsCount = outArgsCount;
if (callCtx != null)
_callContext = callCtx;
else
_callContext = CallContext.GetLogicalCallContext();
if (mcm != null)
{
_URI = mcm.Uri;
_methodName = mcm.MethodName;
_methodSignature = null;
_typeName = mcm.TypeName;
_hasVarArgs = mcm.HasVarArgs;
_methodBase = mcm.MethodBase;
}
}
public ReturnMessage(Exception e, IMethodCallMessage mcm)
{
_e = IsCustomErrorEnabled()? new RemotingException(Environment.GetResourceString("Remoting_InternalError")):e;
_callContext = CallContext.GetLogicalCallContext();
if (mcm != null)
{
_URI = mcm.Uri;
_methodName = mcm.MethodName;
_methodSignature = null;
_typeName = mcm.TypeName;
_hasVarArgs = mcm.HasVarArgs;
_methodBase = mcm.MethodBase;
}
}
public String Uri { get { return _URI; } set { _URI = value; } }
public String MethodName { get { return _methodName; } }
public String TypeName { get { return _typeName; } }
public Object MethodSignature
{
get
{
if ((_methodSignature == null) && (_methodBase != null))
_methodSignature = Message.GenerateMethodSignature(_methodBase);
return _methodSignature;
}
}
public MethodBase MethodBase { get { return _methodBase; } }
public bool HasVarArgs
{
get
{
return _hasVarArgs;
}
}
public int ArgCount
{
get
{
if (_outArgs == null)
{
return _outArgsCount;
}
else
{
return _outArgs.Length;
}
}
}
public Object GetArg(int argNum)
{
if (_outArgs == null)
{
if ((argNum<0) || (argNum>=_outArgsCount))
{
throw new ArgumentOutOfRangeException("argNum");
}
return null;
}
else
{
if ((argNum<0) || (argNum>=_outArgs.Length))
{
throw new ArgumentOutOfRangeException("argNum");
}
return _outArgs[argNum];
}
}
public String GetArgName(int index)
{
if (_outArgs == null)
{
if ((index < 0) || (index>=_outArgsCount))
{
throw new ArgumentOutOfRangeException("index");
}
}
else
{
if ((index < 0) || (index>=_outArgs.Length))
{
throw new ArgumentOutOfRangeException("index");
}
}
if (_methodBase != null)
{
RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(_methodBase);
return methodCache.Parameters[index].Name;
}
else
return "__param" + index;
}
public Object[] Args
{
get
{
if (_outArgs == null)
{
return new Object[_outArgsCount];
}
return _outArgs;
}
}
public int OutArgCount
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.ArgCount;
}
}
public Object GetOutArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArg(argNum);
}
public String GetOutArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArgName(index);
}
public Object[] OutArgs
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.Args;
}
}
public Exception Exception { get {return _e;}}
public virtual Object ReturnValue { get {return _ret;}}
public virtual IDictionary Properties
{
get
{
if (_properties == null)
{
_properties = new MRMDictionary(this, null);
}
return(MRMDictionary) _properties;
}
}
public LogicalCallContext LogicalCallContext
{
get { return GetLogicalCallContext();}
}
internal LogicalCallContext GetLogicalCallContext()
{
if (_callContext == null)
_callContext = new LogicalCallContext();
return _callContext;
}
internal LogicalCallContext SetLogicalCallContext(LogicalCallContext ctx)
{
LogicalCallContext old = _callContext;
_callContext=ctx;
return old;
}
// used to determine if the properties dictionary has already been created
internal bool HasProperties()
{
return _properties != null;
}
static internal bool IsCustomErrorEnabled(){
Object oIsCustomErrorEnabled = CallContext.GetData("__CustomErrorsEnabled");
// The server side will always have this CallContext item set. If it is not set then
// it means this is the client side. In that case customError is false.
return (oIsCustomErrorEnabled == null) ? false:(bool)oIsCustomErrorEnabled;
}
} // class ReturnMessage
//+===============================================================================
//
// Synopsis: Message used for deserialization of a method call
//
//-===============================================================================
///
[Serializable,CLSCompliant(false)]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[System.Runtime.InteropServices.ComVisible(true)]
public class MethodCall : IMethodCallMessage, ISerializable, IInternalMessage, ISerializationRootObject
{
private const BindingFlags LookupAll = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
private const BindingFlags LookupPublic = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
// data
private String uri;
private String methodName;
private MethodBase MI;
private String typeName;
private Object[] args;
private Type[] instArgs;
private LogicalCallContext callContext;
private Type[] methodSignature;
///
protected IDictionary ExternalProperties = null;
///
protected IDictionary InternalProperties = null;
private ServerIdentity srvID;
private Identity identity;
private bool fSoap;
private bool fVarArgs = false;
private ArgMapper argMapper;
//
// MethodCall -- SOAP uses this constructor
//
///
public MethodCall(Header[] h1)
{
Message.DebugOut("MethodCall ctor IN headers: " + (h1 == null ? "" : h1.ToString()) + "\n");
Init();
fSoap = true;
FillHeaders(h1);
ResolveMethod();
Message.DebugOut("MethodCall ctor OUT\n");
}
//
// MethodCall -- this constructor is used for copying an existing message
//
public MethodCall(IMessage msg)
{
if (msg == null)
throw new ArgumentNullException("msg");
Init();
IDictionaryEnumerator de = msg.Properties.GetEnumerator();
while (de.MoveNext())
{
FillHeader(de.Key.ToString(), de.Value);
}
IMethodCallMessage mcm = msg as IMethodCallMessage;
if (mcm != null)
MI = mcm.MethodBase;
ResolveMethod();
}
internal MethodCall(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
Init();
SetObjectData(info, context);
}
internal MethodCall(SmuggledMethodCallMessage smuggledMsg, ArrayList deserializedArgs)
{
uri = smuggledMsg.Uri;
typeName = smuggledMsg.TypeName;
methodName = smuggledMsg.MethodName;
methodSignature = (Type[])smuggledMsg.GetMethodSignature(deserializedArgs);
args = smuggledMsg.GetArgs(deserializedArgs);
instArgs = smuggledMsg.GetInstantiation(deserializedArgs);
callContext = smuggledMsg.GetCallContext(deserializedArgs);
ResolveMethod();
if (smuggledMsg.MessagePropertyCount > 0)
smuggledMsg.PopulateMessageProperties(Properties, deserializedArgs);
}
internal MethodCall(Object handlerObject, BinaryMethodCallMessage smuggledMsg)
{
if (handlerObject != null)
{
uri = handlerObject as String;
if (uri == null)
{
// This must be the tranparent proxy
MarshalByRefObject mbr = handlerObject as MarshalByRefObject;
if (mbr != null)
{
bool fServer;
srvID = MarshalByRefObject.GetIdentity(mbr, out fServer) as ServerIdentity;
uri = srvID.URI;
}
}
}
typeName = smuggledMsg.TypeName;
methodName = smuggledMsg.MethodName;
methodSignature = (Type[])smuggledMsg.MethodSignature;
args = smuggledMsg.Args;
instArgs = smuggledMsg.InstantiationArgs;
callContext = smuggledMsg.LogicalCallContext;
ResolveMethod();
if (smuggledMsg.HasProperties)
smuggledMsg.PopulateMessageProperties(Properties);
}
//
// ISerializationRootObject
//
///
public void RootSetObjectData(SerializationInfo info, StreamingContext ctx)
{
SetObjectData(info, ctx);
}
//
// SetObjectData -- the class can also be initialized in part or in whole by serialization
// in the SOAP case, both the constructor and SetObjectData init the object, in the non-SOAP
// case, just SetObjectData is called
//
internal void SetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
if (fSoap)
{
SetObjectFromSoapData(info);
}
else
{
SerializationInfoEnumerator siEnum = info.GetEnumerator();
while (siEnum.MoveNext())
{
FillHeader(siEnum.Name, siEnum.Value);
}
if ((context.State == StreamingContextStates.Remoting) &&
(context.Context != null))
{
Header[] h = context.Context as Header[];
if(null != h)
{
for (int i=0; i
public void ResolveMethod()
{
ResolveMethod(true);
}
internal void ResolveMethod(bool bThrowIfNotResolved)
{
if ((MI == null) && (methodName != null))
{
BCLDebug.Trace("REMOTE", "TypeName: " + (typeName == null ? "" : typeName) + "\n");
// resolve type
RuntimeType t = ResolveType() as RuntimeType;
BCLDebug.Trace("REMOTE", "Type: " + (t == null ? "" : t.ToString()) + "\n");
if (methodName.Equals(".ctor"))
return;
if (t == null)
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_BadType"),
typeName));
}
// Note: we reflect on non-public members here .. we do
// block incoming remote calls and allow only specific methods
// that we use for implementation of certain features (eg.
// for remote field access)
// ************************************************************
// Note: For the common (non-overloaded method, urt-to-urt) case
// methodSignature is null.
// If the call is from a urt client to an overloaded method,
// methodSignature is non-null. We could have a non-null
// methodSignature if the call is from a non-urt client for
// which we have to do special work if the method is overloaded
// (in the try-catch below).
// ***********************************************************
if (null != methodSignature)
{
// We might still get an AmbiguousMatchException here if
// there are multiple methods with the same name and
// signature distinguished only by their arity (reflection
// doesn't currently provide a way to filter on this in a
// GetMethod call). This should be reasonably rare, so
// handle the common case efficiently and back off to a
// slower algorithm only if necessary.
try
{
MI = t.GetMethod(methodName,
MethodCall.LookupAll,
null,
CallingConventions.Any,
methodSignature,
null);
}
catch (AmbiguousMatchException)
{
// Make a list of all the methods with the right name.
MemberInfo [] methods = t.FindMembers(MemberTypes.Method, MethodCall.LookupAll, Type.FilterName, methodName);
// Filter out all the methods with the wrong arity.
// (Compress them into the start of the array then copy
// them into a new array of exactly the right length).
int arity = instArgs == null ? 0 : instArgs.Length;
int candidates = 0;
for (int i = 0; i < methods.Length; i++)
{
MethodInfo mi = (MethodInfo)methods[i];
int miArity = mi.IsGenericMethod ? mi.GetGenericArguments().Length : 0;
if (miArity == arity)
{
// Got a candidate, compress it back to the
// start of the array if necessary.
if (i > candidates)
methods[candidates] = methods[i];
candidates++;
}
}
MethodInfo[] matches = new MethodInfo[candidates];
for (int i = 0; i < candidates; i++)
matches[i] = (MethodInfo)methods[i];
// Use the default binder to select the right overload
// based on signature.
MI = Type.DefaultBinder.SelectMethod(MethodCall.LookupAll,
matches,
methodSignature,
null);
}
if (instArgs != null && instArgs.Length > 0)
MI = ((MethodInfo)MI).MakeGenericMethod(instArgs);
BCLDebug.Trace("REMOTE", "Method resolved w/sig ", MI == null ? "" : "");
}
else
{
// Check the cache to see if you find the methodbase (unless
// the method has an instantiation, in which case the method
// name is not a unique key).
RemotingTypeCachedData typeCache = null;
if (instArgs == null)
{
typeCache = InternalRemotingServices.GetReflectionCachedData(t);
MI = typeCache.GetLastCalledMethod(methodName);
if (MI != null)
return;
}
// This could give us the wrong MethodBase because
// the server and the client types could be of different
// versions. The mismatch is caught either when the server has
// more than one method defined with the same name or when we
// coerce the args and the incoming argument types do not match
// the method signature.
BCLDebug.Assert(
!methodName.Equals(".ctor"),
"unexpected method type");
bool bOverloaded = false;
try
{
MI = t.GetMethod(methodName,
MethodCall.LookupAll);
if (instArgs != null && instArgs.Length > 0)
MI = ((MethodInfo)MI).MakeGenericMethod(instArgs);
BCLDebug.Trace("REMOTE", "Method resolved w/name ", MI == null ? "" : methodName);
BCLDebug.Trace("REMOTE", "sig not filled in!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
catch (AmbiguousMatchException)
{
// This is the case when no methodSignature was found
// but the method is overloaded ..
// (possibly because a non-URT client called us)
bOverloaded = true;
ResolveOverloadedMethod(t);
} //catch
// In the non-URT call, overloaded case, don't cache the MI
// Avoid caching generic methods -- their names aren't a unique key.
if (MI != null && !bOverloaded && typeCache != null)
typeCache.SetLastCalledMethod(methodName, MI);
}
if (MI == null && bThrowIfNotResolved)
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_Message_MethodMissing"),
methodName,
typeName));
}
}
}
// Helper that gets called when we attempt to resolve a method
// without an accompanying methodSignature ... current thinking is
// that we should make a good faith attempt by matching argument
// counts
void ResolveOverloadedMethod(RuntimeType t)
{
// args is null the first call from soap because we havem't passed the arguments yet.
if (args == null)
return;
MemberInfo[] canidates = t.GetMember(methodName, MemberTypes.Method, MethodCall.LookupPublic);
int canidatesCount = canidates.Length;
if (canidatesCount == 1)
{
MI = canidates[0] as MethodBase;
return;
}
if (canidatesCount == 0)
return;
int argCount = args.Length;
MethodBase match = null;
// We will let resolve succeed if exactly one of the overloaded methods matches in terms of argCount
for (int i = 0; i < canidatesCount; i++)
{
MethodBase canidate = canidates[i] as MethodBase;
if (canidate.GetParameters().Length == argCount)
{
if (match != null)
throw new RemotingException(Environment.GetResourceString("Remoting_AmbiguousMethod"));
match = canidate;
}
}
if (match != null)
MI = match;
}
// This will find the right overloaded method if the argValues from soap have type information,
// By default parameters will be of type string, this could lead to a wrong choice of methodbase.
void ResolveOverloadedMethod(RuntimeType t, String methodName, ArrayList argNames, ArrayList argValues)
{
MemberInfo[] canidates = t.GetMember(methodName, MemberTypes.Method, MethodCall.LookupPublic);
int canidatesCount = canidates.Length;
if (canidatesCount == 1)
{
MI = canidates[0] as MethodBase;
return;
}
if (canidatesCount == 0)
return;
MethodBase match = null;
for (int i = 0; i < canidatesCount; i++)
{
MethodBase canidate = canidates[i] as MethodBase;
ParameterInfo[] parameters = canidate.GetParameters();
if (parameters.Length == argValues.Count)
{
bool isMatch = true;
for (int j = 0; j < parameters.Length; j++)
{
Type parameterType = parameters[j].ParameterType;
if (parameterType.IsByRef)
parameterType = parameterType.GetElementType();
if (parameterType != argValues[j].GetType())
{
isMatch = false;
break;
}
}
if (isMatch)
{
match = canidate;
break;
}
}
}
if (match == null)
throw new RemotingException(Environment.GetResourceString("Remoting_AmbiguousMethod"));
MI = match;
}
//
// GetObjectData -- not implemented
//
///
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(
Environment.GetResourceString("NotSupported_Method"));
}
//
// SetObjectFromSoapData -- parses soap format for serialization data
//
internal void SetObjectFromSoapData(SerializationInfo info)
{
// resolve method
methodName = info.GetString("__methodName");
ArrayList paramNames = (ArrayList)info.GetValue("__paramNameList", typeof(ArrayList));
Hashtable keyToNamespaceTable = (Hashtable)info.GetValue("__keyToNamespaceTable", typeof(Hashtable));
if (MI == null)
{
// This is the case where
// 1) there is no signature in the header,
// 2) there is an overloaded method which can not be resolved by a difference in the number of parameters.
//
// The methodbase can be found only if the parameters from soap have type information
ArrayList argValues = new ArrayList();
ArrayList argNames = paramNames;
// SerializationInfoEnumerator siEnum1 = info.GetEnumerator();
for (int i=0; i>"
+ memberName.Substring(7) + "<<\n");
int position = -1;
for (int j=0; j= args.Length)
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadSerialization"));
}
args[position] = Message.SoapCoerceArg(info.GetValue(memberName, typeof(Object)), pinfos[position].ParameterType, keyToNamespaceTable);
}
}
else
{
for (int i=0; i
public virtual void Init()
{
}
//
// IMethodCallMessage
//
///
public int ArgCount
{
get
{
return(args == null) ? 0 : args.Length;
}
}
///
public Object GetArg(int argNum)
{
return args[argNum];
}
///
public String GetArgName(int index)
{
ResolveMethod();
RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
return methodCache.Parameters[index].Name;
}
///
public Object[] Args
{
get
{
return args;
}
}
///
public int InArgCount
{
get
{
if (argMapper == null) argMapper = new ArgMapper(this, false);
return argMapper.ArgCount;
}
}
///
public Object GetInArg(int argNum)
{
if (argMapper == null) argMapper = new ArgMapper(this, false);
return argMapper.GetArg(argNum);
}
///
public String GetInArgName(int index)
{
if (argMapper == null) argMapper = new ArgMapper(this, false);
return argMapper.GetArgName(index);
}
///
public Object[] InArgs
{
get
{
if (argMapper == null) argMapper = new ArgMapper(this, false);
return argMapper.Args;
}
}
///
public String MethodName { get { return methodName; } }
///
public String TypeName { get { return typeName; } }
///
public Object MethodSignature
{
get
{
if (methodSignature != null)
return methodSignature;
else if (MI != null)
methodSignature = Message.GenerateMethodSignature(this.MethodBase);
return null;
}
}
///
public MethodBase MethodBase
{
get
{
if (MI == null)
MI = RemotingServices.InternalGetMethodBaseFromMethodMessage(this);
return MI;
}
}
///
public String Uri
{
get { return uri; }
set { uri = value; }
}
///
public bool HasVarArgs
{
get { return fVarArgs; }
}
///
public virtual IDictionary Properties
{
get
{
lock(this) {
if (InternalProperties == null)
{
InternalProperties = new Hashtable();
}
if (ExternalProperties == null)
{
ExternalProperties = new MCMDictionary(this, InternalProperties);
}
return ExternalProperties;
}
}
}
///
public LogicalCallContext LogicalCallContext { get { return GetLogicalCallContext();} }
internal LogicalCallContext GetLogicalCallContext()
{
if (callContext == null)
callContext = new LogicalCallContext();
return callContext;
}
internal LogicalCallContext SetLogicalCallContext(LogicalCallContext ctx)
{
LogicalCallContext old=callContext;
callContext=ctx;
return old;
}
//
// IInternalMessage
//
///
ServerIdentity IInternalMessage.ServerIdentityObject
{
get { return srvID;}
set {srvID = value;}
}
///
Identity IInternalMessage.IdentityObject
{
get { return identity;}
set { identity = value;}
}
///
void IInternalMessage.SetURI(String val)
{
uri = val;
}
///
void IInternalMessage.SetCallContext(LogicalCallContext newCallContext)
{
callContext = newCallContext;
}
///
bool IInternalMessage.HasProperties()
{
return (ExternalProperties != null) || (InternalProperties != null);
}
//
// helper functions
//
internal void FillHeaders(Header[] h)
{
FillHeaders(h, false);
}
private void FillHeaders(Header[] h, bool bFromHeaderHandler)
{
if (h == null)
return;
if (bFromHeaderHandler && fSoap)
{
// Handle the case of headers coming off the wire in SOAP.
// look for message properties
int co;
for (co = 0; co < h.Length; co++)
{
Header header = h[co];
if (header.HeaderNamespace == "http://schemas.microsoft.com/clr/soap/messageProperties")
{
// add property to the message
FillHeader(header.Name, header.Value);
}
else
{
// add header to the message as a header
String name = LogicalCallContext.GetPropertyKeyForHeader(header);
FillHeader(name, header);
}
}
}
else
{
int i;
for (i=0; i
public virtual Object HeaderHandler(Header[] h)
{
SerializationMonkey m = (SerializationMonkey) FormatterServices.GetUninitializedObject(typeof(SerializationMonkey));
Header[] newHeaders = null;
if (h != null && h.Length > 0 && h[0].Name == "__methodName")
{
methodName = (String)h[0].Value;
if (h.Length > 1)
{
newHeaders = new Header[h.Length -1];
Array.Copy(h, 1, newHeaders, 0, h.Length-1);
}
else
newHeaders = null;
}
else
newHeaders = h;
FillHeaders(newHeaders, true);
ResolveMethod(false);
m._obj = this;
if (MI != null)
{
ArgMapper argm = new ArgMapper(MI, false);
m.fieldNames = argm.ArgNames;
m.fieldTypes = argm.ArgTypes;
}
return m;
}
}
//+================================================================================
//
// Synopsis: Message used for deserialization of a construction call
//
//-================================================================================
///
[Serializable,CLSCompliant(false)]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[System.Runtime.InteropServices.ComVisible(true)]
public class ConstructionCall : MethodCall, IConstructionCallMessage
{
//
// data
//
internal Type _activationType;
internal String _activationTypeName;
internal IList _contextProperties;
internal Object[] _callSiteActivationAttributes;
internal IActivator _activator;
/*
[NonSerialized()]
internal Object _fakeThisPtr; // used for proxyattribute::CI
*/
//
// construction
//
///
public ConstructionCall(Header[] headers) : base(headers) {}
///
public ConstructionCall(IMessage m) : base(m) {}
internal ConstructionCall(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
#if false
internal Object GetThisPtr()
{
return _fakeThisPtr;
}
internal void SetThisPtr(Object obj)
{
_fakeThisPtr = obj;
}
#endif
//
// Function: FillSpecialHeader
//
// Synopsis: this is the only specialization we need to
// make things go in the right place
//
//
internal override bool FillSpecialHeader(String key, Object value)
{
if (key == null)
{
//skip
}
else if (key.Equals("__ActivationType"))
{
BCLDebug.Assert(value==null, "Phoney type in CCM");
_activationType = null;
}
else if (key.Equals("__ContextProperties"))
{
_contextProperties = (IList) value;
}
else if (key.Equals("__CallSiteActivationAttributes"))
{
_callSiteActivationAttributes = (Object[]) value;
}
else if (key.Equals("__Activator"))
{
_activator = (IActivator) value;
}
else if (key.Equals("__ActivationTypeName"))
{
_activationTypeName = (String) value;
}
else
{
return base.FillSpecialHeader(key, value);
}
return true;
}
//
// IConstructionCallMessage
//
///
public Object[] CallSiteActivationAttributes
{
get
{
return _callSiteActivationAttributes;
}
}
///
public Type ActivationType
{
get
{
if ((_activationType == null) && (_activationTypeName != null))
_activationType = RemotingServices.InternalGetTypeFromQualifiedTypeName(_activationTypeName, false);
return _activationType;
}
}
///
public String ActivationTypeName
{
get
{
return _activationTypeName;
}
}
///
public IList ContextProperties
{
get
{
if (_contextProperties == null)
{
_contextProperties = new ArrayList();
}
return _contextProperties;
}
}
///
public override IDictionary Properties
{
get
{
lock(this)
{
if (InternalProperties == null)
{
InternalProperties = new Hashtable();
}
if (ExternalProperties == null)
{
ExternalProperties = new CCMDictionary(this, InternalProperties);
}
return ExternalProperties;
}
}
}
// IConstructionCallMessage::Activator
///
public IActivator Activator
{
get { return _activator; }
set { _activator = value;}
}
}
//+===============================================================================
//
// Synopsis: Message used for deserialization of a method response
//
//-================================================================================
///
[Serializable,CLSCompliant(false)]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[System.Runtime.InteropServices.ComVisible(true)]
public class MethodResponse : IMethodReturnMessage, ISerializable, ISerializationRootObject, IInternalMessage
{
private MethodBase MI;
private String methodName;
private Type[] methodSignature;
private String uri;
private String typeName;
private Object retVal;
private Exception fault;
private Object[] outArgs;
private LogicalCallContext callContext;
///
protected IDictionary InternalProperties;
///
protected IDictionary ExternalProperties;
private int argCount;
private bool fSoap;
private ArgMapper argMapper;
private RemotingMethodCachedData _methodCache;
// Constructor -- this constructor is called only in the SOAP Scenario
///
public MethodResponse(Header[] h1, IMethodCallMessage mcm)
{
if (mcm == null)
throw new ArgumentNullException("mcm");
Message msg = mcm as Message;
if (null != msg)
{
MI = (MethodBase)msg.GetMethodBase();
}
else
{
MI = (MethodBase)mcm.MethodBase;
}
if (MI == null)
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_Message_MethodMissing"),
mcm.MethodName,
mcm.TypeName));
}
_methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
argCount = _methodCache.Parameters.Length;
fSoap = true;
FillHeaders(h1);
}
internal MethodResponse(IMethodCallMessage msg,
SmuggledMethodReturnMessage smuggledMrm,
ArrayList deserializedArgs)
{
MI = (MethodBase)msg.MethodBase;
_methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
methodName = msg.MethodName;
uri = msg.Uri;
typeName = msg.TypeName;
if (_methodCache.IsOverloaded())
methodSignature = (Type[])msg.MethodSignature;
retVal = smuggledMrm.GetReturnValue(deserializedArgs);
outArgs = smuggledMrm.GetArgs(deserializedArgs);
fault = smuggledMrm.GetException(deserializedArgs);
callContext = smuggledMrm.GetCallContext(deserializedArgs);
if (smuggledMrm.MessagePropertyCount > 0)
smuggledMrm.PopulateMessageProperties(Properties, deserializedArgs);
argCount = _methodCache.Parameters.Length;
fSoap = false;
}
internal MethodResponse(IMethodCallMessage msg,
Object handlerObject,
BinaryMethodReturnMessage smuggledMrm)
{
if (msg != null)
{
MI = (MethodBase)msg.MethodBase;
_methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
methodName = msg.MethodName;
uri = msg.Uri;
typeName = msg.TypeName;
if (_methodCache.IsOverloaded())
methodSignature = (Type[])msg.MethodSignature;
argCount = _methodCache.Parameters.Length;
}
retVal = smuggledMrm.ReturnValue;
outArgs = smuggledMrm.Args;
fault = smuggledMrm.Exception;
callContext = smuggledMrm.LogicalCallContext;
if (smuggledMrm.HasProperties)
smuggledMrm.PopulateMessageProperties(Properties);
fSoap = false;
}
//
// SetObjectData -- this can be called with the object in two possible states. 1. the object
// is servicing a SOAP response in which it will have been half initialized by the constructor,
// or 2. the object is uninitailized and serialization is passing in the contents.
//
internal MethodResponse(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
SetObjectData(info, context);
}
///
public virtual Object HeaderHandler(Header[] h)
{
SerializationMonkey m = (SerializationMonkey) FormatterServices.GetUninitializedObject(typeof(SerializationMonkey));
Header[] newHeaders = null;
if (h != null && h.Length > 0 && h[0].Name == "__methodName")
{
if (h.Length > 1)
{
newHeaders = new Header[h.Length -1];
Array.Copy(h, 1, newHeaders, 0, h.Length-1);
}
else
newHeaders = null;
}
else
newHeaders = h;
Type retType = null;
MethodInfo mi = MI as MethodInfo;
if (mi != null)
{
retType = mi.ReturnType;
}
ParameterInfo[] pinfos = _methodCache.Parameters;
// Calculate length
int outParamsCount = _methodCache.MarshalResponseArgMap.Length;
if (!((retType == null) || (retType == typeof(void))))
outParamsCount++;
Type[] paramTypes = new Type[outParamsCount];
String[] paramNames = new String[outParamsCount];
int paramTypesIndex = 0;
if (!((retType == null) || (retType == typeof(void))))
{
paramTypes[paramTypesIndex++] = retType;
}
foreach (int i in _methodCache.MarshalResponseArgMap)
{
paramNames[paramTypesIndex] = pinfos[i].Name;
if (pinfos[i].ParameterType.IsByRef)
paramTypes[paramTypesIndex++] = pinfos[i].ParameterType.GetElementType();
else
paramTypes[paramTypesIndex++] = pinfos[i].ParameterType;
}
((IFieldInfo)m).FieldTypes = paramTypes;
((IFieldInfo)m).FieldNames = paramNames;
FillHeaders(newHeaders, true);
m._obj = this;
return m;
}
//
// ISerializationRootObject
//
///
public void RootSetObjectData(SerializationInfo info, StreamingContext ctx)
{
SetObjectData(info, ctx);
}
internal void SetObjectData(SerializationInfo info, StreamingContext ctx)
{
if (info == null)
throw new ArgumentNullException("info");
if (fSoap)
{
SetObjectFromSoapData(info);
}
else
{
SerializationInfoEnumerator e = info.GetEnumerator();
bool ret = false;
bool excep = false;
while (e.MoveNext())
{
if (e.Name.Equals("__return"))
{
ret = true;
break;
}
if (e.Name.Equals("__fault"))
{
excep = true;
fault = (Exception)e.Value;
break;
}
FillHeader(e.Name, e.Value);
}
if ((excep) && (ret))
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadSerialization"));
}
}
}
//
// ISerializable
//
//
// GetObjectData -- not implemented
//
///
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(
Environment.GetResourceString("NotSupported_Method"));
}
//
// SetObjectFromSoapData -- assumes SOAP format and populates the arguments array
//
internal void SetObjectFromSoapData(SerializationInfo info)
{
//SerializationInfoEnumerator e = info.GetEnumerator();
Hashtable keyToNamespaceTable = (Hashtable)info.GetValue("__keyToNamespaceTable", typeof(Hashtable));
ArrayList paramNames = (ArrayList)info.GetValue("__paramNameList", typeof(ArrayList));
SoapFault soapFault = (SoapFault)info.GetValue("__fault", typeof(SoapFault));
if (soapFault != null)
{
ServerFault serverFault = soapFault.Detail as ServerFault;
if (null != serverFault)
{
// Server Fault information
if (serverFault.Exception != null)
fault = serverFault.Exception;
else
{
Type exceptionType = Type.GetType(serverFault.ExceptionType, false, false);
if (exceptionType == null)
{
// Exception type cannot be resolved, use a ServerException
StringBuilder sb = new StringBuilder();
sb.Append("\nException Type: ");
sb.Append(serverFault.ExceptionType);
sb.Append("\n");
sb.Append("Exception Message: ");
sb.Append(serverFault.ExceptionMessage);
sb.Append("\n");
sb.Append(serverFault.StackTrace);
fault = new ServerException(sb.ToString());
}
else
{
// Exception type can be resolved, throw the exception
Object[] args = {serverFault.ExceptionMessage};
fault = (Exception)Activator.CreateInstance(
exceptionType,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance,
null,
args,
null,
null);
}
}
}
else if ((soapFault.Detail != null) && (soapFault.Detail.GetType() == typeof(String)) && (!(((String)soapFault.Detail).Length == 0)))
{
fault = new ServerException((String)soapFault.Detail);
}
else
{
fault = new ServerException(soapFault.FaultString);
}
return;
}
MethodInfo mi = MI as MethodInfo;
int paramNameIndex = 0;
if (mi != null)
{
Type retType = mi.ReturnType;
if (retType != typeof(void))
{
paramNameIndex++;
Object returnValue = info.GetValue((String)paramNames[0], typeof(Object));
if (returnValue is String)
retVal = Message.SoapCoerceArg(returnValue, retType, keyToNamespaceTable);
else
retVal = returnValue;
}
}
// populate the args array
ParameterInfo[] pinfos = _methodCache.Parameters;
Object fUnordered = (InternalProperties == null) ? null : InternalProperties["__UnorderedParams"];
if (fUnordered != null &&
(fUnordered is System.Boolean) &&
(true == (bool)fUnordered))
{
// Unordered
for (int i=paramNameIndex; i= argCount)
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadSerialization"));
}
// store the arg in the parameter array
if (outArgs == null)
{
outArgs = new Object[argCount];
}
outArgs[position]= Message.SoapCoerceArg(info.GetValue(memberName, typeof(Object)), pinfos[position].ParameterType, keyToNamespaceTable);
}
}
else
{
// ordered
if (argMapper == null) argMapper = new ArgMapper(this, true);
for (int j=paramNameIndex; j
public String Uri { get {return uri;} set {uri = value;}}
///
public String MethodName { get {return methodName;}}
///
public String TypeName { get {return typeName;}}
///
public Object MethodSignature { get {return methodSignature;}}
///
public MethodBase MethodBase { get {return MI;}}
///
public bool HasVarArgs
{
get {
// Var args nyi..
return false;
}
}
///
public int ArgCount
{
get
{
if (outArgs == null)
return 0;
else
return outArgs.Length;
}
}
///
public Object GetArg(int argNum) {return outArgs[argNum];}
///
public String GetArgName(int index)
{
if (MI != null)
{
RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
ParameterInfo[] paramInfo = methodCache.Parameters;
if (index < 0 || index >= paramInfo.Length)
throw new ArgumentOutOfRangeException("index");
return methodCache.Parameters[index].Name;
}
else
return "__param" + index;
}
///
public Object[] Args { get {return outArgs;}}
///
public int OutArgCount
{
get
{
if (argMapper == null) argMapper = new ArgMapper(this, true);
return argMapper.ArgCount;
}
}
///
public Object GetOutArg(int argNum)
{
if (argMapper == null) argMapper = new ArgMapper(this, true);
return argMapper.GetArg(argNum);
}
///
public String GetOutArgName(int index)
{
if (argMapper == null) argMapper = new ArgMapper(this, true);
return argMapper.GetArgName(index);
}
///
public Object[] OutArgs
{
get
{
if (argMapper == null) argMapper = new ArgMapper(this, true);
return argMapper.Args;
}
}
///
public Exception Exception { get {return fault;}}
///
public Object ReturnValue { get {return retVal;}}
///
public virtual IDictionary Properties
{
get
{
lock(this)
{
if (InternalProperties == null)
{
InternalProperties = new Hashtable();
}
if (ExternalProperties == null)
{
ExternalProperties = new MRMDictionary(this, InternalProperties);
}
return ExternalProperties;
}
}
}
///
public LogicalCallContext LogicalCallContext { get { return GetLogicalCallContext();} }
//
// helpers
//
internal void FillHeaders(Header[] h)
{
FillHeaders(h, false);
} // FillHeaders
private void FillHeaders(Header[] h, bool bFromHeaderHandler)
{
if (h == null)
return;
if (bFromHeaderHandler && fSoap)
{
// Handle the case of headers coming off the wire in SOAP.
// look for message properties
int co;
for (co = 0; co < h.Length; co++)
{
Header header = h[co];
if (header.HeaderNamespace == "http://schemas.microsoft.com/clr/soap/messageProperties")
{
// add property to the message
FillHeader(header.Name, header.Value);
}
else
{
// add header to the message as a header
String name = LogicalCallContext.GetPropertyKeyForHeader(header);
FillHeader(name, header);
}
}
}
else
{
for (int i=0; i
ServerIdentity IInternalMessage.ServerIdentityObject
{
get { return null; }
set {}
}
///
Identity IInternalMessage.IdentityObject
{
get { return null;}
set {}
}
///
void IInternalMessage.SetURI(String val)
{
uri = val;
}
///
void IInternalMessage.SetCallContext(LogicalCallContext newCallContext)
{
callContext = newCallContext;
}
///
bool IInternalMessage.HasProperties()
{
return (ExternalProperties != null) || (InternalProperties != null);
}
} // class MethodResponse
internal interface ISerializationRootObject
{
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
void RootSetObjectData(SerializationInfo info, StreamingContext ctx);
}
[Serializable]
internal class SerializationMonkey : ISerializable, IFieldInfo
{
internal ISerializationRootObject _obj;
internal String[] fieldNames = null;
internal Type[] fieldTypes = null;
internal SerializationMonkey(SerializationInfo info, StreamingContext ctx)
{
_obj.RootSetObjectData(info, ctx);
}
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(
Environment.GetResourceString(
"NotSupported_Method"));
}
public String[] FieldNames
{
get {return fieldNames;}
set {fieldNames = value;}
}
public Type[] FieldTypes
{
get {return fieldTypes;}
set {fieldTypes = value;}
}
}
//+===============================================================================
//
// Synopsis: Message used for deserialization of a method construction
//
//-===============================================================================
///
[Serializable,CLSCompliant(false)]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[System.Runtime.InteropServices.ComVisible(true)]
public class ConstructionResponse : MethodResponse, IConstructionReturnMessage
{
///
public ConstructionResponse(Header[] h, IMethodCallMessage mcm) : base(h, mcm) {}
internal ConstructionResponse(SerializationInfo info, StreamingContext context) : base (info, context) {}
///
public override IDictionary Properties
{
get
{
lock(this)
{
if (InternalProperties == null)
{
InternalProperties = new Hashtable();
}
if (ExternalProperties == null)
{
ExternalProperties = new CRMDictionary(this, InternalProperties);
}
return ExternalProperties;
}
}
}
}
// This is a special message used for helping someone make a transition
// into a Context (or AppDomain) and back out. This is intended as a replacement
// of the callBack object mechanism which is expensive since it involves
// 2 round trips (one to get the callback object) and one to make the call
// on it. Furthermore the callBack object scheme in cross domain cases would
// involve unnecessary marshal/unmarshal-s of vari'ous callBack objects.
//
// We implement IInternalMessage and do our own magic when various
// infrastructure sinks ask for serverID etc. Bottomline intent is to make
// everything look like a complete remote call with all the entailing transitions
// and executing some delegate in another context (or appdomain) without
// actually having a proxy to call "Invoke" on or a server object to "Dispatch"
// on.
[Serializable()]
internal class TransitionCall
:IMessage, IInternalMessage, IMessageSink, ISerializable
{
IDictionary _props; // For IMessage::GetDictionary
IntPtr _sourceCtxID; // Where the request emerged
IntPtr _targetCtxID; // Where the request should execute
int _targetDomainID; // Non zero if we are going to another domain
ServerIdentity _srvID; // Created serverID
Identity _ID; // Created ID
CrossContextDelegate _delegate; // The delegate to execute for the cross context case
IntPtr _eeData; // Used for DoCallbackInEE
// The _delegate should really be on an agile object otherwise
// the whole point of doing a callBack is moot. However, even if it
// is not, remoting and serialization together will ensure that
// everything happens as expected and there is no smuggling.
internal TransitionCall(
IntPtr targetCtxID,
CrossContextDelegate deleg)
{
BCLDebug.Assert(targetCtxID!=IntPtr.Zero, "bad target ctx for call back");
_sourceCtxID = Thread.CurrentContext.InternalContextID;
_targetCtxID = targetCtxID;
_delegate = deleg;
_targetDomainID = 0;
_eeData = IntPtr.Zero;
// We are going to another context in the same app domain
_srvID = new ServerIdentity(
null,
Thread.GetContextInternal(_targetCtxID));
_ID = _srvID;
_ID.RaceSetChannelSink(CrossContextChannel.MessageSink);
_srvID.RaceSetServerObjectChain(this);
//DBG Console.WriteLine("### TransitionCall ctor: " + Int32.Format(_sourceCtxID,"x") + ":" + Int32.Format(_targetCtxID,"x"));
} // TransitionCall
// This constructor should be used for cross appdomain case.
internal TransitionCall(IntPtr targetCtxID, IntPtr eeData, int targetDomainID)
{
BCLDebug.Assert(targetCtxID != IntPtr.Zero, "bad target ctx for call back");
BCLDebug.Assert(targetDomainID !=0, "bad target ctx for call back");
_sourceCtxID = Thread.CurrentContext.InternalContextID;
_targetCtxID = targetCtxID;
_delegate = null;
_targetDomainID = targetDomainID;
_eeData = eeData;
// In the cross domain case, the client side just has a base Identity
// and the server domain has the Server identity. We fault in the latter
// when requested later.
// We are going to a context in another app domain
_srvID = null;
_ID = new Identity("TransitionCallURI", null);
// Create the data needed for the channel sink creation
CrossAppDomainData data =
new CrossAppDomainData(_targetCtxID,
_targetDomainID,
Identity.ProcessGuid);
String unUsed;
IMessageSink channelSink =
CrossAppDomainChannel.AppDomainChannel.CreateMessageSink(
null, //uri
data, //channelData
out unUsed);//out objURI
BCLDebug.Assert(channelSink != null, "X-domain transition failure");
_ID.RaceSetChannelSink(channelSink);
} // TransitionCall
internal TransitionCall(SerializationInfo info, StreamingContext context)
{
if (info == null || (context.State != StreamingContextStates.CrossAppDomain))
{
throw new ArgumentNullException("info");
}
_props = (IDictionary)info.GetValue("props", typeof(IDictionary));
_delegate = (CrossContextDelegate) info.GetValue("delegate", typeof(CrossContextDelegate));
_sourceCtxID = (IntPtr) info.GetValue("sourceCtxID", typeof(IntPtr));
_targetCtxID = (IntPtr) info.GetValue("targetCtxID", typeof(IntPtr));
_eeData = (IntPtr) info.GetValue("eeData", typeof(IntPtr));
_targetDomainID = info.GetInt32("targetDomainID");
BCLDebug.Assert(_targetDomainID != 0, "target domain should be non-zero");
}
//IMessage::GetProperties
public IDictionary Properties
{
get
{
if (_props == null)
{
lock(this)
{
if (_props == null)
{
_props = new Hashtable();
}
}
}
return _props;
}
}
//IInternalMessage::ServerIdentityObject
ServerIdentity IInternalMessage.ServerIdentityObject
{
get
{
if ( (_targetDomainID!=0) && _srvID == null)
{
// We should now be in the target context! (We should not be
// attempting to get the server identity in the client domain).
BCLDebug.Assert(Thread.CurrentContext.InternalContextID
== _targetCtxID,
"ServerID requested in wrong appDomain!");
lock(this)
{
/*DBG Console.WriteLine("### Get SrvID: thrdCtxID== " + Int32.Format(Thread.CurrentContext.InternalContextID,"x"));
Console.WriteLine("### Get SrvID: _targetCtxID" + Int32.Format(_targetCtxID,"x")); DBG*/
// NOTE: if we don't have a managed context object
// corresponding to the targetCtxID ... we just use
// the default context for the AppDomain. This could
// be a problem if by some means we could have
// a non-default target VM context without a managed
// context object associated with it.
Context ctx = Thread.GetContextInternal(_targetCtxID);
if (ctx == null)
{
ctx = Context.DefaultContext;
}
BCLDebug.Assert(ctx != null, "Null target context unexpected!");
_srvID = new ServerIdentity(
null,
Thread.GetContextInternal(_targetCtxID));
_srvID.RaceSetServerObjectChain(this);
}
}
return _srvID;
}
set
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
}
//IInternalMessage::IdentityObject
Identity IInternalMessage.IdentityObject
{
get
{
return _ID;
}
set
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
}
//IInternalMessage::SetURI
void IInternalMessage.SetURI(String uri)
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
void IInternalMessage.SetCallContext(LogicalCallContext callContext)
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
bool IInternalMessage.HasProperties()
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
//IMessage::SyncProcessMessage
public IMessage SyncProcessMessage(IMessage msg)
{
BCLDebug.Assert(
Thread.CurrentContext.InternalContextID == _targetCtxID,
"Transition message routed to wrong context");
try
{
LogicalCallContext oldcctx = Message.PropagateCallContextFromMessageToThread(msg);
if (_delegate != null)
{
_delegate();
}
else
{
// This is the cross appdomain case, so we need to construct
// the delegate and call on it.
CallBackHelper cb = new CallBackHelper(
_eeData,
true /*fromEE*/,
_targetDomainID);
CrossContextDelegate ctxDel = new CrossContextDelegate(cb.Func);
ctxDel();
}
Message.PropagateCallContextFromThreadToMessage(msg, oldcctx);
}
catch (Exception e)
{
ReturnMessage retMsg = new ReturnMessage(e, new ErrorMessage());
retMsg.SetLogicalCallContext(
(LogicalCallContext) msg.Properties[Message.CallContextKey]);
return retMsg;
}
return this;
}
//IMessage::AsyncProcessMessage
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
IMessage retMsg = SyncProcessMessage(msg);
replySink.SyncProcessMessage(retMsg);
return null;
}
//IMessage::GetNextSink()
public IMessageSink NextSink
{
get{return null;}
}
//ISerializable::GetObjectData
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null || (context.State != StreamingContextStates.CrossAppDomain))
{
throw new ArgumentNullException("info");
}
info.AddValue("props", _props, typeof(IDictionary));
info.AddValue("delegate", _delegate, typeof(CrossContextDelegate));
info.AddValue("sourceCtxID", _sourceCtxID);
info.AddValue("targetCtxID", _targetCtxID);
info.AddValue("targetDomainID", _targetDomainID);
info.AddValue("eeData", _eeData);
}
}// class TransitionCall
internal class ArgMapper
{
int[] _map;
IMethodMessage _mm;
RemotingMethodCachedData _methodCachedData;
internal ArgMapper(IMethodMessage mm, bool fOut)
{
_mm = mm;
MethodBase mb = (MethodBase)_mm.MethodBase;
_methodCachedData =
InternalRemotingServices.GetReflectionCachedData(mb);
if (fOut)
_map = _methodCachedData.MarshalResponseArgMap;
else
_map = _methodCachedData.MarshalRequestArgMap;
} // ArgMapper
internal ArgMapper(MethodBase mb, bool fOut)
{
_methodCachedData =
InternalRemotingServices.GetReflectionCachedData(mb);
if (fOut)
_map = _methodCachedData.MarshalResponseArgMap;
else
_map = _methodCachedData.MarshalRequestArgMap;
} // ArgMapper
internal int[] Map
{
get { return _map; }
}
internal int ArgCount
{
get
{
if (_map == null)
{
return 0;
}
else
{
return _map.Length;
}
}
}
internal Object GetArg(int argNum)
{
if (_map == null || argNum < 0 || argNum >= _map.Length)
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
else
{
return _mm.GetArg(_map[argNum]);
}
}
internal String GetArgName(int argNum)
{
if (_map == null || argNum < 0 || argNum >= _map.Length)
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
else
{
return _mm.GetArgName(_map[argNum]);
}
}
internal Object[] Args
{
get
{
if (_map == null)
{
return null;
}
else
{
Object[] ret = new Object[_map.Length];
for(int i=0; i<_map.Length; i++)
{
ret[i] = _mm.GetArg(_map[i]);
}
return ret;
}
}
}
internal Type[] ArgTypes
{
get
{
Type[] ret = null;
if (_map != null)
{
ParameterInfo[] pi = _methodCachedData.Parameters;
ret = new Type[_map.Length];
for (int i=0; i<_map.Length; i++)
{
ret[i] = pi[_map[i]].ParameterType;
}
}
return ret;
}
}
internal String[] ArgNames
{
get
{
String[] ret = null;
if (_map != null)
{
ParameterInfo[] pi = _methodCachedData.Parameters;
ret = new String[_map.Length];
for (int i=0; i<_map.Length; i++)
{
ret[i] = pi[_map[i]].Name;
}
}
return ret;
}
}
//
// Helper functions for getting argument maps
//
internal static void GetParameterMaps(ParameterInfo[] parameters,
out int[] inRefArgMap,
out int[] outRefArgMap,
out int[] outOnlyArgMap,
out int[] nonRefOutArgMap,
out int[] marshalRequestMap,
out int[] marshalResponseMap)
{
int co;
int inRefCount = 0;
int outRefCount = 0;
int outOnlyCount = 0;
int nonRefOutCount = 0;
int marshalRequestCount = 0;
int marshalResponseCount = 0;
int[] tempMarshalRequestMap = new int[parameters.Length];
int[] tempMarshalResponseMap = new int[parameters.Length];
// count instances of each type of parameter
co = 0;
foreach (ParameterInfo param in parameters)
{
bool bIsIn = param.IsIn; // [In]
bool bIsOut = param.IsOut; // [Out] note: out int a === [Out] ref int b
bool bIsByRef = param.ParameterType.IsByRef; // (ref or normal)
if (!bIsByRef)
{
// it's a normal parameter (always passed in)
inRefCount++;
if (bIsOut)
nonRefOutCount++;
}
else
if (bIsOut)
{
outRefCount++;
outOnlyCount++;
}
else
{
inRefCount++;
outRefCount++;
}
// create maps for marshaling
bool bMarshalIn = false;
bool bMarshalOut = false;
if (bIsByRef)
{
if (bIsIn == bIsOut)
{
// "ref int a" or "[In, Out] ref int a"
bMarshalIn = true;
bMarshalOut = true;
}
else
{
// "[In] ref int a" or "out int a"
bMarshalIn = bIsIn;
bMarshalOut = bIsOut;
}
}
else
{
// "int a" or "[In, Out] a"
bMarshalIn = true;
bMarshalOut = bIsOut;
}
if (bMarshalIn)
tempMarshalRequestMap[marshalRequestCount++] = co;
if (bMarshalOut)
tempMarshalResponseMap[marshalResponseCount++] = co;
co++; // parameter index
} // foreach (ParameterInfo param in parameters)
inRefArgMap = new int[inRefCount];
outRefArgMap = new int[outRefCount];
outOnlyArgMap = new int[outOnlyCount];
nonRefOutArgMap = new int[nonRefOutCount];
inRefCount = 0;
outRefCount = 0;
outOnlyCount = 0;
nonRefOutCount = 0;
// build up parameter maps
for (co = 0; co < parameters.Length; co++)
{
ParameterInfo param = parameters[co];
bool bIsOut = param.IsOut; // [Out] note: out int a === [Out] ref int b
bool bIsByRef = param.ParameterType.IsByRef; // (ref or normal)
if (!bIsByRef)
{
// it's an in parameter
inRefArgMap[inRefCount++] = co;
if (bIsOut)
nonRefOutArgMap[nonRefOutCount++] = co;
}
else
if (bIsOut)
{
outRefArgMap[outRefCount++] = co;
outOnlyArgMap[outOnlyCount++] = co;
}
else
{
inRefArgMap[inRefCount++] = co;
outRefArgMap[outRefCount++] = co;
}
}
// copy over marshal maps
marshalRequestMap = new int[marshalRequestCount];
Array.Copy(tempMarshalRequestMap, marshalRequestMap, marshalRequestCount);
marshalResponseMap = new int[marshalResponseCount];
Array.Copy(tempMarshalResponseMap, marshalResponseMap, marshalResponseCount);
} // GetParameterMaps
//
// Helper methods for expanding and contracting argument lists
// when translating from async methods to sync methods and back.
//
internal static Object[] ExpandAsyncEndArgsToSyncArgs(RemotingMethodCachedData syncMethod,
Object[] asyncEndArgs)
{
// This is when we have a list of args associated with EndFoo(), and
// we want to size it to a list of args associated with Foo();
Object[] args = new Object[syncMethod.Parameters.Length];
int[] outRefArgMap = syncMethod.OutRefArgMap;
for (int co = 0; co < outRefArgMap.Length; co++)
{
args[outRefArgMap[co]] = asyncEndArgs[co];
}
return args;
} // ExpandAsyncEndArgsToSyncArgs
} // class ArgMapper
internal class ErrorMessage: IMethodCallMessage
{
// IMessage
public IDictionary Properties { get{ return null;} }
// IMethodMessage
public String Uri { get{ return m_URI; } }
public String MethodName { get{ return m_MethodName; }}
public String TypeName { get{ return m_TypeName; } }
public Object MethodSignature { get { return m_MethodSignature; } }
public MethodBase MethodBase { get { return null; } }
public int ArgCount { get { return m_ArgCount;} }
public String GetArgName(int index) { return m_ArgName; }
public Object GetArg(int argNum) { return null;}
public Object[] Args { get { return null;} }
public bool HasVarArgs { get { return false;} }
// IMethodCallMessage
public int InArgCount { get { return m_ArgCount;} }
public String GetInArgName(int index) { return null; }
public Object GetInArg(int argNum) { return null;}
public Object[] InArgs { get { return null; }}
public LogicalCallContext LogicalCallContext { get { return null; } }
String m_URI = "Exception";
String m_MethodName = "Unknown";
String m_TypeName = "Unknown";
Object m_MethodSignature = null;
int m_ArgCount = 0;
String m_ArgName = "Unknown";
}
//+===============================================================================
//
// Synopsis: Message wrapper used as base class for all exposed message wrappers.
// This is needed so that we can extract the identity object from a custom message.
//
//-================================================================================
///
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[System.Runtime.InteropServices.ComVisible(true)]
public class InternalMessageWrapper
{
///
protected IMessage WrappedMessage;
///
public InternalMessageWrapper(IMessage msg)
{
WrappedMessage = msg;
} // InternalMessageWrapper
internal Object GetIdentityObject()
{
IInternalMessage iim = WrappedMessage as IInternalMessage;
if (null != iim)
{
return iim.IdentityObject;
}
else
{
InternalMessageWrapper imw = WrappedMessage as InternalMessageWrapper;
if(null != imw)
{
return imw.GetIdentityObject();
}
else
{
return null;
}
}
} // GetIdentityObject
internal Object GetServerIdentityObject()
{
IInternalMessage iim = WrappedMessage as IInternalMessage;
if (null != iim)
{
return iim.ServerIdentityObject;
}
else
{
InternalMessageWrapper imw = WrappedMessage as InternalMessageWrapper;
if (null != imw)
{
return imw.GetServerIdentityObject();
}
else
{
return null;
}
}
} // GetServerIdentityObject
} // class InternalMessageWrapper
//+===============================================================================
//
// Synopsis: Message wrapper used for creating custom method call messages.
//
//-================================================================================
///
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[System.Runtime.InteropServices.ComVisible(true)]
public class MethodCallMessageWrapper : InternalMessageWrapper, IMethodCallMessage
{
// we need to overload the dictionary to delegate special values to this class
private class MCMWrapperDictionary : Hashtable
{
private IMethodCallMessage _mcmsg; // pointer to this message object
private IDictionary _idict; // point to contained message's dictionary
public MCMWrapperDictionary(IMethodCallMessage msg, IDictionary idict)
{
_mcmsg = msg;
_idict = idict;
}
public override Object this[Object key]
{
get
{
System.String strKey = key as System.String;
if (null != strKey)
{
switch (strKey)
{
case "__Uri": return _mcmsg.Uri;
case "__MethodName": return _mcmsg.MethodName;
case "__MethodSignature": return _mcmsg.MethodSignature;
case "__TypeName": return _mcmsg.TypeName;
case "__Args": return _mcmsg.Args;
}
}
return _idict[key];
}
set
{
System.String strKey = key as System.String;
if (null != strKey)
{
switch (strKey)
{
case "__MethodName":
case "__MethodSignature":
case "__TypeName":
case "__Args":
throw new RemotingException(
Environment.GetResourceString("Remoting_Default"));
}
_idict[key] = value;
}
}
}
} // class MCMWrapperDictionary
IMethodCallMessage _msg;
IDictionary _properties;
ArgMapper _argMapper = null;
Object[] _args;
///
public MethodCallMessageWrapper(IMethodCallMessage msg) : base(msg)
{
_msg = msg;
_args = _msg.Args;
} // MethodCallMessageWrapper
// IMethodMessage implementation
///
public virtual String Uri
{
get
{
return _msg.Uri;
}
set
{
_msg.Properties[Message.UriKey] = value;
}
}
///
public virtual String MethodName { get {return _msg.MethodName;}}
///
public virtual String TypeName { get {return _msg.TypeName;}}
///
public virtual Object MethodSignature { get {return _msg.MethodSignature;}}
///
public virtual LogicalCallContext LogicalCallContext { get {return _msg.LogicalCallContext;}}
///
public virtual MethodBase MethodBase { get {return _msg.MethodBase;}}
///
public virtual int ArgCount
{
get
{
if (_args != null)
return _args.Length;
else
return 0;
}
}
///
public virtual String GetArgName(int index) { return _msg.GetArgName(index); }
///
public virtual Object GetArg(int argNum) { return _args[argNum]; }
///
public virtual Object[] Args
{
get { return _args; }
set { _args = value; }
}
///
public virtual bool HasVarArgs { get {return _msg.HasVarArgs;} }
// end of IMethodMessage implementation
// IMethodCallMessage implementation
// (We cannot simply delegate to the internal message
// since we override the definition of Args and create our own array
// which can be modified.)
///
public virtual int InArgCount
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.ArgCount;
}
} // InArgCount
///
public virtual Object GetInArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.GetArg(argNum);
} // GetInArg
///
public virtual String GetInArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.GetArgName(index);
} // GetInArgName
///
public virtual Object[] InArgs
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.Args;
}
} // InArgs
// end of IMethodCallMessage implementation
///
public virtual IDictionary Properties
{
get
{
if (_properties == null)
_properties = new MCMWrapperDictionary(this, _msg.Properties);
return _properties;
}
}
} // class MethodCallMessageWrapper
//+================================================================================
//
// Synopsis: Message wrapper used for creating custom method return messages.
//
//-===============================================================================
///
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[System.Runtime.InteropServices.ComVisible(true)]
public class MethodReturnMessageWrapper : InternalMessageWrapper, IMethodReturnMessage
{
// we need to overload the dictionary to delegate special values to this class
private class MRMWrapperDictionary : Hashtable
{
private IMethodReturnMessage _mrmsg; // pointer to this message object
private IDictionary _idict; // point to contained message's dictionary
public MRMWrapperDictionary(IMethodReturnMessage msg, IDictionary idict)
{
_mrmsg = msg;
_idict = idict;
}
public override Object this[Object key]
{
get
{
System.String strKey = key as System.String;
if (null != strKey)
{
switch (strKey)
{
case "__Uri": return _mrmsg.Uri;
case "__MethodName": return _mrmsg.MethodName;
case "__MethodSignature": return _mrmsg.MethodSignature;
case "__TypeName": return _mrmsg.TypeName;
case "__Return": return _mrmsg.ReturnValue;
case "__OutArgs": return _mrmsg.OutArgs;
}
}
return _idict[key];
}
set
{
System.String strKey = key as System.String;
if (null != strKey)
{
switch (strKey)
{
case "__MethodName":
case "__MethodSignature":
case "__TypeName":
case "__Return":
case "__OutArgs":
throw new RemotingException(
Environment.GetResourceString("Remoting_Default"));
}
_idict[key] = value;
}
}
}
} // class MCMWrapperDictionary
IMethodReturnMessage _msg;
IDictionary _properties;
ArgMapper _argMapper = null;
Object[] _args = null;
Object _returnValue = null;
Exception _exception = null;
///
public MethodReturnMessageWrapper(IMethodReturnMessage msg) : base(msg)
{
_msg = msg;
_args = _msg.Args;
_returnValue = _msg.ReturnValue; // be careful if you decide to lazily assign _returnValue
// since the return value might actually be null
_exception = _msg.Exception; // (same thing as above goes for _exception)
} // MethodReturnMessageWrapper
// IMethodMessage implementation
///
public String Uri
{
get
{
return _msg.Uri;
}
set
{
_msg.Properties[Message.UriKey] = value;
}
}
///
public virtual String MethodName { get {return _msg.MethodName;}}
///
public virtual String TypeName { get {return _msg.TypeName;}}
///
public virtual Object MethodSignature { get {return _msg.MethodSignature;}}
///
public virtual LogicalCallContext LogicalCallContext { get {return _msg.LogicalCallContext;}}
///
public virtual MethodBase MethodBase { get {return _msg.MethodBase;}}
///
public virtual int ArgCount
{
get
{
if (_args != null)
return _args.Length;
else
return 0;
}
}
///
public virtual String GetArgName(int index) { return _msg.GetArgName(index); }
///
public virtual Object GetArg(int argNum) { return _args[argNum]; }
///
public virtual Object[] Args
{
get { return _args; }
set { _args = value; }
}
///
public virtual bool HasVarArgs { get {return _msg.HasVarArgs;} }
// end of IMethodMessage implementation
// IMethodReturnMessage implementation
// (We cannot simply delegate to the internal message
// since we override the definition of Args and create our own array
// which can be modified.)
///
public virtual int OutArgCount
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.ArgCount;
}
}
///
public virtual Object GetOutArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArg(argNum);
}
///
public virtual String GetOutArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArgName(index);
}
///
public virtual Object[] OutArgs
{
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.Args;
}
}
///
public virtual Exception Exception
{
get { return _exception; }
set { _exception = value; }
}
///
public virtual Object ReturnValue
{
get { return _returnValue; }
set { _returnValue = value; }
}
// end of IMethodReturnMessage implementation
// IMessage
///
public virtual IDictionary Properties
{
get
{
if (_properties == null)
_properties = new MRMWrapperDictionary(this, _msg.Properties);
return _properties;
}
}
} // class MethodReturnMessageWrapper
} // namespace Remoting
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ResolveDuplexAsyncResult.cs
- EllipticalNodeOperations.cs
- CompiledRegexRunner.cs
- LambdaCompiler.ControlFlow.cs
- DesignerVerbCollection.cs
- TypedRowGenerator.cs
- WebBodyFormatMessageProperty.cs
- GACMembershipCondition.cs
- XmlEventCache.cs
- ElementUtil.cs
- ListViewSelectEventArgs.cs
- PointAnimationUsingPath.cs
- ColorConvertedBitmap.cs
- Evidence.cs
- DataControlImageButton.cs
- CodeCommentStatementCollection.cs
- BinaryParser.cs
- SpecialNameAttribute.cs
- RelationalExpressions.cs
- InplaceBitmapMetadataWriter.cs
- MemoryMappedFileSecurity.cs
- HyperLink.cs
- ExpressionVisitorHelpers.cs
- EntityDataSourceView.cs
- DelegateSerializationHolder.cs
- wgx_commands.cs
- InputMethodStateTypeInfo.cs
- SharedPerformanceCounter.cs
- TrackingExtract.cs
- XmlNodeReader.cs
- TransformerInfo.cs
- ChannelManager.cs
- COM2ColorConverter.cs
- EntryIndex.cs
- DesignerView.xaml.cs
- UnicodeEncoding.cs
- UidManager.cs
- TimeZone.cs
- GetPageNumberCompletedEventArgs.cs
- CqlParserHelpers.cs
- UshortList2.cs
- WsdlBuildProvider.cs
- DownloadProgressEventArgs.cs
- ObfuscationAttribute.cs
- CalendarModeChangedEventArgs.cs
- ConfigurationFileMap.cs
- OutputCacheProfileCollection.cs
- WindowInteropHelper.cs
- SqlDataSourceConfigureSelectPanel.cs
- StringReader.cs
- PageContentAsyncResult.cs
- FeatureSupport.cs
- InvalidProgramException.cs
- WmlCommandAdapter.cs
- ObjectParameterCollection.cs
- TypeConverterMarkupExtension.cs
- DbConnectionPoolGroupProviderInfo.cs
- DesignConnectionCollection.cs
- ICollection.cs
- GcHandle.cs
- PkcsUtils.cs
- OdbcConnection.cs
- DoubleStorage.cs
- counter.cs
- HotSpotCollectionEditor.cs
- SiteOfOriginPart.cs
- RequestUriProcessor.cs
- DependencyObject.cs
- ManipulationDevice.cs
- CompositeActivityTypeDescriptor.cs
- IndexedEnumerable.cs
- EnvelopedPkcs7.cs
- ErrorTolerantObjectWriter.cs
- DiscoveryInnerClientAdhocCD1.cs
- ListDictionaryInternal.cs
- CompoundFileDeflateTransform.cs
- AxisAngleRotation3D.cs
- QilBinary.cs
- COAUTHIDENTITY.cs
- ValueUtilsSmi.cs
- Int32Collection.cs
- LocatorBase.cs
- HitTestParameters.cs
- InvalidWMPVersionException.cs
- Exceptions.cs
- MimeMapping.cs
- OperationCanceledException.cs
- RegisteredScript.cs
- Control.cs
- HashCodeCombiner.cs
- WriteableBitmap.cs
- UiaCoreProviderApi.cs
- OlePropertyStructs.cs
- Variable.cs
- EmptyElement.cs
- RSAOAEPKeyExchangeDeformatter.cs
- TransactionFormatter.cs
- PathGeometry.cs
- ComponentCache.cs
- FaultContractInfo.cs