SQLRETURN ODBC::GetDiagField(SQLSMALLINT HandleType, 
				SQLHANDLE Handle,
				SQLSMALLINT RecNumber, 
				SQLSMALLINT DiagIdentifier,
				SQLPOINTER DiagInfo, 
				SQLSMALLINT BufferLength,
				SQLSMALLINT *StringLengthPtr)
{
	SQLRETURN rc;
	DWORD	ErrorMsgLang = 0;
	CConnect* pConnect;
	CStmt* pStmt;
	CDesc* pDesc;
	
	switch (HandleType)
	{
	case SQL_HANDLE_ENV:
		break;
	case SQL_HANDLE_DBC:
		pConnect = (CConnect*)Handle;
		EnterCriticalSection(&pConnect->m_CSObject);
		ErrorMsgLang = pConnect->getErrorMsgLang();
		break;
	case SQL_HANDLE_STMT:
		pStmt = (CStmt *)Handle;
		pConnect = pStmt->getConnectHandle();
		EnterCriticalSection(&pConnect->m_CSObject);
		ErrorMsgLang = pStmt->getErrorMsgLang();
		break;
	case SQL_HANDLE_DESC:
		pDesc = (CDesc *)Handle;
		pConnect = pDesc->getDescConnect();
		EnterCriticalSection(&pConnect->m_CSObject);
		ErrorMsgLang = pDesc->getErrorMsgLang();
		break;
	default:
		return SQL_INVALID_HANDLE;
	}
	__try{
		rc = ((CHandle *)Handle)->GetDiagField(HandleType, Handle, RecNumber, 
					ErrorMsgLang, DiagIdentifier, DiagInfo, BufferLength, StringLengthPtr);
	}
	__finally {
		switch (HandleType)
		{
			case SQL_HANDLE_ENV:
				break;
			case SQL_HANDLE_DBC:
				LeaveCriticalSection(&pConnect->m_CSObject);
				break;
			case SQL_HANDLE_STMT:
				LeaveCriticalSection(&pConnect->m_CSObject);
				break;
			case SQL_HANDLE_DESC:
				LeaveCriticalSection(&pConnect->m_CSObject);
				break;
		}
	}
	return rc;
}
SQLRETURN  ODBC::EndTran(SQLSMALLINT HandleType, 
				SQLHANDLE Handle,
				SQLSMALLINT CompletionType)
{
	SQLRETURN rc;
	DWORD	ErrorMsgLang = 0;
	CConnect* pConnect;

	switch (HandleType)
	{
	case SQL_HANDLE_ENV:	// DM implments by sending SQLEndTran for every active connection
		rc = SQL_INVALID_HANDLE;
		break;
	case SQL_HANDLE_DBC:
		pConnect = (CConnect*)Handle;
		EnterCriticalSection(&pConnect->m_CSObject);
		ErrorMsgLang = pConnect->getErrorMsgLang();
		rc = pConnect->EndTran(CompletionType);
		LeaveCriticalSection(&pConnect->m_CSObject);
		break;
	default:
		return SQL_INVALID_HANDLE;
	}
	return rc;
}
SQLRETURN ODBC::GetDiagRec(SQLSMALLINT HandleType, 
				SQLHANDLE Handle,
				SQLSMALLINT RecNumber,
				SQLWCHAR *Sqlstate,
				SQLINTEGER *NativeError, 
				SQLWCHAR *MessageText,
				SQLSMALLINT BufferLength, 
				SQLSMALLINT *TextLength)
{

	SQLRETURN rc;
	DWORD	ErrorMsgLang = 0;
	CConnect* pConnect;
	CStmt* pStmt;
	CDesc* pDesc;
	
	switch (HandleType)
	{
	case SQL_HANDLE_ENV:
		break;
	case SQL_HANDLE_DBC:
		pConnect = (CConnect*)Handle;
		EnterCriticalSection(&pConnect->m_CSObject);
		ErrorMsgLang = pConnect->getErrorMsgLang();
		break;
	case SQL_HANDLE_STMT:
		pStmt = (CStmt *)Handle;
		pConnect = pStmt->getConnectHandle();
		EnterCriticalSection(&pConnect->m_CSObject);
		ErrorMsgLang = pStmt->getErrorMsgLang();
		break;
	case SQL_HANDLE_DESC:
		pDesc = (CDesc *)Handle;
		pConnect = pDesc->getDescConnect();
		EnterCriticalSection(&pConnect->m_CSObject);
		ErrorMsgLang = pDesc->getErrorMsgLang();
		break;
	default:
		return SQL_INVALID_HANDLE;
	}
	__try{
		rc = ((CHandle *)Handle)->GetDiagRec(HandleType, Handle, 
					RecNumber, ErrorMsgLang, Sqlstate, NativeError, MessageText, BufferLength, TextLength);
	}
	__finally {
		switch (HandleType)
		{
			case SQL_HANDLE_ENV:
				break;
			case SQL_HANDLE_DBC:
				LeaveCriticalSection(&pConnect->m_CSObject);
				break;
			case SQL_HANDLE_STMT:
				LeaveCriticalSection(&pConnect->m_CSObject);
				break;
			case SQL_HANDLE_DESC:
				LeaveCriticalSection(&pConnect->m_CSObject);
				break;
		}
	}
	return rc;
}