Ejemplo n.º 1
0
bool COdbcDS::FindInstalledDrvr(const char* pDrvrName)
{
	SQLCHAR Description[100];
	SQLSMALLINT descLen;
	SQLRETURN retVal = SQL_SUCCESS;

	// Loop through all of the data sources until the one we're looking for
	// is found.
	int count = 0;
	while (retVal == SQL_SUCCESS || retVal == SQL_SUCCESS_WITH_INFO)
	{
		if (count == 0)
			retVal = SQLDrivers(m_henv, SQL_FETCH_FIRST, Description,
									sizeof(Description), &descLen,
									NULL, 0, NULL);
		else
			retVal = SQLDrivers(m_henv, SQL_FETCH_NEXT, Description,
									sizeof(Description), &descLen,
									NULL, 0, NULL);
		count++;
		if (retVal == SQL_ERROR)
		{
			throw 3;
		}

		if (strcmp(pDrvrName, (const char*)Description) == 0)
		{
			return true;
		}
	}
	return false;
}
Ejemplo n.º 2
0
int print_installed_drivers()
{
	SQLHENV env;
	SQLCHAR driver[256];
	SQLCHAR attr[256];
	
	SQLSMALLINT driver_ret;
	SQLSMALLINT attr_ret;
	SQLUSMALLINT direction;
	SQLRETURN ret;
	
	SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
	SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
	
	direction = SQL_FETCH_FIRST;
	
	printf("------------------\n");
	printf("Installed drivers\n");
	while(SQL_SUCCEEDED(ret = SQLDrivers(env, direction, driver, sizeof(driver), &driver_ret, attr, sizeof(attr), &attr_ret))) {
		direction = SQL_FETCH_NEXT;
		printf("%s - %s\n", driver, attr);
		if (ret == SQL_SUCCESS_WITH_INFO) printf("\tdata truncation\n");
	}
	return 0;
}
Ejemplo n.º 3
0
void ring_vm_odbc_drivers ( void *pPointer )
{
	ring_odbc *pODBC  ;
	SQLCHAR driver[256]  ;
	SQLCHAR attr[256]  ;
	SQLSMALLINT driver_ret  ;
	SQLSMALLINT attr_ret  ;
	SQLUSMALLINT direction  ;
	List *pList  ;
	String *pString  ;
	if ( RING_API_PARACOUNT != 1 ) {
		RING_API_ERROR(RING_API_MISS1PARA);
		return ;
	}
	if ( RING_API_ISPOINTER(1) ) {
		pODBC = (ring_odbc *) RING_API_GETCPOINTER(1,RING_VM_POINTER_ODBC) ;
		if ( pODBC == NULL ) {
			return ;
		}
		pList = RING_API_NEWLIST ;
		direction = SQL_FETCH_FIRST ;
		while ( SQL_SUCCEEDED(SQLDrivers(pODBC->env, direction, driver, sizeof(driver), &driver_ret,attr, sizeof(attr), &attr_ret)) ) {
			direction = SQL_FETCH_NEXT ;
			pString = ring_string_new((char *) driver);
			ring_string_add(pString," - ");
			ring_string_add(pString, (char *) attr);
			ring_list_addstring(pList,ring_string_get(pString));
			ring_string_delete(pString);
		}
		RING_API_RETLIST(pList);
	} else {
		RING_API_ERROR(RING_API_BADPARATYPE);
	}
}
Ejemplo n.º 4
0
Utility::DriverMap& Utility::drivers(Utility::DriverMap& driverMap)
{
	static const EnvironmentHandle henv;
	const int length = sizeof(SQLCHAR) * 512;

	SQLCHAR desc[length];
	std::memset(desc, 0, length);
	SQLSMALLINT len1 = length;
	SQLCHAR attr[length];
	std::memset(attr, 0, length);
	SQLSMALLINT len2 = length;
	RETCODE rc = 0;

	if (!Utility::isError(rc = SQLDrivers(henv, 
		SQL_FETCH_FIRST,
		desc,
		length,
		&len1,
		attr,
		len2,
		&len2)))
	{
		do
		{
			driverMap.insert(DSNMap::value_type(std::string((char *) desc), 
				std::string((char *) attr)));
			std::memset(desc, 0, length);
			std::memset(attr, 0, length);
			len2 = length;
		}while (!Utility::isError(rc = SQLDrivers(henv, 
			SQL_FETCH_NEXT,
			desc,
			length,
			&len1,
			attr,
			len2,
			&len2)));
	}

	if (SQL_NO_DATA != rc) 
		throw EnvironmentException(henv);

	return driverMap;
}
Ejemplo n.º 5
0
void OdbcConnectionUtil::SetupMySqlDSN()
{
    // Get the name of MySQL ODBC Driver
    char driverDesc[1024];
    char driverAttrs[1024];
    char theMySQLDriverName[1024] = "";
    BOOL ret = false;
    SQLRETURN rc = SQL_ERROR;

    SQLHENV sqlenv = SQL_NULL_HENV;
    rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HENV, &sqlenv);
    if ( SQLRETURN_OK(rc) )
        rc = SQLSetEnvAttr(sqlenv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);

    if ( SQLRETURN_OK(rc) )
    {
        SQLUSMALLINT direction = SQL_FETCH_FIRST;
        SQLSMALLINT driverDescLength = 0;
        SQLSMALLINT driverAttrsLength = 0;
        do
        {
            driverDescLength = 0;
            driverAttrsLength = 0;
            rc = SQLDrivers(sqlenv, direction, (SQLCHAR *) driverDesc, (SQLSMALLINT) sizeof(driverDesc), &driverDescLength,
                (SQLCHAR *) driverAttrs, (SQLSMALLINT) sizeof(driverAttrs), &driverAttrsLength);
            if (SQLRETURN_OK(rc))
            {
                if (NULL != strstr(driverDesc, "MySQL"))
                    strcpy(theMySQLDriverName, driverDesc);
            }
            direction = SQL_FETCH_NEXT;
        }
        while ( SQLRETURN_OK(rc) && SQL_NO_DATA != rc && '\0' == theMySQLDriverName[0] );
    }

    if (sqlenv != SQL_NULL_HENV)
        SQLFreeHandle(SQL_HANDLE_ENV, sqlenv);

    if ('\0' != theMySQLDriverName[0])
        MYSQL_ODBC_DRIVER_NAME = theMySQLDriverName;

    char teststr[1024];
    sprintf (teststr, "DSN=%s%cDescription=Test MySql DSN for FDO ODBC provider%cSERVER=%s%cDATABASE=%ls%cOPTION=3%c%c", (const char*)(FdoStringP)m_SetupValues->GetPropertyValue( L"DSNMySql" ), 
        '\0','\0', (const char*)(FdoStringP)m_SetupValues->GetPropertyValue( L"serviceMySql" ), '\0', (FdoString*)(UnitTestUtil::GetEnviron("datastore", L"")), '\0', '\0', '\0');
    m_SetupMySqlDSNdone = true;
#if 0
    if (!SQLConfigDataSource (NULL, ODBC_ADD_DSN, (const char*)MYSQL_ODBC_DRIVER_NAME, teststr))
    {
        DWORD error;
        WORD count;
        SQLInstallerError (1, &error, teststr, sizeof (teststr), &count);
        printf (teststr);
        throw FdoException::Create (L"MySql DSN setup failed");
    }
#endif
}
Ejemplo n.º 6
0
static PyObject* mod_drivers(PyObject* self)
{
    UNUSED(self);

    if (henv == SQL_NULL_HANDLE && !AllocateEnv())
        return 0;

    Object result(PyList_New(0));
    if (!result)
        return 0;

    SQLCHAR szDriverDesc[500];
    SWORD cbDriverDesc;
    SWORD cbAttrs;

    SQLRETURN ret;
    SQLUSMALLINT nDirection = SQL_FETCH_FIRST;

    for (;;)
    {
        Py_BEGIN_ALLOW_THREADS
        ret = SQLDrivers(henv, nDirection, szDriverDesc, _countof(szDriverDesc), &cbDriverDesc, 0, 0, &cbAttrs);
        Py_END_ALLOW_THREADS

        if (!SQL_SUCCEEDED(ret))
            break;

        // REVIEW: This is another reason why we really need a factory that we can use.  At this
        // point we don't have a global text encoding that we can assume for this.  Somehow it
        // seems to be working to use UTF-8, even on Windows.
        Object name(PyString_FromString((const char*)szDriverDesc));
        if (!name)
            return 0;

        if (PyList_Append(result, name.Get()) != 0)
            return 0;
        name.Detach();

        nDirection = SQL_FETCH_NEXT;
    }

    if (ret != SQL_NO_DATA)
    {
        Py_DECREF(result);
        return RaiseErrorFromHandle(0, "SQLDrivers", SQL_NULL_HANDLE, SQL_NULL_HANDLE);
    }

    return result.Detach();
}
Ejemplo n.º 7
0
SQLRETURN SQLDriversA(
    SQLHENV            henv,
    SQLUSMALLINT       fdirection,
    SQLCHAR            *sz_driver_desc,
    SQLSMALLINT        cb_driver_desc_max,
    SQLSMALLINT        *pcb_driver_desc,
    SQLCHAR            *sz_driver_attributes,
    SQLSMALLINT        cb_drvr_attr_max,
    SQLSMALLINT        *pcb_drvr_attr )
{
    return SQLDrivers( henv,
                        fdirection,
                        sz_driver_desc,
                        cb_driver_desc_max,
                        pcb_driver_desc,
                        sz_driver_attributes,
                        cb_drvr_attr_max,
                        pcb_drvr_attr );
}
Ejemplo n.º 8
0
SQLRETURN SQL_API
SQLDriversA(SQLHENV EnvironmentHandle,
	    SQLUSMALLINT Direction,
	    SQLCHAR *DriverDescription,
	    SQLSMALLINT BufferLength1,
	    SQLSMALLINT *DescriptionLengthPtr,
	    SQLCHAR *DriverAttributes,
	    SQLSMALLINT BufferLength2,
	    SQLSMALLINT *AttributesLengthPtr)
{
	return SQLDrivers(EnvironmentHandle,
			  Direction,
			  DriverDescription,
			  BufferLength1,
			  DescriptionLengthPtr,
			  DriverAttributes,
			  BufferLength2,
			  AttributesLengthPtr);
}
Ejemplo n.º 9
0
void list_drivers() 
{
    char driver[256];
    char attr[256];
    SQLSMALLINT driver_ret;
    SQLSMALLINT attr_ret;
    SQLUSMALLINT direction;
    SQLRETURN ret;

    SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);

    printf("Drivers:\n");
    direction = SQL_FETCH_FIRST;
    while(SQL_SUCCEEDED(ret = SQLDrivers(env, direction,
                                         driver, sizeof(driver), &driver_ret,
                                         attr, sizeof(attr), &attr_ret))) {
        direction = SQL_FETCH_NEXT;
        printf("        %s - %s\n", driver, attr);
        if (ret == SQL_SUCCESS_WITH_INFO) printf("\tdata truncation\n");
    }
}
Ejemplo n.º 10
0
void ODBCHandler::listDrivers()
{
     SQLHENV env;
     SQLCHAR driver[256];
     //char attr[256];
     SQLCHAR attr[256];
     SQLSMALLINT driver_ret;
     SQLSMALLINT attr_ret;
     SQLUSMALLINT direction;
     SQLRETURN ret;

     SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
     SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);

     direction = SQL_FETCH_FIRST;
     while(SQL_SUCCEEDED(ret = SQLDrivers(env, direction,
                          driver, sizeof(driver), &driver_ret,
                          attr, sizeof(attr), &attr_ret))) {
       direction = SQL_FETCH_NEXT;
       fprintf(stderr, "%s - %s\n", driver, attr);
       if (ret == SQL_SUCCESS_WITH_INFO) fprintf(stderr, "\tdata truncation\n");
     }
}
Ejemplo n.º 11
0
unsigned short check_drivers(unsigned short dump) {
	SQLUSMALLINT dir = SQL_FETCH_FIRST;
	char driver[BUFLEN + 1];
	SQLSMALLINT driver_ret;
	char attr[BUFLEN + 1];
	SQLSMALLINT attr_ret;
	SQLRETURN ret;
	unsigned short found = 0;

	while (SQL_SUCCEEDED(ret = SQLDrivers(H_ENV, dir, driver, sizeof(driver), &driver_ret, attr, sizeof(attr), &attr_ret))) {
		dir = SQL_FETCH_NEXT;
		if (1 == dump) {
			printf("%s - %s\n", driver, attr);
			if (ret == SQL_SUCCESS_WITH_INFO) printf("\tdata truncation\n");
		}
		else if (strncmp(driver, SQLDRV, sizeof(driver)) == 0) {
			found = 1;
			break;
		}
	}

	return (0 == dump && 0 == found);
}
Ejemplo n.º 12
0
// Establish an Oracle DSN.  Oracle does not have a constant name, but rather
// a formulated one based on installed instance.  We'll look for the substrings
// "Oracle" and "10g", unless the user has overridden this pattern using
// the "odbcoracledriver" environment variable.
void OdbcConnectionUtil::SetupOracleDSN()
{
    char driverDesc[1024];
    char driverAttrs[1024];
    theOracleDriverName[0] = '\0';
	char teststr[1024];
	BOOL ret = false;
	SQLRETURN rc = SQL_ERROR;
    m_SetupOracleDSNdone = true;

    SQLHENV sqlenv = SQL_NULL_HENV;
    rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HENV, &sqlenv);
    if ( SQLRETURN_OK(rc) )
        rc = SQLSetEnvAttr(sqlenv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);

    if ( SQLRETURN_OK(rc) )
    {
        SQLUSMALLINT direction = SQL_FETCH_FIRST;
        SQLSMALLINT driverDescLength = 0;
        SQLSMALLINT driverAttrsLength = 0;
        do
        {
            driverDescLength = 0;
            driverAttrsLength = 0;
            rc = SQLDrivers(sqlenv, direction, (SQLCHAR *) driverDesc, (SQLSMALLINT) sizeof(driverDesc), &driverDescLength,
                (SQLCHAR *) driverAttrs, (SQLSMALLINT) sizeof(driverAttrs), &driverAttrsLength);
            if (SQLRETURN_OK(rc))
            {
                #ifdef WIN32
                #pragma message("TODO: update this with each Oracle version update")
                #endif
                if (NULL != strstr(driverDesc, "Oracle") && (NULL != strstr(driverDesc, "10") || NULL != strstr(driverDesc, "11")))
                    strcpy(theOracleDriverName, driverDesc);
            }
            direction = SQL_FETCH_NEXT;
        }
        while ( SQLRETURN_OK(rc) && SQL_NO_DATA != rc && '\0' == theOracleDriverName[0] );
	    
        if (m_SetupValues->PropertyExist( L"enableOracleSetup" ))
	    {
		    FdoStringP pValue = m_SetupValues->GetPropertyValue( L"enableOracleSetup" );
		    if (pValue != L"true")
			    return;
	    }
        if (SQL_NO_DATA == rc)
            rc = SQL_SUCCESS;
		direction = SQL_FETCH_FIRST;
		FdoStringP pDSNOracle = m_SetupValues->GetPropertyValue( L"DSNOracle");
		while(SQLRETURN_OK(SQLDataSources(sqlenv, direction, (SQLCHAR *)teststr, sizeof(teststr), &driverAttrsLength, (SQLCHAR *)driverDesc, sizeof(driverDesc), &driverDescLength)))
		{
			direction = SQL_FETCH_NEXT;
			if (pDSNOracle == (FdoStringP)teststr)
			{
				SQLFreeHandle(SQL_HANDLE_ENV, sqlenv);
				return;
			}
		}
    }
    if (SQLRETURN_OK(rc) && '\0' != theOracleDriverName[0])
    {
        char* datastoreUpper = driverDesc;
        sprintf(datastoreUpper, "%ls", (FdoString*) UnitTestUtil::GetEnviron("datastore", L""));
        (void) _strupr_s(datastoreUpper, 1024);

        sprintf ( teststr, "DSN=%s%cDescription=Oracle DSN for FDO ODBC provider%cServerName=%s%cUserID=%s%c%c", (const char*)(FdoStringP)m_SetupValues->GetPropertyValue( L"DSNOracle"), '\0',
            '\0', (const char*)(FdoStringP)m_SetupValues->GetPropertyValue( L"serviceOracle" ), '\0', datastoreUpper, '\0', '\0', '\0');
		ret = SQLConfigDataSource (NULL, ODBC_ADD_DSN, theOracleDriverName, teststr);
    }

    if (!SQLRETURN_OK(rc))
    {
    	SQLSMALLINT cRecNmbr = 1;
	    UCHAR		szSqlState[MAX_PATH] = "";
	    UCHAR 	 	szErrorMsg[MAX_PATH] = "";
	    SDWORD		pfNativeError = 0L;
	    SWORD	 	pcbErrorMsg = 0;

		rc = SQLGetDiagRec(SQL_HANDLE_ENV, sqlenv, 1, szSqlState, &pfNativeError, szErrorMsg, MAX_PATH-1, &pcbErrorMsg);
        printf("%.200s\n", (char *)szErrorMsg);
        throw FdoException::Create (L"Oracle DSN setup failed");
    }
	if (sqlenv != SQL_NULL_HENV)
		SQLFreeHandle(SQL_HANDLE_ENV, sqlenv);
    if (!ret )
    {
        DWORD error;
        WORD count;
        SQLInstallerError (1, &error, teststr, sizeof (teststr), &count);
        printf (teststr);
        throw FdoException::Create (L"Oracle DSN setup failed");
    }

    if ('\0' == theOracleDriverName[0])
        throw FdoException::Create (L"Oracle DSN setup failed");
}
Ejemplo n.º 13
0
static int odbc_dispatch5(void)
{
	unsigned long retval;
	PWord rval; int rtype;
	PWord arg1; int type1;
	PWord arg2; int type2;
	PWord arg3; int type3;
	PWord arg4; int type4;
	PWord arg5; int type5;
	PWord arg6; int type6;
	PWord arg7; int type7;
	PWord arg8; int type8;
	PWord arg9; int type9;
	PWord arg10; int type10;

	PI_getan(&arg1,&type1,1);
	if (type1 != PI_INT)
		if (!CI_get_integer((unsigned long *)&arg1,type1))
			PI_FAIL;
	PI_getan(&arg2,&type2,2);
	if (type2 != PI_INT)
		if (!CI_get_integer((unsigned long *)&arg2,type2))
			PI_FAIL;
	PI_getan(&arg3,&type3,3);
	if (type3 != PI_INT)
		if (!CI_get_integer((unsigned long *)&arg3,type3))
			PI_FAIL;
	PI_getan(&arg4,&type4,4);
	if (type4 == PI_SYM)
		arg4 = (unsigned long) PI_getsymname(0,arg4,0);
	else if (!CI_get_integer((unsigned long *)&arg4,type4))
		PI_FAIL;
	PI_getan(&arg5,&type5,5);
	if (type5 != PI_INT)
		if (!CI_get_integer((unsigned long *)&arg5,type5))
			PI_FAIL;
	PI_getan(&arg6,&type6,6);
	if (type6 != PI_INT)
		if (!CI_get_integer((unsigned long *)&arg6,type6))
			PI_FAIL;
	PI_getan(&arg7,&type7,7);
	if (type7 == PI_SYM)
		arg7 = (unsigned long) PI_getsymname(0,arg7,0);
	else if (!CI_get_integer((unsigned long *)&arg7,type7))
		PI_FAIL;
	PI_getan(&arg8,&type8,8);
	if (type8 != PI_INT)
		if (!CI_get_integer((unsigned long *)&arg8,type8))
			PI_FAIL;
	PI_getan(&arg9,&type9,9);
	if (type9 != PI_INT)
		if (!CI_get_integer((unsigned long *)&arg9,type9))
			PI_FAIL;
	PI_getan(&arg10,&type10,10);


	switch(arg1)
	{
		case 0:
			retval = (unsigned long) SQLDrivers(((SQLHENV  ) arg2),((SQLUSMALLINT  ) arg3),((SQLCHAR * ) arg4),((SQLSMALLINT  ) arg5),((SQLSMALLINT * ) arg6),((SQLCHAR * ) arg7),((SQLSMALLINT  ) arg8),((SQLSMALLINT * ) arg9));
			break;
		case 1:
			retval = (unsigned long) SQLDataSources(((SQLHENV  ) arg2),((SQLUSMALLINT  ) arg3),((SQLCHAR * ) arg4),((SQLSMALLINT  ) arg5),((SQLSMALLINT * ) arg6),((SQLCHAR * ) arg7),((SQLSMALLINT  ) arg8),((SQLSMALLINT * ) arg9));
			break;
		default:
			PI_FAIL;
	}
	PI_makedouble(&rval,&rtype,(double) retval);
	if (PI_unify(arg10,type10,rval,rtype))
		PI_SUCCEED;
	PI_FAIL;
}
Ejemplo n.º 14
0
Archivo: lenv.c Proyecto: ld-test/odbc
static int env_getdrivers (lua_State *L) {
    lodbc_env *env = (lodbc_env *) lodbc_getenv (L);
    SQLRETURN ret;
    SQLSMALLINT attrlen,desclen;
    int i = 1;
    char desc[MAX_DESC_LEN];
    char *attr = malloc(MAX_ATTR_LEN+1);
    int is_cb = lua_isfunction(L,2);
    int top = lua_gettop(L);

    if(!attr)
        return LODBC_ALLOCATE_ERROR(L);

    ret = SQLDrivers(env->handle,SQL_FETCH_FIRST,
                     (SQLPOINTER)desc,MAX_DESC_LEN,&desclen,
                     (SQLPOINTER)attr,MAX_ATTR_LEN,&attrlen);
    if(!is_cb) top++,lua_newtable(L);
    if(LODBC_ODBC3_C(SQL_NO_DATA,SQL_NO_DATA_FOUND) == ret) {
        free(attr);
        return is_cb ? 0 : 1;
    }
    while(!lodbc_iserror(ret)) {
        assert(top == lua_gettop(L));
        if(is_cb) lua_pushvalue(L, 2);

        //find our attributes
        if(attr[0]!=0) {
            size_t i=0, last=0, n=1;
            lua_newtable(L);
            do {
                char *p,*a;
                while(attr[++i] != 0);
                a = &(attr[last]);
                p = strchr(a,'=');
                if(p) {
                    lua_pushlstring(L, a, p-a);
                    lua_pushlstring(L, p + 1, (i-last)-(p-a)-1);
                    lua_settable(L,-3);
                }
                else {
                    lua_pushlstring(L,a,(i-last));
                    lua_rawseti(L,-2,n++);
                }
                last=i+1;
            } while(attr[last]!=0);
        }
        else lua_pushnil(L);

        if(!is_cb) {
            lua_newtable(L);
            lua_insert(L,-2);
            lua_rawseti(L,-2,2);
            lua_pushstring(L,desc);
            lua_rawseti(L,-2,1);
            lua_rawseti(L,-2,i++);
        }
        else {
            int ret;
            lua_pushstring(L,desc);
            lua_insert(L,-2);

            lua_call(L,2,LUA_MULTRET);
            ret = lua_gettop(L) - top;
            assert(ret >= 0);
            if(ret) {
                free(attr);
                return ret;
            }
        }

        ret = SQLDrivers(env->handle,SQL_FETCH_NEXT,
                         (SQLPOINTER)desc,MAX_DESC_LEN,&desclen,
                         (SQLPOINTER)attr,MAX_ATTR_LEN,&attrlen);

        if(LODBC_ODBC3_C(SQL_NO_DATA,SQL_NO_DATA_FOUND) == ret) {
            free(attr);
            return is_cb ? 0 : 1;
        }
    }
    free(attr);
    return lodbc_fail(L, hENV, env->handle);
}
Ejemplo n.º 15
0
void
adddrivers_to_list (GtkWidget *widget, GtkWidget *dlg)
{
  SQLCHAR drvdesc[1024], drvattrs[1024], driver[1024], size[64];
  SQLCHAR *data[4];
  void *handle;
  struct stat _stat;
  SQLSMALLINT len, len1;
  SQLRETURN ret;
  HENV henv, drv_henv;
  HDBC drv_hdbc;
  pSQLGetInfoFunc funcHdl;
  pSQLAllocHandle allocHdl;
  pSQLAllocEnv allocEnvHdl = NULL;
  pSQLAllocConnect allocConnectHdl = NULL;
  pSQLFreeHandle freeHdl;
  pSQLFreeEnv freeEnvHdl;
  pSQLFreeConnect freeConnectHdl;

  if (!GTK_IS_CLIST (widget))
    return;
  gtk_clist_clear (GTK_CLIST (widget));

  /* Create a HENV to get the list of drivers then */
  ret = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
  if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
    {
      _iodbcdm_nativeerrorbox (dlg, henv, SQL_NULL_HANDLE, SQL_NULL_HANDLE);
      goto end;
    }

  /* Set the version ODBC API to use */
  SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3,
      SQL_IS_INTEGER);

  /* Get the list of drivers */
  ret =
      SQLDrivers (henv, SQL_FETCH_FIRST, drvdesc,
      sizeof (drvdesc) / sizeof (SQLTCHAR), &len, drvattrs,
      sizeof (drvattrs) / sizeof (SQLTCHAR), &len1);
  if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO
      && ret != SQL_NO_DATA)
    {
      _iodbcdm_nativeerrorbox (dlg, henv, SQL_NULL_HANDLE, SQL_NULL_HANDLE);
      goto error;
    }

  while (ret != SQL_NO_DATA)
    {
      data[0] = drvdesc;

      /* Get the driver library name */
      SQLSetConfigMode (ODBC_BOTH_DSN);
      SQLGetPrivateProfileString (drvdesc, "Driver", "", driver,
	  sizeof (driver) / sizeof (SQLTCHAR), "odbcinst.ini");
      if (driver[0] == '\0')
	SQLGetPrivateProfileString ("Default", "Driver", "", driver,
	    sizeof (driver) / sizeof (SQLTCHAR), "odbcinst.ini");
      if (driver[0] == '\0')
	{
	  data[0] = NULL;
	  goto skip;
	}

      data[1] = driver;

      drv_hdbc = NULL;
      drv_henv = NULL;

      if ((handle = (void *) DLL_OPEN (driver)) != NULL)
	{
	  if ((allocHdl =
		  (pSQLAllocHandle) DLL_PROC (handle,
		      "SQLAllocHandle")) != NULL)
	    {
	      ret = allocHdl (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &drv_henv);
	      if (ret == SQL_ERROR)
		goto nodriverver;
	      ret = allocHdl (SQL_HANDLE_DBC, drv_henv, &drv_hdbc);
	      if (ret == SQL_ERROR)
		goto nodriverver;
	    }
	  else
	    {
	      if ((allocEnvHdl =
		      (pSQLAllocEnv) DLL_PROC (handle,
			  "SQLAllocEnv")) != NULL)
		{
		  ret = allocEnvHdl (&drv_henv);
		  if (ret == SQL_ERROR)
		    goto nodriverver;
		}
	      else
		goto nodriverver;

	      if ((allocConnectHdl =
		      (pSQLAllocConnect) DLL_PROC (handle,
			  "SQLAllocConnect")) != NULL)
		{
		  ret = allocConnectHdl (drv_henv, &drv_hdbc);
		  if (ret == SQL_ERROR)
		    goto nodriverver;
		}
	      else
		goto nodriverver;
	    }

	  if ((funcHdl =
		  (pSQLGetInfoFunc) DLL_PROC (handle, "SQLGetInfo")) != NULL)
	    {
	      /* Retrieve some information */
	      ret =
		  funcHdl (drv_hdbc, SQL_DRIVER_VER, drvattrs,
		  sizeof (drvattrs), &len);
	      if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
		{
		  unsigned int z;
		  /* Drop the description if one provided */
		  for (z = 0; ((char *) drvattrs)[z]; z++)
		    if (((char *) drvattrs)[z] == ' ')
		      ((char *) drvattrs)[z] = '\0';
		  data[2] = drvattrs;
		}
	      else
		goto nodriverver;
	    }
	  else
	    goto nodriverver;
	}
      else
	{
	nodriverver:
	  data[2] = "##.##";
	}

      if (drv_hdbc || drv_henv)
	{
	  if (allocConnectHdl &&
	      (freeConnectHdl =
		  (pSQLFreeConnect) DLL_PROC (handle,
		      "SQLFreeConnect")) != NULL)
	    {
	      freeConnectHdl (drv_hdbc);
	      drv_hdbc = NULL;
	    }

	  if (allocEnvHdl &&
	      (freeEnvHdl =
		  (pSQLFreeEnv) DLL_PROC (handle, "SQLFreeEnv")) != NULL)
	    {
	      freeEnvHdl (drv_henv);
	      drv_henv = NULL;
	    }
	}

      if ((drv_hdbc || drv_henv) &&
	  (freeHdl =
	      (pSQLFreeHandle) DLL_PROC (handle, "SQLFreeHandle")) != NULL)
	{
	  if (drv_hdbc)
	    freeHdl (SQL_HANDLE_DBC, drv_hdbc);
	  if (drv_henv)
	    freeHdl (SQL_HANDLE_ENV, drv_henv);
	}

      if (handle)
        DLL_CLOSE (handle);

      /* Get the size of the driver */
      if (!stat (driver, &_stat))
	{
	  sprintf (size, "%d Kb", (int) (_stat.st_size / 1024));
	  data[3] = size;
	}
      else
	data[3] = "-";

      gtk_clist_append (GTK_CLIST (widget), data);

    skip:
      ret = SQLDrivers (henv, SQL_FETCH_NEXT, drvdesc,
	  sizeof (drvdesc) / sizeof (SQLTCHAR), &len, drvattrs,
	  sizeof (drvattrs) / sizeof (SQLTCHAR), &len1);
      if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO
	  && ret != SQL_NO_DATA)
	{
	  _iodbcdm_nativeerrorbox (dlg, henv, SQL_NULL_HANDLE,
	      SQL_NULL_HANDLE);
	  goto error;
	}
    }

error:
  /* Clean all that */
  SQLFreeHandle (SQL_HANDLE_ENV, henv);

end:
  if (GTK_CLIST (widget)->rows > 0)
    {
      gtk_clist_columns_autosize (GTK_CLIST (widget));
      gtk_clist_sort (GTK_CLIST (widget));
    }
}