1998-01-07 10:17:26 +00:00
|
|
|
|
#include "StdAfx.h"
|
|
|
|
|
|
|
|
|
|
#include "hlapi_c.h"
|
|
|
|
|
#define EYECAST (Word DATAFAR_ *)
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
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()
|
|
|
|
|
|
1998-01-07 10:17:26 +00:00
|
|
|
|
#include "connect.h"
|
|
|
|
|
#include "server.h"
|
|
|
|
|
#include "tracing.h"
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
|
#undef THIS_FILE
|
|
|
|
|
static char THIS_FILE[] = __FILE__;
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
|
|
|
|
|
|
1998-01-07 10:17:26 +00:00
|
|
|
|
// @doc INTERNAL
|
|
|
|
|
|
|
|
|
|
// @rdesc Ritorna il valore corrispondente alla chiave appartenente
|
|
|
|
|
// ad una sezione del file di configurazione
|
|
|
|
|
|
1998-11-13 14:54:23 +00:00
|
|
|
|
CString GetIniString(LPCSTR sec, // @parm Sezione
|
|
|
|
|
LPCSTR key, // @parm Chiave
|
|
|
|
|
LPCSTR def) // @parm Valore di default
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
// @doc EXTERNAL
|
1998-01-07 10:17:26 +00:00
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
// @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>
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
1998-05-04 10:09:51 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
1998-01-07 10:17:26 +00:00
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
|
|
|
|
|
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;
|
1998-01-07 10:17:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
BOOL TDongleServer::ReadHardlockWords(unsigned short reg,
|
|
|
|
|
unsigned short num,
|
|
|
|
|
unsigned short* data)
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
1998-05-04 10:09:51 +00:00
|
|
|
|
BOOL ok = HL_AVAIL() == STATUS_OK;
|
|
|
|
|
if (ok)
|
1998-01-27 10:53:26 +00:00
|
|
|
|
{
|
1998-05-04 10:09:51 +00:00
|
|
|
|
for (unsigned short n = 0; n < num; n++)
|
|
|
|
|
HL_READ(reg+n, EYECAST &data[n]);
|
1998-11-13 14:54:23 +00:00
|
|
|
|
HL_CODE(EYECAST data, 1);
|
1998-01-27 10:53:26 +00:00
|
|
|
|
}
|
1998-05-04 10:09:51 +00:00
|
|
|
|
return ok;
|
1998-01-07 10:17:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
BOOL TDongleServer::HardlockLogin()
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
|
1998-11-13 14:54:23 +00:00
|
|
|
|
const int status = HL_LOGIN(26952, LOCAL_DEVICE, ref, ver);
|
1998-01-07 10:17:26 +00:00
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
Trace(-1, "Login Hardlock %s: %d",
|
|
|
|
|
status == STATUS_OK ? "OK" : "FALLITO", status);
|
|
|
|
|
|
|
|
|
|
_SerNo = 0xFFFF;
|
1998-11-13 14:54:23 +00:00
|
|
|
|
if (status == STATUS_OK)
|
1998-05-04 10:09:51 +00:00
|
|
|
|
{
|
|
|
|
|
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];
|
1998-06-24 13:48:00 +00:00
|
|
|
|
_MaxUsers = Val[1];
|
1998-05-04 10:09:51 +00:00
|
|
|
|
|
|
|
|
|
int index = 0;
|
|
|
|
|
for (unsigned short reg = 48; reg < 60; reg += 4)
|
|
|
|
|
{
|
|
|
|
|
ReadHardlockWords(reg, 4, Val);
|
1998-11-13 14:54:23 +00:00
|
|
|
|
Val[0] ^= _SerNo;
|
|
|
|
|
Val[1] ^= _SerNo;
|
|
|
|
|
Val[2] ^= _SerNo;
|
1998-05-04 10:09:51 +00:00
|
|
|
|
memcpy(&_int_tab[index], Val, 3);
|
|
|
|
|
index += 3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-01-07 10:17:26 +00:00
|
|
|
|
|
1998-11-13 14:54:23 +00:00
|
|
|
|
return status == STATUS_OK;
|
1998-01-07 10:17:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
BOOL TDongleServer::EutronLogin()
|
|
|
|
|
{
|
|
|
|
|
BOOL ok = FALSE;
|
|
|
|
|
memset(&_Eutron, 0, sizeof(_Eutron));
|
|
|
|
|
_Eutron.net_command = NET_KEY_OPEN;
|
|
|
|
|
|
1998-11-13 14:54:23 +00:00
|
|
|
|
const char* labels[2] = { "AGA.CAMPO", "25EBAI" };
|
1998-05-04 10:09:51 +00:00
|
|
|
|
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);
|
1998-11-13 14:54:23 +00:00
|
|
|
|
if (k == 0)
|
|
|
|
|
{
|
|
|
|
|
char pwd[PASSWORD_LENGTH];
|
|
|
|
|
Encode(labels[k], pwd);
|
|
|
|
|
memcpy(_Eutron.password, pwd, strlen(pwd));
|
|
|
|
|
}
|
1998-05-04 10:09:51 +00:00
|
|
|
|
smartlink(&_Eutron);
|
|
|
|
|
ok = _Eutron.status == ST_OK;
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
1998-11-13 14:54:23 +00:00
|
|
|
|
if (k == 1)
|
|
|
|
|
_SerNo = 0;
|
1998-05-04 10:09:51 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-11-13 14:54:23 +00:00
|
|
|
|
Trace(-1, "Login Eutron %s: %d", ok ? "OK" : "FALLITO", _Eutron.status);
|
1998-05-04 10:09:51 +00:00
|
|
|
|
|
|
|
|
|
if (ok && _SerNo != 0)
|
|
|
|
|
{
|
|
|
|
|
TEutronHeader eh;
|
|
|
|
|
if (ReadEutronWords(0, sizeof(TEutronHeader)/2, (unsigned short*)&eh))
|
|
|
|
|
{
|
1998-11-13 14:54:23 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
1998-05-04 10:09:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return _Eutron.status == ST_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL TDongleServer::Login()
|
|
|
|
|
{
|
|
|
|
|
BOOL ok = HardlockLogin() || EutronLogin();
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
1998-06-24 13:48:00 +00:00
|
|
|
|
if (_SerNo == 0 || _MaxUsers == 0)
|
1998-05-04 10:09:51 +00:00
|
|
|
|
{
|
|
|
|
|
const CTime tNow = CTime::GetCurrentTime();
|
|
|
|
|
_AssistanceYear = tNow.GetYear();
|
|
|
|
|
if (_SerNo == 0)
|
|
|
|
|
{
|
1998-06-24 13:48:00 +00:00
|
|
|
|
_MaxUsers = 4;
|
1998-05-04 10:09:51 +00:00
|
|
|
|
memset(_int_tab, 0xFF, sizeof(_int_tab));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
1998-06-24 13:48:00 +00:00
|
|
|
|
_MaxUsers = 1;
|
1998-05-04 10:09:51 +00:00
|
|
|
|
memset(_int_tab, 0x00, sizeof(_int_tab));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Trace(-1, "Numero di serie %u", _SerNo);
|
|
|
|
|
Trace(-1, "Anno assistenza %u", _AssistanceYear);
|
1998-06-24 13:48:00 +00:00
|
|
|
|
Trace(-1, "Numero utenti %u", _MaxUsers);
|
1998-11-13 14:54:23 +00:00
|
|
|
|
|
|
|
|
|
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);
|
1998-05-04 10:09:51 +00:00
|
|
|
|
}
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TDongleServer::Logout()
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
1998-05-04 10:09:51 +00:00
|
|
|
|
if (_Eutron.label[0])
|
|
|
|
|
{
|
|
|
|
|
_Eutron.net_command = NET_KEY_CLOSE;
|
|
|
|
|
smartlink(&_Eutron);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
HL_LOGOUT();
|
|
|
|
|
}
|
|
|
|
|
_SerNo = 0xFFFF;
|
1998-06-24 13:48:00 +00:00
|
|
|
|
_MaxUsers = 0;
|
1998-05-04 10:09:51 +00:00
|
|
|
|
_AssistanceYear = 0;
|
|
|
|
|
memset(_int_tab, 0, sizeof(_int_tab));
|
1998-01-07 10:17:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
BOOL TDongleServer::OnConnect(const CString& topic)
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
1998-06-24 13:48:00 +00:00
|
|
|
|
BOOL ok = Users() < MaxUsers();
|
1998-01-07 10:17:26 +00:00
|
|
|
|
if (!ok)
|
|
|
|
|
Trace(0, "Refusing Topic %s", (const char*)topic);
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
TConnection* TDongleServer::OnCreateConnection(DWORD id)
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
|
|
|
|
TConnection* c = NULL;
|
1998-11-13 14:54:23 +00:00
|
|
|
|
|
|
|
|
|
CString strPeer;
|
|
|
|
|
GetPeerName(id, strPeer);
|
|
|
|
|
|
|
|
|
|
const int n = GetPeerConnections(strPeer);
|
|
|
|
|
if (n > 0 || Peers() < MaxUsers())
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
1998-11-13 14:54:23 +00:00
|
|
|
|
Trace(0, "Connecting %lu from %s", id, strPeer);
|
|
|
|
|
c = new TPrassiConnection(this, id, strPeer);
|
1998-01-07 10:17:26 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
1998-11-13 14:54:23 +00:00
|
|
|
|
Trace(0, "Refusing Connection %lu from %s", id, strPeer);
|
1998-01-07 10:17:26 +00:00
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
BOOL TDongleServer::OnRemoveConnection(DWORD id)
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
1998-11-13 14:54:23 +00:00
|
|
|
|
CString strPeer;
|
|
|
|
|
GetPeerName(id, strPeer);
|
|
|
|
|
Trace(0, "Disconnecting %lu from %s", id, strPeer);
|
1999-01-21 16:40:02 +00:00
|
|
|
|
BOOL ok = TSocketServer::OnRemoveConnection(id);
|
|
|
|
|
return ok;
|
1998-01-07 10:17:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-11-13 14:54:23 +00:00
|
|
|
|
static int CountUsers(TConnection& conn, void* pJolly)
|
1998-06-24 13:48:00 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
1998-11-13 14:54:23 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
1999-01-21 16:40:02 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
1998-11-13 14:54:23 +00:00
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
TDongleServer::TDongleServer()
|
1999-01-21 16:40:02 +00:00
|
|
|
|
: TSocketServer("DONGLE")
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
|
|
|
|
_SerNo = 0xFFFF;
|
1998-06-24 13:48:00 +00:00
|
|
|
|
_MaxUsers = 0;
|
1998-05-04 10:09:51 +00:00
|
|
|
|
_AssistanceYear = 0;
|
|
|
|
|
memset(_int_tab, 0, sizeof(_int_tab));
|
1998-01-07 10:17:26 +00:00
|
|
|
|
Login();
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
TDongleServer::~TDongleServer()
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
1998-05-04 10:09:51 +00:00
|
|
|
|
if (_SerNo != 0xFFFF)
|
|
|
|
|
Logout();
|
1998-01-07 10:17:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
// Start/Stop server
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
static TDongleServer* pDDE = NULL;
|
1998-01-07 10:17:26 +00:00
|
|
|
|
|
|
|
|
|
BOOL StopServer()
|
|
|
|
|
{
|
|
|
|
|
BOOL ok = pDDE != NULL;
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
delete pDDE;
|
|
|
|
|
pDDE = NULL;
|
|
|
|
|
}
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-04 10:09:51 +00:00
|
|
|
|
TDongleServer& GetServer()
|
1998-01-07 10:17:26 +00:00
|
|
|
|
{
|
|
|
|
|
ASSERT(pDDE);
|
|
|
|
|
return *pDDE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL StartServer()
|
|
|
|
|
{
|
|
|
|
|
BOOL ok = pDDE == NULL;
|
|
|
|
|
if (ok)
|
1998-05-04 10:09:51 +00:00
|
|
|
|
pDDE = new TDongleServer;
|
1998-01-07 10:17:26 +00:00
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|