VAN0 Posted March 23, 2023 Share 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 Link to comment Share on other sites More sharing options...
VAN0 Posted March 25, 2023 Author Share 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 Link to comment Share on other sites More sharing options...
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