Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / clr / src / BCL / System / Runtime / Remoting / StackBuilderSink.cs / 5 / StackBuilderSink.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** File: StackBuilderSink.cs
**
**
** Purpose: Terminating sink which will build a stack and
** make a method call on an object
**
**
===========================================================*/
namespace System.Runtime.Remoting.Messaging {
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Metadata;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Principal;
/* Assembly Access */
using System;
using System.Globalization;
[Serializable]
internal class StackBuilderSink : IMessageSink
{
//+===========================================================
//
// Method: Constructor, public
//
// Synopsis: Store server object
//
// History: 06-May-1999 MattSmit Created
//-===========================================================
public StackBuilderSink(MarshalByRefObject server)
{
_server = server;
}
public StackBuilderSink(Object server)
{
_server = server;
if (_server==null)
{
_bStatic = true;
}
}
public virtual IMessage SyncProcessMessage(IMessage msg)
{
return SyncProcessMessage(msg, 0, false);
}
internal virtual IMessage SyncProcessMessage(IMessage msg, int methodPtr, bool fExecuteInContext)
{
// Validate message here
IMessage errMsg = InternalSink.ValidateMessage(msg);
if (errMsg != null)
{
return errMsg;
}
IMethodCallMessage mcMsg = msg as IMethodCallMessage;
IMessage retMessage;
LogicalCallContext oldCallCtx = null;
LogicalCallContext lcc = CallContext.GetLogicalCallContext();
object xADCall = lcc.GetData(CrossAppDomainSink.LCC_DATA_KEY);
bool isCallContextSet = false;
try
{
Object server = _server;
BCLDebug.Assert((server!=null) == (!_bStatic),
"Invalid state in stackbuilder sink?");
// validate the method base if necessary
VerifyIsOkToCallMethod(server, mcMsg);
// install call context onto the thread, holding onto
// the one that is currently on the thread
LogicalCallContext messageCallContext = null;
if (mcMsg != null)
{
messageCallContext = mcMsg.LogicalCallContext;
}
else
{
messageCallContext = (LogicalCallContext)msg.Properties["__CallContext"];
}
oldCallCtx = CallContext.SetLogicalCallContext(messageCallContext);
isCallContextSet = true;
messageCallContext.PropagateIncomingHeadersToCallContext(msg);
PreserveThreadPrincipalIfNecessary(messageCallContext, oldCallCtx);
// NOTE: target for dispatch will be NULL when the StackBuilderSink
// is used for async delegates on static methods.
// *** NOTE ***
// Although we always pass _server to these calls in the EE,
// when we execute using Message::Dispatch we are using TP as
// the this-ptr ... (what the call site thinks is the this-ptr)
// when we execute using StackBuilderSink::PrivatePM we use
// _server as the this-ptr (which could be different if there
// is interception for strictly MBR types in the same AD).
// ************
if (IsOKToStackBlt(mcMsg, server)
&& ((Message)mcMsg).Dispatch(server, fExecuteInContext))
{
//retMessage = StackBasedReturnMessage.GetObjectFromPool((Message)mcMsg);
retMessage = new StackBasedReturnMessage();
((StackBasedReturnMessage)retMessage).InitFields((Message)mcMsg);
// call context could be different then the one from before the call.
LogicalCallContext latestCallContext = CallContext.GetLogicalCallContext();
// retrieve outgoing response headers
latestCallContext.PropagateOutgoingHeadersToMessage(retMessage);
// Install call context back into Message (from the thread)
((StackBasedReturnMessage)retMessage).SetLogicalCallContext(latestCallContext);
}
else
{
MethodBase mb = GetMethodBase(mcMsg);
Object[] outArgs = null;
Object ret = null;
RemotingMethodCachedData methodCache =
InternalRemotingServices.GetReflectionCachedData(mb);
Message.DebugOut("StackBuilderSink::Calling PrivateProcessMessage\n");
Object[] args = Message.CoerceArgs(mcMsg, methodCache.Parameters);
ret = PrivateProcessMessage(
mb.MethodHandle,
args,
server,
methodPtr,
fExecuteInContext,
out outArgs);
CopyNonByrefOutArgsFromOriginalArgs(methodCache, args, ref outArgs);
// call context could be different then the one from before the call.
LogicalCallContext latestCallContext = CallContext.GetLogicalCallContext();
if (xADCall != null && ((bool)xADCall) == true && latestCallContext != null)
{
// Special case Principal since if might not be serializable before returning
// ReturnMessage
latestCallContext.RemovePrincipalIfNotSerializable();
}
retMessage = new ReturnMessage(
ret,
outArgs,
(outArgs == null ? 0 : outArgs.Length),
latestCallContext,
mcMsg);
// retrieve outgoing response headers
latestCallContext.PropagateOutgoingHeadersToMessage(retMessage);
// restore the call context on the thread
CallContext.SetLogicalCallContext(oldCallCtx);
}
} catch (Exception e)
{
Message.DebugOut(
"StackBuilderSink::The server object probably threw an exception " +
e.Message + e.StackTrace + "\n" );
retMessage = new ReturnMessage(e, mcMsg);
((ReturnMessage)retMessage).SetLogicalCallContext(mcMsg.LogicalCallContext);
if (isCallContextSet)
CallContext.SetLogicalCallContext(oldCallCtx);
}
return retMessage;
}
public virtual IMessageCtrl AsyncProcessMessage(
IMessage msg, IMessageSink replySink)
{
IMethodCallMessage mcMsg = (IMethodCallMessage)msg;
IMessageCtrl retCtrl = null;
IMessage retMessage = null;
LogicalCallContext oldCallCtx = null;
bool isCallContextSet = false;
try{
try
{
LogicalCallContext callCtx = (LogicalCallContext)
mcMsg.Properties[Message.CallContextKey];
Object server = _server;
// validate the method base if necessary
VerifyIsOkToCallMethod(server, mcMsg);
// install call context onto the thread, holding onto
// the one that is currently on the thread
oldCallCtx = CallContext.SetLogicalCallContext(callCtx);
isCallContextSet = true;
// retrieve incoming headers
callCtx.PropagateIncomingHeadersToCallContext(msg);
PreserveThreadPrincipalIfNecessary(callCtx, oldCallCtx);
// see if this is a server message that was dispatched asynchronously
ServerChannelSinkStack sinkStack =
msg.Properties["__SinkStack"] as ServerChannelSinkStack;
if (sinkStack != null)
sinkStack.ServerObject = server;
BCLDebug.Assert((server!=null)==(!_bStatic),
"Invalid state in stackbuilder sink?");
MethodBase mb = GetMethodBase(mcMsg);
Object[] outArgs = null;
Object ret = null;
RemotingMethodCachedData methodCache =
InternalRemotingServices.GetReflectionCachedData(mb);
Object[] args = Message.CoerceArgs(mcMsg, methodCache.Parameters);
ret = PrivateProcessMessage(mb.MethodHandle,
args,
server,
0,
false,
out outArgs);
CopyNonByrefOutArgsFromOriginalArgs(methodCache, args, ref outArgs);
if(replySink != null)
{
// call context could be different then the one from before the call.
LogicalCallContext latestCallContext = CallContext.GetLogicalCallContext();
if (latestCallContext != null)
{
// Special case Principal since if might not be serializable before returning
// ReturnMessage
latestCallContext.RemovePrincipalIfNotSerializable();
}
retMessage = new ReturnMessage(
ret,
outArgs,
(outArgs == null ? 0 : outArgs.Length),
latestCallContext,
mcMsg);
// retrieve outgoing response headers
latestCallContext.PropagateOutgoingHeadersToMessage(retMessage);
}
}
catch (Exception e)
{
if(replySink != null)
{
retMessage = new ReturnMessage(e, mcMsg);
((ReturnMessage)retMessage).SetLogicalCallContext(
(LogicalCallContext)
mcMsg.Properties[Message.CallContextKey]);
}
}
finally
{
if (replySink != null)
{
// Call the reply sink without catching the exceptions
// in it. In v2.0 any exceptions in the callback for example
// would probably bring down the process
replySink.SyncProcessMessage(retMessage);
}
}
}
finally {
// restore the call context on the thread
if (isCallContextSet)
CallContext.SetLogicalCallContext(oldCallCtx);
}
return retCtrl;
} // AsyncProcessMessage
public IMessageSink NextSink
{
get
{
// there is no nextSink for the StackBuilderSink
return null;
}
}
// This check if the call-site on the TP is in our own AD
// It also handles the special case where the TP is on
// a well-known object and we cannot do stack-blting
internal bool IsOKToStackBlt(IMethodMessage mcMsg, Object server)
{
bool bOK = false;
Message msg = mcMsg as Message;
if(null != msg)
{
IInternalMessage iiMsg = (IInternalMessage) msg;
// If there is a frame in the message we can always
// Blt it (provided it is not a proxy to a well-known
// object in our own appDomain)!
// The GetThisPtr == server test allows for people to wrap
// our proxy with their own interception .. in that case
// we should not blt the stack.
if (msg.GetFramePtr() != IntPtr.Zero
&& msg.GetThisPtr() == server
&&
( iiMsg.IdentityObject == null ||
( iiMsg.IdentityObject != null
&& iiMsg.IdentityObject == iiMsg.ServerIdentityObject
)
)
)
{
bOK = true;
}
}
return bOK;
}
private static MethodBase GetMethodBase(IMethodMessage msg)
{
MethodBase mb = msg.MethodBase;
if(null == mb)
{
BCLDebug.Trace("REMOTE", "Method missing w/name ", msg.MethodName);
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_Message_MethodMissing"),
msg.MethodName,
msg.TypeName));
}
return mb;
}
private static void VerifyIsOkToCallMethod(Object server, IMethodMessage msg)
{
bool bTypeChecked = false;
MarshalByRefObject mbr = server as MarshalByRefObject;
if (mbr != null)
{
bool fServer;
Identity id = MarshalByRefObject.GetIdentity(mbr, out fServer);
if (id != null)
{
ServerIdentity srvId = id as ServerIdentity;
if ((srvId != null) && srvId.MarshaledAsSpecificType)
{
Type srvType = srvId.ServerType;
if (srvType != null)
{
MethodBase mb = GetMethodBase(msg);
Type declaringType = mb.DeclaringType;
// make sure that srvType is not more restrictive than method base
// (i.e. someone marshaled with a specific type or interface exposed)
if ((declaringType != srvType) &&
!declaringType.IsAssignableFrom(srvType))
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_InvalidCallingType"),
mb.DeclaringType.FullName, srvType.FullName));
}
// Set flag so we don't repeat this work below.
if (declaringType.IsInterface)
{
VerifyNotIRemoteDispatch(declaringType);
}
bTypeChecked = true;
}
}
}
// We must always verify that the type corresponding to
// the method being invoked is compatible with the real server
// type.
if (!bTypeChecked)
{
MethodBase mb = GetMethodBase(msg);
Type reflectedType = mb.ReflectedType;
if (!reflectedType.IsInterface)
{
if (!reflectedType.IsInstanceOfType(mbr))
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_InvalidCallingType"),
reflectedType.FullName,
mbr.GetType().FullName));
}
}
// This code prohibits calls made to System.EnterpriseServices.IRemoteDispatch
// so that remote call cannot bypass lowFilterLevel logic in the serializers.
// This special casing should be removed in the future
else
{
VerifyNotIRemoteDispatch(reflectedType);
}
}
}
} // VerifyIsOkToCallMethod
// This code prohibits calls made to System.EnterpriseServices.IRemoteDispatch
// so that remote call cannot bypass lowFilterLevel logic in the serializers.
// This special casing should be removed in the future
// Check whether we are calling IRemoteDispatch
private static void VerifyNotIRemoteDispatch(Type reflectedType)
{
if(reflectedType.FullName.Equals(sIRemoteDispatch) &&
reflectedType.Module.Assembly.nGetSimpleName().Equals(sIRemoteDispatchAssembly))
{
throw new RemotingException(
Environment.GetResourceString("Remoting_CantInvokeIRemoteDispatch"));
}
}
// copies references of non-byref [In, Out] args from the input args to
// the output args array.
internal void CopyNonByrefOutArgsFromOriginalArgs(RemotingMethodCachedData methodCache,
Object[] args,
ref Object[] marshalResponseArgs)
{
int[] map = methodCache.NonRefOutArgMap;
if (map.Length > 0)
{
if (marshalResponseArgs == null)
marshalResponseArgs = new Object[methodCache.Parameters.Length];
foreach (int pos in map)
{
marshalResponseArgs[pos] = args[pos];
}
}
}
// For the incoming call, we sometimes need to preserve the thread principal from
// the executing thread, instead of blindly bashing it with the one from the message.
// For instance, in cross process calls, the principal will always be null
// in the incoming message. However, when we are hosted in ASP.Net, ASP.Net will handle
// authentication and set up the thread principal. We should dispatch the call
// using the identity that it set up.
internal static void PreserveThreadPrincipalIfNecessary(
LogicalCallContext messageCallContext,
LogicalCallContext threadCallContext)
{
BCLDebug.Assert(messageCallContext != null, "message should always have a call context");
if (threadCallContext != null)
{
if (messageCallContext.Principal == null)
{
IPrincipal currentPrincipal = threadCallContext.Principal;
if (currentPrincipal != null)
{
messageCallContext.Principal = currentPrincipal;
}
}
}
} // PreserveThreadPrincipalIfNecessary
internal Object ServerObject
{
get { return _server; }
}
//+===========================================================
//
// Method: PrivateProcessMessage, public
//
// Synopsis: does the actual work of building the stack,
// finding the correct code address and calling it.
//
// History: 06-May-1999 MattSmit Created
//-============================================================
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object _PrivateProcessMessage(
IntPtr md, Object[] args, Object server, int methodPtr,
bool fExecuteInContext, out Object[] outArgs);
public Object PrivateProcessMessage(
RuntimeMethodHandle md, Object[] args, Object server, int methodPtr,
bool fExecuteInContext, out Object[] outArgs)
{
return _PrivateProcessMessage(md.Value, args, server, methodPtr, fExecuteInContext, out outArgs);
}
private Object _server; // target object
private static string sIRemoteDispatch = "System.EnterpriseServices.IRemoteDispatch";
private static string sIRemoteDispatchAssembly = "System.EnterpriseServices";
bool _bStatic;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** File: StackBuilderSink.cs
**
**
** Purpose: Terminating sink which will build a stack and
** make a method call on an object
**
**
===========================================================*/
namespace System.Runtime.Remoting.Messaging {
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Metadata;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Principal;
/* Assembly Access */
using System;
using System.Globalization;
[Serializable]
internal class StackBuilderSink : IMessageSink
{
//+===========================================================
//
// Method: Constructor, public
//
// Synopsis: Store server object
//
// History: 06-May-1999 MattSmit Created
//-===========================================================
public StackBuilderSink(MarshalByRefObject server)
{
_server = server;
}
public StackBuilderSink(Object server)
{
_server = server;
if (_server==null)
{
_bStatic = true;
}
}
public virtual IMessage SyncProcessMessage(IMessage msg)
{
return SyncProcessMessage(msg, 0, false);
}
internal virtual IMessage SyncProcessMessage(IMessage msg, int methodPtr, bool fExecuteInContext)
{
// Validate message here
IMessage errMsg = InternalSink.ValidateMessage(msg);
if (errMsg != null)
{
return errMsg;
}
IMethodCallMessage mcMsg = msg as IMethodCallMessage;
IMessage retMessage;
LogicalCallContext oldCallCtx = null;
LogicalCallContext lcc = CallContext.GetLogicalCallContext();
object xADCall = lcc.GetData(CrossAppDomainSink.LCC_DATA_KEY);
bool isCallContextSet = false;
try
{
Object server = _server;
BCLDebug.Assert((server!=null) == (!_bStatic),
"Invalid state in stackbuilder sink?");
// validate the method base if necessary
VerifyIsOkToCallMethod(server, mcMsg);
// install call context onto the thread, holding onto
// the one that is currently on the thread
LogicalCallContext messageCallContext = null;
if (mcMsg != null)
{
messageCallContext = mcMsg.LogicalCallContext;
}
else
{
messageCallContext = (LogicalCallContext)msg.Properties["__CallContext"];
}
oldCallCtx = CallContext.SetLogicalCallContext(messageCallContext);
isCallContextSet = true;
messageCallContext.PropagateIncomingHeadersToCallContext(msg);
PreserveThreadPrincipalIfNecessary(messageCallContext, oldCallCtx);
// NOTE: target for dispatch will be NULL when the StackBuilderSink
// is used for async delegates on static methods.
// *** NOTE ***
// Although we always pass _server to these calls in the EE,
// when we execute using Message::Dispatch we are using TP as
// the this-ptr ... (what the call site thinks is the this-ptr)
// when we execute using StackBuilderSink::PrivatePM we use
// _server as the this-ptr (which could be different if there
// is interception for strictly MBR types in the same AD).
// ************
if (IsOKToStackBlt(mcMsg, server)
&& ((Message)mcMsg).Dispatch(server, fExecuteInContext))
{
//retMessage = StackBasedReturnMessage.GetObjectFromPool((Message)mcMsg);
retMessage = new StackBasedReturnMessage();
((StackBasedReturnMessage)retMessage).InitFields((Message)mcMsg);
// call context could be different then the one from before the call.
LogicalCallContext latestCallContext = CallContext.GetLogicalCallContext();
// retrieve outgoing response headers
latestCallContext.PropagateOutgoingHeadersToMessage(retMessage);
// Install call context back into Message (from the thread)
((StackBasedReturnMessage)retMessage).SetLogicalCallContext(latestCallContext);
}
else
{
MethodBase mb = GetMethodBase(mcMsg);
Object[] outArgs = null;
Object ret = null;
RemotingMethodCachedData methodCache =
InternalRemotingServices.GetReflectionCachedData(mb);
Message.DebugOut("StackBuilderSink::Calling PrivateProcessMessage\n");
Object[] args = Message.CoerceArgs(mcMsg, methodCache.Parameters);
ret = PrivateProcessMessage(
mb.MethodHandle,
args,
server,
methodPtr,
fExecuteInContext,
out outArgs);
CopyNonByrefOutArgsFromOriginalArgs(methodCache, args, ref outArgs);
// call context could be different then the one from before the call.
LogicalCallContext latestCallContext = CallContext.GetLogicalCallContext();
if (xADCall != null && ((bool)xADCall) == true && latestCallContext != null)
{
// Special case Principal since if might not be serializable before returning
// ReturnMessage
latestCallContext.RemovePrincipalIfNotSerializable();
}
retMessage = new ReturnMessage(
ret,
outArgs,
(outArgs == null ? 0 : outArgs.Length),
latestCallContext,
mcMsg);
// retrieve outgoing response headers
latestCallContext.PropagateOutgoingHeadersToMessage(retMessage);
// restore the call context on the thread
CallContext.SetLogicalCallContext(oldCallCtx);
}
} catch (Exception e)
{
Message.DebugOut(
"StackBuilderSink::The server object probably threw an exception " +
e.Message + e.StackTrace + "\n" );
retMessage = new ReturnMessage(e, mcMsg);
((ReturnMessage)retMessage).SetLogicalCallContext(mcMsg.LogicalCallContext);
if (isCallContextSet)
CallContext.SetLogicalCallContext(oldCallCtx);
}
return retMessage;
}
public virtual IMessageCtrl AsyncProcessMessage(
IMessage msg, IMessageSink replySink)
{
IMethodCallMessage mcMsg = (IMethodCallMessage)msg;
IMessageCtrl retCtrl = null;
IMessage retMessage = null;
LogicalCallContext oldCallCtx = null;
bool isCallContextSet = false;
try{
try
{
LogicalCallContext callCtx = (LogicalCallContext)
mcMsg.Properties[Message.CallContextKey];
Object server = _server;
// validate the method base if necessary
VerifyIsOkToCallMethod(server, mcMsg);
// install call context onto the thread, holding onto
// the one that is currently on the thread
oldCallCtx = CallContext.SetLogicalCallContext(callCtx);
isCallContextSet = true;
// retrieve incoming headers
callCtx.PropagateIncomingHeadersToCallContext(msg);
PreserveThreadPrincipalIfNecessary(callCtx, oldCallCtx);
// see if this is a server message that was dispatched asynchronously
ServerChannelSinkStack sinkStack =
msg.Properties["__SinkStack"] as ServerChannelSinkStack;
if (sinkStack != null)
sinkStack.ServerObject = server;
BCLDebug.Assert((server!=null)==(!_bStatic),
"Invalid state in stackbuilder sink?");
MethodBase mb = GetMethodBase(mcMsg);
Object[] outArgs = null;
Object ret = null;
RemotingMethodCachedData methodCache =
InternalRemotingServices.GetReflectionCachedData(mb);
Object[] args = Message.CoerceArgs(mcMsg, methodCache.Parameters);
ret = PrivateProcessMessage(mb.MethodHandle,
args,
server,
0,
false,
out outArgs);
CopyNonByrefOutArgsFromOriginalArgs(methodCache, args, ref outArgs);
if(replySink != null)
{
// call context could be different then the one from before the call.
LogicalCallContext latestCallContext = CallContext.GetLogicalCallContext();
if (latestCallContext != null)
{
// Special case Principal since if might not be serializable before returning
// ReturnMessage
latestCallContext.RemovePrincipalIfNotSerializable();
}
retMessage = new ReturnMessage(
ret,
outArgs,
(outArgs == null ? 0 : outArgs.Length),
latestCallContext,
mcMsg);
// retrieve outgoing response headers
latestCallContext.PropagateOutgoingHeadersToMessage(retMessage);
}
}
catch (Exception e)
{
if(replySink != null)
{
retMessage = new ReturnMessage(e, mcMsg);
((ReturnMessage)retMessage).SetLogicalCallContext(
(LogicalCallContext)
mcMsg.Properties[Message.CallContextKey]);
}
}
finally
{
if (replySink != null)
{
// Call the reply sink without catching the exceptions
// in it. In v2.0 any exceptions in the callback for example
// would probably bring down the process
replySink.SyncProcessMessage(retMessage);
}
}
}
finally {
// restore the call context on the thread
if (isCallContextSet)
CallContext.SetLogicalCallContext(oldCallCtx);
}
return retCtrl;
} // AsyncProcessMessage
public IMessageSink NextSink
{
get
{
// there is no nextSink for the StackBuilderSink
return null;
}
}
// This check if the call-site on the TP is in our own AD
// It also handles the special case where the TP is on
// a well-known object and we cannot do stack-blting
internal bool IsOKToStackBlt(IMethodMessage mcMsg, Object server)
{
bool bOK = false;
Message msg = mcMsg as Message;
if(null != msg)
{
IInternalMessage iiMsg = (IInternalMessage) msg;
// If there is a frame in the message we can always
// Blt it (provided it is not a proxy to a well-known
// object in our own appDomain)!
// The GetThisPtr == server test allows for people to wrap
// our proxy with their own interception .. in that case
// we should not blt the stack.
if (msg.GetFramePtr() != IntPtr.Zero
&& msg.GetThisPtr() == server
&&
( iiMsg.IdentityObject == null ||
( iiMsg.IdentityObject != null
&& iiMsg.IdentityObject == iiMsg.ServerIdentityObject
)
)
)
{
bOK = true;
}
}
return bOK;
}
private static MethodBase GetMethodBase(IMethodMessage msg)
{
MethodBase mb = msg.MethodBase;
if(null == mb)
{
BCLDebug.Trace("REMOTE", "Method missing w/name ", msg.MethodName);
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString(
"Remoting_Message_MethodMissing"),
msg.MethodName,
msg.TypeName));
}
return mb;
}
private static void VerifyIsOkToCallMethod(Object server, IMethodMessage msg)
{
bool bTypeChecked = false;
MarshalByRefObject mbr = server as MarshalByRefObject;
if (mbr != null)
{
bool fServer;
Identity id = MarshalByRefObject.GetIdentity(mbr, out fServer);
if (id != null)
{
ServerIdentity srvId = id as ServerIdentity;
if ((srvId != null) && srvId.MarshaledAsSpecificType)
{
Type srvType = srvId.ServerType;
if (srvType != null)
{
MethodBase mb = GetMethodBase(msg);
Type declaringType = mb.DeclaringType;
// make sure that srvType is not more restrictive than method base
// (i.e. someone marshaled with a specific type or interface exposed)
if ((declaringType != srvType) &&
!declaringType.IsAssignableFrom(srvType))
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_InvalidCallingType"),
mb.DeclaringType.FullName, srvType.FullName));
}
// Set flag so we don't repeat this work below.
if (declaringType.IsInterface)
{
VerifyNotIRemoteDispatch(declaringType);
}
bTypeChecked = true;
}
}
}
// We must always verify that the type corresponding to
// the method being invoked is compatible with the real server
// type.
if (!bTypeChecked)
{
MethodBase mb = GetMethodBase(msg);
Type reflectedType = mb.ReflectedType;
if (!reflectedType.IsInterface)
{
if (!reflectedType.IsInstanceOfType(mbr))
{
throw new RemotingException(
String.Format(
CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_InvalidCallingType"),
reflectedType.FullName,
mbr.GetType().FullName));
}
}
// This code prohibits calls made to System.EnterpriseServices.IRemoteDispatch
// so that remote call cannot bypass lowFilterLevel logic in the serializers.
// This special casing should be removed in the future
else
{
VerifyNotIRemoteDispatch(reflectedType);
}
}
}
} // VerifyIsOkToCallMethod
// This code prohibits calls made to System.EnterpriseServices.IRemoteDispatch
// so that remote call cannot bypass lowFilterLevel logic in the serializers.
// This special casing should be removed in the future
// Check whether we are calling IRemoteDispatch
private static void VerifyNotIRemoteDispatch(Type reflectedType)
{
if(reflectedType.FullName.Equals(sIRemoteDispatch) &&
reflectedType.Module.Assembly.nGetSimpleName().Equals(sIRemoteDispatchAssembly))
{
throw new RemotingException(
Environment.GetResourceString("Remoting_CantInvokeIRemoteDispatch"));
}
}
// copies references of non-byref [In, Out] args from the input args to
// the output args array.
internal void CopyNonByrefOutArgsFromOriginalArgs(RemotingMethodCachedData methodCache,
Object[] args,
ref Object[] marshalResponseArgs)
{
int[] map = methodCache.NonRefOutArgMap;
if (map.Length > 0)
{
if (marshalResponseArgs == null)
marshalResponseArgs = new Object[methodCache.Parameters.Length];
foreach (int pos in map)
{
marshalResponseArgs[pos] = args[pos];
}
}
}
// For the incoming call, we sometimes need to preserve the thread principal from
// the executing thread, instead of blindly bashing it with the one from the message.
// For instance, in cross process calls, the principal will always be null
// in the incoming message. However, when we are hosted in ASP.Net, ASP.Net will handle
// authentication and set up the thread principal. We should dispatch the call
// using the identity that it set up.
internal static void PreserveThreadPrincipalIfNecessary(
LogicalCallContext messageCallContext,
LogicalCallContext threadCallContext)
{
BCLDebug.Assert(messageCallContext != null, "message should always have a call context");
if (threadCallContext != null)
{
if (messageCallContext.Principal == null)
{
IPrincipal currentPrincipal = threadCallContext.Principal;
if (currentPrincipal != null)
{
messageCallContext.Principal = currentPrincipal;
}
}
}
} // PreserveThreadPrincipalIfNecessary
internal Object ServerObject
{
get { return _server; }
}
//+===========================================================
//
// Method: PrivateProcessMessage, public
//
// Synopsis: does the actual work of building the stack,
// finding the correct code address and calling it.
//
// History: 06-May-1999 MattSmit Created
//-============================================================
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object _PrivateProcessMessage(
IntPtr md, Object[] args, Object server, int methodPtr,
bool fExecuteInContext, out Object[] outArgs);
public Object PrivateProcessMessage(
RuntimeMethodHandle md, Object[] args, Object server, int methodPtr,
bool fExecuteInContext, out Object[] outArgs)
{
return _PrivateProcessMessage(md.Value, args, server, methodPtr, fExecuteInContext, out outArgs);
}
private Object _server; // target object
private static string sIRemoteDispatch = "System.EnterpriseServices.IRemoteDispatch";
private static string sIRemoteDispatchAssembly = "System.EnterpriseServices";
bool _bStatic;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RelAssertionDirectKeyIdentifierClause.cs
- MgmtConfigurationRecord.cs
- WebFormDesignerActionService.cs
- Schema.cs
- SqlUserDefinedAggregateAttribute.cs
- HierarchicalDataTemplate.cs
- dsa.cs
- PeerCollaboration.cs
- CodeObjectCreateExpression.cs
- ServiceDescriptions.cs
- TypeConverterAttribute.cs
- TaskFileService.cs
- TextRenderer.cs
- UriWriter.cs
- HttpListenerRequest.cs
- ResolveInfo.cs
- Point3DCollection.cs
- Math.cs
- HashMembershipCondition.cs
- MetabaseReader.cs
- PropertyOverridesDialog.cs
- ComplexBindingPropertiesAttribute.cs
- DelegateSerializationHolder.cs
- UIElement3D.cs
- MethodBuilder.cs
- MenuCommand.cs
- Message.cs
- SqlConnectionPoolProviderInfo.cs
- securestring.cs
- FormViewDeleteEventArgs.cs
- SingleObjectCollection.cs
- ScriptControlManager.cs
- ProcessProtocolHandler.cs
- SyncOperationState.cs
- DrawingCollection.cs
- Application.cs
- HttpResponseHeader.cs
- LocalizationComments.cs
- ReplyChannelBinder.cs
- SortedList.cs
- CustomError.cs
- TextTreeInsertUndoUnit.cs
- KeyValueInternalCollection.cs
- SqlAliasesReferenced.cs
- ErrorLog.cs
- RbTree.cs
- _BasicClient.cs
- WindowsFormsHostPropertyMap.cs
- SettingsSavedEventArgs.cs
- DefaultHttpHandler.cs
- ObjectDataSourceSelectingEventArgs.cs
- MenuCommands.cs
- GridViewCommandEventArgs.cs
- StringCollection.cs
- PaintEvent.cs
- BuildProvidersCompiler.cs
- Journal.cs
- Publisher.cs
- RegexWriter.cs
- DocComment.cs
- CompositeFontParser.cs
- HyperLinkColumn.cs
- CodeLinePragma.cs
- WindowsSpinner.cs
- OleDbInfoMessageEvent.cs
- XmlSerializerAssemblyAttribute.cs
- GatewayIPAddressInformationCollection.cs
- CqlWriter.cs
- SoapAttributes.cs
- PeerInvitationResponse.cs
- DesignerActionPanel.cs
- TimeoutException.cs
- DtrList.cs
- Error.cs
- ToolStripPanelRenderEventArgs.cs
- DefaultAsyncDataDispatcher.cs
- PolygonHotSpot.cs
- DataGridCommandEventArgs.cs
- ProfileGroupSettingsCollection.cs
- DockAndAnchorLayout.cs
- MobileResource.cs
- DesignerValidationSummaryAdapter.cs
- _LocalDataStoreMgr.cs
- SByteStorage.cs
- SubordinateTransaction.cs
- FtpCachePolicyElement.cs
- PriorityChain.cs
- ConsumerConnectionPoint.cs
- BitmapEditor.cs
- BaseCollection.cs
- MobileFormsAuthentication.cs
- Evidence.cs
- ToolTipAutomationPeer.cs
- SmtpReplyReader.cs
- AnnouncementInnerClient11.cs
- DesignerLabelAdapter.cs
- TypeAccessException.cs
- WebServiceParameterData.cs
- AutomationIdentifier.cs
- GPRECT.cs