diff --git a/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/DataLink/DataLinkObjectModel.cs b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/DataLink/DataLinkObjectModel.cs
new file mode 100644
index 00000000..d9407532
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Essential/ObjectModels/DataLink/DataLinkObjectModel.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.ObjectModels.DataLink
+{
+ public class DataLinkObjectModel : ObjectModel
+ {
+ private static ObjectModelReference _omr = null;
+ public override ObjectModelReference MakeReference()
+ {
+ if (_omr == null)
+ {
+ _omr = base.MakeReference();
+ _omr.Title = "Data Link";
+ }
+ return _omr;
+ }
+
+ public override void Clear()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void CopyTo(ObjectModel where)
+ {
+ throw new NotImplementedException();
+ }
+
+ private string mvarProviderName = String.Empty;
+ ///
+ /// The name of the OLEDB provider to use in this data link. If no Provider is specified,
+ /// the OLE DB Provider for ODBC (MSDASQL) is the default value. This provides backward
+ /// compatibility with ODBC connection strings.
+ ///
+ public string ProviderName { get { return mvarProviderName; } set { mvarProviderName = value; } }
+
+ private string mvarProviderVersion = null;
+ ///
+ /// The version number of the OLEDB provider to use. If unspecified, will use the version-
+ /// independent OLEDB provider.
+ ///
+ public string ProviderVersion { get { return mvarProviderVersion; } set { mvarProviderVersion = value; } }
+
+ private bool mvarPersistSecurityInformation = false;
+ public bool PersistSecurityInformation { get { return mvarPersistSecurityInformation; } set { mvarPersistSecurityInformation = value; } }
+
+ private string mvarDataSourceName = String.Empty;
+ ///
+ /// The name of the data source or host name of the server from which to retrieve data.
+ ///
+ public string DataSourceName { get { return mvarDataSourceName; } set { mvarDataSourceName = value; } }
+
+ private string mvarInitialCatalog = String.Empty;
+ ///
+ /// The initial catalog or name of the database from which to retrieve data.
+ ///
+ public string InitialCatalog { get { return mvarInitialCatalog; } set { mvarInitialCatalog = value; } }
+
+ private bool mvarUseIntegratedSecurity = false;
+ ///
+ /// Determines whether integrated security (e.g. Windows authentication) is to be used.
+ ///
+ public bool UseIntegratedSecurity { get { return mvarUseIntegratedSecurity; } set { mvarUseIntegratedSecurity = value; } }
+
+ private PropertyList.Property.PropertyCollection mvarProperties = new PropertyList.Property.PropertyCollection();
+ ///
+ /// Additional properties to pass into the connection string.
+ ///
+ public PropertyList.Property.PropertyCollection Properties { get { return mvarProperties; } }
+
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Essential/UniversalEditor.Essential.csproj b/CSharp/Plugins/UniversalEditor.Essential/UniversalEditor.Essential.csproj
index bd273733..c98ed677 100644
--- a/CSharp/Plugins/UniversalEditor.Essential/UniversalEditor.Essential.csproj
+++ b/CSharp/Plugins/UniversalEditor.Essential/UniversalEditor.Essential.csproj
@@ -66,6 +66,7 @@
Code
+
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/DataLink/UniversalDataLink/UDLDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/DataLink/UniversalDataLink/UDLDataFormat.cs
new file mode 100644
index 00000000..17857de4
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/DataLink/UniversalDataLink/UDLDataFormat.cs
@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using UniversalEditor.DataFormats.PropertyList;
+using UniversalEditor.ObjectModels.PropertyList;
+
+using UniversalEditor.ObjectModels.DataLink;
+
+namespace UniversalEditor.DataFormats.DataLink.UniversalDataLink
+{
+ public class UDLDataFormat : WindowsConfigurationDataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ public override DataFormatReference MakeReference()
+ {
+ if (_dfr == null)
+ {
+ _dfr = new DataFormatReference(GetType());
+ _dfr.Capabilities.Add(typeof(DataLinkObjectModel), DataFormatCapabilities.All);
+ _dfr.Capabilities.Add(typeof(PropertyListObjectModel), DataFormatCapabilities.Bootstrap);
+ _dfr.Filters.Add("Universal Data Link", new byte?[][] { new byte?[] { (byte)'[', (byte)'o', (byte)'l', (byte)'e', (byte)'d', (byte)'b', (byte)']' } }, new string[] { "*.udl" });
+ _dfr.Sources.Add("http://msdn.microsoft.com/en-us/library/ms722656%28v=vs.71%29.aspx");
+ }
+ return _dfr;
+ }
+ protected override void BeforeLoadInternal(Stack objectModels)
+ {
+ objectModels.Push(new PropertyListObjectModel());
+ }
+ protected override void AfterLoadInternal(Stack objectModels)
+ {
+ PropertyListObjectModel plom = (objectModels.Pop() as PropertyListObjectModel);
+ DataLinkObjectModel data = (objectModels.Pop() as DataLinkObjectModel);
+
+ Group oledb = plom.Groups["oledb"];
+ if (oledb == null) throw new InvalidDataFormatException("File does not contain a [oledb] group");
+ // if (oledb.CommentAfter != "Everything after this line is an OLE DB initstring") throw new InvalidDataFormatException("File does not contain the magic comment string \"Everything after this line is an OLE DB initstring\"");
+
+ Property provider = oledb.Properties["Provider"];
+ if (provider == null) throw new InvalidDataFormatException("File does not contain a \"Provider\" property in the \"oledb\" group");
+
+ string connstr = provider.Value.ToString();
+ string[] providerNameAndVersionParts = connstr.Split(new char[] { ';' }, 1);
+ string providerNameAndVersion = providerNameAndVersionParts[0];
+ string connstr1 = providerNameAndVersionParts[1];
+
+ string providerName = providerNameAndVersion;
+ string providerVersion = null;
+ if (providerNameAndVersion.Contains("."))
+ {
+ string[] pnav = providerNameAndVersion.Split(new char[] { '.' }, 2);
+ providerName = pnav[0];
+ providerVersion = pnav[1];
+ }
+ data.ProviderName = providerName;
+ data.ProviderVersion = providerVersion;
+
+ Property.PropertyCollection props = ParseConnectionString(connstr1);
+
+ foreach (Property p in props)
+ {
+ if (p.Value == null) continue;
+ switch (p.Name)
+ {
+ case "Data Source":
+ {
+ data.DataSourceName = p.Value.ToString();
+ break;
+ }
+ case "Initial Catalog":
+ {
+ data.InitialCatalog = p.Value.ToString();
+ break;
+ }
+ case "Integrated Security":
+ {
+ data.UseIntegratedSecurity = (p.Value.ToString() == "True");
+ break;
+ }
+ case "Persist Security Info":
+ {
+ data.PersistSecurityInformation = (p.Value.ToString() == "True");
+ break;
+ }
+ default:
+ {
+ data.Properties.Add(p.Clone() as Property);
+ break;
+ }
+ }
+ }
+ }
+
+ private Property.PropertyCollection ParseConnectionString(string connstr)
+ {
+ Property.PropertyCollection props = new Property.PropertyCollection();
+ string next = String.Empty;
+ Property prop = new Property();
+ for (int i = 0; i < connstr.Length; i++)
+ {
+ char c = connstr[i];
+ if (c == '=')
+ {
+ if (i < connstr.Length - 1 && connstr[i + 1] == '=')
+ {
+ next += "=";
+ i++;
+ continue;
+ }
+ else
+ {
+ prop.Name = next;
+ next = String.Empty;
+ }
+ }
+ else if (c == ';')
+ {
+ prop.Value = next;
+ next = String.Empty;
+ props.Add(prop);
+ prop = new Property();
+ }
+ else
+ {
+ connstr += c;
+ }
+ }
+ return props;
+ }
+
+ protected override void BeforeSaveInternal(Stack objectModels)
+ {
+ DataLinkObjectModel data = (objectModels.Pop() as DataLinkObjectModel);
+ PropertyListObjectModel plom = new PropertyListObjectModel();
+
+ Group oledb = new Group("oledb");
+ oledb.CommentAfter = "Everything after this line is an OLE DB initstring";
+
+ StringBuilder connstr = new StringBuilder();
+ connstr.Append(data.ProviderName);
+ if (data.ProviderVersion != null)
+ {
+ connstr.Append(".");
+ connstr.Append(data.ProviderVersion);
+ }
+ connstr.Append(";");
+ connstr.Append("Persist Security Info=");
+ if (data.PersistSecurityInformation)
+ {
+ connstr.Append("True");
+ }
+ else
+ {
+ connstr.Append("False");
+ }
+ connstr.Append(";Data Source=");
+ connstr.Append(data.DataSourceName);
+ connstr.Append(";Initial Catalog=");
+ connstr.Append(data.InitialCatalog);
+ if (data.UseIntegratedSecurity)
+ {
+ connstr.Append(";Integrated Security=SSPI");
+ }
+
+ foreach (Property prop in data.Properties)
+ {
+ connstr.Append(";");
+ connstr.Append(prop.Name.Replace("=", "=="));
+ connstr.Append("=");
+ connstr.Append(prop.Value.ToString());
+ }
+
+ oledb.Properties.Add("Provider", connstr.ToString());
+
+ plom.Groups.Add(oledb);
+
+ objectModels.Push(plom);
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/UniversalEditor.Plugins.Microsoft.csproj b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/UniversalEditor.Plugins.Microsoft.csproj
index e19ec0b1..00df1797 100644
--- a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/UniversalEditor.Plugins.Microsoft.csproj
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/UniversalEditor.Plugins.Microsoft.csproj
@@ -35,6 +35,7 @@
+