setup.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:13k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /* Module:          setup.c
  2.  *
  3.  * Description:     This module contains the setup functions for 
  4.  *                  adding/modifying a Data Source in the ODBC.INI portion
  5.  *                  of the registry.
  6.  *
  7.  * Classes:         n/a
  8.  *
  9.  * API functions:   ConfigDSN
  10.  *
  11.  * Comments:        See "notice.txt" for copyright and license information.
  12.  *
  13.  *************************************************************************************/
  14. #include  "psqlodbc.h"
  15. #include  "connection.h"
  16. #include  <windows.h>
  17. #include  <windowsx.h>
  18. #include  <odbcinst.h>
  19. #include  <string.h>
  20. #include  <stdlib.h>
  21. #include  "resource.h"
  22. #include  "dlg_specific.h"
  23. #define INTFUNC  __stdcall
  24. extern HINSTANCE NEAR s_hModule;               /* Saved module handle. */
  25. extern GLOBAL_VALUES globals;
  26. // Constants ---------------------------------------------------------------
  27. #define MIN(x,y)      ((x) < (y) ? (x) : (y))
  28. #define MAXPATHLEN      (255+1)           // Max path length
  29. #define MAXKEYLEN       (15+1)            // Max keyword length
  30. #define MAXDESC         (255+1)           // Max description length
  31. #define MAXDSNAME       (32+1)            // Max data source name length
  32. // Globals -----------------------------------------------------------------
  33. // NOTE:  All these are used by the dialog procedures
  34. typedef struct tagSETUPDLG {
  35.         HWND       hwndParent;                   // Parent window handle
  36.         LPCSTR     lpszDrvr;                     // Driver description
  37. ConnInfo   ci;
  38.         char       szDSN[MAXDSNAME];             // Original data source name
  39.         BOOL       fNewDSN;                      // New data source flag
  40.         BOOL       fDefault;                     // Default data source flag
  41. } SETUPDLG, FAR *LPSETUPDLG;
  42. // Prototypes --------------------------------------------------------------
  43. void INTFUNC CenterDialog(HWND hdlg);
  44. int  CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
  45. void INTFUNC ParseAttributes (LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
  46. BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);
  47. /* ConfigDSN ---------------------------------------------------------------
  48.   Description:  ODBC Setup entry point
  49.                 This entry point is called by the ODBC Installer
  50.                 (see file header for more details)
  51.   Input      :  hwnd ----------- Parent window handle
  52.                 fRequest ------- Request type (i.e., add, config, or remove)
  53.                 lpszDriver ----- Driver name
  54.                 lpszAttributes - data source attribute string
  55.   Output     :  TRUE success, FALSE otherwise
  56. --------------------------------------------------------------------------*/
  57. BOOL CALLBACK ConfigDSN (HWND    hwnd,
  58.                          WORD    fRequest,
  59.                          LPCSTR  lpszDriver,
  60.                          LPCSTR  lpszAttributes)
  61. {
  62. BOOL  fSuccess;                                            // Success/fail flag
  63. GLOBALHANDLE hglbAttr;
  64. LPSETUPDLG lpsetupdlg;
  65.         
  66.         // Allocate attribute array
  67.         hglbAttr = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(SETUPDLG));
  68.         if (!hglbAttr)
  69.                 return FALSE;
  70.         lpsetupdlg = (LPSETUPDLG)GlobalLock(hglbAttr);
  71.         // Parse attribute string
  72.         if (lpszAttributes)
  73.                 ParseAttributes(lpszAttributes, lpsetupdlg);
  74.         // Save original data source name
  75.         if (lpsetupdlg->ci.dsn[0])
  76.                 lstrcpy(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn);
  77.         else
  78.                 lpsetupdlg->szDSN[0] = '';
  79.         // Remove data source
  80.         if (ODBC_REMOVE_DSN == fRequest) {
  81.                 // Fail if no data source name was supplied
  82.                 if (!lpsetupdlg->ci.dsn[0])
  83.                         fSuccess = FALSE;
  84.                 // Otherwise remove data source from ODBC.INI
  85.                 else
  86.                         fSuccess = SQLRemoveDSNFromIni(lpsetupdlg->ci.dsn);
  87.         }
  88.         // Add or Configure data source
  89.         else {
  90.                 // Save passed variables for global access (e.g., dialog access)
  91.                 lpsetupdlg->hwndParent = hwnd;
  92.                 lpsetupdlg->lpszDrvr     = lpszDriver;
  93.                 lpsetupdlg->fNewDSN      = (ODBC_ADD_DSN == fRequest);
  94.                 lpsetupdlg->fDefault     = !lstrcmpi(lpsetupdlg->ci.dsn, INI_DSN);
  95.                 // Display the appropriate dialog (if parent window handle supplied)
  96.                 if (hwnd) {
  97.                         // Display dialog(s)
  98.                           fSuccess = (IDOK == DialogBoxParam(s_hModule,
  99.                                                                 MAKEINTRESOURCE(DLG_CONFIG),
  100.                                                                 hwnd,
  101.                                                                 ConfigDlgProc,
  102.                                                                 (LONG)(LPSTR)lpsetupdlg));
  103.                 }
  104.                 else if (lpsetupdlg->ci.dsn[0])
  105.                         fSuccess = SetDSNAttributes(hwnd, lpsetupdlg);
  106.                 else
  107.                         fSuccess = FALSE;
  108.         }
  109.         GlobalUnlock(hglbAttr);
  110.         GlobalFree(hglbAttr);
  111.         return fSuccess;
  112. }
  113. /* CenterDialog ------------------------------------------------------------
  114.         Description:  Center the dialog over the frame window
  115.         Input      :  hdlg -- Dialog window handle
  116.         Output     :  None
  117. --------------------------------------------------------------------------*/
  118. void INTFUNC CenterDialog(HWND hdlg)
  119. {
  120.         HWND    hwndFrame;
  121.         RECT    rcDlg, rcScr, rcFrame;
  122.         int             cx, cy;
  123.         hwndFrame = GetParent(hdlg);
  124.         GetWindowRect(hdlg, &rcDlg);
  125.         cx = rcDlg.right  - rcDlg.left;
  126.         cy = rcDlg.bottom - rcDlg.top;
  127.         GetClientRect(hwndFrame, &rcFrame);
  128.         ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.left));
  129.         ClientToScreen(hwndFrame, (LPPOINT)(&rcFrame.right));
  130.         rcDlg.top    = rcFrame.top  + (((rcFrame.bottom - rcFrame.top) - cy) >> 1);
  131.         rcDlg.left   = rcFrame.left + (((rcFrame.right - rcFrame.left) - cx) >> 1);
  132.         rcDlg.bottom = rcDlg.top  + cy;
  133.         rcDlg.right  = rcDlg.left + cx;
  134.         GetWindowRect(GetDesktopWindow(), &rcScr);
  135.         if (rcDlg.bottom > rcScr.bottom)
  136.         {
  137.                 rcDlg.bottom = rcScr.bottom;
  138.                 rcDlg.top    = rcDlg.bottom - cy;
  139.         }
  140.         if (rcDlg.right  > rcScr.right)
  141.         {
  142.                 rcDlg.right = rcScr.right;
  143.                 rcDlg.left  = rcDlg.right - cx;
  144.         }
  145.         if (rcDlg.left < 0) rcDlg.left = 0;
  146.         if (rcDlg.top  < 0) rcDlg.top  = 0;
  147.         MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
  148.         return;
  149. }
  150. /* ConfigDlgProc -----------------------------------------------------------
  151.   Description:  Manage add data source name dialog
  152.   Input      :  hdlg --- Dialog window handle
  153.                 wMsg --- Message
  154.                 wParam - Message parameter
  155.                 lParam - Message parameter
  156.   Output     :  TRUE if message processed, FALSE otherwise
  157. --------------------------------------------------------------------------*/
  158. int CALLBACK ConfigDlgProc(HWND   hdlg,
  159.                            WORD   wMsg,
  160.                            WPARAM wParam,
  161.                            LPARAM lParam)
  162. {
  163. switch (wMsg) {
  164. // Initialize the dialog
  165. case WM_INITDIALOG:
  166. {
  167. LPSETUPDLG lpsetupdlg = (LPSETUPDLG) lParam;
  168. ConnInfo *ci = &lpsetupdlg->ci;
  169. /* Hide the driver connect message */
  170. ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL), SW_HIDE);
  171. SetWindowLong(hdlg, DWL_USER, lParam);
  172. CenterDialog(hdlg);                             // Center dialog
  173. // NOTE: Values supplied in the attribute string will always
  174. //       override settings in ODBC.INI
  175. // Get the rest of the common attributes
  176. getDSNinfo(ci, CONN_DONT_OVERWRITE);
  177. // Fill in any defaults
  178. getDSNdefaults(ci);
  179. // Initialize dialog fields
  180. SetDlgStuff(hdlg, ci);
  181. if (lpsetupdlg->fDefault) {
  182. EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
  183. EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
  184. }
  185. else
  186. SendDlgItemMessage(hdlg, IDC_DSNAME,
  187. EM_LIMITTEXT, (WPARAM)(MAXDSNAME-1), 0L);
  188. SendDlgItemMessage(hdlg, IDC_DESC,
  189. EM_LIMITTEXT, (WPARAM)(MAXDESC-1), 0L);
  190. return TRUE;                                            // Focus was not set
  191.     }
  192. // Process buttons
  193. case WM_COMMAND:
  194. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  195. // Ensure the OK button is enabled only when a data source name
  196. // is entered
  197. case IDC_DSNAME:
  198. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  199. {
  200. char    szItem[MAXDSNAME];              // Edit control text
  201. // Enable/disable the OK button
  202. EnableWindow(GetDlgItem(hdlg, IDOK),
  203. GetDlgItemText(hdlg, IDC_DSNAME,
  204. szItem, sizeof(szItem)));
  205. return TRUE;
  206. }
  207. break;
  208. // Accept results
  209. case IDOK:
  210. {
  211. LPSETUPDLG lpsetupdlg;
  212. lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
  213. // Retrieve dialog values
  214. if (!lpsetupdlg->fDefault)
  215. GetDlgItemText(hdlg, IDC_DSNAME,
  216. lpsetupdlg->ci.dsn,
  217. sizeof(lpsetupdlg->ci.dsn));
  218. // Get Dialog Values
  219. GetDlgStuff(hdlg, &lpsetupdlg->ci);
  220. // Update ODBC.INI
  221. SetDSNAttributes(hdlg, lpsetupdlg);
  222.         }
  223. // Return to caller
  224. case IDCANCEL:
  225. EndDialog(hdlg, wParam);
  226. return TRUE;
  227. case IDC_DRIVER:
  228. DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
  229. hdlg, driver_optionsProc, (LPARAM) NULL);
  230. return TRUE;
  231. case IDC_DATASOURCE:
  232. {
  233. LPSETUPDLG lpsetupdlg;
  234. lpsetupdlg = (LPSETUPDLG)GetWindowLong(hdlg, DWL_USER);
  235. DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
  236. hdlg, ds_optionsProc, (LPARAM) &lpsetupdlg->ci);
  237. return TRUE;
  238. }
  239. }
  240. break;
  241. }
  242. // Message not processed
  243. return FALSE;
  244. }
  245. /* ParseAttributes ---------------------------------------------------------
  246.   Description:  Parse attribute string moving values into the aAttr array
  247.   Input      :  lpszAttributes - Pointer to attribute string
  248.   Output     :  None (global aAttr normally updated)
  249. --------------------------------------------------------------------------*/
  250. void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
  251. {
  252. LPCSTR  lpsz;
  253. LPCSTR  lpszStart;
  254. char    aszKey[MAXKEYLEN];
  255. int     cbKey;
  256. char    value[MAXPATHLEN];
  257. memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
  258.         for (lpsz=lpszAttributes; *lpsz; lpsz++)
  259.         {  //  Extract key name (e.g., DSN), it must be terminated by an equals
  260.                 lpszStart = lpsz;
  261.                 for (;; lpsz++)
  262.                 {
  263.                         if (!*lpsz)
  264.                                 return;         // No key was found
  265.                         else if (*lpsz == '=')
  266.                                 break;          // Valid key found
  267.                 }
  268.                 // Determine the key's index in the key table (-1 if not found)
  269.                 cbKey    = lpsz - lpszStart;
  270.                 if (cbKey < sizeof(aszKey))
  271.                 {
  272.                         _fmemcpy(aszKey, lpszStart, cbKey);
  273.                         aszKey[cbKey] = '';
  274.                 }
  275.                 // Locate end of key value
  276.                 lpszStart = ++lpsz;
  277.                 for (; *lpsz; lpsz++);
  278.                 // lpsetupdlg->aAttr[iElement].fSupplied = TRUE;
  279.                 _fmemcpy(value, lpszStart, MIN(lpsz-lpszStart+1, MAXPATHLEN));
  280. mylog("aszKey='%s', value='%s'n", aszKey, value);
  281. // Copy the appropriate value to the conninfo 
  282. copyAttributes(&lpsetupdlg->ci, aszKey, value);
  283.         }
  284.         return;
  285. }
  286. /* SetDSNAttributes --------------------------------------------------------
  287.   Description:  Write data source attributes to ODBC.INI
  288.   Input      :  hwnd - Parent window handle (plus globals)
  289.   Output     :  TRUE if successful, FALSE otherwise
  290. --------------------------------------------------------------------------*/
  291. BOOL INTFUNC SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
  292. {
  293. LPCSTR  lpszDSN;                                                // Pointer to data source name
  294.     
  295.         lpszDSN = lpsetupdlg->ci.dsn;
  296.         // Validate arguments
  297.         if (lpsetupdlg->fNewDSN && !*lpsetupdlg->ci.dsn)
  298.                 return FALSE;
  299.         // Write the data source name
  300.         if (!SQLWriteDSNToIni(lpszDSN, lpsetupdlg->lpszDrvr))
  301.         {
  302.                 if (hwndParent)
  303.                 {
  304.                         char  szBuf[MAXPATHLEN];
  305.                         char  szMsg[MAXPATHLEN];
  306.                         LoadString(s_hModule, IDS_BADDSN, szBuf, sizeof(szBuf));
  307.                         wsprintf(szMsg, szBuf, lpszDSN);
  308.                         LoadString(s_hModule, IDS_MSGTITLE, szBuf, sizeof(szBuf));
  309.                         MessageBox(hwndParent, szMsg, szBuf, MB_ICONEXCLAMATION | MB_OK);
  310.                 }
  311.                 return FALSE;
  312.         }
  313.         // Update ODBC.INI
  314. writeDSNinfo(&lpsetupdlg->ci);
  315.         // If the data source name has changed, remove the old name
  316.         if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn))
  317.         {
  318.                 SQLRemoveDSNFromIni(lpsetupdlg->szDSN);
  319.         }
  320.         return TRUE;
  321. }