unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;type
  GUID = record //申明调用RAS(创建VPN连接用)函数所需结构体
    Data1: integer;
    Data2: Shortint;
    Data3: Shortint;
    Data4: array[0..6] of byte;
  end;
type
  RASIPADDR = record //申明调用RAS(创建VPN连接用)函数所需结构体
    a: byte;
    b: byte;
    c: byte;
    d: byte;
  end;
type
  RASENTRY = record //申明调用RAS(创建VPN连接用)函数所需结构体
    dwSize: integer;
    dwfOptions: integer;
    dwCountryID: integer;
    dwCountryCode: integer;
    szAreaCode: array[0..9] of byte;
    szLocalPhoneNumber: array[0..127] of byte;
    dwAlternateOffset: integer;
    ipaddr: RASIPADDR;
    ipaddrDns: RASIPADDR;
    ipaddrDnsAlt: RASIPADDR;
    ipaddrWins: RASIPADDR;
    ipaddrWinsAlt: RASIPADDR;
    dwFrameSize: integer;
    dwfNetProtocols: integer;
    dwFramingProtocol: integer;
    szScript: array[0..258] of char;
    szAutodialDll: array[0..258] of char;
    szAutodialFunc: array[0..258] of char;
    szDeviceType: array[0..15] of char;
    szDeviceName: array[0..127] of char;
    szX25PadType: array[0..31] of char;
    szX25Address: array[0..199] of char;
    szX25Facilities: array[0..199] of char;
    szX25UserData: array[0..199] of char;
    dwChannels: integer;
    dwReserved1: integer;
    dwReserved2: integer;
    dwSubEntries: integer;
    dwDialMode: integer;
    dwDialExtraPercent: integer;
    dwDialExtraSampleSeconds: integer;
    dwHangUpExtraPercent: integer;
    dwHangUpExtraSampleSeconds: integer;
    dwIdleDisconnectSeconds: integer;
    dwType: integer;
    dwEncryptionType: integer;
    dwCustomAuthKey: integer;
    guidId: GUID;
    szCustomDialDll: array[0..258] of char;
    dwVpnStrategy: integer;
    dwfOptions2: integer;
    dwfOptions3: integer;
    szDnsSuffix: array[0..254] of char;
    dwTcpWindowSize: integer;
    szPrerequisitePbk: array[0..258] of char;
    szPrerequisiteEntry: array[0..255] of char;
    dwRedialCount: integer;
    dwRedialPause: integer;
  end;  TRasCredentialsA = record
    dwSize,
      dwMask: Longint;
    szUserName: array[0..255] of AnsiChar;
    zPassword: array[0..255] of AnsiChar;
    szDomain: array[0..14] of AnsiChar;
  end;
implementation{$R *.dfm}function RtlMoveMemory(Destination, Source: Pointer; Length: integer): integer; stdcall; external 'kernel32.dll'//function RasSetEntryPropertiesA(lpszPhonebook, lpszEntry: string; lpRasEntry: RASENTRY; dwEntryInfoSize, lpbDeviceInfo, dwDeviceInfoSize: integer): Longint; stdcall; external 'Rasapi32.dll'function RasSetEntryPropertiesA(lpszPhonebook, szEntry: PAnsiChar; lpbEntry: Pointer;  dwEntrySize: Longint; lpbDeviceInfo: Pointer; dwDeviceInfoSize: Longint): Longint; stdcall; external 'Rasapi32.dll';
//function RasSetCredentialsA(lpszPhonebook, lpszEntry: PAnsiChar; lpCredentials: Pointer; fClearCredentials: integer): Longint; stdcall; external 'Rasapi32.dll';
function RasSetCredentialsA(lpszPhoneBook,lpszEntry: PAnsiChar;var lpCredentials: TRasCredentialsA;fRemovePassword: LongBool): Longint; stdcall; external 'Rasapi32.dll';function Create_VPN_Connection(sEntryName, sServer, sUsername, sPassword: string): Boolean;
var
  sDeviceName, sDeviceType: string;
  re: RASENTRY;
  rc: TRasCredentialsA;
begin
  result := false;
  FillChar(rc.szUserName, Length(rc.szUserName), #0);
  FillChar(rc.zPassword, Length(rc.zPassword), #0);
  FillChar(re.szScript, Length(re.szScript), #0);
  FillChar(re.szAutodialDll, Length(re.szAutodialDll), #0);
  FillChar(re.szAreaCode, Length(re.szAreaCode), #0);
  FillChar(re.szLocalPhoneNumber, Length(re.szLocalPhoneNumber), #0);
  FillChar(re.szAutodialFunc, Length(re.szAutodialFunc), #0);
  FillChar(re.szAutodialDll, Length(re.szAutodialDll), #0);
  FillChar(re.szDeviceType, Length(re.szDeviceType), #0);
  FillChar(re.szDeviceName, Length(re.szDeviceName), #0);
  FillChar(re.szX25PadType, Length(re.szX25PadType), #0);
  FillChar(re.szX25Address, Length(re.szX25Address), #0);
  FillChar(re.szX25Facilities, Length(re.szX25Facilities), #0);
  FillChar(re.szX25UserData, Length(re.szX25UserData), #0);
  FillChar(re.szCustomDialDll, Length(re.szCustomDialDll), #0);
  FillChar(re.szDnsSuffix, Length(re.szDnsSuffix), #0);
  FillChar(re.szPrerequisitePbk, Length(re.szPrerequisitePbk), #0);
  FillChar(re.szPrerequisiteEntry, Length(re.szPrerequisiteEntry), #0);
  sDeviceName := 'WAN 微型端口 (L2TP)';
  sDeviceType := 'vpn';
  re.dwSize := sizeof(re);
  re.dwCountryCode := 86;
  re.dwCountryID := 86;
  re.dwDialExtraPercent := 75;
  re.dwDialExtraSampleSeconds := 120;
  re.dwDialMode := 1;
  re.dwEncryptionType := 3;
  re.dwfNetProtocols := 4;
  re.dwfOptions := 1024262928;
  re.dwfOptions2 := 367;
  re.dwFramingProtocol := 1;
  re.dwHangUpExtraPercent := 10;
  re.dwHangUpExtraSampleSeconds := 120;
  re.dwRedialCount := 3;
  re.dwRedialPause := 60;
  re.dwType := 5;
  StrCopy(re.szDeviceName, PChar(sDeviceName));
  StrCopy(re.szDeviceType, PChar(sDeviceType));
  re.dwVpnStrategy := 0;
  re.dwEncryptionType := 3;
  FillChar(rc.szUserName, Length(rc.szUserName), #0);
  FillChar(rc.szDomain, Length(rc.szDomain), #0);
  rc.dwSize := sizeof(rc);
  rc.dwMask := 11;
  StrCopy(rc.szUserName, PChar(sUsername));
  StrCopy(rc.zPassword, PChar(sPassword));
  if RasSetEntryPropertiesA(PChar(''), PChar(sEntryName), @re, sizeof(RASENTRY), nil, 0) = 0 then
    if RasSetCredentialsA(PChar(''), PChar(sEntryName), rc, True) = 0 then
      result := true;
end;procedure TForm1.Button1Click(Sender: TObject);
var
  sDeviceType, sServer, sEntryName, sUsername, sPassword: string;
begin
  sDeviceType := 'PPPoE';
  sEntryName := 'VPN连接';  
  sServer := 'www.vpn.com';
  sUsername := '';
  sPassword := '';
  if Create_VPN_Connection(sEntryName, sServer, sUsername, sPassword) = true then
  begin
    ShowMessage('VPN连接建立成功');
  end  
  else
    ShowMessage('VPN连接建立失败');
end;end.
以上代码COPY于http://topic.csdn.net/u/20080107/16/5842D5CA-FB60-42DB-9C3B-88A8ED8D3585.html9楼。但是我调试的时候,怎么老是建立失败?
单步调试的时候,if Create_VPN_Connection(sEntryName, sServer, sUsername, sPassword) = true then就直接跳到建立失败那去了,没错误提示。哪位大侠做过VPN拨号器啊,指点一下。我想做成类似下面这个图中这样的,输入VPN的IP或网址,还有帐号和密码,点击连接就可以直接登陆了,就是ADSL拨号差不多。

解决方案 »

  1.   

    在 Create_VPN_Connection 函数的实现部分下断点,单步跟踪。看是执行哪个api失败的。然后查阅msdn看返回值或者 GetLastError 取得出错信息,然后解决。
      

  2.   

    Create_VPN_Connection 函数到下面这步就跳到END了,最后就是失败了。能帮我测试下吗,谢谢了。if RasSetEntryPropertiesA(PChar(''), PChar(sEntryName), @re, sizeof(RASENTRY), nil, 0) = 0 then
      

  3.   


    你的vpn的服务器,账户名和密码,在哪里找到的,听说网上有免费的?
    另外,这个vpn,如果是内网的话,路由器,还需要支持vpn通道数
    我上午,一直在观注这个帖子。
      

  4.   


    改为这样试试

    if RasSetEntryPropertiesA(nil,PChar(sEntryName), @re, sizeof(RASENTRY), nil, 0) = 0 then
      

  5.   

    认真看一下别人都做了什么操作吧,多试一下,一个劲的说不行是没用的
    看一下别人的结构体是怎么定义的
    type 
        GUID  =  record  //申明调用RAS(创建VPN连接用)函数所需结构体 
            Data1:  integer; 
            Data2:  Shortint; 
            Data3:  Shortint; 
            Data4:  array[0..7]  of  byte; 
        end; 
    type 
        RASIPADDR  =  record  //申明调用RAS(创建VPN连接用)函数所需结构体 
            a:  byte; 
            b:  byte; 
            c:  byte; 
            d:  byte; 
        end; 
    type 
        RASENTRY  =  record  //申明调用RAS(创建VPN连接用)函数所需结构体 
            dwSize:  integer; 
            dwfOptions:  integer; 
            dwCountryID:  integer; 
            dwCountryCode:  integer; 
            szAreaCode:  array[0..10]  of  byte; 
            szLocalPhoneNumber:  array[0..128]  of  byte; 
            dwAlternateOffset:  integer; 
            ipaddr:  RASIPADDR; 
            ipaddrDns:  RASIPADDR; 
            ipaddrDnsAlt:  RASIPADDR; 
            ipaddrWins:  RASIPADDR; 
            ipaddrWinsAlt:  RASIPADDR; 
            dwFrameSize:  integer; 
            dwfNetProtocols:  integer; 
            dwFramingProtocol:  integer; 
            szScript:  array[0..259]  of  byte; 
            szAutodialDll:  array[0..259]  of  byte; 
            szAutodialFunc:  array[0..259]  of  byte; 
            szDeviceType:  array[0..16]  of  char; 
            szDeviceName:  array[0..128]  of  char; 
            szX25PadType:  array[0..32]  of  byte; 
            szX25Address:  array[0..200]  of  byte; 
            szX25Facilities:  array[0..200]  of  byte; 
            szX25UserData:  array[0..200]  of  byte; 
            dwChannels:  integer; 
            dwReserved1:  integer; 
            dwReserved2:  integer; 
            dwSubEntries:  integer; 
            dwDialMode:  integer; 
            dwDialExtraPercent:  integer; 
            dwDialExtraSampleSeconds:  integer; 
            dwHangUpExtraPercent:  integer; 
            dwHangUpExtraSampleSeconds:  integer; 
            dwIdleDisconnectSeconds:  integer; 
            dwType:  integer; 
            dwEncryptionType:  integer; 
            dwCustomAuthKey:  integer; 
            guidId:  GUID; 
            szCustomDialDll:  array[0..259]  of  byte; 
            dwVpnStrategy:  integer; 
            dwfOptions2:  integer; 
            dwfOptions3:  integer; 
            szDnsSuffix:  array[0..255]  of  byte; 
            dwTcpWindowSize:  integer; 
            szPrerequisitePbk:  array[0..259]  of  byte; 
            szPrerequisiteEntry:  array[0..256]  of  byte; 
            dwRedialCount:  integer; 
            dwRedialPause:  integer; 
        end;     TRasCredentialsA  =  record 
            dwSize, dwMask:  Longint; 
            szUserName:  array[0..256]  of  AnsiChar; 
            zPassword:  array[0..256]  of  AnsiChar; 
            szDomain:  array[0..15]  of  AnsiChar; 
        end; 
      

  6.   

    有xp系统自创建的vpn登录,能登录
    这个 代码老是创建失败
      

  7.   

    RASENTRY的结构定义有问题,导致调用RasSetEntryPropertiesA时返回值为632.
    尽管这个回复时效性很差了,但是希望能够帮到再次找到这里来的人。
    这也是经过很多努力查出来的。
    TRasEntry = record
      dwSize,
      dwfOptions,
      dwCountryID,
      dwCountryCode          : Longint;
      szAreaCode             : array[0.. 10] of Byte;
      szLocalPhoneNumber     : array[0..128] of Byte;
      dwAlternatesOffset     : Longint;
      ipaddr,
      ipaddrDns,
      ipaddrDnsAlt,
      ipaddrWins,
      ipaddrWinsAlt          : TRasIPAddr;
      dwFrameSize,
      dwfNetProtocols,
      dwFramingProtocol      : Longint;
      szScript               : Array [0..259] of Byte;
      szAutodialDll          : Array [0..259] of Byte;
      szAutodialFunc         : Array [0..259] of Byte;
      szDeviceType           : Array [0..16] of Byte;
      szDeviceName           : Array [0..128] of Byte;
      szX25PadType           : Array [0..32] of Byte;
      szX25Address           : Array [0..200] of Byte;
      szX25Facilities        : Array [0..200] of Byte;
      szX25UserData          : Array [0..200] of Byte;
      dwChannels,
      dwReserved1,
      dwReserved2,
      dwSubEntries,
      dwDialMode,
      dwDialExtraPercent,
      dwDialExtraSampleSeconds,
      dwHangUpExtraPercent,
      dwHangUpExtraSampleSeconds,
      dwIdleDisconnectSeconds,
      dwType,
      dwEncryptionType,
      dwCustomAuthKey       : Longint;
      guidId                : GUID;
      szCustomDialDll       : Array [0..259] of Byte;
      dwVpnStrategy,
      dwfOptions2,
      dwfOptions3           : Longint;
      szDnsSuffix           : Array [0..255] of Byte;
      dwTcpWindowSize       : Longint;
      szPrerequisitePbk     : Array [0..259] of Byte;
      szPrerequisiteEntry   : Array [0..256] of Byte;
      dwRedialCount,
      dwRedialPause         : Longint;
    end;
      

  8.   

    上面是我发的正确的RASENTRY结构。
      

  9.   

    不需要身份验证协议和MS-CHAP协议的代码是什么