Для примера можно создать DLL’ку, которая будет, в зависимости
от пользователя будет учитывать или не учитывать время подключения
к серверу и, при учете времени, будет за какое-то определенное время
до окончания лимита, посылать электронное письмо с предупреждением
на ящик пользователя.Для полноценной программы необходимы модули
работы с базами данных и с сокетами. В примере они опущены, чтобы
не загромождать код.
HANDLE hPortZ; // порт
DWORD APIENTRY MprAdminInitializeDll(VOID)
{
// Здесь можно поставить проверку на доступность базы данных, считывание
конфигурации, инициализацию переменных и т.д.
return NO_ERROR;
}
DWORD APIENTRY MprAdminGetIpAddressForUser(WCHAR *UserName,WCHAR
*PortName,DWORD *IpAddress,BOOL *NotifyRelease)
{
// IP адрес назначается самим сервером
NotifyRelease = FALSE;
return NO_ERROR;
}
BOOL APIENTRY MprAdminAcceptNewConnection(RAS_CONNECTION_0 *pRasc0,RAS_CONNECTION_1
*pRasc1)
{
// в процедуре FindNameUser происходит работа с базой данных – поиск
пользователя и возврат в соответствии с результатом
switch (FindNameUser(pRasc0->wszUserName))
{
case 0: // ошибка работы с базой данных
nowork = true;
return FALSE;
break;
case 1: // работать без таймера
createtimer = false;
break;
case 2: // исчерпатн лимит времени
return FALSE;
break;
case 3: // работать с таймером
// создать поток для отсчета времени
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TProc,0,0,&dwThreadId);
if (hThread == NULL)
{
return FALSE;
break;
}
// создать поток для отправки электронного письма
hThreadMail = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TProcMail,0,0,&dwThreadIdMail);
if (hThreadMail == NULL)
{
return FALSE;
break;
}
createtimer = true;
break;
}
return TRUE;
}
BOOL APIENTRY MprAdminAcceptNewLink(RAS_PORT_0 *pRasPort0,RAS_PORT_1
*pRasPort1)
{
hPortZ = pRasPort0->hPort;
return TRUE;
}
void APIENTRY MprAdminLinkHangupNotification(RAS_PORT_0 *pRasPort0,
RAS_PORT_1 *pRasPort1)
{
}
void APIENTRY MprAdminReleaseIpAddress(WCHAR *UserName,WCHAR *PortName,DWORD
*IpAddress)
{
}
void APIENTRY MprAdminConnectionHangupNotification(RAS_CONNECTION_0
*pRasc0,RAS_CONNECTION_1 *pRasc1)
{
if (createtimer == true)
{
// если поток подсчета времени не завершен, то принудительно завершить
его
TerminateThread(hThread,0);
CloseHandle(hThread);
// если поток для отправки почты не завершен, то принудительно завершить
его
TerminateThread(hThreadMail,0);
CloseHandle(hThreadMail);
createtimer = false;
}
// Здесь можно поставить запись в базу информации о продолжительности
подключения и т.д.
}
DWORD APIENTRY MprAdminTerminateDll(VOID)
{
// Здесь можно поставить завершение работы с базой данных и т.д.
return NO_ERROR;
}
// поток подсчитывающий время и отключающий пользователя
DWORD WINAPI TProc(LPVOID lpar)
{
MPR_SERVER_HANDLE ServerHandle; // timeonline – лимит времени пользователя
Sleep(timeonline*1000); // тормозим поток на доступное время работы
MprAdminServerConnect(NULL,&ServerHandle); // подключаемся к
серверу
MprAdminPortClearStats(ServerHandle,hPortZ); // сбрасываем статистику
порта
MprAdminPortReset(ServerHandle,hPortZ); // сбрасываем порт
MprAdminPortDisconnect(ServerHandle,hPortZ); // разрываем соеденение
MprAdminServerDisconnect(ServerHandle); // отключаемся от сервера
ExitThread(0);
return 0;
}// поток отправляющий предупредительное письмо пользователю
DWORD WINAPI TProcMail(LPVOID lpar)
{
// проверка на доступное время подключения
// timeonline – лимит времени пользователя
// interval – интервал в секундах, перед которым посылать пиедупреждение
пользователю
if (timeonline > interval)
{
// доступное время больше минимального интервала
Sleep((timeonline - interval)*1000); // тормозим поток
SendMail(); // посылаем электронное письмо
ExitThread(0);
}
else
{
// доступное время меньше интервала, завершаем поток
ExitThread(0);
}
return 0;
}