We need you! We're working hard on the next version of Developer Fusion -
Let us know what you think we should be up to!
- namespace System.Runtime.Remoting.Channels
- {
- using System;
- using System.Collections;
- using System.IO;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Remoting;
- using System.Runtime.Remoting.Activation;
- using System.Runtime.Remoting.Messaging;
- using System.Runtime.Remoting.Metadata;
- using System.Runtime.Remoting.Proxies;
- using System.Threading;
- using System.Security.Permissions;
- using System.Globalization;
-
-
-
- [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
- internal struct Perf_Contexts
- {
- internal int cRemoteCalls;
- internal int cChannels;
- }
-
- [System.Runtime.InteropServices.ComVisible(true)]
- public sealed class ChannelServices
- {
-
- private static object[] s_currentChannelData = null;
-
- static internal object[] CurrentChannelData {
- get {
- if (s_currentChannelData == null)
- RefreshChannelData();
-
- return s_currentChannelData;
- }
- }
-
-
-
- private ChannelServices()
- {
- }
-
-
- private static object s_channelLock = new object();
- private static RegisteredChannelList s_registeredChannels = new RegisteredChannelList();
-
-
-
-
-
-
-
- private static long remoteCalls {
- get { return Thread.GetDomain().RemotingData.ChannelServicesData.remoteCalls; }
- set { Thread.GetDomain().RemotingData.ChannelServicesData.remoteCalls = value; }
- }
-
- private static IMessageSink xCtxChannel;
-
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe static extern Perf_Contexts* GetPrivateContextsPerfCounters();
-
- unsafe private static Perf_Contexts* perf_Contexts = GetPrivateContextsPerfCounters();
-
-
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
- public static void RegisterChannel(IChannel chnl, bool ensureSecurity)
- {
- RegisterChannelInternal(chnl, ensureSecurity);
- }
-
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
- [Obsolete("Use System.Runtime.Remoting.ChannelServices.RegisterChannel(IChannel chnl, bool ensureSecurity) instead.", false)]
- public static void RegisterChannel(IChannel chnl)
- {
- RegisterChannelInternal(chnl, false);
- }
-
-
- static bool unloadHandlerRegistered = false;
- unsafe static internal void RegisterChannelInternal(IChannel chnl, bool ensureSecurity)
- {
-
- if (null == chnl) {
- throw new ArgumentNullException("chnl");
- }
-
- bool fLocked = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- Monitor.ReliableEnter(s_channelLock, ref fLocked);
- string chnlName = chnl.ChannelName;
-
- RegisteredChannelList regChnlList = s_registeredChannels;
-
-
- if ((chnlName == null) || (chnlName.Length == 0) || (-1 == regChnlList.FindChannelIndex(chnl.ChannelName))) {
- if (ensureSecurity) {
- ISecurableChannel securableChannel = chnl as ISecurableChannel;
- if (securableChannel != null)
- securableChannel.IsSecured = ensureSecurity;
- else
- throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Channel_CannotBeSecured"), chnl.ChannelName ?? chnl.ToString()));
-
- }
- RegisteredChannel[] oldList = regChnlList.RegisteredChannels;
- RegisteredChannel[] newList = null;
- if (oldList == null) {
- newList = new RegisteredChannel[1];
- }
- else
- newList = new RegisteredChannel[oldList.Length + 1];
-
- if (!unloadHandlerRegistered && !(chnl is CrossAppDomainChannel)) {
-
-
-
- AppDomain.CurrentDomain.DomainUnload += new EventHandler(UnloadHandler);
- unloadHandlerRegistered = true;
- }
-
-
- int priority = chnl.ChannelPriority;
- int current = 0;
-
-
- while (current < oldList.Length) {
- RegisteredChannel oldChannel = oldList[current];
- if (priority > oldChannel.Channel.ChannelPriority) {
- newList[current] = new RegisteredChannel(chnl);
- break;
- }
- else {
- newList[current] = oldChannel;
- current++;
- }
- }
-
- if (current == oldList.Length) {
-
-
- newList[oldList.Length] = new RegisteredChannel(chnl);
- }
- else {
-
- while (current < oldList.Length) {
- newList[current + 1] = oldList[current];
- current++;
- }
- }
-
- if (perf_Contexts != null) {
- perf_Contexts->cChannels++;
- }
-
- s_registeredChannels = new RegisteredChannelList(newList);
- }
- else {
- throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_ChannelNameAlreadyRegistered"), chnl.ChannelName));
- }
-
- RefreshChannelData();
- }
-
- finally {
- if (fLocked) {
- Monitor.Exit(s_channelLock);
- }
- }
- }
-
-
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
- unsafe public static void UnregisterChannel(IChannel chnl)
- {
-
-
-
- bool fLocked = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- Monitor.ReliableEnter(s_channelLock, ref fLocked);
- if (chnl != null) {
- RegisteredChannelList regChnlList = s_registeredChannels;
-
-
- int matchingIdx = regChnlList.FindChannelIndex(chnl);
- if (-1 == matchingIdx) {
- throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_ChannelNotRegistered"), chnl.ChannelName));
- }
-
- RegisteredChannel[] oldList = regChnlList.RegisteredChannels;
- RegisteredChannel[] newList = null;
- BCLDebug.Assert((oldList != null) && (oldList.Length != 0), "channel list should not be empty");
-
- newList = new RegisteredChannel[oldList.Length - 1];
-
-
- IChannelReceiver srvChannel = chnl as IChannelReceiver;
- if (srvChannel != null)
- srvChannel.StopListening(null);
-
- int current = 0;
- int oldPos = 0;
- while (oldPos < oldList.Length) {
- if (oldPos == matchingIdx) {
- oldPos++;
- }
- else {
- newList[current] = oldList[oldPos];
- current++;
- oldPos++;
- }
- }
-
- if (perf_Contexts != null) {
- perf_Contexts->cChannels--;
- }
-
- s_registeredChannels = new RegisteredChannelList(newList);
- }
-
- RefreshChannelData();
- }
-
- finally {
- if (fLocked) {
- Monitor.Exit(s_channelLock);
- }
- }
- }
-
-
- public static IChannel[] RegisteredChannels {
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
- get {
- RegisteredChannelList regChnlList = s_registeredChannels;
- int count = regChnlList.Count;
-
- if (0 == count) {
- return new IChannel[0];
- }
- else {
-
-
- int visibleChannels = count - 1;
-
-
-
- int co = 0;
- IChannel[] temp = new IChannel[visibleChannels];
- for (int i = 0; i < count; i++) {
- IChannel channel = regChnlList.GetChannel(i);
-
- if (!(channel is CrossAppDomainChannel))
- temp[co++] = channel;
- }
- return temp;
- }
- }
- }
-
- static internal IMessageSink CreateMessageSink(string url, object data, out string objectURI)
- {
- BCLDebug.Trace("REMOTE", "ChannelServices::CreateMessageSink for url " + url + "\n");
- IMessageSink msgSink = null;
- objectURI = null;
-
- RegisteredChannelList regChnlList = s_registeredChannels;
- int count = regChnlList.Count;
-
- for (int i = 0; i < count; i++) {
- if (regChnlList.IsSender(i)) {
- IChannelSender chnl = (IChannelSender)regChnlList.GetChannel(i);
- msgSink = chnl.CreateMessageSink(url, data, out objectURI);
-
- if (msgSink != null)
- break;
- }
- }
-
-
-
- if (null == objectURI) {
- objectURI = url;
- }
-
- return msgSink;
- }
-
- static internal IMessageSink CreateMessageSink(object data)
- {
- string objectUri;
- return CreateMessageSink(null, data, out objectUri);
- }
-
-
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
- public static IChannel GetChannel(string name)
- {
- RegisteredChannelList regChnlList = s_registeredChannels;
-
- int matchingIdx = regChnlList.FindChannelIndex(name);
- if (0 <= matchingIdx) {
- IChannel channel = regChnlList.GetChannel(matchingIdx);
- if ((channel is CrossAppDomainChannel) || (channel is CrossContextChannel))
- return null;
- else
- return channel;
- }
- else {
- return null;
- }
- }
-
-
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
- public static string[] GetUrlsForObject(MarshalByRefObject obj)
- {
- if (null == obj) {
- return null;
- }
-
- RegisteredChannelList regChnlList = s_registeredChannels;
- int count = regChnlList.Count;
-
- Hashtable table = new Hashtable();
- bool fServer;
- Identity id = MarshalByRefObject.GetIdentity(obj, out fServer);
-
- if (null != id) {
- string uri = id.ObjURI;
-
- if (null != uri) {
- for (int i = 0; i < count; i++) {
- if (regChnlList.IsReceiver(i)) {
- try {
- string[] urls = ((IChannelReceiver)regChnlList.GetChannel(i)).GetUrlsForUri(uri);
-
- for (int j = 0; j < urls.Length; j++) {
- table.Add(urls[j], urls[j]);
- }
- }
- catch (NotSupportedException) {
-
-
- }
- }
- }
- }
- }
-
-
- ICollection keys = table.Keys;
- string[] urlList = new string[keys.Count];
- int co = 0;
- foreach (string key in keys) {
- urlList[co++] = key;
- }
- return urlList;
- }
-
-
- static internal IMessageSink GetChannelSinkForProxy(object obj)
- {
- IMessageSink sink = null;
- if (RemotingServices.IsTransparentProxy(obj)) {
- RealProxy rp = RemotingServices.GetRealProxy(obj);
- RemotingProxy remProxy = rp as RemotingProxy;
- if (null != remProxy) {
- Identity idObj = remProxy.IdentityObject;
- BCLDebug.Assert(null != idObj, "null != idObj");
- sink = idObj.ChannelSink;
- }
- }
-
- return sink;
- }
-
-
-
-
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
- public static IDictionary GetChannelSinkProperties(object obj)
- {
- IMessageSink sink = GetChannelSinkForProxy(obj);
- IClientChannelSink chnlSink = sink as IClientChannelSink;
- if (null != chnlSink) {
-
-
- ArrayList dictionaries = new ArrayList();
-
- do {
- IDictionary dict = chnlSink.Properties;
- if (dict != null)
- dictionaries.Add(dict);
-
- chnlSink = chnlSink.NextChannelSink;
- }
- while (chnlSink != null);
-
- return new AggregateDictionary(dictionaries);
- }
- else {
- IDictionary dict = sink as IDictionary;
- if (null != dict) {
- return dict;
- }
- else {
- return null;
- }
- }
- }
-
-
- static internal IMessageSink GetCrossContextChannelSink()
- {
- if (null == xCtxChannel) {
- xCtxChannel = CrossContextChannel.MessageSink;
- }
-
- return xCtxChannel;
- }
-
-
- #if DEBUG
-
-
- static internal long GetNumberOfRemoteCalls()
- {
- return remoteCalls;
- }
-
- #endif //DEBUG
- unsafe static internal void IncrementRemoteCalls(long cCalls)
- {
- remoteCalls += cCalls;
- if (perf_Contexts != null)
- perf_Contexts->cRemoteCalls += (int)cCalls;
- }
-
- static internal void IncrementRemoteCalls()
- {
- IncrementRemoteCalls(1);
- }
-
-
- static internal void RefreshChannelData()
- {
- bool fLocked = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- Monitor.ReliableEnter(s_channelLock, ref fLocked);
- s_currentChannelData = CollectChannelDataFromChannels();
- }
- finally {
- if (fLocked) {
- Monitor.Exit(s_channelLock);
- }
- }
- }
-
- private static object[] CollectChannelDataFromChannels()
- {
-
-
- RemotingServices.RegisterWellKnownChannels();
-
- RegisteredChannelList regChnlList = s_registeredChannels;
- int count = regChnlList.Count;
-
-
- int numChnls = regChnlList.ReceiverCount;
-
-
- object[] data = new object[numChnls];
-
-
- int nonNullDataCount = 0;
-
-
- for (int i = 0int j = 0; i < count; i++) {
-
- IChannel chnl = regChnlList.GetChannel(i);
-
- if (null == chnl) {
- throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_ChannelNotRegistered"), ""));
- }
-
- if (regChnlList.IsReceiver(i)) {
- BCLDebug.Trace("REMOTE", "Setting info for receiver " + j + "\n");
-
- object channelData = ((IChannelReceiver)chnl).ChannelData;
- data[j] = channelData;
- if (channelData != null)
- nonNullDataCount++;
-
-
- j++;
- }
- }
-
- if (nonNullDataCount != numChnls) {
-
- object[] nonNullData = new object[nonNullDataCount];
- int nonNullCounter = 0;
- for (int co = 0; co < numChnls; co++) {
- object channelData = data[co];
- if (channelData != null)
- nonNullData[nonNullCounter++] = channelData;
- }
-
- data = nonNullData;
- }
-
- return data;
- }
-
-
- static bool IsMethodReallyPublic(MethodInfo mi)
- {
- if (!mi.IsPublic || mi.IsStatic)
- return false;
-
- if (!mi.IsGenericMethod)
- return true;
-
- foreach (Type t in mi.GetGenericArguments())
- if (!t.IsVisible)
- return false;
-
- return true;
- }
-
-
-
-
-
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
- public static ServerProcessing DispatchMessage(IServerChannelSinkStack sinkStack, IMessage msg, out IMessage replyMsg)
- {
- ServerProcessing processing = ServerProcessing.Complete;
- replyMsg = null;
-
- try {
- if (null == msg) {
- throw new ArgumentNullException("msg");
- }
-
- BCLDebug.Trace("REMOTE", "Dispatching for URI " + InternalSink.GetURI(msg));
-
-
-
-
-
-
-
- IncrementRemoteCalls();
-
-
-
- ServerIdentity srvId = CheckDisconnectedOrCreateWellKnownObject(msg);
-
-
-
-
- if (srvId.ServerType == typeof(System.AppDomain)) {
- throw new RemotingException(Environment.GetResourceString("Remoting_AppDomainsCantBeCalledRemotely"));
- }
-
-
- IMethodCallMessage mcm = msg as IMethodCallMessage;
-
- if (mcm == null) {
-
-
-
- if (!typeof(IMessageSink).IsAssignableFrom(srvId.ServerType)) {
- throw new RemotingException(Environment.GetResourceString("Remoting_AppDomainsCantBeCalledRemotely"));
- }
-
- processing = ServerProcessing.Complete;
- replyMsg = ChannelServices.GetCrossContextChannelSink().SyncProcessMessage(msg);
- }
- else {
-
-
-
-
- MethodInfo method = (MethodInfo)mcm.MethodBase;
-
-
-
-
- if (!IsMethodReallyPublic(method) && !RemotingServices.IsMethodAllowedRemotely(method)) {
- throw new RemotingException(Environment.GetResourceString("Remoting_NonPublicOrStaticCantBeCalledRemotely"));
- }
-
- RemotingMethodCachedData cache = (RemotingMethodCachedData)InternalRemotingServices.GetReflectionCachedData(method);
-
-
-
- if (RemotingServices.IsOneWay(method)) {
- processing = ServerProcessing.OneWay;
- ChannelServices.GetCrossContextChannelSink().AsyncProcessMessage(msg, null);
- }
- else {
-
- processing = ServerProcessing.Complete;
- if (!srvId.ServerType.IsContextful) {
- object[] args = new object[] {msg, srvId.ServerContext};
- replyMsg = (IMessage)CrossContextChannel.SyncProcessMessageCallback(args);
- }
- else
- replyMsg = ChannelServices.GetCrossContextChannelSink().SyncProcessMessage(msg);
- }
- }
-
- }
- catch (Exception e) {
- if (processing != ServerProcessing.OneWay) {
- try {
- IMethodCallMessage mcm = (IMethodCallMessage)((msg != null) ? msg : new ErrorMessage());
- replyMsg = (IMessage)new ReturnMessage(e, mcm);
- if (msg != null) {
- ((ReturnMessage)replyMsg).SetLogicalCallContext((LogicalCallContext)msg.Properties[Message.CallContextKey]);
- }
- }
- catch (Exception) {
-
- }
- }
- }
-
- return processing;
- }
-
-
-
-
-
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
- public static IMessage SyncDispatchMessage(IMessage msg)
- {
- IMessage msgRet = null;
- bool fIsOneWay = false;
-
- try {
- if (null == msg) {
- throw new ArgumentNullException("msg");
- }
-
-
-
-
-
- IncrementRemoteCalls();
-
- if (!(msg is TransitionCall)) {
-
-