/* 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 #include #include "psqlodbc.h" #include "connection.h" #include #include #include #include #include #include #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); }