コード例 #1
0
ファイル: drvconn.c プロジェクト: greenplum-db/gpclients
RETCODE		SQL_API
PGAPI_DriverConnect(
					HDBC hdbc,
					HWND hwnd,
					const SQLCHAR FAR * szConnStrIn,
					SQLSMALLINT cbConnStrIn,
					SQLCHAR FAR * szConnStrOut,
					SQLSMALLINT cbConnStrOutMax,
					SQLSMALLINT FAR * pcbConnStrOut,
					SQLUSMALLINT fDriverCompletion)
{
	CSTR func = "PGAPI_DriverConnect";
	ConnectionClass *conn = (ConnectionClass *) hdbc;
	ConnInfo   *ci;

#ifdef WIN32
	RETCODE		dialog_result;
#endif
	BOOL		paramRequired, didUI = FALSE;
	RETCODE		result;
	char		*connStrIn = NULL;
	char		connStrOut[MAX_CONNECT_STRING];
	int			retval;
	char		salt[5];
	char		password_required = AUTH_REQ_OK;
	ssize_t		len = 0;
	SQLSMALLINT	lenStrout;


	mylog("%s: entering...\n", func);

	if (!conn)
	{
		CC_log_error(func, "", NULL);
		return SQL_INVALID_HANDLE;
	}

	connStrIn = make_string(szConnStrIn, cbConnStrIn, NULL, 0);

#ifdef	FORCE_PASSWORD_DISPLAY
	mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn);
	qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion);
#else
	if (get_qlog() || get_mylog())
	{
		char	*hide_str = hide_password(connStrIn);

		mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, NULL_IF_NULL(hide_str));
		qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, NULL_IF_NULL(hide_str), fDriverCompletion);
		if (hide_str)
			free(hide_str);
	}
#endif	/* FORCE_PASSWORD_DISPLAY */

	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);
	dconn_get_common_attributes(connStrIn, ci);
	logs_on_off(1, ci->drivers.debug, ci->drivers.commlog);
	if (connStrIn)
	{
		free(connStrIn);
		connStrIn = NULL;
	}

	/* Fill in any default parameters if they are not there. */
	getDSNdefaults(ci);
	/* initialize pg_version */
	CC_initialize_pg_version(conn);
	memset(salt, 0, sizeof(salt));

#ifdef WIN32
dialog:
#endif
	ci->focus_password = password_required;

inolog("DriverCompletion=%d\n", fDriverCompletion);
	switch (fDriverCompletion)
	{
#ifdef WIN32
		case SQL_DRIVER_PROMPT:
			dialog_result = dconn_DoDialog(hwnd, ci);
			didUI = TRUE;
			if (dialog_result != SQL_SUCCESS)
				return dialog_result;
			break;

		case SQL_DRIVER_COMPLETE_REQUIRED:

			/* Fall through */

		case SQL_DRIVER_COMPLETE:

			paramRequired = password_required;
			/* Password is not a required parameter. */
			if (ci->database[0] == '\0')
				paramRequired = TRUE;
			else if (ci->port[0] == '\0')
				paramRequired = TRUE;
#ifdef	WIN32
			else if (ci->server[0] == '\0')
				paramRequired = TRUE;
#endif /* WIN32 */
			if (paramRequired)
			{
				dialog_result = dconn_DoDialog(hwnd, ci);
				didUI = TRUE;
				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 it's better to just let the application ask
	 * over and over until a password is entered (the user can always hit
	 * Cancel to get out)
	 */
	paramRequired = FALSE;
	if (ci->database[0] == '\0')
		paramRequired = TRUE;
	else if (ci->port[0] == '\0')
		paramRequired = TRUE;
#ifdef	WIN32
	else if (ci->server[0] == '\0')
		paramRequired = TRUE;
#endif /* WIN32 */
	if (paramRequired)
	{
		if (didUI)
			return SQL_NO_DATA_FOUND;
		CC_set_error(conn, CONN_OPENDB_ERROR, "connction string lacks some options", func);
		return SQL_ERROR;
	}

inolog("before CC_connect\n");
	/* do the actual connect */
	retval = CC_connect(conn, password_required, salt);
	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 = -retval;
			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;

	lenStrout = cbConnStrOutMax;
	if (conn->ms_jet && lenStrout > 255)
		lenStrout = 255;
	makeConnectString(connStrOut, ci, lenStrout);
	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);*/
		strncpy(szConnStrOut, connStrOut, cbConnStrOutMax);

		if (len >= cbConnStrOutMax)
		{
			int			clen;

			for (clen = cbConnStrOutMax - 1; clen >= 0 && szConnStrOut[clen] != ';'; clen--)
				szConnStrOut[clen] = '\0';
			result = SQL_SUCCESS_WITH_INFO;
			CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the ConnStrOut.", func);
		}
	}

	if (pcbConnStrOut)
		*pcbConnStrOut = (SQLSMALLINT) len;

#ifdef	FORCE_PASSWORD_DISPLAY
	if (cbConnStrOutMax > 0)
	{
		mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(szConnStrOut), len, cbConnStrOutMax);
		qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(szConnStrOut));
	}
#else
	if (get_qlog() || get_mylog())
	{
		char	*hide_str = NULL;

		if (cbConnStrOutMax > 0)
			hide_str = hide_password(szConnStrOut);
		mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(hide_str), len, cbConnStrOutMax);
		qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(hide_str));
		if (hide_str)
			free(hide_str);
	}
#endif /* FORCE_PASSWORD_DISPLAY */

	if (connStrIn)
		free(connStrIn);
	mylog("PGAPI_DriverConnect: returning %d\n", result);
	return result;
}
コード例 #2
0
ファイル: setup.c プロジェクト: hiinoue/psqlodbc
void
test_connection(HANDLE hwnd, ConnInfo *ci, BOOL withDTC)
{
	int		errnum;
	char		out_conn[MAX_CONNECT_STRING_LEN];
	SQLRETURN	ret;
	SQLHENV		env = SQL_NULL_HANDLE;
	SQLHDBC		conn = SQL_NULL_HANDLE;
	SQLSMALLINT	str_len;
	char		dsn_1st;
	BOOL		connected = FALSE;
#ifdef	UNICODE_SUPPORT
	SQLWCHAR	wout_conn[MAX_CONNECT_STRING_LEN];
	SQLWCHAR	szMsg[SQL_MAX_MESSAGE_LENGTH];
	const SQLWCHAR	*ermsg = NULL;
	SQLWCHAR	*conn_str;
#else
	SQLCHAR		szMsg[SQL_MAX_MESSAGE_LENGTH];
	const SQLCHAR	*ermsg = NULL;
	SQLCHAR		*conn_str;
#endif	/* UNICODE_SUPPORT */

	dsn_1st = ci->dsn[0];
	ci->dsn[0] = '\0';
	makeConnectString(out_conn, ci, sizeof(out_conn));
mylog("conn_string=%s\n", out_conn);
#ifdef	UNICODE_SUPPORT
	msgtowstr(out_conn, wout_conn, _countof(wout_conn));
	conn_str = wout_conn;
#else
	conn_str = out_conn;
#endif /* UNICODE_SUPPORT */
	ci->dsn[0] = dsn_1st;
	if (!SQL_SUCCEEDED(ret = SQLALLOCHANDLEFUNC(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env)))
	{
		ermsg = _T("SQLAllocHandle for env error");
		goto cleanup;
	}
	if (!SQL_SUCCEEDED(ret = SQLSETENVATTRFUNC(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0)))
	{
		snprintf(szMsg, _countof(szMsg), _T("SQLAllocHandle for env error=%d"), ret);
		goto cleanup;
	}
	if (!SQL_SUCCEEDED(ret = SQLALLOCHANDLEFUNC(SQL_HANDLE_DBC, env, &conn)))
	{
		SQLGETDIAGRECFUNC(SQL_HANDLE_ENV, env, 1, NULL, &errnum, szMsg, _countof(szMsg), &str_len);
		ermsg = szMsg;
		goto cleanup;
	}
	if (!SQL_SUCCEEDED(ret = SQLDRIVERCONNECTFUNC(conn, hwnd, conn_str, SQL_NTS, NULL, MAX_CONNECT_STRING_LEN, &str_len, SQL_DRIVER_NOPROMPT)))
	{
		SQLGETDIAGRECFUNC(SQL_HANDLE_DBC, conn, 1, NULL, &errnum, szMsg, _countof(szMsg), &str_len);
		ermsg = szMsg;
		goto cleanup;
	}
	connected = TRUE;
	ermsg = _T("Connection successful");

	if (withDTC)
	{
#ifdef	_HANDLE_ENLIST_IN_DTC_
		HRESULT	res;
		void *pObj = NULL;

		pObj = CALL_GetTransactionObject(&res);
		if (NULL != pObj)
		{
			SQLRETURN ret = SQLSETCONNECTATTRFUNC(conn, SQL_ATTR_ENLIST_IN_DTC, (SQLPOINTER) pObj, 0);
			if (SQL_SUCCEEDED(ret))
			{
				SQLSETCONNECTATTRFUNC(conn, SQL_ATTR_ENLIST_IN_DTC, SQL_DTC_DONE, 0);
				snprintf(szMsg, _countof(szMsg), _T("%s\nenlistment was successful\n"), ermsg);
				ermsg = szMsg;
			}
			else
			{
				SQLGETDIAGRECFUNC(SQL_HANDLE_DBC, conn, 1, NULL, &errnum, szMsg, _countof(szMsg), &str_len);
				if (szMsg[0] != 0)
				{
					snprintf(szMsg, _countof(szMsg), _T("%s\nMSDTC error:%s"), ermsg, szMsg);
					ermsg = szMsg;
				}
			}
			CALL_ReleaseTransactionObject(pObj);
		}
		else if (FAILED(res))
		{
			snprintf(szMsg, _countof(szMsg), _T("%s\nDistibuted Transaction enlistment error %x"), ermsg, res);
			ermsg = szMsg;
		}
#else	/* _HANDLE_ENLIST_IN_DTC_ */
		snprintf(szMsg, _countof(szMsg), _T("%s\nDistibuted Transaction enlistment not supported by this driver"), ermsg);
		ermsg = szMsg;
#endif
	}

cleanup:
	if (NULL != ermsg && NULL != hwnd)
	{
		MESSAGEBOXFUNC(hwnd, ermsg, _T("Connection Test"), MB_ICONEXCLAMATION | MB_OK);
	}

#undef _T
#undef snprintf
#define snprintf _snprintf

	if (NULL != conn)
	{
		if (connected)
			SQLDISCONNECTFUNC(conn);
		SQLFREEHANDLEFUNC(SQL_HANDLE_DBC, conn);
	}
	if (env)
		SQLFREEHANDLEFUNC(SQL_HANDLE_ENV, env);

	return;
}