1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System
.Collections
;
6 using System
.Collections
.Generic
;
7 using System
.Diagnostics
;
8 using System
.Globalization
;
9 using System
.Runtime
.Versioning
;
12 namespace System
.Data
.Common
14 internal partial class DbConnectionOptions
17 // * this method queries "DataDirectory" value from the current AppDomain.
18 // This string is used for to replace "!DataDirectory!" values in the connection string, it is not considered as an "exposed resource".
19 // * This method uses GetFullPath to validate that root path is valid, the result is not exposed out.
20 [ResourceExposure(ResourceScope
.None
)]
21 [ResourceConsumption(ResourceScope
.Machine
, ResourceScope
.Machine
)]
22 internal static string ExpandDataDirectory(string keyword
, string value, ref string datadir
)
24 string fullPath
= null;
25 if ((null != value) && value.StartsWith(DataDirectory
, StringComparison
.OrdinalIgnoreCase
))
27 string rootFolderPath
= datadir
;
28 if (null == rootFolderPath
)
30 // find the replacement path
31 object rootFolderObject
= AppDomain
.CurrentDomain
.GetData("DataDirectory");
32 rootFolderPath
= (rootFolderObject
as string);
33 if ((null != rootFolderObject
) && (null == rootFolderPath
))
35 throw ADP
.InvalidDataDirectory();
37 else if (string.IsNullOrEmpty(rootFolderPath
))
39 rootFolderPath
= AppDomain
.CurrentDomain
.BaseDirectory
;
41 if (null == rootFolderPath
)
45 // cache the |DataDir| for ExpandDataDirectories
46 datadir
= rootFolderPath
;
49 // We don't know if rootFolderpath ends with '\', and we don't know if the given name starts with onw
50 int fileNamePosition
= DataDirectory
.Length
; // filename starts right after the '|datadirectory|' keyword
51 bool rootFolderEndsWith
= (0 < rootFolderPath
.Length
) && rootFolderPath
[rootFolderPath
.Length
- 1] == '\\';
52 bool fileNameStartsWith
= (fileNamePosition
< value.Length
) && value[fileNamePosition
] == '\\';
54 // replace |datadirectory| with root folder path
55 if (!rootFolderEndsWith
&& !fileNameStartsWith
)
58 fullPath
= rootFolderPath
+ '\\' + value.Substring(fileNamePosition
);
60 else if (rootFolderEndsWith
&& fileNameStartsWith
)
62 // need to strip one out
63 fullPath
= rootFolderPath
+ value.Substring(fileNamePosition
+ 1);
67 // simply concatenate the strings
68 fullPath
= rootFolderPath
+ value.Substring(fileNamePosition
);
71 // verify root folder path is a real path without unexpected "..\"
72 if (!ADP
.GetFullPath(fullPath
).StartsWith(rootFolderPath
, StringComparison
.Ordinal
))
74 throw ADP
.InvalidConnectionOptionValue(keyword
);
80 internal string ExpandDataDirectories(ref string filename
, ref int position
)
83 StringBuilder builder
= new StringBuilder(_usersConnectionString
.Length
);
84 string datadir
= null;
87 bool expanded
= false;
89 for (NameValuePair current
= _keyChain
; null != current
; current
= current
.Next
)
91 value = current
.Value
;
93 // remove duplicate keyswords from connectionstring
94 //if ((object)this[current.Name] != (object)value) {
96 // copyPosition += current.Length;
100 // There is a set of keywords we explictly do NOT want to expand |DataDirectory| on
103 switch (current
.Name
)
105 case DbConnectionOptionKeywords
.Driver
:
106 case DbConnectionOptionKeywords
.Pwd
:
107 case DbConnectionOptionKeywords
.UID
:
110 value = ExpandDataDirectory(current
.Name
, value, ref datadir
);
116 switch (current
.Name
)
118 case DbConnectionOptionKeywords
.Provider
:
119 case DbConnectionOptionKeywords
.DataProvider
:
120 case DbConnectionOptionKeywords
.RemoteProvider
:
121 case DbConnectionOptionKeywords
.ExtendedProperties
:
122 case DbConnectionOptionKeywords
.UserID
:
123 case DbConnectionOptionKeywords
.Password
:
124 case DbConnectionOptionKeywords
.UID
:
125 case DbConnectionOptionKeywords
.Pwd
:
128 value = ExpandDataDirectory(current
.Name
, value, ref datadir
);
134 value = current
.Value
;
136 if (_useOdbcRules
|| (DbConnectionOptionKeywords
.FileName
!= current
.Name
))
138 if (value != current
.Value
)
141 AppendKeyValuePairBuilder(builder
, current
.Name
, value, _useOdbcRules
);
146 builder
.Append(_usersConnectionString
, copyPosition
, current
.Length
);
151 // strip out 'File Name=myconnection.udl' for OleDb
152 // remembering is value for which UDL file to open
153 // and where to insert the strnig
156 position
= builder
.Length
;
158 copyPosition
+= current
.Length
;
163 value = builder
.ToString();
172 internal bool HasBlankPassword
{
174 if (!ConvertValueToIntegratedSecurity()) {
175 if (_parsetable
.ContainsKey(KEY
.Password
)) {
176 return ADP
.IsEmpty((string)_parsetable
[KEY
.Password
]);
178 if (_parsetable
.ContainsKey(SYNONYM
.Pwd
)) {
179 return ADP
.IsEmpty((string)_parsetable
[SYNONYM
.Pwd
]); // MDAC 83097
181 return ((_parsetable
.ContainsKey(KEY
.User_ID
) && !ADP
.IsEmpty((string)_parsetable
[KEY
.User_ID
])) || (_parsetable
.ContainsKey(SYNONYM
.UID
) && !ADP
.IsEmpty((string)_parsetable
[SYNONYM
.UID
])));
190 internal static class DbConnectionOptionKeywords
193 internal const string Driver
= "driver";
194 internal const string Pwd
= "pwd";
195 internal const string UID
= "uid";
198 internal const string DataProvider
= "data provider";
199 internal const string ExtendedProperties
= "extended properties";
200 internal const string FileName
= "file name";
201 internal const string Provider
= "provider";
202 internal const string RemoteProvider
= "remote provider";
204 // common keywords (OleDb, OracleClient, SqlClient)
205 internal const string Password
= "password";
206 internal const string UserID
= "user id";