Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Runtime / Remoting / Configuration.cs / 1305376 / Configuration.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** File: Configuration.cs ** ** ** Purpose: Classes used for reading and storing configuration ** ** ===========================================================*/ namespace System.Runtime.Remoting { using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Lifetime; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Metadata; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Threading; using System.IO; using System.Security; using System.Security.Permissions; using System.Collections; using System.Reflection; using System.Globalization; using System.Runtime.Versioning; using System.Diagnostics.Contracts; [Serializable] [System.Runtime.InteropServices.ComVisible(true)] public enum WellKnownObjectMode { Singleton = 1, SingleCall = 2 } // This is the class that plays the role of per-appDomain statics // till we have the real functionality. internal class DomainSpecificRemotingData { const int ACTIVATION_INITIALIZING = 0x00000001; const int ACTIVATION_INITIALIZED = 0x00000002; const int ACTIVATOR_LISTENING = 0x00000004; [System.Security.SecurityCritical /*auto-generated*/] LocalActivator _LocalActivator; ActivationListener _ActivationListener; IContextProperty[] _appDomainProperties; int _flags; Object _ConfigLock; ChannelServicesData _ChannelServicesData; LeaseManager _LeaseManager; ReaderWriterLock _IDTableLock; internal DomainSpecificRemotingData() { _flags = 0; _ConfigLock = new Object(); _ChannelServicesData = new ChannelServicesData(); _IDTableLock = new ReaderWriterLock(); // Add the Lifetime service property to the appdomain. // For now we are assuming that this is the only property // If there are more properties, then an existing array // will need to be expanded to add this property // The property needs to be added here so that the default context // for an appdomain has lifetime services activated _appDomainProperties = new IContextProperty[1]; _appDomainProperties[0] = new System.Runtime.Remoting.Lifetime.LeaseLifeTimeServiceProperty(); } internal LeaseManager LeaseManager { get { return _LeaseManager; } set { _LeaseManager = value; } } // This lock object is exposed for various objects that need to synchronize // there configuration behavior. internal Object ConfigLock { get { return _ConfigLock; } } // This is the rwlock used by the uri table functions internal ReaderWriterLock IDTableLock { get { return _IDTableLock; } } internal LocalActivator LocalActivator { [System.Security.SecurityCritical] // auto-generated get{return _LocalActivator;} [System.Security.SecurityCritical] // auto-generated set{_LocalActivator=value;} } internal ActivationListener ActivationListener { get {return _ActivationListener;} set {_ActivationListener=value;} } // access to InitializingActivation, ActivationInitialized // and ActivatorListening should be guarded by ConfigLock // by the caller. internal bool InitializingActivation { get {return (_flags & ACTIVATION_INITIALIZING) == ACTIVATION_INITIALIZING;} set { if (value == true) { _flags = _flags | ACTIVATION_INITIALIZING; } else { _flags = _flags & ~ACTIVATION_INITIALIZING; } } } internal bool ActivationInitialized { get {return (_flags & ACTIVATION_INITIALIZED) == ACTIVATION_INITIALIZED;} set { if (value == true) { _flags = _flags | ACTIVATION_INITIALIZED; } else { _flags = _flags & ~ACTIVATION_INITIALIZED; } } } internal bool ActivatorListening { get {return (_flags & ACTIVATOR_LISTENING) == ACTIVATOR_LISTENING;} set { if (value == true) { _flags = _flags | ACTIVATOR_LISTENING; } else { _flags = _flags & ~ACTIVATOR_LISTENING; } } } internal IContextProperty[] AppDomainContextProperties { get { return _appDomainProperties; } } internal ChannelServicesData ChannelServicesData { get { return _ChannelServicesData; } } } // class DomainSpecificRemotingData //----------------------------------------------------------------- //--------------------- Remoting Configuration --------------------- //----------------------------------------------------------------- internal static class RemotingConfigHandler { static String _applicationName; static CustomErrorsModes _errorMode = CustomErrorsModes.RemoteOnly; static bool _errorsModeSet = false; static bool _bMachineConfigLoaded = false; static bool _bUrlObjRefMode = false; static Queue _delayLoadChannelConfigQueue = new Queue(); // queue of channels we might be able to use // All functions of RemotingConfigHandler operate upon the config // data stored on a per appDomain basis public static RemotingConfigInfo Info = new RemotingConfigInfo(); private const String _machineConfigFilename = "machine.config"; internal static String ApplicationName { get { if (_applicationName == null) { throw new RemotingException( Environment.GetResourceString( "Remoting_Config_NoAppName")); } return _applicationName; } set { if (_applicationName != null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_AppNameSet"), _applicationName)); } _applicationName = value; // get rid of any starting or trailing slashes char[] slash = new char[]{'/'}; if (_applicationName.StartsWith("/", StringComparison.Ordinal)) _applicationName = _applicationName.TrimStart(slash); if (_applicationName.EndsWith("/", StringComparison.Ordinal)) _applicationName = _applicationName.TrimEnd(slash); } } internal static bool HasApplicationNameBeenSet() { return _applicationName != null; } internal static bool UrlObjRefMode { get { return _bUrlObjRefMode; } } internal static CustomErrorsModes CustomErrorsMode { get { return _errorMode; } set { if (_errorsModeSet) throw new RemotingException(Environment.GetResourceString("Remoting_Config_ErrorsModeSet")); _errorsModeSet = true; _errorMode = value; } } [System.Security.SecurityCritical] // auto-generated internal static IMessageSink FindDelayLoadChannelForCreateMessageSink( String url, Object data, out String objectURI) { LoadMachineConfigIfNecessary(); objectURI = null; IMessageSink msgSink = null; foreach (DelayLoadClientChannelEntry entry in _delayLoadChannelConfigQueue) { IChannelSender channel = entry.Channel; // if the channel is null, that means it has already been registered. if (channel != null) { msgSink = channel.CreateMessageSink(url, data, out objectURI); if (msgSink != null) { entry.RegisterChannel(); return msgSink; } } } return null; } // FindChannelForCreateMessageSink [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] static void LoadMachineConfigIfNecessary() { // Load the machine.config file if we haven't already if (!_bMachineConfigLoaded) { lock (Info) { if (!_bMachineConfigLoaded) { RemotingXmlConfigFileData configData = RemotingXmlConfigFileParser.ParseDefaultConfiguration(); if (configData != null) ConfigureRemoting(configData, false/*ensureSecurity*/); String machineDirectory = System.Security.Util.Config.MachineDirectory; String longFileName = machineDirectory + _machineConfigFilename; new FileIOPermission(FileIOPermissionAccess.Read, longFileName).Assert(); configData = LoadConfigurationFromXmlFile(longFileName); if (configData != null) ConfigureRemoting(configData, false/*ensureSecurity*/); _bMachineConfigLoaded = true; } } } } // LoadMachineConfigIfNecessary [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] internal static void DoConfiguration(String filename, bool ensureSecurity) { LoadMachineConfigIfNecessary(); // load specified config file RemotingXmlConfigFileData configData = LoadConfigurationFromXmlFile(filename); // Configure remoting based on data loaded from the config file. // By design, we do nothing if no remoting config information was // present in the file. if (configData != null) ConfigureRemoting(configData, ensureSecurity); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private static RemotingXmlConfigFileData LoadConfigurationFromXmlFile(String filename) { try { if (filename != null) return RemotingXmlConfigFileParser.ParseConfigFile(filename); else return null; } catch (Exception e) { Exception inner = e.InnerException as FileNotFoundException; if (inner != null) { // if the file is missing, this gives a clearer message e = inner; } throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_ReadFailure"), filename, e)); } } // LoadConfigurationFromXmlFile [System.Security.SecurityCritical] // auto-generated private static void ConfigureRemoting(RemotingXmlConfigFileData configData, bool ensureSecurity) { try { String appName = configData.ApplicationName; if (appName != null) ApplicationName = appName; if (configData.CustomErrors != null) _errorMode = configData.CustomErrors.Mode; // configure channels ConfigureChannels(configData, ensureSecurity); // configure lifetime if (configData.Lifetime != null) { if (configData.Lifetime.IsLeaseTimeSet) LifetimeServices.LeaseTime = configData.Lifetime.LeaseTime; if (configData.Lifetime.IsRenewOnCallTimeSet) LifetimeServices.RenewOnCallTime = configData.Lifetime.RenewOnCallTime; if (configData.Lifetime.IsSponsorshipTimeoutSet) LifetimeServices.SponsorshipTimeout = configData.Lifetime.SponsorshipTimeout; if (configData.Lifetime.IsLeaseManagerPollTimeSet) LifetimeServices.LeaseManagerPollTime = configData.Lifetime.LeaseManagerPollTime; } _bUrlObjRefMode = configData.UrlObjRefMode; // configure other entries Info.StoreRemoteAppEntries(configData); Info.StoreActivatedExports(configData); Info.StoreInteropEntries(configData); Info.StoreWellKnownExports(configData); // start up activation listener if there are any activated objects exposed if (configData.ServerActivatedEntries.Count > 0) ActivationServices.StartListeningForRemoteRequests(); } catch (Exception e) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_ConfigurationFailure"), e)); } } // ConfigureRemoting // configures channels loaded from remoting config file. [System.Security.SecurityCritical] // auto-generated private static void ConfigureChannels(RemotingXmlConfigFileData configData, bool ensureSecurity) { // Register our x-context & x-AD channels first RemotingServices.RegisterWellKnownChannels(); foreach (RemotingXmlConfigFileData.ChannelEntry entry in configData.ChannelEntries) { if (!entry.DelayLoad) { IChannel chnl = CreateChannelFromConfigEntry(entry); ChannelServices.RegisterChannel(chnl, ensureSecurity); } else _delayLoadChannelConfigQueue.Enqueue(new DelayLoadClientChannelEntry(entry, ensureSecurity)); } } // ConfigureChannels [System.Security.SecurityCritical] // auto-generated internal static IChannel CreateChannelFromConfigEntry( RemotingXmlConfigFileData.ChannelEntry entry) { Type type = RemotingConfigInfo.LoadType(entry.TypeName, entry.AssemblyName); bool isServerChannel = typeof(IChannelReceiver).IsAssignableFrom(type); bool isClientChannel = typeof(IChannelSender).IsAssignableFrom(type); IClientChannelSinkProvider clientProviderChain = null; IServerChannelSinkProvider serverProviderChain = null; if (entry.ClientSinkProviders.Count > 0) clientProviderChain = CreateClientChannelSinkProviderChain(entry.ClientSinkProviders); if (entry.ServerSinkProviders.Count > 0) serverProviderChain = CreateServerChannelSinkProviderChain(entry.ServerSinkProviders); // construct argument list Object[] args; if (isServerChannel && isClientChannel) { args = new Object[3]; args[0] = entry.Properties; args[1] = clientProviderChain; args[2] = serverProviderChain; } else if (isServerChannel) { args = new Object[2]; args[0] = entry.Properties; args[1] = serverProviderChain; } else if (isClientChannel) { args = new Object[2]; args[0] = entry.Properties; args[1] = clientProviderChain; } else { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_InvalidChannelType"), type.FullName)); } IChannel channel = null; try { channel = (IChannel)Activator.CreateInstance(type, BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance, null, args, null, null); } catch (MissingMethodException) { String ctor = null; if (isServerChannel && isClientChannel) ctor = "MyChannel(IDictionary properties, IClientChannelSinkProvider clientSinkProvider, IServerChannelSinkProvider serverSinkProvider)"; else if (isServerChannel) ctor = "MyChannel(IDictionary properties, IServerChannelSinkProvider serverSinkProvider)"; else if (isClientChannel) ctor = "MyChannel(IDictionary properties, IClientChannelSinkProvider clientSinkProvider)"; throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_ChannelMissingCtor"), type.FullName, ctor)); } return channel; } // CreateChannelFromEntry // create a client sink provider chain [System.Security.SecurityCritical] // auto-generated private static IClientChannelSinkProvider CreateClientChannelSinkProviderChain(ArrayList entries) { IClientChannelSinkProvider chain = null; IClientChannelSinkProvider current = null; foreach (RemotingXmlConfigFileData.SinkProviderEntry entry in entries) { if (chain == null) { chain = (IClientChannelSinkProvider)CreateChannelSinkProvider(entry, false); current = chain; } else { current.Next = (IClientChannelSinkProvider)CreateChannelSinkProvider(entry, false); current = current.Next; } } return chain; } // CreateClientChannelSinkProviderChain // create a client sink provider chain [System.Security.SecurityCritical] // auto-generated private static IServerChannelSinkProvider CreateServerChannelSinkProviderChain(ArrayList entries) { IServerChannelSinkProvider chain = null; IServerChannelSinkProvider current = null; foreach (RemotingXmlConfigFileData.SinkProviderEntry entry in entries) { if (chain == null) { chain = (IServerChannelSinkProvider)CreateChannelSinkProvider(entry, true); current = chain; } else { current.Next = (IServerChannelSinkProvider)CreateChannelSinkProvider(entry, true); current = current.Next; } } return chain; } // CreateServerChannelSinkProviderChain // create a sink provider from the config file data [System.Security.SecurityCritical] // auto-generated private static Object CreateChannelSinkProvider(RemotingXmlConfigFileData.SinkProviderEntry entry, bool bServer) { Object sinkProvider = null; Type type = RemotingConfigInfo.LoadType(entry.TypeName, entry.AssemblyName); if (bServer) { // make sure this is a client provider if (!typeof(IServerChannelSinkProvider).IsAssignableFrom(type)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_InvalidSinkProviderType"), type.FullName, "IServerChannelSinkProvider")); } } else { // make sure this is a server provider if (!typeof(IClientChannelSinkProvider).IsAssignableFrom(type)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_InvalidSinkProviderType"), type.FullName, "IClientChannelSinkProvider")); } } // check to see if something labelled as a formatter is a formatter if (entry.IsFormatter) { if ((bServer && !typeof(IServerFormatterSinkProvider).IsAssignableFrom(type)) || (!bServer && !typeof(IClientFormatterSinkProvider).IsAssignableFrom(type))) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_SinkProviderNotFormatter"), type.FullName)); } } // setup the argument list and call the constructor Object[] args = new Object[2]; args[0] = entry.Properties; args[1] = entry.ProviderData; try { sinkProvider = Activator.CreateInstance(type, BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance, null, args, null, null); } catch (MissingMethodException) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_SinkProviderMissingCtor"), type.FullName, "MySinkProvider(IDictionary properties, ICollection providerData)")); } return sinkProvider; } // CreateChannelSinkProvider // This is used at the client end to check if an activation needs // to go remote. [System.Security.SecurityCritical] // auto-generated internal static ActivatedClientTypeEntry IsRemotelyActivatedClientType(RuntimeType svrType) { RemotingTypeCachedData cache = (RemotingTypeCachedData) InternalRemotingServices.GetReflectionCachedData(svrType); String assemblyName = cache.SimpleAssemblyName; ActivatedClientTypeEntry entry = Info.QueryRemoteActivate(svrType.FullName, assemblyName); if (entry == null) { // If not found try with the full assembly name String fullAssemblyName = cache.AssemblyName; entry = Info.QueryRemoteActivate(svrType.FullName, fullAssemblyName); if (entry == null){ // If still not found try with partial type name (without namespace) entry = Info.QueryRemoteActivate(svrType.Name, assemblyName); } } return entry; } // IsRemotelyActivatedClientType // This is used at the client end to check if an activation needs // to go remote. internal static ActivatedClientTypeEntry IsRemotelyActivatedClientType(String typeName, String assemblyName) { return Info.QueryRemoteActivate(typeName, assemblyName); } // This is used at the client end to check if a "new Foo" needs to // happen via a Connect() under the covers. [System.Security.SecurityCritical] // auto-generated internal static WellKnownClientTypeEntry IsWellKnownClientType(RuntimeType svrType) { RemotingTypeCachedData cache = (RemotingTypeCachedData) InternalRemotingServices.GetReflectionCachedData(svrType); String assemblyName = cache.SimpleAssemblyName; WellKnownClientTypeEntry wke = Info.QueryConnect(svrType.FullName, assemblyName); if (wke == null) { wke= Info.QueryConnect(svrType.Name, assemblyName); } return wke; } // This is used at the client end to check if a "new Foo" needs to // happen via a Connect() under the covers. internal static WellKnownClientTypeEntry IsWellKnownClientType(String typeName, String assemblyName) { return Info.QueryConnect(typeName, assemblyName); } // // helper functions for processing and parsing data // private static void ParseGenericType(String typeAssem, int indexStart, out String typeName, out String assemName) { int len = typeAssem.Length; int depth = 1; int index = indexStart; while(depth > 0 && (++index < len - 1)) { if (typeAssem[index] == '[') { depth++; } else if (typeAssem[index] == ']') { depth--; } } if (depth > 0 || index >= len) { typeName = null; assemName = null; } else { index = typeAssem.IndexOf(',', index); // comma must be present, and can't be last character if ((index >= 0) && (index < (len - 1))) { typeName = typeAssem.Substring(0, index).Trim(); assemName = typeAssem.Substring(index + 1).Trim(); } else { typeName = null; assemName = null; } } } internal static void ParseType(String typeAssem, out String typeName, out String assemName) { String value = typeAssem; int genericTypeIndex = value.IndexOf("["); if ((genericTypeIndex >= 0) && (genericTypeIndex < (value.Length - 1))) { ParseGenericType(value, genericTypeIndex, out typeName, out assemName); } else { int index = value.IndexOf(","); // comma must be present, and can't be last character if ((index >= 0) && (index < (value.Length - 1))) { typeName = value.Substring(0, index).Trim(); assemName = value.Substring(index + 1).Trim(); } else { typeName = null; assemName = null; } } } // ParseType // This is used at the server end to check if a type being activated // is explicitly allowed by the server. [System.Security.SecurityCritical] // auto-generated internal static bool IsActivationAllowed(RuntimeType svrType) { if (svrType == null) return false; RemotingTypeCachedData cache = (RemotingTypeCachedData) InternalRemotingServices.GetReflectionCachedData(svrType); String assemblyName = cache.SimpleAssemblyName; return Info.ActivationAllowed(svrType.FullName, assemblyName); } // IsActivationAllowed // This is the flavor that we call from the activation listener // code path. This ensures that we don't load a type before checking // that it is configured for remote activation [System.Security.SecurityCritical] // auto-generated internal static bool IsActivationAllowed(String TypeName) { String svrTypeName = RemotingServices.InternalGetTypeNameFromQualifiedTypeName(TypeName); if (svrTypeName == null) { return false; } String typeName; String asmName; ParseType(svrTypeName, out typeName, out asmName); if (asmName == null) return false; int index = asmName.IndexOf(','); if (index != -1) { // strip off the version info asmName = asmName.Substring(0,index); } return Info.ActivationAllowed(typeName, asmName); } // helper for Configuration::RegisterActivatedServiceType internal static void RegisterActivatedServiceType(ActivatedServiceTypeEntry entry) { Info.AddActivatedType(entry.TypeName, entry.AssemblyName, entry.ContextAttributes); } // RegisterActivatedServiceType // helper for Configuration::RegisterWellKnownServiceType [System.Security.SecurityCritical] // auto-generated internal static void RegisterWellKnownServiceType(WellKnownServiceTypeEntry entry) { BCLDebug.Trace("REMOTE", "Adding well known service type for " + entry.ObjectUri); // < String serverType = entry.TypeName; String asmName = entry.AssemblyName; String URI = entry.ObjectUri; WellKnownObjectMode mode = entry.Mode; lock (Info) { // We make an entry in our config tables so as to keep // both the file-based and programmatic config in [....]. Info.AddWellKnownEntry(entry); } } // RegisterWellKnownServiceType // helper for Configuration::RegisterActivatedClientType internal static void RegisterActivatedClientType(ActivatedClientTypeEntry entry) { Info.AddActivatedClientType(entry); } // helper for Configuration::RegisterWellKnownClientType internal static void RegisterWellKnownClientType(WellKnownClientTypeEntry entry) { Info.AddWellKnownClientType(entry); } //helper for Configuration::GetServerTypeForUri [System.Security.SecurityCritical] // auto-generated internal static Type GetServerTypeForUri(String URI) { URI = Identity.RemoveAppNameOrAppGuidIfNecessary(URI); return Info.GetServerTypeForUri(URI); } // helper for Configuration::GetRegisteredActivatedServiceTypes internal static ActivatedServiceTypeEntry[] GetRegisteredActivatedServiceTypes() { return Info.GetRegisteredActivatedServiceTypes(); } // GetRegisteredActivatedServiceTypes // helper for Configuration::GetRegisteredWellKnownServiceTypes internal static WellKnownServiceTypeEntry[] GetRegisteredWellKnownServiceTypes() { return Info.GetRegisteredWellKnownServiceTypes(); } // GetRegisteredWellKnownServiceTypes // helper for Configuration::GetRegisteredActivatedClientTypes internal static ActivatedClientTypeEntry[] GetRegisteredActivatedClientTypes() { return Info.GetRegisteredActivatedClientTypes(); } // GetRegisteredActivatedClientTypes // helper for Configuration::GetRegisteredWellKnownClientTypes internal static WellKnownClientTypeEntry[] GetRegisteredWellKnownClientTypes() { return Info.GetRegisteredWellKnownClientTypes(); } // GetRegisteredWellKnownClientTypes // helper for creating well known objects on demand [System.Security.SecurityCritical] // auto-generated internal static ServerIdentity CreateWellKnownObject(String uri) { uri = Identity.RemoveAppNameOrAppGuidIfNecessary(uri); return Info.StartupWellKnownObject(uri); } internal class RemotingConfigInfo { Hashtable _exportableClasses; // list of objects that can be client-activated // (this should be a StringTable since we only use the key, // but that type was removed from the BCL :( ) Hashtable _remoteTypeInfo; Hashtable _remoteAppInfo; Hashtable _wellKnownExportInfo; //well known exports indexed by object URI in lower-case static char[] SepSpace = {' '}; static char[] SepPound = {'#'}; static char[] SepSemiColon = {';'}; static char[] SepEquals = {'='}; private static Object s_wkoStartLock = new Object(); private static PermissionSet s_fullTrust = new PermissionSet(PermissionState.Unrestricted); internal RemotingConfigInfo() { // < _remoteTypeInfo = Hashtable.Synchronized(new Hashtable()); _exportableClasses = Hashtable.Synchronized(new Hashtable()); _remoteAppInfo = Hashtable.Synchronized(new Hashtable()); _wellKnownExportInfo = Hashtable.Synchronized(new Hashtable()); } // encodes type name and assembly name into one string for purposes of // indexing in lists and hash tables private String EncodeTypeAndAssemblyNames(String typeName, String assemblyName) { return typeName + ", " + assemblyName.ToLower(CultureInfo.InvariantCulture); } // // XML Configuration Helper Functions // internal void StoreActivatedExports(RemotingXmlConfigFileData configData) { foreach (RemotingXmlConfigFileData.TypeEntry entry in configData.ServerActivatedEntries) { ActivatedServiceTypeEntry aste = new ActivatedServiceTypeEntry(entry.TypeName, entry.AssemblyName); aste.ContextAttributes = CreateContextAttributesFromConfigEntries(entry.ContextAttributes); RemotingConfiguration.RegisterActivatedServiceType(aste); } } // StoreActivatedExports [System.Security.SecurityCritical] // auto-generated internal void StoreInteropEntries(RemotingXmlConfigFileData configData) { // process interop xml element entries foreach (RemotingXmlConfigFileData.InteropXmlElementEntry entry in configData.InteropXmlElementEntries) { Assembly assembly = Assembly.Load(entry.UrtAssemblyName); Type type = assembly.GetType(entry.UrtTypeName); SoapServices.RegisterInteropXmlElement(entry.XmlElementName, entry.XmlElementNamespace, type); } // process interop xml type entries foreach (RemotingXmlConfigFileData.InteropXmlTypeEntry entry in configData.InteropXmlTypeEntries) { Assembly assembly = Assembly.Load(entry.UrtAssemblyName); Type type = assembly.GetType(entry.UrtTypeName); SoapServices.RegisterInteropXmlType(entry.XmlTypeName, entry.XmlTypeNamespace, type); } // process preload entries foreach (RemotingXmlConfigFileData.PreLoadEntry entry in configData.PreLoadEntries) { Assembly assembly = Assembly.Load(entry.AssemblyName); if (entry.TypeName != null) { Type type = assembly.GetType(entry.TypeName); SoapServices.PreLoad(type); } else { SoapServices.PreLoad(assembly); } } } // StoreInteropEntries internal void StoreRemoteAppEntries(RemotingXmlConfigFileData configData) { char[] slash = new char[]{'/'}; // add each remote app to the table foreach (RemotingXmlConfigFileData.RemoteAppEntry remApp in configData.RemoteAppEntries) { // form complete application uri by combining specified uri with app-name // (make sure appUri ends with slash, and that app name doesn't start, // with one. then make sure that the combined form has no trailing slashes). String appUri = remApp.AppUri; if ((appUri != null) && !appUri.EndsWith("/", StringComparison.Ordinal)) appUri = appUri.TrimEnd(slash); // add each client activated type for this remote app foreach (RemotingXmlConfigFileData.TypeEntry cae in remApp.ActivatedObjects) { ActivatedClientTypeEntry acte = new ActivatedClientTypeEntry(cae.TypeName, cae.AssemblyName, appUri); acte.ContextAttributes = CreateContextAttributesFromConfigEntries(cae.ContextAttributes); RemotingConfiguration.RegisterActivatedClientType(acte); } // add each well known object for this remote app foreach (RemotingXmlConfigFileData.ClientWellKnownEntry cwke in remApp.WellKnownObjects) { WellKnownClientTypeEntry wke = new WellKnownClientTypeEntry(cwke.TypeName, cwke.AssemblyName, cwke.Url); wke.ApplicationUrl = appUri; RemotingConfiguration.RegisterWellKnownClientType(wke); } } } // StoreRemoteAppEntries [System.Security.SecurityCritical] // auto-generated internal void StoreWellKnownExports(RemotingXmlConfigFileData configData) { // < foreach (RemotingXmlConfigFileData.ServerWellKnownEntry entry in configData.ServerWellKnownEntries) { WellKnownServiceTypeEntry wke = new WellKnownServiceTypeEntry( entry.TypeName, entry.AssemblyName, entry.ObjectURI, entry.ObjectMode); wke.ContextAttributes = null; // Register the well known entry but do not startup the object RemotingConfigHandler.RegisterWellKnownServiceType(wke); } } // StoreWellKnownExports // helper functions for above configuration helpers static IContextAttribute[] CreateContextAttributesFromConfigEntries(ArrayList contextAttributes) { // create context attribute entry list int numAttrs = contextAttributes.Count; if (numAttrs == 0) return null; IContextAttribute[] attrs = new IContextAttribute[numAttrs]; int co = 0; foreach (RemotingXmlConfigFileData.ContextAttributeEntry cae in contextAttributes) { Assembly asm = Assembly.Load(cae.AssemblyName); IContextAttribute attr = null; Hashtable properties = cae.Properties; if ((properties != null) && (properties.Count > 0)) { Object[] args = new Object[1]; args[0] = properties; // We explicitly allow the ability to create internal // only attributes attr = (IContextAttribute) Activator.CreateInstance( asm.GetType(cae.TypeName, false, false), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, args, null, null); } else { attr = (IContextAttribute) Activator.CreateInstance( asm.GetType(cae.TypeName, false, false), true); } attrs[co++] = attr; } return attrs; } // CreateContextAttributesFromConfigEntries // // end of XML configuration helper functions // internal bool ActivationAllowed(String typeName, String assemblyName) { // the assembly name is stored in lower-case to let it be case-insensitive return _exportableClasses.ContainsKey(EncodeTypeAndAssemblyNames(typeName, assemblyName)); } internal ActivatedClientTypeEntry QueryRemoteActivate(String typeName, String assemblyName) { String index = EncodeTypeAndAssemblyNames(typeName, assemblyName); ActivatedClientTypeEntry typeEntry = _remoteTypeInfo[index] as ActivatedClientTypeEntry; if (typeEntry == null) return null; if (typeEntry.GetRemoteAppEntry() == null) { RemoteAppEntry appEntry = (RemoteAppEntry) _remoteAppInfo[typeEntry.ApplicationUrl]; if (appEntry == null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Activation_MissingRemoteAppEntry"), typeEntry.ApplicationUrl)); } typeEntry.CacheRemoteAppEntry(appEntry); } return typeEntry; } internal WellKnownClientTypeEntry QueryConnect(String typeName, String assemblyName) { String index = EncodeTypeAndAssemblyNames(typeName, assemblyName); WellKnownClientTypeEntry typeEntry = _remoteTypeInfo[index] as WellKnownClientTypeEntry; if (typeEntry == null) return null; return typeEntry; } // // helper functions to retrieve registered types // internal ActivatedServiceTypeEntry[] GetRegisteredActivatedServiceTypes() { ActivatedServiceTypeEntry[] entries = new ActivatedServiceTypeEntry[_exportableClasses.Count]; int co = 0; foreach (DictionaryEntry dictEntry in _exportableClasses) { entries[co++] = (ActivatedServiceTypeEntry)dictEntry.Value; } return entries; } // GetRegisteredActivatedServiceTypes internal WellKnownServiceTypeEntry[] GetRegisteredWellKnownServiceTypes() { WellKnownServiceTypeEntry[] entries = new WellKnownServiceTypeEntry[_wellKnownExportInfo.Count]; int co = 0; foreach (DictionaryEntry dictEntry in _wellKnownExportInfo) { WellKnownServiceTypeEntry entry = (WellKnownServiceTypeEntry)dictEntry.Value; WellKnownServiceTypeEntry wkste = new WellKnownServiceTypeEntry( entry.TypeName, entry.AssemblyName, entry.ObjectUri, entry.Mode); wkste.ContextAttributes = entry.ContextAttributes; entries[co++] = wkste; } return entries; } // GetRegisteredWellKnownServiceTypes internal ActivatedClientTypeEntry[] GetRegisteredActivatedClientTypes() { // count number of well known client types int count = 0; foreach (DictionaryEntry dictEntry in _remoteTypeInfo) { ActivatedClientTypeEntry entry = dictEntry.Value as ActivatedClientTypeEntry; if (entry != null) count++; } ActivatedClientTypeEntry[] entries = new ActivatedClientTypeEntry[count]; int co = 0; foreach (DictionaryEntry dictEntry in _remoteTypeInfo) { ActivatedClientTypeEntry entry = dictEntry.Value as ActivatedClientTypeEntry; if (entry != null) { // retrieve application url String appUrl = null; RemoteAppEntry remApp = entry.GetRemoteAppEntry(); if (remApp != null) appUrl = remApp.GetAppURI(); ActivatedClientTypeEntry wkcte = new ActivatedClientTypeEntry(entry.TypeName, entry.AssemblyName, appUrl); // Fetch the context attributes wkcte.ContextAttributes = entry.ContextAttributes; entries[co++] = wkcte; } } return entries; } // GetRegisteredActivatedClientTypes internal WellKnownClientTypeEntry[] GetRegisteredWellKnownClientTypes() { // count number of well known client types int count = 0; foreach (DictionaryEntry dictEntry in _remoteTypeInfo) { WellKnownClientTypeEntry entry = dictEntry.Value as WellKnownClientTypeEntry; if (entry != null) count++; } WellKnownClientTypeEntry[] entries = new WellKnownClientTypeEntry[count]; int co = 0; foreach (DictionaryEntry dictEntry in _remoteTypeInfo) { WellKnownClientTypeEntry entry = dictEntry.Value as WellKnownClientTypeEntry; if (entry != null) { WellKnownClientTypeEntry wkcte = new WellKnownClientTypeEntry(entry.TypeName, entry.AssemblyName, entry.ObjectUrl); // see if there is an associated app RemoteAppEntry remApp = entry.GetRemoteAppEntry(); if (remApp != null) wkcte.ApplicationUrl = remApp.GetAppURI(); entries[co++] = wkcte; } } return entries; } // GetRegisteredWellKnownClientTypes // // end of helper functions to retrieve registered types // internal void AddActivatedType(String typeName, String assemblyName, IContextAttribute[] contextAttributes) { if (typeName == null) throw new ArgumentNullException("typeName"); if (assemblyName == null) throw new ArgumentNullException("assemblyName"); Contract.EndContractBlock(); if (CheckForRedirectedClientType(typeName, assemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_CantUseRedirectedTypeForWellKnownService"), typeName, assemblyName)); } ActivatedServiceTypeEntry aste = new ActivatedServiceTypeEntry(typeName, assemblyName); aste.ContextAttributes = contextAttributes; // The assembly name is stored in lowercase to let it be case-insensitive. String key = EncodeTypeAndAssemblyNames(typeName, assemblyName); _exportableClasses.Add(key, aste); } // AddActivatedType // determines if either a wellknown or activated service type entry // is associated with the given type name and assembly name private bool CheckForServiceEntryWithType(String typeName, String asmName) { return CheckForWellKnownServiceEntryWithType(typeName, asmName) || ActivationAllowed(typeName, asmName); } // CheckForServiceEntryWithType private bool CheckForWellKnownServiceEntryWithType(String typeName, String asmName) { foreach (DictionaryEntry entry in _wellKnownExportInfo) { WellKnownServiceTypeEntry svc = (WellKnownServiceTypeEntry)entry.Value; if (typeName == svc.TypeName) { bool match = false; // need to ignore version while checking if (asmName == svc.AssemblyName) match = true; else { // only well known service entry can have version info if (String.Compare(svc.AssemblyName, 0, asmName, 0, asmName.Length, StringComparison.OrdinalIgnoreCase) == 0) { // if asmName != svc.AssemblyName and svc.AssemblyName // starts with asmName we know that svc.AssemblyName is // longer. If the next character is a comma, then the // assembly names match except for version numbers // which is ok. if (svc.AssemblyName[asmName.Length] == ',') match = true; } } // We were trying to redirect if (match) return true; } } return false; } // CheckForWellKnownServiceEntryOfType // returns true if activation for the type has been redirected. private bool CheckForRedirectedClientType(String typeName, String asmName) { // if asmName has version information, remove it. int index = asmName.IndexOf(","); if (index != -1) asmName = asmName.Substring(0, index); return (QueryRemoteActivate(typeName, asmName) != null) || (QueryConnect(typeName, asmName) != null); } // CheckForRedirectedClientType internal void AddActivatedClientType(ActivatedClientTypeEntry entry) { if (CheckForRedirectedClientType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_TypeAlreadyRedirected"), entry.TypeName, entry.AssemblyName)); } if (CheckForServiceEntryWithType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_CantRedirectActivationOfWellKnownService"), entry.TypeName, entry.AssemblyName)); } String appUrl = entry.ApplicationUrl; RemoteAppEntry appEntry = (RemoteAppEntry)_remoteAppInfo[appUrl]; if (appEntry == null) { appEntry = new RemoteAppEntry(appUrl, appUrl); _remoteAppInfo.Add(appUrl, appEntry); } if (appEntry != null) { entry.CacheRemoteAppEntry(appEntry); } String index = EncodeTypeAndAssemblyNames(entry.TypeName, entry.AssemblyName); _remoteTypeInfo.Add(index, entry); } // AddActivatedClientType internal void AddWellKnownClientType(WellKnownClientTypeEntry entry) { if (CheckForRedirectedClientType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_TypeAlreadyRedirected"), entry.TypeName, entry.AssemblyName)); } if (CheckForServiceEntryWithType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_CantRedirectActivationOfWellKnownService"), entry.TypeName, entry.AssemblyName)); } String appUrl = entry.ApplicationUrl; RemoteAppEntry appEntry = null; if (appUrl != null) { appEntry = (RemoteAppEntry)_remoteAppInfo[appUrl]; if (appEntry == null) { appEntry = new RemoteAppEntry(appUrl, appUrl); _remoteAppInfo.Add(appUrl, appEntry); } } if (appEntry != null) entry.CacheRemoteAppEntry(appEntry); String index = EncodeTypeAndAssemblyNames(entry.TypeName, entry.AssemblyName); _remoteTypeInfo.Add(index, entry); } // AddWellKnownClientType // This is to add programmatically registered well known objects // so that we keep all this data in one place [System.Security.SecurityCritical] // auto-generated internal void AddWellKnownEntry(WellKnownServiceTypeEntry entry) { AddWellKnownEntry(entry, true); } [System.Security.SecurityCritical] // auto-generated internal void AddWellKnownEntry(WellKnownServiceTypeEntry entry, bool fReplace) { if (CheckForRedirectedClientType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_CantUseRedirectedTypeForWellKnownService"), entry.TypeName, entry.AssemblyName)); } String key = entry.ObjectUri.ToLower(CultureInfo.InvariantCulture); if (fReplace) { // Registering a well known object twice replaces the old one, so // we null out the old entry in the identity table after adding // this one. The identity will be recreated the next time someone // asks for this object. _wellKnownExportInfo[key] = entry; IdentityHolder.RemoveIdentity(entry.ObjectUri); } else { _wellKnownExportInfo.Add(key, entry); } } //This API exposes a way to get server type information wiihout booting the object [System.Security.SecurityCritical] // auto-generated internal Type GetServerTypeForUri(String URI) { Contract.Assert(null != URI, "null != URI"); Type serverType = null; String uriLower = URI.ToLower(CultureInfo.InvariantCulture); WellKnownServiceTypeEntry entry = (WellKnownServiceTypeEntry)_wellKnownExportInfo[uriLower]; if(entry != null) { serverType = LoadType(entry.TypeName, entry.AssemblyName); } return serverType; } [System.Security.SecurityCritical] // auto-generated internal ServerIdentity StartupWellKnownObject(String URI) { Contract.Assert(null != URI, "null != URI"); String uriLower = URI.ToLower(CultureInfo.InvariantCulture); ServerIdentity ident = null; WellKnownServiceTypeEntry entry = (WellKnownServiceTypeEntry)_wellKnownExportInfo[uriLower]; if (entry != null) { ident = StartupWellKnownObject( entry.AssemblyName, entry.TypeName, entry.ObjectUri, entry.Mode); } return ident; } [System.Security.SecurityCritical] // auto-generated internal ServerIdentity StartupWellKnownObject( String asmName, String svrTypeName, String URI, WellKnownObjectMode mode) { return StartupWellKnownObject(asmName, svrTypeName, URI, mode, false); } [System.Security.SecurityCritical] // auto-generated internal ServerIdentity StartupWellKnownObject( String asmName, String svrTypeName, String URI, WellKnownObjectMode mode, bool fReplace) { lock (s_wkoStartLock) { MarshalByRefObject obj = null; ServerIdentity srvID = null; // attempt to load the type Type serverType = LoadType(svrTypeName, asmName); // make sure the well known object derives from MarshalByRefObject if(!serverType.IsMarshalByRef) { throw new RemotingException( Environment.GetResourceString("Remoting_WellKnown_MustBeMBR", svrTypeName)); } // make sure that no one beat us to creating // the well known object srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI); if ((srvID != null) && srvID.IsRemoteDisconnected()) { IdentityHolder.RemoveIdentity(URI); srvID = null; } if (srvID == null) { //WellKnown type instances need to be created under full trust //since the permission set might have been restricted by the channel //pipeline. //This assert is protected by Infrastructure link demands. s_fullTrust.Assert(); try { obj = (MarshalByRefObject)Activator.CreateInstance(serverType, true); if (RemotingServices.IsClientProxy(obj)) { // The wellknown type is remoted so we must wrap the proxy // with a local object. // The redirection proxy masquerades as an object of the appropriate // type, and forwards incoming messages to the actual proxy. RedirectionProxy redirectedProxy = new RedirectionProxy(obj, serverType); redirectedProxy.ObjectMode = mode; RemotingServices.MarshalInternal(redirectedProxy, URI, serverType); srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI); Contract.Assert(null != srvID, "null != srvID"); // The redirection proxy handles SingleCall versus Singleton, // so we always set its mode to Singleton. srvID.SetSingletonObjectMode(); } else if (serverType.IsCOMObject && (mode == WellKnownObjectMode.Singleton)) { // Singleton COM objects are wrapped, so that they will be // recreated when an RPC server not available is thrown // if dllhost.exe is killed. ComRedirectionProxy comRedirectedProxy = new ComRedirectionProxy(obj, serverType); RemotingServices.MarshalInternal(comRedirectedProxy, URI, serverType); srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI); Contract.Assert(null != srvID, "null != srvID"); // Only singleton COM objects are redirected this way. srvID.SetSingletonObjectMode(); } else { // make sure the object didn't Marshal itself. String tempUri = RemotingServices.GetObjectUri(obj); if (tempUri != null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_WellKnown_CtorCantMarshal"), URI)); } RemotingServices.MarshalInternal(obj, URI, serverType); srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI); Contract.Assert(null != srvID, "null != srvID"); if (mode == WellKnownObjectMode.SingleCall) { // We need to set a special flag in the serverId // so that every dispatch to this type creates // a new instance of the server object srvID.SetSingleCallObjectMode(); } else { srvID.SetSingletonObjectMode(); } } } catch { throw; } finally { SecurityPermission.RevertAssert(); } } Contract.Assert(null != srvID, "null != srvID"); return srvID; } } // StartupWellKnownObject [System.Security.SecurityCritical] // auto-generated internal static Type LoadType(String typeName, String assemblyName) { Assembly asm = null; // All the LoadType callers have been protected by // Infrastructure LinkDemand, it is safe to assert // this permission. // Assembly.Load demands FileIO when the target // assembly is the same as the executable running. new FileIOPermission(PermissionState.Unrestricted).Assert(); try { asm = Assembly.Load(assemblyName); } finally { CodeAccessPermission.RevertAssert(); } if (asm == null) { throw new RemotingException( Environment.GetResourceString("Remoting_AssemblyLoadFailed", assemblyName)); } Type type = asm.GetType(typeName, false, false); if (type == null) { throw new RemotingException( Environment.GetResourceString("Remoting_BadType", typeName + ", " + assemblyName)); } return type; } // LoadType }// class RemotingConfigInfo } // class RemotingConfigHandler internal class DelayLoadClientChannelEntry { private RemotingXmlConfigFileData.ChannelEntry _entry; private IChannelSender _channel; private bool _bRegistered; private bool _ensureSecurity; internal DelayLoadClientChannelEntry(RemotingXmlConfigFileData.ChannelEntry entry, bool ensureSecurity) { _entry = entry; _channel = null; _bRegistered = false; _ensureSecurity = ensureSecurity; } internal IChannelSender Channel { [System.Security.SecurityCritical] // auto-generated get { // If this method returns null, that means the channel has already been registered. // NOTE: Access to delay load client entries is synchronized at a higher level. if (_channel == null) { if (!_bRegistered) { _channel = (IChannelSender)RemotingConfigHandler.CreateChannelFromConfigEntry(_entry); _entry = null; } } return _channel; } // get } // Channel internal void RegisterChannel() { Contract.Assert(_channel != null, "channel shouldn't be null"); // NOTE: Access to delay load client entries is synchronized at a higher level. ChannelServices.RegisterChannel(_channel, _ensureSecurity); _bRegistered = true; _channel = null; } // RegisterChannel } // class DelayLoadChannelEntry } // namespace // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** File: Configuration.cs ** ** ** Purpose: Classes used for reading and storing configuration ** ** ===========================================================*/ namespace System.Runtime.Remoting { using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Lifetime; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Metadata; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Threading; using System.IO; using System.Security; using System.Security.Permissions; using System.Collections; using System.Reflection; using System.Globalization; using System.Runtime.Versioning; using System.Diagnostics.Contracts; [Serializable] [System.Runtime.InteropServices.ComVisible(true)] public enum WellKnownObjectMode { Singleton = 1, SingleCall = 2 } // This is the class that plays the role of per-appDomain statics // till we have the real functionality. internal class DomainSpecificRemotingData { const int ACTIVATION_INITIALIZING = 0x00000001; const int ACTIVATION_INITIALIZED = 0x00000002; const int ACTIVATOR_LISTENING = 0x00000004; [System.Security.SecurityCritical /*auto-generated*/] LocalActivator _LocalActivator; ActivationListener _ActivationListener; IContextProperty[] _appDomainProperties; int _flags; Object _ConfigLock; ChannelServicesData _ChannelServicesData; LeaseManager _LeaseManager; ReaderWriterLock _IDTableLock; internal DomainSpecificRemotingData() { _flags = 0; _ConfigLock = new Object(); _ChannelServicesData = new ChannelServicesData(); _IDTableLock = new ReaderWriterLock(); // Add the Lifetime service property to the appdomain. // For now we are assuming that this is the only property // If there are more properties, then an existing array // will need to be expanded to add this property // The property needs to be added here so that the default context // for an appdomain has lifetime services activated _appDomainProperties = new IContextProperty[1]; _appDomainProperties[0] = new System.Runtime.Remoting.Lifetime.LeaseLifeTimeServiceProperty(); } internal LeaseManager LeaseManager { get { return _LeaseManager; } set { _LeaseManager = value; } } // This lock object is exposed for various objects that need to synchronize // there configuration behavior. internal Object ConfigLock { get { return _ConfigLock; } } // This is the rwlock used by the uri table functions internal ReaderWriterLock IDTableLock { get { return _IDTableLock; } } internal LocalActivator LocalActivator { [System.Security.SecurityCritical] // auto-generated get{return _LocalActivator;} [System.Security.SecurityCritical] // auto-generated set{_LocalActivator=value;} } internal ActivationListener ActivationListener { get {return _ActivationListener;} set {_ActivationListener=value;} } // access to InitializingActivation, ActivationInitialized // and ActivatorListening should be guarded by ConfigLock // by the caller. internal bool InitializingActivation { get {return (_flags & ACTIVATION_INITIALIZING) == ACTIVATION_INITIALIZING;} set { if (value == true) { _flags = _flags | ACTIVATION_INITIALIZING; } else { _flags = _flags & ~ACTIVATION_INITIALIZING; } } } internal bool ActivationInitialized { get {return (_flags & ACTIVATION_INITIALIZED) == ACTIVATION_INITIALIZED;} set { if (value == true) { _flags = _flags | ACTIVATION_INITIALIZED; } else { _flags = _flags & ~ACTIVATION_INITIALIZED; } } } internal bool ActivatorListening { get {return (_flags & ACTIVATOR_LISTENING) == ACTIVATOR_LISTENING;} set { if (value == true) { _flags = _flags | ACTIVATOR_LISTENING; } else { _flags = _flags & ~ACTIVATOR_LISTENING; } } } internal IContextProperty[] AppDomainContextProperties { get { return _appDomainProperties; } } internal ChannelServicesData ChannelServicesData { get { return _ChannelServicesData; } } } // class DomainSpecificRemotingData //----------------------------------------------------------------- //--------------------- Remoting Configuration --------------------- //----------------------------------------------------------------- internal static class RemotingConfigHandler { static String _applicationName; static CustomErrorsModes _errorMode = CustomErrorsModes.RemoteOnly; static bool _errorsModeSet = false; static bool _bMachineConfigLoaded = false; static bool _bUrlObjRefMode = false; static Queue _delayLoadChannelConfigQueue = new Queue(); // queue of channels we might be able to use // All functions of RemotingConfigHandler operate upon the config // data stored on a per appDomain basis public static RemotingConfigInfo Info = new RemotingConfigInfo(); private const String _machineConfigFilename = "machine.config"; internal static String ApplicationName { get { if (_applicationName == null) { throw new RemotingException( Environment.GetResourceString( "Remoting_Config_NoAppName")); } return _applicationName; } set { if (_applicationName != null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_AppNameSet"), _applicationName)); } _applicationName = value; // get rid of any starting or trailing slashes char[] slash = new char[]{'/'}; if (_applicationName.StartsWith("/", StringComparison.Ordinal)) _applicationName = _applicationName.TrimStart(slash); if (_applicationName.EndsWith("/", StringComparison.Ordinal)) _applicationName = _applicationName.TrimEnd(slash); } } internal static bool HasApplicationNameBeenSet() { return _applicationName != null; } internal static bool UrlObjRefMode { get { return _bUrlObjRefMode; } } internal static CustomErrorsModes CustomErrorsMode { get { return _errorMode; } set { if (_errorsModeSet) throw new RemotingException(Environment.GetResourceString("Remoting_Config_ErrorsModeSet")); _errorsModeSet = true; _errorMode = value; } } [System.Security.SecurityCritical] // auto-generated internal static IMessageSink FindDelayLoadChannelForCreateMessageSink( String url, Object data, out String objectURI) { LoadMachineConfigIfNecessary(); objectURI = null; IMessageSink msgSink = null; foreach (DelayLoadClientChannelEntry entry in _delayLoadChannelConfigQueue) { IChannelSender channel = entry.Channel; // if the channel is null, that means it has already been registered. if (channel != null) { msgSink = channel.CreateMessageSink(url, data, out objectURI); if (msgSink != null) { entry.RegisterChannel(); return msgSink; } } } return null; } // FindChannelForCreateMessageSink [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] static void LoadMachineConfigIfNecessary() { // Load the machine.config file if we haven't already if (!_bMachineConfigLoaded) { lock (Info) { if (!_bMachineConfigLoaded) { RemotingXmlConfigFileData configData = RemotingXmlConfigFileParser.ParseDefaultConfiguration(); if (configData != null) ConfigureRemoting(configData, false/*ensureSecurity*/); String machineDirectory = System.Security.Util.Config.MachineDirectory; String longFileName = machineDirectory + _machineConfigFilename; new FileIOPermission(FileIOPermissionAccess.Read, longFileName).Assert(); configData = LoadConfigurationFromXmlFile(longFileName); if (configData != null) ConfigureRemoting(configData, false/*ensureSecurity*/); _bMachineConfigLoaded = true; } } } } // LoadMachineConfigIfNecessary [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] internal static void DoConfiguration(String filename, bool ensureSecurity) { LoadMachineConfigIfNecessary(); // load specified config file RemotingXmlConfigFileData configData = LoadConfigurationFromXmlFile(filename); // Configure remoting based on data loaded from the config file. // By design, we do nothing if no remoting config information was // present in the file. if (configData != null) ConfigureRemoting(configData, ensureSecurity); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private static RemotingXmlConfigFileData LoadConfigurationFromXmlFile(String filename) { try { if (filename != null) return RemotingXmlConfigFileParser.ParseConfigFile(filename); else return null; } catch (Exception e) { Exception inner = e.InnerException as FileNotFoundException; if (inner != null) { // if the file is missing, this gives a clearer message e = inner; } throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_ReadFailure"), filename, e)); } } // LoadConfigurationFromXmlFile [System.Security.SecurityCritical] // auto-generated private static void ConfigureRemoting(RemotingXmlConfigFileData configData, bool ensureSecurity) { try { String appName = configData.ApplicationName; if (appName != null) ApplicationName = appName; if (configData.CustomErrors != null) _errorMode = configData.CustomErrors.Mode; // configure channels ConfigureChannels(configData, ensureSecurity); // configure lifetime if (configData.Lifetime != null) { if (configData.Lifetime.IsLeaseTimeSet) LifetimeServices.LeaseTime = configData.Lifetime.LeaseTime; if (configData.Lifetime.IsRenewOnCallTimeSet) LifetimeServices.RenewOnCallTime = configData.Lifetime.RenewOnCallTime; if (configData.Lifetime.IsSponsorshipTimeoutSet) LifetimeServices.SponsorshipTimeout = configData.Lifetime.SponsorshipTimeout; if (configData.Lifetime.IsLeaseManagerPollTimeSet) LifetimeServices.LeaseManagerPollTime = configData.Lifetime.LeaseManagerPollTime; } _bUrlObjRefMode = configData.UrlObjRefMode; // configure other entries Info.StoreRemoteAppEntries(configData); Info.StoreActivatedExports(configData); Info.StoreInteropEntries(configData); Info.StoreWellKnownExports(configData); // start up activation listener if there are any activated objects exposed if (configData.ServerActivatedEntries.Count > 0) ActivationServices.StartListeningForRemoteRequests(); } catch (Exception e) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_ConfigurationFailure"), e)); } } // ConfigureRemoting // configures channels loaded from remoting config file. [System.Security.SecurityCritical] // auto-generated private static void ConfigureChannels(RemotingXmlConfigFileData configData, bool ensureSecurity) { // Register our x-context & x-AD channels first RemotingServices.RegisterWellKnownChannels(); foreach (RemotingXmlConfigFileData.ChannelEntry entry in configData.ChannelEntries) { if (!entry.DelayLoad) { IChannel chnl = CreateChannelFromConfigEntry(entry); ChannelServices.RegisterChannel(chnl, ensureSecurity); } else _delayLoadChannelConfigQueue.Enqueue(new DelayLoadClientChannelEntry(entry, ensureSecurity)); } } // ConfigureChannels [System.Security.SecurityCritical] // auto-generated internal static IChannel CreateChannelFromConfigEntry( RemotingXmlConfigFileData.ChannelEntry entry) { Type type = RemotingConfigInfo.LoadType(entry.TypeName, entry.AssemblyName); bool isServerChannel = typeof(IChannelReceiver).IsAssignableFrom(type); bool isClientChannel = typeof(IChannelSender).IsAssignableFrom(type); IClientChannelSinkProvider clientProviderChain = null; IServerChannelSinkProvider serverProviderChain = null; if (entry.ClientSinkProviders.Count > 0) clientProviderChain = CreateClientChannelSinkProviderChain(entry.ClientSinkProviders); if (entry.ServerSinkProviders.Count > 0) serverProviderChain = CreateServerChannelSinkProviderChain(entry.ServerSinkProviders); // construct argument list Object[] args; if (isServerChannel && isClientChannel) { args = new Object[3]; args[0] = entry.Properties; args[1] = clientProviderChain; args[2] = serverProviderChain; } else if (isServerChannel) { args = new Object[2]; args[0] = entry.Properties; args[1] = serverProviderChain; } else if (isClientChannel) { args = new Object[2]; args[0] = entry.Properties; args[1] = clientProviderChain; } else { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_InvalidChannelType"), type.FullName)); } IChannel channel = null; try { channel = (IChannel)Activator.CreateInstance(type, BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance, null, args, null, null); } catch (MissingMethodException) { String ctor = null; if (isServerChannel && isClientChannel) ctor = "MyChannel(IDictionary properties, IClientChannelSinkProvider clientSinkProvider, IServerChannelSinkProvider serverSinkProvider)"; else if (isServerChannel) ctor = "MyChannel(IDictionary properties, IServerChannelSinkProvider serverSinkProvider)"; else if (isClientChannel) ctor = "MyChannel(IDictionary properties, IClientChannelSinkProvider clientSinkProvider)"; throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_ChannelMissingCtor"), type.FullName, ctor)); } return channel; } // CreateChannelFromEntry // create a client sink provider chain [System.Security.SecurityCritical] // auto-generated private static IClientChannelSinkProvider CreateClientChannelSinkProviderChain(ArrayList entries) { IClientChannelSinkProvider chain = null; IClientChannelSinkProvider current = null; foreach (RemotingXmlConfigFileData.SinkProviderEntry entry in entries) { if (chain == null) { chain = (IClientChannelSinkProvider)CreateChannelSinkProvider(entry, false); current = chain; } else { current.Next = (IClientChannelSinkProvider)CreateChannelSinkProvider(entry, false); current = current.Next; } } return chain; } // CreateClientChannelSinkProviderChain // create a client sink provider chain [System.Security.SecurityCritical] // auto-generated private static IServerChannelSinkProvider CreateServerChannelSinkProviderChain(ArrayList entries) { IServerChannelSinkProvider chain = null; IServerChannelSinkProvider current = null; foreach (RemotingXmlConfigFileData.SinkProviderEntry entry in entries) { if (chain == null) { chain = (IServerChannelSinkProvider)CreateChannelSinkProvider(entry, true); current = chain; } else { current.Next = (IServerChannelSinkProvider)CreateChannelSinkProvider(entry, true); current = current.Next; } } return chain; } // CreateServerChannelSinkProviderChain // create a sink provider from the config file data [System.Security.SecurityCritical] // auto-generated private static Object CreateChannelSinkProvider(RemotingXmlConfigFileData.SinkProviderEntry entry, bool bServer) { Object sinkProvider = null; Type type = RemotingConfigInfo.LoadType(entry.TypeName, entry.AssemblyName); if (bServer) { // make sure this is a client provider if (!typeof(IServerChannelSinkProvider).IsAssignableFrom(type)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_InvalidSinkProviderType"), type.FullName, "IServerChannelSinkProvider")); } } else { // make sure this is a server provider if (!typeof(IClientChannelSinkProvider).IsAssignableFrom(type)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_InvalidSinkProviderType"), type.FullName, "IClientChannelSinkProvider")); } } // check to see if something labelled as a formatter is a formatter if (entry.IsFormatter) { if ((bServer && !typeof(IServerFormatterSinkProvider).IsAssignableFrom(type)) || (!bServer && !typeof(IClientFormatterSinkProvider).IsAssignableFrom(type))) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_SinkProviderNotFormatter"), type.FullName)); } } // setup the argument list and call the constructor Object[] args = new Object[2]; args[0] = entry.Properties; args[1] = entry.ProviderData; try { sinkProvider = Activator.CreateInstance(type, BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance, null, args, null, null); } catch (MissingMethodException) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_SinkProviderMissingCtor"), type.FullName, "MySinkProvider(IDictionary properties, ICollection providerData)")); } return sinkProvider; } // CreateChannelSinkProvider // This is used at the client end to check if an activation needs // to go remote. [System.Security.SecurityCritical] // auto-generated internal static ActivatedClientTypeEntry IsRemotelyActivatedClientType(RuntimeType svrType) { RemotingTypeCachedData cache = (RemotingTypeCachedData) InternalRemotingServices.GetReflectionCachedData(svrType); String assemblyName = cache.SimpleAssemblyName; ActivatedClientTypeEntry entry = Info.QueryRemoteActivate(svrType.FullName, assemblyName); if (entry == null) { // If not found try with the full assembly name String fullAssemblyName = cache.AssemblyName; entry = Info.QueryRemoteActivate(svrType.FullName, fullAssemblyName); if (entry == null){ // If still not found try with partial type name (without namespace) entry = Info.QueryRemoteActivate(svrType.Name, assemblyName); } } return entry; } // IsRemotelyActivatedClientType // This is used at the client end to check if an activation needs // to go remote. internal static ActivatedClientTypeEntry IsRemotelyActivatedClientType(String typeName, String assemblyName) { return Info.QueryRemoteActivate(typeName, assemblyName); } // This is used at the client end to check if a "new Foo" needs to // happen via a Connect() under the covers. [System.Security.SecurityCritical] // auto-generated internal static WellKnownClientTypeEntry IsWellKnownClientType(RuntimeType svrType) { RemotingTypeCachedData cache = (RemotingTypeCachedData) InternalRemotingServices.GetReflectionCachedData(svrType); String assemblyName = cache.SimpleAssemblyName; WellKnownClientTypeEntry wke = Info.QueryConnect(svrType.FullName, assemblyName); if (wke == null) { wke= Info.QueryConnect(svrType.Name, assemblyName); } return wke; } // This is used at the client end to check if a "new Foo" needs to // happen via a Connect() under the covers. internal static WellKnownClientTypeEntry IsWellKnownClientType(String typeName, String assemblyName) { return Info.QueryConnect(typeName, assemblyName); } // // helper functions for processing and parsing data // private static void ParseGenericType(String typeAssem, int indexStart, out String typeName, out String assemName) { int len = typeAssem.Length; int depth = 1; int index = indexStart; while(depth > 0 && (++index < len - 1)) { if (typeAssem[index] == '[') { depth++; } else if (typeAssem[index] == ']') { depth--; } } if (depth > 0 || index >= len) { typeName = null; assemName = null; } else { index = typeAssem.IndexOf(',', index); // comma must be present, and can't be last character if ((index >= 0) && (index < (len - 1))) { typeName = typeAssem.Substring(0, index).Trim(); assemName = typeAssem.Substring(index + 1).Trim(); } else { typeName = null; assemName = null; } } } internal static void ParseType(String typeAssem, out String typeName, out String assemName) { String value = typeAssem; int genericTypeIndex = value.IndexOf("["); if ((genericTypeIndex >= 0) && (genericTypeIndex < (value.Length - 1))) { ParseGenericType(value, genericTypeIndex, out typeName, out assemName); } else { int index = value.IndexOf(","); // comma must be present, and can't be last character if ((index >= 0) && (index < (value.Length - 1))) { typeName = value.Substring(0, index).Trim(); assemName = value.Substring(index + 1).Trim(); } else { typeName = null; assemName = null; } } } // ParseType // This is used at the server end to check if a type being activated // is explicitly allowed by the server. [System.Security.SecurityCritical] // auto-generated internal static bool IsActivationAllowed(RuntimeType svrType) { if (svrType == null) return false; RemotingTypeCachedData cache = (RemotingTypeCachedData) InternalRemotingServices.GetReflectionCachedData(svrType); String assemblyName = cache.SimpleAssemblyName; return Info.ActivationAllowed(svrType.FullName, assemblyName); } // IsActivationAllowed // This is the flavor that we call from the activation listener // code path. This ensures that we don't load a type before checking // that it is configured for remote activation [System.Security.SecurityCritical] // auto-generated internal static bool IsActivationAllowed(String TypeName) { String svrTypeName = RemotingServices.InternalGetTypeNameFromQualifiedTypeName(TypeName); if (svrTypeName == null) { return false; } String typeName; String asmName; ParseType(svrTypeName, out typeName, out asmName); if (asmName == null) return false; int index = asmName.IndexOf(','); if (index != -1) { // strip off the version info asmName = asmName.Substring(0,index); } return Info.ActivationAllowed(typeName, asmName); } // helper for Configuration::RegisterActivatedServiceType internal static void RegisterActivatedServiceType(ActivatedServiceTypeEntry entry) { Info.AddActivatedType(entry.TypeName, entry.AssemblyName, entry.ContextAttributes); } // RegisterActivatedServiceType // helper for Configuration::RegisterWellKnownServiceType [System.Security.SecurityCritical] // auto-generated internal static void RegisterWellKnownServiceType(WellKnownServiceTypeEntry entry) { BCLDebug.Trace("REMOTE", "Adding well known service type for " + entry.ObjectUri); // < String serverType = entry.TypeName; String asmName = entry.AssemblyName; String URI = entry.ObjectUri; WellKnownObjectMode mode = entry.Mode; lock (Info) { // We make an entry in our config tables so as to keep // both the file-based and programmatic config in [....]. Info.AddWellKnownEntry(entry); } } // RegisterWellKnownServiceType // helper for Configuration::RegisterActivatedClientType internal static void RegisterActivatedClientType(ActivatedClientTypeEntry entry) { Info.AddActivatedClientType(entry); } // helper for Configuration::RegisterWellKnownClientType internal static void RegisterWellKnownClientType(WellKnownClientTypeEntry entry) { Info.AddWellKnownClientType(entry); } //helper for Configuration::GetServerTypeForUri [System.Security.SecurityCritical] // auto-generated internal static Type GetServerTypeForUri(String URI) { URI = Identity.RemoveAppNameOrAppGuidIfNecessary(URI); return Info.GetServerTypeForUri(URI); } // helper for Configuration::GetRegisteredActivatedServiceTypes internal static ActivatedServiceTypeEntry[] GetRegisteredActivatedServiceTypes() { return Info.GetRegisteredActivatedServiceTypes(); } // GetRegisteredActivatedServiceTypes // helper for Configuration::GetRegisteredWellKnownServiceTypes internal static WellKnownServiceTypeEntry[] GetRegisteredWellKnownServiceTypes() { return Info.GetRegisteredWellKnownServiceTypes(); } // GetRegisteredWellKnownServiceTypes // helper for Configuration::GetRegisteredActivatedClientTypes internal static ActivatedClientTypeEntry[] GetRegisteredActivatedClientTypes() { return Info.GetRegisteredActivatedClientTypes(); } // GetRegisteredActivatedClientTypes // helper for Configuration::GetRegisteredWellKnownClientTypes internal static WellKnownClientTypeEntry[] GetRegisteredWellKnownClientTypes() { return Info.GetRegisteredWellKnownClientTypes(); } // GetRegisteredWellKnownClientTypes // helper for creating well known objects on demand [System.Security.SecurityCritical] // auto-generated internal static ServerIdentity CreateWellKnownObject(String uri) { uri = Identity.RemoveAppNameOrAppGuidIfNecessary(uri); return Info.StartupWellKnownObject(uri); } internal class RemotingConfigInfo { Hashtable _exportableClasses; // list of objects that can be client-activated // (this should be a StringTable since we only use the key, // but that type was removed from the BCL :( ) Hashtable _remoteTypeInfo; Hashtable _remoteAppInfo; Hashtable _wellKnownExportInfo; //well known exports indexed by object URI in lower-case static char[] SepSpace = {' '}; static char[] SepPound = {'#'}; static char[] SepSemiColon = {';'}; static char[] SepEquals = {'='}; private static Object s_wkoStartLock = new Object(); private static PermissionSet s_fullTrust = new PermissionSet(PermissionState.Unrestricted); internal RemotingConfigInfo() { // < _remoteTypeInfo = Hashtable.Synchronized(new Hashtable()); _exportableClasses = Hashtable.Synchronized(new Hashtable()); _remoteAppInfo = Hashtable.Synchronized(new Hashtable()); _wellKnownExportInfo = Hashtable.Synchronized(new Hashtable()); } // encodes type name and assembly name into one string for purposes of // indexing in lists and hash tables private String EncodeTypeAndAssemblyNames(String typeName, String assemblyName) { return typeName + ", " + assemblyName.ToLower(CultureInfo.InvariantCulture); } // // XML Configuration Helper Functions // internal void StoreActivatedExports(RemotingXmlConfigFileData configData) { foreach (RemotingXmlConfigFileData.TypeEntry entry in configData.ServerActivatedEntries) { ActivatedServiceTypeEntry aste = new ActivatedServiceTypeEntry(entry.TypeName, entry.AssemblyName); aste.ContextAttributes = CreateContextAttributesFromConfigEntries(entry.ContextAttributes); RemotingConfiguration.RegisterActivatedServiceType(aste); } } // StoreActivatedExports [System.Security.SecurityCritical] // auto-generated internal void StoreInteropEntries(RemotingXmlConfigFileData configData) { // process interop xml element entries foreach (RemotingXmlConfigFileData.InteropXmlElementEntry entry in configData.InteropXmlElementEntries) { Assembly assembly = Assembly.Load(entry.UrtAssemblyName); Type type = assembly.GetType(entry.UrtTypeName); SoapServices.RegisterInteropXmlElement(entry.XmlElementName, entry.XmlElementNamespace, type); } // process interop xml type entries foreach (RemotingXmlConfigFileData.InteropXmlTypeEntry entry in configData.InteropXmlTypeEntries) { Assembly assembly = Assembly.Load(entry.UrtAssemblyName); Type type = assembly.GetType(entry.UrtTypeName); SoapServices.RegisterInteropXmlType(entry.XmlTypeName, entry.XmlTypeNamespace, type); } // process preload entries foreach (RemotingXmlConfigFileData.PreLoadEntry entry in configData.PreLoadEntries) { Assembly assembly = Assembly.Load(entry.AssemblyName); if (entry.TypeName != null) { Type type = assembly.GetType(entry.TypeName); SoapServices.PreLoad(type); } else { SoapServices.PreLoad(assembly); } } } // StoreInteropEntries internal void StoreRemoteAppEntries(RemotingXmlConfigFileData configData) { char[] slash = new char[]{'/'}; // add each remote app to the table foreach (RemotingXmlConfigFileData.RemoteAppEntry remApp in configData.RemoteAppEntries) { // form complete application uri by combining specified uri with app-name // (make sure appUri ends with slash, and that app name doesn't start, // with one. then make sure that the combined form has no trailing slashes). String appUri = remApp.AppUri; if ((appUri != null) && !appUri.EndsWith("/", StringComparison.Ordinal)) appUri = appUri.TrimEnd(slash); // add each client activated type for this remote app foreach (RemotingXmlConfigFileData.TypeEntry cae in remApp.ActivatedObjects) { ActivatedClientTypeEntry acte = new ActivatedClientTypeEntry(cae.TypeName, cae.AssemblyName, appUri); acte.ContextAttributes = CreateContextAttributesFromConfigEntries(cae.ContextAttributes); RemotingConfiguration.RegisterActivatedClientType(acte); } // add each well known object for this remote app foreach (RemotingXmlConfigFileData.ClientWellKnownEntry cwke in remApp.WellKnownObjects) { WellKnownClientTypeEntry wke = new WellKnownClientTypeEntry(cwke.TypeName, cwke.AssemblyName, cwke.Url); wke.ApplicationUrl = appUri; RemotingConfiguration.RegisterWellKnownClientType(wke); } } } // StoreRemoteAppEntries [System.Security.SecurityCritical] // auto-generated internal void StoreWellKnownExports(RemotingXmlConfigFileData configData) { // < foreach (RemotingXmlConfigFileData.ServerWellKnownEntry entry in configData.ServerWellKnownEntries) { WellKnownServiceTypeEntry wke = new WellKnownServiceTypeEntry( entry.TypeName, entry.AssemblyName, entry.ObjectURI, entry.ObjectMode); wke.ContextAttributes = null; // Register the well known entry but do not startup the object RemotingConfigHandler.RegisterWellKnownServiceType(wke); } } // StoreWellKnownExports // helper functions for above configuration helpers static IContextAttribute[] CreateContextAttributesFromConfigEntries(ArrayList contextAttributes) { // create context attribute entry list int numAttrs = contextAttributes.Count; if (numAttrs == 0) return null; IContextAttribute[] attrs = new IContextAttribute[numAttrs]; int co = 0; foreach (RemotingXmlConfigFileData.ContextAttributeEntry cae in contextAttributes) { Assembly asm = Assembly.Load(cae.AssemblyName); IContextAttribute attr = null; Hashtable properties = cae.Properties; if ((properties != null) && (properties.Count > 0)) { Object[] args = new Object[1]; args[0] = properties; // We explicitly allow the ability to create internal // only attributes attr = (IContextAttribute) Activator.CreateInstance( asm.GetType(cae.TypeName, false, false), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, args, null, null); } else { attr = (IContextAttribute) Activator.CreateInstance( asm.GetType(cae.TypeName, false, false), true); } attrs[co++] = attr; } return attrs; } // CreateContextAttributesFromConfigEntries // // end of XML configuration helper functions // internal bool ActivationAllowed(String typeName, String assemblyName) { // the assembly name is stored in lower-case to let it be case-insensitive return _exportableClasses.ContainsKey(EncodeTypeAndAssemblyNames(typeName, assemblyName)); } internal ActivatedClientTypeEntry QueryRemoteActivate(String typeName, String assemblyName) { String index = EncodeTypeAndAssemblyNames(typeName, assemblyName); ActivatedClientTypeEntry typeEntry = _remoteTypeInfo[index] as ActivatedClientTypeEntry; if (typeEntry == null) return null; if (typeEntry.GetRemoteAppEntry() == null) { RemoteAppEntry appEntry = (RemoteAppEntry) _remoteAppInfo[typeEntry.ApplicationUrl]; if (appEntry == null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Activation_MissingRemoteAppEntry"), typeEntry.ApplicationUrl)); } typeEntry.CacheRemoteAppEntry(appEntry); } return typeEntry; } internal WellKnownClientTypeEntry QueryConnect(String typeName, String assemblyName) { String index = EncodeTypeAndAssemblyNames(typeName, assemblyName); WellKnownClientTypeEntry typeEntry = _remoteTypeInfo[index] as WellKnownClientTypeEntry; if (typeEntry == null) return null; return typeEntry; } // // helper functions to retrieve registered types // internal ActivatedServiceTypeEntry[] GetRegisteredActivatedServiceTypes() { ActivatedServiceTypeEntry[] entries = new ActivatedServiceTypeEntry[_exportableClasses.Count]; int co = 0; foreach (DictionaryEntry dictEntry in _exportableClasses) { entries[co++] = (ActivatedServiceTypeEntry)dictEntry.Value; } return entries; } // GetRegisteredActivatedServiceTypes internal WellKnownServiceTypeEntry[] GetRegisteredWellKnownServiceTypes() { WellKnownServiceTypeEntry[] entries = new WellKnownServiceTypeEntry[_wellKnownExportInfo.Count]; int co = 0; foreach (DictionaryEntry dictEntry in _wellKnownExportInfo) { WellKnownServiceTypeEntry entry = (WellKnownServiceTypeEntry)dictEntry.Value; WellKnownServiceTypeEntry wkste = new WellKnownServiceTypeEntry( entry.TypeName, entry.AssemblyName, entry.ObjectUri, entry.Mode); wkste.ContextAttributes = entry.ContextAttributes; entries[co++] = wkste; } return entries; } // GetRegisteredWellKnownServiceTypes internal ActivatedClientTypeEntry[] GetRegisteredActivatedClientTypes() { // count number of well known client types int count = 0; foreach (DictionaryEntry dictEntry in _remoteTypeInfo) { ActivatedClientTypeEntry entry = dictEntry.Value as ActivatedClientTypeEntry; if (entry != null) count++; } ActivatedClientTypeEntry[] entries = new ActivatedClientTypeEntry[count]; int co = 0; foreach (DictionaryEntry dictEntry in _remoteTypeInfo) { ActivatedClientTypeEntry entry = dictEntry.Value as ActivatedClientTypeEntry; if (entry != null) { // retrieve application url String appUrl = null; RemoteAppEntry remApp = entry.GetRemoteAppEntry(); if (remApp != null) appUrl = remApp.GetAppURI(); ActivatedClientTypeEntry wkcte = new ActivatedClientTypeEntry(entry.TypeName, entry.AssemblyName, appUrl); // Fetch the context attributes wkcte.ContextAttributes = entry.ContextAttributes; entries[co++] = wkcte; } } return entries; } // GetRegisteredActivatedClientTypes internal WellKnownClientTypeEntry[] GetRegisteredWellKnownClientTypes() { // count number of well known client types int count = 0; foreach (DictionaryEntry dictEntry in _remoteTypeInfo) { WellKnownClientTypeEntry entry = dictEntry.Value as WellKnownClientTypeEntry; if (entry != null) count++; } WellKnownClientTypeEntry[] entries = new WellKnownClientTypeEntry[count]; int co = 0; foreach (DictionaryEntry dictEntry in _remoteTypeInfo) { WellKnownClientTypeEntry entry = dictEntry.Value as WellKnownClientTypeEntry; if (entry != null) { WellKnownClientTypeEntry wkcte = new WellKnownClientTypeEntry(entry.TypeName, entry.AssemblyName, entry.ObjectUrl); // see if there is an associated app RemoteAppEntry remApp = entry.GetRemoteAppEntry(); if (remApp != null) wkcte.ApplicationUrl = remApp.GetAppURI(); entries[co++] = wkcte; } } return entries; } // GetRegisteredWellKnownClientTypes // // end of helper functions to retrieve registered types // internal void AddActivatedType(String typeName, String assemblyName, IContextAttribute[] contextAttributes) { if (typeName == null) throw new ArgumentNullException("typeName"); if (assemblyName == null) throw new ArgumentNullException("assemblyName"); Contract.EndContractBlock(); if (CheckForRedirectedClientType(typeName, assemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_CantUseRedirectedTypeForWellKnownService"), typeName, assemblyName)); } ActivatedServiceTypeEntry aste = new ActivatedServiceTypeEntry(typeName, assemblyName); aste.ContextAttributes = contextAttributes; // The assembly name is stored in lowercase to let it be case-insensitive. String key = EncodeTypeAndAssemblyNames(typeName, assemblyName); _exportableClasses.Add(key, aste); } // AddActivatedType // determines if either a wellknown or activated service type entry // is associated with the given type name and assembly name private bool CheckForServiceEntryWithType(String typeName, String asmName) { return CheckForWellKnownServiceEntryWithType(typeName, asmName) || ActivationAllowed(typeName, asmName); } // CheckForServiceEntryWithType private bool CheckForWellKnownServiceEntryWithType(String typeName, String asmName) { foreach (DictionaryEntry entry in _wellKnownExportInfo) { WellKnownServiceTypeEntry svc = (WellKnownServiceTypeEntry)entry.Value; if (typeName == svc.TypeName) { bool match = false; // need to ignore version while checking if (asmName == svc.AssemblyName) match = true; else { // only well known service entry can have version info if (String.Compare(svc.AssemblyName, 0, asmName, 0, asmName.Length, StringComparison.OrdinalIgnoreCase) == 0) { // if asmName != svc.AssemblyName and svc.AssemblyName // starts with asmName we know that svc.AssemblyName is // longer. If the next character is a comma, then the // assembly names match except for version numbers // which is ok. if (svc.AssemblyName[asmName.Length] == ',') match = true; } } // We were trying to redirect if (match) return true; } } return false; } // CheckForWellKnownServiceEntryOfType // returns true if activation for the type has been redirected. private bool CheckForRedirectedClientType(String typeName, String asmName) { // if asmName has version information, remove it. int index = asmName.IndexOf(","); if (index != -1) asmName = asmName.Substring(0, index); return (QueryRemoteActivate(typeName, asmName) != null) || (QueryConnect(typeName, asmName) != null); } // CheckForRedirectedClientType internal void AddActivatedClientType(ActivatedClientTypeEntry entry) { if (CheckForRedirectedClientType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_TypeAlreadyRedirected"), entry.TypeName, entry.AssemblyName)); } if (CheckForServiceEntryWithType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_CantRedirectActivationOfWellKnownService"), entry.TypeName, entry.AssemblyName)); } String appUrl = entry.ApplicationUrl; RemoteAppEntry appEntry = (RemoteAppEntry)_remoteAppInfo[appUrl]; if (appEntry == null) { appEntry = new RemoteAppEntry(appUrl, appUrl); _remoteAppInfo.Add(appUrl, appEntry); } if (appEntry != null) { entry.CacheRemoteAppEntry(appEntry); } String index = EncodeTypeAndAssemblyNames(entry.TypeName, entry.AssemblyName); _remoteTypeInfo.Add(index, entry); } // AddActivatedClientType internal void AddWellKnownClientType(WellKnownClientTypeEntry entry) { if (CheckForRedirectedClientType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_TypeAlreadyRedirected"), entry.TypeName, entry.AssemblyName)); } if (CheckForServiceEntryWithType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_CantRedirectActivationOfWellKnownService"), entry.TypeName, entry.AssemblyName)); } String appUrl = entry.ApplicationUrl; RemoteAppEntry appEntry = null; if (appUrl != null) { appEntry = (RemoteAppEntry)_remoteAppInfo[appUrl]; if (appEntry == null) { appEntry = new RemoteAppEntry(appUrl, appUrl); _remoteAppInfo.Add(appUrl, appEntry); } } if (appEntry != null) entry.CacheRemoteAppEntry(appEntry); String index = EncodeTypeAndAssemblyNames(entry.TypeName, entry.AssemblyName); _remoteTypeInfo.Add(index, entry); } // AddWellKnownClientType // This is to add programmatically registered well known objects // so that we keep all this data in one place [System.Security.SecurityCritical] // auto-generated internal void AddWellKnownEntry(WellKnownServiceTypeEntry entry) { AddWellKnownEntry(entry, true); } [System.Security.SecurityCritical] // auto-generated internal void AddWellKnownEntry(WellKnownServiceTypeEntry entry, bool fReplace) { if (CheckForRedirectedClientType(entry.TypeName, entry.AssemblyName)) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_Config_CantUseRedirectedTypeForWellKnownService"), entry.TypeName, entry.AssemblyName)); } String key = entry.ObjectUri.ToLower(CultureInfo.InvariantCulture); if (fReplace) { // Registering a well known object twice replaces the old one, so // we null out the old entry in the identity table after adding // this one. The identity will be recreated the next time someone // asks for this object. _wellKnownExportInfo[key] = entry; IdentityHolder.RemoveIdentity(entry.ObjectUri); } else { _wellKnownExportInfo.Add(key, entry); } } //This API exposes a way to get server type information wiihout booting the object [System.Security.SecurityCritical] // auto-generated internal Type GetServerTypeForUri(String URI) { Contract.Assert(null != URI, "null != URI"); Type serverType = null; String uriLower = URI.ToLower(CultureInfo.InvariantCulture); WellKnownServiceTypeEntry entry = (WellKnownServiceTypeEntry)_wellKnownExportInfo[uriLower]; if(entry != null) { serverType = LoadType(entry.TypeName, entry.AssemblyName); } return serverType; } [System.Security.SecurityCritical] // auto-generated internal ServerIdentity StartupWellKnownObject(String URI) { Contract.Assert(null != URI, "null != URI"); String uriLower = URI.ToLower(CultureInfo.InvariantCulture); ServerIdentity ident = null; WellKnownServiceTypeEntry entry = (WellKnownServiceTypeEntry)_wellKnownExportInfo[uriLower]; if (entry != null) { ident = StartupWellKnownObject( entry.AssemblyName, entry.TypeName, entry.ObjectUri, entry.Mode); } return ident; } [System.Security.SecurityCritical] // auto-generated internal ServerIdentity StartupWellKnownObject( String asmName, String svrTypeName, String URI, WellKnownObjectMode mode) { return StartupWellKnownObject(asmName, svrTypeName, URI, mode, false); } [System.Security.SecurityCritical] // auto-generated internal ServerIdentity StartupWellKnownObject( String asmName, String svrTypeName, String URI, WellKnownObjectMode mode, bool fReplace) { lock (s_wkoStartLock) { MarshalByRefObject obj = null; ServerIdentity srvID = null; // attempt to load the type Type serverType = LoadType(svrTypeName, asmName); // make sure the well known object derives from MarshalByRefObject if(!serverType.IsMarshalByRef) { throw new RemotingException( Environment.GetResourceString("Remoting_WellKnown_MustBeMBR", svrTypeName)); } // make sure that no one beat us to creating // the well known object srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI); if ((srvID != null) && srvID.IsRemoteDisconnected()) { IdentityHolder.RemoveIdentity(URI); srvID = null; } if (srvID == null) { //WellKnown type instances need to be created under full trust //since the permission set might have been restricted by the channel //pipeline. //This assert is protected by Infrastructure link demands. s_fullTrust.Assert(); try { obj = (MarshalByRefObject)Activator.CreateInstance(serverType, true); if (RemotingServices.IsClientProxy(obj)) { // The wellknown type is remoted so we must wrap the proxy // with a local object. // The redirection proxy masquerades as an object of the appropriate // type, and forwards incoming messages to the actual proxy. RedirectionProxy redirectedProxy = new RedirectionProxy(obj, serverType); redirectedProxy.ObjectMode = mode; RemotingServices.MarshalInternal(redirectedProxy, URI, serverType); srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI); Contract.Assert(null != srvID, "null != srvID"); // The redirection proxy handles SingleCall versus Singleton, // so we always set its mode to Singleton. srvID.SetSingletonObjectMode(); } else if (serverType.IsCOMObject && (mode == WellKnownObjectMode.Singleton)) { // Singleton COM objects are wrapped, so that they will be // recreated when an RPC server not available is thrown // if dllhost.exe is killed. ComRedirectionProxy comRedirectedProxy = new ComRedirectionProxy(obj, serverType); RemotingServices.MarshalInternal(comRedirectedProxy, URI, serverType); srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI); Contract.Assert(null != srvID, "null != srvID"); // Only singleton COM objects are redirected this way. srvID.SetSingletonObjectMode(); } else { // make sure the object didn't Marshal itself. String tempUri = RemotingServices.GetObjectUri(obj); if (tempUri != null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_WellKnown_CtorCantMarshal"), URI)); } RemotingServices.MarshalInternal(obj, URI, serverType); srvID = (ServerIdentity)IdentityHolder.ResolveIdentity(URI); Contract.Assert(null != srvID, "null != srvID"); if (mode == WellKnownObjectMode.SingleCall) { // We need to set a special flag in the serverId // so that every dispatch to this type creates // a new instance of the server object srvID.SetSingleCallObjectMode(); } else { srvID.SetSingletonObjectMode(); } } } catch { throw; } finally { SecurityPermission.RevertAssert(); } } Contract.Assert(null != srvID, "null != srvID"); return srvID; } } // StartupWellKnownObject [System.Security.SecurityCritical] // auto-generated internal static Type LoadType(String typeName, String assemblyName) { Assembly asm = null; // All the LoadType callers have been protected by // Infrastructure LinkDemand, it is safe to assert // this permission. // Assembly.Load demands FileIO when the target // assembly is the same as the executable running. new FileIOPermission(PermissionState.Unrestricted).Assert(); try { asm = Assembly.Load(assemblyName); } finally { CodeAccessPermission.RevertAssert(); } if (asm == null) { throw new RemotingException( Environment.GetResourceString("Remoting_AssemblyLoadFailed", assemblyName)); } Type type = asm.GetType(typeName, false, false); if (type == null) { throw new RemotingException( Environment.GetResourceString("Remoting_BadType", typeName + ", " + assemblyName)); } return type; } // LoadType }// class RemotingConfigInfo } // class RemotingConfigHandler internal class DelayLoadClientChannelEntry { private RemotingXmlConfigFileData.ChannelEntry _entry; private IChannelSender _channel; private bool _bRegistered; private bool _ensureSecurity; internal DelayLoadClientChannelEntry(RemotingXmlConfigFileData.ChannelEntry entry, bool ensureSecurity) { _entry = entry; _channel = null; _bRegistered = false; _ensureSecurity = ensureSecurity; } internal IChannelSender Channel { [System.Security.SecurityCritical] // auto-generated get { // If this method returns null, that means the channel has already been registered. // NOTE: Access to delay load client entries is synchronized at a higher level. if (_channel == null) { if (!_bRegistered) { _channel = (IChannelSender)RemotingConfigHandler.CreateChannelFromConfigEntry(_entry); _entry = null; } } return _channel; } // get } // Channel internal void RegisterChannel() { Contract.Assert(_channel != null, "channel shouldn't be null"); // NOTE: Access to delay load client entries is synchronized at a higher level. ChannelServices.RegisterChannel(_channel, _ensureSecurity); _bRegistered = true; _channel = null; } // RegisterChannel } // class DelayLoadChannelEntry } // namespace // 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
- StyleSheetDesigner.cs
- Transform3D.cs
- NetworkCredential.cs
- SponsorHelper.cs
- DataGridViewDataErrorEventArgs.cs
- controlskin.cs
- SchemaObjectWriter.cs
- TreeNode.cs
- XmlSchemaDocumentation.cs
- AuthenticationModuleElement.cs
- SmiEventStream.cs
- VisualStyleInformation.cs
- BridgeDataRecord.cs
- ListControl.cs
- TransformerInfoCollection.cs
- HealthMonitoringSection.cs
- TemplateXamlParser.cs
- WebControlAdapter.cs
- WindowsStartMenu.cs
- XmlSigningNodeWriter.cs
- ComPlusSynchronizationContext.cs
- SchemaAttDef.cs
- ConfigXmlComment.cs
- UIAgentAsyncEndRequest.cs
- DoWorkEventArgs.cs
- DesignerTransaction.cs
- OperationBehaviorAttribute.cs
- ColorAnimationUsingKeyFrames.cs
- Ticks.cs
- SectionVisual.cs
- EtwTrace.cs
- HttpResponse.cs
- BufferedStream.cs
- TimelineGroup.cs
- ObjectStateManagerMetadata.cs
- EntityCommandDefinition.cs
- GridViewHeaderRowPresenter.cs
- EntryWrittenEventArgs.cs
- StorageEndPropertyMapping.cs
- AttributeQuery.cs
- ByteStreamGeometryContext.cs
- SiteMapNode.cs
- WriteableOnDemandPackagePart.cs
- XmlNotation.cs
- HttpCookie.cs
- PackUriHelper.cs
- StyleCollectionEditor.cs
- XmlComplianceUtil.cs
- MasterPageBuildProvider.cs
- DataSourceXmlTextReader.cs
- DocumentViewer.cs
- XPathNavigatorKeyComparer.cs
- OleDbPropertySetGuid.cs
- HybridDictionary.cs
- GPRECT.cs
- EntityCommand.cs
- AuthenticateEventArgs.cs
- DataGridPagingPage.cs
- AnimationStorage.cs
- LayoutManager.cs
- IPHostEntry.cs
- LayoutTable.cs
- OleDbError.cs
- AttachedPropertyBrowsableForChildrenAttribute.cs
- CallSiteHelpers.cs
- PropertyGridEditorPart.cs
- ProfileParameter.cs
- QueryResponse.cs
- DefaultTextStoreTextComposition.cs
- MultipleViewProviderWrapper.cs
- BitmapEffectInputConnector.cs
- Substitution.cs
- XmlStreamStore.cs
- MatchingStyle.cs
- SimpleColumnProvider.cs
- ApplicationSecurityManager.cs
- ChangeInterceptorAttribute.cs
- AuthenticationManager.cs
- MoveSizeWinEventHandler.cs
- XmlChildNodes.cs
- TagPrefixCollection.cs
- TrackingValidationObjectDictionary.cs
- PathSegmentCollection.cs
- RuleRefElement.cs
- DataRelationCollection.cs
- TypefaceMap.cs
- IsolatedStorageFilePermission.cs
- Types.cs
- OdbcConnectionFactory.cs
- DateTimeStorage.cs
- EntitySqlQueryCacheKey.cs
- CodeTypeParameterCollection.cs
- CacheMemory.cs
- SoapAttributeAttribute.cs
- TextBoxRenderer.cs
- NamedPermissionSet.cs
- FileAuthorizationModule.cs
- MembershipValidatePasswordEventArgs.cs
- WebPartDeleteVerb.cs
- CollectionView.cs