Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 855 git-svn-id: svn://10.65.10.50/trunk@15071 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			940 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			940 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include "baseserv.h"
 | ||
| #include "dongle.h"
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TBit_array
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| TBit_array::TBit_array(size_t size) 
 | ||
|           : _bit(NULL), _size(0)
 | ||
| {
 | ||
|   if (size)
 | ||
|     resize(index(size));
 | ||
| }
 | ||
| 
 | ||
| void TBit_array::copy(const TBit_array& ba)
 | ||
| {
 | ||
|   if (_bit)
 | ||
|   {
 | ||
|     delete _bit;
 | ||
|     _bit = NULL;
 | ||
|     _size = 0;
 | ||
|   }
 | ||
|   resize(ba._size-1);
 | ||
|   memcpy(_bit, ba._bit, _size);
 | ||
| }
 | ||
| 
 | ||
| TBit_array::TBit_array(const TBit_array& ba) : _bit(NULL), _size(0)
 | ||
| { copy(ba); }
 | ||
| 
 | ||
| TBit_array& TBit_array::operator=(const TBit_array& ba)
 | ||
| {
 | ||
|   copy(ba);
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| TBit_array::~TBit_array()
 | ||
| {
 | ||
|   if (_bit)
 | ||
|     delete _bit;
 | ||
| }
 | ||
| 
 | ||
| void TBit_array::set()
 | ||
| {
 | ||
|   if (_bit) 
 | ||
|     memset(_bit, 0xFF, _size);
 | ||
| }
 | ||
| 
 | ||
| void TBit_array::reset()
 | ||
| {
 | ||
|   if (_bit) 
 | ||
|     memset(_bit, 0x0, _size);
 | ||
| }
 | ||
| 
 | ||
| void TBit_array::resize(size_t size)
 | ||
| {
 | ||
|   const size_t oldsize = _size;
 | ||
|   unsigned char* oldbit = _bit;
 | ||
| 
 | ||
|   _size = size+1;
 | ||
|   _bit = new unsigned char[_size];
 | ||
|   reset();
 | ||
| 
 | ||
|   if (oldsize)
 | ||
|   {
 | ||
|     memcpy(_bit, oldbit, oldsize);
 | ||
|     delete oldbit;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| bool TBit_array::operator[] (size_t n) const
 | ||
| {
 | ||
|   const size_t i = index(n);
 | ||
|   if (i >= _size) return false;
 | ||
|   return (_bit[i] & mask(n)) != 0;
 | ||
| }
 | ||
| 
 | ||
| TBit_array& TBit_array::operator|= (const TBit_array& ba)
 | ||
| {
 | ||
|   if (_size < ba._size)
 | ||
|     resize(ba._size);
 | ||
| 
 | ||
|   for (size_t i = 0; i < _size; i++)
 | ||
|     _bit[i] |= ba._bit[i];
 | ||
| 
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| void TBit_array::set(size_t n)
 | ||
| {
 | ||
|   const size_t i = index(n);
 | ||
|   if (i >= _size)
 | ||
|     resize(i);
 | ||
|   _bit[i] |= mask(n);
 | ||
| }
 | ||
| 
 | ||
| void TBit_array::reset(size_t n)
 | ||
| {
 | ||
|   const size_t i = index(n);
 | ||
|   if (i < _size)
 | ||
|     _bit[i] &= ~mask(n);
 | ||
| }
 | ||
| 
 | ||
| void TBit_array::neg(size_t n)
 | ||
| {	
 | ||
|   const size_t i = index(n);
 | ||
|   if (i >= _size) resize(i);
 | ||
|   _bit[i] ^= mask(n);
 | ||
| }
 | ||
| 
 | ||
| size_t TBit_array::ones() const
 | ||
| {
 | ||
|   size_t one = 0;
 | ||
|   for (size_t i = 0; i < _size; i++)
 | ||
|   {
 | ||
|     const unsigned long b = _bit[i];
 | ||
|     if (b)
 | ||
|     {
 | ||
|       for (unsigned long m = 1; m; m <<= 1)
 | ||
|         if (b & m) one++;
 | ||
|     }
 | ||
|   }
 | ||
|   return one;
 | ||
| }
 | ||
| 
 | ||
| long TBit_array::last_one() const
 | ||
| {
 | ||
|   const long bits = sizeof(unsigned char); 
 | ||
|   for (size_t i = _size; i--;)
 | ||
|   {
 | ||
|     const unsigned long b = _bit[i];
 | ||
|     if (b)
 | ||
|     {
 | ||
|       for (int j = bits; j--;)
 | ||
|         if ((1<<j) & b) return (bits * i) + j;
 | ||
|     }
 | ||
|   }
 | ||
|   return -1;
 | ||
| }
 | ||
| 
 | ||
| long TBit_array::first_one() const
 | ||
| {
 | ||
|   const long bits = sizeof(unsigned char); 
 | ||
|   for (size_t i = 0; i < _size; i++)
 | ||
|   {
 | ||
|     const unsigned long b = _bit[i];
 | ||
|     if (b)
 | ||
|     {
 | ||
|       for (int j = 0; j < bits; j++)
 | ||
|         if ((1<<j) & b) return (bits*i)+j;
 | ||
|     }
 | ||
|   }
 | ||
|   return -1;
 | ||
| }
 | ||
| 
 | ||
| bool TBit_array::ok() const
 | ||
| {
 | ||
|   return _bit != NULL && _size > 0;
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Date utilities
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| wxDateTime julian2date(long julian)
 | ||
| {
 | ||
|   long x, z, m, d, y;
 | ||
|   const long daysPer400Years = 146097L;
 | ||
|   const long fudgedDaysPer4000Years = 1460970L + 31;
 | ||
| 
 | ||
|   x = julian + 68569L;
 | ||
|   z = 4 * x / daysPer400Years;
 | ||
|   x = x - (daysPer400Years * z + 3) / 4;
 | ||
|   y = 4000 * (x + 1) / fudgedDaysPer4000Years;
 | ||
|   x = x - 1461 * y / 4 + 31;
 | ||
|   m = 80 * x / 2447;
 | ||
|   d = x - 2447 * m / 80;
 | ||
|   x = m / 11;
 | ||
|   m = m + 2 - 12 * x;
 | ||
|   y = 100 * (z - 49) + y + x;
 | ||
| 
 | ||
|   wxDateTime date(d, wxDateTime::Month(m-1), y);
 | ||
|   return date;
 | ||
| }
 | ||
| 
 | ||
| long date2julian(const wxDateTime& date)
 | ||
| {                      
 | ||
|   const int d = date.GetDay(), m = date.GetMonth()+1, y = date.GetYear();
 | ||
|   
 | ||
|   return (long)(d - 32076)
 | ||
|     + 1461L * (y + 4800L + (m - 14) / 12) / 4
 | ||
|       + 367 * ( m - 2 - (m - 14) / 12 * 12) / 12
 | ||
|         - 3 * ((y + 4900L + (m - 14) / 12) / 100) / 4
 | ||
|           + 1;
 | ||
| }
 | ||
| 
 | ||
| long date2long(const wxDateTime& date)
 | ||
| {
 | ||
| 	long n = date.GetYear()*10000 + (date.GetMonth()+1)*100 + date.GetDay();
 | ||
| 	return n;
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Utilities
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| const char* const encryption_key = "QSECOFR-";
 | ||
| 
 | ||
| wxString encode(const wxChar* data)
 | ||
| {
 | ||
| 	wxString tmp;
 | ||
| 	wxChar* buf = tmp.GetWriteBuf(80);
 | ||
| 	int i;
 | ||
| 	
 | ||
|   for (i = 0; data[i]; i++)
 | ||
|     buf[i] = data[i] + (i < 8 ? encryption_key[i] : data[i - 8]);
 | ||
|   buf[i] = '\0';
 | ||
| 	tmp.UngetWriteBuf();
 | ||
|   return tmp; 
 | ||
| }
 | ||
| 
 | ||
| wxString decode(const char* data)
 | ||
| {
 | ||
| 	wxString tmp;
 | ||
| 	wxChar* buf = tmp.GetWriteBuf(80);
 | ||
| 	int i;
 | ||
| 	
 | ||
|   for (i = 0; data[i]; i++)
 | ||
|     buf[i] = data[i] - (i < 8 ? encryption_key[i] : buf[i - 8]);
 | ||
|   buf[i] = '\0';
 | ||
| 	tmp.UngetWriteBuf();
 | ||
|   return tmp; 
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Hardlock stuff
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| #include "hlapi_c.h"
 | ||
| 
 | ||
| #define USERADR    26952
 | ||
| #define AGAADR     26953
 | ||
| #define REFKEY     (unsigned char*)"CAMPOKEY"
 | ||
| #define VERKEY     (unsigned char*)"<22>pو<70>c<EFBFBD><"
 | ||
| 
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Smartkey stuff
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| #ifdef WIN32
 | ||
| #include "skeylink.h"
 | ||
| #else
 | ||
| #include "skeylinux.h"
 | ||
| #define smartlink clink
 | ||
| #define KEY_NET SKEY_DATA
 | ||
| 
 | ||
| typedef unsigned char byte;
 | ||
| 
 | ||
| #endif
 | ||
| 
 | ||
| static KEY_NET * _eutron_key = NULL;
 | ||
| 
 | ||
| #pragma pack(push, 1)
 | ||
| 
 | ||
| struct TEutronHeader
 | ||
| { 
 | ||
|   char           _serno[8];             //  8
 | ||
|   unsigned short _year_assist;          // 10
 | ||
|   unsigned short _max_users;            // 12
 | ||
|   unsigned long  _last_date;            // 16
 | ||
|   unsigned long  _scad_date;            // 20
 | ||
|   unsigned long  _checksum;             // 24 
 | ||
|   unsigned short _version;              // 26
 | ||
|   unsigned short _patch;                // 28
 | ||
|   unsigned short _offset_to_bits;       // 30
 | ||
|   unsigned short _size_of_bits;         // 32
 | ||
| };
 | ||
| 
 | ||
| struct TEutronFooter
 | ||
| {                
 | ||
|   unsigned long _size;                  // Should be sizeof(TEutronFooter)
 | ||
|   unsigned long _checksum;              // Much smarter position than header
 | ||
|   unsigned long _filler1;
 | ||
|   unsigned long _filler2;
 | ||
|   unsigned long _filler3;
 | ||
|   unsigned long _filler4;
 | ||
|   unsigned long _filler5;
 | ||
|   unsigned long _last_assist;                   // Last date of assistance query
 | ||
|   unsigned long _assistance[MAX_DONGLE_ASSIST]; // Pre-payed assistance
 | ||
|   
 | ||
|   unsigned long checksum(bool set);
 | ||
|   bool valid();
 | ||
|   TEutronFooter();
 | ||
| };
 | ||
| 
 | ||
| #pragma pack(pop)
 | ||
| 
 | ||
| TEutronFooter::TEutronFooter()
 | ||
| {
 | ||
|   const int s = sizeof(TEutronFooter);
 | ||
|   memset(&_size, 0, s);
 | ||
|   _size = s;
 | ||
| }
 | ||
| 
 | ||
| unsigned long TEutronFooter::checksum(bool set)
 | ||
| {
 | ||
|   if (set) _size = sizeof(TEutronFooter);
 | ||
| 
 | ||
|   const unsigned short offset = sizeof(_size) + sizeof(_checksum);
 | ||
|   unsigned char* ptr = (unsigned char*)(&_size) + offset;
 | ||
|   const unsigned short len = (unsigned short)(_size - offset);
 | ||
|   
 | ||
|   unsigned long cs = 0;
 | ||
|   for (unsigned short i = 0; i < len; i++, ptr++)
 | ||
|     cs += *ptr | ~(short(*ptr << 8));
 | ||
|   if (set) _checksum = cs;
 | ||
|   return cs;  
 | ||
| }
 | ||
| 
 | ||
| bool TEutronFooter::valid() 
 | ||
| {
 | ||
|   if (_size == 0 || _checksum == 0)
 | ||
|     return false;
 | ||
|   return _checksum == checksum(false);
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Bit helper functions
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| inline bool test_bit(unsigned short w, int b)
 | ||
| {                            
 | ||
|   bool on = (w & (1 << b)) != 0;
 | ||
|   return on;
 | ||
| }
 | ||
| 
 | ||
| inline void set_bit(unsigned short& w, int b, bool on = true)
 | ||
| {                        
 | ||
|   if (on)  
 | ||
|     w |= 1 << b;
 | ||
|   else  
 | ||
|     w &= ~(1 << b);
 | ||
| }
 | ||
| 
 | ||
| inline void reset_bit(unsigned short& w, unsigned char b)
 | ||
| {                        
 | ||
|   w &= ~(1 << b);
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TDongle
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| TDongle::TDongle() 
 | ||
|        : _hardware(_dongle_unknown), _type(_no_dongle), _serno(0xFFFF), 
 | ||
|          _max_users(1), _year_assist(2007), _dirty(false)
 | ||
| {
 | ||
|   memset(_eprom, 0, sizeof(_eprom));
 | ||
| }  
 | ||
| 
 | ||
| TDongle::~TDongle() 
 | ||
| { 
 | ||
|   if (_serno != 0xFFFF)
 | ||
|     Logout(); 
 | ||
| }
 | ||
| 
 | ||
| // Data punta ad un array di 4 words 
 | ||
| // Deve essere cosi' per problemi del C,
 | ||
| // non trasformare in array: pena di morte! 
 | ||
| void TDongle::garble(unsigned short* data) const
 | ||
| {   
 | ||
|   switch (_hardware)
 | ||
|   {
 | ||
|   case _dongle_hardlock:
 | ||
|     HL_CODE(data, 1);
 | ||
|     break;
 | ||
|   case _dongle_eutron:
 | ||
|     if (_eutron_key)
 | ||
|     {   
 | ||
| #ifdef WIN32
 | ||
|       _eutron_key->net_command = NET_KEY_ACCESS;
 | ||
| #endif
 | ||
|       _eutron_key->command = SCRAMBLING_MODE;
 | ||
|       memcpy(_eutron_key->data, data, 8);
 | ||
|       smartlink(_eutron_key);
 | ||
|       if (_eutron_key->status == ST_OK)
 | ||
|         memcpy(data, _eutron_key->data, 8);
 | ||
|     }  
 | ||
|     break;
 | ||
|   default:
 | ||
|     break;  
 | ||
|   }  
 | ||
| }
 | ||
| 
 | ||
| bool TDongle::already_programmed() const
 | ||
| {     
 | ||
|   if (_hardware == _dongle_hardlock)
 | ||
|   {
 | ||
|     unsigned short data[4];
 | ||
|     memcpy(data, &_eprom[60], sizeof(data));
 | ||
|     garble(data);
 | ||
|     
 | ||
|     if (data[0] < 2000 || data[0] > 3000)
 | ||
|       return false;
 | ||
|       
 | ||
|     if (data[1] == 0 || data[1] >= 10000)  
 | ||
|       return false;
 | ||
|     const long giulio = *((const long*)&data[2]);
 | ||
|     const wxDateTime date = julian2date(giulio);
 | ||
|     if (date.GetYear() < 2000 || date > wxDateTime::Now())
 | ||
|       return false;
 | ||
|   } else
 | ||
|   if (_hardware == _dongle_eutron)
 | ||
|   {
 | ||
|     const TEutronHeader* eh = (const TEutronHeader*)_eprom;
 | ||
|     if (eh->_serno[0] == 0 || eh->_checksum == 0)
 | ||
|       return false;   // Really virgin.
 | ||
|       
 | ||
|     unsigned long cs = 0;
 | ||
|     for (byte * ptr = (byte*)_eprom; ptr < (byte*)&eh->_checksum; ptr++)
 | ||
|       cs += *ptr | ~(short(*ptr << 8));
 | ||
|     if (eh->_checksum != cs)  
 | ||
|       return false;   // Malicious programming!
 | ||
|   }   
 | ||
| 
 | ||
|   return true;  
 | ||
| }
 | ||
|            
 | ||
| bool TDongle::hardlock_login(bool test_all_keys)
 | ||
| {
 | ||
|   bool ok = true;
 | ||
|   _type = _user_dongle;
 | ||
|   if (test_all_keys)
 | ||
|   {
 | ||
|     HL_LOGOUT();
 | ||
|     if (HL_LOGIN(AGAADR, LOCAL_DEVICE, REFKEY, VERKEY) == STATUS_OK) 
 | ||
|       _type = _aga_dongle;
 | ||
|   }  
 | ||
|   HL_LOGOUT();
 | ||
|   ok = HL_LOGIN(USERADR, LOCAL_DEVICE, REFKEY, VERKEY) == STATUS_OK;
 | ||
|   
 | ||
|   if (ok)
 | ||
|   {     
 | ||
|     _hardware = _dongle_hardlock;
 | ||
|     
 | ||
|     HL_READBL((unsigned char*)_eprom);
 | ||
| 
 | ||
|     unsigned short data[4];
 | ||
|     memcpy(data, _eprom, sizeof(data));
 | ||
|     garble(data);
 | ||
|     
 | ||
|     if (data[0] == 0xFAE8)
 | ||
|       _serno = data[1];
 | ||
|     else
 | ||
|     {                  
 | ||
|       if (data[0] == 0x3283 || data[0] == 0xA3AA) // chiave programmatori !!
 | ||
|       {         
 | ||
|         if (_type == _user_dongle)
 | ||
|           _type = _developer_dongle;
 | ||
|         _serno = 0;  
 | ||
|       }  
 | ||
|     }  
 | ||
|   }  
 | ||
| 
 | ||
|   if (ok) 
 | ||
|   {
 | ||
|     _max_users = 1;
 | ||
|     _last_update = wxDateTime::Now();
 | ||
|     _year_assist = _last_update.GetYear();
 | ||
| 
 | ||
|     if (_type == _user_dongle)
 | ||
|     {  
 | ||
|       const bool already = already_programmed();
 | ||
|       
 | ||
|       _module.reset(); // Disattiva  tutti i moduli
 | ||
|       const int last_word = already ? 12 : 4;                    
 | ||
|       unsigned short data[4];
 | ||
| 
 | ||
|       // Legge flag di attivazione dei moduli
 | ||
|       for (int i = 0; i < last_word; i += 4)
 | ||
|       {
 | ||
|         memcpy(data, &_eprom[48+i], sizeof(data));
 | ||
|         garble(data);
 | ||
|         if (data[3] == _serno) // Validate block
 | ||
|         {
 | ||
|           for (int j = 0; j < 3; j++)
 | ||
|           {
 | ||
|             unsigned short parola = data[j] ^ _serno;
 | ||
|             if (parola)
 | ||
|             {
 | ||
|               for (int b = 15; b >= 0; b--)
 | ||
|               {
 | ||
|                 if (test_bit(parola, b))             
 | ||
|                 {
 | ||
|                   const unsigned short bit = i * 12 + j * 16 + b;
 | ||
|                   _module.set(bit+1);
 | ||
|                 }  
 | ||
|               }  
 | ||
|             }  
 | ||
|           }
 | ||
|         }
 | ||
|         else
 | ||
|           break;
 | ||
|       }
 | ||
|       _module.set(0, true); // Forza l'attivazione della base
 | ||
| 
 | ||
|       // Legge anno di assitenza e numero massimo di utenti
 | ||
|       memcpy(data, &_eprom[60], sizeof(data));
 | ||
|       garble(data);      
 | ||
|       
 | ||
|       if (already)
 | ||
|       {
 | ||
|         _year_assist = data[0];
 | ||
|         _max_users = data[1];
 | ||
|         const long& giulio = (const long&)data[2];
 | ||
|         _last_update = julian2date(giulio);
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|         _year_assist = 0;
 | ||
|         _dirty = true;
 | ||
|       }
 | ||
|     }  
 | ||
|     else
 | ||
|     {                   
 | ||
|       _module.set(255); // Last module on key
 | ||
|       _module.set();     // Activate all modules
 | ||
| 
 | ||
|       _max_users = 4;
 | ||
|       _last_update = wxDateTime::Now();
 | ||
|       _year_assist = 3000;
 | ||
|     }  
 | ||
|   }  
 | ||
|   else
 | ||
|     _type = _no_dongle;
 | ||
|   
 | ||
|   return ok;  
 | ||
| }
 | ||
| 
 | ||
| bool TDongle::eutron_login(bool test_all_keys)
 | ||
| {
 | ||
|   bool ok = false;
 | ||
| 
 | ||
|   if (_eutron_key == NULL)             
 | ||
|     _eutron_key = new KEY_NET;
 | ||
|   memset(_eutron_key, 0, sizeof(KEY_NET));
 | ||
| 
 | ||
| #ifdef WIN32
 | ||
|   _eutron_key->net_command = NET_KEY_OPEN;
 | ||
| #else
 | ||
|   _eutron_key->command = LOCATING_MODE;
 | ||
| #endif
 | ||
| 
 | ||
|   const char* labels[3] = { "AGA.INFORMATICA", "AGA.CAMPO", "25EBAI" };
 | ||
|   TDongleType types[3]  = { _aga_dongle, _user_dongle, _developer_dongle };
 | ||
|   for (int k = test_all_keys ? 0 : 1; k < 3; k++)
 | ||
|   {
 | ||
|     memset(_eutron_key->label, 0, LABEL_LENGTH);
 | ||
|     memcpy(_eutron_key->label, labels[k], strlen(labels[k]));  
 | ||
|     memset(_eutron_key->password, 0, PASSWORD_LENGTH);
 | ||
|     memcpy(_eutron_key->password, ::encode(labels[k]), strlen(labels[k]));  
 | ||
|     _eutron_key->status = ST_NONE_KEY;  // Don't leave ST_OK = 0 here!
 | ||
|     smartlink(_eutron_key);
 | ||
|     ok = _eutron_key->status == ST_OK;
 | ||
|     if (ok)
 | ||
|     {                  
 | ||
|       _hardware = _dongle_eutron;
 | ||
|       _type = types[k];
 | ||
|       break;
 | ||
|     }
 | ||
|   }  
 | ||
|   if (ok)
 | ||
|   { 
 | ||
|     _serno = 0;
 | ||
|     _max_users = 1;
 | ||
|     _last_update = wxDateTime::Now();
 | ||
|     _year_assist = _last_update.GetYear();
 | ||
| 
 | ||
|     if (_type == _user_dongle)
 | ||
|     {   
 | ||
|       _module.reset();   // Disattiva tutti i moduli
 | ||
|       if (read_words(0, sizeof(TEutronHeader) / 2, _eprom))
 | ||
|       {
 | ||
|         const TEutronHeader* eh = (const TEutronHeader*)_eprom;
 | ||
|         wxString serno = eh->_serno; serno.Truncate(8);
 | ||
|         _serno = unsigned(atol(serno));
 | ||
|         if (already_programmed())
 | ||
|         {
 | ||
|           _max_users   = eh->_max_users;
 | ||
|           _last_update = eh->_last_date;
 | ||
|           _year_assist = eh->_year_assist;
 | ||
|           
 | ||
|           // Calcola il numero della word dove cominciano i bit di attivazione
 | ||
|           unsigned short otb = eh->_offset_to_bits;
 | ||
|           if (otb == 0) otb = 16;   // Compatibile Hardlock
 | ||
| 
 | ||
|           unsigned short sob = eh->_size_of_bits;
 | ||
|           if (sob == 0) sob = 16;   // Compatibile Hardlock
 | ||
|           
 | ||
|           unsigned short data[64];
 | ||
|           if (read_words(otb, sob, data))
 | ||
|           {  
 | ||
|             int module = 1;
 | ||
|             for (unsigned short w = 0; w < sob; w++)
 | ||
|             {
 | ||
|               for (int b = 0; b < 16; b++)
 | ||
|               {
 | ||
|                 if (test_bit(data[w], b))
 | ||
|                   _module.set(module);
 | ||
|                 module++;  
 | ||
|               }    
 | ||
|             }
 | ||
|           }
 | ||
|         }  
 | ||
|         else
 | ||
|           _dirty = true;
 | ||
|       }  
 | ||
|       _module.set(0, true); // Forza l'attivazione della base
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
| 			_max_users = 4;
 | ||
|       _module.set(255); // Last module on key
 | ||
|       _module.set();    // Activate all modules
 | ||
|       _year_assist = 3000;
 | ||
|     }  
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     delete _eutron_key;
 | ||
|     _eutron_key = NULL;
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| bool TDongle::Login(bool test_all_keys)
 | ||
| {                                                                   
 | ||
|   bool ok = true;
 | ||
| 
 | ||
|   if (_type != _no_dongle) // Already logged in
 | ||
|     Logout();
 | ||
| 
 | ||
|   TDongleHardware hw = _hardware;               
 | ||
|   if (hw == _dongle_unknown)
 | ||
|     hw = (TDongleHardware)GetServerApp().GetConfigInt("Donglehw");
 | ||
|   switch(hw)
 | ||
|   {
 | ||
|   case _dongle_hardlock: 
 | ||
|     ok = hardlock_login(test_all_keys); 
 | ||
|     break;
 | ||
|   case _dongle_eutron: 
 | ||
|     ok = eutron_login(test_all_keys); 
 | ||
|     break;
 | ||
|   default:
 | ||
|     ok = false;
 | ||
|     break;
 | ||
|   }
 | ||
|   if (!ok) 
 | ||
|   {
 | ||
|     if (!ok && hw != _dongle_eutron)
 | ||
|       ok = eutron_login(test_all_keys);
 | ||
|     if (!ok && hw != _dongle_hardlock)
 | ||
|       ok = hardlock_login(test_all_keys);
 | ||
|     if (ok)
 | ||
|       GetServerApp().SetConfigInt("Donglehw",(int)_hardware);
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| bool TDongle::Logout()
 | ||
| { 
 | ||
|   if (_type != _no_dongle)
 | ||
|   {
 | ||
|     switch (_hardware)
 | ||
|     {
 | ||
|     case _dongle_hardlock:  
 | ||
|       HL_LOGOUT(); 
 | ||
|       break;
 | ||
|     case _dongle_eutron:   
 | ||
|       if (_eutron_key)
 | ||
|       {
 | ||
| #ifdef WIN32
 | ||
|         _eutron_key->net_command = NET_KEY_CLOSE;
 | ||
| #endif
 | ||
|         _eutron_key->command = 0;
 | ||
|         smartlink(_eutron_key);
 | ||
|       }  
 | ||
|       break;
 | ||
|     default:
 | ||
|       break;  
 | ||
|     }
 | ||
|   }  
 | ||
| 
 | ||
|   _type = _no_dongle;
 | ||
|   _serno = 0xFFFF;
 | ||
| 
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| bool TDongle::Connected()
 | ||
| {
 | ||
| 	bool ok = false;
 | ||
|   if (type() != _no_dongle)
 | ||
| 	{
 | ||
| 		unsigned short a[4] = { 0, 0, 0, 0 };
 | ||
| 		garble(a);
 | ||
| 		for (int i = 0; i < 4; i++)
 | ||
| 			ok |= (a[0] != 0);
 | ||
| 	}
 | ||
| 	return ok;
 | ||
| }
 | ||
| 
 | ||
| // Data punta ad un array di 4 words 
 | ||
| // Deve essere cosi' per problemi del C,
 | ||
| // non trasformare in array: pena di morte! 
 | ||
| bool TDongle::read_words(unsigned short reg, unsigned short len, unsigned short* ud) const
 | ||
| {         
 | ||
|   bool ok = false;
 | ||
|   switch (_hardware)
 | ||
|   { 
 | ||
|   case _dongle_hardlock:
 | ||
|     {
 | ||
|       for (unsigned short i = 0; i < len; i++)
 | ||
|         HL_READ(reg+i, &ud[i]);
 | ||
|       ok = true;
 | ||
|     }  
 | ||
|     break;
 | ||
|   case _dongle_eutron:
 | ||
|     if (_eutron_key)
 | ||
|     {
 | ||
| #ifdef WIN32
 | ||
|       _eutron_key->net_command = NET_KEY_ACCESS;
 | ||
| #endif
 | ||
|       _eutron_key->command = BLOCK_READING_MODE;
 | ||
|       unsigned short* pointer = (unsigned short*)(&_eutron_key->data[0]);
 | ||
|       unsigned short* number  = (unsigned short*)(&_eutron_key->data[2]);
 | ||
|       while (len > 0)
 | ||
|       {
 | ||
|         *pointer = reg;
 | ||
|         *number = (len <= 16) ? len : 16;
 | ||
|         smartlink(_eutron_key);
 | ||
| 
 | ||
|         ok = _eutron_key->status == ST_OK;
 | ||
|         if (ok)
 | ||
|           memcpy(ud, &_eutron_key->data[4], (*number)*2);
 | ||
|         else
 | ||
|         {
 | ||
|           GetServerApp().WriteLog("*** EUTRON read error");
 | ||
|           break;
 | ||
|         }  
 | ||
|         len -= *number;
 | ||
|         reg += *number;
 | ||
|         ud  += *number;
 | ||
|       }    
 | ||
|     }
 | ||
|     break; 
 | ||
|   default:
 | ||
|     break;
 | ||
|   }  
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| // Data punta ad un array di 4 words 
 | ||
| // Deve essere cosi' per problemi del C,
 | ||
| // non trasformare in array: pena di morte! 
 | ||
| bool TDongle::write_words(unsigned short reg, unsigned short len, unsigned short* data) const
 | ||
| {                     
 | ||
|   bool ok = false;
 | ||
|   switch(_hardware)
 | ||
|   {                
 | ||
|   case _dongle_hardlock:
 | ||
|     {
 | ||
|       int err = STATUS_OK;
 | ||
|       for (unsigned short r = 0; r < len; r++)
 | ||
|       {           
 | ||
|         const unsigned short address = reg+r;
 | ||
|         err = HL_WRITE(address, data[r]);
 | ||
|         if (err != STATUS_OK)                                     
 | ||
|         {
 | ||
|           GetServerApp().WriteLog("*** HARDLOCK write error");
 | ||
|           break;
 | ||
|         }  
 | ||
|       }  
 | ||
|       ok = err == STATUS_OK;
 | ||
|     }  
 | ||
|     break;
 | ||
|   case _dongle_eutron:
 | ||
|     if (_eutron_key)
 | ||
|     {
 | ||
| #ifdef WIN32
 | ||
|       _eutron_key->net_command = NET_KEY_ACCESS;
 | ||
| #endif
 | ||
|       _eutron_key->command = BLOCK_WRITING_MODE;
 | ||
|       unsigned short* pointer = (unsigned short*)(&_eutron_key->data[0]);
 | ||
|       unsigned short* number  = (unsigned short*)(&_eutron_key->data[2]);
 | ||
|       while (len > 0)
 | ||
|       {
 | ||
|         *pointer = reg;
 | ||
|         *number = len > 16 ? 16 : len;
 | ||
|         memcpy(&_eutron_key->data[4], data, (*number)*2);
 | ||
|         smartlink(_eutron_key);
 | ||
|         ok = _eutron_key->status == ST_OK;
 | ||
|         if (!ok)
 | ||
|         {
 | ||
|           GetServerApp().WriteLog("*** EUTRON write error");
 | ||
|           break;
 | ||
|         }  
 | ||
|         reg  += *number;
 | ||
|         len  -= *number;
 | ||
|         data += *number;
 | ||
|       }    
 | ||
|     }
 | ||
|   default:
 | ||
|     break;  
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| bool TDongle::burn_hardlock()
 | ||
| {
 | ||
|   unsigned short data[4];
 | ||
| 
 | ||
|   const wxDateTime today = wxDateTime::Now();   
 | ||
|   const bool already = already_programmed();
 | ||
|   if (already)  
 | ||
|   {       
 | ||
|     memcpy(data, &_eprom[60], sizeof(data));
 | ||
|     garble(data);                         
 | ||
|     if (data[0] < 1997 || data[0] > 2997)
 | ||
| 		{
 | ||
| 			GetServerApp().WriteLog("On Line Assistance error.");
 | ||
|       return false;
 | ||
| 		}
 | ||
|     if (data[1] == 0 || data[1] >= 10000)
 | ||
| 		{
 | ||
| 			GetServerApp().WriteLog("*** Bad users number.");
 | ||
|       return false;
 | ||
| 		}
 | ||
|     const long& val = (const long&)data[2];
 | ||
|     const wxDateTime date= julian2date(val);
 | ||
|     if (date > today)
 | ||
| 		{
 | ||
|       GetServerApp().WriteLog("*** Too late sir: key has already expired!");
 | ||
|       return false;
 | ||
| 		}
 | ||
|   }
 | ||
|   
 | ||
|   data[0] = _year_assist;
 | ||
|   data[1] = _max_users;
 | ||
|   long& val = (long&)data[2];
 | ||
|   val = date2julian(today);
 | ||
|   garble(data);
 | ||
|   write_words(60, 4, data);
 | ||
|   _last_update = today;
 | ||
| 
 | ||
|   // Il primo bit della memoria della chiave corrisponde al modulo uno 
 | ||
|   // non allo zero (che e' la base ed e' sempre attivo)
 | ||
|   unsigned short module = 1;
 | ||
|   for (int octect = 0; octect < 3; octect++)  
 | ||
|   {                                       
 | ||
|     for(int parola = 0; parola < 3; parola++)  
 | ||
|     {        
 | ||
|       unsigned short& p = data[parola];
 | ||
|       p = 0;
 | ||
|       for (int bit = 0; bit < 16; bit++)
 | ||
|       {          
 | ||
|         if (Active(module))
 | ||
|           set_bit(p, bit);
 | ||
|         module++;
 | ||
|       }
 | ||
|       p ^= _serno;
 | ||
|     }
 | ||
|     data[3] = _serno;
 | ||
|     garble(data);
 | ||
|     write_words(48 + 4*octect, 4, data);
 | ||
|   }
 | ||
|   
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| bool TDongle::burn_eutron()
 | ||
| {
 | ||
|   TEutronHeader* eh = (TEutronHeader*)_eprom;
 | ||
|   memset(eh, 0, sizeof(TEutronHeader));
 | ||
|   
 | ||
|   _last_update = wxDateTime::Now();
 | ||
|   sprintf(eh->_serno, "%lu", (unsigned long)_serno);
 | ||
|   eh->_year_assist = _year_assist;
 | ||
|   eh->_max_users   = _max_users;
 | ||
|   eh->_last_date   = date2long(_last_update);
 | ||
|   eh->_scad_date   = 0;
 | ||
|   
 | ||
|   unsigned long cs = 0;
 | ||
|   for (unsigned char* ptr = (unsigned char*)_eprom; ptr < (unsigned char*)&eh->_checksum; ptr++)
 | ||
|     cs += *ptr | ~(short(*ptr << 8));
 | ||
|   eh->_checksum = cs;
 | ||
|   
 | ||
|   const unsigned short otb = sizeof(TEutronHeader) / 2;
 | ||
|   const unsigned short sob = 16;
 | ||
|   eh->_offset_to_bits = otb;
 | ||
|   eh->_size_of_bits = sob;
 | ||
|   
 | ||
|   bool ok = write_words(0, otb, _eprom);
 | ||
|   
 | ||
|   if (ok)
 | ||
|   {
 | ||
|     unsigned short data[sob]; memset(data, 0, sizeof(data));
 | ||
|     for (int module = 1; module < 256; module++)
 | ||
|     {                             
 | ||
|       if (Active(module))
 | ||
|       {
 | ||
|         unsigned short& w = data[(module-1) / 16];
 | ||
|         set_bit(w, (module-1) % 16, true);
 | ||
|       }  
 | ||
|     }
 | ||
|     ok = write_words(otb, sob, data);
 | ||
|   }
 | ||
|   
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| bool TDongle::Burn()
 | ||
| {          
 | ||
|   bool ok = _type == _user_dongle;
 | ||
| 
 | ||
|   if (ok) 
 | ||
|   {       
 | ||
|     switch(_hardware)
 | ||
|     {
 | ||
|       case _dongle_hardlock: ok = burn_hardlock(); break;
 | ||
|       case _dongle_eutron  : ok = burn_eutron(); break;
 | ||
|       default              : break;
 | ||
|     }  
 | ||
|   }   
 | ||
|   if (ok)
 | ||
|     _dirty = false; 
 | ||
| 
 | ||
|   return ok;  
 | ||
| }
 | ||
| 
 |