private void GetConfigDefinitionUpdates(bool requireUpdates, ConfigurationSaveMode saveMode, bool forceSaveAll, out ConfigDefinitionUpdates definitionUpdates, out ArrayList configSourceUpdates) { definitionUpdates = new ConfigDefinitionUpdates(); configSourceUpdates = null; bool hasRemovedSections = this.HasRemovedSections; if (base._sectionRecords != null) { base.InitProtectedConfigurationSection(); foreach (DictionaryEntry entry in base._sectionRecords) { string key = (string) entry.Key; SectionRecord sectionRecord = (SectionRecord) entry.Value; sectionRecord.AddUpdate = false; bool hasFileInput = sectionRecord.HasFileInput; OverrideModeSetting locationDefault = OverrideModeSetting.LocationDefault; bool inheritInChildApps = true; bool moved = false; string xmlElement = null; bool flag5 = false; if (!sectionRecord.HasResult) { if (sectionRecord.HasFileInput) { SectionXmlInfo sectionXmlInfo = sectionRecord.FileInput.SectionXmlInfo; locationDefault = sectionXmlInfo.OverrideModeSetting; inheritInChildApps = !sectionXmlInfo.SkipInChildApps; flag5 = requireUpdates && !string.IsNullOrEmpty(sectionXmlInfo.ConfigSource); } } else { ConfigurationSection result = (ConfigurationSection) sectionRecord.Result; if ((base.TargetFramework != null) && !result.ShouldSerializeSectionInTargetVersion(base.TargetFramework)) { continue; } locationDefault = result.SectionInformation.OverrideModeSetting; inheritInChildApps = result.SectionInformation.InheritInChildApplications; if (!result.SectionInformation.AllowLocation && (!locationDefault.IsDefaultForLocationTag || !inheritInChildApps)) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_inconsistent_location_attributes", new object[] { key })); } flag5 = requireUpdates && !string.IsNullOrEmpty(result.SectionInformation.ConfigSource); try { bool flag6 = (result.SectionInformation.ForceSave || result.IsModified()) || (forceSaveAll && !result.SectionInformation.IsLocked); bool flag7 = this.AreSectionAttributesModified(sectionRecord, result); bool flag8 = flag6 || (result.SectionInformation.RawXml != null); if (flag8 || flag7) { result.SectionInformation.VerifyIsEditable(); result.SectionInformation.Removed = false; hasFileInput = true; moved = this.IsConfigSectionMoved(sectionRecord, result); if (!flag5) { flag5 = !string.IsNullOrEmpty(result.SectionInformation.ConfigSource) && (flag8 || result.SectionInformation.ConfigSourceModified); } if ((flag6 || (result.SectionInformation.RawXml == null)) || (saveMode == ConfigurationSaveMode.Full)) { ConfigurationSection parentElement = this.FindImmediateParentSection(result); xmlElement = result.SerializeSection(parentElement, result.SectionInformation.Name, saveMode); this.ValidateSectionXml(xmlElement, key); } else { xmlElement = result.SectionInformation.RawXml; } if (string.IsNullOrEmpty(xmlElement) && ((!string.IsNullOrEmpty(result.SectionInformation.ConfigSource) || !result.SectionInformation.LocationAttributesAreDefault) || (result.SectionInformation.ProtectionProvider != null))) { xmlElement = this.WriteEmptyElement(result.SectionInformation.Name); } if (string.IsNullOrEmpty(xmlElement)) { result.SectionInformation.Removed = true; xmlElement = null; hasFileInput = false; if (sectionRecord.HasFileInput) { hasRemovedSections = true; sectionRecord.RemoveFileInput(); } goto Label_0416; } if ((flag7 || moved) || string.IsNullOrEmpty(result.SectionInformation.ConfigSource)) { hasRemovedSections = true; } if (result.SectionInformation.ProtectionProvider == null) { goto Label_0416; } ProtectedConfigurationSection section = base.GetSection("configProtectedData") as ProtectedConfigurationSection; try { xmlElement = ProtectedConfigurationSection.FormatEncryptedSection(base.Host.EncryptSection(xmlElement, result.SectionInformation.ProtectionProvider, section), result.SectionInformation.Name, result.SectionInformation.ProtectionProvider.Name); goto Label_0416; } catch (Exception exception) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Encryption_failed", new object[] { result.SectionInformation.SectionName, result.SectionInformation.ProtectionProvider.Name, exception.Message }), exception); } } if (result.SectionInformation.Removed) { hasFileInput = false; if (sectionRecord.HasFileInput) { hasRemovedSections = true; } } } catch (Exception exception2) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_exception_in_config_section_handler", new object[] { result.SectionInformation.SectionName }), exception2); } } Label_0416: if (hasFileInput) { if (base.GetSectionLockedMode(sectionRecord.ConfigKey) == OverrideMode.Deny) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_section_locked"), null); } sectionRecord.AddUpdate = true; DefinitionUpdate update = definitionUpdates.AddUpdate(locationDefault, inheritInChildApps, moved, xmlElement, sectionRecord); if (flag5) { if (configSourceUpdates == null) { configSourceUpdates = new ArrayList(); } configSourceUpdates.Add(update); } } } } if (this._flags[0x1000000]) { hasRemovedSections = true; definitionUpdates.RequireLocation = true; } if (this._flags[0x2000000]) { hasRemovedSections = true; } if (hasRemovedSections) { definitionUpdates.CompleteUpdates(); } else { definitionUpdates = null; } }
// Gather all the updates to the configuration section definitions. private void GetConfigDefinitionUpdates( bool requireUpdates, ConfigurationSaveMode saveMode, bool forceSaveAll, out ConfigDefinitionUpdates definitionUpdates, out ArrayList configSourceUpdates) { definitionUpdates = new ConfigDefinitionUpdates(); configSourceUpdates = null; bool hasChanged = HasRemovedSections; // Loop through all the section records. if (_sectionRecords != null) { InitProtectedConfigurationSection(); // Make sure we have the initialized the protected config section, otherwise the foreach loop may ---- up foreach (DictionaryEntry de in _sectionRecords) { string configKey = (string)de.Key; SectionRecord sectionRecord = (SectionRecord) de.Value; sectionRecord.AddUpdate = false; bool addUpdate = sectionRecord.HasFileInput; // If true, add this section to definitionUpdates, and optinally to configSourceUpdates OverrideModeSetting overrideMode = OverrideModeSetting.LocationDefault; bool inheritInChildApplications = true; bool moved = false; string updatedXml = null; bool addToConfigSourceUpdates = false; // If true, we have to update the external config file for this section if (!sectionRecord.HasResult) { if (sectionRecord.HasFileInput) { SectionXmlInfo sectionXmlInfo = sectionRecord.FileInput.SectionXmlInfo; overrideMode = sectionXmlInfo.OverrideModeSetting; inheritInChildApplications = !sectionXmlInfo.SkipInChildApps; addToConfigSourceUpdates = requireUpdates && !String.IsNullOrEmpty(sectionXmlInfo.ConfigSource); } } else { ConfigurationSection configSection = (ConfigurationSection) sectionRecord.Result; if (TargetFramework != null && !configSection.ShouldSerializeSectionInTargetVersion(TargetFramework)) continue; overrideMode = configSection.SectionInformation.OverrideModeSetting; inheritInChildApplications = configSection.SectionInformation.InheritInChildApplications; // it is an error to require a location section when the type doesn't allow locations. if (!configSection.SectionInformation.AllowLocation && (!overrideMode.IsDefaultForLocationTag || !inheritInChildApplications)) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_inconsistent_location_attributes, configKey)); } addToConfigSourceUpdates = requireUpdates && !String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource); try { bool isModified = configSection.SectionInformation.ForceSave || configSection.IsModified() || (forceSaveAll && !configSection.SectionInformation.IsLocked); bool sectionAttributesModified = AreSectionAttributesModified(sectionRecord, configSection); bool sectionContentModified = (isModified || configSection.SectionInformation.RawXml != null); // Get the updated XML if the section has been modified. if (sectionContentModified || sectionAttributesModified) { configSection.SectionInformation.VerifyIsEditable(); configSection.SectionInformation.Removed = false; addUpdate = true; moved = IsConfigSectionMoved(sectionRecord, configSection); if (!addToConfigSourceUpdates) { addToConfigSourceUpdates = !String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource) && (sectionContentModified || configSection.SectionInformation.ConfigSourceModified); } if ( isModified || configSection.SectionInformation.RawXml == null || saveMode == ConfigurationSaveMode.Full) { // Note: we won't use RawXml if saveMode == Full because Full means we want to // write all properties, and RawXml may not have all properties. ConfigurationSection parentConfigSection = FindImmediateParentSection(configSection); updatedXml = configSection.SerializeSection(parentConfigSection, configSection.SectionInformation.Name, saveMode); ValidateSectionXml(updatedXml, configKey); } else { updatedXml = configSection.SectionInformation.RawXml; } if (string.IsNullOrEmpty(updatedXml)) { // // We always need to emit a section, even if empty, when: // * The section has configSoure // * The section is in a location section that has non-default attributes // * The section is encrypted. // if ( !String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource) || !configSection.SectionInformation.LocationAttributesAreDefault || (configSection.SectionInformation.ProtectionProvider != null)) { updatedXml = WriteEmptyElement(configSection.SectionInformation.Name); } } if (string.IsNullOrEmpty(updatedXml)) { configSection.SectionInformation.Removed = true; // configSection.ElementPresent = false; updatedXml = null; addUpdate = false; if (sectionRecord.HasFileInput) { hasChanged = true; // VSWhidbey 580658: When a section is to be removed, its corresponding file // input should be cleared as well so this section will be indicated as "moved" // next time something is added back to the section. Without marking it as "moved", // adding new content to a removed section fails as the bug describes. sectionRecord.RemoveFileInput(); } } else { // configSection.ElementPresent = true; if (sectionAttributesModified || moved || String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource)) { hasChanged = true; } // Encrypt if required. if (configSection.SectionInformation.ProtectionProvider != null) { ProtectedConfigurationSection protectedConfig = GetSection(BaseConfigurationRecord.RESERVED_SECTION_PROTECTED_CONFIGURATION) as ProtectedConfigurationSection; try { string encryptedSection = Host.EncryptSection(updatedXml, configSection.SectionInformation.ProtectionProvider, protectedConfig); // VsWhidbey 495120: The config host is responsible for encrypting a section, but it is the job of // System.Configuration to format an encrypted section during write (and to detect an encrypted section during read.) updatedXml = ProtectedConfigurationSection.FormatEncryptedSection(encryptedSection, configSection.SectionInformation.Name, configSection.SectionInformation.ProtectionProvider.Name); } catch (Exception e) { throw new ConfigurationErrorsException( SR.GetString(SR.Encryption_failed, configSection.SectionInformation.SectionName, configSection.SectionInformation.ProtectionProvider.Name, e.Message), e); } } } } else if (configSection.SectionInformation.Removed) { addUpdate = false; if (sectionRecord.HasFileInput) { hasChanged = true; } } } catch (Exception e) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_exception_in_config_section_handler, configSection.SectionInformation.SectionName), e); } } if (addUpdate) { // Make sure we are not addingh a definition of a locked section if (GetSectionLockedMode(sectionRecord.ConfigKey) == OverrideMode.Deny) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_section_locked), (IConfigErrorInfo)(null)); } sectionRecord.AddUpdate = true; DefinitionUpdate definitionUpdate = definitionUpdates.AddUpdate(overrideMode, inheritInChildApplications, moved, updatedXml, sectionRecord); if (addToConfigSourceUpdates) { if (configSourceUpdates == null) { configSourceUpdates = new ArrayList(); } configSourceUpdates.Add(definitionUpdate); } } } } if (_flags[ ForceLocationWritten ]) { // We must write the location tag hasChanged = true; definitionUpdates.RequireLocation = true; } if (_flags[ SuggestLocationRemoval ]) { // We should try to remove location hasChanged = true; } if (hasChanged) { definitionUpdates.CompleteUpdates(); } else { definitionUpdates = null; } }
// Gather all the updates to the configuration section definitions. private void GetConfigDefinitionUpdates( bool requireUpdates, ConfigurationSaveMode saveMode, bool forceSaveAll, out ConfigDefinitionUpdates definitionUpdates, out ArrayList configSourceUpdates) { definitionUpdates = new ConfigDefinitionUpdates(); configSourceUpdates = null; bool hasChanged = HasRemovedSections; // Loop through all the section records. if (_sectionRecords != null) { InitProtectedConfigurationSection(); // Make sure we have the initialized the protected config section, otherwise the foreach loop may blow up foreach (DictionaryEntry de in _sectionRecords) { string configKey = (string)de.Key; SectionRecord sectionRecord = (SectionRecord) de.Value; sectionRecord.AddUpdate = false; bool addUpdate = sectionRecord.HasFileInput; // If true, add this section to definitionUpdates, and optinally to configSourceUpdates bool allowOverride = true; bool inheritInChildApplications = true; bool moved = false; string updatedXml = null; bool addToConfigSourceUpdates = false; // If true, we have to update the external config file for this section if (!sectionRecord.HasResult) { if (sectionRecord.HasFileInput) { SectionXmlInfo sectionXmlInfo = sectionRecord.FileInput.SectionXmlInfo; allowOverride = !sectionXmlInfo.LockChildren; inheritInChildApplications = !sectionXmlInfo.SkipInChildApps; addToConfigSourceUpdates = requireUpdates && !String.IsNullOrEmpty(sectionXmlInfo.ConfigSource); } } else { ConfigurationSection configSection = (ConfigurationSection) sectionRecord.Result; allowOverride = configSection.SectionInformation.AllowOverride; inheritInChildApplications = configSection.SectionInformation.InheritInChildApplications; // it is an error to require a location section when the type doesn't allow locations. if (!configSection.SectionInformation.AllowLocation && (!allowOverride || !inheritInChildApplications)) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_inconsistent_location_attributes, configKey)); } addToConfigSourceUpdates = requireUpdates && !String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource); try { bool isModified = configSection.SectionInformation.ForceSave || configSection.IsModified() || (forceSaveAll && !configSection.SectionInformation.IsLocked); bool sectionAttributesModified = AreSectionAttributesModified(sectionRecord, configSection); bool sectionContentModified = (isModified || configSection.SectionInformation.RawXml != null); // Get the updated XML if the section has been modified. if (sectionContentModified || sectionAttributesModified) { configSection.SectionInformation.VerifyIsEditable(); configSection.SectionInformation.Removed = false; addUpdate = true; moved = IsConfigSectionMoved(sectionRecord, configSection); if (!addToConfigSourceUpdates) { addToConfigSourceUpdates = !String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource) && (sectionContentModified || configSection.SectionInformation.ConfigSourceModified); } if ( isModified || configSection.SectionInformation.RawXml == null || saveMode == ConfigurationSaveMode.Full) { // Note: we won't use RawXml if saveMode == Full because Full means we want to // write all properties, and RawXml may not have all properties. ConfigurationSection parentConfigSection = FindImmediateParentSection(configSection); updatedXml = configSection.SerializeSection(parentConfigSection, configSection.SectionInformation.Name, saveMode); ValidateSectionXml(updatedXml, configKey); } else { updatedXml = configSection.SectionInformation.RawXml; } if (string.IsNullOrEmpty(updatedXml)) { // // We always need to emit a section, even if empty, when: // * The section has configSoure // * The section is in a location section that has non-default attributes // * The section is encrypted. // if ( !String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource) || !configSection.SectionInformation.LocationAttributesAreDefault || (configSection.SectionInformation.ProtectionProvider != null)) { updatedXml = WriteEmptyElement(configSection.SectionInformation.Name); } } if (string.IsNullOrEmpty(updatedXml)) { configSection.SectionInformation.Removed = true; // configSection.ElementPresent = false; updatedXml = null; addUpdate = false; if (sectionRecord.HasFileInput) { hasChanged = true; } } else { // configSection.ElementPresent = true; if (sectionAttributesModified || moved || String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource)) { hasChanged = true; } // Encrypt if required. if (configSection.SectionInformation.ProtectionProvider != null) { ProtectedConfigurationSection protectedConfig = GetSection(BaseConfigurationRecord.RESERVED_SECTION_PROTECTED_CONFIGURATION) as ProtectedConfigurationSection; try { string encryptedSection = Host.EncryptSection(updatedXml, configSection.SectionInformation.ProtectionProvider, protectedConfig); updatedXml = ProtectedConfigurationSection.FormatEncryptedSection(encryptedSection, configSection.SectionInformation.Name, configSection.SectionInformation.ProtectionProvider.Name); } catch (Exception e) { throw new ConfigurationErrorsException( SR.GetString(SR.Encryption_failed, configSection.SectionInformation.SectionName, configSection.SectionInformation.ProtectionProvider.Name, e.Message), e); } catch { throw new ConfigurationErrorsException( SR.GetString(SR.Encryption_failed, configSection.SectionInformation.SectionName, configSection.SectionInformation.ProtectionProvider.Name, ExceptionUtil.NoExceptionInformation)); } } } } else if (configSection.SectionInformation.Removed) { addUpdate = false; if (sectionRecord.HasFileInput) { hasChanged = true; } } } catch (Exception e) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_exception_in_config_section_handler, configSection.SectionInformation.SectionName), e); } catch { throw new ConfigurationErrorsException(SR.GetString(SR.Config_exception_in_config_section_handler, configSection.SectionInformation.SectionName)); } } if (addUpdate) { VerifySectionUnlocked(sectionRecord.ConfigKey, null); sectionRecord.AddUpdate = true; DefinitionUpdate definitionUpdate = definitionUpdates.AddUpdate(allowOverride, inheritInChildApplications, moved, updatedXml, sectionRecord); if (addToConfigSourceUpdates) { if (configSourceUpdates == null) { configSourceUpdates = new ArrayList(); } configSourceUpdates.Add(definitionUpdate); } } } } if (_flags[ ForceLocationWritten ]) { // We must write the location tag hasChanged = true; definitionUpdates.RequireLocation = true; } if (_flags[ SuggestLocationRemoval ]) { // We should try to remove location hasChanged = true; } if (hasChanged) { definitionUpdates.CompleteUpdates(); } else { definitionUpdates = null; } }