} // ParseConnectionString /* ** Name: ToConnectionString ** ** Description: ** Build the connection string fron a NameValueCollection. ** ** Input: ** NameValueCollection (a collection of key/values pairs). ** ** Output: ** Connection string (stripped of passwords) ** ** Returns: ** NameValueCollection (a collection of key/values pairs). ** ** History: ** 18-Apr-03 (thoda04) ** Created. */ /// <summary> /// Return the connection string configuration as a connection string. /// </summary> /// <param name="nv"></param> /// <returns></returns> static public string ToConnectionString( ConnectStringConfig nv) { if (nv == null || nv.Count == 0) { return(String.Empty); } System.Text.StringBuilder sb = new System.Text.StringBuilder(100); string [] specialsKeys = { DrvConst.DRV_PROP_HOST, // Host DrvConst.DRV_PROP_PORT, // Port DrvConst.DRV_PROP_DB, // Database DrvConst.DRV_PROP_USR, // User ID DrvConst.DRV_PROP_PWD // Password }; foreach (string strKey in specialsKeys) // emit special keys { // put the special keywords first ToConnectionStringNameValue(sb, nv, strKey, false); } // end foreach foreach (string strKey in nv) // emit the rest of the keys { // skip over the special keywords already put first or ignored if (Array.IndexOf(specialsKeys, strKey) != -1) { continue; } ToConnectionStringNameValue(sb, nv, strKey, false); } // end foreach return(sb.ToString()); } // ToConnectionString
} // ToNormalizedConnectionString /* ** Name: ToConnectionStringNameValue ** ** Description: ** Build the connection string fron a NameValueCollection. ** ** Input: ** NameValueCollection (a collection of key/values pairs). ** ** Output: ** Connection string (stripped of passwords) ** ** Returns: ** NameValueCollection (a collection of key/values pairs). ** ** History: ** 18-Apr-03 (thoda04) ** Created. */ static private void ToConnectionStringNameValue( System.Text.StringBuilder sb, ConnectStringConfig nv, string strKey, bool normalize) { string strValue = nv.Get(strKey); // value string strKeyOriginal = nv.GetKey(strKey); // user-specified key synonym if (strValue == null || strValue.Length == 0) { return; } if (sb.Length != 0) // if 2nd or subsequent item, insert ';' { sb.Append(';'); } if (normalize) // set key if normalize to standard keywords { strKeyOriginal = (String)NormalizedUserKeyword[strKey]; } sb.Append(strKeyOriginal); sb.Append('='); sb.Append(strValue); }
/// <summary> /// Parse the connection string keyword/values pairs /// into a configuration set. /// </summary> /// <param name="connStringParm"></param> /// <param name="sanitizedString"></param> /// <param name="keepPWDKeyword"></param> /// <returns></returns> public static ConnectStringConfig ParseConnectionString( string connStringParm, out string sanitizedString, bool keepPWDKeyword) { ConnectStringConfig nv = new ConnectStringConfig(10); sanitizedString = ""; if (connStringParm == null || connStringParm.Length == 0) return nv; bool insideQuoteString = false; bool insideParenString = false; bool scanningKey = true; // T if scanning key, F if value bool skippingWhitespace= true; // drop whitespace before tokens char priorChar = Char.MinValue; char quoteChar = Char.MinValue; // single or double quote or '\0' char c; int trailingSpaceCount = 0; // number of trailing spaces in token System.Text.StringBuilder sbKey = new System.Text.StringBuilder(100); System.Text.StringBuilder sbVal = new System.Text.StringBuilder(100); System.Text.StringBuilder sbToken = sbKey; string strKey = ""; string strVal = ""; System.Text.StringBuilder sbSanitized = new System.Text.StringBuilder(100); // string to contain connection string without password int sanitizedCount = 0; // last known good string without a pwd int lastSanitizedEqualSign = 0; // position of "=" in sanitized string string connString = String.Concat(connStringParm, ";"); // guarantee a ";" at the end of the string // to force a flush of values to NameValueCollection foreach(char cCurrent in connString) { c = cCurrent; // make a working and writeable copy of char sbSanitized.Append(c); // build up sanitized string if (Char.IsWhiteSpace(c)) { c = ' '; // normalize whitespace to a blank if (skippingWhitespace) // drop whitespace before tokens continue; } else skippingWhitespace = false; // start or continue scan of token if (insideQuoteString) { // We are inside a quoted string. If prior char // was a quote char then that prior char was either // the terminating quote or the first quote for a // quote-quote sequence. Look at the current char // to resolve the context. if (priorChar == quoteChar) // if prior char was a quote char { // and current char is a quote char if (c == quoteChar) // then doubled quotes, append one quote { sbToken.Append(c); // append to sbKey or sbVal priorChar = Char.MinValue; // clear prior quote context continue; // get next character } else // we had a closing quote in the prior char { insideQuoteString = false; // we out of quote string // fall through to normal token processing for current char } } else // ordinary char inside string or possible ending quote { priorChar = c; // remember this char as prior char if (c == quoteChar) // if ending quote (could be dbl quote) continue; // drop ending quote from string // add ordinary char to key/value sbToken.Append(c); // append to sbKey or sbVal continue; // get next char } } if (c == '\"' || c == '\'') { if (scanningKey) throw new ArgumentException( GcfErr.ERR_GC4203_CONNECTION_STRING_BAD_QUOTE.Msg); //"Invalid connection string. Only values, not keywords, "+ //"may delimited by single or double quotes." insideQuoteString = true; // we're inside the string quoteChar = c; priorChar = Char.MinValue; trailingSpaceCount = 0; continue; // drop starting from string } if (insideParenString) { // We are inside a parenthesised list string. sbToken.Append(c); // append to sbKey or sbVal if (c == ')') // if closing paren insideParenString = false; continue; // get next char } if (c == '(') insideParenString = true; if (c == '=') { // Remember the last position of the "=" in sanitized string. // We'll use it to make "PWD=*" in the sanitized string. lastSanitizedEqualSign = sbSanitized.Length; if (scanningKey) // stop scanning the key and { // start scanning the value scanningKey = false; sbToken = sbVal; } else // "Key = Value =" is a bad format throw new ArgumentException( GcfErr.ERR_GC4204_CONNECTION_STRING_DUP_EQUAL.Msg); // "Invalid connection string has duplicate '=' character." skippingWhitespace= true; // drop whitespace before tokens trailingSpaceCount = 0; continue; } if (c == ';') { if (sbKey.Length != 0 && scanningKey) // if key is missing its "=value". throw exception throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, sbKey, "<null>")); // "Connection string keyword '{0}' has invalid value: '<null>'" skippingWhitespace= true; // reset for new token scanningKey = true; // reset for scanning the next key sbToken = sbKey; strKey = sbKey.ToString().TrimEnd(null); strVal = sbVal.ToString(0, sbVal.Length - trailingSpaceCount); if (strKey.Length == 0) if (strVal.Length == 0) continue; else // if key is missing but value is there then error throw new ArgumentException( GcfErr.ERR_GC4205_CONNECTION_STRING_MISSING_KEY.Msg); // "Invalid connection string has " + // "missing keyword before '=' character." string strKeyOriginal = strKey; // save the user's original keyword // so we can reconstruct the original connection string if needed string strKeyUpper = ToInvariantUpper(strKey); string strValLower = ToInvariantLower(strVal); switch (strKeyUpper) // allow synonyms { case "HOST": case "SERVER": case "ADDRESS": case "ADDR": case "NETWORKADDRESS": strKey = DrvConst.DRV_PROP_HOST; break; case "PORT": strKey = DrvConst.DRV_PROP_PORT; break; case "USERID": case "UID": strKey = DrvConst.DRV_PROP_USR; break; case "PWD": case "PASSWORD": strKey = DrvConst.DRV_PROP_PWD; if (keepPWDKeyword) // keep the keyword for those who trace { // change "pwd=xxx;" to "pwd=*;" sbSanitized.Length=lastSanitizedEqualSign; sbSanitized.Append("*;"); } else // chop "pwd=xxx;" sbSanitized.Length = sanitizedCount; break; case "INITIALCATALOG": case "DB": case "DATABASE": strKey = DrvConst.DRV_PROP_DB; break; case "ROLEID": strKey = DrvConst.DRV_PROP_ROLE; break; case "ROLEPWD": case "ROLEPASSWORD": strKey = DrvConst.DRV_PROP_ROLEPWD; if (keepPWDKeyword) // keep the keyword for those who trace { // change "rolepwd=xxx;" to "rolepwd=*;" sbSanitized.Length=lastSanitizedEqualSign; sbSanitized.Append("*;"); } else // chop "rolepwd=xxx;" sbSanitized.Length = sanitizedCount; break; case "DBMS_USER": case "DBMSUSER": case "DBMSUSERID": strKey = DrvConst.DRV_PROP_DBUSR; break; case "DBMS_PWD": case "DBMS_PASSWORD": case "DBMSPWD": case "DBMSPASSWORD": strKey = DrvConst.DRV_PROP_DBPWD; if (keepPWDKeyword) // keep the keyword for those who trace { // change "dbmspwd=xxx;" to "dbmspwd=*;" sbSanitized.Length = lastSanitizedEqualSign; sbSanitized.Append("*;"); } else // chop "dbmspwd=xxx;" sbSanitized.Length = sanitizedCount; break; case "CHARACTER_ENCODING": case "CHAR_ENCODING": case "CHARACTERENCODING": case "CHARENCODING": strKey = DrvConst.DRV_PROP_ENCODE; System.Text.Encoding encoding = CharSet.getEncoding(strVal); if (encoding == null) // unknown .NET encodingName throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); break; case "GROUPID": strKey = DrvConst.DRV_PROP_GRP; break; case "TZ": case "TIMEZONE": strKey = DrvConst.DRV_PROP_TIMEZONE; break; case "DECIMAL": case "DECIMAL_CHAR": case "DECIMALCHAR": strKey = DrvConst.DRV_PROP_DEC_CHAR; break; case "DATE_FMT": case "DATE_FORMAT": case "DATEFORMAT": strKey = DrvConst.DRV_PROP_DATE_FRMT; break; case "MNY_FMT": case "MONEY_FORMAT": case "MONEYFORMAT": strKey = DrvConst.DRV_PROP_MNY_FRMT; break; case "MNY_PREC": case "MONEY_PRECISION": case "MONEYPRECISION": strKey = DrvConst.DRV_PROP_MNY_PREC; break; case "BLANKDATE": strKey = DrvConst.DRV_PROP_BLANKDATE; if (strValLower == "null") break; throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); case "TRACE": strKey = DrvConst.DRV_PROP_TRACE; break; case "TRACELEVEL": strKey = DrvConst.DRV_PROP_TRACELVL; goto case " Common check for good number"; case "CONNECTTIMEOUT": case "CONNECTIONTIMEOUT": strKey = DrvConst.DRV_PROP_TIMEOUT; goto case " Common check for good number"; case "MINPOOLSIZE": strKey = DrvConst.DRV_PROP_MINPOOLSIZE; goto case " Common check for good number"; case "MAXPOOLSIZE": strKey = DrvConst.DRV_PROP_MAXPOOLSIZE; goto case " Common check for good number"; case " Common check for good number": bool isGoodNumber = strVal.Length > 0; // should be true foreach(char numc in strVal) isGoodNumber &= Char.IsDigit(numc); // should stay true if (isGoodNumber) { try {Int32.Parse(strVal);} // test convertion catch (OverflowException) {isGoodNumber = false;} } if (!isGoodNumber) throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); //"Connection string keyword '{0}' has invalid value: '{1}'" break; case "VNODE_USAGE": case "VNODEUSAGE": strKey = DrvConst.DRV_PROP_VNODE; if (strValLower == "connect" || strValLower == "login") break; throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); case "CURSOR_MODE": case "CURSORMODE": strKey = DrvConst.DRV_PROP_CRSR; if (strValLower == "dbms" || strValLower == "readonly" || strValLower == "update") break; throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); case "ENLIST": strKey = DrvConst.DRV_PROP_ENLISTDTC; goto case " Common Boolean Test Code"; case "POOLING": strKey = DrvConst.DRV_PROP_CLIENTPOOL; goto case " Common Boolean Test Code"; case "PERSISTSECURITYINFO": strKey = DrvConst.DRV_PROP_PERSISTSEC; goto case " Common Boolean Test Code"; case "SENDINGRESDATES": case "SEND_INGRES_DATES": strKey = DrvConst.DRV_PROP_SENDINGRESDATES; goto case " Common Boolean Test Code"; case " Common Boolean Test Code": if (strValLower == "true" || strValLower == "yes") strVal = "true"; else if (strValLower == "false" || strValLower == "no") strVal = "false"; else throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); // "Connection string keyword '{0}' has invalid value: '{1}'" break; default: throw new ArgumentException( String.Format( GcfErr.ERR_GC4201_CONNECTION_STRING_BAD_KEY.Msg, strKey)); // Unknown connection string keyword: '{0}' } nv.Set(strKey, strVal); nv.Add(strKey, strKeyOriginal); sbKey.Length = 0; sbVal.Length = 0; trailingSpaceCount = 0; sanitizedCount = sbSanitized.Length; continue; } if (Char.IsWhiteSpace(c)) // track trailing spaces (outside of quotes) trailingSpaceCount++; else trailingSpaceCount = 0; if (scanningKey && Char.IsWhiteSpace(c)) continue; // blank chars inside a key are ignored sbToken.Append(c); // append to sbKey or sbVal } // end foreach(char cCurrent in connString) if (insideQuoteString) // if unmatched quote. throw exception throw new ArgumentException( GcfErr.ERR_GC4206_CONNECTION_STRING_MISSING_QUOTE.Msg); // "Invalid connection string has unmatched quote character." if (insideParenString) // if unmatched parentheses. throw exception throw new ArgumentException( GcfErr.ERR_GC4207_CONNECTION_STRING_MISSING_PAREN.Msg); // "Invalid connection string has unmatched paren character." if (sbSanitized.Length > 0) sbSanitized.Length--; // strip the extra semicolon we added sanitizedString = sbSanitized.ToString(); // return the sanitzied string return nv; // return the NameValueCollection }
/// <summary> /// Construct a new connection string configuration, given an old one. /// </summary> /// <param name="list"></param> public ConnectStringConfig(ConnectStringConfig list) : base(list) { }
/// <summary> /// Release allocated resources of the Command and base Component. /// </summary> /// <param name="disposing"> /// true if object is being explicitly disposed of, not finalized. /// false if method is called by runtime from inside the finalizer. /// </param> protected override void Dispose(bool disposing) { /*if disposing == true Object is being explicitly disposed of, not finalized if disposing == false then method called by runtime from inside the finalizer and we should not reference other objects. */ lock(this) { try { if (disposing) { Close(); _connectionString = null; config = null; } } finally { base.Dispose(disposing); // let component base do its cleanup } } }
/// <summary> /// Start the recovery scan for XIDs and position cursor at start of list. /// </summary> /// <param name="rm">Resource manager to start scan for.</param> /// <returns>Count of XIDs in whole list or XAER* error code.</returns> private int xa_recover_startrscan(RM rm) { const string MASTER_DB = "iidbdb"; int rc = XA_OK; rm.Xids = new AdvanXID[0]; // init to empty in case bad things happen AdvanXID[] xids = rm.Xids; AdvanConnect conn; ConnectStringConfig config = // make a copy new ConnectStringConfig(rm.Config); // XIDs need to come from iidbdb database config.Set(DrvConst.DRV_PROP_DB, MASTER_DB); try { conn = new AdvanConnect( null, rm.Host, config, trace, (AdvanXID)null); } catch (Exception ex) { trace.write("xa_recover: Exception thrown on Connection open: "+ ex.ToString()); return XAER_RMFAIL; // could not connect } try { xids = conn.getPreparedTransactionIDs(rm.DatabaseName); } catch (Exception ex) { trace.write("xa_recover: Exception thrown on GetXIDs: "+ ex.ToString()); rc = XAER_RMERR; // could not connect } finally { try { conn.close(); } catch(Exception /* ignore */) {} } if (rc != XA_OK) return rc; rm.Cursor =0; // reset cursor to XID list back to start if (xids != null) // safety check rm.Xids = xids; // new list of XIDs return rm.Xids.Length; }
/* ** Name: Enlist ** ** Description: ** Enlist in the Microsoft Distributed Transaction Coordinator (MSDTC). ** Called by Connection.EnlistDistributedTransaction(ITransaction). ** ** History: ** 01-Oct-03 (thoda04) ** Created. */ /// <summary> /// Enlist in the Microsoft Distributed Transaction Coordinator (MSDTC). /// </summary> /// <param name="advanConnection">Internal connection.</param> /// <param name="tx">ITransaction interface of object.</param> /// <param name="nv">Connection string parameter values list.</param> internal void Enlist( AdvanConnect advanConnection, ITransaction tx, ConnectStringConfig nv) { this.advanConnect = advanConnection; this.Transaction = tx; trace.write(3, title + ": Enlist()"); if (debugging) Console.WriteLine(title + ": Enlist() begins..."); /* Call DtcGetTransactionManager in MS DTC proxy to establish a connection to the Transaction Manager. From the TM, get the XATM's Single Pipe Helper interface that will help establish an enlistment in MSDTC using the XA protocol (XaSwitch and XIDs). */ XaHelperSinglePipe = GetDtcToXaHelperSinglePipe(); /* Obtain the Resource Manager (RM) cookie. The XARMCreate method is invoked once per connection. The information provided makes it possible for the transaction manager to connect to the database to perform recovery. The transaction manager durably records this information in it's log file. If recovery is necessary, the transaction manager reads the log file, reconnects to the database, and initiates XA recovery. Calling XARMCreate results in a message from the DTC proxy to the XA Transaction Manager (TM). When the XA TM receives a message that contains the DSN and the name of the client DLL, TM will: 1) LoadLibrary the client dll (Ingres.Support.dll which will drag in the referenced Ingres.ProviderInternals from the GAC). 2) GetProcAddress the GetXaSwitch function in the dll. 3) Call the GetXaSwitch function to obtain the XA_Switch. 4) Call the xa_open function to open an XA connection with the resource manager (Ingres). When the our xa_open function is called, the DTC TM passes in the DSN parm as the OPEN_STRING. It then closes the connection by calling xa_close. (It's just testing the connection information so that it won't be surprised when it's in the middle of recovery later.) 5) Generate a RM GUID for the connection. 6) Write a record to the DTCXATM.LOG file indicating that a new resource manager is being established. The log record contains the DSN parm, the name of our RM (Ingres.Support.dll), and the RM GUID. This information will be used to reconnect to Ingres should recovery be necessary. XARMCreate method also causes the MS DTC proxy to create a resource manager object and returns an opaque pointer to that object as the RMCookie. This RMCookie represents the connection to the TM. */ nv = new ConnectStringConfig(nv); // create a working copy // Connection attempts with MSG_P_DTMC will raise error: // GC000B_RMT_LOGIN_FAIL Login failure: invalid username/password // if you try to send login information nv.Remove(DrvConst.DRV_PROP_USR); // remove "user="******"password="******"group=" nv.Remove(DrvConst.DRV_PROP_ROLE); // remove "role=" string xa_open_string = ConnectStringConfig.ToConnectionString(nv); int trace_level = trace.getTraceLevel("XA"); if (trace_level > 0) { xa_open_string += // tell MSDTC process to trace XASwitch ";Trace=XA;TraceLevel=" + trace_level.ToString(); } // Locate the Ingres.Support.dll that holds our XASwitch // support. The dll should be in the GAC so use a type from // the Ingres.Support assembly, qualified by the same // Version and PublicKeyToken that the currently executing // Ingres.Support assembly is using. System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); string fullname = assembly.FullName; string version; int index = fullname.IndexOf(','); // locate ", Verison=..." if (index != -1) version = fullname.Substring(index); else // should not happen unless in a debugging environment version = ", Version=2.0.0.0, Culture=neutral" + ", PublicKeyToken=1234567890123456"; Type type = Type.GetType( "Ingres.Support.XAProvider" + ", Ingres.Support" + version); // BTW, type will be null if Ingres.Support is not properly // in the GAC or has a different version number from // Ingres.Client. A NullReferenceException would follow. string dll = type.Assembly.Location; XaHelperSinglePipe_XARMCreate( xa_open_string, dll, out this.RMCookie); /* Obtain an XID from an ITransaction interface pointer. The ITransaction pointer is offered by a transaction object. The transaction object contains a DTC transaction that is identified by a transaction identifier (TRID) which is a globally unique identifier (GUID). Given a TRID, one can always create an XID. The MS DTC proxy generates an XID and returns it. Into the XID's formatID, MS puts 0x00445443 ("DTC"). Into the XID's gtrid (length=0x10), MS puts a GUID identifying the global transaction identifier. (Same as Transaction.Current.TransactionInformation.DistributedIdentifier.) Into the XID's bqual (length=0x30), MS puts a second GUID identifying the TM that is coordinating the transaction and also a third GUID identifying the database connection. If two components in the same transaction have their own connections, then they will be loosely coupled XA threads of control (different bquals). MS goes beyond the XA spec and expects that the two loosely coupled threads will not deadlock on resource locks. */ XAXIDStruct xaXIDstruct = new XAXIDStruct(-1,0,0,new byte[128]); XaHelperSinglePipe_ConvertTridToXID( Transaction, this.RMCookie, ref xaXIDstruct); advanXID = new AdvanXID(xaXIDstruct); /* Tell the DTC proxy to enlist on behalf of the XA resource manager. EnlistWithRM is called for every transaction that the connection is requested to be enlisted in. The provider is responsible for implementing the ITransactionResourceAsync interface. This interface includes the PrepareRequest, CommitRequest, AbortRequest, and TMDown callbacks. The transaction manager will invoke these callback methods to deliver phase one and phase two notifications to the provider. The MS DTC proxy informs the transaction manager that the provider wishes to enlist in the transaction. The transaction manager creates an internal enlistment object to record the fact that the provider is participating in the transaction. Upon return from EnlistWithRM, the MS DTC proxy will have created an enlistment object and returns the pITransactionEnlistmentAsync interface pointer of the enlistment object back to the provider. */ try { StartMSDTCRequest(MSDTCRequest.ENLIST); // start worker thread if (EnlistmentException != null) throw EnlistmentException; // wait until EnlistWithRM is completed under the worker thread advanConnect.msg.LockConnection(); advanConnect.msg.UnlockConnection(); advanConnect.startTransaction(advanXID); TxBranchState = TXBRANCHSTATE.Active; } catch { // release our bad connection to MS DTC and // shutdown our worker thread to MS DTC. XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie); StartMSDTCRequest(MSDTCRequest.DELIST); throw; } // At this point we have a good MSDTC enlistment! // The advanConnect internal connection object is now being used by // two threads: the application thread and the MSDTC proxy thread. // The advanConnect usage count will block release of the internal // connection advanConnect object back into the connection pool // until each is finished and calls // advanConnect.CloseOrPutBackIntoConnectionPool() method. // See IngresConnection.Open() method for application's claim stake. advanConnect.ReferenceCountIncrement(); // MSDTC proxy thread stakes it claim trace.write(3, title + ": Enlist() complete"); if (debugging) Console.WriteLine(title + ": Enlist() complete"); }
private void ConnectionEditorForm_Load(object sender, System.EventArgs e) { System.Reflection.Assembly assembly = GetType().Module.Assembly; Bitmap bmp = new Bitmap(assembly.GetManifestResourceStream(bitmapName)); this.pictureBox1.Image = bmp; this.pictureBox1.BorderStyle = BorderStyle.FixedSingle; this.pictureBox1.Size = new Size(bmp.Width, bmp.Height); // default to caller's ConnectionString name/value pairs NameValueCollection nv = this.nv; dropDownValues = new NamedArrayList[] { connectionStringLastValue = new NamedArrayList("ConnectionStringLast"), serverDropDownValues = new NamedArrayList("Server"), portDropDownValues = new NamedArrayList("Port"), databaseDropDownValues= new NamedArrayList("Database"), userDropDownValues = new NamedArrayList("User"), groupDropDownValues = new NamedArrayList("Group"), roleDropDownValues = new NamedArrayList("Role"), dbmsUserDropDownValues= new NamedArrayList("DbmsUser") }; LoadValuesFromApplicationDataFolder( // load from ConnectionEditor.xml dropDownValues, ApplicationDataFileName); if (connectionStringLastValue.Count > 0) connectionStringLast = (string)connectionStringLastValue[0]; if (nv.Count == 0 && // if caller has no connection string and connectionStringLast != null && connectionStringLast.Length > 0) // we had a last string { // use the last connection string the editor built try { nv = ConnectStringConfig.ParseConnectionString( connectionStringLast); } catch {} } this.serverBox.Text = GetValueOfKeyword(nv, DrvConst.DRV_PROP_HOST); this.serverBox.Items.AddRange(serverDropDownValues.ToArray()); if (serverDropDownValues.IndexOf("(local)") == -1) this.serverBox.Items.Add("(local)"); this.portBox.Text = GetValueOfKeyword(nv, DrvConst.DRV_PROP_PORT, "II7"); this.portBox.Items.AddRange(portDropDownValues.ToArray()); this.databaseBox.Text = GetValueOfKeyword(nv, DrvConst.DRV_PROP_DB); this.databaseBox.Items.AddRange(databaseDropDownValues.ToArray()); this.userBox.Text = GetValueOfKeyword(nv, DrvConst.DRV_PROP_USR); this.userBox.Items.AddRange(userDropDownValues.ToArray()); this.passwordBox.Text = GetValueOfKeyword(nv, DrvConst.DRV_PROP_PWD); this.checkPersistSecurityInfo.Checked = GetValueOfKeyword(nv, DrvConst.DRV_PROP_PERSISTSEC, false); this.timeoutUpDown.Minimum = Decimal.MinValue; this.timeoutUpDown.Maximum = Decimal.MaxValue; this.timeoutUpDown.Value = GetValueOfKeyword(nv, DrvConst.DRV_PROP_TIMEOUT, 15); this.checkConnectionPooling.Checked = GetValueOfKeyword(nv, DrvConst.DRV_PROP_CLIENTPOOL, true); this.roleBox.Text = GetValueOfKeyword(nv, DrvConst.DRV_PROP_ROLE); this.roleBox.Items.AddRange(roleDropDownValues.ToArray()); this.rolePwdBox.Text = GetValueOfKeyword(nv, DrvConst.DRV_PROP_ROLEPWD); this.dbmsUserBox.Text= GetValueOfKeyword(nv, DrvConst.DRV_PROP_DBUSR); this.dbmsUserBox.Items.AddRange(dbmsUserDropDownValues.ToArray()); this.dbmsPwdBox.Text = GetValueOfKeyword(nv, DrvConst.DRV_PROP_DBPWD); this.groupBox.Text = GetValueOfKeyword(nv, DrvConst.DRV_PROP_GRP); this.groupBox.Items.AddRange(groupDropDownValues.ToArray()); }
private void buttonOK_Click(object sender, System.EventArgs e) { // Lay down the new values into the NamedValueCollection. // Do not clear the nv since there may be some options // that are not in the editor dialog. We do not want to // nv.Clear() since these options would be lost. SetConnectionStringValuesFromControls(this.nv); UpdateDropDownList(serverDropDownValues, this.serverBox); UpdateDropDownList(portDropDownValues, this.portBox); UpdateDropDownList(databaseDropDownValues,this.databaseBox); UpdateDropDownList(userDropDownValues, this.userBox); UpdateDropDownList(roleDropDownValues, this.roleBox); UpdateDropDownList(dbmsUserDropDownValues,this.dbmsUserBox); UpdateDropDownList(groupDropDownValues, this.groupBox); //string connstring = IngresConnection.ToConnectionString(nv); // make a sanitized copy of the connection string keyword/values // that does not include the "Password" values ConnectStringConfig cleannv = this.nv; // debugging cleannv = new ConnectStringConfig(this.nv); cleannv.Remove(DrvConst.DRV_PROP_PWD); cleannv.Remove(DrvConst.DRV_PROP_ROLEPWD); cleannv.Remove(DrvConst.DRV_PROP_DBPWD); string connectionStringLast = // sanitized connection string ConnectStringConfig.ToConnectionString(cleannv); connectionStringLastValue.Clear(); connectionStringLastValue.Add(connectionStringLast); // save dropdown values to ConnectionEditor.xml SaveValuesToApplicationDataFolder( dropDownValues, ApplicationDataFileName); //exit and leave the values in this.nv (form caller's nv) }
public ConnectionEditorForm(ConnectStringConfig nvParm) { nv = nvParm; // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // }
internal ConnectionEditor( IngresDataAdapter adapter, System.ComponentModel.Design.IDesignerHost host) { if (adapter != null && adapter.SelectCommand != null && adapter.SelectCommand.Connection != null) connection = adapter.SelectCommand.Connection; else connection = new IngresConnection(); // format the connection string in key/value pairs nv = ConnectStringConfig.ParseConnectionString( connection.ConnectionString); // the editor will update the key/value pairs Form dlgConnection = new ConnectionEditorForm(nv); DialogResult result = dlgConnection.ShowDialog(); if (result == DialogResult.Cancel) // if Cancel button, return { //MessageBox.Show("Connection DialogResult.Cancel", "ConnectionEditor"); return; } // else (result == DialogResult.OK) // if Next button, go on // rebuild the updated key/value pairs back into a connection string connection.ConnectionString = ConnectStringConfig.ToConnectionString(nv); // connect the Connection object to the four Adapter commands if (adapter != null) { if (adapter.SelectCommand != null) adapter.SelectCommand.Connection = connection; if (adapter.InsertCommand != null) adapter.InsertCommand.Connection = connection; if (adapter.UpdateCommand != null) adapter.UpdateCommand.Connection = connection; if (adapter.DeleteCommand != null) adapter.DeleteCommand.Connection = connection; } }
internal ConnectionEditor(IngresConnection connectionParm) { connection = connectionParm; // format the connection string in key/value pairs nv = ConnectStringConfig.ParseConnectionString( connection.ConnectionString); // the editor will update the key/value pairs Form dlgConnection = new ConnectionEditorForm(nv); DialogResult result = dlgConnection.ShowDialog(); if (result == DialogResult.Cancel) // if Cancel button, return { //MessageBox.Show("Connection DialogResult.Cancel", "ConnectionEditor"); return; } // else (result == DialogResult.OK) // if Next button, go on // rebuild the updated key/value pairs back into a connection string connection.ConnectionString = ConnectStringConfig.ToConnectionString(nv); }
ParseConnectionString( string connStringParm, out string sanitizedString, bool keepPWDKeyword) { ConnectStringConfig nv = new ConnectStringConfig(10); sanitizedString = ""; if (connStringParm == null || connStringParm.Length == 0) { return(nv); } bool insideQuoteString = false; bool insideParenString = false; bool scanningKey = true; // T if scanning key, F if value bool skippingWhitespace = true; // drop whitespace before tokens char priorChar = Char.MinValue; char quoteChar = Char.MinValue; // single or double quote or '\0' char c; int trailingSpaceCount = 0; // number of trailing spaces in token System.Text.StringBuilder sbKey = new System.Text.StringBuilder(100); System.Text.StringBuilder sbVal = new System.Text.StringBuilder(100); System.Text.StringBuilder sbToken = sbKey; string strKey = ""; string strVal = ""; System.Text.StringBuilder sbSanitized = new System.Text.StringBuilder(100); // string to contain connection string without password int sanitizedCount = 0; // last known good string without a pwd int lastSanitizedEqualSign = 0; // position of "=" in sanitized string string connString = String.Concat(connStringParm, ";"); // guarantee a ";" at the end of the string // to force a flush of values to NameValueCollection foreach (char cCurrent in connString) { c = cCurrent; // make a working and writeable copy of char sbSanitized.Append(c); // build up sanitized string if (Char.IsWhiteSpace(c)) { c = ' '; // normalize whitespace to a blank if (skippingWhitespace) // drop whitespace before tokens { continue; } } else { skippingWhitespace = false; // start or continue scan of token } if (insideQuoteString) { // We are inside a quoted string. If prior char // was a quote char then that prior char was either // the terminating quote or the first quote for a // quote-quote sequence. Look at the current char // to resolve the context. if (priorChar == quoteChar) // if prior char was a quote char { // and current char is a quote char if (c == quoteChar) // then doubled quotes, append one quote { sbToken.Append(c); // append to sbKey or sbVal priorChar = Char.MinValue; // clear prior quote context continue; // get next character } else // we had a closing quote in the prior char { insideQuoteString = false; // we out of quote string // fall through to normal token processing for current char } } else // ordinary char inside string or possible ending quote { priorChar = c; // remember this char as prior char if (c == quoteChar) // if ending quote (could be dbl quote) { continue; // drop ending quote from string } // add ordinary char to key/value sbToken.Append(c); // append to sbKey or sbVal continue; // get next char } } if (c == '\"' || c == '\'') { if (scanningKey) { throw new ArgumentException( GcfErr.ERR_GC4203_CONNECTION_STRING_BAD_QUOTE.Msg); } //"Invalid connection string. Only values, not keywords, "+ //"may delimited by single or double quotes." insideQuoteString = true; // we're inside the string quoteChar = c; priorChar = Char.MinValue; trailingSpaceCount = 0; continue; // drop starting from string } if (insideParenString) { // We are inside a parenthesised list string. sbToken.Append(c); // append to sbKey or sbVal if (c == ')') // if closing paren { insideParenString = false; } continue; // get next char } if (c == '(') { insideParenString = true; } if (c == '=') { // Remember the last position of the "=" in sanitized string. // We'll use it to make "PWD=*" in the sanitized string. lastSanitizedEqualSign = sbSanitized.Length; if (scanningKey) // stop scanning the key and { // start scanning the value scanningKey = false; sbToken = sbVal; } else // "Key = Value =" is a bad format { throw new ArgumentException( GcfErr.ERR_GC4204_CONNECTION_STRING_DUP_EQUAL.Msg); } // "Invalid connection string has duplicate '=' character." skippingWhitespace = true; // drop whitespace before tokens trailingSpaceCount = 0; continue; } if (c == ';') { if (sbKey.Length != 0 && scanningKey) { // if key is missing its "=value". throw exception throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, sbKey, "<null>")); } // "Connection string keyword '{0}' has invalid value: '<null>'" skippingWhitespace = true; // reset for new token scanningKey = true; // reset for scanning the next key sbToken = sbKey; strKey = sbKey.ToString().TrimEnd(null); strVal = sbVal.ToString(0, sbVal.Length - trailingSpaceCount); if (strKey.Length == 0) { if (strVal.Length == 0) { continue; } else // if key is missing but value is there then error { throw new ArgumentException( GcfErr.ERR_GC4205_CONNECTION_STRING_MISSING_KEY.Msg); } } // "Invalid connection string has " + // "missing keyword before '=' character." string strKeyOriginal = strKey; // save the user's original keyword // so we can reconstruct the original connection string if needed string strKeyUpper = ToInvariantUpper(strKey); string strValLower = ToInvariantLower(strVal); switch (strKeyUpper) // allow synonyms { case "HOST": case "SERVER": case "ADDRESS": case "ADDR": case "NETWORKADDRESS": strKey = DrvConst.DRV_PROP_HOST; break; case "PORT": strKey = DrvConst.DRV_PROP_PORT; break; case "USERID": case "UID": strKey = DrvConst.DRV_PROP_USR; break; case "PWD": case "PASSWORD": strKey = DrvConst.DRV_PROP_PWD; if (keepPWDKeyword) // keep the keyword for those who trace { // change "pwd=xxx;" to "pwd=*;" sbSanitized.Length = lastSanitizedEqualSign; sbSanitized.Append("*;"); } else { // chop "pwd=xxx;" sbSanitized.Length = sanitizedCount; } break; case "INITIALCATALOG": case "DB": case "DATABASE": strKey = DrvConst.DRV_PROP_DB; break; case "ROLEID": strKey = DrvConst.DRV_PROP_ROLE; break; case "ROLEPWD": case "ROLEPASSWORD": strKey = DrvConst.DRV_PROP_ROLEPWD; if (keepPWDKeyword) // keep the keyword for those who trace { // change "rolepwd=xxx;" to "rolepwd=*;" sbSanitized.Length = lastSanitizedEqualSign; sbSanitized.Append("*;"); } else { // chop "rolepwd=xxx;" sbSanitized.Length = sanitizedCount; } break; case "DBMS_USER": case "DBMSUSER": case "DBMSUSERID": strKey = DrvConst.DRV_PROP_DBUSR; break; case "DBMS_PWD": case "DBMS_PASSWORD": case "DBMSPWD": case "DBMSPASSWORD": strKey = DrvConst.DRV_PROP_DBPWD; if (keepPWDKeyword) // keep the keyword for those who trace { // change "dbmspwd=xxx;" to "dbmspwd=*;" sbSanitized.Length = lastSanitizedEqualSign; sbSanitized.Append("*;"); } else { // chop "dbmspwd=xxx;" sbSanitized.Length = sanitizedCount; } break; case "CHARACTER_ENCODING": case "CHAR_ENCODING": case "CHARACTERENCODING": case "CHARENCODING": strKey = DrvConst.DRV_PROP_ENCODE; System.Text.Encoding encoding = CharSet.getEncoding(strVal); if (encoding == null) // unknown .NET encodingName { throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); } break; case "GROUPID": strKey = DrvConst.DRV_PROP_GRP; break; case "TZ": case "TIMEZONE": strKey = DrvConst.DRV_PROP_TIMEZONE; break; case "DECIMAL": case "DECIMAL_CHAR": case "DECIMALCHAR": strKey = DrvConst.DRV_PROP_DEC_CHAR; break; case "DATE_FMT": case "DATE_FORMAT": case "DATEFORMAT": strKey = DrvConst.DRV_PROP_DATE_FRMT; break; case "MNY_FMT": case "MONEY_FORMAT": case "MONEYFORMAT": strKey = DrvConst.DRV_PROP_MNY_FRMT; break; case "MNY_PREC": case "MONEY_PRECISION": case "MONEYPRECISION": strKey = DrvConst.DRV_PROP_MNY_PREC; break; case "BLANKDATE": strKey = DrvConst.DRV_PROP_BLANKDATE; if (strValLower == "null") { break; } throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); case "TRACE": strKey = DrvConst.DRV_PROP_TRACE; break; case "TRACELEVEL": strKey = DrvConst.DRV_PROP_TRACELVL; goto case " Common check for good number"; case "CONNECTTIMEOUT": case "CONNECTIONTIMEOUT": strKey = DrvConst.DRV_PROP_TIMEOUT; goto case " Common check for good number"; case "MINPOOLSIZE": strKey = DrvConst.DRV_PROP_MINPOOLSIZE; goto case " Common check for good number"; case "MAXPOOLSIZE": strKey = DrvConst.DRV_PROP_MAXPOOLSIZE; goto case " Common check for good number"; case " Common check for good number": bool isGoodNumber = strVal.Length > 0; // should be true foreach (char numc in strVal) { isGoodNumber &= Char.IsDigit(numc); // should stay true } if (isGoodNumber) { try { Int32.Parse(strVal); } // test convertion catch (OverflowException) { isGoodNumber = false; } } if (!isGoodNumber) { throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); } //"Connection string keyword '{0}' has invalid value: '{1}'" break; case "VNODE_USAGE": case "VNODEUSAGE": strKey = DrvConst.DRV_PROP_VNODE; if (strValLower == "connect" || strValLower == "login") { break; } throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); case "CURSOR_MODE": case "CURSORMODE": strKey = DrvConst.DRV_PROP_CRSR; if (strValLower == "dbms" || strValLower == "readonly" || strValLower == "update") { break; } throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); case "ENLIST": strKey = DrvConst.DRV_PROP_ENLISTDTC; goto case " Common Boolean Test Code"; case "POOLING": strKey = DrvConst.DRV_PROP_CLIENTPOOL; goto case " Common Boolean Test Code"; case "PERSISTSECURITYINFO": strKey = DrvConst.DRV_PROP_PERSISTSEC; goto case " Common Boolean Test Code"; case "SENDINGRESDATES": case "SEND_INGRES_DATES": strKey = DrvConst.DRV_PROP_SENDINGRESDATES; goto case " Common Boolean Test Code"; case " Common Boolean Test Code": if (strValLower == "true" || strValLower == "yes") { strVal = "true"; } else if (strValLower == "false" || strValLower == "no") { strVal = "false"; } else { throw new ArgumentException( String.Format( GcfErr.ERR_GC4202_CONNECTION_STRING_BAD_VALUE.Msg, strKey, strVal)); } // "Connection string keyword '{0}' has invalid value: '{1}'" break; default: throw new ArgumentException( String.Format( GcfErr.ERR_GC4201_CONNECTION_STRING_BAD_KEY.Msg, strKey)); // Unknown connection string keyword: '{0}' } nv.Set(strKey, strVal); nv.Add(strKey, strKeyOriginal); sbKey.Length = 0; sbVal.Length = 0; trailingSpaceCount = 0; sanitizedCount = sbSanitized.Length; continue; } if (Char.IsWhiteSpace(c)) // track trailing spaces (outside of quotes) { trailingSpaceCount++; } else { trailingSpaceCount = 0; } if (scanningKey && Char.IsWhiteSpace(c)) { continue; // blank chars inside a key are ignored } sbToken.Append(c); // append to sbKey or sbVal } // end foreach(char cCurrent in connString) if (insideQuoteString) // if unmatched quote. throw exception { throw new ArgumentException( GcfErr.ERR_GC4206_CONNECTION_STRING_MISSING_QUOTE.Msg); } // "Invalid connection string has unmatched quote character." if (insideParenString) // if unmatched parentheses. throw exception { throw new ArgumentException( GcfErr.ERR_GC4207_CONNECTION_STRING_MISSING_PAREN.Msg); } // "Invalid connection string has unmatched paren character." if (sbSanitized.Length > 0) { sbSanitized.Length--; // strip the extra semicolon we added } sanitizedString = sbSanitized.ToString(); // return the sanitzied string return(nv); // return the NameValueCollection } // ParseConnectionString
/* ** Name: ToNormalizedConnectionString ** ** Description: ** Build the connection string fron a NameValueCollection with * standard ConnectionStringBuilder keywords. ** ** Input: ** NameValueCollection (a collection of key/values pairs). ** ** Returns: ** Connection string including passwords ** ** History: ** 12-Aug-05 (thoda04) ** Created. */ /// <summary> /// Return the connection string configuration as a connection string /// using ConnectionStringBuilder normalized keywords. /// </summary> /// <param name="nv"></param> /// <returns></returns> internal static string ToNormalizedConnectionString( ConnectStringConfig nv) { if (nv == null || nv.Count == 0) return String.Empty; System.Text.StringBuilder sb = new System.Text.StringBuilder(100); string[] specialsKeys = { DrvConst.DRV_PROP_HOST, // Host DrvConst.DRV_PROP_PORT, // Port DrvConst.DRV_PROP_DB, // Database DrvConst.DRV_PROP_USR, // User ID DrvConst.DRV_PROP_PWD // Password }; foreach (string strKey in specialsKeys) // emit special keys { // put the special keywords first ToConnectionStringNameValue(sb, nv, strKey, true); } // end foreach foreach (string strKey in nv) // emit the rest of the keys { // skip over the special keywords already put first or ignored if (Array.IndexOf(specialsKeys, strKey) != -1) continue; ToConnectionStringNameValue(sb, nv, strKey, true); } // end foreach return sb.ToString(); }
/* ** Name: ToConnectionStringNameValue ** ** Description: ** Build the connection string fron a NameValueCollection. ** ** Input: ** NameValueCollection (a collection of key/values pairs). ** ** Output: ** Connection string (stripped of passwords) ** ** Returns: ** NameValueCollection (a collection of key/values pairs). ** ** History: ** 18-Apr-03 (thoda04) ** Created. */ private static void ToConnectionStringNameValue( System.Text.StringBuilder sb, ConnectStringConfig nv, string strKey, bool normalize) { string strValue = nv.Get( strKey); // value string strKeyOriginal = nv.GetKey(strKey); // user-specified key synonym if (strValue == null || strValue.Length == 0) return; if (sb.Length !=0) // if 2nd or subsequent item, insert ';' sb.Append(';'); if (normalize) // set key if normalize to standard keywords strKeyOriginal = (String)NormalizedUserKeyword[strKey]; sb.Append(strKeyOriginal); sb.Append('='); sb.Append(strValue); }
private void buttonTestConnection_Click(object sender, System.EventArgs e) { // make a working copy of the connection string keyword/values ConnectStringConfig nv = new ConnectStringConfig(this.nv); // lay down the new values into the NamedValueCollection SetConnectionStringValuesFromControls(nv); try { TestConnection(ConnectStringConfig.ToConnectionString(nv)); } catch(Exception ex) { MessageBox.Show(ex.ToString(), "Connection Test Failed"); return; } MessageBox.Show("Connection successful!", "Connection Test"); }