summaryrefslogtreecommitdiff
path: root/src/interfaces/odbc/drvconn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/odbc/drvconn.c')
-rw-r--r--src/interfaces/odbc/drvconn.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/src/interfaces/odbc/drvconn.c b/src/interfaces/odbc/drvconn.c
new file mode 100644
index 00000000000..ee0d8252d72
--- /dev/null
+++ b/src/interfaces/odbc/drvconn.c
@@ -0,0 +1,327 @@
+
+/* Module: drvconn.c
+ *
+ * Description: This module contains only routines related to
+ * implementing SQLDriverConnect.
+ *
+ * Classes: n/a
+ *
+ * API functions: SQLDriverConnect
+ *
+ * Comments: See "notice.txt" for copyright and license information.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "psqlodbc.h"
+#include "connection.h"
+
+#include <winsock.h>
+#include <sqlext.h>
+#include <string.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <odbcinst.h>
+#include "resource.h"
+
+/* prototypes */
+BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
+RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
+void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci);
+
+
+extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
+extern GLOBAL_VALUES globals;
+
+RETCODE SQL_API SQLDriverConnect(
+ HDBC hdbc,
+ HWND hwnd,
+ UCHAR FAR *szConnStrIn,
+ SWORD cbConnStrIn,
+ UCHAR FAR *szConnStrOut,
+ SWORD cbConnStrOutMax,
+ SWORD FAR *pcbConnStrOut,
+ UWORD fDriverCompletion)
+{
+ConnectionClass *conn = (ConnectionClass *) hdbc;
+ConnInfo *ci;
+RETCODE dialog_result;
+char connect_string[MAX_CONNECT_STRING];
+int retval;
+char password_required = FALSE;
+
+ mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, szConnStrIn);
+
+ if ( ! conn)
+ return SQL_INVALID_HANDLE;
+
+ qlog("conn=%u, SQLDriverConnect( in)='%s'\n", conn, szConnStrIn);
+
+ ci = &(conn->connInfo);
+
+ // Parse the connect string and fill in conninfo for this hdbc.
+ dconn_get_connect_attributes(szConnStrIn, ci);
+
+ // If the ConnInfo in the hdbc is missing anything,
+ // this function will fill them in from the registry (assuming
+ // of course there is a DSN given -- if not, it does nothing!)
+ CC_DSN_info(conn, CONN_DONT_OVERWRITE);
+
+ // Fill in any default parameters if they are not there.
+ CC_set_defaults(conn);
+
+dialog:
+ ci->focus_password = password_required;
+
+ switch(fDriverCompletion) {
+ case SQL_DRIVER_PROMPT:
+ dialog_result = dconn_DoDialog(hwnd, ci);
+ if(dialog_result != SQL_SUCCESS) {
+ return dialog_result;
+ }
+ break;
+
+ case SQL_DRIVER_COMPLETE:
+ case SQL_DRIVER_COMPLETE_REQUIRED:
+ /* Password is not a required parameter. */
+ if( ci->username[0] == '\0' ||
+ ci->server[0] == '\0' ||
+ ci->database[0] == '\0' ||
+ ci->port[0] == '\0' ||
+ password_required) {
+
+ dialog_result = dconn_DoDialog(hwnd, ci);
+ if(dialog_result != SQL_SUCCESS) {
+ return dialog_result;
+ }
+ }
+ break;
+ case SQL_DRIVER_NOPROMPT:
+ break;
+ }
+
+ /* Password is not a required parameter unless authentication asks for it.
+ For now, I think its better to just let the application ask over and over until
+ a password is entered (the user can always hit Cancel to get out)
+ */
+ if( ci->username[0] == '\0' ||
+ ci->server[0] == '\0' ||
+ ci->database[0] == '\0' ||
+ ci->port[0] == '\0') {
+// (password_required && ci->password[0] == '\0'))
+
+ return SQL_NO_DATA_FOUND;
+ }
+
+ if(szConnStrOut) {
+
+ // return the completed string to the caller.
+
+ char got_dsn = (ci->dsn[0] != '\0');
+
+ sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;READONLY=%s;PWD=%s;PROTOCOL=%s;CONNSETTINGS=%s",
+ got_dsn ? "DSN" : "DRIVER",
+ got_dsn ? ci->dsn : ci->driver,
+ ci->database,
+ ci->server,
+ ci->port,
+ ci->username,
+ ci->readonly,
+ ci->password,
+ ci->protocol,
+ ci->conn_settings);
+
+ if(pcbConnStrOut) {
+ *pcbConnStrOut = strlen(connect_string);
+ }
+ strncpy_null(szConnStrOut, connect_string, cbConnStrOutMax);
+ }
+
+ mylog("szConnStrOut = '%s'\n", szConnStrOut);
+ qlog("conn=%u, SQLDriverConnect(out)='%s'\n", conn, szConnStrOut);
+
+ // do the actual connect
+ retval = CC_connect(conn, password_required);
+ if (retval < 0) { /* need a password */
+ if (fDriverCompletion == SQL_DRIVER_NOPROMPT)
+ return SQL_ERROR; /* need a password but not allowed to prompt so error */
+ else {
+ password_required = TRUE;
+ goto dialog;
+ }
+ }
+ else if (retval == 0) {
+ // error msg filled in above
+ return SQL_ERROR;
+ }
+
+ mylog("SQLDRiverConnect: returning success\n");
+ return SQL_SUCCESS;
+}
+
+
+RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci)
+{
+int dialog_result;
+
+mylog("dconn_DoDialog: ci = %u\n", ci);
+
+ if(hwnd) {
+ dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DRIVERCONNDIALOG),
+ hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
+ if(!dialog_result || (dialog_result == -1)) {
+ return SQL_NO_DATA_FOUND;
+ } else {
+ return SQL_SUCCESS;
+ }
+ }
+
+ return SQL_ERROR;
+}
+
+
+BOOL FAR PASCAL dconn_FDriverConnectProc(
+ HWND hdlg,
+ UINT wMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+static ConnInfo *ci;
+
+ switch (wMsg) {
+ case WM_INITDIALOG:
+ ci = (ConnInfo *) lParam; // Save the ConnInfo for the "OK"
+
+ SetDlgItemText(hdlg, SERVER_EDIT, ci->server);
+ SetDlgItemText(hdlg, DATABASE_EDIT, ci->database);
+ SetDlgItemText(hdlg, USERNAME_EDIT, ci->username);
+ SetDlgItemText(hdlg, PASSWORD_EDIT, ci->password);
+ SetDlgItemText(hdlg, PORT_EDIT, ci->port);
+ CheckDlgButton(hdlg, READONLY_EDIT, atoi(ci->readonly));
+
+ CheckDlgButton(hdlg, PG62_EDIT, PROTOCOL_62(ci));
+
+ /* The driver connect dialog box allows manipulating this global variable */
+ CheckDlgButton(hdlg, COMMLOG_EDIT, globals.commlog);
+
+ if (ci->database[0] == '\0')
+ ; /* default focus */
+ else if (ci->server[0] == '\0')
+ SetFocus(GetDlgItem(hdlg, SERVER_EDIT));
+ else if (ci->port[0] == '\0')
+ SetFocus(GetDlgItem(hdlg, PORT_EDIT));
+ else if (ci->username[0] == '\0')
+ SetFocus(GetDlgItem(hdlg, USERNAME_EDIT));
+ else if (ci->focus_password)
+ SetFocus(GetDlgItem(hdlg, PASSWORD_EDIT));
+
+ break;
+
+ case WM_COMMAND:
+ switch (GET_WM_COMMAND_ID(wParam, lParam)) {
+ case IDOK:
+
+ GetDlgItemText(hdlg, SERVER_EDIT, ci->server, sizeof(ci->server));
+ GetDlgItemText(hdlg, DATABASE_EDIT, ci->database, sizeof(ci->database));
+ GetDlgItemText(hdlg, USERNAME_EDIT, ci->username, sizeof(ci->username));
+ GetDlgItemText(hdlg, PASSWORD_EDIT, ci->password, sizeof(ci->password));
+ GetDlgItemText(hdlg, PORT_EDIT, ci->port, sizeof(ci->port));
+
+ sprintf(ci->readonly, "%d", IsDlgButtonChecked(hdlg, READONLY_EDIT));
+
+ if (IsDlgButtonChecked(hdlg, PG62_EDIT))
+ strcpy(ci->protocol, PG62);
+ else
+ ci->protocol[0] = '\0';
+
+ /* The driver connect dialog box allows manipulating this global variable */
+ globals.commlog = IsDlgButtonChecked(hdlg, COMMLOG_EDIT);
+ updateGlobals();
+
+ case IDCANCEL:
+ EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+
+void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
+{
+char *our_connect_string;
+char *pair, *attribute, *value, *equals;
+char *strtok_arg;
+
+ memset(ci, 0, sizeof(ConnInfo));
+
+ our_connect_string = strdup(connect_string);
+ strtok_arg = our_connect_string;
+
+ mylog("our_connect_string = '%s'\n", our_connect_string);
+
+ while(1) {
+ pair = strtok(strtok_arg, ";");
+ if(strtok_arg) {
+ strtok_arg = 0;
+ }
+ if(!pair) {
+ break;
+ }
+
+ equals = strchr(pair, '=');
+ if ( ! equals)
+ continue;
+
+ *equals = '\0';
+ attribute = pair; // ex. DSN
+ value = equals + 1; // ex. 'CEO co1'
+
+ mylog("attribute = '%s', value = '%s'\n", attribute, value);
+
+ if( !attribute || !value)
+ continue;
+
+ /*********************************************************/
+ /* PARSE ATTRIBUTES */
+ /*********************************************************/
+ if(stricmp(attribute, "DSN") == 0)
+ strcpy(ci->dsn, value);
+
+ else if(stricmp(attribute, "driver") == 0)
+ strcpy(ci->driver, value);
+
+ else if(stricmp(attribute, "uid") == 0)
+ strcpy(ci->username, value);
+
+ else if(stricmp(attribute, "pwd") == 0)
+ strcpy(ci->password, value);
+
+ else if ((stricmp(attribute, "server") == 0) ||
+ (stricmp(attribute, "servername") == 0))
+ strcpy(ci->server, value);
+
+ else if(stricmp(attribute, "port") == 0)
+ strcpy(ci->port, value);
+
+ else if(stricmp(attribute, "database") == 0)
+ strcpy(ci->database, value);
+
+ else if (stricmp(attribute, "readonly") == 0)
+ strcpy(ci->readonly, value);
+
+ else if (stricmp(attribute, "protocol") == 0)
+ strcpy(ci->protocol, value);
+
+ else if (stricmp(attribute, "connsettings") == 0)
+ strcpy(ci->conn_settings, value);
+
+ }
+
+
+ free(our_connect_string);
+}