diff options
Diffstat (limited to 'src/interfaces/odbc/drvconn.c')
-rw-r--r-- | src/interfaces/odbc/drvconn.c | 327 |
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); +} |