Skip to content

Instantly share code, notes, and snippets.

@Mordo95
Created June 13, 2018 10:11
Show Gist options
  • Save Mordo95/736eac08fe0ea6aff56664c4472db087 to your computer and use it in GitHub Desktop.
Save Mordo95/736eac08fe0ea6aff56664c4472db087 to your computer and use it in GitHub Desktop.
C# DSN class to Modify or query ODBC sources
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
public enum ODBC_ACTION : int
{
ADD_DSN = 1,
CONFIG_DSN,
REMOVE_DSN,
ADD_SYS_DSN,
CONFIG_SYS_DSN,
REMOVE_SYS_DSN
}
public enum CONFIG_MODE : int
{
ODBC_BOTH_DSN = 0,
ODBC_USER_DSN = 1,
ODBC_SYSTEM_DSN = 2,
}
public static class DSN
{
public static void Remove(string provider, string attributes, bool sysdsn = false)
{
bool ret = ConfigureDSN(sysdsn ? ODBC_ACTION.REMOVE_SYS_DSN : ODBC_ACTION.REMOVE_DSN, provider, attributes);
if (!ret)
throw new Win32Exception(Marshal.GetLastWin32Error().ToString());
}
public static void Add(string provider, string attributes, bool sysdsn = false)
{
bool ret = ConfigureDSN(sysdsn ? ODBC_ACTION.ADD_SYS_DSN : ODBC_ACTION.ADD_DSN, provider, attributes);
if (!ret)
throw new Win32Exception(Marshal.GetLastWin32Error().ToString());
}
public static bool Exists(string provider, string dsnName, bool sysdsn = false, string attributes = "")
{
return ConfigureDSN(sysdsn ? ODBC_ACTION.CONFIG_SYS_DSN : ODBC_ACTION.CONFIG_DSN, provider, string.Concat("DSN=", dsnName, "\0", attributes));
}
public static bool ConfigureDSN(ODBC_ACTION fRequest, string lpszDriver, string lpszAttributes)
{
return SQLConfigDataSource(IntPtr.Zero, (int)fRequest, lpszDriver, lpszAttributes);
}
public static string CreateAttributesFromPrivateProfileString(string input)
{
return input.Replace(';', '\0');
}
public static string GetConfig(string dsnName, CONFIG_MODE configMode = CONFIG_MODE.ODBC_BOTH_DSN)
{
bool success = SQLSetConfigMode(configMode);
if (!success)
throw new Win32Exception(Marshal.GetLastWin32Error());
char[] retBuf = new char[8192];
int length = SQLGetPrivateProfileString(dsnName, null, "", retBuf, retBuf.Length, "odbc.ini");
string keyStr = new string(retBuf, 0, length);
string[] keys = keyStr.Split(new string[] { "\0" }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder sb = new StringBuilder();
foreach (string key in keys)
{
char[] retBuf2 = new char[8192];
int l2 = SQLGetPrivateProfileString(dsnName, key, "", retBuf2, retBuf2.Length, "odbc.ini");
sb.Append(key);
sb.Append(" = ");
sb.Append(new string(retBuf2, 0, l2));
sb.Append(";");
}
return sb.ToString();
}
/// <summary>
/// Win32 API Imports
/// </summary>
[DllImport("ODBCCP32.dll")]
private static extern bool SQLConfigDataSource(IntPtr hwndParent, int fRequest, string lpszDriver, string lpszAttributes);
[DllImport("ODBCCP32.dll", SetLastError = true)]
static extern int SQLGetPrivateProfileString(string lpszSection, string lpszEntry, string lpszDefault, [Out] char[] retBuffer, int cbRetBuffer, string lpszFileName);
[DllImport("ODBCCP32.dll", SetLastError = true)]
static extern bool SQLSetConfigMode(CONFIG_MODE configMode);
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
/* NOTE FOR 32 BIT SOURCES: YOU NEED TO COMPILE WITH x86 ARCHITECTURE. ANY CPU WILL NOT WORK! */
//Check if DSN exists
bool b = DSN.Exists("SQL Server", "test");
//Get DSN details
string dsnDetails = DSN.GetConfig("test");
//Add DSN
DSN.Add("SQL Server", "DSN=some name");
//Delete DSN
DSN.Add("SQL Server", "DSN=some name");
//Backup and restore:
bool exists = DSN.Exists("SQL Server", "test");
if (exists) {
string data = DSN.GetConfig("test");
DSN.Remove("SQL Server", "DSN=test");
DSN.Add("SQL Server", DSN.CreateAttributesFromPrivateProfileString("DSN=test;" + data));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment