在Win32 API 函 数 中 有 一 组 用于实现远程连接服务RAS 的函数,利用这些 函数通 过 编 程 可 以 实 现 建 立 和 Internet 的拨 号 连 接,并可获得Internet 分配给主机的动态 IP地址。
一、 建 立 拨 号 连 接API
----建 立 拨 号 连 接 是 利 用 函 数RasDial() 实 现 的, 该 函 数 调 用 后 立 即 返 回, 若 成 功
返 回0 值, 否 则 返 回 非0 值。 在 拨 号 连 接 过 程 中, 回 调 函 数 接 收 连 接 的 状 态 信 息
及 发 生 的 错 误 代 码。 回 调 函 数 的 原 形 如 下:
VOID WINAPI RasDialFunc(UINT unMsg,RASCONNSTATE rasconnstate,DWORD dwError)
----由 于 在 调 用RasDialFunc 函 数 时, 连 接 操 作 被 挂 起, 因 此, 应 用 程 序 应 尽 快 处 理
发 生 的 事 件 并 返 回。 可 以 在 RasDialFunc 函 数 中 调 用PostMessage 函 数, 将 事 件 通 知 消
息 送 给 窗 口 函 数 来 处 理。
----RASDIALPARAMS 结 构 定 义 如 下:
----DWORD dwSize 结 构 变 量 的 大 小。
----TCHAR szEntryName[RAS_MaxEntryName +1] 拨 号 网 络 中 建 立 的 连 接 名。
----TCHAR szPhoneNumber[RAS_MaxPhoneNumber +1] 电 话 号 码, 若 采 用 szEntryName 中 定 义 的 号
码, 置 为NULL 值。
----TCHAR szCallbackNumber[RAS_MaxCallbackNumber +1] 回 拨 号 码, 不 用 时 置 为NULL。
----TCHAR szUserName[UNLEN +1] 用 户 标 识。
----TCHAR szPassword[PWLEN +1] 用 户 口 令。
----TCHAR szDomain[DNLEN +1] 用 户 权 限 验 证 域, 若 为NULL 采 用RAS 服 务 器 所 在 的 域 进 行
验 证, 若 为‘ *’ 采 用 szEntryName 中 定 义 的 域 进 行 验 证。
----RASCONNSTATE 枚 举 型 结 构, 包 含 拨 号 连 接 过 程 中 各 种 可 能 状 态 的 定 义。
----函 数RasHangUp() 用 来 终 止 拨 号 连 接, 因 程 序 需 要 一 定 的 时 间 来 结 束 连 接, 应 用
程 序 调 用 该 函 数 后 不 能 马 上 退 出, 需 等 待3 秒 后 才 能 退 出。
二、 获 取 动 态IP 地 址API
----在VC 中 是 通 过 调 用 函 数RasGetProjectionInfo() 来 获 取IP 地 址 的。
----函 数 调 用 成 功 时 返 回0 值, 此 时 在 RASPPPIP 结 构 变 量 中 的szIpAddress 就 是 动 态IP 地
址。
三、 程 序 实 现
----程 序 是 在Win 95 环 境 下, 用VC + +5.0 编 写, 并 编 译 运 行 通 过。 完 整 的 源 程 序 清
单 如 下:
// - - - - - - - - - - - - - - - -
//file name ras.c
// - - - - - - - - - - - - - - - -
#include < windows.h >
#include < winuser.h >
#include < string.h >
#include < ras.h >
#include < raserror.h >
#include “resource.h"
// 函 数 原 形
LRESULT CALLBACK DialogProc(HWND hDlg,
UINT message, WPARAM wParam, LPARAM lParam);
void ShowMsg(HWND hwnd,char * msg);
LRESULT MsgDialDlgEvent(HWND hdlg,
UINT uMessage, WPARAM wparam, LPARAM lparam);
VOID WINAPI RasDialFunc
( UINT unMsg, RASCONNSTATE rasconnstate,
DWORD dwError );
BOOL StartCon( HWND hWnd,char
* szUser,char * szPassword );
UINT GetRasConnState( RASCONNSTATE rasconn );
// 全 局 变 量
HRASCONN hCon; //RAS 连 接 句 柄
HWND hWin;
HINSTANCE hInst;
// - - - - - - - - - - - - - - - - -
//windows 入 口 函 数
// - - - - - - - - - - - - - - - - -
int PASCAL WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,LPSTR lpszCmdLine,
int nCmdShow )
{
hInst=hInstance;
if ( DialogBox(hInstance,“RAS_DLG",NULL,
(DLGPROC)DialogProc) == -1 )
MessageBox(NULL,“ 建 立 对 话 框 失 败 !",
“TITLE",MB_OK);
return 0;
}
// - - - - - - - - - - - - - - - - -
// 对 话 框 窗 口 函 数
// - - - - - - - - - - - - - - - - -
LRESULT CALLBACK DialogProc(HWND hDlg,
UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
hWin=hDlg;
hCon=NULL;
return (TRUE);
case WM_RASDIALEVENT:
MsgDialDlgEvent(hDlg,message,wParam,lParam);
return (TRUE);
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
StartCon( hDlg,“ljx@public.smptt.fj.cn",
“abbcd");
break;
case IDCANCEL:
if ( hCon != NULL )
{
RasHangUp(hCon);
Sleep(3000);
}
EndDialog(hDlg,TRUE);
break;
}
break;
}
return (FALSE);
}
// * * * * * * * * * * * * * * * *
// 在 列 表 框 中 显 示 信 息
// * * * * * * * * * * * * * * * *
void ShowMsg(HWND hwnd,char * msg)
{
int lnum;
SendDlgItemMessage(hwnd,IDC_MSG,
LB_ADD STRING,0,(long)msg );
lnum=SendDlgItemMessage(hwnd,IDC_MSG,
LB_GETCOUNT, 0,0);
SendDlgItemMessage(hwnd,IDC_MSG,LB_SET
CURSEL,lnum -1,0);
return;
}
// - - - - - - - - - - - - - - - - -
// BOOL StartCon( HWND hWnd )
// 建 立 拨 号 连 接, 成 功 TRUE else FALSE
// szUser 和szPassword 分 别 为
Internet 的 用 户 名 和 口 令
// - - - - - - - - - - - - - - - - -
BOOL StartCon
( HWND hWnd,char * szUser,char * szPassword )
{
RASDIALPARAMS rdParams;
DWORD dwRet;
char szBuf[300];
// 初 始 化 变 量
rdParams.dwSize = sizeof(RASDIALPARAMS);
lstrcpy(rdParams.szEntryName, “internet");
rdParams.szPhoneNumber[0] = ‘/0';
rdParams.szCallbackNumber[0] = ‘ *';
rdParams.szCallbackNumber[0] = ‘/0';
strcpy(rdParams.szUserName,szUser);
strcpy(rdParams.szPassword,szPassword);
rdParams.szDomain[0] = ‘/0';
hCon=NULL;
// 以 下 开 始 异 步 拨 叫 网 络
dwRet = RasDial( NULL, NULL, &rdParams, 0L,
(RASDIALFUNC) RasDialFunc, &hCon );
if ( dwRet )
{
if ( RasGetErrorString( (UINT)dwRet,
(LPSTR)szBuf, 256 ) != 0 )
wsprintf( (LPSTR)szBuf,
“Undefined RAS Dial Error ( %ld).", dwRet );
ShowMsg(hWnd,szBuf);
return FALSE;
}
return TRUE;
}
// - - - - - - - - - - - - - - -
// RasDial 异 步 处 理 的 回 调 函 数
// unMsg - 发 生 的RAS 事 件
// rasconnstate - 连 接 进 入 的 状 态
// dwError - 发 生 的 错 误 代 码
// - - - - - - - - - - - - - - -
VOID WINAPI RasDialFunc
( UINT unMsg, RASCONNSTATE rasconnstate,
DWORD dwError )
{
PostMessage(hWin,
WM_RASDIALEVENT,
(WPARAM) rasconnstate,
(LPARAM) dwError );
}
// - - - - - - - - - - - - - - - -
// RasDial() 返 回 的 事 件 信 息 由 该 函 数 处 理
// - - - - - - - - - - - - - - - -
LRESULT MsgDialDlgEvent(HWND hdlg, UINT uMessage,
WPARAM wparam, LPARAM lparam)
{
RASPPPIP rip;
DWORD ll,ret;
int num;
char szMessage[256];
LoadString(hInst,GetRasConnState
( (RASCONNSTATE) wparam ), szMessage, 64 );
ShowMsg(hdlg,szMessage);
if ( lparam ) // 发 生 错 误
{
if ( RasGetErrorString
( (UINT)lparam, szMessage, 256 ) != 0 )
wsprintf( (LPSTR)szMessage,
“ 出 错 Undefined RAS Dial Error." );
ShowMsg(hdlg,szMessage);
return TRUE;
}
else if ( RASCS_DONE & wparam ) // 连 接 成 功
{
// 取 动 态 分 配 的IP 地 址
ShowMsg(hdlg,“ 连 接 成 功");
rip.dwSize=sizeof(RASPPPIP);
if((ret=RasGetProjectionInfo(hCon,RASP_PppIp,
(LPVOID) &rip,(LPDWORD) &ll )) != 0 )
{
ShowMsg(hdlg,“ 取IP 地 址 失 败");
}
else
ShowMsg(hdlg,rip.szIpAddress);
}
return TRUE;
}
// - - - - - - - - - - - - - - - -
// 根 据 连 接 状 态
取 字 符 串 资 源 中 对 应 的 标 号
// - - - - - - - - - - - - - - - -
UINT GetRasConnState( RASCONNSTATE rasconn )
{
switch( rasconn )
{
case RASCS_OpenPort:
return IDS_OPENPORT;
case RASCS_PortOpened:
return IDS_PORTOPENED;
case RASCS_ConnectDevice:
return IDS_CONNECTDEVICE;
case RASCS_DeviceConnected:
return IDS_DEVICECONNECTED;
case RASCS_AllDevicesConnected:
return IDS_ALLDEVICESCONNECTED;
case RASCS_Authenticate:
return IDS_AUTHENTICATE;
case RASCS_AuthNotify:
return IDS_AUTHNOTIFY;
case RASCS_AuthRetry:
return IDS_AUTHRETRY;
case RASCS_AuthCallback:
return IDS_AUTHCALLBACK;
case RASCS_AuthChangePassword:
return IDS_AUTHCHANGEPASSWORD;
case RASCS_AuthProject:
return IDS_AUTHPROJECT;
case RASCS_AuthLinkSpeed:
return IDS_AUTHLINKSPEED;
case RASCS_AuthAck:
return IDS_AUTHACK;
case RASCS_ReAuthenticate:
return IDS_REAUTHENTICATE;
case RASCS_Authenticated:
return IDS_AUTHENTICATED;
case RASCS_PrepareForCallback:
return IDS_PREPAREFORCALLBACK;
case RASCS_WaitForModemReset:
return IDS_WAITFORMODEMRESET;
case RASCS_WaitForCallback:
return IDS_WAITFORCALLBACK;
case RASCS_Interactive:
return IDS_INTERACTIVE;
case RASCS_RetryAuthentication:
return IDS_RETRYAUTHENTICATION;
case RASCS_CallbackSetByCaller:
return IDS_CALLBACKSETBYCALLER;
case RASCS_PasswordExpired:
return IDS_PASSWORDEXPIRED;
case RASCS_Connected:
return IDS_CONNECTED;
case RASCS_Disconnected:
return IDS_DISCONNECTED;
default:
return IDS_UNDEFINED_ERROR;
}
}
一、 建 立 拨 号 连 接API
----建 立 拨 号 连 接 是 利 用 函 数RasDial() 实 现 的, 该 函 数 调 用 后 立 即 返 回, 若 成 功
返 回0 值, 否 则 返 回 非0 值。 在 拨 号 连 接 过 程 中, 回 调 函 数 接 收 连 接 的 状 态 信 息
及 发 生 的 错 误 代 码。 回 调 函 数 的 原 形 如 下:
VOID WINAPI RasDialFunc(UINT unMsg,RASCONNSTATE rasconnstate,DWORD dwError)
----由 于 在 调 用RasDialFunc 函 数 时, 连 接 操 作 被 挂 起, 因 此, 应 用 程 序 应 尽 快 处 理
发 生 的 事 件 并 返 回。 可 以 在 RasDialFunc 函 数 中 调 用PostMessage 函 数, 将 事 件 通 知 消
息 送 给 窗 口 函 数 来 处 理。
----RASDIALPARAMS 结 构 定 义 如 下:
----DWORD dwSize 结 构 变 量 的 大 小。
----TCHAR szEntryName[RAS_MaxEntryName +1] 拨 号 网 络 中 建 立 的 连 接 名。
----TCHAR szPhoneNumber[RAS_MaxPhoneNumber +1] 电 话 号 码, 若 采 用 szEntryName 中 定 义 的 号
码, 置 为NULL 值。
----TCHAR szCallbackNumber[RAS_MaxCallbackNumber +1] 回 拨 号 码, 不 用 时 置 为NULL。
----TCHAR szUserName[UNLEN +1] 用 户 标 识。
----TCHAR szPassword[PWLEN +1] 用 户 口 令。
----TCHAR szDomain[DNLEN +1] 用 户 权 限 验 证 域, 若 为NULL 采 用RAS 服 务 器 所 在 的 域 进 行
验 证, 若 为‘ *’ 采 用 szEntryName 中 定 义 的 域 进 行 验 证。
----RASCONNSTATE 枚 举 型 结 构, 包 含 拨 号 连 接 过 程 中 各 种 可 能 状 态 的 定 义。
----函 数RasHangUp() 用 来 终 止 拨 号 连 接, 因 程 序 需 要 一 定 的 时 间 来 结 束 连 接, 应 用
程 序 调 用 该 函 数 后 不 能 马 上 退 出, 需 等 待3 秒 后 才 能 退 出。
二、 获 取 动 态IP 地 址API
----在VC 中 是 通 过 调 用 函 数RasGetProjectionInfo() 来 获 取IP 地 址 的。
----函 数 调 用 成 功 时 返 回0 值, 此 时 在 RASPPPIP 结 构 变 量 中 的szIpAddress 就 是 动 态IP 地
址。
三、 程 序 实 现
----程 序 是 在Win 95 环 境 下, 用VC + +5.0 编 写, 并 编 译 运 行 通 过。 完 整 的 源 程 序 清
单 如 下:
// - - - - - - - - - - - - - - - -
//file name ras.c
// - - - - - - - - - - - - - - - -
#include < windows.h >
#include < winuser.h >
#include < string.h >
#include < ras.h >
#include < raserror.h >
#include “resource.h"
// 函 数 原 形
LRESULT CALLBACK DialogProc(HWND hDlg,
UINT message, WPARAM wParam, LPARAM lParam);
void ShowMsg(HWND hwnd,char * msg);
LRESULT MsgDialDlgEvent(HWND hdlg,
UINT uMessage, WPARAM wparam, LPARAM lparam);
VOID WINAPI RasDialFunc
( UINT unMsg, RASCONNSTATE rasconnstate,
DWORD dwError );
BOOL StartCon( HWND hWnd,char
* szUser,char * szPassword );
UINT GetRasConnState( RASCONNSTATE rasconn );
// 全 局 变 量
HRASCONN hCon; //RAS 连 接 句 柄
HWND hWin;
HINSTANCE hInst;
// - - - - - - - - - - - - - - - - -
//windows 入 口 函 数
// - - - - - - - - - - - - - - - - -
int PASCAL WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,LPSTR lpszCmdLine,
int nCmdShow )
{
hInst=hInstance;
if ( DialogBox(hInstance,“RAS_DLG",NULL,
(DLGPROC)DialogProc) == -1 )
MessageBox(NULL,“ 建 立 对 话 框 失 败 !",
“TITLE",MB_OK);
return 0;
}
// - - - - - - - - - - - - - - - - -
// 对 话 框 窗 口 函 数
// - - - - - - - - - - - - - - - - -
LRESULT CALLBACK DialogProc(HWND hDlg,
UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
hWin=hDlg;
hCon=NULL;
return (TRUE);
case WM_RASDIALEVENT:
MsgDialDlgEvent(hDlg,message,wParam,lParam);
return (TRUE);
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
StartCon( hDlg,“ljx@public.smptt.fj.cn",
“abbcd");
break;
case IDCANCEL:
if ( hCon != NULL )
{
RasHangUp(hCon);
Sleep(3000);
}
EndDialog(hDlg,TRUE);
break;
}
break;
}
return (FALSE);
}
// * * * * * * * * * * * * * * * *
// 在 列 表 框 中 显 示 信 息
// * * * * * * * * * * * * * * * *
void ShowMsg(HWND hwnd,char * msg)
{
int lnum;
SendDlgItemMessage(hwnd,IDC_MSG,
LB_ADD STRING,0,(long)msg );
lnum=SendDlgItemMessage(hwnd,IDC_MSG,
LB_GETCOUNT, 0,0);
SendDlgItemMessage(hwnd,IDC_MSG,LB_SET
CURSEL,lnum -1,0);
return;
}
// - - - - - - - - - - - - - - - - -
// BOOL StartCon( HWND hWnd )
// 建 立 拨 号 连 接, 成 功 TRUE else FALSE
// szUser 和szPassword 分 别 为
Internet 的 用 户 名 和 口 令
// - - - - - - - - - - - - - - - - -
BOOL StartCon
( HWND hWnd,char * szUser,char * szPassword )
{
RASDIALPARAMS rdParams;
DWORD dwRet;
char szBuf[300];
// 初 始 化 变 量
rdParams.dwSize = sizeof(RASDIALPARAMS);
lstrcpy(rdParams.szEntryName, “internet");
rdParams.szPhoneNumber[0] = ‘/0';
rdParams.szCallbackNumber[0] = ‘ *';
rdParams.szCallbackNumber[0] = ‘/0';
strcpy(rdParams.szUserName,szUser);
strcpy(rdParams.szPassword,szPassword);
rdParams.szDomain[0] = ‘/0';
hCon=NULL;
// 以 下 开 始 异 步 拨 叫 网 络
dwRet = RasDial( NULL, NULL, &rdParams, 0L,
(RASDIALFUNC) RasDialFunc, &hCon );
if ( dwRet )
{
if ( RasGetErrorString( (UINT)dwRet,
(LPSTR)szBuf, 256 ) != 0 )
wsprintf( (LPSTR)szBuf,
“Undefined RAS Dial Error ( %ld).", dwRet );
ShowMsg(hWnd,szBuf);
return FALSE;
}
return TRUE;
}
// - - - - - - - - - - - - - - -
// RasDial 异 步 处 理 的 回 调 函 数
// unMsg - 发 生 的RAS 事 件
// rasconnstate - 连 接 进 入 的 状 态
// dwError - 发 生 的 错 误 代 码
// - - - - - - - - - - - - - - -
VOID WINAPI RasDialFunc
( UINT unMsg, RASCONNSTATE rasconnstate,
DWORD dwError )
{
PostMessage(hWin,
WM_RASDIALEVENT,
(WPARAM) rasconnstate,
(LPARAM) dwError );
}
// - - - - - - - - - - - - - - - -
// RasDial() 返 回 的 事 件 信 息 由 该 函 数 处 理
// - - - - - - - - - - - - - - - -
LRESULT MsgDialDlgEvent(HWND hdlg, UINT uMessage,
WPARAM wparam, LPARAM lparam)
{
RASPPPIP rip;
DWORD ll,ret;
int num;
char szMessage[256];
LoadString(hInst,GetRasConnState
( (RASCONNSTATE) wparam ), szMessage, 64 );
ShowMsg(hdlg,szMessage);
if ( lparam ) // 发 生 错 误
{
if ( RasGetErrorString
( (UINT)lparam, szMessage, 256 ) != 0 )
wsprintf( (LPSTR)szMessage,
“ 出 错 Undefined RAS Dial Error." );
ShowMsg(hdlg,szMessage);
return TRUE;
}
else if ( RASCS_DONE & wparam ) // 连 接 成 功
{
// 取 动 态 分 配 的IP 地 址
ShowMsg(hdlg,“ 连 接 成 功");
rip.dwSize=sizeof(RASPPPIP);
if((ret=RasGetProjectionInfo(hCon,RASP_PppIp,
(LPVOID) &rip,(LPDWORD) &ll )) != 0 )
{
ShowMsg(hdlg,“ 取IP 地 址 失 败");
}
else
ShowMsg(hdlg,rip.szIpAddress);
}
return TRUE;
}
// - - - - - - - - - - - - - - - -
// 根 据 连 接 状 态
取 字 符 串 资 源 中 对 应 的 标 号
// - - - - - - - - - - - - - - - -
UINT GetRasConnState( RASCONNSTATE rasconn )
{
switch( rasconn )
{
case RASCS_OpenPort:
return IDS_OPENPORT;
case RASCS_PortOpened:
return IDS_PORTOPENED;
case RASCS_ConnectDevice:
return IDS_CONNECTDEVICE;
case RASCS_DeviceConnected:
return IDS_DEVICECONNECTED;
case RASCS_AllDevicesConnected:
return IDS_ALLDEVICESCONNECTED;
case RASCS_Authenticate:
return IDS_AUTHENTICATE;
case RASCS_AuthNotify:
return IDS_AUTHNOTIFY;
case RASCS_AuthRetry:
return IDS_AUTHRETRY;
case RASCS_AuthCallback:
return IDS_AUTHCALLBACK;
case RASCS_AuthChangePassword:
return IDS_AUTHCHANGEPASSWORD;
case RASCS_AuthProject:
return IDS_AUTHPROJECT;
case RASCS_AuthLinkSpeed:
return IDS_AUTHLINKSPEED;
case RASCS_AuthAck:
return IDS_AUTHACK;
case RASCS_ReAuthenticate:
return IDS_REAUTHENTICATE;
case RASCS_Authenticated:
return IDS_AUTHENTICATED;
case RASCS_PrepareForCallback:
return IDS_PREPAREFORCALLBACK;
case RASCS_WaitForModemReset:
return IDS_WAITFORMODEMRESET;
case RASCS_WaitForCallback:
return IDS_WAITFORCALLBACK;
case RASCS_Interactive:
return IDS_INTERACTIVE;
case RASCS_RetryAuthentication:
return IDS_RETRYAUTHENTICATION;
case RASCS_CallbackSetByCaller:
return IDS_CALLBACKSETBYCALLER;
case RASCS_PasswordExpired:
return IDS_PASSWORDEXPIRED;
case RASCS_Connected:
return IDS_CONNECTED;
case RASCS_Disconnected:
return IDS_DISCONNECTED;
default:
return IDS_UNDEFINED_ERROR;
}
}