|
// ==++==
//
// 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.Runtime.Versioning;
using System.Reflection;
using System.Text;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using System.Globalization;
using System.Diagnostics.Contracts;
using System.Security;
//+=======================================================================
//
// 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;
[System.Security.SecurityCritical] // auto-generated
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;}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void GetAsyncBeginInfo(out AsyncCallback acbd,
out Object state);
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Object GetThisPtr();
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[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.
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[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.
[System.Security.SecurityCritical] // auto-generated
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
{
[System.Security.SecurityCritical]
get { return _srvID; }
[System.Security.SecurityCritical]
set {_srvID = value;}
}
Identity IInternalMessage.IdentityObject
{
[System.Security.SecurityCritical]
get { return _ID; }
[System.Security.SecurityCritical]
set { _ID = value;}
}
[System.Security.SecurityCritical]
void IInternalMessage.SetURI(String URI)
{
_URI = URI;
}
[System.Security.SecurityCritical]
void IInternalMessage.SetCallContext(LogicalCallContext callContext)
{
_callContext = callContext;
}
[System.Security.SecurityCritical]
bool IInternalMessage.HasProperties()
{
return _properties != null;
}
//-------------------------------------------------------------------
// IMessage
//-------------------------------------------------------------------
public IDictionary Properties
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_properties == null)
{
Interlocked.CompareExchange(ref _properties,
new MCMDictionary(this, null),
null);
}
return (IDictionary)_properties;
}
}
//-------------------------------------------------------------------
// IMethodCallMessage
//-------------------------------------------------------------------
public String Uri
{
[System.Security.SecurityCritical] // auto-generated
get { return _URI;}
set { _URI = value; }
}
public bool HasVarArgs
{
[System.Security.SecurityCritical] // auto-generated
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
{
[System.Security.SecurityCritical] // auto-generated
get { return InternalGetArgCount();}
}
[System.Security.SecurityCritical] // auto-generated
public Object GetArg(int argNum)
{
return InternalGetArg(argNum);
}
[System.Security.SecurityCritical] // auto-generated
public String GetArgName(int index)
{
if (index >= ArgCount)
{
throw new ArgumentOutOfRangeException("index");
}
Contract.EndContractBlock();
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
{
[System.Security.SecurityCritical] // auto-generated
get
{
return InternalGetArgs();
}
}
public int InArgCount
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.ArgCount;
}
}
[System.Security.SecurityCritical] // auto-generated
public Object GetInArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.GetArg(argNum);
}
[System.Security.SecurityCritical] // auto-generated
public String GetInArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.GetArgName(index);
}
public Object[] InArgs
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.Args;
}
}
[System.Security.SecurityCritical] // auto-generated
private void UpdateNames()
{
RemotingMethodCachedData methCache =
InternalRemotingServices.GetReflectionCachedData(GetMethodBase());
_typeName = methCache.TypeAndAssemblyName;
_MethodName = methCache.MethodName;
}
public String MethodName
{
[System.Security.SecurityCritical] // auto-generated
get
{
if(null == _MethodName)
UpdateNames();
return _MethodName;
}
}
public String TypeName
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_typeName == null)
UpdateNames();
return _typeName;
}
}
public Object MethodSignature
{
[System.Security.SecurityCritical] // auto-generated
get
{
if(null == _MethodSignature)
_MethodSignature = GenerateMethodSignature(GetMethodBase());
return _MethodSignature;
}
}
public LogicalCallContext LogicalCallContext
{
[System.Security.SecurityCritical] // auto-generated
get
{
return GetLogicalCallContext();
}
}
public MethodBase MethodBase
{
[System.Security.SecurityCritical] // auto-generated
get
{
return GetMethodBase();
}
}
//
// ISerializable
//
[System.Security.SecurityCritical] // auto-generated_required
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(
Environment.GetResourceString("NotSupported_Method"));
}
[System.Security.SecurityCritical] // auto-generated
internal MethodBase GetMethodBase()
{
if(null == _MethodBase)
{
unsafe
{
IRuntimeMethodInfo mh = new RuntimeMethodInfoStub(_methodDesc, null);
_MethodBase = RuntimeType.GetMethodBase(Type.GetTypeFromHandleUnsafe(_governingType), mh);
}
}
return _MethodBase;
}
[System.Security.SecurityCritical] // auto-generated
internal LogicalCallContext SetLogicalCallContext(
LogicalCallContext callCtx)
{
LogicalCallContext oldCtx = _callContext;
_callContext = callCtx;
return oldCtx;
}
[System.Security.SecurityCritical] // auto-generated
internal LogicalCallContext GetLogicalCallContext()
{
if (_callContext == null)
_callContext = new LogicalCallContext();
return _callContext;
}
// Internal helper to create method signature
[System.Security.SecurityCritical] // auto-generated
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.
//
[System.Security.SecurityCritical] // auto-generated
internal static Object[] CoerceArgs(IMethodMessage m)
{
MethodBase mb = m.MethodBase;
Contract.Assert(mb != null, "null method base passed to CoerceArgs");
RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(mb);
return CoerceArgs(m, methodCache.Parameters);
} // CoerceArgs
[System.Security.SecurityCritical] // auto-generated
internal static Object[] CoerceArgs(IMethodMessage m, ParameterInfo[] pi)
{
return CoerceArgs(m.MethodBase, m.Args, pi);
} // CoerceArgs
[System.Security.SecurityCritical] // auto-generated
internal static Object[] CoerceArgs(MethodBase mb, Object[] args, ParameterInfo[] pi)
{
if (pi == null)
{
throw new ArgumentNullException("pi");
}
Contract.EndContractBlock();
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
[System.Security.SecurityCritical] // auto-generated
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
[System.Security.SecurityCritical] // auto-generated
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
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern bool InternalHasVarArgs();
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern int InternalGetArgCount();
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object InternalGetArg(int argNum);
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object[] InternalGetArgs();
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void PropagateOutParameters(Object[] OutArgs, Object retVal);
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern bool Dispatch(Object target);
//
// <
[System.Security.SecurityCritical] // auto-generated
[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);
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static void OutToUnmanagedDebugger(String s);
[System.Security.SecurityCritical] // auto-generated
internal static LogicalCallContext PropagateCallContextFromMessageToThread(IMessage msg)
{
return CallContext.SetLogicalCallContext(
(LogicalCallContext) msg.Properties[Message.CallContextKey]);
}
[System.Security.SecurityCritical] // auto-generated
internal static void PropagateCallContextFromThreadToMessage(IMessage msg)
{
LogicalCallContext callCtx = Thread.CurrentThread.GetMutableExecutionContext().LogicalCallContext;
msg.Properties[Message.CallContextKey] = callCtx;
}
[System.Security.SecurityCritical] // auto-generated
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
//
//-================================================================================
[System.Security.SecurityCritical] // auto-generated
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
{
[System.Security.SecurityCritical]
get
{
if (_iFlags == Intercept)
{
return RemotingServices.MarshalInternal(_o,null,null);
}
else
{
return base.ReturnValue;
}
}
}
public override IDictionary Properties
{
[System.Security.SecurityCritical]
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 RuntimeType _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
}
[System.Security.SecurityCritical] // auto-generated
internal ConstructorCallMessage(Object[] callSiteActivationAttributes,
Object[]womAttr, Object[] typeAttr, RuntimeType serverType)
{
_activationType = serverType;
_activationTypeName = RemotingServices.GetDefaultQualifiedTypeName(_activationType);
_callSiteActivationAttributes = callSiteActivationAttributes;
_womGlobalAttributes = womAttr;
_typeAttributes = typeAttr;
}
[System.Security.SecurityCritical] // auto-generated
public Object GetThisPtr()
{
if (_message != null)
{
return _message.GetThisPtr();
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
public Object[] CallSiteActivationAttributes
{
[System.Security.SecurityCritical] // auto-generated
get
{
return _callSiteActivationAttributes;
}
}
internal Object[] GetWOMAttributes()
{
return _womGlobalAttributes;
}
internal Object[] GetTypeAttributes()
{
return _typeAttributes;
}
public Type ActivationType
{
[System.Security.SecurityCritical] // auto-generated
get
{
if ((_activationType == null) && (_activationTypeName != null))
_activationType = RemotingServices.InternalGetTypeFromQualifiedTypeName(_activationTypeName, false);
return _activationType;
}
}
public String ActivationTypeName
{
[System.Security.SecurityCritical] // auto-generated
get
{
return _activationTypeName;
}
}
public IList ContextProperties
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_contextProperties == null)
{
_contextProperties = new ArrayList();
}
return _contextProperties;
}
}
public String Uri
{
[System.Security.SecurityCritical] // auto-generated
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
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_message != null)
{
return _message.MethodName;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public String TypeName
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_message != null)
{
return _message.TypeName;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public Object MethodSignature
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_message != null)
{
return _message.MethodSignature;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
} // MethodSignature
public MethodBase MethodBase
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_message != null)
{
return _message.MethodBase;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
} // MethodBase
/// <internalonly/>
public int InArgCount
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_argMapper == null)
_argMapper = new ArgMapper(this, false);
return _argMapper.ArgCount;
}
}
[System.Security.SecurityCritical] // auto-generated
public Object GetInArg(int argNum)
{
if (_argMapper == null)
_argMapper = new ArgMapper(this, false);
return _argMapper.GetArg(argNum);
}
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
public String GetInArgName(int index)
{
if (_argMapper == null)
_argMapper = new ArgMapper(this, false);
return _argMapper.GetArgName(index);
}
public Object[] InArgs
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_argMapper == null)
_argMapper = new ArgMapper(this, false);
return _argMapper.Args;
}
}
public int ArgCount
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_message != null)
{
return _message.ArgCount;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
[System.Security.SecurityCritical] // auto-generated
public Object GetArg(int argNum)
{
if (_message != null)
{
return _message.GetArg(argNum);
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
[System.Security.SecurityCritical] // auto-generated
public String GetArgName(int index)
{
if (_message != null)
{
return _message.GetArgName(index);
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
public bool HasVarArgs
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_message != null)
{
return _message.HasVarArgs;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public Object[] Args
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_message != null)
{
return _message.Args;
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
}
public IDictionary Properties
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_properties == null)
{
Object properties = new CCMDictionary(this, new Hashtable());
Interlocked.CompareExchange(ref _properties, properties, null);
}
return(IDictionary) _properties;
}
}
public IActivator Activator
{
[System.Security.SecurityCritical] // auto-generated
get { return _activator; }
[System.Security.SecurityCritical] // auto-generated
set { _activator = value; }
}
public LogicalCallContext LogicalCallContext
{
[System.Security.SecurityCritical] // auto-generated
get
{
return GetLogicalCallContext();
}
}
internal bool ActivateInContext
{
get { return((_iFlags & CCM_ACTIVATEINCONTEXT) != 0);}
set { _iFlags = value ? (_iFlags | CCM_ACTIVATEINCONTEXT) : (_iFlags & ~CCM_ACTIVATEINCONTEXT);}
}
[System.Security.SecurityCritical] // auto-generated
internal void SetFrame(MessageData msgData)
{
Contract.Assert(_message == null, "Can't set frame twice on ConstructorCallMessage");
_message = new Message();
_message.InitFields(msgData);
}
[System.Security.SecurityCritical] // auto-generated
internal LogicalCallContext GetLogicalCallContext()
{
if (_message != null)
{
return _message.GetLogicalCallContext();
}
else
{
throw new InvalidOperationException(
Environment.GetResourceString(
"InvalidOperation_InternalState"));
}
}
[System.Security.SecurityCritical] // auto-generated
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;
}
[System.Security.SecuritySafeCritical] // auto-generated
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"));
}
[System.Security.SecurityCritical] // auto-generated
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"));
}
}
[System.Security.SecurityCritical]
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;
[System.Security.SecurityCritical] // auto-generated
public CRMDictionary(IConstructionReturnMessage msg, IDictionary idict)
: base( (msg.Exception!=null)? CRMkeysFault : CRMkeysNoFault, idict)
{
fault = (msg.Exception != null) ;
_crmsg = msg;
}
[System.Security.SecuritySafeCritical] // auto-generated
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"));
}
[System.Security.SecurityCritical] // auto-generated
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"));
}
}
}
[System.Security.SecurityCritical]
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;
}
[System.Security.SecuritySafeCritical] // auto-generated
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"));
}
[System.Security.SecurityCritical] // auto-generated
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"));
}
}
}
[System.Security.SecurityCritical]
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;
[System.Security.SecurityCritical] // auto-generated
public MRMDictionary(IMethodReturnMessage msg, IDictionary idict)
: base((msg.Exception != null) ? MCMkeysFault : MCMkeysNoFault, idict)
{
fault = (msg.Exception != null) ;
_mrmsg = msg;
}
[System.Security.SecuritySafeCritical]
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"));
}
[System.Security.SecurityCritical] // auto-generated
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"));
}
}
}
}
[System.Security.SecurityCritical]
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);
[System.Security.SecurityCritical]
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;
}
[System.Security.SecuritySafeCritical] //
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
{
Contract.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
{
Contract.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
{
[System.Security.SecurityCritical] // auto-generated
get {return _m.Uri;}
}
public String MethodName
{
[System.Security.SecurityCritical] // auto-generated
get {return _m.MethodName;}
}
public String TypeName
{
[System.Security.SecurityCritical] // auto-generated
get {return _m.TypeName;}
}
public Object MethodSignature
{
[System.Security.SecurityCritical] // auto-generated
get {return _m.MethodSignature;}
}
public MethodBase MethodBase
{
[System.Security.SecurityCritical] // auto-generated
get {return _m.MethodBase;}
}
public bool HasVarArgs
{
[System.Security.SecurityCritical] // auto-generated
get {return _m.HasVarArgs;}
}
public int ArgCount
{
[System.Security.SecurityCritical] // auto-generated
get {return _m.ArgCount;}
}
[System.Security.SecurityCritical] // auto-generated
public Object GetArg(int argNum) {return _m.GetArg(argNum);}
[System.Security.SecurityCritical] // auto-generated
public String GetArgName(int index) {return _m.GetArgName(index);}
public Object[] Args
{
[System.Security.SecurityCritical] // auto-generated
get {return _m.Args;}
}
public LogicalCallContext LogicalCallContext
{
[System.Security.SecurityCritical] // auto-generated
get { return _m.GetLogicalCallContext(); }
}
[System.Security.SecurityCritical] // auto-generated
internal LogicalCallContext GetLogicalCallContext() {return _m.GetLogicalCallContext();}
[System.Security.SecurityCritical] // auto-generated
internal LogicalCallContext SetLogicalCallContext(LogicalCallContext callCtx)
{
return _m.SetLogicalCallContext(callCtx);
}
public int OutArgCount
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.ArgCount;
}
}
[System.Security.SecurityCritical] // auto-generated
public Object GetOutArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArg(argNum);
}
[System.Security.SecurityCritical] // auto-generated
public String GetOutArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArgName(index);
}
public Object[] OutArgs
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.Args;
}
}
public Exception Exception
{
[System.Security.SecurityCritical] // auto-generated
get {return null;}
}
public Object ReturnValue
{
[System.Security.SecurityCritical] // auto-generated
get {return _m.GetReturnValue();}
}
public IDictionary Properties
{
[System.Security.SecurityCritical] // auto-generated
get
{
lock(this)
{
if (_h == null)
{
_h = new Hashtable();
}
if (_d == null)
{
_d = new MRMDictionary(this, _h);
}
return _d;
}
}
}
//
// IInternalMessage
//
ServerIdentity IInternalMessage.ServerIdentityObject
{
[System.Security.SecurityCritical]
get { return null; }
[System.Security.SecurityCritical]
set {}
}
Identity IInternalMessage.IdentityObject
{
[System.Security.SecurityCritical]
get { return null; }
[System.Security.SecurityCritical]
set {}
}
[System.Security.SecurityCritical]
void IInternalMessage.SetURI(String val)
{
_m.Uri = val;
}
[System.Security.SecurityCritical]
void IInternalMessage.SetCallContext(LogicalCallContext newCallContext)
{
_m.SetLogicalCallContext(newCallContext);
}
[System.Security.SecurityCritical]
bool IInternalMessage.HasProperties()
{
return _h != null;
}
} // class StackBasedReturnMessage
//+================================================================================
//
// Synopsis: Message for return from a stack builder sink call
//
//-================================================================================
[System.Security.SecurityCritical] // auto-generated_required
[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;
[System.Security.SecurityCritical] // auto-generated
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 = Thread.CurrentThread.GetMutableExecutionContext().LogicalCallContext;
if (mcm != null)
{
_URI = mcm.Uri;
_methodName = mcm.MethodName;
_methodSignature = null;
_typeName = mcm.TypeName;
_hasVarArgs = mcm.HasVarArgs;
_methodBase = mcm.MethodBase;
}
}
[System.Security.SecurityCritical] // auto-generated
public ReturnMessage(Exception e, IMethodCallMessage mcm)
{
_e = IsCustomErrorEnabled()? new RemotingException(Environment.GetResourceString("Remoting_InternalError")):e;
_callContext = Thread.CurrentThread.GetMutableExecutionContext().LogicalCallContext;
if (mcm != null)
{
_URI = mcm.Uri;
_methodName = mcm.MethodName;
_methodSignature = null;
_typeName = mcm.TypeName;
_hasVarArgs = mcm.HasVarArgs;
_methodBase = mcm.MethodBase;
}
}
public String Uri
{
[System.Security.SecurityCritical]
get { return _URI; }
set { _URI = value; }
}
public String MethodName
{
[System.Security.SecurityCritical]
get { return _methodName; }
}
public String TypeName
{
[System.Security.SecurityCritical]
get { return _typeName; }
}
public Object MethodSignature
{
[System.Security.SecurityCritical]
get
{
if ((_methodSignature == null) && (_methodBase != null))
_methodSignature = Message.GenerateMethodSignature(_methodBase);
return _methodSignature;
}
}
public MethodBase MethodBase
{
[System.Security.SecurityCritical]
get { return _methodBase; }
}
public bool HasVarArgs
{
[System.Security.SecurityCritical]
get
{
return _hasVarArgs;
}
}
public int ArgCount
{
[System.Security.SecurityCritical]
get
{
if (_outArgs == null)
{
return _outArgsCount;
}
else
{
return _outArgs.Length;
}
}
}
[System.Security.SecurityCritical]
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];
}
}
[System.Security.SecurityCritical] // auto-generated
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
{
[System.Security.SecurityCritical]
get
{
if (_outArgs == null)
{
return new Object[_outArgsCount];
}
return _outArgs;
}
}
public int OutArgCount
{
[System.Security.SecurityCritical]
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.ArgCount;
}
}
[System.Security.SecurityCritical]
public Object GetOutArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArg(argNum);
}
[System.Security.SecurityCritical]
public String GetOutArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArgName(index);
}
public Object[] OutArgs
{
[System.Security.SecurityCritical]
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.Args;
}
}
public Exception Exception
{
[System.Security.SecurityCritical]
get { return _e; }
}
public virtual Object ReturnValue
{
[System.Security.SecurityCritical]
get { return _ret; }
}
public virtual IDictionary Properties
{
[System.Security.SecurityCritical]
get
{
if (_properties == null)
{
_properties = new MRMDictionary(this, null);
}
return(MRMDictionary) _properties;
}
}
public LogicalCallContext LogicalCallContext
{
[System.Security.SecurityCritical] // auto-generated
get { return GetLogicalCallContext();}
}
[System.Security.SecurityCritical] // auto-generated
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;
}
[System.Security.SecurityCritical] // auto-generated
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
//
//-================================================================================
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated_required
[Serializable]
[CLSCompliant(false)]
[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;
/// <internalonly/>
protected IDictionary ExternalProperties = null;
/// <internalonly/>
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
//
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
public MethodCall(Header[] h1)
{
Message.DebugOut("MethodCall ctor IN headers: " + (h1 == null ? "<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
//
[System.Security.SecurityCritical] // auto-generated
public MethodCall(IMessage msg)
{
if (msg == null)
throw new ArgumentNullException("msg");
Contract.EndContractBlock();
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();
}
[System.Security.SecurityCritical] // auto-generated
internal MethodCall(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
Contract.EndContractBlock();
Init();
SetObjectData(info, context);
}
[System.Security.SecurityCritical] // auto-generated
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);
}
[System.Security.SecurityCritical] // auto-generated
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
//
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
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
//
[System.Security.SecurityCritical] // auto-generated
internal void SetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
Contract.EndContractBlock();
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<h.Length; i++)
FillHeader(h[i].Name, h[i].Value);
}
}
}
} // SetObjectData
//
// ResolveMethod
//
#if FEATURE_REMOTING
// This is used by Remoting
private static Type ResolveTypeRelativeTo(String typeName, int offset, int count, Type serverType)
{
Type type = ResolveTypeRelativeToBaseTypes(typeName, offset, count, serverType);
if (type == null)
{
// compare against the interface list
// GetInterfaces() returns a complete list of interfaces this type supports
Type[] interfaces = serverType.GetInterfaces();
foreach (Type iface in interfaces)
{
String ifaceTypeName = iface.FullName;
if (ifaceTypeName.Length == count)
{
if (String.CompareOrdinal(typeName, offset, ifaceTypeName, 0, count) == 0)
{
return iface;
}
}
}
}
return type;
} // ResolveTypeRelativeTo
// This is used by Remoting
private static Type ResolveTypeRelativeToBaseTypes(String typeName, int offset, int count, Type serverType)
{
// typeName is excepted to contain the full type name
// offset is the start of the full type name within typeName
// count us the number of characters in the full type name
// serverType is the type of the server object
if ((typeName == null) || (serverType == null))
return null;
String serverTypeName = serverType.FullName;
if (serverTypeName.Length == count)
{
if (String.CompareOrdinal(typeName, offset, serverTypeName, 0, count) == 0)
{
return serverType;
}
}
return ResolveTypeRelativeToBaseTypes(typeName, offset, count, serverType.BaseType);
} // ResolveTypeRelativeTo
#endif // FEATURE_REMOTING
internal Type ResolveType()
{
// resolve type
Type t = null;
if (srvID == null)
srvID = IdentityHolder.CasualResolveIdentity(uri) as ServerIdentity;
if (srvID != null)
{
Type serverType = srvID.GetLastCalledType(typeName);
if (serverType != null)
return serverType;
int startIndex = 0; // start of type name
// check to see if type name starts with "clr:"
if (String.CompareOrdinal(typeName, 0, "clr:", 0, 4) == 0)
{
// type starts just past "clr:"
startIndex = 4;
}
// find end of full type name
int index = typeName.IndexOf(',', startIndex);
if (index == -1)
index = typeName.Length;
serverType = srvID.ServerType;
t = ResolveTypeRelativeTo(typeName, startIndex, index - startIndex, serverType);
}
if (t == null)
{
// fall back to Type.GetType() in case someone isn't using
// our convention for the TypeName
t = RemotingServices.InternalGetTypeFromQualifiedTypeName(typeName);
}
if (srvID != null)
srvID.SetLastCalledType(typeName, t);
return t;
} // ResolveType
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
public void ResolveMethod()
{
ResolveMethod(true);
}
[System.Security.SecurityCritical] // auto-generated
internal void ResolveMethod(bool bThrowIfNotResolved)
{
if ((MI == null) && (methodName != null))
{
BCLDebug.Trace("REMOTE", "TypeName: " + (typeName == null ? "<null>" : typeName) + "\n");
// resolve type
RuntimeType t = ResolveType() as RuntimeType;
BCLDebug.Trace("REMOTE", "Type: " + (t == null ? "<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)
{
bool found = false;
int arity = instArgs == null ? 0 : instArgs.Length;
// Handle the common case efficiently, using GetMethod.
// Note that GetMethod doesn't match methods with uninstantiated
// generic arguments, so we can only use the fast case for
// non-generic methods.
if (arity == 0)
{
try
{
MI = t.GetMethod(methodName,
MethodCall.LookupAll,
null,
CallingConventions.Any,
methodSignature,
null);
found = true;
}
catch (AmbiguousMatchException)
{
// There is more than one match, so we'll have to do
// a full search.
}
}
// Do a more thorough search if the fast case didn't succeed.
if(!found)
{
// 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 candidates = 0;
for (int i = 0; i < methods.Length; i++)
{
// MakeGenericMethod might throw if the generic arguments
// can't be applied to the method in a type-safe way.
// In that case, continue with the next method.
try
{
MethodInfo mi = (MethodInfo)methods[i];
int miArity = mi.IsGenericMethod ? mi.GetGenericArguments().Length : 0;
if (miArity == arity)
{
// Fill in generic arguments.
if (arity > 0)
{
mi = mi.MakeGenericMethod(instArgs);
}
// Got a candidate, compress it back to the
// start of the array.
methods[candidates] = mi;
candidates++;
}
}
catch (ArgumentException) { }
catch (VerificationException) { }
}
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);
}
BCLDebug.Trace("REMOTE", "Method resolved w/sig ", MI == null ? "<null>" : "<not 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.
Contract.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 ? "<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
//
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated_required
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(
Environment.GetResourceString("NotSupported_Method"));
}
//
// SetObjectFromSoapData -- parses soap format for serialization data
//
[System.Security.SecurityCritical] // auto-generated
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<argNames.Count; i++)
{
argValues.Add(info.GetValue((String)argNames[i], typeof(Object)));
}
//ambiguous member, try to find methodBase using actual argment types (if available)
RuntimeType t = ResolveType() as RuntimeType;
if (t == null)
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_BadType"),
typeName));
}
ResolveOverloadedMethod(t, methodName, argNames, argValues);
if (MI == null)
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_Message_MethodMissing"),
methodName,
typeName));
}
}
//ResolveMethod();
//Contract.Assert(null != MI, "null != MI");
// get method parameters and parameter maps
RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
ParameterInfo[] pinfos = methodCache.Parameters;
int[] marshalRequestArgMap = methodCache.MarshalRequestArgMap;
// check to see if parameters are in-order
Object fUnordered = (null == InternalProperties ? null : InternalProperties["__UnorderedParams"]);
// Create an array for arguments
args = new Object[pinfos.Length];
//SerializationInfoEnumerator siEnum = info.GetEnumerator();
// Fill up the argument array
if (fUnordered != null &&
(fUnordered is System.Boolean) &&
(true == (bool)fUnordered))
{
String memberName;
for (int i=0; i<paramNames.Count; i++)
{
memberName = (String)paramNames[i];
Message.DebugOut(
"MethodCall::PopulateData members[i].Name: "
+ memberName + " substring:>>"
+ memberName.Substring(7) + "<<\n");
int position = -1;
for (int j=0; j<pinfos.Length; j++)
{
if (memberName.Equals(pinfos[j].Name))
{
position = pinfos[j].Position;
break;
}
}
if (position == -1)
{
if (!memberName.StartsWith("__param", StringComparison.Ordinal))
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadSerialization"));
}
position = Int32.Parse(memberName.Substring(7), CultureInfo.InvariantCulture);
}
if (position >= 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<paramNames.Count; i++)
{
String memberName = (String)paramNames[i];
args[marshalRequestArgMap[i]] =
Message.SoapCoerceArg(info.GetValue(memberName, typeof(Object)), pinfos[marshalRequestArgMap[i]].ParameterType, keyToNamespaceTable);
}
PopulateOutArguments(methodCache);
}
} // SetObjectFromSoapData
[SecurityCritical]
[PermissionSet(SecurityAction.Assert, Unrestricted = true)]
void PopulateOutArguments(RemotingMethodCachedData methodCache)
{
ParameterInfo[] parameterInfos = methodCache.Parameters;
// We need to have a dummy object in the array for out parameters
// that have value types.
foreach (int outArg in methodCache.OutOnlyArgMap)
{
Type type = parameterInfos[outArg].ParameterType.GetElementType();
if (type.IsValueType)
args[outArg] = Activator.CreateInstance(type, true);
}
}
//
// Init -- constructor helper for for default behavior
//
/// <internalonly/>
public virtual void Init()
{
}
//
// IMethodCallMessage
//
/// <internalonly/>
public int ArgCount
{
[System.Security.SecurityCritical]
get
{
return(args == null) ? 0 : args.Length;
}
}
/// <internalonly/>
[System.Security.SecurityCritical]
public Object GetArg(int argNum)
{
return args[argNum];
}
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
public String GetArgName(int index)
{
ResolveMethod();
RemotingMethodCachedData methodCache = InternalRemotingServices.GetReflectionCachedData(MI);
return methodCache.Parameters[index].Name;
}
/// <internalonly/>
public Object[] Args
{
[System.Security.SecurityCritical]
get
{
return args;
}
}
/// <internalonly/>
public int InArgCount
{
[System.Security.SecurityCritical]
get
{
if (argMapper == null) argMapper = new ArgMapper(this, false);
return argMapper.ArgCount;
}
}
/// <internalonly/>
[System.Security.SecurityCritical]
public Object GetInArg(int argNum)
{
if (argMapper == null) argMapper = new ArgMapper(this, false);
return argMapper.GetArg(argNum);
}
/// <internalonly/>
[System.Security.SecurityCritical]
public String GetInArgName(int index)
{
if (argMapper == null) argMapper = new ArgMapper(this, false);
return argMapper.GetArgName(index);
}
/// <internalonly/>
public Object[] InArgs
{
[System.Security.SecurityCritical]
get
{
if (argMapper == null) argMapper = new ArgMapper(this, false);
return argMapper.Args;
}
}
/// <internalonly/>
public String MethodName
{
[System.Security.SecurityCritical]
get { return methodName; }
}
/// <internalonly/>
public String TypeName
{
[System.Security.SecurityCritical]
get { return typeName; }
}
/// <internalonly/>
public Object MethodSignature
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (methodSignature != null)
return methodSignature;
else if (MI != null)
methodSignature = Message.GenerateMethodSignature(this.MethodBase);
return null;
}
}
/// <internalonly/>
public MethodBase MethodBase
{
[System.Security.SecurityCritical]
get
{
if (MI == null)
MI = RemotingServices.InternalGetMethodBaseFromMethodMessage(this);
return MI;
}
}
/// <internalonly/>
public String Uri
{
[System.Security.SecurityCritical]
get { return uri; }
set { uri = value; }
}
/// <internalonly/>
public bool HasVarArgs
{
[System.Security.SecurityCritical]
get { return fVarArgs; }
}
/// <internalonly/>
public virtual IDictionary Properties
{
[System.Security.SecurityCritical]
get
{
lock(this) {
if (InternalProperties == null)
{
InternalProperties = new Hashtable();
}
if (ExternalProperties == null)
{
ExternalProperties = new MCMDictionary(this, InternalProperties);
}
return ExternalProperties;
}
}
}
/// <internalonly/>
public LogicalCallContext LogicalCallContext
{
[System.Security.SecurityCritical] // auto-generated
get { return GetLogicalCallContext(); }
}
[System.Security.SecurityCritical] // auto-generated
internal LogicalCallContext GetLogicalCallContext()
{
if (callContext == null)
callContext = new LogicalCallContext();
return callContext;
}
internal LogicalCallContext SetLogicalCallContext(LogicalCallContext ctx)
{
LogicalCallContext old=callContext;
callContext=ctx;
return old;
}
//
// IInternalMessage
//
/// <internalonly/>
ServerIdentity IInternalMessage.ServerIdentityObject
{
[System.Security.SecurityCritical]
get { return srvID; }
[System.Security.SecurityCritical]
set { srvID = value; }
}
/// <internalonly/>
Identity IInternalMessage.IdentityObject
{
[System.Security.SecurityCritical]
get { return identity; }
[System.Security.SecurityCritical]
set { identity = value; }
}
/// <internalonly/>
[System.Security.SecurityCritical]
void IInternalMessage.SetURI(String val)
{
uri = val;
}
/// <internalonly/>
[System.Security.SecurityCritical]
void IInternalMessage.SetCallContext(LogicalCallContext newCallContext)
{
callContext = newCallContext;
}
/// <internalonly/>
[System.Security.SecurityCritical]
bool IInternalMessage.HasProperties()
{
return (ExternalProperties != null) || (InternalProperties != null);
}
//
// helper functions
//
[System.Security.SecurityCritical] // auto-generated
internal void FillHeaders(Header[] h)
{
FillHeaders(h, false);
}
[System.Security.SecurityCritical] // auto-generated
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<h.Length; i++)
{
FillHeader(h[i].Name, h[i].Value);
}
}
}
[System.Security.SecurityCritical] // auto-generated
internal virtual bool FillSpecialHeader(String key, Object value)
{
if (key == null)
{
//skip
}
else if (key.Equals("__Uri"))
{
uri = (String) value;
}
else if (key.Equals("__MethodName"))
{
methodName = (String) value;
}
else if (key.Equals("__MethodSignature"))
{
methodSignature = (Type[]) value;
}
else if (key.Equals("__TypeName"))
{
typeName = (String) value;
}
else if (key.Equals("__Args"))
{
args = (Object[]) value;
}
else if (key.Equals("__CallContext"))
{
// if the value is a string, then its the LogicalCallId
if (value is String)
{
callContext = new LogicalCallContext();
callContext.RemotingData.LogicalCallID = (String) value;
}
else
callContext = (LogicalCallContext) value;
}
else
{
return false;
}
return true;
}
[System.Security.SecurityCritical] // auto-generated
internal void FillHeader(String key, Object value)
{
Message.DebugOut("MethodCall::FillHeader: key:" + key + "\n");
if (!FillSpecialHeader(key,value))
{
if (InternalProperties == null)
{
InternalProperties = new Hashtable();
}
InternalProperties[key] = value;
}
}
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
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
//
//-================================================================================
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated_required
[Serializable]
[CLSCompliant(false)]
[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
//
/// <internalonly/>
public ConstructionCall(Header[] headers) : base(headers) {}
/// <internalonly/>
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
//
//
[System.Security.SecurityCritical]
internal override bool FillSpecialHeader(String key, Object value)
{
if (key == null)
{
//skip
}
else if (key.Equals("__ActivationType"))
{
Contract.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
//
/// <internalonly/>
public Object[] CallSiteActivationAttributes
{
[System.Security.SecurityCritical]
get
{
return _callSiteActivationAttributes;
}
}
/// <internalonly/>
public Type ActivationType
{
[System.Security.SecurityCritical]
get
{
if ((_activationType == null) && (_activationTypeName != null))
_activationType = RemotingServices.InternalGetTypeFromQualifiedTypeName(_activationTypeName, false);
return _activationType;
}
}
/// <internalonly/>
public String ActivationTypeName
{
[System.Security.SecurityCritical]
get
{
return _activationTypeName;
}
}
/// <internalonly/>
public IList ContextProperties
{
[System.Security.SecurityCritical]
get
{
if (_contextProperties == null)
{
_contextProperties = new ArrayList();
}
return _contextProperties;
}
}
/// <internalonly/>
public override IDictionary Properties
{
[System.Security.SecurityCritical]
get
{
lock(this)
{
if (InternalProperties == null)
{
InternalProperties = new Hashtable();
}
if (ExternalProperties == null)
{
ExternalProperties = new CCMDictionary(this, InternalProperties);
}
return ExternalProperties;
}
}
}
// IConstructionCallMessage::Activator
/// <internalonly/>
public IActivator Activator
{
[System.Security.SecurityCritical]
get { return _activator; }
[System.Security.SecurityCritical]
set { _activator = value; }
}
}
//+================================================================================
//
// Synopsis: Message used for deserialization of a method response
//
//-================================================================================
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated_required
[Serializable]
[CLSCompliant(false)]
[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;
/// <internalonly/>
protected IDictionary InternalProperties;
/// <internalonly/>
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
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
public MethodResponse(Header[] h1, IMethodCallMessage mcm)
{
if (mcm == null)
throw new ArgumentNullException("mcm");
Contract.EndContractBlock();
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);
}
[System.Security.SecurityCritical] // auto-generated
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;
}
[System.Security.SecurityCritical] // auto-generated
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.
//
[System.Security.SecurityCritical] // auto-generated
internal MethodResponse(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
Contract.EndContractBlock();
SetObjectData(info, context);
}
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
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
//
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
public void RootSetObjectData(SerializationInfo info, StreamingContext ctx)
{
SetObjectData(info, ctx);
}
[System.Security.SecurityCritical] // auto-generated
internal void SetObjectData(SerializationInfo info, StreamingContext ctx)
{
if (info == null)
throw new ArgumentNullException("info");
Contract.EndContractBlock();
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
//
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated_required
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<paramNames.Count; i++)
{
String memberName = (String)paramNames[i];
// check for the parameter name
int position = -1;
for (int j=0; j<pinfos.Length; j++)
{
if (memberName.Equals(pinfos[j].Name))
{
position = pinfos[j].Position;
}
}
// no name so check for well known name
if (position == -1)
{
if (!memberName.StartsWith("__param", StringComparison.Ordinal))
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Message_BadSerialization"));
}
position = Int32.Parse(memberName.Substring(7), CultureInfo.InvariantCulture);
}
// if still not resolved then throw
if (position >= 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<paramNames.Count; j++)
{
String memberName = (String)paramNames[j];
if (outArgs == null)
{
outArgs = new Object[argCount];
}
int position = argMapper.Map[j-paramNameIndex];
outArgs[position] = Message.SoapCoerceArg(info.GetValue(memberName, typeof(Object)), pinfos[position].ParameterType, keyToNamespaceTable);
}
}
} // SetObjectFromSoapData
[System.Security.SecurityCritical] // auto-generated
internal LogicalCallContext GetLogicalCallContext()
{
if (callContext == null)
callContext = new LogicalCallContext();
return callContext;
}
internal LogicalCallContext SetLogicalCallContext(LogicalCallContext ctx)
{
LogicalCallContext old=callContext;
callContext=ctx;
return old;
}
//
// IMethodReturnMessage
//
/// <internalonly/>
public String Uri
{
[System.Security.SecurityCritical]
get { return uri; }
set { uri = value; }
}
/// <internalonly/>
public String MethodName
{
[System.Security.SecurityCritical]
get { return methodName; }
}
/// <internalonly/>
public String TypeName
{
[System.Security.SecurityCritical]
get { return typeName; }
}
/// <internalonly/>
public Object MethodSignature
{
[System.Security.SecurityCritical]
get { return methodSignature; }
}
/// <internalonly/>
public MethodBase MethodBase
{
[System.Security.SecurityCritical]
get { return MI; }
}
/// <internalonly/>
public bool HasVarArgs
{
[System.Security.SecurityCritical]
get
{
// Var args nyi..
return false;
}
}
/// <internalonly/>
public int ArgCount
{
[System.Security.SecurityCritical]
get
{
if (outArgs == null)
return 0;
else
return outArgs.Length;
}
}
/// <internalonly/>
[System.Security.SecurityCritical]
public Object GetArg(int argNum) { return outArgs[argNum]; }
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
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;
}
/// <internalonly/>
public Object[] Args
{
[System.Security.SecurityCritical]
get { return outArgs; }
}
/// <internalonly/>
public int OutArgCount
{
[System.Security.SecurityCritical]
get
{
if (argMapper == null) argMapper = new ArgMapper(this, true);
return argMapper.ArgCount;
}
}
/// <internalonly/>
[System.Security.SecurityCritical]
public Object GetOutArg(int argNum)
{
if (argMapper == null) argMapper = new ArgMapper(this, true);
return argMapper.GetArg(argNum);
}
/// <internalonly/>
[System.Security.SecurityCritical]
public String GetOutArgName(int index)
{
if (argMapper == null) argMapper = new ArgMapper(this, true);
return argMapper.GetArgName(index);
}
/// <internalonly/>
public Object[] OutArgs
{
[System.Security.SecurityCritical]
get
{
if (argMapper == null) argMapper = new ArgMapper(this, true);
return argMapper.Args;
}
}
/// <internalonly/>
public Exception Exception
{
[System.Security.SecurityCritical]
get { return fault; }
}
/// <internalonly/>
public Object ReturnValue
{
[System.Security.SecurityCritical]
get { return retVal; }
}
/// <internalonly/>
public virtual IDictionary Properties
{
[System.Security.SecurityCritical]
get
{
lock(this)
{
if (InternalProperties == null)
{
InternalProperties = new Hashtable();
}
if (ExternalProperties == null)
{
ExternalProperties = new MRMDictionary(this, InternalProperties);
}
return ExternalProperties;
}
}
}
/// <internalonly/>
public LogicalCallContext LogicalCallContext
{
[System.Security.SecurityCritical] // auto-generated
get { return GetLogicalCallContext();}
}
//
// helpers
//
[System.Security.SecurityCritical] // auto-generated
internal void FillHeaders(Header[] h)
{
FillHeaders(h, false);
} // FillHeaders
[System.Security.SecurityCritical] // auto-generated
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<h.Length; i++)
{
FillHeader(h[i].Name, h[i].Value);
}
}
} // FillHeaders
[System.Security.SecurityCritical] // auto-generated
internal void FillHeader(String name, Object value)
{
Message.DebugOut("MethodCall::FillHeaders: name: " + (name == null ? "NULL" : name) + "\n");
Message.DebugOut("MethodCall::FillHeaders: Value.GetClass: " + (value == null ? "NULL" : value.GetType().FullName) + "\n");
Message.DebugOut("MethodCall::FillHeaders: Value.ToString: " + (value == null ? "NULL" : value.ToString()) + "\n");
if (name.Equals("__MethodName"))
{
methodName = (String) value;
}
else if (name.Equals("__Uri"))
{
uri = (String) value;
}
else if (name.Equals("__MethodSignature"))
{
methodSignature = (Type[]) value;
}
else if (name.Equals("__TypeName"))
{
typeName = (String) value;
}
else if (name.Equals("__OutArgs"))
{
outArgs = (Object[]) value;
}
else if (name.Equals("__CallContext"))
{
// if the value is a string, then its the LogicalCallId
if (value is String)
{
callContext = new LogicalCallContext();
callContext.RemotingData.LogicalCallID = (String) value;
}
else
callContext = (LogicalCallContext) value;
}
else if (name.Equals("__Return"))
{
retVal = value;
}
else
{
if (InternalProperties == null)
{
InternalProperties = new Hashtable();
}
InternalProperties[name] = value;
}
}
//
// IInternalMessage
//
/// <internalonly/>
ServerIdentity IInternalMessage.ServerIdentityObject
{
[System.Security.SecurityCritical]
get { return null; }
[System.Security.SecurityCritical]
set { }
}
/// <internalonly/>
Identity IInternalMessage.IdentityObject
{
[System.Security.SecurityCritical]
get { return null; }
[System.Security.SecurityCritical]
set { }
}
/// <internalonly/>
[System.Security.SecurityCritical]
void IInternalMessage.SetURI(String val)
{
uri = val;
}
/// <internalonly/>
[System.Security.SecurityCritical]
void IInternalMessage.SetCallContext(LogicalCallContext newCallContext)
{
callContext = newCallContext;
}
/// <internalonly/>
[System.Security.SecurityCritical]
bool IInternalMessage.HasProperties()
{
return (ExternalProperties != null) || (InternalProperties != null);
}
} // class MethodResponse
internal interface ISerializationRootObject
{
[System.Security.SecurityCritical] // auto-generated_required
void RootSetObjectData(SerializationInfo info, StreamingContext ctx);
}
[Serializable]
internal class SerializationMonkey : ISerializable, IFieldInfo
{
internal ISerializationRootObject _obj;
internal String[] fieldNames = null;
internal Type[] fieldTypes = null;
[System.Security.SecurityCritical] // auto-generated
internal SerializationMonkey(SerializationInfo info, StreamingContext ctx)
{
Contract.Assert(_obj != null, "SerializationMonkey's _obj field should have been initialized elsewhere with a special hack.");
_obj.RootSetObjectData(info, ctx);
}
[System.Security.SecurityCritical] // auto-generated_required
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(
Environment.GetResourceString(
"NotSupported_Method"));
}
public String[] FieldNames
{
[System.Security.SecurityCritical] // auto-generated
get {return fieldNames;}
[System.Security.SecurityCritical] // auto-generated
set {fieldNames = value;}
}
public Type[] FieldTypes
{
[System.Security.SecurityCritical] // auto-generated
get {return fieldTypes;}
[System.Security.SecurityCritical] // auto-generated
set {fieldTypes = value;}
}
}
//+================================================================================
//
// Synopsis: Message used for deserialization of a method construction
//
//-================================================================================
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated_required
[Serializable]
[CLSCompliant(false)]
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
[System.Runtime.InteropServices.ComVisible(true)]
public class ConstructionResponse : MethodResponse, IConstructionReturnMessage
{
/// <internalonly/>
public ConstructionResponse(Header[] h, IMethodCallMessage mcm) : base(h, mcm) {}
internal ConstructionResponse(SerializationInfo info, StreamingContext context) : base (info, context) {}
/// <internalonly/>
public override IDictionary Properties
{
[System.Security.SecurityCritical]
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.
[System.Security.SecurityCritical] // auto-generated
internal TransitionCall(
IntPtr targetCtxID,
CrossContextDelegate deleg)
{
Contract.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.
[System.Security.SecurityCritical] // auto-generated
internal TransitionCall(IntPtr targetCtxID, IntPtr eeData, int targetDomainID)
{
Contract.Assert(targetCtxID != IntPtr.Zero, "bad target ctx for call back");
Contract.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
Contract.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");
}
Contract.EndContractBlock();
_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");
Contract.Assert(_targetDomainID != 0, "target domain should be non-zero");
}
//IMessage::GetProperties
public IDictionary Properties
{
[System.Security.SecurityCritical] // auto-generated
get
{
if (_props == null)
{
lock(this)
{
if (_props == null)
{
_props = new Hashtable();
}
}
}
return _props;
}
}
//IInternalMessage::ServerIdentityObject
ServerIdentity IInternalMessage.ServerIdentityObject
{
[System.Security.SecurityCritical]
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).
Contract.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;
}
Contract.Assert(ctx != null, "Null target context unexpected!");
_srvID = new ServerIdentity(
null,
Thread.GetContextInternal(_targetCtxID));
_srvID.RaceSetServerObjectChain(this);
}
}
return _srvID;
}
[System.Security.SecurityCritical]
set
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
}
//IInternalMessage::IdentityObject
Identity IInternalMessage.IdentityObject
{
[System.Security.SecurityCritical]
get
{
return _ID;
}
[System.Security.SecurityCritical]
set
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
}
//IInternalMessage::SetURI
[System.Security.SecurityCritical]
void IInternalMessage.SetURI(String uri)
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
[System.Security.SecurityCritical]
void IInternalMessage.SetCallContext(LogicalCallContext callContext)
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
[System.Security.SecurityCritical]
bool IInternalMessage.HasProperties()
{
throw new RemotingException(
Environment.GetResourceString(
"Remoting_Default"));
}
//IMessage::SyncProcessMessage
[System.Security.SecurityCritical] // auto-generated
public IMessage SyncProcessMessage(IMessage msg)
{
Contract.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
[System.Security.SecurityCritical] // auto-generated
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
IMessage retMsg = SyncProcessMessage(msg);
replySink.SyncProcessMessage(retMsg);
return null;
}
//IMessage::GetNextSink()
public IMessageSink NextSink
{
[System.Security.SecurityCritical] // auto-generated
get{return null;}
}
//ISerializable::GetObjectData
[System.Security.SecurityCritical] // auto-generated_required
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null || (context.State != StreamingContextStates.CrossAppDomain))
{
throw new ArgumentNullException("info");
}
Contract.EndContractBlock();
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;
[System.Security.SecurityCritical] // auto-generated
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
[System.Security.SecurityCritical] // auto-generated
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;
}
}
}
[System.Security.SecurityCritical] // auto-generated
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]);
}
}
[System.Security.SecurityCritical] // auto-generated
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
{
[System.Security.SecurityCritical] // auto-generated
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
{
[System.Security.SecurityCritical] // auto-generated
get{ return null;}
}
// IMethodMessage
public String Uri
{
[System.Security.SecurityCritical] // auto-generated
get{ return m_URI; }
}
public String MethodName
{
[System.Security.SecurityCritical] // auto-generated
get{ return m_MethodName; }
}
public String TypeName
{
[System.Security.SecurityCritical] // auto-generated
get{ return m_TypeName; }
}
public Object MethodSignature
{
[System.Security.SecurityCritical] // auto-generated
get { return m_MethodSignature; }
}
public MethodBase MethodBase
{
[System.Security.SecurityCritical] // auto-generated
get { return null; }
}
public int ArgCount
{
[System.Security.SecurityCritical] // auto-generated
get { return m_ArgCount;}
}
[System.Security.SecurityCritical] // auto-generated
public String GetArgName(int index) { return m_ArgName; }
[System.Security.SecurityCritical] // auto-generated
public Object GetArg(int argNum) { return null;}
public Object[] Args
{
[System.Security.SecurityCritical] // auto-generated
get { return null;}
}
public bool HasVarArgs
{
[System.Security.SecurityCritical] // auto-generated
get { return false;}
}
// IMethodCallMessage
public int InArgCount
{
[System.Security.SecurityCritical] // auto-generated
get { return m_ArgCount;}
}
[System.Security.SecurityCritical] // auto-generated
public String GetInArgName(int index) { return null; }
[System.Security.SecurityCritical] // auto-generated
public Object GetInArg(int argNum) { return null;}
public Object[] InArgs
{
[System.Security.SecurityCritical] // auto-generated
get { return null; }
}
public LogicalCallContext LogicalCallContext
{
[System.Security.SecurityCritical] // auto-generated
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.
//
//-================================================================================
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public class InternalMessageWrapper
{
/// <internalonly/>
protected IMessage WrappedMessage;
/// <internalonly/>
public InternalMessageWrapper(IMessage msg)
{
WrappedMessage = msg;
} // InternalMessageWrapper
[System.Security.SecurityCritical] // auto-generated
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
[System.Security.SecurityCritical] // auto-generated
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.
//
//-================================================================================
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated_required
[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]
{
[System.Security.SecuritySafeCritical] // overrides transparent public member
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];
}
[System.Security.SecuritySafeCritical] // overrides transparent public member
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;
/// <internalonly/>
public MethodCallMessageWrapper(IMethodCallMessage msg) : base(msg)
{
_msg = msg;
_args = _msg.Args;
} // MethodCallMessageWrapper
// IMethodMessage implementation
/// <internalonly/>
public virtual String Uri
{
[System.Security.SecurityCritical]
get
{
return _msg.Uri;
}
set
{
_msg.Properties[Message.UriKey] = value;
}
}
/// <internalonly/>
public virtual String MethodName
{
[System.Security.SecurityCritical]
get { return _msg.MethodName; }
}
/// <internalonly/>
public virtual String TypeName
{
[System.Security.SecurityCritical]
get { return _msg.TypeName; }
}
/// <internalonly/>
public virtual Object MethodSignature
{
[System.Security.SecurityCritical]
get { return _msg.MethodSignature; }
}
/// <internalonly/>
public virtual LogicalCallContext LogicalCallContext
{
[System.Security.SecurityCritical]
get { return _msg.LogicalCallContext; }
}
/// <internalonly/>
public virtual MethodBase MethodBase
{
[System.Security.SecurityCritical]
get { return _msg.MethodBase; }
}
/// <internalonly/>
public virtual int ArgCount
{
[System.Security.SecurityCritical]
get
{
if (_args != null)
return _args.Length;
else
return 0;
}
}
/// <internalonly/>
[System.Security.SecurityCritical]
public virtual String GetArgName(int index) { return _msg.GetArgName(index); }
/// <internalonly/>
[System.Security.SecurityCritical]
public virtual Object GetArg(int argNum) { return _args[argNum]; }
/// <internalonly/>
public virtual Object[] Args
{
[System.Security.SecurityCritical]
get { return _args; }
set { _args = value; }
}
/// <internalonly/>
public virtual bool HasVarArgs
{
[System.Security.SecurityCritical]
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.)
/// <internalonly/>
public virtual int InArgCount
{
[System.Security.SecurityCritical]
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.ArgCount;
}
} // InArgCount
/// <internalonly/>
[System.Security.SecurityCritical]
public virtual Object GetInArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.GetArg(argNum);
} // GetInArg
/// <internalonly/>
[System.Security.SecurityCritical]
public virtual String GetInArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.GetArgName(index);
} // GetInArgName
/// <internalonly/>
public virtual Object[] InArgs
{
[System.Security.SecurityCritical]
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, false);
return _argMapper.Args;
}
} // InArgs
// end of IMethodCallMessage implementation
/// <internalonly/>
public virtual IDictionary Properties
{
[System.Security.SecurityCritical]
get
{
if (_properties == null)
_properties = new MCMWrapperDictionary(this, _msg.Properties);
return _properties;
}
}
} // class MethodCallMessageWrapper
//+================================================================================
//
// Synopsis: Message wrapper used for creating custom method return messages.
//
//-================================================================================
/// <internalonly/>
[System.Security.SecurityCritical] // auto-generated_required
[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]
{
[System.Security.SecuritySafeCritical] // overrides transparent public member
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];
}
[System.Security.SecuritySafeCritical] // overrides transparent public member
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;
/// <internalonly/>
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
/// <internalonly/>
public String Uri
{
[System.Security.SecurityCritical]
get
{
return _msg.Uri;
}
set
{
_msg.Properties[Message.UriKey] = value;
}
}
/// <internalonly/>
public virtual String MethodName
{
[System.Security.SecurityCritical]
get { return _msg.MethodName; }
}
/// <internalonly/>
public virtual String TypeName
{
[System.Security.SecurityCritical]
get { return _msg.TypeName; }
}
/// <internalonly/>
public virtual Object MethodSignature
{
[System.Security.SecurityCritical]
get { return _msg.MethodSignature; }
}
/// <internalonly/>
public virtual LogicalCallContext LogicalCallContext
{
[System.Security.SecurityCritical]
get { return _msg.LogicalCallContext; }
}
/// <internalonly/>
public virtual MethodBase MethodBase
{
[System.Security.SecurityCritical]
get { return _msg.MethodBase; }
}
/// <internalonly/>
public virtual int ArgCount
{
[System.Security.SecurityCritical]
get
{
if (_args != null)
return _args.Length;
else
return 0;
}
}
/// <internalonly/>
[System.Security.SecurityCritical]
public virtual String GetArgName(int index) { return _msg.GetArgName(index); }
/// <internalonly/>
[System.Security.SecurityCritical]
public virtual Object GetArg(int argNum) { return _args[argNum]; }
/// <internalonly/>
public virtual Object[] Args
{
[System.Security.SecurityCritical]
get { return _args; }
set { _args = value; }
}
/// <internalonly/>
public virtual bool HasVarArgs
{
[System.Security.SecurityCritical]
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.)
/// <internalonly/>
public virtual int OutArgCount
{
[System.Security.SecurityCritical]
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.ArgCount;
}
}
/// <internalonly/>
[System.Security.SecurityCritical]
public virtual Object GetOutArg(int argNum)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArg(argNum);
}
/// <internalonly/>
[System.Security.SecurityCritical]
public virtual String GetOutArgName(int index)
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.GetArgName(index);
}
/// <internalonly/>
public virtual Object[] OutArgs
{
[System.Security.SecurityCritical]
get
{
if (_argMapper == null) _argMapper = new ArgMapper(this, true);
return _argMapper.Args;
}
}
/// <internalonly/>
public virtual Exception Exception
{
[System.Security.SecurityCritical]
get { return _exception; }
set { _exception = value; }
}
/// <internalonly/>
public virtual Object ReturnValue
{
[System.Security.SecurityCritical]
get { return _returnValue; }
set { _returnValue = value; }
}
// end of IMethodReturnMessage implementation
// IMessage
/// <internalonly/>
public virtual IDictionary Properties
{
[System.Security.SecurityCritical]
get
{
if (_properties == null)
_properties = new MRMWrapperDictionary(this, _msg.Properties);
return _properties;
}
}
} // class MethodReturnMessageWrapper
} // namespace Remoting
|