drvconn.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:9k
- /* 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.
- *
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include "psqlodbc.h"
- #include "connection.h"
- #ifndef WIN32
- #include <sys/types.h>
- #include <sys/socket.h>
- #define NEAR
- #else
- #include <winsock.h>
- #include <sqlext.h>
- #endif
- #include <string.h>
- #ifndef WIN32
- #define stricmp(s1,s2) strcasecmp(s1,s2)
- #define strnicmp(s1,s2,n) strncasecmp(s1,s2,n)
- #else
- #include <windows.h>
- #include <windowsx.h>
- #include <odbcinst.h>
- #include "resource.h"
- #endif
- #ifndef TRUE
- #define TRUE (BOOL)1
- #endif
- #ifndef FALSE
- #define FALSE (BOOL)0
- #endif
- #include "dlg_specific.h"
- /* prototypes */
- void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci);
- #ifdef WIN32
- BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
- RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
- extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
- #endif
- 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)
- {
- static char *func = "SQLDriverConnect";
- ConnectionClass *conn = (ConnectionClass *) hdbc;
- ConnInfo *ci;
- #ifdef WIN32
- RETCODE dialog_result;
- #endif
- RETCODE result;
- char connStrIn[MAX_CONNECT_STRING];
- char connStrOut[MAX_CONNECT_STRING];
- int retval;
- char password_required = FALSE;
- int len = 0;
- mylog("%s: entering...n", func);
- if ( ! conn) {
- CC_log_error(func, "", NULL);
- return SQL_INVALID_HANDLE;
- }
- make_string(szConnStrIn, cbConnStrIn, connStrIn);
- mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'n", fDriverCompletion, connStrIn);
- qlog("conn=%u, SQLDriverConnect( in)='%s', fDriverCompletion=%dn", conn, connStrIn, fDriverCompletion);
- ci = &(conn->connInfo);
- // Parse the connect string and fill in conninfo for this hdbc.
- dconn_get_connect_attributes(connStrIn, 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!)
- getDSNinfo(ci, CONN_DONT_OVERWRITE);
- // Fill in any default parameters if they are not there.
- getDSNdefaults(ci);
- #ifdef WIN32
- dialog:
- #endif
- ci->focus_password = password_required;
- switch(fDriverCompletion) {
- #ifdef WIN32
- case SQL_DRIVER_PROMPT:
- dialog_result = dconn_DoDialog(hwnd, ci);
- if(dialog_result != SQL_SUCCESS) {
- return dialog_result;
- }
- break;
- case SQL_DRIVER_COMPLETE_REQUIRED:
- /* Fall through */
- case SQL_DRIVER_COMPLETE:
- /* Password is not a required parameter. */
- if( ci->username[0] == ' ' ||
- ci->server[0] == ' ' ||
- ci->database[0] == ' ' ||
- ci->port[0] == ' ' ||
- password_required) {
- dialog_result = dconn_DoDialog(hwnd, ci);
- if(dialog_result != SQL_SUCCESS) {
- return dialog_result;
- }
- }
- break;
- #else
- case SQL_DRIVER_PROMPT:
- case SQL_DRIVER_COMPLETE:
- case SQL_DRIVER_COMPLETE_REQUIRED:
- #endif
- 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] == ' ' ||
- ci->server[0] == ' ' ||
- ci->database[0] == ' ' ||
- ci->port[0] == ' ') {
- // (password_required && ci->password[0] == ' '))
- return SQL_NO_DATA_FOUND;
- }
- // do the actual connect
- retval = CC_connect(conn, password_required);
- if (retval < 0) { /* need a password */
- if (fDriverCompletion == SQL_DRIVER_NOPROMPT) {
- CC_log_error(func, "Need password but Driver_NoPrompt", conn);
- return SQL_ERROR; /* need a password but not allowed to prompt so error */
- }
- else {
- #ifdef WIN32
- password_required = TRUE;
- goto dialog;
- #else
- return SQL_ERROR; /* until a better solution is found. */
- #endif
- }
- }
- else if (retval == 0) {
- // error msg filled in above
- CC_log_error(func, "Error from CC_Connect", conn);
- return SQL_ERROR;
- }
- /*********************************************/
- /* Create the Output Connection String */
- /*********************************************/
- result = SQL_SUCCESS;
- makeConnectString(connStrOut, ci);
- len = strlen(connStrOut);
- if(szConnStrOut) {
- /* Return the completed string to the caller. The correct method is to
- only construct the connect string if a dialog was put up, otherwise,
- it should just copy the connection input string to the output.
- However, it seems ok to just always construct an output string. There
- are possible bad side effects on working applications (Access) by
- implementing the correct behavior, anyway.
- */
- strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);
- if (len >= cbConnStrOutMax) {
- result = SQL_SUCCESS_WITH_INFO;
- conn->errornumber = CONN_TRUNCATED;
- conn->errormsg = "The buffer was too small for the result.";
- }
- }
- if(pcbConnStrOut)
- *pcbConnStrOut = len;
- mylog("szConnStrOut = '%s'n", szConnStrOut);
- qlog("conn=%u, SQLDriverConnect(out)='%s'n", conn, szConnStrOut);
- mylog("SQLDRiverConnect: returning %dn", result);
- return result;
- }
- #ifdef WIN32
- RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci)
- {
- int dialog_result;
- mylog("dconn_DoDialog: ci = %un", ci);
- if(hwnd) {
- dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
- 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)
- {
- ConnInfo *ci;
- switch (wMsg) {
- case WM_INITDIALOG:
- ci = (ConnInfo *) lParam;
- /* Change the caption for the setup dialog */
- SetWindowText(hdlg, "PostgreSQL Connection");
- SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection");
- /* Hide the DSN and description fields */
- ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
- ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
- ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
- ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
- SetWindowLong(hdlg, DWL_USER, lParam);// Save the ConnInfo for the "OK"
- SetDlgStuff(hdlg, ci);
- if (ci->database[0] == ' ')
- ; /* default focus */
- else if (ci->server[0] == ' ')
- SetFocus(GetDlgItem(hdlg, IDC_SERVER));
- else if (ci->port[0] == ' ')
- SetFocus(GetDlgItem(hdlg, IDC_PORT));
- else if (ci->username[0] == ' ')
- SetFocus(GetDlgItem(hdlg, IDC_USER));
- else if (ci->focus_password)
- SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
- break;
- case WM_COMMAND:
- switch (GET_WM_COMMAND_ID(wParam, lParam)) {
- case IDOK:
- ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
- GetDlgStuff(hdlg, ci);
- case IDCANCEL:
- EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
- return TRUE;
- case IDC_DRIVER:
- DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
- hdlg, driver_optionsProc, (LPARAM) NULL);
- break;
- case IDC_DATASOURCE:
- ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
- DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
- hdlg, ds_optionsProc, (LPARAM) ci);
- break;
- }
- }
- return FALSE;
- }
- #endif /* WIN32 */
- 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 = ' ';
- attribute = pair; // ex. DSN
- value = equals + 1; // ex. 'CEO co1'
- mylog("attribute = '%s', value = '%s'n", attribute, value);
- if( !attribute || !value)
- continue;
- // Copy the appropriate value to the conninfo
- copyAttributes(ci, attribute, value);
- }
- free(our_connect_string);
- }