DllCall to enumerate all ras (vpn) connections?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
highend
Posts: 47
Joined: 24 Nov 2014, 16:57

DllCall to enumerate all ras (vpn) connections?

24 Nov 2014, 17:32

Hi,

I'm trying to get the current active RAS connecion via DllCalls. Trying is the best word for it. I have no C++ / C# background and I'm struggling hard...

What I tried so far:

Code: Select all

ERROR_BUFFER_TOO_SMALL := 603

lpRasConn := 0
dwCb := 0
dwConnections := 0

dwRet := DllCall("rasapi32.dll\RasEnumConnections", "UPtr", 0, "Ptr", &dwCb, "Ptr", &dwConnections, "UInt")

if (dwRet = ERROR_BUFFER_TOO_SMALL) { ; Return successul, &dwCb contains the required buffer size
VarSetCapacity(lpRasConn, dwCb, 0)
	dwRet := DllCall("rasapi32.dll\RasEnumConnections", "UPtr", lpRasConn, "Ptr", &dwCb, "Ptr", &dwConnections, "UInt")
	If ErrorLevel
		MsgBox function returned %ErrorLevel%
}
The first DllCall seems to be correct, it returns 603. But after that I'm rather clueless how to proceed...

Can anyone help me out to get this working?

RasEnumConnections -> http://msdn.microsoft.com/en-us/library ... 85%29.aspx
RasGetConnectStatus -> http://msdn.microsoft.com/en-us/library ... 85%29.aspx
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: DllCall to enumerate all ras (vpn) connections?

25 Nov 2014, 14:09

Try this:

Code: Select all

DllCall("rasapi32.dll\RasEnumConnections", "Ptr", 0, "Ptr*", dwCb, "Ptr*", 0, "UInt")
VarSetCapacity(lpRasConn, dwCb, 0)
dwRet := DllCall("rasapi32.dll\RasEnumConnections", "Ptr", &lpRasConn, "Ptr*", dwCb, "Ptr*", dwConnections, "UInt")
If !dwRet
     MsgBox ERROR_BUFFER_TOO_SMALL
else
     MsgBox Found %dwConnections% Ras connections
highend
Posts: 47
Joined: 24 Nov 2014, 16:57

Re: DllCall to enumerate all ras (vpn) connections?

25 Nov 2014, 15:01

Thank you, HotKeyIt.

It says that it found 0 ras connections. The problem: overall I have 23 of them :)
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: DllCall to enumerate all ras (vpn) connections?

25 Nov 2014, 17:07

Try running script as Admin.
I could try next week (can't connect/try currently).
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: DllCall to enumerate all ras (vpn) connections?

25 Nov 2014, 18:18

@highend
RASCONN structure is tricky and varies with different Win versions. You have to provide the function with initial value.
Initialize dwCb in HotKeyIt's code:

Code: Select all

dwCb := 1356 ; <---- 816 >=XP, 1340, 1356, 1368, 1384 >= Vista
;DllCall("rasapi32.dll\RasEnumConnections", "Ptr", 0, "Ptr*", dwCb, "Ptr*", 0, "UInt")
VarSetCapacity(lpRasConn, dwCb, 0)
dwRet := DllCall("rasapi32.dll\RasEnumConnections", "Ptr", &lpRasConn, "Ptr*", dwCb, "Ptr*", dwConnections, "UInt")
If !dwRet
     MsgBox ERROR_BUFFER_TOO_SMALL
else
     MsgBox Found %dwConnections% Ras connections
What are you up to? May be I can provide you some AHK 1.1 32-bit code for your reference.
My Scripts and Functions: V1  V2
highend
Posts: 47
Joined: 24 Nov 2014, 16:57

Re: DllCall to enumerate all ras (vpn) connections?

25 Nov 2014, 18:49

Try running script as Admin.
Tried it, result wasn't different.

@SKAN

I've tried all values (from the first line) for dwCb but dwRet is 0 in a cases.
What are you up to? May be I can provide you some AHK 1.1 32-bit code for your reference.
I'm currently working on a VPN Watchdog (for IKEv2 / SSTP connections).
Atm I'm using a WMIC call to get the current active VPN connection but this is rather slow.

Code: Select all

wmic /NAMESPACE:"\\root\Microsoft\Windows\RemoteAccess\Client" Path PS_VpnConnection where "ConnectionStatus = 'Connected'" Get ConnectionStatus,Name /format:csv
This returns an output like this:
Node,ConnectionStatus,Name
UK-DT-01,Connected,VPN_Netherlands
I'd like to speed up the whole process and DllCalls should be the fastest way to achieve this.

The format of the output isn't relevant, I'll reformat it as long as I get something that contains the status (connected / disconnected) and the name of this (or all) connections.

Btw, I'm currently on Windows Server 2012 R2 U1 (x64) but the WMIC call runs fine on Win 7 x86 as well (and I won't support Vista or lower).

I'm using AutoHotkey_L (latest version).

Regards,
Highend
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: DllCall to enumerate all ras (vpn) connections?

25 Nov 2014, 19:37

highend wrote:I'm currently on Windows Server 2012 R2 U1 (x64)
For x64, you need increase structure size by 4 bytes.
code
highend
Posts: 47
Joined: 24 Nov 2014, 16:57

Re: DllCall to enumerate all ras (vpn) connections?

25 Nov 2014, 19:59

Thanks, SKAN :)

Connections = 1
Error 0:

Is there a way to retrieve all existing connections (by name) with their status as well?
Maybe:
0|VPN_Romania
0|VPN_Russia
1|VPN_Netherlands
0|VPN_Mexico
...

where 0 = disconnected & 1 = connected?

Btw, the WMIC call takes (on my system) between 0.5 and 0.8 seconds.
The DllCalls only 0.05 seconds -> 10 - 16 times faster :)

Thanks again,
Highend
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: DllCall to enumerate all ras (vpn) connections?

25 Nov 2014, 21:36

highend wrote:Is there a way to retrieve all existing connections (by name) with their status as well?
I have no idea about VPN. I have only a single dial-up connection for my Mobile phone.
RasEnumEntries() will list all entries available while RasEnumConnections() will list the connections.
Combined together:

Code: Select all

#Warn
#SingleInstance, Force
DllCall( "LoadLibrary", "Str","Rasapi32.dll" )

MsgBox % RAS_EnumAll() 

Return                                                              ; // end of auto-execute section //


RAS_EnumAll() {
Static ERROR_BUFFER_TOO_SMALL :=  603
     , ERROR_INVALID_SIZE     :=  632
     , SizeOf_RASENTRYNAME    :=  520  
     , SizeOf_RASCONN         := 1356 + A_PtrSize - 4 ; 816 >=XP, 1340, 1356, 1368, 1384 >= Vista

Local TSz, RASENTRYNAME, pRASENTRYNAME, EC := 0, CC := 0, PBEntry, PBEntries := "`n", RASCONN, pRASCONN  
  
  TSz := SizeOf_RASENTRYNAME  
  VarSetCapacity( RASENTRYNAME, TSz, 0 )         
  NumPut( SizeOf_RASENTRYNAME, RASENTRYNAME )
  pRASENTRYNAME := &RASENTRYNAME
  
  Error := DllCall( "Rasapi32\RasEnumEntriesW", "Int",0, "Int",0, "Ptr",&RASENTRYNAME, "PtrP",TSz, "PtrP",EC )

  If ( Error = ERROR_BUFFER_TOO_SMALL ) 
      VarSetCapacity( RASENTRYNAME, TSz, 0 ) 
    , NumPut( SizeOf_RASENTRYNAME, RASENTRYNAME )
    , DllCall( "Rasapi32\RasEnumEntriesW", "Int",0, "Int",0, "Ptr",&RASENTRYNAME, "PtrP",TSz, "PtrP",EC )

  Loop %EC% 
  { 
     PBEntry := StrGet( pRASENTRYNAME + 4, "UTF-16" )
     PBEntries .=  "0|" PBEntry "`n"
     pRASENTRYNAME += SizeOf_RASENTRYNAME  
  }
  StringTrimRight, PBEntries, PBEntries, 1

  TSz := SizeOf_RASCONN                              
  VarSetCapacity( RASCONN, TSz, 0 ) 
  NumPut( SizeOf_RASCONN, RASCONN )
  pRASCONN := &RASCONN

  Error :=  DllCall( "Rasapi32\RasEnumConnectionsW", "Ptr",&RASCONN, "PtrP",TSz, "PtrP",CC )
  
  If ( Error = ERROR_BUFFER_TOO_SMALL ) 
       VarSetCapacity( RASCONN, TSz, 0 ) 
     , NumPut( SizeOf_RASCONN, RASCONN )
     , DllCall( "Rasapi32\RasEnumConnectionsW", "Ptr",&RASCONN, "PtrP",TSz, "PtrP",CC  )

  Loop %CC%
  { 
     PBEntry := StrGet( pRASCONN + A_PtrSize + 4, "UTF-16" )
     StringReplace, PBEntries, PBEntries, `n0|%PBEntry%`n, `n1|%PBEntry%`n  
     pRASCONN += SizeOf_RASCONN           
  }

Return Trim( PBEntries , "`n" )
}
highend
Posts: 47
Joined: 24 Nov 2014, 16:57

Re: DllCall to enumerate all ras (vpn) connections?

26 Nov 2014, 02:56

Thanks again, SKAN!

Unfortunately I does crash immediately on start ("Test.exe doesn't work anymore")

By commenting out it crashes during the first "Loop %EC%"

It runs through the first 11 connections but on the 12th it crashes (I have 23 connections atm).

Btw, the PBEntry variable stays always empty on these 11 (successful) loops.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: DllCall to enumerate all ras (vpn) connections?

26 Nov 2014, 12:29

I have updated the code. Please try it again.
highend
Posts: 47
Joined: 24 Nov 2014, 16:57

Re: DllCall to enumerate all ras (vpn) connections?

26 Nov 2014, 14:46

Unfortunately, it still does crash.

I've added "OutputDebug, PBEntry: %PBEntry% Index: %A_Index%" in the first Loop %EC%

and this is the output:
[3912] PBEntry: ?? Index: 1
[3912] PBEntry: Index: 2
[3912] PBEntry: Index: 3
[3912] PBEntry: Index: 4
[3912] PBEntry: Index: 5
[3912] PBEntry: Index: 6
[3912] PBEntry: Index: 7
[3912] PBEntry: Index: 8
[3912] PBEntry: Index: 9
[3912] PBEntry: Index: 10
[3912] PBEntry: Index: 11

Code: Select all

  Loop %EC%
  {
     PBEntry := StrGet( pRASENTRYNAME + 4, "UTF-16" )
     PBEntries .=  "0|" PBEntry "`n"
     OutputDebug, PBEntry: %PBEntry% Index: %A_Index%
     pRASENTRYNAME += SizeOf_RASENTRYNAME  
  }
The StrGet() in the 12th loop seems to crash the application...

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: haomingchen1998 and 248 guests