The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: georgek01 on June 28, 2005, 04:03:15 PM

Title: Enumerating USB?
Post by: georgek01 on June 28, 2005, 04:03:15 PM
I'm hoping someone can assist me with this problem.

I need to enumerate USB devices connected to a WIN XP machine. For now I'm using the GUID class for a mouse just to test. I'm able (or so I think) to get a handle to that class using 'SetupDiGetClassDevs'. Once I start my first enumeration call to 'SetupDiEnumDeviceInterfaces' I receive 'No more data available.'

Any obvious reason why the enumeration is not returning TRUE?

.data

; mouse class GUID 4D36E96F-E325-11CE-BFC1-08002BE10318

sCGUID TEXTEQU <{04D36E96FH, 0E325H, 011CEH, {0BFH, 0C1H, 008H, 000H, 02BH, 0E1H, 003H, 018H}}>

CGUID GUID sCGUID


EnumUSB proc hWnd:DWORD

local interface_info:SP_DEVICE_INTERFACE_DATA
local interface_detail:SP_DEVICE_INTERFACE_DETAIL_DATA
local needed:DWORD
local mybuffer :LPVOID

invoke SetupDiGetClassDevs,addr CGUID,NULL,NULL,DIGCF_PRESENT or DIGCF_DEVICEINTERFACE

mov hInfo,eax

invoke SetLastError,0

.if hInfo == INVALID_HANDLE_VALUE
invoke MessageBox,hWnd,addr szAppError,addr szAppName,MB_OK or MB_ICONERROR
invoke SetupDiDestroyDeviceInfoList,hInfo
xor eax,eax
ret
.endif

invoke GetLastError
mov edi,eax

.if edi != 0
invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,0,edi,0,addr mybuffer,0,NULL
invoke MessageBox,hWnd,mybuffer,addr szAppName,MB_OK or MB_ICONERROR
invoke SetupDiDestroyDeviceInfoList,hInfo
xor eax,eax
ret
.endif

mov ecx, 0

invoke SetLastError,0

.while eax != FALSE
mov interface_info.cbSize, sizeof interface_info
invoke SetupDiEnumDeviceInterfaces,hInfo,NULL,addr CGUID,ecx,addr interface_info

; error occurs here: 'No more data available.' on first call (ecx = 0)

.if eax == FALSE
invoke GetLastError
mov edi,eax

.if edi != 0
invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,0,edi,0,addr mybuffer,0,NULL
invoke MessageBox,hWnd,mybuffer,addr szAppName,MB_OK or MB_ICONERROR
.endif

invoke SetupDiDestroyDeviceInfoList,hInfo
xor eax,eax
ret
.endif

mov interface_detail.cbSize,132
invoke SetupDiGetDeviceInterfaceDetail,hInfo,addr interface_info,addr interface_detail,0,256, NULL

.if eax == FALSE
invoke SetupDiDestroyDeviceInfoList,hInfo
invoke MessageBox,hWnd,addr szAppError,addr szAppName,MB_OK or MB_ICONERROR
xor eax,eax
ret
.endif

inc ecx

.endw

xor eax, eax
Ret
EnumUSB EndP
Title: Re: Enumerating USB?
Post by: doomsday on June 29, 2005, 03:52:02 PM
Possibly a stupid question but based on the following assumptions
- you're enumerating USB devices
and
- you're trying to get it to enumerate your mouse (to test the code)

Is it possible that it's not finding anything because you don't have a USB mouse?

regards,
-Brent
Title: Re: Enumerating USB?
Post by: georgek01 on June 30, 2005, 08:22:09 AM
Yes, I do have a USB mouse attached to my machine. It is possible that the class I'm using is incorrect. Would you perhaps know where I can get the correct class from? I looked through the registry but cannot see a GUID for pointing device or mouse class.

Thank you for your response.
Title: Re: Enumerating USB?
Post by: doomsday on June 30, 2005, 11:17:09 PM
God I hope you can read C/C++ !   :)

Take a look at the attached zip.  The list of class GUIDs is in "DevGuid.h", and hopefully some of the code in "main.cpp" will be of use to you.

regards,
-Brent



[attachment deleted by admin]
Title: Re: Enumerating USB?
Post by: georgek01 on July 01, 2005, 07:23:26 AM
Thanks Brent! The app does exactly what I'm looking for - now only to do the same in assembler...  :eek
Title: Re: Enumerating USB?
Post by: Mark Jones on July 01, 2005, 02:22:13 PM
Well, you could peek at the assembler code in a debugger such as OllyDbg (http://www.ollydbg.de/) or just plain disassemble it if it doesn't violate any license agreements (I didn't look at the code.).
Title: Re: Enumerating USB?
Post by: doomsday on July 03, 2005, 03:33:25 PM
Quote from: georgek01Thanks Brent! The app does exactly what I'm looking for - now only to do the same in assembler...

If you really want I could have a go at re-writing it in for MASM, but I seriously doubt there would be much benefit to be had by doing so.  I haven't run it though a profiler but I'd suggest that 90+ percent of the time, in the relevant code, is spent in API calls anyhow.  But yeah, sure if you like I'll give it a go.

regards,
-Brent
Title: Re: Enumerating USB?
Post by: georgek01 on July 04, 2005, 09:13:24 AM
Hi Brent,

I've got some of the code down, but I'm struggling with one piece of the puzzle.

C-code:

memset(&devInfoData,0,sizeof(devInfoData));

How will this translate to assembler?

Thank you for your assistance!







Title: Re: Enumerating USB?
Post by: georgek01 on July 04, 2005, 03:10:12 PM
Will RtlFillMemory and memset produce the same result when passed the same parameters?
Title: Re: Enumerating USB?
Post by: chep on July 04, 2005, 03:16:33 PM
Hi george,

Quote from: georgek01 on July 04, 2005, 03:10:12 PM
Will RtlFillMemory and memset produce the same result when passed the same parameters?

You have to swap the Length & Fill parameters :

memset(PVOID Destination, BYTE Fill, SIZE_T Length)
RtlFillMemory(PVOID Destination, SIZE_T Length, BYTE Fill)

As you are zeroing the memory, you could also use RtlZeroMemory(PVOID Destination, SIZE_T Length) and ommit the 0 parameter.
Title: Re: Enumerating USB?
Post by: doomsday on July 04, 2005, 03:24:32 PM
If you swap the last two arguments, they should.

memset( PointerToMemoryBlock, ByteToFillBlockWith, SizeOfBlock)

vs

RtlFillMemory( PointerToMemoryBlock, SizeOfBlock, ByteToFillBlockWith)

vs

mov edi, PointerToMemoryBlock
mov ecx, SizeOfBlock
mov al, ByteToFillBlockWith
rep stosb



BTW, I doubt that it's necessary to 0-fill the structure in any case... but I left it there on the basis that it can't hurt.

regards,
-Brent
Title: Re: Enumerating USB?
Post by: georgek01 on July 04, 2005, 03:34:45 PM
Thank you!

I am however receiving The supplied user buffer is invalid for the requested operation. I think it may have something to do with my structure definition.

I've translated...

typedef struct _SP_DEVINFO_DATA { 
    DWORD cbSize; 
    GUID ClassGuid; 
    DWORD DevInst; 
    ULONG_PTR Reserved;
} SP_DEVINFO_DATA, *PSP_DEVINFO_DATA;


to...

SP_DEVINFO_DATA STRUCT 
cbSize DWORD ?
ClassGuid DWORD ? 
DevInst DWORD  ?
Reserved DWORD ?
SP_DEVINFO_DATA EndS


Am I correct in assuming ULONG_PTR = DWORD?
Title: Re: Enumerating USB?
Post by: chep on July 04, 2005, 03:55:34 PM
Quote from: georgek01 on July 04, 2005, 03:34:45 PM
Am I correct in assuming ULONG_PTR = DWORD?

Yes, but a GUID is not a DWORD:

Quote from: Windows.inc_GUID STRUCT
  Data1           DWORD ?
  Data2           WORD ?
  Data3           WORD ?
  Data4           BYTE 8 dup (?)
_GUID ENDS

so I think it should be:
SP_DEVINFO_DATA STRUCT 
cbSize DWORD ?
ClassGuid _GUID <?>
DevInst DWORD  ?
Reserved DWORD ?
SP_DEVINFO_DATA EndS
Title: Re: Enumerating USB?
Post by: georgek01 on July 04, 2005, 04:03:23 PM
That works just fine!  :U Thank you!