postgresql/src/interfaces/odbc/setup.c

413 lines
13 KiB
C

/* Module: setup.c
*
* Description: This module contains the setup functions for
* adding/modifying a Data Source in the ODBC.INI portion
* of the registry.
*
* Classes: n/a
*
* API functions: ConfigDSN
*
* Comments: See "notice.txt" for copyright and license information.
*
*************************************************************************************/
#include "psqlodbc.h"
#include "connection.h"
#include <windows.h>
#include <windowsx.h>
#include <odbcinst.h>
#include <string.h>
#include <stdlib.h>
#include "resource.h"
#include "dlg_specific.h"
#define INTFUNC __stdcall
extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
extern GLOBAL_VALUES globals;
/* Constants --------------------------------------------------------------- */
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#ifdef WIN32
#define MAXPGPATH (255+1)
#endif
#define MAXKEYLEN (15+1) /* Max keyword length */
#define MAXDESC (255+1) /* Max description length */
#define MAXDSNAME (32+1) /* Max data source name length */
/* Globals ----------------------------------------------------------------- */
/* NOTE: All these are used by the dialog procedures */
typedef struct tagSETUPDLG {
HWND hwndParent; /* Parent window handle */
LPCSTR lpszDrvr; /* Driver description */
ConnInfo ci;
char szDSN[MAXDSNAME]; /* Original data source name */
BOOL fNewDSN; /* New data source flag */
BOOL fDefault; /* Default data source flag */
} SETUPDLG, FAR *LPSETUPDLG;
/* Prototypes -------------------------------------------------------------- */
void INTFUNC CenterDialog(HWND hdlg);
int CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
void INTFUNC ParseAttributes (LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);
/* ConfigDSN ---------------------------------------------------------------
Description: ODBC Setup entry point
This entry point is called by the ODBC Installer
(see file header for more details)
Input : hwnd ----------- Parent window handle
fRequest ------- Request type (i.e., add, config, or remove)
lpszDriver ----- Driver name
lpszAttributes - data source attribute string
Output : TRUE success, FALSE otherwise
--------------------------------------------------------------------------*/
BOOL CALLBACK ConfigDSN (HWND hwnd,
WORD fRequest,
LPCSTR lpszDriver,
LPCSTR lpszAttributes)
{
BOOL fSuccess; /* Success/fail flag */
GLOBALHANDLE hglbAttr;
LPSETUPDLG lpsetupdlg;
/* Allocate attribute array */
hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG));
if (!hglbAttr)
return FALSE;
lpsetupdlg = (LPSETUPDLG)GlobalLock(hglbAttr);
/* Parse attribute string */
if (lpszAttributes)
ParseAttributes(lpszAttributes, lpsetupdlg);
/* Save original data source name */
if (lpsetupdlg->ci.dsn[0])
lstrcpy(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn);
else
lpsetupdlg->szDSN[0] = '\0';
/* Remove data source */
if (ODBC_REMOVE_DSN == fRequest) {
/* Fail if no data source name was supplied */
if (!lpsetupdlg->ci.dsn[0])
fSuccess = FALSE;
/* Otherwise remove data source from ODBC.INI */
else
fSuccess = SQLRemoveDSNFromIni(lpsetupdlg->ci.dsn);
}
/* Add or Configure data source */
else {
/* Save passed variables for global access (e.g., dialog access) */
lpsetupdlg->hwndParent = hwnd;
lpsetupdlg->lpszDrvr = lpszDriver;
lpsetupdlg->fNewDSN = (ODBC_ADD_DSN == fRequest);
lpsetupdlg->fDefault = !lstrcmpi(lpsetupdlg->ci.dsn, INI_DSN);
/* Display the appropriate dialog (if parent window handle supplied) */
if (hwnd) {
/* Display dialog(s) */
fSuccess = (IDOK == DialogBoxParam(s_hModule,
MAKEINTRESOURCE(DLG_CONFIG),
hwnd,
ConfigDlgProc,
(LONG)(LPSTR)lpsetupdlg));
}
else if (lpsetupdlg->ci.dsn[0])
fSuccess = SetDSNAttributes(hwnd, lpsetupdlg);
else
fSuccess = FALSE;
}
GlobalUnlock(hglbAttr);
GlobalFree(hglbAttr);
return fSuccess;
}
/* CenterDialog ------------------------------------------------------------
Description: Center the dialog over the frame window
Input : hdlg -- Dialog window handle
Output : None
--------------------------------------------------------------------------*/
void INTFUNC CenterDialog(HWND hdlg)
{
HWND hwndFrame;
RECT rcDlg, rcScr, rcFrame;
int cx, cy;
hwndFrame = GetParent(hdlg);
GetWindowRect(hdlg, &rcDlg);
cx = rcDlg.right - rcDlg.left;
cy = rcDlg.bottom - rcDlg.top;
GetClientRect(hwndFrame, &rcFrame);
ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.left));
ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.right));
rcDlg.top = rcFrame.top + (((rcFrame.bottom - rcFrame.top) - cy) >> 1);
rcDlg.left = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1);
rcDlg.bottom = rcDlg.top + cy;
rcDlg.right = rcDlg.left + cx;
GetWindowRect(GetDesktopWindow(), &rcScr);
if (rcDlg.bottom > rcScr.bottom)
{
rcDlg.bottom = rcScr.bottom;
rcDlg.top = rcDlg.bottom - cy;
}
if (rcDlg.right > rcScr.right)
{
rcDlg.right = rcScr.right;
rcDlg.left = rcDlg.right - cx;
}
if (rcDlg.left < 0) rcDlg.left = 0;
if (rcDlg.top < 0) rcDlg.top = 0;
MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
return;
}
/* ConfigDlgProc -----------------------------------------------------------
Description: Manage add data source name dialog
Input : hdlg --- Dialog window handle
wMsg --- Message
wParam - Message parameter
lParam - Message parameter
Output : TRUE if message processed, FALSE otherwise
--------------------------------------------------------------------------*/
int CALLBACK ConfigDlgProc(HWND hdlg,
WORD wMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (wMsg) {
/* Initialize the dialog */
case WM_INITDIALOG:
{
LPSETUPDLG lpsetupdlg = (LPSETUPDLG) lParam;
ConnInfo *ci = &lpsetupdlg->ci;
/* Hide the driver connect message */
ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL), SW_HIDE);
SetWindowLong(hdlg, DWL_USER, lParam);
CenterDialog(hdlg); /* Center dialog */
/* NOTE: Values supplied in the attribute string will always */
/* override settings in ODBC.INI */
/* Get the rest of the common attributes */
getDSNinfo(ci, CONN_DONT_OVERWRITE);
/* Fill in any defaults */
getDSNdefaults(ci);
/* Initialize dialog fields */
SetDlgStuff(hdlg, ci);
if (lpsetupdlg->fDefault) {
EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
}
else
SendDlgItemMessage(hdlg, IDC_DSNAME,
EM_LIMITTEXT, (WPARAM)(MAXDSNAME-1), 0L);
SendDlgItemMessage(hdlg, IDC_DESC,
EM_LIMITTEXT, (WPARAM)(MAXDESC-1), 0L);
return TRUE; /* Focus was not set */
}
/* Process buttons */
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
/* Ensure the OK button is enabled only when a data source name */
/* is entered */
case IDC_DSNAME:
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
{
char szItem[MAXDSNAME]; /* Edit control text */
/* Enable/disable the OK button */
EnableWindow(GetDlgItem(hdlg, IDOK),
GetDlgItemText(hdlg, IDC_DSNAME,
szItem, sizeof(szItem)));
return TRUE;
}
break;
/* Accept results */
case IDOK:
{
LPSETUPDLG lpsetupdlg;
lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
/* Retrieve dialog values */
if (!lpsetupdlg->fDefault)
GetDlgItemText(hdlg, IDC_DSNAME,
lpsetupdlg->ci.dsn,
sizeof(lpsetupdlg->ci.dsn));
/* Get Dialog Values */
GetDlgStuff(hdlg, &lpsetupdlg->ci);
/* Update ODBC.INI */
SetDSNAttributes(hdlg, lpsetupdlg);
}
/* Return to caller */
case IDCANCEL:
EndDialog(hdlg, wParam);
return TRUE;
case IDC_DRIVER:
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
hdlg, driver_optionsProc, (LPARAM) NULL);
return TRUE;
case IDC_DATASOURCE:
{
LPSETUPDLG lpsetupdlg;
lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
hdlg, ds_optionsProc, (LPARAM) &lpsetupdlg->ci);
return TRUE;
}
}
break;
}
/* Message not processed */
return FALSE;
}
/* ParseAttributes ---------------------------------------------------------
Description: Parse attribute string moving values into the aAttr array
Input : lpszAttributes - Pointer to attribute string
Output : None (global aAttr normally updated)
--------------------------------------------------------------------------*/
void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
{
LPCSTR lpsz;
LPCSTR lpszStart;
char aszKey[MAXKEYLEN];
int cbKey;
char value[MAXPGPATH];
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
for (lpsz=lpszAttributes; *lpsz; lpsz++)
{ /* Extract key name (e.g., DSN), it must be terminated by an equals */
lpszStart = lpsz;
for (;; lpsz++)
{
if (!*lpsz)
return; /* No key was found */
else if (*lpsz == '=')
break; /* Valid key found */
}
/* Determine the key's index in the key table (-1 if not found) */
cbKey = lpsz - lpszStart;
if (cbKey < sizeof(aszKey))
{
_fmemcpy(aszKey, lpszStart, cbKey);
aszKey[cbKey] = '\0';
}
/* Locate end of key value */
lpszStart = ++lpsz;
for (; *lpsz; lpsz++);
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
_fmemcpy(value, lpszStart, MIN(lpsz-lpszStart+1, MAXPGPATH));
mylog("aszKey='%s', value='%s'\n", aszKey, value);
/* Copy the appropriate value to the conninfo */
copyAttributes(&lpsetupdlg->ci, aszKey, value);
}
return;
}
/* SetDSNAttributes --------------------------------------------------------
Description: Write data source attributes to ODBC.INI
Input : hwnd - Parent window handle (plus globals)
Output : TRUE if successful, FALSE otherwise
--------------------------------------------------------------------------*/
BOOL INTFUNC SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
{
LPCSTR lpszDSN; /* Pointer to data source name */
lpszDSN = lpsetupdlg->ci.dsn;
/* Validate arguments */
if (lpsetupdlg->fNewDSN && !*lpsetupdlg->ci.dsn)
return FALSE;
/* Write the data source name */
if (!SQLWriteDSNToIni(lpszDSN, lpsetupdlg->lpszDrvr))
{
if (hwndParent)
{
char szBuf[MAXPGPATH];
char szMsg[MAXPGPATH];
LoadString(s_hModule, IDS_BADDSN, szBuf, sizeof(szBuf));
wsprintf(szMsg, szBuf, lpszDSN);
LoadString(s_hModule, IDS_MSGTITLE, szBuf, sizeof(szBuf));
MessageBox(hwndParent, szMsg, szBuf, MB_ICONEXCLAMATION | MB_OK);
}
return FALSE;
}
/* Update ODBC.INI */
writeDSNinfo(&lpsetupdlg->ci);
/* If the data source name has changed, remove the old name */
if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn))
{
SQLRemoveDSNFromIni(lpsetupdlg->szDSN);
}
return TRUE;
}