/*
============================================================================
Name : create.c
Author : Chebotarev Roman
Version :
Copyright : All rights reserved
Description : Hello World in C, Ansi-style
============================================================================
*/
/*
Задаём тип операционной системы в которой производится сборка
программы. Старший байт (0x5) указывает версию ОС, младший
байт (0x01) - подверсию. Таким образом 0x501 = 5.1 (Windows XP).
См. подробности в описании структуры OSVERSIONINFOEX (ссылка ниже).
*/
#define WINVER 0x501
#include <stdio.h>
#include <windows.h>
#include <stdint.h>
/*
При сборке использовался компилятор MinGW. В его поставке содержится
старый файл ras.h и структура RASENTRY в нём соответствует ОС до
Windows XP. В ней отсутствует ряд необходимых полей. Поэтому
пришлось позаимствовать оригинальный заголовочный файл из SDK.
*/
#include "ras-sdk.h"
/*
Если для сборки вы используете MS Visual Studio,
то необходимо заменить предыдущую директиву #include на
#include <ras.h>
*/
#define USER "username"
#define PASSWD "password"
#define SERVER "vpn.server.address.or.hostname"
#define VPN_NAME "VPN connection"
int32_t create_vpn_connection(LPSTR connect_point, LPSTR title);
int32_t set_username_passwd(char *entry_title);
int32_t start_vpn(LPSTR title, HRASCONN * connection);
int main(void)
{
puts("Demonstration of creating VPN connection"); /* prints Demonstration of creating VPN connection */
if(!create_vpn_connection(SERVER, VPN_NAME))
printf("Error creating VPN connection.\n");
else
printf("Success creating VPN connection.\n");
/* Запускаем созданное VPN подключение */
HRASCONN connection = 0;
int32_t error;
if( (error = start_vpn(VPN_NAME, &connection)) )
printf("Error starting VPN connection, code: %d\n", error);
else printf("Start VPN success");
return EXIT_SUCCESS;
}
/*
Вспомогательная функция устанавливающая пароль и имя
пользователя для RAS-подключения с именем заданным указателем *entry_title
*/
int32_t set_username_passwd(char *entry_title)
{
RASDIALPARAMS ras_param;
ZeroMemory(&ras_param, sizeof(RASDIALPARAMS));
ras_param.dwSize = sizeof(RASDIALPARAMS);
memcpy(ras_param.szEntryName, entry_title, strlen(entry_title));
memcpy(ras_param.szUserName, "username", strlen("username"));
memcpy(ras_param.szPassword, "password", strlen("password"));
return RasSetEntryDialParams(0, &ras_param, 0);
}
int32_t create_vpn_connection(LPSTR connect_point, LPSTR title)
{
OSVERSIONINFOEX OS_version_info;
int32_t bOsVersionInfoEx;
int32_t rasentry_struct_size = sizeof(RASENTRY);
ZeroMemory(&OS_version_info, sizeof(OSVERSIONINFOEX));
OS_version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
/* Получаем версию ОС в которой запущена программа */
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &OS_version_info)) )
{
OS_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx( (OSVERSIONINFO *) &OS_version_info) )
return 0;
}
/* Проверяем версию ОС на соответствие платформе WIN32_NT */
if(OS_version_info.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
if ( (OS_version_info.dwMajorVersion == 5 && OS_version_info.dwMinorVersion == 0)
|| OS_version_info.dwMajorVersion <= 4)
/* Следующий оператор выполняется если версия ОС = 5.0 или <= 4.0, что соответствует
Windows 2000 или Windows NT. В этих ОС в структуре RASENTRY отсутствовали поля
начиная с dwfOptions2 (включительно). Программа собранная в Windows XP имеет
структуру RASENTRY бОльшего размера чем используется в Win 2000 и Win NT, поэтому
при попытке вызвать функцию RasSetEntryProperties с указанием размера структуры
через sizeof(RASENTRY) происходит ошибка. Значение 2088 соответствует
размеру RASENTRY без полей начиная с dwfOptions2. Таким образом даже используя
структуру бОльшего чем нужно для Win 2000 и Win NT размера можно сделать
корректный вызов функции RasSetEntryProperties */
rasentry_struct_size = 2088;
}
else /* Выходим т.к. Windows 95, 98, Me по умолчанию не поддерживают VPN подключения */
return 0;
RASENTRY rasEntry; /* Структура описывающая создаваемое/настраиваемое подключение */
memset(&rasEntry, 0, sizeof(RASENTRY));
rasEntry.dwSize = rasentry_struct_size;
/*
Задаём флаговые параметры VPN соединения.
Вкладка "Общие":
RASEO_ModemLights - флажок "При подключении отображать значок в области уведомлений"
Вкладка "Параметры":
RASEO_PreviewUserPw - флажок "Запрашивать имя, пароль, сертификат и т.д."
RASEO_ShowDialingProgress - флажок "Отображать ход подключения"
RASEO2_ReconnectIfDropped - флажок "перезвонить при разрыве связи"
Вкладка "Безопасность":
RASEO_Custom - радиокнопка "Дополнительные (выборочные параметры)"
Дополнительные параметры безопасности:
RASEO_RequireMsCHAP2 - флажок "Протокол проверки пароля Microsoft (MS-CHAP v2)
Вкладка "Сеть":
RASEO_SecureLocalFiles - снять флажки "Клиент для сетей Microsoft" и
"Служба доступа к файлам и принтерам сетей Microsoft"
Свойства "Протокол интернета (TCP/IP)":
RASEO2_DisableNbtOverIP - отключить NetBIOS через TCP/IP
RASEO2_Internet - установка данного флага обозначает что это подключение к Интернету
*/
rasEntry.dwfOptions = RASEO_PreviewUserPw | RASEO_ShowDialingProgress | RASEO_Custom |
RASEO_RequireMsCHAP2 | RASEO_ModemLights | RASEO_SecureLocalFiles;
rasEntry.dwfOptions2 = RASEO2_DisableNbtOverIP | RASEO2_ReconnectIfDropped | RASEO2_Internet;
/* Задаём значения полей структуры */
/* Вкладка "Параметры" */
rasEntry.dwRedialCount = 99; /* Поле "Число повторных попыток набора номера" */
rasEntry.dwRedialPause = 3; /* Поле "Интервал между повторениями" */
/* Вкладка "Безопасность -> Параметры" */
rasEntry.dwEncryptionType = ET_Optional; /* Значение выпадающего списка "Шифрование данных" = "необязательное" */
/* Вкладка "Сеть" */
rasEntry.dwType = RASET_Vpn; /* Тип создаваемого подключения - VPN */
rasEntry.dwVpnStrategy = VS_PptpOnly; /* Значение выпадающего списка "Тип VPN" = "PPTP" */
/* Указываем адрес VPN сервера */
strcpy(rasEntry.szLocalPhoneNumber, connect_point);
/* Тип и имя используемого устройства*/
strcpy(rasEntry.szDeviceType, RASDT_Vpn);
strcpy(rasEntry.szDeviceName, TEXT("VPN"));
/* Создаём или, если подключение с этим именем уже существует - перенастраиваем, подключение */
if(RasSetEntryProperties(0, title, &rasEntry, rasentry_struct_size, NULL, 0) ||
set_username_passwd(title))
return 0;
return 1;
}
int32_t start_vpn(LPSTR title, HRASCONN * connection)
{
RASDIALPARAMS dial_params;
dial_params.dwSize = sizeof(RASDIALPARAMS);
strcpy(dial_params.szEntryName, title);
strcpy(dial_params.szPhoneNumber,"");
strcpy(dial_params.szCallbackNumber, "");
strcpy(dial_params.szUserName, USER);
strcpy(dial_params.szPassword, PASSWD);
strcpy(dial_params.szDomain, "");
dial_params.dwSubEntry = 0;
dial_params.dwCallbackId = 0;
* connection = NULL;
return RasDial(NULL, NULL, &dial_params, 0, NULL, connection);
}