internal StreamInfo Clone() { StreamInfo clone = new StreamInfo(); clone._sectionName = this._sectionName; clone._configSource = this._configSource; clone._streamName = this._streamName; clone._isMonitored = this._isMonitored; clone._version = this._version; return clone; }
// // Set the configSource attribute on a ConfigurationSection // internal void ChangeConfigSource( SectionInformation sectionInformation, string oldConfigSource, string oldConfigSourceStreamName, string newConfigSource) { if (String.IsNullOrEmpty(oldConfigSource)) { oldConfigSource = null; } if (String.IsNullOrEmpty(newConfigSource)) { newConfigSource = null; } // Check if there is a change to config source if (StringUtil.EqualsIgnoreCase(oldConfigSource, newConfigSource)) return; if (String.IsNullOrEmpty(ConfigStreamInfo.StreamName)) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_source_requires_file)); } string newConfigSourceStreamName = null; if (newConfigSource != null) { newConfigSourceStreamName = Host.GetStreamNameForConfigSource(ConfigStreamInfo.StreamName, newConfigSource); } // Add the stream to the updates if (newConfigSourceStreamName != null) { // // Ensure that no parent is using the same config source stream // ValidateUniqueChildConfigSource(sectionInformation.ConfigKey, newConfigSourceStreamName, newConfigSource, null); StreamInfo streamInfo = (StreamInfo) _streamInfoUpdates[newConfigSourceStreamName]; if (streamInfo != null) { // // Detect if another section in this file is using the same configSource // with has a different section name. // if (streamInfo.SectionName != sectionInformation.ConfigKey) { throw new ConfigurationErrorsException( SR.GetString(SR.Config_source_cannot_be_shared, newConfigSource)); } } else { // // Add stream to updates // streamInfo = new StreamInfo(sectionInformation.ConfigKey, newConfigSource, newConfigSourceStreamName); _streamInfoUpdates.Add(newConfigSourceStreamName, streamInfo); } } // remove old streamname if no longer referenced if (oldConfigSourceStreamName != null && !IsStreamUsed(oldConfigSourceStreamName)) { _streamInfoUpdates.Remove(oldConfigSourceStreamName); } // update the configSourceStreamName sectionInformation.ConfigSourceStreamName = newConfigSourceStreamName; }
// // Update the config file with the changes in each ConfigurationSection // internal void SaveAs(string filename, ConfigurationSaveMode saveMode, bool forceUpdateAll) { // Get the updates. SectionUpdates declarationUpdates = GetConfigDeclarationUpdates(saveMode, forceUpdateAll); ConfigDefinitionUpdates definitionUpdates; ArrayList configSourceUpdates; bool checkedConfigForUpdates = false; bool requireUpdates = (filename != null); GetConfigDefinitionUpdates(requireUpdates, saveMode, forceUpdateAll, out definitionUpdates, out configSourceUpdates); if (filename != null) { Debug.Assert(filename.Length > 0, "The caller should make sure that filename is not empty"); // // Verify that the filename is not being used. // // Note that if we are using a remote host, all the streamName's in _streamInfoUpdates // are actually fullpaths on the remote machine. In this case there is no way to // detect if we have a conflict or not. if (!Host.IsRemote && _streamInfoUpdates.Contains(filename)) { throw new ArgumentException(SR.GetString(SR.Filename_in_SaveAs_is_used_already, filename)); } // // If there was no config file for this config record, // record the new stream name and version. // if (String.IsNullOrEmpty(ConfigStreamInfo.StreamName)) { StreamInfo streamInfo = new StreamInfo(null, null, filename); _streamInfoUpdates.Add(filename, streamInfo); ConfigStreamInfo.StreamName = filename; ConfigStreamInfo.StreamVersion = MonitorStream(null, null, ConfigStreamInfo.StreamName); } // // Update the host to redirect filenames // UpdateConfigHost.AddStreamname(ConfigStreamInfo.StreamName, filename, Host.IsRemote); // Redirect also all configSource filenames foreach (StreamInfo streamInfo in _streamInfoUpdates.Values) { if (!String.IsNullOrEmpty(streamInfo.SectionName)) { // Get the new configSource streamName based on the new filename path string newStreamName = InternalConfigHost.StaticGetStreamNameForConfigSource( filename, streamInfo.ConfigSource); // Ask UpdateConfigHost to intercept them. UpdateConfigHost.AddStreamname(streamInfo.StreamName, newStreamName, Host.IsRemote); } } } if (!requireUpdates) { // Check if there are any updates needed for the // configuration record itself. requireUpdates = RecordItselfRequiresUpdates; } if (declarationUpdates != null || definitionUpdates != null || requireUpdates) { // Copy the input stream before opening the output stream. byte[] readBuffer = null; Encoding encoding = null; if (ConfigStreamInfo.HasStream) { using (Stream streamRead = Host.OpenStreamForRead(ConfigStreamInfo.StreamName)) { if (streamRead == null) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_file_has_changed), ConfigStreamInfo.StreamName, 0); } readBuffer = new byte[streamRead.Length]; int count = streamRead.Read(readBuffer, 0, (int) streamRead.Length); if (count != streamRead.Length) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_data_read_count_mismatch)); } } // Read the first byte so that we can determine the encoding. try { using (StreamReader reader = new StreamReader(ConfigStreamInfo.StreamName)) { if (reader.Peek() >= 0) { reader.Read(); } // Dev10 bug 687017 - Handle only UTF-16 explicitly, so that handling of other // encodings are not affected. if (reader.CurrentEncoding is UnicodeEncoding) { encoding = reader.CurrentEncoding; } } } catch { // Ignore any errors, encoding will remain null. } } string changedStreamName = FindChangedConfigurationStream(); if (changedStreamName != null) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_file_has_changed), changedStreamName, 0); } checkedConfigForUpdates = true; // Write the changes to the output stream. object writeContext = null; bool streamOpened = false; try { try { using (Stream streamWrite = Host.OpenStreamForWrite(ConfigStreamInfo.StreamName, null, ref writeContext)) { streamOpened = true; // Use the default StreamWriter constructor if encoding is null, // otherwise specify the encoding. using (StreamWriter streamWriter = encoding == null ? new StreamWriter(streamWrite) : new StreamWriter(streamWrite, encoding)) { XmlUtilWriter utilWriter = new XmlUtilWriter(streamWriter, true); if (ConfigStreamInfo.HasStream) { CopyConfig(declarationUpdates, definitionUpdates, readBuffer, ConfigStreamInfo.StreamName, NamespaceChangeNeeded, utilWriter); } else { CreateNewConfig(declarationUpdates, definitionUpdates, NamespaceChangeNeeded, utilWriter); } } } } catch { if (streamOpened) { Host.WriteCompleted(ConfigStreamInfo.StreamName, false, writeContext); } throw; } } // // Guarantee that exceptions contain at least the name of the stream by wrapping them // in a ConfigurationException. // catch (Exception e) { throw ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, ConfigStreamInfo.StreamName, 0); } Host.WriteCompleted(ConfigStreamInfo.StreamName, true, writeContext); // Update stream information for the config file ConfigStreamInfo.HasStream = true; ConfigStreamInfo.ClearStreamInfos(); ConfigStreamInfo.StreamVersion = MonitorStream(null, null, ConfigStreamInfo.StreamName); } if (configSourceUpdates != null) { // If we haven't checked before, check now if (!checkedConfigForUpdates) { string changedStreamName = FindChangedConfigurationStream(); if (changedStreamName != null) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_file_has_changed), changedStreamName, 0); } } // write updates foreach (DefinitionUpdate update in configSourceUpdates) { SaveConfigSource(update); } } // Update state to reflect the changes to the config file UpdateRecords(); }
protected object MonitorStream(string configKey, string configSource, string streamname) { lock (this) { if (_flags[Closed]) { return null; } StreamInfo streamInfo = (StreamInfo) ConfigStreamInfo.StreamInfos[streamname]; if (streamInfo != null) { if (streamInfo.SectionName != configKey) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_source_cannot_be_shared, streamname)); } if (streamInfo.IsMonitored) { return streamInfo.Version; } } else { streamInfo = new StreamInfo(configKey, configSource, streamname); ConfigStreamInfo.StreamInfos.Add(streamname, streamInfo); } } // // Call the host outside the lock to avoid deadlock. // object version = Host.GetStreamVersion(streamname); StreamChangeCallback callbackDelegate = null; lock (this) { if (_flags[Closed]) { return null; } StreamInfo streamInfo = (StreamInfo) ConfigStreamInfo.StreamInfos[streamname]; if (streamInfo.IsMonitored) { return streamInfo.Version; } streamInfo.IsMonitored = true; streamInfo.Version = version; if (_flags[SupportsChangeNotifications]) { if (ConfigStreamInfo.CallbackDelegate == null) { ConfigStreamInfo.CallbackDelegate = new StreamChangeCallback(this.OnStreamChanged); } callbackDelegate = ConfigStreamInfo.CallbackDelegate; } } if (_flags[SupportsChangeNotifications]) { Host.StartMonitoringStreamForChanges(streamname, callbackDelegate); } return version; }
internal void ChangeConfigSource(SectionInformation sectionInformation, string oldConfigSource, string oldConfigSourceStreamName, string newConfigSource) { if (string.IsNullOrEmpty(oldConfigSource)) { oldConfigSource = null; } if (string.IsNullOrEmpty(newConfigSource)) { newConfigSource = null; } if (!StringUtil.EqualsIgnoreCase(oldConfigSource, newConfigSource)) { if (string.IsNullOrEmpty(base.ConfigStreamInfo.StreamName)) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_source_requires_file")); } string configSourceStreamName = null; if (newConfigSource != null) { configSourceStreamName = base.Host.GetStreamNameForConfigSource(base.ConfigStreamInfo.StreamName, newConfigSource); } if (configSourceStreamName != null) { base.ValidateUniqueChildConfigSource(sectionInformation.ConfigKey, configSourceStreamName, newConfigSource, null); StreamInfo info = (StreamInfo) this._streamInfoUpdates[configSourceStreamName]; if (info != null) { if (info.SectionName != sectionInformation.ConfigKey) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_source_cannot_be_shared", new object[] { newConfigSource })); } } else { info = new StreamInfo(sectionInformation.ConfigKey, newConfigSource, configSourceStreamName); this._streamInfoUpdates.Add(configSourceStreamName, info); } } if ((oldConfigSourceStreamName != null) && !this.IsStreamUsed(oldConfigSourceStreamName)) { this._streamInfoUpdates.Remove(oldConfigSourceStreamName); } sectionInformation.ConfigSourceStreamName = configSourceStreamName; } }
internal void SaveAs(string filename, ConfigurationSaveMode saveMode, bool forceUpdateAll) { ConfigDefinitionUpdates updates2; ArrayList list; SectionUpdates configDeclarationUpdates = this.GetConfigDeclarationUpdates(saveMode, forceUpdateAll); bool flag = false; bool requireUpdates = filename != null; this.GetConfigDefinitionUpdates(requireUpdates, saveMode, forceUpdateAll, out updates2, out list); if (filename != null) { if (!base.Host.IsRemote && this._streamInfoUpdates.Contains(filename)) { throw new ArgumentException(System.Configuration.SR.GetString("Filename_in_SaveAs_is_used_already", new object[] { filename })); } if (string.IsNullOrEmpty(base.ConfigStreamInfo.StreamName)) { StreamInfo info = new StreamInfo(null, null, filename); this._streamInfoUpdates.Add(filename, info); base.ConfigStreamInfo.StreamName = filename; base.ConfigStreamInfo.StreamVersion = base.MonitorStream(null, null, base.ConfigStreamInfo.StreamName); } this.UpdateConfigHost.AddStreamname(base.ConfigStreamInfo.StreamName, filename, base.Host.IsRemote); foreach (StreamInfo info2 in this._streamInfoUpdates.Values) { if (!string.IsNullOrEmpty(info2.SectionName)) { string newStreamname = InternalConfigHost.StaticGetStreamNameForConfigSource(filename, info2.ConfigSource); this.UpdateConfigHost.AddStreamname(info2.StreamName, newStreamname, base.Host.IsRemote); } } } if (!requireUpdates) { requireUpdates = this.RecordItselfRequiresUpdates; } if (((configDeclarationUpdates != null) || (updates2 != null)) || requireUpdates) { byte[] buffer = null; Encoding currentEncoding = null; if (base.ConfigStreamInfo.HasStream) { using (Stream stream = base.Host.OpenStreamForRead(base.ConfigStreamInfo.StreamName)) { if (stream == null) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_file_has_changed"), base.ConfigStreamInfo.StreamName, 0); } buffer = new byte[stream.Length]; if (stream.Read(buffer, 0, (int) stream.Length) != stream.Length) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_data_read_count_mismatch")); } } try { using (StreamReader reader = new StreamReader(base.ConfigStreamInfo.StreamName)) { if (reader.Peek() >= 0) { reader.Read(); } if (reader.CurrentEncoding is UnicodeEncoding) { currentEncoding = reader.CurrentEncoding; } } } catch { } } string str2 = base.FindChangedConfigurationStream(); if (str2 != null) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_file_has_changed"), str2, 0); } flag = true; object writeContext = null; bool flag3 = false; try { try { using (Stream stream2 = base.Host.OpenStreamForWrite(base.ConfigStreamInfo.StreamName, null, ref writeContext)) { flag3 = true; using (StreamWriter writer = (currentEncoding == null) ? new StreamWriter(stream2) : new StreamWriter(stream2, currentEncoding)) { XmlUtilWriter utilWriter = new XmlUtilWriter(writer, true); if (base.ConfigStreamInfo.HasStream) { this.CopyConfig(configDeclarationUpdates, updates2, buffer, base.ConfigStreamInfo.StreamName, this.NamespaceChangeNeeded, utilWriter); } else { this.CreateNewConfig(configDeclarationUpdates, updates2, this.NamespaceChangeNeeded, utilWriter); } } } } catch { if (flag3) { base.Host.WriteCompleted(base.ConfigStreamInfo.StreamName, false, writeContext); } throw; } } catch (Exception exception) { throw ExceptionUtil.WrapAsConfigException(System.Configuration.SR.GetString("Config_error_loading_XML_file"), exception, base.ConfigStreamInfo.StreamName, 0); } base.Host.WriteCompleted(base.ConfigStreamInfo.StreamName, true, writeContext); base.ConfigStreamInfo.HasStream = true; base.ConfigStreamInfo.ClearStreamInfos(); base.ConfigStreamInfo.StreamVersion = base.MonitorStream(null, null, base.ConfigStreamInfo.StreamName); } if (list != null) { if (!flag) { string str3 = base.FindChangedConfigurationStream(); if (str3 != null) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_file_has_changed"), str3, 0); } } foreach (DefinitionUpdate update in list) { this.SaveConfigSource(update); } } this.UpdateRecords(); }