// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@

// Drvr35Adm.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "Drvr35Adm.h"
#include "pagegeneral.h"
#include "pagenetwork.h"
#include "pageoptions.h"
#include "pagelocaltr.h"
#include "pagetracing.h"
#include "tabpagegeneral.h"
#include "tabpagenetwork.h"
#include "tabpageoptions.h"
#include "tabpagelocaltr.h"
#include "tabpagetracing.h"
#include "tabpagetesting.h"
#include "propsheet.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

BOOL bNewDSN;
char szDSN[MAXDSNAME];	// Original data source name

LPCSTR lpszDrvr;
HWND hwndParent;
LPAttr aAttr;			// Attribute array pointer
struct LOOKUP_ENTRY
{
	char	szKey[ MAXKEYLEN];
	int		iKey;
};


// Attribute string look-up table (maps keys to associated indexes)
struct LOOKUP_ENTRY s_aLookup[] =
{
	"DSN",							KEY_DSN,
	"Description",					KEY_DESC,
	"Catalog",						KEY_CATALOG,
	"Schema",						KEY_SCHEMA,
	"Location",						KEY_LOCATION,
	"SQL_LOGIN_TIMEOUT",			KEY_LOGIN,
	"SQL_ATTR_CONNECTION_TIMEOUT",	KEY_CONNECTION,
	"SQL_QUERY_TIMEOUT",			KEY_QUERY,
	"IPAddress",					KEY_IPADDRESS,
	"PortNumber",					KEY_PORTNUM,
	"ErrorMsgLang",					KEY_ERRORLANG,
	"DataLang",						KEY_DATALANG,
	"TraceFlags",					KEY_TRACE_FLAGS,
	"TraceFile",					KEY_TRACE_FILE,
	"TranslationDLL",				KEY_TRANSLATION_DLL,
	"TranslationOption",			KEY_TRANSLATION_OPTION,
	"FetchBufferSize",				KEY_FETCH_BUFFER_SIZE,
	"ServiceName",					KEY_SERVICE_NAME,
	"ReplacementCharacter",			KEY_REPLACEMENT_CHAR,
	"Compression",					KEY_COMPRESSION,
	"",								0
};

//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

/////////////////////////////////////////////////////////////////////////////
// CDrvr35AdmApp

BEGIN_MESSAGE_MAP(CDrvr35AdmApp, CWinApp)
	//{{AFX_MSG_MAP(CDrvr35AdmApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDrvr35AdmApp construction

CDrvr35AdmApp::CDrvr35AdmApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CDrvr35AdmApp object

CDrvr35AdmApp theApp;

void ParseAttributes (LPCSTR  lpszAttributes);

void LoadDriverDll();

/* 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)
                lpszIDriver ---- Driver name
                lpszAttributes - data source attribute string
  Output     :  TRUE success, FALSE otherwise
--------------------------------------------------------------------------*/
extern "C" BOOL WINAPI EXPORT ConfigDSN (HWND    hwnd,
                           WORD    fRequest,
                           LPCSTR  lpszDriver,
                           LPCSTR  lpszAttributes)
{
#ifdef _AFXDLL
	AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
#endif

	BOOL  fSuccess;		// Success/fail flag

	lpszDrvr = lpszDriver;
	hwndParent = hwnd;

	aAttr = (struct ATTR *)malloc (sizeof(Attr) * NUMOFKEYS);

	// Not sure about the return code
	if (aAttr == NULL)
		return FALSE;

	for (int i = 0; i< NUMOFKEYS; i++)
	{
		aAttr[i].fSupplied = 0;
		aAttr[i].szAttr[0] = '\0';
	}

	// Parse attribute string
	if( lpszAttributes)
	{
		ParseAttributes( lpszAttributes);
	}

	// Save original data source name
	if( aAttr[ KEY_DSN].fSupplied)
	{
		lstrcpy( szDSN, aAttr[ KEY_DSN].szAttr);
	}
	else
	{
		szDSN[ 0] = '\0';
	}


	if( fRequest == ODBC_REMOVE_DSN)
	{	// Process REMOVE data source
		if( !aAttr[ KEY_DSN].fSupplied)
		{	// Fail if no data source name was supplied
			fSuccess = FALSE;
		}
		else
		{	// Otherwise remove data source from ODBC.INI
			fSuccess = SQLRemoveDSNFromIni( aAttr[ KEY_DSN].szAttr);

			// delete File DSN
			DeleteFileDSN( aAttr[ KEY_DSN].szAttr);
		}
	}
	else
	{	// Process ADD and CONFIGURE data source

		if (hwnd)
		{
			LPCSTR  lpszDSN;
			int posTCP;
			int posSlash;
			LPSTR ptr;
	
			bNewDSN = fRequest == ODBC_ADD_DSN;
// Data source name
			lpszDSN = aAttr[ KEY_DSN].szAttr;
// Data source description
			if( !aAttr[ KEY_DESC].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_KDESC, "", aAttr[ KEY_DESC].szAttr,
						sizeof( aAttr[ KEY_DESC].szAttr), ODBC_INI);
// Service name
			if( !aAttr[ KEY_SERVICE_NAME].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_KSN, "", aAttr[ KEY_SERVICE_NAME].szAttr,
						sizeof( aAttr[ KEY_SERVICE_NAME].szAttr), ODBC_INI);
			
// Catalog string
			if( !aAttr[ KEY_CATALOG].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_CATALOG, "", aAttr[ KEY_CATALOG].szAttr,
						sizeof( aAttr[ KEY_CATALOG].szAttr), ODBC_INI);
		
// Schema string
			if( !aAttr[ KEY_SCHEMA].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_SCHEMA, "", aAttr[ KEY_SCHEMA].szAttr,
						sizeof( aAttr[ KEY_SCHEMA].szAttr), ODBC_INI);
		
// Association Service (IP Address and Port Number)
			if( (!aAttr[ KEY_IPADDRESS].fSupplied) && (!aAttr[ KEY_PORTNUM].fSupplied))
			{					
				char szBuf[MAXIPLEN+30];
				memset(szBuf, '\0', sizeof(szBuf));
				SQLGetPrivateProfileString( lpszDSN, INI_NETWORK, "", szBuf,
					sizeof( szBuf), ODBC_INI);
				if (strlen(szBuf))
				{
					ptr = szBuf;
// posTCP represents the position of the colon.				
					posTCP = strcspn( szBuf, ":");	
// posSlash represents the position of the slash.				
					posSlash = strcspn( szBuf, "/");	
					if ((posTCP >0) && (posSlash >0))				
					{					
// ptr points to the buffer after :, not including :				
						ptr = ptr + posTCP + 1;					
						strncpy(aAttr[ KEY_IPADDRESS].szAttr, ptr, posSlash - posTCP-1);				

						aAttr[ KEY_IPADDRESS].szAttr[posSlash - posTCP-1] = '\0';
							
						ptr = szBuf + posSlash + 1;				
						strncpy(aAttr[ KEY_PORTNUM].szAttr, ptr, strlen(szBuf) - posSlash-1);								
						aAttr[ KEY_PORTNUM].szAttr[strlen(szBuf) - posSlash-1] = '\0';
				
					}
				}				
			}

			if( !aAttr[ KEY_LOGIN].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_LOGIN, "", aAttr[ KEY_LOGIN].szAttr,
					sizeof( aAttr[ KEY_LOGIN].szAttr), ODBC_INI);

			if( !aAttr[ KEY_CONNECTION].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_CONNECTION, "", aAttr[ KEY_CONNECTION].szAttr,
					sizeof( aAttr[ KEY_CONNECTION].szAttr), ODBC_INI);

			if( !aAttr[ KEY_QUERY].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_QUERY, "", aAttr[ KEY_QUERY].szAttr,
					sizeof( aAttr[ KEY_QUERY].szAttr), ODBC_INI);

			if( !aAttr[ KEY_ERRORLANG].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_ERRORLANG, "", aAttr[ KEY_ERRORLANG].szAttr,
					sizeof( aAttr[ KEY_ERRORLANG].szAttr), ODBC_INI);

			if( !aAttr[ KEY_DATALANG].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_DATALANG, "", aAttr[ KEY_DATALANG].szAttr,
					sizeof( aAttr[ KEY_DATALANG].szAttr), ODBC_INI);

			if( !aAttr[ KEY_TRANSLATION_DLL].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_TRANSLATION_DLL, "", aAttr[ KEY_TRANSLATION_DLL].szAttr,
					sizeof( aAttr[ KEY_TRANSLATION_DLL].szAttr), ODBC_INI);

			if( !aAttr[ KEY_TRANSLATION_OPTION].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_TRANSLATION_OPTION, "", aAttr[ KEY_TRANSLATION_OPTION].szAttr,
					sizeof( aAttr[ KEY_TRANSLATION_OPTION].szAttr), ODBC_INI);

			if(!aAttr[ KEY_TRACE_FLAGS].fSupplied)
				SQLGetPrivateProfileString(szODBC, 
										INI_TRACE_FLAGS, 
										szDefaultTraceFlags,
										aAttr[ KEY_TRACE_FLAGS].szAttr, 
										sizeof( aAttr[ KEY_TRACE_FLAGS].szAttr), 
										szODBCIni);

			if(!aAttr[ KEY_TRACE_FILE].fSupplied)
				SQLGetPrivateProfileString(szODBC, 
										INI_TRACE_FILE, 
										szDefaultTraceFile,
										aAttr[ KEY_TRACE_FILE].szAttr, 
										sizeof( aAttr[ KEY_TRACE_FILE].szAttr), 
										szODBCIni);

			if( !aAttr[ KEY_FETCH_BUFFER_SIZE].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_FETCH_BUFFER_SIZE, "", aAttr[ KEY_FETCH_BUFFER_SIZE].szAttr,
					sizeof( aAttr[ KEY_FETCH_BUFFER_SIZE].szAttr), ODBC_INI);

			if( !aAttr[ KEY_REPLACEMENT_CHAR].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_REPLACEMENT_CHAR, "", aAttr[ KEY_REPLACEMENT_CHAR].szAttr,
					sizeof( aAttr[ KEY_REPLACEMENT_CHAR].szAttr), ODBC_INI);

			if( !aAttr[ KEY_COMPRESSION].fSupplied)
				SQLGetPrivateProfileString( lpszDSN, INI_COMPRESSION, "", aAttr[ KEY_COMPRESSION].szAttr,
					sizeof( aAttr[ KEY_COMPRESSION].szAttr), ODBC_INI);
			CPropSheet dlgPropSheet("TRAF ODBC Setup");
			dlgPropSheet.m_psh.hIcon = AfxGetApp()->LoadIcon(IDI_BOBICON);
			dlgPropSheet.m_psh.dwFlags |= (PSH_USEHICON | PSH_HASHELP) ;

			if(bNewDSN)
			{
				PageGeneral pageGeneral;
				PageNetwork pageNetwork;
				PageOptions pageOptions;
				PageLocalTr pageLocalTr;
				//PageTracing pageTracing;

				pageGeneral.m_ppropsheet = &dlgPropSheet;
				pageNetwork.m_ppropsheet = &dlgPropSheet;
				pageOptions.m_ppropsheet = &dlgPropSheet;
				//pageTracing.m_ppropsheet = &dlgPropSheet;
				pageLocalTr.m_ppropsheet = &dlgPropSheet;

				pageGeneral.m_psp.dwFlags |= PSP_HASHELP ;
				pageNetwork.m_psp.dwFlags |= PSP_HASHELP ;
				pageOptions.m_psp.dwFlags |= PSP_HASHELP ;
				pageLocalTr.m_psp.dwFlags |= PSP_HASHELP ;
				//pageTracing.m_psp.dwFlags |= PSP_HASHELP ;

				dlgPropSheet.AddPage(&pageGeneral);
				dlgPropSheet.AddPage(&pageNetwork);
				dlgPropSheet.AddPage(&pageOptions);
				dlgPropSheet.AddPage(&pageLocalTr);
				//dlgPropSheet.AddPage(&pageTracing);

				dlgPropSheet.SetWizardMode();

				if(dlgPropSheet.DoModal()==ID_WIZFINISH)
					fSuccess = TRUE;
				else
					fSuccess = FALSE;
			}
			else
			{

				TabPageGeneral pageGeneral;
				TabPageNetwork pageNetwork;
				TabPageOptions pageOptions;
				TabPageLocalTr pageLocalTr;
				//TabPageTracing pageTracing;
				TabPageTesting pageTesting;

				pageGeneral.m_psp.dwFlags |= PSP_HASHELP ;
				pageNetwork.m_psp.dwFlags |= PSP_HASHELP ;
				pageOptions.m_psp.dwFlags |= PSP_HASHELP ;
				pageLocalTr.m_psp.dwFlags |= PSP_HASHELP ;
				//pageTracing.m_psp.dwFlags |= PSP_HASHELP ;
				pageTesting.m_psp.dwFlags |= PSP_HASHELP ;

				pageGeneral.m_ppropsheet = &dlgPropSheet;
				pageNetwork.m_ppropsheet = &dlgPropSheet;
				pageOptions.m_ppropsheet = &dlgPropSheet;
				//pageTracing.m_ppropsheet = &dlgPropSheet;
				pageLocalTr.m_ppropsheet = &dlgPropSheet;
				pageTesting.m_ppropsheet = &dlgPropSheet;

				dlgPropSheet.AddPage(&pageGeneral);
				dlgPropSheet.AddPage(&pageNetwork);
				dlgPropSheet.AddPage(&pageOptions);
				dlgPropSheet.AddPage(&pageLocalTr);
				//dlgPropSheet.AddPage(&pageTracing);
				dlgPropSheet.AddPage(&pageTesting);

				if(dlgPropSheet.DoModal()==IDOK)
					fSuccess = TRUE;
				else
					fSuccess = FALSE;
			}
		}

		else if( aAttr[ KEY_DSN].fSupplied)
			fSuccess = SetDSNAttributes( hwnd, lpszDriver, fRequest==ODBC_ADD_DSN);
		else
			fSuccess = FALSE;
	}
	free (aAttr);
	return fSuccess;
}


/* ParseAttributes ---------------------------------------------------------
  Description:  Parse attribute string moving values into the aAttr array
  Input      :  lpszAttributes - Pointer to attribute string
  Output     :  None (global aAttr normally updated)
--------------------------------------------------------------------------*/
void ParseAttributes(LPCSTR lpszAttributes)
{
  
  LPCSTR  lpsz;
  LPCSTR  lpszStart;
  char    aszKey[MAXKEYLEN];
  long   iElement;
  long   cbKey;

  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)
    iElement = -1;
    cbKey    = lpsz - lpszStart;
    if (cbKey < sizeof(aszKey)) {
      register short  j;

      memcpy(aszKey, lpszStart, cbKey);
      aszKey[cbKey] = '\0';
      for (j = 0; *s_aLookup[j].szKey; j++)
        if (!lstrcmpi(s_aLookup[j].szKey, aszKey)) {
          iElement = s_aLookup[j].iKey;
          break;
        }
    }

    // Locate end of key value
    lpszStart = ++lpsz;
    for (; *lpsz; lpsz++);

    // Save value if key is known
    // NOTE: This code assumes the szAttr buffers in aAttr have been
    //       zero initialized
    if (iElement >= 0) {
      aAttr[iElement].fSupplied = TRUE;
      memcpy(aAttr[iElement].szAttr,
               lpszStart,
               min(lpsz-lpszStart+1, sizeof(aAttr[0].szAttr)-1));
    }
  }
  return;
  
}

/* SetDSNAttributes --------------------------------------------------------
  Description:  Write data source attributes to ODBC.INI
  Input      :  hwnd - Parent window handle (plus globals)
  Output     :  TRUE if successful, FALSE otherwise
--------------------------------------------------------------------------*/
BOOL SetDSNAttributes( HWND hwndParent, LPCSTR  lpszDrvr, BOOL    bNewDSN)
{
	LPCSTR	lpszDSN;                        // Pointer to data source name

	lpszDSN = aAttr[ KEY_DSN].szAttr;

	// validate data source name argument
	if( bNewDSN && !*aAttr[ KEY_DSN].szAttr)
		{
		return FALSE;
		}

	// write data source name
	if( !SQLWriteDSNToIni( lpszDSN, lpszDrvr))
	{
		if( hwndParent)
		{
			
			char  szMsg[ MAXPATHLEN];
			CString szBuf;
			
			szBuf.LoadString(IDS_BADDSN);
			wsprintf( szMsg, szBuf, lpszDSN);			
			AfxMessageBox( szMsg);
		}
		return FALSE;
	}

	// update ODBC.INI
	// save the value if the data source is new, edited, or explicitly supplied
	if( hwndParent || aAttr[ KEY_DESC].fSupplied)
		{
		char  szBuf[ MAXPATHLEN];

		WritePrivateProfileString( lpszDSN,	INI_KDESC, aAttr[ KEY_DESC].szAttr,	ODBC_INI);
// update File DSN
		lstrcpy(szBuf, lpszDSN );
		lstrcat(szBuf, " (not sharable)");
		SQLWriteFileDSN( szBuf, "ODBC", "DSN", lpszDSN );

		SQLWritePrivateProfileString( lpszDSN,	INI_KDESC, aAttr[ KEY_DESC].szAttr,	ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_SERVICE_NAME].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_KSN, aAttr[ KEY_SERVICE_NAME].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_KSN, aAttr[ KEY_SERVICE_NAME].szAttr, ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_CATALOG].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_CATALOG, aAttr[ KEY_CATALOG].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_CATALOG, aAttr[ KEY_CATALOG].szAttr, ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_SCHEMA].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_SCHEMA, aAttr[ KEY_SCHEMA].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_SCHEMA, aAttr[ KEY_SCHEMA].szAttr, ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_LOCATION].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_LOCATION, aAttr[ KEY_LOCATION].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_LOCATION, aAttr[ KEY_LOCATION].szAttr, ODBC_INI);
		}

// Association Service (IP Address and Port Number)
// fSupplied is not working for some unknown reason at this time.
//	 if( hwndParent)
		if( hwndParent || aAttr[ KEY_IPADDRESS].fSupplied )
		{	
//		if (strlen(aAttr[ KEY_PORTNUM].szAttr)|| strlen(aAttr[ KEY_IPADDRESS].szAttr))
//		{
			char szBuf[MAXIPLEN+30];
			wsprintf(szBuf, "%s%s/%s", TCP_STR, aAttr[ KEY_IPADDRESS].szAttr, aAttr[ KEY_PORTNUM].szAttr);

		WritePrivateProfileString( lpszDSN,	INI_NETWORK, szBuf, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_NETWORK, szBuf, ODBC_INI);
		//}
		
		}
		
	if( hwndParent || aAttr[ KEY_LOGIN].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_LOGIN, aAttr[ KEY_LOGIN].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_LOGIN, aAttr[ KEY_LOGIN].szAttr, ODBC_INI);
		}
	if( hwndParent || aAttr[ KEY_CONNECTION].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_CONNECTION, aAttr[ KEY_CONNECTION].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_CONNECTION, aAttr[ KEY_CONNECTION].szAttr, ODBC_INI);
		}
	if( hwndParent || aAttr[ KEY_QUERY].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_QUERY, aAttr[ KEY_QUERY].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_QUERY, aAttr[ KEY_QUERY].szAttr, ODBC_INI);
		}

	// the following are the localization (internationalization) attributes
	if( hwndParent || aAttr[ KEY_ERRORLANG].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_ERRORLANG, aAttr[ KEY_ERRORLANG].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_ERRORLANG, aAttr[ KEY_ERRORLANG].szAttr, ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_DATALANG].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_DATALANG, aAttr[ KEY_DATALANG].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_DATALANG, aAttr[ KEY_DATALANG].szAttr, ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_TRANSLATION_DLL].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_TRANSLATION_DLL, aAttr[ KEY_TRANSLATION_DLL].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_TRANSLATION_DLL, aAttr[ KEY_TRANSLATION_DLL].szAttr, ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_TRANSLATION_OPTION].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_TRANSLATION_OPTION, aAttr[ KEY_TRANSLATION_OPTION].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_TRANSLATION_OPTION, aAttr[ KEY_TRANSLATION_OPTION].szAttr, ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_FETCH_BUFFER_SIZE].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_FETCH_BUFFER_SIZE, aAttr[ KEY_FETCH_BUFFER_SIZE].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_FETCH_BUFFER_SIZE, aAttr[ KEY_FETCH_BUFFER_SIZE].szAttr, ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_TRACE_FILE].fSupplied)
		{
		WriteTraceRegistry( INI_TRACE_FILE,aAttr[ KEY_TRACE_FILE].szAttr);
		}
	if( hwndParent || aAttr[ KEY_TRACE_FLAGS].fSupplied)
		{
		WriteTraceRegistry( INI_TRACE_FLAGS,aAttr[ KEY_TRACE_FLAGS].szAttr);
		}

	if( hwndParent || aAttr[ KEY_REPLACEMENT_CHAR].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_REPLACEMENT_CHAR, aAttr[ KEY_REPLACEMENT_CHAR].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_REPLACEMENT_CHAR, aAttr[ KEY_REPLACEMENT_CHAR].szAttr, ODBC_INI);
		}

	if( hwndParent || aAttr[ KEY_COMPRESSION].fSupplied)
		{
		WritePrivateProfileString( lpszDSN,	INI_COMPRESSION, aAttr[ KEY_COMPRESSION].szAttr, ODBC_INI);
		SQLWritePrivateProfileString( lpszDSN,	INI_COMPRESSION, aAttr[ KEY_COMPRESSION].szAttr, ODBC_INI);
		}


// if the data source name has changed, remove the old name
	if( aAttr[ KEY_DSN].fSupplied && lstrcmpi( szDSN, aAttr[ KEY_DSN].szAttr))
		{
		SQLRemoveDSNFromIni( szDSN);
// remove File Data Source Name
		DeleteFileDSN( szDSN );
		}

	return TRUE;
}

//=====================================================

#define MAX_INI_VAL 261

void DeleteFileDSN( LPCSTR lpszDSN )
{
	const char Key1[]  = "Software\\ODBC\\ODBC.INI\\ODBC File DSN";
	const char Name1[] = "DefaultDSNDir";

	const char Key2[]  = "Software\\Microsoft\\Windows\\CurrentVersion";
	const char Name2[] = "CommonFilesDir";

	char	szBuf[ MAXPATHLEN];
	CHAR    szIniVal[MAX_INI_VAL];
	LRESULT lResult;
	DWORD   dwType = 0;
	DWORD   cbData;
	HKEY	hkGlobal = NULL;
	int		rc = -1;

// registry
	lResult= RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key1, 0, KEY_READ, &hkGlobal );
  
	if( lResult == ERROR_SUCCESS ){
		   
		cbData = MAX_INI_VAL;
		szIniVal[0] = '\0';

		lResult= RegQueryValueEx(hkGlobal, Name1, 0, &dwType, (LPBYTE)szIniVal, &cbData );
		
		RegCloseKey(hkGlobal);

		if( lResult == ERROR_SUCCESS ){  

			lstrcpy(szBuf, szIniVal );
			lstrcat(szBuf, "\\" );
			lstrcat(szBuf, lpszDSN );
			lstrcat(szBuf, " (not sharable).dsn");
			rc = _unlink(szBuf);

		}

	}
	if( rc == -1)
	{
		lResult= RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key2, 0, KEY_READ, &hkGlobal );
  
		if( lResult == ERROR_SUCCESS ){
		   
			cbData = MAX_INI_VAL;
			szIniVal[0] = '\0';

			lResult= RegQueryValueEx(hkGlobal, Name2, 0, &dwType, (LPBYTE)szIniVal, &cbData );
		
			RegCloseKey(hkGlobal);

			if( lResult == ERROR_SUCCESS ){  

				lstrcpy(szBuf, szIniVal );
				lstrcat(szBuf, "\\ODBC\\Data Sources\\" );
				lstrcat(szBuf, lpszDSN );
				lstrcat(szBuf, " (not sharable).dsn");
				_unlink(szBuf);

			}

		}
	}

// registry end
}

void WriteTraceRegistry( const char szName[],char* szData)
{
	UWORD wConfigMode;

	SQLGetConfigMode(&wConfigMode);
	SQLSetConfigMode(ODBC_USER_DSN);
	SQLWritePrivateProfileString(szODBC,szName,szData, szODBCIni);
	SQLSetConfigMode(ODBC_SYSTEM_DSN);
	SQLWritePrivateProfileString(szODBC,szName,szData, szODBCIni);
	SQLSetConfigMode(wConfigMode);
/*
	HKEY	hkGlobal = NULL;
	DWORD	dwDisposition;

    if(ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, TRACE_PATH
		,0,(char*)szName,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hkGlobal,&dwDisposition ))
		return;
	
	RegSetValueEx( hkGlobal,szName,0,REG_SZ,(UCHAR*)szData,strlen(szData)+1);
	RegCloseKey(hkGlobal);
*/

}

void ReadTraceRegistry( const char szName[],char* szData, long size)
{
/*
	DWORD   dwType = 0;
	DWORD   cbData;
	HKEY	hkGlobal = NULL;

	if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER,TRACE_PATH,0,KEY_READ,&hkGlobal))
		return;
 
	cbData = size;
	*szData = 0;

	RegQueryValueEx(hkGlobal,szName,0,&dwType,(LPBYTE)szData,&cbData );
	RegCloseKey(hkGlobal);
*/
}

#define GET_DS_ALL "GET_DS_ALL"
typedef void* (* FPGET_DS_ALL)(char* objRef);

void* pDataSourceInfo = NULL;

void getDSInfo(char* Ip, char* port)
{
	char objref[MAXIPLEN+30];
	char Key[50]  = "Software\\ODBC\\ODBCINST.INI\\";
	const char Name[] = "Driver";
	HMODULE Handle = NULL;

	char	szBuf[ MAXPATHLEN];
	LRESULT lResult;
	DWORD   dwType = 0;
	DWORD   cbData;
	HKEY	hkGlobal = NULL;
	int		rc = -1;

	FPGET_DS_ALL fpGET_DS_ALL;

	wsprintf(objref, "%s%s/%s", TCP_STR, Ip, port);
// registry
	strcat(Key,lpszDrvr);

	lResult= RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key, 0, KEY_READ, &hkGlobal );
  
	if( lResult == ERROR_SUCCESS ){
		   
		cbData = MAX_INI_VAL;
		szBuf[0] = '\0';

		lResult= RegQueryValueEx(hkGlobal, Name, 0, &dwType, (LPBYTE)szBuf, &cbData );
		
		RegCloseKey(hkGlobal);
/*
		if( lResult == ERROR_SUCCESS ){  

			if ((Handle = GetModuleHandle(szBuf)) != NULL || (Handle = LoadLibrary(szBuf)) != NULL )
			{
				fpGET_DS_ALL = (FPGET_DS_ALL)GetProcAddress( Handle, GET_DS_ALL);
				if (fpGET_DS_ALL != NULL)
					pDataSourceInfo = (fpGET_DS_ALL)(objref);
				else
					pDataSourceInfo = NULL;
			}
		}
*/
	}

}

void freeDSInfo()
{
	if (pDataSourceInfo != NULL)
	{
		delete pDataSourceInfo;
		pDataSourceInfo = NULL;
	}
}
static unsigned long index = 0;

static char* getDSName(unsigned long index)
{
	DATASOURCE_STATUS_LIST_def *ppDataSourceInfo = (DATASOURCE_STATUS_LIST_def*)pDataSourceInfo;
	if (index >= ppDataSourceInfo->_length)
		return "";
	DATASOURCE_STATUS_def *buffer = ppDataSourceInfo->_buffer + index;
	return buffer->DSName;
}

char* getFirstDSName()
{
	if (pDataSourceInfo != NULL)
	{
		index = 0;
		return getDSName(index++);
	}
	else
		return "";
}

char* getNextDSName()
{
	if (pDataSourceInfo != NULL)
		return getDSName(index++);
	else
		return "";
}

DATASOURCE_STATUS_def *getDSNameDetails(char* sDSName)
{
	DATASOURCE_STATUS_LIST_def* ppDataSourceInfo = (DATASOURCE_STATUS_LIST_def*)pDataSourceInfo;
	DATASOURCE_STATUS_def *buffer;
	
	if (pDataSourceInfo != NULL && ppDataSourceInfo->_buffer != NULL )
	{
		for (unsigned long index = 0; index < ppDataSourceInfo->_length; index++)
		{
			buffer = ppDataSourceInfo->_buffer + index;
			if (strcmp(buffer->DSName, sDSName) == 0)
			{
				return buffer;
			}
		}
	}
	return NULL;
}
