/* 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 #include #include #include #include #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; }