Files correlati : Ricompilazione Demo : [ ] Commento : Migliorie varie sul frontend git-svn-id: svn://10.65.10.50/trunk@7679 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			431 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			431 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include "StdAfx.h"
 | 
						||
 | 
						||
#include "hlapi_c.h"
 | 
						||
#define EYECAST (Word DATAFAR_ *)
 | 
						||
 | 
						||
extern "C"
 | 
						||
{
 | 
						||
#include "skeytsr.h"
 | 
						||
}
 | 
						||
static KEY_NET _Eutron;
 | 
						||
 | 
						||
#pragma pack(1)
 | 
						||
struct TEutronHeader
 | 
						||
{ 
 | 
						||
  char           _serno[8];
 | 
						||
  unsigned short _year_assist;
 | 
						||
  unsigned short _max_users;
 | 
						||
  unsigned long  _last_date;
 | 
						||
  unsigned long  _scad_date;
 | 
						||
  unsigned long  _checksum;  // Must be the last item!
 | 
						||
};
 | 
						||
#pragma pack()
 | 
						||
 | 
						||
#include "connect.h"
 | 
						||
#include "server.h"
 | 
						||
#include "tracing.h"
 | 
						||
 | 
						||
#ifdef _DEBUG
 | 
						||
#define new DEBUG_NEW
 | 
						||
#undef THIS_FILE
 | 
						||
static char THIS_FILE[] = __FILE__;
 | 
						||
#endif
 | 
						||
 | 
						||
 | 
						||
 | 
						||
// @doc INTERNAL
 | 
						||
 | 
						||
// @rdesc Ritorna il valore corrispondente alla chiave appartenente
 | 
						||
//        ad una sezione del file di configurazione
 | 
						||
 | 
						||
CString GetIniString(LPCSTR sec, // @parm Sezione
 | 
						||
		 			           LPCSTR key, // @parm Chiave
 | 
						||
					           LPCSTR def) // @parm Valore di default
 | 
						||
{
 | 
						||
	// Nome del file .ini
 | 
						||
	static CString m_strIniFile;
 | 
						||
	
 | 
						||
	// Lunghezza massima di un nome di directory
 | 
						||
	// o di un valore del file .ini
 | 
						||
	const DWORD dwSize = _MAX_DIR + 1;
 | 
						||
 | 
						||
	// Costruisce il nome del file .ini se necessario
 | 
						||
	if (m_strIniFile.IsEmpty())
 | 
						||
	{
 | 
						||
		GetCurrentDirectory(dwSize, m_strIniFile.GetBuffer(dwSize));
 | 
						||
		m_strIniFile.ReleaseBuffer();
 | 
						||
		m_strIniFile += "\\prawin.ini";
 | 
						||
	}
 | 
						||
 | 
						||
	// Legge il valore della chiave nella sezione specificata
 | 
						||
	CString tmp;
 | 
						||
	char* buf = tmp.GetBuffer(dwSize);
 | 
						||
	GetPrivateProfileString(sec, key, def, buf, dwSize, m_strIniFile);
 | 
						||
	tmp.ReleaseBuffer();
 | 
						||
	return tmp;
 | 
						||
}
 | 
						||
 | 
						||
// @doc EXTERNAL
 | 
						||
 | 
						||
// @func Permette di criptare una parola
 | 
						||
//
 | 
						||
// @rdesc Ritorna la stringa criptata
 | 
						||
const char* Encode(
 | 
						||
  const char* strin, // @parm Stringa da criptare
 | 
						||
  char* strout)      // @parm Stringa criptata
 | 
						||
 | 
						||
  // @xref <f decode>
 | 
						||
{
 | 
						||
  const char * const encryption_key = "QSECOFR-";
 | 
						||
  for (int i = 0; strin[i]; i++)
 | 
						||
    strout[i] = strin[i] + (i < 8 ? encryption_key[i] : strin[i-8]);
 | 
						||
  strout[i] = '\0';
 | 
						||
  return strout; 
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
BOOL TDongleServer::ReadEutronWords(unsigned short reg, 
 | 
						||
									unsigned short num,
 | 
						||
									unsigned short* data)
 | 
						||
{
 | 
						||
	ASSERT(num > 0 && num <= 16);
 | 
						||
	_Eutron.net_command = NET_KEY_ACCESS;
 | 
						||
	memcpy(&_Eutron.command, BLOCK_READING_MODE, 2);
 | 
						||
	unsigned short* pointer = (unsigned short*)(&_Eutron.data[0]);
 | 
						||
	unsigned short* number  = (unsigned short*)(&_Eutron.data[2]);
 | 
						||
	*pointer = reg;
 | 
						||
	*number = num;
 | 
						||
	smartlink(&_Eutron);
 | 
						||
	BOOL ok = _Eutron.status == ST_OK;
 | 
						||
	if (ok)
 | 
						||
		memcpy(data, &_Eutron.data[4], num*2);
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
BOOL TDongleServer::ReadHardlockWords(unsigned short reg, 
 | 
						||
								  	  unsigned short num,
 | 
						||
									  unsigned short* data)
 | 
						||
{
 | 
						||
	BOOL ok = HL_AVAIL() == STATUS_OK;
 | 
						||
	if (ok)
 | 
						||
	{
 | 
						||
		for (unsigned short n = 0; n < num; n++)
 | 
						||
			HL_READ(reg+n, EYECAST &data[n]);
 | 
						||
		HL_CODE(EYECAST data, 1);
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
BOOL TDongleServer::HardlockLogin()
 | 
						||
{
 | 
						||
	const char* const REFKEY = "CAMPOKEY";
 | 
						||
	const char* const VERKEY = "<EFBFBD>pو<EFBFBD>c<EFBFBD><";
 | 
						||
 | 
						||
	unsigned char ref[9]; strcpy((char*)ref, REFKEY);
 | 
						||
	unsigned char ver[9]; strcpy((char*)ver, VERKEY);
 | 
						||
 | 
						||
  const int status = HL_LOGIN(26952, LOCAL_DEVICE, ref, ver);
 | 
						||
 | 
						||
	Trace(-1, "Login Hardlock %s: %d",
 | 
						||
		     status == STATUS_OK ? "OK" : "FALLITO", status);
 | 
						||
 | 
						||
	_SerNo = 0xFFFF;
 | 
						||
  if (status == STATUS_OK)
 | 
						||
	{
 | 
						||
		Word Val[4] = { 0, 0, 0, 0 }; 
 | 
						||
		ReadHardlockWords(0, 4, Val);
 | 
						||
		if (Val[0] == 0xFAE8)
 | 
						||
			_SerNo = Val[1];
 | 
						||
		else
 | 
						||
			_SerNo = 0;
 | 
						||
 | 
						||
		if (_SerNo != 0)
 | 
						||
		{
 | 
						||
			ReadHardlockWords(60, 4, Val);
 | 
						||
			_AssistanceYear = Val[0];
 | 
						||
			_MaxUsers = Val[1];
 | 
						||
 | 
						||
			int index = 0;
 | 
						||
			for (unsigned short reg = 48; reg < 60; reg += 4)
 | 
						||
			{
 | 
						||
				ReadHardlockWords(reg, 4, Val);
 | 
						||
        Val[0] ^= _SerNo;
 | 
						||
        Val[1] ^= _SerNo;
 | 
						||
        Val[2] ^= _SerNo;
 | 
						||
				memcpy(&_int_tab[index], Val, 3);
 | 
						||
				index += 3;
 | 
						||
			}
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
  return status == STATUS_OK;
 | 
						||
}
 | 
						||
 | 
						||
BOOL TDongleServer::EutronLogin()
 | 
						||
{
 | 
						||
  BOOL ok = FALSE;
 | 
						||
  memset(&_Eutron, 0, sizeof(_Eutron));
 | 
						||
  _Eutron.net_command = NET_KEY_OPEN;
 | 
						||
 | 
						||
  const char* labels[2] = { "AGA.CAMPO", "25EBAI" };
 | 
						||
  for (int k = 0; k < 2; k++)
 | 
						||
  {
 | 
						||
    memset(_Eutron.label, 0, LABEL_LENGTH);
 | 
						||
    memcpy(_Eutron.label, labels[k], strlen(labels[k]));  
 | 
						||
    memset(_Eutron.password, 0, PASSWORD_LENGTH);
 | 
						||
	  if (k == 0)
 | 
						||
	  {
 | 
						||
		  char pwd[PASSWORD_LENGTH];
 | 
						||
		  Encode(labels[k], pwd);
 | 
						||
		  memcpy(_Eutron.password, pwd, strlen(pwd));  
 | 
						||
	  }
 | 
						||
    smartlink(&_Eutron);
 | 
						||
    ok = _Eutron.status == ST_OK;
 | 
						||
    if (ok)
 | 
						||
    {               
 | 
						||
	    if (k == 1)
 | 
						||
	      _SerNo = 0;
 | 
						||
      break;
 | 
						||
    }
 | 
						||
  }  
 | 
						||
  Trace(-1, "Login Eutron %s: %d", ok ? "OK" : "FALLITO", _Eutron.status);
 | 
						||
 | 
						||
  if (ok && _SerNo != 0)
 | 
						||
  { 
 | 
						||
	  TEutronHeader eh;
 | 
						||
	  if (ReadEutronWords(0, sizeof(TEutronHeader)/2, (unsigned short*)&eh))
 | 
						||
	  {
 | 
						||
		  char serno[16]; 
 | 
						||
		  strncpy(serno, eh._serno, 8);
 | 
						||
		  serno[8] = '\0';
 | 
						||
		  _SerNo = (unsigned long)atol(serno);
 | 
						||
		  if (eh._max_users > 0)
 | 
						||
		  {
 | 
						||
		    _MaxUsers = eh._max_users;
 | 
						||
		    _AssistanceYear = eh._year_assist;  
 | 
						||
		    ReadEutronWords(16, 16, _int_tab);
 | 
						||
		  }  
 | 
						||
	  }  
 | 
						||
  }
 | 
						||
 | 
						||
  return _Eutron.status == ST_OK;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
BOOL TDongleServer::Login()
 | 
						||
{
 | 
						||
	BOOL ok = HardlockLogin() || EutronLogin();
 | 
						||
	if (ok)
 | 
						||
	{
 | 
						||
		if (_SerNo == 0 || _MaxUsers == 0)
 | 
						||
		{
 | 
						||
			const CTime tNow = CTime::GetCurrentTime();
 | 
						||
			_AssistanceYear = tNow.GetYear();
 | 
						||
			if (_SerNo == 0)
 | 
						||
			{
 | 
						||
				_MaxUsers = 4;
 | 
						||
				memset(_int_tab, 0xFF, sizeof(_int_tab));
 | 
						||
			}
 | 
						||
			else
 | 
						||
			{
 | 
						||
				_MaxUsers = 1;
 | 
						||
				memset(_int_tab, 0x00, sizeof(_int_tab));
 | 
						||
			}
 | 
						||
		}
 | 
						||
 | 
						||
		Trace(-1, "Numero di serie %u", _SerNo);
 | 
						||
		Trace(-1, "Anno assistenza %u", _AssistanceYear);
 | 
						||
		Trace(-1, "Numero utenti   %u", _MaxUsers);
 | 
						||
  
 | 
						||
    CString modules = "Moduli attivi: ";
 | 
						||
    if (_SerNo > 0 && _SerNo != 0xFFFF)
 | 
						||
    {
 | 
						||
      for (int n = 0; n < MAX_MODULES; n++)
 | 
						||
      {
 | 
						||
 				const unsigned short index = n / 16;
 | 
						||
				if (index < 4)
 | 
						||
        {
 | 
						||
					if ((_int_tab[index] >> (n % 16)) & 0x1)
 | 
						||
          {
 | 
						||
            char buff[24];
 | 
						||
            sprintf(buff, "%d ", n+1);
 | 
						||
            modules += buff;
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      if (_SerNo == 0)
 | 
						||
        modules += "Tutti";
 | 
						||
      else
 | 
						||
        modules += "Nessuno";
 | 
						||
    }
 | 
						||
    Trace(-1, modules);
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
void TDongleServer::Logout()
 | 
						||
{
 | 
						||
	if (_Eutron.label[0])
 | 
						||
	{
 | 
						||
		_Eutron.net_command = NET_KEY_CLOSE;
 | 
						||
		smartlink(&_Eutron);
 | 
						||
	}
 | 
						||
	else
 | 
						||
	{
 | 
						||
		HL_LOGOUT();
 | 
						||
	}
 | 
						||
	_SerNo = 0xFFFF;
 | 
						||
	_MaxUsers = 0;
 | 
						||
	_AssistanceYear = 0;
 | 
						||
	memset(_int_tab, 0, sizeof(_int_tab));
 | 
						||
}
 | 
						||
 | 
						||
BOOL TDongleServer::OnConnect(const CString& topic)
 | 
						||
{
 | 
						||
	BOOL ok = Users() < MaxUsers();
 | 
						||
	if (!ok)
 | 
						||
		Trace(0, "Refusing Topic %s", (const char*)topic);
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
TConnection* TDongleServer::OnCreateConnection(DWORD id)
 | 
						||
{
 | 
						||
	TConnection* c = NULL;
 | 
						||
 | 
						||
  CString strPeer;
 | 
						||
  GetPeerName(id, strPeer);
 | 
						||
  
 | 
						||
  const int n = GetPeerConnections(strPeer);
 | 
						||
	if (n > 0 || Peers() < MaxUsers())
 | 
						||
	{
 | 
						||
		Trace(0, "Connecting %lu from %s", id, strPeer);
 | 
						||
		c = new TPrassiConnection(this, id, strPeer);
 | 
						||
	}
 | 
						||
	else
 | 
						||
		Trace(0, "Refusing Connection %lu from %s", id, strPeer);
 | 
						||
	return c;
 | 
						||
}
 | 
						||
 | 
						||
BOOL TDongleServer::OnRemoveConnection(DWORD id)
 | 
						||
{
 | 
						||
  CString strPeer;
 | 
						||
  GetPeerName(id, strPeer);
 | 
						||
	Trace(0, "Disconnecting %lu from %s", id, strPeer); 
 | 
						||
	BOOL ok = TSocketServer::OnRemoveConnection(id);
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
static int CountUsers(TConnection& conn, void* pJolly)
 | 
						||
{
 | 
						||
	CMapStringToOb& users = *(CMapStringToOb*)pJolly;
 | 
						||
	const TPrassiConnection& c = (TPrassiConnection&)conn;
 | 
						||
  const CString& name = c.User();
 | 
						||
  BOOL ok = name != "******";
 | 
						||
  if (ok)
 | 
						||
    users.SetAt(name, NULL);
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
unsigned short TDongleServer::Users() const
 | 
						||
{
 | 
						||
  CMapStringToOb u;
 | 
						||
  ((TDongleServer*)this)->ForEachConnection(CountUsers, &u);
 | 
						||
  unsigned short nTotal = (unsigned short)u.GetCount();
 | 
						||
  return nTotal;
 | 
						||
}
 | 
						||
 | 
						||
static int CountPeerConnections(TConnection& conn, void* pJolly)
 | 
						||
{
 | 
						||
	const CString& name = *(const CString*)pJolly;
 | 
						||
	const TPrassiConnection& c = (TPrassiConnection&)conn;
 | 
						||
  return c.PeerName() == name;
 | 
						||
}
 | 
						||
 | 
						||
int TDongleServer::GetPeerConnections(const CString& strPeer) const
 | 
						||
{
 | 
						||
  int nTotal = ((TDongleServer*)this)->ForEachConnection(CountPeerConnections, (void*)&strPeer);
 | 
						||
  return nTotal;
 | 
						||
}
 | 
						||
 | 
						||
static int CountPeers(TConnection& conn, void* pJolly)
 | 
						||
{
 | 
						||
	CMapStringToOb& users = *(CMapStringToOb*)pJolly;
 | 
						||
	const TPrassiConnection& c = (TPrassiConnection&)conn;
 | 
						||
  const CString& name = c.PeerName();
 | 
						||
  users.SetAt(name, NULL);
 | 
						||
  return 1;
 | 
						||
}
 | 
						||
 | 
						||
unsigned short TDongleServer::Peers() const
 | 
						||
{
 | 
						||
  CMapStringToOb u;
 | 
						||
  ((TDongleServer*)this)->ForEachConnection(CountPeers, &u);
 | 
						||
  unsigned short nTotal = (unsigned short)u.GetCount();
 | 
						||
  return nTotal;
 | 
						||
}
 | 
						||
 | 
						||
BOOL TDongleServer::CanClose() const
 | 
						||
{
 | 
						||
	BOOL bCanExit = !HasConnections();
 | 
						||
	if (!bCanExit)
 | 
						||
	{
 | 
						||
		int nCode = AfxMessageBox("Ci sono ancora degli utenti collegati:\n"
 | 
						||
			                        "Si desidera uscire ugualmente?", 
 | 
						||
								  MB_YESNO | MB_ICONQUESTION);
 | 
						||
  	bCanExit = nCode == IDYES;
 | 
						||
	}
 | 
						||
	return bCanExit;
 | 
						||
}
 | 
						||
 | 
						||
TDongleServer::TDongleServer() 
 | 
						||
             : TSocketServer("DONGLE")
 | 
						||
{
 | 
						||
	 _SerNo = 0xFFFF;
 | 
						||
	 _MaxUsers = 0;
 | 
						||
	 _AssistanceYear = 0;
 | 
						||
	 memset(_int_tab, 0, sizeof(_int_tab));
 | 
						||
	 Login();
 | 
						||
}
 | 
						||
 | 
						||
TDongleServer::~TDongleServer()
 | 
						||
{
 | 
						||
	if (_SerNo != 0xFFFF)
 | 
						||
		Logout();
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Start/Stop server
 | 
						||
 | 
						||
static TDongleServer* pDDE = NULL;
 | 
						||
 | 
						||
BOOL StopServer()
 | 
						||
{
 | 
						||
	BOOL ok = pDDE != NULL;
 | 
						||
	if (ok)
 | 
						||
	{
 | 
						||
		delete pDDE;
 | 
						||
		pDDE = NULL;
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
TDongleServer& GetServer()
 | 
						||
{
 | 
						||
	ASSERT(pDDE);
 | 
						||
	return *pDDE;
 | 
						||
}
 | 
						||
 | 
						||
BOOL StartServer()
 | 
						||
{
 | 
						||
	BOOL ok = pDDE == NULL;
 | 
						||
	if (ok)
 | 
						||
		pDDE = new TDongleServer;
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 |