Exemple #1
0
static SQLRETURN
_SQLExecute_ConvParams (SQLHSTMT hstmt, BOOL bOutput)
{
  STMT (pstmt, hstmt);
  CONN (pdbc, pstmt->hdbc);
  ENVR (penv, pdbc->henv);
  PPARM pparm;
  int maxpar;
  int i;
  SQLULEN j;
  SQLULEN cRows = pstmt->paramset_size;

  if (penv->unicode_driver)
    return SQL_SUCCESS;

  if (cRows == 0)
    cRows = 1;

  maxpar = pstmt->st_nparam;

  pparm = pstmt->st_pparam;
  for (i = 0; i < maxpar; i++, pparm++)
    {
      if (pparm->pm_data == NULL)
        continue;

      if (bOutput && (pparm->pm_usage == SQL_PARAM_OUTPUT || pparm->pm_usage == SQL_PARAM_INPUT_OUTPUT))
        {
          if (pparm->pm_c_type_orig != SQL_C_WCHAR)
            continue;

          for (j = 0; j < cRows; j++)
            _ConvParam(pstmt, pparm, j, bOutput);
        }
      else if (!bOutput && (pparm->pm_usage == SQL_PARAM_INPUT || pparm->pm_usage == SQL_PARAM_INPUT_OUTPUT))
        {
          if (pparm->pm_c_type != SQL_C_WCHAR)
            continue;

          for (j = 0; j < cRows; j++)
            _ConvParam(pstmt, pparm, j, bOutput);

          pparm->pm_c_type = SQL_C_CHAR;
        }
    } /* next column */

  return SQL_SUCCESS;

}
Exemple #2
0
SQLRETURN SQL_API
SQLPrepare_Internal (
    SQLHSTMT hstmt,
    SQLPOINTER szSqlStr,
    SQLINTEGER cbSqlStr,
    SQLCHAR waMode)
{
  STMT (pstmt, hstmt);
  CONN (pdbc, pstmt->hdbc);
  ENVR (penv, pdbc->henv);
  HPROC hproc = SQL_NULL_HPROC;
  SQLRETURN retcode = SQL_SUCCESS;
  sqlstcode_t sqlstat = en_00000;
  void * _SqlStr = NULL;

  /* check state */
  if (pstmt->asyn_on == en_NullProc)
    {
      /* not on asyn state */
      switch (pstmt->state)
	{
	case en_stmt_fetched:
	case en_stmt_xfetched:
	  sqlstat = en_24000;
	  break;

	case en_stmt_needdata:
	case en_stmt_mustput:
	case en_stmt_canput:
	  sqlstat = en_S1010;
	  break;

	default:
	  break;
	}
    }
  else if (pstmt->asyn_on != en_Prepare)
    {
      /* asyn on other */
      sqlstat = en_S1010;
    }

  if (sqlstat != en_00000)
    {
      PUSHSQLERR (pstmt->herr, sqlstat);

      return SQL_ERROR;
    }

  if (szSqlStr == NULL)
    {
      PUSHSQLERR (pstmt->herr, en_S1009);

      return SQL_ERROR;
    }

  if (cbSqlStr < 0 && cbSqlStr != SQL_NTS)
    {
      PUSHSQLERR (pstmt->herr, en_S1090);

      return SQL_ERROR;
    }

  if ((penv->unicode_driver && waMode != 'W')
      || (!penv->unicode_driver && waMode == 'W'))
    {
      if (waMode != 'W')
        {
        /* ansi=>unicode*/
          _SqlStr = _iodbcdm_conv_var_A2W(pstmt, 0, (SQLCHAR *) szSqlStr, cbSqlStr);
        }
      else
        {
        /* unicode=>ansi*/
          _SqlStr = _iodbcdm_conv_var_W2A(pstmt, 0, (SQLWCHAR *) szSqlStr, cbSqlStr);
        }
      szSqlStr = _SqlStr;
      cbSqlStr = SQL_NTS;
    }

  CALL_UDRIVER(pstmt->hdbc, pstmt, retcode, hproc, penv->unicode_driver, 
    en_Prepare, (
       pstmt->dhstmt,
       szSqlStr,
       cbSqlStr));

  if (hproc == SQL_NULL_HPROC)
    {
      _iodbcdm_FreeStmtVars(pstmt);
      PUSHSQLERR (pstmt->herr, en_IM001);
      return SQL_ERROR;
    }

  if (retcode != SQL_STILL_EXECUTING)
    _iodbcdm_FreeStmtVars(pstmt);

  /* stmt state transition */
  if (pstmt->asyn_on == en_Prepare)
    {
      switch (retcode)
	{
	case SQL_SUCCESS:
	case SQL_SUCCESS_WITH_INFO:
	case SQL_ERROR:
	  pstmt->asyn_on = en_NullProc;
	   return retcode;

	case SQL_STILL_EXECUTING:
	default:
	   return retcode;
	}
    }

  switch (retcode)
    {
    case SQL_STILL_EXECUTING:
      pstmt->asyn_on = en_Prepare;
      break;

    case SQL_SUCCESS:
    case SQL_SUCCESS_WITH_INFO:
      pstmt->state = en_stmt_prepared;
      pstmt->prep_state = 1;
      break;

    case SQL_ERROR:
      switch (pstmt->state)
	{
	case en_stmt_prepared:
	case en_stmt_executed_with_info:
	case en_stmt_executed:
	  pstmt->state = en_stmt_allocated;
	  pstmt->prep_state = 0;
	  break;

	default:
	  break;
	}

    default:
      break;
    }

  return retcode;
}
Exemple #3
0
static SQLRETURN
SQLBindParameter_Internal (
    SQLHSTMT		  hstmt,
    SQLUSMALLINT	  ipar,
    SQLSMALLINT		  fParamType,
    SQLSMALLINT		  fCType,
    SQLSMALLINT		  fSqlType,
    SQLULEN		  cbColDef,
    SQLSMALLINT		  ibScale,
    SQLPOINTER		  rgbValue,
    SQLLEN		  cbValueMax,
    SQLLEN		* pcbValue)
{
  STMT (pstmt, hstmt);
  CONN (pdbc, pstmt->hdbc);
  ENVR (penv, pdbc->henv);
  HPROC hproc2 = SQL_NULL_HPROC;
  HPROC hproc3 = SQL_NULL_HPROC;
  SQLSMALLINT nCType;
  SQLSMALLINT nSqlType;
  sqlstcode_t sqlstat = en_00000;
  SQLRETURN retcode = SQL_SUCCESS;
  SQLUINTEGER odbc_ver = ((GENV_t *) pdbc->genv)->odbc_ver;
  SQLUINTEGER dodbc_ver = ((ENV_t *) pdbc->henv)->dodbc_ver;
  PPARM newparam;
  TPARM parm;
  int size;

#if (ODBCVER >= 0x0300)
  if (0)
#else
  /* check param */
  if (fSqlType > SQL_TYPE_MAX ||
      (fSqlType < SQL_TYPE_MIN && fSqlType > SQL_TYPE_DRIVER_START))
    /* Note: SQL_TYPE_DRIVER_START is a negative number 
     * So, we use ">" */
#endif
    {
      sqlstat = en_S1004;
    }
  else if (ipar < 1)
    {
      sqlstat = en_S1093;
    }
  else if ((rgbValue == NULL && pcbValue == NULL)
      && fParamType != SQL_PARAM_OUTPUT)
    {
      sqlstat = en_S1009;
      /* This means, I allow output to nowhere
       * (i.e. * junk output result). But I can't  
       * allow input from nowhere. 
       */
    }
/**********
	else if( cbValueMax < 0L && cbValueMax != SQL_SETPARAM_VALUE_MAX )
	{
		sqlstat = en_S1090;
	}
**********/
  else if (fParamType != SQL_PARAM_INPUT
	&& fParamType != SQL_PARAM_OUTPUT
      && fParamType != SQL_PARAM_INPUT_OUTPUT)
    {
      sqlstat = en_S1105;
    }
  else
    {
      switch (fCType)
	{
	case SQL_C_DEFAULT:
	case SQL_C_BINARY:
	case SQL_C_BIT:
	case SQL_C_CHAR:
	case SQL_C_DATE:
	case SQL_C_DOUBLE:
	case SQL_C_FLOAT:
	case SQL_C_LONG:
	case SQL_C_SHORT:
	case SQL_C_SLONG:
	case SQL_C_SSHORT:
	case SQL_C_STINYINT:
	case SQL_C_TIME:
	case SQL_C_TIMESTAMP:
	case SQL_C_TINYINT:
	case SQL_C_ULONG:
	case SQL_C_USHORT:
	case SQL_C_UTINYINT:
#if (ODBCVER >= 0x0300)
	case SQL_C_GUID:
	case SQL_C_INTERVAL_DAY:
	case SQL_C_INTERVAL_DAY_TO_HOUR:
	case SQL_C_INTERVAL_DAY_TO_MINUTE:
	case SQL_C_INTERVAL_DAY_TO_SECOND:
	case SQL_C_INTERVAL_HOUR:
	case SQL_C_INTERVAL_HOUR_TO_MINUTE:
	case SQL_C_INTERVAL_HOUR_TO_SECOND:
	case SQL_C_INTERVAL_MINUTE:
	case SQL_C_INTERVAL_MINUTE_TO_SECOND:
	case SQL_C_INTERVAL_MONTH:
	case SQL_C_INTERVAL_SECOND:
	case SQL_C_INTERVAL_YEAR:
	case SQL_C_INTERVAL_YEAR_TO_MONTH:
	case SQL_C_NUMERIC:
	case SQL_C_SBIGINT:
	case SQL_C_TYPE_DATE:
	case SQL_C_TYPE_TIME:
	case SQL_C_TYPE_TIMESTAMP:
	case SQL_C_UBIGINT:
	case SQL_C_WCHAR:
#endif
	  break;

	default:
	  sqlstat = en_S1003;
	  break;
	}
    }

  if (sqlstat != en_00000)
    {
      PUSHSQLERR (pstmt->herr, sqlstat);

      return SQL_ERROR;
    }

  /* check state */
  if (pstmt->state >= en_stmt_needdata || pstmt->asyn_on != en_NullProc)
    {
      PUSHSQLERR (pstmt->herr, en_S1010);

      retcode = SQL_ERROR;
    }

  /*
   *  Convert C type to ODBC version of driver
   */
  nCType = _iodbcdm_map_c_type (fCType, penv->dodbc_ver);

  /*
   *  Convert SQL type to ODBC version of driver
   */
  nSqlType = _iodbcdm_map_sql_type (fSqlType, penv->dodbc_ver);

  hproc2 = _iodbcdm_getproc (pstmt->hdbc, en_BindParameter);
#if (ODBCVER >=0x0300)
  hproc3 = _iodbcdm_getproc (pstmt->hdbc, en_BindParam);
#endif

  parm.pm_par = ipar;
  parm.pm_c_type = nCType;
  parm.pm_c_type_orig = nCType;
  parm.pm_sql_type = fSqlType;
  parm.pm_precision = cbColDef;
  parm.pm_scale = ibScale;
  parm.pm_data = rgbValue;
  parm.pm_pOctetLength = pcbValue;
  parm.pm_pInd = pcbValue;
  parm.pm_size = size;
  parm.pm_usage = fParamType;
  parm.pm_cbValueMax = cbValueMax;

#if (ODBCVER >=0x0300)
  if (fCType == SQL_C_WCHAR && !penv->unicode_driver 
      && pcbValue && *pcbValue != SQL_DATA_AT_EXEC)
    nCType = SQL_C_CHAR;
#endif

  if (ipar < 1 || ipar > STMT_MAX_PARAM)
    {
      PUSHSQLERR (pstmt->herr, en_S1093);
      return SQL_ERROR;
    }

  if (ipar > pstmt->st_nparam)
    {
      size_t newsize = ipar + 10;
      if (newsize > STMT_MAX_PARAM)
        newsize = STMT_MAX_PARAM;
      if ((newparam = calloc (newsize, sizeof (TPARM))) == NULL)
	{
          PUSHSQLERR (pstmt->herr, en_S1001);
          return SQL_ERROR;
	}
      if (pstmt->st_pparam)
	{
	  memcpy (newparam, pstmt->st_pparam, pstmt->st_nparam * sizeof (TPARM));
	  free (pstmt->st_pparam);
	}
      pstmt->st_pparam = newparam;
      pstmt->st_nparam = (u_short) newsize;
    }

  pstmt->st_pparam[ipar-1] = parm;


  if (odbc_ver == SQL_OV_ODBC2 && 
      (  dodbc_ver == SQL_OV_ODBC2
       || (dodbc_ver == SQL_OV_ODBC3 && hproc2 != SQL_NULL_HPROC)))
    hproc3 = SQL_NULL_HPROC;

#if (ODBCVER >=0x0300)
  if (fParamType == SQL_PARAM_INPUT && hproc3 != SQL_NULL_HPROC)
    {
      CALL_DRIVER (pstmt->hdbc, pstmt, retcode, hproc3,
	      (pstmt->dhstmt, ipar, nCType, nSqlType, cbColDef,
	      ibScale, rgbValue, pcbValue));
    }
  else
#endif
    {
      if (hproc2 == SQL_NULL_HPROC)
        {
          PUSHSQLERR (pstmt->herr, en_IM001);
          return SQL_ERROR;
        }
      CALL_DRIVER (pstmt->hdbc, pstmt, retcode, hproc2,
          (pstmt->dhstmt, ipar, fParamType, nCType, nSqlType, cbColDef,
	  ibScale, rgbValue, cbValueMax, pcbValue));
    }

  return retcode;
}
Exemple #4
0
SQLRETURN SQL_API
SQLSetCursorName_Internal (
    SQLHSTMT hstmt,
    SQLPOINTER szCursor,
    SQLSMALLINT cbCursor,
    SQLCHAR waMode)
{
  STMT (pstmt, hstmt);
  CONN (pdbc, pstmt->hdbc);
  ENVR (penv, pdbc->henv);
  HPROC hproc = SQL_NULL_HPROC;
  SQLRETURN retcode = SQL_SUCCESS;
  sqlstcode_t sqlstat = en_00000;
  void * _Cursor = NULL;

  if (szCursor == NULL)
    {
      PUSHSQLERR (pstmt->herr, en_S1009);

      return SQL_ERROR;
    }

  if (cbCursor < 0 && cbCursor != SQL_NTS)
    {
      PUSHSQLERR (pstmt->herr, en_S1090);

      return SQL_ERROR;
    }

  /* check state */
  if (pstmt->asyn_on != en_NullProc)
    {
      sqlstat = en_S1010;
    }
  else
    {
      switch (pstmt->state)
	{
	case en_stmt_executed_with_info:
	case en_stmt_executed:
	case en_stmt_cursoropen:
	case en_stmt_fetched:
	case en_stmt_xfetched:
	  sqlstat = en_24000;
	  break;

	case en_stmt_needdata:
	case en_stmt_mustput:
	case en_stmt_canput:
	  sqlstat = en_S1010;
	  break;

	default:
	  break;
	}
    }

  if (sqlstat != en_00000)
    {
      PUSHSQLERR (pstmt->herr, sqlstat);

      return SQL_ERROR;
    }

  if ((penv->unicode_driver && waMode != 'W')
      || (!penv->unicode_driver && waMode == 'W'))
    {
      if (waMode != 'W')
        {
        /* ansi=>unicode*/
          _Cursor = dm_SQL_A2W ((SQLCHAR *) szCursor, cbCursor);
        }
      else
        {
        /* unicode=>ansi*/
          _Cursor = dm_SQL_W2A ((SQLWCHAR *) szCursor, cbCursor);
        }
      szCursor = _Cursor;
      cbCursor = SQL_NTS;
    }

  CALL_UDRIVER(pstmt->hdbc, pstmt, retcode, hproc, penv->unicode_driver, 
    en_SetCursorName, (
       pstmt->dhstmt,
       szCursor,
       cbCursor));

  MEM_FREE(_Cursor);

  if (hproc == SQL_NULL_HPROC)
    {
      PUSHSQLERR (pstmt->herr, en_IM001);

      return SQL_ERROR;
    }

  if (SQL_SUCCEEDED (retcode))
    {
      pstmt->cursor_state = en_stmt_cursor_named;
    }

  return retcode;
}
Exemple #5
0
SQLRETURN SQL_API
SQLExecDirect_Internal (SQLHSTMT hstmt,
    SQLPOINTER szSqlStr,
    SQLINTEGER cbSqlStr,
    SQLCHAR waMode)
{
  STMT (pstmt, hstmt);
  CONN (pdbc, pstmt->hdbc);
  ENVR (penv, pdbc->henv);
  HPROC hproc = SQL_NULL_HPROC;
  SQLRETURN retcode = SQL_SUCCESS;
  sqlstcode_t sqlstat = en_00000;
  void * _SqlStr = NULL;

  /* check arguments */
  if (szSqlStr == NULL)
    {
      sqlstat = en_S1009;
    }
  else if (cbSqlStr < 0 && cbSqlStr != SQL_NTS)
    {
      sqlstat = en_S1090;
    }

  if (sqlstat != en_00000)
    {
      PUSHSQLERR (pstmt->herr, sqlstat);

      return SQL_ERROR;
    }

  /* check state */
  if (pstmt->asyn_on == en_NullProc)
    {
      switch (pstmt->state)
	{
	case en_stmt_fetched:
	case en_stmt_xfetched:
	  sqlstat = en_24000;
	  break;

	case en_stmt_needdata:
	case en_stmt_mustput:
	case en_stmt_canput:
	  sqlstat = en_S1010;
	  break;

	default:
	  break;
	}
    }
  else if (pstmt->asyn_on != en_ExecDirect)
    {
      sqlstat = en_S1010;
    }

  if (sqlstat != en_00000)
    {
      PUSHSQLERR (pstmt->herr, sqlstat);

      return SQL_ERROR;
    }

  if ((penv->unicode_driver && waMode != 'W')
      || (!penv->unicode_driver && waMode == 'W'))
    {
      if (waMode != 'W')
        {
        /* ansi=>unicode*/
          _SqlStr = _iodbcdm_conv_var_A2W(pstmt, 0, (SQLCHAR *) szSqlStr, cbSqlStr);
        }
      else
        {
        /* unicode=>ansi*/
          _SqlStr = _iodbcdm_conv_var_W2A(pstmt, 0, (SQLWCHAR *) szSqlStr, cbSqlStr);
        }
      szSqlStr = _SqlStr;
      cbSqlStr = SQL_NTS;
    }

  if ((retcode = _SQLExecute_ConvParams(hstmt, FALSE)) != SQL_SUCCESS)
    return retcode;
  
  CALL_UDRIVER(pstmt->hdbc, pstmt, retcode, hproc, penv->unicode_driver,
    en_ExecDirect, (
       pstmt->dhstmt,
       szSqlStr,
       cbSqlStr));

  if (hproc == SQL_NULL_HPROC)
    {
      _iodbcdm_FreeStmtVars(pstmt);
      PUSHSQLERR (pstmt->herr, en_IM001);
      return SQL_ERROR;
    }

  if (retcode != SQL_STILL_EXECUTING)
    _iodbcdm_FreeStmtVars(pstmt);

  /* stmt state transition */
  if (pstmt->asyn_on == en_ExecDirect)
    {
      switch (retcode)
	{
	case SQL_SUCCESS:
	case SQL_SUCCESS_WITH_INFO:
	case SQL_NEED_DATA:
	case SQL_ERROR:
	  pstmt->asyn_on = en_NullProc;
	  break;

	case SQL_STILL_EXECUTING:
	default:
	  return retcode;
	}
    }


  if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
    retcode = _SQLExecute_ConvParams(hstmt, TRUE);

  if (pstmt->state <= en_stmt_executed)
    {
      switch (retcode)
	{
	case SQL_SUCCESS:
	  _iodbcdm_do_cursoropen (pstmt);
	  pstmt->prep_state = 1;
	  break;

	case SQL_SUCCESS_WITH_INFO:
	  pstmt->state = en_stmt_executed_with_info;
	  pstmt->prep_state = 1;
	  break;

	case SQL_NEED_DATA:
	  pstmt->state = en_stmt_needdata;
	  pstmt->need_on = en_ExecDirect;
	  break;

	case SQL_STILL_EXECUTING:
	  pstmt->asyn_on = en_ExecDirect;
	  break;

	case SQL_ERROR:
	  pstmt->state = en_stmt_allocated;
	  pstmt->cursor_state = en_stmt_cursor_no;
	  pstmt->prep_state = 0;
	  break;

	default:
	  break;
	}
    }

  return retcode;
}
SQLRETURN SQL_API
SQLGetInfo_Internal (
    SQLHDBC		  hdbc,
    SQLUSMALLINT	  fInfoType,
    SQLPOINTER		  rgbInfoValue,
    SQLSMALLINT		  cbInfoValueMax,
    SQLSMALLINT		* pcbInfoValue,
    SQLCHAR		  waMode)
{
  CONN (pdbc, hdbc);
  ENVR (penv, pdbc->henv);
  STMT (pstmt, NULL);
  STMT (tpstmt, NULL);
  HPROC hproc = SQL_NULL_HPROC;
  SQLRETURN retcode = SQL_SUCCESS;
  void * _InfoValue = NULL;
  void * infoValueOut = rgbInfoValue;

  DWORD dword = 0;
  int size = 0, len = 0, ret = 0;
  wchar_t buf[20] = {'\0'};

  if (cbInfoValueMax < 0)
    {
      PUSHSQLERR (pdbc->herr, en_S1090);
      return SQL_ERROR;
    }

#if (ODBCVER < 0x0300)
  if (				/* fInfoType < SQL_INFO_FIRST || */
      (fInfoType > SQL_INFO_LAST
	  && fInfoType < SQL_INFO_DRIVER_START))
    {
      PUSHSQLERR (pdbc->herr, en_S1096);
      return SQL_ERROR;
    }
#endif
  if (fInfoType == SQL_ODBC_VER 
#if (ODBCVER >= 0x0300)
  	|| fInfoType == SQL_DM_VER
#endif
	)
    {
#if (ODBCVER >= 0x0300)
      if (fInfoType == SQL_DM_VER)
	sprintf ((char*)buf, "%02d.%02d.%04d.%04d", 
	  	SQL_SPEC_MAJOR, SQL_SPEC_MINOR, IODBC_BUILD / 10000, IODBC_BUILD % 10000);
      else
#endif
	sprintf ((char*)buf, "%02d.%02d.0000", SQL_SPEC_MAJOR, SQL_SPEC_MINOR);
      if(waMode == 'W')
        {
          SQLWCHAR *prov = dm_SQL_U8toW((SQLCHAR *)buf, SQL_NTS);
          if(prov)
            {
              WCSNCPY(buf, prov, sizeof(buf)/sizeof(wchar_t));
              free(prov);
            }
          else 
            buf[0] = L'\0';
        }


      if (rgbInfoValue != NULL  && cbInfoValueMax > 0)
	{
	  len = (waMode != 'W' ? STRLEN (buf) : WCSLEN(buf));

	  if (len > cbInfoValueMax - 1)
	    {
	      len = cbInfoValueMax - 1;
	      PUSHSQLERR (pdbc->herr, en_01004);

	      retcode = SQL_SUCCESS_WITH_INFO;
	    }

	  if (waMode != 'W')
	    {
	      STRNCPY (rgbInfoValue, buf, len);
	      ((char *) rgbInfoValue)[len] = '\0';
	    }
	  else
	    {
	      WCSNCPY (rgbInfoValue, buf, len);
	      ((wchar_t *) rgbInfoValue)[len] = L'\0';
	    }
	}

      if (pcbInfoValue != NULL)
	{
	  *pcbInfoValue = (SWORD) len;
	}

      return retcode;
    }

  if (pdbc->state == en_dbc_allocated || pdbc->state == en_dbc_needdata)
    {
      PUSHSQLERR (pdbc->herr, en_08003);

      return SQL_ERROR;
    }

  switch (fInfoType)
    {
    case SQL_DRIVER_HDBC:
      dword = (DWORD) (pdbc->dhdbc);
      size = sizeof (dword);
      break;

    case SQL_DRIVER_HENV:
      penv = (ENV_t *) (pdbc->henv);
      dword = (DWORD) (penv->dhenv);
      size = sizeof (dword);
      break;

    case SQL_DRIVER_HLIB:
      penv = (ENV_t *) (pdbc->henv);
      dword = (DWORD) (penv->hdll);
      size = sizeof (dword);
      break;

    case SQL_DRIVER_HSTMT:
      if (rgbInfoValue != NULL)
	{
	  pstmt = *((STMT_t **) rgbInfoValue);
	}

      for (tpstmt = (STMT_t *) (pdbc->hstmt);
	  tpstmt != NULL;
	  tpstmt = tpstmt->next)
	{
	  if (tpstmt == pstmt)
	    {
	      break;
	    }
	}

      if (tpstmt == NULL)
	{
	  PUSHSQLERR (pdbc->herr, en_S1009);

	  return SQL_ERROR;
	}

      dword = (DWORD) (pstmt->dhstmt);
      size = sizeof (dword);
      break;

    case SQL_DRIVER_NAME:
    case SQL_DRIVER_ODBC_VER:
    case SQL_DRIVER_VER:
    case SQL_ODBC_INTERFACE_CONFORMANCE:
      break;

    default:
      /* NOTE : this was before the switch, just move here to let some informations going through */
      if (pdbc->state == en_dbc_allocated || pdbc->state == en_dbc_needdata)
	{
	  PUSHSQLERR (pdbc->herr, en_08003);
	  return SQL_ERROR;
	}
    }

  if (size)
    {
      if (rgbInfoValue != NULL)
	{
	  *((DWORD *) rgbInfoValue) = dword;
	}

      if (pcbInfoValue != NULL)
	{
	  *(pcbInfoValue) = (SWORD) size;
	}

      return SQL_SUCCESS;
    }

#if (ODBCVER >= 0x0300)
  /*
   *  This was a temp value in ODBC 2
   */
  if (((ENV_t *) pdbc->henv)->dodbc_ver == SQL_OV_ODBC2 && 
	  fInfoType == SQL_OJ_CAPABILITIES)
      fInfoType = 65003;
#endif /* ODBCVER >= 0x0300 */

  if ((penv->unicode_driver && waMode != 'W') 
      || (!penv->unicode_driver && waMode == 'W'))
    {
      switch(fInfoType)
        {
        case SQL_ACCESSIBLE_PROCEDURES:
        case SQL_ACCESSIBLE_TABLES:
        case SQL_CATALOG_NAME:
        case SQL_CATALOG_NAME_SEPARATOR:
        case SQL_CATALOG_TERM:
        case SQL_COLLATION_SEQ:
        case SQL_COLUMN_ALIAS:
        case SQL_DATA_SOURCE_NAME:
        case SQL_DATA_SOURCE_READ_ONLY:
        case SQL_DATABASE_NAME:
        case SQL_DBMS_NAME:
        case SQL_DBMS_VER:
        case SQL_DESCRIBE_PARAMETER:
        case SQL_DRIVER_NAME:
        case SQL_DRIVER_ODBC_VER:
        case SQL_DRIVER_VER:
        case SQL_ODBC_VER:
        case SQL_EXPRESSIONS_IN_ORDERBY:
        case SQL_IDENTIFIER_QUOTE_CHAR:
        case SQL_INTEGRITY:
        case SQL_KEYWORDS:
        case SQL_LIKE_ESCAPE_CLAUSE:
        case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
        case SQL_MULT_RESULT_SETS:
        case SQL_MULTIPLE_ACTIVE_TXN:
        case SQL_NEED_LONG_DATA_LEN:
        case SQL_ORDER_BY_COLUMNS_IN_SELECT:
        case SQL_PROCEDURE_TERM:
        case SQL_PROCEDURES:
        case SQL_ROW_UPDATES:
        case SQL_SCHEMA_TERM:
        case SQL_SEARCH_PATTERN_ESCAPE:
        case SQL_SERVER_NAME:
        case SQL_SPECIAL_CHARACTERS:
        case SQL_TABLE_TERM:
        case SQL_USER_NAME:
        case SQL_XOPEN_CLI_YEAR:
        case SQL_OUTER_JOINS:
          if (waMode != 'W')  
            {
            /* ansi=>unicode*/
              if ((_InfoValue = malloc(cbInfoValueMax * sizeof(wchar_t) + 1)) == NULL)
	        {
                  PUSHSQLERR (pdbc->herr, en_HY001);
                  return SQL_ERROR;
                }
              cbInfoValueMax *=  sizeof(wchar_t);
            }
          else
            {
            /* unicode=>ansi*/
              if ((_InfoValue = malloc(cbInfoValueMax + 1)) == NULL)
	        {
                  PUSHSQLERR (pdbc->herr, en_HY001);
                  return SQL_ERROR;
                }
              cbInfoValueMax /=  sizeof(wchar_t);
            }
          infoValueOut = _InfoValue;
          break;
        }
    }

  CALL_UDRIVER(hdbc, pdbc, retcode, hproc, penv->unicode_driver, 
    en_GetInfo, (pdbc->dhdbc, fInfoType, infoValueOut, cbInfoValueMax, 
    pcbInfoValue));

  if (hproc == SQL_NULL_HPROC)
    {
      PUSHSQLERR (pdbc->herr, en_IM001);
      return SQL_ERROR;
    }

  if (retcode == SQL_ERROR  && fInfoType == SQL_DRIVER_ODBC_VER)
    {
      if (waMode != 'W')
        {
          STRCPY (buf, "01.00");

          if (rgbInfoValue != NULL && cbInfoValueMax > 0)
	    {
	      len = STRLEN (buf);

	      if (len > cbInfoValueMax - 1)
	        {
	          len = cbInfoValueMax - 1;
                  ret = -1;
	        }
              else
                {
                  ret = 0;
                }

	      STRNCPY (rgbInfoValue, buf, len);
	      ((char *) rgbInfoValue)[len] = '\0';
	    }

          if (pcbInfoValue != NULL)
            *pcbInfoValue = (SWORD) len;
        }
      else
        {
          ret = dm_StrCopyOut2_A2W ((SQLCHAR *) "01.00",  
		(SQLWCHAR *) rgbInfoValue, 
    		cbInfoValueMax / sizeof(wchar_t), pcbInfoValue);
          if (pcbInfoValue)
            *pcbInfoValue = *pcbInfoValue * sizeof(wchar_t);
        }

       if (ret == -1)
         {
           PUSHSQLERR (pdbc->herr, en_01004);
           retcode = SQL_SUCCESS_WITH_INFO;
         }
       else
         {
           retcode = SQL_SUCCESS;
         }

    }
  else if (rgbInfoValue 
          && (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
          &&  ((penv->unicode_driver && waMode != 'W') 
              || (!penv->unicode_driver && waMode == 'W')))
    {
      switch(fInfoType)
        {
        case SQL_ACCESSIBLE_PROCEDURES:
        case SQL_ACCESSIBLE_TABLES:
        case SQL_CATALOG_NAME:
        case SQL_CATALOG_NAME_SEPARATOR:
        case SQL_CATALOG_TERM:
        case SQL_COLLATION_SEQ:
        case SQL_COLUMN_ALIAS:
        case SQL_DATA_SOURCE_NAME:
        case SQL_DATA_SOURCE_READ_ONLY:
        case SQL_DATABASE_NAME:
        case SQL_DBMS_NAME:
        case SQL_DBMS_VER:
        case SQL_DESCRIBE_PARAMETER:
        case SQL_DRIVER_NAME:
        case SQL_DRIVER_ODBC_VER:
        case SQL_DRIVER_VER:
        case SQL_ODBC_VER:
        case SQL_EXPRESSIONS_IN_ORDERBY:
        case SQL_IDENTIFIER_QUOTE_CHAR:
        case SQL_INTEGRITY:
        case SQL_KEYWORDS:
        case SQL_LIKE_ESCAPE_CLAUSE:
        case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
        case SQL_MULT_RESULT_SETS:
        case SQL_MULTIPLE_ACTIVE_TXN:
        case SQL_NEED_LONG_DATA_LEN:
        case SQL_ORDER_BY_COLUMNS_IN_SELECT:
        case SQL_PROCEDURE_TERM:
        case SQL_PROCEDURES:
        case SQL_ROW_UPDATES:
        case SQL_SCHEMA_TERM:
        case SQL_SEARCH_PATTERN_ESCAPE:
        case SQL_SERVER_NAME:
        case SQL_SPECIAL_CHARACTERS:
        case SQL_TABLE_TERM:
        case SQL_USER_NAME:
        case SQL_XOPEN_CLI_YEAR:
        case SQL_OUTER_JOINS:
          if (waMode != 'W')
            {
            /* ansi<=unicode*/
              ret = dm_StrCopyOut2_W2A ((SQLWCHAR *) infoValueOut, 
		(SQLCHAR *) rgbInfoValue, 
                cbInfoValueMax / sizeof(wchar_t), pcbInfoValue);
            }
          else
            {
            /* unicode<=ansi*/
              ret = dm_StrCopyOut2_A2W ((SQLCHAR *) infoValueOut, 
		(SQLWCHAR *) rgbInfoValue, 
		cbInfoValueMax, pcbInfoValue);
              if (pcbInfoValue)
                *pcbInfoValue = *pcbInfoValue * sizeof(wchar_t);
            }

          if (ret == -1)
            {
              PUSHSQLERR (pdbc->herr, en_01004);
              retcode = SQL_SUCCESS_WITH_INFO;
            }
          break;
        }
    }
  MEM_FREE(_InfoValue);
  
  return retcode;
}