DbConnectionOptions.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / Common / DbConnectionOptions.cs / 2 / DbConnectionOptions.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.Common {
 
    using System;
    using System.Collections;
    using System.Data;
#if ORACLE 
    using System.Data.OracleClient;
#endif //ORACLE 
    using System.Diagnostics; 
    using System.Globalization;
    using System.Runtime.Serialization; 
    using System.Security.Permissions;
    using System.Text;
    using System.Text.RegularExpressions;
 
    internal class DbConnectionOptions {
        // instances of this class are intended to be immutable, i.e readonly 
        // used by pooling classes so it is much easier to verify correctness 
        // when not worried about the class being modified during execution
 
#if DEBUG
        /*private const string ConnectionStringPatternV1 =
             "[\\s;]*"
            +"(?([^=\\s]|\\s+[^=\\s]|\\s+==|==)+)" 
            +   "\\s*=(?!=)\\s*"
            +"(?(" 
            +   "(" + "\"" + "([^\"]|\"\")*" + "\"" + ")" 
            +   "|"
            +   "(" + "'" + "([^']|'')*" + "'" + ")" 
            +   "|"
            +   "(" + "(?![\"'])" + "([^\\s;]|\\s+[^\\s;])*" + "(?([^=\\s\\p{Cc}]|\\s+[^=\\s\\p{Cc}]|\\s+==|==)+)"  // allow any visible character for keyname except '=' which must quoted as '==' 
            + "\\s*=(?!=)\\s*"                                          // the equal sign divides the key and value parts
            + "(?"
            +  "(\"([^\"\u0000]|\"\")*\")"                              // double quoted string, " must be quoted as ""
            +  "|" 
            +  "('([^'\u0000]|'')*')"                                   // single quoted string, ' must be quoted as ''
            +  "|" 
            +  "((?![\"'\\s])"                                          // unquoted value must not start with " or ' or space, would also like = but too late to change 
            +   "([^;\\s\\p{Cc}]|\\s+[^;\\s\\p{Cc}])*"                  // control characters must be quoted
            +  "(?([^=\\s\\p{Cc}]|\\s+[^=\\s\\p{Cc}])+)"            // allow any visible character for keyname except '=' 
            + "\\s*=\\s*"                                               // the equal sign divides the key and value parts
            + "(?"
            +  "(\\{([^\\}\u0000]|\\}\\})*\\})"                         // quoted string, starts with { and ends with }
            +  "|" 
            +  "((?![\\{\\s])"                                          // unquoted value must not start with { or space, would also like = but too late to change
            +   "([^;\\s\\p{Cc}]|\\s+[^;\\s\\p{Cc}])*"                  // control characters must be quoted 
            +  "(? = in keywords 
        //     first key-value pair wins
        //     quote values using \{ and \}, only driver= and pwd= appear to generically allow quoting
        //     do not strip quotes from value, or add quotes except for driver keyword
        // OLEDB: 
        //     http://msdn.microsoft.com/library/default.asp?url=/library/en-us/oledb/htm/oledbconnectionstringsyntax.asp
        //     support == -> = in keywords 
        //     last key-value pair wins 
        //     quote values using \" or \'
        //     strip quotes from value 
        internal readonly bool UseOdbcRules;

        private System.Security.PermissionSet _permissionset;
 
        // called by derived classes that may cache based on connectionString
        public DbConnectionOptions(string connectionString) 
            : this(connectionString, null, false) { 
        }
 
        // synonyms hashtable is meant to be read-only translation of parsed string
        // keywords/synonyms to a known keyword string
        public DbConnectionOptions(string connectionString, Hashtable synonyms, bool useOdbcRules) {
            UseOdbcRules = useOdbcRules; 
            _parsetable = new Hashtable();
            _usersConnectionString = ((null != connectionString) ? connectionString : ""); 
 
            // first pass on parsing, initial syntax check
            if (0 < _usersConnectionString.Length) { 
                KeyChain = ParseInternal(_parsetable, _usersConnectionString, true, synonyms, UseOdbcRules);
                HasPasswordKeyword = (_parsetable.ContainsKey(KEY.Password) || _parsetable.ContainsKey(SYNONYM.Pwd));
            }
        } 

#if !ORACLE 
        protected DbConnectionOptions(DbConnectionOptions connectionOptions) { // Clone used by SqlConnectionString 
            _usersConnectionString = connectionOptions._usersConnectionString;
            HasPasswordKeyword = connectionOptions.HasPasswordKeyword; 
            UseOdbcRules = connectionOptions.UseOdbcRules;
            _parsetable = connectionOptions._parsetable;
            KeyChain = connectionOptions.KeyChain;
        } 
#endif
 
 
        public string UsersConnectionString(bool hidePassword) {
            return UsersConnectionString(hidePassword, false); 
        }

        private string UsersConnectionString(bool hidePassword, bool forceHidePassword) {
            string connectionString = _usersConnectionString; 
            if (HasPasswordKeyword && (forceHidePassword || (hidePassword && !HasPersistablePassword))) {
                ReplacePasswordPwd(out connectionString, false); 
            } 
            return ((null != connectionString) ? connectionString : "");
        } 

        internal string UsersConnectionStringForTrace() {
            return UsersConnectionString(true, true);
        } 

        internal bool HasBlankPassword { 
            get { 
                if (!ConvertValueToIntegratedSecurity()) {
                    if (_parsetable.ContainsKey(KEY.Password)) { 
                        return ADP.IsEmpty((string)_parsetable[KEY.Password]);
                    } else
                    if (_parsetable.ContainsKey(SYNONYM.Pwd)) {
                        return ADP.IsEmpty((string)_parsetable[SYNONYM.Pwd]); // MDAC 83097 
                    } else {
                        return ((_parsetable.ContainsKey(KEY.User_ID) && !ADP.IsEmpty((string)_parsetable[KEY.User_ID])) || (_parsetable.ContainsKey(SYNONYM.UID) && !ADP.IsEmpty((string)_parsetable[SYNONYM.UID]))); 
                    } 
                }
                return false; 
            }
        }

        internal bool HasPersistablePassword { 
            get {
                if (HasPasswordKeyword) { 
                    return ConvertValueToBoolean(KEY.Persist_Security_Info, false); 
                }
                return true; // no password means persistable password so we don't have to munge 
            }
        }

        public bool IsEmpty { 
            get { return (null == KeyChain); }
        } 
 
        internal Hashtable Parsetable {
            get { return _parsetable; } 
        }

#if !ORACLE
        public ICollection Keys { 
            get { return _parsetable.Keys; }
        } 
 
        public string this[string keyword] {
            get { return (string)_parsetable[keyword]; } 
        }

        internal static void AppendKeyValuePairBuilder(StringBuilder builder, string keyName, string keyValue, bool useOdbcRules) {
            ADP.CheckArgumentNull(builder, "builder"); 
            ADP.CheckArgumentLength(keyName, "keyName");
 
            if ((null == keyName) || !ConnectionStringValidKeyRegex.IsMatch(keyName)) { 
                throw ADP.InvalidKeyname(keyName);
            } 
            if ((null != keyValue) && !IsValueValidInternal(keyValue)) {
                throw ADP.InvalidValue(keyName);
            }
 
            if ((0 < builder.Length) && (';' != builder[builder.Length-1])) {
                builder.Append(";"); 
            } 

            if (useOdbcRules) { 
                builder.Append(keyName);
            }
            else {
                builder.Append(keyName.Replace("=", "==")); 
            }
            builder.Append("="); 
 
            if (null != keyValue) { // else =;
                if (useOdbcRules) { 
                    if ((0 < keyValue.Length) &&
                        (('{' == keyValue[0]) || (0 <= keyValue.IndexOf(';')) || (0 == String.Compare(DbConnectionStringKeywords.Driver, keyName, StringComparison.OrdinalIgnoreCase))) &&
                        !ConnectionStringQuoteOdbcValueRegex.IsMatch(keyValue))
                    { 
                        // always quote Driver value (required for ODBC Version 2.65 and earlier)
                        // always quote values that contain a ';' 
                        builder.Append('{').Append(keyValue.Replace("}", "}}")).Append('}'); 
                    }
                    else { 
                        builder.Append(keyValue);
                    }
                }
                else if (ConnectionStringQuoteValueRegex.IsMatch(keyValue)) { 
                    //  -> 
                    builder.Append(keyValue); 
                } 
                else if ((-1 != keyValue.IndexOf('\"')) && (-1 == keyValue.IndexOf('\''))) {
                    //  -> <'val"ue'> 
                    builder.Append('\'');
                    builder.Append(keyValue);
                    builder.Append('\'');
                } 
                else {
                    //  -> <"val'ue"> 
                    // <=value> -> <"=value"> 
                    // <;value> -> <";value">
                    // < value> -> <" value"> 
                    //  -> <"va lue">
                    //  -> <"va'""lue">
                    builder.Append('\"');
                    builder.Append(keyValue.Replace("\"", "\"\"")); 
                    builder.Append('\"');
                } 
            } 
        }
 
#endif
        public bool ConvertValueToBoolean(string keyName, bool defaultValue) {
            object value = _parsetable[keyName];
            if (null == value) { 
                return defaultValue;
            } 
            return ConvertValueToBooleanInternal(keyName, (string) value); 
        }
 
        internal static bool ConvertValueToBooleanInternal(string keyName, string stringValue) {
            if (CompareInsensitiveInvariant(stringValue, "true") || CompareInsensitiveInvariant(stringValue, "yes"))
                return true;
            else if (CompareInsensitiveInvariant(stringValue, "false") || CompareInsensitiveInvariant(stringValue, "no")) 
                return false;
            else { 
                string tmp = stringValue.Trim();  // Remove leading & trailing white space. 
                if (CompareInsensitiveInvariant(tmp, "true") || CompareInsensitiveInvariant(tmp, "yes"))
                    return true; 
                else if (CompareInsensitiveInvariant(tmp, "false") || CompareInsensitiveInvariant(tmp, "no"))
                    return false;
                else {
                    throw ADP.InvalidConnectionOptionValue(keyName); 
                }
            } 
        } 

        // same as Boolean, but with SSPI thrown in as valid yes 
        public bool ConvertValueToIntegratedSecurity() {
            object value = _parsetable[KEY.Integrated_Security];
            if (null == value) {
                return false; 
            }
            return ConvertValueToIntegratedSecurityInternal((string) value); 
        } 

        internal bool ConvertValueToIntegratedSecurityInternal(string stringValue) { 
            if (CompareInsensitiveInvariant(stringValue, "sspi") || CompareInsensitiveInvariant(stringValue, "true") || CompareInsensitiveInvariant(stringValue, "yes"))
                return true;
            else if (CompareInsensitiveInvariant(stringValue, "false") || CompareInsensitiveInvariant(stringValue, "no"))
                return false; 
            else {
                string tmp = stringValue.Trim();  // Remove leading & trailing white space. 
                if (CompareInsensitiveInvariant(tmp, "sspi") || CompareInsensitiveInvariant(tmp, "true") || CompareInsensitiveInvariant(tmp, "yes")) 
                    return true;
                else if (CompareInsensitiveInvariant(tmp, "false") || CompareInsensitiveInvariant(tmp, "no")) 
                    return false;
                else {
                    throw ADP.InvalidConnectionOptionValue(KEY.Integrated_Security);
                } 
            }
        } 
 
        public int ConvertValueToInt32(string keyName, int defaultValue) {
            object value = _parsetable[keyName]; 
            if (null == value) {
                return defaultValue;
            }
            return ConvertToInt32Internal(keyName, (string) value); 
        }
 
        internal static int ConvertToInt32Internal(string keyname, string stringValue) { 
            try {
                return System.Int32.Parse(stringValue, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture); 
            }
            catch (FormatException e) {
                throw ADP.InvalidConnectionOptionValue(keyname, e);
            } 
            catch (OverflowException e) {
                throw ADP.InvalidConnectionOptionValue(keyname, e); 
            } 
        }
 
        public string ConvertValueToString(string keyName, string defaultValue) {
            string value = (string)_parsetable[keyName];
            return ((null != value) ? value : defaultValue);
        } 

        static private bool CompareInsensitiveInvariant(string strvalue, string strconst) { 
            return (0 == StringComparer.OrdinalIgnoreCase.Compare(strvalue, strconst)); 
        }
 
#if !ORACLE
        public bool ContainsKey(string keyword) {
            return _parsetable.ContainsKey(keyword);
        } 
#endif
 
        protected internal virtual System.Security.PermissionSet CreatePermissionSet() { 
            return null;
        } 

        internal void DemandPermission() {
            if (null == _permissionset) {
                _permissionset = CreatePermissionSet(); 
            }
            _permissionset.Demand(); 
        } 

        protected internal virtual string Expand() { 
            return _usersConnectionString;
        }

#if !ORACLE 
        internal static string ExpandDataDirectory(string keyword, string value, ref string datadir) {
            string fullPath = null; 
            if ((null != value) && value.StartsWith(DataDirectory, StringComparison.OrdinalIgnoreCase)) { 

                string rootFolderPath = datadir; 
                if (null == rootFolderPath) {
                    // find the replacement path
                    object rootFolderObject = AppDomain.CurrentDomain.GetData("DataDirectory");
                    rootFolderPath = (rootFolderObject as string); 
                    if ((null != rootFolderObject) && (null == rootFolderPath)) {
                        throw ADP.InvalidDataDirectory(); 
                    } 
                    else if (ADP.IsEmpty(rootFolderPath)) {
                        rootFolderPath = AppDomain.CurrentDomain.BaseDirectory; 
                    }
                    if (null == rootFolderPath) {
                        rootFolderPath = "";
                    } 
                    // cache the |DataDir| for ExpandDataDirectories
                    datadir = rootFolderPath; 
                } 

                // We don't know if rootFolderpath ends with '\', and we don't know if the given name starts with onw 
                int fileNamePosition = DataDirectory.Length;    // filename starts right after the '|datadirectory|' keyword
                bool rootFolderEndsWith = (0 < rootFolderPath.Length) && rootFolderPath[rootFolderPath.Length-1] == '\\';
                bool fileNameStartsWith = (fileNamePosition < value.Length) && value[fileNamePosition] == '\\';
 
                // replace |datadirectory| with root folder path
                if (!rootFolderEndsWith && !fileNameStartsWith) { 
                    // need to insert '\' 
                    fullPath = rootFolderPath + '\\' + value.Substring(fileNamePosition);
                } 
                else if (rootFolderEndsWith && fileNameStartsWith) {
                    // need to strip one out
                    fullPath = rootFolderPath + value.Substring(fileNamePosition+1);
                } 
                else {
                    // simply concatenate the strings 
                    fullPath = rootFolderPath + value.Substring(fileNamePosition); 
                }
 
                // verify root folder path is a real path without unexpected "..\"
                if (!ADP.GetFullPath(fullPath).StartsWith(rootFolderPath, StringComparison.Ordinal)) {
                    throw ADP.InvalidConnectionOptionValue(keyword);
                } 
            }
            return fullPath; 
        } 

        internal string ExpandDataDirectories(ref string filename, ref int position) { 
            string value = null;
            StringBuilder builder = new StringBuilder(_usersConnectionString.Length);
            string datadir = null;
 
            int copyPosition = 0;
            bool expanded = false; 
 
            for(NameValuePair current = KeyChain; null != current; current = current.Next) {
                value = current.Value; 

                // remove duplicate keyswords from connectionstring
                //if ((object)this[current.Name] != (object)value) {
                //    expanded = true; 
                //    copyPosition += current.Length;
                //    continue; 
                //} 

                // There is a set of keywords we explictly do NOT want to expand |DataDirectory| on 
                if (UseOdbcRules) {
                    switch(current.Name) {
                    case DbConnectionOptionKeywords.Driver:
                    case DbConnectionOptionKeywords.Pwd: 
                    case DbConnectionOptionKeywords.UID:
                        break; 
                    default: 
                        value = ExpandDataDirectory(current.Name, value, ref datadir);
                        break; 
                    }
                }
                else {
                    switch(current.Name) { 
                    case DbConnectionOptionKeywords.Provider:
                    case DbConnectionOptionKeywords.DataProvider: 
                    case DbConnectionOptionKeywords.RemoteProvider: 
                    case DbConnectionOptionKeywords.ExtendedProperties:
                    case DbConnectionOptionKeywords.UserID: 
                    case DbConnectionOptionKeywords.Password:
                    case DbConnectionOptionKeywords.UID:
                    case DbConnectionOptionKeywords.Pwd:
                        break; 
                    default:
                        value = ExpandDataDirectory(current.Name, value, ref datadir); 
                        break; 
                    }
                } 
                if (null == value) {
                    value = current.Value;
                }
                if (UseOdbcRules || (DbConnectionOptionKeywords.FileName != current.Name)) { 
                    if (value != current.Value) {
                        expanded = true; 
                        AppendKeyValuePairBuilder(builder, current.Name, value, UseOdbcRules); 
                        builder.Append(';');
                    } 
                    else {
                        builder.Append(_usersConnectionString, copyPosition, current.Length);
                    }
                } 
                else {
                    // strip out 'File Name=myconnection.udl' for OleDb 
                    // remembering is value for which UDL file to open 
                    // and where to insert the strnig
                    expanded = true; 
                    filename = value;
                    position = builder.Length;
                }
                copyPosition += current.Length; 
            }
 
            if (expanded) { 
                value = builder.ToString();
            } 
            else {
                value = null;
            }
            return value; 
        }
 
        internal string ExpandKeyword(string keyword, string replacementValue) { 
            // preserve duplicates, updated keyword value with replacement value
            // if keyword not specified, append to end of the string 
            bool expanded = false;
            int copyPosition = 0;

            StringBuilder builder = new StringBuilder(_usersConnectionString.Length); 
            for(NameValuePair current = KeyChain; null != current; current = current.Next) {
                if ((current.Name == keyword) && (current.Value == this[keyword])) { 
                    // only replace the parse end-result value instead of all values 
                    // so that when duplicate-keywords occur other original values remain in place
                    AppendKeyValuePairBuilder(builder, current.Name, replacementValue, UseOdbcRules); 
                    builder.Append(';');
                    expanded = true;
                }
                else { 
                    builder.Append(_usersConnectionString, copyPosition, current.Length);
                } 
                copyPosition += current.Length; 
            }
 
            if (!expanded) {
                //
                Debug.Assert(!UseOdbcRules, "ExpandKeyword not ready for Odbc");
                AppendKeyValuePairBuilder(builder, keyword, replacementValue, UseOdbcRules); 
            }
            return builder.ToString(); 
        } 
#endif
#if DEBUG 
        [System.Diagnostics.Conditional("DEBUG")]
        private static void DebugTraceKeyValuePair(string keyname, string keyvalue, Hashtable synonyms) {
            if (Bid.AdvancedOn) {
                Debug.Assert(keyname == keyname.ToLower(CultureInfo.InvariantCulture), "missing ToLower"); 

                string realkeyname = ((null != synonyms) ? (string)synonyms[keyname] : keyname); 
                if ((KEY.Password != realkeyname) && (SYNONYM.Pwd != realkeyname)) { // don't trace passwords ever! 
                    if (null != keyvalue) {
                        Bid.Trace(" KeyName='%ls', KeyValue='%ls'\n", keyname, keyvalue); 
                    }
                    else {
                        Bid.Trace(" KeyName='%ls'\n", keyname);
                    } 
                }
            } 
        } 
#endif
 
        static private string GetKeyName(StringBuilder buffer) {
            int count = buffer.Length;
            while ((0 < count) && Char.IsWhiteSpace(buffer[count-1])) {
                count--; // trailing whitespace 
            }
            return buffer.ToString(0, count).ToLower(CultureInfo.InvariantCulture); 
        } 

        static private string GetKeyValue(StringBuilder buffer, bool trimWhitespace) { 
            int count = buffer.Length;
            int index = 0;
            if (trimWhitespace) {
                while ((index < count) && Char.IsWhiteSpace(buffer[index])) { 
                    index++; // leading whitespace
                } 
                while ((0 < count) && Char.IsWhiteSpace(buffer[count-1])) { 
                    count--; // trailing whitespace
                } 
            }
            return buffer.ToString(index, count - index);
        }
 
        // transistion states used for parsing
        private enum ParserState { 
            NothingYet=1,   //start point 
            Key,
            KeyEqual, 
            KeyEnd,
            UnquotedValue,
            DoubleQuoteValue,
            DoubleQuoteValueQuote, 
            SingleQuoteValue,
            SingleQuoteValueQuote, 
            BraceQuoteValue, 
            BraceQuoteValueQuote,
            QuotedValueEnd, 
            NullTermination,
        };

        static internal int GetKeyValuePair(string connectionString, int currentPosition, StringBuilder buffer, bool useOdbcRules, out string keyname, out string keyvalue) { 
            int startposition = currentPosition;
 
            buffer.Length = 0; 
            keyname = null;
            keyvalue = null; 

            char currentChar = '\0';

            ParserState parserState = ParserState.NothingYet; 
            int length = connectionString.Length;
            for (; currentPosition < length; ++currentPosition) { 
                currentChar = connectionString[currentPosition]; 

                switch(parserState) { 
                case ParserState.NothingYet: // [\\s;]*
                    if ((';' == currentChar) || Char.IsWhiteSpace(currentChar)) {
                        continue;
                    } 
                    if ('\0' == currentChar)            { parserState = ParserState.NullTermination; continue; } // MDAC 83540
                    if (Char.IsControl(currentChar))    { throw ADP.ConnectionStringSyntax(startposition); } 
                    startposition = currentPosition; 
                    if ('=' != currentChar) { // MDAC 86902
                        parserState = ParserState.Key; 
                        break;
                    }
                    else {
                        parserState = ParserState.KeyEqual; 
                        continue;
                    } 
 
                case ParserState.Key: // (?([^=\\s\\p{Cc}]|\\s+[^=\\s\\p{Cc}]|\\s+==|==)+)
                    if ('=' == currentChar)             { parserState = ParserState.KeyEqual;       continue; } 
                    if (Char.IsWhiteSpace(currentChar)) { break; }
                    if (Char.IsControl(currentChar))    { throw ADP.ConnectionStringSyntax(startposition); }
                    break;
 
                case ParserState.KeyEqual: // \\s*=(?!=)\\s*
                    if (!useOdbcRules && '=' == currentChar) { parserState = ParserState.Key;            break; } 
                    keyname = GetKeyName(buffer); 
                    if (ADP.IsEmpty(keyname))           { throw ADP.ConnectionStringSyntax(startposition); }
                    buffer.Length = 0; 
                    parserState = ParserState.KeyEnd;
                    goto case ParserState.KeyEnd;

                case ParserState.KeyEnd: 
                    if (Char.IsWhiteSpace(currentChar)) { continue; }
                    if (useOdbcRules) { 
                        if ('{' == currentChar)             { parserState = ParserState.BraceQuoteValue; break; } 
                    }
                    else { 
                        if ('\'' == currentChar)            { parserState = ParserState.SingleQuoteValue; continue; }
                        if ('"' == currentChar)             { parserState = ParserState.DoubleQuoteValue; continue; }
                    }
                    if (';' == currentChar)             { goto ParserExit; } 
                    if ('\0' == currentChar)            { goto ParserExit; }
                    if (Char.IsControl(currentChar))    { throw ADP.ConnectionStringSyntax(startposition); } 
                    parserState = ParserState.UnquotedValue; 
                    break;
 
                case ParserState.UnquotedValue: // "((?![\"'\\s])" + "([^;\\s\\p{Cc}]|\\s+[^;\\s\\p{Cc}])*" + "(?");
                    Debug.Assert(value1 == value2, "ParseInternal code vs. regex mismatch keyvalue <" + value1 + "> <" + value2 +">"); 
                }
 
            } 
            catch(ArgumentException f) {
                if (null != e) { 
                    string msg1 = e.Message;
                    string msg2 = f.Message;
                    if (msg1.StartsWith("Keyword not supported:", StringComparison.Ordinal) && msg2.StartsWith("Format of the initialization string", StringComparison.Ordinal)) {
                    } 
                    else {
                        Debug.Assert(msg1 == msg2, "ParseInternal code vs regex message mismatch: <"+msg1+"> <"+msg2+">"); 
                    } 
                }
                else { 
                    Debug.Assert(false, "ParseInternal code vs regex throw mismatch " + f.Message);
                }
                e = null;
            } 
            if (null != e) {
                Debug.Assert(false, "ParseInternal code threw exception vs regex mismatch"); 
            } 
        }
#endif 
        private static NameValuePair ParseInternal(Hashtable parsetable, string connectionString, bool buildChain, Hashtable synonyms, bool firstKey) {
            Debug.Assert(null != connectionString, "null connectionstring");
            StringBuilder buffer = new StringBuilder();
            NameValuePair localKeychain = null, keychain = null; 
#if DEBUG
            try { 
#endif 
                int nextStartPosition = 0;
                int endPosition = connectionString.Length; 
                while (nextStartPosition < endPosition) {
                    int startPosition = nextStartPosition;

                    string keyname, keyvalue; 
                    nextStartPosition = GetKeyValuePair(connectionString, startPosition, buffer, firstKey, out keyname, out keyvalue);
                    if (ADP.IsEmpty(keyname)) { 
                        // if (nextStartPosition != endPosition) { throw; } 
                        break;
                    } 
#if DEBUG
                    DebugTraceKeyValuePair(keyname, keyvalue, synonyms);

                    Debug.Assert(IsKeyNameValid(keyname), "ParseFailure, invalid keyname"); 
                    Debug.Assert(IsValueValidInternal(keyvalue), "parse failure, invalid keyvalue");
#endif 
                    string realkeyname = ((null != synonyms) ? (string)synonyms[keyname] : keyname); 
                    if (!IsKeyNameValid(realkeyname)) {
                        throw ADP.KeywordNotSupported(keyname); 
                    }
                    if (!firstKey || !parsetable.Contains(realkeyname)) {
                        parsetable[realkeyname] = keyvalue; // last key-value pair wins (or first)
                    } 

                    if(null != localKeychain) { 
                        localKeychain = localKeychain.Next = new NameValuePair(realkeyname, keyvalue, nextStartPosition - startPosition); 
                    }
                    else if (buildChain) { // first time only - don't contain modified chain from UDL file 
                        keychain = localKeychain = new NameValuePair(realkeyname, keyvalue, nextStartPosition - startPosition);
                    }
                }
#if DEBUG 
            }
            catch(ArgumentException e) { 
                ParseComparision(parsetable, connectionString, synonyms, firstKey, e); 
                throw;
            } 
            ParseComparision(parsetable, connectionString, synonyms, firstKey, null);
#endif
            return keychain;
        } 

        internal NameValuePair ReplacePasswordPwd(out string constr, bool fakePassword) { 
            bool expanded = false; 
            int copyPosition = 0;
            NameValuePair head = null, tail = null, next = null; 
            StringBuilder builder = new StringBuilder(_usersConnectionString.Length);
            for(NameValuePair current = KeyChain; null != current; current = current.Next) {
                if ((KEY.Password != current.Name) && (SYNONYM.Pwd != current.Name)) {
                    builder.Append(_usersConnectionString, copyPosition, current.Length); 
                    if (fakePassword) {
                        next = new NameValuePair(current.Name, current.Value, current.Length); 
                    } 
                }
                else if (fakePassword) { // replace user password/pwd value with * 
                    const string equalstar = "=*;";
                    builder.Append(current.Name).Append(equalstar);
                    next = new NameValuePair(current.Name, "*", current.Name.Length + equalstar.Length);
                    expanded = true; 
                }
                else { // drop the password/pwd completely in returning for user 
                    expanded = true; 
                }
 
                if (fakePassword) {
                    if (null != tail) {
                        tail = tail.Next = next;
                    } 
                    else {
                        tail = head = next; 
                    } 
                }
                copyPosition += current.Length; 
            }
            Debug.Assert(expanded, "password/pwd was not removed");
            constr = builder.ToString();
            return head; 
        }
 
#if !ORACLE 
        internal static void ValidateKeyValuePair(string keyword, string value) {
            if ((null == keyword) || !ConnectionStringValidKeyRegex.IsMatch(keyword)) { 
                throw ADP.InvalidKeyname(keyword);
            }
            if ((null != value) && !ConnectionStringValidValueRegex.IsMatch(value)) {
                throw ADP.InvalidValue(keyword); 
            }
        } 
#endif 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK