Jump to content

[Solved] Can't get VPN disconnect via RasHangUp function call


VAN0
 Share

Recommended Posts

Hello.

I'm trying disconnect VPN connections via RasHangUp function, but for some reason it returns error 668 (The connection dropped.) and no disconnection:

image.thumb.png.446824b16869aba3d5134b4ea62e399c.png

#include <Array.au3>

;-------------------[ get list of connections ]-------------------
Global Const $RAS_MaxDeviceType = 16
Global Const $RAS_MaxDeviceName = 128
Global Const $RAS_MaxEntryName = 256
Global Const $MAX_PATH = 260

#cs
typedef struct _RASCONN {
  DWORD    dwSize;
  HRASCONN hrasconn;
  TCHAR    szEntryName[RAS_MaxEntryName + 1];
  TCHAR    szDeviceType[RAS_MaxDeviceType + 1];
  TCHAR    szDeviceName[RAS_MaxDeviceName + 1];
  TCHAR    szPhonebook[MAX_PATH ];
  DWORD    dwSubEntry;
  GUID     guidEntry;
  DWORD    dwFlags;
  LUID     luid;
  GUID     guidCorrelationId;
} RASCONN, *PRASCONN;
#ce
Global Const $tagRASCONN = "struct;align 4;" & _
        "dword dwSize;" & _
        "handle hrasconn;" & _
        "wchar szEntryName[" & $RAS_MaxEntryName + 1 & "];" & _
        "wchar szDeviceType[" & $RAS_MaxDeviceType + 1 & "];" & _
        "wchar szDeviceName[" & $RAS_MaxDeviceName + 1 & "];" & _
        "wchar szPhonebook[" & $MAX_PATH & "];" & _
        "dword dwSubEntry;" & _
        tagGUID("guidEntry") & _
        "dword dwFlags;" & _
        tagLUID("luid") & _
        tagGUID("guidCorrelationId") & _
        "endstruct;"

Global Const $tagBUFFER_SIZE = "dword bufferSize"
Global Const $tagCONNECTIONS_COUNT = "dword connectionsCount"

Global $tagRASCONNECTIONS = ""

; up-to 5 connections
Local $iMaxConnections = 5
For $i = 1 To $iMaxConnections
    $tagRASCONNECTIONS &= StringRegExpReplace($tagRASCONN, "\s+((?!\d).*?);", " " & $i & "_$1;")
Next

; get the required buffer size
Local $tRASCONNECTIONS = DllStructCreate($tagRASCONNECTIONS)
Local $iRASCONN_size = DllStructGetSize(DllStructCreate($tagRASCONN))

For $i = 1 To $iMaxConnections
    DllStructSetData($tRASCONNECTIONS, $i & "_dwSize", $iRASCONN_size)
Next

Local $tBufferSize = DllStructCreate($tagBUFFER_SIZE)
DllStructSetData($tBufferSize, "bufferSize", DllStructGetSize($tRASCONNECTIONS))
Local $tConnectionsCount = DllStructCreate($tagCONNECTIONS_COUNT)
Local $LPRASCONNA = DllStructGetPtr($tRASCONNECTIONS)

Local $aResult = DllCall("Rasapi32.dll", "dword", "RasEnumConnectionsW", "ptr", $LPRASCONNA, "ptr", DllStructGetPtr($tBufferSize), "ptr", DllStructGetPtr($tConnectionsCount))

ConsoleWrite("RasEnumConnections() [" & _ArrayToString($aResult, ", ") & "]" & @CRLF)

Local $iCount = DllStructGetData($tConnectionsCount, "connectionsCount")

ConsoleWrite("Connections: " & $iCount & @CRLF)

Local $aConnections[$iCount]
For $i = 1 To $iCount
    Local $info[]
    $info.name = DllStructGetData($tRASCONNECTIONS, $i & "_szEntryName")
    $info.handle = DllStructGetData($tRASCONNECTIONS, $i & "_hrasconn")
    $aConnections[$i - 1] = $info

    ConsoleWrite("$aConnections[" & $i - 1 & '] {name: "' & $info.name & '", handle: ' & $info.handle & "}" & @CRLF)
    ;shows $aConnections[0] {name: "VPN NAME", handle: 0x1234567890123456}
Next

;-------------------[ disconnect connections ]-------------------
If $iCount Then
    ;disconnect all connections
    $aResult = DllCall("Rasapi32.dll", "dword", "RasHangUpW", "ptr", $LPRASCONNA)
    ConsoleWrite("RasHangUp() [" & _ArrayToString($aResult, ", ") & "]" & @CRLF)
    ;shows:
    ;RasHangUp() [668, 0x1234567890123456]
    ;where 668 is "The connection dropped."

    ;or disconnect single connection
    For $i = 0 To $iCount - 1 Step 1
        Local $tRASCONN = DllStructCreate($tagRASCONN)
        DllStructSetData($tRASCONN, "hrasconn", $aConnections[$i].handle)
        DllStructSetData($tRASCONN, "dwSize", DllStructGetSize($tagRASCONN))
        $aResult = DllCall("Rasapi32.dll", "dword", "RasHangUpW", "ptr", DllStructGetPtr($tRASCONN))
        ConsoleWrite('RasHangUp("' & $aConnections[$i].name & '") [' & _ArrayToString($aResult, ", ") & "]" & @CRLF)
        ;shows: RasHangUp("VPN NAME") [668, 0x1234567890123456]
    Next
EndIf


#cs
typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID;
#ce
Func tagGUID($id)
    Return "struct;ulong " & $id & "_Data1;ushort " & $id & "_Data2;ushort " & $id & "_Data3;byte " & $id & "_Data4[8];endstruct;"
EndFunc   ;==>tagGUID

#cs
typedef struct _LUID {
  DWORD LowPart;
  LONG  HighPart;
} LUID, *PLUID;
#ce
Func tagLUID($id)
    Return "struct;dword " & $id & "_LowPart;long " & $id & "_HighPart;endstruct;"
EndFunc   ;==>tagLUID

What's strange is if I comment out these lines

DllStructSetData($tRASCONN, "hrasconn", $aConnections[$i].handle)
DllStructSetData($tRASCONN, "dwSize", DllStructGetSize($tagRASCONN))

It still returns same 668 error, which suggests that maybe it's not getting proper "handle"?

Any suggestions what I'm doing wrong?

Thank you

P.S.

The code to get list of active connections is based on this topic, it's working fine.

Edited by VAN0
Link to comment
Share on other sites

As usual, spend almost entire day doing research and trying get this to work and minutes after I posted the question here I found a solution...

The reason for the error is because the function expects a handle and not structure...

Here is a working version:

#include <Array.au3>

;-------------------[ get list of connections ]-------------------
Global Const $RAS_MaxDeviceType = 16
Global Const $RAS_MaxDeviceName = 128
Global Const $RAS_MaxEntryName = 256
Global Const $MAX_PATH = 260

#cs
typedef struct _RASCONN {
  DWORD    dwSize;
  HRASCONN hrasconn;
  TCHAR    szEntryName[RAS_MaxEntryName + 1];
  TCHAR    szDeviceType[RAS_MaxDeviceType + 1];
  TCHAR    szDeviceName[RAS_MaxDeviceName + 1];
  TCHAR    szPhonebook[MAX_PATH ];
  DWORD    dwSubEntry;
  GUID     guidEntry;
  DWORD    dwFlags;
  LUID     luid;
  GUID     guidCorrelationId;
} RASCONN, *PRASCONN;
#ce
Global Const $tagRASCONN = "struct;align 4;" & _
        "dword dwSize;" & _
        "handle hrasconn;" & _
        "wchar szEntryName[" & $RAS_MaxEntryName + 1 & "];" & _
        "wchar szDeviceType[" & $RAS_MaxDeviceType + 1 & "];" & _
        "wchar szDeviceName[" & $RAS_MaxDeviceName + 1 & "];" & _
        "wchar szPhonebook[" & $MAX_PATH & "];" & _
        "dword dwSubEntry;" & _
        tagGUID("guidEntry") & _
        "dword dwFlags;" & _
        tagLUID("luid") & _
        tagGUID("guidCorrelationId") & _
        "endstruct;"

Global Const $tagBUFFER_SIZE = "dword bufferSize"
Global Const $tagCONNECTIONS_COUNT = "dword connectionsCount"

Global $tagRASCONNECTIONS = ""

; up-to 5 connections
Local $iMaxConnections = 5
For $i = 1 To $iMaxConnections
    $tagRASCONNECTIONS &= StringRegExpReplace($tagRASCONN, "\s+((?!\d).*?);", " " & $i & "_$1;")
Next

; get the required buffer size
Local $tRASCONNECTIONS = DllStructCreate($tagRASCONNECTIONS)
Local $iRASCONN_size = DllStructGetSize(DllStructCreate($tagRASCONN))

For $i = 1 To $iMaxConnections
    DllStructSetData($tRASCONNECTIONS, $i & "_dwSize", $iRASCONN_size)
Next

Local $tBufferSize = DllStructCreate($tagBUFFER_SIZE)
DllStructSetData($tBufferSize, "bufferSize", DllStructGetSize($tRASCONNECTIONS))
Local $tConnectionsCount = DllStructCreate($tagCONNECTIONS_COUNT)
Local $LPRASCONNA = DllStructGetPtr($tRASCONNECTIONS)

Local $aResult = DllCall("Rasapi32.dll", "dword", "RasEnumConnectionsW", "ptr", $LPRASCONNA, "ptr", DllStructGetPtr($tBufferSize), "ptr", DllStructGetPtr($tConnectionsCount))

ConsoleWrite("RasEnumConnections() [" & _ArrayToString($aResult, ", ") & "]" & @CRLF)

Local $iCount = DllStructGetData($tConnectionsCount, "connectionsCount")

ConsoleWrite("Connections: " & $iCount & @CRLF)

Local $aConnections[$iCount]
For $i = 1 To $iCount
    Local $info[]
    $info.name = DllStructGetData($tRASCONNECTIONS, $i & "_szEntryName")
    $info.handle = DllStructGetData($tRASCONNECTIONS, $i & "_hrasconn")
    $aConnections[$i - 1] = $info

    ConsoleWrite("$aConnections[" & $i - 1 & '] {name: "' & $info.name & '", handle: ' & $info.handle & "}" & @CRLF)
    ;shows $aConnections[0] {name: "VPN NAME", handle: 0x1234567890123456}
Next

;-------------------[ disconnect connections ]-------------------
If $iCount Then
    ;disconnect connections
    For $i = 0 To $iCount - 1 Step 1
        $aResult = DllCall("Rasapi32.dll", "dword", "RasHangUp", "handle", $aConnections[$i].handle)
        ConsoleWrite('RasHangUp("' & $aConnections[$i].name & '") [' & _ArrayToString($aResult, ", ") & "]" & @CRLF)
        ;shows: RasHangUp("VPN NAME") [0, 0x1234567890123456]
    Next
EndIf


#cs
typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID;
#ce
Func tagGUID($id)
    Return "struct;ulong " & $id & "_Data1;ushort " & $id & "_Data2;ushort " & $id & "_Data3;byte " & $id & "_Data4[8];endstruct;"
EndFunc   ;==>tagGUID

#cs
typedef struct _LUID {
  DWORD LowPart;
  LONG  HighPart;
} LUID, *PLUID;
#ce
Func tagLUID($id)
    Return "struct;dword " & $id & "_LowPart;long " & $id & "_HighPart;endstruct;"
EndFunc   ;==>tagLUID

 

Link to comment
Share on other sites

  • VAN0 changed the title to [Solved] Can't get VPN disconnect via RasHangUp function call

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...