Sign in to follow this  
Followers 0
Raik

nested struct as array ?

13 posts in this topic

#1 ·  Posted (edited)

This is the c-code:

/* http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/staging/rt2860/oid.h#L464 */
struct _NDIS_802_11_BSSID_LIST {
   UINT NumberOfItems;
   NDIS_WLAN_BSSID Bssid[1];
};
/* http://fossies.org/dox/ndiswrapper-1.57/iw__ndis_8h_source.html#l00096 */
struct ndis_wlan_bssid {
        ULONG length;
        mac_address mac;
        UCHAR reserved[2];
        struct ndis_essid ssid;
        ULONG privacy;
        ndis_rssi rssi;
        UINT net_type;
        struct ndis_configuration config;
        UINT mode;
        UCHAR rates[NDIS_MAX_RATES];
};
typedef UCHAR mac_address[ETH_ALEN];
struct ndis_essid {
        ULONG length;
        UCHAR essid[NDIS_ESSID_MAX_SIZE];
};
#define NDIS_ESSID_MAX_SIZE 32
typedef LONG ndis_rssi;
struct ndis_configuration {
        ULONG length;
        ULONG beacon_period;
        ULONG atim_window;
        ULONG ds_config;
        struct ndis_configuration_fh fh_config;
};
#define NDIS_MAX_RATES 8
struct ndis_configuration {
        ULONG length;
        ULONG beacon_period;
        ULONG atim_window;
        ULONG ds_config;
        struct ndis_configuration_fh fh_config;
};
struct ndis_configuration_fh {
        ULONG length;
        ULONG hop_pattern;
        ULONG hop_set;
        ULONG dwell_time;
};
/* http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/if_ether.h#L31 */
#define ETH_ALEN 6

I have it transfered to this:

Global Const $_NDIS_802_11_BSSID_LIST = "ULONG NumberOfItems;"&$_NDIS_WLAN_BSSID&" Bssid[1]"
Global Const $_NDIS_WLAN_BSSID[1] = "ULONG length;BYTE mac_address[6];BYTE reserved[2];STRUCT;"& _
$_NDIS_802_11_SSID&";ENDSTRUCT ssid;ULONG privacy;LONG ndis_rssi;UINT net_type;STRUCT;"& _
$_NDIS_802_11_CONFIGURATION&";ENDSTRUCT config;UINT mode;BYTE rates[8]"
Global Const $_NDIS_802_11_SSID = "ULONG length;BYTE essid[32]"
Global Const $_NDIS_802_11_CONFIGURATION = "ULONG length;ULONG beacon_period;ULONG atim_window;ULONG ds_config;STRUCT;"& _
$_NDIS_802_11_CONFIGURATION_FH&";ENDSTRUCT fh_config"
Global Const $_NDIS_802_11_CONFIGURATION_FH = "ULONG length;ULONG hop_pattern;ULONG hop_set;ULONG dwell_time"

could nestes structs be named like i did?

and how to handle the $_NDIS_WLAN_BSSID&" Bssid[1]"

Edited by Raik

AutoIt-Syntaxsheme for Proton & Phase5 * Firefox Addons by me (resizable Textarea 0.1d) (docked JS-Console 0.1.1)

Share this post


Link to post
Share on other sites



! would have thought you might make your stucts with DllStructCreate()

Something like...

$struct_ndis_configuration_fh = DllStructCreate( _
    "ULONG length;" _
  & "ULONG hop_pattern;" _
  & "ULONG hop_set;" _
  & "ULONG dwell_time" _
)

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I don't think you can nest structs in AutoIt like you want...you basically need to concatenate them then find a way to keep track of the index of all the elements.

Here's a working example to describe what I mean... I couldn't use yours as they are too complicated for me right now but hopefully you get it and maybe can make it work!

;Nested Structs Example
#cs
struct date{
// members of structure
    int day;
int month;
int year;
};
struct company{
char name[20];
int employee_id;
char sex[5];
int age;
struct date dob;};
#ce
Dim $structEmployee ;This will be our final "nested" struct
Dim $s_structNested = ""  ;This is our struct text after it's all put together
$iNumEmployees = 3
$iNumElementsPerEmployee = 7
$s_structCompany =  "char name[20];int employee_id;char sex[5];int age;" ;Struct to be nested is excluded here, take note of the position of each data type
;~     POS1   POS2  POS3  POS4
$s_structDate =  "int day;int month;int year;" ;This is the struct to be nested into company struct
;~    POS5  POS6 POS7
;The following "nests" the structs. You're really concatenating
For $k = 1 To $iNumEmployees
$s_structNested &= $s_structCompany & $s_structDate
Next
ConsoleWrite($s_structNested & @CRLF) ;here's our structure string
$s_structNested = StringTrimRight($s_structNested, 1)   ;Remove that final semi-colon; just found out it apparently isn't necessary
ConsoleWrite($s_structNested & @CRLF) ;here's our structure string without the semi-colon
$structEmployee = DllStructCreate($s_structNested)  ;create the struct
$j = 0
;~ Load data into the struct
For $i = 1 To (($iNumEmployees - 1) * $iNumElementsPerEmployee) + 1 Step 7  ;Here $i = 1 then 8 then 15
$j = $i + 4
DllStructSetData($structEmployee, $i,   "Name" & $i)
DllStructSetData($structEmployee, $i + 1,  $i + 1000)
DllStructSetData($structEmployee, $i + 2,  "Male")
DllStructSetData($structEmployee, $i + 3,  $i + 25)
DllStructSetData($structEmployee, $j,   $i + 2)
DllStructSetData($structEmployee, $j + 1,  $i + 4)
DllStructSetData($structEmployee, $j + 2,  $i + 2008)
Next
;~ Display the struct
For $i = 1 To (($iNumEmployees - 1) * $iNumElementsPerEmployee) + 1 Step 7
$j = $i + 4
ConsoleWrite("Name: "   & DllStructGetData($structEmployee, $i) & @CRLF)
ConsoleWrite("Employee ID: "  & DllStructGetData($structEmployee, $i + 1)   & @CRLF)
ConsoleWrite("Sex: "    & DllStructGetData($structEmployee, $i + 2)   & @CRLF)
ConsoleWrite("Age: "    & DllStructGetData($structEmployee, $i + 3)   & @CRLF)
ConsoleWrite("Date: "   & DllStructGetData($structEmployee, $j + 1)   & "/" & _ ;Month
           DllStructGetData($structEmployee, $j)    & "/" & _ ;Day
           DllStructGetData($structEmployee, $j + 2)   & @CRLF) ;Year
ConsoleWrite(@CRLF)
Next

Edit: Sorry about the formatting, it looked good in Scite. I'll try to attach it too.

NestedStructs2.au3

Edited by MrMitchell

Share this post


Link to post
Share on other sites

As per UCHAR is an unsigned byte.

As per DllStructCreate "If a collection of datatypes is defined as in a "struct{}" in C declaration, the "STRUCT; ...; ENDSTRUCT;" must be used."

But as per declaration in C

struct _NDIS_802_11_BSSID_LIST {
   UINT NumberOfItems;
   NDIS_WLAN_BSSID Bssid[1];

NDIS_WLAN_BSSID seems to be an array (Bssid[1])?

Who can help on this?


AutoIt-Syntaxsheme for Proton & Phase5 * Firefox Addons by me (resizable Textarea 0.1d) (docked JS-Console 0.1.1)

Share this post


Link to post
Share on other sites

Thats the right way?

Global Const $_NDIS_802_11_CONFIGURATION_FH = "ULONG length;ULONG hop_pattern;ULONG hop_set;ULONG dwell_time"

Global Const $_NDIS_802_11_CONFIGURATION = "ULONG length;ULONG beacon_period;ULONG atim_window;ULONG ds_config;"& _
"STRUCT;"&$_NDIS_802_11_CONFIGURATION_FH&";ENDSTRUCT fh_config"

Global Const $_NDIS_802_11_SSID = "ULONG length;BYTE essid[32]"

Global Const $_NDIS_WLAN_BSSID = "ULONG length;BYTE mac_address[6];BYTE reserved[2];"& _
"STRUCT;"&$_NDIS_802_11_SSID&";ENDSTRUCT ssid;ULONG privacy;LONG ndis_rssi;UINT net_type;"& _
"STRUCT;"&$_NDIS_802_11_CONFIGURATION&";ENDSTRUCT config;UINT mode;BYTE rates[8]"

$structBSSID = DllStructCreate($_NDIS_WLAN_BSSID)

Global Const $_NDIS_802_11_BSSID_LIST = "ULONG NumberOfItems;"&DllStructGetPtr($structBSSID)&" Bssid[1]"

AutoIt-Syntaxsheme for Proton & Phase5 * Firefox Addons by me (resizable Textarea 0.1d) (docked JS-Console 0.1.1)

Share this post


Link to post
Share on other sites

Try running Nested_Structs.au3 (even though I have no idea if this is anywhere close to what you need, or if what you need is even possible, but the structs do seem to get created but might need some adjusting...). I still don't know how you would deal with your _NDIS_801_11_BSSID_LIST struct though since it contains an array of structs. I'm very curious and will be following the topic, hopefully someone can help.

You can get _DLLStructDisplay() here.

Share this post


Link to post
Share on other sites

This seems to work (throws no error), but is it the right "translation" of the c-code?

#include "_DLLStructDisplay.au3"

Global Const $_NDIS_802_11_SSID = "ULONG length;BYTE essid[32]"
Global Const $_NDIS_802_11_CONFIGURATION_FH = "ULONG length;ULONG hop_pattern;ULONG hop_set;ULONG dwell_time"
Global Const $_NDIS_802_11_CONFIGURATION = "ULONG length;ULONG beacon_period;ULONG atim_window;ULONG ds_config;"& _
"STRUCT;"&$_NDIS_802_11_CONFIGURATION_FH&";ENDSTRUCT fh_config"
Global Const $_NDIS_WLAN_BSSID = "ULONG length;BYTE mac_address[6];BYTE reserved[2];STRUCT;"&$_NDIS_802_11_SSID&";ENDSTRUCT ssid;"& _
"ULONG privacy;LONG ndis_rssi;UINT net_type;STRUCT;"&$_NDIS_802_11_CONFIGURATION&";ENDSTRUCT config;UINT mode;BYTE rates[8]"
Global Const $_NDIS_802_11_BSSID_LIST = "ULONG NumberOfItems;ptr Bssid[1]"

Local $sStructStr=$_NDIS_802_11_BSSID_LIST

$_NDIS_WLAN_BSSID_struct = DllStructCreate($_NDIS_WLAN_BSSID)

$_NDIS_802_11_BSSID_LIST_struct = DllStructCreate($_NDIS_802_11_BSSID_LIST)
If @error Then Exit ConsoleWrite("DLLStructCreate @error="&@error&@CRLF)

DllStructSetData($_NDIS_802_11_BSSID_LIST_struct,"Bssid",DllStructGetPtr($_NDIS_WLAN_BSSID_struct),1)

If Not _DLLStructDisplay($_NDIS_802_11_BSSID_LIST_struct,$sStructStr,"Randomness") Then
    ConsoleWrite("_DLLStructDisplay failed, @error="&@error&@CRLF)
EndIf

AutoIt-Syntaxsheme for Proton & Phase5 * Firefox Addons by me (resizable Textarea 0.1d) (docked JS-Console 0.1.1)

Share this post


Link to post
Share on other sites

This seems to work (throws no error), but is it the right "translation" of the c-code?

That's what I was hoping someone else could help with. Just don't know how to deal with the "list" struct which contains the array of structs

Share this post


Link to post
Share on other sites

Try this revised method... do you have the documentation for the functions you need these structs for?

Nested_Structs.au3

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

it seems, i have to use the newer ndis_wlan_bssid_ex structure, because nearly all actual networkdrivers are ndis v.6 drivers, witch return datafields with variable length, like for the ssid.

thats the cause, why WMI in win xp is broken, at last the MSNdis_80211_BSSIList query, because it uses the old ndis_wlan_bssid structure with fixed lengths.

for now its enough, tomorow is another day.

btw.: here is the code, witch i want to translate to autoit: https://github.com/metageek-llc/IoctlNdis/blob/master/IoctlNdis.cs

Edit:

struct NDIS_802_11_BSSID_LIST_EX {
   UINT NumberOfItems;
   NDIS_WLAN_BSSID Bssid[1];
};

struct ndis_wlan_bssid_ex {
        ULONG length;
        mac_address mac;
        UCHAR reserved[2];
        struct ndis_essid ssid;
        ULONG privacy;
        ndis_rssi rssi;
        UINT net_type;
        struct ndis_configuration config;
        UINT mode;
        UCHAR rates_ex[NDIS_MAX_RATES_EX];
        ULONG ie_length;
        struct ndis_fixed_ies fixed;
        struct ndis_variable_ies var[];
};

typedef UCHAR mac_address[ETH_ALEN];
#define ETH_ALEN 6

struct ndis_essid {
        ULONG length;
        UCHAR essid[NDIS_ESSID_MAX_SIZE];
};

#define NDIS_ESSID_MAX_SIZE 32
typedef LONG ndis_rssi;

struct ndis_configuration {
        ULONG length;
        ULONG beacon_period;
        ULONG atim_window;
        ULONG ds_config;
        struct ndis_configuration_fh fh_config;
};

#define NDIS_MAX_RATES 8

struct ndis_configuration {
        ULONG length;
        ULONG beacon_period;
        ULONG atim_window;
        ULONG ds_config;
        struct ndis_configuration_fh fh_config;
};

struct ndis_configuration_fh {
        ULONG length;
        ULONG hop_pattern;
        ULONG hop_set;
        ULONG dwell_time;
};

struct ndis_fixed_ies {
        UCHAR time_stamp[8];
        USHORT beacon_interval;
        USHORT capa;
};

struct ndis_variable_ies {
        UCHAR elem_id;
        UCHAR length;
        UCHAR data[];
};

Edit2 :

I have compared with all documentations and this is the result:

$NDIS_ESSID = "STRUCT;ULONG length;BYTE essid[32];ENDSTRUCT"
$NDIS_CONFIGURATION_FH = "STRUCT;align 4;ULONG length;ULONG hop_pattern;ULONG hop_set;ULONG dwell_time;ENDSTRUCT"
$NDIS_CONFIGURATION = "STRUCT;align 4;ULONG length;ULONG beacon_period;ULONG atim_window;ULONG ds_config;"& _
    $NDIS_CONFIGURATION_FH&" fh_config;ENDSTRUCT"
$NDIS_FIXED_IES = "STRUCT;align 1;BYTE time_stamp[8];USHORT beacon_interval;USHORT capa;ENDSTRUCT"
$NDIS_VARIABLE_IES = "STRUCT;align 1;BYTE elem_id;BYTE length;BYTE data[1];ENDSTRUCT"
$NDIS_WLAN_BSSID_EX = "STRUCT;align 4;ULONG length;BYTE mac[6];BYTE reserved[2];"&$NDIS_ESSID&";ULONG privacy;" & _
    "LONG rssi;UINT net_type;"&$NDIS_CONFIGURATION&" config;UINT mode;BYTE rates_ex[16];ULONG ie_length;"& _
    $NDIS_FIXED_IES&" fixed;"&$NDIS_VARIABLE_IES&" var[512];ENDSTRUCT"
$NDIS_802_11_BSSID_LIST_EX = "align 4;UINT NumberOfItems;"&$NDIS_WLAN_BSSID_EX&" Bssid[1]"

PCAUSA NDIS Developer Tools <- OIDScope is realy helpful :-)

Edited by Raik

AutoIt-Syntaxsheme for Proton & Phase5 * Firefox Addons by me (resizable Textarea 0.1d) (docked JS-Console 0.1.1)

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

To give an explanation to everybody, who is interested in this topic:

in the end everything (every return from a dll-function) is a chain of data.
"struct" is only a mask, a grid, a template, a pattern, you can lay over the data.

even "nested" structs are only chains of datafields with a defined length.

You can paste a "struct" to a function, or simply a variable with a defined length. its only importand, to reserve the required space for the data, to fit in.

You can read the data returned, by laying the "struct"-template over it, or by using an offset from the beginning of the data. 

Imagine returned data as a string, from witch you can get a substring like with StringMid(), providing a startvalue (corresponding "offset") and a count (corresponding the size of the struct-element).

The trick with the variable-length - structs is, they all have a "length"-field as its first element, so you can calculate the positions (offsets) of the following elements by this.

Even the names of the struct-elements do not matter for the proper functioning of receiving data from a dllcall.

Putt all structs and sub-structs together and then use DllStructCreate. If a struct has a variable length, use the max. length for each element, and all went fine. Its only important to reserve enough space in ram for the data, returned by the dll-function.

Edited by Raik

AutoIt-Syntaxsheme for Proton & Phase5 * Firefox Addons by me (resizable Textarea 0.1d) (docked JS-Console 0.1.1)

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0