We need you! We're working hard on the next version of Developer Fusion - Let us know what you think we should be up to!

The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting.Activation \ SinkProviderEntry

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*============================================================
  16. **
  17. **  File:    RemotingConfigParser.cs
  18. **
  19. **  Purpose: Parse remoting configuration files.
  20. **
  21. **
  22. ===========================================================*/
  23. using System;
  24. using System.Collections;
  25. using System.IO;
  26. using System.Reflection;
  27. using System.Runtime.Remoting;
  28. using System.Runtime.Remoting.Channels;
  29. using System.Globalization;
  30. using System.Runtime.Versioning;
  31. namespace System.Runtime.Remoting.Activation
  32. {
  33.    
  34.    
  35.     internal class RemotingXmlConfigFileData
  36.     {
  37.         // debug settings
  38.         static internal bool LoadTypes = false;
  39.         // indicates whether we should attempt to load types in config files
  40.        
  41.         //
  42.         // configuration entry storage classes (in alphabetical order)
  43.         // There is one class for each type of entry in a remoting config file.
  44.         //
  45.        
  46.         internal class ChannelEntry
  47.         {
  48.             internal string TypeName;
  49.             internal string AssemblyName;
  50.             internal Hashtable Properties;
  51.             internal bool DelayLoad = false;
  52.             internal ArrayList ClientSinkProviders = new ArrayList();
  53.             internal ArrayList ServerSinkProviders = new ArrayList();
  54.            
  55.             internal ChannelEntry(string typeName, string assemblyName, Hashtable properties)
  56.             {
  57.                 TypeName = typeName;
  58.                 AssemblyName = assemblyName;
  59.                 Properties = properties;
  60.             }
  61.             // ChannelEntry
  62.         }
  63.         // class ChannelEntry
  64.        
  65.         internal class ClientWellKnownEntry
  66.         {
  67.             internal string TypeName;
  68.             internal string AssemblyName;
  69.             internal string Url;
  70.            
  71.             internal ClientWellKnownEntry(string typeName, string assemName, string url)
  72.             {
  73.                 TypeName = typeName;
  74.                 AssemblyName = assemName;
  75.                 Url = url;
  76.             }
  77.         }
  78.         // class ClientWellKnownEntry
  79.        
  80.         internal class ContextAttributeEntry
  81.         {
  82.             internal string TypeName;
  83.             internal string AssemblyName;
  84.             internal Hashtable Properties;
  85.            
  86.             internal ContextAttributeEntry(string typeName, string assemName, Hashtable properties)
  87.             {
  88.                 TypeName = typeName;
  89.                 AssemblyName = assemName;
  90.                 Properties = properties;
  91.             }
  92.         }
  93.         // class ContextAttributeEntry
  94.        
  95.         internal class InteropXmlElementEntry
  96.         {
  97.             internal string XmlElementName;
  98.             internal string XmlElementNamespace;
  99.             internal string UrtTypeName;
  100.             internal string UrtAssemblyName;
  101.            
  102.             internal InteropXmlElementEntry(string xmlElementName, string xmlElementNamespace, string urtTypeName, string urtAssemblyName)
  103.             {
  104.                 XmlElementName = xmlElementName;
  105.                 XmlElementNamespace = xmlElementNamespace;
  106.                 UrtTypeName = urtTypeName;
  107.                 UrtAssemblyName = urtAssemblyName;
  108.             }
  109.         }
  110.         // class InteropXmlElementEntry
  111.         internal class CustomErrorsEntry
  112.         {
  113.             internal CustomErrorsModes Mode;
  114.            
  115.             internal CustomErrorsEntry(CustomErrorsModes mode)
  116.             {
  117.                 Mode = mode;
  118.             }
  119.         }
  120.        
  121.         internal class InteropXmlTypeEntry
  122.         {
  123.             internal string XmlTypeName;
  124.             internal string XmlTypeNamespace;
  125.             internal string UrtTypeName;
  126.             internal string UrtAssemblyName;
  127.            
  128.             internal InteropXmlTypeEntry(string xmlTypeName, string xmlTypeNamespace, string urtTypeName, string urtAssemblyName)
  129.             {
  130.                 XmlTypeName = xmlTypeName;
  131.                 XmlTypeNamespace = xmlTypeNamespace;
  132.                 UrtTypeName = urtTypeName;
  133.                 UrtAssemblyName = urtAssemblyName;
  134.             }
  135.         }
  136.         // class InteropXmlTypeEntry
  137.        
  138.         internal class LifetimeEntry
  139.         {
  140.             // If any of these are false, then the corresponding property wasn't specified
  141.             // in the config file.
  142.             internal bool IsLeaseTimeSet = false;
  143.             internal bool IsRenewOnCallTimeSet = false;
  144.             internal bool IsSponsorshipTimeoutSet = false;
  145.             internal bool IsLeaseManagerPollTimeSet = false;
  146.            
  147.             private TimeSpan _leaseTime;
  148.             private TimeSpan _renewOnCallTime;
  149.             private TimeSpan _sponsorshipTimeout;
  150.             private TimeSpan _leaseManagerPollTime;
  151.            
  152.             internal TimeSpan LeaseTime {
  153.                 get {
  154.                     BCLDebug.Assert(IsLeaseTimeSet == true, "LeaseTime not set");
  155.                     return _leaseTime;
  156.                 }
  157.                 set {
  158.                     _leaseTime = value;
  159.                     IsLeaseTimeSet = true;
  160.                 }
  161.             }
  162.            
  163.             internal TimeSpan RenewOnCallTime {
  164.                 get {
  165.                     BCLDebug.Assert(IsRenewOnCallTimeSet == true, "RenewOnCallTime not set");
  166.                     return _renewOnCallTime;
  167.                 }
  168.                 set {
  169.                     _renewOnCallTime = value;
  170.                     IsRenewOnCallTimeSet = true;
  171.                 }
  172.             }
  173.            
  174.             internal TimeSpan SponsorshipTimeout {
  175.                 get {
  176.                     BCLDebug.Assert(IsSponsorshipTimeoutSet == true, "SponsorShipTimeout not set");
  177.                     return _sponsorshipTimeout;
  178.                 }
  179.                 set {
  180.                     _sponsorshipTimeout = value;
  181.                     IsSponsorshipTimeoutSet = true;
  182.                 }
  183.             }
  184.            
  185.             internal TimeSpan LeaseManagerPollTime {
  186.                 get {
  187.                     BCLDebug.Assert(IsLeaseManagerPollTimeSet == true, "LeaseManagerPollTime not set");
  188.                     return _leaseManagerPollTime;
  189.                 }
  190.                 set {
  191.                     _leaseManagerPollTime = value;
  192.                     IsLeaseManagerPollTimeSet = true;
  193.                 }
  194.             }
  195.            
  196.         }
  197.         // class LifetimeEntry
  198.        
  199.         internal class PreLoadEntry
  200.         {
  201.             // If TypeName is null, then all types in the assembly specified
  202.             // should be preloaded.
  203.            
  204.             internal string TypeName;
  205.             internal string AssemblyName;
  206.            
  207.             public PreLoadEntry(string typeName, string assemblyName)
  208.             {
  209.                 TypeName = typeName;
  210.                 AssemblyName = assemblyName;
  211.             }
  212.         }
  213.         // class PreLoadEntry
  214.        
  215.         internal class RemoteAppEntry
  216.         {
  217.             internal string AppUri;
  218.            
  219.             internal ArrayList WellKnownObjects = new ArrayList();
  220.             internal ArrayList ActivatedObjects = new ArrayList();
  221.            
  222.             internal RemoteAppEntry(string appUri)
  223.             {
  224.                 AppUri = appUri;
  225.             }
  226.            
  227.             internal void AddWellKnownEntry(string typeName, string assemName, string url)
  228.             {
  229.                 ClientWellKnownEntry cwke = new ClientWellKnownEntry(typeName, assemName, url);
  230.                 WellKnownObjects.Add(cwke);
  231.             }
  232.            
  233.             internal void AddActivatedEntry(string typeName, string assemName, ArrayList contextAttributes)
  234.             {
  235.                 TypeEntry te = new TypeEntry(typeName, assemName, contextAttributes);
  236.                 ActivatedObjects.Add(te);
  237.             }
  238.            
  239.         }
  240.         // class RemoteAppEntry
  241.        
  242.         internal class ServerWellKnownEntry : TypeEntry
  243.         {
  244.             internal string ObjectURI;
  245.             internal WellKnownObjectMode ObjectMode;
  246.            
  247.             internal ServerWellKnownEntry(string typeName, string assemName, ArrayList contextAttributes, string objURI, WellKnownObjectMode objMode) : base(typeName, assemName, contextAttributes)
  248.             {
  249.                 ObjectURI = objURI;
  250.                 ObjectMode = objMode;
  251.             }
  252.         }
  253.         // class ServerWellKnownEntry
  254.        
  255.         internal class SinkProviderEntry
  256.         {
  257.             internal string TypeName;
  258.             internal string AssemblyName;
  259.             internal Hashtable Properties;
  260.             internal ArrayList ProviderData = new ArrayList();
  261.             // array of SinkProviderData structures
  262.             internal bool IsFormatter;
  263.             // Is this a formatter sink provider?
  264.             internal SinkProviderEntry(string typeName, string assemName, Hashtable properties, bool isFormatter)
  265.             {
  266.                 TypeName = typeName;
  267.                 AssemblyName = assemName;
  268.                 Properties = properties;
  269.                 IsFormatter = isFormatter;
  270.             }
  271.         }
  272.         // class SinkProviderEntry
  273.        
  274.         internal class TypeEntry
  275.         {
  276.             internal string TypeName;
  277.             internal string AssemblyName;
  278.             internal ArrayList ContextAttributes;
  279.            
  280.             internal TypeEntry(string typeName, string assemName, ArrayList contextAttributes)
  281.             {
  282.                 TypeName = typeName;
  283.                 AssemblyName = assemName;
  284.                 ContextAttributes = contextAttributes;
  285.             }
  286.         }
  287.         // class TypeEntry
  288.        
  289.         //
  290.         // end of configuration entry storage classes
  291.         //
  292.        
  293.        
  294.         //
  295.         // configuration data access
  296.         //
  297.        
  298.         internal string ApplicationName = null;
  299.         // application name
  300.         internal LifetimeEntry Lifetime = null;
  301.         // corresponds to top-level lifetime element
  302.         internal bool UrlObjRefMode = RemotingConfigHandler.UrlObjRefMode;
  303.         // should url obj ref's be used?
  304.         internal CustomErrorsEntry CustomErrors = null;
  305.        
  306.         internal ArrayList ChannelEntries = new ArrayList();
  307.         internal ArrayList InteropXmlElementEntries = new ArrayList();
  308.         internal ArrayList InteropXmlTypeEntries = new ArrayList();
  309.         internal ArrayList PreLoadEntries = new ArrayList();
  310.         internal ArrayList RemoteAppEntries = new ArrayList();
  311.         internal ArrayList ServerActivatedEntries = new ArrayList();
  312.         internal ArrayList ServerWellKnownEntries = new ArrayList();
  313.        
  314.        
  315.         //
  316.         // end of configuration data access
  317.         //
  318.        
  319.        
  320.         //
  321.         // modify configuration data (for multiple entry entities)
  322.         //
  323.        
  324.         internal void AddInteropXmlElementEntry(string xmlElementName, string xmlElementNamespace, string urtTypeName, string urtAssemblyName)
  325.         {
  326.             TryToLoadTypeIfApplicable(urtTypeName, urtAssemblyName);
  327.             InteropXmlElementEntry ixee = new InteropXmlElementEntry(xmlElementName, xmlElementNamespace, urtTypeName, urtAssemblyName);
  328.             InteropXmlElementEntries.Add(ixee);
  329.         }
  330.        
  331.         internal void AddInteropXmlTypeEntry(string xmlTypeName, string xmlTypeNamespace, string urtTypeName, string urtAssemblyName)
  332.         {
  333.             TryToLoadTypeIfApplicable(urtTypeName, urtAssemblyName);
  334.             InteropXmlTypeEntry ixte = new InteropXmlTypeEntry(xmlTypeName, xmlTypeNamespace, urtTypeName, urtAssemblyName);
  335.             InteropXmlTypeEntries.Add(ixte);
  336.         }
  337.        
  338.         internal void AddPreLoadEntry(string typeName, string assemblyName)
  339.         {
  340.             TryToLoadTypeIfApplicable(typeName, assemblyName);
  341.             PreLoadEntry ple = new PreLoadEntry(typeName, assemblyName);
  342.             PreLoadEntries.Add(ple);
  343.         }
  344.        
  345.         internal RemoteAppEntry AddRemoteAppEntry(string appUri)
  346.         {
  347.             RemoteAppEntry rae = new RemoteAppEntry(appUri);
  348.             RemoteAppEntries.Add(rae);
  349.             return rae;
  350.         }
  351.        
  352.         internal void AddServerActivatedEntry(string typeName, string assemName, ArrayList contextAttributes)
  353.         {
  354.             TryToLoadTypeIfApplicable(typeName, assemName);
  355.             TypeEntry te = new TypeEntry(typeName, assemName, contextAttributes);
  356.             ServerActivatedEntries.Add(te);
  357.         }
  358.        
  359.         internal ServerWellKnownEntry AddServerWellKnownEntry(string typeName, string assemName, ArrayList contextAttributes, string objURI, WellKnownObjectMode objMode)
  360.         {
  361.             TryToLoadTypeIfApplicable(typeName, assemName);
  362.             ServerWellKnownEntry swke = new ServerWellKnownEntry(typeName, assemName, contextAttributes, objURI, objMode);
  363.             ServerWellKnownEntries.Add(swke);
  364.             return swke;
  365.         }
  366.        
  367.        
  368.         // debug settings helper
  369.         private void TryToLoadTypeIfApplicable(string typeName, string assemblyName)
  370.         {
  371.             if (!LoadTypes)
  372.                 return;
  373.            
  374.             Assembly asm = Assembly.Load(assemblyName);
  375.             if (asm == null) {
  376.                 throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_AssemblyLoadFailed"), assemblyName));
  377.             }
  378.            
  379.             Type type = asm.GetType(typeName, false, false);
  380.             if (type == null) {
  381.                 throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"), typeName));
  382.             }
  383.         }
  384.        
  385.     }
  386.     // RemotingXmlConfigFileData
  387.    
  388.    
  389.    
  390.     static internal class RemotingXmlConfigFileParser
  391.     {
  392.         // template arrays
  393.         private static Hashtable _channelTemplates = CreateSyncCaseInsensitiveHashtable();
  394.         private static Hashtable _clientChannelSinkTemplates = CreateSyncCaseInsensitiveHashtable();
  395.         private static Hashtable _serverChannelSinkTemplates = CreateSyncCaseInsensitiveHashtable();
  396.        
  397.        
  398.         private static Hashtable CreateSyncCaseInsensitiveHashtable()
  399.         {
  400.             return Hashtable.Synchronized(CreateCaseInsensitiveHashtable());
  401.         }
  402.        
  403.         private static Hashtable CreateCaseInsensitiveHashtable()
  404.         {
  405.             return new Hashtable(StringComparer.InvariantCultureIgnoreCase);
  406.         }
  407.        
  408.        
  409.         public static RemotingXmlConfigFileData ParseDefaultConfiguration()
  410.         {
  411.             ConfigNode node;
  412.            
  413.             // <system.runtime.remoting>
  414.             ConfigNode rootNode = new ConfigNode("system.runtime.remoting", null);
  415.            
  416.             /*
  417.             <application>
  418.                 <channels>
  419.                     <channel ref="http client" displayName="http client (delay loaded)" delayLoadAsClientChannel="true" />
  420.                     <channel ref="tcp client" displayName="tcp client (delay loaded)" delayLoadAsClientChannel="true" />
  421.                     <channel ref="ipc client" displayName="ipc client (delay loaded)" delayLoadAsClientChannel="true" />
  422.                 </channels>
  423.             </application>
  424.             */           
  425. ConfigNode appNode = new ConfigNode("application", rootNode);
  426.             rootNode.Children.Add(appNode);
  427.            
  428.             ConfigNode channelsNode = new ConfigNode("channels", appNode);
  429.             appNode.Children.Add(channelsNode);
  430.            
  431.             node = new ConfigNode("channel", appNode);
  432.             node.Attributes.Add(new DictionaryEntry("ref", "http client"));
  433.             node.Attributes.Add(new DictionaryEntry("displayName", "http client (delay loaded)"));
  434.             node.Attributes.Add(new DictionaryEntry("delayLoadAsClientChannel", "true"));
  435.             channelsNode.Children.Add(node);
  436.            
  437.             node = new ConfigNode("channel", appNode);
  438.             node.Attributes.Add(new DictionaryEntry("ref", "tcp client"));
  439.             node.Attributes.Add(new DictionaryEntry("displayName", "tcp client (delay loaded)"));
  440.             node.Attributes.Add(new DictionaryEntry("delayLoadAsClientChannel", "true"));
  441.             channelsNode.Children.Add(node);
  442.            
  443.             node = new ConfigNode("channel", appNode);
  444.             node.Attributes.Add(new DictionaryEntry("ref", "ipc client"));
  445.             node.Attributes.Add(new DictionaryEntry("displayName", "ipc client (delay loaded)"));
  446.             node.Attributes.Add(new DictionaryEntry("delayLoadAsClientChannel", "true"));
  447.             channelsNode.Children.Add(node);
  448.            
  449.             /*
  450.             <channels>
  451.                 <channel id="http" type="System.Runtime.Remoting.Channels.Http.HttpChannel, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  452.                 <channel id="http client" type="System.Runtime.Remoting.Channels.Http.HttpClientChannel, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  453.                 <channel id="http server" type="System.Runtime.Remoting.Channels.Http.HttpServerChannel, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  454.                 <channel id="tcp" type="System.Runtime.Remoting.Channels.Tcp.TcpChannel, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  455.                 <channel id="tcp client" type="System.Runtime.Remoting.Channels.Tcp.TcpClientChannel, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  456.                 <channel id="tcp server" type="System.Runtime.Remoting.Channels.Tcp.TcpServerChannel, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  457.                 <channel id="ipc" type="System.Runtime.Remoting.Channels.Ipc.IpcChannel, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  458.                 <channel id="ipc client" type="System.Runtime.Remoting.Channels.Ipc.IpcClientChannel, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  459.                 <channel id="ipc server" type="System.Runtime.Remoting.Channels.Ipc.IpcServerChannel, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  460.             </channels>
  461.             */           
  462. channelsNode = new ConfigNode("channels", rootNode);
  463.             rootNode.Children.Add(channelsNode);
  464.            
  465.             node = new ConfigNode("channel", channelsNode);
  466.             node.Attributes.Add(new DictionaryEntry("id", "http"));
  467.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.Http.HttpChannel, " + AssemblyRef.SystemRuntimeRemoting));
  468.             channelsNode.Children.Add(node);
  469.            
  470.             node = new ConfigNode("channel", channelsNode);
  471.             node.Attributes.Add(new DictionaryEntry("id", "http client"));
  472.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.Http.HttpClientChannel, " + AssemblyRef.SystemRuntimeRemoting));
  473.             channelsNode.Children.Add(node);
  474.            
  475.             node = new ConfigNode("channel", channelsNode);
  476.             node.Attributes.Add(new DictionaryEntry("id", "http server"));
  477.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.Http.HttpServerChannel, " + AssemblyRef.SystemRuntimeRemoting));
  478.             channelsNode.Children.Add(node);
  479.            
  480.             node = new ConfigNode("channel", channelsNode);
  481.             node.Attributes.Add(new DictionaryEntry("id", "tcp"));
  482.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.Tcp.TcpChannel, " + AssemblyRef.SystemRuntimeRemoting));
  483.             channelsNode.Children.Add(node);
  484.            
  485.             node = new ConfigNode("channel", channelsNode);
  486.             node.Attributes.Add(new DictionaryEntry("id", "tcp client"));
  487.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.Tcp.TcpClientChannel, " + AssemblyRef.SystemRuntimeRemoting));
  488.             channelsNode.Children.Add(node);
  489.            
  490.             node = new ConfigNode("channel", channelsNode);
  491.             node.Attributes.Add(new DictionaryEntry("id", "tcp server"));
  492.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.Tcp.TcpServerChannel, " + AssemblyRef.SystemRuntimeRemoting));
  493.             channelsNode.Children.Add(node);
  494.            
  495.             node = new ConfigNode("channel", channelsNode);
  496.             node.Attributes.Add(new DictionaryEntry("id", "ipc"));
  497.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.Ipc.IpcChannel, " + AssemblyRef.SystemRuntimeRemoting));
  498.             channelsNode.Children.Add(node);
  499.            
  500.             node = new ConfigNode("channel", channelsNode);
  501.             node.Attributes.Add(new DictionaryEntry("id", "ipc client"));
  502.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.Ipc.IpcClientChannel, " + AssemblyRef.SystemRuntimeRemoting));
  503.             channelsNode.Children.Add(node);
  504.            
  505.             node = new ConfigNode("channel", channelsNode);
  506.             node.Attributes.Add(new DictionaryEntry("id", "ipc server"));
  507.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.Ipc.IpcServerChannel, " + AssemblyRef.SystemRuntimeRemoting));
  508.             channelsNode.Children.Add(node);
  509.            
  510.             /*
  511.             <channelSinkProviders>
  512.                 <clientProviders>
  513.                     <formatter id="soap" type="System.Runtime.Remoting.Channels.SoapClientFormatterSinkProvider, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  514.                     <formatter id="binary" type="System.Runtime.Remoting.Channels.BinaryClientFormatterSinkProvider, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  515.                 </clientProviders>
  516.                 <serverProviders>
  517.                     <formatter id="soap" type="System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  518.                     <formatter id="binary" type="System.Runtime.Remoting.Channels.BinaryServerFormatterSinkProvider, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  519.                     <provider id="wsdl" type="System.Runtime.Remoting.MetadataServices.SdlChannelSinkProvider, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  520.                 </serverProviders>
  521.             </channelSinkProviders>
  522.             */           
  523. ConfigNode channelsSinkNode = new ConfigNode("channelSinkProviders", rootNode);
  524.             rootNode.Children.Add(channelsSinkNode);
  525.            
  526.             ConfigNode clientProvidersNode = new ConfigNode("clientProviders", channelsSinkNode);
  527.             channelsSinkNode.Children.Add(clientProvidersNode);
  528.            
  529.             node = new ConfigNode("formatter", clientProvidersNode);
  530.             node.Attributes.Add(new DictionaryEntry("id", "soap"));
  531.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.SoapClientFormatterSinkProvider, " + AssemblyRef.SystemRuntimeRemoting));
  532.             clientProvidersNode.Children.Add(node);
  533.            
  534.             node = new ConfigNode("formatter", clientProvidersNode);
  535.             node.Attributes.Add(new DictionaryEntry("id", "binary"));
  536.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.BinaryClientFormatterSinkProvider, " + AssemblyRef.SystemRuntimeRemoting));
  537.             clientProvidersNode.Children.Add(node);
  538.            
  539.             ConfigNode serverProvidersNode = new ConfigNode("serverProviders", channelsSinkNode);
  540.             channelsSinkNode.Children.Add(serverProvidersNode);
  541.            
  542.             node = new ConfigNode("formatter", serverProvidersNode);
  543.             node.Attributes.Add(new DictionaryEntry("id", "soap"));
  544.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider, " + AssemblyRef.SystemRuntimeRemoting));
  545.             serverProvidersNode.Children.Add(node);
  546.            
  547.             node = new ConfigNode("formatter", serverProvidersNode);
  548.             node.Attributes.Add(new DictionaryEntry("id", "binary"));
  549.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.Channels.BinaryServerFormatterSinkProvider, " + AssemblyRef.SystemRuntimeRemoting));
  550.             serverProvidersNode.Children.Add(node);
  551.            
  552.             node = new ConfigNode("provider", serverProvidersNode);
  553.             node.Attributes.Add(new DictionaryEntry("id", "wsdl"));
  554.             node.Attributes.Add(new DictionaryEntry("type", "System.Runtime.Remoting.MetadataServices.SdlChannelSinkProvider, " + AssemblyRef.SystemRuntimeRemoting));
  555.             serverProvidersNode.Children.Add(node);
  556.            
  557.             return ParseConfigNode(rootNode);
  558.         }
  559.        
  560.        
  561.         [ResourceExposure(ResourceScope.Machine)]
  562.         [ResourceConsumption(ResourceScope.Machine)]
  563.         public static RemotingXmlConfigFileData ParseConfigFile(string filename)
  564.         {
  565.             ConfigTreeParser parser = new ConfigTreeParser();
  566.             ConfigNode rootNode = parser.Parse(filename, "/configuration/system.runtime.remoting");
  567.            
  568.             return ParseConfigNode(rootNode);
  569.         }
  570.        
  571.         private static RemotingXmlConfigFileData ParseConfigNode(ConfigNode rootNode)
  572.         {
  573.             RemotingXmlConfigFileData configData = new RemotingXmlConfigFileData();
  574.            
  575.             // check to see if this file has a system.runtime.remoting section
  576.             if (rootNode == null)
  577.                 return null;
  578.            
  579.             // process attributes
  580.             foreach (DictionaryEntry entry in rootNode.Attributes) {
  581.                 string key = entry.Key.ToString();
  582.                 switch (key) {
  583.                     case "version":
  584.                        
  585.                         {
  586.                             // we ignore the version attribute because this may be used
  587.                             // by the configuration system
  588.                             break;
  589.                         }
  590.                         break;
  591.                     default:
  592.                        
  593.                         break;
  594.                 }
  595.                 // switch
  596.             }
  597.             // foreach
  598.             ConfigNode appNode = null;
  599.             // "application" node
  600.             ConfigNode channelsNode = null;
  601.             // "channels" node
  602.             ConfigNode providerNode = null;
  603.             // "channelSinkProviders" node
  604.             ConfigNode debugNode = null;
  605.             // "debug" node
  606.             ConfigNode customErrorsNode = null;
  607.             // "customErrors" node
  608.             foreach (ConfigNode node in rootNode.Children) {
  609.                 switch (node.Name) {
  610.                     case "application":
  611.                        
  612.                        
  613.                         {
  614.                             // there can only be one application node in a config file
  615.                             if (appNode != null)
  616.                                 ReportUniqueSectionError(rootNode, appNode, configData);
  617.                            
  618.                             appNode = node;
  619.                             break;
  620.                         }
  621.                         break;
  622.                     case "channels":
  623.                         // case "application"
  624.                        
  625.                         {
  626.                             if (channelsNode != null)
  627.                                 ReportUniqueSectionError(rootNode, channelsNode, configData);
  628.                            
  629.                             channelsNode = node;
  630.                             break;
  631.                         }
  632.                         break;
  633.                     case "channelSinkProviders":
  634.                         // case "channels"
  635.                        
  636.                         {
  637.                             if (providerNode != null)
  638.                                 ReportUniqueSectionError(rootNode, providerNode, configData);
  639.                            
  640.                             providerNode = node;
  641.                             break;
  642.                         }
  643.                         break;
  644.                     case "debug":
  645.                         // case "channelSinkProviders"
  646.                        
  647.                         {
  648.                             if (debugNode != null)
  649.                                 ReportUniqueSectionError(rootNode, debugNode, configData);
  650.                            
  651.                             debugNode = node;
  652.                             break;
  653.                         }
  654.                         break;
  655.                     case "customErrors":
  656.                         // case "debug"
  657.                        
  658.                         {
  659.                             if (customErrorsNode != null)
  660.                                 ReportUniqueSectionError(rootNode, customErrorsNode, configData);
  661.                            
  662.                             customErrorsNode = node;
  663.                             break;
  664.                         }
  665.                         break;
  666.                     default:
  667.                         // case "customErrors"
  668.                         break;
  669.                 }
  670.                 // switch
  671.             }
  672.             // foreach
  673.            
  674.             if (debugNode != null)
  675.                 ProcessDebugNode(debugNode, configData);
  676.            
  677.             if (providerNode != null)
  678.                 ProcessChannelSinkProviderTemplates(providerNode, configData);
  679.            
  680.             if (channelsNode != null)
  681.                 ProcessChannelTemplates(channelsNode, configData);
  682.            
  683.             if (appNode != null)
  684.                 ProcessApplicationNode(appNode, configData);
  685.            
  686.             if (customErrorsNode != null)
  687.                 ProcessCustomErrorsNode(customErrorsNode, configData);
  688.            
  689.             return configData;
  690.         }
  691.         // ParseConfigFile
  692.        
  693.         private static void ReportError(string errorStr, RemotingXmlConfigFileData configData)
  694.         {
  695.            
  696.             throw new RemotingException(errorStr);
  697.         }
  698.         // ReportError
  699.         // means section must be unique
  700.         private static void ReportUniqueSectionError(ConfigNode parent, ConfigNode child, RemotingXmlConfigFileData configData)
  701.         {
  702.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_NodeMustBeUnique"), child.Name, parent.Name), configData);
  703.         }
  704.         // ReportUniqueSectionError
  705.         private static void ReportUnknownValueError(ConfigNode node, string value, RemotingXmlConfigFileData configData)
  706.         {
  707.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_UnknownValue"), node.Name, value), configData);
  708.         }
  709.         // ReportUnknownValueError
  710.         private static void ReportMissingAttributeError(ConfigNode node, string attributeName, RemotingXmlConfigFileData configData)
  711.         {
  712.             ReportMissingAttributeError(node.Name, attributeName, configData);
  713.         }
  714.         // ReportMissingAttributeError
  715.         private static void ReportMissingAttributeError(string nodeDescription, string attributeName, RemotingXmlConfigFileData configData)
  716.         {
  717.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_RequiredXmlAttribute"), nodeDescription, attributeName), configData);
  718.         }
  719.         // ReportMissingAttributeError
  720.         private static void ReportMissingTypeAttributeError(ConfigNode node, string attributeName, RemotingXmlConfigFileData configData)
  721.         {
  722.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_MissingTypeAttribute"), node.Name, attributeName), configData);
  723.         }
  724.         // ReportMissingAttributeError
  725.         private static void ReportMissingXmlTypeAttributeError(ConfigNode node, string attributeName, RemotingXmlConfigFileData configData)
  726.         {
  727.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_MissingXmlTypeAttribute"), node.Name, attributeName), configData);
  728.         }
  729.         // ReportMissingAttributeError
  730.         private static void ReportInvalidTimeFormatError(string time, RemotingXmlConfigFileData configData)
  731.         {
  732.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_InvalidTimeFormat"), time), configData);
  733.         }
  734.         // ReportInvalidTypeFormatError
  735.         // If nodes can be represented as a template, only a template version
  736.         // can have an 'id' attribute
  737.         private static void ReportNonTemplateIdAttributeError(ConfigNode node, RemotingXmlConfigFileData configData)
  738.         {
  739.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_NonTemplateIdAttribute"), node.Name), configData);
  740.         }
  741.         // ReportNonTemplateIdAttributeError
  742.         private static void ReportTemplateCannotReferenceTemplateError(ConfigNode node, RemotingXmlConfigFileData configData)
  743.         {
  744.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_TemplateCannotReferenceTemplate"), node.Name), configData);
  745.         }
  746.         // ReportTemplateCannotReferenceTemplateError
  747.         private static void ReportUnableToResolveTemplateReferenceError(ConfigNode node, string referenceName, RemotingXmlConfigFileData configData)
  748.         {
  749.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_UnableToResolveTemplate"), node.Name, referenceName), configData);
  750.         }
  751.         // ReportUnableToResolveTemplateReferenceError
  752.         private static void ReportAssemblyVersionInfoPresent(string assemName, string entryDescription, RemotingXmlConfigFileData configData)
  753.         {
  754.             // for some entries, version information is not allowed in the assembly name
  755.             ReportError(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Config_VersionPresent"), assemName, entryDescription), configData);
  756.         }
  757.         // ReportAssemblyVersionInfoPresent
  758.        
  759.         private static void ProcessDebugNode(ConfigNode node, RemotingXmlConfigFileData configData)
  760.         {
  761.             foreach (