VAN0 Posted March 23, 2023 Posted March 23, 2023 (edited) Hello. I'm trying get VPN connection status via RasGetConnectStatus For this I first get list of active connections via RasEnumConnections (this part works fine). But when I attempt execute RasGetConnectStatus it returns error 632 The structure size is incorrect. expandcollapse popup#include <Array.au3> ;-------------------[ get list of connections ]------------------- Global Const $RAS_MaxDeviceType = 16 Global Const $RAS_MaxDeviceName = 128 Global Const $RAS_MaxEntryName = 256 Global Const $RAS_MaxPhoneNumber = 128 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;" #cs typedef struct _RASCONNSTATUS { DWORD dwSize; RASCONNSTATE rasconnstate; DWORD dwError; TCHAR szDeviceType[RAS_MaxDeviceType + 1]; TCHAR szDeviceName[RAS_MaxDeviceName + 1]; TCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1]; RASTUNNELENDPOINT localEndPoint; RASTUNNELENDPOINT remoteEndPoint; RASCONNSUBSTATE rasconnsubstate; } RASCONNSTATUS; #ce Global Const $tagRASCONNSTATUS = "struct;" & _ "dword dwSize;" & _ "int rasconnstate;" & _ "dword dwError;" & _ "wchar szDeviceType[" & $RAS_MaxDeviceType + 1 & "];" & _ "wchar szDeviceName[" & $RAS_MaxDeviceName + 1 & "];" & _ "wchar szPhoneNumber[" & $RAS_MaxPhoneNumber + 1 & "];" & _ "dword localEndPoint;" & _ "dword remoteEndPoint;" & _ "int rasconnsubstate;" & _ "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) ;-------------------[ get connection status ]------------------- local $tRASCONNSTATUS = DllStructCreate($tagRASCONNSTATUS) DllStructSetData($tRASCONNSTATUS, "dwSize", DllStructGetSize($tRASCONNSTATUS)) local $aRet = DllCall("Rasapi32.dll", "dword", "RasGetConnectStatusW", "handle", $info.handle, "ptr", DllStructGetPtr($tRASCONNSTATUS)) ;error 632 The structure size is incorrect. ConsoleWrite(_ArrayToString($aRet, ", ") & @CRLF) Next #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 am I doing wrong here? Thank you. Edited March 23, 2023 by VAN0
VAN0 Posted March 25, 2023 Author Posted March 25, 2023 Thanks to @TheXman explaining how to properly construct RASCONNSTATUS struct here is the solution I was looking for: expandcollapse popup#include <Array.au3> ;-------------------[ get list of connections ]------------------- Global Const $RAS_MaxDeviceType = 16 Global Const $RAS_MaxDeviceName = 128 Global Const $RAS_MaxEntryName = 256 Global Const $RAS_MaxPhoneNumber = 128 Global Const $MAX_PATH = 260 Global $RAS_STATUS[] $RAS_STATUS[0] = "Open port" $RAS_STATUS[1] = "Port opened" $RAS_STATUS[2] = "Connect device" $RAS_STATUS[3] = "Device connected" $RAS_STATUS[4] = "All devices connected" $RAS_STATUS[5] = "Authenticate" $RAS_STATUS[6] = "Authenticate: notify" $RAS_STATUS[7] = "Authentication: retry" $RAS_STATUS[8] = "Authentication: callback" $RAS_STATUS[9] = "Authentication: change password" $RAS_STATUS[10] = "Authentication: project" $RAS_STATUS[11] = "Authentication: link speed" $RAS_STATUS[12] = "Authentication: acknowledge" $RAS_STATUS[13] = "Reauthentication" $RAS_STATUS[14] = "Authenticated" $RAS_STATUS[15] = "Prepare for callback" $RAS_STATUS[16] = "Wait for modem reset" $RAS_STATUS[17] = "Wait for modem callback" $RAS_STATUS[18] = "Projected" $RAS_STATUS[19] = "Start authentication" $RAS_STATUS[20] = "Callback complete" $RAS_STATUS[21] = "Logon network" $RAS_STATUS[4096] = "Interactive" $RAS_STATUS[4097] = "Retry authentication" $RAS_STATUS[4098] = "Callback set by Caller" $RAS_STATUS[4099] = "Password expired" $RAS_STATUS[8192] = "Connected" $RAS_STATUS[8193] = "Disconnected" #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;" #cs typedef struct _RASCONNSTATUS { DWORD dwSize; RASCONNSTATE rasconnstate; DWORD dwError; TCHAR szDeviceType[RAS_MaxDeviceType + 1]; TCHAR szDeviceName[RAS_MaxDeviceName + 1]; TCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1]; RASTUNNELENDPOINT localEndPoint; RASTUNNELENDPOINT remoteEndPoint; RASCONNSUBSTATE rasconnsubstate; } RASCONNSTATUS; #ce Global Const $tagRASCONNSTATUS = "struct;" & _ "dword dwSize;" & _ "int rasconnstate;" & _ "dword dwError;" & _ "wchar szDeviceType[" & $RAS_MaxDeviceType + 1 & "];" & _ "wchar szDeviceName[" & $RAS_MaxDeviceName + 1 & "];" & _ "wchar szPhoneNumber[" & $RAS_MaxPhoneNumber + 1 & "];" & _ "dword dwLocalEndPointType;" & _ ;1 = IP4, 2 = IP6 "byte localEndPoint[16];" & _; IP "dword dwRemoteEndPointType;" & _ ;1 = IP4, 2 = IP6 "byte remoteEndPoint[16];" & _; IP "int rasconnsubstate;" & _ "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) ;-------------------[ get connection status ]------------------- local $tRASCONNSTATUS = DllStructCreate($tagRASCONNSTATUS) DllStructSetData($tRASCONNSTATUS, "dwSize", DllStructGetSize($tRASCONNSTATUS)) local $aRet = DllCall("Rasapi32.dll", "dword", "RasGetConnectStatusW", "handle", $info.handle, "ptr", DllStructGetPtr($tRASCONNSTATUS)) ConsoleWrite("RasGetConnectStatus() [" & _ArrayToString($aRet, ", ") & "]" & @CRLF) local $iRasconnstate = DllStructGetData($tRASCONNSTATUS, "rasconnstate") local $status = $RAS_STATUS[$iRasconnstate] if not $status then $status = $iRasconnstate ConsoleWrite("Status: " & $status & @CRLF) ConsoleWrite("Name: " & $info.name & @CRLF) ConsoleWrite("Phone number: " & DllStructGetData($tRASCONNSTATUS, "szPhoneNumber") & @CRLF) ConsoleWrite("IP local: " & getIp($tRASCONNSTATUS, "local") & @CRLF) ConsoleWrite("IP remote: " & getIp($tRASCONNSTATUS, "remote") & @CRLF) Next ; get IP address func getIp($tSTRUCT, $type) local $isIPV6 = DllStructGetData($tSTRUCT, "dw" & $type & "EndPointType") == 2 local $ip = "" local $size = 4 local $sep = "." if $isIPV6 Then $size = 16 $sep = ":" EndIf for $i = 1 to $size if $ip Then $ip &= $sep local $n = DllStructGetData($tSTRUCT, $type & "EndPoint", $i) if $isIPV6 Then $i += 1 Local $tWord = DllStructCreate('word') Local $tByte = DllStructCreate('byte;byte', DllStructGetPtr($tWord)) DllStructSetData($tByte, 1, DllStructGetData($tSTRUCT, $type & "EndPoint", $i)) DllStructSetData($tByte, 2, $n) $n = DllStructGetData($tWord, 1) $n = HEX($n, 4) EndIf $ip &= $n next return $ip EndFunc #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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now