// @@@ 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 @@@
//
//
#include "CDataSource.h"
#include "NLSFunctions.h"
#include "Transport.h"

// Implements the member functions of CDataSource

#define MAX_REGKEY_PATH_LEN			512
#define	ODBC_DS_KEY					"SOFTWARE\\ODBC\\ODBC.INI\\"
#define ODBC_CERTIFICATE_KEY		"SOFTWARE\\ODBC\\ODBCINST.INI\\TRAF ODBC 2.2"
#define SYSTEM_DEFAULT				"SYSTEM_DEFAULT"
#define NO_TIMEOUT					"NO_TIMEOUT"
#define CONNECTION_TIMEOUT_DEFAULT	60
#define LOGIN_TIMEOUT_DEFAULT		60
#define	QUERY_TIMEOUT_DEFAULT		0
#define IOCOMPRESSION_DEFAULT       1000
#define FETCH_BUFFER_SIZE_DEFAULT	512 * 1024
//#define FETCH_BUFFER_SIZE_DEFAULT   0


CDataSource::CDataSource()
{
	m_DSName[0] = '\0';
	m_DSLocation = 0;
	m_DSServer[0] = '\0';
	m_DSCatalog[0] = '\0';
	m_DSCtrlInferNCHAR = FALSE;
	m_DSCharSet = 0;
	m_DSDataLang = MAKELCID (MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT);
	m_DSErrorMsgLang = MAKELCID (MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT);
	m_DSFetchBufferSize = FETCH_BUFFER_SIZE_DEFAULT;
	m_DSSchema[0] = '\0';
	m_DSConnectionTimeout = CONNECTION_TIMEOUT_DEFAULT;
	m_DSLoginTimeout = LOGIN_TIMEOUT_DEFAULT;
	m_DSQueryTimeout = QUERY_TIMEOUT_DEFAULT;
	m_DSTranslationDLL[0] = '\0';
	m_DSTranslationOption = 0;
	m_DSReplacementChar[0] = '\0';
	m_DSSelectRowsets = TRUE;
	m_DSRowsetErrorRecovery = FALSE;
	m_DSServerDSName[0] = 0;
	m_DSServiceName[0] = 0;
	m_DSSession[0] = '\0';
	m_DSApplication[0] = '\0';
	m_DSRoleName[0] = '\0';
	m_DSCertificateDir[0] = '\0';
	m_DSCertificateFile[0] = '\0';
	m_DSCertificateFileActive[0] = '\0';
	m_DSIOCompression = 0;

	DWORD	error;
	HKEY	keyHandle;
	DWORD	keyValueLength;
	DWORD	keyValueType;
	error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
						 ODBC_CERTIFICATE_KEY,
						 0,
						 KEY_READ,
						 &keyHandle);
	if (error == ERROR_SUCCESS)
	{
		// Read CertificateDir	Value
		keyValueLength = sizeof(m_DSCertificateDir);
		error = RegQueryValueEx (keyHandle,
						   "CertificateDir",
						   NULL,				// Reserved
						   &keyValueType,
						   (LPBYTE)m_DSCertificateDir,
						   &keyValueLength);
		if (error != ERROR_SUCCESS)
			m_DSCertificateDir[0] = '\0';
		RegCloseKey(keyHandle);
	}
	else 
		m_DSCertificateDir[0] = '\0';
}

short CDataSource::readDSValues(char *DSName, char* transError)
{

	DWORD	error;
	char	searchKey[MAX_REGKEY_PATH_LEN+1];
	HKEY	keyHandle;
	BYTE	keyValueBuf[256];
	DWORD	keyValueLength;
	DWORD	keyValueType;
	long	tempValue;
	short	i = 0;
	SQLRETURN retcode = ERROR_SUCCESS;
	int translen;
	wchar_t	tmpWBuf[MAX_SQL_IDENTIFIER_LEN + 1];

	strcpyUTF8(m_DSName, (const char *)DSName, sizeof(m_DSName));

	for (i = 0; i < 2 ; i++)
	{
		strcpy(searchKey, ODBC_DS_KEY);
		if ( i == 0)
			strcat(searchKey, (const char *)DSName);
		else
			strcat(searchKey, "DEFAULT");

		error = RegOpenKeyEx(HKEY_CURRENT_USER
						   ,searchKey
						   ,0
						   ,KEY_READ
						   ,&keyHandle);
		if (error == ERROR_SUCCESS)
		{
			m_DSLocation = HKCU_DSN; // HKCU
			// Read AssociationService	Value
			tmpWBuf[0] = L'\0';
			keyValueLength = sizeof(tmpWBuf);
			error = RegQueryValueExW (keyHandle,
							   L"Server",
							   NULL,				// Reserved
							   &keyValueType,
							   (LPBYTE)tmpWBuf,
							   &keyValueLength);
			if (error != ERROR_SUCCESS)
			{
				error = RegQueryValueExW (keyHandle,
							   L"AssociationService",
							   NULL,				// Reserved
							   &keyValueType,
							   (LPBYTE)tmpWBuf,
							   &keyValueLength);
				if (error != ERROR_SUCCESS)
				{
					RegCloseKey( keyHandle);
					if (retcode == ERROR_SUCCESS)
						retcode = DS_AS_KEY_NOT_FOUND;
				}
				else
				{
					retcode = ERROR_SUCCESS;
				}
			}
			else
			{
				retcode = ERROR_SUCCESS;
			}
			if (error == ERROR_SUCCESS)
			{
				// translate m_DSServer to UTF8
				transError[0] = '\0';
				if(wcslen((wchar_t*)tmpWBuf) > 0)
				{
					if (WCharToUTF8((wchar_t*) tmpWBuf, wcslen((wchar_t*)tmpWBuf), m_DSServer, sizeof(m_DSServer), &translen, transError)!= SQL_SUCCESS)
					{
						strcat(transError," :DataSource Server Name ");
						return  DS_TRANSLATION_ERROR;
					}
				}
				break;
			}
		}
		else if (retcode == ERROR_SUCCESS)
			retcode = DS_NOT_FOUND;

		error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
					   searchKey,
					   0,
					   KEY_READ,
					   &keyHandle);
		if (error == ERROR_SUCCESS)
		{
			m_DSLocation = HKLM_DSN; //HKLM
			// Read AssociationService	Value
			tmpWBuf[0] = L'\0';
			keyValueLength = sizeof(tmpWBuf);;
			error = RegQueryValueExW (keyHandle,
							   L"Server",
							   NULL,				// Reserved
							   &keyValueType,
							   (LPBYTE)tmpWBuf,
							   &keyValueLength);
			if (error != ERROR_SUCCESS)
			{
				error = RegQueryValueExW (keyHandle,
							   L"AssociationService",
							   NULL,				// Reserved
							   &keyValueType,
							   (LPBYTE)tmpWBuf,
							   &keyValueLength);
				if (error != ERROR_SUCCESS)
				{
					RegCloseKey( keyHandle);
					if (retcode == ERROR_SUCCESS)
						retcode = DS_AS_KEY_NOT_FOUND;
				}
				else
				{
					retcode = ERROR_SUCCESS;
				}
			}
			else
			{
				retcode = ERROR_SUCCESS;
			}
			if (error == ERROR_SUCCESS)
			{
				// translate m_DSServer to UTF8
				transError[0] = '\0';
				if(wcslen((wchar_t*)tmpWBuf) > 0)
				{
					if (WCharToUTF8((wchar_t*) tmpWBuf, wcslen((wchar_t*)tmpWBuf), m_DSServer, sizeof(m_DSServer), &translen, transError)!= SQL_SUCCESS)
					{
						strcat(transError," :DataSource Server Name ");
						return  DS_TRANSLATION_ERROR;
					}
				}
				break;
			}
		}
		else if (retcode == ERROR_SUCCESS)
			retcode = DS_NOT_FOUND;
	}

	if (retcode != ERROR_SUCCESS)
		return retcode;

	//Read the Catalog Value in unicode
	tmpWBuf[0] = L'\0';
	keyValueLength = sizeof(tmpWBuf);
	error = RegQueryValueExW (keyHandle,
	                   L"Catalog",
					   NULL,				// Reserved
					   &keyValueType,
					   (LPBYTE)tmpWBuf,
					   &keyValueLength);
	if (error != ERROR_SUCCESS)
		m_DSCatalog[0] = '\0';
	transError[0] = '\0';
	//Convert Catalog Value to UTF-8
	if(wcslen((wchar_t*)tmpWBuf) > 0)
	{
		if (WCharToUTF8((wchar_t*) tmpWBuf, wcslen((wchar_t*)tmpWBuf), m_DSCatalog, sizeof(m_DSCatalog), &translen, transError)!= SQL_SUCCESS)
		{
			strcat(transError," :DataSource Catalog Name ");
			return  DS_TRANSLATION_ERROR;
		}
	}

	// Read CtrlInferNCHAR Value
	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "CtrlInferNCHAR",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);
	if (error == ERROR_SUCCESS)
	{
		tempValue = atol((const char *)keyValueBuf);
		if (tempValue)
			m_DSCtrlInferNCHAR = TRUE;
		else
			m_DSCtrlInferNCHAR = FALSE;
	}
	else
		m_DSCtrlInferNCHAR = TRUE;


	// Read DataLang Value
	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "DataLang",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);
	if (error == ERROR_SUCCESS)
	{
		m_DSCharSet = atol((const char *)keyValueBuf);
		m_DSDataLang = m_DSCharSet;
		ODBCNLS_ValidateLanguage(&m_DSDataLang);
	}
	else	
		m_DSDataLang = MAKELCID (MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT);

	// Read ErrorMsgLang Value
	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "ErrorMsgLang",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);
	if (error == ERROR_SUCCESS)
	{
		m_DSErrorMsgLang = atol((const char *)keyValueBuf);
		ODBCNLS_ValidateLanguage(&m_DSErrorMsgLang);
	}
	else	
		m_DSErrorMsgLang = MAKELCID (MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT);

	// Read FetchBufferSize
	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx ( keyHandle
	                   ,"FetchBufferSize"
					   ,NULL				// Reserved
					   ,&keyValueType
					   ,keyValueBuf
					   ,&keyValueLength);
	if (error == ERROR_SUCCESS)
	{	
		if (strcmp((const char *)keyValueBuf, SYSTEM_DEFAULT) == 0)
			m_DSFetchBufferSize = FETCH_BUFFER_SIZE_DEFAULT;
		else
			m_DSFetchBufferSize = atol((const char *)keyValueBuf) * 1024;
	}
	else
		m_DSFetchBufferSize = FETCH_BUFFER_SIZE_DEFAULT;

	//Read the Schema Value in unicode
	tmpWBuf[0] = L'\0';
	keyValueLength = sizeof(tmpWBuf);
	error = RegQueryValueExW (keyHandle,
	                   L"Schema",
					   NULL,				// Reserved
					   &keyValueType,
					   (LPBYTE)tmpWBuf,
					   &keyValueLength);
	if (error != ERROR_SUCCESS)
		m_DSSchema[0] = '\0';
	transError[0] = '\0';
	//Convert Schema Value to UTF-8
	if(wcslen((wchar_t*)tmpWBuf) > 0)
	{
		if (WCharToUTF8((wchar_t*) tmpWBuf, wcslen((wchar_t*)tmpWBuf), m_DSSchema, sizeof(m_DSSchema), &translen, transError) != SQL_SUCCESS)
		{
			strcat(transError, " :DataSource Schema Name ");
			return  DS_TRANSLATION_ERROR;
		}
	}
	//customer specific change
	if(m_DSSchema[0] == '\0')
		gDrvrGlobal.noSchemaInDSN = true;

	// Read SQL_ATTR_CONNECTION_TIMEOUT value
	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "SQL_ATTR_CONNECTION_TIMEOUT",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);
	if (error == ERROR_SUCCESS)
	{	
		if (strcmp((const char *)keyValueBuf, SYSTEM_DEFAULT) == 0)
			m_DSConnectionTimeout = CONNECTION_TIMEOUT_DEFAULT;
		else
		if (strcmp((const char *)keyValueBuf, NO_TIMEOUT) == 0)
			m_DSConnectionTimeout = 0;
		else
			m_DSConnectionTimeout = atol((const char *)keyValueBuf);
	}
	else
		m_DSConnectionTimeout = CONNECTION_TIMEOUT_DEFAULT;
		
	// Read SQL_LOGIN_TIMEOUT value
	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "SQL_LOGIN_TIMEOUT",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);
	if (error == ERROR_SUCCESS)
	{	
		if (strcmp((const char *)keyValueBuf, SYSTEM_DEFAULT) == 0)
			m_DSLoginTimeout = LOGIN_TIMEOUT_DEFAULT;
		else
		if (strcmp((const char *)keyValueBuf, NO_TIMEOUT) == 0)
			m_DSLoginTimeout = 0;
		else
			m_DSLoginTimeout = atol((const char *)keyValueBuf);
	}
	else
		m_DSLoginTimeout = LOGIN_TIMEOUT_DEFAULT;
	
	// Read SQL_QURRY_TIMEOUT value
	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "SQL_QUERY_TIMEOUT",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);
	if (error == ERROR_SUCCESS)
	{	
		if (strcmp((const char *)keyValueBuf, SYSTEM_DEFAULT) == 0)
			m_DSQueryTimeout = QUERY_TIMEOUT_DEFAULT;
		else
		if (strcmp((const char *)keyValueBuf, NO_TIMEOUT) == 0)
			m_DSQueryTimeout = 0;
		else
		{
			m_DSQueryTimeout = atol((const char *)keyValueBuf);
			if(m_DSQueryTimeout != 0 && m_DSQueryTimeout < 30)
				m_DSQueryTimeout = 30;
		}
	}
	else
		m_DSQueryTimeout = QUERY_TIMEOUT_DEFAULT;
	
	// Read TranslationDLL Value
	keyValueLength = sizeof(m_DSTranslationDLL);
	error = RegQueryValueEx (keyHandle,
	                   "TranslationDLL",
					   NULL,				// Reserved
					   &keyValueType,
					   (LPBYTE)m_DSTranslationDLL,
					   &keyValueLength);
	if (error != ERROR_SUCCESS)
		m_DSTranslationDLL[0] = '\0';

	// Read TranslationOption Value
	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "TranslationOption",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);
	if (error == ERROR_SUCCESS)
		m_DSTranslationOption = atol((const char *)keyValueBuf);
	else
		m_DSTranslationOption = 0;

	// Read ReplacementChar Value
	keyValueLength = sizeof(m_DSReplacementChar);
	error = RegQueryValueEx (keyHandle,
	                   "ReplacementCharacter",
					   NULL,				// Reserved
					   &keyValueType,
					   (LPBYTE)m_DSReplacementChar,
					   &keyValueLength);
	if (error != ERROR_SUCCESS)
		m_DSReplacementChar[0] = '\0';

// Read select rowsets value
// It is internal parameter not exposed through the administrator, where we define the behavior for rowset or non-rowset

	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "SelectRowsets",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);

	if (error == ERROR_SUCCESS)
	{
		tempValue = atol((const char *)keyValueBuf);
		if (tempValue)
			m_DSSelectRowsets = TRUE;
		else
			m_DSSelectRowsets = FALSE;
	}
	else
		m_DSSelectRowsets = TRUE;

// Compression 

	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "Compression",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);

	if (error == ERROR_SUCCESS){
		if(_stricmp((const char *)keyValueBuf,SYSTEM_DEFAULT)==0){
				m_DSIOCompression = 0;
		}
		else if(_stricmp((const char *)keyValueBuf,"no compression")==0){
			m_DSIOCompression = COMP_NO_COMPRESSION;
		}
		else if(_stricmp((const char *)keyValueBuf,"best speed")==0){
			m_DSIOCompression = COMP_BEST_SPEED;
		}
		else if(_stricmp((const char *)keyValueBuf,"best compression")==0){
			m_DSIOCompression = COMP_BEST_COMPRESSION;
		}
		else if(_stricmp((const char *)keyValueBuf,"balance")==0){
			m_DSIOCompression = COMP_DEFAULT;
		}
		else{
			m_DSIOCompression = atol((const char *)keyValueBuf);
		}
	}
	else
		m_DSIOCompression = 0;

	//get threshold of compression ,default is 1000
	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx(keyHandle,
		"CompressionThreshold",
		NULL,				// Reserved
		&keyValueType,
		keyValueBuf,
		&keyValueLength);

	if (error == ERROR_SUCCESS)
	{
		if (strcmp((const char *)keyValueBuf, SYSTEM_DEFAULT) == 0)
			m_DSIOCompressionThreshold = IOCOMPRESSION_DEFAULT;
		else
		{
			m_DSIOCompressionThreshold = atol((const char *)keyValueBuf);
		}

	}
	else
		m_DSIOCompressionThreshold = IOCOMPRESSION_DEFAULT;

	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx(keyHandle,
						"RowsetErrorRecovery",
						NULL,
						&keyValueType,
						keyValueBuf,
						&keyValueLength);

	if (error == ERROR_SUCCESS)
	{
		if (atol((const char *)keyValueBuf))
			m_DSRowsetErrorRecovery = TRUE;
		else
			m_DSRowsetErrorRecovery = FALSE;
	}
	else
		m_DSRowsetErrorRecovery = TRUE;

	//Read the ServerDSN Value in unicode
	tmpWBuf[0] = L'\0';
	keyValueLength = sizeof(tmpWBuf);
	error = RegQueryValueExW (keyHandle,
	                   L"ServerDSN",
					   NULL,				// Reserved
					   &keyValueType,
					   (LPBYTE)tmpWBuf,
					   &keyValueLength);
	if (error != ERROR_SUCCESS)
		m_DSServerDSName[0] = '\0';
	transError[0] = '\0';
	//Convert ServerDSN Value to UTF-8
	if(wcslen((wchar_t*)tmpWBuf) > 0)
	{
		if (WCharToUTF8((wchar_t*) tmpWBuf, wcslen((wchar_t*)tmpWBuf), m_DSServerDSName, sizeof(m_DSServerDSName), &translen, transError) != SQL_SUCCESS)
		{
			strcat(transError, " :DataSource ServerDSName ");
			return  DS_TRANSLATION_ERROR;
		}
	}

	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx(keyHandle,
						"MapErrors",
						NULL,
						&keyValueType,
						keyValueBuf,
						&keyValueLength);

	if (error == ERROR_SUCCESS)
	{
		if (atol((const char *)keyValueBuf))
			GTransport.bMapErrors = TRUE;
		else
			GTransport.bMapErrors = FALSE;
	}
	else
		GTransport.bMapErrors = TRUE;

// FlushFetchData Y/N (default is N)
// It is internal parameter not exposed through the administrator,
// where we define the behavior for ATC query driver which cannot handle huge data being returned.

	keyValueLength = sizeof(keyValueBuf);
	error = RegQueryValueEx (keyHandle,
	                   "FlushFetchData",
					   NULL,				// Reserved
					   &keyValueType,
					   keyValueBuf,
					   &keyValueLength);

	if (error == ERROR_SUCCESS)
	{
		if (keyValueBuf[0] == 'N')
			m_DSFlushFetchData = FALSE;
		else
			m_DSFlushFetchData = TRUE;
	}
	else
		m_DSFlushFetchData = FALSE;

	//Read the ServiceName Value in unicode
	tmpWBuf[0] = L'\0';
	keyValueLength = sizeof(tmpWBuf);
	error = RegQueryValueExW (keyHandle,
	                   L"ServiceName",
					   NULL,				// Reserved
					   &keyValueType,
					   (LPBYTE)tmpWBuf,
					   &keyValueLength);
	if (error != ERROR_SUCCESS)
		m_DSServiceName[0] = '\0';
	//Convert ServiceName Value to UTF-8
	if(wcslen((wchar_t*)tmpWBuf) > 0)
	{
		if (WCharToUTF8((wchar_t*) tmpWBuf, wcslen((wchar_t*)tmpWBuf), m_DSServiceName, sizeof(m_DSServiceName), &translen, transError) != SQL_SUCCESS)
		{
			strcat(transError, " :DataSource ServiceName ");
			return  DS_TRANSLATION_ERROR;
		}
	}

	RegCloseKey( keyHandle);
	return ERROR_SUCCESS;
}

void CDataSource::updateDSValues(short DSNType, CONNECT_FIELD_ITEMS *connectFieldItems,
								 CONNECT_KEYWORD_TREE *keywordTree)
{
	long	tempValue;
	char	AttrValue[256];
	short	i;

	if (DSNType == DRIVER_KW_DSN)
		m_DSName[0] = '\0';
	strcpy(m_DSServer, connectFieldItems->server);
	strcpy(m_DSCatalog, connectFieldItems->catalog);
	strcpy(m_DSSchema, connectFieldItems->schema);
	
	for (i = KEY_SCHEMA+1 ; i < KEY_MAX ; i++)
	{
		if (keywordTree[i].AttrRank != 0)
		{
			strcpyUTF8(AttrValue, keywordTree[i].AttrValue, sizeof(AttrValue), keywordTree[i].AttrLength);
			switch (i)
			{
			case KEY_CTRLINFERNCHAR:
				tempValue = atol(AttrValue);
				if (tempValue)
					m_DSCtrlInferNCHAR = TRUE;
				else
					m_DSCtrlInferNCHAR = FALSE;
				break;
			case KEY_DATALANG:
				m_DSCharSet = atol(keywordTree[KEY_DATALANG].AttrValue);
				m_DSDataLang = m_DSCharSet;
				ODBCNLS_ValidateLanguage(&m_DSDataLang);
				break;
			case KEY_ERRORMSGLANG:
				m_DSErrorMsgLang = atol(AttrValue);
				ODBCNLS_ValidateLanguage(&m_DSErrorMsgLang);
				break;
			case KEY_FETCHBUFFERSIZE:
				if (_stricmp(AttrValue, SYSTEM_DEFAULT) == 0)
					m_DSFetchBufferSize = FETCH_BUFFER_SIZE_DEFAULT;
				else
					m_DSFetchBufferSize = atol(AttrValue);
				break;
			case KEY_SQL_ATTR_CONNECTION_TIMEOUT:
				if (_stricmp(AttrValue, SYSTEM_DEFAULT) == 0)
					m_DSConnectionTimeout = CONNECTION_TIMEOUT_DEFAULT;
				else
					m_DSConnectionTimeout = atol(AttrValue);
				break;
			case KEY_SQL_LOGIN_TIMEOUT:
				if (_stricmp(AttrValue, SYSTEM_DEFAULT) == 0)
					m_DSLoginTimeout = LOGIN_TIMEOUT_DEFAULT;
				else
					m_DSLoginTimeout = atol(AttrValue);
				break;
			case KEY_SQL_QUERY_TIMEOUT:
				if (_stricmp(AttrValue, SYSTEM_DEFAULT) == 0)
					m_DSQueryTimeout = QUERY_TIMEOUT_DEFAULT;
				else
					m_DSQueryTimeout = atol(AttrValue);
				break;
			case KEY_TRANSLATIONDLL:
				strcpyUTF8(m_DSTranslationDLL, AttrValue, sizeof(m_DSTranslationDLL));
				break;
			case KEY_TRANSLATIONOPTION:
				m_DSTranslationOption = atol(AttrValue);
				break;
			case KEY_REPLACEMENTCHAR:
				strcpyUTF8(m_DSReplacementChar, AttrValue, sizeof(m_DSReplacementChar));
				break;
			case KEY_SDSN:
				strcpyUTF8(m_DSServerDSName, AttrValue, sizeof(m_DSServerDSName));
				break;
			case KEY_SN:
				strcpyUTF8(m_DSServiceName, AttrValue, sizeof(m_DSServiceName));
				break;
			case KEY_SESSION:
				strcpyUTF8(m_DSSession, AttrValue, sizeof(m_DSSession));
				break;
			case KEY_APPLICATION:
				strcpyUTF8(m_DSApplication, AttrValue, sizeof(m_DSApplication));
				break;
			case KEY_ROLENAME:
				strcpyUTF8(m_DSRoleName, AttrValue, sizeof(m_DSRoleName));
				break;
			case KEY_CERTIFICATEDIR:
				strcpyUTF8(m_DSCertificateDir, AttrValue, sizeof(m_DSCertificateDir));
				break;
			case KEY_CERTIFICATEFILE:
				strcpyUTF8(m_DSCertificateFile, AttrValue, sizeof(m_DSCertificateFile));
				break;
			case KEY_CERTIFICATEFILE_ACTIVE:
				strcpyUTF8(m_DSCertificateFileActive, AttrValue, sizeof(m_DSCertificateFileActive));
				break;
			case KEY_COMPRESSION:
				if(_stricmp(AttrValue,SYSTEM_DEFAULT)==0){
					m_DSIOCompression = 0;
				}
				else if(_stricmp(AttrValue,"no compression")==0){
					m_DSIOCompression = COMP_NO_COMPRESSION;
				}
				else if(_stricmp(AttrValue,"best speed")==0){
					m_DSIOCompression = COMP_BEST_SPEED;
				}
				else if(_stricmp(AttrValue,"best compression")==0){
					m_DSIOCompression = COMP_BEST_COMPRESSION;
				}
				else if(_stricmp(AttrValue,"balance")==0){
					m_DSIOCompression = COMP_DEFAULT;
				}
				else{
					m_DSIOCompression = atol(AttrValue);
				}
				break;
			case KEY_COMPRESSIONTHRESHOLD:
				if (stricmp(AttrValue, SYSTEM_DEFAULT) == 0){
					  m_DSIOCompressionThreshold = IOCOMPRESSION_DEFAULT;
				}
				else
				{
				         m_DSIOCompressionThreshold = atol((const char *)AttrValue);
				}
				break;
			default:
				break;
			}
		}
	}
}
