// TransportSocketClient.cpp: implementation of the CtransportSocketClient class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include <apl_gui.h>
#include <aplBaseLib.h>
#include <aplKerberos.h >
#include <sl_struct.h>

#include "TransportSocketClient.h"
#include "aplNetStepData.h"
#include "ErrMessCl.h" 
#include "DlgErrRepeat.h"


extern CString m_VerCli;
extern CString m_AppName;
extern CaplLog m_MainLog;
extern CString globalRequestedMainLicense;
extern CStringArray globalRequestedAddLicenses;



bool prev_ping = true;
int num_prev_ping=3;

// флаг автоматически восстанавливать соединение при разрыве
bool AutoReconnect = false;

#include "Servises.h"


#define LogErrorWF(ErrMess) m_MainLog.LogMessage(ErrMess,false,true,true,false,0,m_class_info,0,_T(__FILE__),_T(__DATE__),__LINE__)
#define LogMessWF(ErrMess) m_MainLog.LogMessage(ErrMess,true,true,true,true,0,m_class_info,0,_T(__FILE__),_T(__DATE__),__LINE__)

void ResetTimer(int mode = 0,LPVOID lpParameter = 0);

// буфер версии 2 может включать CaplDataBuf вплоть до 256 байт 
// первый байт - размер, далее данные

void GlobalClose(LPVOID param)
{
	if(param== 0)return;
	((CTransportSocketClient*)(param))->m_isGlobalClose = true;
	((CTransportSocketClient*)(param))->OnClose();
}

void GlobalReconnect(LPVOID param)
{
	if(param== 0)return;
	((CTransportSocketClient*)(param))->m_internal_reconnect=2;
	((CTransportSocketClient*)(param))->ForceReconnect();
}

UINT RenewClientStateOnServer(LPVOID lpParameter);

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////



CTransportSocketClient::CTransportSocketClient(CaplNetStepData *data)
{
	ASSERT(data!=0);
	m_aplSocket = 0;
	m_last_calling = _T("");
	m_server_stopping = false;
	m_need_relogin = false;
	m_temp_socket = 0;
	m_used_version=VERSION_OF_RPC_BUFFER_4;

	m_TickStop = 0;

	m_aplError = APL_NET_OK;
	m_ascError=ASC_NO_ERROR;
	m_wsaError = 0;
	m_is_saved_login = false;
	m_num_auto_repeat=30;
	m_timer_auto_repeat=10;
	m_description_serv_error = _T("");
	m_class_info = _T("");
	m_CompName = _T("");
	
	m_need_reconnect = false;
	m_tmp_buf.SetSize(20);

	m_dlg_reconnect = 0;
	
	m_data = data;
	m_hide_mode = data->m_hide_mode;
	m_application_reconnect_text = _T("");
	m_application_close_funct = 0;

	m_am_user = _T("");
	m_am_pwd = _T("");
	m_am_code1 = 0;
	m_am_code2 = 0;

	m_thread_id = 0;
	m_tick_op = 0;
	m_parent_wnd = 0;
	m_internal_reconnect = 0;
	m_isGlobalClose = false;
	m_IsServer4AddLic = false;

	m_event_TempStore=CreateEvent(0,TRUE,TRUE,0);
	InitializeCriticalSection(&m_CS_TempStore);

	m_cif = new CConnectInfo();
	m_def_server_name = _T("");

	m_tick_repeated_mess_time.Zero();
}

CTransportSocketClient::~CTransportSocketClient()
{
	DeleteCriticalSection(&m_CS_TempStore);
	CloseHandle(m_event_TempStore);
	CloseReconnectDlg();
	delete m_cif;
}

void CTransportSocketClient::CloseReconnectDlg()
{
	if(m_dlg_reconnect != 0)
	{
		if(m_dlg_reconnect->m_hWnd != 0)
			m_dlg_reconnect->EndDialog(0);
		delete m_dlg_reconnect;
		m_dlg_reconnect = 0;
	}
}

// !!! здесь специально const char* для совместимости с ansi сервером  
AplNetErrors CTransportSocketClient::TestParamIdent(CaplDataBuf &dbuf, FuctionCodes code, const char* _param_def)
{
	// !!! здесь специально char* для совместимости с ansi сервером  
	char* param_cur = 0;;

	int version_test = 0;
	DWORD code_test=AplCommand;
	bool ret = true;
	int size = 0;
	CStringA param_def = _param_def;

	dbuf.Read(&version_test, 4);
	if(version_test != VERSION_OF_RPC_BUFFER && version_test != VERSION_OF_RPC_BUFFER_2 
			&& version_test != VERSION_OF_RPC_BUFFER_3 && version_test != VERSION_OF_RPC_BUFFER_4)
	{
		return APL_SOCK_MISSED_VERSION;
	}
	dbuf.Read(&code_test, 4);
	if(code_test == AplCommand)
	{
		dbuf.Read(&code_test, 4);
		if(code_test == RPCError)
		{
			// Читаем код функции, в котороы ошибка
			dbuf.Read(&code_test,4);
			if(code_test != code && code_test != 0)return APL_SOCK_MISSED_FUNCTION;
			// Читаем код ошибки
			dbuf.Read(&code_test, 4);
			return (AplNetErrors)code_test;
		}
		else
		{
			return APL_SOCK_MISSED_COMMAND;
		}
	}
	else
	{
		if(code_test != code)return APL_SOCK_MISSED_FUNCTION;
		ret=dbuf.Read(&size);
		if(ret)
		{
			if(size == 0)
			{
				ret = (param_def.GetLength() == 0);
			}
			else
			{
				param_cur = new char[size+1];
				ret=dbuf.Read(param_cur,size);
				param_cur[size] = 0;
				if(ret)
				{
					ret = (param_def == param_cur);
				}
				delete []param_cur;
			}
		}
		if(ret)return APL_NET_OK;
	}
	return APL_SOCK_MISSED_FUNCTION;
}

// !!! здесь специально const char* для совместимости с ansi сервером  
bool CTransportSocketClient::FillStdHeader(CaplDataBuf &dbuf, FuctionCodes code, const char* param_cur)
{
	dbuf.Clear();
	dbuf.Add(&m_used_version,4);
	dbuf.Add(&code, 4);
	// длина строки описания параметров
	int len = strlen(param_cur);
	dbuf.Add(&len, 4);
	// сама строка
	dbuf.Add((void*)param_cur, len);
	return true;

}//bool CTransportSocketClient::FillStdHeader(CaplDataBuf &dbuf,FuctionCodes code,CString param_cur,AplNetErrors err_code){


bool CTransportSocketClient::Call(CaplDataBuf &dbuf, CaplDataBuf *dbuf_ext, bool can_break, bool pause_wait_dlg, bool wait_answer, bool can_reconnect)
{
	void *data = 0, *data_ext = 0;
	DWORD length = 0, length_ext = 0;
	bool ret;
	int counter = 0;
	CaplSocketClient* tempSocket = 0;

	if(m_aplSocket== 0) return false;

	if(m_dlg_reconnect != 0) return true;

	length = dbuf.m_Size;
	data = dbuf.GetBuffer();
	
	if(dbuf_ext != 0)
	{
		data_ext = dbuf_ext->GetBuffer();
		length_ext = dbuf_ext->m_Size;
	}

	CaplTimeMeter t1;

	do{
		if(m_aplSocket == 0) break;;

		tempSocket = m_aplSocket;
		t1.Start();
		m_aplSocket->m_parent_wnd = m_parent_wnd;
		ret=m_aplSocket->Call(&data, length, data_ext, length_ext, can_break, pause_wait_dlg, wait_answer, true);
		m_tick_op += t1.GetTickDelta();

		if(ret) break;

		if(tempSocket != m_aplSocket)
		{
			// внутри вызова Call в диалоге обработался OnClose и был выполнен
			// Reconnect. Есть надежда, что связь восстановлена. Повторим Call
			if(m_aplSocket == 0)
			{
				LogMessWF( APL_T("Не удалось восстановить соединение."));
				break;//увы, связь точно не восстановлена...
			}
			LogMessWF( APL_T("Соединение восстановлено. Повторяем операцию."));
			continue;

		}
		
		// сохраняем коды текущих ошибок
		m_ascError = m_aplSocket->GetLastAscError();
		m_wsaError = m_aplSocket->GetLastWsaError();

		if(can_reconnect && 
			(m_wsaError == WSAECONNABORTED || m_wsaError == WSAECONNRESET || m_wsaError == WSAENOTCONN ||
							m_wsaError == WSAESHUTDOWN || m_wsaError == WSAECONNREFUSED || m_wsaError == WSAEFAULT || m_wsaError == WSAENOTSOCK || m_wsaError == WSAENETDOWN ||
							m_wsaError == WSAENETUNREACH || m_wsaError == WSAENETRESET || m_wsaError == WSAEHOSTDOWN || m_wsaError == WSANOTINITIALISED || m_wsaError == WSAECANCELLED ))
		{
			counter++;
			Disconnect();
			Reconnect(false,_T(__FILE__),__LINE__,_T(__DATE__));
			if(counter >= 5) break;
		}
		else
		{
			break;
		}
	}while(true);

	dbuf.Clear();
	if(GetLastAscError() == ASC_NO_ERROR)
	{
		// После успешного Call в data уже новый буфер с новыми данными
		if(dbuf.GetBuffer() != data)
			dbuf.AttachExternalData(data, length);
		m_aplError = APL_NET_OK;
		return true;
	}
	else
	{
		if(m_aplSocket == 0)
		{
			m_aplError = APL_SOCK_CONNECT_FAULT;
		}
		else
		{
			if(m_aplSocket->GetLastAscError() == ASC_ERROR_PROCESSED_ON_SERVER ||
				m_aplSocket->GetLastAscError() == ASC_TOO_MANY_CLIENTS_ON_SERVER ||
				m_aplSocket->GetLastAscError() == ASC_ERROR_INIT_SERVER ||
				m_aplSocket->GetLastAscError() == ASC_MISSED_RECEIVE_SIZE_ON_SERVER)
			{
				m_aplError =( AplNetErrors)APL_NET_SRV_ERROR_PROCESSED;
			}
			else if(m_aplSocket->GetLastAscError() == ASC_BREAK_CALL)
			{
				m_aplError =( AplNetErrors)APL_NET_CLI_BREAK;
			}
			else
			{
				m_aplError = (AplNetErrors)APL_NET_CLI_NET_ERROR;
			}
		}
	}
	if(GetLastAscError() != ASC_OPERATION_IN_PROGRESS)
	{
		ClearInternalData();
	}
	else
	{
		m_aplError = APL_SOCK_OPERATION_IN_PROGRESS;
	}
	return false;
}

ASC_ERROR_CODES CTransportSocketClient::GetLastAscError()
{
	if(m_aplSocket != 0)
	{
		return m_aplSocket->GetLastAscError();
	}
	else
	{
		return m_ascError;
		//return ASC_ERROR_SOCKET_CLOSE;
	}
	return ASC_NO_ERROR;
}

// !!! второй параметр макроса - const char* для совместимости с ansi сервером 
#define CALL_WITH_TEST_PARAM(funct_code, param_description)\
	m_last_calling = __APL_FUNC__; \
	if(!Call(m_TempStore, dbuf_ext)){aplError=m_aplError; EnterCriticalSection(&m_CS_TempStore); SetEvent(m_event_TempStore); LeaveCriticalSection(&m_CS_TempStore); return false;}\
	aplError = TestParamIdent(m_TempStore, funct_code, param_description);\
	if(aplError != APL_NET_OK){ClearInternalData(); return false;}

#define INIT_DATA_P_VAR(dbuf_work) \
	aplError=APL_NET_OK;CDlgErrRepeat dlg_err_repeat; int res = 0; int count=m_num_auto_repeat;\
	CString add_err_text = _T(""); dlg_err_repeat.m_timer_auto_repeat=m_timer_auto_repeat;\
	CaplDataBuf dbuf_add; CaplDataBuf* dbuf_ext = 0; dbuf_work.Clear(); int size_add = 0; BYTE can_repeat = 0; BYTE is_warning_data = 0; m_description_serv_error = _T("");\
	FuctionCodes code=AplCommand; CStringA fparam_type = "";

// !!! второй параметр макроса - const char* для совместимости с ansi сервером 
#define INIT_DATA_P_DEF(code_funct, params)\
	if(!IsConnected()){aplError=APL_NET_SRV_NOT_CONNECT;\
	if(GetLastAscError()==ASC_ERROR_SOCKET_CLOSE){aplError=(AplNetErrors)APL_NET_CLI_NET_ERROR;};return false;}\
	if(IsOperated()){aplError=APL_SOCK_OPERATION_IN_PROGRESS;return false;}\
	if(!TestTempStoreFree(true)){aplError=APL_SOCK_OPERATION_IN_PROGRESS;return false;}\
	code=code_funct; fparam_type=params;

// !!! второй параметр макроса - const char* для совместимости с ansi сервером 
#define INIT_DATA(code_funct,params)\
	if(m_TickStop > GetTickCount()){return false;}else{m_TickStop=0;}\
	INIT_DATA_P_VAR(m_TempStore) \
	INIT_DATA_P_DEF(code_funct,params)

// !!! второй параметр макроса - const char* для совместимости с ansi сервером 
#define INIT_DATA_D(code_funct,params)\
	CDlgErrRepeat dlg_err_repeat;int res = 0;int count=m_num_auto_repeat;\
	CString add_err_text = _T("");dlg_err_repeat.m_timer_auto_repeat=m_timer_auto_repeat;\
	if(!IsConnected()){aplError=APL_NET_SRV_NOT_CONNECT;\
	if(GetLastAscError()==ASC_ERROR_SOCKET_CLOSE){aplError=(AplNetErrors)APL_NET_CLI_NET_ERROR;};return false;}\
	if(IsOperated()){aplError=APL_SOCK_OPERATION_IN_PROGRESS;return false;}\
	CaplDataBuf dbuf,dbuf_add; dbuf.m_ansi_string = m_data->m_global_ansi_string; CaplDataBuf* dbuf_ext = 0; int size_add = 0; BYTE can_repeat = 0;\
	BYTE is_warning_data = 0; m_description_serv_error = _T(""); FuctionCodes code=code_funct; CStringA fparam_type=params;




#define WRITE_ADDITIONAL_BUF_DEF_BUF(dbuf) \
	FillStdHeader(dbuf, code, fparam_type);\
	if(m_used_version >= VERSION_OF_RPC_BUFFER_2){\
		dbuf.Add(&size_add, 1);\
		if(size_add>0){ dbuf.Add(dbuf_add.GetBuffer(), size_add); }}\
	if(m_used_version >= VERSION_OF_RPC_BUFFER_4) {AddSource2Dbuf(dbuf);}


#define WRITE_ADDITIONAL_BUF   WRITE_ADDITIONAL_BUF_DEF_BUF(m_TempStore)


#ifdef _UNICODE

#define TEST_READ_SERV_ERR(readed_data_buf) \
	readed_data_buf.Read(&size_add,1);/*длина серверного сообщения об ошибке*/\
	if(size_add>0){\
		if(m_data->m_global_ansi_string ){\
			char* cb  =new char[size_add]; readed_data_buf.Read(cb,size_add); dbuf_add.Add(cb, size_add);\
			CaplStringAdapter str_ad(cb); m_description_serv_error = (TCHAR*)str_ad; delete[] cb;/*сообщение об ошибке*/\
		}else{\
			TCHAR* cb=new TCHAR[size_add]; readed_data_buf.Read(cb, size_add*sizeof(TCHAR));dbuf_add.Add(cb, size_add*sizeof(TCHAR));\
			m_description_serv_error = cb;delete[] cb;/*сообщение об ошибке*/\
		}\
	}

#else // #ifdef _UNICODE

#define TEST_READ_SERV_ERR(readed_data_buf) \
	readed_data_buf.Read(&size_add,1);/*длина серверного сообщения об ошибке*/\
	if(size_add>0){char* cb=new char[size_add];readed_data_buf.Read(cb,size_add);dbuf_add.Add(cb,size_add);\
	m_description_serv_error=cb;delete[] cb;/*сообщение об ошибке*/\
	}

#endif // #ifdef _UNICODE


#define READ_ERR__ADDITIONAL_BUF ReadErrAdditionalBuf(m_TempStore, dbuf_add, aplError, is_warning_data, can_repeat);

#define READ_ERR__ADDITIONAL_BUF_D  ReadErrAdditionalBuf(dbuf, dbuf_add, aplError, is_warning_data, can_repeat);

void CTransportSocketClient::ReadErrAdditionalBuf(CaplDataBuf &dbuf, CaplDataBuf &dbuf_add, AplNetErrors &aplError, BYTE &is_warning_data, BYTE &can_repeat)
{
	BYTE size_add;
	dbuf.Read(&aplError,4);
	dbuf_add.Clear();
	if(m_used_version>=VERSION_OF_RPC_BUFFER_2)
	{
		dbuf.Read(&size_add,1);/*была ли ошибка*/
		if(size_add>0)
			dbuf.Read(&can_repeat,1); // флаг возможности повтора операции по запросу клиента

		if(m_used_version>=VERSION_OF_RPC_BUFFER_3 && size_add>0)
			dbuf.Read(&is_warning_data,1); // флаг некритических ошибок при чтении данных
		
		TestReadServError(dbuf, m_data, m_description_serv_error);
	}
}

#define CHECK_REPEAT \
	if(is_warning_data>0)\
	{	CString text = APL_T("При чтении данных возникли ошибки; возможно, часть данных утеряна. Подробности см. лог на сервере.");\
		LogMessWF(text);if(!m_hide_mode && !m_tick_repeated_mess_time.CheckTimeOut(1000)){ AfxMessageBox(text, MB_ICONERROR); m_tick_repeated_mess_time.Start(); } }\
if(APL_ERROR_CONDITION){\
	ClearInternalData(); count++;\
	if(count < m_num_auto_repeat && dlg_err_repeat.m_DontAsk == TRUE){add_err_text.Format( APL_T("\r\nОперация выполнена неудачно %i раз подряд!"), m_num_auto_repeat); continue;}\
	if(can_repeat == 1 && !m_hide_mode){\
		CaplSetResourceHandle res_handle(module_inst);\
		dlg_err_repeat.m_ErrMess = APL_NET_ERROR2char(aplError) + _T("\r\n") + add_err_text + APL_T("\r\nПовторить операцию?");\
		res = dlg_err_repeat.DoModal();\
		if(res == ID_REPEAT){ count = 0; continue; }else{ if(res == IDSTOP){m_TickStop = GetTickCount() + APL_ERROR_STOP_TIME;} break;}\
	}else{ break; }\
}else{break;}


bool CTransportSocketClient::ABO_DCQueryListBase(/*[out]*/ AplNetErrors &aplError, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplBaseOperations__QueryListBase,"")
	do{
		m_used_version = VERSION_OF_RPC_BUFFER_3;
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

bool CTransportSocketClient::ABO_DCGetLicenseStatus(/*[out]*/ AplNetErrors &aplError, CString &status ,/*[out]*/UINT32 *ServerCode)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplBaseOperations__GetLicenseStatus,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		int ResultSize=0;
		m_TempStore.Add(&ResultSize,4);
		CALL_WITH_TEST_PARAM(code,"lbl");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	m_TempStore.ReadStrBuf(status);
	m_TempStore.Read(ServerCode,4);
	ClearInternalData();
	return true;
}



bool CTransportSocketClient::ABO_DCLockServ(/*[out]*/ AplNetErrors &aplError)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplBaseOperations__LockServ,"");
	WRITE_ADDITIONAL_BUF;
	CALL_WITH_TEST_PARAM(code,"");
	READ_ERR__ADDITIONAL_BUF;
	ClearInternalData();
	return true;
}


// Удаление итератора вместе с файлом
bool CTransportSocketClient::AT_DCDeleteIterator(/*[out]*/ AplNetErrors &aplError,int inst_id,int attr_id)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__DeleteIteratorEx,"ll");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&inst_id,4);
		m_TempStore.Add(&attr_id,4);
		// CALL_WITH_TEST_PARAM(code,""); - здесь более умная обработка с вызовом старой функции, если надоть
		m_last_calling = __APL_FUNC__;
		if(!Call(m_TempStore,dbuf_ext))
		{
			aplError=m_aplError;return false;
		}
		else
		{
			aplError=TestParamIdent(m_TempStore,code,"");
			if(aplError==APL_SOCK_MISSED_FUNCTION)
			{
				ClearInternalData();

				// !!! типы параметров  - char* для совместимости с ansi сервером 
				// INIT_DATA(CAplTransport__DeleteIterator,""); - категорически нельзя! Иначе переопределяются переменные типа dbuf!
				code=CAplTransport__DeleteIterator;
				fparam_type = _T("");
				do{
					WRITE_ADDITIONAL_BUF;
					CALL_WITH_TEST_PARAM(code,"");
					READ_ERR__ADDITIONAL_BUF;
					CHECK_REPEAT;
				}while (true);
				break;
			}
			else
			{
				if(aplError!=APL_NET_OK){ClearInternalData();return false;}
				READ_ERR__ADDITIONAL_BUF;
				CHECK_REPEAT;
			}
		}

	}while (true);

	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

// Отсоединение итератора от блоба
bool CTransportSocketClient::AT_DCCloseIterator(/*[out]*/ AplNetErrors &aplError)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__CloseIterator,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

// Чтение из блоба, присоединенного к итератору
bool CTransportSocketClient::AT_DCReadFromIterator(/*[out]*/ AplNetErrors &aplError,
												   /*[in,out]*/ UINT32 *SizeDose, /*[out,size_is(SizeDose)]*/ BYTE *Dose,
												   /*[out]*/ UINT32 *LastDose)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__ReadFromIterator,"l");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(SizeDose,4);
		CALL_WITH_TEST_PARAM(code,"lbl");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	m_TempStore.Read(SizeDose,4);
	m_TempStore.Read(Dose,*SizeDose);
	m_TempStore.Read(LastDose,4);
	ClearInternalData();
	return true;
}

// Запись в блоб, присоединенный к итератору
bool CTransportSocketClient::AT_DCWriteToIterator(/*[in,out]*/ AplNetErrors &aplError,
												  /*[in]*/ UINT32 SizeDose,/*[in,size_is(SizeDose)]*/ BYTE *Dose,
												  /*[in]*/ UINT32 LastDose)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__WriteToIterator,"lbl");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&SizeDose,4);
		m_TempStore.Add(Dose,SizeDose);
		m_TempStore.Add(&LastDose,4);
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}
// Присоединение к итератору существующего БЛОБа или вновь созданного
bool CTransportSocketClient::AT_DCSaveBlob2Srv(/*[in,out]*/ AplNetErrors &aplError,
								/*[in]*/ UINT32 SizeNameBLOB,/*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,
								/*[in]*/ UINT32 SizeNameFile,/*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__SaveBlob2Disk,"lblb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&SizeNameBLOB,4);
		m_TempStore.Add(NameBLOB,SizeNameBLOB);
		m_TempStore.Add(&SizeNameFile,4);
		m_TempStore.Add(NameFile,SizeNameFile);
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	ClearInternalData();
	return true;
}

// Присоединение к итератору существующего БЛОБа или вновь созданного
bool CTransportSocketClient::AT_DCReadBlobFromSrv(/*[in,out]*/ AplNetErrors &aplError,
								/*[in]*/ UINT32 *SizeNameBLOB,/*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,
								/*[in]*/ UINT32 SizeNameFile,/*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile,
								/*[in,out*/UINT32 *SizeBLOB)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__ReadBlobFromSrv,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&SizeNameFile,4);
		m_TempStore.Add(NameFile,SizeNameFile);
		CALL_WITH_TEST_PARAM(code,"lbl");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	m_TempStore.Read(SizeNameBLOB,4);
	m_TempStore.Read(NameBLOB,*SizeNameBLOB);
	m_TempStore.Read(SizeBLOB,4);
	ClearInternalData();
	return true;
}

// Присоединение к итератору существующего БЛОБа или вновь созданного
bool CTransportSocketClient::AT_DCReadBlobFromSrv64(/*[in,out]*/ AplNetErrors &aplError,
								/*[in]*/ UINT32 *SizeNameBLOB,/*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,
								/*[in]*/ UINT32 SizeNameFile,/*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile,
								/*[in,out*/__int64 *SizeBLOB)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__ReadBlobFromSrv64,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&SizeNameFile,4);
		m_TempStore.Add(NameFile,SizeNameFile);
		CALL_WITH_TEST_PARAM(code,"lbl");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	m_TempStore.Read(SizeNameBLOB,4);
	m_TempStore.Read(NameBLOB,*SizeNameBLOB);
	m_TempStore.Read(SizeBLOB,8);
	ClearInternalData();
	return true;
}

// Присоединение к итератору существующего БЛОБа или вновь созданного
bool CTransportSocketClient::AT_DCCreateIterator(/*[in,out]*/ AplNetErrors &aplError,
								/*[in]*/ UINT32 *SizeNameBLOB,/*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,
								/*[in]*/ UINT32 SizeNameFile,/*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile,
								/*[in]*/ UINT32 *SizeDose,/*[in,out*/UINT32 *SizeBLOB,
								/*[in]*/ UINT32 inst_id, /*[in,out*/ int crc32)
{
	bool funct_ex = (0 != inst_id || 0 != crc32);
	INIT_DATA_P_VAR(m_TempStore);

	do{
		if(funct_ex)
		{
			// !!! типы параметров  - char* для совместимости с ansi сервером 
			INIT_DATA_P_DEF(CAplTransport__CreateIteratorEx,"lblblllb");
		}
		else
		{
			// !!! типы параметров  - char* для совместимости с ansi сервером 
			INIT_DATA_P_DEF(CAplTransport__CreateIterator,"lblbll");
		}
		do{
			WRITE_ADDITIONAL_BUF;
			m_TempStore.Add(SizeNameBLOB,4);
			m_TempStore.Add(NameBLOB,*SizeNameBLOB);
			m_TempStore.Add(&SizeNameFile,4);
			m_TempStore.Add(NameFile,SizeNameFile);
			m_TempStore.Add(SizeDose,4);
			m_TempStore.Add(SizeBLOB,4);
			if(funct_ex)
			{
				// сначала размер буфера с параметрами. Не паримся с CaplDbuf, для версии 1 это три числа по 4 байта
				int size_buf_param = 4*3;
				m_TempStore.Add(&size_buf_param,4);
				// версия доп параметров
				int ver_buf_param = 1;
				m_TempStore.Add(&ver_buf_param,4);
				// и два параметра
				m_TempStore.Add(&inst_id,4);
				m_TempStore.Add(&crc32,4);
			}
			CALL_WITH_TEST_PARAM(code,"lbl");
			READ_ERR__ADDITIONAL_BUF;
			CHECK_REPEAT;
		}while (true);
		if(funct_ex && APL_SOCK_MISSED_FUNCTION == aplError)
		{
			ClearInternalData();
			funct_ex = false;
			continue;
		}

		if(APL_ERROR_CONDITION)
		{
			ClearInternalData();
			return false;
		}
		m_TempStore.Read(SizeNameBLOB,4);
		m_TempStore.Read(NameBLOB,*SizeNameBLOB);
		m_TempStore.Read(SizeBLOB,4);
	}while(false);

	ClearInternalData();
	return true;
}



// Присоединение к итератору существующего БЛОБа или вновь созданного
bool CTransportSocketClient::AT_DCCreateIterator64(/*[in,out]*/ AplNetErrors &aplError,
								/*[in]*/ UINT32 *SizeNameBLOB,/*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,
								/*[in]*/ UINT32 SizeNameFile,/*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile,
								/*[in]*/ UINT32 *SizeDose,/*[in,out*/__int64 *SizeBLOB,
								/*[in]*/ UINT32 inst_id, /*[in,out*/ int crc32)
{
	bool funct_ex = (0 != inst_id || 0 != crc32);
	INIT_DATA_P_VAR(m_TempStore);

	do{
		if(funct_ex)
		{
			// !!! типы параметров  - char* для совместимости с ansi сервером 
			INIT_DATA_P_DEF(CAplTransport__CreateIteratorEx64,"lblblllb");
		}
		else
		{
			// !!! типы параметров  - char* для совместимости с ansi сервером 
			INIT_DATA_P_DEF(CAplTransport__CreateIterator64,"lblbll");
		}
		do{
			WRITE_ADDITIONAL_BUF;
			m_TempStore.Add(SizeNameBLOB,4);
			m_TempStore.Add(NameBLOB,*SizeNameBLOB);
			m_TempStore.Add(&SizeNameFile,4);
			m_TempStore.Add(NameFile,SizeNameFile);
			m_TempStore.Add(SizeDose,4);
			m_TempStore.Add(SizeBLOB,8);
			if(funct_ex)
			{
				// сначала размер буфера с параметрами. Не паримся с CaplDbuf, для версии 1 это три числа по 4 байта
				int size_buf_param = 4*3;
				m_TempStore.Add(&size_buf_param,4);
				// версия доп параметров
				int ver_buf_param = 1;
				m_TempStore.Add(&ver_buf_param,4);
				// и два параметра
				m_TempStore.Add(&inst_id,4);
				m_TempStore.Add(&crc32,4);
			}

			// CALL_WITH_TEST_PARAM(code,"lbl");
			m_last_calling = __APL_FUNC__;
			if(!Call(m_TempStore,dbuf_ext))
			{	
				aplError=m_aplError;
				EnterCriticalSection(&m_CS_TempStore);
				SetEvent(m_event_TempStore);
				LeaveCriticalSection(&m_CS_TempStore);
				return false;
			}
			aplError=TestParamIdent(m_TempStore,code,"lbl");
			if(funct_ex && APL_SOCK_MISSED_FUNCTION == aplError) break;
			if(aplError!=APL_NET_OK){ClearInternalData();return false;}

			READ_ERR__ADDITIONAL_BUF;
			CHECK_REPEAT;
		}while (true);
		if(funct_ex && APL_SOCK_MISSED_FUNCTION == aplError)
		{
			ClearInternalData();
			funct_ex = false;
			continue;
		}

		if(APL_ERROR_CONDITION)
		{
			ClearInternalData();
			return false;
		}
		memset(NameBLOB, 0, *SizeNameBLOB);
		m_TempStore.Read(SizeNameBLOB,4);
		m_TempStore.Read(NameBLOB,*SizeNameBLOB);
 		m_TempStore.Read(SizeBLOB,8);
		ClearInternalData();
		break;
	}while(true);

	return true;
}

//  Присоединение к итератору для чтения нескольких БЛОБов
bool CTransportSocketClient::AT_DCCreateMultiIterator(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/ CaplDataBuf &data_in,/*[in]*/ 
																		UINT32 *SizeDose,/*[in,out*/ CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__CreateMultiReadIterator,"lbl");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		m_TempStore.Add(SizeDose,4);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(size),size);

	// не забыть вызвать в конце внешней функции ClearInternalData(); !!!!!!
	return true;
}

//  Присоединение к итератору для чтения нескольких БЛОБов
bool CTransportSocketClient::AT_DCCreateMultiIterator64(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/ CaplDataBuf &data_in,/*[in]*/ 
																	UINT32 *SizeDose,/*[in,out*/ CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__CreateMultiReadIterator64,"lbl");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		m_TempStore.Add(SizeDose,4);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(size),size);

	// не забыть вызвать в конце внешней функции ClearInternalData(); !!!!!!
	return true;
}
// Отсоединение от мульти-итератора
bool CTransportSocketClient::AT_DCCloseMultiIterator(/*[in,out]*/ AplNetErrors &aplError)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__CloseMultiReadIterator,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

// Возвращает максимально возможный размер БЛОБа (для оракла он ограничен размером файла данных БД)
bool CTransportSocketClient::AT_GetMaxBlobSize64(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/ __int64 &MaxSizeBLOB)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__GetMaxBlobSize64,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"l");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	m_TempStore.Read(&MaxSizeBLOB,8);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}


// Чтение из блоба, присоединенного к итератору
bool CTransportSocketClient::AT_DCReadFromMultiIterator(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/ UINT32 *SizeDose,
														CaplDataBuf &data_out, CaplDataBuf &data_out2)
{
	data_out.Clear();
	data_out2.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__ReadFromMultiReadIterator,"l");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(SizeDose,4);
		CALL_WITH_TEST_PARAM(code,"lblb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(size),size);
	m_TempStore.Read(&size,4);
	if(size != 0)
	{
		data_out2.SetExternalData(m_TempStore.GetCurBuffer(size),size);
	}
	// не забыть вызвать в конце внешней функции ClearInternalData();!!!!!!!
	return true;

}

//Проверяет, есть ли
bool CTransportSocketClient::AT_DCAutoupdate_LoadListNamesFiles(/*[in,out]*/AplNetErrors &aplError,
									   /*[in]*/ CaplDataBuf &data_in,CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__Autoupdate_LoadListNamesFiles,"lbl");
	WRITE_ADDITIONAL_BUF;
	m_TempStore.Add(&(data_in.m_Size),4);
	m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
	int a = 0;
	m_TempStore.Add(&a,4);
	CALL_WITH_TEST_PARAM(code,"lb");
	READ_ERR__ADDITIONAL_BUF;
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

//
bool CTransportSocketClient::AT_DCAutoupdate_LoadListNamesFilesEx(/*[in,out]*/AplNetErrors &aplError,
									   /*[in]*/ CaplDataBuf &data_in,CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__Autoupdate_LoadListNamesFilesEx,"lbl");
	WRITE_ADDITIONAL_BUF;
	m_TempStore.Add(&(data_in.m_Size),4);
	m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
	int a = 0;
	m_TempStore.Add(&a,4);
	CALL_WITH_TEST_PARAM(code,"lb");
	READ_ERR__ADDITIONAL_BUF;
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

//  Присоединение к итератору для чтения нескольких БЛОБов
bool CTransportSocketClient::AT_DCAutoupdate_CreateMultiIterator(/*[in,out]*/ AplNetErrors &aplError,
																 /*[in]*/ CaplDataBuf &data_in,/*[in]*/ UINT32 *SizeDose,/*[in,out*/ CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__Autoupdate_CreateMultiReadIterator,"lbl");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		m_TempStore.Add(SizeDose,4);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(size),size);

	// не забыть вызвать в конце внешней функции ClearInternalData(); !!!!!!
	return true;
}

// Отсоединение от мульти-итератора
bool CTransportSocketClient::AT_DCAutoupdate_CloseMultiIterator(/*[in,out]*/ AplNetErrors &aplError)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__Autoupdate_CloseMultiReadIterator,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}


// Чтение из блоба, присоединенного к итератору
bool CTransportSocketClient::AT_DCAutoupdate_ReadFromMultiIterator(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/ UINT32 *SizeDose,
														CaplDataBuf &data_out, CaplDataBuf &data_out2)
{
	data_out.Clear();
	data_out2.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__Autoupdate_ReadFromMultiReadIterator,"l");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(SizeDose,4);
		CALL_WITH_TEST_PARAM(code,"lblb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(size),size);
	m_TempStore.Read(&size,4);
	if(size != 0)
	{
		data_out2.SetExternalData(m_TempStore.GetCurBuffer(size),size);
	}
	// не забыть вызвать в конце внешней функции ClearInternalData();!!!!!!!
	return true;

}


// Получить версию и тип сервера приложений
//	Раскомментарить в середине 24 года, когда большинство серверов будут понимать эту функцию

bool CTransportSocketClient::AT_DCQueryServerVersion(AplNetErrors &aplError, CString *ver_srv, CString *type_srv, CString *class_srv, CString *build_date)
{
	CaplDataBuf dbuf_tmp;
	char EBcode;
	char* c_buf;
	CString s_buf;
	int c_buf_size;
	if(ver_srv!=0) ver_srv->Empty();
	if(type_srv!=0) type_srv->Empty();
	if(class_srv!=0) class_srv->Empty();
	if(build_date!=0) build_date->Empty();

	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA_D(CAplTransport__QueryServerVersion,"");
	WRITE_ADDITIONAL_BUF_DEF_BUF(dbuf)
	m_last_calling = __APL_FUNC__;
	if(!Call(dbuf, dbuf_ext, true ,false, true, false)){aplError = m_aplError; return false;}
	aplError=TestParamIdent(dbuf, code, "lb");


	if(aplError!=APL_NET_OK){ClearInternalData(); return false;}
	READ_ERR__ADDITIONAL_BUF_D;

	dbuf.Read(&c_buf_size, 4);
	dbuf_tmp.SetExternalData(dbuf.GetCurBuffer(), c_buf_size);

	// читаем из буфера
	// заголовки буферов - однобайтовые! 
	// !!! Внимание, этот заголовок пишется в буфер без заключительного нуля!
	c_buf_size = sizeof(std_ExtendedBuf_header);
	c_buf = new char[c_buf_size+1];
	dbuf_tmp.Read(c_buf,c_buf_size);
	c_buf[c_buf_size] = 0;

	if(CStringA(std_ExtendedBuf_header) != c_buf)
	{
		delete[] c_buf;
		//MessageBox(0,"Не тот формат загружаемого буфера","Ошибка",MB_ICONERROR);
		aplError = APL_SOCK_MISSED_VERSION;
		return true;
	}
	delete[] c_buf; c_buf = 0;

	dbuf_tmp.m_ansi_string = m_data->m_global_ansi_string;

	CString input_param;
	do
	{
		if(!dbuf_tmp.Read(&EBcode,1))break;
		if(!dbuf_tmp.ReadStrBuf(input_param))break;

		switch(EBcode)
		{
		case CEB_ver_srv:
			if(ver_srv != 0){*ver_srv = input_param;}
			break;
		case CEB_type_srv:
			if(type_srv != 0){*type_srv=input_param;}
			break;
		case CEB_class_srv:
			if(class_srv != 0){*class_srv=input_param;}
			break;
		case CEB_build_srv:
			if(build_date != 0){*build_date=input_param;}
			break;
		default:
			break;
		};
	}while(true);

	ClearInternalData();
	return true;
} /* */

/************************************************************************
 * Отрабатывает попытку аутентификации через керберос и прочие службы
 * Авторизация для конкретной БД должна выполняться последующим вызовом CAplTransport__ConnectEx!
 ************************************************************************/
bool CTransportSocketClient::AT_DCAuthExternal(/*[out]*/ AplNetErrors &aplError, CaplDataBuf &dbuf_in, CaplDataBuf &dbuf_out)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером
	INIT_DATA(CAplTransport__AuthKerberos,"lb");

	dbuf_out.Clear();
	WRITE_ADDITIONAL_BUF;
	INT32 c_buf_size = dbuf_in.m_Size;
	m_TempStore.Add(&c_buf_size,4);
	m_TempStore.Add(dbuf_in.GetCurBuffer(),c_buf_size);

	CALL_WITH_TEST_PARAM(code,"lb");
	READ_ERR__ADDITIONAL_BUF;
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	m_TempStore.Read(&c_buf_size,4);
	dbuf_out.SetExternalData(m_TempStore.GetCurBuffer(), c_buf_size);
	return true;
}



#define WriteExtBufInt(dbuf_for_write, writed_code, writed_param)\
EBcode=writed_code;dbuf_for_write.Add(&EBcode,1);s_buf.Format(_T("%i"),writed_param);dbuf_for_write.AddStrBuf((LPCTSTR)s_buf);

#define WriteExtBufStr(dbuf_for_write, writed_code, writed_param)\
EBcode=writed_code;dbuf_for_write.Add(&EBcode,1);dbuf_for_write.AddStrBuf((LPCTSTR)writed_param);

#define WriteExtBufExt(dbuf_for_write) \
if(code1==-1){UINT32 wp;dbuf_for_write.Reset();m_tmp_buf.SetCurPos(4);EBcode=CEB_sec_code_1;dbuf_for_write.Add(&EBcode,1);m_tmp_buf.Read(&wp,4);s_buf.Format(_T("%i"),wp);\
	dbuf_for_write.AddStrBuf((LPCTSTR)s_buf);\
	EBcode=CEB_sec_code_2;dbuf_for_write.Add(&EBcode,1);m_tmp_buf.Read(&wp,4);s_buf.Format(_T("%i"),wp);\
	dbuf_for_write.AddStrBuf((LPCTSTR)s_buf);\
	}else if(code1 != 0){	WriteExtBufInt(dbuf_for_write,CEB_sec_code_1,code1);WriteExtBufInt(dbuf_for_write,CEB_sec_code_2,code2);}

#define WriteExtBufData \
if(code==(FuctionCodes)-1){double* p_data;p_data=(double*)m_tmp_buf.m_data+4;m_TempStore.Add(p_data,8);}\
else{UINT32 ucode=code1;m_TempStore.Add(&(ucode),4);ucode=code2;m_TempStore.Add(&(ucode),4);}


//DCOM Отрабатывает попытку соединения клиента с некоторой базой
bool CTransportSocketClient::AT_DCConnectEx(AplNetErrors &aplError, UINT32 *user_id, 
					CString *ver_srv, CString *type_srv, UINT32 *ServerAUSessionId, bool *can_find_in_blob, CString *class_srv)
{
	if(class_srv != 0) class_srv->Empty();

	// устанвавливаем режим основному буферу
	m_TempStore.m_ansi_string = m_data->m_global_ansi_string;

	m_login_data.client_ip=(m_aplSocket== 0)?0:m_aplSocket->GetCompIp();
	//global_session_in_process_counter++;

	/* На будущее - если будем сравнивать с тем, что пришло от приложения
	CString sOsUser, sOsDomain;
	aplGetOSUser(sOsUser, sOsDomain);
	*/
	m_login_data.client_id=GetCurrentProcessId();

	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA_D(CAplTransport__ConnectEx,"lb");
	WRITE_ADDITIONAL_BUF_DEF_BUF(dbuf)

	CaplDataBuf dbuf_tmp;
	char EBcode;
	char* c_buf;
	CString s_buf;
	int c_buf_size;

	// заголовки буферов - однобайтовые! 
	// !!! Внимание, этот заголовок пишется в буфер без заключительного нуля!
	c_buf_size = sizeof(std_ExtendedBuf_header);
	dbuf_tmp.Add(std_ExtendedBuf_header, c_buf_size);
	dbuf_tmp.m_ansi_string = m_data->m_global_ansi_string;

	WriteExtBufStr(dbuf_tmp, CEB_username,(LPCTSTR)m_login_data.username);
	WriteExtBufStr(dbuf_tmp, CEB_pwd,(LPCTSTR)m_login_data.pwd);
	WriteExtBufStr(dbuf_tmp, CEB_name_base,(LPCTSTR)m_login_data.name_base);
	WriteExtBufInt(dbuf_tmp, CEB_client_ip,m_login_data.client_ip);
	WriteExtBufInt(dbuf_tmp, CEB_client_id,m_login_data.client_id);
	// Уникальные параметры сеанса s1 и s2
	WriteExtBufInt(dbuf_tmp, CEB_client_id_s1, m_login_data.s1);
	WriteExtBufInt(dbuf_tmp, CEB_client_id_s2, m_login_data.s2);
	// Тип лицензии
	WriteExtBufStr(dbuf_tmp, CEB_type_license_str,m_login_data.type_license);
	
	//LIC На переходный период до 2025 года - для типов PSS и ILS посылаем еще и число, чтобы корректно работали старые сервера
	if(m_login_data.type_license==_T("PSS"))
	{	WriteExtBufInt(dbuf_tmp, CEB_type_license,0);}
	else if(m_login_data.type_license==_T("ILS"))
	{	WriteExtBufInt(dbuf_tmp, CEB_type_license,1);}
/*	else
	{
		При новых типах лицензий в старом формате CEB_type_license ничего не посылаем.
		Клиент после подключения выполнит проверку, и если сервер старый, и не понимает 
		новые строковые типы, то соединение будет разорвано.
	} */

	WriteExtBufStr(dbuf_tmp, CEB_ver_cli,(LPCTSTR)m_VerCli);
	WriteExtBufStr(dbuf_tmp, CEB_exe_cli,(LPCTSTR)m_AppName);
	if(m_login_data.domain.GetLength() > 0)
	{
		WriteExtBufStr(dbuf_tmp, CEB_domain,(LPCTSTR)m_login_data.domain);
	}
	if(m_CompName != _T(""))
	{
		WriteExtBufStr(dbuf_tmp, CEB_comp_name,m_CompName);
	}
	WriteExtBufStr(dbuf_tmp, CEB_os_user,(LPCTSTR)m_login_data.sOsUser);
	WriteExtBufStr(dbuf_tmp, CEB_name_con,(LPCTSTR)m_login_data.name_connect);


	c_buf_size = dbuf_tmp.m_Size;
	dbuf.Add(&c_buf_size,4);
	dbuf.Add(dbuf_tmp.GetCurBuffer(),c_buf_size);
//	CALL_WITH_TEST_PARAM(code,"lb");
	m_last_calling = __APL_FUNC__;
	if(!Call(dbuf, dbuf_ext, true ,false, true, false)){aplError = m_aplError; return false;}
	aplError=TestParamIdent(dbuf, code, "lb");


	if(aplError!=APL_NET_OK){ClearInternalData(); return false;}
	READ_ERR__ADDITIONAL_BUF_D;

	dbuf.Read(&c_buf_size, 4);
	dbuf_tmp.SetExternalData(dbuf.GetCurBuffer(), c_buf_size);

	// читаем из буфера
	// заголовки буферов - однобайтовые! 
	// !!! Внимание, этот заголовок пишется в буфер без заключительного нуля!
	c_buf_size = sizeof(std_ExtendedBuf_header);
	c_buf = new char[c_buf_size+1];
	dbuf_tmp.Read(c_buf,c_buf_size);
	c_buf[c_buf_size] = 0;
	
	if(CStringA(std_ExtendedBuf_header) != c_buf)
	{
		delete[] c_buf;
		//MessageBox(0,"Не тот формат загружаемого буфера","Ошибка",MB_ICONERROR);
		aplError = APL_SOCK_MISSED_VERSION;
		return true;
	}
	delete[] c_buf; c_buf = 0;

	dbuf_tmp.m_ansi_string = m_data->m_global_ansi_string;
	
	CString input_param, serv_lic_type(_T(""));
	do
	{
		if(!dbuf_tmp.Read(&EBcode,1))break;
		if(!dbuf_tmp.ReadStrBuf(input_param))break;

		switch(EBcode)
		{
//		case CEB_username:
//			username=c_buf;c_buf = 0;break;
//		case CEB_pwd:
//			pwd=c_buf;c_buf = 0;break;
//		case CEB_name_base:
//			name_base=c_buf;c_buf = 0;break;
//		case CEB_client_ip:
//			client_ip=atoi(c_buf);delete[] c_buf;c_buf = 0;break;
		case CEB_client_id:
			m_login_data.client_id = _atoi(input_param);break;
		case CEB_user_id:
			m_login_data.user_id = _atoi(input_param);break;
//		case CEB_type_license:
//			type_license=atoi(c_buf);delete[] c_buf;c_buf = 0;break;
		case CEB_ver_srv:
			if(ver_srv != 0){*ver_srv = input_param;}
			break;
		case CEB_type_srv:
			if(type_srv != 0){*type_srv=input_param;}
			break;
		case CEB_server_ses_id:
			if(ServerAUSessionId != 0){*ServerAUSessionId = _atoi(input_param);}
			break;
//		case CEB_ver_cli:
//			ver_cli=c_buf;c_buf = 0;break;
//		case CEB_exe_cli:
//			exe_cli=c_buf;c_buf = 0;break;
		case CEB_can_find_in_blob:
			if(can_find_in_blob != 0){*can_find_in_blob = input_param==_T('1');}
			break;
		case CEB_class_srv:
			if(class_srv != 0){*class_srv=input_param;}
			break;
		case CEB_type_license_str:
			serv_lic_type = input_param;
			break;
		default:
			break;
		};
	}while(true);

	if(user_id != 0){*user_id=m_login_data.user_id;}

	//LIC Проверка что сервер новый и он правильно понял тип лицензии.
	if(m_login_data.type_license != _T("PSS") && m_login_data.type_license != _T("ILS"))
	{
		if(serv_lic_type != m_login_data.type_license)
		{
			aplError = APL_NET_CLI_SERVER_DN_SUPPORT_FUNCTION;
		}
	}

	ClearInternalData();
	return true;
}

// Функция общается с API Kerberos или API ExternalAuthentication на своем компе и транслирует буфер от него на сервер для передачи API
// Kerberos или ExternalAuthentication там; получает обратно буфер от серверного Kerberos и обрабатывает его своим API до получения
// положительного или отрицательного результата аутентификации
bool CTransportSocketClient::DC_AuthExternal(LPCTSTR _username, LPCTSTR _pwd, LPCTSTR _domain)
{
	AplNetErrors aplError = APL_NET_OK;

	// переменные для аутентификации через Керберос
	CString username = _username;
	CString pwd = _pwd;
	CString domain = _domain;
	CString sServerMess;

	//  SPN
	CString ServerSPN;

	CString csMess;

	CString sAuthSystem = _T("Kerberos");

	// на всякий случай сравниваем время на клиенте и на сервере
	COleDateTime odt_srv, odt_curr = COleDateTime::GetCurrentTime();
	m_data->NET_GetServerDateTime(odt_srv);
	COleDateTimeSpan odts = odt_curr-odt_srv;
	int max_delta_min = 5; // в минутах

	if(!AT_DCServiceGetAuthParam(aplError, APC_GetSPN, ServerSPN))
	{
		csMess = APL_T("При получении с сервера приложений SPN возникла ошибка");
		if(!m_description_serv_error.IsEmpty())
		{
			csMess += _T(": ");
			csMess += m_description_serv_error;
		}
		else
			csMess += _T(". ");

		MY_THROW_EX(aplError, csMess);
	}

	if(ServerSPN == _T(""))
		MY_THROW_EX(APL_NET_SRV_NOT_CONNECT, APL_T("В настройках сервера приложений не задан SPN"));

	int pos_splash = -1;
	if((pos_splash = username.Find(_T("\\"))) != -1)
	{
		// используем домен, который указан в username, а старое значение _domain игнорируем
		domain = username.Left(pos_splash);
		username.Delete(pos_splash + 1);
	}

	CaplDataBuf dbuf_in, dbuf_out;
	CaplKerberosClient kerbClient;

	if(!kerbClient.Init(ServerSPN, username, pwd, domain))
	{
		MY_THROW_EX(APL_NET_CLI_ERROR_PROCESSED,
			CString(APL_T("Ошибка инициализации Kerberos: ")) + kerbClient.m_csError);
	}

	unsigned char *pBufIn=0, *pBufOut=0;
	INT32 iBufSizeIn=0, iBufSizeOut=0;

	int code = -1;

	while(true)
	{
		code=kerbClient.ProcessingBuffer(pBufIn, iBufSizeIn, pBufOut, iBufSizeOut);

#ifdef _DEBUG
		//!!!!!!!!!!!!!!!!!!!!!!
		csMess.Format(APL_T("Kerberos вернул ответ %i и буфер размером %i"), code, iBufSizeOut);
		m_MainLog.LogMessage(csMess);
#endif

		if(iBufSizeIn == 0)
		{
			// при первом вызове
			if(code != 0 && code != 1)
			{
				CString err_mess = APL_T("При получении TGS произошла ошибка: ");
				err_mess += kerbClient.m_csError;

				MY_THROW_EX(APL_NET_CLI_KERBEROS_ERROR, err_mess);
			}
		}
		else
		{
			if(code == -1)
			{
				csMess = CString(APL_T("Аутентификация не пройдена: ")) + kerbClient.m_csError;
				if(abs((int)odts.GetTotalMinutes()) > max_delta_min)
				{
					CString tmp;
					tmp.Format(APL_T("\r\nВнимание! Время на сервере и на клиенте отличается больше чем на %i минут; это может помешать аутентификации через Kerberos"),
						max_delta_min);
					csMess += tmp;
				}
				m_MainLog.LogMessage(csMess);

				MY_THROW_EX(APL_NET_CLI_KERBEROS_ERROR, csMess);
			}
			else if (code == 0)
			{
				//!!!!!!!!!!!!!!!!!!!!!!!!!!
				{
					csMess = APL_T("Kerberos: Аутентификация успешно пройдена !!! ");
					m_MainLog.LogMessage(csMess);
					//aplMessageBox(mess);
				}
				if(iBufSizeIn == 0 || iBufSizeOut==0)
					break;
			}
		}

		if((0==pBufOut || iBufSizeOut==0) && 1==code)
		{
			MY_THROW_EX(APL_NET_CLI_KERBEROS_ERROR,
				CString(APL_T("Kerberos вернул пустой буфер и требование продолжить аутентификацию! ")) + kerbClient.m_csError);
		}

		// Очищаем буфер в транспорте после предыдущей итерации
		ClearInternalData();

		dbuf_in.Clear();
		// заголовки буферов - однобайтовые!
		dbuf_in.Add(std_AuthExBuf_header, strlen(std_AuthExBuf_header) + 1);
		dbuf_in.m_ansi_string = m_data->m_global_ansi_string;
		dbuf_in.AddStrBuf(sAuthSystem);
		dbuf_in.Add(&iBufSizeOut, 4);
		dbuf_in.Add(pBufOut, iBufSizeOut);


		if(!AT_DCAuthExternal(aplError, dbuf_in, dbuf_out))
		{
			if(aplError == APL_NET_SRV_EXTERNAL_AUTH_ERROR)
				csMess = _T("");
			else
				csMess = CString(APL_T("Ошибка при выполнении аутентификации в системе '")) + sAuthSystem + _T("'. ");

			if(!m_description_serv_error.IsEmpty())
			{
				csMess += m_description_serv_error;
			}

			MY_THROW_EX(aplError, csMess);
		}

		dbuf_out.Read(&iBufSizeIn, 4);
		if(iBufSizeIn != 0)
		{
			pBufIn = (unsigned char *)dbuf_out.GetCurBuffer(iBufSizeIn);
		}
		else
			pBufIn = 0;

		dbuf_out.ReadStrBuf(sServerMess);
		//!!!!!!!!!!!!!!!!!!!!!!!!!!
		{
			LogDebugMessageIfDef(APL_T("%s: Получили с сервера буфер размером %i"), (LPCTSTR)sAuthSystem, iBufSizeIn);
			if(!sServerMess.IsEmpty())
			{
				m_MainLog.LogMessage(sAuthSystem + CString(APL_T(": сообщение с сервера приложений: ")) + sServerMess);
			}
		}

		if(iBufSizeIn == 0)
		{
			LogDebugMessageIfDef(APL_T("%s прислал через сервер пустой буфер"), sAuthSystem);
			break;
		}
		//!!!!!!!!!!!!!!!!!!!!!!!!!!
		{
			LogDebugMessageIfDef(APL_T("Следующая итерация %s"), sAuthSystem);
		}

	}
	// Очищаем буфер в транспорте
	ClearInternalData();
	LogDebugMessageIfDef(_T("return. code: %i"), code);
	return code == 0;
}

bool CTransportSocketClient::AT_DCSessionPartsOperate(AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();

	// !!! типы параметров  - char* для совместимости с ansi сервером 
	//INIT_DATA(CAplTransport__BeginLongOperation, "lb");
	INIT_DATA(CAplTransport__SessionPartsOperate, "lb");
	WRITE_ADDITIONAL_BUF;
	m_TempStore.Add(&data_in.m_Size,4);
	m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
	CALL_WITH_TEST_PARAM(code,"lb");
	READ_ERR__ADDITIONAL_BUF;
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	if(size>0)
		data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);

	return true;
}

//DCOM Отрабатывает попытку соединения клиента с некоторой базой
bool CTransportSocketClient::AT_DCBeginLongOperation(AplNetErrors &aplError, UINT32 time_in_minuts)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__BeginLongOperation, "l");
	WRITE_ADDITIONAL_BUF;

	m_TempStore.Add(&time_in_minuts,4);
	CALL_WITH_TEST_PARAM(code, "");
	READ_ERR__ADDITIONAL_BUF;
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

//DCOM Отрабатывает попытку соединения клиента с некоторой базой
bool CTransportSocketClient::AT_DCStartAdminMode(AplNetErrors &aplError,
		LPCTSTR username, LPCTSTR pwd, UINT32 *admin_id, int code1, int code2, LPCTSTR str_about)
{

	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__StartAdminMode,"lb");
	WRITE_ADDITIONAL_BUF;
	CaplDataBuf dbuf_tmp;
	char EBcode;
	char* c_buf;
	CString s_buf;
	int c_buf_size;
	

	// !!! Внимание, этот заголовок пишется в буфер без заключительного нуля!
	c_buf_size=sizeof(std_ExtendedBuf_header);
	dbuf_tmp.Add(std_ExtendedBuf_header,c_buf_size);
	
	UINT32 const_admin_id = 0;

	dbuf_tmp.m_ansi_string = m_data->m_global_ansi_string;

	if(username != 0 && pwd != 0)
	{
		WriteExtBufStr(dbuf_tmp, CEB_username,username);
		WriteExtBufStr(dbuf_tmp, CEB_pwd,pwd);
	}
	else WriteExtBufExt(dbuf_tmp);
	
	if(str_about != 0)WriteExtBufStr(dbuf_tmp, CEB_about,str_about);

	c_buf_size = dbuf_tmp.m_Size;
	m_TempStore.Add(&c_buf_size,4);
	m_TempStore.Add(dbuf_tmp.GetCurBuffer(),c_buf_size);

	CALL_WITH_TEST_PARAM(code,"lb");
	READ_ERR__ADDITIONAL_BUF;

	if(aplError==APL_NET_OK)
	{
		m_TempStore.Read(&c_buf_size,4);
		dbuf_tmp.SetExternalData(m_TempStore.GetCurBuffer(),c_buf_size);
		// читаем из буфера
		// !!! Внимание, этот заголовок пишется в буфер без заключительного нуля!
		c_buf_size=sizeof(std_ExtendedBuf_header);
		c_buf=new char[c_buf_size+1];
		dbuf_tmp.Read(c_buf,c_buf_size);
		c_buf[c_buf_size] = 0;
		if(CStringA(std_ExtendedBuf_header) != c_buf)
		{
			delete[] c_buf;
			//MessageBox(0,"Не тот формат загружаемого буфера","Ошибка",MB_ICONERROR);
			aplError =APL_SOCK_MISSED_VERSION;
			return true;
		}
		delete[] c_buf;c_buf = 0;
		
		dbuf_tmp.m_ansi_string = m_data->m_global_ansi_string;

		CString input_param;
		do{
			if(!dbuf_tmp.Read(&EBcode,1))break;
			if(!dbuf_tmp.ReadStrBuf(input_param))break;

			switch(EBcode)
			{
			case CEB_user_id:
				const_admin_id = _atoi(input_param);break;
			default:
				break;
			};
		}while(true);

		if(admin_id != 0){*admin_id=const_admin_id;}
	}
	
	m_am_user = username;
	m_am_pwd = pwd;
	m_am_code1 = code1;
	m_am_code2 = code2;

	ClearInternalData();
	return true;
}
//DCOM 
bool CTransportSocketClient::AT_DCExitAdminMode(AplNetErrors &aplError, UINT32 *user_id)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__ExitAdminMode,"");
	WRITE_ADDITIONAL_BUF;

	CaplDataBuf dbuf_tmp;
	char EBcode;
	char* c_buf;
	int c_buf_size;
	UINT32 const_user_id = 0;
	
	// !!! Внимание, этот заголовок пишется в буфер без заключительного нуля!
	c_buf_size=sizeof(std_ExtendedBuf_header);


	CALL_WITH_TEST_PARAM(code,"lb");
	READ_ERR__ADDITIONAL_BUF;

	if(APL_ERROR_CONDITION)
	{
		user_id = 0;
		ClearInternalData();
		return false;
	}


	m_TempStore.Read(&c_buf_size,4);
	dbuf_tmp.SetExternalData(m_TempStore.GetCurBuffer(),c_buf_size);
	// читаем из буфера
	// !!! Внимание, этот заголовок пишется в буфер без заключительного нуля!
	c_buf_size = sizeof(std_ExtendedBuf_header);
	c_buf = new char[c_buf_size+1];
	dbuf_tmp.Read(c_buf,c_buf_size);
	c_buf[c_buf_size] = 0;
	if(CStringA(std_ExtendedBuf_header) != c_buf)
	{
		delete[] c_buf;
		//MessageBox(0,"Не тот формат загружаемого буфера","Ошибка",MB_ICONERROR);
		aplError = APL_SOCK_MISSED_VERSION;
		return true;
	}
	delete[] c_buf;c_buf = 0;
	dbuf_tmp.m_ansi_string = m_data->m_global_ansi_string;
	
	CString input_param;
	do{
		if(!dbuf_tmp.Read(&EBcode,1)) break;
		if(!dbuf_tmp.ReadStrBuf(input_param)) break;

		switch(EBcode)
		{
		case CEB_user_id:
			const_user_id = _atoi(input_param); break;
		default:
			break;
		};
	}while(true);
	if(c_buf != 0){ delete[] c_buf;c_buf = 0;}
	
	if(user_id != 0){*user_id = const_user_id;}

	m_am_user = _T("");
	m_am_pwd = _T("");
	m_am_code1 = 0;
	m_am_code2 = 0;

	ClearInternalData();
	return true;
}

bool CTransportSocketClient::AT_DCLoadEntityTables(AplNetErrors &aplError, CaplMap &Entity2Tabl)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__LoadEntityTables,"");
	WRITE_ADDITIONAL_BUF;

	CaplDataBuf dbuf_tmp;
	int count_ent,c_buf_size,i,id_e,id_t;

	CALL_WITH_TEST_PARAM(code,"lb");
	READ_ERR__ADDITIONAL_BUF;

	Entity2Tabl.Clear();
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	m_TempStore.Read(&c_buf_size,4);
	dbuf_tmp.SetExternalData(m_TempStore.GetCurBuffer(),c_buf_size);
	// читаем из буфера
	dbuf_tmp.Read(&count_ent, 4);
	for(i = 0; i<count_ent; i++)
	{
		dbuf_tmp.Read(&id_e,4);
		dbuf_tmp.Read(&id_t,4);
		Entity2Tabl.Add(id_e,id_t);
	}

	ClearInternalData();
	return true;
}

//DCOM Отрабатывает попытку соединения клиента с некоторой базой
bool CTransportSocketClient::AT_DCGetOraAlias(AplNetErrors &aplError,
												 LPCTSTR username, LPCTSTR pwd, int code1, int code2,
												 CaplDataBuf &data_out)
{
	data_out.Clear();
// 	if(username== 0 && code1== 0 && code2== 0){
// 		return false;
// 	}

	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__LoadOraAlias, "lb");
	WRITE_ADDITIONAL_BUF;
	CaplDataBuf dbuf_tmp;
	char EBcode;
// 	char* c_buf;
	int c_buf_size;
	CString s_buf;
	// заголовки буферов - однобайтовые! 
	// !!! Внимание, этот заголовок пишется в буфер без заключительного нуля!
	c_buf_size = sizeof(std_ExtendedBuf_header);
	dbuf_tmp.Add(std_ExtendedBuf_header, c_buf_size);
	
	dbuf_tmp.m_ansi_string = m_data->m_global_ansi_string;

	if(username != 0 && pwd != 0)
	{
		WriteExtBufStr(dbuf_tmp, CEB_username,username);
		WriteExtBufStr(dbuf_tmp, CEB_pwd,pwd);
	}
	else WriteExtBufExt(dbuf_tmp);

	c_buf_size = dbuf_tmp.m_Size;
	m_TempStore.Add(&c_buf_size,4);
	m_TempStore.Add(dbuf_tmp.GetCurBuffer(),c_buf_size);

	CALL_WITH_TEST_PARAM(code,"lb");
	READ_ERR__ADDITIONAL_BUF;
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);

	return true;
}

//DCOM Отрабатывает попытку соединения клиента с некоторой базой
bool CTransportSocketClient::AT_DCDisconnect(/*[in,out]*/ AplNetErrors &aplError)
{
	m_login_data.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__Disconnect,"");
	WRITE_ADDITIONAL_BUF;
	// Убираем функции обработки разрывов, они уже только мешают
	m_aplSocket->external_close_funct = 0;
	m_aplSocket->external_reconnect_funct = 0;

	// если сервер подвис, то ждать его ответ - дело неблагодарное
	// полсекунды при нормальном расклде - вполне нормально
	m_aplSocket->SetTimeOut(1000,500);
	CALL_WITH_TEST_PARAM(code,"");
	READ_ERR__ADDITIONAL_BUF;
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}

	return true;
}


bool CTransportSocketClient::AT_DCLicOperate(AplNetErrors &aplError, LicOperate _command, CStringArray &listIn, CStringArray &listOut)
{
	CaplDataBuf dbuf_tmp, data_out;
	CString s_buf;
	int size;

	listOut.RemoveAll();

	// заголовки буферов - однобайтовые! 
	size = sizeof(std_LicOperate_header);
	dbuf_tmp.Add(std_LicOperate_header, size+1);
	dbuf_tmp.m_ansi_string = m_data->m_global_ansi_string;

	char EBcode;
	byte command = _command;
	dbuf_tmp.Add(&command, 1);

	for(int i=0; i<listIn.GetSize(); i++)
	{
		WriteExtBufStr(dbuf_tmp, CEB_type_license_str, listIn.GetAt(i));
	}

	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__LicOperate,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&dbuf_tmp.m_Size,4);
		m_TempStore.Add(dbuf_tmp.GetBuffer(),dbuf_tmp.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	size = 0;
	m_TempStore.Read(&size,4);
	data_out.Clear();
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);

	// читаем из буфера
	// заголовки буферов - однобайтовые! 
	size = sizeof(std_LicOperate_header);
	char* c_buf = new char[size+1];
	data_out.Read(c_buf, size+1);
	c_buf[size] = 0;

	if(CStringA(std_LicOperate_header) != c_buf)
	{
		delete[] c_buf;
		//MessageBox(0,"Не тот формат загружаемого буфера","Ошибка",MB_ICONERROR);
		aplError = APL_SOCK_MISSED_VERSION;
		return true;
	}
	delete[] c_buf; c_buf = 0;

	data_out.m_ansi_string = m_data->m_global_ansi_string;

	CString input_param;
	do
	{
		if(!data_out.Read(&EBcode,1))break;
		if(!data_out.ReadStrBuf(input_param))break;

		switch(EBcode)
		{
		case CEB_type_license_str:
			listOut.Add(input_param);
			break;
		default:
			break;
		};
	}while(true);

	return true;
}

//DCOM Генерит по запросу буфер и запоминает указатель на него в m_TempStor, а размер в m_TempSize
bool CTransportSocketClient::AT_DCLoad(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__LoadEx,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&data_in.m_Size,4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		//CALL_WITH_TEST_PARAM(code,"lb");
		m_last_calling = __APL_FUNC__;
		if(!Call(m_TempStore, dbuf_ext))
		{
			aplError=m_aplError; return false;
		}
		if(m_TempStore.m_Size != 0)
		{
			aplError = TestParamIdent(m_TempStore, code, "lb");
			if(aplError!=APL_NET_OK)
			{
				ClearInternalData(); return false;
			}
			READ_ERR__ADDITIONAL_BUF;
		}
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	int size = 0;
	m_TempStore.Read(&size, 4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(), size);
	return true;
}

// Служебные операции с шаблонами доступа
bool CTransportSocketClient::AT_DCServiceAccessPatterns(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__ServiceAccessPatterns,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&data_in.m_Size,4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

// Получить историю изменения атрибутов
bool CTransportSocketClient::AT_DCGetAttrsHistory(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__GetAttrsHistory,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&data_in.m_Size,4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

// Возвращает в строковом массиве все значения одного атрибута всех иснтансов
bool CTransportSocketClient::AT_DCGetAllAttrValues(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__GetAllAttrValues,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&data_in.m_Size,4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}



// Заблокировать на запись инстанс или пачку инстансов
bool CTransportSocketClient::AT_DCLockInstance(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, int &result)
{
	result = 0;
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__LockInstance,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&data_in.m_Size,4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"l");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	m_TempStore.Read(&result, 4);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	return true;
}

// Возвращает строку временного пароля для дублицирования сессии
bool CTransportSocketClient::AT_DCGetString4DupSession(CString &spetial_string)
{
	CaplDataBuf dbuf_out;
	AplNetErrors aplError = APL_NET_OK;

	if(!AT_DCGetString4DupSession(aplError, dbuf_out) || SPEC_ERR_CODES(aplError))
	{
		if(m_data != 0) m_data->SetAPLError( (AplNetErrors)aplError, GetDescriptionServError(),_T(__FILE__),__LINE__,__APL_FUNC__);
		dbuf_out.Clear();
		return false;
	}

	dbuf_out.m_ansi_string = m_data->m_global_ansi_string;
	dbuf_out.ReadStrBuf(spetial_string);

	ClearInternalData();
	return true;
}


// Возвращает строку временного пароля для дублицирования сессии
bool CTransportSocketClient::AT_DCGetString4DupSession(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__GetString4DupSession,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

// Служебные операции сервера по запросу клиента
bool CTransportSocketClient::AT_DCServiceOp(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__ServiceOp,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&data_in.m_Size,4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

// Получить список атрибутов, в которых живут идентификтаоры БЛОБов
bool CTransportSocketClient::AT_DCGetAttrs4Blobs(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__GetAttrs4Blobs,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}


//DCOM Генерит буфер, содержащий удаленные инстансы
bool CTransportSocketClient::AT_DCQuerDelInst(AplNetErrors &aplError, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__QuerDelInst,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}


bool CTransportSocketClient::AT_DCQuerSysTime(/*[in,out]*/ AplNetErrors &aplError,
											  /*[out, size_is(8)]*/ BYTE Result[8])
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__QuerSysTime,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"b");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	m_TempStore.Read(Result,8);
	ClearInternalData();
	return true;
}

bool CTransportSocketClient::AT_DCQuerActiveUserList(/*[in,out]*/ AplNetErrors &aplError,
													 /*[in,out]*/ CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__QuerActiveUserList,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

bool CTransportSocketClient::AT_DCQuerActiveUserListEx(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, 
													 /*[in,out]*/ CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__QuerActiveUserListEx,"");
	do{
		if(data_in.m_Size != 0)
		{
			fparam_type = "lb";
		}
		WRITE_ADDITIONAL_BUF;
		if(data_in.m_Size != 0)
		{
			m_TempStore.Add(&(data_in.m_Size),4);
			m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		}
		//CALL_WITH_TEST_PARAM(code,"lb");
		m_last_calling = __APL_FUNC__;
		if(!Call(m_TempStore, dbuf_ext))
		{
			aplError=m_aplError;return false;
		}
		else
		{
			aplError=TestParamIdent(m_TempStore, code, "lb");
			if(aplError==APL_SOCK_MISSED_FUNCT_PARAM)
			{
				ClearInternalData();

				// !!! типы параметров  - char* для совместимости с ansi сервером 
				// INIT_DATA(CAplTransport__DeleteIterator,""); - категорически нельзя! Иначе переопределяются переменные типа dbuf!
				//code=CAplTransport__QuerActiveUserListEx;
				fparam_type = _T("");
				WRITE_ADDITIONAL_BUF;
				CALL_WITH_TEST_PARAM(code,"lb");
				READ_ERR__ADDITIONAL_BUF;
				CHECK_REPEAT;
			}
			else
			{
				if(aplError!=APL_NET_OK){ClearInternalData();return false;}
				READ_ERR__ADDITIONAL_BUF;
				CHECK_REPEAT;
			}
		}
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

//DCOM Вносит изменения от клиента в рабочую базу
bool CTransportSocketClient::AT_DCSaveChanges(/*[in,out]*/ AplNetErrors &aplError,
											  /*[in,out]*/ CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	// используем локальный буфер, чтобы при восстановлении соединения не испортить m_TempStore
	CaplDataBuf tempStore;
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__SaveChanges, "lb");
	do{
		WRITE_ADDITIONAL_BUF_DEF_BUF(tempStore)
		tempStore.Add(&(data_in.m_Size), 4);
		tempStore.Add(data_in.GetBuffer(), data_in.m_Size);
	//	CALL_WITH_TEST_PARAM(code,"lb");
		m_last_calling = __APL_FUNC__;
		if(!Call(tempStore, dbuf_ext, false, true)){aplError= m_aplError; return false;}
		aplError = TestParamIdent(tempStore, code, "lb");
		if(aplError != APL_NET_OK){ClearInternalData(); return false;}
		ReadErrAdditionalBuf(tempStore, dbuf_add, aplError, is_warning_data, can_repeat);
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	tempStore.Read(&size,4);
	data_out.Add(tempStore.GetCurBuffer(),size);
	return true;
}

//DCOM 
bool CTransportSocketClient::AT_DCQuery(/*[in,out]*/ AplNetErrors &aplError,
										/*[in]*/  CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__Query,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

//DCOM 
bool CTransportSocketClient::AT_DCQueryEx(/*[in,out]*/ AplNetErrors &aplError,
										/*[in]*/  CaplDataBuf &data_in, CaplDataBuf &data_out,
										CaplDataBuf &data_out2, LPCTSTR def_source)
{
	data_out.Clear();
	data_out2.Clear();
	int len = _strlen(def_source);
	if(len != 0)
	{
		// если def_source задан - пытаемся вызвать новую функцию
		// !!! типы параметров  - char* для совместимости с ansi сервером 
		INIT_DATA(CAplTransport__QueryExS,"lblb");
		do{
			WRITE_ADDITIONAL_BUF;
			m_TempStore.Add(&(data_in.m_Size),4);
			m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);

			m_TempStore.AddStrBuf(def_source);

			//CALL_WITH_TEST_PARAM(code,"lb");
			m_last_calling = __APL_FUNC__;
			if(!Call(m_TempStore,dbuf_ext))
			{
				aplError=m_aplError;
				EnterCriticalSection(&m_CS_TempStore);SetEvent(m_event_TempStore);LeaveCriticalSection(&m_CS_TempStore);return false;
			}
			aplError=TestParamIdent(m_TempStore,code,"lblb");
			if(aplError==APL_SOCK_MISSED_FUNCTION)
			{
				ClearInternalData();
				// новой функции на сервере нет - вызовем старую
				len = 0;
				break;
			}
			else if(aplError!=APL_NET_OK){ClearInternalData();return false;}

			READ_ERR__ADDITIONAL_BUF;
			can_repeat = 0;
			CHECK_REPEAT;
		}while (true);
	}
	if(len == 0)
	{
		// если def_source  не задан или при вызове новой функции получили ошибку - вызываем старую
		// !!! типы параметров  - char* для совместимости с ansi сервером 
		INIT_DATA(CAplTransport__QueryEx,"lb");
		do{
			WRITE_ADDITIONAL_BUF;
			m_TempStore.Add(&(data_in.m_Size),4);
			m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
			CALL_WITH_TEST_PARAM(code,"lblb");
			READ_ERR__ADDITIONAL_BUF;
			can_repeat = 0;
			CHECK_REPEAT;
		}while (true);
	}
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(size),size);
	m_TempStore.Read(&size,4);
	if(size != 0)
	{
		data_out2.SetExternalData(m_TempStore.GetCurBuffer(),size);
	}
	
	return true;
}



//Установить список доступа
bool CTransportSocketClient::AT_DCSetUsersAccess(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__SetUsersAccess,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
	//	CALL_WITH_TEST_PARAM(code,"");
		m_last_calling = __APL_FUNC__;
		if(!Call(m_TempStore,dbuf_ext)){aplError=m_aplError;return false;}
		aplError=TestParamIdent(m_TempStore,code,"");
		if(APL_ERROR_CONDITION){ClearInternalData();return false;}
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

//Установить список доступа
bool CTransportSocketClient::AT_DCSetUsersAccessBI(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__SetUsersAccessBI,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
	//	CALL_WITH_TEST_PARAM(code,"");
		m_last_calling = __APL_FUNC__;
		if(!Call(m_TempStore,dbuf_ext)){aplError=m_aplError;return false;}
		aplError=TestParamIdent(m_TempStore,code,"lb");
		if(APL_ERROR_CONDITION){ClearInternalData();return false;}
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}
//Получить список доступа
bool CTransportSocketClient::AT_DCGetUsersAccess(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__GetUsersAccess,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

//Получить список доступа с упорядочением по инстансам
bool CTransportSocketClient::AT_DCGetUsersAccessBI(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__GetUsersAccessBI,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

//Получить имя схемы и путь к файлу схемы
bool CTransportSocketClient::AT_DCGetDictName(/*[in,out]*/ AplNetErrors &aplError,
					/*[in,out]*/ UINT32 *BufNameSize,/*[in,out, size_is(*BufNameSize)]*/ BYTE *BufName,
					/*[in,out]*/ UINT32 *BufFilePathSize,/*[in,out, size_is(*BufFilePathSize)]*/ BYTE *BufFilePath)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__GetDictName,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"lblb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	m_TempStore.Read(BufNameSize,4);
	m_TempStore.Read(BufName,*BufNameSize);
	m_TempStore.Read(BufFilePathSize,4);
	m_TempStore.Read(BufFilePath,*BufFilePathSize);
	ClearInternalData();
	return true;
}

//Проверяет, есть ли инстансы с данными условиями
bool CTransportSocketClient::AT_DCTestUniqueAttrValues(/*[in,out]*/AplNetErrors &aplError,
													   /*[in]*/ CaplDataBuf &data_in)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__TestUniqueAttrValues,"lb");
	WRITE_ADDITIONAL_BUF;
	m_TempStore.Add(&(data_in.m_Size),4);
	m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
	CALL_WITH_TEST_PARAM(code,"");
	READ_ERR__ADDITIONAL_BUF;
	return true;
}

//Генерит список инстансов с данными условиями
bool CTransportSocketClient::AT_DCFindInstancesWithAttrValuesQuery(/*[in,out]*/AplNetErrors &aplError,
											/*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__FindInstancesWithAttrValuesQuery,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

//Создает и удаляет индексы
bool CTransportSocketClient::AT_DCOperateIndexes(/*[in,out]*/AplNetErrors &aplError, /*[in]*/ UINT32 attr_id, UINT32 state)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__OperateIndexes,"ll");
	WRITE_ADDITIONAL_BUF;
	m_TempStore.Add(&attr_id,4);
	m_TempStore.Add(&state,4);
	CALL_WITH_TEST_PARAM(code,"");
	READ_ERR__ADDITIONAL_BUF;
	ClearInternalData();
	return true;
}

//Проверяет, есть ли
bool CTransportSocketClient::AT_DCTest(/*[in,out]*/AplNetErrors &aplError, /*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__Test,"lb");
	WRITE_ADDITIONAL_BUF;
	m_TempStore.Add(&(data_in.m_Size),4);
	m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
	CALL_WITH_TEST_PARAM(code,"lb");
	READ_ERR__ADDITIONAL_BUF;
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}

	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

//Вернуть для списка инстансов кто и когда их создал/последний раз изменил
bool CTransportSocketClient::AT_DCLoadInstUserDataTimeInfo(/*[in,out]*/AplNetErrors &aplError, 
											/*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__LoadInstUserDataTimeInfo,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(), data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

// Выполняет SQL-запрос и если есть результат - возвращает клиенту (только для ORACLE или Postgre)
bool CTransportSocketClient::AT_DCExecuteSQL(/*[in,out]*/AplNetErrors &aplError,
														   /*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out, LPCTSTR def_source)
{
	data_out.Clear();
	int len = _strlen(def_source);
	if(len != 0)
	{
		// если def_source задан - пытаемся вызвать новую функцию
		// !!! типы параметров  - char* для совместимости с ansi сервером 
		INIT_DATA(CAplTransport__ExecuteSQLS,"lblb");
		do{
			WRITE_ADDITIONAL_BUF;
			m_TempStore.Add(&(data_in.m_Size),4);
			m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);

			m_TempStore.AddStrBuf(def_source);

			//CALL_WITH_TEST_PARAM(code,"lb");
			m_last_calling = __APL_FUNC__;
			if(!Call(m_TempStore,dbuf_ext))
			{
				aplError=m_aplError;
				EnterCriticalSection(&m_CS_TempStore);SetEvent(m_event_TempStore);LeaveCriticalSection(&m_CS_TempStore);return false;
			}
			aplError=TestParamIdent(m_TempStore,code,"lb");
			if(aplError==APL_SOCK_MISSED_FUNCTION)
			{
				ClearInternalData();
				// новой функции на сервере нет - вызовем старую
				len = 0;
				break;
			}
			else if(aplError!=APL_NET_OK){ClearInternalData();return false;}

			READ_ERR__ADDITIONAL_BUF;
			CHECK_REPEAT;
		}while (true);
	}
	if(len== 0)
	{
		// если def_source  не задан или при вызове новой функции получили ошибку - вызываем старую
		// !!! типы параметров  - char* для совместимости с ansi сервером 
		INIT_DATA(CAplTransport__ExecuteSQL,"lb");
		do{
			WRITE_ADDITIONAL_BUF;
			m_TempStore.Add(&(data_in.m_Size),4);
			m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
			CALL_WITH_TEST_PARAM(code,"lb");
			READ_ERR__ADDITIONAL_BUF;
			CHECK_REPEAT;
		}while (true);
	}

	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

// Выполняет SQL-запрос и если есть результат - возвращает клиенту aplExtent (только для ORACLE или Postgre)
bool CTransportSocketClient::AT_DCExecuteSQLEx(/*[in,out]*/AplNetErrors &aplError,
														   /*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out, bool old, CaplDataBuf &data_out2, LPCTSTR def_source)
{
	data_out.Clear();
	data_out2.Clear();
	int len = _strlen(def_source);
	if(len != 0)
	{
		// если def_source задан - пытаемся вызвать новую функцию
		// !!! типы параметров  - char* для совместимости с ansi сервером 
		INIT_DATA(CAplTransport__ExecuteSQLExS,"lblb");
		do{
			WRITE_ADDITIONAL_BUF;
			m_TempStore.Add(&(data_in.m_Size),4);
			m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);

			m_TempStore.AddStrBuf(def_source);

			//CALL_WITH_TEST_PARAM(code,"lblb");
			m_last_calling = __APL_FUNC__;
			if(!Call(m_TempStore,dbuf_ext))
			{
				aplError=m_aplError;
				EnterCriticalSection(&m_CS_TempStore);SetEvent(m_event_TempStore);LeaveCriticalSection(&m_CS_TempStore);return false;
			}
			if(old)aplError=TestParamIdent(m_TempStore,code,"lb");
			else aplError=TestParamIdent(m_TempStore,code,"lblb");
			if(aplError==APL_SOCK_MISSED_FUNCTION)
			{
				ClearInternalData();
				// новой функции на сервере нет - вызовем старую
				len = 0;
				break;
			}
			else if(aplError!=APL_NET_OK){ClearInternalData();return false;}

			READ_ERR__ADDITIONAL_BUF;
			CHECK_REPEAT;
		}while (true);
	}
	if(len== 0)
	{
		// если def_source  не задан или при вызове новой функции получили ошибку - вызываем старую
		// !!! типы параметров  - char* для совместимости с ansi сервером 
		INIT_DATA(CAplTransport__ExecuteSQLEx,"lb");
		do{
			WRITE_ADDITIONAL_BUF;
			m_TempStore.Add(&(data_in.m_Size),4);
			m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
			if(old){CALL_WITH_TEST_PARAM(code,"lb");}
			else{CALL_WITH_TEST_PARAM(code,"lblb");}
			READ_ERR__ADDITIONAL_BUF;
			CHECK_REPEAT;
		}while (true);
	}

	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(size),size);
	if(!old)
	{
		m_TempStore.Read(&size,4);
		if(size != 0)
		{
			data_out2.SetExternalData(m_TempStore.GetCurBuffer(),size);
		}
	}

	return true;
}

// запрашивает служебные параметры БД
bool CTransportSocketClient::AT_DCLoadBDInfo(/*[in,out]*/AplNetErrors &aplError, /*[OUT]*/ CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__LoadBDInfo,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

// запрашивает историю коннекта пользователей
bool CTransportSocketClient::AT_DCQueryUsersLog(/*[in,out]*/AplNetErrors &aplError,
												/*[OUT]*/ CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__QueryUsersLog,"");
	do{
		WRITE_ADDITIONAL_BUF;
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

// запрашивает историю коннекта пользователей c фильтром
bool CTransportSocketClient::AT_DCQueryUsersLogEx(/*[in,out]*/AplNetErrors &aplError, CaplDataBuf &data_in, 
												/*[OUT]*/ CaplDataBuf &data_out)
{
	data_out.Clear();
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__QueryUsersLogEx,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	int size = 0;
	m_TempStore.Read(&size,4);
	data_out.SetExternalData(m_TempStore.GetCurBuffer(),size);
	return true;
}

// чистит историю коннекта пользователей
bool CTransportSocketClient::AT_DCClearUsersLog(/*[in,out]*/AplNetErrors &aplError,
												/*[OUT]*/ CaplDataBuf &data_in)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__ClearUsersLog,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

// Записывает клиентское сообщение в лог и (если ORACLE) в таблицу
bool CTransportSocketClient::AT_DCWriteToLog(/*[in,out]*/ AplNetErrors &aplError,
											 /*[in,out]*/ CaplDataBuf &data_in)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__WriteToLog,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

// Записывает клиентское сообщение в лог и (если ORACLE) в таблицу
bool CTransportSocketClient::AT_DCControlAccessDoc(/*[in,out]*/ AplNetErrors &aplError,/*[in,out]*/ CaplDataBuf &data_in, UINT32 &result)
{
	result = 0;
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__ControlAccessDoc,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"l");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	if(APL_ERROR_CONDITION)
	{
		ClearInternalData();
		return false;
	}
	m_TempStore.Read(&result,4);
	ClearInternalData();
	return true;
}

// 
bool CTransportSocketClient::AT_DCRunUpdateDictionary(/*[in,out]*/ AplNetErrors &aplError, /*[in,out]*/ CaplDataBuf &data_in)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__RunUpdateDictionary,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

// 
bool CTransportSocketClient::AT_DCRunApp(/*[in,out]*/ AplNetErrors &aplError,
											 /*[in,out]*/ CaplDataBuf &data_in)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__RunApp,"lb");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

// Копирование доступа поинстансово с экстента на экстент
bool CTransportSocketClient::AT_DCCopyAccessFromExt2Ext(/*[in,out]*/AplNetErrors &aplError,
												/*[IN]*/ CaplDataBuf &data_1, /*[IN]*/ CaplDataBuf &data_2,
												int code1, int code2)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__CopyAccessFromExt2Ext,"lblbll");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_1.m_Size),4);
		m_TempStore.Add(data_1.GetBuffer(),data_1.m_Size);
		m_TempStore.Add(&(data_2.m_Size),4);
		m_TempStore.Add(data_2.GetBuffer(),data_2.m_Size);
		WriteExtBufData;
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

// Копирование доступа поинстансово с инстанса на экстент
bool CTransportSocketClient::AT_DCCopyAccessFromInst2Ext(/*[in,out]*/AplNetErrors &aplError,
												/*[OUT]*/ CaplDataBuf &data_in, int code1, int code2)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA(CAplTransport__CopyAccessFromInst2Ext,"lbll");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&(data_in.m_Size),4);
		m_TempStore.Add(data_in.GetBuffer(),data_in.m_Size);
		WriteExtBufData;
		CALL_WITH_TEST_PARAM(code,"");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}

// Запрос доступного метода аутентификации - один раз перед логином
bool CTransportSocketClient::AT_DCServiceGetAuthParam(/*[in,out]*/ AplNetErrors &aplError, UINT32 param, CString &value)
{
	value = _T("");
	// !!! типы параметров  - char* для совместимости с ansi сервером
	INIT_DATA(CAplTransport__ServiceGetAuthParam,"l");
	do{
		WRITE_ADDITIONAL_BUF;
		m_TempStore.Add(&param, 4);
		CALL_WITH_TEST_PARAM(code,"lb");
		READ_ERR__ADDITIONAL_BUF;
		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	m_TempStore.m_ansi_string = m_data->m_global_ansi_string;
	m_TempStore.ReadStrBuf(value);
	return true;
}


// Проверка соответствия версий буферов сервера и клиента - один раз при логине
bool CTransportSocketClient::AT_DCServiceTestVersions(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in)
{
	// !!! типы параметров  - char* для совместимости с ansi сервером 
	INIT_DATA_D(CAplTransport__ServiceTestVersions,"lb");
	do{
		WRITE_ADDITIONAL_BUF_DEF_BUF(dbuf);

		dbuf.Add(&(data_in.m_Size),4);
		dbuf.Add(data_in.GetBuffer(),data_in.m_Size);
		//CALL_WITH_TEST_PARAM(code,"");
		m_last_calling = __APL_FUNC__;
		if(!Call(dbuf,dbuf_ext)){aplError=m_aplError;return false;}
		aplError=TestParamIdent(dbuf,code,"");

		if(aplError==APL_SOCK_MISSED_VERSION)
		{
			code=CAplTransport__ServiceTestVersions;
			ClearInternalData();
			m_used_version--;
			if(m_used_version < VERSION_OF_RPC_BUFFER) break;
			continue;
		}
		if(aplError!=APL_NET_OK){ClearInternalData();return false;}


		//READ_ERR__ADDITIONAL_BUF;
		dbuf.Read(&aplError,4);
		dbuf_add.Clear();
		if(m_used_version>=VERSION_OF_RPC_BUFFER_2)
		{
			dbuf.Read(&size_add,1);/*была ли ошибка*/
			if(size_add>0)
			{
				dbuf.Read(&can_repeat,1);
			}/*флаг возможности повтора операции по запросу клиента*/
			// чтение серверного сообщения об ошибке
			TEST_READ_SERV_ERR(dbuf);
		}

		CHECK_REPEAT;
	}while (true);
	ClearInternalData();
	if(APL_ERROR_CONDITION)
	{
		return false;
	}
	return true;
}


bool CTransportSocketClient::IsOperated()
{
	if(m_aplSocket== 0)return false;
	// если операция уже проводится - больше ничего делать нельзя!
	return m_aplSocket->IsOperated();
}


bool CTransportSocketClient::Connect(bool bDlgMode /*= true*/)
{
	bool ret;
	CaplSocketClient* aplSocket_tmp;
	UINT old_manage_mode = bDlgMode?MANAGE_WAITDLG:MANAGE_ABSENT;

	if(m_data==0)
		return false;
	if(m_aplSocket != 0)
		old_manage_mode = m_aplSocket->GetManageMode();

	if(m_internal_reconnect!=2)
	{
		if(m_aplSocket != 0)
			delete m_aplSocket;
		m_aplSocket = 0;
	}
	if(m_cif->protocol == 0)
	{
		aplSocket_tmp = new CaplSocketClient();
		aplSocket_tmp->m_parent_wnd = m_parent_wnd;
#ifndef _UNICODE
// 		if(m_data->m_Ini.GetInt(_T("Options"), _T("AllowUnicodeServer"), 0)==1)
// 			aplSocket_tmp->m_DenyServerUnicode=false;
#endif
	}
	else
	{
		aplSocket_tmp = new CaplSocketClientH();
		ResetTimer(2,this);
	}
	if(aplSocket_tmp== 0)return false;
	aplSocket_tmp->SetManageMode(old_manage_mode);
	aplSocket_tmp->external_close_funct = GlobalClose;
	aplSocket_tmp->external_reconnect_funct = GlobalReconnect;
	aplSocket_tmp->m_upper_container =(LPVOID)this;
	aplSocket_tmp->m_hide_mode = m_hide_mode;
	int data_i = 0;
	m_tmp_buf.Add(&data_i,4);
	m_tmp_buf.Add(&data_i,4);
	m_tmp_buf.Add(&data_i,4);

	ret = aplSocket_tmp->Connect(m_cif->comp_name, m_cif->port, prev_ping, m_cif->proxy, num_prev_ping);

	if(m_data != 0)
		m_data->m_global_ansi_string = aplSocket_tmp->m_ServerAnsi;

	if(m_internal_reconnect == 2)
	{
		if(ret)
		{
			if(m_aplSocket != 0) delete m_aplSocket;
			m_aplSocket = aplSocket_tmp;
		}
		else
		{
			delete aplSocket_tmp;
		}
	}
	else 
	{
		// даже при ошибке нам нужен нормальный m_aplSocket, чтобы впоследствии определить код ошибки
		m_aplSocket = aplSocket_tmp;
	}
	m_thread_id = GetCurrentThreadId();
	return ret;
}

void CTransportSocketClient::OnClose()
{
	CaplStackLogger stack_logger(__APL_FUNC__);
	if(m_aplSocket != 0)
	{
		m_server_stopping=m_aplSocket->m_ServerStopping;
		m_need_relogin=m_aplSocket->m_need_relogin;
	}
	try{
		Disconnect();
		Reconnect(true,_T(__FILE__),__LINE__,_T(__DATE__));	
	}
	catch(SaplErrorDescription error)
	{
		// здесь ничего не сделать. Только код ошибки присвоить
		m_aplError=(AplNetErrors )error.m_err_code;
	}
}

void CTransportSocketClient::Disconnect()
{
	CaplStackLogger stack_logger(__APL_FUNC__);
	if(m_aplSocket != 0)
	{
		if(m_aplSocket->IsActiveWaitDlg())
		{
			m_aplSocket->m_NeedAutoDelete = true;
		}
		else
		{
			delete m_aplSocket;
		}
	}
	m_thread_id = 0;
	CloseReconnectDlg();

	m_aplSocket = 0;
}

bool CTransportSocketClient::IsConnected()
{
	if(m_aplSocket== 0)return false;
	return m_aplSocket->IsConnected();
}

bool CTransportSocketClient::Reconnect(bool asked, LPCTSTR file, int line, LPCTSTR date)
{
	CaplStackLogger stack_logger(__APL_FUNC__);

	CString str = _T("");

	if(m_internal_reconnect>0)return false;
	if(m_hide_mode && !AutoReconnect)return false;
	if(!m_need_reconnect) return true;


	if(m_need_relogin)
	{
		str = APL_T("Сервер запрашивает повторную авторизацию, так как время бездействия превысило заданный интервал.");
	}
	else if(m_server_stopping)
	{
		str = APL_T("Сервер был остановлен. Обратитесь к администратору для выяснения обстоятельств.");
	}
	else
	{
		str = APL_T("Соединение с сервером было разорвано по неизвестной причине.");
	}

	m_MainLog.LogMessage( str, false, true, true, false, 0, m_class_info, 0, file, date, line);

	if(m_need_relogin)
	{
		do
		{
			if(AfxMessageBox(APL_T("Для продолжения работы необходимо повторно авторизоваться в БД. Выберите \"Да\" если вы желаете продолжить работу, \"Нет\" если желаете завершить работу"), MB_YESNO)
				== IDNO)
			{
				if(m_application_close_funct == 0)
				{
					CWnd *wnd = AfxGetMainWnd();
					if(wnd != 0) wnd->PostMessage(WM_SYSCOMMAND,SC_CLOSE,0);
				}
				else
				{
					if(m_application_close_funct(m_data) == -1)
					{
						continue;
					}
				}
				// а иначе - после этого вызова скорее всего приложение уже наполовину выключено. Так что бежать, бьежать, бежать
				return false;
			}

			if(m_data->NET_Connect(_T(""), _T(""), _T(""), m_data->m_type_lic_current))
			{
				break;
			}

		}while(true);
	}
	else if(!m_hide_mode && asked && !AutoReconnect)
	{
		str+= _T("\n");
		str+= APL_T("Можно восстановить соединение. Если соединение восстановить не удается - рекомендуем завершить работу");
		if(m_application_reconnect_text != _T(""))
		{
			str = m_application_reconnect_text;
		}

		if(m_dlg_reconnect == 0)
		{
			do 
			{
				bool exit = false;

				CaplSetResourceHandle res_handle(module_inst);
				CDlgReconnect *dlg_reconnect;
				m_dlg_reconnect = new CDlgReconnect();
				dlg_reconnect = m_dlg_reconnect;
				m_dlg_reconnect->m_transport=this;
				m_dlg_reconnect->MakeText(str);
				exit=(m_dlg_reconnect->DoModal() == -1);
				delete dlg_reconnect;
				m_dlg_reconnect = 0;
				res_handle.RestoreHandle();
				if(exit)
				{
					if(m_application_close_funct == 0)
					{
						CWnd *wnd = AfxGetMainWnd();
						if(wnd != 0) wnd->PostMessage(WM_SYSCOMMAND,SC_CLOSE,0);
					}
					else
					{
						if(m_application_close_funct(m_data) == -1)
						{
							continue;
						}
					}
					// а иначе - после этого вызова скорее всего приложение уже наполовину выключено. Так что бежать, бьежать, бежать
					return false;
				}
				else
				{
					break;
				}
			} while (true);
// 			m_dlg_reconnect->Create(IDD_RECONNECT_DIALOG,0);
// 			m_dlg_reconnect->ShowWindow(SW_SHOW);
// 			m_dlg_reconnect->SetForegroundWindow();
		}
	}
	if(!asked || AutoReconnect)
	{
		m_internal_reconnect=1;
		if(!ForceReconnect())
			return false;
	}
	return true;
}

bool CTransportSocketClient::ForceReconnect()
{
	bool ret = true;
	AplNetErrors aplError = APL_NET_OK;
	DWORD res;
	CString str;

	//?? long size = 0;
	bool can_no = true;


	CWnd* main_cwnd=AfxGetMainWnd();
	HWND m_hwnd = (main_cwnd==0 ? 0 : main_cwnd->m_hWnd);

	if(m_internal_reconnect!=2)	LogMessWF( APL_T("Попытка восстановить соединение"));
	//else LogMessWF( APL_T("Переконнект по команде сервера"));

	try{
		do{
			if(m_internal_reconnect==2)
			{
				SetWaitDlgText( APL_T("Переконнект по команде сервера"));
				if(m_login_data.pwd.Right(1) == _T('^') && !m_is_saved_login)
				{
					// Это временный пароль. Надо получать новый временный пароль
					CString pwd4rectore;
					if(AT_DCGetString4DupSession(pwd4rectore))
						m_login_data.pwd = pwd4rectore;
					else
					{
						m_need_relogin = true;
						m_data->ConnectWithParam(CONNECT_DLG_MODE__SHOW_ALVAYS);
					}
				}
			}
			else if(AutoReconnect)
			{
				SetWaitDlgText( APL_T("Соединение с сервером было разорвано. Идет восстановление соединения с БД"));
			}
			else
			{
				SetWaitDlgText( APL_T("Идет восстановление соединения с БД"));
			}
			ret=ConnectWithTestLocal(m_cif,m_def_server_name);
			if(!ret)
			{
				if(m_internal_reconnect!=2) AfxMessageBox( APL_T("Сервер недоступен. Восстановить соединение не удалось"));
				if(m_internal_reconnect==2) m_internal_reconnect = 0;
				return false;
			}
			CaplDataBuf test_ver_buf;
			int code, size;
			CStringA cs_buf;

			FILL_SERVICE_TEST(std_databuf);
			// чтобы новый сервер передал наш сокет в дополнительный сервер - придется теперь вызывать эту функцию
			if(!AT_DCServiceTestVersions(aplError, test_ver_buf) || aplError == APL_NET_SRV_MISSED_BUF_FORMAT)
			{
				if(!m_hide_mode )
				{
					if(aplError == APL_SOCK_CONNECT_FAULT || aplError == APL_SOCK_ERROR_PROCESSED)
					{
						continue;
					}
					else
					{
						res = MessageBox(m_hwnd,
							 APL_T("Версия сервера устарела. Обновите сервер приложений \n или обратитесь к системному администратору"),
							 APL_T("Служба RPC PDM Step Suite"),
							MB_OK | MB_TOPMOST | MB_TASKMODAL | MB_SYSTEMMODAL | MB_ICONEXCLAMATION);
					}
				}
				aplError = APL_NET_SRV_NOT_CONNECT;
				MY_THROW(aplError);
			}

			if(m_login_data.isCurrDomainUser /*isKerberos*/)
			{
				try{
					DC_AuthExternal(m_login_data.username, m_login_data.pwd, m_login_data.domain);
				}
				catch(SaplErrorDescription &error)
				{
					if(m_internal_reconnect==2)
						m_description_serv_error = APL_T("Переконнект по команде с сервера завершился ошибкой:\n");
					else
						m_description_serv_error = APL_T("Попытка восстановления соединения завершилась ошибкой:\n");

					m_description_serv_error+= APL_NET_ERROR2char(error.m_err_code);
					m_description_serv_error+= error.m_err_descr;
					if(!m_hide_mode)
					{
						str= m_description_serv_error;
						if(m_internal_reconnect==2)
							str += APL_T("\nПовторить попытку переконнекта?");
						else
							str += APL_T("\nПовторить попытку восстановления соединения?");

						if(aplMessageBox( str,
							MB_TASKMODAL | MB_ICONERROR | MB_YESNO)==IDNO)
						{
							if(m_internal_reconnect==2)
								str = APL_T("Переконнект по команде с сервера завершился ошибкой, соединение разорвано");
							else
								str = APL_T("Соединение с сервером не восстановлено");
							LogErrorWF(str);
							aplMessageBox( str);
							break;
						}
					}
				}
			}

			ret=AT_DCConnectEx(aplError);

			if(!ret || (aplError !=APL_NET_OK && aplError!=APL_NET_SRV_APPROACH_EXPIRE_SRC_LIC_SRV
					&& aplError!=APL_NET_SRV_USER_READ_ONLY))
			{
				if(aplError==APL_NET_SRV_SINGLE_CONNECT_DB)
				{
					str = APL_T("Не найден сервер лицензий. Работа идет\n в режиме эксклюзивного доступа.\n");
					can_no = false;
				}
				else if(aplError==APL_NET_SRV_MISSED_KEY_IN_SRV_LIC)
				{
					str = APL_T("Сервер лицензий не нашел аппаратный ключ.\n Работа идет в режиме эксклюзивного доступа.");
					can_no = false;
				}
				else if(aplError==APL_NET_SRV_SINGLE_CONNECT_LITE_D)
				{
					str = APL_T("Сервер приложений не нашел аппаратный ключ.\n Работа идет в режиме эксклюзивного доступа. \n После установки ключа перезапустите сервер.");
					can_no = false;
				}
				else if(aplError==APL_NET_SRV_USER_READ_ONLY)
				{
					str = APL_T("Ваш доступ к БД ограничен чтением.\n");
					can_no = false;
				}
				else if(aplError==APL_NET_SRV_MISSED_NAME_BASE)
				{
					str.Format(
						 APL_T("Последняя активная база данных с именем %s \n недоступна через текущий сервер приложений.\n Возможно, при восстановлении соединения автоматически\n запустился неверный сервер приложений\n"),
							m_login_data.name_base);
				}
				else if(aplError==APL_NET_SRV_UNKNOWN_USER)
				{
					str=
						 APL_T("Неправильное имя пользователя или пароль. \n Возможно, при восстановлении соединения автоматически\n запустился неверный сервер приложений\n");
				}
				else
				{
					str = APL_T("При попытке восстановления соединения с БД возникла ошибка:\n");
					str+= APL_NET_ERROR2char(aplError);
				}
				
				if(m_hide_mode)
				{
					m_description_serv_error = str;
					return false;
				}
				if(can_no)
				{
					if(m_internal_reconnect==2)
						str+= APL_T("\nПереконнект по команде с сервера завершился ошибкой. Повторить попытку переконнекта?");
					else
						str+= APL_T("\nПовторить попытку восстановления соединения?");

					if(MessageBox(m_hwnd, str, APL_T("Служба RPC PDM Step Suite"),
						MB_TASKMODAL | MB_ICONERROR | MB_YESNO)==IDNO)
					{
						if(m_internal_reconnect==2)
							str = APL_T("Переконнект по команде с сервера завершился ошибкой, соединение разорвано");
						else
							str = APL_T("Соединение с сервером не восстановлено");
						LogErrorWF(str);
						AfxMessageBox( str);
						break;
					}
				}
				else
				{
					// Дополнительные лицензии
					if(m_IsServer4AddLic && m_data->m_types_lic_adt.GetSize() > 0)
					{
						AplNetErrors m_aplError;
						CStringArray tested_lic; tested_lic.Append(m_data->m_types_lic_adt);
						AT_DCLicOperate(m_aplError, LO_TestTake, tested_lic, m_data->m_types_lic_adt);
						ClearInternalData();
					}

					if(m_internal_reconnect==2)
						LogMessWF( APL_T("При переконнекте по команде с сервера возникли предупреждения: ") + str);
					else
						LogMessWF( APL_T("Соединение восстановлено. При установке соединения возникли предупреждения: ") + str);
					if(!m_hide_mode)
					{
						MessageBox(m_hwnd, str, APL_T("Служба RPC PDM Step Suite"), MB_TASKMODAL | MB_ICONERROR | MB_OK);
					}
					m_internal_reconnect = 0;
					return true;
				}
			}
			else
			{
				// Дополнительные лицензии
				if(m_IsServer4AddLic && globalRequestedAddLicenses.GetSize() > 0)
				{
					AplNetErrors m_aplError;
					CStringArray tested_lic; tested_lic.Append(m_data->m_types_lic_adt);
					AT_DCLicOperate(m_aplError, LO_TestTake, tested_lic, m_data->m_types_lic_adt);
					ClearInternalData();
				}

				if(m_am_user != _T("") || m_am_code1  != 0)
				{
					UINT32 admin_user_id;
					ret=AT_DCStartAdminMode(aplError, m_am_user, m_am_pwd, &admin_user_id, m_am_code1, m_am_code2, APL_T("Восстановление режима администратора"));

					if(!ret || (aplError!=APL_NET_OK && aplError!=APL_NET_SRV_APPROACH_EXPIRE_SRC_LIC_SRV))
					{
						str = APL_T("При попытке восстановления соединения с БД возникла ошибка:\n");
						str += APL_NET_ERROR2char(aplError);

						if(!m_hide_mode)
						{
							MessageBox(m_hwnd,str, APL_T("Служба RPC PDM Step Suite"),MB_TASKMODAL | MB_ICONERROR | MB_OK);
						}
						m_description_serv_error=str;
						return false;
					}
				}

				if(m_internal_reconnect==2)
				{
					;//LogMessWF( APL_T("Успешно выполнен переконнект по команде с сервера")); - убрали чтобы не перегружать лог
				}
				else
					LogMessWF( APL_T("Соединение успешно восстановлено"));

				m_internal_reconnect = 0;
				if(m_aplSocket != 0)
				{
					m_aplSocket->SetRenewFunction(::RenewClientStateOnServer,(LPVOID)this);
				}
				return true;
			}

		}while(true);
	}
	catch(SaplErrorDescription error)
	{
		m_internal_reconnect = 0;		
		//throw(error);
	}
	m_internal_reconnect = 0;		

	return false;
}

// Внимание! При ошибке генерит исключение!
bool CTransportSocketClient::ConnectWithTestLocal(CConnectInfo* cif, CString def_server_name, bool foreground_main_wnd, bool bDlgMode /*= true*/)
{
	LogDebugMessageIfDef(_T("CTransportSocketClient::ConnectWithTestLocal begin"));

	if(m_cif==0)
	{
		if(!m_hide_mode)AfxMessageBox( APL_T("Переменная m_cif не инициализирована!"),MB_OK | MB_ICONERROR);
		return false;
	}
	if(cif == 0)
	{
		if(m_cif->id==-1)
		{
			if(!m_hide_mode)AfxMessageBox( APL_T("Не заданы параметры для соединения с БД!"),MB_OK | MB_ICONERROR);
			return false;
		}
	}
	else
	{
		m_cif->Set(cif);
		m_def_server_name = def_server_name;
	}

	
	CString str;
	if(m_internal_reconnect == 1)
	{
		str.Format( APL_T("Соединение с сервером %s:%i было разорвано. Восстанавливаем..."), cif->comp_name, cif->port);
	}
	else if(m_internal_reconnect==2)
	{
		str.Format( APL_T("Производим переконнект по команде сервера %s:%i ..."), cif->comp_name, cif->port);
	}
	else
	{
		str.Format( APL_T("Устанавливаем соединение с сервером %s:%i"),cif->comp_name, cif->port);
	}
	long wait_dlg_h = 0;
	if(!m_hide_mode && cif->protocol == 0)
	{
		wait_dlg_h = StartTransportWaitDlg(str);
	}
	UINT res_exec = 0;
	BOOL res_se = false;

	try
	{
		if(!Connect(bDlgMode))
		{
			// при переконнекте по команде с сервера все ошибки игнорируем и просто продолжаем работать
			if(m_internal_reconnect==2)
			{
				EndTransportWaitDlg(wait_dlg_h,foreground_main_wnd);
				return false;
			}
			if(GetLastAscError()==ASC_ERROR_SERVER_UNICODE)
			{
				MY_THROW_EX(APL_NET_CLI_NOT_CONNECT, ERR_MESS_SERVER_U_CLIENT_A);
			}
			// Проверка на отсутствующий локальный сервер
			if(m_cif->protocol == 0 && (GetLastAscError()==ASC_ERROR_IN_CONNECT || m_isGlobalClose) && def_server_name != _T(""))
			{
				if(IsServerLocal())
				{
					// Так, попытаемся сами запустить локальный сервер с нужным нам портом
					if(IsBreakTransportWaitDlg(wait_dlg_h))
					{
						MY_THROW(APL_NET_CLI_BREAK);
					}
					
					str.Format( APL_T("Пытаемся запустить %s:%i"),def_server_name,cif->port);
					if(!m_hide_mode)
					{
						SetTransportWaitDlgText(wait_dlg_h,str);
					}
					
					// перед запуском ждем пол секунды - мало ли что, например, предыдущий сервер никак не умрет
					Sleep(500);
					str.Format(_T(" /p:%i /h"), cif->port);

#ifdef _UNICODE
					CString cmd = def_server_name + _T(" ") + str;
					CaplStringAdapter str_ad(cmd);
					res_exec = WinExec((const char*)str_ad, SW_MINIMIZE);
#else // #ifdef _UNICODE
					res_exec = WinExec(def_server_name + " " + str, SW_MINIMIZE);
#endif // #ifdef _UNICODE

					if(res_exec == 0 && GetLastError() == 0x02e4)
					{
						SHELLEXECUTEINFO shExecInfo;

						shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

						shExecInfo.fMask = NULL;
						shExecInfo.hwnd = NULL;
						shExecInfo.lpVerb = (LPCTSTR)_T("runas");
						shExecInfo.lpFile = (LPCTSTR)def_server_name;
						shExecInfo.lpParameters = (LPCTSTR)str;
						shExecInfo.lpDirectory = NULL;
						shExecInfo.nShow = SW_MINIMIZE;
						shExecInfo.hInstApp = NULL;

						res_se=ShellExecuteEx(&shExecInfo);
					}
					if(res_exec>31 || res_se==TRUE)
					{
						bool flag = true;
						// Ждем, когда же...
						for(int i = 0;i<100;i++)
						{
							if(IsBreakTransportWaitDlg(wait_dlg_h))
							{
								MY_THROW(APL_NET_CLI_BREAK);
								break;						
							}
							Sleep(300);
							if(Connect(bDlgMode))
							{
								flag = false;
								break;
							}
							if(m_aplSocket!=0 && m_aplSocket->GetLastAscError()==ASC_ERROR_MISSED_VERSION)
							{
								MY_THROW(APL_NET_CLI_NET_ERROR);
								break;
							}
							// если запускали без повышений привилений - каждый 9-й раз пытаемся запустить еще раз
							if(res_se== false && div(i,10).rem==9)
							{
#ifdef _UNICODE
								res_exec = WinExec((const char*)str_ad, SW_MINIMIZE);
#else // #ifdef _UNICODE
								res_exec = WinExec(def_server_name + " " + str, SW_MINIMIZE);
#endif // #ifdef _UNICODE
								
								if(res_exec<31)
								{
									MY_THROW_EX(APL_NET_CLI_LOCAL_SERV_NOT_FOUND, _T("'") + def_server_name + _T("'"));
								}
							}
						}
						if(flag)
						{
							MY_THROW(APL_NET_CLI_NOT_CONNECT);
						}
					}
					else
					{
						MY_THROW_EX(APL_NET_CLI_LOCAL_SERV_NOT_FOUND, _T("'") + def_server_name + _T("'"));
					}
				}
				else
				{
					MY_THROW(APL_NET_CLI_NET_ERROR);
				}
			}
			else
			{
				MY_THROW(APL_NET_CLI_NET_ERROR);
			}
		}
		GetCompName();
	}
	catch(SaplErrorDescription error)
	{
		EndTransportWaitDlg(wait_dlg_h, foreground_main_wnd);
		if(m_aplSocket != 0)
		{
			if(error.m_err_code == APL_NET_CLI_NET_ERROR)
			{
				m_ascError = m_aplSocket->GetLastAscError();
				m_wsaError = m_aplSocket->GetLastWsaError();
				//}else if(error.m_err_code ==APL_NET_CLI_FNF)
			}
			else if(error.m_err_code == APL_NET_CLI_FNF)
			{
				m_ascError=ASC_ERROR_IN_SOCKET;
				m_wsaError=res_exec;
			}
			delete m_aplSocket;
		}
		m_aplSocket = 0;
		throw(error);
		m_isGlobalClose = false;
		return false;
	}

	EndTransportWaitDlg(wait_dlg_h,foreground_main_wnd);
	LogDebugMessageIfDef(_T("CTransportSocketClient::ConnectWithTestLocal end"));
	m_isGlobalClose = false;
	return true;
}

// рассоединение на уровне tcp
void CTransportSocketClient::DisconnectFull()
{
	ResetTimer(1);
	if(IsConnected())
	{
		AplNetErrors aplError = APL_NET_OK;

		AT_DCDisconnect(aplError);
		ClearInternalData();
		Disconnect();
	}
}


void CTransportSocketClient::ClearInternalData()
{
	if(m_aplSocket != 0) 
		m_aplSocket->ClearInternalData();
	//m_TempStore.Clear(); - не надо, а то при реконнекте потеряются предыдущие данные. Все равно в деструкторе класса память освободится
	m_source = _T("");
	
	EnterCriticalSection(&m_CS_TempStore);	
	SetEvent(m_event_TempStore);
	LeaveCriticalSection(&m_CS_TempStore);

	int data_i = 0;
	memcpy((BYTE*)(m_tmp_buf.GetBuffer())+4,&data_i,4);
	memcpy((BYTE*)(m_tmp_buf.GetBuffer())+8,&data_i,4);
}

bool CTransportSocketClient::GetCompName(CString &name)
{
	if(m_CompName != _T(""))
	{
		name = m_CompName;
		return true;
	}
	if(m_aplSocket== 0)
	{
		name = _T("");
		return false;
	}
	bool retval = GetCompName();
	name = m_CompName;
	return retval;
}

bool CTransportSocketClient::GetCompName()
{
	if(m_aplSocket== 0)
	{
		m_CompName = _T("");
		return false;
	}
	return m_aplSocket->GetHostName(m_CompName);
}


bool CTransportSocketClient::TestTempStoreFree(bool block)
{
	DWORD res;
	bool ret_val = false;
	int counter = 10;

	while(counter > 0 && !ret_val)
	{
		counter--;

		EnterCriticalSection(&m_CS_TempStore);
		res=WaitForSingleObject(m_event_TempStore,200);
		switch(res)
		{
		case WAIT_TIMEOUT:
			ret_val = false;
			LeaveCriticalSection(&m_CS_TempStore);
			break;
		case WAIT_OBJECT_0:
		case WAIT_FAILED:
		default:
			if(block){ResetEvent(m_event_TempStore);}
			LeaveCriticalSection(&m_CS_TempStore);
			ret_val = true;
			break;
		}
	}

	return ret_val;
}

CString	CTransportSocketClient::GetDescriptionLastError()
{
	CString str = _T("");
	if(m_aplSocket != 0)
	{
		return m_aplSocket->GetDescriptionLastError();
	}
	else
	{
		::GetDescriptionTransportError(m_ascError,m_wsaError,str);
	}
	return str;
}

CString	CTransportSocketClient::GetDescriptionServError()
{
	if(m_description_serv_error.GetLength()>=250 && m_used_version>=VERSION_OF_RPC_BUFFER_2)
	{
		CString txt=m_description_serv_error;
		txt+= APL_T("...\nВнимание! Полное описание ошибки помещено в лог сервера");
		return txt;
	}
	return m_description_serv_error;
}


void CTransportSocketClient::SetWaitDlgText(LPCTSTR waitdlg_text)
{
	if(m_aplSocket != 0) 
		m_aplSocket->SetWaitDlgText(waitdlg_text);
}

void CTransportSocketClient::SetBreak(bool state)
{
	if(m_aplSocket != 0)
		m_aplSocket->SetBreak(state);
}

void CTransportSocketClient::SetManageMode(int manage_mode)
{
	if(m_aplSocket != 0) 
		m_aplSocket->SetManageMode(manage_mode);
}

void CTransportSocketClient::SetHideMode(bool mode)
{
	m_hide_mode=mode;
	if(m_aplSocket != 0)m_aplSocket->m_hide_mode=mode;
}

void CTransportSocketClient::Attach()
{
	if(m_aplSocket != 0 &&m_temp_socket != 0)
	{
		m_aplSocket->Attach(m_temp_socket);
		m_aplSocket->m_thread_id = GetCurrentThreadId();
	}
	m_thread_id = GetCurrentThreadId();
	m_temp_socket = 0;
}

void CTransportSocketClient::Detach()
{
	if(m_temp_socket== 0)
	{
		if(m_aplSocket== 0)
		{
			m_temp_socket=0;
		}
		else
		{
			m_aplSocket->m_thread_id = 0;
			m_temp_socket=m_aplSocket->Detach();
		}
	}
	m_thread_id = 0;
}

void CTransportSocketClient::SetHalt()
{
	if(m_aplSocket != 0)
	{
		m_aplSocket->SetHalt();
	}
}

void CTransportSocketClient::SetApplicationLevelLogMessage(bool (__cdecl *_ApplicationLevelLogMessageDlg)(LPCTSTR message))
{
	if(m_aplSocket != 0)m_aplSocket->SetApplicationLevelLogMessage(_ApplicationLevelLogMessageDlg);
}

inline bool IsIpBlock(CString &str)
{
	int i = _atoi(str);
	if(i==0)
	{
		if(str==_T("0"))return true;
		return false;
	}
	if(i>255)
		return false;
	return true;
}

bool CTransportSocketClient::IsServerLocal()
{
	CString serv_ip = _T("");
	CString my_host_name;
	if(m_aplSocket != 0)
	{
		if(m_aplSocket->GetHostName(my_host_name))
		{
			if(m_aplSocket!=0 && m_aplSocket->IsConnected()){serv_ip = m_aplSocket->GetCompName();}
			else if (m_cif->id!=-1){serv_ip = m_cif->comp_name;}
			else return false;

			my_host_name.MakeLower();
			serv_ip.MakeLower();

			if(serv_ip==my_host_name || serv_ip==_T("localhost"))
				return true;
			if(serv_ip==_T("127.0.0.1")) // это сравнение оставляем для ускорения, но loopback чуть побольше - это 127.*.*.*
				return true;
			if(serv_ip.Left(4)==_T("127.")) // расширенный анализ IP loopback
			{
				CString str;
				int p0 = 3;
				int p1 = serv_ip.Find(_T("."), p0+1);
				if(p1==-1) return false;
				int p2 = serv_ip.Find(_T("."), p1+1);
				if(p2==-1) return false;
				str = serv_ip.Mid(p0+1, p1-p0-1);
				if(!IsIpBlock(str)) return false;
				str = serv_ip.Mid(p1+1, p2-p1-1);
				if(!IsIpBlock(str)) return false;
				str = serv_ip.Mid(p2+1);
				if(!IsIpBlock(str)) return false;
				return true;
			}
		}
	}
	return false;
}



void TestReadServError(CaplDataBuf &readed_data_buf, CaplNetStepData* m_data, CString &m_description_serv_error)
{
	BYTE size_add;
	m_description_serv_error = _T("");
	readed_data_buf.Read(&size_add,1);/*длина серверного сообщения об ошибке в символах*/

#ifdef _UNICODE
	if(size_add>0)
	{
		if(m_data->m_global_ansi_string )
		{
			char* cb  =new char[size_add];
			readed_data_buf.Read(cb,size_add);
			CaplStringAdapter str_ad(cb);
			m_description_serv_error = (TCHAR*)str_ad;
			delete[] cb;/*сообщение об ошибке*/
		}
		else
		{
			// юникодные строки всегда передаются в UCS2
			int strUcs2Len=0, strUtf32Len=0;
			strUcs2Len=size_add*2; // 2байта на символ

			char* cb  =new char[strUcs2Len];
			readed_data_buf.Read(cb, strUcs2Len);

			ASSERT(2==sizeof(TCHAR));
			m_description_serv_error = (TCHAR*)cb;

			delete[] cb;/*сообщение об ошибке*/


		}
	}
#else // #ifdef _UNICODE
// 	if(m_data!=0)
// 	{
// 		if(!m_data->m_global_ansi_string )
// 			APL_THROW_EX(APLAPIERR_INCOMPATIBLDATAFORMAT,CString( APL_T("Сервер требует для работы UNICODE версию клиента. Операция не выполнена.")));
// 	}

	if(size_add>0)
	{
		if(m_data->m_global_ansi_string )
		{
			char* cb=new char[size_add];
			readed_data_buf.Read(cb,size_add);
			m_description_serv_error=cb;
			delete[] cb;/*сообщение об ошибке*/
		}
		else
		{
			// юникодные строки всегда передаются в UCS2
			int strUcs2Len=0, strUtf32Len=0;
			strUcs2Len=size_add*2; // 2байта на символ

			char* cb  =new char[strUcs2Len];
			readed_data_buf.Read(cb, strUcs2Len);

			CaplStringAdapter str_ad((const wchar_t*)cb);
			m_description_serv_error = (LPCTSTR)str_ad;

			delete[] cb;/*сообщение об ошибке*/
		}
	}

#endif // #ifdef _UNICODE

}

//?? вместо #define ADD_SOURCE_2_BUF(dbuf)
void CTransportSocketClient::AddSource2Dbuf(CaplDataBuf &dbuf)
{
	BYTE size_source_b = 0;
	int size_source_i = m_source.GetLength();
	if(size_source_i > 255){size_source_b = 255;}else{size_source_b = (BYTE)size_source_i;}

#ifdef _UNICODE

	if(size_source_b>0)
	{
		if(dbuf.m_ansi_string)
		{
			CaplStringAdapter str_ad(m_source);
			dbuf.Add(&size_source_b, 1);
			dbuf.Add((void*)(const char*)str_ad, size_source_b);
		}
		else
		{

			ASSERT(2==sizeof(TCHAR));
			dbuf.Add(&size_source_b, 1);
			dbuf.Add((void*)m_source.GetBufferSetLength(size_source_b), size_source_b*sizeof(TCHAR));
		}
	}
	else
	{
		size_source_b = 0;
		dbuf.Add(&size_source_b, 1);
	}

#else // #ifdef _UNICODE

	if(m_data->m_global_ansi_string )
	{
		dbuf.Add(&size_source_b, 1);
		if(size_source_b>0)
		{
			dbuf.Add(m_source.GetBuffer(),size_source_b);
		}
	}
	else
	{
		dbuf.Add(&size_source_b, 1);
		if(size_source_b>0)
		{
			CaplStringAdapter str_ad(m_source);
			CStringW str_w = (const wchar_t*) str_ad;
			// в винде wchar_t всегда длиной 2 байта
			dbuf.Add((void*)str_w.GetBufferSetLength(size_source_b), size_source_b*2);
		}
	}

#endif // #ifdef _UNICODE
}


