cojms1 Posted July 4, 2006 Posted July 4, 2006 Hopefully someone can help.How would I go about making a call to GetIpAddrTable (MSDN).The call requires a ptr to a structure to be sent as the first argument. That structure contains a ptr to another a structure in array form. Briefly: -typedef struct _MIB_IPADDRTABLE { DWORD dwNumEntries; MIB_IPADDRROW table[ANY_SIZE]; } MIB_IPADDRTABLE, *PMIB_IPADDRTABLE; typedef struct _MIB_IPADDRROW { DWORD dwAddr; DWORD dwIndex; DWORD dwMask; DWORD dwBCastAddr; DWORD dwReasmSize; unsigned short unused1; unsigned short wType; } MIB_IPADDRROW, *PMIB_IPADDRROW;How would this be defined in AutoIt thereby allowing me to make a call to the dll and retrieve the necessary information?Any help is appreciated.
Nomad Posted July 5, 2006 Posted July 5, 2006 I don't have a lot of experience with API calls such as this, but the following example should point you in the right direction. I doubt it will work as is, it will need some adjustment:$_MIB_IPADDRROW_STRUCT = DllStructCreate('dword;dword;dword;dword;dword;ushort;ushort') $Pointer = DllStructGetPtr($_MIB_IPADDRROW_STRUCT) $_MIB_IPADDRTABLE_STRUCT = DllStructCreate('dword', $Pointer) $bOrder = 1 ;1 = TRUE, 0 = FALSE ;this next function should be 1 line, it will probably split in 2 (needs re-combined) DllCall("IPHLPAPI.DLL", "int", "GetIpAddrTable", "int", $_MIB_IPADDRTABLE_STRUCT, "ptr", DllStructGetSize($_MIB_IPADDRTABLE_STRUCT), "uint", $bOrder, "int") $dwAddr = DllStructGetData($_MIB_IPADDRROW_STRUCT, 1) $dwIndex = DllStructGetData($_MIB_IPADDRROW_STRUCT, 2) $dwMask = DllStructGetData($_MIB_IPADDRROW_STRUCT, 3) $dwBCastAddr = DllStructGetData($_MIB_IPADDRROW_STRUCT, 4) $dwReasmSize = DllStructGetData($_MIB_IPADDRROW_STRUCT, 5) $sunused1 = DllStructGetData($_MIB_IPADDRROW_STRUCT, 6) $swType = DllStructGetData($_MIB_IPADDRROW_STRUCT, 7) Nomad
cojms1 Posted July 6, 2006 Author Posted July 6, 2006 @NomadThanks (i had started along this line but was starting to get stuck retrieving the information.This is the code so far$_MIB_IPADDRROW_STRUCT = DllStructCreate("dword;dword;dword;dword;dword;ushort;ushort") $Pointer = DllStructGetPtr($_MIB_IPADDRROW_STRUCT) $_MIB_IPADDRTABLE_STRUCT = DllStructCreate("dword", $Pointer) $dwSize = DllStructCreate("dword") ;this next function should be 1 line, it will probably split in 2 (needs re-combined) $ret = DllCall("IPHLPAPI.DLL", "int", "GetIpAddrTable", "ptr", 0, "ptr", DllStructGetPtr($dwSize), "int", 0) if $ret[0] = 122 then $ret = DllCall("IPHLPAPI.DLL", "long", "GetIpAddrTable", "ptr", DllStructGetPtr($_MIB_IPADDRTABLE_STRUCT), "ptr", DllStructGetPtr($dwSize), "int", 0) if $ret[0] = 0 then $dwAddr = DllStructGetData($_MIB_IPADDRROW_STRUCT, 1) $dwIndex = DllStructGetData($_MIB_IPADDRROW_STRUCT, 2) $dwMask = DllStructGetData($_MIB_IPADDRROW_STRUCT, 3) $dwBCastAddr = DllStructGetData($_MIB_IPADDRROW_STRUCT, 4) $dwReasmSize = DllStructGetData($_MIB_IPADDRROW_STRUCT, 5) $sunused1 = DllStructGetData($_MIB_IPADDRROW_STRUCT, 6) $swType = DllStructGetData($_MIB_IPADDRROW_STRUCT, 7) msgbox(0, "IP Address", $dwAddr & @crlf & $dwIndex & @crlf & $dwMask & @crlf & $dwBCastAddr & @crlf & $dwReasmSize & @crlf & $sunused1 & @crlf & $swType) else msgbox(0, "Error", $ret[0]) endif $ret = 0 $dwSize = 0 $Pointer = 0 $_MIB_IPADDRROW_STRUCT = 0 $_MIB_IPADDRTABLE_STRUCT = 0The problem I have now is that the data in _MIB_IPADDRROW_STRUCT does not seem to be in the same order as detailed by the structure definition.Also I have multiple NICs in my laptop and therefore get 2 entries returned but I ponly have access to 1 of them. How would I turn $Pointer into an array or how would I access the items if it were already an array?
Nomad Posted July 6, 2006 Posted July 6, 2006 @Nomad Thanks (i had started along this line but was starting to get stuck retrieving the information. This is the code so far The problem I have now is that the data in _MIB_IPADDRROW_STRUCT does not seem to be in the same order as detailed by the structure definition. Also I have multiple NICs in my laptop and therefore get 2 entries returned but I ponly have access to 1 of them. How would I turn $Pointer into an array or how would I access the items if it were already an array?$Pointer should only be a pointer to the DllStructure array $_MIB_IPADDRROW_STRUCT. It may not be coded correctly for use like that, I'm not familiar with this API function. In any case, to get the data from a DllStructure, whether it is an array or not, you need to use DllStructGetData (Struct, Element, Index). Struct is the DllStructure Element is a number which cooresponds to the "Type" location in the structure. ('dword;int;dword;int') 1 would point to the first element 'dword', 2 would point to the second element 'int', 3 would point to the third element 'dword', etc.. Index is a number which cooresponds to the array index of the Element pointed to. ('char[5];char[6]') Element 1 has 5 indices, Element 2 has 6 indices. To read Index 3 of Element 2 you would do DllStructGetData (Struct, 2, 3). I hope that helps a little. As far as trying to store information as you have asked, I'm not sure. You could try this:$_MIB_IPADDRROW_STRUCT = DllStructCreate("dword[2];dword[2];dword[2];dword[2];dword[2];ushort[2];ushort[2]")But I'm not sure if the API call would know to store the information in an array like this or not. I'd need to reproduce your situation to try this out, and I can't. Do some trial and error, that's what I'd be doing. At least it partially works for you, I wasn't sure if it would work at all, hehe. The rest is just trial and error, and once you get it working correctly, you'll have a nice new UDF. Nomad
livewire Posted July 6, 2006 Posted July 6, 2006 Ejoc discussed structs within structs on this post (3rd page). I'm not sure if it can be done with current beta. I think we would need to add DllStructCreateSubStruct. I am interested in achieving this functionality also.-Livewire
Nomad Posted July 7, 2006 Posted July 7, 2006 Ejoc discussed structs within structs on this post (3rd page). I'm not sure if it can be done with current beta. I think we would need to add DllStructCreateSubStruct. I am interested in achieving this functionality also.-Livewire Yeah, that's a good link. I recommend thoroughly looking over page 3 cojms1 (post # 40+). If there's an answer, it's likely to hit you there. I don't really have the time to dive too deep into it right now. But if you haven't figured it out soon, I might give it a try. If for no other reason than a learning experience. Nomad
livewire Posted July 7, 2006 Posted July 7, 2006 This code is kind of confusing, but creates a struct which contains a float and an array of 5 sub-structs. This will only work with a fixed number of sub structs. This code does work with a dll call (not yours though, cojms1, b/c you need varying length of array) -Livewire expandcollapse popupDim $num_of_sub_structs = 5 Dim $i Dim $sub_struct[$num_of_sub_structs] Dim $sub_struct_representation = "int;int" $struct = DllStructCreate("float;" & OneToMultiple($sub_struct_representation,$num_of_sub_structs)) If @error Then MsgBox(0,"","Error in DllStructCreate " & @error); Exit EndIf For $i = 1 To $num_of_sub_structs $sub_struct[$i - 1] = DllStructCreate($sub_struct_representation,DllStructGetPtr($struct,DetermineLocation($sub_struct_representation,$i,2))) Next DllStructSetData($struct,1,10.123) DllStructSetData($sub_struct[4],1,20) dllstructsetData($sub_struct[4],2,100) MsgBox(0,"Struct Data",DllStructGetData($struct,1) & @CRLF & _ DllStructGetData($struct,DetermineLocation($sub_struct_representation,5,2)) & @CRLF & _ DllStructGetData($struct,DetermineLocation($sub_struct_representation,5,2) + 1)) Func OneToMultiple($rep,$num) Local $local_rep = $rep While $num - 1 > 0 $local_rep &= ";" & $rep $num -= 1 WEnd Return $local_rep EndFunc Func DetermineLocation($rep,$offset,$initial_loc = 1) Local $split_string $split_string = StringSplit($rep,";") Return 1 + ($offset - 1) * $split_string[0] + $initial_loc - 1 EndFunc
cojms1 Posted July 7, 2006 Author Posted July 7, 2006 Thanks for all the help guys. Working code is: - expandcollapse popup$numElements = 7 $strStruct = "dword;dword;dword;dword;dword;ushort;ushort" $_MIB_IPADDRTABLE_STRUCT = DllStructCreate("dword;" & $strStruct) $dwSize = DllStructCreate("dword") $ret = DllCall("IPHLPAPI.DLL", "int", "GetIpAddrTable", "ptr", DllStructGetPtr($_MIB_IPADDRTABLE_STRUCT), "ptr", DllStructGetPtr($dwSize), "int", 0);get the size $ret = DllCall("IPHLPAPI.DLL", "int", "GetIpAddrTable", "ptr", DllStructGetPtr($_MIB_IPADDRTABLE_STRUCT), "ptr", DllStructGetPtr($dwSize), "int", 0);get the number of entries $numEntries = DllStructGetData($_MIB_IPADDRTABLE_STRUCT, 1) ;create the structure string $strTemp = "" for $i = 1 to $numEntries $strTemp &= $strStruct & ";" next $strTemp = StringTrimRight($strTemp, 1) $_MIB_IPADDRTABLE_STRUCT = 0 $_MIB_IPADDRTABLE_STRUCT = DllStructCreate("dword;" & $strTemp) $ret = DllCall("IPHLPAPI.DLL", "int", "GetIpAddrTable", "ptr", DllStructGetPtr($_MIB_IPADDRTABLE_STRUCT), "ptr", DllStructGetPtr($dwSize), "int", 0);get the results if $ret[0] = 0 then for $i = 1 to $numEntries $strMsg = "" $offset = (($i -1) * $numElements) $strAddress = DllStructGetData($_MIB_IPADDRTABLE_STRUCT, $offset + 2) $ret = DllCall("wsock32.dll", "str", "inet_ntoa", "int", $strAddress) $strAddress = $ret[0] $dwindex = DllStructGetData($_MIB_IPADDRTABLE_STRUCT, $offset + 3) $strMask = DllStructGetData($_MIB_IPADDRTABLE_STRUCT, $offset + 4) $ret = DllCall("wsock32.dll", "str", "inet_ntoa", "int", $strMask) $strMask = $ret[0] $strBAddr = DllStructGetData($_MIB_IPADDRTABLE_STRUCT, $offset + 5) $ret = DllCall("wsock32.dll", "str", "inet_ntoa", "int", $strBAddr) $strBAddr = $ret[0] $dwReasmSize = DllStructGetData($_MIB_IPADDRTABLE_STRUCT, $offset + 6) $unused1 = DllStructGetData($_MIB_IPADDRTABLE_STRUCT, $offset + 7) $wType = DllStructGetData($_MIB_IPADDRTABLE_STRUCT, $offset + 8) $strMsg = $strAddress & @crlf & $dwIndex & @crlf & $strMask & @crlf & $strBAddr & @crlf & $dwReasmSize & @crlf & $unused1 & @crlf & $wType msgbox(0, "", $strMsg) next endif $_MIB_IPADDRRABLE_STRUCT = 0
cojms1 Posted July 7, 2006 Author Posted July 7, 2006 Lol. It was quite easy after it had been pointed out that the arrays could be used as repeated types in the structure. Should have seen this earlier really. Right. Now on to getting the rest of the app working. Thanks again for all your help.
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