1 //------------------------------------------------------------------------------
2 // <copyright file="NameValueFileSectionHandler.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6 
7 namespace System.Configuration {
8     using System.Configuration.Internal;
9     using System.IO;
10     using System.Xml;
11     using System.Runtime.Versioning;
12 
13     /// <internalonly/>
14     /// <devdoc>
15     /// <para>
16     /// This section handler allows &lt;appSettings file="user.config" /&gt;
17     /// The file pointed to by the file= attribute is read as if it is
18     /// an appSettings section in the config file.
19     /// Note: the user.config file must have its root element match the
20     /// section referring to it.  So if appSettings has a file="user.config"
21     /// attribute the root element in user.config must also be named appSettings.
22     /// </para>
23     /// </devdoc>
24     public class NameValueFileSectionHandler : IConfigurationSectionHandler {
25 
26         [ResourceExposure(ResourceScope.None)]
27         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
Create(object parent, object configContext, XmlNode section)28         public object Create(object parent, object configContext, XmlNode section) {
29             object result = parent;
30 
31             // parse XML
32             XmlNode fileAttribute = section.Attributes.RemoveNamedItem("file");
33 
34             result = NameValueSectionHandler.CreateStatic(result, section);
35 
36             if (fileAttribute != null && fileAttribute.Value.Length != 0) {
37                 string filename = null;
38                 filename = fileAttribute.Value;
39                 IConfigErrorInfo configXmlNode = fileAttribute as IConfigErrorInfo;
40                 if (configXmlNode == null) {
41                     return null;
42                 }
43 
44                 string configFile = configXmlNode.Filename;
45                 string directory = Path.GetDirectoryName(configFile);
46                 string sourceFileFullPath = Path.Combine(directory, filename);
47 
48                 if (File.Exists(sourceFileFullPath)) {
49 
50                     ConfigXmlDocument doc = new ConfigXmlDocument();
51                     try {
52                         doc.Load(sourceFileFullPath);
53                     }
54                     catch (XmlException e) {
55                         throw new ConfigurationErrorsException(e.Message, e, sourceFileFullPath, e.LineNumber);
56                     }
57 
58                     if (section.Name != doc.DocumentElement.Name) {
59                         throw new ConfigurationErrorsException(
60                                         SR.GetString(SR.Config_name_value_file_section_file_invalid_root, section.Name),
61                                         doc.DocumentElement);
62                     }
63 
64                     result = NameValueSectionHandler.CreateStatic(result, doc.DocumentElement);
65                 }
66             }
67 
68             return result;
69         }
70     }
71 }
72