RAS是Remote Access Service的缩写,意为:远程访问服务,主要用来配置企业的远程用户对企业内部网络访问,包括拨号访问和vpn方式。微软的所有Windows平台中都有RAS客户机,它允许我们将自己的计算机与另一个地方的远程计算机(其特色是一个远程访问服务器组件)相连,一般情况下,  RAS客户机利用连接了电话线的一个调制解调器,通过拨号的方式呼叫远程计算机。服务器这方面,必须有一项等候DUN连接的服务,RAS客户机和服务器之间的连接建立之后,网络协议堆栈(与所用的分帧协议有关)就通过这个RAS连接,与远程计算机通信,就象通过LAN连接的一样。如今,许多调制解调器的数据通信速率明显比直接的LAN连接慢。RAS连接通过电话簿条目中可用的选项,经过验证后,RAS便可自动进入一台机器,登录到一个域。

VPN开发经常使用的API

RAS有四个函数,允许通过程序对电话簿RASENTRY结构进行管理。它们是:RasSet Entry、RasGetEntryProperties、RasRenameEntry和RasDeleteEntry。如要建立一个新条目或对一个现成的条目进行修改,可使用RasSetEntryProperties函数

RasGetEntryProperties  此函数检索并返回一个电话簿条目的属性

RasSetEntryProperties  修改或者创建一个电话本中的链接条目信息,通俗的说就是修改或创建一个VPN链接属性。

DWORD RasGetEntryProperties(
  LPWSTR lpszPhoneBook,
  LPWSTR szEntry,
  LPRASENTRY lpbEntry,
  LPDWORD lpdwEntrySize,
  LPBYTE lpb,
  LPDWORD lpdwSize
);

lpszPhoneBook:常被忽略并被设置为空值,电话薄条目存储在注册表中,而不是在电话本中。

szEntry:一个包含条目名称,空字符结尾字符串的指针。如果指定一个空字符串,该函数返回的默认值在lpbEntry 和 lpb 参数指向的缓冲区。

lpbEntry:指定新的连接数据,要与由 lpszEntry 参数指示的电话簿条目关联的 RASENTRY 结构的指针。
 

RasDeleteEntry

删除电话薄中条目,一般用来删除VPN连接

RasDial:拨号API

DWORD RasDial(

__in         
LPRASDIALEXTENSIONS lpRasDialExtensions,

__in         
LPCTSTR lpszPhonebook,

__in         
LPRASDIALPARAMS lpRasDialParams,

__in         
DWORD dwNotifierType,

__in         
LPVOID lpvNotifier,

__in         
LPHRASCONN lphRasConn

);

lpRasDialExtensions:参数是一个可选指针,指向一个RASDIALEXTENSIONS结构,有了

这个结构,你的应用程序便可使用RasDial函数的扩展特性了,
可忽略,设为NULL

pszPhonebook:用于识别到一个电话簿文件的路径。设为NULL,表示使用当前默认电话簿文件

lpRasDialParams:定义了拨号和用户身份验证参数

dwNotifierType,
lpvNotifier:可同步调用还是异步调用。

lphRasConn:

第一个参数lpRasDialExtensions

typedef struct
tagRASDIALEXTENSIONS {

DWORD    
dwSize;

DWORD    
dwfOptions;

HWND     
hwndParent;

ULONG_PTR reserved;

#if (WINVER >=
0x500)

ULONG_PTR reserved1;

RASEAPINFO RasEapInfo;

#endif

} RASDIALEXTENSIONS

第三个参数lpRasDialParams

typedef struct
_RASDIALPARAMS {

DWORD    
dwSize;

TCHAR    
szEntryName[RAS_MaxEntryName + 1];

TCHAR    
szPhoneNumber[RAS_MaxPhoneNumber + 1];

TCHAR    
szCallbackNumber[RAS_MaxCallbackNumber + 1];

TCHAR    
szUserName[UNLEN + 1];

TCHAR    
szPassword[PWLEN + 1];

TCHAR    
szDomain[DNLEN + 1] ;

#if (WINVER >=
0x401)

DWORD    
dwSubEntry;

ULONG_PTR dwCallbackId;

#endif

}
RASDIALPARAMS;

第四个第五个参数:

如果lpvNotifier参数设为NULL,RasDial就会置入同步模式。dwNotifierType参数就会被忽略。同步调用RasDial是使用该函数的最简单的作用;美中不足的是,同步模式下不能对连接进行监视,如果lpvNotifier

参数不为NULL,就会进入异步模式,
意味着进行连接的同时,函数调用会立即返回。可以对连接进程进行监视

dwNotifierType:

0: lpvNotifier参数使用RasDialFunc函数指针管理连接事件

1: lpvNotifier参数利用RasDialFunc1函数指针管理连接事件

2: lpvNotifier参数利用RasDialFunc2函数指针管理连接事件

0xFFFFFFF: lpvNotifier参数令RasDial在连接事件期间发送一个窗口消息

RasHangUp挂断VPN

DWORD RasHangUp(

__in         
HRASCONN hrasconn

);

hrasconn:RasDial返回的一个连接句柄

注意:连接在利用一个调制解调器端口时,如果连接关闭,这个端口需要花时间重新设置这个连接。因此,你应该一直等下去,直到端口连接完全关闭为止。要做到这一点,在重新设置自己的连接时,可调用

RasGetConnectionStatus:获取VPN链接状态来判断连接是否完全关闭。

DWORD
RasGetConnectStatus(

__in         
HRASCONN hrasconn,

__in_out     
LPRASCONNSTATUS lprasconnstatus

);

hrasconn:RasDial返回的一个连接句柄

lprasconnstatus:取得当前的连接状态

typedef struct
_RASCONNSTATUS {

DWORD        
dwSize;

RASCONNSTATE 
rasconnstate;

DWORD        
dwError;

TCHAR        
szDeviceType[RAS_MaxDeviceType + 1];

TCHAR        
szDeviceName[RAS_MaxDeviceName + 1];

#if (WINVER >=
0x401)

TCHAR       
szPhoneNumber[ RAS_MaxPhoneNumber + 1 ];

#endif // (WINVER
>= 0x401)

} RASCONNSTATUS;

dwSize:必须设为RASCONNSTATUS结构的长度(按字节算)。

rasconnstate:RAS连接活动状态

dwError:若RasGetConnectStatus没有返回0,就取得一个具体的R
A S错误代码

szDeviceType:取得一个字串,该字串代表连接所用的设备类型

szDeviceName:取得当前的设备名

szPhoneNumber:电话号码,如*99#之类的字符串

RasEnumDevices:获得所有具有RAS能力的设备名及类型

DWORD RasEnumDevices(

__in         
LPRASDEVINFO lpRasDevInfo,

__in_out     
LPDWORD lpcb,

__out        
LPDWORD lpcDevices

);

RasValidateEntryName:判断名字的格式是否正确,是否已包含在电话簿中

DWORD
RasValidateEntryName(

__in         
LPCTSTR lpszPhonebook,

__in         
LPCTSTR lpszEntry

);

lpszPhonebook:用于识别到一个电话簿文件的路径。设为NULL,表示使用当前默认电话簿文件

lpszEntry:电话簿中没有这个名字,但该名字格式无误时,便返回ERROR_SUCCESS。若名字格式有错,这个函数就会失败,返回ERROR_INVALIDNAME;

如果电话簿中有这个名字,就会返回ERROR_ALREAD_YEXIST

可以用RasGetEntryDialParams和RasSetEntryDialParams函数来管理与具体电话簿条目相关的用户安全凭据

通过对RasDial的成功调用,本函数调用后返回连接信息被保存为电话簿入口。

RasEnumConnections:返回一个RASCONN结构数组的缓存的长指针,指向每一个RAS连接。

在调用本函数之前,必须设置缓存中RASCONN结构的第一个成员dwSize的值,即RASCONN的大小,为了在不同系统版本中通过,请用sizeof(RASCONN)取得大小。

本函数列出所有活动RAS连接,返回每一个连接句柄和电话簿入口名

函数原型:

DWORD
RasEnumConnections(

LPRASCONN
lprasconn,

LPDWORD
lpcb,

LPDWORD
lpcConnections

);

下面我们来了解一个很重要的数据结构RASENTRY

typedef_struct_RASENTRY
{
  DWORD dwSize;
  DWORD dwfOptions;

DWORD dwCountryID;
  DWORD dwCountryCode;
  TCHAR szAreaCode[ RAS_MaxAreaCode + 1
];
  TCHAR szLocalPhoneNumber[
RAS_MaxPhoneNumber + 1 ];
  DWORD dwAlternatesOffset;
  RASIPADDR ipaddr;
  RASIPADDR ipaddrDns;
  RASIPADDR ipaddrDnsAlt;
  RASIPADDR ipaddrWins;
  RASIPADDR ipaddrWinsAlt;
  DWORD dwFrameSize;
  DWORD dwfNetProtocols;
  DWORD dwFramingProtocol;
  TCHAR szScript[ MAX_PATH ];
  TCHAR szAutoDialDll[ MAX_PATH
];
  TCHAR szAutoDialFunc[ MAX_PATH
];
  TCHAR szDeviceType[ RAS_MaxDeviceType +
1 ];
  TCHAR szDeviceName[ RAS_MaxDeviceName +
1 ];
  TCHAR szX25PadType[ RAS_MaxPadType + 1
];
  TCHAR szX25Address[ RAS_MaxX25Address +
1 ];
  TCHAR szX25Facilities[
RAS_MaxFacilities + 1 ];
  TCHAR szX25UserData[ RAS_MaxUserData +
1 ];
  DWORD dwChannels;
  DWORD dwReserved1;
  DWORD dwReserved2;
  DWORD dwCustomAuthKey;
} RASENTRY;

RASENTRY 赋值:

RasOptions   =  
RASEO_SpecificNameServers   |   RASEO_RemoteDefaultGateway;

//RASEO_UseCountryAndAreaCodes   (是否使用区号与拨号属性)

//RASEO_SpecificIpAddr   (服务类型-> TCP/IP设置-> 是否指定IP地址项)

//RASEO_SpecificNameServers   (设置DNS是否选用)

//RASEO_IpHeaderCompression   (是否选用IP头指针压缩)

//RASEO_RemoteDefaultGateway   (是否选用远程网上默认网关)

//RASEO_DisableLcpExtensions   (是否决定在PPP里不使用LCP,一般不使用这个选项)

//RASEO_TerminalAfterDial   (是否拨号后出现终端窗口 <常规-> 连接方式-> 设置-> 选项-> 连接控制> )

//RASEO_ModemLights   (此选项只对WIN2K有效,选用后在任务栏出现一个状态监测器)

//RASEO_SwCompression   (是否选用软件压缩 <服务器类型-> 高级选项> )

//RASEO_RequireEncryptedPw   (是否选用需要加密的密码 <作用是PPP使用PAP明文> )

//RASEO_RequireMsEncryptedPw   (是否选用需要微软加密的密码)

//RASEO_RequireDataEncryption   (是否选用需要数据加密)

//RASEO_NetworkLogon   (此选项对NT/2K没有影响,是否选用登陆网络)

//RASEO_UseLogonCredentials   (是否当前用户采用用户名、密码、域等信息进行拨号连接)

//RASEO_PromoteAlternates   (是否选用交替号码)

VpnStrategy   =   VS_Default;

strcpy(mName   , "GPRSHY ");

//   rasEntry     Num  
values

rasEntry.dwSize =   sizeof  
(RASENTRY);

rasEntry.dwfOptions =   RasOptions;

rasEntry.dwAlternateOffset =   0;

rasEntry.dwCountryID =   86;//china

rasEntry.dwCountryCode =   86;//china

rasEntry.dwFrameSize =   0;

rasEntry.dwfNetProtocols =   RASNP_Ip;
//   TCP/IP

rasEntry.dwFramingProtocol =  
RASFP_Ppp; //PPP

rasEntry.dwChannels =   0;

rasEntry.dwReserved1 =   0;

rasEntry.dwReserved2 =   0;

if(WINVER   > =   0X400)//
  WIN98系统

{

rasEntry.dwDialMode   =  
RASEDM_DialAsNeeded;

rasEntry.dwIdleDisconnectSeconds=0;

rasEntry.dwSubEntries=0;

rasEntry.dwDialExtraPercent=0;

rasEntry.dwDialExtraSampleSeconds=0;

rasEntry.dwHangUpExtraPercent=0;

rasEntry.dwHangUpExtraSampleSeconds=0;

if(WINVER   > =   0x500)//
  WIN2K系统

{

rasEntry.dwType        
    =   RASET_Vpn;

rasEntry.dwVpnStrategy=VpnStrategy;

rasEntry.dwCustomAuthKey=600;

GUID   guid;

CoCreateGuid(&guid);

rasEntry.guidId=guid;

rasEntry.dwEncryptionType=0;

strcpy(rasEntry.szCustomDialDll,
" ");

//
rasEntry.dwfOptions2=0;

//
rasEntry.dwfOptions3=0;

if(WINVER   > =   0x501)

{

//
rasEntry.dwfOptions2=0;

//
rasEntry.dwfOptions3=0;

}

}

}

//   Strings   values

char   strPhoneNumber[20];

char   strDevType[50];

char   strDevName[50];

strcpy   (strPhoneNumber,  
"*99***1# ");

strcpy   (strDevType,  
"RASDT_Modem ");

strcpy   (strDevName,  
"Hawsna   Wireless   Modem ");

strcpy   (rasEntry.szAreaCode,  
"   ");

strcpy   (rasEntry.szLocalPhoneNumber,
  strPhoneNumber);

strcpy   (rasEntry.szScript,  
" ");

strcpy   (rasEntry.szAutodialDll,
  " ");

strcpy   (rasEntry.szAutodialFunc,
  " ");

strcpy   (rasEntry.szX25PadType,  
" ");

strcpy   (rasEntry.szX25Address,  
" ");

strcpy   (rasEntry.szX25Facilities,
  " ");

strcpy   (rasEntry.szX25UserData,
  " ");

strcpy   (rasEntry.szDeviceType,  
strDevType);

strcpy   (rasEntry.szDeviceName,  
strDevName);

//   IP   addresses

RASIPADDR  
struipaddrDns,struipaddrDnsAlt,struipaddrWins,struipaddrWinsAlt;

struipaddrDns.a   =   211;

struipaddrDns.b   =   136;

struipaddrDns.c   =   20;

struipaddrDns.d   =   203;

struipaddrDnsAlt.a   =   202;

struipaddrDnsAlt.b   =   96;

struipaddrDnsAlt.c   =   128;

struipaddrDnsAlt.d   =   68;

struipaddrWins.a   =   0;

struipaddrWins.b   =   0;

struipaddrWins.c   =   0;

struipaddrWins.d   =   0;

struipaddrWinsAlt.a   =   0;

struipaddrWinsAlt.b   =   0;

struipaddrWinsAlt.c   =   0;

struipaddrWinsAlt.d   =   0;

rasEntry.ipaddrDns   =  
struipaddrDns;

rasEntry.ipaddrDnsAlt   =  
struipaddrDnsAlt;

rasEntry.ipaddrWins   =  
struipaddrWins;

rasEntry.ipaddrWinsAlt   =  
struipaddrWinsAlt;

一个简单的示例:

//   Call   RAS

DWORD   dwRet=RasSetEntryProperties   (NULL,   mName,   &rasEntry,   sizeof(RASENTRY),   NULL,   0);

if   (dwRet)//ERROR_INVALID_PARAMETER   ==   dwRet)  

{

CString   str;

str.Format( "RasSetEntryProperties   failed   %s\n   The   error   code:   %d\n ",   mName,dwRet);

AfxMessageBox(str);

// return   FALSE;

}

C++实现VPN工具之常用API函数的更多相关文章

  1. Delphi 常用API 函数

    Delphi 常用API 函数 AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小 AnyPopup 判断屏幕上是否存在任何弹出式窗口 ArrangeIconic ...

  2. C语言实现单链表,并完成链表常用API函数

    C语言实现单链表,并完成链表常用API函数: 1.链表增.删.改.查. 2.打印链表.反转打印.打印环形链表. 3.链表排序.链表冒泡排序.链表快速排序. 4.求链表节点个数(普通方法.递归方法). ...

  3. Delphi 常用API 函数列表

    Delphi 常用API 函数 AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小AnyPopup 判断屏幕上是否存在任何弹出式窗口ArrangeIconicWi ...

  4. C# 窗体常用API函数 应用程序窗体查找

    常用的处理窗体的API函数如下(注意:API函数必须放在窗体中...): 使用C#语言,要引用DllImport,必须要添加using System.Runtime.InteropServices命名 ...

  5. C#常用 API函数大全

    常用Windows API1. API之网络函数WNetAddConnection 创建同一个网络资源的永久性连接WNetAddConnection2 创建同一个网络资源的连接WNetAddConne ...

  6. Delphi 常用API 函数(好多都没见过)

    AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小AnyPopup 判断屏幕上是否存在任何弹出式窗口ArrangeIconicWindows 排列一个父窗口的最小 ...

  7. Quartz 2D(常用API函数、绘制图形、点线模式)

    Quzrtz 2D 绘图的核心 API 是 CGContextRef ,它专门用于绘制各种图形. 绘制图形关键是两步: 1.获取 CGContextRef ; 2.调用 CGContextRef 的方 ...

  8. 【总结】设备树语法及常用API函数【转】

    本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/74352188 一.DTS编写语法   二.常用函数 设备树函数思路是:uboot ...

  9. StringUtils工具类常用api <转>

    该工具类是用于操作Java.lang.String类的. StringUtils类与String类的区别在于:此类是null安全的,即如果输入参数String为null,则不会抛出NullPointe ...

随机推荐

  1. ASP.NET MVC使用Bootstrap系列(3)——使用Bootstrap 组件

    阅读目录 Bootstrap 导航条 列表组 徽章 媒体对象 页头 路径导航 分页 输入框组 按钮式下拉菜单 警告框 进度条 小结 Bootstrap为我们提供了十几种的可复用组件,包括字体图标.下拉 ...

  2. iOS钥匙串

    钥匙串 苹果的"生态圈",钥匙串访问,使用 AES 256 加密算法,能够保证用户密码的安全 钥匙串访问SDK,是苹果在 iOS 7.0.3 版本以后公布的 钥匙串访问的接口是纯 ...

  3. 【转】Flume日志收集

    from:http://www.cnblogs.com/oubo/archive/2012/05/25/2517751.html Flume日志收集   一.Flume介绍 Flume是一个分布式.可 ...

  4. 要让div中的float不会自动显示到下一行来?

    使用 高度 + hidden: 要尝试 恰当的 高度, 设置合适的 div的 height: ... 要让 float的 "最直接的" "亲生的 " " ...

  5. recording just for inquiry in the future

    auditd审计 相关命令有: auditd, auditctl, ausearch, aureport 相关文件: /etc/audit/auditd.conf, /etc/audit/audit. ...

  6. objective-c与c++的差异

    oc的编译指令为 clang -fobjc-arc -framework Foundation test.m -o test oc中,1表示YES,0表示NO.并不是非0值都是YES,这是因为BOOL ...

  7. NetBeans使用习惯:升级与保存配置

    如何升级:点击 netbeans 的升级更新 ,即可升级版本:不推荐官网下载进行安装,否则会出现,以前的旧版本8.0的目录和8.0.1目录,虽然它会自动检测到以前版本的配置,提示导入... 如何备份: ...

  8. R语言练习(一)

    b = seq(from=0, to=1, by=0.001) #一次方 l1 = function(b){ b^1 } y1 = l1(b) #二次方 l2 = function(b){ b^2 } ...

  9. QT共享库的创建与调用(初级)(附:UI界面不能被改变的其中一个原因)

    背景: 最近在做的一个项目其中一部分既是实现PC与下位机的USB通信.windows平台下已经完成,现需移植到linux平台下. 在linux系统中,通过一段时间的工作,设备已被配置成hid类(后续再 ...

  10. r8 - ASC 41(俄罗斯多校)

    1 今天干的俄罗斯的一场多校,被虐哭啊,就做出两题. 2 3 4 5 6 7 Gym 100496D Data Mining 8 题目讲得是给你一串数字,然后给你i,p,表示从第i开始,对这串数离散话 ...