News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

SetupDiGetDeviceInterfaceDetailA

Started by Roger, April 13, 2009, 10:57:30 PM

Previous topic - Next topic

Roger

Hi All,

Has anyone used 'SetupDiGetDeviceInterfaceDetail'?

The idea is to use the call twice. Firstly to get the size of the required buffer, allocate an appropriate buffer and then use it the second time the call is made.



;--------------------------------< Get the size of the details >---------------------------
invoke SetupDiGetDeviceInterfaceDetailA, [hDevInfoSet], offset DevIntData, 0, 0, offset length, 0

;------------------------------< Make some space for the details >-------------------------
invoke HeapCreate, 0, 0, 0
or eax,eax
jz >error
mov [hHeap], eax ; save handle to heap

invoke HeapAlloc, eax, HEAP_ZERO_MEMORY, [length] ; get space for DEVICE_INTERFACE_DETAIL_DATA
or eax,eax
jz >error
mov [detaildatapntr], eax
;------------------------------------< Get the details >-----------------------------------
mov eax,[length]
mov edx, [detaildatapntr] ; put size of struct into 1st entry
mov [edx],eax

invoke SetupDiGetDeviceInterfaceDetailA, [hDevInfoSet], offset DevIntData, [detaildatapntr], [length], offset length, 0



With the above the first call works and gives a length 040h.  The second call gives the error message:-

"The supplied buffer is not valid for the requested operation"

I have tried giving more space and declaring a fixed buffer in the DATA section and using that all to no avail.

Suggestions will be greatly appreciated.

I have attached the whole programme in case it helps.

Regards Roger

[attachment deleted by admin]

evlncrn8

try using virtualalloc for the buffer, some api's i've played with are quite tempermental when it comes to memory buffers
some 'need' the buffer to be aligned on 0x1000 (page granularity), some 'need' the buffer to be on an alignment of 4

Roger

Quote from: evlncrn8 on April 14, 2009, 07:33:29 AM
try using virtualalloc for the buffer, some api's i've played with are quite tempermental when it comes to memory buffers
some 'need' the buffer to be aligned on 0x1000 (page granularity), some 'need' the buffer to be on an alignment of 4

VirtualAlloc did not solve the problem.

The call can be used two ways to get either a path to a device or a handle to its information

For a path
   invoke SetupDiGetDeviceInterfaceDetailA, [hDevInfoSet], offset DevIntData, [detaildatapntr], [length], offset length, 0

For a handle
   invoke SetupDiGetDeviceInterfaceDetailA, [hDevInfoSet], offset DevIntData, NULL, NULL, offset length, [infodatapntr]

I can get the second method to work with a declared buffer, HeapAlloc or now with VirtualAlloc. This is because in this case I know the value for cbSize which has to be pre-loaded into the buffer before use.
For the first case the size is not clear. MSDN has:-
Quote from: msdn
DeviceInterfaceDetailData
[out] Pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA structure that receives information about the specified interface. You must set the cbSize member to sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA) before calling this function. The cbSize member always contains the size of the fixed part of the data structure, not a size reflecting the variable-length string at the end.
Quote from: msdn
typedef struct _SP_DEVICE_INTERFACE_DETAIL_DATA {
     DWORD cbSize;
     TCHAR DevicePath[ANYSIZE_ARRAY];
} SP_DEVICE_INTERFACE_DETAIL_DATA,
*PSP_DEVICE_INTERFACE_DETAIL_DATA;

As I see it the fixed part is just cbSize  and the variable length string is DevicePath[ANYSIZE_ARRAY]. Therefore the fixed size is just 1 DWORD ie 4.

All quite simple yet if I use the value 4 I get:-
"The supplied buffer is not valid for the requested operation"
However if I use a value of 5, 6 or 7 I get the error message:-
"The data area passed to a system call is too||small"
Presumably cbSize covers more than one DWORD!

8, 9 and any larger value that I have tried gives the not valid message.

Regards Roger

Roger

Hi Everyone,

It seems that the value in cbsize needs to be 5. I cannot see why unless it is 1 DWORD for cbsize plus 1 BYTE for the zero on the end of the string. Anyway 5 works - so far!

Regards Roger