News:

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

SetupDiEnumDeviceInterfaces ERROR_NO_MORE_ITEMS

Started by Astro, July 29, 2009, 03:12:21 PM

Previous topic - Next topic

Astro

 ::)

I can't see anything wrong, but it is insisting on ERROR_NO_MORE_ITEMS.

I've stripped out the code to get down to the core problem. I'm sick of running this through OllyDbg and not seeing any problems.

There may be redundant code in here.

Quote.386
.model flat,stdcall

include \masm32\include\setupapi.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\setupapi.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

GUID struct
  Data1           DWORD ?
  Data2           WORD ?
  Data3           WORD ?
  Data4           BYTE 8 dup (?)
GUID ends

.data?
hDevInfo DWORD ?
DevInfoData DWORD ?
hHeap DWORD ?
hMemDevIntData DWORD ?
hMemDevIntDetailData DWORD ?
usbGUID GUID <?>

.code
DevInst db "USB\VID_0403&PID_6001",0
app db "Test App",0
SDEDI db "SetupDiEnumDeviceInterfaces FAILED",0

EnumUSB proc
; Allocate memory

   ;Create new private heap in process memory
   push 0h ;heap can grow
   push 0h ;allocates 1 page
   push 0h
   call HeapCreate
   mov hHeap,eax

   ;hMemDevIntData DWORD ?
   push 404h ;allocate 1024 bytes
   push 8h ;zero memory
   push hHeap
   call HeapAlloc
   mov hMemDevIntData,eax
   mov dword ptr [hMemDevIntData],400h ;cbSize - 1024 bytes
   
   ;hMemDevIntDetailData DWORD ?
   push 400h ;allocate 1024 bytes
   push 8h ;zero memory
   push hHeap
   call HeapAlloc
   mov hMemDevIntDetailData,eax
   mov dword ptr [hMemDevIntDetailData],400h ;cbSize - 1024 bytes

   ;DEFINE_GUID( GUID_DEVCLASS_USB, 0x36fc9e60L, 0xc465, 0x11cf, 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 );
   ; populate GUID
   mov dword ptr [usbGUID.Data1],36fc9e60h
   mov word ptr [usbGUID.Data2],c465h
   mov word ptr [usbGUID.Data3],11cfh
   mov byte ptr [usbGUID.Data4],80h
   mov byte ptr [usbGUID.Data4+1],56h
   mov byte ptr [usbGUID.Data4+2],44h
   mov byte ptr [usbGUID.Data4+3],45h
   mov byte ptr [usbGUID.Data4+4],53h
   mov byte ptr [usbGUID.Data4+5],54h
   mov byte ptr [usbGUID.Data4+6],00h
   mov byte ptr [usbGUID.Data4+7],00h

   push 0Eh ;DIGCF_ALLCLASSES or DIGCF_DEVICEINTERFACE
   push 0h
   push offset DevInst
   push 0h
   call SetupDiGetClassDevs
   mov hDevInfo,eax

   mov ecx, 0

   push hMemDevIntData
   push ecx
   push offset usbGUID
   push 0h
   push hDevInfo
   call SetupDiEnumDeviceInterfaces ;ERROR_NO_MORE_ITEMS

   push hDevInfo
   call SetupDiDestroyDeviceInfoList
   push hHeap
   call HeapDestroy
   ret
EnumUSB endp
etc..

I got the GUID out of devguid.h in the Windows 2003 Driver SDK.

Please ignore my use of memory and not structures unless this will absolutely, 100% break it.

http://msdn.microsoft.com/en-us/library/ms791129.aspx

Best regards,
Astro.

evlncrn8

DevInst db "USB\VID_0403&PID_6001",0

would be system specific i think...

Astro

Hmm. So the exact same hardware device in another computer could be different? From the docs it appears that this part is constant.

Best regards,
Astro.

Astro

I'm out of ideas. It always returns ERROR_NO_MORE_ITEMS

Best regards,
Astro.

MichaelW

For the SetupDiEnumDeviceInterfaces function you are supposed to be passing the address of a SP_DEVICE_INTERFACE_DATA structure:

typedef struct _SP_DEVICE_INTERFACE_DATA {
  DWORD cbSize;
  GUID InterfaceClassGuid;
  DWORD Flags;
  ULONG_PTR Reserved;
} SP_DEVICE_INTERFACE_DATA, *PSP_DEVICE_INTERFACE_DATA;


And per the documentation:
Quote
You must set the cbSize member to sizeof( SP_DEVICE_INTERFACE_DATA) before calling this function.

I posted a C example in your sizeof thread that successfully calls the functions.
eschew obfuscation

Astro

I got it down to this. See the attached.

It doesn't fail, but it doesn't work, either.

I'm using raw memory instead of structures. Offsets in the memory should be correct (based on structure sizes).

You'll need to run it in a debugger to see anything.

Best regards,
Astro.

[attachment deleted by admin]

dedndave


GUID STRUCT
  Data1 dd ?
  Data2 dw ?
  Data3 dw ?
  Data4 db 8 dup(?)
GUID ENDS

SP_DEVICE_INTERFACE_DATA STRUCT
  cbSize             dd ?
  InterfaceClassGuid GUID <>
  Flags              dd ?
  Reserved           dd ?
SP_DEVICE_INTERFACE_DATA ENDS

.data?
hHeap DWORD ?
hMemDevInfoData DWORD ?
hMemDevIntData SP_DEVICE_INTERFACE_DATA <>
.
.
.
   call HeapAlloc ;use HeapFree to reverse
;        mov hMemDevIntData,eax                          ;huh ?
.
.
.
;        mov dword ptr [hMemDevIntData],400h ;cbSize - 1024 bytes
        mov dword ptr hMemDevIntData.cbSize,sizeof hMemDevIntData

   push offset hMemDevIntData
   push 0h
   push offset usbGUID
   push hMemDevInfoData
   push hDevInfo
   call SetupDiEnumDeviceInterfaces

Astro

Quote;        mov hMemDevIntData,eax                          ;huh ?
To move the pointer returned by HeapAlloc to the variable hMemDevIntData.

Does your code mod work? Not able to test it right now.

Best regards,
Astro.

dedndave

no, it does not - lol
but it is a step in the right direction
hMemDevIntData is a structure, so the heap allocation makes no sense, in this context
maybe you were trying to allocate a heap block for the structure ?

Astro

Quotemaybe you were trying to allocate a heap block for the structure ?
So there is no confusion:

INSTEAD of using a structure, I was trying to allocate memory and use it instead (keeping the data sizes/offsets the same as the structure).

The idea being it only allocated the memory when it needed it, rather than straight out allocating it for the lifetime of the app.

Quoteno, it does not - lol
Why am I not surprised?  :cheekygreen:

Best regards,
Astro.

dedndave

lol
by the time you add the code required to allocate memory, you may as well have defined the structure in uninitialized data
one advantage is that uninitialized data does not add size to the executable
another advantage is code requires execution time - data does not
and finally, if the structure is defined in data, all the element labels are easily accessed
it would take a very large data structure before you see any advantage out of dynamically allocating space for it

Astro

.386
.model flat,stdcall

include \masm32\include\kernel32.inc
include \masm32\include\setupapi.inc
include \masm32\include\rpcrt4.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\setupapi.lib
includelib \masm32\lib\rpcrt4.lib

_GUID struct ;16 bytes
  Data1           DWORD ?
  Data2           WORD ?
  Data3           WORD ?
  Data4           BYTE 8 dup (?)
_GUID ends

_SP_DEVINFO_DATA struct ;28 bytes
  cbSize DWORD ?
  ClassGuid _GUID <>
  DevInst DWORD ?
  Reserved DWORD ?
_SP_DEVINFO_DATA ends

_SP_DEVICE_INTERFACE_DATA struct
  cbSize DWORD ?
  InterfaceClassGuid _GUID <>
  Flags DWORD ?
  Reserved DWORD ?
_SP_DEVICE_INTERFACE_DATA ends

.data?
usbGUID BYTE 16 DUP (?)
hDevInfo DWORD ?
SDD _SP_DEVINFO_DATA <>
SDID _SP_DEVICE_INTERFACE_DATA <>

.code
usb2GUID db "36FC9E60-C465-11CF-8056-444553540000",0

start:
push offset usbGUID
push offset usb2GUID
call UuidFromString

push offset devGUID
push offset dev2GUID
call UuidFromString

mov dword ptr [SDD].cbSize,28
mov dword ptr [SDID].cbSize,28
mov eax,offset usbGUID
mov dword ptr [SDD].ClassGuid,eax

push 4h ;DIGCF_DEVICEINTERFACE
push 0h
push 0h
push 0h
call SetupDiGetClassDevs
mov hDevInfo,eax

push offset SDD
push 0h  ; 0h works - 200h returns ERROR_NO_MORE_ITEMS
push hDevInfo
call SetupDiEnumDeviceInfo

push hDevInfo
call SetupDiDestroyDeviceInfoList

ret
end start

:cheekygreen:

Got this working so far. Setting a GUID or Enumerator doesn't seem to work. I get errors.

At least I can move on now and see what is there!  :cheekygreen:

Best regards,
Astro.