Inheritance: IInternalConfigRecord
        // 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);
     }
 }
Exemple #3
0
        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);
        }