void
TKVList::Merge (TKVList &l)
{
  index_t i;

  for (i = 0; i < l.Count (); i++)
     Define (l.Key (i), l.Value (i));
}
void
TLoginDlg::OnOptions (void)
{
  TKVList props;
  TSetupDlg setupDlg (props);

  SaveToProps ();
  props.Merge (m_props);

  setupDlg.m_bFileDSN = TRUE;
  if (setupDlg.RunModal (m_hInstance, IDD_CONFIGDSN, m_hWnd) == IDOK)
    {
      m_props.Empty ();
      m_props.Merge (props);
      LoadFromProps ();
    }
}
BOOL
TSetupDlg::OnOtherMsg (UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  LPCTSTR szDSN;

  switch (uMsg)
    {
    case WM_ZCNOTIFY:
      /* Notification from the resolver that it found a new publication
       */
      m_SERVER.TryResolve ();
      return TRUE;

    case WM_ZCRESOLVED:
      /* Notification from server combo box that entry is now valid
       * Use DSN info from the server as a policy
       */
      if ((szDSN = m_SERVER.GetDSN ()) != NULL)
	{
	  TKVList dsnprops;

	  SaveToProps ();
	  dsnprops.FromDSN (szDSN);
	  if (dsnprops.Find (_T("Encrypt")) == NOT_FOUND)
	    m_props.Undefine (_T("Encrypt"));
	  m_props.Merge (dsnprops);
	  LoadFromProps ();
	}
      /* else case (GetDSN returned NULL):
       * definitely NOT using zero config - the user typed <host>:<port>
       */
      return TRUE;
    }

  return FALSE;
}
/* Called from SQLConnect/SQLDriverConnect */
BOOL
virtodbc_LoginDlg (TKVList &props, HWND hWnd)
{
  /* Run ConfigDSN if setting up a file dsn from ODBCAD32 */
  if (props.Value (_T("Driver")) && CalledFromODBCAD32 ())
    {
      TSetupDlg dlg (props);
      dlg.m_bFileDSN = TRUE;
      return (dlg.RunModal (g_hInstance, IDD_CONFIGDSN, hWnd) == IDOK);
    }
  else
    {
      TLoginDlg dlg (props);
      return (dlg.RunModal (g_hInstance, IDD_LOGINDLG, hWnd) == IDOK);
    }
}
BOOL APIENTRY
ConfigDSNW (
    HWND hWinParent,
    WORD fRequest,
    LPCTSTR lpszDriver,
    LPCTSTR lpszAttributes)
{
  TCHAR szNewDSN[MAX_DSN_LEN + 1];
  TCHAR szDSN[MAX_DSN_LEN + 1];
  TKVList props;
  TSetupDlg setupDlg (props);

  props.FromAttributes (lpszAttributes);
  if (props.Get (_T("DSN"), szDSN, NUMCHARS (szDSN)))
    {
      props.ReadODBCIni (szDSN, _virtuoso_tags);
      props.FromAttributes (lpszAttributes);
    }

  if (fRequest == ODBC_REMOVE_DSN)
    {
      SQLRemoveDSNFromIni (szDSN);
    }
  else if (fRequest == ODBC_CONFIG_DSN || fRequest == ODBC_ADD_DSN)
    {
      if (hWinParent)
        {
          setupDlg.m_bFileDSN = FALSE;
          if (setupDlg.RunModal (g_hInstance, IDD_CONFIGDSN, hWinParent) == IDOK)
	    {
	      if (props.Get (_T("DSN"), szNewDSN, NUMCHARS (szNewDSN)))
	        {
	          props.Undefine (_T("PWD"));
	          SQLWriteDSNToIni (szNewDSN, lpszDriver);
	          props.WriteODBCIni (szNewDSN, _virtuoso_tags);

	          /* If the DSN has changed, delete the old one */
	          if (fRequest == ODBC_CONFIG_DSN && _tcsicmp (szDSN, szNewDSN))
		    SQLRemoveDSNFromIni (szDSN);
	        }
	    }
        }
      else
        {
	  if (props.Get (_T("DSN"), szNewDSN, NUMCHARS (szNewDSN)))
	    {
	       props.Undefine (_T("PWD"));
	       SQLWriteDSNToIni (szNewDSN, lpszDriver);
	       props.WriteODBCIni (szNewDSN, _virtuoso_tags);

	       /* If the DSN has changed, delete the old one */
	       if (fRequest == ODBC_CONFIG_DSN && _tcsicmp (szDSN, szNewDSN))
	          SQLRemoveDSNFromIni (szDSN);
	    }
        }
    }

  return TRUE;
}