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; }