Сообщений 0    Оценка 100        Оценить  
Система Orphus

Routing and Remote Access Server Administration DLL

Назначение, пример приложения

Автор: Певцов Константин aka Rainbow
Опубликовано: 11.01.2004
Исправлено: 21.04.2006
Версия текста: 1.0
Краткое описание
Функции RAS Admin DLL
Подключение к RAS
Пример приложения

Краткое описание

Routing and Remote Access Server Administration DLL (далее RAS Admin DLL) служит для подключения к серверу удаленного доступа и выполнения администраторских функций, описанных в DLL. Может применяться для организаций, предоставляющих свои услуги по доступу в Internet с помощью удаленного доступа.

Можно отметить три основных задачи, которые можно решить с помощью RAS Admin DLL:

  1. Идентифицировать пользователя, дополнительно к стандартной проверке сервера удаленного доступа.
  2. Записывать время подключения и отключения пользователей.
  3. Принудительно назначать IP адрес пользователю.

Также, при помощи небольших ухищрений можно выполнять практически любые функции. Например, за час, до окончания лимита доступного времени посылать пользователю электронное письмо с предупреждением и т.д.

Возможность использования RAS Admin DLL существует в операционных системах, построенных на базе NT, начиная с WindowsNT 4.0. Но реализация самой DLL для WindowsNT 4.0 и для более поздних операционных систем (Windows 2000/XP) отличается. В данной статье описывается пример создания RAS Admin DLL для Windows 2000/XP. Более подробную информацию можно получить в MSDN.

Функции RAS Admin DLL

RAS Admin DLL должна содержать определенные функции, которые и будут вызываться сервером удаленного доступа, в зависимости от события.

Ниже представлен список этих функций и их краткое описание. Функции представлены в порядке их вызова в течении одного сеанса работы сервера удаленного доступа.


DWORD APIENTRY MprAdminInitializeDll(VOID)

Вызывается при запуске сервера удаленного доступа и подключении вашей DLL. Эта функция вызывается первой из всех, необходимых для работы RAS Admin DLL. Предназначена для ваших инициализационных действий. Требует возврата NO_ERROR для продолжения работы вашей DLL. Если функция возвращает значение отличное от NO_ERROR, то работа RAS Admin DLL блокируется и сервер удаленного доступа работает в обычном режиме.


DWORD APIENTRY MprAdminGetIpAddressForUser(WCHAR *UserName,WCHAR *PortName,DWORD *IpAddress,BOOL *NotifyRelease)

Функция назначения нового IP адреса. При назначении нового IP адреса, NotifyRelease должно принять значение TRUE, а IpAddress – новый IP адрес. Если NotifyRelease равен FALSE, то IP адрес назначается по умолчанию самим сервером удаленного доступа. Вызывается при подключении пользователя к серверу удаленного доступа.


BOOL APIENTRY MprAdminAcceptNewConnection(RAS_CONNECTION_0 *pRasc0,RAS_CONNECTION_1 *pRasc1)

Уведомление о новом подключении. Для продолжения работы требует возврата TRUE. Вызывается при подключении пользователя к серверу удаленного доступа. Структуры RAS_CONNECTION_0 и RAS_CONNECTION_1 описаны в MSDN.


BOOL APIENTRY MprAdminAcceptNewLink(RAS_PORT_0 *pRasPort0,RAS_PORT_1 *pRasPort1)

Уведомление об установке связи. Для продолжения работы требует возврата TRUE. Вызывается при подключении пользователя к серверу удаленного доступа. Структуры RAS_PORT_0 и RAS_PORT_1 описаны в MSDN.


void APIENTRY MprAdminLinkHangupNotification(RAS_PORT_0 *pRasPort0,  RAS_PORT_1 *pRasPort1)

Уведомление о разрыве связи. Вызывается при отключении пользователя от сервера удаленного доступа.


void APIENTRY MprAdminConnectionHangupNotification(RAS_CONNECTION_0 *pRasc0,RAS_CONNECTION_1 *pRasc1)

Уведомление о разрыве соединения. Вызывается при отключении пользователя от сервера удаленного доступа.


void APIENTRY MprAdminReleaseIpAddress(WCHAR *UserName,WCHAR *PortName,DWORD *IpAddress)

Функция освобождения IP адреса. Вызывается при отключении пользователя от сервера удаленного доступа только при принудительном назначении IP адреса.


DWORD APIENTRY MprAdminTerminateDll(VOID)

Вызывается при выключении сервера.

ПРИМЕЧАНИЕ

В MSDN присутствует некоторая неточность при описании этих функций. Дело в том, что в MSDN отсутствуют типы вызовов этих функций, т.е. отсутствует признак APIENTRY (_stdcall). По умолчанию же MSVC генерирует код с _cdecl вызовами.

Из вышеописанных функций нельзя вызывать другие RAS администраторские функции.

Подключение к RAS

Для регистрации вашей RAS Admin DLL в системе и подключении ее к RAS, необходимо прописать соответствующий ключ в реестре. Для простоты можно создать простой reg файл:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\RAS\AdminDll]
"DisplayName"="ras admin dll"
"DLLPath"="c:\\rasdll\\rasdll.dll"

DisplayName – название вашей dll. Никакой существенной роли не играет.

DLLPath – полный путь к вашей dll.

Сервер удаленного доступа не подключит вашу DLL, если в ней реализованы не все требуемые функции и если отсутствует корректная запись в системном реестре.

Пример приложения

Для примера можно создать 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;
}


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
    Сообщений 0    Оценка 100        Оценить