This works like a charm for SQL Server 6.5, I can't vouch for others...
BOOL EnsureDSNExists(LPCSTR szDSN,
BOOL bIsSystemDSN,
LPCSTR szDriverName,
LPCSTR szServer,
LPCSTR szDatabase,
LPCSTR szNetLibrary,
LPCSTR szAddress)
{
char dsn[SQL_MAX_DSN_LENGTH+1];
char desc[256];
short len,desclen;
BOOL result=FALSE;
HENV hEnv;
RETCODE ret;
ret = SQLAllocEnv(&hEnv);
if (ret == SQL_ERROR)
return FALSE;
// search for existing DSN
ret = SQLDataSources(hEnv, SQL_FETCH_FIRST, (BYTE *)dsn, SQL_MAX_DSN_LENGTH, &len, (BYTE *)desc, 255, &desclen);
while (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
if (!strcmp(dsn,szDSN))
{
result=TRUE;
break;
}
ret = SQLDataSources(hEnv, SQL_FETCH_NEXT, (BYTE *)dsn, SQL_MAX_DSN_LENGTH, &len, (BYTE *)desc, 255, &desclen);
}
if (!result)
{
// if we got here, the DSN doesn't exist
char buf[2048];
sprintf(buf,"SERVER=%s%c"
"DSN=%s%c"
"DATABASE=%s%c"
"NETWORK=%s%c"
"ADDRESS=%s%c",
szServer,'\0',
szDSN,'\0',
szDatabase,'\0',
szNetLibrary,'\0',
szAddress,'\0');
result = ::SQLConfigDataSource(NULL, bIsSystemDSN? ODBC_ADD_SYS_DSN:ODBC_ADD_DSN, szDriverName, buf);
}
SQLFreeEnv(hEnv);
return result;
}