ClientConfigurationHost
using System.Configuration.Internal;
using System.IO;
using System.Net;
namespace System.Configuration
{
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 = "MACHINE";
internal const string ExeConfigPath = "MACHINE/EXE";
internal const string RoamingUserConfigPath = "MACHINE/EXE/ROAMING_USER";
internal const string LocalUserConfigPath = "MACHINE/EXE/ROAMING_USER/LOCAL_USER";
private const string MachineConfigFilename = "machine.config";
private const string MachineConfigSubdirectory = "Config";
private static readonly object s_version = new object();
private static volatile string s_machineConfigFilePath;
private ClientConfigPaths _configPaths;
private string _exePath;
private ExeConfigurationFileMap _fileMap;
private bool _initComplete;
internal ClientConfigPaths ConfigPaths => _configPaths ?? (_configPaths = ClientConfigPaths.GetPaths(_exePath, _initComplete));
internal static string MachineConfigFilePath {
get {
if (s_machineConfigFilePath == null)
s_machineConfigFilePath = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config"), "machine.config");
return s_machineConfigFilePath;
}
}
public override bool HasRoamingConfig {
get {
if (_fileMap != null)
return !string.IsNullOrEmpty(_fileMap.RoamingUserConfigFilename);
return ConfigPaths.HasRoamingConfig;
}
}
public override bool HasLocalConfig {
get {
if (_fileMap != null)
return !string.IsNullOrEmpty(_fileMap.LocalUserConfigFilename);
return ConfigPaths.HasLocalConfig;
}
}
public override bool IsAppConfigHttp => !IsFile(GetStreamName("MACHINE/EXE"));
public override bool SupportsRefresh => true;
public override bool SupportsPath => false;
public override bool SupportsLocation => false;
internal ClientConfigurationHost()
{
base.Host = new InternalConfigHost();
}
bool IInternalConfigClientHost.IsExeConfig(string configPath)
{
return StringUtil.EqualsIgnoreCase(configPath, "MACHINE/EXE");
}
bool IInternalConfigClientHost.IsRoamingUserConfig(string configPath)
{
return StringUtil.EqualsIgnoreCase(configPath, "MACHINE/EXE/ROAMING_USER");
}
bool IInternalConfigClientHost.IsLocalUserConfig(string configPath)
{
return StringUtil.EqualsIgnoreCase(configPath, "MACHINE/EXE/ROAMING_USER/LOCAL_USER");
}
string IInternalConfigClientHost.GetExeConfigPath()
{
return "MACHINE/EXE";
}
string IInternalConfigClientHost.GetRoamingUserConfigPath()
{
return "MACHINE/EXE/ROAMING_USER";
}
string IInternalConfigClientHost.GetLocalUserConfigPath()
{
return "MACHINE/EXE/ROAMING_USER/LOCAL_USER";
}
public override void RefreshConfigPaths()
{
if (_configPaths != null && !_configPaths.HasEntryAssembly && _exePath == null) {
ClientConfigPaths.RefreshCurrent();
_configPaths = null;
}
}
private static bool IsUserConfig(string configPath)
{
if (!StringUtil.EqualsIgnoreCase(configPath, "MACHINE/EXE/ROAMING_USER"))
return StringUtil.EqualsIgnoreCase(configPath, "MACHINE/EXE/ROAMING_USER/LOCAL_USER");
return true;
}
public override void Init(IInternalConfigRoot configRoot, params object[] hostInitParams)
{
try {
ConfigurationFileMap configurationFileMap = (ConfigurationFileMap)hostInitParams[0];
_exePath = (string)hostInitParams[1];
base.Host.Init(configRoot, hostInitParams);
_initComplete = configRoot.IsDesignTime;
if (configurationFileMap != null && !string.IsNullOrEmpty(_exePath))
throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::Init");
if (string.IsNullOrEmpty(_exePath))
_exePath = null;
if (configurationFileMap != null) {
_fileMap = new ExeConfigurationFileMap();
if (!string.IsNullOrEmpty(configurationFileMap.MachineConfigFilename))
_fileMap.MachineConfigFilename = Path.GetFullPath(configurationFileMap.MachineConfigFilename);
ExeConfigurationFileMap exeConfigurationFileMap = configurationFileMap as ExeConfigurationFileMap;
if (exeConfigurationFileMap != null) {
if (!string.IsNullOrEmpty(exeConfigurationFileMap.ExeConfigFilename))
_fileMap.ExeConfigFilename = Path.GetFullPath(exeConfigurationFileMap.ExeConfigFilename);
if (!string.IsNullOrEmpty(exeConfigurationFileMap.RoamingUserConfigFilename))
_fileMap.RoamingUserConfigFilename = Path.GetFullPath(exeConfigurationFileMap.RoamingUserConfigFilename);
if (!string.IsNullOrEmpty(exeConfigurationFileMap.LocalUserConfigFilename))
_fileMap.LocalUserConfigFilename = Path.GetFullPath(exeConfigurationFileMap.LocalUserConfigFilename);
}
}
} 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);
}
public override bool IsInitDelayed(IInternalConfigRecord configRecord)
{
if (!_initComplete)
return IsUserConfig(configRecord.ConfigPath);
return false;
}
public override void RequireCompleteInit(IInternalConfigRecord record)
{
lock (this) {
if (!_initComplete) {
_initComplete = true;
ClientConfigPaths.RefreshCurrent();
_configPaths = null;
ClientConfigPaths configPath = ConfigPaths;
}
}
}
public override bool IsConfigRecordRequired(string configPath)
{
switch (ConfigPathUtility.GetName(configPath)) {
case "MACHINE":
case "EXE":
return true;
case "ROAMING_USER":
if (!HasRoamingConfig)
return HasLocalConfig;
return true;
case "LOCAL_USER":
return HasLocalConfig;
default:
return false;
}
}
public override string GetStreamName(string configPath)
{
switch (ConfigPathUtility.GetName(configPath)) {
default:
return _fileMap?.MachineConfigFilename ?? MachineConfigFilePath;
case "EXE":
return _fileMap?.ExeConfigFilename ?? ConfigPaths.ApplicationConfigUri;
case "ROAMING_USER":
return _fileMap?.RoamingUserConfigFilename ?? ConfigPaths.RoamingConfigFilename;
case "LOCAL_USER":
return _fileMap?.LocalUserConfigFilename ?? ConfigPaths.LocalConfigFilename;
}
}
public override string GetStreamNameForConfigSource(string streamName, string configSource)
{
if (IsFile(streamName))
return base.Host.GetStreamNameForConfigSource(streamName, configSource);
int num = streamName.LastIndexOf('/');
if (num < 0)
return null;
return streamName.Substring(0, num + 1) + configSource.Replace('\\', '/');
}
public override object GetStreamVersion(string streamName)
{
if (!IsFile(streamName))
return s_version;
return base.Host.GetStreamVersion(streamName);
}
public override Stream OpenStreamForRead(string streamName)
{
if (IsFile(streamName))
return base.Host.OpenStreamForRead(streamName);
if (streamName == null)
return null;
WebClient webClient = new WebClient();
try {
webClient.Credentials = CredentialCache.DefaultCredentials;
} catch {
}
byte[] array = null;
try {
array = webClient.DownloadData(streamName);
} catch {
}
if (array == null)
return null;
return new MemoryStream(array);
}
public override Stream OpenStreamForWrite(string streamName, string templateStreamName, ref object writeContext)
{
if (!IsFile(streamName))
throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::OpenStreamForWrite '" + streamName + "' '" + templateStreamName + "'");
return base.Host.OpenStreamForWrite(streamName, templateStreamName, ref writeContext);
}
public override void DeleteStream(string streamName)
{
if (!IsFile(streamName))
throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::Delete");
base.Host.DeleteStream(streamName);
}
public override bool IsDefinitionAllowed(string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition)
{
string text;
switch (allowExeDefinition) {
case ConfigurationAllowExeDefinition.MachineOnly:
text = "MACHINE";
break;
case ConfigurationAllowExeDefinition.MachineToApplication:
text = "MACHINE/EXE";
break;
case ConfigurationAllowExeDefinition.MachineToRoamingUser:
text = "MACHINE/EXE/ROAMING_USER";
break;
case ConfigurationAllowExeDefinition.MachineToLocalUser:
return true;
default:
throw ExceptionUtil.UnexpectedError("ClientConfigurationHost::IsDefinitionAllowed");
}
return configPath.Length <= text.Length;
}
public override void VerifyDefinitionAllowed(string configPath, ConfigurationAllowDefinition allowDefinition, ConfigurationAllowExeDefinition allowExeDefinition, IConfigErrorInfo errorInfo)
{
if (!IsDefinitionAllowed(configPath, allowDefinition, allowExeDefinition)) {
Exception ex;
switch (allowExeDefinition) {
case ConfigurationAllowExeDefinition.MachineOnly:
ex = new ConfigurationErrorsException(System.SR.Config_allow_exedefinition_error_machine, errorInfo);
break;
case ConfigurationAllowExeDefinition.MachineToApplication:
ex = new ConfigurationErrorsException(System.SR.Config_allow_exedefinition_error_application, errorInfo);
break;
case ConfigurationAllowExeDefinition.MachineToRoamingUser:
ex = new ConfigurationErrorsException(System.SR.Config_allow_exedefinition_error_roaminguser, errorInfo);
break;
default:
ex = ExceptionUtil.UnexpectedError("ClientConfigurationHost::VerifyDefinitionAllowed");
break;
}
throw ex;
}
}
public override bool PrefetchAll(string configPath, string streamName)
{
return !IsFile(streamName);
}
public override bool PrefetchSection(string sectionGroupName, string sectionName)
{
return sectionGroupName == "system.net";
}
public override object CreateDeprecatedConfigContext(string configPath)
{
return null;
}
public override object CreateConfigurationContext(string configPath, string locationSubPath)
{
return new ExeContext(GetUserLevel(configPath), ConfigPaths.ApplicationUri);
}
private static ConfigurationUserLevel GetUserLevel(string configPath)
{
switch (ConfigPathUtility.GetName(configPath)) {
case "MACHINE":
return ConfigurationUserLevel.None;
case "EXE":
return ConfigurationUserLevel.None;
case "LOCAL_USER":
return ConfigurationUserLevel.PerUserRoamingAndLocal;
case "ROAMING_USER":
return ConfigurationUserLevel.PerUserRoaming;
default:
return ConfigurationUserLevel.None;
}
}
internal static Configuration OpenExeConfiguration(ConfigurationFileMap fileMap, bool isMachine, ConfigurationUserLevel userLevel, string exePath)
{
if (userLevel != 0 && userLevel != ConfigurationUserLevel.PerUserRoaming && userLevel != ConfigurationUserLevel.PerUserRoamingAndLocal)
throw ExceptionUtil.ParameterInvalid("userLevel");
if (fileMap != null) {
if (string.IsNullOrEmpty(fileMap.MachineConfigFilename))
throw ExceptionUtil.ParameterNullOrEmpty("fileMap.MachineConfigFilename");
ExeConfigurationFileMap exeConfigurationFileMap = fileMap as ExeConfigurationFileMap;
if (exeConfigurationFileMap != null) {
switch (userLevel) {
case ConfigurationUserLevel.None:
if (string.IsNullOrEmpty(exeConfigurationFileMap.ExeConfigFilename))
throw ExceptionUtil.ParameterNullOrEmpty("fileMap.ExeConfigFilename");
break;
case ConfigurationUserLevel.PerUserRoaming:
if (string.IsNullOrEmpty(exeConfigurationFileMap.RoamingUserConfigFilename))
throw ExceptionUtil.ParameterNullOrEmpty("fileMap.RoamingUserConfigFilename");
goto case ConfigurationUserLevel.None;
case ConfigurationUserLevel.PerUserRoamingAndLocal:
if (string.IsNullOrEmpty(exeConfigurationFileMap.LocalUserConfigFilename))
throw ExceptionUtil.ParameterNullOrEmpty("fileMap.LocalUserConfigFilename");
goto case ConfigurationUserLevel.PerUserRoaming;
}
}
}
string text = null;
if (!isMachine) {
switch (userLevel) {
case ConfigurationUserLevel.None:
text = "MACHINE/EXE";
break;
case ConfigurationUserLevel.PerUserRoaming:
text = "MACHINE/EXE/ROAMING_USER";
break;
case ConfigurationUserLevel.PerUserRoamingAndLocal:
text = "MACHINE/EXE/ROAMING_USER/LOCAL_USER";
break;
}
} else
text = "MACHINE";
return new Configuration(null, typeof(ClientConfigurationHost), fileMap, exePath, text);
}
}
}