public virtual IMessage SyncProcessMessage(IMessage reqMsg)
{
Message.DebugOut("\n::::::::::::::::::::::::: CrossAppDomain Channel: Sync call starting");
IMessage errMsg = InternalSink.ValidateMessage(reqMsg);
if (errMsg != null)
{
return errMsg;
}
// currentPrincipal is used to save the current principal. It should be
// restored on the reply message.
IPrincipal currentPrincipal = null;
IMessage desRetMsg = null;
try
{
IMethodCallMessage mcmReqMsg = reqMsg as IMethodCallMessage;
if (mcmReqMsg != null)
{
LogicalCallContext lcc = mcmReqMsg.LogicalCallContext;
if (lcc != null)
{
// Special case Principal since if might not be serializable
currentPrincipal = lcc.RemovePrincipalIfNotSerializable();
}
}
MemoryStream reqStm = null;
SmuggledMethodCallMessage smuggledMcm = SmuggledMethodCallMessage.SmuggleIfPossible(reqMsg);
if (smuggledMcm == null)
{
//*********************** SERIALIZE REQ-MSG ****************
// Deserialization of objects requires permissions that users
// of remoting are not guaranteed to possess. Since remoting
// can guarantee that it's users can't abuse deserialization
// (since it won't allow them to pass in raw blobs of
// serialized data), it should assert the permissions
// necessary before calling the deserialization code. This
// will terminate the security stackwalk caused when
// serialization checks for the correct permissions at the
// remoting stack frame so the check won't continue on to
// the user and fail.
// We will hold off from doing this for x-process channels
// until the big picture of distributed security is finalized.
reqStm = CrossAppDomainSerializer.SerializeMessage(reqMsg);
}
// Retrieve calling caller context here, where it is safe from the view
// of app domain checking code
LogicalCallContext oldCallCtx = CallContext.SetLogicalCallContext(null);
// Call helper method here, to avoid confusion with stack frames & app domains
MemoryStream retStm = null;
byte[] responseBytes = null;
SmuggledMethodReturnMessage smuggledMrm;
try
{
if (smuggledMcm != null)
responseBytes = DoTransitionDispatch(null, smuggledMcm, out smuggledMrm);
else
responseBytes = DoTransitionDispatch(reqStm.GetBuffer(), null, out smuggledMrm);
}
finally
{
CallContext.SetLogicalCallContext(oldCallCtx);
}
if (smuggledMrm != null)
{
ArrayList deserializedArgs = smuggledMrm.FixupForNewAppDomain();
desRetMsg = new MethodResponse((IMethodCallMessage)reqMsg,
smuggledMrm,
deserializedArgs);
}
else
{
if (responseBytes != null) {
retStm = new MemoryStream(responseBytes);
Message.DebugOut("::::::::::::::::::::::::::: CrossAppDomain Channel: Sync call returning!!\n");
//*********************** DESERIALIZE RET-MSG **************
desRetMsg = CrossAppDomainSerializer.DeserializeMessage(retStm, reqMsg as IMethodCallMessage);
}
}
}
catch(Exception e)
{
Message.DebugOut("Arrgh.. XAppDomainSink::throwing exception " + e + "\n");
try
{
desRetMsg = new ReturnMessage(e, (reqMsg as IMethodCallMessage));
}
catch(Exception )
{
// Fatal Error .. can't do much here
}
}
// restore the principal if necessary.
if (currentPrincipal != null)
{
IMethodReturnMessage mrmRetMsg = desRetMsg as IMethodReturnMessage;
if (mrmRetMsg != null)
{
LogicalCallContext lcc = mrmRetMsg.LogicalCallContext;
lcc.Principal = currentPrincipal;
}
}
return desRetMsg;
}