using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace Sdaleo { /// /// Core Class to Parse / Generate a UDL String /// internal class UDL : ICloneable, IComparable { #region Internal ReadWrite Properties /// /// Credential Object can point to different databases /// internal string DataBase { get; set; } /// /// Default Connection Timeout /// internal const uint DEFAULT_CONNECTION_TIMEOUT_UDL = 15; /// /// Allow Caller to set connection timeout /// internal uint ConnectionTimeout = DEFAULT_CONNECTION_TIMEOUT_UDL; /// /// Defaulted to 'true'. When set uses the ConnectionTimeout value, when false it won't /// internal bool UseConnectionTimeout = true; // * Secured Password * private SecuredPassword _Password = new SecuredPassword(); /// /// Secured Password Object that stores the password in a secure manner in memory /// internal string Password { get { return _Password.Password; } private set { _Password.Password = value; } } /// /// /// internal string DataSource { get { if (!String.IsNullOrEmpty(ServerAddress) && !String.IsNullOrEmpty(InstanceName)) return ServerAddress + "\\" + InstanceName; else if (!String.IsNullOrEmpty(ServerAddress)) return ServerAddress; else return string.Empty; } private set { if (!String.IsNullOrEmpty(value)) { string[] values = value.Split('\\'); if (values.Length == 2) { ServerAddress = values[0]; InstanceName = values[1]; } else if (values.Length > 2) { int nIndx = value.LastIndexOf('\\'); ServerAddress = value.Substring(0, nIndx); InstanceName = value.Substring(nIndx + 1); } else { ServerAddress = value; } } } } #endregion #region Internal ReadOnly Properties #region ReadOnly String Getters /// /// /// internal string Username { get; private set; } /// /// /// internal string ServerAddress { get; private set; } /// /// /// internal string InstanceName { get; private set; } /// /// /// internal string IntegratedSecurity { get; private set; } /// /// /// internal string AttachDBFilename { get; private set; } /// /// /// internal string ServerType { get; private set; } #endregion #region ReadOnly Bool Getters /// /// /// internal bool TrustedConnection { get; private set; } /// /// /// internal bool PersistSecurityInfo { get; private set; } /// /// /// internal bool UserInstance { get; private set; } /// /// /// internal bool Encrypt { get; private set; } #endregion #endregion #region Constructors /// /// Construction (Set all UDL Settings via Connection String) /// /// Pass in a valid Connection String To correctly instantiate the UDL Object internal UDL(String ConnectionString) { Parse(ConnectionString); } #region SQL CE Constructors /// /// Construction SQL CE (Set common UDL Settings for SQL CE) /// /// /// /// internal UDL(string FileNameNPath, string Password) { this.DataSource = FileNameNPath; UseConnectionTimeout = false; if (!String.IsNullOrEmpty(Password)) { this.Password = Password; this.Encrypt = true; } } #endregion #region Advantage Constructors /// /// Construction Advantage (Set common UDL Settings for Advantage) /// /// /// /// /// internal UDL(string FileNameNPath, string UserID, string Password, string ServerType) { UseConnectionTimeout = false; this.DataSource = FileNameNPath; this.Username = UserID; this.Password = Password; this.ServerType = ServerType; } #endregion #region SQL Server Constructors /// /// Construction SQL Server (Using SQL Login Credential) /// /// Name of Database To Use /// Username to Connect With /// Password to Connect With /// ServerAddress to use as DataSource /// Name of Instance to use as DataSource internal UDL(string DataBase, string Username, string Password, string ServerAddress, string InstanceName) { this.DataBase = DataBase.Trim(); this.Username = Username.Trim(); this.Password = Password; this.ServerAddress = (String.IsNullOrEmpty(ServerAddress)) ? "." : ServerAddress.Trim().ToUpper(); this.InstanceName = InstanceName.Trim().ToUpper(); } /// /// Construction SQL Server (Set common UDL Settings for SQL Server) /// /// Name of Database To Use /// Username to Connect With /// Password to Connect With /// ServerAddress to use as DataSource /// Name of Instance to use as DataSource /// Set to True to use Windows Authentication instead of SQL Auth internal UDL(string DataBase, string Username, string Password, string ServerAddress, string InstanceName, bool TrustedConnection) { this.DataBase = DataBase.Trim(); this.Username = Username.Trim(); this.Password = Password; this.ServerAddress = (String.IsNullOrEmpty(ServerAddress)) ? "." : ServerAddress.Trim().ToUpper(); this.InstanceName = InstanceName.Trim().ToUpper(); this.TrustedConnection = TrustedConnection; this.IntegratedSecurity = TrustedConnection ? "SSPI" : ""; } /// /// Construction SQL Server (Set all UDL Settings for SQL Server) /// /// Name of Database To Use /// Username to Connect With /// Password to Connect With /// ServerAddress to use as DataSource /// Name of Instance to use as DataSource /// Set to SQL Express .mdf file to attach to (Creates a User Instance) /// Set to True to use Windows Authentication instead of SQL Auth /// Legacy Setting that Persists the Security Information internal UDL(string DataBase, string Username, string Password, string ServerAddress, string InstanceName, string AttachDBFilename, bool TrustedConnection, bool PersistSecurityInfo) { this.DataBase = DataBase.Trim(); this.Username = Username.Trim(); this.Password = Password; this.ServerAddress = (String.IsNullOrEmpty(ServerAddress)) ? "." : ServerAddress.Trim().ToUpper(); this.InstanceName = InstanceName.Trim().ToUpper(); this.AttachDBFilename = AttachDBFilename.Trim(); this.UserInstance = !String.IsNullOrEmpty(AttachDBFilename); this.TrustedConnection = TrustedConnection; this.IntegratedSecurity = TrustedConnection? "SSPI" : ""; this.PersistSecurityInfo = PersistSecurityInfo; } #endregion #endregion #region Connection String N' Parse /// /// Returns the Connection String formed from the UDL Properties /// /// /// /// Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword; /// Server=myServerAddress;Database=myDataBase;User ID=myUsername;Password=myPassword;Trusted_Connection=False; /// Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=SSPI; /// Server=myServerAddress;Database=myDataBase;Trusted_Connection=True; /// Server=myServerName\theInstanceName;Database=myDataBase;Trusted_Connection=True; /// Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=SSPI;User ID=myDomain\myUsername;Password=myPassword; /// internal string ConnectionString { get { string strUDL = String.Empty; // * Data Source Must Always be Specified * if (!String.IsNullOrEmpty(ServerAddress) && !String.IsNullOrEmpty(InstanceName)) { strUDL = String.Format(@"Data Source={0}\{1};", ServerAddress, InstanceName); } else if (!String.IsNullOrEmpty(ServerAddress)) { strUDL = String.Format(@"Data Source={0};", ServerAddress); } else throw new Exception("Invalid DataSource Parameter"); // Add Database? if (!String.IsNullOrEmpty(DataBase)) { string strAddMore = String.Format(@"Initial Catalog={0};", DataBase); strUDL += strAddMore; } // Add User Information? if (!String.IsNullOrEmpty(Username)) { string strAddMore = String.Format(@"User ID={0};", Username); strUDL += strAddMore; } // Add Password Information? if (!String.IsNullOrEmpty(Password)) { string strAddMore = String.Format(@"Password={0};", Password); strUDL += strAddMore; } // Should we use User Instance? if (UserInstance && !String.IsNullOrEmpty(AttachDBFilename)) { string strAddMore = String.Format(@"User Instance={0};AttachDBFilename={1};", UserInstance.ToString(), AttachDBFilename); strUDL += strAddMore; } // Should we use Integrated Security? if (TrustedConnection && !String.IsNullOrEmpty(IntegratedSecurity)) { string strAddMore = String.Format(@"Trusted_Connection={0};Integrated Security={1};", TrustedConnection.ToString(), IntegratedSecurity); strUDL += strAddMore; } // Persist Security Info? if (PersistSecurityInfo) { string strAddMore = String.Format(@"Persist Security Info={0};", PersistSecurityInfo.ToString()); strUDL += strAddMore; } // SQL CE Encryption if (Encrypt) { string strAddMore = "Encrypt=TRUE;Encryption Mode=platform default;"; strUDL += strAddMore; } // Advantage DB if (!String.IsNullOrEmpty(ServerType)) { string strAddMore = String.Format("ServerType={0};", ServerType); strUDL += strAddMore; strUDL += "TableType=ADT;"; } // At the end, specifically add the connection timeout * If asked to * if (UseConnectionTimeout) { string strAddMore = String.Format(@"Connection Timeout={0};", ConnectionTimeout.ToString()); strUDL += strAddMore; } return strUDL; } } /// /// Returns a Connection String for use with Legacy ADO /// internal string ConnectionStringADO { get { // Force Persist Security Info bool bPersistSecurity = PersistSecurityInfo; PersistSecurityInfo = true; string retString = "Provider=SQLOLEDB.1;OLE DB Services=-2;" + ConnectionString; PersistSecurityInfo = bPersistSecurity; return retString; } } /// /// Parses (fills in) UDL properties from the passed in Connection String /// /// private void Parse(String ConnectionString) { if (!String.IsNullOrEmpty(ConnectionString)) { String[] tokens = ConnectionString.Split(';'); foreach (string Pair in tokens) { string[] KeyValuePair = Pair.Split('='); try { string left = KeyValuePair[0]; string right = KeyValuePair[1]; switch (KeyValuePair[0].ToUpper().Trim()) { case "INITIAL CATALOG": DataBase = right.Trim(); break; case "USER ID": Username = right.Trim(); break; case "PASSWORD": Password = right; break; case "DATA SOURCE": DataSource = right.Trim(); break; case "ATTACHDBFILENAME": AttachDBFilename = right.Trim(); break; case "USER INSTANCE": UserInstance = Boolean.Parse(right.Trim()); break; case "CONNECTION TIMEOUT": ConnectionTimeout = UInt32.Parse(right.Trim()); break; case "TRUSTED_CONNECTION": TrustedConnection = Boolean.Parse(right.Trim()); break; case "INTEGRATED SECURITY": IntegratedSecurity = KeyValuePair[1].Trim().ToUpper(); break; case "PERSIST SECURITY INFO": PersistSecurityInfo = Boolean.Parse(KeyValuePair[1].Trim()); break; case "ENCRYPT": Encrypt = true; break; case "ENCRYPTION MODE": Encrypt = true; break; case "SERVERTYPE": ServerType = KeyValuePair[1].Trim(); break; } } catch (Exception e) { string m = e.Message; /* ignore and continue iteration */ } } } } #endregion #region ICloneable Members /// /// /// /// public object Clone() { return new UDL(this.ConnectionString); } #endregion #region IComparable Members /// /// /// /// /// public int CompareTo(object obj) { UDL otherUDL = obj as UDL; if (otherUDL != null) { int nCompare = String.Compare(this.ConnectionString, otherUDL.ConnectionString, true); return nCompare; } else { throw new ArgumentException("Object is not a UDL"); } } #endregion #region UDL File Reading / Writing /// /// Use this to Parse a UDL object from a text File /// /// Full Path to File to Read and Parse /// true if the Text file is encrypted, false otherwise /// a valid UDL object if successful, null otherwise internal static UDL UDLReadInFromFile(string FileNameNPath, bool bFileIsEncrypted) { if (!File.Exists(FileNameNPath)) return null; try { // Read In the file string UDLFileContents = string.Empty; FileStream fs = new FileStream(FileNameNPath, FileMode.Open); StreamReader sr = new StreamReader(fs, Encoding.Unicode); string line; while ((line = sr.ReadLine()) != null) { // UDL File is encrypted * Decrypt line by line * //if (bFileIsEncrypted) //line = Encryption.DecryptText(line); if (line.StartsWith("[oledb]") || line.StartsWith(";")) continue; // skip first 2 lines // Read the line UDLFileContents += line; } sr.Close(); fs.Close(); UDLFileContents = UDLFileContents.Trim(); if (String.IsNullOrEmpty(UDLFileContents)) return null; // Parse out the UDL Info UDL udl = new UDL(UDLFileContents); return udl; } catch (Exception) {/* ignore */} return null; } /// /// Use this to Write a UDL Object to a Text File /// /// Full Path to File to Write To /// UDL Object to write out /// True to encrypt File Contents, False Otherwise /// true if successful, false otherwise internal static bool UDLWriteOutToToFile(string FileNameNPath, UDL udl, bool bEncryptFile) { try { string UDLFileContents = string.Empty; // Create the Directory (if it doesn't exist) * Otherwise an error occurs * if (!Directory.Exists(Path.GetDirectoryName(FileNameNPath))) Directory.CreateDirectory(Path.GetDirectoryName(FileNameNPath)); // Write to File FileStream fs = new FileStream(FileNameNPath, FileMode.Create); StreamWriter sw = new StreamWriter(fs, Encoding.Unicode); // UDL File is Encrypted Now, so we encrypte Line-by-line if (bEncryptFile) { // sw.WriteLine(Encryption.EncryptText("[oledb]")); // sw.WriteLine(Encryption.EncryptText("; Everything after this line is an OLE DB initstring")); // write out the Connection string, // sw.WriteLine(Encryption.EncryptText(udl.ConnectionStringLegacy)); } else { sw.WriteLine("[oledb]"); sw.WriteLine("; Everything after this line is an OLE DB initstring"); sw.WriteLine(udl.ConnectionString); } sw.Close(); fs.Close(); return true; } catch (Exception) { /* ignore */ } return false; } #endregion } }