// AssociateContext // // Associate a collection of values with a configRecord // internal void AssociateContext(BaseConfigurationRecord configRecord) { _configRecord = configRecord; // Associate with children foreach (ConfigurationElement currentElement in ConfigurationElements) { currentElement.AssociateContext(_configRecord); } }
internal void AssociateContext(BaseConfigurationRecord configRecord) { this._configRecord = configRecord; foreach (ConfigurationElement element in this.ConfigurationElements) { element.AssociateContext(this._configRecord); } }
internal ContextInformation(BaseConfigurationRecord configRecord) { Debug.Assert(configRecord != null, "configRecord != null"); _hostingContextEvaluated = false; _hostingContext = null; _configRecord = configRecord; }
internal override void AssociateContext(BaseConfigurationRecord configRecord) { base.AssociateContext(configRecord); foreach (Entry entry in this._items) { if (entry._value != null) { entry._value.AssociateContext(configRecord); } } }
void IInternalConfigRoot.Init(IInternalConfigHost host, bool isDesignTime) { _host = host; _isDesignTime = isDesignTime; _hierarchyLock = new ReaderWriterLock(); // Dummy record to hold _children for root if (_isDesignTime) { _rootConfigRecord = MgmtConfigurationRecord.Create(this, null, string.Empty, null); } else { _rootConfigRecord = (BaseConfigurationRecord) RuntimeConfigurationRecord.Create(this, null, string.Empty); } }
// // Clear the result of a configSection evaluation at a particular point // in the hierarchy. // public void ClearResult(BaseConfigurationRecord configRecord, string configKey, bool forceEvaluation) { string[] parts = ConfigPathUtility.GetParts(configRecord.ConfigPath); try { int index; BaseConfigurationRecord currentRecord; AcquireHierarchyLockForRead(); hlFindConfigRecord(parts, out index, out currentRecord); // clear result only if configRecord it is still in the hierarchy if (index == parts.Length && Object.ReferenceEquals(configRecord, currentRecord)) { currentRecord.hlClearResultRecursive(configKey, forceEvaluation); } } finally { ReleaseHierarchyLockForRead(); } }
// // Remove the config record and all its children for the config path. // public void RemoveConfigRecord(BaseConfigurationRecord configRecord) { RemoveConfigImpl(configRecord.ConfigPath, configRecord); }
// // Find and remove the config record and all its children for the config path. // Optionally ensure the config record matches a desired config record. // void RemoveConfigImpl(string configPath, BaseConfigurationRecord configRecord) { if (!ConfigPathUtility.IsValid(configPath)) { throw ExceptionUtil.ParameterInvalid("configPath"); } string[] parts = ConfigPathUtility.GetParts(configPath); BaseConfigurationRecord currentRecord; // search under exclusive writer lock try { int index; AcquireHierarchyLockForWrite(); hlFindConfigRecord(parts, out index, out currentRecord); // Return if not found, or does not match the one we are trying to remove. if (index != parts.Length || (configRecord != null && !Object.ReferenceEquals(configRecord, currentRecord))) return; // Remove it from the hierarchy. currentRecord.Parent.hlRemoveChild(parts[parts.Length - 1]); } finally { ReleaseHierarchyLockForWrite(); } OnConfigRemoved(new InternalConfigEventArgs(configPath)); // Close the record. This is safe to do outside the lock. currentRecord.CloseRecursive(); }
// // Find a config record. // If found, nextIndex == parts.Length and the resulting record is in currentRecord. // If not found, nextIndex is the index of the part of the path not found, and currentRecord // is the record that has been found so far (nexIndex - 1). // private void hlFindConfigRecord(string[] parts, out int nextIndex, out BaseConfigurationRecord currentRecord) { currentRecord = _rootConfigRecord; nextIndex = 0; for (; nextIndex < parts.Length; nextIndex++) { BaseConfigurationRecord childRecord = currentRecord.hlGetChild(parts[nextIndex]); if (childRecord == null) break; currentRecord = childRecord; } }
internal virtual void AssociateContext(BaseConfigurationRecord configRecord) { this._configRecord = configRecord; this.Values.AssociateContext(configRecord); }
internal ContextInformation(BaseConfigurationRecord configRecord) { this._configRecord = configRecord; }
// InitConfigFromFile // // Init the Config From the File. // private void InitConfigFromFile() { bool implicitSectionsAdded = false; try { // If initialization should be delayed, do not read the file. if (ClassFlags[ClassSupportsDelayedInit] && Host.IsInitDelayed(this)) { // determine the root of delayed initialization if (_parent._initDelayedRoot == null) { _initDelayedRoot = this; } else { _initDelayedRoot = _parent._initDelayedRoot; } } else { // // This parent of a record that is not initDelayed must also // not be initDelayed. // Debug.Assert(!_parent.IsInitDelayed, "!_parent.IsInitDelayed"); using (Impersonate()) { // // Get the stream name. Note that this may be an expensive operation // for the client configuration host, which is why it comes after the // check for delayed init. // ConfigStreamInfo.StreamName = Host.GetStreamName(_configPath); if (!String.IsNullOrEmpty(ConfigStreamInfo.StreamName)) { // Lets listen to the stream ConfigStreamInfo.StreamVersion = MonitorStream(null, null, ConfigStreamInfo.StreamName); using (Stream stream = Host.OpenStreamForRead(ConfigStreamInfo.StreamName)) { if (stream == null) { // There is no stream to load from return; } ConfigStreamInfo.HasStream = true; // Determine whether or not to prefetch. _flags[PrefetchAll] = Host.PrefetchAll(_configPath, ConfigStreamInfo.StreamName); using (XmlUtil xmlUtil = new XmlUtil(stream, ConfigStreamInfo.StreamName, true, _initErrors)) { ConfigStreamInfo.StreamEncoding = xmlUtil.Reader.Encoding; // Read the factories Hashtable factoryList = ScanFactories(xmlUtil); _factoryRecords = factoryList; // Add implicit sections before scanning sections AddImplicitSections(null); implicitSectionsAdded = true; // Read the sections themselves if (xmlUtil.Reader.Depth == 1) { ScanSections(xmlUtil); } } } } } } } // // Capture all exceptions and include them in _initErrors so execution in Init can continue. // catch (XmlException e) { // // Treat invalid XML as unrecoverable by replacing all errors with the XML error. // _initErrors.SetSingleGlobalError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, ConfigStreamInfo.StreamName, 0)); } catch (Exception e) { _initErrors.AddError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, ConfigStreamInfo.StreamName, 0), ExceptionAction.Global); } catch { _initErrors.AddError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), null, ConfigStreamInfo.StreamName, 0), ExceptionAction.Global); } // // If there are global errors that make all input invalid, // reset our state so that inherited configuration can still be used, // including location sections that apply to this file. // if (_initErrors.HasGlobalErrors) { // // Parsing of a section may have been in progress when the exception // was thrown, so clear any accumulated local errors. // _initErrors.ResetLocalErrors(); // // Stop monitoring any configSource streams, but still continue // to monitor the main config file if it was successfully monitored. // HybridDictionary streamInfos = null; lock (this) { if (ConfigStreamInfo.HasStreamInfos) { streamInfos = ConfigStreamInfo.StreamInfos; ConfigStreamInfo.ClearStreamInfos(); if (!String.IsNullOrEmpty(ConfigStreamInfo.StreamName)) { StreamInfo fileStreamInfo = (StreamInfo) streamInfos[ConfigStreamInfo.StreamName]; // add this file's streaminfo to the now empty list if (fileStreamInfo != null) { streamInfos.Remove(ConfigStreamInfo.StreamName); ConfigStreamInfo.StreamInfos.Add(ConfigStreamInfo.StreamName, fileStreamInfo); } } } } // Stop monitoring streams outside the lock, to prevent deadlock. if (streamInfos != null) { foreach (StreamInfo streamInfo in streamInfos.Values) { if (streamInfo.IsMonitored) { Host.StopMonitoringStreamForChanges(streamInfo.StreamName, ConfigStreamInfo.CallbackDelegate); } } } // Remove file input if (_sectionRecords != null) { List<SectionRecord> removes = null; foreach (SectionRecord sectionRecord in _sectionRecords.Values) { if (sectionRecord.HasLocationInputs) { // Remove any file input sectionRecord.RemoveFileInput(); } else { // Remove the entire section record if (removes == null) { removes = new List<SectionRecord>(); } removes.Add(sectionRecord); } } if (removes != null) { foreach (SectionRecord sectionRecord in removes) { _sectionRecords.Remove(sectionRecord.ConfigKey); } } } // Remove all location section input defined here if (_locationSections != null) { _locationSections.Clear(); } // Remove all factory records if (_factoryRecords != null) { _factoryRecords.Clear(); } } if (!implicitSectionsAdded) { // Always add implicit sections no matter we have a file or not. AddImplicitSections(null); } }
// Adds a child record. // Requires the hierarchy lock to be acquired (hl) internal void hlAddChild(string configName, BaseConfigurationRecord child) { if (_children == null) { _children = new Hashtable(StringComparer.OrdinalIgnoreCase); } _children.Add(configName, child); }
internal void Init( IInternalConfigRoot configRoot, BaseConfigurationRecord parent, string configPath, string locationSubPath) { _initErrors = new ConfigurationSchemaErrors(); // // try/catch here is only for unexpected exceptions due to errors in // our own code, as we always want the configuration record to be // usable // try { _configRoot = (InternalConfigRoot) configRoot; _parent = parent; _configPath = configPath; _locationSubPath = locationSubPath; _configName = ConfigPathUtility.GetName(configPath); if (IsLocationConfig) { _configStreamInfo = _parent.ConfigStreamInfo; } else { _configStreamInfo = new ConfigRecordStreamInfo(); } // no more initialization in case of root config if (IsRootConfig) return; // determine what features we support _flags[SupportsChangeNotifications] = ClassFlags[ClassSupportsChangeNotifications] && Host.SupportsChangeNotifications; _flags[SupportsRefresh] = ClassFlags[ClassSupportsRefresh] && Host.SupportsRefresh; _flags[SupportsKeepInputs] = ClassFlags[ClassSupportsKeepInputs] || _flags[SupportsRefresh]; _flags[SupportsPath] = Host.SupportsPath; _flags[SupportsLocation] = Host.SupportsLocation; // get static state based on the configPath if (_flags[SupportsLocation]) { _flags[IsAboveApplication] = Host.IsAboveApplication(_configPath); } _flags[IsTrusted] = Host.IsTrustedConfigPath(_configPath); ArrayList locationSubPathInputs = null; if (_flags[SupportsLocation]) { // // Treat location inputs from parent record // as though they were bonafide sections in this record. // if (IsLocationConfig && _parent._locationSections != null) { // Resolve paths and check for errors in location sections. _parent.ResolveLocationSections(); int i = 0; while (i < _parent._locationSections.Count) { LocationSectionRecord locationSectionRecord = (LocationSectionRecord) _parent._locationSections[i]; if (!StringUtil.EqualsIgnoreCase(locationSectionRecord.SectionXmlInfo.SubPath, _locationSubPath)) { i++; } else { // remove the locationSectionRecord from the list _parent._locationSections.RemoveAt(i); if (locationSubPathInputs == null) { locationSubPathInputs = new ArrayList(); } locationSubPathInputs.Add(locationSectionRecord); } } } // // Add location inputs that apply to this path, all the way up the parent hierarchy. // if (Host.IsLocationApplicable(_configPath)) { BaseConfigurationRecord current = _parent; while (!current.IsRootConfig) { if (current._locationSections != null) { current.ResolveLocationSections(); foreach (LocationSectionRecord locationSectionRecord in current._locationSections) { // We use the location tag input if: // - The path matches, and // - It's not skipped due to inheritInChildApplications setting. if (StringUtil.EqualsIgnoreCase(locationSectionRecord.SectionXmlInfo.TargetConfigPath, this._configPath) && !ShouldSkipDueToInheritInChildApplications(locationSectionRecord.SectionXmlInfo.SkipInChildApps)) { // add the location input for this section SectionRecord sectionRecord = EnsureSectionRecord(locationSectionRecord.ConfigKey, true); SectionInput sectionInput = new SectionInput( locationSectionRecord.SectionXmlInfo, locationSectionRecord.ErrorsList); sectionRecord.AddLocationInput(sectionInput); // copy the initialization errors to the record if (locationSectionRecord.HasErrors) { this._initErrors.AddSavedLocalErrors(locationSectionRecord.Errors); } } } } current = current._parent; } } } if (!IsLocationConfig) { // // If config file exists, open it and parse it once so we can // find what to evaluate later. // InitConfigFromFile(); } else { // Add location sections for this record as bonafide sections. if (locationSubPathInputs != null) { foreach (LocationSectionRecord locationSectionRecord in locationSubPathInputs) { // add the file input SectionRecord sectionRecord = EnsureSectionRecord(locationSectionRecord.ConfigKey, true); SectionInput sectionInput = new SectionInput(locationSectionRecord.SectionXmlInfo, locationSectionRecord.ErrorsList); sectionRecord.AddFileInput(sectionInput); // copy the initialization errors to the record if (locationSectionRecord.HasErrors) { this._initErrors.AddSavedLocalErrors(locationSectionRecord.Errors); } } } } } // // Capture all exceptions and include them in initialization errors. // catch (Exception e) { string streamname = (ConfigStreamInfo != null) ? ConfigStreamInfo.StreamName : null; _initErrors.AddError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, streamname, 0), ExceptionAction.Global); } catch { string streamname = (ConfigStreamInfo != null) ? ConfigStreamInfo.StreamName : null; _initErrors.AddError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), null, streamname, 0), ExceptionAction.Global); } }
// Search the config hierarchy for a FactoryRecord. // Note that callers should check whether the returned factory has errors. internal FactoryRecord FindFactoryRecord(string configKey, bool permitErrors, out BaseConfigurationRecord configRecord) { configRecord = null; BaseConfigurationRecord tConfigRecord = this; while (!tConfigRecord.IsRootConfig) { FactoryRecord factoryRecord = tConfigRecord.GetFactoryRecord(configKey, permitErrors); if (factoryRecord != null) { #if DBG if (IsImplicitSection(configKey) && !factoryRecord.HasErrors) { Debug.Assert(tConfigRecord._parent.IsRootConfig, "Implicit section should be found only at the record beneath the root (e.g. machine.config)"); } #endif configRecord = tConfigRecord; return factoryRecord; } tConfigRecord = tConfigRecord._parent; } return null; }
internal void SetRuntimeConfigurationInformation(BaseConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord) { _flags[ Flag_Attached ] = true; // factory info _configKey = factoryRecord.ConfigKey; _group = factoryRecord.Group; _name = factoryRecord.Name; _typeName = factoryRecord.FactoryTypeName; _allowDefinition = factoryRecord.AllowDefinition; _allowExeDefinition = factoryRecord.AllowExeDefinition; _flags[ Flag_AllowLocation ] = factoryRecord.AllowLocation; _flags[ Flag_RestartOnExternalChanges ] = factoryRecord.RestartOnExternalChanges; _flags[ Flag_RequirePermission ] = factoryRecord.RequirePermission; if (factoryRecord.IsUndeclared) { _flags[ Flag_IsUndeclared ] = true; _flags[ Flag_Declared ] = false; _flags[ Flag_DeclarationRequired ] = false; } else { _flags[ Flag_IsUndeclared ] = false; _flags[ Flag_Declared ] = configRecord.GetFactoryRecord(factoryRecord.ConfigKey, false) != null; _flags[ Flag_DeclarationRequired ] = configRecord.IsRootDeclaration(factoryRecord.ConfigKey, false); } // section info _flags[ Flag_LocationLocked ] = sectionRecord.Locked; if (sectionRecord.HasFileInput) { SectionInput fileInput = sectionRecord.FileInput; _flags[ Flag_ProtectionProviderDetermined ] = fileInput.IsProtectionProviderDetermined; _protectionProvider = fileInput.ProtectionProvider; SectionXmlInfo sectionXmlInfo = fileInput.SectionXmlInfo; _configSource = sectionXmlInfo.ConfigSource; _configSourceStreamName = sectionXmlInfo.ConfigSourceStreamName; _flags[ Flag_AllowOverride ] = !sectionXmlInfo.LockChildren; _flags[ Flag_InheritInChildApps ] = !sectionXmlInfo.SkipInChildApps; _protectionProviderName = sectionXmlInfo.ProtectionProviderName; } else { _flags[ Flag_ProtectionProviderDetermined ] = false; _protectionProvider = null; } // element context information _configurationSection.AssociateContext( configRecord ); }
internal void SetRuntimeConfigurationInformation(BaseConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord) { this._flags[1] = true; this._configKey = factoryRecord.ConfigKey; this._group = factoryRecord.Group; this._name = factoryRecord.Name; this._typeName = factoryRecord.FactoryTypeName; this._allowDefinition = factoryRecord.AllowDefinition; this._allowExeDefinition = factoryRecord.AllowExeDefinition; this._flags[8] = factoryRecord.AllowLocation; this._flags[0x10] = factoryRecord.RestartOnExternalChanges; this._flags[0x20] = factoryRecord.RequirePermission; this._overrideModeDefault = factoryRecord.OverrideModeDefault; if (factoryRecord.IsUndeclared) { this._flags[0x2000] = true; this._flags[2] = false; this._flags[4] = false; } else { this._flags[0x2000] = false; this._flags[2] = configRecord.GetFactoryRecord(factoryRecord.ConfigKey, false) != null; this._flags[4] = configRecord.IsRootDeclaration(factoryRecord.ConfigKey, false); } this._flags[0x40] = sectionRecord.Locked; this._flags[0x80] = sectionRecord.LockChildren; this._flags[0x4000] = sectionRecord.LockChildrenWithoutFileInput; if (sectionRecord.HasFileInput) { SectionInput fileInput = sectionRecord.FileInput; this._flags[0x800] = fileInput.IsProtectionProviderDetermined; this._protectionProvider = fileInput.ProtectionProvider; SectionXmlInfo sectionXmlInfo = fileInput.SectionXmlInfo; this._configSource = sectionXmlInfo.ConfigSource; this._configSourceStreamName = sectionXmlInfo.ConfigSourceStreamName; this._overrideMode = sectionXmlInfo.OverrideModeSetting; this._flags[0x100] = !sectionXmlInfo.SkipInChildApps; this._protectionProviderName = sectionXmlInfo.ProtectionProviderName; } else { this._flags[0x800] = false; this._protectionProvider = null; } this._configurationSection.AssociateContext(configRecord); }
internal override void AssociateContext(BaseConfigurationRecord configRecord) { base.AssociateContext(configRecord); foreach (Entry entry in Items) entry.Value?.AssociateContext(configRecord); }