ClientConfigurationHost.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Configuration / System / Configuration / ClientConfigurationHost.cs / 1305376 / ClientConfigurationHost.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Configuration { 
    using System.Configuration.Internal; 
    using System.IO;
    using System.Security.Policy; 
    using System.Security.Permissions;
    using System.Reflection;
    using System.Threading;
    using System.Security; 
    using System.Net;
    using System.Security.Principal; 
 
    internal sealed class ClientConfigurationHost : DelegatingConfigHost, IInternalConfigClientHost {
        internal const string MachineConfigName = "MACHINE"; 
        internal const string ExeConfigName = "EXE";
        internal const string RoamingUserConfigName = "ROAMING_USER";
        internal const string LocalUserConfigName = "LOCAL_USER";
 
        internal const string MachineConfigPath = MachineConfigName;
        internal const string ExeConfigPath = MachineConfigPath + "/" + ExeConfigName; 
        internal const string RoamingUserConfigPath = ExeConfigPath + "/" + RoamingUserConfigName; 
        internal const string LocalUserConfigPath = RoamingUserConfigPath + "/" + LocalUserConfigName;
 
        private const string ConfigExtension = ".config";
        private const string MachineConfigFilename = "machine.config";
        private const string MachineConfigSubdirectory = "Config";
 
        private static object                   s_init = new object();
        private static object                   s_version = new object(); 
        private static string                   s_machineConfigFilePath; 

        private string                          _exePath;       // the physical path to the exe being configured 
        private ClientConfigPaths               _configPaths;   // physical paths to client config files
        private ExeConfigurationFileMap         _fileMap;       // optional file map
        private bool                            _initComplete;
 
        internal ClientConfigurationHost() {
            Host = new InternalConfigHost(); 
        } 

        internal ClientConfigPaths ConfigPaths { 
            get {
                if (_configPaths == null) {
                    _configPaths = ClientConfigPaths.GetPaths(_exePath, _initComplete);
                } 

                return _configPaths; 
            } 
        }
 
        internal void RefreshConfigPaths() {
            // Refresh current config paths.
            if (_configPaths != null && !_configPaths.HasEntryAssembly && _exePath == null) {
                ClientConfigPaths.RefreshCurrent(); 
                _configPaths = null;
            } 
        } 

        static internal string MachineConfigFilePath { 
            [FileIOPermissionAttribute(SecurityAction.Assert, AllFiles=FileIOPermissionAccess.PathDiscovery)]
            get {
                if (s_machineConfigFilePath == null) {
                    string directory = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); 
                    s_machineConfigFilePath = Path.Combine(Path.Combine(directory, MachineConfigSubdirectory), MachineConfigFilename);
                } 
 
                return s_machineConfigFilePath;
            } 
        }

        internal bool HasRoamingConfig {
            get { 
                if (_fileMap != null) {
                    return !String.IsNullOrEmpty(_fileMap.RoamingUserConfigFilename); 
                } 
                else {
                    return ConfigPaths.HasRoamingConfig; 
                }
            }
        }
 
        internal bool HasLocalConfig {
            get { 
                if (_fileMap != null) { 
                    return !String.IsNullOrEmpty(_fileMap.LocalUserConfigFilename);
                } 
                else {
                    return ConfigPaths.HasLocalConfig;
                }
            } 
        }
 
        internal bool IsAppConfigHttp { 
            get {
                return !IsFile(GetStreamName(ExeConfigPath)); 
            }
        }

        // IInternalConfigClientHost methods are used by Venus and Whitehorse 
        // so as not to require explicit knowledge of the contents of the
        // config path. 
 
        // return true if the config path is for an exe config, false otherwise.
        bool IInternalConfigClientHost.IsExeConfig(string configPath) { 
            return StringUtil.EqualsIgnoreCase(configPath, ExeConfigPath);
        }

        bool IInternalConfigClientHost.IsRoamingUserConfig(string configPath) { 
            return StringUtil.EqualsIgnoreCase(configPath, RoamingUserConfigPath);
        } 
 
        bool IInternalConfigClientHost.IsLocalUserConfig(string configPath) {
            return StringUtil.EqualsIgnoreCase(configPath, LocalUserConfigPath); 
        }

        // Return true if the config path is for a user.config file, false otherwise.
        private bool IsUserConfig(string configPath) { 
            return StringUtil.EqualsIgnoreCase(configPath, RoamingUserConfigPath) ||
                   StringUtil.EqualsIgnoreCase(configPath, LocalUserConfigPath); 
        } 

        string IInternalConfigClientHost.GetExeConfigPath() { 
            return ExeConfigPath;
        }

        string IInternalConfigClientHost.GetRoamingUserConfigPath() { 
            return RoamingUserConfigPath;
        } 
 
        string IInternalConfigClientHost.GetLocalUserConfigPath() {
            return LocalUserConfigPath; 
        }

        public override void Init(IInternalConfigRoot configRoot, params object[] hostInitParams) {
            try { 
                ConfigurationFileMap fileMap = (ConfigurationFileMap)   hostInitParams[0];
                _exePath = (string)                                     hostInitParams[1]; 
 
                Host.Init(configRoot, hostInitParams);
 
                // Do not complete initialization in runtime config, to avoid expense of
                // loading user.config files that may not be required.
                _initComplete = configRoot.IsDesignTime;
 
                if (fileMap != null && !String.IsNullOrEmpty(_exePath)) {
                    throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::Init"); 
                } 

                if (String.IsNullOrEmpty(_exePath)) { 
                    _exePath = null;
                }

                // Initialize the fileMap, if provided. 
                if (fileMap != null) {
                    _fileMap = new ExeConfigurationFileMap(); 
                    if (!String.IsNullOrEmpty(fileMap.MachineConfigFilename)) { 
                        _fileMap.MachineConfigFilename = Path.GetFullPath(fileMap.MachineConfigFilename);
                    } 

                    ExeConfigurationFileMap exeFileMap = fileMap as ExeConfigurationFileMap;
                    if (exeFileMap != null) {
                        if (!String.IsNullOrEmpty(exeFileMap.ExeConfigFilename)) { 
                            _fileMap.ExeConfigFilename = Path.GetFullPath(exeFileMap.ExeConfigFilename);
                        } 
 
                        if (!String.IsNullOrEmpty(exeFileMap.RoamingUserConfigFilename)) {
                            _fileMap.RoamingUserConfigFilename = Path.GetFullPath(exeFileMap.RoamingUserConfigFilename); 
                        }

                        if (!String.IsNullOrEmpty(exeFileMap.LocalUserConfigFilename)) {
                            _fileMap.LocalUserConfigFilename = Path.GetFullPath(exeFileMap.LocalUserConfigFilename); 
                        }
                    } 
                } 
            }
            catch (SecurityException) { 
                // Lets try to give them some information telling them
                // they don't have enough security privileges
                throw new ConfigurationErrorsException(
                    SR.GetString(SR.Config_client_config_init_security)); 
            }
            catch { 
                throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::Init"); 
            }
        } 

        public override void InitForConfiguration(ref string locationSubPath, out string configPath, out string locationConfigPath,
                IInternalConfigRoot configRoot, params object[] hostInitConfigurationParams) {
 
            locationSubPath = null;
            configPath = (string) hostInitConfigurationParams[2]; 
            locationConfigPath = null; 

            Init(configRoot, hostInitConfigurationParams); 
        }

        // Delay init if we have not been asked to complete init, and it is a user.config file.
        public override bool IsInitDelayed(IInternalConfigRecord configRecord) { 
            return !_initComplete && IsUserConfig(configRecord.ConfigPath);
        } 
 
        public override void RequireCompleteInit(IInternalConfigRecord record) {
            // Loading information about user.config files is expensive, 
            // so do it just once by locking.
            lock (this) {
                if (!_initComplete) {
                    // Note that all future requests for config must be complete. 
                    _initComplete = true;
 
                    // Throw out the ConfigPath for this exe. 
                    ClientConfigPaths.RefreshCurrent();
 
                    // Throw out our cached copy.
                    _configPaths = null;

                    // Force loading of user.config file information under lock. 
                    ClientConfigPaths configPaths = ConfigPaths;
                } 
            } 
        }
 
        // config path support
        public override bool IsConfigRecordRequired(string configPath) {
            string configName = ConfigPathUtility.GetName(configPath);
            switch (configName) { 
                default:
                    // should never get here 
                    return false; 

                case MachineConfigName: 
                case ExeConfigName:
                    return true;

                case RoamingUserConfigName: 
                    // Makes the design easier even if we only have an empty Roaming config record.
                    return HasRoamingConfig || HasLocalConfig; 
 
                case LocalUserConfigName:
                    return HasLocalConfig; 
            }
        }

        // stream support 
        public override string GetStreamName(string configPath) {
            string configName = ConfigPathUtility.GetName(configPath); 
            if (_fileMap != null) { 
                switch (configName) {
                    default: 
                        // should never get here
                        goto case MachineConfigName;

                    case MachineConfigName: 
                        return _fileMap.MachineConfigFilename;
 
                    case ExeConfigName: 
                        return _fileMap.ExeConfigFilename;
 
                    case RoamingUserConfigName:
                        return _fileMap.RoamingUserConfigFilename;

                    case LocalUserConfigName: 
                        return _fileMap.LocalUserConfigFilename;
                } 
            } 
            else {
                switch (configName) { 
                    default:
                        // should never get here
                        goto case MachineConfigName;
 
                    case MachineConfigName:
                        return MachineConfigFilePath; 
 
                    case ExeConfigName:
                        return ConfigPaths.ApplicationConfigUri; 

                    case RoamingUserConfigName:
                        return ConfigPaths.RoamingConfigFilename;
 
                    case LocalUserConfigName:
                        return ConfigPaths.LocalConfigFilename; 
                } 
            }
        } 

        public override string GetStreamNameForConfigSource(string streamName, string configSource) {
            if (IsFile(streamName)) {
                return Host.GetStreamNameForConfigSource(streamName, configSource); 
            }
 
            int index = streamName.LastIndexOf('/'); 
            if (index < 0)
                return null; 

            string parentUri = streamName.Substring(0, index + 1);
            string result = parentUri + configSource.Replace('\\', '/');
 
            return result;
        } 
 
        public override object GetStreamVersion(string streamName) {
            if (IsFile(streamName)) { 
                return Host.GetStreamVersion(streamName);
            }

            // assume it is the same 
            return s_version;
        } 
 

        // default impl treats name as a file name 
        // null means stream doesn't exist for this name
        public override Stream OpenStreamForRead(string streamName) {
            // the streamName can either be a file name, or a URI
            if (IsFile(streamName)) { 
                return Host.OpenStreamForRead(streamName);
            } 
 
            if (streamName == null) {
                return null; 
            }

            // scheme is http
            WebClient client = new WebClient(); 

            // Try using default credentials 
            try { 
                client.Credentials = CredentialCache.DefaultCredentials;
            } 
            catch {
            }

            byte[] fileData = null; 
            try {
                fileData = client.DownloadData(streamName); 
            } 
            catch {
            } 

            if (fileData == null) {
                return null;
            } 

            MemoryStream stream = new MemoryStream(fileData); 
            return stream; 
        }
 
        public override Stream OpenStreamForWrite(string streamName, string templateStreamName, ref object writeContext) {
            // only support files, not URIs
            if (!IsFile(streamName)) {
                throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::OpenStreamForWrite"); 
            }
 
            return Host.OpenStreamForWrite(streamName, templateStreamName, ref writeContext); 
        }
 
        public override void DeleteStream(string streamName) {
            // only support files, not URIs
            if (!IsFile(streamName)) {
                throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::Delete"); 
            }
 
            Host.DeleteStream(streamName); 
        }
 
        // RefreshConfig support - runtime only
        public override bool SupportsRefresh {
            get {return true;}
        } 

        // path support 
        public override bool SupportsPath { 
            get {return false;}
        } 

        // Do we support location tags?
        public override bool SupportsLocation {
            get {return false;} 
        }
 
        public override bool IsDefinitionAllowed(string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition) { 
            string allowedConfigPath;
 
            switch (allowExeDefinition) {
                case ConfigurationAllowExeDefinition.MachineOnly:
                    allowedConfigPath = MachineConfigPath;
                    break; 

                case ConfigurationAllowExeDefinition.MachineToApplication: 
                    allowedConfigPath = ExeConfigPath; 
                    break;
 
                case ConfigurationAllowExeDefinition.MachineToRoamingUser:
                    allowedConfigPath = RoamingUserConfigPath;
                    break;
 
                // MachineToLocalUser does not current have any definition restrictions
                case ConfigurationAllowExeDefinition.MachineToLocalUser: 
                    return true; 

                default: 
                    // If we have extended ConfigurationAllowExeDefinition
                    // make sure to update this switch accordingly
                    throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::IsDefinitionAllowed");
            } 

            return configPath.Length <= allowedConfigPath.Length; 
        } 

        public override void VerifyDefinitionAllowed(string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo) { 
            if (!IsDefinitionAllowed(configPath, allowDefinition, allowExeDefinition)) {
                switch (allowExeDefinition) {
                    case ConfigurationAllowExeDefinition.MachineOnly:
                        throw new ConfigurationErrorsException( 
                            SR.GetString(SR.Config_allow_exedefinition_error_machine), errorInfo);
 
                    case ConfigurationAllowExeDefinition.MachineToApplication: 
                        throw new ConfigurationErrorsException(
                            SR.GetString(SR.Config_allow_exedefinition_error_application), errorInfo); 

                    case ConfigurationAllowExeDefinition.MachineToRoamingUser:
                        throw new ConfigurationErrorsException(
                            SR.GetString(SR.Config_allow_exedefinition_error_roaminguser), errorInfo); 

                    default: 
                        // If we have extended ConfigurationAllowExeDefinition 
                        // make sure to update this switch accordingly
                        throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::VerifyDefinitionAllowed"); 
                }
            }
        }
 
        // prefetch support
        public override bool PrefetchAll(string configPath, string streamName) { 
            // If it's a file, we don't need to.  Otherwise (e.g. it's from the web), we'll prefetch everything. 
            return !IsFile(streamName);
        } 

        public override bool PrefetchSection(string sectionGroupName, string sectionName) {
            return sectionGroupName == "system.net";
        } 

        // we trust machine.config - admins settings do not have security restrictions. 
        public override bool IsTrustedConfigPath(string configPath) { 
            return configPath == MachineConfigPath;
        } 

        [SecurityPermission(SecurityAction.Assert, ControlEvidence=true)]
        public override void GetRestrictedPermissions(IInternalConfigRecord configRecord, out PermissionSet permissionSet, out bool isHostReady) {
            // Get the stream name as a URL 
            string url;
            bool isFile = IsFile(configRecord.StreamName); 
            if (isFile) { 
                url = UrlPath.ConvertFileNameToUrl(configRecord.StreamName);
            } 
            else {
                url = configRecord.StreamName;
            }
 
            Evidence evidence = new Evidence();
 
            // Add Url evidence, which is simply the URL. 
            evidence.AddHostEvidence(new Url(url));
 
            // Add Zone evidence - My Computer, Intranet, Internet, etc.
            evidence.AddHostEvidence(Zone.CreateFromUrl(url));

            // Add Site evidence if the url is http. 
            if (!isFile) {
                evidence.AddHostEvidence(Site.CreateFromUrl(url)); 
            } 

            // Get the resulting permission set. 
            permissionSet = SecurityManager.GetStandardSandbox(evidence);

            // Client host is always ready to return permissions.
            isHostReady = true; 
        }
 
        // 
 	// Impersonate for Client Config
        // Use the process identity 
        //
        [SecurityPermissionAttribute(SecurityAction.Assert, Flags=SecurityPermissionFlag.ControlPrincipal | SecurityPermissionFlag.UnmanagedCode)]
        public override IDisposable Impersonate() {
            // Use the process identity 
            return WindowsIdentity.Impersonate(IntPtr.Zero);
        } 
 
	// context support
        public override object CreateDeprecatedConfigContext(string configPath) { 
            return null;
        }

        // CreateConfigurationContext 
        //
        // Create the new context 
        // 
        public override object
        CreateConfigurationContext( string configPath, 
                                    string locationSubPath )
        {
            return new ExeContext(GetUserLevel(configPath), ConfigPaths.ApplicationUri);
        } 

        // GetUserLevel 
        // 
        // Given a configPath, determine what the user level is?
        // 
        private ConfigurationUserLevel GetUserLevel(string configPath)
        {
            ConfigurationUserLevel level;
 
            switch (ConfigPathUtility.GetName(configPath)) {
                case MachineConfigName: 
                    // Machine Level 
                    level = ConfigurationUserLevel.None;
                    break; 

                case ExeConfigName:
                    // Exe Level
                    level = ConfigurationUserLevel.None; 
                    break;
 
                case LocalUserConfigName: 
                    // User Level
                    level = ConfigurationUserLevel.PerUserRoamingAndLocal; 
                    break;

                case RoamingUserConfigName:
                    // Roaming Level 
                    level = ConfigurationUserLevel.PerUserRoaming;
                    break; 
 
                default:
                    Debug.Fail("unrecognized configPath " + configPath); 
                    level = ConfigurationUserLevel.None;
                    break;
            }
 
            return level;
        } 
 
        //
        // Create a Configuration object. 
        //
        static internal Configuration OpenExeConfiguration(ConfigurationFileMap fileMap, bool isMachine, ConfigurationUserLevel userLevel, string exePath) {
            // validate userLevel argument
            switch (userLevel) { 
                default:
                    throw ExceptionUtil.ParameterInvalid("userLevel"); 
 
                case ConfigurationUserLevel.None:
                case ConfigurationUserLevel.PerUserRoaming: 
                case ConfigurationUserLevel.PerUserRoamingAndLocal:
                    break;
            }
 
            // validate fileMap arguments
            if (fileMap != null) { 
                if (String.IsNullOrEmpty(fileMap.MachineConfigFilename)) { 
                    throw ExceptionUtil.ParameterNullOrEmpty("fileMap.MachineConfigFilename");
                } 

                ExeConfigurationFileMap exeFileMap = fileMap as ExeConfigurationFileMap;
                if (exeFileMap != null) {
                    switch (userLevel) { 
                        case ConfigurationUserLevel.None:
                            if (String.IsNullOrEmpty(exeFileMap.ExeConfigFilename)) { 
                                throw ExceptionUtil.ParameterNullOrEmpty("fileMap.ExeConfigFilename"); 
                            }
 
                            break;

                        case ConfigurationUserLevel.PerUserRoaming:
                            if (String.IsNullOrEmpty(exeFileMap.RoamingUserConfigFilename)) { 
                                throw ExceptionUtil.ParameterNullOrEmpty("fileMap.RoamingUserConfigFilename");
                            } 
 
                            goto case ConfigurationUserLevel.None;
 
                        case ConfigurationUserLevel.PerUserRoamingAndLocal:
                            if (String.IsNullOrEmpty(exeFileMap.LocalUserConfigFilename)) {
                                throw ExceptionUtil.ParameterNullOrEmpty("fileMap.LocalUserConfigFilename");
                            } 

                            goto case ConfigurationUserLevel.PerUserRoaming; 
                    } 
                }
            } 

            string configPath = null;
            if (isMachine) {
                configPath = MachineConfigPath; 
            }
            else { 
                switch (userLevel) { 
                    case ConfigurationUserLevel.None:
                        configPath = ExeConfigPath; 
                        break;

                    case ConfigurationUserLevel.PerUserRoaming:
                        configPath = RoamingUserConfigPath; 
                        break;
 
                    case ConfigurationUserLevel.PerUserRoamingAndLocal: 
                        configPath = LocalUserConfigPath;
                        break; 
                }
            }

            Configuration configuration = new Configuration(null, typeof(ClientConfigurationHost), fileMap, exePath, configPath); 

            return configuration; 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Configuration { 
    using System.Configuration.Internal; 
    using System.IO;
    using System.Security.Policy; 
    using System.Security.Permissions;
    using System.Reflection;
    using System.Threading;
    using System.Security; 
    using System.Net;
    using System.Security.Principal; 
 
    internal sealed class ClientConfigurationHost : DelegatingConfigHost, IInternalConfigClientHost {
        internal const string MachineConfigName = "MACHINE"; 
        internal const string ExeConfigName = "EXE";
        internal const string RoamingUserConfigName = "ROAMING_USER";
        internal const string LocalUserConfigName = "LOCAL_USER";
 
        internal const string MachineConfigPath = MachineConfigName;
        internal const string ExeConfigPath = MachineConfigPath + "/" + ExeConfigName; 
        internal const string RoamingUserConfigPath = ExeConfigPath + "/" + RoamingUserConfigName; 
        internal const string LocalUserConfigPath = RoamingUserConfigPath + "/" + LocalUserConfigName;
 
        private const string ConfigExtension = ".config";
        private const string MachineConfigFilename = "machine.config";
        private const string MachineConfigSubdirectory = "Config";
 
        private static object                   s_init = new object();
        private static object                   s_version = new object(); 
        private static string                   s_machineConfigFilePath; 

        private string                          _exePath;       // the physical path to the exe being configured 
        private ClientConfigPaths               _configPaths;   // physical paths to client config files
        private ExeConfigurationFileMap         _fileMap;       // optional file map
        private bool                            _initComplete;
 
        internal ClientConfigurationHost() {
            Host = new InternalConfigHost(); 
        } 

        internal ClientConfigPaths ConfigPaths { 
            get {
                if (_configPaths == null) {
                    _configPaths = ClientConfigPaths.GetPaths(_exePath, _initComplete);
                } 

                return _configPaths; 
            } 
        }
 
        internal void RefreshConfigPaths() {
            // Refresh current config paths.
            if (_configPaths != null && !_configPaths.HasEntryAssembly && _exePath == null) {
                ClientConfigPaths.RefreshCurrent(); 
                _configPaths = null;
            } 
        } 

        static internal string MachineConfigFilePath { 
            [FileIOPermissionAttribute(SecurityAction.Assert, AllFiles=FileIOPermissionAccess.PathDiscovery)]
            get {
                if (s_machineConfigFilePath == null) {
                    string directory = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); 
                    s_machineConfigFilePath = Path.Combine(Path.Combine(directory, MachineConfigSubdirectory), MachineConfigFilename);
                } 
 
                return s_machineConfigFilePath;
            } 
        }

        internal bool HasRoamingConfig {
            get { 
                if (_fileMap != null) {
                    return !String.IsNullOrEmpty(_fileMap.RoamingUserConfigFilename); 
                } 
                else {
                    return ConfigPaths.HasRoamingConfig; 
                }
            }
        }
 
        internal bool HasLocalConfig {
            get { 
                if (_fileMap != null) { 
                    return !String.IsNullOrEmpty(_fileMap.LocalUserConfigFilename);
                } 
                else {
                    return ConfigPaths.HasLocalConfig;
                }
            } 
        }
 
        internal bool IsAppConfigHttp { 
            get {
                return !IsFile(GetStreamName(ExeConfigPath)); 
            }
        }

        // IInternalConfigClientHost methods are used by Venus and Whitehorse 
        // so as not to require explicit knowledge of the contents of the
        // config path. 
 
        // return true if the config path is for an exe config, false otherwise.
        bool IInternalConfigClientHost.IsExeConfig(string configPath) { 
            return StringUtil.EqualsIgnoreCase(configPath, ExeConfigPath);
        }

        bool IInternalConfigClientHost.IsRoamingUserConfig(string configPath) { 
            return StringUtil.EqualsIgnoreCase(configPath, RoamingUserConfigPath);
        } 
 
        bool IInternalConfigClientHost.IsLocalUserConfig(string configPath) {
            return StringUtil.EqualsIgnoreCase(configPath, LocalUserConfigPath); 
        }

        // Return true if the config path is for a user.config file, false otherwise.
        private bool IsUserConfig(string configPath) { 
            return StringUtil.EqualsIgnoreCase(configPath, RoamingUserConfigPath) ||
                   StringUtil.EqualsIgnoreCase(configPath, LocalUserConfigPath); 
        } 

        string IInternalConfigClientHost.GetExeConfigPath() { 
            return ExeConfigPath;
        }

        string IInternalConfigClientHost.GetRoamingUserConfigPath() { 
            return RoamingUserConfigPath;
        } 
 
        string IInternalConfigClientHost.GetLocalUserConfigPath() {
            return LocalUserConfigPath; 
        }

        public override void Init(IInternalConfigRoot configRoot, params object[] hostInitParams) {
            try { 
                ConfigurationFileMap fileMap = (ConfigurationFileMap)   hostInitParams[0];
                _exePath = (string)                                     hostInitParams[1]; 
 
                Host.Init(configRoot, hostInitParams);
 
                // Do not complete initialization in runtime config, to avoid expense of
                // loading user.config files that may not be required.
                _initComplete = configRoot.IsDesignTime;
 
                if (fileMap != null && !String.IsNullOrEmpty(_exePath)) {
                    throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::Init"); 
                } 

                if (String.IsNullOrEmpty(_exePath)) { 
                    _exePath = null;
                }

                // Initialize the fileMap, if provided. 
                if (fileMap != null) {
                    _fileMap = new ExeConfigurationFileMap(); 
                    if (!String.IsNullOrEmpty(fileMap.MachineConfigFilename)) { 
                        _fileMap.MachineConfigFilename = Path.GetFullPath(fileMap.MachineConfigFilename);
                    } 

                    ExeConfigurationFileMap exeFileMap = fileMap as ExeConfigurationFileMap;
                    if (exeFileMap != null) {
                        if (!String.IsNullOrEmpty(exeFileMap.ExeConfigFilename)) { 
                            _fileMap.ExeConfigFilename = Path.GetFullPath(exeFileMap.ExeConfigFilename);
                        } 
 
                        if (!String.IsNullOrEmpty(exeFileMap.RoamingUserConfigFilename)) {
                            _fileMap.RoamingUserConfigFilename = Path.GetFullPath(exeFileMap.RoamingUserConfigFilename); 
                        }

                        if (!String.IsNullOrEmpty(exeFileMap.LocalUserConfigFilename)) {
                            _fileMap.LocalUserConfigFilename = Path.GetFullPath(exeFileMap.LocalUserConfigFilename); 
                        }
                    } 
                } 
            }
            catch (SecurityException) { 
                // Lets try to give them some information telling them
                // they don't have enough security privileges
                throw new ConfigurationErrorsException(
                    SR.GetString(SR.Config_client_config_init_security)); 
            }
            catch { 
                throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::Init"); 
            }
        } 

        public override void InitForConfiguration(ref string locationSubPath, out string configPath, out string locationConfigPath,
                IInternalConfigRoot configRoot, params object[] hostInitConfigurationParams) {
 
            locationSubPath = null;
            configPath = (string) hostInitConfigurationParams[2]; 
            locationConfigPath = null; 

            Init(configRoot, hostInitConfigurationParams); 
        }

        // Delay init if we have not been asked to complete init, and it is a user.config file.
        public override bool IsInitDelayed(IInternalConfigRecord configRecord) { 
            return !_initComplete && IsUserConfig(configRecord.ConfigPath);
        } 
 
        public override void RequireCompleteInit(IInternalConfigRecord record) {
            // Loading information about user.config files is expensive, 
            // so do it just once by locking.
            lock (this) {
                if (!_initComplete) {
                    // Note that all future requests for config must be complete. 
                    _initComplete = true;
 
                    // Throw out the ConfigPath for this exe. 
                    ClientConfigPaths.RefreshCurrent();
 
                    // Throw out our cached copy.
                    _configPaths = null;

                    // Force loading of user.config file information under lock. 
                    ClientConfigPaths configPaths = ConfigPaths;
                } 
            } 
        }
 
        // config path support
        public override bool IsConfigRecordRequired(string configPath) {
            string configName = ConfigPathUtility.GetName(configPath);
            switch (configName) { 
                default:
                    // should never get here 
                    return false; 

                case MachineConfigName: 
                case ExeConfigName:
                    return true;

                case RoamingUserConfigName: 
                    // Makes the design easier even if we only have an empty Roaming config record.
                    return HasRoamingConfig || HasLocalConfig; 
 
                case LocalUserConfigName:
                    return HasLocalConfig; 
            }
        }

        // stream support 
        public override string GetStreamName(string configPath) {
            string configName = ConfigPathUtility.GetName(configPath); 
            if (_fileMap != null) { 
                switch (configName) {
                    default: 
                        // should never get here
                        goto case MachineConfigName;

                    case MachineConfigName: 
                        return _fileMap.MachineConfigFilename;
 
                    case ExeConfigName: 
                        return _fileMap.ExeConfigFilename;
 
                    case RoamingUserConfigName:
                        return _fileMap.RoamingUserConfigFilename;

                    case LocalUserConfigName: 
                        return _fileMap.LocalUserConfigFilename;
                } 
            } 
            else {
                switch (configName) { 
                    default:
                        // should never get here
                        goto case MachineConfigName;
 
                    case MachineConfigName:
                        return MachineConfigFilePath; 
 
                    case ExeConfigName:
                        return ConfigPaths.ApplicationConfigUri; 

                    case RoamingUserConfigName:
                        return ConfigPaths.RoamingConfigFilename;
 
                    case LocalUserConfigName:
                        return ConfigPaths.LocalConfigFilename; 
                } 
            }
        } 

        public override string GetStreamNameForConfigSource(string streamName, string configSource) {
            if (IsFile(streamName)) {
                return Host.GetStreamNameForConfigSource(streamName, configSource); 
            }
 
            int index = streamName.LastIndexOf('/'); 
            if (index < 0)
                return null; 

            string parentUri = streamName.Substring(0, index + 1);
            string result = parentUri + configSource.Replace('\\', '/');
 
            return result;
        } 
 
        public override object GetStreamVersion(string streamName) {
            if (IsFile(streamName)) { 
                return Host.GetStreamVersion(streamName);
            }

            // assume it is the same 
            return s_version;
        } 
 

        // default impl treats name as a file name 
        // null means stream doesn't exist for this name
        public override Stream OpenStreamForRead(string streamName) {
            // the streamName can either be a file name, or a URI
            if (IsFile(streamName)) { 
                return Host.OpenStreamForRead(streamName);
            } 
 
            if (streamName == null) {
                return null; 
            }

            // scheme is http
            WebClient client = new WebClient(); 

            // Try using default credentials 
            try { 
                client.Credentials = CredentialCache.DefaultCredentials;
            } 
            catch {
            }

            byte[] fileData = null; 
            try {
                fileData = client.DownloadData(streamName); 
            } 
            catch {
            } 

            if (fileData == null) {
                return null;
            } 

            MemoryStream stream = new MemoryStream(fileData); 
            return stream; 
        }
 
        public override Stream OpenStreamForWrite(string streamName, string templateStreamName, ref object writeContext) {
            // only support files, not URIs
            if (!IsFile(streamName)) {
                throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::OpenStreamForWrite"); 
            }
 
            return Host.OpenStreamForWrite(streamName, templateStreamName, ref writeContext); 
        }
 
        public override void DeleteStream(string streamName) {
            // only support files, not URIs
            if (!IsFile(streamName)) {
                throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::Delete"); 
            }
 
            Host.DeleteStream(streamName); 
        }
 
        // RefreshConfig support - runtime only
        public override bool SupportsRefresh {
            get {return true;}
        } 

        // path support 
        public override bool SupportsPath { 
            get {return false;}
        } 

        // Do we support location tags?
        public override bool SupportsLocation {
            get {return false;} 
        }
 
        public override bool IsDefinitionAllowed(string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition) { 
            string allowedConfigPath;
 
            switch (allowExeDefinition) {
                case ConfigurationAllowExeDefinition.MachineOnly:
                    allowedConfigPath = MachineConfigPath;
                    break; 

                case ConfigurationAllowExeDefinition.MachineToApplication: 
                    allowedConfigPath = ExeConfigPath; 
                    break;
 
                case ConfigurationAllowExeDefinition.MachineToRoamingUser:
                    allowedConfigPath = RoamingUserConfigPath;
                    break;
 
                // MachineToLocalUser does not current have any definition restrictions
                case ConfigurationAllowExeDefinition.MachineToLocalUser: 
                    return true; 

                default: 
                    // If we have extended ConfigurationAllowExeDefinition
                    // make sure to update this switch accordingly
                    throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::IsDefinitionAllowed");
            } 

            return configPath.Length <= allowedConfigPath.Length; 
        } 

        public override void VerifyDefinitionAllowed(string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo) { 
            if (!IsDefinitionAllowed(configPath, allowDefinition, allowExeDefinition)) {
                switch (allowExeDefinition) {
                    case ConfigurationAllowExeDefinition.MachineOnly:
                        throw new ConfigurationErrorsException( 
                            SR.GetString(SR.Config_allow_exedefinition_error_machine), errorInfo);
 
                    case ConfigurationAllowExeDefinition.MachineToApplication: 
                        throw new ConfigurationErrorsException(
                            SR.GetString(SR.Config_allow_exedefinition_error_application), errorInfo); 

                    case ConfigurationAllowExeDefinition.MachineToRoamingUser:
                        throw new ConfigurationErrorsException(
                            SR.GetString(SR.Config_allow_exedefinition_error_roaminguser), errorInfo); 

                    default: 
                        // If we have extended ConfigurationAllowExeDefinition 
                        // make sure to update this switch accordingly
                        throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::VerifyDefinitionAllowed"); 
                }
            }
        }
 
        // prefetch support
        public override bool PrefetchAll(string configPath, string streamName) { 
            // If it's a file, we don't need to.  Otherwise (e.g. it's from the web), we'll prefetch everything. 
            return !IsFile(streamName);
        } 

        public override bool PrefetchSection(string sectionGroupName, string sectionName) {
            return sectionGroupName == "system.net";
        } 

        // we trust machine.config - admins settings do not have security restrictions. 
        public override bool IsTrustedConfigPath(string configPath) { 
            return configPath == MachineConfigPath;
        } 

        [SecurityPermission(SecurityAction.Assert, ControlEvidence=true)]
        public override void GetRestrictedPermissions(IInternalConfigRecord configRecord, out PermissionSet permissionSet, out bool isHostReady) {
            // Get the stream name as a URL 
            string url;
            bool isFile = IsFile(configRecord.StreamName); 
            if (isFile) { 
                url = UrlPath.ConvertFileNameToUrl(configRecord.StreamName);
            } 
            else {
                url = configRecord.StreamName;
            }
 
            Evidence evidence = new Evidence();
 
            // Add Url evidence, which is simply the URL. 
            evidence.AddHostEvidence(new Url(url));
 
            // Add Zone evidence - My Computer, Intranet, Internet, etc.
            evidence.AddHostEvidence(Zone.CreateFromUrl(url));

            // Add Site evidence if the url is http. 
            if (!isFile) {
                evidence.AddHostEvidence(Site.CreateFromUrl(url)); 
            } 

            // Get the resulting permission set. 
            permissionSet = SecurityManager.GetStandardSandbox(evidence);

            // Client host is always ready to return permissions.
            isHostReady = true; 
        }
 
        // 
 	// Impersonate for Client Config
        // Use the process identity 
        //
        [SecurityPermissionAttribute(SecurityAction.Assert, Flags=SecurityPermissionFlag.ControlPrincipal | SecurityPermissionFlag.UnmanagedCode)]
        public override IDisposable Impersonate() {
            // Use the process identity 
            return WindowsIdentity.Impersonate(IntPtr.Zero);
        } 
 
	// context support
        public override object CreateDeprecatedConfigContext(string configPath) { 
            return null;
        }

        // CreateConfigurationContext 
        //
        // Create the new context 
        // 
        public override object
        CreateConfigurationContext( string configPath, 
                                    string locationSubPath )
        {
            return new ExeContext(GetUserLevel(configPath), ConfigPaths.ApplicationUri);
        } 

        // GetUserLevel 
        // 
        // Given a configPath, determine what the user level is?
        // 
        private ConfigurationUserLevel GetUserLevel(string configPath)
        {
            ConfigurationUserLevel level;
 
            switch (ConfigPathUtility.GetName(configPath)) {
                case MachineConfigName: 
                    // Machine Level 
                    level = ConfigurationUserLevel.None;
                    break; 

                case ExeConfigName:
                    // Exe Level
                    level = ConfigurationUserLevel.None; 
                    break;
 
                case LocalUserConfigName: 
                    // User Level
                    level = ConfigurationUserLevel.PerUserRoamingAndLocal; 
                    break;

                case RoamingUserConfigName:
                    // Roaming Level 
                    level = ConfigurationUserLevel.PerUserRoaming;
                    break; 
 
                default:
                    Debug.Fail("unrecognized configPath " + configPath); 
                    level = ConfigurationUserLevel.None;
                    break;
            }
 
            return level;
        } 
 
        //
        // Create a Configuration object. 
        //
        static internal Configuration OpenExeConfiguration(ConfigurationFileMap fileMap, bool isMachine, ConfigurationUserLevel userLevel, string exePath) {
            // validate userLevel argument
            switch (userLevel) { 
                default:
                    throw ExceptionUtil.ParameterInvalid("userLevel"); 
 
                case ConfigurationUserLevel.None:
                case ConfigurationUserLevel.PerUserRoaming: 
                case ConfigurationUserLevel.PerUserRoamingAndLocal:
                    break;
            }
 
            // validate fileMap arguments
            if (fileMap != null) { 
                if (String.IsNullOrEmpty(fileMap.MachineConfigFilename)) { 
                    throw ExceptionUtil.ParameterNullOrEmpty("fileMap.MachineConfigFilename");
                } 

                ExeConfigurationFileMap exeFileMap = fileMap as ExeConfigurationFileMap;
                if (exeFileMap != null) {
                    switch (userLevel) { 
                        case ConfigurationUserLevel.None:
                            if (String.IsNullOrEmpty(exeFileMap.ExeConfigFilename)) { 
                                throw ExceptionUtil.ParameterNullOrEmpty("fileMap.ExeConfigFilename"); 
                            }
 
                            break;

                        case ConfigurationUserLevel.PerUserRoaming:
                            if (String.IsNullOrEmpty(exeFileMap.RoamingUserConfigFilename)) { 
                                throw ExceptionUtil.ParameterNullOrEmpty("fileMap.RoamingUserConfigFilename");
                            } 
 
                            goto case ConfigurationUserLevel.None;
 
                        case ConfigurationUserLevel.PerUserRoamingAndLocal:
                            if (String.IsNullOrEmpty(exeFileMap.LocalUserConfigFilename)) {
                                throw ExceptionUtil.ParameterNullOrEmpty("fileMap.LocalUserConfigFilename");
                            } 

                            goto case ConfigurationUserLevel.PerUserRoaming; 
                    } 
                }
            } 

            string configPath = null;
            if (isMachine) {
                configPath = MachineConfigPath; 
            }
            else { 
                switch (userLevel) { 
                    case ConfigurationUserLevel.None:
                        configPath = ExeConfigPath; 
                        break;

                    case ConfigurationUserLevel.PerUserRoaming:
                        configPath = RoamingUserConfigPath; 
                        break;
 
                    case ConfigurationUserLevel.PerUserRoamingAndLocal: 
                        configPath = LocalUserConfigPath;
                        break; 
                }
            }

            Configuration configuration = new Configuration(null, typeof(ClientConfigurationHost), fileMap, exePath, configPath); 

            return configuration; 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK