I have done a quick search on this but have got a bit lost.

Here is a structure I have:

BLUETOOTH_DEVICE_INFO_EX struct
dwSize dw ?
address db ?
classOfDevice db ?
szName db ?
bPaired db ?
ucLmpVersion db ?
wManuName db "",0
wLmpSubversion dw ?
reserved db 16 dup (?)
wClockOffset dw ?
bConnected db ?
dwDataRecvBytes dw ?
dwDataSentBytes dw ?
cSignalStrength db ?

BLUETOOTH_DEVICE_INFO_EX ends

and here is a function call that uses the above struct

mov , size btdie
call BT_GetLocalDeviceInfo, 1, offset btdie

BT_GetLocalDeviceInfo is part of a dll provided by IVT for use bluesoleil. The function returns 1, indicating that this is successful, so then I process (excuse the diff calling conventions)

push 0
push offset
push offset
push 0
call MessageBoxA

and in the message box I get crap :(. I have run the program through OllyDbg and see a reference to "Acer". Now the first function call checks local settings and szName will contain the bluetooth name of the i am on. It is acer so therefore the function call is running correctly I just get cant access szName in the structure. Any ideas?

Posted on 2008-10-04 12:57:33 by sidey1234
Here is a bit more info. I am also on a diff computer now so the name will Compaq not acer.

0040116B  . 6A 00          PUSH 0                                          ; /Style = MB_OK|MB_APPLMODAL
0040116D  . 68 0E204000    PUSH bt.0040200E                        ; |Title = "x="
00401172  . 68 0E204000    PUSH bt.0040200E                        ; |Text = "x="
00401177  . 6A 00          PUSH 0                                          ; |hOwner = NULL
00401179  . E8 BA000000    CALL <JMP.&USER32.MessageBoxA>          ; \MessageBoxA

here is the program dump from Olly showing the message box call. The address its looking at is 0040200e and that in olly shows this:

00402008  00 00 00 00 00 00 78 01  ......x
00402010  3D 00 00 00 00 00 00 43  =......C
00402018  4F 4D 50 41 51 00 00 00  OMPAQ...

Hope this additional info helps.

Posted on 2008-10-04 15:08:22 by sidey1234
Yeah, the main problem was that your structure was declared wrongly. However, I can't find the declaration of that structure in C so I can't correct it for you. For instance, I'm quite sure szName will not be just db ?. Do you have the structure declared in C or any other languages?
Posted on 2008-10-04 21:02:31 by roticv

DEVICE_CLASS_LENGTH equ 3
DEVICE_ADDRESS_LENGTH equ 6
MAX_DEVICE_NAME_LENGTH equ 64

BLUETOOTH_DEVICE_INFO_EX struct
dwSize dd ?
address db DEVICE_ADDRESS_LENGTH dup (?)
classOfDevice db DEVICE_CLASS_LENGTH dup (?)
szName db MAX_DEVICE_NAME_LENGTH dup (?)
bPaired BOOL ?
ucLmpVersion dw ? ;unicode character = 16 bits
wManuName dw ?
        wLmpSubversion dw ?
reserved db 16 dup (?)
wClockOffset dw ?
bConnected BOOL ?
dwDataRecvBytes dd ?
dwDataSentBytes dd ?
cSignalStrength db ?
BLUETOOTH_DEVICE_INFO_EX ends


You're welcome :)

Posted on 2008-10-04 21:15:11 by Homer
Excellent! Homer thank you that does work :) I guess I was getting a bit above my skill level :)

Roticv for future reference here is the structure declared in c/c++

typedef struct _BLUETOOTH_DEVICE_INFO_EX {
DWORD dwSize;
BYTE address;
BYTE classOfDevice;
CHAR szName;
BOOL bPaired;
UCHAR ucLmpVersion;
WORD wManuName;
WORD wLmpSubversion;
BYTE reserved[16];
WORD wClockOffset;
BOOL bConnected;
DWORD dwDataRecvBytes;
DWORD dwDataSentBytes;
CHAR cSignalStrength;
} BLUETOOTH_DEVICE_INFO_EX, *PBLUETOOTH_DEVICE_INFO_EX;
Posted on 2008-10-05 04:23:35 by sidey1234
The only trick is in naming conventions.
We use dword=32bit , word=16bit, byte=8bit
But we have to pander to the whims of the HLL community and know that CHAR is a byte and UCHAR is a word etc.

You'll get the hang of converting these types :)

Posted on 2008-10-05 04:51:40 by Homer
Sorry, I have another question about this.

using the same structure as before, the external function i am callin will populate this more than once eg it will use the same strcuture 10 times and have 10 different instances of it in memory (hope you followed that)

As i am calling setdlgitemtexta ,blah, blah, offset this works and prints the first name

I would like to be able to access the rest (well pointers on how i'm accessing the second might help me get all the way) so I have tried setdlgitemtexta ,blah, blah, offset which I figured, but was soon proved wrong, would set me nicely into the next szName but it doesnt :(

Hope fully this little will clear things up a littles as I know my explanation sucks, this is how I see the structure is replicated and stored in memory after the function completes.

Structure heh

Christian Name db bob
Surname db jones

heh ends

Structure heh

Christian Name db stuart
Surname db haha


And if this further helps, here is the c version

for(i=0; i<((DevsListLen)/sizeof(BLUETOOTH_DEVICE_INFO)); i++){
pDevice=(BLUETOOTH_DEVICE_INFO*)((UCHAR*)lpDevsList+i*offset);

printf("Device No.%d\n        Device Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
i,
pDevice->address[5],
pDevice->address[4],
pDevice->address[3],
pDevice->address[2],
pDevice->address[1],
pDevice->address[0]);

DWORD dwMask = 0;
BLUETOOTH_DEVICE_INFO_EX devInfo = {0};
memcpy(&devInfo.address, pDevice->address, DEVICE_ADDRESS_LENGTH);
devInfo.dwSize = sizeof(BLUETOOTH_DEVICE_INFO_EX);
devInfo.szName[0]='\0';
dwMask = MASK_DEVICE_NAME;

DWORD dwResult;
dwResult = BT_SetRemoteDeviceInfo(dwMask, &devInfo);
PrintError("BT_SetRemoteDeviceInfo",dwResult);
dwResult = BT_GetRemoteDeviceInfo(dwMask, &devInfo);
PrintError("BT_GetRemoteDeviceInfo",dwResult);

printf("        Device Name: %s\n", devInfo.szName);
PrintDeviceClassInfo(pDevice->classOfDevice);
if(pDevice->bPaired)
Posted on 2008-10-09 09:31:06 by sidey1234
Here is some work I was doing last night. Instead of brain farting all over the place. I decided to just break the c part down.

;lpDevsList+i*offset
;mov ax, size btdi ; offset = sizeof(BLUETOOTH_DEVICE_INFO);
;mov bx, 2 ; Array multilier for 2nd item
;mul bx ; i * offset
;add ax, listlength ; lpDevsList + i * offset

Then I was hoping to just use the result and add that the original btdi.szName, and from how I understand this should point directly to the next one.

Also the data structures are just that, I do not reserve any space in the program other than calling btdi Bluetooth_device_info <?> with some of texts, is anything else need in TASM/asm?

I am continuing to try and figure this out, but are these the right tracks, thanks again in advance
Posted on 2008-10-10 00:53:56 by sidey1234
The C code shows that we are accessing an ARRAY OF STRUCTS.

You can define an array of structs using the DUP keyword

"VariableName DefinedType #Elements DUP (initial data)"

MyArray BLUETOOTH_DEVICE_INFO 10 dup (<>)

This defines an array of 10 structs.
To access it, point at the start of the array, then inside the loop, add the sizeof BLUETOOTH_DEVICE_INFO to your pointer and you are now pointing at the next struct in the array.

lea edi,MyArray
xor ecx,ecx
.while ecx<10
  ;do something with data using edi
  add edi, sizeof BLUETOOTH_DEVICE_INFO
  inc ecx
.endw




Need more help? Happy to provide it.
Posted on 2008-10-10 05:21:37 by Homer
Cheers Homer that terminology is exactly what I was lacking.

When I multiplied the arrays as suggested the function came back invalid parameters :D So I had quick think and an msdn/win32api check later, I created another set of array structures (as suggested) and did a memory move and that works!!. Now just to get it to loop and output the data.

Thanks to your pointers I am now getting even further and learning a shed load, and also rapidly wearing out my keyboard, damn ASM coding overhead :D

Cheers again for help, it is very much appreciated!
Posted on 2008-10-10 14:13:48 by sidey1234
Its my pleasure!
I'm glad you're having fun and learning, keep at it, theres a bunch of people like me who will always be here to assist you when you ask.. I think I speak for all of us when I say that.
Posted on 2008-10-11 07:51:36 by Homer
Here is a snipet of code that I have to access the structure of arrays, while this works and shows all the devices I have found in teh Bluetooth search it isnt doing it right. Its only showing them as its being moved into array2.szNameinq (taken from the above structures)

But surely i shouldnt need to use a second array just access btdi directly?

structures are declared as

btdi BLUETOOTH_DEVICE_INFO <?>
array2 BLUETOOTH_DEVICE_INFO 64 dup (<?>)

I cant specify btdi teh same as array 2 as the function in the dll returns an error.

xor ecx, ecx
mov temp, size btdi ;Number of Bytes to move accross
mov ecx, total
lea edi, array2 ;destination memory address
lea esi, btdi ;source address

DisplayFound:
push ecx
call RtlMoveMemory, edi, esi, temp
;call RtlZeroMemory, esi, temp
call SendDlgItemMessageA, hWnd, IDC_LST1, LB_INSERTSTRING, -1, offset array2.szNameinq
call SendDlgItemMessageA, hWnd, IDC_CBO1, CB_INSERTSTRING, 0,  offset array2.szNameinq
add esi, size btdi
add esi, 6
pop ecx
dec ecx
cmp ecx, 0
jne DisplayFound
ret
Posted on 2008-10-22 08:26:01 by sidey1234
I have found the following piece of code.
;---------- Fill in the points array
                mov    edi,OFFSET points
                mov    dx,10
                mov    bx,20
                mov    ecx,NUMBER_OF_POINTS
next_point:      mov    WORD PTR _x,dx
                mov    WORD PTR _y,bx               
                add    dx,2
                add    bx,4
                add    edi,POINT_SIZE
                loop  next_point
check1::        nop

I haven't tried this in my porgram yet, but would I be right in assuming that to access part of the structure called szName in BTDI I would use szName as stated in the example then to get the next one I would add the size of BTDI to edi and then do szName again?

If so how does that work. I will try this later tonight and update on my findings.
Posted on 2008-10-23 10:26:15 by sidey1234
If you just wish to get a direct pointer to a field of a struct, you could do something like this:

lea edx,.BLUETOOTH_DEVICE_INFO.szName

Given that edi is pointing at the start of a BLUETOOTH_DEVICE_INFO struct, edx is now pointing to the szName field of that struct.

There's lots of ways to address fields of structs, depending on what you want to achieve.

In general, when addressing data, note that that unless you specify a Defined Type such as the name of a struct or the size of a known data type (byte, word, dword, etc), then the assembler will tend to either throw an error (because it's not sure how big your data is), or assume the data is a default size, which for most assemblers is the default bit width of the platform (eg 32 bits on a 32bit platform aka dword).

Posted on 2008-10-23 23:20:26 by Homer
Thanks for replying again homer.

Would I be right in thinking that when the assembler assembles the program it will see a structure and assign a memory address to it.

eg

structre as struct      <-------- address 1
item1                        <--------address 2
item2                        <--------address 3
end struct

then when we do
lea edx,.BLUETOOTH_DEVICE_INFO.szName

its basically taking the base address and adding the (offset ?) of item 1 to that? then loading that address into edx?
Posted on 2008-10-24 13:31:00 by sidey1234
Yes, lea can perform an assignment to a different register and an addition at the same time. Therefore the result (edx) will have the address of BLUETOOTH_DEVICE_INFO stored in edi offset by 'szName'. So basically edx will point to the szName field of the structure pointed to by edi.

In C it would be something like:

BLUETOOTH_DEVICE_INFO *edi;
CHAR *edx;

edi = some_pointer_to_a_BLUETOOTH_DEVICE_INFO_struct;
edx = &(edi->szName[0]);


And this is actually the difference between lea and mov

edx = (edi->szName[0]);  // mov edx, .BLUETOOTH_DEVICE_INFO.szName
edx = &(edi->szName[0]); // lea edx, .BLUETOOTH_DEVICE_INFO.szName

(type checks and type casts omitted for simplicity)
Posted on 2008-10-24 14:00:56 by ti_mo_n
excellent, Thanks to Both homer and ti_mo_n

I think I fully understand this now!!
Posted on 2008-10-27 02:42:05 by sidey1234