602 lines
22 KiB
C#
602 lines
22 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.IO;
|
|
|
|
namespace Sdaleo
|
|
{
|
|
/// <summary>
|
|
/// Core Class to Parse / Generate a UDL String
|
|
/// </summary>
|
|
internal class UDL : ICloneable, IComparable
|
|
{
|
|
#region Internal ReadWrite Properties
|
|
|
|
/// <summary>
|
|
/// Credential Object can point to different databases
|
|
/// </summary>
|
|
internal string DataBase { get; set; }
|
|
|
|
/// <summary>
|
|
/// Default Connection Timeout
|
|
/// </summary>
|
|
internal const uint DEFAULT_CONNECTION_TIMEOUT_UDL = 15;
|
|
|
|
/// <summary>
|
|
/// Allow Caller to set connection timeout
|
|
/// </summary>
|
|
internal uint ConnectionTimeout = DEFAULT_CONNECTION_TIMEOUT_UDL;
|
|
|
|
/// <summary>
|
|
/// Defaulted to 'true'. When set uses the ConnectionTimeout value, when false it won't
|
|
/// </summary>
|
|
internal bool UseConnectionTimeout = true;
|
|
|
|
// * Secured Password *
|
|
private SecuredPassword _Password = new SecuredPassword();
|
|
|
|
/// <summary>
|
|
/// Secured Password Object that stores the password in a secure manner in memory
|
|
/// </summary>
|
|
internal string Password
|
|
{
|
|
get
|
|
{
|
|
return _Password.Password;
|
|
}
|
|
private set
|
|
{
|
|
_Password.Password = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
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
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal string Username { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal string ServerAddress { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal string InstanceName { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal string IntegratedSecurity { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal string AttachDBFilename { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal string ServerType { get; private set; }
|
|
|
|
#endregion
|
|
|
|
#region ReadOnly Bool Getters
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal bool TrustedConnection { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal bool PersistSecurityInfo { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal bool UserInstance { get; private set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
internal bool Encrypt { get; private set; }
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Constructors
|
|
|
|
/// <summary>
|
|
/// Construction (Set all UDL Settings via Connection String)
|
|
/// </summary>
|
|
/// <param name="ConnectionString">Pass in a valid Connection String To correctly instantiate the UDL Object</param>
|
|
internal UDL(String ConnectionString)
|
|
{
|
|
Parse(ConnectionString);
|
|
}
|
|
|
|
#region SQL CE Constructors
|
|
|
|
/// <summary>
|
|
/// Construction SQL CE (Set common UDL Settings for SQL CE)
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <param name="filename"></param>
|
|
/// <param name="Password"></param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Construction Advantage (Set common UDL Settings for Advantage)
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <param name="filename"></param>
|
|
/// <param name="Password"></param>
|
|
/// <param name="ServerType"></param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Construction SQL Server (Using SQL Login Credential)
|
|
/// </summary>
|
|
/// <param name="DataBase">Name of Database To Use</param>
|
|
/// <param name="Username">Username to Connect With</param>
|
|
/// <param name="Password">Password to Connect With</param>
|
|
/// <param name="ServerAddress">ServerAddress to use as DataSource</param>
|
|
/// <param name="InstanceName">Name of Instance to use as DataSource</param>
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Construction SQL Server (Set common UDL Settings for SQL Server)
|
|
/// </summary>
|
|
/// <param name="DataBase">Name of Database To Use</param>
|
|
/// <param name="Username">Username to Connect With</param>
|
|
/// <param name="Password">Password to Connect With</param>
|
|
/// <param name="ServerAddress">ServerAddress to use as DataSource</param>
|
|
/// <param name="InstanceName">Name of Instance to use as DataSource</param>
|
|
/// <param name="TrustedConnection">Set to True to use Windows Authentication instead of SQL Auth</param>
|
|
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" : "";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Construction SQL Server (Set all UDL Settings for SQL Server)
|
|
/// </summary>
|
|
/// <param name="DataBase">Name of Database To Use</param>
|
|
/// <param name="Username">Username to Connect With</param>
|
|
/// <param name="Password">Password to Connect With</param>
|
|
/// <param name="ServerAddress">ServerAddress to use as DataSource</param>
|
|
/// <param name="InstanceName">Name of Instance to use as DataSource</param>
|
|
/// <param name="AttachDBFilename">Set to SQL Express .mdf file to attach to (Creates a User Instance)</param>
|
|
/// <param name="TrustedConnection">Set to True to use Windows Authentication instead of SQL Auth</param>
|
|
/// <param name="PersistSecurityInfo">Legacy Setting that Persists the Security Information</param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Returns the Connection String formed from the UDL Properties
|
|
/// </summary>
|
|
/// <see cref="http://www.connectionstrings.com/sql-server-2008"/>
|
|
/// <example>
|
|
/// 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;
|
|
/// </example>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a Connection String for use with Legacy ADO
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parses (fills in) UDL properties from the passed in Connection String
|
|
/// </summary>
|
|
/// <param name="strToParse"></param>
|
|
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
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public object Clone()
|
|
{
|
|
return new UDL(this.ConnectionString);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IComparable Members
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="obj"></param>
|
|
/// <returns></returns>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Use this to Parse a UDL object from a text File
|
|
/// </summary>
|
|
/// <param name="FileNameNPath">Full Path to File to Read and Parse</param>
|
|
/// <param name="bFileIsEncrypted">true if the Text file is encrypted, false otherwise</param>
|
|
/// <returns>a valid UDL object if successful, null otherwise</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use this to Write a UDL Object to a Text File
|
|
/// </summary>
|
|
/// <param name="FileNameNPath">Full Path to File to Write To</param>
|
|
/// <param name="udl">UDL Object to write out</param>
|
|
/// <param name="bEncryptFile">True to encrypt File Contents, False Otherwise</param>
|
|
/// <returns>true if successful, false otherwise</returns>
|
|
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
|
|
}
|
|
}
|