123456

 

RAS详解

 

1.什么叫RAS?
答:微软的所有Wi n d o w s平台中都有RAS客户机,它允许我们将自己的计算机与另一个地方
的远程计算机(其特色是一个远程访问服务器组件)相连,一般情况下,  RAS客户机利用连
接了电话线的一个调制解调器,通过拨号的方式呼叫远程计算机。因此,有时, RAS客户机
也称作“拨号联网(DUN)客户机”。服务器这方面,必须有一项等候DUN连接的服务,
RAS客户机和服务器之间的连接建立之后,网络协议堆栈(与所用的分帧协议有关)就
通过这个RAS连接,与远程计算机通信,就象通过LAN连接的一样。当然,如今,许多调制
解调器的数据通信速率明显比直接的LAN连接慢。RAS连接通过电话簿条目中可用的选项,经过验证后,RAS便可自
动进入一台机器,登录到一个域。
2.RAS错误打印?
Raserror.h列举了相当多预先定义的错误代码。这个文件中,大家将注意到一个错误说明
字串,这个字串和RAS中所用的各错误代码关联在一起RasGetErrorString
3.平台兼容?
RAS函数所用的有些数据结构中,根据
WINVER定义的值,分别使用或不用额外的数据字段。
所以一定要定义当前的WINVER,不然就失败返回632
直接去targetver.h中看,比如XP:
/ 没有#define WINVER 0x0501 
就直接加上

#ifndef WINVER
#define WINVER 0x0501
#endif 

 

4.具体函数介绍:
(1)

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

 

dwSize:必须设为RASDIALEXTENSIONS结构的长度(按字节算)。
dwfOptions:允许你为使用RasDial扩展特性而设置位标志:如下:
                      RDEOPT_UsePrefixSuffix:令RasDial使用与指定拨号设备关联的前缀和后缀
                      RDEOPT_PausedStates:允许RasDial进入暂停操作状态,从而用户就可以重试登录、改变密码和设置回拨号码
                      RDEOPT_IgnoreModemSpeaker:令RasDial忽略RAS电话簿中的Modem喇叭设置
                      RDEOPT_SetModemSpeaker:如果设置了  RDEOPT_IgnoreModemSpeaker标志,那么利用这个标志,可以打开Modem喇叭
                      RDEOPT_IgnoreSoftwareCompression:令RasDial忽略软件压缩设置
                      RDEOPT_SetSoftwareCompression:在设置了 RDEOPT_IgnoreSoftwareCompression标志的前提下,再用这个标志,便会打开软件压缩
                      RDEOPT_PauseOnScript:供RasDialDlg内部使用。不能设置这个标志
                      RDEOPT_UseCustomScripting:2000/NT不支持
                      RDEOPT_CustomDial:NT不支持
hwndParent:不用,应该设为NULL
reserved:不用,设为0
reserved1:不用,设为0
RasEapInfo:NT不支持

第二个参数:电话簿文件:
电话簿不过是一个RASENTRY结构的集合,这些结构中包含了电话号码、数据速率、用户身份验证信息和其他连接信息,在2000/NT平台上,电话簿的扩展名一般是. PBK的文件中
具体结构参看window网络编程16章吧。

第三个参数:

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;

 

dwSize:必须设为RASDIALPARAMS;结构的长度(按字节算)。
szEntryName:一个字串,允许你标识一个电话簿条目,该条目中包含在RasDial函数的lpszPhonebook参数中列出的电话簿文件内,如为空字串(“”),RasDial就会选择系统上已安装的第一个可用的Modem,

并依据下一个参数szPhoneNumber来拨叫连接
szPhoneNumber:一个字串,代表一个电话号码,这个号码优先于szEntryName字段中指定的电话簿条目内包含的电话号码
szCallbackNumber:允许你指定一个电话号码, RAS服务器可以根据这个号码回拨。如果RAS服务器允许有一个回拨号码,它就会中断原来的连接,利用你指定的回拨号码回拨。这个特性非常不错,因为有了它

服务器就可知道连接的用户来自何处
szUserName:一个字串,标识RAS服务器上的用户进行身份验证时所用的登录名
szPassword:一个字串,标识R A S服务器上的用户进行身份验证时所用的密码
szDomain:可选。允许你指定最初的电话簿子条目拨叫一个RAS多链路连接
dwCallbackId:允许你把一个应用程序定义的值投递到一个R a s D i a l F u n c 2回拨函数中

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

参数不为NULL,就会进入异步模式, 意味着进行连接的同时,函数调用会立即返回。可以对连接进程进行监视
    dwNotifierType:
                   0: lpvNotifier参数使用RasDialFunc函数指针管理连接事件
  1: lpvNotifier参数利用RasDialFunc1函数指针管理连接事件
                  2: lpvNotifier参数利用RasDialFunc2函数指针管理连接事件
 0xFFFFFFF: lpvNotifier参数令RasDial在连接事件期间发送一个窗口消息
分别为以下三个函数:

void CALLBACK RasDialFunc(
  [in]                 UINT unMsg,
  [in]                 RASCONNSTATE rasconnstate,
  [in]                 DWORD dwError
);

 unMsg:只可能为WM_RASDIALEVENT
 rasconnstate:接收RasDial函数即将发生的连接活动:运行、暂停和中断
 dwError: RAS错误代码

void CALLBACK RasDialFunc1(
  [in]                 HRASCONN hrasconn,
  [in]                 UINT unMsg,
  [in]                 RASCONNSTATE rascs,
  [in]                 DWORD dwError,
  [in]                 DWORD dwExtendedError
);

 

hrasconn:指向连接的句柄
dwExtendedError:扩展错误信息

DWORD CALLBACK RasDialFunc2(
  [in]                 DWORD dwCallbackId,
  [in]                 DWORD dwSubEntry,
  [in]                 HRASCONN hrasconn,
  [in]                 UINT unMsg,
  [in]                 RASCONNSTATE rascs,
  [in]                 DWORD dwError,
  [in]                 DWORD dwExtendedError
);

dwCallbackId:包含了一个应用程序定义的值,这个值最初是设在RASDIALPARAMS;结构的dwCallbackId字段中的
dwSubEntry:接收子条目电话簿索引,这个索引会再次回调RasDialFunc2函数

(2)事件通知函数

DWORD RasConnectionNotification(
  __in          HRASCONN hrasconn,
  __in          HANDLE hEvent,
  __in          DWORD dwFlags
);

hrasconn:RasDial返回的一个连接句柄,如为INVALID_HANDLE_VALUE(要强制转换成HRASCONN)
hEvent:CreateEvent创建
dwFlags:
        RASCN_Connection:当hrasconn为INVALID_HANDLE_VALUE,任何一次RAS连接都会触发这一事件
        RASCN_Disconnection:当hrasconn为INVALID_HANDLE_VALUE,任何一次RAS中止都会触发这一事件
        RASCN_BandwidthAdded:在一个多链路连接上,子条目连接会触发这一事件
        RASCN_BandwidthRemoved:在多链路连接上,子条目取消连接时,会触发这一事件

(3)

DWORD RasHangUp(
  __in          HRASCONN hrasconn
);

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

(4)

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#之类的字符串

(5)获得所有具有R A S能力的设备名及类型

DWORD RasEnumDevices(
  __in          LPRASDEVINFO lpRasDevInfo,
  __in_out      LPDWORD lpcb,
  __out         LPDWORD lpcDevices
);

 

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

DWORD RasValidateEntryName(
  __in          LPCTSTR lpszPhonebook,
  __in          LPCTSTR lpszEntry
);

lpszPhonebook:用于识别到一个电话簿文件的路径。设为NULL,表示使用当前默认电话簿文件
lpszEntry:电话簿中没有这个名字,但该名字格式无误时,便返回ERROR_SUCCESS。若名字格式有错,这个函数就会失败,返回ERROR_INVALIDNAME;
如果电话簿中有这个名字,就会返回ERROR_ALREAD_YEXIST

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

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

 

 

 

 

 

 

 

 

 

 


 

posted on 2011-12-07 20:30  hgy413  阅读(1043)  评论(0编辑  收藏  举报

导航