自动创建并连接VPN

来源:互联网 发布:淘宝助理一键适配 编辑:程序博客网 时间:2024/05/29 02:22
一礼拜前写了个自动创建、自动连接VPN的程序,后来发给别人用提示错误:632
看了MSDN的说明意思是结构体大小错误,操作系统是Windows 7,使用Visual Studio 2010编译。在XP操作系统下编译出来的程序仍然这样,不能在XP系统下使用。

创建VPN连接时,RasSetEntryProperties 错误,返回值 632
如果用这个函数取得大小 RasGetEntryProperties(NULL, NULL, NULL, &rasEntrySize, NULL, NULL);
rasEntry.dwSize = rasEntrySize;
那就不会出现632提示,VPN连接成功创建。

但到 RasDial函数时又会出现这个错误,返回值 632


解决办法:

将targetver.h文件改成如下:
#include <WinSDKVer.h>
#define _WIN32_WINNT 0x0501 //把Windows平台定义为XP。如果不定义,拨号的函数在XP下面无法正常工作

#include <SDKDDKVer.h>

拨号函数即可在XP下面正常工作了。


#include "StdAfx.h"#include "resource.h"#include "RasDial.h"    bool CreateVPN(const LPCTSTR pszEntryName, const LPCTSTR pszServerName,     const LPCTSTR pszUserName, const LPCTSTR pszPassWord){    RASENTRY rasEntry;    DWORD rasEntrySize, dwResult;     ZeroMemory(&rasEntry, sizeof(rasEntry));    rasEntrySize = sizeof(rasEntry);    rasEntry.dwCountryCode = 86;    rasEntry.dwCountryID = 86;    rasEntry.dwDialExtraPercent = 75;    rasEntry.dwDialExtraSampleSeconds = 120;    rasEntry.dwDialMode = RASEDM_DialAll;    rasEntry.dwType = RASET_Vpn;    rasEntry.dwRedialCount = 30;    rasEntry.dwRedialPause = 60;    rasEntry.dwSize = sizeof(rasEntry);    rasEntry.dwfOptions = RASEO_SwCompression | RASEO_RequireEncryptedPw | RASEO_RequireDataEncryption |     RASEO_PreviewUserPw ;    rasEntry.dwFramingProtocol = RASFP_Ppp;    rasEntry.dwVpnStrategy = VS_PptpOnly;    rasEntry.dwfNetProtocols = RASNP_Ip;    rasEntry.dwEncryptionType = ET_Optional;    //可选加密    rasEntry.dwHangUpExtraPercent = 10;    rasEntry.dwHangUpExtraSampleSeconds = 120;    lstrcpy(rasEntry.szLocalPhoneNumber, pszServerName);    lstrcpy(rasEntry.szDeviceType, RASDT_Vpn);    lstrcpy(rasEntry.szDeviceName, _T("VPN"));     dwResult = RasSetEntryProperties(NULL, pszEntryName, &rasEntry, sizeof(rasEntry), NULL, 0);    if (dwResult != 0)    {        AfxMessageBox(_T("error : SetEntryProperties"));        return false;    }     RASDIALPARAMS rdParams;    ZeroMemory(&rdParams, sizeof(RASDIALPARAMS));    rdParams.dwSize = sizeof(RASDIALPARAMS);    lstrcpy(rdParams.szEntryName, pszEntryName);    lstrcpy(rdParams.szUserName, pszUserName);    lstrcpy(rdParams.szPassword, pszPassWord);    DWORD dwRet = RasSetEntryDialParams(NULL, &rdParams, FALSE);         if(dwRet == 0)        return true;    else        return false; } bool ConnectVPN(){    RASDIALPARAMS    RasDialParams;    //HRASCONN        hRasConn;    DWORD            Ret;          if (!CreateVPN(c_VPNDescription, c_VPNServer, c_VPNUserName, c_VPNPassword))    {        AfxMessageBox(_T("VPN创建失败"));        return false;    }         ZeroMemory(&RasDialParams, sizeof(RASDIALPARAMS));    RasDialParams.dwSize = sizeof(RASDIALPARAMS);    lstrcpy(RasDialParams.szEntryName, c_VPNDescription);    lstrcpy(RasDialParams.szPhoneNumber, c_VPNServer);    lstrcpy(RasDialParams.szUserName, c_VPNUserName);    lstrcpy(RasDialParams.szPassword, c_VPNPassword);     hRasConn = NULL;    Ret = RasDial(NULL, NULL, &RasDialParams, 0, &RasDialFunc, &hRasConn);         if (Ret != 0)    {        OutputString("RasDial %s failed with error %d\n", RasDialParams.szPhoneNumber, Ret);        RasDeleteEntry(NULL, RasDialParams.szEntryName);        return false;    }     return true;}    void WINAPI RasDialFunc(UINT unMsg, RASCONNSTATE rasconnstate, DWORD dwError){    char szRasString[256]; // Buffer for storing the error string     if (dwError)  // Error occurred    {        RasGetErrorString((UINT)dwError, (LPWSTR)szRasString, 256);        OutputString("Error: %d - %s\n",dwError, szRasString);        //SetEvent(g_TerminalEvent);        return;    }     // Map each of the states of RasDial() and display on the screen    // the next state that RasDial() is entering    switch (rasconnstate)    {        // Running States        case RASCS_OpenPort:            OutputString ("Opening port...\n");            break;        case RASCS_PortOpened:            OutputString ("Port opened.\n");            break;        case RASCS_ConnectDevice:             OutputString ("Connecting device...\n");            break;        case RASCS_DeviceConnected:             OutputString ("Device connected.\n");            break;        case RASCS_AllDevicesConnected:            OutputString ("All devices connected.\n");            break;        case RASCS_Authenticate:             OutputString ("Authenticating...\n");            break;        case RASCS_AuthNotify:            OutputString ("Authentication notify.\n");            break;        case RASCS_AuthRetry:             OutputString ("Retrying authentication...\n");            break;        case RASCS_AuthCallback:            OutputString ("Authentication callback...\n");            break;        case RASCS_AuthChangePassword:             OutputString ("Change password...\n");            break;        case RASCS_AuthProject:             OutputString ("Projection phase started...\n");            break;        case RASCS_AuthLinkSpeed:             OutputString ("Negotiating speed...\n");            break;        case RASCS_AuthAck:             OutputString ("Authentication acknowledge...\n");            break;        case RASCS_ReAuthenticate:             OutputString ("Retrying Authentication...\n");            break;        case RASCS_Authenticated:             OutputString ("Authentication complete.\n");            break;        case RASCS_PrepareForCallback:             OutputString ("Preparing for callback...\n");            break;        case RASCS_WaitForModemReset:             OutputString ("Waiting for modem reset...\n");            break;        case RASCS_WaitForCallback:            OutputString ("Waiting for callback...\n");            break;        case RASCS_Projected:              OutputString ("Projection completed.\n");            break;    #if (WINVER >= 0x400)         case RASCS_StartAuthentication:            OutputString ("Starting authentication...\n");            break;        case RASCS_CallbackComplete:             OutputString ("Callback complete.\n");            break;        case RASCS_LogonNetwork:            OutputString ("Logon to the network.\n");            break;    #endif         case RASCS_SubEntryConnected:            OutputString ("Subentry connected.\n");            break;        case RASCS_SubEntryDisconnected:            OutputString ("Subentry disconnected.\n");            break;         // The RAS Paused States will not occur because        // we did not use the RASDIALEXTENSIONS structure        // to set the RDEOPT_PausedState option flag.         // The Paused States are:         // RASCS_RetryAuthentication:        // RASCS_CallbackSetByCaller:        // RASCS_PasswordExpired:         // Terminal States        case RASCS_Connected:             OutputString ("Connection completed.\n");            OutputString ("连接成功\n");             StartApp();            //SetEvent(g_TerminalEvent);            break;        case RASCS_Disconnected:             OutputString ("Disconnecting...\n");            //SetEvent(g_TerminalEvent);            break;        default:            OutputString ("Unknown Status = %d\n", rasconnstate);            break;    }    //AfxGetApp()->GetMainWnd()->Invalidate();}   void OutputString( char *lpFmt, ... ){     char buff[1024] = "";    va_list    arglist;    va_start( arglist, lpFmt );    vsnprintf( buff, sizeof buff, lpFmt, arglist );    va_end( arglist );    OutputDebugString((CString)buff);    AfxGetApp()->GetMainWnd()->GetDlgItem(IDC_STATIC)->SetWindowTextW((CString)buff);    AfxGetApp()->GetMainWnd()->RedrawWindow();}


其实如果只想实现重新拨号换IP的话,最简单粗暴的办法就是:

system(rasdial 宽带连接 用户名 密码);

只需要一行代码即可。原理就是直接调用Windows自带的rasdial的命令。


0 0
原创粉丝点击