+RETCODE SQL_API
+SQLDriverConnect (
+ HDBC hdbc,
+ SQLHWND hwnd,
+ UCHAR FAR * szConnStrIn,
+ SWORD cbConnStrIn,
+ UCHAR FAR * szConnStrOut,
+ SWORD cbConnStrOutMax,
+ SWORD FAR * pcbConnStrOut,
+ UWORD fDriverCompletion)
+{
+ DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
+ HDLL hdll;
+ char FAR *drv;
+ char drvbuf[1024];
+ char FAR *dsn;
+ char dsnbuf[SQL_MAX_DSN_LENGTH + 1];
+ UCHAR cnstr2drv[1024];
+
+ HPROC hproc;
+ HPROC dialproc;
+
+ int sqlstat = en_00000;
+ RETCODE retcode = SQL_SUCCESS;
+ RETCODE setopterr = SQL_SUCCESS;
+
+ if (hdbc == SQL_NULL_HDBC)
+ {
+ return SQL_INVALID_HANDLE;
+ }
+
+ /* check arguments */
+ if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS)
+ || cbConnStrOutMax < 0)
+ {
+ PUSHSQLERR (pdbc->herr, en_S1090);
+
+ return SQL_ERROR;
+ }
+
+ /* check state */
+ if (pdbc->state != en_dbc_allocated)
+ {
+ PUSHSQLERR (pdbc->herr, en_08002);
+
+ return SQL_ERROR;
+ }
+
+ drv = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
+ "DRIVER", drvbuf, sizeof (drvbuf));
+
+ dsn = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
+ "DSN", dsnbuf, sizeof (dsnbuf));
+
+ switch (fDriverCompletion)
+ {
+ case SQL_DRIVER_NOPROMPT:
+ break;
+
+ case SQL_DRIVER_COMPLETE:
+ case SQL_DRIVER_COMPLETE_REQUIRED:
+ if (dsn != NULL || drv != NULL)
+ {
+ break;
+ }
+ /* fall to next case */
+ case SQL_DRIVER_PROMPT:
+ /* Get data source dialog box function from
+ * current executable */
+ hdll = _iodbcdm_dllopen ((char FAR *) NULL);
+ dialproc = _iodbcdm_dllproc (hdll,
+ "_iodbcdm_drvconn_dialbox");
+
+ if (dialproc == SQL_NULL_HPROC)
+ {
+ sqlstat = en_IM008;
+ break;
+ }
+
+ retcode = dialproc (
+ hwnd, /* window or display handle */
+ dsnbuf, /* input/output dsn buf */
+ sizeof (dsnbuf), /* buf size */
+ &sqlstat); /* error code */
+
+ if (retcode != SQL_SUCCESS)
+ {
+ break;
+ }
+
+ if (cbConnStrIn == SQL_NTS)
+ {
+ cbConnStrIn = STRLEN (szConnStrIn);
+ }
+
+ dsn = dsnbuf;
+
+ if (dsn[0] == '\0')
+ {
+ dsn = "default";
+ }
+
+ if (cbConnStrIn > sizeof (cnstr2drv)
+ - STRLEN (dsn) - STRLEN ("DSN=;") - 1)
+ {
+ sqlstat = en_S1001; /* a lazy way to avoid
+ * using heap memory */
+ break;
+ }
+
+ sprintf ((char*)cnstr2drv, "DSN=%s;", dsn);
+ cbConnStrIn += STRLEN (cnstr2drv);
+ STRNCAT (cnstr2drv, szConnStrIn, cbConnStrIn);
+ szConnStrIn = cnstr2drv;
+ break;
+
+ default:
+ sqlstat = en_S1110;
+ break;
+ }
+
+ if (sqlstat != en_00000)
+ {
+ PUSHSQLERR (pdbc->herr, sqlstat);
+
+ return SQL_ERROR;
+ }
+
+ if (dsn == NULL || dsn[0] == '\0')
+ {
+ dsn = "default";
+ }
+ else
+ /* if you want tracing, you must use a DSN */
+ {
+ setopterr |= _iodbcdm_settracing (hdbc,
+ (char *) dsn, SQL_NTS);
+ }
+
+ if (drv == NULL || drv[0] == '\0')
+ {
+ drv = _iodbcdm_getkeyvalbydsn (dsn, SQL_NTS, "Driver",
+ drvbuf, sizeof (drvbuf));
+ }
+
+ if (drv == NULL)
+ {
+ PUSHSQLERR (pdbc->herr, en_IM002);
+
+ return SQL_ERROR;
+ }
+
+ retcode = _iodbcdm_driverload (drv, hdbc);
+
+ switch (retcode)
+ {
+ case SQL_SUCCESS:
+ break;
+
+ case SQL_SUCCESS_WITH_INFO:
+ setopterr = SQL_ERROR;
+ /* unsuccessed in calling driver's
+ * SQLSetConnectOption() to set login
+ * timeout.
+ */
+ break;
+
+ default:
+ return retcode;
+ }
+
+ hproc = _iodbcdm_getproc (hdbc, en_DriverConnect);
+
+ if (hproc == SQL_NULL_HPROC)
+ {
+ _iodbcdm_driverunload (hdbc);
+
+ PUSHSQLERR (pdbc->herr, en_IM001);
+
+ return SQL_ERROR;
+ }
+
+ CALL_DRIVER (hdbc, retcode, hproc, en_DriverConnect, (
+ pdbc->dhdbc, hwnd,
+ szConnStrIn, cbConnStrIn,
+ szConnStrOut, cbConnStrOutMax,
+ pcbConnStrOut, fDriverCompletion))
+
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+ {
+ /* don't unload driver here for retrive
+ * error message from driver */